]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-vserver-2.3.patch
Up to 5.15.26 (fixes SECURITY issue https://dirtypipe.cm4all.com/ - fixed in .25)
[packages/kernel.git] / kernel-vserver-2.3.patch
1 diff -NurpP --minimal linux-3.18.5/Documentation/vserver/debug.txt linux-3.18.5-vs2.3.7.3/Documentation/vserver/debug.txt
2 --- linux-3.18.5/Documentation/vserver/debug.txt        1970-01-01 00:00:00.000000000 +0000
3 +++ linux-3.18.5-vs2.3.7.3/Documentation/vserver/debug.txt      2015-01-19 10:57:45.000000000 +0000
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.%d.%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 + 4  10 "__hash_vx_info: %p[#%d]"
136 +       "__unhash_vx_info: %p[#%d.%d.%d]"
137 +       "__vx_dynamic_id: [#%d]"
138 + 5  20 "enter_vx_info(%p[#%d],%p) %p[#%d,%p]"
139 +       "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]"
140 +       "moved task %p into vxi:%p[#%d]"
141 +       "task_get_vx_info(%p)"
142 +       "vx_migrate_task(%p,%p[#%d.%d])"
143 + 6  40 "vx_clear_persistent(%p[#%d])"
144 +       "vx_exit_init(%p[#%d],%p[#%d,%d,%d])"
145 +       "vx_set_init(%p[#%d],%p[#%d,%d,%d])"
146 +       "vx_set_persistent(%p[#%d])"
147 +       "vx_set_reaper(%p[#%d],%p[#%d,%d])"
148 + 7  80 "vx_child_reaper(%p[#%u,%u]) = %p[#%u,%u]"
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-3.18.5/arch/alpha/Kconfig linux-3.18.5-vs2.3.7.3/arch/alpha/Kconfig
160 --- linux-3.18.5/arch/alpha/Kconfig     2014-06-12 13:00:27.000000000 +0000
161 +++ linux-3.18.5-vs2.3.7.3/arch/alpha/Kconfig   2015-01-19 10:57:45.000000000 +0000
162 @@ -740,6 +740,8 @@ config DUMMY_CONSOLE
163         depends on VGA_HOSE
164         default y
165  
166 +source "kernel/vserver/Kconfig"
167 +
168  source "security/Kconfig"
169  
170  source "crypto/Kconfig"
171 diff -NurpP --minimal linux-3.18.5/arch/alpha/kernel/systbls.S linux-3.18.5-vs2.3.7.3/arch/alpha/kernel/systbls.S
172 --- linux-3.18.5/arch/alpha/kernel/systbls.S    2015-01-16 22:18:10.000000000 +0000
173 +++ linux-3.18.5-vs2.3.7.3/arch/alpha/kernel/systbls.S  2015-01-19 10:57:45.000000000 +0000
174 @@ -446,7 +446,7 @@ sys_call_table:
175         .quad sys_stat64                        /* 425 */
176         .quad sys_lstat64
177         .quad sys_fstat64
178 -       .quad sys_ni_syscall                    /* sys_vserver */
179 +       .quad sys_vserver                       /* sys_vserver */
180         .quad sys_ni_syscall                    /* sys_mbind */
181         .quad sys_ni_syscall                    /* sys_get_mempolicy */
182         .quad sys_ni_syscall                    /* sys_set_mempolicy */
183 diff -NurpP --minimal linux-3.18.5/arch/alpha/kernel/traps.c linux-3.18.5-vs2.3.7.3/arch/alpha/kernel/traps.c
184 --- linux-3.18.5/arch/alpha/kernel/traps.c      2014-01-22 20:38:10.000000000 +0000
185 +++ linux-3.18.5-vs2.3.7.3/arch/alpha/kernel/traps.c    2015-01-19 10:57:45.000000000 +0000
186 @@ -175,7 +175,8 @@ die_if_kernel(char * str, struct pt_regs
187  #ifdef CONFIG_SMP
188         printk("CPU %d ", hard_smp_processor_id());
189  #endif
190 -       printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err);
191 +       printk("%s(%d:#%u): %s %ld\n", current->comm,
192 +               task_pid_nr(current), current->xid, str, err);
193         dik_show_regs(regs, r9_15);
194         add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
195         dik_show_trace((unsigned long *)(regs+1));
196 diff -NurpP --minimal linux-3.18.5/arch/arm/Kconfig linux-3.18.5-vs2.3.7.3/arch/arm/Kconfig
197 --- linux-3.18.5/arch/arm/Kconfig       2015-01-17 02:39:30.000000000 +0000
198 +++ linux-3.18.5-vs2.3.7.3/arch/arm/Kconfig     2015-01-19 10:57:45.000000000 +0000
199 @@ -2170,6 +2170,8 @@ source "fs/Kconfig"
200  
201  source "arch/arm/Kconfig.debug"
202  
203 +source "kernel/vserver/Kconfig"
204 +
205  source "security/Kconfig"
206  
207  source "crypto/Kconfig"
208 diff -NurpP --minimal linux-3.18.5/arch/arm/kernel/calls.S linux-3.18.5-vs2.3.7.3/arch/arm/kernel/calls.S
209 --- linux-3.18.5/arch/arm/kernel/calls.S        2015-01-17 02:39:31.000000000 +0000
210 +++ linux-3.18.5-vs2.3.7.3/arch/arm/kernel/calls.S      2015-01-19 10:57:45.000000000 +0000
211 @@ -322,7 +322,7 @@
212  /* 310 */      CALL(sys_request_key)
213                 CALL(sys_keyctl)
214                 CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
215 -/* vserver */  CALL(sys_ni_syscall)
216 +               CALL(sys_vserver)
217                 CALL(sys_ioprio_set)
218  /* 315 */      CALL(sys_ioprio_get)
219                 CALL(sys_inotify_init)
220 diff -NurpP --minimal linux-3.18.5/arch/arm/kernel/traps.c linux-3.18.5-vs2.3.7.3/arch/arm/kernel/traps.c
221 --- linux-3.18.5/arch/arm/kernel/traps.c        2015-01-17 02:39:31.000000000 +0000
222 +++ linux-3.18.5-vs2.3.7.3/arch/arm/kernel/traps.c      2015-01-19 10:57:45.000000000 +0000
223 @@ -250,8 +250,8 @@ static int __die(const char *str, int er
224  
225         print_modules();
226         __show_regs(regs);
227 -       printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
228 -               TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk));
229 +       printk(KERN_EMERG "Process %.*s (pid: %d:#%u, stack limit = 0x%p)\n",
230 +               TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), tsk->xid, end_of_stack(tsk));
231  
232         if (!user_mode(regs) || in_interrupt()) {
233                 dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
234 diff -NurpP --minimal linux-3.18.5/arch/cris/Kconfig linux-3.18.5-vs2.3.7.3/arch/cris/Kconfig
235 --- linux-3.18.5/arch/cris/Kconfig      2014-06-12 13:00:42.000000000 +0000
236 +++ linux-3.18.5-vs2.3.7.3/arch/cris/Kconfig    2015-01-19 10:57:45.000000000 +0000
237 @@ -556,6 +556,8 @@ source "fs/Kconfig"
238  
239  source "arch/cris/Kconfig.debug"
240  
241 +source "kernel/vserver/Kconfig"
242 +
243  source "security/Kconfig"
244  
245  source "crypto/Kconfig"
246 diff -NurpP --minimal linux-3.18.5/arch/ia64/Kconfig linux-3.18.5-vs2.3.7.3/arch/ia64/Kconfig
247 --- linux-3.18.5/arch/ia64/Kconfig      2015-01-16 22:18:19.000000000 +0000
248 +++ linux-3.18.5-vs2.3.7.3/arch/ia64/Kconfig    2015-01-19 10:57:45.000000000 +0000
249 @@ -636,6 +636,8 @@ source "fs/Kconfig"
250  
251  source "arch/ia64/Kconfig.debug"
252  
253 +source "kernel/vserver/Kconfig"
254 +
255  source "security/Kconfig"
256  
257  source "crypto/Kconfig"
258 diff -NurpP --minimal linux-3.18.5/arch/ia64/kernel/entry.S linux-3.18.5-vs2.3.7.3/arch/ia64/kernel/entry.S
259 --- linux-3.18.5/arch/ia64/kernel/entry.S       2015-01-17 02:39:35.000000000 +0000
260 +++ linux-3.18.5-vs2.3.7.3/arch/ia64/kernel/entry.S     2015-01-19 10:57:45.000000000 +0000
261 @@ -1706,7 +1706,7 @@ sys_call_table:
262         data8 sys_mq_notify
263         data8 sys_mq_getsetattr
264         data8 sys_kexec_load
265 -       data8 sys_ni_syscall                    // reserved for vserver
266 +       data8 sys_vserver
267         data8 sys_waitid                        // 1270
268         data8 sys_add_key
269         data8 sys_request_key
270 diff -NurpP --minimal linux-3.18.5/arch/ia64/kernel/ptrace.c linux-3.18.5-vs2.3.7.3/arch/ia64/kernel/ptrace.c
271 --- linux-3.18.5/arch/ia64/kernel/ptrace.c      2015-01-17 02:39:35.000000000 +0000
272 +++ linux-3.18.5-vs2.3.7.3/arch/ia64/kernel/ptrace.c    2015-01-19 10:57:45.000000000 +0000
273 @@ -21,6 +21,7 @@
274  #include <linux/regset.h>
275  #include <linux/elf.h>
276  #include <linux/tracehook.h>
277 +#include <linux/vs_base.h>
278  
279  #include <asm/pgtable.h>
280  #include <asm/processor.h>
281 diff -NurpP --minimal linux-3.18.5/arch/ia64/kernel/traps.c linux-3.18.5-vs2.3.7.3/arch/ia64/kernel/traps.c
282 --- linux-3.18.5/arch/ia64/kernel/traps.c       2015-01-17 02:39:35.000000000 +0000
283 +++ linux-3.18.5-vs2.3.7.3/arch/ia64/kernel/traps.c     2015-01-19 10:57:45.000000000 +0000
284 @@ -60,8 +60,9 @@ die (const char *str, struct pt_regs *re
285         put_cpu();
286  
287         if (++die.lock_owner_depth < 3) {
288 -               printk("%s[%d]: %s %ld [%d]\n",
289 -               current->comm, task_pid_nr(current), str, err, ++die_counter);
290 +               printk("%s[%d:#%u]: %s %ld [%d]\n",
291 +                       current->comm, task_pid_nr(current), current->xid,
292 +                       str, err, ++die_counter);
293                 if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV)
294                     != NOTIFY_STOP)
295                         show_regs(regs);
296 @@ -324,8 +325,9 @@ handle_fpu_swa (int fp_fault, struct pt_
297                         if ((last.count & 15) < 5 && (ia64_fetchadd(1, &last.count, acq) & 15) < 5) {
298                                 last.time = current_jiffies + 5 * HZ;
299                                 printk(KERN_WARNING
300 -                                       "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
301 -                                       current->comm, task_pid_nr(current), regs->cr_iip + ia64_psr(regs)->ri, isr);
302 +                                       "%s(%d:#%u): floating-point assist fault at ip %016lx, isr %016lx\n",
303 +                                       current->comm, task_pid_nr(current), current->xid,
304 +                                       regs->cr_iip + ia64_psr(regs)->ri, isr);
305                         }
306                 }
307         }
308 diff -NurpP --minimal linux-3.18.5/arch/m32r/kernel/traps.c linux-3.18.5-vs2.3.7.3/arch/m32r/kernel/traps.c
309 --- linux-3.18.5/arch/m32r/kernel/traps.c       2013-07-14 17:00:26.000000000 +0000
310 +++ linux-3.18.5-vs2.3.7.3/arch/m32r/kernel/traps.c     2015-01-19 10:57:45.000000000 +0000
311 @@ -184,8 +184,9 @@ static void show_registers(struct pt_reg
312         } else {
313                 printk("SPI: %08lx\n", sp);
314         }
315 -       printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
316 -               current->comm, task_pid_nr(current), 0xffff & i, 4096+(unsigned long)current);
317 +       printk("Process %s (pid: %d:#%u, process nr: %d, stackpage=%08lx)",
318 +               current->comm, task_pid_nr(current), current->xid,
319 +               0xffff & i, 4096+(unsigned long)current);
320  
321         /*
322          * When in-kernel, we also print out the stack and code at the
323 diff -NurpP --minimal linux-3.18.5/arch/m68k/Kconfig linux-3.18.5-vs2.3.7.3/arch/m68k/Kconfig
324 --- linux-3.18.5/arch/m68k/Kconfig      2014-06-12 13:00:43.000000000 +0000
325 +++ linux-3.18.5-vs2.3.7.3/arch/m68k/Kconfig    2015-01-19 10:57:45.000000000 +0000
326 @@ -159,6 +159,8 @@ source "fs/Kconfig"
327  
328  source "arch/m68k/Kconfig.debug"
329  
330 +source "kernel/vserver/Kconfig"
331 +
332  source "security/Kconfig"
333  
334  source "crypto/Kconfig"
335 diff -NurpP --minimal linux-3.18.5/arch/mips/Kconfig linux-3.18.5-vs2.3.7.3/arch/mips/Kconfig
336 --- linux-3.18.5/arch/mips/Kconfig      2015-01-17 02:39:35.000000000 +0000
337 +++ linux-3.18.5-vs2.3.7.3/arch/mips/Kconfig    2015-01-19 10:57:45.000000000 +0000
338 @@ -2712,6 +2712,8 @@ source "fs/Kconfig"
339  
340  source "arch/mips/Kconfig.debug"
341  
342 +source "kernel/vserver/Kconfig"
343 +
344  source "security/Kconfig"
345  
346  source "crypto/Kconfig"
347 diff -NurpP --minimal linux-3.18.5/arch/mips/kernel/ptrace.c linux-3.18.5-vs2.3.7.3/arch/mips/kernel/ptrace.c
348 --- linux-3.18.5/arch/mips/kernel/ptrace.c      2015-01-17 02:39:36.000000000 +0000
349 +++ linux-3.18.5-vs2.3.7.3/arch/mips/kernel/ptrace.c    2015-01-19 10:57:45.000000000 +0000
350 @@ -29,6 +29,7 @@
351  #include <linux/audit.h>
352  #include <linux/seccomp.h>
353  #include <linux/ftrace.h>
354 +#include <linux/vs_base.h>
355  
356  #include <asm/byteorder.h>
357  #include <asm/cpu.h>
358 @@ -544,6 +545,9 @@ long arch_ptrace(struct task_struct *chi
359         void __user *datavp = (void __user *) data;
360         unsigned long __user *datalp = (void __user *) data;
361  
362 +       if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT))
363 +               goto out;
364 +
365         switch (request) {
366         /* when I and D space are separate, these will need to be fixed. */
367         case PTRACE_PEEKTEXT: /* read word at location addr. */
368 diff -NurpP --minimal linux-3.18.5/arch/mips/kernel/scall32-o32.S linux-3.18.5-vs2.3.7.3/arch/mips/kernel/scall32-o32.S
369 --- linux-3.18.5/arch/mips/kernel/scall32-o32.S 2015-01-17 02:39:36.000000000 +0000
370 +++ linux-3.18.5-vs2.3.7.3/arch/mips/kernel/scall32-o32.S       2015-01-19 10:57:45.000000000 +0000
371 @@ -501,7 +501,7 @@ EXPORT(sys_call_table)
372         PTR     sys_mq_timedreceive
373         PTR     sys_mq_notify                   /* 4275 */
374         PTR     sys_mq_getsetattr
375 -       PTR     sys_ni_syscall                  /* sys_vserver */
376 +       PTR     sys_vserver
377         PTR     sys_waitid
378         PTR     sys_ni_syscall                  /* available, was setaltroot */
379         PTR     sys_add_key                     /* 4280 */
380 diff -NurpP --minimal linux-3.18.5/arch/mips/kernel/scall64-64.S linux-3.18.5-vs2.3.7.3/arch/mips/kernel/scall64-64.S
381 --- linux-3.18.5/arch/mips/kernel/scall64-64.S  2015-01-17 02:39:36.000000000 +0000
382 +++ linux-3.18.5-vs2.3.7.3/arch/mips/kernel/scall64-64.S        2015-01-19 10:57:45.000000000 +0000
383 @@ -355,7 +355,7 @@ EXPORT(sys_call_table)
384         PTR     sys_mq_timedreceive
385         PTR     sys_mq_notify
386         PTR     sys_mq_getsetattr               /* 5235 */
387 -       PTR     sys_ni_syscall                  /* sys_vserver */
388 +       PTR     sys_vserver
389         PTR     sys_waitid
390         PTR     sys_ni_syscall                  /* available, was setaltroot */
391         PTR     sys_add_key
392 diff -NurpP --minimal linux-3.18.5/arch/mips/kernel/scall64-n32.S linux-3.18.5-vs2.3.7.3/arch/mips/kernel/scall64-n32.S
393 --- linux-3.18.5/arch/mips/kernel/scall64-n32.S 2015-01-17 02:39:36.000000000 +0000
394 +++ linux-3.18.5-vs2.3.7.3/arch/mips/kernel/scall64-n32.S       2015-01-19 10:57:45.000000000 +0000
395 @@ -348,7 +348,7 @@ EXPORT(sysn32_call_table)
396         PTR     compat_sys_mq_timedreceive
397         PTR     compat_sys_mq_notify
398         PTR     compat_sys_mq_getsetattr
399 -       PTR     sys_ni_syscall                  /* 6240, sys_vserver */
400 +       PTR     sys32_vserver                   /* 6240 */
401         PTR     compat_sys_waitid
402         PTR     sys_ni_syscall                  /* available, was setaltroot */
403         PTR     sys_add_key
404 diff -NurpP --minimal linux-3.18.5/arch/mips/kernel/scall64-o32.S linux-3.18.5-vs2.3.7.3/arch/mips/kernel/scall64-o32.S
405 --- linux-3.18.5/arch/mips/kernel/scall64-o32.S 2015-01-17 02:39:36.000000000 +0000
406 +++ linux-3.18.5-vs2.3.7.3/arch/mips/kernel/scall64-o32.S       2015-01-19 10:57:45.000000000 +0000
407 @@ -486,7 +486,7 @@ EXPORT(sys32_call_table)
408         PTR     compat_sys_mq_timedreceive
409         PTR     compat_sys_mq_notify            /* 4275 */
410         PTR     compat_sys_mq_getsetattr
411 -       PTR     sys_ni_syscall                  /* sys_vserver */
412 +       PTR     sys32_vserver
413         PTR     compat_sys_waitid
414         PTR     sys_ni_syscall                  /* available, was setaltroot */
415         PTR     sys_add_key                     /* 4280 */
416 diff -NurpP --minimal linux-3.18.5/arch/mips/kernel/traps.c linux-3.18.5-vs2.3.7.3/arch/mips/kernel/traps.c
417 --- linux-3.18.5/arch/mips/kernel/traps.c       2015-01-16 22:18:20.000000000 +0000
418 +++ linux-3.18.5-vs2.3.7.3/arch/mips/kernel/traps.c     2015-01-19 10:57:45.000000000 +0000
419 @@ -341,9 +341,10 @@ void show_registers(struct pt_regs *regs
420  
421         __show_regs(regs);
422         print_modules();
423 -       printk("Process %s (pid: %d, threadinfo=%p, task=%p, tls=%0*lx)\n",
424 -              current->comm, current->pid, current_thread_info(), current,
425 -             field, current_thread_info()->tp_value);
426 +       printk("Process %s (pid: %d:#%u, threadinfo=%p, task=%p, tls=%0*lx)\n",
427 +               current->comm, task_pid_nr(current), current->xid,
428 +               current_thread_info(), current,
429 +               field, current_thread_info()->tp_value);
430         if (cpu_has_userlocal) {
431                 unsigned long tls;
432  
433 diff -NurpP --minimal linux-3.18.5/arch/parisc/Kconfig linux-3.18.5-vs2.3.7.3/arch/parisc/Kconfig
434 --- linux-3.18.5/arch/parisc/Kconfig    2015-01-16 22:18:21.000000000 +0000
435 +++ linux-3.18.5-vs2.3.7.3/arch/parisc/Kconfig  2015-01-19 10:57:45.000000000 +0000
436 @@ -337,6 +337,8 @@ config SECCOMP
437  
438           If unsure, say Y. Only embedded should say N here.
439  
440 +source "kernel/vserver/Kconfig"
441 +
442  source "security/Kconfig"
443  
444  source "crypto/Kconfig"
445 diff -NurpP --minimal linux-3.18.5/arch/parisc/kernel/syscall_table.S linux-3.18.5-vs2.3.7.3/arch/parisc/kernel/syscall_table.S
446 --- linux-3.18.5/arch/parisc/kernel/syscall_table.S     2015-01-17 02:39:36.000000000 +0000
447 +++ linux-3.18.5-vs2.3.7.3/arch/parisc/kernel/syscall_table.S   2015-01-19 10:57:45.000000000 +0000
448 @@ -358,7 +358,7 @@
449         ENTRY_COMP(mbind)               /* 260 */
450         ENTRY_COMP(get_mempolicy)
451         ENTRY_COMP(set_mempolicy)
452 -       ENTRY_SAME(ni_syscall)  /* 263: reserved for vserver */
453 +       ENTRY_DIFF(vserver)
454         ENTRY_SAME(add_key)
455         ENTRY_SAME(request_key)         /* 265 */
456         ENTRY_SAME(keyctl)
457 diff -NurpP --minimal linux-3.18.5/arch/parisc/kernel/traps.c linux-3.18.5-vs2.3.7.3/arch/parisc/kernel/traps.c
458 --- linux-3.18.5/arch/parisc/kernel/traps.c     2014-06-12 13:01:26.000000000 +0000
459 +++ linux-3.18.5-vs2.3.7.3/arch/parisc/kernel/traps.c   2015-01-19 10:57:45.000000000 +0000
460 @@ -239,8 +239,9 @@ void die_if_kernel(char *str, struct pt_
461                         return; /* STFU */
462  
463                 parisc_printk_ratelimited(1, regs,
464 -                       KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
465 -                       current->comm, task_pid_nr(current), str, err, regs->iaoq[0]);
466 +                       KERN_CRIT "%s (pid %d:#%u): %s (code %ld) at " RFMT "\n",
467 +                       current->comm, task_pid_nr(current), current->xid,
468 +                       str, err, regs->iaoq[0]);
469  
470                 return;
471         }
472 @@ -270,8 +271,8 @@ void die_if_kernel(char *str, struct pt_
473                 pdc_console_restart();
474         
475         if (err)
476 -               printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
477 -                       current->comm, task_pid_nr(current), str, err);
478 +               printk(KERN_CRIT "%s (pid %d:#%u): %s (code %ld)\n",
479 +                       current->comm, task_pid_nr(current), current->xid, str, err);
480  
481         /* Wot's wrong wif bein' racy? */
482         if (current->thread.flags & PARISC_KERNEL_DEATH) {
483 diff -NurpP --minimal linux-3.18.5/arch/powerpc/Kconfig linux-3.18.5-vs2.3.7.3/arch/powerpc/Kconfig
484 --- linux-3.18.5/arch/powerpc/Kconfig   2015-01-17 02:39:36.000000000 +0000
485 +++ linux-3.18.5-vs2.3.7.3/arch/powerpc/Kconfig 2015-01-19 10:57:46.000000000 +0000
486 @@ -1068,6 +1068,8 @@ source "lib/Kconfig"
487  
488  source "arch/powerpc/Kconfig.debug"
489  
490 +source "kernel/vserver/Kconfig"
491 +
492  source "security/Kconfig"
493  
494  config KEYS_COMPAT
495 diff -NurpP --minimal linux-3.18.5/arch/powerpc/include/uapi/asm/unistd.h linux-3.18.5-vs2.3.7.3/arch/powerpc/include/uapi/asm/unistd.h
496 --- linux-3.18.5/arch/powerpc/include/uapi/asm/unistd.h 2015-01-17 02:39:36.000000000 +0000
497 +++ linux-3.18.5-vs2.3.7.3/arch/powerpc/include/uapi/asm/unistd.h       2015-01-19 10:57:46.000000000 +0000
498 @@ -275,7 +275,7 @@
499  #endif
500  #define __NR_rtas              255
501  #define __NR_sys_debug_setcontext 256
502 -/* Number 257 is reserved for vserver */
503 +#define __NR_vserver           257
504  #define __NR_migrate_pages     258
505  #define __NR_mbind             259
506  #define __NR_get_mempolicy     260
507 diff -NurpP --minimal linux-3.18.5/arch/powerpc/kernel/traps.c linux-3.18.5-vs2.3.7.3/arch/powerpc/kernel/traps.c
508 --- linux-3.18.5/arch/powerpc/kernel/traps.c    2015-01-16 22:18:21.000000000 +0000
509 +++ linux-3.18.5-vs2.3.7.3/arch/powerpc/kernel/traps.c  2015-01-19 10:57:46.000000000 +0000
510 @@ -1313,8 +1313,9 @@ void nonrecoverable_exception(struct pt_
511  
512  void trace_syscall(struct pt_regs *regs)
513  {
514 -       printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
515 -              current, task_pid_nr(current), regs->nip, regs->link, regs->gpr[0],
516 +       printk("Task: %p(%d:#%u), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
517 +              current, task_pid_nr(current), current->xid,
518 +              regs->nip, regs->link, regs->gpr[0],
519                regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
520  }
521  
522 diff -NurpP --minimal linux-3.18.5/arch/s390/Kconfig linux-3.18.5-vs2.3.7.3/arch/s390/Kconfig
523 --- linux-3.18.5/arch/s390/Kconfig      2015-01-17 02:39:40.000000000 +0000
524 +++ linux-3.18.5-vs2.3.7.3/arch/s390/Kconfig    2015-01-19 10:57:46.000000000 +0000
525 @@ -652,6 +652,8 @@ source "fs/Kconfig"
526  
527  source "arch/s390/Kconfig.debug"
528  
529 +source "kernel/vserver/Kconfig"
530 +
531  source "security/Kconfig"
532  
533  source "crypto/Kconfig"
534 diff -NurpP --minimal linux-3.18.5/arch/s390/include/asm/tlb.h linux-3.18.5-vs2.3.7.3/arch/s390/include/asm/tlb.h
535 --- linux-3.18.5/arch/s390/include/asm/tlb.h    2015-01-17 02:39:41.000000000 +0000
536 +++ linux-3.18.5-vs2.3.7.3/arch/s390/include/asm/tlb.h  2015-01-19 10:57:46.000000000 +0000
537 @@ -24,6 +24,7 @@
538  #include <linux/mm.h>
539  #include <linux/pagemap.h>
540  #include <linux/swap.h>
541 +
542  #include <asm/processor.h>
543  #include <asm/pgalloc.h>
544  #include <asm/tlbflush.h>
545 diff -NurpP --minimal linux-3.18.5/arch/s390/include/uapi/asm/unistd.h linux-3.18.5-vs2.3.7.3/arch/s390/include/uapi/asm/unistd.h
546 --- linux-3.18.5/arch/s390/include/uapi/asm/unistd.h    2015-01-17 02:39:41.000000000 +0000
547 +++ linux-3.18.5-vs2.3.7.3/arch/s390/include/uapi/asm/unistd.h  2015-01-19 10:57:46.000000000 +0000
548 @@ -200,7 +200,7 @@
549  #define __NR_clock_gettime     (__NR_timer_create+6)
550  #define __NR_clock_getres      (__NR_timer_create+7)
551  #define __NR_clock_nanosleep   (__NR_timer_create+8)
552 -/* Number 263 is reserved for vserver */
553 +#define __NR_vserver           263
554  #define __NR_statfs64          265
555  #define __NR_fstatfs64         266
556  #define __NR_remap_file_pages  267
557 diff -NurpP --minimal linux-3.18.5/arch/s390/kernel/ptrace.c linux-3.18.5-vs2.3.7.3/arch/s390/kernel/ptrace.c
558 --- linux-3.18.5/arch/s390/kernel/ptrace.c      2015-01-17 02:39:41.000000000 +0000
559 +++ linux-3.18.5-vs2.3.7.3/arch/s390/kernel/ptrace.c    2015-01-19 10:57:46.000000000 +0000
560 @@ -21,6 +21,7 @@
561  #include <linux/tracehook.h>
562  #include <linux/seccomp.h>
563  #include <linux/compat.h>
564 +#include <linux/vs_base.h>
565  #include <trace/syscall.h>
566  #include <asm/segment.h>
567  #include <asm/page.h>
568 diff -NurpP --minimal linux-3.18.5/arch/s390/kernel/syscalls.S linux-3.18.5-vs2.3.7.3/arch/s390/kernel/syscalls.S
569 --- linux-3.18.5/arch/s390/kernel/syscalls.S    2015-01-17 02:39:41.000000000 +0000
570 +++ linux-3.18.5-vs2.3.7.3/arch/s390/kernel/syscalls.S  2015-01-19 11:00:51.000000000 +0000
571 @@ -271,7 +271,7 @@ SYSCALL(sys_clock_settime,sys_clock_sett
572  SYSCALL(sys_clock_gettime,sys_clock_gettime,compat_sys_clock_gettime)  /* 260 */
573  SYSCALL(sys_clock_getres,sys_clock_getres,compat_sys_clock_getres)
574  SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,compat_sys_clock_nanosleep)
575 -NI_SYSCALL                                                     /* reserved for vserver */
576 +SYSCALL(sys_vserver,sys_vserver,sys32_vserver)
577  SYSCALL(sys_s390_fadvise64_64,sys_ni_syscall,compat_sys_s390_fadvise64_64)
578  SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64)
579  SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64)
580 diff -NurpP --minimal linux-3.18.5/arch/sh/Kconfig linux-3.18.5-vs2.3.7.3/arch/sh/Kconfig
581 --- linux-3.18.5/arch/sh/Kconfig        2015-01-16 22:18:23.000000000 +0000
582 +++ linux-3.18.5-vs2.3.7.3/arch/sh/Kconfig      2015-01-19 10:57:46.000000000 +0000
583 @@ -878,6 +878,8 @@ source "fs/Kconfig"
584  
585  source "arch/sh/Kconfig.debug"
586  
587 +source "kernel/vserver/Kconfig"
588 +
589  source "security/Kconfig"
590  
591  source "crypto/Kconfig"
592 diff -NurpP --minimal linux-3.18.5/arch/sh/kernel/irq.c linux-3.18.5-vs2.3.7.3/arch/sh/kernel/irq.c
593 --- linux-3.18.5/arch/sh/kernel/irq.c   2014-06-12 13:01:29.000000000 +0000
594 +++ linux-3.18.5-vs2.3.7.3/arch/sh/kernel/irq.c 2015-01-19 10:57:46.000000000 +0000
595 @@ -14,6 +14,7 @@
596  #include <linux/ftrace.h>
597  #include <linux/delay.h>
598  #include <linux/ratelimit.h>
599 +// #include <linux/vs_context.h>
600  #include <asm/processor.h>
601  #include <asm/machvec.h>
602  #include <asm/uaccess.h>
603 diff -NurpP --minimal linux-3.18.5/arch/sparc/Kconfig linux-3.18.5-vs2.3.7.3/arch/sparc/Kconfig
604 --- linux-3.18.5/arch/sparc/Kconfig     2015-01-17 02:39:41.000000000 +0000
605 +++ linux-3.18.5-vs2.3.7.3/arch/sparc/Kconfig   2015-01-19 10:57:46.000000000 +0000
606 @@ -557,6 +557,8 @@ source "fs/Kconfig"
607  
608  source "arch/sparc/Kconfig.debug"
609  
610 +source "kernel/vserver/Kconfig"
611 +
612  source "security/Kconfig"
613  
614  source "crypto/Kconfig"
615 diff -NurpP --minimal linux-3.18.5/arch/sparc/include/uapi/asm/unistd.h linux-3.18.5-vs2.3.7.3/arch/sparc/include/uapi/asm/unistd.h
616 --- linux-3.18.5/arch/sparc/include/uapi/asm/unistd.h   2015-01-17 02:39:41.000000000 +0000
617 +++ linux-3.18.5-vs2.3.7.3/arch/sparc/include/uapi/asm/unistd.h 2015-01-19 10:57:46.000000000 +0000
618 @@ -332,7 +332,7 @@
619  #define __NR_timer_getoverrun  264
620  #define __NR_timer_delete      265
621  #define __NR_timer_create      266
622 -/* #define __NR_vserver                267 Reserved for VSERVER */
623 +#define __NR_vserver           267
624  #define __NR_io_setup          268
625  #define __NR_io_destroy                269
626  #define __NR_io_submit         270
627 diff -NurpP --minimal linux-3.18.5/arch/sparc/kernel/systbls_32.S linux-3.18.5-vs2.3.7.3/arch/sparc/kernel/systbls_32.S
628 --- linux-3.18.5/arch/sparc/kernel/systbls_32.S 2015-01-17 02:39:41.000000000 +0000
629 +++ linux-3.18.5-vs2.3.7.3/arch/sparc/kernel/systbls_32.S       2015-01-19 10:57:46.000000000 +0000
630 @@ -70,7 +70,7 @@ sys_call_table:
631  /*250*/        .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_ni_syscall
632  /*255*/        .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
633  /*260*/        .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
634 -/*265*/        .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
635 +/*265*/        .long sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
636  /*270*/        .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
637  /*275*/        .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
638  /*280*/        .long sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
639 diff -NurpP --minimal linux-3.18.5/arch/sparc/kernel/systbls_64.S linux-3.18.5-vs2.3.7.3/arch/sparc/kernel/systbls_64.S
640 --- linux-3.18.5/arch/sparc/kernel/systbls_64.S 2015-01-17 02:39:41.000000000 +0000
641 +++ linux-3.18.5-vs2.3.7.3/arch/sparc/kernel/systbls_64.S       2015-01-19 10:57:46.000000000 +0000
642 @@ -71,7 +71,7 @@ sys_call_table32:
643  /*250*/        .word sys_mremap, compat_sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall
644         .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
645  /*260*/        .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
646 -       .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
647 +       .word sys_timer_delete, compat_sys_timer_create, sys32_vserver, compat_sys_io_setup, sys_io_destroy
648  /*270*/        .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
649         .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
650  /*280*/        .word sys_tee, sys_add_key, sys_request_key, compat_sys_keyctl, compat_sys_openat
651 @@ -150,7 +150,7 @@ sys_call_table:
652  /*250*/        .word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall
653         .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
654  /*260*/        .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
655 -       .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
656 +       .word sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
657  /*270*/        .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
658         .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
659  /*280*/        .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
660 diff -NurpP --minimal linux-3.18.5/arch/um/Kconfig.rest linux-3.18.5-vs2.3.7.3/arch/um/Kconfig.rest
661 --- linux-3.18.5/arch/um/Kconfig.rest   2012-12-11 03:30:57.000000000 +0000
662 +++ linux-3.18.5-vs2.3.7.3/arch/um/Kconfig.rest 2015-01-19 10:57:46.000000000 +0000
663 @@ -12,6 +12,8 @@ source "arch/um/Kconfig.net"
664  
665  source "fs/Kconfig"
666  
667 +source "kernel/vserver/Kconfig"
668 +
669  source "security/Kconfig"
670  
671  source "crypto/Kconfig"
672 diff -NurpP --minimal linux-3.18.5/arch/x86/Kconfig linux-3.18.5-vs2.3.7.3/arch/x86/Kconfig
673 --- linux-3.18.5/arch/x86/Kconfig       2015-02-05 18:02:39.000000000 +0000
674 +++ linux-3.18.5-vs2.3.7.3/arch/x86/Kconfig     2015-02-05 18:08:00.000000000 +0000
675 @@ -2506,6 +2506,8 @@ source "fs/Kconfig"
676  
677  source "arch/x86/Kconfig.debug"
678  
679 +source "kernel/vserver/Kconfig"
680 +
681  source "security/Kconfig"
682  
683  source "crypto/Kconfig"
684 diff -NurpP --minimal linux-3.18.5/arch/x86/syscalls/syscall_32.tbl linux-3.18.5-vs2.3.7.3/arch/x86/syscalls/syscall_32.tbl
685 --- linux-3.18.5/arch/x86/syscalls/syscall_32.tbl       2015-01-17 02:39:43.000000000 +0000
686 +++ linux-3.18.5-vs2.3.7.3/arch/x86/syscalls/syscall_32.tbl     2015-01-19 10:57:46.000000000 +0000
687 @@ -279,7 +279,7 @@
688  270    i386    tgkill                  sys_tgkill
689  271    i386    utimes                  sys_utimes                      compat_sys_utimes
690  272    i386    fadvise64_64            sys_fadvise64_64                sys32_fadvise64_64
691 -273    i386    vserver
692 +273    i386    vserver                 sys_vserver                     sys32_vserver
693  274    i386    mbind                   sys_mbind
694  275    i386    get_mempolicy           sys_get_mempolicy               compat_sys_get_mempolicy
695  276    i386    set_mempolicy           sys_set_mempolicy
696 diff -NurpP --minimal linux-3.18.5/arch/x86/syscalls/syscall_64.tbl linux-3.18.5-vs2.3.7.3/arch/x86/syscalls/syscall_64.tbl
697 --- linux-3.18.5/arch/x86/syscalls/syscall_64.tbl       2015-01-17 02:39:43.000000000 +0000
698 +++ linux-3.18.5-vs2.3.7.3/arch/x86/syscalls/syscall_64.tbl     2015-01-19 10:57:46.000000000 +0000
699 @@ -242,7 +242,7 @@
700  233    common  epoll_ctl               sys_epoll_ctl
701  234    common  tgkill                  sys_tgkill
702  235    common  utimes                  sys_utimes
703 -236    64      vserver
704 +236    64      vserver                 sys_vserver
705  237    common  mbind                   sys_mbind
706  238    common  set_mempolicy           sys_set_mempolicy
707  239    common  get_mempolicy           sys_get_mempolicy
708 diff -NurpP --minimal linux-3.18.5/block/ioprio.c linux-3.18.5-vs2.3.7.3/block/ioprio.c
709 --- linux-3.18.5/block/ioprio.c 2015-01-17 02:39:43.000000000 +0000
710 +++ linux-3.18.5-vs2.3.7.3/block/ioprio.c       2015-01-19 13:00:07.000000000 +0000
711 @@ -28,6 +28,7 @@
712  #include <linux/syscalls.h>
713  #include <linux/security.h>
714  #include <linux/pid_namespace.h>
715 +#include <linux/vs_base.h>
716  
717  int set_task_ioprio(struct task_struct *task, int ioprio)
718  {
719 @@ -105,6 +106,8 @@ SYSCALL_DEFINE3(ioprio_set, int, which,
720                         else
721                                 pgrp = find_vpid(who);
722                         do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
723 +                               if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
724 +                                       continue;
725                                 ret = set_task_ioprio(p, ioprio);
726                                 if (ret)
727                                         break;
728 @@ -200,6 +203,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which,
729                         else
730                                 pgrp = find_vpid(who);
731                         do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
732 +                               if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
733 +                                       continue;
734                                 tmpio = get_task_ioprio(p);
735                                 if (tmpio < 0)
736                                         continue;
737 diff -NurpP --minimal linux-3.18.5/drivers/block/Kconfig linux-3.18.5-vs2.3.7.3/drivers/block/Kconfig
738 --- linux-3.18.5/drivers/block/Kconfig  2014-06-12 11:33:19.000000000 +0000
739 +++ linux-3.18.5-vs2.3.7.3/drivers/block/Kconfig        2015-01-19 10:57:46.000000000 +0000
740 @@ -283,6 +283,13 @@ config BLK_DEV_CRYPTOLOOP
741  
742  source "drivers/block/drbd/Kconfig"
743  
744 +config BLK_DEV_VROOT
745 +       tristate "Virtual Root device support"
746 +       depends on QUOTACTL
747 +       ---help---
748 +         Saying Y here will allow you to use quota/fs ioctls on a shared
749 +         partition within a virtual server without compromising security.
750 +
751  config BLK_DEV_NBD
752         tristate "Network block device support"
753         depends on NET
754 diff -NurpP --minimal linux-3.18.5/drivers/block/Makefile linux-3.18.5-vs2.3.7.3/drivers/block/Makefile
755 --- linux-3.18.5/drivers/block/Makefile 2014-06-12 11:33:19.000000000 +0000
756 +++ linux-3.18.5-vs2.3.7.3/drivers/block/Makefile       2015-01-19 10:57:46.000000000 +0000
757 @@ -33,6 +33,7 @@ obj-$(CONFIG_VIRTIO_BLK)      += virtio_blk.o
758  
759  obj-$(CONFIG_BLK_DEV_SX8)      += sx8.o
760  obj-$(CONFIG_BLK_DEV_HD)       += hd.o
761 +obj-$(CONFIG_BLK_DEV_VROOT)    += vroot.o
762  
763  obj-$(CONFIG_XEN_BLKDEV_FRONTEND)      += xen-blkfront.o
764  obj-$(CONFIG_XEN_BLKDEV_BACKEND)       += xen-blkback/
765 diff -NurpP --minimal linux-3.18.5/drivers/block/loop.c linux-3.18.5-vs2.3.7.3/drivers/block/loop.c
766 --- linux-3.18.5/drivers/block/loop.c   2014-09-03 13:18:40.000000000 +0000
767 +++ linux-3.18.5-vs2.3.7.3/drivers/block/loop.c 2015-01-19 10:57:46.000000000 +0000
768 @@ -75,6 +75,7 @@
769  #include <linux/sysfs.h>
770  #include <linux/miscdevice.h>
771  #include <linux/falloc.h>
772 +#include <linux/vs_context.h>
773  #include "loop.h"
774  
775  #include <asm/uaccess.h>
776 @@ -885,6 +886,7 @@ static int loop_set_fd(struct loop_devic
777         lo->lo_blocksize = lo_blocksize;
778         lo->lo_device = bdev;
779         lo->lo_flags = lo_flags;
780 +       lo->lo_xid = vx_current_xid();
781         lo->lo_backing_file = file;
782         lo->transfer = transfer_none;
783         lo->ioctl = NULL;
784 @@ -1029,6 +1031,7 @@ static int loop_clr_fd(struct loop_devic
785         lo->lo_sizelimit = 0;
786         lo->lo_encrypt_key_size = 0;
787         lo->lo_thread = NULL;
788 +       lo->lo_xid = 0;
789         memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
790         memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
791         memset(lo->lo_file_name, 0, LO_NAME_SIZE);
792 @@ -1072,7 +1075,7 @@ loop_set_status(struct loop_device *lo,
793  
794         if (lo->lo_encrypt_key_size &&
795             !uid_eq(lo->lo_key_owner, uid) &&
796 -           !capable(CAP_SYS_ADMIN))
797 +           !vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP))
798                 return -EPERM;
799         if (lo->lo_state != Lo_bound)
800                 return -ENXIO;
801 @@ -1162,7 +1165,8 @@ loop_get_status(struct loop_device *lo,
802         memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE);
803         info->lo_encrypt_type =
804                 lo->lo_encryption ? lo->lo_encryption->number : 0;
805 -       if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
806 +       if (lo->lo_encrypt_key_size &&
807 +               vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) {
808                 info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
809                 memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
810                        lo->lo_encrypt_key_size);
811 @@ -1504,6 +1508,11 @@ static int lo_open(struct block_device *
812                 goto out;
813         }
814  
815 +       if (!vx_check(lo->lo_xid, VS_IDENT|VS_HOSTID|VS_ADMIN_P)) {
816 +               err = -EACCES;
817 +               goto out;
818 +       }
819 +
820         mutex_lock(&lo->lo_ctl_mutex);
821         lo->lo_refcnt++;
822         mutex_unlock(&lo->lo_ctl_mutex);
823 diff -NurpP --minimal linux-3.18.5/drivers/block/loop.h linux-3.18.5-vs2.3.7.3/drivers/block/loop.h
824 --- linux-3.18.5/drivers/block/loop.h   2013-11-25 15:44:28.000000000 +0000
825 +++ linux-3.18.5-vs2.3.7.3/drivers/block/loop.h 2015-01-19 10:57:46.000000000 +0000
826 @@ -41,6 +41,7 @@ struct loop_device {
827         struct loop_func_table *lo_encryption;
828         __u32           lo_init[2];
829         kuid_t          lo_key_owner;   /* Who set the key */
830 +       vxid_t          lo_xid;
831         int             (*ioctl)(struct loop_device *, int cmd, 
832                                  unsigned long arg); 
833  
834 diff -NurpP --minimal linux-3.18.5/drivers/block/vroot.c linux-3.18.5-vs2.3.7.3/drivers/block/vroot.c
835 --- linux-3.18.5/drivers/block/vroot.c  1970-01-01 00:00:00.000000000 +0000
836 +++ linux-3.18.5-vs2.3.7.3/drivers/block/vroot.c        2015-01-19 10:57:46.000000000 +0000
837 @@ -0,0 +1,290 @@
838 +/*
839 + *  linux/drivers/block/vroot.c
840 + *
841 + *  written by Herbert Pötzl, 9/11/2002
842 + *  ported to 2.6.10 by Herbert Pötzl, 30/12/2004
843 + *
844 + *  based on the loop.c code by Theodore Ts'o.
845 + *
846 + * Copyright (C) 2002-2007 by Herbert Pötzl.
847 + * Redistribution of this file is permitted under the
848 + * GNU General Public License.
849 + *
850 + */
851 +
852 +#include <linux/module.h>
853 +#include <linux/moduleparam.h>
854 +#include <linux/file.h>
855 +#include <linux/major.h>
856 +#include <linux/blkdev.h>
857 +#include <linux/slab.h>
858 +
859 +#include <linux/vroot.h>
860 +#include <linux/vs_context.h>
861 +
862 +
863 +static int max_vroot = 8;
864 +
865 +static struct vroot_device *vroot_dev;
866 +static struct gendisk **disks;
867 +
868 +
869 +static int vroot_set_dev(
870 +       struct vroot_device *vr,
871 +       struct block_device *bdev,
872 +       unsigned int arg)
873 +{
874 +       struct block_device *real_bdev;
875 +       struct file *file;
876 +       struct inode *inode;
877 +       int error;
878 +
879 +       error = -EBUSY;
880 +       if (vr->vr_state != Vr_unbound)
881 +               goto out;
882 +
883 +       error = -EBADF;
884 +       file = fget(arg);
885 +       if (!file)
886 +               goto out;
887 +
888 +       error = -EINVAL;
889 +       inode = file->f_dentry->d_inode;
890 +
891 +
892 +       if (S_ISBLK(inode->i_mode)) {
893 +               real_bdev = inode->i_bdev;
894 +               vr->vr_device = real_bdev;
895 +               __iget(real_bdev->bd_inode);
896 +       } else
897 +               goto out_fput;
898 +
899 +       vxdprintk(VXD_CBIT(misc, 0),
900 +               "vroot[%d]_set_dev: dev=" VXF_DEV,
901 +               vr->vr_number, VXD_DEV(real_bdev));
902 +
903 +       vr->vr_state = Vr_bound;
904 +       error = 0;
905 +
906 + out_fput:
907 +       fput(file);
908 + out:
909 +       return error;
910 +}
911 +
912 +static int vroot_clr_dev(
913 +       struct vroot_device *vr,
914 +       struct block_device *bdev)
915 +{
916 +       struct block_device *real_bdev;
917 +
918 +       if (vr->vr_state != Vr_bound)
919 +               return -ENXIO;
920 +       if (vr->vr_refcnt > 1)  /* we needed one fd for the ioctl */
921 +               return -EBUSY;
922 +
923 +       real_bdev = vr->vr_device;
924 +
925 +       vxdprintk(VXD_CBIT(misc, 0),
926 +               "vroot[%d]_clr_dev: dev=" VXF_DEV,
927 +               vr->vr_number, VXD_DEV(real_bdev));
928 +
929 +       bdput(real_bdev);
930 +       vr->vr_state = Vr_unbound;
931 +       vr->vr_device = NULL;
932 +       return 0;
933 +}
934 +
935 +
936 +static int vr_ioctl(struct block_device *bdev, fmode_t mode,
937 +       unsigned int cmd, unsigned long arg)
938 +{
939 +       struct vroot_device *vr = bdev->bd_disk->private_data;
940 +       int err;
941 +
942 +       down(&vr->vr_ctl_mutex);
943 +       switch (cmd) {
944 +       case VROOT_SET_DEV:
945 +               err = vroot_set_dev(vr, bdev, arg);
946 +               break;
947 +       case VROOT_CLR_DEV:
948 +               err = vroot_clr_dev(vr, bdev);
949 +               break;
950 +       default:
951 +               err = -EINVAL;
952 +               break;
953 +       }
954 +       up(&vr->vr_ctl_mutex);
955 +       return err;
956 +}
957 +
958 +static int vr_open(struct block_device *bdev, fmode_t mode)
959 +{
960 +       struct vroot_device *vr = bdev->bd_disk->private_data;
961 +
962 +       down(&vr->vr_ctl_mutex);
963 +       vr->vr_refcnt++;
964 +       up(&vr->vr_ctl_mutex);
965 +       return 0;
966 +}
967 +
968 +static void vr_release(struct gendisk *disk, fmode_t mode)
969 +{
970 +       struct vroot_device *vr = disk->private_data;
971 +
972 +       down(&vr->vr_ctl_mutex);
973 +       --vr->vr_refcnt;
974 +       up(&vr->vr_ctl_mutex);
975 +}
976 +
977 +static struct block_device_operations vr_fops = {
978 +       .owner =        THIS_MODULE,
979 +       .open =         vr_open,
980 +       .release =      vr_release,
981 +       .ioctl =        vr_ioctl,
982 +};
983 +
984 +static void vroot_make_request(struct request_queue *q, struct bio *bio)
985 +{
986 +       printk("vroot_make_request %p, %p\n", q, bio);
987 +       bio_io_error(bio);
988 +}
989 +
990 +struct block_device *__vroot_get_real_bdev(struct block_device *bdev)
991 +{
992 +       struct inode *inode = bdev->bd_inode;
993 +       struct vroot_device *vr;
994 +       struct block_device *real_bdev;
995 +       int minor = iminor(inode);
996 +
997 +       vr = &vroot_dev[minor];
998 +       real_bdev = vr->vr_device;
999 +
1000 +       vxdprintk(VXD_CBIT(misc, 0),
1001 +               "vroot[%d]_get_real_bdev: dev=" VXF_DEV,
1002 +               vr->vr_number, VXD_DEV(real_bdev));
1003 +
1004 +       if (vr->vr_state != Vr_bound)
1005 +               return ERR_PTR(-ENXIO);
1006 +
1007 +       __iget(real_bdev->bd_inode);
1008 +       return real_bdev;
1009 +}
1010 +
1011 +
1012 +
1013 +/*
1014 + * And now the modules code and kernel interface.
1015 + */
1016 +
1017 +module_param(max_vroot, int, 0);
1018 +
1019 +MODULE_PARM_DESC(max_vroot, "Maximum number of vroot devices (1-256)");
1020 +MODULE_LICENSE("GPL");
1021 +MODULE_ALIAS_BLOCKDEV_MAJOR(VROOT_MAJOR);
1022 +
1023 +MODULE_AUTHOR ("Herbert Pötzl");
1024 +MODULE_DESCRIPTION ("Virtual Root Device Mapper");
1025 +
1026 +
1027 +int __init vroot_init(void)
1028 +{
1029 +       int err, i;
1030 +
1031 +       if (max_vroot < 1 || max_vroot > 256) {
1032 +               max_vroot = MAX_VROOT_DEFAULT;
1033 +               printk(KERN_WARNING "vroot: invalid max_vroot "
1034 +                       "(must be between 1 and 256), "
1035 +                       "using default (%d)\n", max_vroot);
1036 +       }
1037 +
1038 +       if (register_blkdev(VROOT_MAJOR, "vroot"))
1039 +               return -EIO;
1040 +
1041 +       err = -ENOMEM;
1042 +       vroot_dev = kmalloc(max_vroot * sizeof(struct vroot_device), GFP_KERNEL);
1043 +       if (!vroot_dev)
1044 +               goto out_mem1;
1045 +       memset(vroot_dev, 0, max_vroot * sizeof(struct vroot_device));
1046 +
1047 +       disks = kmalloc(max_vroot * sizeof(struct gendisk *), GFP_KERNEL);
1048 +       if (!disks)
1049 +               goto out_mem2;
1050 +
1051 +       for (i = 0; i < max_vroot; i++) {
1052 +               disks[i] = alloc_disk(1);
1053 +               if (!disks[i])
1054 +                       goto out_mem3;
1055 +               disks[i]->queue = blk_alloc_queue(GFP_KERNEL);
1056 +               if (!disks[i]->queue)
1057 +                       goto out_mem3;
1058 +               blk_queue_make_request(disks[i]->queue, vroot_make_request);
1059 +       }
1060 +
1061 +       for (i = 0; i < max_vroot; i++) {
1062 +               struct vroot_device *vr = &vroot_dev[i];
1063 +               struct gendisk *disk = disks[i];
1064 +
1065 +               memset(vr, 0, sizeof(*vr));
1066 +               sema_init(&vr->vr_ctl_mutex, 1);
1067 +               vr->vr_number = i;
1068 +               disk->major = VROOT_MAJOR;
1069 +               disk->first_minor = i;
1070 +               disk->fops = &vr_fops;
1071 +               sprintf(disk->disk_name, "vroot%d", i);
1072 +               disk->private_data = vr;
1073 +       }
1074 +
1075 +       err = register_vroot_grb(&__vroot_get_real_bdev);
1076 +       if (err)
1077 +               goto out_mem3;
1078 +
1079 +       for (i = 0; i < max_vroot; i++)
1080 +               add_disk(disks[i]);
1081 +       printk(KERN_INFO "vroot: loaded (max %d devices)\n", max_vroot);
1082 +       return 0;
1083 +
1084 +out_mem3:
1085 +       while (i--)
1086 +               put_disk(disks[i]);
1087 +       kfree(disks);
1088 +out_mem2:
1089 +       kfree(vroot_dev);
1090 +out_mem1:
1091 +       unregister_blkdev(VROOT_MAJOR, "vroot");
1092 +       printk(KERN_ERR "vroot: ran out of memory\n");
1093 +       return err;
1094 +}
1095 +
1096 +void vroot_exit(void)
1097 +{
1098 +       int i;
1099 +
1100 +       if (unregister_vroot_grb(&__vroot_get_real_bdev))
1101 +               printk(KERN_WARNING "vroot: cannot unregister grb\n");
1102 +
1103 +       for (i = 0; i < max_vroot; i++) {
1104 +               del_gendisk(disks[i]);
1105 +               put_disk(disks[i]);
1106 +       }
1107 +       unregister_blkdev(VROOT_MAJOR, "vroot");
1108 +
1109 +       kfree(disks);
1110 +       kfree(vroot_dev);
1111 +}
1112 +
1113 +module_init(vroot_init);
1114 +module_exit(vroot_exit);
1115 +
1116 +#ifndef MODULE
1117 +
1118 +static int __init max_vroot_setup(char *str)
1119 +{
1120 +       max_vroot = simple_strtol(str, NULL, 0);
1121 +       return 1;
1122 +}
1123 +
1124 +__setup("max_vroot=", max_vroot_setup);
1125 +
1126 +#endif
1127 +
1128 diff -NurpP --minimal linux-3.18.5/drivers/infiniband/core/addr.c linux-3.18.5-vs2.3.7.3/drivers/infiniband/core/addr.c
1129 --- linux-3.18.5/drivers/infiniband/core/addr.c 2014-06-12 11:33:41.000000000 +0000
1130 +++ linux-3.18.5-vs2.3.7.3/drivers/infiniband/core/addr.c       2015-01-19 10:57:46.000000000 +0000
1131 @@ -284,7 +284,7 @@ static int addr6_resolve(struct sockaddr
1132  
1133         if (ipv6_addr_any(&fl6.saddr)) {
1134                 ret = ipv6_dev_get_saddr(&init_net, ip6_dst_idev(dst)->dev,
1135 -                                        &fl6.daddr, 0, &fl6.saddr);
1136 +                                        &fl6.daddr, 0, &fl6.saddr, NULL);
1137                 if (ret)
1138                         goto put;
1139  
1140 diff -NurpP --minimal linux-3.18.5/drivers/md/dm-ioctl.c linux-3.18.5-vs2.3.7.3/drivers/md/dm-ioctl.c
1141 --- linux-3.18.5/drivers/md/dm-ioctl.c  2015-01-17 02:39:51.000000000 +0000
1142 +++ linux-3.18.5-vs2.3.7.3/drivers/md/dm-ioctl.c        2015-01-19 10:57:46.000000000 +0000
1143 @@ -16,6 +16,7 @@
1144  #include <linux/dm-ioctl.h>
1145  #include <linux/hdreg.h>
1146  #include <linux/compat.h>
1147 +#include <linux/vs_context.h>
1148  
1149  #include <asm/uaccess.h>
1150  
1151 @@ -114,7 +115,8 @@ static struct hash_cell *__get_name_cell
1152         unsigned int h = hash_str(str);
1153  
1154         list_for_each_entry (hc, _name_buckets + h, name_list)
1155 -               if (!strcmp(hc->name, str)) {
1156 +               if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) &&
1157 +                       !strcmp(hc->name, str)) {
1158                         dm_get(hc->md);
1159                         return hc;
1160                 }
1161 @@ -128,7 +130,8 @@ static struct hash_cell *__get_uuid_cell
1162         unsigned int h = hash_str(str);
1163  
1164         list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
1165 -               if (!strcmp(hc->uuid, str)) {
1166 +               if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) &&
1167 +                       !strcmp(hc->uuid, str)) {
1168                         dm_get(hc->md);
1169                         return hc;
1170                 }
1171 @@ -139,13 +142,15 @@ static struct hash_cell *__get_uuid_cell
1172  static struct hash_cell *__get_dev_cell(uint64_t dev)
1173  {
1174         struct mapped_device *md;
1175 -       struct hash_cell *hc;
1176 +       struct hash_cell *hc = NULL;
1177  
1178         md = dm_get_md(huge_decode_dev(dev));
1179         if (!md)
1180                 return NULL;
1181  
1182 -       hc = dm_get_mdptr(md);
1183 +       if (vx_check(dm_get_xid(md), VS_WATCH_P | VS_IDENT))
1184 +               hc = dm_get_mdptr(md);
1185 +
1186         if (!hc) {
1187                 dm_put(md);
1188                 return NULL;
1189 @@ -467,6 +472,9 @@ typedef int (*ioctl_fn)(struct dm_ioctl
1190  
1191  static int remove_all(struct dm_ioctl *param, size_t param_size)
1192  {
1193 +       if (!vx_check(0, VS_ADMIN))
1194 +               return -EPERM;
1195 +
1196         dm_hash_remove_all(true, !!(param->flags & DM_DEFERRED_REMOVE), false);
1197         param->data_size = 0;
1198         return 0;
1199 @@ -514,6 +522,8 @@ static int list_devices(struct dm_ioctl
1200          */
1201         for (i = 0; i < NUM_BUCKETS; i++) {
1202                 list_for_each_entry (hc, _name_buckets + i, name_list) {
1203 +                       if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT))
1204 +                               continue;
1205                         needed += sizeof(struct dm_name_list);
1206                         needed += strlen(hc->name) + 1;
1207                         needed += ALIGN_MASK;
1208 @@ -537,6 +547,8 @@ static int list_devices(struct dm_ioctl
1209          */
1210         for (i = 0; i < NUM_BUCKETS; i++) {
1211                 list_for_each_entry (hc, _name_buckets + i, name_list) {
1212 +                       if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT))
1213 +                               continue;
1214                         if (old_nl)
1215                                 old_nl->next = (uint32_t) ((void *) nl -
1216                                                            (void *) old_nl);
1217 @@ -1797,8 +1809,8 @@ static int ctl_ioctl(uint command, struc
1218         size_t input_param_size;
1219         struct dm_ioctl param_kernel;
1220  
1221 -       /* only root can play with this */
1222 -       if (!capable(CAP_SYS_ADMIN))
1223 +       /* only root and certain contexts can play with this */
1224 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_MAPPER))
1225                 return -EACCES;
1226  
1227         if (_IOC_TYPE(command) != DM_IOCTL)
1228 diff -NurpP --minimal linux-3.18.5/drivers/md/dm.c linux-3.18.5-vs2.3.7.3/drivers/md/dm.c
1229 --- linux-3.18.5/drivers/md/dm.c        2015-02-05 18:02:42.000000000 +0000
1230 +++ linux-3.18.5-vs2.3.7.3/drivers/md/dm.c      2015-01-28 11:48:02.000000000 +0000
1231 @@ -19,6 +19,7 @@
1232  #include <linux/idr.h>
1233  #include <linux/hdreg.h>
1234  #include <linux/delay.h>
1235 +#include <linux/vs_base.h>
1236  
1237  #include <trace/events/block.h>
1238  
1239 @@ -134,6 +135,7 @@ struct mapped_device {
1240         struct mutex suspend_lock;
1241         atomic_t holders;
1242         atomic_t open_count;
1243 +       vxid_t xid;
1244  
1245         /*
1246          * The current mapping.
1247 @@ -397,6 +399,7 @@ int dm_deleting_md(struct mapped_device
1248  static int dm_blk_open(struct block_device *bdev, fmode_t mode)
1249  {
1250         struct mapped_device *md;
1251 +       int ret = -ENXIO;
1252  
1253         spin_lock(&_minor_lock);
1254  
1255 @@ -405,18 +408,19 @@ static int dm_blk_open(struct block_devi
1256                 goto out;
1257  
1258         if (test_bit(DMF_FREEING, &md->flags) ||
1259 -           dm_deleting_md(md)) {
1260 -               md = NULL;
1261 +           dm_deleting_md(md))
1262 +               goto out;
1263 +
1264 +       ret = -EACCES;
1265 +       if (!vx_check(md->xid, VS_IDENT|VS_HOSTID))
1266                 goto out;
1267 -       }
1268  
1269         dm_get(md);
1270         atomic_inc(&md->open_count);
1271 -
1272 +       ret = 0;
1273  out:
1274         spin_unlock(&_minor_lock);
1275 -
1276 -       return md ? 0 : -ENXIO;
1277 +       return ret;
1278  }
1279  
1280  static void dm_blk_close(struct gendisk *disk, fmode_t mode)
1281 @@ -819,6 +823,14 @@ int dm_set_geometry(struct mapped_device
1282         return 0;
1283  }
1284  
1285 +/*
1286 + * Get the xid associated with a dm device
1287 + */
1288 +vxid_t dm_get_xid(struct mapped_device *md)
1289 +{
1290 +       return md->xid;
1291 +}
1292 +
1293  /*-----------------------------------------------------------------
1294   * CRUD START:
1295   *   A more elegant soln is in the works that uses the queue
1296 @@ -2077,6 +2089,7 @@ static struct mapped_device *alloc_dev(i
1297         INIT_LIST_HEAD(&md->table_devices);
1298         spin_lock_init(&md->uevent_lock);
1299  
1300 +       md->xid = vx_current_xid();
1301         md->queue = blk_alloc_queue(GFP_KERNEL);
1302         if (!md->queue)
1303                 goto bad_queue;
1304 diff -NurpP --minimal linux-3.18.5/drivers/md/dm.h linux-3.18.5-vs2.3.7.3/drivers/md/dm.h
1305 --- linux-3.18.5/drivers/md/dm.h        2015-01-17 02:39:51.000000000 +0000
1306 +++ linux-3.18.5-vs2.3.7.3/drivers/md/dm.h      2015-01-19 10:57:46.000000000 +0000
1307 @@ -50,6 +50,8 @@ struct dm_dev_internal {
1308  struct dm_table;
1309  struct dm_md_mempools;
1310  
1311 +vxid_t dm_get_xid(struct mapped_device *md);
1312 +
1313  /*-----------------------------------------------------------------
1314   * Internal table functions.
1315   *---------------------------------------------------------------*/
1316 diff -NurpP --minimal linux-3.18.5/drivers/net/tun.c linux-3.18.5-vs2.3.7.3/drivers/net/tun.c
1317 --- linux-3.18.5/drivers/net/tun.c      2015-01-17 02:40:00.000000000 +0000
1318 +++ linux-3.18.5-vs2.3.7.3/drivers/net/tun.c    2015-01-19 10:57:46.000000000 +0000
1319 @@ -65,6 +65,7 @@
1320  #include <linux/nsproxy.h>
1321  #include <linux/virtio_net.h>
1322  #include <linux/rcupdate.h>
1323 +#include <linux/vs_network.h>
1324  #include <net/ipv6.h>
1325  #include <net/net_namespace.h>
1326  #include <net/netns/generic.h>
1327 @@ -171,6 +172,7 @@ struct tun_struct {
1328         unsigned int            flags;
1329         kuid_t                  owner;
1330         kgid_t                  group;
1331 +       vnid_t                  nid;
1332  
1333         struct net_device       *dev;
1334         netdev_features_t       set_features;
1335 @@ -404,6 +406,7 @@ static inline bool tun_not_capable(struc
1336         return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) ||
1337                   (gid_valid(tun->group) && !in_egroup_p(tun->group))) &&
1338                 !ns_capable(net->user_ns, CAP_NET_ADMIN);
1339 +               /* !cap_raised(current_cap(), CAP_NET_ADMIN) */
1340  }
1341  
1342  static void tun_set_real_num_queues(struct tun_struct *tun)
1343 @@ -1413,6 +1416,7 @@ static void tun_setup(struct net_device
1344  
1345         tun->owner = INVALID_UID;
1346         tun->group = INVALID_GID;
1347 +       tun->nid = nx_current_nid();
1348  
1349         dev->ethtool_ops = &tun_ethtool_ops;
1350         dev->destructor = tun_free_netdev;
1351 @@ -1629,7 +1633,7 @@ static int tun_set_iff(struct net *net,
1352                 int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ?
1353                              MAX_TAP_QUEUES : 1;
1354  
1355 -               if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
1356 +               if (!nx_ns_capable(net->user_ns, CAP_NET_ADMIN, NXC_TUN_CREATE))
1357                         return -EPERM;
1358                 err = security_tun_dev_create();
1359                 if (err < 0)
1360 @@ -1996,6 +2000,16 @@ static long __tun_chr_ioctl(struct file
1361                           from_kgid(&init_user_ns, tun->group));
1362                 break;
1363  
1364 +       case TUNSETNID:
1365 +               if (!capable(CAP_CONTEXT))
1366 +                       return -EPERM;
1367 +
1368 +               /* Set nid owner of the device */
1369 +               tun->nid = (vnid_t) arg;
1370 +
1371 +               tun_debug(KERN_INFO, tun, "nid owner set to %u\n", tun->nid);
1372 +               break;
1373 +
1374         case TUNSETLINK:
1375                 /* Only allow setting the type when the interface is down */
1376                 if (tun->dev->flags & IFF_UP) {
1377 diff -NurpP --minimal linux-3.18.5/drivers/scsi/cxgbi/libcxgbi.c linux-3.18.5-vs2.3.7.3/drivers/scsi/cxgbi/libcxgbi.c
1378 --- linux-3.18.5/drivers/scsi/cxgbi/libcxgbi.c  2015-01-17 02:40:05.000000000 +0000
1379 +++ linux-3.18.5-vs2.3.7.3/drivers/scsi/cxgbi/libcxgbi.c        2015-02-06 01:59:47.000000000 +0000
1380 @@ -764,7 +764,8 @@ static struct cxgbi_sock *cxgbi_check_ro
1381                 struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt);
1382  
1383                 err = ipv6_dev_get_saddr(&init_net, idev ? idev->dev : NULL,
1384 -                                        &daddr6->sin6_addr, 0, &pref_saddr);
1385 +                                        &daddr6->sin6_addr, 0, &pref_saddr,
1386 +                                        NULL);
1387                 if (err) {
1388                         pr_info("failed to get source address to reach %pI6\n",
1389                                 &daddr6->sin6_addr);
1390 diff -NurpP --minimal linux-3.18.5/drivers/tty/sysrq.c linux-3.18.5-vs2.3.7.3/drivers/tty/sysrq.c
1391 --- linux-3.18.5/drivers/tty/sysrq.c    2015-01-16 22:19:12.000000000 +0000
1392 +++ linux-3.18.5-vs2.3.7.3/drivers/tty/sysrq.c  2015-01-19 11:01:25.000000000 +0000
1393 @@ -47,6 +47,7 @@
1394  #include <linux/syscalls.h>
1395  #include <linux/of.h>
1396  #include <linux/rcupdate.h>
1397 +#include <linux/vserver/debug.h>
1398  
1399  #include <asm/ptrace.h>
1400  #include <asm/irq_regs.h>
1401 @@ -408,6 +409,21 @@ static struct sysrq_key_op sysrq_unrt_op
1402         .enable_mask    = SYSRQ_ENABLE_RTNICE,
1403  };
1404  
1405 +
1406 +#ifdef CONFIG_VSERVER_DEBUG
1407 +static void sysrq_handle_vxinfo(int key)
1408 +{
1409 +       dump_vx_info_inactive((key == 'x') ? 0 : 1);
1410 +}
1411 +
1412 +static struct sysrq_key_op sysrq_showvxinfo_op = {
1413 +       .handler        = sysrq_handle_vxinfo,
1414 +       .help_msg       = "conteXt",
1415 +       .action_msg     = "Show Context Info",
1416 +       .enable_mask    = SYSRQ_ENABLE_DUMP,
1417 +};
1418 +#endif
1419 +
1420  /* Key Operations table and lock */
1421  static DEFINE_SPINLOCK(sysrq_key_table_lock);
1422  
1423 @@ -463,7 +479,11 @@ static struct sysrq_key_op *sysrq_key_ta
1424         &sysrq_showstate_blocked_op,    /* w */
1425         /* x: May be registered on ppc/powerpc for xmon */
1426         /* x: May be registered on sparc64 for global PMU dump */
1427 +#ifdef CONFIG_VSERVER_DEBUG
1428 +       &sysrq_showvxinfo_op,           /* x */
1429 +#else
1430         NULL,                           /* x */
1431 +#endif
1432         /* y: May be registered on sparc64 for global register dump */
1433         NULL,                           /* y */
1434         &sysrq_ftrace_dump_op,          /* z */
1435 @@ -478,6 +498,8 @@ static int sysrq_key_table_key2index(int
1436                 retval = key - '0';
1437         else if ((key >= 'a') && (key <= 'z'))
1438                 retval = key + 10 - 'a';
1439 +       else if ((key >= 'A') && (key <= 'Z'))
1440 +               retval = key + 10 - 'A';
1441         else
1442                 retval = -1;
1443         return retval;
1444 diff -NurpP --minimal linux-3.18.5/drivers/tty/tty_io.c linux-3.18.5-vs2.3.7.3/drivers/tty/tty_io.c
1445 --- linux-3.18.5/drivers/tty/tty_io.c   2015-01-17 02:40:14.000000000 +0000
1446 +++ linux-3.18.5-vs2.3.7.3/drivers/tty/tty_io.c 2015-01-19 10:57:46.000000000 +0000
1447 @@ -104,6 +104,7 @@
1448  
1449  #include <linux/kmod.h>
1450  #include <linux/nsproxy.h>
1451 +#include <linux/vs_pid.h>
1452  
1453  #undef TTY_DEBUG_HANGUP
1454  
1455 @@ -2237,7 +2238,8 @@ static int tiocsti(struct tty_struct *tt
1456         char ch, mbz = 0;
1457         struct tty_ldisc *ld;
1458  
1459 -       if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
1460 +       if (((current->signal->tty != tty) &&
1461 +               !vx_capable(CAP_SYS_ADMIN, VXC_TIOCSTI)))
1462                 return -EPERM;
1463         if (get_user(ch, p))
1464                 return -EFAULT;
1465 @@ -2525,6 +2527,7 @@ static int tiocspgrp(struct tty_struct *
1466                 return -ENOTTY;
1467         if (get_user(pgrp_nr, p))
1468                 return -EFAULT;
1469 +       pgrp_nr = vx_rmap_pid(pgrp_nr);
1470         if (pgrp_nr < 0)
1471                 return -EINVAL;
1472         rcu_read_lock();
1473 diff -NurpP --minimal linux-3.18.5/fs/attr.c linux-3.18.5-vs2.3.7.3/fs/attr.c
1474 --- linux-3.18.5/fs/attr.c      2014-09-03 13:19:35.000000000 +0000
1475 +++ linux-3.18.5-vs2.3.7.3/fs/attr.c    2015-01-19 10:57:46.000000000 +0000
1476 @@ -15,6 +15,9 @@
1477  #include <linux/security.h>
1478  #include <linux/evm.h>
1479  #include <linux/ima.h>
1480 +#include <linux/proc_fs.h>
1481 +#include <linux/devpts_fs.h>
1482 +#include <linux/vs_tag.h>
1483  
1484  /**
1485   * inode_change_ok - check if attribute changes to an inode are allowed
1486 @@ -77,6 +80,10 @@ int inode_change_ok(const struct inode *
1487                         return -EPERM;
1488         }
1489  
1490 +       /* check for inode tag permission */
1491 +       if (dx_permission(inode, MAY_WRITE))
1492 +               return -EACCES;
1493 +
1494         return 0;
1495  }
1496  EXPORT_SYMBOL(inode_change_ok);
1497 @@ -147,6 +154,8 @@ void setattr_copy(struct inode *inode, c
1498                 inode->i_uid = attr->ia_uid;
1499         if (ia_valid & ATTR_GID)
1500                 inode->i_gid = attr->ia_gid;
1501 +       if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode))
1502 +               inode->i_tag = attr->ia_tag;
1503         if (ia_valid & ATTR_ATIME)
1504                 inode->i_atime = timespec_trunc(attr->ia_atime,
1505                                                 inode->i_sb->s_time_gran);
1506 @@ -197,7 +206,8 @@ int notify_change(struct dentry * dentry
1507  
1508         WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
1509  
1510 -       if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
1511 +       if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
1512 +               ATTR_TAG | ATTR_TIMES_SET)) {
1513                 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1514                         return -EPERM;
1515         }
1516 diff -NurpP --minimal linux-3.18.5/fs/block_dev.c linux-3.18.5-vs2.3.7.3/fs/block_dev.c
1517 --- linux-3.18.5/fs/block_dev.c 2015-01-17 02:40:16.000000000 +0000
1518 +++ linux-3.18.5-vs2.3.7.3/fs/block_dev.c       2015-01-19 10:57:46.000000000 +0000
1519 @@ -28,6 +28,7 @@
1520  #include <linux/log2.h>
1521  #include <linux/cleancache.h>
1522  #include <linux/aio.h>
1523 +#include <linux/vs_device.h>
1524  #include <asm/uaccess.h>
1525  #include "internal.h"
1526  
1527 @@ -575,6 +576,7 @@ struct block_device *bdget(dev_t dev)
1528                 bdev->bd_invalidated = 0;
1529                 inode->i_mode = S_IFBLK;
1530                 inode->i_rdev = dev;
1531 +               inode->i_mdev = dev;
1532                 inode->i_bdev = bdev;
1533                 inode->i_data.a_ops = &def_blk_aops;
1534                 mapping_set_gfp_mask(&inode->i_data, GFP_USER);
1535 @@ -622,6 +624,11 @@ EXPORT_SYMBOL(bdput);
1536  static struct block_device *bd_acquire(struct inode *inode)
1537  {
1538         struct block_device *bdev;
1539 +       dev_t mdev;
1540 +
1541 +       if (!vs_map_blkdev(inode->i_rdev, &mdev, DATTR_OPEN))
1542 +               return NULL;
1543 +       inode->i_mdev = mdev;
1544  
1545         spin_lock(&bdev_lock);
1546         bdev = inode->i_bdev;
1547 @@ -632,7 +639,7 @@ static struct block_device *bd_acquire(s
1548         }
1549         spin_unlock(&bdev_lock);
1550  
1551 -       bdev = bdget(inode->i_rdev);
1552 +       bdev = bdget(mdev);
1553         if (bdev) {
1554                 spin_lock(&bdev_lock);
1555                 if (!inode->i_bdev) {
1556 diff -NurpP --minimal linux-3.18.5/fs/btrfs/ctree.h linux-3.18.5-vs2.3.7.3/fs/btrfs/ctree.h
1557 --- linux-3.18.5/fs/btrfs/ctree.h       2015-01-17 02:40:16.000000000 +0000
1558 +++ linux-3.18.5-vs2.3.7.3/fs/btrfs/ctree.h     2015-01-19 10:57:46.000000000 +0000
1559 @@ -728,11 +728,14 @@ struct btrfs_inode_item {
1560         /* modification sequence number for NFS */
1561         __le64 sequence;
1562  
1563 +       __le16 tag;
1564         /*
1565          * a little future expansion, for more than this we can
1566          * just grow the inode item and version it
1567          */
1568 -       __le64 reserved[4];
1569 +       __le16 reserved16;
1570 +       __le32 reserved32;
1571 +       __le64 reserved[3];
1572         struct btrfs_timespec atime;
1573         struct btrfs_timespec ctime;
1574         struct btrfs_timespec mtime;
1575 @@ -2098,6 +2101,8 @@ struct btrfs_ioctl_defrag_range_args {
1576  #define BTRFS_DEFAULT_COMMIT_INTERVAL  (30)
1577  #define BTRFS_DEFAULT_MAX_INLINE       (8192)
1578  
1579 +#define BTRFS_MOUNT_TAGGED             (1 << 24)
1580 +
1581  #define btrfs_clear_opt(o, opt)                ((o) &= ~BTRFS_MOUNT_##opt)
1582  #define btrfs_set_opt(o, opt)          ((o) |= BTRFS_MOUNT_##opt)
1583  #define btrfs_raw_test_opt(o, opt)     ((o) & BTRFS_MOUNT_##opt)
1584 @@ -2381,6 +2386,7 @@ BTRFS_SETGET_FUNCS(inode_block_group, st
1585  BTRFS_SETGET_FUNCS(inode_nlink, struct btrfs_inode_item, nlink, 32);
1586  BTRFS_SETGET_FUNCS(inode_uid, struct btrfs_inode_item, uid, 32);
1587  BTRFS_SETGET_FUNCS(inode_gid, struct btrfs_inode_item, gid, 32);
1588 +BTRFS_SETGET_FUNCS(inode_tag, struct btrfs_inode_item, tag, 16);
1589  BTRFS_SETGET_FUNCS(inode_mode, struct btrfs_inode_item, mode, 32);
1590  BTRFS_SETGET_FUNCS(inode_rdev, struct btrfs_inode_item, rdev, 64);
1591  BTRFS_SETGET_FUNCS(inode_flags, struct btrfs_inode_item, flags, 64);
1592 @@ -2453,6 +2459,10 @@ BTRFS_SETGET_FUNCS(extent_flags, struct
1593  
1594  BTRFS_SETGET_FUNCS(extent_refs_v0, struct btrfs_extent_item_v0, refs, 32);
1595  
1596 +#define BTRFS_INODE_IXUNLINK           (1 << 24)
1597 +#define BTRFS_INODE_BARRIER            (1 << 25)
1598 +#define BTRFS_INODE_COW                        (1 << 26)
1599 +
1600  
1601  BTRFS_SETGET_FUNCS(tree_block_level, struct btrfs_tree_block_info, level, 8);
1602  
1603 @@ -3864,6 +3874,7 @@ long btrfs_ioctl(struct file *file, unsi
1604  void btrfs_update_iflags(struct inode *inode);
1605  void btrfs_inherit_iflags(struct inode *inode, struct inode *dir);
1606  int btrfs_is_empty_uuid(u8 *uuid);
1607 +int btrfs_sync_flags(struct inode *inode, int, int);
1608  int btrfs_defrag_file(struct inode *inode, struct file *file,
1609                       struct btrfs_ioctl_defrag_range_args *range,
1610                       u64 newer_than, unsigned long max_pages);
1611 diff -NurpP --minimal linux-3.18.5/fs/btrfs/disk-io.c linux-3.18.5-vs2.3.7.3/fs/btrfs/disk-io.c
1612 --- linux-3.18.5/fs/btrfs/disk-io.c     2015-02-05 18:02:44.000000000 +0000
1613 +++ linux-3.18.5-vs2.3.7.3/fs/btrfs/disk-io.c   2015-01-19 10:57:46.000000000 +0000
1614 @@ -2460,6 +2460,9 @@ int open_ctree(struct super_block *sb,
1615                 goto fail_alloc;
1616         }
1617  
1618 +       if (btrfs_test_opt(tree_root, TAGGED))
1619 +               sb->s_flags |= MS_TAGGED;
1620 +
1621         features = btrfs_super_incompat_flags(disk_super) &
1622                 ~BTRFS_FEATURE_INCOMPAT_SUPP;
1623         if (features) {
1624 diff -NurpP --minimal linux-3.18.5/fs/btrfs/inode.c linux-3.18.5-vs2.3.7.3/fs/btrfs/inode.c
1625 --- linux-3.18.5/fs/btrfs/inode.c       2015-01-17 02:40:16.000000000 +0000
1626 +++ linux-3.18.5-vs2.3.7.3/fs/btrfs/inode.c     2015-01-19 12:26:30.000000000 +0000
1627 @@ -43,6 +43,7 @@
1628  #include <linux/btrfs.h>
1629  #include <linux/blkdev.h>
1630  #include <linux/posix_acl_xattr.h>
1631 +#include <linux/vs_tag.h>
1632  #include "ctree.h"
1633  #include "disk-io.h"
1634  #include "transaction.h"
1635 @@ -3477,6 +3478,9 @@ static void btrfs_read_locked_inode(stru
1636         unsigned long ptr;
1637         int maybe_acls;
1638         u32 rdev;
1639 +       kuid_t kuid;
1640 +       kgid_t kgid;
1641 +       ktag_t ktag;
1642         int ret;
1643         bool filled = false;
1644         int first_xattr_slot;
1645 @@ -3504,8 +3508,14 @@ static void btrfs_read_locked_inode(stru
1646                                     struct btrfs_inode_item);
1647         inode->i_mode = btrfs_inode_mode(leaf, inode_item);
1648         set_nlink(inode, btrfs_inode_nlink(leaf, inode_item));
1649 -       i_uid_write(inode, btrfs_inode_uid(leaf, inode_item));
1650 -       i_gid_write(inode, btrfs_inode_gid(leaf, inode_item));
1651 +
1652 +       kuid = make_kuid(&init_user_ns, btrfs_inode_uid(leaf, inode_item));
1653 +       kgid = make_kgid(&init_user_ns, btrfs_inode_gid(leaf, inode_item));
1654 +       ktag = make_ktag(&init_user_ns, btrfs_inode_tag(leaf, inode_item));
1655 +
1656 +       inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
1657 +       inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
1658 +       inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, ktag);
1659         btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item));
1660  
1661         tspec = btrfs_inode_atime(inode_item);
1662 @@ -3629,11 +3639,18 @@ static void fill_inode_item(struct btrfs
1663                             struct inode *inode)
1664  {
1665         struct btrfs_map_token token;
1666 +       uid_t uid = from_kuid(&init_user_ns,
1667 +               TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
1668 +       gid_t gid = from_kgid(&init_user_ns,
1669 +               TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
1670  
1671         btrfs_init_map_token(&token);
1672  
1673 -       btrfs_set_token_inode_uid(leaf, item, i_uid_read(inode), &token);
1674 -       btrfs_set_token_inode_gid(leaf, item, i_gid_read(inode), &token);
1675 +       btrfs_set_token_inode_uid(leaf, item, uid, &token);
1676 +       btrfs_set_token_inode_gid(leaf, item, gid, &token);
1677 +#ifdef CONFIG_TAGGING_INTERN
1678 +       btrfs_set_token_inode_tag(leaf, item, i_tag_read(inode), &token);
1679 +#endif
1680         btrfs_set_token_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size,
1681                                    &token);
1682         btrfs_set_token_inode_mode(leaf, item, inode->i_mode, &token);
1683 @@ -9459,6 +9476,7 @@ static const struct inode_operations btr
1684         .listxattr      = btrfs_listxattr,
1685         .removexattr    = btrfs_removexattr,
1686         .permission     = btrfs_permission,
1687 +       .sync_flags     = btrfs_sync_flags,
1688         .get_acl        = btrfs_get_acl,
1689         .set_acl        = btrfs_set_acl,
1690         .update_time    = btrfs_update_time,
1691 @@ -9467,6 +9485,7 @@ static const struct inode_operations btr
1692  static const struct inode_operations btrfs_dir_ro_inode_operations = {
1693         .lookup         = btrfs_lookup,
1694         .permission     = btrfs_permission,
1695 +       .sync_flags     = btrfs_sync_flags,
1696         .get_acl        = btrfs_get_acl,
1697         .set_acl        = btrfs_set_acl,
1698         .update_time    = btrfs_update_time,
1699 @@ -9537,6 +9556,7 @@ static const struct inode_operations btr
1700         .removexattr    = btrfs_removexattr,
1701         .permission     = btrfs_permission,
1702         .fiemap         = btrfs_fiemap,
1703 +       .sync_flags     = btrfs_sync_flags,
1704         .get_acl        = btrfs_get_acl,
1705         .set_acl        = btrfs_set_acl,
1706         .update_time    = btrfs_update_time,
1707 diff -NurpP --minimal linux-3.18.5/fs/btrfs/ioctl.c linux-3.18.5-vs2.3.7.3/fs/btrfs/ioctl.c
1708 --- linux-3.18.5/fs/btrfs/ioctl.c       2015-01-17 02:40:16.000000000 +0000
1709 +++ linux-3.18.5-vs2.3.7.3/fs/btrfs/ioctl.c     2015-01-21 09:54:51.000000000 +0000
1710 @@ -107,10 +107,13 @@ static unsigned int btrfs_flags_to_ioctl
1711  {
1712         unsigned int iflags = 0;
1713  
1714 -       if (flags & BTRFS_INODE_SYNC)
1715 -               iflags |= FS_SYNC_FL;
1716         if (flags & BTRFS_INODE_IMMUTABLE)
1717                 iflags |= FS_IMMUTABLE_FL;
1718 +       if (flags & BTRFS_INODE_IXUNLINK)
1719 +               iflags |= FS_IXUNLINK_FL;
1720 +
1721 +       if (flags & BTRFS_INODE_SYNC)
1722 +               iflags |= FS_SYNC_FL;
1723         if (flags & BTRFS_INODE_APPEND)
1724                 iflags |= FS_APPEND_FL;
1725         if (flags & BTRFS_INODE_NODUMP)
1726 @@ -127,34 +130,84 @@ static unsigned int btrfs_flags_to_ioctl
1727         else if (flags & BTRFS_INODE_NOCOMPRESS)
1728                 iflags |= FS_NOCOMP_FL;
1729  
1730 +       if (flags & BTRFS_INODE_BARRIER)
1731 +               iflags |= FS_BARRIER_FL;
1732 +       if (flags & BTRFS_INODE_COW)
1733 +               iflags |= FS_COW_FL;
1734         return iflags;
1735  }
1736  
1737  /*
1738 - * Update inode->i_flags based on the btrfs internal flags.
1739 + * Update inode->i_(v)flags based on the btrfs internal flags.
1740   */
1741  void btrfs_update_iflags(struct inode *inode)
1742  {
1743         struct btrfs_inode *ip = BTRFS_I(inode);
1744         unsigned int new_fl = 0;
1745  
1746 -       if (ip->flags & BTRFS_INODE_SYNC)
1747 -               new_fl |= S_SYNC;
1748         if (ip->flags & BTRFS_INODE_IMMUTABLE)
1749                 new_fl |= S_IMMUTABLE;
1750 +       if (ip->flags & BTRFS_INODE_IXUNLINK)
1751 +               new_fl |= S_IXUNLINK;
1752 +
1753 +       if (ip->flags & BTRFS_INODE_SYNC)
1754 +               new_fl |= S_SYNC;
1755         if (ip->flags & BTRFS_INODE_APPEND)
1756                 new_fl |= S_APPEND;
1757         if (ip->flags & BTRFS_INODE_NOATIME)
1758                 new_fl |= S_NOATIME;
1759         if (ip->flags & BTRFS_INODE_DIRSYNC)
1760                 new_fl |= S_DIRSYNC;
1761 -
1762         set_mask_bits(&inode->i_flags,
1763 -                     S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC,
1764 +                     S_SYNC | S_APPEND | S_IMMUTABLE | S_IXUNLINK | S_NOATIME | S_DIRSYNC,
1765                       new_fl);
1766 +
1767 +       new_fl = 0;
1768 +       if (ip->flags & BTRFS_INODE_BARRIER)
1769 +               new_fl |= V_BARRIER;
1770 +       if (ip->flags & BTRFS_INODE_COW)
1771 +               new_fl |= V_COW;
1772 +
1773 +       set_mask_bits(&inode->i_vflags,
1774 +               V_BARRIER | V_COW, new_fl);
1775  }
1776  
1777  /*
1778 + * Update btrfs internal flags from inode->i_(v)flags.
1779 + */
1780 +void btrfs_update_flags(struct inode *inode)
1781 +{
1782 +       struct btrfs_inode *ip = BTRFS_I(inode);
1783 +
1784 +       unsigned int flags = inode->i_flags;
1785 +       unsigned int vflags = inode->i_vflags;
1786 +
1787 +       ip->flags &= ~(BTRFS_INODE_SYNC | BTRFS_INODE_APPEND |
1788 +                       BTRFS_INODE_IMMUTABLE | BTRFS_INODE_IXUNLINK |
1789 +                       BTRFS_INODE_NOATIME | BTRFS_INODE_DIRSYNC |
1790 +                       BTRFS_INODE_BARRIER | BTRFS_INODE_COW);
1791 +
1792 +       if (flags & S_IMMUTABLE)
1793 +               ip->flags |= BTRFS_INODE_IMMUTABLE;
1794 +       if (flags & S_IXUNLINK)
1795 +               ip->flags |= BTRFS_INODE_IXUNLINK;
1796 +
1797 +       if (flags & S_SYNC)
1798 +               ip->flags |= BTRFS_INODE_SYNC;
1799 +       if (flags & S_APPEND)
1800 +               ip->flags |= BTRFS_INODE_APPEND;
1801 +       if (flags & S_NOATIME)
1802 +               ip->flags |= BTRFS_INODE_NOATIME;
1803 +       if (flags & S_DIRSYNC)
1804 +               ip->flags |= BTRFS_INODE_DIRSYNC;
1805 +
1806 +       if (vflags & V_BARRIER)
1807 +               ip->flags |= BTRFS_INODE_BARRIER;
1808 +       if (vflags & V_COW)
1809 +               ip->flags |= BTRFS_INODE_COW;
1810 + }
1811 +
1812 +/*
1813   * Inherit flags from the parent inode.
1814   *
1815   * Currently only the compression flags and the cow flags are inherited.
1816 @@ -167,6 +220,7 @@ void btrfs_inherit_iflags(struct inode *
1817                 return;
1818  
1819         flags = BTRFS_I(dir)->flags;
1820 +       flags &= ~BTRFS_INODE_BARRIER;
1821  
1822         if (flags & BTRFS_INODE_NOCOMPRESS) {
1823                 BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS;
1824 @@ -185,6 +239,30 @@ void btrfs_inherit_iflags(struct inode *
1825         btrfs_update_iflags(inode);
1826  }
1827  
1828 +int btrfs_sync_flags(struct inode *inode, int flags, int vflags)
1829 +{
1830 +       struct btrfs_inode *ip = BTRFS_I(inode);
1831 +       struct btrfs_root *root = ip->root;
1832 +       struct btrfs_trans_handle *trans;
1833 +       int ret;
1834 +
1835 +       trans = btrfs_join_transaction(root);
1836 +       BUG_ON(!trans);
1837 +
1838 +       inode->i_flags = flags;
1839 +       inode->i_vflags = vflags;
1840 +       btrfs_update_flags(inode);
1841 +
1842 +       ret = btrfs_update_inode(trans, root, inode);
1843 +       BUG_ON(ret);
1844 +
1845 +       btrfs_update_iflags(inode);
1846 +       inode->i_ctime = CURRENT_TIME;
1847 +       btrfs_end_transaction(trans, root);
1848 +
1849 +       return 0;
1850 +}
1851 +
1852  static int btrfs_ioctl_getflags(struct file *file, void __user *arg)
1853  {
1854         struct btrfs_inode *ip = BTRFS_I(file_inode(file));
1855 @@ -247,21 +325,27 @@ static int btrfs_ioctl_setflags(struct f
1856  
1857         flags = btrfs_mask_flags(inode->i_mode, flags);
1858         oldflags = btrfs_flags_to_ioctl(ip->flags);
1859 -       if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) {
1860 +       if ((flags ^ oldflags) & (FS_APPEND_FL |
1861 +               FS_IMMUTABLE_FL | FS_IXUNLINK_FL)) {
1862                 if (!capable(CAP_LINUX_IMMUTABLE)) {
1863                         ret = -EPERM;
1864                         goto out_unlock;
1865                 }
1866         }
1867  
1868 -       if (flags & FS_SYNC_FL)
1869 -               ip->flags |= BTRFS_INODE_SYNC;
1870 -       else
1871 -               ip->flags &= ~BTRFS_INODE_SYNC;
1872         if (flags & FS_IMMUTABLE_FL)
1873                 ip->flags |= BTRFS_INODE_IMMUTABLE;
1874         else
1875                 ip->flags &= ~BTRFS_INODE_IMMUTABLE;
1876 +       if (flags & FS_IXUNLINK_FL)
1877 +               ip->flags |= BTRFS_INODE_IXUNLINK;
1878 +       else
1879 +               ip->flags &= ~BTRFS_INODE_IXUNLINK;
1880 +
1881 +       if (flags & FS_SYNC_FL)
1882 +               ip->flags |= BTRFS_INODE_SYNC;
1883 +       else
1884 +               ip->flags &= ~BTRFS_INODE_SYNC;
1885         if (flags & FS_APPEND_FL)
1886                 ip->flags |= BTRFS_INODE_APPEND;
1887         else
1888 diff -NurpP --minimal linux-3.18.5/fs/btrfs/super.c linux-3.18.5-vs2.3.7.3/fs/btrfs/super.c
1889 --- linux-3.18.5/fs/btrfs/super.c       2015-02-05 18:02:44.000000000 +0000
1890 +++ linux-3.18.5-vs2.3.7.3/fs/btrfs/super.c     2015-01-19 10:57:46.000000000 +0000
1891 @@ -325,7 +325,7 @@ enum {
1892         Opt_commit_interval, Opt_barrier, Opt_nodefrag, Opt_nodiscard,
1893         Opt_noenospc_debug, Opt_noflushoncommit, Opt_acl, Opt_datacow,
1894         Opt_datasum, Opt_treelog, Opt_noinode_cache,
1895 -       Opt_err,
1896 +       Opt_tag, Opt_notag, Opt_tagid, Opt_err,
1897  };
1898  
1899  static match_table_t tokens = {
1900 @@ -377,6 +377,9 @@ static match_table_t tokens = {
1901         {Opt_rescan_uuid_tree, "rescan_uuid_tree"},
1902         {Opt_fatal_errors, "fatal_errors=%s"},
1903         {Opt_commit_interval, "commit=%d"},
1904 +       {Opt_tag, "tag"},
1905 +       {Opt_notag, "notag"},
1906 +       {Opt_tagid, "tagid=%u"},
1907         {Opt_err, NULL},
1908  };
1909  
1910 @@ -743,6 +746,22 @@ int btrfs_parse_options(struct btrfs_roo
1911                                 info->commit_interval = BTRFS_DEFAULT_COMMIT_INTERVAL;
1912                         }
1913                         break;
1914 +#ifndef CONFIG_TAGGING_NONE
1915 +               case Opt_tag:
1916 +                       printk(KERN_INFO "btrfs: use tagging\n");
1917 +                       btrfs_set_opt(info->mount_opt, TAGGED);
1918 +                       break;
1919 +               case Opt_notag:
1920 +                       printk(KERN_INFO "btrfs: disabled tagging\n");
1921 +                       btrfs_clear_opt(info->mount_opt, TAGGED);
1922 +                       break;
1923 +#endif
1924 +#ifdef CONFIG_PROPAGATE
1925 +               case Opt_tagid:
1926 +                       /* use args[0] */
1927 +                       btrfs_set_opt(info->mount_opt, TAGGED);
1928 +                       break;
1929 +#endif
1930                 case Opt_err:
1931                         btrfs_info(root->fs_info, "unrecognized mount option '%s'", p);
1932                         ret = -EINVAL;
1933 @@ -1495,6 +1514,12 @@ static int btrfs_remount(struct super_bl
1934         btrfs_resize_thread_pool(fs_info,
1935                 fs_info->thread_pool_size, old_thread_pool_size);
1936  
1937 +       if (btrfs_test_opt(root, TAGGED) && !(sb->s_flags & MS_TAGGED)) {
1938 +               printk("btrfs: %s: tagging not permitted on remount.\n",
1939 +                       sb->s_id);
1940 +               return -EINVAL;
1941 +       }
1942 +
1943         if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
1944                 goto out;
1945  
1946 diff -NurpP --minimal linux-3.18.5/fs/char_dev.c linux-3.18.5-vs2.3.7.3/fs/char_dev.c
1947 --- linux-3.18.5/fs/char_dev.c  2014-01-22 20:39:05.000000000 +0000
1948 +++ linux-3.18.5-vs2.3.7.3/fs/char_dev.c        2015-01-19 10:57:46.000000000 +0000
1949 @@ -21,6 +21,8 @@
1950  #include <linux/mutex.h>
1951  #include <linux/backing-dev.h>
1952  #include <linux/tty.h>
1953 +#include <linux/vs_context.h>
1954 +#include <linux/vs_device.h>
1955  
1956  #include "internal.h"
1957  
1958 @@ -372,14 +374,21 @@ static int chrdev_open(struct inode *ino
1959         struct cdev *p;
1960         struct cdev *new = NULL;
1961         int ret = 0;
1962 +       dev_t mdev;
1963 +
1964 +       if (!vs_map_chrdev(inode->i_rdev, &mdev, DATTR_OPEN))
1965 +               return -EPERM;
1966 +       inode->i_mdev = mdev;
1967  
1968         spin_lock(&cdev_lock);
1969         p = inode->i_cdev;
1970         if (!p) {
1971                 struct kobject *kobj;
1972                 int idx;
1973 +
1974                 spin_unlock(&cdev_lock);
1975 -               kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
1976 +
1977 +               kobj = kobj_lookup(cdev_map, mdev, &idx);
1978                 if (!kobj)
1979                         return -ENXIO;
1980                 new = container_of(kobj, struct cdev, kobj);
1981 diff -NurpP --minimal linux-3.18.5/fs/dcache.c linux-3.18.5-vs2.3.7.3/fs/dcache.c
1982 --- linux-3.18.5/fs/dcache.c    2015-02-05 18:02:45.000000000 +0000
1983 +++ linux-3.18.5-vs2.3.7.3/fs/dcache.c  2015-01-19 12:06:59.000000000 +0000
1984 @@ -38,6 +38,7 @@
1985  #include <linux/prefetch.h>
1986  #include <linux/ratelimit.h>
1987  #include <linux/list_lru.h>
1988 +#include <linux/vs_limit.h>
1989  #include "internal.h"
1990  #include "mount.h"
1991  
1992 @@ -654,6 +655,7 @@ EXPORT_SYMBOL(dput);
1993  static inline void __dget_dlock(struct dentry *dentry)
1994  {
1995         dentry->d_lockref.count++;
1996 +       vx_dentry_inc(dentry);
1997  }
1998  
1999  static inline void __dget(struct dentry *dentry)
2000 @@ -666,6 +668,8 @@ struct dentry *dget_parent(struct dentry
2001         int gotref;
2002         struct dentry *ret;
2003  
2004 +       vx_dentry_dec(dentry);
2005 +
2006         /*
2007          * Do optimistic parent lookup without any
2008          * locking.
2009 @@ -1410,6 +1414,9 @@ struct dentry *__d_alloc(struct super_bl
2010         struct dentry *dentry;
2011         char *dname;
2012  
2013 +       if (!vx_dentry_avail(1))
2014 +               return NULL;
2015 +
2016         dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
2017         if (!dentry)
2018                 return NULL;
2019 @@ -1445,6 +1452,7 @@ struct dentry *__d_alloc(struct super_bl
2020  
2021         dentry->d_lockref.count = 1;
2022         dentry->d_flags = 0;
2023 +       vx_dentry_inc(dentry);
2024         spin_lock_init(&dentry->d_lock);
2025         seqcount_init(&dentry->d_seq);
2026         dentry->d_inode = NULL;
2027 @@ -2184,6 +2192,7 @@ struct dentry *__d_lookup(const struct d
2028                 }
2029  
2030                 dentry->d_lockref.count++;
2031 +               vx_dentry_inc(dentry);
2032                 found = dentry;
2033                 spin_unlock(&dentry->d_lock);
2034                 break;
2035 diff -NurpP --minimal linux-3.18.5/fs/devpts/inode.c linux-3.18.5-vs2.3.7.3/fs/devpts/inode.c
2036 --- linux-3.18.5/fs/devpts/inode.c      2014-09-03 13:19:39.000000000 +0000
2037 +++ linux-3.18.5-vs2.3.7.3/fs/devpts/inode.c    2015-01-19 10:57:47.000000000 +0000
2038 @@ -27,6 +27,7 @@
2039  #include <linux/parser.h>
2040  #include <linux/fsnotify.h>
2041  #include <linux/seq_file.h>
2042 +#include <linux/vs_base.h>
2043  
2044  #define DEVPTS_DEFAULT_MODE 0600
2045  /*
2046 @@ -38,6 +39,21 @@
2047  #define DEVPTS_DEFAULT_PTMX_MODE 0000
2048  #define PTMX_MINOR     2
2049  
2050 +static int devpts_permission(struct inode *inode, int mask)
2051 +{
2052 +       int ret = -EACCES;
2053 +
2054 +       /* devpts is xid tagged */
2055 +       if (vx_check((vxid_t)i_tag_read(inode), VS_WATCH_P | VS_IDENT))
2056 +               ret = generic_permission(inode, mask);
2057 +       return ret;
2058 +}
2059 +
2060 +static struct inode_operations devpts_file_inode_operations = {
2061 +       .permission     = devpts_permission,
2062 +};
2063 +
2064 +
2065  /*
2066   * sysctl support for setting limits on the number of Unix98 ptys allocated.
2067   * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly.
2068 @@ -350,6 +366,34 @@ static int devpts_show_options(struct se
2069         return 0;
2070  }
2071  
2072 +static int devpts_filter(struct dentry *de)
2073 +{
2074 +       vxid_t xid = 0;
2075 +
2076 +       /* devpts is xid tagged */
2077 +       if (de && de->d_inode)
2078 +               xid = (vxid_t)i_tag_read(de->d_inode);
2079 +#ifdef CONFIG_VSERVER_WARN_DEVPTS
2080 +       else
2081 +               vxwprintk_task(1, "devpts " VS_Q("%.*s") " without inode.",
2082 +                       de->d_name.len, de->d_name.name);
2083 +#endif
2084 +       return vx_check(xid, VS_WATCH_P | VS_IDENT);
2085 +}
2086 +
2087 +static int devpts_readdir(struct file * filp, struct dir_context *ctx)
2088 +{
2089 +       return dcache_readdir_filter(filp, ctx, devpts_filter);
2090 +}
2091 +
2092 +static struct file_operations devpts_dir_operations = {
2093 +       .open           = dcache_dir_open,
2094 +       .release        = dcache_dir_close,
2095 +       .llseek         = dcache_dir_lseek,
2096 +       .read           = generic_read_dir,
2097 +       .iterate        = devpts_readdir,
2098 +};
2099 +
2100  static const struct super_operations devpts_sops = {
2101         .statfs         = simple_statfs,
2102         .remount_fs     = devpts_remount,
2103 @@ -393,8 +437,10 @@ devpts_fill_super(struct super_block *s,
2104         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
2105         inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
2106         inode->i_op = &simple_dir_inode_operations;
2107 -       inode->i_fop = &simple_dir_operations;
2108 +       inode->i_fop = &devpts_dir_operations;
2109         set_nlink(inode, 2);
2110 +       /* devpts is xid tagged */
2111 +       i_tag_write(inode, (vtag_t)vx_current_xid());
2112  
2113         s->s_root = d_make_root(inode);
2114         if (s->s_root)
2115 @@ -598,6 +644,9 @@ struct inode *devpts_pty_new(struct inod
2116         inode->i_gid = opts->setgid ? opts->gid : current_fsgid();
2117         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
2118         init_special_inode(inode, S_IFCHR|opts->mode, device);
2119 +       /* devpts is xid tagged */
2120 +       i_tag_write(inode, (vtag_t)vx_current_xid());
2121 +       inode->i_op = &devpts_file_inode_operations;
2122         inode->i_private = priv;
2123  
2124         sprintf(s, "%d", index);
2125 diff -NurpP --minimal linux-3.18.5/fs/ext2/balloc.c linux-3.18.5-vs2.3.7.3/fs/ext2/balloc.c
2126 --- linux-3.18.5/fs/ext2/balloc.c       2013-05-31 13:45:23.000000000 +0000
2127 +++ linux-3.18.5-vs2.3.7.3/fs/ext2/balloc.c     2015-01-19 10:57:47.000000000 +0000
2128 @@ -693,7 +693,6 @@ ext2_try_to_allocate(struct super_block
2129                         start = 0;
2130                 end = EXT2_BLOCKS_PER_GROUP(sb);
2131         }
2132 -
2133         BUG_ON(start > EXT2_BLOCKS_PER_GROUP(sb));
2134  
2135  repeat:
2136 diff -NurpP --minimal linux-3.18.5/fs/ext2/ext2.h linux-3.18.5-vs2.3.7.3/fs/ext2/ext2.h
2137 --- linux-3.18.5/fs/ext2/ext2.h 2012-12-11 03:30:57.000000000 +0000
2138 +++ linux-3.18.5-vs2.3.7.3/fs/ext2/ext2.h       2015-01-19 10:57:47.000000000 +0000
2139 @@ -244,8 +244,12 @@ struct ext2_group_desc
2140  #define EXT2_NOTAIL_FL                 FS_NOTAIL_FL    /* file tail should not be merged */
2141  #define EXT2_DIRSYNC_FL                        FS_DIRSYNC_FL   /* dirsync behaviour (directories only) */
2142  #define EXT2_TOPDIR_FL                 FS_TOPDIR_FL    /* Top of directory hierarchies*/
2143 +#define EXT2_IXUNLINK_FL               FS_IXUNLINK_FL  /* Immutable invert on unlink */
2144  #define EXT2_RESERVED_FL               FS_RESERVED_FL  /* reserved for ext2 lib */
2145  
2146 +#define EXT2_BARRIER_FL                        FS_BARRIER_FL   /* Barrier for chroot() */
2147 +#define EXT2_COW_FL                    FS_COW_FL       /* Copy on Write marker */
2148 +
2149  #define EXT2_FL_USER_VISIBLE           FS_FL_USER_VISIBLE      /* User visible flags */
2150  #define EXT2_FL_USER_MODIFIABLE                FS_FL_USER_MODIFIABLE   /* User modifiable flags */
2151  
2152 @@ -329,7 +333,8 @@ struct ext2_inode {
2153                         __u16   i_pad1;
2154                         __le16  l_i_uid_high;   /* these 2 fields    */
2155                         __le16  l_i_gid_high;   /* were reserved2[0] */
2156 -                       __u32   l_i_reserved2;
2157 +                       __le16  l_i_tag;        /* Context Tag */
2158 +                       __u16   l_i_reserved2;
2159                 } linux2;
2160                 struct {
2161                         __u8    h_i_frag;       /* Fragment number */
2162 @@ -357,6 +362,7 @@ struct ext2_inode {
2163  #define i_gid_low      i_gid
2164  #define i_uid_high     osd2.linux2.l_i_uid_high
2165  #define i_gid_high     osd2.linux2.l_i_gid_high
2166 +#define i_raw_tag      osd2.linux2.l_i_tag
2167  #define i_reserved2    osd2.linux2.l_i_reserved2
2168  
2169  /*
2170 @@ -384,6 +390,7 @@ struct ext2_inode {
2171  #define EXT2_MOUNT_USRQUOTA            0x020000  /* user quota */
2172  #define EXT2_MOUNT_GRPQUOTA            0x040000  /* group quota */
2173  #define EXT2_MOUNT_RESERVATION         0x080000  /* Preallocation */
2174 +#define EXT2_MOUNT_TAGGED              (1<<24)   /* Enable Context Tags */
2175  
2176  
2177  #define clear_opt(o, opt)              o &= ~EXT2_MOUNT_##opt
2178 @@ -757,6 +764,7 @@ extern void ext2_set_inode_flags(struct
2179  extern void ext2_get_inode_flags(struct ext2_inode_info *);
2180  extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
2181                        u64 start, u64 len);
2182 +extern int ext2_sync_flags(struct inode *, int, int);
2183  
2184  /* ioctl.c */
2185  extern long ext2_ioctl(struct file *, unsigned int, unsigned long);
2186 diff -NurpP --minimal linux-3.18.5/fs/ext2/file.c linux-3.18.5-vs2.3.7.3/fs/ext2/file.c
2187 --- linux-3.18.5/fs/ext2/file.c 2014-09-03 13:19:39.000000000 +0000
2188 +++ linux-3.18.5-vs2.3.7.3/fs/ext2/file.c       2015-01-19 10:57:47.000000000 +0000
2189 @@ -105,4 +105,5 @@ const struct inode_operations ext2_file_
2190         .get_acl        = ext2_get_acl,
2191         .set_acl        = ext2_set_acl,
2192         .fiemap         = ext2_fiemap,
2193 +       .sync_flags     = ext2_sync_flags,
2194  };
2195 diff -NurpP --minimal linux-3.18.5/fs/ext2/ialloc.c linux-3.18.5-vs2.3.7.3/fs/ext2/ialloc.c
2196 --- linux-3.18.5/fs/ext2/ialloc.c       2014-06-12 13:02:41.000000000 +0000
2197 +++ linux-3.18.5-vs2.3.7.3/fs/ext2/ialloc.c     2015-01-19 10:57:47.000000000 +0000
2198 @@ -17,6 +17,7 @@
2199  #include <linux/backing-dev.h>
2200  #include <linux/buffer_head.h>
2201  #include <linux/random.h>
2202 +#include <linux/vs_tag.h>
2203  #include "ext2.h"
2204  #include "xattr.h"
2205  #include "acl.h"
2206 @@ -546,6 +547,7 @@ got:
2207                 inode->i_mode = mode;
2208                 inode->i_uid = current_fsuid();
2209                 inode->i_gid = dir->i_gid;
2210 +               i_tag_write(inode, dx_current_fstag(sb));
2211         } else
2212                 inode_init_owner(inode, dir, mode);
2213  
2214 diff -NurpP --minimal linux-3.18.5/fs/ext2/inode.c linux-3.18.5-vs2.3.7.3/fs/ext2/inode.c
2215 --- linux-3.18.5/fs/ext2/inode.c        2014-09-03 13:19:39.000000000 +0000
2216 +++ linux-3.18.5-vs2.3.7.3/fs/ext2/inode.c      2015-01-19 10:57:47.000000000 +0000
2217 @@ -32,6 +32,7 @@
2218  #include <linux/fiemap.h>
2219  #include <linux/namei.h>
2220  #include <linux/aio.h>
2221 +#include <linux/vs_tag.h>
2222  #include "ext2.h"
2223  #include "acl.h"
2224  #include "xip.h"
2225 @@ -1182,7 +1183,7 @@ static void ext2_truncate_blocks(struct
2226                 return;
2227         if (ext2_inode_is_fast_symlink(inode))
2228                 return;
2229 -       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
2230 +       if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
2231                 return;
2232         __ext2_truncate_blocks(inode, offset);
2233  }
2234 @@ -1273,36 +1274,61 @@ void ext2_set_inode_flags(struct inode *
2235  {
2236         unsigned int flags = EXT2_I(inode)->i_flags;
2237  
2238 -       inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
2239 +       inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK |
2240 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2241 +
2242 +
2243 +       if (flags & EXT2_IMMUTABLE_FL)
2244 +               inode->i_flags |= S_IMMUTABLE;
2245 +       if (flags & EXT2_IXUNLINK_FL)
2246 +               inode->i_flags |= S_IXUNLINK;
2247 +
2248         if (flags & EXT2_SYNC_FL)
2249                 inode->i_flags |= S_SYNC;
2250         if (flags & EXT2_APPEND_FL)
2251                 inode->i_flags |= S_APPEND;
2252 -       if (flags & EXT2_IMMUTABLE_FL)
2253 -               inode->i_flags |= S_IMMUTABLE;
2254         if (flags & EXT2_NOATIME_FL)
2255                 inode->i_flags |= S_NOATIME;
2256         if (flags & EXT2_DIRSYNC_FL)
2257                 inode->i_flags |= S_DIRSYNC;
2258 +
2259 +       inode->i_vflags &= ~(V_BARRIER | V_COW);
2260 +
2261 +       if (flags & EXT2_BARRIER_FL)
2262 +               inode->i_vflags |= V_BARRIER;
2263 +       if (flags & EXT2_COW_FL)
2264 +               inode->i_vflags |= V_COW;
2265  }
2266  
2267  /* Propagate flags from i_flags to EXT2_I(inode)->i_flags */
2268  void ext2_get_inode_flags(struct ext2_inode_info *ei)
2269  {
2270         unsigned int flags = ei->vfs_inode.i_flags;
2271 +       unsigned int vflags = ei->vfs_inode.i_vflags;
2272 +
2273 +       ei->i_flags &= ~(EXT2_SYNC_FL | EXT2_APPEND_FL |
2274 +                       EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL |
2275 +                       EXT2_NOATIME_FL | EXT2_DIRSYNC_FL |
2276 +                       EXT2_BARRIER_FL | EXT2_COW_FL);
2277 +
2278 +       if (flags & S_IMMUTABLE)
2279 +               ei->i_flags |= EXT2_IMMUTABLE_FL;
2280 +       if (flags & S_IXUNLINK)
2281 +               ei->i_flags |= EXT2_IXUNLINK_FL;
2282  
2283 -       ei->i_flags &= ~(EXT2_SYNC_FL|EXT2_APPEND_FL|
2284 -                       EXT2_IMMUTABLE_FL|EXT2_NOATIME_FL|EXT2_DIRSYNC_FL);
2285         if (flags & S_SYNC)
2286                 ei->i_flags |= EXT2_SYNC_FL;
2287         if (flags & S_APPEND)
2288                 ei->i_flags |= EXT2_APPEND_FL;
2289 -       if (flags & S_IMMUTABLE)
2290 -               ei->i_flags |= EXT2_IMMUTABLE_FL;
2291         if (flags & S_NOATIME)
2292                 ei->i_flags |= EXT2_NOATIME_FL;
2293         if (flags & S_DIRSYNC)
2294                 ei->i_flags |= EXT2_DIRSYNC_FL;
2295 +
2296 +       if (vflags & V_BARRIER)
2297 +               ei->i_flags |= EXT2_BARRIER_FL;
2298 +       if (vflags & V_COW)
2299 +               ei->i_flags |= EXT2_COW_FL;
2300  }
2301  
2302  struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
2303 @@ -1338,8 +1364,10 @@ struct inode *ext2_iget (struct super_bl
2304                 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
2305                 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
2306         }
2307 -       i_uid_write(inode, i_uid);
2308 -       i_gid_write(inode, i_gid);
2309 +       i_uid_write(inode, INOTAG_UID(DX_TAG(inode), i_uid, i_gid));
2310 +       i_gid_write(inode, INOTAG_GID(DX_TAG(inode), i_uid, i_gid));
2311 +       i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
2312 +               le16_to_cpu(raw_inode->i_raw_tag)));
2313         set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
2314         inode->i_size = le32_to_cpu(raw_inode->i_size);
2315         inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
2316 @@ -1437,8 +1465,10 @@ static int __ext2_write_inode(struct ino
2317         struct ext2_inode_info *ei = EXT2_I(inode);
2318         struct super_block *sb = inode->i_sb;
2319         ino_t ino = inode->i_ino;
2320 -       uid_t uid = i_uid_read(inode);
2321 -       gid_t gid = i_gid_read(inode);
2322 +       uid_t uid = from_kuid(&init_user_ns,
2323 +               TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
2324 +       gid_t gid = from_kgid(&init_user_ns,
2325 +               TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
2326         struct buffer_head * bh;
2327         struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);
2328         int n;
2329 @@ -1474,6 +1504,9 @@ static int __ext2_write_inode(struct ino
2330                 raw_inode->i_uid_high = 0;
2331                 raw_inode->i_gid_high = 0;
2332         }
2333 +#ifdef CONFIG_TAGGING_INTERN
2334 +       raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
2335 +#endif
2336         raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
2337         raw_inode->i_size = cpu_to_le32(inode->i_size);
2338         raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
2339 @@ -1554,7 +1587,8 @@ int ext2_setattr(struct dentry *dentry,
2340         if (is_quota_modification(inode, iattr))
2341                 dquot_initialize(inode);
2342         if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
2343 -           (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
2344 +           (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)) ||
2345 +           (iattr->ia_valid & ATTR_TAG && !tag_eq(iattr->ia_tag, inode->i_tag))) {
2346                 error = dquot_transfer(inode, iattr);
2347                 if (error)
2348                         return error;
2349 diff -NurpP --minimal linux-3.18.5/fs/ext2/ioctl.c linux-3.18.5-vs2.3.7.3/fs/ext2/ioctl.c
2350 --- linux-3.18.5/fs/ext2/ioctl.c        2013-05-31 13:45:23.000000000 +0000
2351 +++ linux-3.18.5-vs2.3.7.3/fs/ext2/ioctl.c      2015-01-19 10:57:47.000000000 +0000
2352 @@ -17,6 +17,16 @@
2353  #include <asm/uaccess.h>
2354  
2355  
2356 +int ext2_sync_flags(struct inode *inode, int flags, int vflags)
2357 +{
2358 +       inode->i_flags = flags;
2359 +       inode->i_vflags = vflags;
2360 +       ext2_get_inode_flags(EXT2_I(inode));
2361 +       inode->i_ctime = CURRENT_TIME_SEC;
2362 +       mark_inode_dirty(inode);
2363 +       return 0;
2364 +}
2365 +
2366  long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2367  {
2368         struct inode *inode = file_inode(filp);
2369 @@ -51,6 +61,11 @@ long ext2_ioctl(struct file *filp, unsig
2370  
2371                 flags = ext2_mask_flags(inode->i_mode, flags);
2372  
2373 +               if (IS_BARRIER(inode)) {
2374 +                       vxwprintk_task(1, "messing with the barrier.");
2375 +                       return -EACCES;
2376 +               }
2377 +
2378                 mutex_lock(&inode->i_mutex);
2379                 /* Is it quota file? Do not allow user to mess with it */
2380                 if (IS_NOQUOTA(inode)) {
2381 @@ -66,7 +81,9 @@ long ext2_ioctl(struct file *filp, unsig
2382                  *
2383                  * This test looks nicer. Thanks to Pauline Middelink
2384                  */
2385 -               if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
2386 +               if ((oldflags & EXT2_IMMUTABLE_FL) ||
2387 +                       ((flags ^ oldflags) & (EXT2_APPEND_FL |
2388 +                       EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL))) {
2389                         if (!capable(CAP_LINUX_IMMUTABLE)) {
2390                                 mutex_unlock(&inode->i_mutex);
2391                                 ret = -EPERM;
2392 @@ -74,7 +91,7 @@ long ext2_ioctl(struct file *filp, unsig
2393                         }
2394                 }
2395  
2396 -               flags = flags & EXT2_FL_USER_MODIFIABLE;
2397 +               flags &= EXT2_FL_USER_MODIFIABLE;
2398                 flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE;
2399                 ei->i_flags = flags;
2400  
2401 diff -NurpP --minimal linux-3.18.5/fs/ext2/namei.c linux-3.18.5-vs2.3.7.3/fs/ext2/namei.c
2402 --- linux-3.18.5/fs/ext2/namei.c        2014-06-12 11:34:57.000000000 +0000
2403 +++ linux-3.18.5-vs2.3.7.3/fs/ext2/namei.c      2015-01-19 10:57:47.000000000 +0000
2404 @@ -32,6 +32,7 @@
2405  
2406  #include <linux/pagemap.h>
2407  #include <linux/quotaops.h>
2408 +#include <linux/vs_tag.h>
2409  #include "ext2.h"
2410  #include "xattr.h"
2411  #include "acl.h"
2412 @@ -73,6 +74,7 @@ static struct dentry *ext2_lookup(struct
2413                                         (unsigned long) ino);
2414                         return ERR_PTR(-EIO);
2415                 }
2416 +               dx_propagate_tag(nd, inode);
2417         }
2418         return d_splice_alias(inode, dentry);
2419  }
2420 @@ -433,6 +435,7 @@ const struct inode_operations ext2_speci
2421         .removexattr    = generic_removexattr,
2422  #endif
2423         .setattr        = ext2_setattr,
2424 +       .sync_flags     = ext2_sync_flags,
2425         .get_acl        = ext2_get_acl,
2426         .set_acl        = ext2_set_acl,
2427  };
2428 diff -NurpP --minimal linux-3.18.5/fs/ext2/super.c linux-3.18.5-vs2.3.7.3/fs/ext2/super.c
2429 --- linux-3.18.5/fs/ext2/super.c        2015-01-17 02:40:17.000000000 +0000
2430 +++ linux-3.18.5-vs2.3.7.3/fs/ext2/super.c      2015-01-19 10:57:47.000000000 +0000
2431 @@ -395,7 +395,8 @@ enum {
2432         Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
2433         Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
2434         Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota,
2435 -       Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation
2436 +       Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation,
2437 +       Opt_tag, Opt_notag, Opt_tagid
2438  };
2439  
2440  static const match_table_t tokens = {
2441 @@ -423,6 +424,9 @@ static const match_table_t tokens = {
2442         {Opt_acl, "acl"},
2443         {Opt_noacl, "noacl"},
2444         {Opt_xip, "xip"},
2445 +       {Opt_tag, "tag"},
2446 +       {Opt_notag, "notag"},
2447 +       {Opt_tagid, "tagid=%u"},
2448         {Opt_grpquota, "grpquota"},
2449         {Opt_ignore, "noquota"},
2450         {Opt_quota, "quota"},
2451 @@ -506,6 +510,20 @@ static int parse_options(char *options,
2452                 case Opt_nouid32:
2453                         set_opt (sbi->s_mount_opt, NO_UID32);
2454                         break;
2455 +#ifndef CONFIG_TAGGING_NONE
2456 +               case Opt_tag:
2457 +                       set_opt (sbi->s_mount_opt, TAGGED);
2458 +                       break;
2459 +               case Opt_notag:
2460 +                       clear_opt (sbi->s_mount_opt, TAGGED);
2461 +                       break;
2462 +#endif
2463 +#ifdef CONFIG_PROPAGATE
2464 +               case Opt_tagid:
2465 +                       /* use args[0] */
2466 +                       set_opt (sbi->s_mount_opt, TAGGED);
2467 +                       break;
2468 +#endif
2469                 case Opt_nocheck:
2470                         clear_opt (sbi->s_mount_opt, CHECK);
2471                         break;
2472 @@ -864,6 +882,8 @@ static int ext2_fill_super(struct super_
2473         if (!parse_options((char *) data, sb))
2474                 goto failed_mount;
2475  
2476 +       if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAGGED)
2477 +               sb->s_flags |= MS_TAGGED;
2478         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2479                 ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
2480                  MS_POSIXACL : 0);
2481 @@ -1270,6 +1290,14 @@ static int ext2_remount (struct super_bl
2482                 err = -EINVAL;
2483                 goto restore_opts;
2484         }
2485 +
2486 +       if ((sbi->s_mount_opt & EXT2_MOUNT_TAGGED) &&
2487 +               !(sb->s_flags & MS_TAGGED)) {
2488 +               printk("EXT2-fs: %s: tagging not permitted on remount.\n",
2489 +                      sb->s_id);
2490 +               err = -EINVAL;
2491 +               goto restore_opts;
2492 +       }
2493  
2494         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2495                 ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
2496 diff -NurpP --minimal linux-3.18.5/fs/ext3/ext3.h linux-3.18.5-vs2.3.7.3/fs/ext3/ext3.h
2497 --- linux-3.18.5/fs/ext3/ext3.h 2015-01-17 02:40:17.000000000 +0000
2498 +++ linux-3.18.5-vs2.3.7.3/fs/ext3/ext3.h       2015-01-19 10:57:47.000000000 +0000
2499 @@ -151,10 +151,14 @@ struct ext3_group_desc
2500  #define EXT3_NOTAIL_FL                 0x00008000 /* file tail should not be merged */
2501  #define EXT3_DIRSYNC_FL                        0x00010000 /* dirsync behaviour (directories only) */
2502  #define EXT3_TOPDIR_FL                 0x00020000 /* Top of directory hierarchies*/
2503 +#define EXT3_IXUNLINK_FL               0x08000000 /* Immutable invert on unlink */
2504  #define EXT3_RESERVED_FL               0x80000000 /* reserved for ext3 lib */
2505  
2506 -#define EXT3_FL_USER_VISIBLE           0x0003DFFF /* User visible flags */
2507 -#define EXT3_FL_USER_MODIFIABLE                0x000380FF /* User modifiable flags */
2508 +#define EXT3_BARRIER_FL                        0x04000000 /* Barrier for chroot() */
2509 +#define EXT3_COW_FL                    0x20000000 /* Copy on Write marker */
2510 +
2511 +#define EXT3_FL_USER_VISIBLE           0x0103DFFF /* User visible flags */
2512 +#define EXT3_FL_USER_MODIFIABLE                0x010380FF /* User modifiable flags */
2513  
2514  /* Flags that should be inherited by new inodes from their parent. */
2515  #define EXT3_FL_INHERITED (EXT3_SECRM_FL | EXT3_UNRM_FL | EXT3_COMPR_FL |\
2516 @@ -292,7 +296,8 @@ struct ext3_inode {
2517                         __u16   i_pad1;
2518                         __le16  l_i_uid_high;   /* these 2 fields    */
2519                         __le16  l_i_gid_high;   /* were reserved2[0] */
2520 -                       __u32   l_i_reserved2;
2521 +                       __le16  l_i_tag;        /* Context Tag */
2522 +                       __u16   l_i_reserved2;
2523                 } linux2;
2524                 struct {
2525                         __u8    h_i_frag;       /* Fragment number */
2526 @@ -322,6 +327,7 @@ struct ext3_inode {
2527  #define i_gid_low      i_gid
2528  #define i_uid_high     osd2.linux2.l_i_uid_high
2529  #define i_gid_high     osd2.linux2.l_i_gid_high
2530 +#define i_raw_tag      osd2.linux2.l_i_tag
2531  #define i_reserved2    osd2.linux2.l_i_reserved2
2532  
2533  /*
2534 @@ -366,6 +372,7 @@ struct ext3_inode {
2535  #define EXT3_MOUNT_GRPQUOTA            0x200000 /* "old" group quota */
2536  #define EXT3_MOUNT_DATA_ERR_ABORT      0x400000 /* Abort on file data write
2537                                                   * error in ordered mode */
2538 +#define EXT3_MOUNT_TAGGED              (1<<24) /* Enable Context Tags */
2539  
2540  /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
2541  #ifndef _LINUX_EXT2_FS_H
2542 @@ -1063,6 +1070,7 @@ extern void ext3_get_inode_flags(struct
2543  extern void ext3_set_aops(struct inode *inode);
2544  extern int ext3_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
2545                        u64 start, u64 len);
2546 +extern int ext3_sync_flags(struct inode *, int, int);
2547  
2548  /* ioctl.c */
2549  extern long ext3_ioctl(struct file *, unsigned int, unsigned long);
2550 diff -NurpP --minimal linux-3.18.5/fs/ext3/file.c linux-3.18.5-vs2.3.7.3/fs/ext3/file.c
2551 --- linux-3.18.5/fs/ext3/file.c 2014-09-03 13:19:39.000000000 +0000
2552 +++ linux-3.18.5-vs2.3.7.3/fs/ext3/file.c       2015-01-19 10:57:47.000000000 +0000
2553 @@ -77,5 +77,6 @@ const struct inode_operations ext3_file_
2554         .get_acl        = ext3_get_acl,
2555         .set_acl        = ext3_set_acl,
2556         .fiemap         = ext3_fiemap,
2557 +       .sync_flags     = ext3_sync_flags,
2558  };
2559  
2560 diff -NurpP --minimal linux-3.18.5/fs/ext3/ialloc.c linux-3.18.5-vs2.3.7.3/fs/ext3/ialloc.c
2561 --- linux-3.18.5/fs/ext3/ialloc.c       2014-06-12 13:02:41.000000000 +0000
2562 +++ linux-3.18.5-vs2.3.7.3/fs/ext3/ialloc.c     2015-01-19 10:57:47.000000000 +0000
2563 @@ -14,6 +14,7 @@
2564  
2565  #include <linux/quotaops.h>
2566  #include <linux/random.h>
2567 +#include <linux/vs_tag.h>
2568  
2569  #include "ext3.h"
2570  #include "xattr.h"
2571 @@ -469,6 +470,7 @@ got:
2572                 inode->i_mode = mode;
2573                 inode->i_uid = current_fsuid();
2574                 inode->i_gid = dir->i_gid;
2575 +               i_tag_write(inode, dx_current_fstag(sb));
2576         } else
2577                 inode_init_owner(inode, dir, mode);
2578  
2579 diff -NurpP --minimal linux-3.18.5/fs/ext3/inode.c linux-3.18.5-vs2.3.7.3/fs/ext3/inode.c
2580 --- linux-3.18.5/fs/ext3/inode.c        2014-09-03 13:19:39.000000000 +0000
2581 +++ linux-3.18.5-vs2.3.7.3/fs/ext3/inode.c      2015-01-19 10:57:47.000000000 +0000
2582 @@ -28,6 +28,8 @@
2583  #include <linux/mpage.h>
2584  #include <linux/namei.h>
2585  #include <linux/aio.h>
2586 +#include <linux/vs_tag.h>
2587 +
2588  #include "ext3.h"
2589  #include "xattr.h"
2590  #include "acl.h"
2591 @@ -2813,36 +2815,60 @@ void ext3_set_inode_flags(struct inode *
2592  {
2593         unsigned int flags = EXT3_I(inode)->i_flags;
2594  
2595 -       inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
2596 +       inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK |
2597 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2598 +
2599 +       if (flags & EXT3_IMMUTABLE_FL)
2600 +               inode->i_flags |= S_IMMUTABLE;
2601 +       if (flags & EXT3_IXUNLINK_FL)
2602 +               inode->i_flags |= S_IXUNLINK;
2603 +
2604         if (flags & EXT3_SYNC_FL)
2605                 inode->i_flags |= S_SYNC;
2606         if (flags & EXT3_APPEND_FL)
2607                 inode->i_flags |= S_APPEND;
2608 -       if (flags & EXT3_IMMUTABLE_FL)
2609 -               inode->i_flags |= S_IMMUTABLE;
2610         if (flags & EXT3_NOATIME_FL)
2611                 inode->i_flags |= S_NOATIME;
2612         if (flags & EXT3_DIRSYNC_FL)
2613                 inode->i_flags |= S_DIRSYNC;
2614 +
2615 +       inode->i_vflags &= ~(V_BARRIER | V_COW);
2616 +
2617 +       if (flags & EXT3_BARRIER_FL)
2618 +               inode->i_vflags |= V_BARRIER;
2619 +       if (flags & EXT3_COW_FL)
2620 +               inode->i_vflags |= V_COW;
2621  }
2622  
2623  /* Propagate flags from i_flags to EXT3_I(inode)->i_flags */
2624  void ext3_get_inode_flags(struct ext3_inode_info *ei)
2625  {
2626         unsigned int flags = ei->vfs_inode.i_flags;
2627 +       unsigned int vflags = ei->vfs_inode.i_vflags;
2628 +
2629 +       ei->i_flags &= ~(EXT3_SYNC_FL | EXT3_APPEND_FL |
2630 +                       EXT3_IMMUTABLE_FL | EXT3_IXUNLINK_FL |
2631 +                       EXT3_NOATIME_FL | EXT3_DIRSYNC_FL |
2632 +                       EXT3_BARRIER_FL | EXT3_COW_FL);
2633 +
2634 +       if (flags & S_IMMUTABLE)
2635 +               ei->i_flags |= EXT3_IMMUTABLE_FL;
2636 +       if (flags & S_IXUNLINK)
2637 +               ei->i_flags |= EXT3_IXUNLINK_FL;
2638  
2639 -       ei->i_flags &= ~(EXT3_SYNC_FL|EXT3_APPEND_FL|
2640 -                       EXT3_IMMUTABLE_FL|EXT3_NOATIME_FL|EXT3_DIRSYNC_FL);
2641         if (flags & S_SYNC)
2642                 ei->i_flags |= EXT3_SYNC_FL;
2643         if (flags & S_APPEND)
2644                 ei->i_flags |= EXT3_APPEND_FL;
2645 -       if (flags & S_IMMUTABLE)
2646 -               ei->i_flags |= EXT3_IMMUTABLE_FL;
2647         if (flags & S_NOATIME)
2648                 ei->i_flags |= EXT3_NOATIME_FL;
2649         if (flags & S_DIRSYNC)
2650                 ei->i_flags |= EXT3_DIRSYNC_FL;
2651 +
2652 +       if (vflags & V_BARRIER)
2653 +               ei->i_flags |= EXT3_BARRIER_FL;
2654 +       if (vflags & V_COW)
2655 +               ei->i_flags |= EXT3_COW_FL;
2656  }
2657  
2658  struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
2659 @@ -2880,8 +2906,10 @@ struct inode *ext3_iget(struct super_blo
2660                 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
2661                 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
2662         }
2663 -       i_uid_write(inode, i_uid);
2664 -       i_gid_write(inode, i_gid);
2665 +       i_uid_write(inode, INOTAG_UID(DX_TAG(inode), i_uid, i_gid));
2666 +       i_gid_write(inode, INOTAG_GID(DX_TAG(inode), i_uid, i_gid));
2667 +       i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
2668 +               le16_to_cpu(raw_inode->i_raw_tag)));
2669         set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
2670         inode->i_size = le32_to_cpu(raw_inode->i_size);
2671         inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
2672 @@ -3053,8 +3081,10 @@ again:
2673  
2674         ext3_get_inode_flags(ei);
2675         raw_inode->i_mode = cpu_to_le16(inode->i_mode);
2676 -       i_uid = i_uid_read(inode);
2677 -       i_gid = i_gid_read(inode);
2678 +       i_uid = from_kuid(&init_user_ns,
2679 +               TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
2680 +       i_gid = from_kgid(&init_user_ns,
2681 +               TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
2682         if(!(test_opt(inode->i_sb, NO_UID32))) {
2683                 raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid));
2684                 raw_inode->i_gid_low = cpu_to_le16(low_16_bits(i_gid));
2685 @@ -3079,6 +3109,9 @@ again:
2686                 raw_inode->i_uid_high = 0;
2687                 raw_inode->i_gid_high = 0;
2688         }
2689 +#ifdef CONFIG_TAGGING_INTERN
2690 +       raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
2691 +#endif
2692         raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
2693         disksize = cpu_to_le32(ei->i_disksize);
2694         if (disksize != raw_inode->i_size) {
2695 @@ -3251,7 +3284,8 @@ int ext3_setattr(struct dentry *dentry,
2696         if (is_quota_modification(inode, attr))
2697                 dquot_initialize(inode);
2698         if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
2699 -           (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
2700 +           (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid)) ||
2701 +           (ia_valid & ATTR_TAG && !tag_eq(attr->ia_tag, inode->i_tag))) {
2702                 handle_t *handle;
2703  
2704                 /* (user+group)*(old+new) structure, inode write (sb,
2705 @@ -3273,6 +3307,8 @@ int ext3_setattr(struct dentry *dentry,
2706                         inode->i_uid = attr->ia_uid;
2707                 if (attr->ia_valid & ATTR_GID)
2708                         inode->i_gid = attr->ia_gid;
2709 +               if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
2710 +                       inode->i_tag = attr->ia_tag;
2711                 error = ext3_mark_inode_dirty(handle, inode);
2712                 ext3_journal_stop(handle);
2713         }
2714 diff -NurpP --minimal linux-3.18.5/fs/ext3/ioctl.c linux-3.18.5-vs2.3.7.3/fs/ext3/ioctl.c
2715 --- linux-3.18.5/fs/ext3/ioctl.c        2013-05-31 13:45:23.000000000 +0000
2716 +++ linux-3.18.5-vs2.3.7.3/fs/ext3/ioctl.c      2015-01-19 10:57:47.000000000 +0000
2717 @@ -12,6 +12,34 @@
2718  #include <asm/uaccess.h>
2719  #include "ext3.h"
2720  
2721 +
2722 +int ext3_sync_flags(struct inode *inode, int flags, int vflags)
2723 +{
2724 +       handle_t *handle = NULL;
2725 +       struct ext3_iloc iloc;
2726 +       int err;
2727 +
2728 +       handle = ext3_journal_start(inode, 1);
2729 +       if (IS_ERR(handle))
2730 +               return PTR_ERR(handle);
2731 +
2732 +       if (IS_SYNC(inode))
2733 +               handle->h_sync = 1;
2734 +       err = ext3_reserve_inode_write(handle, inode, &iloc);
2735 +       if (err)
2736 +               goto flags_err;
2737 +
2738 +       inode->i_flags = flags;
2739 +       inode->i_vflags = vflags;
2740 +       ext3_get_inode_flags(EXT3_I(inode));
2741 +       inode->i_ctime = CURRENT_TIME_SEC;
2742 +
2743 +       err = ext3_mark_iloc_dirty(handle, inode, &iloc);
2744 +flags_err:
2745 +       ext3_journal_stop(handle);
2746 +       return err;
2747 +}
2748 +
2749  long ext3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2750  {
2751         struct inode *inode = file_inode(filp);
2752 @@ -45,6 +73,11 @@ long ext3_ioctl(struct file *filp, unsig
2753  
2754                 flags = ext3_mask_flags(inode->i_mode, flags);
2755  
2756 +               if (IS_BARRIER(inode)) {
2757 +                       vxwprintk_task(1, "messing with the barrier.");
2758 +                       return -EACCES;
2759 +               }
2760 +
2761                 mutex_lock(&inode->i_mutex);
2762  
2763                 /* Is it quota file? Do not allow user to mess with it */
2764 @@ -63,7 +96,9 @@ long ext3_ioctl(struct file *filp, unsig
2765                  *
2766                  * This test looks nicer. Thanks to Pauline Middelink
2767                  */
2768 -               if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
2769 +               if ((oldflags & EXT3_IMMUTABLE_FL) ||
2770 +                       ((flags ^ oldflags) & (EXT3_APPEND_FL |
2771 +                       EXT3_IMMUTABLE_FL | EXT3_IXUNLINK_FL))) {
2772                         if (!capable(CAP_LINUX_IMMUTABLE))
2773                                 goto flags_out;
2774                 }
2775 @@ -88,7 +123,7 @@ long ext3_ioctl(struct file *filp, unsig
2776                 if (err)
2777                         goto flags_err;
2778  
2779 -               flags = flags & EXT3_FL_USER_MODIFIABLE;
2780 +               flags &= EXT3_FL_USER_MODIFIABLE;
2781                 flags |= oldflags & ~EXT3_FL_USER_MODIFIABLE;
2782                 ei->i_flags = flags;
2783  
2784 diff -NurpP --minimal linux-3.18.5/fs/ext3/namei.c linux-3.18.5-vs2.3.7.3/fs/ext3/namei.c
2785 --- linux-3.18.5/fs/ext3/namei.c        2014-06-12 11:34:57.000000000 +0000
2786 +++ linux-3.18.5-vs2.3.7.3/fs/ext3/namei.c      2015-01-19 10:57:47.000000000 +0000
2787 @@ -25,6 +25,8 @@
2788   */
2789  
2790  #include <linux/quotaops.h>
2791 +#include <linux/vs_tag.h>
2792 +
2793  #include "ext3.h"
2794  #include "namei.h"
2795  #include "xattr.h"
2796 @@ -915,6 +917,7 @@ restart:
2797                                         submit_bh(READ | REQ_META | REQ_PRIO,
2798                                                   bh);
2799                                 }
2800 +               dx_propagate_tag(nd, inode);
2801                         }
2802                 }
2803                 if ((bh = bh_use[ra_ptr++]) == NULL)
2804 @@ -2568,6 +2571,7 @@ const struct inode_operations ext3_dir_i
2805         .listxattr      = ext3_listxattr,
2806         .removexattr    = generic_removexattr,
2807  #endif
2808 +       .sync_flags     = ext3_sync_flags,
2809         .get_acl        = ext3_get_acl,
2810         .set_acl        = ext3_set_acl,
2811  };
2812 diff -NurpP --minimal linux-3.18.5/fs/ext3/super.c linux-3.18.5-vs2.3.7.3/fs/ext3/super.c
2813 --- linux-3.18.5/fs/ext3/super.c        2015-01-17 02:40:17.000000000 +0000
2814 +++ linux-3.18.5-vs2.3.7.3/fs/ext3/super.c      2015-01-19 10:57:47.000000000 +0000
2815 @@ -826,7 +826,8 @@ enum {
2816         Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
2817         Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
2818         Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
2819 -       Opt_resize, Opt_usrquota, Opt_grpquota
2820 +       Opt_resize, Opt_usrquota, Opt_grpquota,
2821 +       Opt_tag, Opt_notag, Opt_tagid
2822  };
2823  
2824  static const match_table_t tokens = {
2825 @@ -884,6 +885,9 @@ static const match_table_t tokens = {
2826         {Opt_barrier, "barrier"},
2827         {Opt_nobarrier, "nobarrier"},
2828         {Opt_resize, "resize"},
2829 +       {Opt_tag, "tag"},
2830 +       {Opt_notag, "notag"},
2831 +       {Opt_tagid, "tagid=%u"},
2832         {Opt_err, NULL},
2833  };
2834  
2835 @@ -1056,6 +1060,20 @@ static int parse_options (char *options,
2836                 case Opt_nouid32:
2837                         set_opt (sbi->s_mount_opt, NO_UID32);
2838                         break;
2839 +#ifndef CONFIG_TAGGING_NONE
2840 +               case Opt_tag:
2841 +                       set_opt (sbi->s_mount_opt, TAGGED);
2842 +                       break;
2843 +               case Opt_notag:
2844 +                       clear_opt (sbi->s_mount_opt, TAGGED);
2845 +                       break;
2846 +#endif
2847 +#ifdef CONFIG_PROPAGATE
2848 +               case Opt_tagid:
2849 +                       /* use args[0] */
2850 +                       set_opt (sbi->s_mount_opt, TAGGED);
2851 +                       break;
2852 +#endif
2853                 case Opt_nocheck:
2854                         clear_opt (sbi->s_mount_opt, CHECK);
2855                         break;
2856 @@ -1781,6 +1799,9 @@ static int ext3_fill_super (struct super
2857                             NULL, 0))
2858                 goto failed_mount;
2859  
2860 +       if (EXT3_SB(sb)->s_mount_opt & EXT3_MOUNT_TAGGED)
2861 +               sb->s_flags |= MS_TAGGED;
2862 +
2863         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2864                 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
2865  
2866 @@ -2678,6 +2699,14 @@ static int ext3_remount (struct super_bl
2867         if (test_opt(sb, ABORT))
2868                 ext3_abort(sb, __func__, "Abort forced by user");
2869  
2870 +       if ((sbi->s_mount_opt & EXT3_MOUNT_TAGGED) &&
2871 +               !(sb->s_flags & MS_TAGGED)) {
2872 +               printk("EXT3-fs: %s: tagging not permitted on remount.\n",
2873 +                       sb->s_id);
2874 +               err = -EINVAL;
2875 +               goto restore_opts;
2876 +       }
2877 +
2878         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2879                 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
2880  
2881 diff -NurpP --minimal linux-3.18.5/fs/ext4/ext4.h linux-3.18.5-vs2.3.7.3/fs/ext4/ext4.h
2882 --- linux-3.18.5/fs/ext4/ext4.h 2015-01-17 02:40:17.000000000 +0000
2883 +++ linux-3.18.5-vs2.3.7.3/fs/ext4/ext4.h       2015-01-19 10:57:47.000000000 +0000
2884 @@ -385,7 +385,10 @@ struct flex_groups {
2885  #define EXT4_EXTENTS_FL                        0x00080000 /* Inode uses extents */
2886  #define EXT4_EA_INODE_FL               0x00200000 /* Inode used for large EA */
2887  #define EXT4_EOFBLOCKS_FL              0x00400000 /* Blocks allocated beyond EOF */
2888 +#define EXT4_BARRIER_FL                        0x04000000 /* Barrier for chroot() */
2889 +#define EXT4_IXUNLINK_FL               0x08000000 /* Immutable invert on unlink */
2890  #define EXT4_INLINE_DATA_FL            0x10000000 /* Inode has inline data. */
2891 +#define EXT4_COW_FL                    0x20000000 /* Copy on Write marker */
2892  #define EXT4_RESERVED_FL               0x80000000 /* reserved for ext4 lib */
2893  
2894  #define EXT4_FL_USER_VISIBLE           0x004BDFFF /* User visible flags */
2895 @@ -671,7 +674,7 @@ struct ext4_inode {
2896                         __le16  l_i_uid_high;   /* these 2 fields */
2897                         __le16  l_i_gid_high;   /* were reserved2[0] */
2898                         __le16  l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
2899 -                       __le16  l_i_reserved;
2900 +                       __le16  l_i_tag;        /* Context Tag */
2901                 } linux2;
2902                 struct {
2903                         __le16  h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
2904 @@ -791,6 +794,7 @@ do {                                                                               \
2905  #define i_gid_low      i_gid
2906  #define i_uid_high     osd2.linux2.l_i_uid_high
2907  #define i_gid_high     osd2.linux2.l_i_gid_high
2908 +#define i_raw_tag      osd2.linux2.l_i_tag
2909  #define i_checksum_lo  osd2.linux2.l_i_checksum_lo
2910  
2911  #elif defined(__GNU__)
2912 @@ -980,6 +984,7 @@ struct ext4_inode_info {
2913  #define EXT4_MOUNT_POSIX_ACL           0x08000 /* POSIX Access Control Lists */
2914  #define EXT4_MOUNT_NO_AUTO_DA_ALLOC    0x10000 /* No auto delalloc mapping */
2915  #define EXT4_MOUNT_BARRIER             0x20000 /* Use block barriers */
2916 +#define EXT4_MOUNT_TAGGED              0x40000 /* Enable Context Tags */
2917  #define EXT4_MOUNT_QUOTA               0x80000 /* Some quota option set */
2918  #define EXT4_MOUNT_USRQUOTA            0x100000 /* "old" user quota */
2919  #define EXT4_MOUNT_GRPQUOTA            0x200000 /* "old" group quota */
2920 @@ -2644,6 +2649,7 @@ extern struct buffer_head *ext4_get_firs
2921  extern int ext4_inline_data_fiemap(struct inode *inode,
2922                                    struct fiemap_extent_info *fieinfo,
2923                                    int *has_inline);
2924 +extern int ext4_sync_flags(struct inode *, int, int);
2925  extern int ext4_try_to_evict_inline_data(handle_t *handle,
2926                                          struct inode *inode,
2927                                          int needed);
2928 diff -NurpP --minimal linux-3.18.5/fs/ext4/file.c linux-3.18.5-vs2.3.7.3/fs/ext4/file.c
2929 --- linux-3.18.5/fs/ext4/file.c 2015-01-17 02:40:17.000000000 +0000
2930 +++ linux-3.18.5-vs2.3.7.3/fs/ext4/file.c       2015-01-19 10:57:47.000000000 +0000
2931 @@ -610,5 +610,6 @@ const struct inode_operations ext4_file_
2932         .get_acl        = ext4_get_acl,
2933         .set_acl        = ext4_set_acl,
2934         .fiemap         = ext4_fiemap,
2935 +       .sync_flags     = ext4_sync_flags,
2936  };
2937  
2938 diff -NurpP --minimal linux-3.18.5/fs/ext4/ialloc.c linux-3.18.5-vs2.3.7.3/fs/ext4/ialloc.c
2939 --- linux-3.18.5/fs/ext4/ialloc.c       2015-01-17 02:40:17.000000000 +0000
2940 +++ linux-3.18.5-vs2.3.7.3/fs/ext4/ialloc.c     2015-01-19 10:57:47.000000000 +0000
2941 @@ -22,6 +22,7 @@
2942  #include <linux/random.h>
2943  #include <linux/bitops.h>
2944  #include <linux/blkdev.h>
2945 +#include <linux/vs_tag.h>
2946  #include <asm/byteorder.h>
2947  
2948  #include "ext4.h"
2949 @@ -754,6 +755,7 @@ struct inode *__ext4_new_inode(handle_t
2950                 inode->i_mode = mode;
2951                 inode->i_uid = current_fsuid();
2952                 inode->i_gid = dir->i_gid;
2953 +               i_tag_write(inode, dx_current_fstag(sb));
2954         } else
2955                 inode_init_owner(inode, dir, mode);
2956         dquot_initialize(inode);
2957 diff -NurpP --minimal linux-3.18.5/fs/ext4/inode.c linux-3.18.5-vs2.3.7.3/fs/ext4/inode.c
2958 --- linux-3.18.5/fs/ext4/inode.c        2015-01-17 02:40:17.000000000 +0000
2959 +++ linux-3.18.5-vs2.3.7.3/fs/ext4/inode.c      2015-01-19 12:50:18.000000000 +0000
2960 @@ -39,6 +39,7 @@
2961  #include <linux/ratelimit.h>
2962  #include <linux/aio.h>
2963  #include <linux/bitops.h>
2964 +#include <linux/vs_tag.h>
2965  
2966  #include "ext4_jbd2.h"
2967  #include "xattr.h"
2968 @@ -3811,42 +3812,66 @@ void ext4_set_inode_flags(struct inode *
2969         unsigned int flags = EXT4_I(inode)->i_flags;
2970         unsigned int new_fl = 0;
2971  
2972 +       if (flags & EXT4_IMMUTABLE_FL)
2973 +               new_fl |= S_IMMUTABLE;
2974 +       if (flags & EXT4_IXUNLINK_FL)
2975 +               new_fl |= S_IXUNLINK;
2976 +
2977         if (flags & EXT4_SYNC_FL)
2978                 new_fl |= S_SYNC;
2979         if (flags & EXT4_APPEND_FL)
2980                 new_fl |= S_APPEND;
2981 -       if (flags & EXT4_IMMUTABLE_FL)
2982 -               new_fl |= S_IMMUTABLE;
2983         if (flags & EXT4_NOATIME_FL)
2984                 new_fl |= S_NOATIME;
2985         if (flags & EXT4_DIRSYNC_FL)
2986                 new_fl |= S_DIRSYNC;
2987         inode_set_flags(inode, new_fl,
2988 -                       S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
2989 +               S_IXUNLINK | S_IMMUTABLE |
2990 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2991 +
2992 +       new_fl = 0;
2993 +       if (flags & EXT4_BARRIER_FL)
2994 +               new_fl |= V_BARRIER;
2995 +       if (flags & EXT4_COW_FL)
2996 +               new_fl |= V_COW;
2997 +
2998 +       set_mask_bits(&inode->i_vflags,
2999 +               V_BARRIER | V_COW, new_fl);
3000  }
3001  
3002  /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
3003  void ext4_get_inode_flags(struct ext4_inode_info *ei)
3004  {
3005 -       unsigned int vfs_fl;
3006 +       unsigned int vfs_fl, vfs_vf;
3007         unsigned long old_fl, new_fl;
3008  
3009         do {
3010                 vfs_fl = ei->vfs_inode.i_flags;
3011 +               vfs_vf = ei->vfs_inode.i_vflags;
3012                 old_fl = ei->i_flags;
3013                 new_fl = old_fl & ~(EXT4_SYNC_FL|EXT4_APPEND_FL|
3014                                 EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL|
3015 -                               EXT4_DIRSYNC_FL);
3016 +                               EXT4_DIRSYNC_FL|EXT4_BARRIER_FL|
3017 +                               EXT4_COW_FL);
3018 +
3019 +               if (vfs_fl & S_IMMUTABLE)
3020 +                       new_fl |= EXT4_IMMUTABLE_FL;
3021 +               if (vfs_fl & S_IXUNLINK)
3022 +                       new_fl |= EXT4_IXUNLINK_FL;
3023 +
3024                 if (vfs_fl & S_SYNC)
3025                         new_fl |= EXT4_SYNC_FL;
3026                 if (vfs_fl & S_APPEND)
3027                         new_fl |= EXT4_APPEND_FL;
3028 -               if (vfs_fl & S_IMMUTABLE)
3029 -                       new_fl |= EXT4_IMMUTABLE_FL;
3030                 if (vfs_fl & S_NOATIME)
3031                         new_fl |= EXT4_NOATIME_FL;
3032                 if (vfs_fl & S_DIRSYNC)
3033                         new_fl |= EXT4_DIRSYNC_FL;
3034 +
3035 +               if (vfs_vf & V_BARRIER)
3036 +                       new_fl |= EXT4_BARRIER_FL;
3037 +               if (vfs_vf & V_COW)
3038 +                       new_fl |= EXT4_COW_FL;
3039         } while (cmpxchg(&ei->i_flags, old_fl, new_fl) != old_fl);
3040  }
3041  
3042 @@ -3950,8 +3975,10 @@ struct inode *ext4_iget(struct super_blo
3043                 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
3044                 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
3045         }
3046 -       i_uid_write(inode, i_uid);
3047 -       i_gid_write(inode, i_gid);
3048 +       i_uid_write(inode, INOTAG_UID(DX_TAG(inode), i_uid, i_gid));
3049 +       i_gid_write(inode, INOTAG_GID(DX_TAG(inode), i_uid, i_gid));
3050 +       i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
3051 +               le16_to_cpu(raw_inode->i_raw_tag)));
3052         set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
3053  
3054         ext4_clear_state_flags(ei);     /* Only relevant on 32-bit archs */
3055 @@ -4191,8 +4218,10 @@ static int ext4_do_update_inode(handle_t
3056  
3057         ext4_get_inode_flags(ei);
3058         raw_inode->i_mode = cpu_to_le16(inode->i_mode);
3059 -       i_uid = i_uid_read(inode);
3060 -       i_gid = i_gid_read(inode);
3061 +       i_uid = from_kuid(&init_user_ns,
3062 +               TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
3063 +       i_gid = from_kgid(&init_user_ns,
3064 +               TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
3065         if (!(test_opt(inode->i_sb, NO_UID32))) {
3066                 raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid));
3067                 raw_inode->i_gid_low = cpu_to_le16(low_16_bits(i_gid));
3068 @@ -4215,6 +4244,9 @@ static int ext4_do_update_inode(handle_t
3069                 raw_inode->i_uid_high = 0;
3070                 raw_inode->i_gid_high = 0;
3071         }
3072 +#ifdef CONFIG_TAGGING_INTERN
3073 +       raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
3074 +#endif
3075         raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
3076  
3077         EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode);
3078 @@ -4458,7 +4490,8 @@ int ext4_setattr(struct dentry *dentry,
3079         if (is_quota_modification(inode, attr))
3080                 dquot_initialize(inode);
3081         if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
3082 -           (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
3083 +           (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid)) ||
3084 +           (ia_valid & ATTR_TAG && !tag_eq(attr->ia_tag, inode->i_tag))) {
3085                 handle_t *handle;
3086  
3087                 /* (user+group)*(old+new) structure, inode write (sb,
3088 @@ -4481,6 +4514,8 @@ int ext4_setattr(struct dentry *dentry,
3089                         inode->i_uid = attr->ia_uid;
3090                 if (attr->ia_valid & ATTR_GID)
3091                         inode->i_gid = attr->ia_gid;
3092 +               if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
3093 +                       inode->i_tag = attr->ia_tag;
3094                 error = ext4_mark_inode_dirty(handle, inode);
3095                 ext4_journal_stop(handle);
3096         }
3097 diff -NurpP --minimal linux-3.18.5/fs/ext4/ioctl.c linux-3.18.5-vs2.3.7.3/fs/ext4/ioctl.c
3098 --- linux-3.18.5/fs/ext4/ioctl.c        2015-01-17 02:40:17.000000000 +0000
3099 +++ linux-3.18.5-vs2.3.7.3/fs/ext4/ioctl.c      2015-01-19 10:57:47.000000000 +0000
3100 @@ -14,6 +14,7 @@
3101  #include <linux/compat.h>
3102  #include <linux/mount.h>
3103  #include <linux/file.h>
3104 +#include <linux/vs_tag.h>
3105  #include <asm/uaccess.h>
3106  #include "ext4_jbd2.h"
3107  #include "ext4.h"
3108 @@ -198,6 +199,33 @@ journal_err_out:
3109         return err;
3110  }
3111  
3112 +int ext4_sync_flags(struct inode *inode, int flags, int vflags)
3113 +{
3114 +       handle_t *handle = NULL;
3115 +       struct ext4_iloc iloc;
3116 +       int err;
3117 +
3118 +       handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
3119 +       if (IS_ERR(handle))
3120 +               return PTR_ERR(handle);
3121 +
3122 +       if (IS_SYNC(inode))
3123 +               ext4_handle_sync(handle);
3124 +       err = ext4_reserve_inode_write(handle, inode, &iloc);
3125 +       if (err)
3126 +               goto flags_err;
3127 +
3128 +       inode->i_flags = flags;
3129 +       inode->i_vflags = vflags;
3130 +       ext4_get_inode_flags(EXT4_I(inode));
3131 +       inode->i_ctime = ext4_current_time(inode);
3132 +
3133 +       err = ext4_mark_iloc_dirty(handle, inode, &iloc);
3134 +flags_err:
3135 +       ext4_journal_stop(handle);
3136 +       return err;
3137 +}
3138 +
3139  long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3140  {
3141         struct inode *inode = file_inode(filp);
3142 @@ -231,6 +259,11 @@ long ext4_ioctl(struct file *filp, unsig
3143  
3144                 flags = ext4_mask_flags(inode->i_mode, flags);
3145  
3146 +               if (IS_BARRIER(inode)) {
3147 +                       vxwprintk_task(1, "messing with the barrier.");
3148 +                       return -EACCES;
3149 +               }
3150 +
3151                 err = -EPERM;
3152                 mutex_lock(&inode->i_mutex);
3153                 /* Is it quota file? Do not allow user to mess with it */
3154 @@ -248,7 +281,9 @@ long ext4_ioctl(struct file *filp, unsig
3155                  *
3156                  * This test looks nicer. Thanks to Pauline Middelink
3157                  */
3158 -               if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
3159 +               if ((oldflags & EXT4_IMMUTABLE_FL) ||
3160 +                       ((flags ^ oldflags) & (EXT4_APPEND_FL |
3161 +                       EXT4_IMMUTABLE_FL | EXT4_IXUNLINK_FL))) {
3162                         if (!capable(CAP_LINUX_IMMUTABLE))
3163                                 goto flags_out;
3164                 }
3165 diff -NurpP --minimal linux-3.18.5/fs/ext4/namei.c linux-3.18.5-vs2.3.7.3/fs/ext4/namei.c
3166 --- linux-3.18.5/fs/ext4/namei.c        2015-01-17 02:40:17.000000000 +0000
3167 +++ linux-3.18.5-vs2.3.7.3/fs/ext4/namei.c      2015-01-19 10:57:47.000000000 +0000
3168 @@ -34,6 +34,7 @@
3169  #include <linux/quotaops.h>
3170  #include <linux/buffer_head.h>
3171  #include <linux/bio.h>
3172 +#include <linux/vs_tag.h>
3173  #include "ext4.h"
3174  #include "ext4_jbd2.h"
3175  
3176 @@ -1279,6 +1280,7 @@ restart:
3177                                         ll_rw_block(READ | REQ_META | REQ_PRIO,
3178                                                     1, &bh);
3179                         }
3180 +               dx_propagate_tag(nd, inode);
3181                 }
3182                 if ((bh = bh_use[ra_ptr++]) == NULL)
3183                         goto next;
3184 @@ -3539,6 +3541,7 @@ const struct inode_operations ext4_dir_i
3185         .get_acl        = ext4_get_acl,
3186         .set_acl        = ext4_set_acl,
3187         .fiemap         = ext4_fiemap,
3188 +       .sync_flags     = ext4_sync_flags,
3189  };
3190  
3191  const struct inode_operations ext4_special_inode_operations = {
3192 diff -NurpP --minimal linux-3.18.5/fs/ext4/super.c linux-3.18.5-vs2.3.7.3/fs/ext4/super.c
3193 --- linux-3.18.5/fs/ext4/super.c        2015-01-17 02:40:17.000000000 +0000
3194 +++ linux-3.18.5-vs2.3.7.3/fs/ext4/super.c      2015-01-19 10:57:47.000000000 +0000
3195 @@ -1146,7 +1146,7 @@ enum {
3196         Opt_inode_readahead_blks, Opt_journal_ioprio,
3197         Opt_dioread_nolock, Opt_dioread_lock,
3198         Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
3199 -       Opt_max_dir_size_kb,
3200 +       Opt_max_dir_size_kb, Opt_tag, Opt_notag, Opt_tagid
3201  };
3202  
3203  static const match_table_t tokens = {
3204 @@ -1227,6 +1227,9 @@ static const match_table_t tokens = {
3205         {Opt_removed, "reservation"},   /* mount option from ext2/3 */
3206         {Opt_removed, "noreservation"}, /* mount option from ext2/3 */
3207         {Opt_removed, "journal=%u"},    /* mount option from ext2/3 */
3208 +       {Opt_tag, "tag"},
3209 +       {Opt_notag, "notag"},
3210 +       {Opt_tagid, "tagid=%u"},
3211         {Opt_err, NULL},
3212  };
3213  
3214 @@ -1459,6 +1462,20 @@ static int handle_mount_opt(struct super
3215         case Opt_i_version:
3216                 sb->s_flags |= MS_I_VERSION;
3217                 return 1;
3218 +#ifndef CONFIG_TAGGING_NONE
3219 +       case Opt_tag:
3220 +               set_opt(sb, TAGGED);
3221 +               return 1;
3222 +       case Opt_notag:
3223 +               clear_opt(sb, TAGGED);
3224 +               return 1;
3225 +#endif
3226 +#ifdef CONFIG_PROPAGATE
3227 +       case Opt_tagid:
3228 +               /* use args[0] */
3229 +               set_opt(sb, TAGGED);
3230 +               return 1;
3231 +#endif
3232         }
3233  
3234         for (m = ext4_mount_opts; m->token != Opt_err; m++)
3235 @@ -3600,6 +3617,9 @@ static int ext4_fill_super(struct super_
3236                         clear_opt(sb, DELALLOC);
3237         }
3238  
3239 +       if (EXT4_SB(sb)->s_mount_opt & EXT4_MOUNT_TAGGED)
3240 +               sb->s_flags |= MS_TAGGED;
3241 +
3242         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
3243                 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
3244  
3245 @@ -4872,6 +4892,14 @@ static int ext4_remount(struct super_blo
3246         if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED)
3247                 ext4_abort(sb, "Abort forced by user");
3248  
3249 +       if ((sbi->s_mount_opt & EXT4_MOUNT_TAGGED) &&
3250 +               !(sb->s_flags & MS_TAGGED)) {
3251 +               printk("EXT4-fs: %s: tagging not permitted on remount.\n",
3252 +                       sb->s_id);
3253 +               err = -EINVAL;
3254 +               goto restore_opts;
3255 +       }
3256 +
3257         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
3258                 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
3259  
3260 diff -NurpP --minimal linux-3.18.5/fs/fcntl.c linux-3.18.5-vs2.3.7.3/fs/fcntl.c
3261 --- linux-3.18.5/fs/fcntl.c     2015-01-17 02:40:17.000000000 +0000
3262 +++ linux-3.18.5-vs2.3.7.3/fs/fcntl.c   2015-01-19 11:48:08.000000000 +0000
3263 @@ -22,6 +22,7 @@
3264  #include <linux/pid_namespace.h>
3265  #include <linux/user_namespace.h>
3266  #include <linux/shmem_fs.h>
3267 +#include <linux/vs_limit.h>
3268  
3269  #include <asm/poll.h>
3270  #include <asm/siginfo.h>
3271 @@ -385,6 +386,8 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, f
3272  
3273         if (!f.file)
3274                 goto out;
3275 +       if (!vx_files_avail(1))
3276 +               goto out;
3277  
3278         if (unlikely(f.file->f_mode & FMODE_PATH)) {
3279                 if (!check_fcntl_cmd(cmd))
3280 diff -NurpP --minimal linux-3.18.5/fs/file.c linux-3.18.5-vs2.3.7.3/fs/file.c
3281 --- linux-3.18.5/fs/file.c      2015-01-17 02:40:17.000000000 +0000
3282 +++ linux-3.18.5-vs2.3.7.3/fs/file.c    2015-01-19 10:57:47.000000000 +0000
3283 @@ -22,6 +22,7 @@
3284  #include <linux/spinlock.h>
3285  #include <linux/rcupdate.h>
3286  #include <linux/workqueue.h>
3287 +#include <linux/vs_limit.h>
3288  
3289  int sysctl_nr_open __read_mostly = 1024*1024;
3290  int sysctl_nr_open_min = BITS_PER_LONG;
3291 @@ -309,6 +310,8 @@ struct files_struct *dup_fd(struct files
3292                 struct file *f = *old_fds++;
3293                 if (f) {
3294                         get_file(f);
3295 +                       /* TODO: sum it first for check and performance */
3296 +                       vx_openfd_inc(open_files - i);
3297                 } else {
3298                         /*
3299                          * The fd may be claimed in the fd bitmap but not yet
3300 @@ -369,9 +372,11 @@ static struct fdtable *close_files(struc
3301                                         filp_close(file, files);
3302                                         cond_resched_rcu_qs();
3303                                 }
3304 +                               vx_openfd_dec(i);
3305                         }
3306                         i++;
3307                         set >>= 1;
3308 +                       cond_resched();
3309                 }
3310         }
3311  
3312 @@ -487,6 +492,7 @@ repeat:
3313         else
3314                 __clear_close_on_exec(fd, fdt);
3315         error = fd;
3316 +       vx_openfd_inc(fd);
3317  #if 1
3318         /* Sanity check */
3319         if (rcu_access_pointer(fdt->fd[fd]) != NULL) {
3320 @@ -517,6 +523,7 @@ static void __put_unused_fd(struct files
3321         __clear_open_fd(fd, fdt);
3322         if (fd < files->next_fd)
3323                 files->next_fd = fd;
3324 +       vx_openfd_dec(fd);
3325  }
3326  
3327  void put_unused_fd(unsigned int fd)
3328 @@ -784,6 +791,8 @@ __releases(&files->file_lock)
3329  
3330         if (tofree)
3331                 filp_close(tofree, files);
3332 +       else
3333 +               vx_openfd_inc(fd);      /* fd was unused */
3334  
3335         return fd;
3336  
3337 diff -NurpP --minimal linux-3.18.5/fs/file_table.c linux-3.18.5-vs2.3.7.3/fs/file_table.c
3338 --- linux-3.18.5/fs/file_table.c        2015-01-17 02:40:17.000000000 +0000
3339 +++ linux-3.18.5-vs2.3.7.3/fs/file_table.c      2015-01-19 12:36:42.000000000 +0000
3340 @@ -26,6 +26,8 @@
3341  #include <linux/hardirq.h>
3342  #include <linux/task_work.h>
3343  #include <linux/ima.h>
3344 +#include <linux/vs_limit.h>
3345 +#include <linux/vs_context.h>
3346  
3347  #include <linux/atomic.h>
3348  
3349 @@ -137,6 +139,8 @@ struct file *get_empty_filp(void)
3350         mutex_init(&f->f_pos_lock);
3351         eventpoll_init_file(f);
3352         /* f->f_version: 0 */
3353 +       f->f_xid = vx_current_xid();
3354 +       vx_files_inc(f);
3355         return f;
3356  
3357  over:
3358 @@ -219,6 +223,8 @@ static void __fput(struct file *file)
3359                 put_write_access(inode);
3360                 __mnt_drop_write(mnt);
3361         }
3362 +       vx_files_dec(file);
3363 +       file->f_xid = 0;
3364         file->f_path.dentry = NULL;
3365         file->f_path.mnt = NULL;
3366         file->f_inode = NULL;
3367 @@ -305,6 +311,8 @@ void put_filp(struct file *file)
3368  {
3369         if (atomic_long_dec_and_test(&file->f_count)) {
3370                 security_file_free(file);
3371 +               vx_files_dec(file);
3372 +               file->f_xid = 0;
3373                 file_free(file);
3374         }
3375  }
3376 diff -NurpP --minimal linux-3.18.5/fs/fs_struct.c linux-3.18.5-vs2.3.7.3/fs/fs_struct.c
3377 --- linux-3.18.5/fs/fs_struct.c 2014-01-22 20:39:06.000000000 +0000
3378 +++ linux-3.18.5-vs2.3.7.3/fs/fs_struct.c       2015-01-19 10:57:47.000000000 +0000
3379 @@ -4,6 +4,7 @@
3380  #include <linux/path.h>
3381  #include <linux/slab.h>
3382  #include <linux/fs_struct.h>
3383 +#include <linux/vserver/global.h>
3384  #include "internal.h"
3385  
3386  /*
3387 @@ -87,6 +88,7 @@ void free_fs_struct(struct fs_struct *fs
3388  {
3389         path_put(&fs->root);
3390         path_put(&fs->pwd);
3391 +       atomic_dec(&vs_global_fs);
3392         kmem_cache_free(fs_cachep, fs);
3393  }
3394  
3395 @@ -124,6 +126,7 @@ struct fs_struct *copy_fs_struct(struct
3396                 fs->pwd = old->pwd;
3397                 path_get(&fs->pwd);
3398                 spin_unlock(&old->lock);
3399 +               atomic_inc(&vs_global_fs);
3400         }
3401         return fs;
3402  }
3403 diff -NurpP --minimal linux-3.18.5/fs/gfs2/file.c linux-3.18.5-vs2.3.7.3/fs/gfs2/file.c
3404 --- linux-3.18.5/fs/gfs2/file.c 2015-01-17 02:40:17.000000000 +0000
3405 +++ linux-3.18.5-vs2.3.7.3/fs/gfs2/file.c       2015-01-19 10:57:47.000000000 +0000
3406 @@ -138,6 +138,9 @@ static const u32 fsflags_to_gfs2[32] = {
3407         [12] = GFS2_DIF_EXHASH,
3408         [14] = GFS2_DIF_INHERIT_JDATA,
3409         [17] = GFS2_DIF_TOPDIR,
3410 +       [27] = GFS2_DIF_IXUNLINK,
3411 +       [26] = GFS2_DIF_BARRIER,
3412 +       [29] = GFS2_DIF_COW,
3413  };
3414  
3415  static const u32 gfs2_to_fsflags[32] = {
3416 @@ -148,6 +151,9 @@ static const u32 gfs2_to_fsflags[32] = {
3417         [gfs2fl_ExHash] = FS_INDEX_FL,
3418         [gfs2fl_TopLevel] = FS_TOPDIR_FL,
3419         [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL,
3420 +       [gfs2fl_IXUnlink] = FS_IXUNLINK_FL,
3421 +       [gfs2fl_Barrier] = FS_BARRIER_FL,
3422 +       [gfs2fl_Cow] = FS_COW_FL,
3423  };
3424  
3425  static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
3426 @@ -178,12 +184,18 @@ void gfs2_set_inode_flags(struct inode *
3427  {
3428         struct gfs2_inode *ip = GFS2_I(inode);
3429         unsigned int flags = inode->i_flags;
3430 +       unsigned int vflags = inode->i_vflags;
3431 +
3432 +       flags &= ~(S_IMMUTABLE | S_IXUNLINK |
3433 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC | S_NOSEC);
3434  
3435 -       flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_NOSEC);
3436         if ((ip->i_eattr == 0) && !is_sxid(inode->i_mode))
3437                 inode->i_flags |= S_NOSEC;
3438         if (ip->i_diskflags & GFS2_DIF_IMMUTABLE)
3439                 flags |= S_IMMUTABLE;
3440 +       if (ip->i_diskflags & GFS2_DIF_IXUNLINK)
3441 +               flags |= S_IXUNLINK;
3442 +
3443         if (ip->i_diskflags & GFS2_DIF_APPENDONLY)
3444                 flags |= S_APPEND;
3445         if (ip->i_diskflags & GFS2_DIF_NOATIME)
3446 @@ -191,6 +203,43 @@ void gfs2_set_inode_flags(struct inode *
3447         if (ip->i_diskflags & GFS2_DIF_SYNC)
3448                 flags |= S_SYNC;
3449         inode->i_flags = flags;
3450 +
3451 +       vflags &= ~(V_BARRIER | V_COW);
3452 +
3453 +       if (ip->i_diskflags & GFS2_DIF_BARRIER)
3454 +               vflags |= V_BARRIER;
3455 +       if (ip->i_diskflags & GFS2_DIF_COW)
3456 +               vflags |= V_COW;
3457 +       inode->i_vflags = vflags;
3458 +}
3459 +
3460 +void gfs2_get_inode_flags(struct inode *inode)
3461 +{
3462 +       struct gfs2_inode *ip = GFS2_I(inode);
3463 +       unsigned int flags = inode->i_flags;
3464 +       unsigned int vflags = inode->i_vflags;
3465 +
3466 +       ip->i_diskflags &= ~(GFS2_DIF_APPENDONLY |
3467 +                       GFS2_DIF_NOATIME | GFS2_DIF_SYNC |
3468 +                       GFS2_DIF_IMMUTABLE | GFS2_DIF_IXUNLINK |
3469 +                       GFS2_DIF_BARRIER | GFS2_DIF_COW);
3470 +
3471 +       if (flags & S_IMMUTABLE)
3472 +               ip->i_diskflags |= GFS2_DIF_IMMUTABLE;
3473 +       if (flags & S_IXUNLINK)
3474 +               ip->i_diskflags |= GFS2_DIF_IXUNLINK;
3475 +
3476 +       if (flags & S_APPEND)
3477 +               ip->i_diskflags |= GFS2_DIF_APPENDONLY;
3478 +       if (flags & S_NOATIME)
3479 +               ip->i_diskflags |= GFS2_DIF_NOATIME;
3480 +       if (flags & S_SYNC)
3481 +               ip->i_diskflags |= GFS2_DIF_SYNC;
3482 +
3483 +       if (vflags & V_BARRIER)
3484 +               ip->i_diskflags |= GFS2_DIF_BARRIER;
3485 +       if (vflags & V_COW)
3486 +               ip->i_diskflags |= GFS2_DIF_COW;
3487  }
3488  
3489  /* Flags that can be set by user space */
3490 @@ -304,6 +353,37 @@ static int gfs2_set_flags(struct file *f
3491         return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA);
3492  }
3493  
3494 +int gfs2_sync_flags(struct inode *inode, int flags, int vflags)
3495 +{
3496 +       struct gfs2_inode *ip = GFS2_I(inode);
3497 +       struct gfs2_sbd *sdp = GFS2_SB(inode);
3498 +       struct buffer_head *bh;
3499 +       struct gfs2_holder gh;
3500 +       int error;
3501 +
3502 +       error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
3503 +       if (error)
3504 +               return error;
3505 +       error = gfs2_trans_begin(sdp, RES_DINODE, 0);
3506 +       if (error)
3507 +               goto out;
3508 +       error = gfs2_meta_inode_buffer(ip, &bh);
3509 +       if (error)
3510 +               goto out_trans_end;
3511 +       gfs2_trans_add_meta(ip->i_gl, bh);
3512 +       inode->i_flags = flags;
3513 +       inode->i_vflags = vflags;
3514 +       gfs2_get_inode_flags(inode);
3515 +       gfs2_dinode_out(ip, bh->b_data);
3516 +       brelse(bh);
3517 +       gfs2_set_aops(inode);
3518 +out_trans_end:
3519 +       gfs2_trans_end(sdp);
3520 +out:
3521 +       gfs2_glock_dq_uninit(&gh);
3522 +       return error;
3523 +}
3524 +
3525  static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3526  {
3527         switch(cmd) {
3528 diff -NurpP --minimal linux-3.18.5/fs/gfs2/inode.h linux-3.18.5-vs2.3.7.3/fs/gfs2/inode.h
3529 --- linux-3.18.5/fs/gfs2/inode.h        2013-11-25 15:45:01.000000000 +0000
3530 +++ linux-3.18.5-vs2.3.7.3/fs/gfs2/inode.h      2015-01-19 10:57:47.000000000 +0000
3531 @@ -118,6 +118,7 @@ extern const struct file_operations gfs2
3532  extern const struct file_operations gfs2_dir_fops_nolock;
3533  
3534  extern void gfs2_set_inode_flags(struct inode *inode);
3535 +extern int gfs2_sync_flags(struct inode *inode, int flags, int vflags);
3536   
3537  #ifdef CONFIG_GFS2_FS_LOCKING_DLM
3538  extern const struct file_operations gfs2_file_fops;
3539 diff -NurpP --minimal linux-3.18.5/fs/hostfs/hostfs.h linux-3.18.5-vs2.3.7.3/fs/hostfs/hostfs.h
3540 --- linux-3.18.5/fs/hostfs/hostfs.h     2015-01-16 22:19:18.000000000 +0000
3541 +++ linux-3.18.5-vs2.3.7.3/fs/hostfs/hostfs.h   2015-01-19 10:57:47.000000000 +0000
3542 @@ -42,6 +42,7 @@ struct hostfs_iattr {
3543         unsigned short  ia_mode;
3544         uid_t           ia_uid;
3545         gid_t           ia_gid;
3546 +       vtag_t          ia_tag;
3547         loff_t          ia_size;
3548         struct timespec ia_atime;
3549         struct timespec ia_mtime;
3550 diff -NurpP --minimal linux-3.18.5/fs/inode.c linux-3.18.5-vs2.3.7.3/fs/inode.c
3551 --- linux-3.18.5/fs/inode.c     2015-01-16 22:19:18.000000000 +0000
3552 +++ linux-3.18.5-vs2.3.7.3/fs/inode.c   2015-01-19 10:57:47.000000000 +0000
3553 @@ -18,6 +18,7 @@
3554  #include <linux/buffer_head.h> /* for inode_has_buffers */
3555  #include <linux/ratelimit.h>
3556  #include <linux/list_lru.h>
3557 +#include <linux/vs_tag.h>
3558  #include "internal.h"
3559  
3560  /*
3561 @@ -129,6 +130,8 @@ int inode_init_always(struct super_block
3562         struct address_space *const mapping = &inode->i_data;
3563  
3564         inode->i_sb = sb;
3565 +
3566 +       /* essential because of inode slab reuse */
3567         inode->i_blkbits = sb->s_blocksize_bits;
3568         inode->i_flags = 0;
3569         atomic_set(&inode->i_count, 1);
3570 @@ -138,6 +141,7 @@ int inode_init_always(struct super_block
3571         inode->i_opflags = 0;
3572         i_uid_write(inode, 0);
3573         i_gid_write(inode, 0);
3574 +       i_tag_write(inode, 0);
3575         atomic_set(&inode->i_writecount, 0);
3576         inode->i_size = 0;
3577         inode->i_blocks = 0;
3578 @@ -150,6 +154,7 @@ int inode_init_always(struct super_block
3579         inode->i_bdev = NULL;
3580         inode->i_cdev = NULL;
3581         inode->i_rdev = 0;
3582 +       inode->i_mdev = 0;
3583         inode->dirtied_when = 0;
3584  
3585         if (security_inode_alloc(inode))
3586 @@ -478,6 +483,8 @@ void __insert_inode_hash(struct inode *i
3587  }
3588  EXPORT_SYMBOL(__insert_inode_hash);
3589  
3590 +EXPORT_SYMBOL_GPL(__iget);
3591 +
3592  /**
3593   *     __remove_inode_hash - remove an inode from the hash
3594   *     @inode: inode to unhash
3595 @@ -1795,9 +1802,11 @@ void init_special_inode(struct inode *in
3596         if (S_ISCHR(mode)) {
3597                 inode->i_fop = &def_chr_fops;
3598                 inode->i_rdev = rdev;
3599 +               inode->i_mdev = rdev;
3600         } else if (S_ISBLK(mode)) {
3601                 inode->i_fop = &def_blk_fops;
3602                 inode->i_rdev = rdev;
3603 +               inode->i_mdev = rdev;
3604         } else if (S_ISFIFO(mode))
3605                 inode->i_fop = &pipefifo_fops;
3606         else if (S_ISSOCK(mode))
3607 @@ -1826,6 +1835,7 @@ void inode_init_owner(struct inode *inod
3608         } else
3609                 inode->i_gid = current_fsgid();
3610         inode->i_mode = mode;
3611 +       i_tag_write(inode, dx_current_fstag(inode->i_sb));
3612  }
3613  EXPORT_SYMBOL(inode_init_owner);
3614  
3615 diff -NurpP --minimal linux-3.18.5/fs/ioctl.c linux-3.18.5-vs2.3.7.3/fs/ioctl.c
3616 --- linux-3.18.5/fs/ioctl.c     2014-01-22 20:39:06.000000000 +0000
3617 +++ linux-3.18.5-vs2.3.7.3/fs/ioctl.c   2015-01-19 10:57:47.000000000 +0000
3618 @@ -15,6 +15,9 @@
3619  #include <linux/writeback.h>
3620  #include <linux/buffer_head.h>
3621  #include <linux/falloc.h>
3622 +#include <linux/proc_fs.h>
3623 +#include <linux/vserver/inode.h>
3624 +#include <linux/vs_tag.h>
3625  
3626  #include <asm/ioctls.h>
3627  
3628 diff -NurpP --minimal linux-3.18.5/fs/jfs/file.c linux-3.18.5-vs2.3.7.3/fs/jfs/file.c
3629 --- linux-3.18.5/fs/jfs/file.c  2014-09-03 13:19:40.000000000 +0000
3630 +++ linux-3.18.5-vs2.3.7.3/fs/jfs/file.c        2015-01-19 10:58:03.000000000 +0000
3631 @@ -110,7 +110,8 @@ int jfs_setattr(struct dentry *dentry, s
3632         if (is_quota_modification(inode, iattr))
3633                 dquot_initialize(inode);
3634         if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
3635 -           (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
3636 +           (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)) ||
3637 +           (iattr->ia_valid & ATTR_TAG && !tag_eq(iattr->ia_tag, inode->i_tag))) {
3638                 rc = dquot_transfer(inode, iattr);
3639                 if (rc)
3640                         return rc;
3641 @@ -146,6 +147,7 @@ const struct inode_operations jfs_file_i
3642         .get_acl        = jfs_get_acl,
3643         .set_acl        = jfs_set_acl,
3644  #endif
3645 +       .sync_flags     = jfs_sync_flags,
3646  };
3647  
3648  const struct file_operations jfs_file_operations = {
3649 diff -NurpP --minimal linux-3.18.5/fs/jfs/ioctl.c linux-3.18.5-vs2.3.7.3/fs/jfs/ioctl.c
3650 --- linux-3.18.5/fs/jfs/ioctl.c 2013-05-31 13:45:24.000000000 +0000
3651 +++ linux-3.18.5-vs2.3.7.3/fs/jfs/ioctl.c       2015-01-19 10:58:03.000000000 +0000
3652 @@ -12,6 +12,7 @@
3653  #include <linux/time.h>
3654  #include <linux/sched.h>
3655  #include <linux/blkdev.h>
3656 +#include <linux/mount.h>
3657  #include <asm/current.h>
3658  #include <asm/uaccess.h>
3659  
3660 @@ -56,6 +57,16 @@ static long jfs_map_ext2(unsigned long f
3661  }
3662  
3663  
3664 +int jfs_sync_flags(struct inode *inode, int flags, int vflags)
3665 +{
3666 +       inode->i_flags = flags;
3667 +       inode->i_vflags = vflags;
3668 +       jfs_get_inode_flags(JFS_IP(inode));
3669 +       inode->i_ctime = CURRENT_TIME_SEC;
3670 +       mark_inode_dirty(inode);
3671 +       return 0;
3672 +}
3673 +
3674  long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3675  {
3676         struct inode *inode = file_inode(filp);
3677 @@ -89,6 +100,11 @@ long jfs_ioctl(struct file *filp, unsign
3678                 if (!S_ISDIR(inode->i_mode))
3679                         flags &= ~JFS_DIRSYNC_FL;
3680  
3681 +               if (IS_BARRIER(inode)) {
3682 +                       vxwprintk_task(1, "messing with the barrier.");
3683 +                       return -EACCES;
3684 +               }
3685 +
3686                 /* Is it quota file? Do not allow user to mess with it */
3687                 if (IS_NOQUOTA(inode)) {
3688                         err = -EPERM;
3689 @@ -106,8 +122,8 @@ long jfs_ioctl(struct file *filp, unsign
3690                  * the relevant capability.
3691                  */
3692                 if ((oldflags & JFS_IMMUTABLE_FL) ||
3693 -                       ((flags ^ oldflags) &
3694 -                       (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
3695 +                       ((flags ^ oldflags) & (JFS_APPEND_FL |
3696 +                       JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL))) {
3697                         if (!capable(CAP_LINUX_IMMUTABLE)) {
3698                                 mutex_unlock(&inode->i_mutex);
3699                                 err = -EPERM;
3700 @@ -115,7 +131,7 @@ long jfs_ioctl(struct file *filp, unsign
3701                         }
3702                 }
3703  
3704 -               flags = flags & JFS_FL_USER_MODIFIABLE;
3705 +               flags &= JFS_FL_USER_MODIFIABLE;
3706                 flags |= oldflags & ~JFS_FL_USER_MODIFIABLE;
3707                 jfs_inode->mode2 = flags;
3708  
3709 diff -NurpP --minimal linux-3.18.5/fs/jfs/jfs_dinode.h linux-3.18.5-vs2.3.7.3/fs/jfs/jfs_dinode.h
3710 --- linux-3.18.5/fs/jfs/jfs_dinode.h    2012-12-11 03:30:57.000000000 +0000
3711 +++ linux-3.18.5-vs2.3.7.3/fs/jfs/jfs_dinode.h  2015-01-19 10:58:03.000000000 +0000
3712 @@ -161,9 +161,13 @@ struct dinode {
3713  
3714  #define JFS_APPEND_FL          0x01000000 /* writes to file may only append */
3715  #define JFS_IMMUTABLE_FL       0x02000000 /* Immutable file */
3716 +#define JFS_IXUNLINK_FL                0x08000000 /* Immutable invert on unlink */
3717  
3718 -#define JFS_FL_USER_VISIBLE    0x03F80000
3719 -#define JFS_FL_USER_MODIFIABLE 0x03F80000
3720 +#define JFS_BARRIER_FL         0x04000000 /* Barrier for chroot() */
3721 +#define JFS_COW_FL             0x20000000 /* Copy on Write marker */
3722 +
3723 +#define JFS_FL_USER_VISIBLE    0x07F80000
3724 +#define JFS_FL_USER_MODIFIABLE 0x07F80000
3725  #define JFS_FL_INHERIT         0x03C80000
3726  
3727  /* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
3728 diff -NurpP --minimal linux-3.18.5/fs/jfs/jfs_filsys.h linux-3.18.5-vs2.3.7.3/fs/jfs/jfs_filsys.h
3729 --- linux-3.18.5/fs/jfs/jfs_filsys.h    2012-12-11 03:30:57.000000000 +0000
3730 +++ linux-3.18.5-vs2.3.7.3/fs/jfs/jfs_filsys.h  2015-01-19 10:58:03.000000000 +0000
3731 @@ -266,6 +266,7 @@
3732  #define JFS_NAME_MAX   255
3733  #define JFS_PATH_MAX   BPSIZE
3734  
3735 +#define JFS_TAGGED             0x00800000      /* Context Tagging */
3736  
3737  /*
3738   *     file system state (superblock state)
3739 diff -NurpP --minimal linux-3.18.5/fs/jfs/jfs_imap.c linux-3.18.5-vs2.3.7.3/fs/jfs/jfs_imap.c
3740 --- linux-3.18.5/fs/jfs/jfs_imap.c      2013-11-25 15:45:01.000000000 +0000
3741 +++ linux-3.18.5-vs2.3.7.3/fs/jfs/jfs_imap.c    2015-01-19 10:58:03.000000000 +0000
3742 @@ -46,6 +46,7 @@
3743  #include <linux/pagemap.h>
3744  #include <linux/quotaops.h>
3745  #include <linux/slab.h>
3746 +#include <linux/vs_tag.h>
3747  
3748  #include "jfs_incore.h"
3749  #include "jfs_inode.h"
3750 @@ -3047,6 +3048,8 @@ static int copy_from_dinode(struct dinod
3751  {
3752         struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3753         struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
3754 +       kuid_t kuid;
3755 +       kgid_t kgid;
3756  
3757         jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
3758         jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
3759 @@ -3067,14 +3070,18 @@ static int copy_from_dinode(struct dinod
3760         }
3761         set_nlink(ip, le32_to_cpu(dip->di_nlink));
3762  
3763 -       jfs_ip->saved_uid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
3764 +       kuid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
3765 +       kgid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
3766 +       ip->i_tag = INOTAG_KTAG(DX_TAG(ip), kuid, kgid, GLOBAL_ROOT_TAG);
3767 +
3768 +       jfs_ip->saved_uid = INOTAG_KUID(DX_TAG(ip), kuid, kgid);
3769         if (!uid_valid(sbi->uid))
3770                 ip->i_uid = jfs_ip->saved_uid;
3771         else {
3772                 ip->i_uid = sbi->uid;
3773         }
3774  
3775 -       jfs_ip->saved_gid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
3776 +       jfs_ip->saved_gid = INOTAG_KGID(DX_TAG(ip), kuid, kgid);
3777         if (!gid_valid(sbi->gid))
3778                 ip->i_gid = jfs_ip->saved_gid;
3779         else {
3780 @@ -3139,16 +3146,14 @@ static void copy_to_dinode(struct dinode
3781         dip->di_size = cpu_to_le64(ip->i_size);
3782         dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
3783         dip->di_nlink = cpu_to_le32(ip->i_nlink);
3784 -       if (!uid_valid(sbi->uid))
3785 -               dip->di_uid = cpu_to_le32(i_uid_read(ip));
3786 -       else
3787 -               dip->di_uid =cpu_to_le32(from_kuid(&init_user_ns,
3788 -                                                  jfs_ip->saved_uid));
3789 -       if (!gid_valid(sbi->gid))
3790 -               dip->di_gid = cpu_to_le32(i_gid_read(ip));
3791 -       else
3792 -               dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3793 -                                                   jfs_ip->saved_gid));
3794 +       dip->di_uid = cpu_to_le32(from_kuid(&init_user_ns,
3795 +               TAGINO_KUID(DX_TAG(ip),
3796 +               !uid_valid(sbi->uid) ? ip->i_uid : jfs_ip->saved_uid,
3797 +               ip->i_tag)));
3798 +       dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3799 +               TAGINO_KGID(DX_TAG(ip),
3800 +               !gid_valid(sbi->gid) ? ip->i_gid : jfs_ip->saved_gid,
3801 +               ip->i_tag)));
3802         jfs_get_inode_flags(jfs_ip);
3803         /*
3804          * mode2 is only needed for storing the higher order bits.
3805 diff -NurpP --minimal linux-3.18.5/fs/jfs/jfs_inode.c linux-3.18.5-vs2.3.7.3/fs/jfs/jfs_inode.c
3806 --- linux-3.18.5/fs/jfs/jfs_inode.c     2014-09-03 13:19:40.000000000 +0000
3807 +++ linux-3.18.5-vs2.3.7.3/fs/jfs/jfs_inode.c   2015-01-21 09:53:08.000000000 +0000
3808 @@ -18,6 +18,7 @@
3809  
3810  #include <linux/fs.h>
3811  #include <linux/quotaops.h>
3812 +#include <linux/vs_tag.h>
3813  #include "jfs_incore.h"
3814  #include "jfs_inode.h"
3815  #include "jfs_filsys.h"
3816 @@ -33,26 +34,45 @@ void jfs_set_inode_flags(struct inode *i
3817  
3818         if (flags & JFS_IMMUTABLE_FL)
3819                 new_fl |= S_IMMUTABLE;
3820 +       if (flags & JFS_IXUNLINK_FL)
3821 +               inode->i_flags |= S_IXUNLINK;
3822 +
3823 +       if (flags & JFS_SYNC_FL)
3824 +               inode->i_flags |= S_SYNC;
3825         if (flags & JFS_APPEND_FL)
3826                 new_fl |= S_APPEND;
3827         if (flags & JFS_NOATIME_FL)
3828                 new_fl |= S_NOATIME;
3829         if (flags & JFS_DIRSYNC_FL)
3830                 new_fl |= S_DIRSYNC;
3831 -       if (flags & JFS_SYNC_FL)
3832 -               new_fl |= S_SYNC;
3833 -       inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND | S_NOATIME |
3834 +       inode_set_flags(inode, new_fl, S_IMMUTABLE | S_IXUNLINK | S_APPEND | S_NOATIME |
3835                         S_DIRSYNC | S_SYNC);
3836 +
3837 +       new_fl = 0;
3838 +       if (flags & JFS_BARRIER_FL)
3839 +               new_fl |= V_BARRIER;
3840 +       if (flags & JFS_COW_FL)
3841 +               new_fl |= V_COW;
3842 +
3843 +       set_mask_bits(&inode->i_vflags,
3844 +               V_BARRIER | V_COW, new_fl);
3845  }
3846  
3847  void jfs_get_inode_flags(struct jfs_inode_info *jfs_ip)
3848  {
3849         unsigned int flags = jfs_ip->vfs_inode.i_flags;
3850 +       unsigned int vflags = jfs_ip->vfs_inode.i_vflags;
3851 +
3852 +       jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL |
3853 +                          JFS_APPEND_FL | JFS_NOATIME_FL |
3854 +                          JFS_DIRSYNC_FL | JFS_SYNC_FL |
3855 +                          JFS_BARRIER_FL | JFS_COW_FL);
3856  
3857 -       jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_APPEND_FL | JFS_NOATIME_FL |
3858 -                          JFS_DIRSYNC_FL | JFS_SYNC_FL);
3859         if (flags & S_IMMUTABLE)
3860                 jfs_ip->mode2 |= JFS_IMMUTABLE_FL;
3861 +       if (flags & S_IXUNLINK)
3862 +               jfs_ip->mode2 |= JFS_IXUNLINK_FL;
3863 +
3864         if (flags & S_APPEND)
3865                 jfs_ip->mode2 |= JFS_APPEND_FL;
3866         if (flags & S_NOATIME)
3867 @@ -61,6 +81,11 @@ void jfs_get_inode_flags(struct jfs_inod
3868                 jfs_ip->mode2 |= JFS_DIRSYNC_FL;
3869         if (flags & S_SYNC)
3870                 jfs_ip->mode2 |= JFS_SYNC_FL;
3871 +
3872 +       if (vflags & V_BARRIER)
3873 +               jfs_ip->mode2 |= JFS_BARRIER_FL;
3874 +       if (vflags & V_COW)
3875 +               jfs_ip->mode2 |= JFS_COW_FL;
3876  }
3877  
3878  /*
3879 diff -NurpP --minimal linux-3.18.5/fs/jfs/jfs_inode.h linux-3.18.5-vs2.3.7.3/fs/jfs/jfs_inode.h
3880 --- linux-3.18.5/fs/jfs/jfs_inode.h     2012-12-11 03:30:57.000000000 +0000
3881 +++ linux-3.18.5-vs2.3.7.3/fs/jfs/jfs_inode.h   2015-01-19 10:58:03.000000000 +0000
3882 @@ -39,6 +39,7 @@ extern struct dentry *jfs_fh_to_dentry(s
3883  extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
3884         int fh_len, int fh_type);
3885  extern void jfs_set_inode_flags(struct inode *);
3886 +extern int jfs_sync_flags(struct inode *, int, int);
3887  extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
3888  extern int jfs_setattr(struct dentry *, struct iattr *);
3889  
3890 diff -NurpP --minimal linux-3.18.5/fs/jfs/namei.c linux-3.18.5-vs2.3.7.3/fs/jfs/namei.c
3891 --- linux-3.18.5/fs/jfs/namei.c 2014-06-12 11:34:58.000000000 +0000
3892 +++ linux-3.18.5-vs2.3.7.3/fs/jfs/namei.c       2015-01-19 10:58:03.000000000 +0000
3893 @@ -22,6 +22,7 @@
3894  #include <linux/ctype.h>
3895  #include <linux/quotaops.h>
3896  #include <linux/exportfs.h>
3897 +#include <linux/vs_tag.h>
3898  #include "jfs_incore.h"
3899  #include "jfs_superblock.h"
3900  #include "jfs_inode.h"
3901 @@ -1461,6 +1462,7 @@ static struct dentry *jfs_lookup(struct
3902                         jfs_err("jfs_lookup: iget failed on inum %d", (uint)inum);
3903         }
3904  
3905 +       dx_propagate_tag(nd, ip);
3906         return d_splice_alias(ip, dentry);
3907  }
3908  
3909 @@ -1526,6 +1528,7 @@ const struct inode_operations jfs_dir_in
3910         .get_acl        = jfs_get_acl,
3911         .set_acl        = jfs_set_acl,
3912  #endif
3913 +       .sync_flags     = jfs_sync_flags,
3914  };
3915  
3916  const struct file_operations jfs_dir_operations = {
3917 diff -NurpP --minimal linux-3.18.5/fs/jfs/super.c linux-3.18.5-vs2.3.7.3/fs/jfs/super.c
3918 --- linux-3.18.5/fs/jfs/super.c 2015-01-17 02:40:19.000000000 +0000
3919 +++ linux-3.18.5-vs2.3.7.3/fs/jfs/super.c       2015-01-19 10:58:03.000000000 +0000
3920 @@ -203,7 +203,8 @@ enum {
3921         Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
3922         Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
3923         Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask,
3924 -       Opt_discard, Opt_nodiscard, Opt_discard_minblk
3925 +       Opt_discard, Opt_nodiscard, Opt_discard_minblk,
3926 +       Opt_tag, Opt_notag, Opt_tagid
3927  };
3928  
3929  static const match_table_t tokens = {
3930 @@ -213,6 +214,10 @@ static const match_table_t tokens = {
3931         {Opt_resize, "resize=%u"},
3932         {Opt_resize_nosize, "resize"},
3933         {Opt_errors, "errors=%s"},
3934 +       {Opt_tag, "tag"},
3935 +       {Opt_notag, "notag"},
3936 +       {Opt_tagid, "tagid=%u"},
3937 +       {Opt_tag, "tagxid"},
3938         {Opt_ignore, "noquota"},
3939         {Opt_ignore, "quota"},
3940         {Opt_usrquota, "usrquota"},
3941 @@ -402,7 +407,20 @@ static int parse_options(char *options,
3942                                 pr_err("JFS: discard option not supported on device\n");
3943                         break;
3944                 }
3945 -
3946 +#ifndef CONFIG_TAGGING_NONE
3947 +               case Opt_tag:
3948 +                       *flag |= JFS_TAGGED;
3949 +                       break;
3950 +               case Opt_notag:
3951 +                       *flag &= JFS_TAGGED;
3952 +                       break;
3953 +#endif
3954 +#ifdef CONFIG_PROPAGATE
3955 +               case Opt_tagid:
3956 +                       /* use args[0] */
3957 +                       *flag |= JFS_TAGGED;
3958 +                       break;
3959 +#endif
3960                 default:
3961                         printk("jfs: Unrecognized mount option \"%s\" or missing value\n",
3962                                p);
3963 @@ -434,6 +452,12 @@ static int jfs_remount(struct super_bloc
3964         if (!parse_options(data, sb, &newLVSize, &flag))
3965                 return -EINVAL;
3966  
3967 +       if ((flag & JFS_TAGGED) && !(sb->s_flags & MS_TAGGED)) {
3968 +               printk(KERN_ERR "JFS: %s: tagging not permitted on remount.\n",
3969 +                       sb->s_id);
3970 +               return -EINVAL;
3971 +       }
3972 +
3973         if (newLVSize) {
3974                 if (sb->s_flags & MS_RDONLY) {
3975                         pr_err("JFS: resize requires volume to be mounted read-write\n");
3976 @@ -517,6 +541,9 @@ static int jfs_fill_super(struct super_b
3977  #ifdef CONFIG_JFS_POSIX_ACL
3978         sb->s_flags |= MS_POSIXACL;
3979  #endif
3980 +       /* map mount option tagxid */
3981 +       if (sbi->flag & JFS_TAGGED)
3982 +               sb->s_flags |= MS_TAGGED;
3983  
3984         if (newLVSize) {
3985                 pr_err("resize option for remount only\n");
3986 diff -NurpP --minimal linux-3.18.5/fs/libfs.c linux-3.18.5-vs2.3.7.3/fs/libfs.c
3987 --- linux-3.18.5/fs/libfs.c     2015-02-05 18:02:45.000000000 +0000
3988 +++ linux-3.18.5-vs2.3.7.3/fs/libfs.c   2015-01-22 07:27:38.000000000 +0000
3989 @@ -146,13 +146,14 @@ static inline unsigned char dt_type(stru
3990   * both impossible due to the lock on directory.
3991   */
3992  
3993 -int dcache_readdir(struct file *file, struct dir_context *ctx)
3994 +static inline int do_dcache_readdir_filter(struct file *filp,
3995 +       struct dir_context *ctx, int (*filter)(struct dentry *dentry))
3996  {
3997 -       struct dentry *dentry = file->f_path.dentry;
3998 -       struct dentry *cursor = file->private_data;
3999 +       struct dentry *dentry = filp->f_path.dentry;
4000 +       struct dentry *cursor = filp->private_data;
4001         struct list_head *p, *q = &cursor->d_child;
4002  
4003 -       if (!dir_emit_dots(file, ctx))
4004 +       if (!dir_emit_dots(filp, ctx))
4005                 return 0;
4006         spin_lock(&dentry->d_lock);
4007         if (ctx->pos == 2)
4008 @@ -160,6 +161,8 @@ int dcache_readdir(struct file *file, st
4009  
4010         for (p = q->next; p != &dentry->d_subdirs; p = p->next) {
4011                 struct dentry *next = list_entry(p, struct dentry, d_child);
4012 +               if (filter && !filter(next))
4013 +                       continue;
4014                 spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
4015                 if (!simple_positive(next)) {
4016                         spin_unlock(&next->d_lock);
4017 @@ -182,8 +185,22 @@ int dcache_readdir(struct file *file, st
4018         spin_unlock(&dentry->d_lock);
4019         return 0;
4020  }
4021 +
4022  EXPORT_SYMBOL(dcache_readdir);
4023  
4024 +int dcache_readdir(struct file *filp, struct dir_context *ctx)
4025 +{
4026 +       return do_dcache_readdir_filter(filp, ctx, NULL);
4027 +}
4028 +
4029 +EXPORT_SYMBOL(dcache_readdir_filter);
4030 +
4031 +int dcache_readdir_filter(struct file *filp, struct dir_context *ctx,
4032 +       int (*filter)(struct dentry *))
4033 +{
4034 +       return do_dcache_readdir_filter(filp, ctx, filter);
4035 +}
4036 +
4037  ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
4038  {
4039         return -EISDIR;
4040 diff -NurpP --minimal linux-3.18.5/fs/locks.c linux-3.18.5-vs2.3.7.3/fs/locks.c
4041 --- linux-3.18.5/fs/locks.c     2015-02-05 18:02:45.000000000 +0000
4042 +++ linux-3.18.5-vs2.3.7.3/fs/locks.c   2015-01-28 11:48:02.000000000 +0000
4043 @@ -129,6 +129,8 @@
4044  #include <linux/hashtable.h>
4045  #include <linux/percpu.h>
4046  #include <linux/lglock.h>
4047 +#include <linux/vs_base.h>
4048 +#include <linux/vs_limit.h>
4049  
4050  #define CREATE_TRACE_POINTS
4051  #include <trace/events/filelock.h>
4052 @@ -214,11 +216,17 @@ static void locks_init_lock_heads(struct
4053  /* Allocate an empty lock structure. */
4054  struct file_lock *locks_alloc_lock(void)
4055  {
4056 -       struct file_lock *fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
4057 +       struct file_lock *fl;
4058  
4059 -       if (fl)
4060 -               locks_init_lock_heads(fl);
4061 +       if (!vx_locks_avail(1))
4062 +               return NULL;
4063  
4064 +       fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
4065 +
4066 +       if (fl) {
4067 +               locks_init_lock_heads(fl);
4068 +               fl->fl_xid = -1;
4069 +       }
4070         return fl;
4071  }
4072  EXPORT_SYMBOL_GPL(locks_alloc_lock);
4073 @@ -246,6 +254,7 @@ void locks_free_lock(struct file_lock *f
4074         BUG_ON(!list_empty(&fl->fl_block));
4075         BUG_ON(!hlist_unhashed(&fl->fl_link));
4076  
4077 +       vx_locks_dec(fl);
4078         locks_release_private(fl);
4079         kmem_cache_free(filelock_cache, fl);
4080  }
4081 @@ -267,6 +276,7 @@ void locks_init_lock(struct file_lock *f
4082  {
4083         memset(fl, 0, sizeof(struct file_lock));
4084         locks_init_lock_heads(fl);
4085 +       fl->fl_xid = -1;
4086  }
4087  
4088  EXPORT_SYMBOL(locks_init_lock);
4089 @@ -284,6 +294,7 @@ void locks_copy_conflock(struct file_loc
4090         new->fl_start = fl->fl_start;
4091         new->fl_end = fl->fl_end;
4092         new->fl_lmops = fl->fl_lmops;
4093 +       new->fl_xid = fl->fl_xid;
4094         new->fl_ops = NULL;
4095  
4096         if (fl->fl_lmops) {
4097 @@ -345,6 +356,11 @@ flock_make_lock(struct file *filp, unsig
4098         fl->fl_flags = FL_FLOCK;
4099         fl->fl_type = type;
4100         fl->fl_end = OFFSET_MAX;
4101 +
4102 +       vxd_assert(filp->f_xid == vx_current_xid(),
4103 +               "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
4104 +       fl->fl_xid = filp->f_xid;
4105 +       vx_locks_inc(fl);
4106         
4107         return fl;
4108  }
4109 @@ -467,6 +483,7 @@ static int lease_init(struct file *filp,
4110  
4111         fl->fl_owner = filp;
4112         fl->fl_pid = current->tgid;
4113 +       fl->fl_xid = vx_current_xid();
4114  
4115         fl->fl_file = filp;
4116         fl->fl_flags = FL_LEASE;
4117 @@ -486,6 +503,11 @@ static struct file_lock *lease_alloc(str
4118         if (fl == NULL)
4119                 return ERR_PTR(error);
4120  
4121 +       fl->fl_xid = vx_current_xid();
4122 +       if (filp)
4123 +               vxd_assert(filp->f_xid == fl->fl_xid,
4124 +                       "f_xid(%d) == fl_xid(%d)", filp->f_xid, fl->fl_xid);
4125 +       vx_locks_inc(fl);
4126         error = lease_init(filp, type, fl);
4127         if (error) {
4128                 locks_free_lock(fl);
4129 @@ -892,6 +914,7 @@ static int flock_lock_file(struct file *
4130                 spin_lock(&inode->i_lock);
4131         }
4132  
4133 +       new_fl->fl_xid = -1;
4134  find_conflict:
4135         for_each_lock(inode, before) {
4136                 struct file_lock *fl = *before;
4137 @@ -912,6 +935,7 @@ find_conflict:
4138                 goto out;
4139         locks_copy_lock(new_fl, request);
4140         locks_insert_lock(before, new_fl);
4141 +       vx_locks_inc(new_fl);
4142         new_fl = NULL;
4143         error = 0;
4144  
4145 @@ -923,7 +947,8 @@ out:
4146         return error;
4147  }
4148  
4149 -static int __posix_lock_file(struct inode *inode, struct file_lock *request, struct file_lock *conflock)
4150 +static int __posix_lock_file(struct inode *inode, struct file_lock *request,
4151 +       struct file_lock *conflock, vxid_t xid)
4152  {
4153         struct file_lock *fl;
4154         struct file_lock *new_fl = NULL;
4155 @@ -935,6 +960,8 @@ static int __posix_lock_file(struct inod
4156         bool added = false;
4157         LIST_HEAD(dispose);
4158  
4159 +       vxd_assert(xid == vx_current_xid(),
4160 +               "xid(%d) == current(%d)", xid, vx_current_xid());
4161         /*
4162          * We may need two file_lock structures for this operation,
4163          * so we get them in advance to avoid races.
4164 @@ -945,7 +972,11 @@ static int __posix_lock_file(struct inod
4165             (request->fl_type != F_UNLCK ||
4166              request->fl_start != 0 || request->fl_end != OFFSET_MAX)) {
4167                 new_fl = locks_alloc_lock();
4168 +               new_fl->fl_xid = xid;
4169 +               vx_locks_inc(new_fl);
4170                 new_fl2 = locks_alloc_lock();
4171 +               new_fl2->fl_xid = xid;
4172 +               vx_locks_inc(new_fl2);
4173         }
4174  
4175         spin_lock(&inode->i_lock);
4176 @@ -1158,7 +1189,8 @@ static int __posix_lock_file(struct inod
4177  int posix_lock_file(struct file *filp, struct file_lock *fl,
4178                         struct file_lock *conflock)
4179  {
4180 -       return __posix_lock_file(file_inode(filp), fl, conflock);
4181 +       return __posix_lock_file(file_inode(filp),
4182 +               fl, conflock, filp->f_xid);
4183  }
4184  EXPORT_SYMBOL(posix_lock_file);
4185  
4186 @@ -1252,7 +1284,7 @@ int locks_mandatory_area(int read_write,
4187                 if (filp) {
4188                         fl.fl_owner = filp;
4189                         fl.fl_flags &= ~FL_SLEEP;
4190 -                       error = __posix_lock_file(inode, &fl, NULL);
4191 +                       error = __posix_lock_file(inode, &fl, NULL, filp->f_xid);
4192                         if (!error)
4193                                 break;
4194                 }
4195 @@ -1260,7 +1292,7 @@ int locks_mandatory_area(int read_write,
4196                 if (sleep)
4197                         fl.fl_flags |= FL_SLEEP;
4198                 fl.fl_owner = current->files;
4199 -               error = __posix_lock_file(inode, &fl, NULL);
4200 +               error = __posix_lock_file(inode, &fl, NULL, filp->f_xid);
4201                 if (error != FILE_LOCK_DEFERRED)
4202                         break;
4203                 error = wait_event_interruptible(fl.fl_wait, !fl.fl_next);
4204 @@ -1655,6 +1687,7 @@ generic_add_lease(struct file *filp, lon
4205                 goto out;
4206  
4207         locks_insert_lock(before, lease);
4208 +       vx_locks_inc(lease);
4209         /*
4210          * The check in break_lease() is lockless. It's possible for another
4211          * open to race in after we did the earlier check for a conflicting
4212 @@ -2110,6 +2143,11 @@ int fcntl_setlk(unsigned int fd, struct
4213         if (file_lock == NULL)
4214                 return -ENOLCK;
4215  
4216 +       vxd_assert(filp->f_xid == vx_current_xid(),
4217 +               "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
4218 +       file_lock->fl_xid = filp->f_xid;
4219 +       vx_locks_inc(file_lock);
4220 +
4221         /*
4222          * This might block, so we do it before checking the inode.
4223          */
4224 @@ -2250,6 +2288,11 @@ int fcntl_setlk64(unsigned int fd, struc
4225         if (file_lock == NULL)
4226                 return -ENOLCK;
4227  
4228 +       vxd_assert(filp->f_xid == vx_current_xid(),
4229 +               "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
4230 +       file_lock->fl_xid = filp->f_xid;
4231 +       vx_locks_inc(file_lock);
4232 +
4233         /*
4234          * This might block, so we do it before checking the inode.
4235          */
4236 @@ -2557,8 +2600,11 @@ static int locks_show(struct seq_file *f
4237  
4238         lock_get_status(f, fl, iter->li_pos, "");
4239  
4240 -       list_for_each_entry(bfl, &fl->fl_block, fl_block)
4241 +       list_for_each_entry(bfl, &fl->fl_block, fl_block) {
4242 +               if (!vx_check(fl->fl_xid, VS_WATCH_P | VS_IDENT))
4243 +                       continue;
4244                 lock_get_status(f, bfl, iter->li_pos, " ->");
4245 +       }
4246  
4247         return 0;
4248  }
4249 diff -NurpP --minimal linux-3.18.5/fs/mount.h linux-3.18.5-vs2.3.7.3/fs/mount.h
4250 --- linux-3.18.5/fs/mount.h     2015-01-17 02:40:19.000000000 +0000
4251 +++ linux-3.18.5-vs2.3.7.3/fs/mount.h   2015-01-19 10:58:03.000000000 +0000
4252 @@ -62,6 +62,7 @@ struct mount {
4253         int mnt_expiry_mark;            /* true if marked for expiry */
4254         struct hlist_head mnt_pins;
4255         struct path mnt_ex_mountpoint;
4256 +       vtag_t mnt_tag;                 /* tagging used for vfsmount */
4257  };
4258  
4259  #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
4260 diff -NurpP --minimal linux-3.18.5/fs/namei.c linux-3.18.5-vs2.3.7.3/fs/namei.c
4261 --- linux-3.18.5/fs/namei.c     2015-01-17 02:40:19.000000000 +0000
4262 +++ linux-3.18.5-vs2.3.7.3/fs/namei.c   2015-01-22 08:31:30.000000000 +0000
4263 @@ -34,10 +34,20 @@
4264  #include <linux/device_cgroup.h>
4265  #include <linux/fs_struct.h>
4266  #include <linux/posix_acl.h>
4267 +#include <linux/proc_fs.h>
4268 +#include <linux/magic.h>
4269 +#include <linux/vserver/inode.h>
4270 +#include <linux/vs_base.h>
4271 +#include <linux/vs_tag.h>
4272 +#include <linux/vs_cowbl.h>
4273 +#include <linux/vs_device.h>
4274 +#include <linux/vs_context.h>
4275 +#include <linux/pid_namespace.h>
4276  #include <linux/hash.h>
4277  #include <asm/uaccess.h>
4278  
4279  #include "internal.h"
4280 +#include "proc/internal.h"
4281  #include "mount.h"
4282  
4283  /* [Feb-1997 T. Schoebel-Theuer]
4284 @@ -278,6 +288,93 @@ static int check_acl(struct inode *inode
4285         return -EAGAIN;
4286  }
4287  
4288 +static inline int dx_barrier(const struct inode *inode)
4289 +{
4290 +       if (IS_BARRIER(inode) && !vx_check(0, VS_ADMIN | VS_WATCH)) {
4291 +               vxwprintk_task(1, "did hit the barrier.");
4292 +               return 1;
4293 +       }
4294 +       return 0;
4295 +}
4296 +
4297 +static int __dx_permission(const struct inode *inode, int mask)
4298 +{
4299 +       if (dx_barrier(inode))
4300 +               return -EACCES;
4301 +
4302 +       if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) {
4303 +               /* devpts is xid tagged */
4304 +               if (S_ISDIR(inode->i_mode) ||
4305 +                   vx_check((vxid_t)i_tag_read(inode), VS_IDENT | VS_WATCH_P))
4306 +                       return 0;
4307 +
4308 +               /* just pretend we didn't find anything */
4309 +               return -ENOENT;
4310 +       }
4311 +       else if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) {
4312 +               struct proc_dir_entry *de = PDE(inode);
4313 +
4314 +               if (de && !vx_hide_check(0, de->vx_flags)) {
4315 +                       vxdprintk(VXD_CBIT(misc, 9),
4316 +                               VS_Q("%*s") " hidden by _dx_permission",
4317 +                               de->namelen, de->name);
4318 +                       goto out;
4319 +               }
4320 +
4321 +               if ((mask & (MAY_WRITE | MAY_APPEND))) {
4322 +                       struct pid *pid;
4323 +                       struct task_struct *tsk;
4324 +
4325 +                       if (vx_check(0, VS_ADMIN | VS_WATCH_P) ||
4326 +                           vx_flags(VXF_STATE_SETUP, 0))
4327 +                               return 0;
4328 +
4329 +                       pid = PROC_I(inode)->pid;
4330 +                       if (!pid)
4331 +                               goto out;
4332 +
4333 +                       rcu_read_lock();
4334 +                       tsk = pid_task(pid, PIDTYPE_PID);
4335 +                       vxdprintk(VXD_CBIT(tag, 0), "accessing %p[#%u]",
4336 +                                 tsk, (tsk ? vx_task_xid(tsk) : 0));
4337 +                       if (tsk &&
4338 +                               vx_check(vx_task_xid(tsk), VS_IDENT | VS_WATCH_P)) {
4339 +                               rcu_read_unlock();
4340 +                               return 0;
4341 +                       }
4342 +                       rcu_read_unlock();
4343 +               }
4344 +               else {
4345 +                       /* FIXME: Should we block some entries here? */
4346 +                       return 0;
4347 +               }
4348 +       }
4349 +       else {
4350 +               if (dx_notagcheck(inode->i_sb) ||
4351 +                   dx_check((vxid_t)i_tag_read(inode),
4352 +                       DX_HOSTID | DX_ADMIN | DX_WATCH | DX_IDENT))
4353 +                       return 0;
4354 +       }
4355 +
4356 +out:
4357 +       return -EACCES;
4358 +}
4359 +
4360 +int dx_permission(const struct inode *inode, int mask)
4361 +{
4362 +       int ret = __dx_permission(inode, mask);
4363 +       if (unlikely(ret)) {
4364 +#ifndef        CONFIG_VSERVER_WARN_DEVPTS
4365 +               if (inode->i_sb->s_magic != DEVPTS_SUPER_MAGIC)
4366 +#endif
4367 +                   vxwprintk_task(1,
4368 +                       "denied [0x%x] access to inode %s:%p[#%d,%lu]",
4369 +                       mask, inode->i_sb->s_id, inode,
4370 +                       i_tag_read(inode), inode->i_ino);
4371 +       }
4372 +       return ret;
4373 +}
4374 +
4375  /*
4376   * This does the basic permission checking
4377   */
4378 @@ -402,10 +499,14 @@ int __inode_permission(struct inode *ino
4379                 /*
4380                  * Nobody gets write access to an immutable file.
4381                  */
4382 -               if (IS_IMMUTABLE(inode))
4383 +               if (IS_IMMUTABLE(inode) && !IS_COW(inode))
4384                         return -EACCES;
4385         }
4386  
4387 +       retval = dx_permission(inode, mask);
4388 +       if (retval)
4389 +               return retval;
4390 +
4391         retval = do_inode_permission(inode, mask);
4392         if (retval)
4393                 return retval;
4394 @@ -1416,6 +1517,9 @@ static int lookup_fast(struct nameidata
4395                                 goto unlazy;
4396                         }
4397                 }
4398 +
4399 +               /* FIXME: check dx permission */
4400 +
4401                 path->mnt = mnt;
4402                 path->dentry = dentry;
4403                 if (likely(__follow_mount_rcu(nd, path, inode)))
4404 @@ -1442,6 +1546,8 @@ unlazy:
4405                 goto need_lookup;
4406         }
4407  
4408 +       /* FIXME: check dx permission */
4409 +
4410         path->mnt = mnt;
4411         path->dentry = dentry;
4412         err = follow_managed(path, nd->flags);
4413 @@ -2434,7 +2540,7 @@ static int may_delete(struct inode *dir,
4414                 return -EPERM;
4415  
4416         if (check_sticky(dir, inode) || IS_APPEND(inode) ||
4417 -           IS_IMMUTABLE(inode) || IS_SWAPFILE(inode))
4418 +               IS_IXORUNLINK(inode) || IS_SWAPFILE(inode))
4419                 return -EPERM;
4420         if (isdir) {
4421                 if (!d_is_dir(victim))
4422 @@ -2516,19 +2622,25 @@ int vfs_create(struct inode *dir, struct
4423                 bool want_excl)
4424  {
4425         int error = may_create(dir, dentry);
4426 -       if (error)
4427 +       if (error) {
4428 +               vxdprintk(VXD_CBIT(misc, 3), "may_create failed with %d", error);
4429                 return error;
4430 +       }
4431  
4432         if (!dir->i_op->create)
4433                 return -EACCES; /* shouldn't it be ENOSYS? */
4434         mode &= S_IALLUGO;
4435         mode |= S_IFREG;
4436         error = security_inode_create(dir, dentry, mode);
4437 -       if (error)
4438 +       if (error) {
4439 +               vxdprintk(VXD_CBIT(misc, 3), "security_inode_create failed with %d", error);
4440                 return error;
4441 +       }
4442         error = dir->i_op->create(dir, dentry, mode, want_excl);
4443         if (!error)
4444                 fsnotify_create(dir, dentry);
4445 +       else
4446 +               vxdprintk(VXD_CBIT(misc, 3), "i_op->create failed with %d", error);
4447         return error;
4448  }
4449  EXPORT_SYMBOL(vfs_create);
4450 @@ -2564,6 +2676,15 @@ static int may_open(struct path *path, i
4451                 break;
4452         }
4453  
4454 +#ifdef CONFIG_VSERVER_COWBL
4455 +       if (IS_COW(inode) &&
4456 +               ((flag & O_ACCMODE) != O_RDONLY)) {
4457 +               if (IS_COW_LINK(inode))
4458 +                       return -EMLINK;
4459 +               inode->i_flags &= ~(S_IXUNLINK|S_IMMUTABLE);
4460 +               mark_inode_dirty(inode);
4461 +       }
4462 +#endif
4463         error = inode_permission(inode, acc_mode);
4464         if (error)
4465                 return error;
4466 @@ -3058,6 +3179,16 @@ finish_open:
4467         }
4468  finish_open_created:
4469         error = may_open(&nd->path, acc_mode, open_flag);
4470 +#ifdef CONFIG_VSERVER_COWBL
4471 +       if (error == -EMLINK) {
4472 +               struct dentry *dentry;
4473 +               dentry = cow_break_link(name->name);
4474 +               if (IS_ERR(dentry))
4475 +                       error = PTR_ERR(dentry);
4476 +               else
4477 +                       dput(dentry);
4478 +       }
4479 +#endif
4480         if (error)
4481                 goto out;
4482  
4483 @@ -3187,6 +3318,7 @@ static struct file *path_openat(int dfd,
4484         int opened = 0;
4485         int error;
4486  
4487 +restart:
4488         file = get_empty_filp();
4489         if (IS_ERR(file))
4490                 return file;
4491 @@ -3228,6 +3360,16 @@ static struct file *path_openat(int dfd,
4492                 error = do_last(nd, &path, file, op, &opened, pathname);
4493                 put_link(nd, &link, cookie);
4494         }
4495 +
4496 +#ifdef CONFIG_VSERVER_COWBL
4497 +       if (error == -EMLINK) {
4498 +               if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT))
4499 +                       path_put(&nd->root);
4500 +               if (base)
4501 +                       fput(base);
4502 +               goto restart;
4503 +       }
4504 +#endif
4505  out:
4506         if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT))
4507                 path_put(&nd->root);
4508 @@ -3343,6 +3485,11 @@ struct dentry *kern_path_create(int dfd,
4509                 goto fail;
4510         }
4511         *path = nd.path;
4512 +       vxdprintk(VXD_CBIT(misc, 3), "kern_path_create path.dentry = %p (%.*s), dentry = %p (%.*s), d_inode = %p",
4513 +               path->dentry, path->dentry->d_name.len,
4514 +               path->dentry->d_name.name, dentry,
4515 +               dentry->d_name.len, dentry->d_name.name,
4516 +               path->dentry->d_inode);
4517         return dentry;
4518  fail:
4519         dput(dentry);
4520 @@ -3899,7 +4046,7 @@ int vfs_link(struct dentry *old_dentry,
4521         /*
4522          * A link to an append-only or immutable file cannot be created.
4523          */
4524 -       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
4525 +       if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
4526                 return -EPERM;
4527         if (!dir->i_op->link)
4528                 return -EPERM;
4529 @@ -4404,6 +4551,289 @@ int generic_readlink(struct dentry *dent
4530  }
4531  EXPORT_SYMBOL(generic_readlink);
4532  
4533 +
4534 +#ifdef CONFIG_VSERVER_COWBL
4535 +
4536 +static inline
4537 +long do_cow_splice(struct file *in, struct file *out, size_t len)
4538 +{
4539 +       loff_t ppos = 0;
4540 +       loff_t opos = 0;
4541 +
4542 +       return do_splice_direct(in, &ppos, out, &opos, len, 0);
4543 +}
4544 +
4545 +struct dentry *cow_break_link(const char *pathname)
4546 +{
4547 +       int ret, mode, pathlen, redo = 0, drop = 1;
4548 +       struct nameidata old_nd, dir_nd;
4549 +       struct path dir_path, *old_path, *new_path;
4550 +       struct dentry *dir, *old_dentry, *new_dentry = NULL;
4551 +       struct file *old_file;
4552 +       struct file *new_file;
4553 +       char *to, *path, pad='\251';
4554 +       loff_t size;
4555 +
4556 +       vxdprintk(VXD_CBIT(misc, 1),
4557 +               "cow_break_link(" VS_Q("%s") ")", pathname);
4558 +
4559 +       path = kmalloc(PATH_MAX, GFP_KERNEL);
4560 +       ret = -ENOMEM;
4561 +       if (!path)
4562 +               goto out;
4563 +
4564 +       /* old_nd.path will have refs to dentry and mnt */
4565 +       ret = do_path_lookup(AT_FDCWD, pathname, LOOKUP_FOLLOW, &old_nd);
4566 +       vxdprintk(VXD_CBIT(misc, 2),
4567 +               "do_path_lookup(old): %d", ret);
4568 +       if (ret < 0)
4569 +               goto out_free_path;
4570 +
4571 +       /* dentry/mnt refs handed over to old_path */
4572 +       old_path = &old_nd.path;
4573 +       /* no explicit reference for old_dentry here */
4574 +       old_dentry = old_path->dentry;
4575 +
4576 +       mode = old_dentry->d_inode->i_mode;
4577 +       to = d_path(old_path, path, PATH_MAX-2);
4578 +       pathlen = strlen(to);
4579 +       vxdprintk(VXD_CBIT(misc, 2),
4580 +               "old path " VS_Q("%s") " [%p:" VS_Q("%.*s") ":%d]", to,
4581 +               old_dentry,
4582 +               old_dentry->d_name.len, old_dentry->d_name.name,
4583 +               old_dentry->d_name.len);
4584 +
4585 +       to[pathlen + 1] = 0;
4586 +retry:
4587 +       new_dentry = NULL;
4588 +       to[pathlen] = pad--;
4589 +       ret = -ELOOP;
4590 +       if (pad <= '\240')
4591 +               goto out_rel_old;
4592 +
4593 +       vxdprintk(VXD_CBIT(misc, 1), "temp copy " VS_Q("%s"), to);
4594 +
4595 +       /* dir_nd.path will have refs to dentry and mnt */
4596 +       ret = do_path_lookup(AT_FDCWD, to,
4597 +               LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE, &dir_nd);
4598 +       vxdprintk(VXD_CBIT(misc, 2), "do_path_lookup(new): %d", ret);
4599 +       if (ret < 0)
4600 +               goto retry;
4601 +
4602 +       /* this puppy downs the dir inode mutex if successful.
4603 +          dir_path will hold refs to dentry and mnt and
4604 +          we'll have write access to the mnt */
4605 +       new_dentry = kern_path_create(AT_FDCWD, to, &dir_path, 0);
4606 +       if (!new_dentry || IS_ERR(new_dentry)) {
4607 +               path_put(&dir_nd.path);
4608 +               vxdprintk(VXD_CBIT(misc, 2),
4609 +                       "kern_path_create(new) failed with %ld",
4610 +                       PTR_ERR(new_dentry));
4611 +               goto retry;
4612 +       }
4613 +       vxdprintk(VXD_CBIT(misc, 2),
4614 +               "kern_path_create(new): %p [" VS_Q("%.*s") ":%d]",
4615 +               new_dentry,
4616 +               new_dentry->d_name.len, new_dentry->d_name.name,
4617 +               new_dentry->d_name.len);
4618 +
4619 +       /* take a reference on new_dentry */
4620 +       dget(new_dentry);
4621 +
4622 +       /* dentry/mnt refs handed over to new_path */
4623 +       new_path = &dir_path;
4624 +
4625 +       /* dentry for old/new dir */
4626 +       dir = dir_nd.path.dentry;
4627 +
4628 +       /* give up reference on dir */
4629 +       dput(new_path->dentry);
4630 +
4631 +       /* new_dentry already has a reference */
4632 +       new_path->dentry = new_dentry;
4633 +
4634 +       ret = vfs_create(dir->d_inode, new_dentry, mode, 1);
4635 +       vxdprintk(VXD_CBIT(misc, 2),
4636 +               "vfs_create(new): %d", ret);
4637 +       if (ret == -EEXIST) {
4638 +               path_put(&dir_nd.path);
4639 +               mutex_unlock(&dir->d_inode->i_mutex);
4640 +               mnt_drop_write(new_path->mnt);
4641 +               path_put(new_path);
4642 +               new_dentry = NULL;
4643 +               goto retry;
4644 +       }
4645 +       else if (ret < 0)
4646 +               goto out_unlock_new;
4647 +
4648 +       /* drop out early, ret passes ENOENT */
4649 +       ret = -ENOENT;
4650 +       if ((redo = d_unhashed(old_dentry)))
4651 +               goto out_unlock_new;
4652 +
4653 +       /* doesn't change refs for old_path */
4654 +       old_file = dentry_open(old_path, O_RDONLY, current_cred());
4655 +       vxdprintk(VXD_CBIT(misc, 2),
4656 +               "dentry_open(old): %p", old_file);
4657 +       if (IS_ERR(old_file)) {
4658 +               ret = PTR_ERR(old_file);
4659 +               goto out_unlock_new;
4660 +       }
4661 +
4662 +       /* doesn't change refs for new_path */
4663 +       new_file = dentry_open(new_path, O_WRONLY, current_cred());
4664 +       vxdprintk(VXD_CBIT(misc, 2),
4665 +               "dentry_open(new): %p", new_file);
4666 +       if (IS_ERR(new_file)) {
4667 +               ret = PTR_ERR(new_file);
4668 +               goto out_fput_old;
4669 +       }
4670 +
4671 +       /* unlock the inode mutex from kern_path_create() */
4672 +       mutex_unlock(&dir->d_inode->i_mutex);
4673 +
4674 +       /* drop write access to mnt */
4675 +       mnt_drop_write(new_path->mnt);
4676 +
4677 +       drop = 0;
4678 +
4679 +       size = i_size_read(old_file->f_dentry->d_inode);
4680 +       ret = do_cow_splice(old_file, new_file, size);
4681 +       vxdprintk(VXD_CBIT(misc, 2), "do_splice_direct: %d", ret);
4682 +       if (ret < 0) {
4683 +               goto out_fput_both;
4684 +       } else if (ret < size) {
4685 +               ret = -ENOSPC;
4686 +               goto out_fput_both;
4687 +       } else {
4688 +               struct inode *old_inode = old_dentry->d_inode;
4689 +               struct inode *new_inode = new_dentry->d_inode;
4690 +               struct iattr attr = {
4691 +                       .ia_uid = old_inode->i_uid,
4692 +                       .ia_gid = old_inode->i_gid,
4693 +                       .ia_valid = ATTR_UID | ATTR_GID
4694 +                       };
4695 +
4696 +               setattr_copy(new_inode, &attr);
4697 +               mark_inode_dirty(new_inode);
4698 +       }
4699 +
4700 +       /* lock rename mutex */
4701 +       mutex_lock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
4702 +
4703 +       /* drop out late */
4704 +       ret = -ENOENT;
4705 +       if ((redo = d_unhashed(old_dentry)))
4706 +               goto out_unlock;
4707 +
4708 +       vxdprintk(VXD_CBIT(misc, 2),
4709 +               "vfs_rename: [" VS_Q("%*s") ":%d] -> [" VS_Q("%*s") ":%d]",
4710 +               new_dentry->d_name.len, new_dentry->d_name.name,
4711 +               new_dentry->d_name.len,
4712 +               old_dentry->d_name.len, old_dentry->d_name.name,
4713 +               old_dentry->d_name.len);
4714 +       ret = vfs_rename(dir_nd.path.dentry->d_inode, new_dentry,
4715 +               old_dentry->d_parent->d_inode, old_dentry, NULL, 0);
4716 +       vxdprintk(VXD_CBIT(misc, 2), "vfs_rename: %d", ret);
4717 +
4718 +out_unlock:
4719 +       mutex_unlock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
4720 +
4721 +out_fput_both:
4722 +       vxdprintk(VXD_CBIT(misc, 3),
4723 +               "fput(new_file=%p[#%ld])", new_file,
4724 +               atomic_long_read(&new_file->f_count));
4725 +       fput(new_file);
4726 +
4727 +out_fput_old:
4728 +       vxdprintk(VXD_CBIT(misc, 3),
4729 +               "fput(old_file=%p[#%ld])", old_file,
4730 +               atomic_long_read(&old_file->f_count));
4731 +       fput(old_file);
4732 +
4733 +out_unlock_new:
4734 +       /* drop references from dir_nd.path */
4735 +       path_put(&dir_nd.path);
4736 +
4737 +       if (drop) {
4738 +               /* unlock the inode mutex from kern_path_create() */
4739 +               mutex_unlock(&dir->d_inode->i_mutex);
4740 +
4741 +               /* drop write access to mnt */
4742 +               mnt_drop_write(new_path->mnt);
4743 +       }
4744 +
4745 +       if (!ret)
4746 +               goto out_redo;
4747 +
4748 +       /* error path cleanup */
4749 +       vfs_unlink(dir->d_inode, new_dentry, NULL);
4750 +
4751 +out_redo:
4752 +       if (!redo)
4753 +               goto out_rel_both;
4754 +
4755 +       /* lookup dentry once again
4756 +          old_nd.path will be freed as old_path in out_rel_old */
4757 +       ret = do_path_lookup(AT_FDCWD, pathname, LOOKUP_FOLLOW, &old_nd);
4758 +       if (ret)
4759 +               goto out_rel_both;
4760 +
4761 +       /* drop reference on new_dentry */
4762 +       dput(new_dentry);
4763 +       new_dentry = old_path->dentry;
4764 +       dget(new_dentry);
4765 +       vxdprintk(VXD_CBIT(misc, 2),
4766 +               "do_path_lookup(redo): %p [" VS_Q("%.*s") ":%d]",
4767 +               new_dentry,
4768 +               new_dentry->d_name.len, new_dentry->d_name.name,
4769 +               new_dentry->d_name.len);
4770 +
4771 +out_rel_both:
4772 +       if (new_path)
4773 +               path_put(new_path);
4774 +out_rel_old:
4775 +       path_put(old_path);
4776 +out_free_path:
4777 +       kfree(path);
4778 +out:
4779 +       if (ret) {
4780 +               dput(new_dentry);
4781 +               new_dentry = ERR_PTR(ret);
4782 +       }
4783 +       vxdprintk(VXD_CBIT(misc, 3),
4784 +               "cow_break_link returning with %p", new_dentry);
4785 +       return new_dentry;
4786 +}
4787 +
4788 +#endif
4789 +
4790 +int    vx_info_mnt_namespace(struct mnt_namespace *ns, char *buffer)
4791 +{
4792 +       struct path path;
4793 +       struct vfsmount *vmnt;
4794 +       char *pstr, *root;
4795 +       int length = 0;
4796 +
4797 +       pstr = kmalloc(PATH_MAX, GFP_KERNEL);
4798 +       if (!pstr)
4799 +               return 0;
4800 +
4801 +       vmnt = &ns->root->mnt;
4802 +       path.mnt = vmnt;
4803 +       path.dentry = vmnt->mnt_root;
4804 +       root = d_path(&path, pstr, PATH_MAX - 2);
4805 +       length = sprintf(buffer + length,
4806 +               "Namespace:\t%p [#%u]\n"
4807 +               "RootPath:\t%s\n",
4808 +               ns, atomic_read(&ns->count),
4809 +               root);
4810 +       kfree(pstr);
4811 +       return length;
4812 +}
4813 +
4814 +EXPORT_SYMBOL(vx_info_mnt_namespace);
4815 +
4816  /* get the link contents into pagecache */
4817  static char *page_getlink(struct dentry * dentry, struct page **ppage)
4818  {
4819 diff -NurpP --minimal linux-3.18.5/fs/namespace.c linux-3.18.5-vs2.3.7.3/fs/namespace.c
4820 --- linux-3.18.5/fs/namespace.c 2015-02-05 18:02:45.000000000 +0000
4821 +++ linux-3.18.5-vs2.3.7.3/fs/namespace.c       2015-01-19 12:08:57.000000000 +0000
4822 @@ -24,6 +24,11 @@
4823  #include <linux/magic.h>
4824  #include <linux/bootmem.h>
4825  #include <linux/task_work.h>
4826 +#include <linux/vs_base.h>
4827 +#include <linux/vs_context.h>
4828 +#include <linux/vs_tag.h>
4829 +#include <linux/vserver/space.h>
4830 +#include <linux/vserver/global.h>
4831  #include "pnode.h"
4832  #include "internal.h"
4833  
4834 @@ -897,6 +902,10 @@ vfs_kern_mount(struct file_system_type *
4835         if (!type)
4836                 return ERR_PTR(-ENODEV);
4837  
4838 +       if ((type->fs_flags & FS_BINARY_MOUNTDATA) &&
4839 +               !vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT))
4840 +               return ERR_PTR(-EPERM);
4841 +
4842         mnt = alloc_vfsmnt(name);
4843         if (!mnt)
4844                 return ERR_PTR(-ENOMEM);
4845 @@ -971,6 +980,7 @@ static struct mount *clone_mnt(struct mo
4846         mnt->mnt.mnt_root = dget(root);
4847         mnt->mnt_mountpoint = mnt->mnt.mnt_root;
4848         mnt->mnt_parent = mnt;
4849 +       mnt->mnt_tag = old->mnt_tag;
4850         lock_mount_hash();
4851         list_add_tail(&mnt->mnt_instance, &sb->s_mounts);
4852         unlock_mount_hash();
4853 @@ -1508,7 +1518,8 @@ out_unlock:
4854   */
4855  static inline bool may_mount(void)
4856  {
4857 -       return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN);
4858 +       return vx_ns_capable(current->nsproxy->mnt_ns->user_ns,
4859 +               CAP_SYS_ADMIN, VXC_SECURE_MOUNT);
4860  }
4861  
4862  /*
4863 @@ -1969,6 +1980,7 @@ static int do_change_type(struct path *p
4864                 if (err)
4865                         goto out_unlock;
4866         }
4867 +       // mnt->mnt_flags = mnt_flags;
4868  
4869         lock_mount_hash();
4870         for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))
4871 @@ -1997,12 +2009,14 @@ static bool has_locked_children(struct m
4872   * do loopback mount.
4873   */
4874  static int do_loopback(struct path *path, const char *old_name,
4875 -                               int recurse)
4876 +       vtag_t tag, unsigned long flags, int mnt_flags)
4877  {
4878         struct path old_path;
4879         struct mount *mnt = NULL, *old, *parent;
4880         struct mountpoint *mp;
4881 +       int recurse = flags & MS_REC;
4882         int err;
4883 +
4884         if (!old_name || !*old_name)
4885                 return -EINVAL;
4886         err = kern_path(old_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
4887 @@ -2079,7 +2093,7 @@ static int change_mount_flags(struct vfs
4888   * on it - tough luck.
4889   */
4890  static int do_remount(struct path *path, int flags, int mnt_flags,
4891 -                     void *data)
4892 +       void *data, vxid_t xid)
4893  {
4894         int err;
4895         struct super_block *sb = path->mnt->mnt_sb;
4896 @@ -2579,6 +2593,7 @@ long do_mount(const char *dev_name, cons
4897         struct path path;
4898         int retval = 0;
4899         int mnt_flags = 0;
4900 +       vtag_t tag = 0;
4901  
4902         /* Discard magic */
4903         if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
4904 @@ -2604,6 +2619,12 @@ long do_mount(const char *dev_name, cons
4905         if (!(flags & MS_NOATIME))
4906                 mnt_flags |= MNT_RELATIME;
4907  
4908 +       if (dx_parse_tag(data_page, &tag, 1, &mnt_flags, &flags)) {
4909 +               /* FIXME: bind and re-mounts get the tag flag? */
4910 +               if (flags & (MS_BIND|MS_REMOUNT))
4911 +                       flags |= MS_TAGID;
4912 +       }
4913 +
4914         /* Separate the per-mountpoint flags */
4915         if (flags & MS_NOSUID)
4916                 mnt_flags |= MNT_NOSUID;
4917 @@ -2628,15 +2649,17 @@ long do_mount(const char *dev_name, cons
4918                 mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK;
4919         }
4920  
4921 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_DEV_MOUNT))
4922 +               mnt_flags |= MNT_NODEV;
4923         flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN |
4924                    MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
4925                    MS_STRICTATIME);
4926  
4927         if (flags & MS_REMOUNT)
4928                 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
4929 -                                   data_page);
4930 +                                   data_page, tag);
4931         else if (flags & MS_BIND)
4932 -               retval = do_loopback(&path, dev_name, flags & MS_REC);
4933 +               retval = do_loopback(&path, dev_name, tag, flags, mnt_flags);
4934         else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
4935                 retval = do_change_type(&path, flags);
4936         else if (flags & MS_MOVE)
4937 @@ -2752,6 +2775,7 @@ struct mnt_namespace *copy_mnt_ns(unsign
4938                         p = next_mnt(p, old);
4939         }
4940         namespace_unlock();
4941 +       atomic_inc(&vs_global_mnt_ns);
4942  
4943         if (rootmnt)
4944                 mntput(rootmnt);
4945 @@ -2926,9 +2950,10 @@ SYSCALL_DEFINE2(pivot_root, const char _
4946         new_mnt = real_mount(new.mnt);
4947         root_mnt = real_mount(root.mnt);
4948         old_mnt = real_mount(old.mnt);
4949 -       if (IS_MNT_SHARED(old_mnt) ||
4950 +       if ((IS_MNT_SHARED(old_mnt) ||
4951                 IS_MNT_SHARED(new_mnt->mnt_parent) ||
4952 -               IS_MNT_SHARED(root_mnt->mnt_parent))
4953 +               IS_MNT_SHARED(root_mnt->mnt_parent)) &&
4954 +               !vx_flags(VXF_STATE_SETUP, 0))
4955                 goto out4;
4956         if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
4957                 goto out4;
4958 @@ -3063,6 +3088,7 @@ void put_mnt_ns(struct mnt_namespace *ns
4959         if (!atomic_dec_and_test(&ns->count))
4960                 return;
4961         drop_collected_mounts(&ns->root->mnt);
4962 +       atomic_dec(&vs_global_mnt_ns);
4963         free_mnt_ns(ns);
4964  }
4965  
4966 diff -NurpP --minimal linux-3.18.5/fs/nfs/client.c linux-3.18.5-vs2.3.7.3/fs/nfs/client.c
4967 --- linux-3.18.5/fs/nfs/client.c        2015-01-17 02:40:19.000000000 +0000
4968 +++ linux-3.18.5-vs2.3.7.3/fs/nfs/client.c      2015-01-19 10:58:03.000000000 +0000
4969 @@ -693,6 +693,9 @@ int nfs_init_server_rpcclient(struct nfs
4970         if (server->flags & NFS_MOUNT_SOFT)
4971                 server->client->cl_softrtry = 1;
4972  
4973 +       server->client->cl_tag = 0;
4974 +       if (server->flags & NFS_MOUNT_TAGGED)
4975 +               server->client->cl_tag = 1;
4976         return 0;
4977  }
4978  EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
4979 @@ -871,6 +874,10 @@ static void nfs_server_set_fsinfo(struct
4980                 server->acdirmin = server->acdirmax = 0;
4981         }
4982  
4983 +       /* FIXME: needs fsinfo
4984 +       if (server->flags & NFS_MOUNT_TAGGED)
4985 +               sb->s_flags |= MS_TAGGED;       */
4986 +
4987         server->maxfilesize = fsinfo->maxfilesize;
4988  
4989         server->time_delta = fsinfo->time_delta;
4990 diff -NurpP --minimal linux-3.18.5/fs/nfs/dir.c linux-3.18.5-vs2.3.7.3/fs/nfs/dir.c
4991 --- linux-3.18.5/fs/nfs/dir.c   2015-01-17 02:40:19.000000000 +0000
4992 +++ linux-3.18.5-vs2.3.7.3/fs/nfs/dir.c 2015-01-19 10:58:03.000000000 +0000
4993 @@ -37,6 +37,7 @@
4994  #include <linux/sched.h>
4995  #include <linux/kmemleak.h>
4996  #include <linux/xattr.h>
4997 +#include <linux/vs_tag.h>
4998  
4999  #include "delegation.h"
5000  #include "iostat.h"
5001 @@ -1392,6 +1393,7 @@ struct dentry *nfs_lookup(struct inode *
5002         /* Success: notify readdir to use READDIRPLUS */
5003         nfs_advise_use_readdirplus(dir);
5004  
5005 +       dx_propagate_tag(nd, inode);
5006  no_entry:
5007         res = d_materialise_unique(dentry, inode);
5008         if (res != NULL) {
5009 diff -NurpP --minimal linux-3.18.5/fs/nfs/inode.c linux-3.18.5-vs2.3.7.3/fs/nfs/inode.c
5010 --- linux-3.18.5/fs/nfs/inode.c 2015-01-17 02:40:19.000000000 +0000
5011 +++ linux-3.18.5-vs2.3.7.3/fs/nfs/inode.c       2015-01-19 11:44:24.000000000 +0000
5012 @@ -38,6 +38,7 @@
5013  #include <linux/slab.h>
5014  #include <linux/compat.h>
5015  #include <linux/freezer.h>
5016 +#include <linux/vs_tag.h>
5017  
5018  #include <asm/uaccess.h>
5019  
5020 @@ -368,6 +369,8 @@ nfs_fhget(struct super_block *sb, struct
5021         if (inode->i_state & I_NEW) {
5022                 struct nfs_inode *nfsi = NFS_I(inode);
5023                 unsigned long now = jiffies;
5024 +               kuid_t kuid;
5025 +               kgid_t kgid;
5026  
5027                 /* We set i_ino for the few things that still rely on it,
5028                  * such as stat(2) */
5029 @@ -412,8 +415,8 @@ nfs_fhget(struct super_block *sb, struct
5030                 inode->i_version = 0;
5031                 inode->i_size = 0;
5032                 clear_nlink(inode);
5033 -               inode->i_uid = make_kuid(&init_user_ns, -2);
5034 -               inode->i_gid = make_kgid(&init_user_ns, -2);
5035 +               kuid = make_kuid(&init_user_ns, -2);
5036 +               kgid = make_kgid(&init_user_ns, -2);
5037                 inode->i_blocks = 0;
5038                 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
5039                 nfsi->write_io = 0;
5040 @@ -447,11 +450,11 @@ nfs_fhget(struct super_block *sb, struct
5041                 else if (nfs_server_capable(inode, NFS_CAP_NLINK))
5042                         nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
5043                 if (fattr->valid & NFS_ATTR_FATTR_OWNER)
5044 -                       inode->i_uid = fattr->uid;
5045 +                       kuid = fattr->uid;
5046                 else if (nfs_server_capable(inode, NFS_CAP_OWNER))
5047                         nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
5048                 if (fattr->valid & NFS_ATTR_FATTR_GROUP)
5049 -                       inode->i_gid = fattr->gid;
5050 +                       kgid = fattr->gid;
5051                 else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
5052                         nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
5053                 if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
5054 @@ -462,6 +465,10 @@ nfs_fhget(struct super_block *sb, struct
5055                          */
5056                         inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
5057                 }
5058 +               inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
5059 +               inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
5060 +               inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, GLOBAL_ROOT_TAG);
5061 +                               /* maybe fattr->xid someday */
5062  
5063                 nfs_setsecurity(inode, fattr, label);
5064  
5065 @@ -592,6 +599,8 @@ void nfs_setattr_update_inode(struct ino
5066                         inode->i_uid = attr->ia_uid;
5067                 if ((attr->ia_valid & ATTR_GID) != 0)
5068                         inode->i_gid = attr->ia_gid;
5069 +               if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
5070 +                       inode->i_tag = attr->ia_tag;
5071                 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS
5072                                 | NFS_INO_INVALID_ACL);
5073                 spin_unlock(&inode->i_lock);
5074 @@ -1171,7 +1180,9 @@ static int nfs_check_inode_attributes(st
5075         struct nfs_inode *nfsi = NFS_I(inode);
5076         loff_t cur_size, new_isize;
5077         unsigned long invalid = 0;
5078 -
5079 +       kuid_t kuid;
5080 +       kgid_t kgid;
5081 +       ktag_t ktag;
5082  
5083         if (nfs_have_delegated_attributes(inode))
5084                 return 0;
5085 @@ -1196,13 +1207,18 @@ static int nfs_check_inode_attributes(st
5086                         invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
5087         }
5088  
5089 +       kuid = INOTAG_KUID(DX_TAG(inode), fattr->uid, fattr->gid);
5090 +       kgid = INOTAG_KGID(DX_TAG(inode), fattr->uid, fattr->gid);
5091 +       ktag = INOTAG_KTAG(DX_TAG(inode), fattr->uid, fattr->gid, GLOBAL_ROOT_TAG);
5092 +
5093         /* Have any file permissions changed? */
5094         if ((fattr->valid & NFS_ATTR_FATTR_MODE) && (inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO))
5095                 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
5096 -       if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, fattr->uid))
5097 +       if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, kuid))
5098                 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
5099 -       if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, fattr->gid))
5100 +       if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, kgid))
5101                 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
5102 +               /* maybe check for tag too? */
5103  
5104         /* Has the link count changed? */
5105         if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink)
5106 @@ -1533,6 +1549,9 @@ static int nfs_update_inode(struct inode
5107         unsigned long invalid = 0;
5108         unsigned long now = jiffies;
5109         unsigned long save_cache_validity;
5110 +       kuid_t kuid;
5111 +       kgid_t kgid;
5112 +       ktag_t ktag;
5113  
5114         dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
5115                         __func__, inode->i_sb->s_id, inode->i_ino,
5116 @@ -1637,6 +1656,9 @@ static int nfs_update_inode(struct inode
5117                                 | NFS_INO_REVAL_PAGECACHE
5118                                 | NFS_INO_REVAL_FORCED);
5119  
5120 +       kuid = TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag);
5121 +       kgid = TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag);
5122 +       ktag = TAGINO_KTAG(DX_TAG(inode), inode->i_tag);
5123  
5124         if (fattr->valid & NFS_ATTR_FATTR_ATIME)
5125                 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
5126 @@ -1683,6 +1705,10 @@ static int nfs_update_inode(struct inode
5127                                 | NFS_INO_INVALID_ACL
5128                                 | NFS_INO_REVAL_FORCED);
5129  
5130 +       inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
5131 +       inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
5132 +       inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, ktag);
5133 +
5134         if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
5135                 if (inode->i_nlink != fattr->nlink) {
5136                         invalid |= NFS_INO_INVALID_ATTR;
5137 diff -NurpP --minimal linux-3.18.5/fs/nfs/nfs3xdr.c linux-3.18.5-vs2.3.7.3/fs/nfs/nfs3xdr.c
5138 --- linux-3.18.5/fs/nfs/nfs3xdr.c       2014-09-03 13:19:40.000000000 +0000
5139 +++ linux-3.18.5-vs2.3.7.3/fs/nfs/nfs3xdr.c     2015-01-19 10:58:03.000000000 +0000
5140 @@ -20,6 +20,7 @@
5141  #include <linux/nfs3.h>
5142  #include <linux/nfs_fs.h>
5143  #include <linux/nfsacl.h>
5144 +#include <linux/vs_tag.h>
5145  #include "internal.h"
5146  
5147  #define NFSDBG_FACILITY                NFSDBG_XDR
5148 @@ -558,7 +559,8 @@ static __be32 *xdr_decode_nfstime3(__be3
5149   *             set_mtime       mtime;
5150   *     };
5151   */
5152 -static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
5153 +static void encode_sattr3(struct xdr_stream *xdr,
5154 +       const struct iattr *attr, int tag)
5155  {
5156         u32 nbytes;
5157         __be32 *p;
5158 @@ -590,15 +592,19 @@ static void encode_sattr3(struct xdr_str
5159         } else
5160                 *p++ = xdr_zero;
5161  
5162 -       if (attr->ia_valid & ATTR_UID) {
5163 +       if (attr->ia_valid & ATTR_UID ||
5164 +               (tag && (attr->ia_valid & ATTR_TAG))) {
5165                 *p++ = xdr_one;
5166 -               *p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));
5167 +               *p++ = cpu_to_be32(from_kuid(&init_user_ns,
5168 +                       TAGINO_KUID(tag, attr->ia_uid, attr->ia_tag)));
5169         } else
5170                 *p++ = xdr_zero;
5171  
5172 -       if (attr->ia_valid & ATTR_GID) {
5173 +       if (attr->ia_valid & ATTR_GID ||
5174 +               (tag && (attr->ia_valid & ATTR_TAG))) {
5175                 *p++ = xdr_one;
5176 -               *p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));
5177 +               *p++ = cpu_to_be32(from_kgid(&init_user_ns,
5178 +                       TAGINO_KGID(tag, attr->ia_gid, attr->ia_tag)));
5179         } else
5180                 *p++ = xdr_zero;
5181  
5182 @@ -887,7 +893,7 @@ static void nfs3_xdr_enc_setattr3args(st
5183                                       const struct nfs3_sattrargs *args)
5184  {
5185         encode_nfs_fh3(xdr, args->fh);
5186 -       encode_sattr3(xdr, args->sattr);
5187 +       encode_sattr3(xdr, args->sattr, req->rq_task->tk_client->cl_tag);
5188         encode_sattrguard3(xdr, args);
5189  }
5190  
5191 @@ -1037,13 +1043,13 @@ static void nfs3_xdr_enc_write3args(stru
5192   *     };
5193   */
5194  static void encode_createhow3(struct xdr_stream *xdr,
5195 -                             const struct nfs3_createargs *args)
5196 +       const struct nfs3_createargs *args, int tag)
5197  {
5198         encode_uint32(xdr, args->createmode);
5199         switch (args->createmode) {
5200         case NFS3_CREATE_UNCHECKED:
5201         case NFS3_CREATE_GUARDED:
5202 -               encode_sattr3(xdr, args->sattr);
5203 +               encode_sattr3(xdr, args->sattr, tag);
5204                 break;
5205         case NFS3_CREATE_EXCLUSIVE:
5206                 encode_createverf3(xdr, args->verifier);
5207 @@ -1058,7 +1064,7 @@ static void nfs3_xdr_enc_create3args(str
5208                                      const struct nfs3_createargs *args)
5209  {
5210         encode_diropargs3(xdr, args->fh, args->name, args->len);
5211 -       encode_createhow3(xdr, args);
5212 +       encode_createhow3(xdr, args, req->rq_task->tk_client->cl_tag);
5213  }
5214  
5215  /*
5216 @@ -1074,7 +1080,7 @@ static void nfs3_xdr_enc_mkdir3args(stru
5217                                     const struct nfs3_mkdirargs *args)
5218  {
5219         encode_diropargs3(xdr, args->fh, args->name, args->len);
5220 -       encode_sattr3(xdr, args->sattr);
5221 +       encode_sattr3(xdr, args->sattr, req->rq_task->tk_client->cl_tag);
5222  }
5223  
5224  /*
5225 @@ -1091,9 +1097,9 @@ static void nfs3_xdr_enc_mkdir3args(stru
5226   *     };
5227   */
5228  static void encode_symlinkdata3(struct xdr_stream *xdr,
5229 -                               const struct nfs3_symlinkargs *args)
5230 +       const struct nfs3_symlinkargs *args, int tag)
5231  {
5232 -       encode_sattr3(xdr, args->sattr);
5233 +       encode_sattr3(xdr, args->sattr, tag);
5234         encode_nfspath3(xdr, args->pages, args->pathlen);
5235  }
5236  
5237 @@ -1102,7 +1108,7 @@ static void nfs3_xdr_enc_symlink3args(st
5238                                       const struct nfs3_symlinkargs *args)
5239  {
5240         encode_diropargs3(xdr, args->fromfh, args->fromname, args->fromlen);
5241 -       encode_symlinkdata3(xdr, args);
5242 +       encode_symlinkdata3(xdr, args, req->rq_task->tk_client->cl_tag);
5243  }
5244  
5245  /*
5246 @@ -1130,24 +1136,24 @@ static void nfs3_xdr_enc_symlink3args(st
5247   *     };
5248   */
5249  static void encode_devicedata3(struct xdr_stream *xdr,
5250 -                              const struct nfs3_mknodargs *args)
5251 +       const struct nfs3_mknodargs *args, int tag)
5252  {
5253 -       encode_sattr3(xdr, args->sattr);
5254 +       encode_sattr3(xdr, args->sattr, tag);
5255         encode_specdata3(xdr, args->rdev);
5256  }
5257  
5258  static void encode_mknoddata3(struct xdr_stream *xdr,
5259 -                             const struct nfs3_mknodargs *args)
5260 +       const struct nfs3_mknodargs *args, int tag)
5261  {
5262         encode_ftype3(xdr, args->type);
5263         switch (args->type) {
5264         case NF3CHR:
5265         case NF3BLK:
5266 -               encode_devicedata3(xdr, args);
5267 +               encode_devicedata3(xdr, args, tag);
5268                 break;
5269         case NF3SOCK:
5270         case NF3FIFO:
5271 -               encode_sattr3(xdr, args->sattr);
5272 +               encode_sattr3(xdr, args->sattr, tag);
5273                 break;
5274         case NF3REG:
5275         case NF3DIR:
5276 @@ -1162,7 +1168,7 @@ static void nfs3_xdr_enc_mknod3args(stru
5277                                     const struct nfs3_mknodargs *args)
5278  {
5279         encode_diropargs3(xdr, args->fh, args->name, args->len);
5280 -       encode_mknoddata3(xdr, args);
5281 +       encode_mknoddata3(xdr, args, req->rq_task->tk_client->cl_tag);
5282  }
5283  
5284  /*
5285 diff -NurpP --minimal linux-3.18.5/fs/nfs/super.c linux-3.18.5-vs2.3.7.3/fs/nfs/super.c
5286 --- linux-3.18.5/fs/nfs/super.c 2015-01-17 02:40:19.000000000 +0000
5287 +++ linux-3.18.5-vs2.3.7.3/fs/nfs/super.c       2015-01-19 10:58:03.000000000 +0000
5288 @@ -55,6 +55,7 @@
5289  #include <linux/parser.h>
5290  #include <linux/nsproxy.h>
5291  #include <linux/rcupdate.h>
5292 +#include <linux/vs_tag.h>
5293  
5294  #include <asm/uaccess.h>
5295  
5296 @@ -103,6 +104,7 @@ enum {
5297         Opt_mountport,
5298         Opt_mountvers,
5299         Opt_minorversion,
5300 +       Opt_tagid,
5301  
5302         /* Mount options that take string arguments */
5303         Opt_nfsvers,
5304 @@ -115,6 +117,9 @@ enum {
5305         /* Special mount options */
5306         Opt_userspace, Opt_deprecated, Opt_sloppy,
5307  
5308 +       /* Linux-VServer tagging options */
5309 +       Opt_tag, Opt_notag,
5310 +
5311         Opt_err
5312  };
5313  
5314 @@ -184,6 +189,10 @@ static const match_table_t nfs_mount_opt
5315         { Opt_fscache_uniq, "fsc=%s" },
5316         { Opt_local_lock, "local_lock=%s" },
5317  
5318 +       { Opt_tag, "tag" },
5319 +       { Opt_notag, "notag" },
5320 +       { Opt_tagid, "tagid=%u" },
5321 +
5322         /* The following needs to be listed after all other options */
5323         { Opt_nfsvers, "v%s" },
5324  
5325 @@ -638,6 +647,7 @@ static void nfs_show_mount_options(struc
5326                 { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
5327                 { NFS_MOUNT_UNSHARED, ",nosharecache", "" },
5328                 { NFS_MOUNT_NORESVPORT, ",noresvport", "" },
5329 +               { NFS_MOUNT_TAGGED, ",tag", "" },
5330                 { 0, NULL, NULL }
5331         };
5332         const struct proc_nfs_info *nfs_infop;
5333 @@ -1320,6 +1330,14 @@ static int nfs_parse_mount_options(char
5334                 case Opt_nomigration:
5335                         mnt->options &= NFS_OPTION_MIGRATION;
5336                         break;
5337 +#ifndef CONFIG_TAGGING_NONE
5338 +               case Opt_tag:
5339 +                       mnt->flags |= NFS_MOUNT_TAGGED;
5340 +                       break;
5341 +               case Opt_notag:
5342 +                       mnt->flags &= ~NFS_MOUNT_TAGGED;
5343 +                       break;
5344 +#endif
5345  
5346                 /*
5347                  * options that take numeric values
5348 @@ -1406,6 +1424,12 @@ static int nfs_parse_mount_options(char
5349                                 goto out_invalid_value;
5350                         mnt->minorversion = option;
5351                         break;
5352 +#ifdef CONFIG_PROPAGATE
5353 +               case Opt_tagid:
5354 +                       /* use args[0] */
5355 +                       nfs_data.flags |= NFS_MOUNT_TAGGED;
5356 +                       break;
5357 +#endif
5358  
5359                 /*
5360                  * options that take text values
5361 diff -NurpP --minimal linux-3.18.5/fs/nfsd/auth.c linux-3.18.5-vs2.3.7.3/fs/nfsd/auth.c
5362 --- linux-3.18.5/fs/nfsd/auth.c 2015-01-16 22:19:19.000000000 +0000
5363 +++ linux-3.18.5-vs2.3.7.3/fs/nfsd/auth.c       2015-01-19 12:46:19.000000000 +0000
5364 @@ -1,6 +1,7 @@
5365  /* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
5366  
5367  #include <linux/sched.h>
5368 +#include <linux/vs_tag.h>
5369  #include "nfsd.h"
5370  #include "auth.h"
5371  
5372 @@ -35,6 +36,9 @@ int nfsd_setuser(struct svc_rqst *rqstp,
5373  
5374         new->fsuid = rqstp->rq_cred.cr_uid;
5375         new->fsgid = rqstp->rq_cred.cr_gid;
5376 +       /* FIXME: this desperately needs a tag :)
5377 +       new->xid = (vxid_t)INOTAG_TAG(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid, 0);
5378 +                       */
5379  
5380         rqgi = rqstp->rq_cred.cr_group_info;
5381  
5382 diff -NurpP --minimal linux-3.18.5/fs/nfsd/nfs3xdr.c linux-3.18.5-vs2.3.7.3/fs/nfsd/nfs3xdr.c
5383 --- linux-3.18.5/fs/nfsd/nfs3xdr.c      2015-01-16 22:19:19.000000000 +0000
5384 +++ linux-3.18.5-vs2.3.7.3/fs/nfsd/nfs3xdr.c    2015-01-19 10:58:03.000000000 +0000
5385 @@ -8,6 +8,7 @@
5386  
5387  #include <linux/namei.h>
5388  #include <linux/sunrpc/svc_xprt.h>
5389 +#include <linux/vs_tag.h>
5390  #include "xdr3.h"
5391  #include "auth.h"
5392  #include "netns.h"
5393 @@ -98,6 +99,8 @@ static __be32 *
5394  decode_sattr3(__be32 *p, struct iattr *iap)
5395  {
5396         u32     tmp;
5397 +       kuid_t  kuid = GLOBAL_ROOT_UID;
5398 +       kgid_t  kgid = GLOBAL_ROOT_GID;
5399  
5400         iap->ia_valid = 0;
5401  
5402 @@ -106,15 +109,18 @@ decode_sattr3(__be32 *p, struct iattr *i
5403                 iap->ia_mode = ntohl(*p++);
5404         }
5405         if (*p++) {
5406 -               iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++));
5407 +               kuid = make_kuid(&init_user_ns, ntohl(*p++));
5408                 if (uid_valid(iap->ia_uid))
5409                         iap->ia_valid |= ATTR_UID;
5410         }
5411         if (*p++) {
5412 -               iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++));
5413 +               kgid = make_kgid(&init_user_ns, ntohl(*p++));
5414                 if (gid_valid(iap->ia_gid))
5415                         iap->ia_valid |= ATTR_GID;
5416         }
5417 +       iap->ia_uid = INOTAG_KUID(DX_TAG_NFSD, kuid, kgid);
5418 +       iap->ia_gid = INOTAG_KGID(DX_TAG_NFSD, kuid, kgid);
5419 +       iap->ia_tag = INOTAG_KTAG(DX_TAG_NFSD, kuid, kgid, GLOBAL_ROOT_TAG);
5420         if (*p++) {
5421                 u64     newsize;
5422  
5423 @@ -167,8 +173,12 @@ encode_fattr3(struct svc_rqst *rqstp, __
5424         *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
5425         *p++ = htonl((u32) (stat->mode & S_IALLUGO));
5426         *p++ = htonl((u32) stat->nlink);
5427 -       *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
5428 -       *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
5429 +       *p++ = htonl((u32) from_kuid(&init_user_ns,
5430 +               TAGINO_KUID(0 /* FIXME: DX_TAG(dentry->d_inode) */,
5431 +               stat->uid, stat->tag)));
5432 +       *p++ = htonl((u32) from_kgid(&init_user_ns,
5433 +               TAGINO_KGID(0 /* FIXME: DX_TAG(dentry->d_inode) */,
5434 +               stat->gid, stat->tag)));
5435         if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
5436                 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
5437         } else {
5438 diff -NurpP --minimal linux-3.18.5/fs/nfsd/nfs4xdr.c linux-3.18.5-vs2.3.7.3/fs/nfsd/nfs4xdr.c
5439 --- linux-3.18.5/fs/nfsd/nfs4xdr.c      2015-02-05 18:02:45.000000000 +0000
5440 +++ linux-3.18.5-vs2.3.7.3/fs/nfsd/nfs4xdr.c    2015-01-19 12:45:51.000000000 +0000
5441 @@ -39,6 +39,7 @@
5442  #include <linux/utsname.h>
5443  #include <linux/pagemap.h>
5444  #include <linux/sunrpc/svcauth_gss.h>
5445 +#include <linux/vs_tag.h>
5446  
5447  #include "idmap.h"
5448  #include "acl.h"
5449 @@ -2436,12 +2437,16 @@ out_acl:
5450                 *p++ = cpu_to_be32(stat.nlink);
5451         }
5452         if (bmval1 & FATTR4_WORD1_OWNER) {
5453 -               status = nfsd4_encode_user(xdr, rqstp, stat.uid);
5454 +               status = nfsd4_encode_user(xdr, rqstp,
5455 +                       TAGINO_KUID(DX_TAG(dentry->d_inode),
5456 +                               stat.uid, stat.tag));
5457                 if (status)
5458                         goto out;
5459         }
5460         if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
5461 -               status = nfsd4_encode_group(xdr, rqstp, stat.gid);
5462 +               status = nfsd4_encode_group(xdr, rqstp,
5463 +                       TAGINO_KGID(DX_TAG(dentry->d_inode),
5464 +                               stat.gid, stat.tag));
5465                 if (status)
5466                         goto out;
5467         }
5468 diff -NurpP --minimal linux-3.18.5/fs/nfsd/nfsxdr.c linux-3.18.5-vs2.3.7.3/fs/nfsd/nfsxdr.c
5469 --- linux-3.18.5/fs/nfsd/nfsxdr.c       2015-01-16 22:19:19.000000000 +0000
5470 +++ linux-3.18.5-vs2.3.7.3/fs/nfsd/nfsxdr.c     2015-01-19 10:58:03.000000000 +0000
5471 @@ -7,6 +7,7 @@
5472  #include "vfs.h"
5473  #include "xdr.h"
5474  #include "auth.h"
5475 +#include <linux/vs_tag.h>
5476  
5477  #define NFSDDBG_FACILITY               NFSDDBG_XDR
5478  
5479 @@ -89,6 +90,8 @@ static __be32 *
5480  decode_sattr(__be32 *p, struct iattr *iap)
5481  {
5482         u32     tmp, tmp1;
5483 +       kuid_t  kuid = GLOBAL_ROOT_UID;
5484 +       kgid_t  kgid = GLOBAL_ROOT_GID;
5485  
5486         iap->ia_valid = 0;
5487  
5488 @@ -101,15 +104,18 @@ decode_sattr(__be32 *p, struct iattr *ia
5489                 iap->ia_mode = tmp;
5490         }
5491         if ((tmp = ntohl(*p++)) != (u32)-1) {
5492 -               iap->ia_uid = make_kuid(&init_user_ns, tmp);
5493 +               kuid = make_kuid(&init_user_ns, tmp);
5494                 if (uid_valid(iap->ia_uid))
5495                         iap->ia_valid |= ATTR_UID;
5496         }
5497         if ((tmp = ntohl(*p++)) != (u32)-1) {
5498 -               iap->ia_gid = make_kgid(&init_user_ns, tmp);
5499 +               kgid = make_kgid(&init_user_ns, tmp);
5500                 if (gid_valid(iap->ia_gid))
5501                         iap->ia_valid |= ATTR_GID;
5502         }
5503 +       iap->ia_uid = INOTAG_KUID(DX_TAG_NFSD, kuid, kgid);
5504 +       iap->ia_gid = INOTAG_KGID(DX_TAG_NFSD, kuid, kgid);
5505 +       iap->ia_tag = INOTAG_KTAG(DX_TAG_NFSD, kuid, kgid, GLOBAL_ROOT_TAG);
5506         if ((tmp = ntohl(*p++)) != (u32)-1) {
5507                 iap->ia_valid |= ATTR_SIZE;
5508                 iap->ia_size = tmp;
5509 @@ -154,8 +160,10 @@ encode_fattr(struct svc_rqst *rqstp, __b
5510         *p++ = htonl(nfs_ftypes[type >> 12]);
5511         *p++ = htonl((u32) stat->mode);
5512         *p++ = htonl((u32) stat->nlink);
5513 -       *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
5514 -       *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
5515 +       *p++ = htonl((u32) from_kuid(&init_user_ns,
5516 +               TAGINO_KUID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
5517 +       *p++ = htonl((u32) from_kgid(&init_user_ns,
5518 +               TAGINO_KGID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
5519  
5520         if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
5521                 *p++ = htonl(NFS_MAXPATHLEN);
5522 diff -NurpP --minimal linux-3.18.5/fs/ocfs2/dlmglue.c linux-3.18.5-vs2.3.7.3/fs/ocfs2/dlmglue.c
5523 --- linux-3.18.5/fs/ocfs2/dlmglue.c     2015-01-17 02:40:20.000000000 +0000
5524 +++ linux-3.18.5-vs2.3.7.3/fs/ocfs2/dlmglue.c   2015-01-19 10:58:03.000000000 +0000
5525 @@ -2047,6 +2047,7 @@ static void __ocfs2_stuff_meta_lvb(struc
5526         lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
5527         lvb->lvb_iuid      = cpu_to_be32(i_uid_read(inode));
5528         lvb->lvb_igid      = cpu_to_be32(i_gid_read(inode));
5529 +       lvb->lvb_itag      = cpu_to_be16(i_tag_read(inode));
5530         lvb->lvb_imode     = cpu_to_be16(inode->i_mode);
5531         lvb->lvb_inlink    = cpu_to_be16(inode->i_nlink);
5532         lvb->lvb_iatime_packed  =
5533 @@ -2097,6 +2098,7 @@ static void ocfs2_refresh_inode_from_lvb
5534  
5535         i_uid_write(inode, be32_to_cpu(lvb->lvb_iuid));
5536         i_gid_write(inode, be32_to_cpu(lvb->lvb_igid));
5537 +       i_tag_write(inode, be16_to_cpu(lvb->lvb_itag));
5538         inode->i_mode    = be16_to_cpu(lvb->lvb_imode);
5539         set_nlink(inode, be16_to_cpu(lvb->lvb_inlink));
5540         ocfs2_unpack_timespec(&inode->i_atime,
5541 diff -NurpP --minimal linux-3.18.5/fs/ocfs2/dlmglue.h linux-3.18.5-vs2.3.7.3/fs/ocfs2/dlmglue.h
5542 --- linux-3.18.5/fs/ocfs2/dlmglue.h     2014-06-12 13:02:45.000000000 +0000
5543 +++ linux-3.18.5-vs2.3.7.3/fs/ocfs2/dlmglue.h   2015-01-19 10:58:03.000000000 +0000
5544 @@ -46,7 +46,8 @@ struct ocfs2_meta_lvb {
5545         __be16       lvb_inlink;
5546         __be32       lvb_iattr;
5547         __be32       lvb_igeneration;
5548 -       __be32       lvb_reserved2;
5549 +       __be16       lvb_itag;
5550 +       __be16       lvb_reserved2;
5551  };
5552  
5553  #define OCFS2_QINFO_LVB_VERSION 1
5554 diff -NurpP --minimal linux-3.18.5/fs/ocfs2/file.c linux-3.18.5-vs2.3.7.3/fs/ocfs2/file.c
5555 --- linux-3.18.5/fs/ocfs2/file.c        2015-01-17 02:40:20.000000000 +0000
5556 +++ linux-3.18.5-vs2.3.7.3/fs/ocfs2/file.c      2015-01-19 10:58:03.000000000 +0000
5557 @@ -1139,7 +1139,7 @@ int ocfs2_setattr(struct dentry *dentry,
5558                 attr->ia_valid &= ~ATTR_SIZE;
5559  
5560  #define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \
5561 -                          | ATTR_GID | ATTR_UID | ATTR_MODE)
5562 +                          | ATTR_GID | ATTR_UID | ATTR_TAG | ATTR_MODE)
5563         if (!(attr->ia_valid & OCFS2_VALID_ATTRS))
5564                 return 0;
5565  
5566 diff -NurpP --minimal linux-3.18.5/fs/ocfs2/inode.c linux-3.18.5-vs2.3.7.3/fs/ocfs2/inode.c
5567 --- linux-3.18.5/fs/ocfs2/inode.c       2014-06-12 13:02:45.000000000 +0000
5568 +++ linux-3.18.5-vs2.3.7.3/fs/ocfs2/inode.c     2015-01-19 10:58:03.000000000 +0000
5569 @@ -28,6 +28,7 @@
5570  #include <linux/highmem.h>
5571  #include <linux/pagemap.h>
5572  #include <linux/quotaops.h>
5573 +#include <linux/vs_tag.h>
5574  
5575  #include <asm/byteorder.h>
5576  
5577 @@ -78,11 +79,13 @@ void ocfs2_set_inode_flags(struct inode
5578  {
5579         unsigned int flags = OCFS2_I(inode)->ip_attr;
5580  
5581 -       inode->i_flags &= ~(S_IMMUTABLE |
5582 +       inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK |
5583                 S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
5584  
5585         if (flags & OCFS2_IMMUTABLE_FL)
5586                 inode->i_flags |= S_IMMUTABLE;
5587 +       if (flags & OCFS2_IXUNLINK_FL)
5588 +               inode->i_flags |= S_IXUNLINK;
5589  
5590         if (flags & OCFS2_SYNC_FL)
5591                 inode->i_flags |= S_SYNC;
5592 @@ -92,25 +95,44 @@ void ocfs2_set_inode_flags(struct inode
5593                 inode->i_flags |= S_NOATIME;
5594         if (flags & OCFS2_DIRSYNC_FL)
5595                 inode->i_flags |= S_DIRSYNC;
5596 +
5597 +       inode->i_vflags &= ~(V_BARRIER | V_COW);
5598 +
5599 +       if (flags & OCFS2_BARRIER_FL)
5600 +               inode->i_vflags |= V_BARRIER;
5601 +       if (flags & OCFS2_COW_FL)
5602 +               inode->i_vflags |= V_COW;
5603  }
5604  
5605  /* Propagate flags from i_flags to OCFS2_I(inode)->ip_attr */
5606  void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi)
5607  {
5608         unsigned int flags = oi->vfs_inode.i_flags;
5609 +       unsigned int vflags = oi->vfs_inode.i_vflags;
5610 +
5611 +       oi->ip_attr &= ~(OCFS2_SYNC_FL | OCFS2_APPEND_FL |
5612 +                       OCFS2_IMMUTABLE_FL | OCFS2_IXUNLINK_FL |
5613 +                       OCFS2_NOATIME_FL | OCFS2_DIRSYNC_FL |
5614 +                       OCFS2_BARRIER_FL | OCFS2_COW_FL);
5615 +
5616 +       if (flags & S_IMMUTABLE)
5617 +               oi->ip_attr |= OCFS2_IMMUTABLE_FL;
5618 +       if (flags & S_IXUNLINK)
5619 +               oi->ip_attr |= OCFS2_IXUNLINK_FL;
5620  
5621 -       oi->ip_attr &= ~(OCFS2_SYNC_FL|OCFS2_APPEND_FL|
5622 -                       OCFS2_IMMUTABLE_FL|OCFS2_NOATIME_FL|OCFS2_DIRSYNC_FL);
5623         if (flags & S_SYNC)
5624                 oi->ip_attr |= OCFS2_SYNC_FL;
5625         if (flags & S_APPEND)
5626                 oi->ip_attr |= OCFS2_APPEND_FL;
5627 -       if (flags & S_IMMUTABLE)
5628 -               oi->ip_attr |= OCFS2_IMMUTABLE_FL;
5629         if (flags & S_NOATIME)
5630                 oi->ip_attr |= OCFS2_NOATIME_FL;
5631         if (flags & S_DIRSYNC)
5632                 oi->ip_attr |= OCFS2_DIRSYNC_FL;
5633 +
5634 +       if (vflags & V_BARRIER)
5635 +               oi->ip_attr |= OCFS2_BARRIER_FL;
5636 +       if (vflags & V_COW)
5637 +               oi->ip_attr |= OCFS2_COW_FL;
5638  }
5639  
5640  struct inode *ocfs2_ilookup(struct super_block *sb, u64 blkno)
5641 @@ -268,6 +290,8 @@ void ocfs2_populate_inode(struct inode *
5642         struct super_block *sb;
5643         struct ocfs2_super *osb;
5644         int use_plocks = 1;
5645 +       uid_t uid;
5646 +       gid_t gid;
5647  
5648         sb = inode->i_sb;
5649         osb = OCFS2_SB(sb);
5650 @@ -296,8 +320,12 @@ void ocfs2_populate_inode(struct inode *
5651         inode->i_generation = le32_to_cpu(fe->i_generation);
5652         inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
5653         inode->i_mode = le16_to_cpu(fe->i_mode);
5654 -       i_uid_write(inode, le32_to_cpu(fe->i_uid));
5655 -       i_gid_write(inode, le32_to_cpu(fe->i_gid));
5656 +       uid = le32_to_cpu(fe->i_uid);
5657 +       gid = le32_to_cpu(fe->i_gid);
5658 +       i_uid_write(inode, INOTAG_UID(DX_TAG(inode), uid, gid));
5659 +       i_gid_write(inode, INOTAG_GID(DX_TAG(inode), uid, gid));
5660 +       i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), uid, gid,
5661 +               /* le16_to_cpu(raw_inode->i_raw_tag) */ 0));
5662  
5663         /* Fast symlinks will have i_size but no allocated clusters. */
5664         if (S_ISLNK(inode->i_mode) && !fe->i_clusters) {
5665 diff -NurpP --minimal linux-3.18.5/fs/ocfs2/inode.h linux-3.18.5-vs2.3.7.3/fs/ocfs2/inode.h
5666 --- linux-3.18.5/fs/ocfs2/inode.h       2015-01-17 02:40:20.000000000 +0000
5667 +++ linux-3.18.5-vs2.3.7.3/fs/ocfs2/inode.h     2015-01-19 10:58:03.000000000 +0000
5668 @@ -157,6 +157,7 @@ struct buffer_head *ocfs2_bread(struct i
5669  
5670  void ocfs2_set_inode_flags(struct inode *inode);
5671  void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi);
5672 +int ocfs2_sync_flags(struct inode *inode, int, int);
5673  
5674  static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode)
5675  {
5676 diff -NurpP --minimal linux-3.18.5/fs/ocfs2/ioctl.c linux-3.18.5-vs2.3.7.3/fs/ocfs2/ioctl.c
5677 --- linux-3.18.5/fs/ocfs2/ioctl.c       2015-01-16 22:19:19.000000000 +0000
5678 +++ linux-3.18.5-vs2.3.7.3/fs/ocfs2/ioctl.c     2015-01-19 10:58:03.000000000 +0000
5679 @@ -76,7 +76,41 @@ static int ocfs2_get_inode_attr(struct i
5680         return status;
5681  }
5682  
5683 -static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
5684 +int ocfs2_sync_flags(struct inode *inode, int flags, int vflags)
5685 +{
5686 +       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
5687 +       struct buffer_head *bh = NULL;
5688 +       handle_t *handle = NULL;
5689 +       int status;
5690 +
5691 +       status = ocfs2_inode_lock(inode, &bh, 1);
5692 +       if (status < 0) {
5693 +               mlog_errno(status);
5694 +               return status;
5695 +       }
5696 +       handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
5697 +       if (IS_ERR(handle)) {
5698 +               status = PTR_ERR(handle);
5699 +               mlog_errno(status);
5700 +               goto bail_unlock;
5701 +       }
5702 +
5703 +       inode->i_flags = flags;
5704 +       inode->i_vflags = vflags;
5705 +       ocfs2_get_inode_flags(OCFS2_I(inode));
5706 +
5707 +       status = ocfs2_mark_inode_dirty(handle, inode, bh);
5708 +       if (status < 0)
5709 +               mlog_errno(status);
5710 +
5711 +       ocfs2_commit_trans(osb, handle);
5712 +bail_unlock:
5713 +       ocfs2_inode_unlock(inode, 1);
5714 +       brelse(bh);
5715 +       return status;
5716 +}
5717 +
5718 +int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
5719                                 unsigned mask)
5720  {
5721         struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
5722 @@ -116,6 +150,11 @@ static int ocfs2_set_inode_attr(struct i
5723                         goto bail_unlock;
5724         }
5725  
5726 +       if (IS_BARRIER(inode)) {
5727 +               vxwprintk_task(1, "messing with the barrier.");
5728 +               goto bail_unlock;
5729 +       }
5730 +
5731         handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
5732         if (IS_ERR(handle)) {
5733                 status = PTR_ERR(handle);
5734 @@ -841,6 +880,7 @@ bail:
5735         return status;
5736  }
5737  
5738 +
5739  long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
5740  {
5741         struct inode *inode = file_inode(filp);
5742 diff -NurpP --minimal linux-3.18.5/fs/ocfs2/namei.c linux-3.18.5-vs2.3.7.3/fs/ocfs2/namei.c
5743 --- linux-3.18.5/fs/ocfs2/namei.c       2015-02-05 18:02:45.000000000 +0000
5744 +++ linux-3.18.5-vs2.3.7.3/fs/ocfs2/namei.c     2015-01-19 12:15:49.000000000 +0000
5745 @@ -41,6 +41,7 @@
5746  #include <linux/slab.h>
5747  #include <linux/highmem.h>
5748  #include <linux/quotaops.h>
5749 +#include <linux/vs_tag.h>
5750  
5751  #include <cluster/masklog.h>
5752  
5753 @@ -524,6 +525,7 @@ static int __ocfs2_mknod_locked(struct i
5754         struct ocfs2_extent_list *fel;
5755         u16 feat;
5756         struct ocfs2_inode_info *oi = OCFS2_I(inode);
5757 +       ktag_t ktag;
5758  
5759         *new_fe_bh = NULL;
5760  
5761 @@ -561,8 +563,13 @@ static int __ocfs2_mknod_locked(struct i
5762         fe->i_suballoc_loc = cpu_to_le64(suballoc_loc);
5763         fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
5764         fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
5765 -       fe->i_uid = cpu_to_le32(i_uid_read(inode));
5766 -       fe->i_gid = cpu_to_le32(i_gid_read(inode));
5767 +
5768 +       ktag = make_ktag(&init_user_ns, dx_current_fstag(osb->sb));
5769 +       fe->i_uid = cpu_to_le32(from_kuid(&init_user_ns,
5770 +               TAGINO_KUID(DX_TAG(inode), inode->i_uid, ktag)));
5771 +       fe->i_gid = cpu_to_le32(from_kgid(&init_user_ns,
5772 +               TAGINO_KGID(DX_TAG(inode), inode->i_gid, ktag)));
5773 +       inode->i_tag = ktag; /* is this correct? */
5774         fe->i_mode = cpu_to_le16(inode->i_mode);
5775         if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
5776                 fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
5777 diff -NurpP --minimal linux-3.18.5/fs/ocfs2/ocfs2.h linux-3.18.5-vs2.3.7.3/fs/ocfs2/ocfs2.h
5778 --- linux-3.18.5/fs/ocfs2/ocfs2.h       2014-09-03 13:19:40.000000000 +0000
5779 +++ linux-3.18.5-vs2.3.7.3/fs/ocfs2/ocfs2.h     2015-01-19 10:58:03.000000000 +0000
5780 @@ -273,6 +273,7 @@ enum ocfs2_mount_options
5781                                                      writes */
5782         OCFS2_MOUNT_HB_NONE = 1 << 13, /* No heartbeat */
5783         OCFS2_MOUNT_HB_GLOBAL = 1 << 14, /* Global heartbeat */
5784 +       OCFS2_MOUNT_TAGGED = 1 << 15, /* use tagging */
5785  };
5786  
5787  #define OCFS2_OSB_SOFT_RO      0x0001
5788 diff -NurpP --minimal linux-3.18.5/fs/ocfs2/ocfs2_fs.h linux-3.18.5-vs2.3.7.3/fs/ocfs2/ocfs2_fs.h
5789 --- linux-3.18.5/fs/ocfs2/ocfs2_fs.h    2012-12-11 03:30:57.000000000 +0000
5790 +++ linux-3.18.5-vs2.3.7.3/fs/ocfs2/ocfs2_fs.h  2015-01-19 10:58:03.000000000 +0000
5791 @@ -266,6 +266,11 @@
5792  #define OCFS2_TOPDIR_FL                        FS_TOPDIR_FL    /* Top of directory hierarchies*/
5793  #define OCFS2_RESERVED_FL              FS_RESERVED_FL  /* reserved for ext2 lib */
5794  
5795 +#define OCFS2_IXUNLINK_FL              FS_IXUNLINK_FL  /* Immutable invert on unlink */
5796 +
5797 +#define OCFS2_BARRIER_FL               FS_BARRIER_FL   /* Barrier for chroot() */
5798 +#define OCFS2_COW_FL                   FS_COW_FL       /* Copy on Write marker */
5799 +
5800  #define OCFS2_FL_VISIBLE               FS_FL_USER_VISIBLE      /* User visible flags */
5801  #define OCFS2_FL_MODIFIABLE            FS_FL_USER_MODIFIABLE   /* User modifiable flags */
5802  
5803 diff -NurpP --minimal linux-3.18.5/fs/ocfs2/super.c linux-3.18.5-vs2.3.7.3/fs/ocfs2/super.c
5804 --- linux-3.18.5/fs/ocfs2/super.c       2015-01-17 02:40:20.000000000 +0000
5805 +++ linux-3.18.5-vs2.3.7.3/fs/ocfs2/super.c     2015-01-19 10:58:03.000000000 +0000
5806 @@ -185,6 +185,7 @@ enum {
5807         Opt_coherency_full,
5808         Opt_resv_level,
5809         Opt_dir_resv_level,
5810 +       Opt_tag, Opt_notag, Opt_tagid,
5811         Opt_err,
5812  };
5813  
5814 @@ -216,6 +217,9 @@ static const match_table_t tokens = {
5815         {Opt_coherency_full, "coherency=full"},
5816         {Opt_resv_level, "resv_level=%u"},
5817         {Opt_dir_resv_level, "dir_resv_level=%u"},
5818 +       {Opt_tag, "tag"},
5819 +       {Opt_notag, "notag"},
5820 +       {Opt_tagid, "tagid=%u"},
5821         {Opt_err, NULL}
5822  };
5823  
5824 @@ -666,6 +670,13 @@ static int ocfs2_remount(struct super_bl
5825                 goto out;
5826         }
5827  
5828 +       if ((osb->s_mount_opt & OCFS2_MOUNT_TAGGED) !=
5829 +           (parsed_options.mount_opt & OCFS2_MOUNT_TAGGED)) {
5830 +               ret = -EINVAL;
5831 +               mlog(ML_ERROR, "Cannot change tagging on remount\n");
5832 +               goto out;
5833 +       }
5834 +
5835         /* We're going to/from readonly mode. */
5836         if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
5837                 /* Disable quota accounting before remounting RO */
5838 @@ -1185,6 +1196,9 @@ static int ocfs2_fill_super(struct super
5839  
5840         ocfs2_complete_mount_recovery(osb);
5841  
5842 +       if (osb->s_mount_opt & OCFS2_MOUNT_TAGGED)
5843 +               sb->s_flags |= MS_TAGGED;
5844 +
5845         if (ocfs2_mount_local(osb))
5846                 snprintf(nodestr, sizeof(nodestr), "local");
5847         else
5848 @@ -1493,6 +1507,20 @@ static int ocfs2_parse_options(struct su
5849                             option < OCFS2_MAX_RESV_LEVEL)
5850                                 mopt->dir_resv_level = option;
5851                         break;
5852 +#ifndef CONFIG_TAGGING_NONE
5853 +               case Opt_tag:
5854 +                       mopt->mount_opt |= OCFS2_MOUNT_TAGGED;
5855 +                       break;
5856 +               case Opt_notag:
5857 +                       mopt->mount_opt &= ~OCFS2_MOUNT_TAGGED;
5858 +                       break;
5859 +#endif
5860 +#ifdef CONFIG_PROPAGATE
5861 +               case Opt_tagid:
5862 +                       /* use args[0] */
5863 +                       mopt->mount_opt |= OCFS2_MOUNT_TAGGED;
5864 +                       break;
5865 +#endif
5866                 default:
5867                         mlog(ML_ERROR,
5868                              "Unrecognized mount option \"%s\" "
5869 diff -NurpP --minimal linux-3.18.5/fs/open.c linux-3.18.5-vs2.3.7.3/fs/open.c
5870 --- linux-3.18.5/fs/open.c      2015-01-17 02:40:20.000000000 +0000
5871 +++ linux-3.18.5-vs2.3.7.3/fs/open.c    2015-01-19 10:58:03.000000000 +0000
5872 @@ -31,6 +31,11 @@
5873  #include <linux/ima.h>
5874  #include <linux/dnotify.h>
5875  #include <linux/compat.h>
5876 +#include <linux/vs_base.h>
5877 +#include <linux/vs_limit.h>
5878 +#include <linux/vs_tag.h>
5879 +#include <linux/vs_cowbl.h>
5880 +#include <linux/vserver/dlimit.h>
5881  
5882  #include "internal.h"
5883  
5884 @@ -68,6 +73,11 @@ long vfs_truncate(struct path *path, lof
5885         struct inode *inode;
5886         long error;
5887  
5888 +#ifdef CONFIG_VSERVER_COWBL
5889 +       error = cow_check_and_break(path);
5890 +       if (error)
5891 +               goto out;
5892 +#endif
5893         inode = path->dentry->d_inode;
5894  
5895         /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
5896 @@ -530,6 +540,13 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
5897         unsigned int lookup_flags = LOOKUP_FOLLOW;
5898  retry:
5899         error = user_path_at(dfd, filename, lookup_flags, &path);
5900 +#ifdef CONFIG_VSERVER_COWBL
5901 +       if (!error) {
5902 +               error = cow_check_and_break(&path);
5903 +               if (error)
5904 +                       path_put(&path);
5905 +       }
5906 +#endif
5907         if (!error) {
5908                 error = chmod_common(&path, mode);
5909                 path_put(&path);
5910 @@ -563,13 +580,15 @@ static int chown_common(struct path *pat
5911                 if (!uid_valid(uid))
5912                         return -EINVAL;
5913                 newattrs.ia_valid |= ATTR_UID;
5914 -               newattrs.ia_uid = uid;
5915 +               newattrs.ia_uid = make_kuid(&init_user_ns,
5916 +                       dx_map_uid(user));
5917         }
5918         if (group != (gid_t) -1) {
5919                 if (!gid_valid(gid))
5920                         return -EINVAL;
5921                 newattrs.ia_valid |= ATTR_GID;
5922 -               newattrs.ia_gid = gid;
5923 +               newattrs.ia_gid = make_kgid(&init_user_ns,
5924 +                       dx_map_gid(group));
5925         }
5926         if (!S_ISDIR(inode->i_mode))
5927                 newattrs.ia_valid |=
5928 @@ -608,6 +627,18 @@ retry:
5929         error = mnt_want_write(path.mnt);
5930         if (error)
5931                 goto out_release;
5932 +#ifdef CONFIG_VSERVER_COWBL
5933 +       error = cow_check_and_break(&path);
5934 +       if (!error)
5935 +#endif
5936 +#ifdef CONFIG_VSERVER_COWBL
5937 +       error = cow_check_and_break(&path);
5938 +       if (!error)
5939 +#endif
5940 +#ifdef CONFIG_VSERVER_COWBL
5941 +       error = cow_check_and_break(&path);
5942 +       if (!error)
5943 +#endif
5944         error = chown_common(&path, user, group);
5945         mnt_drop_write(path.mnt);
5946  out_release:
5947 diff -NurpP --minimal linux-3.18.5/fs/proc/array.c linux-3.18.5-vs2.3.7.3/fs/proc/array.c
5948 --- linux-3.18.5/fs/proc/array.c        2015-01-16 22:19:20.000000000 +0000
5949 +++ linux-3.18.5-vs2.3.7.3/fs/proc/array.c      2015-01-21 06:37:56.000000000 +0000
5950 @@ -82,6 +82,8 @@
5951  #include <linux/ptrace.h>
5952  #include <linux/tracehook.h>
5953  #include <linux/user_namespace.h>
5954 +#include <linux/vs_context.h>
5955 +#include <linux/vs_network.h>
5956  
5957  #include <asm/pgtable.h>
5958  #include <asm/processor.h>
5959 @@ -164,6 +166,9 @@ static inline void task_state(struct seq
5960         rcu_read_lock();
5961         ppid = pid_alive(p) ?
5962                 task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
5963 +       if (unlikely(vx_current_initpid(p->pid)))
5964 +               ppid = 0;
5965 +
5966         tpid = 0;
5967         if (pid_alive(p)) {
5968                 struct task_struct *tracer = ptrace_parent(p);
5969 @@ -289,8 +294,8 @@ static inline void task_sig(struct seq_f
5970         render_sigset_t(m, "SigCgt:\t", &caught);
5971  }
5972  
5973 -static void render_cap_t(struct seq_file *m, const char *header,
5974 -                       kernel_cap_t *a)
5975 +void render_cap_t(struct seq_file *m, const char *header,
5976 +                       struct vx_info *vxi, kernel_cap_t *a)
5977  {
5978         unsigned __capi;
5979  
5980 @@ -315,10 +320,11 @@ static inline void task_cap(struct seq_f
5981         cap_bset        = cred->cap_bset;
5982         rcu_read_unlock();
5983  
5984 -       render_cap_t(m, "CapInh:\t", &cap_inheritable);
5985 -       render_cap_t(m, "CapPrm:\t", &cap_permitted);
5986 -       render_cap_t(m, "CapEff:\t", &cap_effective);
5987 -       render_cap_t(m, "CapBnd:\t", &cap_bset);
5988 +       /* FIXME: maybe move the p->vx_info masking to __task_cred() ? */
5989 +       render_cap_t(m, "CapInh:\t", p->vx_info, &cap_inheritable);
5990 +       render_cap_t(m, "CapPrm:\t", p->vx_info, &cap_permitted);
5991 +       render_cap_t(m, "CapEff:\t", p->vx_info, &cap_effective);
5992 +       render_cap_t(m, "CapBnd:\t", p->vx_info, &cap_bset);
5993  }
5994  
5995  static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
5996 @@ -347,6 +353,43 @@ static void task_cpus_allowed(struct seq
5997         seq_putc(m, '\n');
5998  }
5999  
6000 +int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
6001 +                       struct pid *pid, struct task_struct *task)
6002 +{
6003 +       seq_printf(m,   "Proxy:\t%p(%c)\n"
6004 +                       "Count:\t%u\n"
6005 +                       "uts:\t%p(%c)\n"
6006 +                       "ipc:\t%p(%c)\n"
6007 +                       "mnt:\t%p(%c)\n"
6008 +                       "pid:\t%p(%c)\n"
6009 +                       "net:\t%p(%c)\n",
6010 +                       task->nsproxy,
6011 +                       (task->nsproxy == init_task.nsproxy ? 'I' : '-'),
6012 +                       atomic_read(&task->nsproxy->count),
6013 +                       task->nsproxy->uts_ns,
6014 +                       (task->nsproxy->uts_ns == init_task.nsproxy->uts_ns ? 'I' : '-'),
6015 +                       task->nsproxy->ipc_ns,
6016 +                       (task->nsproxy->ipc_ns == init_task.nsproxy->ipc_ns ? 'I' : '-'),
6017 +                       task->nsproxy->mnt_ns,
6018 +                       (task->nsproxy->mnt_ns == init_task.nsproxy->mnt_ns ? 'I' : '-'),
6019 +                       task->nsproxy->pid_ns_for_children,
6020 +                       (task->nsproxy->pid_ns_for_children ==
6021 +                               init_task.nsproxy->pid_ns_for_children ? 'I' : '-'),
6022 +                       task->nsproxy->net_ns,
6023 +                       (task->nsproxy->net_ns == init_task.nsproxy->net_ns ? 'I' : '-'));
6024 +       return 0;
6025 +}
6026 +
6027 +void task_vs_id(struct seq_file *m, struct task_struct *task)
6028 +{
6029 +       if (task_vx_flags(task, VXF_HIDE_VINFO, 0))
6030 +               return;
6031 +
6032 +       seq_printf(m, "VxID:\t%d\n", vx_task_xid(task));
6033 +       seq_printf(m, "NxID:\t%d\n", nx_task_nid(task));
6034 +}
6035 +
6036 +
6037  int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
6038                         struct pid *pid, struct task_struct *task)
6039  {
6040 @@ -364,6 +407,7 @@ int proc_pid_status(struct seq_file *m,
6041         task_seccomp(m, task);
6042         task_cpus_allowed(m, task);
6043         cpuset_task_status_allowed(m, task);
6044 +       task_vs_id(m, task);
6045         task_context_switch_counts(m, task);
6046         return 0;
6047  }
6048 @@ -467,6 +511,17 @@ static int do_task_stat(struct seq_file
6049         /* convert nsec -> ticks */
6050         start_time = nsec_to_clock_t(task->real_start_time);
6051  
6052 +       /* fixup start time for virt uptime */
6053 +       if (vx_flags(VXF_VIRT_UPTIME, 0)) {
6054 +               unsigned long long bias =
6055 +                       current->vx_info->cvirt.bias_clock;
6056 +
6057 +               if (start_time > bias)
6058 +                       start_time -= bias;
6059 +               else
6060 +                       start_time = 0;
6061 +       }
6062 +
6063         seq_printf(m, "%d (%s) %c", pid_nr_ns(pid, ns), tcomm, state);
6064         seq_put_decimal_ll(m, ' ', ppid);
6065         seq_put_decimal_ll(m, ' ', pgid);
6066 diff -NurpP --minimal linux-3.18.5/fs/proc/base.c linux-3.18.5-vs2.3.7.3/fs/proc/base.c
6067 --- linux-3.18.5/fs/proc/base.c 2015-02-05 18:02:45.000000000 +0000
6068 +++ linux-3.18.5-vs2.3.7.3/fs/proc/base.c       2015-01-22 09:04:57.000000000 +0000
6069 @@ -87,6 +87,8 @@
6070  #include <linux/slab.h>
6071  #include <linux/flex_array.h>
6072  #include <linux/posix-timers.h>
6073 +#include <linux/vs_context.h>
6074 +#include <linux/vs_network.h>
6075  #ifdef CONFIG_HARDWALL
6076  #include <asm/hardwall.h>
6077  #endif
6078 @@ -884,11 +886,15 @@ static ssize_t oom_adj_write(struct file
6079                 oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
6080  
6081         if (oom_adj < task->signal->oom_score_adj &&
6082 -           !capable(CAP_SYS_RESOURCE)) {
6083 +           !vx_capable(CAP_SYS_RESOURCE, VXC_OOM_ADJUST)) {
6084                 err = -EACCES;
6085                 goto err_sighand;
6086         }
6087  
6088 +       /* prevent guest processes from circumventing the oom killer */
6089 +       if (vx_current_xid() && (oom_adj == OOM_DISABLE))
6090 +               oom_adj = OOM_ADJUST_MIN;
6091 +
6092         /*
6093          * /proc/pid/oom_adj is provided for legacy purposes, ask users to use
6094          * /proc/pid/oom_score_adj instead.
6095 @@ -1476,6 +1482,8 @@ struct inode *proc_pid_make_inode(struct
6096                 inode->i_gid = cred->egid;
6097                 rcu_read_unlock();
6098         }
6099 +       /* procfs is xid tagged */
6100 +       i_tag_write(inode, (vtag_t)vx_task_xid(task));
6101         security_task_to_inode(task, inode);
6102  
6103  out:
6104 @@ -1521,6 +1529,8 @@ int pid_getattr(struct vfsmount *mnt, st
6105  
6106  /* dentry stuff */
6107  
6108 +// static unsigned name_to_int(struct dentry *dentry);
6109 +
6110  /*
6111   *     Exceptional case: normally we are not allowed to unhash a busy
6112   * directory. In this case, however, we can do it - no aliasing problems
6113 @@ -1549,6 +1559,19 @@ int pid_revalidate(struct dentry *dentry
6114         task = get_proc_task(inode);
6115  
6116         if (task) {
6117 +               unsigned pid = name_to_int(&dentry->d_name);
6118 +
6119 +               if (pid != ~0U && pid != vx_map_pid(task->pid) &&
6120 +                       pid != __task_pid_nr_ns(task, PIDTYPE_PID,
6121 +                               task_active_pid_ns(task))) {
6122 +                       vxdprintk(VXD_CBIT(misc, 10),
6123 +                               VS_Q("%*s") " dropped by pid_revalidate(%d!=%d)",
6124 +                               dentry->d_name.len, dentry->d_name.name,
6125 +                               pid, vx_map_pid(task->pid));
6126 +                       put_task_struct(task);
6127 +                       d_drop(dentry);
6128 +                       return 0;
6129 +               }
6130                 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
6131                     task_dumpable(task)) {
6132                         rcu_read_lock();
6133 @@ -2085,6 +2108,13 @@ static struct dentry *proc_pident_lookup
6134         if (!task)
6135                 goto out_no_task;
6136  
6137 +       /* TODO: maybe we can come up with a generic approach? */
6138 +       if (task_vx_flags(task, VXF_HIDE_VINFO, 0) &&
6139 +               (dentry->d_name.len == 5) &&
6140 +               (!memcmp(dentry->d_name.name, "vinfo", 5) ||
6141 +               !memcmp(dentry->d_name.name, "ninfo", 5)))
6142 +               goto out;
6143 +
6144         /*
6145          * Yes, it does not scale. And it should not. Don't add
6146          * new entries into /proc/<tgid>/ without very good reasons.
6147 @@ -2534,6 +2564,11 @@ static int proc_pid_personality(struct s
6148  static const struct file_operations proc_task_operations;
6149  static const struct inode_operations proc_task_inode_operations;
6150  
6151 +extern int proc_pid_vx_info(struct seq_file *,
6152 +       struct pid_namespace *, struct pid *, struct task_struct *);
6153 +extern int proc_pid_nx_info(struct seq_file *,
6154 +       struct pid_namespace *, struct pid *, struct task_struct *);
6155 +
6156  static const struct pid_entry tgid_base_stuff[] = {
6157         DIR("task",       S_IRUGO|S_IXUGO, proc_task_inode_operations, proc_task_operations),
6158         DIR("fd",         S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
6159 @@ -2600,6 +2635,8 @@ static const struct pid_entry tgid_base_
6160  #ifdef CONFIG_CGROUPS
6161         ONE("cgroup",  S_IRUGO, proc_cgroup_show),
6162  #endif
6163 +       ONE("vinfo",      S_IRUGO, proc_pid_vx_info),
6164 +       ONE("ninfo",      S_IRUGO, proc_pid_nx_info),
6165         ONE("oom_score",  S_IRUGO, proc_oom_score),
6166         REG("oom_adj",    S_IRUGO|S_IWUSR, proc_oom_adj_operations),
6167         REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
6168 @@ -2811,7 +2848,7 @@ retry:
6169         iter.task = NULL;
6170         pid = find_ge_pid(iter.tgid, ns);
6171         if (pid) {
6172 -               iter.tgid = pid_nr_ns(pid, ns);
6173 +               iter.tgid = pid_unmapped_nr_ns(pid, ns);
6174                 iter.task = pid_task(pid, PIDTYPE_PID);
6175                 /* What we to know is if the pid we have find is the
6176                  * pid of a thread_group_leader.  Testing for task
6177 @@ -2869,8 +2906,10 @@ int proc_pid_readdir(struct file *file,
6178                 if (!has_pid_permissions(ns, iter.task, 2))
6179                         continue;
6180  
6181 -               len = snprintf(name, sizeof(name), "%d", iter.tgid);
6182 +               len = snprintf(name, sizeof(name), "%d", vx_map_tgid(iter.tgid));
6183                 ctx->pos = iter.tgid + TGID_OFFSET;
6184 +               if (!vx_proc_task_visible(iter.task))
6185 +                       continue;
6186                 if (!proc_fill_cache(file, ctx, name, len,
6187                                      proc_pid_instantiate, iter.task, NULL)) {
6188                         put_task_struct(iter.task);
6189 @@ -2967,6 +3006,7 @@ static const struct pid_entry tid_base_s
6190         REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
6191         REG("setgroups",  S_IRUGO|S_IWUSR, proc_setgroups_operations),
6192  #endif
6193 +       ONE("nsproxy",  S_IRUGO, proc_pid_nsproxy),
6194  };
6195  
6196  static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)
6197 @@ -3033,6 +3073,8 @@ static struct dentry *proc_task_lookup(s
6198         tid = name_to_int(&dentry->d_name);
6199         if (tid == ~0U)
6200                 goto out;
6201 +       if (vx_current_initpid(tid))
6202 +               goto out;
6203  
6204         ns = dentry->d_sb->s_fs_info;
6205         rcu_read_lock();
6206 diff -NurpP --minimal linux-3.18.5/fs/proc/generic.c linux-3.18.5-vs2.3.7.3/fs/proc/generic.c
6207 --- linux-3.18.5/fs/proc/generic.c      2015-01-16 22:19:20.000000000 +0000
6208 +++ linux-3.18.5-vs2.3.7.3/fs/proc/generic.c    2015-01-22 08:31:12.000000000 +0000
6209 @@ -23,6 +23,7 @@
6210  #include <linux/bitops.h>
6211  #include <linux/spinlock.h>
6212  #include <linux/completion.h>
6213 +#include <linux/vserver/inode.h>
6214  #include <asm/uaccess.h>
6215  
6216  #include "internal.h"
6217 @@ -186,6 +187,12 @@ struct dentry *proc_lookup_de(struct pro
6218         for (de = de->subdir; de ; de = de->next) {
6219                 if (de->namelen != dentry->d_name.len)
6220                         continue;
6221 +               if (!vx_hide_check(0, de->vx_flags)) {
6222 +                       vxdprintk(VXD_CBIT(misc, 9),
6223 +                               VS_Q("%*s") " hidden in proc_lookup_de()",
6224 +                               de->namelen, de->name);
6225 +                       continue;
6226 +               }
6227                 if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
6228                         pde_get(de);
6229                         spin_unlock(&proc_subdir_lock);
6230 @@ -194,6 +201,8 @@ struct dentry *proc_lookup_de(struct pro
6231                                 return ERR_PTR(-ENOMEM);
6232                         d_set_d_op(dentry, &simple_dentry_operations);
6233                         d_add(dentry, inode);
6234 +                       /* generic proc entries belong to the host */
6235 +                       i_tag_write(inode, 0);
6236                         return NULL;
6237                 }
6238         }
6239 @@ -241,6 +250,13 @@ int proc_readdir_de(struct proc_dir_entr
6240         do {
6241                 struct proc_dir_entry *next;
6242                 pde_get(de);
6243 +
6244 +               if (!vx_hide_check(0, de->vx_flags)) {
6245 +                       vxdprintk(VXD_CBIT(misc, 9),
6246 +                               VS_Q("%*s") " hidden in proc_readdir_de()",
6247 +                               de->namelen, de->name);
6248 +                       goto skip;
6249 +               }
6250                 spin_unlock(&proc_subdir_lock);
6251                 if (!dir_emit(ctx, de->name, de->namelen,
6252                             de->low_ino, de->mode >> 12)) {
6253 @@ -248,6 +264,7 @@ int proc_readdir_de(struct proc_dir_entr
6254                         return 0;
6255                 }
6256                 spin_lock(&proc_subdir_lock);
6257 +       skip:
6258                 ctx->pos++;
6259                 next = de->next;
6260                 pde_put(de);
6261 @@ -354,6 +371,7 @@ static struct proc_dir_entry *__proc_cre
6262         ent->namelen = qstr.len;
6263         ent->mode = mode;
6264         ent->nlink = nlink;
6265 +       ent->vx_flags = IATTR_PROC_DEFAULT;
6266         atomic_set(&ent->count, 1);
6267         spin_lock_init(&ent->pde_unload_lock);
6268         INIT_LIST_HEAD(&ent->pde_openers);
6269 @@ -377,7 +395,8 @@ struct proc_dir_entry *proc_symlink(cons
6270                                 kfree(ent->data);
6271                                 kfree(ent);
6272                                 ent = NULL;
6273 -                       }
6274 +                       } else
6275 +                               ent->vx_flags = IATTR_PROC_SYMLINK;
6276                 } else {
6277                         kfree(ent);
6278                         ent = NULL;
6279 diff -NurpP --minimal linux-3.18.5/fs/proc/inode.c linux-3.18.5-vs2.3.7.3/fs/proc/inode.c
6280 --- linux-3.18.5/fs/proc/inode.c        2015-01-16 22:19:20.000000000 +0000
6281 +++ linux-3.18.5-vs2.3.7.3/fs/proc/inode.c      2015-01-19 10:58:03.000000000 +0000
6282 @@ -415,6 +415,8 @@ struct inode *proc_get_inode(struct supe
6283                         inode->i_uid = de->uid;
6284                         inode->i_gid = de->gid;
6285                 }
6286 +               if (de->vx_flags)
6287 +                       PROC_I(inode)->vx_flags = de->vx_flags;
6288                 if (de->size)
6289                         inode->i_size = de->size;
6290                 if (de->nlink)
6291 diff -NurpP --minimal linux-3.18.5/fs/proc/internal.h linux-3.18.5-vs2.3.7.3/fs/proc/internal.h
6292 --- linux-3.18.5/fs/proc/internal.h     2015-01-17 02:40:20.000000000 +0000
6293 +++ linux-3.18.5-vs2.3.7.3/fs/proc/internal.h   2015-01-19 12:40:33.000000000 +0000
6294 @@ -14,6 +14,7 @@
6295  #include <linux/spinlock.h>
6296  #include <linux/atomic.h>
6297  #include <linux/binfmts.h>
6298 +#include <linux/vs_pid.h>
6299  
6300  struct ctl_table_header;
6301  struct mempolicy;
6302 @@ -35,6 +36,7 @@ struct proc_dir_entry {
6303         nlink_t nlink;
6304         kuid_t uid;
6305         kgid_t gid;
6306 +       int vx_flags;
6307         loff_t size;
6308         const struct inode_operations *proc_iops;
6309         const struct file_operations *proc_fops;
6310 @@ -50,15 +52,22 @@ struct proc_dir_entry {
6311         char name[];
6312  };
6313  
6314 +struct vx_info;
6315 +struct nx_info;
6316 +
6317  union proc_op {
6318         int (*proc_get_link)(struct dentry *, struct path *);
6319         int (*proc_show)(struct seq_file *m,
6320                 struct pid_namespace *ns, struct pid *pid,
6321                 struct task_struct *task);
6322 +       int (*proc_vs_read)(char *page);
6323 +       int (*proc_vxi_read)(struct vx_info *vxi, char *page);
6324 +       int (*proc_nxi_read)(struct nx_info *nxi, char *page);
6325  };
6326  
6327  struct proc_inode {
6328         struct pid *pid;
6329 +       int vx_flags;
6330         int fd;
6331         union proc_op op;
6332         struct proc_dir_entry *pde;
6333 @@ -91,11 +100,16 @@ static inline struct pid *proc_pid(struc
6334         return PROC_I(inode)->pid;
6335  }
6336  
6337 -static inline struct task_struct *get_proc_task(struct inode *inode)
6338 +static inline struct task_struct *get_proc_task_real(struct inode *inode)
6339  {
6340         return get_pid_task(proc_pid(inode), PIDTYPE_PID);
6341  }
6342  
6343 +static inline struct task_struct *get_proc_task(struct inode *inode)
6344 +{
6345 +       return vx_get_proc_task(inode, proc_pid(inode));
6346 +}
6347 +
6348  static inline int task_dumpable(struct task_struct *task)
6349  {
6350         int dumpable = 0;
6351 @@ -154,6 +168,8 @@ extern int proc_pid_status(struct seq_fi
6352                            struct pid *, struct task_struct *);
6353  extern int proc_pid_statm(struct seq_file *, struct pid_namespace *,
6354                           struct pid *, struct task_struct *);
6355 +extern int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
6356 +                           struct pid *pid, struct task_struct *task);
6357  
6358  /*
6359   * base.c
6360 diff -NurpP --minimal linux-3.18.5/fs/proc/loadavg.c linux-3.18.5-vs2.3.7.3/fs/proc/loadavg.c
6361 --- linux-3.18.5/fs/proc/loadavg.c      2014-06-12 11:34:59.000000000 +0000
6362 +++ linux-3.18.5-vs2.3.7.3/fs/proc/loadavg.c    2015-01-19 10:58:03.000000000 +0000
6363 @@ -12,15 +12,27 @@
6364  
6365  static int loadavg_proc_show(struct seq_file *m, void *v)
6366  {
6367 +       unsigned long running;
6368 +       unsigned int threads;
6369         unsigned long avnrun[3];
6370  
6371         get_avenrun(avnrun, FIXED_1/200, 0);
6372  
6373 +       if (vx_flags(VXF_VIRT_LOAD, 0)) {
6374 +               struct vx_info *vxi = current_vx_info();
6375 +
6376 +               running = atomic_read(&vxi->cvirt.nr_running);
6377 +               threads = atomic_read(&vxi->cvirt.nr_threads);
6378 +       } else {
6379 +               running = nr_running();
6380 +               threads = nr_threads;
6381 +       }
6382 +
6383         seq_printf(m, "%lu.%02lu %lu.%02lu %lu.%02lu %ld/%d %d\n",
6384                 LOAD_INT(avnrun[0]), LOAD_FRAC(avnrun[0]),
6385                 LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
6386                 LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
6387 -               nr_running(), nr_threads,
6388 +               running, threads,
6389                 task_active_pid_ns(current)->last_pid);
6390         return 0;
6391  }
6392 diff -NurpP --minimal linux-3.18.5/fs/proc/meminfo.c linux-3.18.5-vs2.3.7.3/fs/proc/meminfo.c
6393 --- linux-3.18.5/fs/proc/meminfo.c      2015-01-16 22:19:20.000000000 +0000
6394 +++ linux-3.18.5-vs2.3.7.3/fs/proc/meminfo.c    2015-01-19 10:58:03.000000000 +0000
6395 @@ -41,7 +41,8 @@ static int meminfo_proc_show(struct seq_
6396         si_swapinfo(&i);
6397         committed = percpu_counter_read_positive(&vm_committed_as);
6398  
6399 -       cached = global_page_state(NR_FILE_PAGES) -
6400 +       cached = vx_flags(VXF_VIRT_MEM, 0) ?
6401 +               vx_vsi_cached(&i) : global_page_state(NR_FILE_PAGES) -
6402                         total_swapcache_pages() - i.bufferram;
6403         if (cached < 0)
6404                 cached = 0;
6405 diff -NurpP --minimal linux-3.18.5/fs/proc/root.c linux-3.18.5-vs2.3.7.3/fs/proc/root.c
6406 --- linux-3.18.5/fs/proc/root.c 2015-01-16 22:19:20.000000000 +0000
6407 +++ linux-3.18.5-vs2.3.7.3/fs/proc/root.c       2015-01-19 10:58:04.000000000 +0000
6408 @@ -20,9 +20,14 @@
6409  #include <linux/mount.h>
6410  #include <linux/pid_namespace.h>
6411  #include <linux/parser.h>
6412 +#include <linux/vserver/inode.h>
6413  
6414  #include "internal.h"
6415  
6416 +struct proc_dir_entry *proc_virtual;
6417 +
6418 +extern void proc_vx_init(void);
6419 +
6420  static int proc_test_super(struct super_block *sb, void *data)
6421  {
6422         return sb->s_fs_info == data;
6423 @@ -116,7 +121,8 @@ static struct dentry *proc_mount(struct
6424                         return ERR_PTR(-EPERM);
6425  
6426                 /* Does the mounter have privilege over the pid namespace? */
6427 -               if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
6428 +               if (!vx_ns_capable(ns->user_ns,
6429 +                       CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
6430                         return ERR_PTR(-EPERM);
6431         }
6432  
6433 @@ -190,6 +196,7 @@ void __init proc_root_init(void)
6434         proc_tty_init();
6435         proc_mkdir("bus", NULL);
6436         proc_sys_init();
6437 +       proc_vx_init();
6438  }
6439  
6440  static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
6441 @@ -251,6 +258,7 @@ struct proc_dir_entry proc_root = {
6442         .proc_iops      = &proc_root_inode_operations, 
6443         .proc_fops      = &proc_root_operations,
6444         .parent         = &proc_root,
6445 +       .vx_flags       = IATTR_ADMIN | IATTR_WATCH,
6446         .name           = "/proc",
6447  };
6448  
6449 diff -NurpP --minimal linux-3.18.5/fs/proc/self.c linux-3.18.5-vs2.3.7.3/fs/proc/self.c
6450 --- linux-3.18.5/fs/proc/self.c 2014-06-12 13:02:46.000000000 +0000
6451 +++ linux-3.18.5-vs2.3.7.3/fs/proc/self.c       2015-01-19 10:58:04.000000000 +0000
6452 @@ -2,6 +2,7 @@
6453  #include <linux/namei.h>
6454  #include <linux/slab.h>
6455  #include <linux/pid_namespace.h>
6456 +#include <linux/vserver/inode.h>
6457  #include "internal.h"
6458  
6459  /*
6460 @@ -54,6 +55,8 @@ int proc_setup_self(struct super_block *
6461         self = d_alloc_name(s->s_root, "self");
6462         if (self) {
6463                 struct inode *inode = new_inode_pseudo(s);
6464 +
6465 +               // self->vx_flags = IATTR_PROC_SYMLINK;
6466                 if (inode) {
6467                         inode->i_ino = self_inum;
6468                         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
6469 diff -NurpP --minimal linux-3.18.5/fs/proc/stat.c linux-3.18.5-vs2.3.7.3/fs/proc/stat.c
6470 --- linux-3.18.5/fs/proc/stat.c 2015-02-05 18:02:45.000000000 +0000
6471 +++ linux-3.18.5-vs2.3.7.3/fs/proc/stat.c       2015-01-28 11:48:02.000000000 +0000
6472 @@ -9,8 +9,10 @@
6473  #include <linux/slab.h>
6474  #include <linux/time.h>
6475  #include <linux/irqnr.h>
6476 +#include <linux/vserver/cvirt.h>
6477  #include <linux/cputime.h>
6478  #include <linux/tick.h>
6479 +#include <linux/cpuset.h>
6480  
6481  #ifndef arch_irq_stat_cpu
6482  #define arch_irq_stat_cpu(cpu) 0
6483 @@ -87,14 +89,26 @@ static int show_stat(struct seq_file *p,
6484         u64 sum_softirq = 0;
6485         unsigned int per_softirq_sums[NR_SOFTIRQS] = {0};
6486         struct timespec boottime;
6487 +       cpumask_var_t cpus_allowed;
6488 +       bool virt_cpu = vx_flags(VXF_VIRT_CPU, 0);
6489  
6490         user = nice = system = idle = iowait =
6491                 irq = softirq = steal = 0;
6492         guest = guest_nice = 0;
6493         getboottime(&boottime);
6494 +
6495 +       if (vx_flags(VXF_VIRT_UPTIME, 0))
6496 +               vx_vsi_boottime(&boottime);
6497 +
6498 +       if (virt_cpu)
6499 +               cpuset_cpus_allowed(current, cpus_allowed);
6500 +
6501         jif = boottime.tv_sec;
6502  
6503         for_each_possible_cpu(i) {
6504 +               if (virt_cpu && !cpumask_test_cpu(i, cpus_allowed))
6505 +                       continue;
6506 +
6507                 user += kcpustat_cpu(i).cpustat[CPUTIME_USER];
6508                 nice += kcpustat_cpu(i).cpustat[CPUTIME_NICE];
6509                 system += kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
6510 @@ -131,6 +145,9 @@ static int show_stat(struct seq_file *p,
6511         seq_putc(p, '\n');
6512  
6513         for_each_online_cpu(i) {
6514 +               if (virt_cpu && !cpumask_test_cpu(i, cpus_allowed))
6515 +                       continue;
6516 +
6517                 /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
6518                 user = kcpustat_cpu(i).cpustat[CPUTIME_USER];
6519                 nice = kcpustat_cpu(i).cpustat[CPUTIME_NICE];
6520 diff -NurpP --minimal linux-3.18.5/fs/proc/uptime.c linux-3.18.5-vs2.3.7.3/fs/proc/uptime.c
6521 --- linux-3.18.5/fs/proc/uptime.c       2014-06-12 13:02:46.000000000 +0000
6522 +++ linux-3.18.5-vs2.3.7.3/fs/proc/uptime.c     2015-01-19 12:41:00.000000000 +0000
6523 @@ -5,6 +5,7 @@
6524  #include <linux/seq_file.h>
6525  #include <linux/time.h>
6526  #include <linux/kernel_stat.h>
6527 +#include <linux/vserver/cvirt.h>
6528  #include <linux/cputime.h>
6529  
6530  static int uptime_proc_show(struct seq_file *m, void *v)
6531 @@ -24,6 +25,10 @@ static int uptime_proc_show(struct seq_f
6532         nsec = cputime64_to_jiffies64(idletime) * TICK_NSEC;
6533         idle.tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
6534         idle.tv_nsec = rem;
6535 +
6536 +       if (vx_flags(VXF_VIRT_UPTIME, 0))
6537 +               vx_vsi_uptime(&uptime, &idle);
6538 +
6539         seq_printf(m, "%lu.%02lu %lu.%02lu\n",
6540                         (unsigned long) uptime.tv_sec,
6541                         (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
6542 diff -NurpP --minimal linux-3.18.5/fs/proc_namespace.c linux-3.18.5-vs2.3.7.3/fs/proc_namespace.c
6543 --- linux-3.18.5/fs/proc_namespace.c    2015-01-16 22:19:20.000000000 +0000
6544 +++ linux-3.18.5-vs2.3.7.3/fs/proc_namespace.c  2015-01-19 10:58:04.000000000 +0000
6545 @@ -44,6 +44,8 @@ static int show_sb_opts(struct seq_file
6546                 { MS_SYNCHRONOUS, ",sync" },
6547                 { MS_DIRSYNC, ",dirsync" },
6548                 { MS_MANDLOCK, ",mand" },
6549 +               { MS_TAGGED, ",tag" },
6550 +               { MS_NOTAGCHECK, ",notagcheck" },
6551                 { 0, NULL }
6552         };
6553         const struct proc_fs_info *fs_infop;
6554 @@ -80,6 +82,38 @@ static inline void mangle(struct seq_fil
6555         seq_escape(m, s, " \t\n\\");
6556  }
6557  
6558 +#ifdef CONFIG_VSERVER_EXTRA_MNT_CHECK
6559 +
6560 +static int mnt_is_reachable(struct vfsmount *vfsmnt)
6561 +{
6562 +       struct path root;
6563 +       struct dentry *point;
6564 +       struct mount *mnt = real_mount(vfsmnt);
6565 +       struct mount *root_mnt;
6566 +       int ret;
6567 +
6568 +       if (mnt == mnt->mnt_ns->root)
6569 +               return 1;
6570 +
6571 +       rcu_read_lock();
6572 +       root = current->fs->root;
6573 +       root_mnt = real_mount(root.mnt);
6574 +       point = root.dentry;
6575 +
6576 +       while ((mnt != mnt->mnt_parent) && (mnt != root_mnt)) {
6577 +               point = mnt->mnt_mountpoint;
6578 +               mnt = mnt->mnt_parent;
6579 +       }
6580 +       rcu_read_unlock();
6581 +
6582 +       ret = (mnt == root_mnt) && is_subdir(point, root.dentry);
6583 +       return ret;
6584 +}
6585 +
6586 +#else
6587 +#define        mnt_is_reachable(v)     (1)
6588 +#endif
6589 +
6590  static void show_type(struct seq_file *m, struct super_block *sb)
6591  {
6592         mangle(m, sb->s_type->name);
6593 @@ -96,6 +130,17 @@ static int show_vfsmnt(struct seq_file *
6594         struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
6595         struct super_block *sb = mnt_path.dentry->d_sb;
6596  
6597 +       if (vx_flags(VXF_HIDE_MOUNT, 0))
6598 +               return SEQ_SKIP;
6599 +       if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6600 +               return SEQ_SKIP;
6601 +
6602 +       if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
6603 +               mnt == current->fs->root.mnt) {
6604 +               seq_puts(m, "/dev/root / ");
6605 +               goto type;
6606 +       }
6607 +
6608         if (sb->s_op->show_devname) {
6609                 err = sb->s_op->show_devname(m, mnt_path.dentry);
6610                 if (err)
6611 @@ -106,6 +151,7 @@ static int show_vfsmnt(struct seq_file *
6612         seq_putc(m, ' ');
6613         seq_path(m, &mnt_path, " \t\n\\");
6614         seq_putc(m, ' ');
6615 +type:
6616         show_type(m, sb);
6617         seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw");
6618         err = show_sb_opts(m, sb);
6619 @@ -128,6 +174,11 @@ static int show_mountinfo(struct seq_fil
6620         struct path root = p->root;
6621         int err = 0;
6622  
6623 +       if (vx_flags(VXF_HIDE_MOUNT, 0))
6624 +               return SEQ_SKIP;
6625 +       if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6626 +               return SEQ_SKIP;
6627 +
6628         seq_printf(m, "%i %i %u:%u ", r->mnt_id, r->mnt_parent->mnt_id,
6629                    MAJOR(sb->s_dev), MINOR(sb->s_dev));
6630         if (sb->s_op->show_path)
6631 @@ -187,6 +238,17 @@ static int show_vfsstat(struct seq_file
6632         struct super_block *sb = mnt_path.dentry->d_sb;
6633         int err = 0;
6634  
6635 +       if (vx_flags(VXF_HIDE_MOUNT, 0))
6636 +               return SEQ_SKIP;
6637 +       if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6638 +               return SEQ_SKIP;
6639 +
6640 +       if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
6641 +               mnt == current->fs->root.mnt) {
6642 +               seq_puts(m, "device /dev/root mounted on / ");
6643 +               goto type;
6644 +       }
6645 +
6646         /* device */
6647         if (sb->s_op->show_devname) {
6648                 seq_puts(m, "device ");
6649 @@ -203,7 +265,7 @@ static int show_vfsstat(struct seq_file
6650         seq_puts(m, " mounted on ");
6651         seq_path(m, &mnt_path, " \t\n\\");
6652         seq_putc(m, ' ');
6653 -
6654 +type:
6655         /* file system type */
6656         seq_puts(m, "with fstype ");
6657         show_type(m, sb);
6658 diff -NurpP --minimal linux-3.18.5/fs/quota/dquot.c linux-3.18.5-vs2.3.7.3/fs/quota/dquot.c
6659 --- linux-3.18.5/fs/quota/dquot.c       2015-01-17 02:40:20.000000000 +0000
6660 +++ linux-3.18.5-vs2.3.7.3/fs/quota/dquot.c     2015-01-19 23:44:31.000000000 +0000
6661 @@ -1598,6 +1598,12 @@ int __dquot_alloc_space(struct inode *in
6662         struct dquot **dquots = inode->i_dquot;
6663         int reserve = flags & DQUOT_SPACE_RESERVE;
6664  
6665 +       if ((ret = dl_alloc_inode(inode)))
6666 +               return ret;
6667 +
6668 +       if ((ret = dl_alloc_space(inode, number)))
6669 +               return ret;
6670 +
6671         if (!dquot_active(inode)) {
6672                 inode_incr_space(inode, number, reserve);
6673                 goto out;
6674 @@ -1649,6 +1655,9 @@ int dquot_alloc_inode(const struct inode
6675         struct dquot_warn warn[MAXQUOTAS];
6676         struct dquot * const *dquots = inode->i_dquot;
6677  
6678 +       if ((ret = dl_alloc_inode(inode)))
6679 +               return ret;
6680 +
6681         if (!dquot_active(inode))
6682                 return 0;
6683         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
6684 @@ -1748,6 +1757,8 @@ void __dquot_free_space(struct inode *in
6685         struct dquot **dquots = inode->i_dquot;
6686         int reserve = flags & DQUOT_SPACE_RESERVE, index;
6687  
6688 +       dl_free_space(inode, number);
6689 +
6690         if (!dquot_active(inode)) {
6691                 inode_decr_space(inode, number, reserve);
6692                 return;
6693 @@ -1791,6 +1802,8 @@ void dquot_free_inode(const struct inode
6694         struct dquot * const *dquots = inode->i_dquot;
6695         int index;
6696  
6697 +       dl_free_inode(inode);
6698 +
6699         if (!dquot_active(inode))
6700                 return;
6701  
6702 diff -NurpP --minimal linux-3.18.5/fs/quota/quota.c linux-3.18.5-vs2.3.7.3/fs/quota/quota.c
6703 --- linux-3.18.5/fs/quota/quota.c       2015-01-16 22:19:20.000000000 +0000
6704 +++ linux-3.18.5-vs2.3.7.3/fs/quota/quota.c     2015-01-19 10:58:04.000000000 +0000
6705 @@ -8,6 +8,7 @@
6706  #include <linux/fs.h>
6707  #include <linux/namei.h>
6708  #include <linux/slab.h>
6709 +#include <linux/vs_context.h>
6710  #include <asm/current.h>
6711  #include <linux/uaccess.h>
6712  #include <linux/kernel.h>
6713 @@ -38,7 +39,7 @@ static int check_quotactl_permission(str
6714                         break;
6715                 /*FALLTHROUGH*/
6716         default:
6717 -               if (!capable(CAP_SYS_ADMIN))
6718 +               if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
6719                         return -EPERM;
6720         }
6721  
6722 @@ -350,6 +351,46 @@ static int do_quotactl(struct super_bloc
6723  
6724  #ifdef CONFIG_BLOCK
6725  
6726 +#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
6727 +
6728 +#include <linux/vroot.h>
6729 +#include <linux/major.h>
6730 +#include <linux/module.h>
6731 +#include <linux/kallsyms.h>
6732 +#include <linux/vserver/debug.h>
6733 +
6734 +static vroot_grb_func *vroot_get_real_bdev = NULL;
6735 +
6736 +static DEFINE_SPINLOCK(vroot_grb_lock);
6737 +
6738 +int register_vroot_grb(vroot_grb_func *func) {
6739 +       int ret = -EBUSY;
6740 +
6741 +       spin_lock(&vroot_grb_lock);
6742 +       if (!vroot_get_real_bdev) {
6743 +               vroot_get_real_bdev = func;
6744 +               ret = 0;
6745 +       }
6746 +       spin_unlock(&vroot_grb_lock);
6747 +       return ret;
6748 +}
6749 +EXPORT_SYMBOL(register_vroot_grb);
6750 +
6751 +int unregister_vroot_grb(vroot_grb_func *func) {
6752 +       int ret = -EINVAL;
6753 +
6754 +       spin_lock(&vroot_grb_lock);
6755 +       if (vroot_get_real_bdev) {
6756 +               vroot_get_real_bdev = NULL;
6757 +               ret = 0;
6758 +       }
6759 +       spin_unlock(&vroot_grb_lock);
6760 +       return ret;
6761 +}
6762 +EXPORT_SYMBOL(unregister_vroot_grb);
6763 +
6764 +#endif
6765 +
6766  /* Return 1 if 'cmd' will block on frozen filesystem */
6767  static int quotactl_cmd_write(int cmd)
6768  {
6769 @@ -385,6 +426,22 @@ static struct super_block *quotactl_bloc
6770         putname(tmp);
6771         if (IS_ERR(bdev))
6772                 return ERR_CAST(bdev);
6773 +#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
6774 +       if (bdev && bdev->bd_inode &&
6775 +               imajor(bdev->bd_inode) == VROOT_MAJOR) {
6776 +               struct block_device *bdnew = (void *)-EINVAL;
6777 +
6778 +               if (vroot_get_real_bdev)
6779 +                       bdnew = vroot_get_real_bdev(bdev);
6780 +               else
6781 +                       vxdprintk(VXD_CBIT(misc, 0),
6782 +                                       "vroot_get_real_bdev not set");
6783 +               bdput(bdev);
6784 +               if (IS_ERR(bdnew))
6785 +                       return ERR_PTR(PTR_ERR(bdnew));
6786 +               bdev = bdnew;
6787 +       }
6788 +#endif
6789         if (quotactl_cmd_write(cmd))
6790                 sb = get_super_thawed(bdev);
6791         else
6792 diff -NurpP --minimal linux-3.18.5/fs/stat.c linux-3.18.5-vs2.3.7.3/fs/stat.c
6793 --- linux-3.18.5/fs/stat.c      2014-01-22 20:39:07.000000000 +0000
6794 +++ linux-3.18.5-vs2.3.7.3/fs/stat.c    2015-01-19 10:58:04.000000000 +0000
6795 @@ -26,6 +26,7 @@ void generic_fillattr(struct inode *inod
6796         stat->nlink = inode->i_nlink;
6797         stat->uid = inode->i_uid;
6798         stat->gid = inode->i_gid;
6799 +       stat->tag = inode->i_tag;
6800         stat->rdev = inode->i_rdev;
6801         stat->size = i_size_read(inode);
6802         stat->atime = inode->i_atime;
6803 diff -NurpP --minimal linux-3.18.5/fs/statfs.c linux-3.18.5-vs2.3.7.3/fs/statfs.c
6804 --- linux-3.18.5/fs/statfs.c    2013-11-25 15:47:00.000000000 +0000
6805 +++ linux-3.18.5-vs2.3.7.3/fs/statfs.c  2015-01-19 10:58:04.000000000 +0000
6806 @@ -7,6 +7,8 @@
6807  #include <linux/statfs.h>
6808  #include <linux/security.h>
6809  #include <linux/uaccess.h>
6810 +#include <linux/vs_base.h>
6811 +#include <linux/vs_dlimit.h>
6812  #include "internal.h"
6813  
6814  static int flags_by_mnt(int mnt_flags)
6815 @@ -60,6 +62,8 @@ static int statfs_by_dentry(struct dentr
6816         retval = dentry->d_sb->s_op->statfs(dentry, buf);
6817         if (retval == 0 && buf->f_frsize == 0)
6818                 buf->f_frsize = buf->f_bsize;
6819 +       if (!vx_check(0, VS_ADMIN|VS_WATCH))
6820 +               vx_vsi_statfs(dentry->d_sb, buf);
6821         return retval;
6822  }
6823  
6824 diff -NurpP --minimal linux-3.18.5/fs/super.c linux-3.18.5-vs2.3.7.3/fs/super.c
6825 --- linux-3.18.5/fs/super.c     2015-01-17 02:40:20.000000000 +0000
6826 +++ linux-3.18.5-vs2.3.7.3/fs/super.c   2015-01-19 10:58:04.000000000 +0000
6827 @@ -33,6 +33,8 @@
6828  #include <linux/cleancache.h>
6829  #include <linux/fsnotify.h>
6830  #include <linux/lockdep.h>
6831 +#include <linux/magic.h>
6832 +#include <linux/vs_context.h>
6833  #include "internal.h"
6834  
6835  
6836 @@ -1114,6 +1116,13 @@ mount_fs(struct file_system_type *type,
6837         WARN_ON(sb->s_bdi == &default_backing_dev_info);
6838         sb->s_flags |= MS_BORN;
6839  
6840 +       error = -EPERM;
6841 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT) &&
6842 +               !sb->s_bdev &&
6843 +               (sb->s_magic != PROC_SUPER_MAGIC) &&
6844 +               (sb->s_magic != DEVPTS_SUPER_MAGIC))
6845 +               goto out_sb;
6846 +
6847         error = security_sb_kern_mount(sb, flags, secdata);
6848         if (error)
6849                 goto out_sb;
6850 diff -NurpP --minimal linux-3.18.5/fs/utimes.c linux-3.18.5-vs2.3.7.3/fs/utimes.c
6851 --- linux-3.18.5/fs/utimes.c    2014-01-22 20:39:07.000000000 +0000
6852 +++ linux-3.18.5-vs2.3.7.3/fs/utimes.c  2015-01-19 10:58:04.000000000 +0000
6853 @@ -8,6 +8,8 @@
6854  #include <linux/stat.h>
6855  #include <linux/utime.h>
6856  #include <linux/syscalls.h>
6857 +#include <linux/mount.h>
6858 +#include <linux/vs_cowbl.h>
6859  #include <asm/uaccess.h>
6860  #include <asm/unistd.h>
6861  
6862 @@ -52,13 +54,19 @@ static int utimes_common(struct path *pa
6863  {
6864         int error;
6865         struct iattr newattrs;
6866 -       struct inode *inode = path->dentry->d_inode;
6867         struct inode *delegated_inode = NULL;
6868 +       struct inode *inode;
6869 +
6870 +       error = cow_check_and_break(path);
6871 +       if (error)
6872 +               goto out;
6873  
6874         error = mnt_want_write(path->mnt);
6875         if (error)
6876                 goto out;
6877  
6878 +       inode = path->dentry->d_inode;
6879 +
6880         if (times && times[0].tv_nsec == UTIME_NOW &&
6881                      times[1].tv_nsec == UTIME_NOW)
6882                 times = NULL;
6883 diff -NurpP --minimal linux-3.18.5/fs/xattr.c linux-3.18.5-vs2.3.7.3/fs/xattr.c
6884 --- linux-3.18.5/fs/xattr.c     2015-01-17 02:40:20.000000000 +0000
6885 +++ linux-3.18.5-vs2.3.7.3/fs/xattr.c   2015-01-19 10:58:04.000000000 +0000
6886 @@ -21,6 +21,7 @@
6887  #include <linux/audit.h>
6888  #include <linux/vmalloc.h>
6889  #include <linux/posix_acl_xattr.h>
6890 +#include <linux/mount.h>
6891  
6892  #include <asm/uaccess.h>
6893  
6894 @@ -52,7 +53,7 @@ xattr_permission(struct inode *inode, co
6895          * The trusted.* namespace can only be accessed by privileged users.
6896          */
6897         if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
6898 -               if (!capable(CAP_SYS_ADMIN))
6899 +               if (!vx_capable(CAP_SYS_ADMIN, VXC_FS_TRUSTED))
6900                         return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
6901                 return 0;
6902         }
6903 diff -NurpP --minimal linux-3.18.5/include/linux/capability.h linux-3.18.5-vs2.3.7.3/include/linux/capability.h
6904 --- linux-3.18.5/include/linux/capability.h     2015-01-16 22:19:21.000000000 +0000
6905 +++ linux-3.18.5-vs2.3.7.3/include/linux/capability.h   2015-01-19 10:58:04.000000000 +0000
6906 @@ -79,7 +79,8 @@ extern const kernel_cap_t __cap_init_eff
6907  #else /* HAND-CODED capability initializers */
6908  
6909  #define CAP_LAST_U32                   ((_KERNEL_CAPABILITY_U32S) - 1)
6910 -#define CAP_LAST_U32_VALID_MASK                (CAP_TO_MASK(CAP_LAST_CAP + 1) -1)
6911 +#define CAP_LAST_U32_VALID_MASK                ((CAP_TO_MASK(CAP_LAST_CAP + 1) -1) \
6912 +                                       | CAP_TO_MASK(CAP_CONTEXT))
6913  
6914  # define CAP_EMPTY_SET    ((kernel_cap_t){{ 0, 0 }})
6915  # define CAP_FULL_SET     ((kernel_cap_t){{ ~0, CAP_LAST_U32_VALID_MASK }})
6916 diff -NurpP --minimal linux-3.18.5/include/linux/cred.h linux-3.18.5-vs2.3.7.3/include/linux/cred.h
6917 --- linux-3.18.5/include/linux/cred.h   2015-02-05 18:02:45.000000000 +0000
6918 +++ linux-3.18.5-vs2.3.7.3/include/linux/cred.h 2015-01-19 10:58:04.000000000 +0000
6919 @@ -144,6 +144,7 @@ extern void exit_creds(struct task_struc
6920  extern int copy_creds(struct task_struct *, unsigned long);
6921  extern const struct cred *get_task_cred(struct task_struct *);
6922  extern struct cred *cred_alloc_blank(void);
6923 +extern struct cred *__prepare_creds(const struct cred *);
6924  extern struct cred *prepare_creds(void);
6925  extern struct cred *prepare_exec_creds(void);
6926  extern int commit_creds(struct cred *);
6927 @@ -197,6 +198,31 @@ static inline void validate_process_cred
6928  }
6929  #endif
6930  
6931 +static inline void set_cred_subscribers(struct cred *cred, int n)
6932 +{
6933 +#ifdef CONFIG_DEBUG_CREDENTIALS
6934 +       atomic_set(&cred->subscribers, n);
6935 +#endif
6936 +}
6937 +
6938 +static inline int read_cred_subscribers(const struct cred *cred)
6939 +{
6940 +#ifdef CONFIG_DEBUG_CREDENTIALS
6941 +       return atomic_read(&cred->subscribers);
6942 +#else
6943 +       return 0;
6944 +#endif
6945 +}
6946 +
6947 +static inline void alter_cred_subscribers(const struct cred *_cred, int n)
6948 +{
6949 +#ifdef CONFIG_DEBUG_CREDENTIALS
6950 +       struct cred *cred = (struct cred *) _cred;
6951 +
6952 +       atomic_add(n, &cred->subscribers);
6953 +#endif
6954 +}
6955 +
6956  /**
6957   * get_new_cred - Get a reference on a new set of credentials
6958   * @cred: The new credentials to reference
6959 diff -NurpP --minimal linux-3.18.5/include/linux/devpts_fs.h linux-3.18.5-vs2.3.7.3/include/linux/devpts_fs.h
6960 --- linux-3.18.5/include/linux/devpts_fs.h      2013-02-19 13:58:50.000000000 +0000
6961 +++ linux-3.18.5-vs2.3.7.3/include/linux/devpts_fs.h    2015-01-19 10:58:04.000000000 +0000
6962 @@ -45,5 +45,4 @@ static inline void devpts_pty_kill(struc
6963  
6964  #endif
6965  
6966 -
6967  #endif /* _LINUX_DEVPTS_FS_H */
6968 diff -NurpP --minimal linux-3.18.5/include/linux/fs.h linux-3.18.5-vs2.3.7.3/include/linux/fs.h
6969 --- linux-3.18.5/include/linux/fs.h     2015-01-17 02:40:21.000000000 +0000
6970 +++ linux-3.18.5-vs2.3.7.3/include/linux/fs.h   2015-01-19 10:58:04.000000000 +0000
6971 @@ -221,6 +221,7 @@ typedef void (dio_iodone_t)(struct kiocb
6972  #define ATTR_KILL_PRIV (1 << 14)
6973  #define ATTR_OPEN      (1 << 15) /* Truncating from open(O_TRUNC) */
6974  #define ATTR_TIMES_SET (1 << 16)
6975 +#define ATTR_TAG       (1 << 17)
6976  
6977  /*
6978   * Whiteout is represented by a char device.  The following constants define the
6979 @@ -243,6 +244,7 @@ struct iattr {
6980         umode_t         ia_mode;
6981         kuid_t          ia_uid;
6982         kgid_t          ia_gid;
6983 +       ktag_t          ia_tag;
6984         loff_t          ia_size;
6985         struct timespec ia_atime;
6986         struct timespec ia_mtime;
6987 @@ -540,7 +542,9 @@ struct inode {
6988         unsigned short          i_opflags;
6989         kuid_t                  i_uid;
6990         kgid_t                  i_gid;
6991 -       unsigned int            i_flags;
6992 +       ktag_t                  i_tag;
6993 +       unsigned short          i_flags;
6994 +       unsigned short          i_vflags;
6995  
6996  #ifdef CONFIG_FS_POSIX_ACL
6997         struct posix_acl        *i_acl;
6998 @@ -569,6 +573,7 @@ struct inode {
6999                 unsigned int __i_nlink;
7000         };
7001         dev_t                   i_rdev;
7002 +       dev_t                   i_mdev;
7003         loff_t                  i_size;
7004         struct timespec         i_atime;
7005         struct timespec         i_mtime;
7006 @@ -730,6 +735,11 @@ static inline gid_t i_gid_read(const str
7007         return from_kgid(&init_user_ns, inode->i_gid);
7008  }
7009  
7010 +static inline vtag_t i_tag_read(const struct inode *inode)
7011 +{
7012 +       return from_ktag(&init_user_ns, inode->i_tag);
7013 +}
7014 +
7015  static inline void i_uid_write(struct inode *inode, uid_t uid)
7016  {
7017         inode->i_uid = make_kuid(&init_user_ns, uid);
7018 @@ -740,14 +750,19 @@ static inline void i_gid_write(struct in
7019         inode->i_gid = make_kgid(&init_user_ns, gid);
7020  }
7021  
7022 +static inline void i_tag_write(struct inode *inode, vtag_t tag)
7023 +{
7024 +       inode->i_tag = make_ktag(&init_user_ns, tag);
7025 +}
7026 +
7027  static inline unsigned iminor(const struct inode *inode)
7028  {
7029 -       return MINOR(inode->i_rdev);
7030 +       return MINOR(inode->i_mdev);
7031  }
7032  
7033  static inline unsigned imajor(const struct inode *inode)
7034  {
7035 -       return MAJOR(inode->i_rdev);
7036 +       return MAJOR(inode->i_mdev);
7037  }
7038  
7039  extern struct block_device *I_BDEV(struct inode *inode);
7040 @@ -805,6 +820,7 @@ struct file {
7041         loff_t                  f_pos;
7042         struct fown_struct      f_owner;
7043         const struct cred       *f_cred;
7044 +       vxid_t                  f_xid;
7045         struct file_ra_state    f_ra;
7046  
7047         u64                     f_version;
7048 @@ -929,6 +945,7 @@ struct file_lock {
7049         struct file *fl_file;
7050         loff_t fl_start;
7051         loff_t fl_end;
7052 +       vxid_t fl_xid;
7053  
7054         struct fasync_struct *  fl_fasync; /* for lease break notifications */
7055         /* for lease breaks: */
7056 @@ -1542,6 +1559,7 @@ struct inode_operations {
7057         ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
7058         ssize_t (*listxattr) (struct dentry *, char *, size_t);
7059         int (*removexattr) (struct dentry *, const char *);
7060 +       int (*sync_flags) (struct inode *, int, int);
7061         int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
7062                       u64 len);
7063         int (*update_time)(struct inode *, struct timespec *, int);
7064 @@ -1559,6 +1577,7 @@ ssize_t rw_copy_check_uvector(int type,
7065                               unsigned long nr_segs, unsigned long fast_segs,
7066                               struct iovec *fast_pointer,
7067                               struct iovec **ret_pointer);
7068 +ssize_t vfs_sendfile(struct file *, struct file *, loff_t *, size_t, loff_t);
7069  
7070  extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
7071  extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *);
7072 @@ -1612,6 +1631,14 @@ struct super_operations {
7073  #define S_IMA          1024    /* Inode has an associated IMA struct */
7074  #define S_AUTOMOUNT    2048    /* Automount/referral quasi-directory */
7075  #define S_NOSEC                4096    /* no suid or xattr security attributes */
7076 +#define S_IXUNLINK     8192    /* Immutable Invert on unlink */
7077 +
7078 +/* Linux-VServer related Inode flags */
7079 +
7080 +#define V_VALID                1
7081 +#define V_XATTR                2
7082 +#define V_BARRIER      4       /* Barrier for chroot() */
7083 +#define V_COW          8       /* Copy on Write */
7084  
7085  /*
7086   * Note that nosuid etc flags are inode-specific: setting some file-system
7087 @@ -1636,10 +1663,13 @@ struct super_operations {
7088  #define IS_MANDLOCK(inode)     __IS_FLG(inode, MS_MANDLOCK)
7089  #define IS_NOATIME(inode)      __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
7090  #define IS_I_VERSION(inode)    __IS_FLG(inode, MS_I_VERSION)
7091 +#define IS_TAGGED(inode)       __IS_FLG(inode, MS_TAGGED)
7092  
7093  #define IS_NOQUOTA(inode)      ((inode)->i_flags & S_NOQUOTA)
7094  #define IS_APPEND(inode)       ((inode)->i_flags & S_APPEND)
7095  #define IS_IMMUTABLE(inode)    ((inode)->i_flags & S_IMMUTABLE)
7096 +#define IS_IXUNLINK(inode)     ((inode)->i_flags & S_IXUNLINK)
7097 +#define IS_IXORUNLINK(inode)   ((IS_IXUNLINK(inode) ? S_IMMUTABLE : 0) ^ IS_IMMUTABLE(inode))
7098  #define IS_POSIXACL(inode)     __IS_FLG(inode, MS_POSIXACL)
7099  
7100  #define IS_DEADDIR(inode)      ((inode)->i_flags & S_DEAD)
7101 @@ -1653,6 +1683,16 @@ struct super_operations {
7102  #define IS_WHITEOUT(inode)     (S_ISCHR(inode->i_mode) && \
7103                                  (inode)->i_rdev == WHITEOUT_DEV)
7104  
7105 +#define IS_BARRIER(inode)      (S_ISDIR((inode)->i_mode) && ((inode)->i_vflags & V_BARRIER))
7106 +
7107 +#ifdef CONFIG_VSERVER_COWBL
7108 +#  define IS_COW(inode)                (IS_IXUNLINK(inode) && IS_IMMUTABLE(inode))
7109 +#  define IS_COW_LINK(inode)   (S_ISREG((inode)->i_mode) && ((inode)->i_nlink > 1))
7110 +#else
7111 +#  define IS_COW(inode)                (0)
7112 +#  define IS_COW_LINK(inode)   (0)
7113 +#endif
7114 +
7115  /*
7116   * Inode state bits.  Protected by inode->i_lock
7117   *
7118 @@ -1902,6 +1942,9 @@ extern struct kobject *fs_kobj;
7119  extern int locks_mandatory_locked(struct file *);
7120  extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size_t);
7121  
7122 +#define ATTR_FLAG_BARRIER      512     /* Barrier for chroot() */
7123 +#define ATTR_FLAG_IXUNLINK     1024    /* Immutable invert on unlink */
7124 +
7125  /*
7126   * Candidates for mandatory locking have the setgid bit set
7127   * but no group execute bit -  an otherwise meaningless combination.
7128 @@ -2610,6 +2653,7 @@ extern int dcache_dir_open(struct inode
7129  extern int dcache_dir_close(struct inode *, struct file *);
7130  extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
7131  extern int dcache_readdir(struct file *, struct dir_context *);
7132 +extern int dcache_readdir_filter(struct file *, struct dir_context *, int (*)(struct dentry *));
7133  extern int simple_setattr(struct dentry *, struct iattr *);
7134  extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
7135  extern int simple_statfs(struct dentry *, struct kstatfs *);
7136 diff -NurpP --minimal linux-3.18.5/include/linux/init_task.h linux-3.18.5-vs2.3.7.3/include/linux/init_task.h
7137 --- linux-3.18.5/include/linux/init_task.h      2015-01-17 02:40:21.000000000 +0000
7138 +++ linux-3.18.5-vs2.3.7.3/include/linux/init_task.h    2015-01-19 10:58:04.000000000 +0000
7139 @@ -237,6 +237,10 @@ extern struct task_group root_task_group
7140         INIT_CPUSET_SEQ(tsk)                                            \
7141         INIT_RT_MUTEXES(tsk)                                            \
7142         INIT_VTIME(tsk)                                                 \
7143 +       .xid            = 0,                                            \
7144 +       .vx_info        = NULL,                                         \
7145 +       .nid            = 0,                                            \
7146 +       .nx_info        = NULL,                                         \
7147  }
7148  
7149  
7150 diff -NurpP --minimal linux-3.18.5/include/linux/ipc.h linux-3.18.5-vs2.3.7.3/include/linux/ipc.h
7151 --- linux-3.18.5/include/linux/ipc.h    2014-06-12 11:35:01.000000000 +0000
7152 +++ linux-3.18.5-vs2.3.7.3/include/linux/ipc.h  2015-01-19 10:58:04.000000000 +0000
7153 @@ -16,6 +16,7 @@ struct kern_ipc_perm
7154         key_t           key;
7155         kuid_t          uid;
7156         kgid_t          gid;
7157 +       vxid_t          xid;
7158         kuid_t          cuid;
7159         kgid_t          cgid;
7160         umode_t         mode; 
7161 diff -NurpP --minimal linux-3.18.5/include/linux/memcontrol.h linux-3.18.5-vs2.3.7.3/include/linux/memcontrol.h
7162 --- linux-3.18.5/include/linux/memcontrol.h     2015-01-17 02:40:21.000000000 +0000
7163 +++ linux-3.18.5-vs2.3.7.3/include/linux/memcontrol.h   2015-01-19 10:58:04.000000000 +0000
7164 @@ -79,6 +79,13 @@ extern struct mem_cgroup *mem_cgroup_fro
7165  extern struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg);
7166  extern struct mem_cgroup *mem_cgroup_from_css(struct cgroup_subsys_state *css);
7167  
7168 +extern u64 mem_cgroup_res_read_u64(struct mem_cgroup *mem, int member);
7169 +extern u64 mem_cgroup_memsw_read_u64(struct mem_cgroup *mem, int member);
7170 +
7171 +extern s64 mem_cgroup_stat_read_cache(struct mem_cgroup *mem);
7172 +extern s64 mem_cgroup_stat_read_anon(struct mem_cgroup *mem);
7173 +extern s64 mem_cgroup_stat_read_mapped(struct mem_cgroup *mem);
7174 +
7175  static inline
7176  bool mm_match_cgroup(const struct mm_struct *mm, const struct mem_cgroup *memcg)
7177  {
7178 diff -NurpP --minimal linux-3.18.5/include/linux/mount.h linux-3.18.5-vs2.3.7.3/include/linux/mount.h
7179 --- linux-3.18.5/include/linux/mount.h  2015-01-17 02:40:21.000000000 +0000
7180 +++ linux-3.18.5-vs2.3.7.3/include/linux/mount.h        2015-01-19 10:58:04.000000000 +0000
7181 @@ -62,6 +62,9 @@ struct mnt_namespace;
7182  #define MNT_SYNC_UMOUNT                0x2000000
7183  #define MNT_MARKED             0x4000000
7184  
7185 +#define MNT_TAGID      0x10000
7186 +#define MNT_NOTAG      0x20000
7187 +
7188  struct vfsmount {
7189         struct dentry *mnt_root;        /* root of the mounted tree */
7190         struct super_block *mnt_sb;     /* pointer to superblock */
7191 diff -NurpP --minimal linux-3.18.5/include/linux/net.h linux-3.18.5-vs2.3.7.3/include/linux/net.h
7192 --- linux-3.18.5/include/linux/net.h    2014-06-12 13:02:49.000000000 +0000
7193 +++ linux-3.18.5-vs2.3.7.3/include/linux/net.h  2015-01-19 10:58:04.000000000 +0000
7194 @@ -39,6 +39,7 @@ struct net;
7195  #define SOCK_PASSCRED          3
7196  #define SOCK_PASSSEC           4
7197  #define SOCK_EXTERNALLY_ALLOCATED 5
7198 +#define SOCK_USER_SOCKET       6
7199  
7200  #ifndef ARCH_HAS_SOCKET_TYPES
7201  /**
7202 diff -NurpP --minimal linux-3.18.5/include/linux/netdevice.h linux-3.18.5-vs2.3.7.3/include/linux/netdevice.h
7203 --- linux-3.18.5/include/linux/netdevice.h      2015-02-05 18:02:45.000000000 +0000
7204 +++ linux-3.18.5-vs2.3.7.3/include/linux/netdevice.h    2015-01-28 11:48:02.000000000 +0000
7205 @@ -2124,6 +2124,7 @@ int init_dummy_netdev(struct net_device
7206  
7207  struct net_device *dev_get_by_index(struct net *net, int ifindex);
7208  struct net_device *__dev_get_by_index(struct net *net, int ifindex);
7209 +struct net_device *dev_get_by_index_real_rcu(struct net *net, int ifindex);
7210  struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex);
7211  int netdev_get_name(struct net *net, char *name, int ifindex);
7212  int dev_restart(struct net_device *dev);
7213 diff -NurpP --minimal linux-3.18.5/include/linux/nsproxy.h linux-3.18.5-vs2.3.7.3/include/linux/nsproxy.h
7214 --- linux-3.18.5/include/linux/nsproxy.h        2015-01-16 22:19:23.000000000 +0000
7215 +++ linux-3.18.5-vs2.3.7.3/include/linux/nsproxy.h      2015-01-19 10:58:04.000000000 +0000
7216 @@ -3,6 +3,7 @@
7217  
7218  #include <linux/spinlock.h>
7219  #include <linux/sched.h>
7220 +#include <linux/vserver/debug.h>
7221  
7222  struct mnt_namespace;
7223  struct uts_namespace;
7224 @@ -63,6 +64,7 @@ extern struct nsproxy init_nsproxy;
7225   */
7226  
7227  int copy_namespaces(unsigned long flags, struct task_struct *tsk);
7228 +struct nsproxy *copy_nsproxy(struct nsproxy *orig);
7229  void exit_task_namespaces(struct task_struct *tsk);
7230  void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new);
7231  void free_nsproxy(struct nsproxy *ns);
7232 @@ -70,16 +72,26 @@ int unshare_nsproxy_namespaces(unsigned
7233         struct cred *, struct fs_struct *);
7234  int __init nsproxy_cache_init(void);
7235  
7236 -static inline void put_nsproxy(struct nsproxy *ns)
7237 +#define        get_nsproxy(n)  __get_nsproxy(n, __FILE__, __LINE__)
7238 +
7239 +static inline void __get_nsproxy(struct nsproxy *ns,
7240 +       const char *_file, int _line)
7241  {
7242 -       if (atomic_dec_and_test(&ns->count)) {
7243 -               free_nsproxy(ns);
7244 -       }
7245 +       vxlprintk(VXD_CBIT(space, 0), "get_nsproxy(%p[%u])",
7246 +               ns, atomic_read(&ns->count), _file, _line);
7247 +       atomic_inc(&ns->count);
7248  }
7249  
7250 -static inline void get_nsproxy(struct nsproxy *ns)
7251 +#define        put_nsproxy(n)  __put_nsproxy(n, __FILE__, __LINE__)
7252 +
7253 +static inline void __put_nsproxy(struct nsproxy *ns,
7254 +       const char *_file, int _line)
7255  {
7256 -       atomic_inc(&ns->count);
7257 +       vxlprintk(VXD_CBIT(space, 0), "put_nsproxy(%p[%u])",
7258 +               ns, atomic_read(&ns->count), _file, _line);
7259 +       if (atomic_dec_and_test(&ns->count)) {
7260 +               free_nsproxy(ns);
7261 +       }
7262  }
7263  
7264  #endif
7265 diff -NurpP --minimal linux-3.18.5/include/linux/pid.h linux-3.18.5-vs2.3.7.3/include/linux/pid.h
7266 --- linux-3.18.5/include/linux/pid.h    2013-11-25 15:45:06.000000000 +0000
7267 +++ linux-3.18.5-vs2.3.7.3/include/linux/pid.h  2015-01-19 10:58:04.000000000 +0000
7268 @@ -8,7 +8,8 @@ enum pid_type
7269         PIDTYPE_PID,
7270         PIDTYPE_PGID,
7271         PIDTYPE_SID,
7272 -       PIDTYPE_MAX
7273 +       PIDTYPE_MAX,
7274 +       PIDTYPE_REALPID
7275  };
7276  
7277  /*
7278 @@ -170,6 +171,7 @@ static inline pid_t pid_nr(struct pid *p
7279  }
7280  
7281  pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns);
7282 +pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns);
7283  pid_t pid_vnr(struct pid *pid);
7284  
7285  #define do_each_pid_task(pid, type, task)                              \
7286 diff -NurpP --minimal linux-3.18.5/include/linux/quotaops.h linux-3.18.5-vs2.3.7.3/include/linux/quotaops.h
7287 --- linux-3.18.5/include/linux/quotaops.h       2014-06-12 13:02:49.000000000 +0000
7288 +++ linux-3.18.5-vs2.3.7.3/include/linux/quotaops.h     2015-01-19 10:58:04.000000000 +0000
7289 @@ -8,6 +8,7 @@
7290  #define _LINUX_QUOTAOPS_
7291  
7292  #include <linux/fs.h>
7293 +#include <linux/vs_dlimit.h>
7294  
7295  #define DQUOT_SPACE_WARN       0x1
7296  #define DQUOT_SPACE_RESERVE    0x2
7297 @@ -215,11 +216,12 @@ static inline void dquot_drop(struct ino
7298  
7299  static inline int dquot_alloc_inode(const struct inode *inode)
7300  {
7301 -       return 0;
7302 +       return dl_alloc_inode(inode);
7303  }
7304  
7305  static inline void dquot_free_inode(const struct inode *inode)
7306  {
7307 +       dl_free_inode(inode);
7308  }
7309  
7310  static inline int dquot_transfer(struct inode *inode, struct iattr *iattr)
7311 @@ -230,6 +232,10 @@ static inline int dquot_transfer(struct
7312  static inline int __dquot_alloc_space(struct inode *inode, qsize_t number,
7313                 int flags)
7314  {
7315 +       int ret = 0;
7316 +
7317 +       if ((ret = dl_alloc_space(inode, number)))
7318 +               return ret;
7319         if (!(flags & DQUOT_SPACE_RESERVE))
7320                 inode_add_bytes(inode, number);
7321         return 0;
7322 @@ -240,6 +246,7 @@ static inline void __dquot_free_space(st
7323  {
7324         if (!(flags & DQUOT_SPACE_RESERVE))
7325                 inode_sub_bytes(inode, number);
7326 +       dl_free_space(inode, number);
7327  }
7328  
7329  static inline int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
7330 diff -NurpP --minimal linux-3.18.5/include/linux/sched.h linux-3.18.5-vs2.3.7.3/include/linux/sched.h
7331 --- linux-3.18.5/include/linux/sched.h  2015-01-17 02:40:22.000000000 +0000
7332 +++ linux-3.18.5-vs2.3.7.3/include/linux/sched.h        2015-01-19 10:58:04.000000000 +0000
7333 @@ -1438,6 +1438,14 @@ struct task_struct {
7334  #endif
7335         struct seccomp seccomp;
7336  
7337 +/* vserver context data */
7338 +       struct vx_info *vx_info;
7339 +       struct nx_info *nx_info;
7340 +
7341 +       vxid_t xid;
7342 +       vnid_t nid;
7343 +       vtag_t tag;
7344 +
7345  /* Thread group tracking */
7346         u32 parent_exec_id;
7347         u32 self_exec_id;
7348 @@ -1743,6 +1751,11 @@ struct pid_namespace;
7349  pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
7350                         struct pid_namespace *ns);
7351  
7352 +#include <linux/vserver/base.h>
7353 +#include <linux/vserver/context.h>
7354 +#include <linux/vserver/debug.h>
7355 +#include <linux/vserver/pid.h>
7356 +
7357  static inline pid_t task_pid_nr(struct task_struct *tsk)
7358  {
7359         return tsk->pid;
7360 @@ -1756,7 +1769,8 @@ static inline pid_t task_pid_nr_ns(struc
7361  
7362  static inline pid_t task_pid_vnr(struct task_struct *tsk)
7363  {
7364 -       return __task_pid_nr_ns(tsk, PIDTYPE_PID, NULL);
7365 +       // return __task_pid_nr_ns(tsk, PIDTYPE_PID, NULL);
7366 +       return vx_map_pid(__task_pid_nr_ns(tsk, PIDTYPE_PID, NULL));
7367  }
7368  
7369  
7370 @@ -1769,7 +1783,7 @@ pid_t task_tgid_nr_ns(struct task_struct
7371  
7372  static inline pid_t task_tgid_vnr(struct task_struct *tsk)
7373  {
7374 -       return pid_vnr(task_tgid(tsk));
7375 +       return vx_map_tgid(pid_vnr(task_tgid(tsk)));
7376  }
7377  
7378  
7379 diff -NurpP --minimal linux-3.18.5/include/linux/shmem_fs.h linux-3.18.5-vs2.3.7.3/include/linux/shmem_fs.h
7380 --- linux-3.18.5/include/linux/shmem_fs.h       2015-01-16 22:19:23.000000000 +0000
7381 +++ linux-3.18.5-vs2.3.7.3/include/linux/shmem_fs.h     2015-01-19 10:58:04.000000000 +0000
7382 @@ -10,6 +10,9 @@
7383  
7384  /* inode in-kernel data */
7385  
7386 +#define TMPFS_SUPER_MAGIC      0x01021994
7387 +
7388 +
7389  struct shmem_inode_info {
7390         spinlock_t              lock;
7391         unsigned int            seals;          /* shmem seals */
7392 diff -NurpP --minimal linux-3.18.5/include/linux/stat.h linux-3.18.5-vs2.3.7.3/include/linux/stat.h
7393 --- linux-3.18.5/include/linux/stat.h   2012-12-11 03:30:57.000000000 +0000
7394 +++ linux-3.18.5-vs2.3.7.3/include/linux/stat.h 2015-01-19 10:58:04.000000000 +0000
7395 @@ -25,6 +25,7 @@ struct kstat {
7396         unsigned int    nlink;
7397         kuid_t          uid;
7398         kgid_t          gid;
7399 +       ktag_t          tag;
7400         dev_t           rdev;
7401         loff_t          size;
7402         struct timespec  atime;
7403 diff -NurpP --minimal linux-3.18.5/include/linux/sunrpc/auth.h linux-3.18.5-vs2.3.7.3/include/linux/sunrpc/auth.h
7404 --- linux-3.18.5/include/linux/sunrpc/auth.h    2015-01-16 22:19:23.000000000 +0000
7405 +++ linux-3.18.5-vs2.3.7.3/include/linux/sunrpc/auth.h  2015-01-19 10:58:04.000000000 +0000
7406 @@ -36,6 +36,7 @@ enum {
7407  struct auth_cred {
7408         kuid_t  uid;
7409         kgid_t  gid;
7410 +       ktag_t  tag;
7411         struct group_info *group_info;
7412         const char *principal;
7413         unsigned long ac_flags;
7414 diff -NurpP --minimal linux-3.18.5/include/linux/sunrpc/clnt.h linux-3.18.5-vs2.3.7.3/include/linux/sunrpc/clnt.h
7415 --- linux-3.18.5/include/linux/sunrpc/clnt.h    2014-06-12 13:02:50.000000000 +0000
7416 +++ linux-3.18.5-vs2.3.7.3/include/linux/sunrpc/clnt.h  2015-01-19 10:58:04.000000000 +0000
7417 @@ -51,7 +51,8 @@ struct rpc_clnt {
7418                                 cl_discrtry : 1,/* disconnect before retry */
7419                                 cl_noretranstimeo: 1,/* No retransmit timeouts */
7420                                 cl_autobind : 1,/* use getport() */
7421 -                               cl_chatty   : 1;/* be verbose */
7422 +                               cl_chatty   : 1,/* be verbose */
7423 +                               cl_tag      : 1;/* context tagging */
7424  
7425         struct rpc_rtt *        cl_rtt;         /* RTO estimator data */
7426         const struct rpc_timeout *cl_timeout;   /* Timeout strategy */
7427 diff -NurpP --minimal linux-3.18.5/include/linux/types.h linux-3.18.5-vs2.3.7.3/include/linux/types.h
7428 --- linux-3.18.5/include/linux/types.h  2014-09-03 13:19:43.000000000 +0000
7429 +++ linux-3.18.5-vs2.3.7.3/include/linux/types.h        2015-01-19 10:58:04.000000000 +0000
7430 @@ -32,6 +32,9 @@ typedef __kernel_uid32_t      uid_t;
7431  typedef __kernel_gid32_t       gid_t;
7432  typedef __kernel_uid16_t        uid16_t;
7433  typedef __kernel_gid16_t        gid16_t;
7434 +typedef unsigned int           vxid_t;
7435 +typedef unsigned int           vnid_t;
7436 +typedef unsigned int           vtag_t;
7437  
7438  typedef unsigned long          uintptr_t;
7439  
7440 diff -NurpP --minimal linux-3.18.5/include/linux/uidgid.h linux-3.18.5-vs2.3.7.3/include/linux/uidgid.h
7441 --- linux-3.18.5/include/linux/uidgid.h 2014-06-12 11:35:03.000000000 +0000
7442 +++ linux-3.18.5-vs2.3.7.3/include/linux/uidgid.h       2015-01-25 18:11:57.000000000 +0000
7443 @@ -21,13 +21,17 @@ typedef struct {
7444         uid_t val;
7445  } kuid_t;
7446  
7447 -
7448  typedef struct {
7449         gid_t val;
7450  } kgid_t;
7451  
7452 +typedef struct {
7453 +       vtag_t val;
7454 +} ktag_t;
7455 +
7456  #define KUIDT_INIT(value) (kuid_t){ value }
7457  #define KGIDT_INIT(value) (kgid_t){ value }
7458 +#define KTAGT_INIT(value) (ktag_t){ value }
7459  
7460  static inline uid_t __kuid_val(kuid_t uid)
7461  {
7462 @@ -39,11 +43,18 @@ static inline gid_t __kgid_val(kgid_t gi
7463         return gid.val;
7464  }
7465  
7466 +static inline vtag_t __ktag_val(ktag_t tag)
7467 +{
7468 +       return tag.val;
7469 +}
7470 +
7471  #define GLOBAL_ROOT_UID KUIDT_INIT(0)
7472  #define GLOBAL_ROOT_GID KGIDT_INIT(0)
7473 +#define GLOBAL_ROOT_TAG KTAGT_INIT(0)
7474  
7475  #define INVALID_UID KUIDT_INIT(-1)
7476  #define INVALID_GID KGIDT_INIT(-1)
7477 +#define INVALID_TAG KTAGT_INIT(-1)
7478  
7479  static inline bool uid_eq(kuid_t left, kuid_t right)
7480  {
7481 @@ -55,6 +66,11 @@ static inline bool gid_eq(kgid_t left, k
7482         return __kgid_val(left) == __kgid_val(right);
7483  }
7484  
7485 +static inline bool tag_eq(ktag_t left, ktag_t right)
7486 +{
7487 +       return __ktag_val(left) == __ktag_val(right);
7488 +}
7489 +
7490  static inline bool uid_gt(kuid_t left, kuid_t right)
7491  {
7492         return __kuid_val(left) > __kuid_val(right);
7493 @@ -105,13 +121,21 @@ static inline bool gid_valid(kgid_t gid)
7494         return !gid_eq(gid, INVALID_GID);
7495  }
7496  
7497 +static inline bool tag_valid(ktag_t tag)
7498 +{
7499 +       return !tag_eq(tag, INVALID_TAG);
7500 +}
7501 +
7502  #ifdef CONFIG_USER_NS
7503  
7504  extern kuid_t make_kuid(struct user_namespace *from, uid_t uid);
7505  extern kgid_t make_kgid(struct user_namespace *from, gid_t gid);
7506 +extern ktag_t make_ktag(struct user_namespace *from, gid_t gid);
7507  
7508  extern uid_t from_kuid(struct user_namespace *to, kuid_t uid);
7509  extern gid_t from_kgid(struct user_namespace *to, kgid_t gid);
7510 +extern vtag_t from_ktag(struct user_namespace *to, ktag_t tag);
7511 +
7512  extern uid_t from_kuid_munged(struct user_namespace *to, kuid_t uid);
7513  extern gid_t from_kgid_munged(struct user_namespace *to, kgid_t gid);
7514  
7515 @@ -137,6 +161,11 @@ static inline kgid_t make_kgid(struct us
7516         return KGIDT_INIT(gid);
7517  }
7518  
7519 +static inline ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
7520 +{
7521 +       return KTAGT_INIT(tag);
7522 +}
7523 +
7524  static inline uid_t from_kuid(struct user_namespace *to, kuid_t kuid)
7525  {
7526         return __kuid_val(kuid);
7527 @@ -147,6 +176,11 @@ static inline gid_t from_kgid(struct use
7528         return __kgid_val(kgid);
7529  }
7530  
7531 +static inline vtag_t from_ktag(struct user_namespace *to, ktag_t ktag)
7532 +{
7533 +       return __ktag_val(ktag);
7534 +}
7535 +
7536  static inline uid_t from_kuid_munged(struct user_namespace *to, kuid_t kuid)
7537  {
7538         uid_t uid = from_kuid(to, kuid);
7539 diff -NurpP --minimal linux-3.18.5/include/linux/vroot.h linux-3.18.5-vs2.3.7.3/include/linux/vroot.h
7540 --- linux-3.18.5/include/linux/vroot.h  1970-01-01 00:00:00.000000000 +0000
7541 +++ linux-3.18.5-vs2.3.7.3/include/linux/vroot.h        2015-01-19 10:58:04.000000000 +0000
7542 @@ -0,0 +1,51 @@
7543 +
7544 +/*
7545 + * include/linux/vroot.h
7546 + *
7547 + * written by Herbert Pötzl, 9/11/2002
7548 + * ported to 2.6 by Herbert Pötzl, 30/12/2004
7549 + *
7550 + * Copyright (C) 2002-2007 by Herbert Pötzl.
7551 + * Redistribution of this file is permitted under the
7552 + * GNU General Public License.
7553 + */
7554 +
7555 +#ifndef _LINUX_VROOT_H
7556 +#define _LINUX_VROOT_H
7557 +
7558 +
7559 +#ifdef __KERNEL__
7560 +
7561 +/* Possible states of device */
7562 +enum {
7563 +       Vr_unbound,
7564 +       Vr_bound,
7565 +};
7566 +
7567 +struct vroot_device {
7568 +       int             vr_number;
7569 +       int             vr_refcnt;
7570 +
7571 +       struct semaphore        vr_ctl_mutex;
7572 +       struct block_device    *vr_device;
7573 +       int                     vr_state;
7574 +};
7575 +
7576 +
7577 +typedef struct block_device *(vroot_grb_func)(struct block_device *);
7578 +
7579 +extern int register_vroot_grb(vroot_grb_func *);
7580 +extern int unregister_vroot_grb(vroot_grb_func *);
7581 +
7582 +#endif /* __KERNEL__ */
7583 +
7584 +#define MAX_VROOT_DEFAULT      8
7585 +
7586 +/*
7587 + * IOCTL commands --- we will commandeer 0x56 ('V')
7588 + */
7589 +
7590 +#define VROOT_SET_DEV          0x5600
7591 +#define VROOT_CLR_DEV          0x5601
7592 +
7593 +#endif /* _LINUX_VROOT_H */
7594 diff -NurpP --minimal linux-3.18.5/include/linux/vs_base.h linux-3.18.5-vs2.3.7.3/include/linux/vs_base.h
7595 --- linux-3.18.5/include/linux/vs_base.h        1970-01-01 00:00:00.000000000 +0000
7596 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_base.h      2015-01-19 10:58:04.000000000 +0000
7597 @@ -0,0 +1,10 @@
7598 +#ifndef _VS_BASE_H
7599 +#define _VS_BASE_H
7600 +
7601 +#include "vserver/base.h"
7602 +#include "vserver/check.h"
7603 +#include "vserver/debug.h"
7604 +
7605 +#else
7606 +#warning duplicate inclusion
7607 +#endif
7608 diff -NurpP --minimal linux-3.18.5/include/linux/vs_context.h linux-3.18.5-vs2.3.7.3/include/linux/vs_context.h
7609 --- linux-3.18.5/include/linux/vs_context.h     1970-01-01 00:00:00.000000000 +0000
7610 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_context.h   2015-01-19 10:58:04.000000000 +0000
7611 @@ -0,0 +1,242 @@
7612 +#ifndef _VS_CONTEXT_H
7613 +#define _VS_CONTEXT_H
7614 +
7615 +#include "vserver/base.h"
7616 +#include "vserver/check.h"
7617 +#include "vserver/context.h"
7618 +#include "vserver/history.h"
7619 +#include "vserver/debug.h"
7620 +
7621 +#include <linux/sched.h>
7622 +
7623 +
7624 +#define get_vx_info(i) __get_vx_info(i, __FILE__, __LINE__, __HERE__)
7625 +
7626 +static inline struct vx_info *__get_vx_info(struct vx_info *vxi,
7627 +       const char *_file, int _line, void *_here)
7628 +{
7629 +       if (!vxi)
7630 +               return NULL;
7631 +
7632 +       vxlprintk(VXD_CBIT(xid, 2), "get_vx_info(%p[#%d.%d])",
7633 +               vxi, vxi ? vxi->vx_id : 0,
7634 +               vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7635 +               _file, _line);
7636 +       __vxh_get_vx_info(vxi, _here);
7637 +
7638 +       atomic_inc(&vxi->vx_usecnt);
7639 +       return vxi;
7640 +}
7641 +
7642 +
7643 +extern void free_vx_info(struct vx_info *);
7644 +
7645 +#define put_vx_info(i) __put_vx_info(i, __FILE__, __LINE__, __HERE__)
7646 +
7647 +static inline void __put_vx_info(struct vx_info *vxi,
7648 +       const char *_file, int _line, void *_here)
7649 +{
7650 +       if (!vxi)
7651 +               return;
7652 +
7653 +       vxlprintk(VXD_CBIT(xid, 2), "put_vx_info(%p[#%d.%d])",
7654 +               vxi, vxi ? vxi->vx_id : 0,
7655 +               vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7656 +               _file, _line);
7657 +       __vxh_put_vx_info(vxi, _here);
7658 +
7659 +       if (atomic_dec_and_test(&vxi->vx_usecnt))
7660 +               free_vx_info(vxi);
7661 +}
7662 +
7663 +
7664 +#define init_vx_info(p, i) \
7665 +       __init_vx_info(p, i, __FILE__, __LINE__, __HERE__)
7666 +
7667 +static inline void __init_vx_info(struct vx_info **vxp, struct vx_info *vxi,
7668 +       const char *_file, int _line, void *_here)
7669 +{
7670 +       if (vxi) {
7671 +               vxlprintk(VXD_CBIT(xid, 3),
7672 +                       "init_vx_info(%p[#%d.%d])",
7673 +                       vxi, vxi ? vxi->vx_id : 0,
7674 +                       vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7675 +                       _file, _line);
7676 +               __vxh_init_vx_info(vxi, vxp, _here);
7677 +
7678 +               atomic_inc(&vxi->vx_usecnt);
7679 +       }
7680 +       *vxp = vxi;
7681 +}
7682 +
7683 +
7684 +#define set_vx_info(p, i) \
7685 +       __set_vx_info(p, i, __FILE__, __LINE__, __HERE__)
7686 +
7687 +static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi,
7688 +       const char *_file, int _line, void *_here)
7689 +{
7690 +       struct vx_info *vxo;
7691 +
7692 +       if (!vxi)
7693 +               return;
7694 +
7695 +       vxlprintk(VXD_CBIT(xid, 3), "set_vx_info(%p[#%d.%d])",
7696 +               vxi, vxi ? vxi->vx_id : 0,
7697 +               vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7698 +               _file, _line);
7699 +       __vxh_set_vx_info(vxi, vxp, _here);
7700 +
7701 +       atomic_inc(&vxi->vx_usecnt);
7702 +       vxo = xchg(vxp, vxi);
7703 +       BUG_ON(vxo);
7704 +}
7705 +
7706 +
7707 +#define clr_vx_info(p) __clr_vx_info(p, __FILE__, __LINE__, __HERE__)
7708 +
7709 +static inline void __clr_vx_info(struct vx_info **vxp,
7710 +       const char *_file, int _line, void *_here)
7711 +{
7712 +       struct vx_info *vxo;
7713 +
7714 +       vxo = xchg(vxp, NULL);
7715 +       if (!vxo)
7716 +               return;
7717 +
7718 +       vxlprintk(VXD_CBIT(xid, 3), "clr_vx_info(%p[#%d.%d])",
7719 +               vxo, vxo ? vxo->vx_id : 0,
7720 +               vxo ? atomic_read(&vxo->vx_usecnt) : 0,
7721 +               _file, _line);
7722 +       __vxh_clr_vx_info(vxo, vxp, _here);
7723 +
7724 +       if (atomic_dec_and_test(&vxo->vx_usecnt))
7725 +               free_vx_info(vxo);
7726 +}
7727 +
7728 +
7729 +#define claim_vx_info(v, p) \
7730 +       __claim_vx_info(v, p, __FILE__, __LINE__, __HERE__)
7731 +
7732 +static inline void __claim_vx_info(struct vx_info *vxi,
7733 +       struct task_struct *task,
7734 +       const char *_file, int _line, void *_here)
7735 +{
7736 +       vxlprintk(VXD_CBIT(xid, 3), "claim_vx_info(%p[#%d.%d.%d]) %p",
7737 +               vxi, vxi ? vxi->vx_id : 0,
7738 +               vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7739 +               vxi ? atomic_read(&vxi->vx_tasks) : 0,
7740 +               task, _file, _line);
7741 +       __vxh_claim_vx_info(vxi, task, _here);
7742 +
7743 +       atomic_inc(&vxi->vx_tasks);
7744 +}
7745 +
7746 +
7747 +extern void unhash_vx_info(struct vx_info *);
7748 +
7749 +#define release_vx_info(v, p) \
7750 +       __release_vx_info(v, p, __FILE__, __LINE__, __HERE__)
7751 +
7752 +static inline void __release_vx_info(struct vx_info *vxi,
7753 +       struct task_struct *task,
7754 +       const char *_file, int _line, void *_here)
7755 +{
7756 +       vxlprintk(VXD_CBIT(xid, 3), "release_vx_info(%p[#%d.%d.%d]) %p",
7757 +               vxi, vxi ? vxi->vx_id : 0,
7758 +               vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7759 +               vxi ? atomic_read(&vxi->vx_tasks) : 0,
7760 +               task, _file, _line);
7761 +       __vxh_release_vx_info(vxi, task, _here);
7762 +
7763 +       might_sleep();
7764 +
7765 +       if (atomic_dec_and_test(&vxi->vx_tasks))
7766 +               unhash_vx_info(vxi);
7767 +}
7768 +
7769 +
7770 +#define task_get_vx_info(p) \
7771 +       __task_get_vx_info(p, __FILE__, __LINE__, __HERE__)
7772 +
7773 +static inline struct vx_info *__task_get_vx_info(struct task_struct *p,
7774 +       const char *_file, int _line, void *_here)
7775 +{
7776 +       struct vx_info *vxi;
7777 +
7778 +       task_lock(p);
7779 +       vxlprintk(VXD_CBIT(xid, 5), "task_get_vx_info(%p)",
7780 +               p, _file, _line);
7781 +       vxi = __get_vx_info(p->vx_info, _file, _line, _here);
7782 +       task_unlock(p);
7783 +       return vxi;
7784 +}
7785 +
7786 +
7787 +static inline void __wakeup_vx_info(struct vx_info *vxi)
7788 +{
7789 +       if (waitqueue_active(&vxi->vx_wait))
7790 +               wake_up_interruptible(&vxi->vx_wait);
7791 +}
7792 +
7793 +
7794 +#define enter_vx_info(v, s) __enter_vx_info(v, s, __FILE__, __LINE__)
7795 +
7796 +static inline void __enter_vx_info(struct vx_info *vxi,
7797 +       struct vx_info_save *vxis, const char *_file, int _line)
7798 +{
7799 +       vxlprintk(VXD_CBIT(xid, 5), "enter_vx_info(%p[#%d],%p) %p[#%d,%p]",
7800 +               vxi, vxi ? vxi->vx_id : 0, vxis, current,
7801 +               current->xid, current->vx_info, _file, _line);
7802 +       vxis->vxi = xchg(&current->vx_info, vxi);
7803 +       vxis->xid = current->xid;
7804 +       current->xid = vxi ? vxi->vx_id : 0;
7805 +}
7806 +
7807 +#define leave_vx_info(s) __leave_vx_info(s, __FILE__, __LINE__)
7808 +
7809 +static inline void __leave_vx_info(struct vx_info_save *vxis,
7810 +       const char *_file, int _line)
7811 +{
7812 +       vxlprintk(VXD_CBIT(xid, 5), "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]",
7813 +               vxis, vxis->xid, vxis->vxi, current,
7814 +               current->xid, current->vx_info, _file, _line);
7815 +       (void)xchg(&current->vx_info, vxis->vxi);
7816 +       current->xid = vxis->xid;
7817 +}
7818 +
7819 +
7820 +static inline void __enter_vx_admin(struct vx_info_save *vxis)
7821 +{
7822 +       vxis->vxi = xchg(&current->vx_info, NULL);
7823 +       vxis->xid = xchg(&current->xid, (vxid_t)0);
7824 +}
7825 +
7826 +static inline void __leave_vx_admin(struct vx_info_save *vxis)
7827 +{
7828 +       (void)xchg(&current->xid, vxis->xid);
7829 +       (void)xchg(&current->vx_info, vxis->vxi);
7830 +}
7831 +
7832 +#define task_is_init(p) \
7833 +       __task_is_init(p, __FILE__, __LINE__, __HERE__)
7834 +
7835 +static inline int __task_is_init(struct task_struct *p,
7836 +       const char *_file, int _line, void *_here)
7837 +{
7838 +       int is_init = is_global_init(p);
7839 +
7840 +       task_lock(p);
7841 +       if (p->vx_info)
7842 +               is_init = p->vx_info->vx_initpid == p->pid;
7843 +       task_unlock(p);
7844 +       return is_init;
7845 +}
7846 +
7847 +extern void exit_vx_info(struct task_struct *, int);
7848 +extern void exit_vx_info_early(struct task_struct *, int);
7849 +
7850 +
7851 +#else
7852 +#warning duplicate inclusion
7853 +#endif
7854 diff -NurpP --minimal linux-3.18.5/include/linux/vs_cowbl.h linux-3.18.5-vs2.3.7.3/include/linux/vs_cowbl.h
7855 --- linux-3.18.5/include/linux/vs_cowbl.h       1970-01-01 00:00:00.000000000 +0000
7856 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_cowbl.h     2015-01-19 10:58:04.000000000 +0000
7857 @@ -0,0 +1,48 @@
7858 +#ifndef _VS_COWBL_H
7859 +#define _VS_COWBL_H
7860 +
7861 +#include <linux/fs.h>
7862 +#include <linux/dcache.h>
7863 +#include <linux/namei.h>
7864 +#include <linux/slab.h>
7865 +
7866 +extern struct dentry *cow_break_link(const char *pathname);
7867 +
7868 +static inline int cow_check_and_break(struct path *path)
7869 +{
7870 +       struct inode *inode = path->dentry->d_inode;
7871 +       int error = 0;
7872 +
7873 +       /* do we need this check? */
7874 +       if (IS_RDONLY(inode))
7875 +               return -EROFS;
7876 +
7877 +       if (IS_COW(inode)) {
7878 +               if (IS_COW_LINK(inode)) {
7879 +                       struct dentry *new_dentry, *old_dentry = path->dentry;
7880 +                       char *pp, *buf;
7881 +
7882 +                       buf = kmalloc(PATH_MAX, GFP_KERNEL);
7883 +                       if (!buf) {
7884 +                               return -ENOMEM;
7885 +                       }
7886 +                       pp = d_path(path, buf, PATH_MAX);
7887 +                       new_dentry = cow_break_link(pp);
7888 +                       kfree(buf);
7889 +                       if (!IS_ERR(new_dentry)) {
7890 +                               path->dentry = new_dentry;
7891 +                               dput(old_dentry);
7892 +                       } else
7893 +                               error = PTR_ERR(new_dentry);
7894 +               } else {
7895 +                       inode->i_flags &= ~(S_IXUNLINK | S_IMMUTABLE);
7896 +                       inode->i_ctime = CURRENT_TIME;
7897 +                       mark_inode_dirty(inode);
7898 +               }
7899 +       }
7900 +       return error;
7901 +}
7902 +
7903 +#else
7904 +#warning duplicate inclusion
7905 +#endif
7906 diff -NurpP --minimal linux-3.18.5/include/linux/vs_cvirt.h linux-3.18.5-vs2.3.7.3/include/linux/vs_cvirt.h
7907 --- linux-3.18.5/include/linux/vs_cvirt.h       1970-01-01 00:00:00.000000000 +0000
7908 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_cvirt.h     2015-01-19 10:58:04.000000000 +0000
7909 @@ -0,0 +1,50 @@
7910 +#ifndef _VS_CVIRT_H
7911 +#define _VS_CVIRT_H
7912 +
7913 +#include "vserver/cvirt.h"
7914 +#include "vserver/context.h"
7915 +#include "vserver/base.h"
7916 +#include "vserver/check.h"
7917 +#include "vserver/debug.h"
7918 +
7919 +
7920 +static inline void vx_activate_task(struct task_struct *p)
7921 +{
7922 +       struct vx_info *vxi;
7923 +
7924 +       if ((vxi = p->vx_info)) {
7925 +               vx_update_load(vxi);
7926 +               atomic_inc(&vxi->cvirt.nr_running);
7927 +       }
7928 +}
7929 +
7930 +static inline void vx_deactivate_task(struct task_struct *p)
7931 +{
7932 +       struct vx_info *vxi;
7933 +
7934 +       if ((vxi = p->vx_info)) {
7935 +               vx_update_load(vxi);
7936 +               atomic_dec(&vxi->cvirt.nr_running);
7937 +       }
7938 +}
7939 +
7940 +static inline void vx_uninterruptible_inc(struct task_struct *p)
7941 +{
7942 +       struct vx_info *vxi;
7943 +
7944 +       if ((vxi = p->vx_info))
7945 +               atomic_inc(&vxi->cvirt.nr_uninterruptible);
7946 +}
7947 +
7948 +static inline void vx_uninterruptible_dec(struct task_struct *p)
7949 +{
7950 +       struct vx_info *vxi;
7951 +
7952 +       if ((vxi = p->vx_info))
7953 +               atomic_dec(&vxi->cvirt.nr_uninterruptible);
7954 +}
7955 +
7956 +
7957 +#else
7958 +#warning duplicate inclusion
7959 +#endif
7960 diff -NurpP --minimal linux-3.18.5/include/linux/vs_device.h linux-3.18.5-vs2.3.7.3/include/linux/vs_device.h
7961 --- linux-3.18.5/include/linux/vs_device.h      1970-01-01 00:00:00.000000000 +0000
7962 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_device.h    2015-01-19 10:58:04.000000000 +0000
7963 @@ -0,0 +1,45 @@
7964 +#ifndef _VS_DEVICE_H
7965 +#define _VS_DEVICE_H
7966 +
7967 +#include "vserver/base.h"
7968 +#include "vserver/device.h"
7969 +#include "vserver/debug.h"
7970 +
7971 +
7972 +#ifdef CONFIG_VSERVER_DEVICE
7973 +
7974 +int vs_map_device(struct vx_info *, dev_t, dev_t *, umode_t);
7975 +
7976 +#define vs_device_perm(v, d, m, p) \
7977 +       ((vs_map_device(current_vx_info(), d, NULL, m) & (p)) == (p))
7978 +
7979 +#else
7980 +
7981 +static inline
7982 +int vs_map_device(struct vx_info *vxi,
7983 +       dev_t device, dev_t *target, umode_t mode)
7984 +{
7985 +       if (target)
7986 +               *target = device;
7987 +       return ~0;
7988 +}
7989 +
7990 +#define vs_device_perm(v, d, m, p) ((p) == (p))
7991 +
7992 +#endif
7993 +
7994 +
7995 +#define vs_map_chrdev(d, t, p) \
7996 +       ((vs_map_device(current_vx_info(), d, t, S_IFCHR) & (p)) == (p))
7997 +#define vs_map_blkdev(d, t, p) \
7998 +       ((vs_map_device(current_vx_info(), d, t, S_IFBLK) & (p)) == (p))
7999 +
8000 +#define vs_chrdev_perm(d, p) \
8001 +       vs_device_perm(current_vx_info(), d, S_IFCHR, p)
8002 +#define vs_blkdev_perm(d, p) \
8003 +       vs_device_perm(current_vx_info(), d, S_IFBLK, p)
8004 +
8005 +
8006 +#else
8007 +#warning duplicate inclusion
8008 +#endif
8009 diff -NurpP --minimal linux-3.18.5/include/linux/vs_dlimit.h linux-3.18.5-vs2.3.7.3/include/linux/vs_dlimit.h
8010 --- linux-3.18.5/include/linux/vs_dlimit.h      1970-01-01 00:00:00.000000000 +0000
8011 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_dlimit.h    2015-01-19 10:58:04.000000000 +0000
8012 @@ -0,0 +1,215 @@
8013 +#ifndef _VS_DLIMIT_H
8014 +#define _VS_DLIMIT_H
8015 +
8016 +#include <linux/fs.h>
8017 +
8018 +#include "vserver/dlimit.h"
8019 +#include "vserver/base.h"
8020 +#include "vserver/debug.h"
8021 +
8022 +
8023 +#define get_dl_info(i) __get_dl_info(i, __FILE__, __LINE__)
8024 +
8025 +static inline struct dl_info *__get_dl_info(struct dl_info *dli,
8026 +       const char *_file, int _line)
8027 +{
8028 +       if (!dli)
8029 +               return NULL;
8030 +       vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])",
8031 +               dli, dli ? dli->dl_tag : 0,
8032 +               dli ? atomic_read(&dli->dl_usecnt) : 0,
8033 +               _file, _line);
8034 +       atomic_inc(&dli->dl_usecnt);
8035 +       return dli;
8036 +}
8037 +
8038 +
8039 +#define free_dl_info(i) \
8040 +       call_rcu(&(i)->dl_rcu, rcu_free_dl_info)
8041 +
8042 +#define put_dl_info(i) __put_dl_info(i, __FILE__, __LINE__)
8043 +
8044 +static inline void __put_dl_info(struct dl_info *dli,
8045 +       const char *_file, int _line)
8046 +{
8047 +       if (!dli)
8048 +               return;
8049 +       vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])",
8050 +               dli, dli ? dli->dl_tag : 0,
8051 +               dli ? atomic_read(&dli->dl_usecnt) : 0,
8052 +               _file, _line);
8053 +       if (atomic_dec_and_test(&dli->dl_usecnt))
8054 +               free_dl_info(dli);
8055 +}
8056 +
8057 +
8058 +#define __dlimit_char(d)       ((d) ? '*' : ' ')
8059 +
8060 +static inline int __dl_alloc_space(struct super_block *sb,
8061 +       vtag_t tag, dlsize_t nr, const char *file, int line)
8062 +{
8063 +       struct dl_info *dli = NULL;
8064 +       int ret = 0;
8065 +
8066 +       if (nr == 0)
8067 +               goto out;
8068 +       dli = locate_dl_info(sb, tag);
8069 +       if (!dli)
8070 +               goto out;
8071 +
8072 +       spin_lock(&dli->dl_lock);
8073 +       ret = (dli->dl_space_used + nr > dli->dl_space_total);
8074 +       if (!ret)
8075 +               dli->dl_space_used += nr;
8076 +       spin_unlock(&dli->dl_lock);
8077 +       put_dl_info(dli);
8078 +out:
8079 +       vxlprintk(VXD_CBIT(dlim, 1),
8080 +               "ALLOC (%p,#%d)%c %lld bytes (%d)",
8081 +               sb, tag, __dlimit_char(dli), (long long)nr,
8082 +               ret, file, line);
8083 +       return ret ? -ENOSPC : 0;
8084 +}
8085 +
8086 +static inline void __dl_free_space(struct super_block *sb,
8087 +       vtag_t tag, dlsize_t nr, const char *_file, int _line)
8088 +{
8089 +       struct dl_info *dli = NULL;
8090 +
8091 +       if (nr == 0)
8092 +               goto out;
8093 +       dli = locate_dl_info(sb, tag);
8094 +       if (!dli)
8095 +               goto out;
8096 +
8097 +       spin_lock(&dli->dl_lock);
8098 +       if (dli->dl_space_used > nr)
8099 +               dli->dl_space_used -= nr;
8100 +       else
8101 +               dli->dl_space_used = 0;
8102 +       spin_unlock(&dli->dl_lock);
8103 +       put_dl_info(dli);
8104 +out:
8105 +       vxlprintk(VXD_CBIT(dlim, 1),
8106 +               "FREE  (%p,#%d)%c %lld bytes",
8107 +               sb, tag, __dlimit_char(dli), (long long)nr,
8108 +               _file, _line);
8109 +}
8110 +
8111 +static inline int __dl_alloc_inode(struct super_block *sb,
8112 +       vtag_t tag, const char *_file, int _line)
8113 +{
8114 +       struct dl_info *dli;
8115 +       int ret = 0;
8116 +
8117 +       dli = locate_dl_info(sb, tag);
8118 +       if (!dli)
8119 +               goto out;
8120 +
8121 +       spin_lock(&dli->dl_lock);
8122 +       dli->dl_inodes_used++;
8123 +       ret = (dli->dl_inodes_used > dli->dl_inodes_total);
8124 +       spin_unlock(&dli->dl_lock);
8125 +       put_dl_info(dli);
8126 +out:
8127 +       vxlprintk(VXD_CBIT(dlim, 0),
8128 +               "ALLOC (%p,#%d)%c inode (%d)",
8129 +               sb, tag, __dlimit_char(dli), ret, _file, _line);
8130 +       return ret ? -ENOSPC : 0;
8131 +}
8132 +
8133 +static inline void __dl_free_inode(struct super_block *sb,
8134 +       vtag_t tag, const char *_file, int _line)
8135 +{
8136 +       struct dl_info *dli;
8137 +
8138 +       dli = locate_dl_info(sb, tag);
8139 +       if (!dli)
8140 +               goto out;
8141 +
8142 +       spin_lock(&dli->dl_lock);
8143 +       if (dli->dl_inodes_used > 1)
8144 +               dli->dl_inodes_used--;
8145 +       else
8146 +               dli->dl_inodes_used = 0;
8147 +       spin_unlock(&dli->dl_lock);
8148 +       put_dl_info(dli);
8149 +out:
8150 +       vxlprintk(VXD_CBIT(dlim, 0),
8151 +               "FREE  (%p,#%d)%c inode",
8152 +               sb, tag, __dlimit_char(dli), _file, _line);
8153 +}
8154 +
8155 +static inline void __dl_adjust_block(struct super_block *sb, vtag_t tag,
8156 +       unsigned long long *free_blocks, unsigned long long *root_blocks,
8157 +       const char *_file, int _line)
8158 +{
8159 +       struct dl_info *dli;
8160 +       uint64_t broot, bfree;
8161 +
8162 +       dli = locate_dl_info(sb, tag);
8163 +       if (!dli)
8164 +               return;
8165 +
8166 +       spin_lock(&dli->dl_lock);
8167 +       broot = (dli->dl_space_total -
8168 +               (dli->dl_space_total >> 10) * dli->dl_nrlmult)
8169 +               >> sb->s_blocksize_bits;
8170 +       bfree = (dli->dl_space_total - dli->dl_space_used)
8171 +                       >> sb->s_blocksize_bits;
8172 +       spin_unlock(&dli->dl_lock);
8173 +
8174 +       vxlprintk(VXD_CBIT(dlim, 2),
8175 +               "ADJUST: %lld,%lld on %lld,%lld [mult=%d]",
8176 +               (long long)bfree, (long long)broot,
8177 +               *free_blocks, *root_blocks, dli->dl_nrlmult,
8178 +               _file, _line);
8179 +       if (free_blocks) {
8180 +               if (*free_blocks > bfree)
8181 +                       *free_blocks = bfree;
8182 +       }
8183 +       if (root_blocks) {
8184 +               if (*root_blocks > broot)
8185 +                       *root_blocks = broot;
8186 +       }
8187 +       put_dl_info(dli);
8188 +}
8189 +
8190 +#define dl_prealloc_space(in, bytes) \
8191 +       __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
8192 +               __FILE__, __LINE__ )
8193 +
8194 +#define dl_alloc_space(in, bytes) \
8195 +       __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
8196 +               __FILE__, __LINE__ )
8197 +
8198 +#define dl_reserve_space(in, bytes) \
8199 +       __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
8200 +               __FILE__, __LINE__ )
8201 +
8202 +#define dl_claim_space(in, bytes) (0)
8203 +
8204 +#define dl_release_space(in, bytes) \
8205 +       __dl_free_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
8206 +               __FILE__, __LINE__ )
8207 +
8208 +#define dl_free_space(in, bytes) \
8209 +       __dl_free_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
8210 +               __FILE__, __LINE__ )
8211 +
8212 +
8213 +
8214 +#define dl_alloc_inode(in) \
8215 +       __dl_alloc_inode((in)->i_sb, i_tag_read(in), __FILE__, __LINE__ )
8216 +
8217 +#define dl_free_inode(in) \
8218 +       __dl_free_inode((in)->i_sb, i_tag_read(in), __FILE__, __LINE__ )
8219 +
8220 +
8221 +#define dl_adjust_block(sb, tag, fb, rb) \
8222 +       __dl_adjust_block(sb, tag, fb, rb, __FILE__, __LINE__ )
8223 +
8224 +
8225 +#else
8226 +#warning duplicate inclusion
8227 +#endif
8228 diff -NurpP --minimal linux-3.18.5/include/linux/vs_inet.h linux-3.18.5-vs2.3.7.3/include/linux/vs_inet.h
8229 --- linux-3.18.5/include/linux/vs_inet.h        1970-01-01 00:00:00.000000000 +0000
8230 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_inet.h      2015-01-19 10:58:04.000000000 +0000
8231 @@ -0,0 +1,364 @@
8232 +#ifndef _VS_INET_H
8233 +#define _VS_INET_H
8234 +
8235 +#include "vserver/base.h"
8236 +#include "vserver/network.h"
8237 +#include "vserver/debug.h"
8238 +
8239 +#define IPI_LOOPBACK   htonl(INADDR_LOOPBACK)
8240 +
8241 +#define NXAV4(a)       NIPQUAD((a)->ip[0]), NIPQUAD((a)->ip[1]), \
8242 +                       NIPQUAD((a)->mask), (a)->type
8243 +#define NXAV4_FMT      "[" NIPQUAD_FMT "-" NIPQUAD_FMT "/" NIPQUAD_FMT ":%04x]"
8244 +
8245 +#define NIPQUAD(addr) \
8246 +       ((unsigned char *)&addr)[0], \
8247 +       ((unsigned char *)&addr)[1], \
8248 +       ((unsigned char *)&addr)[2], \
8249 +       ((unsigned char *)&addr)[3]
8250 +
8251 +#define NIPQUAD_FMT "%u.%u.%u.%u"
8252 +
8253 +
8254 +static inline
8255 +int v4_addr_match(struct nx_addr_v4 *nxa, __be32 addr, uint16_t tmask)
8256 +{
8257 +       __be32 ip = nxa->ip[0].s_addr;
8258 +       __be32 mask = nxa->mask.s_addr;
8259 +       __be32 bcast = ip | ~mask;
8260 +       int ret = 0;
8261 +
8262 +       switch (nxa->type & tmask) {
8263 +       case NXA_TYPE_MASK:
8264 +               ret = (ip == (addr & mask));
8265 +               break;
8266 +       case NXA_TYPE_ADDR:
8267 +               ret = 3;
8268 +               if (addr == ip)
8269 +                       break;
8270 +               /* fall through to broadcast */
8271 +       case NXA_MOD_BCAST:
8272 +               ret = ((tmask & NXA_MOD_BCAST) && (addr == bcast));
8273 +               break;
8274 +       case NXA_TYPE_RANGE:
8275 +               ret = ((nxa->ip[0].s_addr <= addr) &&
8276 +                       (nxa->ip[1].s_addr > addr));
8277 +               break;
8278 +       case NXA_TYPE_ANY:
8279 +               ret = 2;
8280 +               break;
8281 +       }
8282 +
8283 +       vxdprintk(VXD_CBIT(net, 0),
8284 +               "v4_addr_match(%p" NXAV4_FMT "," NIPQUAD_FMT ",%04x) = %d",
8285 +               nxa, NXAV4(nxa), NIPQUAD(addr), tmask, ret);
8286 +       return ret;
8287 +}
8288 +
8289 +static inline
8290 +int v4_addr_in_nx_info(struct nx_info *nxi, __be32 addr, uint16_t tmask)
8291 +{
8292 +       struct nx_addr_v4 *nxa;
8293 +       unsigned long irqflags;
8294 +       int ret = 1;
8295 +
8296 +       if (!nxi)
8297 +               goto out;
8298 +
8299 +       ret = 2;
8300 +       /* allow 127.0.0.1 when remapping lback */
8301 +       if ((tmask & NXA_LOOPBACK) &&
8302 +               (addr == IPI_LOOPBACK) &&
8303 +               nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
8304 +               goto out;
8305 +       ret = 3;
8306 +       /* check for lback address */
8307 +       if ((tmask & NXA_MOD_LBACK) &&
8308 +               (nxi->v4_lback.s_addr == addr))
8309 +               goto out;
8310 +       ret = 4;
8311 +       /* check for broadcast address */
8312 +       if ((tmask & NXA_MOD_BCAST) &&
8313 +               (nxi->v4_bcast.s_addr == addr))
8314 +               goto out;
8315 +       ret = 5;
8316 +
8317 +       /* check for v4 addresses */
8318 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
8319 +       for (nxa = &nxi->v4; nxa; nxa = nxa->next)
8320 +               if (v4_addr_match(nxa, addr, tmask))
8321 +                       goto out_unlock;
8322 +       ret = 0;
8323 +out_unlock:
8324 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
8325 +out:
8326 +       vxdprintk(VXD_CBIT(net, 0),
8327 +               "v4_addr_in_nx_info(%p[#%u]," NIPQUAD_FMT ",%04x) = %d",
8328 +               nxi, nxi ? nxi->nx_id : 0, NIPQUAD(addr), tmask, ret);
8329 +       return ret;
8330 +}
8331 +
8332 +static inline
8333 +int v4_nx_addr_match(struct nx_addr_v4 *nxa, struct nx_addr_v4 *addr, uint16_t mask)
8334 +{
8335 +       /* FIXME: needs full range checks */
8336 +       return v4_addr_match(nxa, addr->ip[0].s_addr, mask);
8337 +}
8338 +
8339 +static inline
8340 +int v4_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v4 *nxa, uint16_t mask)
8341 +{
8342 +       struct nx_addr_v4 *ptr;
8343 +       unsigned long irqflags;
8344 +       int ret = 1;
8345 +
8346 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
8347 +       for (ptr = &nxi->v4; ptr; ptr = ptr->next)
8348 +               if (v4_nx_addr_match(ptr, nxa, mask))
8349 +                       goto out_unlock;
8350 +       ret = 0;
8351 +out_unlock:
8352 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
8353 +       return ret;
8354 +}
8355 +
8356 +#include <net/inet_sock.h>
8357 +
8358 +/*
8359 + *     Check if a given address matches for a socket
8360 + *
8361 + *     nxi:            the socket's nx_info if any
8362 + *     addr:           to be verified address
8363 + */
8364 +static inline
8365 +int v4_sock_addr_match (
8366 +       struct nx_info *nxi,
8367 +       struct inet_sock *inet,
8368 +       __be32 addr)
8369 +{
8370 +       __be32 saddr = inet->inet_rcv_saddr;
8371 +       __be32 bcast = nxi ? nxi->v4_bcast.s_addr : INADDR_BROADCAST;
8372 +
8373 +       if (addr && (saddr == addr || bcast == addr))
8374 +               return 1;
8375 +       if (!saddr)
8376 +               return v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND);
8377 +       return 0;
8378 +}
8379 +
8380 +
8381 +/* inet related checks and helpers */
8382 +
8383 +
8384 +struct in_ifaddr;
8385 +struct net_device;
8386 +struct sock;
8387 +
8388 +#ifdef CONFIG_INET
8389 +
8390 +#include <linux/netdevice.h>
8391 +#include <linux/inetdevice.h>
8392 +#include <net/inet_sock.h>
8393 +#include <net/inet_timewait_sock.h>
8394 +
8395 +
8396 +int dev_in_nx_info(struct net_device *, struct nx_info *);
8397 +int v4_dev_in_nx_info(struct net_device *, struct nx_info *);
8398 +int nx_v4_addr_conflict(struct nx_info *, struct nx_info *);
8399 +
8400 +
8401 +/*
8402 + *     check if address is covered by socket
8403 + *
8404 + *     sk:     the socket to check against
8405 + *     addr:   the address in question (must be != 0)
8406 + */
8407 +
8408 +static inline
8409 +int __v4_addr_match_socket(const struct sock *sk, struct nx_addr_v4 *nxa)
8410 +{
8411 +       struct nx_info *nxi = sk->sk_nx_info;
8412 +       __be32 saddr = sk->sk_rcv_saddr;
8413 +
8414 +       vxdprintk(VXD_CBIT(net, 5),
8415 +               "__v4_addr_in_socket(%p," NXAV4_FMT ") %p:" NIPQUAD_FMT " %p;%lx",
8416 +               sk, NXAV4(nxa), nxi, NIPQUAD(saddr), sk->sk_socket,
8417 +               (sk->sk_socket?sk->sk_socket->flags:0));
8418 +
8419 +       if (saddr) {            /* direct address match */
8420 +               return v4_addr_match(nxa, saddr, -1);
8421 +       } else if (nxi) {       /* match against nx_info */
8422 +               return v4_nx_addr_in_nx_info(nxi, nxa, -1);
8423 +       } else {                /* unrestricted any socket */
8424 +               return 1;
8425 +       }
8426 +}
8427 +
8428 +
8429 +
8430 +static inline
8431 +int nx_dev_visible(struct nx_info *nxi, struct net_device *dev)
8432 +{
8433 +       vxdprintk(VXD_CBIT(net, 1),
8434 +               "nx_dev_visible(%p[#%u],%p " VS_Q("%s") ") %d",
8435 +               nxi, nxi ? nxi->nx_id : 0, dev, dev->name,
8436 +               nxi ? dev_in_nx_info(dev, nxi) : 0);
8437 +
8438 +       if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8439 +               return 1;
8440 +       if (dev_in_nx_info(dev, nxi))
8441 +               return 1;
8442 +       return 0;
8443 +}
8444 +
8445 +
8446 +static inline
8447 +int v4_ifa_in_nx_info(struct in_ifaddr *ifa, struct nx_info *nxi)
8448 +{
8449 +       if (!nxi)
8450 +               return 1;
8451 +       if (!ifa)
8452 +               return 0;
8453 +       return v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW);
8454 +}
8455 +
8456 +static inline
8457 +int nx_v4_ifa_visible(struct nx_info *nxi, struct in_ifaddr *ifa)
8458 +{
8459 +       vxdprintk(VXD_CBIT(net, 1), "nx_v4_ifa_visible(%p[#%u],%p) %d",
8460 +               nxi, nxi ? nxi->nx_id : 0, ifa,
8461 +               nxi ? v4_ifa_in_nx_info(ifa, nxi) : 0);
8462 +
8463 +       if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8464 +               return 1;
8465 +       if (v4_ifa_in_nx_info(ifa, nxi))
8466 +               return 1;
8467 +       return 0;
8468 +}
8469 +
8470 +
8471 +struct nx_v4_sock_addr {
8472 +       __be32 saddr;   /* Address used for validation */
8473 +       __be32 baddr;   /* Address used for socket bind */
8474 +};
8475 +
8476 +static inline
8477 +int v4_map_sock_addr(struct inet_sock *inet, struct sockaddr_in *addr,
8478 +       struct nx_v4_sock_addr *nsa)
8479 +{
8480 +       struct sock *sk = &inet->sk;
8481 +       struct nx_info *nxi = sk->sk_nx_info;
8482 +       __be32 saddr = addr->sin_addr.s_addr;
8483 +       __be32 baddr = saddr;
8484 +
8485 +       vxdprintk(VXD_CBIT(net, 3),
8486 +               "inet_bind(%p)* %p,%p;%lx " NIPQUAD_FMT,
8487 +               sk, sk->sk_nx_info, sk->sk_socket,
8488 +               (sk->sk_socket ? sk->sk_socket->flags : 0),
8489 +               NIPQUAD(saddr));
8490 +
8491 +       if (nxi) {
8492 +               if (saddr == INADDR_ANY) {
8493 +                       if (nx_info_flags(nxi, NXF_SINGLE_IP, 0))
8494 +                               baddr = nxi->v4.ip[0].s_addr;
8495 +               } else if (saddr == IPI_LOOPBACK) {
8496 +                       if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
8497 +                               baddr = nxi->v4_lback.s_addr;
8498 +               } else if (!ipv4_is_multicast(saddr) ||
8499 +                       !nx_info_ncaps(nxi, NXC_MULTICAST)) {
8500 +                       /* normal address bind */
8501 +                       if (!v4_addr_in_nx_info(nxi, saddr, NXA_MASK_BIND))
8502 +                               return -EADDRNOTAVAIL;
8503 +               }
8504 +       }
8505 +
8506 +       vxdprintk(VXD_CBIT(net, 3),
8507 +               "inet_bind(%p) " NIPQUAD_FMT ", " NIPQUAD_FMT,
8508 +               sk, NIPQUAD(saddr), NIPQUAD(baddr));
8509 +
8510 +       nsa->saddr = saddr;
8511 +       nsa->baddr = baddr;
8512 +       return 0;
8513 +}
8514 +
8515 +static inline
8516 +void v4_set_sock_addr(struct inet_sock *inet, struct nx_v4_sock_addr *nsa)
8517 +{
8518 +       inet->inet_saddr = nsa->baddr;
8519 +       inet->inet_rcv_saddr = nsa->baddr;
8520 +}
8521 +
8522 +
8523 +/*
8524 + *      helper to simplify inet_lookup_listener
8525 + *
8526 + *      nxi:   the socket's nx_info if any
8527 + *      addr:  to be verified address
8528 + *      saddr: socket address
8529 + */
8530 +static inline int v4_inet_addr_match (
8531 +       struct nx_info *nxi,
8532 +       __be32 addr,
8533 +       __be32 saddr)
8534 +{
8535 +       if (addr && (saddr == addr))
8536 +               return 1;
8537 +       if (!saddr)
8538 +               return nxi ? v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND) : 1;
8539 +       return 0;
8540 +}
8541 +
8542 +static inline __be32 nx_map_sock_lback(struct nx_info *nxi, __be32 addr)
8543 +{
8544 +       if (nx_info_flags(nxi, NXF_HIDE_LBACK, 0) &&
8545 +               (addr == nxi->v4_lback.s_addr))
8546 +               return IPI_LOOPBACK;
8547 +       return addr;
8548 +}
8549 +
8550 +static inline
8551 +int nx_info_has_v4(struct nx_info *nxi)
8552 +{
8553 +       if (!nxi)
8554 +               return 1;
8555 +       if (NX_IPV4(nxi))
8556 +               return 1;
8557 +       if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
8558 +               return 1;
8559 +       return 0;
8560 +}
8561 +
8562 +#else /* CONFIG_INET */
8563 +
8564 +static inline
8565 +int nx_dev_visible(struct nx_info *n, struct net_device *d)
8566 +{
8567 +       return 1;
8568 +}
8569 +
8570 +static inline
8571 +int nx_v4_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
8572 +{
8573 +       return 1;
8574 +}
8575 +
8576 +static inline
8577 +int v4_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
8578 +{
8579 +       return 1;
8580 +}
8581 +
8582 +static inline
8583 +int nx_info_has_v4(struct nx_info *nxi)
8584 +{
8585 +       return 0;
8586 +}
8587 +
8588 +#endif /* CONFIG_INET */
8589 +
8590 +#define current_nx_info_has_v4() \
8591 +       nx_info_has_v4(current_nx_info())
8592 +
8593 +#else
8594 +// #warning duplicate inclusion
8595 +#endif
8596 diff -NurpP --minimal linux-3.18.5/include/linux/vs_inet6.h linux-3.18.5-vs2.3.7.3/include/linux/vs_inet6.h
8597 --- linux-3.18.5/include/linux/vs_inet6.h       1970-01-01 00:00:00.000000000 +0000
8598 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_inet6.h     2015-01-19 10:58:04.000000000 +0000
8599 @@ -0,0 +1,257 @@
8600 +#ifndef _VS_INET6_H
8601 +#define _VS_INET6_H
8602 +
8603 +#include "vserver/base.h"
8604 +#include "vserver/network.h"
8605 +#include "vserver/debug.h"
8606 +
8607 +#include <net/ipv6.h>
8608 +
8609 +#define NXAV6(a)       &(a)->ip, &(a)->mask, (a)->prefix, (a)->type
8610 +#define NXAV6_FMT      "[%pI6/%pI6/%d:%04x]"
8611 +
8612 +
8613 +#ifdef CONFIG_IPV6
8614 +
8615 +static inline
8616 +int v6_addr_match(struct nx_addr_v6 *nxa,
8617 +       const struct in6_addr *addr, uint16_t mask)
8618 +{
8619 +       int ret = 0;
8620 +
8621 +       switch (nxa->type & mask) {
8622 +       case NXA_TYPE_MASK:
8623 +               ret = ipv6_masked_addr_cmp(&nxa->ip, &nxa->mask, addr);
8624 +               break;
8625 +       case NXA_TYPE_ADDR:
8626 +               ret = ipv6_addr_equal(&nxa->ip, addr);
8627 +               break;
8628 +       case NXA_TYPE_ANY:
8629 +               ret = 1;
8630 +               break;
8631 +       }
8632 +       vxdprintk(VXD_CBIT(net, 0),
8633 +               "v6_addr_match(%p" NXAV6_FMT ",%pI6,%04x) = %d",
8634 +               nxa, NXAV6(nxa), addr, mask, ret);
8635 +       return ret;
8636 +}
8637 +
8638 +static inline
8639 +int v6_addr_in_nx_info(struct nx_info *nxi,
8640 +       const struct in6_addr *addr, uint16_t mask)
8641 +{
8642 +       struct nx_addr_v6 *nxa;
8643 +       unsigned long irqflags;
8644 +       int ret = 1;
8645 +
8646 +       if (!nxi)
8647 +               goto out;
8648 +
8649 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
8650 +       for (nxa = &nxi->v6; nxa; nxa = nxa->next)
8651 +               if (v6_addr_match(nxa, addr, mask))
8652 +                       goto out_unlock;
8653 +       ret = 0;
8654 +out_unlock:
8655 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
8656 +out:
8657 +       vxdprintk(VXD_CBIT(net, 0),
8658 +               "v6_addr_in_nx_info(%p[#%u],%pI6,%04x) = %d",
8659 +               nxi, nxi ? nxi->nx_id : 0, addr, mask, ret);
8660 +       return ret;
8661 +}
8662 +
8663 +static inline
8664 +int v6_nx_addr_match(struct nx_addr_v6 *nxa, struct nx_addr_v6 *addr, uint16_t mask)
8665 +{
8666 +       /* FIXME: needs full range checks */
8667 +       return v6_addr_match(nxa, &addr->ip, mask);
8668 +}
8669 +
8670 +static inline
8671 +int v6_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v6 *nxa, uint16_t mask)
8672 +{
8673 +       struct nx_addr_v6 *ptr;
8674 +       unsigned long irqflags;
8675 +       int ret = 1;
8676 +
8677 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
8678 +       for (ptr = &nxi->v6; ptr; ptr = ptr->next)
8679 +               if (v6_nx_addr_match(ptr, nxa, mask))
8680 +                       goto out_unlock;
8681 +       ret = 0;
8682 +out_unlock:
8683 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
8684 +       return ret;
8685 +}
8686 +
8687 +
8688 +/*
8689 + *     Check if a given address matches for a socket
8690 + *
8691 + *     nxi:            the socket's nx_info if any
8692 + *     addr:           to be verified address
8693 + */
8694 +static inline
8695 +int v6_sock_addr_match (
8696 +       struct nx_info *nxi,
8697 +       struct inet_sock *inet,
8698 +       struct in6_addr *addr)
8699 +{
8700 +       struct sock *sk = &inet->sk;
8701 +       const struct in6_addr *saddr = inet6_rcv_saddr(sk);
8702 +
8703 +       if (!ipv6_addr_any(addr) &&
8704 +               ipv6_addr_equal(saddr, addr))
8705 +               return 1;
8706 +       if (ipv6_addr_any(saddr))
8707 +               return v6_addr_in_nx_info(nxi, addr, -1);
8708 +       return 0;
8709 +}
8710 +
8711 +/*
8712 + *     check if address is covered by socket
8713 + *
8714 + *     sk:     the socket to check against
8715 + *     addr:   the address in question (must be != 0)
8716 + */
8717 +
8718 +static inline
8719 +int __v6_addr_match_socket(const struct sock *sk, struct nx_addr_v6 *nxa)
8720 +{
8721 +       struct nx_info *nxi = sk->sk_nx_info;
8722 +       const struct in6_addr *saddr = inet6_rcv_saddr(sk);
8723 +
8724 +       vxdprintk(VXD_CBIT(net, 5),
8725 +               "__v6_addr_in_socket(%p," NXAV6_FMT ") %p:%pI6 %p;%lx",
8726 +               sk, NXAV6(nxa), nxi, saddr, sk->sk_socket,
8727 +               (sk->sk_socket?sk->sk_socket->flags:0));
8728 +
8729 +       if (!ipv6_addr_any(saddr)) {    /* direct address match */
8730 +               return v6_addr_match(nxa, saddr, -1);
8731 +       } else if (nxi) {               /* match against nx_info */
8732 +               return v6_nx_addr_in_nx_info(nxi, nxa, -1);
8733 +       } else {                        /* unrestricted any socket */
8734 +               return 1;
8735 +       }
8736 +}
8737 +
8738 +
8739 +/* inet related checks and helpers */
8740 +
8741 +
8742 +struct in_ifaddr;
8743 +struct net_device;
8744 +struct sock;
8745 +
8746 +
8747 +#include <linux/netdevice.h>
8748 +#include <linux/inetdevice.h>
8749 +#include <net/inet_timewait_sock.h>
8750 +
8751 +
8752 +int dev_in_nx_info(struct net_device *, struct nx_info *);
8753 +int v6_dev_in_nx_info(struct net_device *, struct nx_info *);
8754 +int nx_v6_addr_conflict(struct nx_info *, struct nx_info *);
8755 +
8756 +
8757 +
8758 +static inline
8759 +int v6_ifa_in_nx_info(struct inet6_ifaddr *ifa, struct nx_info *nxi)
8760 +{
8761 +       if (!nxi)
8762 +               return 1;
8763 +       if (!ifa)
8764 +               return 0;
8765 +       return v6_addr_in_nx_info(nxi, &ifa->addr, -1);
8766 +}
8767 +
8768 +static inline
8769 +int nx_v6_ifa_visible(struct nx_info *nxi, struct inet6_ifaddr *ifa)
8770 +{
8771 +       vxdprintk(VXD_CBIT(net, 1), "nx_v6_ifa_visible(%p[#%u],%p) %d",
8772 +               nxi, nxi ? nxi->nx_id : 0, ifa,
8773 +               nxi ? v6_ifa_in_nx_info(ifa, nxi) : 0);
8774 +
8775 +       if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8776 +               return 1;
8777 +       if (v6_ifa_in_nx_info(ifa, nxi))
8778 +               return 1;
8779 +       return 0;
8780 +}
8781 +
8782 +
8783 +struct nx_v6_sock_addr {
8784 +       struct in6_addr saddr;  /* Address used for validation */
8785 +       struct in6_addr baddr;  /* Address used for socket bind */
8786 +};
8787 +
8788 +static inline
8789 +int v6_map_sock_addr(struct inet_sock *inet, struct sockaddr_in6 *addr,
8790 +       struct nx_v6_sock_addr *nsa)
8791 +{
8792 +       // struct sock *sk = &inet->sk;
8793 +       // struct nx_info *nxi = sk->sk_nx_info;
8794 +       struct in6_addr saddr = addr->sin6_addr;
8795 +       struct in6_addr baddr = saddr;
8796 +
8797 +       nsa->saddr = saddr;
8798 +       nsa->baddr = baddr;
8799 +       return 0;
8800 +}
8801 +
8802 +static inline
8803 +void v6_set_sock_addr(struct inet_sock *inet, struct nx_v6_sock_addr *nsa)
8804 +{
8805 +       // struct sock *sk = &inet->sk;
8806 +       // struct in6_addr *saddr = inet6_rcv_saddr(sk);
8807 +
8808 +       // *saddr = nsa->baddr;
8809 +       // inet->inet_saddr = nsa->baddr;
8810 +}
8811 +
8812 +static inline
8813 +int nx_info_has_v6(struct nx_info *nxi)
8814 +{
8815 +       if (!nxi)
8816 +               return 1;
8817 +       if (NX_IPV6(nxi))
8818 +               return 1;
8819 +       return 0;
8820 +}
8821 +
8822 +#else /* CONFIG_IPV6 */
8823 +
8824 +static inline
8825 +int nx_v6_dev_visible(struct nx_info *n, struct net_device *d)
8826 +{
8827 +       return 1;
8828 +}
8829 +
8830 +
8831 +static inline
8832 +int nx_v6_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
8833 +{
8834 +       return 1;
8835 +}
8836 +
8837 +static inline
8838 +int v6_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
8839 +{
8840 +       return 1;
8841 +}
8842 +
8843 +static inline
8844 +int nx_info_has_v6(struct nx_info *nxi)
8845 +{
8846 +       return 0;
8847 +}
8848 +
8849 +#endif /* CONFIG_IPV6 */
8850 +
8851 +#define current_nx_info_has_v6() \
8852 +       nx_info_has_v6(current_nx_info())
8853 +
8854 +#else
8855 +#warning duplicate inclusion
8856 +#endif
8857 diff -NurpP --minimal linux-3.18.5/include/linux/vs_limit.h linux-3.18.5-vs2.3.7.3/include/linux/vs_limit.h
8858 --- linux-3.18.5/include/linux/vs_limit.h       1970-01-01 00:00:00.000000000 +0000
8859 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_limit.h     2015-01-19 10:58:04.000000000 +0000
8860 @@ -0,0 +1,140 @@
8861 +#ifndef _VS_LIMIT_H
8862 +#define _VS_LIMIT_H
8863 +
8864 +#include "vserver/limit.h"
8865 +#include "vserver/base.h"
8866 +#include "vserver/context.h"
8867 +#include "vserver/debug.h"
8868 +#include "vserver/context.h"
8869 +#include "vserver/limit_int.h"
8870 +
8871 +
8872 +#define vx_acc_cres(v, d, p, r) \
8873 +       __vx_acc_cres(v, r, d, p, __FILE__, __LINE__)
8874 +
8875 +#define vx_acc_cres_cond(x, d, p, r) \
8876 +       __vx_acc_cres(((x) == vx_current_xid()) ? current_vx_info() : 0, \
8877 +       r, d, p, __FILE__, __LINE__)
8878 +
8879 +
8880 +#define vx_add_cres(v, a, p, r) \
8881 +       __vx_add_cres(v, r, a, p, __FILE__, __LINE__)
8882 +#define vx_sub_cres(v, a, p, r)                vx_add_cres(v, -(a), p, r)
8883 +
8884 +#define vx_add_cres_cond(x, a, p, r) \
8885 +       __vx_add_cres(((x) == vx_current_xid()) ? current_vx_info() : 0, \
8886 +       r, a, p, __FILE__, __LINE__)
8887 +#define vx_sub_cres_cond(x, a, p, r)   vx_add_cres_cond(x, -(a), p, r)
8888 +
8889 +
8890 +/* process and file limits */
8891 +
8892 +#define vx_nproc_inc(p) \
8893 +       vx_acc_cres((p)->vx_info, 1, p, RLIMIT_NPROC)
8894 +
8895 +#define vx_nproc_dec(p) \
8896 +       vx_acc_cres((p)->vx_info,-1, p, RLIMIT_NPROC)
8897 +
8898 +#define vx_files_inc(f) \
8899 +       vx_acc_cres_cond((f)->f_xid, 1, f, RLIMIT_NOFILE)
8900 +
8901 +#define vx_files_dec(f) \
8902 +       vx_acc_cres_cond((f)->f_xid,-1, f, RLIMIT_NOFILE)
8903 +
8904 +#define vx_locks_inc(l) \
8905 +       vx_acc_cres_cond((l)->fl_xid, 1, l, RLIMIT_LOCKS)
8906 +
8907 +#define vx_locks_dec(l) \
8908 +       vx_acc_cres_cond((l)->fl_xid,-1, l, RLIMIT_LOCKS)
8909 +
8910 +#define vx_openfd_inc(f) \
8911 +       vx_acc_cres(current_vx_info(), 1, (void *)(long)(f), VLIMIT_OPENFD)
8912 +
8913 +#define vx_openfd_dec(f) \
8914 +       vx_acc_cres(current_vx_info(),-1, (void *)(long)(f), VLIMIT_OPENFD)
8915 +
8916 +
8917 +#define vx_cres_avail(v, n, r) \
8918 +       __vx_cres_avail(v, r, n, __FILE__, __LINE__)
8919 +
8920 +
8921 +#define vx_nproc_avail(n) \
8922 +       vx_cres_avail(current_vx_info(), n, RLIMIT_NPROC)
8923 +
8924 +#define vx_files_avail(n) \
8925 +       vx_cres_avail(current_vx_info(), n, RLIMIT_NOFILE)
8926 +
8927 +#define vx_locks_avail(n) \
8928 +       vx_cres_avail(current_vx_info(), n, RLIMIT_LOCKS)
8929 +
8930 +#define vx_openfd_avail(n) \
8931 +       vx_cres_avail(current_vx_info(), n, VLIMIT_OPENFD)
8932 +
8933 +
8934 +/* dentry limits */
8935 +
8936 +#define vx_dentry_inc(d) do {                                          \
8937 +       if (d_count(d) == 1)                                            \
8938 +               vx_acc_cres(current_vx_info(), 1, d, VLIMIT_DENTRY);    \
8939 +       } while (0)
8940 +
8941 +#define vx_dentry_dec(d) do {                                          \
8942 +       if (d_count(d) == 0)                                            \
8943 +               vx_acc_cres(current_vx_info(),-1, d, VLIMIT_DENTRY);    \
8944 +       } while (0)
8945 +
8946 +#define vx_dentry_avail(n) \
8947 +       vx_cres_avail(current_vx_info(), n, VLIMIT_DENTRY)
8948 +
8949 +
8950 +/* socket limits */
8951 +
8952 +#define vx_sock_inc(s) \
8953 +       vx_acc_cres((s)->sk_vx_info, 1, s, VLIMIT_NSOCK)
8954 +
8955 +#define vx_sock_dec(s) \
8956 +       vx_acc_cres((s)->sk_vx_info,-1, s, VLIMIT_NSOCK)
8957 +
8958 +#define vx_sock_avail(n) \
8959 +       vx_cres_avail(current_vx_info(), n, VLIMIT_NSOCK)
8960 +
8961 +
8962 +/* ipc resource limits */
8963 +
8964 +#define vx_ipcmsg_add(v, u, a) \
8965 +       vx_add_cres(v, a, u, RLIMIT_MSGQUEUE)
8966 +
8967 +#define vx_ipcmsg_sub(v, u, a) \
8968 +       vx_sub_cres(v, a, u, RLIMIT_MSGQUEUE)
8969 +
8970 +#define vx_ipcmsg_avail(v, a) \
8971 +       vx_cres_avail(v, a, RLIMIT_MSGQUEUE)
8972 +
8973 +
8974 +#define vx_ipcshm_add(v, k, a) \
8975 +       vx_add_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
8976 +
8977 +#define vx_ipcshm_sub(v, k, a) \
8978 +       vx_sub_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
8979 +
8980 +#define vx_ipcshm_avail(v, a) \
8981 +       vx_cres_avail(v, a, VLIMIT_SHMEM)
8982 +
8983 +
8984 +#define vx_semary_inc(a) \
8985 +       vx_acc_cres(current_vx_info(), 1, a, VLIMIT_SEMARY)
8986 +
8987 +#define vx_semary_dec(a) \
8988 +       vx_acc_cres(current_vx_info(), -1, a, VLIMIT_SEMARY)
8989 +
8990 +
8991 +#define vx_nsems_add(a,n) \
8992 +       vx_add_cres(current_vx_info(), n, a, VLIMIT_NSEMS)
8993 +
8994 +#define vx_nsems_sub(a,n) \
8995 +       vx_sub_cres(current_vx_info(), n, a, VLIMIT_NSEMS)
8996 +
8997 +
8998 +#else
8999 +#warning duplicate inclusion
9000 +#endif
9001 diff -NurpP --minimal linux-3.18.5/include/linux/vs_network.h linux-3.18.5-vs2.3.7.3/include/linux/vs_network.h
9002 --- linux-3.18.5/include/linux/vs_network.h     1970-01-01 00:00:00.000000000 +0000
9003 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_network.h   2015-01-19 10:58:04.000000000 +0000
9004 @@ -0,0 +1,169 @@
9005 +#ifndef _NX_VS_NETWORK_H
9006 +#define _NX_VS_NETWORK_H
9007 +
9008 +#include "vserver/context.h"
9009 +#include "vserver/network.h"
9010 +#include "vserver/base.h"
9011 +#include "vserver/check.h"
9012 +#include "vserver/debug.h"
9013 +
9014 +#include <linux/sched.h>
9015 +
9016 +
9017 +#define get_nx_info(i) __get_nx_info(i, __FILE__, __LINE__)
9018 +
9019 +static inline struct nx_info *__get_nx_info(struct nx_info *nxi,
9020 +       const char *_file, int _line)
9021 +{
9022 +       if (!nxi)
9023 +               return NULL;
9024 +
9025 +       vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])",
9026 +               nxi, nxi ? nxi->nx_id : 0,
9027 +               nxi ? atomic_read(&nxi->nx_usecnt) : 0,
9028 +               _file, _line);
9029 +
9030 +       atomic_inc(&nxi->nx_usecnt);
9031 +       return nxi;
9032 +}
9033 +
9034 +
9035 +extern void free_nx_info(struct nx_info *);
9036 +
9037 +#define put_nx_info(i) __put_nx_info(i, __FILE__, __LINE__)
9038 +
9039 +static inline void __put_nx_info(struct nx_info *nxi, const char *_file, int _line)
9040 +{
9041 +       if (!nxi)
9042 +               return;
9043 +
9044 +       vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])",
9045 +               nxi, nxi ? nxi->nx_id : 0,
9046 +               nxi ? atomic_read(&nxi->nx_usecnt) : 0,
9047 +               _file, _line);
9048 +
9049 +       if (atomic_dec_and_test(&nxi->nx_usecnt))
9050 +               free_nx_info(nxi);
9051 +}
9052 +
9053 +
9054 +#define init_nx_info(p, i) __init_nx_info(p, i, __FILE__, __LINE__)
9055 +
9056 +static inline void __init_nx_info(struct nx_info **nxp, struct nx_info *nxi,
9057 +               const char *_file, int _line)
9058 +{
9059 +       if (nxi) {
9060 +               vxlprintk(VXD_CBIT(nid, 3),
9061 +                       "init_nx_info(%p[#%d.%d])",
9062 +                       nxi, nxi ? nxi->nx_id : 0,
9063 +                       nxi ? atomic_read(&nxi->nx_usecnt) : 0,
9064 +                       _file, _line);
9065 +
9066 +               atomic_inc(&nxi->nx_usecnt);
9067 +       }
9068 +       *nxp = nxi;
9069 +}
9070 +
9071 +
9072 +#define set_nx_info(p, i) __set_nx_info(p, i, __FILE__, __LINE__)
9073 +
9074 +static inline void __set_nx_info(struct nx_info **nxp, struct nx_info *nxi,
9075 +       const char *_file, int _line)
9076 +{
9077 +       struct nx_info *nxo;
9078 +
9079 +       if (!nxi)
9080 +               return;
9081 +
9082 +       vxlprintk(VXD_CBIT(nid, 3), "set_nx_info(%p[#%d.%d])",
9083 +               nxi, nxi ? nxi->nx_id : 0,
9084 +               nxi ? atomic_read(&nxi->nx_usecnt) : 0,
9085 +               _file, _line);
9086 +
9087 +       atomic_inc(&nxi->nx_usecnt);
9088 +       nxo = xchg(nxp, nxi);
9089 +       BUG_ON(nxo);
9090 +}
9091 +
9092 +#define clr_nx_info(p) __clr_nx_info(p, __FILE__, __LINE__)
9093 +
9094 +static inline void __clr_nx_info(struct nx_info **nxp,
9095 +       const char *_file, int _line)
9096 +{
9097 +       struct nx_info *nxo;
9098 +
9099 +       nxo = xchg(nxp, NULL);
9100 +       if (!nxo)
9101 +               return;
9102 +
9103 +       vxlprintk(VXD_CBIT(nid, 3), "clr_nx_info(%p[#%d.%d])",
9104 +               nxo, nxo ? nxo->nx_id : 0,
9105 +               nxo ? atomic_read(&nxo->nx_usecnt) : 0,
9106 +               _file, _line);
9107 +
9108 +       if (atomic_dec_and_test(&nxo->nx_usecnt))
9109 +               free_nx_info(nxo);
9110 +}
9111 +
9112 +
9113 +#define claim_nx_info(v, p) __claim_nx_info(v, p, __FILE__, __LINE__)
9114 +
9115 +static inline void __claim_nx_info(struct nx_info *nxi,
9116 +       struct task_struct *task, const char *_file, int _line)
9117 +{
9118 +       vxlprintk(VXD_CBIT(nid, 3), "claim_nx_info(%p[#%d.%d.%d]) %p",
9119 +               nxi, nxi ? nxi->nx_id : 0,
9120 +               nxi?atomic_read(&nxi->nx_usecnt):0,
9121 +               nxi?atomic_read(&nxi->nx_tasks):0,
9122 +               task, _file, _line);
9123 +
9124 +       atomic_inc(&nxi->nx_tasks);
9125 +}
9126 +
9127 +
9128 +extern void unhash_nx_info(struct nx_info *);
9129 +
9130 +#define release_nx_info(v, p) __release_nx_info(v, p, __FILE__, __LINE__)
9131 +
9132 +static inline void __release_nx_info(struct nx_info *nxi,
9133 +       struct task_struct *task, const char *_file, int _line)
9134 +{
9135 +       vxlprintk(VXD_CBIT(nid, 3), "release_nx_info(%p[#%d.%d.%d]) %p",
9136 +               nxi, nxi ? nxi->nx_id : 0,
9137 +               nxi ? atomic_read(&nxi->nx_usecnt) : 0,
9138 +               nxi ? atomic_read(&nxi->nx_tasks) : 0,
9139 +               task, _file, _line);
9140 +
9141 +       might_sleep();
9142 +
9143 +       if (atomic_dec_and_test(&nxi->nx_tasks))
9144 +               unhash_nx_info(nxi);
9145 +}
9146 +
9147 +
9148 +#define task_get_nx_info(i)    __task_get_nx_info(i, __FILE__, __LINE__)
9149 +
9150 +static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p,
9151 +       const char *_file, int _line)
9152 +{
9153 +       struct nx_info *nxi;
9154 +
9155 +       task_lock(p);
9156 +       vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)",
9157 +               p, _file, _line);
9158 +       nxi = __get_nx_info(p->nx_info, _file, _line);
9159 +       task_unlock(p);
9160 +       return nxi;
9161 +}
9162 +
9163 +
9164 +static inline void exit_nx_info(struct task_struct *p)
9165 +{
9166 +       if (p->nx_info)
9167 +               release_nx_info(p->nx_info, p);
9168 +}
9169 +
9170 +
9171 +#else
9172 +#warning duplicate inclusion
9173 +#endif
9174 diff -NurpP --minimal linux-3.18.5/include/linux/vs_pid.h linux-3.18.5-vs2.3.7.3/include/linux/vs_pid.h
9175 --- linux-3.18.5/include/linux/vs_pid.h 1970-01-01 00:00:00.000000000 +0000
9176 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_pid.h       2015-01-19 10:58:04.000000000 +0000
9177 @@ -0,0 +1,50 @@
9178 +#ifndef _VS_PID_H
9179 +#define _VS_PID_H
9180 +
9181 +#include "vserver/base.h"
9182 +#include "vserver/check.h"
9183 +#include "vserver/context.h"
9184 +#include "vserver/debug.h"
9185 +#include "vserver/pid.h"
9186 +#include <linux/pid_namespace.h>
9187 +
9188 +
9189 +#define VXF_FAKE_INIT  (VXF_INFO_INIT | VXF_STATE_INIT)
9190 +
9191 +static inline
9192 +int vx_proc_task_visible(struct task_struct *task)
9193 +{
9194 +       if ((task->pid == 1) &&
9195 +               !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT))
9196 +               /* show a blend through init */
9197 +               goto visible;
9198 +       if (vx_check(vx_task_xid(task), VS_WATCH | VS_IDENT))
9199 +               goto visible;
9200 +       return 0;
9201 +visible:
9202 +       return 1;
9203 +}
9204 +
9205 +#define find_task_by_real_pid(pid) find_task_by_pid_ns(pid, &init_pid_ns)
9206 +
9207 +
9208 +static inline
9209 +struct task_struct *vx_get_proc_task(struct inode *inode, struct pid *pid)
9210 +{
9211 +       struct task_struct *task = get_pid_task(pid, PIDTYPE_PID);
9212 +
9213 +       if (task && !vx_proc_task_visible(task)) {
9214 +               vxdprintk(VXD_CBIT(misc, 6),
9215 +                       "dropping task (get) %p[#%u,%u] for %p[#%u,%u]",
9216 +                       task, task->xid, task->pid,
9217 +                       current, current->xid, current->pid);
9218 +               put_task_struct(task);
9219 +               task = NULL;
9220 +       }
9221 +       return task;
9222 +}
9223 +
9224 +
9225 +#else
9226 +#warning duplicate inclusion
9227 +#endif
9228 diff -NurpP --minimal linux-3.18.5/include/linux/vs_sched.h linux-3.18.5-vs2.3.7.3/include/linux/vs_sched.h
9229 --- linux-3.18.5/include/linux/vs_sched.h       1970-01-01 00:00:00.000000000 +0000
9230 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_sched.h     2015-01-19 10:58:04.000000000 +0000
9231 @@ -0,0 +1,40 @@
9232 +#ifndef _VS_SCHED_H
9233 +#define _VS_SCHED_H
9234 +
9235 +#include "vserver/base.h"
9236 +#include "vserver/context.h"
9237 +#include "vserver/sched.h"
9238 +
9239 +
9240 +#define MAX_PRIO_BIAS           20
9241 +#define MIN_PRIO_BIAS          -20
9242 +
9243 +static inline
9244 +int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
9245 +{
9246 +       struct vx_info *vxi = p->vx_info;
9247 +
9248 +       if (vxi)
9249 +               prio += vx_cpu(vxi, sched_pc).prio_bias;
9250 +       return prio;
9251 +}
9252 +
9253 +static inline void vx_account_user(struct vx_info *vxi,
9254 +       cputime_t cputime, int nice)
9255 +{
9256 +       if (!vxi)
9257 +               return;
9258 +       vx_cpu(vxi, sched_pc).user_ticks += cputime;
9259 +}
9260 +
9261 +static inline void vx_account_system(struct vx_info *vxi,
9262 +       cputime_t cputime, int idle)
9263 +{
9264 +       if (!vxi)
9265 +               return;
9266 +       vx_cpu(vxi, sched_pc).sys_ticks += cputime;
9267 +}
9268 +
9269 +#else
9270 +#warning duplicate inclusion
9271 +#endif
9272 diff -NurpP --minimal linux-3.18.5/include/linux/vs_socket.h linux-3.18.5-vs2.3.7.3/include/linux/vs_socket.h
9273 --- linux-3.18.5/include/linux/vs_socket.h      1970-01-01 00:00:00.000000000 +0000
9274 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_socket.h    2015-01-19 10:58:04.000000000 +0000
9275 @@ -0,0 +1,67 @@
9276 +#ifndef _VS_SOCKET_H
9277 +#define _VS_SOCKET_H
9278 +
9279 +#include "vserver/debug.h"
9280 +#include "vserver/base.h"
9281 +#include "vserver/cacct.h"
9282 +#include "vserver/context.h"
9283 +#include "vserver/tag.h"
9284 +
9285 +
9286 +/* socket accounting */
9287 +
9288 +#include <linux/socket.h>
9289 +
9290 +static inline int vx_sock_type(int family)
9291 +{
9292 +       switch (family) {
9293 +       case PF_UNSPEC:
9294 +               return VXA_SOCK_UNSPEC;
9295 +       case PF_UNIX:
9296 +               return VXA_SOCK_UNIX;
9297 +       case PF_INET:
9298 +               return VXA_SOCK_INET;
9299 +       case PF_INET6:
9300 +               return VXA_SOCK_INET6;
9301 +       case PF_PACKET:
9302 +               return VXA_SOCK_PACKET;
9303 +       default:
9304 +               return VXA_SOCK_OTHER;
9305 +       }
9306 +}
9307 +
9308 +#define vx_acc_sock(v, f, p, s) \
9309 +       __vx_acc_sock(v, f, p, s, __FILE__, __LINE__)
9310 +
9311 +static inline void __vx_acc_sock(struct vx_info *vxi,
9312 +       int family, int pos, int size, char *file, int line)
9313 +{
9314 +       if (vxi) {
9315 +               int type = vx_sock_type(family);
9316 +
9317 +               atomic_long_inc(&vxi->cacct.sock[type][pos].count);
9318 +               atomic_long_add(size, &vxi->cacct.sock[type][pos].total);
9319 +       }
9320 +}
9321 +
9322 +#define vx_sock_recv(sk, s) \
9323 +       vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, s)
9324 +#define vx_sock_send(sk, s) \
9325 +       vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, s)
9326 +#define vx_sock_fail(sk, s) \
9327 +       vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, s)
9328 +
9329 +
9330 +#define sock_vx_init(s) do {           \
9331 +       (s)->sk_xid = 0;                \
9332 +       (s)->sk_vx_info = NULL;         \
9333 +       } while (0)
9334 +
9335 +#define sock_nx_init(s) do {           \
9336 +       (s)->sk_nid = 0;                \
9337 +       (s)->sk_nx_info = NULL;         \
9338 +       } while (0)
9339 +
9340 +#else
9341 +#warning duplicate inclusion
9342 +#endif
9343 diff -NurpP --minimal linux-3.18.5/include/linux/vs_tag.h linux-3.18.5-vs2.3.7.3/include/linux/vs_tag.h
9344 --- linux-3.18.5/include/linux/vs_tag.h 1970-01-01 00:00:00.000000000 +0000
9345 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_tag.h       2015-01-19 10:58:04.000000000 +0000
9346 @@ -0,0 +1,47 @@
9347 +#ifndef _VS_TAG_H
9348 +#define _VS_TAG_H
9349 +
9350 +#include <linux/vserver/tag.h>
9351 +
9352 +/* check conditions */
9353 +
9354 +#define DX_ADMIN       0x0001
9355 +#define DX_WATCH       0x0002
9356 +#define DX_HOSTID      0x0008
9357 +
9358 +#define DX_IDENT       0x0010
9359 +
9360 +#define DX_ARG_MASK    0x0010
9361 +
9362 +
9363 +#define dx_task_tag(t) ((t)->tag)
9364 +
9365 +#define dx_current_tag() dx_task_tag(current)
9366 +
9367 +#define dx_check(c, m) __dx_check(dx_current_tag(), c, m)
9368 +
9369 +#define dx_weak_check(c, m)    ((m) ? dx_check(c, m) : 1)
9370 +
9371 +
9372 +/*
9373 + * check current context for ADMIN/WATCH and
9374 + * optionally against supplied argument
9375 + */
9376 +static inline int __dx_check(vtag_t cid, vtag_t id, unsigned int mode)
9377 +{
9378 +       if (mode & DX_ARG_MASK) {
9379 +               if ((mode & DX_IDENT) && (id == cid))
9380 +                       return 1;
9381 +       }
9382 +       return (((mode & DX_ADMIN) && (cid == 0)) ||
9383 +               ((mode & DX_WATCH) && (cid == 1)) ||
9384 +               ((mode & DX_HOSTID) && (id == 0)));
9385 +}
9386 +
9387 +struct inode;
9388 +int dx_permission(const struct inode *inode, int mask);
9389 +
9390 +
9391 +#else
9392 +#warning duplicate inclusion
9393 +#endif
9394 diff -NurpP --minimal linux-3.18.5/include/linux/vs_time.h linux-3.18.5-vs2.3.7.3/include/linux/vs_time.h
9395 --- linux-3.18.5/include/linux/vs_time.h        1970-01-01 00:00:00.000000000 +0000
9396 +++ linux-3.18.5-vs2.3.7.3/include/linux/vs_time.h      2015-01-19 10:58:04.000000000 +0000
9397 @@ -0,0 +1,19 @@
9398 +#ifndef _VS_TIME_H
9399 +#define _VS_TIME_H
9400 +
9401 +
9402 +/* time faking stuff */
9403 +
9404 +#ifdef CONFIG_VSERVER_VTIME
9405 +
9406 +extern void vx_adjust_timespec(struct timespec *ts);
9407 +extern int vx_settimeofday(const struct timespec *ts);
9408 +
9409 +#else
9410 +#define        vx_adjust_timespec(t)   do { } while (0)
9411 +#define        vx_settimeofday(t)      do_settimeofday(t)
9412 +#endif
9413 +
9414 +#else
9415 +#warning duplicate inclusion
9416 +#endif
9417 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/base.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/base.h
9418 --- linux-3.18.5/include/linux/vserver/base.h   1970-01-01 00:00:00.000000000 +0000
9419 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/base.h 2015-01-19 10:58:04.000000000 +0000
9420 @@ -0,0 +1,184 @@
9421 +#ifndef _VSERVER_BASE_H
9422 +#define _VSERVER_BASE_H
9423 +
9424 +
9425 +/* context state changes */
9426 +
9427 +enum {
9428 +       VSC_STARTUP = 1,
9429 +       VSC_SHUTDOWN,
9430 +
9431 +       VSC_NETUP,
9432 +       VSC_NETDOWN,
9433 +};
9434 +
9435 +
9436 +
9437 +#define vx_task_xid(t) ((t)->xid)
9438 +
9439 +#define vx_current_xid() vx_task_xid(current)
9440 +
9441 +#define current_vx_info() (current->vx_info)
9442 +
9443 +
9444 +#define nx_task_nid(t) ((t)->nid)
9445 +
9446 +#define nx_current_nid() nx_task_nid(current)
9447 +
9448 +#define current_nx_info() (current->nx_info)
9449 +
9450 +
9451 +/* generic flag merging */
9452 +
9453 +#define vs_check_flags(v, m, f)        (((v) & (m)) ^ (f))
9454 +
9455 +#define vs_mask_flags(v, f, m) (((v) & ~(m)) | ((f) & (m)))
9456 +
9457 +#define vs_mask_mask(v, f, m)  (((v) & ~(m)) | ((v) & (f) & (m)))
9458 +
9459 +#define vs_check_bit(v, n)     ((v) & (1LL << (n)))
9460 +
9461 +
9462 +/* context flags */
9463 +
9464 +#define __vx_flags(v)  ((v) ? (v)->vx_flags : 0)
9465 +
9466 +#define vx_current_flags()     __vx_flags(current_vx_info())
9467 +
9468 +#define vx_info_flags(v, m, f) \
9469 +       vs_check_flags(__vx_flags(v), m, f)
9470 +
9471 +#define task_vx_flags(t, m, f) \
9472 +       ((t) && vx_info_flags((t)->vx_info, m, f))
9473 +
9474 +#define vx_flags(m, f) vx_info_flags(current_vx_info(), m, f)
9475 +
9476 +
9477 +/* context caps */
9478 +
9479 +#define __vx_ccaps(v)  ((v) ? (v)->vx_ccaps : 0)
9480 +
9481 +#define vx_current_ccaps()     __vx_ccaps(current_vx_info())
9482 +
9483 +#define vx_info_ccaps(v, c)    (__vx_ccaps(v) & (c))
9484 +
9485 +#define vx_ccaps(c)    vx_info_ccaps(current_vx_info(), (c))
9486 +
9487 +
9488 +
9489 +/* network flags */
9490 +
9491 +#define __nx_flags(n)  ((n) ? (n)->nx_flags : 0)
9492 +
9493 +#define nx_current_flags()     __nx_flags(current_nx_info())
9494 +
9495 +#define nx_info_flags(n, m, f) \
9496 +       vs_check_flags(__nx_flags(n), m, f)
9497 +
9498 +#define task_nx_flags(t, m, f) \
9499 +       ((t) && nx_info_flags((t)->nx_info, m, f))
9500 +
9501 +#define nx_flags(m, f) nx_info_flags(current_nx_info(), m, f)
9502 +
9503 +
9504 +/* network caps */
9505 +
9506 +#define __nx_ncaps(n)  ((n) ? (n)->nx_ncaps : 0)
9507 +
9508 +#define nx_current_ncaps()     __nx_ncaps(current_nx_info())
9509 +
9510 +#define nx_info_ncaps(n, c)    (__nx_ncaps(n) & (c))
9511 +
9512 +#define nx_ncaps(c)    nx_info_ncaps(current_nx_info(), c)
9513 +
9514 +
9515 +/* context mask capabilities */
9516 +
9517 +#define __vx_mcaps(v)  ((v) ? (v)->vx_ccaps >> 32UL : ~0 )
9518 +
9519 +#define vx_info_mcaps(v, c)    (__vx_mcaps(v) & (c))
9520 +
9521 +#define vx_mcaps(c)    vx_info_mcaps(current_vx_info(), c)
9522 +
9523 +
9524 +/* context bcap mask */
9525 +
9526 +#define __vx_bcaps(v)          ((v)->vx_bcaps)
9527 +
9528 +#define vx_current_bcaps()     __vx_bcaps(current_vx_info())
9529 +
9530 +
9531 +/* mask given bcaps */
9532 +
9533 +#define vx_info_mbcaps(v, c)   ((v) ? cap_intersect(__vx_bcaps(v), c) : c)
9534 +
9535 +#define vx_mbcaps(c)           vx_info_mbcaps(current_vx_info(), c)
9536 +
9537 +
9538 +/* masked cap_bset */
9539 +
9540 +#define vx_info_cap_bset(v)    vx_info_mbcaps(v, current->cap_bset)
9541 +
9542 +#define vx_current_cap_bset()  vx_info_cap_bset(current_vx_info())
9543 +
9544 +#if 0
9545 +#define vx_info_mbcap(v, b) \
9546 +       (!vx_info_flags(v, VXF_STATE_SETUP, 0) ? \
9547 +       vx_info_bcaps(v, b) : (b))
9548 +
9549 +#define task_vx_mbcap(t, b) \
9550 +       vx_info_mbcap((t)->vx_info, (t)->b)
9551 +
9552 +#define vx_mbcap(b)    task_vx_mbcap(current, b)
9553 +#endif
9554 +
9555 +#define vx_cap_raised(v, c, f) cap_raised(vx_info_mbcaps(v, c), f)
9556 +
9557 +#define vx_capable(b, c) (capable(b) || \
9558 +       (cap_raised(current_cap(), b) && vx_ccaps(c)))
9559 +
9560 +#define vx_ns_capable(n, b, c) (ns_capable(n, b) || \
9561 +       (cap_raised(current_cap(), b) && vx_ccaps(c)))
9562 +
9563 +#define nx_capable(b, c) (capable(b) || \
9564 +       (cap_raised(current_cap(), b) && nx_ncaps(c)))
9565 +
9566 +#define nx_ns_capable(n, b, c) (ns_capable(n, b) || \
9567 +       (cap_raised(current_cap(), b) && nx_ncaps(c)))
9568 +
9569 +#define vx_task_initpid(t, n) \
9570 +       ((t)->vx_info && \
9571 +       ((t)->vx_info->vx_initpid == (n)))
9572 +
9573 +#define vx_current_initpid(n)  vx_task_initpid(current, n)
9574 +
9575 +
9576 +/* context unshare mask */
9577 +
9578 +#define __vx_umask(v)          ((v)->vx_umask)
9579 +
9580 +#define vx_current_umask()     __vx_umask(current_vx_info())
9581 +
9582 +#define vx_can_unshare(b, f) (capable(b) || \
9583 +       (cap_raised(current_cap(), b) && \
9584 +       !((f) & ~vx_current_umask())))
9585 +
9586 +#define vx_ns_can_unshare(n, b, f) (ns_capable(n, b) || \
9587 +       (cap_raised(current_cap(), b) && \
9588 +       !((f) & ~vx_current_umask())))
9589 +
9590 +#define __vx_wmask(v)          ((v)->vx_wmask)
9591 +
9592 +#define vx_current_wmask()     __vx_wmask(current_vx_info())
9593 +
9594 +
9595 +#define __vx_state(v)  ((v) ? ((v)->vx_state) : 0)
9596 +
9597 +#define vx_info_state(v, m)    (__vx_state(v) & (m))
9598 +
9599 +
9600 +#define __nx_state(n)  ((n) ? ((n)->nx_state) : 0)
9601 +
9602 +#define nx_info_state(n, m)    (__nx_state(n) & (m))
9603 +
9604 +#endif
9605 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/cacct.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/cacct.h
9606 --- linux-3.18.5/include/linux/vserver/cacct.h  1970-01-01 00:00:00.000000000 +0000
9607 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/cacct.h        2015-01-19 10:58:04.000000000 +0000
9608 @@ -0,0 +1,15 @@
9609 +#ifndef _VSERVER_CACCT_H
9610 +#define _VSERVER_CACCT_H
9611 +
9612 +
9613 +enum sock_acc_field {
9614 +       VXA_SOCK_UNSPEC = 0,
9615 +       VXA_SOCK_UNIX,
9616 +       VXA_SOCK_INET,
9617 +       VXA_SOCK_INET6,
9618 +       VXA_SOCK_PACKET,
9619 +       VXA_SOCK_OTHER,
9620 +       VXA_SOCK_SIZE   /* array size */
9621 +};
9622 +
9623 +#endif /* _VSERVER_CACCT_H */
9624 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/cacct_cmd.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/cacct_cmd.h
9625 --- linux-3.18.5/include/linux/vserver/cacct_cmd.h      1970-01-01 00:00:00.000000000 +0000
9626 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/cacct_cmd.h    2015-01-19 10:58:04.000000000 +0000
9627 @@ -0,0 +1,10 @@
9628 +#ifndef _VSERVER_CACCT_CMD_H
9629 +#define _VSERVER_CACCT_CMD_H
9630 +
9631 +
9632 +#include <linux/compiler.h>
9633 +#include <uapi/vserver/cacct_cmd.h>
9634 +
9635 +extern int vc_sock_stat(struct vx_info *, void __user *);
9636 +
9637 +#endif /* _VSERVER_CACCT_CMD_H */
9638 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/cacct_def.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/cacct_def.h
9639 --- linux-3.18.5/include/linux/vserver/cacct_def.h      1970-01-01 00:00:00.000000000 +0000
9640 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/cacct_def.h    2015-01-19 10:58:04.000000000 +0000
9641 @@ -0,0 +1,43 @@
9642 +#ifndef _VSERVER_CACCT_DEF_H
9643 +#define _VSERVER_CACCT_DEF_H
9644 +
9645 +#include <asm/atomic.h>
9646 +#include <linux/vserver/cacct.h>
9647 +
9648 +
9649 +struct _vx_sock_acc {
9650 +       atomic_long_t count;
9651 +       atomic_long_t total;
9652 +};
9653 +
9654 +/* context sub struct */
9655 +
9656 +struct _vx_cacct {
9657 +       struct _vx_sock_acc sock[VXA_SOCK_SIZE][3];
9658 +       atomic_t slab[8];
9659 +       atomic_t page[6][8];
9660 +};
9661 +
9662 +#ifdef CONFIG_VSERVER_DEBUG
9663 +
9664 +static inline void __dump_vx_cacct(struct _vx_cacct *cacct)
9665 +{
9666 +       int i, j;
9667 +
9668 +       printk("\t_vx_cacct:");
9669 +       for (i = 0; i < 6; i++) {
9670 +               struct _vx_sock_acc *ptr = cacct->sock[i];
9671 +
9672 +               printk("\t [%d] =", i);
9673 +               for (j = 0; j < 3; j++) {
9674 +                       printk(" [%d] = %8lu, %8lu", j,
9675 +                               atomic_long_read(&ptr[j].count),
9676 +                               atomic_long_read(&ptr[j].total));
9677 +               }
9678 +               printk("\n");
9679 +       }
9680 +}
9681 +
9682 +#endif
9683 +
9684 +#endif /* _VSERVER_CACCT_DEF_H */
9685 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/cacct_int.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/cacct_int.h
9686 --- linux-3.18.5/include/linux/vserver/cacct_int.h      1970-01-01 00:00:00.000000000 +0000
9687 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/cacct_int.h    2015-01-19 10:58:04.000000000 +0000
9688 @@ -0,0 +1,17 @@
9689 +#ifndef _VSERVER_CACCT_INT_H
9690 +#define _VSERVER_CACCT_INT_H
9691 +
9692 +static inline
9693 +unsigned long vx_sock_count(struct _vx_cacct *cacct, int type, int pos)
9694 +{
9695 +       return atomic_long_read(&cacct->sock[type][pos].count);
9696 +}
9697 +
9698 +
9699 +static inline
9700 +unsigned long vx_sock_total(struct _vx_cacct *cacct, int type, int pos)
9701 +{
9702 +       return atomic_long_read(&cacct->sock[type][pos].total);
9703 +}
9704 +
9705 +#endif /* _VSERVER_CACCT_INT_H */
9706 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/check.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/check.h
9707 --- linux-3.18.5/include/linux/vserver/check.h  1970-01-01 00:00:00.000000000 +0000
9708 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/check.h        2015-01-19 10:58:04.000000000 +0000
9709 @@ -0,0 +1,89 @@
9710 +#ifndef _VSERVER_CHECK_H
9711 +#define _VSERVER_CHECK_H
9712 +
9713 +
9714 +#define MAX_S_CONTEXT  65535   /* Arbitrary limit */
9715 +
9716 +#ifdef CONFIG_VSERVER_DYNAMIC_IDS
9717 +#define MIN_D_CONTEXT  49152   /* dynamic contexts start here */
9718 +#else
9719 +#define MIN_D_CONTEXT  65536
9720 +#endif
9721 +
9722 +/* check conditions */
9723 +
9724 +#define VS_ADMIN       0x0001
9725 +#define VS_WATCH       0x0002
9726 +#define VS_HIDE                0x0004
9727 +#define VS_HOSTID      0x0008
9728 +
9729 +#define VS_IDENT       0x0010
9730 +#define VS_EQUIV       0x0020
9731 +#define VS_PARENT      0x0040
9732 +#define VS_CHILD       0x0080
9733 +
9734 +#define VS_ARG_MASK    0x00F0
9735 +
9736 +#define VS_DYNAMIC     0x0100
9737 +#define VS_STATIC      0x0200
9738 +
9739 +#define VS_ATR_MASK    0x0F00
9740 +
9741 +#ifdef CONFIG_VSERVER_PRIVACY
9742 +#define VS_ADMIN_P     (0)
9743 +#define VS_WATCH_P     (0)
9744 +#else
9745 +#define VS_ADMIN_P     VS_ADMIN
9746 +#define VS_WATCH_P     VS_WATCH
9747 +#endif
9748 +
9749 +#define VS_HARDIRQ     0x1000
9750 +#define VS_SOFTIRQ     0x2000
9751 +#define VS_IRQ         0x4000
9752 +
9753 +#define VS_IRQ_MASK    0xF000
9754 +
9755 +#include <linux/hardirq.h>
9756 +
9757 +/*
9758 + * check current context for ADMIN/WATCH and
9759 + * optionally against supplied argument
9760 + */
9761 +static inline int __vs_check(int cid, int id, unsigned int mode)
9762 +{
9763 +       if (mode & VS_ARG_MASK) {
9764 +               if ((mode & VS_IDENT) && (id == cid))
9765 +                       return 1;
9766 +       }
9767 +       if (mode & VS_ATR_MASK) {
9768 +               if ((mode & VS_DYNAMIC) &&
9769 +                       (id >= MIN_D_CONTEXT) &&
9770 +                       (id <= MAX_S_CONTEXT))
9771 +                       return 1;
9772 +               if ((mode & VS_STATIC) &&
9773 +                       (id > 1) && (id < MIN_D_CONTEXT))
9774 +                       return 1;
9775 +       }
9776 +       if (mode & VS_IRQ_MASK) {
9777 +               if ((mode & VS_IRQ) && unlikely(in_interrupt()))
9778 +                       return 1;
9779 +               if ((mode & VS_HARDIRQ) && unlikely(in_irq()))
9780 +                       return 1;
9781 +               if ((mode & VS_SOFTIRQ) && unlikely(in_softirq()))
9782 +                       return 1;
9783 +       }
9784 +       return (((mode & VS_ADMIN) && (cid == 0)) ||
9785 +               ((mode & VS_WATCH) && (cid == 1)) ||
9786 +               ((mode & VS_HOSTID) && (id == 0)));
9787 +}
9788 +
9789 +#define vx_check(c, m) __vs_check(vx_current_xid(), c, (m) | VS_IRQ)
9790 +
9791 +#define vx_weak_check(c, m)    ((m) ? vx_check(c, m) : 1)
9792 +
9793 +
9794 +#define nx_check(c, m) __vs_check(nx_current_nid(), c, m)
9795 +
9796 +#define nx_weak_check(c, m)    ((m) ? nx_check(c, m) : 1)
9797 +
9798 +#endif
9799 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/context.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/context.h
9800 --- linux-3.18.5/include/linux/vserver/context.h        1970-01-01 00:00:00.000000000 +0000
9801 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/context.h      2015-01-19 10:58:04.000000000 +0000
9802 @@ -0,0 +1,110 @@
9803 +#ifndef _VSERVER_CONTEXT_H
9804 +#define _VSERVER_CONTEXT_H
9805 +
9806 +
9807 +#include <linux/list.h>
9808 +#include <linux/spinlock.h>
9809 +#include <linux/rcupdate.h>
9810 +#include <uapi/vserver/context.h>
9811 +
9812 +#include "limit_def.h"
9813 +#include "sched_def.h"
9814 +#include "cvirt_def.h"
9815 +#include "cacct_def.h"
9816 +#include "device_def.h"
9817 +
9818 +#define VX_SPACES      2
9819 +
9820 +struct _vx_info_pc {
9821 +       struct _vx_sched_pc sched_pc;
9822 +       struct _vx_cvirt_pc cvirt_pc;
9823 +};
9824 +
9825 +struct _vx_space {
9826 +       unsigned long vx_nsmask;                /* assignment mask */
9827 +       struct nsproxy *vx_nsproxy;             /* private namespaces */
9828 +       struct fs_struct *vx_fs;                /* private namespace fs */
9829 +       const struct cred *vx_cred;             /* task credentials */
9830 +};
9831 +
9832 +struct vx_info {
9833 +       struct hlist_node vx_hlist;             /* linked list of contexts */
9834 +       vxid_t vx_id;                           /* context id */
9835 +       atomic_t vx_usecnt;                     /* usage count */
9836 +       atomic_t vx_tasks;                      /* tasks count */
9837 +       struct vx_info *vx_parent;              /* parent context */
9838 +       int vx_state;                           /* context state */
9839 +
9840 +       struct _vx_space space[VX_SPACES];      /* namespace store */
9841 +
9842 +       uint64_t vx_flags;                      /* context flags */
9843 +       uint64_t vx_ccaps;                      /* context caps (vserver) */
9844 +       uint64_t vx_umask;                      /* unshare mask (guest) */
9845 +       uint64_t vx_wmask;                      /* warn mask (guest) */
9846 +       kernel_cap_t vx_bcaps;                  /* bounding caps (system) */
9847 +
9848 +       struct task_struct *vx_reaper;          /* guest reaper process */
9849 +       pid_t vx_initpid;                       /* PID of guest init */
9850 +       int64_t vx_badness_bias;                /* OOM points bias */
9851 +
9852 +       struct _vx_limit limit;                 /* vserver limits */
9853 +       struct _vx_sched sched;                 /* vserver scheduler */
9854 +       struct _vx_cvirt cvirt;                 /* virtual/bias stuff */
9855 +       struct _vx_cacct cacct;                 /* context accounting */
9856 +
9857 +       struct _vx_device dmap;                 /* default device map targets */
9858 +
9859 +#ifndef CONFIG_SMP
9860 +       struct _vx_info_pc info_pc;             /* per cpu data */
9861 +#else
9862 +       struct _vx_info_pc *ptr_pc;             /* per cpu array */
9863 +#endif
9864 +
9865 +       wait_queue_head_t vx_wait;              /* context exit waitqueue */
9866 +       int reboot_cmd;                         /* last sys_reboot() cmd */
9867 +       int exit_code;                          /* last process exit code */
9868 +
9869 +       char vx_name[65];                       /* vserver name */
9870 +};
9871 +
9872 +#ifndef CONFIG_SMP
9873 +#define        vx_ptr_pc(vxi)          (&(vxi)->info_pc)
9874 +#define        vx_per_cpu(vxi, v, id)  vx_ptr_pc(vxi)->v
9875 +#else
9876 +#define        vx_ptr_pc(vxi)          ((vxi)->ptr_pc)
9877 +#define        vx_per_cpu(vxi, v, id)  per_cpu_ptr(vx_ptr_pc(vxi), id)->v
9878 +#endif
9879 +
9880 +#define        vx_cpu(vxi, v)          vx_per_cpu(vxi, v, smp_processor_id())
9881 +
9882 +
9883 +struct vx_info_save {
9884 +       struct vx_info *vxi;
9885 +       vxid_t xid;
9886 +};
9887 +
9888 +
9889 +/* status flags */
9890 +
9891 +#define VXS_HASHED     0x0001
9892 +#define VXS_PAUSED     0x0010
9893 +#define VXS_SHUTDOWN   0x0100
9894 +#define VXS_HELPER     0x1000
9895 +#define VXS_RELEASED   0x8000
9896 +
9897 +
9898 +extern void claim_vx_info(struct vx_info *, struct task_struct *);
9899 +extern void release_vx_info(struct vx_info *, struct task_struct *);
9900 +
9901 +extern struct vx_info *lookup_vx_info(int);
9902 +extern struct vx_info *lookup_or_create_vx_info(int);
9903 +
9904 +extern int get_xid_list(int, unsigned int *, int);
9905 +extern int xid_is_hashed(vxid_t);
9906 +
9907 +extern int vx_migrate_task(struct task_struct *, struct vx_info *, int);
9908 +
9909 +extern long vs_state_change(struct vx_info *, unsigned int);
9910 +
9911 +
9912 +#endif /* _VSERVER_CONTEXT_H */
9913 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/context_cmd.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/context_cmd.h
9914 --- linux-3.18.5/include/linux/vserver/context_cmd.h    1970-01-01 00:00:00.000000000 +0000
9915 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/context_cmd.h  2015-01-19 10:58:04.000000000 +0000
9916 @@ -0,0 +1,33 @@
9917 +#ifndef _VSERVER_CONTEXT_CMD_H
9918 +#define _VSERVER_CONTEXT_CMD_H
9919 +
9920 +#include <uapi/vserver/context_cmd.h>
9921 +
9922 +extern int vc_task_xid(uint32_t);
9923 +
9924 +extern int vc_vx_info(struct vx_info *, void __user *);
9925 +
9926 +extern int vc_ctx_stat(struct vx_info *, void __user *);
9927 +
9928 +extern int vc_ctx_create(uint32_t, void __user *);
9929 +extern int vc_ctx_migrate(struct vx_info *, void __user *);
9930 +
9931 +extern int vc_get_cflags(struct vx_info *, void __user *);
9932 +extern int vc_set_cflags(struct vx_info *, void __user *);
9933 +
9934 +extern int vc_get_ccaps(struct vx_info *, void __user *);
9935 +extern int vc_set_ccaps(struct vx_info *, void __user *);
9936 +
9937 +extern int vc_get_bcaps(struct vx_info *, void __user *);
9938 +extern int vc_set_bcaps(struct vx_info *, void __user *);
9939 +
9940 +extern int vc_get_umask(struct vx_info *, void __user *);
9941 +extern int vc_set_umask(struct vx_info *, void __user *);
9942 +
9943 +extern int vc_get_wmask(struct vx_info *, void __user *);
9944 +extern int vc_set_wmask(struct vx_info *, void __user *);
9945 +
9946 +extern int vc_get_badness(struct vx_info *, void __user *);
9947 +extern int vc_set_badness(struct vx_info *, void __user *);
9948 +
9949 +#endif /* _VSERVER_CONTEXT_CMD_H */
9950 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/cvirt.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/cvirt.h
9951 --- linux-3.18.5/include/linux/vserver/cvirt.h  1970-01-01 00:00:00.000000000 +0000
9952 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/cvirt.h        2015-01-19 10:58:04.000000000 +0000
9953 @@ -0,0 +1,18 @@
9954 +#ifndef _VSERVER_CVIRT_H
9955 +#define _VSERVER_CVIRT_H
9956 +
9957 +struct timespec;
9958 +
9959 +void vx_vsi_boottime(struct timespec *);
9960 +
9961 +void vx_vsi_uptime(struct timespec *, struct timespec *);
9962 +
9963 +
9964 +struct vx_info;
9965 +
9966 +void vx_update_load(struct vx_info *);
9967 +
9968 +
9969 +int vx_do_syslog(int, char __user *, int);
9970 +
9971 +#endif /* _VSERVER_CVIRT_H */
9972 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/cvirt_cmd.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/cvirt_cmd.h
9973 --- linux-3.18.5/include/linux/vserver/cvirt_cmd.h      1970-01-01 00:00:00.000000000 +0000
9974 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/cvirt_cmd.h    2015-01-19 10:58:04.000000000 +0000
9975 @@ -0,0 +1,13 @@
9976 +#ifndef _VSERVER_CVIRT_CMD_H
9977 +#define _VSERVER_CVIRT_CMD_H
9978 +
9979 +
9980 +#include <linux/compiler.h>
9981 +#include <uapi/vserver/cvirt_cmd.h>
9982 +
9983 +extern int vc_set_vhi_name(struct vx_info *, void __user *);
9984 +extern int vc_get_vhi_name(struct vx_info *, void __user *);
9985 +
9986 +extern int vc_virt_stat(struct vx_info *, void __user *);
9987 +
9988 +#endif /* _VSERVER_CVIRT_CMD_H */
9989 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/cvirt_def.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/cvirt_def.h
9990 --- linux-3.18.5/include/linux/vserver/cvirt_def.h      1970-01-01 00:00:00.000000000 +0000
9991 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/cvirt_def.h    2015-01-19 10:58:04.000000000 +0000
9992 @@ -0,0 +1,80 @@
9993 +#ifndef _VSERVER_CVIRT_DEF_H
9994 +#define _VSERVER_CVIRT_DEF_H
9995 +
9996 +#include <linux/jiffies.h>
9997 +#include <linux/spinlock.h>
9998 +#include <linux/wait.h>
9999 +#include <linux/time.h>
10000 +#include <asm/atomic.h>
10001 +
10002 +
10003 +struct _vx_usage_stat {
10004 +       uint64_t user;
10005 +       uint64_t nice;
10006 +       uint64_t system;
10007 +       uint64_t softirq;
10008 +       uint64_t irq;
10009 +       uint64_t idle;
10010 +       uint64_t iowait;
10011 +};
10012 +
10013 +struct _vx_syslog {
10014 +       wait_queue_head_t log_wait;
10015 +       spinlock_t logbuf_lock;         /* lock for the log buffer */
10016 +
10017 +       unsigned long log_start;        /* next char to be read by syslog() */
10018 +       unsigned long con_start;        /* next char to be sent to consoles */
10019 +       unsigned long log_end;  /* most-recently-written-char + 1 */
10020 +       unsigned long logged_chars;     /* #chars since last read+clear operation */
10021 +
10022 +       char log_buf[1024];
10023 +};
10024 +
10025 +
10026 +/* context sub struct */
10027 +
10028 +struct _vx_cvirt {
10029 +       atomic_t nr_threads;            /* number of current threads */
10030 +       atomic_t nr_running;            /* number of running threads */
10031 +       atomic_t nr_uninterruptible;    /* number of uninterruptible threads */
10032 +
10033 +       atomic_t nr_onhold;             /* processes on hold */
10034 +       uint32_t onhold_last;           /* jiffies when put on hold */
10035 +
10036 +       struct timespec bias_ts;        /* time offset to the host */
10037 +       struct timespec bias_idle;
10038 +       struct timespec bias_uptime;    /* context creation point */
10039 +       uint64_t bias_clock;            /* offset in clock_t */
10040 +
10041 +       spinlock_t load_lock;           /* lock for the load averages */
10042 +       atomic_t load_updates;          /* nr of load updates done so far */
10043 +       uint32_t load_last;             /* last time load was calculated */
10044 +       uint32_t load[3];               /* load averages 1,5,15 */
10045 +
10046 +       atomic_t total_forks;           /* number of forks so far */
10047 +
10048 +       struct _vx_syslog syslog;
10049 +};
10050 +
10051 +struct _vx_cvirt_pc {
10052 +       struct _vx_usage_stat cpustat;
10053 +};
10054 +
10055 +
10056 +#ifdef CONFIG_VSERVER_DEBUG
10057 +
10058 +static inline void __dump_vx_cvirt(struct _vx_cvirt *cvirt)
10059 +{
10060 +       printk("\t_vx_cvirt:\n");
10061 +       printk("\t threads: %4d, %4d, %4d, %4d\n",
10062 +               atomic_read(&cvirt->nr_threads),
10063 +               atomic_read(&cvirt->nr_running),
10064 +               atomic_read(&cvirt->nr_uninterruptible),
10065 +               atomic_read(&cvirt->nr_onhold));
10066 +       /* add rest here */
10067 +       printk("\t total_forks = %d\n", atomic_read(&cvirt->total_forks));
10068 +}
10069 +
10070 +#endif
10071 +
10072 +#endif /* _VSERVER_CVIRT_DEF_H */
10073 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/debug.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/debug.h
10074 --- linux-3.18.5/include/linux/vserver/debug.h  1970-01-01 00:00:00.000000000 +0000
10075 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/debug.h        2015-01-19 10:58:04.000000000 +0000
10076 @@ -0,0 +1,146 @@
10077 +#ifndef _VSERVER_DEBUG_H
10078 +#define _VSERVER_DEBUG_H
10079 +
10080 +
10081 +#define VXD_CBIT(n, m) (vs_debug_ ## n & (1 << (m)))
10082 +#define VXD_CMIN(n, m) (vs_debug_ ## n > (m))
10083 +#define VXD_MASK(n, m) (vs_debug_ ## n & (m))
10084 +
10085 +#define VXD_DEV(d)     (d), (d)->bd_inode->i_ino,              \
10086 +                       imajor((d)->bd_inode), iminor((d)->bd_inode)
10087 +#define VXF_DEV                "%p[%lu,%d:%d]"
10088 +
10089 +#if    defined(CONFIG_QUOTES_UTF8)
10090 +#define        VS_Q_LQM        "\xc2\xbb"
10091 +#define        VS_Q_RQM        "\xc2\xab"
10092 +#elif  defined(CONFIG_QUOTES_ASCII)
10093 +#define        VS_Q_LQM        "\x27"
10094 +#define        VS_Q_RQM        "\x27"
10095 +#else
10096 +#define        VS_Q_LQM        "\xbb"
10097 +#define        VS_Q_RQM        "\xab"
10098 +#endif
10099 +
10100 +#define        VS_Q(f)         VS_Q_LQM f VS_Q_RQM
10101 +
10102 +
10103 +#define vxd_path(p)                                            \
10104 +       ({ static char _buffer[PATH_MAX];                       \
10105 +          d_path(p, _buffer, sizeof(_buffer)); })
10106 +
10107 +#define vxd_cond_path(n)                                       \
10108 +       ((n) ? vxd_path(&(n)->path) : "<null>" )
10109 +
10110 +
10111 +#ifdef CONFIG_VSERVER_DEBUG
10112 +
10113 +extern unsigned int vs_debug_switch;
10114 +extern unsigned int vs_debug_xid;
10115 +extern unsigned int vs_debug_nid;
10116 +extern unsigned int vs_debug_tag;
10117 +extern unsigned int vs_debug_net;
10118 +extern unsigned int vs_debug_limit;
10119 +extern unsigned int vs_debug_cres;
10120 +extern unsigned int vs_debug_dlim;
10121 +extern unsigned int vs_debug_quota;
10122 +extern unsigned int vs_debug_cvirt;
10123 +extern unsigned int vs_debug_space;
10124 +extern unsigned int vs_debug_perm;
10125 +extern unsigned int vs_debug_misc;
10126 +
10127 +
10128 +#define VX_LOGLEVEL    "vxD: "
10129 +#define VX_PROC_FMT    "%p: "
10130 +#define VX_PROCESS     current
10131 +
10132 +#define vxdprintk(c, f, x...)                                  \
10133 +       do {                                                    \
10134 +               if (c)                                          \
10135 +                       printk(VX_LOGLEVEL VX_PROC_FMT f "\n",  \
10136 +                               VX_PROCESS , ##x);              \
10137 +       } while (0)
10138 +
10139 +#define vxlprintk(c, f, x...)                                  \
10140 +       do {                                                    \
10141 +               if (c)                                          \
10142 +                       printk(VX_LOGLEVEL f " @%s:%d\n", x);   \
10143 +       } while (0)
10144 +
10145 +#define vxfprintk(c, f, x...)                                  \
10146 +       do {                                                    \
10147 +               if (c)                                          \
10148 +                       printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \
10149 +       } while (0)
10150 +
10151 +
10152 +struct vx_info;
10153 +
10154 +void dump_vx_info(struct vx_info *, int);
10155 +void dump_vx_info_inactive(int);
10156 +
10157 +#else  /* CONFIG_VSERVER_DEBUG */
10158 +
10159 +#define vs_debug_switch        0
10160 +#define vs_debug_xid   0
10161 +#define vs_debug_nid   0
10162 +#define vs_debug_tag   0
10163 +#define vs_debug_net   0
10164 +#define vs_debug_limit 0
10165 +#define vs_debug_cres  0
10166 +#define vs_debug_dlim  0
10167 +#define vs_debug_quota 0
10168 +#define vs_debug_cvirt 0
10169 +#define vs_debug_space 0
10170 +#define vs_debug_perm  0
10171 +#define vs_debug_misc  0
10172 +
10173 +#define vxdprintk(x...) do { } while (0)
10174 +#define vxlprintk(x...) do { } while (0)
10175 +#define vxfprintk(x...) do { } while (0)
10176 +
10177 +#endif /* CONFIG_VSERVER_DEBUG */
10178 +
10179 +
10180 +#ifdef CONFIG_VSERVER_WARN
10181 +
10182 +#define VX_WARNLEVEL   KERN_WARNING "vxW: "
10183 +#define VX_WARN_TASK   "[" VS_Q("%s") ",%u:#%u|%u|%u] "
10184 +#define VX_WARN_XID    "[xid #%u] "
10185 +#define VX_WARN_NID    "[nid #%u] "
10186 +#define VX_WARN_TAG    "[tag #%u] "
10187 +
10188 +#define vxwprintk(c, f, x...)                                  \
10189 +       do {                                                    \
10190 +               if (c)                                          \
10191 +                       printk(VX_WARNLEVEL f "\n", ##x);       \
10192 +       } while (0)
10193 +
10194 +#else  /* CONFIG_VSERVER_WARN */
10195 +
10196 +#define vxwprintk(x...) do { } while (0)
10197 +
10198 +#endif /* CONFIG_VSERVER_WARN */
10199 +
10200 +#define vxwprintk_task(c, f, x...)                             \
10201 +       vxwprintk(c, VX_WARN_TASK f,                            \
10202 +               current->comm, current->pid,                    \
10203 +               current->xid, current->nid,                     \
10204 +               current->tag, ##x)
10205 +#define vxwprintk_xid(c, f, x...)                              \
10206 +       vxwprintk(c, VX_WARN_XID f, current->xid, x)
10207 +#define vxwprintk_nid(c, f, x...)                              \
10208 +       vxwprintk(c, VX_WARN_NID f, current->nid, x)
10209 +#define vxwprintk_tag(c, f, x...)                              \
10210 +       vxwprintk(c, VX_WARN_TAG f, current->tag, x)
10211 +
10212 +#ifdef CONFIG_VSERVER_DEBUG
10213 +#define vxd_assert_lock(l)     assert_spin_locked(l)
10214 +#define vxd_assert(c, f, x...) vxlprintk(!(c), \
10215 +       "assertion [" f "] failed.", ##x, __FILE__, __LINE__)
10216 +#else
10217 +#define vxd_assert_lock(l)     do { } while (0)
10218 +#define vxd_assert(c, f, x...) do { } while (0)
10219 +#endif
10220 +
10221 +
10222 +#endif /* _VSERVER_DEBUG_H */
10223 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/debug_cmd.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/debug_cmd.h
10224 --- linux-3.18.5/include/linux/vserver/debug_cmd.h      1970-01-01 00:00:00.000000000 +0000
10225 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/debug_cmd.h    2015-01-19 10:58:04.000000000 +0000
10226 @@ -0,0 +1,37 @@
10227 +#ifndef _VSERVER_DEBUG_CMD_H
10228 +#define _VSERVER_DEBUG_CMD_H
10229 +
10230 +#include <uapi/vserver/debug_cmd.h>
10231 +
10232 +
10233 +#ifdef CONFIG_COMPAT
10234 +
10235 +#include <asm/compat.h>
10236 +
10237 +struct vcmd_read_history_v0_x32 {
10238 +       uint32_t index;
10239 +       uint32_t count;
10240 +       compat_uptr_t data_ptr;
10241 +};
10242 +
10243 +struct vcmd_read_monitor_v0_x32 {
10244 +       uint32_t index;
10245 +       uint32_t count;
10246 +       compat_uptr_t data_ptr;
10247 +};
10248 +
10249 +#endif  /* CONFIG_COMPAT */
10250 +
10251 +extern int vc_dump_history(uint32_t);
10252 +
10253 +extern int vc_read_history(uint32_t, void __user *);
10254 +extern int vc_read_monitor(uint32_t, void __user *);
10255 +
10256 +#ifdef CONFIG_COMPAT
10257 +
10258 +extern int vc_read_history_x32(uint32_t, void __user *);
10259 +extern int vc_read_monitor_x32(uint32_t, void __user *);
10260 +
10261 +#endif  /* CONFIG_COMPAT */
10262 +
10263 +#endif /* _VSERVER_DEBUG_CMD_H */
10264 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/device.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/device.h
10265 --- linux-3.18.5/include/linux/vserver/device.h 1970-01-01 00:00:00.000000000 +0000
10266 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/device.h       2015-01-19 10:58:04.000000000 +0000
10267 @@ -0,0 +1,9 @@
10268 +#ifndef _VSERVER_DEVICE_H
10269 +#define _VSERVER_DEVICE_H
10270 +
10271 +
10272 +#include <uapi/vserver/device.h>
10273 +
10274 +#else  /* _VSERVER_DEVICE_H */
10275 +#warning duplicate inclusion
10276 +#endif /* _VSERVER_DEVICE_H */
10277 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/device_cmd.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/device_cmd.h
10278 --- linux-3.18.5/include/linux/vserver/device_cmd.h     1970-01-01 00:00:00.000000000 +0000
10279 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/device_cmd.h   2015-01-19 10:58:04.000000000 +0000
10280 @@ -0,0 +1,31 @@
10281 +#ifndef _VSERVER_DEVICE_CMD_H
10282 +#define _VSERVER_DEVICE_CMD_H
10283 +
10284 +#include <uapi/vserver/device_cmd.h>
10285 +
10286 +
10287 +#ifdef CONFIG_COMPAT
10288 +
10289 +#include <asm/compat.h>
10290 +
10291 +struct vcmd_set_mapping_v0_x32 {
10292 +       compat_uptr_t device_ptr;
10293 +       compat_uptr_t target_ptr;
10294 +       uint32_t flags;
10295 +};
10296 +
10297 +#endif /* CONFIG_COMPAT */
10298 +
10299 +#include <linux/compiler.h>
10300 +
10301 +extern int vc_set_mapping(struct vx_info *, void __user *);
10302 +extern int vc_unset_mapping(struct vx_info *, void __user *);
10303 +
10304 +#ifdef CONFIG_COMPAT
10305 +
10306 +extern int vc_set_mapping_x32(struct vx_info *, void __user *);
10307 +extern int vc_unset_mapping_x32(struct vx_info *, void __user *);
10308 +
10309 +#endif /* CONFIG_COMPAT */
10310 +
10311 +#endif /* _VSERVER_DEVICE_CMD_H */
10312 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/device_def.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/device_def.h
10313 --- linux-3.18.5/include/linux/vserver/device_def.h     1970-01-01 00:00:00.000000000 +0000
10314 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/device_def.h   2015-01-19 10:58:04.000000000 +0000
10315 @@ -0,0 +1,17 @@
10316 +#ifndef _VSERVER_DEVICE_DEF_H
10317 +#define _VSERVER_DEVICE_DEF_H
10318 +
10319 +#include <linux/types.h>
10320 +
10321 +struct vx_dmap_target {
10322 +       dev_t target;
10323 +       uint32_t flags;
10324 +};
10325 +
10326 +struct _vx_device {
10327 +#ifdef CONFIG_VSERVER_DEVICE
10328 +       struct vx_dmap_target targets[2];
10329 +#endif
10330 +};
10331 +
10332 +#endif /* _VSERVER_DEVICE_DEF_H */
10333 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/dlimit.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/dlimit.h
10334 --- linux-3.18.5/include/linux/vserver/dlimit.h 1970-01-01 00:00:00.000000000 +0000
10335 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/dlimit.h       2015-01-19 10:58:04.000000000 +0000
10336 @@ -0,0 +1,54 @@
10337 +#ifndef _VSERVER_DLIMIT_H
10338 +#define _VSERVER_DLIMIT_H
10339 +
10340 +#include "switch.h"
10341 +
10342 +
10343 +#ifdef __KERNEL__
10344 +
10345 +/*      keep in sync with CDLIM_INFINITY       */
10346 +
10347 +#define DLIM_INFINITY          (~0ULL)
10348 +
10349 +#include <linux/spinlock.h>
10350 +#include <linux/rcupdate.h>
10351 +
10352 +struct super_block;
10353 +
10354 +struct dl_info {
10355 +       struct hlist_node dl_hlist;             /* linked list of contexts */
10356 +       struct rcu_head dl_rcu;                 /* the rcu head */
10357 +       vtag_t dl_tag;                          /* context tag */
10358 +       atomic_t dl_usecnt;                     /* usage count */
10359 +       atomic_t dl_refcnt;                     /* reference count */
10360 +
10361 +       struct super_block *dl_sb;              /* associated superblock */
10362 +
10363 +       spinlock_t dl_lock;                     /* protect the values */
10364 +
10365 +       unsigned long long dl_space_used;       /* used space in bytes */
10366 +       unsigned long long dl_space_total;      /* maximum space in bytes */
10367 +       unsigned long dl_inodes_used;           /* used inodes */
10368 +       unsigned long dl_inodes_total;          /* maximum inodes */
10369 +
10370 +       unsigned int dl_nrlmult;                /* non root limit mult */
10371 +};
10372 +
10373 +struct rcu_head;
10374 +
10375 +extern void rcu_free_dl_info(struct rcu_head *);
10376 +extern void unhash_dl_info(struct dl_info *);
10377 +
10378 +extern struct dl_info *locate_dl_info(struct super_block *, vtag_t);
10379 +
10380 +
10381 +struct kstatfs;
10382 +
10383 +extern void vx_vsi_statfs(struct super_block *, struct kstatfs *);
10384 +
10385 +typedef uint64_t dlsize_t;
10386 +
10387 +#endif /* __KERNEL__ */
10388 +#else  /* _VSERVER_DLIMIT_H */
10389 +#warning duplicate inclusion
10390 +#endif /* _VSERVER_DLIMIT_H */
10391 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/dlimit_cmd.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/dlimit_cmd.h
10392 --- linux-3.18.5/include/linux/vserver/dlimit_cmd.h     1970-01-01 00:00:00.000000000 +0000
10393 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/dlimit_cmd.h   2015-01-19 10:58:04.000000000 +0000
10394 @@ -0,0 +1,46 @@
10395 +#ifndef _VSERVER_DLIMIT_CMD_H
10396 +#define _VSERVER_DLIMIT_CMD_H
10397 +
10398 +#include <uapi/vserver/dlimit_cmd.h>
10399 +
10400 +
10401 +#ifdef CONFIG_COMPAT
10402 +
10403 +#include <asm/compat.h>
10404 +
10405 +struct vcmd_ctx_dlimit_base_v0_x32 {
10406 +       compat_uptr_t name_ptr;
10407 +       uint32_t flags;
10408 +};
10409 +
10410 +struct vcmd_ctx_dlimit_v0_x32 {
10411 +       compat_uptr_t name_ptr;
10412 +       uint32_t space_used;                    /* used space in kbytes */
10413 +       uint32_t space_total;                   /* maximum space in kbytes */
10414 +       uint32_t inodes_used;                   /* used inodes */
10415 +       uint32_t inodes_total;                  /* maximum inodes */
10416 +       uint32_t reserved;                      /* reserved for root in % */
10417 +       uint32_t flags;
10418 +};
10419 +
10420 +#endif /* CONFIG_COMPAT */
10421 +
10422 +#include <linux/compiler.h>
10423 +
10424 +extern int vc_add_dlimit(uint32_t, void __user *);
10425 +extern int vc_rem_dlimit(uint32_t, void __user *);
10426 +
10427 +extern int vc_set_dlimit(uint32_t, void __user *);
10428 +extern int vc_get_dlimit(uint32_t, void __user *);
10429 +
10430 +#ifdef CONFIG_COMPAT
10431 +
10432 +extern int vc_add_dlimit_x32(uint32_t, void __user *);
10433 +extern int vc_rem_dlimit_x32(uint32_t, void __user *);
10434 +
10435 +extern int vc_set_dlimit_x32(uint32_t, void __user *);
10436 +extern int vc_get_dlimit_x32(uint32_t, void __user *);
10437 +
10438 +#endif /* CONFIG_COMPAT */
10439 +
10440 +#endif /* _VSERVER_DLIMIT_CMD_H */
10441 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/global.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/global.h
10442 --- linux-3.18.5/include/linux/vserver/global.h 1970-01-01 00:00:00.000000000 +0000
10443 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/global.h       2015-01-19 10:58:04.000000000 +0000
10444 @@ -0,0 +1,19 @@
10445 +#ifndef _VSERVER_GLOBAL_H
10446 +#define _VSERVER_GLOBAL_H
10447 +
10448 +
10449 +extern atomic_t vx_global_ctotal;
10450 +extern atomic_t vx_global_cactive;
10451 +
10452 +extern atomic_t nx_global_ctotal;
10453 +extern atomic_t nx_global_cactive;
10454 +
10455 +extern atomic_t vs_global_nsproxy;
10456 +extern atomic_t vs_global_fs;
10457 +extern atomic_t vs_global_mnt_ns;
10458 +extern atomic_t vs_global_uts_ns;
10459 +extern atomic_t vs_global_user_ns;
10460 +extern atomic_t vs_global_pid_ns;
10461 +
10462 +
10463 +#endif /* _VSERVER_GLOBAL_H */
10464 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/history.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/history.h
10465 --- linux-3.18.5/include/linux/vserver/history.h        1970-01-01 00:00:00.000000000 +0000
10466 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/history.h      2015-01-19 10:58:04.000000000 +0000
10467 @@ -0,0 +1,197 @@
10468 +#ifndef _VSERVER_HISTORY_H
10469 +#define _VSERVER_HISTORY_H
10470 +
10471 +
10472 +enum {
10473 +       VXH_UNUSED = 0,
10474 +       VXH_THROW_OOPS = 1,
10475 +
10476 +       VXH_GET_VX_INFO,
10477 +       VXH_PUT_VX_INFO,
10478 +       VXH_INIT_VX_INFO,
10479 +       VXH_SET_VX_INFO,
10480 +       VXH_CLR_VX_INFO,
10481 +       VXH_CLAIM_VX_INFO,
10482 +       VXH_RELEASE_VX_INFO,
10483 +       VXH_ALLOC_VX_INFO,
10484 +       VXH_DEALLOC_VX_INFO,
10485 +       VXH_HASH_VX_INFO,
10486 +       VXH_UNHASH_VX_INFO,
10487 +       VXH_LOC_VX_INFO,
10488 +       VXH_LOOKUP_VX_INFO,
10489 +       VXH_CREATE_VX_INFO,
10490 +};
10491 +
10492 +struct _vxhe_vxi {
10493 +       struct vx_info *ptr;
10494 +       unsigned xid;
10495 +       unsigned usecnt;
10496 +       unsigned tasks;
10497 +};
10498 +
10499 +struct _vxhe_set_clr {
10500 +       void *data;
10501 +};
10502 +
10503 +struct _vxhe_loc_lookup {
10504 +       unsigned arg;
10505 +};
10506 +
10507 +struct _vx_hist_entry {
10508 +       void *loc;
10509 +       unsigned short seq;
10510 +       unsigned short type;
10511 +       struct _vxhe_vxi vxi;
10512 +       union {
10513 +               struct _vxhe_set_clr sc;
10514 +               struct _vxhe_loc_lookup ll;
10515 +       };
10516 +};
10517 +
10518 +#ifdef CONFIG_VSERVER_HISTORY
10519 +
10520 +extern unsigned volatile int vxh_active;
10521 +
10522 +struct _vx_hist_entry *vxh_advance(void *loc);
10523 +
10524 +
10525 +static inline
10526 +void   __vxh_copy_vxi(struct _vx_hist_entry *entry, struct vx_info *vxi)
10527 +{
10528 +       entry->vxi.ptr = vxi;
10529 +       if (vxi) {
10530 +               entry->vxi.usecnt = atomic_read(&vxi->vx_usecnt);
10531 +               entry->vxi.tasks = atomic_read(&vxi->vx_tasks);
10532 +               entry->vxi.xid = vxi->vx_id;
10533 +       }
10534 +}
10535 +
10536 +
10537 +#define        __HERE__ current_text_addr()
10538 +
10539 +#define __VXH_BODY(__type, __data, __here)     \
10540 +       struct _vx_hist_entry *entry;           \
10541 +                                               \
10542 +       preempt_disable();                      \
10543 +       entry = vxh_advance(__here);            \
10544 +       __data;                                 \
10545 +       entry->type = __type;                   \
10546 +       preempt_enable();
10547 +
10548 +
10549 +       /* pass vxi only */
10550 +
10551 +#define __VXH_SMPL                             \
10552 +       __vxh_copy_vxi(entry, vxi)
10553 +
10554 +static inline
10555 +void   __vxh_smpl(struct vx_info *vxi, int __type, void *__here)
10556 +{
10557 +       __VXH_BODY(__type, __VXH_SMPL, __here)
10558 +}
10559 +
10560 +       /* pass vxi and data (void *) */
10561 +
10562 +#define __VXH_DATA                             \
10563 +       __vxh_copy_vxi(entry, vxi);             \
10564 +       entry->sc.data = data
10565 +
10566 +static inline
10567 +void   __vxh_data(struct vx_info *vxi, void *data,
10568 +                       int __type, void *__here)
10569 +{
10570 +       __VXH_BODY(__type, __VXH_DATA, __here)
10571 +}
10572 +
10573 +       /* pass vxi and arg (long) */
10574 +
10575 +#define __VXH_LONG                             \
10576 +       __vxh_copy_vxi(entry, vxi);             \
10577 +       entry->ll.arg = arg
10578 +
10579 +static inline
10580 +void   __vxh_long(struct vx_info *vxi, long arg,
10581 +                       int __type, void *__here)
10582 +{
10583 +       __VXH_BODY(__type, __VXH_LONG, __here)
10584 +}
10585 +
10586 +
10587 +static inline
10588 +void   __vxh_throw_oops(void *__here)
10589 +{
10590 +       __VXH_BODY(VXH_THROW_OOPS, {}, __here);
10591 +       /* prevent further acquisition */
10592 +       vxh_active = 0;
10593 +}
10594 +
10595 +
10596 +#define vxh_throw_oops()       __vxh_throw_oops(__HERE__);
10597 +
10598 +#define __vxh_get_vx_info(v, h)        __vxh_smpl(v, VXH_GET_VX_INFO, h);
10599 +#define __vxh_put_vx_info(v, h)        __vxh_smpl(v, VXH_PUT_VX_INFO, h);
10600 +
10601 +#define __vxh_init_vx_info(v, d, h) \
10602 +       __vxh_data(v, d, VXH_INIT_VX_INFO, h);
10603 +#define __vxh_set_vx_info(v, d, h) \
10604 +       __vxh_data(v, d, VXH_SET_VX_INFO, h);
10605 +#define __vxh_clr_vx_info(v, d, h) \
10606 +       __vxh_data(v, d, VXH_CLR_VX_INFO, h);
10607 +
10608 +#define __vxh_claim_vx_info(v, d, h) \
10609 +       __vxh_data(v, d, VXH_CLAIM_VX_INFO, h);
10610 +#define __vxh_release_vx_info(v, d, h) \
10611 +       __vxh_data(v, d, VXH_RELEASE_VX_INFO, h);
10612 +
10613 +#define vxh_alloc_vx_info(v) \
10614 +       __vxh_smpl(v, VXH_ALLOC_VX_INFO, __HERE__);
10615 +#define vxh_dealloc_vx_info(v) \
10616 +       __vxh_smpl(v, VXH_DEALLOC_VX_INFO, __HERE__);
10617 +
10618 +#define vxh_hash_vx_info(v) \
10619 +       __vxh_smpl(v, VXH_HASH_VX_INFO, __HERE__);
10620 +#define vxh_unhash_vx_info(v) \
10621 +       __vxh_smpl(v, VXH_UNHASH_VX_INFO, __HERE__);
10622 +
10623 +#define vxh_loc_vx_info(v, l) \
10624 +       __vxh_long(v, l, VXH_LOC_VX_INFO, __HERE__);
10625 +#define vxh_lookup_vx_info(v, l) \
10626 +       __vxh_long(v, l, VXH_LOOKUP_VX_INFO, __HERE__);
10627 +#define vxh_create_vx_info(v, l) \
10628 +       __vxh_long(v, l, VXH_CREATE_VX_INFO, __HERE__);
10629 +
10630 +extern void vxh_dump_history(void);
10631 +
10632 +
10633 +#else  /* CONFIG_VSERVER_HISTORY */
10634 +
10635 +#define        __HERE__        0
10636 +
10637 +#define vxh_throw_oops()               do { } while (0)
10638 +
10639 +#define __vxh_get_vx_info(v, h)                do { } while (0)
10640 +#define __vxh_put_vx_info(v, h)                do { } while (0)
10641 +
10642 +#define __vxh_init_vx_info(v, d, h)    do { } while (0)
10643 +#define __vxh_set_vx_info(v, d, h)     do { } while (0)
10644 +#define __vxh_clr_vx_info(v, d, h)     do { } while (0)
10645 +
10646 +#define __vxh_claim_vx_info(v, d, h)   do { } while (0)
10647 +#define __vxh_release_vx_info(v, d, h) do { } while (0)
10648 +
10649 +#define vxh_alloc_vx_info(v)           do { } while (0)
10650 +#define vxh_dealloc_vx_info(v)         do { } while (0)
10651 +
10652 +#define vxh_hash_vx_info(v)            do { } while (0)
10653 +#define vxh_unhash_vx_info(v)          do { } while (0)
10654 +
10655 +#define vxh_loc_vx_info(v, l)          do { } while (0)
10656 +#define vxh_lookup_vx_info(v, l)       do { } while (0)
10657 +#define vxh_create_vx_info(v, l)       do { } while (0)
10658 +
10659 +#define vxh_dump_history()             do { } while (0)
10660 +
10661 +
10662 +#endif /* CONFIG_VSERVER_HISTORY */
10663 +
10664 +#endif /* _VSERVER_HISTORY_H */
10665 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/inode.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/inode.h
10666 --- linux-3.18.5/include/linux/vserver/inode.h  1970-01-01 00:00:00.000000000 +0000
10667 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/inode.h        2015-01-19 10:58:04.000000000 +0000
10668 @@ -0,0 +1,19 @@
10669 +#ifndef _VSERVER_INODE_H
10670 +#define _VSERVER_INODE_H
10671 +
10672 +#include <uapi/vserver/inode.h>
10673 +
10674 +
10675 +#ifdef CONFIG_VSERVER_PROC_SECURE
10676 +#define IATTR_PROC_DEFAULT     ( IATTR_ADMIN | IATTR_HIDE )
10677 +#define IATTR_PROC_SYMLINK     ( IATTR_ADMIN )
10678 +#else
10679 +#define IATTR_PROC_DEFAULT     ( IATTR_ADMIN )
10680 +#define IATTR_PROC_SYMLINK     ( IATTR_ADMIN )
10681 +#endif
10682 +
10683 +#define vx_hide_check(c, m)    (((m) & IATTR_HIDE) ? vx_check(c, m) : 1)
10684 +
10685 +#else  /* _VSERVER_INODE_H */
10686 +#warning duplicate inclusion
10687 +#endif /* _VSERVER_INODE_H */
10688 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/inode_cmd.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/inode_cmd.h
10689 --- linux-3.18.5/include/linux/vserver/inode_cmd.h      1970-01-01 00:00:00.000000000 +0000
10690 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/inode_cmd.h    2015-01-19 10:58:04.000000000 +0000
10691 @@ -0,0 +1,36 @@
10692 +#ifndef _VSERVER_INODE_CMD_H
10693 +#define _VSERVER_INODE_CMD_H
10694 +
10695 +#include <uapi/vserver/inode_cmd.h>
10696 +
10697 +
10698 +
10699 +#ifdef CONFIG_COMPAT
10700 +
10701 +#include <asm/compat.h>
10702 +
10703 +struct vcmd_ctx_iattr_v1_x32 {
10704 +       compat_uptr_t name_ptr;
10705 +       uint32_t tag;
10706 +       uint32_t flags;
10707 +       uint32_t mask;
10708 +};
10709 +
10710 +#endif /* CONFIG_COMPAT */
10711 +
10712 +#include <linux/compiler.h>
10713 +
10714 +extern int vc_get_iattr(void __user *);
10715 +extern int vc_set_iattr(void __user *);
10716 +
10717 +extern int vc_fget_iattr(uint32_t, void __user *);
10718 +extern int vc_fset_iattr(uint32_t, void __user *);
10719 +
10720 +#ifdef CONFIG_COMPAT
10721 +
10722 +extern int vc_get_iattr_x32(void __user *);
10723 +extern int vc_set_iattr_x32(void __user *);
10724 +
10725 +#endif /* CONFIG_COMPAT */
10726 +
10727 +#endif /* _VSERVER_INODE_CMD_H */
10728 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/limit.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/limit.h
10729 --- linux-3.18.5/include/linux/vserver/limit.h  1970-01-01 00:00:00.000000000 +0000
10730 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/limit.h        2015-01-19 10:58:04.000000000 +0000
10731 @@ -0,0 +1,61 @@
10732 +#ifndef _VSERVER_LIMIT_H
10733 +#define _VSERVER_LIMIT_H
10734 +
10735 +#include <uapi/vserver/limit.h>
10736 +
10737 +
10738 +#define        VLIM_NOCHECK    ((1L << VLIMIT_DENTRY) | (1L << RLIMIT_RSS))
10739 +
10740 +/*     keep in sync with CRLIM_INFINITY */
10741 +
10742 +#define        VLIM_INFINITY   (~0ULL)
10743 +
10744 +#include <asm/atomic.h>
10745 +#include <asm/resource.h>
10746 +
10747 +#ifndef RLIM_INFINITY
10748 +#warning RLIM_INFINITY is undefined
10749 +#endif
10750 +
10751 +#define __rlim_val(l, r, v)    ((l)->res[r].v)
10752 +
10753 +#define __rlim_soft(l, r)      __rlim_val(l, r, soft)
10754 +#define __rlim_hard(l, r)      __rlim_val(l, r, hard)
10755 +
10756 +#define __rlim_rcur(l, r)      __rlim_val(l, r, rcur)
10757 +#define __rlim_rmin(l, r)      __rlim_val(l, r, rmin)
10758 +#define __rlim_rmax(l, r)      __rlim_val(l, r, rmax)
10759 +
10760 +#define __rlim_lhit(l, r)      __rlim_val(l, r, lhit)
10761 +#define __rlim_hit(l, r)       atomic_inc(&__rlim_lhit(l, r))
10762 +
10763 +typedef atomic_long_t rlim_atomic_t;
10764 +typedef unsigned long rlim_t;
10765 +
10766 +#define __rlim_get(l, r)       atomic_long_read(&__rlim_rcur(l, r))
10767 +#define __rlim_set(l, r, v)    atomic_long_set(&__rlim_rcur(l, r), v)
10768 +#define __rlim_inc(l, r)       atomic_long_inc(&__rlim_rcur(l, r))
10769 +#define __rlim_dec(l, r)       atomic_long_dec(&__rlim_rcur(l, r))
10770 +#define __rlim_add(l, r, v)    atomic_long_add(v, &__rlim_rcur(l, r))
10771 +#define __rlim_sub(l, r, v)    atomic_long_sub(v, &__rlim_rcur(l, r))
10772 +
10773 +
10774 +#if    (RLIM_INFINITY == VLIM_INFINITY)
10775 +#define        VX_VLIM(r) ((long long)(long)(r))
10776 +#define        VX_RLIM(v) ((rlim_t)(v))
10777 +#else
10778 +#define        VX_VLIM(r) (((r) == RLIM_INFINITY) \
10779 +               ? VLIM_INFINITY : (long long)(r))
10780 +#define        VX_RLIM(v) (((v) == VLIM_INFINITY) \
10781 +               ? RLIM_INFINITY : (rlim_t)(v))
10782 +#endif
10783 +
10784 +struct sysinfo;
10785 +
10786 +void vx_vsi_meminfo(struct sysinfo *);
10787 +void vx_vsi_swapinfo(struct sysinfo *);
10788 +long vx_vsi_cached(struct sysinfo *);
10789 +
10790 +#define NUM_LIMITS     24
10791 +
10792 +#endif /* _VSERVER_LIMIT_H */
10793 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/limit_cmd.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/limit_cmd.h
10794 --- linux-3.18.5/include/linux/vserver/limit_cmd.h      1970-01-01 00:00:00.000000000 +0000
10795 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/limit_cmd.h    2015-01-19 10:58:04.000000000 +0000
10796 @@ -0,0 +1,35 @@
10797 +#ifndef _VSERVER_LIMIT_CMD_H
10798 +#define _VSERVER_LIMIT_CMD_H
10799 +
10800 +#include <uapi/vserver/limit_cmd.h>
10801 +
10802 +
10803 +#ifdef CONFIG_IA32_EMULATION
10804 +
10805 +struct vcmd_ctx_rlimit_v0_x32 {
10806 +       uint32_t id;
10807 +       uint64_t minimum;
10808 +       uint64_t softlimit;
10809 +       uint64_t maximum;
10810 +} __attribute__ ((packed));
10811 +
10812 +#endif /* CONFIG_IA32_EMULATION */
10813 +
10814 +#include <linux/compiler.h>
10815 +
10816 +extern int vc_get_rlimit_mask(uint32_t, void __user *);
10817 +extern int vc_get_rlimit(struct vx_info *, void __user *);
10818 +extern int vc_set_rlimit(struct vx_info *, void __user *);
10819 +extern int vc_reset_hits(struct vx_info *, void __user *);
10820 +extern int vc_reset_minmax(struct vx_info *, void __user *);
10821 +
10822 +extern int vc_rlimit_stat(struct vx_info *, void __user *);
10823 +
10824 +#ifdef CONFIG_IA32_EMULATION
10825 +
10826 +extern int vc_get_rlimit_x32(struct vx_info *, void __user *);
10827 +extern int vc_set_rlimit_x32(struct vx_info *, void __user *);
10828 +
10829 +#endif /* CONFIG_IA32_EMULATION */
10830 +
10831 +#endif /* _VSERVER_LIMIT_CMD_H */
10832 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/limit_def.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/limit_def.h
10833 --- linux-3.18.5/include/linux/vserver/limit_def.h      1970-01-01 00:00:00.000000000 +0000
10834 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/limit_def.h    2015-01-19 10:58:04.000000000 +0000
10835 @@ -0,0 +1,47 @@
10836 +#ifndef _VSERVER_LIMIT_DEF_H
10837 +#define _VSERVER_LIMIT_DEF_H
10838 +
10839 +#include <asm/atomic.h>
10840 +#include <asm/resource.h>
10841 +
10842 +#include "limit.h"
10843 +
10844 +
10845 +struct _vx_res_limit {
10846 +       rlim_t soft;            /* Context soft limit */
10847 +       rlim_t hard;            /* Context hard limit */
10848 +
10849 +       rlim_atomic_t rcur;     /* Current value */
10850 +       rlim_t rmin;            /* Context minimum */
10851 +       rlim_t rmax;            /* Context maximum */
10852 +
10853 +       atomic_t lhit;          /* Limit hits */
10854 +};
10855 +
10856 +/* context sub struct */
10857 +
10858 +struct _vx_limit {
10859 +       struct _vx_res_limit res[NUM_LIMITS];
10860 +};
10861 +
10862 +#ifdef CONFIG_VSERVER_DEBUG
10863 +
10864 +static inline void __dump_vx_limit(struct _vx_limit *limit)
10865 +{
10866 +       int i;
10867 +
10868 +       printk("\t_vx_limit:");
10869 +       for (i = 0; i < NUM_LIMITS; i++) {
10870 +               printk("\t [%2d] = %8lu %8lu/%8lu, %8ld/%8ld, %8d\n",
10871 +                       i, (unsigned long)__rlim_get(limit, i),
10872 +                       (unsigned long)__rlim_rmin(limit, i),
10873 +                       (unsigned long)__rlim_rmax(limit, i),
10874 +                       (long)__rlim_soft(limit, i),
10875 +                       (long)__rlim_hard(limit, i),
10876 +                       atomic_read(&__rlim_lhit(limit, i)));
10877 +       }
10878 +}
10879 +
10880 +#endif
10881 +
10882 +#endif /* _VSERVER_LIMIT_DEF_H */
10883 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/limit_int.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/limit_int.h
10884 --- linux-3.18.5/include/linux/vserver/limit_int.h      1970-01-01 00:00:00.000000000 +0000
10885 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/limit_int.h    2015-01-19 10:58:04.000000000 +0000
10886 @@ -0,0 +1,193 @@
10887 +#ifndef _VSERVER_LIMIT_INT_H
10888 +#define _VSERVER_LIMIT_INT_H
10889 +
10890 +#define VXD_RCRES_COND(r)      VXD_CBIT(cres, r)
10891 +#define VXD_RLIMIT_COND(r)     VXD_CBIT(limit, r)
10892 +
10893 +extern const char *vlimit_name[NUM_LIMITS];
10894 +
10895 +static inline void __vx_acc_cres(struct vx_info *vxi,
10896 +       int res, int dir, void *_data, char *_file, int _line)
10897 +{
10898 +       if (VXD_RCRES_COND(res))
10899 +               vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5ld%s (%p)",
10900 +                       (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10901 +                       (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10902 +                       (dir > 0) ? "++" : "--", _data, _file, _line);
10903 +       if (!vxi)
10904 +               return;
10905 +
10906 +       if (dir > 0)
10907 +               __rlim_inc(&vxi->limit, res);
10908 +       else
10909 +               __rlim_dec(&vxi->limit, res);
10910 +}
10911 +
10912 +static inline void __vx_add_cres(struct vx_info *vxi,
10913 +       int res, int amount, void *_data, char *_file, int _line)
10914 +{
10915 +       if (VXD_RCRES_COND(res))
10916 +               vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5ld += %5d (%p)",
10917 +                       (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10918 +                       (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10919 +                       amount, _data, _file, _line);
10920 +       if (amount == 0)
10921 +               return;
10922 +       if (!vxi)
10923 +               return;
10924 +       __rlim_add(&vxi->limit, res, amount);
10925 +}
10926 +
10927 +static inline
10928 +int __vx_cres_adjust_max(struct _vx_limit *limit, int res, rlim_t value)
10929 +{
10930 +       int cond = (value > __rlim_rmax(limit, res));
10931 +
10932 +       if (cond)
10933 +               __rlim_rmax(limit, res) = value;
10934 +       return cond;
10935 +}
10936 +
10937 +static inline
10938 +int __vx_cres_adjust_min(struct _vx_limit *limit, int res, rlim_t value)
10939 +{
10940 +       int cond = (value < __rlim_rmin(limit, res));
10941 +
10942 +       if (cond)
10943 +               __rlim_rmin(limit, res) = value;
10944 +       return cond;
10945 +}
10946 +
10947 +static inline
10948 +void __vx_cres_fixup(struct _vx_limit *limit, int res, rlim_t value)
10949 +{
10950 +       if (!__vx_cres_adjust_max(limit, res, value))
10951 +               __vx_cres_adjust_min(limit, res, value);
10952 +}
10953 +
10954 +
10955 +/*     return values:
10956 +        +1 ... no limit hit
10957 +        -1 ... over soft limit
10958 +         0 ... over hard limit         */
10959 +
10960 +static inline int __vx_cres_avail(struct vx_info *vxi,
10961 +       int res, int num, char *_file, int _line)
10962 +{
10963 +       struct _vx_limit *limit;
10964 +       rlim_t value;
10965 +
10966 +       if (VXD_RLIMIT_COND(res))
10967 +               vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld/%5ld > %5ld + %5d",
10968 +                       (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10969 +                       (vxi ? (long)__rlim_soft(&vxi->limit, res) : -1),
10970 +                       (vxi ? (long)__rlim_hard(&vxi->limit, res) : -1),
10971 +                       (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10972 +                       num, _file, _line);
10973 +       if (!vxi)
10974 +               return 1;
10975 +
10976 +       limit = &vxi->limit;
10977 +       value = __rlim_get(limit, res);
10978 +
10979 +       if (!__vx_cres_adjust_max(limit, res, value))
10980 +               __vx_cres_adjust_min(limit, res, value);
10981 +
10982 +       if (num == 0)
10983 +               return 1;
10984 +
10985 +       if (__rlim_soft(limit, res) == RLIM_INFINITY)
10986 +               return -1;
10987 +       if (value + num <= __rlim_soft(limit, res))
10988 +               return -1;
10989 +
10990 +       if (__rlim_hard(limit, res) == RLIM_INFINITY)
10991 +               return 1;
10992 +       if (value + num <= __rlim_hard(limit, res))
10993 +               return 1;
10994 +
10995 +       __rlim_hit(limit, res);
10996 +       return 0;
10997 +}
10998 +
10999 +
11000 +static const int VLA_RSS[] = { RLIMIT_RSS, VLIMIT_ANON, VLIMIT_MAPPED, 0 };
11001 +
11002 +static inline
11003 +rlim_t __vx_cres_array_sum(struct _vx_limit *limit, const int *array)
11004 +{
11005 +       rlim_t value, sum = 0;
11006 +       int res;
11007 +
11008 +       while ((res = *array++)) {
11009 +               value = __rlim_get(limit, res);
11010 +               __vx_cres_fixup(limit, res, value);
11011 +               sum += value;
11012 +       }
11013 +       return sum;
11014 +}
11015 +
11016 +static inline
11017 +rlim_t __vx_cres_array_fixup(struct _vx_limit *limit, const int *array)
11018 +{
11019 +       rlim_t value = __vx_cres_array_sum(limit, array + 1);
11020 +       int res = *array;
11021 +
11022 +       if (value == __rlim_get(limit, res))
11023 +               return value;
11024 +
11025 +       __rlim_set(limit, res, value);
11026 +       /* now adjust min/max */
11027 +       if (!__vx_cres_adjust_max(limit, res, value))
11028 +               __vx_cres_adjust_min(limit, res, value);
11029 +
11030 +       return value;
11031 +}
11032 +
11033 +static inline int __vx_cres_array_avail(struct vx_info *vxi,
11034 +       const int *array, int num, char *_file, int _line)
11035 +{
11036 +       struct _vx_limit *limit;
11037 +       rlim_t value = 0;
11038 +       int res;
11039 +
11040 +       if (num == 0)
11041 +               return 1;
11042 +       if (!vxi)
11043 +               return 1;
11044 +
11045 +       limit = &vxi->limit;
11046 +       res = *array;
11047 +       value = __vx_cres_array_sum(limit, array + 1);
11048 +
11049 +       __rlim_set(limit, res, value);
11050 +       __vx_cres_fixup(limit, res, value);
11051 +
11052 +       return __vx_cres_avail(vxi, res, num, _file, _line);
11053 +}
11054 +
11055 +
11056 +static inline void vx_limit_fixup(struct _vx_limit *limit, int id)
11057 +{
11058 +       rlim_t value;
11059 +       int res;
11060 +
11061 +       /* complex resources first */
11062 +       if ((id < 0) || (id == RLIMIT_RSS))
11063 +               __vx_cres_array_fixup(limit, VLA_RSS);
11064 +
11065 +       for (res = 0; res < NUM_LIMITS; res++) {
11066 +               if ((id > 0) && (res != id))
11067 +                       continue;
11068 +
11069 +               value = __rlim_get(limit, res);
11070 +               __vx_cres_fixup(limit, res, value);
11071 +
11072 +               /* not supposed to happen, maybe warn? */
11073 +               if (__rlim_rmax(limit, res) > __rlim_hard(limit, res))
11074 +                       __rlim_rmax(limit, res) = __rlim_hard(limit, res);
11075 +       }
11076 +}
11077 +
11078 +
11079 +#endif /* _VSERVER_LIMIT_INT_H */
11080 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/monitor.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/monitor.h
11081 --- linux-3.18.5/include/linux/vserver/monitor.h        1970-01-01 00:00:00.000000000 +0000
11082 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/monitor.h      2015-01-19 10:58:04.000000000 +0000
11083 @@ -0,0 +1,6 @@
11084 +#ifndef _VSERVER_MONITOR_H
11085 +#define _VSERVER_MONITOR_H
11086 +
11087 +#include <uapi/vserver/monitor.h>
11088 +
11089 +#endif /* _VSERVER_MONITOR_H */
11090 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/network.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/network.h
11091 --- linux-3.18.5/include/linux/vserver/network.h        1970-01-01 00:00:00.000000000 +0000
11092 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/network.h      2015-01-19 10:58:04.000000000 +0000
11093 @@ -0,0 +1,76 @@
11094 +#ifndef _VSERVER_NETWORK_H
11095 +#define _VSERVER_NETWORK_H
11096 +
11097 +
11098 +#include <linux/list.h>
11099 +#include <linux/spinlock.h>
11100 +#include <linux/rcupdate.h>
11101 +#include <linux/in.h>
11102 +#include <linux/in6.h>
11103 +#include <asm/atomic.h>
11104 +#include <uapi/vserver/network.h>
11105 +
11106 +struct nx_addr_v4 {
11107 +       struct nx_addr_v4 *next;
11108 +       struct in_addr ip[2];
11109 +       struct in_addr mask;
11110 +       uint16_t type;
11111 +       uint16_t flags;
11112 +};
11113 +
11114 +struct nx_addr_v6 {
11115 +       struct nx_addr_v6 *next;
11116 +       struct in6_addr ip;
11117 +       struct in6_addr mask;
11118 +       uint32_t prefix;
11119 +       uint16_t type;
11120 +       uint16_t flags;
11121 +};
11122 +
11123 +struct nx_info {
11124 +       struct hlist_node nx_hlist;     /* linked list of nxinfos */
11125 +       vnid_t nx_id;                   /* vnet id */
11126 +       atomic_t nx_usecnt;             /* usage count */
11127 +       atomic_t nx_tasks;              /* tasks count */
11128 +       int nx_state;                   /* context state */
11129 +
11130 +       uint64_t nx_flags;              /* network flag word */
11131 +       uint64_t nx_ncaps;              /* network capabilities */
11132 +
11133 +       spinlock_t addr_lock;           /* protect address changes */
11134 +       struct in_addr v4_lback;        /* Loopback address */
11135 +       struct in_addr v4_bcast;        /* Broadcast address */
11136 +       struct nx_addr_v4 v4;           /* First/Single ipv4 address */
11137 +#ifdef CONFIG_IPV6
11138 +       struct nx_addr_v6 v6;           /* First/Single ipv6 address */
11139 +#endif
11140 +       char nx_name[65];               /* network context name */
11141 +};
11142 +
11143 +
11144 +/* status flags */
11145 +
11146 +#define NXS_HASHED      0x0001
11147 +#define NXS_SHUTDOWN    0x0100
11148 +#define NXS_RELEASED    0x8000
11149 +
11150 +extern struct nx_info *lookup_nx_info(int);
11151 +
11152 +extern int get_nid_list(int, unsigned int *, int);
11153 +extern int nid_is_hashed(vnid_t);
11154 +
11155 +extern int nx_migrate_task(struct task_struct *, struct nx_info *);
11156 +
11157 +extern long vs_net_change(struct nx_info *, unsigned int);
11158 +
11159 +struct sock;
11160 +
11161 +
11162 +#define NX_IPV4(n)     ((n)->v4.type != NXA_TYPE_NONE)
11163 +#ifdef  CONFIG_IPV6
11164 +#define NX_IPV6(n)     ((n)->v6.type != NXA_TYPE_NONE)
11165 +#else
11166 +#define NX_IPV6(n)     (0)
11167 +#endif
11168 +
11169 +#endif /* _VSERVER_NETWORK_H */
11170 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/network_cmd.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/network_cmd.h
11171 --- linux-3.18.5/include/linux/vserver/network_cmd.h    1970-01-01 00:00:00.000000000 +0000
11172 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/network_cmd.h  2015-01-19 10:58:04.000000000 +0000
11173 @@ -0,0 +1,37 @@
11174 +#ifndef _VSERVER_NETWORK_CMD_H
11175 +#define _VSERVER_NETWORK_CMD_H
11176 +
11177 +#include <uapi/vserver/network_cmd.h>
11178 +
11179 +extern int vc_task_nid(uint32_t);
11180 +
11181 +extern int vc_nx_info(struct nx_info *, void __user *);
11182 +
11183 +extern int vc_net_create(uint32_t, void __user *);
11184 +extern int vc_net_migrate(struct nx_info *, void __user *);
11185 +
11186 +extern int vc_net_add(struct nx_info *, void __user *);
11187 +extern int vc_net_remove(struct nx_info *, void __user *);
11188 +
11189 +extern int vc_net_add_ipv4_v1(struct nx_info *, void __user *);
11190 +extern int vc_net_add_ipv4(struct nx_info *, void __user *);
11191 +
11192 +extern int vc_net_rem_ipv4_v1(struct nx_info *, void __user *);
11193 +extern int vc_net_rem_ipv4(struct nx_info *, void __user *);
11194 +
11195 +extern int vc_net_add_ipv6(struct nx_info *, void __user *);
11196 +extern int vc_net_remove_ipv6(struct nx_info *, void __user *);
11197 +
11198 +extern int vc_add_match_ipv4(struct nx_info *, void __user *);
11199 +extern int vc_get_match_ipv4(struct nx_info *, void __user *);
11200 +
11201 +extern int vc_add_match_ipv6(struct nx_info *, void __user *);
11202 +extern int vc_get_match_ipv6(struct nx_info *, void __user *);
11203 +
11204 +extern int vc_get_nflags(struct nx_info *, void __user *);
11205 +extern int vc_set_nflags(struct nx_info *, void __user *);
11206 +
11207 +extern int vc_get_ncaps(struct nx_info *, void __user *);
11208 +extern int vc_set_ncaps(struct nx_info *, void __user *);
11209 +
11210 +#endif /* _VSERVER_CONTEXT_CMD_H */
11211 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/percpu.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/percpu.h
11212 --- linux-3.18.5/include/linux/vserver/percpu.h 1970-01-01 00:00:00.000000000 +0000
11213 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/percpu.h       2015-01-19 10:58:04.000000000 +0000
11214 @@ -0,0 +1,14 @@
11215 +#ifndef _VSERVER_PERCPU_H
11216 +#define _VSERVER_PERCPU_H
11217 +
11218 +#include "cvirt_def.h"
11219 +#include "sched_def.h"
11220 +
11221 +struct _vx_percpu {
11222 +       struct _vx_cvirt_pc cvirt;
11223 +       struct _vx_sched_pc sched;
11224 +};
11225 +
11226 +#define        PERCPU_PERCTX   (sizeof(struct _vx_percpu))
11227 +
11228 +#endif /* _VSERVER_PERCPU_H */
11229 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/pid.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/pid.h
11230 --- linux-3.18.5/include/linux/vserver/pid.h    1970-01-01 00:00:00.000000000 +0000
11231 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/pid.h  2015-01-19 10:58:04.000000000 +0000
11232 @@ -0,0 +1,51 @@
11233 +#ifndef _VSERVER_PID_H
11234 +#define _VSERVER_PID_H
11235 +
11236 +/* pid faking stuff */
11237 +
11238 +#define vx_info_map_pid(v, p) \
11239 +       __vx_info_map_pid((v), (p), __func__, __FILE__, __LINE__)
11240 +#define vx_info_map_tgid(v,p)  vx_info_map_pid(v,p)
11241 +#define vx_map_pid(p) vx_info_map_pid(current_vx_info(), p)
11242 +#define vx_map_tgid(p) vx_map_pid(p)
11243 +
11244 +static inline int __vx_info_map_pid(struct vx_info *vxi, int pid,
11245 +       const char *func, const char *file, int line)
11246 +{
11247 +       if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
11248 +               vxfprintk(VXD_CBIT(cvirt, 2),
11249 +                       "vx_map_tgid: %p/%llx: %d -> %d",
11250 +                       vxi, (long long)vxi->vx_flags, pid,
11251 +                       (pid && pid == vxi->vx_initpid) ? 1 : pid,
11252 +                       func, file, line);
11253 +               if (pid == 0)
11254 +                       return 0;
11255 +               if (pid == vxi->vx_initpid)
11256 +                       return 1;
11257 +       }
11258 +       return pid;
11259 +}
11260 +
11261 +#define vx_info_rmap_pid(v, p) \
11262 +       __vx_info_rmap_pid((v), (p), __func__, __FILE__, __LINE__)
11263 +#define vx_rmap_pid(p) vx_info_rmap_pid(current_vx_info(), p)
11264 +#define vx_rmap_tgid(p) vx_rmap_pid(p)
11265 +
11266 +static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid,
11267 +       const char *func, const char *file, int line)
11268 +{
11269 +       if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
11270 +               vxfprintk(VXD_CBIT(cvirt, 2),
11271 +                       "vx_rmap_tgid: %p/%llx: %d -> %d",
11272 +                       vxi, (long long)vxi->vx_flags, pid,
11273 +                       (pid == 1) ? vxi->vx_initpid : pid,
11274 +                       func, file, line);
11275 +               if ((pid == 1) && vxi->vx_initpid)
11276 +                       return vxi->vx_initpid;
11277 +               if (pid == vxi->vx_initpid)
11278 +                       return ~0U;
11279 +       }
11280 +       return pid;
11281 +}
11282 +
11283 +#endif
11284 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/sched.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/sched.h
11285 --- linux-3.18.5/include/linux/vserver/sched.h  1970-01-01 00:00:00.000000000 +0000
11286 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/sched.h        2015-01-19 10:58:04.000000000 +0000
11287 @@ -0,0 +1,23 @@
11288 +#ifndef _VSERVER_SCHED_H
11289 +#define _VSERVER_SCHED_H
11290 +
11291 +
11292 +#ifdef __KERNEL__
11293 +
11294 +struct timespec;
11295 +
11296 +void vx_vsi_uptime(struct timespec *, struct timespec *);
11297 +
11298 +
11299 +struct vx_info;
11300 +
11301 +void vx_update_load(struct vx_info *);
11302 +
11303 +
11304 +void vx_update_sched_param(struct _vx_sched *sched,
11305 +       struct _vx_sched_pc *sched_pc);
11306 +
11307 +#endif /* __KERNEL__ */
11308 +#else  /* _VSERVER_SCHED_H */
11309 +#warning duplicate inclusion
11310 +#endif /* _VSERVER_SCHED_H */
11311 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/sched_cmd.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/sched_cmd.h
11312 --- linux-3.18.5/include/linux/vserver/sched_cmd.h      1970-01-01 00:00:00.000000000 +0000
11313 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/sched_cmd.h    2015-01-19 10:58:04.000000000 +0000
11314 @@ -0,0 +1,11 @@
11315 +#ifndef _VSERVER_SCHED_CMD_H
11316 +#define _VSERVER_SCHED_CMD_H
11317 +
11318 +
11319 +#include <linux/compiler.h>
11320 +#include <uapi/vserver/sched_cmd.h>
11321 +
11322 +extern int vc_set_prio_bias(struct vx_info *, void __user *);
11323 +extern int vc_get_prio_bias(struct vx_info *, void __user *);
11324 +
11325 +#endif /* _VSERVER_SCHED_CMD_H */
11326 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/sched_def.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/sched_def.h
11327 --- linux-3.18.5/include/linux/vserver/sched_def.h      1970-01-01 00:00:00.000000000 +0000
11328 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/sched_def.h    2015-01-19 10:58:04.000000000 +0000
11329 @@ -0,0 +1,38 @@
11330 +#ifndef _VSERVER_SCHED_DEF_H
11331 +#define _VSERVER_SCHED_DEF_H
11332 +
11333 +#include <linux/spinlock.h>
11334 +#include <linux/jiffies.h>
11335 +#include <linux/cpumask.h>
11336 +#include <asm/atomic.h>
11337 +#include <asm/param.h>
11338 +
11339 +
11340 +/* context sub struct */
11341 +
11342 +struct _vx_sched {
11343 +       int prio_bias;                  /* bias offset for priority */
11344 +
11345 +       cpumask_t update;               /* CPUs which should update */
11346 +};
11347 +
11348 +struct _vx_sched_pc {
11349 +       int prio_bias;                  /* bias offset for priority */
11350 +
11351 +       uint64_t user_ticks;            /* token tick events */
11352 +       uint64_t sys_ticks;             /* token tick events */
11353 +       uint64_t hold_ticks;            /* token ticks paused */
11354 +};
11355 +
11356 +
11357 +#ifdef CONFIG_VSERVER_DEBUG
11358 +
11359 +static inline void __dump_vx_sched(struct _vx_sched *sched)
11360 +{
11361 +       printk("\t_vx_sched:\n");
11362 +       printk("\t priority = %4d\n", sched->prio_bias);
11363 +}
11364 +
11365 +#endif
11366 +
11367 +#endif /* _VSERVER_SCHED_DEF_H */
11368 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/signal.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/signal.h
11369 --- linux-3.18.5/include/linux/vserver/signal.h 1970-01-01 00:00:00.000000000 +0000
11370 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/signal.h       2015-01-19 10:58:04.000000000 +0000
11371 @@ -0,0 +1,14 @@
11372 +#ifndef _VSERVER_SIGNAL_H
11373 +#define _VSERVER_SIGNAL_H
11374 +
11375 +
11376 +#ifdef __KERNEL__
11377 +
11378 +struct vx_info;
11379 +
11380 +int vx_info_kill(struct vx_info *, int, int);
11381 +
11382 +#endif /* __KERNEL__ */
11383 +#else  /* _VSERVER_SIGNAL_H */
11384 +#warning duplicate inclusion
11385 +#endif /* _VSERVER_SIGNAL_H */
11386 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/signal_cmd.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/signal_cmd.h
11387 --- linux-3.18.5/include/linux/vserver/signal_cmd.h     1970-01-01 00:00:00.000000000 +0000
11388 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/signal_cmd.h   2015-01-19 10:58:04.000000000 +0000
11389 @@ -0,0 +1,14 @@
11390 +#ifndef _VSERVER_SIGNAL_CMD_H
11391 +#define _VSERVER_SIGNAL_CMD_H
11392 +
11393 +#include <uapi/vserver/signal_cmd.h>
11394 +
11395 +
11396 +extern int vc_ctx_kill(struct vx_info *, void __user *);
11397 +extern int vc_wait_exit(struct vx_info *, void __user *);
11398 +
11399 +
11400 +extern int vc_get_pflags(uint32_t pid, void __user *);
11401 +extern int vc_set_pflags(uint32_t pid, void __user *);
11402 +
11403 +#endif /* _VSERVER_SIGNAL_CMD_H */
11404 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/space.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/space.h
11405 --- linux-3.18.5/include/linux/vserver/space.h  1970-01-01 00:00:00.000000000 +0000
11406 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/space.h        2015-01-19 10:58:04.000000000 +0000
11407 @@ -0,0 +1,12 @@
11408 +#ifndef _VSERVER_SPACE_H
11409 +#define _VSERVER_SPACE_H
11410 +
11411 +#include <linux/types.h>
11412 +
11413 +struct vx_info;
11414 +
11415 +int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index);
11416 +
11417 +#else  /* _VSERVER_SPACE_H */
11418 +#warning duplicate inclusion
11419 +#endif /* _VSERVER_SPACE_H */
11420 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/space_cmd.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/space_cmd.h
11421 --- linux-3.18.5/include/linux/vserver/space_cmd.h      1970-01-01 00:00:00.000000000 +0000
11422 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/space_cmd.h    2015-01-19 10:58:04.000000000 +0000
11423 @@ -0,0 +1,13 @@
11424 +#ifndef _VSERVER_SPACE_CMD_H
11425 +#define _VSERVER_SPACE_CMD_H
11426 +
11427 +#include <uapi/vserver/space_cmd.h>
11428 +
11429 +
11430 +extern int vc_enter_space_v1(struct vx_info *, void __user *);
11431 +extern int vc_set_space_v1(struct vx_info *, void __user *);
11432 +extern int vc_enter_space(struct vx_info *, void __user *);
11433 +extern int vc_set_space(struct vx_info *, void __user *);
11434 +extern int vc_get_space_mask(void __user *, int);
11435 +
11436 +#endif /* _VSERVER_SPACE_CMD_H */
11437 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/switch.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/switch.h
11438 --- linux-3.18.5/include/linux/vserver/switch.h 1970-01-01 00:00:00.000000000 +0000
11439 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/switch.h       2015-01-19 10:58:04.000000000 +0000
11440 @@ -0,0 +1,8 @@
11441 +#ifndef _VSERVER_SWITCH_H
11442 +#define _VSERVER_SWITCH_H
11443 +
11444 +
11445 +#include <linux/errno.h>
11446 +#include <uapi/vserver/switch.h>
11447 +
11448 +#endif /* _VSERVER_SWITCH_H */
11449 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/tag.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/tag.h
11450 --- linux-3.18.5/include/linux/vserver/tag.h    1970-01-01 00:00:00.000000000 +0000
11451 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/tag.h  2015-01-19 10:58:04.000000000 +0000
11452 @@ -0,0 +1,160 @@
11453 +#ifndef _DX_TAG_H
11454 +#define _DX_TAG_H
11455 +
11456 +#include <linux/types.h>
11457 +#include <linux/uidgid.h>
11458 +
11459 +
11460 +#define DX_TAG(in)     (IS_TAGGED(in))
11461 +
11462 +
11463 +#ifdef CONFIG_TAG_NFSD
11464 +#define DX_TAG_NFSD    1
11465 +#else
11466 +#define DX_TAG_NFSD    0
11467 +#endif
11468 +
11469 +
11470 +#ifdef CONFIG_TAGGING_NONE
11471 +
11472 +#define MAX_UID                0xFFFFFFFF
11473 +#define MAX_GID                0xFFFFFFFF
11474 +
11475 +#define INOTAG_TAG(cond, uid, gid, tag)        (0)
11476 +
11477 +#define TAGINO_UID(cond, uid, tag)     (uid)
11478 +#define TAGINO_GID(cond, gid, tag)     (gid)
11479 +
11480 +#endif
11481 +
11482 +
11483 +#ifdef CONFIG_TAGGING_GID16
11484 +
11485 +#define MAX_UID                0xFFFFFFFF
11486 +#define MAX_GID                0x0000FFFF
11487 +
11488 +#define INOTAG_TAG(cond, uid, gid, tag)        \
11489 +       ((cond) ? (((gid) >> 16) & 0xFFFF) : 0)
11490 +
11491 +#define TAGINO_UID(cond, uid, tag)     (uid)
11492 +#define TAGINO_GID(cond, gid, tag)     \
11493 +       ((cond) ? (((gid) & 0xFFFF) | ((tag) << 16)) : (gid))
11494 +
11495 +#endif
11496 +
11497 +
11498 +#ifdef CONFIG_TAGGING_ID24
11499 +
11500 +#define MAX_UID                0x00FFFFFF
11501 +#define MAX_GID                0x00FFFFFF
11502 +
11503 +#define INOTAG_TAG(cond, uid, gid, tag)        \
11504 +       ((cond) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0)
11505 +
11506 +#define TAGINO_UID(cond, uid, tag)     \
11507 +       ((cond) ? (((uid) & 0xFFFFFF) | (((tag) & 0xFF00) << 16)) : (uid))
11508 +#define TAGINO_GID(cond, gid, tag)     \
11509 +       ((cond) ? (((gid) & 0xFFFFFF) | (((tag) & 0x00FF) << 24)) : (gid))
11510 +
11511 +#endif
11512 +
11513 +
11514 +#ifdef CONFIG_TAGGING_UID16
11515 +
11516 +#define MAX_UID                0x0000FFFF
11517 +#define MAX_GID                0xFFFFFFFF
11518 +
11519 +#define INOTAG_TAG(cond, uid, gid, tag)        \
11520 +       ((cond) ? (((uid) >> 16) & 0xFFFF) : 0)
11521 +
11522 +#define TAGINO_UID(cond, uid, tag)     \
11523 +       ((cond) ? (((uid) & 0xFFFF) | ((tag) << 16)) : (uid))
11524 +#define TAGINO_GID(cond, gid, tag)     (gid)
11525 +
11526 +#endif
11527 +
11528 +
11529 +#ifdef CONFIG_TAGGING_INTERN
11530 +
11531 +#define MAX_UID                0xFFFFFFFF
11532 +#define MAX_GID                0xFFFFFFFF
11533 +
11534 +#define INOTAG_TAG(cond, uid, gid, tag)        \
11535 +       ((cond) ? (tag) : 0)
11536 +
11537 +#define TAGINO_UID(cond, uid, tag)     (uid)
11538 +#define TAGINO_GID(cond, gid, tag)     (gid)
11539 +
11540 +#endif
11541 +
11542 +
11543 +#ifndef CONFIG_TAGGING_NONE
11544 +#define dx_current_fstag(sb)   \
11545 +       ((sb)->s_flags & MS_TAGGED ? dx_current_tag() : 0)
11546 +#else
11547 +#define dx_current_fstag(sb)   (0)
11548 +#endif
11549 +
11550 +#ifndef CONFIG_TAGGING_INTERN
11551 +#define TAGINO_TAG(cond, tag)  (0)
11552 +#else
11553 +#define TAGINO_TAG(cond, tag)  ((cond) ? (tag) : 0)
11554 +#endif
11555 +
11556 +#define TAGINO_KUID(cond, kuid, ktag)  \
11557 +       KUIDT_INIT(TAGINO_UID(cond, __kuid_val(kuid), __ktag_val(ktag)))
11558 +#define TAGINO_KGID(cond, kgid, ktag)  \
11559 +       KGIDT_INIT(TAGINO_GID(cond, __kgid_val(kgid), __ktag_val(ktag)))
11560 +#define TAGINO_KTAG(cond, ktag)                \
11561 +       KTAGT_INIT(TAGINO_TAG(cond, __ktag_val(ktag)))
11562 +
11563 +
11564 +#define INOTAG_UID(cond, uid, gid)     \
11565 +       ((cond) ? ((uid) & MAX_UID) : (uid))
11566 +#define INOTAG_GID(cond, uid, gid)     \
11567 +       ((cond) ? ((gid) & MAX_GID) : (gid))
11568 +
11569 +#define INOTAG_KUID(cond, kuid, kgid)  \
11570 +       KUIDT_INIT(INOTAG_UID(cond, __kuid_val(kuid), __kgid_val(kgid)))
11571 +#define INOTAG_KGID(cond, kuid, kgid)  \
11572 +       KGIDT_INIT(INOTAG_GID(cond, __kuid_val(kuid), __kgid_val(kgid)))
11573 +#define INOTAG_KTAG(cond, kuid, kgid, ktag) \
11574 +       KTAGT_INIT(INOTAG_TAG(cond, \
11575 +               __kuid_val(kuid), __kgid_val(kgid), __ktag_val(ktag)))
11576 +
11577 +
11578 +static inline uid_t dx_map_uid(uid_t uid)
11579 +{
11580 +       if ((uid > MAX_UID) && (uid != -1))
11581 +               uid = -2;
11582 +       return (uid & MAX_UID);
11583 +}
11584 +
11585 +static inline gid_t dx_map_gid(gid_t gid)
11586 +{
11587 +       if ((gid > MAX_GID) && (gid != -1))
11588 +               gid = -2;
11589 +       return (gid & MAX_GID);
11590 +}
11591 +
11592 +struct peer_tag {
11593 +       int32_t xid;
11594 +       int32_t nid;
11595 +};
11596 +
11597 +#define dx_notagcheck(sb) ((sb) && ((sb)->s_flags & MS_NOTAGCHECK))
11598 +
11599 +int dx_parse_tag(char *string, vtag_t *tag, int remove, int *mnt_flags,
11600 +                unsigned long *flags);
11601 +
11602 +#ifdef CONFIG_PROPAGATE
11603 +
11604 +void __dx_propagate_tag(struct nameidata *nd, struct inode *inode);
11605 +
11606 +#define dx_propagate_tag(n, i) __dx_propagate_tag(n, i)
11607 +
11608 +#else
11609 +#define dx_propagate_tag(n, i) do { } while (0)
11610 +#endif
11611 +
11612 +#endif /* _DX_TAG_H */
11613 diff -NurpP --minimal linux-3.18.5/include/linux/vserver/tag_cmd.h linux-3.18.5-vs2.3.7.3/include/linux/vserver/tag_cmd.h
11614 --- linux-3.18.5/include/linux/vserver/tag_cmd.h        1970-01-01 00:00:00.000000000 +0000
11615 +++ linux-3.18.5-vs2.3.7.3/include/linux/vserver/tag_cmd.h      2015-01-19 10:58:04.000000000 +0000
11616 @@ -0,0 +1,10 @@
11617 +#ifndef _VSERVER_TAG_CMD_H
11618 +#define _VSERVER_TAG_CMD_H
11619 +
11620 +#include <uapi/vserver/tag_cmd.h>
11621 +
11622 +extern int vc_task_tag(uint32_t);
11623 +
11624 +extern int vc_tag_migrate(uint32_t);
11625 +
11626 +#endif /* _VSERVER_TAG_CMD_H */
11627 diff -NurpP --minimal linux-3.18.5/include/net/addrconf.h linux-3.18.5-vs2.3.7.3/include/net/addrconf.h
11628 --- linux-3.18.5/include/net/addrconf.h 2015-01-17 02:40:22.000000000 +0000
11629 +++ linux-3.18.5-vs2.3.7.3/include/net/addrconf.h       2015-01-19 10:58:04.000000000 +0000
11630 @@ -79,7 +79,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str
11631  
11632  int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
11633                        const struct in6_addr *daddr, unsigned int srcprefs,
11634 -                      struct in6_addr *saddr);
11635 +                      struct in6_addr *saddr, struct nx_info *nxi);
11636  int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
11637                       u32 banned_flags);
11638  int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
11639 diff -NurpP --minimal linux-3.18.5/include/net/af_unix.h linux-3.18.5-vs2.3.7.3/include/net/af_unix.h
11640 --- linux-3.18.5/include/net/af_unix.h  2013-11-25 15:47:02.000000000 +0000
11641 +++ linux-3.18.5-vs2.3.7.3/include/net/af_unix.h        2015-01-19 10:58:04.000000000 +0000
11642 @@ -4,6 +4,7 @@
11643  #include <linux/socket.h>
11644  #include <linux/un.h>
11645  #include <linux/mutex.h>
11646 +#include <linux/vs_base.h>
11647  #include <net/sock.h>
11648  
11649  void unix_inflight(struct file *fp);
11650 diff -NurpP --minimal linux-3.18.5/include/net/inet_timewait_sock.h linux-3.18.5-vs2.3.7.3/include/net/inet_timewait_sock.h
11651 --- linux-3.18.5/include/net/inet_timewait_sock.h       2015-01-16 22:19:24.000000000 +0000
11652 +++ linux-3.18.5-vs2.3.7.3/include/net/inet_timewait_sock.h     2015-01-19 10:58:04.000000000 +0000
11653 @@ -122,6 +122,10 @@ struct inet_timewait_sock {
11654  #define tw_v6_rcv_saddr        __tw_common.skc_v6_rcv_saddr
11655  #define tw_dport               __tw_common.skc_dport
11656  #define tw_num                 __tw_common.skc_num
11657 +#define tw_xid                 __tw_common.skc_xid
11658 +#define tw_vx_info             __tw_common.skc_vx_info
11659 +#define tw_nid                 __tw_common.skc_nid
11660 +#define tw_nx_info             __tw_common.skc_nx_info
11661  
11662         int                     tw_timeout;
11663         volatile unsigned char  tw_substate;
11664 diff -NurpP --minimal linux-3.18.5/include/net/ip6_route.h linux-3.18.5-vs2.3.7.3/include/net/ip6_route.h
11665 --- linux-3.18.5/include/net/ip6_route.h        2014-09-03 13:19:43.000000000 +0000
11666 +++ linux-3.18.5-vs2.3.7.3/include/net/ip6_route.h      2015-01-19 10:58:04.000000000 +0000
11667 @@ -80,7 +80,7 @@ int ip6_del_rt(struct rt6_info *);
11668  
11669  int ip6_route_get_saddr(struct net *net, struct rt6_info *rt,
11670                         const struct in6_addr *daddr, unsigned int prefs,
11671 -                       struct in6_addr *saddr);
11672 +                       struct in6_addr *saddr, struct nx_info *nxi);
11673  
11674  struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
11675                             const struct in6_addr *saddr, int oif, int flags);
11676 diff -NurpP --minimal linux-3.18.5/include/net/route.h linux-3.18.5-vs2.3.7.3/include/net/route.h
11677 --- linux-3.18.5/include/net/route.h    2014-06-12 13:02:51.000000000 +0000
11678 +++ linux-3.18.5-vs2.3.7.3/include/net/route.h  2015-01-19 10:58:04.000000000 +0000
11679 @@ -205,6 +205,9 @@ static inline void ip_rt_put(struct rtab
11680         dst_release(&rt->dst);
11681  }
11682  
11683 +#include <linux/vs_base.h>
11684 +#include <linux/vs_inet.h>
11685 +
11686  #define IPTOS_RT_MASK  (IPTOS_TOS_MASK & ~3)
11687  
11688  extern const __u8 ip_tos2prio[16];
11689 @@ -252,6 +255,9 @@ static inline void ip_route_connect_init
11690                            protocol, flow_flags, dst, src, dport, sport);
11691  }
11692  
11693 +extern struct rtable *ip_v4_find_src(struct net *net, struct nx_info *,
11694 +       struct flowi4 *);
11695 +
11696  static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
11697                                               __be32 dst, __be32 src, u32 tos,
11698                                               int oif, u8 protocol,
11699 @@ -260,11 +266,25 @@ static inline struct rtable *ip_route_co
11700  {
11701         struct net *net = sock_net(sk);
11702         struct rtable *rt;
11703 +       struct nx_info *nx_info = current_nx_info();
11704  
11705         ip_route_connect_init(fl4, dst, src, tos, oif, protocol,
11706                               sport, dport, sk);
11707  
11708 -       if (!dst || !src) {
11709 +       if (sk)
11710 +               nx_info = sk->sk_nx_info;
11711 +
11712 +       vxdprintk(VXD_CBIT(net, 4),
11713 +               "ip_route_connect(%p) %p,%p;%lx",
11714 +               sk, nx_info, sk->sk_socket,
11715 +               (sk->sk_socket?sk->sk_socket->flags:0));
11716 +
11717 +       rt = ip_v4_find_src(net, nx_info, fl4);
11718 +       if (IS_ERR(rt))
11719 +               return rt;
11720 +       ip_rt_put(rt);
11721 +
11722 +       if (!fl4->daddr || !fl4->saddr) {
11723                 rt = __ip_route_output_key(net, fl4);
11724                 if (IS_ERR(rt))
11725                         return rt;
11726 diff -NurpP --minimal linux-3.18.5/include/net/sock.h linux-3.18.5-vs2.3.7.3/include/net/sock.h
11727 --- linux-3.18.5/include/net/sock.h     2015-01-17 02:40:22.000000000 +0000
11728 +++ linux-3.18.5-vs2.3.7.3/include/net/sock.h   2015-01-19 10:58:04.000000000 +0000
11729 @@ -193,6 +193,10 @@ struct sock_common {
11730  #ifdef CONFIG_NET_NS
11731         struct net              *skc_net;
11732  #endif
11733 +       vxid_t                  skc_xid;
11734 +       struct vx_info          *skc_vx_info;
11735 +       vnid_t                  skc_nid;
11736 +       struct nx_info          *skc_nx_info;
11737  
11738  #if IS_ENABLED(CONFIG_IPV6)
11739         struct in6_addr         skc_v6_daddr;
11740 @@ -327,7 +331,11 @@ struct sock {
11741  #define sk_prot                        __sk_common.skc_prot
11742  #define sk_net                 __sk_common.skc_net
11743  #define sk_v6_daddr            __sk_common.skc_v6_daddr
11744 -#define sk_v6_rcv_saddr        __sk_common.skc_v6_rcv_saddr
11745 +#define sk_v6_rcv_saddr                __sk_common.skc_v6_rcv_saddr
11746 +#define sk_xid                 __sk_common.skc_xid
11747 +#define sk_vx_info             __sk_common.skc_vx_info
11748 +#define sk_nid                 __sk_common.skc_nid
11749 +#define sk_nx_info             __sk_common.skc_nx_info
11750  
11751         socket_lock_t           sk_lock;
11752         struct sk_buff_head     sk_receive_queue;
11753 diff -NurpP --minimal linux-3.18.5/include/uapi/Kbuild linux-3.18.5-vs2.3.7.3/include/uapi/Kbuild
11754 --- linux-3.18.5/include/uapi/Kbuild    2015-01-17 02:40:22.000000000 +0000
11755 +++ linux-3.18.5-vs2.3.7.3/include/uapi/Kbuild  2015-01-19 10:59:16.000000000 +0000
11756 @@ -13,3 +13,4 @@ header-y += drm/
11757  header-y += xen/
11758  header-y += scsi/
11759  header-y += misc/
11760 +header-y += vserver/
11761 diff -NurpP --minimal linux-3.18.5/include/uapi/linux/capability.h linux-3.18.5-vs2.3.7.3/include/uapi/linux/capability.h
11762 --- linux-3.18.5/include/uapi/linux/capability.h        2014-09-03 13:19:44.000000000 +0000
11763 +++ linux-3.18.5-vs2.3.7.3/include/uapi/linux/capability.h      2015-01-19 10:58:04.000000000 +0000
11764 @@ -259,6 +259,7 @@ struct vfs_cap_data {
11765     arbitrary SCSI commands */
11766  /* Allow setting encryption key on loopback filesystem */
11767  /* Allow setting zone reclaim policy */
11768 +/* Allow the selection of a security context */
11769  
11770  #define CAP_SYS_ADMIN        21
11771  
11772 @@ -354,7 +355,12 @@ struct vfs_cap_data {
11773  
11774  #define CAP_LAST_CAP         CAP_AUDIT_READ
11775  
11776 -#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
11777 +/* Allow context manipulations */
11778 +/* Allow changing context info on files */
11779 +
11780 +#define CAP_CONTEXT         63
11781 +
11782 +#define cap_valid(x) ((x) >= 0 && ((x) <= CAP_LAST_CAP || (x) == CAP_CONTEXT))
11783  
11784  /*
11785   * Bit location of each capability (used by user-space library and kernel)
11786 diff -NurpP --minimal linux-3.18.5/include/uapi/linux/fs.h linux-3.18.5-vs2.3.7.3/include/uapi/linux/fs.h
11787 --- linux-3.18.5/include/uapi/linux/fs.h        2015-01-17 02:40:23.000000000 +0000
11788 +++ linux-3.18.5-vs2.3.7.3/include/uapi/linux/fs.h      2015-01-19 10:58:04.000000000 +0000
11789 @@ -90,6 +90,9 @@ struct inodes_stat_t {
11790  #define MS_KERNMOUNT   (1<<22) /* this is a kern_mount call */
11791  #define MS_I_VERSION   (1<<23) /* Update inode I_version field */
11792  #define MS_STRICTATIME (1<<24) /* Always perform atime updates */
11793 +#define MS_TAGGED      (1<<8)  /* use generic inode tagging */
11794 +#define MS_NOTAGCHECK  (1<<9)  /* don't check tags */
11795 +#define MS_TAGID       (1<<25) /* use specific tag for this mount */
11796  
11797  /* These sb flags are internal to the kernel */
11798  #define MS_NOSEC       (1<<28)
11799 @@ -195,11 +198,14 @@ struct inodes_stat_t {
11800  #define FS_EXTENT_FL                   0x00080000 /* Extents */
11801  #define FS_DIRECTIO_FL                 0x00100000 /* Use direct i/o */
11802  #define FS_NOCOW_FL                    0x00800000 /* Do not cow file */
11803 +#define FS_IXUNLINK_FL                 0x08000000 /* Immutable invert on unlink */
11804  #define FS_RESERVED_FL                 0x80000000 /* reserved for ext2 lib */
11805  
11806 -#define FS_FL_USER_VISIBLE             0x0003DFFF /* User visible flags */
11807 -#define FS_FL_USER_MODIFIABLE          0x000380FF /* User modifiable flags */
11808 +#define FS_BARRIER_FL                  0x04000000 /* Barrier for chroot() */
11809 +#define FS_COW_FL                      0x20000000 /* Copy on Write marker */
11810  
11811 +#define FS_FL_USER_VISIBLE             0x0103DFFF /* User visible flags */
11812 +#define FS_FL_USER_MODIFIABLE          0x010380FF /* User modifiable flags */
11813  
11814  #define SYNC_FILE_RANGE_WAIT_BEFORE    1
11815  #define SYNC_FILE_RANGE_WRITE          2
11816 diff -NurpP --minimal linux-3.18.5/include/uapi/linux/gfs2_ondisk.h linux-3.18.5-vs2.3.7.3/include/uapi/linux/gfs2_ondisk.h
11817 --- linux-3.18.5/include/uapi/linux/gfs2_ondisk.h       2014-09-03 13:19:44.000000000 +0000
11818 +++ linux-3.18.5-vs2.3.7.3/include/uapi/linux/gfs2_ondisk.h     2015-01-19 10:58:04.000000000 +0000
11819 @@ -225,6 +225,9 @@ enum {
11820         gfs2fl_Sync             = 8,
11821         gfs2fl_System           = 9,
11822         gfs2fl_TopLevel         = 10,
11823 +       gfs2fl_IXUnlink         = 16,
11824 +       gfs2fl_Barrier          = 17,
11825 +       gfs2fl_Cow              = 18,
11826         gfs2fl_TruncInProg      = 29,
11827         gfs2fl_InheritDirectio  = 30,
11828         gfs2fl_InheritJdata     = 31,
11829 @@ -242,6 +245,9 @@ enum {
11830  #define GFS2_DIF_SYNC                  0x00000100
11831  #define GFS2_DIF_SYSTEM                        0x00000200 /* New in gfs2 */
11832  #define GFS2_DIF_TOPDIR                        0x00000400 /* New in gfs2 */
11833 +#define GFS2_DIF_IXUNLINK               0x00010000
11834 +#define GFS2_DIF_BARRIER                0x00020000
11835 +#define GFS2_DIF_COW                    0x00040000
11836  #define GFS2_DIF_TRUNC_IN_PROG         0x20000000 /* New in gfs2 */
11837  #define GFS2_DIF_INHERIT_DIRECTIO      0x40000000 /* only in gfs1 */
11838  #define GFS2_DIF_INHERIT_JDATA         0x80000000
11839 diff -NurpP --minimal linux-3.18.5/include/uapi/linux/if_tun.h linux-3.18.5-vs2.3.7.3/include/uapi/linux/if_tun.h
11840 --- linux-3.18.5/include/uapi/linux/if_tun.h    2013-11-25 15:47:02.000000000 +0000
11841 +++ linux-3.18.5-vs2.3.7.3/include/uapi/linux/if_tun.h  2015-01-19 10:58:04.000000000 +0000
11842 @@ -58,6 +58,7 @@
11843  #define TUNSETQUEUE  _IOW('T', 217, int)
11844  #define TUNSETIFINDEX  _IOW('T', 218, unsigned int)
11845  #define TUNGETFILTER _IOR('T', 219, struct sock_fprog)
11846 +#define TUNSETNID     _IOW('T', 220, int)
11847  
11848  /* TUNSETIFF ifr flags */
11849  #define IFF_TUN                0x0001
11850 diff -NurpP --minimal linux-3.18.5/include/uapi/linux/major.h linux-3.18.5-vs2.3.7.3/include/uapi/linux/major.h
11851 --- linux-3.18.5/include/uapi/linux/major.h     2014-01-22 20:39:12.000000000 +0000
11852 +++ linux-3.18.5-vs2.3.7.3/include/uapi/linux/major.h   2015-01-19 10:58:04.000000000 +0000
11853 @@ -15,6 +15,7 @@
11854  #define HD_MAJOR               IDE0_MAJOR
11855  #define PTY_SLAVE_MAJOR                3
11856  #define TTY_MAJOR              4
11857 +#define VROOT_MAJOR            4
11858  #define TTYAUX_MAJOR           5
11859  #define LP_MAJOR               6
11860  #define VCS_MAJOR              7
11861 diff -NurpP --minimal linux-3.18.5/include/uapi/linux/nfs_mount.h linux-3.18.5-vs2.3.7.3/include/uapi/linux/nfs_mount.h
11862 --- linux-3.18.5/include/uapi/linux/nfs_mount.h 2014-01-22 20:39:12.000000000 +0000
11863 +++ linux-3.18.5-vs2.3.7.3/include/uapi/linux/nfs_mount.h       2015-01-19 10:58:04.000000000 +0000
11864 @@ -63,7 +63,8 @@ struct nfs_mount_data {
11865  #define NFS_MOUNT_SECFLAVOUR   0x2000  /* 5 non-text parsed mount data only */
11866  #define NFS_MOUNT_NORDIRPLUS   0x4000  /* 5 */
11867  #define NFS_MOUNT_UNSHARED     0x8000  /* 5 */
11868 -#define NFS_MOUNT_FLAGMASK     0xFFFF
11869 +#define NFS_MOUNT_TAGGED       0x10000 /* context tagging */
11870 +#define NFS_MOUNT_FLAGMASK     0x1FFFF
11871  
11872  /* The following are for internal use only */
11873  #define NFS_MOUNT_LOOKUP_CACHE_NONEG   0x10000
11874 diff -NurpP --minimal linux-3.18.5/include/uapi/linux/reboot.h linux-3.18.5-vs2.3.7.3/include/uapi/linux/reboot.h
11875 --- linux-3.18.5/include/uapi/linux/reboot.h    2012-12-11 03:30:57.000000000 +0000
11876 +++ linux-3.18.5-vs2.3.7.3/include/uapi/linux/reboot.h  2015-01-19 10:58:04.000000000 +0000
11877 @@ -33,7 +33,7 @@
11878  #define        LINUX_REBOOT_CMD_RESTART2       0xA1B2C3D4
11879  #define        LINUX_REBOOT_CMD_SW_SUSPEND     0xD000FCE2
11880  #define        LINUX_REBOOT_CMD_KEXEC          0x45584543
11881 -
11882 +#define        LINUX_REBOOT_CMD_OOM            0xDEADBEEF
11883  
11884  
11885  #endif /* _UAPI_LINUX_REBOOT_H */
11886 diff -NurpP --minimal linux-3.18.5/include/uapi/linux/sysctl.h linux-3.18.5-vs2.3.7.3/include/uapi/linux/sysctl.h
11887 --- linux-3.18.5/include/uapi/linux/sysctl.h    2015-01-16 22:19:26.000000000 +0000
11888 +++ linux-3.18.5-vs2.3.7.3/include/uapi/linux/sysctl.h  2015-01-19 10:58:04.000000000 +0000
11889 @@ -60,6 +60,7 @@ enum
11890         CTL_ABI=9,              /* Binary emulation */
11891         CTL_CPU=10,             /* CPU stuff (speed scaling, etc) */
11892         CTL_ARLAN=254,          /* arlan wireless driver */
11893 +       CTL_VSERVER=4242,       /* Linux-VServer debug */
11894         CTL_S390DBF=5677,       /* s390 debug */
11895         CTL_SUNRPC=7249,        /* sunrpc debug */
11896         CTL_PM=9899,            /* frv power management */
11897 @@ -94,6 +95,7 @@ enum
11898  
11899         KERN_PANIC=15,          /* int: panic timeout */
11900         KERN_REALROOTDEV=16,    /* real root device to mount after initrd */
11901 +       KERN_VSHELPER=17,       /* string: path to vshelper policy agent */
11902  
11903         KERN_SPARC_REBOOT=21,   /* reboot command on Sparc */
11904         KERN_CTLALTDEL=22,      /* int: allow ctl-alt-del to reboot */
11905 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/Kbuild linux-3.18.5-vs2.3.7.3/include/uapi/vserver/Kbuild
11906 --- linux-3.18.5/include/uapi/vserver/Kbuild    1970-01-01 00:00:00.000000000 +0000
11907 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/Kbuild  2015-01-19 10:58:04.000000000 +0000
11908 @@ -0,0 +1,9 @@
11909 +
11910 +header-y += context_cmd.h network_cmd.h space_cmd.h \
11911 +       cacct_cmd.h cvirt_cmd.h limit_cmd.h dlimit_cmd.h \
11912 +       inode_cmd.h tag_cmd.h sched_cmd.h signal_cmd.h \
11913 +       debug_cmd.h device_cmd.h
11914 +
11915 +header-y += switch.h context.h network.h monitor.h \
11916 +       limit.h inode.h device.h
11917 +
11918 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/cacct_cmd.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/cacct_cmd.h
11919 --- linux-3.18.5/include/uapi/vserver/cacct_cmd.h       1970-01-01 00:00:00.000000000 +0000
11920 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/cacct_cmd.h     2015-01-19 10:58:04.000000000 +0000
11921 @@ -0,0 +1,15 @@
11922 +#ifndef _UAPI_VS_CACCT_CMD_H
11923 +#define _UAPI_VS_CACCT_CMD_H
11924 +
11925 +
11926 +/* virtual host info name commands */
11927 +
11928 +#define VCMD_sock_stat         VC_CMD(VSTAT, 5, 0)
11929 +
11930 +struct vcmd_sock_stat_v0 {
11931 +       uint32_t field;
11932 +       uint32_t count[3];
11933 +       uint64_t total[3];
11934 +};
11935 +
11936 +#endif /* _UAPI_VS_CACCT_CMD_H */
11937 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/context.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/context.h
11938 --- linux-3.18.5/include/uapi/vserver/context.h 1970-01-01 00:00:00.000000000 +0000
11939 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/context.h       2015-01-19 10:58:04.000000000 +0000
11940 @@ -0,0 +1,81 @@
11941 +#ifndef _UAPI_VS_CONTEXT_H
11942 +#define _UAPI_VS_CONTEXT_H
11943 +
11944 +#include <linux/types.h>
11945 +#include <linux/capability.h>
11946 +
11947 +
11948 +/* context flags */
11949 +
11950 +#define VXF_INFO_SCHED         0x00000002
11951 +#define VXF_INFO_NPROC         0x00000004
11952 +#define VXF_INFO_PRIVATE       0x00000008
11953 +
11954 +#define VXF_INFO_INIT          0x00000010
11955 +#define VXF_INFO_HIDE          0x00000020
11956 +#define VXF_INFO_ULIMIT                0x00000040
11957 +#define VXF_INFO_NSPACE                0x00000080
11958 +
11959 +#define VXF_SCHED_HARD         0x00000100
11960 +#define VXF_SCHED_PRIO         0x00000200
11961 +#define VXF_SCHED_PAUSE                0x00000400
11962 +
11963 +#define VXF_VIRT_MEM           0x00010000
11964 +#define VXF_VIRT_UPTIME                0x00020000
11965 +#define VXF_VIRT_CPU           0x00040000
11966 +#define VXF_VIRT_LOAD          0x00080000
11967 +#define VXF_VIRT_TIME          0x00100000
11968 +
11969 +#define VXF_HIDE_MOUNT         0x01000000
11970 +/* was VXF_HIDE_NETIF          0x02000000 */
11971 +#define VXF_HIDE_VINFO         0x04000000
11972 +
11973 +#define VXF_STATE_SETUP                (1ULL << 32)
11974 +#define VXF_STATE_INIT         (1ULL << 33)
11975 +#define VXF_STATE_ADMIN                (1ULL << 34)
11976 +
11977 +#define VXF_SC_HELPER          (1ULL << 36)
11978 +#define VXF_REBOOT_KILL                (1ULL << 37)
11979 +#define VXF_PERSISTENT         (1ULL << 38)
11980 +
11981 +#define VXF_FORK_RSS           (1ULL << 48)
11982 +#define VXF_PROLIFIC           (1ULL << 49)
11983 +
11984 +#define VXF_IGNEG_NICE         (1ULL << 52)
11985 +
11986 +#define VXF_ONE_TIME           (0x0007ULL << 32)
11987 +
11988 +#define VXF_INIT_SET           (VXF_STATE_SETUP | VXF_STATE_INIT | VXF_STATE_ADMIN)
11989 +
11990 +
11991 +/* context migration */
11992 +
11993 +#define VXM_SET_INIT           0x00000001
11994 +#define VXM_SET_REAPER         0x00000002
11995 +
11996 +/* context caps */
11997 +
11998 +#define VXC_SET_UTSNAME                0x00000001
11999 +#define VXC_SET_RLIMIT         0x00000002
12000 +#define VXC_FS_SECURITY                0x00000004
12001 +#define VXC_FS_TRUSTED         0x00000008
12002 +#define VXC_TIOCSTI            0x00000010
12003 +
12004 +/* was VXC_RAW_ICMP            0x00000100 */
12005 +#define VXC_SYSLOG             0x00001000
12006 +#define VXC_OOM_ADJUST         0x00002000
12007 +#define VXC_AUDIT_CONTROL      0x00004000
12008 +
12009 +#define VXC_SECURE_MOUNT       0x00010000
12010 +/* #define VXC_SECURE_REMOUNT  0x00020000 */
12011 +#define VXC_BINARY_MOUNT       0x00040000
12012 +#define VXC_DEV_MOUNT          0x00080000
12013 +
12014 +#define VXC_QUOTA_CTL          0x00100000
12015 +#define VXC_ADMIN_MAPPER       0x00200000
12016 +#define VXC_ADMIN_CLOOP                0x00400000
12017 +
12018 +#define VXC_KTHREAD            0x01000000
12019 +#define VXC_NAMESPACE          0x02000000
12020 +
12021 +#endif /* _UAPI_VS_CONTEXT_H */
12022 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/context_cmd.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/context_cmd.h
12023 --- linux-3.18.5/include/uapi/vserver/context_cmd.h     1970-01-01 00:00:00.000000000 +0000
12024 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/context_cmd.h   2015-01-19 10:58:04.000000000 +0000
12025 @@ -0,0 +1,115 @@
12026 +#ifndef _UAPI_VS_CONTEXT_CMD_H
12027 +#define _UAPI_VS_CONTEXT_CMD_H
12028 +
12029 +
12030 +/* vinfo commands */
12031 +
12032 +#define VCMD_task_xid          VC_CMD(VINFO, 1, 0)
12033 +
12034 +
12035 +#define VCMD_vx_info           VC_CMD(VINFO, 5, 0)
12036 +
12037 +struct vcmd_vx_info_v0 {
12038 +       uint32_t xid;
12039 +       uint32_t initpid;
12040 +       /* more to come */
12041 +};
12042 +
12043 +
12044 +#define VCMD_ctx_stat          VC_CMD(VSTAT, 0, 0)
12045 +
12046 +struct vcmd_ctx_stat_v0 {
12047 +       uint32_t usecnt;
12048 +       uint32_t tasks;
12049 +       /* more to come */
12050 +};
12051 +
12052 +
12053 +/* context commands */
12054 +
12055 +#define VCMD_ctx_create_v0     VC_CMD(VPROC, 1, 0)
12056 +#define VCMD_ctx_create                VC_CMD(VPROC, 1, 1)
12057 +
12058 +struct vcmd_ctx_create {
12059 +       uint64_t flagword;
12060 +};
12061 +
12062 +#define VCMD_ctx_migrate_v0    VC_CMD(PROCMIG, 1, 0)
12063 +#define VCMD_ctx_migrate       VC_CMD(PROCMIG, 1, 1)
12064 +
12065 +struct vcmd_ctx_migrate {
12066 +       uint64_t flagword;
12067 +};
12068 +
12069 +
12070 +
12071 +/* flag commands */
12072 +
12073 +#define VCMD_get_cflags                VC_CMD(FLAGS, 1, 0)
12074 +#define VCMD_set_cflags                VC_CMD(FLAGS, 2, 0)
12075 +
12076 +struct vcmd_ctx_flags_v0 {
12077 +       uint64_t flagword;
12078 +       uint64_t mask;
12079 +};
12080 +
12081 +
12082 +
12083 +/* context caps commands */
12084 +
12085 +#define VCMD_get_ccaps         VC_CMD(FLAGS, 3, 1)
12086 +#define VCMD_set_ccaps         VC_CMD(FLAGS, 4, 1)
12087 +
12088 +struct vcmd_ctx_caps_v1 {
12089 +       uint64_t ccaps;
12090 +       uint64_t cmask;
12091 +};
12092 +
12093 +
12094 +
12095 +/* bcaps commands */
12096 +
12097 +#define VCMD_get_bcaps         VC_CMD(FLAGS, 9, 0)
12098 +#define VCMD_set_bcaps         VC_CMD(FLAGS, 10, 0)
12099 +
12100 +struct vcmd_bcaps {
12101 +       uint64_t bcaps;
12102 +       uint64_t bmask;
12103 +};
12104 +
12105 +
12106 +
12107 +/* umask commands */
12108 +
12109 +#define VCMD_get_umask         VC_CMD(FLAGS, 13, 0)
12110 +#define VCMD_set_umask         VC_CMD(FLAGS, 14, 0)
12111 +
12112 +struct vcmd_umask {
12113 +       uint64_t umask;
12114 +       uint64_t mask;
12115 +};
12116 +
12117 +
12118 +
12119 +/* wmask commands */
12120 +
12121 +#define VCMD_get_wmask         VC_CMD(FLAGS, 15, 0)
12122 +#define VCMD_set_wmask         VC_CMD(FLAGS, 16, 0)
12123 +
12124 +struct vcmd_wmask {
12125 +       uint64_t wmask;
12126 +       uint64_t mask;
12127 +};
12128 +
12129 +
12130 +
12131 +/* OOM badness */
12132 +
12133 +#define VCMD_get_badness       VC_CMD(MEMCTRL, 5, 0)
12134 +#define VCMD_set_badness       VC_CMD(MEMCTRL, 6, 0)
12135 +
12136 +struct vcmd_badness_v0 {
12137 +       int64_t bias;
12138 +};
12139 +
12140 +#endif /* _UAPI_VS_CONTEXT_CMD_H */
12141 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/cvirt_cmd.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/cvirt_cmd.h
12142 --- linux-3.18.5/include/uapi/vserver/cvirt_cmd.h       1970-01-01 00:00:00.000000000 +0000
12143 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/cvirt_cmd.h     2015-01-19 10:58:04.000000000 +0000
12144 @@ -0,0 +1,41 @@
12145 +#ifndef _UAPI_VS_CVIRT_CMD_H
12146 +#define _UAPI_VS_CVIRT_CMD_H
12147 +
12148 +
12149 +/* virtual host info name commands */
12150 +
12151 +#define VCMD_set_vhi_name      VC_CMD(VHOST, 1, 0)
12152 +#define VCMD_get_vhi_name      VC_CMD(VHOST, 2, 0)
12153 +
12154 +struct vcmd_vhi_name_v0 {
12155 +       uint32_t field;
12156 +       char name[65];
12157 +};
12158 +
12159 +
12160 +enum vhi_name_field {
12161 +       VHIN_CONTEXT = 0,
12162 +       VHIN_SYSNAME,
12163 +       VHIN_NODENAME,
12164 +       VHIN_RELEASE,
12165 +       VHIN_VERSION,
12166 +       VHIN_MACHINE,
12167 +       VHIN_DOMAINNAME,
12168 +};
12169 +
12170 +
12171 +
12172 +#define VCMD_virt_stat         VC_CMD(VSTAT, 3, 0)
12173 +
12174 +struct vcmd_virt_stat_v0 {
12175 +       uint64_t offset;
12176 +       uint64_t uptime;
12177 +       uint32_t nr_threads;
12178 +       uint32_t nr_running;
12179 +       uint32_t nr_uninterruptible;
12180 +       uint32_t nr_onhold;
12181 +       uint32_t nr_forks;
12182 +       uint32_t load[3];
12183 +};
12184 +
12185 +#endif /* _UAPI_VS_CVIRT_CMD_H */
12186 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/debug_cmd.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/debug_cmd.h
12187 --- linux-3.18.5/include/uapi/vserver/debug_cmd.h       1970-01-01 00:00:00.000000000 +0000
12188 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/debug_cmd.h     2015-01-19 10:58:04.000000000 +0000
12189 @@ -0,0 +1,24 @@
12190 +#ifndef _UAPI_VS_DEBUG_CMD_H
12191 +#define _UAPI_VS_DEBUG_CMD_H
12192 +
12193 +
12194 +/* debug commands */
12195 +
12196 +#define VCMD_dump_history      VC_CMD(DEBUG, 1, 0)
12197 +
12198 +#define VCMD_read_history      VC_CMD(DEBUG, 5, 0)
12199 +#define VCMD_read_monitor      VC_CMD(DEBUG, 6, 0)
12200 +
12201 +struct  vcmd_read_history_v0 {
12202 +       uint32_t index;
12203 +       uint32_t count;
12204 +       char __user *data;
12205 +};
12206 +
12207 +struct  vcmd_read_monitor_v0 {
12208 +       uint32_t index;
12209 +       uint32_t count;
12210 +       char __user *data;
12211 +};
12212 +
12213 +#endif /* _UAPI_VS_DEBUG_CMD_H */
12214 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/device.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/device.h
12215 --- linux-3.18.5/include/uapi/vserver/device.h  1970-01-01 00:00:00.000000000 +0000
12216 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/device.h        2015-01-19 10:58:04.000000000 +0000
12217 @@ -0,0 +1,12 @@
12218 +#ifndef _UAPI_VS_DEVICE_H
12219 +#define _UAPI_VS_DEVICE_H
12220 +
12221 +
12222 +#define DATTR_CREATE   0x00000001
12223 +#define DATTR_OPEN     0x00000002
12224 +
12225 +#define DATTR_REMAP    0x00000010
12226 +
12227 +#define DATTR_MASK     0x00000013
12228 +
12229 +#endif /* _UAPI_VS_DEVICE_H */
12230 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/device_cmd.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/device_cmd.h
12231 --- linux-3.18.5/include/uapi/vserver/device_cmd.h      1970-01-01 00:00:00.000000000 +0000
12232 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/device_cmd.h    2015-01-19 10:58:04.000000000 +0000
12233 @@ -0,0 +1,16 @@
12234 +#ifndef _UAPI_VS_DEVICE_CMD_H
12235 +#define _UAPI_VS_DEVICE_CMD_H
12236 +
12237 +
12238 +/*  device vserver commands */
12239 +
12240 +#define VCMD_set_mapping       VC_CMD(DEVICE, 1, 0)
12241 +#define VCMD_unset_mapping     VC_CMD(DEVICE, 2, 0)
12242 +
12243 +struct vcmd_set_mapping_v0 {
12244 +       const char __user *device;
12245 +       const char __user *target;
12246 +       uint32_t flags;
12247 +};
12248 +
12249 +#endif /* _UAPI_VS_DEVICE_CMD_H */
12250 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/dlimit_cmd.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/dlimit_cmd.h
12251 --- linux-3.18.5/include/uapi/vserver/dlimit_cmd.h      1970-01-01 00:00:00.000000000 +0000
12252 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/dlimit_cmd.h    2015-01-19 10:58:04.000000000 +0000
12253 @@ -0,0 +1,67 @@
12254 +#ifndef _UAPI_VS_DLIMIT_CMD_H
12255 +#define _UAPI_VS_DLIMIT_CMD_H
12256 +
12257 +
12258 +/*  dlimit vserver commands */
12259 +
12260 +#define VCMD_add_dlimit                VC_CMD(DLIMIT, 1, 0)
12261 +#define VCMD_rem_dlimit                VC_CMD(DLIMIT, 2, 0)
12262 +
12263 +#define VCMD_set_dlimit                VC_CMD(DLIMIT, 5, 0)
12264 +#define VCMD_get_dlimit                VC_CMD(DLIMIT, 6, 0)
12265 +
12266 +struct vcmd_ctx_dlimit_base_v0 {
12267 +       const char __user *name;
12268 +       uint32_t flags;
12269 +};
12270 +
12271 +struct vcmd_ctx_dlimit_v0 {
12272 +       const char __user *name;
12273 +       uint32_t space_used;                    /* used space in kbytes */
12274 +       uint32_t space_total;                   /* maximum space in kbytes */
12275 +       uint32_t inodes_used;                   /* used inodes */
12276 +       uint32_t inodes_total;                  /* maximum inodes */
12277 +       uint32_t reserved;                      /* reserved for root in % */
12278 +       uint32_t flags;
12279 +};
12280 +
12281 +#define CDLIM_UNSET            ((uint32_t)0UL)
12282 +#define CDLIM_INFINITY         ((uint32_t)~0UL)
12283 +#define CDLIM_KEEP             ((uint32_t)~1UL)
12284 +
12285 +#define DLIME_UNIT     0
12286 +#define DLIME_KILO     1
12287 +#define DLIME_MEGA     2
12288 +#define DLIME_GIGA     3
12289 +
12290 +#define DLIMF_SHIFT    0x10
12291 +
12292 +#define DLIMS_USED     0
12293 +#define DLIMS_TOTAL    2
12294 +
12295 +static inline
12296 +uint64_t dlimit_space_32to64(uint32_t val, uint32_t flags, int shift)
12297 +{
12298 +       int exp = (flags & DLIMF_SHIFT) ?
12299 +               (flags >> shift) & DLIME_GIGA : DLIME_KILO;
12300 +       return ((uint64_t)val) << (10 * exp);
12301 +}
12302 +
12303 +static inline
12304 +uint32_t dlimit_space_64to32(uint64_t val, uint32_t *flags, int shift)
12305 +{
12306 +       int exp = 0;
12307 +
12308 +       if (*flags & DLIMF_SHIFT) {
12309 +               while (val > (1LL << 32) && (exp < 3)) {
12310 +                       val >>= 10;
12311 +                       exp++;
12312 +               }
12313 +               *flags &= ~(DLIME_GIGA << shift);
12314 +               *flags |= exp << shift;
12315 +       } else
12316 +               val >>= 10;
12317 +       return val;
12318 +}
12319 +
12320 +#endif /* _UAPI_VS_DLIMIT_CMD_H */
12321 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/inode.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/inode.h
12322 --- linux-3.18.5/include/uapi/vserver/inode.h   1970-01-01 00:00:00.000000000 +0000
12323 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/inode.h 2015-01-19 10:58:04.000000000 +0000
12324 @@ -0,0 +1,23 @@
12325 +#ifndef _UAPI_VS_INODE_H
12326 +#define _UAPI_VS_INODE_H
12327 +
12328 +
12329 +#define IATTR_TAG      0x01000000
12330 +
12331 +#define IATTR_ADMIN    0x00000001
12332 +#define IATTR_WATCH    0x00000002
12333 +#define IATTR_HIDE     0x00000004
12334 +#define IATTR_FLAGS    0x00000007
12335 +
12336 +#define IATTR_BARRIER  0x00010000
12337 +#define IATTR_IXUNLINK 0x00020000
12338 +#define IATTR_IMMUTABLE 0x00040000
12339 +#define IATTR_COW      0x00080000
12340 +
12341 +
12342 +/* inode ioctls */
12343 +
12344 +#define FIOC_GETXFLG   _IOR('x', 5, long)
12345 +#define FIOC_SETXFLG   _IOW('x', 6, long)
12346 +
12347 +#endif /* _UAPI_VS_INODE_H */
12348 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/inode_cmd.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/inode_cmd.h
12349 --- linux-3.18.5/include/uapi/vserver/inode_cmd.h       1970-01-01 00:00:00.000000000 +0000
12350 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/inode_cmd.h     2015-01-19 10:58:04.000000000 +0000
12351 @@ -0,0 +1,26 @@
12352 +#ifndef _UAPI_VS_INODE_CMD_H
12353 +#define _UAPI_VS_INODE_CMD_H
12354 +
12355 +
12356 +/*  inode vserver commands */
12357 +
12358 +#define VCMD_get_iattr         VC_CMD(INODE, 1, 1)
12359 +#define VCMD_set_iattr         VC_CMD(INODE, 2, 1)
12360 +
12361 +#define VCMD_fget_iattr                VC_CMD(INODE, 3, 0)
12362 +#define VCMD_fset_iattr                VC_CMD(INODE, 4, 0)
12363 +
12364 +struct vcmd_ctx_iattr_v1 {
12365 +       const char __user *name;
12366 +       uint32_t tag;
12367 +       uint32_t flags;
12368 +       uint32_t mask;
12369 +};
12370 +
12371 +struct vcmd_ctx_fiattr_v0 {
12372 +       uint32_t tag;
12373 +       uint32_t flags;
12374 +       uint32_t mask;
12375 +};
12376 +
12377 +#endif /* _UAPI_VS_INODE_CMD_H */
12378 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/limit.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/limit.h
12379 --- linux-3.18.5/include/uapi/vserver/limit.h   1970-01-01 00:00:00.000000000 +0000
12380 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/limit.h 2015-01-19 10:58:04.000000000 +0000
12381 @@ -0,0 +1,14 @@
12382 +#ifndef _UAPI_VS_LIMIT_H
12383 +#define _UAPI_VS_LIMIT_H
12384 +
12385 +
12386 +#define VLIMIT_NSOCK   16
12387 +#define VLIMIT_OPENFD  17
12388 +#define VLIMIT_ANON    18
12389 +#define VLIMIT_SHMEM   19
12390 +#define VLIMIT_SEMARY  20
12391 +#define VLIMIT_NSEMS   21
12392 +#define VLIMIT_DENTRY  22
12393 +#define VLIMIT_MAPPED  23
12394 +
12395 +#endif /* _UAPI_VS_LIMIT_H */
12396 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/limit_cmd.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/limit_cmd.h
12397 --- linux-3.18.5/include/uapi/vserver/limit_cmd.h       1970-01-01 00:00:00.000000000 +0000
12398 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/limit_cmd.h     2015-01-19 10:58:04.000000000 +0000
12399 @@ -0,0 +1,40 @@
12400 +#ifndef _UAPI_VS_LIMIT_CMD_H
12401 +#define _UAPI_VS_LIMIT_CMD_H
12402 +
12403 +
12404 +/*  rlimit vserver commands */
12405 +
12406 +#define VCMD_get_rlimit                VC_CMD(RLIMIT, 1, 0)
12407 +#define VCMD_set_rlimit                VC_CMD(RLIMIT, 2, 0)
12408 +#define VCMD_get_rlimit_mask   VC_CMD(RLIMIT, 3, 0)
12409 +#define VCMD_reset_hits                VC_CMD(RLIMIT, 7, 0)
12410 +#define VCMD_reset_minmax      VC_CMD(RLIMIT, 9, 0)
12411 +
12412 +struct vcmd_ctx_rlimit_v0 {
12413 +       uint32_t id;
12414 +       uint64_t minimum;
12415 +       uint64_t softlimit;
12416 +       uint64_t maximum;
12417 +};
12418 +
12419 +struct vcmd_ctx_rlimit_mask_v0 {
12420 +       uint32_t minimum;
12421 +       uint32_t softlimit;
12422 +       uint32_t maximum;
12423 +};
12424 +
12425 +#define VCMD_rlimit_stat       VC_CMD(VSTAT, 1, 0)
12426 +
12427 +struct vcmd_rlimit_stat_v0 {
12428 +       uint32_t id;
12429 +       uint32_t hits;
12430 +       uint64_t value;
12431 +       uint64_t minimum;
12432 +       uint64_t maximum;
12433 +};
12434 +
12435 +#define CRLIM_UNSET            (0ULL)
12436 +#define CRLIM_INFINITY         (~0ULL)
12437 +#define CRLIM_KEEP             (~1ULL)
12438 +
12439 +#endif /* _UAPI_VS_LIMIT_CMD_H */
12440 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/monitor.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/monitor.h
12441 --- linux-3.18.5/include/uapi/vserver/monitor.h 1970-01-01 00:00:00.000000000 +0000
12442 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/monitor.h       2015-01-19 10:58:04.000000000 +0000
12443 @@ -0,0 +1,96 @@
12444 +#ifndef _UAPI_VS_MONITOR_H
12445 +#define _UAPI_VS_MONITOR_H
12446 +
12447 +#include <linux/types.h>
12448 +
12449 +
12450 +enum {
12451 +       VXM_UNUSED = 0,
12452 +
12453 +       VXM_SYNC = 0x10,
12454 +
12455 +       VXM_UPDATE = 0x20,
12456 +       VXM_UPDATE_1,
12457 +       VXM_UPDATE_2,
12458 +
12459 +       VXM_RQINFO_1 = 0x24,
12460 +       VXM_RQINFO_2,
12461 +
12462 +       VXM_ACTIVATE = 0x40,
12463 +       VXM_DEACTIVATE,
12464 +       VXM_IDLE,
12465 +
12466 +       VXM_HOLD = 0x44,
12467 +       VXM_UNHOLD,
12468 +
12469 +       VXM_MIGRATE = 0x48,
12470 +       VXM_RESCHED,
12471 +
12472 +       /* all other bits are flags */
12473 +       VXM_SCHED = 0x80,
12474 +};
12475 +
12476 +struct _vxm_update_1 {
12477 +       uint32_t tokens_max;
12478 +       uint32_t fill_rate;
12479 +       uint32_t interval;
12480 +};
12481 +
12482 +struct _vxm_update_2 {
12483 +       uint32_t tokens_min;
12484 +       uint32_t fill_rate;
12485 +       uint32_t interval;
12486 +};
12487 +
12488 +struct _vxm_rqinfo_1 {
12489 +       uint16_t running;
12490 +       uint16_t onhold;
12491 +       uint16_t iowait;
12492 +       uint16_t uintr;
12493 +       uint32_t idle_tokens;
12494 +};
12495 +
12496 +struct _vxm_rqinfo_2 {
12497 +       uint32_t norm_time;
12498 +       uint32_t idle_time;
12499 +       uint32_t idle_skip;
12500 +};
12501 +
12502 +struct _vxm_sched {
12503 +       uint32_t tokens;
12504 +       uint32_t norm_time;
12505 +       uint32_t idle_time;
12506 +};
12507 +
12508 +struct _vxm_task {
12509 +       uint16_t pid;
12510 +       uint16_t state;
12511 +};
12512 +
12513 +struct _vxm_event {
12514 +       uint32_t jif;
12515 +       union {
12516 +               uint32_t seq;
12517 +               uint32_t sec;
12518 +       };
12519 +       union {
12520 +               uint32_t tokens;
12521 +               uint32_t nsec;
12522 +               struct _vxm_task tsk;
12523 +       };
12524 +};
12525 +
12526 +struct _vx_mon_entry {
12527 +       uint16_t type;
12528 +       uint16_t xid;
12529 +       union {
12530 +               struct _vxm_event ev;
12531 +               struct _vxm_sched sd;
12532 +               struct _vxm_update_1 u1;
12533 +               struct _vxm_update_2 u2;
12534 +               struct _vxm_rqinfo_1 q1;
12535 +               struct _vxm_rqinfo_2 q2;
12536 +       };
12537 +};
12538 +
12539 +#endif /* _UAPI_VS_MONITOR_H */
12540 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/network.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/network.h
12541 --- linux-3.18.5/include/uapi/vserver/network.h 1970-01-01 00:00:00.000000000 +0000
12542 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/network.h       2015-01-19 10:58:04.000000000 +0000
12543 @@ -0,0 +1,76 @@
12544 +#ifndef _UAPI_VS_NETWORK_H
12545 +#define _UAPI_VS_NETWORK_H
12546 +
12547 +#include <linux/types.h>
12548 +
12549 +
12550 +#define MAX_N_CONTEXT  65535   /* Arbitrary limit */
12551 +
12552 +
12553 +/* network flags */
12554 +
12555 +#define NXF_INFO_PRIVATE       0x00000008
12556 +
12557 +#define NXF_SINGLE_IP          0x00000100
12558 +#define NXF_LBACK_REMAP                0x00000200
12559 +#define NXF_LBACK_ALLOW                0x00000400
12560 +
12561 +#define NXF_HIDE_NETIF         0x02000000
12562 +#define NXF_HIDE_LBACK         0x04000000
12563 +
12564 +#define NXF_STATE_SETUP                (1ULL << 32)
12565 +#define NXF_STATE_ADMIN                (1ULL << 34)
12566 +
12567 +#define NXF_SC_HELPER          (1ULL << 36)
12568 +#define NXF_PERSISTENT         (1ULL << 38)
12569 +
12570 +#define NXF_ONE_TIME           (0x0005ULL << 32)
12571 +
12572 +
12573 +#define        NXF_INIT_SET            (__nxf_init_set())
12574 +
12575 +static inline uint64_t __nxf_init_set(void) {
12576 +       return    NXF_STATE_ADMIN
12577 +#ifdef CONFIG_VSERVER_AUTO_LBACK
12578 +               | NXF_LBACK_REMAP
12579 +               | NXF_HIDE_LBACK
12580 +#endif
12581 +#ifdef CONFIG_VSERVER_AUTO_SINGLE
12582 +               | NXF_SINGLE_IP
12583 +#endif
12584 +               | NXF_HIDE_NETIF;
12585 +}
12586 +
12587 +
12588 +/* network caps */
12589 +
12590 +#define NXC_TUN_CREATE         0x00000001
12591 +
12592 +#define NXC_RAW_ICMP           0x00000100
12593 +
12594 +#define NXC_MULTICAST          0x00001000
12595 +
12596 +
12597 +/* address types */
12598 +
12599 +#define NXA_TYPE_IPV4          0x0001
12600 +#define NXA_TYPE_IPV6          0x0002
12601 +
12602 +#define NXA_TYPE_NONE          0x0000
12603 +#define NXA_TYPE_ANY           0x00FF
12604 +
12605 +#define NXA_TYPE_ADDR          0x0010
12606 +#define NXA_TYPE_MASK          0x0020
12607 +#define NXA_TYPE_RANGE         0x0040
12608 +
12609 +#define NXA_MASK_ALL           (NXA_TYPE_ADDR | NXA_TYPE_MASK | NXA_TYPE_RANGE)
12610 +
12611 +#define NXA_MOD_BCAST          0x0100
12612 +#define NXA_MOD_LBACK          0x0200
12613 +
12614 +#define NXA_LOOPBACK           0x1000
12615 +
12616 +#define NXA_MASK_BIND          (NXA_MASK_ALL | NXA_MOD_BCAST | NXA_MOD_LBACK)
12617 +#define NXA_MASK_SHOW          (NXA_MASK_ALL | NXA_LOOPBACK)
12618 +
12619 +#endif /* _UAPI_VS_NETWORK_H */
12620 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/network_cmd.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/network_cmd.h
12621 --- linux-3.18.5/include/uapi/vserver/network_cmd.h     1970-01-01 00:00:00.000000000 +0000
12622 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/network_cmd.h   2015-01-19 10:58:04.000000000 +0000
12623 @@ -0,0 +1,123 @@
12624 +#ifndef _UAPI_VS_NETWORK_CMD_H
12625 +#define _UAPI_VS_NETWORK_CMD_H
12626 +
12627 +
12628 +/* vinfo commands */
12629 +
12630 +#define VCMD_task_nid          VC_CMD(VINFO, 2, 0)
12631 +
12632 +
12633 +#define VCMD_nx_info           VC_CMD(VINFO, 6, 0)
12634 +
12635 +struct vcmd_nx_info_v0 {
12636 +       uint32_t nid;
12637 +       /* more to come */
12638 +};
12639 +
12640 +
12641 +#include <linux/in.h>
12642 +#include <linux/in6.h>
12643 +
12644 +#define VCMD_net_create_v0     VC_CMD(VNET, 1, 0)
12645 +#define VCMD_net_create                VC_CMD(VNET, 1, 1)
12646 +
12647 +struct  vcmd_net_create {
12648 +       uint64_t flagword;
12649 +};
12650 +
12651 +#define VCMD_net_migrate       VC_CMD(NETMIG, 1, 0)
12652 +
12653 +#define VCMD_net_add           VC_CMD(NETALT, 1, 0)
12654 +#define VCMD_net_remove                VC_CMD(NETALT, 2, 0)
12655 +
12656 +struct vcmd_net_addr_v0 {
12657 +       uint16_t type;
12658 +       uint16_t count;
12659 +       struct in_addr ip[4];
12660 +       struct in_addr mask[4];
12661 +};
12662 +
12663 +#define VCMD_net_add_ipv4_v1   VC_CMD(NETALT, 1, 1)
12664 +#define VCMD_net_rem_ipv4_v1   VC_CMD(NETALT, 2, 1)
12665 +
12666 +struct vcmd_net_addr_ipv4_v1 {
12667 +       uint16_t type;
12668 +       uint16_t flags;
12669 +       struct in_addr ip;
12670 +       struct in_addr mask;
12671 +};
12672 +
12673 +#define VCMD_net_add_ipv4      VC_CMD(NETALT, 1, 2)
12674 +#define VCMD_net_rem_ipv4      VC_CMD(NETALT, 2, 2)
12675 +
12676 +struct vcmd_net_addr_ipv4_v2 {
12677 +       uint16_t type;
12678 +       uint16_t flags;
12679 +       struct in_addr ip;
12680 +       struct in_addr ip2;
12681 +       struct in_addr mask;
12682 +};
12683 +
12684 +#define VCMD_net_add_ipv6      VC_CMD(NETALT, 3, 1)
12685 +#define VCMD_net_remove_ipv6   VC_CMD(NETALT, 4, 1)
12686 +
12687 +struct vcmd_net_addr_ipv6_v1 {
12688 +       uint16_t type;
12689 +       uint16_t flags;
12690 +       uint32_t prefix;
12691 +       struct in6_addr ip;
12692 +       struct in6_addr mask;
12693 +};
12694 +
12695 +#define VCMD_add_match_ipv4    VC_CMD(NETALT, 5, 0)
12696 +#define VCMD_get_match_ipv4    VC_CMD(NETALT, 6, 0)
12697 +
12698 +struct vcmd_match_ipv4_v0 {
12699 +       uint16_t type;
12700 +       uint16_t flags;
12701 +       uint16_t parent;
12702 +       uint16_t prefix;
12703 +       struct in_addr ip;
12704 +       struct in_addr ip2;
12705 +       struct in_addr mask;
12706 +};
12707 +
12708 +#define VCMD_add_match_ipv6    VC_CMD(NETALT, 7, 0)
12709 +#define VCMD_get_match_ipv6    VC_CMD(NETALT, 8, 0)
12710 +
12711 +struct vcmd_match_ipv6_v0 {
12712 +       uint16_t type;
12713 +       uint16_t flags;
12714 +       uint16_t parent;
12715 +       uint16_t prefix;
12716 +       struct in6_addr ip;
12717 +       struct in6_addr ip2;
12718 +       struct in6_addr mask;
12719 +};
12720 +
12721 +
12722 +
12723 +
12724 +/* flag commands */
12725 +
12726 +#define VCMD_get_nflags                VC_CMD(FLAGS, 5, 0)
12727 +#define VCMD_set_nflags                VC_CMD(FLAGS, 6, 0)
12728 +
12729 +struct vcmd_net_flags_v0 {
12730 +       uint64_t flagword;
12731 +       uint64_t mask;
12732 +};
12733 +
12734 +
12735 +
12736 +/* network caps commands */
12737 +
12738 +#define VCMD_get_ncaps         VC_CMD(FLAGS, 7, 0)
12739 +#define VCMD_set_ncaps         VC_CMD(FLAGS, 8, 0)
12740 +
12741 +struct vcmd_net_caps_v0 {
12742 +       uint64_t ncaps;
12743 +       uint64_t cmask;
12744 +};
12745 +
12746 +#endif /* _UAPI_VS_NETWORK_CMD_H */
12747 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/sched_cmd.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/sched_cmd.h
12748 --- linux-3.18.5/include/uapi/vserver/sched_cmd.h       1970-01-01 00:00:00.000000000 +0000
12749 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/sched_cmd.h     2015-01-19 10:58:04.000000000 +0000
12750 @@ -0,0 +1,13 @@
12751 +#ifndef _UAPI_VS_SCHED_CMD_H
12752 +#define _UAPI_VS_SCHED_CMD_H
12753 +
12754 +
12755 +struct vcmd_prio_bias {
12756 +       int32_t cpu_id;
12757 +       int32_t prio_bias;
12758 +};
12759 +
12760 +#define VCMD_set_prio_bias     VC_CMD(SCHED, 4, 0)
12761 +#define VCMD_get_prio_bias     VC_CMD(SCHED, 5, 0)
12762 +
12763 +#endif /* _UAPI_VS_SCHED_CMD_H */
12764 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/signal_cmd.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/signal_cmd.h
12765 --- linux-3.18.5/include/uapi/vserver/signal_cmd.h      1970-01-01 00:00:00.000000000 +0000
12766 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/signal_cmd.h    2015-01-19 10:58:04.000000000 +0000
12767 @@ -0,0 +1,31 @@
12768 +#ifndef _UAPI_VS_SIGNAL_CMD_H
12769 +#define _UAPI_VS_SIGNAL_CMD_H
12770 +
12771 +
12772 +/*  signalling vserver commands */
12773 +
12774 +#define VCMD_ctx_kill          VC_CMD(PROCTRL, 1, 0)
12775 +#define VCMD_wait_exit         VC_CMD(EVENT, 99, 0)
12776 +
12777 +struct vcmd_ctx_kill_v0 {
12778 +       int32_t pid;
12779 +       int32_t sig;
12780 +};
12781 +
12782 +struct vcmd_wait_exit_v0 {
12783 +       int32_t reboot_cmd;
12784 +       int32_t exit_code;
12785 +};
12786 +
12787 +
12788 +/*  process alteration commands */
12789 +
12790 +#define VCMD_get_pflags                VC_CMD(PROCALT, 5, 0)
12791 +#define VCMD_set_pflags                VC_CMD(PROCALT, 6, 0)
12792 +
12793 +struct vcmd_pflags_v0 {
12794 +       uint32_t flagword;
12795 +       uint32_t mask;
12796 +};
12797 +
12798 +#endif /* _UAPI_VS_SIGNAL_CMD_H */
12799 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/space_cmd.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/space_cmd.h
12800 --- linux-3.18.5/include/uapi/vserver/space_cmd.h       1970-01-01 00:00:00.000000000 +0000
12801 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/space_cmd.h     2015-01-19 10:58:04.000000000 +0000
12802 @@ -0,0 +1,28 @@
12803 +#ifndef _UAPI_VS_SPACE_CMD_H
12804 +#define _UAPI_VS_SPACE_CMD_H
12805 +
12806 +
12807 +#define VCMD_enter_space_v0    VC_CMD(PROCALT, 1, 0)
12808 +#define VCMD_enter_space_v1    VC_CMD(PROCALT, 1, 1)
12809 +#define VCMD_enter_space       VC_CMD(PROCALT, 1, 2)
12810 +
12811 +#define VCMD_set_space_v0      VC_CMD(PROCALT, 3, 0)
12812 +#define VCMD_set_space_v1      VC_CMD(PROCALT, 3, 1)
12813 +#define VCMD_set_space         VC_CMD(PROCALT, 3, 2)
12814 +
12815 +#define VCMD_get_space_mask_v0 VC_CMD(PROCALT, 4, 0)
12816 +
12817 +#define VCMD_get_space_mask    VC_CMD(VSPACE, 0, 1)
12818 +#define VCMD_get_space_default VC_CMD(VSPACE, 1, 0)
12819 +
12820 +
12821 +struct vcmd_space_mask_v1 {
12822 +       uint64_t mask;
12823 +};
12824 +
12825 +struct vcmd_space_mask_v2 {
12826 +       uint64_t mask;
12827 +       uint32_t index;
12828 +};
12829 +
12830 +#endif /* _UAPI_VS_SPACE_CMD_H */
12831 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/switch.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/switch.h
12832 --- linux-3.18.5/include/uapi/vserver/switch.h  1970-01-01 00:00:00.000000000 +0000
12833 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/switch.h        2015-01-19 10:58:04.000000000 +0000
12834 @@ -0,0 +1,90 @@
12835 +#ifndef _UAPI_VS_SWITCH_H
12836 +#define _UAPI_VS_SWITCH_H
12837 +
12838 +#include <linux/types.h>
12839 +
12840 +
12841 +#define VC_CATEGORY(c)         (((c) >> 24) & 0x3F)
12842 +#define VC_COMMAND(c)          (((c) >> 16) & 0xFF)
12843 +#define VC_VERSION(c)          ((c) & 0xFFF)
12844 +
12845 +#define VC_CMD(c, i, v)                ((((VC_CAT_ ## c) & 0x3F) << 24) \
12846 +                               | (((i) & 0xFF) << 16) | ((v) & 0xFFF))
12847 +
12848 +/*
12849 +
12850 +  Syscall Matrix V2.8
12851 +
12852 +        |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|
12853 +        |STATS  |DESTROY|ALTER  |CHANGE |LIMIT  |TEST   | |       |       |
12854 +        |INFO   |SETUP  |       |MOVE   |       |       | |       |       |
12855 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12856 +  SYSTEM |VERSION|VSETUP |VHOST  |       |       |       | |DEVICE |       |
12857 +  HOST   |     00|     01|     02|     03|     04|     05| |     06|     07|
12858 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12859 +  CPU    |       |VPROC  |PROCALT|PROCMIG|PROCTRL|       | |SCHED. |       |
12860 +  PROCESS|     08|     09|     10|     11|     12|     13| |     14|     15|
12861 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12862 +  MEMORY |       |       |       |       |MEMCTRL|       | |SWAP   |       |
12863 +        |     16|     17|     18|     19|     20|     21| |     22|     23|
12864 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12865 +  NETWORK|       |VNET   |NETALT |NETMIG |NETCTL |       | |SERIAL |       |
12866 +        |     24|     25|     26|     27|     28|     29| |     30|     31|
12867 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12868 +  DISK   |       |       |       |TAGMIG |DLIMIT |       | |INODE  |       |
12869 +  VFS    |     32|     33|     34|     35|     36|     37| |     38|     39|
12870 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12871 +  OTHER  |VSTAT  |       |       |       |       |       | |VINFO  |       |
12872 +        |     40|     41|     42|     43|     44|     45| |     46|     47|
12873 +  =======+=======+=======+=======+=======+=======+=======+ +=======+=======+
12874 +  SPECIAL|EVENT  |       |       |       |FLAGS  |       | |VSPACE |       |
12875 +        |     48|     49|     50|     51|     52|     53| |     54|     55|
12876 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12877 +  SPECIAL|DEBUG  |       |       |       |RLIMIT |SYSCALL| |       |COMPAT |
12878 +        |     56|     57|     58|     59|     60|TEST 61| |     62|     63|
12879 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12880 +
12881 +*/
12882 +
12883 +#define VC_CAT_VERSION         0
12884 +
12885 +#define VC_CAT_VSETUP          1
12886 +#define VC_CAT_VHOST           2
12887 +
12888 +#define VC_CAT_DEVICE          6
12889 +
12890 +#define VC_CAT_VPROC           9
12891 +#define VC_CAT_PROCALT         10
12892 +#define VC_CAT_PROCMIG         11
12893 +#define VC_CAT_PROCTRL         12
12894 +
12895 +#define VC_CAT_SCHED           14
12896 +#define VC_CAT_MEMCTRL         20
12897 +
12898 +#define VC_CAT_VNET            25
12899 +#define VC_CAT_NETALT          26
12900 +#define VC_CAT_NETMIG          27
12901 +#define VC_CAT_NETCTRL         28
12902 +
12903 +#define VC_CAT_TAGMIG          35
12904 +#define VC_CAT_DLIMIT          36
12905 +#define VC_CAT_INODE           38
12906 +
12907 +#define VC_CAT_VSTAT           40
12908 +#define VC_CAT_VINFO           46
12909 +#define VC_CAT_EVENT           48
12910 +
12911 +#define VC_CAT_FLAGS           52
12912 +#define VC_CAT_VSPACE          54
12913 +#define VC_CAT_DEBUG           56
12914 +#define VC_CAT_RLIMIT          60
12915 +
12916 +#define VC_CAT_SYSTEST         61
12917 +#define VC_CAT_COMPAT          63
12918 +
12919 +/*  query version */
12920 +
12921 +#define VCMD_get_version       VC_CMD(VERSION, 0, 0)
12922 +#define VCMD_get_vci           VC_CMD(VERSION, 1, 0)
12923 +
12924 +#endif /* _UAPI_VS_SWITCH_H */
12925 diff -NurpP --minimal linux-3.18.5/include/uapi/vserver/tag_cmd.h linux-3.18.5-vs2.3.7.3/include/uapi/vserver/tag_cmd.h
12926 --- linux-3.18.5/include/uapi/vserver/tag_cmd.h 1970-01-01 00:00:00.000000000 +0000
12927 +++ linux-3.18.5-vs2.3.7.3/include/uapi/vserver/tag_cmd.h       2015-01-19 10:58:04.000000000 +0000
12928 @@ -0,0 +1,14 @@
12929 +#ifndef _UAPI_VS_TAG_CMD_H
12930 +#define _UAPI_VS_TAG_CMD_H
12931 +
12932 +
12933 +/* vinfo commands */
12934 +
12935 +#define VCMD_task_tag          VC_CMD(VINFO, 3, 0)
12936 +
12937 +
12938 +/* context commands */
12939 +
12940 +#define VCMD_tag_migrate       VC_CMD(TAGMIG, 1, 0)
12941 +
12942 +#endif /* _UAPI_VS_TAG_CMD_H */
12943 diff -NurpP --minimal linux-3.18.5/init/Kconfig linux-3.18.5-vs2.3.7.3/init/Kconfig
12944 --- linux-3.18.5/init/Kconfig   2015-01-17 02:40:23.000000000 +0000
12945 +++ linux-3.18.5-vs2.3.7.3/init/Kconfig 2015-01-19 13:07:13.000000000 +0000
12946 @@ -923,6 +923,7 @@ config NUMA_BALANCING
12947  menuconfig CGROUPS
12948         boolean "Control Group support"
12949         select KERNFS
12950 +       default y
12951         help
12952           This option adds support for grouping sets of processes together, for
12953           use with process control subsystems such as Cpusets, CFS, memory
12954 diff -NurpP --minimal linux-3.18.5/init/main.c linux-3.18.5-vs2.3.7.3/init/main.c
12955 --- linux-3.18.5/init/main.c    2015-01-17 02:40:23.000000000 +0000
12956 +++ linux-3.18.5-vs2.3.7.3/init/main.c  2015-01-19 11:05:25.000000000 +0000
12957 @@ -78,6 +78,7 @@
12958  #include <linux/context_tracking.h>
12959  #include <linux/random.h>
12960  #include <linux/list.h>
12961 +#include <linux/vserver/percpu.h>
12962  
12963  #include <asm/io.h>
12964  #include <asm/bugs.h>
12965 diff -NurpP --minimal linux-3.18.5/ipc/mqueue.c linux-3.18.5-vs2.3.7.3/ipc/mqueue.c
12966 --- linux-3.18.5/ipc/mqueue.c   2014-06-12 13:02:52.000000000 +0000
12967 +++ linux-3.18.5-vs2.3.7.3/ipc/mqueue.c 2015-01-19 10:58:05.000000000 +0000
12968 @@ -35,6 +35,8 @@
12969  #include <linux/ipc_namespace.h>
12970  #include <linux/user_namespace.h>
12971  #include <linux/slab.h>
12972 +#include <linux/vs_context.h>
12973 +#include <linux/vs_limit.h>
12974  
12975  #include <net/sock.h>
12976  #include "util.h"
12977 @@ -76,6 +78,7 @@ struct mqueue_inode_info {
12978         struct pid *notify_owner;
12979         struct user_namespace *notify_user_ns;
12980         struct user_struct *user;       /* user who created, for accounting */
12981 +       struct vx_info *vxi;
12982         struct sock *notify_sock;
12983         struct sk_buff *notify_cookie;
12984  
12985 @@ -234,6 +237,7 @@ static struct inode *mqueue_get_inode(st
12986         if (S_ISREG(mode)) {
12987                 struct mqueue_inode_info *info;
12988                 unsigned long mq_bytes, mq_treesize;
12989 +               struct vx_info *vxi = current_vx_info();
12990  
12991                 inode->i_fop = &mqueue_file_operations;
12992                 inode->i_size = FILENT_SIZE;
12993 @@ -247,6 +251,7 @@ static struct inode *mqueue_get_inode(st
12994                 info->notify_user_ns = NULL;
12995                 info->qsize = 0;
12996                 info->user = NULL;      /* set when all is ok */
12997 +               info->vxi = NULL;
12998                 info->msg_tree = RB_ROOT;
12999                 info->node_cache = NULL;
13000                 memset(&info->attr, 0, sizeof(info->attr));
13001 @@ -280,17 +285,20 @@ static struct inode *mqueue_get_inode(st
13002  
13003                 spin_lock(&mq_lock);
13004                 if (u->mq_bytes + mq_bytes < u->mq_bytes ||
13005 -                   u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE)) {
13006 +                   u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE) ||
13007 +                   !vx_ipcmsg_avail(vxi, mq_bytes)) {
13008                         spin_unlock(&mq_lock);
13009                         /* mqueue_evict_inode() releases info->messages */
13010                         ret = -EMFILE;
13011                         goto out_inode;
13012                 }
13013                 u->mq_bytes += mq_bytes;
13014 +               vx_ipcmsg_add(vxi, u, mq_bytes);
13015                 spin_unlock(&mq_lock);
13016  
13017                 /* all is ok */
13018                 info->user = get_uid(u);
13019 +               info->vxi = get_vx_info(vxi);
13020         } else if (S_ISDIR(mode)) {
13021                 inc_nlink(inode);
13022                 /* Some things misbehave if size == 0 on a directory */
13023 @@ -402,8 +410,11 @@ static void mqueue_evict_inode(struct in
13024  
13025         user = info->user;
13026         if (user) {
13027 +               struct vx_info *vxi = info->vxi;
13028 +
13029                 spin_lock(&mq_lock);
13030                 user->mq_bytes -= mq_bytes;
13031 +               vx_ipcmsg_sub(vxi, user, mq_bytes);
13032                 /*
13033                  * get_ns_from_inode() ensures that the
13034                  * (ipc_ns = sb->s_fs_info) is either a valid ipc_ns
13035 @@ -413,6 +424,7 @@ static void mqueue_evict_inode(struct in
13036                 if (ipc_ns)
13037                         ipc_ns->mq_queues_count--;
13038                 spin_unlock(&mq_lock);
13039 +               put_vx_info(vxi);
13040                 free_uid(user);
13041         }
13042         if (ipc_ns)
13043 diff -NurpP --minimal linux-3.18.5/ipc/msg.c linux-3.18.5-vs2.3.7.3/ipc/msg.c
13044 --- linux-3.18.5/ipc/msg.c      2014-09-03 13:19:44.000000000 +0000
13045 +++ linux-3.18.5-vs2.3.7.3/ipc/msg.c    2015-01-19 10:58:05.000000000 +0000
13046 @@ -37,6 +37,7 @@
13047  #include <linux/rwsem.h>
13048  #include <linux/nsproxy.h>
13049  #include <linux/ipc_namespace.h>
13050 +#include <linux/vs_base.h>
13051  
13052  #include <asm/current.h>
13053  #include <linux/uaccess.h>
13054 @@ -129,6 +130,7 @@ static int newque(struct ipc_namespace *
13055  
13056         msq->q_perm.mode = msgflg & S_IRWXUGO;
13057         msq->q_perm.key = key;
13058 +       msq->q_perm.xid = vx_current_xid();
13059  
13060         msq->q_perm.security = NULL;
13061         retval = security_msg_queue_alloc(msq);
13062 diff -NurpP --minimal linux-3.18.5/ipc/sem.c linux-3.18.5-vs2.3.7.3/ipc/sem.c
13063 --- linux-3.18.5/ipc/sem.c      2015-01-17 02:40:23.000000000 +0000
13064 +++ linux-3.18.5-vs2.3.7.3/ipc/sem.c    2015-01-19 10:58:05.000000000 +0000
13065 @@ -85,6 +85,8 @@
13066  #include <linux/rwsem.h>
13067  #include <linux/nsproxy.h>
13068  #include <linux/ipc_namespace.h>
13069 +#include <linux/vs_base.h>
13070 +#include <linux/vs_limit.h>
13071  
13072  #include <linux/uaccess.h>
13073  #include "util.h"
13074 @@ -499,6 +501,7 @@ static int newary(struct ipc_namespace *
13075  
13076         sma->sem_perm.mode = (semflg & S_IRWXUGO);
13077         sma->sem_perm.key = key;
13078 +       sma->sem_perm.xid = vx_current_xid();
13079  
13080         sma->sem_perm.security = NULL;
13081         retval = security_sem_alloc(sma);
13082 @@ -528,6 +531,9 @@ static int newary(struct ipc_namespace *
13083                 return id;
13084         }
13085         ns->used_sems += nsems;
13086 +       /* FIXME: obsoleted? */
13087 +       vx_semary_inc(sma);
13088 +       vx_nsems_add(sma, nsems);
13089  
13090         sem_unlock(sma, -1);
13091         rcu_read_unlock();
13092 @@ -1116,6 +1122,9 @@ static void freeary(struct ipc_namespace
13093  
13094         wake_up_sem_queue_do(&tasks);
13095         ns->used_sems -= sma->sem_nsems;
13096 +       /* FIXME: obsoleted? */
13097 +       vx_nsems_sub(sma, sma->sem_nsems);
13098 +       vx_semary_dec(sma);
13099         ipc_rcu_putref(sma, sem_rcu_free);
13100  }
13101  
13102 diff -NurpP --minimal linux-3.18.5/ipc/shm.c linux-3.18.5-vs2.3.7.3/ipc/shm.c
13103 --- linux-3.18.5/ipc/shm.c      2015-01-17 02:40:23.000000000 +0000
13104 +++ linux-3.18.5-vs2.3.7.3/ipc/shm.c    2015-01-19 10:58:05.000000000 +0000
13105 @@ -42,6 +42,8 @@
13106  #include <linux/nsproxy.h>
13107  #include <linux/mount.h>
13108  #include <linux/ipc_namespace.h>
13109 +#include <linux/vs_context.h>
13110 +#include <linux/vs_limit.h>
13111  
13112  #include <linux/uaccess.h>
13113  
13114 @@ -210,10 +212,14 @@ static void shm_open(struct vm_area_stru
13115  static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
13116  {
13117         struct file *shm_file;
13118 +       struct vx_info *vxi = lookup_vx_info(shp->shm_perm.xid);
13119 +       int numpages = (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
13120  
13121         shm_file = shp->shm_file;
13122         shp->shm_file = NULL;
13123 -       ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
13124 +       vx_ipcshm_sub(vxi, shp, numpages);
13125 +       ns->shm_tot -= numpages;
13126 +
13127         shm_rmid(ns, shp);
13128         shm_unlock(shp);
13129         if (!is_file_hugepages(shm_file))
13130 @@ -221,6 +227,7 @@ static void shm_destroy(struct ipc_names
13131         else if (shp->mlock_user)
13132                 user_shm_unlock(file_inode(shm_file)->i_size, shp->mlock_user);
13133         fput(shm_file);
13134 +       put_vx_info(vxi);
13135         ipc_rcu_putref(shp, shm_rcu_free);
13136  }
13137  
13138 @@ -502,11 +509,15 @@ static int newseg(struct ipc_namespace *
13139                         ns->shm_tot + numpages > ns->shm_ctlall)
13140                 return -ENOSPC;
13141  
13142 +       if (!vx_ipcshm_avail(current_vx_info(), numpages))
13143 +               return -ENOSPC;
13144 +
13145         shp = ipc_rcu_alloc(sizeof(*shp));
13146         if (!shp)
13147                 return -ENOMEM;
13148  
13149         shp->shm_perm.key = key;
13150 +       shp->shm_perm.xid = vx_current_xid();
13151         shp->shm_perm.mode = (shmflg & S_IRWXUGO);
13152         shp->mlock_user = NULL;
13153  
13154 @@ -576,6 +587,7 @@ static int newseg(struct ipc_namespace *
13155  
13156         ipc_unlock_object(&shp->shm_perm);
13157         rcu_read_unlock();
13158 +       vx_ipcshm_add(current_vx_info(), key, numpages);
13159         return error;
13160  
13161  no_id:
13162 diff -NurpP --minimal linux-3.18.5/kernel/Makefile linux-3.18.5-vs2.3.7.3/kernel/Makefile
13163 --- linux-3.18.5/kernel/Makefile        2015-01-17 02:40:23.000000000 +0000
13164 +++ linux-3.18.5-vs2.3.7.3/kernel/Makefile      2015-01-19 10:58:05.000000000 +0000
13165 @@ -26,6 +26,7 @@ obj-y += power/
13166  obj-y += printk/
13167  obj-y += irq/
13168  obj-y += rcu/
13169 +obj-y += vserver/
13170  
13171  obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o
13172  obj-$(CONFIG_FREEZER) += freezer.o
13173 diff -NurpP --minimal linux-3.18.5/kernel/auditsc.c linux-3.18.5-vs2.3.7.3/kernel/auditsc.c
13174 --- linux-3.18.5/kernel/auditsc.c       2015-01-17 02:40:23.000000000 +0000
13175 +++ linux-3.18.5-vs2.3.7.3/kernel/auditsc.c     2015-01-19 10:58:05.000000000 +0000
13176 @@ -2025,7 +2025,7 @@ static int audit_set_loginuid_perm(kuid_
13177         if (is_audit_feature_set(AUDIT_FEATURE_LOGINUID_IMMUTABLE))
13178                 return -EPERM;
13179         /* it is set, you need permission */
13180 -       if (!capable(CAP_AUDIT_CONTROL))
13181 +       if (!vx_capable(CAP_AUDIT_CONTROL, VXC_AUDIT_CONTROL))
13182                 return -EPERM;
13183         /* reject if this is not an unset and we don't allow that */
13184         if (is_audit_feature_set(AUDIT_FEATURE_ONLY_UNSET_LOGINUID) && uid_valid(loginuid))
13185 diff -NurpP --minimal linux-3.18.5/kernel/capability.c linux-3.18.5-vs2.3.7.3/kernel/capability.c
13186 --- linux-3.18.5/kernel/capability.c    2015-01-16 22:19:27.000000000 +0000
13187 +++ linux-3.18.5-vs2.3.7.3/kernel/capability.c  2015-01-19 10:58:05.000000000 +0000
13188 @@ -17,6 +17,7 @@
13189  #include <linux/syscalls.h>
13190  #include <linux/pid_namespace.h>
13191  #include <linux/user_namespace.h>
13192 +#include <linux/vs_context.h>
13193  #include <asm/uaccess.h>
13194  
13195  /*
13196 @@ -106,6 +107,7 @@ static int cap_validate_magic(cap_user_h
13197         return 0;
13198  }
13199  
13200 +
13201  /*
13202   * The only thing that can change the capabilities of the current
13203   * process is the current process. As such, we can't be in this code
13204 @@ -343,6 +345,8 @@ bool has_ns_capability_noaudit(struct ta
13205         return (ret == 0);
13206  }
13207  
13208 +#include <linux/vserver/base.h>
13209 +
13210  /**
13211   * has_capability_noaudit - Does a task have a capability (unaudited) in the
13212   * initial user ns
13213 diff -NurpP --minimal linux-3.18.5/kernel/compat.c linux-3.18.5-vs2.3.7.3/kernel/compat.c
13214 --- linux-3.18.5/kernel/compat.c        2015-01-16 22:19:27.000000000 +0000
13215 +++ linux-3.18.5-vs2.3.7.3/kernel/compat.c      2015-01-19 10:58:05.000000000 +0000
13216 @@ -27,6 +27,7 @@
13217  #include <linux/times.h>
13218  #include <linux/ptrace.h>
13219  #include <linux/gfp.h>
13220 +#include <linux/vs_time.h>
13221  
13222  #include <asm/uaccess.h>
13223  
13224 @@ -1058,7 +1059,7 @@ COMPAT_SYSCALL_DEFINE1(stime, compat_tim
13225         if (err)
13226                 return err;
13227  
13228 -       do_settimeofday(&tv);
13229 +       vx_settimeofday(&tv);
13230         return 0;
13231  }
13232  
13233 diff -NurpP --minimal linux-3.18.5/kernel/cred.c linux-3.18.5-vs2.3.7.3/kernel/cred.c
13234 --- linux-3.18.5/kernel/cred.c  2013-02-19 13:58:56.000000000 +0000
13235 +++ linux-3.18.5-vs2.3.7.3/kernel/cred.c        2015-01-19 10:58:05.000000000 +0000
13236 @@ -56,31 +56,6 @@ struct cred init_cred = {
13237         .group_info             = &init_groups,
13238  };
13239  
13240 -static inline void set_cred_subscribers(struct cred *cred, int n)
13241 -{
13242 -#ifdef CONFIG_DEBUG_CREDENTIALS
13243 -       atomic_set(&cred->subscribers, n);
13244 -#endif
13245 -}
13246 -
13247 -static inline int read_cred_subscribers(const struct cred *cred)
13248 -{
13249 -#ifdef CONFIG_DEBUG_CREDENTIALS
13250 -       return atomic_read(&cred->subscribers);
13251 -#else
13252 -       return 0;
13253 -#endif
13254 -}
13255 -
13256 -static inline void alter_cred_subscribers(const struct cred *_cred, int n)
13257 -{
13258 -#ifdef CONFIG_DEBUG_CREDENTIALS
13259 -       struct cred *cred = (struct cred *) _cred;
13260 -
13261 -       atomic_add(n, &cred->subscribers);
13262 -#endif
13263 -}
13264 -
13265  /*
13266   * The RCU callback to actually dispose of a set of credentials
13267   */
13268 @@ -232,21 +207,16 @@ error:
13269   *
13270   * Call commit_creds() or abort_creds() to clean up.
13271   */
13272 -struct cred *prepare_creds(void)
13273 +struct cred *__prepare_creds(const struct cred *old)
13274  {
13275 -       struct task_struct *task = current;
13276 -       const struct cred *old;
13277         struct cred *new;
13278  
13279 -       validate_process_creds();
13280 -
13281         new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
13282         if (!new)
13283                 return NULL;
13284  
13285         kdebug("prepare_creds() alloc %p", new);
13286  
13287 -       old = task->cred;
13288         memcpy(new, old, sizeof(struct cred));
13289  
13290         atomic_set(&new->usage, 1);
13291 @@ -275,6 +245,13 @@ error:
13292         abort_creds(new);
13293         return NULL;
13294  }
13295 +
13296 +struct cred *prepare_creds(void)
13297 +{
13298 +       validate_process_creds();
13299 +
13300 +       return __prepare_creds(current->cred);
13301 +}
13302  EXPORT_SYMBOL(prepare_creds);
13303  
13304  /*
13305 diff -NurpP --minimal linux-3.18.5/kernel/exit.c linux-3.18.5-vs2.3.7.3/kernel/exit.c
13306 --- linux-3.18.5/kernel/exit.c  2015-02-05 18:02:45.000000000 +0000
13307 +++ linux-3.18.5-vs2.3.7.3/kernel/exit.c        2015-01-19 11:06:12.000000000 +0000
13308 @@ -48,6 +48,10 @@
13309  #include <linux/fs_struct.h>
13310  #include <linux/init_task.h>
13311  #include <linux/perf_event.h>
13312 +#include <linux/vs_limit.h>
13313 +#include <linux/vs_context.h>
13314 +#include <linux/vs_network.h>
13315 +#include <linux/vs_pid.h>
13316  #include <trace/events/sched.h>
13317  #include <linux/hw_breakpoint.h>
13318  #include <linux/oom.h>
13319 @@ -474,15 +478,25 @@ static struct task_struct *find_new_reap
13320         __acquires(&tasklist_lock)
13321  {
13322         struct pid_namespace *pid_ns = task_active_pid_ns(father);
13323 -       struct task_struct *thread;
13324 +       struct vx_info *vxi = task_get_vx_info(father);
13325 +       struct task_struct *thread = father;
13326 +       struct task_struct *reaper;
13327  
13328 -       thread = father;
13329         while_each_thread(father, thread) {
13330                 if (thread->flags & PF_EXITING)
13331                         continue;
13332                 if (unlikely(pid_ns->child_reaper == father))
13333                         pid_ns->child_reaper = thread;
13334 -               return thread;
13335 +               reaper = thread;
13336 +               goto out_put;
13337 +       }
13338 +
13339 +       reaper = pid_ns->child_reaper;
13340 +       if (vxi) {
13341 +               BUG_ON(!vxi->vx_reaper);
13342 +               if (vxi->vx_reaper != init_pid_ns.child_reaper &&
13343 +                   vxi->vx_reaper != father)
13344 +                       reaper = vxi->vx_reaper;
13345         }
13346  
13347         if (unlikely(pid_ns->child_reaper == father)) {
13348 @@ -520,7 +534,9 @@ static struct task_struct *find_new_reap
13349                 }
13350         }
13351  
13352 -       return pid_ns->child_reaper;
13353 +out_put:
13354 +       put_vx_info(vxi);
13355 +       return reaper;
13356  }
13357  
13358  /*
13359 @@ -572,10 +588,15 @@ static void forget_original_parent(struc
13360                 struct task_struct *t = p;
13361  
13362                 do {
13363 -                       t->real_parent = reaper;
13364 +                       struct task_struct *new_parent = reaper;
13365 +
13366 +                       if (unlikely(p == reaper))
13367 +                               new_parent = task_active_pid_ns(p)->child_reaper;
13368 +
13369 +                       t->real_parent = new_parent;
13370                         if (t->parent == father) {
13371                                 BUG_ON(t->ptrace);
13372 -                               t->parent = t->real_parent;
13373 +                               t->parent = new_parent;
13374                         }
13375                         if (t->pdeath_signal)
13376                                 group_send_sig_info(t->pdeath_signal,
13377 @@ -777,6 +798,9 @@ void do_exit(long code)
13378          */
13379         flush_ptrace_hw_breakpoint(tsk);
13380  
13381 +       /* needs to stay before exit_notify() */
13382 +       exit_vx_info_early(tsk, code);
13383 +
13384         TASKS_RCU(tasks_rcu_i = __srcu_read_lock(&tasks_rcu_exit_srcu));
13385         exit_notify(tsk, group_dead);
13386         proc_exit_connector(tsk);
13387 @@ -834,10 +858,15 @@ void do_exit(long code)
13388         smp_mb();
13389         raw_spin_unlock_wait(&tsk->pi_lock);
13390  
13391 +       /* needs to stay after exit_notify() */
13392 +       exit_vx_info(tsk, code);
13393 +       exit_nx_info(tsk);
13394 +
13395         /* causes final put_task_struct in finish_task_switch(). */
13396         tsk->state = TASK_DEAD;
13397         tsk->flags |= PF_NOFREEZE;      /* tell freezer to ignore us */
13398         schedule();
13399 +       printk("bad task: %p [%lx]\n", current, current->state);
13400         BUG();
13401         /* Avoid "noreturn function does return".  */
13402         for (;;)
13403 diff -NurpP --minimal linux-3.18.5/kernel/fork.c linux-3.18.5-vs2.3.7.3/kernel/fork.c
13404 --- linux-3.18.5/kernel/fork.c  2015-01-17 02:40:23.000000000 +0000
13405 +++ linux-3.18.5-vs2.3.7.3/kernel/fork.c        2015-01-21 09:21:45.000000000 +0000
13406 @@ -74,6 +74,9 @@
13407  #include <linux/uprobes.h>
13408  #include <linux/aio.h>
13409  #include <linux/compiler.h>
13410 +#include <linux/vs_context.h>
13411 +#include <linux/vs_network.h>
13412 +#include <linux/vs_limit.h>
13413  
13414  #include <asm/pgtable.h>
13415  #include <asm/pgalloc.h>
13416 @@ -214,6 +217,8 @@ void free_task(struct task_struct *tsk)
13417         arch_release_thread_info(tsk->stack);
13418         free_thread_info(tsk->stack);
13419         rt_mutex_debug_task_free(tsk);
13420 +       clr_vx_info(&tsk->vx_info);
13421 +       clr_nx_info(&tsk->nx_info);
13422         ftrace_graph_exit_task(tsk);
13423         put_seccomp_filter(tsk);
13424         arch_release_task_struct(tsk);
13425 @@ -1188,6 +1193,8 @@ static struct task_struct *copy_process(
13426  {
13427         int retval;
13428         struct task_struct *p;
13429 +       struct vx_info *vxi;
13430 +       struct nx_info *nxi;
13431  
13432         if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
13433                 return ERR_PTR(-EINVAL);
13434 @@ -1249,7 +1256,12 @@ static struct task_struct *copy_process(
13435         DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
13436         DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
13437  #endif
13438 +       init_vx_info(&p->vx_info, current_vx_info());
13439 +       init_nx_info(&p->nx_info, current_nx_info());
13440 +
13441         retval = -EAGAIN;
13442 +       if (!vx_nproc_avail(1))
13443 +               goto bad_fork_free;
13444         if (atomic_read(&p->real_cred->user->processes) >=
13445                         task_rlimit(p, RLIMIT_NPROC)) {
13446                 if (p->real_cred->user != INIT_USER &&
13447 @@ -1535,6 +1547,18 @@ static struct task_struct *copy_process(
13448         total_forks++;
13449         spin_unlock(&current->sighand->siglock);
13450         syscall_tracepoint_update(p);
13451 +
13452 +       /* p is copy of current */
13453 +       vxi = p->vx_info;
13454 +       if (vxi) {
13455 +               claim_vx_info(vxi, p);
13456 +               atomic_inc(&vxi->cvirt.nr_threads);
13457 +               atomic_inc(&vxi->cvirt.total_forks);
13458 +               vx_nproc_inc(p);
13459 +       }
13460 +       nxi = p->nx_info;
13461 +       if (nxi)
13462 +               claim_nx_info(nxi, p);
13463         write_unlock_irq(&tasklist_lock);
13464  
13465         proc_fork_connector(p);
13466 diff -NurpP --minimal linux-3.18.5/kernel/kthread.c linux-3.18.5-vs2.3.7.3/kernel/kthread.c
13467 --- linux-3.18.5/kernel/kthread.c       2015-01-17 02:40:23.000000000 +0000
13468 +++ linux-3.18.5-vs2.3.7.3/kernel/kthread.c     2015-01-19 10:58:05.000000000 +0000
13469 @@ -18,6 +18,7 @@
13470  #include <linux/freezer.h>
13471  #include <linux/ptrace.h>
13472  #include <linux/uaccess.h>
13473 +#include <linux/vs_pid.h>
13474  #include <trace/events/sched.h>
13475  
13476  static DEFINE_SPINLOCK(kthread_create_lock);
13477 diff -NurpP --minimal linux-3.18.5/kernel/nsproxy.c linux-3.18.5-vs2.3.7.3/kernel/nsproxy.c
13478 --- linux-3.18.5/kernel/nsproxy.c       2015-01-16 22:19:27.000000000 +0000
13479 +++ linux-3.18.5-vs2.3.7.3/kernel/nsproxy.c     2015-01-19 10:58:05.000000000 +0000
13480 @@ -20,11 +20,14 @@
13481  #include <linux/mnt_namespace.h>
13482  #include <linux/utsname.h>
13483  #include <linux/pid_namespace.h>
13484 +#include <linux/vserver/global.h>
13485 +#include <linux/vserver/debug.h>
13486  #include <net/net_namespace.h>
13487  #include <linux/ipc_namespace.h>
13488  #include <linux/proc_ns.h>
13489  #include <linux/file.h>
13490  #include <linux/syscalls.h>
13491 +#include "../fs/mount.h"
13492  
13493  static struct kmem_cache *nsproxy_cachep;
13494  
13495 @@ -46,8 +49,11 @@ static inline struct nsproxy *create_nsp
13496         struct nsproxy *nsproxy;
13497  
13498         nsproxy = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL);
13499 -       if (nsproxy)
13500 +       if (nsproxy) {
13501                 atomic_set(&nsproxy->count, 1);
13502 +               atomic_inc(&vs_global_nsproxy);
13503 +       }
13504 +       vxdprintk(VXD_CBIT(space, 2), "create_nsproxy = %p[1]", nsproxy);
13505         return nsproxy;
13506  }
13507  
13508 @@ -56,9 +62,12 @@ static inline struct nsproxy *create_nsp
13509   * Return the newly created nsproxy.  Do not attach this to the task,
13510   * leave it to the caller to do proper locking and attach it to task.
13511   */
13512 -static struct nsproxy *create_new_namespaces(unsigned long flags,
13513 -       struct task_struct *tsk, struct user_namespace *user_ns,
13514 -       struct fs_struct *new_fs)
13515 +static struct nsproxy *unshare_namespaces(
13516 +       unsigned long flags,
13517 +       struct nsproxy *orig,
13518 +       struct fs_struct *new_fs,
13519 +       struct user_namespace *new_user,
13520 +       struct pid_namespace *new_pid)
13521  {
13522         struct nsproxy *new_nsp;
13523         int err;
13524 @@ -67,32 +76,31 @@ static struct nsproxy *create_new_namesp
13525         if (!new_nsp)
13526                 return ERR_PTR(-ENOMEM);
13527  
13528 -       new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, user_ns, new_fs);
13529 +       new_nsp->mnt_ns = copy_mnt_ns(flags, orig->mnt_ns, new_user, new_fs);
13530         if (IS_ERR(new_nsp->mnt_ns)) {
13531                 err = PTR_ERR(new_nsp->mnt_ns);
13532                 goto out_ns;
13533         }
13534  
13535 -       new_nsp->uts_ns = copy_utsname(flags, user_ns, tsk->nsproxy->uts_ns);
13536 +       new_nsp->uts_ns = copy_utsname(flags, new_user, orig->uts_ns);
13537         if (IS_ERR(new_nsp->uts_ns)) {
13538                 err = PTR_ERR(new_nsp->uts_ns);
13539                 goto out_uts;
13540         }
13541  
13542 -       new_nsp->ipc_ns = copy_ipcs(flags, user_ns, tsk->nsproxy->ipc_ns);
13543 +       new_nsp->ipc_ns = copy_ipcs(flags, new_user, orig->ipc_ns);
13544         if (IS_ERR(new_nsp->ipc_ns)) {
13545                 err = PTR_ERR(new_nsp->ipc_ns);
13546                 goto out_ipc;
13547         }
13548  
13549 -       new_nsp->pid_ns_for_children =
13550 -               copy_pid_ns(flags, user_ns, tsk->nsproxy->pid_ns_for_children);
13551 +       new_nsp->pid_ns_for_children = copy_pid_ns(flags, new_user, new_pid);
13552         if (IS_ERR(new_nsp->pid_ns_for_children)) {
13553                 err = PTR_ERR(new_nsp->pid_ns_for_children);
13554                 goto out_pid;
13555         }
13556  
13557 -       new_nsp->net_ns = copy_net_ns(flags, user_ns, tsk->nsproxy->net_ns);
13558 +       new_nsp->net_ns = copy_net_ns(flags, new_user, orig->net_ns);
13559         if (IS_ERR(new_nsp->net_ns)) {
13560                 err = PTR_ERR(new_nsp->net_ns);
13561                 goto out_net;
13562 @@ -117,6 +125,41 @@ out_ns:
13563         return ERR_PTR(err);
13564  }
13565  
13566 +static struct nsproxy *create_new_namespaces(unsigned long flags,
13567 +       struct task_struct *tsk, struct user_namespace *user_ns,
13568 +       struct fs_struct *new_fs)
13569 +
13570 +{
13571 +       return unshare_namespaces(flags, tsk->nsproxy,
13572 +               new_fs, user_ns, task_active_pid_ns(tsk));
13573 +}
13574 +
13575 +/*
13576 + * copies the nsproxy, setting refcount to 1, and grabbing a
13577 + * reference to all contained namespaces.
13578 + */
13579 +struct nsproxy *copy_nsproxy(struct nsproxy *orig)
13580 +{
13581 +       struct nsproxy *ns = create_nsproxy();
13582 +
13583 +       if (ns) {
13584 +               memcpy(ns, orig, sizeof(struct nsproxy));
13585 +               atomic_set(&ns->count, 1);
13586 +
13587 +               if (ns->mnt_ns)
13588 +                       get_mnt_ns(ns->mnt_ns);
13589 +               if (ns->uts_ns)
13590 +                       get_uts_ns(ns->uts_ns);
13591 +               if (ns->ipc_ns)
13592 +                       get_ipc_ns(ns->ipc_ns);
13593 +               if (ns->pid_ns_for_children)
13594 +                       get_pid_ns(ns->pid_ns_for_children);
13595 +               if (ns->net_ns)
13596 +                       get_net(ns->net_ns);
13597 +       }
13598 +       return ns;
13599 +}
13600 +
13601  /*
13602   * called from clone.  This now handles copy for nsproxy and all
13603   * namespaces therein.
13604 @@ -125,7 +168,10 @@ int copy_namespaces(unsigned long flags,
13605  {
13606         struct nsproxy *old_ns = tsk->nsproxy;
13607         struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns);
13608 -       struct nsproxy *new_ns;
13609 +       struct nsproxy *new_ns = NULL;
13610 +
13611 +       vxdprintk(VXD_CBIT(space, 7), "copy_namespaces(0x%08lx,%p[%p])",
13612 +               flags, tsk, old_ns);
13613  
13614         if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
13615                               CLONE_NEWPID | CLONE_NEWNET)))) {
13616 @@ -133,7 +179,7 @@ int copy_namespaces(unsigned long flags,
13617                 return 0;
13618         }
13619  
13620 -       if (!ns_capable(user_ns, CAP_SYS_ADMIN))
13621 +       if (!vx_ns_can_unshare(user_ns, CAP_SYS_ADMIN, flags))
13622                 return -EPERM;
13623  
13624         /*
13625 @@ -152,6 +198,9 @@ int copy_namespaces(unsigned long flags,
13626                 return  PTR_ERR(new_ns);
13627  
13628         tsk->nsproxy = new_ns;
13629 +       vxdprintk(VXD_CBIT(space, 3),
13630 +               "copy_namespaces(0x%08lx,%p[%p]) = [%p]",
13631 +               flags, tsk, old_ns, new_ns);
13632         return 0;
13633  }
13634  
13635 @@ -165,7 +214,9 @@ void free_nsproxy(struct nsproxy *ns)
13636                 put_ipc_ns(ns->ipc_ns);
13637         if (ns->pid_ns_for_children)
13638                 put_pid_ns(ns->pid_ns_for_children);
13639 -       put_net(ns->net_ns);
13640 +       if (ns->net_ns)
13641 +               put_net(ns->net_ns);
13642 +       atomic_dec(&vs_global_nsproxy);
13643         kmem_cache_free(nsproxy_cachep, ns);
13644  }
13645  
13646 @@ -179,12 +230,16 @@ int unshare_nsproxy_namespaces(unsigned
13647         struct user_namespace *user_ns;
13648         int err = 0;
13649  
13650 +       vxdprintk(VXD_CBIT(space, 4),
13651 +               "unshare_nsproxy_namespaces(0x%08lx,[%p])",
13652 +               unshare_flags, current->nsproxy);
13653 +
13654         if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
13655                                CLONE_NEWNET | CLONE_NEWPID)))
13656                 return 0;
13657  
13658         user_ns = new_cred ? new_cred->user_ns : current_user_ns();
13659 -       if (!ns_capable(user_ns, CAP_SYS_ADMIN))
13660 +       if (!vx_ns_can_unshare(user_ns, CAP_SYS_ADMIN, unshare_flags))
13661                 return -EPERM;
13662  
13663         *new_nsp = create_new_namespaces(unshare_flags, current, user_ns,
13664 diff -NurpP --minimal linux-3.18.5/kernel/pid.c linux-3.18.5-vs2.3.7.3/kernel/pid.c
13665 --- linux-3.18.5/kernel/pid.c   2015-02-05 18:02:45.000000000 +0000
13666 +++ linux-3.18.5-vs2.3.7.3/kernel/pid.c 2015-01-19 10:58:05.000000000 +0000
13667 @@ -38,6 +38,7 @@
13668  #include <linux/syscalls.h>
13669  #include <linux/proc_ns.h>
13670  #include <linux/proc_fs.h>
13671 +#include <linux/vs_pid.h>
13672  
13673  #define pid_hashfn(nr, ns)     \
13674         hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
13675 @@ -375,7 +376,7 @@ EXPORT_SYMBOL_GPL(find_pid_ns);
13676  
13677  struct pid *find_vpid(int nr)
13678  {
13679 -       return find_pid_ns(nr, task_active_pid_ns(current));
13680 +       return find_pid_ns(vx_rmap_pid(nr), task_active_pid_ns(current));
13681  }
13682  EXPORT_SYMBOL_GPL(find_vpid);
13683  
13684 @@ -431,6 +432,9 @@ void transfer_pid(struct task_struct *ol
13685  struct task_struct *pid_task(struct pid *pid, enum pid_type type)
13686  {
13687         struct task_struct *result = NULL;
13688 +
13689 +       if (type == PIDTYPE_REALPID)
13690 +               type = PIDTYPE_PID;
13691         if (pid) {
13692                 struct hlist_node *first;
13693                 first = rcu_dereference_check(hlist_first_rcu(&pid->tasks[type]),
13694 @@ -450,7 +454,7 @@ struct task_struct *find_task_by_pid_ns(
13695         rcu_lockdep_assert(rcu_read_lock_held(),
13696                            "find_task_by_pid_ns() needs rcu_read_lock()"
13697                            " protection");
13698 -       return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
13699 +       return pid_task(find_pid_ns(vx_rmap_pid(nr), ns), PIDTYPE_PID);
13700  }
13701  
13702  struct task_struct *find_task_by_vpid(pid_t vnr)
13703 @@ -494,7 +498,7 @@ struct pid *find_get_pid(pid_t nr)
13704  }
13705  EXPORT_SYMBOL_GPL(find_get_pid);
13706  
13707 -pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
13708 +pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns)
13709  {
13710         struct upid *upid;
13711         pid_t nr = 0;
13712 @@ -508,6 +512,11 @@ pid_t pid_nr_ns(struct pid *pid, struct
13713  }
13714  EXPORT_SYMBOL_GPL(pid_nr_ns);
13715  
13716 +pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
13717 +{
13718 +       return vx_map_pid(pid_unmapped_nr_ns(pid, ns));
13719 +}
13720 +
13721  pid_t pid_vnr(struct pid *pid)
13722  {
13723         return pid_nr_ns(pid, task_active_pid_ns(current));
13724 diff -NurpP --minimal linux-3.18.5/kernel/pid_namespace.c linux-3.18.5-vs2.3.7.3/kernel/pid_namespace.c
13725 --- linux-3.18.5/kernel/pid_namespace.c 2014-06-12 13:02:52.000000000 +0000
13726 +++ linux-3.18.5-vs2.3.7.3/kernel/pid_namespace.c       2015-01-19 10:58:05.000000000 +0000
13727 @@ -18,6 +18,7 @@
13728  #include <linux/proc_ns.h>
13729  #include <linux/reboot.h>
13730  #include <linux/export.h>
13731 +#include <linux/vserver/global.h>
13732  
13733  struct pid_cache {
13734         int nr_ids;
13735 @@ -110,6 +111,7 @@ static struct pid_namespace *create_pid_
13736                 goto out_free_map;
13737  
13738         kref_init(&ns->kref);
13739 +       atomic_inc(&vs_global_pid_ns);
13740         ns->level = level;
13741         ns->parent = get_pid_ns(parent_pid_ns);
13742         ns->user_ns = get_user_ns(user_ns);
13743 @@ -127,6 +129,7 @@ static struct pid_namespace *create_pid_
13744  out_free_map:
13745         kfree(ns->pidmap[0].page);
13746  out_free:
13747 +       atomic_dec(&vs_global_pid_ns);
13748         kmem_cache_free(pid_ns_cachep, ns);
13749  out:
13750         return ERR_PTR(err);
13751 diff -NurpP --minimal linux-3.18.5/kernel/printk/printk.c linux-3.18.5-vs2.3.7.3/kernel/printk/printk.c
13752 --- linux-3.18.5/kernel/printk/printk.c 2015-01-17 02:40:23.000000000 +0000
13753 +++ linux-3.18.5-vs2.3.7.3/kernel/printk/printk.c       2015-01-19 11:13:25.000000000 +0000
13754 @@ -46,6 +46,7 @@
13755  #include <linux/irq_work.h>
13756  #include <linux/utsname.h>
13757  #include <linux/ctype.h>
13758 +#include <linux/vs_cvirt.h>
13759  
13760  #include <asm/uaccess.h>
13761  
13762 @@ -490,7 +491,7 @@ static int check_syslog_permissions(int
13763                 return 0;
13764  
13765         if (syslog_action_restricted(type)) {
13766 -               if (capable(CAP_SYSLOG))
13767 +               if (vx_capable(CAP_SYSLOG, VXC_SYSLOG))
13768                         return 0;
13769                 /*
13770                  * For historical reasons, accept CAP_SYS_ADMIN too, with
13771 @@ -1270,12 +1271,9 @@ int do_syslog(int type, char __user *buf
13772         if (error)
13773                 return error;
13774  
13775 -       switch (type) {
13776 -       case SYSLOG_ACTION_CLOSE:       /* Close log */
13777 -               break;
13778 -       case SYSLOG_ACTION_OPEN:        /* Open log */
13779 -               break;
13780 -       case SYSLOG_ACTION_READ:        /* Read from log */
13781 +       if ((type == SYSLOG_ACTION_READ) ||
13782 +           (type == SYSLOG_ACTION_READ_ALL) ||
13783 +           (type == SYSLOG_ACTION_READ_CLEAR)) {
13784                 error = -EINVAL;
13785                 if (!buf || len < 0)
13786                         goto out;
13787 @@ -1286,6 +1284,16 @@ int do_syslog(int type, char __user *buf
13788                         error = -EFAULT;
13789                         goto out;
13790                 }
13791 +       }
13792 +       if (!vx_check(0, VS_ADMIN|VS_WATCH))
13793 +               return vx_do_syslog(type, buf, len);
13794 +
13795 +       switch (type) {
13796 +       case SYSLOG_ACTION_CLOSE:       /* Close log */
13797 +               break;
13798 +       case SYSLOG_ACTION_OPEN:        /* Open log */
13799 +               break;
13800 +       case SYSLOG_ACTION_READ:        /* Read from log */
13801                 error = wait_event_interruptible(log_wait,
13802                                                  syslog_seq != log_next_seq);
13803                 if (error)
13804 @@ -1298,16 +1306,6 @@ int do_syslog(int type, char __user *buf
13805                 /* FALL THRU */
13806         /* Read last kernel messages */
13807         case SYSLOG_ACTION_READ_ALL:
13808 -               error = -EINVAL;
13809 -               if (!buf || len < 0)
13810 -                       goto out;
13811 -               error = 0;
13812 -               if (!len)
13813 -                       goto out;
13814 -               if (!access_ok(VERIFY_WRITE, buf, len)) {
13815 -                       error = -EFAULT;
13816 -                       goto out;
13817 -               }
13818                 error = syslog_print_all(buf, len, clear);
13819                 break;
13820         /* Clear ring buffer */
13821 diff -NurpP --minimal linux-3.18.5/kernel/ptrace.c linux-3.18.5-vs2.3.7.3/kernel/ptrace.c
13822 --- linux-3.18.5/kernel/ptrace.c        2015-01-16 22:19:27.000000000 +0000
13823 +++ linux-3.18.5-vs2.3.7.3/kernel/ptrace.c      2015-01-19 10:58:13.000000000 +0000
13824 @@ -23,6 +23,7 @@
13825  #include <linux/syscalls.h>
13826  #include <linux/uaccess.h>
13827  #include <linux/regset.h>
13828 +#include <linux/vs_context.h>
13829  #include <linux/hw_breakpoint.h>
13830  #include <linux/cn_proc.h>
13831  #include <linux/compat.h>
13832 @@ -258,6 +259,11 @@ ok:
13833         }
13834         rcu_read_unlock();
13835  
13836 +       if (!vx_check(task->xid, VS_ADMIN_P|VS_WATCH_P|VS_IDENT))
13837 +               return -EPERM;
13838 +       if (!vx_check(task->xid, VS_IDENT) &&
13839 +               !task_vx_flags(task, VXF_STATE_ADMIN, 0))
13840 +               return -EACCES;
13841         return security_ptrace_access_check(task, mode);
13842  }
13843  
13844 diff -NurpP --minimal linux-3.18.5/kernel/reboot.c linux-3.18.5-vs2.3.7.3/kernel/reboot.c
13845 --- linux-3.18.5/kernel/reboot.c        2015-01-17 02:40:23.000000000 +0000
13846 +++ linux-3.18.5-vs2.3.7.3/kernel/reboot.c      2015-01-19 10:58:13.000000000 +0000
13847 @@ -16,6 +16,7 @@
13848  #include <linux/syscalls.h>
13849  #include <linux/syscore_ops.h>
13850  #include <linux/uaccess.h>
13851 +#include <linux/vs_pid.h>
13852  
13853  /*
13854   * this indicates whether you can reboot with ctrl-alt-del: the default is yes
13855 @@ -269,6 +270,8 @@ EXPORT_SYMBOL_GPL(kernel_power_off);
13856  
13857  static DEFINE_MUTEX(reboot_mutex);
13858  
13859 +long vs_reboot(unsigned int, void __user *);
13860 +
13861  /*
13862   * Reboot system call: for obvious reasons only root may call it,
13863   * and even root needs to set up some magic numbers in the registers
13864 @@ -311,6 +314,9 @@ SYSCALL_DEFINE4(reboot, int, magic1, int
13865         if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
13866                 cmd = LINUX_REBOOT_CMD_HALT;
13867  
13868 +       if (!vx_check(0, VS_ADMIN|VS_WATCH))
13869 +               return vs_reboot(cmd, arg);
13870 +
13871         mutex_lock(&reboot_mutex);
13872         switch (cmd) {
13873         case LINUX_REBOOT_CMD_RESTART:
13874 diff -NurpP --minimal linux-3.18.5/kernel/sched/core.c linux-3.18.5-vs2.3.7.3/kernel/sched/core.c
13875 --- linux-3.18.5/kernel/sched/core.c    2015-02-05 18:02:45.000000000 +0000
13876 +++ linux-3.18.5-vs2.3.7.3/kernel/sched/core.c  2015-01-19 11:06:53.000000000 +0000
13877 @@ -74,6 +74,8 @@
13878  #include <linux/binfmts.h>
13879  #include <linux/context_tracking.h>
13880  #include <linux/compiler.h>
13881 +#include <linux/vs_sched.h>
13882 +#include <linux/vs_cvirt.h>
13883  
13884  #include <asm/switch_to.h>
13885  #include <asm/tlb.h>
13886 @@ -3192,7 +3194,7 @@ SYSCALL_DEFINE1(nice, int, increment)
13887  
13888         nice = clamp_val(nice, MIN_NICE, MAX_NICE);
13889         if (increment < 0 && !can_nice(current, nice))
13890 -               return -EPERM;
13891 +               return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
13892  
13893         retval = security_task_setnice(current, nice);
13894         if (retval)
13895 diff -NurpP --minimal linux-3.18.5/kernel/sched/cputime.c linux-3.18.5-vs2.3.7.3/kernel/sched/cputime.c
13896 --- linux-3.18.5/kernel/sched/cputime.c 2015-01-17 02:40:23.000000000 +0000
13897 +++ linux-3.18.5-vs2.3.7.3/kernel/sched/cputime.c       2015-01-19 11:08:36.000000000 +0000
13898 @@ -4,6 +4,7 @@
13899  #include <linux/kernel_stat.h>
13900  #include <linux/static_key.h>
13901  #include <linux/context_tracking.h>
13902 +#include <linux/vs_sched.h>
13903  #include "sched.h"
13904  
13905  
13906 @@ -135,14 +136,17 @@ static inline void task_group_account_fi
13907  void account_user_time(struct task_struct *p, cputime_t cputime,
13908                        cputime_t cputime_scaled)
13909  {
13910 +       struct vx_info *vxi = p->vx_info;  /* p is _always_ current */
13911 +       int nice = (task_nice(p) > 0);
13912         int index;
13913  
13914         /* Add user time to process. */
13915         p->utime += cputime;
13916         p->utimescaled += cputime_scaled;
13917 +       vx_account_user(vxi, cputime, nice);
13918         account_group_user_time(p, cputime);
13919  
13920 -       index = (task_nice(p) > 0) ? CPUTIME_NICE : CPUTIME_USER;
13921 +       index = (nice) ? CPUTIME_NICE : CPUTIME_USER;
13922  
13923         /* Add user time to cpustat. */
13924         task_group_account_field(p, index, (__force u64) cputime);
13925 @@ -189,9 +193,12 @@ static inline
13926  void __account_system_time(struct task_struct *p, cputime_t cputime,
13927                         cputime_t cputime_scaled, int index)
13928  {
13929 +       struct vx_info *vxi = p->vx_info;  /* p is _always_ current */
13930 +
13931         /* Add system time to process. */
13932         p->stime += cputime;
13933         p->stimescaled += cputime_scaled;
13934 +       vx_account_system(vxi, cputime, 0 /* do we have idle time? */);
13935         account_group_system_time(p, cputime);
13936  
13937         /* Add system time to cpustat. */
13938 diff -NurpP --minimal linux-3.18.5/kernel/sched/fair.c linux-3.18.5-vs2.3.7.3/kernel/sched/fair.c
13939 --- linux-3.18.5/kernel/sched/fair.c    2015-01-17 02:40:23.000000000 +0000
13940 +++ linux-3.18.5-vs2.3.7.3/kernel/sched/fair.c  2015-01-19 10:58:14.000000000 +0000
13941 @@ -30,6 +30,7 @@
13942  #include <linux/mempolicy.h>
13943  #include <linux/migrate.h>
13944  #include <linux/task_work.h>
13945 +#include <linux/vs_cvirt.h>
13946  
13947  #include <trace/events/sched.h>
13948  
13949 @@ -2840,6 +2841,8 @@ enqueue_entity(struct cfs_rq *cfs_rq, st
13950                 __enqueue_entity(cfs_rq, se);
13951         se->on_rq = 1;
13952  
13953 +       if (entity_is_task(se))
13954 +               vx_activate_task(task_of(se));
13955         if (cfs_rq->nr_running == 1) {
13956                 list_add_leaf_cfs_rq(cfs_rq);
13957                 check_enqueue_throttle(cfs_rq);
13958 @@ -2921,6 +2924,8 @@ dequeue_entity(struct cfs_rq *cfs_rq, st
13959         if (se != cfs_rq->curr)
13960                 __dequeue_entity(cfs_rq, se);
13961         se->on_rq = 0;
13962 +       if (entity_is_task(se))
13963 +               vx_deactivate_task(task_of(se));
13964         account_entity_dequeue(cfs_rq, se);
13965  
13966         /*
13967 diff -NurpP --minimal linux-3.18.5/kernel/sched/proc.c linux-3.18.5-vs2.3.7.3/kernel/sched/proc.c
13968 --- linux-3.18.5/kernel/sched/proc.c    2015-01-16 22:19:27.000000000 +0000
13969 +++ linux-3.18.5-vs2.3.7.3/kernel/sched/proc.c  2015-01-19 10:58:14.000000000 +0000
13970 @@ -71,9 +71,17 @@ EXPORT_SYMBOL(avenrun); /* should be rem
13971   */
13972  void get_avenrun(unsigned long *loads, unsigned long offset, int shift)
13973  {
13974 -       loads[0] = (avenrun[0] + offset) << shift;
13975 -       loads[1] = (avenrun[1] + offset) << shift;
13976 -       loads[2] = (avenrun[2] + offset) << shift;
13977 +       if (vx_flags(VXF_VIRT_LOAD, 0)) {
13978 +               struct vx_info *vxi = current_vx_info();
13979 +
13980 +               loads[0] = (vxi->cvirt.load[0] + offset) << shift;
13981 +               loads[1] = (vxi->cvirt.load[1] + offset) << shift;
13982 +               loads[2] = (vxi->cvirt.load[2] + offset) << shift;
13983 +       } else {
13984 +               loads[0] = (avenrun[0] + offset) << shift;
13985 +               loads[1] = (avenrun[1] + offset) << shift;
13986 +               loads[2] = (avenrun[2] + offset) << shift;
13987 +       }
13988  }
13989  
13990  long calc_load_fold_active(struct rq *this_rq)
13991 diff -NurpP --minimal linux-3.18.5/kernel/signal.c linux-3.18.5-vs2.3.7.3/kernel/signal.c
13992 --- linux-3.18.5/kernel/signal.c        2015-01-16 22:19:27.000000000 +0000
13993 +++ linux-3.18.5-vs2.3.7.3/kernel/signal.c      2015-01-19 13:14:52.000000000 +0000
13994 @@ -34,6 +34,8 @@
13995  #include <linux/compat.h>
13996  #include <linux/cn_proc.h>
13997  #include <linux/compiler.h>
13998 +#include <linux/vs_context.h>
13999 +#include <linux/vs_pid.h>
14000  
14001  #define CREATE_TRACE_POINTS
14002  #include <trace/events/signal.h>
14003 @@ -767,9 +769,18 @@ static int check_kill_permission(int sig
14004         struct pid *sid;
14005         int error;
14006  
14007 +       vxdprintk(VXD_CBIT(misc, 7),
14008 +               "check_kill_permission(%d,%p,%p[#%u,%u])",
14009 +               sig, info, t, vx_task_xid(t), t->pid);
14010 +
14011         if (!valid_signal(sig))
14012                 return -EINVAL;
14013  
14014 +/*     FIXME: needed? if so, why?
14015 +       if ((info != SEND_SIG_NOINFO) &&
14016 +               (is_si_special(info) || !si_fromuser(info)))
14017 +               goto skip;      */
14018 +
14019         if (!si_fromuser(info))
14020                 return 0;
14021  
14022 @@ -793,6 +804,20 @@ static int check_kill_permission(int sig
14023                 }
14024         }
14025  
14026 +       error = -EPERM;
14027 +       if (t->pid == 1 && current->xid)
14028 +               return error;
14029 +
14030 +       error = -ESRCH;
14031 +       /* FIXME: we shouldn't return ESRCH ever, to avoid
14032 +                 loops, maybe ENOENT or EACCES? */
14033 +       if (!vx_check(vx_task_xid(t), VS_WATCH_P | VS_IDENT)) {
14034 +               vxdprintk(current->xid || VXD_CBIT(misc, 7),
14035 +                       "signal %d[%p] xid mismatch %p[#%u,%u] xid=#%u",
14036 +                       sig, info, t, vx_task_xid(t), t->pid, current->xid);
14037 +               return error;
14038 +       }
14039 +/* skip: */
14040         return security_task_kill(t, info, sig, 0);
14041  }
14042  
14043 @@ -1334,7 +1359,7 @@ int kill_pid_info(int sig, struct siginf
14044         rcu_read_lock();
14045  retry:
14046         p = pid_task(pid, PIDTYPE_PID);
14047 -       if (p) {
14048 +       if (p && vx_check(vx_task_xid(p), VS_IDENT)) {
14049                 error = group_send_sig_info(sig, info, p);
14050                 if (unlikely(error == -ESRCH))
14051                         /*
14052 @@ -1382,7 +1407,7 @@ int kill_pid_info_as_cred(int sig, struc
14053  
14054         rcu_read_lock();
14055         p = pid_task(pid, PIDTYPE_PID);
14056 -       if (!p) {
14057 +       if (!p || !vx_check(vx_task_xid(p), VS_IDENT)) {
14058                 ret = -ESRCH;
14059                 goto out_unlock;
14060         }
14061 @@ -1434,8 +1459,10 @@ static int kill_something_info(int sig,
14062                 struct task_struct * p;
14063  
14064                 for_each_process(p) {
14065 -                       if (task_pid_vnr(p) > 1 &&
14066 -                                       !same_thread_group(p, current)) {
14067 +                       if (vx_check(vx_task_xid(p), VS_ADMIN|VS_IDENT) &&
14068 +                               task_pid_vnr(p) > 1 &&
14069 +                               !same_thread_group(p, current) &&
14070 +                               !vx_current_initpid(p->pid)) {
14071                                 int err = group_send_sig_info(sig, info, p);
14072                                 ++count;
14073                                 if (err != -EPERM)
14074 @@ -2288,6 +2315,11 @@ relock:
14075                                 !sig_kernel_only(signr))
14076                         continue;
14077  
14078 +               /* virtual init is protected against user signals */
14079 +               if ((ksig->info.si_code == SI_USER) &&
14080 +                       vx_current_initpid(current->pid))
14081 +                       continue;
14082 +
14083                 if (sig_kernel_stop(signr)) {
14084                         /*
14085                          * The default action is to stop all threads in
14086 diff -NurpP --minimal linux-3.18.5/kernel/softirq.c linux-3.18.5-vs2.3.7.3/kernel/softirq.c
14087 --- linux-3.18.5/kernel/softirq.c       2015-01-17 02:40:23.000000000 +0000
14088 +++ linux-3.18.5-vs2.3.7.3/kernel/softirq.c     2015-01-19 11:09:03.000000000 +0000
14089 @@ -26,6 +26,7 @@
14090  #include <linux/smpboot.h>
14091  #include <linux/tick.h>
14092  #include <linux/irq.h>
14093 +#include <linux/vs_context.h>
14094  
14095  #define CREATE_TRACE_POINTS
14096  #include <trace/events/irq.h>
14097 diff -NurpP --minimal linux-3.18.5/kernel/sys.c linux-3.18.5-vs2.3.7.3/kernel/sys.c
14098 --- linux-3.18.5/kernel/sys.c   2015-01-17 02:40:23.000000000 +0000
14099 +++ linux-3.18.5-vs2.3.7.3/kernel/sys.c 2015-01-19 11:17:00.000000000 +0000
14100 @@ -54,6 +54,7 @@
14101  #include <linux/cred.h>
14102  
14103  #include <linux/kmsg_dump.h>
14104 +#include <linux/vs_pid.h>
14105  /* Move somewhere else to avoid recompiling? */
14106  #include <generated/utsrelease.h>
14107  
14108 @@ -145,7 +146,10 @@ static int set_one_prio(struct task_stru
14109                 goto out;
14110         }
14111         if (niceval < task_nice(p) && !can_nice(p, niceval)) {
14112 -               error = -EACCES;
14113 +               if (vx_flags(VXF_IGNEG_NICE, 0))
14114 +                       error = 0;
14115 +               else
14116 +                       error = -EACCES;
14117                 goto out;
14118         }
14119         no_nice = security_task_setnice(p, niceval);
14120 @@ -196,6 +200,8 @@ SYSCALL_DEFINE3(setpriority, int, which,
14121                 else
14122                         pgrp = task_pgrp(current);
14123                 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
14124 +                       if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
14125 +                               continue;
14126                         error = set_one_prio(p, niceval, error);
14127                 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
14128                 break;
14129 @@ -262,6 +268,8 @@ SYSCALL_DEFINE2(getpriority, int, which,
14130                 else
14131                         pgrp = task_pgrp(current);
14132                 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
14133 +                       if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
14134 +                               continue;
14135                         niceval = nice_to_rlimit(task_nice(p));
14136                         if (niceval > retval)
14137                                 retval = niceval;
14138 @@ -278,6 +286,8 @@ SYSCALL_DEFINE2(getpriority, int, which,
14139                                 goto out_unlock;        /* No processes for this user */
14140                 }
14141                 do_each_thread(g, p) {
14142 +                       if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
14143 +                               continue;
14144                         if (uid_eq(task_uid(p), uid)) {
14145                                 niceval = nice_to_rlimit(task_nice(p));
14146                                 if (niceval > retval)
14147 @@ -1202,7 +1212,8 @@ SYSCALL_DEFINE2(sethostname, char __user
14148         int errno;
14149         char tmp[__NEW_UTS_LEN];
14150  
14151 -       if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
14152 +       if (!vx_ns_capable(current->nsproxy->uts_ns->user_ns,
14153 +               CAP_SYS_ADMIN, VXC_SET_UTSNAME))
14154                 return -EPERM;
14155  
14156         if (len < 0 || len > __NEW_UTS_LEN)
14157 @@ -1253,7 +1264,8 @@ SYSCALL_DEFINE2(setdomainname, char __us
14158         int errno;
14159         char tmp[__NEW_UTS_LEN];
14160  
14161 -       if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
14162 +       if (!vx_ns_capable(current->nsproxy->uts_ns->user_ns,
14163 +               CAP_SYS_ADMIN, VXC_SET_UTSNAME))
14164                 return -EPERM;
14165         if (len < 0 || len > __NEW_UTS_LEN)
14166                 return -EINVAL;
14167 @@ -1371,7 +1383,7 @@ int do_prlimit(struct task_struct *tsk,
14168                 /* Keep the capable check against init_user_ns until
14169                    cgroups can contain all limits */
14170                 if (new_rlim->rlim_max > rlim->rlim_max &&
14171 -                               !capable(CAP_SYS_RESOURCE))
14172 +                       !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
14173                         retval = -EPERM;
14174                 if (!retval)
14175                         retval = security_task_setrlimit(tsk->group_leader,
14176 @@ -1424,7 +1436,8 @@ static int check_prlimit_permission(stru
14177             gid_eq(cred->gid, tcred->sgid) &&
14178             gid_eq(cred->gid, tcred->gid))
14179                 return 0;
14180 -       if (ns_capable(tcred->user_ns, CAP_SYS_RESOURCE))
14181 +       if (vx_ns_capable(tcred->user_ns,
14182 +               CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
14183                 return 0;
14184  
14185         return -EPERM;
14186 diff -NurpP --minimal linux-3.18.5/kernel/sysctl.c linux-3.18.5-vs2.3.7.3/kernel/sysctl.c
14187 --- linux-3.18.5/kernel/sysctl.c        2015-01-17 02:40:23.000000000 +0000
14188 +++ linux-3.18.5-vs2.3.7.3/kernel/sysctl.c      2015-02-02 01:19:02.000000000 +0000
14189 @@ -84,6 +84,7 @@
14190  #if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_LOCK_STAT)
14191  #include <linux/lockdep.h>
14192  #endif
14193 +extern char vshelper_path[];
14194  #ifdef CONFIG_CHR_DEV_SG
14195  #include <scsi/sg.h>
14196  #endif
14197 @@ -278,6 +279,13 @@ static int max_extfrag_threshold = 1000;
14198  
14199  static struct ctl_table kern_table[] = {
14200         {
14201 +               .procname       = "vshelper",
14202 +               .data           = &vshelper_path,
14203 +               .maxlen         = 256,
14204 +               .mode           = 0644,
14205 +               .proc_handler   = proc_dostring,
14206 +       },
14207 +       {
14208                 .procname       = "sched_child_runs_first",
14209                 .data           = &sysctl_sched_child_runs_first,
14210                 .maxlen         = sizeof(unsigned int),
14211 @@ -1300,7 +1308,6 @@ static struct ctl_table vm_table[] = {
14212                 .extra1         = &min_extfrag_threshold,
14213                 .extra2         = &max_extfrag_threshold,
14214         },
14215 -
14216  #endif /* CONFIG_COMPACTION */
14217         {
14218                 .procname       = "min_free_kbytes",
14219 diff -NurpP --minimal linux-3.18.5/kernel/sysctl_binary.c linux-3.18.5-vs2.3.7.3/kernel/sysctl_binary.c
14220 --- linux-3.18.5/kernel/sysctl_binary.c 2015-01-17 02:40:23.000000000 +0000
14221 +++ linux-3.18.5-vs2.3.7.3/kernel/sysctl_binary.c       2015-01-19 10:58:14.000000000 +0000
14222 @@ -73,6 +73,7 @@ static const struct bin_table bin_kern_t
14223  
14224         { CTL_INT,      KERN_PANIC,                     "panic" },
14225         { CTL_INT,      KERN_REALROOTDEV,               "real-root-dev" },
14226 +       { CTL_STR,      KERN_VSHELPER,                  "vshelper" },
14227  
14228         { CTL_STR,      KERN_SPARC_REBOOT,              "reboot-cmd" },
14229         { CTL_INT,      KERN_CTLALTDEL,                 "ctrl-alt-del" },
14230 diff -NurpP --minimal linux-3.18.5/kernel/time/posix-timers.c linux-3.18.5-vs2.3.7.3/kernel/time/posix-timers.c
14231 --- linux-3.18.5/kernel/time/posix-timers.c     2015-01-17 02:40:23.000000000 +0000
14232 +++ linux-3.18.5-vs2.3.7.3/kernel/time/posix-timers.c   2015-01-19 13:01:37.000000000 +0000
14233 @@ -48,6 +48,7 @@
14234  #include <linux/workqueue.h>
14235  #include <linux/export.h>
14236  #include <linux/hashtable.h>
14237 +#include <linux/vs_context.h>
14238  
14239  #include "timekeeping.h"
14240  
14241 @@ -400,6 +401,7 @@ int posix_timer_event(struct k_itimer *t
14242  {
14243         struct task_struct *task;
14244         int shared, ret = -1;
14245 +
14246         /*
14247          * FIXME: if ->sigq is queued we can race with
14248          * dequeue_signal()->do_schedule_next_timer().
14249 @@ -416,10 +418,18 @@ int posix_timer_event(struct k_itimer *t
14250         rcu_read_lock();
14251         task = pid_task(timr->it_pid, PIDTYPE_PID);
14252         if (task) {
14253 +               struct vx_info_save vxis;
14254 +               struct vx_info *vxi;
14255 +
14256 +               vxi = get_vx_info(task->vx_info);
14257 +               enter_vx_info(vxi, &vxis);
14258                 shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID);
14259                 ret = send_sigqueue(timr->sigq, task, shared);
14260 +               leave_vx_info(&vxis);
14261 +               put_vx_info(vxi);
14262         }
14263         rcu_read_unlock();
14264 +
14265         /* If we failed to send the signal the timer stops. */
14266         return ret > 0;
14267  }
14268 diff -NurpP --minimal linux-3.18.5/kernel/time/time.c linux-3.18.5-vs2.3.7.3/kernel/time/time.c
14269 --- linux-3.18.5/kernel/time/time.c     2015-02-05 18:02:46.000000000 +0000
14270 +++ linux-3.18.5-vs2.3.7.3/kernel/time/time.c   2015-02-05 18:08:00.000000000 +0000
14271 @@ -37,6 +37,7 @@
14272  #include <linux/fs.h>
14273  #include <linux/math64.h>
14274  #include <linux/ptrace.h>
14275 +#include <linux/vs_time.h>
14276  
14277  #include <asm/uaccess.h>
14278  #include <asm/unistd.h>
14279 @@ -93,7 +94,7 @@ SYSCALL_DEFINE1(stime, time_t __user *,
14280         if (err)
14281                 return err;
14282  
14283 -       do_settimeofday(&tv);
14284 +       vx_settimeofday(&tv);
14285         return 0;
14286  }
14287  
14288 @@ -182,7 +183,7 @@ int do_sys_settimeofday(const struct tim
14289                 }
14290         }
14291         if (tv)
14292 -               return do_settimeofday(tv);
14293 +               return vx_settimeofday(tv);
14294         return 0;
14295  }
14296  
14297 diff -NurpP --minimal linux-3.18.5/kernel/time/timekeeping.c linux-3.18.5-vs2.3.7.3/kernel/time/timekeeping.c
14298 --- linux-3.18.5/kernel/time/timekeeping.c      2015-01-16 22:19:28.000000000 +0000
14299 +++ linux-3.18.5-vs2.3.7.3/kernel/time/timekeeping.c    2015-01-19 11:18:21.000000000 +0000
14300 @@ -23,6 +23,7 @@
14301  #include <linux/stop_machine.h>
14302  #include <linux/pvclock_gtod.h>
14303  #include <linux/compiler.h>
14304 +#include <linux/vs_time.h>
14305  
14306  #include "tick-internal.h"
14307  #include "ntp_internal.h"
14308 @@ -680,7 +681,9 @@ void getnstime_raw_and_real(struct times
14309         } while (read_seqcount_retry(&tk_core.seq, seq));
14310  
14311         timespec_add_ns(ts_raw, nsecs_raw);
14312 +       vx_adjust_timespec(ts_raw);
14313         timespec_add_ns(ts_real, nsecs_real);
14314 +       vx_adjust_timespec(ts_real);
14315  }
14316  EXPORT_SYMBOL(getnstime_raw_and_real);
14317  
14318 diff -NurpP --minimal linux-3.18.5/kernel/time/timer.c linux-3.18.5-vs2.3.7.3/kernel/time/timer.c
14319 --- linux-3.18.5/kernel/time/timer.c    2015-01-17 02:40:23.000000000 +0000
14320 +++ linux-3.18.5-vs2.3.7.3/kernel/time/timer.c  2015-01-19 13:02:42.000000000 +0000
14321 @@ -42,6 +42,10 @@
14322  #include <linux/sched/sysctl.h>
14323  #include <linux/slab.h>
14324  #include <linux/compat.h>
14325 +#include <linux/vs_base.h>
14326 +#include <linux/vs_cvirt.h>
14327 +#include <linux/vs_pid.h>
14328 +#include <linux/vserver/sched.h>
14329  
14330  #include <asm/uaccess.h>
14331  #include <asm/unistd.h>
14332 diff -NurpP --minimal linux-3.18.5/kernel/user_namespace.c linux-3.18.5-vs2.3.7.3/kernel/user_namespace.c
14333 --- linux-3.18.5/kernel/user_namespace.c        2015-02-05 18:02:46.000000000 +0000
14334 +++ linux-3.18.5-vs2.3.7.3/kernel/user_namespace.c      2015-01-25 18:29:17.000000000 +0000
14335 @@ -22,6 +22,7 @@
14336  #include <linux/ctype.h>
14337  #include <linux/projid.h>
14338  #include <linux/fs_struct.h>
14339 +#include <linux/vserver/global.h>
14340  
14341  static struct kmem_cache *user_ns_cachep __read_mostly;
14342  static DEFINE_MUTEX(userns_state_mutex);
14343 @@ -95,6 +96,7 @@ int create_user_ns(struct cred *new)
14344  
14345         atomic_set(&ns->count, 1);
14346         /* Leave the new->user_ns reference with the new user namespace. */
14347 +       atomic_inc(&vs_global_user_ns);
14348         ns->parent = parent_ns;
14349         ns->level = parent_ns->level + 1;
14350         ns->owner = owner;
14351 @@ -356,6 +358,18 @@ gid_t from_kgid_munged(struct user_names
14352  }
14353  EXPORT_SYMBOL(from_kgid_munged);
14354  
14355 +ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
14356 +{
14357 +       return KTAGT_INIT(tag);
14358 +}
14359 +EXPORT_SYMBOL(make_ktag);
14360 +
14361 +vtag_t from_ktag(struct user_namespace *to, ktag_t tag)
14362 +{
14363 +       return __ktag_val(tag);
14364 +}
14365 +EXPORT_SYMBOL(from_ktag);
14366 +
14367  /**
14368   *     make_kprojid - Map a user-namespace projid pair into a kprojid.
14369   *     @ns:  User namespace that the projid is in
14370 @@ -956,6 +970,8 @@ static void *userns_get(struct task_stru
14371  
14372  static void userns_put(void *ns)
14373  {
14374 +       /* FIXME: maybe move into destroyer? */
14375 +       atomic_dec(&vs_global_user_ns);
14376         put_user_ns(ns);
14377  }
14378  
14379 diff -NurpP --minimal linux-3.18.5/kernel/utsname.c linux-3.18.5-vs2.3.7.3/kernel/utsname.c
14380 --- linux-3.18.5/kernel/utsname.c       2015-01-16 22:19:28.000000000 +0000
14381 +++ linux-3.18.5-vs2.3.7.3/kernel/utsname.c     2015-01-19 10:58:31.000000000 +0000
14382 @@ -16,14 +16,17 @@
14383  #include <linux/slab.h>
14384  #include <linux/user_namespace.h>
14385  #include <linux/proc_ns.h>
14386 +#include <linux/vserver/global.h>
14387  
14388  static struct uts_namespace *create_uts_ns(void)
14389  {
14390         struct uts_namespace *uts_ns;
14391  
14392         uts_ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL);
14393 -       if (uts_ns)
14394 +       if (uts_ns) {
14395                 kref_init(&uts_ns->kref);
14396 +               atomic_inc(&vs_global_uts_ns);
14397 +       }
14398         return uts_ns;
14399  }
14400  
14401 @@ -85,6 +88,7 @@ void free_uts_ns(struct kref *kref)
14402         ns = container_of(kref, struct uts_namespace, kref);
14403         put_user_ns(ns->user_ns);
14404         proc_free_inum(ns->proc_inum);
14405 +       atomic_dec(&vs_global_uts_ns);
14406         kfree(ns);
14407  }
14408  
14409 diff -NurpP --minimal linux-3.18.5/kernel/vserver/Kconfig linux-3.18.5-vs2.3.7.3/kernel/vserver/Kconfig
14410 --- linux-3.18.5/kernel/vserver/Kconfig 1970-01-01 00:00:00.000000000 +0000
14411 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/Kconfig       2015-01-19 10:58:31.000000000 +0000
14412 @@ -0,0 +1,230 @@
14413 +#
14414 +# Linux VServer configuration
14415 +#
14416 +
14417 +menu "Linux VServer"
14418 +
14419 +config VSERVER_AUTO_LBACK
14420 +       bool    "Automatically Assign Loopback IP"
14421 +       default y
14422 +       help
14423 +         Automatically assign a guest specific loopback
14424 +         IP and add it to the kernel network stack on
14425 +         startup.
14426 +
14427 +config VSERVER_AUTO_SINGLE
14428 +       bool    "Automatic Single IP Special Casing"
14429 +       default n
14430 +       help
14431 +         This allows network contexts with a single IP to
14432 +         automatically remap 0.0.0.0 bindings to that IP,
14433 +         avoiding further network checks and improving
14434 +         performance.
14435 +
14436 +         (note: such guests do not allow to change the ip
14437 +          on the fly and do not show loopback addresses)
14438 +
14439 +config VSERVER_COWBL
14440 +       bool    "Enable COW Immutable Link Breaking"
14441 +       default y
14442 +       help
14443 +         This enables the COW (Copy-On-Write) link break code.
14444 +         It allows you to treat unified files like normal files
14445 +         when writing to them (which will implicitely break the
14446 +         link and create a copy of the unified file)
14447 +
14448 +config VSERVER_VTIME
14449 +       bool    "Enable Virtualized Guest Time (EXPERIMENTAL)"
14450 +       default n
14451 +       help
14452 +         This enables per guest time offsets to allow for
14453 +         adjusting the system clock individually per guest.
14454 +         this adds some overhead to the time functions and
14455 +         therefore should not be enabled without good reason.
14456 +
14457 +config VSERVER_DEVICE
14458 +       bool    "Enable Guest Device Mapping (EXPERIMENTAL)"
14459 +       default n
14460 +       help
14461 +         This enables generic device remapping.
14462 +
14463 +config VSERVER_PROC_SECURE
14464 +       bool    "Enable Proc Security"
14465 +       depends on PROC_FS
14466 +       default y
14467 +       help
14468 +         This configures ProcFS security to initially hide
14469 +         non-process entries for all contexts except the main and
14470 +         spectator context (i.e. for all guests), which is a secure
14471 +         default.
14472 +
14473 +         (note: on 1.2x the entries were visible by default)
14474 +
14475 +choice
14476 +       prompt  "Persistent Inode Tagging"
14477 +       default TAGGING_ID24
14478 +       help
14479 +         This adds persistent context information to filesystems
14480 +         mounted with the tagxid option. Tagging is a requirement
14481 +         for per-context disk limits and per-context quota.
14482 +
14483 +
14484 +config TAGGING_NONE
14485 +       bool    "Disabled"
14486 +       help
14487 +         do not store per-context information in inodes.
14488 +
14489 +config TAGGING_UID16
14490 +       bool    "UID16/GID32"
14491 +       help
14492 +         reduces UID to 16 bit, but leaves GID at 32 bit.
14493 +
14494 +config TAGGING_GID16
14495 +       bool    "UID32/GID16"
14496 +       help
14497 +         reduces GID to 16 bit, but leaves UID at 32 bit.
14498 +
14499 +config TAGGING_ID24
14500 +       bool    "UID24/GID24"
14501 +       help
14502 +         uses the upper 8bit from UID and GID for XID tagging
14503 +         which leaves 24bit for UID/GID each, which should be
14504 +         more than sufficient for normal use.
14505 +
14506 +config TAGGING_INTERN
14507 +       bool    "UID32/GID32"
14508 +       help
14509 +         this uses otherwise reserved inode fields in the on
14510 +         disk representation, which limits the use to a few
14511 +         filesystems (currently ext2 and ext3)
14512 +
14513 +endchoice
14514 +
14515 +config TAG_NFSD
14516 +       bool    "Tag NFSD User Auth and Files"
14517 +       default n
14518 +       help
14519 +         Enable this if you do want the in-kernel NFS
14520 +         Server to use the tagging specified above.
14521 +         (will require patched clients too)
14522 +
14523 +config VSERVER_PRIVACY
14524 +       bool    "Honor Privacy Aspects of Guests"
14525 +       default n
14526 +       help
14527 +         When enabled, most context checks will disallow
14528 +         access to structures assigned to a specific context,
14529 +         like ptys or loop devices.
14530 +
14531 +config VSERVER_CONTEXTS
14532 +       int     "Maximum number of Contexts (1-65533)"  if EMBEDDED
14533 +       range 1 65533
14534 +       default "768"   if 64BIT
14535 +       default "256"
14536 +       help
14537 +         This setting will optimize certain data structures
14538 +         and memory allocations according to the expected
14539 +         maximum.
14540 +
14541 +         note: this is not a strict upper limit.
14542 +
14543 +config VSERVER_WARN
14544 +       bool    "VServer Warnings"
14545 +       default y
14546 +       help
14547 +         This enables various runtime warnings, which will
14548 +         notify about potential manipulation attempts or
14549 +         resource shortage. It is generally considered to
14550 +         be a good idea to have that enabled.
14551 +
14552 +config VSERVER_WARN_DEVPTS
14553 +       bool    "VServer DevPTS Warnings"
14554 +       depends on VSERVER_WARN
14555 +       default y
14556 +       help
14557 +         This enables DevPTS related warnings, issued when a
14558 +         process inside a context tries to lookup or access
14559 +         a dynamic pts from the host or a different context.
14560 +
14561 +config VSERVER_DEBUG
14562 +       bool    "VServer Debugging Code"
14563 +       default n
14564 +       help
14565 +         Set this to yes if you want to be able to activate
14566 +         debugging output at runtime. It adds a very small
14567 +         overhead to all vserver related functions and
14568 +         increases the kernel size by about 20k.
14569 +
14570 +config VSERVER_HISTORY
14571 +       bool    "VServer History Tracing"
14572 +       depends on VSERVER_DEBUG
14573 +       default n
14574 +       help
14575 +         Set this to yes if you want to record the history of
14576 +         linux-vserver activities, so they can be replayed in
14577 +         the event of a kernel panic or oops.
14578 +
14579 +config VSERVER_HISTORY_SIZE
14580 +       int     "Per-CPU History Size (32-65536)"
14581 +       depends on VSERVER_HISTORY
14582 +       range 32 65536
14583 +       default 64
14584 +       help
14585 +         This allows you to specify the number of entries in
14586 +         the per-CPU history buffer.
14587 +
14588 +config VSERVER_EXTRA_MNT_CHECK
14589 +       bool    "Extra Checks for Reachability"
14590 +       default n
14591 +       help
14592 +         Set this to yes if you want to do extra checks for
14593 +         vfsmount reachability in the proc filesystem code.
14594 +         This shouldn't be required on any setup utilizing
14595 +         mnt namespaces.
14596 +
14597 +choice
14598 +       prompt  "Quotes used in debug and warn messages"
14599 +       default QUOTES_ISO8859
14600 +
14601 +config QUOTES_ISO8859
14602 +       bool    "Extended ASCII (ISO 8859) angle quotes"
14603 +       help
14604 +         This uses the extended ASCII characters \xbb
14605 +         and \xab for quoting file and process names.
14606 +
14607 +config QUOTES_UTF8
14608 +       bool    "UTF-8 angle quotes"
14609 +       help
14610 +         This uses the the UTF-8 sequences for angle
14611 +         quotes to quote file and process names.
14612 +
14613 +config QUOTES_ASCII
14614 +       bool    "ASCII single quotes"
14615 +       help
14616 +         This uses the ASCII single quote character
14617 +         (\x27) to quote file and process names.
14618 +
14619 +endchoice
14620 +
14621 +endmenu
14622 +
14623 +
14624 +config VSERVER
14625 +       bool
14626 +       default y
14627 +       select NAMESPACES
14628 +       select UTS_NS
14629 +       select IPC_NS
14630 +#      select USER_NS
14631 +       select SYSVIPC
14632 +
14633 +config VSERVER_SECURITY
14634 +       bool
14635 +       depends on SECURITY
14636 +       default y
14637 +       select SECURITY_CAPABILITIES
14638 +
14639 +config VSERVER_DISABLED
14640 +       bool
14641 +       default n
14642 +
14643 diff -NurpP --minimal linux-3.18.5/kernel/vserver/Makefile linux-3.18.5-vs2.3.7.3/kernel/vserver/Makefile
14644 --- linux-3.18.5/kernel/vserver/Makefile        1970-01-01 00:00:00.000000000 +0000
14645 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/Makefile      2015-01-19 10:58:31.000000000 +0000
14646 @@ -0,0 +1,18 @@
14647 +#
14648 +# Makefile for the Linux vserver routines.
14649 +#
14650 +
14651 +
14652 +obj-y          += vserver.o
14653 +
14654 +vserver-y      := switch.o context.o space.o sched.o network.o inode.o \
14655 +                  limit.o cvirt.o cacct.o signal.o helper.o init.o \
14656 +                  dlimit.o tag.o
14657 +
14658 +vserver-$(CONFIG_INET) += inet.o
14659 +vserver-$(CONFIG_PROC_FS) += proc.o
14660 +vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o debug.o
14661 +vserver-$(CONFIG_VSERVER_HISTORY) += history.o
14662 +vserver-$(CONFIG_VSERVER_MONITOR) += monitor.o
14663 +vserver-$(CONFIG_VSERVER_DEVICE) += device.o
14664 +
14665 diff -NurpP --minimal linux-3.18.5/kernel/vserver/cacct.c linux-3.18.5-vs2.3.7.3/kernel/vserver/cacct.c
14666 --- linux-3.18.5/kernel/vserver/cacct.c 1970-01-01 00:00:00.000000000 +0000
14667 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/cacct.c       2015-01-19 10:58:31.000000000 +0000
14668 @@ -0,0 +1,42 @@
14669 +/*
14670 + *  linux/kernel/vserver/cacct.c
14671 + *
14672 + *  Virtual Server: Context Accounting
14673 + *
14674 + *  Copyright (C) 2006-2007 Herbert Pötzl
14675 + *
14676 + *  V0.01  added accounting stats
14677 + *
14678 + */
14679 +
14680 +#include <linux/types.h>
14681 +#include <linux/vs_context.h>
14682 +#include <linux/vserver/cacct_cmd.h>
14683 +#include <linux/vserver/cacct_int.h>
14684 +
14685 +#include <asm/errno.h>
14686 +#include <asm/uaccess.h>
14687 +
14688 +
14689 +int vc_sock_stat(struct vx_info *vxi, void __user *data)
14690 +{
14691 +       struct vcmd_sock_stat_v0 vc_data;
14692 +       int j, field;
14693 +
14694 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
14695 +               return -EFAULT;
14696 +
14697 +       field = vc_data.field;
14698 +       if ((field < 0) || (field >= VXA_SOCK_SIZE))
14699 +               return -EINVAL;
14700 +
14701 +       for (j = 0; j < 3; j++) {
14702 +               vc_data.count[j] = vx_sock_count(&vxi->cacct, field, j);
14703 +               vc_data.total[j] = vx_sock_total(&vxi->cacct, field, j);
14704 +       }
14705 +
14706 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
14707 +               return -EFAULT;
14708 +       return 0;
14709 +}
14710 +
14711 diff -NurpP --minimal linux-3.18.5/kernel/vserver/cacct_init.h linux-3.18.5-vs2.3.7.3/kernel/vserver/cacct_init.h
14712 --- linux-3.18.5/kernel/vserver/cacct_init.h    1970-01-01 00:00:00.000000000 +0000
14713 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/cacct_init.h  2015-01-19 10:58:31.000000000 +0000
14714 @@ -0,0 +1,25 @@
14715 +
14716 +
14717 +static inline void vx_info_init_cacct(struct _vx_cacct *cacct)
14718 +{
14719 +       int i, j;
14720 +
14721 +
14722 +       for (i = 0; i < VXA_SOCK_SIZE; i++) {
14723 +               for (j = 0; j < 3; j++) {
14724 +                       atomic_long_set(&cacct->sock[i][j].count, 0);
14725 +                       atomic_long_set(&cacct->sock[i][j].total, 0);
14726 +               }
14727 +       }
14728 +       for (i = 0; i < 8; i++)
14729 +               atomic_set(&cacct->slab[i], 0);
14730 +       for (i = 0; i < 5; i++)
14731 +               for (j = 0; j < 4; j++)
14732 +                       atomic_set(&cacct->page[i][j], 0);
14733 +}
14734 +
14735 +static inline void vx_info_exit_cacct(struct _vx_cacct *cacct)
14736 +{
14737 +       return;
14738 +}
14739 +
14740 diff -NurpP --minimal linux-3.18.5/kernel/vserver/cacct_proc.h linux-3.18.5-vs2.3.7.3/kernel/vserver/cacct_proc.h
14741 --- linux-3.18.5/kernel/vserver/cacct_proc.h    1970-01-01 00:00:00.000000000 +0000
14742 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/cacct_proc.h  2015-01-19 10:58:31.000000000 +0000
14743 @@ -0,0 +1,53 @@
14744 +#ifndef _VX_CACCT_PROC_H
14745 +#define _VX_CACCT_PROC_H
14746 +
14747 +#include <linux/vserver/cacct_int.h>
14748 +
14749 +
14750 +#define VX_SOCKA_TOP   \
14751 +       "Type\t    recv #/bytes\t\t   send #/bytes\t\t    fail #/bytes\n"
14752 +
14753 +static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer)
14754 +{
14755 +       int i, j, length = 0;
14756 +       static char *type[VXA_SOCK_SIZE] = {
14757 +               "UNSPEC", "UNIX", "INET", "INET6", "PACKET", "OTHER"
14758 +       };
14759 +
14760 +       length += sprintf(buffer + length, VX_SOCKA_TOP);
14761 +       for (i = 0; i < VXA_SOCK_SIZE; i++) {
14762 +               length += sprintf(buffer + length, "%s:", type[i]);
14763 +               for (j = 0; j < 3; j++) {
14764 +                       length += sprintf(buffer + length,
14765 +                               "\t%10lu/%-10lu",
14766 +                               vx_sock_count(cacct, i, j),
14767 +                               vx_sock_total(cacct, i, j));
14768 +               }
14769 +               buffer[length++] = '\n';
14770 +       }
14771 +
14772 +       length += sprintf(buffer + length, "\n");
14773 +       length += sprintf(buffer + length,
14774 +               "slab:\t %8u %8u %8u %8u\n",
14775 +               atomic_read(&cacct->slab[1]),
14776 +               atomic_read(&cacct->slab[4]),
14777 +               atomic_read(&cacct->slab[0]),
14778 +               atomic_read(&cacct->slab[2]));
14779 +
14780 +       length += sprintf(buffer + length, "\n");
14781 +       for (i = 0; i < 5; i++) {
14782 +               length += sprintf(buffer + length,
14783 +                       "page[%d]: %8u %8u %8u %8u\t %8u %8u %8u %8u\n", i,
14784 +                       atomic_read(&cacct->page[i][0]),
14785 +                       atomic_read(&cacct->page[i][1]),
14786 +                       atomic_read(&cacct->page[i][2]),
14787 +                       atomic_read(&cacct->page[i][3]),
14788 +                       atomic_read(&cacct->page[i][4]),
14789 +                       atomic_read(&cacct->page[i][5]),
14790 +                       atomic_read(&cacct->page[i][6]),
14791 +                       atomic_read(&cacct->page[i][7]));
14792 +       }
14793 +       return length;
14794 +}
14795 +
14796 +#endif /* _VX_CACCT_PROC_H */
14797 diff -NurpP --minimal linux-3.18.5/kernel/vserver/context.c linux-3.18.5-vs2.3.7.3/kernel/vserver/context.c
14798 --- linux-3.18.5/kernel/vserver/context.c       1970-01-01 00:00:00.000000000 +0000
14799 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/context.c     2015-01-19 10:58:31.000000000 +0000
14800 @@ -0,0 +1,1119 @@
14801 +/*
14802 + *  linux/kernel/vserver/context.c
14803 + *
14804 + *  Virtual Server: Context Support
14805 + *
14806 + *  Copyright (C) 2003-2011  Herbert Pötzl
14807 + *
14808 + *  V0.01  context helper
14809 + *  V0.02  vx_ctx_kill syscall command
14810 + *  V0.03  replaced context_info calls
14811 + *  V0.04  redesign of struct (de)alloc
14812 + *  V0.05  rlimit basic implementation
14813 + *  V0.06  task_xid and info commands
14814 + *  V0.07  context flags and caps
14815 + *  V0.08  switch to RCU based hash
14816 + *  V0.09  revert to non RCU for now
14817 + *  V0.10  and back to working RCU hash
14818 + *  V0.11  and back to locking again
14819 + *  V0.12  referenced context store
14820 + *  V0.13  separate per cpu data
14821 + *  V0.14  changed vcmds to vxi arg
14822 + *  V0.15  added context stat
14823 + *  V0.16  have __create claim() the vxi
14824 + *  V0.17  removed older and legacy stuff
14825 + *  V0.18  added user credentials
14826 + *  V0.19  added warn mask
14827 + *
14828 + */
14829 +
14830 +#include <linux/slab.h>
14831 +#include <linux/types.h>
14832 +#include <linux/security.h>
14833 +#include <linux/pid_namespace.h>
14834 +#include <linux/capability.h>
14835 +
14836 +#include <linux/vserver/context.h>
14837 +#include <linux/vserver/network.h>
14838 +#include <linux/vserver/debug.h>
14839 +#include <linux/vserver/limit.h>
14840 +#include <linux/vserver/limit_int.h>
14841 +#include <linux/vserver/space.h>
14842 +#include <linux/init_task.h>
14843 +#include <linux/fs_struct.h>
14844 +#include <linux/cred.h>
14845 +
14846 +#include <linux/vs_context.h>
14847 +#include <linux/vs_limit.h>
14848 +#include <linux/vs_pid.h>
14849 +#include <linux/vserver/context_cmd.h>
14850 +
14851 +#include "cvirt_init.h"
14852 +#include "cacct_init.h"
14853 +#include "limit_init.h"
14854 +#include "sched_init.h"
14855 +
14856 +
14857 +atomic_t vx_global_ctotal      = ATOMIC_INIT(0);
14858 +atomic_t vx_global_cactive     = ATOMIC_INIT(0);
14859 +
14860 +
14861 +/*     now inactive context structures */
14862 +
14863 +static struct hlist_head vx_info_inactive = HLIST_HEAD_INIT;
14864 +
14865 +static DEFINE_SPINLOCK(vx_info_inactive_lock);
14866 +
14867 +
14868 +/*     __alloc_vx_info()
14869 +
14870 +       * allocate an initialized vx_info struct
14871 +       * doesn't make it visible (hash)                        */
14872 +
14873 +static struct vx_info *__alloc_vx_info(vxid_t xid)
14874 +{
14875 +       struct vx_info *new = NULL;
14876 +       int cpu, index;
14877 +
14878 +       vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid);
14879 +
14880 +       /* would this benefit from a slab cache? */
14881 +       new = kmalloc(sizeof(struct vx_info), GFP_KERNEL);
14882 +       if (!new)
14883 +               return 0;
14884 +
14885 +       memset(new, 0, sizeof(struct vx_info));
14886 +#ifdef CONFIG_SMP
14887 +       new->ptr_pc = alloc_percpu(struct _vx_info_pc);
14888 +       if (!new->ptr_pc)
14889 +               goto error;
14890 +#endif
14891 +       new->vx_id = xid;
14892 +       INIT_HLIST_NODE(&new->vx_hlist);
14893 +       atomic_set(&new->vx_usecnt, 0);
14894 +       atomic_set(&new->vx_tasks, 0);
14895 +       new->vx_parent = NULL;
14896 +       new->vx_state = 0;
14897 +       init_waitqueue_head(&new->vx_wait);
14898 +
14899 +       /* prepare reaper */
14900 +       get_task_struct(init_pid_ns.child_reaper);
14901 +       new->vx_reaper = init_pid_ns.child_reaper;
14902 +       new->vx_badness_bias = 0;
14903 +
14904 +       /* rest of init goes here */
14905 +       vx_info_init_limit(&new->limit);
14906 +       vx_info_init_sched(&new->sched);
14907 +       vx_info_init_cvirt(&new->cvirt);
14908 +       vx_info_init_cacct(&new->cacct);
14909 +
14910 +       /* per cpu data structures */
14911 +       for_each_possible_cpu(cpu) {
14912 +               vx_info_init_sched_pc(
14913 +                       &vx_per_cpu(new, sched_pc, cpu), cpu);
14914 +               vx_info_init_cvirt_pc(
14915 +                       &vx_per_cpu(new, cvirt_pc, cpu), cpu);
14916 +       }
14917 +
14918 +       new->vx_flags = VXF_INIT_SET;
14919 +       new->vx_bcaps = CAP_FULL_SET;   // maybe ~CAP_SETPCAP
14920 +       new->vx_ccaps = 0;
14921 +       new->vx_umask = 0;
14922 +       new->vx_wmask = 0;
14923 +
14924 +       new->reboot_cmd = 0;
14925 +       new->exit_code = 0;
14926 +
14927 +       // preconfig spaces
14928 +       for (index = 0; index < VX_SPACES; index++) {
14929 +               struct _vx_space *space = &new->space[index];
14930 +
14931 +               // filesystem
14932 +               spin_lock(&init_fs.lock);
14933 +               init_fs.users++;
14934 +               spin_unlock(&init_fs.lock);
14935 +               space->vx_fs = &init_fs;
14936 +
14937 +               /* FIXME: do we want defaults? */
14938 +               // space->vx_real_cred = 0;
14939 +               // space->vx_cred = 0;
14940 +       }
14941 +
14942 +
14943 +       vxdprintk(VXD_CBIT(xid, 0),
14944 +               "alloc_vx_info(%d) = %p", xid, new);
14945 +       vxh_alloc_vx_info(new);
14946 +       atomic_inc(&vx_global_ctotal);
14947 +       return new;
14948 +#ifdef CONFIG_SMP
14949 +error:
14950 +       kfree(new);
14951 +       return 0;
14952 +#endif
14953 +}
14954 +
14955 +/*     __dealloc_vx_info()
14956 +
14957 +       * final disposal of vx_info                             */
14958 +
14959 +static void __dealloc_vx_info(struct vx_info *vxi)
14960 +{
14961 +#ifdef CONFIG_VSERVER_WARN
14962 +       struct vx_info_save vxis;
14963 +       int cpu;
14964 +#endif
14965 +       vxdprintk(VXD_CBIT(xid, 0),
14966 +               "dealloc_vx_info(%p)", vxi);
14967 +       vxh_dealloc_vx_info(vxi);
14968 +
14969 +#ifdef CONFIG_VSERVER_WARN
14970 +       enter_vx_info(vxi, &vxis);
14971 +       vx_info_exit_limit(&vxi->limit);
14972 +       vx_info_exit_sched(&vxi->sched);
14973 +       vx_info_exit_cvirt(&vxi->cvirt);
14974 +       vx_info_exit_cacct(&vxi->cacct);
14975 +
14976 +       for_each_possible_cpu(cpu) {
14977 +               vx_info_exit_sched_pc(
14978 +                       &vx_per_cpu(vxi, sched_pc, cpu), cpu);
14979 +               vx_info_exit_cvirt_pc(
14980 +                       &vx_per_cpu(vxi, cvirt_pc, cpu), cpu);
14981 +       }
14982 +       leave_vx_info(&vxis);
14983 +#endif
14984 +
14985 +       vxi->vx_id = -1;
14986 +       vxi->vx_state |= VXS_RELEASED;
14987 +
14988 +#ifdef CONFIG_SMP
14989 +       free_percpu(vxi->ptr_pc);
14990 +#endif
14991 +       kfree(vxi);
14992 +       atomic_dec(&vx_global_ctotal);
14993 +}
14994 +
14995 +static void __shutdown_vx_info(struct vx_info *vxi)
14996 +{
14997 +       struct nsproxy *nsproxy;
14998 +       struct fs_struct *fs;
14999 +       struct cred *cred;
15000 +       int index, kill;
15001 +
15002 +       might_sleep();
15003 +
15004 +       vxi->vx_state |= VXS_SHUTDOWN;
15005 +       vs_state_change(vxi, VSC_SHUTDOWN);
15006 +
15007 +       for (index = 0; index < VX_SPACES; index++) {
15008 +               struct _vx_space *space = &vxi->space[index];
15009 +
15010 +               nsproxy = xchg(&space->vx_nsproxy, NULL);
15011 +               if (nsproxy)
15012 +                       put_nsproxy(nsproxy);
15013 +
15014 +               fs = xchg(&space->vx_fs, NULL);
15015 +               spin_lock(&fs->lock);
15016 +               kill = !--fs->users;
15017 +               spin_unlock(&fs->lock);
15018 +               if (kill)
15019 +                       free_fs_struct(fs);
15020 +
15021 +               cred = (struct cred *)xchg(&space->vx_cred, NULL);
15022 +               if (cred)
15023 +                       abort_creds(cred);
15024 +       }
15025 +}
15026 +
15027 +/* exported stuff */
15028 +
15029 +void free_vx_info(struct vx_info *vxi)
15030 +{
15031 +       unsigned long flags;
15032 +       unsigned index;
15033 +
15034 +       /* check for reference counts first */
15035 +       BUG_ON(atomic_read(&vxi->vx_usecnt));
15036 +       BUG_ON(atomic_read(&vxi->vx_tasks));
15037 +
15038 +       /* context must not be hashed */
15039 +       BUG_ON(vx_info_state(vxi, VXS_HASHED));
15040 +
15041 +       /* context shutdown is mandatory */
15042 +       BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN));
15043 +
15044 +       /* spaces check */
15045 +       for (index = 0; index < VX_SPACES; index++) {
15046 +               struct _vx_space *space = &vxi->space[index];
15047 +
15048 +               BUG_ON(space->vx_nsproxy);
15049 +               BUG_ON(space->vx_fs);
15050 +               // BUG_ON(space->vx_real_cred);
15051 +               // BUG_ON(space->vx_cred);
15052 +       }
15053 +
15054 +       spin_lock_irqsave(&vx_info_inactive_lock, flags);
15055 +       hlist_del(&vxi->vx_hlist);
15056 +       spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
15057 +
15058 +       __dealloc_vx_info(vxi);
15059 +}
15060 +
15061 +
15062 +/*     hash table for vx_info hash */
15063 +
15064 +#define VX_HASH_SIZE   13
15065 +
15066 +static struct hlist_head vx_info_hash[VX_HASH_SIZE] =
15067 +       { [0 ... VX_HASH_SIZE-1] = HLIST_HEAD_INIT };
15068 +
15069 +static DEFINE_SPINLOCK(vx_info_hash_lock);
15070 +
15071 +
15072 +static inline unsigned int __hashval(vxid_t xid)
15073 +{
15074 +       return (xid % VX_HASH_SIZE);
15075 +}
15076 +
15077 +
15078 +
15079 +/*     __hash_vx_info()
15080 +
15081 +       * add the vxi to the global hash table
15082 +       * requires the hash_lock to be held                     */
15083 +
15084 +static inline void __hash_vx_info(struct vx_info *vxi)
15085 +{
15086 +       struct hlist_head *head;
15087 +
15088 +       vxd_assert_lock(&vx_info_hash_lock);
15089 +       vxdprintk(VXD_CBIT(xid, 4),
15090 +               "__hash_vx_info: %p[#%d]", vxi, vxi->vx_id);
15091 +       vxh_hash_vx_info(vxi);
15092 +
15093 +       /* context must not be hashed */
15094 +       BUG_ON(vx_info_state(vxi, VXS_HASHED));
15095 +
15096 +       vxi->vx_state |= VXS_HASHED;
15097 +       head = &vx_info_hash[__hashval(vxi->vx_id)];
15098 +       hlist_add_head(&vxi->vx_hlist, head);
15099 +       atomic_inc(&vx_global_cactive);
15100 +}
15101 +
15102 +/*     __unhash_vx_info()
15103 +
15104 +       * remove the vxi from the global hash table
15105 +       * requires the hash_lock to be held                     */
15106 +
15107 +static inline void __unhash_vx_info(struct vx_info *vxi)
15108 +{
15109 +       unsigned long flags;
15110 +
15111 +       vxd_assert_lock(&vx_info_hash_lock);
15112 +       vxdprintk(VXD_CBIT(xid, 4),
15113 +               "__unhash_vx_info: %p[#%d.%d.%d]", vxi, vxi->vx_id,
15114 +               atomic_read(&vxi->vx_usecnt), atomic_read(&vxi->vx_tasks));
15115 +       vxh_unhash_vx_info(vxi);
15116 +
15117 +       /* context must be hashed */
15118 +       BUG_ON(!vx_info_state(vxi, VXS_HASHED));
15119 +       /* but without tasks */
15120 +       BUG_ON(atomic_read(&vxi->vx_tasks));
15121 +
15122 +       vxi->vx_state &= ~VXS_HASHED;
15123 +       hlist_del_init(&vxi->vx_hlist);
15124 +       spin_lock_irqsave(&vx_info_inactive_lock, flags);
15125 +       hlist_add_head(&vxi->vx_hlist, &vx_info_inactive);
15126 +       spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
15127 +       atomic_dec(&vx_global_cactive);
15128 +}
15129 +
15130 +
15131 +/*     __lookup_vx_info()
15132 +
15133 +       * requires the hash_lock to be held
15134 +       * doesn't increment the vx_refcnt                       */
15135 +
15136 +static inline struct vx_info *__lookup_vx_info(vxid_t xid)
15137 +{
15138 +       struct hlist_head *head = &vx_info_hash[__hashval(xid)];
15139 +       struct hlist_node *pos;
15140 +       struct vx_info *vxi;
15141 +
15142 +       vxd_assert_lock(&vx_info_hash_lock);
15143 +       hlist_for_each(pos, head) {
15144 +               vxi = hlist_entry(pos, struct vx_info, vx_hlist);
15145 +
15146 +               if (vxi->vx_id == xid)
15147 +                       goto found;
15148 +       }
15149 +       vxi = NULL;
15150 +found:
15151 +       vxdprintk(VXD_CBIT(xid, 0),
15152 +               "__lookup_vx_info(#%u): %p[#%u]",
15153 +               xid, vxi, vxi ? vxi->vx_id : 0);
15154 +       vxh_lookup_vx_info(vxi, xid);
15155 +       return vxi;
15156 +}
15157 +
15158 +
15159 +/*     __create_vx_info()
15160 +
15161 +       * create the requested context
15162 +       * get(), claim() and hash it                            */
15163 +
15164 +static struct vx_info *__create_vx_info(int id)
15165 +{
15166 +       struct vx_info *new, *vxi = NULL;
15167 +
15168 +       vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id);
15169 +
15170 +       if (!(new = __alloc_vx_info(id)))
15171 +               return ERR_PTR(-ENOMEM);
15172 +
15173 +       /* required to make dynamic xids unique */
15174 +       spin_lock(&vx_info_hash_lock);
15175 +
15176 +       /* static context requested */
15177 +       if ((vxi = __lookup_vx_info(id))) {
15178 +               vxdprintk(VXD_CBIT(xid, 0),
15179 +                       "create_vx_info(%d) = %p (already there)", id, vxi);
15180 +               if (vx_info_flags(vxi, VXF_STATE_SETUP, 0))
15181 +                       vxi = ERR_PTR(-EBUSY);
15182 +               else
15183 +                       vxi = ERR_PTR(-EEXIST);
15184 +               goto out_unlock;
15185 +       }
15186 +       /* new context */
15187 +       vxdprintk(VXD_CBIT(xid, 0),
15188 +               "create_vx_info(%d) = %p (new)", id, new);
15189 +       claim_vx_info(new, NULL);
15190 +       __hash_vx_info(get_vx_info(new));
15191 +       vxi = new, new = NULL;
15192 +
15193 +out_unlock:
15194 +       spin_unlock(&vx_info_hash_lock);
15195 +       vxh_create_vx_info(IS_ERR(vxi) ? NULL : vxi, id);
15196 +       if (new)
15197 +               __dealloc_vx_info(new);
15198 +       return vxi;
15199 +}
15200 +
15201 +
15202 +/*     exported stuff                                          */
15203 +
15204 +
15205 +void unhash_vx_info(struct vx_info *vxi)
15206 +{
15207 +       spin_lock(&vx_info_hash_lock);
15208 +       __unhash_vx_info(vxi);
15209 +       spin_unlock(&vx_info_hash_lock);
15210 +       __shutdown_vx_info(vxi);
15211 +       __wakeup_vx_info(vxi);
15212 +}
15213 +
15214 +
15215 +/*     lookup_vx_info()
15216 +
15217 +       * search for a vx_info and get() it
15218 +       * negative id means current                             */
15219 +
15220 +struct vx_info *lookup_vx_info(int id)
15221 +{
15222 +       struct vx_info *vxi = NULL;
15223 +
15224 +       if (id < 0) {
15225 +               vxi = get_vx_info(current_vx_info());
15226 +       } else if (id > 1) {
15227 +               spin_lock(&vx_info_hash_lock);
15228 +               vxi = get_vx_info(__lookup_vx_info(id));
15229 +               spin_unlock(&vx_info_hash_lock);
15230 +       }
15231 +       return vxi;
15232 +}
15233 +
15234 +/*     xid_is_hashed()
15235 +
15236 +       * verify that xid is still hashed                       */
15237 +
15238 +int xid_is_hashed(vxid_t xid)
15239 +{
15240 +       int hashed;
15241 +
15242 +       spin_lock(&vx_info_hash_lock);
15243 +       hashed = (__lookup_vx_info(xid) != NULL);
15244 +       spin_unlock(&vx_info_hash_lock);
15245 +       return hashed;
15246 +}
15247 +
15248 +#ifdef CONFIG_PROC_FS
15249 +
15250 +/*     get_xid_list()
15251 +
15252 +       * get a subset of hashed xids for proc
15253 +       * assumes size is at least one                          */
15254 +
15255 +int get_xid_list(int index, unsigned int *xids, int size)
15256 +{
15257 +       int hindex, nr_xids = 0;
15258 +
15259 +       /* only show current and children */
15260 +       if (!vx_check(0, VS_ADMIN | VS_WATCH)) {
15261 +               if (index > 0)
15262 +                       return 0;
15263 +               xids[nr_xids] = vx_current_xid();
15264 +               return 1;
15265 +       }
15266 +
15267 +       for (hindex = 0; hindex < VX_HASH_SIZE; hindex++) {
15268 +               struct hlist_head *head = &vx_info_hash[hindex];
15269 +               struct hlist_node *pos;
15270 +
15271 +               spin_lock(&vx_info_hash_lock);
15272 +               hlist_for_each(pos, head) {
15273 +                       struct vx_info *vxi;
15274 +
15275 +                       if (--index > 0)
15276 +                               continue;
15277 +
15278 +                       vxi = hlist_entry(pos, struct vx_info, vx_hlist);
15279 +                       xids[nr_xids] = vxi->vx_id;
15280 +                       if (++nr_xids >= size) {
15281 +                               spin_unlock(&vx_info_hash_lock);
15282 +                               goto out;
15283 +                       }
15284 +               }
15285 +               /* keep the lock time short */
15286 +               spin_unlock(&vx_info_hash_lock);
15287 +       }
15288 +out:
15289 +       return nr_xids;
15290 +}
15291 +#endif
15292 +
15293 +#ifdef CONFIG_VSERVER_DEBUG
15294 +
15295 +void   dump_vx_info_inactive(int level)
15296 +{
15297 +       struct hlist_node *entry, *next;
15298 +
15299 +       hlist_for_each_safe(entry, next, &vx_info_inactive) {
15300 +               struct vx_info *vxi =
15301 +                       list_entry(entry, struct vx_info, vx_hlist);
15302 +
15303 +               dump_vx_info(vxi, level);
15304 +       }
15305 +}
15306 +
15307 +#endif
15308 +
15309 +#if 0
15310 +int vx_migrate_user(struct task_struct *p, struct vx_info *vxi)
15311 +{
15312 +       struct user_struct *new_user, *old_user;
15313 +
15314 +       if (!p || !vxi)
15315 +               BUG();
15316 +
15317 +       if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
15318 +               return -EACCES;
15319 +
15320 +       new_user = alloc_uid(vxi->vx_id, p->uid);
15321 +       if (!new_user)
15322 +               return -ENOMEM;
15323 +
15324 +       old_user = p->user;
15325 +       if (new_user != old_user) {
15326 +               atomic_inc(&new_user->processes);
15327 +               atomic_dec(&old_user->processes);
15328 +               p->user = new_user;
15329 +       }
15330 +       free_uid(old_user);
15331 +       return 0;
15332 +}
15333 +#endif
15334 +
15335 +#if 0
15336 +void vx_mask_cap_bset(struct vx_info *vxi, struct task_struct *p)
15337 +{
15338 +       // p->cap_effective &= vxi->vx_cap_bset;
15339 +       p->cap_effective =
15340 +               cap_intersect(p->cap_effective, vxi->cap_bset);
15341 +       // p->cap_inheritable &= vxi->vx_cap_bset;
15342 +       p->cap_inheritable =
15343 +               cap_intersect(p->cap_inheritable, vxi->cap_bset);
15344 +       // p->cap_permitted &= vxi->vx_cap_bset;
15345 +       p->cap_permitted =
15346 +               cap_intersect(p->cap_permitted, vxi->cap_bset);
15347 +}
15348 +#endif
15349 +
15350 +
15351 +#include <linux/file.h>
15352 +#include <linux/fdtable.h>
15353 +
15354 +static int vx_openfd_task(struct task_struct *tsk)
15355 +{
15356 +       struct files_struct *files = tsk->files;
15357 +       struct fdtable *fdt;
15358 +       const unsigned long *bptr;
15359 +       int count, total;
15360 +
15361 +       /* no rcu_read_lock() because of spin_lock() */
15362 +       spin_lock(&files->file_lock);
15363 +       fdt = files_fdtable(files);
15364 +       bptr = fdt->open_fds;
15365 +       count = fdt->max_fds / (sizeof(unsigned long) * 8);
15366 +       for (total = 0; count > 0; count--) {
15367 +               if (*bptr)
15368 +                       total += hweight_long(*bptr);
15369 +               bptr++;
15370 +       }
15371 +       spin_unlock(&files->file_lock);
15372 +       return total;
15373 +}
15374 +
15375 +
15376 +/*     for *space compatibility */
15377 +
15378 +asmlinkage long sys_unshare(unsigned long);
15379 +
15380 +/*
15381 + *     migrate task to new context
15382 + *     gets vxi, puts old_vxi on change
15383 + *     optionally unshares namespaces (hack)
15384 + */
15385 +
15386 +int vx_migrate_task(struct task_struct *p, struct vx_info *vxi, int unshare)
15387 +{
15388 +       struct vx_info *old_vxi;
15389 +       int ret = 0;
15390 +
15391 +       if (!p || !vxi)
15392 +               BUG();
15393 +
15394 +       vxdprintk(VXD_CBIT(xid, 5),
15395 +               "vx_migrate_task(%p,%p[#%d.%d])", p, vxi,
15396 +               vxi->vx_id, atomic_read(&vxi->vx_usecnt));
15397 +
15398 +       if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0) &&
15399 +               !vx_info_flags(vxi, VXF_STATE_SETUP, 0))
15400 +               return -EACCES;
15401 +
15402 +       if (vx_info_state(vxi, VXS_SHUTDOWN))
15403 +               return -EFAULT;
15404 +
15405 +       old_vxi = task_get_vx_info(p);
15406 +       if (old_vxi == vxi)
15407 +               goto out;
15408 +
15409 +//     if (!(ret = vx_migrate_user(p, vxi))) {
15410 +       {
15411 +               int openfd;
15412 +
15413 +               task_lock(p);
15414 +               openfd = vx_openfd_task(p);
15415 +
15416 +               if (old_vxi) {
15417 +                       atomic_dec(&old_vxi->cvirt.nr_threads);
15418 +                       atomic_dec(&old_vxi->cvirt.nr_running);
15419 +                       __rlim_dec(&old_vxi->limit, RLIMIT_NPROC);
15420 +                       /* FIXME: what about the struct files here? */
15421 +                       __rlim_sub(&old_vxi->limit, VLIMIT_OPENFD, openfd);
15422 +                       /* account for the executable */
15423 +                       __rlim_dec(&old_vxi->limit, VLIMIT_DENTRY);
15424 +               }
15425 +               atomic_inc(&vxi->cvirt.nr_threads);
15426 +               atomic_inc(&vxi->cvirt.nr_running);
15427 +               __rlim_inc(&vxi->limit, RLIMIT_NPROC);
15428 +               /* FIXME: what about the struct files here? */
15429 +               __rlim_add(&vxi->limit, VLIMIT_OPENFD, openfd);
15430 +               /* account for the executable */
15431 +               __rlim_inc(&vxi->limit, VLIMIT_DENTRY);
15432 +
15433 +               if (old_vxi) {
15434 +                       release_vx_info(old_vxi, p);
15435 +                       clr_vx_info(&p->vx_info);
15436 +               }
15437 +               claim_vx_info(vxi, p);
15438 +               set_vx_info(&p->vx_info, vxi);
15439 +               p->xid = vxi->vx_id;
15440 +
15441 +               vxdprintk(VXD_CBIT(xid, 5),
15442 +                       "moved task %p into vxi:%p[#%d]",
15443 +                       p, vxi, vxi->vx_id);
15444 +
15445 +               // vx_mask_cap_bset(vxi, p);
15446 +               task_unlock(p);
15447 +
15448 +               /* hack for *spaces to provide compatibility */
15449 +               if (unshare) {
15450 +                       struct nsproxy *old_nsp, *new_nsp;
15451 +
15452 +                       ret = unshare_nsproxy_namespaces(
15453 +                               CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER,
15454 +                               &new_nsp, NULL, NULL);
15455 +                       if (ret)
15456 +                               goto out;
15457 +
15458 +                       old_nsp = xchg(&p->nsproxy, new_nsp);
15459 +                       vx_set_space(vxi,
15460 +                               CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER, 0);
15461 +                       put_nsproxy(old_nsp);
15462 +               }
15463 +       }
15464 +out:
15465 +       put_vx_info(old_vxi);
15466 +       return ret;
15467 +}
15468 +
15469 +int vx_set_reaper(struct vx_info *vxi, struct task_struct *p)
15470 +{
15471 +       struct task_struct *old_reaper;
15472 +       struct vx_info *reaper_vxi;
15473 +
15474 +       if (!vxi)
15475 +               return -EINVAL;
15476 +
15477 +       vxdprintk(VXD_CBIT(xid, 6),
15478 +               "vx_set_reaper(%p[#%d],%p[#%d,%d])",
15479 +               vxi, vxi->vx_id, p, p->xid, p->pid);
15480 +
15481 +       old_reaper = vxi->vx_reaper;
15482 +       if (old_reaper == p)
15483 +               return 0;
15484 +
15485 +       reaper_vxi = task_get_vx_info(p);
15486 +       if (reaper_vxi && reaper_vxi != vxi) {
15487 +               vxwprintk(1,
15488 +                       "Unsuitable reaper [" VS_Q("%s") ",%u:#%u] "
15489 +                       "for [xid #%u]",
15490 +                       p->comm, p->pid, p->xid, vx_current_xid());
15491 +               goto out;
15492 +       }
15493 +
15494 +       /* set new child reaper */
15495 +       get_task_struct(p);
15496 +       vxi->vx_reaper = p;
15497 +       put_task_struct(old_reaper);
15498 +out:
15499 +       put_vx_info(reaper_vxi);
15500 +       return 0;
15501 +}
15502 +
15503 +int vx_set_init(struct vx_info *vxi, struct task_struct *p)
15504 +{
15505 +       if (!vxi)
15506 +               return -EINVAL;
15507 +
15508 +       vxdprintk(VXD_CBIT(xid, 6),
15509 +               "vx_set_init(%p[#%d],%p[#%d,%d,%d])",
15510 +               vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
15511 +
15512 +       vxi->vx_flags &= ~VXF_STATE_INIT;
15513 +       // vxi->vx_initpid = p->tgid;
15514 +       vxi->vx_initpid = p->pid;
15515 +       return 0;
15516 +}
15517 +
15518 +void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code)
15519 +{
15520 +       vxdprintk(VXD_CBIT(xid, 6),
15521 +               "vx_exit_init(%p[#%d],%p[#%d,%d,%d])",
15522 +               vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
15523 +
15524 +       vxi->exit_code = code;
15525 +       vxi->vx_initpid = 0;
15526 +}
15527 +
15528 +
15529 +void vx_set_persistent(struct vx_info *vxi)
15530 +{
15531 +       vxdprintk(VXD_CBIT(xid, 6),
15532 +               "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id);
15533 +
15534 +       get_vx_info(vxi);
15535 +       claim_vx_info(vxi, NULL);
15536 +}
15537 +
15538 +void vx_clear_persistent(struct vx_info *vxi)
15539 +{
15540 +       vxdprintk(VXD_CBIT(xid, 6),
15541 +               "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id);
15542 +
15543 +       release_vx_info(vxi, NULL);
15544 +       put_vx_info(vxi);
15545 +}
15546 +
15547 +void vx_update_persistent(struct vx_info *vxi)
15548 +{
15549 +       if (vx_info_flags(vxi, VXF_PERSISTENT, 0))
15550 +               vx_set_persistent(vxi);
15551 +       else
15552 +               vx_clear_persistent(vxi);
15553 +}
15554 +
15555 +
15556 +/*     task must be current or locked          */
15557 +
15558 +void   exit_vx_info(struct task_struct *p, int code)
15559 +{
15560 +       struct vx_info *vxi = p->vx_info;
15561 +
15562 +       if (vxi) {
15563 +               atomic_dec(&vxi->cvirt.nr_threads);
15564 +               vx_nproc_dec(p);
15565 +
15566 +               vxi->exit_code = code;
15567 +               release_vx_info(vxi, p);
15568 +       }
15569 +}
15570 +
15571 +void   exit_vx_info_early(struct task_struct *p, int code)
15572 +{
15573 +       struct vx_info *vxi = p->vx_info;
15574 +
15575 +       if (vxi) {
15576 +               if (vxi->vx_initpid == p->pid)
15577 +                       vx_exit_init(vxi, p, code);
15578 +               if (vxi->vx_reaper == p)
15579 +                       vx_set_reaper(vxi, init_pid_ns.child_reaper);
15580 +       }
15581 +}
15582 +
15583 +
15584 +/* vserver syscall commands below here */
15585 +
15586 +/* taks xid and vx_info functions */
15587 +
15588 +#include <asm/uaccess.h>
15589 +
15590 +
15591 +int vc_task_xid(uint32_t id)
15592 +{
15593 +       vxid_t xid;
15594 +
15595 +       if (id) {
15596 +               struct task_struct *tsk;
15597 +
15598 +               rcu_read_lock();
15599 +               tsk = find_task_by_real_pid(id);
15600 +               xid = (tsk) ? tsk->xid : -ESRCH;
15601 +               rcu_read_unlock();
15602 +       } else
15603 +               xid = vx_current_xid();
15604 +       return xid;
15605 +}
15606 +
15607 +
15608 +int vc_vx_info(struct vx_info *vxi, void __user *data)
15609 +{
15610 +       struct vcmd_vx_info_v0 vc_data;
15611 +
15612 +       vc_data.xid = vxi->vx_id;
15613 +       vc_data.initpid = vxi->vx_initpid;
15614 +
15615 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15616 +               return -EFAULT;
15617 +       return 0;
15618 +}
15619 +
15620 +
15621 +int vc_ctx_stat(struct vx_info *vxi, void __user *data)
15622 +{
15623 +       struct vcmd_ctx_stat_v0 vc_data;
15624 +
15625 +       vc_data.usecnt = atomic_read(&vxi->vx_usecnt);
15626 +       vc_data.tasks = atomic_read(&vxi->vx_tasks);
15627 +
15628 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15629 +               return -EFAULT;
15630 +       return 0;
15631 +}
15632 +
15633 +
15634 +/* context functions */
15635 +
15636 +int vc_ctx_create(uint32_t xid, void __user *data)
15637 +{
15638 +       struct vcmd_ctx_create vc_data = { .flagword = VXF_INIT_SET };
15639 +       struct vx_info *new_vxi;
15640 +       int ret;
15641 +
15642 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
15643 +               return -EFAULT;
15644 +
15645 +       if ((xid > MAX_S_CONTEXT) || (xid < 2))
15646 +               return -EINVAL;
15647 +
15648 +       new_vxi = __create_vx_info(xid);
15649 +       if (IS_ERR(new_vxi))
15650 +               return PTR_ERR(new_vxi);
15651 +
15652 +       /* initial flags */
15653 +       new_vxi->vx_flags = vc_data.flagword;
15654 +
15655 +       ret = -ENOEXEC;
15656 +       if (vs_state_change(new_vxi, VSC_STARTUP))
15657 +               goto out;
15658 +
15659 +       ret = vx_migrate_task(current, new_vxi, (!data));
15660 +       if (ret)
15661 +               goto out;
15662 +
15663 +       /* return context id on success */
15664 +       ret = new_vxi->vx_id;
15665 +
15666 +       /* get a reference for persistent contexts */
15667 +       if ((vc_data.flagword & VXF_PERSISTENT))
15668 +               vx_set_persistent(new_vxi);
15669 +out:
15670 +       release_vx_info(new_vxi, NULL);
15671 +       put_vx_info(new_vxi);
15672 +       return ret;
15673 +}
15674 +
15675 +
15676 +int vc_ctx_migrate(struct vx_info *vxi, void __user *data)
15677 +{
15678 +       struct vcmd_ctx_migrate vc_data = { .flagword = 0 };
15679 +       int ret;
15680 +
15681 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
15682 +               return -EFAULT;
15683 +
15684 +       ret = vx_migrate_task(current, vxi, 0);
15685 +       if (ret)
15686 +               return ret;
15687 +       if (vc_data.flagword & VXM_SET_INIT)
15688 +               ret = vx_set_init(vxi, current);
15689 +       if (ret)
15690 +               return ret;
15691 +       if (vc_data.flagword & VXM_SET_REAPER)
15692 +               ret = vx_set_reaper(vxi, current);
15693 +       return ret;
15694 +}
15695 +
15696 +
15697 +int vc_get_cflags(struct vx_info *vxi, void __user *data)
15698 +{
15699 +       struct vcmd_ctx_flags_v0 vc_data;
15700 +
15701 +       vc_data.flagword = vxi->vx_flags;
15702 +
15703 +       /* special STATE flag handling */
15704 +       vc_data.mask = vs_mask_flags(~0ULL, vxi->vx_flags, VXF_ONE_TIME);
15705 +
15706 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15707 +               return -EFAULT;
15708 +       return 0;
15709 +}
15710 +
15711 +int vc_set_cflags(struct vx_info *vxi, void __user *data)
15712 +{
15713 +       struct vcmd_ctx_flags_v0 vc_data;
15714 +       uint64_t mask, trigger;
15715 +
15716 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15717 +               return -EFAULT;
15718 +
15719 +       /* special STATE flag handling */
15720 +       mask = vs_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME);
15721 +       trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword);
15722 +
15723 +       if (vxi == current_vx_info()) {
15724 +               /* if (trigger & VXF_STATE_SETUP)
15725 +                       vx_mask_cap_bset(vxi, current); */
15726 +               if (trigger & VXF_STATE_INIT) {
15727 +                       int ret;
15728 +
15729 +                       ret = vx_set_init(vxi, current);
15730 +                       if (ret)
15731 +                               return ret;
15732 +                       ret = vx_set_reaper(vxi, current);
15733 +                       if (ret)
15734 +                               return ret;
15735 +               }
15736 +       }
15737 +
15738 +       vxi->vx_flags = vs_mask_flags(vxi->vx_flags,
15739 +               vc_data.flagword, mask);
15740 +       if (trigger & VXF_PERSISTENT)
15741 +               vx_update_persistent(vxi);
15742 +
15743 +       return 0;
15744 +}
15745 +
15746 +
15747 +static inline uint64_t caps_from_cap_t(kernel_cap_t c)
15748 +{
15749 +       uint64_t v = c.cap[0] | ((uint64_t)c.cap[1] << 32);
15750 +
15751 +       // printk("caps_from_cap_t(%08x:%08x) = %016llx\n", c.cap[1], c.cap[0], v);
15752 +       return v;
15753 +}
15754 +
15755 +static inline kernel_cap_t cap_t_from_caps(uint64_t v)
15756 +{
15757 +       kernel_cap_t c = __cap_empty_set;
15758 +
15759 +       c.cap[0] = v & 0xFFFFFFFF;
15760 +       c.cap[1] = (v >> 32) & 0xFFFFFFFF;
15761 +
15762 +       // printk("cap_t_from_caps(%016llx) = %08x:%08x\n", v, c.cap[1], c.cap[0]);
15763 +       return c;
15764 +}
15765 +
15766 +
15767 +static int do_get_caps(struct vx_info *vxi, uint64_t *bcaps, uint64_t *ccaps)
15768 +{
15769 +       if (bcaps)
15770 +               *bcaps = caps_from_cap_t(vxi->vx_bcaps);
15771 +       if (ccaps)
15772 +               *ccaps = vxi->vx_ccaps;
15773 +
15774 +       return 0;
15775 +}
15776 +
15777 +int vc_get_ccaps(struct vx_info *vxi, void __user *data)
15778 +{
15779 +       struct vcmd_ctx_caps_v1 vc_data;
15780 +       int ret;
15781 +
15782 +       ret = do_get_caps(vxi, NULL, &vc_data.ccaps);
15783 +       if (ret)
15784 +               return ret;
15785 +       vc_data.cmask = ~0ULL;
15786 +
15787 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15788 +               return -EFAULT;
15789 +       return 0;
15790 +}
15791 +
15792 +static int do_set_caps(struct vx_info *vxi,
15793 +       uint64_t bcaps, uint64_t bmask, uint64_t ccaps, uint64_t cmask)
15794 +{
15795 +       uint64_t bcold = caps_from_cap_t(vxi->vx_bcaps);
15796 +
15797 +#if 0
15798 +       printk("do_set_caps(%16llx, %16llx, %16llx, %16llx)\n",
15799 +               bcaps, bmask, ccaps, cmask);
15800 +#endif
15801 +       vxi->vx_bcaps = cap_t_from_caps(
15802 +               vs_mask_flags(bcold, bcaps, bmask));
15803 +       vxi->vx_ccaps = vs_mask_flags(vxi->vx_ccaps, ccaps, cmask);
15804 +
15805 +       return 0;
15806 +}
15807 +
15808 +int vc_set_ccaps(struct vx_info *vxi, void __user *data)
15809 +{
15810 +       struct vcmd_ctx_caps_v1 vc_data;
15811 +
15812 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15813 +               return -EFAULT;
15814 +
15815 +       return do_set_caps(vxi, 0, 0, vc_data.ccaps, vc_data.cmask);
15816 +}
15817 +
15818 +int vc_get_bcaps(struct vx_info *vxi, void __user *data)
15819 +{
15820 +       struct vcmd_bcaps vc_data;
15821 +       int ret;
15822 +
15823 +       ret = do_get_caps(vxi, &vc_data.bcaps, NULL);
15824 +       if (ret)
15825 +               return ret;
15826 +       vc_data.bmask = ~0ULL;
15827 +
15828 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15829 +               return -EFAULT;
15830 +       return 0;
15831 +}
15832 +
15833 +int vc_set_bcaps(struct vx_info *vxi, void __user *data)
15834 +{
15835 +       struct vcmd_bcaps vc_data;
15836 +
15837 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15838 +               return -EFAULT;
15839 +
15840 +       return do_set_caps(vxi, vc_data.bcaps, vc_data.bmask, 0, 0);
15841 +}
15842 +
15843 +
15844 +int vc_get_umask(struct vx_info *vxi, void __user *data)
15845 +{
15846 +       struct vcmd_umask vc_data;
15847 +
15848 +       vc_data.umask = vxi->vx_umask;
15849 +       vc_data.mask = ~0ULL;
15850 +
15851 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15852 +               return -EFAULT;
15853 +       return 0;
15854 +}
15855 +
15856 +int vc_set_umask(struct vx_info *vxi, void __user *data)
15857 +{
15858 +       struct vcmd_umask vc_data;
15859 +
15860 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15861 +               return -EFAULT;
15862 +
15863 +       vxi->vx_umask = vs_mask_flags(vxi->vx_umask,
15864 +               vc_data.umask, vc_data.mask);
15865 +       return 0;
15866 +}
15867 +
15868 +
15869 +int vc_get_wmask(struct vx_info *vxi, void __user *data)
15870 +{
15871 +       struct vcmd_wmask vc_data;
15872 +
15873 +       vc_data.wmask = vxi->vx_wmask;
15874 +       vc_data.mask = ~0ULL;
15875 +
15876 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15877 +               return -EFAULT;
15878 +       return 0;
15879 +}
15880 +
15881 +int vc_set_wmask(struct vx_info *vxi, void __user *data)
15882 +{
15883 +       struct vcmd_wmask vc_data;
15884 +
15885 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15886 +               return -EFAULT;
15887 +
15888 +       vxi->vx_wmask = vs_mask_flags(vxi->vx_wmask,
15889 +               vc_data.wmask, vc_data.mask);
15890 +       return 0;
15891 +}
15892 +
15893 +
15894 +int vc_get_badness(struct vx_info *vxi, void __user *data)
15895 +{
15896 +       struct vcmd_badness_v0 vc_data;
15897 +
15898 +       vc_data.bias = vxi->vx_badness_bias;
15899 +
15900 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15901 +               return -EFAULT;
15902 +       return 0;
15903 +}
15904 +
15905 +int vc_set_badness(struct vx_info *vxi, void __user *data)
15906 +{
15907 +       struct vcmd_badness_v0 vc_data;
15908 +
15909 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15910 +               return -EFAULT;
15911 +
15912 +       vxi->vx_badness_bias = vc_data.bias;
15913 +       return 0;
15914 +}
15915 +
15916 +#include <linux/module.h>
15917 +
15918 +EXPORT_SYMBOL_GPL(free_vx_info);
15919 +
15920 diff -NurpP --minimal linux-3.18.5/kernel/vserver/cvirt.c linux-3.18.5-vs2.3.7.3/kernel/vserver/cvirt.c
15921 --- linux-3.18.5/kernel/vserver/cvirt.c 1970-01-01 00:00:00.000000000 +0000
15922 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/cvirt.c       2015-01-19 10:58:31.000000000 +0000
15923 @@ -0,0 +1,313 @@
15924 +/*
15925 + *  linux/kernel/vserver/cvirt.c
15926 + *
15927 + *  Virtual Server: Context Virtualization
15928 + *
15929 + *  Copyright (C) 2004-2007  Herbert Pötzl
15930 + *
15931 + *  V0.01  broken out from limit.c
15932 + *  V0.02  added utsname stuff
15933 + *  V0.03  changed vcmds to vxi arg
15934 + *
15935 + */
15936 +
15937 +#include <linux/types.h>
15938 +#include <linux/utsname.h>
15939 +#include <linux/vs_cvirt.h>
15940 +#include <linux/vserver/switch.h>
15941 +#include <linux/vserver/cvirt_cmd.h>
15942 +
15943 +#include <asm/uaccess.h>
15944 +
15945 +
15946 +void vx_vsi_boottime(struct timespec *boottime)
15947 +{
15948 +       struct vx_info *vxi = current_vx_info();
15949 +
15950 +       set_normalized_timespec(boottime,
15951 +               boottime->tv_sec + vxi->cvirt.bias_uptime.tv_sec,
15952 +               boottime->tv_nsec + vxi->cvirt.bias_uptime.tv_nsec);
15953 +       return;
15954 +}
15955 +
15956 +void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle)
15957 +{
15958 +       struct vx_info *vxi = current_vx_info();
15959 +
15960 +       set_normalized_timespec(uptime,
15961 +               uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec,
15962 +               uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec);
15963 +       if (!idle)
15964 +               return;
15965 +       set_normalized_timespec(idle,
15966 +               idle->tv_sec - vxi->cvirt.bias_idle.tv_sec,
15967 +               idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec);
15968 +       return;
15969 +}
15970 +
15971 +uint64_t vx_idle_jiffies(void)
15972 +{
15973 +       return init_task.utime + init_task.stime;
15974 +}
15975 +
15976 +
15977 +
15978 +static inline uint32_t __update_loadavg(uint32_t load,
15979 +       int wsize, int delta, int n)
15980 +{
15981 +       unsigned long long calc, prev;
15982 +
15983 +       /* just set it to n */
15984 +       if (unlikely(delta >= wsize))
15985 +               return (n << FSHIFT);
15986 +
15987 +       calc = delta * n;
15988 +       calc <<= FSHIFT;
15989 +       prev = (wsize - delta);
15990 +       prev *= load;
15991 +       calc += prev;
15992 +       do_div(calc, wsize);
15993 +       return calc;
15994 +}
15995 +
15996 +
15997 +void vx_update_load(struct vx_info *vxi)
15998 +{
15999 +       uint32_t now, last, delta;
16000 +       unsigned int nr_running, nr_uninterruptible;
16001 +       unsigned int total;
16002 +       unsigned long flags;
16003 +
16004 +       spin_lock_irqsave(&vxi->cvirt.load_lock, flags);
16005 +
16006 +       now = jiffies;
16007 +       last = vxi->cvirt.load_last;
16008 +       delta = now - last;
16009 +
16010 +       if (delta < 5*HZ)
16011 +               goto out;
16012 +
16013 +       nr_running = atomic_read(&vxi->cvirt.nr_running);
16014 +       nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible);
16015 +       total = nr_running + nr_uninterruptible;
16016 +
16017 +       vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0],
16018 +               60*HZ, delta, total);
16019 +       vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
16020 +               5*60*HZ, delta, total);
16021 +       vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
16022 +               15*60*HZ, delta, total);
16023 +
16024 +       vxi->cvirt.load_last = now;
16025 +out:
16026 +       atomic_inc(&vxi->cvirt.load_updates);
16027 +       spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags);
16028 +}
16029 +
16030 +
16031 +/*
16032 + * Commands to do_syslog:
16033 + *
16034 + *      0 -- Close the log.  Currently a NOP.
16035 + *      1 -- Open the log. Currently a NOP.
16036 + *      2 -- Read from the log.
16037 + *      3 -- Read all messages remaining in the ring buffer.
16038 + *      4 -- Read and clear all messages remaining in the ring buffer
16039 + *      5 -- Clear ring buffer.
16040 + *      6 -- Disable printk's to console
16041 + *      7 -- Enable printk's to console
16042 + *      8 -- Set level of messages printed to console
16043 + *      9 -- Return number of unread characters in the log buffer
16044 + *     10 -- Return size of the log buffer
16045 + */
16046 +int vx_do_syslog(int type, char __user *buf, int len)
16047 +{
16048 +       int error = 0;
16049 +       int do_clear = 0;
16050 +       struct vx_info *vxi = current_vx_info();
16051 +       struct _vx_syslog *log;
16052 +
16053 +       if (!vxi)
16054 +               return -EINVAL;
16055 +       log = &vxi->cvirt.syslog;
16056 +
16057 +       switch (type) {
16058 +       case 0:         /* Close log */
16059 +       case 1:         /* Open log */
16060 +               break;
16061 +       case 2:         /* Read from log */
16062 +               error = wait_event_interruptible(log->log_wait,
16063 +                       (log->log_start - log->log_end));
16064 +               if (error)
16065 +                       break;
16066 +               spin_lock_irq(&log->logbuf_lock);
16067 +               spin_unlock_irq(&log->logbuf_lock);
16068 +               break;
16069 +       case 4:         /* Read/clear last kernel messages */
16070 +               do_clear = 1;
16071 +               /* fall through */
16072 +       case 3:         /* Read last kernel messages */
16073 +               return 0;
16074 +
16075 +       case 5:         /* Clear ring buffer */
16076 +               return 0;
16077 +
16078 +       case 6:         /* Disable logging to console */
16079 +       case 7:         /* Enable logging to console */
16080 +       case 8:         /* Set level of messages printed to console */
16081 +               break;
16082 +
16083 +       case 9:         /* Number of chars in the log buffer */
16084 +               return 0;
16085 +       case 10:        /* Size of the log buffer */
16086 +               return 0;
16087 +       default:
16088 +               error = -EINVAL;
16089 +               break;
16090 +       }
16091 +       return error;
16092 +}
16093 +
16094 +
16095 +/* virtual host info names */
16096 +
16097 +static char *vx_vhi_name(struct vx_info *vxi, int id)
16098 +{
16099 +       struct nsproxy *nsproxy;
16100 +       struct uts_namespace *uts;
16101 +
16102 +       if (id == VHIN_CONTEXT)
16103 +               return vxi->vx_name;
16104 +
16105 +       nsproxy = vxi->space[0].vx_nsproxy;
16106 +       if (!nsproxy)
16107 +               return NULL;
16108 +
16109 +       uts = nsproxy->uts_ns;
16110 +       if (!uts)
16111 +               return NULL;
16112 +
16113 +       switch (id) {
16114 +       case VHIN_SYSNAME:
16115 +               return uts->name.sysname;
16116 +       case VHIN_NODENAME:
16117 +               return uts->name.nodename;
16118 +       case VHIN_RELEASE:
16119 +               return uts->name.release;
16120 +       case VHIN_VERSION:
16121 +               return uts->name.version;
16122 +       case VHIN_MACHINE:
16123 +               return uts->name.machine;
16124 +       case VHIN_DOMAINNAME:
16125 +               return uts->name.domainname;
16126 +       default:
16127 +               return NULL;
16128 +       }
16129 +       return NULL;
16130 +}
16131 +
16132 +int vc_set_vhi_name(struct vx_info *vxi, void __user *data)
16133 +{
16134 +       struct vcmd_vhi_name_v0 vc_data;
16135 +       char *name;
16136 +
16137 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16138 +               return -EFAULT;
16139 +
16140 +       name = vx_vhi_name(vxi, vc_data.field);
16141 +       if (!name)
16142 +               return -EINVAL;
16143 +
16144 +       memcpy(name, vc_data.name, 65);
16145 +       return 0;
16146 +}
16147 +
16148 +int vc_get_vhi_name(struct vx_info *vxi, void __user *data)
16149 +{
16150 +       struct vcmd_vhi_name_v0 vc_data;
16151 +       char *name;
16152 +
16153 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16154 +               return -EFAULT;
16155 +
16156 +       name = vx_vhi_name(vxi, vc_data.field);
16157 +       if (!name)
16158 +               return -EINVAL;
16159 +
16160 +       memcpy(vc_data.name, name, 65);
16161 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
16162 +               return -EFAULT;
16163 +       return 0;
16164 +}
16165 +
16166 +
16167 +int vc_virt_stat(struct vx_info *vxi, void __user *data)
16168 +{
16169 +       struct vcmd_virt_stat_v0 vc_data;
16170 +       struct _vx_cvirt *cvirt = &vxi->cvirt;
16171 +       struct timespec uptime;
16172 +
16173 +       do_posix_clock_monotonic_gettime(&uptime);
16174 +       set_normalized_timespec(&uptime,
16175 +               uptime.tv_sec - cvirt->bias_uptime.tv_sec,
16176 +               uptime.tv_nsec - cvirt->bias_uptime.tv_nsec);
16177 +
16178 +       vc_data.offset = timespec_to_ns(&cvirt->bias_ts);
16179 +       vc_data.uptime = timespec_to_ns(&uptime);
16180 +       vc_data.nr_threads = atomic_read(&cvirt->nr_threads);
16181 +       vc_data.nr_running = atomic_read(&cvirt->nr_running);
16182 +       vc_data.nr_uninterruptible = atomic_read(&cvirt->nr_uninterruptible);
16183 +       vc_data.nr_onhold = atomic_read(&cvirt->nr_onhold);
16184 +       vc_data.nr_forks = atomic_read(&cvirt->total_forks);
16185 +       vc_data.load[0] = cvirt->load[0];
16186 +       vc_data.load[1] = cvirt->load[1];
16187 +       vc_data.load[2] = cvirt->load[2];
16188 +
16189 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
16190 +               return -EFAULT;
16191 +       return 0;
16192 +}
16193 +
16194 +
16195 +#ifdef CONFIG_VSERVER_VTIME
16196 +
16197 +/* virtualized time base */
16198 +
16199 +void vx_adjust_timespec(struct timespec *ts)
16200 +{
16201 +       struct vx_info *vxi;
16202 +
16203 +       if (!vx_flags(VXF_VIRT_TIME, 0))
16204 +               return;
16205 +
16206 +       vxi = current_vx_info();
16207 +       ts->tv_sec += vxi->cvirt.bias_ts.tv_sec;
16208 +       ts->tv_nsec += vxi->cvirt.bias_ts.tv_nsec;
16209 +
16210 +       if (ts->tv_nsec >= NSEC_PER_SEC) {
16211 +               ts->tv_sec++;
16212 +               ts->tv_nsec -= NSEC_PER_SEC;
16213 +       } else if (ts->tv_nsec < 0) {
16214 +               ts->tv_sec--;
16215 +               ts->tv_nsec += NSEC_PER_SEC;
16216 +       }
16217 +}
16218 +
16219 +int vx_settimeofday(const struct timespec *ts)
16220 +{
16221 +       struct timespec ats, delta;
16222 +       struct vx_info *vxi;
16223 +
16224 +       if (!vx_flags(VXF_VIRT_TIME, 0))
16225 +               return do_settimeofday(ts);
16226 +
16227 +       getnstimeofday(&ats);
16228 +       delta = timespec_sub(*ts, ats);
16229 +
16230 +       vxi = current_vx_info();
16231 +       vxi->cvirt.bias_ts = timespec_add(vxi->cvirt.bias_ts, delta);
16232 +       return 0;
16233 +}
16234 +
16235 +#endif
16236 +
16237 diff -NurpP --minimal linux-3.18.5/kernel/vserver/cvirt_init.h linux-3.18.5-vs2.3.7.3/kernel/vserver/cvirt_init.h
16238 --- linux-3.18.5/kernel/vserver/cvirt_init.h    1970-01-01 00:00:00.000000000 +0000
16239 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/cvirt_init.h  2015-01-19 10:58:31.000000000 +0000
16240 @@ -0,0 +1,70 @@
16241 +
16242 +
16243 +extern uint64_t vx_idle_jiffies(void);
16244 +
16245 +static inline void vx_info_init_cvirt(struct _vx_cvirt *cvirt)
16246 +{
16247 +       uint64_t idle_jiffies = vx_idle_jiffies();
16248 +       uint64_t nsuptime;
16249 +
16250 +       do_posix_clock_monotonic_gettime(&cvirt->bias_uptime);
16251 +       nsuptime = (unsigned long long)cvirt->bias_uptime.tv_sec
16252 +               * NSEC_PER_SEC + cvirt->bias_uptime.tv_nsec;
16253 +       cvirt->bias_clock = nsec_to_clock_t(nsuptime);
16254 +       cvirt->bias_ts.tv_sec = 0;
16255 +       cvirt->bias_ts.tv_nsec = 0;
16256 +
16257 +       jiffies_to_timespec(idle_jiffies, &cvirt->bias_idle);
16258 +       atomic_set(&cvirt->nr_threads, 0);
16259 +       atomic_set(&cvirt->nr_running, 0);
16260 +       atomic_set(&cvirt->nr_uninterruptible, 0);
16261 +       atomic_set(&cvirt->nr_onhold, 0);
16262 +
16263 +       spin_lock_init(&cvirt->load_lock);
16264 +       cvirt->load_last = jiffies;
16265 +       atomic_set(&cvirt->load_updates, 0);
16266 +       cvirt->load[0] = 0;
16267 +       cvirt->load[1] = 0;
16268 +       cvirt->load[2] = 0;
16269 +       atomic_set(&cvirt->total_forks, 0);
16270 +
16271 +       spin_lock_init(&cvirt->syslog.logbuf_lock);
16272 +       init_waitqueue_head(&cvirt->syslog.log_wait);
16273 +       cvirt->syslog.log_start = 0;
16274 +       cvirt->syslog.log_end = 0;
16275 +       cvirt->syslog.con_start = 0;
16276 +       cvirt->syslog.logged_chars = 0;
16277 +}
16278 +
16279 +static inline
16280 +void vx_info_init_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
16281 +{
16282 +       // cvirt_pc->cpustat = { 0 };
16283 +}
16284 +
16285 +static inline void vx_info_exit_cvirt(struct _vx_cvirt *cvirt)
16286 +{
16287 +#ifdef CONFIG_VSERVER_WARN
16288 +       int value;
16289 +#endif
16290 +       vxwprintk_xid((value = atomic_read(&cvirt->nr_threads)),
16291 +               "!!! cvirt: %p[nr_threads] = %d on exit.",
16292 +               cvirt, value);
16293 +       vxwprintk_xid((value = atomic_read(&cvirt->nr_running)),
16294 +               "!!! cvirt: %p[nr_running] = %d on exit.",
16295 +               cvirt, value);
16296 +       vxwprintk_xid((value = atomic_read(&cvirt->nr_uninterruptible)),
16297 +               "!!! cvirt: %p[nr_uninterruptible] = %d on exit.",
16298 +               cvirt, value);
16299 +       vxwprintk_xid((value = atomic_read(&cvirt->nr_onhold)),
16300 +               "!!! cvirt: %p[nr_onhold] = %d on exit.",
16301 +               cvirt, value);
16302 +       return;
16303 +}
16304 +
16305 +static inline
16306 +void vx_info_exit_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
16307 +{
16308 +       return;
16309 +}
16310 +
16311 diff -NurpP --minimal linux-3.18.5/kernel/vserver/cvirt_proc.h linux-3.18.5-vs2.3.7.3/kernel/vserver/cvirt_proc.h
16312 --- linux-3.18.5/kernel/vserver/cvirt_proc.h    1970-01-01 00:00:00.000000000 +0000
16313 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/cvirt_proc.h  2015-01-19 10:58:31.000000000 +0000
16314 @@ -0,0 +1,123 @@
16315 +#ifndef _VX_CVIRT_PROC_H
16316 +#define _VX_CVIRT_PROC_H
16317 +
16318 +#include <linux/nsproxy.h>
16319 +#include <linux/mnt_namespace.h>
16320 +#include <linux/ipc_namespace.h>
16321 +#include <linux/utsname.h>
16322 +#include <linux/ipc.h>
16323 +
16324 +extern int vx_info_mnt_namespace(struct mnt_namespace *, char *);
16325 +
16326 +static inline
16327 +int vx_info_proc_nsproxy(struct nsproxy *nsproxy, char *buffer)
16328 +{
16329 +       struct mnt_namespace *ns;
16330 +       struct uts_namespace *uts;
16331 +       struct ipc_namespace *ipc;
16332 +       int length = 0;
16333 +
16334 +       if (!nsproxy)
16335 +               goto out;
16336 +
16337 +       length += sprintf(buffer + length,
16338 +               "NSProxy:\t%p [%p,%p,%p]\n",
16339 +               nsproxy, nsproxy->mnt_ns,
16340 +               nsproxy->uts_ns, nsproxy->ipc_ns);
16341 +
16342 +       ns = nsproxy->mnt_ns;
16343 +       if (!ns)
16344 +               goto skip_ns;
16345 +
16346 +       length += vx_info_mnt_namespace(ns, buffer + length);
16347 +
16348 +skip_ns:
16349 +
16350 +       uts = nsproxy->uts_ns;
16351 +       if (!uts)
16352 +               goto skip_uts;
16353 +
16354 +       length += sprintf(buffer + length,
16355 +               "SysName:\t%.*s\n"
16356 +               "NodeName:\t%.*s\n"
16357 +               "Release:\t%.*s\n"
16358 +               "Version:\t%.*s\n"
16359 +               "Machine:\t%.*s\n"
16360 +               "DomainName:\t%.*s\n",
16361 +               __NEW_UTS_LEN, uts->name.sysname,
16362 +               __NEW_UTS_LEN, uts->name.nodename,
16363 +               __NEW_UTS_LEN, uts->name.release,
16364 +               __NEW_UTS_LEN, uts->name.version,
16365 +               __NEW_UTS_LEN, uts->name.machine,
16366 +               __NEW_UTS_LEN, uts->name.domainname);
16367 +skip_uts:
16368 +
16369 +       ipc = nsproxy->ipc_ns;
16370 +       if (!ipc)
16371 +               goto skip_ipc;
16372 +
16373 +       length += sprintf(buffer + length,
16374 +               "SEMS:\t\t%d %d %d %d  %d\n"
16375 +               "MSG:\t\t%d %d %d\n"
16376 +               "SHM:\t\t%lu %lu  %d %ld\n",
16377 +               ipc->sem_ctls[0], ipc->sem_ctls[1],
16378 +               ipc->sem_ctls[2], ipc->sem_ctls[3],
16379 +               ipc->used_sems,
16380 +               ipc->msg_ctlmax, ipc->msg_ctlmnb, ipc->msg_ctlmni,
16381 +               (unsigned long)ipc->shm_ctlmax,
16382 +               (unsigned long)ipc->shm_ctlall,
16383 +               ipc->shm_ctlmni, ipc->shm_tot);
16384 +skip_ipc:
16385 +out:
16386 +       return length;
16387 +}
16388 +
16389 +
16390 +#include <linux/sched.h>
16391 +
16392 +#define LOAD_INT(x) ((x) >> FSHIFT)
16393 +#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1 - 1)) * 100)
16394 +
16395 +static inline
16396 +int vx_info_proc_cvirt(struct _vx_cvirt *cvirt, char *buffer)
16397 +{
16398 +       int length = 0;
16399 +       int a, b, c;
16400 +
16401 +       length += sprintf(buffer + length,
16402 +               "BiasUptime:\t%lu.%02lu\n",
16403 +               (unsigned long)cvirt->bias_uptime.tv_sec,
16404 +               (cvirt->bias_uptime.tv_nsec / (NSEC_PER_SEC / 100)));
16405 +
16406 +       a = cvirt->load[0] + (FIXED_1 / 200);
16407 +       b = cvirt->load[1] + (FIXED_1 / 200);
16408 +       c = cvirt->load[2] + (FIXED_1 / 200);
16409 +       length += sprintf(buffer + length,
16410 +               "nr_threads:\t%d\n"
16411 +               "nr_running:\t%d\n"
16412 +               "nr_unintr:\t%d\n"
16413 +               "nr_onhold:\t%d\n"
16414 +               "load_updates:\t%d\n"
16415 +               "loadavg:\t%d.%02d %d.%02d %d.%02d\n"
16416 +               "total_forks:\t%d\n",
16417 +               atomic_read(&cvirt->nr_threads),
16418 +               atomic_read(&cvirt->nr_running),
16419 +               atomic_read(&cvirt->nr_uninterruptible),
16420 +               atomic_read(&cvirt->nr_onhold),
16421 +               atomic_read(&cvirt->load_updates),
16422 +               LOAD_INT(a), LOAD_FRAC(a),
16423 +               LOAD_INT(b), LOAD_FRAC(b),
16424 +               LOAD_INT(c), LOAD_FRAC(c),
16425 +               atomic_read(&cvirt->total_forks));
16426 +       return length;
16427 +}
16428 +
16429 +static inline
16430 +int vx_info_proc_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc,
16431 +       char *buffer, int cpu)
16432 +{
16433 +       int length = 0;
16434 +       return length;
16435 +}
16436 +
16437 +#endif /* _VX_CVIRT_PROC_H */
16438 diff -NurpP --minimal linux-3.18.5/kernel/vserver/debug.c linux-3.18.5-vs2.3.7.3/kernel/vserver/debug.c
16439 --- linux-3.18.5/kernel/vserver/debug.c 1970-01-01 00:00:00.000000000 +0000
16440 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/debug.c       2015-01-19 10:58:31.000000000 +0000
16441 @@ -0,0 +1,32 @@
16442 +/*
16443 + *  kernel/vserver/debug.c
16444 + *
16445 + *  Copyright (C) 2005-2007 Herbert Pötzl
16446 + *
16447 + *  V0.01  vx_info dump support
16448 + *
16449 + */
16450 +
16451 +#include <linux/module.h>
16452 +
16453 +#include <linux/vserver/context.h>
16454 +
16455 +
16456 +void   dump_vx_info(struct vx_info *vxi, int level)
16457 +{
16458 +       printk("vx_info %p[#%d, %d.%d, %4x]\n", vxi, vxi->vx_id,
16459 +               atomic_read(&vxi->vx_usecnt),
16460 +               atomic_read(&vxi->vx_tasks),
16461 +               vxi->vx_state);
16462 +       if (level > 0) {
16463 +               __dump_vx_limit(&vxi->limit);
16464 +               __dump_vx_sched(&vxi->sched);
16465 +               __dump_vx_cvirt(&vxi->cvirt);
16466 +               __dump_vx_cacct(&vxi->cacct);
16467 +       }
16468 +       printk("---\n");
16469 +}
16470 +
16471 +
16472 +EXPORT_SYMBOL_GPL(dump_vx_info);
16473 +
16474 diff -NurpP --minimal linux-3.18.5/kernel/vserver/device.c linux-3.18.5-vs2.3.7.3/kernel/vserver/device.c
16475 --- linux-3.18.5/kernel/vserver/device.c        1970-01-01 00:00:00.000000000 +0000
16476 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/device.c      2015-01-19 10:58:31.000000000 +0000
16477 @@ -0,0 +1,443 @@
16478 +/*
16479 + *  linux/kernel/vserver/device.c
16480 + *
16481 + *  Linux-VServer: Device Support
16482 + *
16483 + *  Copyright (C) 2006  Herbert Pötzl
16484 + *  Copyright (C) 2007  Daniel Hokka Zakrisson
16485 + *
16486 + *  V0.01  device mapping basics
16487 + *  V0.02  added defaults
16488 + *
16489 + */
16490 +
16491 +#include <linux/slab.h>
16492 +#include <linux/rcupdate.h>
16493 +#include <linux/fs.h>
16494 +#include <linux/namei.h>
16495 +#include <linux/hash.h>
16496 +
16497 +#include <asm/errno.h>
16498 +#include <asm/uaccess.h>
16499 +#include <linux/vserver/base.h>
16500 +#include <linux/vserver/debug.h>
16501 +#include <linux/vserver/context.h>
16502 +#include <linux/vserver/device.h>
16503 +#include <linux/vserver/device_cmd.h>
16504 +
16505 +
16506 +#define DMAP_HASH_BITS 4
16507 +
16508 +
16509 +struct vs_mapping {
16510 +       union {
16511 +               struct hlist_node hlist;
16512 +               struct list_head list;
16513 +       } u;
16514 +#define dm_hlist       u.hlist
16515 +#define dm_list                u.list
16516 +       vxid_t xid;
16517 +       dev_t device;
16518 +       struct vx_dmap_target target;
16519 +};
16520 +
16521 +
16522 +static struct hlist_head dmap_main_hash[1 << DMAP_HASH_BITS];
16523 +
16524 +static DEFINE_SPINLOCK(dmap_main_hash_lock);
16525 +
16526 +static struct vx_dmap_target dmap_defaults[2] = {
16527 +       { .flags = DATTR_OPEN },
16528 +       { .flags = DATTR_OPEN },
16529 +};
16530 +
16531 +
16532 +struct kmem_cache *dmap_cachep __read_mostly;
16533 +
16534 +int __init dmap_cache_init(void)
16535 +{
16536 +       dmap_cachep = kmem_cache_create("dmap_cache",
16537 +               sizeof(struct vs_mapping), 0,
16538 +               SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
16539 +       return 0;
16540 +}
16541 +
16542 +__initcall(dmap_cache_init);
16543 +
16544 +
16545 +static inline unsigned int __hashval(dev_t dev, int bits)
16546 +{
16547 +       return hash_long((unsigned long)dev, bits);
16548 +}
16549 +
16550 +
16551 +/*     __hash_mapping()
16552 + *     add the mapping to the hash table
16553 + */
16554 +static inline void __hash_mapping(struct vx_info *vxi, struct vs_mapping *vdm)
16555 +{
16556 +       spinlock_t *hash_lock = &dmap_main_hash_lock;
16557 +       struct hlist_head *head, *hash = dmap_main_hash;
16558 +       int device = vdm->device;
16559 +
16560 +       spin_lock(hash_lock);
16561 +       vxdprintk(VXD_CBIT(misc, 8), "__hash_mapping: %p[#%d] %08x:%08x",
16562 +               vxi, vxi ? vxi->vx_id : 0, device, vdm->target.target);
16563 +
16564 +       head = &hash[__hashval(device, DMAP_HASH_BITS)];
16565 +       hlist_add_head(&vdm->dm_hlist, head);
16566 +       spin_unlock(hash_lock);
16567 +}
16568 +
16569 +
16570 +static inline int __mode_to_default(umode_t mode)
16571 +{
16572 +       switch (mode) {
16573 +       case S_IFBLK:
16574 +               return 0;
16575 +       case S_IFCHR:
16576 +               return 1;
16577 +       default:
16578 +               BUG();
16579 +       }
16580 +}
16581 +
16582 +
16583 +/*     __set_default()
16584 + *     set a default
16585 + */
16586 +static inline void __set_default(struct vx_info *vxi, umode_t mode,
16587 +       struct vx_dmap_target *vdmt)
16588 +{
16589 +       spinlock_t *hash_lock = &dmap_main_hash_lock;
16590 +       spin_lock(hash_lock);
16591 +
16592 +       if (vxi)
16593 +               vxi->dmap.targets[__mode_to_default(mode)] = *vdmt;
16594 +       else
16595 +               dmap_defaults[__mode_to_default(mode)] = *vdmt;
16596 +
16597 +
16598 +       spin_unlock(hash_lock);
16599 +
16600 +       vxdprintk(VXD_CBIT(misc, 8), "__set_default: %p[#%u] %08x %04x",
16601 +                 vxi, vxi ? vxi->vx_id : 0, vdmt->target, vdmt->flags);
16602 +}
16603 +
16604 +
16605 +/*     __remove_default()
16606 + *     remove a default
16607 + */
16608 +static inline int __remove_default(struct vx_info *vxi, umode_t mode)
16609 +{
16610 +       spinlock_t *hash_lock = &dmap_main_hash_lock;
16611 +       spin_lock(hash_lock);
16612 +
16613 +       if (vxi)
16614 +               vxi->dmap.targets[__mode_to_default(mode)].flags = 0;
16615 +       else    /* remove == reset */
16616 +               dmap_defaults[__mode_to_default(mode)].flags = DATTR_OPEN | mode;
16617 +
16618 +       spin_unlock(hash_lock);
16619 +       return 0;
16620 +}
16621 +
16622 +
16623 +/*     __find_mapping()
16624 + *     find a mapping in the hash table
16625 + *
16626 + *     caller must hold hash_lock
16627 + */
16628 +static inline int __find_mapping(vxid_t xid, dev_t device, umode_t mode,
16629 +       struct vs_mapping **local, struct vs_mapping **global)
16630 +{
16631 +       struct hlist_head *hash = dmap_main_hash;
16632 +       struct hlist_head *head = &hash[__hashval(device, DMAP_HASH_BITS)];
16633 +       struct hlist_node *pos;
16634 +       struct vs_mapping *vdm;
16635 +
16636 +       *local = NULL;
16637 +       if (global)
16638 +               *global = NULL;
16639 +
16640 +       hlist_for_each(pos, head) {
16641 +               vdm = hlist_entry(pos, struct vs_mapping, dm_hlist);
16642 +
16643 +               if ((vdm->device == device) &&
16644 +                       !((vdm->target.flags ^ mode) & S_IFMT)) {
16645 +                       if (vdm->xid == xid) {
16646 +                               *local = vdm;
16647 +                               return 1;
16648 +                       } else if (global && vdm->xid == 0)
16649 +                               *global = vdm;
16650 +               }
16651 +       }
16652 +
16653 +       if (global && *global)
16654 +               return 0;
16655 +       else
16656 +               return -ENOENT;
16657 +}
16658 +
16659 +
16660 +/*     __lookup_mapping()
16661 + *     find a mapping and store the result in target and flags
16662 + */
16663 +static inline int __lookup_mapping(struct vx_info *vxi,
16664 +       dev_t device, dev_t *target, int *flags, umode_t mode)
16665 +{
16666 +       spinlock_t *hash_lock = &dmap_main_hash_lock;
16667 +       struct vs_mapping *vdm, *global;
16668 +       struct vx_dmap_target *vdmt;
16669 +       int ret = 0;
16670 +       vxid_t xid = vxi->vx_id;
16671 +       int index;
16672 +
16673 +       spin_lock(hash_lock);
16674 +       if (__find_mapping(xid, device, mode, &vdm, &global) > 0) {
16675 +               ret = 1;
16676 +               vdmt = &vdm->target;
16677 +               goto found;
16678 +       }
16679 +
16680 +       index = __mode_to_default(mode);
16681 +       if (vxi && vxi->dmap.targets[index].flags) {
16682 +               ret = 2;
16683 +               vdmt = &vxi->dmap.targets[index];
16684 +       } else if (global) {
16685 +               ret = 3;
16686 +               vdmt = &global->target;
16687 +               goto found;
16688 +       } else {
16689 +               ret = 4;
16690 +               vdmt = &dmap_defaults[index];
16691 +       }
16692 +
16693 +found:
16694 +       if (target && (vdmt->flags & DATTR_REMAP))
16695 +               *target = vdmt->target;
16696 +       else if (target)
16697 +               *target = device;
16698 +       if (flags)
16699 +               *flags = vdmt->flags;
16700 +
16701 +       spin_unlock(hash_lock);
16702 +
16703 +       return ret;
16704 +}
16705 +
16706 +
16707 +/*     __remove_mapping()
16708 + *     remove a mapping from the hash table
16709 + */
16710 +static inline int __remove_mapping(struct vx_info *vxi, dev_t device,
16711 +       umode_t mode)
16712 +{
16713 +       spinlock_t *hash_lock = &dmap_main_hash_lock;
16714 +       struct vs_mapping *vdm = NULL;
16715 +       int ret = 0;
16716 +
16717 +       spin_lock(hash_lock);
16718 +
16719 +       ret = __find_mapping((vxi ? vxi->vx_id : 0), device, mode, &vdm,
16720 +               NULL);
16721 +       vxdprintk(VXD_CBIT(misc, 8), "__remove_mapping: %p[#%d] %08x %04x",
16722 +               vxi, vxi ? vxi->vx_id : 0, device, mode);
16723 +       if (ret < 0)
16724 +               goto out;
16725 +       hlist_del(&vdm->dm_hlist);
16726 +
16727 +out:
16728 +       spin_unlock(hash_lock);
16729 +       if (vdm)
16730 +               kmem_cache_free(dmap_cachep, vdm);
16731 +       return ret;
16732 +}
16733 +
16734 +
16735 +
16736 +int vs_map_device(struct vx_info *vxi,
16737 +       dev_t device, dev_t *target, umode_t mode)
16738 +{
16739 +       int ret, flags = DATTR_MASK;
16740 +
16741 +       if (!vxi) {
16742 +               if (target)
16743 +                       *target = device;
16744 +               goto out;
16745 +       }
16746 +       ret = __lookup_mapping(vxi, device, target, &flags, mode);
16747 +       vxdprintk(VXD_CBIT(misc, 8), "vs_map_device: %08x target: %08x flags: %04x mode: %04x mapped=%d",
16748 +               device, target ? *target : 0, flags, mode, ret);
16749 +out:
16750 +       return (flags & DATTR_MASK);
16751 +}
16752 +
16753 +
16754 +
16755 +static int do_set_mapping(struct vx_info *vxi,
16756 +       dev_t device, dev_t target, int flags, umode_t mode)
16757 +{
16758 +       if (device) {
16759 +               struct vs_mapping *new;
16760 +
16761 +               new = kmem_cache_alloc(dmap_cachep, GFP_KERNEL);
16762 +               if (!new)
16763 +                       return -ENOMEM;
16764 +
16765 +               INIT_HLIST_NODE(&new->dm_hlist);
16766 +               new->device = device;
16767 +               new->target.target = target;
16768 +               new->target.flags = flags | mode;
16769 +               new->xid = (vxi ? vxi->vx_id : 0);
16770 +
16771 +               vxdprintk(VXD_CBIT(misc, 8), "do_set_mapping: %08x target: %08x flags: %04x", device, target, flags);
16772 +               __hash_mapping(vxi, new);
16773 +       } else {
16774 +               struct vx_dmap_target new = {
16775 +                       .target = target,
16776 +                       .flags = flags | mode,
16777 +               };
16778 +               __set_default(vxi, mode, &new);
16779 +       }
16780 +       return 0;
16781 +}
16782 +
16783 +
16784 +static int do_unset_mapping(struct vx_info *vxi,
16785 +       dev_t device, dev_t target, int flags, umode_t mode)
16786 +{
16787 +       int ret = -EINVAL;
16788 +
16789 +       if (device) {
16790 +               ret = __remove_mapping(vxi, device, mode);
16791 +               if (ret < 0)
16792 +                       goto out;
16793 +       } else {
16794 +               ret = __remove_default(vxi, mode);
16795 +               if (ret < 0)
16796 +                       goto out;
16797 +       }
16798 +
16799 +out:
16800 +       return ret;
16801 +}
16802 +
16803 +
16804 +static inline int __user_device(const char __user *name, dev_t *dev,
16805 +       umode_t *mode)
16806 +{
16807 +       struct nameidata nd;
16808 +       int ret;
16809 +
16810 +       if (!name) {
16811 +               *dev = 0;
16812 +               return 0;
16813 +       }
16814 +       ret = user_lpath(name, &nd.path);
16815 +       if (ret)
16816 +               return ret;
16817 +       if (nd.path.dentry->d_inode) {
16818 +               *dev = nd.path.dentry->d_inode->i_rdev;
16819 +               *mode = nd.path.dentry->d_inode->i_mode;
16820 +       }
16821 +       path_put(&nd.path);
16822 +       return 0;
16823 +}
16824 +
16825 +static inline int __mapping_mode(dev_t device, dev_t target,
16826 +       umode_t device_mode, umode_t target_mode, umode_t *mode)
16827 +{
16828 +       if (device)
16829 +               *mode = device_mode & S_IFMT;
16830 +       else if (target)
16831 +               *mode = target_mode & S_IFMT;
16832 +       else
16833 +               return -EINVAL;
16834 +
16835 +       /* if both given, device and target mode have to match */
16836 +       if (device && target &&
16837 +               ((device_mode ^ target_mode) & S_IFMT))
16838 +               return -EINVAL;
16839 +       return 0;
16840 +}
16841 +
16842 +
16843 +static inline int do_mapping(struct vx_info *vxi, const char __user *device_path,
16844 +       const char __user *target_path, int flags, int set)
16845 +{
16846 +       dev_t device = ~0, target = ~0;
16847 +       umode_t device_mode = 0, target_mode = 0, mode;
16848 +       int ret;
16849 +
16850 +       ret = __user_device(device_path, &device, &device_mode);
16851 +       if (ret)
16852 +               return ret;
16853 +       ret = __user_device(target_path, &target, &target_mode);
16854 +       if (ret)
16855 +               return ret;
16856 +
16857 +       ret = __mapping_mode(device, target,
16858 +               device_mode, target_mode, &mode);
16859 +       if (ret)
16860 +               return ret;
16861 +
16862 +       if (set)
16863 +               return do_set_mapping(vxi, device, target,
16864 +                       flags, mode);
16865 +       else
16866 +               return do_unset_mapping(vxi, device, target,
16867 +                       flags, mode);
16868 +}
16869 +
16870 +
16871 +int vc_set_mapping(struct vx_info *vxi, void __user *data)
16872 +{
16873 +       struct vcmd_set_mapping_v0 vc_data;
16874 +
16875 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16876 +               return -EFAULT;
16877 +
16878 +       return do_mapping(vxi, vc_data.device, vc_data.target,
16879 +               vc_data.flags, 1);
16880 +}
16881 +
16882 +int vc_unset_mapping(struct vx_info *vxi, void __user *data)
16883 +{
16884 +       struct vcmd_set_mapping_v0 vc_data;
16885 +
16886 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16887 +               return -EFAULT;
16888 +
16889 +       return do_mapping(vxi, vc_data.device, vc_data.target,
16890 +               vc_data.flags, 0);
16891 +}
16892 +
16893 +
16894 +#ifdef CONFIG_COMPAT
16895 +
16896 +int vc_set_mapping_x32(struct vx_info *vxi, void __user *data)
16897 +{
16898 +       struct vcmd_set_mapping_v0_x32 vc_data;
16899 +
16900 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16901 +               return -EFAULT;
16902 +
16903 +       return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
16904 +               compat_ptr(vc_data.target_ptr), vc_data.flags, 1);
16905 +}
16906 +
16907 +int vc_unset_mapping_x32(struct vx_info *vxi, void __user *data)
16908 +{
16909 +       struct vcmd_set_mapping_v0_x32 vc_data;
16910 +
16911 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16912 +               return -EFAULT;
16913 +
16914 +       return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
16915 +               compat_ptr(vc_data.target_ptr), vc_data.flags, 0);
16916 +}
16917 +
16918 +#endif /* CONFIG_COMPAT */
16919 +
16920 +
16921 diff -NurpP --minimal linux-3.18.5/kernel/vserver/dlimit.c linux-3.18.5-vs2.3.7.3/kernel/vserver/dlimit.c
16922 --- linux-3.18.5/kernel/vserver/dlimit.c        1970-01-01 00:00:00.000000000 +0000
16923 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/dlimit.c      2015-01-19 10:58:31.000000000 +0000
16924 @@ -0,0 +1,528 @@
16925 +/*
16926 + *  linux/kernel/vserver/dlimit.c
16927 + *
16928 + *  Virtual Server: Context Disk Limits
16929 + *
16930 + *  Copyright (C) 2004-2009  Herbert Pötzl
16931 + *
16932 + *  V0.01  initial version
16933 + *  V0.02  compat32 splitup
16934 + *  V0.03  extended interface
16935 + *
16936 + */
16937 +
16938 +#include <linux/statfs.h>
16939 +#include <linux/sched.h>
16940 +#include <linux/namei.h>
16941 +#include <linux/vs_tag.h>
16942 +#include <linux/vs_dlimit.h>
16943 +#include <linux/vserver/dlimit_cmd.h>
16944 +#include <linux/slab.h>
16945 +// #include <linux/gfp.h>
16946 +
16947 +#include <asm/uaccess.h>
16948 +
16949 +/*     __alloc_dl_info()
16950 +
16951 +       * allocate an initialized dl_info struct
16952 +       * doesn't make it visible (hash)                        */
16953 +
16954 +static struct dl_info *__alloc_dl_info(struct super_block *sb, vtag_t tag)
16955 +{
16956 +       struct dl_info *new = NULL;
16957 +
16958 +       vxdprintk(VXD_CBIT(dlim, 5),
16959 +               "alloc_dl_info(%p,%d)*", sb, tag);
16960 +
16961 +       /* would this benefit from a slab cache? */
16962 +       new = kmalloc(sizeof(struct dl_info), GFP_KERNEL);
16963 +       if (!new)
16964 +               return 0;
16965 +
16966 +       memset(new, 0, sizeof(struct dl_info));
16967 +       new->dl_tag = tag;
16968 +       new->dl_sb = sb;
16969 +       // INIT_RCU_HEAD(&new->dl_rcu);
16970 +       INIT_HLIST_NODE(&new->dl_hlist);
16971 +       spin_lock_init(&new->dl_lock);
16972 +       atomic_set(&new->dl_refcnt, 0);
16973 +       atomic_set(&new->dl_usecnt, 0);
16974 +
16975 +       /* rest of init goes here */
16976 +
16977 +       vxdprintk(VXD_CBIT(dlim, 4),
16978 +               "alloc_dl_info(%p,%d) = %p", sb, tag, new);
16979 +       return new;
16980 +}
16981 +
16982 +/*     __dealloc_dl_info()
16983 +
16984 +       * final disposal of dl_info                             */
16985 +
16986 +static void __dealloc_dl_info(struct dl_info *dli)
16987 +{
16988 +       vxdprintk(VXD_CBIT(dlim, 4),
16989 +               "dealloc_dl_info(%p)", dli);
16990 +
16991 +       dli->dl_hlist.next = LIST_POISON1;
16992 +       dli->dl_tag = -1;
16993 +       dli->dl_sb = 0;
16994 +
16995 +       BUG_ON(atomic_read(&dli->dl_usecnt));
16996 +       BUG_ON(atomic_read(&dli->dl_refcnt));
16997 +
16998 +       kfree(dli);
16999 +}
17000 +
17001 +
17002 +/*     hash table for dl_info hash */
17003 +
17004 +#define DL_HASH_SIZE   13
17005 +
17006 +struct hlist_head dl_info_hash[DL_HASH_SIZE];
17007 +
17008 +static DEFINE_SPINLOCK(dl_info_hash_lock);
17009 +
17010 +
17011 +static inline unsigned int __hashval(struct super_block *sb, vtag_t tag)
17012 +{
17013 +       return ((tag ^ (unsigned long)sb) % DL_HASH_SIZE);
17014 +}
17015 +
17016 +
17017 +
17018 +/*     __hash_dl_info()
17019 +
17020 +       * add the dli to the global hash table
17021 +       * requires the hash_lock to be held                     */
17022 +
17023 +static inline void __hash_dl_info(struct dl_info *dli)
17024 +{
17025 +       struct hlist_head *head;
17026 +
17027 +       vxdprintk(VXD_CBIT(dlim, 6),
17028 +               "__hash_dl_info: %p[#%d]", dli, dli->dl_tag);
17029 +       get_dl_info(dli);
17030 +       head = &dl_info_hash[__hashval(dli->dl_sb, dli->dl_tag)];
17031 +       hlist_add_head_rcu(&dli->dl_hlist, head);
17032 +}
17033 +
17034 +/*     __unhash_dl_info()
17035 +
17036 +       * remove the dli from the global hash table
17037 +       * requires the hash_lock to be held                     */
17038 +
17039 +static inline void __unhash_dl_info(struct dl_info *dli)
17040 +{
17041 +       vxdprintk(VXD_CBIT(dlim, 6),
17042 +               "__unhash_dl_info: %p[#%d]", dli, dli->dl_tag);
17043 +       hlist_del_rcu(&dli->dl_hlist);
17044 +       put_dl_info(dli);
17045 +}
17046 +
17047 +
17048 +/*     __lookup_dl_info()
17049 +
17050 +       * requires the rcu_read_lock()
17051 +       * doesn't increment the dl_refcnt                       */
17052 +
17053 +static inline struct dl_info *__lookup_dl_info(struct super_block *sb, vtag_t tag)
17054 +{
17055 +       struct hlist_head *head = &dl_info_hash[__hashval(sb, tag)];
17056 +       struct dl_info *dli;
17057 +
17058 +       hlist_for_each_entry_rcu(dli, head, dl_hlist) {
17059 +               if (dli->dl_tag == tag && dli->dl_sb == sb)
17060 +                       return dli;
17061 +       }
17062 +       return NULL;
17063 +}
17064 +
17065 +
17066 +struct dl_info *locate_dl_info(struct super_block *sb, vtag_t tag)
17067 +{
17068 +       struct dl_info *dli;
17069 +
17070 +       rcu_read_lock();
17071 +       dli = get_dl_info(__lookup_dl_info(sb, tag));
17072 +       vxdprintk(VXD_CBIT(dlim, 7),
17073 +               "locate_dl_info(%p,#%d) = %p", sb, tag, dli);
17074 +       rcu_read_unlock();
17075 +       return dli;
17076 +}
17077 +
17078 +void rcu_free_dl_info(struct rcu_head *head)
17079 +{
17080 +       struct dl_info *dli = container_of(head, struct dl_info, dl_rcu);
17081 +       int usecnt, refcnt;
17082 +
17083 +       BUG_ON(!dli || !head);
17084 +
17085 +       usecnt = atomic_read(&dli->dl_usecnt);
17086 +       BUG_ON(usecnt < 0);
17087 +
17088 +       refcnt = atomic_read(&dli->dl_refcnt);
17089 +       BUG_ON(refcnt < 0);
17090 +
17091 +       vxdprintk(VXD_CBIT(dlim, 3),
17092 +               "rcu_free_dl_info(%p)", dli);
17093 +       if (!usecnt)
17094 +               __dealloc_dl_info(dli);
17095 +       else
17096 +               printk("!!! rcu didn't free\n");
17097 +}
17098 +
17099 +
17100 +
17101 +
17102 +static int do_addrem_dlimit(uint32_t id, const char __user *name,
17103 +       uint32_t flags, int add)
17104 +{
17105 +       struct path path;
17106 +       int ret;
17107 +
17108 +       ret = user_lpath(name, &path);
17109 +       if (!ret) {
17110 +               struct super_block *sb;
17111 +               struct dl_info *dli;
17112 +
17113 +               ret = -EINVAL;
17114 +               if (!path.dentry->d_inode)
17115 +                       goto out_release;
17116 +               if (!(sb = path.dentry->d_inode->i_sb))
17117 +                       goto out_release;
17118 +
17119 +               if (add) {
17120 +                       dli = __alloc_dl_info(sb, id);
17121 +                       spin_lock(&dl_info_hash_lock);
17122 +
17123 +                       ret = -EEXIST;
17124 +                       if (__lookup_dl_info(sb, id))
17125 +                               goto out_unlock;
17126 +                       __hash_dl_info(dli);
17127 +                       dli = NULL;
17128 +               } else {
17129 +                       spin_lock(&dl_info_hash_lock);
17130 +                       dli = __lookup_dl_info(sb, id);
17131 +
17132 +                       ret = -ESRCH;
17133 +                       if (!dli)
17134 +                               goto out_unlock;
17135 +                       __unhash_dl_info(dli);
17136 +               }
17137 +               ret = 0;
17138 +       out_unlock:
17139 +               spin_unlock(&dl_info_hash_lock);
17140 +               if (add && dli)
17141 +                       __dealloc_dl_info(dli);
17142 +       out_release:
17143 +               path_put(&path);
17144 +       }
17145 +       return ret;
17146 +}
17147 +
17148 +int vc_add_dlimit(uint32_t id, void __user *data)
17149 +{
17150 +       struct vcmd_ctx_dlimit_base_v0 vc_data;
17151 +
17152 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17153 +               return -EFAULT;
17154 +
17155 +       return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1);
17156 +}
17157 +
17158 +int vc_rem_dlimit(uint32_t id, void __user *data)
17159 +{
17160 +       struct vcmd_ctx_dlimit_base_v0 vc_data;
17161 +
17162 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17163 +               return -EFAULT;
17164 +
17165 +       return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0);
17166 +}
17167 +
17168 +#ifdef CONFIG_COMPAT
17169 +
17170 +int vc_add_dlimit_x32(uint32_t id, void __user *data)
17171 +{
17172 +       struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
17173 +
17174 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17175 +               return -EFAULT;
17176 +
17177 +       return do_addrem_dlimit(id,
17178 +               compat_ptr(vc_data.name_ptr), vc_data.flags, 1);
17179 +}
17180 +
17181 +int vc_rem_dlimit_x32(uint32_t id, void __user *data)
17182 +{
17183 +       struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
17184 +
17185 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17186 +               return -EFAULT;
17187 +
17188 +       return do_addrem_dlimit(id,
17189 +               compat_ptr(vc_data.name_ptr), vc_data.flags, 0);
17190 +}
17191 +
17192 +#endif /* CONFIG_COMPAT */
17193 +
17194 +
17195 +static inline
17196 +int do_set_dlimit(uint32_t id, const char __user *name,
17197 +       uint32_t space_used, uint32_t space_total,
17198 +       uint32_t inodes_used, uint32_t inodes_total,
17199 +       uint32_t reserved, uint32_t flags)
17200 +{
17201 +       struct path path;
17202 +       int ret;
17203 +
17204 +       ret = user_lpath(name, &path);
17205 +       if (!ret) {
17206 +               struct super_block *sb;
17207 +               struct dl_info *dli;
17208 +
17209 +               ret = -EINVAL;
17210 +               if (!path.dentry->d_inode)
17211 +                       goto out_release;
17212 +               if (!(sb = path.dentry->d_inode->i_sb))
17213 +                       goto out_release;
17214 +
17215 +               /* sanity checks */
17216 +               if ((reserved != CDLIM_KEEP &&
17217 +                       reserved > 100) ||
17218 +                       (inodes_used != CDLIM_KEEP &&
17219 +                       inodes_used > inodes_total) ||
17220 +                       (space_used != CDLIM_KEEP &&
17221 +                       space_used > space_total))
17222 +                       goto out_release;
17223 +
17224 +               ret = -ESRCH;
17225 +               dli = locate_dl_info(sb, id);
17226 +               if (!dli)
17227 +                       goto out_release;
17228 +
17229 +               spin_lock(&dli->dl_lock);
17230 +
17231 +               if (inodes_used != CDLIM_KEEP)
17232 +                       dli->dl_inodes_used = inodes_used;
17233 +               if (inodes_total != CDLIM_KEEP)
17234 +                       dli->dl_inodes_total = inodes_total;
17235 +               if (space_used != CDLIM_KEEP)
17236 +                       dli->dl_space_used = dlimit_space_32to64(
17237 +                               space_used, flags, DLIMS_USED);
17238 +
17239 +               if (space_total == CDLIM_INFINITY)
17240 +                       dli->dl_space_total = DLIM_INFINITY;
17241 +               else if (space_total != CDLIM_KEEP)
17242 +                       dli->dl_space_total = dlimit_space_32to64(
17243 +                               space_total, flags, DLIMS_TOTAL);
17244 +
17245 +               if (reserved != CDLIM_KEEP)
17246 +                       dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100;
17247 +
17248 +               spin_unlock(&dli->dl_lock);
17249 +
17250 +               put_dl_info(dli);
17251 +               ret = 0;
17252 +
17253 +       out_release:
17254 +               path_put(&path);
17255 +       }
17256 +       return ret;
17257 +}
17258 +
17259 +int vc_set_dlimit(uint32_t id, void __user *data)
17260 +{
17261 +       struct vcmd_ctx_dlimit_v0 vc_data;
17262 +
17263 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17264 +               return -EFAULT;
17265 +
17266 +       return do_set_dlimit(id, vc_data.name,
17267 +               vc_data.space_used, vc_data.space_total,
17268 +               vc_data.inodes_used, vc_data.inodes_total,
17269 +               vc_data.reserved, vc_data.flags);
17270 +}
17271 +
17272 +#ifdef CONFIG_COMPAT
17273 +
17274 +int vc_set_dlimit_x32(uint32_t id, void __user *data)
17275 +{
17276 +       struct vcmd_ctx_dlimit_v0_x32 vc_data;
17277 +
17278 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17279 +               return -EFAULT;
17280 +
17281 +       return do_set_dlimit(id, compat_ptr(vc_data.name_ptr),
17282 +               vc_data.space_used, vc_data.space_total,
17283 +               vc_data.inodes_used, vc_data.inodes_total,
17284 +               vc_data.reserved, vc_data.flags);
17285 +}
17286 +
17287 +#endif /* CONFIG_COMPAT */
17288 +
17289 +
17290 +static inline
17291 +int do_get_dlimit(uint32_t id, const char __user *name,
17292 +       uint32_t *space_used, uint32_t *space_total,
17293 +       uint32_t *inodes_used, uint32_t *inodes_total,
17294 +       uint32_t *reserved, uint32_t *flags)
17295 +{
17296 +       struct path path;
17297 +       int ret;
17298 +
17299 +       ret = user_lpath(name, &path);
17300 +       if (!ret) {
17301 +               struct super_block *sb;
17302 +               struct dl_info *dli;
17303 +
17304 +               ret = -EINVAL;
17305 +               if (!path.dentry->d_inode)
17306 +                       goto out_release;
17307 +               if (!(sb = path.dentry->d_inode->i_sb))
17308 +                       goto out_release;
17309 +
17310 +               ret = -ESRCH;
17311 +               dli = locate_dl_info(sb, id);
17312 +               if (!dli)
17313 +                       goto out_release;
17314 +
17315 +               spin_lock(&dli->dl_lock);
17316 +               *inodes_used = dli->dl_inodes_used;
17317 +               *inodes_total = dli->dl_inodes_total;
17318 +
17319 +               *space_used = dlimit_space_64to32(
17320 +                       dli->dl_space_used, flags, DLIMS_USED);
17321 +
17322 +               if (dli->dl_space_total == DLIM_INFINITY)
17323 +                       *space_total = CDLIM_INFINITY;
17324 +               else
17325 +                       *space_total = dlimit_space_64to32(
17326 +                               dli->dl_space_total, flags, DLIMS_TOTAL);
17327 +
17328 +               *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10);
17329 +               spin_unlock(&dli->dl_lock);
17330 +
17331 +               put_dl_info(dli);
17332 +               ret = -EFAULT;
17333 +
17334 +               ret = 0;
17335 +       out_release:
17336 +               path_put(&path);
17337 +       }
17338 +       return ret;
17339 +}
17340 +
17341 +
17342 +int vc_get_dlimit(uint32_t id, void __user *data)
17343 +{
17344 +       struct vcmd_ctx_dlimit_v0 vc_data;
17345 +       int ret;
17346 +
17347 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17348 +               return -EFAULT;
17349 +
17350 +       ret = do_get_dlimit(id, vc_data.name,
17351 +               &vc_data.space_used, &vc_data.space_total,
17352 +               &vc_data.inodes_used, &vc_data.inodes_total,
17353 +               &vc_data.reserved, &vc_data.flags);
17354 +       if (ret)
17355 +               return ret;
17356 +
17357 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17358 +               return -EFAULT;
17359 +       return 0;
17360 +}
17361 +
17362 +#ifdef CONFIG_COMPAT
17363 +
17364 +int vc_get_dlimit_x32(uint32_t id, void __user *data)
17365 +{
17366 +       struct vcmd_ctx_dlimit_v0_x32 vc_data;
17367 +       int ret;
17368 +
17369 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17370 +               return -EFAULT;
17371 +
17372 +       ret = do_get_dlimit(id, compat_ptr(vc_data.name_ptr),
17373 +               &vc_data.space_used, &vc_data.space_total,
17374 +               &vc_data.inodes_used, &vc_data.inodes_total,
17375 +               &vc_data.reserved, &vc_data.flags);
17376 +       if (ret)
17377 +               return ret;
17378 +
17379 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17380 +               return -EFAULT;
17381 +       return 0;
17382 +}
17383 +
17384 +#endif /* CONFIG_COMPAT */
17385 +
17386 +
17387 +void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf)
17388 +{
17389 +       struct dl_info *dli;
17390 +       __u64 blimit, bfree, bavail;
17391 +       __u32 ifree;
17392 +
17393 +       dli = locate_dl_info(sb, dx_current_tag());
17394 +       if (!dli)
17395 +               return;
17396 +
17397 +       spin_lock(&dli->dl_lock);
17398 +       if (dli->dl_inodes_total == (unsigned long)DLIM_INFINITY)
17399 +               goto no_ilim;
17400 +
17401 +       /* reduce max inodes available to limit */
17402 +       if (buf->f_files > dli->dl_inodes_total)
17403 +               buf->f_files = dli->dl_inodes_total;
17404 +
17405 +       ifree = dli->dl_inodes_total - dli->dl_inodes_used;
17406 +       /* reduce free inodes to min */
17407 +       if (ifree < buf->f_ffree)
17408 +               buf->f_ffree = ifree;
17409 +
17410 +no_ilim:
17411 +       if (dli->dl_space_total == DLIM_INFINITY)
17412 +               goto no_blim;
17413 +
17414 +       blimit = dli->dl_space_total >> sb->s_blocksize_bits;
17415 +
17416 +       if (dli->dl_space_total < dli->dl_space_used)
17417 +               bfree = 0;
17418 +       else
17419 +               bfree = (dli->dl_space_total - dli->dl_space_used)
17420 +                       >> sb->s_blocksize_bits;
17421 +
17422 +       bavail = ((dli->dl_space_total >> 10) * dli->dl_nrlmult);
17423 +       if (bavail < dli->dl_space_used)
17424 +               bavail = 0;
17425 +       else
17426 +               bavail = (bavail - dli->dl_space_used)
17427 +                       >> sb->s_blocksize_bits;
17428 +
17429 +       /* reduce max space available to limit */
17430 +       if (buf->f_blocks > blimit)
17431 +               buf->f_blocks = blimit;
17432 +
17433 +       /* reduce free space to min */
17434 +       if (bfree < buf->f_bfree)
17435 +               buf->f_bfree = bfree;
17436 +
17437 +       /* reduce avail space to min */
17438 +       if (bavail < buf->f_bavail)
17439 +               buf->f_bavail = bavail;
17440 +
17441 +no_blim:
17442 +       spin_unlock(&dli->dl_lock);
17443 +       put_dl_info(dli);
17444 +
17445 +       return;
17446 +}
17447 +
17448 +#include <linux/module.h>
17449 +
17450 +EXPORT_SYMBOL_GPL(locate_dl_info);
17451 +EXPORT_SYMBOL_GPL(rcu_free_dl_info);
17452 +
17453 diff -NurpP --minimal linux-3.18.5/kernel/vserver/helper.c linux-3.18.5-vs2.3.7.3/kernel/vserver/helper.c
17454 --- linux-3.18.5/kernel/vserver/helper.c        1970-01-01 00:00:00.000000000 +0000
17455 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/helper.c      2015-01-19 10:58:31.000000000 +0000
17456 @@ -0,0 +1,242 @@
17457 +/*
17458 + *  linux/kernel/vserver/helper.c
17459 + *
17460 + *  Virtual Context Support
17461 + *
17462 + *  Copyright (C) 2004-2007  Herbert Pötzl
17463 + *
17464 + *  V0.01  basic helper
17465 + *
17466 + */
17467 +
17468 +#include <linux/kmod.h>
17469 +#include <linux/reboot.h>
17470 +#include <linux/vs_context.h>
17471 +#include <linux/vs_network.h>
17472 +#include <linux/vserver/signal.h>
17473 +
17474 +
17475 +char vshelper_path[255] = "/sbin/vshelper";
17476 +
17477 +static int vshelper_init(struct subprocess_info *info, struct cred *new_cred)
17478 +{
17479 +       current->flags &= ~PF_NO_SETAFFINITY;
17480 +       return 0;
17481 +}
17482 +
17483 +static int vs_call_usermodehelper(char *path, char **argv, char **envp, int wait)
17484 +{
17485 +       struct subprocess_info *info;
17486 +       gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
17487 +
17488 +       info = call_usermodehelper_setup(path, argv, envp, gfp_mask,
17489 +                                        vshelper_init, NULL, NULL);
17490 +       if (info == NULL)
17491 +               return -ENOMEM;
17492 +
17493 +       return call_usermodehelper_exec(info, wait);
17494 +}
17495 +
17496 +static int do_vshelper(char *name, char *argv[], char *envp[], int sync)
17497 +{
17498 +       int ret;
17499 +
17500 +       if ((ret = vs_call_usermodehelper(name, argv, envp,
17501 +               sync ? UMH_WAIT_PROC : UMH_WAIT_EXEC))) {
17502 +               printk(KERN_WARNING "%s: (%s %s) returned %s with %d\n",
17503 +                       name, argv[1], argv[2],
17504 +                       sync ? "sync" : "async", ret);
17505 +       }
17506 +       vxdprintk(VXD_CBIT(switch, 4),
17507 +               "%s: (%s %s) returned %s with %d",
17508 +               name, argv[1], argv[2], sync ? "sync" : "async", ret);
17509 +       return ret;
17510 +}
17511 +
17512 +/*
17513 + *      vshelper path is set via /proc/sys
17514 + *      invoked by vserver sys_reboot(), with
17515 + *      the following arguments
17516 + *
17517 + *      argv [0] = vshelper_path;
17518 + *      argv [1] = action: "restart", "halt", "poweroff", ...
17519 + *      argv [2] = context identifier
17520 + *
17521 + *      envp [*] = type-specific parameters
17522 + */
17523 +
17524 +long vs_reboot_helper(struct vx_info *vxi, int cmd, void __user *arg)
17525 +{
17526 +       char id_buf[8], cmd_buf[16];
17527 +       char uid_buf[16], pid_buf[16];
17528 +       int ret;
17529 +
17530 +       char *argv[] = {vshelper_path, NULL, id_buf, 0};
17531 +       char *envp[] = {"HOME=/", "TERM=linux",
17532 +                       "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
17533 +                       uid_buf, pid_buf, cmd_buf, 0};
17534 +
17535 +       if (vx_info_state(vxi, VXS_HELPER))
17536 +               return -EAGAIN;
17537 +       vxi->vx_state |= VXS_HELPER;
17538 +
17539 +       snprintf(id_buf, sizeof(id_buf), "%d", vxi->vx_id);
17540 +
17541 +       snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17542 +       snprintf(uid_buf, sizeof(uid_buf), "VS_UID=%d",
17543 +               from_kuid(&init_user_ns, current_uid()));
17544 +       snprintf(pid_buf, sizeof(pid_buf), "VS_PID=%d", current->pid);
17545 +
17546 +       switch (cmd) {
17547 +       case LINUX_REBOOT_CMD_RESTART:
17548 +               argv[1] = "restart";
17549 +               break;
17550 +
17551 +       case LINUX_REBOOT_CMD_HALT:
17552 +               argv[1] = "halt";
17553 +               break;
17554 +
17555 +       case LINUX_REBOOT_CMD_POWER_OFF:
17556 +               argv[1] = "poweroff";
17557 +               break;
17558 +
17559 +       case LINUX_REBOOT_CMD_SW_SUSPEND:
17560 +               argv[1] = "swsusp";
17561 +               break;
17562 +
17563 +       case LINUX_REBOOT_CMD_OOM:
17564 +               argv[1] = "oom";
17565 +               break;
17566 +
17567 +       default:
17568 +               vxi->vx_state &= ~VXS_HELPER;
17569 +               return 0;
17570 +       }
17571 +
17572 +       ret = do_vshelper(vshelper_path, argv, envp, 0);
17573 +       vxi->vx_state &= ~VXS_HELPER;
17574 +       __wakeup_vx_info(vxi);
17575 +       return (ret) ? -EPERM : 0;
17576 +}
17577 +
17578 +
17579 +long vs_reboot(unsigned int cmd, void __user *arg)
17580 +{
17581 +       struct vx_info *vxi = current_vx_info();
17582 +       long ret = 0;
17583 +
17584 +       vxdprintk(VXD_CBIT(misc, 5),
17585 +               "vs_reboot(%p[#%d],%u)",
17586 +               vxi, vxi ? vxi->vx_id : 0, cmd);
17587 +
17588 +       ret = vs_reboot_helper(vxi, cmd, arg);
17589 +       if (ret)
17590 +               return ret;
17591 +
17592 +       vxi->reboot_cmd = cmd;
17593 +       if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
17594 +               switch (cmd) {
17595 +               case LINUX_REBOOT_CMD_RESTART:
17596 +               case LINUX_REBOOT_CMD_HALT:
17597 +               case LINUX_REBOOT_CMD_POWER_OFF:
17598 +                       vx_info_kill(vxi, 0, SIGKILL);
17599 +                       vx_info_kill(vxi, 1, SIGKILL);
17600 +               default:
17601 +                       break;
17602 +               }
17603 +       }
17604 +       return 0;
17605 +}
17606 +
17607 +long vs_oom_action(unsigned int cmd)
17608 +{
17609 +       struct vx_info *vxi = current_vx_info();
17610 +       long ret = 0;
17611 +
17612 +       vxdprintk(VXD_CBIT(misc, 5),
17613 +               "vs_oom_action(%p[#%d],%u)",
17614 +               vxi, vxi ? vxi->vx_id : 0, cmd);
17615 +
17616 +       ret = vs_reboot_helper(vxi, cmd, NULL);
17617 +       if (ret)
17618 +               return ret;
17619 +
17620 +       vxi->reboot_cmd = cmd;
17621 +       if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
17622 +               vx_info_kill(vxi, 0, SIGKILL);
17623 +               vx_info_kill(vxi, 1, SIGKILL);
17624 +       }
17625 +       return 0;
17626 +}
17627 +
17628 +/*
17629 + *      argv [0] = vshelper_path;
17630 + *      argv [1] = action: "startup", "shutdown"
17631 + *      argv [2] = context identifier
17632 + *
17633 + *      envp [*] = type-specific parameters
17634 + */
17635 +
17636 +long vs_state_change(struct vx_info *vxi, unsigned int cmd)
17637 +{
17638 +       char id_buf[8], cmd_buf[16];
17639 +       char *argv[] = {vshelper_path, NULL, id_buf, 0};
17640 +       char *envp[] = {"HOME=/", "TERM=linux",
17641 +                       "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
17642 +
17643 +       if (!vx_info_flags(vxi, VXF_SC_HELPER, 0))
17644 +               return 0;
17645 +
17646 +       snprintf(id_buf, sizeof(id_buf), "%d", vxi->vx_id);
17647 +       snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17648 +
17649 +       switch (cmd) {
17650 +       case VSC_STARTUP:
17651 +               argv[1] = "startup";
17652 +               break;
17653 +       case VSC_SHUTDOWN:
17654 +               argv[1] = "shutdown";
17655 +               break;
17656 +       default:
17657 +               return 0;
17658 +       }
17659 +
17660 +       return do_vshelper(vshelper_path, argv, envp, 1);
17661 +}
17662 +
17663 +
17664 +/*
17665 + *      argv [0] = vshelper_path;
17666 + *      argv [1] = action: "netup", "netdown"
17667 + *      argv [2] = context identifier
17668 + *
17669 + *      envp [*] = type-specific parameters
17670 + */
17671 +
17672 +long vs_net_change(struct nx_info *nxi, unsigned int cmd)
17673 +{
17674 +       char id_buf[8], cmd_buf[16];
17675 +       char *argv[] = {vshelper_path, NULL, id_buf, 0};
17676 +       char *envp[] = {"HOME=/", "TERM=linux",
17677 +                       "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
17678 +
17679 +       if (!nx_info_flags(nxi, NXF_SC_HELPER, 0))
17680 +               return 0;
17681 +
17682 +       snprintf(id_buf, sizeof(id_buf), "%d", nxi->nx_id);
17683 +       snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17684 +
17685 +       switch (cmd) {
17686 +       case VSC_NETUP:
17687 +               argv[1] = "netup";
17688 +               break;
17689 +       case VSC_NETDOWN:
17690 +               argv[1] = "netdown";
17691 +               break;
17692 +       default:
17693 +               return 0;
17694 +       }
17695 +
17696 +       return do_vshelper(vshelper_path, argv, envp, 1);
17697 +}
17698 +
17699 diff -NurpP --minimal linux-3.18.5/kernel/vserver/history.c linux-3.18.5-vs2.3.7.3/kernel/vserver/history.c
17700 --- linux-3.18.5/kernel/vserver/history.c       1970-01-01 00:00:00.000000000 +0000
17701 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/history.c     2015-01-19 10:58:31.000000000 +0000
17702 @@ -0,0 +1,258 @@
17703 +/*
17704 + *  kernel/vserver/history.c
17705 + *
17706 + *  Virtual Context History Backtrace
17707 + *
17708 + *  Copyright (C) 2004-2007  Herbert Pötzl
17709 + *
17710 + *  V0.01  basic structure
17711 + *  V0.02  hash/unhash and trace
17712 + *  V0.03  preemption fixes
17713 + *
17714 + */
17715 +
17716 +#include <linux/module.h>
17717 +#include <asm/uaccess.h>
17718 +
17719 +#include <linux/vserver/context.h>
17720 +#include <linux/vserver/debug.h>
17721 +#include <linux/vserver/debug_cmd.h>
17722 +#include <linux/vserver/history.h>
17723 +
17724 +
17725 +#ifdef CONFIG_VSERVER_HISTORY
17726 +#define VXH_SIZE       CONFIG_VSERVER_HISTORY_SIZE
17727 +#else
17728 +#define VXH_SIZE       64
17729 +#endif
17730 +
17731 +struct _vx_history {
17732 +       unsigned int counter;
17733 +
17734 +       struct _vx_hist_entry entry[VXH_SIZE + 1];
17735 +};
17736 +
17737 +
17738 +DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
17739 +
17740 +unsigned volatile int vxh_active = 1;
17741 +
17742 +static atomic_t sequence = ATOMIC_INIT(0);
17743 +
17744 +
17745 +/*     vxh_advance()
17746 +
17747 +       * requires disabled preemption                          */
17748 +
17749 +struct _vx_hist_entry *vxh_advance(void *loc)
17750 +{
17751 +       unsigned int cpu = smp_processor_id();
17752 +       struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
17753 +       struct _vx_hist_entry *entry;
17754 +       unsigned int index;
17755 +
17756 +       index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
17757 +       entry = &hist->entry[index];
17758 +
17759 +       entry->seq = atomic_inc_return(&sequence);
17760 +       entry->loc = loc;
17761 +       return entry;
17762 +}
17763 +
17764 +EXPORT_SYMBOL_GPL(vxh_advance);
17765 +
17766 +
17767 +#define VXH_LOC_FMTS   "(#%04x,*%d):%p"
17768 +
17769 +#define VXH_LOC_ARGS(e)        (e)->seq, cpu, (e)->loc
17770 +
17771 +
17772 +#define VXH_VXI_FMTS   "%p[#%d,%d.%d]"
17773 +
17774 +#define VXH_VXI_ARGS(e)        (e)->vxi.ptr,                           \
17775 +                       (e)->vxi.ptr ? (e)->vxi.xid : 0,        \
17776 +                       (e)->vxi.ptr ? (e)->vxi.usecnt : 0,     \
17777 +                       (e)->vxi.ptr ? (e)->vxi.tasks : 0
17778 +
17779 +void   vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
17780 +{
17781 +       switch (e->type) {
17782 +       case VXH_THROW_OOPS:
17783 +               printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
17784 +               break;
17785 +
17786 +       case VXH_GET_VX_INFO:
17787 +       case VXH_PUT_VX_INFO:
17788 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
17789 +                       VXH_LOC_ARGS(e),
17790 +                       (e->type == VXH_GET_VX_INFO) ? "get" : "put",
17791 +                       VXH_VXI_ARGS(e));
17792 +               break;
17793 +
17794 +       case VXH_INIT_VX_INFO:
17795 +       case VXH_SET_VX_INFO:
17796 +       case VXH_CLR_VX_INFO:
17797 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
17798 +                       VXH_LOC_ARGS(e),
17799 +                       (e->type == VXH_INIT_VX_INFO) ? "init" :
17800 +                       ((e->type == VXH_SET_VX_INFO) ? "set" : "clr"),
17801 +                       VXH_VXI_ARGS(e), e->sc.data);
17802 +               break;
17803 +
17804 +       case VXH_CLAIM_VX_INFO:
17805 +       case VXH_RELEASE_VX_INFO:
17806 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
17807 +                       VXH_LOC_ARGS(e),
17808 +                       (e->type == VXH_CLAIM_VX_INFO) ? "claim" : "release",
17809 +                       VXH_VXI_ARGS(e), e->sc.data);
17810 +               break;
17811 +
17812 +       case VXH_ALLOC_VX_INFO:
17813 +       case VXH_DEALLOC_VX_INFO:
17814 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
17815 +                       VXH_LOC_ARGS(e),
17816 +                       (e->type == VXH_ALLOC_VX_INFO) ? "alloc" : "dealloc",
17817 +                       VXH_VXI_ARGS(e));
17818 +               break;
17819 +
17820 +       case VXH_HASH_VX_INFO:
17821 +       case VXH_UNHASH_VX_INFO:
17822 +               printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
17823 +                       VXH_LOC_ARGS(e),
17824 +                       (e->type == VXH_HASH_VX_INFO) ? "hash" : "unhash",
17825 +                       VXH_VXI_ARGS(e));
17826 +               break;
17827 +
17828 +       case VXH_LOC_VX_INFO:
17829 +       case VXH_LOOKUP_VX_INFO:
17830 +       case VXH_CREATE_VX_INFO:
17831 +               printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
17832 +                       VXH_LOC_ARGS(e),
17833 +                       (e->type == VXH_CREATE_VX_INFO) ? "create" :
17834 +                       ((e->type == VXH_LOC_VX_INFO) ? "loc" : "lookup"),
17835 +                       e->ll.arg, VXH_VXI_ARGS(e));
17836 +               break;
17837 +       }
17838 +}
17839 +
17840 +static void __vxh_dump_history(void)
17841 +{
17842 +       unsigned int i, cpu;
17843 +
17844 +       printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
17845 +               atomic_read(&sequence), NR_CPUS);
17846 +
17847 +       for (i = 0; i < VXH_SIZE; i++) {
17848 +               for_each_online_cpu(cpu) {
17849 +                       struct _vx_history *hist =
17850 +                               &per_cpu(vx_history_buffer, cpu);
17851 +                       unsigned int index = (hist->counter - i) % VXH_SIZE;
17852 +                       struct _vx_hist_entry *entry = &hist->entry[index];
17853 +
17854 +                       vxh_dump_entry(entry, cpu);
17855 +               }
17856 +       }
17857 +}
17858 +
17859 +void   vxh_dump_history(void)
17860 +{
17861 +       vxh_active = 0;
17862 +#ifdef CONFIG_SMP
17863 +       local_irq_enable();
17864 +       smp_send_stop();
17865 +       local_irq_disable();
17866 +#endif
17867 +       __vxh_dump_history();
17868 +}
17869 +
17870 +
17871 +/* vserver syscall commands below here */
17872 +
17873 +
17874 +int vc_dump_history(uint32_t id)
17875 +{
17876 +       vxh_active = 0;
17877 +       __vxh_dump_history();
17878 +       vxh_active = 1;
17879 +
17880 +       return 0;
17881 +}
17882 +
17883 +
17884 +int do_read_history(struct __user _vx_hist_entry *data,
17885 +       int cpu, uint32_t *index, uint32_t *count)
17886 +{
17887 +       int pos, ret = 0;
17888 +       struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
17889 +       int end = hist->counter;
17890 +       int start = end - VXH_SIZE + 2;
17891 +       int idx = *index;
17892 +
17893 +       /* special case: get current pos */
17894 +       if (!*count) {
17895 +               *index = end;
17896 +               return 0;
17897 +       }
17898 +
17899 +       /* have we lost some data? */
17900 +       if (idx < start)
17901 +               idx = start;
17902 +
17903 +       for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
17904 +               struct _vx_hist_entry *entry =
17905 +                       &hist->entry[idx % VXH_SIZE];
17906 +
17907 +               /* send entry to userspace */
17908 +               ret = copy_to_user(&data[pos], entry, sizeof(*entry));
17909 +               if (ret)
17910 +                       break;
17911 +       }
17912 +       /* save new index and count */
17913 +       *index = idx;
17914 +       *count = pos;
17915 +       return ret ? ret : (*index < end);
17916 +}
17917 +
17918 +int vc_read_history(uint32_t id, void __user *data)
17919 +{
17920 +       struct vcmd_read_history_v0 vc_data;
17921 +       int ret;
17922 +
17923 +       if (id >= NR_CPUS)
17924 +               return -EINVAL;
17925 +
17926 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17927 +               return -EFAULT;
17928 +
17929 +       ret = do_read_history((struct __user _vx_hist_entry *)vc_data.data,
17930 +               id, &vc_data.index, &vc_data.count);
17931 +
17932 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17933 +               return -EFAULT;
17934 +       return ret;
17935 +}
17936 +
17937 +#ifdef CONFIG_COMPAT
17938 +
17939 +int vc_read_history_x32(uint32_t id, void __user *data)
17940 +{
17941 +       struct vcmd_read_history_v0_x32 vc_data;
17942 +       int ret;
17943 +
17944 +       if (id >= NR_CPUS)
17945 +               return -EINVAL;
17946 +
17947 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17948 +               return -EFAULT;
17949 +
17950 +       ret = do_read_history((struct __user _vx_hist_entry *)
17951 +               compat_ptr(vc_data.data_ptr),
17952 +               id, &vc_data.index, &vc_data.count);
17953 +
17954 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17955 +               return -EFAULT;
17956 +       return ret;
17957 +}
17958 +
17959 +#endif /* CONFIG_COMPAT */
17960 +
17961 diff -NurpP --minimal linux-3.18.5/kernel/vserver/inet.c linux-3.18.5-vs2.3.7.3/kernel/vserver/inet.c
17962 --- linux-3.18.5/kernel/vserver/inet.c  1970-01-01 00:00:00.000000000 +0000
17963 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/inet.c        2015-01-19 10:58:31.000000000 +0000
17964 @@ -0,0 +1,236 @@
17965 +
17966 +#include <linux/in.h>
17967 +#include <linux/inetdevice.h>
17968 +#include <linux/export.h>
17969 +#include <linux/vs_inet.h>
17970 +#include <linux/vs_inet6.h>
17971 +#include <linux/vserver/debug.h>
17972 +#include <net/route.h>
17973 +#include <net/addrconf.h>
17974 +
17975 +
17976 +int nx_v4_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
17977 +{
17978 +       int ret = 0;
17979 +
17980 +       if (!nxi1 || !nxi2 || nxi1 == nxi2)
17981 +               ret = 1;
17982 +       else {
17983 +               struct nx_addr_v4 *ptr;
17984 +               unsigned long irqflags;
17985 +
17986 +               spin_lock_irqsave(&nxi1->addr_lock, irqflags);
17987 +               for (ptr = &nxi1->v4; ptr; ptr = ptr->next) {
17988 +                       if (v4_nx_addr_in_nx_info(nxi2, ptr, -1)) {
17989 +                               ret = 1;
17990 +                               break;
17991 +                       }
17992 +               }
17993 +               spin_unlock_irqrestore(&nxi1->addr_lock, irqflags);
17994 +       }
17995 +
17996 +       vxdprintk(VXD_CBIT(net, 2),
17997 +               "nx_v4_addr_conflict(%p,%p): %d",
17998 +               nxi1, nxi2, ret);
17999 +
18000 +       return ret;
18001 +}
18002 +
18003 +
18004 +#ifdef CONFIG_IPV6
18005 +
18006 +int nx_v6_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
18007 +{
18008 +       int ret = 0;
18009 +
18010 +       if (!nxi1 || !nxi2 || nxi1 == nxi2)
18011 +               ret = 1;
18012 +       else {
18013 +               struct nx_addr_v6 *ptr;
18014 +               unsigned long irqflags;
18015 +
18016 +               spin_lock_irqsave(&nxi1->addr_lock, irqflags);
18017 +               for (ptr = &nxi1->v6; ptr; ptr = ptr->next) {
18018 +                       if (v6_nx_addr_in_nx_info(nxi2, ptr, -1)) {
18019 +                               ret = 1;
18020 +                               break;
18021 +                       }
18022 +               }
18023 +               spin_unlock_irqrestore(&nxi1->addr_lock, irqflags);
18024 +       }
18025 +
18026 +       vxdprintk(VXD_CBIT(net, 2),
18027 +               "nx_v6_addr_conflict(%p,%p): %d",
18028 +               nxi1, nxi2, ret);
18029 +
18030 +       return ret;
18031 +}
18032 +
18033 +#endif
18034 +
18035 +int v4_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
18036 +{
18037 +       struct in_device *in_dev;
18038 +       struct in_ifaddr **ifap;
18039 +       struct in_ifaddr *ifa;
18040 +       int ret = 0;
18041 +
18042 +       if (!dev)
18043 +               goto out;
18044 +       in_dev = in_dev_get(dev);
18045 +       if (!in_dev)
18046 +               goto out;
18047 +
18048 +       for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
18049 +               ifap = &ifa->ifa_next) {
18050 +               if (v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW)) {
18051 +                       ret = 1;
18052 +                       break;
18053 +               }
18054 +       }
18055 +       in_dev_put(in_dev);
18056 +out:
18057 +       return ret;
18058 +}
18059 +
18060 +
18061 +#ifdef CONFIG_IPV6
18062 +
18063 +int v6_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
18064 +{
18065 +       struct inet6_dev *in_dev;
18066 +       struct inet6_ifaddr *ifa;
18067 +       int ret = 0;
18068 +
18069 +       if (!dev)
18070 +               goto out;
18071 +       in_dev = in6_dev_get(dev);
18072 +       if (!in_dev)
18073 +               goto out;
18074 +
18075 +       // for (ifap = &in_dev->addr_list; (ifa = *ifap) != NULL;
18076 +       list_for_each_entry(ifa, &in_dev->addr_list, if_list) {
18077 +               if (v6_addr_in_nx_info(nxi, &ifa->addr, -1)) {
18078 +                       ret = 1;
18079 +                       break;
18080 +               }
18081 +       }
18082 +       in6_dev_put(in_dev);
18083 +out:
18084 +       return ret;
18085 +}
18086 +
18087 +#endif
18088 +
18089 +int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
18090 +{
18091 +       int ret = 1;
18092 +
18093 +       if (!nxi)
18094 +               goto out;
18095 +       if (nxi->v4.type && v4_dev_in_nx_info(dev, nxi))
18096 +               goto out;
18097 +#ifdef CONFIG_IPV6
18098 +       ret = 2;
18099 +       if (nxi->v6.type && v6_dev_in_nx_info(dev, nxi))
18100 +               goto out;
18101 +#endif
18102 +       ret = 0;
18103 +out:
18104 +       vxdprintk(VXD_CBIT(net, 3),
18105 +               "dev_in_nx_info(%p,%p[#%d]) = %d",
18106 +               dev, nxi, nxi ? nxi->nx_id : 0, ret);
18107 +       return ret;
18108 +}
18109 +
18110 +struct rtable *ip_v4_find_src(struct net *net, struct nx_info *nxi,
18111 +       struct flowi4 *fl4)
18112 +{
18113 +       struct rtable *rt;
18114 +
18115 +       if (!nxi)
18116 +               return NULL;
18117 +
18118 +       /* FIXME: handle lback only case */
18119 +       if (!NX_IPV4(nxi))
18120 +               return ERR_PTR(-EPERM);
18121 +
18122 +       vxdprintk(VXD_CBIT(net, 4),
18123 +               "ip_v4_find_src(%p[#%u]) " NIPQUAD_FMT " -> " NIPQUAD_FMT,
18124 +               nxi, nxi ? nxi->nx_id : 0,
18125 +               NIPQUAD(fl4->saddr), NIPQUAD(fl4->daddr));
18126 +
18127 +       /* single IP is unconditional */
18128 +       if (nx_info_flags(nxi, NXF_SINGLE_IP, 0) &&
18129 +               (fl4->saddr == INADDR_ANY))
18130 +               fl4->saddr = nxi->v4.ip[0].s_addr;
18131 +
18132 +       if (fl4->saddr == INADDR_ANY) {
18133 +               struct nx_addr_v4 *ptr;
18134 +               __be32 found = 0;
18135 +
18136 +               rt = __ip_route_output_key(net, fl4);
18137 +               if (!IS_ERR(rt)) {
18138 +                       found = fl4->saddr;
18139 +                       ip_rt_put(rt);
18140 +                       vxdprintk(VXD_CBIT(net, 4),
18141 +                               "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
18142 +                               nxi, nxi ? nxi->nx_id : 0, fl4->flowi4_oif, NIPQUAD(found));
18143 +                       if (v4_addr_in_nx_info(nxi, found, NXA_MASK_BIND))
18144 +                               goto found;
18145 +               }
18146 +
18147 +               WARN_ON_ONCE(in_irq());
18148 +               spin_lock_bh(&nxi->addr_lock);
18149 +               for (ptr = &nxi->v4; ptr; ptr = ptr->next) {
18150 +                       __be32 primary = ptr->ip[0].s_addr;
18151 +                       __be32 mask = ptr->mask.s_addr;
18152 +                       __be32 neta = primary & mask;
18153 +
18154 +                       vxdprintk(VXD_CBIT(net, 4), "ip_v4_find_src(%p[#%u]) chk: "
18155 +                               NIPQUAD_FMT "/" NIPQUAD_FMT "/" NIPQUAD_FMT,
18156 +                               nxi, nxi ? nxi->nx_id : 0, NIPQUAD(primary),
18157 +                               NIPQUAD(mask), NIPQUAD(neta));
18158 +                       if ((found & mask) != neta)
18159 +                               continue;
18160 +
18161 +                       fl4->saddr = primary;
18162 +                       rt = __ip_route_output_key(net, fl4);
18163 +                       vxdprintk(VXD_CBIT(net, 4),
18164 +                               "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
18165 +                               nxi, nxi ? nxi->nx_id : 0, fl4->flowi4_oif, NIPQUAD(primary));
18166 +                       if (!IS_ERR(rt)) {
18167 +                               found = fl4->saddr;
18168 +                               ip_rt_put(rt);
18169 +                               if (found == primary)
18170 +                                       goto found_unlock;
18171 +                       }
18172 +               }
18173 +               /* still no source ip? */
18174 +               found = ipv4_is_loopback(fl4->daddr)
18175 +                       ? IPI_LOOPBACK : nxi->v4.ip[0].s_addr;
18176 +       found_unlock:
18177 +               spin_unlock_bh(&nxi->addr_lock);
18178 +       found:
18179 +               /* assign src ip to flow */
18180 +               fl4->saddr = found;
18181 +
18182 +       } else {
18183 +               if (!v4_addr_in_nx_info(nxi, fl4->saddr, NXA_MASK_BIND))
18184 +                       return ERR_PTR(-EPERM);
18185 +       }
18186 +
18187 +       if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0)) {
18188 +               if (ipv4_is_loopback(fl4->daddr))
18189 +                       fl4->daddr = nxi->v4_lback.s_addr;
18190 +               if (ipv4_is_loopback(fl4->saddr))
18191 +                       fl4->saddr = nxi->v4_lback.s_addr;
18192 +       } else if (ipv4_is_loopback(fl4->daddr) &&
18193 +               !nx_info_flags(nxi, NXF_LBACK_ALLOW, 0))
18194 +               return ERR_PTR(-EPERM);
18195 +
18196 +       return NULL;
18197 +}
18198 +
18199 +EXPORT_SYMBOL_GPL(ip_v4_find_src);
18200 +
18201 diff -NurpP --minimal linux-3.18.5/kernel/vserver/init.c linux-3.18.5-vs2.3.7.3/kernel/vserver/init.c
18202 --- linux-3.18.5/kernel/vserver/init.c  1970-01-01 00:00:00.000000000 +0000
18203 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/init.c        2015-01-19 10:58:31.000000000 +0000
18204 @@ -0,0 +1,45 @@
18205 +/*
18206 + *  linux/kernel/init.c
18207 + *
18208 + *  Virtual Server Init
18209 + *
18210 + *  Copyright (C) 2004-2007  Herbert Pötzl
18211 + *
18212 + *  V0.01  basic structure
18213 + *
18214 + */
18215 +
18216 +#include <linux/init.h>
18217 +
18218 +int    vserver_register_sysctl(void);
18219 +void   vserver_unregister_sysctl(void);
18220 +
18221 +
18222 +static int __init init_vserver(void)
18223 +{
18224 +       int ret = 0;
18225 +
18226 +#ifdef CONFIG_VSERVER_DEBUG
18227 +       vserver_register_sysctl();
18228 +#endif
18229 +       return ret;
18230 +}
18231 +
18232 +
18233 +static void __exit exit_vserver(void)
18234 +{
18235 +
18236 +#ifdef CONFIG_VSERVER_DEBUG
18237 +       vserver_unregister_sysctl();
18238 +#endif
18239 +       return;
18240 +}
18241 +
18242 +/* FIXME: GFP_ZONETYPES gone
18243 +long vx_slab[GFP_ZONETYPES]; */
18244 +long vx_area;
18245 +
18246 +
18247 +module_init(init_vserver);
18248 +module_exit(exit_vserver);
18249 +
18250 diff -NurpP --minimal linux-3.18.5/kernel/vserver/inode.c linux-3.18.5-vs2.3.7.3/kernel/vserver/inode.c
18251 --- linux-3.18.5/kernel/vserver/inode.c 1970-01-01 00:00:00.000000000 +0000
18252 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/inode.c       2015-01-19 10:58:31.000000000 +0000
18253 @@ -0,0 +1,440 @@
18254 +/*
18255 + *  linux/kernel/vserver/inode.c
18256 + *
18257 + *  Virtual Server: File System Support
18258 + *
18259 + *  Copyright (C) 2004-2007  Herbert Pötzl
18260 + *
18261 + *  V0.01  separated from vcontext V0.05
18262 + *  V0.02  moved to tag (instead of xid)
18263 + *
18264 + */
18265 +
18266 +#include <linux/tty.h>
18267 +#include <linux/proc_fs.h>
18268 +#include <linux/devpts_fs.h>
18269 +#include <linux/fs.h>
18270 +#include <linux/file.h>
18271 +#include <linux/mount.h>
18272 +#include <linux/parser.h>
18273 +#include <linux/namei.h>
18274 +#include <linux/magic.h>
18275 +#include <linux/slab.h>
18276 +#include <linux/vserver/inode.h>
18277 +#include <linux/vserver/inode_cmd.h>
18278 +#include <linux/vs_base.h>
18279 +#include <linux/vs_tag.h>
18280 +
18281 +#include <asm/uaccess.h>
18282 +#include <../../fs/proc/internal.h>
18283 +
18284 +
18285 +static int __vc_get_iattr(struct inode *in, uint32_t *tag, uint32_t *flags, uint32_t *mask)
18286 +{
18287 +       struct proc_dir_entry *entry;
18288 +
18289 +       if (!in || !in->i_sb)
18290 +               return -ESRCH;
18291 +
18292 +       *flags = IATTR_TAG
18293 +               | (IS_IMMUTABLE(in) ? IATTR_IMMUTABLE : 0)
18294 +               | (IS_IXUNLINK(in) ? IATTR_IXUNLINK : 0)
18295 +               | (IS_BARRIER(in) ? IATTR_BARRIER : 0)
18296 +               | (IS_COW(in) ? IATTR_COW : 0);
18297 +       *mask = IATTR_IXUNLINK | IATTR_IMMUTABLE | IATTR_COW;
18298 +
18299 +       if (S_ISDIR(in->i_mode))
18300 +               *mask |= IATTR_BARRIER;
18301 +
18302 +       if (IS_TAGGED(in)) {
18303 +               *tag = i_tag_read(in);
18304 +               *mask |= IATTR_TAG;
18305 +       }
18306 +
18307 +       switch (in->i_sb->s_magic) {
18308 +       case PROC_SUPER_MAGIC:
18309 +               entry = PROC_I(in)->pde;
18310 +
18311 +               /* check for specific inodes? */
18312 +               if (entry)
18313 +                       *mask |= IATTR_FLAGS;
18314 +               if (entry)
18315 +                       *flags |= (entry->vx_flags & IATTR_FLAGS);
18316 +               else
18317 +                       *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS);
18318 +               break;
18319 +
18320 +       case DEVPTS_SUPER_MAGIC:
18321 +               *tag = i_tag_read(in);
18322 +               *mask |= IATTR_TAG;
18323 +               break;
18324 +
18325 +       default:
18326 +               break;
18327 +       }
18328 +       return 0;
18329 +}
18330 +
18331 +int vc_get_iattr(void __user *data)
18332 +{
18333 +       struct path path;
18334 +       struct vcmd_ctx_iattr_v1 vc_data = { .tag = -1 };
18335 +       int ret;
18336 +
18337 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18338 +               return -EFAULT;
18339 +
18340 +       ret = user_lpath(vc_data.name, &path);
18341 +       if (!ret) {
18342 +               ret = __vc_get_iattr(path.dentry->d_inode,
18343 +                       &vc_data.tag, &vc_data.flags, &vc_data.mask);
18344 +               path_put(&path);
18345 +       }
18346 +       if (ret)
18347 +               return ret;
18348 +
18349 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18350 +               ret = -EFAULT;
18351 +       return ret;
18352 +}
18353 +
18354 +#ifdef CONFIG_COMPAT
18355 +
18356 +int vc_get_iattr_x32(void __user *data)
18357 +{
18358 +       struct path path;
18359 +       struct vcmd_ctx_iattr_v1_x32 vc_data = { .tag = -1 };
18360 +       int ret;
18361 +
18362 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18363 +               return -EFAULT;
18364 +
18365 +       ret = user_lpath(compat_ptr(vc_data.name_ptr), &path);
18366 +       if (!ret) {
18367 +               ret = __vc_get_iattr(path.dentry->d_inode,
18368 +                       &vc_data.tag, &vc_data.flags, &vc_data.mask);
18369 +               path_put(&path);
18370 +       }
18371 +       if (ret)
18372 +               return ret;
18373 +
18374 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18375 +               ret = -EFAULT;
18376 +       return ret;
18377 +}
18378 +
18379 +#endif /* CONFIG_COMPAT */
18380 +
18381 +
18382 +int vc_fget_iattr(uint32_t fd, void __user *data)
18383 +{
18384 +       struct file *filp;
18385 +       struct vcmd_ctx_fiattr_v0 vc_data = { .tag = -1 };
18386 +       int ret;
18387 +
18388 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18389 +               return -EFAULT;
18390 +
18391 +       filp = fget(fd);
18392 +       if (!filp || !filp->f_dentry || !filp->f_dentry->d_inode)
18393 +               return -EBADF;
18394 +
18395 +       ret = __vc_get_iattr(filp->f_dentry->d_inode,
18396 +               &vc_data.tag, &vc_data.flags, &vc_data.mask);
18397 +
18398 +       fput(filp);
18399 +
18400 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18401 +               ret = -EFAULT;
18402 +       return ret;
18403 +}
18404 +
18405 +
18406 +static int __vc_set_iattr(struct dentry *de, uint32_t *tag, uint32_t *flags, uint32_t *mask)
18407 +{
18408 +       struct inode *in = de->d_inode;
18409 +       int error = 0, is_proc = 0, has_tag = 0;
18410 +       struct iattr attr = { 0 };
18411 +
18412 +       if (!in || !in->i_sb)
18413 +               return -ESRCH;
18414 +
18415 +       is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC);
18416 +       if ((*mask & IATTR_FLAGS) && !is_proc)
18417 +               return -EINVAL;
18418 +
18419 +       has_tag = IS_TAGGED(in) ||
18420 +               (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC);
18421 +       if ((*mask & IATTR_TAG) && !has_tag)
18422 +               return -EINVAL;
18423 +
18424 +       mutex_lock(&in->i_mutex);
18425 +       if (*mask & IATTR_TAG) {
18426 +               attr.ia_tag = make_ktag(&init_user_ns, *tag);
18427 +               attr.ia_valid |= ATTR_TAG;
18428 +       }
18429 +
18430 +       if (*mask & IATTR_FLAGS) {
18431 +               struct proc_dir_entry *entry = PROC_I(in)->pde;
18432 +               unsigned int iflags = PROC_I(in)->vx_flags;
18433 +
18434 +               iflags = (iflags & ~(*mask & IATTR_FLAGS))
18435 +                       | (*flags & IATTR_FLAGS);
18436 +               PROC_I(in)->vx_flags = iflags;
18437 +               if (entry)
18438 +                       entry->vx_flags = iflags;
18439 +       }
18440 +
18441 +       if (*mask & (IATTR_IMMUTABLE | IATTR_IXUNLINK |
18442 +               IATTR_BARRIER | IATTR_COW)) {
18443 +               int iflags = in->i_flags;
18444 +               int vflags = in->i_vflags;
18445 +
18446 +               if (*mask & IATTR_IMMUTABLE) {
18447 +                       if (*flags & IATTR_IMMUTABLE)
18448 +                               iflags |= S_IMMUTABLE;
18449 +                       else
18450 +                               iflags &= ~S_IMMUTABLE;
18451 +               }
18452 +               if (*mask & IATTR_IXUNLINK) {
18453 +                       if (*flags & IATTR_IXUNLINK)
18454 +                               iflags |= S_IXUNLINK;
18455 +                       else
18456 +                               iflags &= ~S_IXUNLINK;
18457 +               }
18458 +               if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) {
18459 +                       if (*flags & IATTR_BARRIER)
18460 +                               vflags |= V_BARRIER;
18461 +                       else
18462 +                               vflags &= ~V_BARRIER;
18463 +               }
18464 +               if (S_ISREG(in->i_mode) && (*mask & IATTR_COW)) {
18465 +                       if (*flags & IATTR_COW)
18466 +                               vflags |= V_COW;
18467 +                       else
18468 +                               vflags &= ~V_COW;
18469 +               }
18470 +               if (in->i_op && in->i_op->sync_flags) {
18471 +                       error = in->i_op->sync_flags(in, iflags, vflags);
18472 +                       if (error)
18473 +                               goto out;
18474 +               }
18475 +       }
18476 +
18477 +       if (attr.ia_valid) {
18478 +               if (in->i_op && in->i_op->setattr)
18479 +                       error = in->i_op->setattr(de, &attr);
18480 +               else {
18481 +                       error = inode_change_ok(in, &attr);
18482 +                       if (!error) {
18483 +                               setattr_copy(in, &attr);
18484 +                               mark_inode_dirty(in);
18485 +                       }
18486 +               }
18487 +       }
18488 +
18489 +out:
18490 +       mutex_unlock(&in->i_mutex);
18491 +       return error;
18492 +}
18493 +
18494 +int vc_set_iattr(void __user *data)
18495 +{
18496 +       struct path path;
18497 +       struct vcmd_ctx_iattr_v1 vc_data;
18498 +       int ret;
18499 +
18500 +       if (!capable(CAP_LINUX_IMMUTABLE))
18501 +               return -EPERM;
18502 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18503 +               return -EFAULT;
18504 +
18505 +       ret = user_lpath(vc_data.name, &path);
18506 +       if (!ret) {
18507 +               ret = __vc_set_iattr(path.dentry,
18508 +                       &vc_data.tag, &vc_data.flags, &vc_data.mask);
18509 +               path_put(&path);
18510 +       }
18511 +
18512 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18513 +               ret = -EFAULT;
18514 +       return ret;
18515 +}
18516 +
18517 +#ifdef CONFIG_COMPAT
18518 +
18519 +int vc_set_iattr_x32(void __user *data)
18520 +{
18521 +       struct path path;
18522 +       struct vcmd_ctx_iattr_v1_x32 vc_data;
18523 +       int ret;
18524 +
18525 +       if (!capable(CAP_LINUX_IMMUTABLE))
18526 +               return -EPERM;
18527 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18528 +               return -EFAULT;
18529 +
18530 +       ret = user_lpath(compat_ptr(vc_data.name_ptr), &path);
18531 +       if (!ret) {
18532 +               ret = __vc_set_iattr(path.dentry,
18533 +                       &vc_data.tag, &vc_data.flags, &vc_data.mask);
18534 +               path_put(&path);
18535 +       }
18536 +
18537 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18538 +               ret = -EFAULT;
18539 +       return ret;
18540 +}
18541 +
18542 +#endif /* CONFIG_COMPAT */
18543 +
18544 +int vc_fset_iattr(uint32_t fd, void __user *data)
18545 +{
18546 +       struct file *filp;
18547 +       struct vcmd_ctx_fiattr_v0 vc_data;
18548 +       int ret;
18549 +
18550 +       if (!capable(CAP_LINUX_IMMUTABLE))
18551 +               return -EPERM;
18552 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18553 +               return -EFAULT;
18554 +
18555 +       filp = fget(fd);
18556 +       if (!filp || !filp->f_dentry || !filp->f_dentry->d_inode)
18557 +               return -EBADF;
18558 +
18559 +       ret = __vc_set_iattr(filp->f_dentry, &vc_data.tag,
18560 +               &vc_data.flags, &vc_data.mask);
18561 +
18562 +       fput(filp);
18563 +
18564 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18565 +               return -EFAULT;
18566 +       return ret;
18567 +}
18568 +
18569 +
18570 +enum { Opt_notagcheck, Opt_tag, Opt_notag, Opt_tagid, Opt_err };
18571 +
18572 +static match_table_t tokens = {
18573 +       {Opt_notagcheck, "notagcheck"},
18574 +#ifdef CONFIG_PROPAGATE
18575 +       {Opt_notag, "notag"},
18576 +       {Opt_tag, "tag"},
18577 +       {Opt_tagid, "tagid=%u"},
18578 +#endif
18579 +       {Opt_err, NULL}
18580 +};
18581 +
18582 +
18583 +static void __dx_parse_remove(char *string, char *opt)
18584 +{
18585 +       char *p = strstr(string, opt);
18586 +       char *q = p;
18587 +
18588 +       if (p) {
18589 +               while (*q != '\0' && *q != ',')
18590 +                       q++;
18591 +               while (*q)
18592 +                       *p++ = *q++;
18593 +               while (*p)
18594 +                       *p++ = '\0';
18595 +       }
18596 +}
18597 +
18598 +int dx_parse_tag(char *string, vtag_t *tag, int remove, int *mnt_flags,
18599 +                unsigned long *flags)
18600 +{
18601 +       int set = 0;
18602 +       substring_t args[MAX_OPT_ARGS];
18603 +       int token;
18604 +       char *s, *p, *opts;
18605 +#if defined(CONFIG_PROPAGATE) || defined(CONFIG_VSERVER_DEBUG)
18606 +       int option = 0;
18607 +#endif
18608 +
18609 +       if (!string)
18610 +               return 0;
18611 +       s = kstrdup(string, GFP_KERNEL | GFP_ATOMIC);
18612 +       if (!s)
18613 +               return 0;
18614 +
18615 +       opts = s;
18616 +       while ((p = strsep(&opts, ",")) != NULL) {
18617 +               token = match_token(p, tokens, args);
18618 +
18619 +               switch (token) {
18620 +#ifdef CONFIG_PROPAGATE
18621 +               case Opt_tag:
18622 +                       if (tag)
18623 +                               *tag = 0;
18624 +                       if (remove)
18625 +                               __dx_parse_remove(s, "tag");
18626 +                       *mnt_flags |= MNT_TAGID;
18627 +                       set |= MNT_TAGID;
18628 +                       break;
18629 +               case Opt_notag:
18630 +                       if (remove)
18631 +                               __dx_parse_remove(s, "notag");
18632 +                       *mnt_flags |= MNT_NOTAG;
18633 +                       set |= MNT_NOTAG;
18634 +                       break;
18635 +               case Opt_tagid:
18636 +                       if (tag && !match_int(args, &option))
18637 +                               *tag = option;
18638 +                       if (remove)
18639 +                               __dx_parse_remove(s, "tagid");
18640 +                       *mnt_flags |= MNT_TAGID;
18641 +                       set |= MNT_TAGID;
18642 +                       break;
18643 +#endif /* CONFIG_PROPAGATE */
18644 +               case Opt_notagcheck:
18645 +                       if (remove)
18646 +                               __dx_parse_remove(s, "notagcheck");
18647 +                       *flags |= MS_NOTAGCHECK;
18648 +                       set |= MS_NOTAGCHECK;
18649 +                       break;
18650 +               }
18651 +               vxdprintk(VXD_CBIT(tag, 7),
18652 +                       "dx_parse_tag(" VS_Q("%s") "): %d:#%d",
18653 +                       p, token, option);
18654 +       }
18655 +       if (set)
18656 +               strcpy(string, s);
18657 +       kfree(s);
18658 +       return set;
18659 +}
18660 +
18661 +#ifdef CONFIG_PROPAGATE
18662 +
18663 +void __dx_propagate_tag(struct nameidata *nd, struct inode *inode)
18664 +{
18665 +       vtag_t new_tag = 0;
18666 +       struct vfsmount *mnt;
18667 +       int propagate;
18668 +
18669 +       if (!nd)
18670 +               return;
18671 +       mnt = nd->path.mnt;
18672 +       if (!mnt)
18673 +               return;
18674 +
18675 +       propagate = (mnt->mnt_flags & MNT_TAGID);
18676 +       if (propagate)
18677 +               new_tag = mnt->mnt_tag;
18678 +
18679 +       vxdprintk(VXD_CBIT(tag, 7),
18680 +               "dx_propagate_tag(%p[#%lu.%d]): %d,%d",
18681 +               inode, inode->i_ino, inode->i_tag,
18682 +               new_tag, (propagate) ? 1 : 0);
18683 +
18684 +       if (propagate)
18685 +               i_tag_write(inode, new_tag);
18686 +}
18687 +
18688 +#include <linux/module.h>
18689 +
18690 +EXPORT_SYMBOL_GPL(__dx_propagate_tag);
18691 +
18692 +#endif /* CONFIG_PROPAGATE */
18693 +
18694 diff -NurpP --minimal linux-3.18.5/kernel/vserver/limit.c linux-3.18.5-vs2.3.7.3/kernel/vserver/limit.c
18695 --- linux-3.18.5/kernel/vserver/limit.c 1970-01-01 00:00:00.000000000 +0000
18696 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/limit.c       2015-01-19 10:58:31.000000000 +0000
18697 @@ -0,0 +1,345 @@
18698 +/*
18699 + *  linux/kernel/vserver/limit.c
18700 + *
18701 + *  Virtual Server: Context Limits
18702 + *
18703 + *  Copyright (C) 2004-2010  Herbert Pötzl
18704 + *
18705 + *  V0.01  broken out from vcontext V0.05
18706 + *  V0.02  changed vcmds to vxi arg
18707 + *  V0.03  added memory cgroup support
18708 + *
18709 + */
18710 +
18711 +#include <linux/sched.h>
18712 +#include <linux/module.h>
18713 +#include <linux/memcontrol.h>
18714 +#include <linux/res_counter.h>
18715 +#include <linux/vs_limit.h>
18716 +#include <linux/vserver/limit.h>
18717 +#include <linux/vserver/limit_cmd.h>
18718 +
18719 +#include <asm/uaccess.h>
18720 +
18721 +
18722 +const char *vlimit_name[NUM_LIMITS] = {
18723 +       [RLIMIT_CPU]            = "CPU",
18724 +       [RLIMIT_NPROC]          = "NPROC",
18725 +       [RLIMIT_NOFILE]         = "NOFILE",
18726 +       [RLIMIT_LOCKS]          = "LOCKS",
18727 +       [RLIMIT_SIGPENDING]     = "SIGP",
18728 +       [RLIMIT_MSGQUEUE]       = "MSGQ",
18729 +
18730 +       [VLIMIT_NSOCK]          = "NSOCK",
18731 +       [VLIMIT_OPENFD]         = "OPENFD",
18732 +       [VLIMIT_SHMEM]          = "SHMEM",
18733 +       [VLIMIT_DENTRY]         = "DENTRY",
18734 +};
18735 +
18736 +EXPORT_SYMBOL_GPL(vlimit_name);
18737 +
18738 +#define MASK_ENTRY(x)  (1 << (x))
18739 +
18740 +const struct vcmd_ctx_rlimit_mask_v0 vlimit_mask = {
18741 +               /* minimum */
18742 +       0
18743 +       ,       /* softlimit */
18744 +       0
18745 +       ,       /* maximum */
18746 +       MASK_ENTRY( RLIMIT_NPROC        ) |
18747 +       MASK_ENTRY( RLIMIT_NOFILE       ) |
18748 +       MASK_ENTRY( RLIMIT_LOCKS        ) |
18749 +       MASK_ENTRY( RLIMIT_MSGQUEUE     ) |
18750 +
18751 +       MASK_ENTRY( VLIMIT_NSOCK        ) |
18752 +       MASK_ENTRY( VLIMIT_OPENFD       ) |
18753 +       MASK_ENTRY( VLIMIT_SHMEM        ) |
18754 +       MASK_ENTRY( VLIMIT_DENTRY       ) |
18755 +       0
18756 +};
18757 +               /* accounting only */
18758 +uint32_t account_mask =
18759 +       MASK_ENTRY( VLIMIT_SEMARY       ) |
18760 +       MASK_ENTRY( VLIMIT_NSEMS        ) |
18761 +       MASK_ENTRY( VLIMIT_MAPPED       ) |
18762 +       0;
18763 +
18764 +
18765 +static int is_valid_vlimit(int id)
18766 +{
18767 +       uint32_t mask = vlimit_mask.minimum |
18768 +               vlimit_mask.softlimit | vlimit_mask.maximum;
18769 +       return mask & (1 << id);
18770 +}
18771 +
18772 +static int is_accounted_vlimit(int id)
18773 +{
18774 +       if (is_valid_vlimit(id))
18775 +               return 1;
18776 +       return account_mask & (1 << id);
18777 +}
18778 +
18779 +
18780 +static inline uint64_t vc_get_soft(struct vx_info *vxi, int id)
18781 +{
18782 +       rlim_t limit = __rlim_soft(&vxi->limit, id);
18783 +       return VX_VLIM(limit);
18784 +}
18785 +
18786 +static inline uint64_t vc_get_hard(struct vx_info *vxi, int id)
18787 +{
18788 +       rlim_t limit = __rlim_hard(&vxi->limit, id);
18789 +       return VX_VLIM(limit);
18790 +}
18791 +
18792 +static int do_get_rlimit(struct vx_info *vxi, uint32_t id,
18793 +       uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
18794 +{
18795 +       if (!is_valid_vlimit(id))
18796 +               return -EINVAL;
18797 +
18798 +       if (minimum)
18799 +               *minimum = CRLIM_UNSET;
18800 +       if (softlimit)
18801 +               *softlimit = vc_get_soft(vxi, id);
18802 +       if (maximum)
18803 +               *maximum = vc_get_hard(vxi, id);
18804 +       return 0;
18805 +}
18806 +
18807 +int vc_get_rlimit(struct vx_info *vxi, void __user *data)
18808 +{
18809 +       struct vcmd_ctx_rlimit_v0 vc_data;
18810 +       int ret;
18811 +
18812 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18813 +               return -EFAULT;
18814 +
18815 +       ret = do_get_rlimit(vxi, vc_data.id,
18816 +               &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
18817 +       if (ret)
18818 +               return ret;
18819 +
18820 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18821 +               return -EFAULT;
18822 +       return 0;
18823 +}
18824 +
18825 +static int do_set_rlimit(struct vx_info *vxi, uint32_t id,
18826 +       uint64_t minimum, uint64_t softlimit, uint64_t maximum)
18827 +{
18828 +       if (!is_valid_vlimit(id))
18829 +               return -EINVAL;
18830 +
18831 +       if (maximum != CRLIM_KEEP)
18832 +               __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum);
18833 +       if (softlimit != CRLIM_KEEP)
18834 +               __rlim_soft(&vxi->limit, id) = VX_RLIM(softlimit);
18835 +
18836 +       /* clamp soft limit */
18837 +       if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id))
18838 +               __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id);
18839 +
18840 +       return 0;
18841 +}
18842 +
18843 +int vc_set_rlimit(struct vx_info *vxi, void __user *data)
18844 +{
18845 +       struct vcmd_ctx_rlimit_v0 vc_data;
18846 +
18847 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18848 +               return -EFAULT;
18849 +
18850 +       return do_set_rlimit(vxi, vc_data.id,
18851 +               vc_data.minimum, vc_data.softlimit, vc_data.maximum);
18852 +}
18853 +
18854 +#ifdef CONFIG_IA32_EMULATION
18855 +
18856 +int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data)
18857 +{
18858 +       struct vcmd_ctx_rlimit_v0_x32 vc_data;
18859 +
18860 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18861 +               return -EFAULT;
18862 +
18863 +       return do_set_rlimit(vxi, vc_data.id,
18864 +               vc_data.minimum, vc_data.softlimit, vc_data.maximum);
18865 +}
18866 +
18867 +int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data)
18868 +{
18869 +       struct vcmd_ctx_rlimit_v0_x32 vc_data;
18870 +       int ret;
18871 +
18872 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18873 +               return -EFAULT;
18874 +
18875 +       ret = do_get_rlimit(vxi, vc_data.id,
18876 +               &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
18877 +       if (ret)
18878 +               return ret;
18879 +
18880 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18881 +               return -EFAULT;
18882 +       return 0;
18883 +}
18884 +
18885 +#endif /* CONFIG_IA32_EMULATION */
18886 +
18887 +
18888 +int vc_get_rlimit_mask(uint32_t id, void __user *data)
18889 +{
18890 +       if (copy_to_user(data, &vlimit_mask, sizeof(vlimit_mask)))
18891 +               return -EFAULT;
18892 +       return 0;
18893 +}
18894 +
18895 +
18896 +static inline void vx_reset_hits(struct _vx_limit *limit)
18897 +{
18898 +       int lim;
18899 +
18900 +       for (lim = 0; lim < NUM_LIMITS; lim++) {
18901 +               atomic_set(&__rlim_lhit(limit, lim), 0);
18902 +       }
18903 +}
18904 +
18905 +int vc_reset_hits(struct vx_info *vxi, void __user *data)
18906 +{
18907 +       vx_reset_hits(&vxi->limit);
18908 +       return 0;
18909 +}
18910 +
18911 +static inline void vx_reset_minmax(struct _vx_limit *limit)
18912 +{
18913 +       rlim_t value;
18914 +       int lim;
18915 +
18916 +       for (lim = 0; lim < NUM_LIMITS; lim++) {
18917 +               value = __rlim_get(limit, lim);
18918 +               __rlim_rmax(limit, lim) = value;
18919 +               __rlim_rmin(limit, lim) = value;
18920 +       }
18921 +}
18922 +
18923 +int vc_reset_minmax(struct vx_info *vxi, void __user *data)
18924 +{
18925 +       vx_reset_minmax(&vxi->limit);
18926 +       return 0;
18927 +}
18928 +
18929 +
18930 +int vc_rlimit_stat(struct vx_info *vxi, void __user *data)
18931 +{
18932 +       struct vcmd_rlimit_stat_v0 vc_data;
18933 +       struct _vx_limit *limit = &vxi->limit;
18934 +       int id;
18935 +
18936 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18937 +               return -EFAULT;
18938 +
18939 +       id = vc_data.id;
18940 +       if (!is_accounted_vlimit(id))
18941 +               return -EINVAL;
18942 +
18943 +       vx_limit_fixup(limit, id);
18944 +       vc_data.hits = atomic_read(&__rlim_lhit(limit, id));
18945 +       vc_data.value = __rlim_get(limit, id);
18946 +       vc_data.minimum = __rlim_rmin(limit, id);
18947 +       vc_data.maximum = __rlim_rmax(limit, id);
18948 +
18949 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18950 +               return -EFAULT;
18951 +       return 0;
18952 +}
18953 +
18954 +
18955 +void vx_vsi_meminfo(struct sysinfo *val)
18956 +{
18957 +#ifdef CONFIG_MEMCG
18958 +       struct mem_cgroup *mcg;
18959 +       u64 res_limit, res_usage;
18960 +
18961 +       rcu_read_lock();
18962 +       mcg = mem_cgroup_from_task(current);
18963 +       rcu_read_unlock();
18964 +       if (!mcg)
18965 +               goto out;
18966 +
18967 +       res_limit = mem_cgroup_res_read_u64(mcg, RES_LIMIT);
18968 +       res_usage = mem_cgroup_res_read_u64(mcg, RES_USAGE);
18969 +
18970 +       if (res_limit != RES_COUNTER_MAX)
18971 +               val->totalram = (res_limit >> PAGE_SHIFT);
18972 +       val->freeram = val->totalram - (res_usage >> PAGE_SHIFT);
18973 +       val->bufferram = 0;
18974 +       val->totalhigh = 0;
18975 +       val->freehigh = 0;
18976 +out:
18977 +#endif /* CONFIG_MEMCG */
18978 +       return;
18979 +}
18980 +
18981 +void vx_vsi_swapinfo(struct sysinfo *val)
18982 +{
18983 +#ifdef CONFIG_MEMCG
18984 +#ifdef CONFIG_MEMCG_SWAP
18985 +       struct mem_cgroup *mcg;
18986 +       u64 res_limit, res_usage, memsw_limit, memsw_usage;
18987 +       s64 swap_limit, swap_usage;
18988 +
18989 +       rcu_read_lock();
18990 +       mcg = mem_cgroup_from_task(current);
18991 +       rcu_read_unlock();
18992 +       if (!mcg)
18993 +               goto out;
18994 +
18995 +       res_limit = mem_cgroup_res_read_u64(mcg, RES_LIMIT);
18996 +       res_usage = mem_cgroup_res_read_u64(mcg, RES_USAGE);
18997 +       memsw_limit = mem_cgroup_memsw_read_u64(mcg, RES_LIMIT);
18998 +       memsw_usage = mem_cgroup_memsw_read_u64(mcg, RES_USAGE);
18999 +
19000 +       /* memory unlimited */
19001 +       if (res_limit == RES_COUNTER_MAX)
19002 +               goto out;
19003 +
19004 +       swap_limit = memsw_limit - res_limit;
19005 +       /* we have a swap limit? */
19006 +       if (memsw_limit != RES_COUNTER_MAX)
19007 +               val->totalswap = swap_limit >> PAGE_SHIFT;
19008 +
19009 +       /* calculate swap part */
19010 +       swap_usage = (memsw_usage > res_usage) ?
19011 +               memsw_usage - res_usage : 0;
19012 +
19013 +       /* total shown minus usage gives free swap */
19014 +       val->freeswap = (swap_usage < swap_limit) ?
19015 +               val->totalswap - (swap_usage >> PAGE_SHIFT) : 0;
19016 +out:
19017 +#else  /* !CONFIG_MEMCG_SWAP */
19018 +       val->totalswap = 0;
19019 +       val->freeswap = 0;
19020 +#endif /* !CONFIG_MEMCG_SWAP */
19021 +#endif /* CONFIG_MEMCG */
19022 +       return;
19023 +}
19024 +
19025 +long vx_vsi_cached(struct sysinfo *val)
19026 +{
19027 +       long cache = 0;
19028 +#ifdef CONFIG_MEMCG
19029 +       struct mem_cgroup *mcg;
19030 +
19031 +       rcu_read_lock();
19032 +       mcg = mem_cgroup_from_task(current);
19033 +       rcu_read_unlock();
19034 +       if (!mcg)
19035 +               goto out;
19036 +
19037 +       cache = mem_cgroup_stat_read_cache(mcg);
19038 +out:
19039 +#endif
19040 +       return cache;
19041 +}
19042 +
19043 diff -NurpP --minimal linux-3.18.5/kernel/vserver/limit_init.h linux-3.18.5-vs2.3.7.3/kernel/vserver/limit_init.h
19044 --- linux-3.18.5/kernel/vserver/limit_init.h    1970-01-01 00:00:00.000000000 +0000
19045 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/limit_init.h  2015-01-19 10:58:31.000000000 +0000
19046 @@ -0,0 +1,31 @@
19047 +
19048 +
19049 +static inline void vx_info_init_limit(struct _vx_limit *limit)
19050 +{
19051 +       int lim;
19052 +
19053 +       for (lim = 0; lim < NUM_LIMITS; lim++) {
19054 +               __rlim_soft(limit, lim) = RLIM_INFINITY;
19055 +               __rlim_hard(limit, lim) = RLIM_INFINITY;
19056 +               __rlim_set(limit, lim, 0);
19057 +               atomic_set(&__rlim_lhit(limit, lim), 0);
19058 +               __rlim_rmin(limit, lim) = 0;
19059 +               __rlim_rmax(limit, lim) = 0;
19060 +       }
19061 +}
19062 +
19063 +static inline void vx_info_exit_limit(struct _vx_limit *limit)
19064 +{
19065 +       rlim_t value;
19066 +       int lim;
19067 +
19068 +       for (lim = 0; lim < NUM_LIMITS; lim++) {
19069 +               if ((1 << lim) & VLIM_NOCHECK)
19070 +                       continue;
19071 +               value = __rlim_get(limit, lim);
19072 +               vxwprintk_xid(value,
19073 +                       "!!! limit: %p[%s,%d] = %ld on exit.",
19074 +                       limit, vlimit_name[lim], lim, (long)value);
19075 +       }
19076 +}
19077 +
19078 diff -NurpP --minimal linux-3.18.5/kernel/vserver/limit_proc.h linux-3.18.5-vs2.3.7.3/kernel/vserver/limit_proc.h
19079 --- linux-3.18.5/kernel/vserver/limit_proc.h    1970-01-01 00:00:00.000000000 +0000
19080 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/limit_proc.h  2015-01-19 10:58:31.000000000 +0000
19081 @@ -0,0 +1,57 @@
19082 +#ifndef _VX_LIMIT_PROC_H
19083 +#define _VX_LIMIT_PROC_H
19084 +
19085 +#include <linux/vserver/limit_int.h>
19086 +
19087 +
19088 +#define VX_LIMIT_FMT   ":\t%8ld\t%8ld/%8ld\t%8lld/%8lld\t%6d\n"
19089 +#define VX_LIMIT_TOP   \
19090 +       "Limit\t current\t     min/max\t\t    soft/hard\t\thits\n"
19091 +
19092 +#define VX_LIMIT_ARG(r)                                \
19093 +       (unsigned long)__rlim_get(limit, r),    \
19094 +       (unsigned long)__rlim_rmin(limit, r),   \
19095 +       (unsigned long)__rlim_rmax(limit, r),   \
19096 +       VX_VLIM(__rlim_soft(limit, r)),         \
19097 +       VX_VLIM(__rlim_hard(limit, r)),         \
19098 +       atomic_read(&__rlim_lhit(limit, r))
19099 +
19100 +static inline int vx_info_proc_limit(struct _vx_limit *limit, char *buffer)
19101 +{
19102 +       vx_limit_fixup(limit, -1);
19103 +       return sprintf(buffer, VX_LIMIT_TOP
19104 +               "PROC"  VX_LIMIT_FMT
19105 +               "VM"    VX_LIMIT_FMT
19106 +               "VML"   VX_LIMIT_FMT
19107 +               "RSS"   VX_LIMIT_FMT
19108 +               "ANON"  VX_LIMIT_FMT
19109 +               "RMAP"  VX_LIMIT_FMT
19110 +               "FILES" VX_LIMIT_FMT
19111 +               "OFD"   VX_LIMIT_FMT
19112 +               "LOCKS" VX_LIMIT_FMT
19113 +               "SOCK"  VX_LIMIT_FMT
19114 +               "MSGQ"  VX_LIMIT_FMT
19115 +               "SHM"   VX_LIMIT_FMT
19116 +               "SEMA"  VX_LIMIT_FMT
19117 +               "SEMS"  VX_LIMIT_FMT
19118 +               "DENT"  VX_LIMIT_FMT,
19119 +               VX_LIMIT_ARG(RLIMIT_NPROC),
19120 +               VX_LIMIT_ARG(RLIMIT_AS),
19121 +               VX_LIMIT_ARG(RLIMIT_MEMLOCK),
19122 +               VX_LIMIT_ARG(RLIMIT_RSS),
19123 +               VX_LIMIT_ARG(VLIMIT_ANON),
19124 +               VX_LIMIT_ARG(VLIMIT_MAPPED),
19125 +               VX_LIMIT_ARG(RLIMIT_NOFILE),
19126 +               VX_LIMIT_ARG(VLIMIT_OPENFD),
19127 +               VX_LIMIT_ARG(RLIMIT_LOCKS),
19128 +               VX_LIMIT_ARG(VLIMIT_NSOCK),
19129 +               VX_LIMIT_ARG(RLIMIT_MSGQUEUE),
19130 +               VX_LIMIT_ARG(VLIMIT_SHMEM),
19131 +               VX_LIMIT_ARG(VLIMIT_SEMARY),
19132 +               VX_LIMIT_ARG(VLIMIT_NSEMS),
19133 +               VX_LIMIT_ARG(VLIMIT_DENTRY));
19134 +}
19135 +
19136 +#endif /* _VX_LIMIT_PROC_H */
19137 +
19138 +
19139 diff -NurpP --minimal linux-3.18.5/kernel/vserver/network.c linux-3.18.5-vs2.3.7.3/kernel/vserver/network.c
19140 --- linux-3.18.5/kernel/vserver/network.c       1970-01-01 00:00:00.000000000 +0000
19141 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/network.c     2015-01-19 10:58:31.000000000 +0000
19142 @@ -0,0 +1,1053 @@
19143 +/*
19144 + *  linux/kernel/vserver/network.c
19145 + *
19146 + *  Virtual Server: Network Support
19147 + *
19148 + *  Copyright (C) 2003-2007  Herbert Pötzl
19149 + *
19150 + *  V0.01  broken out from vcontext V0.05
19151 + *  V0.02  cleaned up implementation
19152 + *  V0.03  added equiv nx commands
19153 + *  V0.04  switch to RCU based hash
19154 + *  V0.05  and back to locking again
19155 + *  V0.06  changed vcmds to nxi arg
19156 + *  V0.07  have __create claim() the nxi
19157 + *
19158 + */
19159 +
19160 +#include <linux/err.h>
19161 +#include <linux/slab.h>
19162 +#include <linux/rcupdate.h>
19163 +#include <net/ipv6.h>
19164 +
19165 +#include <linux/vs_network.h>
19166 +#include <linux/vs_pid.h>
19167 +#include <linux/vserver/network_cmd.h>
19168 +
19169 +
19170 +atomic_t nx_global_ctotal      = ATOMIC_INIT(0);
19171 +atomic_t nx_global_cactive     = ATOMIC_INIT(0);
19172 +
19173 +static struct kmem_cache *nx_addr_v4_cachep = NULL;
19174 +static struct kmem_cache *nx_addr_v6_cachep = NULL;
19175 +
19176 +
19177 +static int __init init_network(void)
19178 +{
19179 +       nx_addr_v4_cachep = kmem_cache_create("nx_v4_addr_cache",
19180 +               sizeof(struct nx_addr_v4), 0,
19181 +               SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
19182 +       nx_addr_v6_cachep = kmem_cache_create("nx_v6_addr_cache",
19183 +               sizeof(struct nx_addr_v6), 0,
19184 +               SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
19185 +       return 0;
19186 +}
19187 +
19188 +
19189 +/*     __alloc_nx_addr_v4()                                    */
19190 +
19191 +static inline struct nx_addr_v4 *__alloc_nx_addr_v4(void)
19192 +{
19193 +       struct nx_addr_v4 *nxa = kmem_cache_alloc(
19194 +               nx_addr_v4_cachep, GFP_KERNEL);
19195 +
19196 +       if (!IS_ERR(nxa))
19197 +               memset(nxa, 0, sizeof(*nxa));
19198 +       return nxa;
19199 +}
19200 +
19201 +/*     __dealloc_nx_addr_v4()                                  */
19202 +
19203 +static inline void __dealloc_nx_addr_v4(struct nx_addr_v4 *nxa)
19204 +{
19205 +       kmem_cache_free(nx_addr_v4_cachep, nxa);
19206 +}
19207 +
19208 +/*     __dealloc_nx_addr_v4_all()                              */
19209 +
19210 +static inline void __dealloc_nx_addr_v4_all(struct nx_addr_v4 *nxa)
19211 +{
19212 +       while (nxa) {
19213 +               struct nx_addr_v4 *next = nxa->next;
19214 +
19215 +               __dealloc_nx_addr_v4(nxa);
19216 +               nxa = next;
19217 +       }
19218 +}
19219 +
19220 +
19221 +#ifdef CONFIG_IPV6
19222 +
19223 +/*     __alloc_nx_addr_v6()                                    */
19224 +
19225 +static inline struct nx_addr_v6 *__alloc_nx_addr_v6(void)
19226 +{
19227 +       struct nx_addr_v6 *nxa = kmem_cache_alloc(
19228 +               nx_addr_v6_cachep, GFP_KERNEL);
19229 +
19230 +       if (!IS_ERR(nxa))
19231 +               memset(nxa, 0, sizeof(*nxa));
19232 +       return nxa;
19233 +}
19234 +
19235 +/*     __dealloc_nx_addr_v6()                                  */
19236 +
19237 +static inline void __dealloc_nx_addr_v6(struct nx_addr_v6 *nxa)
19238 +{
19239 +       kmem_cache_free(nx_addr_v6_cachep, nxa);
19240 +}
19241 +
19242 +/*     __dealloc_nx_addr_v6_all()                              */
19243 +
19244 +static inline void __dealloc_nx_addr_v6_all(struct nx_addr_v6 *nxa)
19245 +{
19246 +       while (nxa) {
19247 +               struct nx_addr_v6 *next = nxa->next;
19248 +
19249 +               __dealloc_nx_addr_v6(nxa);
19250 +               nxa = next;
19251 +       }
19252 +}
19253 +
19254 +#endif /* CONFIG_IPV6 */
19255 +
19256 +/*     __alloc_nx_info()
19257 +
19258 +       * allocate an initialized nx_info struct
19259 +       * doesn't make it visible (hash)                        */
19260 +
19261 +static struct nx_info *__alloc_nx_info(vnid_t nid)
19262 +{
19263 +       struct nx_info *new = NULL;
19264 +
19265 +       vxdprintk(VXD_CBIT(nid, 1), "alloc_nx_info(%d)*", nid);
19266 +
19267 +       /* would this benefit from a slab cache? */
19268 +       new = kmalloc(sizeof(struct nx_info), GFP_KERNEL);
19269 +       if (!new)
19270 +               return 0;
19271 +
19272 +       memset(new, 0, sizeof(struct nx_info));
19273 +       new->nx_id = nid;
19274 +       INIT_HLIST_NODE(&new->nx_hlist);
19275 +       atomic_set(&new->nx_usecnt, 0);
19276 +       atomic_set(&new->nx_tasks, 0);
19277 +       spin_lock_init(&new->addr_lock);
19278 +       new->nx_state = 0;
19279 +
19280 +       new->nx_flags = NXF_INIT_SET;
19281 +
19282 +       /* rest of init goes here */
19283 +
19284 +       new->v4_lback.s_addr = htonl(INADDR_LOOPBACK);
19285 +       new->v4_bcast.s_addr = htonl(INADDR_BROADCAST);
19286 +
19287 +       vxdprintk(VXD_CBIT(nid, 0),
19288 +               "alloc_nx_info(%d) = %p", nid, new);
19289 +       atomic_inc(&nx_global_ctotal);
19290 +       return new;
19291 +}
19292 +
19293 +/*     __dealloc_nx_info()
19294 +
19295 +       * final disposal of nx_info                             */
19296 +
19297 +static void __dealloc_nx_info(struct nx_info *nxi)
19298 +{
19299 +       vxdprintk(VXD_CBIT(nid, 0),
19300 +               "dealloc_nx_info(%p)", nxi);
19301 +
19302 +       nxi->nx_hlist.next = LIST_POISON1;
19303 +       nxi->nx_id = -1;
19304 +
19305 +       BUG_ON(atomic_read(&nxi->nx_usecnt));
19306 +       BUG_ON(atomic_read(&nxi->nx_tasks));
19307 +
19308 +       __dealloc_nx_addr_v4_all(nxi->v4.next);
19309 +#ifdef CONFIG_IPV6
19310 +       __dealloc_nx_addr_v6_all(nxi->v6.next);
19311 +#endif
19312 +
19313 +       nxi->nx_state |= NXS_RELEASED;
19314 +       kfree(nxi);
19315 +       atomic_dec(&nx_global_ctotal);
19316 +}
19317 +
19318 +static void __shutdown_nx_info(struct nx_info *nxi)
19319 +{
19320 +       nxi->nx_state |= NXS_SHUTDOWN;
19321 +       vs_net_change(nxi, VSC_NETDOWN);
19322 +}
19323 +
19324 +/*     exported stuff                                          */
19325 +
19326 +void free_nx_info(struct nx_info *nxi)
19327 +{
19328 +       /* context shutdown is mandatory */
19329 +       BUG_ON(nxi->nx_state != NXS_SHUTDOWN);
19330 +
19331 +       /* context must not be hashed */
19332 +       BUG_ON(nxi->nx_state & NXS_HASHED);
19333 +
19334 +       BUG_ON(atomic_read(&nxi->nx_usecnt));
19335 +       BUG_ON(atomic_read(&nxi->nx_tasks));
19336 +
19337 +       __dealloc_nx_info(nxi);
19338 +}
19339 +
19340 +
19341 +void __nx_set_lback(struct nx_info *nxi)
19342 +{
19343 +       int nid = nxi->nx_id;
19344 +       __be32 lback = htonl(INADDR_LOOPBACK ^ ((nid & 0xFFFF) << 8));
19345 +
19346 +       nxi->v4_lback.s_addr = lback;
19347 +}
19348 +
19349 +extern int __nx_inet_add_lback(__be32 addr);
19350 +extern int __nx_inet_del_lback(__be32 addr);
19351 +
19352 +
19353 +/*     hash table for nx_info hash */
19354 +
19355 +#define NX_HASH_SIZE   13
19356 +
19357 +struct hlist_head nx_info_hash[NX_HASH_SIZE];
19358 +
19359 +static DEFINE_SPINLOCK(nx_info_hash_lock);
19360 +
19361 +
19362 +static inline unsigned int __hashval(vnid_t nid)
19363 +{
19364 +       return (nid % NX_HASH_SIZE);
19365 +}
19366 +
19367 +
19368 +
19369 +/*     __hash_nx_info()
19370 +
19371 +       * add the nxi to the global hash table
19372 +       * requires the hash_lock to be held                     */
19373 +
19374 +static inline void __hash_nx_info(struct nx_info *nxi)
19375 +{
19376 +       struct hlist_head *head;
19377 +
19378 +       vxd_assert_lock(&nx_info_hash_lock);
19379 +       vxdprintk(VXD_CBIT(nid, 4),
19380 +               "__hash_nx_info: %p[#%d]", nxi, nxi->nx_id);
19381 +
19382 +       /* context must not be hashed */
19383 +       BUG_ON(nx_info_state(nxi, NXS_HASHED));
19384 +
19385 +       nxi->nx_state |= NXS_HASHED;
19386 +       head = &nx_info_hash[__hashval(nxi->nx_id)];
19387 +       hlist_add_head(&nxi->nx_hlist, head);
19388 +       atomic_inc(&nx_global_cactive);
19389 +}
19390 +
19391 +/*     __unhash_nx_info()
19392 +
19393 +       * remove the nxi from the global hash table
19394 +       * requires the hash_lock to be held                     */
19395 +
19396 +static inline void __unhash_nx_info(struct nx_info *nxi)
19397 +{
19398 +       vxd_assert_lock(&nx_info_hash_lock);
19399 +       vxdprintk(VXD_CBIT(nid, 4),
19400 +               "__unhash_nx_info: %p[#%d.%d.%d]", nxi, nxi->nx_id,
19401 +               atomic_read(&nxi->nx_usecnt), atomic_read(&nxi->nx_tasks));
19402 +
19403 +       /* context must be hashed */
19404 +       BUG_ON(!nx_info_state(nxi, NXS_HASHED));
19405 +       /* but without tasks */
19406 +       BUG_ON(atomic_read(&nxi->nx_tasks));
19407 +
19408 +       nxi->nx_state &= ~NXS_HASHED;
19409 +       hlist_del(&nxi->nx_hlist);
19410 +       atomic_dec(&nx_global_cactive);
19411 +}
19412 +
19413 +
19414 +/*     __lookup_nx_info()
19415 +
19416 +       * requires the hash_lock to be held
19417 +       * doesn't increment the nx_refcnt                       */
19418 +
19419 +static inline struct nx_info *__lookup_nx_info(vnid_t nid)
19420 +{
19421 +       struct hlist_head *head = &nx_info_hash[__hashval(nid)];
19422 +       struct hlist_node *pos;
19423 +       struct nx_info *nxi;
19424 +
19425 +       vxd_assert_lock(&nx_info_hash_lock);
19426 +       hlist_for_each(pos, head) {
19427 +               nxi = hlist_entry(pos, struct nx_info, nx_hlist);
19428 +
19429 +               if (nxi->nx_id == nid)
19430 +                       goto found;
19431 +       }
19432 +       nxi = NULL;
19433 +found:
19434 +       vxdprintk(VXD_CBIT(nid, 0),
19435 +               "__lookup_nx_info(#%u): %p[#%u]",
19436 +               nid, nxi, nxi ? nxi->nx_id : 0);
19437 +       return nxi;
19438 +}
19439 +
19440 +
19441 +/*     __create_nx_info()
19442 +
19443 +       * create the requested context
19444 +       * get(), claim() and hash it                            */
19445 +
19446 +static struct nx_info *__create_nx_info(int id)
19447 +{
19448 +       struct nx_info *new, *nxi = NULL;
19449 +
19450 +       vxdprintk(VXD_CBIT(nid, 1), "create_nx_info(%d)*", id);
19451 +
19452 +       if (!(new = __alloc_nx_info(id)))
19453 +               return ERR_PTR(-ENOMEM);
19454 +
19455 +       /* required to make dynamic xids unique */
19456 +       spin_lock(&nx_info_hash_lock);
19457 +
19458 +       /* static context requested */
19459 +       if ((nxi = __lookup_nx_info(id))) {
19460 +               vxdprintk(VXD_CBIT(nid, 0),
19461 +                       "create_nx_info(%d) = %p (already there)", id, nxi);
19462 +               if (nx_info_flags(nxi, NXF_STATE_SETUP, 0))
19463 +                       nxi = ERR_PTR(-EBUSY);
19464 +               else
19465 +                       nxi = ERR_PTR(-EEXIST);
19466 +               goto out_unlock;
19467 +       }
19468 +       /* new context */
19469 +       vxdprintk(VXD_CBIT(nid, 0),
19470 +               "create_nx_info(%d) = %p (new)", id, new);
19471 +       claim_nx_info(new, NULL);
19472 +       __nx_set_lback(new);
19473 +       __hash_nx_info(get_nx_info(new));
19474 +       nxi = new, new = NULL;
19475 +
19476 +out_unlock:
19477 +       spin_unlock(&nx_info_hash_lock);
19478 +       if (new)
19479 +               __dealloc_nx_info(new);
19480 +       return nxi;
19481 +}
19482 +
19483 +
19484 +
19485 +/*     exported stuff                                          */
19486 +
19487 +
19488 +void unhash_nx_info(struct nx_info *nxi)
19489 +{
19490 +       __shutdown_nx_info(nxi);
19491 +       spin_lock(&nx_info_hash_lock);
19492 +       __unhash_nx_info(nxi);
19493 +       spin_unlock(&nx_info_hash_lock);
19494 +}
19495 +
19496 +/*     lookup_nx_info()
19497 +
19498 +       * search for a nx_info and get() it
19499 +       * negative id means current                             */
19500 +
19501 +struct nx_info *lookup_nx_info(int id)
19502 +{
19503 +       struct nx_info *nxi = NULL;
19504 +
19505 +       if (id < 0) {
19506 +               nxi = get_nx_info(current_nx_info());
19507 +       } else if (id > 1) {
19508 +               spin_lock(&nx_info_hash_lock);
19509 +               nxi = get_nx_info(__lookup_nx_info(id));
19510 +               spin_unlock(&nx_info_hash_lock);
19511 +       }
19512 +       return nxi;
19513 +}
19514 +
19515 +/*     nid_is_hashed()
19516 +
19517 +       * verify that nid is still hashed                       */
19518 +
19519 +int nid_is_hashed(vnid_t nid)
19520 +{
19521 +       int hashed;
19522 +
19523 +       spin_lock(&nx_info_hash_lock);
19524 +       hashed = (__lookup_nx_info(nid) != NULL);
19525 +       spin_unlock(&nx_info_hash_lock);
19526 +       return hashed;
19527 +}
19528 +
19529 +
19530 +#ifdef CONFIG_PROC_FS
19531 +
19532 +/*     get_nid_list()
19533 +
19534 +       * get a subset of hashed nids for proc
19535 +       * assumes size is at least one                          */
19536 +
19537 +int get_nid_list(int index, unsigned int *nids, int size)
19538 +{
19539 +       int hindex, nr_nids = 0;
19540 +
19541 +       /* only show current and children */
19542 +       if (!nx_check(0, VS_ADMIN | VS_WATCH)) {
19543 +               if (index > 0)
19544 +                       return 0;
19545 +               nids[nr_nids] = nx_current_nid();
19546 +               return 1;
19547 +       }
19548 +
19549 +       for (hindex = 0; hindex < NX_HASH_SIZE; hindex++) {
19550 +               struct hlist_head *head = &nx_info_hash[hindex];
19551 +               struct hlist_node *pos;
19552 +
19553 +               spin_lock(&nx_info_hash_lock);
19554 +               hlist_for_each(pos, head) {
19555 +                       struct nx_info *nxi;
19556 +
19557 +                       if (--index > 0)
19558 +                               continue;
19559 +
19560 +                       nxi = hlist_entry(pos, struct nx_info, nx_hlist);
19561 +                       nids[nr_nids] = nxi->nx_id;
19562 +                       if (++nr_nids >= size) {
19563 +                               spin_unlock(&nx_info_hash_lock);
19564 +                               goto out;
19565 +                       }
19566 +               }
19567 +               /* keep the lock time short */
19568 +               spin_unlock(&nx_info_hash_lock);
19569 +       }
19570 +out:
19571 +       return nr_nids;
19572 +}
19573 +#endif
19574 +
19575 +
19576 +/*
19577 + *     migrate task to new network
19578 + *     gets nxi, puts old_nxi on change
19579 + */
19580 +
19581 +int nx_migrate_task(struct task_struct *p, struct nx_info *nxi)
19582 +{
19583 +       struct nx_info *old_nxi;
19584 +       int ret = 0;
19585 +
19586 +       if (!p || !nxi)
19587 +               BUG();
19588 +
19589 +       vxdprintk(VXD_CBIT(nid, 5),
19590 +               "nx_migrate_task(%p,%p[#%d.%d.%d])",
19591 +               p, nxi, nxi->nx_id,
19592 +               atomic_read(&nxi->nx_usecnt),
19593 +               atomic_read(&nxi->nx_tasks));
19594 +
19595 +       if (nx_info_flags(nxi, NXF_INFO_PRIVATE, 0) &&
19596 +               !nx_info_flags(nxi, NXF_STATE_SETUP, 0))
19597 +               return -EACCES;
19598 +
19599 +       if (nx_info_state(nxi, NXS_SHUTDOWN))
19600 +               return -EFAULT;
19601 +
19602 +       /* maybe disallow this completely? */
19603 +       old_nxi = task_get_nx_info(p);
19604 +       if (old_nxi == nxi)
19605 +               goto out;
19606 +
19607 +       task_lock(p);
19608 +       if (old_nxi)
19609 +               clr_nx_info(&p->nx_info);
19610 +       claim_nx_info(nxi, p);
19611 +       set_nx_info(&p->nx_info, nxi);
19612 +       p->nid = nxi->nx_id;
19613 +       task_unlock(p);
19614 +
19615 +       vxdprintk(VXD_CBIT(nid, 5),
19616 +               "moved task %p into nxi:%p[#%d]",
19617 +               p, nxi, nxi->nx_id);
19618 +
19619 +       if (old_nxi)
19620 +               release_nx_info(old_nxi, p);
19621 +       ret = 0;
19622 +out:
19623 +       put_nx_info(old_nxi);
19624 +       return ret;
19625 +}
19626 +
19627 +
19628 +void nx_set_persistent(struct nx_info *nxi)
19629 +{
19630 +       vxdprintk(VXD_CBIT(nid, 6),
19631 +               "nx_set_persistent(%p[#%d])", nxi, nxi->nx_id);
19632 +
19633 +       get_nx_info(nxi);
19634 +       claim_nx_info(nxi, NULL);
19635 +}
19636 +
19637 +void nx_clear_persistent(struct nx_info *nxi)
19638 +{
19639 +       vxdprintk(VXD_CBIT(nid, 6),
19640 +               "nx_clear_persistent(%p[#%d])", nxi, nxi->nx_id);
19641 +
19642 +       release_nx_info(nxi, NULL);
19643 +       put_nx_info(nxi);
19644 +}
19645 +
19646 +void nx_update_persistent(struct nx_info *nxi)
19647 +{
19648 +       if (nx_info_flags(nxi, NXF_PERSISTENT, 0))
19649 +               nx_set_persistent(nxi);
19650 +       else
19651 +               nx_clear_persistent(nxi);
19652 +}
19653 +
19654 +/* vserver syscall commands below here */
19655 +
19656 +/* taks nid and nx_info functions */
19657 +
19658 +#include <asm/uaccess.h>
19659 +
19660 +
19661 +int vc_task_nid(uint32_t id)
19662 +{
19663 +       vnid_t nid;
19664 +
19665 +       if (id) {
19666 +               struct task_struct *tsk;
19667 +
19668 +               rcu_read_lock();
19669 +               tsk = find_task_by_real_pid(id);
19670 +               nid = (tsk) ? tsk->nid : -ESRCH;
19671 +               rcu_read_unlock();
19672 +       } else
19673 +               nid = nx_current_nid();
19674 +       return nid;
19675 +}
19676 +
19677 +
19678 +int vc_nx_info(struct nx_info *nxi, void __user *data)
19679 +{
19680 +       struct vcmd_nx_info_v0 vc_data;
19681 +
19682 +       vc_data.nid = nxi->nx_id;
19683 +
19684 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
19685 +               return -EFAULT;
19686 +       return 0;
19687 +}
19688 +
19689 +
19690 +/* network functions */
19691 +
19692 +int vc_net_create(uint32_t nid, void __user *data)
19693 +{
19694 +       struct vcmd_net_create vc_data = { .flagword = NXF_INIT_SET };
19695 +       struct nx_info *new_nxi;
19696 +       int ret;
19697 +
19698 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19699 +               return -EFAULT;
19700 +
19701 +       if ((nid > MAX_S_CONTEXT) || (nid < 2))
19702 +               return -EINVAL;
19703 +
19704 +       new_nxi = __create_nx_info(nid);
19705 +       if (IS_ERR(new_nxi))
19706 +               return PTR_ERR(new_nxi);
19707 +
19708 +       /* initial flags */
19709 +       new_nxi->nx_flags = vc_data.flagword;
19710 +
19711 +       ret = -ENOEXEC;
19712 +       if (vs_net_change(new_nxi, VSC_NETUP))
19713 +               goto out;
19714 +
19715 +       ret = nx_migrate_task(current, new_nxi);
19716 +       if (ret)
19717 +               goto out;
19718 +
19719 +       /* return context id on success */
19720 +       ret = new_nxi->nx_id;
19721 +
19722 +       /* get a reference for persistent contexts */
19723 +       if ((vc_data.flagword & NXF_PERSISTENT))
19724 +               nx_set_persistent(new_nxi);
19725 +out:
19726 +       release_nx_info(new_nxi, NULL);
19727 +       put_nx_info(new_nxi);
19728 +       return ret;
19729 +}
19730 +
19731 +
19732 +int vc_net_migrate(struct nx_info *nxi, void __user *data)
19733 +{
19734 +       return nx_migrate_task(current, nxi);
19735 +}
19736 +
19737 +
19738 +static inline
19739 +struct nx_addr_v4 *__find_v4_addr(struct nx_info *nxi,
19740 +       __be32 ip, __be32 ip2, __be32 mask, uint16_t type, uint16_t flags,
19741 +       struct nx_addr_v4 **prev)
19742 +{
19743 +       struct nx_addr_v4 *nxa = &nxi->v4;
19744 +
19745 +       for (; nxa; nxa = nxa->next) {
19746 +               if ((nxa->ip[0].s_addr == ip) &&
19747 +                   (nxa->ip[1].s_addr == ip2) &&
19748 +                   (nxa->mask.s_addr == mask) &&
19749 +                   (nxa->type == type) &&
19750 +                   (nxa->flags == flags))
19751 +                   return nxa;
19752 +
19753 +               /* save previous entry */
19754 +               if (prev)
19755 +                       *prev = nxa;
19756 +       }
19757 +       return NULL;
19758 +}
19759 +
19760 +int do_add_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
19761 +       uint16_t type, uint16_t flags)
19762 +{
19763 +       struct nx_addr_v4 *nxa = NULL;
19764 +       struct nx_addr_v4 *new = __alloc_nx_addr_v4();
19765 +       unsigned long irqflags;
19766 +       int ret = -EEXIST;
19767 +
19768 +       if (IS_ERR(new))
19769 +               return PTR_ERR(new);
19770 +
19771 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
19772 +       if (__find_v4_addr(nxi, ip, ip2, mask, type, flags, &nxa))
19773 +               goto out_unlock;
19774 +
19775 +       if (NX_IPV4(nxi)) {
19776 +               nxa->next = new;
19777 +               nxa = new;
19778 +               new = NULL;
19779 +
19780 +               /* remove single ip for ip list */
19781 +               nxi->nx_flags &= ~NXF_SINGLE_IP;
19782 +       }
19783 +
19784 +       nxa->ip[0].s_addr = ip;
19785 +       nxa->ip[1].s_addr = ip2;
19786 +       nxa->mask.s_addr = mask;
19787 +       nxa->type = type;
19788 +       nxa->flags = flags;
19789 +       ret = 0;
19790 +out_unlock:
19791 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
19792 +       if (new)
19793 +               __dealloc_nx_addr_v4(new);
19794 +       return ret;
19795 +}
19796 +
19797 +int do_remove_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
19798 +       uint16_t type, uint16_t flags)
19799 +{
19800 +       struct nx_addr_v4 *nxa = NULL;
19801 +       struct nx_addr_v4 *old = NULL;
19802 +       unsigned long irqflags;
19803 +       int ret = 0;
19804 +
19805 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
19806 +       switch (type) {
19807 +       case NXA_TYPE_ADDR:
19808 +               old = __find_v4_addr(nxi, ip, ip2, mask, type, flags, &nxa);
19809 +               if (old) {
19810 +                       if (nxa) {
19811 +                               nxa->next = old->next;
19812 +                               old->next = NULL;
19813 +                       } else {
19814 +                               if (old->next) {
19815 +                                       nxa = old;
19816 +                                       old = old->next;
19817 +                                       *nxa = *old;
19818 +                                       old->next = NULL;
19819 +                               } else {
19820 +                                       memset(old, 0, sizeof(*old));
19821 +                                       old = NULL;
19822 +                               }
19823 +                       }
19824 +               } else
19825 +                       ret = -ESRCH;
19826 +               break;
19827 +
19828 +       case NXA_TYPE_ANY:
19829 +               nxa = &nxi->v4;
19830 +               old = nxa->next;
19831 +               memset(nxa, 0, sizeof(*nxa));
19832 +               break;
19833 +
19834 +       default:
19835 +               ret = -EINVAL;
19836 +       }
19837 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
19838 +       __dealloc_nx_addr_v4_all(old);
19839 +       return ret;
19840 +}
19841 +
19842 +
19843 +int vc_net_add(struct nx_info *nxi, void __user *data)
19844 +{
19845 +       struct vcmd_net_addr_v0 vc_data;
19846 +       int index, ret = 0;
19847 +
19848 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19849 +               return -EFAULT;
19850 +
19851 +       switch (vc_data.type) {
19852 +       case NXA_TYPE_IPV4:
19853 +               if ((vc_data.count < 1) || (vc_data.count > 4))
19854 +                       return -EINVAL;
19855 +
19856 +               index = 0;
19857 +               while (index < vc_data.count) {
19858 +                       ret = do_add_v4_addr(nxi, vc_data.ip[index].s_addr, 0,
19859 +                               vc_data.mask[index].s_addr, NXA_TYPE_ADDR, 0);
19860 +                       if (ret)
19861 +                               return ret;
19862 +                       index++;
19863 +               }
19864 +               ret = index;
19865 +               break;
19866 +
19867 +       case NXA_TYPE_IPV4|NXA_MOD_BCAST:
19868 +               nxi->v4_bcast = vc_data.ip[0];
19869 +               ret = 1;
19870 +               break;
19871 +
19872 +       case NXA_TYPE_IPV4|NXA_MOD_LBACK:
19873 +               nxi->v4_lback = vc_data.ip[0];
19874 +               ret = 1;
19875 +               break;
19876 +
19877 +       default:
19878 +               ret = -EINVAL;
19879 +               break;
19880 +       }
19881 +       return ret;
19882 +}
19883 +
19884 +int vc_net_remove(struct nx_info *nxi, void __user *data)
19885 +{
19886 +       struct vcmd_net_addr_v0 vc_data;
19887 +
19888 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19889 +               return -EFAULT;
19890 +
19891 +       switch (vc_data.type) {
19892 +       case NXA_TYPE_ANY:
19893 +               return do_remove_v4_addr(nxi, 0, 0, 0, vc_data.type, 0);
19894 +       default:
19895 +               return -EINVAL;
19896 +       }
19897 +       return 0;
19898 +}
19899 +
19900 +
19901 +int vc_net_add_ipv4_v1(struct nx_info *nxi, void __user *data)
19902 +{
19903 +       struct vcmd_net_addr_ipv4_v1 vc_data;
19904 +
19905 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19906 +               return -EFAULT;
19907 +
19908 +       switch (vc_data.type) {
19909 +       case NXA_TYPE_ADDR:
19910 +       case NXA_TYPE_MASK:
19911 +               return do_add_v4_addr(nxi, vc_data.ip.s_addr, 0,
19912 +                       vc_data.mask.s_addr, vc_data.type, vc_data.flags);
19913 +
19914 +       case NXA_TYPE_ADDR | NXA_MOD_BCAST:
19915 +               nxi->v4_bcast = vc_data.ip;
19916 +               break;
19917 +
19918 +       case NXA_TYPE_ADDR | NXA_MOD_LBACK:
19919 +               nxi->v4_lback = vc_data.ip;
19920 +               break;
19921 +
19922 +       default:
19923 +               return -EINVAL;
19924 +       }
19925 +       return 0;
19926 +}
19927 +
19928 +int vc_net_add_ipv4(struct nx_info *nxi, void __user *data)
19929 +{
19930 +       struct vcmd_net_addr_ipv4_v2 vc_data;
19931 +
19932 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19933 +               return -EFAULT;
19934 +
19935 +       switch (vc_data.type) {
19936 +       case NXA_TYPE_ADDR:
19937 +       case NXA_TYPE_MASK:
19938 +       case NXA_TYPE_RANGE:
19939 +               return do_add_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr,
19940 +                       vc_data.mask.s_addr, vc_data.type, vc_data.flags);
19941 +
19942 +       case NXA_TYPE_ADDR | NXA_MOD_BCAST:
19943 +               nxi->v4_bcast = vc_data.ip;
19944 +               break;
19945 +
19946 +       case NXA_TYPE_ADDR | NXA_MOD_LBACK:
19947 +               nxi->v4_lback = vc_data.ip;
19948 +               break;
19949 +
19950 +       default:
19951 +               return -EINVAL;
19952 +       }
19953 +       return 0;
19954 +}
19955 +
19956 +int vc_net_rem_ipv4_v1(struct nx_info *nxi, void __user *data)
19957 +{
19958 +       struct vcmd_net_addr_ipv4_v1 vc_data;
19959 +
19960 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19961 +               return -EFAULT;
19962 +
19963 +       return do_remove_v4_addr(nxi, vc_data.ip.s_addr, 0,
19964 +               vc_data.mask.s_addr, vc_data.type, vc_data.flags);
19965 +}
19966 +
19967 +int vc_net_rem_ipv4(struct nx_info *nxi, void __user *data)
19968 +{
19969 +       struct vcmd_net_addr_ipv4_v2 vc_data;
19970 +
19971 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19972 +               return -EFAULT;
19973 +
19974 +       return do_remove_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr,
19975 +               vc_data.mask.s_addr, vc_data.type, vc_data.flags);
19976 +}
19977 +
19978 +#ifdef CONFIG_IPV6
19979 +
19980 +static inline
19981 +struct nx_addr_v6 *__find_v6_addr(struct nx_info *nxi,
19982 +       struct in6_addr *ip, struct in6_addr *mask,
19983 +       uint32_t prefix, uint16_t type, uint16_t flags,
19984 +       struct nx_addr_v6 **prev)
19985 +{
19986 +       struct nx_addr_v6 *nxa = &nxi->v6;
19987 +
19988 +       for (; nxa; nxa = nxa->next) {
19989 +               if (ipv6_addr_equal(&nxa->ip, ip) &&
19990 +                   ipv6_addr_equal(&nxa->mask, mask) &&
19991 +                   (nxa->prefix == prefix) &&
19992 +                   (nxa->type == type) &&
19993 +                   (nxa->flags == flags))
19994 +                   return nxa;
19995 +
19996 +               /* save previous entry */
19997 +               if (prev)
19998 +                       *prev = nxa;
19999 +       }
20000 +       return NULL;
20001 +}
20002 +
20003 +
20004 +int do_add_v6_addr(struct nx_info *nxi,
20005 +       struct in6_addr *ip, struct in6_addr *mask,
20006 +       uint32_t prefix, uint16_t type, uint16_t flags)
20007 +{
20008 +       struct nx_addr_v6 *nxa = NULL;
20009 +       struct nx_addr_v6 *new = __alloc_nx_addr_v6();
20010 +       unsigned long irqflags;
20011 +       int ret = -EEXIST;
20012 +
20013 +       if (IS_ERR(new))
20014 +               return PTR_ERR(new);
20015 +
20016 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
20017 +       if (__find_v6_addr(nxi, ip, mask, prefix, type, flags, &nxa))
20018 +               goto out_unlock;
20019 +
20020 +       if (NX_IPV6(nxi)) {
20021 +               nxa->next = new;
20022 +               nxa = new;
20023 +               new = NULL;
20024 +       }
20025 +
20026 +       nxa->ip = *ip;
20027 +       nxa->mask = *mask;
20028 +       nxa->prefix = prefix;
20029 +       nxa->type = type;
20030 +       nxa->flags = flags;
20031 +       ret = 0;
20032 +out_unlock:
20033 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
20034 +       if (new)
20035 +               __dealloc_nx_addr_v6(new);
20036 +       return ret;
20037 +}
20038 +
20039 +int do_remove_v6_addr(struct nx_info *nxi,
20040 +       struct in6_addr *ip, struct in6_addr *mask,
20041 +       uint32_t prefix, uint16_t type, uint16_t flags)
20042 +{
20043 +       struct nx_addr_v6 *nxa = NULL;
20044 +       struct nx_addr_v6 *old = NULL;
20045 +       unsigned long irqflags;
20046 +       int ret = 0;
20047 +
20048 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
20049 +       switch (type) {
20050 +       case NXA_TYPE_ADDR:
20051 +               old = __find_v6_addr(nxi, ip, mask, prefix, type, flags, &nxa);
20052 +               if (old) {
20053 +                       if (nxa) {
20054 +                               nxa->next = old->next;
20055 +                               old->next = NULL;
20056 +                       } else {
20057 +                               if (old->next) {
20058 +                                       nxa = old;
20059 +                                       old = old->next;
20060 +                                       *nxa = *old;
20061 +                                       old->next = NULL;
20062 +                               } else {
20063 +                                       memset(old, 0, sizeof(*old));
20064 +                                       old = NULL;
20065 +                               }
20066 +                       }
20067 +               } else
20068 +                       ret = -ESRCH;
20069 +               break;
20070 +
20071 +       case NXA_TYPE_ANY:
20072 +               nxa = &nxi->v6;
20073 +               old = nxa->next;
20074 +               memset(nxa, 0, sizeof(*nxa));
20075 +               break;
20076 +
20077 +       default:
20078 +               ret = -EINVAL;
20079 +       }
20080 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
20081 +       __dealloc_nx_addr_v6_all(old);
20082 +       return ret;
20083 +}
20084 +
20085 +int vc_net_add_ipv6(struct nx_info *nxi, void __user *data)
20086 +{
20087 +       struct vcmd_net_addr_ipv6_v1 vc_data;
20088 +
20089 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
20090 +               return -EFAULT;
20091 +
20092 +       switch (vc_data.type) {
20093 +       case NXA_TYPE_ADDR:
20094 +               memset(&vc_data.mask, ~0, sizeof(vc_data.mask));
20095 +               /* fallthrough */
20096 +       case NXA_TYPE_MASK:
20097 +               return do_add_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
20098 +                       vc_data.prefix, vc_data.type, vc_data.flags);
20099 +       default:
20100 +               return -EINVAL;
20101 +       }
20102 +       return 0;
20103 +}
20104 +
20105 +int vc_net_remove_ipv6(struct nx_info *nxi, void __user *data)
20106 +{
20107 +       struct vcmd_net_addr_ipv6_v1 vc_data;
20108 +
20109 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
20110 +               return -EFAULT;
20111 +
20112 +       switch (vc_data.type) {
20113 +       case NXA_TYPE_ADDR:
20114 +               memset(&vc_data.mask, ~0, sizeof(vc_data.mask));
20115 +               /* fallthrough */
20116 +       case NXA_TYPE_MASK:
20117 +               return do_remove_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
20118 +                       vc_data.prefix, vc_data.type, vc_data.flags);
20119 +       case NXA_TYPE_ANY:
20120 +               return do_remove_v6_addr(nxi, NULL, NULL, 0, vc_data.type, 0);
20121 +       default:
20122 +               return -EINVAL;
20123 +       }
20124 +       return 0;
20125 +}
20126 +
20127 +#endif /* CONFIG_IPV6 */
20128 +
20129 +
20130 +int vc_get_nflags(struct nx_info *nxi, void __user *data)
20131 +{
20132 +       struct vcmd_net_flags_v0 vc_data;
20133 +
20134 +       vc_data.flagword = nxi->nx_flags;
20135 +
20136 +       /* special STATE flag handling */
20137 +       vc_data.mask = vs_mask_flags(~0ULL, nxi->nx_flags, NXF_ONE_TIME);
20138 +
20139 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
20140 +               return -EFAULT;
20141 +       return 0;
20142 +}
20143 +
20144 +int vc_set_nflags(struct nx_info *nxi, void __user *data)
20145 +{
20146 +       struct vcmd_net_flags_v0 vc_data;
20147 +       uint64_t mask, trigger;
20148 +
20149 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
20150 +               return -EFAULT;
20151 +
20152 +       /* special STATE flag handling */
20153 +       mask = vs_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME);
20154 +       trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword);
20155 +
20156 +       nxi->nx_flags = vs_mask_flags(nxi->nx_flags,
20157 +               vc_data.flagword, mask);
20158 +       if (trigger & NXF_PERSISTENT)
20159 +               nx_update_persistent(nxi);
20160 +
20161 +       return 0;
20162 +}
20163 +
20164 +int vc_get_ncaps(struct nx_info *nxi, void __user *data)
20165 +{
20166 +       struct vcmd_net_caps_v0 vc_data;
20167 +
20168 +       vc_data.ncaps = nxi->nx_ncaps;
20169 +       vc_data.cmask = ~0ULL;
20170 +
20171 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
20172 +               return -EFAULT;
20173 +       return 0;
20174 +}
20175 +
20176 +int vc_set_ncaps(struct nx_info *nxi, void __user *data)
20177 +{
20178 +       struct vcmd_net_caps_v0 vc_data;
20179 +
20180 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
20181 +               return -EFAULT;
20182 +
20183 +       nxi->nx_ncaps = vs_mask_flags(nxi->nx_ncaps,
20184 +               vc_data.ncaps, vc_data.cmask);
20185 +       return 0;
20186 +}
20187 +
20188 +
20189 +#include <linux/module.h>
20190 +
20191 +module_init(init_network);
20192 +
20193 +EXPORT_SYMBOL_GPL(free_nx_info);
20194 +EXPORT_SYMBOL_GPL(unhash_nx_info);
20195 +
20196 diff -NurpP --minimal linux-3.18.5/kernel/vserver/proc.c linux-3.18.5-vs2.3.7.3/kernel/vserver/proc.c
20197 --- linux-3.18.5/kernel/vserver/proc.c  1970-01-01 00:00:00.000000000 +0000
20198 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/proc.c        2015-01-21 08:57:26.000000000 +0000
20199 @@ -0,0 +1,1100 @@
20200 +/*
20201 + *  linux/kernel/vserver/proc.c
20202 + *
20203 + *  Virtual Context Support
20204 + *
20205 + *  Copyright (C) 2003-2011  Herbert Pötzl
20206 + *
20207 + *  V0.01  basic structure
20208 + *  V0.02  adaptation vs1.3.0
20209 + *  V0.03  proc permissions
20210 + *  V0.04  locking/generic
20211 + *  V0.05  next generation procfs
20212 + *  V0.06  inode validation
20213 + *  V0.07  generic rewrite vid
20214 + *  V0.08  remove inode type
20215 + *  V0.09  added u/wmask info
20216 + *
20217 + */
20218 +
20219 +#include <linux/proc_fs.h>
20220 +#include <linux/fs_struct.h>
20221 +#include <linux/mount.h>
20222 +#include <linux/namei.h>
20223 +#include <asm/unistd.h>
20224 +
20225 +#include <linux/vs_context.h>
20226 +#include <linux/vs_network.h>
20227 +#include <linux/vs_cvirt.h>
20228 +
20229 +#include <linux/in.h>
20230 +#include <linux/inetdevice.h>
20231 +#include <linux/vs_inet.h>
20232 +#include <linux/vs_inet6.h>
20233 +
20234 +#include <linux/vserver/global.h>
20235 +
20236 +#include "cvirt_proc.h"
20237 +#include "cacct_proc.h"
20238 +#include "limit_proc.h"
20239 +#include "sched_proc.h"
20240 +#include "vci_config.h"
20241 +
20242 +#include <../../fs/proc/internal.h>
20243 +
20244 +
20245 +static inline char *print_cap_t(char *buffer, kernel_cap_t *c)
20246 +{
20247 +       unsigned __capi;
20248 +
20249 +       CAP_FOR_EACH_U32(__capi) {
20250 +               buffer += sprintf(buffer, "%08x",
20251 +                       c->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]);
20252 +       }
20253 +       return buffer;
20254 +}
20255 +
20256 +
20257 +static struct proc_dir_entry *proc_virtual;
20258 +
20259 +static struct proc_dir_entry *proc_virtnet;
20260 +
20261 +
20262 +/* first the actual feeds */
20263 +
20264 +
20265 +static int proc_vci(char *buffer)
20266 +{
20267 +       return sprintf(buffer,
20268 +               "VCIVersion:\t%04x:%04x\n"
20269 +               "VCISyscall:\t%d\n"
20270 +               "VCIKernel:\t%08x\n",
20271 +               VCI_VERSION >> 16,
20272 +               VCI_VERSION & 0xFFFF,
20273 +               __NR_vserver,
20274 +               vci_kernel_config());
20275 +}
20276 +
20277 +static int proc_virtual_info(char *buffer)
20278 +{
20279 +       return proc_vci(buffer);
20280 +}
20281 +
20282 +static int proc_virtual_status(char *buffer)
20283 +{
20284 +       return sprintf(buffer,
20285 +               "#CTotal:\t%d\n"
20286 +               "#CActive:\t%d\n"
20287 +               "#NSProxy:\t%d\t%d %d %d %d %d %d\n"
20288 +               "#InitTask:\t%d\t%d %d\n",
20289 +               atomic_read(&vx_global_ctotal),
20290 +               atomic_read(&vx_global_cactive),
20291 +               atomic_read(&vs_global_nsproxy),
20292 +               atomic_read(&vs_global_fs),
20293 +               atomic_read(&vs_global_mnt_ns),
20294 +               atomic_read(&vs_global_uts_ns),
20295 +               atomic_read(&nr_ipc_ns),
20296 +               atomic_read(&vs_global_user_ns),
20297 +               atomic_read(&vs_global_pid_ns),
20298 +               atomic_read(&init_task.usage),
20299 +               atomic_read(&init_task.nsproxy->count),
20300 +               init_task.fs->users);
20301 +}
20302 +
20303 +
20304 +int proc_vxi_info(struct vx_info *vxi, char *buffer)
20305 +{
20306 +       int length;
20307 +
20308 +       length = sprintf(buffer,
20309 +               "ID:\t%d\n"
20310 +               "Info:\t%p\n"
20311 +               "Init:\t%d\n"
20312 +               "OOM:\t%lld\n",
20313 +               vxi->vx_id,
20314 +               vxi,
20315 +               vxi->vx_initpid,
20316 +               vxi->vx_badness_bias);
20317 +       return length;
20318 +}
20319 +
20320 +int proc_vxi_status(struct vx_info *vxi, char *buffer)
20321 +{
20322 +       char *orig = buffer;
20323 +
20324 +       buffer += sprintf(buffer,
20325 +               "UseCnt:\t%d\n"
20326 +               "Tasks:\t%d\n"
20327 +               "Flags:\t%016llx\n",
20328 +               atomic_read(&vxi->vx_usecnt),
20329 +               atomic_read(&vxi->vx_tasks),
20330 +               (unsigned long long)vxi->vx_flags);
20331 +
20332 +       buffer += sprintf(buffer, "BCaps:\t");
20333 +       buffer = print_cap_t(buffer, &vxi->vx_bcaps);
20334 +       buffer += sprintf(buffer, "\n");
20335 +
20336 +       buffer += sprintf(buffer,
20337 +               "CCaps:\t%016llx\n"
20338 +               "Umask:\t%16llx\n"
20339 +               "Wmask:\t%16llx\n"
20340 +               "Spaces:\t%08lx %08lx\n",
20341 +               (unsigned long long)vxi->vx_ccaps,
20342 +               (unsigned long long)vxi->vx_umask,
20343 +               (unsigned long long)vxi->vx_wmask,
20344 +               vxi->space[0].vx_nsmask, vxi->space[1].vx_nsmask);
20345 +       return buffer - orig;
20346 +}
20347 +
20348 +int proc_vxi_limit(struct vx_info *vxi, char *buffer)
20349 +{
20350 +       return vx_info_proc_limit(&vxi->limit, buffer);
20351 +}
20352 +
20353 +int proc_vxi_sched(struct vx_info *vxi, char *buffer)
20354 +{
20355 +       int cpu, length;
20356 +
20357 +       length = vx_info_proc_sched(&vxi->sched, buffer);
20358 +       for_each_online_cpu(cpu) {
20359 +               length += vx_info_proc_sched_pc(
20360 +                       &vx_per_cpu(vxi, sched_pc, cpu),
20361 +                       buffer + length, cpu);
20362 +       }
20363 +       return length;
20364 +}
20365 +
20366 +int proc_vxi_nsproxy0(struct vx_info *vxi, char *buffer)
20367 +{
20368 +       return vx_info_proc_nsproxy(vxi->space[0].vx_nsproxy, buffer);
20369 +}
20370 +
20371 +int proc_vxi_nsproxy1(struct vx_info *vxi, char *buffer)
20372 +{
20373 +       return vx_info_proc_nsproxy(vxi->space[1].vx_nsproxy, buffer);
20374 +}
20375 +
20376 +int proc_vxi_cvirt(struct vx_info *vxi, char *buffer)
20377 +{
20378 +       int cpu, length;
20379 +
20380 +       vx_update_load(vxi);
20381 +       length = vx_info_proc_cvirt(&vxi->cvirt, buffer);
20382 +       for_each_online_cpu(cpu) {
20383 +               length += vx_info_proc_cvirt_pc(
20384 +                       &vx_per_cpu(vxi, cvirt_pc, cpu),
20385 +                       buffer + length, cpu);
20386 +       }
20387 +       return length;
20388 +}
20389 +
20390 +int proc_vxi_cacct(struct vx_info *vxi, char *buffer)
20391 +{
20392 +       return vx_info_proc_cacct(&vxi->cacct, buffer);
20393 +}
20394 +
20395 +
20396 +static int proc_virtnet_info(char *buffer)
20397 +{
20398 +       return proc_vci(buffer);
20399 +}
20400 +
20401 +static int proc_virtnet_status(char *buffer)
20402 +{
20403 +       return sprintf(buffer,
20404 +               "#CTotal:\t%d\n"
20405 +               "#CActive:\t%d\n",
20406 +               atomic_read(&nx_global_ctotal),
20407 +               atomic_read(&nx_global_cactive));
20408 +}
20409 +
20410 +int proc_nxi_info(struct nx_info *nxi, char *buffer)
20411 +{
20412 +       struct nx_addr_v4 *v4a;
20413 +#ifdef CONFIG_IPV6
20414 +       struct nx_addr_v6 *v6a;
20415 +#endif
20416 +       int length, i;
20417 +
20418 +       length = sprintf(buffer,
20419 +               "ID:\t%d\n"
20420 +               "Info:\t%p\n"
20421 +               "Bcast:\t" NIPQUAD_FMT "\n"
20422 +               "Lback:\t" NIPQUAD_FMT "\n",
20423 +               nxi->nx_id,
20424 +               nxi,
20425 +               NIPQUAD(nxi->v4_bcast.s_addr),
20426 +               NIPQUAD(nxi->v4_lback.s_addr));
20427 +
20428 +       if (!NX_IPV4(nxi))
20429 +               goto skip_v4;
20430 +       for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
20431 +               length += sprintf(buffer + length, "%d:\t" NXAV4_FMT "\n",
20432 +                       i, NXAV4(v4a));
20433 +skip_v4:
20434 +#ifdef CONFIG_IPV6
20435 +       if (!NX_IPV6(nxi))
20436 +               goto skip_v6;
20437 +       for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
20438 +               length += sprintf(buffer + length, "%d:\t" NXAV6_FMT "\n",
20439 +                       i, NXAV6(v6a));
20440 +skip_v6:
20441 +#endif
20442 +       return length;
20443 +}
20444 +
20445 +int proc_nxi_status(struct nx_info *nxi, char *buffer)
20446 +{
20447 +       int length;
20448 +
20449 +       length = sprintf(buffer,
20450 +               "UseCnt:\t%d\n"
20451 +               "Tasks:\t%d\n"
20452 +               "Flags:\t%016llx\n"
20453 +               "NCaps:\t%016llx\n",
20454 +               atomic_read(&nxi->nx_usecnt),
20455 +               atomic_read(&nxi->nx_tasks),
20456 +               (unsigned long long)nxi->nx_flags,
20457 +               (unsigned long long)nxi->nx_ncaps);
20458 +       return length;
20459 +}
20460 +
20461 +
20462 +
20463 +/* here the inode helpers */
20464 +
20465 +struct vs_entry {
20466 +       int len;
20467 +       char *name;
20468 +       mode_t mode;
20469 +       struct inode_operations *iop;
20470 +       struct file_operations *fop;
20471 +       union proc_op op;
20472 +};
20473 +
20474 +static struct inode *vs_proc_make_inode(struct super_block *sb, struct vs_entry *p)
20475 +{
20476 +       struct inode *inode = new_inode(sb);
20477 +
20478 +       if (!inode)
20479 +               goto out;
20480 +
20481 +       inode->i_mode = p->mode;
20482 +       if (p->iop)
20483 +               inode->i_op = p->iop;
20484 +       if (p->fop)
20485 +               inode->i_fop = p->fop;
20486 +
20487 +       set_nlink(inode, (p->mode & S_IFDIR) ? 2 : 1);
20488 +       inode->i_flags |= S_IMMUTABLE;
20489 +
20490 +       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
20491 +
20492 +       i_uid_write(inode, 0);
20493 +       i_gid_write(inode, 0);
20494 +       i_tag_write(inode, 0);
20495 +out:
20496 +       return inode;
20497 +}
20498 +
20499 +static struct dentry *vs_proc_instantiate(struct inode *dir,
20500 +       struct dentry *dentry, int id, void *ptr)
20501 +{
20502 +       struct vs_entry *p = ptr;
20503 +       struct inode *inode = vs_proc_make_inode(dir->i_sb, p);
20504 +       struct dentry *error = ERR_PTR(-EINVAL);
20505 +
20506 +       if (!inode)
20507 +               goto out;
20508 +
20509 +       PROC_I(inode)->op = p->op;
20510 +       PROC_I(inode)->fd = id;
20511 +       d_add(dentry, inode);
20512 +       error = NULL;
20513 +out:
20514 +       return error;
20515 +}
20516 +
20517 +/* Lookups */
20518 +
20519 +typedef struct dentry *vx_instantiate_t(struct inode *, struct dentry *, int, void *);
20520 +
20521 +
20522 +/*
20523 + * Fill a directory entry.
20524 + *
20525 + * If possible create the dcache entry and derive our inode number and
20526 + * file type from dcache entry.
20527 + *
20528 + * Since all of the proc inode numbers are dynamically generated, the inode
20529 + * numbers do not exist until the inode is cache.  This means creating the
20530 + * the dcache entry in iterate is necessary to keep the inode numbers
20531 + * reported by iterate in sync with the inode numbers reported
20532 + * by stat.
20533 + */
20534 +static int vx_proc_fill_cache(struct file *filp, struct dir_context *ctx,
20535 +       char *name, int len, vx_instantiate_t instantiate, int id, void *ptr)
20536 +{
20537 +       struct dentry *child, *dir = filp->f_dentry;
20538 +       struct inode *inode;
20539 +       struct qstr qname;
20540 +       ino_t ino = 0;
20541 +       unsigned type = DT_UNKNOWN;
20542 +
20543 +       qname.name = name;
20544 +       qname.len  = len;
20545 +       qname.hash = full_name_hash(name, len);
20546 +
20547 +       child = d_lookup(dir, &qname);
20548 +       if (!child) {
20549 +               struct dentry *new;
20550 +               new = d_alloc(dir, &qname);
20551 +               if (new) {
20552 +                       child = instantiate(dir->d_inode, new, id, ptr);
20553 +                       if (child)
20554 +                               dput(new);
20555 +                       else
20556 +                               child = new;
20557 +               }
20558 +       }
20559 +       if (!child || IS_ERR(child) || !child->d_inode)
20560 +               goto end_instantiate;
20561 +       inode = child->d_inode;
20562 +       if (inode) {
20563 +               ino = inode->i_ino;
20564 +               type = inode->i_mode >> 12;
20565 +       }
20566 +       dput(child);
20567 +end_instantiate:
20568 +       if (!ino)
20569 +               ino = 1;
20570 +       return !dir_emit(ctx, name, len, ino, type);
20571 +}
20572 +
20573 +
20574 +
20575 +/* get and revalidate vx_info/xid */
20576 +
20577 +static inline
20578 +struct vx_info *get_proc_vx_info(struct inode *inode)
20579 +{
20580 +       return lookup_vx_info(PROC_I(inode)->fd);
20581 +}
20582 +
20583 +static int proc_xid_revalidate(struct dentry *dentry, unsigned int flags)
20584 +{
20585 +       struct inode *inode = dentry->d_inode;
20586 +       vxid_t xid = PROC_I(inode)->fd;
20587 +
20588 +       if (flags & LOOKUP_RCU) /* FIXME: can be dropped? */
20589 +               return -ECHILD;
20590 +
20591 +       if (!xid || xid_is_hashed(xid))
20592 +               return 1;
20593 +       d_drop(dentry);
20594 +       return 0;
20595 +}
20596 +
20597 +
20598 +/* get and revalidate nx_info/nid */
20599 +
20600 +static int proc_nid_revalidate(struct dentry *dentry, unsigned int flags)
20601 +{
20602 +       struct inode *inode = dentry->d_inode;
20603 +       vnid_t nid = PROC_I(inode)->fd;
20604 +
20605 +       if (flags & LOOKUP_RCU) /* FIXME: can be dropped? */
20606 +               return -ECHILD;
20607 +
20608 +       if (!nid || nid_is_hashed(nid))
20609 +               return 1;
20610 +       d_drop(dentry);
20611 +       return 0;
20612 +}
20613 +
20614 +
20615 +
20616 +#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
20617 +
20618 +static ssize_t proc_vs_info_read(struct file *file, char __user *buf,
20619 +                         size_t count, loff_t *ppos)
20620 +{
20621 +       struct inode *inode = file->f_dentry->d_inode;
20622 +       unsigned long page;
20623 +       ssize_t length = 0;
20624 +
20625 +       if (count > PROC_BLOCK_SIZE)
20626 +               count = PROC_BLOCK_SIZE;
20627 +
20628 +       /* fade that out as soon as stable */
20629 +       WARN_ON(PROC_I(inode)->fd);
20630 +
20631 +       if (!(page = __get_free_page(GFP_KERNEL)))
20632 +               return -ENOMEM;
20633 +
20634 +       BUG_ON(!PROC_I(inode)->op.proc_vs_read);
20635 +       length = PROC_I(inode)->op.proc_vs_read((char *)page);
20636 +
20637 +       if (length >= 0)
20638 +               length = simple_read_from_buffer(buf, count, ppos,
20639 +                       (char *)page, length);
20640 +
20641 +       free_page(page);
20642 +       return length;
20643 +}
20644 +
20645 +static ssize_t proc_vx_info_read(struct file *file, char __user *buf,
20646 +                         size_t count, loff_t *ppos)
20647 +{
20648 +       struct inode *inode = file->f_dentry->d_inode;
20649 +       struct vx_info *vxi = NULL;
20650 +       vxid_t xid = PROC_I(inode)->fd;
20651 +       unsigned long page;
20652 +       ssize_t length = 0;
20653 +
20654 +       if (count > PROC_BLOCK_SIZE)
20655 +               count = PROC_BLOCK_SIZE;
20656 +
20657 +       /* fade that out as soon as stable */
20658 +       WARN_ON(!xid);
20659 +       vxi = lookup_vx_info(xid);
20660 +       if (!vxi)
20661 +               goto out;
20662 +
20663 +       length = -ENOMEM;
20664 +       if (!(page = __get_free_page(GFP_KERNEL)))
20665 +               goto out_put;
20666 +
20667 +       BUG_ON(!PROC_I(inode)->op.proc_vxi_read);
20668 +       length = PROC_I(inode)->op.proc_vxi_read(vxi, (char *)page);
20669 +
20670 +       if (length >= 0)
20671 +               length = simple_read_from_buffer(buf, count, ppos,
20672 +                       (char *)page, length);
20673 +
20674 +       free_page(page);
20675 +out_put:
20676 +       put_vx_info(vxi);
20677 +out:
20678 +       return length;
20679 +}
20680 +
20681 +static ssize_t proc_nx_info_read(struct file *file, char __user *buf,
20682 +                         size_t count, loff_t *ppos)
20683 +{
20684 +       struct inode *inode = file->f_dentry->d_inode;
20685 +       struct nx_info *nxi = NULL;
20686 +       vnid_t nid = PROC_I(inode)->fd;
20687 +       unsigned long page;
20688 +       ssize_t length = 0;
20689 +
20690 +       if (count > PROC_BLOCK_SIZE)
20691 +               count = PROC_BLOCK_SIZE;
20692 +
20693 +       /* fade that out as soon as stable */
20694 +       WARN_ON(!nid);
20695 +       nxi = lookup_nx_info(nid);
20696 +       if (!nxi)
20697 +               goto out;
20698 +
20699 +       length = -ENOMEM;
20700 +       if (!(page = __get_free_page(GFP_KERNEL)))
20701 +               goto out_put;
20702 +
20703 +       BUG_ON(!PROC_I(inode)->op.proc_nxi_read);
20704 +       length = PROC_I(inode)->op.proc_nxi_read(nxi, (char *)page);
20705 +
20706 +       if (length >= 0)
20707 +               length = simple_read_from_buffer(buf, count, ppos,
20708 +                       (char *)page, length);
20709 +
20710 +       free_page(page);
20711 +out_put:
20712 +       put_nx_info(nxi);
20713 +out:
20714 +       return length;
20715 +}
20716 +
20717 +
20718 +
20719 +/* here comes the lower level */
20720 +
20721 +
20722 +#define NOD(NAME, MODE, IOP, FOP, OP) {        \
20723 +       .len  = sizeof(NAME) - 1,       \
20724 +       .name = (NAME),                 \
20725 +       .mode = MODE,                   \
20726 +       .iop  = IOP,                    \
20727 +       .fop  = FOP,                    \
20728 +       .op   = OP,                     \
20729 +}
20730 +
20731 +
20732 +#define DIR(NAME, MODE, OTYPE)                         \
20733 +       NOD(NAME, (S_IFDIR | (MODE)),                   \
20734 +               &proc_ ## OTYPE ## _inode_operations,   \
20735 +               &proc_ ## OTYPE ## _file_operations, { } )
20736 +
20737 +#define INF(NAME, MODE, OTYPE)                         \
20738 +       NOD(NAME, (S_IFREG | (MODE)), NULL,             \
20739 +               &proc_vs_info_file_operations,          \
20740 +               { .proc_vs_read = &proc_##OTYPE } )
20741 +
20742 +#define VINF(NAME, MODE, OTYPE)                                \
20743 +       NOD(NAME, (S_IFREG | (MODE)), NULL,             \
20744 +               &proc_vx_info_file_operations,          \
20745 +               { .proc_vxi_read = &proc_##OTYPE } )
20746 +
20747 +#define NINF(NAME, MODE, OTYPE)                                \
20748 +       NOD(NAME, (S_IFREG | (MODE)), NULL,             \
20749 +               &proc_nx_info_file_operations,          \
20750 +               { .proc_nxi_read = &proc_##OTYPE } )
20751 +
20752 +
20753 +static struct file_operations proc_vs_info_file_operations = {
20754 +       .read =         proc_vs_info_read,
20755 +};
20756 +
20757 +static struct file_operations proc_vx_info_file_operations = {
20758 +       .read =         proc_vx_info_read,
20759 +};
20760 +
20761 +static struct dentry_operations proc_xid_dentry_operations = {
20762 +       .d_revalidate = proc_xid_revalidate,
20763 +};
20764 +
20765 +static struct vs_entry vx_base_stuff[] = {
20766 +       VINF("info",    S_IRUGO, vxi_info),
20767 +       VINF("status",  S_IRUGO, vxi_status),
20768 +       VINF("limit",   S_IRUGO, vxi_limit),
20769 +       VINF("sched",   S_IRUGO, vxi_sched),
20770 +       VINF("nsproxy", S_IRUGO, vxi_nsproxy0),
20771 +       VINF("nsproxy1",S_IRUGO, vxi_nsproxy1),
20772 +       VINF("cvirt",   S_IRUGO, vxi_cvirt),
20773 +       VINF("cacct",   S_IRUGO, vxi_cacct),
20774 +       {}
20775 +};
20776 +
20777 +
20778 +
20779 +
20780 +static struct dentry *proc_xid_instantiate(struct inode *dir,
20781 +       struct dentry *dentry, int id, void *ptr)
20782 +{
20783 +       dentry->d_op = &proc_xid_dentry_operations;
20784 +       return vs_proc_instantiate(dir, dentry, id, ptr);
20785 +}
20786 +
20787 +static struct dentry *proc_xid_lookup(struct inode *dir,
20788 +       struct dentry *dentry, unsigned int flags)
20789 +{
20790 +       struct vs_entry *p = vx_base_stuff;
20791 +       struct dentry *error = ERR_PTR(-ENOENT);
20792 +
20793 +       for (; p->name; p++) {
20794 +               if (p->len != dentry->d_name.len)
20795 +                       continue;
20796 +               if (!memcmp(dentry->d_name.name, p->name, p->len))
20797 +                       break;
20798 +       }
20799 +       if (!p->name)
20800 +               goto out;
20801 +
20802 +       error = proc_xid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
20803 +out:
20804 +       return error;
20805 +}
20806 +
20807 +static int proc_xid_iterate(struct file *filp, struct dir_context *ctx)
20808 +{
20809 +       struct dentry *dentry = filp->f_dentry;
20810 +       struct inode *inode = dentry->d_inode;
20811 +       struct vs_entry *p = vx_base_stuff;
20812 +       int size = sizeof(vx_base_stuff) / sizeof(struct vs_entry);
20813 +       int index;
20814 +       u64 ino;
20815 +
20816 +       switch (ctx->pos) {
20817 +       case 0:
20818 +               ino = inode->i_ino;
20819 +               if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
20820 +                       goto out;
20821 +               ctx->pos++;
20822 +               /* fall through */
20823 +       case 1:
20824 +               ino = parent_ino(dentry);
20825 +               if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
20826 +                       goto out;
20827 +               ctx->pos++;
20828 +               /* fall through */
20829 +       default:
20830 +               index = ctx->pos - 2;
20831 +               if (index >= size)
20832 +                       goto out;
20833 +               for (p += index; p->name; p++) {
20834 +                       if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
20835 +                               vs_proc_instantiate, PROC_I(inode)->fd, p))
20836 +                               goto out;
20837 +                       ctx->pos++;
20838 +               }
20839 +       }
20840 +out:
20841 +       return 1;
20842 +}
20843 +
20844 +
20845 +
20846 +static struct file_operations proc_nx_info_file_operations = {
20847 +       .read =         proc_nx_info_read,
20848 +};
20849 +
20850 +static struct dentry_operations proc_nid_dentry_operations = {
20851 +       .d_revalidate = proc_nid_revalidate,
20852 +};
20853 +
20854 +static struct vs_entry nx_base_stuff[] = {
20855 +       NINF("info",    S_IRUGO, nxi_info),
20856 +       NINF("status",  S_IRUGO, nxi_status),
20857 +       {}
20858 +};
20859 +
20860 +
20861 +static struct dentry *proc_nid_instantiate(struct inode *dir,
20862 +       struct dentry *dentry, int id, void *ptr)
20863 +{
20864 +       dentry->d_op = &proc_nid_dentry_operations;
20865 +       return vs_proc_instantiate(dir, dentry, id, ptr);
20866 +}
20867 +
20868 +static struct dentry *proc_nid_lookup(struct inode *dir,
20869 +       struct dentry *dentry, unsigned int flags)
20870 +{
20871 +       struct vs_entry *p = nx_base_stuff;
20872 +       struct dentry *error = ERR_PTR(-ENOENT);
20873 +
20874 +       for (; p->name; p++) {
20875 +               if (p->len != dentry->d_name.len)
20876 +                       continue;
20877 +               if (!memcmp(dentry->d_name.name, p->name, p->len))
20878 +                       break;
20879 +       }
20880 +       if (!p->name)
20881 +               goto out;
20882 +
20883 +       error = proc_nid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
20884 +out:
20885 +       return error;
20886 +}
20887 +
20888 +static int proc_nid_iterate(struct file *filp, struct dir_context *ctx)
20889 +{
20890 +       struct dentry *dentry = filp->f_dentry;
20891 +       struct inode *inode = dentry->d_inode;
20892 +       struct vs_entry *p = nx_base_stuff;
20893 +       int size = sizeof(nx_base_stuff) / sizeof(struct vs_entry);
20894 +       int index;
20895 +       u64 ino;
20896 +
20897 +       switch (ctx->pos) {
20898 +       case 0:
20899 +               ino = inode->i_ino;
20900 +               if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
20901 +                       goto out;
20902 +               ctx->pos++;
20903 +               /* fall through */
20904 +       case 1:
20905 +               ino = parent_ino(dentry);
20906 +               if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
20907 +                       goto out;
20908 +               ctx->pos++;
20909 +               /* fall through */
20910 +       default:
20911 +               index = ctx->pos - 2;
20912 +               if (index >= size)
20913 +                       goto out;
20914 +               for (p += index; p->name; p++) {
20915 +                       if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
20916 +                               vs_proc_instantiate, PROC_I(inode)->fd, p))
20917 +                               goto out;
20918 +                       ctx->pos++;
20919 +               }
20920 +       }
20921 +out:
20922 +       return 1;
20923 +}
20924 +
20925 +
20926 +#define MAX_MULBY10    ((~0U - 9) / 10)
20927 +
20928 +static inline int atovid(const char *str, int len)
20929 +{
20930 +       int vid, c;
20931 +
20932 +       vid = 0;
20933 +       while (len-- > 0) {
20934 +               c = *str - '0';
20935 +               str++;
20936 +               if (c > 9)
20937 +                       return -1;
20938 +               if (vid >= MAX_MULBY10)
20939 +                       return -1;
20940 +               vid *= 10;
20941 +               vid += c;
20942 +               if (!vid)
20943 +                       return -1;
20944 +       }
20945 +       return vid;
20946 +}
20947 +
20948 +/* now the upper level (virtual) */
20949 +
20950 +
20951 +static struct file_operations proc_xid_file_operations = {
20952 +       .read =         generic_read_dir,
20953 +       .iterate =      proc_xid_iterate,
20954 +};
20955 +
20956 +static struct inode_operations proc_xid_inode_operations = {
20957 +       .lookup =       proc_xid_lookup,
20958 +};
20959 +
20960 +static struct vs_entry vx_virtual_stuff[] = {
20961 +       INF("info",     S_IRUGO, virtual_info),
20962 +       INF("status",   S_IRUGO, virtual_status),
20963 +       DIR(NULL,       S_IRUGO | S_IXUGO, xid),
20964 +};
20965 +
20966 +
20967 +static struct dentry *proc_virtual_lookup(struct inode *dir,
20968 +       struct dentry *dentry, unsigned int flags)
20969 +{
20970 +       struct vs_entry *p = vx_virtual_stuff;
20971 +       struct dentry *error = ERR_PTR(-ENOENT);
20972 +       int id = 0;
20973 +
20974 +       for (; p->name; p++) {
20975 +               if (p->len != dentry->d_name.len)
20976 +                       continue;
20977 +               if (!memcmp(dentry->d_name.name, p->name, p->len))
20978 +                       break;
20979 +       }
20980 +       if (p->name)
20981 +               goto instantiate;
20982 +
20983 +       id = atovid(dentry->d_name.name, dentry->d_name.len);
20984 +       if ((id < 0) || !xid_is_hashed(id))
20985 +               goto out;
20986 +
20987 +instantiate:
20988 +       error = proc_xid_instantiate(dir, dentry, id, p);
20989 +out:
20990 +       return error;
20991 +}
20992 +
20993 +static struct file_operations proc_nid_file_operations = {
20994 +       .read =         generic_read_dir,
20995 +       .iterate =      proc_nid_iterate,
20996 +};
20997 +
20998 +static struct inode_operations proc_nid_inode_operations = {
20999 +       .lookup =       proc_nid_lookup,
21000 +};
21001 +
21002 +static struct vs_entry nx_virtnet_stuff[] = {
21003 +       INF("info",     S_IRUGO, virtnet_info),
21004 +       INF("status",   S_IRUGO, virtnet_status),
21005 +       DIR(NULL,       S_IRUGO | S_IXUGO, nid),
21006 +};
21007 +
21008 +
21009 +static struct dentry *proc_virtnet_lookup(struct inode *dir,
21010 +       struct dentry *dentry, unsigned int flags)
21011 +{
21012 +       struct vs_entry *p = nx_virtnet_stuff;
21013 +       struct dentry *error = ERR_PTR(-ENOENT);
21014 +       int id = 0;
21015 +
21016 +       for (; p->name; p++) {
21017 +               if (p->len != dentry->d_name.len)
21018 +                       continue;
21019 +               if (!memcmp(dentry->d_name.name, p->name, p->len))
21020 +                       break;
21021 +       }
21022 +       if (p->name)
21023 +               goto instantiate;
21024 +
21025 +       id = atovid(dentry->d_name.name, dentry->d_name.len);
21026 +       if ((id < 0) || !nid_is_hashed(id))
21027 +               goto out;
21028 +
21029 +instantiate:
21030 +       error = proc_nid_instantiate(dir, dentry, id, p);
21031 +out:
21032 +       return error;
21033 +}
21034 +
21035 +
21036 +#define PROC_MAXVIDS 32
21037 +
21038 +int proc_virtual_iterate(struct file *filp, struct dir_context *ctx)
21039 +{
21040 +       struct dentry *dentry = filp->f_dentry;
21041 +       struct inode *inode = dentry->d_inode;
21042 +       struct vs_entry *p = vx_virtual_stuff;
21043 +       int size = sizeof(vx_virtual_stuff) / sizeof(struct vs_entry);
21044 +       int index;
21045 +       unsigned int xid_array[PROC_MAXVIDS];
21046 +       char buf[PROC_NUMBUF];
21047 +       unsigned int nr_xids, i;
21048 +       u64 ino;
21049 +
21050 +       switch (ctx->pos) {
21051 +       case 0:
21052 +               ino = inode->i_ino;
21053 +               if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
21054 +                       goto out;
21055 +               ctx->pos++;
21056 +               /* fall through */
21057 +       case 1:
21058 +               ino = parent_ino(dentry);
21059 +               if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
21060 +                       goto out;
21061 +               ctx->pos++;
21062 +               /* fall through */
21063 +       default:
21064 +               index = ctx->pos - 2;
21065 +               if (index >= size)
21066 +                       goto entries;
21067 +               for (p += index; p->name; p++) {
21068 +                       if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
21069 +                               vs_proc_instantiate, 0, p))
21070 +                               goto out;
21071 +                       ctx->pos++;
21072 +               }
21073 +       entries:
21074 +               index = ctx->pos - size;
21075 +               p = &vx_virtual_stuff[size - 1];
21076 +               nr_xids = get_xid_list(index, xid_array, PROC_MAXVIDS);
21077 +               for (i = 0; i < nr_xids; i++) {
21078 +                       int n, xid = xid_array[i];
21079 +                       unsigned int j = PROC_NUMBUF;
21080 +
21081 +                       n = xid;
21082 +                       do
21083 +                               buf[--j] = '0' + (n % 10);
21084 +                       while (n /= 10);
21085 +
21086 +                       if (vx_proc_fill_cache(filp, ctx,
21087 +                               buf + j, PROC_NUMBUF - j,
21088 +                               vs_proc_instantiate, xid, p))
21089 +                               goto out;
21090 +                       ctx->pos++;
21091 +               }
21092 +       }
21093 +out:
21094 +       return 0;
21095 +}
21096 +
21097 +static int proc_virtual_getattr(struct vfsmount *mnt,
21098 +       struct dentry *dentry, struct kstat *stat)
21099 +{
21100 +       struct inode *inode = dentry->d_inode;
21101 +
21102 +       generic_fillattr(inode, stat);
21103 +       stat->nlink = 2 + atomic_read(&vx_global_cactive);
21104 +       return 0;
21105 +}
21106 +
21107 +static struct file_operations proc_virtual_dir_operations = {
21108 +       .read =         generic_read_dir,
21109 +       .iterate =      proc_virtual_iterate,
21110 +};
21111 +
21112 +static struct inode_operations proc_virtual_dir_inode_operations = {
21113 +       .getattr =      proc_virtual_getattr,
21114 +       .lookup =       proc_virtual_lookup,
21115 +};
21116 +
21117 +
21118 +
21119 +int proc_virtnet_iterate(struct file *filp, struct dir_context *ctx)
21120 +{
21121 +       struct dentry *dentry = filp->f_dentry;
21122 +       struct inode *inode = dentry->d_inode;
21123 +       struct vs_entry *p = nx_virtnet_stuff;
21124 +       int size = sizeof(nx_virtnet_stuff) / sizeof(struct vs_entry);
21125 +       int index;
21126 +       unsigned int nid_array[PROC_MAXVIDS];
21127 +       char buf[PROC_NUMBUF];
21128 +       unsigned int nr_nids, i;
21129 +       u64 ino;
21130 +
21131 +       switch (ctx->pos) {
21132 +       case 0:
21133 +               ino = inode->i_ino;
21134 +               if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
21135 +                       goto out;
21136 +               ctx->pos++;
21137 +               /* fall through */
21138 +       case 1:
21139 +               ino = parent_ino(dentry);
21140 +               if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
21141 +                       goto out;
21142 +               ctx->pos++;
21143 +               /* fall through */
21144 +       default:
21145 +               index = ctx->pos - 2;
21146 +               if (index >= size)
21147 +                       goto entries;
21148 +               for (p += index; p->name; p++) {
21149 +                       if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
21150 +                               vs_proc_instantiate, 0, p))
21151 +                               goto out;
21152 +                       ctx->pos++;
21153 +               }
21154 +       entries:
21155 +               index = ctx->pos - size;
21156 +               p = &nx_virtnet_stuff[size - 1];
21157 +               nr_nids = get_nid_list(index, nid_array, PROC_MAXVIDS);
21158 +               for (i = 0; i < nr_nids; i++) {
21159 +                       int n, nid = nid_array[i];
21160 +                       unsigned int j = PROC_NUMBUF;
21161 +
21162 +                       n = nid;
21163 +                       do
21164 +                               buf[--j] = '0' + (n % 10);
21165 +                       while (n /= 10);
21166 +
21167 +                       if (vx_proc_fill_cache(filp, ctx,
21168 +                               buf + j, PROC_NUMBUF - j,
21169 +                               vs_proc_instantiate, nid, p))
21170 +                               goto out;
21171 +                       ctx->pos++;
21172 +               }
21173 +       }
21174 +out:
21175 +       return 0;
21176 +}
21177 +
21178 +static int proc_virtnet_getattr(struct vfsmount *mnt,
21179 +       struct dentry *dentry, struct kstat *stat)
21180 +{
21181 +       struct inode *inode = dentry->d_inode;
21182 +
21183 +       generic_fillattr(inode, stat);
21184 +       stat->nlink = 2 + atomic_read(&nx_global_cactive);
21185 +       return 0;
21186 +}
21187 +
21188 +static struct file_operations proc_virtnet_dir_operations = {
21189 +       .read =         generic_read_dir,
21190 +       .iterate =      proc_virtnet_iterate,
21191 +};
21192 +
21193 +static struct inode_operations proc_virtnet_dir_inode_operations = {
21194 +       .getattr =      proc_virtnet_getattr,
21195 +       .lookup =       proc_virtnet_lookup,
21196 +};
21197 +
21198 +
21199 +
21200 +void proc_vx_init(void)
21201 +{
21202 +       struct proc_dir_entry *ent;
21203 +
21204 +       ent = proc_mkdir("virtual", 0);
21205 +       if (ent) {
21206 +               ent->proc_fops = &proc_virtual_dir_operations;
21207 +               ent->proc_iops = &proc_virtual_dir_inode_operations;
21208 +       }
21209 +       proc_virtual = ent;
21210 +
21211 +       ent = proc_mkdir("virtnet", 0);
21212 +       if (ent) {
21213 +               ent->proc_fops = &proc_virtnet_dir_operations;
21214 +               ent->proc_iops = &proc_virtnet_dir_inode_operations;
21215 +       }
21216 +       proc_virtnet = ent;
21217 +}
21218 +
21219 +
21220 +
21221 +
21222 +/* per pid info */
21223 +
21224 +void render_cap_t(struct seq_file *, const char *,
21225 +       struct vx_info *, kernel_cap_t *);
21226 +
21227 +
21228 +int proc_pid_vx_info(
21229 +       struct seq_file *m,
21230 +       struct pid_namespace *ns,
21231 +       struct pid *pid,
21232 +       struct task_struct *p)
21233 +{
21234 +       struct vx_info *vxi;
21235 +
21236 +       seq_printf(m, "XID:\t%d\n", vx_task_xid(p));
21237 +
21238 +       vxi = task_get_vx_info(p);
21239 +       if (!vxi)
21240 +               return 0;
21241 +
21242 +       render_cap_t(m, "BCaps:\t", vxi, &vxi->vx_bcaps);
21243 +       seq_printf(m, "CCaps:\t%016llx\n",
21244 +               (unsigned long long)vxi->vx_ccaps);
21245 +       seq_printf(m, "CFlags:\t%016llx\n",
21246 +               (unsigned long long)vxi->vx_flags);
21247 +       seq_printf(m, "CIPid:\t%d\n", vxi->vx_initpid);
21248 +
21249 +       put_vx_info(vxi);
21250 +       return 0;
21251 +}
21252 +
21253 +
21254 +int proc_pid_nx_info(
21255 +       struct seq_file *m,
21256 +       struct pid_namespace *ns,
21257 +       struct pid *pid,
21258 +       struct task_struct *p)
21259 +{
21260 +       struct nx_info *nxi;
21261 +       struct nx_addr_v4 *v4a;
21262 +#ifdef CONFIG_IPV6
21263 +       struct nx_addr_v6 *v6a;
21264 +#endif
21265 +       int i;
21266 +
21267 +       seq_printf(m, "NID:\t%d\n", nx_task_nid(p));
21268 +
21269 +       nxi = task_get_nx_info(p);
21270 +       if (!nxi)
21271 +               return 0;
21272 +
21273 +       seq_printf(m, "NCaps:\t%016llx\n",
21274 +               (unsigned long long)nxi->nx_ncaps);
21275 +       seq_printf(m, "NFlags:\t%016llx\n",
21276 +               (unsigned long long)nxi->nx_flags);
21277 +
21278 +       seq_printf(m, "V4Root[bcast]:\t" NIPQUAD_FMT "\n",
21279 +               NIPQUAD(nxi->v4_bcast.s_addr));
21280 +       seq_printf(m, "V4Root[lback]:\t" NIPQUAD_FMT "\n",
21281 +               NIPQUAD(nxi->v4_lback.s_addr));
21282 +       if (!NX_IPV4(nxi))
21283 +               goto skip_v4;
21284 +       for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
21285 +               seq_printf(m, "V4Root[%d]:\t" NXAV4_FMT "\n",
21286 +                       i, NXAV4(v4a));
21287 +skip_v4:
21288 +#ifdef CONFIG_IPV6
21289 +       if (!NX_IPV6(nxi))
21290 +               goto skip_v6;
21291 +       for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
21292 +               seq_printf(m, "V6Root[%d]:\t" NXAV6_FMT "\n",
21293 +                       i, NXAV6(v6a));
21294 +skip_v6:
21295 +#endif
21296 +       put_nx_info(nxi);
21297 +       return 0;
21298 +}
21299 +
21300 diff -NurpP --minimal linux-3.18.5/kernel/vserver/sched.c linux-3.18.5-vs2.3.7.3/kernel/vserver/sched.c
21301 --- linux-3.18.5/kernel/vserver/sched.c 1970-01-01 00:00:00.000000000 +0000
21302 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/sched.c       2015-01-19 10:58:31.000000000 +0000
21303 @@ -0,0 +1,83 @@
21304 +/*
21305 + *  linux/kernel/vserver/sched.c
21306 + *
21307 + *  Virtual Server: Scheduler Support
21308 + *
21309 + *  Copyright (C) 2004-2010  Herbert Pötzl
21310 + *
21311 + *  V0.01  adapted Sam Vilains version to 2.6.3
21312 + *  V0.02  removed legacy interface
21313 + *  V0.03  changed vcmds to vxi arg
21314 + *  V0.04  removed older and legacy interfaces
21315 + *  V0.05  removed scheduler code/commands
21316 + *
21317 + */
21318 +
21319 +#include <linux/vs_context.h>
21320 +#include <linux/vs_sched.h>
21321 +#include <linux/cpumask.h>
21322 +#include <linux/vserver/sched_cmd.h>
21323 +
21324 +#include <asm/uaccess.h>
21325 +
21326 +
21327 +void vx_update_sched_param(struct _vx_sched *sched,
21328 +       struct _vx_sched_pc *sched_pc)
21329 +{
21330 +       sched_pc->prio_bias = sched->prio_bias;
21331 +}
21332 +
21333 +static int do_set_prio_bias(struct vx_info *vxi, struct vcmd_prio_bias *data)
21334 +{
21335 +       int cpu;
21336 +
21337 +       if (data->prio_bias > MAX_PRIO_BIAS)
21338 +               data->prio_bias = MAX_PRIO_BIAS;
21339 +       if (data->prio_bias < MIN_PRIO_BIAS)
21340 +               data->prio_bias = MIN_PRIO_BIAS;
21341 +
21342 +       if (data->cpu_id != ~0) {
21343 +               vxi->sched.update = cpumask_of_cpu(data->cpu_id);
21344 +               cpumask_and(&vxi->sched.update, &vxi->sched.update,
21345 +                       cpu_online_mask);
21346 +       } else
21347 +               cpumask_copy(&vxi->sched.update, cpu_online_mask);
21348 +
21349 +       for_each_cpu_mask(cpu, vxi->sched.update)
21350 +               vx_update_sched_param(&vxi->sched,
21351 +                       &vx_per_cpu(vxi, sched_pc, cpu));
21352 +       return 0;
21353 +}
21354 +
21355 +int vc_set_prio_bias(struct vx_info *vxi, void __user *data)
21356 +{
21357 +       struct vcmd_prio_bias vc_data;
21358 +
21359 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21360 +               return -EFAULT;
21361 +
21362 +       return do_set_prio_bias(vxi, &vc_data);
21363 +}
21364 +
21365 +int vc_get_prio_bias(struct vx_info *vxi, void __user *data)
21366 +{
21367 +       struct vcmd_prio_bias vc_data;
21368 +       struct _vx_sched_pc *pcd;
21369 +       int cpu;
21370 +
21371 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21372 +               return -EFAULT;
21373 +
21374 +       cpu = vc_data.cpu_id;
21375 +
21376 +       if (!cpu_possible(cpu))
21377 +               return -EINVAL;
21378 +
21379 +       pcd = &vx_per_cpu(vxi, sched_pc, cpu);
21380 +       vc_data.prio_bias = pcd->prio_bias;
21381 +
21382 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
21383 +               return -EFAULT;
21384 +       return 0;
21385 +}
21386 +
21387 diff -NurpP --minimal linux-3.18.5/kernel/vserver/sched_init.h linux-3.18.5-vs2.3.7.3/kernel/vserver/sched_init.h
21388 --- linux-3.18.5/kernel/vserver/sched_init.h    1970-01-01 00:00:00.000000000 +0000
21389 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/sched_init.h  2015-01-19 10:58:31.000000000 +0000
21390 @@ -0,0 +1,27 @@
21391 +
21392 +static inline void vx_info_init_sched(struct _vx_sched *sched)
21393 +{
21394 +       /* scheduling; hard code starting values as constants */
21395 +       sched->prio_bias = 0;
21396 +}
21397 +
21398 +static inline
21399 +void vx_info_init_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
21400 +{
21401 +       sched_pc->prio_bias = 0;
21402 +
21403 +       sched_pc->user_ticks = 0;
21404 +       sched_pc->sys_ticks = 0;
21405 +       sched_pc->hold_ticks = 0;
21406 +}
21407 +
21408 +static inline void vx_info_exit_sched(struct _vx_sched *sched)
21409 +{
21410 +       return;
21411 +}
21412 +
21413 +static inline
21414 +void vx_info_exit_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
21415 +{
21416 +       return;
21417 +}
21418 diff -NurpP --minimal linux-3.18.5/kernel/vserver/sched_proc.h linux-3.18.5-vs2.3.7.3/kernel/vserver/sched_proc.h
21419 --- linux-3.18.5/kernel/vserver/sched_proc.h    1970-01-01 00:00:00.000000000 +0000
21420 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/sched_proc.h  2015-01-19 10:58:31.000000000 +0000
21421 @@ -0,0 +1,32 @@
21422 +#ifndef _VX_SCHED_PROC_H
21423 +#define _VX_SCHED_PROC_H
21424 +
21425 +
21426 +static inline
21427 +int vx_info_proc_sched(struct _vx_sched *sched, char *buffer)
21428 +{
21429 +       int length = 0;
21430 +
21431 +       length += sprintf(buffer,
21432 +               "PrioBias:\t%8d\n",
21433 +               sched->prio_bias);
21434 +       return length;
21435 +}
21436 +
21437 +static inline
21438 +int vx_info_proc_sched_pc(struct _vx_sched_pc *sched_pc,
21439 +       char *buffer, int cpu)
21440 +{
21441 +       int length = 0;
21442 +
21443 +       length += sprintf(buffer + length,
21444 +               "cpu %d: %lld %lld %lld", cpu,
21445 +               (unsigned long long)sched_pc->user_ticks,
21446 +               (unsigned long long)sched_pc->sys_ticks,
21447 +               (unsigned long long)sched_pc->hold_ticks);
21448 +       length += sprintf(buffer + length,
21449 +               " %d\n", sched_pc->prio_bias);
21450 +       return length;
21451 +}
21452 +
21453 +#endif /* _VX_SCHED_PROC_H */
21454 diff -NurpP --minimal linux-3.18.5/kernel/vserver/signal.c linux-3.18.5-vs2.3.7.3/kernel/vserver/signal.c
21455 --- linux-3.18.5/kernel/vserver/signal.c        1970-01-01 00:00:00.000000000 +0000
21456 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/signal.c      2015-01-19 10:58:31.000000000 +0000
21457 @@ -0,0 +1,134 @@
21458 +/*
21459 + *  linux/kernel/vserver/signal.c
21460 + *
21461 + *  Virtual Server: Signal Support
21462 + *
21463 + *  Copyright (C) 2003-2007  Herbert Pötzl
21464 + *
21465 + *  V0.01  broken out from vcontext V0.05
21466 + *  V0.02  changed vcmds to vxi arg
21467 + *  V0.03  adjusted siginfo for kill
21468 + *
21469 + */
21470 +
21471 +#include <asm/uaccess.h>
21472 +
21473 +#include <linux/vs_context.h>
21474 +#include <linux/vs_pid.h>
21475 +#include <linux/vserver/signal_cmd.h>
21476 +
21477 +
21478 +int vx_info_kill(struct vx_info *vxi, int pid, int sig)
21479 +{
21480 +       int retval, count = 0;
21481 +       struct task_struct *p;
21482 +       struct siginfo *sip = SEND_SIG_PRIV;
21483 +
21484 +       retval = -ESRCH;
21485 +       vxdprintk(VXD_CBIT(misc, 4),
21486 +               "vx_info_kill(%p[#%d],%d,%d)*",
21487 +               vxi, vxi->vx_id, pid, sig);
21488 +       read_lock(&tasklist_lock);
21489 +       switch (pid) {
21490 +       case  0:
21491 +       case -1:
21492 +               for_each_process(p) {
21493 +                       int err = 0;
21494 +
21495 +                       if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
21496 +                               (pid && vxi->vx_initpid == p->pid))
21497 +                               continue;
21498 +
21499 +                       err = group_send_sig_info(sig, sip, p);
21500 +                       ++count;
21501 +                       if (err != -EPERM)
21502 +                               retval = err;
21503 +               }
21504 +               break;
21505 +
21506 +       case 1:
21507 +               if (vxi->vx_initpid) {
21508 +                       pid = vxi->vx_initpid;
21509 +                       /* for now, only SIGINT to private init ... */
21510 +                       if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
21511 +                               /* ... as long as there are tasks left */
21512 +                               (atomic_read(&vxi->vx_tasks) > 1))
21513 +                               sig = SIGINT;
21514 +               }
21515 +               /* fallthrough */
21516 +       default:
21517 +               rcu_read_lock();
21518 +               p = find_task_by_real_pid(pid);
21519 +               rcu_read_unlock();
21520 +               if (p) {
21521 +                       if (vx_task_xid(p) == vxi->vx_id)
21522 +                               retval = group_send_sig_info(sig, sip, p);
21523 +               }
21524 +               break;
21525 +       }
21526 +       read_unlock(&tasklist_lock);
21527 +       vxdprintk(VXD_CBIT(misc, 4),
21528 +               "vx_info_kill(%p[#%d],%d,%d,%ld) = %d",
21529 +               vxi, vxi->vx_id, pid, sig, (long)sip, retval);
21530 +       return retval;
21531 +}
21532 +
21533 +int vc_ctx_kill(struct vx_info *vxi, void __user *data)
21534 +{
21535 +       struct vcmd_ctx_kill_v0 vc_data;
21536 +
21537 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21538 +               return -EFAULT;
21539 +
21540 +       /* special check to allow guest shutdown */
21541 +       if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
21542 +               /* forbid killall pid=0 when init is present */
21543 +               (((vc_data.pid < 1) && vxi->vx_initpid) ||
21544 +               (vc_data.pid > 1)))
21545 +               return -EACCES;
21546 +
21547 +       return vx_info_kill(vxi, vc_data.pid, vc_data.sig);
21548 +}
21549 +
21550 +
21551 +static int __wait_exit(struct vx_info *vxi)
21552 +{
21553 +       DECLARE_WAITQUEUE(wait, current);
21554 +       int ret = 0;
21555 +
21556 +       add_wait_queue(&vxi->vx_wait, &wait);
21557 +       set_current_state(TASK_INTERRUPTIBLE);
21558 +
21559 +wait:
21560 +       if (vx_info_state(vxi,
21561 +               VXS_SHUTDOWN | VXS_HASHED | VXS_HELPER) == VXS_SHUTDOWN)
21562 +               goto out;
21563 +       if (signal_pending(current)) {
21564 +               ret = -ERESTARTSYS;
21565 +               goto out;
21566 +       }
21567 +       schedule();
21568 +       goto wait;
21569 +
21570 +out:
21571 +       set_current_state(TASK_RUNNING);
21572 +       remove_wait_queue(&vxi->vx_wait, &wait);
21573 +       return ret;
21574 +}
21575 +
21576 +
21577 +
21578 +int vc_wait_exit(struct vx_info *vxi, void __user *data)
21579 +{
21580 +       struct vcmd_wait_exit_v0 vc_data;
21581 +       int ret;
21582 +
21583 +       ret = __wait_exit(vxi);
21584 +       vc_data.reboot_cmd = vxi->reboot_cmd;
21585 +       vc_data.exit_code = vxi->exit_code;
21586 +
21587 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
21588 +               ret = -EFAULT;
21589 +       return ret;
21590 +}
21591 +
21592 diff -NurpP --minimal linux-3.18.5/kernel/vserver/space.c linux-3.18.5-vs2.3.7.3/kernel/vserver/space.c
21593 --- linux-3.18.5/kernel/vserver/space.c 1970-01-01 00:00:00.000000000 +0000
21594 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/space.c       2015-01-25 18:27:56.000000000 +0000
21595 @@ -0,0 +1,436 @@
21596 +/*
21597 + *  linux/kernel/vserver/space.c
21598 + *
21599 + *  Virtual Server: Context Space Support
21600 + *
21601 + *  Copyright (C) 2003-2010  Herbert Pötzl
21602 + *
21603 + *  V0.01  broken out from context.c 0.07
21604 + *  V0.02  added task locking for namespace
21605 + *  V0.03  broken out vx_enter_namespace
21606 + *  V0.04  added *space support and commands
21607 + *  V0.05  added credential support
21608 + *
21609 + */
21610 +
21611 +#include <linux/utsname.h>
21612 +#include <linux/nsproxy.h>
21613 +#include <linux/err.h>
21614 +#include <linux/fs_struct.h>
21615 +#include <linux/cred.h>
21616 +#include <asm/uaccess.h>
21617 +
21618 +#include <linux/vs_context.h>
21619 +#include <linux/vserver/space.h>
21620 +#include <linux/vserver/space_cmd.h>
21621 +
21622 +atomic_t vs_global_nsproxy     = ATOMIC_INIT(0);
21623 +atomic_t vs_global_fs          = ATOMIC_INIT(0);
21624 +atomic_t vs_global_mnt_ns      = ATOMIC_INIT(0);
21625 +atomic_t vs_global_uts_ns      = ATOMIC_INIT(0);
21626 +atomic_t vs_global_user_ns     = ATOMIC_INIT(0);
21627 +atomic_t vs_global_pid_ns      = ATOMIC_INIT(0);
21628 +
21629 +
21630 +/* namespace functions */
21631 +
21632 +#include <linux/mnt_namespace.h>
21633 +#include <linux/user_namespace.h>
21634 +#include <linux/pid_namespace.h>
21635 +#include <linux/ipc_namespace.h>
21636 +#include <net/net_namespace.h>
21637 +#include "../fs/mount.h"
21638 +
21639 +
21640 +static const struct vcmd_space_mask_v1 space_mask_v0 = {
21641 +       .mask = CLONE_FS |
21642 +               CLONE_NEWNS |
21643 +#ifdef CONFIG_UTS_NS
21644 +               CLONE_NEWUTS |
21645 +#endif
21646 +#ifdef CONFIG_IPC_NS
21647 +               CLONE_NEWIPC |
21648 +#endif
21649 +#ifdef CONFIG_USER_NS
21650 +               CLONE_NEWUSER |
21651 +#endif
21652 +               0
21653 +};
21654 +
21655 +static const struct vcmd_space_mask_v1 space_mask = {
21656 +       .mask = CLONE_FS |
21657 +               CLONE_NEWNS |
21658 +#ifdef CONFIG_UTS_NS
21659 +               CLONE_NEWUTS |
21660 +#endif
21661 +#ifdef CONFIG_IPC_NS
21662 +               CLONE_NEWIPC |
21663 +#endif
21664 +#ifdef CONFIG_USER_NS
21665 +               CLONE_NEWUSER |
21666 +#endif
21667 +#ifdef CONFIG_PID_NS
21668 +               CLONE_NEWPID |
21669 +#endif
21670 +#ifdef CONFIG_NET_NS
21671 +               CLONE_NEWNET |
21672 +#endif
21673 +               0
21674 +};
21675 +
21676 +static const struct vcmd_space_mask_v1 default_space_mask = {
21677 +       .mask = CLONE_FS |
21678 +               CLONE_NEWNS |
21679 +#ifdef CONFIG_UTS_NS
21680 +               CLONE_NEWUTS |
21681 +#endif
21682 +#ifdef CONFIG_IPC_NS
21683 +               CLONE_NEWIPC |
21684 +#endif
21685 +#ifdef CONFIG_USER_NS
21686 +//             CLONE_NEWUSER |
21687 +#endif
21688 +#ifdef CONFIG_PID_NS
21689 +//             CLONE_NEWPID |
21690 +#endif
21691 +               0
21692 +};
21693 +
21694 +/*
21695 + *     build a new nsproxy mix
21696 + *      assumes that both proxies are 'const'
21697 + *     does not touch nsproxy refcounts
21698 + *     will hold a reference on the result.
21699 + */
21700 +
21701 +struct nsproxy *vs_mix_nsproxy(struct nsproxy *old_nsproxy,
21702 +       struct nsproxy *new_nsproxy, unsigned long mask)
21703 +{
21704 +       struct mnt_namespace *old_ns;
21705 +       struct uts_namespace *old_uts;
21706 +       struct ipc_namespace *old_ipc;
21707 +#ifdef CONFIG_PID_NS
21708 +       struct pid_namespace *old_pid;
21709 +#endif
21710 +#ifdef CONFIG_NET_NS
21711 +       struct net *old_net;
21712 +#endif
21713 +       struct nsproxy *nsproxy;
21714 +
21715 +       nsproxy = copy_nsproxy(old_nsproxy);
21716 +       if (!nsproxy)
21717 +               goto out;
21718 +
21719 +       if (mask & CLONE_NEWNS) {
21720 +               old_ns = nsproxy->mnt_ns;
21721 +               nsproxy->mnt_ns = new_nsproxy->mnt_ns;
21722 +               if (nsproxy->mnt_ns)
21723 +                       get_mnt_ns(nsproxy->mnt_ns);
21724 +       } else
21725 +               old_ns = NULL;
21726 +
21727 +       if (mask & CLONE_NEWUTS) {
21728 +               old_uts = nsproxy->uts_ns;
21729 +               nsproxy->uts_ns = new_nsproxy->uts_ns;
21730 +               if (nsproxy->uts_ns)
21731 +                       get_uts_ns(nsproxy->uts_ns);
21732 +       } else
21733 +               old_uts = NULL;
21734 +
21735 +       if (mask & CLONE_NEWIPC) {
21736 +               old_ipc = nsproxy->ipc_ns;
21737 +               nsproxy->ipc_ns = new_nsproxy->ipc_ns;
21738 +               if (nsproxy->ipc_ns)
21739 +                       get_ipc_ns(nsproxy->ipc_ns);
21740 +       } else
21741 +               old_ipc = NULL;
21742 +
21743 +#ifdef CONFIG_PID_NS
21744 +       if (mask & CLONE_NEWPID) {
21745 +               old_pid = nsproxy->pid_ns_for_children;
21746 +               nsproxy->pid_ns_for_children = new_nsproxy->pid_ns_for_children;
21747 +               if (nsproxy->pid_ns_for_children)
21748 +                       get_pid_ns(nsproxy->pid_ns_for_children);
21749 +       } else
21750 +               old_pid = NULL;
21751 +#endif
21752 +#ifdef CONFIG_NET_NS
21753 +       if (mask & CLONE_NEWNET) {
21754 +               old_net = nsproxy->net_ns;
21755 +               nsproxy->net_ns = new_nsproxy->net_ns;
21756 +               if (nsproxy->net_ns)
21757 +                       get_net(nsproxy->net_ns);
21758 +       } else
21759 +               old_net = NULL;
21760 +#endif
21761 +       if (old_ns)
21762 +               put_mnt_ns(old_ns);
21763 +       if (old_uts)
21764 +               put_uts_ns(old_uts);
21765 +       if (old_ipc)
21766 +               put_ipc_ns(old_ipc);
21767 +#ifdef CONFIG_PID_NS
21768 +       if (old_pid)
21769 +               put_pid_ns(old_pid);
21770 +#endif
21771 +#ifdef CONFIG_NET_NS
21772 +       if (old_net)
21773 +               put_net(old_net);
21774 +#endif
21775 +out:
21776 +       return nsproxy;
21777 +}
21778 +
21779 +
21780 +/*
21781 + *     merge two nsproxy structs into a new one.
21782 + *     will hold a reference on the result.
21783 + */
21784 +
21785 +static inline
21786 +struct nsproxy *__vs_merge_nsproxy(struct nsproxy *old,
21787 +       struct nsproxy *proxy, unsigned long mask)
21788 +{
21789 +       struct nsproxy null_proxy = { .mnt_ns = NULL };
21790 +
21791 +       if (!proxy)
21792 +               return NULL;
21793 +
21794 +       if (mask) {
21795 +               /* vs_mix_nsproxy returns with reference */
21796 +               return vs_mix_nsproxy(old ? old : &null_proxy,
21797 +                       proxy, mask);
21798 +       }
21799 +       get_nsproxy(proxy);
21800 +       return proxy;
21801 +}
21802 +
21803 +
21804 +int vx_enter_space(struct vx_info *vxi, unsigned long mask, unsigned index)
21805 +{
21806 +       struct nsproxy *proxy, *proxy_cur, *proxy_new;
21807 +       struct fs_struct *fs_cur, *fs = NULL;
21808 +       struct _vx_space *space;
21809 +       int ret, kill = 0;
21810 +
21811 +       vxdprintk(VXD_CBIT(space, 8), "vx_enter_space(%p[#%u],0x%08lx,%d)",
21812 +               vxi, vxi->vx_id, mask, index);
21813 +
21814 +       if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
21815 +               return -EACCES;
21816 +
21817 +       if (index >= VX_SPACES)
21818 +               return -EINVAL;
21819 +
21820 +       space = &vxi->space[index];
21821 +
21822 +       if (!mask)
21823 +               mask = space->vx_nsmask;
21824 +
21825 +       if ((mask & space->vx_nsmask) != mask)
21826 +               return -EINVAL;
21827 +
21828 +       if (mask & CLONE_FS) {
21829 +               fs = copy_fs_struct(space->vx_fs);
21830 +               if (!fs)
21831 +                       return -ENOMEM;
21832 +       }
21833 +       proxy = space->vx_nsproxy;
21834 +
21835 +       vxdprintk(VXD_CBIT(space, 9),
21836 +               "vx_enter_space(%p[#%u],0x%08lx,%d) -> (%p,%p)",
21837 +               vxi, vxi->vx_id, mask, index, proxy, fs);
21838 +
21839 +       task_lock(current);
21840 +       fs_cur = current->fs;
21841 +
21842 +       if (mask & CLONE_FS) {
21843 +               spin_lock(&fs_cur->lock);
21844 +               current->fs = fs;
21845 +               kill = !--fs_cur->users;
21846 +               spin_unlock(&fs_cur->lock);
21847 +       }
21848 +
21849 +       proxy_cur = current->nsproxy;
21850 +       get_nsproxy(proxy_cur);
21851 +       task_unlock(current);
21852 +
21853 +       if (kill)
21854 +               free_fs_struct(fs_cur);
21855 +
21856 +       proxy_new = __vs_merge_nsproxy(proxy_cur, proxy, mask);
21857 +       if (IS_ERR(proxy_new)) {
21858 +               ret = PTR_ERR(proxy_new);
21859 +               goto out_put;
21860 +       }
21861 +
21862 +       proxy_new = xchg(&current->nsproxy, proxy_new);
21863 +
21864 +       if (mask & CLONE_NEWUSER) {
21865 +               struct cred *cred;
21866 +
21867 +               vxdprintk(VXD_CBIT(space, 10),
21868 +                       "vx_enter_space(%p[#%u],%p) cred (%p,%p)",
21869 +                       vxi, vxi->vx_id, space->vx_cred,
21870 +                       current->real_cred, current->cred);
21871 +
21872 +               if (space->vx_cred) {
21873 +                       cred = __prepare_creds(space->vx_cred);
21874 +                       if (cred)
21875 +                               commit_creds(cred);
21876 +               }
21877 +       }
21878 +
21879 +       ret = 0;
21880 +
21881 +       if (proxy_new)
21882 +               put_nsproxy(proxy_new);
21883 +out_put:
21884 +       if (proxy_cur)
21885 +               put_nsproxy(proxy_cur);
21886 +       return ret;
21887 +}
21888 +
21889 +
21890 +int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index)
21891 +{
21892 +       struct nsproxy *proxy_vxi, *proxy_cur, *proxy_new;
21893 +       struct fs_struct *fs_vxi, *fs = NULL;
21894 +       struct _vx_space *space;
21895 +       int ret, kill = 0;
21896 +
21897 +       vxdprintk(VXD_CBIT(space, 8), "vx_set_space(%p[#%u],0x%08lx,%d)",
21898 +               vxi, vxi->vx_id, mask, index);
21899 +
21900 +       if ((mask & space_mask.mask) != mask)
21901 +               return -EINVAL;
21902 +
21903 +       if (index >= VX_SPACES)
21904 +               return -EINVAL;
21905 +
21906 +       space = &vxi->space[index];
21907 +
21908 +       proxy_vxi = space->vx_nsproxy;
21909 +       fs_vxi = space->vx_fs;
21910 +
21911 +       if (mask & CLONE_FS) {
21912 +               fs = copy_fs_struct(current->fs);
21913 +               if (!fs)
21914 +                       return -ENOMEM;
21915 +       }
21916 +
21917 +       task_lock(current);
21918 +
21919 +       if (mask & CLONE_FS) {
21920 +               spin_lock(&fs_vxi->lock);
21921 +               space->vx_fs = fs;
21922 +               kill = !--fs_vxi->users;
21923 +               spin_unlock(&fs_vxi->lock);
21924 +       }
21925 +
21926 +       proxy_cur = current->nsproxy;
21927 +       get_nsproxy(proxy_cur);
21928 +       task_unlock(current);
21929 +
21930 +       if (kill)
21931 +               free_fs_struct(fs_vxi);
21932 +
21933 +       proxy_new = __vs_merge_nsproxy(proxy_vxi, proxy_cur, mask);
21934 +       if (IS_ERR(proxy_new)) {
21935 +               ret = PTR_ERR(proxy_new);
21936 +               goto out_put;
21937 +       }
21938 +
21939 +       proxy_new = xchg(&space->vx_nsproxy, proxy_new);
21940 +       space->vx_nsmask |= mask;
21941 +
21942 +       if (mask & CLONE_NEWUSER) {
21943 +               struct cred *cred;
21944 +
21945 +               vxdprintk(VXD_CBIT(space, 10),
21946 +                       "vx_set_space(%p[#%u],%p) cred (%p,%p)",
21947 +                       vxi, vxi->vx_id, space->vx_cred,
21948 +                       current->real_cred, current->cred);
21949 +
21950 +               cred = prepare_creds();
21951 +               cred = (struct cred *)xchg(&space->vx_cred, cred);
21952 +               if (cred)
21953 +                       abort_creds(cred);
21954 +       }
21955 +
21956 +       ret = 0;
21957 +
21958 +       if (proxy_new)
21959 +               put_nsproxy(proxy_new);
21960 +out_put:
21961 +       if (proxy_cur)
21962 +               put_nsproxy(proxy_cur);
21963 +       return ret;
21964 +}
21965 +
21966 +
21967 +int vc_enter_space_v1(struct vx_info *vxi, void __user *data)
21968 +{
21969 +       struct vcmd_space_mask_v1 vc_data = { .mask = 0 };
21970 +
21971 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21972 +               return -EFAULT;
21973 +
21974 +       return vx_enter_space(vxi, vc_data.mask, 0);
21975 +}
21976 +
21977 +int vc_enter_space(struct vx_info *vxi, void __user *data)
21978 +{
21979 +       struct vcmd_space_mask_v2 vc_data = { .mask = 0 };
21980 +
21981 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21982 +               return -EFAULT;
21983 +
21984 +       if (vc_data.index >= VX_SPACES)
21985 +               return -EINVAL;
21986 +
21987 +       return vx_enter_space(vxi, vc_data.mask, vc_data.index);
21988 +}
21989 +
21990 +int vc_set_space_v1(struct vx_info *vxi, void __user *data)
21991 +{
21992 +       struct vcmd_space_mask_v1 vc_data = { .mask = 0 };
21993 +
21994 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21995 +               return -EFAULT;
21996 +
21997 +       return vx_set_space(vxi, vc_data.mask, 0);
21998 +}
21999 +
22000 +int vc_set_space(struct vx_info *vxi, void __user *data)
22001 +{
22002 +       struct vcmd_space_mask_v2 vc_data = { .mask = 0 };
22003 +
22004 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
22005 +               return -EFAULT;
22006 +
22007 +       if (vc_data.index >= VX_SPACES)
22008 +               return -EINVAL;
22009 +
22010 +       return vx_set_space(vxi, vc_data.mask, vc_data.index);
22011 +}
22012 +
22013 +int vc_get_space_mask(void __user *data, int type)
22014 +{
22015 +       const struct vcmd_space_mask_v1 *mask;
22016 +
22017 +       if (type == 0)
22018 +               mask = &space_mask_v0;
22019 +       else if (type == 1)
22020 +               mask = &space_mask;
22021 +       else
22022 +               mask = &default_space_mask;
22023 +
22024 +       vxdprintk(VXD_CBIT(space, 10),
22025 +               "vc_get_space_mask(%d) = %08llx", type, mask->mask);
22026 +
22027 +       if (copy_to_user(data, mask, sizeof(*mask)))
22028 +               return -EFAULT;
22029 +       return 0;
22030 +}
22031 +
22032 diff -NurpP --minimal linux-3.18.5/kernel/vserver/switch.c linux-3.18.5-vs2.3.7.3/kernel/vserver/switch.c
22033 --- linux-3.18.5/kernel/vserver/switch.c        1970-01-01 00:00:00.000000000 +0000
22034 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/switch.c      2015-01-19 10:58:31.000000000 +0000
22035 @@ -0,0 +1,556 @@
22036 +/*
22037 + *  linux/kernel/vserver/switch.c
22038 + *
22039 + *  Virtual Server: Syscall Switch
22040 + *
22041 + *  Copyright (C) 2003-2011  Herbert Pötzl
22042 + *
22043 + *  V0.01  syscall switch
22044 + *  V0.02  added signal to context
22045 + *  V0.03  added rlimit functions
22046 + *  V0.04  added iattr, task/xid functions
22047 + *  V0.05  added debug/history stuff
22048 + *  V0.06  added compat32 layer
22049 + *  V0.07  vcmd args and perms
22050 + *  V0.08  added status commands
22051 + *  V0.09  added tag commands
22052 + *  V0.10  added oom bias
22053 + *  V0.11  added device commands
22054 + *  V0.12  added warn mask
22055 + *
22056 + */
22057 +
22058 +#include <linux/vs_context.h>
22059 +#include <linux/vs_network.h>
22060 +#include <linux/vserver/switch.h>
22061 +
22062 +#include "vci_config.h"
22063 +
22064 +
22065 +static inline
22066 +int vc_get_version(uint32_t id)
22067 +{
22068 +       return VCI_VERSION;
22069 +}
22070 +
22071 +static inline
22072 +int vc_get_vci(uint32_t id)
22073 +{
22074 +       return vci_kernel_config();
22075 +}
22076 +
22077 +#include <linux/vserver/context_cmd.h>
22078 +#include <linux/vserver/cvirt_cmd.h>
22079 +#include <linux/vserver/cacct_cmd.h>
22080 +#include <linux/vserver/limit_cmd.h>
22081 +#include <linux/vserver/network_cmd.h>
22082 +#include <linux/vserver/sched_cmd.h>
22083 +#include <linux/vserver/debug_cmd.h>
22084 +#include <linux/vserver/inode_cmd.h>
22085 +#include <linux/vserver/dlimit_cmd.h>
22086 +#include <linux/vserver/signal_cmd.h>
22087 +#include <linux/vserver/space_cmd.h>
22088 +#include <linux/vserver/tag_cmd.h>
22089 +#include <linux/vserver/device_cmd.h>
22090 +
22091 +#include <linux/vserver/inode.h>
22092 +#include <linux/vserver/dlimit.h>
22093 +
22094 +
22095 +#ifdef CONFIG_COMPAT
22096 +#define __COMPAT(name, id, data, compat)       \
22097 +       (compat) ? name ## _x32(id, data) : name(id, data)
22098 +#define __COMPAT_NO_ID(name, data, compat)     \
22099 +       (compat) ? name ## _x32(data) : name(data)
22100 +#else
22101 +#define __COMPAT(name, id, data, compat)       \
22102 +       name(id, data)
22103 +#define __COMPAT_NO_ID(name, data, compat)     \
22104 +       name(data)
22105 +#endif
22106 +
22107 +
22108 +static inline
22109 +long do_vcmd(uint32_t cmd, uint32_t id,
22110 +       struct vx_info *vxi, struct nx_info *nxi,
22111 +       void __user *data, int compat)
22112 +{
22113 +       switch (cmd) {
22114 +
22115 +       case VCMD_get_version:
22116 +               return vc_get_version(id);
22117 +       case VCMD_get_vci:
22118 +               return vc_get_vci(id);
22119 +
22120 +       case VCMD_task_xid:
22121 +               return vc_task_xid(id);
22122 +       case VCMD_vx_info:
22123 +               return vc_vx_info(vxi, data);
22124 +
22125 +       case VCMD_task_nid:
22126 +               return vc_task_nid(id);
22127 +       case VCMD_nx_info:
22128 +               return vc_nx_info(nxi, data);
22129 +
22130 +       case VCMD_task_tag:
22131 +               return vc_task_tag(id);
22132 +
22133 +       case VCMD_set_space_v1:
22134 +               return vc_set_space_v1(vxi, data);
22135 +       /* this is version 2 */
22136 +       case VCMD_set_space:
22137 +               return vc_set_space(vxi, data);
22138 +
22139 +       case VCMD_get_space_mask_v0:
22140 +               return vc_get_space_mask(data, 0);
22141 +       /* this is version 1 */
22142 +       case VCMD_get_space_mask:
22143 +               return vc_get_space_mask(data, 1);
22144 +
22145 +       case VCMD_get_space_default:
22146 +               return vc_get_space_mask(data, -1);
22147 +
22148 +       case VCMD_set_umask:
22149 +               return vc_set_umask(vxi, data);
22150 +
22151 +       case VCMD_get_umask:
22152 +               return vc_get_umask(vxi, data);
22153 +
22154 +       case VCMD_set_wmask:
22155 +               return vc_set_wmask(vxi, data);
22156 +
22157 +       case VCMD_get_wmask:
22158 +               return vc_get_wmask(vxi, data);
22159 +#ifdef CONFIG_IA32_EMULATION
22160 +       case VCMD_get_rlimit:
22161 +               return __COMPAT(vc_get_rlimit, vxi, data, compat);
22162 +       case VCMD_set_rlimit:
22163 +               return __COMPAT(vc_set_rlimit, vxi, data, compat);
22164 +#else
22165 +       case VCMD_get_rlimit:
22166 +               return vc_get_rlimit(vxi, data);
22167 +       case VCMD_set_rlimit:
22168 +               return vc_set_rlimit(vxi, data);
22169 +#endif
22170 +       case VCMD_get_rlimit_mask:
22171 +               return vc_get_rlimit_mask(id, data);
22172 +       case VCMD_reset_hits:
22173 +               return vc_reset_hits(vxi, data);
22174 +       case VCMD_reset_minmax:
22175 +               return vc_reset_minmax(vxi, data);
22176 +
22177 +       case VCMD_get_vhi_name:
22178 +               return vc_get_vhi_name(vxi, data);
22179 +       case VCMD_set_vhi_name:
22180 +               return vc_set_vhi_name(vxi, data);
22181 +
22182 +       case VCMD_ctx_stat:
22183 +               return vc_ctx_stat(vxi, data);
22184 +       case VCMD_virt_stat:
22185 +               return vc_virt_stat(vxi, data);
22186 +       case VCMD_sock_stat:
22187 +               return vc_sock_stat(vxi, data);
22188 +       case VCMD_rlimit_stat:
22189 +               return vc_rlimit_stat(vxi, data);
22190 +
22191 +       case VCMD_set_cflags:
22192 +               return vc_set_cflags(vxi, data);
22193 +       case VCMD_get_cflags:
22194 +               return vc_get_cflags(vxi, data);
22195 +
22196 +       /* this is version 1 */
22197 +       case VCMD_set_ccaps:
22198 +               return vc_set_ccaps(vxi, data);
22199 +       /* this is version 1 */
22200 +       case VCMD_get_ccaps:
22201 +               return vc_get_ccaps(vxi, data);
22202 +       case VCMD_set_bcaps:
22203 +               return vc_set_bcaps(vxi, data);
22204 +       case VCMD_get_bcaps:
22205 +               return vc_get_bcaps(vxi, data);
22206 +
22207 +       case VCMD_set_badness:
22208 +               return vc_set_badness(vxi, data);
22209 +       case VCMD_get_badness:
22210 +               return vc_get_badness(vxi, data);
22211 +
22212 +       case VCMD_set_nflags:
22213 +               return vc_set_nflags(nxi, data);
22214 +       case VCMD_get_nflags:
22215 +               return vc_get_nflags(nxi, data);
22216 +
22217 +       case VCMD_set_ncaps:
22218 +               return vc_set_ncaps(nxi, data);
22219 +       case VCMD_get_ncaps:
22220 +               return vc_get_ncaps(nxi, data);
22221 +
22222 +       case VCMD_set_prio_bias:
22223 +               return vc_set_prio_bias(vxi, data);
22224 +       case VCMD_get_prio_bias:
22225 +               return vc_get_prio_bias(vxi, data);
22226 +       case VCMD_add_dlimit:
22227 +               return __COMPAT(vc_add_dlimit, id, data, compat);
22228 +       case VCMD_rem_dlimit:
22229 +               return __COMPAT(vc_rem_dlimit, id, data, compat);
22230 +       case VCMD_set_dlimit:
22231 +               return __COMPAT(vc_set_dlimit, id, data, compat);
22232 +       case VCMD_get_dlimit:
22233 +               return __COMPAT(vc_get_dlimit, id, data, compat);
22234 +
22235 +       case VCMD_ctx_kill:
22236 +               return vc_ctx_kill(vxi, data);
22237 +
22238 +       case VCMD_wait_exit:
22239 +               return vc_wait_exit(vxi, data);
22240 +
22241 +       case VCMD_get_iattr:
22242 +               return __COMPAT_NO_ID(vc_get_iattr, data, compat);
22243 +       case VCMD_set_iattr:
22244 +               return __COMPAT_NO_ID(vc_set_iattr, data, compat);
22245 +
22246 +       case VCMD_fget_iattr:
22247 +               return vc_fget_iattr(id, data);
22248 +       case VCMD_fset_iattr:
22249 +               return vc_fset_iattr(id, data);
22250 +
22251 +       case VCMD_enter_space_v0:
22252 +               return vc_enter_space_v1(vxi, NULL);
22253 +       case VCMD_enter_space_v1:
22254 +               return vc_enter_space_v1(vxi, data);
22255 +       /* this is version 2 */
22256 +       case VCMD_enter_space:
22257 +               return vc_enter_space(vxi, data);
22258 +
22259 +       case VCMD_ctx_create_v0:
22260 +               return vc_ctx_create(id, NULL);
22261 +       case VCMD_ctx_create:
22262 +               return vc_ctx_create(id, data);
22263 +       case VCMD_ctx_migrate_v0:
22264 +               return vc_ctx_migrate(vxi, NULL);
22265 +       case VCMD_ctx_migrate:
22266 +               return vc_ctx_migrate(vxi, data);
22267 +
22268 +       case VCMD_net_create_v0:
22269 +               return vc_net_create(id, NULL);
22270 +       case VCMD_net_create:
22271 +               return vc_net_create(id, data);
22272 +       case VCMD_net_migrate:
22273 +               return vc_net_migrate(nxi, data);
22274 +
22275 +       case VCMD_tag_migrate:
22276 +               return vc_tag_migrate(id);
22277 +
22278 +       case VCMD_net_add:
22279 +               return vc_net_add(nxi, data);
22280 +       case VCMD_net_remove:
22281 +               return vc_net_remove(nxi, data);
22282 +
22283 +       case VCMD_net_add_ipv4_v1:
22284 +               return vc_net_add_ipv4_v1(nxi, data);
22285 +       /* this is version 2 */
22286 +       case VCMD_net_add_ipv4:
22287 +               return vc_net_add_ipv4(nxi, data);
22288 +
22289 +       case VCMD_net_rem_ipv4_v1:
22290 +               return vc_net_rem_ipv4_v1(nxi, data);
22291 +       /* this is version 2 */
22292 +       case VCMD_net_rem_ipv4:
22293 +               return vc_net_rem_ipv4(nxi, data);
22294 +#ifdef CONFIG_IPV6
22295 +       case VCMD_net_add_ipv6:
22296 +               return vc_net_add_ipv6(nxi, data);
22297 +       case VCMD_net_remove_ipv6:
22298 +               return vc_net_remove_ipv6(nxi, data);
22299 +#endif
22300 +/*     case VCMD_add_match_ipv4:
22301 +               return vc_add_match_ipv4(nxi, data);
22302 +       case VCMD_get_match_ipv4:
22303 +               return vc_get_match_ipv4(nxi, data);
22304 +#ifdef CONFIG_IPV6
22305 +       case VCMD_add_match_ipv6:
22306 +               return vc_add_match_ipv6(nxi, data);
22307 +       case VCMD_get_match_ipv6:
22308 +               return vc_get_match_ipv6(nxi, data);
22309 +#endif */
22310 +
22311 +#ifdef CONFIG_VSERVER_DEVICE
22312 +       case VCMD_set_mapping:
22313 +               return __COMPAT(vc_set_mapping, vxi, data, compat);
22314 +       case VCMD_unset_mapping:
22315 +               return __COMPAT(vc_unset_mapping, vxi, data, compat);
22316 +#endif
22317 +#ifdef CONFIG_VSERVER_HISTORY
22318 +       case VCMD_dump_history:
22319 +               return vc_dump_history(id);
22320 +       case VCMD_read_history:
22321 +               return __COMPAT(vc_read_history, id, data, compat);
22322 +#endif
22323 +       default:
22324 +               vxwprintk_task(1, "unimplemented VCMD_%02d_%d[%d]",
22325 +                       VC_CATEGORY(cmd), VC_COMMAND(cmd), VC_VERSION(cmd));
22326 +       }
22327 +       return -ENOSYS;
22328 +}
22329 +
22330 +
22331 +#define        __VCMD(vcmd, _perm, _args, _flags)              \
22332 +       case VCMD_ ## vcmd: perm = _perm;               \
22333 +               args = _args; flags = _flags; break
22334 +
22335 +
22336 +#define VCA_NONE       0x00
22337 +#define VCA_VXI                0x01
22338 +#define VCA_NXI                0x02
22339 +
22340 +#define VCF_NONE       0x00
22341 +#define VCF_INFO       0x01
22342 +#define VCF_ADMIN      0x02
22343 +#define VCF_ARES       0x06    /* includes admin */
22344 +#define VCF_SETUP      0x08
22345 +
22346 +#define VCF_ZIDOK      0x10    /* zero id okay */
22347 +
22348 +
22349 +static inline
22350 +long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
22351 +{
22352 +       long ret;
22353 +       int permit = -1, state = 0;
22354 +       int perm = -1, args = 0, flags = 0;
22355 +       struct vx_info *vxi = NULL;
22356 +       struct nx_info *nxi = NULL;
22357 +
22358 +       switch (cmd) {
22359 +       /* unpriviledged commands */
22360 +       __VCMD(get_version,      0, VCA_NONE,   0);
22361 +       __VCMD(get_vci,          0, VCA_NONE,   0);
22362 +       __VCMD(get_rlimit_mask,  0, VCA_NONE,   0);
22363 +       __VCMD(get_space_mask_v0,0, VCA_NONE,   0);
22364 +       __VCMD(get_space_mask,   0, VCA_NONE,   0);
22365 +       __VCMD(get_space_default,0, VCA_NONE,   0);
22366 +
22367 +       /* info commands */
22368 +       __VCMD(task_xid,         2, VCA_NONE,   0);
22369 +       __VCMD(reset_hits,       2, VCA_VXI,    0);
22370 +       __VCMD(reset_minmax,     2, VCA_VXI,    0);
22371 +       __VCMD(vx_info,          3, VCA_VXI,    VCF_INFO);
22372 +       __VCMD(get_bcaps,        3, VCA_VXI,    VCF_INFO);
22373 +       __VCMD(get_ccaps,        3, VCA_VXI,    VCF_INFO);
22374 +       __VCMD(get_cflags,       3, VCA_VXI,    VCF_INFO);
22375 +       __VCMD(get_umask,        3, VCA_VXI,    VCF_INFO);
22376 +       __VCMD(get_wmask,        3, VCA_VXI,    VCF_INFO);
22377 +       __VCMD(get_badness,      3, VCA_VXI,    VCF_INFO);
22378 +       __VCMD(get_vhi_name,     3, VCA_VXI,    VCF_INFO);
22379 +       __VCMD(get_rlimit,       3, VCA_VXI,    VCF_INFO);
22380 +
22381 +       __VCMD(ctx_stat,         3, VCA_VXI,    VCF_INFO);
22382 +       __VCMD(virt_stat,        3, VCA_VXI,    VCF_INFO);
22383 +       __VCMD(sock_stat,        3, VCA_VXI,    VCF_INFO);
22384 +       __VCMD(rlimit_stat,      3, VCA_VXI,    VCF_INFO);
22385 +
22386 +       __VCMD(task_nid,         2, VCA_NONE,   0);
22387 +       __VCMD(nx_info,          3, VCA_NXI,    VCF_INFO);
22388 +       __VCMD(get_ncaps,        3, VCA_NXI,    VCF_INFO);
22389 +       __VCMD(get_nflags,       3, VCA_NXI,    VCF_INFO);
22390 +
22391 +       __VCMD(task_tag,         2, VCA_NONE,   0);
22392 +
22393 +       __VCMD(get_iattr,        2, VCA_NONE,   0);
22394 +       __VCMD(fget_iattr,       2, VCA_NONE,   0);
22395 +       __VCMD(get_dlimit,       3, VCA_NONE,   VCF_INFO);
22396 +       __VCMD(get_prio_bias,    3, VCA_VXI,    VCF_INFO);
22397 +
22398 +       /* lower admin commands */
22399 +       __VCMD(wait_exit,        4, VCA_VXI,    VCF_INFO);
22400 +       __VCMD(ctx_create_v0,    5, VCA_NONE,   0);
22401 +       __VCMD(ctx_create,       5, VCA_NONE,   0);
22402 +       __VCMD(ctx_migrate_v0,   5, VCA_VXI,    VCF_ADMIN);
22403 +       __VCMD(ctx_migrate,      5, VCA_VXI,    VCF_ADMIN);
22404 +       __VCMD(enter_space_v0,   5, VCA_VXI,    VCF_ADMIN);
22405 +       __VCMD(enter_space_v1,   5, VCA_VXI,    VCF_ADMIN);
22406 +       __VCMD(enter_space,      5, VCA_VXI,    VCF_ADMIN);
22407 +
22408 +       __VCMD(net_create_v0,    5, VCA_NONE,   0);
22409 +       __VCMD(net_create,       5, VCA_NONE,   0);
22410 +       __VCMD(net_migrate,      5, VCA_NXI,    VCF_ADMIN);
22411 +
22412 +       __VCMD(tag_migrate,      5, VCA_NONE,   VCF_ADMIN);
22413 +
22414 +       /* higher admin commands */
22415 +       __VCMD(ctx_kill,         6, VCA_VXI,    VCF_ARES);
22416 +       __VCMD(set_space_v1,     7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22417 +       __VCMD(set_space,        7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22418 +
22419 +       __VCMD(set_ccaps,        7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22420 +       __VCMD(set_bcaps,        7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22421 +       __VCMD(set_cflags,       7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22422 +       __VCMD(set_umask,        7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22423 +       __VCMD(set_wmask,        7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22424 +       __VCMD(set_badness,      7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22425 +
22426 +       __VCMD(set_vhi_name,     7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22427 +       __VCMD(set_rlimit,       7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22428 +       __VCMD(set_prio_bias,    7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22429 +
22430 +       __VCMD(set_ncaps,        7, VCA_NXI,    VCF_ARES | VCF_SETUP);
22431 +       __VCMD(set_nflags,       7, VCA_NXI,    VCF_ARES | VCF_SETUP);
22432 +       __VCMD(net_add,          8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22433 +       __VCMD(net_remove,       8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22434 +       __VCMD(net_add_ipv4_v1,  8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22435 +       __VCMD(net_rem_ipv4_v1,  8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22436 +       __VCMD(net_add_ipv4,     8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22437 +       __VCMD(net_rem_ipv4,     8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22438 +#ifdef CONFIG_IPV6
22439 +       __VCMD(net_add_ipv6,     8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22440 +       __VCMD(net_remove_ipv6,  8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22441 +#endif
22442 +       __VCMD(set_iattr,        7, VCA_NONE,   0);
22443 +       __VCMD(fset_iattr,       7, VCA_NONE,   0);
22444 +       __VCMD(set_dlimit,       7, VCA_NONE,   VCF_ARES);
22445 +       __VCMD(add_dlimit,       8, VCA_NONE,   VCF_ARES);
22446 +       __VCMD(rem_dlimit,       8, VCA_NONE,   VCF_ARES);
22447 +
22448 +#ifdef CONFIG_VSERVER_DEVICE
22449 +       __VCMD(set_mapping,      8, VCA_VXI,    VCF_ARES|VCF_ZIDOK);
22450 +       __VCMD(unset_mapping,    8, VCA_VXI,    VCF_ARES|VCF_ZIDOK);
22451 +#endif
22452 +       /* debug level admin commands */
22453 +#ifdef CONFIG_VSERVER_HISTORY
22454 +       __VCMD(dump_history,     9, VCA_NONE,   0);
22455 +       __VCMD(read_history,     9, VCA_NONE,   0);
22456 +#endif
22457 +
22458 +       default:
22459 +               perm = -1;
22460 +       }
22461 +
22462 +       vxdprintk(VXD_CBIT(switch, 0),
22463 +               "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]",
22464 +               VC_CATEGORY(cmd), VC_COMMAND(cmd),
22465 +               VC_VERSION(cmd), id, data, compat,
22466 +               perm, args, flags);
22467 +
22468 +       ret = -ENOSYS;
22469 +       if (perm < 0)
22470 +               goto out;
22471 +
22472 +       state = 1;
22473 +       if (!capable(CAP_CONTEXT))
22474 +               goto out;
22475 +
22476 +       state = 2;
22477 +       /* moved here from the individual commands */
22478 +       ret = -EPERM;
22479 +       if ((perm > 1) && !capable(CAP_SYS_ADMIN))
22480 +               goto out;
22481 +
22482 +       state = 3;
22483 +       /* vcmd involves resource management  */
22484 +       ret = -EPERM;
22485 +       if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE))
22486 +               goto out;
22487 +
22488 +       state = 4;
22489 +       /* various legacy exceptions */
22490 +       switch (cmd) {
22491 +       /* will go away when spectator is a cap */
22492 +       case VCMD_ctx_migrate_v0:
22493 +       case VCMD_ctx_migrate:
22494 +               if (id == 1) {
22495 +                       current->xid = 1;
22496 +                       ret = 1;
22497 +                       goto out;
22498 +               }
22499 +               break;
22500 +
22501 +       /* will go away when spectator is a cap */
22502 +       case VCMD_net_migrate:
22503 +               if (id == 1) {
22504 +                       current->nid = 1;
22505 +                       ret = 1;
22506 +                       goto out;
22507 +               }
22508 +               break;
22509 +       }
22510 +
22511 +       /* vcmds are fine by default */
22512 +       permit = 1;
22513 +
22514 +       /* admin type vcmds require admin ... */
22515 +       if (flags & VCF_ADMIN)
22516 +               permit = vx_check(0, VS_ADMIN) ? 1 : 0;
22517 +
22518 +       /* ... but setup type vcmds override that */
22519 +       if (!permit && (flags & VCF_SETUP))
22520 +               permit = vx_flags(VXF_STATE_SETUP, 0) ? 2 : 0;
22521 +
22522 +       state = 5;
22523 +       ret = -EPERM;
22524 +       if (!permit)
22525 +               goto out;
22526 +
22527 +       state = 6;
22528 +       if (!id && (flags & VCF_ZIDOK))
22529 +               goto skip_id;
22530 +
22531 +       ret = -ESRCH;
22532 +       if (args & VCA_VXI) {
22533 +               vxi = lookup_vx_info(id);
22534 +               if (!vxi)
22535 +                       goto out;
22536 +
22537 +               if ((flags & VCF_ADMIN) &&
22538 +                       /* special case kill for shutdown */
22539 +                       (cmd != VCMD_ctx_kill) &&
22540 +                       /* can context be administrated? */
22541 +                       !vx_info_flags(vxi, VXF_STATE_ADMIN, 0)) {
22542 +                       ret = -EACCES;
22543 +                       goto out_vxi;
22544 +               }
22545 +       }
22546 +       state = 7;
22547 +       if (args & VCA_NXI) {
22548 +               nxi = lookup_nx_info(id);
22549 +               if (!nxi)
22550 +                       goto out_vxi;
22551 +
22552 +               if ((flags & VCF_ADMIN) &&
22553 +                       /* can context be administrated? */
22554 +                       !nx_info_flags(nxi, NXF_STATE_ADMIN, 0)) {
22555 +                       ret = -EACCES;
22556 +                       goto out_nxi;
22557 +               }
22558 +       }
22559 +skip_id:
22560 +       state = 8;
22561 +       ret = do_vcmd(cmd, id, vxi, nxi, data, compat);
22562 +
22563 +out_nxi:
22564 +       if ((args & VCA_NXI) && nxi)
22565 +               put_nx_info(nxi);
22566 +out_vxi:
22567 +       if ((args & VCA_VXI) && vxi)
22568 +               put_vx_info(vxi);
22569 +out:
22570 +       vxdprintk(VXD_CBIT(switch, 1),
22571 +               "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]",
22572 +               VC_CATEGORY(cmd), VC_COMMAND(cmd),
22573 +               VC_VERSION(cmd), ret, ret, state, permit);
22574 +       return ret;
22575 +}
22576 +
22577 +asmlinkage long
22578 +sys_vserver(uint32_t cmd, uint32_t id, void __user *data)
22579 +{
22580 +       return do_vserver(cmd, id, data, 0);
22581 +}
22582 +
22583 +#ifdef CONFIG_COMPAT
22584 +
22585 +asmlinkage long
22586 +sys32_vserver(uint32_t cmd, uint32_t id, void __user *data)
22587 +{
22588 +       return do_vserver(cmd, id, data, 1);
22589 +}
22590 +
22591 +#endif /* CONFIG_COMPAT */
22592 diff -NurpP --minimal linux-3.18.5/kernel/vserver/sysctl.c linux-3.18.5-vs2.3.7.3/kernel/vserver/sysctl.c
22593 --- linux-3.18.5/kernel/vserver/sysctl.c        1970-01-01 00:00:00.000000000 +0000
22594 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/sysctl.c      2015-01-19 18:06:52.000000000 +0000
22595 @@ -0,0 +1,247 @@
22596 +/*
22597 + *  kernel/vserver/sysctl.c
22598 + *
22599 + *  Virtual Context Support
22600 + *
22601 + *  Copyright (C) 2004-2007  Herbert Pötzl
22602 + *
22603 + *  V0.01  basic structure
22604 + *
22605 + */
22606 +
22607 +#include <linux/module.h>
22608 +#include <linux/ctype.h>
22609 +#include <linux/sysctl.h>
22610 +#include <linux/parser.h>
22611 +#include <asm/uaccess.h>
22612 +
22613 +enum {
22614 +       CTL_DEBUG_ERROR         = 0,
22615 +       CTL_DEBUG_SWITCH        = 1,
22616 +       CTL_DEBUG_XID,
22617 +       CTL_DEBUG_NID,
22618 +       CTL_DEBUG_TAG,
22619 +       CTL_DEBUG_NET,
22620 +       CTL_DEBUG_LIMIT,
22621 +       CTL_DEBUG_CRES,
22622 +       CTL_DEBUG_DLIM,
22623 +       CTL_DEBUG_QUOTA,
22624 +       CTL_DEBUG_CVIRT,
22625 +       CTL_DEBUG_SPACE,
22626 +       CTL_DEBUG_PERM,
22627 +       CTL_DEBUG_MISC,
22628 +};
22629 +
22630 +
22631 +unsigned int vs_debug_switch   = 0;
22632 +unsigned int vs_debug_xid      = 0;
22633 +unsigned int vs_debug_nid      = 0;
22634 +unsigned int vs_debug_tag      = 0;
22635 +unsigned int vs_debug_net      = 0;
22636 +unsigned int vs_debug_limit    = 0;
22637 +unsigned int vs_debug_cres     = 0;
22638 +unsigned int vs_debug_dlim     = 0;
22639 +unsigned int vs_debug_quota    = 0;
22640 +unsigned int vs_debug_cvirt    = 0;
22641 +unsigned int vs_debug_space    = 0;
22642 +unsigned int vs_debug_perm     = 0;
22643 +unsigned int vs_debug_misc     = 0;
22644 +
22645 +
22646 +static struct ctl_table_header *vserver_table_header;
22647 +static struct ctl_table vserver_root_table[];
22648 +
22649 +
22650 +void vserver_register_sysctl(void)
22651 +{
22652 +       if (!vserver_table_header) {
22653 +               vserver_table_header = register_sysctl_table(vserver_root_table);
22654 +       }
22655 +
22656 +}
22657 +
22658 +void vserver_unregister_sysctl(void)
22659 +{
22660 +       if (vserver_table_header) {
22661 +               unregister_sysctl_table(vserver_table_header);
22662 +               vserver_table_header = NULL;
22663 +       }
22664 +}
22665 +
22666 +
22667 +static int proc_dodebug(struct ctl_table *table, int write,
22668 +       void __user *buffer, size_t *lenp, loff_t *ppos)
22669 +{
22670 +       char            tmpbuf[20], *p, c;
22671 +       unsigned int    value;
22672 +       size_t          left, len;
22673 +
22674 +       if ((*ppos && !write) || !*lenp) {
22675 +               *lenp = 0;
22676 +               return 0;
22677 +       }
22678 +
22679 +       left = *lenp;
22680 +
22681 +       if (write) {
22682 +               if (!access_ok(VERIFY_READ, buffer, left))
22683 +                       return -EFAULT;
22684 +               p = (char *)buffer;
22685 +               while (left && __get_user(c, p) >= 0 && isspace(c))
22686 +                       left--, p++;
22687 +               if (!left)
22688 +                       goto done;
22689 +
22690 +               if (left > sizeof(tmpbuf) - 1)
22691 +                       return -EINVAL;
22692 +               if (copy_from_user(tmpbuf, p, left))
22693 +                       return -EFAULT;
22694 +               tmpbuf[left] = '\0';
22695 +
22696 +               for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
22697 +                       value = 10 * value + (*p - '0');
22698 +               if (*p && !isspace(*p))
22699 +                       return -EINVAL;
22700 +               while (left && isspace(*p))
22701 +                       left--, p++;
22702 +               *(unsigned int *)table->data = value;
22703 +       } else {
22704 +               if (!access_ok(VERIFY_WRITE, buffer, left))
22705 +                       return -EFAULT;
22706 +               len = sprintf(tmpbuf, "%d", *(unsigned int *)table->data);
22707 +               if (len > left)
22708 +                       len = left;
22709 +               if (__copy_to_user(buffer, tmpbuf, len))
22710 +                       return -EFAULT;
22711 +               if ((left -= len) > 0) {
22712 +                       if (put_user('\n', (char *)buffer + len))
22713 +                               return -EFAULT;
22714 +                       left--;
22715 +               }
22716 +       }
22717 +
22718 +done:
22719 +       *lenp -= left;
22720 +       *ppos += *lenp;
22721 +       return 0;
22722 +}
22723 +
22724 +static int zero;
22725 +
22726 +#define        CTL_ENTRY(ctl, name)                            \
22727 +       {                                               \
22728 +               .procname       = #name,                \
22729 +               .data           = &vs_ ## name,         \
22730 +               .maxlen         = sizeof(int),          \
22731 +               .mode           = 0644,                 \
22732 +               .proc_handler   = &proc_dodebug,        \
22733 +               .extra1         = &zero,                \
22734 +               .extra2         = &zero,                \
22735 +       }
22736 +
22737 +static struct ctl_table vserver_debug_table[] = {
22738 +       CTL_ENTRY(CTL_DEBUG_SWITCH,     debug_switch),
22739 +       CTL_ENTRY(CTL_DEBUG_XID,        debug_xid),
22740 +       CTL_ENTRY(CTL_DEBUG_NID,        debug_nid),
22741 +       CTL_ENTRY(CTL_DEBUG_TAG,        debug_tag),
22742 +       CTL_ENTRY(CTL_DEBUG_NET,        debug_net),
22743 +       CTL_ENTRY(CTL_DEBUG_LIMIT,      debug_limit),
22744 +       CTL_ENTRY(CTL_DEBUG_CRES,       debug_cres),
22745 +       CTL_ENTRY(CTL_DEBUG_DLIM,       debug_dlim),
22746 +       CTL_ENTRY(CTL_DEBUG_QUOTA,      debug_quota),
22747 +       CTL_ENTRY(CTL_DEBUG_CVIRT,      debug_cvirt),
22748 +       CTL_ENTRY(CTL_DEBUG_SPACE,      debug_space),
22749 +       CTL_ENTRY(CTL_DEBUG_PERM,       debug_perm),
22750 +       CTL_ENTRY(CTL_DEBUG_MISC,       debug_misc),
22751 +       { 0 }
22752 +};
22753 +
22754 +static struct ctl_table vserver_root_table[] = {
22755 +       {
22756 +               .procname       = "vserver",
22757 +               .mode           = 0555,
22758 +               .child          = vserver_debug_table
22759 +       },
22760 +       { 0 }
22761 +};
22762 +
22763 +
22764 +static match_table_t tokens = {
22765 +       { CTL_DEBUG_SWITCH,     "switch=%x"     },
22766 +       { CTL_DEBUG_XID,        "xid=%x"        },
22767 +       { CTL_DEBUG_NID,        "nid=%x"        },
22768 +       { CTL_DEBUG_TAG,        "tag=%x"        },
22769 +       { CTL_DEBUG_NET,        "net=%x"        },
22770 +       { CTL_DEBUG_LIMIT,      "limit=%x"      },
22771 +       { CTL_DEBUG_CRES,       "cres=%x"       },
22772 +       { CTL_DEBUG_DLIM,       "dlim=%x"       },
22773 +       { CTL_DEBUG_QUOTA,      "quota=%x"      },
22774 +       { CTL_DEBUG_CVIRT,      "cvirt=%x"      },
22775 +       { CTL_DEBUG_SPACE,      "space=%x"      },
22776 +       { CTL_DEBUG_PERM,       "perm=%x"       },
22777 +       { CTL_DEBUG_MISC,       "misc=%x"       },
22778 +       { CTL_DEBUG_ERROR,      NULL            }
22779 +};
22780 +
22781 +#define        HANDLE_CASE(id, name, val)                              \
22782 +       case CTL_DEBUG_ ## id:                                  \
22783 +               vs_debug_ ## name = val;                        \
22784 +               printk("vs_debug_" #name "=0x%x\n", val);       \
22785 +               break
22786 +
22787 +
22788 +static int __init vs_debug_setup(char *str)
22789 +{
22790 +       char *p;
22791 +       int token;
22792 +
22793 +       printk("vs_debug_setup(%s)\n", str);
22794 +       while ((p = strsep(&str, ",")) != NULL) {
22795 +               substring_t args[MAX_OPT_ARGS];
22796 +               unsigned int value;
22797 +
22798 +               if (!*p)
22799 +                       continue;
22800 +
22801 +               token = match_token(p, tokens, args);
22802 +               value = (token > 0) ? simple_strtoul(args[0].from, NULL, 0) : 0;
22803 +
22804 +               switch (token) {
22805 +               HANDLE_CASE(SWITCH, switch, value);
22806 +               HANDLE_CASE(XID,    xid,    value);
22807 +               HANDLE_CASE(NID,    nid,    value);
22808 +               HANDLE_CASE(TAG,    tag,    value);
22809 +               HANDLE_CASE(NET,    net,    value);
22810 +               HANDLE_CASE(LIMIT,  limit,  value);
22811 +               HANDLE_CASE(CRES,   cres,   value);
22812 +               HANDLE_CASE(DLIM,   dlim,   value);
22813 +               HANDLE_CASE(QUOTA,  quota,  value);
22814 +               HANDLE_CASE(CVIRT,  cvirt,  value);
22815 +               HANDLE_CASE(SPACE,  space,  value);
22816 +               HANDLE_CASE(PERM,   perm,   value);
22817 +               HANDLE_CASE(MISC,   misc,   value);
22818 +               default:
22819 +                       return -EINVAL;
22820 +                       break;
22821 +               }
22822 +       }
22823 +       return 1;
22824 +}
22825 +
22826 +__setup("vsdebug=", vs_debug_setup);
22827 +
22828 +
22829 +
22830 +EXPORT_SYMBOL_GPL(vs_debug_switch);
22831 +EXPORT_SYMBOL_GPL(vs_debug_xid);
22832 +EXPORT_SYMBOL_GPL(vs_debug_nid);
22833 +EXPORT_SYMBOL_GPL(vs_debug_net);
22834 +EXPORT_SYMBOL_GPL(vs_debug_limit);
22835 +EXPORT_SYMBOL_GPL(vs_debug_cres);
22836 +EXPORT_SYMBOL_GPL(vs_debug_dlim);
22837 +EXPORT_SYMBOL_GPL(vs_debug_quota);
22838 +EXPORT_SYMBOL_GPL(vs_debug_cvirt);
22839 +EXPORT_SYMBOL_GPL(vs_debug_space);
22840 +EXPORT_SYMBOL_GPL(vs_debug_perm);
22841 +EXPORT_SYMBOL_GPL(vs_debug_misc);
22842 +
22843 diff -NurpP --minimal linux-3.18.5/kernel/vserver/tag.c linux-3.18.5-vs2.3.7.3/kernel/vserver/tag.c
22844 --- linux-3.18.5/kernel/vserver/tag.c   1970-01-01 00:00:00.000000000 +0000
22845 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/tag.c 2015-01-19 10:58:31.000000000 +0000
22846 @@ -0,0 +1,63 @@
22847 +/*
22848 + *  linux/kernel/vserver/tag.c
22849 + *
22850 + *  Virtual Server: Shallow Tag Space
22851 + *
22852 + *  Copyright (C) 2007  Herbert Pötzl
22853 + *
22854 + *  V0.01  basic implementation
22855 + *
22856 + */
22857 +
22858 +#include <linux/sched.h>
22859 +#include <linux/vserver/debug.h>
22860 +#include <linux/vs_pid.h>
22861 +#include <linux/vs_tag.h>
22862 +
22863 +#include <linux/vserver/tag_cmd.h>
22864 +
22865 +
22866 +int dx_migrate_task(struct task_struct *p, vtag_t tag)
22867 +{
22868 +       if (!p)
22869 +               BUG();
22870 +
22871 +       vxdprintk(VXD_CBIT(tag, 5),
22872 +               "dx_migrate_task(%p[#%d],#%d)", p, p->tag, tag);
22873 +
22874 +       task_lock(p);
22875 +       p->tag = tag;
22876 +       task_unlock(p);
22877 +
22878 +       vxdprintk(VXD_CBIT(tag, 5),
22879 +               "moved task %p into [#%d]", p, tag);
22880 +       return 0;
22881 +}
22882 +
22883 +/* vserver syscall commands below here */
22884 +
22885 +/* taks xid and vx_info functions */
22886 +
22887 +
22888 +int vc_task_tag(uint32_t id)
22889 +{
22890 +       vtag_t tag;
22891 +
22892 +       if (id) {
22893 +               struct task_struct *tsk;
22894 +               rcu_read_lock();
22895 +               tsk = find_task_by_real_pid(id);
22896 +               tag = (tsk) ? tsk->tag : -ESRCH;
22897 +               rcu_read_unlock();
22898 +       } else
22899 +               tag = dx_current_tag();
22900 +       return tag;
22901 +}
22902 +
22903 +
22904 +int vc_tag_migrate(uint32_t tag)
22905 +{
22906 +       return dx_migrate_task(current, tag & 0xFFFF);
22907 +}
22908 +
22909 +
22910 diff -NurpP --minimal linux-3.18.5/kernel/vserver/vci_config.h linux-3.18.5-vs2.3.7.3/kernel/vserver/vci_config.h
22911 --- linux-3.18.5/kernel/vserver/vci_config.h    1970-01-01 00:00:00.000000000 +0000
22912 +++ linux-3.18.5-vs2.3.7.3/kernel/vserver/vci_config.h  2015-01-19 10:58:31.000000000 +0000
22913 @@ -0,0 +1,80 @@
22914 +
22915 +/*  interface version */
22916 +
22917 +#define VCI_VERSION            0x00020308
22918 +
22919 +
22920 +enum {
22921 +       VCI_KCBIT_NO_DYNAMIC = 0,
22922 +
22923 +       VCI_KCBIT_PROC_SECURE = 4,
22924 +       /* VCI_KCBIT_HARDCPU = 5, */
22925 +       /* VCI_KCBIT_IDLELIMIT = 6, */
22926 +       /* VCI_KCBIT_IDLETIME = 7, */
22927 +
22928 +       VCI_KCBIT_COWBL = 8,
22929 +       VCI_KCBIT_FULLCOWBL = 9,
22930 +       VCI_KCBIT_SPACES = 10,
22931 +       VCI_KCBIT_NETV2 = 11,
22932 +       VCI_KCBIT_MEMCG = 12,
22933 +       VCI_KCBIT_MEMCG_SWAP = 13,
22934 +
22935 +       VCI_KCBIT_DEBUG = 16,
22936 +       VCI_KCBIT_HISTORY = 20,
22937 +       VCI_KCBIT_TAGGED = 24,
22938 +       VCI_KCBIT_PPTAG = 28,
22939 +
22940 +       VCI_KCBIT_MORE = 31,
22941 +};
22942 +
22943 +
22944 +static inline uint32_t vci_kernel_config(void)
22945 +{
22946 +       return
22947 +       (1 << VCI_KCBIT_NO_DYNAMIC) |
22948 +
22949 +       /* configured features */
22950 +#ifdef CONFIG_VSERVER_PROC_SECURE
22951 +       (1 << VCI_KCBIT_PROC_SECURE) |
22952 +#endif
22953 +#ifdef CONFIG_VSERVER_COWBL
22954 +       (1 << VCI_KCBIT_COWBL) |
22955 +       (1 << VCI_KCBIT_FULLCOWBL) |
22956 +#endif
22957 +       (1 << VCI_KCBIT_SPACES) |
22958 +       (1 << VCI_KCBIT_NETV2) |
22959 +#ifdef CONFIG_MEMCG
22960 +       (1 << VCI_KCBIT_MEMCG) |
22961 +#endif
22962 +#ifdef CONFIG_MEMCG_SWAP
22963 +       (1 << VCI_KCBIT_MEMCG_SWAP) |
22964 +#endif
22965 +
22966 +       /* debug options */
22967 +#ifdef CONFIG_VSERVER_DEBUG
22968 +       (1 << VCI_KCBIT_DEBUG) |
22969 +#endif
22970 +#ifdef CONFIG_VSERVER_HISTORY
22971 +       (1 << VCI_KCBIT_HISTORY) |
22972 +#endif
22973 +
22974 +       /* inode context tagging */
22975 +#if    defined(CONFIG_TAGGING_NONE)
22976 +       (0 << VCI_KCBIT_TAGGED) |
22977 +#elif  defined(CONFIG_TAGGING_UID16)
22978 +       (1 << VCI_KCBIT_TAGGED) |
22979 +#elif  defined(CONFIG_TAGGING_GID16)
22980 +       (2 << VCI_KCBIT_TAGGED) |
22981 +#elif  defined(CONFIG_TAGGING_ID24)
22982 +       (3 << VCI_KCBIT_TAGGED) |
22983 +#elif  defined(CONFIG_TAGGING_INTERN)
22984 +       (4 << VCI_KCBIT_TAGGED) |
22985 +#elif  defined(CONFIG_TAGGING_RUNTIME)
22986 +       (5 << VCI_KCBIT_TAGGED) |
22987 +#else
22988 +       (7 << VCI_KCBIT_TAGGED) |
22989 +#endif
22990 +       (1 << VCI_KCBIT_PPTAG) |
22991 +       0;
22992 +}
22993 +
22994 diff -NurpP --minimal linux-3.18.5/mm/memcontrol.c linux-3.18.5-vs2.3.7.3/mm/memcontrol.c
22995 --- linux-3.18.5/mm/memcontrol.c        2015-01-17 02:40:24.000000000 +0000
22996 +++ linux-3.18.5-vs2.3.7.3/mm/memcontrol.c      2015-01-19 11:03:45.000000000 +0000
22997 @@ -2653,6 +2653,31 @@ static struct mem_cgroup *mem_cgroup_loo
22998         return mem_cgroup_from_id(id);
22999  }
23000  
23001 +u64 mem_cgroup_res_read_u64(struct mem_cgroup *mem, int member)
23002 +{
23003 +       return res_counter_read_u64(&mem->res, member);
23004 +}
23005 +
23006 +u64 mem_cgroup_memsw_read_u64(struct mem_cgroup *mem, int member)
23007 +{
23008 +       return res_counter_read_u64(&mem->memsw, member);
23009 +}
23010 +
23011 +s64 mem_cgroup_stat_read_cache(struct mem_cgroup *mem)
23012 +{
23013 +       return mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_CACHE);
23014 +}
23015 +
23016 +s64 mem_cgroup_stat_read_anon(struct mem_cgroup *mem)
23017 +{
23018 +       return mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_RSS);
23019 +}
23020 +
23021 +s64 mem_cgroup_stat_read_mapped(struct mem_cgroup *mem)
23022 +{
23023 +       return mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_FILE_MAPPED);
23024 +}
23025 +
23026  /*
23027   * try_get_mem_cgroup_from_page - look up page's memcg association
23028   * @page: the page
23029 diff -NurpP --minimal linux-3.18.5/mm/oom_kill.c linux-3.18.5-vs2.3.7.3/mm/oom_kill.c
23030 --- linux-3.18.5/mm/oom_kill.c  2015-01-17 02:40:24.000000000 +0000
23031 +++ linux-3.18.5-vs2.3.7.3/mm/oom_kill.c        2015-01-19 10:58:31.000000000 +0000
23032 @@ -35,6 +35,8 @@
23033  #include <linux/freezer.h>
23034  #include <linux/ftrace.h>
23035  #include <linux/ratelimit.h>
23036 +#include <linux/reboot.h>
23037 +#include <linux/vs_context.h>
23038  
23039  #define CREATE_TRACE_POINTS
23040  #include <trace/events/oom.h>
23041 @@ -121,11 +123,18 @@ found:
23042  static bool oom_unkillable_task(struct task_struct *p,
23043                 const struct mem_cgroup *memcg, const nodemask_t *nodemask)
23044  {
23045 -       if (is_global_init(p))
23046 +       unsigned xid = vx_current_xid();
23047 +
23048 +       /* skip the init task, global and per guest */
23049 +       if (task_is_init(p))
23050                 return true;
23051         if (p->flags & PF_KTHREAD)
23052                 return true;
23053  
23054 +       /* skip other guest and host processes if oom in guest */
23055 +       if (xid && vx_task_xid(p) != xid)
23056 +               return true;
23057 +
23058         /* When mem_cgroup_out_of_memory() and p is not member of the group */
23059         if (memcg && !task_in_mem_cgroup(p, memcg))
23060                 return true;
23061 @@ -453,8 +462,8 @@ void oom_kill_process(struct task_struct
23062                 dump_header(p, gfp_mask, order, memcg, nodemask);
23063  
23064         task_lock(p);
23065 -       pr_err("%s: Kill process %d (%s) score %d or sacrifice child\n",
23066 -               message, task_pid_nr(p), p->comm, points);
23067 +       pr_err("%s: Kill process %d:#%u (%s) score %d or sacrifice child\n",
23068 +               message, task_pid_nr(p), p->xid, p->comm, points);
23069         task_unlock(p);
23070  
23071         /*
23072 @@ -497,8 +506,8 @@ void oom_kill_process(struct task_struct
23073  
23074         /* mm cannot safely be dereferenced after task_unlock(victim) */
23075         mm = victim->mm;
23076 -       pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
23077 -               task_pid_nr(victim), victim->comm, K(victim->mm->total_vm),
23078 +       pr_err("Killed process %d:#%u (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
23079 +               task_pid_nr(victim), victim->xid, victim->comm, K(victim->mm->total_vm),
23080                 K(get_mm_counter(victim->mm, MM_ANONPAGES)),
23081                 K(get_mm_counter(victim->mm, MM_FILEPAGES)));
23082         task_unlock(victim);
23083 @@ -569,6 +578,8 @@ int unregister_oom_notifier(struct notif
23084  }
23085  EXPORT_SYMBOL_GPL(unregister_oom_notifier);
23086  
23087 +long vs_oom_action(unsigned int);
23088 +
23089  /*
23090   * Try to acquire the OOM killer lock for the zones in zonelist.  Returns zero
23091   * if a parallel OOM killing is already taking place that includes a zone in
23092 @@ -677,7 +688,12 @@ void out_of_memory(struct zonelist *zone
23093         /* Found nothing?!?! Either we hang forever, or we panic. */
23094         if (!p) {
23095                 dump_header(NULL, gfp_mask, order, NULL, mpol_mask);
23096 -               panic("Out of memory and no killable processes...\n");
23097 +
23098 +               /* avoid panic for guest OOM */
23099 +               if (vx_current_xid())
23100 +                       vs_oom_action(LINUX_REBOOT_CMD_OOM);
23101 +               else
23102 +                       panic("Out of memory and no killable processes...\n");
23103         }
23104         if (p != (void *)-1UL) {
23105                 oom_kill_process(p, gfp_mask, order, points, totalpages, NULL,
23106 diff -NurpP --minimal linux-3.18.5/mm/page_alloc.c linux-3.18.5-vs2.3.7.3/mm/page_alloc.c
23107 --- linux-3.18.5/mm/page_alloc.c        2015-01-17 02:40:24.000000000 +0000
23108 +++ linux-3.18.5-vs2.3.7.3/mm/page_alloc.c      2015-01-19 10:58:31.000000000 +0000
23109 @@ -59,6 +59,8 @@
23110  #include <linux/page-debug-flags.h>
23111  #include <linux/hugetlb.h>
23112  #include <linux/sched/rt.h>
23113 +#include <linux/vs_base.h>
23114 +#include <linux/vs_limit.h>
23115  
23116  #include <asm/sections.h>
23117  #include <asm/tlbflush.h>
23118 @@ -3096,6 +3098,9 @@ void si_meminfo(struct sysinfo *val)
23119         val->totalhigh = totalhigh_pages;
23120         val->freehigh = nr_free_highpages();
23121         val->mem_unit = PAGE_SIZE;
23122 +
23123 +       if (vx_flags(VXF_VIRT_MEM, 0))
23124 +               vx_vsi_meminfo(val);
23125  }
23126  
23127  EXPORT_SYMBOL(si_meminfo);
23128 @@ -3121,6 +3126,9 @@ void si_meminfo_node(struct sysinfo *val
23129         val->freehigh = 0;
23130  #endif
23131         val->mem_unit = PAGE_SIZE;
23132 +
23133 +       if (vx_flags(VXF_VIRT_MEM, 0))
23134 +               vx_vsi_meminfo(val);
23135  }
23136  #endif
23137  
23138 diff -NurpP --minimal linux-3.18.5/mm/pgtable-generic.c linux-3.18.5-vs2.3.7.3/mm/pgtable-generic.c
23139 --- linux-3.18.5/mm/pgtable-generic.c   2015-01-16 22:19:29.000000000 +0000
23140 +++ linux-3.18.5-vs2.3.7.3/mm/pgtable-generic.c 2015-01-19 10:58:31.000000000 +0000
23141 @@ -6,6 +6,8 @@
23142   *  Copyright (C) 2010  Linus Torvalds
23143   */
23144  
23145 +#include <linux/mm.h>
23146 +
23147  #include <linux/pagemap.h>
23148  #include <asm/tlb.h>
23149  #include <asm-generic/pgtable.h>
23150 diff -NurpP --minimal linux-3.18.5/mm/shmem.c linux-3.18.5-vs2.3.7.3/mm/shmem.c
23151 --- linux-3.18.5/mm/shmem.c     2015-01-17 02:40:24.000000000 +0000
23152 +++ linux-3.18.5-vs2.3.7.3/mm/shmem.c   2015-01-19 10:58:31.000000000 +0000
23153 @@ -2183,7 +2183,7 @@ static int shmem_statfs(struct dentry *d
23154  {
23155         struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
23156  
23157 -       buf->f_type = TMPFS_MAGIC;
23158 +       buf->f_type = TMPFS_SUPER_MAGIC;
23159         buf->f_bsize = PAGE_CACHE_SIZE;
23160         buf->f_namelen = NAME_MAX;
23161         if (sbinfo->max_blocks) {
23162 @@ -3036,7 +3036,7 @@ int shmem_fill_super(struct super_block
23163         sb->s_maxbytes = MAX_LFS_FILESIZE;
23164         sb->s_blocksize = PAGE_CACHE_SIZE;
23165         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
23166 -       sb->s_magic = TMPFS_MAGIC;
23167 +       sb->s_magic = TMPFS_SUPER_MAGIC;
23168         sb->s_op = &shmem_ops;
23169         sb->s_time_gran = 1;
23170  #ifdef CONFIG_TMPFS_XATTR
23171 diff -NurpP --minimal linux-3.18.5/mm/slab.c linux-3.18.5-vs2.3.7.3/mm/slab.c
23172 --- linux-3.18.5/mm/slab.c      2015-01-17 02:40:24.000000000 +0000
23173 +++ linux-3.18.5-vs2.3.7.3/mm/slab.c    2015-01-19 10:58:31.000000000 +0000
23174 @@ -336,6 +336,8 @@ static void kmem_cache_node_init(struct
23175  #define STATS_INC_FREEMISS(x)  do { } while (0)
23176  #endif
23177  
23178 +#include "slab_vs.h"
23179 +
23180  #if DEBUG
23181  
23182  /*
23183 @@ -3168,6 +3170,7 @@ slab_alloc_node(struct kmem_cache *cache
23184         /* ___cache_alloc_node can fall back to other nodes */
23185         ptr = ____cache_alloc_node(cachep, flags, nodeid);
23186    out:
23187 +       vx_slab_alloc(cachep, flags);
23188         local_irq_restore(save_flags);
23189         ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller);
23190         kmemleak_alloc_recursive(ptr, cachep->object_size, 1, cachep->flags,
23191 @@ -3354,6 +3357,7 @@ static inline void __cache_free(struct k
23192         check_irq_off();
23193         kmemleak_free_recursive(objp, cachep->flags);
23194         objp = cache_free_debugcheck(cachep, objp, caller);
23195 +       vx_slab_free(cachep);
23196  
23197         kmemcheck_slab_free(cachep, objp, cachep->object_size);
23198  
23199 diff -NurpP --minimal linux-3.18.5/mm/slab_vs.h linux-3.18.5-vs2.3.7.3/mm/slab_vs.h
23200 --- linux-3.18.5/mm/slab_vs.h   1970-01-01 00:00:00.000000000 +0000
23201 +++ linux-3.18.5-vs2.3.7.3/mm/slab_vs.h 2015-01-19 10:58:31.000000000 +0000
23202 @@ -0,0 +1,29 @@
23203 +
23204 +#include <linux/vserver/context.h>
23205 +
23206 +#include <linux/vs_context.h>
23207 +
23208 +static inline
23209 +void vx_slab_alloc(struct kmem_cache *cachep, gfp_t flags)
23210 +{
23211 +       int what = gfp_zone(cachep->allocflags);
23212 +       struct vx_info *vxi = current_vx_info();
23213 +
23214 +       if (!vxi)
23215 +               return;
23216 +
23217 +       atomic_add(cachep->size, &vxi->cacct.slab[what]);
23218 +}
23219 +
23220 +static inline
23221 +void vx_slab_free(struct kmem_cache *cachep)
23222 +{
23223 +       int what = gfp_zone(cachep->allocflags);
23224 +       struct vx_info *vxi = current_vx_info();
23225 +
23226 +       if (!vxi)
23227 +               return;
23228 +
23229 +       atomic_sub(cachep->size, &vxi->cacct.slab[what]);
23230 +}
23231 +
23232 diff -NurpP --minimal linux-3.18.5/mm/swapfile.c linux-3.18.5-vs2.3.7.3/mm/swapfile.c
23233 --- linux-3.18.5/mm/swapfile.c  2015-01-16 22:19:29.000000000 +0000
23234 +++ linux-3.18.5-vs2.3.7.3/mm/swapfile.c        2015-01-19 10:58:31.000000000 +0000
23235 @@ -39,6 +39,7 @@
23236  #include <asm/tlbflush.h>
23237  #include <linux/swapops.h>
23238  #include <linux/page_cgroup.h>
23239 +#include <linux/vs_base.h>
23240  
23241  static bool swap_count_continued(struct swap_info_struct *, pgoff_t,
23242                                  unsigned char);
23243 @@ -2028,6 +2029,16 @@ static int swap_show(struct seq_file *sw
23244  
23245         if (si == SEQ_START_TOKEN) {
23246                 seq_puts(swap,"Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
23247 +               if (vx_flags(VXF_VIRT_MEM, 0)) {
23248 +                       struct sysinfo si;
23249 +
23250 +                       vx_vsi_swapinfo(&si);
23251 +                       if (si.totalswap < (1 << 10))
23252 +                               return 0;
23253 +                       seq_printf(swap, "%s\t\t\t\t\t%s\t%lu\t%lu\t%d\n",
23254 +                               "hdv0", "partition", si.totalswap >> 10,
23255 +                               (si.totalswap - si.freeswap) >> 10, -1);
23256 +               }
23257                 return 0;
23258         }
23259  
23260 @@ -2576,6 +2587,8 @@ void si_swapinfo(struct sysinfo *val)
23261         val->freeswap = atomic_long_read(&nr_swap_pages) + nr_to_be_unused;
23262         val->totalswap = total_swap_pages + nr_to_be_unused;
23263         spin_unlock(&swap_lock);
23264 +       if (vx_flags(VXF_VIRT_MEM, 0))
23265 +               vx_vsi_swapinfo(val);
23266  }
23267  
23268  /*
23269 diff -NurpP --minimal linux-3.18.5/net/bridge/br_multicast.c linux-3.18.5-vs2.3.7.3/net/bridge/br_multicast.c
23270 --- linux-3.18.5/net/bridge/br_multicast.c      2015-01-17 02:40:24.000000000 +0000
23271 +++ linux-3.18.5-vs2.3.7.3/net/bridge/br_multicast.c    2015-01-19 10:58:31.000000000 +0000
23272 @@ -448,7 +448,7 @@ static struct sk_buff *br_ip6_multicast_
23273         ip6h->hop_limit = 1;
23274         ipv6_addr_set(&ip6h->daddr, htonl(0xff020000), 0, 0, htonl(1));
23275         if (ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0,
23276 -                              &ip6h->saddr)) {
23277 +                              &ip6h->saddr, NULL)) {
23278                 kfree_skb(skb);
23279                 return NULL;
23280         }
23281 diff -NurpP --minimal linux-3.18.5/net/core/dev.c linux-3.18.5-vs2.3.7.3/net/core/dev.c
23282 --- linux-3.18.5/net/core/dev.c 2015-02-05 18:02:46.000000000 +0000
23283 +++ linux-3.18.5-vs2.3.7.3/net/core/dev.c       2015-01-28 11:48:02.000000000 +0000
23284 @@ -122,6 +122,7 @@
23285  #include <linux/in.h>
23286  #include <linux/jhash.h>
23287  #include <linux/random.h>
23288 +#include <linux/vs_inet.h>
23289  #include <trace/events/napi.h>
23290  #include <trace/events/net.h>
23291  #include <trace/events/skb.h>
23292 @@ -674,7 +675,8 @@ struct net_device *__dev_get_by_name(str
23293         struct hlist_head *head = dev_name_hash(net, name);
23294  
23295         hlist_for_each_entry(dev, head, name_hlist)
23296 -               if (!strncmp(dev->name, name, IFNAMSIZ))
23297 +               if (!strncmp(dev->name, name, IFNAMSIZ) &&
23298 +                   nx_dev_visible(current_nx_info(), dev))
23299                         return dev;
23300  
23301         return NULL;
23302 @@ -699,7 +701,8 @@ struct net_device *dev_get_by_name_rcu(s
23303         struct hlist_head *head = dev_name_hash(net, name);
23304  
23305         hlist_for_each_entry_rcu(dev, head, name_hlist)
23306 -               if (!strncmp(dev->name, name, IFNAMSIZ))
23307 +               if (!strncmp(dev->name, name, IFNAMSIZ) &&
23308 +                   nx_dev_visible(current_nx_info(), dev))
23309                         return dev;
23310  
23311         return NULL;
23312 @@ -749,7 +752,8 @@ struct net_device *__dev_get_by_index(st
23313         struct hlist_head *head = dev_index_hash(net, ifindex);
23314  
23315         hlist_for_each_entry(dev, head, index_hlist)
23316 -               if (dev->ifindex == ifindex)
23317 +               if ((dev->ifindex == ifindex) &&
23318 +                   nx_dev_visible(current_nx_info(), dev))
23319                         return dev;
23320  
23321         return NULL;
23322 @@ -767,7 +771,7 @@ EXPORT_SYMBOL(__dev_get_by_index);
23323   *     about locking. The caller must hold RCU lock.
23324   */
23325  
23326 -struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
23327 +struct net_device *dev_get_by_index_real_rcu(struct net *net, int ifindex)
23328  {
23329         struct net_device *dev;
23330         struct hlist_head *head = dev_index_hash(net, ifindex);
23331 @@ -778,6 +782,16 @@ struct net_device *dev_get_by_index_rcu(
23332  
23333         return NULL;
23334  }
23335 +EXPORT_SYMBOL(dev_get_by_index_real_rcu);
23336 +
23337 +struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
23338 +{
23339 +       struct net_device *dev = dev_get_by_index_real_rcu(net, ifindex);
23340 +
23341 +       if (nx_dev_visible(current_nx_info(), dev))
23342 +               return dev;
23343 +       return NULL;
23344 +}
23345  EXPORT_SYMBOL(dev_get_by_index_rcu);
23346  
23347  
23348 @@ -860,7 +874,8 @@ struct net_device *dev_getbyhwaddr_rcu(s
23349  
23350         for_each_netdev_rcu(net, dev)
23351                 if (dev->type == type &&
23352 -                   !memcmp(dev->dev_addr, ha, dev->addr_len))
23353 +                   !memcmp(dev->dev_addr, ha, dev->addr_len) &&
23354 +                   nx_dev_visible(current_nx_info(), dev))
23355                         return dev;
23356  
23357         return NULL;
23358 @@ -872,9 +887,11 @@ struct net_device *__dev_getfirstbyhwtyp
23359         struct net_device *dev;
23360  
23361         ASSERT_RTNL();
23362 -       for_each_netdev(net, dev)
23363 -               if (dev->type == type)
23364 +       for_each_netdev(net, dev) {
23365 +               if ((dev->type == type) &&
23366 +                   nx_dev_visible(current_nx_info(), dev))
23367                         return dev;
23368 +       }
23369  
23370         return NULL;
23371  }
23372 @@ -886,7 +903,8 @@ struct net_device *dev_getfirstbyhwtype(
23373  
23374         rcu_read_lock();
23375         for_each_netdev_rcu(net, dev)
23376 -               if (dev->type == type) {
23377 +               if ((dev->type == type) &&
23378 +                   nx_dev_visible(current_nx_info(), dev)) {
23379                         dev_hold(dev);
23380                         ret = dev;
23381                         break;
23382 @@ -916,7 +934,8 @@ struct net_device *__dev_get_by_flags(st
23383  
23384         ret = NULL;
23385         for_each_netdev(net, dev) {
23386 -               if (((dev->flags ^ if_flags) & mask) == 0) {
23387 +               if ((((dev->flags ^ if_flags) & mask) == 0) &&
23388 +                       nx_dev_visible(current_nx_info(), dev)) {
23389                         ret = dev;
23390                         break;
23391                 }
23392 @@ -994,6 +1013,8 @@ static int __dev_alloc_name(struct net *
23393                                 continue;
23394                         if (i < 0 || i >= max_netdevices)
23395                                 continue;
23396 +                       if (!nx_dev_visible(current_nx_info(), d))
23397 +                               continue;
23398  
23399                         /*  avoid cases where sscanf is not exact inverse of printf */
23400                         snprintf(buf, IFNAMSIZ, name, i);
23401 diff -NurpP --minimal linux-3.18.5/net/core/net-procfs.c linux-3.18.5-vs2.3.7.3/net/core/net-procfs.c
23402 --- linux-3.18.5/net/core/net-procfs.c  2013-11-25 15:45:09.000000000 +0000
23403 +++ linux-3.18.5-vs2.3.7.3/net/core/net-procfs.c        2015-01-19 10:58:31.000000000 +0000
23404 @@ -1,6 +1,7 @@
23405  #include <linux/netdevice.h>
23406  #include <linux/proc_fs.h>
23407  #include <linux/seq_file.h>
23408 +#include <linux/vs_inet.h>
23409  #include <net/wext.h>
23410  
23411  #define BUCKET_SPACE (32 - NETDEV_HASHBITS - 1)
23412 @@ -77,8 +78,13 @@ static void dev_seq_stop(struct seq_file
23413  static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
23414  {
23415         struct rtnl_link_stats64 temp;
23416 -       const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);
23417 +       const struct rtnl_link_stats64 *stats;
23418 +
23419 +       /* device visible inside network context? */
23420 +       if (!nx_dev_visible(current_nx_info(), dev))
23421 +               return;
23422  
23423 +       stats = dev_get_stats(dev, &temp);
23424         seq_printf(seq, "%6s: %7llu %7llu %4llu %4llu %4llu %5llu %10llu %9llu "
23425                    "%8llu %7llu %4llu %4llu %4llu %5llu %7llu %10llu\n",
23426                    dev->name, stats->rx_bytes, stats->rx_packets,
23427 diff -NurpP --minimal linux-3.18.5/net/core/rtnetlink.c linux-3.18.5-vs2.3.7.3/net/core/rtnetlink.c
23428 --- linux-3.18.5/net/core/rtnetlink.c   2015-01-17 02:40:24.000000000 +0000
23429 +++ linux-3.18.5-vs2.3.7.3/net/core/rtnetlink.c 2015-01-19 10:58:31.000000000 +0000
23430 @@ -1280,6 +1280,8 @@ static int rtnl_dump_ifinfo(struct sk_bu
23431                 hlist_for_each_entry_rcu(dev, head, index_hlist) {
23432                         if (idx < s_idx)
23433                                 goto cont;
23434 +                       if (!nx_dev_visible(skb->sk->sk_nx_info, dev))
23435 +                               continue;
23436                         err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
23437                                                NETLINK_CB(cb->skb).portid,
23438                                                cb->nlh->nlmsg_seq, 0,
23439 @@ -2229,6 +2231,9 @@ void rtmsg_ifinfo(int type, struct net_d
23440         int err = -ENOBUFS;
23441         size_t if_info_size;
23442  
23443 +       if (!nx_dev_visible(current_nx_info(), dev))
23444 +               return;
23445 +
23446         skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), flags);
23447         if (skb == NULL)
23448                 goto errout;
23449 diff -NurpP --minimal linux-3.18.5/net/core/sock.c linux-3.18.5-vs2.3.7.3/net/core/sock.c
23450 --- linux-3.18.5/net/core/sock.c        2015-01-17 02:40:24.000000000 +0000
23451 +++ linux-3.18.5-vs2.3.7.3/net/core/sock.c      2015-01-19 10:58:31.000000000 +0000
23452 @@ -133,6 +133,10 @@
23453  #include <net/netprio_cgroup.h>
23454  
23455  #include <linux/filter.h>
23456 +#include <linux/vs_socket.h>
23457 +#include <linux/vs_limit.h>
23458 +#include <linux/vs_context.h>
23459 +#include <linux/vs_network.h>
23460  
23461  #include <trace/events/sock.h>
23462  
23463 @@ -1310,6 +1314,8 @@ static struct sock *sk_prot_alloc(struct
23464                         goto out_free_sec;
23465                 sk_tx_queue_clear(sk);
23466         }
23467 +               sock_vx_init(sk);
23468 +               sock_nx_init(sk);
23469  
23470         return sk;
23471  
23472 @@ -1406,6 +1412,11 @@ static void __sk_free(struct sock *sk)
23473                 put_cred(sk->sk_peer_cred);
23474         put_pid(sk->sk_peer_pid);
23475         put_net(sock_net(sk));
23476 +       vx_sock_dec(sk);
23477 +       clr_vx_info(&sk->sk_vx_info);
23478 +       sk->sk_xid = -1;
23479 +       clr_nx_info(&sk->sk_nx_info);
23480 +       sk->sk_nid = -1;
23481         sk_prot_free(sk->sk_prot_creator, sk);
23482  }
23483  
23484 @@ -1467,6 +1478,8 @@ struct sock *sk_clone_lock(const struct
23485  
23486                 /* SANITY */
23487                 get_net(sock_net(newsk));
23488 +               sock_vx_init(newsk);
23489 +               sock_nx_init(newsk);
23490                 sk_node_init(&newsk->sk_node);
23491                 sock_lock_init(newsk);
23492                 bh_lock_sock(newsk);
23493 @@ -1524,6 +1537,12 @@ struct sock *sk_clone_lock(const struct
23494                 smp_wmb();
23495                 atomic_set(&newsk->sk_refcnt, 2);
23496  
23497 +               set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info);
23498 +               newsk->sk_xid = sk->sk_xid;
23499 +               vx_sock_inc(newsk);
23500 +               set_nx_info(&newsk->sk_nx_info, sk->sk_nx_info);
23501 +               newsk->sk_nid = sk->sk_nid;
23502 +
23503                 /*
23504                  * Increment the counter in the same struct proto as the master
23505                  * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
23506 @@ -2302,6 +2321,12 @@ void sock_init_data(struct socket *sock,
23507  
23508         sk->sk_stamp = ktime_set(-1L, 0);
23509  
23510 +       set_vx_info(&sk->sk_vx_info, current_vx_info());
23511 +       sk->sk_xid = vx_current_xid();
23512 +       vx_sock_inc(sk);
23513 +       set_nx_info(&sk->sk_nx_info, current_nx_info());
23514 +       sk->sk_nid = nx_current_nid();
23515 +
23516  #ifdef CONFIG_NET_RX_BUSY_POLL
23517         sk->sk_napi_id          =       0;
23518         sk->sk_ll_usec          =       sysctl_net_busy_read;
23519 diff -NurpP --minimal linux-3.18.5/net/ipv4/af_inet.c linux-3.18.5-vs2.3.7.3/net/ipv4/af_inet.c
23520 --- linux-3.18.5/net/ipv4/af_inet.c     2015-01-17 02:40:24.000000000 +0000
23521 +++ linux-3.18.5-vs2.3.7.3/net/ipv4/af_inet.c   2015-01-19 10:58:31.000000000 +0000
23522 @@ -118,6 +118,7 @@
23523  #ifdef CONFIG_IP_MROUTE
23524  #include <linux/mroute.h>
23525  #endif
23526 +#include <linux/vs_limit.h>
23527  
23528  
23529  /* The inetsw table contains everything that inet_create needs to
23530 @@ -305,10 +306,13 @@ lookup_protocol:
23531         }
23532  
23533         err = -EPERM;
23534 +       if ((protocol == IPPROTO_ICMP) &&
23535 +               nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
23536 +               goto override;
23537         if (sock->type == SOCK_RAW && !kern &&
23538             !ns_capable(net->user_ns, CAP_NET_RAW))
23539                 goto out_rcu_unlock;
23540 -
23541 +override:
23542         sock->ops = answer->ops;
23543         answer_prot = answer->prot;
23544         answer_flags = answer->flags;
23545 @@ -423,6 +427,7 @@ int inet_bind(struct socket *sock, struc
23546         struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
23547         struct sock *sk = sock->sk;
23548         struct inet_sock *inet = inet_sk(sk);
23549 +       struct nx_v4_sock_addr nsa;
23550         struct net *net = sock_net(sk);
23551         unsigned short snum;
23552         int chk_addr_ret;
23553 @@ -447,7 +452,11 @@ int inet_bind(struct socket *sock, struc
23554                         goto out;
23555         }
23556  
23557 -       chk_addr_ret = inet_addr_type(net, addr->sin_addr.s_addr);
23558 +       err = v4_map_sock_addr(inet, addr, &nsa);
23559 +       if (err)
23560 +               goto out;
23561 +
23562 +       chk_addr_ret = inet_addr_type(net, nsa.saddr);
23563  
23564         /* Not specified by any standard per-se, however it breaks too
23565          * many applications when removed.  It is unfortunate since
23566 @@ -459,7 +468,7 @@ int inet_bind(struct socket *sock, struc
23567         err = -EADDRNOTAVAIL;
23568         if (!net->ipv4.sysctl_ip_nonlocal_bind &&
23569             !(inet->freebind || inet->transparent) &&
23570 -           addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
23571 +           nsa.saddr != htonl(INADDR_ANY) &&
23572             chk_addr_ret != RTN_LOCAL &&
23573             chk_addr_ret != RTN_MULTICAST &&
23574             chk_addr_ret != RTN_BROADCAST)
23575 @@ -485,7 +494,7 @@ int inet_bind(struct socket *sock, struc
23576         if (sk->sk_state != TCP_CLOSE || inet->inet_num)
23577                 goto out_release_sock;
23578  
23579 -       inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
23580 +       v4_set_sock_addr(inet, &nsa);
23581         if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
23582                 inet->inet_saddr = 0;  /* Use device */
23583  
23584 @@ -704,11 +713,13 @@ int inet_getname(struct socket *sock, st
23585                      peer == 1))
23586                         return -ENOTCONN;
23587                 sin->sin_port = inet->inet_dport;
23588 -               sin->sin_addr.s_addr = inet->inet_daddr;
23589 +               sin->sin_addr.s_addr =
23590 +                       nx_map_sock_lback(sk->sk_nx_info, inet->inet_daddr);
23591         } else {
23592                 __be32 addr = inet->inet_rcv_saddr;
23593                 if (!addr)
23594                         addr = inet->inet_saddr;
23595 +               addr = nx_map_sock_lback(sk->sk_nx_info, addr);
23596                 sin->sin_port = inet->inet_sport;
23597                 sin->sin_addr.s_addr = addr;
23598         }
23599 diff -NurpP --minimal linux-3.18.5/net/ipv4/arp.c linux-3.18.5-vs2.3.7.3/net/ipv4/arp.c
23600 --- linux-3.18.5/net/ipv4/arp.c 2015-01-17 02:40:24.000000000 +0000
23601 +++ linux-3.18.5-vs2.3.7.3/net/ipv4/arp.c       2015-01-19 10:58:31.000000000 +0000
23602 @@ -1349,6 +1349,7 @@ static void arp_format_neigh_entry(struc
23603         struct net_device *dev = n->dev;
23604         int hatype = dev->type;
23605  
23606 +       /* FIXME: check for network context */
23607         read_lock(&n->lock);
23608         /* Convert hardware address to XX:XX:XX:XX ... form. */
23609  #if IS_ENABLED(CONFIG_AX25)
23610 @@ -1380,6 +1381,7 @@ static void arp_format_pneigh_entry(stru
23611         int hatype = dev ? dev->type : 0;
23612         char tbuf[16];
23613  
23614 +       /* FIXME: check for network context */
23615         sprintf(tbuf, "%pI4", n->key);
23616         seq_printf(seq, "%-16s 0x%-10x0x%-10x%s     *        %s\n",
23617                    tbuf, hatype, ATF_PUBL | ATF_PERM, "00:00:00:00:00:00",
23618 diff -NurpP --minimal linux-3.18.5/net/ipv4/devinet.c linux-3.18.5-vs2.3.7.3/net/ipv4/devinet.c
23619 --- linux-3.18.5/net/ipv4/devinet.c     2015-01-16 22:19:30.000000000 +0000
23620 +++ linux-3.18.5-vs2.3.7.3/net/ipv4/devinet.c   2015-01-19 10:58:31.000000000 +0000
23621 @@ -534,6 +534,7 @@ struct in_device *inetdev_by_index(struc
23622  }
23623  EXPORT_SYMBOL(inetdev_by_index);
23624  
23625 +
23626  /* Called only from RTNL semaphored context. No locks. */
23627  
23628  struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
23629 @@ -958,6 +959,8 @@ int devinet_ioctl(struct net *net, unsig
23630  
23631         in_dev = __in_dev_get_rtnl(dev);
23632         if (in_dev) {
23633 +               struct nx_info *nxi = current_nx_info();
23634 +
23635                 if (tryaddrmatch) {
23636                         /* Matthias Andree */
23637                         /* compare label and address (4.4BSD style) */
23638 @@ -966,6 +969,8 @@ int devinet_ioctl(struct net *net, unsig
23639                            This is checked above. */
23640                         for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
23641                              ifap = &ifa->ifa_next) {
23642 +                               if (!nx_v4_ifa_visible(nxi, ifa))
23643 +                                       continue;
23644                                 if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
23645                                     sin_orig.sin_addr.s_addr ==
23646                                                         ifa->ifa_local) {
23647 @@ -978,9 +983,12 @@ int devinet_ioctl(struct net *net, unsig
23648                    comparing just the label */
23649                 if (!ifa) {
23650                         for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
23651 -                            ifap = &ifa->ifa_next)
23652 +                            ifap = &ifa->ifa_next) {
23653 +                               if (!nx_v4_ifa_visible(nxi, ifa))
23654 +                                       continue;
23655                                 if (!strcmp(ifr.ifr_name, ifa->ifa_label))
23656                                         break;
23657 +                       }
23658                 }
23659         }
23660  
23661 @@ -1134,6 +1142,8 @@ static int inet_gifconf(struct net_devic
23662                 goto out;
23663  
23664         for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
23665 +               if (!nx_v4_ifa_visible(current_nx_info(), ifa))
23666 +                       continue;
23667                 if (!buf) {
23668                         done += sizeof(ifr);
23669                         continue;
23670 @@ -1538,6 +1548,7 @@ static int inet_dump_ifaddr(struct sk_bu
23671         struct net_device *dev;
23672         struct in_device *in_dev;
23673         struct in_ifaddr *ifa;
23674 +       struct sock *sk = skb->sk;
23675         struct hlist_head *head;
23676  
23677         s_h = cb->args[0];
23678 @@ -1561,6 +1572,8 @@ static int inet_dump_ifaddr(struct sk_bu
23679  
23680                         for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
23681                              ifa = ifa->ifa_next, ip_idx++) {
23682 +                       if (sk && !nx_v4_ifa_visible(sk->sk_nx_info, ifa))
23683 +                               continue;
23684                                 if (ip_idx < s_ip_idx)
23685                                         continue;
23686                                 if (inet_fill_ifaddr(skb, ifa,
23687 diff -NurpP --minimal linux-3.18.5/net/ipv4/fib_trie.c linux-3.18.5-vs2.3.7.3/net/ipv4/fib_trie.c
23688 --- linux-3.18.5/net/ipv4/fib_trie.c    2015-01-16 22:19:30.000000000 +0000
23689 +++ linux-3.18.5-vs2.3.7.3/net/ipv4/fib_trie.c  2015-01-19 10:58:31.000000000 +0000
23690 @@ -2530,6 +2530,7 @@ static int fib_route_seq_show(struct seq
23691  
23692                         seq_setwidth(seq, 127);
23693  
23694 +                       /* FIXME: check for network context? */
23695                         if (fi)
23696                                 seq_printf(seq,
23697                                          "%s\t%08X\t%08X\t%04X\t%d\t%u\t"
23698 diff -NurpP --minimal linux-3.18.5/net/ipv4/inet_connection_sock.c linux-3.18.5-vs2.3.7.3/net/ipv4/inet_connection_sock.c
23699 --- linux-3.18.5/net/ipv4/inet_connection_sock.c        2014-09-03 13:19:48.000000000 +0000
23700 +++ linux-3.18.5-vs2.3.7.3/net/ipv4/inet_connection_sock.c      2015-01-19 10:58:31.000000000 +0000
23701 @@ -42,6 +42,37 @@ void inet_get_local_port_range(struct ne
23702  }
23703  EXPORT_SYMBOL(inet_get_local_port_range);
23704  
23705 +int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
23706 +{
23707 +       __be32  sk1_rcv_saddr = sk1->sk_rcv_saddr,
23708 +               sk2_rcv_saddr = sk2->sk_rcv_saddr;
23709 +
23710 +       if (inet_v6_ipv6only(sk2))
23711 +               return 0;
23712 +
23713 +       if (sk1_rcv_saddr &&
23714 +           sk2_rcv_saddr &&
23715 +           sk1_rcv_saddr == sk2_rcv_saddr)
23716 +               return 1;
23717 +
23718 +       if (sk1_rcv_saddr &&
23719 +           !sk2_rcv_saddr &&
23720 +           v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, NXA_MASK_BIND))
23721 +               return 1;
23722 +
23723 +       if (sk2_rcv_saddr &&
23724 +           !sk1_rcv_saddr &&
23725 +           v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, NXA_MASK_BIND))
23726 +               return 1;
23727 +
23728 +       if (!sk1_rcv_saddr &&
23729 +           !sk2_rcv_saddr &&
23730 +           nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info))
23731 +               return 1;
23732 +
23733 +       return 0;
23734 +}
23735 +
23736  int inet_csk_bind_conflict(const struct sock *sk,
23737                            const struct inet_bind_bucket *tb, bool relax)
23738  {
23739 @@ -69,15 +100,13 @@ int inet_csk_bind_conflict(const struct
23740                             (sk2->sk_state != TCP_TIME_WAIT &&
23741                              !uid_eq(uid, sock_i_uid(sk2))))) {
23742  
23743 -                               if (!sk2->sk_rcv_saddr || !sk->sk_rcv_saddr ||
23744 -                                   sk2->sk_rcv_saddr == sk->sk_rcv_saddr)
23745 +                               if (ipv4_rcv_saddr_equal(sk, sk2))
23746                                         break;
23747                         }
23748                         if (!relax && reuse && sk2->sk_reuse &&
23749                             sk2->sk_state != TCP_LISTEN) {
23750  
23751 -                               if (!sk2->sk_rcv_saddr || !sk->sk_rcv_saddr ||
23752 -                                   sk2->sk_rcv_saddr == sk->sk_rcv_saddr)
23753 +                               if (ipv4_rcv_saddr_equal(sk, sk2))
23754                                         break;
23755                         }
23756                 }
23757 diff -NurpP --minimal linux-3.18.5/net/ipv4/inet_diag.c linux-3.18.5-vs2.3.7.3/net/ipv4/inet_diag.c
23758 --- linux-3.18.5/net/ipv4/inet_diag.c   2014-02-01 02:17:51.000000000 +0000
23759 +++ linux-3.18.5-vs2.3.7.3/net/ipv4/inet_diag.c 2015-01-19 10:58:31.000000000 +0000
23760 @@ -31,6 +31,8 @@
23761  
23762  #include <linux/inet.h>
23763  #include <linux/stddef.h>
23764 +#include <linux/vs_network.h>
23765 +#include <linux/vs_inet.h>
23766  
23767  #include <linux/inet_diag.h>
23768  #include <linux/sock_diag.h>
23769 @@ -110,8 +112,10 @@ int inet_sk_diag_fill(struct sock *sk, s
23770         memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
23771         memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
23772  
23773 -       r->id.idiag_src[0] = inet->inet_rcv_saddr;
23774 -       r->id.idiag_dst[0] = inet->inet_daddr;
23775 +       r->id.idiag_src[0] = nx_map_sock_lback(sk->sk_nx_info,
23776 +               inet->inet_rcv_saddr);
23777 +       r->id.idiag_dst[0] = nx_map_sock_lback(sk->sk_nx_info,
23778 +               inet->inet_daddr);
23779  
23780         if (nla_put_u8(skb, INET_DIAG_SHUTDOWN, sk->sk_shutdown))
23781                 goto errout;
23782 @@ -254,8 +258,8 @@ static int inet_twsk_diag_fill(struct in
23783         memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
23784         memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
23785  
23786 -       r->id.idiag_src[0]    = tw->tw_rcv_saddr;
23787 -       r->id.idiag_dst[0]    = tw->tw_daddr;
23788 +       r->id.idiag_src[0]    = nx_map_sock_lback(tw->tw_nx_info, tw->tw_rcv_saddr);
23789 +       r->id.idiag_dst[0]    = nx_map_sock_lback(tw->tw_nx_info, tw->tw_daddr);
23790  
23791         r->idiag_state        = tw->tw_substate;
23792         r->idiag_timer        = 3;
23793 @@ -298,12 +302,14 @@ int inet_diag_dump_one_icsk(struct inet_
23794  
23795         err = -EINVAL;
23796         if (req->sdiag_family == AF_INET) {
23797 +               /* TODO: lback */
23798                 sk = inet_lookup(net, hashinfo, req->id.idiag_dst[0],
23799                                  req->id.idiag_dport, req->id.idiag_src[0],
23800                                  req->id.idiag_sport, req->id.idiag_if);
23801         }
23802  #if IS_ENABLED(CONFIG_IPV6)
23803         else if (req->sdiag_family == AF_INET6) {
23804 +               /* TODO: lback */
23805                 sk = inet6_lookup(net, hashinfo,
23806                                   (struct in6_addr *)req->id.idiag_dst,
23807                                   req->id.idiag_dport,
23808 @@ -501,6 +507,7 @@ int inet_diag_bc_sk(const struct nlattr
23809         } else
23810  #endif
23811         {
23812 +                       /* TODO: lback */
23813                 entry.saddr = &inet->inet_rcv_saddr;
23814                 entry.daddr = &inet->inet_daddr;
23815         }
23816 @@ -659,6 +666,7 @@ static int inet_twsk_diag_dump(struct so
23817                 } else
23818  #endif
23819                 {
23820 +                       /* TODO: lback */
23821                         entry.saddr = &tw->tw_rcv_saddr;
23822                         entry.daddr = &tw->tw_daddr;
23823                 }
23824 @@ -741,8 +749,8 @@ static int inet_diag_fill_req(struct sk_
23825         memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
23826         memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
23827  
23828 -       r->id.idiag_src[0] = ireq->ir_loc_addr;
23829 -       r->id.idiag_dst[0] = ireq->ir_rmt_addr;
23830 +       r->id.idiag_src[0] = nx_map_sock_lback(sk->sk_nx_info, ireq->ir_loc_addr);
23831 +       r->id.idiag_dst[0] = nx_map_sock_lback(sk->sk_nx_info, ireq->ir_rmt_addr);
23832  
23833         r->idiag_expires = jiffies_to_msecs(tmo);
23834         r->idiag_rqueue = 0;
23835 @@ -806,6 +814,7 @@ static int inet_diag_dump_reqs(struct sk
23836                             r->id.idiag_dport)
23837                                 continue;
23838  
23839 +                       /* TODO: lback */
23840                         if (bc) {
23841                                 inet_diag_req_addrs(sk, req, &entry);
23842                                 entry.dport = ntohs(ireq->ir_rmt_port);
23843 @@ -862,6 +871,8 @@ void inet_diag_dump_icsk(struct inet_has
23844                                 if (!net_eq(sock_net(sk), net))
23845                                         continue;
23846  
23847 +                               if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23848 +                                       continue;
23849                                 if (num < s_num) {
23850                                         num++;
23851                                         continue;
23852 @@ -934,6 +945,8 @@ skip_listen_ht:
23853  
23854                         if (!net_eq(sock_net(sk), net))
23855                                 continue;
23856 +                       if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23857 +                               continue;
23858                         if (num < s_num)
23859                                 goto next_normal;
23860                         state = (sk->sk_state == TCP_TIME_WAIT) ?
23861 diff -NurpP --minimal linux-3.18.5/net/ipv4/inet_hashtables.c linux-3.18.5-vs2.3.7.3/net/ipv4/inet_hashtables.c
23862 --- linux-3.18.5/net/ipv4/inet_hashtables.c     2015-01-17 02:40:24.000000000 +0000
23863 +++ linux-3.18.5-vs2.3.7.3/net/ipv4/inet_hashtables.c   2015-01-19 10:58:31.000000000 +0000
23864 @@ -22,6 +22,7 @@
23865  #include <net/inet_connection_sock.h>
23866  #include <net/inet_hashtables.h>
23867  #include <net/secure_seq.h>
23868 +#include <net/route.h>
23869  #include <net/ip.h>
23870  
23871  static unsigned int inet_ehashfn(struct net *net, const __be32 laddr,
23872 @@ -181,6 +182,11 @@ static inline int compute_score(struct s
23873                         if (rcv_saddr != daddr)
23874                                 return -1;
23875                         score += 4;
23876 +               } else {
23877 +                       /* block non nx_info ips */
23878 +                       if (!v4_addr_in_nx_info(sk->sk_nx_info,
23879 +                               daddr, NXA_MASK_BIND))
23880 +                               return -1;
23881                 }
23882                 if (sk->sk_bound_dev_if) {
23883                         if (sk->sk_bound_dev_if != dif)
23884 @@ -198,7 +204,6 @@ static inline int compute_score(struct s
23885   * wildcarded during the search since they can never be otherwise.
23886   */
23887  
23888 -
23889  struct sock *__inet_lookup_listener(struct net *net,
23890                                     struct inet_hashinfo *hashinfo,
23891                                     const __be32 saddr, __be16 sport,
23892 @@ -234,6 +239,7 @@ begin:
23893                         phash = next_pseudo_random32(phash);
23894                 }
23895         }
23896 +
23897         /*
23898          * if the nulls value we got at the end of this lookup is
23899          * not the expected one, we must restart lookup.
23900 diff -NurpP --minimal linux-3.18.5/net/ipv4/netfilter.c linux-3.18.5-vs2.3.7.3/net/ipv4/netfilter.c
23901 --- linux-3.18.5/net/ipv4/netfilter.c   2014-06-12 13:02:57.000000000 +0000
23902 +++ linux-3.18.5-vs2.3.7.3/net/ipv4/netfilter.c 2015-01-19 10:58:31.000000000 +0000
23903 @@ -11,7 +11,7 @@
23904  #include <linux/skbuff.h>
23905  #include <linux/gfp.h>
23906  #include <linux/export.h>
23907 -#include <net/route.h>
23908 +// #include <net/route.h>
23909  #include <net/xfrm.h>
23910  #include <net/ip.h>
23911  #include <net/netfilter/nf_queue.h>
23912 diff -NurpP --minimal linux-3.18.5/net/ipv4/raw.c linux-3.18.5-vs2.3.7.3/net/ipv4/raw.c
23913 --- linux-3.18.5/net/ipv4/raw.c 2015-01-16 22:19:30.000000000 +0000
23914 +++ linux-3.18.5-vs2.3.7.3/net/ipv4/raw.c       2015-01-19 10:58:31.000000000 +0000
23915 @@ -117,7 +117,7 @@ static struct sock *__raw_v4_lookup(stru
23916  
23917                 if (net_eq(sock_net(sk), net) && inet->inet_num == num  &&
23918                     !(inet->inet_daddr && inet->inet_daddr != raddr)    &&
23919 -                   !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
23920 +                   v4_sock_addr_match(sk->sk_nx_info, inet, laddr)     &&
23921                     !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
23922                         goto found; /* gotcha */
23923         }
23924 @@ -402,6 +402,12 @@ static int raw_send_hdrinc(struct sock *
23925                 icmp_out_count(net, ((struct icmphdr *)
23926                         skb_transport_header(skb))->type);
23927  
23928 +       err = -EPERM;
23929 +       if (!nx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW) &&
23930 +               sk->sk_nx_info &&
23931 +               !v4_addr_in_nx_info(sk->sk_nx_info, iph->saddr, NXA_MASK_BIND))
23932 +               goto error_free;
23933 +
23934         err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, skb, NULL,
23935                       rt->dst.dev, dst_output);
23936         if (err > 0)
23937 @@ -590,6 +596,16 @@ static int raw_sendmsg(struct kiocb *ioc
23938                         goto done;
23939         }
23940  
23941 +       if (sk->sk_nx_info) {
23942 +               rt = ip_v4_find_src(sock_net(sk), sk->sk_nx_info, &fl4);
23943 +               if (IS_ERR(rt)) {
23944 +                       err = PTR_ERR(rt);
23945 +                       rt = NULL;
23946 +                       goto done;
23947 +               }
23948 +               ip_rt_put(rt);
23949 +       }
23950 +
23951         security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
23952         rt = ip_route_output_flow(sock_net(sk), &fl4, sk);
23953         if (IS_ERR(rt)) {
23954 @@ -668,17 +684,19 @@ static int raw_bind(struct sock *sk, str
23955  {
23956         struct inet_sock *inet = inet_sk(sk);
23957         struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
23958 +       struct nx_v4_sock_addr nsa = { 0 };
23959         int ret = -EINVAL;
23960         int chk_addr_ret;
23961  
23962         if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
23963                 goto out;
23964 -       chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
23965 +       v4_map_sock_addr(inet, addr, &nsa);
23966 +       chk_addr_ret = inet_addr_type(sock_net(sk), nsa.saddr);
23967         ret = -EADDRNOTAVAIL;
23968 -       if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
23969 +       if (nsa.saddr && chk_addr_ret != RTN_LOCAL &&
23970             chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
23971                 goto out;
23972 -       inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
23973 +       v4_set_sock_addr(inet, &nsa);
23974         if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
23975                 inet->inet_saddr = 0;  /* Use device */
23976         sk_dst_reset(sk);
23977 @@ -727,7 +745,8 @@ static int raw_recvmsg(struct kiocb *ioc
23978         /* Copy the address. */
23979         if (sin) {
23980                 sin->sin_family = AF_INET;
23981 -               sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
23982 +               sin->sin_addr.s_addr =
23983 +                       nx_map_sock_lback(sk->sk_nx_info, ip_hdr(skb)->saddr);
23984                 sin->sin_port = 0;
23985                 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
23986                 *addr_len = sizeof(*sin);
23987 @@ -923,7 +942,8 @@ static struct sock *raw_get_first(struct
23988         for (state->bucket = 0; state->bucket < RAW_HTABLE_SIZE;
23989                         ++state->bucket) {
23990                 sk_for_each(sk, &state->h->ht[state->bucket])
23991 -                       if (sock_net(sk) == seq_file_net(seq))
23992 +                       if ((sock_net(sk) == seq_file_net(seq)) &&
23993 +                           nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23994                                 goto found;
23995         }
23996         sk = NULL;
23997 @@ -939,7 +959,8 @@ static struct sock *raw_get_next(struct
23998                 sk = sk_next(sk);
23999  try_again:
24000                 ;
24001 -       } while (sk && sock_net(sk) != seq_file_net(seq));
24002 +       } while (sk && ((sock_net(sk) != seq_file_net(seq)) ||
24003 +               !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
24004  
24005         if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
24006                 sk = sk_head(&state->h->ht[state->bucket]);
24007 diff -NurpP --minimal linux-3.18.5/net/ipv4/route.c linux-3.18.5-vs2.3.7.3/net/ipv4/route.c
24008 --- linux-3.18.5/net/ipv4/route.c       2015-01-17 02:40:25.000000000 +0000
24009 +++ linux-3.18.5-vs2.3.7.3/net/ipv4/route.c     2015-01-19 10:58:31.000000000 +0000
24010 @@ -2071,7 +2071,7 @@ struct rtable *__ip_route_output_key(str
24011  
24012  
24013         if (fl4->flowi4_oif) {
24014 -               dev_out = dev_get_by_index_rcu(net, fl4->flowi4_oif);
24015 +               dev_out = dev_get_by_index_real_rcu(net, fl4->flowi4_oif);
24016                 rth = ERR_PTR(-ENODEV);
24017                 if (dev_out == NULL)
24018                         goto out;
24019 diff -NurpP --minimal linux-3.18.5/net/ipv4/tcp.c linux-3.18.5-vs2.3.7.3/net/ipv4/tcp.c
24020 --- linux-3.18.5/net/ipv4/tcp.c 2015-01-17 02:40:25.000000000 +0000
24021 +++ linux-3.18.5-vs2.3.7.3/net/ipv4/tcp.c       2015-01-19 10:58:31.000000000 +0000
24022 @@ -268,6 +268,7 @@
24023  #include <linux/crypto.h>
24024  #include <linux/time.h>
24025  #include <linux/slab.h>
24026 +#include <linux/in.h>
24027  
24028  #include <net/icmp.h>
24029  #include <net/inet_common.h>
24030 diff -NurpP --minimal linux-3.18.5/net/ipv4/tcp_ipv4.c linux-3.18.5-vs2.3.7.3/net/ipv4/tcp_ipv4.c
24031 --- linux-3.18.5/net/ipv4/tcp_ipv4.c    2015-02-05 18:02:46.000000000 +0000
24032 +++ linux-3.18.5-vs2.3.7.3/net/ipv4/tcp_ipv4.c  2015-01-19 10:58:31.000000000 +0000
24033 @@ -1885,6 +1885,12 @@ static void *listening_get_next(struct s
24034                 req = req->dl_next;
24035                 while (1) {
24036                         while (req) {
24037 +                               vxdprintk(VXD_CBIT(net, 6),
24038 +                                       "sk,req: %p [#%d] (from %d)", req->sk,
24039 +                                       (req->sk)?req->sk->sk_nid:0, nx_current_nid());
24040 +                               if (req->sk &&
24041 +                                       !nx_check(req->sk->sk_nid, VS_WATCH_P | VS_IDENT))
24042 +                                       continue;
24043                                 if (req->rsk_ops->family == st->family) {
24044                                         cur = req;
24045                                         goto out;
24046 @@ -1909,6 +1915,10 @@ get_req:
24047         }
24048  get_sk:
24049         sk_nulls_for_each_from(sk, node) {
24050 +               vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
24051 +                       sk, sk->sk_nid, nx_current_nid());
24052 +               if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24053 +                       continue;
24054                 if (!net_eq(sock_net(sk), net))
24055                         continue;
24056                 if (sk->sk_family == st->family) {
24057 @@ -1983,6 +1993,11 @@ static void *established_get_first(struc
24058  
24059                 spin_lock_bh(lock);
24060                 sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
24061 +                       vxdprintk(VXD_CBIT(net, 6),
24062 +                               "sk,egf: %p [#%d] (from %d)",
24063 +                               sk, sk->sk_nid, nx_current_nid());
24064 +                       if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24065 +                               continue;
24066                         if (sk->sk_family != st->family ||
24067                             !net_eq(sock_net(sk), net)) {
24068                                 continue;
24069 @@ -2009,6 +2024,11 @@ static void *established_get_next(struct
24070         sk = sk_nulls_next(sk);
24071  
24072         sk_nulls_for_each_from(sk, node) {
24073 +               vxdprintk(VXD_CBIT(net, 6),
24074 +                       "sk,egn: %p [#%d] (from %d)",
24075 +                       sk, sk->sk_nid, nx_current_nid());
24076 +               if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24077 +                       continue;
24078                 if (sk->sk_family == st->family && net_eq(sock_net(sk), net))
24079                         return sk;
24080         }
24081 @@ -2207,9 +2227,9 @@ static void get_openreq4(const struct so
24082         seq_printf(f, "%4d: %08X:%04X %08X:%04X"
24083                 " %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK",
24084                 i,
24085 -               ireq->ir_loc_addr,
24086 +               nx_map_sock_lback(current_nx_info(), ireq->ir_loc_addr),
24087                 ntohs(inet_sk(sk)->inet_sport),
24088 -               ireq->ir_rmt_addr,
24089 +               nx_map_sock_lback(current_nx_info(), ireq->ir_rmt_addr),
24090                 ntohs(ireq->ir_rmt_port),
24091                 TCP_SYN_RECV,
24092                 0, 0, /* could print option size, but that is af dependent. */
24093 @@ -2231,8 +2251,8 @@ static void get_tcp4_sock(struct sock *s
24094         const struct inet_connection_sock *icsk = inet_csk(sk);
24095         const struct inet_sock *inet = inet_sk(sk);
24096         struct fastopen_queue *fastopenq = icsk->icsk_accept_queue.fastopenq;
24097 -       __be32 dest = inet->inet_daddr;
24098 -       __be32 src = inet->inet_rcv_saddr;
24099 +       __be32 dest = nx_map_sock_lback(current_nx_info(), inet->inet_daddr);
24100 +       __be32 src = nx_map_sock_lback(current_nx_info(), inet->inet_rcv_saddr);
24101         __u16 destp = ntohs(inet->inet_dport);
24102         __u16 srcp = ntohs(inet->inet_sport);
24103         int rx_queue;
24104 @@ -2289,8 +2309,8 @@ static void get_timewait4_sock(const str
24105         __u16 destp, srcp;
24106         s32 delta = tw->tw_ttd - inet_tw_time_stamp();
24107  
24108 -       dest  = tw->tw_daddr;
24109 -       src   = tw->tw_rcv_saddr;
24110 +       dest  = nx_map_sock_lback(current_nx_info(), tw->tw_daddr);
24111 +       src   = nx_map_sock_lback(current_nx_info(), tw->tw_rcv_saddr);
24112         destp = ntohs(tw->tw_dport);
24113         srcp  = ntohs(tw->tw_sport);
24114  
24115 diff -NurpP --minimal linux-3.18.5/net/ipv4/tcp_minisocks.c linux-3.18.5-vs2.3.7.3/net/ipv4/tcp_minisocks.c
24116 --- linux-3.18.5/net/ipv4/tcp_minisocks.c       2015-01-17 02:40:25.000000000 +0000
24117 +++ linux-3.18.5-vs2.3.7.3/net/ipv4/tcp_minisocks.c     2015-01-19 10:58:31.000000000 +0000
24118 @@ -23,6 +23,9 @@
24119  #include <linux/slab.h>
24120  #include <linux/sysctl.h>
24121  #include <linux/workqueue.h>
24122 +#include <linux/vs_limit.h>
24123 +#include <linux/vs_socket.h>
24124 +#include <linux/vs_context.h>
24125  #include <net/tcp.h>
24126  #include <net/inet_common.h>
24127  #include <net/xfrm.h>
24128 @@ -290,6 +293,11 @@ void tcp_time_wait(struct sock *sk, int
24129                 tcptw->tw_ts_recent_stamp = tp->rx_opt.ts_recent_stamp;
24130                 tcptw->tw_ts_offset     = tp->tsoffset;
24131  
24132 +               tw->tw_xid              = sk->sk_xid;
24133 +               tw->tw_vx_info          = NULL;
24134 +               tw->tw_nid              = sk->sk_nid;
24135 +               tw->tw_nx_info          = NULL;
24136 +
24137  #if IS_ENABLED(CONFIG_IPV6)
24138                 if (tw->tw_family == PF_INET6) {
24139                         struct ipv6_pinfo *np = inet6_sk(sk);
24140 diff -NurpP --minimal linux-3.18.5/net/ipv4/udp.c linux-3.18.5-vs2.3.7.3/net/ipv4/udp.c
24141 --- linux-3.18.5/net/ipv4/udp.c 2015-01-17 02:40:25.000000000 +0000
24142 +++ linux-3.18.5-vs2.3.7.3/net/ipv4/udp.c       2015-01-19 10:58:31.000000000 +0000
24143 @@ -309,14 +309,7 @@ fail:
24144  }
24145  EXPORT_SYMBOL(udp_lib_get_port);
24146  
24147 -static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
24148 -{
24149 -       struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
24150 -
24151 -       return  (!ipv6_only_sock(sk2)  &&
24152 -                (!inet1->inet_rcv_saddr || !inet2->inet_rcv_saddr ||
24153 -                  inet1->inet_rcv_saddr == inet2->inet_rcv_saddr));
24154 -}
24155 +extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *);
24156  
24157  static unsigned int udp4_portaddr_hash(struct net *net, __be32 saddr,
24158                                        unsigned int port)
24159 @@ -351,6 +344,11 @@ static inline int compute_score(struct s
24160                         if (inet->inet_rcv_saddr != daddr)
24161                                 return -1;
24162                         score += 4;
24163 +               } else {
24164 +                       /* block non nx_info ips */
24165 +                       if (!v4_addr_in_nx_info(sk->sk_nx_info,
24166 +                               daddr, NXA_MASK_BIND))
24167 +                               return -1;
24168                 }
24169                 if (inet->inet_daddr) {
24170                         if (inet->inet_daddr != saddr)
24171 @@ -473,6 +471,7 @@ begin:
24172         return result;
24173  }
24174  
24175 +
24176  /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
24177   * harder than this. -DaveM
24178   */
24179 @@ -519,6 +518,11 @@ begin:
24180         sk_nulls_for_each_rcu(sk, node, &hslot->head) {
24181                 score = compute_score(sk, net, saddr, hnum, sport,
24182                                       daddr, dport, dif);
24183 +               /* FIXME: disabled?
24184 +               if (score == 9) {
24185 +                       result = sk;
24186 +                       break;
24187 +               } else */
24188                 if (score > badness) {
24189                         result = sk;
24190                         badness = score;
24191 @@ -543,6 +547,7 @@ begin:
24192         if (get_nulls_value(node) != slot)
24193                 goto begin;
24194  
24195 +
24196         if (result) {
24197                 if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
24198                         result = NULL;
24199 @@ -552,6 +557,7 @@ begin:
24200                         goto begin;
24201                 }
24202         }
24203 +
24204         rcu_read_unlock();
24205         return result;
24206  }
24207 @@ -586,7 +592,7 @@ static inline bool __udp_is_mcast_sock(s
24208             udp_sk(sk)->udp_port_hash != hnum ||
24209             (inet->inet_daddr && inet->inet_daddr != rmt_addr) ||
24210             (inet->inet_dport != rmt_port && inet->inet_dport) ||
24211 -           (inet->inet_rcv_saddr && inet->inet_rcv_saddr != loc_addr) ||
24212 +           !v4_sock_addr_match(sk->sk_nx_info, inet, loc_addr) ||
24213             ipv6_only_sock(sk) ||
24214             (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
24215                 return false;
24216 @@ -1008,6 +1014,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
24217                                    inet_sk_flowi_flags(sk),
24218                                    faddr, saddr, dport, inet->inet_sport);
24219  
24220 +               if (sk->sk_nx_info) {
24221 +                       rt = ip_v4_find_src(net, sk->sk_nx_info, fl4);
24222 +                       if (IS_ERR(rt)) {
24223 +                               err = PTR_ERR(rt);
24224 +                               rt = NULL;
24225 +                               goto out;
24226 +                       }
24227 +                       ip_rt_put(rt);
24228 +               }
24229 +
24230                 security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
24231                 rt = ip_route_output_flow(net, fl4, sk);
24232                 if (IS_ERR(rt)) {
24233 @@ -1312,7 +1328,8 @@ try_again:
24234         if (sin) {
24235                 sin->sin_family = AF_INET;
24236                 sin->sin_port = udp_hdr(skb)->source;
24237 -               sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
24238 +               sin->sin_addr.s_addr = nx_map_sock_lback(
24239 +                       skb->sk->sk_nx_info, ip_hdr(skb)->saddr);
24240                 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
24241                 *addr_len = sizeof(*sin);
24242         }
24243 @@ -2271,6 +2288,8 @@ static struct sock *udp_get_first(struct
24244                 sk_nulls_for_each(sk, node, &hslot->head) {
24245                         if (!net_eq(sock_net(sk), net))
24246                                 continue;
24247 +                       if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24248 +                               continue;
24249                         if (sk->sk_family == state->family)
24250                                 goto found;
24251                 }
24252 @@ -2288,7 +2307,9 @@ static struct sock *udp_get_next(struct
24253  
24254         do {
24255                 sk = sk_nulls_next(sk);
24256 -       } while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != state->family));
24257 +       } while (sk && (!net_eq(sock_net(sk), net) ||
24258 +               sk->sk_family != state->family ||
24259 +               !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
24260  
24261         if (!sk) {
24262                 if (state->bucket <= state->udp_table->mask)
24263 @@ -2384,8 +2405,8 @@ static void udp4_format_sock(struct sock
24264                 int bucket)
24265  {
24266         struct inet_sock *inet = inet_sk(sp);
24267 -       __be32 dest = inet->inet_daddr;
24268 -       __be32 src  = inet->inet_rcv_saddr;
24269 +       __be32 dest = nx_map_sock_lback(current_nx_info(), inet->inet_daddr);
24270 +       __be32 src = nx_map_sock_lback(current_nx_info(), inet->inet_rcv_saddr);
24271         __u16 destp       = ntohs(inet->inet_dport);
24272         __u16 srcp        = ntohs(inet->inet_sport);
24273  
24274 diff -NurpP --minimal linux-3.18.5/net/ipv6/Kconfig linux-3.18.5-vs2.3.7.3/net/ipv6/Kconfig
24275 --- linux-3.18.5/net/ipv6/Kconfig       2014-06-12 11:35:11.000000000 +0000
24276 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/Kconfig     2015-01-19 10:58:31.000000000 +0000
24277 @@ -4,8 +4,8 @@
24278  
24279  #   IPv6 as module will cause a CRASH if you try to unload it
24280  menuconfig IPV6
24281 -       tristate "The IPv6 protocol"
24282 -       default m
24283 +       bool "The IPv6 protocol"
24284 +       default n
24285         ---help---
24286           This is complemental support for the IP version 6.
24287           You will still be able to do traditional IPv4 networking as well.
24288 diff -NurpP --minimal linux-3.18.5/net/ipv6/addrconf.c linux-3.18.5-vs2.3.7.3/net/ipv6/addrconf.c
24289 --- linux-3.18.5/net/ipv6/addrconf.c    2015-01-17 02:40:25.000000000 +0000
24290 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/addrconf.c  2015-01-19 10:58:31.000000000 +0000
24291 @@ -90,6 +90,8 @@
24292  #include <linux/proc_fs.h>
24293  #include <linux/seq_file.h>
24294  #include <linux/export.h>
24295 +#include <linux/vs_network.h>
24296 +#include <linux/vs_inet6.h>
24297  
24298  /* Set to 3 to get tracing... */
24299  #define ACONF_DEBUG 2
24300 @@ -1319,7 +1321,7 @@ out:
24301  
24302  int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
24303                        const struct in6_addr *daddr, unsigned int prefs,
24304 -                      struct in6_addr *saddr)
24305 +                      struct in6_addr *saddr, struct nx_info *nxi)
24306  {
24307         struct ipv6_saddr_score scores[2],
24308                                 *score = &scores[0], *hiscore = &scores[1];
24309 @@ -1391,6 +1393,8 @@ int ipv6_dev_get_saddr(struct net *net,
24310                                                dev->name);
24311                                 continue;
24312                         }
24313 +                       if (!v6_addr_in_nx_info(nxi, &score->ifa->addr, -1))
24314 +                               continue;
24315  
24316                         score->rule = -1;
24317                         bitmap_zero(score->scorebits, IPV6_SADDR_RULE_MAX);
24318 @@ -3503,7 +3507,10 @@ static void if6_seq_stop(struct seq_file
24319  static int if6_seq_show(struct seq_file *seq, void *v)
24320  {
24321         struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
24322 -       seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
24323 +
24324 +       if (nx_check(0, VS_ADMIN|VS_WATCH) ||
24325 +           v6_addr_in_nx_info(current_nx_info(), &ifp->addr, -1))
24326 +               seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
24327                    &ifp->addr,
24328                    ifp->idev->dev->ifindex,
24329                    ifp->prefix_len,
24330 @@ -4084,6 +4091,11 @@ static int in6_dump_addrs(struct inet6_d
24331         struct ifacaddr6 *ifaca;
24332         int err = 1;
24333         int ip_idx = *p_ip_idx;
24334 +       struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
24335 +
24336 +       /* disable ipv6 on non v6 guests */
24337 +       if (nxi && !nx_info_has_v6(nxi))
24338 +               return skb->len;
24339  
24340         read_lock_bh(&idev->lock);
24341         switch (type) {
24342 @@ -4094,6 +4106,8 @@ static int in6_dump_addrs(struct inet6_d
24343                 list_for_each_entry(ifa, &idev->addr_list, if_list) {
24344                         if (++ip_idx < s_ip_idx)
24345                                 continue;
24346 +                               if (!v6_addr_in_nx_info(nxi, &ifa->addr, -1))
24347 +                                       continue;
24348                         err = inet6_fill_ifaddr(skb, ifa,
24349                                                 NETLINK_CB(cb->skb).portid,
24350                                                 cb->nlh->nlmsg_seq,
24351 @@ -4111,6 +4125,8 @@ static int in6_dump_addrs(struct inet6_d
24352                      ifmca = ifmca->next, ip_idx++) {
24353                         if (ip_idx < s_ip_idx)
24354                                 continue;
24355 +                               if (!v6_addr_in_nx_info(nxi, &ifmca->mca_addr, -1))
24356 +                                       continue;
24357                         err = inet6_fill_ifmcaddr(skb, ifmca,
24358                                                   NETLINK_CB(cb->skb).portid,
24359                                                   cb->nlh->nlmsg_seq,
24360 @@ -4126,6 +4142,8 @@ static int in6_dump_addrs(struct inet6_d
24361                      ifaca = ifaca->aca_next, ip_idx++) {
24362                         if (ip_idx < s_ip_idx)
24363                                 continue;
24364 +                               if (!v6_addr_in_nx_info(nxi, &ifaca->aca_addr, -1))
24365 +                                       continue;
24366                         err = inet6_fill_ifacaddr(skb, ifaca,
24367                                                   NETLINK_CB(cb->skb).portid,
24368                                                   cb->nlh->nlmsg_seq,
24369 @@ -4154,6 +4172,10 @@ static int inet6_dump_addr(struct sk_buf
24370         struct inet6_dev *idev;
24371         struct hlist_head *head;
24372  
24373 +       /* FIXME: maybe disable ipv6 on non v6 guests?
24374 +       if (skb->sk && skb->sk->sk_vx_info)
24375 +               return skb->len; */
24376 +
24377         s_h = cb->args[0];
24378         s_idx = idx = cb->args[1];
24379         s_ip_idx = ip_idx = cb->args[2];
24380 @@ -4617,6 +4639,7 @@ static int inet6_dump_ifinfo(struct sk_b
24381         struct net_device *dev;
24382         struct inet6_dev *idev;
24383         struct hlist_head *head;
24384 +       struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
24385  
24386         s_h = cb->args[0];
24387         s_idx = cb->args[1];
24388 @@ -4628,6 +4651,8 @@ static int inet6_dump_ifinfo(struct sk_b
24389                 hlist_for_each_entry_rcu(dev, head, index_hlist) {
24390                         if (idx < s_idx)
24391                                 goto cont;
24392 +                       if (!v6_dev_in_nx_info(dev, nxi))
24393 +                               goto cont;
24394                         idev = __in6_dev_get(dev);
24395                         if (!idev)
24396                                 goto cont;
24397 diff -NurpP --minimal linux-3.18.5/net/ipv6/af_inet6.c linux-3.18.5-vs2.3.7.3/net/ipv6/af_inet6.c
24398 --- linux-3.18.5/net/ipv6/af_inet6.c    2015-01-17 02:40:25.000000000 +0000
24399 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/af_inet6.c  2015-01-19 10:58:31.000000000 +0000
24400 @@ -43,6 +43,8 @@
24401  #include <linux/netdevice.h>
24402  #include <linux/icmpv6.h>
24403  #include <linux/netfilter_ipv6.h>
24404 +#include <linux/vs_inet.h>
24405 +#include <linux/vs_inet6.h>
24406  
24407  #include <net/ip.h>
24408  #include <net/ipv6.h>
24409 @@ -155,10 +157,13 @@ lookup_protocol:
24410         }
24411  
24412         err = -EPERM;
24413 +       if ((protocol == IPPROTO_ICMPV6) &&
24414 +               nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
24415 +               goto override;
24416         if (sock->type == SOCK_RAW && !kern &&
24417             !ns_capable(net->user_ns, CAP_NET_RAW))
24418                 goto out_rcu_unlock;
24419 -
24420 +override:
24421         sock->ops = answer->ops;
24422         answer_prot = answer->prot;
24423         answer_flags = answer->flags;
24424 @@ -256,6 +261,7 @@ int inet6_bind(struct socket *sock, stru
24425         struct inet_sock *inet = inet_sk(sk);
24426         struct ipv6_pinfo *np = inet6_sk(sk);
24427         struct net *net = sock_net(sk);
24428 +       struct nx_v6_sock_addr nsa;
24429         __be32 v4addr = 0;
24430         unsigned short snum;
24431         int addr_type = 0;
24432 @@ -271,6 +277,10 @@ int inet6_bind(struct socket *sock, stru
24433         if (addr->sin6_family != AF_INET6)
24434                 return -EAFNOSUPPORT;
24435  
24436 +       err = v6_map_sock_addr(inet, addr, &nsa);
24437 +       if (err)
24438 +               return err;
24439 +
24440         addr_type = ipv6_addr_type(&addr->sin6_addr);
24441         if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
24442                 return -EINVAL;
24443 @@ -311,6 +321,10 @@ int inet6_bind(struct socket *sock, stru
24444                         err = -EADDRNOTAVAIL;
24445                         goto out;
24446                 }
24447 +               if (!v4_addr_in_nx_info(sk->sk_nx_info, v4addr, NXA_MASK_BIND)) {
24448 +                       err = -EADDRNOTAVAIL;
24449 +                       goto out;
24450 +               }
24451         } else {
24452                 if (addr_type != IPV6_ADDR_ANY) {
24453                         struct net_device *dev = NULL;
24454 @@ -337,6 +351,11 @@ int inet6_bind(struct socket *sock, stru
24455                                 }
24456                         }
24457  
24458 +                       if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
24459 +                               err = -EADDRNOTAVAIL;
24460 +                               goto out_unlock;
24461 +                       }
24462 +
24463                         /* ipv4 addr of the socket is invalid.  Only the
24464                          * unspecified and mapped address have a v4 equivalent.
24465                          */
24466 @@ -353,6 +372,9 @@ int inet6_bind(struct socket *sock, stru
24467                 }
24468         }
24469  
24470 +       /* what's that for? */
24471 +       v6_set_sock_addr(inet, &nsa);
24472 +
24473         inet->inet_rcv_saddr = v4addr;
24474         inet->inet_saddr = v4addr;
24475  
24476 @@ -454,9 +476,11 @@ int inet6_getname(struct socket *sock, s
24477                         return -ENOTCONN;
24478                 sin->sin6_port = inet->inet_dport;
24479                 sin->sin6_addr = sk->sk_v6_daddr;
24480 +               /* FIXME: remap lback? */
24481                 if (np->sndflow)
24482                         sin->sin6_flowinfo = np->flow_label;
24483         } else {
24484 +               /* FIXME: remap lback? */
24485                 if (ipv6_addr_any(&sk->sk_v6_rcv_saddr))
24486                         sin->sin6_addr = np->saddr;
24487                 else
24488 diff -NurpP --minimal linux-3.18.5/net/ipv6/datagram.c linux-3.18.5-vs2.3.7.3/net/ipv6/datagram.c
24489 --- linux-3.18.5/net/ipv6/datagram.c    2015-01-17 02:40:25.000000000 +0000
24490 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/datagram.c  2015-01-19 10:58:31.000000000 +0000
24491 @@ -675,7 +675,7 @@ int ip6_datagram_send_ctl(struct net *ne
24492  
24493                         rcu_read_lock();
24494                         if (fl6->flowi6_oif) {
24495 -                               dev = dev_get_by_index_rcu(net, fl6->flowi6_oif);
24496 +                               dev = dev_get_by_index_real_rcu(net, fl6->flowi6_oif);
24497                                 if (!dev) {
24498                                         rcu_read_unlock();
24499                                         return -ENODEV;
24500 diff -NurpP --minimal linux-3.18.5/net/ipv6/fib6_rules.c linux-3.18.5-vs2.3.7.3/net/ipv6/fib6_rules.c
24501 --- linux-3.18.5/net/ipv6/fib6_rules.c  2014-06-12 11:35:11.000000000 +0000
24502 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/fib6_rules.c        2015-01-19 10:58:31.000000000 +0000
24503 @@ -97,7 +97,7 @@ static int fib6_rule_action(struct fib_r
24504                                                ip6_dst_idev(&rt->dst)->dev,
24505                                                &flp6->daddr,
24506                                                rt6_flags2srcprefs(flags),
24507 -                                              &saddr))
24508 +                                              &saddr, NULL))
24509                                 goto again;
24510                         if (!ipv6_prefix_equal(&saddr, &r->src.addr,
24511                                                r->src.plen))
24512 diff -NurpP --minimal linux-3.18.5/net/ipv6/inet6_hashtables.c linux-3.18.5-vs2.3.7.3/net/ipv6/inet6_hashtables.c
24513 --- linux-3.18.5/net/ipv6/inet6_hashtables.c    2015-01-17 02:40:25.000000000 +0000
24514 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/inet6_hashtables.c  2015-01-19 10:58:31.000000000 +0000
24515 @@ -16,6 +16,7 @@
24516  
24517  #include <linux/module.h>
24518  #include <linux/random.h>
24519 +#include <linux/vs_inet6.h>
24520  
24521  #include <net/inet_connection_sock.h>
24522  #include <net/inet_hashtables.h>
24523 @@ -116,7 +117,6 @@ struct sock *__inet6_lookup_established(
24524         unsigned int slot = hash & hashinfo->ehash_mask;
24525         struct inet_ehash_bucket *head = &hashinfo->ehash[slot];
24526  
24527 -
24528         rcu_read_lock();
24529  begin:
24530         sk_nulls_for_each_rcu(sk, node, &head->chain) {
24531 @@ -158,6 +158,9 @@ static inline int compute_score(struct s
24532                         if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))
24533                                 return -1;
24534                         score++;
24535 +               } else {
24536 +                       if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
24537 +                               return -1;
24538                 }
24539                 if (sk->sk_bound_dev_if) {
24540                         if (sk->sk_bound_dev_if != dif)
24541 diff -NurpP --minimal linux-3.18.5/net/ipv6/ip6_fib.c linux-3.18.5-vs2.3.7.3/net/ipv6/ip6_fib.c
24542 --- linux-3.18.5/net/ipv6/ip6_fib.c     2015-01-17 02:40:25.000000000 +0000
24543 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/ip6_fib.c   2015-01-19 10:58:31.000000000 +0000
24544 @@ -1845,6 +1845,7 @@ static int ipv6_route_seq_show(struct se
24545         struct rt6_info *rt = v;
24546         struct ipv6_route_iter *iter = seq->private;
24547  
24548 +       /* FIXME: check for network context? */
24549         seq_printf(seq, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen);
24550  
24551  #ifdef CONFIG_IPV6_SUBTREES
24552 diff -NurpP --minimal linux-3.18.5/net/ipv6/ip6_output.c linux-3.18.5-vs2.3.7.3/net/ipv6/ip6_output.c
24553 --- linux-3.18.5/net/ipv6/ip6_output.c  2015-01-17 02:40:25.000000000 +0000
24554 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/ip6_output.c        2015-01-19 10:58:31.000000000 +0000
24555 @@ -907,7 +907,8 @@ static int ip6_dst_lookup_tail(struct so
24556                 struct rt6_info *rt = (struct rt6_info *) *dst;
24557                 err = ip6_route_get_saddr(net, rt, &fl6->daddr,
24558                                           sk ? inet6_sk(sk)->srcprefs : 0,
24559 -                                         &fl6->saddr);
24560 +                                         &fl6->saddr,
24561 +                                         sk ? sk->sk_nx_info : NULL);
24562                 if (err)
24563                         goto out_err_release;
24564         }
24565 diff -NurpP --minimal linux-3.18.5/net/ipv6/ndisc.c linux-3.18.5-vs2.3.7.3/net/ipv6/ndisc.c
24566 --- linux-3.18.5/net/ipv6/ndisc.c       2015-01-17 02:40:25.000000000 +0000
24567 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/ndisc.c     2015-01-19 10:58:31.000000000 +0000
24568 @@ -487,7 +487,7 @@ void ndisc_send_na(struct net_device *de
24569         } else {
24570                 if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
24571                                        inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
24572 -                                      &tmpaddr))
24573 +                                      &tmpaddr, NULL))
24574                         return;
24575                 src_addr = &tmpaddr;
24576         }
24577 diff -NurpP --minimal linux-3.18.5/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c linux-3.18.5-vs2.3.7.3/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c
24578 --- linux-3.18.5/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c    2015-01-17 02:40:25.000000000 +0000
24579 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c  2015-01-19 23:51:41.000000000 +0000
24580 @@ -35,7 +35,7 @@ nf_nat_masquerade_ipv6(struct sk_buff *s
24581                             ctinfo == IP_CT_RELATED_REPLY));
24582  
24583         if (ipv6_dev_get_saddr(dev_net(out), out,
24584 -                              &ipv6_hdr(skb)->daddr, 0, &src) < 0)
24585 +                              &ipv6_hdr(skb)->daddr, 0, &src, NULL) < 0)
24586                 return NF_DROP;
24587  
24588         nfct_nat(ct)->masq_index = out->ifindex;
24589 diff -NurpP --minimal linux-3.18.5/net/ipv6/raw.c linux-3.18.5-vs2.3.7.3/net/ipv6/raw.c
24590 --- linux-3.18.5/net/ipv6/raw.c 2015-01-17 02:40:25.000000000 +0000
24591 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/raw.c       2015-01-19 10:58:31.000000000 +0000
24592 @@ -30,6 +30,7 @@
24593  #include <linux/icmpv6.h>
24594  #include <linux/netfilter.h>
24595  #include <linux/netfilter_ipv6.h>
24596 +#include <linux/vs_inet6.h>
24597  #include <linux/skbuff.h>
24598  #include <linux/compat.h>
24599  #include <asm/uaccess.h>
24600 @@ -291,6 +292,13 @@ static int rawv6_bind(struct sock *sk, s
24601                                 goto out_unlock;
24602                 }
24603  
24604 +               if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
24605 +                       err = -EADDRNOTAVAIL;
24606 +                       if (dev)
24607 +                               dev_put(dev);
24608 +                       goto out;
24609 +               }
24610 +
24611                 /* ipv4 addr of the socket is invalid.  Only the
24612                  * unspecified and mapped address have a v4 equivalent.
24613                  */
24614 diff -NurpP --minimal linux-3.18.5/net/ipv6/route.c linux-3.18.5-vs2.3.7.3/net/ipv6/route.c
24615 --- linux-3.18.5/net/ipv6/route.c       2015-01-17 02:40:25.000000000 +0000
24616 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/route.c     2015-01-19 11:21:40.000000000 +0000
24617 @@ -58,6 +58,7 @@
24618  #include <net/netevent.h>
24619  #include <net/netlink.h>
24620  #include <net/nexthop.h>
24621 +#include <linux/vs_inet6.h>
24622  
24623  #include <asm/uaccess.h>
24624  
24625 @@ -2183,15 +2184,17 @@ int ip6_route_get_saddr(struct net *net,
24626                         struct rt6_info *rt,
24627                         const struct in6_addr *daddr,
24628                         unsigned int prefs,
24629 -                       struct in6_addr *saddr)
24630 +                       struct in6_addr *saddr,
24631 +                       struct nx_info *nxi)
24632  {
24633         struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt);
24634         int err = 0;
24635 -       if (rt->rt6i_prefsrc.plen)
24636 +       if (rt->rt6i_prefsrc.plen && (!nxi ||
24637 +           v6_addr_in_nx_info(nxi, &rt->rt6i_prefsrc.addr, NXA_TYPE_ADDR)))
24638                 *saddr = rt->rt6i_prefsrc.addr;
24639         else
24640                 err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
24641 -                                        daddr, prefs, saddr);
24642 +                                        daddr, prefs, saddr, nxi);
24643         return err;
24644  }
24645  
24646 @@ -2632,7 +2635,8 @@ static int rt6_fill_node(struct net *net
24647                                 goto nla_put_failure;
24648         } else if (dst) {
24649                 struct in6_addr saddr_buf;
24650 -               if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0 &&
24651 +               if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf,
24652 +                   (skb->sk ? skb->sk->sk_nx_info : NULL)) == 0 &&
24653                     nla_put(skb, RTA_PREFSRC, 16, &saddr_buf))
24654                         goto nla_put_failure;
24655         }
24656 diff -NurpP --minimal linux-3.18.5/net/ipv6/tcp_ipv6.c linux-3.18.5-vs2.3.7.3/net/ipv6/tcp_ipv6.c
24657 --- linux-3.18.5/net/ipv6/tcp_ipv6.c    2015-02-05 18:02:46.000000000 +0000
24658 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/tcp_ipv6.c  2015-01-28 11:48:02.000000000 +0000
24659 @@ -69,6 +69,7 @@
24660  
24661  #include <linux/crypto.h>
24662  #include <linux/scatterlist.h>
24663 +#include <linux/vs_inet6.h>
24664  
24665  static void    tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
24666  static void    tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
24667 @@ -164,8 +165,15 @@ static int tcp_v6_connect(struct sock *s
24668          *      connect() to INADDR_ANY means loopback (BSD'ism).
24669          */
24670  
24671 -       if (ipv6_addr_any(&usin->sin6_addr))
24672 -               usin->sin6_addr.s6_addr[15] = 0x1;
24673 +       if(ipv6_addr_any(&usin->sin6_addr)) {
24674 +               struct nx_info *nxi =  sk->sk_nx_info;
24675 +
24676 +               if (nxi && nx_info_has_v6(nxi))
24677 +                       /* FIXME: remap lback? */
24678 +                       usin->sin6_addr = nxi->v6.ip;
24679 +               else
24680 +                       usin->sin6_addr.s6_addr[15] = 0x1;
24681 +       }
24682  
24683         addr_type = ipv6_addr_type(&usin->sin6_addr);
24684  
24685 diff -NurpP --minimal linux-3.18.5/net/ipv6/udp.c linux-3.18.5-vs2.3.7.3/net/ipv6/udp.c
24686 --- linux-3.18.5/net/ipv6/udp.c 2015-01-17 02:40:25.000000000 +0000
24687 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/udp.c       2015-01-19 10:58:32.000000000 +0000
24688 @@ -47,6 +47,7 @@
24689  #include <net/xfrm.h>
24690  #include <net/inet6_hashtables.h>
24691  #include <net/busy_poll.h>
24692 +#include <linux/vs_inet6.h>
24693  
24694  #include <linux/proc_fs.h>
24695  #include <linux/seq_file.h>
24696 @@ -159,6 +160,10 @@ static inline int compute_score(struct s
24697                         if (inet->inet_dport != sport)
24698                                 return -1;
24699                         score++;
24700 +               } else {
24701 +                       /* block non nx_info ips */
24702 +                       if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
24703 +                               return -1;
24704                 }
24705                 if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
24706                         if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))
24707 diff -NurpP --minimal linux-3.18.5/net/ipv6/xfrm6_policy.c linux-3.18.5-vs2.3.7.3/net/ipv6/xfrm6_policy.c
24708 --- linux-3.18.5/net/ipv6/xfrm6_policy.c        2015-01-17 02:40:25.000000000 +0000
24709 +++ linux-3.18.5-vs2.3.7.3/net/ipv6/xfrm6_policy.c      2015-01-19 10:58:32.000000000 +0000
24710 @@ -63,7 +63,7 @@ static int xfrm6_get_saddr(struct net *n
24711         dev = ip6_dst_idev(dst)->dev;
24712         ipv6_dev_get_saddr(dev_net(dev), dev,
24713                            (struct in6_addr *)&daddr->a6, 0,
24714 -                          (struct in6_addr *)&saddr->a6);
24715 +                          (struct in6_addr *)&saddr->a6, NULL);
24716         dst_release(dst);
24717         return 0;
24718  }
24719 diff -NurpP --minimal linux-3.18.5/net/netfilter/ipvs/ip_vs_xmit.c linux-3.18.5-vs2.3.7.3/net/netfilter/ipvs/ip_vs_xmit.c
24720 --- linux-3.18.5/net/netfilter/ipvs/ip_vs_xmit.c        2015-01-17 02:40:25.000000000 +0000
24721 +++ linux-3.18.5-vs2.3.7.3/net/netfilter/ipvs/ip_vs_xmit.c      2015-01-19 10:58:32.000000000 +0000
24722 @@ -379,7 +379,7 @@ __ip_vs_route_output_v6(struct net *net,
24723                 return dst;
24724         if (ipv6_addr_any(&fl6.saddr) &&
24725             ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev,
24726 -                              &fl6.daddr, 0, &fl6.saddr) < 0)
24727 +                              &fl6.daddr, 0, &fl6.saddr, NULL) < 0)
24728                 goto out_err;
24729         if (do_xfrm) {
24730                 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
24731 diff -NurpP --minimal linux-3.18.5/net/netlink/af_netlink.c linux-3.18.5-vs2.3.7.3/net/netlink/af_netlink.c
24732 --- linux-3.18.5/net/netlink/af_netlink.c       2015-02-05 18:02:46.000000000 +0000
24733 +++ linux-3.18.5-vs2.3.7.3/net/netlink/af_netlink.c     2015-01-28 11:48:02.000000000 +0000
24734 @@ -61,6 +61,9 @@
24735  #include <linux/rhashtable.h>
24736  #include <asm/cacheflush.h>
24737  #include <linux/hash.h>
24738 +#include <linux/vs_context.h>
24739 +#include <linux/vs_network.h>
24740 +#include <linux/vs_limit.h>
24741  
24742  #include <net/net_namespace.h>
24743  #include <net/sock.h>
24744 @@ -2899,6 +2902,8 @@ static struct sock *netlink_seq_socket_i
24745  
24746                                 if (sock_net(s) != seq_file_net(seq))
24747                                         continue;
24748 +                               if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT))
24749 +                                       continue;
24750                                 if (off == pos) {
24751                                         iter->link = i;
24752                                         iter->hash_idx = j;
24753 diff -NurpP --minimal linux-3.18.5/net/socket.c linux-3.18.5-vs2.3.7.3/net/socket.c
24754 --- linux-3.18.5/net/socket.c   2015-01-17 02:40:30.000000000 +0000
24755 +++ linux-3.18.5-vs2.3.7.3/net/socket.c 2015-01-19 10:58:32.000000000 +0000
24756 @@ -99,6 +99,9 @@
24757  
24758  #include <net/sock.h>
24759  #include <linux/netfilter.h>
24760 +#include <linux/vs_socket.h>
24761 +#include <linux/vs_inet.h>
24762 +#include <linux/vs_inet6.h>
24763  
24764  #include <linux/if_tun.h>
24765  #include <linux/ipv6_route.h>
24766 @@ -634,13 +637,29 @@ static inline int __sock_sendmsg_nosec(s
24767                                        struct msghdr *msg, size_t size)
24768  {
24769         struct sock_iocb *si = kiocb_to_siocb(iocb);
24770 +       size_t len;
24771  
24772         si->sock = sock;
24773         si->scm = NULL;
24774         si->msg = msg;
24775         si->size = size;
24776  
24777 -       return sock->ops->sendmsg(iocb, sock, msg, size);
24778 +       len = sock->ops->sendmsg(iocb, sock, msg, size);
24779 +       if (sock->sk) {
24780 +               if (len == size)
24781 +                       vx_sock_send(sock->sk, size);
24782 +               else
24783 +                       vx_sock_fail(sock->sk, size);
24784 +       }
24785 +       vxdprintk(VXD_CBIT(net, 7),
24786 +               "__sock_sendmsg: %p[%p,%p,%p;%d/%d]:%d/%zu",
24787 +               sock, sock->sk,
24788 +               (sock->sk)?sock->sk->sk_nx_info:0,
24789 +               (sock->sk)?sock->sk->sk_vx_info:0,
24790 +               (sock->sk)?sock->sk->sk_xid:0,
24791 +               (sock->sk)?sock->sk->sk_nid:0,
24792 +               (unsigned int)size, len);
24793 +       return len;
24794  }
24795  
24796  static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
24797 @@ -780,6 +799,7 @@ static inline int __sock_recvmsg_nosec(s
24798                                        struct msghdr *msg, size_t size, int flags)
24799  {
24800         struct sock_iocb *si = kiocb_to_siocb(iocb);
24801 +       int len;
24802  
24803         si->sock = sock;
24804         si->scm = NULL;
24805 @@ -787,7 +807,18 @@ static inline int __sock_recvmsg_nosec(s
24806         si->size = size;
24807         si->flags = flags;
24808  
24809 -       return sock->ops->recvmsg(iocb, sock, msg, size, flags);
24810 +       len = sock->ops->recvmsg(iocb, sock, msg, size, flags);
24811 +       if ((len >= 0) && sock->sk)
24812 +               vx_sock_recv(sock->sk, len);
24813 +       vxdprintk(VXD_CBIT(net, 7),
24814 +               "__sock_recvmsg: %p[%p,%p,%p;%d/%d]:%d/%d",
24815 +               sock, sock->sk,
24816 +               (sock->sk)?sock->sk->sk_nx_info:0,
24817 +               (sock->sk)?sock->sk->sk_vx_info:0,
24818 +               (sock->sk)?sock->sk->sk_xid:0,
24819 +               (sock->sk)?sock->sk->sk_nid:0,
24820 +               (unsigned int)size, len);
24821 +       return len;
24822  }
24823  
24824  static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
24825 @@ -1264,6 +1295,13 @@ int __sock_create(struct net *net, int f
24826         if (type < 0 || type >= SOCK_MAX)
24827                 return -EINVAL;
24828  
24829 +       if (!nx_check(0, VS_ADMIN)) {
24830 +               if (family == PF_INET && !current_nx_info_has_v4())
24831 +                       return -EAFNOSUPPORT;
24832 +               if (family == PF_INET6 && !current_nx_info_has_v6())
24833 +                       return -EAFNOSUPPORT;
24834 +       }
24835 +
24836         /* Compatibility.
24837  
24838            This uglymoron is moved from INET layer to here to avoid
24839 @@ -1398,6 +1436,7 @@ SYSCALL_DEFINE3(socket, int, family, int
24840         if (retval < 0)
24841                 goto out;
24842  
24843 +       set_bit(SOCK_USER_SOCKET, &sock->flags);
24844         retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
24845         if (retval < 0)
24846                 goto out_release;
24847 @@ -1439,10 +1478,12 @@ SYSCALL_DEFINE4(socketpair, int, family,
24848         err = sock_create(family, type, protocol, &sock1);
24849         if (err < 0)
24850                 goto out;
24851 +       set_bit(SOCK_USER_SOCKET, &sock1->flags);
24852  
24853         err = sock_create(family, type, protocol, &sock2);
24854         if (err < 0)
24855                 goto out_release_1;
24856 +       set_bit(SOCK_USER_SOCKET, &sock2->flags);
24857  
24858         err = sock1->ops->socketpair(sock1, sock2);
24859         if (err < 0)
24860 diff -NurpP --minimal linux-3.18.5/net/sunrpc/auth.c linux-3.18.5-vs2.3.7.3/net/sunrpc/auth.c
24861 --- linux-3.18.5/net/sunrpc/auth.c      2015-01-16 22:19:32.000000000 +0000
24862 +++ linux-3.18.5-vs2.3.7.3/net/sunrpc/auth.c    2015-01-19 11:18:55.000000000 +0000
24863 @@ -15,6 +15,7 @@
24864  #include <linux/sunrpc/clnt.h>
24865  #include <linux/sunrpc/gss_api.h>
24866  #include <linux/spinlock.h>
24867 +#include <linux/vs_tag.h>
24868  
24869  #ifdef RPC_DEBUG
24870  # define RPCDBG_FACILITY       RPCDBG_AUTH
24871 @@ -630,6 +631,7 @@ rpcauth_lookupcred(struct rpc_auth *auth
24872         memset(&acred, 0, sizeof(acred));
24873         acred.uid = cred->fsuid;
24874         acred.gid = cred->fsgid;
24875 +       acred.tag = make_ktag(&init_user_ns, dx_current_tag());
24876         acred.group_info = cred->group_info;
24877         ret = auth->au_ops->lookup_cred(auth, &acred, flags);
24878         return ret;
24879 @@ -669,6 +671,7 @@ rpcauth_bind_root_cred(struct rpc_task *
24880         struct auth_cred acred = {
24881                 .uid = GLOBAL_ROOT_UID,
24882                 .gid = GLOBAL_ROOT_GID,
24883 +               .tag = KTAGT_INIT(dx_current_tag()),
24884         };
24885  
24886         dprintk("RPC: %5u looking up %s cred\n",
24887 diff -NurpP --minimal linux-3.18.5/net/sunrpc/auth_unix.c linux-3.18.5-vs2.3.7.3/net/sunrpc/auth_unix.c
24888 --- linux-3.18.5/net/sunrpc/auth_unix.c 2013-11-25 15:47:08.000000000 +0000
24889 +++ linux-3.18.5-vs2.3.7.3/net/sunrpc/auth_unix.c       2015-01-19 10:58:32.000000000 +0000
24890 @@ -13,11 +13,13 @@
24891  #include <linux/sunrpc/clnt.h>
24892  #include <linux/sunrpc/auth.h>
24893  #include <linux/user_namespace.h>
24894 +#include <linux/vs_tag.h>
24895  
24896  #define NFS_NGROUPS    16
24897  
24898  struct unx_cred {
24899         struct rpc_cred         uc_base;
24900 +       ktag_t                  uc_tag;
24901         kgid_t                  uc_gid;
24902         kgid_t                  uc_gids[NFS_NGROUPS];
24903  };
24904 @@ -80,6 +82,7 @@ unx_create_cred(struct rpc_auth *auth, s
24905                 groups = NFS_NGROUPS;
24906  
24907         cred->uc_gid = acred->gid;
24908 +       cred->uc_tag = acred->tag;
24909         for (i = 0; i < groups; i++)
24910                 cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
24911         if (i < NFS_NGROUPS)
24912 @@ -121,7 +124,9 @@ unx_match(struct auth_cred *acred, struc
24913         unsigned int i;
24914  
24915  
24916 -       if (!uid_eq(cred->uc_uid, acred->uid) || !gid_eq(cred->uc_gid, acred->gid))
24917 +       if (!uid_eq(cred->uc_uid, acred->uid) ||
24918 +           !gid_eq(cred->uc_gid, acred->gid) ||
24919 +           !tag_eq(cred->uc_tag, acred->tag))
24920                 return 0;
24921  
24922         if (acred->group_info != NULL)
24923 @@ -146,7 +151,7 @@ unx_marshal(struct rpc_task *task, __be3
24924         struct rpc_clnt *clnt = task->tk_client;
24925         struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base);
24926         __be32          *base, *hold;
24927 -       int             i;
24928 +       int             i, tag;
24929  
24930         *p++ = htonl(RPC_AUTH_UNIX);
24931         base = p++;
24932 @@ -157,8 +162,11 @@ unx_marshal(struct rpc_task *task, __be3
24933          */
24934         p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
24935  
24936 -       *p++ = htonl((u32) from_kuid(&init_user_ns, cred->uc_uid));
24937 -       *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gid));
24938 +       tag = task->tk_client->cl_tag;
24939 +       *p++ = htonl((u32) from_kuid(&init_user_ns,
24940 +               TAGINO_KUID(tag, cred->uc_uid, cred->uc_tag)));
24941 +       *p++ = htonl((u32) from_kgid(&init_user_ns,
24942 +               TAGINO_KGID(tag, cred->uc_gid, cred->uc_tag)));
24943         hold = p++;
24944         for (i = 0; i < 16 && gid_valid(cred->uc_gids[i]); i++)
24945                 *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gids[i]));
24946 diff -NurpP --minimal linux-3.18.5/net/sunrpc/clnt.c linux-3.18.5-vs2.3.7.3/net/sunrpc/clnt.c
24947 --- linux-3.18.5/net/sunrpc/clnt.c      2015-01-17 02:40:30.000000000 +0000
24948 +++ linux-3.18.5-vs2.3.7.3/net/sunrpc/clnt.c    2015-01-19 10:58:32.000000000 +0000
24949 @@ -31,6 +31,7 @@
24950  #include <linux/in.h>
24951  #include <linux/in6.h>
24952  #include <linux/un.h>
24953 +#include <linux/vs_cvirt.h>
24954  
24955  #include <linux/sunrpc/clnt.h>
24956  #include <linux/sunrpc/addr.h>
24957 @@ -468,6 +469,9 @@ struct rpc_clnt *rpc_create_xprt(struct
24958         if (!(args->flags & RPC_CLNT_CREATE_QUIET))
24959                 clnt->cl_chatty = 1;
24960  
24961 +       /* TODO: handle RPC_CLNT_CREATE_TAGGED
24962 +       if (args->flags & RPC_CLNT_CREATE_TAGGED)
24963 +               clnt->cl_tag = 1; */
24964         return clnt;
24965  }
24966  EXPORT_SYMBOL_GPL(rpc_create_xprt);
24967 diff -NurpP --minimal linux-3.18.5/net/unix/af_unix.c linux-3.18.5-vs2.3.7.3/net/unix/af_unix.c
24968 --- linux-3.18.5/net/unix/af_unix.c     2014-09-03 13:19:49.000000000 +0000
24969 +++ linux-3.18.5-vs2.3.7.3/net/unix/af_unix.c   2015-01-19 10:58:32.000000000 +0000
24970 @@ -117,6 +117,8 @@
24971  #include <net/checksum.h>
24972  #include <linux/security.h>
24973  #include <linux/freezer.h>
24974 +#include <linux/vs_context.h>
24975 +#include <linux/vs_limit.h>
24976  
24977  struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
24978  EXPORT_SYMBOL_GPL(unix_socket_table);
24979 @@ -272,6 +274,8 @@ static struct sock *__unix_find_socket_b
24980                 if (!net_eq(sock_net(s), net))
24981                         continue;
24982  
24983 +               if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT))
24984 +                       continue;
24985                 if (u->addr->len == len &&
24986                     !memcmp(u->addr->name, sunname, len))
24987                         goto found;
24988 @@ -2283,6 +2287,8 @@ static struct sock *unix_from_bucket(str
24989         for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
24990                 if (sock_net(sk) != seq_file_net(seq))
24991                         continue;
24992 +               if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24993 +                       continue;
24994                 if (++count == offset)
24995                         break;
24996         }
24997 @@ -2300,6 +2306,8 @@ static struct sock *unix_next_socket(str
24998                 sk = sk_next(sk);
24999                 if (!sk)
25000                         goto next_bucket;
25001 +               if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
25002 +                       continue;
25003                 if (sock_net(sk) == seq_file_net(seq))
25004                         return sk;
25005         }
25006 diff -NurpP --minimal linux-3.18.5/scripts/checksyscalls.sh linux-3.18.5-vs2.3.7.3/scripts/checksyscalls.sh
25007 --- linux-3.18.5/scripts/checksyscalls.sh       2014-06-12 13:03:01.000000000 +0000
25008 +++ linux-3.18.5-vs2.3.7.3/scripts/checksyscalls.sh     2015-01-19 10:58:32.000000000 +0000
25009 @@ -196,7 +196,6 @@ cat << EOF
25010  #define __IGNORE_afs_syscall
25011  #define __IGNORE_getpmsg
25012  #define __IGNORE_putpmsg
25013 -#define __IGNORE_vserver
25014  EOF
25015  }
25016  
25017 diff -NurpP --minimal linux-3.18.5/security/commoncap.c linux-3.18.5-vs2.3.7.3/security/commoncap.c
25018 --- linux-3.18.5/security/commoncap.c   2015-01-16 22:19:32.000000000 +0000
25019 +++ linux-3.18.5-vs2.3.7.3/security/commoncap.c 2015-01-19 10:58:32.000000000 +0000
25020 @@ -76,6 +76,7 @@ int cap_netlink_send(struct sock *sk, st
25021  int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
25022                 int cap, int audit)
25023  {
25024 +       struct vx_info *vxi = current_vx_info(); /* FIXME: get vxi from cred? */
25025         struct user_namespace *ns = targ_ns;
25026  
25027         /* See if cred has the capability in the target user namespace
25028 @@ -84,8 +85,12 @@ int cap_capable(const struct cred *cred,
25029          */
25030         for (;;) {
25031                 /* Do we have the necessary capabilities? */
25032 -               if (ns == cred->user_ns)
25033 -                       return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM;
25034 +               if (ns == cred->user_ns) {
25035 +                       if (vx_info_flags(vxi, VXF_STATE_SETUP, 0) &&
25036 +                           cap_raised(cred->cap_effective, cap))
25037 +                               return 0;
25038 +                       return vx_cap_raised(vxi, cred->cap_effective, cap) ? 0 : -EPERM;
25039 +               }
25040  
25041                 /* Have we tried all of the parent namespaces? */
25042                 if (ns == &init_user_ns)
25043 @@ -631,7 +636,7 @@ int cap_inode_setxattr(struct dentry *de
25044  
25045         if (!strncmp(name, XATTR_SECURITY_PREFIX,
25046                      sizeof(XATTR_SECURITY_PREFIX) - 1) &&
25047 -           !capable(CAP_SYS_ADMIN))
25048 +               !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY))
25049                 return -EPERM;
25050         return 0;
25051  }
25052 @@ -657,7 +662,7 @@ int cap_inode_removexattr(struct dentry
25053  
25054         if (!strncmp(name, XATTR_SECURITY_PREFIX,
25055                      sizeof(XATTR_SECURITY_PREFIX) - 1) &&
25056 -           !capable(CAP_SYS_ADMIN))
25057 +               !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY))
25058                 return -EPERM;
25059         return 0;
25060  }
25061 diff -NurpP --minimal linux-3.18.5/security/selinux/hooks.c linux-3.18.5-vs2.3.7.3/security/selinux/hooks.c
25062 --- linux-3.18.5/security/selinux/hooks.c       2015-01-17 02:40:31.000000000 +0000
25063 +++ linux-3.18.5-vs2.3.7.3/security/selinux/hooks.c     2015-01-19 10:58:32.000000000 +0000
25064 @@ -68,7 +68,6 @@
25065  #include <linux/dccp.h>
25066  #include <linux/quota.h>
25067  #include <linux/un.h>          /* for Unix socket types */
25068 -#include <net/af_unix.h>       /* for Unix socket types */
25069  #include <linux/parser.h>
25070  #include <linux/nfs_mount.h>
25071  #include <net/ipv6.h>
This page took 2.65271 seconds and 3 git commands to generate.