]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-vserver-2.3.patch
- up to 4.1.42
[packages/kernel.git] / kernel-vserver-2.3.patch
1 diff -NurpP --minimal linux-4.1.41/Documentation/vserver/debug.txt linux-4.1.41-vs2.3.8.5.3/Documentation/vserver/debug.txt
2 --- linux-4.1.41/Documentation/vserver/debug.txt        1970-01-01 00:00:00.000000000 +0000
3 +++ linux-4.1.41-vs2.3.8.5.3/Documentation/vserver/debug.txt    2016-07-05 04:41:47.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-4.1.41/arch/alpha/Kconfig linux-4.1.41-vs2.3.8.5.3/arch/alpha/Kconfig
160 --- linux-4.1.41/arch/alpha/Kconfig     2015-07-06 20:41:36.000000000 +0000
161 +++ linux-4.1.41-vs2.3.8.5.3/arch/alpha/Kconfig 2016-07-05 04:41:47.000000000 +0000
162 @@ -744,6 +744,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-4.1.41/arch/alpha/kernel/systbls.S linux-4.1.41-vs2.3.8.5.3/arch/alpha/kernel/systbls.S
172 --- linux-4.1.41/arch/alpha/kernel/systbls.S    2015-07-06 20:41:36.000000000 +0000
173 +++ linux-4.1.41-vs2.3.8.5.3/arch/alpha/kernel/systbls.S        2016-07-05 04:41:47.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-4.1.41/arch/alpha/kernel/traps.c linux-4.1.41-vs2.3.8.5.3/arch/alpha/kernel/traps.c
184 --- linux-4.1.41/arch/alpha/kernel/traps.c      2015-07-06 20:41:36.000000000 +0000
185 +++ linux-4.1.41-vs2.3.8.5.3/arch/alpha/kernel/traps.c  2016-07-05 04:41:47.000000000 +0000
186 @@ -174,7 +174,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-4.1.41/arch/arm/Kconfig linux-4.1.41-vs2.3.8.5.3/arch/arm/Kconfig
197 --- linux-4.1.41/arch/arm/Kconfig       2017-06-23 10:03:35.000000000 +0000
198 +++ linux-4.1.41-vs2.3.8.5.3/arch/arm/Kconfig   2016-07-05 04:41:47.000000000 +0000
199 @@ -2110,6 +2110,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-4.1.41/arch/arm/kernel/calls.S linux-4.1.41-vs2.3.8.5.3/arch/arm/kernel/calls.S
209 --- linux-4.1.41/arch/arm/kernel/calls.S        2015-04-12 22:12:50.000000000 +0000
210 +++ linux-4.1.41-vs2.3.8.5.3/arch/arm/kernel/calls.S    2016-07-05 04:41:47.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-4.1.41/arch/arm/kernel/traps.c linux-4.1.41-vs2.3.8.5.3/arch/arm/kernel/traps.c
221 --- linux-4.1.41/arch/arm/kernel/traps.c        2015-07-06 20:41:36.000000000 +0000
222 +++ linux-4.1.41-vs2.3.8.5.3/arch/arm/kernel/traps.c    2016-07-05 04:41:47.000000000 +0000
223 @@ -250,8 +250,8 @@ static int __die(const char *str, int er
224  
225         print_modules();
226         __show_regs(regs);
227 -       pr_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 +       pr_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-4.1.41/arch/cris/Kconfig linux-4.1.41-vs2.3.8.5.3/arch/cris/Kconfig
235 --- linux-4.1.41/arch/cris/Kconfig      2015-07-06 20:41:36.000000000 +0000
236 +++ linux-4.1.41-vs2.3.8.5.3/arch/cris/Kconfig  2016-07-05 04:41:47.000000000 +0000
237 @@ -570,6 +570,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-4.1.41/arch/ia64/Kconfig linux-4.1.41-vs2.3.8.5.3/arch/ia64/Kconfig
247 --- linux-4.1.41/arch/ia64/Kconfig      2015-07-06 20:41:36.000000000 +0000
248 +++ linux-4.1.41-vs2.3.8.5.3/arch/ia64/Kconfig  2016-07-05 04:41:47.000000000 +0000
249 @@ -628,6 +628,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-4.1.41/arch/ia64/kernel/entry.S linux-4.1.41-vs2.3.8.5.3/arch/ia64/kernel/entry.S
259 --- linux-4.1.41/arch/ia64/kernel/entry.S       2015-04-12 22:12:50.000000000 +0000
260 +++ linux-4.1.41-vs2.3.8.5.3/arch/ia64/kernel/entry.S   2016-07-05 04:41:47.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-4.1.41/arch/ia64/kernel/ptrace.c linux-4.1.41-vs2.3.8.5.3/arch/ia64/kernel/ptrace.c
271 --- linux-4.1.41/arch/ia64/kernel/ptrace.c      2015-04-12 22:12:50.000000000 +0000
272 +++ linux-4.1.41-vs2.3.8.5.3/arch/ia64/kernel/ptrace.c  2016-07-05 04:41:47.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-4.1.41/arch/ia64/kernel/traps.c linux-4.1.41-vs2.3.8.5.3/arch/ia64/kernel/traps.c
282 --- linux-4.1.41/arch/ia64/kernel/traps.c       2015-04-12 22:12:50.000000000 +0000
283 +++ linux-4.1.41-vs2.3.8.5.3/arch/ia64/kernel/traps.c   2016-07-05 04:41:47.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-4.1.41/arch/m32r/kernel/traps.c linux-4.1.41-vs2.3.8.5.3/arch/m32r/kernel/traps.c
309 --- linux-4.1.41/arch/m32r/kernel/traps.c       2015-04-12 22:12:50.000000000 +0000
310 +++ linux-4.1.41-vs2.3.8.5.3/arch/m32r/kernel/traps.c   2016-07-05 04:41:47.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-4.1.41/arch/m68k/Kconfig linux-4.1.41-vs2.3.8.5.3/arch/m68k/Kconfig
324 --- linux-4.1.41/arch/m68k/Kconfig      2015-07-06 20:41:36.000000000 +0000
325 +++ linux-4.1.41-vs2.3.8.5.3/arch/m68k/Kconfig  2016-07-05 04:41:47.000000000 +0000
326 @@ -163,6 +163,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-4.1.41/arch/mips/Kconfig linux-4.1.41-vs2.3.8.5.3/arch/mips/Kconfig
336 --- linux-4.1.41/arch/mips/Kconfig      2017-06-23 10:03:38.000000000 +0000
337 +++ linux-4.1.41-vs2.3.8.5.3/arch/mips/Kconfig  2017-06-23 10:07:02.000000000 +0000
338 @@ -2889,6 +2889,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-4.1.41/arch/mips/kernel/ptrace.c linux-4.1.41-vs2.3.8.5.3/arch/mips/kernel/ptrace.c
348 --- linux-4.1.41/arch/mips/kernel/ptrace.c      2017-06-23 10:03:38.000000000 +0000
349 +++ linux-4.1.41-vs2.3.8.5.3/arch/mips/kernel/ptrace.c  2016-07-05 04:41:47.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 @@ -584,6 +585,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-4.1.41/arch/mips/kernel/scall32-o32.S linux-4.1.41-vs2.3.8.5.3/arch/mips/kernel/scall32-o32.S
369 --- linux-4.1.41/arch/mips/kernel/scall32-o32.S 2015-04-12 22:12:50.000000000 +0000
370 +++ linux-4.1.41-vs2.3.8.5.3/arch/mips/kernel/scall32-o32.S     2016-07-05 04:41:47.000000000 +0000
371 @@ -502,7 +502,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-4.1.41/arch/mips/kernel/scall64-64.S linux-4.1.41-vs2.3.8.5.3/arch/mips/kernel/scall64-64.S
381 --- linux-4.1.41/arch/mips/kernel/scall64-64.S  2017-06-23 10:03:38.000000000 +0000
382 +++ linux-4.1.41-vs2.3.8.5.3/arch/mips/kernel/scall64-64.S      2016-07-05 04:41:47.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-4.1.41/arch/mips/kernel/scall64-n32.S linux-4.1.41-vs2.3.8.5.3/arch/mips/kernel/scall64-n32.S
393 --- linux-4.1.41/arch/mips/kernel/scall64-n32.S 2017-06-23 10:03:38.000000000 +0000
394 +++ linux-4.1.41-vs2.3.8.5.3/arch/mips/kernel/scall64-n32.S     2016-10-25 21:31:17.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-4.1.41/arch/mips/kernel/scall64-o32.S linux-4.1.41-vs2.3.8.5.3/arch/mips/kernel/scall64-o32.S
405 --- linux-4.1.41/arch/mips/kernel/scall64-o32.S 2017-06-23 10:03:38.000000000 +0000
406 +++ linux-4.1.41-vs2.3.8.5.3/arch/mips/kernel/scall64-o32.S     2016-10-25 21:31:17.000000000 +0000
407 @@ -487,7 +487,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-4.1.41/arch/mips/kernel/traps.c linux-4.1.41-vs2.3.8.5.3/arch/mips/kernel/traps.c
417 --- linux-4.1.41/arch/mips/kernel/traps.c       2017-06-23 10:03:38.000000000 +0000
418 +++ linux-4.1.41-vs2.3.8.5.3/arch/mips/kernel/traps.c   2016-07-05 04:41:47.000000000 +0000
419 @@ -349,9 +349,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-4.1.41/arch/parisc/Kconfig linux-4.1.41-vs2.3.8.5.3/arch/parisc/Kconfig
434 --- linux-4.1.41/arch/parisc/Kconfig    2015-07-06 20:41:37.000000000 +0000
435 +++ linux-4.1.41-vs2.3.8.5.3/arch/parisc/Kconfig        2016-07-05 04:41:47.000000000 +0000
436 @@ -338,6 +338,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-4.1.41/arch/parisc/kernel/syscall_table.S linux-4.1.41-vs2.3.8.5.3/arch/parisc/kernel/syscall_table.S
446 --- linux-4.1.41/arch/parisc/kernel/syscall_table.S     2015-04-12 22:12:50.000000000 +0000
447 +++ linux-4.1.41-vs2.3.8.5.3/arch/parisc/kernel/syscall_table.S 2016-07-05 04:41:47.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-4.1.41/arch/parisc/kernel/traps.c linux-4.1.41-vs2.3.8.5.3/arch/parisc/kernel/traps.c
458 --- linux-4.1.41/arch/parisc/kernel/traps.c     2017-06-23 10:03:39.000000000 +0000
459 +++ linux-4.1.41-vs2.3.8.5.3/arch/parisc/kernel/traps.c 2016-07-05 04:41:47.000000000 +0000
460 @@ -235,8 +235,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 @@ -266,8 +267,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-4.1.41/arch/powerpc/Kconfig linux-4.1.41-vs2.3.8.5.3/arch/powerpc/Kconfig
484 --- linux-4.1.41/arch/powerpc/Kconfig   2015-07-06 20:41:37.000000000 +0000
485 +++ linux-4.1.41-vs2.3.8.5.3/arch/powerpc/Kconfig       2016-07-05 04:41:47.000000000 +0000
486 @@ -1077,6 +1077,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-4.1.41/arch/powerpc/include/uapi/asm/unistd.h linux-4.1.41-vs2.3.8.5.3/arch/powerpc/include/uapi/asm/unistd.h
496 --- linux-4.1.41/arch/powerpc/include/uapi/asm/unistd.h 2015-07-06 20:41:37.000000000 +0000
497 +++ linux-4.1.41-vs2.3.8.5.3/arch/powerpc/include/uapi/asm/unistd.h     2016-07-05 04:41:47.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-4.1.41/arch/powerpc/kernel/traps.c linux-4.1.41-vs2.3.8.5.3/arch/powerpc/kernel/traps.c
508 --- linux-4.1.41/arch/powerpc/kernel/traps.c    2015-04-12 22:12:50.000000000 +0000
509 +++ linux-4.1.41-vs2.3.8.5.3/arch/powerpc/kernel/traps.c        2016-07-05 04:41:47.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-4.1.41/arch/s390/Kconfig linux-4.1.41-vs2.3.8.5.3/arch/s390/Kconfig
523 --- linux-4.1.41/arch/s390/Kconfig      2015-07-06 20:41:37.000000000 +0000
524 +++ linux-4.1.41-vs2.3.8.5.3/arch/s390/Kconfig  2016-07-05 04:41:47.000000000 +0000
525 @@ -653,6 +653,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-4.1.41/arch/s390/include/asm/tlb.h linux-4.1.41-vs2.3.8.5.3/arch/s390/include/asm/tlb.h
535 --- linux-4.1.41/arch/s390/include/asm/tlb.h    2015-07-06 20:41:37.000000000 +0000
536 +++ linux-4.1.41-vs2.3.8.5.3/arch/s390/include/asm/tlb.h        2016-07-05 04:41:47.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-4.1.41/arch/s390/include/uapi/asm/unistd.h linux-4.1.41-vs2.3.8.5.3/arch/s390/include/uapi/asm/unistd.h
546 --- linux-4.1.41/arch/s390/include/uapi/asm/unistd.h    2015-04-12 22:12:50.000000000 +0000
547 +++ linux-4.1.41-vs2.3.8.5.3/arch/s390/include/uapi/asm/unistd.h        2016-07-05 04:41:47.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-4.1.41/arch/s390/kernel/ptrace.c linux-4.1.41-vs2.3.8.5.3/arch/s390/kernel/ptrace.c
558 --- linux-4.1.41/arch/s390/kernel/ptrace.c      2015-07-06 20:41:37.000000000 +0000
559 +++ linux-4.1.41-vs2.3.8.5.3/arch/s390/kernel/ptrace.c  2016-07-05 04:41:47.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-4.1.41/arch/s390/kernel/syscalls.S linux-4.1.41-vs2.3.8.5.3/arch/s390/kernel/syscalls.S
569 --- linux-4.1.41/arch/s390/kernel/syscalls.S    2015-07-06 20:41:37.000000000 +0000
570 +++ linux-4.1.41-vs2.3.8.5.3/arch/s390/kernel/syscalls.S        2016-07-05 04:41:47.000000000 +0000
571 @@ -271,7 +271,7 @@ SYSCALL(sys_clock_settime,compat_sys_clo
572  SYSCALL(sys_clock_gettime,compat_sys_clock_gettime)    /* 260 */
573  SYSCALL(sys_clock_getres,compat_sys_clock_getres)
574  SYSCALL(sys_clock_nanosleep,compat_sys_clock_nanosleep)
575 -NI_SYSCALL                                             /* reserved for vserver */
576 +SYSCALL(sys_vserver,sys_vserver,sys32_vserver)
577  SYSCALL(sys_ni_syscall,compat_sys_s390_fadvise64_64)
578  SYSCALL(sys_statfs64,compat_sys_statfs64)
579  SYSCALL(sys_fstatfs64,compat_sys_fstatfs64)
580 diff -NurpP --minimal linux-4.1.41/arch/sh/Kconfig linux-4.1.41-vs2.3.8.5.3/arch/sh/Kconfig
581 --- linux-4.1.41/arch/sh/Kconfig        2015-07-06 20:41:37.000000000 +0000
582 +++ linux-4.1.41-vs2.3.8.5.3/arch/sh/Kconfig    2016-07-05 04:41:47.000000000 +0000
583 @@ -882,6 +882,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-4.1.41/arch/sh/kernel/irq.c linux-4.1.41-vs2.3.8.5.3/arch/sh/kernel/irq.c
593 --- linux-4.1.41/arch/sh/kernel/irq.c   2015-07-06 20:41:37.000000000 +0000
594 +++ linux-4.1.41-vs2.3.8.5.3/arch/sh/kernel/irq.c       2016-07-05 04:41:47.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-4.1.41/arch/sparc/Kconfig linux-4.1.41-vs2.3.8.5.3/arch/sparc/Kconfig
604 --- linux-4.1.41/arch/sparc/Kconfig     2015-07-06 20:41:37.000000000 +0000
605 +++ linux-4.1.41-vs2.3.8.5.3/arch/sparc/Kconfig 2016-07-05 04:41:47.000000000 +0000
606 @@ -564,6 +564,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-4.1.41/arch/sparc/include/uapi/asm/unistd.h linux-4.1.41-vs2.3.8.5.3/arch/sparc/include/uapi/asm/unistd.h
616 --- linux-4.1.41/arch/sparc/include/uapi/asm/unistd.h   2015-04-12 22:12:50.000000000 +0000
617 +++ linux-4.1.41-vs2.3.8.5.3/arch/sparc/include/uapi/asm/unistd.h       2016-07-05 04:41:47.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-4.1.41/arch/sparc/kernel/systbls_32.S linux-4.1.41-vs2.3.8.5.3/arch/sparc/kernel/systbls_32.S
628 --- linux-4.1.41/arch/sparc/kernel/systbls_32.S 2015-04-12 22:12:50.000000000 +0000
629 +++ linux-4.1.41-vs2.3.8.5.3/arch/sparc/kernel/systbls_32.S     2016-07-05 04:41:47.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-4.1.41/arch/sparc/kernel/systbls_64.S linux-4.1.41-vs2.3.8.5.3/arch/sparc/kernel/systbls_64.S
640 --- linux-4.1.41/arch/sparc/kernel/systbls_64.S 2015-04-12 22:12:50.000000000 +0000
641 +++ linux-4.1.41-vs2.3.8.5.3/arch/sparc/kernel/systbls_64.S     2016-07-05 04:41:47.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 @@ -151,7 +151,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-4.1.41/arch/um/Kconfig.rest linux-4.1.41-vs2.3.8.5.3/arch/um/Kconfig.rest
661 --- linux-4.1.41/arch/um/Kconfig.rest   2015-04-12 22:12:50.000000000 +0000
662 +++ linux-4.1.41-vs2.3.8.5.3/arch/um/Kconfig.rest       2016-07-05 04:41:47.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-4.1.41/arch/x86/Kconfig linux-4.1.41-vs2.3.8.5.3/arch/x86/Kconfig
673 --- linux-4.1.41/arch/x86/Kconfig       2015-07-06 20:41:37.000000000 +0000
674 +++ linux-4.1.41-vs2.3.8.5.3/arch/x86/Kconfig   2016-07-05 04:41:47.000000000 +0000
675 @@ -2587,6 +2587,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-4.1.41/arch/x86/syscalls/syscall_32.tbl linux-4.1.41-vs2.3.8.5.3/arch/x86/syscalls/syscall_32.tbl
685 --- linux-4.1.41/arch/x86/syscalls/syscall_32.tbl       2017-06-23 10:03:41.000000000 +0000
686 +++ linux-4.1.41-vs2.3.8.5.3/arch/x86/syscalls/syscall_32.tbl   2016-10-25 21:31:17.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-4.1.41/arch/x86/syscalls/syscall_64.tbl linux-4.1.41-vs2.3.8.5.3/arch/x86/syscalls/syscall_64.tbl
697 --- linux-4.1.41/arch/x86/syscalls/syscall_64.tbl       2015-07-06 20:41:37.000000000 +0000
698 +++ linux-4.1.41-vs2.3.8.5.3/arch/x86/syscalls/syscall_64.tbl   2016-07-05 04:41:47.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-4.1.41/block/ioprio.c linux-4.1.41-vs2.3.8.5.3/block/ioprio.c
709 --- linux-4.1.41/block/ioprio.c 2017-06-23 10:03:42.000000000 +0000
710 +++ linux-4.1.41-vs2.3.8.5.3/block/ioprio.c     2016-10-25 21:31:17.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 @@ -202,6 +205,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-4.1.41/drivers/block/Kconfig linux-4.1.41-vs2.3.8.5.3/drivers/block/Kconfig
738 --- linux-4.1.41/drivers/block/Kconfig  2015-07-06 20:41:37.000000000 +0000
739 +++ linux-4.1.41-vs2.3.8.5.3/drivers/block/Kconfig      2016-07-05 04:41:47.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-4.1.41/drivers/block/Makefile linux-4.1.41-vs2.3.8.5.3/drivers/block/Makefile
755 --- linux-4.1.41/drivers/block/Makefile 2015-07-06 20:41:37.000000000 +0000
756 +++ linux-4.1.41-vs2.3.8.5.3/drivers/block/Makefile     2016-07-05 04:41:47.000000000 +0000
757 @@ -34,6 +34,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-4.1.41/drivers/block/loop.c linux-4.1.41-vs2.3.8.5.3/drivers/block/loop.c
766 --- linux-4.1.41/drivers/block/loop.c   2017-06-23 10:03:42.000000000 +0000
767 +++ linux-4.1.41-vs2.3.8.5.3/drivers/block/loop.c       2017-05-30 07:39:22.000000000 +0000
768 @@ -76,6 +76,7 @@
769  #include <linux/miscdevice.h>
770  #include <linux/falloc.h>
771  #include <linux/uio.h>
772 +#include <linux/vs_context.h>
773  #include "loop.h"
774  
775  #include <asm/uaccess.h>
776 @@ -737,6 +738,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 = NULL;
783         lo->ioctl = NULL;
784 @@ -853,6 +855,7 @@ static int loop_clr_fd(struct loop_devic
785         lo->lo_offset = 0;
786         lo->lo_sizelimit = 0;
787         lo->lo_encrypt_key_size = 0;
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 @@ -898,7 +901,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 @@ -988,7 +991,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 @@ -1330,6 +1334,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-4.1.41/drivers/block/loop.h linux-4.1.41-vs2.3.8.5.3/drivers/block/loop.h
824 --- linux-4.1.41/drivers/block/loop.h   2017-06-23 10:03:42.000000000 +0000
825 +++ linux-4.1.41-vs2.3.8.5.3/drivers/block/loop.h       2016-07-05 04:41:47.000000000 +0000
826 @@ -43,6 +43,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-4.1.41/drivers/block/vroot.c linux-4.1.41-vs2.3.8.5.3/drivers/block/vroot.c
835 --- linux-4.1.41/drivers/block/vroot.c  1970-01-01 00:00:00.000000000 +0000
836 +++ linux-4.1.41-vs2.3.8.5.3/drivers/block/vroot.c      2016-07-05 04:41:47.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_path.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-4.1.41/drivers/infiniband/core/addr.c linux-4.1.41-vs2.3.8.5.3/drivers/infiniband/core/addr.c
1129 --- linux-4.1.41/drivers/infiniband/core/addr.c 2015-07-06 20:41:38.000000000 +0000
1130 +++ linux-4.1.41-vs2.3.8.5.3/drivers/infiniband/core/addr.c     2016-07-05 04:41:47.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-4.1.41/drivers/md/dm-ioctl.c linux-4.1.41-vs2.3.8.5.3/drivers/md/dm-ioctl.c
1141 --- linux-4.1.41/drivers/md/dm-ioctl.c  2017-06-23 10:03:49.000000000 +0000
1142 +++ linux-4.1.41-vs2.3.8.5.3/drivers/md/dm-ioctl.c      2017-05-30 07:39:23.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 @@ -1801,8 +1813,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-4.1.41/drivers/md/dm.c linux-4.1.41-vs2.3.8.5.3/drivers/md/dm.c
1229 --- linux-4.1.41/drivers/md/dm.c        2017-06-23 10:03:49.000000000 +0000
1230 +++ linux-4.1.41-vs2.3.8.5.3/drivers/md/dm.c    2016-10-25 21:31:18.000000000 +0000
1231 @@ -24,6 +24,7 @@
1232  #include <linux/ktime.h>
1233  #include <linux/elevator.h> /* for rq_end_sector() */
1234  #include <linux/blk-mq.h>
1235 +#include <linux/vs_base.h>
1236  
1237  #include <trace/events/block.h>
1238  
1239 @@ -141,6 +142,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 @@ -442,6 +444,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 @@ -450,17 +453,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 +       ret = 0;
1272  out:
1273         spin_unlock(&_minor_lock);
1274 -
1275 -       return md ? 0 : -ENXIO;
1276 +       return ret;
1277  }
1278  
1279  static void dm_blk_close(struct gendisk *disk, fmode_t mode)
1280 @@ -876,6 +881,14 @@ int dm_set_geometry(struct mapped_device
1281         return 0;
1282  }
1283  
1284 +/*
1285 + * Get the xid associated with a dm device
1286 + */
1287 +vxid_t dm_get_xid(struct mapped_device *md)
1288 +{
1289 +       return md->xid;
1290 +}
1291 +
1292  /*-----------------------------------------------------------------
1293   * CRUD START:
1294   *   A more elegant soln is in the works that uses the queue
1295 @@ -2302,6 +2315,7 @@ static struct mapped_device *alloc_dev(i
1296         INIT_LIST_HEAD(&md->table_devices);
1297         spin_lock_init(&md->uevent_lock);
1298  
1299 +       md->xid = vx_current_xid();
1300         md->queue = blk_alloc_queue(GFP_KERNEL);
1301         if (!md->queue)
1302                 goto bad_queue;
1303 diff -NurpP --minimal linux-4.1.41/drivers/md/dm.h linux-4.1.41-vs2.3.8.5.3/drivers/md/dm.h
1304 --- linux-4.1.41/drivers/md/dm.h        2015-07-06 20:41:38.000000000 +0000
1305 +++ linux-4.1.41-vs2.3.8.5.3/drivers/md/dm.h    2016-07-05 04:41:47.000000000 +0000
1306 @@ -51,6 +51,8 @@ struct dm_dev_internal {
1307  struct dm_table;
1308  struct dm_md_mempools;
1309  
1310 +vxid_t dm_get_xid(struct mapped_device *md);
1311 +
1312  /*-----------------------------------------------------------------
1313   * Internal table functions.
1314   *---------------------------------------------------------------*/
1315 diff -NurpP --minimal linux-4.1.41/drivers/net/tun.c linux-4.1.41-vs2.3.8.5.3/drivers/net/tun.c
1316 --- linux-4.1.41/drivers/net/tun.c      2017-06-23 10:03:52.000000000 +0000
1317 +++ linux-4.1.41-vs2.3.8.5.3/drivers/net/tun.c  2016-10-25 21:31:18.000000000 +0000
1318 @@ -65,6 +65,7 @@
1319  #include <linux/nsproxy.h>
1320  #include <linux/virtio_net.h>
1321  #include <linux/rcupdate.h>
1322 +#include <linux/vs_network.h>
1323  #include <net/net_namespace.h>
1324  #include <net/netns/generic.h>
1325  #include <net/rtnetlink.h>
1326 @@ -181,6 +182,7 @@ struct tun_struct {
1327         unsigned int            flags;
1328         kuid_t                  owner;
1329         kgid_t                  group;
1330 +       vnid_t                  nid;
1331  
1332         struct net_device       *dev;
1333         netdev_features_t       set_features;
1334 @@ -421,6 +423,7 @@ static inline bool tun_not_capable(struc
1335         return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) ||
1336                   (gid_valid(tun->group) && !in_egroup_p(tun->group))) &&
1337                 !ns_capable(net->user_ns, CAP_NET_ADMIN);
1338 +               /* !cap_raised(current_cap(), CAP_NET_ADMIN) */
1339  }
1340  
1341  static void tun_set_real_num_queues(struct tun_struct *tun)
1342 @@ -1408,6 +1411,7 @@ static void tun_setup(struct net_device
1343  
1344         tun->owner = INVALID_UID;
1345         tun->group = INVALID_GID;
1346 +       tun->nid = nx_current_nid();
1347  
1348         dev->ethtool_ops = &tun_ethtool_ops;
1349         dev->destructor = tun_free_netdev;
1350 @@ -1608,7 +1612,7 @@ static int tun_set_iff(struct net *net,
1351                 int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ?
1352                              MAX_TAP_QUEUES : 1;
1353  
1354 -               if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
1355 +               if (!nx_ns_capable(net->user_ns, CAP_NET_ADMIN, NXC_TUN_CREATE))
1356                         return -EPERM;
1357                 err = security_tun_dev_create();
1358                 if (err < 0)
1359 @@ -1957,6 +1961,16 @@ static long __tun_chr_ioctl(struct file
1360                           from_kgid(&init_user_ns, tun->group));
1361                 break;
1362  
1363 +       case TUNSETNID:
1364 +               if (!capable(CAP_CONTEXT))
1365 +                       return -EPERM;
1366 +
1367 +               /* Set nid owner of the device */
1368 +               tun->nid = (vnid_t) arg;
1369 +
1370 +               tun_debug(KERN_INFO, tun, "nid owner set to %u\n", tun->nid);
1371 +               break;
1372 +
1373         case TUNSETLINK:
1374                 /* Only allow setting the type when the interface is down */
1375                 if (tun->dev->flags & IFF_UP) {
1376 diff -NurpP --minimal linux-4.1.41/drivers/scsi/cxgbi/libcxgbi.c linux-4.1.41-vs2.3.8.5.3/drivers/scsi/cxgbi/libcxgbi.c
1377 --- linux-4.1.41/drivers/scsi/cxgbi/libcxgbi.c  2015-04-12 22:12:50.000000000 +0000
1378 +++ linux-4.1.41-vs2.3.8.5.3/drivers/scsi/cxgbi/libcxgbi.c      2016-07-05 04:41:47.000000000 +0000
1379 @@ -764,7 +764,8 @@ static struct cxgbi_sock *cxgbi_check_ro
1380                 struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt);
1381  
1382                 err = ipv6_dev_get_saddr(&init_net, idev ? idev->dev : NULL,
1383 -                                        &daddr6->sin6_addr, 0, &pref_saddr);
1384 +                                        &daddr6->sin6_addr, 0, &pref_saddr,
1385 +                                        NULL);
1386                 if (err) {
1387                         pr_info("failed to get source address to reach %pI6\n",
1388                                 &daddr6->sin6_addr);
1389 diff -NurpP --minimal linux-4.1.41/drivers/tty/sysrq.c linux-4.1.41-vs2.3.8.5.3/drivers/tty/sysrq.c
1390 --- linux-4.1.41/drivers/tty/sysrq.c    2017-06-23 10:03:57.000000000 +0000
1391 +++ linux-4.1.41-vs2.3.8.5.3/drivers/tty/sysrq.c        2017-05-30 07:39:23.000000000 +0000
1392 @@ -47,6 +47,7 @@
1393  #include <linux/syscalls.h>
1394  #include <linux/of.h>
1395  #include <linux/rcupdate.h>
1396 +#include <linux/vserver/debug.h>
1397  
1398  #include <asm/ptrace.h>
1399  #include <asm/irq_regs.h>
1400 @@ -407,6 +408,21 @@ static struct sysrq_key_op sysrq_unrt_op
1401         .enable_mask    = SYSRQ_ENABLE_RTNICE,
1402  };
1403  
1404 +
1405 +#ifdef CONFIG_VSERVER_DEBUG
1406 +static void sysrq_handle_vxinfo(int key)
1407 +{
1408 +       dump_vx_info_inactive((key == 'x') ? 0 : 1);
1409 +}
1410 +
1411 +static struct sysrq_key_op sysrq_showvxinfo_op = {
1412 +       .handler        = sysrq_handle_vxinfo,
1413 +       .help_msg       = "conteXt",
1414 +       .action_msg     = "Show Context Info",
1415 +       .enable_mask    = SYSRQ_ENABLE_DUMP,
1416 +};
1417 +#endif
1418 +
1419  /* Key Operations table and lock */
1420  static DEFINE_SPINLOCK(sysrq_key_table_lock);
1421  
1422 @@ -462,7 +478,11 @@ static struct sysrq_key_op *sysrq_key_ta
1423         &sysrq_showstate_blocked_op,    /* w */
1424         /* x: May be registered on ppc/powerpc for xmon */
1425         /* x: May be registered on sparc64 for global PMU dump */
1426 +#ifdef CONFIG_VSERVER_DEBUG
1427 +       &sysrq_showvxinfo_op,           /* x */
1428 +#else
1429         NULL,                           /* x */
1430 +#endif
1431         /* y: May be registered on sparc64 for global register dump */
1432         NULL,                           /* y */
1433         &sysrq_ftrace_dump_op,          /* z */
1434 @@ -477,6 +497,8 @@ static int sysrq_key_table_key2index(int
1435                 retval = key - '0';
1436         else if ((key >= 'a') && (key <= 'z'))
1437                 retval = key + 10 - 'a';
1438 +       else if ((key >= 'A') && (key <= 'Z'))
1439 +               retval = key + 10 - 'A';
1440         else
1441                 retval = -1;
1442         return retval;
1443 diff -NurpP --minimal linux-4.1.41/drivers/tty/tty_io.c linux-4.1.41-vs2.3.8.5.3/drivers/tty/tty_io.c
1444 --- linux-4.1.41/drivers/tty/tty_io.c   2017-06-23 10:03:57.000000000 +0000
1445 +++ linux-4.1.41-vs2.3.8.5.3/drivers/tty/tty_io.c       2016-07-05 04:41:47.000000000 +0000
1446 @@ -104,6 +104,7 @@
1447  
1448  #include <linux/kmod.h>
1449  #include <linux/nsproxy.h>
1450 +#include <linux/vs_pid.h>
1451  
1452  #undef TTY_DEBUG_HANGUP
1453  
1454 @@ -2287,7 +2288,8 @@ static int tiocsti(struct tty_struct *tt
1455         char ch, mbz = 0;
1456         struct tty_ldisc *ld;
1457  
1458 -       if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
1459 +       if (((current->signal->tty != tty) &&
1460 +               !vx_capable(CAP_SYS_ADMIN, VXC_TIOCSTI)))
1461                 return -EPERM;
1462         if (get_user(ch, p))
1463                 return -EFAULT;
1464 @@ -2601,6 +2603,7 @@ static int tiocspgrp(struct tty_struct *
1465                 return -ENOTTY;
1466         if (get_user(pgrp_nr, p))
1467                 return -EFAULT;
1468 +       pgrp_nr = vx_rmap_pid(pgrp_nr);
1469         if (pgrp_nr < 0)
1470                 return -EINVAL;
1471         rcu_read_lock();
1472 diff -NurpP --minimal linux-4.1.41/fs/attr.c linux-4.1.41-vs2.3.8.5.3/fs/attr.c
1473 --- linux-4.1.41/fs/attr.c      2017-06-23 10:03:58.000000000 +0000
1474 +++ linux-4.1.41-vs2.3.8.5.3/fs/attr.c  2017-05-30 07:39:23.000000000 +0000
1475 @@ -15,6 +15,9 @@
1476  #include <linux/security.h>
1477  #include <linux/evm.h>
1478  #include <linux/ima.h>
1479 +#include <linux/proc_fs.h>
1480 +#include <linux/devpts_fs.h>
1481 +#include <linux/vs_tag.h>
1482  
1483  /**
1484   * setattr_prepare - check if attribute changes to a dentry are allowed
1485 @@ -80,6 +83,10 @@ int setattr_prepare(struct dentry *dentr
1486                         return -EPERM;
1487         }
1488  
1489 +       /* check for inode tag permission */
1490 +       if (dx_permission(inode, MAY_WRITE))
1491 +               return -EACCES;
1492 +
1493  kill_priv:
1494         /* User has permission for the change */
1495         if (ia_valid & ATTR_KILL_PRIV) {
1496 @@ -160,6 +167,8 @@ void setattr_copy(struct inode *inode, c
1497                 inode->i_uid = attr->ia_uid;
1498         if (ia_valid & ATTR_GID)
1499                 inode->i_gid = attr->ia_gid;
1500 +       if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode))
1501 +               inode->i_tag = attr->ia_tag;
1502         if (ia_valid & ATTR_ATIME)
1503                 inode->i_atime = timespec_trunc(attr->ia_atime,
1504                                                 inode->i_sb->s_time_gran);
1505 @@ -210,7 +219,8 @@ int notify_change(struct dentry * dentry
1506  
1507         WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
1508  
1509 -       if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
1510 +       if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
1511 +               ATTR_TAG | ATTR_TIMES_SET)) {
1512                 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1513                         return -EPERM;
1514         }
1515 diff -NurpP --minimal linux-4.1.41/fs/block_dev.c linux-4.1.41-vs2.3.8.5.3/fs/block_dev.c
1516 --- linux-4.1.41/fs/block_dev.c 2017-06-23 10:03:58.000000000 +0000
1517 +++ linux-4.1.41-vs2.3.8.5.3/fs/block_dev.c     2017-05-30 07:39:23.000000000 +0000
1518 @@ -27,6 +27,7 @@
1519  #include <linux/namei.h>
1520  #include <linux/log2.h>
1521  #include <linux/cleancache.h>
1522 +#include <linux/vs_device.h>
1523  #include <asm/uaccess.h>
1524  #include "internal.h"
1525  
1526 @@ -610,6 +611,7 @@ struct block_device *bdget(dev_t dev)
1527                 bdev->bd_invalidated = 0;
1528                 inode->i_mode = S_IFBLK;
1529                 inode->i_rdev = dev;
1530 +               inode->i_mdev = dev;
1531                 inode->i_bdev = bdev;
1532                 inode->i_data.a_ops = &def_blk_aops;
1533                 mapping_set_gfp_mask(&inode->i_data, GFP_USER);
1534 @@ -656,6 +658,11 @@ EXPORT_SYMBOL(bdput);
1535  static struct block_device *bd_acquire(struct inode *inode)
1536  {
1537         struct block_device *bdev;
1538 +       dev_t mdev;
1539 +
1540 +       if (!vs_map_blkdev(inode->i_rdev, &mdev, DATTR_OPEN))
1541 +               return NULL;
1542 +       inode->i_mdev = mdev;
1543  
1544         spin_lock(&bdev_lock);
1545         bdev = inode->i_bdev;
1546 @@ -666,7 +673,7 @@ static struct block_device *bd_acquire(s
1547         }
1548         spin_unlock(&bdev_lock);
1549  
1550 -       bdev = bdget(inode->i_rdev);
1551 +       bdev = bdget(mdev);
1552         if (bdev) {
1553                 spin_lock(&bdev_lock);
1554                 if (!inode->i_bdev) {
1555 diff -NurpP --minimal linux-4.1.41/fs/btrfs/ctree.h linux-4.1.41-vs2.3.8.5.3/fs/btrfs/ctree.h
1556 --- linux-4.1.41/fs/btrfs/ctree.h       2017-06-23 10:03:58.000000000 +0000
1557 +++ linux-4.1.41-vs2.3.8.5.3/fs/btrfs/ctree.h   2016-07-05 04:41:47.000000000 +0000
1558 @@ -731,11 +731,14 @@ struct btrfs_inode_item {
1559         /* modification sequence number for NFS */
1560         __le64 sequence;
1561  
1562 +       __le16 tag;
1563         /*
1564          * a little future expansion, for more than this we can
1565          * just grow the inode item and version it
1566          */
1567 -       __le64 reserved[4];
1568 +       __le16 reserved16;
1569 +       __le32 reserved32;
1570 +       __le64 reserved[3];
1571         struct btrfs_timespec atime;
1572         struct btrfs_timespec ctime;
1573         struct btrfs_timespec mtime;
1574 @@ -2156,6 +2159,8 @@ struct btrfs_ioctl_defrag_range_args {
1575  #define BTRFS_DEFAULT_COMMIT_INTERVAL  (30)
1576  #define BTRFS_DEFAULT_MAX_INLINE       (8192)
1577  
1578 +#define BTRFS_MOUNT_TAGGED             (1 << 24)
1579 +
1580  #define btrfs_clear_opt(o, opt)                ((o) &= ~BTRFS_MOUNT_##opt)
1581  #define btrfs_set_opt(o, opt)          ((o) |= BTRFS_MOUNT_##opt)
1582  #define btrfs_raw_test_opt(o, opt)     ((o) & BTRFS_MOUNT_##opt)
1583 @@ -2483,6 +2488,7 @@ BTRFS_SETGET_FUNCS(inode_block_group, st
1584  BTRFS_SETGET_FUNCS(inode_nlink, struct btrfs_inode_item, nlink, 32);
1585  BTRFS_SETGET_FUNCS(inode_uid, struct btrfs_inode_item, uid, 32);
1586  BTRFS_SETGET_FUNCS(inode_gid, struct btrfs_inode_item, gid, 32);
1587 +BTRFS_SETGET_FUNCS(inode_tag, struct btrfs_inode_item, tag, 16);
1588  BTRFS_SETGET_FUNCS(inode_mode, struct btrfs_inode_item, mode, 32);
1589  BTRFS_SETGET_FUNCS(inode_rdev, struct btrfs_inode_item, rdev, 64);
1590  BTRFS_SETGET_FUNCS(inode_flags, struct btrfs_inode_item, flags, 64);
1591 @@ -2530,6 +2536,10 @@ BTRFS_SETGET_FUNCS(extent_flags, struct
1592  
1593  BTRFS_SETGET_FUNCS(extent_refs_v0, struct btrfs_extent_item_v0, refs, 32);
1594  
1595 +#define BTRFS_INODE_IXUNLINK           (1 << 24)
1596 +#define BTRFS_INODE_BARRIER            (1 << 25)
1597 +#define BTRFS_INODE_COW                        (1 << 26)
1598 +
1599  
1600  BTRFS_SETGET_FUNCS(tree_block_level, struct btrfs_tree_block_info, level, 8);
1601  
1602 @@ -3960,6 +3970,7 @@ long btrfs_compat_ioctl(struct file *fil
1603  void btrfs_update_iflags(struct inode *inode);
1604  void btrfs_inherit_iflags(struct inode *inode, struct inode *dir);
1605  int btrfs_is_empty_uuid(u8 *uuid);
1606 +int btrfs_sync_flags(struct inode *inode, int, int);
1607  int btrfs_defrag_file(struct inode *inode, struct file *file,
1608                       struct btrfs_ioctl_defrag_range_args *range,
1609                       u64 newer_than, unsigned long max_pages);
1610 diff -NurpP --minimal linux-4.1.41/fs/btrfs/disk-io.c linux-4.1.41-vs2.3.8.5.3/fs/btrfs/disk-io.c
1611 --- linux-4.1.41/fs/btrfs/disk-io.c     2017-06-23 10:03:58.000000000 +0000
1612 +++ linux-4.1.41-vs2.3.8.5.3/fs/btrfs/disk-io.c 2016-07-05 04:41:47.000000000 +0000
1613 @@ -2687,6 +2687,9 @@ int open_ctree(struct super_block *sb,
1614                 goto fail_alloc;
1615         }
1616  
1617 +       if (btrfs_test_opt(tree_root, TAGGED))
1618 +               sb->s_flags |= MS_TAGGED;
1619 +
1620         features = btrfs_super_incompat_flags(disk_super) &
1621                 ~BTRFS_FEATURE_INCOMPAT_SUPP;
1622         if (features) {
1623 diff -NurpP --minimal linux-4.1.41/fs/btrfs/inode.c linux-4.1.41-vs2.3.8.5.3/fs/btrfs/inode.c
1624 --- linux-4.1.41/fs/btrfs/inode.c       2017-06-23 10:03:58.000000000 +0000
1625 +++ linux-4.1.41-vs2.3.8.5.3/fs/btrfs/inode.c   2017-05-30 07:39:23.000000000 +0000
1626 @@ -43,6 +43,7 @@
1627  #include <linux/blkdev.h>
1628  #include <linux/posix_acl_xattr.h>
1629  #include <linux/uio.h>
1630 +#include <linux/vs_tag.h>
1631  #include "ctree.h"
1632  #include "disk-io.h"
1633  #include "transaction.h"
1634 @@ -3579,6 +3580,9 @@ static void btrfs_read_locked_inode(stru
1635         unsigned long ptr;
1636         int maybe_acls;
1637         u32 rdev;
1638 +       kuid_t kuid;
1639 +       kgid_t kgid;
1640 +       ktag_t ktag;
1641         int ret;
1642         bool filled = false;
1643         int first_xattr_slot;
1644 @@ -3606,8 +3610,14 @@ static void btrfs_read_locked_inode(stru
1645                                     struct btrfs_inode_item);
1646         inode->i_mode = btrfs_inode_mode(leaf, inode_item);
1647         set_nlink(inode, btrfs_inode_nlink(leaf, inode_item));
1648 -       i_uid_write(inode, btrfs_inode_uid(leaf, inode_item));
1649 -       i_gid_write(inode, btrfs_inode_gid(leaf, inode_item));
1650 +
1651 +       kuid = make_kuid(&init_user_ns, btrfs_inode_uid(leaf, inode_item));
1652 +       kgid = make_kgid(&init_user_ns, btrfs_inode_gid(leaf, inode_item));
1653 +       ktag = make_ktag(&init_user_ns, btrfs_inode_tag(leaf, inode_item));
1654 +
1655 +       inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
1656 +       inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
1657 +       inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, ktag);
1658         btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item));
1659  
1660         inode->i_atime.tv_sec = btrfs_timespec_sec(leaf, &inode_item->atime);
1661 @@ -3734,11 +3744,18 @@ static void fill_inode_item(struct btrfs
1662                             struct inode *inode)
1663  {
1664         struct btrfs_map_token token;
1665 +       uid_t uid = from_kuid(&init_user_ns,
1666 +               TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
1667 +       gid_t gid = from_kgid(&init_user_ns,
1668 +               TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
1669  
1670         btrfs_init_map_token(&token);
1671  
1672 -       btrfs_set_token_inode_uid(leaf, item, i_uid_read(inode), &token);
1673 -       btrfs_set_token_inode_gid(leaf, item, i_gid_read(inode), &token);
1674 +       btrfs_set_token_inode_uid(leaf, item, uid, &token);
1675 +       btrfs_set_token_inode_gid(leaf, item, gid, &token);
1676 +#ifdef CONFIG_TAGGING_INTERN
1677 +       btrfs_set_token_inode_tag(leaf, item, i_tag_read(inode), &token);
1678 +#endif
1679         btrfs_set_token_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size,
1680                                    &token);
1681         btrfs_set_token_inode_mode(leaf, item, inode->i_mode, &token);
1682 @@ -9875,6 +9892,7 @@ static const struct inode_operations btr
1683         .listxattr      = btrfs_listxattr,
1684         .removexattr    = btrfs_removexattr,
1685         .permission     = btrfs_permission,
1686 +       .sync_flags     = btrfs_sync_flags,
1687         .get_acl        = btrfs_get_acl,
1688         .set_acl        = btrfs_set_acl,
1689         .update_time    = btrfs_update_time,
1690 @@ -9883,6 +9901,7 @@ static const struct inode_operations btr
1691  static const struct inode_operations btrfs_dir_ro_inode_operations = {
1692         .lookup         = btrfs_lookup,
1693         .permission     = btrfs_permission,
1694 +       .sync_flags     = btrfs_sync_flags,
1695         .get_acl        = btrfs_get_acl,
1696         .set_acl        = btrfs_set_acl,
1697         .update_time    = btrfs_update_time,
1698 @@ -9953,6 +9972,7 @@ static const struct inode_operations btr
1699         .removexattr    = btrfs_removexattr,
1700         .permission     = btrfs_permission,
1701         .fiemap         = btrfs_fiemap,
1702 +       .sync_flags     = btrfs_sync_flags,
1703         .get_acl        = btrfs_get_acl,
1704         .set_acl        = btrfs_set_acl,
1705         .update_time    = btrfs_update_time,
1706 diff -NurpP --minimal linux-4.1.41/fs/btrfs/ioctl.c linux-4.1.41-vs2.3.8.5.3/fs/btrfs/ioctl.c
1707 --- linux-4.1.41/fs/btrfs/ioctl.c       2017-06-23 10:03:58.000000000 +0000
1708 +++ linux-4.1.41-vs2.3.8.5.3/fs/btrfs/ioctl.c   2017-05-30 07:39:23.000000000 +0000
1709 @@ -107,10 +107,13 @@ static unsigned int btrfs_flags_to_ioctl
1710  {
1711         unsigned int iflags = 0;
1712  
1713 -       if (flags & BTRFS_INODE_SYNC)
1714 -               iflags |= FS_SYNC_FL;
1715         if (flags & BTRFS_INODE_IMMUTABLE)
1716                 iflags |= FS_IMMUTABLE_FL;
1717 +       if (flags & BTRFS_INODE_IXUNLINK)
1718 +               iflags |= FS_IXUNLINK_FL;
1719 +
1720 +       if (flags & BTRFS_INODE_SYNC)
1721 +               iflags |= FS_SYNC_FL;
1722         if (flags & BTRFS_INODE_APPEND)
1723                 iflags |= FS_APPEND_FL;
1724         if (flags & BTRFS_INODE_NODUMP)
1725 @@ -127,34 +130,84 @@ static unsigned int btrfs_flags_to_ioctl
1726         else if (flags & BTRFS_INODE_NOCOMPRESS)
1727                 iflags |= FS_NOCOMP_FL;
1728  
1729 +       if (flags & BTRFS_INODE_BARRIER)
1730 +               iflags |= FS_BARRIER_FL;
1731 +       if (flags & BTRFS_INODE_COW)
1732 +               iflags |= FS_COW_FL;
1733         return iflags;
1734  }
1735  
1736  /*
1737 - * Update inode->i_flags based on the btrfs internal flags.
1738 + * Update inode->i_(v)flags based on the btrfs internal flags.
1739   */
1740  void btrfs_update_iflags(struct inode *inode)
1741  {
1742         struct btrfs_inode *ip = BTRFS_I(inode);
1743         unsigned int new_fl = 0;
1744  
1745 -       if (ip->flags & BTRFS_INODE_SYNC)
1746 -               new_fl |= S_SYNC;
1747         if (ip->flags & BTRFS_INODE_IMMUTABLE)
1748                 new_fl |= S_IMMUTABLE;
1749 +       if (ip->flags & BTRFS_INODE_IXUNLINK)
1750 +               new_fl |= S_IXUNLINK;
1751 +
1752 +       if (ip->flags & BTRFS_INODE_SYNC)
1753 +               new_fl |= S_SYNC;
1754         if (ip->flags & BTRFS_INODE_APPEND)
1755                 new_fl |= S_APPEND;
1756         if (ip->flags & BTRFS_INODE_NOATIME)
1757                 new_fl |= S_NOATIME;
1758         if (ip->flags & BTRFS_INODE_DIRSYNC)
1759                 new_fl |= S_DIRSYNC;
1760 -
1761         set_mask_bits(&inode->i_flags,
1762 -                     S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC,
1763 +                     S_SYNC | S_APPEND | S_IMMUTABLE | S_IXUNLINK | S_NOATIME | S_DIRSYNC,
1764                       new_fl);
1765 +
1766 +       new_fl = 0;
1767 +       if (ip->flags & BTRFS_INODE_BARRIER)
1768 +               new_fl |= V_BARRIER;
1769 +       if (ip->flags & BTRFS_INODE_COW)
1770 +               new_fl |= V_COW;
1771 +
1772 +       set_mask_bits(&inode->i_vflags,
1773 +               V_BARRIER | V_COW, new_fl);
1774  }
1775  
1776  /*
1777 + * Update btrfs internal flags from inode->i_(v)flags.
1778 + */
1779 +void btrfs_update_flags(struct inode *inode)
1780 +{
1781 +       struct btrfs_inode *ip = BTRFS_I(inode);
1782 +
1783 +       unsigned int flags = inode->i_flags;
1784 +       unsigned int vflags = inode->i_vflags;
1785 +
1786 +       ip->flags &= ~(BTRFS_INODE_SYNC | BTRFS_INODE_APPEND |
1787 +                       BTRFS_INODE_IMMUTABLE | BTRFS_INODE_IXUNLINK |
1788 +                       BTRFS_INODE_NOATIME | BTRFS_INODE_DIRSYNC |
1789 +                       BTRFS_INODE_BARRIER | BTRFS_INODE_COW);
1790 +
1791 +       if (flags & S_IMMUTABLE)
1792 +               ip->flags |= BTRFS_INODE_IMMUTABLE;
1793 +       if (flags & S_IXUNLINK)
1794 +               ip->flags |= BTRFS_INODE_IXUNLINK;
1795 +
1796 +       if (flags & S_SYNC)
1797 +               ip->flags |= BTRFS_INODE_SYNC;
1798 +       if (flags & S_APPEND)
1799 +               ip->flags |= BTRFS_INODE_APPEND;
1800 +       if (flags & S_NOATIME)
1801 +               ip->flags |= BTRFS_INODE_NOATIME;
1802 +       if (flags & S_DIRSYNC)
1803 +               ip->flags |= BTRFS_INODE_DIRSYNC;
1804 +
1805 +       if (vflags & V_BARRIER)
1806 +               ip->flags |= BTRFS_INODE_BARRIER;
1807 +       if (vflags & V_COW)
1808 +               ip->flags |= BTRFS_INODE_COW;
1809 + }
1810 +
1811 +/*
1812   * Inherit flags from the parent inode.
1813   *
1814   * Currently only the compression flags and the cow flags are inherited.
1815 @@ -167,6 +220,7 @@ void btrfs_inherit_iflags(struct inode *
1816                 return;
1817  
1818         flags = BTRFS_I(dir)->flags;
1819 +       flags &= ~BTRFS_INODE_BARRIER;
1820  
1821         if (flags & BTRFS_INODE_NOCOMPRESS) {
1822                 BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS;
1823 @@ -185,6 +239,30 @@ void btrfs_inherit_iflags(struct inode *
1824         btrfs_update_iflags(inode);
1825  }
1826  
1827 +int btrfs_sync_flags(struct inode *inode, int flags, int vflags)
1828 +{
1829 +       struct btrfs_inode *ip = BTRFS_I(inode);
1830 +       struct btrfs_root *root = ip->root;
1831 +       struct btrfs_trans_handle *trans;
1832 +       int ret;
1833 +
1834 +       trans = btrfs_join_transaction(root);
1835 +       BUG_ON(!trans);
1836 +
1837 +       inode->i_flags = flags;
1838 +       inode->i_vflags = vflags;
1839 +       btrfs_update_flags(inode);
1840 +
1841 +       ret = btrfs_update_inode(trans, root, inode);
1842 +       BUG_ON(ret);
1843 +
1844 +       btrfs_update_iflags(inode);
1845 +       inode->i_ctime = CURRENT_TIME;
1846 +       btrfs_end_transaction(trans, root);
1847 +
1848 +       return 0;
1849 +}
1850 +
1851  static int btrfs_ioctl_getflags(struct file *file, void __user *arg)
1852  {
1853         struct btrfs_inode *ip = BTRFS_I(file_inode(file));
1854 @@ -247,21 +325,27 @@ static int btrfs_ioctl_setflags(struct f
1855  
1856         flags = btrfs_mask_flags(inode->i_mode, flags);
1857         oldflags = btrfs_flags_to_ioctl(ip->flags);
1858 -       if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) {
1859 +       if ((flags ^ oldflags) & (FS_APPEND_FL |
1860 +               FS_IMMUTABLE_FL | FS_IXUNLINK_FL)) {
1861                 if (!capable(CAP_LINUX_IMMUTABLE)) {
1862                         ret = -EPERM;
1863                         goto out_unlock;
1864                 }
1865         }
1866  
1867 -       if (flags & FS_SYNC_FL)
1868 -               ip->flags |= BTRFS_INODE_SYNC;
1869 -       else
1870 -               ip->flags &= ~BTRFS_INODE_SYNC;
1871         if (flags & FS_IMMUTABLE_FL)
1872                 ip->flags |= BTRFS_INODE_IMMUTABLE;
1873         else
1874                 ip->flags &= ~BTRFS_INODE_IMMUTABLE;
1875 +       if (flags & FS_IXUNLINK_FL)
1876 +               ip->flags |= BTRFS_INODE_IXUNLINK;
1877 +       else
1878 +               ip->flags &= ~BTRFS_INODE_IXUNLINK;
1879 +
1880 +       if (flags & FS_SYNC_FL)
1881 +               ip->flags |= BTRFS_INODE_SYNC;
1882 +       else
1883 +               ip->flags &= ~BTRFS_INODE_SYNC;
1884         if (flags & FS_APPEND_FL)
1885                 ip->flags |= BTRFS_INODE_APPEND;
1886         else
1887 diff -NurpP --minimal linux-4.1.41/fs/btrfs/super.c linux-4.1.41-vs2.3.8.5.3/fs/btrfs/super.c
1888 --- linux-4.1.41/fs/btrfs/super.c       2017-06-23 10:03:58.000000000 +0000
1889 +++ linux-4.1.41-vs2.3.8.5.3/fs/btrfs/super.c   2016-10-25 21:31:19.000000000 +0000
1890 @@ -325,7 +325,7 @@ enum {
1891         Opt_commit_interval, Opt_barrier, Opt_nodefrag, Opt_nodiscard,
1892         Opt_noenospc_debug, Opt_noflushoncommit, Opt_acl, Opt_datacow,
1893         Opt_datasum, Opt_treelog, Opt_noinode_cache,
1894 -       Opt_err,
1895 +       Opt_tag, Opt_notag, Opt_tagid, Opt_err,
1896  };
1897  
1898  static match_table_t tokens = {
1899 @@ -377,6 +377,9 @@ static match_table_t tokens = {
1900         {Opt_rescan_uuid_tree, "rescan_uuid_tree"},
1901         {Opt_fatal_errors, "fatal_errors=%s"},
1902         {Opt_commit_interval, "commit=%d"},
1903 +       {Opt_tag, "tag"},
1904 +       {Opt_notag, "notag"},
1905 +       {Opt_tagid, "tagid=%u"},
1906         {Opt_err, NULL},
1907  };
1908  
1909 @@ -743,6 +746,22 @@ int btrfs_parse_options(struct btrfs_roo
1910                                 info->commit_interval = BTRFS_DEFAULT_COMMIT_INTERVAL;
1911                         }
1912                         break;
1913 +#ifndef CONFIG_TAGGING_NONE
1914 +               case Opt_tag:
1915 +                       printk(KERN_INFO "btrfs: use tagging\n");
1916 +                       btrfs_set_opt(info->mount_opt, TAGGED);
1917 +                       break;
1918 +               case Opt_notag:
1919 +                       printk(KERN_INFO "btrfs: disabled tagging\n");
1920 +                       btrfs_clear_opt(info->mount_opt, TAGGED);
1921 +                       break;
1922 +#endif
1923 +#ifdef CONFIG_PROPAGATE
1924 +               case Opt_tagid:
1925 +                       /* use args[0] */
1926 +                       btrfs_set_opt(info->mount_opt, TAGGED);
1927 +                       break;
1928 +#endif
1929                 case Opt_err:
1930                         btrfs_info(root->fs_info, "unrecognized mount option '%s'", p);
1931                         ret = -EINVAL;
1932 @@ -1522,6 +1541,12 @@ static int btrfs_remount(struct super_bl
1933         btrfs_resize_thread_pool(fs_info,
1934                 fs_info->thread_pool_size, old_thread_pool_size);
1935  
1936 +       if (btrfs_test_opt(root, TAGGED) && !(sb->s_flags & MS_TAGGED)) {
1937 +               printk("btrfs: %s: tagging not permitted on remount.\n",
1938 +                       sb->s_id);
1939 +               return -EINVAL;
1940 +       }
1941 +
1942         if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
1943                 goto out;
1944  
1945 diff -NurpP --minimal linux-4.1.41/fs/char_dev.c linux-4.1.41-vs2.3.8.5.3/fs/char_dev.c
1946 --- linux-4.1.41/fs/char_dev.c  2015-04-12 22:12:50.000000000 +0000
1947 +++ linux-4.1.41-vs2.3.8.5.3/fs/char_dev.c      2016-07-05 04:41:47.000000000 +0000
1948 @@ -21,6 +21,8 @@
1949  #include <linux/mutex.h>
1950  #include <linux/backing-dev.h>
1951  #include <linux/tty.h>
1952 +#include <linux/vs_context.h>
1953 +#include <linux/vs_device.h>
1954  
1955  #include "internal.h"
1956  
1957 @@ -350,14 +352,21 @@ static int chrdev_open(struct inode *ino
1958         struct cdev *p;
1959         struct cdev *new = NULL;
1960         int ret = 0;
1961 +       dev_t mdev;
1962 +
1963 +       if (!vs_map_chrdev(inode->i_rdev, &mdev, DATTR_OPEN))
1964 +               return -EPERM;
1965 +       inode->i_mdev = mdev;
1966  
1967         spin_lock(&cdev_lock);
1968         p = inode->i_cdev;
1969         if (!p) {
1970                 struct kobject *kobj;
1971                 int idx;
1972 +
1973                 spin_unlock(&cdev_lock);
1974 -               kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
1975 +
1976 +               kobj = kobj_lookup(cdev_map, mdev, &idx);
1977                 if (!kobj)
1978                         return -ENXIO;
1979                 new = container_of(kobj, struct cdev, kobj);
1980 diff -NurpP --minimal linux-4.1.41/fs/dcache.c linux-4.1.41-vs2.3.8.5.3/fs/dcache.c
1981 --- linux-4.1.41/fs/dcache.c    2017-06-23 10:03:59.000000000 +0000
1982 +++ linux-4.1.41-vs2.3.8.5.3/fs/dcache.c        2017-05-30 07:39:23.000000000 +0000
1983 @@ -39,6 +39,7 @@
1984  #include <linux/ratelimit.h>
1985  #include <linux/list_lru.h>
1986  #include <linux/kasan.h>
1987 +#include <linux/vs_limit.h>
1988  
1989  #include "internal.h"
1990  #include "mount.h"
1991 @@ -650,6 +651,7 @@ static inline bool fast_dput(struct dent
1992                 spin_lock(&dentry->d_lock);
1993                 if (dentry->d_lockref.count > 1) {
1994                         dentry->d_lockref.count--;
1995 +                       vx_dentry_dec(dentry);
1996                         spin_unlock(&dentry->d_lock);
1997                         return 1;
1998                 }
1999 @@ -779,6 +781,7 @@ repeat:
2000         dentry_lru_add(dentry);
2001  
2002         dentry->d_lockref.count--;
2003 +       vx_dentry_dec(dentry);
2004         spin_unlock(&dentry->d_lock);
2005         return;
2006  
2007 @@ -796,6 +799,7 @@ EXPORT_SYMBOL(dput);
2008  static inline void __dget_dlock(struct dentry *dentry)
2009  {
2010         dentry->d_lockref.count++;
2011 +       vx_dentry_inc(dentry);
2012  }
2013  
2014  static inline void __dget(struct dentry *dentry)
2015 @@ -808,6 +812,8 @@ struct dentry *dget_parent(struct dentry
2016         int gotref;
2017         struct dentry *ret;
2018  
2019 +       vx_dentry_dec(dentry);
2020 +
2021         /*
2022          * Do optimistic parent lookup without any
2023          * locking.
2024 @@ -838,6 +844,7 @@ repeat:
2025         rcu_read_unlock();
2026         BUG_ON(!ret->d_lockref.count);
2027         ret->d_lockref.count++;
2028 +       vx_dentry_inc(ret);
2029         spin_unlock(&ret->d_lock);
2030         return ret;
2031  }
2032 @@ -992,6 +999,7 @@ static void shrink_dentry_list(struct li
2033                         parent = lock_parent(dentry);
2034                         if (dentry->d_lockref.count != 1) {
2035                                 dentry->d_lockref.count--;
2036 +                               vx_dentry_dec(dentry);
2037                                 spin_unlock(&dentry->d_lock);
2038                                 if (parent)
2039                                         spin_unlock(&parent->d_lock);
2040 @@ -1553,6 +1561,9 @@ struct dentry *__d_alloc(struct super_bl
2041         struct dentry *dentry;
2042         char *dname;
2043  
2044 +       if (!vx_dentry_avail(1))
2045 +               return NULL;
2046 +
2047         dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
2048         if (!dentry)
2049                 return NULL;
2050 @@ -1591,6 +1602,7 @@ struct dentry *__d_alloc(struct super_bl
2051  
2052         dentry->d_lockref.count = 1;
2053         dentry->d_flags = 0;
2054 +       vx_dentry_inc(dentry);
2055         spin_lock_init(&dentry->d_lock);
2056         seqcount_init(&dentry->d_seq);
2057         dentry->d_inode = NULL;
2058 @@ -2324,6 +2336,7 @@ struct dentry *__d_lookup(const struct d
2059                 }
2060  
2061                 dentry->d_lockref.count++;
2062 +               vx_dentry_inc(dentry);
2063                 found = dentry;
2064                 spin_unlock(&dentry->d_lock);
2065                 break;
2066 @@ -3341,6 +3354,7 @@ static enum d_walk_ret d_genocide_kill(v
2067                 if (!(dentry->d_flags & DCACHE_GENOCIDE)) {
2068                         dentry->d_flags |= DCACHE_GENOCIDE;
2069                         dentry->d_lockref.count--;
2070 +                       vx_dentry_dec(dentry);
2071                 }
2072         }
2073         return D_WALK_CONTINUE;
2074 diff -NurpP --minimal linux-4.1.41/fs/devpts/inode.c linux-4.1.41-vs2.3.8.5.3/fs/devpts/inode.c
2075 --- linux-4.1.41/fs/devpts/inode.c      2017-06-23 10:03:59.000000000 +0000
2076 +++ linux-4.1.41-vs2.3.8.5.3/fs/devpts/inode.c  2016-07-05 04:41:47.000000000 +0000
2077 @@ -27,6 +27,7 @@
2078  #include <linux/parser.h>
2079  #include <linux/fsnotify.h>
2080  #include <linux/seq_file.h>
2081 +#include <linux/vs_base.h>
2082  
2083  #define DEVPTS_DEFAULT_MODE 0600
2084  /*
2085 @@ -38,6 +39,21 @@
2086  #define DEVPTS_DEFAULT_PTMX_MODE 0000
2087  #define PTMX_MINOR     2
2088  
2089 +static int devpts_permission(struct inode *inode, int mask)
2090 +{
2091 +       int ret = -EACCES;
2092 +
2093 +       /* devpts is xid tagged */
2094 +       if (vx_check((vxid_t)i_tag_read(inode), VS_WATCH_P | VS_IDENT))
2095 +               ret = generic_permission(inode, mask);
2096 +       return ret;
2097 +}
2098 +
2099 +static struct inode_operations devpts_file_inode_operations = {
2100 +       .permission     = devpts_permission,
2101 +};
2102 +
2103 +
2104  /*
2105   * sysctl support for setting limits on the number of Unix98 ptys allocated.
2106   * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly.
2107 @@ -350,6 +366,34 @@ static int devpts_show_options(struct se
2108         return 0;
2109  }
2110  
2111 +static int devpts_filter(struct dentry *de)
2112 +{
2113 +       vxid_t xid = 0;
2114 +
2115 +       /* devpts is xid tagged */
2116 +       if (de && de->d_inode)
2117 +               xid = (vxid_t)i_tag_read(de->d_inode);
2118 +#ifdef CONFIG_VSERVER_WARN_DEVPTS
2119 +       else
2120 +               vxwprintk_task(1, "devpts " VS_Q("%.*s") " without inode.",
2121 +                       de->d_name.len, de->d_name.name);
2122 +#endif
2123 +       return vx_check(xid, VS_WATCH_P | VS_IDENT);
2124 +}
2125 +
2126 +static int devpts_readdir(struct file * filp, struct dir_context *ctx)
2127 +{
2128 +       return dcache_readdir_filter(filp, ctx, devpts_filter);
2129 +}
2130 +
2131 +static struct file_operations devpts_dir_operations = {
2132 +       .open           = dcache_dir_open,
2133 +       .release        = dcache_dir_close,
2134 +       .llseek         = dcache_dir_lseek,
2135 +       .read           = generic_read_dir,
2136 +       .iterate        = devpts_readdir,
2137 +};
2138 +
2139  static const struct super_operations devpts_sops = {
2140         .statfs         = simple_statfs,
2141         .remount_fs     = devpts_remount,
2142 @@ -393,8 +437,10 @@ devpts_fill_super(struct super_block *s,
2143         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
2144         inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
2145         inode->i_op = &simple_dir_inode_operations;
2146 -       inode->i_fop = &simple_dir_operations;
2147 +       inode->i_fop = &devpts_dir_operations;
2148         set_nlink(inode, 2);
2149 +       /* devpts is xid tagged */
2150 +       i_tag_write(inode, (vtag_t)vx_current_xid());
2151  
2152         s->s_root = d_make_root(inode);
2153         if (s->s_root)
2154 @@ -618,6 +664,9 @@ struct inode *devpts_pty_new(struct inod
2155         inode->i_gid = opts->setgid ? opts->gid : current_fsgid();
2156         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
2157         init_special_inode(inode, S_IFCHR|opts->mode, device);
2158 +       /* devpts is xid tagged */
2159 +       i_tag_write(inode, (vtag_t)vx_current_xid());
2160 +       inode->i_op = &devpts_file_inode_operations;
2161         inode->i_private = priv;
2162  
2163         sprintf(s, "%d", index);
2164 diff -NurpP --minimal linux-4.1.41/fs/ext2/balloc.c linux-4.1.41-vs2.3.8.5.3/fs/ext2/balloc.c
2165 --- linux-4.1.41/fs/ext2/balloc.c       2015-04-12 22:12:50.000000000 +0000
2166 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext2/balloc.c   2016-07-05 04:41:47.000000000 +0000
2167 @@ -693,7 +693,6 @@ ext2_try_to_allocate(struct super_block
2168                         start = 0;
2169                 end = EXT2_BLOCKS_PER_GROUP(sb);
2170         }
2171 -
2172         BUG_ON(start > EXT2_BLOCKS_PER_GROUP(sb));
2173  
2174  repeat:
2175 diff -NurpP --minimal linux-4.1.41/fs/ext2/ext2.h linux-4.1.41-vs2.3.8.5.3/fs/ext2/ext2.h
2176 --- linux-4.1.41/fs/ext2/ext2.h 2015-07-06 20:41:42.000000000 +0000
2177 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext2/ext2.h     2016-07-05 04:41:47.000000000 +0000
2178 @@ -244,8 +244,12 @@ struct ext2_group_desc
2179  #define EXT2_NOTAIL_FL                 FS_NOTAIL_FL    /* file tail should not be merged */
2180  #define EXT2_DIRSYNC_FL                        FS_DIRSYNC_FL   /* dirsync behaviour (directories only) */
2181  #define EXT2_TOPDIR_FL                 FS_TOPDIR_FL    /* Top of directory hierarchies*/
2182 +#define EXT2_IXUNLINK_FL               FS_IXUNLINK_FL  /* Immutable invert on unlink */
2183  #define EXT2_RESERVED_FL               FS_RESERVED_FL  /* reserved for ext2 lib */
2184  
2185 +#define EXT2_BARRIER_FL                        FS_BARRIER_FL   /* Barrier for chroot() */
2186 +#define EXT2_COW_FL                    FS_COW_FL       /* Copy on Write marker */
2187 +
2188  #define EXT2_FL_USER_VISIBLE           FS_FL_USER_VISIBLE      /* User visible flags */
2189  #define EXT2_FL_USER_MODIFIABLE                FS_FL_USER_MODIFIABLE   /* User modifiable flags */
2190  
2191 @@ -329,7 +333,8 @@ struct ext2_inode {
2192                         __u16   i_pad1;
2193                         __le16  l_i_uid_high;   /* these 2 fields    */
2194                         __le16  l_i_gid_high;   /* were reserved2[0] */
2195 -                       __u32   l_i_reserved2;
2196 +                       __le16  l_i_tag;        /* Context Tag */
2197 +                       __u16   l_i_reserved2;
2198                 } linux2;
2199                 struct {
2200                         __u8    h_i_frag;       /* Fragment number */
2201 @@ -357,6 +362,7 @@ struct ext2_inode {
2202  #define i_gid_low      i_gid
2203  #define i_uid_high     osd2.linux2.l_i_uid_high
2204  #define i_gid_high     osd2.linux2.l_i_gid_high
2205 +#define i_raw_tag      osd2.linux2.l_i_tag
2206  #define i_reserved2    osd2.linux2.l_i_reserved2
2207  
2208  /*
2209 @@ -389,6 +395,7 @@ struct ext2_inode {
2210  #else
2211  #define EXT2_MOUNT_DAX                 0
2212  #endif
2213 +#define EXT2_MOUNT_TAGGED              0x200000  /* Enable Context Tags */
2214  
2215  
2216  #define clear_opt(o, opt)              o &= ~EXT2_MOUNT_##opt
2217 @@ -765,6 +772,7 @@ extern void ext2_set_inode_flags(struct
2218  extern void ext2_get_inode_flags(struct ext2_inode_info *);
2219  extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
2220                        u64 start, u64 len);
2221 +extern int ext2_sync_flags(struct inode *, int, int);
2222  
2223  /* ioctl.c */
2224  extern long ext2_ioctl(struct file *, unsigned int, unsigned long);
2225 diff -NurpP --minimal linux-4.1.41/fs/ext2/file.c linux-4.1.41-vs2.3.8.5.3/fs/ext2/file.c
2226 --- linux-4.1.41/fs/ext2/file.c 2017-06-23 10:03:59.000000000 +0000
2227 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext2/file.c     2016-07-05 04:41:47.000000000 +0000
2228 @@ -118,4 +118,5 @@ const struct inode_operations ext2_file_
2229         .get_acl        = ext2_get_acl,
2230         .set_acl        = ext2_set_acl,
2231         .fiemap         = ext2_fiemap,
2232 +       .sync_flags     = ext2_sync_flags,
2233  };
2234 diff -NurpP --minimal linux-4.1.41/fs/ext2/ialloc.c linux-4.1.41-vs2.3.8.5.3/fs/ext2/ialloc.c
2235 --- linux-4.1.41/fs/ext2/ialloc.c       2015-07-06 20:41:42.000000000 +0000
2236 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext2/ialloc.c   2016-07-05 04:41:47.000000000 +0000
2237 @@ -17,6 +17,7 @@
2238  #include <linux/backing-dev.h>
2239  #include <linux/buffer_head.h>
2240  #include <linux/random.h>
2241 +#include <linux/vs_tag.h>
2242  #include "ext2.h"
2243  #include "xattr.h"
2244  #include "acl.h"
2245 @@ -546,6 +547,7 @@ got:
2246                 inode->i_mode = mode;
2247                 inode->i_uid = current_fsuid();
2248                 inode->i_gid = dir->i_gid;
2249 +               i_tag_write(inode, dx_current_fstag(sb));
2250         } else
2251                 inode_init_owner(inode, dir, mode);
2252  
2253 diff -NurpP --minimal linux-4.1.41/fs/ext2/inode.c linux-4.1.41-vs2.3.8.5.3/fs/ext2/inode.c
2254 --- linux-4.1.41/fs/ext2/inode.c        2017-06-23 10:03:59.000000000 +0000
2255 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext2/inode.c    2017-05-30 07:39:23.000000000 +0000
2256 @@ -32,6 +32,7 @@
2257  #include <linux/fiemap.h>
2258  #include <linux/namei.h>
2259  #include <linux/uio.h>
2260 +#include <linux/vs_tag.h>
2261  #include "ext2.h"
2262  #include "acl.h"
2263  #include "xattr.h"
2264 @@ -1182,7 +1183,7 @@ static void ext2_truncate_blocks(struct
2265                 return;
2266         if (ext2_inode_is_fast_symlink(inode))
2267                 return;
2268 -       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
2269 +       if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
2270                 return;
2271         __ext2_truncate_blocks(inode, offset);
2272  }
2273 @@ -1273,39 +1274,62 @@ void ext2_set_inode_flags(struct inode *
2274  {
2275         unsigned int flags = EXT2_I(inode)->i_flags;
2276  
2277 -       inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME |
2278 -                               S_DIRSYNC | S_DAX);
2279 +       inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK | S_DAX |
2280 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2281 +
2282 +       if (flags & EXT2_IMMUTABLE_FL)
2283 +               inode->i_flags |= S_IMMUTABLE;
2284 +       if (flags & EXT2_IXUNLINK_FL)
2285 +               inode->i_flags |= S_IXUNLINK;
2286 +
2287         if (flags & EXT2_SYNC_FL)
2288                 inode->i_flags |= S_SYNC;
2289         if (flags & EXT2_APPEND_FL)
2290                 inode->i_flags |= S_APPEND;
2291 -       if (flags & EXT2_IMMUTABLE_FL)
2292 -               inode->i_flags |= S_IMMUTABLE;
2293         if (flags & EXT2_NOATIME_FL)
2294                 inode->i_flags |= S_NOATIME;
2295         if (flags & EXT2_DIRSYNC_FL)
2296                 inode->i_flags |= S_DIRSYNC;
2297         if (test_opt(inode->i_sb, DAX))
2298                 inode->i_flags |= S_DAX;
2299 +
2300 +       inode->i_vflags &= ~(V_BARRIER | V_COW);
2301 +
2302 +       if (flags & EXT2_BARRIER_FL)
2303 +               inode->i_vflags |= V_BARRIER;
2304 +       if (flags & EXT2_COW_FL)
2305 +               inode->i_vflags |= V_COW;
2306  }
2307  
2308  /* Propagate flags from i_flags to EXT2_I(inode)->i_flags */
2309  void ext2_get_inode_flags(struct ext2_inode_info *ei)
2310  {
2311         unsigned int flags = ei->vfs_inode.i_flags;
2312 +       unsigned int vflags = ei->vfs_inode.i_vflags;
2313 +
2314 +       ei->i_flags &= ~(EXT2_SYNC_FL | EXT2_APPEND_FL |
2315 +                       EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL |
2316 +                       EXT2_NOATIME_FL | EXT2_DIRSYNC_FL |
2317 +                       EXT2_BARRIER_FL | EXT2_COW_FL);
2318 +
2319 +       if (flags & S_IMMUTABLE)
2320 +               ei->i_flags |= EXT2_IMMUTABLE_FL;
2321 +       if (flags & S_IXUNLINK)
2322 +               ei->i_flags |= EXT2_IXUNLINK_FL;
2323  
2324 -       ei->i_flags &= ~(EXT2_SYNC_FL|EXT2_APPEND_FL|
2325 -                       EXT2_IMMUTABLE_FL|EXT2_NOATIME_FL|EXT2_DIRSYNC_FL);
2326         if (flags & S_SYNC)
2327                 ei->i_flags |= EXT2_SYNC_FL;
2328         if (flags & S_APPEND)
2329                 ei->i_flags |= EXT2_APPEND_FL;
2330 -       if (flags & S_IMMUTABLE)
2331 -               ei->i_flags |= EXT2_IMMUTABLE_FL;
2332         if (flags & S_NOATIME)
2333                 ei->i_flags |= EXT2_NOATIME_FL;
2334         if (flags & S_DIRSYNC)
2335                 ei->i_flags |= EXT2_DIRSYNC_FL;
2336 +
2337 +       if (vflags & V_BARRIER)
2338 +               ei->i_flags |= EXT2_BARRIER_FL;
2339 +       if (vflags & V_COW)
2340 +               ei->i_flags |= EXT2_COW_FL;
2341  }
2342  
2343  struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
2344 @@ -1341,8 +1365,10 @@ struct inode *ext2_iget (struct super_bl
2345                 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
2346                 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
2347         }
2348 -       i_uid_write(inode, i_uid);
2349 -       i_gid_write(inode, i_gid);
2350 +       i_uid_write(inode, INOTAG_UID(DX_TAG(inode), i_uid, i_gid));
2351 +       i_gid_write(inode, INOTAG_GID(DX_TAG(inode), i_uid, i_gid));
2352 +       i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
2353 +               le16_to_cpu(raw_inode->i_raw_tag)));
2354         set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
2355         inode->i_size = le32_to_cpu(raw_inode->i_size);
2356         inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
2357 @@ -1437,8 +1463,10 @@ static int __ext2_write_inode(struct ino
2358         struct ext2_inode_info *ei = EXT2_I(inode);
2359         struct super_block *sb = inode->i_sb;
2360         ino_t ino = inode->i_ino;
2361 -       uid_t uid = i_uid_read(inode);
2362 -       gid_t gid = i_gid_read(inode);
2363 +       uid_t uid = from_kuid(&init_user_ns,
2364 +               TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
2365 +       gid_t gid = from_kgid(&init_user_ns,
2366 +               TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
2367         struct buffer_head * bh;
2368         struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);
2369         int n;
2370 @@ -1474,6 +1502,9 @@ static int __ext2_write_inode(struct ino
2371                 raw_inode->i_uid_high = 0;
2372                 raw_inode->i_gid_high = 0;
2373         }
2374 +#ifdef CONFIG_TAGGING_INTERN
2375 +       raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
2376 +#endif
2377         raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
2378         raw_inode->i_size = cpu_to_le32(inode->i_size);
2379         raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
2380 @@ -1554,7 +1585,8 @@ int ext2_setattr(struct dentry *dentry,
2381         if (is_quota_modification(inode, iattr))
2382                 dquot_initialize(inode);
2383         if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
2384 -           (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
2385 +           (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)) ||
2386 +           (iattr->ia_valid & ATTR_TAG && !tag_eq(iattr->ia_tag, inode->i_tag))) {
2387                 error = dquot_transfer(inode, iattr);
2388                 if (error)
2389                         return error;
2390 diff -NurpP --minimal linux-4.1.41/fs/ext2/ioctl.c linux-4.1.41-vs2.3.8.5.3/fs/ext2/ioctl.c
2391 --- linux-4.1.41/fs/ext2/ioctl.c        2015-04-12 22:12:50.000000000 +0000
2392 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext2/ioctl.c    2016-07-05 04:41:47.000000000 +0000
2393 @@ -17,6 +17,16 @@
2394  #include <asm/uaccess.h>
2395  
2396  
2397 +int ext2_sync_flags(struct inode *inode, int flags, int vflags)
2398 +{
2399 +       inode->i_flags = flags;
2400 +       inode->i_vflags = vflags;
2401 +       ext2_get_inode_flags(EXT2_I(inode));
2402 +       inode->i_ctime = CURRENT_TIME_SEC;
2403 +       mark_inode_dirty(inode);
2404 +       return 0;
2405 +}
2406 +
2407  long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2408  {
2409         struct inode *inode = file_inode(filp);
2410 @@ -51,6 +61,11 @@ long ext2_ioctl(struct file *filp, unsig
2411  
2412                 flags = ext2_mask_flags(inode->i_mode, flags);
2413  
2414 +               if (IS_BARRIER(inode)) {
2415 +                       vxwprintk_task(1, "messing with the barrier.");
2416 +                       return -EACCES;
2417 +               }
2418 +
2419                 mutex_lock(&inode->i_mutex);
2420                 /* Is it quota file? Do not allow user to mess with it */
2421                 if (IS_NOQUOTA(inode)) {
2422 @@ -66,7 +81,9 @@ long ext2_ioctl(struct file *filp, unsig
2423                  *
2424                  * This test looks nicer. Thanks to Pauline Middelink
2425                  */
2426 -               if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
2427 +               if ((oldflags & EXT2_IMMUTABLE_FL) ||
2428 +                       ((flags ^ oldflags) & (EXT2_APPEND_FL |
2429 +                       EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL))) {
2430                         if (!capable(CAP_LINUX_IMMUTABLE)) {
2431                                 mutex_unlock(&inode->i_mutex);
2432                                 ret = -EPERM;
2433 @@ -74,7 +91,7 @@ long ext2_ioctl(struct file *filp, unsig
2434                         }
2435                 }
2436  
2437 -               flags = flags & EXT2_FL_USER_MODIFIABLE;
2438 +               flags &= EXT2_FL_USER_MODIFIABLE;
2439                 flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE;
2440                 ei->i_flags = flags;
2441  
2442 diff -NurpP --minimal linux-4.1.41/fs/ext2/namei.c linux-4.1.41-vs2.3.8.5.3/fs/ext2/namei.c
2443 --- linux-4.1.41/fs/ext2/namei.c        2015-07-06 20:41:42.000000000 +0000
2444 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext2/namei.c    2016-07-05 04:41:47.000000000 +0000
2445 @@ -32,6 +32,7 @@
2446  
2447  #include <linux/pagemap.h>
2448  #include <linux/quotaops.h>
2449 +#include <linux/vs_tag.h>
2450  #include "ext2.h"
2451  #include "xattr.h"
2452  #include "acl.h"
2453 @@ -72,6 +73,7 @@ static struct dentry *ext2_lookup(struct
2454                                         (unsigned long) ino);
2455                         return ERR_PTR(-EIO);
2456                 }
2457 +               dx_propagate_tag(nd, inode);
2458         }
2459         return d_splice_alias(inode, dentry);
2460  }
2461 @@ -426,6 +428,7 @@ const struct inode_operations ext2_speci
2462         .removexattr    = generic_removexattr,
2463  #endif
2464         .setattr        = ext2_setattr,
2465 +       .sync_flags     = ext2_sync_flags,
2466         .get_acl        = ext2_get_acl,
2467         .set_acl        = ext2_set_acl,
2468  };
2469 diff -NurpP --minimal linux-4.1.41/fs/ext2/super.c linux-4.1.41-vs2.3.8.5.3/fs/ext2/super.c
2470 --- linux-4.1.41/fs/ext2/super.c        2015-04-12 22:12:50.000000000 +0000
2471 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext2/super.c    2016-07-05 04:41:47.000000000 +0000
2472 @@ -405,7 +405,8 @@ enum {
2473         Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
2474         Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
2475         Opt_acl, Opt_noacl, Opt_xip, Opt_dax, Opt_ignore, Opt_err, Opt_quota,
2476 -       Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation
2477 +       Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation,
2478 +       Opt_tag, Opt_notag, Opt_tagid
2479  };
2480  
2481  static const match_table_t tokens = {
2482 @@ -433,6 +434,9 @@ static const match_table_t tokens = {
2483         {Opt_acl, "acl"},
2484         {Opt_noacl, "noacl"},
2485         {Opt_xip, "xip"},
2486 +       {Opt_tag, "tag"},
2487 +       {Opt_notag, "notag"},
2488 +       {Opt_tagid, "tagid=%u"},
2489         {Opt_dax, "dax"},
2490         {Opt_grpquota, "grpquota"},
2491         {Opt_ignore, "noquota"},
2492 @@ -517,6 +521,20 @@ static int parse_options(char *options,
2493                 case Opt_nouid32:
2494                         set_opt (sbi->s_mount_opt, NO_UID32);
2495                         break;
2496 +#ifndef CONFIG_TAGGING_NONE
2497 +               case Opt_tag:
2498 +                       set_opt (sbi->s_mount_opt, TAGGED);
2499 +                       break;
2500 +               case Opt_notag:
2501 +                       clear_opt (sbi->s_mount_opt, TAGGED);
2502 +                       break;
2503 +#endif
2504 +#ifdef CONFIG_PROPAGATE
2505 +               case Opt_tagid:
2506 +                       /* use args[0] */
2507 +                       set_opt (sbi->s_mount_opt, TAGGED);
2508 +                       break;
2509 +#endif
2510                 case Opt_nocheck:
2511                         clear_opt (sbi->s_mount_opt, CHECK);
2512                         break;
2513 @@ -879,6 +897,8 @@ static int ext2_fill_super(struct super_
2514         if (!parse_options((char *) data, sb))
2515                 goto failed_mount;
2516  
2517 +       if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAGGED)
2518 +               sb->s_flags |= MS_TAGGED;
2519         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2520                 ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
2521                  MS_POSIXACL : 0);
2522 @@ -1288,6 +1308,14 @@ static int ext2_remount (struct super_bl
2523                 err = -EINVAL;
2524                 goto restore_opts;
2525         }
2526 +
2527 +       if ((sbi->s_mount_opt & EXT2_MOUNT_TAGGED) &&
2528 +               !(sb->s_flags & MS_TAGGED)) {
2529 +               printk("EXT2-fs: %s: tagging not permitted on remount.\n",
2530 +                      sb->s_id);
2531 +               err = -EINVAL;
2532 +               goto restore_opts;
2533 +       }
2534  
2535         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2536                 ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
2537 diff -NurpP --minimal linux-4.1.41/fs/ext3/ext3.h linux-4.1.41-vs2.3.8.5.3/fs/ext3/ext3.h
2538 --- linux-4.1.41/fs/ext3/ext3.h 2015-04-12 22:12:50.000000000 +0000
2539 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext3/ext3.h     2016-07-05 04:41:47.000000000 +0000
2540 @@ -151,10 +151,14 @@ struct ext3_group_desc
2541  #define EXT3_NOTAIL_FL                 0x00008000 /* file tail should not be merged */
2542  #define EXT3_DIRSYNC_FL                        0x00010000 /* dirsync behaviour (directories only) */
2543  #define EXT3_TOPDIR_FL                 0x00020000 /* Top of directory hierarchies*/
2544 +#define EXT3_IXUNLINK_FL               0x08000000 /* Immutable invert on unlink */
2545  #define EXT3_RESERVED_FL               0x80000000 /* reserved for ext3 lib */
2546  
2547 -#define EXT3_FL_USER_VISIBLE           0x0003DFFF /* User visible flags */
2548 -#define EXT3_FL_USER_MODIFIABLE                0x000380FF /* User modifiable flags */
2549 +#define EXT3_BARRIER_FL                        0x04000000 /* Barrier for chroot() */
2550 +#define EXT3_COW_FL                    0x20000000 /* Copy on Write marker */
2551 +
2552 +#define EXT3_FL_USER_VISIBLE           0x0103DFFF /* User visible flags */
2553 +#define EXT3_FL_USER_MODIFIABLE                0x010380FF /* User modifiable flags */
2554  
2555  /* Flags that should be inherited by new inodes from their parent. */
2556  #define EXT3_FL_INHERITED (EXT3_SECRM_FL | EXT3_UNRM_FL | EXT3_COMPR_FL |\
2557 @@ -292,7 +296,8 @@ struct ext3_inode {
2558                         __u16   i_pad1;
2559                         __le16  l_i_uid_high;   /* these 2 fields    */
2560                         __le16  l_i_gid_high;   /* were reserved2[0] */
2561 -                       __u32   l_i_reserved2;
2562 +                       __le16  l_i_tag;        /* Context Tag */
2563 +                       __u16   l_i_reserved2;
2564                 } linux2;
2565                 struct {
2566                         __u8    h_i_frag;       /* Fragment number */
2567 @@ -322,6 +327,7 @@ struct ext3_inode {
2568  #define i_gid_low      i_gid
2569  #define i_uid_high     osd2.linux2.l_i_uid_high
2570  #define i_gid_high     osd2.linux2.l_i_gid_high
2571 +#define i_raw_tag      osd2.linux2.l_i_tag
2572  #define i_reserved2    osd2.linux2.l_i_reserved2
2573  
2574  /*
2575 @@ -366,6 +372,7 @@ struct ext3_inode {
2576  #define EXT3_MOUNT_GRPQUOTA            0x200000 /* "old" group quota */
2577  #define EXT3_MOUNT_DATA_ERR_ABORT      0x400000 /* Abort on file data write
2578                                                   * error in ordered mode */
2579 +#define EXT3_MOUNT_TAGGED              (1<<24) /* Enable Context Tags */
2580  
2581  /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
2582  #ifndef _LINUX_EXT2_FS_H
2583 @@ -1067,6 +1074,7 @@ extern void ext3_get_inode_flags(struct
2584  extern void ext3_set_aops(struct inode *inode);
2585  extern int ext3_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
2586                        u64 start, u64 len);
2587 +extern int ext3_sync_flags(struct inode *, int, int);
2588  
2589  /* ioctl.c */
2590  extern long ext3_ioctl(struct file *, unsigned int, unsigned long);
2591 diff -NurpP --minimal linux-4.1.41/fs/ext3/file.c linux-4.1.41-vs2.3.8.5.3/fs/ext3/file.c
2592 --- linux-4.1.41/fs/ext3/file.c 2015-07-06 20:41:42.000000000 +0000
2593 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext3/file.c     2016-07-05 04:41:47.000000000 +0000
2594 @@ -75,5 +75,6 @@ const struct inode_operations ext3_file_
2595         .get_acl        = ext3_get_acl,
2596         .set_acl        = ext3_set_acl,
2597         .fiemap         = ext3_fiemap,
2598 +       .sync_flags     = ext3_sync_flags,
2599  };
2600  
2601 diff -NurpP --minimal linux-4.1.41/fs/ext3/ialloc.c linux-4.1.41-vs2.3.8.5.3/fs/ext3/ialloc.c
2602 --- linux-4.1.41/fs/ext3/ialloc.c       2015-07-06 20:41:42.000000000 +0000
2603 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext3/ialloc.c   2016-07-05 04:41:47.000000000 +0000
2604 @@ -14,6 +14,7 @@
2605  
2606  #include <linux/quotaops.h>
2607  #include <linux/random.h>
2608 +#include <linux/vs_tag.h>
2609  
2610  #include "ext3.h"
2611  #include "xattr.h"
2612 @@ -469,6 +470,7 @@ got:
2613                 inode->i_mode = mode;
2614                 inode->i_uid = current_fsuid();
2615                 inode->i_gid = dir->i_gid;
2616 +               i_tag_write(inode, dx_current_fstag(sb));
2617         } else
2618                 inode_init_owner(inode, dir, mode);
2619  
2620 diff -NurpP --minimal linux-4.1.41/fs/ext3/inode.c linux-4.1.41-vs2.3.8.5.3/fs/ext3/inode.c
2621 --- linux-4.1.41/fs/ext3/inode.c        2017-06-23 10:03:59.000000000 +0000
2622 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext3/inode.c    2017-05-30 07:39:23.000000000 +0000
2623 @@ -28,6 +28,7 @@
2624  #include <linux/mpage.h>
2625  #include <linux/namei.h>
2626  #include <linux/uio.h>
2627 +#include <linux/vs_tag.h>
2628  #include "ext3.h"
2629  #include "xattr.h"
2630  #include "acl.h"
2631 @@ -2813,36 +2814,60 @@ void ext3_set_inode_flags(struct inode *
2632  {
2633         unsigned int flags = EXT3_I(inode)->i_flags;
2634  
2635 -       inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
2636 +       inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK |
2637 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2638 +
2639 +       if (flags & EXT3_IMMUTABLE_FL)
2640 +               inode->i_flags |= S_IMMUTABLE;
2641 +       if (flags & EXT3_IXUNLINK_FL)
2642 +               inode->i_flags |= S_IXUNLINK;
2643 +
2644         if (flags & EXT3_SYNC_FL)
2645                 inode->i_flags |= S_SYNC;
2646         if (flags & EXT3_APPEND_FL)
2647                 inode->i_flags |= S_APPEND;
2648 -       if (flags & EXT3_IMMUTABLE_FL)
2649 -               inode->i_flags |= S_IMMUTABLE;
2650         if (flags & EXT3_NOATIME_FL)
2651                 inode->i_flags |= S_NOATIME;
2652         if (flags & EXT3_DIRSYNC_FL)
2653                 inode->i_flags |= S_DIRSYNC;
2654 +
2655 +       inode->i_vflags &= ~(V_BARRIER | V_COW);
2656 +
2657 +       if (flags & EXT3_BARRIER_FL)
2658 +               inode->i_vflags |= V_BARRIER;
2659 +       if (flags & EXT3_COW_FL)
2660 +               inode->i_vflags |= V_COW;
2661  }
2662  
2663  /* Propagate flags from i_flags to EXT3_I(inode)->i_flags */
2664  void ext3_get_inode_flags(struct ext3_inode_info *ei)
2665  {
2666         unsigned int flags = ei->vfs_inode.i_flags;
2667 +       unsigned int vflags = ei->vfs_inode.i_vflags;
2668 +
2669 +       ei->i_flags &= ~(EXT3_SYNC_FL | EXT3_APPEND_FL |
2670 +                       EXT3_IMMUTABLE_FL | EXT3_IXUNLINK_FL |
2671 +                       EXT3_NOATIME_FL | EXT3_DIRSYNC_FL |
2672 +                       EXT3_BARRIER_FL | EXT3_COW_FL);
2673 +
2674 +       if (flags & S_IMMUTABLE)
2675 +               ei->i_flags |= EXT3_IMMUTABLE_FL;
2676 +       if (flags & S_IXUNLINK)
2677 +               ei->i_flags |= EXT3_IXUNLINK_FL;
2678  
2679 -       ei->i_flags &= ~(EXT3_SYNC_FL|EXT3_APPEND_FL|
2680 -                       EXT3_IMMUTABLE_FL|EXT3_NOATIME_FL|EXT3_DIRSYNC_FL);
2681         if (flags & S_SYNC)
2682                 ei->i_flags |= EXT3_SYNC_FL;
2683         if (flags & S_APPEND)
2684                 ei->i_flags |= EXT3_APPEND_FL;
2685 -       if (flags & S_IMMUTABLE)
2686 -               ei->i_flags |= EXT3_IMMUTABLE_FL;
2687         if (flags & S_NOATIME)
2688                 ei->i_flags |= EXT3_NOATIME_FL;
2689         if (flags & S_DIRSYNC)
2690                 ei->i_flags |= EXT3_DIRSYNC_FL;
2691 +
2692 +       if (vflags & V_BARRIER)
2693 +               ei->i_flags |= EXT3_BARRIER_FL;
2694 +       if (vflags & V_COW)
2695 +               ei->i_flags |= EXT3_COW_FL;
2696  }
2697  
2698  struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
2699 @@ -2880,8 +2905,10 @@ struct inode *ext3_iget(struct super_blo
2700                 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
2701                 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
2702         }
2703 -       i_uid_write(inode, i_uid);
2704 -       i_gid_write(inode, i_gid);
2705 +       i_uid_write(inode, INOTAG_UID(DX_TAG(inode), i_uid, i_gid));
2706 +       i_gid_write(inode, INOTAG_GID(DX_TAG(inode), i_uid, i_gid));
2707 +       i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
2708 +               le16_to_cpu(raw_inode->i_raw_tag)));
2709         set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
2710         inode->i_size = le32_to_cpu(raw_inode->i_size);
2711         inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
2712 @@ -3053,8 +3080,10 @@ again:
2713  
2714         ext3_get_inode_flags(ei);
2715         raw_inode->i_mode = cpu_to_le16(inode->i_mode);
2716 -       i_uid = i_uid_read(inode);
2717 -       i_gid = i_gid_read(inode);
2718 +       i_uid = from_kuid(&init_user_ns,
2719 +               TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
2720 +       i_gid = from_kgid(&init_user_ns,
2721 +               TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
2722         if(!(test_opt(inode->i_sb, NO_UID32))) {
2723                 raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid));
2724                 raw_inode->i_gid_low = cpu_to_le16(low_16_bits(i_gid));
2725 @@ -3079,6 +3108,9 @@ again:
2726                 raw_inode->i_uid_high = 0;
2727                 raw_inode->i_gid_high = 0;
2728         }
2729 +#ifdef CONFIG_TAGGING_INTERN
2730 +       raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
2731 +#endif
2732         raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
2733         disksize = cpu_to_le32(ei->i_disksize);
2734         if (disksize != raw_inode->i_size) {
2735 @@ -3251,7 +3283,8 @@ int ext3_setattr(struct dentry *dentry,
2736         if (is_quota_modification(inode, attr))
2737                 dquot_initialize(inode);
2738         if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
2739 -           (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
2740 +           (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid)) ||
2741 +           (ia_valid & ATTR_TAG && !tag_eq(attr->ia_tag, inode->i_tag))) {
2742                 handle_t *handle;
2743  
2744                 /* (user+group)*(old+new) structure, inode write (sb,
2745 @@ -3273,6 +3306,8 @@ int ext3_setattr(struct dentry *dentry,
2746                         inode->i_uid = attr->ia_uid;
2747                 if (attr->ia_valid & ATTR_GID)
2748                         inode->i_gid = attr->ia_gid;
2749 +               if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
2750 +                       inode->i_tag = attr->ia_tag;
2751                 error = ext3_mark_inode_dirty(handle, inode);
2752                 ext3_journal_stop(handle);
2753         }
2754 diff -NurpP --minimal linux-4.1.41/fs/ext3/ioctl.c linux-4.1.41-vs2.3.8.5.3/fs/ext3/ioctl.c
2755 --- linux-4.1.41/fs/ext3/ioctl.c        2015-04-12 22:12:50.000000000 +0000
2756 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext3/ioctl.c    2016-07-05 04:41:47.000000000 +0000
2757 @@ -12,6 +12,34 @@
2758  #include <asm/uaccess.h>
2759  #include "ext3.h"
2760  
2761 +
2762 +int ext3_sync_flags(struct inode *inode, int flags, int vflags)
2763 +{
2764 +       handle_t *handle = NULL;
2765 +       struct ext3_iloc iloc;
2766 +       int err;
2767 +
2768 +       handle = ext3_journal_start(inode, 1);
2769 +       if (IS_ERR(handle))
2770 +               return PTR_ERR(handle);
2771 +
2772 +       if (IS_SYNC(inode))
2773 +               handle->h_sync = 1;
2774 +       err = ext3_reserve_inode_write(handle, inode, &iloc);
2775 +       if (err)
2776 +               goto flags_err;
2777 +
2778 +       inode->i_flags = flags;
2779 +       inode->i_vflags = vflags;
2780 +       ext3_get_inode_flags(EXT3_I(inode));
2781 +       inode->i_ctime = CURRENT_TIME_SEC;
2782 +
2783 +       err = ext3_mark_iloc_dirty(handle, inode, &iloc);
2784 +flags_err:
2785 +       ext3_journal_stop(handle);
2786 +       return err;
2787 +}
2788 +
2789  long ext3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2790  {
2791         struct inode *inode = file_inode(filp);
2792 @@ -45,6 +73,11 @@ long ext3_ioctl(struct file *filp, unsig
2793  
2794                 flags = ext3_mask_flags(inode->i_mode, flags);
2795  
2796 +               if (IS_BARRIER(inode)) {
2797 +                       vxwprintk_task(1, "messing with the barrier.");
2798 +                       return -EACCES;
2799 +               }
2800 +
2801                 mutex_lock(&inode->i_mutex);
2802  
2803                 /* Is it quota file? Do not allow user to mess with it */
2804 @@ -63,7 +96,9 @@ long ext3_ioctl(struct file *filp, unsig
2805                  *
2806                  * This test looks nicer. Thanks to Pauline Middelink
2807                  */
2808 -               if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
2809 +               if ((oldflags & EXT3_IMMUTABLE_FL) ||
2810 +                       ((flags ^ oldflags) & (EXT3_APPEND_FL |
2811 +                       EXT3_IMMUTABLE_FL | EXT3_IXUNLINK_FL))) {
2812                         if (!capable(CAP_LINUX_IMMUTABLE))
2813                                 goto flags_out;
2814                 }
2815 @@ -88,7 +123,7 @@ long ext3_ioctl(struct file *filp, unsig
2816                 if (err)
2817                         goto flags_err;
2818  
2819 -               flags = flags & EXT3_FL_USER_MODIFIABLE;
2820 +               flags &= EXT3_FL_USER_MODIFIABLE;
2821                 flags |= oldflags & ~EXT3_FL_USER_MODIFIABLE;
2822                 ei->i_flags = flags;
2823  
2824 diff -NurpP --minimal linux-4.1.41/fs/ext3/namei.c linux-4.1.41-vs2.3.8.5.3/fs/ext3/namei.c
2825 --- linux-4.1.41/fs/ext3/namei.c        2015-07-06 20:41:42.000000000 +0000
2826 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext3/namei.c    2016-07-05 04:41:47.000000000 +0000
2827 @@ -25,6 +25,8 @@
2828   */
2829  
2830  #include <linux/quotaops.h>
2831 +#include <linux/vs_tag.h>
2832 +
2833  #include "ext3.h"
2834  #include "namei.h"
2835  #include "xattr.h"
2836 @@ -915,6 +917,7 @@ restart:
2837                                         submit_bh(READ | REQ_META | REQ_PRIO,
2838                                                   bh);
2839                                 }
2840 +               dx_propagate_tag(nd, inode);
2841                         }
2842                 }
2843                 if ((bh = bh_use[ra_ptr++]) == NULL)
2844 @@ -2568,6 +2571,7 @@ const struct inode_operations ext3_dir_i
2845         .listxattr      = ext3_listxattr,
2846         .removexattr    = generic_removexattr,
2847  #endif
2848 +       .sync_flags     = ext3_sync_flags,
2849         .get_acl        = ext3_get_acl,
2850         .set_acl        = ext3_set_acl,
2851  };
2852 diff -NurpP --minimal linux-4.1.41/fs/ext3/super.c linux-4.1.41-vs2.3.8.5.3/fs/ext3/super.c
2853 --- linux-4.1.41/fs/ext3/super.c        2015-07-06 20:41:42.000000000 +0000
2854 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext3/super.c    2016-07-05 04:41:47.000000000 +0000
2855 @@ -837,7 +837,8 @@ enum {
2856         Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
2857         Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
2858         Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
2859 -       Opt_resize, Opt_usrquota, Opt_grpquota
2860 +       Opt_resize, Opt_usrquota, Opt_grpquota,
2861 +       Opt_tag, Opt_notag, Opt_tagid
2862  };
2863  
2864  static const match_table_t tokens = {
2865 @@ -895,6 +896,9 @@ static const match_table_t tokens = {
2866         {Opt_barrier, "barrier"},
2867         {Opt_nobarrier, "nobarrier"},
2868         {Opt_resize, "resize"},
2869 +       {Opt_tag, "tag"},
2870 +       {Opt_notag, "notag"},
2871 +       {Opt_tagid, "tagid=%u"},
2872         {Opt_err, NULL},
2873  };
2874  
2875 @@ -1067,6 +1071,20 @@ static int parse_options (char *options,
2876                 case Opt_nouid32:
2877                         set_opt (sbi->s_mount_opt, NO_UID32);
2878                         break;
2879 +#ifndef CONFIG_TAGGING_NONE
2880 +               case Opt_tag:
2881 +                       set_opt (sbi->s_mount_opt, TAGGED);
2882 +                       break;
2883 +               case Opt_notag:
2884 +                       clear_opt (sbi->s_mount_opt, TAGGED);
2885 +                       break;
2886 +#endif
2887 +#ifdef CONFIG_PROPAGATE
2888 +               case Opt_tagid:
2889 +                       /* use args[0] */
2890 +                       set_opt (sbi->s_mount_opt, TAGGED);
2891 +                       break;
2892 +#endif
2893                 case Opt_nocheck:
2894                         clear_opt (sbi->s_mount_opt, CHECK);
2895                         break;
2896 @@ -1792,6 +1810,9 @@ static int ext3_fill_super (struct super
2897                             NULL, 0))
2898                 goto failed_mount;
2899  
2900 +       if (EXT3_SB(sb)->s_mount_opt & EXT3_MOUNT_TAGGED)
2901 +               sb->s_flags |= MS_TAGGED;
2902 +
2903         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2904                 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
2905  
2906 @@ -2690,6 +2711,14 @@ static int ext3_remount (struct super_bl
2907         if (test_opt(sb, ABORT))
2908                 ext3_abort(sb, __func__, "Abort forced by user");
2909  
2910 +       if ((sbi->s_mount_opt & EXT3_MOUNT_TAGGED) &&
2911 +               !(sb->s_flags & MS_TAGGED)) {
2912 +               printk("EXT3-fs: %s: tagging not permitted on remount.\n",
2913 +                       sb->s_id);
2914 +               err = -EINVAL;
2915 +               goto restore_opts;
2916 +       }
2917 +
2918         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2919                 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
2920  
2921 diff -NurpP --minimal linux-4.1.41/fs/ext4/ext4.h linux-4.1.41-vs2.3.8.5.3/fs/ext4/ext4.h
2922 --- linux-4.1.41/fs/ext4/ext4.h 2017-06-23 10:03:59.000000000 +0000
2923 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext4/ext4.h     2017-05-30 07:39:23.000000000 +0000
2924 @@ -378,7 +378,10 @@ struct flex_groups {
2925  #define EXT4_EXTENTS_FL                        0x00080000 /* Inode uses extents */
2926  #define EXT4_EA_INODE_FL               0x00200000 /* Inode used for large EA */
2927  #define EXT4_EOFBLOCKS_FL              0x00400000 /* Blocks allocated beyond EOF */
2928 +#define EXT4_BARRIER_FL                        0x04000000 /* Barrier for chroot() */
2929 +#define EXT4_IXUNLINK_FL               0x08000000 /* Immutable invert on unlink */
2930  #define EXT4_INLINE_DATA_FL            0x10000000 /* Inode has inline data. */
2931 +#define EXT4_COW_FL                    0x20000000 /* Copy on Write marker */
2932  #define EXT4_RESERVED_FL               0x80000000 /* reserved for ext4 lib */
2933  
2934  #define EXT4_FL_USER_VISIBLE           0x004BDFFF /* User visible flags */
2935 @@ -674,7 +677,7 @@ struct ext4_inode {
2936                         __le16  l_i_uid_high;   /* these 2 fields */
2937                         __le16  l_i_gid_high;   /* were reserved2[0] */
2938                         __le16  l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
2939 -                       __le16  l_i_reserved;
2940 +                       __le16  l_i_tag;        /* Context Tag */
2941                 } linux2;
2942                 struct {
2943                         __le16  h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
2944 @@ -794,6 +797,7 @@ do {                                                                               \
2945  #define i_gid_low      i_gid
2946  #define i_uid_high     osd2.linux2.l_i_uid_high
2947  #define i_gid_high     osd2.linux2.l_i_gid_high
2948 +#define i_raw_tag      osd2.linux2.l_i_tag
2949  #define i_checksum_lo  osd2.linux2.l_i_checksum_lo
2950  
2951  #elif defined(__GNU__)
2952 @@ -1033,6 +1037,7 @@ struct ext4_inode_info {
2953  #define EXT4_MOUNT_POSIX_ACL           0x08000 /* POSIX Access Control Lists */
2954  #define EXT4_MOUNT_NO_AUTO_DA_ALLOC    0x10000 /* No auto delalloc mapping */
2955  #define EXT4_MOUNT_BARRIER             0x20000 /* Use block barriers */
2956 +#define EXT4_MOUNT_TAGGED              0x40000 /* Enable Context Tags */
2957  #define EXT4_MOUNT_QUOTA               0x80000 /* Some quota option set */
2958  #define EXT4_MOUNT_USRQUOTA            0x100000 /* "old" user quota */
2959  #define EXT4_MOUNT_GRPQUOTA            0x200000 /* "old" group quota */
2960 @@ -2314,6 +2319,7 @@ extern int ext4_punch_hole(struct inode
2961  extern int ext4_truncate_restart_trans(handle_t *, struct inode *, int nblocks);
2962  extern void ext4_set_inode_flags(struct inode *);
2963  extern void ext4_get_inode_flags(struct ext4_inode_info *);
2964 +extern int ext4_sync_flags(struct inode *, int, int);
2965  extern int ext4_alloc_da_blocks(struct inode *inode);
2966  extern void ext4_set_aops(struct inode *inode);
2967  extern int ext4_writepage_trans_blocks(struct inode *);
2968 diff -NurpP --minimal linux-4.1.41/fs/ext4/file.c linux-4.1.41-vs2.3.8.5.3/fs/ext4/file.c
2969 --- linux-4.1.41/fs/ext4/file.c 2017-06-23 10:03:59.000000000 +0000
2970 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext4/file.c     2016-07-05 04:41:47.000000000 +0000
2971 @@ -659,5 +659,6 @@ const struct inode_operations ext4_file_
2972         .get_acl        = ext4_get_acl,
2973         .set_acl        = ext4_set_acl,
2974         .fiemap         = ext4_fiemap,
2975 +       .sync_flags     = ext4_sync_flags,
2976  };
2977  
2978 diff -NurpP --minimal linux-4.1.41/fs/ext4/ialloc.c linux-4.1.41-vs2.3.8.5.3/fs/ext4/ialloc.c
2979 --- linux-4.1.41/fs/ext4/ialloc.c       2017-06-23 10:03:59.000000000 +0000
2980 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext4/ialloc.c   2016-07-05 04:41:47.000000000 +0000
2981 @@ -21,6 +21,7 @@
2982  #include <linux/random.h>
2983  #include <linux/bitops.h>
2984  #include <linux/blkdev.h>
2985 +#include <linux/vs_tag.h>
2986  #include <asm/byteorder.h>
2987  
2988  #include "ext4.h"
2989 @@ -753,6 +754,7 @@ struct inode *__ext4_new_inode(handle_t
2990                 inode->i_mode = mode;
2991                 inode->i_uid = current_fsuid();
2992                 inode->i_gid = dir->i_gid;
2993 +               i_tag_write(inode, dx_current_fstag(sb));
2994         } else
2995                 inode_init_owner(inode, dir, mode);
2996         dquot_initialize(inode);
2997 diff -NurpP --minimal linux-4.1.41/fs/ext4/inode.c linux-4.1.41-vs2.3.8.5.3/fs/ext4/inode.c
2998 --- linux-4.1.41/fs/ext4/inode.c        2017-06-23 10:03:59.000000000 +0000
2999 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext4/inode.c    2017-05-30 07:39:23.000000000 +0000
3000 @@ -36,6 +36,7 @@
3001  #include <linux/printk.h>
3002  #include <linux/slab.h>
3003  #include <linux/bitops.h>
3004 +#include <linux/vs_tag.h>
3005  
3006  #include "ext4_jbd2.h"
3007  #include "xattr.h"
3008 @@ -4043,12 +4044,15 @@ void ext4_set_inode_flags(struct inode *
3009         unsigned int flags = EXT4_I(inode)->i_flags;
3010         unsigned int new_fl = 0;
3011  
3012 +       if (flags & EXT4_IMMUTABLE_FL)
3013 +               new_fl |= S_IMMUTABLE;
3014 +       if (flags & EXT4_IXUNLINK_FL)
3015 +               new_fl |= S_IXUNLINK;
3016 +
3017         if (flags & EXT4_SYNC_FL)
3018                 new_fl |= S_SYNC;
3019         if (flags & EXT4_APPEND_FL)
3020                 new_fl |= S_APPEND;
3021 -       if (flags & EXT4_IMMUTABLE_FL)
3022 -               new_fl |= S_IMMUTABLE;
3023         if (flags & EXT4_NOATIME_FL)
3024                 new_fl |= S_NOATIME;
3025         if (flags & EXT4_DIRSYNC_FL)
3026 @@ -4056,31 +4060,52 @@ void ext4_set_inode_flags(struct inode *
3027         if (test_opt(inode->i_sb, DAX))
3028                 new_fl |= S_DAX;
3029         inode_set_flags(inode, new_fl,
3030 -                       S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX);
3031 +               S_IXUNLINK | S_IMMUTABLE | S_DAX |
3032 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
3033 +
3034 +       new_fl = 0;
3035 +       if (flags & EXT4_BARRIER_FL)
3036 +               new_fl |= V_BARRIER;
3037 +       if (flags & EXT4_COW_FL)
3038 +               new_fl |= V_COW;
3039 +
3040 +       set_mask_bits(&inode->i_vflags,
3041 +               V_BARRIER | V_COW, new_fl);
3042  }
3043  
3044  /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
3045  void ext4_get_inode_flags(struct ext4_inode_info *ei)
3046  {
3047 -       unsigned int vfs_fl;
3048 +       unsigned int vfs_fl, vfs_vf;
3049         unsigned long old_fl, new_fl;
3050  
3051         do {
3052                 vfs_fl = ei->vfs_inode.i_flags;
3053 +               vfs_vf = ei->vfs_inode.i_vflags;
3054                 old_fl = ei->i_flags;
3055                 new_fl = old_fl & ~(EXT4_SYNC_FL|EXT4_APPEND_FL|
3056                                 EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL|
3057 -                               EXT4_DIRSYNC_FL);
3058 +                               EXT4_DIRSYNC_FL|EXT4_BARRIER_FL|
3059 +                               EXT4_COW_FL);
3060 +
3061 +               if (vfs_fl & S_IMMUTABLE)
3062 +                       new_fl |= EXT4_IMMUTABLE_FL;
3063 +               if (vfs_fl & S_IXUNLINK)
3064 +                       new_fl |= EXT4_IXUNLINK_FL;
3065 +
3066                 if (vfs_fl & S_SYNC)
3067                         new_fl |= EXT4_SYNC_FL;
3068                 if (vfs_fl & S_APPEND)
3069                         new_fl |= EXT4_APPEND_FL;
3070 -               if (vfs_fl & S_IMMUTABLE)
3071 -                       new_fl |= EXT4_IMMUTABLE_FL;
3072                 if (vfs_fl & S_NOATIME)
3073                         new_fl |= EXT4_NOATIME_FL;
3074                 if (vfs_fl & S_DIRSYNC)
3075                         new_fl |= EXT4_DIRSYNC_FL;
3076 +
3077 +               if (vfs_vf & V_BARRIER)
3078 +                       new_fl |= EXT4_BARRIER_FL;
3079 +               if (vfs_vf & V_COW)
3080 +                       new_fl |= EXT4_COW_FL;
3081         } while (cmpxchg(&ei->i_flags, old_fl, new_fl) != old_fl);
3082  }
3083  
3084 @@ -4184,8 +4209,10 @@ struct inode *ext4_iget(struct super_blo
3085                 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
3086                 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
3087         }
3088 -       i_uid_write(inode, i_uid);
3089 -       i_gid_write(inode, i_gid);
3090 +       i_uid_write(inode, INOTAG_UID(DX_TAG(inode), i_uid, i_gid));
3091 +       i_gid_write(inode, INOTAG_GID(DX_TAG(inode), i_uid, i_gid));
3092 +       i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
3093 +               le16_to_cpu(raw_inode->i_raw_tag)));
3094         set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
3095  
3096         ext4_clear_state_flags(ei);     /* Only relevant on 32-bit archs */
3097 @@ -4490,8 +4517,10 @@ static int ext4_do_update_inode(handle_t
3098  
3099         ext4_get_inode_flags(ei);
3100         raw_inode->i_mode = cpu_to_le16(inode->i_mode);
3101 -       i_uid = i_uid_read(inode);
3102 -       i_gid = i_gid_read(inode);
3103 +       i_uid = from_kuid(&init_user_ns,
3104 +               TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
3105 +       i_gid = from_kgid(&init_user_ns,
3106 +               TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
3107         if (!(test_opt(inode->i_sb, NO_UID32))) {
3108                 raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid));
3109                 raw_inode->i_gid_low = cpu_to_le16(low_16_bits(i_gid));
3110 @@ -4514,6 +4543,9 @@ static int ext4_do_update_inode(handle_t
3111                 raw_inode->i_uid_high = 0;
3112                 raw_inode->i_gid_high = 0;
3113         }
3114 +#ifdef CONFIG_TAGGING_INTERN
3115 +       raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
3116 +#endif
3117         raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
3118  
3119         EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode);
3120 @@ -4758,7 +4790,8 @@ int ext4_setattr(struct dentry *dentry,
3121         if (is_quota_modification(inode, attr))
3122                 dquot_initialize(inode);
3123         if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
3124 -           (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
3125 +           (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid)) ||
3126 +           (ia_valid & ATTR_TAG && !tag_eq(attr->ia_tag, inode->i_tag))) {
3127                 handle_t *handle;
3128  
3129                 /* (user+group)*(old+new) structure, inode write (sb,
3130 @@ -4781,6 +4814,8 @@ int ext4_setattr(struct dentry *dentry,
3131                         inode->i_uid = attr->ia_uid;
3132                 if (attr->ia_valid & ATTR_GID)
3133                         inode->i_gid = attr->ia_gid;
3134 +               if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
3135 +                       inode->i_tag = attr->ia_tag;
3136                 error = ext4_mark_inode_dirty(handle, inode);
3137                 ext4_journal_stop(handle);
3138         }
3139 diff -NurpP --minimal linux-4.1.41/fs/ext4/ioctl.c linux-4.1.41-vs2.3.8.5.3/fs/ext4/ioctl.c
3140 --- linux-4.1.41/fs/ext4/ioctl.c        2017-06-23 10:03:59.000000000 +0000
3141 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext4/ioctl.c    2016-10-25 21:31:19.000000000 +0000
3142 @@ -14,6 +14,7 @@
3143  #include <linux/mount.h>
3144  #include <linux/file.h>
3145  #include <linux/random.h>
3146 +#include <linux/vs_tag.h>
3147  #include <asm/uaccess.h>
3148  #include "ext4_jbd2.h"
3149  #include "ext4.h"
3150 @@ -206,6 +207,33 @@ static int uuid_is_zero(__u8 u[16])
3151         return 1;
3152  }
3153  
3154 +int ext4_sync_flags(struct inode *inode, int flags, int vflags)
3155 +{
3156 +       handle_t *handle = NULL;
3157 +       struct ext4_iloc iloc;
3158 +       int err;
3159 +
3160 +       handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
3161 +       if (IS_ERR(handle))
3162 +               return PTR_ERR(handle);
3163 +
3164 +       if (IS_SYNC(inode))
3165 +               ext4_handle_sync(handle);
3166 +       err = ext4_reserve_inode_write(handle, inode, &iloc);
3167 +       if (err)
3168 +               goto flags_err;
3169 +
3170 +       inode->i_flags = flags;
3171 +       inode->i_vflags = vflags;
3172 +       ext4_get_inode_flags(EXT4_I(inode));
3173 +       inode->i_ctime = ext4_current_time(inode);
3174 +
3175 +       err = ext4_mark_iloc_dirty(handle, inode, &iloc);
3176 +flags_err:
3177 +       ext4_journal_stop(handle);
3178 +       return err;
3179 +}
3180 +
3181  long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3182  {
3183         struct inode *inode = file_inode(filp);
3184 @@ -239,6 +267,11 @@ long ext4_ioctl(struct file *filp, unsig
3185  
3186                 flags = ext4_mask_flags(inode->i_mode, flags);
3187  
3188 +               if (IS_BARRIER(inode)) {
3189 +                       vxwprintk_task(1, "messing with the barrier.");
3190 +                       return -EACCES;
3191 +               }
3192 +
3193                 err = -EPERM;
3194                 mutex_lock(&inode->i_mutex);
3195                 /* Is it quota file? Do not allow user to mess with it */
3196 @@ -256,7 +289,9 @@ long ext4_ioctl(struct file *filp, unsig
3197                  *
3198                  * This test looks nicer. Thanks to Pauline Middelink
3199                  */
3200 -               if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
3201 +               if ((oldflags & EXT4_IMMUTABLE_FL) ||
3202 +                       ((flags ^ oldflags) & (EXT4_APPEND_FL |
3203 +                       EXT4_IMMUTABLE_FL | EXT4_IXUNLINK_FL))) {
3204                         if (!capable(CAP_LINUX_IMMUTABLE))
3205                                 goto flags_out;
3206                 }
3207 diff -NurpP --minimal linux-4.1.41/fs/ext4/namei.c linux-4.1.41-vs2.3.8.5.3/fs/ext4/namei.c
3208 --- linux-4.1.41/fs/ext4/namei.c        2017-06-23 10:03:59.000000000 +0000
3209 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext4/namei.c    2016-07-05 04:41:47.000000000 +0000
3210 @@ -33,6 +33,7 @@
3211  #include <linux/quotaops.h>
3212  #include <linux/buffer_head.h>
3213  #include <linux/bio.h>
3214 +#include <linux/vs_tag.h>
3215  #include "ext4.h"
3216  #include "ext4_jbd2.h"
3217  
3218 @@ -1447,6 +1448,7 @@ restart:
3219                                         ll_rw_block(READ | REQ_META | REQ_PRIO,
3220                                                     1, &bh);
3221                         }
3222 +               dx_propagate_tag(nd, inode);
3223                 }
3224                 if ((bh = bh_use[ra_ptr++]) == NULL)
3225                         goto next;
3226 @@ -3905,6 +3907,7 @@ const struct inode_operations ext4_dir_i
3227         .get_acl        = ext4_get_acl,
3228         .set_acl        = ext4_set_acl,
3229         .fiemap         = ext4_fiemap,
3230 +       .sync_flags     = ext4_sync_flags,
3231  };
3232  
3233  const struct inode_operations ext4_special_inode_operations = {
3234 diff -NurpP --minimal linux-4.1.41/fs/ext4/super.c linux-4.1.41-vs2.3.8.5.3/fs/ext4/super.c
3235 --- linux-4.1.41/fs/ext4/super.c        2017-06-23 10:03:59.000000000 +0000
3236 +++ linux-4.1.41-vs2.3.8.5.3/fs/ext4/super.c    2017-05-30 07:39:23.000000000 +0000
3237 @@ -1147,6 +1147,7 @@ enum {
3238         Opt_no_mbcache,
3239         Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
3240         Opt_max_dir_size_kb, Opt_nojournal_checksum,
3241 +       Opt_tag, Opt_notag, Opt_tagid
3242  };
3243  
3244  static const match_table_t tokens = {
3245 @@ -1233,6 +1234,9 @@ static const match_table_t tokens = {
3246         {Opt_removed, "reservation"},   /* mount option from ext2/3 */
3247         {Opt_removed, "noreservation"}, /* mount option from ext2/3 */
3248         {Opt_removed, "journal=%u"},    /* mount option from ext2/3 */
3249 +       {Opt_tag, "tag"},
3250 +       {Opt_notag, "notag"},
3251 +       {Opt_tagid, "tagid=%u"},
3252         {Opt_err, NULL},
3253  };
3254  
3255 @@ -1476,6 +1480,20 @@ static int handle_mount_opt(struct super
3256         case Opt_nolazytime:
3257                 sb->s_flags &= ~MS_LAZYTIME;
3258                 return 1;
3259 +#ifndef CONFIG_TAGGING_NONE
3260 +       case Opt_tag:
3261 +               set_opt(sb, TAGGED);
3262 +               return 1;
3263 +       case Opt_notag:
3264 +               clear_opt(sb, TAGGED);
3265 +               return 1;
3266 +#endif
3267 +#ifdef CONFIG_PROPAGATE
3268 +       case Opt_tagid:
3269 +               /* use args[0] */
3270 +               set_opt(sb, TAGGED);
3271 +               return 1;
3272 +#endif
3273         }
3274  
3275         for (m = ext4_mount_opts; m->token != Opt_err; m++)
3276 @@ -3686,6 +3704,9 @@ static int ext4_fill_super(struct super_
3277                         clear_opt(sb, DELALLOC);
3278         }
3279  
3280 +       if (EXT4_SB(sb)->s_mount_opt & EXT4_MOUNT_TAGGED)
3281 +               sb->s_flags |= MS_TAGGED;
3282 +
3283         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
3284                 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
3285  
3286 @@ -5016,6 +5037,14 @@ static int ext4_remount(struct super_blo
3287         if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED)
3288                 ext4_abort(sb, "Abort forced by user");
3289  
3290 +       if ((sbi->s_mount_opt & EXT4_MOUNT_TAGGED) &&
3291 +               !(sb->s_flags & MS_TAGGED)) {
3292 +               printk("EXT4-fs: %s: tagging not permitted on remount.\n",
3293 +                       sb->s_id);
3294 +               err = -EINVAL;
3295 +               goto restore_opts;
3296 +       }
3297 +
3298         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
3299                 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
3300  
3301 diff -NurpP --minimal linux-4.1.41/fs/fcntl.c linux-4.1.41-vs2.3.8.5.3/fs/fcntl.c
3302 --- linux-4.1.41/fs/fcntl.c     2015-04-12 22:12:50.000000000 +0000
3303 +++ linux-4.1.41-vs2.3.8.5.3/fs/fcntl.c 2016-07-05 04:41:47.000000000 +0000
3304 @@ -22,6 +22,7 @@
3305  #include <linux/pid_namespace.h>
3306  #include <linux/user_namespace.h>
3307  #include <linux/shmem_fs.h>
3308 +#include <linux/vs_limit.h>
3309  
3310  #include <asm/poll.h>
3311  #include <asm/siginfo.h>
3312 @@ -385,6 +386,8 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, f
3313  
3314         if (!f.file)
3315                 goto out;
3316 +       if (!vx_files_avail(1))
3317 +               goto out;
3318  
3319         if (unlikely(f.file->f_mode & FMODE_PATH)) {
3320                 if (!check_fcntl_cmd(cmd))
3321 diff -NurpP --minimal linux-4.1.41/fs/file.c linux-4.1.41-vs2.3.8.5.3/fs/file.c
3322 --- linux-4.1.41/fs/file.c      2015-07-06 20:41:42.000000000 +0000
3323 +++ linux-4.1.41-vs2.3.8.5.3/fs/file.c  2016-07-05 04:41:47.000000000 +0000
3324 @@ -22,6 +22,7 @@
3325  #include <linux/spinlock.h>
3326  #include <linux/rcupdate.h>
3327  #include <linux/workqueue.h>
3328 +#include <linux/vs_limit.h>
3329  
3330  int sysctl_nr_open __read_mostly = 1024*1024;
3331  int sysctl_nr_open_min = BITS_PER_LONG;
3332 @@ -309,6 +310,8 @@ struct files_struct *dup_fd(struct files
3333                 struct file *f = *old_fds++;
3334                 if (f) {
3335                         get_file(f);
3336 +                       /* TODO: sum it first for check and performance */
3337 +                       vx_openfd_inc(open_files - i);
3338                 } else {
3339                         /*
3340                          * The fd may be claimed in the fd bitmap but not yet
3341 @@ -369,9 +372,11 @@ static struct fdtable *close_files(struc
3342                                         filp_close(file, files);
3343                                         cond_resched_rcu_qs();
3344                                 }
3345 +                               vx_openfd_dec(i);
3346                         }
3347                         i++;
3348                         set >>= 1;
3349 +                       cond_resched();
3350                 }
3351         }
3352  
3353 @@ -487,6 +492,7 @@ repeat:
3354         else
3355                 __clear_close_on_exec(fd, fdt);
3356         error = fd;
3357 +       vx_openfd_inc(fd);
3358  #if 1
3359         /* Sanity check */
3360         if (rcu_access_pointer(fdt->fd[fd]) != NULL) {
3361 @@ -517,6 +523,7 @@ static void __put_unused_fd(struct files
3362         __clear_open_fd(fd, fdt);
3363         if (fd < files->next_fd)
3364                 files->next_fd = fd;
3365 +       vx_openfd_dec(fd);
3366  }
3367  
3368  void put_unused_fd(unsigned int fd)
3369 @@ -783,6 +790,8 @@ __releases(&files->file_lock)
3370  
3371         if (tofree)
3372                 filp_close(tofree, files);
3373 +       else
3374 +               vx_openfd_inc(fd);      /* fd was unused */
3375  
3376         return fd;
3377  
3378 diff -NurpP --minimal linux-4.1.41/fs/file_table.c linux-4.1.41-vs2.3.8.5.3/fs/file_table.c
3379 --- linux-4.1.41/fs/file_table.c        2015-07-06 20:41:42.000000000 +0000
3380 +++ linux-4.1.41-vs2.3.8.5.3/fs/file_table.c    2016-07-05 04:41:47.000000000 +0000
3381 @@ -26,6 +26,8 @@
3382  #include <linux/hardirq.h>
3383  #include <linux/task_work.h>
3384  #include <linux/ima.h>
3385 +#include <linux/vs_limit.h>
3386 +#include <linux/vs_context.h>
3387  
3388  #include <linux/atomic.h>
3389  
3390 @@ -137,6 +139,8 @@ struct file *get_empty_filp(void)
3391         mutex_init(&f->f_pos_lock);
3392         eventpoll_init_file(f);
3393         /* f->f_version: 0 */
3394 +       f->f_xid = vx_current_xid();
3395 +       vx_files_inc(f);
3396         return f;
3397  
3398  over:
3399 @@ -219,6 +223,8 @@ static void __fput(struct file *file)
3400                 put_write_access(inode);
3401                 __mnt_drop_write(mnt);
3402         }
3403 +       vx_files_dec(file);
3404 +       file->f_xid = 0;
3405         file->f_path.dentry = NULL;
3406         file->f_path.mnt = NULL;
3407         file->f_inode = NULL;
3408 @@ -305,6 +311,8 @@ void put_filp(struct file *file)
3409  {
3410         if (atomic_long_dec_and_test(&file->f_count)) {
3411                 security_file_free(file);
3412 +               vx_files_dec(file);
3413 +               file->f_xid = 0;
3414                 file_free(file);
3415         }
3416  }
3417 diff -NurpP --minimal linux-4.1.41/fs/fs_struct.c linux-4.1.41-vs2.3.8.5.3/fs/fs_struct.c
3418 --- linux-4.1.41/fs/fs_struct.c 2015-04-12 22:12:50.000000000 +0000
3419 +++ linux-4.1.41-vs2.3.8.5.3/fs/fs_struct.c     2016-07-05 04:41:47.000000000 +0000
3420 @@ -4,6 +4,7 @@
3421  #include <linux/path.h>
3422  #include <linux/slab.h>
3423  #include <linux/fs_struct.h>
3424 +#include <linux/vserver/global.h>
3425  #include "internal.h"
3426  
3427  /*
3428 @@ -87,6 +88,7 @@ void free_fs_struct(struct fs_struct *fs
3429  {
3430         path_put(&fs->root);
3431         path_put(&fs->pwd);
3432 +       atomic_dec(&vs_global_fs);
3433         kmem_cache_free(fs_cachep, fs);
3434  }
3435  
3436 @@ -124,6 +126,7 @@ struct fs_struct *copy_fs_struct(struct
3437                 fs->pwd = old->pwd;
3438                 path_get(&fs->pwd);
3439                 spin_unlock(&old->lock);
3440 +               atomic_inc(&vs_global_fs);
3441         }
3442         return fs;
3443  }
3444 diff -NurpP --minimal linux-4.1.41/fs/gfs2/file.c linux-4.1.41-vs2.3.8.5.3/fs/gfs2/file.c
3445 --- linux-4.1.41/fs/gfs2/file.c 2015-07-06 20:41:42.000000000 +0000
3446 +++ linux-4.1.41-vs2.3.8.5.3/fs/gfs2/file.c     2016-07-05 04:41:47.000000000 +0000
3447 @@ -137,6 +137,9 @@ static const u32 fsflags_to_gfs2[32] = {
3448         [12] = GFS2_DIF_EXHASH,
3449         [14] = GFS2_DIF_INHERIT_JDATA,
3450         [17] = GFS2_DIF_TOPDIR,
3451 +       [27] = GFS2_DIF_IXUNLINK,
3452 +       [26] = GFS2_DIF_BARRIER,
3453 +       [29] = GFS2_DIF_COW,
3454  };
3455  
3456  static const u32 gfs2_to_fsflags[32] = {
3457 @@ -147,6 +150,9 @@ static const u32 gfs2_to_fsflags[32] = {
3458         [gfs2fl_ExHash] = FS_INDEX_FL,
3459         [gfs2fl_TopLevel] = FS_TOPDIR_FL,
3460         [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL,
3461 +       [gfs2fl_IXUnlink] = FS_IXUNLINK_FL,
3462 +       [gfs2fl_Barrier] = FS_BARRIER_FL,
3463 +       [gfs2fl_Cow] = FS_COW_FL,
3464  };
3465  
3466  static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
3467 @@ -177,12 +183,18 @@ void gfs2_set_inode_flags(struct inode *
3468  {
3469         struct gfs2_inode *ip = GFS2_I(inode);
3470         unsigned int flags = inode->i_flags;
3471 +       unsigned int vflags = inode->i_vflags;
3472 +
3473 +       flags &= ~(S_IMMUTABLE | S_IXUNLINK |
3474 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC | S_NOSEC);
3475  
3476 -       flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_NOSEC);
3477         if ((ip->i_eattr == 0) && !is_sxid(inode->i_mode))
3478                 inode->i_flags |= S_NOSEC;
3479         if (ip->i_diskflags & GFS2_DIF_IMMUTABLE)
3480                 flags |= S_IMMUTABLE;
3481 +       if (ip->i_diskflags & GFS2_DIF_IXUNLINK)
3482 +               flags |= S_IXUNLINK;
3483 +
3484         if (ip->i_diskflags & GFS2_DIF_APPENDONLY)
3485                 flags |= S_APPEND;
3486         if (ip->i_diskflags & GFS2_DIF_NOATIME)
3487 @@ -190,6 +202,43 @@ void gfs2_set_inode_flags(struct inode *
3488         if (ip->i_diskflags & GFS2_DIF_SYNC)
3489                 flags |= S_SYNC;
3490         inode->i_flags = flags;
3491 +
3492 +       vflags &= ~(V_BARRIER | V_COW);
3493 +
3494 +       if (ip->i_diskflags & GFS2_DIF_BARRIER)
3495 +               vflags |= V_BARRIER;
3496 +       if (ip->i_diskflags & GFS2_DIF_COW)
3497 +               vflags |= V_COW;
3498 +       inode->i_vflags = vflags;
3499 +}
3500 +
3501 +void gfs2_get_inode_flags(struct inode *inode)
3502 +{
3503 +       struct gfs2_inode *ip = GFS2_I(inode);
3504 +       unsigned int flags = inode->i_flags;
3505 +       unsigned int vflags = inode->i_vflags;
3506 +
3507 +       ip->i_diskflags &= ~(GFS2_DIF_APPENDONLY |
3508 +                       GFS2_DIF_NOATIME | GFS2_DIF_SYNC |
3509 +                       GFS2_DIF_IMMUTABLE | GFS2_DIF_IXUNLINK |
3510 +                       GFS2_DIF_BARRIER | GFS2_DIF_COW);
3511 +
3512 +       if (flags & S_IMMUTABLE)
3513 +               ip->i_diskflags |= GFS2_DIF_IMMUTABLE;
3514 +       if (flags & S_IXUNLINK)
3515 +               ip->i_diskflags |= GFS2_DIF_IXUNLINK;
3516 +
3517 +       if (flags & S_APPEND)
3518 +               ip->i_diskflags |= GFS2_DIF_APPENDONLY;
3519 +       if (flags & S_NOATIME)
3520 +               ip->i_diskflags |= GFS2_DIF_NOATIME;
3521 +       if (flags & S_SYNC)
3522 +               ip->i_diskflags |= GFS2_DIF_SYNC;
3523 +
3524 +       if (vflags & V_BARRIER)
3525 +               ip->i_diskflags |= GFS2_DIF_BARRIER;
3526 +       if (vflags & V_COW)
3527 +               ip->i_diskflags |= GFS2_DIF_COW;
3528  }
3529  
3530  /* Flags that can be set by user space */
3531 @@ -303,6 +352,37 @@ static int gfs2_set_flags(struct file *f
3532         return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA);
3533  }
3534  
3535 +int gfs2_sync_flags(struct inode *inode, int flags, int vflags)
3536 +{
3537 +       struct gfs2_inode *ip = GFS2_I(inode);
3538 +       struct gfs2_sbd *sdp = GFS2_SB(inode);
3539 +       struct buffer_head *bh;
3540 +       struct gfs2_holder gh;
3541 +       int error;
3542 +
3543 +       error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
3544 +       if (error)
3545 +               return error;
3546 +       error = gfs2_trans_begin(sdp, RES_DINODE, 0);
3547 +       if (error)
3548 +               goto out;
3549 +       error = gfs2_meta_inode_buffer(ip, &bh);
3550 +       if (error)
3551 +               goto out_trans_end;
3552 +       gfs2_trans_add_meta(ip->i_gl, bh);
3553 +       inode->i_flags = flags;
3554 +       inode->i_vflags = vflags;
3555 +       gfs2_get_inode_flags(inode);
3556 +       gfs2_dinode_out(ip, bh->b_data);
3557 +       brelse(bh);
3558 +       gfs2_set_aops(inode);
3559 +out_trans_end:
3560 +       gfs2_trans_end(sdp);
3561 +out:
3562 +       gfs2_glock_dq_uninit(&gh);
3563 +       return error;
3564 +}
3565 +
3566  static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3567  {
3568         switch(cmd) {
3569 diff -NurpP --minimal linux-4.1.41/fs/gfs2/inode.h linux-4.1.41-vs2.3.8.5.3/fs/gfs2/inode.h
3570 --- linux-4.1.41/fs/gfs2/inode.h        2015-04-12 22:12:50.000000000 +0000
3571 +++ linux-4.1.41-vs2.3.8.5.3/fs/gfs2/inode.h    2016-07-05 04:41:47.000000000 +0000
3572 @@ -118,6 +118,7 @@ extern const struct file_operations gfs2
3573  extern const struct file_operations gfs2_dir_fops_nolock;
3574  
3575  extern void gfs2_set_inode_flags(struct inode *inode);
3576 +extern int gfs2_sync_flags(struct inode *inode, int flags, int vflags);
3577   
3578  #ifdef CONFIG_GFS2_FS_LOCKING_DLM
3579  extern const struct file_operations gfs2_file_fops;
3580 diff -NurpP --minimal linux-4.1.41/fs/hostfs/hostfs.h linux-4.1.41-vs2.3.8.5.3/fs/hostfs/hostfs.h
3581 --- linux-4.1.41/fs/hostfs/hostfs.h     2015-07-06 20:41:42.000000000 +0000
3582 +++ linux-4.1.41-vs2.3.8.5.3/fs/hostfs/hostfs.h 2016-07-05 04:41:47.000000000 +0000
3583 @@ -42,6 +42,7 @@ struct hostfs_iattr {
3584         unsigned short  ia_mode;
3585         uid_t           ia_uid;
3586         gid_t           ia_gid;
3587 +       vtag_t          ia_tag;
3588         loff_t          ia_size;
3589         struct timespec ia_atime;
3590         struct timespec ia_mtime;
3591 diff -NurpP --minimal linux-4.1.41/fs/inode.c linux-4.1.41-vs2.3.8.5.3/fs/inode.c
3592 --- linux-4.1.41/fs/inode.c     2017-06-23 10:03:59.000000000 +0000
3593 +++ linux-4.1.41-vs2.3.8.5.3/fs/inode.c 2016-07-05 04:41:47.000000000 +0000
3594 @@ -18,6 +18,7 @@
3595  #include <linux/buffer_head.h> /* for inode_has_buffers */
3596  #include <linux/ratelimit.h>
3597  #include <linux/list_lru.h>
3598 +#include <linux/vs_tag.h>
3599  #include <trace/events/writeback.h>
3600  #include "internal.h"
3601  
3602 @@ -135,6 +136,8 @@ int inode_init_always(struct super_block
3603         struct address_space *const mapping = &inode->i_data;
3604  
3605         inode->i_sb = sb;
3606 +
3607 +       /* essential because of inode slab reuse */
3608         inode->i_blkbits = sb->s_blocksize_bits;
3609         inode->i_flags = 0;
3610         atomic_set(&inode->i_count, 1);
3611 @@ -144,6 +147,7 @@ int inode_init_always(struct super_block
3612         inode->i_opflags = 0;
3613         i_uid_write(inode, 0);
3614         i_gid_write(inode, 0);
3615 +       i_tag_write(inode, 0);
3616         atomic_set(&inode->i_writecount, 0);
3617         inode->i_size = 0;
3618         inode->i_blocks = 0;
3619 @@ -153,6 +157,7 @@ int inode_init_always(struct super_block
3620         inode->i_bdev = NULL;
3621         inode->i_cdev = NULL;
3622         inode->i_rdev = 0;
3623 +       inode->i_mdev = 0;
3624         inode->dirtied_when = 0;
3625  
3626         if (security_inode_alloc(inode))
3627 @@ -469,6 +474,8 @@ void __insert_inode_hash(struct inode *i
3628  }
3629  EXPORT_SYMBOL(__insert_inode_hash);
3630  
3631 +EXPORT_SYMBOL_GPL(__iget);
3632 +
3633  /**
3634   *     __remove_inode_hash - remove an inode from the hash
3635   *     @inode: inode to unhash
3636 @@ -1857,9 +1864,11 @@ void init_special_inode(struct inode *in
3637         if (S_ISCHR(mode)) {
3638                 inode->i_fop = &def_chr_fops;
3639                 inode->i_rdev = rdev;
3640 +               inode->i_mdev = rdev;
3641         } else if (S_ISBLK(mode)) {
3642                 inode->i_fop = &def_blk_fops;
3643                 inode->i_rdev = rdev;
3644 +               inode->i_mdev = rdev;
3645         } else if (S_ISFIFO(mode))
3646                 inode->i_fop = &pipefifo_fops;
3647         else if (S_ISSOCK(mode))
3648 @@ -1888,6 +1897,7 @@ void inode_init_owner(struct inode *inod
3649         } else
3650                 inode->i_gid = current_fsgid();
3651         inode->i_mode = mode;
3652 +       i_tag_write(inode, dx_current_fstag(inode->i_sb));
3653  }
3654  EXPORT_SYMBOL(inode_init_owner);
3655  
3656 diff -NurpP --minimal linux-4.1.41/fs/ioctl.c linux-4.1.41-vs2.3.8.5.3/fs/ioctl.c
3657 --- linux-4.1.41/fs/ioctl.c     2015-04-12 22:12:50.000000000 +0000
3658 +++ linux-4.1.41-vs2.3.8.5.3/fs/ioctl.c 2016-07-05 04:41:47.000000000 +0000
3659 @@ -15,6 +15,9 @@
3660  #include <linux/writeback.h>
3661  #include <linux/buffer_head.h>
3662  #include <linux/falloc.h>
3663 +#include <linux/proc_fs.h>
3664 +#include <linux/vserver/inode.h>
3665 +#include <linux/vs_tag.h>
3666  
3667  #include <asm/ioctls.h>
3668  
3669 diff -NurpP --minimal linux-4.1.41/fs/jfs/file.c linux-4.1.41-vs2.3.8.5.3/fs/jfs/file.c
3670 --- linux-4.1.41/fs/jfs/file.c  2017-06-23 10:03:59.000000000 +0000
3671 +++ linux-4.1.41-vs2.3.8.5.3/fs/jfs/file.c      2017-05-30 07:39:23.000000000 +0000
3672 @@ -110,7 +110,8 @@ int jfs_setattr(struct dentry *dentry, s
3673         if (is_quota_modification(inode, iattr))
3674                 dquot_initialize(inode);
3675         if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
3676 -           (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
3677 +           (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)) ||
3678 +           (iattr->ia_valid & ATTR_TAG && !tag_eq(iattr->ia_tag, inode->i_tag))) {
3679                 rc = dquot_transfer(inode, iattr);
3680                 if (rc)
3681                         return rc;
3682 @@ -146,6 +147,7 @@ const struct inode_operations jfs_file_i
3683         .get_acl        = jfs_get_acl,
3684         .set_acl        = jfs_set_acl,
3685  #endif
3686 +       .sync_flags     = jfs_sync_flags,
3687  };
3688  
3689  const struct file_operations jfs_file_operations = {
3690 diff -NurpP --minimal linux-4.1.41/fs/jfs/ioctl.c linux-4.1.41-vs2.3.8.5.3/fs/jfs/ioctl.c
3691 --- linux-4.1.41/fs/jfs/ioctl.c 2015-04-12 22:12:50.000000000 +0000
3692 +++ linux-4.1.41-vs2.3.8.5.3/fs/jfs/ioctl.c     2016-07-05 04:41:47.000000000 +0000
3693 @@ -12,6 +12,7 @@
3694  #include <linux/time.h>
3695  #include <linux/sched.h>
3696  #include <linux/blkdev.h>
3697 +#include <linux/mount.h>
3698  #include <asm/current.h>
3699  #include <asm/uaccess.h>
3700  
3701 @@ -56,6 +57,16 @@ static long jfs_map_ext2(unsigned long f
3702  }
3703  
3704  
3705 +int jfs_sync_flags(struct inode *inode, int flags, int vflags)
3706 +{
3707 +       inode->i_flags = flags;
3708 +       inode->i_vflags = vflags;
3709 +       jfs_get_inode_flags(JFS_IP(inode));
3710 +       inode->i_ctime = CURRENT_TIME_SEC;
3711 +       mark_inode_dirty(inode);
3712 +       return 0;
3713 +}
3714 +
3715  long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3716  {
3717         struct inode *inode = file_inode(filp);
3718 @@ -89,6 +100,11 @@ long jfs_ioctl(struct file *filp, unsign
3719                 if (!S_ISDIR(inode->i_mode))
3720                         flags &= ~JFS_DIRSYNC_FL;
3721  
3722 +               if (IS_BARRIER(inode)) {
3723 +                       vxwprintk_task(1, "messing with the barrier.");
3724 +                       return -EACCES;
3725 +               }
3726 +
3727                 /* Is it quota file? Do not allow user to mess with it */
3728                 if (IS_NOQUOTA(inode)) {
3729                         err = -EPERM;
3730 @@ -106,8 +122,8 @@ long jfs_ioctl(struct file *filp, unsign
3731                  * the relevant capability.
3732                  */
3733                 if ((oldflags & JFS_IMMUTABLE_FL) ||
3734 -                       ((flags ^ oldflags) &
3735 -                       (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
3736 +                       ((flags ^ oldflags) & (JFS_APPEND_FL |
3737 +                       JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL))) {
3738                         if (!capable(CAP_LINUX_IMMUTABLE)) {
3739                                 mutex_unlock(&inode->i_mutex);
3740                                 err = -EPERM;
3741 @@ -115,7 +131,7 @@ long jfs_ioctl(struct file *filp, unsign
3742                         }
3743                 }
3744  
3745 -               flags = flags & JFS_FL_USER_MODIFIABLE;
3746 +               flags &= JFS_FL_USER_MODIFIABLE;
3747                 flags |= oldflags & ~JFS_FL_USER_MODIFIABLE;
3748                 jfs_inode->mode2 = flags;
3749  
3750 diff -NurpP --minimal linux-4.1.41/fs/jfs/jfs_dinode.h linux-4.1.41-vs2.3.8.5.3/fs/jfs/jfs_dinode.h
3751 --- linux-4.1.41/fs/jfs/jfs_dinode.h    2015-04-12 22:12:50.000000000 +0000
3752 +++ linux-4.1.41-vs2.3.8.5.3/fs/jfs/jfs_dinode.h        2016-07-05 04:41:47.000000000 +0000
3753 @@ -161,9 +161,13 @@ struct dinode {
3754  
3755  #define JFS_APPEND_FL          0x01000000 /* writes to file may only append */
3756  #define JFS_IMMUTABLE_FL       0x02000000 /* Immutable file */
3757 +#define JFS_IXUNLINK_FL                0x08000000 /* Immutable invert on unlink */
3758  
3759 -#define JFS_FL_USER_VISIBLE    0x03F80000
3760 -#define JFS_FL_USER_MODIFIABLE 0x03F80000
3761 +#define JFS_BARRIER_FL         0x04000000 /* Barrier for chroot() */
3762 +#define JFS_COW_FL             0x20000000 /* Copy on Write marker */
3763 +
3764 +#define JFS_FL_USER_VISIBLE    0x07F80000
3765 +#define JFS_FL_USER_MODIFIABLE 0x07F80000
3766  #define JFS_FL_INHERIT         0x03C80000
3767  
3768  /* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
3769 diff -NurpP --minimal linux-4.1.41/fs/jfs/jfs_filsys.h linux-4.1.41-vs2.3.8.5.3/fs/jfs/jfs_filsys.h
3770 --- linux-4.1.41/fs/jfs/jfs_filsys.h    2015-04-12 22:12:50.000000000 +0000
3771 +++ linux-4.1.41-vs2.3.8.5.3/fs/jfs/jfs_filsys.h        2016-07-05 04:41:47.000000000 +0000
3772 @@ -266,6 +266,7 @@
3773  #define JFS_NAME_MAX   255
3774  #define JFS_PATH_MAX   BPSIZE
3775  
3776 +#define JFS_TAGGED             0x00800000      /* Context Tagging */
3777  
3778  /*
3779   *     file system state (superblock state)
3780 diff -NurpP --minimal linux-4.1.41/fs/jfs/jfs_imap.c linux-4.1.41-vs2.3.8.5.3/fs/jfs/jfs_imap.c
3781 --- linux-4.1.41/fs/jfs/jfs_imap.c      2015-04-12 22:12:50.000000000 +0000
3782 +++ linux-4.1.41-vs2.3.8.5.3/fs/jfs/jfs_imap.c  2016-07-05 04:41:47.000000000 +0000
3783 @@ -46,6 +46,7 @@
3784  #include <linux/pagemap.h>
3785  #include <linux/quotaops.h>
3786  #include <linux/slab.h>
3787 +#include <linux/vs_tag.h>
3788  
3789  #include "jfs_incore.h"
3790  #include "jfs_inode.h"
3791 @@ -3047,6 +3048,8 @@ static int copy_from_dinode(struct dinod
3792  {
3793         struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3794         struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
3795 +       kuid_t kuid;
3796 +       kgid_t kgid;
3797  
3798         jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
3799         jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
3800 @@ -3067,14 +3070,18 @@ static int copy_from_dinode(struct dinod
3801         }
3802         set_nlink(ip, le32_to_cpu(dip->di_nlink));
3803  
3804 -       jfs_ip->saved_uid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
3805 +       kuid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
3806 +       kgid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
3807 +       ip->i_tag = INOTAG_KTAG(DX_TAG(ip), kuid, kgid, GLOBAL_ROOT_TAG);
3808 +
3809 +       jfs_ip->saved_uid = INOTAG_KUID(DX_TAG(ip), kuid, kgid);
3810         if (!uid_valid(sbi->uid))
3811                 ip->i_uid = jfs_ip->saved_uid;
3812         else {
3813                 ip->i_uid = sbi->uid;
3814         }
3815  
3816 -       jfs_ip->saved_gid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
3817 +       jfs_ip->saved_gid = INOTAG_KGID(DX_TAG(ip), kuid, kgid);
3818         if (!gid_valid(sbi->gid))
3819                 ip->i_gid = jfs_ip->saved_gid;
3820         else {
3821 @@ -3139,16 +3146,14 @@ static void copy_to_dinode(struct dinode
3822         dip->di_size = cpu_to_le64(ip->i_size);
3823         dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
3824         dip->di_nlink = cpu_to_le32(ip->i_nlink);
3825 -       if (!uid_valid(sbi->uid))
3826 -               dip->di_uid = cpu_to_le32(i_uid_read(ip));
3827 -       else
3828 -               dip->di_uid =cpu_to_le32(from_kuid(&init_user_ns,
3829 -                                                  jfs_ip->saved_uid));
3830 -       if (!gid_valid(sbi->gid))
3831 -               dip->di_gid = cpu_to_le32(i_gid_read(ip));
3832 -       else
3833 -               dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3834 -                                                   jfs_ip->saved_gid));
3835 +       dip->di_uid = cpu_to_le32(from_kuid(&init_user_ns,
3836 +               TAGINO_KUID(DX_TAG(ip),
3837 +               !uid_valid(sbi->uid) ? ip->i_uid : jfs_ip->saved_uid,
3838 +               ip->i_tag)));
3839 +       dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3840 +               TAGINO_KGID(DX_TAG(ip),
3841 +               !gid_valid(sbi->gid) ? ip->i_gid : jfs_ip->saved_gid,
3842 +               ip->i_tag)));
3843         jfs_get_inode_flags(jfs_ip);
3844         /*
3845          * mode2 is only needed for storing the higher order bits.
3846 diff -NurpP --minimal linux-4.1.41/fs/jfs/jfs_inode.c linux-4.1.41-vs2.3.8.5.3/fs/jfs/jfs_inode.c
3847 --- linux-4.1.41/fs/jfs/jfs_inode.c     2015-04-12 22:12:50.000000000 +0000
3848 +++ linux-4.1.41-vs2.3.8.5.3/fs/jfs/jfs_inode.c 2016-07-05 04:41:47.000000000 +0000
3849 @@ -18,6 +18,7 @@
3850  
3851  #include <linux/fs.h>
3852  #include <linux/quotaops.h>
3853 +#include <linux/vs_tag.h>
3854  #include "jfs_incore.h"
3855  #include "jfs_inode.h"
3856  #include "jfs_filsys.h"
3857 @@ -33,26 +34,45 @@ void jfs_set_inode_flags(struct inode *i
3858  
3859         if (flags & JFS_IMMUTABLE_FL)
3860                 new_fl |= S_IMMUTABLE;
3861 +       if (flags & JFS_IXUNLINK_FL)
3862 +               inode->i_flags |= S_IXUNLINK;
3863 +
3864 +       if (flags & JFS_SYNC_FL)
3865 +               inode->i_flags |= S_SYNC;
3866         if (flags & JFS_APPEND_FL)
3867                 new_fl |= S_APPEND;
3868         if (flags & JFS_NOATIME_FL)
3869                 new_fl |= S_NOATIME;
3870         if (flags & JFS_DIRSYNC_FL)
3871                 new_fl |= S_DIRSYNC;
3872 -       if (flags & JFS_SYNC_FL)
3873 -               new_fl |= S_SYNC;
3874 -       inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND | S_NOATIME |
3875 +       inode_set_flags(inode, new_fl, S_IMMUTABLE | S_IXUNLINK | S_APPEND | S_NOATIME |
3876                         S_DIRSYNC | S_SYNC);
3877 +
3878 +       new_fl = 0;
3879 +       if (flags & JFS_BARRIER_FL)
3880 +               new_fl |= V_BARRIER;
3881 +       if (flags & JFS_COW_FL)
3882 +               new_fl |= V_COW;
3883 +
3884 +       set_mask_bits(&inode->i_vflags,
3885 +               V_BARRIER | V_COW, new_fl);
3886  }
3887  
3888  void jfs_get_inode_flags(struct jfs_inode_info *jfs_ip)
3889  {
3890         unsigned int flags = jfs_ip->vfs_inode.i_flags;
3891 +       unsigned int vflags = jfs_ip->vfs_inode.i_vflags;
3892 +
3893 +       jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL |
3894 +                          JFS_APPEND_FL | JFS_NOATIME_FL |
3895 +                          JFS_DIRSYNC_FL | JFS_SYNC_FL |
3896 +                          JFS_BARRIER_FL | JFS_COW_FL);
3897  
3898 -       jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_APPEND_FL | JFS_NOATIME_FL |
3899 -                          JFS_DIRSYNC_FL | JFS_SYNC_FL);
3900         if (flags & S_IMMUTABLE)
3901                 jfs_ip->mode2 |= JFS_IMMUTABLE_FL;
3902 +       if (flags & S_IXUNLINK)
3903 +               jfs_ip->mode2 |= JFS_IXUNLINK_FL;
3904 +
3905         if (flags & S_APPEND)
3906                 jfs_ip->mode2 |= JFS_APPEND_FL;
3907         if (flags & S_NOATIME)
3908 @@ -61,6 +81,11 @@ void jfs_get_inode_flags(struct jfs_inod
3909                 jfs_ip->mode2 |= JFS_DIRSYNC_FL;
3910         if (flags & S_SYNC)
3911                 jfs_ip->mode2 |= JFS_SYNC_FL;
3912 +
3913 +       if (vflags & V_BARRIER)
3914 +               jfs_ip->mode2 |= JFS_BARRIER_FL;
3915 +       if (vflags & V_COW)
3916 +               jfs_ip->mode2 |= JFS_COW_FL;
3917  }
3918  
3919  /*
3920 diff -NurpP --minimal linux-4.1.41/fs/jfs/jfs_inode.h linux-4.1.41-vs2.3.8.5.3/fs/jfs/jfs_inode.h
3921 --- linux-4.1.41/fs/jfs/jfs_inode.h     2015-04-12 22:12:50.000000000 +0000
3922 +++ linux-4.1.41-vs2.3.8.5.3/fs/jfs/jfs_inode.h 2016-07-05 04:41:47.000000000 +0000
3923 @@ -39,6 +39,7 @@ extern struct dentry *jfs_fh_to_dentry(s
3924  extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
3925         int fh_len, int fh_type);
3926  extern void jfs_set_inode_flags(struct inode *);
3927 +extern int jfs_sync_flags(struct inode *, int, int);
3928  extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
3929  extern int jfs_setattr(struct dentry *, struct iattr *);
3930  
3931 diff -NurpP --minimal linux-4.1.41/fs/jfs/namei.c linux-4.1.41-vs2.3.8.5.3/fs/jfs/namei.c
3932 --- linux-4.1.41/fs/jfs/namei.c 2015-07-06 20:41:42.000000000 +0000
3933 +++ linux-4.1.41-vs2.3.8.5.3/fs/jfs/namei.c     2016-07-05 04:41:47.000000000 +0000
3934 @@ -22,6 +22,7 @@
3935  #include <linux/ctype.h>
3936  #include <linux/quotaops.h>
3937  #include <linux/exportfs.h>
3938 +#include <linux/vs_tag.h>
3939  #include "jfs_incore.h"
3940  #include "jfs_superblock.h"
3941  #include "jfs_inode.h"
3942 @@ -1459,6 +1460,7 @@ static struct dentry *jfs_lookup(struct
3943                         jfs_err("jfs_lookup: iget failed on inum %d", (uint)inum);
3944         }
3945  
3946 +       dx_propagate_tag(nd, ip);
3947         return d_splice_alias(ip, dentry);
3948  }
3949  
3950 @@ -1524,6 +1526,7 @@ const struct inode_operations jfs_dir_in
3951         .get_acl        = jfs_get_acl,
3952         .set_acl        = jfs_set_acl,
3953  #endif
3954 +       .sync_flags     = jfs_sync_flags,
3955  };
3956  
3957  const struct file_operations jfs_dir_operations = {
3958 diff -NurpP --minimal linux-4.1.41/fs/jfs/super.c linux-4.1.41-vs2.3.8.5.3/fs/jfs/super.c
3959 --- linux-4.1.41/fs/jfs/super.c 2015-07-06 20:41:42.000000000 +0000
3960 +++ linux-4.1.41-vs2.3.8.5.3/fs/jfs/super.c     2016-07-05 04:41:47.000000000 +0000
3961 @@ -206,7 +206,8 @@ enum {
3962         Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
3963         Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
3964         Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask,
3965 -       Opt_discard, Opt_nodiscard, Opt_discard_minblk
3966 +       Opt_discard, Opt_nodiscard, Opt_discard_minblk,
3967 +       Opt_tag, Opt_notag, Opt_tagid
3968  };
3969  
3970  static const match_table_t tokens = {
3971 @@ -216,6 +217,10 @@ static const match_table_t tokens = {
3972         {Opt_resize, "resize=%u"},
3973         {Opt_resize_nosize, "resize"},
3974         {Opt_errors, "errors=%s"},
3975 +       {Opt_tag, "tag"},
3976 +       {Opt_notag, "notag"},
3977 +       {Opt_tagid, "tagid=%u"},
3978 +       {Opt_tag, "tagxid"},
3979         {Opt_ignore, "noquota"},
3980         {Opt_ignore, "quota"},
3981         {Opt_usrquota, "usrquota"},
3982 @@ -405,7 +410,20 @@ static int parse_options(char *options,
3983                                 pr_err("JFS: discard option not supported on device\n");
3984                         break;
3985                 }
3986 -
3987 +#ifndef CONFIG_TAGGING_NONE
3988 +               case Opt_tag:
3989 +                       *flag |= JFS_TAGGED;
3990 +                       break;
3991 +               case Opt_notag:
3992 +                       *flag &= JFS_TAGGED;
3993 +                       break;
3994 +#endif
3995 +#ifdef CONFIG_PROPAGATE
3996 +               case Opt_tagid:
3997 +                       /* use args[0] */
3998 +                       *flag |= JFS_TAGGED;
3999 +                       break;
4000 +#endif
4001                 default:
4002                         printk("jfs: Unrecognized mount option \"%s\" or missing value\n",
4003                                p);
4004 @@ -437,6 +455,12 @@ static int jfs_remount(struct super_bloc
4005         if (!parse_options(data, sb, &newLVSize, &flag))
4006                 return -EINVAL;
4007  
4008 +       if ((flag & JFS_TAGGED) && !(sb->s_flags & MS_TAGGED)) {
4009 +               printk(KERN_ERR "JFS: %s: tagging not permitted on remount.\n",
4010 +                       sb->s_id);
4011 +               return -EINVAL;
4012 +       }
4013 +
4014         if (newLVSize) {
4015                 if (sb->s_flags & MS_RDONLY) {
4016                         pr_err("JFS: resize requires volume to be mounted read-write\n");
4017 @@ -520,6 +544,9 @@ static int jfs_fill_super(struct super_b
4018  #ifdef CONFIG_JFS_POSIX_ACL
4019         sb->s_flags |= MS_POSIXACL;
4020  #endif
4021 +       /* map mount option tagxid */
4022 +       if (sbi->flag & JFS_TAGGED)
4023 +               sb->s_flags |= MS_TAGGED;
4024  
4025         if (newLVSize) {
4026                 pr_err("resize option for remount only\n");
4027 diff -NurpP --minimal linux-4.1.41/fs/libfs.c linux-4.1.41-vs2.3.8.5.3/fs/libfs.c
4028 --- linux-4.1.41/fs/libfs.c     2017-06-23 10:03:59.000000000 +0000
4029 +++ linux-4.1.41-vs2.3.8.5.3/fs/libfs.c 2017-05-30 07:39:23.000000000 +0000
4030 @@ -146,13 +146,14 @@ static inline unsigned char dt_type(stru
4031   * both impossible due to the lock on directory.
4032   */
4033  
4034 -int dcache_readdir(struct file *file, struct dir_context *ctx)
4035 +static inline int do_dcache_readdir_filter(struct file *filp,
4036 +       struct dir_context *ctx, int (*filter)(struct dentry *dentry))
4037  {
4038 -       struct dentry *dentry = file->f_path.dentry;
4039 -       struct dentry *cursor = file->private_data;
4040 +       struct dentry *dentry = filp->f_path.dentry;
4041 +       struct dentry *cursor = filp->private_data;
4042         struct list_head *p, *q = &cursor->d_child;
4043  
4044 -       if (!dir_emit_dots(file, ctx))
4045 +       if (!dir_emit_dots(filp, ctx))
4046                 return 0;
4047         spin_lock(&dentry->d_lock);
4048         if (ctx->pos == 2)
4049 @@ -160,6 +161,8 @@ int dcache_readdir(struct file *file, st
4050  
4051         for (p = q->next; p != &dentry->d_subdirs; p = p->next) {
4052                 struct dentry *next = list_entry(p, struct dentry, d_child);
4053 +               if (filter && !filter(next))
4054 +                       continue;
4055                 spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
4056                 if (!simple_positive(next)) {
4057                         spin_unlock(&next->d_lock);
4058 @@ -182,8 +185,22 @@ int dcache_readdir(struct file *file, st
4059         spin_unlock(&dentry->d_lock);
4060         return 0;
4061  }
4062 +
4063  EXPORT_SYMBOL(dcache_readdir);
4064  
4065 +int dcache_readdir(struct file *filp, struct dir_context *ctx)
4066 +{
4067 +       return do_dcache_readdir_filter(filp, ctx, NULL);
4068 +}
4069 +
4070 +EXPORT_SYMBOL(dcache_readdir_filter);
4071 +
4072 +int dcache_readdir_filter(struct file *filp, struct dir_context *ctx,
4073 +       int (*filter)(struct dentry *))
4074 +{
4075 +       return do_dcache_readdir_filter(filp, ctx, filter);
4076 +}
4077 +
4078  ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
4079  {
4080         return -EISDIR;
4081 diff -NurpP --minimal linux-4.1.41/fs/locks.c linux-4.1.41-vs2.3.8.5.3/fs/locks.c
4082 --- linux-4.1.41/fs/locks.c     2017-06-23 10:03:59.000000000 +0000
4083 +++ linux-4.1.41-vs2.3.8.5.3/fs/locks.c 2016-10-25 21:31:19.000000000 +0000
4084 @@ -129,6 +129,8 @@
4085  #include <linux/hashtable.h>
4086  #include <linux/percpu.h>
4087  #include <linux/lglock.h>
4088 +#include <linux/vs_base.h>
4089 +#include <linux/vs_limit.h>
4090  
4091  #define CREATE_TRACE_POINTS
4092  #include <trace/events/filelock.h>
4093 @@ -251,11 +253,15 @@ static void locks_init_lock_heads(struct
4094  /* Allocate an empty lock structure. */
4095  struct file_lock *locks_alloc_lock(void)
4096  {
4097 -       struct file_lock *fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
4098 +       struct file_lock *fl;
4099  
4100 -       if (fl)
4101 -               locks_init_lock_heads(fl);
4102 +       fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
4103  
4104 +       if (fl) {
4105 +               locks_init_lock_heads(fl);
4106 +               vx_locks_inc(fl);
4107 +               fl->fl_xid = -1;
4108 +       }
4109         return fl;
4110  }
4111  EXPORT_SYMBOL_GPL(locks_alloc_lock);
4112 @@ -307,6 +313,7 @@ void locks_init_lock(struct file_lock *f
4113  {
4114         memset(fl, 0, sizeof(struct file_lock));
4115         locks_init_lock_heads(fl);
4116 +       fl->fl_xid = -1;
4117  }
4118  
4119  EXPORT_SYMBOL(locks_init_lock);
4120 @@ -324,6 +331,7 @@ void locks_copy_conflock(struct file_loc
4121         new->fl_start = fl->fl_start;
4122         new->fl_end = fl->fl_end;
4123         new->fl_lmops = fl->fl_lmops;
4124 +       new->fl_xid = fl->fl_xid;
4125         new->fl_ops = NULL;
4126  
4127         if (fl->fl_lmops) {
4128 @@ -385,7 +393,10 @@ flock_make_lock(struct file *filp, unsig
4129         fl->fl_flags = FL_FLOCK;
4130         fl->fl_type = type;
4131         fl->fl_end = OFFSET_MAX;
4132 -       
4133 +
4134 +       vxd_assert(filp->f_xid == vx_current_xid(),
4135 +               "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
4136 +       fl->fl_xid = filp->f_xid;
4137         return fl;
4138  }
4139  
4140 @@ -507,6 +518,7 @@ static int lease_init(struct file *filp,
4141  
4142         fl->fl_owner = filp;
4143         fl->fl_pid = current->tgid;
4144 +       fl->fl_xid = vx_current_xid();
4145  
4146         fl->fl_file = filp;
4147         fl->fl_flags = FL_LEASE;
4148 @@ -526,6 +538,10 @@ static struct file_lock *lease_alloc(str
4149         if (fl == NULL)
4150                 return ERR_PTR(error);
4151  
4152 +       fl->fl_xid = vx_current_xid();
4153 +       if (filp)
4154 +               vxd_assert(filp->f_xid == fl->fl_xid,
4155 +                       "f_xid(%d) == fl_xid(%d)", filp->f_xid, fl->fl_xid);
4156         error = lease_init(filp, type, fl);
4157         if (error) {
4158                 locks_free_lock(fl);
4159 @@ -904,6 +920,7 @@ static int flock_lock_inode(struct inode
4160                 goto out;
4161         }
4162  
4163 +       new_fl->fl_xid = -1;
4164  find_conflict:
4165         list_for_each_entry(fl, &ctx->flc_flock, fl_list) {
4166                 if (!flock_locks_conflict(request, fl))
4167 @@ -930,7 +947,8 @@ out:
4168         return error;
4169  }
4170  
4171 -static int __posix_lock_file(struct inode *inode, struct file_lock *request, struct file_lock *conflock)
4172 +static int __posix_lock_file(struct inode *inode, struct file_lock *request,
4173 +       struct file_lock *conflock, vxid_t xid)
4174  {
4175         struct file_lock *fl, *tmp;
4176         struct file_lock *new_fl = NULL;
4177 @@ -946,6 +964,9 @@ static int __posix_lock_file(struct inod
4178         if (!ctx)
4179                 return (request->fl_type == F_UNLCK) ? 0 : -ENOMEM;
4180  
4181 +       if (xid)
4182 +               vxd_assert(xid == vx_current_xid(),
4183 +                       "xid(%d) == current(%d)", xid, vx_current_xid());
4184         /*
4185          * We may need two file_lock structures for this operation,
4186          * so we get them in advance to avoid races.
4187 @@ -956,7 +977,11 @@ static int __posix_lock_file(struct inod
4188             (request->fl_type != F_UNLCK ||
4189              request->fl_start != 0 || request->fl_end != OFFSET_MAX)) {
4190                 new_fl = locks_alloc_lock();
4191 +               new_fl->fl_xid = xid;
4192 +               // vx_locks_inc(new_fl);
4193                 new_fl2 = locks_alloc_lock();
4194 +               new_fl2->fl_xid = xid;
4195 +               // vx_locks_inc(new_fl2);
4196         }
4197  
4198         spin_lock(&ctx->flc_lock);
4199 @@ -1158,7 +1183,8 @@ static int __posix_lock_file(struct inod
4200  int posix_lock_file(struct file *filp, struct file_lock *fl,
4201                         struct file_lock *conflock)
4202  {
4203 -       return __posix_lock_file(file_inode(filp), fl, conflock);
4204 +       return __posix_lock_file(file_inode(filp),
4205 +               fl, conflock, filp->f_xid);
4206  }
4207  EXPORT_SYMBOL(posix_lock_file);
4208  
4209 @@ -1175,7 +1201,7 @@ int posix_lock_inode_wait(struct inode *
4210         int error;
4211         might_sleep ();
4212         for (;;) {
4213 -               error = __posix_lock_file(inode, fl, NULL);
4214 +               error = __posix_lock_file(inode, fl, NULL, 0);
4215                 if (error != FILE_LOCK_DEFERRED)
4216                         break;
4217                 error = wait_event_interruptible(fl->fl_wait, !fl->fl_next);
4218 @@ -1255,10 +1281,13 @@ int locks_mandatory_area(int read_write,
4219         fl.fl_end = offset + count - 1;
4220  
4221         for (;;) {
4222 +               vxid_t f_xid = 0;
4223 +
4224                 if (filp) {
4225                         fl.fl_owner = filp;
4226                         fl.fl_flags &= ~FL_SLEEP;
4227 -                       error = __posix_lock_file(inode, &fl, NULL);
4228 +                       f_xid = filp->f_xid;
4229 +                       error = __posix_lock_file(inode, &fl, NULL, f_xid);
4230                         if (!error)
4231                                 break;
4232                 }
4233 @@ -1266,7 +1295,7 @@ int locks_mandatory_area(int read_write,
4234                 if (sleep)
4235                         fl.fl_flags |= FL_SLEEP;
4236                 fl.fl_owner = current->files;
4237 -               error = __posix_lock_file(inode, &fl, NULL);
4238 +               error = __posix_lock_file(inode, &fl, NULL, f_xid);
4239                 if (error != FILE_LOCK_DEFERRED)
4240                         break;
4241                 error = wait_event_interruptible(fl.fl_wait, !fl.fl_next);
4242 @@ -2137,6 +2166,11 @@ int fcntl_setlk(unsigned int fd, struct
4243         if (file_lock == NULL)
4244                 return -ENOLCK;
4245  
4246 +       vxd_assert(filp->f_xid == vx_current_xid(),
4247 +               "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
4248 +       file_lock->fl_xid = filp->f_xid;
4249 +       // vx_locks_inc(file_lock);
4250 +
4251         /*
4252          * This might block, so we do it before checking the inode.
4253          */
4254 @@ -2279,6 +2313,11 @@ int fcntl_setlk64(unsigned int fd, struc
4255         if (file_lock == NULL)
4256                 return -ENOLCK;
4257  
4258 +       vxd_assert(filp->f_xid == vx_current_xid(),
4259 +               "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
4260 +       file_lock->fl_xid = filp->f_xid;
4261 +       // vx_locks_inc(file_lock);
4262 +
4263         /*
4264          * This might block, so we do it before checking the inode.
4265          */
4266 @@ -2591,8 +2630,11 @@ static int locks_show(struct seq_file *f
4267  
4268         lock_get_status(f, fl, iter->li_pos, "");
4269  
4270 -       list_for_each_entry(bfl, &fl->fl_block, fl_block)
4271 +       list_for_each_entry(bfl, &fl->fl_block, fl_block) {
4272 +               if (!vx_check(fl->fl_xid, VS_WATCH_P | VS_IDENT))
4273 +                       continue;
4274                 lock_get_status(f, bfl, iter->li_pos, " ->");
4275 +       }
4276  
4277         return 0;
4278  }
4279 diff -NurpP --minimal linux-4.1.41/fs/mount.h linux-4.1.41-vs2.3.8.5.3/fs/mount.h
4280 --- linux-4.1.41/fs/mount.h     2017-06-23 10:03:59.000000000 +0000
4281 +++ linux-4.1.41-vs2.3.8.5.3/fs/mount.h 2017-05-30 07:39:23.000000000 +0000
4282 @@ -67,6 +67,7 @@ struct mount {
4283         struct hlist_head mnt_pins;
4284         struct fs_pin mnt_umount;
4285         struct dentry *mnt_ex_mountpoint;
4286 +       vtag_t mnt_tag;                 /* tagging used for vfsmount */
4287  };
4288  
4289  #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
4290 diff -NurpP --minimal linux-4.1.41/fs/namei.c linux-4.1.41-vs2.3.8.5.3/fs/namei.c
4291 --- linux-4.1.41/fs/namei.c     2017-06-23 10:03:59.000000000 +0000
4292 +++ linux-4.1.41-vs2.3.8.5.3/fs/namei.c 2016-07-05 04:41:47.000000000 +0000
4293 @@ -34,10 +34,20 @@
4294  #include <linux/device_cgroup.h>
4295  #include <linux/fs_struct.h>
4296  #include <linux/posix_acl.h>
4297 +#include <linux/proc_fs.h>
4298 +#include <linux/magic.h>
4299 +#include <linux/vserver/inode.h>
4300 +#include <linux/vs_base.h>
4301 +#include <linux/vs_tag.h>
4302 +#include <linux/vs_cowbl.h>
4303 +#include <linux/vs_device.h>
4304 +#include <linux/vs_context.h>
4305 +#include <linux/pid_namespace.h>
4306  #include <linux/hash.h>
4307  #include <asm/uaccess.h>
4308  
4309  #include "internal.h"
4310 +#include "proc/internal.h"
4311  #include "mount.h"
4312  
4313  /* [Feb-1997 T. Schoebel-Theuer]
4314 @@ -283,6 +293,93 @@ static int check_acl(struct inode *inode
4315         return -EAGAIN;
4316  }
4317  
4318 +static inline int dx_barrier(const struct inode *inode)
4319 +{
4320 +       if (IS_BARRIER(inode) && !vx_check(0, VS_ADMIN | VS_WATCH)) {
4321 +               vxwprintk_task(1, "did hit the barrier.");
4322 +               return 1;
4323 +       }
4324 +       return 0;
4325 +}
4326 +
4327 +static int __dx_permission(const struct inode *inode, int mask)
4328 +{
4329 +       if (dx_barrier(inode))
4330 +               return -EACCES;
4331 +
4332 +       if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) {
4333 +               /* devpts is xid tagged */
4334 +               if (S_ISDIR(inode->i_mode) ||
4335 +                   vx_check((vxid_t)i_tag_read(inode), VS_IDENT | VS_WATCH_P))
4336 +                       return 0;
4337 +
4338 +               /* just pretend we didn't find anything */
4339 +               return -ENOENT;
4340 +       }
4341 +       else if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) {
4342 +               struct proc_dir_entry *de = PDE(inode);
4343 +
4344 +               if (de && !vx_hide_check(0, de->vx_flags)) {
4345 +                       vxdprintk(VXD_CBIT(misc, 9),
4346 +                               VS_Q("%*s") " hidden by _dx_permission",
4347 +                               de->namelen, de->name);
4348 +                       goto out;
4349 +               }
4350 +
4351 +               if ((mask & (MAY_WRITE | MAY_APPEND))) {
4352 +                       struct pid *pid;
4353 +                       struct task_struct *tsk;
4354 +
4355 +                       if (vx_check(0, VS_ADMIN | VS_WATCH_P) ||
4356 +                           vx_flags(VXF_STATE_SETUP, 0))
4357 +                               return 0;
4358 +
4359 +                       pid = PROC_I(inode)->pid;
4360 +                       if (!pid)
4361 +                               goto out;
4362 +
4363 +                       rcu_read_lock();
4364 +                       tsk = pid_task(pid, PIDTYPE_PID);
4365 +                       vxdprintk(VXD_CBIT(tag, 0), "accessing %p[#%u]",
4366 +                                 tsk, (tsk ? vx_task_xid(tsk) : 0));
4367 +                       if (tsk &&
4368 +                               vx_check(vx_task_xid(tsk), VS_IDENT | VS_WATCH_P)) {
4369 +                               rcu_read_unlock();
4370 +                               return 0;
4371 +                       }
4372 +                       rcu_read_unlock();
4373 +               }
4374 +               else {
4375 +                       /* FIXME: Should we block some entries here? */
4376 +                       return 0;
4377 +               }
4378 +       }
4379 +       else {
4380 +               if (dx_notagcheck(inode->i_sb) ||
4381 +                   dx_check((vxid_t)i_tag_read(inode),
4382 +                       DX_HOSTID | DX_ADMIN | DX_WATCH | DX_IDENT))
4383 +                       return 0;
4384 +       }
4385 +
4386 +out:
4387 +       return -EACCES;
4388 +}
4389 +
4390 +int dx_permission(const struct inode *inode, int mask)
4391 +{
4392 +       int ret = __dx_permission(inode, mask);
4393 +       if (unlikely(ret)) {
4394 +#ifndef        CONFIG_VSERVER_WARN_DEVPTS
4395 +               if (inode->i_sb->s_magic != DEVPTS_SUPER_MAGIC)
4396 +#endif
4397 +                   vxwprintk_task(1,
4398 +                       "denied [0x%x] access to inode %s:%p[#%d,%lu]",
4399 +                       mask, inode->i_sb->s_id, inode,
4400 +                       i_tag_read(inode), inode->i_ino);
4401 +       }
4402 +       return ret;
4403 +}
4404 +
4405  /*
4406   * This does the basic permission checking
4407   */
4408 @@ -407,10 +504,14 @@ int __inode_permission(struct inode *ino
4409                 /*
4410                  * Nobody gets write access to an immutable file.
4411                  */
4412 -               if (IS_IMMUTABLE(inode))
4413 +               if (IS_IMMUTABLE(inode) && !IS_COW(inode))
4414                         return -EACCES;
4415         }
4416  
4417 +       retval = dx_permission(inode, mask);
4418 +       if (retval)
4419 +               return retval;
4420 +
4421         retval = do_inode_permission(inode, mask);
4422         if (retval)
4423                 return retval;
4424 @@ -1479,6 +1580,9 @@ static int lookup_fast(struct nameidata
4425                  */
4426                 if (negative)
4427                         return -ENOENT;
4428 +
4429 +               /* FIXME: check dx permission */
4430 +
4431                 path->mnt = mnt;
4432                 path->dentry = dentry;
4433                 if (likely(__follow_mount_rcu(nd, path, inode)))
4434 @@ -1509,6 +1613,8 @@ unlazy:
4435                 dput(dentry);
4436                 return -ENOENT;
4437         }
4438 +
4439 +       /* FIXME: check dx permission */
4440         path->mnt = mnt;
4441         path->dentry = dentry;
4442         err = follow_managed(path, nd->flags);
4443 @@ -2502,7 +2608,7 @@ static int may_delete(struct inode *dir,
4444                 return -EPERM;
4445  
4446         if (check_sticky(dir, inode) || IS_APPEND(inode) ||
4447 -           IS_IMMUTABLE(inode) || IS_SWAPFILE(inode))
4448 +               IS_IXORUNLINK(inode) || IS_SWAPFILE(inode))
4449                 return -EPERM;
4450         if (isdir) {
4451                 if (!d_is_dir(victim))
4452 @@ -2584,19 +2690,25 @@ int vfs_create(struct inode *dir, struct
4453                 bool want_excl)
4454  {
4455         int error = may_create(dir, dentry);
4456 -       if (error)
4457 +       if (error) {
4458 +               vxdprintk(VXD_CBIT(misc, 3), "may_create failed with %d", error);
4459                 return error;
4460 +       }
4461  
4462         if (!dir->i_op->create)
4463                 return -EACCES; /* shouldn't it be ENOSYS? */
4464         mode &= S_IALLUGO;
4465         mode |= S_IFREG;
4466         error = security_inode_create(dir, dentry, mode);
4467 -       if (error)
4468 +       if (error) {
4469 +               vxdprintk(VXD_CBIT(misc, 3), "security_inode_create failed with %d", error);
4470                 return error;
4471 +       }
4472         error = dir->i_op->create(dir, dentry, mode, want_excl);
4473         if (!error)
4474                 fsnotify_create(dir, dentry);
4475 +       else
4476 +               vxdprintk(VXD_CBIT(misc, 3), "i_op->create failed with %d", error);
4477         return error;
4478  }
4479  EXPORT_SYMBOL(vfs_create);
4480 @@ -2632,6 +2744,15 @@ static int may_open(struct path *path, i
4481                 break;
4482         }
4483  
4484 +#ifdef CONFIG_VSERVER_COWBL
4485 +       if (IS_COW(inode) &&
4486 +               ((flag & O_ACCMODE) != O_RDONLY)) {
4487 +               if (IS_COW_LINK(inode))
4488 +                       return -EMLINK;
4489 +               inode->i_flags &= ~(S_IXUNLINK|S_IMMUTABLE);
4490 +               mark_inode_dirty(inode);
4491 +       }
4492 +#endif
4493         error = inode_permission(inode, acc_mode);
4494         if (error)
4495                 return error;
4496 @@ -3115,6 +3236,16 @@ finish_open:
4497         }
4498  finish_open_created:
4499         error = may_open(&nd->path, acc_mode, open_flag);
4500 +#ifdef CONFIG_VSERVER_COWBL
4501 +       if (error == -EMLINK) {
4502 +               struct dentry *dentry;
4503 +               dentry = cow_break_link(name->name);
4504 +               if (IS_ERR(dentry))
4505 +                       error = PTR_ERR(dentry);
4506 +               else
4507 +                       dput(dentry);
4508 +       }
4509 +#endif
4510         if (error)
4511                 goto out;
4512  
4513 @@ -3247,6 +3378,9 @@ static struct file *path_openat(int dfd,
4514         int opened = 0;
4515         int error;
4516  
4517 +#ifdef CONFIG_VSERVER_COWBL
4518 +restart:
4519 +#endif
4520         file = get_empty_filp();
4521         if (IS_ERR(file))
4522                 return file;
4523 @@ -3283,6 +3417,13 @@ static struct file *path_openat(int dfd,
4524                 error = do_last(nd, &path, file, op, &opened, pathname);
4525                 put_link(nd, &link, cookie);
4526         }
4527 +
4528 +#ifdef CONFIG_VSERVER_COWBL
4529 +       if (error == -EMLINK) {
4530 +               path_cleanup(nd);
4531 +               goto restart;
4532 +       }
4533 +#endif
4534  out:
4535         path_cleanup(nd);
4536  out2:
4537 @@ -3401,6 +3542,11 @@ static struct dentry *filename_create(in
4538                 goto fail;
4539         }
4540         *path = nd.path;
4541 +       vxdprintk(VXD_CBIT(misc, 3), "kern_path_create path.dentry = %p (%.*s), dentry = %p (%.*s), d_inode = %p",
4542 +               path->dentry, path->dentry->d_name.len,
4543 +               path->dentry->d_name.name, dentry,
4544 +               dentry->d_name.len, dentry->d_name.name,
4545 +               path->dentry->d_inode);
4546         return dentry;
4547  fail:
4548         dput(dentry);
4549 @@ -3970,7 +4116,7 @@ int vfs_link(struct dentry *old_dentry,
4550         /*
4551          * A link to an append-only or immutable file cannot be created.
4552          */
4553 -       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
4554 +       if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
4555                 return -EPERM;
4556         if (!dir->i_op->link)
4557                 return -EPERM;
4558 @@ -4475,6 +4621,295 @@ int generic_readlink(struct dentry *dent
4559  }
4560  EXPORT_SYMBOL(generic_readlink);
4561  
4562 +
4563 +#ifdef CONFIG_VSERVER_COWBL
4564 +
4565 +static inline
4566 +long do_cow_splice(struct file *in, struct file *out, size_t len)
4567 +{
4568 +       loff_t ppos = 0;
4569 +       loff_t opos = 0;
4570 +
4571 +       return do_splice_direct(in, &ppos, out, &opos, len, 0);
4572 +}
4573 +
4574 +struct dentry *cow_break_link(const char *pathname)
4575 +{
4576 +       int ret, mode, pathlen, redo = 0, drop = 1;
4577 +       struct nameidata old_nd, dir_nd;
4578 +       struct path dir_path, *old_path, *new_path;
4579 +       struct dentry *dir, *old_dentry, *new_dentry = NULL;
4580 +       struct file *old_file;
4581 +       struct file *new_file;
4582 +       char *to, *path, pad='\251';
4583 +       loff_t size;
4584 +       struct filename *filename = getname_kernel(pathname);
4585 +       struct filename *to_filename;
4586 +
4587 +       vxdprintk(VXD_CBIT(misc, 1),
4588 +               "cow_break_link(" VS_Q("%s") ")", pathname);
4589 +
4590 +       path = kmalloc(PATH_MAX, GFP_KERNEL);
4591 +       ret = -ENOMEM;
4592 +       if (!path || IS_ERR(filename))
4593 +               goto out;
4594 +
4595 +       /* old_nd.path will have refs to dentry and mnt */
4596 +       ret = filename_lookup(AT_FDCWD, filename, LOOKUP_FOLLOW, &old_nd);
4597 +       vxdprintk(VXD_CBIT(misc, 2),
4598 +               "do_path_lookup(old): %d", ret);
4599 +       if (ret < 0)
4600 +               goto out_free_path;
4601 +
4602 +       /* dentry/mnt refs handed over to old_path */
4603 +       old_path = &old_nd.path;
4604 +       /* no explicit reference for old_dentry here */
4605 +       old_dentry = old_path->dentry;
4606 +
4607 +       mode = old_dentry->d_inode->i_mode;
4608 +       to = d_path(old_path, path, PATH_MAX-2);
4609 +       pathlen = strlen(to);
4610 +       vxdprintk(VXD_CBIT(misc, 2),
4611 +               "old path " VS_Q("%s") " [%p:" VS_Q("%.*s") ":%d]", to,
4612 +               old_dentry,
4613 +               old_dentry->d_name.len, old_dentry->d_name.name,
4614 +               old_dentry->d_name.len);
4615 +
4616 +       to[pathlen + 1] = 0;
4617 +retry:
4618 +       new_dentry = NULL;
4619 +       to[pathlen] = pad--;
4620 +       ret = -ELOOP;
4621 +       if (pad <= '\240')
4622 +               goto out_rel_old;
4623 +
4624 +       vxdprintk(VXD_CBIT(misc, 1), "temp copy " VS_Q("%s"), to);
4625 +
4626 +       /* dir_nd.path will have refs to dentry and mnt */
4627 +       to_filename = getname_kernel(to);
4628 +       ret = filename_lookup(AT_FDCWD, to_filename,
4629 +               LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE, &dir_nd);
4630 +       putname(to_filename);
4631 +       vxdprintk(VXD_CBIT(misc, 2), "do_path_lookup(new): %d", ret);
4632 +       if (ret < 0)
4633 +               goto retry;
4634 +
4635 +       /* this puppy downs the dir inode mutex if successful.
4636 +          dir_path will hold refs to dentry and mnt and
4637 +          we'll have write access to the mnt */
4638 +       new_dentry = kern_path_create(AT_FDCWD, to, &dir_path, 0);
4639 +       if (!new_dentry || IS_ERR(new_dentry)) {
4640 +               path_put(&dir_nd.path);
4641 +               vxdprintk(VXD_CBIT(misc, 2),
4642 +                       "kern_path_create(new) failed with %ld",
4643 +                       PTR_ERR(new_dentry));
4644 +               goto retry;
4645 +       }
4646 +       vxdprintk(VXD_CBIT(misc, 2),
4647 +               "kern_path_create(new): %p [" VS_Q("%.*s") ":%d]",
4648 +               new_dentry,
4649 +               new_dentry->d_name.len, new_dentry->d_name.name,
4650 +               new_dentry->d_name.len);
4651 +
4652 +       /* take a reference on new_dentry */
4653 +       dget(new_dentry);
4654 +
4655 +       /* dentry/mnt refs handed over to new_path */
4656 +       new_path = &dir_path;
4657 +
4658 +       /* dentry for old/new dir */
4659 +       dir = dir_nd.path.dentry;
4660 +
4661 +       /* give up reference on dir */
4662 +       dput(new_path->dentry);
4663 +
4664 +       /* new_dentry already has a reference */
4665 +       new_path->dentry = new_dentry;
4666 +
4667 +       ret = vfs_create(dir->d_inode, new_dentry, mode, 1);
4668 +       vxdprintk(VXD_CBIT(misc, 2),
4669 +               "vfs_create(new): %d", ret);
4670 +       if (ret == -EEXIST) {
4671 +               path_put(&dir_nd.path);
4672 +               mutex_unlock(&dir->d_inode->i_mutex);
4673 +               mnt_drop_write(new_path->mnt);
4674 +               path_put(new_path);
4675 +               new_dentry = NULL;
4676 +               goto retry;
4677 +       }
4678 +       else if (ret < 0)
4679 +               goto out_unlock_new;
4680 +
4681 +       /* the old file went away */
4682 +       ret = -ENOENT;
4683 +       if ((redo = d_unhashed(old_dentry)))
4684 +               goto out_unlock_new;
4685 +
4686 +       /* doesn't change refs for old_path */
4687 +       old_file = dentry_open(old_path, O_RDONLY, current_cred());
4688 +       vxdprintk(VXD_CBIT(misc, 2),
4689 +               "dentry_open(old): %p", old_file);
4690 +       if (IS_ERR(old_file)) {
4691 +               ret = PTR_ERR(old_file);
4692 +               goto out_unlock_new;
4693 +       }
4694 +
4695 +       /* doesn't change refs for new_path */
4696 +       new_file = dentry_open(new_path, O_WRONLY, current_cred());
4697 +       vxdprintk(VXD_CBIT(misc, 2),
4698 +               "dentry_open(new): %p", new_file);
4699 +       if (IS_ERR(new_file)) {
4700 +               ret = PTR_ERR(new_file);
4701 +               goto out_fput_old;
4702 +       }
4703 +
4704 +       /* unlock the inode mutex from kern_path_create() */
4705 +       mutex_unlock(&dir->d_inode->i_mutex);
4706 +
4707 +       /* drop write access to mnt */
4708 +       mnt_drop_write(new_path->mnt);
4709 +
4710 +       drop = 0;
4711 +
4712 +       size = i_size_read(old_file->f_path.dentry->d_inode);
4713 +       ret = do_cow_splice(old_file, new_file, size);
4714 +       vxdprintk(VXD_CBIT(misc, 2), "do_splice_direct: %d", ret);
4715 +       if (ret < 0) {
4716 +               goto out_fput_both;
4717 +       } else if (ret < size) {
4718 +               ret = -ENOSPC;
4719 +               goto out_fput_both;
4720 +       } else {
4721 +               struct inode *old_inode = old_dentry->d_inode;
4722 +               struct inode *new_inode = new_dentry->d_inode;
4723 +               struct iattr attr = {
4724 +                       .ia_uid = old_inode->i_uid,
4725 +                       .ia_gid = old_inode->i_gid,
4726 +                       .ia_valid = ATTR_UID | ATTR_GID
4727 +                       };
4728 +
4729 +               setattr_copy(new_inode, &attr);
4730 +               mark_inode_dirty(new_inode);
4731 +       }
4732 +
4733 +       /* lock rename mutex */
4734 +       mutex_lock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
4735 +
4736 +       /* drop out late */
4737 +       ret = -ENOENT;
4738 +       if ((redo = d_unhashed(old_dentry)))
4739 +               goto out_unlock;
4740 +
4741 +       vxdprintk(VXD_CBIT(misc, 2),
4742 +               "vfs_rename: [" VS_Q("%*s") ":%d] -> [" VS_Q("%*s") ":%d]",
4743 +               new_dentry->d_name.len, new_dentry->d_name.name,
4744 +               new_dentry->d_name.len,
4745 +               old_dentry->d_name.len, old_dentry->d_name.name,
4746 +               old_dentry->d_name.len);
4747 +       ret = vfs_rename(dir_nd.path.dentry->d_inode, new_dentry,
4748 +               old_dentry->d_parent->d_inode, old_dentry, NULL, 0);
4749 +       vxdprintk(VXD_CBIT(misc, 2), "vfs_rename: %d", ret);
4750 +
4751 +out_unlock:
4752 +       mutex_unlock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
4753 +
4754 +out_fput_both:
4755 +       vxdprintk(VXD_CBIT(misc, 3),
4756 +               "fput(new_file=%p[#%ld])", new_file,
4757 +               atomic_long_read(&new_file->f_count));
4758 +       fput(new_file);
4759 +
4760 +out_fput_old:
4761 +       vxdprintk(VXD_CBIT(misc, 3),
4762 +               "fput(old_file=%p[#%ld])", old_file,
4763 +               atomic_long_read(&old_file->f_count));
4764 +       fput(old_file);
4765 +
4766 +out_unlock_new:
4767 +       /* drop references from dir_nd.path */
4768 +       path_put(&dir_nd.path);
4769 +
4770 +       if (drop) {
4771 +               /* unlock the inode mutex from kern_path_create() */
4772 +               mutex_unlock(&dir->d_inode->i_mutex);
4773 +
4774 +               /* drop write access to mnt */
4775 +               mnt_drop_write(new_path->mnt);
4776 +       }
4777 +
4778 +       if (!ret)
4779 +               goto out_redo;
4780 +
4781 +       /* error path cleanup */
4782 +       vfs_unlink(dir->d_inode, new_dentry, NULL);
4783 +
4784 +out_redo:
4785 +       if (!redo)
4786 +               goto out_rel_both;
4787 +
4788 +       /* lookup dentry once again
4789 +          old_nd.path will be freed as old_path in out_rel_old */
4790 +       ret = filename_lookup(AT_FDCWD, filename, LOOKUP_FOLLOW, &old_nd);
4791 +       if (ret)
4792 +               goto out_rel_both;
4793 +
4794 +       /* drop reference on new_dentry */
4795 +       dput(new_dentry);
4796 +       new_dentry = old_path->dentry;
4797 +       dget(new_dentry);
4798 +       vxdprintk(VXD_CBIT(misc, 2),
4799 +               "do_path_lookup(redo): %p [" VS_Q("%.*s") ":%d]",
4800 +               new_dentry,
4801 +               new_dentry->d_name.len, new_dentry->d_name.name,
4802 +               new_dentry->d_name.len);
4803 +
4804 +out_rel_both:
4805 +       if (new_path)
4806 +               path_put(new_path);
4807 +out_rel_old:
4808 +       path_put(old_path);
4809 +out_free_path:
4810 +       kfree(path);
4811 +out:
4812 +       if (ret) {
4813 +               dput(new_dentry);
4814 +               new_dentry = ERR_PTR(ret);
4815 +       }
4816 +       if (!IS_ERR(filename))
4817 +               putname(filename);
4818 +       vxdprintk(VXD_CBIT(misc, 3),
4819 +               "cow_break_link returning with %p", new_dentry);
4820 +       return new_dentry;
4821 +}
4822 +
4823 +#endif
4824 +
4825 +int    vx_info_mnt_namespace(struct mnt_namespace *ns, char *buffer)
4826 +{
4827 +       struct path path;
4828 +       struct vfsmount *vmnt;
4829 +       char *pstr, *root;
4830 +       int length = 0;
4831 +
4832 +       pstr = kmalloc(PATH_MAX, GFP_KERNEL);
4833 +       if (!pstr)
4834 +               return 0;
4835 +
4836 +       vmnt = &ns->root->mnt;
4837 +       path.mnt = vmnt;
4838 +       path.dentry = vmnt->mnt_root;
4839 +       root = d_path(&path, pstr, PATH_MAX - 2);
4840 +       length = sprintf(buffer + length,
4841 +               "Namespace:\t%p [#%u]\n"
4842 +               "RootPath:\t%s\n",
4843 +               ns, atomic_read(&ns->count),
4844 +               root);
4845 +       kfree(pstr);
4846 +       return length;
4847 +}
4848 +
4849 +EXPORT_SYMBOL(vx_info_mnt_namespace);
4850 +
4851  /* get the link contents into pagecache */
4852  static char *page_getlink(struct dentry * dentry, struct page **ppage)
4853  {
4854 diff -NurpP --minimal linux-4.1.41/fs/namespace.c linux-4.1.41-vs2.3.8.5.3/fs/namespace.c
4855 --- linux-4.1.41/fs/namespace.c 2017-06-23 10:03:59.000000000 +0000
4856 +++ linux-4.1.41-vs2.3.8.5.3/fs/namespace.c     2017-05-30 07:39:23.000000000 +0000
4857 @@ -24,6 +24,11 @@
4858  #include <linux/magic.h>
4859  #include <linux/bootmem.h>
4860  #include <linux/task_work.h>
4861 +#include <linux/vs_base.h>
4862 +#include <linux/vs_context.h>
4863 +#include <linux/vs_tag.h>
4864 +#include <linux/vserver/space.h>
4865 +#include <linux/vserver/global.h>
4866  #include "pnode.h"
4867  #include "internal.h"
4868  
4869 @@ -959,6 +964,10 @@ vfs_kern_mount(struct file_system_type *
4870         if (!type)
4871                 return ERR_PTR(-ENODEV);
4872  
4873 +       if ((type->fs_flags & FS_BINARY_MOUNTDATA) &&
4874 +               !vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT))
4875 +               return ERR_PTR(-EPERM);
4876 +
4877         mnt = alloc_vfsmnt(name);
4878         if (!mnt)
4879                 return ERR_PTR(-ENOMEM);
4880 @@ -1034,6 +1043,7 @@ static struct mount *clone_mnt(struct mo
4881         mnt->mnt.mnt_root = dget(root);
4882         mnt->mnt_mountpoint = mnt->mnt.mnt_root;
4883         mnt->mnt_parent = mnt;
4884 +       mnt->mnt_tag = old->mnt_tag;
4885         lock_mount_hash();
4886         list_add_tail(&mnt->mnt_instance, &sb->s_mounts);
4887         unlock_mount_hash();
4888 @@ -1608,7 +1618,8 @@ out_unlock:
4889   */
4890  static inline bool may_mount(void)
4891  {
4892 -       return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN);
4893 +       return vx_ns_capable(current->nsproxy->mnt_ns->user_ns,
4894 +               CAP_SYS_ADMIN, VXC_SECURE_MOUNT);
4895  }
4896  
4897  /*
4898 @@ -2109,6 +2120,7 @@ static int do_change_type(struct path *p
4899                 if (err)
4900                         goto out_unlock;
4901         }
4902 +       // mnt->mnt_flags = mnt_flags;
4903  
4904         lock_mount_hash();
4905         for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))
4906 @@ -2137,12 +2149,14 @@ static bool has_locked_children(struct m
4907   * do loopback mount.
4908   */
4909  static int do_loopback(struct path *path, const char *old_name,
4910 -                               int recurse)
4911 +       vtag_t tag, unsigned long flags, int mnt_flags)
4912  {
4913         struct path old_path;
4914         struct mount *mnt = NULL, *old, *parent;
4915         struct mountpoint *mp;
4916 +       int recurse = flags & MS_REC;
4917         int err;
4918 +
4919         if (!old_name || !*old_name)
4920                 return -EINVAL;
4921         err = kern_path(old_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
4922 @@ -2222,7 +2236,7 @@ static int change_mount_flags(struct vfs
4923   * on it - tough luck.
4924   */
4925  static int do_remount(struct path *path, int flags, int mnt_flags,
4926 -                     void *data)
4927 +       void *data, vxid_t xid)
4928  {
4929         int err;
4930         struct super_block *sb = path->mnt->mnt_sb;
4931 @@ -2730,6 +2744,7 @@ long do_mount(const char *dev_name, cons
4932         struct path path;
4933         int retval = 0;
4934         int mnt_flags = 0;
4935 +       vtag_t tag = 0;
4936  
4937         /* Discard magic */
4938         if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
4939 @@ -2755,6 +2770,12 @@ long do_mount(const char *dev_name, cons
4940         if (!(flags & MS_NOATIME))
4941                 mnt_flags |= MNT_RELATIME;
4942  
4943 +       if (dx_parse_tag(data_page, &tag, 1, &mnt_flags, &flags)) {
4944 +               /* FIXME: bind and re-mounts get the tag flag? */
4945 +               if (flags & (MS_BIND|MS_REMOUNT))
4946 +                       flags |= MS_TAGID;
4947 +       }
4948 +
4949         /* Separate the per-mountpoint flags */
4950         if (flags & MS_NOSUID)
4951                 mnt_flags |= MNT_NOSUID;
4952 @@ -2779,15 +2800,17 @@ long do_mount(const char *dev_name, cons
4953                 mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK;
4954         }
4955  
4956 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_DEV_MOUNT))
4957 +               mnt_flags |= MNT_NODEV;
4958         flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN |
4959                    MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
4960                    MS_STRICTATIME);
4961  
4962         if (flags & MS_REMOUNT)
4963                 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
4964 -                                   data_page);
4965 +                                   data_page, tag);
4966         else if (flags & MS_BIND)
4967 -               retval = do_loopback(&path, dev_name, flags & MS_REC);
4968 +               retval = do_loopback(&path, dev_name, tag, flags, mnt_flags);
4969         else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
4970                 retval = do_change_type(&path, flags);
4971         else if (flags & MS_MOVE)
4972 @@ -2907,6 +2930,7 @@ struct mnt_namespace *copy_mnt_ns(unsign
4973                         p = next_mnt(p, old);
4974         }
4975         namespace_unlock();
4976 +       atomic_inc(&vs_global_mnt_ns);
4977  
4978         if (rootmnt)
4979                 mntput(rootmnt);
4980 @@ -3082,9 +3106,10 @@ SYSCALL_DEFINE2(pivot_root, const char _
4981         new_mnt = real_mount(new.mnt);
4982         root_mnt = real_mount(root.mnt);
4983         old_mnt = real_mount(old.mnt);
4984 -       if (IS_MNT_SHARED(old_mnt) ||
4985 +       if ((IS_MNT_SHARED(old_mnt) ||
4986                 IS_MNT_SHARED(new_mnt->mnt_parent) ||
4987 -               IS_MNT_SHARED(root_mnt->mnt_parent))
4988 +               IS_MNT_SHARED(root_mnt->mnt_parent)) &&
4989 +               !vx_flags(VXF_STATE_SETUP, 0))
4990                 goto out4;
4991         if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
4992                 goto out4;
4993 @@ -3222,6 +3247,7 @@ void put_mnt_ns(struct mnt_namespace *ns
4994         if (!atomic_dec_and_test(&ns->count))
4995                 return;
4996         drop_collected_mounts(&ns->root->mnt);
4997 +       atomic_dec(&vs_global_mnt_ns);
4998         free_mnt_ns(ns);
4999  }
5000  
5001 diff -NurpP --minimal linux-4.1.41/fs/nfs/client.c linux-4.1.41-vs2.3.8.5.3/fs/nfs/client.c
5002 --- linux-4.1.41/fs/nfs/client.c        2017-06-23 10:03:59.000000000 +0000
5003 +++ linux-4.1.41-vs2.3.8.5.3/fs/nfs/client.c    2016-07-05 04:41:47.000000000 +0000
5004 @@ -692,6 +692,9 @@ int nfs_init_server_rpcclient(struct nfs
5005         if (server->flags & NFS_MOUNT_SOFT)
5006                 server->client->cl_softrtry = 1;
5007  
5008 +       server->client->cl_tag = 0;
5009 +       if (server->flags & NFS_MOUNT_TAGGED)
5010 +               server->client->cl_tag = 1;
5011         return 0;
5012  }
5013  EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
5014 @@ -870,6 +873,10 @@ static void nfs_server_set_fsinfo(struct
5015                 server->acdirmin = server->acdirmax = 0;
5016         }
5017  
5018 +       /* FIXME: needs fsinfo
5019 +       if (server->flags & NFS_MOUNT_TAGGED)
5020 +               sb->s_flags |= MS_TAGGED;       */
5021 +
5022         server->maxfilesize = fsinfo->maxfilesize;
5023  
5024         server->time_delta = fsinfo->time_delta;
5025 diff -NurpP --minimal linux-4.1.41/fs/nfs/dir.c linux-4.1.41-vs2.3.8.5.3/fs/nfs/dir.c
5026 --- linux-4.1.41/fs/nfs/dir.c   2017-06-23 10:03:59.000000000 +0000
5027 +++ linux-4.1.41-vs2.3.8.5.3/fs/nfs/dir.c       2016-10-25 21:31:19.000000000 +0000
5028 @@ -37,6 +37,7 @@
5029  #include <linux/sched.h>
5030  #include <linux/kmemleak.h>
5031  #include <linux/xattr.h>
5032 +#include <linux/vs_tag.h>
5033  
5034  #include "delegation.h"
5035  #include "iostat.h"
5036 @@ -1411,6 +1412,7 @@ struct dentry *nfs_lookup(struct inode *
5037         /* Success: notify readdir to use READDIRPLUS */
5038         nfs_advise_use_readdirplus(dir);
5039  
5040 +       dx_propagate_tag(nd, inode);
5041  no_entry:
5042         res = d_splice_alias(inode, dentry);
5043         if (res != NULL) {
5044 diff -NurpP --minimal linux-4.1.41/fs/nfs/inode.c linux-4.1.41-vs2.3.8.5.3/fs/nfs/inode.c
5045 --- linux-4.1.41/fs/nfs/inode.c 2017-06-23 10:03:59.000000000 +0000
5046 +++ linux-4.1.41-vs2.3.8.5.3/fs/nfs/inode.c     2016-07-05 04:41:47.000000000 +0000
5047 @@ -38,6 +38,7 @@
5048  #include <linux/slab.h>
5049  #include <linux/compat.h>
5050  #include <linux/freezer.h>
5051 +#include <linux/vs_tag.h>
5052  
5053  #include <asm/uaccess.h>
5054  
5055 @@ -376,6 +377,8 @@ nfs_fhget(struct super_block *sb, struct
5056         if (inode->i_state & I_NEW) {
5057                 struct nfs_inode *nfsi = NFS_I(inode);
5058                 unsigned long now = jiffies;
5059 +               kuid_t kuid;
5060 +               kgid_t kgid;
5061  
5062                 /* We set i_ino for the few things that still rely on it,
5063                  * such as stat(2) */
5064 @@ -419,8 +422,8 @@ nfs_fhget(struct super_block *sb, struct
5065                 inode->i_version = 0;
5066                 inode->i_size = 0;
5067                 clear_nlink(inode);
5068 -               inode->i_uid = make_kuid(&init_user_ns, -2);
5069 -               inode->i_gid = make_kgid(&init_user_ns, -2);
5070 +               kuid = make_kuid(&init_user_ns, -2);
5071 +               kgid = make_kgid(&init_user_ns, -2);
5072                 inode->i_blocks = 0;
5073                 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
5074                 nfsi->write_io = 0;
5075 @@ -454,11 +457,11 @@ nfs_fhget(struct super_block *sb, struct
5076                 else if (nfs_server_capable(inode, NFS_CAP_NLINK))
5077                         nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
5078                 if (fattr->valid & NFS_ATTR_FATTR_OWNER)
5079 -                       inode->i_uid = fattr->uid;
5080 +                       kuid = fattr->uid;
5081                 else if (nfs_server_capable(inode, NFS_CAP_OWNER))
5082                         nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
5083                 if (fattr->valid & NFS_ATTR_FATTR_GROUP)
5084 -                       inode->i_gid = fattr->gid;
5085 +                       kgid = fattr->gid;
5086                 else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
5087                         nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
5088                 if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
5089 @@ -469,6 +472,10 @@ nfs_fhget(struct super_block *sb, struct
5090                          */
5091                         inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
5092                 }
5093 +               inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
5094 +               inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
5095 +               inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, GLOBAL_ROOT_TAG);
5096 +                               /* maybe fattr->xid someday */
5097  
5098                 nfs_setsecurity(inode, fattr, label);
5099  
5100 @@ -608,6 +615,8 @@ void nfs_setattr_update_inode(struct ino
5101                         inode->i_uid = attr->ia_uid;
5102                 if ((attr->ia_valid & ATTR_GID) != 0)
5103                         inode->i_gid = attr->ia_gid;
5104 +               if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
5105 +                       inode->i_tag = attr->ia_tag;
5106                 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS
5107                                 | NFS_INO_INVALID_ACL);
5108         }
5109 @@ -1221,7 +1230,9 @@ static int nfs_check_inode_attributes(st
5110         struct nfs_inode *nfsi = NFS_I(inode);
5111         loff_t cur_size, new_isize;
5112         unsigned long invalid = 0;
5113 -
5114 +       kuid_t kuid;
5115 +       kgid_t kgid;
5116 +       ktag_t ktag;
5117  
5118         if (nfs_have_delegated_attributes(inode))
5119                 return 0;
5120 @@ -1248,13 +1259,18 @@ static int nfs_check_inode_attributes(st
5121         if (nfsi->nrequests != 0)
5122                 invalid &= ~NFS_INO_REVAL_PAGECACHE;
5123  
5124 +       kuid = INOTAG_KUID(DX_TAG(inode), fattr->uid, fattr->gid);
5125 +       kgid = INOTAG_KGID(DX_TAG(inode), fattr->uid, fattr->gid);
5126 +       ktag = INOTAG_KTAG(DX_TAG(inode), fattr->uid, fattr->gid, GLOBAL_ROOT_TAG);
5127 +
5128         /* Have any file permissions changed? */
5129         if ((fattr->valid & NFS_ATTR_FATTR_MODE) && (inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO))
5130                 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
5131 -       if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, fattr->uid))
5132 +       if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, kuid))
5133                 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
5134 -       if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, fattr->gid))
5135 +       if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, kgid))
5136                 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
5137 +               /* maybe check for tag too? */
5138  
5139         /* Has the link count changed? */
5140         if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink)
5141 @@ -1628,6 +1644,9 @@ static int nfs_update_inode(struct inode
5142         unsigned long now = jiffies;
5143         unsigned long save_cache_validity;
5144         bool cache_revalidated = true;
5145 +       kuid_t kuid;
5146 +       kgid_t kgid;
5147 +       ktag_t ktag;
5148  
5149         dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
5150                         __func__, inode->i_sb->s_id, inode->i_ino,
5151 @@ -1738,6 +1757,9 @@ static int nfs_update_inode(struct inode
5152                 cache_revalidated = false;
5153         }
5154  
5155 +       kuid = TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag);
5156 +       kgid = TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag);
5157 +       ktag = TAGINO_KTAG(DX_TAG(inode), inode->i_tag);
5158  
5159         if (fattr->valid & NFS_ATTR_FATTR_ATIME)
5160                 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
5161 @@ -1792,6 +1814,10 @@ static int nfs_update_inode(struct inode
5162                 cache_revalidated = false;
5163         }
5164  
5165 +       inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
5166 +       inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
5167 +       inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, ktag);
5168 +
5169         if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
5170                 if (inode->i_nlink != fattr->nlink) {
5171                         invalid |= NFS_INO_INVALID_ATTR;
5172 diff -NurpP --minimal linux-4.1.41/fs/nfs/nfs3xdr.c linux-4.1.41-vs2.3.8.5.3/fs/nfs/nfs3xdr.c
5173 --- linux-4.1.41/fs/nfs/nfs3xdr.c       2017-06-23 10:03:59.000000000 +0000
5174 +++ linux-4.1.41-vs2.3.8.5.3/fs/nfs/nfs3xdr.c   2016-07-05 04:41:47.000000000 +0000
5175 @@ -20,6 +20,7 @@
5176  #include <linux/nfs3.h>
5177  #include <linux/nfs_fs.h>
5178  #include <linux/nfsacl.h>
5179 +#include <linux/vs_tag.h>
5180  #include "internal.h"
5181  
5182  #define NFSDBG_FACILITY                NFSDBG_XDR
5183 @@ -558,7 +559,8 @@ static __be32 *xdr_decode_nfstime3(__be3
5184   *             set_mtime       mtime;
5185   *     };
5186   */
5187 -static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
5188 +static void encode_sattr3(struct xdr_stream *xdr,
5189 +       const struct iattr *attr, int tag)
5190  {
5191         u32 nbytes;
5192         __be32 *p;
5193 @@ -590,15 +592,19 @@ static void encode_sattr3(struct xdr_str
5194         } else
5195                 *p++ = xdr_zero;
5196  
5197 -       if (attr->ia_valid & ATTR_UID) {
5198 +       if (attr->ia_valid & ATTR_UID ||
5199 +               (tag && (attr->ia_valid & ATTR_TAG))) {
5200                 *p++ = xdr_one;
5201 -               *p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));
5202 +               *p++ = cpu_to_be32(from_kuid(&init_user_ns,
5203 +                       TAGINO_KUID(tag, attr->ia_uid, attr->ia_tag)));
5204         } else
5205                 *p++ = xdr_zero;
5206  
5207 -       if (attr->ia_valid & ATTR_GID) {
5208 +       if (attr->ia_valid & ATTR_GID ||
5209 +               (tag && (attr->ia_valid & ATTR_TAG))) {
5210                 *p++ = xdr_one;
5211 -               *p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));
5212 +               *p++ = cpu_to_be32(from_kgid(&init_user_ns,
5213 +                       TAGINO_KGID(tag, attr->ia_gid, attr->ia_tag)));
5214         } else
5215                 *p++ = xdr_zero;
5216  
5217 @@ -887,7 +893,7 @@ static void nfs3_xdr_enc_setattr3args(st
5218                                       const struct nfs3_sattrargs *args)
5219  {
5220         encode_nfs_fh3(xdr, args->fh);
5221 -       encode_sattr3(xdr, args->sattr);
5222 +       encode_sattr3(xdr, args->sattr, req->rq_task->tk_client->cl_tag);
5223         encode_sattrguard3(xdr, args);
5224  }
5225  
5226 @@ -1037,13 +1043,13 @@ static void nfs3_xdr_enc_write3args(stru
5227   *     };
5228   */
5229  static void encode_createhow3(struct xdr_stream *xdr,
5230 -                             const struct nfs3_createargs *args)
5231 +       const struct nfs3_createargs *args, int tag)
5232  {
5233         encode_uint32(xdr, args->createmode);
5234         switch (args->createmode) {
5235         case NFS3_CREATE_UNCHECKED:
5236         case NFS3_CREATE_GUARDED:
5237 -               encode_sattr3(xdr, args->sattr);
5238 +               encode_sattr3(xdr, args->sattr, tag);
5239                 break;
5240         case NFS3_CREATE_EXCLUSIVE:
5241                 encode_createverf3(xdr, args->verifier);
5242 @@ -1058,7 +1064,7 @@ static void nfs3_xdr_enc_create3args(str
5243                                      const struct nfs3_createargs *args)
5244  {
5245         encode_diropargs3(xdr, args->fh, args->name, args->len);
5246 -       encode_createhow3(xdr, args);
5247 +       encode_createhow3(xdr, args, req->rq_task->tk_client->cl_tag);
5248  }
5249  
5250  /*
5251 @@ -1074,7 +1080,7 @@ static void nfs3_xdr_enc_mkdir3args(stru
5252                                     const struct nfs3_mkdirargs *args)
5253  {
5254         encode_diropargs3(xdr, args->fh, args->name, args->len);
5255 -       encode_sattr3(xdr, args->sattr);
5256 +       encode_sattr3(xdr, args->sattr, req->rq_task->tk_client->cl_tag);
5257  }
5258  
5259  /*
5260 @@ -1091,9 +1097,9 @@ static void nfs3_xdr_enc_mkdir3args(stru
5261   *     };
5262   */
5263  static void encode_symlinkdata3(struct xdr_stream *xdr,
5264 -                               const struct nfs3_symlinkargs *args)
5265 +       const struct nfs3_symlinkargs *args, int tag)
5266  {
5267 -       encode_sattr3(xdr, args->sattr);
5268 +       encode_sattr3(xdr, args->sattr, tag);
5269         encode_nfspath3(xdr, args->pages, args->pathlen);
5270  }
5271  
5272 @@ -1102,7 +1108,7 @@ static void nfs3_xdr_enc_symlink3args(st
5273                                       const struct nfs3_symlinkargs *args)
5274  {
5275         encode_diropargs3(xdr, args->fromfh, args->fromname, args->fromlen);
5276 -       encode_symlinkdata3(xdr, args);
5277 +       encode_symlinkdata3(xdr, args, req->rq_task->tk_client->cl_tag);
5278  }
5279  
5280  /*
5281 @@ -1130,24 +1136,24 @@ static void nfs3_xdr_enc_symlink3args(st
5282   *     };
5283   */
5284  static void encode_devicedata3(struct xdr_stream *xdr,
5285 -                              const struct nfs3_mknodargs *args)
5286 +       const struct nfs3_mknodargs *args, int tag)
5287  {
5288 -       encode_sattr3(xdr, args->sattr);
5289 +       encode_sattr3(xdr, args->sattr, tag);
5290         encode_specdata3(xdr, args->rdev);
5291  }
5292  
5293  static void encode_mknoddata3(struct xdr_stream *xdr,
5294 -                             const struct nfs3_mknodargs *args)
5295 +       const struct nfs3_mknodargs *args, int tag)
5296  {
5297         encode_ftype3(xdr, args->type);
5298         switch (args->type) {
5299         case NF3CHR:
5300         case NF3BLK:
5301 -               encode_devicedata3(xdr, args);
5302 +               encode_devicedata3(xdr, args, tag);
5303                 break;
5304         case NF3SOCK:
5305         case NF3FIFO:
5306 -               encode_sattr3(xdr, args->sattr);
5307 +               encode_sattr3(xdr, args->sattr, tag);
5308                 break;
5309         case NF3REG:
5310         case NF3DIR:
5311 @@ -1162,7 +1168,7 @@ static void nfs3_xdr_enc_mknod3args(stru
5312                                     const struct nfs3_mknodargs *args)
5313  {
5314         encode_diropargs3(xdr, args->fh, args->name, args->len);
5315 -       encode_mknoddata3(xdr, args);
5316 +       encode_mknoddata3(xdr, args, req->rq_task->tk_client->cl_tag);
5317  }
5318  
5319  /*
5320 diff -NurpP --minimal linux-4.1.41/fs/nfs/super.c linux-4.1.41-vs2.3.8.5.3/fs/nfs/super.c
5321 --- linux-4.1.41/fs/nfs/super.c 2015-07-06 20:41:42.000000000 +0000
5322 +++ linux-4.1.41-vs2.3.8.5.3/fs/nfs/super.c     2016-07-05 04:41:47.000000000 +0000
5323 @@ -54,6 +54,7 @@
5324  #include <linux/parser.h>
5325  #include <linux/nsproxy.h>
5326  #include <linux/rcupdate.h>
5327 +#include <linux/vs_tag.h>
5328  
5329  #include <asm/uaccess.h>
5330  
5331 @@ -102,6 +103,7 @@ enum {
5332         Opt_mountport,
5333         Opt_mountvers,
5334         Opt_minorversion,
5335 +       Opt_tagid,
5336  
5337         /* Mount options that take string arguments */
5338         Opt_nfsvers,
5339 @@ -114,6 +116,9 @@ enum {
5340         /* Special mount options */
5341         Opt_userspace, Opt_deprecated, Opt_sloppy,
5342  
5343 +       /* Linux-VServer tagging options */
5344 +       Opt_tag, Opt_notag,
5345 +
5346         Opt_err
5347  };
5348  
5349 @@ -183,6 +188,10 @@ static const match_table_t nfs_mount_opt
5350         { Opt_fscache_uniq, "fsc=%s" },
5351         { Opt_local_lock, "local_lock=%s" },
5352  
5353 +       { Opt_tag, "tag" },
5354 +       { Opt_notag, "notag" },
5355 +       { Opt_tagid, "tagid=%u" },
5356 +
5357         /* The following needs to be listed after all other options */
5358         { Opt_nfsvers, "v%s" },
5359  
5360 @@ -639,6 +648,7 @@ static void nfs_show_mount_options(struc
5361                 { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
5362                 { NFS_MOUNT_UNSHARED, ",nosharecache", "" },
5363                 { NFS_MOUNT_NORESVPORT, ",noresvport", "" },
5364 +               { NFS_MOUNT_TAGGED, ",tag", "" },
5365                 { 0, NULL, NULL }
5366         };
5367         const struct proc_nfs_info *nfs_infop;
5368 @@ -1321,6 +1331,14 @@ static int nfs_parse_mount_options(char
5369                 case Opt_nomigration:
5370                         mnt->options &= NFS_OPTION_MIGRATION;
5371                         break;
5372 +#ifndef CONFIG_TAGGING_NONE
5373 +               case Opt_tag:
5374 +                       mnt->flags |= NFS_MOUNT_TAGGED;
5375 +                       break;
5376 +               case Opt_notag:
5377 +                       mnt->flags &= ~NFS_MOUNT_TAGGED;
5378 +                       break;
5379 +#endif
5380  
5381                 /*
5382                  * options that take numeric values
5383 @@ -1407,6 +1425,12 @@ static int nfs_parse_mount_options(char
5384                                 goto out_invalid_value;
5385                         mnt->minorversion = option;
5386                         break;
5387 +#ifdef CONFIG_PROPAGATE
5388 +               case Opt_tagid:
5389 +                       /* use args[0] */
5390 +                       nfs_data.flags |= NFS_MOUNT_TAGGED;
5391 +                       break;
5392 +#endif
5393  
5394                 /*
5395                  * options that take text values
5396 diff -NurpP --minimal linux-4.1.41/fs/nfsd/auth.c linux-4.1.41-vs2.3.8.5.3/fs/nfsd/auth.c
5397 --- linux-4.1.41/fs/nfsd/auth.c 2015-04-12 22:12:50.000000000 +0000
5398 +++ linux-4.1.41-vs2.3.8.5.3/fs/nfsd/auth.c     2016-07-05 04:41:47.000000000 +0000
5399 @@ -1,6 +1,7 @@
5400  /* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
5401  
5402  #include <linux/sched.h>
5403 +#include <linux/vs_tag.h>
5404  #include "nfsd.h"
5405  #include "auth.h"
5406  
5407 @@ -35,6 +36,9 @@ int nfsd_setuser(struct svc_rqst *rqstp,
5408  
5409         new->fsuid = rqstp->rq_cred.cr_uid;
5410         new->fsgid = rqstp->rq_cred.cr_gid;
5411 +       /* FIXME: this desperately needs a tag :)
5412 +       new->xid = (vxid_t)INOTAG_TAG(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid, 0);
5413 +                       */
5414  
5415         rqgi = rqstp->rq_cred.cr_group_info;
5416  
5417 diff -NurpP --minimal linux-4.1.41/fs/nfsd/nfs3xdr.c linux-4.1.41-vs2.3.8.5.3/fs/nfsd/nfs3xdr.c
5418 --- linux-4.1.41/fs/nfsd/nfs3xdr.c      2017-06-23 10:03:59.000000000 +0000
5419 +++ linux-4.1.41-vs2.3.8.5.3/fs/nfsd/nfs3xdr.c  2017-05-30 07:39:23.000000000 +0000
5420 @@ -8,6 +8,7 @@
5421  
5422  #include <linux/namei.h>
5423  #include <linux/sunrpc/svc_xprt.h>
5424 +#include <linux/vs_tag.h>
5425  #include "xdr3.h"
5426  #include "auth.h"
5427  #include "netns.h"
5428 @@ -98,6 +99,8 @@ static __be32 *
5429  decode_sattr3(__be32 *p, struct iattr *iap)
5430  {
5431         u32     tmp;
5432 +       kuid_t  kuid = GLOBAL_ROOT_UID;
5433 +       kgid_t  kgid = GLOBAL_ROOT_GID;
5434  
5435         iap->ia_valid = 0;
5436  
5437 @@ -106,15 +109,18 @@ decode_sattr3(__be32 *p, struct iattr *i
5438                 iap->ia_mode = ntohl(*p++);
5439         }
5440         if (*p++) {
5441 -               iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++));
5442 +               kuid = make_kuid(&init_user_ns, ntohl(*p++));
5443                 if (uid_valid(iap->ia_uid))
5444                         iap->ia_valid |= ATTR_UID;
5445         }
5446         if (*p++) {
5447 -               iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++));
5448 +               kgid = make_kgid(&init_user_ns, ntohl(*p++));
5449                 if (gid_valid(iap->ia_gid))
5450                         iap->ia_valid |= ATTR_GID;
5451         }
5452 +       iap->ia_uid = INOTAG_KUID(DX_TAG_NFSD, kuid, kgid);
5453 +       iap->ia_gid = INOTAG_KGID(DX_TAG_NFSD, kuid, kgid);
5454 +       iap->ia_tag = INOTAG_KTAG(DX_TAG_NFSD, kuid, kgid, GLOBAL_ROOT_TAG);
5455         if (*p++) {
5456                 u64     newsize;
5457  
5458 @@ -167,8 +173,12 @@ encode_fattr3(struct svc_rqst *rqstp, __
5459         *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
5460         *p++ = htonl((u32) (stat->mode & S_IALLUGO));
5461         *p++ = htonl((u32) stat->nlink);
5462 -       *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
5463 -       *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
5464 +       *p++ = htonl((u32) from_kuid(&init_user_ns,
5465 +               TAGINO_KUID(0 /* FIXME: DX_TAG(dentry->d_inode) */,
5466 +               stat->uid, stat->tag)));
5467 +       *p++ = htonl((u32) from_kgid(&init_user_ns,
5468 +               TAGINO_KGID(0 /* FIXME: DX_TAG(dentry->d_inode) */,
5469 +               stat->gid, stat->tag)));
5470         if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
5471                 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
5472         } else {
5473 diff -NurpP --minimal linux-4.1.41/fs/nfsd/nfs4xdr.c linux-4.1.41-vs2.3.8.5.3/fs/nfsd/nfs4xdr.c
5474 --- linux-4.1.41/fs/nfsd/nfs4xdr.c      2017-06-23 10:03:59.000000000 +0000
5475 +++ linux-4.1.41-vs2.3.8.5.3/fs/nfsd/nfs4xdr.c  2017-05-30 07:39:23.000000000 +0000
5476 @@ -39,6 +39,7 @@
5477  #include <linux/utsname.h>
5478  #include <linux/pagemap.h>
5479  #include <linux/sunrpc/svcauth_gss.h>
5480 +#include <linux/vs_tag.h>
5481  
5482  #include "idmap.h"
5483  #include "acl.h"
5484 @@ -2629,12 +2630,16 @@ out_acl:
5485                 *p++ = cpu_to_be32(stat.nlink);
5486         }
5487         if (bmval1 & FATTR4_WORD1_OWNER) {
5488 -               status = nfsd4_encode_user(xdr, rqstp, stat.uid);
5489 +               status = nfsd4_encode_user(xdr, rqstp,
5490 +                       TAGINO_KUID(DX_TAG(dentry->d_inode),
5491 +                               stat.uid, stat.tag));
5492                 if (status)
5493                         goto out;
5494         }
5495         if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
5496 -               status = nfsd4_encode_group(xdr, rqstp, stat.gid);
5497 +               status = nfsd4_encode_group(xdr, rqstp,
5498 +                       TAGINO_KGID(DX_TAG(dentry->d_inode),
5499 +                               stat.gid, stat.tag));
5500                 if (status)
5501                         goto out;
5502         }
5503 diff -NurpP --minimal linux-4.1.41/fs/nfsd/nfsxdr.c linux-4.1.41-vs2.3.8.5.3/fs/nfsd/nfsxdr.c
5504 --- linux-4.1.41/fs/nfsd/nfsxdr.c       2017-06-23 10:03:59.000000000 +0000
5505 +++ linux-4.1.41-vs2.3.8.5.3/fs/nfsd/nfsxdr.c   2017-05-30 07:39:23.000000000 +0000
5506 @@ -7,6 +7,7 @@
5507  #include "vfs.h"
5508  #include "xdr.h"
5509  #include "auth.h"
5510 +#include <linux/vs_tag.h>
5511  
5512  #define NFSDDBG_FACILITY               NFSDDBG_XDR
5513  
5514 @@ -89,6 +90,8 @@ static __be32 *
5515  decode_sattr(__be32 *p, struct iattr *iap)
5516  {
5517         u32     tmp, tmp1;
5518 +       kuid_t  kuid = GLOBAL_ROOT_UID;
5519 +       kgid_t  kgid = GLOBAL_ROOT_GID;
5520  
5521         iap->ia_valid = 0;
5522  
5523 @@ -101,15 +104,18 @@ decode_sattr(__be32 *p, struct iattr *ia
5524                 iap->ia_mode = tmp;
5525         }
5526         if ((tmp = ntohl(*p++)) != (u32)-1) {
5527 -               iap->ia_uid = make_kuid(&init_user_ns, tmp);
5528 +               kuid = make_kuid(&init_user_ns, tmp);
5529                 if (uid_valid(iap->ia_uid))
5530                         iap->ia_valid |= ATTR_UID;
5531         }
5532         if ((tmp = ntohl(*p++)) != (u32)-1) {
5533 -               iap->ia_gid = make_kgid(&init_user_ns, tmp);
5534 +               kgid = make_kgid(&init_user_ns, tmp);
5535                 if (gid_valid(iap->ia_gid))
5536                         iap->ia_valid |= ATTR_GID;
5537         }
5538 +       iap->ia_uid = INOTAG_KUID(DX_TAG_NFSD, kuid, kgid);
5539 +       iap->ia_gid = INOTAG_KGID(DX_TAG_NFSD, kuid, kgid);
5540 +       iap->ia_tag = INOTAG_KTAG(DX_TAG_NFSD, kuid, kgid, GLOBAL_ROOT_TAG);
5541         if ((tmp = ntohl(*p++)) != (u32)-1) {
5542                 iap->ia_valid |= ATTR_SIZE;
5543                 iap->ia_size = tmp;
5544 @@ -154,8 +160,10 @@ encode_fattr(struct svc_rqst *rqstp, __b
5545         *p++ = htonl(nfs_ftypes[type >> 12]);
5546         *p++ = htonl((u32) stat->mode);
5547         *p++ = htonl((u32) stat->nlink);
5548 -       *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
5549 -       *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
5550 +       *p++ = htonl((u32) from_kuid(&init_user_ns,
5551 +               TAGINO_KUID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
5552 +       *p++ = htonl((u32) from_kgid(&init_user_ns,
5553 +               TAGINO_KGID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
5554  
5555         if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
5556                 *p++ = htonl(NFS_MAXPATHLEN);
5557 diff -NurpP --minimal linux-4.1.41/fs/ocfs2/dlmglue.c linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/dlmglue.c
5558 --- linux-4.1.41/fs/ocfs2/dlmglue.c     2017-06-23 10:03:59.000000000 +0000
5559 +++ linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/dlmglue.c 2017-05-30 07:39:23.000000000 +0000
5560 @@ -2083,6 +2083,7 @@ static void __ocfs2_stuff_meta_lvb(struc
5561         lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
5562         lvb->lvb_iuid      = cpu_to_be32(i_uid_read(inode));
5563         lvb->lvb_igid      = cpu_to_be32(i_gid_read(inode));
5564 +       lvb->lvb_itag      = cpu_to_be16(i_tag_read(inode));
5565         lvb->lvb_imode     = cpu_to_be16(inode->i_mode);
5566         lvb->lvb_inlink    = cpu_to_be16(inode->i_nlink);
5567         lvb->lvb_iatime_packed  =
5568 @@ -2133,6 +2134,7 @@ static void ocfs2_refresh_inode_from_lvb
5569  
5570         i_uid_write(inode, be32_to_cpu(lvb->lvb_iuid));
5571         i_gid_write(inode, be32_to_cpu(lvb->lvb_igid));
5572 +       i_tag_write(inode, be16_to_cpu(lvb->lvb_itag));
5573         inode->i_mode    = be16_to_cpu(lvb->lvb_imode);
5574         set_nlink(inode, be16_to_cpu(lvb->lvb_inlink));
5575         ocfs2_unpack_timespec(&inode->i_atime,
5576 diff -NurpP --minimal linux-4.1.41/fs/ocfs2/dlmglue.h linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/dlmglue.h
5577 --- linux-4.1.41/fs/ocfs2/dlmglue.h     2015-04-12 22:12:50.000000000 +0000
5578 +++ linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/dlmglue.h 2016-07-05 04:41:47.000000000 +0000
5579 @@ -46,7 +46,8 @@ struct ocfs2_meta_lvb {
5580         __be16       lvb_inlink;
5581         __be32       lvb_iattr;
5582         __be32       lvb_igeneration;
5583 -       __be32       lvb_reserved2;
5584 +       __be16       lvb_itag;
5585 +       __be16       lvb_reserved2;
5586  };
5587  
5588  #define OCFS2_QINFO_LVB_VERSION 1
5589 diff -NurpP --minimal linux-4.1.41/fs/ocfs2/file.c linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/file.c
5590 --- linux-4.1.41/fs/ocfs2/file.c        2017-06-23 10:03:59.000000000 +0000
5591 +++ linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/file.c    2017-05-30 07:39:23.000000000 +0000
5592 @@ -1146,7 +1146,7 @@ int ocfs2_setattr(struct dentry *dentry,
5593                 attr->ia_valid &= ~ATTR_SIZE;
5594  
5595  #define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \
5596 -                          | ATTR_GID | ATTR_UID | ATTR_MODE)
5597 +                          | ATTR_GID | ATTR_UID | ATTR_TAG | ATTR_MODE)
5598         if (!(attr->ia_valid & OCFS2_VALID_ATTRS))
5599                 return 0;
5600  
5601 diff -NurpP --minimal linux-4.1.41/fs/ocfs2/inode.c linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/inode.c
5602 --- linux-4.1.41/fs/ocfs2/inode.c       2015-07-06 20:41:42.000000000 +0000
5603 +++ linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/inode.c   2016-07-05 04:41:47.000000000 +0000
5604 @@ -28,6 +28,7 @@
5605  #include <linux/highmem.h>
5606  #include <linux/pagemap.h>
5607  #include <linux/quotaops.h>
5608 +#include <linux/vs_tag.h>
5609  
5610  #include <asm/byteorder.h>
5611  
5612 @@ -78,11 +79,13 @@ void ocfs2_set_inode_flags(struct inode
5613  {
5614         unsigned int flags = OCFS2_I(inode)->ip_attr;
5615  
5616 -       inode->i_flags &= ~(S_IMMUTABLE |
5617 +       inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK |
5618                 S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
5619  
5620         if (flags & OCFS2_IMMUTABLE_FL)
5621                 inode->i_flags |= S_IMMUTABLE;
5622 +       if (flags & OCFS2_IXUNLINK_FL)
5623 +               inode->i_flags |= S_IXUNLINK;
5624  
5625         if (flags & OCFS2_SYNC_FL)
5626                 inode->i_flags |= S_SYNC;
5627 @@ -92,25 +95,44 @@ void ocfs2_set_inode_flags(struct inode
5628                 inode->i_flags |= S_NOATIME;
5629         if (flags & OCFS2_DIRSYNC_FL)
5630                 inode->i_flags |= S_DIRSYNC;
5631 +
5632 +       inode->i_vflags &= ~(V_BARRIER | V_COW);
5633 +
5634 +       if (flags & OCFS2_BARRIER_FL)
5635 +               inode->i_vflags |= V_BARRIER;
5636 +       if (flags & OCFS2_COW_FL)
5637 +               inode->i_vflags |= V_COW;
5638  }
5639  
5640  /* Propagate flags from i_flags to OCFS2_I(inode)->ip_attr */
5641  void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi)
5642  {
5643         unsigned int flags = oi->vfs_inode.i_flags;
5644 +       unsigned int vflags = oi->vfs_inode.i_vflags;
5645 +
5646 +       oi->ip_attr &= ~(OCFS2_SYNC_FL | OCFS2_APPEND_FL |
5647 +                       OCFS2_IMMUTABLE_FL | OCFS2_IXUNLINK_FL |
5648 +                       OCFS2_NOATIME_FL | OCFS2_DIRSYNC_FL |
5649 +                       OCFS2_BARRIER_FL | OCFS2_COW_FL);
5650 +
5651 +       if (flags & S_IMMUTABLE)
5652 +               oi->ip_attr |= OCFS2_IMMUTABLE_FL;
5653 +       if (flags & S_IXUNLINK)
5654 +               oi->ip_attr |= OCFS2_IXUNLINK_FL;
5655  
5656 -       oi->ip_attr &= ~(OCFS2_SYNC_FL|OCFS2_APPEND_FL|
5657 -                       OCFS2_IMMUTABLE_FL|OCFS2_NOATIME_FL|OCFS2_DIRSYNC_FL);
5658         if (flags & S_SYNC)
5659                 oi->ip_attr |= OCFS2_SYNC_FL;
5660         if (flags & S_APPEND)
5661                 oi->ip_attr |= OCFS2_APPEND_FL;
5662 -       if (flags & S_IMMUTABLE)
5663 -               oi->ip_attr |= OCFS2_IMMUTABLE_FL;
5664         if (flags & S_NOATIME)
5665                 oi->ip_attr |= OCFS2_NOATIME_FL;
5666         if (flags & S_DIRSYNC)
5667                 oi->ip_attr |= OCFS2_DIRSYNC_FL;
5668 +
5669 +       if (vflags & V_BARRIER)
5670 +               oi->ip_attr |= OCFS2_BARRIER_FL;
5671 +       if (vflags & V_COW)
5672 +               oi->ip_attr |= OCFS2_COW_FL;
5673  }
5674  
5675  struct inode *ocfs2_ilookup(struct super_block *sb, u64 blkno)
5676 @@ -268,6 +290,8 @@ void ocfs2_populate_inode(struct inode *
5677         struct super_block *sb;
5678         struct ocfs2_super *osb;
5679         int use_plocks = 1;
5680 +       uid_t uid;
5681 +       gid_t gid;
5682  
5683         sb = inode->i_sb;
5684         osb = OCFS2_SB(sb);
5685 @@ -296,8 +320,12 @@ void ocfs2_populate_inode(struct inode *
5686         inode->i_generation = le32_to_cpu(fe->i_generation);
5687         inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
5688         inode->i_mode = le16_to_cpu(fe->i_mode);
5689 -       i_uid_write(inode, le32_to_cpu(fe->i_uid));
5690 -       i_gid_write(inode, le32_to_cpu(fe->i_gid));
5691 +       uid = le32_to_cpu(fe->i_uid);
5692 +       gid = le32_to_cpu(fe->i_gid);
5693 +       i_uid_write(inode, INOTAG_UID(DX_TAG(inode), uid, gid));
5694 +       i_gid_write(inode, INOTAG_GID(DX_TAG(inode), uid, gid));
5695 +       i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), uid, gid,
5696 +               /* le16_to_cpu(raw_inode->i_raw_tag) */ 0));
5697  
5698         /* Fast symlinks will have i_size but no allocated clusters. */
5699         if (S_ISLNK(inode->i_mode) && !fe->i_clusters) {
5700 diff -NurpP --minimal linux-4.1.41/fs/ocfs2/inode.h linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/inode.h
5701 --- linux-4.1.41/fs/ocfs2/inode.h       2015-04-12 22:12:50.000000000 +0000
5702 +++ linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/inode.h   2016-07-05 04:41:47.000000000 +0000
5703 @@ -161,6 +161,7 @@ struct buffer_head *ocfs2_bread(struct i
5704  
5705  void ocfs2_set_inode_flags(struct inode *inode);
5706  void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi);
5707 +int ocfs2_sync_flags(struct inode *inode, int, int);
5708  
5709  static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode)
5710  {
5711 diff -NurpP --minimal linux-4.1.41/fs/ocfs2/ioctl.c linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/ioctl.c
5712 --- linux-4.1.41/fs/ocfs2/ioctl.c       2015-04-12 22:12:50.000000000 +0000
5713 +++ linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/ioctl.c   2016-07-05 04:41:47.000000000 +0000
5714 @@ -76,7 +76,41 @@ static int ocfs2_get_inode_attr(struct i
5715         return status;
5716  }
5717  
5718 -static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
5719 +int ocfs2_sync_flags(struct inode *inode, int flags, int vflags)
5720 +{
5721 +       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
5722 +       struct buffer_head *bh = NULL;
5723 +       handle_t *handle = NULL;
5724 +       int status;
5725 +
5726 +       status = ocfs2_inode_lock(inode, &bh, 1);
5727 +       if (status < 0) {
5728 +               mlog_errno(status);
5729 +               return status;
5730 +       }
5731 +       handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
5732 +       if (IS_ERR(handle)) {
5733 +               status = PTR_ERR(handle);
5734 +               mlog_errno(status);
5735 +               goto bail_unlock;
5736 +       }
5737 +
5738 +       inode->i_flags = flags;
5739 +       inode->i_vflags = vflags;
5740 +       ocfs2_get_inode_flags(OCFS2_I(inode));
5741 +
5742 +       status = ocfs2_mark_inode_dirty(handle, inode, bh);
5743 +       if (status < 0)
5744 +               mlog_errno(status);
5745 +
5746 +       ocfs2_commit_trans(osb, handle);
5747 +bail_unlock:
5748 +       ocfs2_inode_unlock(inode, 1);
5749 +       brelse(bh);
5750 +       return status;
5751 +}
5752 +
5753 +int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
5754                                 unsigned mask)
5755  {
5756         struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
5757 @@ -116,6 +150,11 @@ static int ocfs2_set_inode_attr(struct i
5758                         goto bail_unlock;
5759         }
5760  
5761 +       if (IS_BARRIER(inode)) {
5762 +               vxwprintk_task(1, "messing with the barrier.");
5763 +               goto bail_unlock;
5764 +       }
5765 +
5766         handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
5767         if (IS_ERR(handle)) {
5768                 status = PTR_ERR(handle);
5769 @@ -841,6 +880,7 @@ bail:
5770         return status;
5771  }
5772  
5773 +
5774  long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
5775  {
5776         struct inode *inode = file_inode(filp);
5777 diff -NurpP --minimal linux-4.1.41/fs/ocfs2/namei.c linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/namei.c
5778 --- linux-4.1.41/fs/ocfs2/namei.c       2017-06-23 10:04:00.000000000 +0000
5779 +++ linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/namei.c   2016-07-05 04:41:47.000000000 +0000
5780 @@ -41,6 +41,7 @@
5781  #include <linux/slab.h>
5782  #include <linux/highmem.h>
5783  #include <linux/quotaops.h>
5784 +#include <linux/vs_tag.h>
5785  
5786  #include <cluster/masklog.h>
5787  
5788 @@ -509,6 +510,7 @@ static int __ocfs2_mknod_locked(struct i
5789         struct ocfs2_extent_list *fel;
5790         u16 feat;
5791         struct ocfs2_inode_info *oi = OCFS2_I(inode);
5792 +       ktag_t ktag;
5793  
5794         *new_fe_bh = NULL;
5795  
5796 @@ -546,8 +548,13 @@ static int __ocfs2_mknod_locked(struct i
5797         fe->i_suballoc_loc = cpu_to_le64(suballoc_loc);
5798         fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
5799         fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
5800 -       fe->i_uid = cpu_to_le32(i_uid_read(inode));
5801 -       fe->i_gid = cpu_to_le32(i_gid_read(inode));
5802 +
5803 +       ktag = make_ktag(&init_user_ns, dx_current_fstag(osb->sb));
5804 +       fe->i_uid = cpu_to_le32(from_kuid(&init_user_ns,
5805 +               TAGINO_KUID(DX_TAG(inode), inode->i_uid, ktag)));
5806 +       fe->i_gid = cpu_to_le32(from_kgid(&init_user_ns,
5807 +               TAGINO_KGID(DX_TAG(inode), inode->i_gid, ktag)));
5808 +       inode->i_tag = ktag; /* is this correct? */
5809         fe->i_mode = cpu_to_le16(inode->i_mode);
5810         if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
5811                 fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
5812 diff -NurpP --minimal linux-4.1.41/fs/ocfs2/ocfs2.h linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/ocfs2.h
5813 --- linux-4.1.41/fs/ocfs2/ocfs2.h       2015-04-12 22:12:50.000000000 +0000
5814 +++ linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/ocfs2.h   2016-07-05 04:41:47.000000000 +0000
5815 @@ -286,6 +286,7 @@ enum ocfs2_mount_options
5816         OCFS2_MOUNT_HB_GLOBAL = 1 << 14, /* Global heartbeat */
5817  
5818         OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT = 1 << 15,  /* Journal Async Commit */
5819 +       OCFS2_MOUNT_TAGGED = 1 << 16, /* use tagging */
5820  };
5821  
5822  #define OCFS2_OSB_SOFT_RO      0x0001
5823 diff -NurpP --minimal linux-4.1.41/fs/ocfs2/ocfs2_fs.h linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/ocfs2_fs.h
5824 --- linux-4.1.41/fs/ocfs2/ocfs2_fs.h    2015-04-12 22:12:50.000000000 +0000
5825 +++ linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/ocfs2_fs.h        2016-07-05 04:41:47.000000000 +0000
5826 @@ -275,6 +275,11 @@
5827  #define OCFS2_TOPDIR_FL                        FS_TOPDIR_FL    /* Top of directory hierarchies*/
5828  #define OCFS2_RESERVED_FL              FS_RESERVED_FL  /* reserved for ext2 lib */
5829  
5830 +#define OCFS2_IXUNLINK_FL              FS_IXUNLINK_FL  /* Immutable invert on unlink */
5831 +
5832 +#define OCFS2_BARRIER_FL               FS_BARRIER_FL   /* Barrier for chroot() */
5833 +#define OCFS2_COW_FL                   FS_COW_FL       /* Copy on Write marker */
5834 +
5835  #define OCFS2_FL_VISIBLE               FS_FL_USER_VISIBLE      /* User visible flags */
5836  #define OCFS2_FL_MODIFIABLE            FS_FL_USER_MODIFIABLE   /* User modifiable flags */
5837  
5838 diff -NurpP --minimal linux-4.1.41/fs/ocfs2/super.c linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/super.c
5839 --- linux-4.1.41/fs/ocfs2/super.c       2017-06-23 10:04:00.000000000 +0000
5840 +++ linux-4.1.41-vs2.3.8.5.3/fs/ocfs2/super.c   2016-07-05 04:41:47.000000000 +0000
5841 @@ -192,6 +192,7 @@ enum {
5842         Opt_resv_level,
5843         Opt_dir_resv_level,
5844         Opt_journal_async_commit,
5845 +       Opt_tag, Opt_notag, Opt_tagid,
5846         Opt_err,
5847  };
5848  
5849 @@ -224,6 +225,9 @@ static const match_table_t tokens = {
5850         {Opt_resv_level, "resv_level=%u"},
5851         {Opt_dir_resv_level, "dir_resv_level=%u"},
5852         {Opt_journal_async_commit, "journal_async_commit"},
5853 +       {Opt_tag, "tag"},
5854 +       {Opt_notag, "notag"},
5855 +       {Opt_tagid, "tagid=%u"},
5856         {Opt_err, NULL}
5857  };
5858  
5859 @@ -675,6 +679,13 @@ static int ocfs2_remount(struct super_bl
5860                 goto out;
5861         }
5862  
5863 +       if ((osb->s_mount_opt & OCFS2_MOUNT_TAGGED) !=
5864 +           (parsed_options.mount_opt & OCFS2_MOUNT_TAGGED)) {
5865 +               ret = -EINVAL;
5866 +               mlog(ML_ERROR, "Cannot change tagging on remount\n");
5867 +               goto out;
5868 +       }
5869 +
5870         /* We're going to/from readonly mode. */
5871         if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
5872                 /* Disable quota accounting before remounting RO */
5873 @@ -1164,6 +1175,9 @@ static int ocfs2_fill_super(struct super
5874  
5875         ocfs2_complete_mount_recovery(osb);
5876  
5877 +       if (osb->s_mount_opt & OCFS2_MOUNT_TAGGED)
5878 +               sb->s_flags |= MS_TAGGED;
5879 +
5880         if (ocfs2_mount_local(osb))
5881                 snprintf(nodestr, sizeof(nodestr), "local");
5882         else
5883 @@ -1475,6 +1489,20 @@ static int ocfs2_parse_options(struct su
5884                 case Opt_journal_async_commit:
5885                         mopt->mount_opt |= OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT;
5886                         break;
5887 +#ifndef CONFIG_TAGGING_NONE
5888 +               case Opt_tag:
5889 +                       mopt->mount_opt |= OCFS2_MOUNT_TAGGED;
5890 +                       break;
5891 +               case Opt_notag:
5892 +                       mopt->mount_opt &= ~OCFS2_MOUNT_TAGGED;
5893 +                       break;
5894 +#endif
5895 +#ifdef CONFIG_PROPAGATE
5896 +               case Opt_tagid:
5897 +                       /* use args[0] */
5898 +                       mopt->mount_opt |= OCFS2_MOUNT_TAGGED;
5899 +                       break;
5900 +#endif
5901                 default:
5902                         mlog(ML_ERROR,
5903                              "Unrecognized mount option \"%s\" "
5904 diff -NurpP --minimal linux-4.1.41/fs/open.c linux-4.1.41-vs2.3.8.5.3/fs/open.c
5905 --- linux-4.1.41/fs/open.c      2017-06-23 10:04:00.000000000 +0000
5906 +++ linux-4.1.41-vs2.3.8.5.3/fs/open.c  2016-07-05 05:07:17.000000000 +0000
5907 @@ -31,6 +31,11 @@
5908  #include <linux/ima.h>
5909  #include <linux/dnotify.h>
5910  #include <linux/compat.h>
5911 +#include <linux/vs_base.h>
5912 +#include <linux/vs_limit.h>
5913 +#include <linux/vs_tag.h>
5914 +#include <linux/vs_cowbl.h>
5915 +#include <linux/vserver/dlimit.h>
5916  
5917  #include "internal.h"
5918  
5919 @@ -68,6 +73,11 @@ long vfs_truncate(struct path *path, lof
5920         struct inode *inode;
5921         long error;
5922  
5923 +#ifdef CONFIG_VSERVER_COWBL
5924 +       error = cow_check_and_break(path);
5925 +       if (error)
5926 +               goto out;
5927 +#endif
5928         inode = path->dentry->d_inode;
5929  
5930         /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
5931 @@ -546,6 +556,13 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
5932         unsigned int lookup_flags = LOOKUP_FOLLOW;
5933  retry:
5934         error = user_path_at(dfd, filename, lookup_flags, &path);
5935 +#ifdef CONFIG_VSERVER_COWBL
5936 +       if (!error) {
5937 +               error = cow_check_and_break(&path);
5938 +               if (error)
5939 +                       path_put(&path);
5940 +       }
5941 +#endif
5942         if (!error) {
5943                 error = chmod_common(&path, mode);
5944                 path_put(&path);
5945 @@ -580,13 +597,15 @@ retry_deleg:
5946                 if (!uid_valid(uid))
5947                         return -EINVAL;
5948                 newattrs.ia_valid |= ATTR_UID;
5949 -               newattrs.ia_uid = uid;
5950 +               newattrs.ia_uid = make_kuid(&init_user_ns,
5951 +                       dx_map_uid(user));
5952         }
5953         if (group != (gid_t) -1) {
5954                 if (!gid_valid(gid))
5955                         return -EINVAL;
5956                 newattrs.ia_valid |= ATTR_GID;
5957 -               newattrs.ia_gid = gid;
5958 +               newattrs.ia_gid = make_kgid(&init_user_ns,
5959 +                       dx_map_gid(group));
5960         }
5961         if (!S_ISDIR(inode->i_mode))
5962                 newattrs.ia_valid |=
5963 @@ -624,6 +643,10 @@ retry:
5964         error = mnt_want_write(path.mnt);
5965         if (error)
5966                 goto out_release;
5967 +#ifdef CONFIG_VSERVER_COWBL
5968 +       error = cow_check_and_break(&path);
5969 +       if (!error)
5970 +#endif
5971         error = chown_common(&path, user, group);
5972         mnt_drop_write(path.mnt);
5973  out_release:
5974 diff -NurpP --minimal linux-4.1.41/fs/proc/array.c linux-4.1.41-vs2.3.8.5.3/fs/proc/array.c
5975 --- linux-4.1.41/fs/proc/array.c        2017-06-23 10:04:00.000000000 +0000
5976 +++ linux-4.1.41-vs2.3.8.5.3/fs/proc/array.c    2016-07-05 04:41:47.000000000 +0000
5977 @@ -83,6 +83,8 @@
5978  #include <linux/tracehook.h>
5979  #include <linux/string_helpers.h>
5980  #include <linux/user_namespace.h>
5981 +#include <linux/vs_context.h>
5982 +#include <linux/vs_network.h>
5983  
5984  #include <asm/pgtable.h>
5985  #include <asm/processor.h>
5986 @@ -146,6 +148,9 @@ static inline void task_state(struct seq
5987         ppid = pid_alive(p) ?
5988                 task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
5989  
5990 +       if (unlikely(vx_current_initpid(p->pid)))
5991 +               ppid = 0;
5992 +
5993         tracer = ptrace_parent(p);
5994         if (tracer)
5995                 tpid = task_pid_nr_ns(tracer, ns);
5996 @@ -284,8 +289,8 @@ static inline void task_sig(struct seq_f
5997         render_sigset_t(m, "SigCgt:\t", &caught);
5998  }
5999  
6000 -static void render_cap_t(struct seq_file *m, const char *header,
6001 -                       kernel_cap_t *a)
6002 +void render_cap_t(struct seq_file *m, const char *header,
6003 +                       struct vx_info *vxi, kernel_cap_t *a)
6004  {
6005         unsigned __capi;
6006  
6007 @@ -310,10 +315,11 @@ static inline void task_cap(struct seq_f
6008         cap_bset        = cred->cap_bset;
6009         rcu_read_unlock();
6010  
6011 -       render_cap_t(m, "CapInh:\t", &cap_inheritable);
6012 -       render_cap_t(m, "CapPrm:\t", &cap_permitted);
6013 -       render_cap_t(m, "CapEff:\t", &cap_effective);
6014 -       render_cap_t(m, "CapBnd:\t", &cap_bset);
6015 +       /* FIXME: maybe move the p->vx_info masking to __task_cred() ? */
6016 +       render_cap_t(m, "CapInh:\t", p->vx_info, &cap_inheritable);
6017 +       render_cap_t(m, "CapPrm:\t", p->vx_info, &cap_permitted);
6018 +       render_cap_t(m, "CapEff:\t", p->vx_info, &cap_effective);
6019 +       render_cap_t(m, "CapBnd:\t", p->vx_info, &cap_bset);
6020  }
6021  
6022  static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
6023 @@ -340,6 +346,43 @@ static void task_cpus_allowed(struct seq
6024                    cpumask_pr_args(&task->cpus_allowed));
6025  }
6026  
6027 +int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
6028 +                       struct pid *pid, struct task_struct *task)
6029 +{
6030 +       seq_printf(m,   "Proxy:\t%p(%c)\n"
6031 +                       "Count:\t%u\n"
6032 +                       "uts:\t%p(%c)\n"
6033 +                       "ipc:\t%p(%c)\n"
6034 +                       "mnt:\t%p(%c)\n"
6035 +                       "pid:\t%p(%c)\n"
6036 +                       "net:\t%p(%c)\n",
6037 +                       task->nsproxy,
6038 +                       (task->nsproxy == init_task.nsproxy ? 'I' : '-'),
6039 +                       atomic_read(&task->nsproxy->count),
6040 +                       task->nsproxy->uts_ns,
6041 +                       (task->nsproxy->uts_ns == init_task.nsproxy->uts_ns ? 'I' : '-'),
6042 +                       task->nsproxy->ipc_ns,
6043 +                       (task->nsproxy->ipc_ns == init_task.nsproxy->ipc_ns ? 'I' : '-'),
6044 +                       task->nsproxy->mnt_ns,
6045 +                       (task->nsproxy->mnt_ns == init_task.nsproxy->mnt_ns ? 'I' : '-'),
6046 +                       task->nsproxy->pid_ns_for_children,
6047 +                       (task->nsproxy->pid_ns_for_children ==
6048 +                               init_task.nsproxy->pid_ns_for_children ? 'I' : '-'),
6049 +                       task->nsproxy->net_ns,
6050 +                       (task->nsproxy->net_ns == init_task.nsproxy->net_ns ? 'I' : '-'));
6051 +       return 0;
6052 +}
6053 +
6054 +void task_vs_id(struct seq_file *m, struct task_struct *task)
6055 +{
6056 +       if (task_vx_flags(task, VXF_HIDE_VINFO, 0))
6057 +               return;
6058 +
6059 +       seq_printf(m, "VxID:\t%d\n", vx_task_xid(task));
6060 +       seq_printf(m, "NxID:\t%d\n", nx_task_nid(task));
6061 +}
6062 +
6063 +
6064  int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
6065                         struct pid *pid, struct task_struct *task)
6066  {
6067 @@ -357,6 +400,7 @@ int proc_pid_status(struct seq_file *m,
6068         task_seccomp(m, task);
6069         task_cpus_allowed(m, task);
6070         cpuset_task_status_allowed(m, task);
6071 +       task_vs_id(m, task);
6072         task_context_switch_counts(m, task);
6073         return 0;
6074  }
6075 @@ -460,6 +504,17 @@ static int do_task_stat(struct seq_file
6076         /* convert nsec -> ticks */
6077         start_time = nsec_to_clock_t(task->real_start_time);
6078  
6079 +       /* fixup start time for virt uptime */
6080 +       if (vx_flags(VXF_VIRT_UPTIME, 0)) {
6081 +               unsigned long long bias =
6082 +                       current->vx_info->cvirt.bias_clock;
6083 +
6084 +               if (start_time > bias)
6085 +                       start_time -= bias;
6086 +               else
6087 +                       start_time = 0;
6088 +       }
6089 +
6090         seq_printf(m, "%d (%s) %c", pid_nr_ns(pid, ns), tcomm, state);
6091         seq_put_decimal_ll(m, ' ', ppid);
6092         seq_put_decimal_ll(m, ' ', pgid);
6093 diff -NurpP --minimal linux-4.1.41/fs/proc/base.c linux-4.1.41-vs2.3.8.5.3/fs/proc/base.c
6094 --- linux-4.1.41/fs/proc/base.c 2017-06-23 10:04:00.000000000 +0000
6095 +++ linux-4.1.41-vs2.3.8.5.3/fs/proc/base.c     2017-05-30 07:39:23.000000000 +0000
6096 @@ -87,6 +87,8 @@
6097  #include <linux/slab.h>
6098  #include <linux/flex_array.h>
6099  #include <linux/posix-timers.h>
6100 +#include <linux/vs_context.h>
6101 +#include <linux/vs_network.h>
6102  #ifdef CONFIG_HARDWALL
6103  #include <asm/hardwall.h>
6104  #endif
6105 @@ -892,11 +894,15 @@ static ssize_t oom_adj_write(struct file
6106                 oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
6107  
6108         if (oom_adj < task->signal->oom_score_adj &&
6109 -           !capable(CAP_SYS_RESOURCE)) {
6110 +           !vx_capable(CAP_SYS_RESOURCE, VXC_OOM_ADJUST)) {
6111                 err = -EACCES;
6112                 goto err_sighand;
6113         }
6114  
6115 +       /* prevent guest processes from circumventing the oom killer */
6116 +       if (vx_current_xid() && (oom_adj == OOM_DISABLE))
6117 +               oom_adj = OOM_ADJUST_MIN;
6118 +
6119         /*
6120          * /proc/pid/oom_adj is provided for legacy purposes, ask users to use
6121          * /proc/pid/oom_score_adj instead.
6122 @@ -1484,6 +1490,8 @@ struct inode *proc_pid_make_inode(struct
6123                 inode->i_gid = cred->egid;
6124                 rcu_read_unlock();
6125         }
6126 +       /* procfs is xid tagged */
6127 +       i_tag_write(inode, (vtag_t)vx_task_xid(task));
6128         security_task_to_inode(task, inode);
6129  
6130  out:
6131 @@ -1529,6 +1537,8 @@ int pid_getattr(struct vfsmount *mnt, st
6132  
6133  /* dentry stuff */
6134  
6135 +// static unsigned name_to_int(struct dentry *dentry);
6136 +
6137  /*
6138   *     Exceptional case: normally we are not allowed to unhash a busy
6139   * directory. In this case, however, we can do it - no aliasing problems
6140 @@ -1557,6 +1567,19 @@ int pid_revalidate(struct dentry *dentry
6141         task = get_proc_task(inode);
6142  
6143         if (task) {
6144 +               unsigned pid = name_to_int(&dentry->d_name);
6145 +
6146 +               if (pid != ~0U && pid != vx_map_pid(task->pid) &&
6147 +                       pid != __task_pid_nr_ns(task, PIDTYPE_PID,
6148 +                               task_active_pid_ns(task))) {
6149 +                       vxdprintk(VXD_CBIT(misc, 10),
6150 +                               VS_Q("%*s") " dropped by pid_revalidate(%d!=%d)",
6151 +                               dentry->d_name.len, dentry->d_name.name,
6152 +                               pid, vx_map_pid(task->pid));
6153 +                       put_task_struct(task);
6154 +                       d_drop(dentry);
6155 +                       return 0;
6156 +               }
6157                 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
6158                     task_dumpable(task)) {
6159                         rcu_read_lock();
6160 @@ -2094,6 +2117,13 @@ static struct dentry *proc_pident_lookup
6161         if (!task)
6162                 goto out_no_task;
6163  
6164 +       /* TODO: maybe we can come up with a generic approach? */
6165 +       if (task_vx_flags(task, VXF_HIDE_VINFO, 0) &&
6166 +               (dentry->d_name.len == 5) &&
6167 +               (!memcmp(dentry->d_name.name, "vinfo", 5) ||
6168 +               !memcmp(dentry->d_name.name, "ninfo", 5)))
6169 +               goto out;
6170 +
6171         /*
6172          * Yes, it does not scale. And it should not. Don't add
6173          * new entries into /proc/<tgid>/ without very good reasons.
6174 @@ -2545,6 +2575,11 @@ static int proc_pid_personality(struct s
6175  static const struct file_operations proc_task_operations;
6176  static const struct inode_operations proc_task_inode_operations;
6177  
6178 +extern int proc_pid_vx_info(struct seq_file *,
6179 +       struct pid_namespace *, struct pid *, struct task_struct *);
6180 +extern int proc_pid_nx_info(struct seq_file *,
6181 +       struct pid_namespace *, struct pid *, struct task_struct *);
6182 +
6183  static const struct pid_entry tgid_base_stuff[] = {
6184         DIR("task",       S_IRUGO|S_IXUGO, proc_task_inode_operations, proc_task_operations),
6185         DIR("fd",         S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
6186 @@ -2611,6 +2646,8 @@ static const struct pid_entry tgid_base_
6187  #ifdef CONFIG_CGROUPS
6188         ONE("cgroup",  S_IRUGO, proc_cgroup_show),
6189  #endif
6190 +       ONE("vinfo",      S_IRUGO, proc_pid_vx_info),
6191 +       ONE("ninfo",      S_IRUGO, proc_pid_nx_info),
6192         ONE("oom_score",  S_IRUGO, proc_oom_score),
6193         REG("oom_adj",    S_IRUGO|S_IWUSR, proc_oom_adj_operations),
6194         REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
6195 @@ -2825,7 +2862,7 @@ retry:
6196         iter.task = NULL;
6197         pid = find_ge_pid(iter.tgid, ns);
6198         if (pid) {
6199 -               iter.tgid = pid_nr_ns(pid, ns);
6200 +               iter.tgid = pid_unmapped_nr_ns(pid, ns);
6201                 iter.task = pid_task(pid, PIDTYPE_PID);
6202                 /* What we to know is if the pid we have find is the
6203                  * pid of a thread_group_leader.  Testing for task
6204 @@ -2883,8 +2920,10 @@ int proc_pid_readdir(struct file *file,
6205                 if (!has_pid_permissions(ns, iter.task, 2))
6206                         continue;
6207  
6208 -               len = snprintf(name, sizeof(name), "%d", iter.tgid);
6209 +               len = snprintf(name, sizeof(name), "%d", vx_map_tgid(iter.tgid));
6210                 ctx->pos = iter.tgid + TGID_OFFSET;
6211 +               if (!vx_proc_task_visible(iter.task))
6212 +                       continue;
6213                 if (!proc_fill_cache(file, ctx, name, len,
6214                                      proc_pid_instantiate, iter.task, NULL)) {
6215                         put_task_struct(iter.task);
6216 @@ -2981,6 +3020,7 @@ static const struct pid_entry tid_base_s
6217         REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
6218         REG("setgroups",  S_IRUGO|S_IWUSR, proc_setgroups_operations),
6219  #endif
6220 +       ONE("nsproxy",  S_IRUGO, proc_pid_nsproxy),
6221  };
6222  
6223  static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)
6224 @@ -3047,6 +3087,8 @@ static struct dentry *proc_task_lookup(s
6225         tid = name_to_int(&dentry->d_name);
6226         if (tid == ~0U)
6227                 goto out;
6228 +       if (vx_current_initpid(tid))
6229 +               goto out;
6230  
6231         ns = dentry->d_sb->s_fs_info;
6232         rcu_read_lock();
6233 diff -NurpP --minimal linux-4.1.41/fs/proc/generic.c linux-4.1.41-vs2.3.8.5.3/fs/proc/generic.c
6234 --- linux-4.1.41/fs/proc/generic.c      2017-06-23 10:04:00.000000000 +0000
6235 +++ linux-4.1.41-vs2.3.8.5.3/fs/proc/generic.c  2017-05-30 07:39:23.000000000 +0000
6236 @@ -22,6 +22,7 @@
6237  #include <linux/bitops.h>
6238  #include <linux/spinlock.h>
6239  #include <linux/completion.h>
6240 +#include <linux/vserver/inode.h>
6241  #include <asm/uaccess.h>
6242  
6243  #include "internal.h"
6244 @@ -66,8 +67,16 @@ static struct proc_dir_entry *pde_subdir
6245                         node = node->rb_left;
6246                 else if (result > 0)
6247                         node = node->rb_right;
6248 -               else
6249 +               else {
6250 +                       if (!vx_hide_check(0, de->vx_flags)) {
6251 +                               vxdprintk(VXD_CBIT(misc, 9),
6252 +                                       VS_Q("%*s")
6253 +                                       " hidden in pde_subdir_find()",
6254 +                                       de->namelen, de->name);
6255 +                               return 0;
6256 +                       }
6257                         return de;
6258 +               }
6259         }
6260         return NULL;
6261  }
6262 @@ -241,6 +250,8 @@ struct dentry *proc_lookup_de(struct pro
6263                         return ERR_PTR(-ENOMEM);
6264                 d_set_d_op(dentry, &simple_dentry_operations);
6265                 d_add(dentry, inode);
6266 +                       /* generic proc entries belong to the host */
6267 +                       i_tag_write(inode, 0);
6268                 return NULL;
6269         }
6270         spin_unlock(&proc_subdir_lock);
6271 @@ -287,6 +298,13 @@ int proc_readdir_de(struct proc_dir_entr
6272         do {
6273                 struct proc_dir_entry *next;
6274                 pde_get(de);
6275 +
6276 +               if (!vx_hide_check(0, de->vx_flags)) {
6277 +                       vxdprintk(VXD_CBIT(misc, 9),
6278 +                               VS_Q("%*s") " hidden in proc_readdir_de()",
6279 +                               de->namelen, de->name);
6280 +                       goto skip;
6281 +               }
6282                 spin_unlock(&proc_subdir_lock);
6283                 if (!dir_emit(ctx, de->name, de->namelen,
6284                             de->low_ino, de->mode >> 12)) {
6285 @@ -294,6 +312,7 @@ int proc_readdir_de(struct proc_dir_entr
6286                         return 0;
6287                 }
6288                 spin_lock(&proc_subdir_lock);
6289 +       skip:
6290                 ctx->pos++;
6291                 next = pde_subdir_next(de);
6292                 pde_put(de);
6293 @@ -387,6 +406,7 @@ static struct proc_dir_entry *__proc_cre
6294         ent->mode = mode;
6295         ent->nlink = nlink;
6296         ent->subdir = RB_ROOT;
6297 +       ent->vx_flags = IATTR_PROC_DEFAULT;
6298         atomic_set(&ent->count, 1);
6299         spin_lock_init(&ent->pde_unload_lock);
6300         INIT_LIST_HEAD(&ent->pde_openers);
6301 @@ -411,7 +431,8 @@ struct proc_dir_entry *proc_symlink(cons
6302                                 kfree(ent->data);
6303                                 kfree(ent);
6304                                 ent = NULL;
6305 -                       }
6306 +                       } else
6307 +                               ent->vx_flags = IATTR_PROC_SYMLINK;
6308                 } else {
6309                         kfree(ent);
6310                         ent = NULL;
6311 diff -NurpP --minimal linux-4.1.41/fs/proc/inode.c linux-4.1.41-vs2.3.8.5.3/fs/proc/inode.c
6312 --- linux-4.1.41/fs/proc/inode.c        2017-06-23 10:04:00.000000000 +0000
6313 +++ linux-4.1.41-vs2.3.8.5.3/fs/proc/inode.c    2016-07-05 04:41:47.000000000 +0000
6314 @@ -432,6 +432,8 @@ struct inode *proc_get_inode(struct supe
6315                         inode->i_uid = de->uid;
6316                         inode->i_gid = de->gid;
6317                 }
6318 +               if (de->vx_flags)
6319 +                       PROC_I(inode)->vx_flags = de->vx_flags;
6320                 if (de->size)
6321                         inode->i_size = de->size;
6322                 if (de->nlink)
6323 diff -NurpP --minimal linux-4.1.41/fs/proc/internal.h linux-4.1.41-vs2.3.8.5.3/fs/proc/internal.h
6324 --- linux-4.1.41/fs/proc/internal.h     2017-06-23 10:04:00.000000000 +0000
6325 +++ linux-4.1.41-vs2.3.8.5.3/fs/proc/internal.h 2016-07-05 04:41:47.000000000 +0000
6326 @@ -14,6 +14,7 @@
6327  #include <linux/spinlock.h>
6328  #include <linux/atomic.h>
6329  #include <linux/binfmts.h>
6330 +#include <linux/vs_pid.h>
6331  
6332  struct ctl_table_header;
6333  struct mempolicy;
6334 @@ -34,6 +35,7 @@ struct proc_dir_entry {
6335         nlink_t nlink;
6336         kuid_t uid;
6337         kgid_t gid;
6338 +       int vx_flags;
6339         loff_t size;
6340         const struct inode_operations *proc_iops;
6341         const struct file_operations *proc_fops;
6342 @@ -51,15 +53,22 @@ struct proc_dir_entry {
6343         char name[];
6344  };
6345  
6346 +struct vx_info;
6347 +struct nx_info;
6348 +
6349  union proc_op {
6350         int (*proc_get_link)(struct dentry *, struct path *);
6351         int (*proc_show)(struct seq_file *m,
6352                 struct pid_namespace *ns, struct pid *pid,
6353                 struct task_struct *task);
6354 +       int (*proc_vs_read)(char *page);
6355 +       int (*proc_vxi_read)(struct vx_info *vxi, char *page);
6356 +       int (*proc_nxi_read)(struct nx_info *nxi, char *page);
6357  };
6358  
6359  struct proc_inode {
6360         struct pid *pid;
6361 +       int vx_flags;
6362         int fd;
6363         union proc_op op;
6364         struct proc_dir_entry *pde;
6365 @@ -92,11 +101,16 @@ static inline struct pid *proc_pid(struc
6366         return PROC_I(inode)->pid;
6367  }
6368  
6369 -static inline struct task_struct *get_proc_task(struct inode *inode)
6370 +static inline struct task_struct *get_proc_task_real(struct inode *inode)
6371  {
6372         return get_pid_task(proc_pid(inode), PIDTYPE_PID);
6373  }
6374  
6375 +static inline struct task_struct *get_proc_task(struct inode *inode)
6376 +{
6377 +       return vx_get_proc_task(inode, proc_pid(inode));
6378 +}
6379 +
6380  static inline int task_dumpable(struct task_struct *task)
6381  {
6382         int dumpable = 0;
6383 @@ -155,6 +169,8 @@ extern int proc_pid_status(struct seq_fi
6384                            struct pid *, struct task_struct *);
6385  extern int proc_pid_statm(struct seq_file *, struct pid_namespace *,
6386                           struct pid *, struct task_struct *);
6387 +extern int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
6388 +                           struct pid *pid, struct task_struct *task);
6389  
6390  /*
6391   * base.c
6392 diff -NurpP --minimal linux-4.1.41/fs/proc/loadavg.c linux-4.1.41-vs2.3.8.5.3/fs/proc/loadavg.c
6393 --- linux-4.1.41/fs/proc/loadavg.c      2015-04-12 22:12:50.000000000 +0000
6394 +++ linux-4.1.41-vs2.3.8.5.3/fs/proc/loadavg.c  2016-07-05 04:41:47.000000000 +0000
6395 @@ -12,15 +12,27 @@
6396  
6397  static int loadavg_proc_show(struct seq_file *m, void *v)
6398  {
6399 +       unsigned long running;
6400 +       unsigned int threads;
6401         unsigned long avnrun[3];
6402  
6403         get_avenrun(avnrun, FIXED_1/200, 0);
6404  
6405 +       if (vx_flags(VXF_VIRT_LOAD, 0)) {
6406 +               struct vx_info *vxi = current_vx_info();
6407 +
6408 +               running = atomic_read(&vxi->cvirt.nr_running);
6409 +               threads = atomic_read(&vxi->cvirt.nr_threads);
6410 +       } else {
6411 +               running = nr_running();
6412 +               threads = nr_threads;
6413 +       }
6414 +
6415         seq_printf(m, "%lu.%02lu %lu.%02lu %lu.%02lu %ld/%d %d\n",
6416                 LOAD_INT(avnrun[0]), LOAD_FRAC(avnrun[0]),
6417                 LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
6418                 LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
6419 -               nr_running(), nr_threads,
6420 +               running, threads,
6421                 task_active_pid_ns(current)->last_pid);
6422         return 0;
6423  }
6424 diff -NurpP --minimal linux-4.1.41/fs/proc/meminfo.c linux-4.1.41-vs2.3.8.5.3/fs/proc/meminfo.c
6425 --- linux-4.1.41/fs/proc/meminfo.c      2015-04-12 22:12:50.000000000 +0000
6426 +++ linux-4.1.41-vs2.3.8.5.3/fs/proc/meminfo.c  2016-07-05 04:41:47.000000000 +0000
6427 @@ -44,7 +44,8 @@ static int meminfo_proc_show(struct seq_
6428         si_swapinfo(&i);
6429         committed = percpu_counter_read_positive(&vm_committed_as);
6430  
6431 -       cached = global_page_state(NR_FILE_PAGES) -
6432 +       cached = vx_flags(VXF_VIRT_MEM, 0) ?
6433 +               vx_vsi_cached(&i) : global_page_state(NR_FILE_PAGES) -
6434                         total_swapcache_pages() - i.bufferram;
6435         if (cached < 0)
6436                 cached = 0;
6437 diff -NurpP --minimal linux-4.1.41/fs/proc/root.c linux-4.1.41-vs2.3.8.5.3/fs/proc/root.c
6438 --- linux-4.1.41/fs/proc/root.c 2017-06-23 10:04:00.000000000 +0000
6439 +++ linux-4.1.41-vs2.3.8.5.3/fs/proc/root.c     2016-07-05 04:41:47.000000000 +0000
6440 @@ -20,9 +20,14 @@
6441  #include <linux/mount.h>
6442  #include <linux/pid_namespace.h>
6443  #include <linux/parser.h>
6444 +#include <linux/vserver/inode.h>
6445  
6446  #include "internal.h"
6447  
6448 +struct proc_dir_entry *proc_virtual;
6449 +
6450 +extern void proc_vx_init(void);
6451 +
6452  static int proc_test_super(struct super_block *sb, void *data)
6453  {
6454         return sb->s_fs_info == data;
6455 @@ -113,7 +118,8 @@ static struct dentry *proc_mount(struct
6456                 options = data;
6457  
6458                 /* Does the mounter have privilege over the pid namespace? */
6459 -               if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
6460 +               if (!vx_ns_capable(ns->user_ns,
6461 +                       CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
6462                         return ERR_PTR(-EPERM);
6463         }
6464  
6465 @@ -194,6 +200,7 @@ void __init proc_root_init(void)
6466         proc_tty_init();
6467         proc_mkdir("bus", NULL);
6468         proc_sys_init();
6469 +       proc_vx_init();
6470  }
6471  
6472  static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
6473 @@ -255,6 +262,7 @@ struct proc_dir_entry proc_root = {
6474         .proc_iops      = &proc_root_inode_operations, 
6475         .proc_fops      = &proc_root_operations,
6476         .parent         = &proc_root,
6477 +       .vx_flags       = IATTR_ADMIN | IATTR_WATCH,
6478         .subdir         = RB_ROOT,
6479         .name           = "/proc",
6480  };
6481 diff -NurpP --minimal linux-4.1.41/fs/proc/self.c linux-4.1.41-vs2.3.8.5.3/fs/proc/self.c
6482 --- linux-4.1.41/fs/proc/self.c 2015-07-06 20:41:42.000000000 +0000
6483 +++ linux-4.1.41-vs2.3.8.5.3/fs/proc/self.c     2016-07-05 04:41:47.000000000 +0000
6484 @@ -2,6 +2,7 @@
6485  #include <linux/namei.h>
6486  #include <linux/slab.h>
6487  #include <linux/pid_namespace.h>
6488 +#include <linux/vserver/inode.h>
6489  #include "internal.h"
6490  
6491  /*
6492 @@ -54,6 +55,8 @@ int proc_setup_self(struct super_block *
6493         self = d_alloc_name(s->s_root, "self");
6494         if (self) {
6495                 struct inode *inode = new_inode_pseudo(s);
6496 +
6497 +               // self->vx_flags = IATTR_PROC_SYMLINK;
6498                 if (inode) {
6499                         inode->i_ino = self_inum;
6500                         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
6501 diff -NurpP --minimal linux-4.1.41/fs/proc/stat.c linux-4.1.41-vs2.3.8.5.3/fs/proc/stat.c
6502 --- linux-4.1.41/fs/proc/stat.c 2015-04-12 22:12:50.000000000 +0000
6503 +++ linux-4.1.41-vs2.3.8.5.3/fs/proc/stat.c     2016-07-05 04:41:47.000000000 +0000
6504 @@ -9,8 +9,10 @@
6505  #include <linux/slab.h>
6506  #include <linux/time.h>
6507  #include <linux/irqnr.h>
6508 +#include <linux/vserver/cvirt.h>
6509  #include <linux/cputime.h>
6510  #include <linux/tick.h>
6511 +#include <linux/cpuset.h>
6512  
6513  #ifndef arch_irq_stat_cpu
6514  #define arch_irq_stat_cpu(cpu) 0
6515 @@ -87,14 +89,26 @@ static int show_stat(struct seq_file *p,
6516         u64 sum_softirq = 0;
6517         unsigned int per_softirq_sums[NR_SOFTIRQS] = {0};
6518         struct timespec boottime;
6519 +       cpumask_var_t cpus_allowed;
6520 +       bool virt_cpu = vx_flags(VXF_VIRT_CPU, 0);
6521  
6522         user = nice = system = idle = iowait =
6523                 irq = softirq = steal = 0;
6524         guest = guest_nice = 0;
6525         getboottime(&boottime);
6526 +
6527 +       if (vx_flags(VXF_VIRT_UPTIME, 0))
6528 +               vx_vsi_boottime(&boottime);
6529 +
6530 +       if (virt_cpu)
6531 +               cpuset_cpus_allowed(current, cpus_allowed);
6532 +
6533         jif = boottime.tv_sec;
6534  
6535         for_each_possible_cpu(i) {
6536 +               if (virt_cpu && !cpumask_test_cpu(i, cpus_allowed))
6537 +                       continue;
6538 +
6539                 user += kcpustat_cpu(i).cpustat[CPUTIME_USER];
6540                 nice += kcpustat_cpu(i).cpustat[CPUTIME_NICE];
6541                 system += kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
6542 @@ -131,6 +145,9 @@ static int show_stat(struct seq_file *p,
6543         seq_putc(p, '\n');
6544  
6545         for_each_online_cpu(i) {
6546 +               if (virt_cpu && !cpumask_test_cpu(i, cpus_allowed))
6547 +                       continue;
6548 +
6549                 /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
6550                 user = kcpustat_cpu(i).cpustat[CPUTIME_USER];
6551                 nice = kcpustat_cpu(i).cpustat[CPUTIME_NICE];
6552 diff -NurpP --minimal linux-4.1.41/fs/proc/uptime.c linux-4.1.41-vs2.3.8.5.3/fs/proc/uptime.c
6553 --- linux-4.1.41/fs/proc/uptime.c       2015-04-12 22:12:50.000000000 +0000
6554 +++ linux-4.1.41-vs2.3.8.5.3/fs/proc/uptime.c   2016-07-05 04:41:47.000000000 +0000
6555 @@ -5,6 +5,7 @@
6556  #include <linux/seq_file.h>
6557  #include <linux/time.h>
6558  #include <linux/kernel_stat.h>
6559 +#include <linux/vserver/cvirt.h>
6560  #include <linux/cputime.h>
6561  
6562  static int uptime_proc_show(struct seq_file *m, void *v)
6563 @@ -24,6 +25,10 @@ static int uptime_proc_show(struct seq_f
6564         nsec = cputime64_to_jiffies64(idletime) * TICK_NSEC;
6565         idle.tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
6566         idle.tv_nsec = rem;
6567 +
6568 +       if (vx_flags(VXF_VIRT_UPTIME, 0))
6569 +               vx_vsi_uptime(&uptime, &idle);
6570 +
6571         seq_printf(m, "%lu.%02lu %lu.%02lu\n",
6572                         (unsigned long) uptime.tv_sec,
6573                         (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
6574 diff -NurpP --minimal linux-4.1.41/fs/proc_namespace.c linux-4.1.41-vs2.3.8.5.3/fs/proc_namespace.c
6575 --- linux-4.1.41/fs/proc_namespace.c    2017-06-23 10:04:00.000000000 +0000
6576 +++ linux-4.1.41-vs2.3.8.5.3/fs/proc_namespace.c        2016-07-05 04:41:47.000000000 +0000
6577 @@ -45,6 +45,8 @@ static int show_sb_opts(struct seq_file
6578                 { MS_DIRSYNC, ",dirsync" },
6579                 { MS_MANDLOCK, ",mand" },
6580                 { MS_LAZYTIME, ",lazytime" },
6581 +               { MS_TAGGED, ",tag" },
6582 +               { MS_NOTAGCHECK, ",notagcheck" },
6583                 { 0, NULL }
6584         };
6585         const struct proc_fs_info *fs_infop;
6586 @@ -81,6 +83,38 @@ static inline void mangle(struct seq_fil
6587         seq_escape(m, s, " \t\n\\");
6588  }
6589  
6590 +#ifdef CONFIG_VSERVER_EXTRA_MNT_CHECK
6591 +
6592 +static int mnt_is_reachable(struct vfsmount *vfsmnt)
6593 +{
6594 +       struct path root;
6595 +       struct dentry *point;
6596 +       struct mount *mnt = real_mount(vfsmnt);
6597 +       struct mount *root_mnt;
6598 +       int ret;
6599 +
6600 +       if (mnt == mnt->mnt_ns->root)
6601 +               return 1;
6602 +
6603 +       rcu_read_lock();
6604 +       root = current->fs->root;
6605 +       root_mnt = real_mount(root.mnt);
6606 +       point = root.dentry;
6607 +
6608 +       while ((mnt != mnt->mnt_parent) && (mnt != root_mnt)) {
6609 +               point = mnt->mnt_mountpoint;
6610 +               mnt = mnt->mnt_parent;
6611 +       }
6612 +       rcu_read_unlock();
6613 +
6614 +       ret = (mnt == root_mnt) && is_subdir(point, root.dentry);
6615 +       return ret;
6616 +}
6617 +
6618 +#else
6619 +#define        mnt_is_reachable(v)     (1)
6620 +#endif
6621 +
6622  static void show_type(struct seq_file *m, struct super_block *sb)
6623  {
6624         mangle(m, sb->s_type->name);
6625 @@ -98,6 +132,17 @@ static int show_vfsmnt(struct seq_file *
6626         struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
6627         struct super_block *sb = mnt_path.dentry->d_sb;
6628  
6629 +       if (vx_flags(VXF_HIDE_MOUNT, 0))
6630 +               return SEQ_SKIP;
6631 +       if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6632 +               return SEQ_SKIP;
6633 +
6634 +       if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
6635 +               mnt == current->fs->root.mnt) {
6636 +               seq_puts(m, "/dev/root / ");
6637 +               goto type;
6638 +       }
6639 +
6640         if (sb->s_op->show_devname) {
6641                 err = sb->s_op->show_devname(m, mnt_path.dentry);
6642                 if (err)
6643 @@ -111,6 +156,7 @@ static int show_vfsmnt(struct seq_file *
6644         if (err)
6645                 goto out;
6646         seq_putc(m, ' ');
6647 +type:
6648         show_type(m, sb);
6649         seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw");
6650         err = show_sb_opts(m, sb);
6651 @@ -132,6 +178,11 @@ static int show_mountinfo(struct seq_fil
6652         struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
6653         int err = 0;
6654  
6655 +       if (vx_flags(VXF_HIDE_MOUNT, 0))
6656 +               return SEQ_SKIP;
6657 +       if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6658 +               return SEQ_SKIP;
6659 +
6660         seq_printf(m, "%i %i %u:%u ", r->mnt_id, r->mnt_parent->mnt_id,
6661                    MAJOR(sb->s_dev), MINOR(sb->s_dev));
6662         if (sb->s_op->show_path)
6663 @@ -192,6 +243,17 @@ static int show_vfsstat(struct seq_file
6664         struct super_block *sb = mnt_path.dentry->d_sb;
6665         int err = 0;
6666  
6667 +       if (vx_flags(VXF_HIDE_MOUNT, 0))
6668 +               return SEQ_SKIP;
6669 +       if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6670 +               return SEQ_SKIP;
6671 +
6672 +       if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
6673 +               mnt == current->fs->root.mnt) {
6674 +               seq_puts(m, "device /dev/root mounted on / ");
6675 +               goto type;
6676 +       }
6677 +
6678         /* device */
6679         if (sb->s_op->show_devname) {
6680                 seq_puts(m, "device ");
6681 @@ -213,7 +275,7 @@ static int show_vfsstat(struct seq_file
6682         if (err)
6683                 goto out;
6684         seq_putc(m, ' ');
6685 -
6686 +type:
6687         /* file system type */
6688         seq_puts(m, "with fstype ");
6689         show_type(m, sb);
6690 diff -NurpP --minimal linux-4.1.41/fs/quota/dquot.c linux-4.1.41-vs2.3.8.5.3/fs/quota/dquot.c
6691 --- linux-4.1.41/fs/quota/dquot.c       2017-06-23 10:04:00.000000000 +0000
6692 +++ linux-4.1.41-vs2.3.8.5.3/fs/quota/dquot.c   2016-07-05 04:41:47.000000000 +0000
6693 @@ -1624,6 +1624,9 @@ int __dquot_alloc_space(struct inode *in
6694         int reserve = flags & DQUOT_SPACE_RESERVE;
6695         struct dquot **dquots;
6696  
6697 +       if ((ret = dl_alloc_space(inode, number)))
6698 +               return ret;
6699 +
6700         if (!dquot_active(inode)) {
6701                 inode_incr_space(inode, number, reserve);
6702                 goto out;
6703 @@ -1676,6 +1679,9 @@ int dquot_alloc_inode(struct inode *inod
6704         struct dquot_warn warn[MAXQUOTAS];
6705         struct dquot * const *dquots;
6706  
6707 +       if ((ret = dl_alloc_inode(inode)))
6708 +               return ret;
6709 +
6710         if (!dquot_active(inode))
6711                 return 0;
6712         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
6713 @@ -1778,6 +1784,8 @@ void __dquot_free_space(struct inode *in
6714         struct dquot **dquots;
6715         int reserve = flags & DQUOT_SPACE_RESERVE, index;
6716  
6717 +       dl_free_space(inode, number);
6718 +
6719         if (!dquot_active(inode)) {
6720                 inode_decr_space(inode, number, reserve);
6721                 return;
6722 @@ -1822,6 +1830,8 @@ void dquot_free_inode(struct inode *inod
6723         struct dquot * const *dquots;
6724         int index;
6725  
6726 +       dl_free_inode(inode);
6727 +
6728         if (!dquot_active(inode))
6729                 return;
6730  
6731 diff -NurpP --minimal linux-4.1.41/fs/quota/quota.c linux-4.1.41-vs2.3.8.5.3/fs/quota/quota.c
6732 --- linux-4.1.41/fs/quota/quota.c       2015-07-06 20:41:42.000000000 +0000
6733 +++ linux-4.1.41-vs2.3.8.5.3/fs/quota/quota.c   2016-07-05 04:41:47.000000000 +0000
6734 @@ -8,6 +8,7 @@
6735  #include <linux/fs.h>
6736  #include <linux/namei.h>
6737  #include <linux/slab.h>
6738 +#include <linux/vs_context.h>
6739  #include <asm/current.h>
6740  #include <linux/uaccess.h>
6741  #include <linux/kernel.h>
6742 @@ -38,7 +39,7 @@ static int check_quotactl_permission(str
6743                         break;
6744                 /*FALLTHROUGH*/
6745         default:
6746 -               if (!capable(CAP_SYS_ADMIN))
6747 +               if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
6748                         return -EPERM;
6749         }
6750  
6751 @@ -702,6 +703,46 @@ static int do_quotactl(struct super_bloc
6752  
6753  #ifdef CONFIG_BLOCK
6754  
6755 +#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
6756 +
6757 +#include <linux/vroot.h>
6758 +#include <linux/major.h>
6759 +#include <linux/module.h>
6760 +#include <linux/kallsyms.h>
6761 +#include <linux/vserver/debug.h>
6762 +
6763 +static vroot_grb_func *vroot_get_real_bdev = NULL;
6764 +
6765 +static DEFINE_SPINLOCK(vroot_grb_lock);
6766 +
6767 +int register_vroot_grb(vroot_grb_func *func) {
6768 +       int ret = -EBUSY;
6769 +
6770 +       spin_lock(&vroot_grb_lock);
6771 +       if (!vroot_get_real_bdev) {
6772 +               vroot_get_real_bdev = func;
6773 +               ret = 0;
6774 +       }
6775 +       spin_unlock(&vroot_grb_lock);
6776 +       return ret;
6777 +}
6778 +EXPORT_SYMBOL(register_vroot_grb);
6779 +
6780 +int unregister_vroot_grb(vroot_grb_func *func) {
6781 +       int ret = -EINVAL;
6782 +
6783 +       spin_lock(&vroot_grb_lock);
6784 +       if (vroot_get_real_bdev) {
6785 +               vroot_get_real_bdev = NULL;
6786 +               ret = 0;
6787 +       }
6788 +       spin_unlock(&vroot_grb_lock);
6789 +       return ret;
6790 +}
6791 +EXPORT_SYMBOL(unregister_vroot_grb);
6792 +
6793 +#endif
6794 +
6795  /* Return 1 if 'cmd' will block on frozen filesystem */
6796  static int quotactl_cmd_write(int cmd)
6797  {
6798 @@ -737,6 +778,22 @@ static struct super_block *quotactl_bloc
6799         putname(tmp);
6800         if (IS_ERR(bdev))
6801                 return ERR_CAST(bdev);
6802 +#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
6803 +       if (bdev && bdev->bd_inode &&
6804 +               imajor(bdev->bd_inode) == VROOT_MAJOR) {
6805 +               struct block_device *bdnew = (void *)-EINVAL;
6806 +
6807 +               if (vroot_get_real_bdev)
6808 +                       bdnew = vroot_get_real_bdev(bdev);
6809 +               else
6810 +                       vxdprintk(VXD_CBIT(misc, 0),
6811 +                                       "vroot_get_real_bdev not set");
6812 +               bdput(bdev);
6813 +               if (IS_ERR(bdnew))
6814 +                       return ERR_PTR(PTR_ERR(bdnew));
6815 +               bdev = bdnew;
6816 +       }
6817 +#endif
6818         if (quotactl_cmd_write(cmd))
6819                 sb = get_super_thawed(bdev);
6820         else
6821 diff -NurpP --minimal linux-4.1.41/fs/stat.c linux-4.1.41-vs2.3.8.5.3/fs/stat.c
6822 --- linux-4.1.41/fs/stat.c      2015-07-06 20:41:42.000000000 +0000
6823 +++ linux-4.1.41-vs2.3.8.5.3/fs/stat.c  2016-07-05 04:41:47.000000000 +0000
6824 @@ -26,6 +26,7 @@ void generic_fillattr(struct inode *inod
6825         stat->nlink = inode->i_nlink;
6826         stat->uid = inode->i_uid;
6827         stat->gid = inode->i_gid;
6828 +       stat->tag = inode->i_tag;
6829         stat->rdev = inode->i_rdev;
6830         stat->size = i_size_read(inode);
6831         stat->atime = inode->i_atime;
6832 diff -NurpP --minimal linux-4.1.41/fs/statfs.c linux-4.1.41-vs2.3.8.5.3/fs/statfs.c
6833 --- linux-4.1.41/fs/statfs.c    2015-04-12 22:12:50.000000000 +0000
6834 +++ linux-4.1.41-vs2.3.8.5.3/fs/statfs.c        2016-07-05 04:41:47.000000000 +0000
6835 @@ -7,6 +7,8 @@
6836  #include <linux/statfs.h>
6837  #include <linux/security.h>
6838  #include <linux/uaccess.h>
6839 +#include <linux/vs_base.h>
6840 +#include <linux/vs_dlimit.h>
6841  #include "internal.h"
6842  
6843  static int flags_by_mnt(int mnt_flags)
6844 @@ -60,6 +62,8 @@ static int statfs_by_dentry(struct dentr
6845         retval = dentry->d_sb->s_op->statfs(dentry, buf);
6846         if (retval == 0 && buf->f_frsize == 0)
6847                 buf->f_frsize = buf->f_bsize;
6848 +       if (!vx_check(0, VS_ADMIN|VS_WATCH))
6849 +               vx_vsi_statfs(dentry->d_sb, buf);
6850         return retval;
6851  }
6852  
6853 diff -NurpP --minimal linux-4.1.41/fs/super.c linux-4.1.41-vs2.3.8.5.3/fs/super.c
6854 --- linux-4.1.41/fs/super.c     2015-07-06 20:41:42.000000000 +0000
6855 +++ linux-4.1.41-vs2.3.8.5.3/fs/super.c 2016-07-05 04:41:47.000000000 +0000
6856 @@ -33,6 +33,8 @@
6857  #include <linux/cleancache.h>
6858  #include <linux/fsnotify.h>
6859  #include <linux/lockdep.h>
6860 +#include <linux/magic.h>
6861 +#include <linux/vs_context.h>
6862  #include "internal.h"
6863  
6864  
6865 @@ -1115,6 +1117,13 @@ mount_fs(struct file_system_type *type,
6866         WARN_ON(!sb->s_bdi);
6867         sb->s_flags |= MS_BORN;
6868  
6869 +       error = -EPERM;
6870 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT) &&
6871 +               !sb->s_bdev &&
6872 +               (sb->s_magic != PROC_SUPER_MAGIC) &&
6873 +               (sb->s_magic != DEVPTS_SUPER_MAGIC))
6874 +               goto out_sb;
6875 +
6876         error = security_sb_kern_mount(sb, flags, secdata);
6877         if (error)
6878                 goto out_sb;
6879 diff -NurpP --minimal linux-4.1.41/fs/utimes.c linux-4.1.41-vs2.3.8.5.3/fs/utimes.c
6880 --- linux-4.1.41/fs/utimes.c    2017-06-23 10:04:00.000000000 +0000
6881 +++ linux-4.1.41-vs2.3.8.5.3/fs/utimes.c        2017-05-30 07:39:23.000000000 +0000
6882 @@ -8,6 +8,8 @@
6883  #include <linux/stat.h>
6884  #include <linux/utime.h>
6885  #include <linux/syscalls.h>
6886 +#include <linux/mount.h>
6887 +#include <linux/vs_cowbl.h>
6888  #include <asm/uaccess.h>
6889  #include <asm/unistd.h>
6890  
6891 @@ -52,13 +54,19 @@ static int utimes_common(struct path *pa
6892  {
6893         int error;
6894         struct iattr newattrs;
6895 -       struct inode *inode = path->dentry->d_inode;
6896         struct inode *delegated_inode = NULL;
6897 +       struct inode *inode;
6898 +
6899 +       error = cow_check_and_break(path);
6900 +       if (error)
6901 +               goto out;
6902  
6903         error = mnt_want_write(path->mnt);
6904         if (error)
6905                 goto out;
6906  
6907 +       inode = path->dentry->d_inode;
6908 +
6909         if (times && times[0].tv_nsec == UTIME_NOW &&
6910                      times[1].tv_nsec == UTIME_NOW)
6911                 times = NULL;
6912 diff -NurpP --minimal linux-4.1.41/fs/xattr.c linux-4.1.41-vs2.3.8.5.3/fs/xattr.c
6913 --- linux-4.1.41/fs/xattr.c     2017-06-23 10:04:00.000000000 +0000
6914 +++ linux-4.1.41-vs2.3.8.5.3/fs/xattr.c 2017-06-23 10:07:02.000000000 +0000
6915 @@ -21,6 +21,7 @@
6916  #include <linux/audit.h>
6917  #include <linux/vmalloc.h>
6918  #include <linux/posix_acl_xattr.h>
6919 +#include <linux/mount.h>
6920  
6921  #include <asm/uaccess.h>
6922  
6923 @@ -52,7 +53,7 @@ xattr_permission(struct inode *inode, co
6924          * The trusted.* namespace can only be accessed by privileged users.
6925          */
6926         if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
6927 -               if (!capable(CAP_SYS_ADMIN))
6928 +               if (!vx_capable(CAP_SYS_ADMIN, VXC_FS_TRUSTED))
6929                         return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
6930                 return 0;
6931         }
6932 diff -NurpP --minimal linux-4.1.41/include/linux/capability.h linux-4.1.41-vs2.3.8.5.3/include/linux/capability.h
6933 --- linux-4.1.41/include/linux/capability.h     2017-06-23 10:04:00.000000000 +0000
6934 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/capability.h 2017-05-30 07:39:23.000000000 +0000
6935 @@ -79,7 +79,8 @@ extern const kernel_cap_t __cap_init_eff
6936  #else /* HAND-CODED capability initializers */
6937  
6938  #define CAP_LAST_U32                   ((_KERNEL_CAPABILITY_U32S) - 1)
6939 -#define CAP_LAST_U32_VALID_MASK                (CAP_TO_MASK(CAP_LAST_CAP + 1) -1)
6940 +#define CAP_LAST_U32_VALID_MASK                ((CAP_TO_MASK(CAP_LAST_CAP + 1) -1) \
6941 +                                       | CAP_TO_MASK(CAP_CONTEXT))
6942  
6943  # define CAP_EMPTY_SET    ((kernel_cap_t){{ 0, 0 }})
6944  # define CAP_FULL_SET     ((kernel_cap_t){{ ~0, CAP_LAST_U32_VALID_MASK }})
6945 diff -NurpP --minimal linux-4.1.41/include/linux/cred.h linux-4.1.41-vs2.3.8.5.3/include/linux/cred.h
6946 --- linux-4.1.41/include/linux/cred.h   2015-07-06 20:41:42.000000000 +0000
6947 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/cred.h       2016-07-05 04:41:47.000000000 +0000
6948 @@ -159,6 +159,7 @@ extern void exit_creds(struct task_struc
6949  extern int copy_creds(struct task_struct *, unsigned long);
6950  extern const struct cred *get_task_cred(struct task_struct *);
6951  extern struct cred *cred_alloc_blank(void);
6952 +extern struct cred *__prepare_creds(const struct cred *);
6953  extern struct cred *prepare_creds(void);
6954  extern struct cred *prepare_exec_creds(void);
6955  extern int commit_creds(struct cred *);
6956 @@ -212,6 +213,31 @@ static inline void validate_process_cred
6957  }
6958  #endif
6959  
6960 +static inline void set_cred_subscribers(struct cred *cred, int n)
6961 +{
6962 +#ifdef CONFIG_DEBUG_CREDENTIALS
6963 +       atomic_set(&cred->subscribers, n);
6964 +#endif
6965 +}
6966 +
6967 +static inline int read_cred_subscribers(const struct cred *cred)
6968 +{
6969 +#ifdef CONFIG_DEBUG_CREDENTIALS
6970 +       return atomic_read(&cred->subscribers);
6971 +#else
6972 +       return 0;
6973 +#endif
6974 +}
6975 +
6976 +static inline void alter_cred_subscribers(const struct cred *_cred, int n)
6977 +{
6978 +#ifdef CONFIG_DEBUG_CREDENTIALS
6979 +       struct cred *cred = (struct cred *) _cred;
6980 +
6981 +       atomic_add(n, &cred->subscribers);
6982 +#endif
6983 +}
6984 +
6985  /**
6986   * get_new_cred - Get a reference on a new set of credentials
6987   * @cred: The new credentials to reference
6988 diff -NurpP --minimal linux-4.1.41/include/linux/dcache.h linux-4.1.41-vs2.3.8.5.3/include/linux/dcache.h
6989 --- linux-4.1.41/include/linux/dcache.h 2017-06-23 10:04:00.000000000 +0000
6990 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/dcache.h     2016-07-06 06:58:45.000000000 +0000
6991 @@ -10,6 +10,7 @@
6992  #include <linux/cache.h>
6993  #include <linux/rcupdate.h>
6994  #include <linux/lockref.h>
6995 +// #include <linux/vs_limit.h>
6996  
6997  struct path;
6998  struct vfsmount;
6999 @@ -348,8 +349,10 @@ extern char *dentry_path(struct dentry *
7000   */
7001  static inline struct dentry *dget_dlock(struct dentry *dentry)
7002  {
7003 -       if (dentry)
7004 +       if (dentry) {
7005                 dentry->d_lockref.count++;
7006 +               // vx_dentry_inc(dentry);
7007 +       }
7008         return dentry;
7009  }
7010  
7011 diff -NurpP --minimal linux-4.1.41/include/linux/devpts_fs.h linux-4.1.41-vs2.3.8.5.3/include/linux/devpts_fs.h
7012 --- linux-4.1.41/include/linux/devpts_fs.h      2017-06-23 10:04:00.000000000 +0000
7013 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/devpts_fs.h  2016-07-05 04:41:47.000000000 +0000
7014 @@ -49,5 +49,4 @@ static inline void devpts_pty_kill(struc
7015  
7016  #endif
7017  
7018 -
7019  #endif /* _LINUX_DEVPTS_FS_H */
7020 diff -NurpP --minimal linux-4.1.41/include/linux/fs.h linux-4.1.41-vs2.3.8.5.3/include/linux/fs.h
7021 --- linux-4.1.41/include/linux/fs.h     2017-06-23 10:04:00.000000000 +0000
7022 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/fs.h 2017-05-30 07:39:23.000000000 +0000
7023 @@ -225,6 +225,7 @@ typedef void (dax_iodone_t)(struct buffe
7024  #define ATTR_KILL_PRIV (1 << 14)
7025  #define ATTR_OPEN      (1 << 15) /* Truncating from open(O_TRUNC) */
7026  #define ATTR_TIMES_SET (1 << 16)
7027 +#define ATTR_TAG       (1 << 17)
7028  
7029  /*
7030   * Whiteout is represented by a char device.  The following constants define the
7031 @@ -247,6 +248,7 @@ struct iattr {
7032         umode_t         ia_mode;
7033         kuid_t          ia_uid;
7034         kgid_t          ia_gid;
7035 +       ktag_t          ia_tag;
7036         loff_t          ia_size;
7037         struct timespec ia_atime;
7038         struct timespec ia_mtime;
7039 @@ -585,7 +587,9 @@ struct inode {
7040         unsigned short          i_opflags;
7041         kuid_t                  i_uid;
7042         kgid_t                  i_gid;
7043 -       unsigned int            i_flags;
7044 +       ktag_t                  i_tag;
7045 +       unsigned short          i_flags;
7046 +       unsigned short          i_vflags;
7047  
7048  #ifdef CONFIG_FS_POSIX_ACL
7049         struct posix_acl        *i_acl;
7050 @@ -614,6 +618,7 @@ struct inode {
7051                 unsigned int __i_nlink;
7052         };
7053         dev_t                   i_rdev;
7054 +       dev_t                   i_mdev;
7055         loff_t                  i_size;
7056         struct timespec         i_atime;
7057         struct timespec         i_mtime;
7058 @@ -773,6 +778,11 @@ static inline gid_t i_gid_read(const str
7059         return from_kgid(&init_user_ns, inode->i_gid);
7060  }
7061  
7062 +static inline vtag_t i_tag_read(const struct inode *inode)
7063 +{
7064 +       return from_ktag(&init_user_ns, inode->i_tag);
7065 +}
7066 +
7067  static inline void i_uid_write(struct inode *inode, uid_t uid)
7068  {
7069         inode->i_uid = make_kuid(&init_user_ns, uid);
7070 @@ -783,14 +793,19 @@ static inline void i_gid_write(struct in
7071         inode->i_gid = make_kgid(&init_user_ns, gid);
7072  }
7073  
7074 +static inline void i_tag_write(struct inode *inode, vtag_t tag)
7075 +{
7076 +       inode->i_tag = make_ktag(&init_user_ns, tag);
7077 +}
7078 +
7079  static inline unsigned iminor(const struct inode *inode)
7080  {
7081 -       return MINOR(inode->i_rdev);
7082 +       return MINOR(inode->i_mdev);
7083  }
7084  
7085  static inline unsigned imajor(const struct inode *inode)
7086  {
7087 -       return MAJOR(inode->i_rdev);
7088 +       return MAJOR(inode->i_mdev);
7089  }
7090  
7091  extern struct block_device *I_BDEV(struct inode *inode);
7092 @@ -847,6 +862,7 @@ struct file {
7093         loff_t                  f_pos;
7094         struct fown_struct      f_owner;
7095         const struct cred       *f_cred;
7096 +       vxid_t                  f_xid;
7097         struct file_ra_state    f_ra;
7098  
7099         u64                     f_version;
7100 @@ -975,6 +991,7 @@ struct file_lock {
7101         struct file *fl_file;
7102         loff_t fl_start;
7103         loff_t fl_end;
7104 +       vxid_t fl_xid;
7105  
7106         struct fasync_struct *  fl_fasync; /* for lease break notifications */
7107         /* for lease breaks: */
7108 @@ -1647,6 +1664,7 @@ struct inode_operations {
7109         ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
7110         ssize_t (*listxattr) (struct dentry *, char *, size_t);
7111         int (*removexattr) (struct dentry *, const char *);
7112 +       int (*sync_flags) (struct inode *, int, int);
7113         int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
7114                       u64 len);
7115         int (*update_time)(struct inode *, struct timespec *, int);
7116 @@ -1663,6 +1681,7 @@ ssize_t rw_copy_check_uvector(int type,
7117                               unsigned long nr_segs, unsigned long fast_segs,
7118                               struct iovec *fast_pointer,
7119                               struct iovec **ret_pointer);
7120 +ssize_t vfs_sendfile(struct file *, struct file *, loff_t *, size_t, loff_t);
7121  
7122  extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
7123  extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *);
7124 @@ -1728,6 +1747,14 @@ struct super_operations {
7125  #else
7126  #define S_DAX          0       /* Make all the DAX code disappear */
7127  #endif
7128 +#define S_IXUNLINK     16384   /* Immutable Invert on unlink */
7129 +
7130 +/* Linux-VServer related Inode flags */
7131 +
7132 +#define V_VALID                1
7133 +#define V_XATTR                2
7134 +#define V_BARRIER      4       /* Barrier for chroot() */
7135 +#define V_COW          8       /* Copy on Write */
7136  
7137  /*
7138   * Note that nosuid etc flags are inode-specific: setting some file-system
7139 @@ -1752,10 +1779,13 @@ struct super_operations {
7140  #define IS_MANDLOCK(inode)     __IS_FLG(inode, MS_MANDLOCK)
7141  #define IS_NOATIME(inode)      __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
7142  #define IS_I_VERSION(inode)    __IS_FLG(inode, MS_I_VERSION)
7143 +#define IS_TAGGED(inode)       __IS_FLG(inode, MS_TAGGED)
7144  
7145  #define IS_NOQUOTA(inode)      ((inode)->i_flags & S_NOQUOTA)
7146  #define IS_APPEND(inode)       ((inode)->i_flags & S_APPEND)
7147  #define IS_IMMUTABLE(inode)    ((inode)->i_flags & S_IMMUTABLE)
7148 +#define IS_IXUNLINK(inode)     ((inode)->i_flags & S_IXUNLINK)
7149 +#define IS_IXORUNLINK(inode)   ((IS_IXUNLINK(inode) ? S_IMMUTABLE : 0) ^ IS_IMMUTABLE(inode))
7150  #define IS_POSIXACL(inode)     __IS_FLG(inode, MS_POSIXACL)
7151  
7152  #define IS_DEADDIR(inode)      ((inode)->i_flags & S_DEAD)
7153 @@ -1770,6 +1800,16 @@ struct super_operations {
7154  #define IS_WHITEOUT(inode)     (S_ISCHR(inode->i_mode) && \
7155                                  (inode)->i_rdev == WHITEOUT_DEV)
7156  
7157 +#define IS_BARRIER(inode)      (S_ISDIR((inode)->i_mode) && ((inode)->i_vflags & V_BARRIER))
7158 +
7159 +#ifdef CONFIG_VSERVER_COWBL
7160 +#  define IS_COW(inode)                (IS_IXUNLINK(inode) && IS_IMMUTABLE(inode))
7161 +#  define IS_COW_LINK(inode)   (S_ISREG((inode)->i_mode) && ((inode)->i_nlink > 1))
7162 +#else
7163 +#  define IS_COW(inode)                (0)
7164 +#  define IS_COW_LINK(inode)   (0)
7165 +#endif
7166 +
7167  /*
7168   * Inode state bits.  Protected by inode->i_lock
7169   *
7170 @@ -2019,6 +2059,9 @@ extern struct kobject *fs_kobj;
7171  extern int locks_mandatory_locked(struct file *);
7172  extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size_t);
7173  
7174 +#define ATTR_FLAG_BARRIER      512     /* Barrier for chroot() */
7175 +#define ATTR_FLAG_IXUNLINK     1024    /* Immutable invert on unlink */
7176 +
7177  /*
7178   * Candidates for mandatory locking have the setgid bit set
7179   * but no group execute bit -  an otherwise meaningless combination.
7180 @@ -2764,6 +2807,7 @@ extern int dcache_dir_open(struct inode
7181  extern int dcache_dir_close(struct inode *, struct file *);
7182  extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
7183  extern int dcache_readdir(struct file *, struct dir_context *);
7184 +extern int dcache_readdir_filter(struct file *, struct dir_context *, int (*)(struct dentry *));
7185  extern int simple_setattr(struct dentry *, struct iattr *);
7186  extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
7187  extern int simple_statfs(struct dentry *, struct kstatfs *);
7188 diff -NurpP --minimal linux-4.1.41/include/linux/init_task.h linux-4.1.41-vs2.3.8.5.3/include/linux/init_task.h
7189 --- linux-4.1.41/include/linux/init_task.h      2015-04-12 22:12:50.000000000 +0000
7190 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/init_task.h  2016-07-05 04:41:47.000000000 +0000
7191 @@ -258,6 +258,10 @@ extern struct task_group root_task_group
7192         INIT_VTIME(tsk)                                                 \
7193         INIT_NUMA_BALANCING(tsk)                                        \
7194         INIT_KASAN(tsk)                                                 \
7195 +       .xid            = 0,                                            \
7196 +       .vx_info        = NULL,                                         \
7197 +       .nid            = 0,                                            \
7198 +       .nx_info        = NULL,                                         \
7199  }
7200  
7201  
7202 diff -NurpP --minimal linux-4.1.41/include/linux/ipc.h linux-4.1.41-vs2.3.8.5.3/include/linux/ipc.h
7203 --- linux-4.1.41/include/linux/ipc.h    2015-04-12 22:12:50.000000000 +0000
7204 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/ipc.h        2016-07-05 04:41:47.000000000 +0000
7205 @@ -16,6 +16,7 @@ struct kern_ipc_perm
7206         key_t           key;
7207         kuid_t          uid;
7208         kgid_t          gid;
7209 +       vxid_t          xid;
7210         kuid_t          cuid;
7211         kgid_t          cgid;
7212         umode_t         mode; 
7213 diff -NurpP --minimal linux-4.1.41/include/linux/memcontrol.h linux-4.1.41-vs2.3.8.5.3/include/linux/memcontrol.h
7214 --- linux-4.1.41/include/linux/memcontrol.h     2015-07-06 20:41:42.000000000 +0000
7215 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/memcontrol.h 2016-07-06 06:59:44.000000000 +0000
7216 @@ -66,6 +66,7 @@ enum mem_cgroup_events_index {
7217         MEMCG_NR_EVENTS,
7218  };
7219  
7220 +
7221  #ifdef CONFIG_MEMCG
7222  void mem_cgroup_events(struct mem_cgroup *memcg,
7223                        enum mem_cgroup_events_index idx,
7224 @@ -97,6 +98,11 @@ extern struct mem_cgroup *mem_cgroup_fro
7225  extern struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg);
7226  extern struct mem_cgroup *mem_cgroup_from_css(struct cgroup_subsys_state *css);
7227  
7228 +extern u64 mem_cgroup_mem_usage_pages(struct mem_cgroup *memcg);
7229 +extern u64 mem_cgroup_mem_limit_pages(struct mem_cgroup *memcg);
7230 +extern u64 mem_cgroup_memsw_usage_pages(struct mem_cgroup *memcg);
7231 +extern u64 mem_cgroup_memsw_limit_pages(struct mem_cgroup *memcg);
7232 +
7233  static inline bool mm_match_cgroup(struct mm_struct *mm,
7234                                    struct mem_cgroup *memcg)
7235  {
7236 diff -NurpP --minimal linux-4.1.41/include/linux/mount.h linux-4.1.41-vs2.3.8.5.3/include/linux/mount.h
7237 --- linux-4.1.41/include/linux/mount.h  2017-06-23 10:04:00.000000000 +0000
7238 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/mount.h      2017-05-30 07:39:23.000000000 +0000
7239 @@ -63,6 +63,9 @@ struct mnt_namespace;
7240  #define MNT_MARKED             0x4000000
7241  #define MNT_UMOUNT             0x8000000
7242  
7243 +#define MNT_TAGID      0x10000
7244 +#define MNT_NOTAG      0x20000
7245 +
7246  struct vfsmount {
7247         struct dentry *mnt_root;        /* root of the mounted tree */
7248         struct super_block *mnt_sb;     /* pointer to superblock */
7249 diff -NurpP --minimal linux-4.1.41/include/linux/net.h linux-4.1.41-vs2.3.8.5.3/include/linux/net.h
7250 --- linux-4.1.41/include/linux/net.h    2015-07-06 20:41:42.000000000 +0000
7251 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/net.h        2016-07-05 04:41:47.000000000 +0000
7252 @@ -39,6 +39,7 @@ struct net;
7253  #define SOCK_PASSCRED          3
7254  #define SOCK_PASSSEC           4
7255  #define SOCK_EXTERNALLY_ALLOCATED 5
7256 +#define SOCK_USER_SOCKET       6
7257  
7258  #ifndef ARCH_HAS_SOCKET_TYPES
7259  /**
7260 diff -NurpP --minimal linux-4.1.41/include/linux/netdevice.h linux-4.1.41-vs2.3.8.5.3/include/linux/netdevice.h
7261 --- linux-4.1.41/include/linux/netdevice.h      2017-06-23 10:04:00.000000000 +0000
7262 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/netdevice.h  2017-05-30 07:39:23.000000000 +0000
7263 @@ -2223,6 +2223,7 @@ static inline int dev_recursion_level(vo
7264  
7265  struct net_device *dev_get_by_index(struct net *net, int ifindex);
7266  struct net_device *__dev_get_by_index(struct net *net, int ifindex);
7267 +struct net_device *dev_get_by_index_real_rcu(struct net *net, int ifindex);
7268  struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex);
7269  int netdev_get_name(struct net *net, char *name, int ifindex);
7270  int dev_restart(struct net_device *dev);
7271 diff -NurpP --minimal linux-4.1.41/include/linux/nsproxy.h linux-4.1.41-vs2.3.8.5.3/include/linux/nsproxy.h
7272 --- linux-4.1.41/include/linux/nsproxy.h        2015-04-12 22:12:50.000000000 +0000
7273 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/nsproxy.h    2016-07-05 04:41:47.000000000 +0000
7274 @@ -3,6 +3,7 @@
7275  
7276  #include <linux/spinlock.h>
7277  #include <linux/sched.h>
7278 +#include <linux/vserver/debug.h>
7279  
7280  struct mnt_namespace;
7281  struct uts_namespace;
7282 @@ -63,6 +64,7 @@ extern struct nsproxy init_nsproxy;
7283   */
7284  
7285  int copy_namespaces(unsigned long flags, struct task_struct *tsk);
7286 +struct nsproxy *copy_nsproxy(struct nsproxy *orig);
7287  void exit_task_namespaces(struct task_struct *tsk);
7288  void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new);
7289  void free_nsproxy(struct nsproxy *ns);
7290 @@ -70,16 +72,26 @@ int unshare_nsproxy_namespaces(unsigned
7291         struct cred *, struct fs_struct *);
7292  int __init nsproxy_cache_init(void);
7293  
7294 -static inline void put_nsproxy(struct nsproxy *ns)
7295 +#define        get_nsproxy(n)  __get_nsproxy(n, __FILE__, __LINE__)
7296 +
7297 +static inline void __get_nsproxy(struct nsproxy *ns,
7298 +       const char *_file, int _line)
7299  {
7300 -       if (atomic_dec_and_test(&ns->count)) {
7301 -               free_nsproxy(ns);
7302 -       }
7303 +       vxlprintk(VXD_CBIT(space, 0), "get_nsproxy(%p[%u])",
7304 +               ns, atomic_read(&ns->count), _file, _line);
7305 +       atomic_inc(&ns->count);
7306  }
7307  
7308 -static inline void get_nsproxy(struct nsproxy *ns)
7309 +#define        put_nsproxy(n)  __put_nsproxy(n, __FILE__, __LINE__)
7310 +
7311 +static inline void __put_nsproxy(struct nsproxy *ns,
7312 +       const char *_file, int _line)
7313  {
7314 -       atomic_inc(&ns->count);
7315 +       vxlprintk(VXD_CBIT(space, 0), "put_nsproxy(%p[%u])",
7316 +               ns, atomic_read(&ns->count), _file, _line);
7317 +       if (atomic_dec_and_test(&ns->count)) {
7318 +               free_nsproxy(ns);
7319 +       }
7320  }
7321  
7322  #endif
7323 diff -NurpP --minimal linux-4.1.41/include/linux/pid.h linux-4.1.41-vs2.3.8.5.3/include/linux/pid.h
7324 --- linux-4.1.41/include/linux/pid.h    2015-04-12 22:12:50.000000000 +0000
7325 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/pid.h        2016-07-05 04:41:47.000000000 +0000
7326 @@ -8,7 +8,8 @@ enum pid_type
7327         PIDTYPE_PID,
7328         PIDTYPE_PGID,
7329         PIDTYPE_SID,
7330 -       PIDTYPE_MAX
7331 +       PIDTYPE_MAX,
7332 +       PIDTYPE_REALPID
7333  };
7334  
7335  /*
7336 @@ -170,6 +171,7 @@ static inline pid_t pid_nr(struct pid *p
7337  }
7338  
7339  pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns);
7340 +pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns);
7341  pid_t pid_vnr(struct pid *pid);
7342  
7343  #define do_each_pid_task(pid, type, task)                              \
7344 diff -NurpP --minimal linux-4.1.41/include/linux/quotaops.h linux-4.1.41-vs2.3.8.5.3/include/linux/quotaops.h
7345 --- linux-4.1.41/include/linux/quotaops.h       2015-07-06 20:41:43.000000000 +0000
7346 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/quotaops.h   2016-07-05 04:41:47.000000000 +0000
7347 @@ -8,6 +8,7 @@
7348  #define _LINUX_QUOTAOPS_
7349  
7350  #include <linux/fs.h>
7351 +#include <linux/vs_dlimit.h>
7352  
7353  #define DQUOT_SPACE_WARN       0x1
7354  #define DQUOT_SPACE_RESERVE    0x2
7355 @@ -210,11 +211,12 @@ static inline void dquot_drop(struct ino
7356  
7357  static inline int dquot_alloc_inode(struct inode *inode)
7358  {
7359 -       return 0;
7360 +       return dl_alloc_inode(inode);
7361  }
7362  
7363  static inline void dquot_free_inode(struct inode *inode)
7364  {
7365 +       dl_free_inode(inode);
7366  }
7367  
7368  static inline int dquot_transfer(struct inode *inode, struct iattr *iattr)
7369 @@ -225,6 +227,10 @@ static inline int dquot_transfer(struct
7370  static inline int __dquot_alloc_space(struct inode *inode, qsize_t number,
7371                 int flags)
7372  {
7373 +       int ret = 0;
7374 +
7375 +       if ((ret = dl_alloc_space(inode, number)))
7376 +               return ret;
7377         if (!(flags & DQUOT_SPACE_RESERVE))
7378                 inode_add_bytes(inode, number);
7379         return 0;
7380 @@ -235,6 +241,7 @@ static inline void __dquot_free_space(st
7381  {
7382         if (!(flags & DQUOT_SPACE_RESERVE))
7383                 inode_sub_bytes(inode, number);
7384 +       dl_free_space(inode, number);
7385  }
7386  
7387  static inline int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
7388 diff -NurpP --minimal linux-4.1.41/include/linux/sched.h linux-4.1.41-vs2.3.8.5.3/include/linux/sched.h
7389 --- linux-4.1.41/include/linux/sched.h  2017-06-23 10:04:01.000000000 +0000
7390 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/sched.h      2017-06-23 10:07:02.000000000 +0000
7391 @@ -1505,6 +1505,14 @@ struct task_struct {
7392  #endif
7393         struct seccomp seccomp;
7394  
7395 +/* vserver context data */
7396 +       struct vx_info *vx_info;
7397 +       struct nx_info *nx_info;
7398 +
7399 +       vxid_t xid;
7400 +       vnid_t nid;
7401 +       vtag_t tag;
7402 +
7403  /* Thread group tracking */
7404         u32 parent_exec_id;
7405         u32 self_exec_id;
7406 @@ -1811,6 +1819,11 @@ struct pid_namespace;
7407  pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
7408                         struct pid_namespace *ns);
7409  
7410 +#include <linux/vserver/base.h>
7411 +#include <linux/vserver/context.h>
7412 +#include <linux/vserver/debug.h>
7413 +#include <linux/vserver/pid.h>
7414 +
7415  static inline pid_t task_pid_nr(struct task_struct *tsk)
7416  {
7417         return tsk->pid;
7418 @@ -1824,7 +1837,8 @@ static inline pid_t task_pid_nr_ns(struc
7419  
7420  static inline pid_t task_pid_vnr(struct task_struct *tsk)
7421  {
7422 -       return __task_pid_nr_ns(tsk, PIDTYPE_PID, NULL);
7423 +       // return __task_pid_nr_ns(tsk, PIDTYPE_PID, NULL);
7424 +       return vx_map_pid(__task_pid_nr_ns(tsk, PIDTYPE_PID, NULL));
7425  }
7426  
7427  
7428 @@ -1837,7 +1851,7 @@ pid_t task_tgid_nr_ns(struct task_struct
7429  
7430  static inline pid_t task_tgid_vnr(struct task_struct *tsk)
7431  {
7432 -       return pid_vnr(task_tgid(tsk));
7433 +       return vx_map_tgid(pid_vnr(task_tgid(tsk)));
7434  }
7435  
7436  
7437 diff -NurpP --minimal linux-4.1.41/include/linux/shmem_fs.h linux-4.1.41-vs2.3.8.5.3/include/linux/shmem_fs.h
7438 --- linux-4.1.41/include/linux/shmem_fs.h       2015-04-12 22:12:50.000000000 +0000
7439 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/shmem_fs.h   2016-07-05 04:41:47.000000000 +0000
7440 @@ -10,6 +10,9 @@
7441  
7442  /* inode in-kernel data */
7443  
7444 +#define TMPFS_SUPER_MAGIC      0x01021994
7445 +
7446 +
7447  struct shmem_inode_info {
7448         spinlock_t              lock;
7449         unsigned int            seals;          /* shmem seals */
7450 diff -NurpP --minimal linux-4.1.41/include/linux/stat.h linux-4.1.41-vs2.3.8.5.3/include/linux/stat.h
7451 --- linux-4.1.41/include/linux/stat.h   2015-04-12 22:12:50.000000000 +0000
7452 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/stat.h       2016-07-05 04:41:47.000000000 +0000
7453 @@ -25,6 +25,7 @@ struct kstat {
7454         unsigned int    nlink;
7455         kuid_t          uid;
7456         kgid_t          gid;
7457 +       ktag_t          tag;
7458         dev_t           rdev;
7459         loff_t          size;
7460         struct timespec  atime;
7461 diff -NurpP --minimal linux-4.1.41/include/linux/sunrpc/auth.h linux-4.1.41-vs2.3.8.5.3/include/linux/sunrpc/auth.h
7462 --- linux-4.1.41/include/linux/sunrpc/auth.h    2015-04-12 22:12:50.000000000 +0000
7463 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/sunrpc/auth.h        2016-07-05 04:41:47.000000000 +0000
7464 @@ -36,6 +36,7 @@ enum {
7465  struct auth_cred {
7466         kuid_t  uid;
7467         kgid_t  gid;
7468 +       ktag_t  tag;
7469         struct group_info *group_info;
7470         const char *principal;
7471         unsigned long ac_flags;
7472 diff -NurpP --minimal linux-4.1.41/include/linux/sunrpc/clnt.h linux-4.1.41-vs2.3.8.5.3/include/linux/sunrpc/clnt.h
7473 --- linux-4.1.41/include/linux/sunrpc/clnt.h    2017-06-23 10:04:01.000000000 +0000
7474 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/sunrpc/clnt.h        2017-05-30 07:39:23.000000000 +0000
7475 @@ -51,7 +51,8 @@ struct rpc_clnt {
7476                                 cl_discrtry : 1,/* disconnect before retry */
7477                                 cl_noretranstimeo: 1,/* No retransmit timeouts */
7478                                 cl_autobind : 1,/* use getport() */
7479 -                               cl_chatty   : 1;/* be verbose */
7480 +                               cl_chatty   : 1,/* be verbose */
7481 +                               cl_tag      : 1;/* context tagging */
7482  
7483         struct rpc_rtt *        cl_rtt;         /* RTO estimator data */
7484         const struct rpc_timeout *cl_timeout;   /* Timeout strategy */
7485 diff -NurpP --minimal linux-4.1.41/include/linux/types.h linux-4.1.41-vs2.3.8.5.3/include/linux/types.h
7486 --- linux-4.1.41/include/linux/types.h  2017-06-23 10:04:01.000000000 +0000
7487 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/types.h      2016-07-05 04:41:47.000000000 +0000
7488 @@ -32,6 +32,9 @@ typedef __kernel_uid32_t      uid_t;
7489  typedef __kernel_gid32_t       gid_t;
7490  typedef __kernel_uid16_t        uid16_t;
7491  typedef __kernel_gid16_t        gid16_t;
7492 +typedef unsigned int           vxid_t;
7493 +typedef unsigned int           vnid_t;
7494 +typedef unsigned int           vtag_t;
7495  
7496  typedef unsigned long          uintptr_t;
7497  
7498 diff -NurpP --minimal linux-4.1.41/include/linux/uidgid.h linux-4.1.41-vs2.3.8.5.3/include/linux/uidgid.h
7499 --- linux-4.1.41/include/linux/uidgid.h 2015-07-06 20:41:43.000000000 +0000
7500 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/uidgid.h     2016-07-05 04:41:47.000000000 +0000
7501 @@ -21,13 +21,17 @@ typedef struct {
7502         uid_t val;
7503  } kuid_t;
7504  
7505 -
7506  typedef struct {
7507         gid_t val;
7508  } kgid_t;
7509  
7510 +typedef struct {
7511 +       vtag_t val;
7512 +} ktag_t;
7513 +
7514  #define KUIDT_INIT(value) (kuid_t){ value }
7515  #define KGIDT_INIT(value) (kgid_t){ value }
7516 +#define KTAGT_INIT(value) (ktag_t){ value }
7517  
7518  #ifdef CONFIG_MULTIUSER
7519  static inline uid_t __kuid_val(kuid_t uid)
7520 @@ -51,11 +55,18 @@ static inline gid_t __kgid_val(kgid_t gi
7521  }
7522  #endif
7523  
7524 +static inline vtag_t __ktag_val(ktag_t tag)
7525 +{
7526 +       return tag.val;
7527 +}
7528 +
7529  #define GLOBAL_ROOT_UID KUIDT_INIT(0)
7530  #define GLOBAL_ROOT_GID KGIDT_INIT(0)
7531 +#define GLOBAL_ROOT_TAG KTAGT_INIT(0)
7532  
7533  #define INVALID_UID KUIDT_INIT(-1)
7534  #define INVALID_GID KGIDT_INIT(-1)
7535 +#define INVALID_TAG KTAGT_INIT(-1)
7536  
7537  static inline bool uid_eq(kuid_t left, kuid_t right)
7538  {
7539 @@ -67,6 +78,11 @@ static inline bool gid_eq(kgid_t left, k
7540         return __kgid_val(left) == __kgid_val(right);
7541  }
7542  
7543 +static inline bool tag_eq(ktag_t left, ktag_t right)
7544 +{
7545 +       return __ktag_val(left) == __ktag_val(right);
7546 +}
7547 +
7548  static inline bool uid_gt(kuid_t left, kuid_t right)
7549  {
7550         return __kuid_val(left) > __kuid_val(right);
7551 @@ -117,13 +133,21 @@ static inline bool gid_valid(kgid_t gid)
7552         return __kgid_val(gid) != (gid_t) -1;
7553  }
7554  
7555 +static inline bool tag_valid(ktag_t tag)
7556 +{
7557 +       return !tag_eq(tag, INVALID_TAG);
7558 +}
7559 +
7560  #ifdef CONFIG_USER_NS
7561  
7562  extern kuid_t make_kuid(struct user_namespace *from, uid_t uid);
7563  extern kgid_t make_kgid(struct user_namespace *from, gid_t gid);
7564 +extern ktag_t make_ktag(struct user_namespace *from, gid_t gid);
7565  
7566  extern uid_t from_kuid(struct user_namespace *to, kuid_t uid);
7567  extern gid_t from_kgid(struct user_namespace *to, kgid_t gid);
7568 +extern vtag_t from_ktag(struct user_namespace *to, ktag_t tag);
7569 +
7570  extern uid_t from_kuid_munged(struct user_namespace *to, kuid_t uid);
7571  extern gid_t from_kgid_munged(struct user_namespace *to, kgid_t gid);
7572  
7573 @@ -149,6 +173,11 @@ static inline kgid_t make_kgid(struct us
7574         return KGIDT_INIT(gid);
7575  }
7576  
7577 +static inline ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
7578 +{
7579 +       return KTAGT_INIT(tag);
7580 +}
7581 +
7582  static inline uid_t from_kuid(struct user_namespace *to, kuid_t kuid)
7583  {
7584         return __kuid_val(kuid);
7585 @@ -159,6 +188,11 @@ static inline gid_t from_kgid(struct use
7586         return __kgid_val(kgid);
7587  }
7588  
7589 +static inline vtag_t from_ktag(struct user_namespace *to, ktag_t ktag)
7590 +{
7591 +       return __ktag_val(ktag);
7592 +}
7593 +
7594  static inline uid_t from_kuid_munged(struct user_namespace *to, kuid_t kuid)
7595  {
7596         uid_t uid = from_kuid(to, kuid);
7597 diff -NurpP --minimal linux-4.1.41/include/linux/vroot.h linux-4.1.41-vs2.3.8.5.3/include/linux/vroot.h
7598 --- linux-4.1.41/include/linux/vroot.h  1970-01-01 00:00:00.000000000 +0000
7599 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vroot.h      2016-07-05 04:41:47.000000000 +0000
7600 @@ -0,0 +1,51 @@
7601 +
7602 +/*
7603 + * include/linux/vroot.h
7604 + *
7605 + * written by Herbert Pötzl, 9/11/2002
7606 + * ported to 2.6 by Herbert Pötzl, 30/12/2004
7607 + *
7608 + * Copyright (C) 2002-2007 by Herbert Pötzl.
7609 + * Redistribution of this file is permitted under the
7610 + * GNU General Public License.
7611 + */
7612 +
7613 +#ifndef _LINUX_VROOT_H
7614 +#define _LINUX_VROOT_H
7615 +
7616 +
7617 +#ifdef __KERNEL__
7618 +
7619 +/* Possible states of device */
7620 +enum {
7621 +       Vr_unbound,
7622 +       Vr_bound,
7623 +};
7624 +
7625 +struct vroot_device {
7626 +       int             vr_number;
7627 +       int             vr_refcnt;
7628 +
7629 +       struct semaphore        vr_ctl_mutex;
7630 +       struct block_device    *vr_device;
7631 +       int                     vr_state;
7632 +};
7633 +
7634 +
7635 +typedef struct block_device *(vroot_grb_func)(struct block_device *);
7636 +
7637 +extern int register_vroot_grb(vroot_grb_func *);
7638 +extern int unregister_vroot_grb(vroot_grb_func *);
7639 +
7640 +#endif /* __KERNEL__ */
7641 +
7642 +#define MAX_VROOT_DEFAULT      8
7643 +
7644 +/*
7645 + * IOCTL commands --- we will commandeer 0x56 ('V')
7646 + */
7647 +
7648 +#define VROOT_SET_DEV          0x5600
7649 +#define VROOT_CLR_DEV          0x5601
7650 +
7651 +#endif /* _LINUX_VROOT_H */
7652 diff -NurpP --minimal linux-4.1.41/include/linux/vs_base.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_base.h
7653 --- linux-4.1.41/include/linux/vs_base.h        1970-01-01 00:00:00.000000000 +0000
7654 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_base.h    2016-07-05 04:41:47.000000000 +0000
7655 @@ -0,0 +1,10 @@
7656 +#ifndef _VS_BASE_H
7657 +#define _VS_BASE_H
7658 +
7659 +#include "vserver/base.h"
7660 +#include "vserver/check.h"
7661 +#include "vserver/debug.h"
7662 +
7663 +#else
7664 +#warning duplicate inclusion
7665 +#endif
7666 diff -NurpP --minimal linux-4.1.41/include/linux/vs_context.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_context.h
7667 --- linux-4.1.41/include/linux/vs_context.h     1970-01-01 00:00:00.000000000 +0000
7668 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_context.h 2016-07-05 04:41:47.000000000 +0000
7669 @@ -0,0 +1,242 @@
7670 +#ifndef _VS_CONTEXT_H
7671 +#define _VS_CONTEXT_H
7672 +
7673 +#include "vserver/base.h"
7674 +#include "vserver/check.h"
7675 +#include "vserver/context.h"
7676 +#include "vserver/history.h"
7677 +#include "vserver/debug.h"
7678 +
7679 +#include <linux/sched.h>
7680 +
7681 +
7682 +#define get_vx_info(i) __get_vx_info(i, __FILE__, __LINE__, __HERE__)
7683 +
7684 +static inline struct vx_info *__get_vx_info(struct vx_info *vxi,
7685 +       const char *_file, int _line, void *_here)
7686 +{
7687 +       if (!vxi)
7688 +               return NULL;
7689 +
7690 +       vxlprintk(VXD_CBIT(xid, 2), "get_vx_info(%p[#%d.%d])",
7691 +               vxi, vxi ? vxi->vx_id : 0,
7692 +               vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7693 +               _file, _line);
7694 +       __vxh_get_vx_info(vxi, _here);
7695 +
7696 +       atomic_inc(&vxi->vx_usecnt);
7697 +       return vxi;
7698 +}
7699 +
7700 +
7701 +extern void free_vx_info(struct vx_info *);
7702 +
7703 +#define put_vx_info(i) __put_vx_info(i, __FILE__, __LINE__, __HERE__)
7704 +
7705 +static inline void __put_vx_info(struct vx_info *vxi,
7706 +       const char *_file, int _line, void *_here)
7707 +{
7708 +       if (!vxi)
7709 +               return;
7710 +
7711 +       vxlprintk(VXD_CBIT(xid, 2), "put_vx_info(%p[#%d.%d])",
7712 +               vxi, vxi ? vxi->vx_id : 0,
7713 +               vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7714 +               _file, _line);
7715 +       __vxh_put_vx_info(vxi, _here);
7716 +
7717 +       if (atomic_dec_and_test(&vxi->vx_usecnt))
7718 +               free_vx_info(vxi);
7719 +}
7720 +
7721 +
7722 +#define init_vx_info(p, i) \
7723 +       __init_vx_info(p, i, __FILE__, __LINE__, __HERE__)
7724 +
7725 +static inline void __init_vx_info(struct vx_info **vxp, struct vx_info *vxi,
7726 +       const char *_file, int _line, void *_here)
7727 +{
7728 +       if (vxi) {
7729 +               vxlprintk(VXD_CBIT(xid, 3),
7730 +                       "init_vx_info(%p[#%d.%d])",
7731 +                       vxi, vxi ? vxi->vx_id : 0,
7732 +                       vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7733 +                       _file, _line);
7734 +               __vxh_init_vx_info(vxi, vxp, _here);
7735 +
7736 +               atomic_inc(&vxi->vx_usecnt);
7737 +       }
7738 +       *vxp = vxi;
7739 +}
7740 +
7741 +
7742 +#define set_vx_info(p, i) \
7743 +       __set_vx_info(p, i, __FILE__, __LINE__, __HERE__)
7744 +
7745 +static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi,
7746 +       const char *_file, int _line, void *_here)
7747 +{
7748 +       struct vx_info *vxo;
7749 +
7750 +       if (!vxi)
7751 +               return;
7752 +
7753 +       vxlprintk(VXD_CBIT(xid, 3), "set_vx_info(%p[#%d.%d])",
7754 +               vxi, vxi ? vxi->vx_id : 0,
7755 +               vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7756 +               _file, _line);
7757 +       __vxh_set_vx_info(vxi, vxp, _here);
7758 +
7759 +       atomic_inc(&vxi->vx_usecnt);
7760 +       vxo = xchg(vxp, vxi);
7761 +       BUG_ON(vxo);
7762 +}
7763 +
7764 +
7765 +#define clr_vx_info(p) __clr_vx_info(p, __FILE__, __LINE__, __HERE__)
7766 +
7767 +static inline void __clr_vx_info(struct vx_info **vxp,
7768 +       const char *_file, int _line, void *_here)
7769 +{
7770 +       struct vx_info *vxo;
7771 +
7772 +       vxo = xchg(vxp, NULL);
7773 +       if (!vxo)
7774 +               return;
7775 +
7776 +       vxlprintk(VXD_CBIT(xid, 3), "clr_vx_info(%p[#%d.%d])",
7777 +               vxo, vxo ? vxo->vx_id : 0,
7778 +               vxo ? atomic_read(&vxo->vx_usecnt) : 0,
7779 +               _file, _line);
7780 +       __vxh_clr_vx_info(vxo, vxp, _here);
7781 +
7782 +       if (atomic_dec_and_test(&vxo->vx_usecnt))
7783 +               free_vx_info(vxo);
7784 +}
7785 +
7786 +
7787 +#define claim_vx_info(v, p) \
7788 +       __claim_vx_info(v, p, __FILE__, __LINE__, __HERE__)
7789 +
7790 +static inline void __claim_vx_info(struct vx_info *vxi,
7791 +       struct task_struct *task,
7792 +       const char *_file, int _line, void *_here)
7793 +{
7794 +       vxlprintk(VXD_CBIT(xid, 3), "claim_vx_info(%p[#%d.%d.%d]) %p",
7795 +               vxi, vxi ? vxi->vx_id : 0,
7796 +               vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7797 +               vxi ? atomic_read(&vxi->vx_tasks) : 0,
7798 +               task, _file, _line);
7799 +       __vxh_claim_vx_info(vxi, task, _here);
7800 +
7801 +       atomic_inc(&vxi->vx_tasks);
7802 +}
7803 +
7804 +
7805 +extern void unhash_vx_info(struct vx_info *);
7806 +
7807 +#define release_vx_info(v, p) \
7808 +       __release_vx_info(v, p, __FILE__, __LINE__, __HERE__)
7809 +
7810 +static inline void __release_vx_info(struct vx_info *vxi,
7811 +       struct task_struct *task,
7812 +       const char *_file, int _line, void *_here)
7813 +{
7814 +       vxlprintk(VXD_CBIT(xid, 3), "release_vx_info(%p[#%d.%d.%d]) %p",
7815 +               vxi, vxi ? vxi->vx_id : 0,
7816 +               vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7817 +               vxi ? atomic_read(&vxi->vx_tasks) : 0,
7818 +               task, _file, _line);
7819 +       __vxh_release_vx_info(vxi, task, _here);
7820 +
7821 +       might_sleep();
7822 +
7823 +       if (atomic_dec_and_test(&vxi->vx_tasks))
7824 +               unhash_vx_info(vxi);
7825 +}
7826 +
7827 +
7828 +#define task_get_vx_info(p) \
7829 +       __task_get_vx_info(p, __FILE__, __LINE__, __HERE__)
7830 +
7831 +static inline struct vx_info *__task_get_vx_info(struct task_struct *p,
7832 +       const char *_file, int _line, void *_here)
7833 +{
7834 +       struct vx_info *vxi;
7835 +
7836 +       task_lock(p);
7837 +       vxlprintk(VXD_CBIT(xid, 5), "task_get_vx_info(%p)",
7838 +               p, _file, _line);
7839 +       vxi = __get_vx_info(p->vx_info, _file, _line, _here);
7840 +       task_unlock(p);
7841 +       return vxi;
7842 +}
7843 +
7844 +
7845 +static inline void __wakeup_vx_info(struct vx_info *vxi)
7846 +{
7847 +       if (waitqueue_active(&vxi->vx_wait))
7848 +               wake_up_interruptible(&vxi->vx_wait);
7849 +}
7850 +
7851 +
7852 +#define enter_vx_info(v, s) __enter_vx_info(v, s, __FILE__, __LINE__)
7853 +
7854 +static inline void __enter_vx_info(struct vx_info *vxi,
7855 +       struct vx_info_save *vxis, const char *_file, int _line)
7856 +{
7857 +       vxlprintk(VXD_CBIT(xid, 5), "enter_vx_info(%p[#%d],%p) %p[#%d,%p]",
7858 +               vxi, vxi ? vxi->vx_id : 0, vxis, current,
7859 +               current->xid, current->vx_info, _file, _line);
7860 +       vxis->vxi = xchg(&current->vx_info, vxi);
7861 +       vxis->xid = current->xid;
7862 +       current->xid = vxi ? vxi->vx_id : 0;
7863 +}
7864 +
7865 +#define leave_vx_info(s) __leave_vx_info(s, __FILE__, __LINE__)
7866 +
7867 +static inline void __leave_vx_info(struct vx_info_save *vxis,
7868 +       const char *_file, int _line)
7869 +{
7870 +       vxlprintk(VXD_CBIT(xid, 5), "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]",
7871 +               vxis, vxis->xid, vxis->vxi, current,
7872 +               current->xid, current->vx_info, _file, _line);
7873 +       (void)xchg(&current->vx_info, vxis->vxi);
7874 +       current->xid = vxis->xid;
7875 +}
7876 +
7877 +
7878 +static inline void __enter_vx_admin(struct vx_info_save *vxis)
7879 +{
7880 +       vxis->vxi = xchg(&current->vx_info, NULL);
7881 +       vxis->xid = xchg(&current->xid, (vxid_t)0);
7882 +}
7883 +
7884 +static inline void __leave_vx_admin(struct vx_info_save *vxis)
7885 +{
7886 +       (void)xchg(&current->xid, vxis->xid);
7887 +       (void)xchg(&current->vx_info, vxis->vxi);
7888 +}
7889 +
7890 +#define task_is_init(p) \
7891 +       __task_is_init(p, __FILE__, __LINE__, __HERE__)
7892 +
7893 +static inline int __task_is_init(struct task_struct *p,
7894 +       const char *_file, int _line, void *_here)
7895 +{
7896 +       int is_init = is_global_init(p);
7897 +
7898 +       task_lock(p);
7899 +       if (p->vx_info)
7900 +               is_init = p->vx_info->vx_initpid == p->pid;
7901 +       task_unlock(p);
7902 +       return is_init;
7903 +}
7904 +
7905 +extern void exit_vx_info(struct task_struct *, int);
7906 +extern void exit_vx_info_early(struct task_struct *, int);
7907 +
7908 +
7909 +#else
7910 +#warning duplicate inclusion
7911 +#endif
7912 diff -NurpP --minimal linux-4.1.41/include/linux/vs_cowbl.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_cowbl.h
7913 --- linux-4.1.41/include/linux/vs_cowbl.h       1970-01-01 00:00:00.000000000 +0000
7914 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_cowbl.h   2016-07-05 04:41:47.000000000 +0000
7915 @@ -0,0 +1,48 @@
7916 +#ifndef _VS_COWBL_H
7917 +#define _VS_COWBL_H
7918 +
7919 +#include <linux/fs.h>
7920 +#include <linux/dcache.h>
7921 +#include <linux/namei.h>
7922 +#include <linux/slab.h>
7923 +
7924 +extern struct dentry *cow_break_link(const char *pathname);
7925 +
7926 +static inline int cow_check_and_break(struct path *path)
7927 +{
7928 +       struct inode *inode = path->dentry->d_inode;
7929 +       int error = 0;
7930 +
7931 +       /* do we need this check? */
7932 +       if (IS_RDONLY(inode))
7933 +               return -EROFS;
7934 +
7935 +       if (IS_COW(inode)) {
7936 +               if (IS_COW_LINK(inode)) {
7937 +                       struct dentry *new_dentry, *old_dentry = path->dentry;
7938 +                       char *pp, *buf;
7939 +
7940 +                       buf = kmalloc(PATH_MAX, GFP_KERNEL);
7941 +                       if (!buf) {
7942 +                               return -ENOMEM;
7943 +                       }
7944 +                       pp = d_path(path, buf, PATH_MAX);
7945 +                       new_dentry = cow_break_link(pp);
7946 +                       kfree(buf);
7947 +                       if (!IS_ERR(new_dentry)) {
7948 +                               path->dentry = new_dentry;
7949 +                               dput(old_dentry);
7950 +                       } else
7951 +                               error = PTR_ERR(new_dentry);
7952 +               } else {
7953 +                       inode->i_flags &= ~(S_IXUNLINK | S_IMMUTABLE);
7954 +                       inode->i_ctime = CURRENT_TIME;
7955 +                       mark_inode_dirty(inode);
7956 +               }
7957 +       }
7958 +       return error;
7959 +}
7960 +
7961 +#else
7962 +#warning duplicate inclusion
7963 +#endif
7964 diff -NurpP --minimal linux-4.1.41/include/linux/vs_cvirt.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_cvirt.h
7965 --- linux-4.1.41/include/linux/vs_cvirt.h       1970-01-01 00:00:00.000000000 +0000
7966 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_cvirt.h   2016-07-05 04:41:47.000000000 +0000
7967 @@ -0,0 +1,50 @@
7968 +#ifndef _VS_CVIRT_H
7969 +#define _VS_CVIRT_H
7970 +
7971 +#include "vserver/cvirt.h"
7972 +#include "vserver/context.h"
7973 +#include "vserver/base.h"
7974 +#include "vserver/check.h"
7975 +#include "vserver/debug.h"
7976 +
7977 +
7978 +static inline void vx_activate_task(struct task_struct *p)
7979 +{
7980 +       struct vx_info *vxi;
7981 +
7982 +       if ((vxi = p->vx_info)) {
7983 +               vx_update_load(vxi);
7984 +               atomic_inc(&vxi->cvirt.nr_running);
7985 +       }
7986 +}
7987 +
7988 +static inline void vx_deactivate_task(struct task_struct *p)
7989 +{
7990 +       struct vx_info *vxi;
7991 +
7992 +       if ((vxi = p->vx_info)) {
7993 +               vx_update_load(vxi);
7994 +               atomic_dec(&vxi->cvirt.nr_running);
7995 +       }
7996 +}
7997 +
7998 +static inline void vx_uninterruptible_inc(struct task_struct *p)
7999 +{
8000 +       struct vx_info *vxi;
8001 +
8002 +       if ((vxi = p->vx_info))
8003 +               atomic_inc(&vxi->cvirt.nr_uninterruptible);
8004 +}
8005 +
8006 +static inline void vx_uninterruptible_dec(struct task_struct *p)
8007 +{
8008 +       struct vx_info *vxi;
8009 +
8010 +       if ((vxi = p->vx_info))
8011 +               atomic_dec(&vxi->cvirt.nr_uninterruptible);
8012 +}
8013 +
8014 +
8015 +#else
8016 +#warning duplicate inclusion
8017 +#endif
8018 diff -NurpP --minimal linux-4.1.41/include/linux/vs_device.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_device.h
8019 --- linux-4.1.41/include/linux/vs_device.h      1970-01-01 00:00:00.000000000 +0000
8020 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_device.h  2016-07-05 04:41:47.000000000 +0000
8021 @@ -0,0 +1,45 @@
8022 +#ifndef _VS_DEVICE_H
8023 +#define _VS_DEVICE_H
8024 +
8025 +#include "vserver/base.h"
8026 +#include "vserver/device.h"
8027 +#include "vserver/debug.h"
8028 +
8029 +
8030 +#ifdef CONFIG_VSERVER_DEVICE
8031 +
8032 +int vs_map_device(struct vx_info *, dev_t, dev_t *, umode_t);
8033 +
8034 +#define vs_device_perm(v, d, m, p) \
8035 +       ((vs_map_device(current_vx_info(), d, NULL, m) & (p)) == (p))
8036 +
8037 +#else
8038 +
8039 +static inline
8040 +int vs_map_device(struct vx_info *vxi,
8041 +       dev_t device, dev_t *target, umode_t mode)
8042 +{
8043 +       if (target)
8044 +               *target = device;
8045 +       return ~0;
8046 +}
8047 +
8048 +#define vs_device_perm(v, d, m, p) ((p) == (p))
8049 +
8050 +#endif
8051 +
8052 +
8053 +#define vs_map_chrdev(d, t, p) \
8054 +       ((vs_map_device(current_vx_info(), d, t, S_IFCHR) & (p)) == (p))
8055 +#define vs_map_blkdev(d, t, p) \
8056 +       ((vs_map_device(current_vx_info(), d, t, S_IFBLK) & (p)) == (p))
8057 +
8058 +#define vs_chrdev_perm(d, p) \
8059 +       vs_device_perm(current_vx_info(), d, S_IFCHR, p)
8060 +#define vs_blkdev_perm(d, p) \
8061 +       vs_device_perm(current_vx_info(), d, S_IFBLK, p)
8062 +
8063 +
8064 +#else
8065 +#warning duplicate inclusion
8066 +#endif
8067 diff -NurpP --minimal linux-4.1.41/include/linux/vs_dlimit.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_dlimit.h
8068 --- linux-4.1.41/include/linux/vs_dlimit.h      1970-01-01 00:00:00.000000000 +0000
8069 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_dlimit.h  2016-07-05 04:41:47.000000000 +0000
8070 @@ -0,0 +1,215 @@
8071 +#ifndef _VS_DLIMIT_H
8072 +#define _VS_DLIMIT_H
8073 +
8074 +#include <linux/fs.h>
8075 +
8076 +#include "vserver/dlimit.h"
8077 +#include "vserver/base.h"
8078 +#include "vserver/debug.h"
8079 +
8080 +
8081 +#define get_dl_info(i) __get_dl_info(i, __FILE__, __LINE__)
8082 +
8083 +static inline struct dl_info *__get_dl_info(struct dl_info *dli,
8084 +       const char *_file, int _line)
8085 +{
8086 +       if (!dli)
8087 +               return NULL;
8088 +       vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])",
8089 +               dli, dli ? dli->dl_tag : 0,
8090 +               dli ? atomic_read(&dli->dl_usecnt) : 0,
8091 +               _file, _line);
8092 +       atomic_inc(&dli->dl_usecnt);
8093 +       return dli;
8094 +}
8095 +
8096 +
8097 +#define free_dl_info(i) \
8098 +       call_rcu(&(i)->dl_rcu, rcu_free_dl_info)
8099 +
8100 +#define put_dl_info(i) __put_dl_info(i, __FILE__, __LINE__)
8101 +
8102 +static inline void __put_dl_info(struct dl_info *dli,
8103 +       const char *_file, int _line)
8104 +{
8105 +       if (!dli)
8106 +               return;
8107 +       vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])",
8108 +               dli, dli ? dli->dl_tag : 0,
8109 +               dli ? atomic_read(&dli->dl_usecnt) : 0,
8110 +               _file, _line);
8111 +       if (atomic_dec_and_test(&dli->dl_usecnt))
8112 +               free_dl_info(dli);
8113 +}
8114 +
8115 +
8116 +#define __dlimit_char(d)       ((d) ? '*' : ' ')
8117 +
8118 +static inline int __dl_alloc_space(struct super_block *sb,
8119 +       vtag_t tag, dlsize_t nr, const char *file, int line)
8120 +{
8121 +       struct dl_info *dli = NULL;
8122 +       int ret = 0;
8123 +
8124 +       if (nr == 0)
8125 +               goto out;
8126 +       dli = locate_dl_info(sb, tag);
8127 +       if (!dli)
8128 +               goto out;
8129 +
8130 +       spin_lock(&dli->dl_lock);
8131 +       ret = (dli->dl_space_used + nr > dli->dl_space_total);
8132 +       if (!ret)
8133 +               dli->dl_space_used += nr;
8134 +       spin_unlock(&dli->dl_lock);
8135 +       put_dl_info(dli);
8136 +out:
8137 +       vxlprintk(VXD_CBIT(dlim, 1),
8138 +               "ALLOC (%p,#%d)%c %lld bytes (%d)",
8139 +               sb, tag, __dlimit_char(dli), (long long)nr,
8140 +               ret, file, line);
8141 +       return ret ? -ENOSPC : 0;
8142 +}
8143 +
8144 +static inline void __dl_free_space(struct super_block *sb,
8145 +       vtag_t tag, dlsize_t nr, const char *_file, int _line)
8146 +{
8147 +       struct dl_info *dli = NULL;
8148 +
8149 +       if (nr == 0)
8150 +               goto out;
8151 +       dli = locate_dl_info(sb, tag);
8152 +       if (!dli)
8153 +               goto out;
8154 +
8155 +       spin_lock(&dli->dl_lock);
8156 +       if (dli->dl_space_used > nr)
8157 +               dli->dl_space_used -= nr;
8158 +       else
8159 +               dli->dl_space_used = 0;
8160 +       spin_unlock(&dli->dl_lock);
8161 +       put_dl_info(dli);
8162 +out:
8163 +       vxlprintk(VXD_CBIT(dlim, 1),
8164 +               "FREE  (%p,#%d)%c %lld bytes",
8165 +               sb, tag, __dlimit_char(dli), (long long)nr,
8166 +               _file, _line);
8167 +}
8168 +
8169 +static inline int __dl_alloc_inode(struct super_block *sb,
8170 +       vtag_t tag, const char *_file, int _line)
8171 +{
8172 +       struct dl_info *dli;
8173 +       int ret = 0;
8174 +
8175 +       dli = locate_dl_info(sb, tag);
8176 +       if (!dli)
8177 +               goto out;
8178 +
8179 +       spin_lock(&dli->dl_lock);
8180 +       dli->dl_inodes_used++;
8181 +       ret = (dli->dl_inodes_used > dli->dl_inodes_total);
8182 +       spin_unlock(&dli->dl_lock);
8183 +       put_dl_info(dli);
8184 +out:
8185 +       vxlprintk(VXD_CBIT(dlim, 0),
8186 +               "ALLOC (%p,#%d)%c inode (%d)",
8187 +               sb, tag, __dlimit_char(dli), ret, _file, _line);
8188 +       return ret ? -ENOSPC : 0;
8189 +}
8190 +
8191 +static inline void __dl_free_inode(struct super_block *sb,
8192 +       vtag_t tag, const char *_file, int _line)
8193 +{
8194 +       struct dl_info *dli;
8195 +
8196 +       dli = locate_dl_info(sb, tag);
8197 +       if (!dli)
8198 +               goto out;
8199 +
8200 +       spin_lock(&dli->dl_lock);
8201 +       if (dli->dl_inodes_used > 1)
8202 +               dli->dl_inodes_used--;
8203 +       else
8204 +               dli->dl_inodes_used = 0;
8205 +       spin_unlock(&dli->dl_lock);
8206 +       put_dl_info(dli);
8207 +out:
8208 +       vxlprintk(VXD_CBIT(dlim, 0),
8209 +               "FREE  (%p,#%d)%c inode",
8210 +               sb, tag, __dlimit_char(dli), _file, _line);
8211 +}
8212 +
8213 +static inline void __dl_adjust_block(struct super_block *sb, vtag_t tag,
8214 +       unsigned long long *free_blocks, unsigned long long *root_blocks,
8215 +       const char *_file, int _line)
8216 +{
8217 +       struct dl_info *dli;
8218 +       uint64_t broot, bfree;
8219 +
8220 +       dli = locate_dl_info(sb, tag);
8221 +       if (!dli)
8222 +               return;
8223 +
8224 +       spin_lock(&dli->dl_lock);
8225 +       broot = (dli->dl_space_total -
8226 +               (dli->dl_space_total >> 10) * dli->dl_nrlmult)
8227 +               >> sb->s_blocksize_bits;
8228 +       bfree = (dli->dl_space_total - dli->dl_space_used)
8229 +                       >> sb->s_blocksize_bits;
8230 +       spin_unlock(&dli->dl_lock);
8231 +
8232 +       vxlprintk(VXD_CBIT(dlim, 2),
8233 +               "ADJUST: %lld,%lld on %lld,%lld [mult=%d]",
8234 +               (long long)bfree, (long long)broot,
8235 +               *free_blocks, *root_blocks, dli->dl_nrlmult,
8236 +               _file, _line);
8237 +       if (free_blocks) {
8238 +               if (*free_blocks > bfree)
8239 +                       *free_blocks = bfree;
8240 +       }
8241 +       if (root_blocks) {
8242 +               if (*root_blocks > broot)
8243 +                       *root_blocks = broot;
8244 +       }
8245 +       put_dl_info(dli);
8246 +}
8247 +
8248 +#define dl_prealloc_space(in, bytes) \
8249 +       __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
8250 +               __FILE__, __LINE__ )
8251 +
8252 +#define dl_alloc_space(in, bytes) \
8253 +       __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
8254 +               __FILE__, __LINE__ )
8255 +
8256 +#define dl_reserve_space(in, bytes) \
8257 +       __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
8258 +               __FILE__, __LINE__ )
8259 +
8260 +#define dl_claim_space(in, bytes) (0)
8261 +
8262 +#define dl_release_space(in, bytes) \
8263 +       __dl_free_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
8264 +               __FILE__, __LINE__ )
8265 +
8266 +#define dl_free_space(in, bytes) \
8267 +       __dl_free_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
8268 +               __FILE__, __LINE__ )
8269 +
8270 +
8271 +
8272 +#define dl_alloc_inode(in) \
8273 +       __dl_alloc_inode((in)->i_sb, i_tag_read(in), __FILE__, __LINE__ )
8274 +
8275 +#define dl_free_inode(in) \
8276 +       __dl_free_inode((in)->i_sb, i_tag_read(in), __FILE__, __LINE__ )
8277 +
8278 +
8279 +#define dl_adjust_block(sb, tag, fb, rb) \
8280 +       __dl_adjust_block(sb, tag, fb, rb, __FILE__, __LINE__ )
8281 +
8282 +
8283 +#else
8284 +#warning duplicate inclusion
8285 +#endif
8286 diff -NurpP --minimal linux-4.1.41/include/linux/vs_inet.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_inet.h
8287 --- linux-4.1.41/include/linux/vs_inet.h        1970-01-01 00:00:00.000000000 +0000
8288 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_inet.h    2016-07-05 04:41:47.000000000 +0000
8289 @@ -0,0 +1,364 @@
8290 +#ifndef _VS_INET_H
8291 +#define _VS_INET_H
8292 +
8293 +#include "vserver/base.h"
8294 +#include "vserver/network.h"
8295 +#include "vserver/debug.h"
8296 +
8297 +#define IPI_LOOPBACK   htonl(INADDR_LOOPBACK)
8298 +
8299 +#define NXAV4(a)       NIPQUAD((a)->ip[0]), NIPQUAD((a)->ip[1]), \
8300 +                       NIPQUAD((a)->mask), (a)->type
8301 +#define NXAV4_FMT      "[" NIPQUAD_FMT "-" NIPQUAD_FMT "/" NIPQUAD_FMT ":%04x]"
8302 +
8303 +#define NIPQUAD(addr) \
8304 +       ((unsigned char *)&addr)[0], \
8305 +       ((unsigned char *)&addr)[1], \
8306 +       ((unsigned char *)&addr)[2], \
8307 +       ((unsigned char *)&addr)[3]
8308 +
8309 +#define NIPQUAD_FMT "%u.%u.%u.%u"
8310 +
8311 +
8312 +static inline
8313 +int v4_addr_match(struct nx_addr_v4 *nxa, __be32 addr, uint16_t tmask)
8314 +{
8315 +       __be32 ip = nxa->ip[0].s_addr;
8316 +       __be32 mask = nxa->mask.s_addr;
8317 +       __be32 bcast = ip | ~mask;
8318 +       int ret = 0;
8319 +
8320 +       switch (nxa->type & tmask) {
8321 +       case NXA_TYPE_MASK:
8322 +               ret = (ip == (addr & mask));
8323 +               break;
8324 +       case NXA_TYPE_ADDR:
8325 +               ret = 3;
8326 +               if (addr == ip)
8327 +                       break;
8328 +               /* fall through to broadcast */
8329 +       case NXA_MOD_BCAST:
8330 +               ret = ((tmask & NXA_MOD_BCAST) && (addr == bcast));
8331 +               break;
8332 +       case NXA_TYPE_RANGE:
8333 +               ret = ((nxa->ip[0].s_addr <= addr) &&
8334 +                       (nxa->ip[1].s_addr > addr));
8335 +               break;
8336 +       case NXA_TYPE_ANY:
8337 +               ret = 2;
8338 +               break;
8339 +       }
8340 +
8341 +       vxdprintk(VXD_CBIT(net, 0),
8342 +               "v4_addr_match(%p" NXAV4_FMT "," NIPQUAD_FMT ",%04x) = %d",
8343 +               nxa, NXAV4(nxa), NIPQUAD(addr), tmask, ret);
8344 +       return ret;
8345 +}
8346 +
8347 +static inline
8348 +int v4_addr_in_nx_info(struct nx_info *nxi, __be32 addr, uint16_t tmask)
8349 +{
8350 +       struct nx_addr_v4 *nxa;
8351 +       unsigned long irqflags;
8352 +       int ret = 1;
8353 +
8354 +       if (!nxi)
8355 +               goto out;
8356 +
8357 +       ret = 2;
8358 +       /* allow 127.0.0.1 when remapping lback */
8359 +       if ((tmask & NXA_LOOPBACK) &&
8360 +               (addr == IPI_LOOPBACK) &&
8361 +               nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
8362 +               goto out;
8363 +       ret = 3;
8364 +       /* check for lback address */
8365 +       if ((tmask & NXA_MOD_LBACK) &&
8366 +               (nxi->v4_lback.s_addr == addr))
8367 +               goto out;
8368 +       ret = 4;
8369 +       /* check for broadcast address */
8370 +       if ((tmask & NXA_MOD_BCAST) &&
8371 +               (nxi->v4_bcast.s_addr == addr))
8372 +               goto out;
8373 +       ret = 5;
8374 +
8375 +       /* check for v4 addresses */
8376 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
8377 +       for (nxa = &nxi->v4; nxa; nxa = nxa->next)
8378 +               if (v4_addr_match(nxa, addr, tmask))
8379 +                       goto out_unlock;
8380 +       ret = 0;
8381 +out_unlock:
8382 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
8383 +out:
8384 +       vxdprintk(VXD_CBIT(net, 0),
8385 +               "v4_addr_in_nx_info(%p[#%u]," NIPQUAD_FMT ",%04x) = %d",
8386 +               nxi, nxi ? nxi->nx_id : 0, NIPQUAD(addr), tmask, ret);
8387 +       return ret;
8388 +}
8389 +
8390 +static inline
8391 +int v4_nx_addr_match(struct nx_addr_v4 *nxa, struct nx_addr_v4 *addr, uint16_t mask)
8392 +{
8393 +       /* FIXME: needs full range checks */
8394 +       return v4_addr_match(nxa, addr->ip[0].s_addr, mask);
8395 +}
8396 +
8397 +static inline
8398 +int v4_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v4 *nxa, uint16_t mask)
8399 +{
8400 +       struct nx_addr_v4 *ptr;
8401 +       unsigned long irqflags;
8402 +       int ret = 1;
8403 +
8404 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
8405 +       for (ptr = &nxi->v4; ptr; ptr = ptr->next)
8406 +               if (v4_nx_addr_match(ptr, nxa, mask))
8407 +                       goto out_unlock;
8408 +       ret = 0;
8409 +out_unlock:
8410 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
8411 +       return ret;
8412 +}
8413 +
8414 +#include <net/inet_sock.h>
8415 +
8416 +/*
8417 + *     Check if a given address matches for a socket
8418 + *
8419 + *     nxi:            the socket's nx_info if any
8420 + *     addr:           to be verified address
8421 + */
8422 +static inline
8423 +int v4_sock_addr_match (
8424 +       struct nx_info *nxi,
8425 +       struct inet_sock *inet,
8426 +       __be32 addr)
8427 +{
8428 +       __be32 saddr = inet->inet_rcv_saddr;
8429 +       __be32 bcast = nxi ? nxi->v4_bcast.s_addr : INADDR_BROADCAST;
8430 +
8431 +       if (addr && (saddr == addr || bcast == addr))
8432 +               return 1;
8433 +       if (!saddr)
8434 +               return v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND);
8435 +       return 0;
8436 +}
8437 +
8438 +
8439 +/* inet related checks and helpers */
8440 +
8441 +
8442 +struct in_ifaddr;
8443 +struct net_device;
8444 +struct sock;
8445 +
8446 +#ifdef CONFIG_INET
8447 +
8448 +#include <linux/netdevice.h>
8449 +#include <linux/inetdevice.h>
8450 +#include <net/inet_sock.h>
8451 +#include <net/inet_timewait_sock.h>
8452 +
8453 +
8454 +int dev_in_nx_info(struct net_device *, struct nx_info *);
8455 +int v4_dev_in_nx_info(struct net_device *, struct nx_info *);
8456 +int nx_v4_addr_conflict(struct nx_info *, struct nx_info *);
8457 +
8458 +
8459 +/*
8460 + *     check if address is covered by socket
8461 + *
8462 + *     sk:     the socket to check against
8463 + *     addr:   the address in question (must be != 0)
8464 + */
8465 +
8466 +static inline
8467 +int __v4_addr_match_socket(const struct sock *sk, struct nx_addr_v4 *nxa)
8468 +{
8469 +       struct nx_info *nxi = sk->sk_nx_info;
8470 +       __be32 saddr = sk->sk_rcv_saddr;
8471 +
8472 +       vxdprintk(VXD_CBIT(net, 5),
8473 +               "__v4_addr_in_socket(%p," NXAV4_FMT ") %p:" NIPQUAD_FMT " %p;%lx",
8474 +               sk, NXAV4(nxa), nxi, NIPQUAD(saddr), sk->sk_socket,
8475 +               (sk->sk_socket?sk->sk_socket->flags:0));
8476 +
8477 +       if (saddr) {            /* direct address match */
8478 +               return v4_addr_match(nxa, saddr, -1);
8479 +       } else if (nxi) {       /* match against nx_info */
8480 +               return v4_nx_addr_in_nx_info(nxi, nxa, -1);
8481 +       } else {                /* unrestricted any socket */
8482 +               return 1;
8483 +       }
8484 +}
8485 +
8486 +
8487 +
8488 +static inline
8489 +int nx_dev_visible(struct nx_info *nxi, struct net_device *dev)
8490 +{
8491 +       vxdprintk(VXD_CBIT(net, 1),
8492 +               "nx_dev_visible(%p[#%u],%p " VS_Q("%s") ") %d",
8493 +               nxi, nxi ? nxi->nx_id : 0, dev, dev->name,
8494 +               nxi ? dev_in_nx_info(dev, nxi) : 0);
8495 +
8496 +       if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8497 +               return 1;
8498 +       if (dev_in_nx_info(dev, nxi))
8499 +               return 1;
8500 +       return 0;
8501 +}
8502 +
8503 +
8504 +static inline
8505 +int v4_ifa_in_nx_info(struct in_ifaddr *ifa, struct nx_info *nxi)
8506 +{
8507 +       if (!nxi)
8508 +               return 1;
8509 +       if (!ifa)
8510 +               return 0;
8511 +       return v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW);
8512 +}
8513 +
8514 +static inline
8515 +int nx_v4_ifa_visible(struct nx_info *nxi, struct in_ifaddr *ifa)
8516 +{
8517 +       vxdprintk(VXD_CBIT(net, 1), "nx_v4_ifa_visible(%p[#%u],%p) %d",
8518 +               nxi, nxi ? nxi->nx_id : 0, ifa,
8519 +               nxi ? v4_ifa_in_nx_info(ifa, nxi) : 0);
8520 +
8521 +       if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8522 +               return 1;
8523 +       if (v4_ifa_in_nx_info(ifa, nxi))
8524 +               return 1;
8525 +       return 0;
8526 +}
8527 +
8528 +
8529 +struct nx_v4_sock_addr {
8530 +       __be32 saddr;   /* Address used for validation */
8531 +       __be32 baddr;   /* Address used for socket bind */
8532 +};
8533 +
8534 +static inline
8535 +int v4_map_sock_addr(struct inet_sock *inet, struct sockaddr_in *addr,
8536 +       struct nx_v4_sock_addr *nsa)
8537 +{
8538 +       struct sock *sk = &inet->sk;
8539 +       struct nx_info *nxi = sk->sk_nx_info;
8540 +       __be32 saddr = addr->sin_addr.s_addr;
8541 +       __be32 baddr = saddr;
8542 +
8543 +       vxdprintk(VXD_CBIT(net, 3),
8544 +               "inet_bind(%p)* %p,%p;%lx " NIPQUAD_FMT,
8545 +               sk, sk->sk_nx_info, sk->sk_socket,
8546 +               (sk->sk_socket ? sk->sk_socket->flags : 0),
8547 +               NIPQUAD(saddr));
8548 +
8549 +       if (nxi) {
8550 +               if (saddr == INADDR_ANY) {
8551 +                       if (nx_info_flags(nxi, NXF_SINGLE_IP, 0))
8552 +                               baddr = nxi->v4.ip[0].s_addr;
8553 +               } else if (saddr == IPI_LOOPBACK) {
8554 +                       if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
8555 +                               baddr = nxi->v4_lback.s_addr;
8556 +               } else if (!ipv4_is_multicast(saddr) ||
8557 +                       !nx_info_ncaps(nxi, NXC_MULTICAST)) {
8558 +                       /* normal address bind */
8559 +                       if (!v4_addr_in_nx_info(nxi, saddr, NXA_MASK_BIND))
8560 +                               return -EADDRNOTAVAIL;
8561 +               }
8562 +       }
8563 +
8564 +       vxdprintk(VXD_CBIT(net, 3),
8565 +               "inet_bind(%p) " NIPQUAD_FMT ", " NIPQUAD_FMT,
8566 +               sk, NIPQUAD(saddr), NIPQUAD(baddr));
8567 +
8568 +       nsa->saddr = saddr;
8569 +       nsa->baddr = baddr;
8570 +       return 0;
8571 +}
8572 +
8573 +static inline
8574 +void v4_set_sock_addr(struct inet_sock *inet, struct nx_v4_sock_addr *nsa)
8575 +{
8576 +       inet->inet_saddr = nsa->baddr;
8577 +       inet->inet_rcv_saddr = nsa->baddr;
8578 +}
8579 +
8580 +
8581 +/*
8582 + *      helper to simplify inet_lookup_listener
8583 + *
8584 + *      nxi:   the socket's nx_info if any
8585 + *      addr:  to be verified address
8586 + *      saddr: socket address
8587 + */
8588 +static inline int v4_inet_addr_match (
8589 +       struct nx_info *nxi,
8590 +       __be32 addr,
8591 +       __be32 saddr)
8592 +{
8593 +       if (addr && (saddr == addr))
8594 +               return 1;
8595 +       if (!saddr)
8596 +               return nxi ? v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND) : 1;
8597 +       return 0;
8598 +}
8599 +
8600 +static inline __be32 nx_map_sock_lback(struct nx_info *nxi, __be32 addr)
8601 +{
8602 +       if (nx_info_flags(nxi, NXF_HIDE_LBACK, 0) &&
8603 +               (addr == nxi->v4_lback.s_addr))
8604 +               return IPI_LOOPBACK;
8605 +       return addr;
8606 +}
8607 +
8608 +static inline
8609 +int nx_info_has_v4(struct nx_info *nxi)
8610 +{
8611 +       if (!nxi)
8612 +               return 1;
8613 +       if (NX_IPV4(nxi))
8614 +               return 1;
8615 +       if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
8616 +               return 1;
8617 +       return 0;
8618 +}
8619 +
8620 +#else /* CONFIG_INET */
8621 +
8622 +static inline
8623 +int nx_dev_visible(struct nx_info *n, struct net_device *d)
8624 +{
8625 +       return 1;
8626 +}
8627 +
8628 +static inline
8629 +int nx_v4_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
8630 +{
8631 +       return 1;
8632 +}
8633 +
8634 +static inline
8635 +int v4_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
8636 +{
8637 +       return 1;
8638 +}
8639 +
8640 +static inline
8641 +int nx_info_has_v4(struct nx_info *nxi)
8642 +{
8643 +       return 0;
8644 +}
8645 +
8646 +#endif /* CONFIG_INET */
8647 +
8648 +#define current_nx_info_has_v4() \
8649 +       nx_info_has_v4(current_nx_info())
8650 +
8651 +#else
8652 +// #warning duplicate inclusion
8653 +#endif
8654 diff -NurpP --minimal linux-4.1.41/include/linux/vs_inet6.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_inet6.h
8655 --- linux-4.1.41/include/linux/vs_inet6.h       1970-01-01 00:00:00.000000000 +0000
8656 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_inet6.h   2016-07-05 04:41:47.000000000 +0000
8657 @@ -0,0 +1,257 @@
8658 +#ifndef _VS_INET6_H
8659 +#define _VS_INET6_H
8660 +
8661 +#include "vserver/base.h"
8662 +#include "vserver/network.h"
8663 +#include "vserver/debug.h"
8664 +
8665 +#include <net/ipv6.h>
8666 +
8667 +#define NXAV6(a)       &(a)->ip, &(a)->mask, (a)->prefix, (a)->type
8668 +#define NXAV6_FMT      "[%pI6/%pI6/%d:%04x]"
8669 +
8670 +
8671 +#ifdef CONFIG_IPV6
8672 +
8673 +static inline
8674 +int v6_addr_match(struct nx_addr_v6 *nxa,
8675 +       const struct in6_addr *addr, uint16_t mask)
8676 +{
8677 +       int ret = 0;
8678 +
8679 +       switch (nxa->type & mask) {
8680 +       case NXA_TYPE_MASK:
8681 +               ret = ipv6_masked_addr_cmp(&nxa->ip, &nxa->mask, addr);
8682 +               break;
8683 +       case NXA_TYPE_ADDR:
8684 +               ret = ipv6_addr_equal(&nxa->ip, addr);
8685 +               break;
8686 +       case NXA_TYPE_ANY:
8687 +               ret = 1;
8688 +               break;
8689 +       }
8690 +       vxdprintk(VXD_CBIT(net, 0),
8691 +               "v6_addr_match(%p" NXAV6_FMT ",%pI6,%04x) = %d",
8692 +               nxa, NXAV6(nxa), addr, mask, ret);
8693 +       return ret;
8694 +}
8695 +
8696 +static inline
8697 +int v6_addr_in_nx_info(struct nx_info *nxi,
8698 +       const struct in6_addr *addr, uint16_t mask)
8699 +{
8700 +       struct nx_addr_v6 *nxa;
8701 +       unsigned long irqflags;
8702 +       int ret = 1;
8703 +
8704 +       if (!nxi)
8705 +               goto out;
8706 +
8707 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
8708 +       for (nxa = &nxi->v6; nxa; nxa = nxa->next)
8709 +               if (v6_addr_match(nxa, addr, mask))
8710 +                       goto out_unlock;
8711 +       ret = 0;
8712 +out_unlock:
8713 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
8714 +out:
8715 +       vxdprintk(VXD_CBIT(net, 0),
8716 +               "v6_addr_in_nx_info(%p[#%u],%pI6,%04x) = %d",
8717 +               nxi, nxi ? nxi->nx_id : 0, addr, mask, ret);
8718 +       return ret;
8719 +}
8720 +
8721 +static inline
8722 +int v6_nx_addr_match(struct nx_addr_v6 *nxa, struct nx_addr_v6 *addr, uint16_t mask)
8723 +{
8724 +       /* FIXME: needs full range checks */
8725 +       return v6_addr_match(nxa, &addr->ip, mask);
8726 +}
8727 +
8728 +static inline
8729 +int v6_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v6 *nxa, uint16_t mask)
8730 +{
8731 +       struct nx_addr_v6 *ptr;
8732 +       unsigned long irqflags;
8733 +       int ret = 1;
8734 +
8735 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
8736 +       for (ptr = &nxi->v6; ptr; ptr = ptr->next)
8737 +               if (v6_nx_addr_match(ptr, nxa, mask))
8738 +                       goto out_unlock;
8739 +       ret = 0;
8740 +out_unlock:
8741 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
8742 +       return ret;
8743 +}
8744 +
8745 +
8746 +/*
8747 + *     Check if a given address matches for a socket
8748 + *
8749 + *     nxi:            the socket's nx_info if any
8750 + *     addr:           to be verified address
8751 + */
8752 +static inline
8753 +int v6_sock_addr_match (
8754 +       struct nx_info *nxi,
8755 +       struct inet_sock *inet,
8756 +       struct in6_addr *addr)
8757 +{
8758 +       struct sock *sk = &inet->sk;
8759 +       const struct in6_addr *saddr = inet6_rcv_saddr(sk);
8760 +
8761 +       if (!ipv6_addr_any(addr) &&
8762 +               ipv6_addr_equal(saddr, addr))
8763 +               return 1;
8764 +       if (ipv6_addr_any(saddr))
8765 +               return v6_addr_in_nx_info(nxi, addr, -1);
8766 +       return 0;
8767 +}
8768 +
8769 +/*
8770 + *     check if address is covered by socket
8771 + *
8772 + *     sk:     the socket to check against
8773 + *     addr:   the address in question (must be != 0)
8774 + */
8775 +
8776 +static inline
8777 +int __v6_addr_match_socket(const struct sock *sk, struct nx_addr_v6 *nxa)
8778 +{
8779 +       struct nx_info *nxi = sk->sk_nx_info;
8780 +       const struct in6_addr *saddr = inet6_rcv_saddr(sk);
8781 +
8782 +       vxdprintk(VXD_CBIT(net, 5),
8783 +               "__v6_addr_in_socket(%p," NXAV6_FMT ") %p:%pI6 %p;%lx",
8784 +               sk, NXAV6(nxa), nxi, saddr, sk->sk_socket,
8785 +               (sk->sk_socket?sk->sk_socket->flags:0));
8786 +
8787 +       if (!ipv6_addr_any(saddr)) {    /* direct address match */
8788 +               return v6_addr_match(nxa, saddr, -1);
8789 +       } else if (nxi) {               /* match against nx_info */
8790 +               return v6_nx_addr_in_nx_info(nxi, nxa, -1);
8791 +       } else {                        /* unrestricted any socket */
8792 +               return 1;
8793 +       }
8794 +}
8795 +
8796 +
8797 +/* inet related checks and helpers */
8798 +
8799 +
8800 +struct in_ifaddr;
8801 +struct net_device;
8802 +struct sock;
8803 +
8804 +
8805 +#include <linux/netdevice.h>
8806 +#include <linux/inetdevice.h>
8807 +#include <net/inet_timewait_sock.h>
8808 +
8809 +
8810 +int dev_in_nx_info(struct net_device *, struct nx_info *);
8811 +int v6_dev_in_nx_info(struct net_device *, struct nx_info *);
8812 +int nx_v6_addr_conflict(struct nx_info *, struct nx_info *);
8813 +
8814 +
8815 +
8816 +static inline
8817 +int v6_ifa_in_nx_info(struct inet6_ifaddr *ifa, struct nx_info *nxi)
8818 +{
8819 +       if (!nxi)
8820 +               return 1;
8821 +       if (!ifa)
8822 +               return 0;
8823 +       return v6_addr_in_nx_info(nxi, &ifa->addr, -1);
8824 +}
8825 +
8826 +static inline
8827 +int nx_v6_ifa_visible(struct nx_info *nxi, struct inet6_ifaddr *ifa)
8828 +{
8829 +       vxdprintk(VXD_CBIT(net, 1), "nx_v6_ifa_visible(%p[#%u],%p) %d",
8830 +               nxi, nxi ? nxi->nx_id : 0, ifa,
8831 +               nxi ? v6_ifa_in_nx_info(ifa, nxi) : 0);
8832 +
8833 +       if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8834 +               return 1;
8835 +       if (v6_ifa_in_nx_info(ifa, nxi))
8836 +               return 1;
8837 +       return 0;
8838 +}
8839 +
8840 +
8841 +struct nx_v6_sock_addr {
8842 +       struct in6_addr saddr;  /* Address used for validation */
8843 +       struct in6_addr baddr;  /* Address used for socket bind */
8844 +};
8845 +
8846 +static inline
8847 +int v6_map_sock_addr(struct inet_sock *inet, struct sockaddr_in6 *addr,
8848 +       struct nx_v6_sock_addr *nsa)
8849 +{
8850 +       // struct sock *sk = &inet->sk;
8851 +       // struct nx_info *nxi = sk->sk_nx_info;
8852 +       struct in6_addr saddr = addr->sin6_addr;
8853 +       struct in6_addr baddr = saddr;
8854 +
8855 +       nsa->saddr = saddr;
8856 +       nsa->baddr = baddr;
8857 +       return 0;
8858 +}
8859 +
8860 +static inline
8861 +void v6_set_sock_addr(struct inet_sock *inet, struct nx_v6_sock_addr *nsa)
8862 +{
8863 +       // struct sock *sk = &inet->sk;
8864 +       // struct in6_addr *saddr = inet6_rcv_saddr(sk);
8865 +
8866 +       // *saddr = nsa->baddr;
8867 +       // inet->inet_saddr = nsa->baddr;
8868 +}
8869 +
8870 +static inline
8871 +int nx_info_has_v6(struct nx_info *nxi)
8872 +{
8873 +       if (!nxi)
8874 +               return 1;
8875 +       if (NX_IPV6(nxi))
8876 +               return 1;
8877 +       return 0;
8878 +}
8879 +
8880 +#else /* CONFIG_IPV6 */
8881 +
8882 +static inline
8883 +int nx_v6_dev_visible(struct nx_info *n, struct net_device *d)
8884 +{
8885 +       return 1;
8886 +}
8887 +
8888 +
8889 +static inline
8890 +int nx_v6_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
8891 +{
8892 +       return 1;
8893 +}
8894 +
8895 +static inline
8896 +int v6_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
8897 +{
8898 +       return 1;
8899 +}
8900 +
8901 +static inline
8902 +int nx_info_has_v6(struct nx_info *nxi)
8903 +{
8904 +       return 0;
8905 +}
8906 +
8907 +#endif /* CONFIG_IPV6 */
8908 +
8909 +#define current_nx_info_has_v6() \
8910 +       nx_info_has_v6(current_nx_info())
8911 +
8912 +#else
8913 +#warning duplicate inclusion
8914 +#endif
8915 diff -NurpP --minimal linux-4.1.41/include/linux/vs_limit.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_limit.h
8916 --- linux-4.1.41/include/linux/vs_limit.h       1970-01-01 00:00:00.000000000 +0000
8917 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_limit.h   2016-07-05 04:41:47.000000000 +0000
8918 @@ -0,0 +1,140 @@
8919 +#ifndef _VS_LIMIT_H
8920 +#define _VS_LIMIT_H
8921 +
8922 +#include "vserver/limit.h"
8923 +#include "vserver/base.h"
8924 +#include "vserver/context.h"
8925 +#include "vserver/debug.h"
8926 +#include "vserver/context.h"
8927 +#include "vserver/limit_int.h"
8928 +
8929 +
8930 +#define vx_acc_cres(v, d, p, r) \
8931 +       __vx_acc_cres(v, r, d, p, __FILE__, __LINE__)
8932 +
8933 +#define vx_acc_cres_cond(x, d, p, r) \
8934 +       __vx_acc_cres(((x) == vx_current_xid()) ? current_vx_info() : 0, \
8935 +       r, d, p, __FILE__, __LINE__)
8936 +
8937 +
8938 +#define vx_add_cres(v, a, p, r) \
8939 +       __vx_add_cres(v, r, a, p, __FILE__, __LINE__)
8940 +#define vx_sub_cres(v, a, p, r)                vx_add_cres(v, -(a), p, r)
8941 +
8942 +#define vx_add_cres_cond(x, a, p, r) \
8943 +       __vx_add_cres(((x) == vx_current_xid()) ? current_vx_info() : 0, \
8944 +       r, a, p, __FILE__, __LINE__)
8945 +#define vx_sub_cres_cond(x, a, p, r)   vx_add_cres_cond(x, -(a), p, r)
8946 +
8947 +
8948 +/* process and file limits */
8949 +
8950 +#define vx_nproc_inc(p) \
8951 +       vx_acc_cres((p)->vx_info, 1, p, RLIMIT_NPROC)
8952 +
8953 +#define vx_nproc_dec(p) \
8954 +       vx_acc_cres((p)->vx_info,-1, p, RLIMIT_NPROC)
8955 +
8956 +#define vx_files_inc(f) \
8957 +       vx_acc_cres_cond((f)->f_xid, 1, f, RLIMIT_NOFILE)
8958 +
8959 +#define vx_files_dec(f) \
8960 +       vx_acc_cres_cond((f)->f_xid,-1, f, RLIMIT_NOFILE)
8961 +
8962 +#define vx_locks_inc(l) \
8963 +       vx_acc_cres_cond((l)->fl_xid, 1, l, RLIMIT_LOCKS)
8964 +
8965 +#define vx_locks_dec(l) \
8966 +       vx_acc_cres_cond((l)->fl_xid,-1, l, RLIMIT_LOCKS)
8967 +
8968 +#define vx_openfd_inc(f) \
8969 +       vx_acc_cres(current_vx_info(), 1, (void *)(long)(f), VLIMIT_OPENFD)
8970 +
8971 +#define vx_openfd_dec(f) \
8972 +       vx_acc_cres(current_vx_info(),-1, (void *)(long)(f), VLIMIT_OPENFD)
8973 +
8974 +
8975 +#define vx_cres_avail(v, n, r) \
8976 +       __vx_cres_avail(v, r, n, __FILE__, __LINE__)
8977 +
8978 +
8979 +#define vx_nproc_avail(n) \
8980 +       vx_cres_avail(current_vx_info(), n, RLIMIT_NPROC)
8981 +
8982 +#define vx_files_avail(n) \
8983 +       vx_cres_avail(current_vx_info(), n, RLIMIT_NOFILE)
8984 +
8985 +#define vx_locks_avail(n) \
8986 +       vx_cres_avail(current_vx_info(), n, RLIMIT_LOCKS)
8987 +
8988 +#define vx_openfd_avail(n) \
8989 +       vx_cres_avail(current_vx_info(), n, VLIMIT_OPENFD)
8990 +
8991 +
8992 +/* dentry limits */
8993 +
8994 +#define vx_dentry_inc(d) do {                                          \
8995 +       if (d_count(d) == 1)                                            \
8996 +               vx_acc_cres(current_vx_info(), 1, d, VLIMIT_DENTRY);    \
8997 +       } while (0)
8998 +
8999 +#define vx_dentry_dec(d) do {                                          \
9000 +       if (d_count(d) == 0)                                            \
9001 +               vx_acc_cres(current_vx_info(),-1, d, VLIMIT_DENTRY);    \
9002 +       } while (0)
9003 +
9004 +#define vx_dentry_avail(n) \
9005 +       vx_cres_avail(current_vx_info(), n, VLIMIT_DENTRY)
9006 +
9007 +
9008 +/* socket limits */
9009 +
9010 +#define vx_sock_inc(s) \
9011 +       vx_acc_cres((s)->sk_vx_info, 1, s, VLIMIT_NSOCK)
9012 +
9013 +#define vx_sock_dec(s) \
9014 +       vx_acc_cres((s)->sk_vx_info,-1, s, VLIMIT_NSOCK)
9015 +
9016 +#define vx_sock_avail(n) \
9017 +       vx_cres_avail(current_vx_info(), n, VLIMIT_NSOCK)
9018 +
9019 +
9020 +/* ipc resource limits */
9021 +
9022 +#define vx_ipcmsg_add(v, u, a) \
9023 +       vx_add_cres(v, a, u, RLIMIT_MSGQUEUE)
9024 +
9025 +#define vx_ipcmsg_sub(v, u, a) \
9026 +       vx_sub_cres(v, a, u, RLIMIT_MSGQUEUE)
9027 +
9028 +#define vx_ipcmsg_avail(v, a) \
9029 +       vx_cres_avail(v, a, RLIMIT_MSGQUEUE)
9030 +
9031 +
9032 +#define vx_ipcshm_add(v, k, a) \
9033 +       vx_add_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
9034 +
9035 +#define vx_ipcshm_sub(v, k, a) \
9036 +       vx_sub_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
9037 +
9038 +#define vx_ipcshm_avail(v, a) \
9039 +       vx_cres_avail(v, a, VLIMIT_SHMEM)
9040 +
9041 +
9042 +#define vx_semary_inc(a) \
9043 +       vx_acc_cres(current_vx_info(), 1, a, VLIMIT_SEMARY)
9044 +
9045 +#define vx_semary_dec(a) \
9046 +       vx_acc_cres(current_vx_info(), -1, a, VLIMIT_SEMARY)
9047 +
9048 +
9049 +#define vx_nsems_add(a,n) \
9050 +       vx_add_cres(current_vx_info(), n, a, VLIMIT_NSEMS)
9051 +
9052 +#define vx_nsems_sub(a,n) \
9053 +       vx_sub_cres(current_vx_info(), n, a, VLIMIT_NSEMS)
9054 +
9055 +
9056 +#else
9057 +#warning duplicate inclusion
9058 +#endif
9059 diff -NurpP --minimal linux-4.1.41/include/linux/vs_network.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_network.h
9060 --- linux-4.1.41/include/linux/vs_network.h     1970-01-01 00:00:00.000000000 +0000
9061 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_network.h 2016-07-05 04:41:47.000000000 +0000
9062 @@ -0,0 +1,169 @@
9063 +#ifndef _NX_VS_NETWORK_H
9064 +#define _NX_VS_NETWORK_H
9065 +
9066 +#include "vserver/context.h"
9067 +#include "vserver/network.h"
9068 +#include "vserver/base.h"
9069 +#include "vserver/check.h"
9070 +#include "vserver/debug.h"
9071 +
9072 +#include <linux/sched.h>
9073 +
9074 +
9075 +#define get_nx_info(i) __get_nx_info(i, __FILE__, __LINE__)
9076 +
9077 +static inline struct nx_info *__get_nx_info(struct nx_info *nxi,
9078 +       const char *_file, int _line)
9079 +{
9080 +       if (!nxi)
9081 +               return NULL;
9082 +
9083 +       vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])",
9084 +               nxi, nxi ? nxi->nx_id : 0,
9085 +               nxi ? atomic_read(&nxi->nx_usecnt) : 0,
9086 +               _file, _line);
9087 +
9088 +       atomic_inc(&nxi->nx_usecnt);
9089 +       return nxi;
9090 +}
9091 +
9092 +
9093 +extern void free_nx_info(struct nx_info *);
9094 +
9095 +#define put_nx_info(i) __put_nx_info(i, __FILE__, __LINE__)
9096 +
9097 +static inline void __put_nx_info(struct nx_info *nxi, const char *_file, int _line)
9098 +{
9099 +       if (!nxi)
9100 +               return;
9101 +
9102 +       vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])",
9103 +               nxi, nxi ? nxi->nx_id : 0,
9104 +               nxi ? atomic_read(&nxi->nx_usecnt) : 0,
9105 +               _file, _line);
9106 +
9107 +       if (atomic_dec_and_test(&nxi->nx_usecnt))
9108 +               free_nx_info(nxi);
9109 +}
9110 +
9111 +
9112 +#define init_nx_info(p, i) __init_nx_info(p, i, __FILE__, __LINE__)
9113 +
9114 +static inline void __init_nx_info(struct nx_info **nxp, struct nx_info *nxi,
9115 +               const char *_file, int _line)
9116 +{
9117 +       if (nxi) {
9118 +               vxlprintk(VXD_CBIT(nid, 3),
9119 +                       "init_nx_info(%p[#%d.%d])",
9120 +                       nxi, nxi ? nxi->nx_id : 0,
9121 +                       nxi ? atomic_read(&nxi->nx_usecnt) : 0,
9122 +                       _file, _line);
9123 +
9124 +               atomic_inc(&nxi->nx_usecnt);
9125 +       }
9126 +       *nxp = nxi;
9127 +}
9128 +
9129 +
9130 +#define set_nx_info(p, i) __set_nx_info(p, i, __FILE__, __LINE__)
9131 +
9132 +static inline void __set_nx_info(struct nx_info **nxp, struct nx_info *nxi,
9133 +       const char *_file, int _line)
9134 +{
9135 +       struct nx_info *nxo;
9136 +
9137 +       if (!nxi)
9138 +               return;
9139 +
9140 +       vxlprintk(VXD_CBIT(nid, 3), "set_nx_info(%p[#%d.%d])",
9141 +               nxi, nxi ? nxi->nx_id : 0,
9142 +               nxi ? atomic_read(&nxi->nx_usecnt) : 0,
9143 +               _file, _line);
9144 +
9145 +       atomic_inc(&nxi->nx_usecnt);
9146 +       nxo = xchg(nxp, nxi);
9147 +       BUG_ON(nxo);
9148 +}
9149 +
9150 +#define clr_nx_info(p) __clr_nx_info(p, __FILE__, __LINE__)
9151 +
9152 +static inline void __clr_nx_info(struct nx_info **nxp,
9153 +       const char *_file, int _line)
9154 +{
9155 +       struct nx_info *nxo;
9156 +
9157 +       nxo = xchg(nxp, NULL);
9158 +       if (!nxo)
9159 +               return;
9160 +
9161 +       vxlprintk(VXD_CBIT(nid, 3), "clr_nx_info(%p[#%d.%d])",
9162 +               nxo, nxo ? nxo->nx_id : 0,
9163 +               nxo ? atomic_read(&nxo->nx_usecnt) : 0,
9164 +               _file, _line);
9165 +
9166 +       if (atomic_dec_and_test(&nxo->nx_usecnt))
9167 +               free_nx_info(nxo);
9168 +}
9169 +
9170 +
9171 +#define claim_nx_info(v, p) __claim_nx_info(v, p, __FILE__, __LINE__)
9172 +
9173 +static inline void __claim_nx_info(struct nx_info *nxi,
9174 +       struct task_struct *task, const char *_file, int _line)
9175 +{
9176 +       vxlprintk(VXD_CBIT(nid, 3), "claim_nx_info(%p[#%d.%d.%d]) %p",
9177 +               nxi, nxi ? nxi->nx_id : 0,
9178 +               nxi?atomic_read(&nxi->nx_usecnt):0,
9179 +               nxi?atomic_read(&nxi->nx_tasks):0,
9180 +               task, _file, _line);
9181 +
9182 +       atomic_inc(&nxi->nx_tasks);
9183 +}
9184 +
9185 +
9186 +extern void unhash_nx_info(struct nx_info *);
9187 +
9188 +#define release_nx_info(v, p) __release_nx_info(v, p, __FILE__, __LINE__)
9189 +
9190 +static inline void __release_nx_info(struct nx_info *nxi,
9191 +       struct task_struct *task, const char *_file, int _line)
9192 +{
9193 +       vxlprintk(VXD_CBIT(nid, 3), "release_nx_info(%p[#%d.%d.%d]) %p",
9194 +               nxi, nxi ? nxi->nx_id : 0,
9195 +               nxi ? atomic_read(&nxi->nx_usecnt) : 0,
9196 +               nxi ? atomic_read(&nxi->nx_tasks) : 0,
9197 +               task, _file, _line);
9198 +
9199 +       might_sleep();
9200 +
9201 +       if (atomic_dec_and_test(&nxi->nx_tasks))
9202 +               unhash_nx_info(nxi);
9203 +}
9204 +
9205 +
9206 +#define task_get_nx_info(i)    __task_get_nx_info(i, __FILE__, __LINE__)
9207 +
9208 +static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p,
9209 +       const char *_file, int _line)
9210 +{
9211 +       struct nx_info *nxi;
9212 +
9213 +       task_lock(p);
9214 +       vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)",
9215 +               p, _file, _line);
9216 +       nxi = __get_nx_info(p->nx_info, _file, _line);
9217 +       task_unlock(p);
9218 +       return nxi;
9219 +}
9220 +
9221 +
9222 +static inline void exit_nx_info(struct task_struct *p)
9223 +{
9224 +       if (p->nx_info)
9225 +               release_nx_info(p->nx_info, p);
9226 +}
9227 +
9228 +
9229 +#else
9230 +#warning duplicate inclusion
9231 +#endif
9232 diff -NurpP --minimal linux-4.1.41/include/linux/vs_pid.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_pid.h
9233 --- linux-4.1.41/include/linux/vs_pid.h 1970-01-01 00:00:00.000000000 +0000
9234 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_pid.h     2016-07-05 04:41:47.000000000 +0000
9235 @@ -0,0 +1,50 @@
9236 +#ifndef _VS_PID_H
9237 +#define _VS_PID_H
9238 +
9239 +#include "vserver/base.h"
9240 +#include "vserver/check.h"
9241 +#include "vserver/context.h"
9242 +#include "vserver/debug.h"
9243 +#include "vserver/pid.h"
9244 +#include <linux/pid_namespace.h>
9245 +
9246 +
9247 +#define VXF_FAKE_INIT  (VXF_INFO_INIT | VXF_STATE_INIT)
9248 +
9249 +static inline
9250 +int vx_proc_task_visible(struct task_struct *task)
9251 +{
9252 +       if ((task->pid == 1) &&
9253 +               !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT))
9254 +               /* show a blend through init */
9255 +               goto visible;
9256 +       if (vx_check(vx_task_xid(task), VS_WATCH | VS_IDENT))
9257 +               goto visible;
9258 +       return 0;
9259 +visible:
9260 +       return 1;
9261 +}
9262 +
9263 +#define find_task_by_real_pid(pid) find_task_by_pid_ns(pid, &init_pid_ns)
9264 +
9265 +
9266 +static inline
9267 +struct task_struct *vx_get_proc_task(struct inode *inode, struct pid *pid)
9268 +{
9269 +       struct task_struct *task = get_pid_task(pid, PIDTYPE_PID);
9270 +
9271 +       if (task && !vx_proc_task_visible(task)) {
9272 +               vxdprintk(VXD_CBIT(misc, 6),
9273 +                       "dropping task (get) %p[#%u,%u] for %p[#%u,%u]",
9274 +                       task, task->xid, task->pid,
9275 +                       current, current->xid, current->pid);
9276 +               put_task_struct(task);
9277 +               task = NULL;
9278 +       }
9279 +       return task;
9280 +}
9281 +
9282 +
9283 +#else
9284 +#warning duplicate inclusion
9285 +#endif
9286 diff -NurpP --minimal linux-4.1.41/include/linux/vs_sched.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_sched.h
9287 --- linux-4.1.41/include/linux/vs_sched.h       1970-01-01 00:00:00.000000000 +0000
9288 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_sched.h   2016-07-05 04:41:47.000000000 +0000
9289 @@ -0,0 +1,40 @@
9290 +#ifndef _VS_SCHED_H
9291 +#define _VS_SCHED_H
9292 +
9293 +#include "vserver/base.h"
9294 +#include "vserver/context.h"
9295 +#include "vserver/sched.h"
9296 +
9297 +
9298 +#define MAX_PRIO_BIAS           20
9299 +#define MIN_PRIO_BIAS          -20
9300 +
9301 +static inline
9302 +int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
9303 +{
9304 +       struct vx_info *vxi = p->vx_info;
9305 +
9306 +       if (vxi)
9307 +               prio += vx_cpu(vxi, sched_pc).prio_bias;
9308 +       return prio;
9309 +}
9310 +
9311 +static inline void vx_account_user(struct vx_info *vxi,
9312 +       cputime_t cputime, int nice)
9313 +{
9314 +       if (!vxi)
9315 +               return;
9316 +       vx_cpu(vxi, sched_pc).user_ticks += cputime;
9317 +}
9318 +
9319 +static inline void vx_account_system(struct vx_info *vxi,
9320 +       cputime_t cputime, int idle)
9321 +{
9322 +       if (!vxi)
9323 +               return;
9324 +       vx_cpu(vxi, sched_pc).sys_ticks += cputime;
9325 +}
9326 +
9327 +#else
9328 +#warning duplicate inclusion
9329 +#endif
9330 diff -NurpP --minimal linux-4.1.41/include/linux/vs_socket.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_socket.h
9331 --- linux-4.1.41/include/linux/vs_socket.h      1970-01-01 00:00:00.000000000 +0000
9332 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_socket.h  2016-07-05 04:41:47.000000000 +0000
9333 @@ -0,0 +1,67 @@
9334 +#ifndef _VS_SOCKET_H
9335 +#define _VS_SOCKET_H
9336 +
9337 +#include "vserver/debug.h"
9338 +#include "vserver/base.h"
9339 +#include "vserver/cacct.h"
9340 +#include "vserver/context.h"
9341 +#include "vserver/tag.h"
9342 +
9343 +
9344 +/* socket accounting */
9345 +
9346 +#include <linux/socket.h>
9347 +
9348 +static inline int vx_sock_type(int family)
9349 +{
9350 +       switch (family) {
9351 +       case PF_UNSPEC:
9352 +               return VXA_SOCK_UNSPEC;
9353 +       case PF_UNIX:
9354 +               return VXA_SOCK_UNIX;
9355 +       case PF_INET:
9356 +               return VXA_SOCK_INET;
9357 +       case PF_INET6:
9358 +               return VXA_SOCK_INET6;
9359 +       case PF_PACKET:
9360 +               return VXA_SOCK_PACKET;
9361 +       default:
9362 +               return VXA_SOCK_OTHER;
9363 +       }
9364 +}
9365 +
9366 +#define vx_acc_sock(v, f, p, s) \
9367 +       __vx_acc_sock(v, f, p, s, __FILE__, __LINE__)
9368 +
9369 +static inline void __vx_acc_sock(struct vx_info *vxi,
9370 +       int family, int pos, int size, char *file, int line)
9371 +{
9372 +       if (vxi) {
9373 +               int type = vx_sock_type(family);
9374 +
9375 +               atomic_long_inc(&vxi->cacct.sock[type][pos].count);
9376 +               atomic_long_add(size, &vxi->cacct.sock[type][pos].total);
9377 +       }
9378 +}
9379 +
9380 +#define vx_sock_recv(sk, s) \
9381 +       vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, s)
9382 +#define vx_sock_send(sk, s) \
9383 +       vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, s)
9384 +#define vx_sock_fail(sk, s) \
9385 +       vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, s)
9386 +
9387 +
9388 +#define sock_vx_init(s) do {           \
9389 +       (s)->sk_xid = 0;                \
9390 +       (s)->sk_vx_info = NULL;         \
9391 +       } while (0)
9392 +
9393 +#define sock_nx_init(s) do {           \
9394 +       (s)->sk_nid = 0;                \
9395 +       (s)->sk_nx_info = NULL;         \
9396 +       } while (0)
9397 +
9398 +#else
9399 +#warning duplicate inclusion
9400 +#endif
9401 diff -NurpP --minimal linux-4.1.41/include/linux/vs_tag.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_tag.h
9402 --- linux-4.1.41/include/linux/vs_tag.h 1970-01-01 00:00:00.000000000 +0000
9403 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_tag.h     2016-07-05 04:41:47.000000000 +0000
9404 @@ -0,0 +1,47 @@
9405 +#ifndef _VS_TAG_H
9406 +#define _VS_TAG_H
9407 +
9408 +#include <linux/vserver/tag.h>
9409 +
9410 +/* check conditions */
9411 +
9412 +#define DX_ADMIN       0x0001
9413 +#define DX_WATCH       0x0002
9414 +#define DX_HOSTID      0x0008
9415 +
9416 +#define DX_IDENT       0x0010
9417 +
9418 +#define DX_ARG_MASK    0x0010
9419 +
9420 +
9421 +#define dx_task_tag(t) ((t)->tag)
9422 +
9423 +#define dx_current_tag() dx_task_tag(current)
9424 +
9425 +#define dx_check(c, m) __dx_check(dx_current_tag(), c, m)
9426 +
9427 +#define dx_weak_check(c, m)    ((m) ? dx_check(c, m) : 1)
9428 +
9429 +
9430 +/*
9431 + * check current context for ADMIN/WATCH and
9432 + * optionally against supplied argument
9433 + */
9434 +static inline int __dx_check(vtag_t cid, vtag_t id, unsigned int mode)
9435 +{
9436 +       if (mode & DX_ARG_MASK) {
9437 +               if ((mode & DX_IDENT) && (id == cid))
9438 +                       return 1;
9439 +       }
9440 +       return (((mode & DX_ADMIN) && (cid == 0)) ||
9441 +               ((mode & DX_WATCH) && (cid == 1)) ||
9442 +               ((mode & DX_HOSTID) && (id == 0)));
9443 +}
9444 +
9445 +struct inode;
9446 +int dx_permission(const struct inode *inode, int mask);
9447 +
9448 +
9449 +#else
9450 +#warning duplicate inclusion
9451 +#endif
9452 diff -NurpP --minimal linux-4.1.41/include/linux/vs_time.h linux-4.1.41-vs2.3.8.5.3/include/linux/vs_time.h
9453 --- linux-4.1.41/include/linux/vs_time.h        1970-01-01 00:00:00.000000000 +0000
9454 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vs_time.h    2016-07-05 04:41:47.000000000 +0000
9455 @@ -0,0 +1,19 @@
9456 +#ifndef _VS_TIME_H
9457 +#define _VS_TIME_H
9458 +
9459 +
9460 +/* time faking stuff */
9461 +
9462 +#ifdef CONFIG_VSERVER_VTIME
9463 +
9464 +extern void vx_adjust_timespec(struct timespec *ts);
9465 +extern int vx_settimeofday(const struct timespec *ts);
9466 +
9467 +#else
9468 +#define        vx_adjust_timespec(t)   do { } while (0)
9469 +#define        vx_settimeofday(t)      do_settimeofday(t)
9470 +#endif
9471 +
9472 +#else
9473 +#warning duplicate inclusion
9474 +#endif
9475 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/base.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/base.h
9476 --- linux-4.1.41/include/linux/vserver/base.h   1970-01-01 00:00:00.000000000 +0000
9477 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/base.h       2016-07-05 04:41:47.000000000 +0000
9478 @@ -0,0 +1,184 @@
9479 +#ifndef _VSERVER_BASE_H
9480 +#define _VSERVER_BASE_H
9481 +
9482 +
9483 +/* context state changes */
9484 +
9485 +enum {
9486 +       VSC_STARTUP = 1,
9487 +       VSC_SHUTDOWN,
9488 +
9489 +       VSC_NETUP,
9490 +       VSC_NETDOWN,
9491 +};
9492 +
9493 +
9494 +
9495 +#define vx_task_xid(t) ((t)->xid)
9496 +
9497 +#define vx_current_xid() vx_task_xid(current)
9498 +
9499 +#define current_vx_info() (current->vx_info)
9500 +
9501 +
9502 +#define nx_task_nid(t) ((t)->nid)
9503 +
9504 +#define nx_current_nid() nx_task_nid(current)
9505 +
9506 +#define current_nx_info() (current->nx_info)
9507 +
9508 +
9509 +/* generic flag merging */
9510 +
9511 +#define vs_check_flags(v, m, f)        (((v) & (m)) ^ (f))
9512 +
9513 +#define vs_mask_flags(v, f, m) (((v) & ~(m)) | ((f) & (m)))
9514 +
9515 +#define vs_mask_mask(v, f, m)  (((v) & ~(m)) | ((v) & (f) & (m)))
9516 +
9517 +#define vs_check_bit(v, n)     ((v) & (1LL << (n)))
9518 +
9519 +
9520 +/* context flags */
9521 +
9522 +#define __vx_flags(v)  ((v) ? (v)->vx_flags : 0)
9523 +
9524 +#define vx_current_flags()     __vx_flags(current_vx_info())
9525 +
9526 +#define vx_info_flags(v, m, f) \
9527 +       vs_check_flags(__vx_flags(v), m, f)
9528 +
9529 +#define task_vx_flags(t, m, f) \
9530 +       ((t) && vx_info_flags((t)->vx_info, m, f))
9531 +
9532 +#define vx_flags(m, f) vx_info_flags(current_vx_info(), m, f)
9533 +
9534 +
9535 +/* context caps */
9536 +
9537 +#define __vx_ccaps(v)  ((v) ? (v)->vx_ccaps : 0)
9538 +
9539 +#define vx_current_ccaps()     __vx_ccaps(current_vx_info())
9540 +
9541 +#define vx_info_ccaps(v, c)    (__vx_ccaps(v) & (c))
9542 +
9543 +#define vx_ccaps(c)    vx_info_ccaps(current_vx_info(), (c))
9544 +
9545 +
9546 +
9547 +/* network flags */
9548 +
9549 +#define __nx_flags(n)  ((n) ? (n)->nx_flags : 0)
9550 +
9551 +#define nx_current_flags()     __nx_flags(current_nx_info())
9552 +
9553 +#define nx_info_flags(n, m, f) \
9554 +       vs_check_flags(__nx_flags(n), m, f)
9555 +
9556 +#define task_nx_flags(t, m, f) \
9557 +       ((t) && nx_info_flags((t)->nx_info, m, f))
9558 +
9559 +#define nx_flags(m, f) nx_info_flags(current_nx_info(), m, f)
9560 +
9561 +
9562 +/* network caps */
9563 +
9564 +#define __nx_ncaps(n)  ((n) ? (n)->nx_ncaps : 0)
9565 +
9566 +#define nx_current_ncaps()     __nx_ncaps(current_nx_info())
9567 +
9568 +#define nx_info_ncaps(n, c)    (__nx_ncaps(n) & (c))
9569 +
9570 +#define nx_ncaps(c)    nx_info_ncaps(current_nx_info(), c)
9571 +
9572 +
9573 +/* context mask capabilities */
9574 +
9575 +#define __vx_mcaps(v)  ((v) ? (v)->vx_ccaps >> 32UL : ~0 )
9576 +
9577 +#define vx_info_mcaps(v, c)    (__vx_mcaps(v) & (c))
9578 +
9579 +#define vx_mcaps(c)    vx_info_mcaps(current_vx_info(), c)
9580 +
9581 +
9582 +/* context bcap mask */
9583 +
9584 +#define __vx_bcaps(v)          ((v)->vx_bcaps)
9585 +
9586 +#define vx_current_bcaps()     __vx_bcaps(current_vx_info())
9587 +
9588 +
9589 +/* mask given bcaps */
9590 +
9591 +#define vx_info_mbcaps(v, c)   ((v) ? cap_intersect(__vx_bcaps(v), c) : c)
9592 +
9593 +#define vx_mbcaps(c)           vx_info_mbcaps(current_vx_info(), c)
9594 +
9595 +
9596 +/* masked cap_bset */
9597 +
9598 +#define vx_info_cap_bset(v)    vx_info_mbcaps(v, current->cap_bset)
9599 +
9600 +#define vx_current_cap_bset()  vx_info_cap_bset(current_vx_info())
9601 +
9602 +#if 0
9603 +#define vx_info_mbcap(v, b) \
9604 +       (!vx_info_flags(v, VXF_STATE_SETUP, 0) ? \
9605 +       vx_info_bcaps(v, b) : (b))
9606 +
9607 +#define task_vx_mbcap(t, b) \
9608 +       vx_info_mbcap((t)->vx_info, (t)->b)
9609 +
9610 +#define vx_mbcap(b)    task_vx_mbcap(current, b)
9611 +#endif
9612 +
9613 +#define vx_cap_raised(v, c, f) cap_raised(vx_info_mbcaps(v, c), f)
9614 +
9615 +#define vx_capable(b, c) (capable(b) || \
9616 +       (cap_raised(current_cap(), b) && vx_ccaps(c)))
9617 +
9618 +#define vx_ns_capable(n, b, c) (ns_capable(n, b) || \
9619 +       (cap_raised(current_cap(), b) && vx_ccaps(c)))
9620 +
9621 +#define nx_capable(b, c) (capable(b) || \
9622 +       (cap_raised(current_cap(), b) && nx_ncaps(c)))
9623 +
9624 +#define nx_ns_capable(n, b, c) (ns_capable(n, b) || \
9625 +       (cap_raised(current_cap(), b) && nx_ncaps(c)))
9626 +
9627 +#define vx_task_initpid(t, n) \
9628 +       ((t)->vx_info && \
9629 +       ((t)->vx_info->vx_initpid == (n)))
9630 +
9631 +#define vx_current_initpid(n)  vx_task_initpid(current, n)
9632 +
9633 +
9634 +/* context unshare mask */
9635 +
9636 +#define __vx_umask(v)          ((v)->vx_umask)
9637 +
9638 +#define vx_current_umask()     __vx_umask(current_vx_info())
9639 +
9640 +#define vx_can_unshare(b, f) (capable(b) || \
9641 +       (cap_raised(current_cap(), b) && \
9642 +       !((f) & ~vx_current_umask())))
9643 +
9644 +#define vx_ns_can_unshare(n, b, f) (ns_capable(n, b) || \
9645 +       (cap_raised(current_cap(), b) && \
9646 +       !((f) & ~vx_current_umask())))
9647 +
9648 +#define __vx_wmask(v)          ((v)->vx_wmask)
9649 +
9650 +#define vx_current_wmask()     __vx_wmask(current_vx_info())
9651 +
9652 +
9653 +#define __vx_state(v)  ((v) ? ((v)->vx_state) : 0)
9654 +
9655 +#define vx_info_state(v, m)    (__vx_state(v) & (m))
9656 +
9657 +
9658 +#define __nx_state(n)  ((n) ? ((n)->nx_state) : 0)
9659 +
9660 +#define nx_info_state(n, m)    (__nx_state(n) & (m))
9661 +
9662 +#endif
9663 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/cacct.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/cacct.h
9664 --- linux-4.1.41/include/linux/vserver/cacct.h  1970-01-01 00:00:00.000000000 +0000
9665 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/cacct.h      2016-07-05 04:41:47.000000000 +0000
9666 @@ -0,0 +1,15 @@
9667 +#ifndef _VSERVER_CACCT_H
9668 +#define _VSERVER_CACCT_H
9669 +
9670 +
9671 +enum sock_acc_field {
9672 +       VXA_SOCK_UNSPEC = 0,
9673 +       VXA_SOCK_UNIX,
9674 +       VXA_SOCK_INET,
9675 +       VXA_SOCK_INET6,
9676 +       VXA_SOCK_PACKET,
9677 +       VXA_SOCK_OTHER,
9678 +       VXA_SOCK_SIZE   /* array size */
9679 +};
9680 +
9681 +#endif /* _VSERVER_CACCT_H */
9682 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/cacct_cmd.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/cacct_cmd.h
9683 --- linux-4.1.41/include/linux/vserver/cacct_cmd.h      1970-01-01 00:00:00.000000000 +0000
9684 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/cacct_cmd.h  2016-07-05 04:41:47.000000000 +0000
9685 @@ -0,0 +1,10 @@
9686 +#ifndef _VSERVER_CACCT_CMD_H
9687 +#define _VSERVER_CACCT_CMD_H
9688 +
9689 +
9690 +#include <linux/compiler.h>
9691 +#include <uapi/vserver/cacct_cmd.h>
9692 +
9693 +extern int vc_sock_stat(struct vx_info *, void __user *);
9694 +
9695 +#endif /* _VSERVER_CACCT_CMD_H */
9696 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/cacct_def.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/cacct_def.h
9697 --- linux-4.1.41/include/linux/vserver/cacct_def.h      1970-01-01 00:00:00.000000000 +0000
9698 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/cacct_def.h  2016-07-05 04:41:47.000000000 +0000
9699 @@ -0,0 +1,43 @@
9700 +#ifndef _VSERVER_CACCT_DEF_H
9701 +#define _VSERVER_CACCT_DEF_H
9702 +
9703 +#include <asm/atomic.h>
9704 +#include <linux/vserver/cacct.h>
9705 +
9706 +
9707 +struct _vx_sock_acc {
9708 +       atomic_long_t count;
9709 +       atomic_long_t total;
9710 +};
9711 +
9712 +/* context sub struct */
9713 +
9714 +struct _vx_cacct {
9715 +       struct _vx_sock_acc sock[VXA_SOCK_SIZE][3];
9716 +       atomic_t slab[8];
9717 +       atomic_t page[6][8];
9718 +};
9719 +
9720 +#ifdef CONFIG_VSERVER_DEBUG
9721 +
9722 +static inline void __dump_vx_cacct(struct _vx_cacct *cacct)
9723 +{
9724 +       int i, j;
9725 +
9726 +       printk("\t_vx_cacct:");
9727 +       for (i = 0; i < 6; i++) {
9728 +               struct _vx_sock_acc *ptr = cacct->sock[i];
9729 +
9730 +               printk("\t [%d] =", i);
9731 +               for (j = 0; j < 3; j++) {
9732 +                       printk(" [%d] = %8lu, %8lu", j,
9733 +                               atomic_long_read(&ptr[j].count),
9734 +                               atomic_long_read(&ptr[j].total));
9735 +               }
9736 +               printk("\n");
9737 +       }
9738 +}
9739 +
9740 +#endif
9741 +
9742 +#endif /* _VSERVER_CACCT_DEF_H */
9743 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/cacct_int.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/cacct_int.h
9744 --- linux-4.1.41/include/linux/vserver/cacct_int.h      1970-01-01 00:00:00.000000000 +0000
9745 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/cacct_int.h  2016-07-05 04:41:47.000000000 +0000
9746 @@ -0,0 +1,17 @@
9747 +#ifndef _VSERVER_CACCT_INT_H
9748 +#define _VSERVER_CACCT_INT_H
9749 +
9750 +static inline
9751 +unsigned long vx_sock_count(struct _vx_cacct *cacct, int type, int pos)
9752 +{
9753 +       return atomic_long_read(&cacct->sock[type][pos].count);
9754 +}
9755 +
9756 +
9757 +static inline
9758 +unsigned long vx_sock_total(struct _vx_cacct *cacct, int type, int pos)
9759 +{
9760 +       return atomic_long_read(&cacct->sock[type][pos].total);
9761 +}
9762 +
9763 +#endif /* _VSERVER_CACCT_INT_H */
9764 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/check.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/check.h
9765 --- linux-4.1.41/include/linux/vserver/check.h  1970-01-01 00:00:00.000000000 +0000
9766 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/check.h      2016-07-05 04:41:47.000000000 +0000
9767 @@ -0,0 +1,89 @@
9768 +#ifndef _VSERVER_CHECK_H
9769 +#define _VSERVER_CHECK_H
9770 +
9771 +
9772 +#define MAX_S_CONTEXT  65535   /* Arbitrary limit */
9773 +
9774 +#ifdef CONFIG_VSERVER_DYNAMIC_IDS
9775 +#define MIN_D_CONTEXT  49152   /* dynamic contexts start here */
9776 +#else
9777 +#define MIN_D_CONTEXT  65536
9778 +#endif
9779 +
9780 +/* check conditions */
9781 +
9782 +#define VS_ADMIN       0x0001
9783 +#define VS_WATCH       0x0002
9784 +#define VS_HIDE                0x0004
9785 +#define VS_HOSTID      0x0008
9786 +
9787 +#define VS_IDENT       0x0010
9788 +#define VS_EQUIV       0x0020
9789 +#define VS_PARENT      0x0040
9790 +#define VS_CHILD       0x0080
9791 +
9792 +#define VS_ARG_MASK    0x00F0
9793 +
9794 +#define VS_DYNAMIC     0x0100
9795 +#define VS_STATIC      0x0200
9796 +
9797 +#define VS_ATR_MASK    0x0F00
9798 +
9799 +#ifdef CONFIG_VSERVER_PRIVACY
9800 +#define VS_ADMIN_P     (0)
9801 +#define VS_WATCH_P     (0)
9802 +#else
9803 +#define VS_ADMIN_P     VS_ADMIN
9804 +#define VS_WATCH_P     VS_WATCH
9805 +#endif
9806 +
9807 +#define VS_HARDIRQ     0x1000
9808 +#define VS_SOFTIRQ     0x2000
9809 +#define VS_IRQ         0x4000
9810 +
9811 +#define VS_IRQ_MASK    0xF000
9812 +
9813 +#include <linux/hardirq.h>
9814 +
9815 +/*
9816 + * check current context for ADMIN/WATCH and
9817 + * optionally against supplied argument
9818 + */
9819 +static inline int __vs_check(int cid, int id, unsigned int mode)
9820 +{
9821 +       if (mode & VS_ARG_MASK) {
9822 +               if ((mode & VS_IDENT) && (id == cid))
9823 +                       return 1;
9824 +       }
9825 +       if (mode & VS_ATR_MASK) {
9826 +               if ((mode & VS_DYNAMIC) &&
9827 +                       (id >= MIN_D_CONTEXT) &&
9828 +                       (id <= MAX_S_CONTEXT))
9829 +                       return 1;
9830 +               if ((mode & VS_STATIC) &&
9831 +                       (id > 1) && (id < MIN_D_CONTEXT))
9832 +                       return 1;
9833 +       }
9834 +       if (mode & VS_IRQ_MASK) {
9835 +               if ((mode & VS_IRQ) && unlikely(in_interrupt()))
9836 +                       return 1;
9837 +               if ((mode & VS_HARDIRQ) && unlikely(in_irq()))
9838 +                       return 1;
9839 +               if ((mode & VS_SOFTIRQ) && unlikely(in_softirq()))
9840 +                       return 1;
9841 +       }
9842 +       return (((mode & VS_ADMIN) && (cid == 0)) ||
9843 +               ((mode & VS_WATCH) && (cid == 1)) ||
9844 +               ((mode & VS_HOSTID) && (id == 0)));
9845 +}
9846 +
9847 +#define vx_check(c, m) __vs_check(vx_current_xid(), c, (m) | VS_IRQ)
9848 +
9849 +#define vx_weak_check(c, m)    ((m) ? vx_check(c, m) : 1)
9850 +
9851 +
9852 +#define nx_check(c, m) __vs_check(nx_current_nid(), c, m)
9853 +
9854 +#define nx_weak_check(c, m)    ((m) ? nx_check(c, m) : 1)
9855 +
9856 +#endif
9857 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/context.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/context.h
9858 --- linux-4.1.41/include/linux/vserver/context.h        1970-01-01 00:00:00.000000000 +0000
9859 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/context.h    2016-07-05 04:41:47.000000000 +0000
9860 @@ -0,0 +1,110 @@
9861 +#ifndef _VSERVER_CONTEXT_H
9862 +#define _VSERVER_CONTEXT_H
9863 +
9864 +
9865 +#include <linux/list.h>
9866 +#include <linux/spinlock.h>
9867 +#include <linux/rcupdate.h>
9868 +#include <uapi/vserver/context.h>
9869 +
9870 +#include "limit_def.h"
9871 +#include "sched_def.h"
9872 +#include "cvirt_def.h"
9873 +#include "cacct_def.h"
9874 +#include "device_def.h"
9875 +
9876 +#define VX_SPACES      2
9877 +
9878 +struct _vx_info_pc {
9879 +       struct _vx_sched_pc sched_pc;
9880 +       struct _vx_cvirt_pc cvirt_pc;
9881 +};
9882 +
9883 +struct _vx_space {
9884 +       unsigned long vx_nsmask;                /* assignment mask */
9885 +       struct nsproxy *vx_nsproxy;             /* private namespaces */
9886 +       struct fs_struct *vx_fs;                /* private namespace fs */
9887 +       const struct cred *vx_cred;             /* task credentials */
9888 +};
9889 +
9890 +struct vx_info {
9891 +       struct hlist_node vx_hlist;             /* linked list of contexts */
9892 +       vxid_t vx_id;                           /* context id */
9893 +       atomic_t vx_usecnt;                     /* usage count */
9894 +       atomic_t vx_tasks;                      /* tasks count */
9895 +       struct vx_info *vx_parent;              /* parent context */
9896 +       int vx_state;                           /* context state */
9897 +
9898 +       struct _vx_space space[VX_SPACES];      /* namespace store */
9899 +
9900 +       uint64_t vx_flags;                      /* context flags */
9901 +       uint64_t vx_ccaps;                      /* context caps (vserver) */
9902 +       uint64_t vx_umask;                      /* unshare mask (guest) */
9903 +       uint64_t vx_wmask;                      /* warn mask (guest) */
9904 +       kernel_cap_t vx_bcaps;                  /* bounding caps (system) */
9905 +
9906 +       struct task_struct *vx_reaper;          /* guest reaper process */
9907 +       pid_t vx_initpid;                       /* PID of guest init */
9908 +       int64_t vx_badness_bias;                /* OOM points bias */
9909 +
9910 +       struct _vx_limit limit;                 /* vserver limits */
9911 +       struct _vx_sched sched;                 /* vserver scheduler */
9912 +       struct _vx_cvirt cvirt;                 /* virtual/bias stuff */
9913 +       struct _vx_cacct cacct;                 /* context accounting */
9914 +
9915 +       struct _vx_device dmap;                 /* default device map targets */
9916 +
9917 +#ifndef CONFIG_SMP
9918 +       struct _vx_info_pc info_pc;             /* per cpu data */
9919 +#else
9920 +       struct _vx_info_pc *ptr_pc;             /* per cpu array */
9921 +#endif
9922 +
9923 +       wait_queue_head_t vx_wait;              /* context exit waitqueue */
9924 +       int reboot_cmd;                         /* last sys_reboot() cmd */
9925 +       int exit_code;                          /* last process exit code */
9926 +
9927 +       char vx_name[65];                       /* vserver name */
9928 +};
9929 +
9930 +#ifndef CONFIG_SMP
9931 +#define        vx_ptr_pc(vxi)          (&(vxi)->info_pc)
9932 +#define        vx_per_cpu(vxi, v, id)  vx_ptr_pc(vxi)->v
9933 +#else
9934 +#define        vx_ptr_pc(vxi)          ((vxi)->ptr_pc)
9935 +#define        vx_per_cpu(vxi, v, id)  per_cpu_ptr(vx_ptr_pc(vxi), id)->v
9936 +#endif
9937 +
9938 +#define        vx_cpu(vxi, v)          vx_per_cpu(vxi, v, smp_processor_id())
9939 +
9940 +
9941 +struct vx_info_save {
9942 +       struct vx_info *vxi;
9943 +       vxid_t xid;
9944 +};
9945 +
9946 +
9947 +/* status flags */
9948 +
9949 +#define VXS_HASHED     0x0001
9950 +#define VXS_PAUSED     0x0010
9951 +#define VXS_SHUTDOWN   0x0100
9952 +#define VXS_HELPER     0x1000
9953 +#define VXS_RELEASED   0x8000
9954 +
9955 +
9956 +extern void claim_vx_info(struct vx_info *, struct task_struct *);
9957 +extern void release_vx_info(struct vx_info *, struct task_struct *);
9958 +
9959 +extern struct vx_info *lookup_vx_info(int);
9960 +extern struct vx_info *lookup_or_create_vx_info(int);
9961 +
9962 +extern int get_xid_list(int, unsigned int *, int);
9963 +extern int xid_is_hashed(vxid_t);
9964 +
9965 +extern int vx_migrate_task(struct task_struct *, struct vx_info *, int);
9966 +
9967 +extern long vs_state_change(struct vx_info *, unsigned int);
9968 +
9969 +
9970 +#endif /* _VSERVER_CONTEXT_H */
9971 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/context_cmd.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/context_cmd.h
9972 --- linux-4.1.41/include/linux/vserver/context_cmd.h    1970-01-01 00:00:00.000000000 +0000
9973 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/context_cmd.h        2016-07-05 04:41:47.000000000 +0000
9974 @@ -0,0 +1,33 @@
9975 +#ifndef _VSERVER_CONTEXT_CMD_H
9976 +#define _VSERVER_CONTEXT_CMD_H
9977 +
9978 +#include <uapi/vserver/context_cmd.h>
9979 +
9980 +extern int vc_task_xid(uint32_t);
9981 +
9982 +extern int vc_vx_info(struct vx_info *, void __user *);
9983 +
9984 +extern int vc_ctx_stat(struct vx_info *, void __user *);
9985 +
9986 +extern int vc_ctx_create(uint32_t, void __user *);
9987 +extern int vc_ctx_migrate(struct vx_info *, void __user *);
9988 +
9989 +extern int vc_get_cflags(struct vx_info *, void __user *);
9990 +extern int vc_set_cflags(struct vx_info *, void __user *);
9991 +
9992 +extern int vc_get_ccaps(struct vx_info *, void __user *);
9993 +extern int vc_set_ccaps(struct vx_info *, void __user *);
9994 +
9995 +extern int vc_get_bcaps(struct vx_info *, void __user *);
9996 +extern int vc_set_bcaps(struct vx_info *, void __user *);
9997 +
9998 +extern int vc_get_umask(struct vx_info *, void __user *);
9999 +extern int vc_set_umask(struct vx_info *, void __user *);
10000 +
10001 +extern int vc_get_wmask(struct vx_info *, void __user *);
10002 +extern int vc_set_wmask(struct vx_info *, void __user *);
10003 +
10004 +extern int vc_get_badness(struct vx_info *, void __user *);
10005 +extern int vc_set_badness(struct vx_info *, void __user *);
10006 +
10007 +#endif /* _VSERVER_CONTEXT_CMD_H */
10008 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/cvirt.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/cvirt.h
10009 --- linux-4.1.41/include/linux/vserver/cvirt.h  1970-01-01 00:00:00.000000000 +0000
10010 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/cvirt.h      2016-07-05 04:41:47.000000000 +0000
10011 @@ -0,0 +1,18 @@
10012 +#ifndef _VSERVER_CVIRT_H
10013 +#define _VSERVER_CVIRT_H
10014 +
10015 +struct timespec;
10016 +
10017 +void vx_vsi_boottime(struct timespec *);
10018 +
10019 +void vx_vsi_uptime(struct timespec *, struct timespec *);
10020 +
10021 +
10022 +struct vx_info;
10023 +
10024 +void vx_update_load(struct vx_info *);
10025 +
10026 +
10027 +int vx_do_syslog(int, char __user *, int);
10028 +
10029 +#endif /* _VSERVER_CVIRT_H */
10030 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/cvirt_cmd.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/cvirt_cmd.h
10031 --- linux-4.1.41/include/linux/vserver/cvirt_cmd.h      1970-01-01 00:00:00.000000000 +0000
10032 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/cvirt_cmd.h  2016-07-05 04:41:47.000000000 +0000
10033 @@ -0,0 +1,13 @@
10034 +#ifndef _VSERVER_CVIRT_CMD_H
10035 +#define _VSERVER_CVIRT_CMD_H
10036 +
10037 +
10038 +#include <linux/compiler.h>
10039 +#include <uapi/vserver/cvirt_cmd.h>
10040 +
10041 +extern int vc_set_vhi_name(struct vx_info *, void __user *);
10042 +extern int vc_get_vhi_name(struct vx_info *, void __user *);
10043 +
10044 +extern int vc_virt_stat(struct vx_info *, void __user *);
10045 +
10046 +#endif /* _VSERVER_CVIRT_CMD_H */
10047 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/cvirt_def.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/cvirt_def.h
10048 --- linux-4.1.41/include/linux/vserver/cvirt_def.h      1970-01-01 00:00:00.000000000 +0000
10049 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/cvirt_def.h  2016-07-05 04:41:47.000000000 +0000
10050 @@ -0,0 +1,80 @@
10051 +#ifndef _VSERVER_CVIRT_DEF_H
10052 +#define _VSERVER_CVIRT_DEF_H
10053 +
10054 +#include <linux/jiffies.h>
10055 +#include <linux/spinlock.h>
10056 +#include <linux/wait.h>
10057 +#include <linux/time.h>
10058 +#include <asm/atomic.h>
10059 +
10060 +
10061 +struct _vx_usage_stat {
10062 +       uint64_t user;
10063 +       uint64_t nice;
10064 +       uint64_t system;
10065 +       uint64_t softirq;
10066 +       uint64_t irq;
10067 +       uint64_t idle;
10068 +       uint64_t iowait;
10069 +};
10070 +
10071 +struct _vx_syslog {
10072 +       wait_queue_head_t log_wait;
10073 +       spinlock_t logbuf_lock;         /* lock for the log buffer */
10074 +
10075 +       unsigned long log_start;        /* next char to be read by syslog() */
10076 +       unsigned long con_start;        /* next char to be sent to consoles */
10077 +       unsigned long log_end;  /* most-recently-written-char + 1 */
10078 +       unsigned long logged_chars;     /* #chars since last read+clear operation */
10079 +
10080 +       char log_buf[1024];
10081 +};
10082 +
10083 +
10084 +/* context sub struct */
10085 +
10086 +struct _vx_cvirt {
10087 +       atomic_t nr_threads;            /* number of current threads */
10088 +       atomic_t nr_running;            /* number of running threads */
10089 +       atomic_t nr_uninterruptible;    /* number of uninterruptible threads */
10090 +
10091 +       atomic_t nr_onhold;             /* processes on hold */
10092 +       uint32_t onhold_last;           /* jiffies when put on hold */
10093 +
10094 +       struct timespec bias_ts;        /* time offset to the host */
10095 +       struct timespec bias_idle;
10096 +       struct timespec bias_uptime;    /* context creation point */
10097 +       uint64_t bias_clock;            /* offset in clock_t */
10098 +
10099 +       spinlock_t load_lock;           /* lock for the load averages */
10100 +       atomic_t load_updates;          /* nr of load updates done so far */
10101 +       uint32_t load_last;             /* last time load was calculated */
10102 +       uint32_t load[3];               /* load averages 1,5,15 */
10103 +
10104 +       atomic_t total_forks;           /* number of forks so far */
10105 +
10106 +       struct _vx_syslog syslog;
10107 +};
10108 +
10109 +struct _vx_cvirt_pc {
10110 +       struct _vx_usage_stat cpustat;
10111 +};
10112 +
10113 +
10114 +#ifdef CONFIG_VSERVER_DEBUG
10115 +
10116 +static inline void __dump_vx_cvirt(struct _vx_cvirt *cvirt)
10117 +{
10118 +       printk("\t_vx_cvirt:\n");
10119 +       printk("\t threads: %4d, %4d, %4d, %4d\n",
10120 +               atomic_read(&cvirt->nr_threads),
10121 +               atomic_read(&cvirt->nr_running),
10122 +               atomic_read(&cvirt->nr_uninterruptible),
10123 +               atomic_read(&cvirt->nr_onhold));
10124 +       /* add rest here */
10125 +       printk("\t total_forks = %d\n", atomic_read(&cvirt->total_forks));
10126 +}
10127 +
10128 +#endif
10129 +
10130 +#endif /* _VSERVER_CVIRT_DEF_H */
10131 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/debug.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/debug.h
10132 --- linux-4.1.41/include/linux/vserver/debug.h  1970-01-01 00:00:00.000000000 +0000
10133 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/debug.h      2016-07-05 04:41:47.000000000 +0000
10134 @@ -0,0 +1,146 @@
10135 +#ifndef _VSERVER_DEBUG_H
10136 +#define _VSERVER_DEBUG_H
10137 +
10138 +
10139 +#define VXD_CBIT(n, m) (vs_debug_ ## n & (1 << (m)))
10140 +#define VXD_CMIN(n, m) (vs_debug_ ## n > (m))
10141 +#define VXD_MASK(n, m) (vs_debug_ ## n & (m))
10142 +
10143 +#define VXD_DEV(d)     (d), (d)->bd_inode->i_ino,              \
10144 +                       imajor((d)->bd_inode), iminor((d)->bd_inode)
10145 +#define VXF_DEV                "%p[%lu,%d:%d]"
10146 +
10147 +#if    defined(CONFIG_QUOTES_UTF8)
10148 +#define        VS_Q_LQM        "\xc2\xbb"
10149 +#define        VS_Q_RQM        "\xc2\xab"
10150 +#elif  defined(CONFIG_QUOTES_ASCII)
10151 +#define        VS_Q_LQM        "\x27"
10152 +#define        VS_Q_RQM        "\x27"
10153 +#else
10154 +#define        VS_Q_LQM        "\xbb"
10155 +#define        VS_Q_RQM        "\xab"
10156 +#endif
10157 +
10158 +#define        VS_Q(f)         VS_Q_LQM f VS_Q_RQM
10159 +
10160 +
10161 +#define vxd_path(p)                                            \
10162 +       ({ static char _buffer[PATH_MAX];                       \
10163 +          d_path(p, _buffer, sizeof(_buffer)); })
10164 +
10165 +#define vxd_cond_path(n)                                       \
10166 +       ((n) ? vxd_path(&(n)->path) : "<null>" )
10167 +
10168 +
10169 +#ifdef CONFIG_VSERVER_DEBUG
10170 +
10171 +extern unsigned int vs_debug_switch;
10172 +extern unsigned int vs_debug_xid;
10173 +extern unsigned int vs_debug_nid;
10174 +extern unsigned int vs_debug_tag;
10175 +extern unsigned int vs_debug_net;
10176 +extern unsigned int vs_debug_limit;
10177 +extern unsigned int vs_debug_cres;
10178 +extern unsigned int vs_debug_dlim;
10179 +extern unsigned int vs_debug_quota;
10180 +extern unsigned int vs_debug_cvirt;
10181 +extern unsigned int vs_debug_space;
10182 +extern unsigned int vs_debug_perm;
10183 +extern unsigned int vs_debug_misc;
10184 +
10185 +
10186 +#define VX_LOGLEVEL    "vxD: "
10187 +#define VX_PROC_FMT    "%p: "
10188 +#define VX_PROCESS     current
10189 +
10190 +#define vxdprintk(c, f, x...)                                  \
10191 +       do {                                                    \
10192 +               if (c)                                          \
10193 +                       printk(VX_LOGLEVEL VX_PROC_FMT f "\n",  \
10194 +                               VX_PROCESS , ##x);              \
10195 +       } while (0)
10196 +
10197 +#define vxlprintk(c, f, x...)                                  \
10198 +       do {                                                    \
10199 +               if (c)                                          \
10200 +                       printk(VX_LOGLEVEL f " @%s:%d\n", x);   \
10201 +       } while (0)
10202 +
10203 +#define vxfprintk(c, f, x...)                                  \
10204 +       do {                                                    \
10205 +               if (c)                                          \
10206 +                       printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \
10207 +       } while (0)
10208 +
10209 +
10210 +struct vx_info;
10211 +
10212 +void dump_vx_info(struct vx_info *, int);
10213 +void dump_vx_info_inactive(int);
10214 +
10215 +#else  /* CONFIG_VSERVER_DEBUG */
10216 +
10217 +#define vs_debug_switch        0
10218 +#define vs_debug_xid   0
10219 +#define vs_debug_nid   0
10220 +#define vs_debug_tag   0
10221 +#define vs_debug_net   0
10222 +#define vs_debug_limit 0
10223 +#define vs_debug_cres  0
10224 +#define vs_debug_dlim  0
10225 +#define vs_debug_quota 0
10226 +#define vs_debug_cvirt 0
10227 +#define vs_debug_space 0
10228 +#define vs_debug_perm  0
10229 +#define vs_debug_misc  0
10230 +
10231 +#define vxdprintk(x...) do { } while (0)
10232 +#define vxlprintk(x...) do { } while (0)
10233 +#define vxfprintk(x...) do { } while (0)
10234 +
10235 +#endif /* CONFIG_VSERVER_DEBUG */
10236 +
10237 +
10238 +#ifdef CONFIG_VSERVER_WARN
10239 +
10240 +#define VX_WARNLEVEL   KERN_WARNING "vxW: "
10241 +#define VX_WARN_TASK   "[" VS_Q("%s") ",%u:#%u|%u|%u] "
10242 +#define VX_WARN_XID    "[xid #%u] "
10243 +#define VX_WARN_NID    "[nid #%u] "
10244 +#define VX_WARN_TAG    "[tag #%u] "
10245 +
10246 +#define vxwprintk(c, f, x...)                                  \
10247 +       do {                                                    \
10248 +               if (c)                                          \
10249 +                       printk(VX_WARNLEVEL f "\n", ##x);       \
10250 +       } while (0)
10251 +
10252 +#else  /* CONFIG_VSERVER_WARN */
10253 +
10254 +#define vxwprintk(x...) do { } while (0)
10255 +
10256 +#endif /* CONFIG_VSERVER_WARN */
10257 +
10258 +#define vxwprintk_task(c, f, x...)                             \
10259 +       vxwprintk(c, VX_WARN_TASK f,                            \
10260 +               current->comm, current->pid,                    \
10261 +               current->xid, current->nid,                     \
10262 +               current->tag, ##x)
10263 +#define vxwprintk_xid(c, f, x...)                              \
10264 +       vxwprintk(c, VX_WARN_XID f, current->xid, x)
10265 +#define vxwprintk_nid(c, f, x...)                              \
10266 +       vxwprintk(c, VX_WARN_NID f, current->nid, x)
10267 +#define vxwprintk_tag(c, f, x...)                              \
10268 +       vxwprintk(c, VX_WARN_TAG f, current->tag, x)
10269 +
10270 +#ifdef CONFIG_VSERVER_DEBUG
10271 +#define vxd_assert_lock(l)     assert_spin_locked(l)
10272 +#define vxd_assert(c, f, x...) vxlprintk(!(c), \
10273 +       "assertion [" f "] failed.", ##x, __FILE__, __LINE__)
10274 +#else
10275 +#define vxd_assert_lock(l)     do { } while (0)
10276 +#define vxd_assert(c, f, x...) do { } while (0)
10277 +#endif
10278 +
10279 +
10280 +#endif /* _VSERVER_DEBUG_H */
10281 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/debug_cmd.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/debug_cmd.h
10282 --- linux-4.1.41/include/linux/vserver/debug_cmd.h      1970-01-01 00:00:00.000000000 +0000
10283 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/debug_cmd.h  2016-07-05 04:41:47.000000000 +0000
10284 @@ -0,0 +1,37 @@
10285 +#ifndef _VSERVER_DEBUG_CMD_H
10286 +#define _VSERVER_DEBUG_CMD_H
10287 +
10288 +#include <uapi/vserver/debug_cmd.h>
10289 +
10290 +
10291 +#ifdef CONFIG_COMPAT
10292 +
10293 +#include <asm/compat.h>
10294 +
10295 +struct vcmd_read_history_v0_x32 {
10296 +       uint32_t index;
10297 +       uint32_t count;
10298 +       compat_uptr_t data_ptr;
10299 +};
10300 +
10301 +struct vcmd_read_monitor_v0_x32 {
10302 +       uint32_t index;
10303 +       uint32_t count;
10304 +       compat_uptr_t data_ptr;
10305 +};
10306 +
10307 +#endif  /* CONFIG_COMPAT */
10308 +
10309 +extern int vc_dump_history(uint32_t);
10310 +
10311 +extern int vc_read_history(uint32_t, void __user *);
10312 +extern int vc_read_monitor(uint32_t, void __user *);
10313 +
10314 +#ifdef CONFIG_COMPAT
10315 +
10316 +extern int vc_read_history_x32(uint32_t, void __user *);
10317 +extern int vc_read_monitor_x32(uint32_t, void __user *);
10318 +
10319 +#endif  /* CONFIG_COMPAT */
10320 +
10321 +#endif /* _VSERVER_DEBUG_CMD_H */
10322 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/device.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/device.h
10323 --- linux-4.1.41/include/linux/vserver/device.h 1970-01-01 00:00:00.000000000 +0000
10324 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/device.h     2016-07-05 04:41:47.000000000 +0000
10325 @@ -0,0 +1,9 @@
10326 +#ifndef _VSERVER_DEVICE_H
10327 +#define _VSERVER_DEVICE_H
10328 +
10329 +
10330 +#include <uapi/vserver/device.h>
10331 +
10332 +#else  /* _VSERVER_DEVICE_H */
10333 +#warning duplicate inclusion
10334 +#endif /* _VSERVER_DEVICE_H */
10335 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/device_cmd.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/device_cmd.h
10336 --- linux-4.1.41/include/linux/vserver/device_cmd.h     1970-01-01 00:00:00.000000000 +0000
10337 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/device_cmd.h 2016-07-05 04:41:47.000000000 +0000
10338 @@ -0,0 +1,31 @@
10339 +#ifndef _VSERVER_DEVICE_CMD_H
10340 +#define _VSERVER_DEVICE_CMD_H
10341 +
10342 +#include <uapi/vserver/device_cmd.h>
10343 +
10344 +
10345 +#ifdef CONFIG_COMPAT
10346 +
10347 +#include <asm/compat.h>
10348 +
10349 +struct vcmd_set_mapping_v0_x32 {
10350 +       compat_uptr_t device_ptr;
10351 +       compat_uptr_t target_ptr;
10352 +       uint32_t flags;
10353 +};
10354 +
10355 +#endif /* CONFIG_COMPAT */
10356 +
10357 +#include <linux/compiler.h>
10358 +
10359 +extern int vc_set_mapping(struct vx_info *, void __user *);
10360 +extern int vc_unset_mapping(struct vx_info *, void __user *);
10361 +
10362 +#ifdef CONFIG_COMPAT
10363 +
10364 +extern int vc_set_mapping_x32(struct vx_info *, void __user *);
10365 +extern int vc_unset_mapping_x32(struct vx_info *, void __user *);
10366 +
10367 +#endif /* CONFIG_COMPAT */
10368 +
10369 +#endif /* _VSERVER_DEVICE_CMD_H */
10370 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/device_def.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/device_def.h
10371 --- linux-4.1.41/include/linux/vserver/device_def.h     1970-01-01 00:00:00.000000000 +0000
10372 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/device_def.h 2016-07-05 04:41:47.000000000 +0000
10373 @@ -0,0 +1,17 @@
10374 +#ifndef _VSERVER_DEVICE_DEF_H
10375 +#define _VSERVER_DEVICE_DEF_H
10376 +
10377 +#include <linux/types.h>
10378 +
10379 +struct vx_dmap_target {
10380 +       dev_t target;
10381 +       uint32_t flags;
10382 +};
10383 +
10384 +struct _vx_device {
10385 +#ifdef CONFIG_VSERVER_DEVICE
10386 +       struct vx_dmap_target targets[2];
10387 +#endif
10388 +};
10389 +
10390 +#endif /* _VSERVER_DEVICE_DEF_H */
10391 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/dlimit.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/dlimit.h
10392 --- linux-4.1.41/include/linux/vserver/dlimit.h 1970-01-01 00:00:00.000000000 +0000
10393 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/dlimit.h     2016-07-05 04:41:47.000000000 +0000
10394 @@ -0,0 +1,54 @@
10395 +#ifndef _VSERVER_DLIMIT_H
10396 +#define _VSERVER_DLIMIT_H
10397 +
10398 +#include "switch.h"
10399 +
10400 +
10401 +#ifdef __KERNEL__
10402 +
10403 +/*      keep in sync with CDLIM_INFINITY       */
10404 +
10405 +#define DLIM_INFINITY          (~0ULL)
10406 +
10407 +#include <linux/spinlock.h>
10408 +#include <linux/rcupdate.h>
10409 +
10410 +struct super_block;
10411 +
10412 +struct dl_info {
10413 +       struct hlist_node dl_hlist;             /* linked list of contexts */
10414 +       struct rcu_head dl_rcu;                 /* the rcu head */
10415 +       vtag_t dl_tag;                          /* context tag */
10416 +       atomic_t dl_usecnt;                     /* usage count */
10417 +       atomic_t dl_refcnt;                     /* reference count */
10418 +
10419 +       struct super_block *dl_sb;              /* associated superblock */
10420 +
10421 +       spinlock_t dl_lock;                     /* protect the values */
10422 +
10423 +       unsigned long long dl_space_used;       /* used space in bytes */
10424 +       unsigned long long dl_space_total;      /* maximum space in bytes */
10425 +       unsigned long dl_inodes_used;           /* used inodes */
10426 +       unsigned long dl_inodes_total;          /* maximum inodes */
10427 +
10428 +       unsigned int dl_nrlmult;                /* non root limit mult */
10429 +};
10430 +
10431 +struct rcu_head;
10432 +
10433 +extern void rcu_free_dl_info(struct rcu_head *);
10434 +extern void unhash_dl_info(struct dl_info *);
10435 +
10436 +extern struct dl_info *locate_dl_info(struct super_block *, vtag_t);
10437 +
10438 +
10439 +struct kstatfs;
10440 +
10441 +extern void vx_vsi_statfs(struct super_block *, struct kstatfs *);
10442 +
10443 +typedef uint64_t dlsize_t;
10444 +
10445 +#endif /* __KERNEL__ */
10446 +#else  /* _VSERVER_DLIMIT_H */
10447 +#warning duplicate inclusion
10448 +#endif /* _VSERVER_DLIMIT_H */
10449 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/dlimit_cmd.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/dlimit_cmd.h
10450 --- linux-4.1.41/include/linux/vserver/dlimit_cmd.h     1970-01-01 00:00:00.000000000 +0000
10451 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/dlimit_cmd.h 2016-07-05 04:41:47.000000000 +0000
10452 @@ -0,0 +1,46 @@
10453 +#ifndef _VSERVER_DLIMIT_CMD_H
10454 +#define _VSERVER_DLIMIT_CMD_H
10455 +
10456 +#include <uapi/vserver/dlimit_cmd.h>
10457 +
10458 +
10459 +#ifdef CONFIG_COMPAT
10460 +
10461 +#include <asm/compat.h>
10462 +
10463 +struct vcmd_ctx_dlimit_base_v0_x32 {
10464 +       compat_uptr_t name_ptr;
10465 +       uint32_t flags;
10466 +};
10467 +
10468 +struct vcmd_ctx_dlimit_v0_x32 {
10469 +       compat_uptr_t name_ptr;
10470 +       uint32_t space_used;                    /* used space in kbytes */
10471 +       uint32_t space_total;                   /* maximum space in kbytes */
10472 +       uint32_t inodes_used;                   /* used inodes */
10473 +       uint32_t inodes_total;                  /* maximum inodes */
10474 +       uint32_t reserved;                      /* reserved for root in % */
10475 +       uint32_t flags;
10476 +};
10477 +
10478 +#endif /* CONFIG_COMPAT */
10479 +
10480 +#include <linux/compiler.h>
10481 +
10482 +extern int vc_add_dlimit(uint32_t, void __user *);
10483 +extern int vc_rem_dlimit(uint32_t, void __user *);
10484 +
10485 +extern int vc_set_dlimit(uint32_t, void __user *);
10486 +extern int vc_get_dlimit(uint32_t, void __user *);
10487 +
10488 +#ifdef CONFIG_COMPAT
10489 +
10490 +extern int vc_add_dlimit_x32(uint32_t, void __user *);
10491 +extern int vc_rem_dlimit_x32(uint32_t, void __user *);
10492 +
10493 +extern int vc_set_dlimit_x32(uint32_t, void __user *);
10494 +extern int vc_get_dlimit_x32(uint32_t, void __user *);
10495 +
10496 +#endif /* CONFIG_COMPAT */
10497 +
10498 +#endif /* _VSERVER_DLIMIT_CMD_H */
10499 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/global.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/global.h
10500 --- linux-4.1.41/include/linux/vserver/global.h 1970-01-01 00:00:00.000000000 +0000
10501 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/global.h     2016-07-05 04:41:47.000000000 +0000
10502 @@ -0,0 +1,19 @@
10503 +#ifndef _VSERVER_GLOBAL_H
10504 +#define _VSERVER_GLOBAL_H
10505 +
10506 +
10507 +extern atomic_t vx_global_ctotal;
10508 +extern atomic_t vx_global_cactive;
10509 +
10510 +extern atomic_t nx_global_ctotal;
10511 +extern atomic_t nx_global_cactive;
10512 +
10513 +extern atomic_t vs_global_nsproxy;
10514 +extern atomic_t vs_global_fs;
10515 +extern atomic_t vs_global_mnt_ns;
10516 +extern atomic_t vs_global_uts_ns;
10517 +extern atomic_t vs_global_user_ns;
10518 +extern atomic_t vs_global_pid_ns;
10519 +
10520 +
10521 +#endif /* _VSERVER_GLOBAL_H */
10522 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/history.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/history.h
10523 --- linux-4.1.41/include/linux/vserver/history.h        1970-01-01 00:00:00.000000000 +0000
10524 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/history.h    2016-07-05 04:41:47.000000000 +0000
10525 @@ -0,0 +1,197 @@
10526 +#ifndef _VSERVER_HISTORY_H
10527 +#define _VSERVER_HISTORY_H
10528 +
10529 +
10530 +enum {
10531 +       VXH_UNUSED = 0,
10532 +       VXH_THROW_OOPS = 1,
10533 +
10534 +       VXH_GET_VX_INFO,
10535 +       VXH_PUT_VX_INFO,
10536 +       VXH_INIT_VX_INFO,
10537 +       VXH_SET_VX_INFO,
10538 +       VXH_CLR_VX_INFO,
10539 +       VXH_CLAIM_VX_INFO,
10540 +       VXH_RELEASE_VX_INFO,
10541 +       VXH_ALLOC_VX_INFO,
10542 +       VXH_DEALLOC_VX_INFO,
10543 +       VXH_HASH_VX_INFO,
10544 +       VXH_UNHASH_VX_INFO,
10545 +       VXH_LOC_VX_INFO,
10546 +       VXH_LOOKUP_VX_INFO,
10547 +       VXH_CREATE_VX_INFO,
10548 +};
10549 +
10550 +struct _vxhe_vxi {
10551 +       struct vx_info *ptr;
10552 +       unsigned xid;
10553 +       unsigned usecnt;
10554 +       unsigned tasks;
10555 +};
10556 +
10557 +struct _vxhe_set_clr {
10558 +       void *data;
10559 +};
10560 +
10561 +struct _vxhe_loc_lookup {
10562 +       unsigned arg;
10563 +};
10564 +
10565 +struct _vx_hist_entry {
10566 +       void *loc;
10567 +       unsigned short seq;
10568 +       unsigned short type;
10569 +       struct _vxhe_vxi vxi;
10570 +       union {
10571 +               struct _vxhe_set_clr sc;
10572 +               struct _vxhe_loc_lookup ll;
10573 +       };
10574 +};
10575 +
10576 +#ifdef CONFIG_VSERVER_HISTORY
10577 +
10578 +extern unsigned volatile int vxh_active;
10579 +
10580 +struct _vx_hist_entry *vxh_advance(void *loc);
10581 +
10582 +
10583 +static inline
10584 +void   __vxh_copy_vxi(struct _vx_hist_entry *entry, struct vx_info *vxi)
10585 +{
10586 +       entry->vxi.ptr = vxi;
10587 +       if (vxi) {
10588 +               entry->vxi.usecnt = atomic_read(&vxi->vx_usecnt);
10589 +               entry->vxi.tasks = atomic_read(&vxi->vx_tasks);
10590 +               entry->vxi.xid = vxi->vx_id;
10591 +       }
10592 +}
10593 +
10594 +
10595 +#define        __HERE__ current_text_addr()
10596 +
10597 +#define __VXH_BODY(__type, __data, __here)     \
10598 +       struct _vx_hist_entry *entry;           \
10599 +                                               \
10600 +       preempt_disable();                      \
10601 +       entry = vxh_advance(__here);            \
10602 +       __data;                                 \
10603 +       entry->type = __type;                   \
10604 +       preempt_enable();
10605 +
10606 +
10607 +       /* pass vxi only */
10608 +
10609 +#define __VXH_SMPL                             \
10610 +       __vxh_copy_vxi(entry, vxi)
10611 +
10612 +static inline
10613 +void   __vxh_smpl(struct vx_info *vxi, int __type, void *__here)
10614 +{
10615 +       __VXH_BODY(__type, __VXH_SMPL, __here)
10616 +}
10617 +
10618 +       /* pass vxi and data (void *) */
10619 +
10620 +#define __VXH_DATA                             \
10621 +       __vxh_copy_vxi(entry, vxi);             \
10622 +       entry->sc.data = data
10623 +
10624 +static inline
10625 +void   __vxh_data(struct vx_info *vxi, void *data,
10626 +                       int __type, void *__here)
10627 +{
10628 +       __VXH_BODY(__type, __VXH_DATA, __here)
10629 +}
10630 +
10631 +       /* pass vxi and arg (long) */
10632 +
10633 +#define __VXH_LONG                             \
10634 +       __vxh_copy_vxi(entry, vxi);             \
10635 +       entry->ll.arg = arg
10636 +
10637 +static inline
10638 +void   __vxh_long(struct vx_info *vxi, long arg,
10639 +                       int __type, void *__here)
10640 +{
10641 +       __VXH_BODY(__type, __VXH_LONG, __here)
10642 +}
10643 +
10644 +
10645 +static inline
10646 +void   __vxh_throw_oops(void *__here)
10647 +{
10648 +       __VXH_BODY(VXH_THROW_OOPS, {}, __here);
10649 +       /* prevent further acquisition */
10650 +       vxh_active = 0;
10651 +}
10652 +
10653 +
10654 +#define vxh_throw_oops()       __vxh_throw_oops(__HERE__);
10655 +
10656 +#define __vxh_get_vx_info(v, h)        __vxh_smpl(v, VXH_GET_VX_INFO, h);
10657 +#define __vxh_put_vx_info(v, h)        __vxh_smpl(v, VXH_PUT_VX_INFO, h);
10658 +
10659 +#define __vxh_init_vx_info(v, d, h) \
10660 +       __vxh_data(v, d, VXH_INIT_VX_INFO, h);
10661 +#define __vxh_set_vx_info(v, d, h) \
10662 +       __vxh_data(v, d, VXH_SET_VX_INFO, h);
10663 +#define __vxh_clr_vx_info(v, d, h) \
10664 +       __vxh_data(v, d, VXH_CLR_VX_INFO, h);
10665 +
10666 +#define __vxh_claim_vx_info(v, d, h) \
10667 +       __vxh_data(v, d, VXH_CLAIM_VX_INFO, h);
10668 +#define __vxh_release_vx_info(v, d, h) \
10669 +       __vxh_data(v, d, VXH_RELEASE_VX_INFO, h);
10670 +
10671 +#define vxh_alloc_vx_info(v) \
10672 +       __vxh_smpl(v, VXH_ALLOC_VX_INFO, __HERE__);
10673 +#define vxh_dealloc_vx_info(v) \
10674 +       __vxh_smpl(v, VXH_DEALLOC_VX_INFO, __HERE__);
10675 +
10676 +#define vxh_hash_vx_info(v) \
10677 +       __vxh_smpl(v, VXH_HASH_VX_INFO, __HERE__);
10678 +#define vxh_unhash_vx_info(v) \
10679 +       __vxh_smpl(v, VXH_UNHASH_VX_INFO, __HERE__);
10680 +
10681 +#define vxh_loc_vx_info(v, l) \
10682 +       __vxh_long(v, l, VXH_LOC_VX_INFO, __HERE__);
10683 +#define vxh_lookup_vx_info(v, l) \
10684 +       __vxh_long(v, l, VXH_LOOKUP_VX_INFO, __HERE__);
10685 +#define vxh_create_vx_info(v, l) \
10686 +       __vxh_long(v, l, VXH_CREATE_VX_INFO, __HERE__);
10687 +
10688 +extern void vxh_dump_history(void);
10689 +
10690 +
10691 +#else  /* CONFIG_VSERVER_HISTORY */
10692 +
10693 +#define        __HERE__        0
10694 +
10695 +#define vxh_throw_oops()               do { } while (0)
10696 +
10697 +#define __vxh_get_vx_info(v, h)                do { } while (0)
10698 +#define __vxh_put_vx_info(v, h)                do { } while (0)
10699 +
10700 +#define __vxh_init_vx_info(v, d, h)    do { } while (0)
10701 +#define __vxh_set_vx_info(v, d, h)     do { } while (0)
10702 +#define __vxh_clr_vx_info(v, d, h)     do { } while (0)
10703 +
10704 +#define __vxh_claim_vx_info(v, d, h)   do { } while (0)
10705 +#define __vxh_release_vx_info(v, d, h) do { } while (0)
10706 +
10707 +#define vxh_alloc_vx_info(v)           do { } while (0)
10708 +#define vxh_dealloc_vx_info(v)         do { } while (0)
10709 +
10710 +#define vxh_hash_vx_info(v)            do { } while (0)
10711 +#define vxh_unhash_vx_info(v)          do { } while (0)
10712 +
10713 +#define vxh_loc_vx_info(v, l)          do { } while (0)
10714 +#define vxh_lookup_vx_info(v, l)       do { } while (0)
10715 +#define vxh_create_vx_info(v, l)       do { } while (0)
10716 +
10717 +#define vxh_dump_history()             do { } while (0)
10718 +
10719 +
10720 +#endif /* CONFIG_VSERVER_HISTORY */
10721 +
10722 +#endif /* _VSERVER_HISTORY_H */
10723 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/inode.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/inode.h
10724 --- linux-4.1.41/include/linux/vserver/inode.h  1970-01-01 00:00:00.000000000 +0000
10725 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/inode.h      2016-07-05 04:41:47.000000000 +0000
10726 @@ -0,0 +1,19 @@
10727 +#ifndef _VSERVER_INODE_H
10728 +#define _VSERVER_INODE_H
10729 +
10730 +#include <uapi/vserver/inode.h>
10731 +
10732 +
10733 +#ifdef CONFIG_VSERVER_PROC_SECURE
10734 +#define IATTR_PROC_DEFAULT     ( IATTR_ADMIN | IATTR_HIDE )
10735 +#define IATTR_PROC_SYMLINK     ( IATTR_ADMIN )
10736 +#else
10737 +#define IATTR_PROC_DEFAULT     ( IATTR_ADMIN )
10738 +#define IATTR_PROC_SYMLINK     ( IATTR_ADMIN )
10739 +#endif
10740 +
10741 +#define vx_hide_check(c, m)    (((m) & IATTR_HIDE) ? vx_check(c, m) : 1)
10742 +
10743 +#else  /* _VSERVER_INODE_H */
10744 +#warning duplicate inclusion
10745 +#endif /* _VSERVER_INODE_H */
10746 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/inode_cmd.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/inode_cmd.h
10747 --- linux-4.1.41/include/linux/vserver/inode_cmd.h      1970-01-01 00:00:00.000000000 +0000
10748 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/inode_cmd.h  2016-07-05 04:41:47.000000000 +0000
10749 @@ -0,0 +1,36 @@
10750 +#ifndef _VSERVER_INODE_CMD_H
10751 +#define _VSERVER_INODE_CMD_H
10752 +
10753 +#include <uapi/vserver/inode_cmd.h>
10754 +
10755 +
10756 +
10757 +#ifdef CONFIG_COMPAT
10758 +
10759 +#include <asm/compat.h>
10760 +
10761 +struct vcmd_ctx_iattr_v1_x32 {
10762 +       compat_uptr_t name_ptr;
10763 +       uint32_t tag;
10764 +       uint32_t flags;
10765 +       uint32_t mask;
10766 +};
10767 +
10768 +#endif /* CONFIG_COMPAT */
10769 +
10770 +#include <linux/compiler.h>
10771 +
10772 +extern int vc_get_iattr(void __user *);
10773 +extern int vc_set_iattr(void __user *);
10774 +
10775 +extern int vc_fget_iattr(uint32_t, void __user *);
10776 +extern int vc_fset_iattr(uint32_t, void __user *);
10777 +
10778 +#ifdef CONFIG_COMPAT
10779 +
10780 +extern int vc_get_iattr_x32(void __user *);
10781 +extern int vc_set_iattr_x32(void __user *);
10782 +
10783 +#endif /* CONFIG_COMPAT */
10784 +
10785 +#endif /* _VSERVER_INODE_CMD_H */
10786 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/limit.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/limit.h
10787 --- linux-4.1.41/include/linux/vserver/limit.h  1970-01-01 00:00:00.000000000 +0000
10788 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/limit.h      2016-11-12 13:56:54.000000000 +0000
10789 @@ -0,0 +1,67 @@
10790 +#ifndef _VSERVER_LIMIT_H
10791 +#define _VSERVER_LIMIT_H
10792 +
10793 +#include <uapi/vserver/limit.h>
10794 +
10795 +
10796 +#define        VLIM_NOCHECK    ((1L << VLIMIT_DENTRY) | (1L << RLIMIT_RSS))
10797 +
10798 +/*     keep in sync with CRLIM_INFINITY */
10799 +
10800 +#define        VLIM_INFINITY   (~0ULL)
10801 +
10802 +#include <asm/atomic.h>
10803 +#include <asm/resource.h>
10804 +
10805 +#ifndef RLIM_INFINITY
10806 +#warning RLIM_INFINITY is undefined
10807 +#endif
10808 +
10809 +#define __rlim_val(l, r, v)    ((l)->res[r].v)
10810 +
10811 +#define __rlim_soft(l, r)      __rlim_val(l, r, soft)
10812 +#define __rlim_hard(l, r)      __rlim_val(l, r, hard)
10813 +
10814 +#define __rlim_rcur(l, r)      __rlim_val(l, r, rcur)
10815 +#define __rlim_rmin(l, r)      __rlim_val(l, r, rmin)
10816 +#define __rlim_rmax(l, r)      __rlim_val(l, r, rmax)
10817 +
10818 +#define __rlim_lhit(l, r)      __rlim_val(l, r, lhit)
10819 +#define __rlim_hit(l, r)       atomic_inc(&__rlim_lhit(l, r))
10820 +
10821 +typedef atomic_long_t rlim_atomic_t;
10822 +typedef unsigned long rlim_t;
10823 +
10824 +#define __rlim_get(l, r)       atomic_long_read(&__rlim_rcur(l, r))
10825 +#define __rlim_set(l, r, v)    atomic_long_set(&__rlim_rcur(l, r), v)
10826 +#define __rlim_inc(l, r)       atomic_long_inc(&__rlim_rcur(l, r))
10827 +#define __rlim_dec(l, r)       atomic_long_dec(&__rlim_rcur(l, r))
10828 +#define __rlim_add(l, r, v)    atomic_long_add(v, &__rlim_rcur(l, r))
10829 +#define __rlim_sub(l, r, v)    atomic_long_sub(v, &__rlim_rcur(l, r))
10830 +
10831 +
10832 +#if    (RLIM_INFINITY == VLIM_INFINITY)
10833 +#define        VX_VLIM(r) ((long long)(long)(r))
10834 +#define        VX_RLIM(v) ((rlim_t)(v))
10835 +#else
10836 +#define        VX_VLIM(r) (((r) == RLIM_INFINITY) \
10837 +               ? VLIM_INFINITY : (long long)(r))
10838 +#define        VX_RLIM(v) (((v) == VLIM_INFINITY) \
10839 +               ? RLIM_INFINITY : (rlim_t)(v))
10840 +#endif
10841 +
10842 +struct sysinfo;
10843 +
10844 +#ifdef CONFIG_MEMCG
10845 +void vx_vsi_meminfo(struct sysinfo *);
10846 +void vx_vsi_swapinfo(struct sysinfo *);
10847 +long vx_vsi_cached(struct sysinfo *);
10848 +#else  /* !CONFIG_MEMCG */
10849 +#define vx_vsi_meminfo(s) do { } while (0)
10850 +#define vx_vsi_swapinfo(s) do { } while (0)
10851 +#define vx_vsi_cached(s) (0L)
10852 +#endif /* !CONFIG_MEMCG */
10853 +
10854 +#define NUM_LIMITS     24
10855 +
10856 +#endif /* _VSERVER_LIMIT_H */
10857 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/limit_cmd.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/limit_cmd.h
10858 --- linux-4.1.41/include/linux/vserver/limit_cmd.h      1970-01-01 00:00:00.000000000 +0000
10859 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/limit_cmd.h  2016-07-05 04:41:47.000000000 +0000
10860 @@ -0,0 +1,35 @@
10861 +#ifndef _VSERVER_LIMIT_CMD_H
10862 +#define _VSERVER_LIMIT_CMD_H
10863 +
10864 +#include <uapi/vserver/limit_cmd.h>
10865 +
10866 +
10867 +#ifdef CONFIG_IA32_EMULATION
10868 +
10869 +struct vcmd_ctx_rlimit_v0_x32 {
10870 +       uint32_t id;
10871 +       uint64_t minimum;
10872 +       uint64_t softlimit;
10873 +       uint64_t maximum;
10874 +} __attribute__ ((packed));
10875 +
10876 +#endif /* CONFIG_IA32_EMULATION */
10877 +
10878 +#include <linux/compiler.h>
10879 +
10880 +extern int vc_get_rlimit_mask(uint32_t, void __user *);
10881 +extern int vc_get_rlimit(struct vx_info *, void __user *);
10882 +extern int vc_set_rlimit(struct vx_info *, void __user *);
10883 +extern int vc_reset_hits(struct vx_info *, void __user *);
10884 +extern int vc_reset_minmax(struct vx_info *, void __user *);
10885 +
10886 +extern int vc_rlimit_stat(struct vx_info *, void __user *);
10887 +
10888 +#ifdef CONFIG_IA32_EMULATION
10889 +
10890 +extern int vc_get_rlimit_x32(struct vx_info *, void __user *);
10891 +extern int vc_set_rlimit_x32(struct vx_info *, void __user *);
10892 +
10893 +#endif /* CONFIG_IA32_EMULATION */
10894 +
10895 +#endif /* _VSERVER_LIMIT_CMD_H */
10896 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/limit_def.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/limit_def.h
10897 --- linux-4.1.41/include/linux/vserver/limit_def.h      1970-01-01 00:00:00.000000000 +0000
10898 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/limit_def.h  2016-07-05 04:41:47.000000000 +0000
10899 @@ -0,0 +1,47 @@
10900 +#ifndef _VSERVER_LIMIT_DEF_H
10901 +#define _VSERVER_LIMIT_DEF_H
10902 +
10903 +#include <asm/atomic.h>
10904 +#include <asm/resource.h>
10905 +
10906 +#include "limit.h"
10907 +
10908 +
10909 +struct _vx_res_limit {
10910 +       rlim_t soft;            /* Context soft limit */
10911 +       rlim_t hard;            /* Context hard limit */
10912 +
10913 +       rlim_atomic_t rcur;     /* Current value */
10914 +       rlim_t rmin;            /* Context minimum */
10915 +       rlim_t rmax;            /* Context maximum */
10916 +
10917 +       atomic_t lhit;          /* Limit hits */
10918 +};
10919 +
10920 +/* context sub struct */
10921 +
10922 +struct _vx_limit {
10923 +       struct _vx_res_limit res[NUM_LIMITS];
10924 +};
10925 +
10926 +#ifdef CONFIG_VSERVER_DEBUG
10927 +
10928 +static inline void __dump_vx_limit(struct _vx_limit *limit)
10929 +{
10930 +       int i;
10931 +
10932 +       printk("\t_vx_limit:");
10933 +       for (i = 0; i < NUM_LIMITS; i++) {
10934 +               printk("\t [%2d] = %8lu %8lu/%8lu, %8ld/%8ld, %8d\n",
10935 +                       i, (unsigned long)__rlim_get(limit, i),
10936 +                       (unsigned long)__rlim_rmin(limit, i),
10937 +                       (unsigned long)__rlim_rmax(limit, i),
10938 +                       (long)__rlim_soft(limit, i),
10939 +                       (long)__rlim_hard(limit, i),
10940 +                       atomic_read(&__rlim_lhit(limit, i)));
10941 +       }
10942 +}
10943 +
10944 +#endif
10945 +
10946 +#endif /* _VSERVER_LIMIT_DEF_H */
10947 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/limit_int.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/limit_int.h
10948 --- linux-4.1.41/include/linux/vserver/limit_int.h      1970-01-01 00:00:00.000000000 +0000
10949 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/limit_int.h  2016-07-05 04:41:47.000000000 +0000
10950 @@ -0,0 +1,193 @@
10951 +#ifndef _VSERVER_LIMIT_INT_H
10952 +#define _VSERVER_LIMIT_INT_H
10953 +
10954 +#define VXD_RCRES_COND(r)      VXD_CBIT(cres, r)
10955 +#define VXD_RLIMIT_COND(r)     VXD_CBIT(limit, r)
10956 +
10957 +extern const char *vlimit_name[NUM_LIMITS];
10958 +
10959 +static inline void __vx_acc_cres(struct vx_info *vxi,
10960 +       int res, int dir, void *_data, char *_file, int _line)
10961 +{
10962 +       if (VXD_RCRES_COND(res))
10963 +               vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5ld%s (%p)",
10964 +                       (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10965 +                       (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10966 +                       (dir > 0) ? "++" : "--", _data, _file, _line);
10967 +       if (!vxi)
10968 +               return;
10969 +
10970 +       if (dir > 0)
10971 +               __rlim_inc(&vxi->limit, res);
10972 +       else
10973 +               __rlim_dec(&vxi->limit, res);
10974 +}
10975 +
10976 +static inline void __vx_add_cres(struct vx_info *vxi,
10977 +       int res, int amount, void *_data, char *_file, int _line)
10978 +{
10979 +       if (VXD_RCRES_COND(res))
10980 +               vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5ld += %5d (%p)",
10981 +                       (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10982 +                       (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10983 +                       amount, _data, _file, _line);
10984 +       if (amount == 0)
10985 +               return;
10986 +       if (!vxi)
10987 +               return;
10988 +       __rlim_add(&vxi->limit, res, amount);
10989 +}
10990 +
10991 +static inline
10992 +int __vx_cres_adjust_max(struct _vx_limit *limit, int res, rlim_t value)
10993 +{
10994 +       int cond = (value > __rlim_rmax(limit, res));
10995 +
10996 +       if (cond)
10997 +               __rlim_rmax(limit, res) = value;
10998 +       return cond;
10999 +}
11000 +
11001 +static inline
11002 +int __vx_cres_adjust_min(struct _vx_limit *limit, int res, rlim_t value)
11003 +{
11004 +       int cond = (value < __rlim_rmin(limit, res));
11005 +
11006 +       if (cond)
11007 +               __rlim_rmin(limit, res) = value;
11008 +       return cond;
11009 +}
11010 +
11011 +static inline
11012 +void __vx_cres_fixup(struct _vx_limit *limit, int res, rlim_t value)
11013 +{
11014 +       if (!__vx_cres_adjust_max(limit, res, value))
11015 +               __vx_cres_adjust_min(limit, res, value);
11016 +}
11017 +
11018 +
11019 +/*     return values:
11020 +        +1 ... no limit hit
11021 +        -1 ... over soft limit
11022 +         0 ... over hard limit         */
11023 +
11024 +static inline int __vx_cres_avail(struct vx_info *vxi,
11025 +       int res, int num, char *_file, int _line)
11026 +{
11027 +       struct _vx_limit *limit;
11028 +       rlim_t value;
11029 +
11030 +       if (VXD_RLIMIT_COND(res))
11031 +               vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld/%5ld > %5ld + %5d",
11032 +                       (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
11033 +                       (vxi ? (long)__rlim_soft(&vxi->limit, res) : -1),
11034 +                       (vxi ? (long)__rlim_hard(&vxi->limit, res) : -1),
11035 +                       (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
11036 +                       num, _file, _line);
11037 +       if (!vxi)
11038 +               return 1;
11039 +
11040 +       limit = &vxi->limit;
11041 +       value = __rlim_get(limit, res);
11042 +
11043 +       if (!__vx_cres_adjust_max(limit, res, value))
11044 +               __vx_cres_adjust_min(limit, res, value);
11045 +
11046 +       if (num == 0)
11047 +               return 1;
11048 +
11049 +       if (__rlim_soft(limit, res) == RLIM_INFINITY)
11050 +               return -1;
11051 +       if (value + num <= __rlim_soft(limit, res))
11052 +               return -1;
11053 +
11054 +       if (__rlim_hard(limit, res) == RLIM_INFINITY)
11055 +               return 1;
11056 +       if (value + num <= __rlim_hard(limit, res))
11057 +               return 1;
11058 +
11059 +       __rlim_hit(limit, res);
11060 +       return 0;
11061 +}
11062 +
11063 +
11064 +static const int VLA_RSS[] = { RLIMIT_RSS, VLIMIT_ANON, VLIMIT_MAPPED, 0 };
11065 +
11066 +static inline
11067 +rlim_t __vx_cres_array_sum(struct _vx_limit *limit, const int *array)
11068 +{
11069 +       rlim_t value, sum = 0;
11070 +       int res;
11071 +
11072 +       while ((res = *array++)) {
11073 +               value = __rlim_get(limit, res);
11074 +               __vx_cres_fixup(limit, res, value);
11075 +               sum += value;
11076 +       }
11077 +       return sum;
11078 +}
11079 +
11080 +static inline
11081 +rlim_t __vx_cres_array_fixup(struct _vx_limit *limit, const int *array)
11082 +{
11083 +       rlim_t value = __vx_cres_array_sum(limit, array + 1);
11084 +       int res = *array;
11085 +
11086 +       if (value == __rlim_get(limit, res))
11087 +               return value;
11088 +
11089 +       __rlim_set(limit, res, value);
11090 +       /* now adjust min/max */
11091 +       if (!__vx_cres_adjust_max(limit, res, value))
11092 +               __vx_cres_adjust_min(limit, res, value);
11093 +
11094 +       return value;
11095 +}
11096 +
11097 +static inline int __vx_cres_array_avail(struct vx_info *vxi,
11098 +       const int *array, int num, char *_file, int _line)
11099 +{
11100 +       struct _vx_limit *limit;
11101 +       rlim_t value = 0;
11102 +       int res;
11103 +
11104 +       if (num == 0)
11105 +               return 1;
11106 +       if (!vxi)
11107 +               return 1;
11108 +
11109 +       limit = &vxi->limit;
11110 +       res = *array;
11111 +       value = __vx_cres_array_sum(limit, array + 1);
11112 +
11113 +       __rlim_set(limit, res, value);
11114 +       __vx_cres_fixup(limit, res, value);
11115 +
11116 +       return __vx_cres_avail(vxi, res, num, _file, _line);
11117 +}
11118 +
11119 +
11120 +static inline void vx_limit_fixup(struct _vx_limit *limit, int id)
11121 +{
11122 +       rlim_t value;
11123 +       int res;
11124 +
11125 +       /* complex resources first */
11126 +       if ((id < 0) || (id == RLIMIT_RSS))
11127 +               __vx_cres_array_fixup(limit, VLA_RSS);
11128 +
11129 +       for (res = 0; res < NUM_LIMITS; res++) {
11130 +               if ((id > 0) && (res != id))
11131 +                       continue;
11132 +
11133 +               value = __rlim_get(limit, res);
11134 +               __vx_cres_fixup(limit, res, value);
11135 +
11136 +               /* not supposed to happen, maybe warn? */
11137 +               if (__rlim_rmax(limit, res) > __rlim_hard(limit, res))
11138 +                       __rlim_rmax(limit, res) = __rlim_hard(limit, res);
11139 +       }
11140 +}
11141 +
11142 +
11143 +#endif /* _VSERVER_LIMIT_INT_H */
11144 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/monitor.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/monitor.h
11145 --- linux-4.1.41/include/linux/vserver/monitor.h        1970-01-01 00:00:00.000000000 +0000
11146 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/monitor.h    2016-07-05 04:41:47.000000000 +0000
11147 @@ -0,0 +1,6 @@
11148 +#ifndef _VSERVER_MONITOR_H
11149 +#define _VSERVER_MONITOR_H
11150 +
11151 +#include <uapi/vserver/monitor.h>
11152 +
11153 +#endif /* _VSERVER_MONITOR_H */
11154 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/network.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/network.h
11155 --- linux-4.1.41/include/linux/vserver/network.h        1970-01-01 00:00:00.000000000 +0000
11156 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/network.h    2016-07-05 04:41:47.000000000 +0000
11157 @@ -0,0 +1,76 @@
11158 +#ifndef _VSERVER_NETWORK_H
11159 +#define _VSERVER_NETWORK_H
11160 +
11161 +
11162 +#include <linux/list.h>
11163 +#include <linux/spinlock.h>
11164 +#include <linux/rcupdate.h>
11165 +#include <linux/in.h>
11166 +#include <linux/in6.h>
11167 +#include <asm/atomic.h>
11168 +#include <uapi/vserver/network.h>
11169 +
11170 +struct nx_addr_v4 {
11171 +       struct nx_addr_v4 *next;
11172 +       struct in_addr ip[2];
11173 +       struct in_addr mask;
11174 +       uint16_t type;
11175 +       uint16_t flags;
11176 +};
11177 +
11178 +struct nx_addr_v6 {
11179 +       struct nx_addr_v6 *next;
11180 +       struct in6_addr ip;
11181 +       struct in6_addr mask;
11182 +       uint32_t prefix;
11183 +       uint16_t type;
11184 +       uint16_t flags;
11185 +};
11186 +
11187 +struct nx_info {
11188 +       struct hlist_node nx_hlist;     /* linked list of nxinfos */
11189 +       vnid_t nx_id;                   /* vnet id */
11190 +       atomic_t nx_usecnt;             /* usage count */
11191 +       atomic_t nx_tasks;              /* tasks count */
11192 +       int nx_state;                   /* context state */
11193 +
11194 +       uint64_t nx_flags;              /* network flag word */
11195 +       uint64_t nx_ncaps;              /* network capabilities */
11196 +
11197 +       spinlock_t addr_lock;           /* protect address changes */
11198 +       struct in_addr v4_lback;        /* Loopback address */
11199 +       struct in_addr v4_bcast;        /* Broadcast address */
11200 +       struct nx_addr_v4 v4;           /* First/Single ipv4 address */
11201 +#ifdef CONFIG_IPV6
11202 +       struct nx_addr_v6 v6;           /* First/Single ipv6 address */
11203 +#endif
11204 +       char nx_name[65];               /* network context name */
11205 +};
11206 +
11207 +
11208 +/* status flags */
11209 +
11210 +#define NXS_HASHED      0x0001
11211 +#define NXS_SHUTDOWN    0x0100
11212 +#define NXS_RELEASED    0x8000
11213 +
11214 +extern struct nx_info *lookup_nx_info(int);
11215 +
11216 +extern int get_nid_list(int, unsigned int *, int);
11217 +extern int nid_is_hashed(vnid_t);
11218 +
11219 +extern int nx_migrate_task(struct task_struct *, struct nx_info *);
11220 +
11221 +extern long vs_net_change(struct nx_info *, unsigned int);
11222 +
11223 +struct sock;
11224 +
11225 +
11226 +#define NX_IPV4(n)     ((n)->v4.type != NXA_TYPE_NONE)
11227 +#ifdef  CONFIG_IPV6
11228 +#define NX_IPV6(n)     ((n)->v6.type != NXA_TYPE_NONE)
11229 +#else
11230 +#define NX_IPV6(n)     (0)
11231 +#endif
11232 +
11233 +#endif /* _VSERVER_NETWORK_H */
11234 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/network_cmd.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/network_cmd.h
11235 --- linux-4.1.41/include/linux/vserver/network_cmd.h    1970-01-01 00:00:00.000000000 +0000
11236 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/network_cmd.h        2016-07-05 04:41:47.000000000 +0000
11237 @@ -0,0 +1,37 @@
11238 +#ifndef _VSERVER_NETWORK_CMD_H
11239 +#define _VSERVER_NETWORK_CMD_H
11240 +
11241 +#include <uapi/vserver/network_cmd.h>
11242 +
11243 +extern int vc_task_nid(uint32_t);
11244 +
11245 +extern int vc_nx_info(struct nx_info *, void __user *);
11246 +
11247 +extern int vc_net_create(uint32_t, void __user *);
11248 +extern int vc_net_migrate(struct nx_info *, void __user *);
11249 +
11250 +extern int vc_net_add(struct nx_info *, void __user *);
11251 +extern int vc_net_remove(struct nx_info *, void __user *);
11252 +
11253 +extern int vc_net_add_ipv4_v1(struct nx_info *, void __user *);
11254 +extern int vc_net_add_ipv4(struct nx_info *, void __user *);
11255 +
11256 +extern int vc_net_rem_ipv4_v1(struct nx_info *, void __user *);
11257 +extern int vc_net_rem_ipv4(struct nx_info *, void __user *);
11258 +
11259 +extern int vc_net_add_ipv6(struct nx_info *, void __user *);
11260 +extern int vc_net_remove_ipv6(struct nx_info *, void __user *);
11261 +
11262 +extern int vc_add_match_ipv4(struct nx_info *, void __user *);
11263 +extern int vc_get_match_ipv4(struct nx_info *, void __user *);
11264 +
11265 +extern int vc_add_match_ipv6(struct nx_info *, void __user *);
11266 +extern int vc_get_match_ipv6(struct nx_info *, void __user *);
11267 +
11268 +extern int vc_get_nflags(struct nx_info *, void __user *);
11269 +extern int vc_set_nflags(struct nx_info *, void __user *);
11270 +
11271 +extern int vc_get_ncaps(struct nx_info *, void __user *);
11272 +extern int vc_set_ncaps(struct nx_info *, void __user *);
11273 +
11274 +#endif /* _VSERVER_CONTEXT_CMD_H */
11275 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/percpu.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/percpu.h
11276 --- linux-4.1.41/include/linux/vserver/percpu.h 1970-01-01 00:00:00.000000000 +0000
11277 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/percpu.h     2016-07-05 04:41:47.000000000 +0000
11278 @@ -0,0 +1,14 @@
11279 +#ifndef _VSERVER_PERCPU_H
11280 +#define _VSERVER_PERCPU_H
11281 +
11282 +#include "cvirt_def.h"
11283 +#include "sched_def.h"
11284 +
11285 +struct _vx_percpu {
11286 +       struct _vx_cvirt_pc cvirt;
11287 +       struct _vx_sched_pc sched;
11288 +};
11289 +
11290 +#define        PERCPU_PERCTX   (sizeof(struct _vx_percpu))
11291 +
11292 +#endif /* _VSERVER_PERCPU_H */
11293 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/pid.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/pid.h
11294 --- linux-4.1.41/include/linux/vserver/pid.h    1970-01-01 00:00:00.000000000 +0000
11295 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/pid.h        2016-07-05 04:41:47.000000000 +0000
11296 @@ -0,0 +1,51 @@
11297 +#ifndef _VSERVER_PID_H
11298 +#define _VSERVER_PID_H
11299 +
11300 +/* pid faking stuff */
11301 +
11302 +#define vx_info_map_pid(v, p) \
11303 +       __vx_info_map_pid((v), (p), __func__, __FILE__, __LINE__)
11304 +#define vx_info_map_tgid(v,p)  vx_info_map_pid(v,p)
11305 +#define vx_map_pid(p) vx_info_map_pid(current_vx_info(), p)
11306 +#define vx_map_tgid(p) vx_map_pid(p)
11307 +
11308 +static inline int __vx_info_map_pid(struct vx_info *vxi, int pid,
11309 +       const char *func, const char *file, int line)
11310 +{
11311 +       if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
11312 +               vxfprintk(VXD_CBIT(cvirt, 2),
11313 +                       "vx_map_tgid: %p/%llx: %d -> %d",
11314 +                       vxi, (long long)vxi->vx_flags, pid,
11315 +                       (pid && pid == vxi->vx_initpid) ? 1 : pid,
11316 +                       func, file, line);
11317 +               if (pid == 0)
11318 +                       return 0;
11319 +               if (pid == vxi->vx_initpid)
11320 +                       return 1;
11321 +       }
11322 +       return pid;
11323 +}
11324 +
11325 +#define vx_info_rmap_pid(v, p) \
11326 +       __vx_info_rmap_pid((v), (p), __func__, __FILE__, __LINE__)
11327 +#define vx_rmap_pid(p) vx_info_rmap_pid(current_vx_info(), p)
11328 +#define vx_rmap_tgid(p) vx_rmap_pid(p)
11329 +
11330 +static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid,
11331 +       const char *func, const char *file, int line)
11332 +{
11333 +       if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
11334 +               vxfprintk(VXD_CBIT(cvirt, 2),
11335 +                       "vx_rmap_tgid: %p/%llx: %d -> %d",
11336 +                       vxi, (long long)vxi->vx_flags, pid,
11337 +                       (pid == 1) ? vxi->vx_initpid : pid,
11338 +                       func, file, line);
11339 +               if ((pid == 1) && vxi->vx_initpid)
11340 +                       return vxi->vx_initpid;
11341 +               if (pid == vxi->vx_initpid)
11342 +                       return ~0U;
11343 +       }
11344 +       return pid;
11345 +}
11346 +
11347 +#endif
11348 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/sched.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/sched.h
11349 --- linux-4.1.41/include/linux/vserver/sched.h  1970-01-01 00:00:00.000000000 +0000
11350 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/sched.h      2016-07-05 04:41:47.000000000 +0000
11351 @@ -0,0 +1,23 @@
11352 +#ifndef _VSERVER_SCHED_H
11353 +#define _VSERVER_SCHED_H
11354 +
11355 +
11356 +#ifdef __KERNEL__
11357 +
11358 +struct timespec;
11359 +
11360 +void vx_vsi_uptime(struct timespec *, struct timespec *);
11361 +
11362 +
11363 +struct vx_info;
11364 +
11365 +void vx_update_load(struct vx_info *);
11366 +
11367 +
11368 +void vx_update_sched_param(struct _vx_sched *sched,
11369 +       struct _vx_sched_pc *sched_pc);
11370 +
11371 +#endif /* __KERNEL__ */
11372 +#else  /* _VSERVER_SCHED_H */
11373 +#warning duplicate inclusion
11374 +#endif /* _VSERVER_SCHED_H */
11375 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/sched_cmd.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/sched_cmd.h
11376 --- linux-4.1.41/include/linux/vserver/sched_cmd.h      1970-01-01 00:00:00.000000000 +0000
11377 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/sched_cmd.h  2016-07-05 04:41:47.000000000 +0000
11378 @@ -0,0 +1,11 @@
11379 +#ifndef _VSERVER_SCHED_CMD_H
11380 +#define _VSERVER_SCHED_CMD_H
11381 +
11382 +
11383 +#include <linux/compiler.h>
11384 +#include <uapi/vserver/sched_cmd.h>
11385 +
11386 +extern int vc_set_prio_bias(struct vx_info *, void __user *);
11387 +extern int vc_get_prio_bias(struct vx_info *, void __user *);
11388 +
11389 +#endif /* _VSERVER_SCHED_CMD_H */
11390 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/sched_def.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/sched_def.h
11391 --- linux-4.1.41/include/linux/vserver/sched_def.h      1970-01-01 00:00:00.000000000 +0000
11392 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/sched_def.h  2016-07-05 04:41:47.000000000 +0000
11393 @@ -0,0 +1,38 @@
11394 +#ifndef _VSERVER_SCHED_DEF_H
11395 +#define _VSERVER_SCHED_DEF_H
11396 +
11397 +#include <linux/spinlock.h>
11398 +#include <linux/jiffies.h>
11399 +#include <linux/cpumask.h>
11400 +#include <asm/atomic.h>
11401 +#include <asm/param.h>
11402 +
11403 +
11404 +/* context sub struct */
11405 +
11406 +struct _vx_sched {
11407 +       int prio_bias;                  /* bias offset for priority */
11408 +
11409 +       cpumask_t update;               /* CPUs which should update */
11410 +};
11411 +
11412 +struct _vx_sched_pc {
11413 +       int prio_bias;                  /* bias offset for priority */
11414 +
11415 +       uint64_t user_ticks;            /* token tick events */
11416 +       uint64_t sys_ticks;             /* token tick events */
11417 +       uint64_t hold_ticks;            /* token ticks paused */
11418 +};
11419 +
11420 +
11421 +#ifdef CONFIG_VSERVER_DEBUG
11422 +
11423 +static inline void __dump_vx_sched(struct _vx_sched *sched)
11424 +{
11425 +       printk("\t_vx_sched:\n");
11426 +       printk("\t priority = %4d\n", sched->prio_bias);
11427 +}
11428 +
11429 +#endif
11430 +
11431 +#endif /* _VSERVER_SCHED_DEF_H */
11432 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/signal.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/signal.h
11433 --- linux-4.1.41/include/linux/vserver/signal.h 1970-01-01 00:00:00.000000000 +0000
11434 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/signal.h     2016-07-05 04:41:47.000000000 +0000
11435 @@ -0,0 +1,14 @@
11436 +#ifndef _VSERVER_SIGNAL_H
11437 +#define _VSERVER_SIGNAL_H
11438 +
11439 +
11440 +#ifdef __KERNEL__
11441 +
11442 +struct vx_info;
11443 +
11444 +int vx_info_kill(struct vx_info *, int, int);
11445 +
11446 +#endif /* __KERNEL__ */
11447 +#else  /* _VSERVER_SIGNAL_H */
11448 +#warning duplicate inclusion
11449 +#endif /* _VSERVER_SIGNAL_H */
11450 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/signal_cmd.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/signal_cmd.h
11451 --- linux-4.1.41/include/linux/vserver/signal_cmd.h     1970-01-01 00:00:00.000000000 +0000
11452 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/signal_cmd.h 2016-07-05 04:41:47.000000000 +0000
11453 @@ -0,0 +1,14 @@
11454 +#ifndef _VSERVER_SIGNAL_CMD_H
11455 +#define _VSERVER_SIGNAL_CMD_H
11456 +
11457 +#include <uapi/vserver/signal_cmd.h>
11458 +
11459 +
11460 +extern int vc_ctx_kill(struct vx_info *, void __user *);
11461 +extern int vc_wait_exit(struct vx_info *, void __user *);
11462 +
11463 +
11464 +extern int vc_get_pflags(uint32_t pid, void __user *);
11465 +extern int vc_set_pflags(uint32_t pid, void __user *);
11466 +
11467 +#endif /* _VSERVER_SIGNAL_CMD_H */
11468 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/space.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/space.h
11469 --- linux-4.1.41/include/linux/vserver/space.h  1970-01-01 00:00:00.000000000 +0000
11470 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/space.h      2016-07-05 04:41:47.000000000 +0000
11471 @@ -0,0 +1,12 @@
11472 +#ifndef _VSERVER_SPACE_H
11473 +#define _VSERVER_SPACE_H
11474 +
11475 +#include <linux/types.h>
11476 +
11477 +struct vx_info;
11478 +
11479 +int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index);
11480 +
11481 +#else  /* _VSERVER_SPACE_H */
11482 +#warning duplicate inclusion
11483 +#endif /* _VSERVER_SPACE_H */
11484 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/space_cmd.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/space_cmd.h
11485 --- linux-4.1.41/include/linux/vserver/space_cmd.h      1970-01-01 00:00:00.000000000 +0000
11486 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/space_cmd.h  2016-07-05 04:41:47.000000000 +0000
11487 @@ -0,0 +1,13 @@
11488 +#ifndef _VSERVER_SPACE_CMD_H
11489 +#define _VSERVER_SPACE_CMD_H
11490 +
11491 +#include <uapi/vserver/space_cmd.h>
11492 +
11493 +
11494 +extern int vc_enter_space_v1(struct vx_info *, void __user *);
11495 +extern int vc_set_space_v1(struct vx_info *, void __user *);
11496 +extern int vc_enter_space(struct vx_info *, void __user *);
11497 +extern int vc_set_space(struct vx_info *, void __user *);
11498 +extern int vc_get_space_mask(void __user *, int);
11499 +
11500 +#endif /* _VSERVER_SPACE_CMD_H */
11501 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/switch.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/switch.h
11502 --- linux-4.1.41/include/linux/vserver/switch.h 1970-01-01 00:00:00.000000000 +0000
11503 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/switch.h     2016-07-05 04:41:47.000000000 +0000
11504 @@ -0,0 +1,8 @@
11505 +#ifndef _VSERVER_SWITCH_H
11506 +#define _VSERVER_SWITCH_H
11507 +
11508 +
11509 +#include <linux/errno.h>
11510 +#include <uapi/vserver/switch.h>
11511 +
11512 +#endif /* _VSERVER_SWITCH_H */
11513 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/tag.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/tag.h
11514 --- linux-4.1.41/include/linux/vserver/tag.h    1970-01-01 00:00:00.000000000 +0000
11515 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/tag.h        2016-07-05 04:41:47.000000000 +0000
11516 @@ -0,0 +1,160 @@
11517 +#ifndef _DX_TAG_H
11518 +#define _DX_TAG_H
11519 +
11520 +#include <linux/types.h>
11521 +#include <linux/uidgid.h>
11522 +
11523 +
11524 +#define DX_TAG(in)     (IS_TAGGED(in))
11525 +
11526 +
11527 +#ifdef CONFIG_TAG_NFSD
11528 +#define DX_TAG_NFSD    1
11529 +#else
11530 +#define DX_TAG_NFSD    0
11531 +#endif
11532 +
11533 +
11534 +#ifdef CONFIG_TAGGING_NONE
11535 +
11536 +#define MAX_UID                0xFFFFFFFF
11537 +#define MAX_GID                0xFFFFFFFF
11538 +
11539 +#define INOTAG_TAG(cond, uid, gid, tag)        (0)
11540 +
11541 +#define TAGINO_UID(cond, uid, tag)     (uid)
11542 +#define TAGINO_GID(cond, gid, tag)     (gid)
11543 +
11544 +#endif
11545 +
11546 +
11547 +#ifdef CONFIG_TAGGING_GID16
11548 +
11549 +#define MAX_UID                0xFFFFFFFF
11550 +#define MAX_GID                0x0000FFFF
11551 +
11552 +#define INOTAG_TAG(cond, uid, gid, tag)        \
11553 +       ((cond) ? (((gid) >> 16) & 0xFFFF) : 0)
11554 +
11555 +#define TAGINO_UID(cond, uid, tag)     (uid)
11556 +#define TAGINO_GID(cond, gid, tag)     \
11557 +       ((cond) ? (((gid) & 0xFFFF) | ((tag) << 16)) : (gid))
11558 +
11559 +#endif
11560 +
11561 +
11562 +#ifdef CONFIG_TAGGING_ID24
11563 +
11564 +#define MAX_UID                0x00FFFFFF
11565 +#define MAX_GID                0x00FFFFFF
11566 +
11567 +#define INOTAG_TAG(cond, uid, gid, tag)        \
11568 +       ((cond) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0)
11569 +
11570 +#define TAGINO_UID(cond, uid, tag)     \
11571 +       ((cond) ? (((uid) & 0xFFFFFF) | (((tag) & 0xFF00) << 16)) : (uid))
11572 +#define TAGINO_GID(cond, gid, tag)     \
11573 +       ((cond) ? (((gid) & 0xFFFFFF) | (((tag) & 0x00FF) << 24)) : (gid))
11574 +
11575 +#endif
11576 +
11577 +
11578 +#ifdef CONFIG_TAGGING_UID16
11579 +
11580 +#define MAX_UID                0x0000FFFF
11581 +#define MAX_GID                0xFFFFFFFF
11582 +
11583 +#define INOTAG_TAG(cond, uid, gid, tag)        \
11584 +       ((cond) ? (((uid) >> 16) & 0xFFFF) : 0)
11585 +
11586 +#define TAGINO_UID(cond, uid, tag)     \
11587 +       ((cond) ? (((uid) & 0xFFFF) | ((tag) << 16)) : (uid))
11588 +#define TAGINO_GID(cond, gid, tag)     (gid)
11589 +
11590 +#endif
11591 +
11592 +
11593 +#ifdef CONFIG_TAGGING_INTERN
11594 +
11595 +#define MAX_UID                0xFFFFFFFF
11596 +#define MAX_GID                0xFFFFFFFF
11597 +
11598 +#define INOTAG_TAG(cond, uid, gid, tag)        \
11599 +       ((cond) ? (tag) : 0)
11600 +
11601 +#define TAGINO_UID(cond, uid, tag)     (uid)
11602 +#define TAGINO_GID(cond, gid, tag)     (gid)
11603 +
11604 +#endif
11605 +
11606 +
11607 +#ifndef CONFIG_TAGGING_NONE
11608 +#define dx_current_fstag(sb)   \
11609 +       ((sb)->s_flags & MS_TAGGED ? dx_current_tag() : 0)
11610 +#else
11611 +#define dx_current_fstag(sb)   (0)
11612 +#endif
11613 +
11614 +#ifndef CONFIG_TAGGING_INTERN
11615 +#define TAGINO_TAG(cond, tag)  (0)
11616 +#else
11617 +#define TAGINO_TAG(cond, tag)  ((cond) ? (tag) : 0)
11618 +#endif
11619 +
11620 +#define TAGINO_KUID(cond, kuid, ktag)  \
11621 +       KUIDT_INIT(TAGINO_UID(cond, __kuid_val(kuid), __ktag_val(ktag)))
11622 +#define TAGINO_KGID(cond, kgid, ktag)  \
11623 +       KGIDT_INIT(TAGINO_GID(cond, __kgid_val(kgid), __ktag_val(ktag)))
11624 +#define TAGINO_KTAG(cond, ktag)                \
11625 +       KTAGT_INIT(TAGINO_TAG(cond, __ktag_val(ktag)))
11626 +
11627 +
11628 +#define INOTAG_UID(cond, uid, gid)     \
11629 +       ((cond) ? ((uid) & MAX_UID) : (uid))
11630 +#define INOTAG_GID(cond, uid, gid)     \
11631 +       ((cond) ? ((gid) & MAX_GID) : (gid))
11632 +
11633 +#define INOTAG_KUID(cond, kuid, kgid)  \
11634 +       KUIDT_INIT(INOTAG_UID(cond, __kuid_val(kuid), __kgid_val(kgid)))
11635 +#define INOTAG_KGID(cond, kuid, kgid)  \
11636 +       KGIDT_INIT(INOTAG_GID(cond, __kuid_val(kuid), __kgid_val(kgid)))
11637 +#define INOTAG_KTAG(cond, kuid, kgid, ktag) \
11638 +       KTAGT_INIT(INOTAG_TAG(cond, \
11639 +               __kuid_val(kuid), __kgid_val(kgid), __ktag_val(ktag)))
11640 +
11641 +
11642 +static inline uid_t dx_map_uid(uid_t uid)
11643 +{
11644 +       if ((uid > MAX_UID) && (uid != -1))
11645 +               uid = -2;
11646 +       return (uid & MAX_UID);
11647 +}
11648 +
11649 +static inline gid_t dx_map_gid(gid_t gid)
11650 +{
11651 +       if ((gid > MAX_GID) && (gid != -1))
11652 +               gid = -2;
11653 +       return (gid & MAX_GID);
11654 +}
11655 +
11656 +struct peer_tag {
11657 +       int32_t xid;
11658 +       int32_t nid;
11659 +};
11660 +
11661 +#define dx_notagcheck(sb) ((sb) && ((sb)->s_flags & MS_NOTAGCHECK))
11662 +
11663 +int dx_parse_tag(char *string, vtag_t *tag, int remove, int *mnt_flags,
11664 +                unsigned long *flags);
11665 +
11666 +#ifdef CONFIG_PROPAGATE
11667 +
11668 +void __dx_propagate_tag(struct nameidata *nd, struct inode *inode);
11669 +
11670 +#define dx_propagate_tag(n, i) __dx_propagate_tag(n, i)
11671 +
11672 +#else
11673 +#define dx_propagate_tag(n, i) do { } while (0)
11674 +#endif
11675 +
11676 +#endif /* _DX_TAG_H */
11677 diff -NurpP --minimal linux-4.1.41/include/linux/vserver/tag_cmd.h linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/tag_cmd.h
11678 --- linux-4.1.41/include/linux/vserver/tag_cmd.h        1970-01-01 00:00:00.000000000 +0000
11679 +++ linux-4.1.41-vs2.3.8.5.3/include/linux/vserver/tag_cmd.h    2016-07-05 04:41:47.000000000 +0000
11680 @@ -0,0 +1,10 @@
11681 +#ifndef _VSERVER_TAG_CMD_H
11682 +#define _VSERVER_TAG_CMD_H
11683 +
11684 +#include <uapi/vserver/tag_cmd.h>
11685 +
11686 +extern int vc_task_tag(uint32_t);
11687 +
11688 +extern int vc_tag_migrate(uint32_t);
11689 +
11690 +#endif /* _VSERVER_TAG_CMD_H */
11691 diff -NurpP --minimal linux-4.1.41/include/net/addrconf.h linux-4.1.41-vs2.3.8.5.3/include/net/addrconf.h
11692 --- linux-4.1.41/include/net/addrconf.h 2017-06-23 10:04:01.000000000 +0000
11693 +++ linux-4.1.41-vs2.3.8.5.3/include/net/addrconf.h     2017-06-23 10:07:02.000000000 +0000
11694 @@ -84,7 +84,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str
11695  
11696  int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
11697                        const struct in6_addr *daddr, unsigned int srcprefs,
11698 -                      struct in6_addr *saddr);
11699 +                      struct in6_addr *saddr, struct nx_info *nxi);
11700  int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
11701                       u32 banned_flags);
11702  int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
11703 diff -NurpP --minimal linux-4.1.41/include/net/af_unix.h linux-4.1.41-vs2.3.8.5.3/include/net/af_unix.h
11704 --- linux-4.1.41/include/net/af_unix.h  2017-06-23 10:04:01.000000000 +0000
11705 +++ linux-4.1.41-vs2.3.8.5.3/include/net/af_unix.h      2016-07-05 04:41:47.000000000 +0000
11706 @@ -4,6 +4,7 @@
11707  #include <linux/socket.h>
11708  #include <linux/un.h>
11709  #include <linux/mutex.h>
11710 +// #include <linux/vs_base.h>
11711  #include <net/sock.h>
11712  
11713  void unix_inflight(struct user_struct *user, struct file *fp);
11714 diff -NurpP --minimal linux-4.1.41/include/net/inet_timewait_sock.h linux-4.1.41-vs2.3.8.5.3/include/net/inet_timewait_sock.h
11715 --- linux-4.1.41/include/net/inet_timewait_sock.h       2017-06-23 10:04:01.000000000 +0000
11716 +++ linux-4.1.41-vs2.3.8.5.3/include/net/inet_timewait_sock.h   2016-07-05 04:41:47.000000000 +0000
11717 @@ -70,6 +70,10 @@ struct inet_timewait_sock {
11718  #define tw_dport               __tw_common.skc_dport
11719  #define tw_num                 __tw_common.skc_num
11720  #define tw_cookie              __tw_common.skc_cookie
11721 +#define tw_xid                 __tw_common.skc_xid
11722 +#define tw_vx_info             __tw_common.skc_vx_info
11723 +#define tw_nid                 __tw_common.skc_nid
11724 +#define tw_nx_info             __tw_common.skc_nx_info
11725  
11726         int                     tw_timeout;
11727         volatile unsigned char  tw_substate;
11728 diff -NurpP --minimal linux-4.1.41/include/net/ip6_route.h linux-4.1.41-vs2.3.8.5.3/include/net/ip6_route.h
11729 --- linux-4.1.41/include/net/ip6_route.h        2017-06-23 10:04:01.000000000 +0000
11730 +++ linux-4.1.41-vs2.3.8.5.3/include/net/ip6_route.h    2017-06-23 10:07:02.000000000 +0000
11731 @@ -89,7 +89,7 @@ int ip6_del_rt(struct rt6_info *);
11732  
11733  int ip6_route_get_saddr(struct net *net, struct rt6_info *rt,
11734                         const struct in6_addr *daddr, unsigned int prefs,
11735 -                       struct in6_addr *saddr);
11736 +                       struct in6_addr *saddr, struct nx_info *nxi);
11737  
11738  struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
11739                             const struct in6_addr *saddr, int oif, int flags);
11740 diff -NurpP --minimal linux-4.1.41/include/net/route.h linux-4.1.41-vs2.3.8.5.3/include/net/route.h
11741 --- linux-4.1.41/include/net/route.h    2015-04-12 22:12:50.000000000 +0000
11742 +++ linux-4.1.41-vs2.3.8.5.3/include/net/route.h        2016-07-05 04:41:47.000000000 +0000
11743 @@ -207,6 +207,9 @@ static inline void ip_rt_put(struct rtab
11744         dst_release(&rt->dst);
11745  }
11746  
11747 +#include <linux/vs_base.h>
11748 +#include <linux/vs_inet.h>
11749 +
11750  #define IPTOS_RT_MASK  (IPTOS_TOS_MASK & ~3)
11751  
11752  extern const __u8 ip_tos2prio[16];
11753 @@ -254,6 +257,9 @@ static inline void ip_route_connect_init
11754                            protocol, flow_flags, dst, src, dport, sport);
11755  }
11756  
11757 +extern struct rtable *ip_v4_find_src(struct net *net, struct nx_info *,
11758 +       struct flowi4 *);
11759 +
11760  static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
11761                                               __be32 dst, __be32 src, u32 tos,
11762                                               int oif, u8 protocol,
11763 @@ -262,11 +268,25 @@ static inline struct rtable *ip_route_co
11764  {
11765         struct net *net = sock_net(sk);
11766         struct rtable *rt;
11767 +       struct nx_info *nx_info = current_nx_info();
11768  
11769         ip_route_connect_init(fl4, dst, src, tos, oif, protocol,
11770                               sport, dport, sk);
11771  
11772 -       if (!dst || !src) {
11773 +       if (sk)
11774 +               nx_info = sk->sk_nx_info;
11775 +
11776 +       vxdprintk(VXD_CBIT(net, 4),
11777 +               "ip_route_connect(%p) %p,%p;%lx",
11778 +               sk, nx_info, sk->sk_socket,
11779 +               (sk->sk_socket?sk->sk_socket->flags:0));
11780 +
11781 +       rt = ip_v4_find_src(net, nx_info, fl4);
11782 +       if (IS_ERR(rt))
11783 +               return rt;
11784 +       ip_rt_put(rt);
11785 +
11786 +       if (!fl4->daddr || !fl4->saddr) {
11787                 rt = __ip_route_output_key(net, fl4);
11788                 if (IS_ERR(rt))
11789                         return rt;
11790 diff -NurpP --minimal linux-4.1.41/include/net/sock.h linux-4.1.41-vs2.3.8.5.3/include/net/sock.h
11791 --- linux-4.1.41/include/net/sock.h     2017-06-23 10:04:01.000000000 +0000
11792 +++ linux-4.1.41-vs2.3.8.5.3/include/net/sock.h 2016-07-05 04:41:47.000000000 +0000
11793 @@ -196,6 +196,10 @@ struct sock_common {
11794         struct in6_addr         skc_v6_daddr;
11795         struct in6_addr         skc_v6_rcv_saddr;
11796  #endif
11797 +       vxid_t                  skc_xid;
11798 +       struct vx_info          *skc_vx_info;
11799 +       vnid_t                  skc_nid;
11800 +       struct nx_info          *skc_nx_info;
11801  
11802         atomic64_t              skc_cookie;
11803  
11804 @@ -328,8 +332,12 @@ struct sock {
11805  #define sk_prot                        __sk_common.skc_prot
11806  #define sk_net                 __sk_common.skc_net
11807  #define sk_v6_daddr            __sk_common.skc_v6_daddr
11808 -#define sk_v6_rcv_saddr        __sk_common.skc_v6_rcv_saddr
11809 +#define sk_v6_rcv_saddr                __sk_common.skc_v6_rcv_saddr
11810  #define sk_cookie              __sk_common.skc_cookie
11811 +#define sk_xid                 __sk_common.skc_xid
11812 +#define sk_vx_info             __sk_common.skc_vx_info
11813 +#define sk_nid                 __sk_common.skc_nid
11814 +#define sk_nx_info             __sk_common.skc_nx_info
11815  
11816         socket_lock_t           sk_lock;
11817         struct sk_buff_head     sk_receive_queue;
11818 diff -NurpP --minimal linux-4.1.41/include/uapi/Kbuild linux-4.1.41-vs2.3.8.5.3/include/uapi/Kbuild
11819 --- linux-4.1.41/include/uapi/Kbuild    2015-04-12 22:12:50.000000000 +0000
11820 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/Kbuild        2016-07-05 04:41:47.000000000 +0000
11821 @@ -13,3 +13,4 @@ header-y += drm/
11822  header-y += xen/
11823  header-y += scsi/
11824  header-y += misc/
11825 +header-y += vserver/
11826 diff -NurpP --minimal linux-4.1.41/include/uapi/linux/capability.h linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/capability.h
11827 --- linux-4.1.41/include/uapi/linux/capability.h        2015-04-12 22:12:50.000000000 +0000
11828 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/capability.h    2016-07-05 04:41:47.000000000 +0000
11829 @@ -259,6 +259,7 @@ struct vfs_cap_data {
11830     arbitrary SCSI commands */
11831  /* Allow setting encryption key on loopback filesystem */
11832  /* Allow setting zone reclaim policy */
11833 +/* Allow the selection of a security context */
11834  
11835  #define CAP_SYS_ADMIN        21
11836  
11837 @@ -354,7 +355,12 @@ struct vfs_cap_data {
11838  
11839  #define CAP_LAST_CAP         CAP_AUDIT_READ
11840  
11841 -#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
11842 +/* Allow context manipulations */
11843 +/* Allow changing context info on files */
11844 +
11845 +#define CAP_CONTEXT         63
11846 +
11847 +#define cap_valid(x) ((x) >= 0 && ((x) <= CAP_LAST_CAP || (x) == CAP_CONTEXT))
11848  
11849  /*
11850   * Bit location of each capability (used by user-space library and kernel)
11851 diff -NurpP --minimal linux-4.1.41/include/uapi/linux/fs.h linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/fs.h
11852 --- linux-4.1.41/include/uapi/linux/fs.h        2015-04-12 22:12:50.000000000 +0000
11853 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/fs.h    2016-07-05 04:41:47.000000000 +0000
11854 @@ -91,6 +91,9 @@ struct inodes_stat_t {
11855  #define MS_I_VERSION   (1<<23) /* Update inode I_version field */
11856  #define MS_STRICTATIME (1<<24) /* Always perform atime updates */
11857  #define MS_LAZYTIME    (1<<25) /* Update the on-disk [acm]times lazily */
11858 +#define MS_TAGGED      (1<<8)  /* use generic inode tagging */
11859 +#define MS_NOTAGCHECK  (1<<9)  /* don't check tags */
11860 +#define MS_TAGID       (1<<26) /* use specific tag for this mount */
11861  
11862  /* These sb flags are internal to the kernel */
11863  #define MS_NOSEC       (1<<28)
11864 @@ -197,11 +200,14 @@ struct inodes_stat_t {
11865  #define FS_EXTENT_FL                   0x00080000 /* Extents */
11866  #define FS_DIRECTIO_FL                 0x00100000 /* Use direct i/o */
11867  #define FS_NOCOW_FL                    0x00800000 /* Do not cow file */
11868 +#define FS_IXUNLINK_FL                 0x08000000 /* Immutable invert on unlink */
11869  #define FS_RESERVED_FL                 0x80000000 /* reserved for ext2 lib */
11870  
11871 -#define FS_FL_USER_VISIBLE             0x0003DFFF /* User visible flags */
11872 -#define FS_FL_USER_MODIFIABLE          0x000380FF /* User modifiable flags */
11873 +#define FS_BARRIER_FL                  0x04000000 /* Barrier for chroot() */
11874 +#define FS_COW_FL                      0x20000000 /* Copy on Write marker */
11875  
11876 +#define FS_FL_USER_VISIBLE             0x0103DFFF /* User visible flags */
11877 +#define FS_FL_USER_MODIFIABLE          0x010380FF /* User modifiable flags */
11878  
11879  #define SYNC_FILE_RANGE_WAIT_BEFORE    1
11880  #define SYNC_FILE_RANGE_WRITE          2
11881 diff -NurpP --minimal linux-4.1.41/include/uapi/linux/gfs2_ondisk.h linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/gfs2_ondisk.h
11882 --- linux-4.1.41/include/uapi/linux/gfs2_ondisk.h       2015-04-12 22:12:50.000000000 +0000
11883 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/gfs2_ondisk.h   2016-07-05 04:41:47.000000000 +0000
11884 @@ -225,6 +225,9 @@ enum {
11885         gfs2fl_Sync             = 8,
11886         gfs2fl_System           = 9,
11887         gfs2fl_TopLevel         = 10,
11888 +       gfs2fl_IXUnlink         = 16,
11889 +       gfs2fl_Barrier          = 17,
11890 +       gfs2fl_Cow              = 18,
11891         gfs2fl_TruncInProg      = 29,
11892         gfs2fl_InheritDirectio  = 30,
11893         gfs2fl_InheritJdata     = 31,
11894 @@ -242,6 +245,9 @@ enum {
11895  #define GFS2_DIF_SYNC                  0x00000100
11896  #define GFS2_DIF_SYSTEM                        0x00000200 /* New in gfs2 */
11897  #define GFS2_DIF_TOPDIR                        0x00000400 /* New in gfs2 */
11898 +#define GFS2_DIF_IXUNLINK               0x00010000
11899 +#define GFS2_DIF_BARRIER                0x00020000
11900 +#define GFS2_DIF_COW                    0x00040000
11901  #define GFS2_DIF_TRUNC_IN_PROG         0x20000000 /* New in gfs2 */
11902  #define GFS2_DIF_INHERIT_DIRECTIO      0x40000000 /* only in gfs1 */
11903  #define GFS2_DIF_INHERIT_JDATA         0x80000000
11904 diff -NurpP --minimal linux-4.1.41/include/uapi/linux/if_tun.h linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/if_tun.h
11905 --- linux-4.1.41/include/uapi/linux/if_tun.h    2015-04-12 22:12:50.000000000 +0000
11906 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/if_tun.h        2016-07-05 04:41:47.000000000 +0000
11907 @@ -50,6 +50,7 @@
11908  #define TUNGETFILTER _IOR('T', 219, struct sock_fprog)
11909  #define TUNSETVNETLE _IOW('T', 220, int)
11910  #define TUNGETVNETLE _IOR('T', 221, int)
11911 +#define TUNSETNID     _IOW('T', 222, int)
11912  
11913  /* TUNSETIFF ifr flags */
11914  #define IFF_TUN                0x0001
11915 diff -NurpP --minimal linux-4.1.41/include/uapi/linux/major.h linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/major.h
11916 --- linux-4.1.41/include/uapi/linux/major.h     2015-04-12 22:12:50.000000000 +0000
11917 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/major.h 2016-07-05 04:41:47.000000000 +0000
11918 @@ -15,6 +15,7 @@
11919  #define HD_MAJOR               IDE0_MAJOR
11920  #define PTY_SLAVE_MAJOR                3
11921  #define TTY_MAJOR              4
11922 +#define VROOT_MAJOR            4
11923  #define TTYAUX_MAJOR           5
11924  #define LP_MAJOR               6
11925  #define VCS_MAJOR              7
11926 diff -NurpP --minimal linux-4.1.41/include/uapi/linux/nfs_mount.h linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/nfs_mount.h
11927 --- linux-4.1.41/include/uapi/linux/nfs_mount.h 2015-04-12 22:12:50.000000000 +0000
11928 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/nfs_mount.h     2016-07-05 04:41:47.000000000 +0000
11929 @@ -63,7 +63,8 @@ struct nfs_mount_data {
11930  #define NFS_MOUNT_SECFLAVOUR   0x2000  /* 5 non-text parsed mount data only */
11931  #define NFS_MOUNT_NORDIRPLUS   0x4000  /* 5 */
11932  #define NFS_MOUNT_UNSHARED     0x8000  /* 5 */
11933 -#define NFS_MOUNT_FLAGMASK     0xFFFF
11934 +#define NFS_MOUNT_TAGGED       0x10000 /* context tagging */
11935 +#define NFS_MOUNT_FLAGMASK     0x1FFFF
11936  
11937  /* The following are for internal use only */
11938  #define NFS_MOUNT_LOOKUP_CACHE_NONEG   0x10000
11939 diff -NurpP --minimal linux-4.1.41/include/uapi/linux/reboot.h linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/reboot.h
11940 --- linux-4.1.41/include/uapi/linux/reboot.h    2015-04-12 22:12:50.000000000 +0000
11941 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/reboot.h        2016-07-05 04:41:47.000000000 +0000
11942 @@ -33,7 +33,7 @@
11943  #define        LINUX_REBOOT_CMD_RESTART2       0xA1B2C3D4
11944  #define        LINUX_REBOOT_CMD_SW_SUSPEND     0xD000FCE2
11945  #define        LINUX_REBOOT_CMD_KEXEC          0x45584543
11946 -
11947 +#define        LINUX_REBOOT_CMD_OOM            0xDEADBEEF
11948  
11949  
11950  #endif /* _UAPI_LINUX_REBOOT_H */
11951 diff -NurpP --minimal linux-4.1.41/include/uapi/linux/sysctl.h linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/sysctl.h
11952 --- linux-4.1.41/include/uapi/linux/sysctl.h    2015-04-12 22:12:50.000000000 +0000
11953 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/linux/sysctl.h        2016-07-05 04:41:47.000000000 +0000
11954 @@ -60,6 +60,7 @@ enum
11955         CTL_ABI=9,              /* Binary emulation */
11956         CTL_CPU=10,             /* CPU stuff (speed scaling, etc) */
11957         CTL_ARLAN=254,          /* arlan wireless driver */
11958 +       CTL_VSERVER=4242,       /* Linux-VServer debug */
11959         CTL_S390DBF=5677,       /* s390 debug */
11960         CTL_SUNRPC=7249,        /* sunrpc debug */
11961         CTL_PM=9899,            /* frv power management */
11962 @@ -94,6 +95,7 @@ enum
11963  
11964         KERN_PANIC=15,          /* int: panic timeout */
11965         KERN_REALROOTDEV=16,    /* real root device to mount after initrd */
11966 +       KERN_VSHELPER=17,       /* string: path to vshelper policy agent */
11967  
11968         KERN_SPARC_REBOOT=21,   /* reboot command on Sparc */
11969         KERN_CTLALTDEL=22,      /* int: allow ctl-alt-del to reboot */
11970 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/Kbuild linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/Kbuild
11971 --- linux-4.1.41/include/uapi/vserver/Kbuild    1970-01-01 00:00:00.000000000 +0000
11972 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/Kbuild        2016-07-05 04:41:47.000000000 +0000
11973 @@ -0,0 +1,9 @@
11974 +
11975 +header-y += context_cmd.h network_cmd.h space_cmd.h \
11976 +       cacct_cmd.h cvirt_cmd.h limit_cmd.h dlimit_cmd.h \
11977 +       inode_cmd.h tag_cmd.h sched_cmd.h signal_cmd.h \
11978 +       debug_cmd.h device_cmd.h
11979 +
11980 +header-y += switch.h context.h network.h monitor.h \
11981 +       limit.h inode.h device.h
11982 +
11983 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/cacct_cmd.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/cacct_cmd.h
11984 --- linux-4.1.41/include/uapi/vserver/cacct_cmd.h       1970-01-01 00:00:00.000000000 +0000
11985 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/cacct_cmd.h   2016-07-05 04:41:47.000000000 +0000
11986 @@ -0,0 +1,15 @@
11987 +#ifndef _UAPI_VS_CACCT_CMD_H
11988 +#define _UAPI_VS_CACCT_CMD_H
11989 +
11990 +
11991 +/* virtual host info name commands */
11992 +
11993 +#define VCMD_sock_stat         VC_CMD(VSTAT, 5, 0)
11994 +
11995 +struct vcmd_sock_stat_v0 {
11996 +       uint32_t field;
11997 +       uint32_t count[3];
11998 +       uint64_t total[3];
11999 +};
12000 +
12001 +#endif /* _UAPI_VS_CACCT_CMD_H */
12002 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/context.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/context.h
12003 --- linux-4.1.41/include/uapi/vserver/context.h 1970-01-01 00:00:00.000000000 +0000
12004 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/context.h     2016-07-05 04:41:47.000000000 +0000
12005 @@ -0,0 +1,81 @@
12006 +#ifndef _UAPI_VS_CONTEXT_H
12007 +#define _UAPI_VS_CONTEXT_H
12008 +
12009 +#include <linux/types.h>
12010 +#include <linux/capability.h>
12011 +
12012 +
12013 +/* context flags */
12014 +
12015 +#define VXF_INFO_SCHED         0x00000002
12016 +#define VXF_INFO_NPROC         0x00000004
12017 +#define VXF_INFO_PRIVATE       0x00000008
12018 +
12019 +#define VXF_INFO_INIT          0x00000010
12020 +#define VXF_INFO_HIDE          0x00000020
12021 +#define VXF_INFO_ULIMIT                0x00000040
12022 +#define VXF_INFO_NSPACE                0x00000080
12023 +
12024 +#define VXF_SCHED_HARD         0x00000100
12025 +#define VXF_SCHED_PRIO         0x00000200
12026 +#define VXF_SCHED_PAUSE                0x00000400
12027 +
12028 +#define VXF_VIRT_MEM           0x00010000
12029 +#define VXF_VIRT_UPTIME                0x00020000
12030 +#define VXF_VIRT_CPU           0x00040000
12031 +#define VXF_VIRT_LOAD          0x00080000
12032 +#define VXF_VIRT_TIME          0x00100000
12033 +
12034 +#define VXF_HIDE_MOUNT         0x01000000
12035 +/* was VXF_HIDE_NETIF          0x02000000 */
12036 +#define VXF_HIDE_VINFO         0x04000000
12037 +
12038 +#define VXF_STATE_SETUP                (1ULL << 32)
12039 +#define VXF_STATE_INIT         (1ULL << 33)
12040 +#define VXF_STATE_ADMIN                (1ULL << 34)
12041 +
12042 +#define VXF_SC_HELPER          (1ULL << 36)
12043 +#define VXF_REBOOT_KILL                (1ULL << 37)
12044 +#define VXF_PERSISTENT         (1ULL << 38)
12045 +
12046 +#define VXF_FORK_RSS           (1ULL << 48)
12047 +#define VXF_PROLIFIC           (1ULL << 49)
12048 +
12049 +#define VXF_IGNEG_NICE         (1ULL << 52)
12050 +
12051 +#define VXF_ONE_TIME           (0x0007ULL << 32)
12052 +
12053 +#define VXF_INIT_SET           (VXF_STATE_SETUP | VXF_STATE_INIT | VXF_STATE_ADMIN)
12054 +
12055 +
12056 +/* context migration */
12057 +
12058 +#define VXM_SET_INIT           0x00000001
12059 +#define VXM_SET_REAPER         0x00000002
12060 +
12061 +/* context caps */
12062 +
12063 +#define VXC_SET_UTSNAME                0x00000001
12064 +#define VXC_SET_RLIMIT         0x00000002
12065 +#define VXC_FS_SECURITY                0x00000004
12066 +#define VXC_FS_TRUSTED         0x00000008
12067 +#define VXC_TIOCSTI            0x00000010
12068 +
12069 +/* was VXC_RAW_ICMP            0x00000100 */
12070 +#define VXC_SYSLOG             0x00001000
12071 +#define VXC_OOM_ADJUST         0x00002000
12072 +#define VXC_AUDIT_CONTROL      0x00004000
12073 +
12074 +#define VXC_SECURE_MOUNT       0x00010000
12075 +/* #define VXC_SECURE_REMOUNT  0x00020000 */
12076 +#define VXC_BINARY_MOUNT       0x00040000
12077 +#define VXC_DEV_MOUNT          0x00080000
12078 +
12079 +#define VXC_QUOTA_CTL          0x00100000
12080 +#define VXC_ADMIN_MAPPER       0x00200000
12081 +#define VXC_ADMIN_CLOOP                0x00400000
12082 +
12083 +#define VXC_KTHREAD            0x01000000
12084 +#define VXC_NAMESPACE          0x02000000
12085 +
12086 +#endif /* _UAPI_VS_CONTEXT_H */
12087 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/context_cmd.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/context_cmd.h
12088 --- linux-4.1.41/include/uapi/vserver/context_cmd.h     1970-01-01 00:00:00.000000000 +0000
12089 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/context_cmd.h 2016-07-05 04:41:47.000000000 +0000
12090 @@ -0,0 +1,115 @@
12091 +#ifndef _UAPI_VS_CONTEXT_CMD_H
12092 +#define _UAPI_VS_CONTEXT_CMD_H
12093 +
12094 +
12095 +/* vinfo commands */
12096 +
12097 +#define VCMD_task_xid          VC_CMD(VINFO, 1, 0)
12098 +
12099 +
12100 +#define VCMD_vx_info           VC_CMD(VINFO, 5, 0)
12101 +
12102 +struct vcmd_vx_info_v0 {
12103 +       uint32_t xid;
12104 +       uint32_t initpid;
12105 +       /* more to come */
12106 +};
12107 +
12108 +
12109 +#define VCMD_ctx_stat          VC_CMD(VSTAT, 0, 0)
12110 +
12111 +struct vcmd_ctx_stat_v0 {
12112 +       uint32_t usecnt;
12113 +       uint32_t tasks;
12114 +       /* more to come */
12115 +};
12116 +
12117 +
12118 +/* context commands */
12119 +
12120 +#define VCMD_ctx_create_v0     VC_CMD(VPROC, 1, 0)
12121 +#define VCMD_ctx_create                VC_CMD(VPROC, 1, 1)
12122 +
12123 +struct vcmd_ctx_create {
12124 +       uint64_t flagword;
12125 +};
12126 +
12127 +#define VCMD_ctx_migrate_v0    VC_CMD(PROCMIG, 1, 0)
12128 +#define VCMD_ctx_migrate       VC_CMD(PROCMIG, 1, 1)
12129 +
12130 +struct vcmd_ctx_migrate {
12131 +       uint64_t flagword;
12132 +};
12133 +
12134 +
12135 +
12136 +/* flag commands */
12137 +
12138 +#define VCMD_get_cflags                VC_CMD(FLAGS, 1, 0)
12139 +#define VCMD_set_cflags                VC_CMD(FLAGS, 2, 0)
12140 +
12141 +struct vcmd_ctx_flags_v0 {
12142 +       uint64_t flagword;
12143 +       uint64_t mask;
12144 +};
12145 +
12146 +
12147 +
12148 +/* context caps commands */
12149 +
12150 +#define VCMD_get_ccaps         VC_CMD(FLAGS, 3, 1)
12151 +#define VCMD_set_ccaps         VC_CMD(FLAGS, 4, 1)
12152 +
12153 +struct vcmd_ctx_caps_v1 {
12154 +       uint64_t ccaps;
12155 +       uint64_t cmask;
12156 +};
12157 +
12158 +
12159 +
12160 +/* bcaps commands */
12161 +
12162 +#define VCMD_get_bcaps         VC_CMD(FLAGS, 9, 0)
12163 +#define VCMD_set_bcaps         VC_CMD(FLAGS, 10, 0)
12164 +
12165 +struct vcmd_bcaps {
12166 +       uint64_t bcaps;
12167 +       uint64_t bmask;
12168 +};
12169 +
12170 +
12171 +
12172 +/* umask commands */
12173 +
12174 +#define VCMD_get_umask         VC_CMD(FLAGS, 13, 0)
12175 +#define VCMD_set_umask         VC_CMD(FLAGS, 14, 0)
12176 +
12177 +struct vcmd_umask {
12178 +       uint64_t umask;
12179 +       uint64_t mask;
12180 +};
12181 +
12182 +
12183 +
12184 +/* wmask commands */
12185 +
12186 +#define VCMD_get_wmask         VC_CMD(FLAGS, 15, 0)
12187 +#define VCMD_set_wmask         VC_CMD(FLAGS, 16, 0)
12188 +
12189 +struct vcmd_wmask {
12190 +       uint64_t wmask;
12191 +       uint64_t mask;
12192 +};
12193 +
12194 +
12195 +
12196 +/* OOM badness */
12197 +
12198 +#define VCMD_get_badness       VC_CMD(MEMCTRL, 5, 0)
12199 +#define VCMD_set_badness       VC_CMD(MEMCTRL, 6, 0)
12200 +
12201 +struct vcmd_badness_v0 {
12202 +       int64_t bias;
12203 +};
12204 +
12205 +#endif /* _UAPI_VS_CONTEXT_CMD_H */
12206 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/cvirt_cmd.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/cvirt_cmd.h
12207 --- linux-4.1.41/include/uapi/vserver/cvirt_cmd.h       1970-01-01 00:00:00.000000000 +0000
12208 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/cvirt_cmd.h   2016-07-05 04:41:47.000000000 +0000
12209 @@ -0,0 +1,41 @@
12210 +#ifndef _UAPI_VS_CVIRT_CMD_H
12211 +#define _UAPI_VS_CVIRT_CMD_H
12212 +
12213 +
12214 +/* virtual host info name commands */
12215 +
12216 +#define VCMD_set_vhi_name      VC_CMD(VHOST, 1, 0)
12217 +#define VCMD_get_vhi_name      VC_CMD(VHOST, 2, 0)
12218 +
12219 +struct vcmd_vhi_name_v0 {
12220 +       uint32_t field;
12221 +       char name[65];
12222 +};
12223 +
12224 +
12225 +enum vhi_name_field {
12226 +       VHIN_CONTEXT = 0,
12227 +       VHIN_SYSNAME,
12228 +       VHIN_NODENAME,
12229 +       VHIN_RELEASE,
12230 +       VHIN_VERSION,
12231 +       VHIN_MACHINE,
12232 +       VHIN_DOMAINNAME,
12233 +};
12234 +
12235 +
12236 +
12237 +#define VCMD_virt_stat         VC_CMD(VSTAT, 3, 0)
12238 +
12239 +struct vcmd_virt_stat_v0 {
12240 +       uint64_t offset;
12241 +       uint64_t uptime;
12242 +       uint32_t nr_threads;
12243 +       uint32_t nr_running;
12244 +       uint32_t nr_uninterruptible;
12245 +       uint32_t nr_onhold;
12246 +       uint32_t nr_forks;
12247 +       uint32_t load[3];
12248 +};
12249 +
12250 +#endif /* _UAPI_VS_CVIRT_CMD_H */
12251 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/debug_cmd.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/debug_cmd.h
12252 --- linux-4.1.41/include/uapi/vserver/debug_cmd.h       1970-01-01 00:00:00.000000000 +0000
12253 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/debug_cmd.h   2016-07-05 04:41:47.000000000 +0000
12254 @@ -0,0 +1,24 @@
12255 +#ifndef _UAPI_VS_DEBUG_CMD_H
12256 +#define _UAPI_VS_DEBUG_CMD_H
12257 +
12258 +
12259 +/* debug commands */
12260 +
12261 +#define VCMD_dump_history      VC_CMD(DEBUG, 1, 0)
12262 +
12263 +#define VCMD_read_history      VC_CMD(DEBUG, 5, 0)
12264 +#define VCMD_read_monitor      VC_CMD(DEBUG, 6, 0)
12265 +
12266 +struct  vcmd_read_history_v0 {
12267 +       uint32_t index;
12268 +       uint32_t count;
12269 +       char __user *data;
12270 +};
12271 +
12272 +struct  vcmd_read_monitor_v0 {
12273 +       uint32_t index;
12274 +       uint32_t count;
12275 +       char __user *data;
12276 +};
12277 +
12278 +#endif /* _UAPI_VS_DEBUG_CMD_H */
12279 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/device.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/device.h
12280 --- linux-4.1.41/include/uapi/vserver/device.h  1970-01-01 00:00:00.000000000 +0000
12281 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/device.h      2016-07-05 04:41:47.000000000 +0000
12282 @@ -0,0 +1,12 @@
12283 +#ifndef _UAPI_VS_DEVICE_H
12284 +#define _UAPI_VS_DEVICE_H
12285 +
12286 +
12287 +#define DATTR_CREATE   0x00000001
12288 +#define DATTR_OPEN     0x00000002
12289 +
12290 +#define DATTR_REMAP    0x00000010
12291 +
12292 +#define DATTR_MASK     0x00000013
12293 +
12294 +#endif /* _UAPI_VS_DEVICE_H */
12295 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/device_cmd.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/device_cmd.h
12296 --- linux-4.1.41/include/uapi/vserver/device_cmd.h      1970-01-01 00:00:00.000000000 +0000
12297 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/device_cmd.h  2016-07-05 04:41:47.000000000 +0000
12298 @@ -0,0 +1,16 @@
12299 +#ifndef _UAPI_VS_DEVICE_CMD_H
12300 +#define _UAPI_VS_DEVICE_CMD_H
12301 +
12302 +
12303 +/*  device vserver commands */
12304 +
12305 +#define VCMD_set_mapping       VC_CMD(DEVICE, 1, 0)
12306 +#define VCMD_unset_mapping     VC_CMD(DEVICE, 2, 0)
12307 +
12308 +struct vcmd_set_mapping_v0 {
12309 +       const char __user *device;
12310 +       const char __user *target;
12311 +       uint32_t flags;
12312 +};
12313 +
12314 +#endif /* _UAPI_VS_DEVICE_CMD_H */
12315 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/dlimit_cmd.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/dlimit_cmd.h
12316 --- linux-4.1.41/include/uapi/vserver/dlimit_cmd.h      1970-01-01 00:00:00.000000000 +0000
12317 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/dlimit_cmd.h  2016-07-05 04:41:47.000000000 +0000
12318 @@ -0,0 +1,67 @@
12319 +#ifndef _UAPI_VS_DLIMIT_CMD_H
12320 +#define _UAPI_VS_DLIMIT_CMD_H
12321 +
12322 +
12323 +/*  dlimit vserver commands */
12324 +
12325 +#define VCMD_add_dlimit                VC_CMD(DLIMIT, 1, 0)
12326 +#define VCMD_rem_dlimit                VC_CMD(DLIMIT, 2, 0)
12327 +
12328 +#define VCMD_set_dlimit                VC_CMD(DLIMIT, 5, 0)
12329 +#define VCMD_get_dlimit                VC_CMD(DLIMIT, 6, 0)
12330 +
12331 +struct vcmd_ctx_dlimit_base_v0 {
12332 +       const char __user *name;
12333 +       uint32_t flags;
12334 +};
12335 +
12336 +struct vcmd_ctx_dlimit_v0 {
12337 +       const char __user *name;
12338 +       uint32_t space_used;                    /* used space in kbytes */
12339 +       uint32_t space_total;                   /* maximum space in kbytes */
12340 +       uint32_t inodes_used;                   /* used inodes */
12341 +       uint32_t inodes_total;                  /* maximum inodes */
12342 +       uint32_t reserved;                      /* reserved for root in % */
12343 +       uint32_t flags;
12344 +};
12345 +
12346 +#define CDLIM_UNSET            ((uint32_t)0UL)
12347 +#define CDLIM_INFINITY         ((uint32_t)~0UL)
12348 +#define CDLIM_KEEP             ((uint32_t)~1UL)
12349 +
12350 +#define DLIME_UNIT     0
12351 +#define DLIME_KILO     1
12352 +#define DLIME_MEGA     2
12353 +#define DLIME_GIGA     3
12354 +
12355 +#define DLIMF_SHIFT    0x10
12356 +
12357 +#define DLIMS_USED     0
12358 +#define DLIMS_TOTAL    2
12359 +
12360 +static inline
12361 +uint64_t dlimit_space_32to64(uint32_t val, uint32_t flags, int shift)
12362 +{
12363 +       int exp = (flags & DLIMF_SHIFT) ?
12364 +               (flags >> shift) & DLIME_GIGA : DLIME_KILO;
12365 +       return ((uint64_t)val) << (10 * exp);
12366 +}
12367 +
12368 +static inline
12369 +uint32_t dlimit_space_64to32(uint64_t val, uint32_t *flags, int shift)
12370 +{
12371 +       int exp = 0;
12372 +
12373 +       if (*flags & DLIMF_SHIFT) {
12374 +               while (val > (1LL << 32) && (exp < 3)) {
12375 +                       val >>= 10;
12376 +                       exp++;
12377 +               }
12378 +               *flags &= ~(DLIME_GIGA << shift);
12379 +               *flags |= exp << shift;
12380 +       } else
12381 +               val >>= 10;
12382 +       return val;
12383 +}
12384 +
12385 +#endif /* _UAPI_VS_DLIMIT_CMD_H */
12386 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/inode.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/inode.h
12387 --- linux-4.1.41/include/uapi/vserver/inode.h   1970-01-01 00:00:00.000000000 +0000
12388 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/inode.h       2016-07-05 04:41:47.000000000 +0000
12389 @@ -0,0 +1,23 @@
12390 +#ifndef _UAPI_VS_INODE_H
12391 +#define _UAPI_VS_INODE_H
12392 +
12393 +
12394 +#define IATTR_TAG      0x01000000
12395 +
12396 +#define IATTR_ADMIN    0x00000001
12397 +#define IATTR_WATCH    0x00000002
12398 +#define IATTR_HIDE     0x00000004
12399 +#define IATTR_FLAGS    0x00000007
12400 +
12401 +#define IATTR_BARRIER  0x00010000
12402 +#define IATTR_IXUNLINK 0x00020000
12403 +#define IATTR_IMMUTABLE 0x00040000
12404 +#define IATTR_COW      0x00080000
12405 +
12406 +
12407 +/* inode ioctls */
12408 +
12409 +#define FIOC_GETXFLG   _IOR('x', 5, long)
12410 +#define FIOC_SETXFLG   _IOW('x', 6, long)
12411 +
12412 +#endif /* _UAPI_VS_INODE_H */
12413 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/inode_cmd.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/inode_cmd.h
12414 --- linux-4.1.41/include/uapi/vserver/inode_cmd.h       1970-01-01 00:00:00.000000000 +0000
12415 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/inode_cmd.h   2016-07-05 04:41:47.000000000 +0000
12416 @@ -0,0 +1,26 @@
12417 +#ifndef _UAPI_VS_INODE_CMD_H
12418 +#define _UAPI_VS_INODE_CMD_H
12419 +
12420 +
12421 +/*  inode vserver commands */
12422 +
12423 +#define VCMD_get_iattr         VC_CMD(INODE, 1, 1)
12424 +#define VCMD_set_iattr         VC_CMD(INODE, 2, 1)
12425 +
12426 +#define VCMD_fget_iattr                VC_CMD(INODE, 3, 0)
12427 +#define VCMD_fset_iattr                VC_CMD(INODE, 4, 0)
12428 +
12429 +struct vcmd_ctx_iattr_v1 {
12430 +       const char __user *name;
12431 +       uint32_t tag;
12432 +       uint32_t flags;
12433 +       uint32_t mask;
12434 +};
12435 +
12436 +struct vcmd_ctx_fiattr_v0 {
12437 +       uint32_t tag;
12438 +       uint32_t flags;
12439 +       uint32_t mask;
12440 +};
12441 +
12442 +#endif /* _UAPI_VS_INODE_CMD_H */
12443 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/limit.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/limit.h
12444 --- linux-4.1.41/include/uapi/vserver/limit.h   1970-01-01 00:00:00.000000000 +0000
12445 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/limit.h       2016-07-05 04:41:47.000000000 +0000
12446 @@ -0,0 +1,14 @@
12447 +#ifndef _UAPI_VS_LIMIT_H
12448 +#define _UAPI_VS_LIMIT_H
12449 +
12450 +
12451 +#define VLIMIT_NSOCK   16
12452 +#define VLIMIT_OPENFD  17
12453 +#define VLIMIT_ANON    18
12454 +#define VLIMIT_SHMEM   19
12455 +#define VLIMIT_SEMARY  20
12456 +#define VLIMIT_NSEMS   21
12457 +#define VLIMIT_DENTRY  22
12458 +#define VLIMIT_MAPPED  23
12459 +
12460 +#endif /* _UAPI_VS_LIMIT_H */
12461 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/limit_cmd.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/limit_cmd.h
12462 --- linux-4.1.41/include/uapi/vserver/limit_cmd.h       1970-01-01 00:00:00.000000000 +0000
12463 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/limit_cmd.h   2016-07-05 04:41:47.000000000 +0000
12464 @@ -0,0 +1,40 @@
12465 +#ifndef _UAPI_VS_LIMIT_CMD_H
12466 +#define _UAPI_VS_LIMIT_CMD_H
12467 +
12468 +
12469 +/*  rlimit vserver commands */
12470 +
12471 +#define VCMD_get_rlimit                VC_CMD(RLIMIT, 1, 0)
12472 +#define VCMD_set_rlimit                VC_CMD(RLIMIT, 2, 0)
12473 +#define VCMD_get_rlimit_mask   VC_CMD(RLIMIT, 3, 0)
12474 +#define VCMD_reset_hits                VC_CMD(RLIMIT, 7, 0)
12475 +#define VCMD_reset_minmax      VC_CMD(RLIMIT, 9, 0)
12476 +
12477 +struct vcmd_ctx_rlimit_v0 {
12478 +       uint32_t id;
12479 +       uint64_t minimum;
12480 +       uint64_t softlimit;
12481 +       uint64_t maximum;
12482 +};
12483 +
12484 +struct vcmd_ctx_rlimit_mask_v0 {
12485 +       uint32_t minimum;
12486 +       uint32_t softlimit;
12487 +       uint32_t maximum;
12488 +};
12489 +
12490 +#define VCMD_rlimit_stat       VC_CMD(VSTAT, 1, 0)
12491 +
12492 +struct vcmd_rlimit_stat_v0 {
12493 +       uint32_t id;
12494 +       uint32_t hits;
12495 +       uint64_t value;
12496 +       uint64_t minimum;
12497 +       uint64_t maximum;
12498 +};
12499 +
12500 +#define CRLIM_UNSET            (0ULL)
12501 +#define CRLIM_INFINITY         (~0ULL)
12502 +#define CRLIM_KEEP             (~1ULL)
12503 +
12504 +#endif /* _UAPI_VS_LIMIT_CMD_H */
12505 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/monitor.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/monitor.h
12506 --- linux-4.1.41/include/uapi/vserver/monitor.h 1970-01-01 00:00:00.000000000 +0000
12507 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/monitor.h     2016-07-05 04:41:47.000000000 +0000
12508 @@ -0,0 +1,96 @@
12509 +#ifndef _UAPI_VS_MONITOR_H
12510 +#define _UAPI_VS_MONITOR_H
12511 +
12512 +#include <linux/types.h>
12513 +
12514 +
12515 +enum {
12516 +       VXM_UNUSED = 0,
12517 +
12518 +       VXM_SYNC = 0x10,
12519 +
12520 +       VXM_UPDATE = 0x20,
12521 +       VXM_UPDATE_1,
12522 +       VXM_UPDATE_2,
12523 +
12524 +       VXM_RQINFO_1 = 0x24,
12525 +       VXM_RQINFO_2,
12526 +
12527 +       VXM_ACTIVATE = 0x40,
12528 +       VXM_DEACTIVATE,
12529 +       VXM_IDLE,
12530 +
12531 +       VXM_HOLD = 0x44,
12532 +       VXM_UNHOLD,
12533 +
12534 +       VXM_MIGRATE = 0x48,
12535 +       VXM_RESCHED,
12536 +
12537 +       /* all other bits are flags */
12538 +       VXM_SCHED = 0x80,
12539 +};
12540 +
12541 +struct _vxm_update_1 {
12542 +       uint32_t tokens_max;
12543 +       uint32_t fill_rate;
12544 +       uint32_t interval;
12545 +};
12546 +
12547 +struct _vxm_update_2 {
12548 +       uint32_t tokens_min;
12549 +       uint32_t fill_rate;
12550 +       uint32_t interval;
12551 +};
12552 +
12553 +struct _vxm_rqinfo_1 {
12554 +       uint16_t running;
12555 +       uint16_t onhold;
12556 +       uint16_t iowait;
12557 +       uint16_t uintr;
12558 +       uint32_t idle_tokens;
12559 +};
12560 +
12561 +struct _vxm_rqinfo_2 {
12562 +       uint32_t norm_time;
12563 +       uint32_t idle_time;
12564 +       uint32_t idle_skip;
12565 +};
12566 +
12567 +struct _vxm_sched {
12568 +       uint32_t tokens;
12569 +       uint32_t norm_time;
12570 +       uint32_t idle_time;
12571 +};
12572 +
12573 +struct _vxm_task {
12574 +       uint16_t pid;
12575 +       uint16_t state;
12576 +};
12577 +
12578 +struct _vxm_event {
12579 +       uint32_t jif;
12580 +       union {
12581 +               uint32_t seq;
12582 +               uint32_t sec;
12583 +       };
12584 +       union {
12585 +               uint32_t tokens;
12586 +               uint32_t nsec;
12587 +               struct _vxm_task tsk;
12588 +       };
12589 +};
12590 +
12591 +struct _vx_mon_entry {
12592 +       uint16_t type;
12593 +       uint16_t xid;
12594 +       union {
12595 +               struct _vxm_event ev;
12596 +               struct _vxm_sched sd;
12597 +               struct _vxm_update_1 u1;
12598 +               struct _vxm_update_2 u2;
12599 +               struct _vxm_rqinfo_1 q1;
12600 +               struct _vxm_rqinfo_2 q2;
12601 +       };
12602 +};
12603 +
12604 +#endif /* _UAPI_VS_MONITOR_H */
12605 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/network.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/network.h
12606 --- linux-4.1.41/include/uapi/vserver/network.h 1970-01-01 00:00:00.000000000 +0000
12607 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/network.h     2016-07-05 04:41:47.000000000 +0000
12608 @@ -0,0 +1,76 @@
12609 +#ifndef _UAPI_VS_NETWORK_H
12610 +#define _UAPI_VS_NETWORK_H
12611 +
12612 +#include <linux/types.h>
12613 +
12614 +
12615 +#define MAX_N_CONTEXT  65535   /* Arbitrary limit */
12616 +
12617 +
12618 +/* network flags */
12619 +
12620 +#define NXF_INFO_PRIVATE       0x00000008
12621 +
12622 +#define NXF_SINGLE_IP          0x00000100
12623 +#define NXF_LBACK_REMAP                0x00000200
12624 +#define NXF_LBACK_ALLOW                0x00000400
12625 +
12626 +#define NXF_HIDE_NETIF         0x02000000
12627 +#define NXF_HIDE_LBACK         0x04000000
12628 +
12629 +#define NXF_STATE_SETUP                (1ULL << 32)
12630 +#define NXF_STATE_ADMIN                (1ULL << 34)
12631 +
12632 +#define NXF_SC_HELPER          (1ULL << 36)
12633 +#define NXF_PERSISTENT         (1ULL << 38)
12634 +
12635 +#define NXF_ONE_TIME           (0x0005ULL << 32)
12636 +
12637 +
12638 +#define        NXF_INIT_SET            (__nxf_init_set())
12639 +
12640 +static inline uint64_t __nxf_init_set(void) {
12641 +       return    NXF_STATE_ADMIN
12642 +#ifdef CONFIG_VSERVER_AUTO_LBACK
12643 +               | NXF_LBACK_REMAP
12644 +               | NXF_HIDE_LBACK
12645 +#endif
12646 +#ifdef CONFIG_VSERVER_AUTO_SINGLE
12647 +               | NXF_SINGLE_IP
12648 +#endif
12649 +               | NXF_HIDE_NETIF;
12650 +}
12651 +
12652 +
12653 +/* network caps */
12654 +
12655 +#define NXC_TUN_CREATE         0x00000001
12656 +
12657 +#define NXC_RAW_ICMP           0x00000100
12658 +
12659 +#define NXC_MULTICAST          0x00001000
12660 +
12661 +
12662 +/* address types */
12663 +
12664 +#define NXA_TYPE_IPV4          0x0001
12665 +#define NXA_TYPE_IPV6          0x0002
12666 +
12667 +#define NXA_TYPE_NONE          0x0000
12668 +#define NXA_TYPE_ANY           0x00FF
12669 +
12670 +#define NXA_TYPE_ADDR          0x0010
12671 +#define NXA_TYPE_MASK          0x0020
12672 +#define NXA_TYPE_RANGE         0x0040
12673 +
12674 +#define NXA_MASK_ALL           (NXA_TYPE_ADDR | NXA_TYPE_MASK | NXA_TYPE_RANGE)
12675 +
12676 +#define NXA_MOD_BCAST          0x0100
12677 +#define NXA_MOD_LBACK          0x0200
12678 +
12679 +#define NXA_LOOPBACK           0x1000
12680 +
12681 +#define NXA_MASK_BIND          (NXA_MASK_ALL | NXA_MOD_BCAST | NXA_MOD_LBACK)
12682 +#define NXA_MASK_SHOW          (NXA_MASK_ALL | NXA_LOOPBACK)
12683 +
12684 +#endif /* _UAPI_VS_NETWORK_H */
12685 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/network_cmd.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/network_cmd.h
12686 --- linux-4.1.41/include/uapi/vserver/network_cmd.h     1970-01-01 00:00:00.000000000 +0000
12687 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/network_cmd.h 2016-07-05 04:41:47.000000000 +0000
12688 @@ -0,0 +1,123 @@
12689 +#ifndef _UAPI_VS_NETWORK_CMD_H
12690 +#define _UAPI_VS_NETWORK_CMD_H
12691 +
12692 +
12693 +/* vinfo commands */
12694 +
12695 +#define VCMD_task_nid          VC_CMD(VINFO, 2, 0)
12696 +
12697 +
12698 +#define VCMD_nx_info           VC_CMD(VINFO, 6, 0)
12699 +
12700 +struct vcmd_nx_info_v0 {
12701 +       uint32_t nid;
12702 +       /* more to come */
12703 +};
12704 +
12705 +
12706 +#include <linux/in.h>
12707 +#include <linux/in6.h>
12708 +
12709 +#define VCMD_net_create_v0     VC_CMD(VNET, 1, 0)
12710 +#define VCMD_net_create                VC_CMD(VNET, 1, 1)
12711 +
12712 +struct  vcmd_net_create {
12713 +       uint64_t flagword;
12714 +};
12715 +
12716 +#define VCMD_net_migrate       VC_CMD(NETMIG, 1, 0)
12717 +
12718 +#define VCMD_net_add           VC_CMD(NETALT, 1, 0)
12719 +#define VCMD_net_remove                VC_CMD(NETALT, 2, 0)
12720 +
12721 +struct vcmd_net_addr_v0 {
12722 +       uint16_t type;
12723 +       uint16_t count;
12724 +       struct in_addr ip[4];
12725 +       struct in_addr mask[4];
12726 +};
12727 +
12728 +#define VCMD_net_add_ipv4_v1   VC_CMD(NETALT, 1, 1)
12729 +#define VCMD_net_rem_ipv4_v1   VC_CMD(NETALT, 2, 1)
12730 +
12731 +struct vcmd_net_addr_ipv4_v1 {
12732 +       uint16_t type;
12733 +       uint16_t flags;
12734 +       struct in_addr ip;
12735 +       struct in_addr mask;
12736 +};
12737 +
12738 +#define VCMD_net_add_ipv4      VC_CMD(NETALT, 1, 2)
12739 +#define VCMD_net_rem_ipv4      VC_CMD(NETALT, 2, 2)
12740 +
12741 +struct vcmd_net_addr_ipv4_v2 {
12742 +       uint16_t type;
12743 +       uint16_t flags;
12744 +       struct in_addr ip;
12745 +       struct in_addr ip2;
12746 +       struct in_addr mask;
12747 +};
12748 +
12749 +#define VCMD_net_add_ipv6      VC_CMD(NETALT, 3, 1)
12750 +#define VCMD_net_remove_ipv6   VC_CMD(NETALT, 4, 1)
12751 +
12752 +struct vcmd_net_addr_ipv6_v1 {
12753 +       uint16_t type;
12754 +       uint16_t flags;
12755 +       uint32_t prefix;
12756 +       struct in6_addr ip;
12757 +       struct in6_addr mask;
12758 +};
12759 +
12760 +#define VCMD_add_match_ipv4    VC_CMD(NETALT, 5, 0)
12761 +#define VCMD_get_match_ipv4    VC_CMD(NETALT, 6, 0)
12762 +
12763 +struct vcmd_match_ipv4_v0 {
12764 +       uint16_t type;
12765 +       uint16_t flags;
12766 +       uint16_t parent;
12767 +       uint16_t prefix;
12768 +       struct in_addr ip;
12769 +       struct in_addr ip2;
12770 +       struct in_addr mask;
12771 +};
12772 +
12773 +#define VCMD_add_match_ipv6    VC_CMD(NETALT, 7, 0)
12774 +#define VCMD_get_match_ipv6    VC_CMD(NETALT, 8, 0)
12775 +
12776 +struct vcmd_match_ipv6_v0 {
12777 +       uint16_t type;
12778 +       uint16_t flags;
12779 +       uint16_t parent;
12780 +       uint16_t prefix;
12781 +       struct in6_addr ip;
12782 +       struct in6_addr ip2;
12783 +       struct in6_addr mask;
12784 +};
12785 +
12786 +
12787 +
12788 +
12789 +/* flag commands */
12790 +
12791 +#define VCMD_get_nflags                VC_CMD(FLAGS, 5, 0)
12792 +#define VCMD_set_nflags                VC_CMD(FLAGS, 6, 0)
12793 +
12794 +struct vcmd_net_flags_v0 {
12795 +       uint64_t flagword;
12796 +       uint64_t mask;
12797 +};
12798 +
12799 +
12800 +
12801 +/* network caps commands */
12802 +
12803 +#define VCMD_get_ncaps         VC_CMD(FLAGS, 7, 0)
12804 +#define VCMD_set_ncaps         VC_CMD(FLAGS, 8, 0)
12805 +
12806 +struct vcmd_net_caps_v0 {
12807 +       uint64_t ncaps;
12808 +       uint64_t cmask;
12809 +};
12810 +
12811 +#endif /* _UAPI_VS_NETWORK_CMD_H */
12812 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/sched_cmd.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/sched_cmd.h
12813 --- linux-4.1.41/include/uapi/vserver/sched_cmd.h       1970-01-01 00:00:00.000000000 +0000
12814 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/sched_cmd.h   2016-07-05 04:41:47.000000000 +0000
12815 @@ -0,0 +1,13 @@
12816 +#ifndef _UAPI_VS_SCHED_CMD_H
12817 +#define _UAPI_VS_SCHED_CMD_H
12818 +
12819 +
12820 +struct vcmd_prio_bias {
12821 +       int32_t cpu_id;
12822 +       int32_t prio_bias;
12823 +};
12824 +
12825 +#define VCMD_set_prio_bias     VC_CMD(SCHED, 4, 0)
12826 +#define VCMD_get_prio_bias     VC_CMD(SCHED, 5, 0)
12827 +
12828 +#endif /* _UAPI_VS_SCHED_CMD_H */
12829 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/signal_cmd.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/signal_cmd.h
12830 --- linux-4.1.41/include/uapi/vserver/signal_cmd.h      1970-01-01 00:00:00.000000000 +0000
12831 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/signal_cmd.h  2016-07-05 04:41:47.000000000 +0000
12832 @@ -0,0 +1,31 @@
12833 +#ifndef _UAPI_VS_SIGNAL_CMD_H
12834 +#define _UAPI_VS_SIGNAL_CMD_H
12835 +
12836 +
12837 +/*  signalling vserver commands */
12838 +
12839 +#define VCMD_ctx_kill          VC_CMD(PROCTRL, 1, 0)
12840 +#define VCMD_wait_exit         VC_CMD(EVENT, 99, 0)
12841 +
12842 +struct vcmd_ctx_kill_v0 {
12843 +       int32_t pid;
12844 +       int32_t sig;
12845 +};
12846 +
12847 +struct vcmd_wait_exit_v0 {
12848 +       int32_t reboot_cmd;
12849 +       int32_t exit_code;
12850 +};
12851 +
12852 +
12853 +/*  process alteration commands */
12854 +
12855 +#define VCMD_get_pflags                VC_CMD(PROCALT, 5, 0)
12856 +#define VCMD_set_pflags                VC_CMD(PROCALT, 6, 0)
12857 +
12858 +struct vcmd_pflags_v0 {
12859 +       uint32_t flagword;
12860 +       uint32_t mask;
12861 +};
12862 +
12863 +#endif /* _UAPI_VS_SIGNAL_CMD_H */
12864 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/space_cmd.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/space_cmd.h
12865 --- linux-4.1.41/include/uapi/vserver/space_cmd.h       1970-01-01 00:00:00.000000000 +0000
12866 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/space_cmd.h   2016-07-05 04:41:47.000000000 +0000
12867 @@ -0,0 +1,28 @@
12868 +#ifndef _UAPI_VS_SPACE_CMD_H
12869 +#define _UAPI_VS_SPACE_CMD_H
12870 +
12871 +
12872 +#define VCMD_enter_space_v0    VC_CMD(PROCALT, 1, 0)
12873 +#define VCMD_enter_space_v1    VC_CMD(PROCALT, 1, 1)
12874 +#define VCMD_enter_space       VC_CMD(PROCALT, 1, 2)
12875 +
12876 +#define VCMD_set_space_v0      VC_CMD(PROCALT, 3, 0)
12877 +#define VCMD_set_space_v1      VC_CMD(PROCALT, 3, 1)
12878 +#define VCMD_set_space         VC_CMD(PROCALT, 3, 2)
12879 +
12880 +#define VCMD_get_space_mask_v0 VC_CMD(PROCALT, 4, 0)
12881 +
12882 +#define VCMD_get_space_mask    VC_CMD(VSPACE, 0, 1)
12883 +#define VCMD_get_space_default VC_CMD(VSPACE, 1, 0)
12884 +
12885 +
12886 +struct vcmd_space_mask_v1 {
12887 +       uint64_t mask;
12888 +};
12889 +
12890 +struct vcmd_space_mask_v2 {
12891 +       uint64_t mask;
12892 +       uint32_t index;
12893 +};
12894 +
12895 +#endif /* _UAPI_VS_SPACE_CMD_H */
12896 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/switch.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/switch.h
12897 --- linux-4.1.41/include/uapi/vserver/switch.h  1970-01-01 00:00:00.000000000 +0000
12898 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/switch.h      2016-07-05 04:41:47.000000000 +0000
12899 @@ -0,0 +1,90 @@
12900 +#ifndef _UAPI_VS_SWITCH_H
12901 +#define _UAPI_VS_SWITCH_H
12902 +
12903 +#include <linux/types.h>
12904 +
12905 +
12906 +#define VC_CATEGORY(c)         (((c) >> 24) & 0x3F)
12907 +#define VC_COMMAND(c)          (((c) >> 16) & 0xFF)
12908 +#define VC_VERSION(c)          ((c) & 0xFFF)
12909 +
12910 +#define VC_CMD(c, i, v)                ((((VC_CAT_ ## c) & 0x3F) << 24) \
12911 +                               | (((i) & 0xFF) << 16) | ((v) & 0xFFF))
12912 +
12913 +/*
12914 +
12915 +  Syscall Matrix V2.8
12916 +
12917 +        |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|
12918 +        |STATS  |DESTROY|ALTER  |CHANGE |LIMIT  |TEST   | |       |       |
12919 +        |INFO   |SETUP  |       |MOVE   |       |       | |       |       |
12920 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12921 +  SYSTEM |VERSION|VSETUP |VHOST  |       |       |       | |DEVICE |       |
12922 +  HOST   |     00|     01|     02|     03|     04|     05| |     06|     07|
12923 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12924 +  CPU    |       |VPROC  |PROCALT|PROCMIG|PROCTRL|       | |SCHED. |       |
12925 +  PROCESS|     08|     09|     10|     11|     12|     13| |     14|     15|
12926 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12927 +  MEMORY |       |       |       |       |MEMCTRL|       | |SWAP   |       |
12928 +        |     16|     17|     18|     19|     20|     21| |     22|     23|
12929 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12930 +  NETWORK|       |VNET   |NETALT |NETMIG |NETCTL |       | |SERIAL |       |
12931 +        |     24|     25|     26|     27|     28|     29| |     30|     31|
12932 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12933 +  DISK   |       |       |       |TAGMIG |DLIMIT |       | |INODE  |       |
12934 +  VFS    |     32|     33|     34|     35|     36|     37| |     38|     39|
12935 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12936 +  OTHER  |VSTAT  |       |       |       |       |       | |VINFO  |       |
12937 +        |     40|     41|     42|     43|     44|     45| |     46|     47|
12938 +  =======+=======+=======+=======+=======+=======+=======+ +=======+=======+
12939 +  SPECIAL|EVENT  |       |       |       |FLAGS  |       | |VSPACE |       |
12940 +        |     48|     49|     50|     51|     52|     53| |     54|     55|
12941 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12942 +  SPECIAL|DEBUG  |       |       |       |RLIMIT |SYSCALL| |       |COMPAT |
12943 +        |     56|     57|     58|     59|     60|TEST 61| |     62|     63|
12944 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12945 +
12946 +*/
12947 +
12948 +#define VC_CAT_VERSION         0
12949 +
12950 +#define VC_CAT_VSETUP          1
12951 +#define VC_CAT_VHOST           2
12952 +
12953 +#define VC_CAT_DEVICE          6
12954 +
12955 +#define VC_CAT_VPROC           9
12956 +#define VC_CAT_PROCALT         10
12957 +#define VC_CAT_PROCMIG         11
12958 +#define VC_CAT_PROCTRL         12
12959 +
12960 +#define VC_CAT_SCHED           14
12961 +#define VC_CAT_MEMCTRL         20
12962 +
12963 +#define VC_CAT_VNET            25
12964 +#define VC_CAT_NETALT          26
12965 +#define VC_CAT_NETMIG          27
12966 +#define VC_CAT_NETCTRL         28
12967 +
12968 +#define VC_CAT_TAGMIG          35
12969 +#define VC_CAT_DLIMIT          36
12970 +#define VC_CAT_INODE           38
12971 +
12972 +#define VC_CAT_VSTAT           40
12973 +#define VC_CAT_VINFO           46
12974 +#define VC_CAT_EVENT           48
12975 +
12976 +#define VC_CAT_FLAGS           52
12977 +#define VC_CAT_VSPACE          54
12978 +#define VC_CAT_DEBUG           56
12979 +#define VC_CAT_RLIMIT          60
12980 +
12981 +#define VC_CAT_SYSTEST         61
12982 +#define VC_CAT_COMPAT          63
12983 +
12984 +/*  query version */
12985 +
12986 +#define VCMD_get_version       VC_CMD(VERSION, 0, 0)
12987 +#define VCMD_get_vci           VC_CMD(VERSION, 1, 0)
12988 +
12989 +#endif /* _UAPI_VS_SWITCH_H */
12990 diff -NurpP --minimal linux-4.1.41/include/uapi/vserver/tag_cmd.h linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/tag_cmd.h
12991 --- linux-4.1.41/include/uapi/vserver/tag_cmd.h 1970-01-01 00:00:00.000000000 +0000
12992 +++ linux-4.1.41-vs2.3.8.5.3/include/uapi/vserver/tag_cmd.h     2016-07-05 04:41:47.000000000 +0000
12993 @@ -0,0 +1,14 @@
12994 +#ifndef _UAPI_VS_TAG_CMD_H
12995 +#define _UAPI_VS_TAG_CMD_H
12996 +
12997 +
12998 +/* vinfo commands */
12999 +
13000 +#define VCMD_task_tag          VC_CMD(VINFO, 3, 0)
13001 +
13002 +
13003 +/* context commands */
13004 +
13005 +#define VCMD_tag_migrate       VC_CMD(TAGMIG, 1, 0)
13006 +
13007 +#endif /* _UAPI_VS_TAG_CMD_H */
13008 diff -NurpP --minimal linux-4.1.41/init/Kconfig linux-4.1.41-vs2.3.8.5.3/init/Kconfig
13009 --- linux-4.1.41/init/Kconfig   2015-07-06 20:41:43.000000000 +0000
13010 +++ linux-4.1.41-vs2.3.8.5.3/init/Kconfig       2016-07-05 04:41:47.000000000 +0000
13011 @@ -938,6 +938,7 @@ config NUMA_BALANCING_DEFAULT_ENABLED
13012  menuconfig CGROUPS
13013         bool "Control Group support"
13014         select KERNFS
13015 +       default y
13016         help
13017           This option adds support for grouping sets of processes together, for
13018           use with process control subsystems such as Cpusets, CFS, memory
13019 diff -NurpP --minimal linux-4.1.41/init/main.c linux-4.1.41-vs2.3.8.5.3/init/main.c
13020 --- linux-4.1.41/init/main.c    2017-06-23 10:04:01.000000000 +0000
13021 +++ linux-4.1.41-vs2.3.8.5.3/init/main.c        2016-07-05 04:41:47.000000000 +0000
13022 @@ -81,6 +81,7 @@
13023  #include <linux/integrity.h>
13024  #include <linux/proc_ns.h>
13025  #include <linux/io.h>
13026 +#include <linux/vserver/percpu.h>
13027  
13028  #include <asm/io.h>
13029  #include <asm/bugs.h>
13030 diff -NurpP --minimal linux-4.1.41/ipc/mqueue.c linux-4.1.41-vs2.3.8.5.3/ipc/mqueue.c
13031 --- linux-4.1.41/ipc/mqueue.c   2017-06-23 10:04:01.000000000 +0000
13032 +++ linux-4.1.41-vs2.3.8.5.3/ipc/mqueue.c       2016-07-05 04:41:47.000000000 +0000
13033 @@ -35,6 +35,8 @@
13034  #include <linux/ipc_namespace.h>
13035  #include <linux/user_namespace.h>
13036  #include <linux/slab.h>
13037 +#include <linux/vs_context.h>
13038 +#include <linux/vs_limit.h>
13039  
13040  #include <net/sock.h>
13041  #include "util.h"
13042 @@ -76,6 +78,7 @@ struct mqueue_inode_info {
13043         struct pid *notify_owner;
13044         struct user_namespace *notify_user_ns;
13045         struct user_struct *user;       /* user who created, for accounting */
13046 +       struct vx_info *vxi;
13047         struct sock *notify_sock;
13048         struct sk_buff *notify_cookie;
13049  
13050 @@ -231,6 +234,7 @@ static struct inode *mqueue_get_inode(st
13051         if (S_ISREG(mode)) {
13052                 struct mqueue_inode_info *info;
13053                 unsigned long mq_bytes, mq_treesize;
13054 +               struct vx_info *vxi = current_vx_info();
13055  
13056                 inode->i_fop = &mqueue_file_operations;
13057                 inode->i_size = FILENT_SIZE;
13058 @@ -244,6 +248,7 @@ static struct inode *mqueue_get_inode(st
13059                 info->notify_user_ns = NULL;
13060                 info->qsize = 0;
13061                 info->user = NULL;      /* set when all is ok */
13062 +               info->vxi = NULL;
13063                 info->msg_tree = RB_ROOT;
13064                 info->node_cache = NULL;
13065                 memset(&info->attr, 0, sizeof(info->attr));
13066 @@ -277,17 +282,20 @@ static struct inode *mqueue_get_inode(st
13067  
13068                 spin_lock(&mq_lock);
13069                 if (u->mq_bytes + mq_bytes < u->mq_bytes ||
13070 -                   u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE)) {
13071 +                   u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE) ||
13072 +                   !vx_ipcmsg_avail(vxi, mq_bytes)) {
13073                         spin_unlock(&mq_lock);
13074                         /* mqueue_evict_inode() releases info->messages */
13075                         ret = -EMFILE;
13076                         goto out_inode;
13077                 }
13078                 u->mq_bytes += mq_bytes;
13079 +               vx_ipcmsg_add(vxi, u, mq_bytes);
13080                 spin_unlock(&mq_lock);
13081  
13082                 /* all is ok */
13083                 info->user = get_uid(u);
13084 +               info->vxi = get_vx_info(vxi);
13085         } else if (S_ISDIR(mode)) {
13086                 inc_nlink(inode);
13087                 /* Some things misbehave if size == 0 on a directory */
13088 @@ -399,8 +407,11 @@ static void mqueue_evict_inode(struct in
13089  
13090         user = info->user;
13091         if (user) {
13092 +               struct vx_info *vxi = info->vxi;
13093 +
13094                 spin_lock(&mq_lock);
13095                 user->mq_bytes -= mq_bytes;
13096 +               vx_ipcmsg_sub(vxi, user, mq_bytes);
13097                 /*
13098                  * get_ns_from_inode() ensures that the
13099                  * (ipc_ns = sb->s_fs_info) is either a valid ipc_ns
13100 @@ -410,6 +421,7 @@ static void mqueue_evict_inode(struct in
13101                 if (ipc_ns)
13102                         ipc_ns->mq_queues_count--;
13103                 spin_unlock(&mq_lock);
13104 +               put_vx_info(vxi);
13105                 free_uid(user);
13106         }
13107         if (ipc_ns)
13108 diff -NurpP --minimal linux-4.1.41/ipc/msg.c linux-4.1.41-vs2.3.8.5.3/ipc/msg.c
13109 --- linux-4.1.41/ipc/msg.c      2017-06-23 10:04:01.000000000 +0000
13110 +++ linux-4.1.41-vs2.3.8.5.3/ipc/msg.c  2016-10-25 21:31:19.000000000 +0000
13111 @@ -37,6 +37,7 @@
13112  #include <linux/rwsem.h>
13113  #include <linux/nsproxy.h>
13114  #include <linux/ipc_namespace.h>
13115 +#include <linux/vs_base.h>
13116  
13117  #include <asm/current.h>
13118  #include <linux/uaccess.h>
13119 @@ -129,6 +130,7 @@ static int newque(struct ipc_namespace *
13120  
13121         msq->q_perm.mode = msgflg & S_IRWXUGO;
13122         msq->q_perm.key = key;
13123 +       msq->q_perm.xid = vx_current_xid();
13124  
13125         msq->q_perm.security = NULL;
13126         retval = security_msg_queue_alloc(msq);
13127 diff -NurpP --minimal linux-4.1.41/ipc/sem.c linux-4.1.41-vs2.3.8.5.3/ipc/sem.c
13128 --- linux-4.1.41/ipc/sem.c      2017-06-23 10:04:01.000000000 +0000
13129 +++ linux-4.1.41-vs2.3.8.5.3/ipc/sem.c  2016-10-25 21:31:19.000000000 +0000
13130 @@ -85,6 +85,8 @@
13131  #include <linux/rwsem.h>
13132  #include <linux/nsproxy.h>
13133  #include <linux/ipc_namespace.h>
13134 +#include <linux/vs_base.h>
13135 +#include <linux/vs_limit.h>
13136  
13137  #include <linux/uaccess.h>
13138  #include "util.h"
13139 @@ -516,6 +518,7 @@ static int newary(struct ipc_namespace *
13140  
13141         sma->sem_perm.mode = (semflg & S_IRWXUGO);
13142         sma->sem_perm.key = key;
13143 +       sma->sem_perm.xid = vx_current_xid();
13144  
13145         sma->sem_perm.security = NULL;
13146         retval = security_sem_alloc(sma);
13147 @@ -545,6 +548,9 @@ static int newary(struct ipc_namespace *
13148                 return id;
13149         }
13150         ns->used_sems += nsems;
13151 +       /* FIXME: obsoleted? */
13152 +       vx_semary_inc(sma);
13153 +       vx_nsems_add(sma, nsems);
13154  
13155         sem_unlock(sma, -1);
13156         rcu_read_unlock();
13157 @@ -1133,6 +1139,9 @@ static void freeary(struct ipc_namespace
13158  
13159         wake_up_sem_queue_do(&tasks);
13160         ns->used_sems -= sma->sem_nsems;
13161 +       /* FIXME: obsoleted? */
13162 +       vx_nsems_sub(sma, sma->sem_nsems);
13163 +       vx_semary_dec(sma);
13164         ipc_rcu_putref(sma, sem_rcu_free);
13165  }
13166  
13167 diff -NurpP --minimal linux-4.1.41/ipc/shm.c linux-4.1.41-vs2.3.8.5.3/ipc/shm.c
13168 --- linux-4.1.41/ipc/shm.c      2017-06-23 10:04:01.000000000 +0000
13169 +++ linux-4.1.41-vs2.3.8.5.3/ipc/shm.c  2017-05-30 07:39:23.000000000 +0000
13170 @@ -42,6 +42,8 @@
13171  #include <linux/nsproxy.h>
13172  #include <linux/mount.h>
13173  #include <linux/ipc_namespace.h>
13174 +#include <linux/vs_context.h>
13175 +#include <linux/vs_limit.h>
13176  
13177  #include <linux/uaccess.h>
13178  
13179 @@ -228,10 +230,14 @@ static void shm_open(struct vm_area_stru
13180  static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
13181  {
13182         struct file *shm_file;
13183 +       struct vx_info *vxi = lookup_vx_info(shp->shm_perm.xid);
13184 +       int numpages = (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
13185  
13186         shm_file = shp->shm_file;
13187         shp->shm_file = NULL;
13188 -       ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
13189 +       vx_ipcshm_sub(vxi, shp, numpages);
13190 +       ns->shm_tot -= numpages;
13191 +
13192         shm_rmid(ns, shp);
13193         shm_unlock(shp);
13194         if (!is_file_hugepages(shm_file))
13195 @@ -240,6 +246,7 @@ static void shm_destroy(struct ipc_names
13196                 user_shm_unlock(i_size_read(file_inode(shm_file)),
13197                                 shp->mlock_user);
13198         fput(shm_file);
13199 +       put_vx_info(vxi);
13200         ipc_rcu_putref(shp, shm_rcu_free);
13201  }
13202  
13203 @@ -537,11 +544,15 @@ static int newseg(struct ipc_namespace *
13204                         ns->shm_tot + numpages > ns->shm_ctlall)
13205                 return -ENOSPC;
13206  
13207 +       if (!vx_ipcshm_avail(current_vx_info(), numpages))
13208 +               return -ENOSPC;
13209 +
13210         shp = ipc_rcu_alloc(sizeof(*shp));
13211         if (!shp)
13212                 return -ENOMEM;
13213  
13214         shp->shm_perm.key = key;
13215 +       shp->shm_perm.xid = vx_current_xid();
13216         shp->shm_perm.mode = (shmflg & S_IRWXUGO);
13217         shp->mlock_user = NULL;
13218  
13219 @@ -612,6 +623,7 @@ static int newseg(struct ipc_namespace *
13220  
13221         ipc_unlock_object(&shp->shm_perm);
13222         rcu_read_unlock();
13223 +       vx_ipcshm_add(current_vx_info(), key, numpages);
13224         return error;
13225  
13226  no_id:
13227 diff -NurpP --minimal linux-4.1.41/kernel/Makefile linux-4.1.41-vs2.3.8.5.3/kernel/Makefile
13228 --- linux-4.1.41/kernel/Makefile        2015-07-06 20:41:43.000000000 +0000
13229 +++ linux-4.1.41-vs2.3.8.5.3/kernel/Makefile    2016-07-05 04:41:47.000000000 +0000
13230 @@ -29,6 +29,7 @@ obj-y += printk/
13231  obj-y += irq/
13232  obj-y += rcu/
13233  obj-y += livepatch/
13234 +obj-y += vserver/
13235  
13236  obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o
13237  obj-$(CONFIG_FREEZER) += freezer.o
13238 diff -NurpP --minimal linux-4.1.41/kernel/auditsc.c linux-4.1.41-vs2.3.8.5.3/kernel/auditsc.c
13239 --- linux-4.1.41/kernel/auditsc.c       2017-06-23 10:04:01.000000000 +0000
13240 +++ linux-4.1.41-vs2.3.8.5.3/kernel/auditsc.c   2016-10-25 21:31:19.000000000 +0000
13241 @@ -1961,7 +1961,7 @@ static int audit_set_loginuid_perm(kuid_
13242         if (is_audit_feature_set(AUDIT_FEATURE_LOGINUID_IMMUTABLE))
13243                 return -EPERM;
13244         /* it is set, you need permission */
13245 -       if (!capable(CAP_AUDIT_CONTROL))
13246 +       if (!vx_capable(CAP_AUDIT_CONTROL, VXC_AUDIT_CONTROL))
13247                 return -EPERM;
13248         /* reject if this is not an unset and we don't allow that */
13249         if (is_audit_feature_set(AUDIT_FEATURE_ONLY_UNSET_LOGINUID) && uid_valid(loginuid))
13250 diff -NurpP --minimal linux-4.1.41/kernel/capability.c linux-4.1.41-vs2.3.8.5.3/kernel/capability.c
13251 --- linux-4.1.41/kernel/capability.c    2017-06-23 10:04:01.000000000 +0000
13252 +++ linux-4.1.41-vs2.3.8.5.3/kernel/capability.c        2017-05-30 07:39:23.000000000 +0000
13253 @@ -17,6 +17,7 @@
13254  #include <linux/syscalls.h>
13255  #include <linux/pid_namespace.h>
13256  #include <linux/user_namespace.h>
13257 +#include <linux/vs_context.h>
13258  #include <asm/uaccess.h>
13259  
13260  /*
13261 @@ -107,6 +108,7 @@ static int cap_validate_magic(cap_user_h
13262         return 0;
13263  }
13264  
13265 +
13266  /*
13267   * The only thing that can change the capabilities of the current
13268   * process is the current process. As such, we can't be in this code
13269 @@ -344,6 +346,8 @@ bool has_ns_capability_noaudit(struct ta
13270         return (ret == 0);
13271  }
13272  
13273 +#include <linux/vserver/base.h>
13274 +
13275  /**
13276   * has_capability_noaudit - Does a task have a capability (unaudited) in the
13277   * initial user ns
13278 diff -NurpP --minimal linux-4.1.41/kernel/compat.c linux-4.1.41-vs2.3.8.5.3/kernel/compat.c
13279 --- linux-4.1.41/kernel/compat.c        2015-07-06 20:41:43.000000000 +0000
13280 +++ linux-4.1.41-vs2.3.8.5.3/kernel/compat.c    2016-07-05 04:41:47.000000000 +0000
13281 @@ -27,6 +27,7 @@
13282  #include <linux/times.h>
13283  #include <linux/ptrace.h>
13284  #include <linux/gfp.h>
13285 +#include <linux/vs_time.h>
13286  
13287  #include <asm/uaccess.h>
13288  
13289 @@ -1059,7 +1060,7 @@ COMPAT_SYSCALL_DEFINE1(stime, compat_tim
13290         if (err)
13291                 return err;
13292  
13293 -       do_settimeofday(&tv);
13294 +       vx_settimeofday(&tv);
13295         return 0;
13296  }
13297  
13298 diff -NurpP --minimal linux-4.1.41/kernel/cred.c linux-4.1.41-vs2.3.8.5.3/kernel/cred.c
13299 --- linux-4.1.41/kernel/cred.c  2015-07-06 20:41:43.000000000 +0000
13300 +++ linux-4.1.41-vs2.3.8.5.3/kernel/cred.c      2016-07-05 04:41:47.000000000 +0000
13301 @@ -59,31 +59,6 @@ struct cred init_cred = {
13302         .group_info             = &init_groups,
13303  };
13304  
13305 -static inline void set_cred_subscribers(struct cred *cred, int n)
13306 -{
13307 -#ifdef CONFIG_DEBUG_CREDENTIALS
13308 -       atomic_set(&cred->subscribers, n);
13309 -#endif
13310 -}
13311 -
13312 -static inline int read_cred_subscribers(const struct cred *cred)
13313 -{
13314 -#ifdef CONFIG_DEBUG_CREDENTIALS
13315 -       return atomic_read(&cred->subscribers);
13316 -#else
13317 -       return 0;
13318 -#endif
13319 -}
13320 -
13321 -static inline void alter_cred_subscribers(const struct cred *_cred, int n)
13322 -{
13323 -#ifdef CONFIG_DEBUG_CREDENTIALS
13324 -       struct cred *cred = (struct cred *) _cred;
13325 -
13326 -       atomic_add(n, &cred->subscribers);
13327 -#endif
13328 -}
13329 -
13330  /*
13331   * The RCU callback to actually dispose of a set of credentials
13332   */
13333 @@ -235,21 +210,16 @@ error:
13334   *
13335   * Call commit_creds() or abort_creds() to clean up.
13336   */
13337 -struct cred *prepare_creds(void)
13338 +struct cred *__prepare_creds(const struct cred *old)
13339  {
13340 -       struct task_struct *task = current;
13341 -       const struct cred *old;
13342         struct cred *new;
13343  
13344 -       validate_process_creds();
13345 -
13346         new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
13347         if (!new)
13348                 return NULL;
13349  
13350         kdebug("prepare_creds() alloc %p", new);
13351  
13352 -       old = task->cred;
13353         memcpy(new, old, sizeof(struct cred));
13354  
13355         atomic_set(&new->usage, 1);
13356 @@ -278,6 +248,13 @@ error:
13357         abort_creds(new);
13358         return NULL;
13359  }
13360 +
13361 +struct cred *prepare_creds(void)
13362 +{
13363 +       validate_process_creds();
13364 +
13365 +       return __prepare_creds(current->cred);
13366 +}
13367  EXPORT_SYMBOL(prepare_creds);
13368  
13369  /*
13370 diff -NurpP --minimal linux-4.1.41/kernel/exit.c linux-4.1.41-vs2.3.8.5.3/kernel/exit.c
13371 --- linux-4.1.41/kernel/exit.c  2017-06-23 10:04:01.000000000 +0000
13372 +++ linux-4.1.41-vs2.3.8.5.3/kernel/exit.c      2016-07-05 04:41:47.000000000 +0000
13373 @@ -48,6 +48,10 @@
13374  #include <linux/fs_struct.h>
13375  #include <linux/init_task.h>
13376  #include <linux/perf_event.h>
13377 +#include <linux/vs_limit.h>
13378 +#include <linux/vs_context.h>
13379 +#include <linux/vs_network.h>
13380 +#include <linux/vs_pid.h>
13381  #include <trace/events/sched.h>
13382  #include <linux/hw_breakpoint.h>
13383  #include <linux/oom.h>
13384 @@ -456,14 +460,24 @@ static struct task_struct *find_child_re
13385  {
13386         struct pid_namespace *pid_ns = task_active_pid_ns(father);
13387         struct task_struct *reaper = pid_ns->child_reaper;
13388 +       struct vx_info *vxi = task_get_vx_info(father);
13389 +
13390 +       if (vxi) {
13391 +               BUG_ON(!vxi->vx_reaper);
13392 +               if (vxi->vx_reaper != init_pid_ns.child_reaper &&
13393 +                   vxi->vx_reaper != father) {
13394 +                       reaper = vxi->vx_reaper;
13395 +                       goto out_put;
13396 +               }
13397 +       }
13398  
13399         if (likely(reaper != father))
13400 -               return reaper;
13401 +               goto out_put;
13402  
13403         reaper = find_alive_thread(father);
13404         if (reaper) {
13405                 pid_ns->child_reaper = reaper;
13406 -               return reaper;
13407 +               goto out_put;
13408         }
13409  
13410         write_unlock_irq(&tasklist_lock);
13411 @@ -474,7 +488,10 @@ static struct task_struct *find_child_re
13412         zap_pid_ns_processes(pid_ns);
13413         write_lock_irq(&tasklist_lock);
13414  
13415 -       return father;
13416 +       reaper = father;
13417 +out_put:
13418 +       put_vx_info(vxi);
13419 +       return reaper;
13420  }
13421  
13422  /*
13423 @@ -562,9 +579,13 @@ static void forget_original_parent(struc
13424                 return;
13425  
13426         reaper = find_new_reaper(father, reaper);
13427 -       list_for_each_entry(p, &father->children, sibling) {
13428 +       for (p = list_first_entry(&father->children, struct task_struct, sibling);
13429 +            &p->sibling != &father->children; ) {
13430 +               struct task_struct *next, *this_reaper = reaper;
13431 +               if (p == reaper)
13432 +                       this_reaper = task_active_pid_ns(reaper)->child_reaper;
13433                 for_each_thread(p, t) {
13434 -                       t->real_parent = reaper;
13435 +                       t->real_parent = this_reaper;
13436                         BUG_ON((!t->ptrace) != (t->parent == father));
13437                         if (likely(!t->ptrace))
13438                                 t->parent = t->real_parent;
13439 @@ -576,10 +597,13 @@ static void forget_original_parent(struc
13440                  * If this is a threaded reparent there is no need to
13441                  * notify anyone anything has happened.
13442                  */
13443 -               if (!same_thread_group(reaper, father))
13444 +               if (!same_thread_group(this_reaper, father))
13445                         reparent_leader(father, p, dead);
13446 +               next = list_next_entry(p, sibling);
13447 +               list_add(&p->sibling, &this_reaper->children);
13448 +               p = next;
13449         }
13450 -       list_splice_tail_init(&father->children, &reaper->children);
13451 +       INIT_LIST_HEAD(&father->children);
13452  }
13453  
13454  /*
13455 @@ -761,6 +785,9 @@ void do_exit(long code)
13456          */
13457         flush_ptrace_hw_breakpoint(tsk);
13458  
13459 +       /* needs to stay before exit_notify() */
13460 +       exit_vx_info_early(tsk, code);
13461 +
13462         TASKS_RCU(tasks_rcu_i = __srcu_read_lock(&tasks_rcu_exit_srcu));
13463         exit_notify(tsk, group_dead);
13464         proc_exit_connector(tsk);
13465 @@ -818,10 +845,15 @@ void do_exit(long code)
13466         smp_mb();
13467         raw_spin_unlock_wait(&tsk->pi_lock);
13468  
13469 +       /* needs to stay after exit_notify() */
13470 +       exit_vx_info(tsk, code);
13471 +       exit_nx_info(tsk);
13472 +
13473         /* causes final put_task_struct in finish_task_switch(). */
13474         tsk->state = TASK_DEAD;
13475         tsk->flags |= PF_NOFREEZE;      /* tell freezer to ignore us */
13476         schedule();
13477 +       printk("bad task: %p [%lx]\n", current, current->state);
13478         BUG();
13479         /* Avoid "noreturn function does return".  */
13480         for (;;)
13481 diff -NurpP --minimal linux-4.1.41/kernel/fork.c linux-4.1.41-vs2.3.8.5.3/kernel/fork.c
13482 --- linux-4.1.41/kernel/fork.c  2017-06-23 10:04:01.000000000 +0000
13483 +++ linux-4.1.41-vs2.3.8.5.3/kernel/fork.c      2016-07-05 04:41:47.000000000 +0000
13484 @@ -75,6 +75,9 @@
13485  #include <linux/aio.h>
13486  #include <linux/compiler.h>
13487  #include <linux/sysctl.h>
13488 +#include <linux/vs_context.h>
13489 +#include <linux/vs_network.h>
13490 +#include <linux/vs_limit.h>
13491  
13492  #include <asm/pgtable.h>
13493  #include <asm/pgalloc.h>
13494 @@ -225,6 +228,8 @@ void free_task(struct task_struct *tsk)
13495         arch_release_thread_info(tsk->stack);
13496         free_thread_info(tsk->stack);
13497         rt_mutex_debug_task_free(tsk);
13498 +       clr_vx_info(&tsk->vx_info);
13499 +       clr_nx_info(&tsk->nx_info);
13500         ftrace_graph_exit_task(tsk);
13501         put_seccomp_filter(tsk);
13502         arch_release_task_struct(tsk);
13503 @@ -1245,6 +1250,8 @@ static struct task_struct *copy_process(
13504  {
13505         int retval;
13506         struct task_struct *p;
13507 +       struct vx_info *vxi;
13508 +       struct nx_info *nxi;
13509  
13510         if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
13511                 return ERR_PTR(-EINVAL);
13512 @@ -1306,7 +1313,12 @@ static struct task_struct *copy_process(
13513         DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
13514         DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
13515  #endif
13516 +       init_vx_info(&p->vx_info, current_vx_info());
13517 +       init_nx_info(&p->nx_info, current_nx_info());
13518 +
13519         retval = -EAGAIN;
13520 +       if (!vx_nproc_avail(1))
13521 +               goto bad_fork_free;
13522         if (atomic_read(&p->real_cred->user->processes) >=
13523                         task_rlimit(p, RLIMIT_NPROC)) {
13524                 if (p->real_cred->user != INIT_USER &&
13525 @@ -1590,6 +1602,18 @@ static struct task_struct *copy_process(
13526         total_forks++;
13527         spin_unlock(&current->sighand->siglock);
13528         syscall_tracepoint_update(p);
13529 +
13530 +       /* p is copy of current */
13531 +       vxi = p->vx_info;
13532 +       if (vxi) {
13533 +               claim_vx_info(vxi, p);
13534 +               atomic_inc(&vxi->cvirt.nr_threads);
13535 +               atomic_inc(&vxi->cvirt.total_forks);
13536 +               vx_nproc_inc(p);
13537 +       }
13538 +       nxi = p->nx_info;
13539 +       if (nxi)
13540 +               claim_nx_info(nxi, p);
13541         write_unlock_irq(&tasklist_lock);
13542  
13543         proc_fork_connector(p);
13544 diff -NurpP --minimal linux-4.1.41/kernel/kthread.c linux-4.1.41-vs2.3.8.5.3/kernel/kthread.c
13545 --- linux-4.1.41/kernel/kthread.c       2015-04-12 22:12:50.000000000 +0000
13546 +++ linux-4.1.41-vs2.3.8.5.3/kernel/kthread.c   2016-07-05 04:41:47.000000000 +0000
13547 @@ -18,6 +18,7 @@
13548  #include <linux/freezer.h>
13549  #include <linux/ptrace.h>
13550  #include <linux/uaccess.h>
13551 +#include <linux/vs_pid.h>
13552  #include <trace/events/sched.h>
13553  
13554  static DEFINE_SPINLOCK(kthread_create_lock);
13555 diff -NurpP --minimal linux-4.1.41/kernel/nsproxy.c linux-4.1.41-vs2.3.8.5.3/kernel/nsproxy.c
13556 --- linux-4.1.41/kernel/nsproxy.c       2015-04-12 22:12:50.000000000 +0000
13557 +++ linux-4.1.41-vs2.3.8.5.3/kernel/nsproxy.c   2016-07-05 04:41:47.000000000 +0000
13558 @@ -20,11 +20,14 @@
13559  #include <linux/mnt_namespace.h>
13560  #include <linux/utsname.h>
13561  #include <linux/pid_namespace.h>
13562 +#include <linux/vserver/global.h>
13563 +#include <linux/vserver/debug.h>
13564  #include <net/net_namespace.h>
13565  #include <linux/ipc_namespace.h>
13566  #include <linux/proc_ns.h>
13567  #include <linux/file.h>
13568  #include <linux/syscalls.h>
13569 +#include "../fs/mount.h"
13570  
13571  static struct kmem_cache *nsproxy_cachep;
13572  
13573 @@ -46,8 +49,11 @@ static inline struct nsproxy *create_nsp
13574         struct nsproxy *nsproxy;
13575  
13576         nsproxy = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL);
13577 -       if (nsproxy)
13578 +       if (nsproxy) {
13579                 atomic_set(&nsproxy->count, 1);
13580 +               atomic_inc(&vs_global_nsproxy);
13581 +       }
13582 +       vxdprintk(VXD_CBIT(space, 2), "create_nsproxy = %p[1]", nsproxy);
13583         return nsproxy;
13584  }
13585  
13586 @@ -56,9 +62,12 @@ static inline struct nsproxy *create_nsp
13587   * Return the newly created nsproxy.  Do not attach this to the task,
13588   * leave it to the caller to do proper locking and attach it to task.
13589   */
13590 -static struct nsproxy *create_new_namespaces(unsigned long flags,
13591 -       struct task_struct *tsk, struct user_namespace *user_ns,
13592 -       struct fs_struct *new_fs)
13593 +static struct nsproxy *unshare_namespaces(
13594 +       unsigned long flags,
13595 +       struct nsproxy *orig,
13596 +       struct fs_struct *new_fs,
13597 +       struct user_namespace *new_user,
13598 +       struct pid_namespace *new_pid)
13599  {
13600         struct nsproxy *new_nsp;
13601         int err;
13602 @@ -67,32 +76,31 @@ static struct nsproxy *create_new_namesp
13603         if (!new_nsp)
13604                 return ERR_PTR(-ENOMEM);
13605  
13606 -       new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, user_ns, new_fs);
13607 +       new_nsp->mnt_ns = copy_mnt_ns(flags, orig->mnt_ns, new_user, new_fs);
13608         if (IS_ERR(new_nsp->mnt_ns)) {
13609                 err = PTR_ERR(new_nsp->mnt_ns);
13610                 goto out_ns;
13611         }
13612  
13613 -       new_nsp->uts_ns = copy_utsname(flags, user_ns, tsk->nsproxy->uts_ns);
13614 +       new_nsp->uts_ns = copy_utsname(flags, new_user, orig->uts_ns);
13615         if (IS_ERR(new_nsp->uts_ns)) {
13616                 err = PTR_ERR(new_nsp->uts_ns);
13617                 goto out_uts;
13618         }
13619  
13620 -       new_nsp->ipc_ns = copy_ipcs(flags, user_ns, tsk->nsproxy->ipc_ns);
13621 +       new_nsp->ipc_ns = copy_ipcs(flags, new_user, orig->ipc_ns);
13622         if (IS_ERR(new_nsp->ipc_ns)) {
13623                 err = PTR_ERR(new_nsp->ipc_ns);
13624                 goto out_ipc;
13625         }
13626  
13627 -       new_nsp->pid_ns_for_children =
13628 -               copy_pid_ns(flags, user_ns, tsk->nsproxy->pid_ns_for_children);
13629 +       new_nsp->pid_ns_for_children = copy_pid_ns(flags, new_user, new_pid);
13630         if (IS_ERR(new_nsp->pid_ns_for_children)) {
13631                 err = PTR_ERR(new_nsp->pid_ns_for_children);
13632                 goto out_pid;
13633         }
13634  
13635 -       new_nsp->net_ns = copy_net_ns(flags, user_ns, tsk->nsproxy->net_ns);
13636 +       new_nsp->net_ns = copy_net_ns(flags, new_user, orig->net_ns);
13637         if (IS_ERR(new_nsp->net_ns)) {
13638                 err = PTR_ERR(new_nsp->net_ns);
13639                 goto out_net;
13640 @@ -117,6 +125,41 @@ out_ns:
13641         return ERR_PTR(err);
13642  }
13643  
13644 +static struct nsproxy *create_new_namespaces(unsigned long flags,
13645 +       struct task_struct *tsk, struct user_namespace *user_ns,
13646 +       struct fs_struct *new_fs)
13647 +
13648 +{
13649 +       return unshare_namespaces(flags, tsk->nsproxy,
13650 +               new_fs, user_ns, task_active_pid_ns(tsk));
13651 +}
13652 +
13653 +/*
13654 + * copies the nsproxy, setting refcount to 1, and grabbing a
13655 + * reference to all contained namespaces.
13656 + */
13657 +struct nsproxy *copy_nsproxy(struct nsproxy *orig)
13658 +{
13659 +       struct nsproxy *ns = create_nsproxy();
13660 +
13661 +       if (ns) {
13662 +               memcpy(ns, orig, sizeof(struct nsproxy));
13663 +               atomic_set(&ns->count, 1);
13664 +
13665 +               if (ns->mnt_ns)
13666 +                       get_mnt_ns(ns->mnt_ns);
13667 +               if (ns->uts_ns)
13668 +                       get_uts_ns(ns->uts_ns);
13669 +               if (ns->ipc_ns)
13670 +                       get_ipc_ns(ns->ipc_ns);
13671 +               if (ns->pid_ns_for_children)
13672 +                       get_pid_ns(ns->pid_ns_for_children);
13673 +               if (ns->net_ns)
13674 +                       get_net(ns->net_ns);
13675 +       }
13676 +       return ns;
13677 +}
13678 +
13679  /*
13680   * called from clone.  This now handles copy for nsproxy and all
13681   * namespaces therein.
13682 @@ -125,7 +168,10 @@ int copy_namespaces(unsigned long flags,
13683  {
13684         struct nsproxy *old_ns = tsk->nsproxy;
13685         struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns);
13686 -       struct nsproxy *new_ns;
13687 +       struct nsproxy *new_ns = NULL;
13688 +
13689 +       vxdprintk(VXD_CBIT(space, 7), "copy_namespaces(0x%08lx,%p[%p])",
13690 +               flags, tsk, old_ns);
13691  
13692         if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
13693                               CLONE_NEWPID | CLONE_NEWNET)))) {
13694 @@ -133,7 +179,7 @@ int copy_namespaces(unsigned long flags,
13695                 return 0;
13696         }
13697  
13698 -       if (!ns_capable(user_ns, CAP_SYS_ADMIN))
13699 +       if (!vx_ns_can_unshare(user_ns, CAP_SYS_ADMIN, flags))
13700                 return -EPERM;
13701  
13702         /*
13703 @@ -152,6 +198,9 @@ int copy_namespaces(unsigned long flags,
13704                 return  PTR_ERR(new_ns);
13705  
13706         tsk->nsproxy = new_ns;
13707 +       vxdprintk(VXD_CBIT(space, 3),
13708 +               "copy_namespaces(0x%08lx,%p[%p]) = [%p]",
13709 +               flags, tsk, old_ns, new_ns);
13710         return 0;
13711  }
13712  
13713 @@ -165,7 +214,9 @@ void free_nsproxy(struct nsproxy *ns)
13714                 put_ipc_ns(ns->ipc_ns);
13715         if (ns->pid_ns_for_children)
13716                 put_pid_ns(ns->pid_ns_for_children);
13717 -       put_net(ns->net_ns);
13718 +       if (ns->net_ns)
13719 +               put_net(ns->net_ns);
13720 +       atomic_dec(&vs_global_nsproxy);
13721         kmem_cache_free(nsproxy_cachep, ns);
13722  }
13723  
13724 @@ -179,12 +230,16 @@ int unshare_nsproxy_namespaces(unsigned
13725         struct user_namespace *user_ns;
13726         int err = 0;
13727  
13728 +       vxdprintk(VXD_CBIT(space, 4),
13729 +               "unshare_nsproxy_namespaces(0x%08lx,[%p])",
13730 +               unshare_flags, current->nsproxy);
13731 +
13732         if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
13733                                CLONE_NEWNET | CLONE_NEWPID)))
13734                 return 0;
13735  
13736         user_ns = new_cred ? new_cred->user_ns : current_user_ns();
13737 -       if (!ns_capable(user_ns, CAP_SYS_ADMIN))
13738 +       if (!vx_ns_can_unshare(user_ns, CAP_SYS_ADMIN, unshare_flags))
13739                 return -EPERM;
13740  
13741         *new_nsp = create_new_namespaces(unshare_flags, current, user_ns,
13742 diff -NurpP --minimal linux-4.1.41/kernel/pid.c linux-4.1.41-vs2.3.8.5.3/kernel/pid.c
13743 --- linux-4.1.41/kernel/pid.c   2015-07-06 20:41:43.000000000 +0000
13744 +++ linux-4.1.41-vs2.3.8.5.3/kernel/pid.c       2016-07-05 04:41:47.000000000 +0000
13745 @@ -38,6 +38,7 @@
13746  #include <linux/syscalls.h>
13747  #include <linux/proc_ns.h>
13748  #include <linux/proc_fs.h>
13749 +#include <linux/vs_pid.h>
13750  
13751  #define pid_hashfn(nr, ns)     \
13752         hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
13753 @@ -379,7 +380,7 @@ EXPORT_SYMBOL_GPL(find_pid_ns);
13754  
13755  struct pid *find_vpid(int nr)
13756  {
13757 -       return find_pid_ns(nr, task_active_pid_ns(current));
13758 +       return find_pid_ns(vx_rmap_pid(nr), task_active_pid_ns(current));
13759  }
13760  EXPORT_SYMBOL_GPL(find_vpid);
13761  
13762 @@ -435,6 +436,9 @@ void transfer_pid(struct task_struct *ol
13763  struct task_struct *pid_task(struct pid *pid, enum pid_type type)
13764  {
13765         struct task_struct *result = NULL;
13766 +
13767 +       if (type == PIDTYPE_REALPID)
13768 +               type = PIDTYPE_PID;
13769         if (pid) {
13770                 struct hlist_node *first;
13771                 first = rcu_dereference_check(hlist_first_rcu(&pid->tasks[type]),
13772 @@ -454,7 +458,7 @@ struct task_struct *find_task_by_pid_ns(
13773         rcu_lockdep_assert(rcu_read_lock_held(),
13774                            "find_task_by_pid_ns() needs rcu_read_lock()"
13775                            " protection");
13776 -       return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
13777 +       return pid_task(find_pid_ns(vx_rmap_pid(nr), ns), PIDTYPE_PID);
13778  }
13779  
13780  struct task_struct *find_task_by_vpid(pid_t vnr)
13781 @@ -498,7 +502,7 @@ struct pid *find_get_pid(pid_t nr)
13782  }
13783  EXPORT_SYMBOL_GPL(find_get_pid);
13784  
13785 -pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
13786 +pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns)
13787  {
13788         struct upid *upid;
13789         pid_t nr = 0;
13790 @@ -512,6 +516,11 @@ pid_t pid_nr_ns(struct pid *pid, struct
13791  }
13792  EXPORT_SYMBOL_GPL(pid_nr_ns);
13793  
13794 +pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
13795 +{
13796 +       return vx_map_pid(pid_unmapped_nr_ns(pid, ns));
13797 +}
13798 +
13799  pid_t pid_vnr(struct pid *pid)
13800  {
13801         return pid_nr_ns(pid, task_active_pid_ns(current));
13802 diff -NurpP --minimal linux-4.1.41/kernel/pid_namespace.c linux-4.1.41-vs2.3.8.5.3/kernel/pid_namespace.c
13803 --- linux-4.1.41/kernel/pid_namespace.c 2017-06-23 10:04:01.000000000 +0000
13804 +++ linux-4.1.41-vs2.3.8.5.3/kernel/pid_namespace.c     2017-06-23 10:07:02.000000000 +0000
13805 @@ -18,6 +18,7 @@
13806  #include <linux/proc_ns.h>
13807  #include <linux/reboot.h>
13808  #include <linux/export.h>
13809 +#include <linux/vserver/global.h>
13810  
13811  struct pid_cache {
13812         int nr_ids;
13813 @@ -111,6 +112,7 @@ static struct pid_namespace *create_pid_
13814         ns->ns.ops = &pidns_operations;
13815  
13816         kref_init(&ns->kref);
13817 +       atomic_inc(&vs_global_pid_ns);
13818         ns->level = level;
13819         ns->parent = get_pid_ns(parent_pid_ns);
13820         ns->user_ns = get_user_ns(user_ns);
13821 @@ -128,6 +130,7 @@ static struct pid_namespace *create_pid_
13822  out_free_map:
13823         kfree(ns->pidmap[0].page);
13824  out_free:
13825 +       atomic_dec(&vs_global_pid_ns);
13826         kmem_cache_free(pid_ns_cachep, ns);
13827  out:
13828         return ERR_PTR(err);
13829 diff -NurpP --minimal linux-4.1.41/kernel/printk/printk.c linux-4.1.41-vs2.3.8.5.3/kernel/printk/printk.c
13830 --- linux-4.1.41/kernel/printk/printk.c 2017-06-23 10:04:01.000000000 +0000
13831 +++ linux-4.1.41-vs2.3.8.5.3/kernel/printk/printk.c     2017-05-30 07:39:23.000000000 +0000
13832 @@ -46,6 +46,7 @@
13833  #include <linux/utsname.h>
13834  #include <linux/ctype.h>
13835  #include <linux/uio.h>
13836 +#include <linux/vs_cvirt.h>
13837  
13838  #include <asm/uaccess.h>
13839  
13840 @@ -487,7 +488,7 @@ int check_syslog_permissions(int type, b
13841                 goto ok;
13842  
13843         if (syslog_action_restricted(type)) {
13844 -               if (capable(CAP_SYSLOG))
13845 +               if (vx_capable(CAP_SYSLOG, VXC_SYSLOG))
13846                         goto ok;
13847                 /*
13848                  * For historical reasons, accept CAP_SYS_ADMIN too, with
13849 @@ -1264,12 +1265,9 @@ int do_syslog(int type, char __user *buf
13850         if (error)
13851                 goto out;
13852  
13853 -       switch (type) {
13854 -       case SYSLOG_ACTION_CLOSE:       /* Close log */
13855 -               break;
13856 -       case SYSLOG_ACTION_OPEN:        /* Open log */
13857 -               break;
13858 -       case SYSLOG_ACTION_READ:        /* Read from log */
13859 +       if ((type == SYSLOG_ACTION_READ) ||
13860 +           (type == SYSLOG_ACTION_READ_ALL) ||
13861 +           (type == SYSLOG_ACTION_READ_CLEAR)) {
13862                 error = -EINVAL;
13863                 if (!buf || len < 0)
13864                         goto out;
13865 @@ -1280,6 +1278,16 @@ int do_syslog(int type, char __user *buf
13866                         error = -EFAULT;
13867                         goto out;
13868                 }
13869 +       }
13870 +       if (!vx_check(0, VS_ADMIN|VS_WATCH))
13871 +               return vx_do_syslog(type, buf, len);
13872 +
13873 +       switch (type) {
13874 +       case SYSLOG_ACTION_CLOSE:       /* Close log */
13875 +               break;
13876 +       case SYSLOG_ACTION_OPEN:        /* Open log */
13877 +               break;
13878 +       case SYSLOG_ACTION_READ:        /* Read from log */
13879                 error = wait_event_interruptible(log_wait,
13880                                                  syslog_seq != log_next_seq);
13881                 if (error)
13882 @@ -1292,16 +1300,6 @@ int do_syslog(int type, char __user *buf
13883                 /* FALL THRU */
13884         /* Read last kernel messages */
13885         case SYSLOG_ACTION_READ_ALL:
13886 -               error = -EINVAL;
13887 -               if (!buf || len < 0)
13888 -                       goto out;
13889 -               error = 0;
13890 -               if (!len)
13891 -                       goto out;
13892 -               if (!access_ok(VERIFY_WRITE, buf, len)) {
13893 -                       error = -EFAULT;
13894 -                       goto out;
13895 -               }
13896                 error = syslog_print_all(buf, len, clear);
13897                 break;
13898         /* Clear ring buffer */
13899 diff -NurpP --minimal linux-4.1.41/kernel/ptrace.c linux-4.1.41-vs2.3.8.5.3/kernel/ptrace.c
13900 --- linux-4.1.41/kernel/ptrace.c        2017-06-23 10:04:01.000000000 +0000
13901 +++ linux-4.1.41-vs2.3.8.5.3/kernel/ptrace.c    2017-05-30 07:39:23.000000000 +0000
13902 @@ -24,6 +24,7 @@
13903  #include <linux/syscalls.h>
13904  #include <linux/uaccess.h>
13905  #include <linux/regset.h>
13906 +#include <linux/vs_context.h>
13907  #include <linux/hw_breakpoint.h>
13908  #include <linux/cn_proc.h>
13909  #include <linux/compat.h>
13910 @@ -317,6 +318,11 @@ ok:
13911         }
13912         rcu_read_unlock();
13913  
13914 +       if (!vx_check(task->xid, VS_ADMIN_P|VS_WATCH_P|VS_IDENT))
13915 +               return -EPERM;
13916 +       if (!vx_check(task->xid, VS_IDENT) &&
13917 +               !task_vx_flags(task, VXF_STATE_ADMIN, 0))
13918 +               return -EACCES;
13919         return security_ptrace_access_check(task, mode);
13920  }
13921  
13922 diff -NurpP --minimal linux-4.1.41/kernel/reboot.c linux-4.1.41-vs2.3.8.5.3/kernel/reboot.c
13923 --- linux-4.1.41/kernel/reboot.c        2015-07-06 20:41:43.000000000 +0000
13924 +++ linux-4.1.41-vs2.3.8.5.3/kernel/reboot.c    2016-07-05 04:41:47.000000000 +0000
13925 @@ -16,6 +16,7 @@
13926  #include <linux/syscalls.h>
13927  #include <linux/syscore_ops.h>
13928  #include <linux/uaccess.h>
13929 +#include <linux/vs_pid.h>
13930  
13931  /*
13932   * this indicates whether you can reboot with ctrl-alt-del: the default is yes
13933 @@ -269,6 +270,8 @@ EXPORT_SYMBOL_GPL(kernel_power_off);
13934  
13935  static DEFINE_MUTEX(reboot_mutex);
13936  
13937 +long vs_reboot(unsigned int, void __user *);
13938 +
13939  /*
13940   * Reboot system call: for obvious reasons only root may call it,
13941   * and even root needs to set up some magic numbers in the registers
13942 @@ -311,6 +314,9 @@ SYSCALL_DEFINE4(reboot, int, magic1, int
13943         if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
13944                 cmd = LINUX_REBOOT_CMD_HALT;
13945  
13946 +       if (!vx_check(0, VS_ADMIN|VS_WATCH))
13947 +               return vs_reboot(cmd, arg);
13948 +
13949         mutex_lock(&reboot_mutex);
13950         switch (cmd) {
13951         case LINUX_REBOOT_CMD_RESTART:
13952 diff -NurpP --minimal linux-4.1.41/kernel/sched/core.c linux-4.1.41-vs2.3.8.5.3/kernel/sched/core.c
13953 --- linux-4.1.41/kernel/sched/core.c    2017-06-23 10:04:01.000000000 +0000
13954 +++ linux-4.1.41-vs2.3.8.5.3/kernel/sched/core.c        2016-10-25 21:31:19.000000000 +0000
13955 @@ -74,6 +74,8 @@
13956  #include <linux/binfmts.h>
13957  #include <linux/context_tracking.h>
13958  #include <linux/compiler.h>
13959 +#include <linux/vs_sched.h>
13960 +#include <linux/vs_cvirt.h>
13961  
13962  #include <asm/switch_to.h>
13963  #include <asm/tlb.h>
13964 @@ -3185,7 +3187,7 @@ SYSCALL_DEFINE1(nice, int, increment)
13965  
13966         nice = clamp_val(nice, MIN_NICE, MAX_NICE);
13967         if (increment < 0 && !can_nice(current, nice))
13968 -               return -EPERM;
13969 +               return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
13970  
13971         retval = security_task_setnice(current, nice);
13972         if (retval)
13973 diff -NurpP --minimal linux-4.1.41/kernel/sched/cputime.c linux-4.1.41-vs2.3.8.5.3/kernel/sched/cputime.c
13974 --- linux-4.1.41/kernel/sched/cputime.c 2017-06-23 10:04:01.000000000 +0000
13975 +++ linux-4.1.41-vs2.3.8.5.3/kernel/sched/cputime.c     2016-07-05 04:41:47.000000000 +0000
13976 @@ -4,6 +4,7 @@
13977  #include <linux/kernel_stat.h>
13978  #include <linux/static_key.h>
13979  #include <linux/context_tracking.h>
13980 +#include <linux/vs_sched.h>
13981  #include "sched.h"
13982  
13983  
13984 @@ -135,14 +136,17 @@ static inline void task_group_account_fi
13985  void account_user_time(struct task_struct *p, cputime_t cputime,
13986                        cputime_t cputime_scaled)
13987  {
13988 +       struct vx_info *vxi = p->vx_info;  /* p is _always_ current */
13989 +       int nice = (task_nice(p) > 0);
13990         int index;
13991  
13992         /* Add user time to process. */
13993         p->utime += cputime;
13994         p->utimescaled += cputime_scaled;
13995 +       vx_account_user(vxi, cputime, nice);
13996         account_group_user_time(p, cputime);
13997  
13998 -       index = (task_nice(p) > 0) ? CPUTIME_NICE : CPUTIME_USER;
13999 +       index = (nice) ? CPUTIME_NICE : CPUTIME_USER;
14000  
14001         /* Add user time to cpustat. */
14002         task_group_account_field(p, index, (__force u64) cputime);
14003 @@ -189,9 +193,12 @@ static inline
14004  void __account_system_time(struct task_struct *p, cputime_t cputime,
14005                         cputime_t cputime_scaled, int index)
14006  {
14007 +       struct vx_info *vxi = p->vx_info;  /* p is _always_ current */
14008 +
14009         /* Add system time to process. */
14010         p->stime += cputime;
14011         p->stimescaled += cputime_scaled;
14012 +       vx_account_system(vxi, cputime, 0 /* do we have idle time? */);
14013         account_group_system_time(p, cputime);
14014  
14015         /* Add system time to cpustat. */
14016 diff -NurpP --minimal linux-4.1.41/kernel/sched/fair.c linux-4.1.41-vs2.3.8.5.3/kernel/sched/fair.c
14017 --- linux-4.1.41/kernel/sched/fair.c    2017-06-23 10:04:01.000000000 +0000
14018 +++ linux-4.1.41-vs2.3.8.5.3/kernel/sched/fair.c        2017-06-23 10:07:02.000000000 +0000
14019 @@ -30,6 +30,7 @@
14020  #include <linux/mempolicy.h>
14021  #include <linux/migrate.h>
14022  #include <linux/task_work.h>
14023 +#include <linux/vs_cvirt.h>
14024  
14025  #include <trace/events/sched.h>
14026  
14027 @@ -3090,6 +3091,8 @@ enqueue_entity(struct cfs_rq *cfs_rq, st
14028                 __enqueue_entity(cfs_rq, se);
14029         se->on_rq = 1;
14030  
14031 +       if (entity_is_task(se))
14032 +               vx_activate_task(task_of(se));
14033         if (cfs_rq->nr_running == 1) {
14034                 list_add_leaf_cfs_rq(cfs_rq);
14035                 check_enqueue_throttle(cfs_rq);
14036 @@ -3171,6 +3174,8 @@ dequeue_entity(struct cfs_rq *cfs_rq, st
14037         if (se != cfs_rq->curr)
14038                 __dequeue_entity(cfs_rq, se);
14039         se->on_rq = 0;
14040 +       if (entity_is_task(se))
14041 +               vx_deactivate_task(task_of(se));
14042         account_entity_dequeue(cfs_rq, se);
14043  
14044         /*
14045 diff -NurpP --minimal linux-4.1.41/kernel/sched/proc.c linux-4.1.41-vs2.3.8.5.3/kernel/sched/proc.c
14046 --- linux-4.1.41/kernel/sched/proc.c    2017-06-23 10:04:01.000000000 +0000
14047 +++ linux-4.1.41-vs2.3.8.5.3/kernel/sched/proc.c        2016-07-05 04:41:47.000000000 +0000
14048 @@ -71,9 +71,17 @@ EXPORT_SYMBOL(avenrun); /* should be rem
14049   */
14050  void get_avenrun(unsigned long *loads, unsigned long offset, int shift)
14051  {
14052 -       loads[0] = (avenrun[0] + offset) << shift;
14053 -       loads[1] = (avenrun[1] + offset) << shift;
14054 -       loads[2] = (avenrun[2] + offset) << shift;
14055 +       if (vx_flags(VXF_VIRT_LOAD, 0)) {
14056 +               struct vx_info *vxi = current_vx_info();
14057 +
14058 +               loads[0] = (vxi->cvirt.load[0] + offset) << shift;
14059 +               loads[1] = (vxi->cvirt.load[1] + offset) << shift;
14060 +               loads[2] = (vxi->cvirt.load[2] + offset) << shift;
14061 +       } else {
14062 +               loads[0] = (avenrun[0] + offset) << shift;
14063 +               loads[1] = (avenrun[1] + offset) << shift;
14064 +               loads[2] = (avenrun[2] + offset) << shift;
14065 +       }
14066  }
14067  
14068  long calc_load_fold_active(struct rq *this_rq)
14069 diff -NurpP --minimal linux-4.1.41/kernel/signal.c linux-4.1.41-vs2.3.8.5.3/kernel/signal.c
14070 --- linux-4.1.41/kernel/signal.c        2017-06-23 10:04:01.000000000 +0000
14071 +++ linux-4.1.41-vs2.3.8.5.3/kernel/signal.c    2016-07-05 04:41:47.000000000 +0000
14072 @@ -34,6 +34,8 @@
14073  #include <linux/compat.h>
14074  #include <linux/cn_proc.h>
14075  #include <linux/compiler.h>
14076 +#include <linux/vs_context.h>
14077 +#include <linux/vs_pid.h>
14078  
14079  #define CREATE_TRACE_POINTS
14080  #include <trace/events/signal.h>
14081 @@ -767,9 +769,18 @@ static int check_kill_permission(int sig
14082         struct pid *sid;
14083         int error;
14084  
14085 +       vxdprintk(VXD_CBIT(misc, 7),
14086 +               "check_kill_permission(%d,%p,%p[#%u,%u])",
14087 +               sig, info, t, vx_task_xid(t), t->pid);
14088 +
14089         if (!valid_signal(sig))
14090                 return -EINVAL;
14091  
14092 +/*     FIXME: needed? if so, why?
14093 +       if ((info != SEND_SIG_NOINFO) &&
14094 +               (is_si_special(info) || !si_fromuser(info)))
14095 +               goto skip;      */
14096 +
14097         if (!si_fromuser(info))
14098                 return 0;
14099  
14100 @@ -793,6 +804,20 @@ static int check_kill_permission(int sig
14101                 }
14102         }
14103  
14104 +       error = -EPERM;
14105 +       if (t->pid == 1 && current->xid)
14106 +               return error;
14107 +
14108 +       error = -ESRCH;
14109 +       /* FIXME: we shouldn't return ESRCH ever, to avoid
14110 +                 loops, maybe ENOENT or EACCES? */
14111 +       if (!vx_check(vx_task_xid(t), VS_WATCH_P | VS_IDENT)) {
14112 +               vxdprintk(current->xid || VXD_CBIT(misc, 7),
14113 +                       "signal %d[%p] xid mismatch %p[#%u,%u] xid=#%u",
14114 +                       sig, info, t, vx_task_xid(t), t->pid, current->xid);
14115 +               return error;
14116 +       }
14117 +/* skip: */
14118         return security_task_kill(t, info, sig, 0);
14119  }
14120  
14121 @@ -1344,8 +1369,14 @@ int kill_pid_info(int sig, struct siginf
14122         for (;;) {
14123                 rcu_read_lock();
14124                 p = pid_task(pid, PIDTYPE_PID);
14125 -               if (p)
14126 -                       error = group_send_sig_info(sig, info, p);
14127 +               if (p) {
14128 +                       if (vx_check(vx_task_xid(p), VS_IDENT))
14129 +                               error = group_send_sig_info(sig, info, p);
14130 +                       else {
14131 +                               rcu_read_unlock();
14132 +                               return -ESRCH;
14133 +                       }
14134 +               }
14135                 rcu_read_unlock();
14136                 if (likely(!p || error != -ESRCH))
14137                         return error;
14138 @@ -1390,7 +1421,7 @@ int kill_pid_info_as_cred(int sig, struc
14139  
14140         rcu_read_lock();
14141         p = pid_task(pid, PIDTYPE_PID);
14142 -       if (!p) {
14143 +       if (!p || !vx_check(vx_task_xid(p), VS_IDENT)) {
14144                 ret = -ESRCH;
14145                 goto out_unlock;
14146         }
14147 @@ -1442,8 +1473,10 @@ static int kill_something_info(int sig,
14148                 struct task_struct * p;
14149  
14150                 for_each_process(p) {
14151 -                       if (task_pid_vnr(p) > 1 &&
14152 -                                       !same_thread_group(p, current)) {
14153 +                       if (vx_check(vx_task_xid(p), VS_ADMIN|VS_IDENT) &&
14154 +                               task_pid_vnr(p) > 1 &&
14155 +                               !same_thread_group(p, current) &&
14156 +                               !vx_current_initpid(p->pid)) {
14157                                 int err = group_send_sig_info(sig, info, p);
14158                                 ++count;
14159                                 if (err != -EPERM)
14160 @@ -2296,6 +2329,11 @@ relock:
14161                                 !sig_kernel_only(signr))
14162                         continue;
14163  
14164 +               /* virtual init is protected against user signals */
14165 +               if ((ksig->info.si_code == SI_USER) &&
14166 +                       vx_current_initpid(current->pid))
14167 +                       continue;
14168 +
14169                 if (sig_kernel_stop(signr)) {
14170                         /*
14171                          * The default action is to stop all threads in
14172 diff -NurpP --minimal linux-4.1.41/kernel/softirq.c linux-4.1.41-vs2.3.8.5.3/kernel/softirq.c
14173 --- linux-4.1.41/kernel/softirq.c       2015-04-12 22:12:50.000000000 +0000
14174 +++ linux-4.1.41-vs2.3.8.5.3/kernel/softirq.c   2016-07-05 04:41:47.000000000 +0000
14175 @@ -26,6 +26,7 @@
14176  #include <linux/smpboot.h>
14177  #include <linux/tick.h>
14178  #include <linux/irq.h>
14179 +#include <linux/vs_context.h>
14180  
14181  #define CREATE_TRACE_POINTS
14182  #include <trace/events/irq.h>
14183 diff -NurpP --minimal linux-4.1.41/kernel/sys.c linux-4.1.41-vs2.3.8.5.3/kernel/sys.c
14184 --- linux-4.1.41/kernel/sys.c   2017-06-23 10:04:01.000000000 +0000
14185 +++ linux-4.1.41-vs2.3.8.5.3/kernel/sys.c       2016-07-05 04:41:47.000000000 +0000
14186 @@ -54,6 +54,7 @@
14187  #include <linux/cred.h>
14188  
14189  #include <linux/kmsg_dump.h>
14190 +#include <linux/vs_pid.h>
14191  /* Move somewhere else to avoid recompiling? */
14192  #include <generated/utsrelease.h>
14193  
14194 @@ -157,7 +158,10 @@ static int set_one_prio(struct task_stru
14195                 goto out;
14196         }
14197         if (niceval < task_nice(p) && !can_nice(p, niceval)) {
14198 -               error = -EACCES;
14199 +               if (vx_flags(VXF_IGNEG_NICE, 0))
14200 +                       error = 0;
14201 +               else
14202 +                       error = -EACCES;
14203                 goto out;
14204         }
14205         no_nice = security_task_setnice(p, niceval);
14206 @@ -208,6 +212,8 @@ SYSCALL_DEFINE3(setpriority, int, which,
14207                 else
14208                         pgrp = task_pgrp(current);
14209                 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
14210 +                       if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
14211 +                               continue;
14212                         error = set_one_prio(p, niceval, error);
14213                 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
14214                 break;
14215 @@ -274,6 +280,8 @@ SYSCALL_DEFINE2(getpriority, int, which,
14216                 else
14217                         pgrp = task_pgrp(current);
14218                 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
14219 +                       if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
14220 +                               continue;
14221                         niceval = nice_to_rlimit(task_nice(p));
14222                         if (niceval > retval)
14223                                 retval = niceval;
14224 @@ -290,6 +298,8 @@ SYSCALL_DEFINE2(getpriority, int, which,
14225                                 goto out_unlock;        /* No processes for this user */
14226                 }
14227                 do_each_thread(g, p) {
14228 +                       if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
14229 +                               continue;
14230                         if (uid_eq(task_uid(p), uid)) {
14231                                 niceval = nice_to_rlimit(task_nice(p));
14232                                 if (niceval > retval)
14233 @@ -1217,7 +1227,8 @@ SYSCALL_DEFINE2(sethostname, char __user
14234         int errno;
14235         char tmp[__NEW_UTS_LEN];
14236  
14237 -       if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
14238 +       if (!vx_ns_capable(current->nsproxy->uts_ns->user_ns,
14239 +               CAP_SYS_ADMIN, VXC_SET_UTSNAME))
14240                 return -EPERM;
14241  
14242         if (len < 0 || len > __NEW_UTS_LEN)
14243 @@ -1268,7 +1279,8 @@ SYSCALL_DEFINE2(setdomainname, char __us
14244         int errno;
14245         char tmp[__NEW_UTS_LEN];
14246  
14247 -       if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
14248 +       if (!vx_ns_capable(current->nsproxy->uts_ns->user_ns,
14249 +               CAP_SYS_ADMIN, VXC_SET_UTSNAME))
14250                 return -EPERM;
14251         if (len < 0 || len > __NEW_UTS_LEN)
14252                 return -EINVAL;
14253 @@ -1386,7 +1398,7 @@ int do_prlimit(struct task_struct *tsk,
14254                 /* Keep the capable check against init_user_ns until
14255                    cgroups can contain all limits */
14256                 if (new_rlim->rlim_max > rlim->rlim_max &&
14257 -                               !capable(CAP_SYS_RESOURCE))
14258 +                       !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
14259                         retval = -EPERM;
14260                 if (!retval)
14261                         retval = security_task_setrlimit(tsk->group_leader,
14262 @@ -1439,7 +1451,8 @@ static int check_prlimit_permission(stru
14263             gid_eq(cred->gid, tcred->sgid) &&
14264             gid_eq(cred->gid, tcred->gid))
14265                 return 0;
14266 -       if (ns_capable(tcred->user_ns, CAP_SYS_RESOURCE))
14267 +       if (vx_ns_capable(tcred->user_ns,
14268 +               CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
14269                 return 0;
14270  
14271         return -EPERM;
14272 diff -NurpP --minimal linux-4.1.41/kernel/sysctl.c linux-4.1.41-vs2.3.8.5.3/kernel/sysctl.c
14273 --- linux-4.1.41/kernel/sysctl.c        2017-06-23 10:04:01.000000000 +0000
14274 +++ linux-4.1.41-vs2.3.8.5.3/kernel/sysctl.c    2017-05-30 07:39:23.000000000 +0000
14275 @@ -86,6 +86,7 @@
14276  #if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_LOCK_STAT)
14277  #include <linux/lockdep.h>
14278  #endif
14279 +extern char vshelper_path[];
14280  #ifdef CONFIG_CHR_DEV_SG
14281  #include <scsi/sg.h>
14282  #endif
14283 @@ -278,6 +279,13 @@ static int max_extfrag_threshold = 1000;
14284  
14285  static struct ctl_table kern_table[] = {
14286         {
14287 +               .procname       = "vshelper",
14288 +               .data           = &vshelper_path,
14289 +               .maxlen         = 256,
14290 +               .mode           = 0644,
14291 +               .proc_handler   = proc_dostring,
14292 +       },
14293 +       {
14294                 .procname       = "sched_child_runs_first",
14295                 .data           = &sysctl_sched_child_runs_first,
14296                 .maxlen         = sizeof(unsigned int),
14297 @@ -1343,7 +1351,6 @@ static struct ctl_table vm_table[] = {
14298                 .extra1         = &zero,
14299                 .extra2         = &one,
14300         },
14301 -
14302  #endif /* CONFIG_COMPACTION */
14303         {
14304                 .procname       = "min_free_kbytes",
14305 diff -NurpP --minimal linux-4.1.41/kernel/sysctl_binary.c linux-4.1.41-vs2.3.8.5.3/kernel/sysctl_binary.c
14306 --- linux-4.1.41/kernel/sysctl_binary.c 2017-06-23 10:04:01.000000000 +0000
14307 +++ linux-4.1.41-vs2.3.8.5.3/kernel/sysctl_binary.c     2016-07-05 04:41:47.000000000 +0000
14308 @@ -73,6 +73,7 @@ static const struct bin_table bin_kern_t
14309  
14310         { CTL_INT,      KERN_PANIC,                     "panic" },
14311         { CTL_INT,      KERN_REALROOTDEV,               "real-root-dev" },
14312 +       { CTL_STR,      KERN_VSHELPER,                  "vshelper" },
14313  
14314         { CTL_STR,      KERN_SPARC_REBOOT,              "reboot-cmd" },
14315         { CTL_INT,      KERN_CTLALTDEL,                 "ctrl-alt-del" },
14316 diff -NurpP --minimal linux-4.1.41/kernel/time/posix-timers.c linux-4.1.41-vs2.3.8.5.3/kernel/time/posix-timers.c
14317 --- linux-4.1.41/kernel/time/posix-timers.c     2015-04-12 22:12:50.000000000 +0000
14318 +++ linux-4.1.41-vs2.3.8.5.3/kernel/time/posix-timers.c 2016-07-05 04:41:47.000000000 +0000
14319 @@ -48,6 +48,7 @@
14320  #include <linux/workqueue.h>
14321  #include <linux/export.h>
14322  #include <linux/hashtable.h>
14323 +#include <linux/vs_context.h>
14324  
14325  #include "timekeeping.h"
14326  
14327 @@ -400,6 +401,7 @@ int posix_timer_event(struct k_itimer *t
14328  {
14329         struct task_struct *task;
14330         int shared, ret = -1;
14331 +
14332         /*
14333          * FIXME: if ->sigq is queued we can race with
14334          * dequeue_signal()->do_schedule_next_timer().
14335 @@ -416,10 +418,18 @@ int posix_timer_event(struct k_itimer *t
14336         rcu_read_lock();
14337         task = pid_task(timr->it_pid, PIDTYPE_PID);
14338         if (task) {
14339 +               struct vx_info_save vxis;
14340 +               struct vx_info *vxi;
14341 +
14342 +               vxi = get_vx_info(task->vx_info);
14343 +               enter_vx_info(vxi, &vxis);
14344                 shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID);
14345                 ret = send_sigqueue(timr->sigq, task, shared);
14346 +               leave_vx_info(&vxis);
14347 +               put_vx_info(vxi);
14348         }
14349         rcu_read_unlock();
14350 +
14351         /* If we failed to send the signal the timer stops. */
14352         return ret > 0;
14353  }
14354 diff -NurpP --minimal linux-4.1.41/kernel/time/time.c linux-4.1.41-vs2.3.8.5.3/kernel/time/time.c
14355 --- linux-4.1.41/kernel/time/time.c     2015-04-12 22:12:50.000000000 +0000
14356 +++ linux-4.1.41-vs2.3.8.5.3/kernel/time/time.c 2016-07-05 04:41:47.000000000 +0000
14357 @@ -37,6 +37,7 @@
14358  #include <linux/fs.h>
14359  #include <linux/math64.h>
14360  #include <linux/ptrace.h>
14361 +#include <linux/vs_time.h>
14362  
14363  #include <asm/uaccess.h>
14364  #include <asm/unistd.h>
14365 @@ -93,7 +94,7 @@ SYSCALL_DEFINE1(stime, time_t __user *,
14366         if (err)
14367                 return err;
14368  
14369 -       do_settimeofday(&tv);
14370 +       vx_settimeofday(&tv);
14371         return 0;
14372  }
14373  
14374 @@ -182,7 +183,7 @@ int do_sys_settimeofday(const struct tim
14375                 }
14376         }
14377         if (tv)
14378 -               return do_settimeofday(tv);
14379 +               return vx_settimeofday(tv);
14380         return 0;
14381  }
14382  
14383 diff -NurpP --minimal linux-4.1.41/kernel/time/timekeeping.c linux-4.1.41-vs2.3.8.5.3/kernel/time/timekeeping.c
14384 --- linux-4.1.41/kernel/time/timekeeping.c      2017-06-23 10:04:01.000000000 +0000
14385 +++ linux-4.1.41-vs2.3.8.5.3/kernel/time/timekeeping.c  2017-05-30 07:39:23.000000000 +0000
14386 @@ -23,6 +23,7 @@
14387  #include <linux/stop_machine.h>
14388  #include <linux/pvclock_gtod.h>
14389  #include <linux/compiler.h>
14390 +#include <linux/vs_time.h>
14391  
14392  #include "tick-internal.h"
14393  #include "ntp_internal.h"
14394 @@ -900,7 +901,9 @@ void getnstime_raw_and_real(struct times
14395         } while (read_seqcount_retry(&tk_core.seq, seq));
14396  
14397         timespec_add_ns(ts_raw, nsecs_raw);
14398 +       vx_adjust_timespec(ts_raw);
14399         timespec_add_ns(ts_real, nsecs_real);
14400 +       vx_adjust_timespec(ts_real);
14401  }
14402  EXPORT_SYMBOL(getnstime_raw_and_real);
14403  
14404 diff -NurpP --minimal linux-4.1.41/kernel/time/timer.c linux-4.1.41-vs2.3.8.5.3/kernel/time/timer.c
14405 --- linux-4.1.41/kernel/time/timer.c    2015-07-06 20:41:43.000000000 +0000
14406 +++ linux-4.1.41-vs2.3.8.5.3/kernel/time/timer.c        2016-07-05 04:41:47.000000000 +0000
14407 @@ -42,6 +42,10 @@
14408  #include <linux/sched/sysctl.h>
14409  #include <linux/slab.h>
14410  #include <linux/compat.h>
14411 +#include <linux/vs_base.h>
14412 +#include <linux/vs_cvirt.h>
14413 +#include <linux/vs_pid.h>
14414 +#include <linux/vserver/sched.h>
14415  
14416  #include <asm/uaccess.h>
14417  #include <asm/unistd.h>
14418 diff -NurpP --minimal linux-4.1.41/kernel/user_namespace.c linux-4.1.41-vs2.3.8.5.3/kernel/user_namespace.c
14419 --- linux-4.1.41/kernel/user_namespace.c        2015-04-12 22:12:50.000000000 +0000
14420 +++ linux-4.1.41-vs2.3.8.5.3/kernel/user_namespace.c    2016-07-05 04:41:47.000000000 +0000
14421 @@ -22,6 +22,7 @@
14422  #include <linux/ctype.h>
14423  #include <linux/projid.h>
14424  #include <linux/fs_struct.h>
14425 +#include <linux/vserver/global.h>
14426  
14427  static struct kmem_cache *user_ns_cachep __read_mostly;
14428  static DEFINE_MUTEX(userns_state_mutex);
14429 @@ -96,6 +97,7 @@ int create_user_ns(struct cred *new)
14430  
14431         atomic_set(&ns->count, 1);
14432         /* Leave the new->user_ns reference with the new user namespace. */
14433 +       atomic_inc(&vs_global_user_ns);
14434         ns->parent = parent_ns;
14435         ns->level = parent_ns->level + 1;
14436         ns->owner = owner;
14437 @@ -144,6 +146,7 @@ void free_user_ns(struct user_namespace
14438                 key_put(ns->persistent_keyring_register);
14439  #endif
14440                 ns_free_inum(&ns->ns);
14441 +               atomic_dec(&vs_global_user_ns);
14442                 kmem_cache_free(user_ns_cachep, ns);
14443                 ns = parent;
14444         } while (atomic_dec_and_test(&parent->count));
14445 @@ -357,6 +360,18 @@ gid_t from_kgid_munged(struct user_names
14446  }
14447  EXPORT_SYMBOL(from_kgid_munged);
14448  
14449 +ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
14450 +{
14451 +       return KTAGT_INIT(tag);
14452 +}
14453 +EXPORT_SYMBOL(make_ktag);
14454 +
14455 +vtag_t from_ktag(struct user_namespace *to, ktag_t tag)
14456 +{
14457 +       return __ktag_val(tag);
14458 +}
14459 +EXPORT_SYMBOL(from_ktag);
14460 +
14461  /**
14462   *     make_kprojid - Map a user-namespace projid pair into a kprojid.
14463   *     @ns:  User namespace that the projid is in
14464 diff -NurpP --minimal linux-4.1.41/kernel/utsname.c linux-4.1.41-vs2.3.8.5.3/kernel/utsname.c
14465 --- linux-4.1.41/kernel/utsname.c       2015-04-12 22:12:50.000000000 +0000
14466 +++ linux-4.1.41-vs2.3.8.5.3/kernel/utsname.c   2016-07-05 04:41:47.000000000 +0000
14467 @@ -16,14 +16,17 @@
14468  #include <linux/slab.h>
14469  #include <linux/user_namespace.h>
14470  #include <linux/proc_ns.h>
14471 +#include <linux/vserver/global.h>
14472  
14473  static struct uts_namespace *create_uts_ns(void)
14474  {
14475         struct uts_namespace *uts_ns;
14476  
14477         uts_ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL);
14478 -       if (uts_ns)
14479 +       if (uts_ns) {
14480                 kref_init(&uts_ns->kref);
14481 +               atomic_inc(&vs_global_uts_ns);
14482 +       }
14483         return uts_ns;
14484  }
14485  
14486 @@ -87,6 +90,7 @@ void free_uts_ns(struct kref *kref)
14487         ns = container_of(kref, struct uts_namespace, kref);
14488         put_user_ns(ns->user_ns);
14489         ns_free_inum(&ns->ns);
14490 +       atomic_dec(&vs_global_uts_ns);
14491         kfree(ns);
14492  }
14493  
14494 diff -NurpP --minimal linux-4.1.41/kernel/vserver/Kconfig linux-4.1.41-vs2.3.8.5.3/kernel/vserver/Kconfig
14495 --- linux-4.1.41/kernel/vserver/Kconfig 1970-01-01 00:00:00.000000000 +0000
14496 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/Kconfig     2016-07-05 04:41:47.000000000 +0000
14497 @@ -0,0 +1,230 @@
14498 +#
14499 +# Linux VServer configuration
14500 +#
14501 +
14502 +menu "Linux VServer"
14503 +
14504 +config VSERVER_AUTO_LBACK
14505 +       bool    "Automatically Assign Loopback IP"
14506 +       default y
14507 +       help
14508 +         Automatically assign a guest specific loopback
14509 +         IP and add it to the kernel network stack on
14510 +         startup.
14511 +
14512 +config VSERVER_AUTO_SINGLE
14513 +       bool    "Automatic Single IP Special Casing"
14514 +       default n
14515 +       help
14516 +         This allows network contexts with a single IP to
14517 +         automatically remap 0.0.0.0 bindings to that IP,
14518 +         avoiding further network checks and improving
14519 +         performance.
14520 +
14521 +         (note: such guests do not allow to change the ip
14522 +          on the fly and do not show loopback addresses)
14523 +
14524 +config VSERVER_COWBL
14525 +       bool    "Enable COW Immutable Link Breaking"
14526 +       default y
14527 +       help
14528 +         This enables the COW (Copy-On-Write) link break code.
14529 +         It allows you to treat unified files like normal files
14530 +         when writing to them (which will implicitely break the
14531 +         link and create a copy of the unified file)
14532 +
14533 +config VSERVER_VTIME
14534 +       bool    "Enable Virtualized Guest Time (EXPERIMENTAL)"
14535 +       default n
14536 +       help
14537 +         This enables per guest time offsets to allow for
14538 +         adjusting the system clock individually per guest.
14539 +         this adds some overhead to the time functions and
14540 +         therefore should not be enabled without good reason.
14541 +
14542 +config VSERVER_DEVICE
14543 +       bool    "Enable Guest Device Mapping (EXPERIMENTAL)"
14544 +       default n
14545 +       help
14546 +         This enables generic device remapping.
14547 +
14548 +config VSERVER_PROC_SECURE
14549 +       bool    "Enable Proc Security"
14550 +       depends on PROC_FS
14551 +       default y
14552 +       help
14553 +         This configures ProcFS security to initially hide
14554 +         non-process entries for all contexts except the main and
14555 +         spectator context (i.e. for all guests), which is a secure
14556 +         default.
14557 +
14558 +         (note: on 1.2x the entries were visible by default)
14559 +
14560 +choice
14561 +       prompt  "Persistent Inode Tagging"
14562 +       default TAGGING_ID24
14563 +       help
14564 +         This adds persistent context information to filesystems
14565 +         mounted with the tagxid option. Tagging is a requirement
14566 +         for per-context disk limits and per-context quota.
14567 +
14568 +
14569 +config TAGGING_NONE
14570 +       bool    "Disabled"
14571 +       help
14572 +         do not store per-context information in inodes.
14573 +
14574 +config TAGGING_UID16
14575 +       bool    "UID16/GID32"
14576 +       help
14577 +         reduces UID to 16 bit, but leaves GID at 32 bit.
14578 +
14579 +config TAGGING_GID16
14580 +       bool    "UID32/GID16"
14581 +       help
14582 +         reduces GID to 16 bit, but leaves UID at 32 bit.
14583 +
14584 +config TAGGING_ID24
14585 +       bool    "UID24/GID24"
14586 +       help
14587 +         uses the upper 8bit from UID and GID for XID tagging
14588 +         which leaves 24bit for UID/GID each, which should be
14589 +         more than sufficient for normal use.
14590 +
14591 +config TAGGING_INTERN
14592 +       bool    "UID32/GID32"
14593 +       help
14594 +         this uses otherwise reserved inode fields in the on
14595 +         disk representation, which limits the use to a few
14596 +         filesystems (currently ext2 and ext3)
14597 +
14598 +endchoice
14599 +
14600 +config TAG_NFSD
14601 +       bool    "Tag NFSD User Auth and Files"
14602 +       default n
14603 +       help
14604 +         Enable this if you do want the in-kernel NFS
14605 +         Server to use the tagging specified above.
14606 +         (will require patched clients too)
14607 +
14608 +config VSERVER_PRIVACY
14609 +       bool    "Honor Privacy Aspects of Guests"
14610 +       default n
14611 +       help
14612 +         When enabled, most context checks will disallow
14613 +         access to structures assigned to a specific context,
14614 +         like ptys or loop devices.
14615 +
14616 +config VSERVER_CONTEXTS
14617 +       int     "Maximum number of Contexts (1-65533)"  if EMBEDDED
14618 +       range 1 65533
14619 +       default "768"   if 64BIT
14620 +       default "256"
14621 +       help
14622 +         This setting will optimize certain data structures
14623 +         and memory allocations according to the expected
14624 +         maximum.
14625 +
14626 +         note: this is not a strict upper limit.
14627 +
14628 +config VSERVER_WARN
14629 +       bool    "VServer Warnings"
14630 +       default y
14631 +       help
14632 +         This enables various runtime warnings, which will
14633 +         notify about potential manipulation attempts or
14634 +         resource shortage. It is generally considered to
14635 +         be a good idea to have that enabled.
14636 +
14637 +config VSERVER_WARN_DEVPTS
14638 +       bool    "VServer DevPTS Warnings"
14639 +       depends on VSERVER_WARN
14640 +       default y
14641 +       help
14642 +         This enables DevPTS related warnings, issued when a
14643 +         process inside a context tries to lookup or access
14644 +         a dynamic pts from the host or a different context.
14645 +
14646 +config VSERVER_DEBUG
14647 +       bool    "VServer Debugging Code"
14648 +       default n
14649 +       help
14650 +         Set this to yes if you want to be able to activate
14651 +         debugging output at runtime. It adds a very small
14652 +         overhead to all vserver related functions and
14653 +         increases the kernel size by about 20k.
14654 +
14655 +config VSERVER_HISTORY
14656 +       bool    "VServer History Tracing"
14657 +       depends on VSERVER_DEBUG
14658 +       default n
14659 +       help
14660 +         Set this to yes if you want to record the history of
14661 +         linux-vserver activities, so they can be replayed in
14662 +         the event of a kernel panic or oops.
14663 +
14664 +config VSERVER_HISTORY_SIZE
14665 +       int     "Per-CPU History Size (32-65536)"
14666 +       depends on VSERVER_HISTORY
14667 +       range 32 65536
14668 +       default 64
14669 +       help
14670 +         This allows you to specify the number of entries in
14671 +         the per-CPU history buffer.
14672 +
14673 +config VSERVER_EXTRA_MNT_CHECK
14674 +       bool    "Extra Checks for Reachability"
14675 +       default n
14676 +       help
14677 +         Set this to yes if you want to do extra checks for
14678 +         vfsmount reachability in the proc filesystem code.
14679 +         This shouldn't be required on any setup utilizing
14680 +         mnt namespaces.
14681 +
14682 +choice
14683 +       prompt  "Quotes used in debug and warn messages"
14684 +       default QUOTES_ISO8859
14685 +
14686 +config QUOTES_ISO8859
14687 +       bool    "Extended ASCII (ISO 8859) angle quotes"
14688 +       help
14689 +         This uses the extended ASCII characters \xbb
14690 +         and \xab for quoting file and process names.
14691 +
14692 +config QUOTES_UTF8
14693 +       bool    "UTF-8 angle quotes"
14694 +       help
14695 +         This uses the the UTF-8 sequences for angle
14696 +         quotes to quote file and process names.
14697 +
14698 +config QUOTES_ASCII
14699 +       bool    "ASCII single quotes"
14700 +       help
14701 +         This uses the ASCII single quote character
14702 +         (\x27) to quote file and process names.
14703 +
14704 +endchoice
14705 +
14706 +endmenu
14707 +
14708 +
14709 +config VSERVER
14710 +       bool
14711 +       default y
14712 +       select NAMESPACES
14713 +       select UTS_NS
14714 +       select IPC_NS
14715 +#      select USER_NS
14716 +       select SYSVIPC
14717 +
14718 +config VSERVER_SECURITY
14719 +       bool
14720 +       depends on SECURITY
14721 +       default y
14722 +       select SECURITY_CAPABILITIES
14723 +
14724 +config VSERVER_DISABLED
14725 +       bool
14726 +       default n
14727 +
14728 diff -NurpP --minimal linux-4.1.41/kernel/vserver/Makefile linux-4.1.41-vs2.3.8.5.3/kernel/vserver/Makefile
14729 --- linux-4.1.41/kernel/vserver/Makefile        1970-01-01 00:00:00.000000000 +0000
14730 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/Makefile    2016-07-05 04:41:47.000000000 +0000
14731 @@ -0,0 +1,18 @@
14732 +#
14733 +# Makefile for the Linux vserver routines.
14734 +#
14735 +
14736 +
14737 +obj-y          += vserver.o
14738 +
14739 +vserver-y      := switch.o context.o space.o sched.o network.o inode.o \
14740 +                  limit.o cvirt.o cacct.o signal.o helper.o init.o \
14741 +                  dlimit.o tag.o
14742 +
14743 +vserver-$(CONFIG_INET) += inet.o
14744 +vserver-$(CONFIG_PROC_FS) += proc.o
14745 +vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o debug.o
14746 +vserver-$(CONFIG_VSERVER_HISTORY) += history.o
14747 +vserver-$(CONFIG_VSERVER_MONITOR) += monitor.o
14748 +vserver-$(CONFIG_VSERVER_DEVICE) += device.o
14749 +
14750 diff -NurpP --minimal linux-4.1.41/kernel/vserver/cacct.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/cacct.c
14751 --- linux-4.1.41/kernel/vserver/cacct.c 1970-01-01 00:00:00.000000000 +0000
14752 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/cacct.c     2016-07-05 04:41:47.000000000 +0000
14753 @@ -0,0 +1,42 @@
14754 +/*
14755 + *  linux/kernel/vserver/cacct.c
14756 + *
14757 + *  Virtual Server: Context Accounting
14758 + *
14759 + *  Copyright (C) 2006-2007 Herbert Pötzl
14760 + *
14761 + *  V0.01  added accounting stats
14762 + *
14763 + */
14764 +
14765 +#include <linux/types.h>
14766 +#include <linux/vs_context.h>
14767 +#include <linux/vserver/cacct_cmd.h>
14768 +#include <linux/vserver/cacct_int.h>
14769 +
14770 +#include <asm/errno.h>
14771 +#include <asm/uaccess.h>
14772 +
14773 +
14774 +int vc_sock_stat(struct vx_info *vxi, void __user *data)
14775 +{
14776 +       struct vcmd_sock_stat_v0 vc_data;
14777 +       int j, field;
14778 +
14779 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
14780 +               return -EFAULT;
14781 +
14782 +       field = vc_data.field;
14783 +       if ((field < 0) || (field >= VXA_SOCK_SIZE))
14784 +               return -EINVAL;
14785 +
14786 +       for (j = 0; j < 3; j++) {
14787 +               vc_data.count[j] = vx_sock_count(&vxi->cacct, field, j);
14788 +               vc_data.total[j] = vx_sock_total(&vxi->cacct, field, j);
14789 +       }
14790 +
14791 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
14792 +               return -EFAULT;
14793 +       return 0;
14794 +}
14795 +
14796 diff -NurpP --minimal linux-4.1.41/kernel/vserver/cacct_init.h linux-4.1.41-vs2.3.8.5.3/kernel/vserver/cacct_init.h
14797 --- linux-4.1.41/kernel/vserver/cacct_init.h    1970-01-01 00:00:00.000000000 +0000
14798 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/cacct_init.h        2016-07-05 04:41:47.000000000 +0000
14799 @@ -0,0 +1,25 @@
14800 +
14801 +
14802 +static inline void vx_info_init_cacct(struct _vx_cacct *cacct)
14803 +{
14804 +       int i, j;
14805 +
14806 +
14807 +       for (i = 0; i < VXA_SOCK_SIZE; i++) {
14808 +               for (j = 0; j < 3; j++) {
14809 +                       atomic_long_set(&cacct->sock[i][j].count, 0);
14810 +                       atomic_long_set(&cacct->sock[i][j].total, 0);
14811 +               }
14812 +       }
14813 +       for (i = 0; i < 8; i++)
14814 +               atomic_set(&cacct->slab[i], 0);
14815 +       for (i = 0; i < 5; i++)
14816 +               for (j = 0; j < 4; j++)
14817 +                       atomic_set(&cacct->page[i][j], 0);
14818 +}
14819 +
14820 +static inline void vx_info_exit_cacct(struct _vx_cacct *cacct)
14821 +{
14822 +       return;
14823 +}
14824 +
14825 diff -NurpP --minimal linux-4.1.41/kernel/vserver/cacct_proc.h linux-4.1.41-vs2.3.8.5.3/kernel/vserver/cacct_proc.h
14826 --- linux-4.1.41/kernel/vserver/cacct_proc.h    1970-01-01 00:00:00.000000000 +0000
14827 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/cacct_proc.h        2016-07-05 04:41:47.000000000 +0000
14828 @@ -0,0 +1,53 @@
14829 +#ifndef _VX_CACCT_PROC_H
14830 +#define _VX_CACCT_PROC_H
14831 +
14832 +#include <linux/vserver/cacct_int.h>
14833 +
14834 +
14835 +#define VX_SOCKA_TOP   \
14836 +       "Type\t    recv #/bytes\t\t   send #/bytes\t\t    fail #/bytes\n"
14837 +
14838 +static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer)
14839 +{
14840 +       int i, j, length = 0;
14841 +       static char *type[VXA_SOCK_SIZE] = {
14842 +               "UNSPEC", "UNIX", "INET", "INET6", "PACKET", "OTHER"
14843 +       };
14844 +
14845 +       length += sprintf(buffer + length, VX_SOCKA_TOP);
14846 +       for (i = 0; i < VXA_SOCK_SIZE; i++) {
14847 +               length += sprintf(buffer + length, "%s:", type[i]);
14848 +               for (j = 0; j < 3; j++) {
14849 +                       length += sprintf(buffer + length,
14850 +                               "\t%10lu/%-10lu",
14851 +                               vx_sock_count(cacct, i, j),
14852 +                               vx_sock_total(cacct, i, j));
14853 +               }
14854 +               buffer[length++] = '\n';
14855 +       }
14856 +
14857 +       length += sprintf(buffer + length, "\n");
14858 +       length += sprintf(buffer + length,
14859 +               "slab:\t %8u %8u %8u %8u\n",
14860 +               atomic_read(&cacct->slab[1]),
14861 +               atomic_read(&cacct->slab[4]),
14862 +               atomic_read(&cacct->slab[0]),
14863 +               atomic_read(&cacct->slab[2]));
14864 +
14865 +       length += sprintf(buffer + length, "\n");
14866 +       for (i = 0; i < 5; i++) {
14867 +               length += sprintf(buffer + length,
14868 +                       "page[%d]: %8u %8u %8u %8u\t %8u %8u %8u %8u\n", i,
14869 +                       atomic_read(&cacct->page[i][0]),
14870 +                       atomic_read(&cacct->page[i][1]),
14871 +                       atomic_read(&cacct->page[i][2]),
14872 +                       atomic_read(&cacct->page[i][3]),
14873 +                       atomic_read(&cacct->page[i][4]),
14874 +                       atomic_read(&cacct->page[i][5]),
14875 +                       atomic_read(&cacct->page[i][6]),
14876 +                       atomic_read(&cacct->page[i][7]));
14877 +       }
14878 +       return length;
14879 +}
14880 +
14881 +#endif /* _VX_CACCT_PROC_H */
14882 diff -NurpP --minimal linux-4.1.41/kernel/vserver/context.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/context.c
14883 --- linux-4.1.41/kernel/vserver/context.c       1970-01-01 00:00:00.000000000 +0000
14884 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/context.c   2016-07-05 04:41:47.000000000 +0000
14885 @@ -0,0 +1,1119 @@
14886 +/*
14887 + *  linux/kernel/vserver/context.c
14888 + *
14889 + *  Virtual Server: Context Support
14890 + *
14891 + *  Copyright (C) 2003-2011  Herbert Pötzl
14892 + *
14893 + *  V0.01  context helper
14894 + *  V0.02  vx_ctx_kill syscall command
14895 + *  V0.03  replaced context_info calls
14896 + *  V0.04  redesign of struct (de)alloc
14897 + *  V0.05  rlimit basic implementation
14898 + *  V0.06  task_xid and info commands
14899 + *  V0.07  context flags and caps
14900 + *  V0.08  switch to RCU based hash
14901 + *  V0.09  revert to non RCU for now
14902 + *  V0.10  and back to working RCU hash
14903 + *  V0.11  and back to locking again
14904 + *  V0.12  referenced context store
14905 + *  V0.13  separate per cpu data
14906 + *  V0.14  changed vcmds to vxi arg
14907 + *  V0.15  added context stat
14908 + *  V0.16  have __create claim() the vxi
14909 + *  V0.17  removed older and legacy stuff
14910 + *  V0.18  added user credentials
14911 + *  V0.19  added warn mask
14912 + *
14913 + */
14914 +
14915 +#include <linux/slab.h>
14916 +#include <linux/types.h>
14917 +#include <linux/security.h>
14918 +#include <linux/pid_namespace.h>
14919 +#include <linux/capability.h>
14920 +
14921 +#include <linux/vserver/context.h>
14922 +#include <linux/vserver/network.h>
14923 +#include <linux/vserver/debug.h>
14924 +#include <linux/vserver/limit.h>
14925 +#include <linux/vserver/limit_int.h>
14926 +#include <linux/vserver/space.h>
14927 +#include <linux/init_task.h>
14928 +#include <linux/fs_struct.h>
14929 +#include <linux/cred.h>
14930 +
14931 +#include <linux/vs_context.h>
14932 +#include <linux/vs_limit.h>
14933 +#include <linux/vs_pid.h>
14934 +#include <linux/vserver/context_cmd.h>
14935 +
14936 +#include "cvirt_init.h"
14937 +#include "cacct_init.h"
14938 +#include "limit_init.h"
14939 +#include "sched_init.h"
14940 +
14941 +
14942 +atomic_t vx_global_ctotal      = ATOMIC_INIT(0);
14943 +atomic_t vx_global_cactive     = ATOMIC_INIT(0);
14944 +
14945 +
14946 +/*     now inactive context structures */
14947 +
14948 +static struct hlist_head vx_info_inactive = HLIST_HEAD_INIT;
14949 +
14950 +static DEFINE_SPINLOCK(vx_info_inactive_lock);
14951 +
14952 +
14953 +/*     __alloc_vx_info()
14954 +
14955 +       * allocate an initialized vx_info struct
14956 +       * doesn't make it visible (hash)                        */
14957 +
14958 +static struct vx_info *__alloc_vx_info(vxid_t xid)
14959 +{
14960 +       struct vx_info *new = NULL;
14961 +       int cpu, index;
14962 +
14963 +       vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid);
14964 +
14965 +       /* would this benefit from a slab cache? */
14966 +       new = kmalloc(sizeof(struct vx_info), GFP_KERNEL);
14967 +       if (!new)
14968 +               return 0;
14969 +
14970 +       memset(new, 0, sizeof(struct vx_info));
14971 +#ifdef CONFIG_SMP
14972 +       new->ptr_pc = alloc_percpu(struct _vx_info_pc);
14973 +       if (!new->ptr_pc)
14974 +               goto error;
14975 +#endif
14976 +       new->vx_id = xid;
14977 +       INIT_HLIST_NODE(&new->vx_hlist);
14978 +       atomic_set(&new->vx_usecnt, 0);
14979 +       atomic_set(&new->vx_tasks, 0);
14980 +       new->vx_parent = NULL;
14981 +       new->vx_state = 0;
14982 +       init_waitqueue_head(&new->vx_wait);
14983 +
14984 +       /* prepare reaper */
14985 +       get_task_struct(init_pid_ns.child_reaper);
14986 +       new->vx_reaper = init_pid_ns.child_reaper;
14987 +       new->vx_badness_bias = 0;
14988 +
14989 +       /* rest of init goes here */
14990 +       vx_info_init_limit(&new->limit);
14991 +       vx_info_init_sched(&new->sched);
14992 +       vx_info_init_cvirt(&new->cvirt);
14993 +       vx_info_init_cacct(&new->cacct);
14994 +
14995 +       /* per cpu data structures */
14996 +       for_each_possible_cpu(cpu) {
14997 +               vx_info_init_sched_pc(
14998 +                       &vx_per_cpu(new, sched_pc, cpu), cpu);
14999 +               vx_info_init_cvirt_pc(
15000 +                       &vx_per_cpu(new, cvirt_pc, cpu), cpu);
15001 +       }
15002 +
15003 +       new->vx_flags = VXF_INIT_SET;
15004 +       new->vx_bcaps = CAP_FULL_SET;   // maybe ~CAP_SETPCAP
15005 +       new->vx_ccaps = 0;
15006 +       new->vx_umask = 0;
15007 +       new->vx_wmask = 0;
15008 +
15009 +       new->reboot_cmd = 0;
15010 +       new->exit_code = 0;
15011 +
15012 +       // preconfig spaces
15013 +       for (index = 0; index < VX_SPACES; index++) {
15014 +               struct _vx_space *space = &new->space[index];
15015 +
15016 +               // filesystem
15017 +               spin_lock(&init_fs.lock);
15018 +               init_fs.users++;
15019 +               spin_unlock(&init_fs.lock);
15020 +               space->vx_fs = &init_fs;
15021 +
15022 +               /* FIXME: do we want defaults? */
15023 +               // space->vx_real_cred = 0;
15024 +               // space->vx_cred = 0;
15025 +       }
15026 +
15027 +
15028 +       vxdprintk(VXD_CBIT(xid, 0),
15029 +               "alloc_vx_info(%d) = %p", xid, new);
15030 +       vxh_alloc_vx_info(new);
15031 +       atomic_inc(&vx_global_ctotal);
15032 +       return new;
15033 +#ifdef CONFIG_SMP
15034 +error:
15035 +       kfree(new);
15036 +       return 0;
15037 +#endif
15038 +}
15039 +
15040 +/*     __dealloc_vx_info()
15041 +
15042 +       * final disposal of vx_info                             */
15043 +
15044 +static void __dealloc_vx_info(struct vx_info *vxi)
15045 +{
15046 +#ifdef CONFIG_VSERVER_WARN
15047 +       struct vx_info_save vxis;
15048 +       int cpu;
15049 +#endif
15050 +       vxdprintk(VXD_CBIT(xid, 0),
15051 +               "dealloc_vx_info(%p)", vxi);
15052 +       vxh_dealloc_vx_info(vxi);
15053 +
15054 +#ifdef CONFIG_VSERVER_WARN
15055 +       enter_vx_info(vxi, &vxis);
15056 +       vx_info_exit_limit(&vxi->limit);
15057 +       vx_info_exit_sched(&vxi->sched);
15058 +       vx_info_exit_cvirt(&vxi->cvirt);
15059 +       vx_info_exit_cacct(&vxi->cacct);
15060 +
15061 +       for_each_possible_cpu(cpu) {
15062 +               vx_info_exit_sched_pc(
15063 +                       &vx_per_cpu(vxi, sched_pc, cpu), cpu);
15064 +               vx_info_exit_cvirt_pc(
15065 +                       &vx_per_cpu(vxi, cvirt_pc, cpu), cpu);
15066 +       }
15067 +       leave_vx_info(&vxis);
15068 +#endif
15069 +
15070 +       vxi->vx_id = -1;
15071 +       vxi->vx_state |= VXS_RELEASED;
15072 +
15073 +#ifdef CONFIG_SMP
15074 +       free_percpu(vxi->ptr_pc);
15075 +#endif
15076 +       kfree(vxi);
15077 +       atomic_dec(&vx_global_ctotal);
15078 +}
15079 +
15080 +static void __shutdown_vx_info(struct vx_info *vxi)
15081 +{
15082 +       struct nsproxy *nsproxy;
15083 +       struct fs_struct *fs;
15084 +       struct cred *cred;
15085 +       int index, kill;
15086 +
15087 +       might_sleep();
15088 +
15089 +       vxi->vx_state |= VXS_SHUTDOWN;
15090 +       vs_state_change(vxi, VSC_SHUTDOWN);
15091 +
15092 +       for (index = 0; index < VX_SPACES; index++) {
15093 +               struct _vx_space *space = &vxi->space[index];
15094 +
15095 +               nsproxy = xchg(&space->vx_nsproxy, NULL);
15096 +               if (nsproxy)
15097 +                       put_nsproxy(nsproxy);
15098 +
15099 +               fs = xchg(&space->vx_fs, NULL);
15100 +               spin_lock(&fs->lock);
15101 +               kill = !--fs->users;
15102 +               spin_unlock(&fs->lock);
15103 +               if (kill)
15104 +                       free_fs_struct(fs);
15105 +
15106 +               cred = (struct cred *)xchg(&space->vx_cred, NULL);
15107 +               if (cred)
15108 +                       abort_creds(cred);
15109 +       }
15110 +}
15111 +
15112 +/* exported stuff */
15113 +
15114 +void free_vx_info(struct vx_info *vxi)
15115 +{
15116 +       unsigned long flags;
15117 +       unsigned index;
15118 +
15119 +       /* check for reference counts first */
15120 +       BUG_ON(atomic_read(&vxi->vx_usecnt));
15121 +       BUG_ON(atomic_read(&vxi->vx_tasks));
15122 +
15123 +       /* context must not be hashed */
15124 +       BUG_ON(vx_info_state(vxi, VXS_HASHED));
15125 +
15126 +       /* context shutdown is mandatory */
15127 +       BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN));
15128 +
15129 +       /* spaces check */
15130 +       for (index = 0; index < VX_SPACES; index++) {
15131 +               struct _vx_space *space = &vxi->space[index];
15132 +
15133 +               BUG_ON(space->vx_nsproxy);
15134 +               BUG_ON(space->vx_fs);
15135 +               // BUG_ON(space->vx_real_cred);
15136 +               // BUG_ON(space->vx_cred);
15137 +       }
15138 +
15139 +       spin_lock_irqsave(&vx_info_inactive_lock, flags);
15140 +       hlist_del(&vxi->vx_hlist);
15141 +       spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
15142 +
15143 +       __dealloc_vx_info(vxi);
15144 +}
15145 +
15146 +
15147 +/*     hash table for vx_info hash */
15148 +
15149 +#define VX_HASH_SIZE   13
15150 +
15151 +static struct hlist_head vx_info_hash[VX_HASH_SIZE] =
15152 +       { [0 ... VX_HASH_SIZE-1] = HLIST_HEAD_INIT };
15153 +
15154 +static DEFINE_SPINLOCK(vx_info_hash_lock);
15155 +
15156 +
15157 +static inline unsigned int __hashval(vxid_t xid)
15158 +{
15159 +       return (xid % VX_HASH_SIZE);
15160 +}
15161 +
15162 +
15163 +
15164 +/*     __hash_vx_info()
15165 +
15166 +       * add the vxi to the global hash table
15167 +       * requires the hash_lock to be held                     */
15168 +
15169 +static inline void __hash_vx_info(struct vx_info *vxi)
15170 +{
15171 +       struct hlist_head *head;
15172 +
15173 +       vxd_assert_lock(&vx_info_hash_lock);
15174 +       vxdprintk(VXD_CBIT(xid, 4),
15175 +               "__hash_vx_info: %p[#%d]", vxi, vxi->vx_id);
15176 +       vxh_hash_vx_info(vxi);
15177 +
15178 +       /* context must not be hashed */
15179 +       BUG_ON(vx_info_state(vxi, VXS_HASHED));
15180 +
15181 +       vxi->vx_state |= VXS_HASHED;
15182 +       head = &vx_info_hash[__hashval(vxi->vx_id)];
15183 +       hlist_add_head(&vxi->vx_hlist, head);
15184 +       atomic_inc(&vx_global_cactive);
15185 +}
15186 +
15187 +/*     __unhash_vx_info()
15188 +
15189 +       * remove the vxi from the global hash table
15190 +       * requires the hash_lock to be held                     */
15191 +
15192 +static inline void __unhash_vx_info(struct vx_info *vxi)
15193 +{
15194 +       unsigned long flags;
15195 +
15196 +       vxd_assert_lock(&vx_info_hash_lock);
15197 +       vxdprintk(VXD_CBIT(xid, 4),
15198 +               "__unhash_vx_info: %p[#%d.%d.%d]", vxi, vxi->vx_id,
15199 +               atomic_read(&vxi->vx_usecnt), atomic_read(&vxi->vx_tasks));
15200 +       vxh_unhash_vx_info(vxi);
15201 +
15202 +       /* context must be hashed */
15203 +       BUG_ON(!vx_info_state(vxi, VXS_HASHED));
15204 +       /* but without tasks */
15205 +       BUG_ON(atomic_read(&vxi->vx_tasks));
15206 +
15207 +       vxi->vx_state &= ~VXS_HASHED;
15208 +       hlist_del_init(&vxi->vx_hlist);
15209 +       spin_lock_irqsave(&vx_info_inactive_lock, flags);
15210 +       hlist_add_head(&vxi->vx_hlist, &vx_info_inactive);
15211 +       spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
15212 +       atomic_dec(&vx_global_cactive);
15213 +}
15214 +
15215 +
15216 +/*     __lookup_vx_info()
15217 +
15218 +       * requires the hash_lock to be held
15219 +       * doesn't increment the vx_refcnt                       */
15220 +
15221 +static inline struct vx_info *__lookup_vx_info(vxid_t xid)
15222 +{
15223 +       struct hlist_head *head = &vx_info_hash[__hashval(xid)];
15224 +       struct hlist_node *pos;
15225 +       struct vx_info *vxi;
15226 +
15227 +       vxd_assert_lock(&vx_info_hash_lock);
15228 +       hlist_for_each(pos, head) {
15229 +               vxi = hlist_entry(pos, struct vx_info, vx_hlist);
15230 +
15231 +               if (vxi->vx_id == xid)
15232 +                       goto found;
15233 +       }
15234 +       vxi = NULL;
15235 +found:
15236 +       vxdprintk(VXD_CBIT(xid, 0),
15237 +               "__lookup_vx_info(#%u): %p[#%u]",
15238 +               xid, vxi, vxi ? vxi->vx_id : 0);
15239 +       vxh_lookup_vx_info(vxi, xid);
15240 +       return vxi;
15241 +}
15242 +
15243 +
15244 +/*     __create_vx_info()
15245 +
15246 +       * create the requested context
15247 +       * get(), claim() and hash it                            */
15248 +
15249 +static struct vx_info *__create_vx_info(int id)
15250 +{
15251 +       struct vx_info *new, *vxi = NULL;
15252 +
15253 +       vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id);
15254 +
15255 +       if (!(new = __alloc_vx_info(id)))
15256 +               return ERR_PTR(-ENOMEM);
15257 +
15258 +       /* required to make dynamic xids unique */
15259 +       spin_lock(&vx_info_hash_lock);
15260 +
15261 +       /* static context requested */
15262 +       if ((vxi = __lookup_vx_info(id))) {
15263 +               vxdprintk(VXD_CBIT(xid, 0),
15264 +                       "create_vx_info(%d) = %p (already there)", id, vxi);
15265 +               if (vx_info_flags(vxi, VXF_STATE_SETUP, 0))
15266 +                       vxi = ERR_PTR(-EBUSY);
15267 +               else
15268 +                       vxi = ERR_PTR(-EEXIST);
15269 +               goto out_unlock;
15270 +       }
15271 +       /* new context */
15272 +       vxdprintk(VXD_CBIT(xid, 0),
15273 +               "create_vx_info(%d) = %p (new)", id, new);
15274 +       claim_vx_info(new, NULL);
15275 +       __hash_vx_info(get_vx_info(new));
15276 +       vxi = new, new = NULL;
15277 +
15278 +out_unlock:
15279 +       spin_unlock(&vx_info_hash_lock);
15280 +       vxh_create_vx_info(IS_ERR(vxi) ? NULL : vxi, id);
15281 +       if (new)
15282 +               __dealloc_vx_info(new);
15283 +       return vxi;
15284 +}
15285 +
15286 +
15287 +/*     exported stuff                                          */
15288 +
15289 +
15290 +void unhash_vx_info(struct vx_info *vxi)
15291 +{
15292 +       spin_lock(&vx_info_hash_lock);
15293 +       __unhash_vx_info(vxi);
15294 +       spin_unlock(&vx_info_hash_lock);
15295 +       __shutdown_vx_info(vxi);
15296 +       __wakeup_vx_info(vxi);
15297 +}
15298 +
15299 +
15300 +/*     lookup_vx_info()
15301 +
15302 +       * search for a vx_info and get() it
15303 +       * negative id means current                             */
15304 +
15305 +struct vx_info *lookup_vx_info(int id)
15306 +{
15307 +       struct vx_info *vxi = NULL;
15308 +
15309 +       if (id < 0) {
15310 +               vxi = get_vx_info(current_vx_info());
15311 +       } else if (id > 1) {
15312 +               spin_lock(&vx_info_hash_lock);
15313 +               vxi = get_vx_info(__lookup_vx_info(id));
15314 +               spin_unlock(&vx_info_hash_lock);
15315 +       }
15316 +       return vxi;
15317 +}
15318 +
15319 +/*     xid_is_hashed()
15320 +
15321 +       * verify that xid is still hashed                       */
15322 +
15323 +int xid_is_hashed(vxid_t xid)
15324 +{
15325 +       int hashed;
15326 +
15327 +       spin_lock(&vx_info_hash_lock);
15328 +       hashed = (__lookup_vx_info(xid) != NULL);
15329 +       spin_unlock(&vx_info_hash_lock);
15330 +       return hashed;
15331 +}
15332 +
15333 +#ifdef CONFIG_PROC_FS
15334 +
15335 +/*     get_xid_list()
15336 +
15337 +       * get a subset of hashed xids for proc
15338 +       * assumes size is at least one                          */
15339 +
15340 +int get_xid_list(int index, unsigned int *xids, int size)
15341 +{
15342 +       int hindex, nr_xids = 0;
15343 +
15344 +       /* only show current and children */
15345 +       if (!vx_check(0, VS_ADMIN | VS_WATCH)) {
15346 +               if (index > 0)
15347 +                       return 0;
15348 +               xids[nr_xids] = vx_current_xid();
15349 +               return 1;
15350 +       }
15351 +
15352 +       for (hindex = 0; hindex < VX_HASH_SIZE; hindex++) {
15353 +               struct hlist_head *head = &vx_info_hash[hindex];
15354 +               struct hlist_node *pos;
15355 +
15356 +               spin_lock(&vx_info_hash_lock);
15357 +               hlist_for_each(pos, head) {
15358 +                       struct vx_info *vxi;
15359 +
15360 +                       if (--index > 0)
15361 +                               continue;
15362 +
15363 +                       vxi = hlist_entry(pos, struct vx_info, vx_hlist);
15364 +                       xids[nr_xids] = vxi->vx_id;
15365 +                       if (++nr_xids >= size) {
15366 +                               spin_unlock(&vx_info_hash_lock);
15367 +                               goto out;
15368 +                       }
15369 +               }
15370 +               /* keep the lock time short */
15371 +               spin_unlock(&vx_info_hash_lock);
15372 +       }
15373 +out:
15374 +       return nr_xids;
15375 +}
15376 +#endif
15377 +
15378 +#ifdef CONFIG_VSERVER_DEBUG
15379 +
15380 +void   dump_vx_info_inactive(int level)
15381 +{
15382 +       struct hlist_node *entry, *next;
15383 +
15384 +       hlist_for_each_safe(entry, next, &vx_info_inactive) {
15385 +               struct vx_info *vxi =
15386 +                       list_entry(entry, struct vx_info, vx_hlist);
15387 +
15388 +               dump_vx_info(vxi, level);
15389 +       }
15390 +}
15391 +
15392 +#endif
15393 +
15394 +#if 0
15395 +int vx_migrate_user(struct task_struct *p, struct vx_info *vxi)
15396 +{
15397 +       struct user_struct *new_user, *old_user;
15398 +
15399 +       if (!p || !vxi)
15400 +               BUG();
15401 +
15402 +       if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
15403 +               return -EACCES;
15404 +
15405 +       new_user = alloc_uid(vxi->vx_id, p->uid);
15406 +       if (!new_user)
15407 +               return -ENOMEM;
15408 +
15409 +       old_user = p->user;
15410 +       if (new_user != old_user) {
15411 +               atomic_inc(&new_user->processes);
15412 +               atomic_dec(&old_user->processes);
15413 +               p->user = new_user;
15414 +       }
15415 +       free_uid(old_user);
15416 +       return 0;
15417 +}
15418 +#endif
15419 +
15420 +#if 0
15421 +void vx_mask_cap_bset(struct vx_info *vxi, struct task_struct *p)
15422 +{
15423 +       // p->cap_effective &= vxi->vx_cap_bset;
15424 +       p->cap_effective =
15425 +               cap_intersect(p->cap_effective, vxi->cap_bset);
15426 +       // p->cap_inheritable &= vxi->vx_cap_bset;
15427 +       p->cap_inheritable =
15428 +               cap_intersect(p->cap_inheritable, vxi->cap_bset);
15429 +       // p->cap_permitted &= vxi->vx_cap_bset;
15430 +       p->cap_permitted =
15431 +               cap_intersect(p->cap_permitted, vxi->cap_bset);
15432 +}
15433 +#endif
15434 +
15435 +
15436 +#include <linux/file.h>
15437 +#include <linux/fdtable.h>
15438 +
15439 +static int vx_openfd_task(struct task_struct *tsk)
15440 +{
15441 +       struct files_struct *files = tsk->files;
15442 +       struct fdtable *fdt;
15443 +       const unsigned long *bptr;
15444 +       int count, total;
15445 +
15446 +       /* no rcu_read_lock() because of spin_lock() */
15447 +       spin_lock(&files->file_lock);
15448 +       fdt = files_fdtable(files);
15449 +       bptr = fdt->open_fds;
15450 +       count = fdt->max_fds / (sizeof(unsigned long) * 8);
15451 +       for (total = 0; count > 0; count--) {
15452 +               if (*bptr)
15453 +                       total += hweight_long(*bptr);
15454 +               bptr++;
15455 +       }
15456 +       spin_unlock(&files->file_lock);
15457 +       return total;
15458 +}
15459 +
15460 +
15461 +/*     for *space compatibility */
15462 +
15463 +asmlinkage long sys_unshare(unsigned long);
15464 +
15465 +/*
15466 + *     migrate task to new context
15467 + *     gets vxi, puts old_vxi on change
15468 + *     optionally unshares namespaces (hack)
15469 + */
15470 +
15471 +int vx_migrate_task(struct task_struct *p, struct vx_info *vxi, int unshare)
15472 +{
15473 +       struct vx_info *old_vxi;
15474 +       int ret = 0;
15475 +
15476 +       if (!p || !vxi)
15477 +               BUG();
15478 +
15479 +       vxdprintk(VXD_CBIT(xid, 5),
15480 +               "vx_migrate_task(%p,%p[#%d.%d])", p, vxi,
15481 +               vxi->vx_id, atomic_read(&vxi->vx_usecnt));
15482 +
15483 +       if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0) &&
15484 +               !vx_info_flags(vxi, VXF_STATE_SETUP, 0))
15485 +               return -EACCES;
15486 +
15487 +       if (vx_info_state(vxi, VXS_SHUTDOWN))
15488 +               return -EFAULT;
15489 +
15490 +       old_vxi = task_get_vx_info(p);
15491 +       if (old_vxi == vxi)
15492 +               goto out;
15493 +
15494 +//     if (!(ret = vx_migrate_user(p, vxi))) {
15495 +       {
15496 +               int openfd;
15497 +
15498 +               task_lock(p);
15499 +               openfd = vx_openfd_task(p);
15500 +
15501 +               if (old_vxi) {
15502 +                       atomic_dec(&old_vxi->cvirt.nr_threads);
15503 +                       atomic_dec(&old_vxi->cvirt.nr_running);
15504 +                       __rlim_dec(&old_vxi->limit, RLIMIT_NPROC);
15505 +                       /* FIXME: what about the struct files here? */
15506 +                       __rlim_sub(&old_vxi->limit, VLIMIT_OPENFD, openfd);
15507 +                       /* account for the executable */
15508 +                       __rlim_dec(&old_vxi->limit, VLIMIT_DENTRY);
15509 +               }
15510 +               atomic_inc(&vxi->cvirt.nr_threads);
15511 +               atomic_inc(&vxi->cvirt.nr_running);
15512 +               __rlim_inc(&vxi->limit, RLIMIT_NPROC);
15513 +               /* FIXME: what about the struct files here? */
15514 +               __rlim_add(&vxi->limit, VLIMIT_OPENFD, openfd);
15515 +               /* account for the executable */
15516 +               __rlim_inc(&vxi->limit, VLIMIT_DENTRY);
15517 +
15518 +               if (old_vxi) {
15519 +                       release_vx_info(old_vxi, p);
15520 +                       clr_vx_info(&p->vx_info);
15521 +               }
15522 +               claim_vx_info(vxi, p);
15523 +               set_vx_info(&p->vx_info, vxi);
15524 +               p->xid = vxi->vx_id;
15525 +
15526 +               vxdprintk(VXD_CBIT(xid, 5),
15527 +                       "moved task %p into vxi:%p[#%d]",
15528 +                       p, vxi, vxi->vx_id);
15529 +
15530 +               // vx_mask_cap_bset(vxi, p);
15531 +               task_unlock(p);
15532 +
15533 +               /* hack for *spaces to provide compatibility */
15534 +               if (unshare) {
15535 +                       struct nsproxy *old_nsp, *new_nsp;
15536 +
15537 +                       ret = unshare_nsproxy_namespaces(
15538 +                               CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER,
15539 +                               &new_nsp, NULL, NULL);
15540 +                       if (ret)
15541 +                               goto out;
15542 +
15543 +                       old_nsp = xchg(&p->nsproxy, new_nsp);
15544 +                       vx_set_space(vxi,
15545 +                               CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER, 0);
15546 +                       put_nsproxy(old_nsp);
15547 +               }
15548 +       }
15549 +out:
15550 +       put_vx_info(old_vxi);
15551 +       return ret;
15552 +}
15553 +
15554 +int vx_set_reaper(struct vx_info *vxi, struct task_struct *p)
15555 +{
15556 +       struct task_struct *old_reaper;
15557 +       struct vx_info *reaper_vxi;
15558 +
15559 +       if (!vxi)
15560 +               return -EINVAL;
15561 +
15562 +       vxdprintk(VXD_CBIT(xid, 6),
15563 +               "vx_set_reaper(%p[#%d],%p[#%d,%d])",
15564 +               vxi, vxi->vx_id, p, p->xid, p->pid);
15565 +
15566 +       old_reaper = vxi->vx_reaper;
15567 +       if (old_reaper == p)
15568 +               return 0;
15569 +
15570 +       reaper_vxi = task_get_vx_info(p);
15571 +       if (reaper_vxi && reaper_vxi != vxi) {
15572 +               vxwprintk(1,
15573 +                       "Unsuitable reaper [" VS_Q("%s") ",%u:#%u] "
15574 +                       "for [xid #%u]",
15575 +                       p->comm, p->pid, p->xid, vx_current_xid());
15576 +               goto out;
15577 +       }
15578 +
15579 +       /* set new child reaper */
15580 +       get_task_struct(p);
15581 +       vxi->vx_reaper = p;
15582 +       put_task_struct(old_reaper);
15583 +out:
15584 +       put_vx_info(reaper_vxi);
15585 +       return 0;
15586 +}
15587 +
15588 +int vx_set_init(struct vx_info *vxi, struct task_struct *p)
15589 +{
15590 +       if (!vxi)
15591 +               return -EINVAL;
15592 +
15593 +       vxdprintk(VXD_CBIT(xid, 6),
15594 +               "vx_set_init(%p[#%d],%p[#%d,%d,%d])",
15595 +               vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
15596 +
15597 +       vxi->vx_flags &= ~VXF_STATE_INIT;
15598 +       // vxi->vx_initpid = p->tgid;
15599 +       vxi->vx_initpid = p->pid;
15600 +       return 0;
15601 +}
15602 +
15603 +void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code)
15604 +{
15605 +       vxdprintk(VXD_CBIT(xid, 6),
15606 +               "vx_exit_init(%p[#%d],%p[#%d,%d,%d])",
15607 +               vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
15608 +
15609 +       vxi->exit_code = code;
15610 +       vxi->vx_initpid = 0;
15611 +}
15612 +
15613 +
15614 +void vx_set_persistent(struct vx_info *vxi)
15615 +{
15616 +       vxdprintk(VXD_CBIT(xid, 6),
15617 +               "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id);
15618 +
15619 +       get_vx_info(vxi);
15620 +       claim_vx_info(vxi, NULL);
15621 +}
15622 +
15623 +void vx_clear_persistent(struct vx_info *vxi)
15624 +{
15625 +       vxdprintk(VXD_CBIT(xid, 6),
15626 +               "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id);
15627 +
15628 +       release_vx_info(vxi, NULL);
15629 +       put_vx_info(vxi);
15630 +}
15631 +
15632 +void vx_update_persistent(struct vx_info *vxi)
15633 +{
15634 +       if (vx_info_flags(vxi, VXF_PERSISTENT, 0))
15635 +               vx_set_persistent(vxi);
15636 +       else
15637 +               vx_clear_persistent(vxi);
15638 +}
15639 +
15640 +
15641 +/*     task must be current or locked          */
15642 +
15643 +void   exit_vx_info(struct task_struct *p, int code)
15644 +{
15645 +       struct vx_info *vxi = p->vx_info;
15646 +
15647 +       if (vxi) {
15648 +               atomic_dec(&vxi->cvirt.nr_threads);
15649 +               vx_nproc_dec(p);
15650 +
15651 +               vxi->exit_code = code;
15652 +               release_vx_info(vxi, p);
15653 +       }
15654 +}
15655 +
15656 +void   exit_vx_info_early(struct task_struct *p, int code)
15657 +{
15658 +       struct vx_info *vxi = p->vx_info;
15659 +
15660 +       if (vxi) {
15661 +               if (vxi->vx_initpid == p->pid)
15662 +                       vx_exit_init(vxi, p, code);
15663 +               if (vxi->vx_reaper == p)
15664 +                       vx_set_reaper(vxi, init_pid_ns.child_reaper);
15665 +       }
15666 +}
15667 +
15668 +
15669 +/* vserver syscall commands below here */
15670 +
15671 +/* taks xid and vx_info functions */
15672 +
15673 +#include <asm/uaccess.h>
15674 +
15675 +
15676 +int vc_task_xid(uint32_t id)
15677 +{
15678 +       vxid_t xid;
15679 +
15680 +       if (id) {
15681 +               struct task_struct *tsk;
15682 +
15683 +               rcu_read_lock();
15684 +               tsk = find_task_by_real_pid(id);
15685 +               xid = (tsk) ? tsk->xid : -ESRCH;
15686 +               rcu_read_unlock();
15687 +       } else
15688 +               xid = vx_current_xid();
15689 +       return xid;
15690 +}
15691 +
15692 +
15693 +int vc_vx_info(struct vx_info *vxi, void __user *data)
15694 +{
15695 +       struct vcmd_vx_info_v0 vc_data;
15696 +
15697 +       vc_data.xid = vxi->vx_id;
15698 +       vc_data.initpid = vxi->vx_initpid;
15699 +
15700 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15701 +               return -EFAULT;
15702 +       return 0;
15703 +}
15704 +
15705 +
15706 +int vc_ctx_stat(struct vx_info *vxi, void __user *data)
15707 +{
15708 +       struct vcmd_ctx_stat_v0 vc_data;
15709 +
15710 +       vc_data.usecnt = atomic_read(&vxi->vx_usecnt);
15711 +       vc_data.tasks = atomic_read(&vxi->vx_tasks);
15712 +
15713 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15714 +               return -EFAULT;
15715 +       return 0;
15716 +}
15717 +
15718 +
15719 +/* context functions */
15720 +
15721 +int vc_ctx_create(uint32_t xid, void __user *data)
15722 +{
15723 +       struct vcmd_ctx_create vc_data = { .flagword = VXF_INIT_SET };
15724 +       struct vx_info *new_vxi;
15725 +       int ret;
15726 +
15727 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
15728 +               return -EFAULT;
15729 +
15730 +       if ((xid > MAX_S_CONTEXT) || (xid < 2))
15731 +               return -EINVAL;
15732 +
15733 +       new_vxi = __create_vx_info(xid);
15734 +       if (IS_ERR(new_vxi))
15735 +               return PTR_ERR(new_vxi);
15736 +
15737 +       /* initial flags */
15738 +       new_vxi->vx_flags = vc_data.flagword;
15739 +
15740 +       ret = -ENOEXEC;
15741 +       if (vs_state_change(new_vxi, VSC_STARTUP))
15742 +               goto out;
15743 +
15744 +       ret = vx_migrate_task(current, new_vxi, (!data));
15745 +       if (ret)
15746 +               goto out;
15747 +
15748 +       /* return context id on success */
15749 +       ret = new_vxi->vx_id;
15750 +
15751 +       /* get a reference for persistent contexts */
15752 +       if ((vc_data.flagword & VXF_PERSISTENT))
15753 +               vx_set_persistent(new_vxi);
15754 +out:
15755 +       release_vx_info(new_vxi, NULL);
15756 +       put_vx_info(new_vxi);
15757 +       return ret;
15758 +}
15759 +
15760 +
15761 +int vc_ctx_migrate(struct vx_info *vxi, void __user *data)
15762 +{
15763 +       struct vcmd_ctx_migrate vc_data = { .flagword = 0 };
15764 +       int ret;
15765 +
15766 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
15767 +               return -EFAULT;
15768 +
15769 +       ret = vx_migrate_task(current, vxi, 0);
15770 +       if (ret)
15771 +               return ret;
15772 +       if (vc_data.flagword & VXM_SET_INIT)
15773 +               ret = vx_set_init(vxi, current);
15774 +       if (ret)
15775 +               return ret;
15776 +       if (vc_data.flagword & VXM_SET_REAPER)
15777 +               ret = vx_set_reaper(vxi, current);
15778 +       return ret;
15779 +}
15780 +
15781 +
15782 +int vc_get_cflags(struct vx_info *vxi, void __user *data)
15783 +{
15784 +       struct vcmd_ctx_flags_v0 vc_data;
15785 +
15786 +       vc_data.flagword = vxi->vx_flags;
15787 +
15788 +       /* special STATE flag handling */
15789 +       vc_data.mask = vs_mask_flags(~0ULL, vxi->vx_flags, VXF_ONE_TIME);
15790 +
15791 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15792 +               return -EFAULT;
15793 +       return 0;
15794 +}
15795 +
15796 +int vc_set_cflags(struct vx_info *vxi, void __user *data)
15797 +{
15798 +       struct vcmd_ctx_flags_v0 vc_data;
15799 +       uint64_t mask, trigger;
15800 +
15801 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15802 +               return -EFAULT;
15803 +
15804 +       /* special STATE flag handling */
15805 +       mask = vs_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME);
15806 +       trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword);
15807 +
15808 +       if (vxi == current_vx_info()) {
15809 +               /* if (trigger & VXF_STATE_SETUP)
15810 +                       vx_mask_cap_bset(vxi, current); */
15811 +               if (trigger & VXF_STATE_INIT) {
15812 +                       int ret;
15813 +
15814 +                       ret = vx_set_init(vxi, current);
15815 +                       if (ret)
15816 +                               return ret;
15817 +                       ret = vx_set_reaper(vxi, current);
15818 +                       if (ret)
15819 +                               return ret;
15820 +               }
15821 +       }
15822 +
15823 +       vxi->vx_flags = vs_mask_flags(vxi->vx_flags,
15824 +               vc_data.flagword, mask);
15825 +       if (trigger & VXF_PERSISTENT)
15826 +               vx_update_persistent(vxi);
15827 +
15828 +       return 0;
15829 +}
15830 +
15831 +
15832 +static inline uint64_t caps_from_cap_t(kernel_cap_t c)
15833 +{
15834 +       uint64_t v = c.cap[0] | ((uint64_t)c.cap[1] << 32);
15835 +
15836 +       // printk("caps_from_cap_t(%08x:%08x) = %016llx\n", c.cap[1], c.cap[0], v);
15837 +       return v;
15838 +}
15839 +
15840 +static inline kernel_cap_t cap_t_from_caps(uint64_t v)
15841 +{
15842 +       kernel_cap_t c = __cap_empty_set;
15843 +
15844 +       c.cap[0] = v & 0xFFFFFFFF;
15845 +       c.cap[1] = (v >> 32) & 0xFFFFFFFF;
15846 +
15847 +       // printk("cap_t_from_caps(%016llx) = %08x:%08x\n", v, c.cap[1], c.cap[0]);
15848 +       return c;
15849 +}
15850 +
15851 +
15852 +static int do_get_caps(struct vx_info *vxi, uint64_t *bcaps, uint64_t *ccaps)
15853 +{
15854 +       if (bcaps)
15855 +               *bcaps = caps_from_cap_t(vxi->vx_bcaps);
15856 +       if (ccaps)
15857 +               *ccaps = vxi->vx_ccaps;
15858 +
15859 +       return 0;
15860 +}
15861 +
15862 +int vc_get_ccaps(struct vx_info *vxi, void __user *data)
15863 +{
15864 +       struct vcmd_ctx_caps_v1 vc_data;
15865 +       int ret;
15866 +
15867 +       ret = do_get_caps(vxi, NULL, &vc_data.ccaps);
15868 +       if (ret)
15869 +               return ret;
15870 +       vc_data.cmask = ~0ULL;
15871 +
15872 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15873 +               return -EFAULT;
15874 +       return 0;
15875 +}
15876 +
15877 +static int do_set_caps(struct vx_info *vxi,
15878 +       uint64_t bcaps, uint64_t bmask, uint64_t ccaps, uint64_t cmask)
15879 +{
15880 +       uint64_t bcold = caps_from_cap_t(vxi->vx_bcaps);
15881 +
15882 +#if 0
15883 +       printk("do_set_caps(%16llx, %16llx, %16llx, %16llx)\n",
15884 +               bcaps, bmask, ccaps, cmask);
15885 +#endif
15886 +       vxi->vx_bcaps = cap_t_from_caps(
15887 +               vs_mask_flags(bcold, bcaps, bmask));
15888 +       vxi->vx_ccaps = vs_mask_flags(vxi->vx_ccaps, ccaps, cmask);
15889 +
15890 +       return 0;
15891 +}
15892 +
15893 +int vc_set_ccaps(struct vx_info *vxi, void __user *data)
15894 +{
15895 +       struct vcmd_ctx_caps_v1 vc_data;
15896 +
15897 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15898 +               return -EFAULT;
15899 +
15900 +       return do_set_caps(vxi, 0, 0, vc_data.ccaps, vc_data.cmask);
15901 +}
15902 +
15903 +int vc_get_bcaps(struct vx_info *vxi, void __user *data)
15904 +{
15905 +       struct vcmd_bcaps vc_data;
15906 +       int ret;
15907 +
15908 +       ret = do_get_caps(vxi, &vc_data.bcaps, NULL);
15909 +       if (ret)
15910 +               return ret;
15911 +       vc_data.bmask = ~0ULL;
15912 +
15913 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15914 +               return -EFAULT;
15915 +       return 0;
15916 +}
15917 +
15918 +int vc_set_bcaps(struct vx_info *vxi, void __user *data)
15919 +{
15920 +       struct vcmd_bcaps vc_data;
15921 +
15922 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15923 +               return -EFAULT;
15924 +
15925 +       return do_set_caps(vxi, vc_data.bcaps, vc_data.bmask, 0, 0);
15926 +}
15927 +
15928 +
15929 +int vc_get_umask(struct vx_info *vxi, void __user *data)
15930 +{
15931 +       struct vcmd_umask vc_data;
15932 +
15933 +       vc_data.umask = vxi->vx_umask;
15934 +       vc_data.mask = ~0ULL;
15935 +
15936 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15937 +               return -EFAULT;
15938 +       return 0;
15939 +}
15940 +
15941 +int vc_set_umask(struct vx_info *vxi, void __user *data)
15942 +{
15943 +       struct vcmd_umask vc_data;
15944 +
15945 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15946 +               return -EFAULT;
15947 +
15948 +       vxi->vx_umask = vs_mask_flags(vxi->vx_umask,
15949 +               vc_data.umask, vc_data.mask);
15950 +       return 0;
15951 +}
15952 +
15953 +
15954 +int vc_get_wmask(struct vx_info *vxi, void __user *data)
15955 +{
15956 +       struct vcmd_wmask vc_data;
15957 +
15958 +       vc_data.wmask = vxi->vx_wmask;
15959 +       vc_data.mask = ~0ULL;
15960 +
15961 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15962 +               return -EFAULT;
15963 +       return 0;
15964 +}
15965 +
15966 +int vc_set_wmask(struct vx_info *vxi, void __user *data)
15967 +{
15968 +       struct vcmd_wmask vc_data;
15969 +
15970 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15971 +               return -EFAULT;
15972 +
15973 +       vxi->vx_wmask = vs_mask_flags(vxi->vx_wmask,
15974 +               vc_data.wmask, vc_data.mask);
15975 +       return 0;
15976 +}
15977 +
15978 +
15979 +int vc_get_badness(struct vx_info *vxi, void __user *data)
15980 +{
15981 +       struct vcmd_badness_v0 vc_data;
15982 +
15983 +       vc_data.bias = vxi->vx_badness_bias;
15984 +
15985 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15986 +               return -EFAULT;
15987 +       return 0;
15988 +}
15989 +
15990 +int vc_set_badness(struct vx_info *vxi, void __user *data)
15991 +{
15992 +       struct vcmd_badness_v0 vc_data;
15993 +
15994 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15995 +               return -EFAULT;
15996 +
15997 +       vxi->vx_badness_bias = vc_data.bias;
15998 +       return 0;
15999 +}
16000 +
16001 +#include <linux/module.h>
16002 +
16003 +EXPORT_SYMBOL_GPL(free_vx_info);
16004 +
16005 diff -NurpP --minimal linux-4.1.41/kernel/vserver/cvirt.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/cvirt.c
16006 --- linux-4.1.41/kernel/vserver/cvirt.c 1970-01-01 00:00:00.000000000 +0000
16007 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/cvirt.c     2016-07-05 04:41:47.000000000 +0000
16008 @@ -0,0 +1,313 @@
16009 +/*
16010 + *  linux/kernel/vserver/cvirt.c
16011 + *
16012 + *  Virtual Server: Context Virtualization
16013 + *
16014 + *  Copyright (C) 2004-2007  Herbert Pötzl
16015 + *
16016 + *  V0.01  broken out from limit.c
16017 + *  V0.02  added utsname stuff
16018 + *  V0.03  changed vcmds to vxi arg
16019 + *
16020 + */
16021 +
16022 +#include <linux/types.h>
16023 +#include <linux/utsname.h>
16024 +#include <linux/vs_cvirt.h>
16025 +#include <linux/vserver/switch.h>
16026 +#include <linux/vserver/cvirt_cmd.h>
16027 +
16028 +#include <asm/uaccess.h>
16029 +
16030 +
16031 +void vx_vsi_boottime(struct timespec *boottime)
16032 +{
16033 +       struct vx_info *vxi = current_vx_info();
16034 +
16035 +       set_normalized_timespec(boottime,
16036 +               boottime->tv_sec + vxi->cvirt.bias_uptime.tv_sec,
16037 +               boottime->tv_nsec + vxi->cvirt.bias_uptime.tv_nsec);
16038 +       return;
16039 +}
16040 +
16041 +void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle)
16042 +{
16043 +       struct vx_info *vxi = current_vx_info();
16044 +
16045 +       set_normalized_timespec(uptime,
16046 +               uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec,
16047 +               uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec);
16048 +       if (!idle)
16049 +               return;
16050 +       set_normalized_timespec(idle,
16051 +               idle->tv_sec - vxi->cvirt.bias_idle.tv_sec,
16052 +               idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec);
16053 +       return;
16054 +}
16055 +
16056 +uint64_t vx_idle_jiffies(void)
16057 +{
16058 +       return init_task.utime + init_task.stime;
16059 +}
16060 +
16061 +
16062 +
16063 +static inline uint32_t __update_loadavg(uint32_t load,
16064 +       int wsize, int delta, int n)
16065 +{
16066 +       unsigned long long calc, prev;
16067 +
16068 +       /* just set it to n */
16069 +       if (unlikely(delta >= wsize))
16070 +               return (n << FSHIFT);
16071 +
16072 +       calc = delta * n;
16073 +       calc <<= FSHIFT;
16074 +       prev = (wsize - delta);
16075 +       prev *= load;
16076 +       calc += prev;
16077 +       do_div(calc, wsize);
16078 +       return calc;
16079 +}
16080 +
16081 +
16082 +void vx_update_load(struct vx_info *vxi)
16083 +{
16084 +       uint32_t now, last, delta;
16085 +       unsigned int nr_running, nr_uninterruptible;
16086 +       unsigned int total;
16087 +       unsigned long flags;
16088 +
16089 +       spin_lock_irqsave(&vxi->cvirt.load_lock, flags);
16090 +
16091 +       now = jiffies;
16092 +       last = vxi->cvirt.load_last;
16093 +       delta = now - last;
16094 +
16095 +       if (delta < 5*HZ)
16096 +               goto out;
16097 +
16098 +       nr_running = atomic_read(&vxi->cvirt.nr_running);
16099 +       nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible);
16100 +       total = nr_running + nr_uninterruptible;
16101 +
16102 +       vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0],
16103 +               60*HZ, delta, total);
16104 +       vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
16105 +               5*60*HZ, delta, total);
16106 +       vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
16107 +               15*60*HZ, delta, total);
16108 +
16109 +       vxi->cvirt.load_last = now;
16110 +out:
16111 +       atomic_inc(&vxi->cvirt.load_updates);
16112 +       spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags);
16113 +}
16114 +
16115 +
16116 +/*
16117 + * Commands to do_syslog:
16118 + *
16119 + *      0 -- Close the log.  Currently a NOP.
16120 + *      1 -- Open the log. Currently a NOP.
16121 + *      2 -- Read from the log.
16122 + *      3 -- Read all messages remaining in the ring buffer.
16123 + *      4 -- Read and clear all messages remaining in the ring buffer
16124 + *      5 -- Clear ring buffer.
16125 + *      6 -- Disable printk's to console
16126 + *      7 -- Enable printk's to console
16127 + *      8 -- Set level of messages printed to console
16128 + *      9 -- Return number of unread characters in the log buffer
16129 + *     10 -- Return size of the log buffer
16130 + */
16131 +int vx_do_syslog(int type, char __user *buf, int len)
16132 +{
16133 +       int error = 0;
16134 +       int do_clear = 0;
16135 +       struct vx_info *vxi = current_vx_info();
16136 +       struct _vx_syslog *log;
16137 +
16138 +       if (!vxi)
16139 +               return -EINVAL;
16140 +       log = &vxi->cvirt.syslog;
16141 +
16142 +       switch (type) {
16143 +       case 0:         /* Close log */
16144 +       case 1:         /* Open log */
16145 +               break;
16146 +       case 2:         /* Read from log */
16147 +               error = wait_event_interruptible(log->log_wait,
16148 +                       (log->log_start - log->log_end));
16149 +               if (error)
16150 +                       break;
16151 +               spin_lock_irq(&log->logbuf_lock);
16152 +               spin_unlock_irq(&log->logbuf_lock);
16153 +               break;
16154 +       case 4:         /* Read/clear last kernel messages */
16155 +               do_clear = 1;
16156 +               /* fall through */
16157 +       case 3:         /* Read last kernel messages */
16158 +               return 0;
16159 +
16160 +       case 5:         /* Clear ring buffer */
16161 +               return 0;
16162 +
16163 +       case 6:         /* Disable logging to console */
16164 +       case 7:         /* Enable logging to console */
16165 +       case 8:         /* Set level of messages printed to console */
16166 +               break;
16167 +
16168 +       case 9:         /* Number of chars in the log buffer */
16169 +               return 0;
16170 +       case 10:        /* Size of the log buffer */
16171 +               return 0;
16172 +       default:
16173 +               error = -EINVAL;
16174 +               break;
16175 +       }
16176 +       return error;
16177 +}
16178 +
16179 +
16180 +/* virtual host info names */
16181 +
16182 +static char *vx_vhi_name(struct vx_info *vxi, int id)
16183 +{
16184 +       struct nsproxy *nsproxy;
16185 +       struct uts_namespace *uts;
16186 +
16187 +       if (id == VHIN_CONTEXT)
16188 +               return vxi->vx_name;
16189 +
16190 +       nsproxy = vxi->space[0].vx_nsproxy;
16191 +       if (!nsproxy)
16192 +               return NULL;
16193 +
16194 +       uts = nsproxy->uts_ns;
16195 +       if (!uts)
16196 +               return NULL;
16197 +
16198 +       switch (id) {
16199 +       case VHIN_SYSNAME:
16200 +               return uts->name.sysname;
16201 +       case VHIN_NODENAME:
16202 +               return uts->name.nodename;
16203 +       case VHIN_RELEASE:
16204 +               return uts->name.release;
16205 +       case VHIN_VERSION:
16206 +               return uts->name.version;
16207 +       case VHIN_MACHINE:
16208 +               return uts->name.machine;
16209 +       case VHIN_DOMAINNAME:
16210 +               return uts->name.domainname;
16211 +       default:
16212 +               return NULL;
16213 +       }
16214 +       return NULL;
16215 +}
16216 +
16217 +int vc_set_vhi_name(struct vx_info *vxi, void __user *data)
16218 +{
16219 +       struct vcmd_vhi_name_v0 vc_data;
16220 +       char *name;
16221 +
16222 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16223 +               return -EFAULT;
16224 +
16225 +       name = vx_vhi_name(vxi, vc_data.field);
16226 +       if (!name)
16227 +               return -EINVAL;
16228 +
16229 +       memcpy(name, vc_data.name, 65);
16230 +       return 0;
16231 +}
16232 +
16233 +int vc_get_vhi_name(struct vx_info *vxi, void __user *data)
16234 +{
16235 +       struct vcmd_vhi_name_v0 vc_data;
16236 +       char *name;
16237 +
16238 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16239 +               return -EFAULT;
16240 +
16241 +       name = vx_vhi_name(vxi, vc_data.field);
16242 +       if (!name)
16243 +               return -EINVAL;
16244 +
16245 +       memcpy(vc_data.name, name, 65);
16246 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
16247 +               return -EFAULT;
16248 +       return 0;
16249 +}
16250 +
16251 +
16252 +int vc_virt_stat(struct vx_info *vxi, void __user *data)
16253 +{
16254 +       struct vcmd_virt_stat_v0 vc_data;
16255 +       struct _vx_cvirt *cvirt = &vxi->cvirt;
16256 +       struct timespec uptime;
16257 +
16258 +       do_posix_clock_monotonic_gettime(&uptime);
16259 +       set_normalized_timespec(&uptime,
16260 +               uptime.tv_sec - cvirt->bias_uptime.tv_sec,
16261 +               uptime.tv_nsec - cvirt->bias_uptime.tv_nsec);
16262 +
16263 +       vc_data.offset = timespec_to_ns(&cvirt->bias_ts);
16264 +       vc_data.uptime = timespec_to_ns(&uptime);
16265 +       vc_data.nr_threads = atomic_read(&cvirt->nr_threads);
16266 +       vc_data.nr_running = atomic_read(&cvirt->nr_running);
16267 +       vc_data.nr_uninterruptible = atomic_read(&cvirt->nr_uninterruptible);
16268 +       vc_data.nr_onhold = atomic_read(&cvirt->nr_onhold);
16269 +       vc_data.nr_forks = atomic_read(&cvirt->total_forks);
16270 +       vc_data.load[0] = cvirt->load[0];
16271 +       vc_data.load[1] = cvirt->load[1];
16272 +       vc_data.load[2] = cvirt->load[2];
16273 +
16274 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
16275 +               return -EFAULT;
16276 +       return 0;
16277 +}
16278 +
16279 +
16280 +#ifdef CONFIG_VSERVER_VTIME
16281 +
16282 +/* virtualized time base */
16283 +
16284 +void vx_adjust_timespec(struct timespec *ts)
16285 +{
16286 +       struct vx_info *vxi;
16287 +
16288 +       if (!vx_flags(VXF_VIRT_TIME, 0))
16289 +               return;
16290 +
16291 +       vxi = current_vx_info();
16292 +       ts->tv_sec += vxi->cvirt.bias_ts.tv_sec;
16293 +       ts->tv_nsec += vxi->cvirt.bias_ts.tv_nsec;
16294 +
16295 +       if (ts->tv_nsec >= NSEC_PER_SEC) {
16296 +               ts->tv_sec++;
16297 +               ts->tv_nsec -= NSEC_PER_SEC;
16298 +       } else if (ts->tv_nsec < 0) {
16299 +               ts->tv_sec--;
16300 +               ts->tv_nsec += NSEC_PER_SEC;
16301 +       }
16302 +}
16303 +
16304 +int vx_settimeofday(const struct timespec *ts)
16305 +{
16306 +       struct timespec ats, delta;
16307 +       struct vx_info *vxi;
16308 +
16309 +       if (!vx_flags(VXF_VIRT_TIME, 0))
16310 +               return do_settimeofday(ts);
16311 +
16312 +       getnstimeofday(&ats);
16313 +       delta = timespec_sub(*ts, ats);
16314 +
16315 +       vxi = current_vx_info();
16316 +       vxi->cvirt.bias_ts = timespec_add(vxi->cvirt.bias_ts, delta);
16317 +       return 0;
16318 +}
16319 +
16320 +#endif
16321 +
16322 diff -NurpP --minimal linux-4.1.41/kernel/vserver/cvirt_init.h linux-4.1.41-vs2.3.8.5.3/kernel/vserver/cvirt_init.h
16323 --- linux-4.1.41/kernel/vserver/cvirt_init.h    1970-01-01 00:00:00.000000000 +0000
16324 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/cvirt_init.h        2016-07-05 04:41:47.000000000 +0000
16325 @@ -0,0 +1,70 @@
16326 +
16327 +
16328 +extern uint64_t vx_idle_jiffies(void);
16329 +
16330 +static inline void vx_info_init_cvirt(struct _vx_cvirt *cvirt)
16331 +{
16332 +       uint64_t idle_jiffies = vx_idle_jiffies();
16333 +       uint64_t nsuptime;
16334 +
16335 +       do_posix_clock_monotonic_gettime(&cvirt->bias_uptime);
16336 +       nsuptime = (unsigned long long)cvirt->bias_uptime.tv_sec
16337 +               * NSEC_PER_SEC + cvirt->bias_uptime.tv_nsec;
16338 +       cvirt->bias_clock = nsec_to_clock_t(nsuptime);
16339 +       cvirt->bias_ts.tv_sec = 0;
16340 +       cvirt->bias_ts.tv_nsec = 0;
16341 +
16342 +       jiffies_to_timespec(idle_jiffies, &cvirt->bias_idle);
16343 +       atomic_set(&cvirt->nr_threads, 0);
16344 +       atomic_set(&cvirt->nr_running, 0);
16345 +       atomic_set(&cvirt->nr_uninterruptible, 0);
16346 +       atomic_set(&cvirt->nr_onhold, 0);
16347 +
16348 +       spin_lock_init(&cvirt->load_lock);
16349 +       cvirt->load_last = jiffies;
16350 +       atomic_set(&cvirt->load_updates, 0);
16351 +       cvirt->load[0] = 0;
16352 +       cvirt->load[1] = 0;
16353 +       cvirt->load[2] = 0;
16354 +       atomic_set(&cvirt->total_forks, 0);
16355 +
16356 +       spin_lock_init(&cvirt->syslog.logbuf_lock);
16357 +       init_waitqueue_head(&cvirt->syslog.log_wait);
16358 +       cvirt->syslog.log_start = 0;
16359 +       cvirt->syslog.log_end = 0;
16360 +       cvirt->syslog.con_start = 0;
16361 +       cvirt->syslog.logged_chars = 0;
16362 +}
16363 +
16364 +static inline
16365 +void vx_info_init_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
16366 +{
16367 +       // cvirt_pc->cpustat = { 0 };
16368 +}
16369 +
16370 +static inline void vx_info_exit_cvirt(struct _vx_cvirt *cvirt)
16371 +{
16372 +#ifdef CONFIG_VSERVER_WARN
16373 +       int value;
16374 +#endif
16375 +       vxwprintk_xid((value = atomic_read(&cvirt->nr_threads)),
16376 +               "!!! cvirt: %p[nr_threads] = %d on exit.",
16377 +               cvirt, value);
16378 +       vxwprintk_xid((value = atomic_read(&cvirt->nr_running)),
16379 +               "!!! cvirt: %p[nr_running] = %d on exit.",
16380 +               cvirt, value);
16381 +       vxwprintk_xid((value = atomic_read(&cvirt->nr_uninterruptible)),
16382 +               "!!! cvirt: %p[nr_uninterruptible] = %d on exit.",
16383 +               cvirt, value);
16384 +       vxwprintk_xid((value = atomic_read(&cvirt->nr_onhold)),
16385 +               "!!! cvirt: %p[nr_onhold] = %d on exit.",
16386 +               cvirt, value);
16387 +       return;
16388 +}
16389 +
16390 +static inline
16391 +void vx_info_exit_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
16392 +{
16393 +       return;
16394 +}
16395 +
16396 diff -NurpP --minimal linux-4.1.41/kernel/vserver/cvirt_proc.h linux-4.1.41-vs2.3.8.5.3/kernel/vserver/cvirt_proc.h
16397 --- linux-4.1.41/kernel/vserver/cvirt_proc.h    1970-01-01 00:00:00.000000000 +0000
16398 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/cvirt_proc.h        2016-07-05 04:41:47.000000000 +0000
16399 @@ -0,0 +1,123 @@
16400 +#ifndef _VX_CVIRT_PROC_H
16401 +#define _VX_CVIRT_PROC_H
16402 +
16403 +#include <linux/nsproxy.h>
16404 +#include <linux/mnt_namespace.h>
16405 +#include <linux/ipc_namespace.h>
16406 +#include <linux/utsname.h>
16407 +#include <linux/ipc.h>
16408 +
16409 +extern int vx_info_mnt_namespace(struct mnt_namespace *, char *);
16410 +
16411 +static inline
16412 +int vx_info_proc_nsproxy(struct nsproxy *nsproxy, char *buffer)
16413 +{
16414 +       struct mnt_namespace *ns;
16415 +       struct uts_namespace *uts;
16416 +       struct ipc_namespace *ipc;
16417 +       int length = 0;
16418 +
16419 +       if (!nsproxy)
16420 +               goto out;
16421 +
16422 +       length += sprintf(buffer + length,
16423 +               "NSProxy:\t%p [%p,%p,%p]\n",
16424 +               nsproxy, nsproxy->mnt_ns,
16425 +               nsproxy->uts_ns, nsproxy->ipc_ns);
16426 +
16427 +       ns = nsproxy->mnt_ns;
16428 +       if (!ns)
16429 +               goto skip_ns;
16430 +
16431 +       length += vx_info_mnt_namespace(ns, buffer + length);
16432 +
16433 +skip_ns:
16434 +
16435 +       uts = nsproxy->uts_ns;
16436 +       if (!uts)
16437 +               goto skip_uts;
16438 +
16439 +       length += sprintf(buffer + length,
16440 +               "SysName:\t%.*s\n"
16441 +               "NodeName:\t%.*s\n"
16442 +               "Release:\t%.*s\n"
16443 +               "Version:\t%.*s\n"
16444 +               "Machine:\t%.*s\n"
16445 +               "DomainName:\t%.*s\n",
16446 +               __NEW_UTS_LEN, uts->name.sysname,
16447 +               __NEW_UTS_LEN, uts->name.nodename,
16448 +               __NEW_UTS_LEN, uts->name.release,
16449 +               __NEW_UTS_LEN, uts->name.version,
16450 +               __NEW_UTS_LEN, uts->name.machine,
16451 +               __NEW_UTS_LEN, uts->name.domainname);
16452 +skip_uts:
16453 +
16454 +       ipc = nsproxy->ipc_ns;
16455 +       if (!ipc)
16456 +               goto skip_ipc;
16457 +
16458 +       length += sprintf(buffer + length,
16459 +               "SEMS:\t\t%d %d %d %d  %d\n"
16460 +               "MSG:\t\t%d %d %d\n"
16461 +               "SHM:\t\t%lu %lu  %d %ld\n",
16462 +               ipc->sem_ctls[0], ipc->sem_ctls[1],
16463 +               ipc->sem_ctls[2], ipc->sem_ctls[3],
16464 +               ipc->used_sems,
16465 +               ipc->msg_ctlmax, ipc->msg_ctlmnb, ipc->msg_ctlmni,
16466 +               (unsigned long)ipc->shm_ctlmax,
16467 +               (unsigned long)ipc->shm_ctlall,
16468 +               ipc->shm_ctlmni, ipc->shm_tot);
16469 +skip_ipc:
16470 +out:
16471 +       return length;
16472 +}
16473 +
16474 +
16475 +#include <linux/sched.h>
16476 +
16477 +#define LOAD_INT(x) ((x) >> FSHIFT)
16478 +#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1 - 1)) * 100)
16479 +
16480 +static inline
16481 +int vx_info_proc_cvirt(struct _vx_cvirt *cvirt, char *buffer)
16482 +{
16483 +       int length = 0;
16484 +       int a, b, c;
16485 +
16486 +       length += sprintf(buffer + length,
16487 +               "BiasUptime:\t%lu.%02lu\n",
16488 +               (unsigned long)cvirt->bias_uptime.tv_sec,
16489 +               (cvirt->bias_uptime.tv_nsec / (NSEC_PER_SEC / 100)));
16490 +
16491 +       a = cvirt->load[0] + (FIXED_1 / 200);
16492 +       b = cvirt->load[1] + (FIXED_1 / 200);
16493 +       c = cvirt->load[2] + (FIXED_1 / 200);
16494 +       length += sprintf(buffer + length,
16495 +               "nr_threads:\t%d\n"
16496 +               "nr_running:\t%d\n"
16497 +               "nr_unintr:\t%d\n"
16498 +               "nr_onhold:\t%d\n"
16499 +               "load_updates:\t%d\n"
16500 +               "loadavg:\t%d.%02d %d.%02d %d.%02d\n"
16501 +               "total_forks:\t%d\n",
16502 +               atomic_read(&cvirt->nr_threads),
16503 +               atomic_read(&cvirt->nr_running),
16504 +               atomic_read(&cvirt->nr_uninterruptible),
16505 +               atomic_read(&cvirt->nr_onhold),
16506 +               atomic_read(&cvirt->load_updates),
16507 +               LOAD_INT(a), LOAD_FRAC(a),
16508 +               LOAD_INT(b), LOAD_FRAC(b),
16509 +               LOAD_INT(c), LOAD_FRAC(c),
16510 +               atomic_read(&cvirt->total_forks));
16511 +       return length;
16512 +}
16513 +
16514 +static inline
16515 +int vx_info_proc_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc,
16516 +       char *buffer, int cpu)
16517 +{
16518 +       int length = 0;
16519 +       return length;
16520 +}
16521 +
16522 +#endif /* _VX_CVIRT_PROC_H */
16523 diff -NurpP --minimal linux-4.1.41/kernel/vserver/debug.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/debug.c
16524 --- linux-4.1.41/kernel/vserver/debug.c 1970-01-01 00:00:00.000000000 +0000
16525 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/debug.c     2016-07-05 04:41:47.000000000 +0000
16526 @@ -0,0 +1,32 @@
16527 +/*
16528 + *  kernel/vserver/debug.c
16529 + *
16530 + *  Copyright (C) 2005-2007 Herbert Pötzl
16531 + *
16532 + *  V0.01  vx_info dump support
16533 + *
16534 + */
16535 +
16536 +#include <linux/module.h>
16537 +
16538 +#include <linux/vserver/context.h>
16539 +
16540 +
16541 +void   dump_vx_info(struct vx_info *vxi, int level)
16542 +{
16543 +       printk("vx_info %p[#%d, %d.%d, %4x]\n", vxi, vxi->vx_id,
16544 +               atomic_read(&vxi->vx_usecnt),
16545 +               atomic_read(&vxi->vx_tasks),
16546 +               vxi->vx_state);
16547 +       if (level > 0) {
16548 +               __dump_vx_limit(&vxi->limit);
16549 +               __dump_vx_sched(&vxi->sched);
16550 +               __dump_vx_cvirt(&vxi->cvirt);
16551 +               __dump_vx_cacct(&vxi->cacct);
16552 +       }
16553 +       printk("---\n");
16554 +}
16555 +
16556 +
16557 +EXPORT_SYMBOL_GPL(dump_vx_info);
16558 +
16559 diff -NurpP --minimal linux-4.1.41/kernel/vserver/device.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/device.c
16560 --- linux-4.1.41/kernel/vserver/device.c        1970-01-01 00:00:00.000000000 +0000
16561 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/device.c    2016-07-05 04:41:47.000000000 +0000
16562 @@ -0,0 +1,443 @@
16563 +/*
16564 + *  linux/kernel/vserver/device.c
16565 + *
16566 + *  Linux-VServer: Device Support
16567 + *
16568 + *  Copyright (C) 2006  Herbert Pötzl
16569 + *  Copyright (C) 2007  Daniel Hokka Zakrisson
16570 + *
16571 + *  V0.01  device mapping basics
16572 + *  V0.02  added defaults
16573 + *
16574 + */
16575 +
16576 +#include <linux/slab.h>
16577 +#include <linux/rcupdate.h>
16578 +#include <linux/fs.h>
16579 +#include <linux/namei.h>
16580 +#include <linux/hash.h>
16581 +
16582 +#include <asm/errno.h>
16583 +#include <asm/uaccess.h>
16584 +#include <linux/vserver/base.h>
16585 +#include <linux/vserver/debug.h>
16586 +#include <linux/vserver/context.h>
16587 +#include <linux/vserver/device.h>
16588 +#include <linux/vserver/device_cmd.h>
16589 +
16590 +
16591 +#define DMAP_HASH_BITS 4
16592 +
16593 +
16594 +struct vs_mapping {
16595 +       union {
16596 +               struct hlist_node hlist;
16597 +               struct list_head list;
16598 +       } u;
16599 +#define dm_hlist       u.hlist
16600 +#define dm_list                u.list
16601 +       vxid_t xid;
16602 +       dev_t device;
16603 +       struct vx_dmap_target target;
16604 +};
16605 +
16606 +
16607 +static struct hlist_head dmap_main_hash[1 << DMAP_HASH_BITS];
16608 +
16609 +static DEFINE_SPINLOCK(dmap_main_hash_lock);
16610 +
16611 +static struct vx_dmap_target dmap_defaults[2] = {
16612 +       { .flags = DATTR_OPEN },
16613 +       { .flags = DATTR_OPEN },
16614 +};
16615 +
16616 +
16617 +struct kmem_cache *dmap_cachep __read_mostly;
16618 +
16619 +int __init dmap_cache_init(void)
16620 +{
16621 +       dmap_cachep = kmem_cache_create("dmap_cache",
16622 +               sizeof(struct vs_mapping), 0,
16623 +               SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
16624 +       return 0;
16625 +}
16626 +
16627 +__initcall(dmap_cache_init);
16628 +
16629 +
16630 +static inline unsigned int __hashval(dev_t dev, int bits)
16631 +{
16632 +       return hash_long((unsigned long)dev, bits);
16633 +}
16634 +
16635 +
16636 +/*     __hash_mapping()
16637 + *     add the mapping to the hash table
16638 + */
16639 +static inline void __hash_mapping(struct vx_info *vxi, struct vs_mapping *vdm)
16640 +{
16641 +       spinlock_t *hash_lock = &dmap_main_hash_lock;
16642 +       struct hlist_head *head, *hash = dmap_main_hash;
16643 +       int device = vdm->device;
16644 +
16645 +       spin_lock(hash_lock);
16646 +       vxdprintk(VXD_CBIT(misc, 8), "__hash_mapping: %p[#%d] %08x:%08x",
16647 +               vxi, vxi ? vxi->vx_id : 0, device, vdm->target.target);
16648 +
16649 +       head = &hash[__hashval(device, DMAP_HASH_BITS)];
16650 +       hlist_add_head(&vdm->dm_hlist, head);
16651 +       spin_unlock(hash_lock);
16652 +}
16653 +
16654 +
16655 +static inline int __mode_to_default(umode_t mode)
16656 +{
16657 +       switch (mode) {
16658 +       case S_IFBLK:
16659 +               return 0;
16660 +       case S_IFCHR:
16661 +               return 1;
16662 +       default:
16663 +               BUG();
16664 +       }
16665 +}
16666 +
16667 +
16668 +/*     __set_default()
16669 + *     set a default
16670 + */
16671 +static inline void __set_default(struct vx_info *vxi, umode_t mode,
16672 +       struct vx_dmap_target *vdmt)
16673 +{
16674 +       spinlock_t *hash_lock = &dmap_main_hash_lock;
16675 +       spin_lock(hash_lock);
16676 +
16677 +       if (vxi)
16678 +               vxi->dmap.targets[__mode_to_default(mode)] = *vdmt;
16679 +       else
16680 +               dmap_defaults[__mode_to_default(mode)] = *vdmt;
16681 +
16682 +
16683 +       spin_unlock(hash_lock);
16684 +
16685 +       vxdprintk(VXD_CBIT(misc, 8), "__set_default: %p[#%u] %08x %04x",
16686 +                 vxi, vxi ? vxi->vx_id : 0, vdmt->target, vdmt->flags);
16687 +}
16688 +
16689 +
16690 +/*     __remove_default()
16691 + *     remove a default
16692 + */
16693 +static inline int __remove_default(struct vx_info *vxi, umode_t mode)
16694 +{
16695 +       spinlock_t *hash_lock = &dmap_main_hash_lock;
16696 +       spin_lock(hash_lock);
16697 +
16698 +       if (vxi)
16699 +               vxi->dmap.targets[__mode_to_default(mode)].flags = 0;
16700 +       else    /* remove == reset */
16701 +               dmap_defaults[__mode_to_default(mode)].flags = DATTR_OPEN | mode;
16702 +
16703 +       spin_unlock(hash_lock);
16704 +       return 0;
16705 +}
16706 +
16707 +
16708 +/*     __find_mapping()
16709 + *     find a mapping in the hash table
16710 + *
16711 + *     caller must hold hash_lock
16712 + */
16713 +static inline int __find_mapping(vxid_t xid, dev_t device, umode_t mode,
16714 +       struct vs_mapping **local, struct vs_mapping **global)
16715 +{
16716 +       struct hlist_head *hash = dmap_main_hash;
16717 +       struct hlist_head *head = &hash[__hashval(device, DMAP_HASH_BITS)];
16718 +       struct hlist_node *pos;
16719 +       struct vs_mapping *vdm;
16720 +
16721 +       *local = NULL;
16722 +       if (global)
16723 +               *global = NULL;
16724 +
16725 +       hlist_for_each(pos, head) {
16726 +               vdm = hlist_entry(pos, struct vs_mapping, dm_hlist);
16727 +
16728 +               if ((vdm->device == device) &&
16729 +                       !((vdm->target.flags ^ mode) & S_IFMT)) {
16730 +                       if (vdm->xid == xid) {
16731 +                               *local = vdm;
16732 +                               return 1;
16733 +                       } else if (global && vdm->xid == 0)
16734 +                               *global = vdm;
16735 +               }
16736 +       }
16737 +
16738 +       if (global && *global)
16739 +               return 0;
16740 +       else
16741 +               return -ENOENT;
16742 +}
16743 +
16744 +
16745 +/*     __lookup_mapping()
16746 + *     find a mapping and store the result in target and flags
16747 + */
16748 +static inline int __lookup_mapping(struct vx_info *vxi,
16749 +       dev_t device, dev_t *target, int *flags, umode_t mode)
16750 +{
16751 +       spinlock_t *hash_lock = &dmap_main_hash_lock;
16752 +       struct vs_mapping *vdm, *global;
16753 +       struct vx_dmap_target *vdmt;
16754 +       int ret = 0;
16755 +       vxid_t xid = vxi->vx_id;
16756 +       int index;
16757 +
16758 +       spin_lock(hash_lock);
16759 +       if (__find_mapping(xid, device, mode, &vdm, &global) > 0) {
16760 +               ret = 1;
16761 +               vdmt = &vdm->target;
16762 +               goto found;
16763 +       }
16764 +
16765 +       index = __mode_to_default(mode);
16766 +       if (vxi && vxi->dmap.targets[index].flags) {
16767 +               ret = 2;
16768 +               vdmt = &vxi->dmap.targets[index];
16769 +       } else if (global) {
16770 +               ret = 3;
16771 +               vdmt = &global->target;
16772 +               goto found;
16773 +       } else {
16774 +               ret = 4;
16775 +               vdmt = &dmap_defaults[index];
16776 +       }
16777 +
16778 +found:
16779 +       if (target && (vdmt->flags & DATTR_REMAP))
16780 +               *target = vdmt->target;
16781 +       else if (target)
16782 +               *target = device;
16783 +       if (flags)
16784 +               *flags = vdmt->flags;
16785 +
16786 +       spin_unlock(hash_lock);
16787 +
16788 +       return ret;
16789 +}
16790 +
16791 +
16792 +/*     __remove_mapping()
16793 + *     remove a mapping from the hash table
16794 + */
16795 +static inline int __remove_mapping(struct vx_info *vxi, dev_t device,
16796 +       umode_t mode)
16797 +{
16798 +       spinlock_t *hash_lock = &dmap_main_hash_lock;
16799 +       struct vs_mapping *vdm = NULL;
16800 +       int ret = 0;
16801 +
16802 +       spin_lock(hash_lock);
16803 +
16804 +       ret = __find_mapping((vxi ? vxi->vx_id : 0), device, mode, &vdm,
16805 +               NULL);
16806 +       vxdprintk(VXD_CBIT(misc, 8), "__remove_mapping: %p[#%d] %08x %04x",
16807 +               vxi, vxi ? vxi->vx_id : 0, device, mode);
16808 +       if (ret < 0)
16809 +               goto out;
16810 +       hlist_del(&vdm->dm_hlist);
16811 +
16812 +out:
16813 +       spin_unlock(hash_lock);
16814 +       if (vdm)
16815 +               kmem_cache_free(dmap_cachep, vdm);
16816 +       return ret;
16817 +}
16818 +
16819 +
16820 +
16821 +int vs_map_device(struct vx_info *vxi,
16822 +       dev_t device, dev_t *target, umode_t mode)
16823 +{
16824 +       int ret, flags = DATTR_MASK;
16825 +
16826 +       if (!vxi) {
16827 +               if (target)
16828 +                       *target = device;
16829 +               goto out;
16830 +       }
16831 +       ret = __lookup_mapping(vxi, device, target, &flags, mode);
16832 +       vxdprintk(VXD_CBIT(misc, 8), "vs_map_device: %08x target: %08x flags: %04x mode: %04x mapped=%d",
16833 +               device, target ? *target : 0, flags, mode, ret);
16834 +out:
16835 +       return (flags & DATTR_MASK);
16836 +}
16837 +
16838 +
16839 +
16840 +static int do_set_mapping(struct vx_info *vxi,
16841 +       dev_t device, dev_t target, int flags, umode_t mode)
16842 +{
16843 +       if (device) {
16844 +               struct vs_mapping *new;
16845 +
16846 +               new = kmem_cache_alloc(dmap_cachep, GFP_KERNEL);
16847 +               if (!new)
16848 +                       return -ENOMEM;
16849 +
16850 +               INIT_HLIST_NODE(&new->dm_hlist);
16851 +               new->device = device;
16852 +               new->target.target = target;
16853 +               new->target.flags = flags | mode;
16854 +               new->xid = (vxi ? vxi->vx_id : 0);
16855 +
16856 +               vxdprintk(VXD_CBIT(misc, 8), "do_set_mapping: %08x target: %08x flags: %04x", device, target, flags);
16857 +               __hash_mapping(vxi, new);
16858 +       } else {
16859 +               struct vx_dmap_target new = {
16860 +                       .target = target,
16861 +                       .flags = flags | mode,
16862 +               };
16863 +               __set_default(vxi, mode, &new);
16864 +       }
16865 +       return 0;
16866 +}
16867 +
16868 +
16869 +static int do_unset_mapping(struct vx_info *vxi,
16870 +       dev_t device, dev_t target, int flags, umode_t mode)
16871 +{
16872 +       int ret = -EINVAL;
16873 +
16874 +       if (device) {
16875 +               ret = __remove_mapping(vxi, device, mode);
16876 +               if (ret < 0)
16877 +                       goto out;
16878 +       } else {
16879 +               ret = __remove_default(vxi, mode);
16880 +               if (ret < 0)
16881 +                       goto out;
16882 +       }
16883 +
16884 +out:
16885 +       return ret;
16886 +}
16887 +
16888 +
16889 +static inline int __user_device(const char __user *name, dev_t *dev,
16890 +       umode_t *mode)
16891 +{
16892 +       struct path path;
16893 +       int ret;
16894 +
16895 +       if (!name) {
16896 +               *dev = 0;
16897 +               return 0;
16898 +       }
16899 +       ret = user_lpath(name, &path);
16900 +       if (ret)
16901 +               return ret;
16902 +       if (path.dentry->d_inode) {
16903 +               *dev = path.dentry->d_inode->i_rdev;
16904 +               *mode = path.dentry->d_inode->i_mode;
16905 +       }
16906 +       path_put(&path);
16907 +       return 0;
16908 +}
16909 +
16910 +static inline int __mapping_mode(dev_t device, dev_t target,
16911 +       umode_t device_mode, umode_t target_mode, umode_t *mode)
16912 +{
16913 +       if (device)
16914 +               *mode = device_mode & S_IFMT;
16915 +       else if (target)
16916 +               *mode = target_mode & S_IFMT;
16917 +       else
16918 +               return -EINVAL;
16919 +
16920 +       /* if both given, device and target mode have to match */
16921 +       if (device && target &&
16922 +               ((device_mode ^ target_mode) & S_IFMT))
16923 +               return -EINVAL;
16924 +       return 0;
16925 +}
16926 +
16927 +
16928 +static inline int do_mapping(struct vx_info *vxi, const char __user *device_path,
16929 +       const char __user *target_path, int flags, int set)
16930 +{
16931 +       dev_t device = ~0, target = ~0;
16932 +       umode_t device_mode = 0, target_mode = 0, mode;
16933 +       int ret;
16934 +
16935 +       ret = __user_device(device_path, &device, &device_mode);
16936 +       if (ret)
16937 +               return ret;
16938 +       ret = __user_device(target_path, &target, &target_mode);
16939 +       if (ret)
16940 +               return ret;
16941 +
16942 +       ret = __mapping_mode(device, target,
16943 +               device_mode, target_mode, &mode);
16944 +       if (ret)
16945 +               return ret;
16946 +
16947 +       if (set)
16948 +               return do_set_mapping(vxi, device, target,
16949 +                       flags, mode);
16950 +       else
16951 +               return do_unset_mapping(vxi, device, target,
16952 +                       flags, mode);
16953 +}
16954 +
16955 +
16956 +int vc_set_mapping(struct vx_info *vxi, void __user *data)
16957 +{
16958 +       struct vcmd_set_mapping_v0 vc_data;
16959 +
16960 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16961 +               return -EFAULT;
16962 +
16963 +       return do_mapping(vxi, vc_data.device, vc_data.target,
16964 +               vc_data.flags, 1);
16965 +}
16966 +
16967 +int vc_unset_mapping(struct vx_info *vxi, void __user *data)
16968 +{
16969 +       struct vcmd_set_mapping_v0 vc_data;
16970 +
16971 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16972 +               return -EFAULT;
16973 +
16974 +       return do_mapping(vxi, vc_data.device, vc_data.target,
16975 +               vc_data.flags, 0);
16976 +}
16977 +
16978 +
16979 +#ifdef CONFIG_COMPAT
16980 +
16981 +int vc_set_mapping_x32(struct vx_info *vxi, void __user *data)
16982 +{
16983 +       struct vcmd_set_mapping_v0_x32 vc_data;
16984 +
16985 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16986 +               return -EFAULT;
16987 +
16988 +       return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
16989 +               compat_ptr(vc_data.target_ptr), vc_data.flags, 1);
16990 +}
16991 +
16992 +int vc_unset_mapping_x32(struct vx_info *vxi, void __user *data)
16993 +{
16994 +       struct vcmd_set_mapping_v0_x32 vc_data;
16995 +
16996 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16997 +               return -EFAULT;
16998 +
16999 +       return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
17000 +               compat_ptr(vc_data.target_ptr), vc_data.flags, 0);
17001 +}
17002 +
17003 +#endif /* CONFIG_COMPAT */
17004 +
17005 +
17006 diff -NurpP --minimal linux-4.1.41/kernel/vserver/dlimit.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/dlimit.c
17007 --- linux-4.1.41/kernel/vserver/dlimit.c        1970-01-01 00:00:00.000000000 +0000
17008 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/dlimit.c    2016-07-05 04:41:47.000000000 +0000
17009 @@ -0,0 +1,528 @@
17010 +/*
17011 + *  linux/kernel/vserver/dlimit.c
17012 + *
17013 + *  Virtual Server: Context Disk Limits
17014 + *
17015 + *  Copyright (C) 2004-2009  Herbert Pötzl
17016 + *
17017 + *  V0.01  initial version
17018 + *  V0.02  compat32 splitup
17019 + *  V0.03  extended interface
17020 + *
17021 + */
17022 +
17023 +#include <linux/statfs.h>
17024 +#include <linux/sched.h>
17025 +#include <linux/namei.h>
17026 +#include <linux/vs_tag.h>
17027 +#include <linux/vs_dlimit.h>
17028 +#include <linux/vserver/dlimit_cmd.h>
17029 +#include <linux/slab.h>
17030 +// #include <linux/gfp.h>
17031 +
17032 +#include <asm/uaccess.h>
17033 +
17034 +/*     __alloc_dl_info()
17035 +
17036 +       * allocate an initialized dl_info struct
17037 +       * doesn't make it visible (hash)                        */
17038 +
17039 +static struct dl_info *__alloc_dl_info(struct super_block *sb, vtag_t tag)
17040 +{
17041 +       struct dl_info *new = NULL;
17042 +
17043 +       vxdprintk(VXD_CBIT(dlim, 5),
17044 +               "alloc_dl_info(%p,%d)*", sb, tag);
17045 +
17046 +       /* would this benefit from a slab cache? */
17047 +       new = kmalloc(sizeof(struct dl_info), GFP_KERNEL);
17048 +       if (!new)
17049 +               return 0;
17050 +
17051 +       memset(new, 0, sizeof(struct dl_info));
17052 +       new->dl_tag = tag;
17053 +       new->dl_sb = sb;
17054 +       // INIT_RCU_HEAD(&new->dl_rcu);
17055 +       INIT_HLIST_NODE(&new->dl_hlist);
17056 +       spin_lock_init(&new->dl_lock);
17057 +       atomic_set(&new->dl_refcnt, 0);
17058 +       atomic_set(&new->dl_usecnt, 0);
17059 +
17060 +       /* rest of init goes here */
17061 +
17062 +       vxdprintk(VXD_CBIT(dlim, 4),
17063 +               "alloc_dl_info(%p,%d) = %p", sb, tag, new);
17064 +       return new;
17065 +}
17066 +
17067 +/*     __dealloc_dl_info()
17068 +
17069 +       * final disposal of dl_info                             */
17070 +
17071 +static void __dealloc_dl_info(struct dl_info *dli)
17072 +{
17073 +       vxdprintk(VXD_CBIT(dlim, 4),
17074 +               "dealloc_dl_info(%p)", dli);
17075 +
17076 +       dli->dl_hlist.next = LIST_POISON1;
17077 +       dli->dl_tag = -1;
17078 +       dli->dl_sb = 0;
17079 +
17080 +       BUG_ON(atomic_read(&dli->dl_usecnt));
17081 +       BUG_ON(atomic_read(&dli->dl_refcnt));
17082 +
17083 +       kfree(dli);
17084 +}
17085 +
17086 +
17087 +/*     hash table for dl_info hash */
17088 +
17089 +#define DL_HASH_SIZE   13
17090 +
17091 +struct hlist_head dl_info_hash[DL_HASH_SIZE];
17092 +
17093 +static DEFINE_SPINLOCK(dl_info_hash_lock);
17094 +
17095 +
17096 +static inline unsigned int __hashval(struct super_block *sb, vtag_t tag)
17097 +{
17098 +       return ((tag ^ (unsigned long)sb) % DL_HASH_SIZE);
17099 +}
17100 +
17101 +
17102 +
17103 +/*     __hash_dl_info()
17104 +
17105 +       * add the dli to the global hash table
17106 +       * requires the hash_lock to be held                     */
17107 +
17108 +static inline void __hash_dl_info(struct dl_info *dli)
17109 +{
17110 +       struct hlist_head *head;
17111 +
17112 +       vxdprintk(VXD_CBIT(dlim, 6),
17113 +               "__hash_dl_info: %p[#%d]", dli, dli->dl_tag);
17114 +       get_dl_info(dli);
17115 +       head = &dl_info_hash[__hashval(dli->dl_sb, dli->dl_tag)];
17116 +       hlist_add_head_rcu(&dli->dl_hlist, head);
17117 +}
17118 +
17119 +/*     __unhash_dl_info()
17120 +
17121 +       * remove the dli from the global hash table
17122 +       * requires the hash_lock to be held                     */
17123 +
17124 +static inline void __unhash_dl_info(struct dl_info *dli)
17125 +{
17126 +       vxdprintk(VXD_CBIT(dlim, 6),
17127 +               "__unhash_dl_info: %p[#%d]", dli, dli->dl_tag);
17128 +       hlist_del_rcu(&dli->dl_hlist);
17129 +       put_dl_info(dli);
17130 +}
17131 +
17132 +
17133 +/*     __lookup_dl_info()
17134 +
17135 +       * requires the rcu_read_lock()
17136 +       * doesn't increment the dl_refcnt                       */
17137 +
17138 +static inline struct dl_info *__lookup_dl_info(struct super_block *sb, vtag_t tag)
17139 +{
17140 +       struct hlist_head *head = &dl_info_hash[__hashval(sb, tag)];
17141 +       struct dl_info *dli;
17142 +
17143 +       hlist_for_each_entry_rcu(dli, head, dl_hlist) {
17144 +               if (dli->dl_tag == tag && dli->dl_sb == sb)
17145 +                       return dli;
17146 +       }
17147 +       return NULL;
17148 +}
17149 +
17150 +
17151 +struct dl_info *locate_dl_info(struct super_block *sb, vtag_t tag)
17152 +{
17153 +       struct dl_info *dli;
17154 +
17155 +       rcu_read_lock();
17156 +       dli = get_dl_info(__lookup_dl_info(sb, tag));
17157 +       vxdprintk(VXD_CBIT(dlim, 7),
17158 +               "locate_dl_info(%p,#%d) = %p", sb, tag, dli);
17159 +       rcu_read_unlock();
17160 +       return dli;
17161 +}
17162 +
17163 +void rcu_free_dl_info(struct rcu_head *head)
17164 +{
17165 +       struct dl_info *dli = container_of(head, struct dl_info, dl_rcu);
17166 +       int usecnt, refcnt;
17167 +
17168 +       BUG_ON(!dli || !head);
17169 +
17170 +       usecnt = atomic_read(&dli->dl_usecnt);
17171 +       BUG_ON(usecnt < 0);
17172 +
17173 +       refcnt = atomic_read(&dli->dl_refcnt);
17174 +       BUG_ON(refcnt < 0);
17175 +
17176 +       vxdprintk(VXD_CBIT(dlim, 3),
17177 +               "rcu_free_dl_info(%p)", dli);
17178 +       if (!usecnt)
17179 +               __dealloc_dl_info(dli);
17180 +       else
17181 +               printk("!!! rcu didn't free\n");
17182 +}
17183 +
17184 +
17185 +
17186 +
17187 +static int do_addrem_dlimit(uint32_t id, const char __user *name,
17188 +       uint32_t flags, int add)
17189 +{
17190 +       struct path path;
17191 +       int ret;
17192 +
17193 +       ret = user_lpath(name, &path);
17194 +       if (!ret) {
17195 +               struct super_block *sb;
17196 +               struct dl_info *dli;
17197 +
17198 +               ret = -EINVAL;
17199 +               if (!path.dentry->d_inode)
17200 +                       goto out_release;
17201 +               if (!(sb = path.dentry->d_inode->i_sb))
17202 +                       goto out_release;
17203 +
17204 +               if (add) {
17205 +                       dli = __alloc_dl_info(sb, id);
17206 +                       spin_lock(&dl_info_hash_lock);
17207 +
17208 +                       ret = -EEXIST;
17209 +                       if (__lookup_dl_info(sb, id))
17210 +                               goto out_unlock;
17211 +                       __hash_dl_info(dli);
17212 +                       dli = NULL;
17213 +               } else {
17214 +                       spin_lock(&dl_info_hash_lock);
17215 +                       dli = __lookup_dl_info(sb, id);
17216 +
17217 +                       ret = -ESRCH;
17218 +                       if (!dli)
17219 +                               goto out_unlock;
17220 +                       __unhash_dl_info(dli);
17221 +               }
17222 +               ret = 0;
17223 +       out_unlock:
17224 +               spin_unlock(&dl_info_hash_lock);
17225 +               if (add && dli)
17226 +                       __dealloc_dl_info(dli);
17227 +       out_release:
17228 +               path_put(&path);
17229 +       }
17230 +       return ret;
17231 +}
17232 +
17233 +int vc_add_dlimit(uint32_t id, void __user *data)
17234 +{
17235 +       struct vcmd_ctx_dlimit_base_v0 vc_data;
17236 +
17237 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17238 +               return -EFAULT;
17239 +
17240 +       return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1);
17241 +}
17242 +
17243 +int vc_rem_dlimit(uint32_t id, void __user *data)
17244 +{
17245 +       struct vcmd_ctx_dlimit_base_v0 vc_data;
17246 +
17247 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17248 +               return -EFAULT;
17249 +
17250 +       return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0);
17251 +}
17252 +
17253 +#ifdef CONFIG_COMPAT
17254 +
17255 +int vc_add_dlimit_x32(uint32_t id, void __user *data)
17256 +{
17257 +       struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
17258 +
17259 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17260 +               return -EFAULT;
17261 +
17262 +       return do_addrem_dlimit(id,
17263 +               compat_ptr(vc_data.name_ptr), vc_data.flags, 1);
17264 +}
17265 +
17266 +int vc_rem_dlimit_x32(uint32_t id, void __user *data)
17267 +{
17268 +       struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
17269 +
17270 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17271 +               return -EFAULT;
17272 +
17273 +       return do_addrem_dlimit(id,
17274 +               compat_ptr(vc_data.name_ptr), vc_data.flags, 0);
17275 +}
17276 +
17277 +#endif /* CONFIG_COMPAT */
17278 +
17279 +
17280 +static inline
17281 +int do_set_dlimit(uint32_t id, const char __user *name,
17282 +       uint32_t space_used, uint32_t space_total,
17283 +       uint32_t inodes_used, uint32_t inodes_total,
17284 +       uint32_t reserved, uint32_t flags)
17285 +{
17286 +       struct path path;
17287 +       int ret;
17288 +
17289 +       ret = user_lpath(name, &path);
17290 +       if (!ret) {
17291 +               struct super_block *sb;
17292 +               struct dl_info *dli;
17293 +
17294 +               ret = -EINVAL;
17295 +               if (!path.dentry->d_inode)
17296 +                       goto out_release;
17297 +               if (!(sb = path.dentry->d_inode->i_sb))
17298 +                       goto out_release;
17299 +
17300 +               /* sanity checks */
17301 +               if ((reserved != CDLIM_KEEP &&
17302 +                       reserved > 100) ||
17303 +                       (inodes_used != CDLIM_KEEP &&
17304 +                       inodes_used > inodes_total) ||
17305 +                       (space_used != CDLIM_KEEP &&
17306 +                       space_used > space_total))
17307 +                       goto out_release;
17308 +
17309 +               ret = -ESRCH;
17310 +               dli = locate_dl_info(sb, id);
17311 +               if (!dli)
17312 +                       goto out_release;
17313 +
17314 +               spin_lock(&dli->dl_lock);
17315 +
17316 +               if (inodes_used != CDLIM_KEEP)
17317 +                       dli->dl_inodes_used = inodes_used;
17318 +               if (inodes_total != CDLIM_KEEP)
17319 +                       dli->dl_inodes_total = inodes_total;
17320 +               if (space_used != CDLIM_KEEP)
17321 +                       dli->dl_space_used = dlimit_space_32to64(
17322 +                               space_used, flags, DLIMS_USED);
17323 +
17324 +               if (space_total == CDLIM_INFINITY)
17325 +                       dli->dl_space_total = DLIM_INFINITY;
17326 +               else if (space_total != CDLIM_KEEP)
17327 +                       dli->dl_space_total = dlimit_space_32to64(
17328 +                               space_total, flags, DLIMS_TOTAL);
17329 +
17330 +               if (reserved != CDLIM_KEEP)
17331 +                       dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100;
17332 +
17333 +               spin_unlock(&dli->dl_lock);
17334 +
17335 +               put_dl_info(dli);
17336 +               ret = 0;
17337 +
17338 +       out_release:
17339 +               path_put(&path);
17340 +       }
17341 +       return ret;
17342 +}
17343 +
17344 +int vc_set_dlimit(uint32_t id, void __user *data)
17345 +{
17346 +       struct vcmd_ctx_dlimit_v0 vc_data;
17347 +
17348 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17349 +               return -EFAULT;
17350 +
17351 +       return do_set_dlimit(id, vc_data.name,
17352 +               vc_data.space_used, vc_data.space_total,
17353 +               vc_data.inodes_used, vc_data.inodes_total,
17354 +               vc_data.reserved, vc_data.flags);
17355 +}
17356 +
17357 +#ifdef CONFIG_COMPAT
17358 +
17359 +int vc_set_dlimit_x32(uint32_t id, void __user *data)
17360 +{
17361 +       struct vcmd_ctx_dlimit_v0_x32 vc_data;
17362 +
17363 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17364 +               return -EFAULT;
17365 +
17366 +       return do_set_dlimit(id, compat_ptr(vc_data.name_ptr),
17367 +               vc_data.space_used, vc_data.space_total,
17368 +               vc_data.inodes_used, vc_data.inodes_total,
17369 +               vc_data.reserved, vc_data.flags);
17370 +}
17371 +
17372 +#endif /* CONFIG_COMPAT */
17373 +
17374 +
17375 +static inline
17376 +int do_get_dlimit(uint32_t id, const char __user *name,
17377 +       uint32_t *space_used, uint32_t *space_total,
17378 +       uint32_t *inodes_used, uint32_t *inodes_total,
17379 +       uint32_t *reserved, uint32_t *flags)
17380 +{
17381 +       struct path path;
17382 +       int ret;
17383 +
17384 +       ret = user_lpath(name, &path);
17385 +       if (!ret) {
17386 +               struct super_block *sb;
17387 +               struct dl_info *dli;
17388 +
17389 +               ret = -EINVAL;
17390 +               if (!path.dentry->d_inode)
17391 +                       goto out_release;
17392 +               if (!(sb = path.dentry->d_inode->i_sb))
17393 +                       goto out_release;
17394 +
17395 +               ret = -ESRCH;
17396 +               dli = locate_dl_info(sb, id);
17397 +               if (!dli)
17398 +                       goto out_release;
17399 +
17400 +               spin_lock(&dli->dl_lock);
17401 +               *inodes_used = dli->dl_inodes_used;
17402 +               *inodes_total = dli->dl_inodes_total;
17403 +
17404 +               *space_used = dlimit_space_64to32(
17405 +                       dli->dl_space_used, flags, DLIMS_USED);
17406 +
17407 +               if (dli->dl_space_total == DLIM_INFINITY)
17408 +                       *space_total = CDLIM_INFINITY;
17409 +               else
17410 +                       *space_total = dlimit_space_64to32(
17411 +                               dli->dl_space_total, flags, DLIMS_TOTAL);
17412 +
17413 +               *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10);
17414 +               spin_unlock(&dli->dl_lock);
17415 +
17416 +               put_dl_info(dli);
17417 +               ret = -EFAULT;
17418 +
17419 +               ret = 0;
17420 +       out_release:
17421 +               path_put(&path);
17422 +       }
17423 +       return ret;
17424 +}
17425 +
17426 +
17427 +int vc_get_dlimit(uint32_t id, void __user *data)
17428 +{
17429 +       struct vcmd_ctx_dlimit_v0 vc_data;
17430 +       int ret;
17431 +
17432 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17433 +               return -EFAULT;
17434 +
17435 +       ret = do_get_dlimit(id, vc_data.name,
17436 +               &vc_data.space_used, &vc_data.space_total,
17437 +               &vc_data.inodes_used, &vc_data.inodes_total,
17438 +               &vc_data.reserved, &vc_data.flags);
17439 +       if (ret)
17440 +               return ret;
17441 +
17442 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17443 +               return -EFAULT;
17444 +       return 0;
17445 +}
17446 +
17447 +#ifdef CONFIG_COMPAT
17448 +
17449 +int vc_get_dlimit_x32(uint32_t id, void __user *data)
17450 +{
17451 +       struct vcmd_ctx_dlimit_v0_x32 vc_data;
17452 +       int ret;
17453 +
17454 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17455 +               return -EFAULT;
17456 +
17457 +       ret = do_get_dlimit(id, compat_ptr(vc_data.name_ptr),
17458 +               &vc_data.space_used, &vc_data.space_total,
17459 +               &vc_data.inodes_used, &vc_data.inodes_total,
17460 +               &vc_data.reserved, &vc_data.flags);
17461 +       if (ret)
17462 +               return ret;
17463 +
17464 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17465 +               return -EFAULT;
17466 +       return 0;
17467 +}
17468 +
17469 +#endif /* CONFIG_COMPAT */
17470 +
17471 +
17472 +void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf)
17473 +{
17474 +       struct dl_info *dli;
17475 +       __u64 blimit, bfree, bavail;
17476 +       __u32 ifree;
17477 +
17478 +       dli = locate_dl_info(sb, dx_current_tag());
17479 +       if (!dli)
17480 +               return;
17481 +
17482 +       spin_lock(&dli->dl_lock);
17483 +       if (dli->dl_inodes_total == (unsigned long)DLIM_INFINITY)
17484 +               goto no_ilim;
17485 +
17486 +       /* reduce max inodes available to limit */
17487 +       if (buf->f_files > dli->dl_inodes_total)
17488 +               buf->f_files = dli->dl_inodes_total;
17489 +
17490 +       ifree = dli->dl_inodes_total - dli->dl_inodes_used;
17491 +       /* reduce free inodes to min */
17492 +       if (ifree < buf->f_ffree)
17493 +               buf->f_ffree = ifree;
17494 +
17495 +no_ilim:
17496 +       if (dli->dl_space_total == DLIM_INFINITY)
17497 +               goto no_blim;
17498 +
17499 +       blimit = dli->dl_space_total >> sb->s_blocksize_bits;
17500 +
17501 +       if (dli->dl_space_total < dli->dl_space_used)
17502 +               bfree = 0;
17503 +       else
17504 +               bfree = (dli->dl_space_total - dli->dl_space_used)
17505 +                       >> sb->s_blocksize_bits;
17506 +
17507 +       bavail = ((dli->dl_space_total >> 10) * dli->dl_nrlmult);
17508 +       if (bavail < dli->dl_space_used)
17509 +               bavail = 0;
17510 +       else
17511 +               bavail = (bavail - dli->dl_space_used)
17512 +                       >> sb->s_blocksize_bits;
17513 +
17514 +       /* reduce max space available to limit */
17515 +       if (buf->f_blocks > blimit)
17516 +               buf->f_blocks = blimit;
17517 +
17518 +       /* reduce free space to min */
17519 +       if (bfree < buf->f_bfree)
17520 +               buf->f_bfree = bfree;
17521 +
17522 +       /* reduce avail space to min */
17523 +       if (bavail < buf->f_bavail)
17524 +               buf->f_bavail = bavail;
17525 +
17526 +no_blim:
17527 +       spin_unlock(&dli->dl_lock);
17528 +       put_dl_info(dli);
17529 +
17530 +       return;
17531 +}
17532 +
17533 +#include <linux/module.h>
17534 +
17535 +EXPORT_SYMBOL_GPL(locate_dl_info);
17536 +EXPORT_SYMBOL_GPL(rcu_free_dl_info);
17537 +
17538 diff -NurpP --minimal linux-4.1.41/kernel/vserver/helper.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/helper.c
17539 --- linux-4.1.41/kernel/vserver/helper.c        1970-01-01 00:00:00.000000000 +0000
17540 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/helper.c    2016-07-05 04:41:47.000000000 +0000
17541 @@ -0,0 +1,242 @@
17542 +/*
17543 + *  linux/kernel/vserver/helper.c
17544 + *
17545 + *  Virtual Context Support
17546 + *
17547 + *  Copyright (C) 2004-2007  Herbert Pötzl
17548 + *
17549 + *  V0.01  basic helper
17550 + *
17551 + */
17552 +
17553 +#include <linux/kmod.h>
17554 +#include <linux/reboot.h>
17555 +#include <linux/vs_context.h>
17556 +#include <linux/vs_network.h>
17557 +#include <linux/vserver/signal.h>
17558 +
17559 +
17560 +char vshelper_path[255] = "/sbin/vshelper";
17561 +
17562 +static int vshelper_init(struct subprocess_info *info, struct cred *new_cred)
17563 +{
17564 +       current->flags &= ~PF_NO_SETAFFINITY;
17565 +       return 0;
17566 +}
17567 +
17568 +static int vs_call_usermodehelper(char *path, char **argv, char **envp, int wait)
17569 +{
17570 +       struct subprocess_info *info;
17571 +       gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
17572 +
17573 +       info = call_usermodehelper_setup(path, argv, envp, gfp_mask,
17574 +                                        vshelper_init, NULL, NULL);
17575 +       if (info == NULL)
17576 +               return -ENOMEM;
17577 +
17578 +       return call_usermodehelper_exec(info, wait);
17579 +}
17580 +
17581 +static int do_vshelper(char *name, char *argv[], char *envp[], int sync)
17582 +{
17583 +       int ret;
17584 +
17585 +       if ((ret = vs_call_usermodehelper(name, argv, envp,
17586 +               sync ? UMH_WAIT_PROC : UMH_WAIT_EXEC))) {
17587 +               printk(KERN_WARNING "%s: (%s %s) returned %s with %d\n",
17588 +                       name, argv[1], argv[2],
17589 +                       sync ? "sync" : "async", ret);
17590 +       }
17591 +       vxdprintk(VXD_CBIT(switch, 4),
17592 +               "%s: (%s %s) returned %s with %d",
17593 +               name, argv[1], argv[2], sync ? "sync" : "async", ret);
17594 +       return ret;
17595 +}
17596 +
17597 +/*
17598 + *      vshelper path is set via /proc/sys
17599 + *      invoked by vserver sys_reboot(), with
17600 + *      the following arguments
17601 + *
17602 + *      argv [0] = vshelper_path;
17603 + *      argv [1] = action: "restart", "halt", "poweroff", ...
17604 + *      argv [2] = context identifier
17605 + *
17606 + *      envp [*] = type-specific parameters
17607 + */
17608 +
17609 +long vs_reboot_helper(struct vx_info *vxi, int cmd, void __user *arg)
17610 +{
17611 +       char id_buf[8], cmd_buf[16];
17612 +       char uid_buf[16], pid_buf[16];
17613 +       int ret;
17614 +
17615 +       char *argv[] = {vshelper_path, NULL, id_buf, 0};
17616 +       char *envp[] = {"HOME=/", "TERM=linux",
17617 +                       "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
17618 +                       uid_buf, pid_buf, cmd_buf, 0};
17619 +
17620 +       if (vx_info_state(vxi, VXS_HELPER))
17621 +               return -EAGAIN;
17622 +       vxi->vx_state |= VXS_HELPER;
17623 +
17624 +       snprintf(id_buf, sizeof(id_buf), "%d", vxi->vx_id);
17625 +
17626 +       snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17627 +       snprintf(uid_buf, sizeof(uid_buf), "VS_UID=%d",
17628 +               from_kuid(&init_user_ns, current_uid()));
17629 +       snprintf(pid_buf, sizeof(pid_buf), "VS_PID=%d", current->pid);
17630 +
17631 +       switch (cmd) {
17632 +       case LINUX_REBOOT_CMD_RESTART:
17633 +               argv[1] = "restart";
17634 +               break;
17635 +
17636 +       case LINUX_REBOOT_CMD_HALT:
17637 +               argv[1] = "halt";
17638 +               break;
17639 +
17640 +       case LINUX_REBOOT_CMD_POWER_OFF:
17641 +               argv[1] = "poweroff";
17642 +               break;
17643 +
17644 +       case LINUX_REBOOT_CMD_SW_SUSPEND:
17645 +               argv[1] = "swsusp";
17646 +               break;
17647 +
17648 +       case LINUX_REBOOT_CMD_OOM:
17649 +               argv[1] = "oom";
17650 +               break;
17651 +
17652 +       default:
17653 +               vxi->vx_state &= ~VXS_HELPER;
17654 +               return 0;
17655 +       }
17656 +
17657 +       ret = do_vshelper(vshelper_path, argv, envp, 0);
17658 +       vxi->vx_state &= ~VXS_HELPER;
17659 +       __wakeup_vx_info(vxi);
17660 +       return (ret) ? -EPERM : 0;
17661 +}
17662 +
17663 +
17664 +long vs_reboot(unsigned int cmd, void __user *arg)
17665 +{
17666 +       struct vx_info *vxi = current_vx_info();
17667 +       long ret = 0;
17668 +
17669 +       vxdprintk(VXD_CBIT(misc, 5),
17670 +               "vs_reboot(%p[#%d],%u)",
17671 +               vxi, vxi ? vxi->vx_id : 0, cmd);
17672 +
17673 +       ret = vs_reboot_helper(vxi, cmd, arg);
17674 +       if (ret)
17675 +               return ret;
17676 +
17677 +       vxi->reboot_cmd = cmd;
17678 +       if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
17679 +               switch (cmd) {
17680 +               case LINUX_REBOOT_CMD_RESTART:
17681 +               case LINUX_REBOOT_CMD_HALT:
17682 +               case LINUX_REBOOT_CMD_POWER_OFF:
17683 +                       vx_info_kill(vxi, 0, SIGKILL);
17684 +                       vx_info_kill(vxi, 1, SIGKILL);
17685 +               default:
17686 +                       break;
17687 +               }
17688 +       }
17689 +       return 0;
17690 +}
17691 +
17692 +long vs_oom_action(unsigned int cmd)
17693 +{
17694 +       struct vx_info *vxi = current_vx_info();
17695 +       long ret = 0;
17696 +
17697 +       vxdprintk(VXD_CBIT(misc, 5),
17698 +               "vs_oom_action(%p[#%d],%u)",
17699 +               vxi, vxi ? vxi->vx_id : 0, cmd);
17700 +
17701 +       ret = vs_reboot_helper(vxi, cmd, NULL);
17702 +       if (ret)
17703 +               return ret;
17704 +
17705 +       vxi->reboot_cmd = cmd;
17706 +       if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
17707 +               vx_info_kill(vxi, 0, SIGKILL);
17708 +               vx_info_kill(vxi, 1, SIGKILL);
17709 +       }
17710 +       return 0;
17711 +}
17712 +
17713 +/*
17714 + *      argv [0] = vshelper_path;
17715 + *      argv [1] = action: "startup", "shutdown"
17716 + *      argv [2] = context identifier
17717 + *
17718 + *      envp [*] = type-specific parameters
17719 + */
17720 +
17721 +long vs_state_change(struct vx_info *vxi, unsigned int cmd)
17722 +{
17723 +       char id_buf[8], cmd_buf[16];
17724 +       char *argv[] = {vshelper_path, NULL, id_buf, 0};
17725 +       char *envp[] = {"HOME=/", "TERM=linux",
17726 +                       "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
17727 +
17728 +       if (!vx_info_flags(vxi, VXF_SC_HELPER, 0))
17729 +               return 0;
17730 +
17731 +       snprintf(id_buf, sizeof(id_buf), "%d", vxi->vx_id);
17732 +       snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17733 +
17734 +       switch (cmd) {
17735 +       case VSC_STARTUP:
17736 +               argv[1] = "startup";
17737 +               break;
17738 +       case VSC_SHUTDOWN:
17739 +               argv[1] = "shutdown";
17740 +               break;
17741 +       default:
17742 +               return 0;
17743 +       }
17744 +
17745 +       return do_vshelper(vshelper_path, argv, envp, 1);
17746 +}
17747 +
17748 +
17749 +/*
17750 + *      argv [0] = vshelper_path;
17751 + *      argv [1] = action: "netup", "netdown"
17752 + *      argv [2] = context identifier
17753 + *
17754 + *      envp [*] = type-specific parameters
17755 + */
17756 +
17757 +long vs_net_change(struct nx_info *nxi, unsigned int cmd)
17758 +{
17759 +       char id_buf[8], cmd_buf[16];
17760 +       char *argv[] = {vshelper_path, NULL, id_buf, 0};
17761 +       char *envp[] = {"HOME=/", "TERM=linux",
17762 +                       "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
17763 +
17764 +       if (!nx_info_flags(nxi, NXF_SC_HELPER, 0))
17765 +               return 0;
17766 +
17767 +       snprintf(id_buf, sizeof(id_buf), "%d", nxi->nx_id);
17768 +       snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17769 +
17770 +       switch (cmd) {
17771 +       case VSC_NETUP:
17772 +               argv[1] = "netup";
17773 +               break;
17774 +       case VSC_NETDOWN:
17775 +               argv[1] = "netdown";
17776 +               break;
17777 +       default:
17778 +               return 0;
17779 +       }
17780 +
17781 +       return do_vshelper(vshelper_path, argv, envp, 1);
17782 +}
17783 +
17784 diff -NurpP --minimal linux-4.1.41/kernel/vserver/history.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/history.c
17785 --- linux-4.1.41/kernel/vserver/history.c       1970-01-01 00:00:00.000000000 +0000
17786 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/history.c   2016-07-05 04:41:47.000000000 +0000
17787 @@ -0,0 +1,258 @@
17788 +/*
17789 + *  kernel/vserver/history.c
17790 + *
17791 + *  Virtual Context History Backtrace
17792 + *
17793 + *  Copyright (C) 2004-2007  Herbert Pötzl
17794 + *
17795 + *  V0.01  basic structure
17796 + *  V0.02  hash/unhash and trace
17797 + *  V0.03  preemption fixes
17798 + *
17799 + */
17800 +
17801 +#include <linux/module.h>
17802 +#include <asm/uaccess.h>
17803 +
17804 +#include <linux/vserver/context.h>
17805 +#include <linux/vserver/debug.h>
17806 +#include <linux/vserver/debug_cmd.h>
17807 +#include <linux/vserver/history.h>
17808 +
17809 +
17810 +#ifdef CONFIG_VSERVER_HISTORY
17811 +#define VXH_SIZE       CONFIG_VSERVER_HISTORY_SIZE
17812 +#else
17813 +#define VXH_SIZE       64
17814 +#endif
17815 +
17816 +struct _vx_history {
17817 +       unsigned int counter;
17818 +
17819 +       struct _vx_hist_entry entry[VXH_SIZE + 1];
17820 +};
17821 +
17822 +
17823 +DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
17824 +
17825 +unsigned volatile int vxh_active = 1;
17826 +
17827 +static atomic_t sequence = ATOMIC_INIT(0);
17828 +
17829 +
17830 +/*     vxh_advance()
17831 +
17832 +       * requires disabled preemption                          */
17833 +
17834 +struct _vx_hist_entry *vxh_advance(void *loc)
17835 +{
17836 +       unsigned int cpu = smp_processor_id();
17837 +       struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
17838 +       struct _vx_hist_entry *entry;
17839 +       unsigned int index;
17840 +
17841 +       index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
17842 +       entry = &hist->entry[index];
17843 +
17844 +       entry->seq = atomic_inc_return(&sequence);
17845 +       entry->loc = loc;
17846 +       return entry;
17847 +}
17848 +
17849 +EXPORT_SYMBOL_GPL(vxh_advance);
17850 +
17851 +
17852 +#define VXH_LOC_FMTS   "(#%04x,*%d):%p"
17853 +
17854 +#define VXH_LOC_ARGS(e)        (e)->seq, cpu, (e)->loc
17855 +
17856 +
17857 +#define VXH_VXI_FMTS   "%p[#%d,%d.%d]"
17858 +
17859 +#define VXH_VXI_ARGS(e)        (e)->vxi.ptr,                           \
17860 +                       (e)->vxi.ptr ? (e)->vxi.xid : 0,        \
17861 +                       (e)->vxi.ptr ? (e)->vxi.usecnt : 0,     \
17862 +                       (e)->vxi.ptr ? (e)->vxi.tasks : 0
17863 +
17864 +void   vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
17865 +{
17866 +       switch (e->type) {
17867 +       case VXH_THROW_OOPS:
17868 +               printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
17869 +               break;
17870 +
17871 +       case VXH_GET_VX_INFO:
17872 +       case VXH_PUT_VX_INFO:
17873 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
17874 +                       VXH_LOC_ARGS(e),
17875 +                       (e->type == VXH_GET_VX_INFO) ? "get" : "put",
17876 +                       VXH_VXI_ARGS(e));
17877 +               break;
17878 +
17879 +       case VXH_INIT_VX_INFO:
17880 +       case VXH_SET_VX_INFO:
17881 +       case VXH_CLR_VX_INFO:
17882 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
17883 +                       VXH_LOC_ARGS(e),
17884 +                       (e->type == VXH_INIT_VX_INFO) ? "init" :
17885 +                       ((e->type == VXH_SET_VX_INFO) ? "set" : "clr"),
17886 +                       VXH_VXI_ARGS(e), e->sc.data);
17887 +               break;
17888 +
17889 +       case VXH_CLAIM_VX_INFO:
17890 +       case VXH_RELEASE_VX_INFO:
17891 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
17892 +                       VXH_LOC_ARGS(e),
17893 +                       (e->type == VXH_CLAIM_VX_INFO) ? "claim" : "release",
17894 +                       VXH_VXI_ARGS(e), e->sc.data);
17895 +               break;
17896 +
17897 +       case VXH_ALLOC_VX_INFO:
17898 +       case VXH_DEALLOC_VX_INFO:
17899 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
17900 +                       VXH_LOC_ARGS(e),
17901 +                       (e->type == VXH_ALLOC_VX_INFO) ? "alloc" : "dealloc",
17902 +                       VXH_VXI_ARGS(e));
17903 +               break;
17904 +
17905 +       case VXH_HASH_VX_INFO:
17906 +       case VXH_UNHASH_VX_INFO:
17907 +               printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
17908 +                       VXH_LOC_ARGS(e),
17909 +                       (e->type == VXH_HASH_VX_INFO) ? "hash" : "unhash",
17910 +                       VXH_VXI_ARGS(e));
17911 +               break;
17912 +
17913 +       case VXH_LOC_VX_INFO:
17914 +       case VXH_LOOKUP_VX_INFO:
17915 +       case VXH_CREATE_VX_INFO:
17916 +               printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
17917 +                       VXH_LOC_ARGS(e),
17918 +                       (e->type == VXH_CREATE_VX_INFO) ? "create" :
17919 +                       ((e->type == VXH_LOC_VX_INFO) ? "loc" : "lookup"),
17920 +                       e->ll.arg, VXH_VXI_ARGS(e));
17921 +               break;
17922 +       }
17923 +}
17924 +
17925 +static void __vxh_dump_history(void)
17926 +{
17927 +       unsigned int i, cpu;
17928 +
17929 +       printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
17930 +               atomic_read(&sequence), NR_CPUS);
17931 +
17932 +       for (i = 0; i < VXH_SIZE; i++) {
17933 +               for_each_online_cpu(cpu) {
17934 +                       struct _vx_history *hist =
17935 +                               &per_cpu(vx_history_buffer, cpu);
17936 +                       unsigned int index = (hist->counter - i) % VXH_SIZE;
17937 +                       struct _vx_hist_entry *entry = &hist->entry[index];
17938 +
17939 +                       vxh_dump_entry(entry, cpu);
17940 +               }
17941 +       }
17942 +}
17943 +
17944 +void   vxh_dump_history(void)
17945 +{
17946 +       vxh_active = 0;
17947 +#ifdef CONFIG_SMP
17948 +       local_irq_enable();
17949 +       smp_send_stop();
17950 +       local_irq_disable();
17951 +#endif
17952 +       __vxh_dump_history();
17953 +}
17954 +
17955 +
17956 +/* vserver syscall commands below here */
17957 +
17958 +
17959 +int vc_dump_history(uint32_t id)
17960 +{
17961 +       vxh_active = 0;
17962 +       __vxh_dump_history();
17963 +       vxh_active = 1;
17964 +
17965 +       return 0;
17966 +}
17967 +
17968 +
17969 +int do_read_history(struct __user _vx_hist_entry *data,
17970 +       int cpu, uint32_t *index, uint32_t *count)
17971 +{
17972 +       int pos, ret = 0;
17973 +       struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
17974 +       int end = hist->counter;
17975 +       int start = end - VXH_SIZE + 2;
17976 +       int idx = *index;
17977 +
17978 +       /* special case: get current pos */
17979 +       if (!*count) {
17980 +               *index = end;
17981 +               return 0;
17982 +       }
17983 +
17984 +       /* have we lost some data? */
17985 +       if (idx < start)
17986 +               idx = start;
17987 +
17988 +       for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
17989 +               struct _vx_hist_entry *entry =
17990 +                       &hist->entry[idx % VXH_SIZE];
17991 +
17992 +               /* send entry to userspace */
17993 +               ret = copy_to_user(&data[pos], entry, sizeof(*entry));
17994 +               if (ret)
17995 +                       break;
17996 +       }
17997 +       /* save new index and count */
17998 +       *index = idx;
17999 +       *count = pos;
18000 +       return ret ? ret : (*index < end);
18001 +}
18002 +
18003 +int vc_read_history(uint32_t id, void __user *data)
18004 +{
18005 +       struct vcmd_read_history_v0 vc_data;
18006 +       int ret;
18007 +
18008 +       if (id >= NR_CPUS)
18009 +               return -EINVAL;
18010 +
18011 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18012 +               return -EFAULT;
18013 +
18014 +       ret = do_read_history((struct __user _vx_hist_entry *)vc_data.data,
18015 +               id, &vc_data.index, &vc_data.count);
18016 +
18017 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18018 +               return -EFAULT;
18019 +       return ret;
18020 +}
18021 +
18022 +#ifdef CONFIG_COMPAT
18023 +
18024 +int vc_read_history_x32(uint32_t id, void __user *data)
18025 +{
18026 +       struct vcmd_read_history_v0_x32 vc_data;
18027 +       int ret;
18028 +
18029 +       if (id >= NR_CPUS)
18030 +               return -EINVAL;
18031 +
18032 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18033 +               return -EFAULT;
18034 +
18035 +       ret = do_read_history((struct __user _vx_hist_entry *)
18036 +               compat_ptr(vc_data.data_ptr),
18037 +               id, &vc_data.index, &vc_data.count);
18038 +
18039 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18040 +               return -EFAULT;
18041 +       return ret;
18042 +}
18043 +
18044 +#endif /* CONFIG_COMPAT */
18045 +
18046 diff -NurpP --minimal linux-4.1.41/kernel/vserver/inet.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/inet.c
18047 --- linux-4.1.41/kernel/vserver/inet.c  1970-01-01 00:00:00.000000000 +0000
18048 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/inet.c      2016-07-05 04:41:47.000000000 +0000
18049 @@ -0,0 +1,236 @@
18050 +
18051 +#include <linux/in.h>
18052 +#include <linux/inetdevice.h>
18053 +#include <linux/export.h>
18054 +#include <linux/vs_inet.h>
18055 +#include <linux/vs_inet6.h>
18056 +#include <linux/vserver/debug.h>
18057 +#include <net/route.h>
18058 +#include <net/addrconf.h>
18059 +
18060 +
18061 +int nx_v4_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
18062 +{
18063 +       int ret = 0;
18064 +
18065 +       if (!nxi1 || !nxi2 || nxi1 == nxi2)
18066 +               ret = 1;
18067 +       else {
18068 +               struct nx_addr_v4 *ptr;
18069 +               unsigned long irqflags;
18070 +
18071 +               spin_lock_irqsave(&nxi1->addr_lock, irqflags);
18072 +               for (ptr = &nxi1->v4; ptr; ptr = ptr->next) {
18073 +                       if (v4_nx_addr_in_nx_info(nxi2, ptr, -1)) {
18074 +                               ret = 1;
18075 +                               break;
18076 +                       }
18077 +               }
18078 +               spin_unlock_irqrestore(&nxi1->addr_lock, irqflags);
18079 +       }
18080 +
18081 +       vxdprintk(VXD_CBIT(net, 2),
18082 +               "nx_v4_addr_conflict(%p,%p): %d",
18083 +               nxi1, nxi2, ret);
18084 +
18085 +       return ret;
18086 +}
18087 +
18088 +
18089 +#ifdef CONFIG_IPV6
18090 +
18091 +int nx_v6_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
18092 +{
18093 +       int ret = 0;
18094 +
18095 +       if (!nxi1 || !nxi2 || nxi1 == nxi2)
18096 +               ret = 1;
18097 +       else {
18098 +               struct nx_addr_v6 *ptr;
18099 +               unsigned long irqflags;
18100 +
18101 +               spin_lock_irqsave(&nxi1->addr_lock, irqflags);
18102 +               for (ptr = &nxi1->v6; ptr; ptr = ptr->next) {
18103 +                       if (v6_nx_addr_in_nx_info(nxi2, ptr, -1)) {
18104 +                               ret = 1;
18105 +                               break;
18106 +                       }
18107 +               }
18108 +               spin_unlock_irqrestore(&nxi1->addr_lock, irqflags);
18109 +       }
18110 +
18111 +       vxdprintk(VXD_CBIT(net, 2),
18112 +               "nx_v6_addr_conflict(%p,%p): %d",
18113 +               nxi1, nxi2, ret);
18114 +
18115 +       return ret;
18116 +}
18117 +
18118 +#endif
18119 +
18120 +int v4_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
18121 +{
18122 +       struct in_device *in_dev;
18123 +       struct in_ifaddr **ifap;
18124 +       struct in_ifaddr *ifa;
18125 +       int ret = 0;
18126 +
18127 +       if (!dev)
18128 +               goto out;
18129 +       in_dev = in_dev_get(dev);
18130 +       if (!in_dev)
18131 +               goto out;
18132 +
18133 +       for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
18134 +               ifap = &ifa->ifa_next) {
18135 +               if (v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW)) {
18136 +                       ret = 1;
18137 +                       break;
18138 +               }
18139 +       }
18140 +       in_dev_put(in_dev);
18141 +out:
18142 +       return ret;
18143 +}
18144 +
18145 +
18146 +#ifdef CONFIG_IPV6
18147 +
18148 +int v6_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
18149 +{
18150 +       struct inet6_dev *in_dev;
18151 +       struct inet6_ifaddr *ifa;
18152 +       int ret = 0;
18153 +
18154 +       if (!dev)
18155 +               goto out;
18156 +       in_dev = in6_dev_get(dev);
18157 +       if (!in_dev)
18158 +               goto out;
18159 +
18160 +       // for (ifap = &in_dev->addr_list; (ifa = *ifap) != NULL;
18161 +       list_for_each_entry(ifa, &in_dev->addr_list, if_list) {
18162 +               if (v6_addr_in_nx_info(nxi, &ifa->addr, -1)) {
18163 +                       ret = 1;
18164 +                       break;
18165 +               }
18166 +       }
18167 +       in6_dev_put(in_dev);
18168 +out:
18169 +       return ret;
18170 +}
18171 +
18172 +#endif
18173 +
18174 +int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
18175 +{
18176 +       int ret = 1;
18177 +
18178 +       if (!nxi)
18179 +               goto out;
18180 +       if (nxi->v4.type && v4_dev_in_nx_info(dev, nxi))
18181 +               goto out;
18182 +#ifdef CONFIG_IPV6
18183 +       ret = 2;
18184 +       if (nxi->v6.type && v6_dev_in_nx_info(dev, nxi))
18185 +               goto out;
18186 +#endif
18187 +       ret = 0;
18188 +out:
18189 +       vxdprintk(VXD_CBIT(net, 3),
18190 +               "dev_in_nx_info(%p,%p[#%d]) = %d",
18191 +               dev, nxi, nxi ? nxi->nx_id : 0, ret);
18192 +       return ret;
18193 +}
18194 +
18195 +struct rtable *ip_v4_find_src(struct net *net, struct nx_info *nxi,
18196 +       struct flowi4 *fl4)
18197 +{
18198 +       struct rtable *rt;
18199 +
18200 +       if (!nxi)
18201 +               return NULL;
18202 +
18203 +       /* FIXME: handle lback only case */
18204 +       if (!NX_IPV4(nxi))
18205 +               return ERR_PTR(-EPERM);
18206 +
18207 +       vxdprintk(VXD_CBIT(net, 4),
18208 +               "ip_v4_find_src(%p[#%u]) " NIPQUAD_FMT " -> " NIPQUAD_FMT,
18209 +               nxi, nxi ? nxi->nx_id : 0,
18210 +               NIPQUAD(fl4->saddr), NIPQUAD(fl4->daddr));
18211 +
18212 +       /* single IP is unconditional */
18213 +       if (nx_info_flags(nxi, NXF_SINGLE_IP, 0) &&
18214 +               (fl4->saddr == INADDR_ANY))
18215 +               fl4->saddr = nxi->v4.ip[0].s_addr;
18216 +
18217 +       if (fl4->saddr == INADDR_ANY) {
18218 +               struct nx_addr_v4 *ptr;
18219 +               __be32 found = 0;
18220 +
18221 +               rt = __ip_route_output_key(net, fl4);
18222 +               if (!IS_ERR(rt)) {
18223 +                       found = fl4->saddr;
18224 +                       ip_rt_put(rt);
18225 +                       vxdprintk(VXD_CBIT(net, 4),
18226 +                               "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
18227 +                               nxi, nxi ? nxi->nx_id : 0, fl4->flowi4_oif, NIPQUAD(found));
18228 +                       if (v4_addr_in_nx_info(nxi, found, NXA_MASK_BIND))
18229 +                               goto found;
18230 +               }
18231 +
18232 +               WARN_ON_ONCE(in_irq());
18233 +               spin_lock_bh(&nxi->addr_lock);
18234 +               for (ptr = &nxi->v4; ptr; ptr = ptr->next) {
18235 +                       __be32 primary = ptr->ip[0].s_addr;
18236 +                       __be32 mask = ptr->mask.s_addr;
18237 +                       __be32 neta = primary & mask;
18238 +
18239 +                       vxdprintk(VXD_CBIT(net, 4), "ip_v4_find_src(%p[#%u]) chk: "
18240 +                               NIPQUAD_FMT "/" NIPQUAD_FMT "/" NIPQUAD_FMT,
18241 +                               nxi, nxi ? nxi->nx_id : 0, NIPQUAD(primary),
18242 +                               NIPQUAD(mask), NIPQUAD(neta));
18243 +                       if ((found & mask) != neta)
18244 +                               continue;
18245 +
18246 +                       fl4->saddr = primary;
18247 +                       rt = __ip_route_output_key(net, fl4);
18248 +                       vxdprintk(VXD_CBIT(net, 4),
18249 +                               "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
18250 +                               nxi, nxi ? nxi->nx_id : 0, fl4->flowi4_oif, NIPQUAD(primary));
18251 +                       if (!IS_ERR(rt)) {
18252 +                               found = fl4->saddr;
18253 +                               ip_rt_put(rt);
18254 +                               if (found == primary)
18255 +                                       goto found_unlock;
18256 +                       }
18257 +               }
18258 +               /* still no source ip? */
18259 +               found = ipv4_is_loopback(fl4->daddr)
18260 +                       ? IPI_LOOPBACK : nxi->v4.ip[0].s_addr;
18261 +       found_unlock:
18262 +               spin_unlock_bh(&nxi->addr_lock);
18263 +       found:
18264 +               /* assign src ip to flow */
18265 +               fl4->saddr = found;
18266 +
18267 +       } else {
18268 +               if (!v4_addr_in_nx_info(nxi, fl4->saddr, NXA_MASK_BIND))
18269 +                       return ERR_PTR(-EPERM);
18270 +       }
18271 +
18272 +       if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0)) {
18273 +               if (ipv4_is_loopback(fl4->daddr))
18274 +                       fl4->daddr = nxi->v4_lback.s_addr;
18275 +               if (ipv4_is_loopback(fl4->saddr))
18276 +                       fl4->saddr = nxi->v4_lback.s_addr;
18277 +       } else if (ipv4_is_loopback(fl4->daddr) &&
18278 +               !nx_info_flags(nxi, NXF_LBACK_ALLOW, 0))
18279 +               return ERR_PTR(-EPERM);
18280 +
18281 +       return NULL;
18282 +}
18283 +
18284 +EXPORT_SYMBOL_GPL(ip_v4_find_src);
18285 +
18286 diff -NurpP --minimal linux-4.1.41/kernel/vserver/init.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/init.c
18287 --- linux-4.1.41/kernel/vserver/init.c  1970-01-01 00:00:00.000000000 +0000
18288 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/init.c      2016-07-05 04:41:47.000000000 +0000
18289 @@ -0,0 +1,45 @@
18290 +/*
18291 + *  linux/kernel/init.c
18292 + *
18293 + *  Virtual Server Init
18294 + *
18295 + *  Copyright (C) 2004-2007  Herbert Pötzl
18296 + *
18297 + *  V0.01  basic structure
18298 + *
18299 + */
18300 +
18301 +#include <linux/init.h>
18302 +
18303 +int    vserver_register_sysctl(void);
18304 +void   vserver_unregister_sysctl(void);
18305 +
18306 +
18307 +static int __init init_vserver(void)
18308 +{
18309 +       int ret = 0;
18310 +
18311 +#ifdef CONFIG_VSERVER_DEBUG
18312 +       vserver_register_sysctl();
18313 +#endif
18314 +       return ret;
18315 +}
18316 +
18317 +
18318 +static void __exit exit_vserver(void)
18319 +{
18320 +
18321 +#ifdef CONFIG_VSERVER_DEBUG
18322 +       vserver_unregister_sysctl();
18323 +#endif
18324 +       return;
18325 +}
18326 +
18327 +/* FIXME: GFP_ZONETYPES gone
18328 +long vx_slab[GFP_ZONETYPES]; */
18329 +long vx_area;
18330 +
18331 +
18332 +module_init(init_vserver);
18333 +module_exit(exit_vserver);
18334 +
18335 diff -NurpP --minimal linux-4.1.41/kernel/vserver/inode.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/inode.c
18336 --- linux-4.1.41/kernel/vserver/inode.c 1970-01-01 00:00:00.000000000 +0000
18337 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/inode.c     2017-05-30 07:49:54.000000000 +0000
18338 @@ -0,0 +1,440 @@
18339 +/*
18340 + *  linux/kernel/vserver/inode.c
18341 + *
18342 + *  Virtual Server: File System Support
18343 + *
18344 + *  Copyright (C) 2004-2007  Herbert Pötzl
18345 + *
18346 + *  V0.01  separated from vcontext V0.05
18347 + *  V0.02  moved to tag (instead of xid)
18348 + *
18349 + */
18350 +
18351 +#include <linux/tty.h>
18352 +#include <linux/proc_fs.h>
18353 +#include <linux/devpts_fs.h>
18354 +#include <linux/fs.h>
18355 +#include <linux/file.h>
18356 +#include <linux/mount.h>
18357 +#include <linux/parser.h>
18358 +#include <linux/namei.h>
18359 +#include <linux/magic.h>
18360 +#include <linux/slab.h>
18361 +#include <linux/vserver/inode.h>
18362 +#include <linux/vserver/inode_cmd.h>
18363 +#include <linux/vs_base.h>
18364 +#include <linux/vs_tag.h>
18365 +
18366 +#include <asm/uaccess.h>
18367 +#include <../../fs/proc/internal.h>
18368 +
18369 +
18370 +static int __vc_get_iattr(struct inode *in, uint32_t *tag, uint32_t *flags, uint32_t *mask)
18371 +{
18372 +       struct proc_dir_entry *entry;
18373 +
18374 +       if (!in || !in->i_sb)
18375 +               return -ESRCH;
18376 +
18377 +       *flags = IATTR_TAG
18378 +               | (IS_IMMUTABLE(in) ? IATTR_IMMUTABLE : 0)
18379 +               | (IS_IXUNLINK(in) ? IATTR_IXUNLINK : 0)
18380 +               | (IS_BARRIER(in) ? IATTR_BARRIER : 0)
18381 +               | (IS_COW(in) ? IATTR_COW : 0);
18382 +       *mask = IATTR_IXUNLINK | IATTR_IMMUTABLE | IATTR_COW;
18383 +
18384 +       if (S_ISDIR(in->i_mode))
18385 +               *mask |= IATTR_BARRIER;
18386 +
18387 +       if (IS_TAGGED(in)) {
18388 +               *tag = i_tag_read(in);
18389 +               *mask |= IATTR_TAG;
18390 +       }
18391 +
18392 +       switch (in->i_sb->s_magic) {
18393 +       case PROC_SUPER_MAGIC:
18394 +               entry = PROC_I(in)->pde;
18395 +
18396 +               /* check for specific inodes? */
18397 +               if (entry)
18398 +                       *mask |= IATTR_FLAGS;
18399 +               if (entry)
18400 +                       *flags |= (entry->vx_flags & IATTR_FLAGS);
18401 +               else
18402 +                       *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS);
18403 +               break;
18404 +
18405 +       case DEVPTS_SUPER_MAGIC:
18406 +               *tag = i_tag_read(in);
18407 +               *mask |= IATTR_TAG;
18408 +               break;
18409 +
18410 +       default:
18411 +               break;
18412 +       }
18413 +       return 0;
18414 +}
18415 +
18416 +int vc_get_iattr(void __user *data)
18417 +{
18418 +       struct path path;
18419 +       struct vcmd_ctx_iattr_v1 vc_data = { .tag = -1 };
18420 +       int ret;
18421 +
18422 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18423 +               return -EFAULT;
18424 +
18425 +       ret = user_lpath(vc_data.name, &path);
18426 +       if (!ret) {
18427 +               ret = __vc_get_iattr(path.dentry->d_inode,
18428 +                       &vc_data.tag, &vc_data.flags, &vc_data.mask);
18429 +               path_put(&path);
18430 +       }
18431 +       if (ret)
18432 +               return ret;
18433 +
18434 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18435 +               ret = -EFAULT;
18436 +       return ret;
18437 +}
18438 +
18439 +#ifdef CONFIG_COMPAT
18440 +
18441 +int vc_get_iattr_x32(void __user *data)
18442 +{
18443 +       struct path path;
18444 +       struct vcmd_ctx_iattr_v1_x32 vc_data = { .tag = -1 };
18445 +       int ret;
18446 +
18447 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18448 +               return -EFAULT;
18449 +
18450 +       ret = user_lpath(compat_ptr(vc_data.name_ptr), &path);
18451 +       if (!ret) {
18452 +               ret = __vc_get_iattr(path.dentry->d_inode,
18453 +                       &vc_data.tag, &vc_data.flags, &vc_data.mask);
18454 +               path_put(&path);
18455 +       }
18456 +       if (ret)
18457 +               return ret;
18458 +
18459 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18460 +               ret = -EFAULT;
18461 +       return ret;
18462 +}
18463 +
18464 +#endif /* CONFIG_COMPAT */
18465 +
18466 +
18467 +int vc_fget_iattr(uint32_t fd, void __user *data)
18468 +{
18469 +       struct file *filp;
18470 +       struct vcmd_ctx_fiattr_v0 vc_data = { .tag = -1 };
18471 +       int ret;
18472 +
18473 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18474 +               return -EFAULT;
18475 +
18476 +       filp = fget(fd);
18477 +       if (!filp || !filp->f_path.dentry || !filp->f_path.dentry->d_inode)
18478 +               return -EBADF;
18479 +
18480 +       ret = __vc_get_iattr(filp->f_path.dentry->d_inode,
18481 +               &vc_data.tag, &vc_data.flags, &vc_data.mask);
18482 +
18483 +       fput(filp);
18484 +
18485 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18486 +               ret = -EFAULT;
18487 +       return ret;
18488 +}
18489 +
18490 +
18491 +static int __vc_set_iattr(struct dentry *de, uint32_t *tag, uint32_t *flags, uint32_t *mask)
18492 +{
18493 +       struct inode *in = de->d_inode;
18494 +       int error = 0, is_proc = 0, has_tag = 0;
18495 +       struct iattr attr = { 0 };
18496 +
18497 +       if (!in || !in->i_sb)
18498 +               return -ESRCH;
18499 +
18500 +       is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC);
18501 +       if ((*mask & IATTR_FLAGS) && !is_proc)
18502 +               return -EINVAL;
18503 +
18504 +       has_tag = IS_TAGGED(in) ||
18505 +               (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC);
18506 +       if ((*mask & IATTR_TAG) && !has_tag)
18507 +               return -EINVAL;
18508 +
18509 +       mutex_lock(&in->i_mutex);
18510 +       if (*mask & IATTR_TAG) {
18511 +               attr.ia_tag = make_ktag(&init_user_ns, *tag);
18512 +               attr.ia_valid |= ATTR_TAG;
18513 +       }
18514 +
18515 +       if (*mask & IATTR_FLAGS) {
18516 +               struct proc_dir_entry *entry = PROC_I(in)->pde;
18517 +               unsigned int iflags = PROC_I(in)->vx_flags;
18518 +
18519 +               iflags = (iflags & ~(*mask & IATTR_FLAGS))
18520 +                       | (*flags & IATTR_FLAGS);
18521 +               PROC_I(in)->vx_flags = iflags;
18522 +               if (entry)
18523 +                       entry->vx_flags = iflags;
18524 +       }
18525 +
18526 +       if (*mask & (IATTR_IMMUTABLE | IATTR_IXUNLINK |
18527 +               IATTR_BARRIER | IATTR_COW)) {
18528 +               int iflags = in->i_flags;
18529 +               int vflags = in->i_vflags;
18530 +
18531 +               if (*mask & IATTR_IMMUTABLE) {
18532 +                       if (*flags & IATTR_IMMUTABLE)
18533 +                               iflags |= S_IMMUTABLE;
18534 +                       else
18535 +                               iflags &= ~S_IMMUTABLE;
18536 +               }
18537 +               if (*mask & IATTR_IXUNLINK) {
18538 +                       if (*flags & IATTR_IXUNLINK)
18539 +                               iflags |= S_IXUNLINK;
18540 +                       else
18541 +                               iflags &= ~S_IXUNLINK;
18542 +               }
18543 +               if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) {
18544 +                       if (*flags & IATTR_BARRIER)
18545 +                               vflags |= V_BARRIER;
18546 +                       else
18547 +                               vflags &= ~V_BARRIER;
18548 +               }
18549 +               if (S_ISREG(in->i_mode) && (*mask & IATTR_COW)) {
18550 +                       if (*flags & IATTR_COW)
18551 +                               vflags |= V_COW;
18552 +                       else
18553 +                               vflags &= ~V_COW;
18554 +               }
18555 +               if (in->i_op && in->i_op->sync_flags) {
18556 +                       error = in->i_op->sync_flags(in, iflags, vflags);
18557 +                       if (error)
18558 +                               goto out;
18559 +               }
18560 +       }
18561 +
18562 +       if (attr.ia_valid) {
18563 +               if (in->i_op && in->i_op->setattr)
18564 +                       error = in->i_op->setattr(de, &attr);
18565 +               else {
18566 +                       error = setattr_prepare(de, &attr);
18567 +                       if (!error) {
18568 +                               setattr_copy(in, &attr);
18569 +                               mark_inode_dirty(in);
18570 +                       }
18571 +               }
18572 +       }
18573 +
18574 +out:
18575 +       mutex_unlock(&in->i_mutex);
18576 +       return error;
18577 +}
18578 +
18579 +int vc_set_iattr(void __user *data)
18580 +{
18581 +       struct path path;
18582 +       struct vcmd_ctx_iattr_v1 vc_data;
18583 +       int ret;
18584 +
18585 +       if (!capable(CAP_LINUX_IMMUTABLE))
18586 +               return -EPERM;
18587 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18588 +               return -EFAULT;
18589 +
18590 +       ret = user_lpath(vc_data.name, &path);
18591 +       if (!ret) {
18592 +               ret = __vc_set_iattr(path.dentry,
18593 +                       &vc_data.tag, &vc_data.flags, &vc_data.mask);
18594 +               path_put(&path);
18595 +       }
18596 +
18597 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18598 +               ret = -EFAULT;
18599 +       return ret;
18600 +}
18601 +
18602 +#ifdef CONFIG_COMPAT
18603 +
18604 +int vc_set_iattr_x32(void __user *data)
18605 +{
18606 +       struct path path;
18607 +       struct vcmd_ctx_iattr_v1_x32 vc_data;
18608 +       int ret;
18609 +
18610 +       if (!capable(CAP_LINUX_IMMUTABLE))
18611 +               return -EPERM;
18612 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18613 +               return -EFAULT;
18614 +
18615 +       ret = user_lpath(compat_ptr(vc_data.name_ptr), &path);
18616 +       if (!ret) {
18617 +               ret = __vc_set_iattr(path.dentry,
18618 +                       &vc_data.tag, &vc_data.flags, &vc_data.mask);
18619 +               path_put(&path);
18620 +       }
18621 +
18622 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18623 +               ret = -EFAULT;
18624 +       return ret;
18625 +}
18626 +
18627 +#endif /* CONFIG_COMPAT */
18628 +
18629 +int vc_fset_iattr(uint32_t fd, void __user *data)
18630 +{
18631 +       struct file *filp;
18632 +       struct vcmd_ctx_fiattr_v0 vc_data;
18633 +       int ret;
18634 +
18635 +       if (!capable(CAP_LINUX_IMMUTABLE))
18636 +               return -EPERM;
18637 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18638 +               return -EFAULT;
18639 +
18640 +       filp = fget(fd);
18641 +       if (!filp || !filp->f_path.dentry || !filp->f_path.dentry->d_inode)
18642 +               return -EBADF;
18643 +
18644 +       ret = __vc_set_iattr(filp->f_path.dentry, &vc_data.tag,
18645 +               &vc_data.flags, &vc_data.mask);
18646 +
18647 +       fput(filp);
18648 +
18649 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18650 +               return -EFAULT;
18651 +       return ret;
18652 +}
18653 +
18654 +
18655 +enum { Opt_notagcheck, Opt_tag, Opt_notag, Opt_tagid, Opt_err };
18656 +
18657 +static match_table_t tokens = {
18658 +       {Opt_notagcheck, "notagcheck"},
18659 +#ifdef CONFIG_PROPAGATE
18660 +       {Opt_notag, "notag"},
18661 +       {Opt_tag, "tag"},
18662 +       {Opt_tagid, "tagid=%u"},
18663 +#endif
18664 +       {Opt_err, NULL}
18665 +};
18666 +
18667 +
18668 +static void __dx_parse_remove(char *string, char *opt)
18669 +{
18670 +       char *p = strstr(string, opt);
18671 +       char *q = p;
18672 +
18673 +       if (p) {
18674 +               while (*q != '\0' && *q != ',')
18675 +                       q++;
18676 +               while (*q)
18677 +                       *p++ = *q++;
18678 +               while (*p)
18679 +                       *p++ = '\0';
18680 +       }
18681 +}
18682 +
18683 +int dx_parse_tag(char *string, vtag_t *tag, int remove, int *mnt_flags,
18684 +                unsigned long *flags)
18685 +{
18686 +       int set = 0;
18687 +       substring_t args[MAX_OPT_ARGS];
18688 +       int token;
18689 +       char *s, *p, *opts;
18690 +#if defined(CONFIG_PROPAGATE) || defined(CONFIG_VSERVER_DEBUG)
18691 +       int option = 0;
18692 +#endif
18693 +
18694 +       if (!string)
18695 +               return 0;
18696 +       s = kstrdup(string, GFP_KERNEL | GFP_ATOMIC);
18697 +       if (!s)
18698 +               return 0;
18699 +
18700 +       opts = s;
18701 +       while ((p = strsep(&opts, ",")) != NULL) {
18702 +               token = match_token(p, tokens, args);
18703 +
18704 +               switch (token) {
18705 +#ifdef CONFIG_PROPAGATE
18706 +               case Opt_tag:
18707 +                       if (tag)
18708 +                               *tag = 0;
18709 +                       if (remove)
18710 +                               __dx_parse_remove(s, "tag");
18711 +                       *mnt_flags |= MNT_TAGID;
18712 +                       set |= MNT_TAGID;
18713 +                       break;
18714 +               case Opt_notag:
18715 +                       if (remove)
18716 +                               __dx_parse_remove(s, "notag");
18717 +                       *mnt_flags |= MNT_NOTAG;
18718 +                       set |= MNT_NOTAG;
18719 +                       break;
18720 +               case Opt_tagid:
18721 +                       if (tag && !match_int(args, &option))
18722 +                               *tag = option;
18723 +                       if (remove)
18724 +                               __dx_parse_remove(s, "tagid");
18725 +                       *mnt_flags |= MNT_TAGID;
18726 +                       set |= MNT_TAGID;
18727 +                       break;
18728 +#endif /* CONFIG_PROPAGATE */
18729 +               case Opt_notagcheck:
18730 +                       if (remove)
18731 +                               __dx_parse_remove(s, "notagcheck");
18732 +                       *flags |= MS_NOTAGCHECK;
18733 +                       set |= MS_NOTAGCHECK;
18734 +                       break;
18735 +               }
18736 +               vxdprintk(VXD_CBIT(tag, 7),
18737 +                       "dx_parse_tag(" VS_Q("%s") "): %d:#%d",
18738 +                       p, token, option);
18739 +       }
18740 +       if (set)
18741 +               strcpy(string, s);
18742 +       kfree(s);
18743 +       return set;
18744 +}
18745 +
18746 +#ifdef CONFIG_PROPAGATE
18747 +
18748 +void __dx_propagate_tag(struct nameidata *nd, struct inode *inode)
18749 +{
18750 +       vtag_t new_tag = 0;
18751 +       struct vfsmount *mnt;
18752 +       int propagate;
18753 +
18754 +       if (!nd)
18755 +               return;
18756 +       mnt = nd->path.mnt;
18757 +       if (!mnt)
18758 +               return;
18759 +
18760 +       propagate = (mnt->mnt_flags & MNT_TAGID);
18761 +       if (propagate)
18762 +               new_tag = mnt->mnt_tag;
18763 +
18764 +       vxdprintk(VXD_CBIT(tag, 7),
18765 +               "dx_propagate_tag(%p[#%lu.%d]): %d,%d",
18766 +               inode, inode->i_ino, inode->i_tag,
18767 +               new_tag, (propagate) ? 1 : 0);
18768 +
18769 +       if (propagate)
18770 +               i_tag_write(inode, new_tag);
18771 +}
18772 +
18773 +#include <linux/module.h>
18774 +
18775 +EXPORT_SYMBOL_GPL(__dx_propagate_tag);
18776 +
18777 +#endif /* CONFIG_PROPAGATE */
18778 +
18779 diff -NurpP --minimal linux-4.1.41/kernel/vserver/limit.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/limit.c
18780 --- linux-4.1.41/kernel/vserver/limit.c 1970-01-01 00:00:00.000000000 +0000
18781 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/limit.c     2016-11-12 12:58:54.000000000 +0000
18782 @@ -0,0 +1,343 @@
18783 +/*
18784 + *  linux/kernel/vserver/limit.c
18785 + *
18786 + *  Virtual Server: Context Limits
18787 + *
18788 + *  Copyright (C) 2004-2010  Herbert Pötzl
18789 + *
18790 + *  V0.01  broken out from vcontext V0.05
18791 + *  V0.02  changed vcmds to vxi arg
18792 + *  V0.03  added memory cgroup support
18793 + *
18794 + */
18795 +
18796 +#include <linux/sched.h>
18797 +#include <linux/module.h>
18798 +#include <linux/memcontrol.h>
18799 +#include <linux/page_counter.h>
18800 +#include <linux/vs_limit.h>
18801 +#include <linux/vserver/limit.h>
18802 +#include <linux/vserver/limit_cmd.h>
18803 +
18804 +#include <asm/uaccess.h>
18805 +
18806 +
18807 +const char *vlimit_name[NUM_LIMITS] = {
18808 +       [RLIMIT_CPU]            = "CPU",
18809 +       [RLIMIT_NPROC]          = "NPROC",
18810 +       [RLIMIT_NOFILE]         = "NOFILE",
18811 +       [RLIMIT_LOCKS]          = "LOCKS",
18812 +       [RLIMIT_SIGPENDING]     = "SIGP",
18813 +       [RLIMIT_MSGQUEUE]       = "MSGQ",
18814 +
18815 +       [VLIMIT_NSOCK]          = "NSOCK",
18816 +       [VLIMIT_OPENFD]         = "OPENFD",
18817 +       [VLIMIT_SHMEM]          = "SHMEM",
18818 +       [VLIMIT_DENTRY]         = "DENTRY",
18819 +};
18820 +
18821 +EXPORT_SYMBOL_GPL(vlimit_name);
18822 +
18823 +#define MASK_ENTRY(x)  (1 << (x))
18824 +
18825 +const struct vcmd_ctx_rlimit_mask_v0 vlimit_mask = {
18826 +               /* minimum */
18827 +       0
18828 +       ,       /* softlimit */
18829 +       0
18830 +       ,       /* maximum */
18831 +       MASK_ENTRY( RLIMIT_NPROC        ) |
18832 +       MASK_ENTRY( RLIMIT_NOFILE       ) |
18833 +       MASK_ENTRY( RLIMIT_LOCKS        ) |
18834 +       MASK_ENTRY( RLIMIT_MSGQUEUE     ) |
18835 +
18836 +       MASK_ENTRY( VLIMIT_NSOCK        ) |
18837 +       MASK_ENTRY( VLIMIT_OPENFD       ) |
18838 +       MASK_ENTRY( VLIMIT_SHMEM        ) |
18839 +       MASK_ENTRY( VLIMIT_DENTRY       ) |
18840 +       0
18841 +};
18842 +               /* accounting only */
18843 +uint32_t account_mask =
18844 +       MASK_ENTRY( VLIMIT_SEMARY       ) |
18845 +       MASK_ENTRY( VLIMIT_NSEMS        ) |
18846 +       MASK_ENTRY( VLIMIT_MAPPED       ) |
18847 +       0;
18848 +
18849 +
18850 +static int is_valid_vlimit(int id)
18851 +{
18852 +       uint32_t mask = vlimit_mask.minimum |
18853 +               vlimit_mask.softlimit | vlimit_mask.maximum;
18854 +       return mask & (1 << id);
18855 +}
18856 +
18857 +static int is_accounted_vlimit(int id)
18858 +{
18859 +       if (is_valid_vlimit(id))
18860 +               return 1;
18861 +       return account_mask & (1 << id);
18862 +}
18863 +
18864 +
18865 +static inline uint64_t vc_get_soft(struct vx_info *vxi, int id)
18866 +{
18867 +       rlim_t limit = __rlim_soft(&vxi->limit, id);
18868 +       return VX_VLIM(limit);
18869 +}
18870 +
18871 +static inline uint64_t vc_get_hard(struct vx_info *vxi, int id)
18872 +{
18873 +       rlim_t limit = __rlim_hard(&vxi->limit, id);
18874 +       return VX_VLIM(limit);
18875 +}
18876 +
18877 +static int do_get_rlimit(struct vx_info *vxi, uint32_t id,
18878 +       uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
18879 +{
18880 +       if (!is_valid_vlimit(id))
18881 +               return -EINVAL;
18882 +
18883 +       if (minimum)
18884 +               *minimum = CRLIM_UNSET;
18885 +       if (softlimit)
18886 +               *softlimit = vc_get_soft(vxi, id);
18887 +       if (maximum)
18888 +               *maximum = vc_get_hard(vxi, id);
18889 +       return 0;
18890 +}
18891 +
18892 +int vc_get_rlimit(struct vx_info *vxi, void __user *data)
18893 +{
18894 +       struct vcmd_ctx_rlimit_v0 vc_data;
18895 +       int ret;
18896 +
18897 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18898 +               return -EFAULT;
18899 +
18900 +       ret = do_get_rlimit(vxi, vc_data.id,
18901 +               &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
18902 +       if (ret)
18903 +               return ret;
18904 +
18905 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18906 +               return -EFAULT;
18907 +       return 0;
18908 +}
18909 +
18910 +static int do_set_rlimit(struct vx_info *vxi, uint32_t id,
18911 +       uint64_t minimum, uint64_t softlimit, uint64_t maximum)
18912 +{
18913 +       if (!is_valid_vlimit(id))
18914 +               return -EINVAL;
18915 +
18916 +       if (maximum != CRLIM_KEEP)
18917 +               __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum);
18918 +       if (softlimit != CRLIM_KEEP)
18919 +               __rlim_soft(&vxi->limit, id) = VX_RLIM(softlimit);
18920 +
18921 +       /* clamp soft limit */
18922 +       if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id))
18923 +               __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id);
18924 +
18925 +       return 0;
18926 +}
18927 +
18928 +int vc_set_rlimit(struct vx_info *vxi, void __user *data)
18929 +{
18930 +       struct vcmd_ctx_rlimit_v0 vc_data;
18931 +
18932 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18933 +               return -EFAULT;
18934 +
18935 +       return do_set_rlimit(vxi, vc_data.id,
18936 +               vc_data.minimum, vc_data.softlimit, vc_data.maximum);
18937 +}
18938 +
18939 +#ifdef CONFIG_IA32_EMULATION
18940 +
18941 +int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data)
18942 +{
18943 +       struct vcmd_ctx_rlimit_v0_x32 vc_data;
18944 +
18945 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18946 +               return -EFAULT;
18947 +
18948 +       return do_set_rlimit(vxi, vc_data.id,
18949 +               vc_data.minimum, vc_data.softlimit, vc_data.maximum);
18950 +}
18951 +
18952 +int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data)
18953 +{
18954 +       struct vcmd_ctx_rlimit_v0_x32 vc_data;
18955 +       int ret;
18956 +
18957 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18958 +               return -EFAULT;
18959 +
18960 +       ret = do_get_rlimit(vxi, vc_data.id,
18961 +               &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
18962 +       if (ret)
18963 +               return ret;
18964 +
18965 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18966 +               return -EFAULT;
18967 +       return 0;
18968 +}
18969 +
18970 +#endif /* CONFIG_IA32_EMULATION */
18971 +
18972 +
18973 +int vc_get_rlimit_mask(uint32_t id, void __user *data)
18974 +{
18975 +       if (copy_to_user(data, &vlimit_mask, sizeof(vlimit_mask)))
18976 +               return -EFAULT;
18977 +       return 0;
18978 +}
18979 +
18980 +
18981 +static inline void vx_reset_hits(struct _vx_limit *limit)
18982 +{
18983 +       int lim;
18984 +
18985 +       for (lim = 0; lim < NUM_LIMITS; lim++) {
18986 +               atomic_set(&__rlim_lhit(limit, lim), 0);
18987 +       }
18988 +}
18989 +
18990 +int vc_reset_hits(struct vx_info *vxi, void __user *data)
18991 +{
18992 +       vx_reset_hits(&vxi->limit);
18993 +       return 0;
18994 +}
18995 +
18996 +static inline void vx_reset_minmax(struct _vx_limit *limit)
18997 +{
18998 +       rlim_t value;
18999 +       int lim;
19000 +
19001 +       for (lim = 0; lim < NUM_LIMITS; lim++) {
19002 +               value = __rlim_get(limit, lim);
19003 +               __rlim_rmax(limit, lim) = value;
19004 +               __rlim_rmin(limit, lim) = value;
19005 +       }
19006 +}
19007 +
19008 +int vc_reset_minmax(struct vx_info *vxi, void __user *data)
19009 +{
19010 +       vx_reset_minmax(&vxi->limit);
19011 +       return 0;
19012 +}
19013 +
19014 +
19015 +int vc_rlimit_stat(struct vx_info *vxi, void __user *data)
19016 +{
19017 +       struct vcmd_rlimit_stat_v0 vc_data;
19018 +       struct _vx_limit *limit = &vxi->limit;
19019 +       int id;
19020 +
19021 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
19022 +               return -EFAULT;
19023 +
19024 +       id = vc_data.id;
19025 +       if (!is_accounted_vlimit(id))
19026 +               return -EINVAL;
19027 +
19028 +       vx_limit_fixup(limit, id);
19029 +       vc_data.hits = atomic_read(&__rlim_lhit(limit, id));
19030 +       vc_data.value = __rlim_get(limit, id);
19031 +       vc_data.minimum = __rlim_rmin(limit, id);
19032 +       vc_data.maximum = __rlim_rmax(limit, id);
19033 +
19034 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
19035 +               return -EFAULT;
19036 +       return 0;
19037 +}
19038 +
19039 +
19040 +#ifdef CONFIG_MEMCG
19041 +void vx_vsi_meminfo(struct sysinfo *val)
19042 +{
19043 +       struct mem_cgroup *mcg;
19044 +       u64 res_limit, res_usage;
19045 +
19046 +       rcu_read_lock();
19047 +       mcg = mem_cgroup_from_task(current);
19048 +       rcu_read_unlock();
19049 +       if (!mcg)
19050 +               goto out;
19051 +
19052 +       res_limit = mem_cgroup_mem_limit_pages(mcg);
19053 +       res_usage = mem_cgroup_mem_usage_pages(mcg);
19054 +
19055 +       if (res_limit != PAGE_COUNTER_MAX)
19056 +               val->totalram = res_limit;
19057 +       val->freeram = val->totalram - res_usage;
19058 +       val->bufferram = 0;
19059 +       val->totalhigh = 0;
19060 +       val->freehigh = 0;
19061 +out:
19062 +       return;
19063 +}
19064 +
19065 +void vx_vsi_swapinfo(struct sysinfo *val)
19066 +{
19067 +#ifdef CONFIG_MEMCG_SWAP
19068 +       struct mem_cgroup *mcg;
19069 +       u64 res_limit, res_usage, memsw_limit, memsw_usage;
19070 +       s64 swap_limit, swap_usage;
19071 +
19072 +       rcu_read_lock();
19073 +       mcg = mem_cgroup_from_task(current);
19074 +       rcu_read_unlock();
19075 +       if (!mcg)
19076 +               goto out;
19077 +
19078 +       res_limit = mem_cgroup_mem_limit_pages(mcg);
19079 +       res_usage = mem_cgroup_mem_usage_pages(mcg);
19080 +       memsw_limit = mem_cgroup_memsw_limit_pages(mcg);
19081 +       memsw_usage = mem_cgroup_memsw_usage_pages(mcg);
19082 +
19083 +       /* memory unlimited */
19084 +       if (res_limit == PAGE_COUNTER_MAX)
19085 +               goto out;
19086 +
19087 +       swap_limit = memsw_limit - res_limit;
19088 +       /* we have a swap limit? */
19089 +       if (memsw_limit != PAGE_COUNTER_MAX)
19090 +               val->totalswap = swap_limit;
19091 +
19092 +       /* calculate swap part */
19093 +       swap_usage = (memsw_usage > res_usage) ?
19094 +               memsw_usage - res_usage : 0;
19095 +
19096 +       /* total shown minus usage gives free swap */
19097 +       val->freeswap = (swap_usage < swap_limit) ?
19098 +               val->totalswap - swap_usage : 0;
19099 +out:
19100 +#else  /* !CONFIG_MEMCG_SWAP */
19101 +       val->totalswap = 0;
19102 +       val->freeswap = 0;
19103 +#endif /* !CONFIG_MEMCG_SWAP */
19104 +       return;
19105 +}
19106 +
19107 +long vx_vsi_cached(struct sysinfo *val)
19108 +{
19109 +       long cache = 0;
19110 +#ifdef CONFIG_MEMCG_BROKEN
19111 +       struct mem_cgroup *mcg;
19112 +
19113 +       rcu_read_lock();
19114 +       mcg = mem_cgroup_from_task(current);
19115 +       rcu_read_unlock();
19116 +       if (!mcg)
19117 +               goto out;
19118 +
19119 +       // cache = mem_cgroup_stat_read_cache(mcg);
19120 +out:
19121 +#endif
19122 +       return cache;
19123 +}
19124 +#endif /* !CONFIG_MEMCG */
19125 +
19126 diff -NurpP --minimal linux-4.1.41/kernel/vserver/limit_init.h linux-4.1.41-vs2.3.8.5.3/kernel/vserver/limit_init.h
19127 --- linux-4.1.41/kernel/vserver/limit_init.h    1970-01-01 00:00:00.000000000 +0000
19128 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/limit_init.h        2016-07-05 04:41:47.000000000 +0000
19129 @@ -0,0 +1,31 @@
19130 +
19131 +
19132 +static inline void vx_info_init_limit(struct _vx_limit *limit)
19133 +{
19134 +       int lim;
19135 +
19136 +       for (lim = 0; lim < NUM_LIMITS; lim++) {
19137 +               __rlim_soft(limit, lim) = RLIM_INFINITY;
19138 +               __rlim_hard(limit, lim) = RLIM_INFINITY;
19139 +               __rlim_set(limit, lim, 0);
19140 +               atomic_set(&__rlim_lhit(limit, lim), 0);
19141 +               __rlim_rmin(limit, lim) = 0;
19142 +               __rlim_rmax(limit, lim) = 0;
19143 +       }
19144 +}
19145 +
19146 +static inline void vx_info_exit_limit(struct _vx_limit *limit)
19147 +{
19148 +       rlim_t value;
19149 +       int lim;
19150 +
19151 +       for (lim = 0; lim < NUM_LIMITS; lim++) {
19152 +               if ((1 << lim) & VLIM_NOCHECK)
19153 +                       continue;
19154 +               value = __rlim_get(limit, lim);
19155 +               vxwprintk_xid(value,
19156 +                       "!!! limit: %p[%s,%d] = %ld on exit.",
19157 +                       limit, vlimit_name[lim], lim, (long)value);
19158 +       }
19159 +}
19160 +
19161 diff -NurpP --minimal linux-4.1.41/kernel/vserver/limit_proc.h linux-4.1.41-vs2.3.8.5.3/kernel/vserver/limit_proc.h
19162 --- linux-4.1.41/kernel/vserver/limit_proc.h    1970-01-01 00:00:00.000000000 +0000
19163 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/limit_proc.h        2016-07-05 04:41:47.000000000 +0000
19164 @@ -0,0 +1,57 @@
19165 +#ifndef _VX_LIMIT_PROC_H
19166 +#define _VX_LIMIT_PROC_H
19167 +
19168 +#include <linux/vserver/limit_int.h>
19169 +
19170 +
19171 +#define VX_LIMIT_FMT   ":\t%8ld\t%8ld/%8ld\t%8lld/%8lld\t%6d\n"
19172 +#define VX_LIMIT_TOP   \
19173 +       "Limit\t current\t     min/max\t\t    soft/hard\t\thits\n"
19174 +
19175 +#define VX_LIMIT_ARG(r)                                \
19176 +       (unsigned long)__rlim_get(limit, r),    \
19177 +       (unsigned long)__rlim_rmin(limit, r),   \
19178 +       (unsigned long)__rlim_rmax(limit, r),   \
19179 +       VX_VLIM(__rlim_soft(limit, r)),         \
19180 +       VX_VLIM(__rlim_hard(limit, r)),         \
19181 +       atomic_read(&__rlim_lhit(limit, r))
19182 +
19183 +static inline int vx_info_proc_limit(struct _vx_limit *limit, char *buffer)
19184 +{
19185 +       vx_limit_fixup(limit, -1);
19186 +       return sprintf(buffer, VX_LIMIT_TOP
19187 +               "PROC"  VX_LIMIT_FMT
19188 +               "VM"    VX_LIMIT_FMT
19189 +               "VML"   VX_LIMIT_FMT
19190 +               "RSS"   VX_LIMIT_FMT
19191 +               "ANON"  VX_LIMIT_FMT
19192 +               "RMAP"  VX_LIMIT_FMT
19193 +               "FILES" VX_LIMIT_FMT
19194 +               "OFD"   VX_LIMIT_FMT
19195 +               "LOCKS" VX_LIMIT_FMT
19196 +               "SOCK"  VX_LIMIT_FMT
19197 +               "MSGQ"  VX_LIMIT_FMT
19198 +               "SHM"   VX_LIMIT_FMT
19199 +               "SEMA"  VX_LIMIT_FMT
19200 +               "SEMS"  VX_LIMIT_FMT
19201 +               "DENT"  VX_LIMIT_FMT,
19202 +               VX_LIMIT_ARG(RLIMIT_NPROC),
19203 +               VX_LIMIT_ARG(RLIMIT_AS),
19204 +               VX_LIMIT_ARG(RLIMIT_MEMLOCK),
19205 +               VX_LIMIT_ARG(RLIMIT_RSS),
19206 +               VX_LIMIT_ARG(VLIMIT_ANON),
19207 +               VX_LIMIT_ARG(VLIMIT_MAPPED),
19208 +               VX_LIMIT_ARG(RLIMIT_NOFILE),
19209 +               VX_LIMIT_ARG(VLIMIT_OPENFD),
19210 +               VX_LIMIT_ARG(RLIMIT_LOCKS),
19211 +               VX_LIMIT_ARG(VLIMIT_NSOCK),
19212 +               VX_LIMIT_ARG(RLIMIT_MSGQUEUE),
19213 +               VX_LIMIT_ARG(VLIMIT_SHMEM),
19214 +               VX_LIMIT_ARG(VLIMIT_SEMARY),
19215 +               VX_LIMIT_ARG(VLIMIT_NSEMS),
19216 +               VX_LIMIT_ARG(VLIMIT_DENTRY));
19217 +}
19218 +
19219 +#endif /* _VX_LIMIT_PROC_H */
19220 +
19221 +
19222 diff -NurpP --minimal linux-4.1.41/kernel/vserver/network.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/network.c
19223 --- linux-4.1.41/kernel/vserver/network.c       1970-01-01 00:00:00.000000000 +0000
19224 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/network.c   2016-07-05 04:41:47.000000000 +0000
19225 @@ -0,0 +1,1053 @@
19226 +/*
19227 + *  linux/kernel/vserver/network.c
19228 + *
19229 + *  Virtual Server: Network Support
19230 + *
19231 + *  Copyright (C) 2003-2007  Herbert Pötzl
19232 + *
19233 + *  V0.01  broken out from vcontext V0.05
19234 + *  V0.02  cleaned up implementation
19235 + *  V0.03  added equiv nx commands
19236 + *  V0.04  switch to RCU based hash
19237 + *  V0.05  and back to locking again
19238 + *  V0.06  changed vcmds to nxi arg
19239 + *  V0.07  have __create claim() the nxi
19240 + *
19241 + */
19242 +
19243 +#include <linux/err.h>
19244 +#include <linux/slab.h>
19245 +#include <linux/rcupdate.h>
19246 +#include <net/ipv6.h>
19247 +
19248 +#include <linux/vs_network.h>
19249 +#include <linux/vs_pid.h>
19250 +#include <linux/vserver/network_cmd.h>
19251 +
19252 +
19253 +atomic_t nx_global_ctotal      = ATOMIC_INIT(0);
19254 +atomic_t nx_global_cactive     = ATOMIC_INIT(0);
19255 +
19256 +static struct kmem_cache *nx_addr_v4_cachep = NULL;
19257 +static struct kmem_cache *nx_addr_v6_cachep = NULL;
19258 +
19259 +
19260 +static int __init init_network(void)
19261 +{
19262 +       nx_addr_v4_cachep = kmem_cache_create("nx_v4_addr_cache",
19263 +               sizeof(struct nx_addr_v4), 0,
19264 +               SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
19265 +       nx_addr_v6_cachep = kmem_cache_create("nx_v6_addr_cache",
19266 +               sizeof(struct nx_addr_v6), 0,
19267 +               SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
19268 +       return 0;
19269 +}
19270 +
19271 +
19272 +/*     __alloc_nx_addr_v4()                                    */
19273 +
19274 +static inline struct nx_addr_v4 *__alloc_nx_addr_v4(void)
19275 +{
19276 +       struct nx_addr_v4 *nxa = kmem_cache_alloc(
19277 +               nx_addr_v4_cachep, GFP_KERNEL);
19278 +
19279 +       if (!IS_ERR(nxa))
19280 +               memset(nxa, 0, sizeof(*nxa));
19281 +       return nxa;
19282 +}
19283 +
19284 +/*     __dealloc_nx_addr_v4()                                  */
19285 +
19286 +static inline void __dealloc_nx_addr_v4(struct nx_addr_v4 *nxa)
19287 +{
19288 +       kmem_cache_free(nx_addr_v4_cachep, nxa);
19289 +}
19290 +
19291 +/*     __dealloc_nx_addr_v4_all()                              */
19292 +
19293 +static inline void __dealloc_nx_addr_v4_all(struct nx_addr_v4 *nxa)
19294 +{
19295 +       while (nxa) {
19296 +               struct nx_addr_v4 *next = nxa->next;
19297 +
19298 +               __dealloc_nx_addr_v4(nxa);
19299 +               nxa = next;
19300 +       }
19301 +}
19302 +
19303 +
19304 +#ifdef CONFIG_IPV6
19305 +
19306 +/*     __alloc_nx_addr_v6()                                    */
19307 +
19308 +static inline struct nx_addr_v6 *__alloc_nx_addr_v6(void)
19309 +{
19310 +       struct nx_addr_v6 *nxa = kmem_cache_alloc(
19311 +               nx_addr_v6_cachep, GFP_KERNEL);
19312 +
19313 +       if (!IS_ERR(nxa))
19314 +               memset(nxa, 0, sizeof(*nxa));
19315 +       return nxa;
19316 +}
19317 +
19318 +/*     __dealloc_nx_addr_v6()                                  */
19319 +
19320 +static inline void __dealloc_nx_addr_v6(struct nx_addr_v6 *nxa)
19321 +{
19322 +       kmem_cache_free(nx_addr_v6_cachep, nxa);
19323 +}
19324 +
19325 +/*     __dealloc_nx_addr_v6_all()                              */
19326 +
19327 +static inline void __dealloc_nx_addr_v6_all(struct nx_addr_v6 *nxa)
19328 +{
19329 +       while (nxa) {
19330 +               struct nx_addr_v6 *next = nxa->next;
19331 +
19332 +               __dealloc_nx_addr_v6(nxa);
19333 +               nxa = next;
19334 +       }
19335 +}
19336 +
19337 +#endif /* CONFIG_IPV6 */
19338 +
19339 +/*     __alloc_nx_info()
19340 +
19341 +       * allocate an initialized nx_info struct
19342 +       * doesn't make it visible (hash)                        */
19343 +
19344 +static struct nx_info *__alloc_nx_info(vnid_t nid)
19345 +{
19346 +       struct nx_info *new = NULL;
19347 +
19348 +       vxdprintk(VXD_CBIT(nid, 1), "alloc_nx_info(%d)*", nid);
19349 +
19350 +       /* would this benefit from a slab cache? */
19351 +       new = kmalloc(sizeof(struct nx_info), GFP_KERNEL);
19352 +       if (!new)
19353 +               return 0;
19354 +
19355 +       memset(new, 0, sizeof(struct nx_info));
19356 +       new->nx_id = nid;
19357 +       INIT_HLIST_NODE(&new->nx_hlist);
19358 +       atomic_set(&new->nx_usecnt, 0);
19359 +       atomic_set(&new->nx_tasks, 0);
19360 +       spin_lock_init(&new->addr_lock);
19361 +       new->nx_state = 0;
19362 +
19363 +       new->nx_flags = NXF_INIT_SET;
19364 +
19365 +       /* rest of init goes here */
19366 +
19367 +       new->v4_lback.s_addr = htonl(INADDR_LOOPBACK);
19368 +       new->v4_bcast.s_addr = htonl(INADDR_BROADCAST);
19369 +
19370 +       vxdprintk(VXD_CBIT(nid, 0),
19371 +               "alloc_nx_info(%d) = %p", nid, new);
19372 +       atomic_inc(&nx_global_ctotal);
19373 +       return new;
19374 +}
19375 +
19376 +/*     __dealloc_nx_info()
19377 +
19378 +       * final disposal of nx_info                             */
19379 +
19380 +static void __dealloc_nx_info(struct nx_info *nxi)
19381 +{
19382 +       vxdprintk(VXD_CBIT(nid, 0),
19383 +               "dealloc_nx_info(%p)", nxi);
19384 +
19385 +       nxi->nx_hlist.next = LIST_POISON1;
19386 +       nxi->nx_id = -1;
19387 +
19388 +       BUG_ON(atomic_read(&nxi->nx_usecnt));
19389 +       BUG_ON(atomic_read(&nxi->nx_tasks));
19390 +
19391 +       __dealloc_nx_addr_v4_all(nxi->v4.next);
19392 +#ifdef CONFIG_IPV6
19393 +       __dealloc_nx_addr_v6_all(nxi->v6.next);
19394 +#endif
19395 +
19396 +       nxi->nx_state |= NXS_RELEASED;
19397 +       kfree(nxi);
19398 +       atomic_dec(&nx_global_ctotal);
19399 +}
19400 +
19401 +static void __shutdown_nx_info(struct nx_info *nxi)
19402 +{
19403 +       nxi->nx_state |= NXS_SHUTDOWN;
19404 +       vs_net_change(nxi, VSC_NETDOWN);
19405 +}
19406 +
19407 +/*     exported stuff                                          */
19408 +
19409 +void free_nx_info(struct nx_info *nxi)
19410 +{
19411 +       /* context shutdown is mandatory */
19412 +       BUG_ON(nxi->nx_state != NXS_SHUTDOWN);
19413 +
19414 +       /* context must not be hashed */
19415 +       BUG_ON(nxi->nx_state & NXS_HASHED);
19416 +
19417 +       BUG_ON(atomic_read(&nxi->nx_usecnt));
19418 +       BUG_ON(atomic_read(&nxi->nx_tasks));
19419 +
19420 +       __dealloc_nx_info(nxi);
19421 +}
19422 +
19423 +
19424 +void __nx_set_lback(struct nx_info *nxi)
19425 +{
19426 +       int nid = nxi->nx_id;
19427 +       __be32 lback = htonl(INADDR_LOOPBACK ^ ((nid & 0xFFFF) << 8));
19428 +
19429 +       nxi->v4_lback.s_addr = lback;
19430 +}
19431 +
19432 +extern int __nx_inet_add_lback(__be32 addr);
19433 +extern int __nx_inet_del_lback(__be32 addr);
19434 +
19435 +
19436 +/*     hash table for nx_info hash */
19437 +
19438 +#define NX_HASH_SIZE   13
19439 +
19440 +struct hlist_head nx_info_hash[NX_HASH_SIZE];
19441 +
19442 +static DEFINE_SPINLOCK(nx_info_hash_lock);
19443 +
19444 +
19445 +static inline unsigned int __hashval(vnid_t nid)
19446 +{
19447 +       return (nid % NX_HASH_SIZE);
19448 +}
19449 +
19450 +
19451 +
19452 +/*     __hash_nx_info()
19453 +
19454 +       * add the nxi to the global hash table
19455 +       * requires the hash_lock to be held                     */
19456 +
19457 +static inline void __hash_nx_info(struct nx_info *nxi)
19458 +{
19459 +       struct hlist_head *head;
19460 +
19461 +       vxd_assert_lock(&nx_info_hash_lock);
19462 +       vxdprintk(VXD_CBIT(nid, 4),
19463 +               "__hash_nx_info: %p[#%d]", nxi, nxi->nx_id);
19464 +
19465 +       /* context must not be hashed */
19466 +       BUG_ON(nx_info_state(nxi, NXS_HASHED));
19467 +
19468 +       nxi->nx_state |= NXS_HASHED;
19469 +       head = &nx_info_hash[__hashval(nxi->nx_id)];
19470 +       hlist_add_head(&nxi->nx_hlist, head);
19471 +       atomic_inc(&nx_global_cactive);
19472 +}
19473 +
19474 +/*     __unhash_nx_info()
19475 +
19476 +       * remove the nxi from the global hash table
19477 +       * requires the hash_lock to be held                     */
19478 +
19479 +static inline void __unhash_nx_info(struct nx_info *nxi)
19480 +{
19481 +       vxd_assert_lock(&nx_info_hash_lock);
19482 +       vxdprintk(VXD_CBIT(nid, 4),
19483 +               "__unhash_nx_info: %p[#%d.%d.%d]", nxi, nxi->nx_id,
19484 +               atomic_read(&nxi->nx_usecnt), atomic_read(&nxi->nx_tasks));
19485 +
19486 +       /* context must be hashed */
19487 +       BUG_ON(!nx_info_state(nxi, NXS_HASHED));
19488 +       /* but without tasks */
19489 +       BUG_ON(atomic_read(&nxi->nx_tasks));
19490 +
19491 +       nxi->nx_state &= ~NXS_HASHED;
19492 +       hlist_del(&nxi->nx_hlist);
19493 +       atomic_dec(&nx_global_cactive);
19494 +}
19495 +
19496 +
19497 +/*     __lookup_nx_info()
19498 +
19499 +       * requires the hash_lock to be held
19500 +       * doesn't increment the nx_refcnt                       */
19501 +
19502 +static inline struct nx_info *__lookup_nx_info(vnid_t nid)
19503 +{
19504 +       struct hlist_head *head = &nx_info_hash[__hashval(nid)];
19505 +       struct hlist_node *pos;
19506 +       struct nx_info *nxi;
19507 +
19508 +       vxd_assert_lock(&nx_info_hash_lock);
19509 +       hlist_for_each(pos, head) {
19510 +               nxi = hlist_entry(pos, struct nx_info, nx_hlist);
19511 +
19512 +               if (nxi->nx_id == nid)
19513 +                       goto found;
19514 +       }
19515 +       nxi = NULL;
19516 +found:
19517 +       vxdprintk(VXD_CBIT(nid, 0),
19518 +               "__lookup_nx_info(#%u): %p[#%u]",
19519 +               nid, nxi, nxi ? nxi->nx_id : 0);
19520 +       return nxi;
19521 +}
19522 +
19523 +
19524 +/*     __create_nx_info()
19525 +
19526 +       * create the requested context
19527 +       * get(), claim() and hash it                            */
19528 +
19529 +static struct nx_info *__create_nx_info(int id)
19530 +{
19531 +       struct nx_info *new, *nxi = NULL;
19532 +
19533 +       vxdprintk(VXD_CBIT(nid, 1), "create_nx_info(%d)*", id);
19534 +
19535 +       if (!(new = __alloc_nx_info(id)))
19536 +               return ERR_PTR(-ENOMEM);
19537 +
19538 +       /* required to make dynamic xids unique */
19539 +       spin_lock(&nx_info_hash_lock);
19540 +
19541 +       /* static context requested */
19542 +       if ((nxi = __lookup_nx_info(id))) {
19543 +               vxdprintk(VXD_CBIT(nid, 0),
19544 +                       "create_nx_info(%d) = %p (already there)", id, nxi);
19545 +               if (nx_info_flags(nxi, NXF_STATE_SETUP, 0))
19546 +                       nxi = ERR_PTR(-EBUSY);
19547 +               else
19548 +                       nxi = ERR_PTR(-EEXIST);
19549 +               goto out_unlock;
19550 +       }
19551 +       /* new context */
19552 +       vxdprintk(VXD_CBIT(nid, 0),
19553 +               "create_nx_info(%d) = %p (new)", id, new);
19554 +       claim_nx_info(new, NULL);
19555 +       __nx_set_lback(new);
19556 +       __hash_nx_info(get_nx_info(new));
19557 +       nxi = new, new = NULL;
19558 +
19559 +out_unlock:
19560 +       spin_unlock(&nx_info_hash_lock);
19561 +       if (new)
19562 +               __dealloc_nx_info(new);
19563 +       return nxi;
19564 +}
19565 +
19566 +
19567 +
19568 +/*     exported stuff                                          */
19569 +
19570 +
19571 +void unhash_nx_info(struct nx_info *nxi)
19572 +{
19573 +       __shutdown_nx_info(nxi);
19574 +       spin_lock(&nx_info_hash_lock);
19575 +       __unhash_nx_info(nxi);
19576 +       spin_unlock(&nx_info_hash_lock);
19577 +}
19578 +
19579 +/*     lookup_nx_info()
19580 +
19581 +       * search for a nx_info and get() it
19582 +       * negative id means current                             */
19583 +
19584 +struct nx_info *lookup_nx_info(int id)
19585 +{
19586 +       struct nx_info *nxi = NULL;
19587 +
19588 +       if (id < 0) {
19589 +               nxi = get_nx_info(current_nx_info());
19590 +       } else if (id > 1) {
19591 +               spin_lock(&nx_info_hash_lock);
19592 +               nxi = get_nx_info(__lookup_nx_info(id));
19593 +               spin_unlock(&nx_info_hash_lock);
19594 +       }
19595 +       return nxi;
19596 +}
19597 +
19598 +/*     nid_is_hashed()
19599 +
19600 +       * verify that nid is still hashed                       */
19601 +
19602 +int nid_is_hashed(vnid_t nid)
19603 +{
19604 +       int hashed;
19605 +
19606 +       spin_lock(&nx_info_hash_lock);
19607 +       hashed = (__lookup_nx_info(nid) != NULL);
19608 +       spin_unlock(&nx_info_hash_lock);
19609 +       return hashed;
19610 +}
19611 +
19612 +
19613 +#ifdef CONFIG_PROC_FS
19614 +
19615 +/*     get_nid_list()
19616 +
19617 +       * get a subset of hashed nids for proc
19618 +       * assumes size is at least one                          */
19619 +
19620 +int get_nid_list(int index, unsigned int *nids, int size)
19621 +{
19622 +       int hindex, nr_nids = 0;
19623 +
19624 +       /* only show current and children */
19625 +       if (!nx_check(0, VS_ADMIN | VS_WATCH)) {
19626 +               if (index > 0)
19627 +                       return 0;
19628 +               nids[nr_nids] = nx_current_nid();
19629 +               return 1;
19630 +       }
19631 +
19632 +       for (hindex = 0; hindex < NX_HASH_SIZE; hindex++) {
19633 +               struct hlist_head *head = &nx_info_hash[hindex];
19634 +               struct hlist_node *pos;
19635 +
19636 +               spin_lock(&nx_info_hash_lock);
19637 +               hlist_for_each(pos, head) {
19638 +                       struct nx_info *nxi;
19639 +
19640 +                       if (--index > 0)
19641 +                               continue;
19642 +
19643 +                       nxi = hlist_entry(pos, struct nx_info, nx_hlist);
19644 +                       nids[nr_nids] = nxi->nx_id;
19645 +                       if (++nr_nids >= size) {
19646 +                               spin_unlock(&nx_info_hash_lock);
19647 +                               goto out;
19648 +                       }
19649 +               }
19650 +               /* keep the lock time short */
19651 +               spin_unlock(&nx_info_hash_lock);
19652 +       }
19653 +out:
19654 +       return nr_nids;
19655 +}
19656 +#endif
19657 +
19658 +
19659 +/*
19660 + *     migrate task to new network
19661 + *     gets nxi, puts old_nxi on change
19662 + */
19663 +
19664 +int nx_migrate_task(struct task_struct *p, struct nx_info *nxi)
19665 +{
19666 +       struct nx_info *old_nxi;
19667 +       int ret = 0;
19668 +
19669 +       if (!p || !nxi)
19670 +               BUG();
19671 +
19672 +       vxdprintk(VXD_CBIT(nid, 5),
19673 +               "nx_migrate_task(%p,%p[#%d.%d.%d])",
19674 +               p, nxi, nxi->nx_id,
19675 +               atomic_read(&nxi->nx_usecnt),
19676 +               atomic_read(&nxi->nx_tasks));
19677 +
19678 +       if (nx_info_flags(nxi, NXF_INFO_PRIVATE, 0) &&
19679 +               !nx_info_flags(nxi, NXF_STATE_SETUP, 0))
19680 +               return -EACCES;
19681 +
19682 +       if (nx_info_state(nxi, NXS_SHUTDOWN))
19683 +               return -EFAULT;
19684 +
19685 +       /* maybe disallow this completely? */
19686 +       old_nxi = task_get_nx_info(p);
19687 +       if (old_nxi == nxi)
19688 +               goto out;
19689 +
19690 +       task_lock(p);
19691 +       if (old_nxi)
19692 +               clr_nx_info(&p->nx_info);
19693 +       claim_nx_info(nxi, p);
19694 +       set_nx_info(&p->nx_info, nxi);
19695 +       p->nid = nxi->nx_id;
19696 +       task_unlock(p);
19697 +
19698 +       vxdprintk(VXD_CBIT(nid, 5),
19699 +               "moved task %p into nxi:%p[#%d]",
19700 +               p, nxi, nxi->nx_id);
19701 +
19702 +       if (old_nxi)
19703 +               release_nx_info(old_nxi, p);
19704 +       ret = 0;
19705 +out:
19706 +       put_nx_info(old_nxi);
19707 +       return ret;
19708 +}
19709 +
19710 +
19711 +void nx_set_persistent(struct nx_info *nxi)
19712 +{
19713 +       vxdprintk(VXD_CBIT(nid, 6),
19714 +               "nx_set_persistent(%p[#%d])", nxi, nxi->nx_id);
19715 +
19716 +       get_nx_info(nxi);
19717 +       claim_nx_info(nxi, NULL);
19718 +}
19719 +
19720 +void nx_clear_persistent(struct nx_info *nxi)
19721 +{
19722 +       vxdprintk(VXD_CBIT(nid, 6),
19723 +               "nx_clear_persistent(%p[#%d])", nxi, nxi->nx_id);
19724 +
19725 +       release_nx_info(nxi, NULL);
19726 +       put_nx_info(nxi);
19727 +}
19728 +
19729 +void nx_update_persistent(struct nx_info *nxi)
19730 +{
19731 +       if (nx_info_flags(nxi, NXF_PERSISTENT, 0))
19732 +               nx_set_persistent(nxi);
19733 +       else
19734 +               nx_clear_persistent(nxi);
19735 +}
19736 +
19737 +/* vserver syscall commands below here */
19738 +
19739 +/* taks nid and nx_info functions */
19740 +
19741 +#include <asm/uaccess.h>
19742 +
19743 +
19744 +int vc_task_nid(uint32_t id)
19745 +{
19746 +       vnid_t nid;
19747 +
19748 +       if (id) {
19749 +               struct task_struct *tsk;
19750 +
19751 +               rcu_read_lock();
19752 +               tsk = find_task_by_real_pid(id);
19753 +               nid = (tsk) ? tsk->nid : -ESRCH;
19754 +               rcu_read_unlock();
19755 +       } else
19756 +               nid = nx_current_nid();
19757 +       return nid;
19758 +}
19759 +
19760 +
19761 +int vc_nx_info(struct nx_info *nxi, void __user *data)
19762 +{
19763 +       struct vcmd_nx_info_v0 vc_data;
19764 +
19765 +       vc_data.nid = nxi->nx_id;
19766 +
19767 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
19768 +               return -EFAULT;
19769 +       return 0;
19770 +}
19771 +
19772 +
19773 +/* network functions */
19774 +
19775 +int vc_net_create(uint32_t nid, void __user *data)
19776 +{
19777 +       struct vcmd_net_create vc_data = { .flagword = NXF_INIT_SET };
19778 +       struct nx_info *new_nxi;
19779 +       int ret;
19780 +
19781 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19782 +               return -EFAULT;
19783 +
19784 +       if ((nid > MAX_S_CONTEXT) || (nid < 2))
19785 +               return -EINVAL;
19786 +
19787 +       new_nxi = __create_nx_info(nid);
19788 +       if (IS_ERR(new_nxi))
19789 +               return PTR_ERR(new_nxi);
19790 +
19791 +       /* initial flags */
19792 +       new_nxi->nx_flags = vc_data.flagword;
19793 +
19794 +       ret = -ENOEXEC;
19795 +       if (vs_net_change(new_nxi, VSC_NETUP))
19796 +               goto out;
19797 +
19798 +       ret = nx_migrate_task(current, new_nxi);
19799 +       if (ret)
19800 +               goto out;
19801 +
19802 +       /* return context id on success */
19803 +       ret = new_nxi->nx_id;
19804 +
19805 +       /* get a reference for persistent contexts */
19806 +       if ((vc_data.flagword & NXF_PERSISTENT))
19807 +               nx_set_persistent(new_nxi);
19808 +out:
19809 +       release_nx_info(new_nxi, NULL);
19810 +       put_nx_info(new_nxi);
19811 +       return ret;
19812 +}
19813 +
19814 +
19815 +int vc_net_migrate(struct nx_info *nxi, void __user *data)
19816 +{
19817 +       return nx_migrate_task(current, nxi);
19818 +}
19819 +
19820 +
19821 +static inline
19822 +struct nx_addr_v4 *__find_v4_addr(struct nx_info *nxi,
19823 +       __be32 ip, __be32 ip2, __be32 mask, uint16_t type, uint16_t flags,
19824 +       struct nx_addr_v4 **prev)
19825 +{
19826 +       struct nx_addr_v4 *nxa = &nxi->v4;
19827 +
19828 +       for (; nxa; nxa = nxa->next) {
19829 +               if ((nxa->ip[0].s_addr == ip) &&
19830 +                   (nxa->ip[1].s_addr == ip2) &&
19831 +                   (nxa->mask.s_addr == mask) &&
19832 +                   (nxa->type == type) &&
19833 +                   (nxa->flags == flags))
19834 +                   return nxa;
19835 +
19836 +               /* save previous entry */
19837 +               if (prev)
19838 +                       *prev = nxa;
19839 +       }
19840 +       return NULL;
19841 +}
19842 +
19843 +int do_add_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
19844 +       uint16_t type, uint16_t flags)
19845 +{
19846 +       struct nx_addr_v4 *nxa = NULL;
19847 +       struct nx_addr_v4 *new = __alloc_nx_addr_v4();
19848 +       unsigned long irqflags;
19849 +       int ret = -EEXIST;
19850 +
19851 +       if (IS_ERR(new))
19852 +               return PTR_ERR(new);
19853 +
19854 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
19855 +       if (__find_v4_addr(nxi, ip, ip2, mask, type, flags, &nxa))
19856 +               goto out_unlock;
19857 +
19858 +       if (NX_IPV4(nxi)) {
19859 +               nxa->next = new;
19860 +               nxa = new;
19861 +               new = NULL;
19862 +
19863 +               /* remove single ip for ip list */
19864 +               nxi->nx_flags &= ~NXF_SINGLE_IP;
19865 +       }
19866 +
19867 +       nxa->ip[0].s_addr = ip;
19868 +       nxa->ip[1].s_addr = ip2;
19869 +       nxa->mask.s_addr = mask;
19870 +       nxa->type = type;
19871 +       nxa->flags = flags;
19872 +       ret = 0;
19873 +out_unlock:
19874 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
19875 +       if (new)
19876 +               __dealloc_nx_addr_v4(new);
19877 +       return ret;
19878 +}
19879 +
19880 +int do_remove_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
19881 +       uint16_t type, uint16_t flags)
19882 +{
19883 +       struct nx_addr_v4 *nxa = NULL;
19884 +       struct nx_addr_v4 *old = NULL;
19885 +       unsigned long irqflags;
19886 +       int ret = 0;
19887 +
19888 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
19889 +       switch (type) {
19890 +       case NXA_TYPE_ADDR:
19891 +               old = __find_v4_addr(nxi, ip, ip2, mask, type, flags, &nxa);
19892 +               if (old) {
19893 +                       if (nxa) {
19894 +                               nxa->next = old->next;
19895 +                               old->next = NULL;
19896 +                       } else {
19897 +                               if (old->next) {
19898 +                                       nxa = old;
19899 +                                       old = old->next;
19900 +                                       *nxa = *old;
19901 +                                       old->next = NULL;
19902 +                               } else {
19903 +                                       memset(old, 0, sizeof(*old));
19904 +                                       old = NULL;
19905 +                               }
19906 +                       }
19907 +               } else
19908 +                       ret = -ESRCH;
19909 +               break;
19910 +
19911 +       case NXA_TYPE_ANY:
19912 +               nxa = &nxi->v4;
19913 +               old = nxa->next;
19914 +               memset(nxa, 0, sizeof(*nxa));
19915 +               break;
19916 +
19917 +       default:
19918 +               ret = -EINVAL;
19919 +       }
19920 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
19921 +       __dealloc_nx_addr_v4_all(old);
19922 +       return ret;
19923 +}
19924 +
19925 +
19926 +int vc_net_add(struct nx_info *nxi, void __user *data)
19927 +{
19928 +       struct vcmd_net_addr_v0 vc_data;
19929 +       int index, ret = 0;
19930 +
19931 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19932 +               return -EFAULT;
19933 +
19934 +       switch (vc_data.type) {
19935 +       case NXA_TYPE_IPV4:
19936 +               if ((vc_data.count < 1) || (vc_data.count > 4))
19937 +                       return -EINVAL;
19938 +
19939 +               index = 0;
19940 +               while (index < vc_data.count) {
19941 +                       ret = do_add_v4_addr(nxi, vc_data.ip[index].s_addr, 0,
19942 +                               vc_data.mask[index].s_addr, NXA_TYPE_ADDR, 0);
19943 +                       if (ret)
19944 +                               return ret;
19945 +                       index++;
19946 +               }
19947 +               ret = index;
19948 +               break;
19949 +
19950 +       case NXA_TYPE_IPV4|NXA_MOD_BCAST:
19951 +               nxi->v4_bcast = vc_data.ip[0];
19952 +               ret = 1;
19953 +               break;
19954 +
19955 +       case NXA_TYPE_IPV4|NXA_MOD_LBACK:
19956 +               nxi->v4_lback = vc_data.ip[0];
19957 +               ret = 1;
19958 +               break;
19959 +
19960 +       default:
19961 +               ret = -EINVAL;
19962 +               break;
19963 +       }
19964 +       return ret;
19965 +}
19966 +
19967 +int vc_net_remove(struct nx_info *nxi, void __user *data)
19968 +{
19969 +       struct vcmd_net_addr_v0 vc_data;
19970 +
19971 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19972 +               return -EFAULT;
19973 +
19974 +       switch (vc_data.type) {
19975 +       case NXA_TYPE_ANY:
19976 +               return do_remove_v4_addr(nxi, 0, 0, 0, vc_data.type, 0);
19977 +       default:
19978 +               return -EINVAL;
19979 +       }
19980 +       return 0;
19981 +}
19982 +
19983 +
19984 +int vc_net_add_ipv4_v1(struct nx_info *nxi, void __user *data)
19985 +{
19986 +       struct vcmd_net_addr_ipv4_v1 vc_data;
19987 +
19988 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19989 +               return -EFAULT;
19990 +
19991 +       switch (vc_data.type) {
19992 +       case NXA_TYPE_ADDR:
19993 +       case NXA_TYPE_MASK:
19994 +               return do_add_v4_addr(nxi, vc_data.ip.s_addr, 0,
19995 +                       vc_data.mask.s_addr, vc_data.type, vc_data.flags);
19996 +
19997 +       case NXA_TYPE_ADDR | NXA_MOD_BCAST:
19998 +               nxi->v4_bcast = vc_data.ip;
19999 +               break;
20000 +
20001 +       case NXA_TYPE_ADDR | NXA_MOD_LBACK:
20002 +               nxi->v4_lback = vc_data.ip;
20003 +               break;
20004 +
20005 +       default:
20006 +               return -EINVAL;
20007 +       }
20008 +       return 0;
20009 +}
20010 +
20011 +int vc_net_add_ipv4(struct nx_info *nxi, void __user *data)
20012 +{
20013 +       struct vcmd_net_addr_ipv4_v2 vc_data;
20014 +
20015 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
20016 +               return -EFAULT;
20017 +
20018 +       switch (vc_data.type) {
20019 +       case NXA_TYPE_ADDR:
20020 +       case NXA_TYPE_MASK:
20021 +       case NXA_TYPE_RANGE:
20022 +               return do_add_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr,
20023 +                       vc_data.mask.s_addr, vc_data.type, vc_data.flags);
20024 +
20025 +       case NXA_TYPE_ADDR | NXA_MOD_BCAST:
20026 +               nxi->v4_bcast = vc_data.ip;
20027 +               break;
20028 +
20029 +       case NXA_TYPE_ADDR | NXA_MOD_LBACK:
20030 +               nxi->v4_lback = vc_data.ip;
20031 +               break;
20032 +
20033 +       default:
20034 +               return -EINVAL;
20035 +       }
20036 +       return 0;
20037 +}
20038 +
20039 +int vc_net_rem_ipv4_v1(struct nx_info *nxi, void __user *data)
20040 +{
20041 +       struct vcmd_net_addr_ipv4_v1 vc_data;
20042 +
20043 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
20044 +               return -EFAULT;
20045 +
20046 +       return do_remove_v4_addr(nxi, vc_data.ip.s_addr, 0,
20047 +               vc_data.mask.s_addr, vc_data.type, vc_data.flags);
20048 +}
20049 +
20050 +int vc_net_rem_ipv4(struct nx_info *nxi, void __user *data)
20051 +{
20052 +       struct vcmd_net_addr_ipv4_v2 vc_data;
20053 +
20054 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
20055 +               return -EFAULT;
20056 +
20057 +       return do_remove_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr,
20058 +               vc_data.mask.s_addr, vc_data.type, vc_data.flags);
20059 +}
20060 +
20061 +#ifdef CONFIG_IPV6
20062 +
20063 +static inline
20064 +struct nx_addr_v6 *__find_v6_addr(struct nx_info *nxi,
20065 +       struct in6_addr *ip, struct in6_addr *mask,
20066 +       uint32_t prefix, uint16_t type, uint16_t flags,
20067 +       struct nx_addr_v6 **prev)
20068 +{
20069 +       struct nx_addr_v6 *nxa = &nxi->v6;
20070 +
20071 +       for (; nxa; nxa = nxa->next) {
20072 +               if (ipv6_addr_equal(&nxa->ip, ip) &&
20073 +                   ipv6_addr_equal(&nxa->mask, mask) &&
20074 +                   (nxa->prefix == prefix) &&
20075 +                   (nxa->type == type) &&
20076 +                   (nxa->flags == flags))
20077 +                   return nxa;
20078 +
20079 +               /* save previous entry */
20080 +               if (prev)
20081 +                       *prev = nxa;
20082 +       }
20083 +       return NULL;
20084 +}
20085 +
20086 +
20087 +int do_add_v6_addr(struct nx_info *nxi,
20088 +       struct in6_addr *ip, struct in6_addr *mask,
20089 +       uint32_t prefix, uint16_t type, uint16_t flags)
20090 +{
20091 +       struct nx_addr_v6 *nxa = NULL;
20092 +       struct nx_addr_v6 *new = __alloc_nx_addr_v6();
20093 +       unsigned long irqflags;
20094 +       int ret = -EEXIST;
20095 +
20096 +       if (IS_ERR(new))
20097 +               return PTR_ERR(new);
20098 +
20099 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
20100 +       if (__find_v6_addr(nxi, ip, mask, prefix, type, flags, &nxa))
20101 +               goto out_unlock;
20102 +
20103 +       if (NX_IPV6(nxi)) {
20104 +               nxa->next = new;
20105 +               nxa = new;
20106 +               new = NULL;
20107 +       }
20108 +
20109 +       nxa->ip = *ip;
20110 +       nxa->mask = *mask;
20111 +       nxa->prefix = prefix;
20112 +       nxa->type = type;
20113 +       nxa->flags = flags;
20114 +       ret = 0;
20115 +out_unlock:
20116 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
20117 +       if (new)
20118 +               __dealloc_nx_addr_v6(new);
20119 +       return ret;
20120 +}
20121 +
20122 +int do_remove_v6_addr(struct nx_info *nxi,
20123 +       struct in6_addr *ip, struct in6_addr *mask,
20124 +       uint32_t prefix, uint16_t type, uint16_t flags)
20125 +{
20126 +       struct nx_addr_v6 *nxa = NULL;
20127 +       struct nx_addr_v6 *old = NULL;
20128 +       unsigned long irqflags;
20129 +       int ret = 0;
20130 +
20131 +       spin_lock_irqsave(&nxi->addr_lock, irqflags);
20132 +       switch (type) {
20133 +       case NXA_TYPE_ADDR:
20134 +               old = __find_v6_addr(nxi, ip, mask, prefix, type, flags, &nxa);
20135 +               if (old) {
20136 +                       if (nxa) {
20137 +                               nxa->next = old->next;
20138 +                               old->next = NULL;
20139 +                       } else {
20140 +                               if (old->next) {
20141 +                                       nxa = old;
20142 +                                       old = old->next;
20143 +                                       *nxa = *old;
20144 +                                       old->next = NULL;
20145 +                               } else {
20146 +                                       memset(old, 0, sizeof(*old));
20147 +                                       old = NULL;
20148 +                               }
20149 +                       }
20150 +               } else
20151 +                       ret = -ESRCH;
20152 +               break;
20153 +
20154 +       case NXA_TYPE_ANY:
20155 +               nxa = &nxi->v6;
20156 +               old = nxa->next;
20157 +               memset(nxa, 0, sizeof(*nxa));
20158 +               break;
20159 +
20160 +       default:
20161 +               ret = -EINVAL;
20162 +       }
20163 +       spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
20164 +       __dealloc_nx_addr_v6_all(old);
20165 +       return ret;
20166 +}
20167 +
20168 +int vc_net_add_ipv6(struct nx_info *nxi, void __user *data)
20169 +{
20170 +       struct vcmd_net_addr_ipv6_v1 vc_data;
20171 +
20172 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
20173 +               return -EFAULT;
20174 +
20175 +       switch (vc_data.type) {
20176 +       case NXA_TYPE_ADDR:
20177 +               memset(&vc_data.mask, ~0, sizeof(vc_data.mask));
20178 +               /* fallthrough */
20179 +       case NXA_TYPE_MASK:
20180 +               return do_add_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
20181 +                       vc_data.prefix, vc_data.type, vc_data.flags);
20182 +       default:
20183 +               return -EINVAL;
20184 +       }
20185 +       return 0;
20186 +}
20187 +
20188 +int vc_net_remove_ipv6(struct nx_info *nxi, void __user *data)
20189 +{
20190 +       struct vcmd_net_addr_ipv6_v1 vc_data;
20191 +
20192 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
20193 +               return -EFAULT;
20194 +
20195 +       switch (vc_data.type) {
20196 +       case NXA_TYPE_ADDR:
20197 +               memset(&vc_data.mask, ~0, sizeof(vc_data.mask));
20198 +               /* fallthrough */
20199 +       case NXA_TYPE_MASK:
20200 +               return do_remove_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
20201 +                       vc_data.prefix, vc_data.type, vc_data.flags);
20202 +       case NXA_TYPE_ANY:
20203 +               return do_remove_v6_addr(nxi, NULL, NULL, 0, vc_data.type, 0);
20204 +       default:
20205 +               return -EINVAL;
20206 +       }
20207 +       return 0;
20208 +}
20209 +
20210 +#endif /* CONFIG_IPV6 */
20211 +
20212 +
20213 +int vc_get_nflags(struct nx_info *nxi, void __user *data)
20214 +{
20215 +       struct vcmd_net_flags_v0 vc_data;
20216 +
20217 +       vc_data.flagword = nxi->nx_flags;
20218 +
20219 +       /* special STATE flag handling */
20220 +       vc_data.mask = vs_mask_flags(~0ULL, nxi->nx_flags, NXF_ONE_TIME);
20221 +
20222 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
20223 +               return -EFAULT;
20224 +       return 0;
20225 +}
20226 +
20227 +int vc_set_nflags(struct nx_info *nxi, void __user *data)
20228 +{
20229 +       struct vcmd_net_flags_v0 vc_data;
20230 +       uint64_t mask, trigger;
20231 +
20232 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
20233 +               return -EFAULT;
20234 +
20235 +       /* special STATE flag handling */
20236 +       mask = vs_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME);
20237 +       trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword);
20238 +
20239 +       nxi->nx_flags = vs_mask_flags(nxi->nx_flags,
20240 +               vc_data.flagword, mask);
20241 +       if (trigger & NXF_PERSISTENT)
20242 +               nx_update_persistent(nxi);
20243 +
20244 +       return 0;
20245 +}
20246 +
20247 +int vc_get_ncaps(struct nx_info *nxi, void __user *data)
20248 +{
20249 +       struct vcmd_net_caps_v0 vc_data;
20250 +
20251 +       vc_data.ncaps = nxi->nx_ncaps;
20252 +       vc_data.cmask = ~0ULL;
20253 +
20254 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
20255 +               return -EFAULT;
20256 +       return 0;
20257 +}
20258 +
20259 +int vc_set_ncaps(struct nx_info *nxi, void __user *data)
20260 +{
20261 +       struct vcmd_net_caps_v0 vc_data;
20262 +
20263 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
20264 +               return -EFAULT;
20265 +
20266 +       nxi->nx_ncaps = vs_mask_flags(nxi->nx_ncaps,
20267 +               vc_data.ncaps, vc_data.cmask);
20268 +       return 0;
20269 +}
20270 +
20271 +
20272 +#include <linux/module.h>
20273 +
20274 +module_init(init_network);
20275 +
20276 +EXPORT_SYMBOL_GPL(free_nx_info);
20277 +EXPORT_SYMBOL_GPL(unhash_nx_info);
20278 +
20279 diff -NurpP --minimal linux-4.1.41/kernel/vserver/proc.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/proc.c
20280 --- linux-4.1.41/kernel/vserver/proc.c  1970-01-01 00:00:00.000000000 +0000
20281 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/proc.c      2016-07-05 04:41:47.000000000 +0000
20282 @@ -0,0 +1,1100 @@
20283 +/*
20284 + *  linux/kernel/vserver/proc.c
20285 + *
20286 + *  Virtual Context Support
20287 + *
20288 + *  Copyright (C) 2003-2011  Herbert Pötzl
20289 + *
20290 + *  V0.01  basic structure
20291 + *  V0.02  adaptation vs1.3.0
20292 + *  V0.03  proc permissions
20293 + *  V0.04  locking/generic
20294 + *  V0.05  next generation procfs
20295 + *  V0.06  inode validation
20296 + *  V0.07  generic rewrite vid
20297 + *  V0.08  remove inode type
20298 + *  V0.09  added u/wmask info
20299 + *
20300 + */
20301 +
20302 +#include <linux/proc_fs.h>
20303 +#include <linux/fs_struct.h>
20304 +#include <linux/mount.h>
20305 +#include <linux/namei.h>
20306 +#include <asm/unistd.h>
20307 +
20308 +#include <linux/vs_context.h>
20309 +#include <linux/vs_network.h>
20310 +#include <linux/vs_cvirt.h>
20311 +
20312 +#include <linux/in.h>
20313 +#include <linux/inetdevice.h>
20314 +#include <linux/vs_inet.h>
20315 +#include <linux/vs_inet6.h>
20316 +
20317 +#include <linux/vserver/global.h>
20318 +
20319 +#include "cvirt_proc.h"
20320 +#include "cacct_proc.h"
20321 +#include "limit_proc.h"
20322 +#include "sched_proc.h"
20323 +#include "vci_config.h"
20324 +
20325 +#include <../../fs/proc/internal.h>
20326 +
20327 +
20328 +static inline char *print_cap_t(char *buffer, kernel_cap_t *c)
20329 +{
20330 +       unsigned __capi;
20331 +
20332 +       CAP_FOR_EACH_U32(__capi) {
20333 +               buffer += sprintf(buffer, "%08x",
20334 +                       c->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]);
20335 +       }
20336 +       return buffer;
20337 +}
20338 +
20339 +
20340 +static struct proc_dir_entry *proc_virtual;
20341 +
20342 +static struct proc_dir_entry *proc_virtnet;
20343 +
20344 +
20345 +/* first the actual feeds */
20346 +
20347 +
20348 +static int proc_vci(char *buffer)
20349 +{
20350 +       return sprintf(buffer,
20351 +               "VCIVersion:\t%04x:%04x\n"
20352 +               "VCISyscall:\t%d\n"
20353 +               "VCIKernel:\t%08x\n",
20354 +               VCI_VERSION >> 16,
20355 +               VCI_VERSION & 0xFFFF,
20356 +               __NR_vserver,
20357 +               vci_kernel_config());
20358 +}
20359 +
20360 +static int proc_virtual_info(char *buffer)
20361 +{
20362 +       return proc_vci(buffer);
20363 +}
20364 +
20365 +static int proc_virtual_status(char *buffer)
20366 +{
20367 +       return sprintf(buffer,
20368 +               "#CTotal:\t%d\n"
20369 +               "#CActive:\t%d\n"
20370 +               "#NSProxy:\t%d\t%d %d %d %d %d %d\n"
20371 +               "#InitTask:\t%d\t%d %d\n",
20372 +               atomic_read(&vx_global_ctotal),
20373 +               atomic_read(&vx_global_cactive),
20374 +               atomic_read(&vs_global_nsproxy),
20375 +               atomic_read(&vs_global_fs),
20376 +               atomic_read(&vs_global_mnt_ns),
20377 +               atomic_read(&vs_global_uts_ns),
20378 +               atomic_read(&nr_ipc_ns),
20379 +               atomic_read(&vs_global_user_ns),
20380 +               atomic_read(&vs_global_pid_ns),
20381 +               atomic_read(&init_task.usage),
20382 +               atomic_read(&init_task.nsproxy->count),
20383 +               init_task.fs->users);
20384 +}
20385 +
20386 +
20387 +int proc_vxi_info(struct vx_info *vxi, char *buffer)
20388 +{
20389 +       int length;
20390 +
20391 +       length = sprintf(buffer,
20392 +               "ID:\t%d\n"
20393 +               "Info:\t%p\n"
20394 +               "Init:\t%d\n"
20395 +               "OOM:\t%lld\n",
20396 +               vxi->vx_id,
20397 +               vxi,
20398 +               vxi->vx_initpid,
20399 +               vxi->vx_badness_bias);
20400 +       return length;
20401 +}
20402 +
20403 +int proc_vxi_status(struct vx_info *vxi, char *buffer)
20404 +{
20405 +       char *orig = buffer;
20406 +
20407 +       buffer += sprintf(buffer,
20408 +               "UseCnt:\t%d\n"
20409 +               "Tasks:\t%d\n"
20410 +               "Flags:\t%016llx\n",
20411 +               atomic_read(&vxi->vx_usecnt),
20412 +               atomic_read(&vxi->vx_tasks),
20413 +               (unsigned long long)vxi->vx_flags);
20414 +
20415 +       buffer += sprintf(buffer, "BCaps:\t");
20416 +       buffer = print_cap_t(buffer, &vxi->vx_bcaps);
20417 +       buffer += sprintf(buffer, "\n");
20418 +
20419 +       buffer += sprintf(buffer,
20420 +               "CCaps:\t%016llx\n"
20421 +               "Umask:\t%16llx\n"
20422 +               "Wmask:\t%16llx\n"
20423 +               "Spaces:\t%08lx %08lx\n",
20424 +               (unsigned long long)vxi->vx_ccaps,
20425 +               (unsigned long long)vxi->vx_umask,
20426 +               (unsigned long long)vxi->vx_wmask,
20427 +               vxi->space[0].vx_nsmask, vxi->space[1].vx_nsmask);
20428 +       return buffer - orig;
20429 +}
20430 +
20431 +int proc_vxi_limit(struct vx_info *vxi, char *buffer)
20432 +{
20433 +       return vx_info_proc_limit(&vxi->limit, buffer);
20434 +}
20435 +
20436 +int proc_vxi_sched(struct vx_info *vxi, char *buffer)
20437 +{
20438 +       int cpu, length;
20439 +
20440 +       length = vx_info_proc_sched(&vxi->sched, buffer);
20441 +       for_each_online_cpu(cpu) {
20442 +               length += vx_info_proc_sched_pc(
20443 +                       &vx_per_cpu(vxi, sched_pc, cpu),
20444 +                       buffer + length, cpu);
20445 +       }
20446 +       return length;
20447 +}
20448 +
20449 +int proc_vxi_nsproxy0(struct vx_info *vxi, char *buffer)
20450 +{
20451 +       return vx_info_proc_nsproxy(vxi->space[0].vx_nsproxy, buffer);
20452 +}
20453 +
20454 +int proc_vxi_nsproxy1(struct vx_info *vxi, char *buffer)
20455 +{
20456 +       return vx_info_proc_nsproxy(vxi->space[1].vx_nsproxy, buffer);
20457 +}
20458 +
20459 +int proc_vxi_cvirt(struct vx_info *vxi, char *buffer)
20460 +{
20461 +       int cpu, length;
20462 +
20463 +       vx_update_load(vxi);
20464 +       length = vx_info_proc_cvirt(&vxi->cvirt, buffer);
20465 +       for_each_online_cpu(cpu) {
20466 +               length += vx_info_proc_cvirt_pc(
20467 +                       &vx_per_cpu(vxi, cvirt_pc, cpu),
20468 +                       buffer + length, cpu);
20469 +       }
20470 +       return length;
20471 +}
20472 +
20473 +int proc_vxi_cacct(struct vx_info *vxi, char *buffer)
20474 +{
20475 +       return vx_info_proc_cacct(&vxi->cacct, buffer);
20476 +}
20477 +
20478 +
20479 +static int proc_virtnet_info(char *buffer)
20480 +{
20481 +       return proc_vci(buffer);
20482 +}
20483 +
20484 +static int proc_virtnet_status(char *buffer)
20485 +{
20486 +       return sprintf(buffer,
20487 +               "#CTotal:\t%d\n"
20488 +               "#CActive:\t%d\n",
20489 +               atomic_read(&nx_global_ctotal),
20490 +               atomic_read(&nx_global_cactive));
20491 +}
20492 +
20493 +int proc_nxi_info(struct nx_info *nxi, char *buffer)
20494 +{
20495 +       struct nx_addr_v4 *v4a;
20496 +#ifdef CONFIG_IPV6
20497 +       struct nx_addr_v6 *v6a;
20498 +#endif
20499 +       int length, i;
20500 +
20501 +       length = sprintf(buffer,
20502 +               "ID:\t%d\n"
20503 +               "Info:\t%p\n"
20504 +               "Bcast:\t" NIPQUAD_FMT "\n"
20505 +               "Lback:\t" NIPQUAD_FMT "\n",
20506 +               nxi->nx_id,
20507 +               nxi,
20508 +               NIPQUAD(nxi->v4_bcast.s_addr),
20509 +               NIPQUAD(nxi->v4_lback.s_addr));
20510 +
20511 +       if (!NX_IPV4(nxi))
20512 +               goto skip_v4;
20513 +       for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
20514 +               length += sprintf(buffer + length, "%d:\t" NXAV4_FMT "\n",
20515 +                       i, NXAV4(v4a));
20516 +skip_v4:
20517 +#ifdef CONFIG_IPV6
20518 +       if (!NX_IPV6(nxi))
20519 +               goto skip_v6;
20520 +       for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
20521 +               length += sprintf(buffer + length, "%d:\t" NXAV6_FMT "\n",
20522 +                       i, NXAV6(v6a));
20523 +skip_v6:
20524 +#endif
20525 +       return length;
20526 +}
20527 +
20528 +int proc_nxi_status(struct nx_info *nxi, char *buffer)
20529 +{
20530 +       int length;
20531 +
20532 +       length = sprintf(buffer,
20533 +               "UseCnt:\t%d\n"
20534 +               "Tasks:\t%d\n"
20535 +               "Flags:\t%016llx\n"
20536 +               "NCaps:\t%016llx\n",
20537 +               atomic_read(&nxi->nx_usecnt),
20538 +               atomic_read(&nxi->nx_tasks),
20539 +               (unsigned long long)nxi->nx_flags,
20540 +               (unsigned long long)nxi->nx_ncaps);
20541 +       return length;
20542 +}
20543 +
20544 +
20545 +
20546 +/* here the inode helpers */
20547 +
20548 +struct vs_entry {
20549 +       int len;
20550 +       char *name;
20551 +       mode_t mode;
20552 +       struct inode_operations *iop;
20553 +       struct file_operations *fop;
20554 +       union proc_op op;
20555 +};
20556 +
20557 +static struct inode *vs_proc_make_inode(struct super_block *sb, struct vs_entry *p)
20558 +{
20559 +       struct inode *inode = new_inode(sb);
20560 +
20561 +       if (!inode)
20562 +               goto out;
20563 +
20564 +       inode->i_mode = p->mode;
20565 +       if (p->iop)
20566 +               inode->i_op = p->iop;
20567 +       if (p->fop)
20568 +               inode->i_fop = p->fop;
20569 +
20570 +       set_nlink(inode, (p->mode & S_IFDIR) ? 2 : 1);
20571 +       inode->i_flags |= S_IMMUTABLE;
20572 +
20573 +       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
20574 +
20575 +       i_uid_write(inode, 0);
20576 +       i_gid_write(inode, 0);
20577 +       i_tag_write(inode, 0);
20578 +out:
20579 +       return inode;
20580 +}
20581 +
20582 +static struct dentry *vs_proc_instantiate(struct inode *dir,
20583 +       struct dentry *dentry, int id, void *ptr)
20584 +{
20585 +       struct vs_entry *p = ptr;
20586 +       struct inode *inode = vs_proc_make_inode(dir->i_sb, p);
20587 +       struct dentry *error = ERR_PTR(-EINVAL);
20588 +
20589 +       if (!inode)
20590 +               goto out;
20591 +
20592 +       PROC_I(inode)->op = p->op;
20593 +       PROC_I(inode)->fd = id;
20594 +       d_add(dentry, inode);
20595 +       error = NULL;
20596 +out:
20597 +       return error;
20598 +}
20599 +
20600 +/* Lookups */
20601 +
20602 +typedef struct dentry *vx_instantiate_t(struct inode *, struct dentry *, int, void *);
20603 +
20604 +
20605 +/*
20606 + * Fill a directory entry.
20607 + *
20608 + * If possible create the dcache entry and derive our inode number and
20609 + * file type from dcache entry.
20610 + *
20611 + * Since all of the proc inode numbers are dynamically generated, the inode
20612 + * numbers do not exist until the inode is cache.  This means creating the
20613 + * the dcache entry in iterate is necessary to keep the inode numbers
20614 + * reported by iterate in sync with the inode numbers reported
20615 + * by stat.
20616 + */
20617 +static int vx_proc_fill_cache(struct file *filp, struct dir_context *ctx,
20618 +       char *name, int len, vx_instantiate_t instantiate, int id, void *ptr)
20619 +{
20620 +       struct dentry *child, *dir = filp->f_path.dentry;
20621 +       struct inode *inode;
20622 +       struct qstr qname;
20623 +       ino_t ino = 0;
20624 +       unsigned type = DT_UNKNOWN;
20625 +
20626 +       qname.name = name;
20627 +       qname.len  = len;
20628 +       qname.hash = full_name_hash(name, len);
20629 +
20630 +       child = d_lookup(dir, &qname);
20631 +       if (!child) {
20632 +               struct dentry *new;
20633 +               new = d_alloc(dir, &qname);
20634 +               if (new) {
20635 +                       child = instantiate(dir->d_inode, new, id, ptr);
20636 +                       if (child)
20637 +                               dput(new);
20638 +                       else
20639 +                               child = new;
20640 +               }
20641 +       }
20642 +       if (!child || IS_ERR(child) || !child->d_inode)
20643 +               goto end_instantiate;
20644 +       inode = child->d_inode;
20645 +       if (inode) {
20646 +               ino = inode->i_ino;
20647 +               type = inode->i_mode >> 12;
20648 +       }
20649 +       dput(child);
20650 +end_instantiate:
20651 +       if (!ino)
20652 +               ino = 1;
20653 +       return !dir_emit(ctx, name, len, ino, type);
20654 +}
20655 +
20656 +
20657 +
20658 +/* get and revalidate vx_info/xid */
20659 +
20660 +static inline
20661 +struct vx_info *get_proc_vx_info(struct inode *inode)
20662 +{
20663 +       return lookup_vx_info(PROC_I(inode)->fd);
20664 +}
20665 +
20666 +static int proc_xid_revalidate(struct dentry *dentry, unsigned int flags)
20667 +{
20668 +       struct inode *inode = dentry->d_inode;
20669 +       vxid_t xid = PROC_I(inode)->fd;
20670 +
20671 +       if (flags & LOOKUP_RCU) /* FIXME: can be dropped? */
20672 +               return -ECHILD;
20673 +
20674 +       if (!xid || xid_is_hashed(xid))
20675 +               return 1;
20676 +       d_drop(dentry);
20677 +       return 0;
20678 +}
20679 +
20680 +
20681 +/* get and revalidate nx_info/nid */
20682 +
20683 +static int proc_nid_revalidate(struct dentry *dentry, unsigned int flags)
20684 +{
20685 +       struct inode *inode = dentry->d_inode;
20686 +       vnid_t nid = PROC_I(inode)->fd;
20687 +
20688 +       if (flags & LOOKUP_RCU) /* FIXME: can be dropped? */
20689 +               return -ECHILD;
20690 +
20691 +       if (!nid || nid_is_hashed(nid))
20692 +               return 1;
20693 +       d_drop(dentry);
20694 +       return 0;
20695 +}
20696 +
20697 +
20698 +
20699 +#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
20700 +
20701 +static ssize_t proc_vs_info_read(struct file *file, char __user *buf,
20702 +                         size_t count, loff_t *ppos)
20703 +{
20704 +       struct inode *inode = file->f_path.dentry->d_inode;
20705 +       unsigned long page;
20706 +       ssize_t length = 0;
20707 +
20708 +       if (count > PROC_BLOCK_SIZE)
20709 +               count = PROC_BLOCK_SIZE;
20710 +
20711 +       /* fade that out as soon as stable */
20712 +       WARN_ON(PROC_I(inode)->fd);
20713 +
20714 +       if (!(page = __get_free_page(GFP_KERNEL)))
20715 +               return -ENOMEM;
20716 +
20717 +       BUG_ON(!PROC_I(inode)->op.proc_vs_read);
20718 +       length = PROC_I(inode)->op.proc_vs_read((char *)page);
20719 +
20720 +       if (length >= 0)
20721 +               length = simple_read_from_buffer(buf, count, ppos,
20722 +                       (char *)page, length);
20723 +
20724 +       free_page(page);
20725 +       return length;
20726 +}
20727 +
20728 +static ssize_t proc_vx_info_read(struct file *file, char __user *buf,
20729 +                         size_t count, loff_t *ppos)
20730 +{
20731 +       struct inode *inode = file->f_path.dentry->d_inode;
20732 +       struct vx_info *vxi = NULL;
20733 +       vxid_t xid = PROC_I(inode)->fd;
20734 +       unsigned long page;
20735 +       ssize_t length = 0;
20736 +
20737 +       if (count > PROC_BLOCK_SIZE)
20738 +               count = PROC_BLOCK_SIZE;
20739 +
20740 +       /* fade that out as soon as stable */
20741 +       WARN_ON(!xid);
20742 +       vxi = lookup_vx_info(xid);
20743 +       if (!vxi)
20744 +               goto out;
20745 +
20746 +       length = -ENOMEM;
20747 +       if (!(page = __get_free_page(GFP_KERNEL)))
20748 +               goto out_put;
20749 +
20750 +       BUG_ON(!PROC_I(inode)->op.proc_vxi_read);
20751 +       length = PROC_I(inode)->op.proc_vxi_read(vxi, (char *)page);
20752 +
20753 +       if (length >= 0)
20754 +               length = simple_read_from_buffer(buf, count, ppos,
20755 +                       (char *)page, length);
20756 +
20757 +       free_page(page);
20758 +out_put:
20759 +       put_vx_info(vxi);
20760 +out:
20761 +       return length;
20762 +}
20763 +
20764 +static ssize_t proc_nx_info_read(struct file *file, char __user *buf,
20765 +                         size_t count, loff_t *ppos)
20766 +{
20767 +       struct inode *inode = file->f_path.dentry->d_inode;
20768 +       struct nx_info *nxi = NULL;
20769 +       vnid_t nid = PROC_I(inode)->fd;
20770 +       unsigned long page;
20771 +       ssize_t length = 0;
20772 +
20773 +       if (count > PROC_BLOCK_SIZE)
20774 +               count = PROC_BLOCK_SIZE;
20775 +
20776 +       /* fade that out as soon as stable */
20777 +       WARN_ON(!nid);
20778 +       nxi = lookup_nx_info(nid);
20779 +       if (!nxi)
20780 +               goto out;
20781 +
20782 +       length = -ENOMEM;
20783 +       if (!(page = __get_free_page(GFP_KERNEL)))
20784 +               goto out_put;
20785 +
20786 +       BUG_ON(!PROC_I(inode)->op.proc_nxi_read);
20787 +       length = PROC_I(inode)->op.proc_nxi_read(nxi, (char *)page);
20788 +
20789 +       if (length >= 0)
20790 +               length = simple_read_from_buffer(buf, count, ppos,
20791 +                       (char *)page, length);
20792 +
20793 +       free_page(page);
20794 +out_put:
20795 +       put_nx_info(nxi);
20796 +out:
20797 +       return length;
20798 +}
20799 +
20800 +
20801 +
20802 +/* here comes the lower level */
20803 +
20804 +
20805 +#define NOD(NAME, MODE, IOP, FOP, OP) {        \
20806 +       .len  = sizeof(NAME) - 1,       \
20807 +       .name = (NAME),                 \
20808 +       .mode = MODE,                   \
20809 +       .iop  = IOP,                    \
20810 +       .fop  = FOP,                    \
20811 +       .op   = OP,                     \
20812 +}
20813 +
20814 +
20815 +#define DIR(NAME, MODE, OTYPE)                         \
20816 +       NOD(NAME, (S_IFDIR | (MODE)),                   \
20817 +               &proc_ ## OTYPE ## _inode_operations,   \
20818 +               &proc_ ## OTYPE ## _file_operations, { } )
20819 +
20820 +#define INF(NAME, MODE, OTYPE)                         \
20821 +       NOD(NAME, (S_IFREG | (MODE)), NULL,             \
20822 +               &proc_vs_info_file_operations,          \
20823 +               { .proc_vs_read = &proc_##OTYPE } )
20824 +
20825 +#define VINF(NAME, MODE, OTYPE)                                \
20826 +       NOD(NAME, (S_IFREG | (MODE)), NULL,             \
20827 +               &proc_vx_info_file_operations,          \
20828 +               { .proc_vxi_read = &proc_##OTYPE } )
20829 +
20830 +#define NINF(NAME, MODE, OTYPE)                                \
20831 +       NOD(NAME, (S_IFREG | (MODE)), NULL,             \
20832 +               &proc_nx_info_file_operations,          \
20833 +               { .proc_nxi_read = &proc_##OTYPE } )
20834 +
20835 +
20836 +static struct file_operations proc_vs_info_file_operations = {
20837 +       .read =         proc_vs_info_read,
20838 +};
20839 +
20840 +static struct file_operations proc_vx_info_file_operations = {
20841 +       .read =         proc_vx_info_read,
20842 +};
20843 +
20844 +static struct dentry_operations proc_xid_dentry_operations = {
20845 +       .d_revalidate = proc_xid_revalidate,
20846 +};
20847 +
20848 +static struct vs_entry vx_base_stuff[] = {
20849 +       VINF("info",    S_IRUGO, vxi_info),
20850 +       VINF("status",  S_IRUGO, vxi_status),
20851 +       VINF("limit",   S_IRUGO, vxi_limit),
20852 +       VINF("sched",   S_IRUGO, vxi_sched),
20853 +       VINF("nsproxy", S_IRUGO, vxi_nsproxy0),
20854 +       VINF("nsproxy1",S_IRUGO, vxi_nsproxy1),
20855 +       VINF("cvirt",   S_IRUGO, vxi_cvirt),
20856 +       VINF("cacct",   S_IRUGO, vxi_cacct),
20857 +       {}
20858 +};
20859 +
20860 +
20861 +
20862 +
20863 +static struct dentry *proc_xid_instantiate(struct inode *dir,
20864 +       struct dentry *dentry, int id, void *ptr)
20865 +{
20866 +       dentry->d_op = &proc_xid_dentry_operations;
20867 +       return vs_proc_instantiate(dir, dentry, id, ptr);
20868 +}
20869 +
20870 +static struct dentry *proc_xid_lookup(struct inode *dir,
20871 +       struct dentry *dentry, unsigned int flags)
20872 +{
20873 +       struct vs_entry *p = vx_base_stuff;
20874 +       struct dentry *error = ERR_PTR(-ENOENT);
20875 +
20876 +       for (; p->name; p++) {
20877 +               if (p->len != dentry->d_name.len)
20878 +                       continue;
20879 +               if (!memcmp(dentry->d_name.name, p->name, p->len))
20880 +                       break;
20881 +       }
20882 +       if (!p->name)
20883 +               goto out;
20884 +
20885 +       error = proc_xid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
20886 +out:
20887 +       return error;
20888 +}
20889 +
20890 +static int proc_xid_iterate(struct file *filp, struct dir_context *ctx)
20891 +{
20892 +       struct dentry *dentry = filp->f_path.dentry;
20893 +       struct inode *inode = dentry->d_inode;
20894 +       struct vs_entry *p = vx_base_stuff;
20895 +       int size = sizeof(vx_base_stuff) / sizeof(struct vs_entry);
20896 +       int index;
20897 +       u64 ino;
20898 +
20899 +       switch (ctx->pos) {
20900 +       case 0:
20901 +               ino = inode->i_ino;
20902 +               if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
20903 +                       goto out;
20904 +               ctx->pos++;
20905 +               /* fall through */
20906 +       case 1:
20907 +               ino = parent_ino(dentry);
20908 +               if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
20909 +                       goto out;
20910 +               ctx->pos++;
20911 +               /* fall through */
20912 +       default:
20913 +               index = ctx->pos - 2;
20914 +               if (index >= size)
20915 +                       goto out;
20916 +               for (p += index; p->name; p++) {
20917 +                       if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
20918 +                               vs_proc_instantiate, PROC_I(inode)->fd, p))
20919 +                               goto out;
20920 +                       ctx->pos++;
20921 +               }
20922 +       }
20923 +out:
20924 +       return 1;
20925 +}
20926 +
20927 +
20928 +
20929 +static struct file_operations proc_nx_info_file_operations = {
20930 +       .read =         proc_nx_info_read,
20931 +};
20932 +
20933 +static struct dentry_operations proc_nid_dentry_operations = {
20934 +       .d_revalidate = proc_nid_revalidate,
20935 +};
20936 +
20937 +static struct vs_entry nx_base_stuff[] = {
20938 +       NINF("info",    S_IRUGO, nxi_info),
20939 +       NINF("status",  S_IRUGO, nxi_status),
20940 +       {}
20941 +};
20942 +
20943 +
20944 +static struct dentry *proc_nid_instantiate(struct inode *dir,
20945 +       struct dentry *dentry, int id, void *ptr)
20946 +{
20947 +       dentry->d_op = &proc_nid_dentry_operations;
20948 +       return vs_proc_instantiate(dir, dentry, id, ptr);
20949 +}
20950 +
20951 +static struct dentry *proc_nid_lookup(struct inode *dir,
20952 +       struct dentry *dentry, unsigned int flags)
20953 +{
20954 +       struct vs_entry *p = nx_base_stuff;
20955 +       struct dentry *error = ERR_PTR(-ENOENT);
20956 +
20957 +       for (; p->name; p++) {
20958 +               if (p->len != dentry->d_name.len)
20959 +                       continue;
20960 +               if (!memcmp(dentry->d_name.name, p->name, p->len))
20961 +                       break;
20962 +       }
20963 +       if (!p->name)
20964 +               goto out;
20965 +
20966 +       error = proc_nid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
20967 +out:
20968 +       return error;
20969 +}
20970 +
20971 +static int proc_nid_iterate(struct file *filp, struct dir_context *ctx)
20972 +{
20973 +       struct dentry *dentry = filp->f_path.dentry;
20974 +       struct inode *inode = dentry->d_inode;
20975 +       struct vs_entry *p = nx_base_stuff;
20976 +       int size = sizeof(nx_base_stuff) / sizeof(struct vs_entry);
20977 +       int index;
20978 +       u64 ino;
20979 +
20980 +       switch (ctx->pos) {
20981 +       case 0:
20982 +               ino = inode->i_ino;
20983 +               if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
20984 +                       goto out;
20985 +               ctx->pos++;
20986 +               /* fall through */
20987 +       case 1:
20988 +               ino = parent_ino(dentry);
20989 +               if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
20990 +                       goto out;
20991 +               ctx->pos++;
20992 +               /* fall through */
20993 +       default:
20994 +               index = ctx->pos - 2;
20995 +               if (index >= size)
20996 +                       goto out;
20997 +               for (p += index; p->name; p++) {
20998 +                       if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
20999 +                               vs_proc_instantiate, PROC_I(inode)->fd, p))
21000 +                               goto out;
21001 +                       ctx->pos++;
21002 +               }
21003 +       }
21004 +out:
21005 +       return 1;
21006 +}
21007 +
21008 +
21009 +#define MAX_MULBY10    ((~0U - 9) / 10)
21010 +
21011 +static inline int atovid(const char *str, int len)
21012 +{
21013 +       int vid, c;
21014 +
21015 +       vid = 0;
21016 +       while (len-- > 0) {
21017 +               c = *str - '0';
21018 +               str++;
21019 +               if (c > 9)
21020 +                       return -1;
21021 +               if (vid >= MAX_MULBY10)
21022 +                       return -1;
21023 +               vid *= 10;
21024 +               vid += c;
21025 +               if (!vid)
21026 +                       return -1;
21027 +       }
21028 +       return vid;
21029 +}
21030 +
21031 +/* now the upper level (virtual) */
21032 +
21033 +
21034 +static struct file_operations proc_xid_file_operations = {
21035 +       .read =         generic_read_dir,
21036 +       .iterate =      proc_xid_iterate,
21037 +};
21038 +
21039 +static struct inode_operations proc_xid_inode_operations = {
21040 +       .lookup =       proc_xid_lookup,
21041 +};
21042 +
21043 +static struct vs_entry vx_virtual_stuff[] = {
21044 +       INF("info",     S_IRUGO, virtual_info),
21045 +       INF("status",   S_IRUGO, virtual_status),
21046 +       DIR(NULL,       S_IRUGO | S_IXUGO, xid),
21047 +};
21048 +
21049 +
21050 +static struct dentry *proc_virtual_lookup(struct inode *dir,
21051 +       struct dentry *dentry, unsigned int flags)
21052 +{
21053 +       struct vs_entry *p = vx_virtual_stuff;
21054 +       struct dentry *error = ERR_PTR(-ENOENT);
21055 +       int id = 0;
21056 +
21057 +       for (; p->name; p++) {
21058 +               if (p->len != dentry->d_name.len)
21059 +                       continue;
21060 +               if (!memcmp(dentry->d_name.name, p->name, p->len))
21061 +                       break;
21062 +       }
21063 +       if (p->name)
21064 +               goto instantiate;
21065 +
21066 +       id = atovid(dentry->d_name.name, dentry->d_name.len);
21067 +       if ((id < 0) || !xid_is_hashed(id))
21068 +               goto out;
21069 +
21070 +instantiate:
21071 +       error = proc_xid_instantiate(dir, dentry, id, p);
21072 +out:
21073 +       return error;
21074 +}
21075 +
21076 +static struct file_operations proc_nid_file_operations = {
21077 +       .read =         generic_read_dir,
21078 +       .iterate =      proc_nid_iterate,
21079 +};
21080 +
21081 +static struct inode_operations proc_nid_inode_operations = {
21082 +       .lookup =       proc_nid_lookup,
21083 +};
21084 +
21085 +static struct vs_entry nx_virtnet_stuff[] = {
21086 +       INF("info",     S_IRUGO, virtnet_info),
21087 +       INF("status",   S_IRUGO, virtnet_status),
21088 +       DIR(NULL,       S_IRUGO | S_IXUGO, nid),
21089 +};
21090 +
21091 +
21092 +static struct dentry *proc_virtnet_lookup(struct inode *dir,
21093 +       struct dentry *dentry, unsigned int flags)
21094 +{
21095 +       struct vs_entry *p = nx_virtnet_stuff;
21096 +       struct dentry *error = ERR_PTR(-ENOENT);
21097 +       int id = 0;
21098 +
21099 +       for (; p->name; p++) {
21100 +               if (p->len != dentry->d_name.len)
21101 +                       continue;
21102 +               if (!memcmp(dentry->d_name.name, p->name, p->len))
21103 +                       break;
21104 +       }
21105 +       if (p->name)
21106 +               goto instantiate;
21107 +
21108 +       id = atovid(dentry->d_name.name, dentry->d_name.len);
21109 +       if ((id < 0) || !nid_is_hashed(id))
21110 +               goto out;
21111 +
21112 +instantiate:
21113 +       error = proc_nid_instantiate(dir, dentry, id, p);
21114 +out:
21115 +       return error;
21116 +}
21117 +
21118 +
21119 +#define PROC_MAXVIDS 32
21120 +
21121 +int proc_virtual_iterate(struct file *filp, struct dir_context *ctx)
21122 +{
21123 +       struct dentry *dentry = filp->f_path.dentry;
21124 +       struct inode *inode = dentry->d_inode;
21125 +       struct vs_entry *p = vx_virtual_stuff;
21126 +       int size = sizeof(vx_virtual_stuff) / sizeof(struct vs_entry);
21127 +       int index;
21128 +       unsigned int xid_array[PROC_MAXVIDS];
21129 +       char buf[PROC_NUMBUF];
21130 +       unsigned int nr_xids, i;
21131 +       u64 ino;
21132 +
21133 +       switch (ctx->pos) {
21134 +       case 0:
21135 +               ino = inode->i_ino;
21136 +               if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
21137 +                       goto out;
21138 +               ctx->pos++;
21139 +               /* fall through */
21140 +       case 1:
21141 +               ino = parent_ino(dentry);
21142 +               if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
21143 +                       goto out;
21144 +               ctx->pos++;
21145 +               /* fall through */
21146 +       default:
21147 +               index = ctx->pos - 2;
21148 +               if (index >= size)
21149 +                       goto entries;
21150 +               for (p += index; p->name; p++) {
21151 +                       if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
21152 +                               vs_proc_instantiate, 0, p))
21153 +                               goto out;
21154 +                       ctx->pos++;
21155 +               }
21156 +       entries:
21157 +               index = ctx->pos - size;
21158 +               p = &vx_virtual_stuff[size - 1];
21159 +               nr_xids = get_xid_list(index, xid_array, PROC_MAXVIDS);
21160 +               for (i = 0; i < nr_xids; i++) {
21161 +                       int n, xid = xid_array[i];
21162 +                       unsigned int j = PROC_NUMBUF;
21163 +
21164 +                       n = xid;
21165 +                       do
21166 +                               buf[--j] = '0' + (n % 10);
21167 +                       while (n /= 10);
21168 +
21169 +                       if (vx_proc_fill_cache(filp, ctx,
21170 +                               buf + j, PROC_NUMBUF - j,
21171 +                               vs_proc_instantiate, xid, p))
21172 +                               goto out;
21173 +                       ctx->pos++;
21174 +               }
21175 +       }
21176 +out:
21177 +       return 0;
21178 +}
21179 +
21180 +static int proc_virtual_getattr(struct vfsmount *mnt,
21181 +       struct dentry *dentry, struct kstat *stat)
21182 +{
21183 +       struct inode *inode = dentry->d_inode;
21184 +
21185 +       generic_fillattr(inode, stat);
21186 +       stat->nlink = 2 + atomic_read(&vx_global_cactive);
21187 +       return 0;
21188 +}
21189 +
21190 +static struct file_operations proc_virtual_dir_operations = {
21191 +       .read =         generic_read_dir,
21192 +       .iterate =      proc_virtual_iterate,
21193 +};
21194 +
21195 +static struct inode_operations proc_virtual_dir_inode_operations = {
21196 +       .getattr =      proc_virtual_getattr,
21197 +       .lookup =       proc_virtual_lookup,
21198 +};
21199 +
21200 +
21201 +
21202 +int proc_virtnet_iterate(struct file *filp, struct dir_context *ctx)
21203 +{
21204 +       struct dentry *dentry = filp->f_path.dentry;
21205 +       struct inode *inode = dentry->d_inode;
21206 +       struct vs_entry *p = nx_virtnet_stuff;
21207 +       int size = sizeof(nx_virtnet_stuff) / sizeof(struct vs_entry);
21208 +       int index;
21209 +       unsigned int nid_array[PROC_MAXVIDS];
21210 +       char buf[PROC_NUMBUF];
21211 +       unsigned int nr_nids, i;
21212 +       u64 ino;
21213 +
21214 +       switch (ctx->pos) {
21215 +       case 0:
21216 +               ino = inode->i_ino;
21217 +               if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
21218 +                       goto out;
21219 +               ctx->pos++;
21220 +               /* fall through */
21221 +       case 1:
21222 +               ino = parent_ino(dentry);
21223 +               if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
21224 +                       goto out;
21225 +               ctx->pos++;
21226 +               /* fall through */
21227 +       default:
21228 +               index = ctx->pos - 2;
21229 +               if (index >= size)
21230 +                       goto entries;
21231 +               for (p += index; p->name; p++) {
21232 +                       if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
21233 +                               vs_proc_instantiate, 0, p))
21234 +                               goto out;
21235 +                       ctx->pos++;
21236 +               }
21237 +       entries:
21238 +               index = ctx->pos - size;
21239 +               p = &nx_virtnet_stuff[size - 1];
21240 +               nr_nids = get_nid_list(index, nid_array, PROC_MAXVIDS);
21241 +               for (i = 0; i < nr_nids; i++) {
21242 +                       int n, nid = nid_array[i];
21243 +                       unsigned int j = PROC_NUMBUF;
21244 +
21245 +                       n = nid;
21246 +                       do
21247 +                               buf[--j] = '0' + (n % 10);
21248 +                       while (n /= 10);
21249 +
21250 +                       if (vx_proc_fill_cache(filp, ctx,
21251 +                               buf + j, PROC_NUMBUF - j,
21252 +                               vs_proc_instantiate, nid, p))
21253 +                               goto out;
21254 +                       ctx->pos++;
21255 +               }
21256 +       }
21257 +out:
21258 +       return 0;
21259 +}
21260 +
21261 +static int proc_virtnet_getattr(struct vfsmount *mnt,
21262 +       struct dentry *dentry, struct kstat *stat)
21263 +{
21264 +       struct inode *inode = dentry->d_inode;
21265 +
21266 +       generic_fillattr(inode, stat);
21267 +       stat->nlink = 2 + atomic_read(&nx_global_cactive);
21268 +       return 0;
21269 +}
21270 +
21271 +static struct file_operations proc_virtnet_dir_operations = {
21272 +       .read =         generic_read_dir,
21273 +       .iterate =      proc_virtnet_iterate,
21274 +};
21275 +
21276 +static struct inode_operations proc_virtnet_dir_inode_operations = {
21277 +       .getattr =      proc_virtnet_getattr,
21278 +       .lookup =       proc_virtnet_lookup,
21279 +};
21280 +
21281 +
21282 +
21283 +void proc_vx_init(void)
21284 +{
21285 +       struct proc_dir_entry *ent;
21286 +
21287 +       ent = proc_mkdir("virtual", 0);
21288 +       if (ent) {
21289 +               ent->proc_fops = &proc_virtual_dir_operations;
21290 +               ent->proc_iops = &proc_virtual_dir_inode_operations;
21291 +       }
21292 +       proc_virtual = ent;
21293 +
21294 +       ent = proc_mkdir("virtnet", 0);
21295 +       if (ent) {
21296 +               ent->proc_fops = &proc_virtnet_dir_operations;
21297 +               ent->proc_iops = &proc_virtnet_dir_inode_operations;
21298 +       }
21299 +       proc_virtnet = ent;
21300 +}
21301 +
21302 +
21303 +
21304 +
21305 +/* per pid info */
21306 +
21307 +void render_cap_t(struct seq_file *, const char *,
21308 +       struct vx_info *, kernel_cap_t *);
21309 +
21310 +
21311 +int proc_pid_vx_info(
21312 +       struct seq_file *m,
21313 +       struct pid_namespace *ns,
21314 +       struct pid *pid,
21315 +       struct task_struct *p)
21316 +{
21317 +       struct vx_info *vxi;
21318 +
21319 +       seq_printf(m, "XID:\t%d\n", vx_task_xid(p));
21320 +
21321 +       vxi = task_get_vx_info(p);
21322 +       if (!vxi)
21323 +               return 0;
21324 +
21325 +       render_cap_t(m, "BCaps:\t", vxi, &vxi->vx_bcaps);
21326 +       seq_printf(m, "CCaps:\t%016llx\n",
21327 +               (unsigned long long)vxi->vx_ccaps);
21328 +       seq_printf(m, "CFlags:\t%016llx\n",
21329 +               (unsigned long long)vxi->vx_flags);
21330 +       seq_printf(m, "CIPid:\t%d\n", vxi->vx_initpid);
21331 +
21332 +       put_vx_info(vxi);
21333 +       return 0;
21334 +}
21335 +
21336 +
21337 +int proc_pid_nx_info(
21338 +       struct seq_file *m,
21339 +       struct pid_namespace *ns,
21340 +       struct pid *pid,
21341 +       struct task_struct *p)
21342 +{
21343 +       struct nx_info *nxi;
21344 +       struct nx_addr_v4 *v4a;
21345 +#ifdef CONFIG_IPV6
21346 +       struct nx_addr_v6 *v6a;
21347 +#endif
21348 +       int i;
21349 +
21350 +       seq_printf(m, "NID:\t%d\n", nx_task_nid(p));
21351 +
21352 +       nxi = task_get_nx_info(p);
21353 +       if (!nxi)
21354 +               return 0;
21355 +
21356 +       seq_printf(m, "NCaps:\t%016llx\n",
21357 +               (unsigned long long)nxi->nx_ncaps);
21358 +       seq_printf(m, "NFlags:\t%016llx\n",
21359 +               (unsigned long long)nxi->nx_flags);
21360 +
21361 +       seq_printf(m, "V4Root[bcast]:\t" NIPQUAD_FMT "\n",
21362 +               NIPQUAD(nxi->v4_bcast.s_addr));
21363 +       seq_printf(m, "V4Root[lback]:\t" NIPQUAD_FMT "\n",
21364 +               NIPQUAD(nxi->v4_lback.s_addr));
21365 +       if (!NX_IPV4(nxi))
21366 +               goto skip_v4;
21367 +       for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
21368 +               seq_printf(m, "V4Root[%d]:\t" NXAV4_FMT "\n",
21369 +                       i, NXAV4(v4a));
21370 +skip_v4:
21371 +#ifdef CONFIG_IPV6
21372 +       if (!NX_IPV6(nxi))
21373 +               goto skip_v6;
21374 +       for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
21375 +               seq_printf(m, "V6Root[%d]:\t" NXAV6_FMT "\n",
21376 +                       i, NXAV6(v6a));
21377 +skip_v6:
21378 +#endif
21379 +       put_nx_info(nxi);
21380 +       return 0;
21381 +}
21382 +
21383 diff -NurpP --minimal linux-4.1.41/kernel/vserver/sched.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/sched.c
21384 --- linux-4.1.41/kernel/vserver/sched.c 1970-01-01 00:00:00.000000000 +0000
21385 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/sched.c     2016-07-05 04:41:47.000000000 +0000
21386 @@ -0,0 +1,83 @@
21387 +/*
21388 + *  linux/kernel/vserver/sched.c
21389 + *
21390 + *  Virtual Server: Scheduler Support
21391 + *
21392 + *  Copyright (C) 2004-2010  Herbert Pötzl
21393 + *
21394 + *  V0.01  adapted Sam Vilains version to 2.6.3
21395 + *  V0.02  removed legacy interface
21396 + *  V0.03  changed vcmds to vxi arg
21397 + *  V0.04  removed older and legacy interfaces
21398 + *  V0.05  removed scheduler code/commands
21399 + *
21400 + */
21401 +
21402 +#include <linux/vs_context.h>
21403 +#include <linux/vs_sched.h>
21404 +#include <linux/cpumask.h>
21405 +#include <linux/vserver/sched_cmd.h>
21406 +
21407 +#include <asm/uaccess.h>
21408 +
21409 +
21410 +void vx_update_sched_param(struct _vx_sched *sched,
21411 +       struct _vx_sched_pc *sched_pc)
21412 +{
21413 +       sched_pc->prio_bias = sched->prio_bias;
21414 +}
21415 +
21416 +static int do_set_prio_bias(struct vx_info *vxi, struct vcmd_prio_bias *data)
21417 +{
21418 +       int cpu;
21419 +
21420 +       if (data->prio_bias > MAX_PRIO_BIAS)
21421 +               data->prio_bias = MAX_PRIO_BIAS;
21422 +       if (data->prio_bias < MIN_PRIO_BIAS)
21423 +               data->prio_bias = MIN_PRIO_BIAS;
21424 +
21425 +       if (data->cpu_id != ~0) {
21426 +               vxi->sched.update = *get_cpu_mask(data->cpu_id);
21427 +               cpumask_and(&vxi->sched.update, &vxi->sched.update,
21428 +                       cpu_online_mask);
21429 +       } else
21430 +               cpumask_copy(&vxi->sched.update, cpu_online_mask);
21431 +
21432 +       for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)vxi->sched.update)
21433 +               vx_update_sched_param(&vxi->sched,
21434 +                       &vx_per_cpu(vxi, sched_pc, cpu));
21435 +       return 0;
21436 +}
21437 +
21438 +int vc_set_prio_bias(struct vx_info *vxi, void __user *data)
21439 +{
21440 +       struct vcmd_prio_bias vc_data;
21441 +
21442 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21443 +               return -EFAULT;
21444 +
21445 +       return do_set_prio_bias(vxi, &vc_data);
21446 +}
21447 +
21448 +int vc_get_prio_bias(struct vx_info *vxi, void __user *data)
21449 +{
21450 +       struct vcmd_prio_bias vc_data;
21451 +       struct _vx_sched_pc *pcd;
21452 +       int cpu;
21453 +
21454 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21455 +               return -EFAULT;
21456 +
21457 +       cpu = vc_data.cpu_id;
21458 +
21459 +       if (!cpu_possible(cpu))
21460 +               return -EINVAL;
21461 +
21462 +       pcd = &vx_per_cpu(vxi, sched_pc, cpu);
21463 +       vc_data.prio_bias = pcd->prio_bias;
21464 +
21465 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
21466 +               return -EFAULT;
21467 +       return 0;
21468 +}
21469 +
21470 diff -NurpP --minimal linux-4.1.41/kernel/vserver/sched_init.h linux-4.1.41-vs2.3.8.5.3/kernel/vserver/sched_init.h
21471 --- linux-4.1.41/kernel/vserver/sched_init.h    1970-01-01 00:00:00.000000000 +0000
21472 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/sched_init.h        2016-07-05 04:41:47.000000000 +0000
21473 @@ -0,0 +1,27 @@
21474 +
21475 +static inline void vx_info_init_sched(struct _vx_sched *sched)
21476 +{
21477 +       /* scheduling; hard code starting values as constants */
21478 +       sched->prio_bias = 0;
21479 +}
21480 +
21481 +static inline
21482 +void vx_info_init_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
21483 +{
21484 +       sched_pc->prio_bias = 0;
21485 +
21486 +       sched_pc->user_ticks = 0;
21487 +       sched_pc->sys_ticks = 0;
21488 +       sched_pc->hold_ticks = 0;
21489 +}
21490 +
21491 +static inline void vx_info_exit_sched(struct _vx_sched *sched)
21492 +{
21493 +       return;
21494 +}
21495 +
21496 +static inline
21497 +void vx_info_exit_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
21498 +{
21499 +       return;
21500 +}
21501 diff -NurpP --minimal linux-4.1.41/kernel/vserver/sched_proc.h linux-4.1.41-vs2.3.8.5.3/kernel/vserver/sched_proc.h
21502 --- linux-4.1.41/kernel/vserver/sched_proc.h    1970-01-01 00:00:00.000000000 +0000
21503 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/sched_proc.h        2016-07-05 04:41:47.000000000 +0000
21504 @@ -0,0 +1,32 @@
21505 +#ifndef _VX_SCHED_PROC_H
21506 +#define _VX_SCHED_PROC_H
21507 +
21508 +
21509 +static inline
21510 +int vx_info_proc_sched(struct _vx_sched *sched, char *buffer)
21511 +{
21512 +       int length = 0;
21513 +
21514 +       length += sprintf(buffer,
21515 +               "PrioBias:\t%8d\n",
21516 +               sched->prio_bias);
21517 +       return length;
21518 +}
21519 +
21520 +static inline
21521 +int vx_info_proc_sched_pc(struct _vx_sched_pc *sched_pc,
21522 +       char *buffer, int cpu)
21523 +{
21524 +       int length = 0;
21525 +
21526 +       length += sprintf(buffer + length,
21527 +               "cpu %d: %lld %lld %lld", cpu,
21528 +               (unsigned long long)sched_pc->user_ticks,
21529 +               (unsigned long long)sched_pc->sys_ticks,
21530 +               (unsigned long long)sched_pc->hold_ticks);
21531 +       length += sprintf(buffer + length,
21532 +               " %d\n", sched_pc->prio_bias);
21533 +       return length;
21534 +}
21535 +
21536 +#endif /* _VX_SCHED_PROC_H */
21537 diff -NurpP --minimal linux-4.1.41/kernel/vserver/signal.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/signal.c
21538 --- linux-4.1.41/kernel/vserver/signal.c        1970-01-01 00:00:00.000000000 +0000
21539 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/signal.c    2016-07-05 04:41:47.000000000 +0000
21540 @@ -0,0 +1,134 @@
21541 +/*
21542 + *  linux/kernel/vserver/signal.c
21543 + *
21544 + *  Virtual Server: Signal Support
21545 + *
21546 + *  Copyright (C) 2003-2007  Herbert Pötzl
21547 + *
21548 + *  V0.01  broken out from vcontext V0.05
21549 + *  V0.02  changed vcmds to vxi arg
21550 + *  V0.03  adjusted siginfo for kill
21551 + *
21552 + */
21553 +
21554 +#include <asm/uaccess.h>
21555 +
21556 +#include <linux/vs_context.h>
21557 +#include <linux/vs_pid.h>
21558 +#include <linux/vserver/signal_cmd.h>
21559 +
21560 +
21561 +int vx_info_kill(struct vx_info *vxi, int pid, int sig)
21562 +{
21563 +       int retval, count = 0;
21564 +       struct task_struct *p;
21565 +       struct siginfo *sip = SEND_SIG_PRIV;
21566 +
21567 +       retval = -ESRCH;
21568 +       vxdprintk(VXD_CBIT(misc, 4),
21569 +               "vx_info_kill(%p[#%d],%d,%d)*",
21570 +               vxi, vxi->vx_id, pid, sig);
21571 +       read_lock(&tasklist_lock);
21572 +       switch (pid) {
21573 +       case  0:
21574 +       case -1:
21575 +               for_each_process(p) {
21576 +                       int err = 0;
21577 +
21578 +                       if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
21579 +                               (pid && vxi->vx_initpid == p->pid))
21580 +                               continue;
21581 +
21582 +                       err = group_send_sig_info(sig, sip, p);
21583 +                       ++count;
21584 +                       if (err != -EPERM)
21585 +                               retval = err;
21586 +               }
21587 +               break;
21588 +
21589 +       case 1:
21590 +               if (vxi->vx_initpid) {
21591 +                       pid = vxi->vx_initpid;
21592 +                       /* for now, only SIGINT to private init ... */
21593 +                       if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
21594 +                               /* ... as long as there are tasks left */
21595 +                               (atomic_read(&vxi->vx_tasks) > 1))
21596 +                               sig = SIGINT;
21597 +               }
21598 +               /* fallthrough */
21599 +       default:
21600 +               rcu_read_lock();
21601 +               p = find_task_by_real_pid(pid);
21602 +               rcu_read_unlock();
21603 +               if (p) {
21604 +                       if (vx_task_xid(p) == vxi->vx_id)
21605 +                               retval = group_send_sig_info(sig, sip, p);
21606 +               }
21607 +               break;
21608 +       }
21609 +       read_unlock(&tasklist_lock);
21610 +       vxdprintk(VXD_CBIT(misc, 4),
21611 +               "vx_info_kill(%p[#%d],%d,%d,%ld) = %d",
21612 +               vxi, vxi->vx_id, pid, sig, (long)sip, retval);
21613 +       return retval;
21614 +}
21615 +
21616 +int vc_ctx_kill(struct vx_info *vxi, void __user *data)
21617 +{
21618 +       struct vcmd_ctx_kill_v0 vc_data;
21619 +
21620 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21621 +               return -EFAULT;
21622 +
21623 +       /* special check to allow guest shutdown */
21624 +       if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
21625 +               /* forbid killall pid=0 when init is present */
21626 +               (((vc_data.pid < 1) && vxi->vx_initpid) ||
21627 +               (vc_data.pid > 1)))
21628 +               return -EACCES;
21629 +
21630 +       return vx_info_kill(vxi, vc_data.pid, vc_data.sig);
21631 +}
21632 +
21633 +
21634 +static int __wait_exit(struct vx_info *vxi)
21635 +{
21636 +       DECLARE_WAITQUEUE(wait, current);
21637 +       int ret = 0;
21638 +
21639 +       add_wait_queue(&vxi->vx_wait, &wait);
21640 +       set_current_state(TASK_INTERRUPTIBLE);
21641 +
21642 +wait:
21643 +       if (vx_info_state(vxi,
21644 +               VXS_SHUTDOWN | VXS_HASHED | VXS_HELPER) == VXS_SHUTDOWN)
21645 +               goto out;
21646 +       if (signal_pending(current)) {
21647 +               ret = -ERESTARTSYS;
21648 +               goto out;
21649 +       }
21650 +       schedule();
21651 +       goto wait;
21652 +
21653 +out:
21654 +       set_current_state(TASK_RUNNING);
21655 +       remove_wait_queue(&vxi->vx_wait, &wait);
21656 +       return ret;
21657 +}
21658 +
21659 +
21660 +
21661 +int vc_wait_exit(struct vx_info *vxi, void __user *data)
21662 +{
21663 +       struct vcmd_wait_exit_v0 vc_data;
21664 +       int ret;
21665 +
21666 +       ret = __wait_exit(vxi);
21667 +       vc_data.reboot_cmd = vxi->reboot_cmd;
21668 +       vc_data.exit_code = vxi->exit_code;
21669 +
21670 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
21671 +               ret = -EFAULT;
21672 +       return ret;
21673 +}
21674 +
21675 diff -NurpP --minimal linux-4.1.41/kernel/vserver/space.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/space.c
21676 --- linux-4.1.41/kernel/vserver/space.c 1970-01-01 00:00:00.000000000 +0000
21677 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/space.c     2016-07-05 04:41:47.000000000 +0000
21678 @@ -0,0 +1,436 @@
21679 +/*
21680 + *  linux/kernel/vserver/space.c
21681 + *
21682 + *  Virtual Server: Context Space Support
21683 + *
21684 + *  Copyright (C) 2003-2010  Herbert Pötzl
21685 + *
21686 + *  V0.01  broken out from context.c 0.07
21687 + *  V0.02  added task locking for namespace
21688 + *  V0.03  broken out vx_enter_namespace
21689 + *  V0.04  added *space support and commands
21690 + *  V0.05  added credential support
21691 + *
21692 + */
21693 +
21694 +#include <linux/utsname.h>
21695 +#include <linux/nsproxy.h>
21696 +#include <linux/err.h>
21697 +#include <linux/fs_struct.h>
21698 +#include <linux/cred.h>
21699 +#include <asm/uaccess.h>
21700 +
21701 +#include <linux/vs_context.h>
21702 +#include <linux/vserver/space.h>
21703 +#include <linux/vserver/space_cmd.h>
21704 +
21705 +atomic_t vs_global_nsproxy     = ATOMIC_INIT(0);
21706 +atomic_t vs_global_fs          = ATOMIC_INIT(0);
21707 +atomic_t vs_global_mnt_ns      = ATOMIC_INIT(0);
21708 +atomic_t vs_global_uts_ns      = ATOMIC_INIT(0);
21709 +atomic_t vs_global_user_ns     = ATOMIC_INIT(0);
21710 +atomic_t vs_global_pid_ns      = ATOMIC_INIT(0);
21711 +
21712 +
21713 +/* namespace functions */
21714 +
21715 +#include <linux/mnt_namespace.h>
21716 +#include <linux/user_namespace.h>
21717 +#include <linux/pid_namespace.h>
21718 +#include <linux/ipc_namespace.h>
21719 +#include <net/net_namespace.h>
21720 +#include "../fs/mount.h"
21721 +
21722 +
21723 +static const struct vcmd_space_mask_v1 space_mask_v0 = {
21724 +       .mask = CLONE_FS |
21725 +               CLONE_NEWNS |
21726 +#ifdef CONFIG_UTS_NS
21727 +               CLONE_NEWUTS |
21728 +#endif
21729 +#ifdef CONFIG_IPC_NS
21730 +               CLONE_NEWIPC |
21731 +#endif
21732 +#ifdef CONFIG_USER_NS
21733 +               CLONE_NEWUSER |
21734 +#endif
21735 +               0
21736 +};
21737 +
21738 +static const struct vcmd_space_mask_v1 space_mask = {
21739 +       .mask = CLONE_FS |
21740 +               CLONE_NEWNS |
21741 +#ifdef CONFIG_UTS_NS
21742 +               CLONE_NEWUTS |
21743 +#endif
21744 +#ifdef CONFIG_IPC_NS
21745 +               CLONE_NEWIPC |
21746 +#endif
21747 +#ifdef CONFIG_USER_NS
21748 +               CLONE_NEWUSER |
21749 +#endif
21750 +#ifdef CONFIG_PID_NS
21751 +               CLONE_NEWPID |
21752 +#endif
21753 +#ifdef CONFIG_NET_NS
21754 +               CLONE_NEWNET |
21755 +#endif
21756 +               0
21757 +};
21758 +
21759 +static const struct vcmd_space_mask_v1 default_space_mask = {
21760 +       .mask = CLONE_FS |
21761 +               CLONE_NEWNS |
21762 +#ifdef CONFIG_UTS_NS
21763 +               CLONE_NEWUTS |
21764 +#endif
21765 +#ifdef CONFIG_IPC_NS
21766 +               CLONE_NEWIPC |
21767 +#endif
21768 +#ifdef CONFIG_USER_NS
21769 +//             CLONE_NEWUSER |
21770 +#endif
21771 +#ifdef CONFIG_PID_NS
21772 +//             CLONE_NEWPID |
21773 +#endif
21774 +               0
21775 +};
21776 +
21777 +/*
21778 + *     build a new nsproxy mix
21779 + *      assumes that both proxies are 'const'
21780 + *     does not touch nsproxy refcounts
21781 + *     will hold a reference on the result.
21782 + */
21783 +
21784 +struct nsproxy *vs_mix_nsproxy(struct nsproxy *old_nsproxy,
21785 +       struct nsproxy *new_nsproxy, unsigned long mask)
21786 +{
21787 +       struct mnt_namespace *old_ns;
21788 +       struct uts_namespace *old_uts;
21789 +       struct ipc_namespace *old_ipc;
21790 +#ifdef CONFIG_PID_NS
21791 +       struct pid_namespace *old_pid;
21792 +#endif
21793 +#ifdef CONFIG_NET_NS
21794 +       struct net *old_net;
21795 +#endif
21796 +       struct nsproxy *nsproxy;
21797 +
21798 +       nsproxy = copy_nsproxy(old_nsproxy);
21799 +       if (!nsproxy)
21800 +               goto out;
21801 +
21802 +       if (mask & CLONE_NEWNS) {
21803 +               old_ns = nsproxy->mnt_ns;
21804 +               nsproxy->mnt_ns = new_nsproxy->mnt_ns;
21805 +               if (nsproxy->mnt_ns)
21806 +                       get_mnt_ns(nsproxy->mnt_ns);
21807 +       } else
21808 +               old_ns = NULL;
21809 +
21810 +       if (mask & CLONE_NEWUTS) {
21811 +               old_uts = nsproxy->uts_ns;
21812 +               nsproxy->uts_ns = new_nsproxy->uts_ns;
21813 +               if (nsproxy->uts_ns)
21814 +                       get_uts_ns(nsproxy->uts_ns);
21815 +       } else
21816 +               old_uts = NULL;
21817 +
21818 +       if (mask & CLONE_NEWIPC) {
21819 +               old_ipc = nsproxy->ipc_ns;
21820 +               nsproxy->ipc_ns = new_nsproxy->ipc_ns;
21821 +               if (nsproxy->ipc_ns)
21822 +                       get_ipc_ns(nsproxy->ipc_ns);
21823 +       } else
21824 +               old_ipc = NULL;
21825 +
21826 +#ifdef CONFIG_PID_NS
21827 +       if (mask & CLONE_NEWPID) {
21828 +               old_pid = nsproxy->pid_ns_for_children;
21829 +               nsproxy->pid_ns_for_children = new_nsproxy->pid_ns_for_children;
21830 +               if (nsproxy->pid_ns_for_children)
21831 +                       get_pid_ns(nsproxy->pid_ns_for_children);
21832 +       } else
21833 +               old_pid = NULL;
21834 +#endif
21835 +#ifdef CONFIG_NET_NS
21836 +       if (mask & CLONE_NEWNET) {
21837 +               old_net = nsproxy->net_ns;
21838 +               nsproxy->net_ns = new_nsproxy->net_ns;
21839 +               if (nsproxy->net_ns)
21840 +                       get_net(nsproxy->net_ns);
21841 +       } else
21842 +               old_net = NULL;
21843 +#endif
21844 +       if (old_ns)
21845 +               put_mnt_ns(old_ns);
21846 +       if (old_uts)
21847 +               put_uts_ns(old_uts);
21848 +       if (old_ipc)
21849 +               put_ipc_ns(old_ipc);
21850 +#ifdef CONFIG_PID_NS
21851 +       if (old_pid)
21852 +               put_pid_ns(old_pid);
21853 +#endif
21854 +#ifdef CONFIG_NET_NS
21855 +       if (old_net)
21856 +               put_net(old_net);
21857 +#endif
21858 +out:
21859 +       return nsproxy;
21860 +}
21861 +
21862 +
21863 +/*
21864 + *     merge two nsproxy structs into a new one.
21865 + *     will hold a reference on the result.
21866 + */
21867 +
21868 +static inline
21869 +struct nsproxy *__vs_merge_nsproxy(struct nsproxy *old,
21870 +       struct nsproxy *proxy, unsigned long mask)
21871 +{
21872 +       struct nsproxy null_proxy = { .mnt_ns = NULL };
21873 +
21874 +       if (!proxy)
21875 +               return NULL;
21876 +
21877 +       if (mask) {
21878 +               /* vs_mix_nsproxy returns with reference */
21879 +               return vs_mix_nsproxy(old ? old : &null_proxy,
21880 +                       proxy, mask);
21881 +       }
21882 +       get_nsproxy(proxy);
21883 +       return proxy;
21884 +}
21885 +
21886 +
21887 +int vx_enter_space(struct vx_info *vxi, unsigned long mask, unsigned index)
21888 +{
21889 +       struct nsproxy *proxy, *proxy_cur, *proxy_new;
21890 +       struct fs_struct *fs_cur, *fs = NULL;
21891 +       struct _vx_space *space;
21892 +       int ret, kill = 0;
21893 +
21894 +       vxdprintk(VXD_CBIT(space, 8), "vx_enter_space(%p[#%u],0x%08lx,%d)",
21895 +               vxi, vxi->vx_id, mask, index);
21896 +
21897 +       if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
21898 +               return -EACCES;
21899 +
21900 +       if (index >= VX_SPACES)
21901 +               return -EINVAL;
21902 +
21903 +       space = &vxi->space[index];
21904 +
21905 +       if (!mask)
21906 +               mask = space->vx_nsmask;
21907 +
21908 +       if ((mask & space->vx_nsmask) != mask)
21909 +               return -EINVAL;
21910 +
21911 +       if (mask & CLONE_FS) {
21912 +               fs = copy_fs_struct(space->vx_fs);
21913 +               if (!fs)
21914 +                       return -ENOMEM;
21915 +       }
21916 +       proxy = space->vx_nsproxy;
21917 +
21918 +       vxdprintk(VXD_CBIT(space, 9),
21919 +               "vx_enter_space(%p[#%u],0x%08lx,%d) -> (%p,%p)",
21920 +               vxi, vxi->vx_id, mask, index, proxy, fs);
21921 +
21922 +       task_lock(current);
21923 +       fs_cur = current->fs;
21924 +
21925 +       if (mask & CLONE_FS) {
21926 +               spin_lock(&fs_cur->lock);
21927 +               current->fs = fs;
21928 +               kill = !--fs_cur->users;
21929 +               spin_unlock(&fs_cur->lock);
21930 +       }
21931 +
21932 +       proxy_cur = current->nsproxy;
21933 +       get_nsproxy(proxy_cur);
21934 +       task_unlock(current);
21935 +
21936 +       if (kill)
21937 +               free_fs_struct(fs_cur);
21938 +
21939 +       proxy_new = __vs_merge_nsproxy(proxy_cur, proxy, mask);
21940 +       if (IS_ERR(proxy_new)) {
21941 +               ret = PTR_ERR(proxy_new);
21942 +               goto out_put;
21943 +       }
21944 +
21945 +       proxy_new = xchg(&current->nsproxy, proxy_new);
21946 +
21947 +       if (mask & CLONE_NEWUSER) {
21948 +               struct cred *cred;
21949 +
21950 +               vxdprintk(VXD_CBIT(space, 10),
21951 +                       "vx_enter_space(%p[#%u],%p) cred (%p,%p)",
21952 +                       vxi, vxi->vx_id, space->vx_cred,
21953 +                       current->real_cred, current->cred);
21954 +
21955 +               if (space->vx_cred) {
21956 +                       cred = __prepare_creds(space->vx_cred);
21957 +                       if (cred)
21958 +                               commit_creds(cred);
21959 +               }
21960 +       }
21961 +
21962 +       ret = 0;
21963 +
21964 +       if (proxy_new)
21965 +               put_nsproxy(proxy_new);
21966 +out_put:
21967 +       if (proxy_cur)
21968 +               put_nsproxy(proxy_cur);
21969 +       return ret;
21970 +}
21971 +
21972 +
21973 +int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index)
21974 +{
21975 +       struct nsproxy *proxy_vxi, *proxy_cur, *proxy_new;
21976 +       struct fs_struct *fs_vxi, *fs = NULL;
21977 +       struct _vx_space *space;
21978 +       int ret, kill = 0;
21979 +
21980 +       vxdprintk(VXD_CBIT(space, 8), "vx_set_space(%p[#%u],0x%08lx,%d)",
21981 +               vxi, vxi->vx_id, mask, index);
21982 +
21983 +       if ((mask & space_mask.mask) != mask)
21984 +               return -EINVAL;
21985 +
21986 +       if (index >= VX_SPACES)
21987 +               return -EINVAL;
21988 +
21989 +       space = &vxi->space[index];
21990 +
21991 +       proxy_vxi = space->vx_nsproxy;
21992 +       fs_vxi = space->vx_fs;
21993 +
21994 +       if (mask & CLONE_FS) {
21995 +               fs = copy_fs_struct(current->fs);
21996 +               if (!fs)
21997 +                       return -ENOMEM;
21998 +       }
21999 +
22000 +       task_lock(current);
22001 +
22002 +       if (mask & CLONE_FS) {
22003 +               spin_lock(&fs_vxi->lock);
22004 +               space->vx_fs = fs;
22005 +               kill = !--fs_vxi->users;
22006 +               spin_unlock(&fs_vxi->lock);
22007 +       }
22008 +
22009 +       proxy_cur = current->nsproxy;
22010 +       get_nsproxy(proxy_cur);
22011 +       task_unlock(current);
22012 +
22013 +       if (kill)
22014 +               free_fs_struct(fs_vxi);
22015 +
22016 +       proxy_new = __vs_merge_nsproxy(proxy_vxi, proxy_cur, mask);
22017 +       if (IS_ERR(proxy_new)) {
22018 +               ret = PTR_ERR(proxy_new);
22019 +               goto out_put;
22020 +       }
22021 +
22022 +       proxy_new = xchg(&space->vx_nsproxy, proxy_new);
22023 +       space->vx_nsmask |= mask;
22024 +
22025 +       if (mask & CLONE_NEWUSER) {
22026 +               struct cred *cred;
22027 +
22028 +               vxdprintk(VXD_CBIT(space, 10),
22029 +                       "vx_set_space(%p[#%u],%p) cred (%p,%p)",
22030 +                       vxi, vxi->vx_id, space->vx_cred,
22031 +                       current->real_cred, current->cred);
22032 +
22033 +               cred = prepare_creds();
22034 +               cred = (struct cred *)xchg(&space->vx_cred, cred);
22035 +               if (cred)
22036 +                       abort_creds(cred);
22037 +       }
22038 +
22039 +       ret = 0;
22040 +
22041 +       if (proxy_new)
22042 +               put_nsproxy(proxy_new);
22043 +out_put:
22044 +       if (proxy_cur)
22045 +               put_nsproxy(proxy_cur);
22046 +       return ret;
22047 +}
22048 +
22049 +
22050 +int vc_enter_space_v1(struct vx_info *vxi, void __user *data)
22051 +{
22052 +       struct vcmd_space_mask_v1 vc_data = { .mask = 0 };
22053 +
22054 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
22055 +               return -EFAULT;
22056 +
22057 +       return vx_enter_space(vxi, vc_data.mask, 0);
22058 +}
22059 +
22060 +int vc_enter_space(struct vx_info *vxi, void __user *data)
22061 +{
22062 +       struct vcmd_space_mask_v2 vc_data = { .mask = 0 };
22063 +
22064 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
22065 +               return -EFAULT;
22066 +
22067 +       if (vc_data.index >= VX_SPACES)
22068 +               return -EINVAL;
22069 +
22070 +       return vx_enter_space(vxi, vc_data.mask, vc_data.index);
22071 +}
22072 +
22073 +int vc_set_space_v1(struct vx_info *vxi, void __user *data)
22074 +{
22075 +       struct vcmd_space_mask_v1 vc_data = { .mask = 0 };
22076 +
22077 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
22078 +               return -EFAULT;
22079 +
22080 +       return vx_set_space(vxi, vc_data.mask, 0);
22081 +}
22082 +
22083 +int vc_set_space(struct vx_info *vxi, void __user *data)
22084 +{
22085 +       struct vcmd_space_mask_v2 vc_data = { .mask = 0 };
22086 +
22087 +       if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
22088 +               return -EFAULT;
22089 +
22090 +       if (vc_data.index >= VX_SPACES)
22091 +               return -EINVAL;
22092 +
22093 +       return vx_set_space(vxi, vc_data.mask, vc_data.index);
22094 +}
22095 +
22096 +int vc_get_space_mask(void __user *data, int type)
22097 +{
22098 +       const struct vcmd_space_mask_v1 *mask;
22099 +
22100 +       if (type == 0)
22101 +               mask = &space_mask_v0;
22102 +       else if (type == 1)
22103 +               mask = &space_mask;
22104 +       else
22105 +               mask = &default_space_mask;
22106 +
22107 +       vxdprintk(VXD_CBIT(space, 10),
22108 +               "vc_get_space_mask(%d) = %08llx", type, mask->mask);
22109 +
22110 +       if (copy_to_user(data, mask, sizeof(*mask)))
22111 +               return -EFAULT;
22112 +       return 0;
22113 +}
22114 +
22115 diff -NurpP --minimal linux-4.1.41/kernel/vserver/switch.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/switch.c
22116 --- linux-4.1.41/kernel/vserver/switch.c        1970-01-01 00:00:00.000000000 +0000
22117 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/switch.c    2016-07-05 04:41:47.000000000 +0000
22118 @@ -0,0 +1,556 @@
22119 +/*
22120 + *  linux/kernel/vserver/switch.c
22121 + *
22122 + *  Virtual Server: Syscall Switch
22123 + *
22124 + *  Copyright (C) 2003-2011  Herbert Pötzl
22125 + *
22126 + *  V0.01  syscall switch
22127 + *  V0.02  added signal to context
22128 + *  V0.03  added rlimit functions
22129 + *  V0.04  added iattr, task/xid functions
22130 + *  V0.05  added debug/history stuff
22131 + *  V0.06  added compat32 layer
22132 + *  V0.07  vcmd args and perms
22133 + *  V0.08  added status commands
22134 + *  V0.09  added tag commands
22135 + *  V0.10  added oom bias
22136 + *  V0.11  added device commands
22137 + *  V0.12  added warn mask
22138 + *
22139 + */
22140 +
22141 +#include <linux/vs_context.h>
22142 +#include <linux/vs_network.h>
22143 +#include <linux/vserver/switch.h>
22144 +
22145 +#include "vci_config.h"
22146 +
22147 +
22148 +static inline
22149 +int vc_get_version(uint32_t id)
22150 +{
22151 +       return VCI_VERSION;
22152 +}
22153 +
22154 +static inline
22155 +int vc_get_vci(uint32_t id)
22156 +{
22157 +       return vci_kernel_config();
22158 +}
22159 +
22160 +#include <linux/vserver/context_cmd.h>
22161 +#include <linux/vserver/cvirt_cmd.h>
22162 +#include <linux/vserver/cacct_cmd.h>
22163 +#include <linux/vserver/limit_cmd.h>
22164 +#include <linux/vserver/network_cmd.h>
22165 +#include <linux/vserver/sched_cmd.h>
22166 +#include <linux/vserver/debug_cmd.h>
22167 +#include <linux/vserver/inode_cmd.h>
22168 +#include <linux/vserver/dlimit_cmd.h>
22169 +#include <linux/vserver/signal_cmd.h>
22170 +#include <linux/vserver/space_cmd.h>
22171 +#include <linux/vserver/tag_cmd.h>
22172 +#include <linux/vserver/device_cmd.h>
22173 +
22174 +#include <linux/vserver/inode.h>
22175 +#include <linux/vserver/dlimit.h>
22176 +
22177 +
22178 +#ifdef CONFIG_COMPAT
22179 +#define __COMPAT(name, id, data, compat)       \
22180 +       (compat) ? name ## _x32(id, data) : name(id, data)
22181 +#define __COMPAT_NO_ID(name, data, compat)     \
22182 +       (compat) ? name ## _x32(data) : name(data)
22183 +#else
22184 +#define __COMPAT(name, id, data, compat)       \
22185 +       name(id, data)
22186 +#define __COMPAT_NO_ID(name, data, compat)     \
22187 +       name(data)
22188 +#endif
22189 +
22190 +
22191 +static inline
22192 +long do_vcmd(uint32_t cmd, uint32_t id,
22193 +       struct vx_info *vxi, struct nx_info *nxi,
22194 +       void __user *data, int compat)
22195 +{
22196 +       switch (cmd) {
22197 +
22198 +       case VCMD_get_version:
22199 +               return vc_get_version(id);
22200 +       case VCMD_get_vci:
22201 +               return vc_get_vci(id);
22202 +
22203 +       case VCMD_task_xid:
22204 +               return vc_task_xid(id);
22205 +       case VCMD_vx_info:
22206 +               return vc_vx_info(vxi, data);
22207 +
22208 +       case VCMD_task_nid:
22209 +               return vc_task_nid(id);
22210 +       case VCMD_nx_info:
22211 +               return vc_nx_info(nxi, data);
22212 +
22213 +       case VCMD_task_tag:
22214 +               return vc_task_tag(id);
22215 +
22216 +       case VCMD_set_space_v1:
22217 +               return vc_set_space_v1(vxi, data);
22218 +       /* this is version 2 */
22219 +       case VCMD_set_space:
22220 +               return vc_set_space(vxi, data);
22221 +
22222 +       case VCMD_get_space_mask_v0:
22223 +               return vc_get_space_mask(data, 0);
22224 +       /* this is version 1 */
22225 +       case VCMD_get_space_mask:
22226 +               return vc_get_space_mask(data, 1);
22227 +
22228 +       case VCMD_get_space_default:
22229 +               return vc_get_space_mask(data, -1);
22230 +
22231 +       case VCMD_set_umask:
22232 +               return vc_set_umask(vxi, data);
22233 +
22234 +       case VCMD_get_umask:
22235 +               return vc_get_umask(vxi, data);
22236 +
22237 +       case VCMD_set_wmask:
22238 +               return vc_set_wmask(vxi, data);
22239 +
22240 +       case VCMD_get_wmask:
22241 +               return vc_get_wmask(vxi, data);
22242 +#ifdef CONFIG_IA32_EMULATION
22243 +       case VCMD_get_rlimit:
22244 +               return __COMPAT(vc_get_rlimit, vxi, data, compat);
22245 +       case VCMD_set_rlimit:
22246 +               return __COMPAT(vc_set_rlimit, vxi, data, compat);
22247 +#else
22248 +       case VCMD_get_rlimit:
22249 +               return vc_get_rlimit(vxi, data);
22250 +       case VCMD_set_rlimit:
22251 +               return vc_set_rlimit(vxi, data);
22252 +#endif
22253 +       case VCMD_get_rlimit_mask:
22254 +               return vc_get_rlimit_mask(id, data);
22255 +       case VCMD_reset_hits:
22256 +               return vc_reset_hits(vxi, data);
22257 +       case VCMD_reset_minmax:
22258 +               return vc_reset_minmax(vxi, data);
22259 +
22260 +       case VCMD_get_vhi_name:
22261 +               return vc_get_vhi_name(vxi, data);
22262 +       case VCMD_set_vhi_name:
22263 +               return vc_set_vhi_name(vxi, data);
22264 +
22265 +       case VCMD_ctx_stat:
22266 +               return vc_ctx_stat(vxi, data);
22267 +       case VCMD_virt_stat:
22268 +               return vc_virt_stat(vxi, data);
22269 +       case VCMD_sock_stat:
22270 +               return vc_sock_stat(vxi, data);
22271 +       case VCMD_rlimit_stat:
22272 +               return vc_rlimit_stat(vxi, data);
22273 +
22274 +       case VCMD_set_cflags:
22275 +               return vc_set_cflags(vxi, data);
22276 +       case VCMD_get_cflags:
22277 +               return vc_get_cflags(vxi, data);
22278 +
22279 +       /* this is version 1 */
22280 +       case VCMD_set_ccaps:
22281 +               return vc_set_ccaps(vxi, data);
22282 +       /* this is version 1 */
22283 +       case VCMD_get_ccaps:
22284 +               return vc_get_ccaps(vxi, data);
22285 +       case VCMD_set_bcaps:
22286 +               return vc_set_bcaps(vxi, data);
22287 +       case VCMD_get_bcaps:
22288 +               return vc_get_bcaps(vxi, data);
22289 +
22290 +       case VCMD_set_badness:
22291 +               return vc_set_badness(vxi, data);
22292 +       case VCMD_get_badness:
22293 +               return vc_get_badness(vxi, data);
22294 +
22295 +       case VCMD_set_nflags:
22296 +               return vc_set_nflags(nxi, data);
22297 +       case VCMD_get_nflags:
22298 +               return vc_get_nflags(nxi, data);
22299 +
22300 +       case VCMD_set_ncaps:
22301 +               return vc_set_ncaps(nxi, data);
22302 +       case VCMD_get_ncaps:
22303 +               return vc_get_ncaps(nxi, data);
22304 +
22305 +       case VCMD_set_prio_bias:
22306 +               return vc_set_prio_bias(vxi, data);
22307 +       case VCMD_get_prio_bias:
22308 +               return vc_get_prio_bias(vxi, data);
22309 +       case VCMD_add_dlimit:
22310 +               return __COMPAT(vc_add_dlimit, id, data, compat);
22311 +       case VCMD_rem_dlimit:
22312 +               return __COMPAT(vc_rem_dlimit, id, data, compat);
22313 +       case VCMD_set_dlimit:
22314 +               return __COMPAT(vc_set_dlimit, id, data, compat);
22315 +       case VCMD_get_dlimit:
22316 +               return __COMPAT(vc_get_dlimit, id, data, compat);
22317 +
22318 +       case VCMD_ctx_kill:
22319 +               return vc_ctx_kill(vxi, data);
22320 +
22321 +       case VCMD_wait_exit:
22322 +               return vc_wait_exit(vxi, data);
22323 +
22324 +       case VCMD_get_iattr:
22325 +               return __COMPAT_NO_ID(vc_get_iattr, data, compat);
22326 +       case VCMD_set_iattr:
22327 +               return __COMPAT_NO_ID(vc_set_iattr, data, compat);
22328 +
22329 +       case VCMD_fget_iattr:
22330 +               return vc_fget_iattr(id, data);
22331 +       case VCMD_fset_iattr:
22332 +               return vc_fset_iattr(id, data);
22333 +
22334 +       case VCMD_enter_space_v0:
22335 +               return vc_enter_space_v1(vxi, NULL);
22336 +       case VCMD_enter_space_v1:
22337 +               return vc_enter_space_v1(vxi, data);
22338 +       /* this is version 2 */
22339 +       case VCMD_enter_space:
22340 +               return vc_enter_space(vxi, data);
22341 +
22342 +       case VCMD_ctx_create_v0:
22343 +               return vc_ctx_create(id, NULL);
22344 +       case VCMD_ctx_create:
22345 +               return vc_ctx_create(id, data);
22346 +       case VCMD_ctx_migrate_v0:
22347 +               return vc_ctx_migrate(vxi, NULL);
22348 +       case VCMD_ctx_migrate:
22349 +               return vc_ctx_migrate(vxi, data);
22350 +
22351 +       case VCMD_net_create_v0:
22352 +               return vc_net_create(id, NULL);
22353 +       case VCMD_net_create:
22354 +               return vc_net_create(id, data);
22355 +       case VCMD_net_migrate:
22356 +               return vc_net_migrate(nxi, data);
22357 +
22358 +       case VCMD_tag_migrate:
22359 +               return vc_tag_migrate(id);
22360 +
22361 +       case VCMD_net_add:
22362 +               return vc_net_add(nxi, data);
22363 +       case VCMD_net_remove:
22364 +               return vc_net_remove(nxi, data);
22365 +
22366 +       case VCMD_net_add_ipv4_v1:
22367 +               return vc_net_add_ipv4_v1(nxi, data);
22368 +       /* this is version 2 */
22369 +       case VCMD_net_add_ipv4:
22370 +               return vc_net_add_ipv4(nxi, data);
22371 +
22372 +       case VCMD_net_rem_ipv4_v1:
22373 +               return vc_net_rem_ipv4_v1(nxi, data);
22374 +       /* this is version 2 */
22375 +       case VCMD_net_rem_ipv4:
22376 +               return vc_net_rem_ipv4(nxi, data);
22377 +#ifdef CONFIG_IPV6
22378 +       case VCMD_net_add_ipv6:
22379 +               return vc_net_add_ipv6(nxi, data);
22380 +       case VCMD_net_remove_ipv6:
22381 +               return vc_net_remove_ipv6(nxi, data);
22382 +#endif
22383 +/*     case VCMD_add_match_ipv4:
22384 +               return vc_add_match_ipv4(nxi, data);
22385 +       case VCMD_get_match_ipv4:
22386 +               return vc_get_match_ipv4(nxi, data);
22387 +#ifdef CONFIG_IPV6
22388 +       case VCMD_add_match_ipv6:
22389 +               return vc_add_match_ipv6(nxi, data);
22390 +       case VCMD_get_match_ipv6:
22391 +               return vc_get_match_ipv6(nxi, data);
22392 +#endif */
22393 +
22394 +#ifdef CONFIG_VSERVER_DEVICE
22395 +       case VCMD_set_mapping:
22396 +               return __COMPAT(vc_set_mapping, vxi, data, compat);
22397 +       case VCMD_unset_mapping:
22398 +               return __COMPAT(vc_unset_mapping, vxi, data, compat);
22399 +#endif
22400 +#ifdef CONFIG_VSERVER_HISTORY
22401 +       case VCMD_dump_history:
22402 +               return vc_dump_history(id);
22403 +       case VCMD_read_history:
22404 +               return __COMPAT(vc_read_history, id, data, compat);
22405 +#endif
22406 +       default:
22407 +               vxwprintk_task(1, "unimplemented VCMD_%02d_%d[%d]",
22408 +                       VC_CATEGORY(cmd), VC_COMMAND(cmd), VC_VERSION(cmd));
22409 +       }
22410 +       return -ENOSYS;
22411 +}
22412 +
22413 +
22414 +#define        __VCMD(vcmd, _perm, _args, _flags)              \
22415 +       case VCMD_ ## vcmd: perm = _perm;               \
22416 +               args = _args; flags = _flags; break
22417 +
22418 +
22419 +#define VCA_NONE       0x00
22420 +#define VCA_VXI                0x01
22421 +#define VCA_NXI                0x02
22422 +
22423 +#define VCF_NONE       0x00
22424 +#define VCF_INFO       0x01
22425 +#define VCF_ADMIN      0x02
22426 +#define VCF_ARES       0x06    /* includes admin */
22427 +#define VCF_SETUP      0x08
22428 +
22429 +#define VCF_ZIDOK      0x10    /* zero id okay */
22430 +
22431 +
22432 +static inline
22433 +long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
22434 +{
22435 +       long ret;
22436 +       int permit = -1, state = 0;
22437 +       int perm = -1, args = 0, flags = 0;
22438 +       struct vx_info *vxi = NULL;
22439 +       struct nx_info *nxi = NULL;
22440 +
22441 +       switch (cmd) {
22442 +       /* unpriviledged commands */
22443 +       __VCMD(get_version,      0, VCA_NONE,   0);
22444 +       __VCMD(get_vci,          0, VCA_NONE,   0);
22445 +       __VCMD(get_rlimit_mask,  0, VCA_NONE,   0);
22446 +       __VCMD(get_space_mask_v0,0, VCA_NONE,   0);
22447 +       __VCMD(get_space_mask,   0, VCA_NONE,   0);
22448 +       __VCMD(get_space_default,0, VCA_NONE,   0);
22449 +
22450 +       /* info commands */
22451 +       __VCMD(task_xid,         2, VCA_NONE,   0);
22452 +       __VCMD(reset_hits,       2, VCA_VXI,    0);
22453 +       __VCMD(reset_minmax,     2, VCA_VXI,    0);
22454 +       __VCMD(vx_info,          3, VCA_VXI,    VCF_INFO);
22455 +       __VCMD(get_bcaps,        3, VCA_VXI,    VCF_INFO);
22456 +       __VCMD(get_ccaps,        3, VCA_VXI,    VCF_INFO);
22457 +       __VCMD(get_cflags,       3, VCA_VXI,    VCF_INFO);
22458 +       __VCMD(get_umask,        3, VCA_VXI,    VCF_INFO);
22459 +       __VCMD(get_wmask,        3, VCA_VXI,    VCF_INFO);
22460 +       __VCMD(get_badness,      3, VCA_VXI,    VCF_INFO);
22461 +       __VCMD(get_vhi_name,     3, VCA_VXI,    VCF_INFO);
22462 +       __VCMD(get_rlimit,       3, VCA_VXI,    VCF_INFO);
22463 +
22464 +       __VCMD(ctx_stat,         3, VCA_VXI,    VCF_INFO);
22465 +       __VCMD(virt_stat,        3, VCA_VXI,    VCF_INFO);
22466 +       __VCMD(sock_stat,        3, VCA_VXI,    VCF_INFO);
22467 +       __VCMD(rlimit_stat,      3, VCA_VXI,    VCF_INFO);
22468 +
22469 +       __VCMD(task_nid,         2, VCA_NONE,   0);
22470 +       __VCMD(nx_info,          3, VCA_NXI,    VCF_INFO);
22471 +       __VCMD(get_ncaps,        3, VCA_NXI,    VCF_INFO);
22472 +       __VCMD(get_nflags,       3, VCA_NXI,    VCF_INFO);
22473 +
22474 +       __VCMD(task_tag,         2, VCA_NONE,   0);
22475 +
22476 +       __VCMD(get_iattr,        2, VCA_NONE,   0);
22477 +       __VCMD(fget_iattr,       2, VCA_NONE,   0);
22478 +       __VCMD(get_dlimit,       3, VCA_NONE,   VCF_INFO);
22479 +       __VCMD(get_prio_bias,    3, VCA_VXI,    VCF_INFO);
22480 +
22481 +       /* lower admin commands */
22482 +       __VCMD(wait_exit,        4, VCA_VXI,    VCF_INFO);
22483 +       __VCMD(ctx_create_v0,    5, VCA_NONE,   0);
22484 +       __VCMD(ctx_create,       5, VCA_NONE,   0);
22485 +       __VCMD(ctx_migrate_v0,   5, VCA_VXI,    VCF_ADMIN);
22486 +       __VCMD(ctx_migrate,      5, VCA_VXI,    VCF_ADMIN);
22487 +       __VCMD(enter_space_v0,   5, VCA_VXI,    VCF_ADMIN);
22488 +       __VCMD(enter_space_v1,   5, VCA_VXI,    VCF_ADMIN);
22489 +       __VCMD(enter_space,      5, VCA_VXI,    VCF_ADMIN);
22490 +
22491 +       __VCMD(net_create_v0,    5, VCA_NONE,   0);
22492 +       __VCMD(net_create,       5, VCA_NONE,   0);
22493 +       __VCMD(net_migrate,      5, VCA_NXI,    VCF_ADMIN);
22494 +
22495 +       __VCMD(tag_migrate,      5, VCA_NONE,   VCF_ADMIN);
22496 +
22497 +       /* higher admin commands */
22498 +       __VCMD(ctx_kill,         6, VCA_VXI,    VCF_ARES);
22499 +       __VCMD(set_space_v1,     7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22500 +       __VCMD(set_space,        7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22501 +
22502 +       __VCMD(set_ccaps,        7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22503 +       __VCMD(set_bcaps,        7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22504 +       __VCMD(set_cflags,       7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22505 +       __VCMD(set_umask,        7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22506 +       __VCMD(set_wmask,        7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22507 +       __VCMD(set_badness,      7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22508 +
22509 +       __VCMD(set_vhi_name,     7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22510 +       __VCMD(set_rlimit,       7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22511 +       __VCMD(set_prio_bias,    7, VCA_VXI,    VCF_ARES | VCF_SETUP);
22512 +
22513 +       __VCMD(set_ncaps,        7, VCA_NXI,    VCF_ARES | VCF_SETUP);
22514 +       __VCMD(set_nflags,       7, VCA_NXI,    VCF_ARES | VCF_SETUP);
22515 +       __VCMD(net_add,          8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22516 +       __VCMD(net_remove,       8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22517 +       __VCMD(net_add_ipv4_v1,  8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22518 +       __VCMD(net_rem_ipv4_v1,  8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22519 +       __VCMD(net_add_ipv4,     8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22520 +       __VCMD(net_rem_ipv4,     8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22521 +#ifdef CONFIG_IPV6
22522 +       __VCMD(net_add_ipv6,     8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22523 +       __VCMD(net_remove_ipv6,  8, VCA_NXI,    VCF_ARES | VCF_SETUP);
22524 +#endif
22525 +       __VCMD(set_iattr,        7, VCA_NONE,   0);
22526 +       __VCMD(fset_iattr,       7, VCA_NONE,   0);
22527 +       __VCMD(set_dlimit,       7, VCA_NONE,   VCF_ARES);
22528 +       __VCMD(add_dlimit,       8, VCA_NONE,   VCF_ARES);
22529 +       __VCMD(rem_dlimit,       8, VCA_NONE,   VCF_ARES);
22530 +
22531 +#ifdef CONFIG_VSERVER_DEVICE
22532 +       __VCMD(set_mapping,      8, VCA_VXI,    VCF_ARES|VCF_ZIDOK);
22533 +       __VCMD(unset_mapping,    8, VCA_VXI,    VCF_ARES|VCF_ZIDOK);
22534 +#endif
22535 +       /* debug level admin commands */
22536 +#ifdef CONFIG_VSERVER_HISTORY
22537 +       __VCMD(dump_history,     9, VCA_NONE,   0);
22538 +       __VCMD(read_history,     9, VCA_NONE,   0);
22539 +#endif
22540 +
22541 +       default:
22542 +               perm = -1;
22543 +       }
22544 +
22545 +       vxdprintk(VXD_CBIT(switch, 0),
22546 +               "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]",
22547 +               VC_CATEGORY(cmd), VC_COMMAND(cmd),
22548 +               VC_VERSION(cmd), id, data, compat,
22549 +               perm, args, flags);
22550 +
22551 +       ret = -ENOSYS;
22552 +       if (perm < 0)
22553 +               goto out;
22554 +
22555 +       state = 1;
22556 +       if (!capable(CAP_CONTEXT))
22557 +               goto out;
22558 +
22559 +       state = 2;
22560 +       /* moved here from the individual commands */
22561 +       ret = -EPERM;
22562 +       if ((perm > 1) && !capable(CAP_SYS_ADMIN))
22563 +               goto out;
22564 +
22565 +       state = 3;
22566 +       /* vcmd involves resource management  */
22567 +       ret = -EPERM;
22568 +       if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE))
22569 +               goto out;
22570 +
22571 +       state = 4;
22572 +       /* various legacy exceptions */
22573 +       switch (cmd) {
22574 +       /* will go away when spectator is a cap */
22575 +       case VCMD_ctx_migrate_v0:
22576 +       case VCMD_ctx_migrate:
22577 +               if (id == 1) {
22578 +                       current->xid = 1;
22579 +                       ret = 1;
22580 +                       goto out;
22581 +               }
22582 +               break;
22583 +
22584 +       /* will go away when spectator is a cap */
22585 +       case VCMD_net_migrate:
22586 +               if (id == 1) {
22587 +                       current->nid = 1;
22588 +                       ret = 1;
22589 +                       goto out;
22590 +               }
22591 +               break;
22592 +       }
22593 +
22594 +       /* vcmds are fine by default */
22595 +       permit = 1;
22596 +
22597 +       /* admin type vcmds require admin ... */
22598 +       if (flags & VCF_ADMIN)
22599 +               permit = vx_check(0, VS_ADMIN) ? 1 : 0;
22600 +
22601 +       /* ... but setup type vcmds override that */
22602 +       if (!permit && (flags & VCF_SETUP))
22603 +               permit = vx_flags(VXF_STATE_SETUP, 0) ? 2 : 0;
22604 +
22605 +       state = 5;
22606 +       ret = -EPERM;
22607 +       if (!permit)
22608 +               goto out;
22609 +
22610 +       state = 6;
22611 +       if (!id && (flags & VCF_ZIDOK))
22612 +               goto skip_id;
22613 +
22614 +       ret = -ESRCH;
22615 +       if (args & VCA_VXI) {
22616 +               vxi = lookup_vx_info(id);
22617 +               if (!vxi)
22618 +                       goto out;
22619 +
22620 +               if ((flags & VCF_ADMIN) &&
22621 +                       /* special case kill for shutdown */
22622 +                       (cmd != VCMD_ctx_kill) &&
22623 +                       /* can context be administrated? */
22624 +                       !vx_info_flags(vxi, VXF_STATE_ADMIN, 0)) {
22625 +                       ret = -EACCES;
22626 +                       goto out_vxi;
22627 +               }
22628 +       }
22629 +       state = 7;
22630 +       if (args & VCA_NXI) {
22631 +               nxi = lookup_nx_info(id);
22632 +               if (!nxi)
22633 +                       goto out_vxi;
22634 +
22635 +               if ((flags & VCF_ADMIN) &&
22636 +                       /* can context be administrated? */
22637 +                       !nx_info_flags(nxi, NXF_STATE_ADMIN, 0)) {
22638 +                       ret = -EACCES;
22639 +                       goto out_nxi;
22640 +               }
22641 +       }
22642 +skip_id:
22643 +       state = 8;
22644 +       ret = do_vcmd(cmd, id, vxi, nxi, data, compat);
22645 +
22646 +out_nxi:
22647 +       if ((args & VCA_NXI) && nxi)
22648 +               put_nx_info(nxi);
22649 +out_vxi:
22650 +       if ((args & VCA_VXI) && vxi)
22651 +               put_vx_info(vxi);
22652 +out:
22653 +       vxdprintk(VXD_CBIT(switch, 1),
22654 +               "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]",
22655 +               VC_CATEGORY(cmd), VC_COMMAND(cmd),
22656 +               VC_VERSION(cmd), ret, ret, state, permit);
22657 +       return ret;
22658 +}
22659 +
22660 +asmlinkage long
22661 +sys_vserver(uint32_t cmd, uint32_t id, void __user *data)
22662 +{
22663 +       return do_vserver(cmd, id, data, 0);
22664 +}
22665 +
22666 +#ifdef CONFIG_COMPAT
22667 +
22668 +asmlinkage long
22669 +sys32_vserver(uint32_t cmd, uint32_t id, void __user *data)
22670 +{
22671 +       return do_vserver(cmd, id, data, 1);
22672 +}
22673 +
22674 +#endif /* CONFIG_COMPAT */
22675 diff -NurpP --minimal linux-4.1.41/kernel/vserver/sysctl.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/sysctl.c
22676 --- linux-4.1.41/kernel/vserver/sysctl.c        1970-01-01 00:00:00.000000000 +0000
22677 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/sysctl.c    2016-07-05 04:41:47.000000000 +0000
22678 @@ -0,0 +1,247 @@
22679 +/*
22680 + *  kernel/vserver/sysctl.c
22681 + *
22682 + *  Virtual Context Support
22683 + *
22684 + *  Copyright (C) 2004-2007  Herbert Pötzl
22685 + *
22686 + *  V0.01  basic structure
22687 + *
22688 + */
22689 +
22690 +#include <linux/module.h>
22691 +#include <linux/ctype.h>
22692 +#include <linux/sysctl.h>
22693 +#include <linux/parser.h>
22694 +#include <asm/uaccess.h>
22695 +
22696 +enum {
22697 +       CTL_DEBUG_ERROR         = 0,
22698 +       CTL_DEBUG_SWITCH        = 1,
22699 +       CTL_DEBUG_XID,
22700 +       CTL_DEBUG_NID,
22701 +       CTL_DEBUG_TAG,
22702 +       CTL_DEBUG_NET,
22703 +       CTL_DEBUG_LIMIT,
22704 +       CTL_DEBUG_CRES,
22705 +       CTL_DEBUG_DLIM,
22706 +       CTL_DEBUG_QUOTA,
22707 +       CTL_DEBUG_CVIRT,
22708 +       CTL_DEBUG_SPACE,
22709 +       CTL_DEBUG_PERM,
22710 +       CTL_DEBUG_MISC,
22711 +};
22712 +
22713 +
22714 +unsigned int vs_debug_switch   = 0;
22715 +unsigned int vs_debug_xid      = 0;
22716 +unsigned int vs_debug_nid      = 0;
22717 +unsigned int vs_debug_tag      = 0;
22718 +unsigned int vs_debug_net      = 0;
22719 +unsigned int vs_debug_limit    = 0;
22720 +unsigned int vs_debug_cres     = 0;
22721 +unsigned int vs_debug_dlim     = 0;
22722 +unsigned int vs_debug_quota    = 0;
22723 +unsigned int vs_debug_cvirt    = 0;
22724 +unsigned int vs_debug_space    = 0;
22725 +unsigned int vs_debug_perm     = 0;
22726 +unsigned int vs_debug_misc     = 0;
22727 +
22728 +
22729 +static struct ctl_table_header *vserver_table_header;
22730 +static struct ctl_table vserver_root_table[];
22731 +
22732 +
22733 +void vserver_register_sysctl(void)
22734 +{
22735 +       if (!vserver_table_header) {
22736 +               vserver_table_header = register_sysctl_table(vserver_root_table);
22737 +       }
22738 +
22739 +}
22740 +
22741 +void vserver_unregister_sysctl(void)
22742 +{
22743 +       if (vserver_table_header) {
22744 +               unregister_sysctl_table(vserver_table_header);
22745 +               vserver_table_header = NULL;
22746 +       }
22747 +}
22748 +
22749 +
22750 +static int proc_dodebug(struct ctl_table *table, int write,
22751 +       void __user *buffer, size_t *lenp, loff_t *ppos)
22752 +{
22753 +       char            tmpbuf[20], *p, c;
22754 +       unsigned int    value;
22755 +       size_t          left, len;
22756 +
22757 +       if ((*ppos && !write) || !*lenp) {
22758 +               *lenp = 0;
22759 +               return 0;
22760 +       }
22761 +
22762 +       left = *lenp;
22763 +
22764 +       if (write) {
22765 +               if (!access_ok(VERIFY_READ, buffer, left))
22766 +                       return -EFAULT;
22767 +               p = (char *)buffer;
22768 +               while (left && __get_user(c, p) >= 0 && isspace(c))
22769 +                       left--, p++;
22770 +               if (!left)
22771 +                       goto done;
22772 +
22773 +               if (left > sizeof(tmpbuf) - 1)
22774 +                       return -EINVAL;
22775 +               if (copy_from_user(tmpbuf, p, left))
22776 +                       return -EFAULT;
22777 +               tmpbuf[left] = '\0';
22778 +
22779 +               for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
22780 +                       value = 10 * value + (*p - '0');
22781 +               if (*p && !isspace(*p))
22782 +                       return -EINVAL;
22783 +               while (left && isspace(*p))
22784 +                       left--, p++;
22785 +               *(unsigned int *)table->data = value;
22786 +       } else {
22787 +               if (!access_ok(VERIFY_WRITE, buffer, left))
22788 +                       return -EFAULT;
22789 +               len = sprintf(tmpbuf, "%d", *(unsigned int *)table->data);
22790 +               if (len > left)
22791 +                       len = left;
22792 +               if (__copy_to_user(buffer, tmpbuf, len))
22793 +                       return -EFAULT;
22794 +               if ((left -= len) > 0) {
22795 +                       if (put_user('\n', (char *)buffer + len))
22796 +                               return -EFAULT;
22797 +                       left--;
22798 +               }
22799 +       }
22800 +
22801 +done:
22802 +       *lenp -= left;
22803 +       *ppos += *lenp;
22804 +       return 0;
22805 +}
22806 +
22807 +static int zero;
22808 +
22809 +#define        CTL_ENTRY(ctl, name)                            \
22810 +       {                                               \
22811 +               .procname       = #name,                \
22812 +               .data           = &vs_ ## name,         \
22813 +               .maxlen         = sizeof(int),          \
22814 +               .mode           = 0644,                 \
22815 +               .proc_handler   = &proc_dodebug,        \
22816 +               .extra1         = &zero,                \
22817 +               .extra2         = &zero,                \
22818 +       }
22819 +
22820 +static struct ctl_table vserver_debug_table[] = {
22821 +       CTL_ENTRY(CTL_DEBUG_SWITCH,     debug_switch),
22822 +       CTL_ENTRY(CTL_DEBUG_XID,        debug_xid),
22823 +       CTL_ENTRY(CTL_DEBUG_NID,        debug_nid),
22824 +       CTL_ENTRY(CTL_DEBUG_TAG,        debug_tag),
22825 +       CTL_ENTRY(CTL_DEBUG_NET,        debug_net),
22826 +       CTL_ENTRY(CTL_DEBUG_LIMIT,      debug_limit),
22827 +       CTL_ENTRY(CTL_DEBUG_CRES,       debug_cres),
22828 +       CTL_ENTRY(CTL_DEBUG_DLIM,       debug_dlim),
22829 +       CTL_ENTRY(CTL_DEBUG_QUOTA,      debug_quota),
22830 +       CTL_ENTRY(CTL_DEBUG_CVIRT,      debug_cvirt),
22831 +       CTL_ENTRY(CTL_DEBUG_SPACE,      debug_space),
22832 +       CTL_ENTRY(CTL_DEBUG_PERM,       debug_perm),
22833 +       CTL_ENTRY(CTL_DEBUG_MISC,       debug_misc),
22834 +       { 0 }
22835 +};
22836 +
22837 +static struct ctl_table vserver_root_table[] = {
22838 +       {
22839 +               .procname       = "vserver",
22840 +               .mode           = 0555,
22841 +               .child          = vserver_debug_table
22842 +       },
22843 +       { 0 }
22844 +};
22845 +
22846 +
22847 +static match_table_t tokens = {
22848 +       { CTL_DEBUG_SWITCH,     "switch=%x"     },
22849 +       { CTL_DEBUG_XID,        "xid=%x"        },
22850 +       { CTL_DEBUG_NID,        "nid=%x"        },
22851 +       { CTL_DEBUG_TAG,        "tag=%x"        },
22852 +       { CTL_DEBUG_NET,        "net=%x"        },
22853 +       { CTL_DEBUG_LIMIT,      "limit=%x"      },
22854 +       { CTL_DEBUG_CRES,       "cres=%x"       },
22855 +       { CTL_DEBUG_DLIM,       "dlim=%x"       },
22856 +       { CTL_DEBUG_QUOTA,      "quota=%x"      },
22857 +       { CTL_DEBUG_CVIRT,      "cvirt=%x"      },
22858 +       { CTL_DEBUG_SPACE,      "space=%x"      },
22859 +       { CTL_DEBUG_PERM,       "perm=%x"       },
22860 +       { CTL_DEBUG_MISC,       "misc=%x"       },
22861 +       { CTL_DEBUG_ERROR,      NULL            }
22862 +};
22863 +
22864 +#define        HANDLE_CASE(id, name, val)                              \
22865 +       case CTL_DEBUG_ ## id:                                  \
22866 +               vs_debug_ ## name = val;                        \
22867 +               printk("vs_debug_" #name "=0x%x\n", val);       \
22868 +               break
22869 +
22870 +
22871 +static int __init vs_debug_setup(char *str)
22872 +{
22873 +       char *p;
22874 +       int token;
22875 +
22876 +       printk("vs_debug_setup(%s)\n", str);
22877 +       while ((p = strsep(&str, ",")) != NULL) {
22878 +               substring_t args[MAX_OPT_ARGS];
22879 +               unsigned int value;
22880 +
22881 +               if (!*p)
22882 +                       continue;
22883 +
22884 +               token = match_token(p, tokens, args);
22885 +               value = (token > 0) ? simple_strtoul(args[0].from, NULL, 0) : 0;
22886 +
22887 +               switch (token) {
22888 +               HANDLE_CASE(SWITCH, switch, value);
22889 +               HANDLE_CASE(XID,    xid,    value);
22890 +               HANDLE_CASE(NID,    nid,    value);
22891 +               HANDLE_CASE(TAG,    tag,    value);
22892 +               HANDLE_CASE(NET,    net,    value);
22893 +               HANDLE_CASE(LIMIT,  limit,  value);
22894 +               HANDLE_CASE(CRES,   cres,   value);
22895 +               HANDLE_CASE(DLIM,   dlim,   value);
22896 +               HANDLE_CASE(QUOTA,  quota,  value);
22897 +               HANDLE_CASE(CVIRT,  cvirt,  value);
22898 +               HANDLE_CASE(SPACE,  space,  value);
22899 +               HANDLE_CASE(PERM,   perm,   value);
22900 +               HANDLE_CASE(MISC,   misc,   value);
22901 +               default:
22902 +                       return -EINVAL;
22903 +                       break;
22904 +               }
22905 +       }
22906 +       return 1;
22907 +}
22908 +
22909 +__setup("vsdebug=", vs_debug_setup);
22910 +
22911 +
22912 +
22913 +EXPORT_SYMBOL_GPL(vs_debug_switch);
22914 +EXPORT_SYMBOL_GPL(vs_debug_xid);
22915 +EXPORT_SYMBOL_GPL(vs_debug_nid);
22916 +EXPORT_SYMBOL_GPL(vs_debug_net);
22917 +EXPORT_SYMBOL_GPL(vs_debug_limit);
22918 +EXPORT_SYMBOL_GPL(vs_debug_cres);
22919 +EXPORT_SYMBOL_GPL(vs_debug_dlim);
22920 +EXPORT_SYMBOL_GPL(vs_debug_quota);
22921 +EXPORT_SYMBOL_GPL(vs_debug_cvirt);
22922 +EXPORT_SYMBOL_GPL(vs_debug_space);
22923 +EXPORT_SYMBOL_GPL(vs_debug_perm);
22924 +EXPORT_SYMBOL_GPL(vs_debug_misc);
22925 +
22926 diff -NurpP --minimal linux-4.1.41/kernel/vserver/tag.c linux-4.1.41-vs2.3.8.5.3/kernel/vserver/tag.c
22927 --- linux-4.1.41/kernel/vserver/tag.c   1970-01-01 00:00:00.000000000 +0000
22928 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/tag.c       2016-07-05 04:41:47.000000000 +0000
22929 @@ -0,0 +1,63 @@
22930 +/*
22931 + *  linux/kernel/vserver/tag.c
22932 + *
22933 + *  Virtual Server: Shallow Tag Space
22934 + *
22935 + *  Copyright (C) 2007  Herbert Pötzl
22936 + *
22937 + *  V0.01  basic implementation
22938 + *
22939 + */
22940 +
22941 +#include <linux/sched.h>
22942 +#include <linux/vserver/debug.h>
22943 +#include <linux/vs_pid.h>
22944 +#include <linux/vs_tag.h>
22945 +
22946 +#include <linux/vserver/tag_cmd.h>
22947 +
22948 +
22949 +int dx_migrate_task(struct task_struct *p, vtag_t tag)
22950 +{
22951 +       if (!p)
22952 +               BUG();
22953 +
22954 +       vxdprintk(VXD_CBIT(tag, 5),
22955 +               "dx_migrate_task(%p[#%d],#%d)", p, p->tag, tag);
22956 +
22957 +       task_lock(p);
22958 +       p->tag = tag;
22959 +       task_unlock(p);
22960 +
22961 +       vxdprintk(VXD_CBIT(tag, 5),
22962 +               "moved task %p into [#%d]", p, tag);
22963 +       return 0;
22964 +}
22965 +
22966 +/* vserver syscall commands below here */
22967 +
22968 +/* taks xid and vx_info functions */
22969 +
22970 +
22971 +int vc_task_tag(uint32_t id)
22972 +{
22973 +       vtag_t tag;
22974 +
22975 +       if (id) {
22976 +               struct task_struct *tsk;
22977 +               rcu_read_lock();
22978 +               tsk = find_task_by_real_pid(id);
22979 +               tag = (tsk) ? tsk->tag : -ESRCH;
22980 +               rcu_read_unlock();
22981 +       } else
22982 +               tag = dx_current_tag();
22983 +       return tag;
22984 +}
22985 +
22986 +
22987 +int vc_tag_migrate(uint32_t tag)
22988 +{
22989 +       return dx_migrate_task(current, tag & 0xFFFF);
22990 +}
22991 +
22992 +
22993 diff -NurpP --minimal linux-4.1.41/kernel/vserver/vci_config.h linux-4.1.41-vs2.3.8.5.3/kernel/vserver/vci_config.h
22994 --- linux-4.1.41/kernel/vserver/vci_config.h    1970-01-01 00:00:00.000000000 +0000
22995 +++ linux-4.1.41-vs2.3.8.5.3/kernel/vserver/vci_config.h        2016-07-05 04:41:47.000000000 +0000
22996 @@ -0,0 +1,80 @@
22997 +
22998 +/*  interface version */
22999 +
23000 +#define VCI_VERSION            0x00020308
23001 +
23002 +
23003 +enum {
23004 +       VCI_KCBIT_NO_DYNAMIC = 0,
23005 +
23006 +       VCI_KCBIT_PROC_SECURE = 4,
23007 +       /* VCI_KCBIT_HARDCPU = 5, */
23008 +       /* VCI_KCBIT_IDLELIMIT = 6, */
23009 +       /* VCI_KCBIT_IDLETIME = 7, */
23010 +
23011 +       VCI_KCBIT_COWBL = 8,
23012 +       VCI_KCBIT_FULLCOWBL = 9,
23013 +       VCI_KCBIT_SPACES = 10,
23014 +       VCI_KCBIT_NETV2 = 11,
23015 +       VCI_KCBIT_MEMCG = 12,
23016 +       VCI_KCBIT_MEMCG_SWAP = 13,
23017 +
23018 +       VCI_KCBIT_DEBUG = 16,
23019 +       VCI_KCBIT_HISTORY = 20,
23020 +       VCI_KCBIT_TAGGED = 24,
23021 +       VCI_KCBIT_PPTAG = 28,
23022 +
23023 +       VCI_KCBIT_MORE = 31,
23024 +};
23025 +
23026 +
23027 +static inline uint32_t vci_kernel_config(void)
23028 +{
23029 +       return
23030 +       (1 << VCI_KCBIT_NO_DYNAMIC) |
23031 +
23032 +       /* configured features */
23033 +#ifdef CONFIG_VSERVER_PROC_SECURE
23034 +       (1 << VCI_KCBIT_PROC_SECURE) |
23035 +#endif
23036 +#ifdef CONFIG_VSERVER_COWBL
23037 +       (1 << VCI_KCBIT_COWBL) |
23038 +       (1 << VCI_KCBIT_FULLCOWBL) |
23039 +#endif
23040 +       (1 << VCI_KCBIT_SPACES) |
23041 +       (1 << VCI_KCBIT_NETV2) |
23042 +#ifdef CONFIG_MEMCG
23043 +       (1 << VCI_KCBIT_MEMCG) |
23044 +#endif
23045 +#ifdef CONFIG_MEMCG_SWAP
23046 +       (1 << VCI_KCBIT_MEMCG_SWAP) |
23047 +#endif
23048 +
23049 +       /* debug options */
23050 +#ifdef CONFIG_VSERVER_DEBUG
23051 +       (1 << VCI_KCBIT_DEBUG) |
23052 +#endif
23053 +#ifdef CONFIG_VSERVER_HISTORY
23054 +       (1 << VCI_KCBIT_HISTORY) |
23055 +#endif
23056 +
23057 +       /* inode context tagging */
23058 +#if    defined(CONFIG_TAGGING_NONE)
23059 +       (0 << VCI_KCBIT_TAGGED) |
23060 +#elif  defined(CONFIG_TAGGING_UID16)
23061 +       (1 << VCI_KCBIT_TAGGED) |
23062 +#elif  defined(CONFIG_TAGGING_GID16)
23063 +       (2 << VCI_KCBIT_TAGGED) |
23064 +#elif  defined(CONFIG_TAGGING_ID24)
23065 +       (3 << VCI_KCBIT_TAGGED) |
23066 +#elif  defined(CONFIG_TAGGING_INTERN)
23067 +       (4 << VCI_KCBIT_TAGGED) |
23068 +#elif  defined(CONFIG_TAGGING_RUNTIME)
23069 +       (5 << VCI_KCBIT_TAGGED) |
23070 +#else
23071 +       (7 << VCI_KCBIT_TAGGED) |
23072 +#endif
23073 +       (1 << VCI_KCBIT_PPTAG) |
23074 +       0;
23075 +}
23076 +
23077 diff -NurpP --minimal linux-4.1.41/mm/memcontrol.c linux-4.1.41-vs2.3.8.5.3/mm/memcontrol.c
23078 --- linux-4.1.41/mm/memcontrol.c        2017-06-23 10:04:02.000000000 +0000
23079 +++ linux-4.1.41-vs2.3.8.5.3/mm/memcontrol.c    2016-07-05 18:27:07.000000000 +0000
23080 @@ -3192,6 +3192,28 @@ static u64 mem_cgroup_read_u64(struct cg
23081         }
23082  }
23083  
23084 +u64 mem_cgroup_mem_usage_pages(struct mem_cgroup *memcg)
23085 +{
23086 +       return mem_cgroup_usage(memcg, false) >> PAGE_SHIFT;
23087 +}
23088 +
23089 +u64 mem_cgroup_mem_limit_pages(struct mem_cgroup *memcg)
23090 +{
23091 +       return (u64)memcg->memory.limit;
23092 +}
23093 +
23094 +u64 mem_cgroup_memsw_usage_pages(struct mem_cgroup *memcg)
23095 +{
23096 +       return mem_cgroup_usage(memcg, true) >> PAGE_SHIFT;
23097 +}
23098 +
23099 +u64 mem_cgroup_memsw_limit_pages(struct mem_cgroup *memcg)
23100 +{
23101 +       return (u64)memcg->memsw.limit;
23102 +}
23103 +
23104 +
23105 +
23106  #ifdef CONFIG_MEMCG_KMEM
23107  static int memcg_activate_kmem(struct mem_cgroup *memcg,
23108                                unsigned long nr_pages)
23109 diff -NurpP --minimal linux-4.1.41/mm/oom_kill.c linux-4.1.41-vs2.3.8.5.3/mm/oom_kill.c
23110 --- linux-4.1.41/mm/oom_kill.c  2015-07-06 20:41:43.000000000 +0000
23111 +++ linux-4.1.41-vs2.3.8.5.3/mm/oom_kill.c      2016-07-05 04:41:47.000000000 +0000
23112 @@ -35,6 +35,8 @@
23113  #include <linux/freezer.h>
23114  #include <linux/ftrace.h>
23115  #include <linux/ratelimit.h>
23116 +#include <linux/reboot.h>
23117 +#include <linux/vs_context.h>
23118  
23119  #define CREATE_TRACE_POINTS
23120  #include <trace/events/oom.h>
23121 @@ -121,11 +123,18 @@ found:
23122  static bool oom_unkillable_task(struct task_struct *p,
23123                 struct mem_cgroup *memcg, const nodemask_t *nodemask)
23124  {
23125 -       if (is_global_init(p))
23126 +       unsigned xid = vx_current_xid();
23127 +
23128 +       /* skip the init task, global and per guest */
23129 +       if (task_is_init(p))
23130                 return true;
23131         if (p->flags & PF_KTHREAD)
23132                 return true;
23133  
23134 +       /* skip other guest and host processes if oom in guest */
23135 +       if (xid && vx_task_xid(p) != xid)
23136 +               return true;
23137 +
23138         /* When mem_cgroup_out_of_memory() and p is not member of the group */
23139         if (memcg && !task_in_mem_cgroup(p, memcg))
23140                 return true;
23141 @@ -528,8 +537,8 @@ void oom_kill_process(struct task_struct
23142                 dump_header(p, gfp_mask, order, memcg, nodemask);
23143  
23144         task_lock(p);
23145 -       pr_err("%s: Kill process %d (%s) score %d or sacrifice child\n",
23146 -               message, task_pid_nr(p), p->comm, points);
23147 +       pr_err("%s: Kill process %d:#%u (%s) score %d or sacrifice child\n",
23148 +               message, task_pid_nr(p), p->xid, p->comm, points);
23149         task_unlock(p);
23150  
23151         /*
23152 @@ -573,8 +582,8 @@ void oom_kill_process(struct task_struct
23153         /* mm cannot safely be dereferenced after task_unlock(victim) */
23154         mm = victim->mm;
23155         mark_tsk_oom_victim(victim);
23156 -       pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
23157 -               task_pid_nr(victim), victim->comm, K(victim->mm->total_vm),
23158 +       pr_err("Killed process %d:%u (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
23159 +               task_pid_nr(victim), victim->xid, victim->comm, K(victim->mm->total_vm),
23160                 K(get_mm_counter(victim->mm, MM_ANONPAGES)),
23161                 K(get_mm_counter(victim->mm, MM_FILEPAGES)));
23162         task_unlock(victim);
23163 @@ -645,6 +654,8 @@ int unregister_oom_notifier(struct notif
23164  }
23165  EXPORT_SYMBOL_GPL(unregister_oom_notifier);
23166  
23167 +long vs_oom_action(unsigned int);
23168 +
23169  /*
23170   * Try to acquire the OOM killer lock for the zones in zonelist.  Returns zero
23171   * if a parallel OOM killing is already taking place that includes a zone in
23172 @@ -757,7 +768,12 @@ static void __out_of_memory(struct zonel
23173         /* Found nothing?!?! Either we hang forever, or we panic. */
23174         if (!p) {
23175                 dump_header(NULL, gfp_mask, order, NULL, mpol_mask);
23176 -               panic("Out of memory and no killable processes...\n");
23177 +
23178 +               /* avoid panic for guest OOM */
23179 +               if (vx_current_xid())
23180 +                       vs_oom_action(LINUX_REBOOT_CMD_OOM);
23181 +               else
23182 +                       panic("Out of memory and no killable processes...\n");
23183         }
23184         if (p != (void *)-1UL) {
23185                 oom_kill_process(p, gfp_mask, order, points, totalpages, NULL,
23186 diff -NurpP --minimal linux-4.1.41/mm/page_alloc.c linux-4.1.41-vs2.3.8.5.3/mm/page_alloc.c
23187 --- linux-4.1.41/mm/page_alloc.c        2017-06-23 10:04:02.000000000 +0000
23188 +++ linux-4.1.41-vs2.3.8.5.3/mm/page_alloc.c    2017-05-30 07:39:23.000000000 +0000
23189 @@ -61,6 +61,8 @@
23190  #include <linux/hugetlb.h>
23191  #include <linux/sched/rt.h>
23192  #include <linux/page_owner.h>
23193 +#include <linux/vs_base.h>
23194 +#include <linux/vs_limit.h>
23195  
23196  #include <asm/sections.h>
23197  #include <asm/tlbflush.h>
23198 @@ -3189,6 +3191,9 @@ void si_meminfo(struct sysinfo *val)
23199         val->totalhigh = totalhigh_pages;
23200         val->freehigh = nr_free_highpages();
23201         val->mem_unit = PAGE_SIZE;
23202 +
23203 +       if (vx_flags(VXF_VIRT_MEM, 0))
23204 +               vx_vsi_meminfo(val);
23205  }
23206  
23207  EXPORT_SYMBOL(si_meminfo);
23208 @@ -3214,6 +3219,9 @@ void si_meminfo_node(struct sysinfo *val
23209         val->freehigh = 0;
23210  #endif
23211         val->mem_unit = PAGE_SIZE;
23212 +
23213 +       if (vx_flags(VXF_VIRT_MEM, 0))
23214 +               vx_vsi_meminfo(val);
23215  }
23216  #endif
23217  
23218 diff -NurpP --minimal linux-4.1.41/mm/pgtable-generic.c linux-4.1.41-vs2.3.8.5.3/mm/pgtable-generic.c
23219 --- linux-4.1.41/mm/pgtable-generic.c   2015-04-12 22:12:50.000000000 +0000
23220 +++ linux-4.1.41-vs2.3.8.5.3/mm/pgtable-generic.c       2016-07-05 04:41:47.000000000 +0000
23221 @@ -6,6 +6,8 @@
23222   *  Copyright (C) 2010  Linus Torvalds
23223   */
23224  
23225 +#include <linux/mm.h>
23226 +
23227  #include <linux/pagemap.h>
23228  #include <asm/tlb.h>
23229  #include <asm-generic/pgtable.h>
23230 diff -NurpP --minimal linux-4.1.41/mm/shmem.c linux-4.1.41-vs2.3.8.5.3/mm/shmem.c
23231 --- linux-4.1.41/mm/shmem.c     2017-06-23 10:04:02.000000000 +0000
23232 +++ linux-4.1.41-vs2.3.8.5.3/mm/shmem.c 2017-05-30 07:39:23.000000000 +0000
23233 @@ -2182,7 +2182,7 @@ static int shmem_statfs(struct dentry *d
23234  {
23235         struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
23236  
23237 -       buf->f_type = TMPFS_MAGIC;
23238 +       buf->f_type = TMPFS_SUPER_MAGIC;
23239         buf->f_bsize = PAGE_CACHE_SIZE;
23240         buf->f_namelen = NAME_MAX;
23241         if (sbinfo->max_blocks) {
23242 @@ -3035,7 +3035,7 @@ int shmem_fill_super(struct super_block
23243         sb->s_maxbytes = MAX_LFS_FILESIZE;
23244         sb->s_blocksize = PAGE_CACHE_SIZE;
23245         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
23246 -       sb->s_magic = TMPFS_MAGIC;
23247 +       sb->s_magic = TMPFS_SUPER_MAGIC;
23248         sb->s_op = &shmem_ops;
23249         sb->s_time_gran = 1;
23250  #ifdef CONFIG_TMPFS_XATTR
23251 diff -NurpP --minimal linux-4.1.41/mm/slab.c linux-4.1.41-vs2.3.8.5.3/mm/slab.c
23252 --- linux-4.1.41/mm/slab.c      2017-06-23 10:04:02.000000000 +0000
23253 +++ linux-4.1.41-vs2.3.8.5.3/mm/slab.c  2016-07-05 04:41:47.000000000 +0000
23254 @@ -336,6 +336,8 @@ static void kmem_cache_node_init(struct
23255  #define STATS_INC_FREEMISS(x)  do { } while (0)
23256  #endif
23257  
23258 +#include "slab_vs.h"
23259 +
23260  #if DEBUG
23261  
23262  /*
23263 @@ -3192,6 +3194,7 @@ slab_alloc_node(struct kmem_cache *cache
23264         /* ___cache_alloc_node can fall back to other nodes */
23265         ptr = ____cache_alloc_node(cachep, flags, nodeid);
23266    out:
23267 +       vx_slab_alloc(cachep, flags);
23268         local_irq_restore(save_flags);
23269         ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller);
23270         kmemleak_alloc_recursive(ptr, cachep->object_size, 1, cachep->flags,
23271 @@ -3380,6 +3383,7 @@ static inline void __cache_free(struct k
23272         check_irq_off();
23273         kmemleak_free_recursive(objp, cachep->flags);
23274         objp = cache_free_debugcheck(cachep, objp, caller);
23275 +       vx_slab_free(cachep);
23276  
23277         kmemcheck_slab_free(cachep, objp, cachep->object_size);
23278  
23279 diff -NurpP --minimal linux-4.1.41/mm/slab_vs.h linux-4.1.41-vs2.3.8.5.3/mm/slab_vs.h
23280 --- linux-4.1.41/mm/slab_vs.h   1970-01-01 00:00:00.000000000 +0000
23281 +++ linux-4.1.41-vs2.3.8.5.3/mm/slab_vs.h       2016-07-05 04:41:47.000000000 +0000
23282 @@ -0,0 +1,29 @@
23283 +
23284 +#include <linux/vserver/context.h>
23285 +
23286 +#include <linux/vs_context.h>
23287 +
23288 +static inline
23289 +void vx_slab_alloc(struct kmem_cache *cachep, gfp_t flags)
23290 +{
23291 +       int what = gfp_zone(cachep->allocflags);
23292 +       struct vx_info *vxi = current_vx_info();
23293 +
23294 +       if (!vxi)
23295 +               return;
23296 +
23297 +       atomic_add(cachep->size, &vxi->cacct.slab[what]);
23298 +}
23299 +
23300 +static inline
23301 +void vx_slab_free(struct kmem_cache *cachep)
23302 +{
23303 +       int what = gfp_zone(cachep->allocflags);
23304 +       struct vx_info *vxi = current_vx_info();
23305 +
23306 +       if (!vxi)
23307 +               return;
23308 +
23309 +       atomic_sub(cachep->size, &vxi->cacct.slab[what]);
23310 +}
23311 +
23312 diff -NurpP --minimal linux-4.1.41/mm/swapfile.c linux-4.1.41-vs2.3.8.5.3/mm/swapfile.c
23313 --- linux-4.1.41/mm/swapfile.c  2015-07-06 20:41:43.000000000 +0000
23314 +++ linux-4.1.41-vs2.3.8.5.3/mm/swapfile.c      2016-11-12 14:22:20.000000000 +0000
23315 @@ -39,6 +39,7 @@
23316  #include <asm/tlbflush.h>
23317  #include <linux/swapops.h>
23318  #include <linux/swap_cgroup.h>
23319 +#include <linux/vs_base.h>
23320  
23321  static bool swap_count_continued(struct swap_info_struct *, pgoff_t,
23322                                  unsigned char);
23323 @@ -2028,6 +2029,16 @@ static int swap_show(struct seq_file *sw
23324  
23325         if (si == SEQ_START_TOKEN) {
23326                 seq_puts(swap,"Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
23327 +               if (vx_flags(VXF_VIRT_MEM, 0)) {
23328 +                       struct sysinfo si = { 0 };
23329 +
23330 +                       vx_vsi_swapinfo(&si);
23331 +                       if (si.totalswap < (1 << 10))
23332 +                               return 0;
23333 +                       seq_printf(swap, "%s\t\t\t\t\t%s\t%lu\t%lu\t%d\n",
23334 +                               "hdv0", "partition", si.totalswap >> 10,
23335 +                               (si.totalswap - si.freeswap) >> 10, -1);
23336 +               }
23337                 return 0;
23338         }
23339  
23340 @@ -2576,6 +2587,8 @@ void si_swapinfo(struct sysinfo *val)
23341         val->freeswap = atomic_long_read(&nr_swap_pages) + nr_to_be_unused;
23342         val->totalswap = total_swap_pages + nr_to_be_unused;
23343         spin_unlock(&swap_lock);
23344 +       if (vx_flags(VXF_VIRT_MEM, 0))
23345 +               vx_vsi_swapinfo(val);
23346  }
23347  
23348  /*
23349 diff -NurpP --minimal linux-4.1.41/net/bridge/br_multicast.c linux-4.1.41-vs2.3.8.5.3/net/bridge/br_multicast.c
23350 --- linux-4.1.41/net/bridge/br_multicast.c      2017-06-23 10:04:02.000000000 +0000
23351 +++ linux-4.1.41-vs2.3.8.5.3/net/bridge/br_multicast.c  2016-07-05 04:41:47.000000000 +0000
23352 @@ -448,7 +448,7 @@ static struct sk_buff *br_ip6_multicast_
23353         ip6h->hop_limit = 1;
23354         ipv6_addr_set(&ip6h->daddr, htonl(0xff020000), 0, 0, htonl(1));
23355         if (ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0,
23356 -                              &ip6h->saddr)) {
23357 +                              &ip6h->saddr, NULL)) {
23358                 kfree_skb(skb);
23359                 return NULL;
23360         }
23361 diff -NurpP --minimal linux-4.1.41/net/core/dev.c linux-4.1.41-vs2.3.8.5.3/net/core/dev.c
23362 --- linux-4.1.41/net/core/dev.c 2017-06-23 10:04:02.000000000 +0000
23363 +++ linux-4.1.41-vs2.3.8.5.3/net/core/dev.c     2017-05-30 07:39:23.000000000 +0000
23364 @@ -123,6 +123,7 @@
23365  #include <linux/in.h>
23366  #include <linux/jhash.h>
23367  #include <linux/random.h>
23368 +#include <linux/vs_inet.h>
23369  #include <trace/events/napi.h>
23370  #include <trace/events/net.h>
23371  #include <trace/events/skb.h>
23372 @@ -694,7 +695,8 @@ struct net_device *__dev_get_by_name(str
23373         struct hlist_head *head = dev_name_hash(net, name);
23374  
23375         hlist_for_each_entry(dev, head, name_hlist)
23376 -               if (!strncmp(dev->name, name, IFNAMSIZ))
23377 +               if (!strncmp(dev->name, name, IFNAMSIZ) &&
23378 +                   nx_dev_visible(current_nx_info(), dev))
23379                         return dev;
23380  
23381         return NULL;
23382 @@ -719,7 +721,8 @@ struct net_device *dev_get_by_name_rcu(s
23383         struct hlist_head *head = dev_name_hash(net, name);
23384  
23385         hlist_for_each_entry_rcu(dev, head, name_hlist)
23386 -               if (!strncmp(dev->name, name, IFNAMSIZ))
23387 +               if (!strncmp(dev->name, name, IFNAMSIZ) &&
23388 +                   nx_dev_visible(current_nx_info(), dev))
23389                         return dev;
23390  
23391         return NULL;
23392 @@ -769,7 +772,8 @@ struct net_device *__dev_get_by_index(st
23393         struct hlist_head *head = dev_index_hash(net, ifindex);
23394  
23395         hlist_for_each_entry(dev, head, index_hlist)
23396 -               if (dev->ifindex == ifindex)
23397 +               if ((dev->ifindex == ifindex) &&
23398 +                   nx_dev_visible(current_nx_info(), dev))
23399                         return dev;
23400  
23401         return NULL;
23402 @@ -787,7 +791,7 @@ EXPORT_SYMBOL(__dev_get_by_index);
23403   *     about locking. The caller must hold RCU lock.
23404   */
23405  
23406 -struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
23407 +struct net_device *dev_get_by_index_real_rcu(struct net *net, int ifindex)
23408  {
23409         struct net_device *dev;
23410         struct hlist_head *head = dev_index_hash(net, ifindex);
23411 @@ -798,6 +802,16 @@ struct net_device *dev_get_by_index_rcu(
23412  
23413         return NULL;
23414  }
23415 +EXPORT_SYMBOL(dev_get_by_index_real_rcu);
23416 +
23417 +struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
23418 +{
23419 +       struct net_device *dev = dev_get_by_index_real_rcu(net, ifindex);
23420 +
23421 +       if (nx_dev_visible(current_nx_info(), dev))
23422 +               return dev;
23423 +       return NULL;
23424 +}
23425  EXPORT_SYMBOL(dev_get_by_index_rcu);
23426  
23427  
23428 @@ -880,7 +894,8 @@ struct net_device *dev_getbyhwaddr_rcu(s
23429  
23430         for_each_netdev_rcu(net, dev)
23431                 if (dev->type == type &&
23432 -                   !memcmp(dev->dev_addr, ha, dev->addr_len))
23433 +                   !memcmp(dev->dev_addr, ha, dev->addr_len) &&
23434 +                   nx_dev_visible(current_nx_info(), dev))
23435                         return dev;
23436  
23437         return NULL;
23438 @@ -892,9 +907,11 @@ struct net_device *__dev_getfirstbyhwtyp
23439         struct net_device *dev;
23440  
23441         ASSERT_RTNL();
23442 -       for_each_netdev(net, dev)
23443 -               if (dev->type == type)
23444 +       for_each_netdev(net, dev) {
23445 +               if ((dev->type == type) &&
23446 +                   nx_dev_visible(current_nx_info(), dev))
23447                         return dev;
23448 +       }
23449  
23450         return NULL;
23451  }
23452 @@ -906,7 +923,8 @@ struct net_device *dev_getfirstbyhwtype(
23453  
23454         rcu_read_lock();
23455         for_each_netdev_rcu(net, dev)
23456 -               if (dev->type == type) {
23457 +               if ((dev->type == type) &&
23458 +                   nx_dev_visible(current_nx_info(), dev)) {
23459                         dev_hold(dev);
23460                         ret = dev;
23461                         break;
23462 @@ -936,7 +954,8 @@ struct net_device *__dev_get_by_flags(st
23463  
23464         ret = NULL;
23465         for_each_netdev(net, dev) {
23466 -               if (((dev->flags ^ if_flags) & mask) == 0) {
23467 +               if ((((dev->flags ^ if_flags) & mask) == 0) &&
23468 +                       nx_dev_visible(current_nx_info(), dev)) {
23469                         ret = dev;
23470                         break;
23471                 }
23472 @@ -1014,6 +1033,8 @@ static int __dev_alloc_name(struct net *
23473                                 continue;
23474                         if (i < 0 || i >= max_netdevices)
23475                                 continue;
23476 +                       if (!nx_dev_visible(current_nx_info(), d))
23477 +                               continue;
23478  
23479                         /*  avoid cases where sscanf is not exact inverse of printf */
23480                         snprintf(buf, IFNAMSIZ, name, i);
23481 diff -NurpP --minimal linux-4.1.41/net/core/net-procfs.c linux-4.1.41-vs2.3.8.5.3/net/core/net-procfs.c
23482 --- linux-4.1.41/net/core/net-procfs.c  2015-04-12 22:12:50.000000000 +0000
23483 +++ linux-4.1.41-vs2.3.8.5.3/net/core/net-procfs.c      2016-07-05 04:41:47.000000000 +0000
23484 @@ -1,6 +1,7 @@
23485  #include <linux/netdevice.h>
23486  #include <linux/proc_fs.h>
23487  #include <linux/seq_file.h>
23488 +#include <linux/vs_inet.h>
23489  #include <net/wext.h>
23490  
23491  #define BUCKET_SPACE (32 - NETDEV_HASHBITS - 1)
23492 @@ -77,8 +78,13 @@ static void dev_seq_stop(struct seq_file
23493  static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
23494  {
23495         struct rtnl_link_stats64 temp;
23496 -       const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);
23497 +       const struct rtnl_link_stats64 *stats;
23498 +
23499 +       /* device visible inside network context? */
23500 +       if (!nx_dev_visible(current_nx_info(), dev))
23501 +               return;
23502  
23503 +       stats = dev_get_stats(dev, &temp);
23504         seq_printf(seq, "%6s: %7llu %7llu %4llu %4llu %4llu %5llu %10llu %9llu "
23505                    "%8llu %7llu %4llu %4llu %4llu %5llu %7llu %10llu\n",
23506                    dev->name, stats->rx_bytes, stats->rx_packets,
23507 diff -NurpP --minimal linux-4.1.41/net/core/rtnetlink.c linux-4.1.41-vs2.3.8.5.3/net/core/rtnetlink.c
23508 --- linux-4.1.41/net/core/rtnetlink.c   2017-06-23 10:04:02.000000000 +0000
23509 +++ linux-4.1.41-vs2.3.8.5.3/net/core/rtnetlink.c       2017-06-23 10:07:02.000000000 +0000
23510 @@ -1354,6 +1354,8 @@ static int rtnl_dump_ifinfo(struct sk_bu
23511                 hlist_for_each_entry(dev, head, index_hlist) {
23512                         if (idx < s_idx)
23513                                 goto cont;
23514 +                       if (!nx_dev_visible(skb->sk->sk_nx_info, dev))
23515 +                               continue;
23516                         err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
23517                                                NETLINK_CB(cb->skb).portid,
23518                                                cb->nlh->nlmsg_seq, 0,
23519 @@ -2425,6 +2427,9 @@ void rtmsg_ifinfo(int type, struct net_d
23520  {
23521         struct sk_buff *skb;
23522  
23523 +       if (!nx_dev_visible(current_nx_info(), dev))
23524 +               return;
23525 +
23526         if (dev->reg_state != NETREG_REGISTERED)
23527                 return;
23528  
23529 diff -NurpP --minimal linux-4.1.41/net/core/sock.c linux-4.1.41-vs2.3.8.5.3/net/core/sock.c
23530 --- linux-4.1.41/net/core/sock.c        2017-06-23 10:04:02.000000000 +0000
23531 +++ linux-4.1.41-vs2.3.8.5.3/net/core/sock.c    2016-07-05 04:41:47.000000000 +0000
23532 @@ -133,6 +133,10 @@
23533  #include <net/netprio_cgroup.h>
23534  
23535  #include <linux/filter.h>
23536 +#include <linux/vs_socket.h>
23537 +#include <linux/vs_limit.h>
23538 +#include <linux/vs_context.h>
23539 +#include <linux/vs_network.h>
23540  
23541  #include <trace/events/sock.h>
23542  
23543 @@ -1346,6 +1350,8 @@ static struct sock *sk_prot_alloc(struct
23544                         goto out_free_sec;
23545                 sk_tx_queue_clear(sk);
23546         }
23547 +               sock_vx_init(sk);
23548 +               sock_nx_init(sk);
23549  
23550         return sk;
23551  
23552 @@ -1442,6 +1448,11 @@ static void __sk_free(struct sock *sk)
23553                 put_cred(sk->sk_peer_cred);
23554         put_pid(sk->sk_peer_pid);
23555         put_net(sock_net(sk));
23556 +       vx_sock_dec(sk);
23557 +       clr_vx_info(&sk->sk_vx_info);
23558 +       sk->sk_xid = -1;
23559 +       clr_nx_info(&sk->sk_nx_info);
23560 +       sk->sk_nid = -1;
23561         sk_prot_free(sk->sk_prot_creator, sk);
23562  }
23563  
23564 @@ -1502,6 +1513,8 @@ struct sock *sk_clone_lock(const struct
23565  
23566                 /* SANITY */
23567                 get_net(sock_net(newsk));
23568 +               sock_vx_init(newsk);
23569 +               sock_nx_init(newsk);
23570                 sk_node_init(&newsk->sk_node);
23571                 sock_lock_init(newsk);
23572                 bh_lock_sock(newsk);
23573 @@ -1561,6 +1574,12 @@ struct sock *sk_clone_lock(const struct
23574                 smp_wmb();
23575                 atomic_set(&newsk->sk_refcnt, 2);
23576  
23577 +               set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info);
23578 +               newsk->sk_xid = sk->sk_xid;
23579 +               vx_sock_inc(newsk);
23580 +               set_nx_info(&newsk->sk_nx_info, sk->sk_nx_info);
23581 +               newsk->sk_nid = sk->sk_nid;
23582 +
23583                 /*
23584                  * Increment the counter in the same struct proto as the master
23585                  * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
23586 @@ -2345,6 +2364,12 @@ void sock_init_data(struct socket *sock,
23587  
23588         sk->sk_stamp = ktime_set(-1L, 0);
23589  
23590 +       set_vx_info(&sk->sk_vx_info, current_vx_info());
23591 +       sk->sk_xid = vx_current_xid();
23592 +       vx_sock_inc(sk);
23593 +       set_nx_info(&sk->sk_nx_info, current_nx_info());
23594 +       sk->sk_nid = nx_current_nid();
23595 +
23596  #ifdef CONFIG_NET_RX_BUSY_POLL
23597         sk->sk_napi_id          =       0;
23598         sk->sk_ll_usec          =       sysctl_net_busy_read;
23599 diff -NurpP --minimal linux-4.1.41/net/ipv4/af_inet.c linux-4.1.41-vs2.3.8.5.3/net/ipv4/af_inet.c
23600 --- linux-4.1.41/net/ipv4/af_inet.c     2017-06-23 10:04:02.000000000 +0000
23601 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv4/af_inet.c 2017-05-30 07:39:23.000000000 +0000
23602 @@ -118,6 +118,7 @@
23603  #ifdef CONFIG_IP_MROUTE
23604  #include <linux/mroute.h>
23605  #endif
23606 +#include <linux/vs_limit.h>
23607  
23608  
23609  /* The inetsw table contains everything that inet_create needs to
23610 @@ -310,10 +311,13 @@ lookup_protocol:
23611         }
23612  
23613         err = -EPERM;
23614 +       if ((protocol == IPPROTO_ICMP) &&
23615 +               nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
23616 +               goto override;
23617         if (sock->type == SOCK_RAW && !kern &&
23618             !ns_capable(net->user_ns, CAP_NET_RAW))
23619                 goto out_rcu_unlock;
23620 -
23621 +override:
23622         sock->ops = answer->ops;
23623         answer_prot = answer->prot;
23624         answer_flags = answer->flags;
23625 @@ -426,6 +430,7 @@ int inet_bind(struct socket *sock, struc
23626         struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
23627         struct sock *sk = sock->sk;
23628         struct inet_sock *inet = inet_sk(sk);
23629 +       struct nx_v4_sock_addr nsa;
23630         struct net *net = sock_net(sk);
23631         unsigned short snum;
23632         int chk_addr_ret;
23633 @@ -450,7 +455,11 @@ int inet_bind(struct socket *sock, struc
23634                         goto out;
23635         }
23636  
23637 -       chk_addr_ret = inet_addr_type(net, addr->sin_addr.s_addr);
23638 +       err = v4_map_sock_addr(inet, addr, &nsa);
23639 +       if (err)
23640 +               goto out;
23641 +
23642 +       chk_addr_ret = inet_addr_type(net, nsa.saddr);
23643  
23644         /* Not specified by any standard per-se, however it breaks too
23645          * many applications when removed.  It is unfortunate since
23646 @@ -462,7 +471,7 @@ int inet_bind(struct socket *sock, struc
23647         err = -EADDRNOTAVAIL;
23648         if (!net->ipv4.sysctl_ip_nonlocal_bind &&
23649             !(inet->freebind || inet->transparent) &&
23650 -           addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
23651 +           nsa.saddr != htonl(INADDR_ANY) &&
23652             chk_addr_ret != RTN_LOCAL &&
23653             chk_addr_ret != RTN_MULTICAST &&
23654             chk_addr_ret != RTN_BROADCAST)
23655 @@ -488,7 +497,7 @@ int inet_bind(struct socket *sock, struc
23656         if (sk->sk_state != TCP_CLOSE || inet->inet_num)
23657                 goto out_release_sock;
23658  
23659 -       inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
23660 +       v4_set_sock_addr(inet, &nsa);
23661         if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
23662                 inet->inet_saddr = 0;  /* Use device */
23663  
23664 @@ -707,11 +716,13 @@ int inet_getname(struct socket *sock, st
23665                      peer == 1))
23666                         return -ENOTCONN;
23667                 sin->sin_port = inet->inet_dport;
23668 -               sin->sin_addr.s_addr = inet->inet_daddr;
23669 +               sin->sin_addr.s_addr =
23670 +                       nx_map_sock_lback(sk->sk_nx_info, inet->inet_daddr);
23671         } else {
23672                 __be32 addr = inet->inet_rcv_saddr;
23673                 if (!addr)
23674                         addr = inet->inet_saddr;
23675 +               addr = nx_map_sock_lback(sk->sk_nx_info, addr);
23676                 sin->sin_port = inet->inet_sport;
23677                 sin->sin_addr.s_addr = addr;
23678         }
23679 diff -NurpP --minimal linux-4.1.41/net/ipv4/arp.c linux-4.1.41-vs2.3.8.5.3/net/ipv4/arp.c
23680 --- linux-4.1.41/net/ipv4/arp.c 2015-07-06 20:41:43.000000000 +0000
23681 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv4/arp.c     2016-07-05 04:41:47.000000000 +0000
23682 @@ -1257,6 +1257,7 @@ static void arp_format_neigh_entry(struc
23683         struct net_device *dev = n->dev;
23684         int hatype = dev->type;
23685  
23686 +       /* FIXME: check for network context */
23687         read_lock(&n->lock);
23688         /* Convert hardware address to XX:XX:XX:XX ... form. */
23689  #if IS_ENABLED(CONFIG_AX25)
23690 @@ -1288,6 +1289,7 @@ static void arp_format_pneigh_entry(stru
23691         int hatype = dev ? dev->type : 0;
23692         char tbuf[16];
23693  
23694 +       /* FIXME: check for network context */
23695         sprintf(tbuf, "%pI4", n->key);
23696         seq_printf(seq, "%-16s 0x%-10x0x%-10x%s     *        %s\n",
23697                    tbuf, hatype, ATF_PUBL | ATF_PERM, "00:00:00:00:00:00",
23698 diff -NurpP --minimal linux-4.1.41/net/ipv4/devinet.c linux-4.1.41-vs2.3.8.5.3/net/ipv4/devinet.c
23699 --- linux-4.1.41/net/ipv4/devinet.c     2017-06-23 10:04:02.000000000 +0000
23700 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv4/devinet.c 2016-10-25 21:31:20.000000000 +0000
23701 @@ -538,6 +538,7 @@ struct in_device *inetdev_by_index(struc
23702  }
23703  EXPORT_SYMBOL(inetdev_by_index);
23704  
23705 +
23706  /* Called only from RTNL semaphored context. No locks. */
23707  
23708  struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
23709 @@ -993,6 +994,8 @@ int devinet_ioctl(struct net *net, unsig
23710  
23711         in_dev = __in_dev_get_rtnl(dev);
23712         if (in_dev) {
23713 +               struct nx_info *nxi = current_nx_info();
23714 +
23715                 if (tryaddrmatch) {
23716                         /* Matthias Andree */
23717                         /* compare label and address (4.4BSD style) */
23718 @@ -1001,6 +1004,8 @@ int devinet_ioctl(struct net *net, unsig
23719                            This is checked above. */
23720                         for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
23721                              ifap = &ifa->ifa_next) {
23722 +                               if (!nx_v4_ifa_visible(nxi, ifa))
23723 +                                       continue;
23724                                 if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
23725                                     sin_orig.sin_addr.s_addr ==
23726                                                         ifa->ifa_local) {
23727 @@ -1013,9 +1018,12 @@ int devinet_ioctl(struct net *net, unsig
23728                    comparing just the label */
23729                 if (!ifa) {
23730                         for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
23731 -                            ifap = &ifa->ifa_next)
23732 +                            ifap = &ifa->ifa_next) {
23733 +                               if (!nx_v4_ifa_visible(nxi, ifa))
23734 +                                       continue;
23735                                 if (!strcmp(ifr.ifr_name, ifa->ifa_label))
23736                                         break;
23737 +                       }
23738                 }
23739         }
23740  
23741 @@ -1169,6 +1177,8 @@ static int inet_gifconf(struct net_devic
23742                 goto out;
23743  
23744         for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
23745 +               if (!nx_v4_ifa_visible(current_nx_info(), ifa))
23746 +                       continue;
23747                 if (!buf) {
23748                         done += sizeof(ifr);
23749                         continue;
23750 @@ -1574,6 +1584,7 @@ static int inet_dump_ifaddr(struct sk_bu
23751         struct net_device *dev;
23752         struct in_device *in_dev;
23753         struct in_ifaddr *ifa;
23754 +       struct sock *sk = skb->sk;
23755         struct hlist_head *head;
23756  
23757         s_h = cb->args[0];
23758 @@ -1597,6 +1608,8 @@ static int inet_dump_ifaddr(struct sk_bu
23759  
23760                         for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
23761                              ifa = ifa->ifa_next, ip_idx++) {
23762 +                       if (sk && !nx_v4_ifa_visible(sk->sk_nx_info, ifa))
23763 +                               continue;
23764                                 if (ip_idx < s_ip_idx)
23765                                         continue;
23766                                 if (inet_fill_ifaddr(skb, ifa,
23767 diff -NurpP --minimal linux-4.1.41/net/ipv4/fib_trie.c linux-4.1.41-vs2.3.8.5.3/net/ipv4/fib_trie.c
23768 --- linux-4.1.41/net/ipv4/fib_trie.c    2017-06-23 10:04:02.000000000 +0000
23769 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv4/fib_trie.c        2016-07-05 04:41:47.000000000 +0000
23770 @@ -2576,6 +2576,7 @@ static int fib_route_seq_show(struct seq
23771  
23772                 seq_setwidth(seq, 127);
23773  
23774 +               /* FIXME: check for network context? */
23775                 if (fi)
23776                         seq_printf(seq,
23777                                    "%s\t%08X\t%08X\t%04X\t%d\t%u\t"
23778 diff -NurpP --minimal linux-4.1.41/net/ipv4/inet_connection_sock.c linux-4.1.41-vs2.3.8.5.3/net/ipv4/inet_connection_sock.c
23779 --- linux-4.1.41/net/ipv4/inet_connection_sock.c        2017-06-23 10:04:02.000000000 +0000
23780 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv4/inet_connection_sock.c    2016-07-05 04:41:47.000000000 +0000
23781 @@ -43,6 +43,37 @@ void inet_get_local_port_range(struct ne
23782  }
23783  EXPORT_SYMBOL(inet_get_local_port_range);
23784  
23785 +int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
23786 +{
23787 +       __be32  sk1_rcv_saddr = sk1->sk_rcv_saddr,
23788 +               sk2_rcv_saddr = sk2->sk_rcv_saddr;
23789 +
23790 +       if (inet_v6_ipv6only(sk2))
23791 +               return 0;
23792 +
23793 +       if (sk1_rcv_saddr &&
23794 +           sk2_rcv_saddr &&
23795 +           sk1_rcv_saddr == sk2_rcv_saddr)
23796 +               return 1;
23797 +
23798 +       if (sk1_rcv_saddr &&
23799 +           !sk2_rcv_saddr &&
23800 +           v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, NXA_MASK_BIND))
23801 +               return 1;
23802 +
23803 +       if (sk2_rcv_saddr &&
23804 +           !sk1_rcv_saddr &&
23805 +           v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, NXA_MASK_BIND))
23806 +               return 1;
23807 +
23808 +       if (!sk1_rcv_saddr &&
23809 +           !sk2_rcv_saddr &&
23810 +           nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info))
23811 +               return 1;
23812 +
23813 +       return 0;
23814 +}
23815 +
23816  int inet_csk_bind_conflict(const struct sock *sk,
23817                            const struct inet_bind_bucket *tb, bool relax)
23818  {
23819 @@ -70,15 +101,13 @@ int inet_csk_bind_conflict(const struct
23820                             (sk2->sk_state != TCP_TIME_WAIT &&
23821                              !uid_eq(uid, sock_i_uid(sk2))))) {
23822  
23823 -                               if (!sk2->sk_rcv_saddr || !sk->sk_rcv_saddr ||
23824 -                                   sk2->sk_rcv_saddr == sk->sk_rcv_saddr)
23825 +                               if (ipv4_rcv_saddr_equal(sk, sk2))
23826                                         break;
23827                         }
23828                         if (!relax && reuse && sk2->sk_reuse &&
23829                             sk2->sk_state != TCP_LISTEN) {
23830  
23831 -                               if (!sk2->sk_rcv_saddr || !sk->sk_rcv_saddr ||
23832 -                                   sk2->sk_rcv_saddr == sk->sk_rcv_saddr)
23833 +                               if (ipv4_rcv_saddr_equal(sk, sk2))
23834                                         break;
23835                         }
23836                 }
23837 diff -NurpP --minimal linux-4.1.41/net/ipv4/inet_diag.c linux-4.1.41-vs2.3.8.5.3/net/ipv4/inet_diag.c
23838 --- linux-4.1.41/net/ipv4/inet_diag.c   2015-07-06 20:41:43.000000000 +0000
23839 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv4/inet_diag.c       2016-07-05 04:41:47.000000000 +0000
23840 @@ -31,6 +31,8 @@
23841  
23842  #include <linux/inet.h>
23843  #include <linux/stddef.h>
23844 +#include <linux/vs_network.h>
23845 +#include <linux/vs_inet.h>
23846  
23847  #include <linux/inet_diag.h>
23848  #include <linux/sock_diag.h>
23849 @@ -770,6 +772,7 @@ static int inet_diag_dump_reqs(struct sk
23850                             r->id.idiag_dport)
23851                                 continue;
23852  
23853 +                       /* TODO: lback */
23854                         if (bc) {
23855                                 /* Note: entry.sport and entry.userlocks are already set */
23856                                 entry_fill_addrs(&entry, req_to_sk(req));
23857 @@ -827,6 +830,8 @@ void inet_diag_dump_icsk(struct inet_has
23858                                 if (!net_eq(sock_net(sk), net))
23859                                         continue;
23860  
23861 +                               if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23862 +                                       continue;
23863                                 if (num < s_num) {
23864                                         num++;
23865                                         continue;
23866 @@ -898,6 +903,8 @@ skip_listen_ht:
23867  
23868                         if (!net_eq(sock_net(sk), net))
23869                                 continue;
23870 +                       if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23871 +                               continue;
23872                         if (num < s_num)
23873                                 goto next_normal;
23874                         state = (sk->sk_state == TCP_TIME_WAIT) ?
23875 diff -NurpP --minimal linux-4.1.41/net/ipv4/inet_hashtables.c linux-4.1.41-vs2.3.8.5.3/net/ipv4/inet_hashtables.c
23876 --- linux-4.1.41/net/ipv4/inet_hashtables.c     2015-07-06 20:41:43.000000000 +0000
23877 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv4/inet_hashtables.c 2016-07-05 04:41:47.000000000 +0000
23878 @@ -22,6 +22,7 @@
23879  #include <net/inet_connection_sock.h>
23880  #include <net/inet_hashtables.h>
23881  #include <net/secure_seq.h>
23882 +#include <net/route.h>
23883  #include <net/ip.h>
23884  
23885  static u32 inet_ehashfn(const struct net *net, const __be32 laddr,
23886 @@ -184,6 +185,11 @@ static inline int compute_score(struct s
23887                         if (rcv_saddr != daddr)
23888                                 return -1;
23889                         score += 4;
23890 +               } else {
23891 +                       /* block non nx_info ips */
23892 +                       if (!v4_addr_in_nx_info(sk->sk_nx_info,
23893 +                               daddr, NXA_MASK_BIND))
23894 +                               return -1;
23895                 }
23896                 if (sk->sk_bound_dev_if) {
23897                         if (sk->sk_bound_dev_if != dif)
23898 @@ -201,7 +207,6 @@ static inline int compute_score(struct s
23899   * wildcarded during the search since they can never be otherwise.
23900   */
23901  
23902 -
23903  struct sock *__inet_lookup_listener(struct net *net,
23904                                     struct inet_hashinfo *hashinfo,
23905                                     const __be32 saddr, __be16 sport,
23906 @@ -237,6 +242,7 @@ begin:
23907                         phash = next_pseudo_random32(phash);
23908                 }
23909         }
23910 +
23911         /*
23912          * if the nulls value we got at the end of this lookup is
23913          * not the expected one, we must restart lookup.
23914 diff -NurpP --minimal linux-4.1.41/net/ipv4/netfilter.c linux-4.1.41-vs2.3.8.5.3/net/ipv4/netfilter.c
23915 --- linux-4.1.41/net/ipv4/netfilter.c   2015-07-06 20:41:43.000000000 +0000
23916 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv4/netfilter.c       2016-07-05 04:41:47.000000000 +0000
23917 @@ -11,7 +11,7 @@
23918  #include <linux/skbuff.h>
23919  #include <linux/gfp.h>
23920  #include <linux/export.h>
23921 -#include <net/route.h>
23922 +// #include <net/route.h>
23923  #include <net/xfrm.h>
23924  #include <net/ip.h>
23925  #include <net/netfilter/nf_queue.h>
23926 diff -NurpP --minimal linux-4.1.41/net/ipv4/raw.c linux-4.1.41-vs2.3.8.5.3/net/ipv4/raw.c
23927 --- linux-4.1.41/net/ipv4/raw.c 2017-06-23 10:04:02.000000000 +0000
23928 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv4/raw.c     2017-06-23 10:07:02.000000000 +0000
23929 @@ -126,7 +126,7 @@ static struct sock *__raw_v4_lookup(stru
23930  
23931                 if (net_eq(sock_net(sk), net) && inet->inet_num == num  &&
23932                     !(inet->inet_daddr && inet->inet_daddr != raddr)    &&
23933 -                   !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
23934 +                   v4_sock_addr_match(sk->sk_nx_info, inet, laddr)     &&
23935                     !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
23936                         goto found; /* gotcha */
23937         }
23938 @@ -414,6 +414,12 @@ static int raw_send_hdrinc(struct sock *
23939                 icmp_out_count(net, ((struct icmphdr *)
23940                         skb_transport_header(skb))->type);
23941  
23942 +       err = -EPERM;
23943 +       if (!nx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW) &&
23944 +               sk->sk_nx_info &&
23945 +               !v4_addr_in_nx_info(sk->sk_nx_info, iph->saddr, NXA_MASK_BIND))
23946 +               goto error_free;
23947 +
23948         err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, sk, skb,
23949                       NULL, rt->dst.dev, dst_output_sk);
23950         if (err > 0)
23951 @@ -611,6 +617,16 @@ static int raw_sendmsg(struct sock *sk,
23952                         goto done;
23953         }
23954  
23955 +       if (sk->sk_nx_info) {
23956 +               rt = ip_v4_find_src(sock_net(sk), sk->sk_nx_info, &fl4);
23957 +               if (IS_ERR(rt)) {
23958 +                       err = PTR_ERR(rt);
23959 +                       rt = NULL;
23960 +                       goto done;
23961 +               }
23962 +               ip_rt_put(rt);
23963 +       }
23964 +
23965         security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
23966         rt = ip_route_output_flow(sock_net(sk), &fl4, sk);
23967         if (IS_ERR(rt)) {
23968 @@ -689,17 +705,19 @@ static int raw_bind(struct sock *sk, str
23969  {
23970         struct inet_sock *inet = inet_sk(sk);
23971         struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
23972 +       struct nx_v4_sock_addr nsa = { 0 };
23973         int ret = -EINVAL;
23974         int chk_addr_ret;
23975  
23976         if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
23977                 goto out;
23978 -       chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
23979 +       v4_map_sock_addr(inet, addr, &nsa);
23980 +       chk_addr_ret = inet_addr_type(sock_net(sk), nsa.saddr);
23981         ret = -EADDRNOTAVAIL;
23982 -       if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
23983 +       if (nsa.saddr && chk_addr_ret != RTN_LOCAL &&
23984             chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
23985                 goto out;
23986 -       inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
23987 +       v4_set_sock_addr(inet, &nsa);
23988         if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
23989                 inet->inet_saddr = 0;  /* Use device */
23990         sk_dst_reset(sk);
23991 @@ -748,7 +766,8 @@ static int raw_recvmsg(struct sock *sk,
23992         /* Copy the address. */
23993         if (sin) {
23994                 sin->sin_family = AF_INET;
23995 -               sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
23996 +               sin->sin_addr.s_addr =
23997 +                       nx_map_sock_lback(sk->sk_nx_info, ip_hdr(skb)->saddr);
23998                 sin->sin_port = 0;
23999                 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
24000                 *addr_len = sizeof(*sin);
24001 @@ -944,7 +963,8 @@ static struct sock *raw_get_first(struct
24002         for (state->bucket = 0; state->bucket < RAW_HTABLE_SIZE;
24003                         ++state->bucket) {
24004                 sk_for_each(sk, &state->h->ht[state->bucket])
24005 -                       if (sock_net(sk) == seq_file_net(seq))
24006 +                       if ((sock_net(sk) == seq_file_net(seq)) &&
24007 +                           nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24008                                 goto found;
24009         }
24010         sk = NULL;
24011 @@ -960,7 +980,8 @@ static struct sock *raw_get_next(struct
24012                 sk = sk_next(sk);
24013  try_again:
24014                 ;
24015 -       } while (sk && sock_net(sk) != seq_file_net(seq));
24016 +       } while (sk && ((sock_net(sk) != seq_file_net(seq)) ||
24017 +               !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
24018  
24019         if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
24020                 sk = sk_head(&state->h->ht[state->bucket]);
24021 diff -NurpP --minimal linux-4.1.41/net/ipv4/route.c linux-4.1.41-vs2.3.8.5.3/net/ipv4/route.c
24022 --- linux-4.1.41/net/ipv4/route.c       2017-06-23 10:04:02.000000000 +0000
24023 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv4/route.c   2017-06-23 10:07:02.000000000 +0000
24024 @@ -2148,7 +2148,7 @@ struct rtable *__ip_route_output_key(str
24025  
24026  
24027         if (fl4->flowi4_oif) {
24028 -               dev_out = dev_get_by_index_rcu(net, fl4->flowi4_oif);
24029 +               dev_out = dev_get_by_index_real_rcu(net, fl4->flowi4_oif);
24030                 rth = ERR_PTR(-ENODEV);
24031                 if (!dev_out)
24032                         goto out;
24033 diff -NurpP --minimal linux-4.1.41/net/ipv4/tcp.c linux-4.1.41-vs2.3.8.5.3/net/ipv4/tcp.c
24034 --- linux-4.1.41/net/ipv4/tcp.c 2017-06-23 10:04:02.000000000 +0000
24035 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv4/tcp.c     2016-07-05 04:41:47.000000000 +0000
24036 @@ -269,6 +269,7 @@
24037  #include <linux/crypto.h>
24038  #include <linux/time.h>
24039  #include <linux/slab.h>
24040 +#include <linux/in.h>
24041  
24042  #include <net/icmp.h>
24043  #include <net/inet_common.h>
24044 diff -NurpP --minimal linux-4.1.41/net/ipv4/tcp_ipv4.c linux-4.1.41-vs2.3.8.5.3/net/ipv4/tcp_ipv4.c
24045 --- linux-4.1.41/net/ipv4/tcp_ipv4.c    2017-06-23 10:04:02.000000000 +0000
24046 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv4/tcp_ipv4.c        2016-07-05 04:41:47.000000000 +0000
24047 @@ -1846,6 +1846,12 @@ static void *listening_get_next(struct s
24048                 req = req->dl_next;
24049                 while (1) {
24050                         while (req) {
24051 +                               vxdprintk(VXD_CBIT(net, 6),
24052 +                                       "sk,req: %p [#%d] (from %d)", req->sk,
24053 +                                       (req->sk)?req->sk->sk_nid:0, nx_current_nid());
24054 +                               if (req->sk &&
24055 +                                       !nx_check(req->sk->sk_nid, VS_WATCH_P | VS_IDENT))
24056 +                                       continue;
24057                                 if (req->rsk_ops->family == st->family) {
24058                                         cur = req;
24059                                         goto out;
24060 @@ -1870,6 +1876,10 @@ get_req:
24061         }
24062  get_sk:
24063         sk_nulls_for_each_from(sk, node) {
24064 +               vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
24065 +                       sk, sk->sk_nid, nx_current_nid());
24066 +               if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24067 +                       continue;
24068                 if (!net_eq(sock_net(sk), net))
24069                         continue;
24070                 if (sk->sk_family == st->family) {
24071 @@ -1944,6 +1954,11 @@ static void *established_get_first(struc
24072  
24073                 spin_lock_bh(lock);
24074                 sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
24075 +                       vxdprintk(VXD_CBIT(net, 6),
24076 +                               "sk,egf: %p [#%d] (from %d)",
24077 +                               sk, sk->sk_nid, nx_current_nid());
24078 +                       if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24079 +                               continue;
24080                         if (sk->sk_family != st->family ||
24081                             !net_eq(sock_net(sk), net)) {
24082                                 continue;
24083 @@ -1970,6 +1985,11 @@ static void *established_get_next(struct
24084         sk = sk_nulls_next(sk);
24085  
24086         sk_nulls_for_each_from(sk, node) {
24087 +               vxdprintk(VXD_CBIT(net, 6),
24088 +                       "sk,egn: %p [#%d] (from %d)",
24089 +                       sk, sk->sk_nid, nx_current_nid());
24090 +               if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24091 +                       continue;
24092                 if (sk->sk_family == st->family && net_eq(sock_net(sk), net))
24093                         return sk;
24094         }
24095 @@ -2168,9 +2188,9 @@ static void get_openreq4(const struct re
24096         seq_printf(f, "%4d: %08X:%04X %08X:%04X"
24097                 " %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK",
24098                 i,
24099 -               ireq->ir_loc_addr,
24100 +               nx_map_sock_lback(current_nx_info(), ireq->ir_loc_addr),
24101                 ireq->ir_num,
24102 -               ireq->ir_rmt_addr,
24103 +               nx_map_sock_lback(current_nx_info(), ireq->ir_rmt_addr),
24104                 ntohs(ireq->ir_rmt_port),
24105                 TCP_SYN_RECV,
24106                 0, 0, /* could print option size, but that is af dependent. */
24107 @@ -2192,8 +2212,8 @@ static void get_tcp4_sock(struct sock *s
24108         const struct inet_connection_sock *icsk = inet_csk(sk);
24109         const struct inet_sock *inet = inet_sk(sk);
24110         struct fastopen_queue *fastopenq = icsk->icsk_accept_queue.fastopenq;
24111 -       __be32 dest = inet->inet_daddr;
24112 -       __be32 src = inet->inet_rcv_saddr;
24113 +       __be32 dest = nx_map_sock_lback(current_nx_info(), inet->inet_daddr);
24114 +       __be32 src = nx_map_sock_lback(current_nx_info(), inet->inet_rcv_saddr);
24115         __u16 destp = ntohs(inet->inet_dport);
24116         __u16 srcp = ntohs(inet->inet_sport);
24117         int rx_queue;
24118 @@ -2250,8 +2270,8 @@ static void get_timewait4_sock(const str
24119         __be32 dest, src;
24120         __u16 destp, srcp;
24121  
24122 -       dest  = tw->tw_daddr;
24123 -       src   = tw->tw_rcv_saddr;
24124 +       dest  = nx_map_sock_lback(current_nx_info(), tw->tw_daddr);
24125 +       src   = nx_map_sock_lback(current_nx_info(), tw->tw_rcv_saddr);
24126         destp = ntohs(tw->tw_dport);
24127         srcp  = ntohs(tw->tw_sport);
24128  
24129 diff -NurpP --minimal linux-4.1.41/net/ipv4/tcp_minisocks.c linux-4.1.41-vs2.3.8.5.3/net/ipv4/tcp_minisocks.c
24130 --- linux-4.1.41/net/ipv4/tcp_minisocks.c       2017-06-23 10:04:02.000000000 +0000
24131 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv4/tcp_minisocks.c   2016-07-05 04:41:47.000000000 +0000
24132 @@ -23,6 +23,9 @@
24133  #include <linux/slab.h>
24134  #include <linux/sysctl.h>
24135  #include <linux/workqueue.h>
24136 +#include <linux/vs_limit.h>
24137 +#include <linux/vs_socket.h>
24138 +#include <linux/vs_context.h>
24139  #include <net/tcp.h>
24140  #include <net/inet_common.h>
24141  #include <net/xfrm.h>
24142 @@ -293,6 +296,11 @@ void tcp_time_wait(struct sock *sk, int
24143                 tcptw->tw_ts_offset     = tp->tsoffset;
24144                 tcptw->tw_last_oow_ack_time = 0;
24145  
24146 +               tw->tw_xid              = sk->sk_xid;
24147 +               tw->tw_vx_info          = NULL;
24148 +               tw->tw_nid              = sk->sk_nid;
24149 +               tw->tw_nx_info          = NULL;
24150 +
24151  #if IS_ENABLED(CONFIG_IPV6)
24152                 if (tw->tw_family == PF_INET6) {
24153                         struct ipv6_pinfo *np = inet6_sk(sk);
24154 diff -NurpP --minimal linux-4.1.41/net/ipv4/udp.c linux-4.1.41-vs2.3.8.5.3/net/ipv4/udp.c
24155 --- linux-4.1.41/net/ipv4/udp.c 2017-06-23 10:04:02.000000000 +0000
24156 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv4/udp.c     2017-05-30 07:39:23.000000000 +0000
24157 @@ -310,14 +310,7 @@ fail:
24158  }
24159  EXPORT_SYMBOL(udp_lib_get_port);
24160  
24161 -static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
24162 -{
24163 -       struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
24164 -
24165 -       return  (!ipv6_only_sock(sk2)  &&
24166 -                (!inet1->inet_rcv_saddr || !inet2->inet_rcv_saddr ||
24167 -                  inet1->inet_rcv_saddr == inet2->inet_rcv_saddr));
24168 -}
24169 +extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *);
24170  
24171  static u32 udp4_portaddr_hash(const struct net *net, __be32 saddr,
24172                               unsigned int port)
24173 @@ -356,6 +349,11 @@ static inline int compute_score(struct s
24174                 if (inet->inet_rcv_saddr != daddr)
24175                         return -1;
24176                 score += 4;
24177 +               } else {
24178 +                       /* block non nx_info ips */
24179 +                       if (!v4_addr_in_nx_info(sk->sk_nx_info,
24180 +                               daddr, NXA_MASK_BIND))
24181 +                               return -1;
24182         }
24183  
24184         if (inet->inet_daddr) {
24185 @@ -486,6 +484,7 @@ begin:
24186         return result;
24187  }
24188  
24189 +
24190  /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
24191   * harder than this. -DaveM
24192   */
24193 @@ -532,6 +531,11 @@ begin:
24194         sk_nulls_for_each_rcu(sk, node, &hslot->head) {
24195                 score = compute_score(sk, net, saddr, hnum, sport,
24196                                       daddr, dport, dif);
24197 +               /* FIXME: disabled?
24198 +               if (score == 9) {
24199 +                       result = sk;
24200 +                       break;
24201 +               } else */
24202                 if (score > badness) {
24203                         result = sk;
24204                         badness = score;
24205 @@ -556,6 +560,7 @@ begin:
24206         if (get_nulls_value(node) != slot)
24207                 goto begin;
24208  
24209 +
24210         if (result) {
24211                 if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
24212                         result = NULL;
24213 @@ -565,6 +570,7 @@ begin:
24214                         goto begin;
24215                 }
24216         }
24217 +
24218         rcu_read_unlock();
24219         return result;
24220  }
24221 @@ -599,7 +605,7 @@ static inline bool __udp_is_mcast_sock(s
24222             udp_sk(sk)->udp_port_hash != hnum ||
24223             (inet->inet_daddr && inet->inet_daddr != rmt_addr) ||
24224             (inet->inet_dport != rmt_port && inet->inet_dport) ||
24225 -           (inet->inet_rcv_saddr && inet->inet_rcv_saddr != loc_addr) ||
24226 +           !v4_sock_addr_match(sk->sk_nx_info, inet, loc_addr) ||
24227             ipv6_only_sock(sk) ||
24228             (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
24229                 return false;
24230 @@ -1022,6 +1028,16 @@ int udp_sendmsg(struct sock *sk, struct
24231                                    inet_sk_flowi_flags(sk),
24232                                    faddr, saddr, dport, inet->inet_sport);
24233  
24234 +               if (sk->sk_nx_info) {
24235 +                       rt = ip_v4_find_src(net, sk->sk_nx_info, fl4);
24236 +                       if (IS_ERR(rt)) {
24237 +                               err = PTR_ERR(rt);
24238 +                               rt = NULL;
24239 +                               goto out;
24240 +                       }
24241 +                       ip_rt_put(rt);
24242 +               }
24243 +
24244                 security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
24245                 rt = ip_route_output_flow(net, fl4, sk);
24246                 if (IS_ERR(rt)) {
24247 @@ -1326,7 +1342,8 @@ try_again:
24248         if (sin) {
24249                 sin->sin_family = AF_INET;
24250                 sin->sin_port = udp_hdr(skb)->source;
24251 -               sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
24252 +               sin->sin_addr.s_addr = nx_map_sock_lback(
24253 +                       skb->sk->sk_nx_info, ip_hdr(skb)->saddr);
24254                 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
24255                 *addr_len = sizeof(*sin);
24256         }
24257 @@ -2308,6 +2325,8 @@ static struct sock *udp_get_first(struct
24258                 sk_nulls_for_each(sk, node, &hslot->head) {
24259                         if (!net_eq(sock_net(sk), net))
24260                                 continue;
24261 +                       if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24262 +                               continue;
24263                         if (sk->sk_family == state->family)
24264                                 goto found;
24265                 }
24266 @@ -2325,7 +2344,9 @@ static struct sock *udp_get_next(struct
24267  
24268         do {
24269                 sk = sk_nulls_next(sk);
24270 -       } while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != state->family));
24271 +       } while (sk && (!net_eq(sock_net(sk), net) ||
24272 +               sk->sk_family != state->family ||
24273 +               !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
24274  
24275         if (!sk) {
24276                 if (state->bucket <= state->udp_table->mask)
24277 @@ -2421,8 +2442,8 @@ static void udp4_format_sock(struct sock
24278                 int bucket)
24279  {
24280         struct inet_sock *inet = inet_sk(sp);
24281 -       __be32 dest = inet->inet_daddr;
24282 -       __be32 src  = inet->inet_rcv_saddr;
24283 +       __be32 dest = nx_map_sock_lback(current_nx_info(), inet->inet_daddr);
24284 +       __be32 src = nx_map_sock_lback(current_nx_info(), inet->inet_rcv_saddr);
24285         __u16 destp       = ntohs(inet->inet_dport);
24286         __u16 srcp        = ntohs(inet->inet_sport);
24287  
24288 diff -NurpP --minimal linux-4.1.41/net/ipv6/Kconfig linux-4.1.41-vs2.3.8.5.3/net/ipv6/Kconfig
24289 --- linux-4.1.41/net/ipv6/Kconfig       2015-04-12 22:12:50.000000000 +0000
24290 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/Kconfig   2016-07-05 04:41:47.000000000 +0000
24291 @@ -4,8 +4,8 @@
24292  
24293  #   IPv6 as module will cause a CRASH if you try to unload it
24294  menuconfig IPV6
24295 -       tristate "The IPv6 protocol"
24296 -       default m
24297 +       bool "The IPv6 protocol"
24298 +       default n
24299         ---help---
24300           This is complemental support for the IP version 6.
24301           You will still be able to do traditional IPv4 networking as well.
24302 diff -NurpP --minimal linux-4.1.41/net/ipv6/addrconf.c linux-4.1.41-vs2.3.8.5.3/net/ipv6/addrconf.c
24303 --- linux-4.1.41/net/ipv6/addrconf.c    2017-06-23 10:04:02.000000000 +0000
24304 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/addrconf.c        2017-06-23 10:07:02.000000000 +0000
24305 @@ -91,6 +91,8 @@
24306  #include <linux/proc_fs.h>
24307  #include <linux/seq_file.h>
24308  #include <linux/export.h>
24309 +#include <linux/vs_network.h>
24310 +#include <linux/vs_inet6.h>
24311  
24312  /* Set to 3 to get tracing... */
24313  #define ACONF_DEBUG 2
24314 @@ -1369,7 +1371,7 @@ out:
24315  
24316  int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
24317                        const struct in6_addr *daddr, unsigned int prefs,
24318 -                      struct in6_addr *saddr)
24319 +                      struct in6_addr *saddr, struct nx_info *nxi)
24320  {
24321         struct ipv6_saddr_score scores[2],
24322                                 *score = &scores[0], *hiscore = &scores[1];
24323 @@ -1439,6 +1441,8 @@ int ipv6_dev_get_saddr(struct net *net,
24324                                                     dev->name);
24325                                 continue;
24326                         }
24327 +                       if (!v6_addr_in_nx_info(nxi, &score->ifa->addr, -1))
24328 +                               continue;
24329  
24330                         score->rule = -1;
24331                         bitmap_zero(score->scorebits, IPV6_SADDR_RULE_MAX);
24332 @@ -3756,7 +3760,10 @@ static void if6_seq_stop(struct seq_file
24333  static int if6_seq_show(struct seq_file *seq, void *v)
24334  {
24335         struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
24336 -       seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
24337 +
24338 +       if (nx_check(0, VS_ADMIN|VS_WATCH) ||
24339 +           v6_addr_in_nx_info(current_nx_info(), &ifp->addr, -1))
24340 +               seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
24341                    &ifp->addr,
24342                    ifp->idev->dev->ifindex,
24343                    ifp->prefix_len,
24344 @@ -4340,6 +4347,11 @@ static int in6_dump_addrs(struct inet6_d
24345         struct ifacaddr6 *ifaca;
24346         int err = 1;
24347         int ip_idx = *p_ip_idx;
24348 +       struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
24349 +
24350 +       /* disable ipv6 on non v6 guests */
24351 +       if (nxi && !nx_info_has_v6(nxi))
24352 +               return skb->len;
24353  
24354         read_lock_bh(&idev->lock);
24355         switch (type) {
24356 @@ -4350,6 +4362,8 @@ static int in6_dump_addrs(struct inet6_d
24357                 list_for_each_entry(ifa, &idev->addr_list, if_list) {
24358                         if (++ip_idx < s_ip_idx)
24359                                 continue;
24360 +                               if (!v6_addr_in_nx_info(nxi, &ifa->addr, -1))
24361 +                                       continue;
24362                         err = inet6_fill_ifaddr(skb, ifa,
24363                                                 NETLINK_CB(cb->skb).portid,
24364                                                 cb->nlh->nlmsg_seq,
24365 @@ -4367,6 +4381,8 @@ static int in6_dump_addrs(struct inet6_d
24366                      ifmca = ifmca->next, ip_idx++) {
24367                         if (ip_idx < s_ip_idx)
24368                                 continue;
24369 +                               if (!v6_addr_in_nx_info(nxi, &ifmca->mca_addr, -1))
24370 +                                       continue;
24371                         err = inet6_fill_ifmcaddr(skb, ifmca,
24372                                                   NETLINK_CB(cb->skb).portid,
24373                                                   cb->nlh->nlmsg_seq,
24374 @@ -4382,6 +4398,8 @@ static int in6_dump_addrs(struct inet6_d
24375                      ifaca = ifaca->aca_next, ip_idx++) {
24376                         if (ip_idx < s_ip_idx)
24377                                 continue;
24378 +                               if (!v6_addr_in_nx_info(nxi, &ifaca->aca_addr, -1))
24379 +                                       continue;
24380                         err = inet6_fill_ifacaddr(skb, ifaca,
24381                                                   NETLINK_CB(cb->skb).portid,
24382                                                   cb->nlh->nlmsg_seq,
24383 @@ -4410,6 +4428,10 @@ static int inet6_dump_addr(struct sk_buf
24384         struct inet6_dev *idev;
24385         struct hlist_head *head;
24386  
24387 +       /* FIXME: maybe disable ipv6 on non v6 guests?
24388 +       if (skb->sk && skb->sk->sk_vx_info)
24389 +               return skb->len; */
24390 +
24391         s_h = cb->args[0];
24392         s_idx = idx = cb->args[1];
24393         s_ip_idx = ip_idx = cb->args[2];
24394 @@ -4901,6 +4923,7 @@ static int inet6_dump_ifinfo(struct sk_b
24395         struct net_device *dev;
24396         struct inet6_dev *idev;
24397         struct hlist_head *head;
24398 +       struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
24399  
24400         s_h = cb->args[0];
24401         s_idx = cb->args[1];
24402 @@ -4912,6 +4935,8 @@ static int inet6_dump_ifinfo(struct sk_b
24403                 hlist_for_each_entry_rcu(dev, head, index_hlist) {
24404                         if (idx < s_idx)
24405                                 goto cont;
24406 +                       if (!v6_dev_in_nx_info(dev, nxi))
24407 +                               goto cont;
24408                         idev = __in6_dev_get(dev);
24409                         if (!idev)
24410                                 goto cont;
24411 diff -NurpP --minimal linux-4.1.41/net/ipv6/af_inet6.c linux-4.1.41-vs2.3.8.5.3/net/ipv6/af_inet6.c
24412 --- linux-4.1.41/net/ipv6/af_inet6.c    2017-06-23 10:04:02.000000000 +0000
24413 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/af_inet6.c        2016-07-05 04:41:47.000000000 +0000
24414 @@ -43,6 +43,8 @@
24415  #include <linux/netdevice.h>
24416  #include <linux/icmpv6.h>
24417  #include <linux/netfilter_ipv6.h>
24418 +#include <linux/vs_inet.h>
24419 +#include <linux/vs_inet6.h>
24420  
24421  #include <net/ip.h>
24422  #include <net/ipv6.h>
24423 @@ -158,10 +160,13 @@ lookup_protocol:
24424         }
24425  
24426         err = -EPERM;
24427 +       if ((protocol == IPPROTO_ICMPV6) &&
24428 +               nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
24429 +               goto override;
24430         if (sock->type == SOCK_RAW && !kern &&
24431             !ns_capable(net->user_ns, CAP_NET_RAW))
24432                 goto out_rcu_unlock;
24433 -
24434 +override:
24435         sock->ops = answer->ops;
24436         answer_prot = answer->prot;
24437         answer_flags = answer->flags;
24438 @@ -259,6 +264,7 @@ int inet6_bind(struct socket *sock, stru
24439         struct inet_sock *inet = inet_sk(sk);
24440         struct ipv6_pinfo *np = inet6_sk(sk);
24441         struct net *net = sock_net(sk);
24442 +       struct nx_v6_sock_addr nsa;
24443         __be32 v4addr = 0;
24444         unsigned short snum;
24445         int addr_type = 0;
24446 @@ -274,6 +280,10 @@ int inet6_bind(struct socket *sock, stru
24447         if (addr->sin6_family != AF_INET6)
24448                 return -EAFNOSUPPORT;
24449  
24450 +       err = v6_map_sock_addr(inet, addr, &nsa);
24451 +       if (err)
24452 +               return err;
24453 +
24454         addr_type = ipv6_addr_type(&addr->sin6_addr);
24455         if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
24456                 return -EINVAL;
24457 @@ -314,6 +324,10 @@ int inet6_bind(struct socket *sock, stru
24458                         err = -EADDRNOTAVAIL;
24459                         goto out;
24460                 }
24461 +               if (!v4_addr_in_nx_info(sk->sk_nx_info, v4addr, NXA_MASK_BIND)) {
24462 +                       err = -EADDRNOTAVAIL;
24463 +                       goto out;
24464 +               }
24465         } else {
24466                 if (addr_type != IPV6_ADDR_ANY) {
24467                         struct net_device *dev = NULL;
24468 @@ -340,6 +354,11 @@ int inet6_bind(struct socket *sock, stru
24469                                 }
24470                         }
24471  
24472 +                       if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
24473 +                               err = -EADDRNOTAVAIL;
24474 +                               goto out_unlock;
24475 +                       }
24476 +
24477                         /* ipv4 addr of the socket is invalid.  Only the
24478                          * unspecified and mapped address have a v4 equivalent.
24479                          */
24480 @@ -356,6 +375,9 @@ int inet6_bind(struct socket *sock, stru
24481                 }
24482         }
24483  
24484 +       /* what's that for? */
24485 +       v6_set_sock_addr(inet, &nsa);
24486 +
24487         inet->inet_rcv_saddr = v4addr;
24488         inet->inet_saddr = v4addr;
24489  
24490 @@ -459,9 +481,11 @@ int inet6_getname(struct socket *sock, s
24491                         return -ENOTCONN;
24492                 sin->sin6_port = inet->inet_dport;
24493                 sin->sin6_addr = sk->sk_v6_daddr;
24494 +               /* FIXME: remap lback? */
24495                 if (np->sndflow)
24496                         sin->sin6_flowinfo = np->flow_label;
24497         } else {
24498 +               /* FIXME: remap lback? */
24499                 if (ipv6_addr_any(&sk->sk_v6_rcv_saddr))
24500                         sin->sin6_addr = np->saddr;
24501                 else
24502 diff -NurpP --minimal linux-4.1.41/net/ipv6/datagram.c linux-4.1.41-vs2.3.8.5.3/net/ipv6/datagram.c
24503 --- linux-4.1.41/net/ipv6/datagram.c    2017-06-23 10:04:02.000000000 +0000
24504 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/datagram.c        2016-07-05 04:41:47.000000000 +0000
24505 @@ -729,7 +729,7 @@ int ip6_datagram_send_ctl(struct net *ne
24506  
24507                         rcu_read_lock();
24508                         if (fl6->flowi6_oif) {
24509 -                               dev = dev_get_by_index_rcu(net, fl6->flowi6_oif);
24510 +                               dev = dev_get_by_index_real_rcu(net, fl6->flowi6_oif);
24511                                 if (!dev) {
24512                                         rcu_read_unlock();
24513                                         return -ENODEV;
24514 diff -NurpP --minimal linux-4.1.41/net/ipv6/fib6_rules.c linux-4.1.41-vs2.3.8.5.3/net/ipv6/fib6_rules.c
24515 --- linux-4.1.41/net/ipv6/fib6_rules.c  2015-07-06 20:41:43.000000000 +0000
24516 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/fib6_rules.c      2016-07-05 04:41:47.000000000 +0000
24517 @@ -97,7 +97,7 @@ static int fib6_rule_action(struct fib_r
24518                                                ip6_dst_idev(&rt->dst)->dev,
24519                                                &flp6->daddr,
24520                                                rt6_flags2srcprefs(flags),
24521 -                                              &saddr))
24522 +                                              &saddr, NULL))
24523                                 goto again;
24524                         if (!ipv6_prefix_equal(&saddr, &r->src.addr,
24525                                                r->src.plen))
24526 diff -NurpP --minimal linux-4.1.41/net/ipv6/inet6_hashtables.c linux-4.1.41-vs2.3.8.5.3/net/ipv6/inet6_hashtables.c
24527 --- linux-4.1.41/net/ipv6/inet6_hashtables.c    2015-07-06 20:41:43.000000000 +0000
24528 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/inet6_hashtables.c        2016-07-05 04:41:47.000000000 +0000
24529 @@ -16,6 +16,7 @@
24530  
24531  #include <linux/module.h>
24532  #include <linux/random.h>
24533 +#include <linux/vs_inet6.h>
24534  
24535  #include <net/inet_connection_sock.h>
24536  #include <net/inet_hashtables.h>
24537 @@ -66,7 +67,6 @@ struct sock *__inet6_lookup_established(
24538         unsigned int slot = hash & hashinfo->ehash_mask;
24539         struct inet_ehash_bucket *head = &hashinfo->ehash[slot];
24540  
24541 -
24542         rcu_read_lock();
24543  begin:
24544         sk_nulls_for_each_rcu(sk, node, &head->chain) {
24545 @@ -108,6 +108,9 @@ static inline int compute_score(struct s
24546                         if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))
24547                                 return -1;
24548                         score++;
24549 +               } else {
24550 +                       if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
24551 +                               return -1;
24552                 }
24553                 if (sk->sk_bound_dev_if) {
24554                         if (sk->sk_bound_dev_if != dif)
24555 diff -NurpP --minimal linux-4.1.41/net/ipv6/ip6_fib.c linux-4.1.41-vs2.3.8.5.3/net/ipv6/ip6_fib.c
24556 --- linux-4.1.41/net/ipv6/ip6_fib.c     2015-07-06 20:41:43.000000000 +0000
24557 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/ip6_fib.c 2016-07-05 04:41:47.000000000 +0000
24558 @@ -1888,6 +1888,7 @@ static int ipv6_route_seq_show(struct se
24559         struct rt6_info *rt = v;
24560         struct ipv6_route_iter *iter = seq->private;
24561  
24562 +       /* FIXME: check for network context? */
24563         seq_printf(seq, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen);
24564  
24565  #ifdef CONFIG_IPV6_SUBTREES
24566 diff -NurpP --minimal linux-4.1.41/net/ipv6/ip6_output.c linux-4.1.41-vs2.3.8.5.3/net/ipv6/ip6_output.c
24567 --- linux-4.1.41/net/ipv6/ip6_output.c  2017-06-23 10:04:02.000000000 +0000
24568 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/ip6_output.c      2016-07-05 04:41:47.000000000 +0000
24569 @@ -908,7 +908,8 @@ static int ip6_dst_lookup_tail(struct so
24570                 rt = (*dst)->error ? NULL : (struct rt6_info *)*dst;
24571                 err = ip6_route_get_saddr(net, rt, &fl6->daddr,
24572                                           sk ? inet6_sk(sk)->srcprefs : 0,
24573 -                                         &fl6->saddr);
24574 +                                         &fl6->saddr,
24575 +                                         sk ? sk->sk_nx_info : NULL);
24576                 if (err)
24577                         goto out_err_release;
24578  
24579 diff -NurpP --minimal linux-4.1.41/net/ipv6/ndisc.c linux-4.1.41-vs2.3.8.5.3/net/ipv6/ndisc.c
24580 --- linux-4.1.41/net/ipv6/ndisc.c       2017-06-23 10:04:03.000000000 +0000
24581 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/ndisc.c   2016-07-05 04:41:47.000000000 +0000
24582 @@ -497,7 +497,7 @@ void ndisc_send_na(struct net_device *de
24583         } else {
24584                 if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
24585                                        inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
24586 -                                      &tmpaddr))
24587 +                                      &tmpaddr, NULL))
24588                         return;
24589                 src_addr = &tmpaddr;
24590         }
24591 diff -NurpP --minimal linux-4.1.41/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c linux-4.1.41-vs2.3.8.5.3/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c
24592 --- linux-4.1.41/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c    2015-04-12 22:12:50.000000000 +0000
24593 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c        2016-07-05 04:41:47.000000000 +0000
24594 @@ -35,7 +35,7 @@ nf_nat_masquerade_ipv6(struct sk_buff *s
24595                             ctinfo == IP_CT_RELATED_REPLY));
24596  
24597         if (ipv6_dev_get_saddr(dev_net(out), out,
24598 -                              &ipv6_hdr(skb)->daddr, 0, &src) < 0)
24599 +                              &ipv6_hdr(skb)->daddr, 0, &src, NULL) < 0)
24600                 return NF_DROP;
24601  
24602         nfct_nat(ct)->masq_index = out->ifindex;
24603 diff -NurpP --minimal linux-4.1.41/net/ipv6/raw.c linux-4.1.41-vs2.3.8.5.3/net/ipv6/raw.c
24604 --- linux-4.1.41/net/ipv6/raw.c 2017-06-23 10:04:03.000000000 +0000
24605 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/raw.c     2017-06-23 10:07:02.000000000 +0000
24606 @@ -30,6 +30,7 @@
24607  #include <linux/icmpv6.h>
24608  #include <linux/netfilter.h>
24609  #include <linux/netfilter_ipv6.h>
24610 +#include <linux/vs_inet6.h>
24611  #include <linux/skbuff.h>
24612  #include <linux/compat.h>
24613  #include <linux/uaccess.h>
24614 @@ -291,6 +292,13 @@ static int rawv6_bind(struct sock *sk, s
24615                                 goto out_unlock;
24616                 }
24617  
24618 +               if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
24619 +                       err = -EADDRNOTAVAIL;
24620 +                       if (dev)
24621 +                               dev_put(dev);
24622 +                       goto out;
24623 +               }
24624 +
24625                 /* ipv4 addr of the socket is invalid.  Only the
24626                  * unspecified and mapped address have a v4 equivalent.
24627                  */
24628 diff -NurpP --minimal linux-4.1.41/net/ipv6/route.c linux-4.1.41-vs2.3.8.5.3/net/ipv6/route.c
24629 --- linux-4.1.41/net/ipv6/route.c       2017-06-23 10:04:03.000000000 +0000
24630 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/route.c   2017-06-23 10:07:02.000000000 +0000
24631 @@ -58,6 +58,7 @@
24632  #include <net/netevent.h>
24633  #include <net/netlink.h>
24634  #include <net/nexthop.h>
24635 +#include <linux/vs_inet6.h>
24636  
24637  #include <asm/uaccess.h>
24638  
24639 @@ -2266,16 +2267,18 @@ int ip6_route_get_saddr(struct net *net,
24640                         struct rt6_info *rt,
24641                         const struct in6_addr *daddr,
24642                         unsigned int prefs,
24643 -                       struct in6_addr *saddr)
24644 +                       struct in6_addr *saddr,
24645 +                       struct nx_info *nxi)
24646  {
24647         struct inet6_dev *idev =
24648                 rt ? ip6_dst_idev((struct dst_entry *)rt) : NULL;
24649         int err = 0;
24650 -       if (rt && rt->rt6i_prefsrc.plen)
24651 +       if (rt && rt->rt6i_prefsrc.plen && (!nxi ||
24652 +           v6_addr_in_nx_info(nxi, &rt->rt6i_prefsrc.addr, NXA_TYPE_ADDR)))
24653                 *saddr = rt->rt6i_prefsrc.addr;
24654         else
24655                 err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
24656 -                                        daddr, prefs, saddr);
24657 +                                        daddr, prefs, saddr, nxi);
24658         return err;
24659  }
24660  
24661 @@ -2858,7 +2861,8 @@ static int rt6_fill_node(struct net *net
24662                                 goto nla_put_failure;
24663         } else if (dst) {
24664                 struct in6_addr saddr_buf;
24665 -               if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0 &&
24666 +               if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf,
24667 +                   (skb->sk ? skb->sk->sk_nx_info : NULL)) == 0 &&
24668                     nla_put_in6_addr(skb, RTA_PREFSRC, &saddr_buf))
24669                         goto nla_put_failure;
24670         }
24671 diff -NurpP --minimal linux-4.1.41/net/ipv6/tcp_ipv6.c linux-4.1.41-vs2.3.8.5.3/net/ipv6/tcp_ipv6.c
24672 --- linux-4.1.41/net/ipv6/tcp_ipv6.c    2017-06-23 10:04:03.000000000 +0000
24673 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/tcp_ipv6.c        2016-10-25 21:31:20.000000000 +0000
24674 @@ -69,6 +69,7 @@
24675  
24676  #include <linux/crypto.h>
24677  #include <linux/scatterlist.h>
24678 +#include <linux/vs_inet6.h>
24679  
24680  static void    tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
24681  static void    tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
24682 @@ -151,7 +152,10 @@ static int tcp_v6_connect(struct sock *s
24683          */
24684  
24685         if (ipv6_addr_any(&usin->sin6_addr)) {
24686 -               if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
24687 +               if (nxi && nx_info_has_v6(nxi))
24688 +                       /* FIXME: remap lback? */
24689 +                       usin->sin6_addr = nxi->v6.ip;
24690 +               else if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
24691                         ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK),
24692                                                &usin->sin6_addr);
24693                 else
24694 diff -NurpP --minimal linux-4.1.41/net/ipv6/udp.c linux-4.1.41-vs2.3.8.5.3/net/ipv6/udp.c
24695 --- linux-4.1.41/net/ipv6/udp.c 2017-06-23 10:04:03.000000000 +0000
24696 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/udp.c     2017-05-30 07:39:23.000000000 +0000
24697 @@ -47,6 +47,7 @@
24698  #include <net/xfrm.h>
24699  #include <net/inet6_hashtables.h>
24700  #include <net/busy_poll.h>
24701 +#include <linux/vs_inet6.h>
24702  
24703  #include <linux/proc_fs.h>
24704  #include <linux/seq_file.h>
24705 @@ -76,32 +77,60 @@ static u32 udp6_ehashfn(const struct net
24706                                udp_ipv6_hash_secret + net_hash_mix(net));
24707  }
24708  
24709 -int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
24710 +int ipv6_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
24711  {
24712 +       const struct in6_addr *sk1_rcv_saddr6 = inet6_rcv_saddr(sk1);
24713         const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
24714 +       __be32 sk1_rcv_saddr = sk1->sk_rcv_saddr;
24715 +       __be32 sk2_rcv_saddr = sk2->sk_rcv_saddr;
24716         int sk2_ipv6only = inet_v6_ipv6only(sk2);
24717 -       int addr_type = ipv6_addr_type(&sk->sk_v6_rcv_saddr);
24718 +       int addr_type1 = ipv6_addr_type(sk1_rcv_saddr6);
24719         int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED;
24720  
24721         /* if both are mapped, treat as IPv4 */
24722 -       if (addr_type == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED)
24723 -               return (!sk2_ipv6only &&
24724 -                       (!sk->sk_rcv_saddr || !sk2->sk_rcv_saddr ||
24725 -                         sk->sk_rcv_saddr == sk2->sk_rcv_saddr));
24726 +       if (addr_type1 == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED) {
24727 +               if (!sk2_ipv6only &&
24728 +                       (!sk1->sk_rcv_saddr || !sk2->sk_rcv_saddr ||
24729 +                         sk1->sk_rcv_saddr == sk2->sk_rcv_saddr))
24730 +                       goto vs_v4;
24731 +               else
24732 +                       return 0;
24733 +       }
24734  
24735         if (addr_type2 == IPV6_ADDR_ANY &&
24736 -           !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED))
24737 -               return 1;
24738 +           !(sk2_ipv6only && addr_type1 == IPV6_ADDR_MAPPED))
24739 +               goto vs;
24740  
24741 -       if (addr_type == IPV6_ADDR_ANY &&
24742 -           !(ipv6_only_sock(sk) && addr_type2 == IPV6_ADDR_MAPPED))
24743 -               return 1;
24744 +       if (addr_type1 == IPV6_ADDR_ANY &&
24745 +           !(ipv6_only_sock(sk1) && addr_type2 == IPV6_ADDR_MAPPED))
24746 +               goto vs;
24747  
24748         if (sk2_rcv_saddr6 &&
24749 -           ipv6_addr_equal(&sk->sk_v6_rcv_saddr, sk2_rcv_saddr6))
24750 -               return 1;
24751 +           ipv6_addr_equal(&sk1->sk_v6_rcv_saddr, sk2_rcv_saddr6))
24752 +               goto vs;
24753  
24754         return 0;
24755 +
24756 +vs_v4:
24757 +       if (!sk1_rcv_saddr && !sk2_rcv_saddr)
24758 +               return nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24759 +       if (!sk2_rcv_saddr)
24760 +               return v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, -1);
24761 +       if (!sk1_rcv_saddr)
24762 +               return v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, -1);
24763 +       return 1;
24764 +vs:
24765 +       if (addr_type2 == IPV6_ADDR_ANY && addr_type1 == IPV6_ADDR_ANY)
24766 +               return nx_v6_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24767 +       else if (addr_type2 == IPV6_ADDR_ANY)
24768 +               return v6_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr6, -1);
24769 +       else if (addr_type1 == IPV6_ADDR_ANY) {
24770 +               if (addr_type2 == IPV6_ADDR_MAPPED)
24771 +                       return nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24772 +               else
24773 +                       return v6_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr6, -1);
24774 +       }
24775 +       return 1;
24776  }
24777  
24778  static u32 udp6_portaddr_hash(const struct net *net,
24779 @@ -162,6 +191,10 @@ static inline int compute_score(struct s
24780                 if (inet->inet_dport != sport)
24781                         return -1;
24782                 score++;
24783 +               } else {
24784 +                       /* block non nx_info ips */
24785 +                       if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
24786 +                               return -1;
24787         }
24788  
24789         if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
24790 diff -NurpP --minimal linux-4.1.41/net/ipv6/xfrm6_policy.c linux-4.1.41-vs2.3.8.5.3/net/ipv6/xfrm6_policy.c
24791 --- linux-4.1.41/net/ipv6/xfrm6_policy.c        2017-06-23 10:04:03.000000000 +0000
24792 +++ linux-4.1.41-vs2.3.8.5.3/net/ipv6/xfrm6_policy.c    2016-07-05 04:41:47.000000000 +0000
24793 @@ -61,7 +61,8 @@ static int xfrm6_get_saddr(struct net *n
24794                 return -EHOSTUNREACH;
24795  
24796         dev = ip6_dst_idev(dst)->dev;
24797 -       ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6);
24798 +       ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6,
24799 +               0, &saddr->in6, NULL);
24800         dst_release(dst);
24801         return 0;
24802  }
24803 diff -NurpP --minimal linux-4.1.41/net/netfilter/ipvs/ip_vs_xmit.c linux-4.1.41-vs2.3.8.5.3/net/netfilter/ipvs/ip_vs_xmit.c
24804 --- linux-4.1.41/net/netfilter/ipvs/ip_vs_xmit.c        2017-06-23 10:04:04.000000000 +0000
24805 +++ linux-4.1.41-vs2.3.8.5.3/net/netfilter/ipvs/ip_vs_xmit.c    2016-07-05 04:41:47.000000000 +0000
24806 @@ -377,7 +377,7 @@ __ip_vs_route_output_v6(struct net *net,
24807                 return dst;
24808         if (ipv6_addr_any(&fl6.saddr) &&
24809             ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev,
24810 -                              &fl6.daddr, 0, &fl6.saddr) < 0)
24811 +                              &fl6.daddr, 0, &fl6.saddr, NULL) < 0)
24812                 goto out_err;
24813         if (do_xfrm) {
24814                 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
24815 diff -NurpP --minimal linux-4.1.41/net/netlink/af_netlink.c linux-4.1.41-vs2.3.8.5.3/net/netlink/af_netlink.c
24816 --- linux-4.1.41/net/netlink/af_netlink.c       2017-06-23 10:04:04.000000000 +0000
24817 +++ linux-4.1.41-vs2.3.8.5.3/net/netlink/af_netlink.c   2016-10-25 21:31:20.000000000 +0000
24818 @@ -62,6 +62,8 @@
24819  #include <asm/cacheflush.h>
24820  #include <linux/hash.h>
24821  #include <linux/genetlink.h>
24822 +#include <linux/vs_context.h>
24823 +#include <linux/vs_network.h>
24824  
24825  #include <net/net_namespace.h>
24826  #include <net/sock.h>
24827 @@ -3022,7 +3024,8 @@ static void *__netlink_seq_next(struct s
24828                         if (err)
24829                                 return ERR_PTR(err);
24830                 }
24831 -       } while (sock_net(&nlk->sk) != seq_file_net(seq));
24832 +       } while ((sock_net(&nlk->sk) != seq_file_net(seq)) ||
24833 +               !nx_check(nlk->sk.sk_nid, VS_WATCH_P | VS_IDENT));
24834  
24835         return nlk;
24836  }
24837 diff -NurpP --minimal linux-4.1.41/net/socket.c linux-4.1.41-vs2.3.8.5.3/net/socket.c
24838 --- linux-4.1.41/net/socket.c   2017-06-23 10:04:05.000000000 +0000
24839 +++ linux-4.1.41-vs2.3.8.5.3/net/socket.c       2016-10-25 21:31:20.000000000 +0000
24840 @@ -99,10 +99,12 @@
24841  
24842  #include <net/sock.h>
24843  #include <linux/netfilter.h>
24844 +#include <linux/vs_socket.h>
24845 +#include <linux/vs_inet.h>
24846 +#include <linux/vs_inet6.h>
24847  
24848  #include <linux/if_tun.h>
24849  #include <linux/ipv6_route.h>
24850 -#include <linux/route.h>
24851  #include <linux/sockios.h>
24852  #include <linux/atalk.h>
24853  #include <net/busy_poll.h>
24854 @@ -610,8 +612,24 @@ EXPORT_SYMBOL(__sock_tx_timestamp);
24855  
24856  static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
24857  {
24858 -       int ret = sock->ops->sendmsg(sock, msg, msg_data_left(msg));
24859 -       BUG_ON(ret == -EIOCBQUEUED);
24860 +       size_t size = msg_data_left(msg);
24861 +       int ret = sock->ops->sendmsg(sock, msg, size);
24862 +#if 0
24863 +       if (sock->sk) {
24864 +               if (!ret)
24865 +                       vx_sock_fail(sock->sk, size);
24866 +               else
24867 +                       vx_sock_send(sock->sk, size);
24868 +       }
24869 +#endif
24870 +       vxdprintk(VXD_CBIT(net, 7),
24871 +               "sock_sendmsg_nosec: %p[%p,%p,%p;%d/%d]:%zu/%zu",
24872 +               sock, sock->sk,
24873 +               (sock->sk)?sock->sk->sk_nx_info:0,
24874 +               (sock->sk)?sock->sk->sk_vx_info:0,
24875 +               (sock->sk)?sock->sk->sk_xid:0,
24876 +               (sock->sk)?sock->sk->sk_nid:0,
24877 +               size, msg_data_left(msg));
24878         return ret;
24879  }
24880  
24881 @@ -1109,6 +1127,13 @@ int __sock_create(struct net *net, int f
24882         if (type < 0 || type >= SOCK_MAX)
24883                 return -EINVAL;
24884  
24885 +       if (!nx_check(0, VS_ADMIN)) {
24886 +               if (family == PF_INET && !current_nx_info_has_v4())
24887 +                       return -EAFNOSUPPORT;
24888 +               if (family == PF_INET6 && !current_nx_info_has_v6())
24889 +                       return -EAFNOSUPPORT;
24890 +       }
24891 +
24892         /* Compatibility.
24893  
24894            This uglymoron is moved from INET layer to here to avoid
24895 @@ -1243,6 +1268,7 @@ SYSCALL_DEFINE3(socket, int, family, int
24896         if (retval < 0)
24897                 goto out;
24898  
24899 +       set_bit(SOCK_USER_SOCKET, &sock->flags);
24900         retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
24901         if (retval < 0)
24902                 goto out_release;
24903 @@ -1284,10 +1310,12 @@ SYSCALL_DEFINE4(socketpair, int, family,
24904         err = sock_create(family, type, protocol, &sock1);
24905         if (err < 0)
24906                 goto out;
24907 +       set_bit(SOCK_USER_SOCKET, &sock1->flags);
24908  
24909         err = sock_create(family, type, protocol, &sock2);
24910         if (err < 0)
24911                 goto out_release_1;
24912 +       set_bit(SOCK_USER_SOCKET, &sock2->flags);
24913  
24914         err = sock1->ops->socketpair(sock1, sock2);
24915         if (err < 0)
24916 diff -NurpP --minimal linux-4.1.41/net/sunrpc/auth.c linux-4.1.41-vs2.3.8.5.3/net/sunrpc/auth.c
24917 --- linux-4.1.41/net/sunrpc/auth.c      2015-04-12 22:12:50.000000000 +0000
24918 +++ linux-4.1.41-vs2.3.8.5.3/net/sunrpc/auth.c  2016-07-05 04:41:47.000000000 +0000
24919 @@ -15,6 +15,7 @@
24920  #include <linux/sunrpc/clnt.h>
24921  #include <linux/sunrpc/gss_api.h>
24922  #include <linux/spinlock.h>
24923 +#include <linux/vs_tag.h>
24924  
24925  #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
24926  # define RPCDBG_FACILITY       RPCDBG_AUTH
24927 @@ -630,6 +631,7 @@ rpcauth_lookupcred(struct rpc_auth *auth
24928         memset(&acred, 0, sizeof(acred));
24929         acred.uid = cred->fsuid;
24930         acred.gid = cred->fsgid;
24931 +       acred.tag = make_ktag(&init_user_ns, dx_current_tag());
24932         acred.group_info = cred->group_info;
24933         ret = auth->au_ops->lookup_cred(auth, &acred, flags);
24934         return ret;
24935 @@ -669,6 +671,7 @@ rpcauth_bind_root_cred(struct rpc_task *
24936         struct auth_cred acred = {
24937                 .uid = GLOBAL_ROOT_UID,
24938                 .gid = GLOBAL_ROOT_GID,
24939 +               .tag = KTAGT_INIT(dx_current_tag()),
24940         };
24941  
24942         dprintk("RPC: %5u looking up %s cred\n",
24943 diff -NurpP --minimal linux-4.1.41/net/sunrpc/auth_unix.c linux-4.1.41-vs2.3.8.5.3/net/sunrpc/auth_unix.c
24944 --- linux-4.1.41/net/sunrpc/auth_unix.c 2015-04-12 22:12:50.000000000 +0000
24945 +++ linux-4.1.41-vs2.3.8.5.3/net/sunrpc/auth_unix.c     2016-07-05 04:41:47.000000000 +0000
24946 @@ -13,11 +13,13 @@
24947  #include <linux/sunrpc/clnt.h>
24948  #include <linux/sunrpc/auth.h>
24949  #include <linux/user_namespace.h>
24950 +#include <linux/vs_tag.h>
24951  
24952  #define NFS_NGROUPS    16
24953  
24954  struct unx_cred {
24955         struct rpc_cred         uc_base;
24956 +       ktag_t                  uc_tag;
24957         kgid_t                  uc_gid;
24958         kgid_t                  uc_gids[NFS_NGROUPS];
24959  };
24960 @@ -80,6 +82,7 @@ unx_create_cred(struct rpc_auth *auth, s
24961                 groups = NFS_NGROUPS;
24962  
24963         cred->uc_gid = acred->gid;
24964 +       cred->uc_tag = acred->tag;
24965         for (i = 0; i < groups; i++)
24966                 cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
24967         if (i < NFS_NGROUPS)
24968 @@ -121,7 +124,9 @@ unx_match(struct auth_cred *acred, struc
24969         unsigned int i;
24970  
24971  
24972 -       if (!uid_eq(cred->uc_uid, acred->uid) || !gid_eq(cred->uc_gid, acred->gid))
24973 +       if (!uid_eq(cred->uc_uid, acred->uid) ||
24974 +           !gid_eq(cred->uc_gid, acred->gid) ||
24975 +           !tag_eq(cred->uc_tag, acred->tag))
24976                 return 0;
24977  
24978         if (acred->group_info != NULL)
24979 @@ -146,7 +151,7 @@ unx_marshal(struct rpc_task *task, __be3
24980         struct rpc_clnt *clnt = task->tk_client;
24981         struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base);
24982         __be32          *base, *hold;
24983 -       int             i;
24984 +       int             i, tag;
24985  
24986         *p++ = htonl(RPC_AUTH_UNIX);
24987         base = p++;
24988 @@ -157,8 +162,11 @@ unx_marshal(struct rpc_task *task, __be3
24989          */
24990         p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
24991  
24992 -       *p++ = htonl((u32) from_kuid(&init_user_ns, cred->uc_uid));
24993 -       *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gid));
24994 +       tag = task->tk_client->cl_tag;
24995 +       *p++ = htonl((u32) from_kuid(&init_user_ns,
24996 +               TAGINO_KUID(tag, cred->uc_uid, cred->uc_tag)));
24997 +       *p++ = htonl((u32) from_kgid(&init_user_ns,
24998 +               TAGINO_KGID(tag, cred->uc_gid, cred->uc_tag)));
24999         hold = p++;
25000         for (i = 0; i < 16 && gid_valid(cred->uc_gids[i]); i++)
25001                 *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gids[i]));
25002 diff -NurpP --minimal linux-4.1.41/net/sunrpc/clnt.c linux-4.1.41-vs2.3.8.5.3/net/sunrpc/clnt.c
25003 --- linux-4.1.41/net/sunrpc/clnt.c      2017-06-23 10:04:05.000000000 +0000
25004 +++ linux-4.1.41-vs2.3.8.5.3/net/sunrpc/clnt.c  2017-05-30 07:39:23.000000000 +0000
25005 @@ -31,6 +31,7 @@
25006  #include <linux/in.h>
25007  #include <linux/in6.h>
25008  #include <linux/un.h>
25009 +#include <linux/vs_cvirt.h>
25010  
25011  #include <linux/sunrpc/clnt.h>
25012  #include <linux/sunrpc/addr.h>
25013 @@ -477,6 +478,9 @@ static struct rpc_clnt *rpc_create_xprt(
25014         if (!(args->flags & RPC_CLNT_CREATE_QUIET))
25015                 clnt->cl_chatty = 1;
25016  
25017 +       /* TODO: handle RPC_CLNT_CREATE_TAGGED
25018 +       if (args->flags & RPC_CLNT_CREATE_TAGGED)
25019 +               clnt->cl_tag = 1; */
25020         return clnt;
25021  }
25022  
25023 diff -NurpP --minimal linux-4.1.41/net/unix/af_unix.c linux-4.1.41-vs2.3.8.5.3/net/unix/af_unix.c
25024 --- linux-4.1.41/net/unix/af_unix.c     2017-06-23 10:04:05.000000000 +0000
25025 +++ linux-4.1.41-vs2.3.8.5.3/net/unix/af_unix.c 2016-10-25 21:31:20.000000000 +0000
25026 @@ -117,6 +117,8 @@
25027  #include <net/checksum.h>
25028  #include <linux/security.h>
25029  #include <linux/freezer.h>
25030 +#include <linux/vs_context.h>
25031 +#include <linux/vs_limit.h>
25032  
25033  struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
25034  EXPORT_SYMBOL_GPL(unix_socket_table);
25035 @@ -272,6 +274,8 @@ static struct sock *__unix_find_socket_b
25036                 if (!net_eq(sock_net(s), net))
25037                         continue;
25038  
25039 +               if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT))
25040 +                       continue;
25041                 if (u->addr->len == len &&
25042                     !memcmp(u->addr->name, sunname, len))
25043                         goto found;
25044 @@ -2455,6 +2459,8 @@ static struct sock *unix_from_bucket(str
25045         for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
25046                 if (sock_net(sk) != seq_file_net(seq))
25047                         continue;
25048 +               if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
25049 +                       continue;
25050                 if (++count == offset)
25051                         break;
25052         }
25053 @@ -2472,6 +2478,8 @@ static struct sock *unix_next_socket(str
25054                 sk = sk_next(sk);
25055                 if (!sk)
25056                         goto next_bucket;
25057 +               if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
25058 +                       continue;
25059                 if (sock_net(sk) == seq_file_net(seq))
25060                         return sk;
25061         }
25062 diff -NurpP --minimal linux-4.1.41/scripts/checksyscalls.sh linux-4.1.41-vs2.3.8.5.3/scripts/checksyscalls.sh
25063 --- linux-4.1.41/scripts/checksyscalls.sh       2015-04-12 22:12:50.000000000 +0000
25064 +++ linux-4.1.41-vs2.3.8.5.3/scripts/checksyscalls.sh   2016-07-05 04:41:47.000000000 +0000
25065 @@ -196,7 +196,6 @@ cat << EOF
25066  #define __IGNORE_afs_syscall
25067  #define __IGNORE_getpmsg
25068  #define __IGNORE_putpmsg
25069 -#define __IGNORE_vserver
25070  EOF
25071  }
25072  
25073 diff -NurpP --minimal linux-4.1.41/security/commoncap.c linux-4.1.41-vs2.3.8.5.3/security/commoncap.c
25074 --- linux-4.1.41/security/commoncap.c   2017-06-23 10:04:05.000000000 +0000
25075 +++ linux-4.1.41-vs2.3.8.5.3/security/commoncap.c       2016-07-05 04:41:47.000000000 +0000
25076 @@ -76,6 +76,7 @@ int cap_netlink_send(struct sock *sk, st
25077  int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
25078                 int cap, int audit)
25079  {
25080 +       struct vx_info *vxi = current_vx_info(); /* FIXME: get vxi from cred? */
25081         struct user_namespace *ns = targ_ns;
25082  
25083         /* See if cred has the capability in the target user namespace
25084 @@ -84,8 +85,12 @@ int cap_capable(const struct cred *cred,
25085          */
25086         for (;;) {
25087                 /* Do we have the necessary capabilities? */
25088 -               if (ns == cred->user_ns)
25089 -                       return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM;
25090 +               if (ns == cred->user_ns) {
25091 +                       if (vx_info_flags(vxi, VXF_STATE_SETUP, 0) &&
25092 +                           cap_raised(cred->cap_effective, cap))
25093 +                               return 0;
25094 +                       return vx_cap_raised(vxi, cred->cap_effective, cap) ? 0 : -EPERM;
25095 +               }
25096  
25097                 /* Have we tried all of the parent namespaces? */
25098                 if (ns == &init_user_ns)
25099 @@ -632,7 +637,7 @@ int cap_inode_setxattr(struct dentry *de
25100  
25101         if (!strncmp(name, XATTR_SECURITY_PREFIX,
25102                      sizeof(XATTR_SECURITY_PREFIX) - 1) &&
25103 -           !capable(CAP_SYS_ADMIN))
25104 +               !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY))
25105                 return -EPERM;
25106         return 0;
25107  }
25108 @@ -658,7 +663,7 @@ int cap_inode_removexattr(struct dentry
25109  
25110         if (!strncmp(name, XATTR_SECURITY_PREFIX,
25111                      sizeof(XATTR_SECURITY_PREFIX) - 1) &&
25112 -           !capable(CAP_SYS_ADMIN))
25113 +               !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY))
25114                 return -EPERM;
25115         return 0;
25116  }
25117 diff -NurpP --minimal linux-4.1.41/security/selinux/hooks.c linux-4.1.41-vs2.3.8.5.3/security/selinux/hooks.c
25118 --- linux-4.1.41/security/selinux/hooks.c       2017-06-23 10:04:05.000000000 +0000
25119 +++ linux-4.1.41-vs2.3.8.5.3/security/selinux/hooks.c   2017-05-30 07:39:23.000000000 +0000
25120 @@ -67,7 +67,6 @@
25121  #include <linux/dccp.h>
25122  #include <linux/quota.h>
25123  #include <linux/un.h>          /* for Unix socket types */
25124 -#include <net/af_unix.h>       /* for Unix socket types */
25125  #include <linux/parser.h>
25126  #include <linux/nfs_mount.h>
25127  #include <net/ipv6.h>
This page took 2.139886 seconds and 3 git commands to generate.