]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-vserver-2.3.patch
- up to 4.1.39
[packages/kernel.git] / kernel-vserver-2.3.patch
CommitLineData
f973f73f
AM
1diff -NurpP --minimal linux-4.1.27/Documentation/vserver/debug.txt linux-4.1.27-vs2.3.8.5.2/Documentation/vserver/debug.txt
2--- linux-4.1.27/Documentation/vserver/debug.txt 1970-01-01 00:00:00.000000000 +0000
3+++ linux-4.1.27-vs2.3.8.5.2/Documentation/vserver/debug.txt 2016-07-05 04:41:47.000000000 +0000
d33d7b00
AM
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"
9e3e8383
AM
38+ 1 2 "cow_break_link(?%s?)"
39+ "temp copy ?%s?"
d33d7b00
AM
40+ 2 4 "dentry_open(new): %p"
41+ "dentry_open(old): %p"
42+ "lookup_create(new): %p"
9e3e8383 43+ "old path ?%s?"
d33d7b00
AM
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+
9e3e8383 111+ 7 80 "dx_parse_tag(?%s?): %d:#%d"
d33d7b00
AM
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"
f973f73f
AM
159diff -NurpP --minimal linux-4.1.27/arch/alpha/Kconfig linux-4.1.27-vs2.3.8.5.2/arch/alpha/Kconfig
160--- linux-4.1.27/arch/alpha/Kconfig 2015-07-06 20:41:36.000000000 +0000
161+++ linux-4.1.27-vs2.3.8.5.2/arch/alpha/Kconfig 2016-07-05 04:41:47.000000000 +0000
5eef5607 162@@ -744,6 +744,8 @@ config DUMMY_CONSOLE
2380c486
JR
163 depends on VGA_HOSE
164 default y
d337f35e
JR
165
166+source "kernel/vserver/Kconfig"
167+
168 source "security/Kconfig"
169
170 source "crypto/Kconfig"
f973f73f
AM
171diff -NurpP --minimal linux-4.1.27/arch/alpha/kernel/systbls.S linux-4.1.27-vs2.3.8.5.2/arch/alpha/kernel/systbls.S
172--- linux-4.1.27/arch/alpha/kernel/systbls.S 2015-07-06 20:41:36.000000000 +0000
173+++ linux-4.1.27-vs2.3.8.5.2/arch/alpha/kernel/systbls.S 2016-07-05 04:41:47.000000000 +0000
d337f35e
JR
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 */
f973f73f
AM
183diff -NurpP --minimal linux-4.1.27/arch/alpha/kernel/traps.c linux-4.1.27-vs2.3.8.5.2/arch/alpha/kernel/traps.c
184--- linux-4.1.27/arch/alpha/kernel/traps.c 2015-07-06 20:41:36.000000000 +0000
185+++ linux-4.1.27-vs2.3.8.5.2/arch/alpha/kernel/traps.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 186@@ -174,7 +174,8 @@ die_if_kernel(char * str, struct pt_regs
d337f35e
JR
187 #ifdef CONFIG_SMP
188 printk("CPU %d ", hard_smp_processor_id());
189 #endif
2380c486 190- printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err);
61333608 191+ printk("%s(%d:#%u): %s %ld\n", current->comm,
2380c486 192+ task_pid_nr(current), current->xid, str, err);
d337f35e 193 dik_show_regs(regs, r9_15);
b00e13aa 194 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
d337f35e 195 dik_show_trace((unsigned long *)(regs+1));
f973f73f
AM
196diff -NurpP --minimal linux-4.1.27/arch/arm/Kconfig linux-4.1.27-vs2.3.8.5.2/arch/arm/Kconfig
197--- linux-4.1.27/arch/arm/Kconfig 2016-07-05 04:28:15.000000000 +0000
198+++ linux-4.1.27-vs2.3.8.5.2/arch/arm/Kconfig 2016-07-05 04:41:47.000000000 +0000
5eef5607 199@@ -2110,6 +2110,8 @@ source "fs/Kconfig"
d337f35e
JR
200
201 source "arch/arm/Kconfig.debug"
202
203+source "kernel/vserver/Kconfig"
204+
205 source "security/Kconfig"
206
207 source "crypto/Kconfig"
f973f73f
AM
208diff -NurpP --minimal linux-4.1.27/arch/arm/kernel/calls.S linux-4.1.27-vs2.3.8.5.2/arch/arm/kernel/calls.S
209--- linux-4.1.27/arch/arm/kernel/calls.S 2015-04-12 22:12:50.000000000 +0000
210+++ linux-4.1.27-vs2.3.8.5.2/arch/arm/kernel/calls.S 2016-07-05 04:41:47.000000000 +0000
d337f35e
JR
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)
f973f73f
AM
220diff -NurpP --minimal linux-4.1.27/arch/arm/kernel/traps.c linux-4.1.27-vs2.3.8.5.2/arch/arm/kernel/traps.c
221--- linux-4.1.27/arch/arm/kernel/traps.c 2015-07-06 20:41:36.000000000 +0000
222+++ linux-4.1.27-vs2.3.8.5.2/arch/arm/kernel/traps.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 223@@ -250,8 +250,8 @@ static int __die(const char *str, int er
78865d5b 224
d337f35e
JR
225 print_modules();
226 __show_regs(regs);
5eef5607
AM
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));
d337f35e
JR
231
232 if (!user_mode(regs) || in_interrupt()) {
7e46296a 233 dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
f973f73f
AM
234diff -NurpP --minimal linux-4.1.27/arch/cris/Kconfig linux-4.1.27-vs2.3.8.5.2/arch/cris/Kconfig
235--- linux-4.1.27/arch/cris/Kconfig 2015-07-06 20:41:36.000000000 +0000
236+++ linux-4.1.27-vs2.3.8.5.2/arch/cris/Kconfig 2016-07-05 04:41:47.000000000 +0000
5eef5607 237@@ -570,6 +570,8 @@ source "fs/Kconfig"
d337f35e
JR
238
239 source "arch/cris/Kconfig.debug"
240
241+source "kernel/vserver/Kconfig"
242+
243 source "security/Kconfig"
244
245 source "crypto/Kconfig"
f973f73f
AM
246diff -NurpP --minimal linux-4.1.27/arch/ia64/Kconfig linux-4.1.27-vs2.3.8.5.2/arch/ia64/Kconfig
247--- linux-4.1.27/arch/ia64/Kconfig 2015-07-06 20:41:36.000000000 +0000
248+++ linux-4.1.27-vs2.3.8.5.2/arch/ia64/Kconfig 2016-07-05 04:41:47.000000000 +0000
5eef5607 249@@ -628,6 +628,8 @@ source "fs/Kconfig"
2380c486
JR
250
251 source "arch/ia64/Kconfig.debug"
d337f35e
JR
252
253+source "kernel/vserver/Kconfig"
254+
255 source "security/Kconfig"
256
257 source "crypto/Kconfig"
f973f73f
AM
258diff -NurpP --minimal linux-4.1.27/arch/ia64/kernel/entry.S linux-4.1.27-vs2.3.8.5.2/arch/ia64/kernel/entry.S
259--- linux-4.1.27/arch/ia64/kernel/entry.S 2015-04-12 22:12:50.000000000 +0000
260+++ linux-4.1.27-vs2.3.8.5.2/arch/ia64/kernel/entry.S 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 261@@ -1706,7 +1706,7 @@ sys_call_table:
2380c486
JR
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
f973f73f
AM
270diff -NurpP --minimal linux-4.1.27/arch/ia64/kernel/ptrace.c linux-4.1.27-vs2.3.8.5.2/arch/ia64/kernel/ptrace.c
271--- linux-4.1.27/arch/ia64/kernel/ptrace.c 2015-04-12 22:12:50.000000000 +0000
272+++ linux-4.1.27-vs2.3.8.5.2/arch/ia64/kernel/ptrace.c 2016-07-05 04:41:47.000000000 +0000
78865d5b 273@@ -21,6 +21,7 @@
2380c486 274 #include <linux/regset.h>
d337f35e 275 #include <linux/elf.h>
ec22aa5c 276 #include <linux/tracehook.h>
d337f35e
JR
277+#include <linux/vs_base.h>
278
279 #include <asm/pgtable.h>
280 #include <asm/processor.h>
f973f73f
AM
281diff -NurpP --minimal linux-4.1.27/arch/ia64/kernel/traps.c linux-4.1.27-vs2.3.8.5.2/arch/ia64/kernel/traps.c
282--- linux-4.1.27/arch/ia64/kernel/traps.c 2015-04-12 22:12:50.000000000 +0000
283+++ linux-4.1.27-vs2.3.8.5.2/arch/ia64/kernel/traps.c 2016-07-05 04:41:47.000000000 +0000
1e8b8f9b 284@@ -60,8 +60,9 @@ die (const char *str, struct pt_regs *re
d337f35e
JR
285 put_cpu();
286
287 if (++die.lock_owner_depth < 3) {
288- printk("%s[%d]: %s %ld [%d]\n",
2380c486 289- current->comm, task_pid_nr(current), str, err, ++die_counter);
61333608 290+ printk("%s[%d:#%u]: %s %ld [%d]\n",
2380c486 291+ current->comm, task_pid_nr(current), current->xid,
d337f35e 292+ str, err, ++die_counter);
2380c486
JR
293 if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV)
294 != NOTIFY_STOP)
295 show_regs(regs);
1e8b8f9b 296@@ -324,8 +325,9 @@ handle_fpu_swa (int fp_fault, struct pt_
2380c486
JR
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);
61333608 302+ "%s(%d:#%u): floating-point assist fault at ip %016lx, isr %016lx\n",
2380c486
JR
303+ current->comm, task_pid_nr(current), current->xid,
304+ regs->cr_iip + ia64_psr(regs)->ri, isr);
305 }
306 }
d337f35e 307 }
f973f73f
AM
308diff -NurpP --minimal linux-4.1.27/arch/m32r/kernel/traps.c linux-4.1.27-vs2.3.8.5.2/arch/m32r/kernel/traps.c
309--- linux-4.1.27/arch/m32r/kernel/traps.c 2015-04-12 22:12:50.000000000 +0000
310+++ linux-4.1.27-vs2.3.8.5.2/arch/m32r/kernel/traps.c 2016-07-05 04:41:47.000000000 +0000
09be7631 311@@ -184,8 +184,9 @@ static void show_registers(struct pt_reg
d337f35e
JR
312 } else {
313 printk("SPI: %08lx\n", sp);
314 }
315- printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
2380c486 316- current->comm, task_pid_nr(current), 0xffff & i, 4096+(unsigned long)current);
61333608 317+ printk("Process %s (pid: %d:#%u, process nr: %d, stackpage=%08lx)",
2380c486 318+ current->comm, task_pid_nr(current), current->xid,
d337f35e
JR
319+ 0xffff & i, 4096+(unsigned long)current);
320
321 /*
322 * When in-kernel, we also print out the stack and code at the
f973f73f
AM
323diff -NurpP --minimal linux-4.1.27/arch/m68k/Kconfig linux-4.1.27-vs2.3.8.5.2/arch/m68k/Kconfig
324--- linux-4.1.27/arch/m68k/Kconfig 2015-07-06 20:41:36.000000000 +0000
325+++ linux-4.1.27-vs2.3.8.5.2/arch/m68k/Kconfig 2016-07-05 04:41:47.000000000 +0000
5eef5607 326@@ -163,6 +163,8 @@ source "fs/Kconfig"
d337f35e
JR
327
328 source "arch/m68k/Kconfig.debug"
329
330+source "kernel/vserver/Kconfig"
331+
332 source "security/Kconfig"
333
334 source "crypto/Kconfig"
f973f73f
AM
335diff -NurpP --minimal linux-4.1.27/arch/mips/Kconfig linux-4.1.27-vs2.3.8.5.2/arch/mips/Kconfig
336--- linux-4.1.27/arch/mips/Kconfig 2016-07-05 04:28:16.000000000 +0000
337+++ linux-4.1.27-vs2.3.8.5.2/arch/mips/Kconfig 2016-07-05 04:41:47.000000000 +0000
338@@ -2888,6 +2888,8 @@ source "fs/Kconfig"
d337f35e
JR
339
340 source "arch/mips/Kconfig.debug"
341
342+source "kernel/vserver/Kconfig"
343+
344 source "security/Kconfig"
345
346 source "crypto/Kconfig"
f973f73f
AM
347diff -NurpP --minimal linux-4.1.27/arch/mips/kernel/ptrace.c linux-4.1.27-vs2.3.8.5.2/arch/mips/kernel/ptrace.c
348--- linux-4.1.27/arch/mips/kernel/ptrace.c 2016-07-05 04:28:16.000000000 +0000
349+++ linux-4.1.27-vs2.3.8.5.2/arch/mips/kernel/ptrace.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 350@@ -29,6 +29,7 @@
2380c486
JR
351 #include <linux/audit.h>
352 #include <linux/seccomp.h>
c2e5f7c8 353 #include <linux/ftrace.h>
d337f35e
JR
354+#include <linux/vs_base.h>
355
356 #include <asm/byteorder.h>
357 #include <asm/cpu.h>
f973f73f 358@@ -584,6 +585,9 @@ long arch_ptrace(struct task_struct *chi
ab30d09f
AM
359 void __user *datavp = (void __user *) data;
360 unsigned long __user *datalp = (void __user *) data;
d337f35e 361
2380c486 362+ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT))
d337f35e
JR
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. */
f973f73f
AM
368diff -NurpP --minimal linux-4.1.27/arch/mips/kernel/scall32-o32.S linux-4.1.27-vs2.3.8.5.2/arch/mips/kernel/scall32-o32.S
369--- linux-4.1.27/arch/mips/kernel/scall32-o32.S 2015-04-12 22:12:50.000000000 +0000
370+++ linux-4.1.27-vs2.3.8.5.2/arch/mips/kernel/scall32-o32.S 2016-07-05 04:41:47.000000000 +0000
5eef5607 371@@ -502,7 +502,7 @@ EXPORT(sys_call_table)
c2e5f7c8
JR
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 */
f973f73f
AM
380diff -NurpP --minimal linux-4.1.27/arch/mips/kernel/scall64-64.S linux-4.1.27-vs2.3.8.5.2/arch/mips/kernel/scall64-64.S
381--- linux-4.1.27/arch/mips/kernel/scall64-64.S 2016-07-05 04:28:16.000000000 +0000
382+++ linux-4.1.27-vs2.3.8.5.2/arch/mips/kernel/scall64-64.S 2016-07-05 04:41:47.000000000 +0000
bb20add7 383@@ -355,7 +355,7 @@ EXPORT(sys_call_table)
d337f35e
JR
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
f973f73f
AM
392diff -NurpP --minimal linux-4.1.27/arch/mips/kernel/scall64-n32.S linux-4.1.27-vs2.3.8.5.2/arch/mips/kernel/scall64-n32.S
393--- linux-4.1.27/arch/mips/kernel/scall64-n32.S 2016-07-05 04:28:16.000000000 +0000
394+++ linux-4.1.27-vs2.3.8.5.2/arch/mips/kernel/scall64-n32.S 2016-07-05 04:41:47.000000000 +0000
bb20add7 395@@ -348,7 +348,7 @@ EXPORT(sysn32_call_table)
d337f35e
JR
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 */
2380c486 401 PTR compat_sys_waitid
d337f35e
JR
402 PTR sys_ni_syscall /* available, was setaltroot */
403 PTR sys_add_key
f973f73f
AM
404diff -NurpP --minimal linux-4.1.27/arch/mips/kernel/scall64-o32.S linux-4.1.27-vs2.3.8.5.2/arch/mips/kernel/scall64-o32.S
405--- linux-4.1.27/arch/mips/kernel/scall64-o32.S 2015-04-12 22:12:50.000000000 +0000
406+++ linux-4.1.27-vs2.3.8.5.2/arch/mips/kernel/scall64-o32.S 2016-07-05 04:41:47.000000000 +0000
5eef5607 407@@ -487,7 +487,7 @@ EXPORT(sys32_call_table)
d337f35e
JR
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
b00e13aa 413 PTR compat_sys_waitid
d337f35e
JR
414 PTR sys_ni_syscall /* available, was setaltroot */
415 PTR sys_add_key /* 4280 */
f973f73f
AM
416diff -NurpP --minimal linux-4.1.27/arch/mips/kernel/traps.c linux-4.1.27-vs2.3.8.5.2/arch/mips/kernel/traps.c
417--- linux-4.1.27/arch/mips/kernel/traps.c 2016-07-05 04:28:16.000000000 +0000
418+++ linux-4.1.27-vs2.3.8.5.2/arch/mips/kernel/traps.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 419@@ -349,9 +349,10 @@ void show_registers(struct pt_regs *regs
2380c486
JR
420
421 __show_regs(regs);
d337f35e 422 print_modules();
2380c486
JR
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
f973f73f
AM
433diff -NurpP --minimal linux-4.1.27/arch/parisc/Kconfig linux-4.1.27-vs2.3.8.5.2/arch/parisc/Kconfig
434--- linux-4.1.27/arch/parisc/Kconfig 2015-07-06 20:41:37.000000000 +0000
435+++ linux-4.1.27-vs2.3.8.5.2/arch/parisc/Kconfig 2016-07-05 04:41:47.000000000 +0000
5eef5607 436@@ -338,6 +338,8 @@ config SECCOMP
d337f35e 437
bb20add7 438 If unsure, say Y. Only embedded should say N here.
d337f35e
JR
439
440+source "kernel/vserver/Kconfig"
441+
442 source "security/Kconfig"
443
444 source "crypto/Kconfig"
f973f73f
AM
445diff -NurpP --minimal linux-4.1.27/arch/parisc/kernel/syscall_table.S linux-4.1.27-vs2.3.8.5.2/arch/parisc/kernel/syscall_table.S
446--- linux-4.1.27/arch/parisc/kernel/syscall_table.S 2015-04-12 22:12:50.000000000 +0000
447+++ linux-4.1.27-vs2.3.8.5.2/arch/parisc/kernel/syscall_table.S 2016-07-05 04:41:47.000000000 +0000
b00e13aa 448@@ -358,7 +358,7 @@
d337f35e
JR
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)
f973f73f
AM
457diff -NurpP --minimal linux-4.1.27/arch/parisc/kernel/traps.c linux-4.1.27-vs2.3.8.5.2/arch/parisc/kernel/traps.c
458--- linux-4.1.27/arch/parisc/kernel/traps.c 2016-07-05 04:28:16.000000000 +0000
459+++ linux-4.1.27-vs2.3.8.5.2/arch/parisc/kernel/traps.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 460@@ -235,8 +235,9 @@ void die_if_kernel(char *str, struct pt_
d337f35e
JR
461 return; /* STFU */
462
98968f7b
JR
463 parisc_printk_ratelimited(1, regs,
464- KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
2380c486 465- current->comm, task_pid_nr(current), str, err, regs->iaoq[0]);
98968f7b 466+ KERN_CRIT "%s (pid %d:#%u): %s (code %ld) at " RFMT "\n",
2380c486 467+ current->comm, task_pid_nr(current), current->xid,
d337f35e 468+ str, err, regs->iaoq[0]);
98968f7b
JR
469
470 return;
471 }
5eef5607 472@@ -266,8 +267,8 @@ void die_if_kernel(char *str, struct pt_
d337f35e
JR
473 pdc_console_restart();
474
2380c486
JR
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) {
f973f73f
AM
483diff -NurpP --minimal linux-4.1.27/arch/powerpc/Kconfig linux-4.1.27-vs2.3.8.5.2/arch/powerpc/Kconfig
484--- linux-4.1.27/arch/powerpc/Kconfig 2015-07-06 20:41:37.000000000 +0000
485+++ linux-4.1.27-vs2.3.8.5.2/arch/powerpc/Kconfig 2016-07-05 04:41:47.000000000 +0000
5eef5607 486@@ -1077,6 +1077,8 @@ source "lib/Kconfig"
d33d7b00
AM
487
488 source "arch/powerpc/Kconfig.debug"
489
490+source "kernel/vserver/Kconfig"
491+
492 source "security/Kconfig"
493
494 config KEYS_COMPAT
f973f73f
AM
495diff -NurpP --minimal linux-4.1.27/arch/powerpc/include/uapi/asm/unistd.h linux-4.1.27-vs2.3.8.5.2/arch/powerpc/include/uapi/asm/unistd.h
496--- linux-4.1.27/arch/powerpc/include/uapi/asm/unistd.h 2015-07-06 20:41:37.000000000 +0000
497+++ linux-4.1.27-vs2.3.8.5.2/arch/powerpc/include/uapi/asm/unistd.h 2016-07-05 04:41:47.000000000 +0000
adc1caaa
AM
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
f973f73f
AM
507diff -NurpP --minimal linux-4.1.27/arch/powerpc/kernel/traps.c linux-4.1.27-vs2.3.8.5.2/arch/powerpc/kernel/traps.c
508--- linux-4.1.27/arch/powerpc/kernel/traps.c 2015-04-12 22:12:50.000000000 +0000
509+++ linux-4.1.27-vs2.3.8.5.2/arch/powerpc/kernel/traps.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 510@@ -1313,8 +1313,9 @@ void nonrecoverable_exception(struct pt_
d337f35e
JR
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",
2380c486 515- current, task_pid_nr(current), regs->nip, regs->link, regs->gpr[0],
61333608 516+ printk("Task: %p(%d:#%u), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
2380c486 517+ current, task_pid_nr(current), current->xid,
d337f35e
JR
518+ regs->nip, regs->link, regs->gpr[0],
519 regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
520 }
521
f973f73f
AM
522diff -NurpP --minimal linux-4.1.27/arch/s390/Kconfig linux-4.1.27-vs2.3.8.5.2/arch/s390/Kconfig
523--- linux-4.1.27/arch/s390/Kconfig 2015-07-06 20:41:37.000000000 +0000
524+++ linux-4.1.27-vs2.3.8.5.2/arch/s390/Kconfig 2016-07-05 04:41:47.000000000 +0000
5eef5607 525@@ -653,6 +653,8 @@ source "fs/Kconfig"
d33d7b00
AM
526
527 source "arch/s390/Kconfig.debug"
528
529+source "kernel/vserver/Kconfig"
530+
531 source "security/Kconfig"
0411181d 532
d33d7b00 533 source "crypto/Kconfig"
f973f73f
AM
534diff -NurpP --minimal linux-4.1.27/arch/s390/include/asm/tlb.h linux-4.1.27-vs2.3.8.5.2/arch/s390/include/asm/tlb.h
535--- linux-4.1.27/arch/s390/include/asm/tlb.h 2015-07-06 20:41:37.000000000 +0000
536+++ linux-4.1.27-vs2.3.8.5.2/arch/s390/include/asm/tlb.h 2016-07-05 04:41:47.000000000 +0000
dd5f3080 537@@ -24,6 +24,7 @@
0411181d 538 #include <linux/mm.h>
d33d7b00 539 #include <linux/pagemap.h>
0411181d 540 #include <linux/swap.h>
0411181d
AM
541+
542 #include <asm/processor.h>
543 #include <asm/pgalloc.h>
763640ca 544 #include <asm/tlbflush.h>
f973f73f
AM
545diff -NurpP --minimal linux-4.1.27/arch/s390/include/uapi/asm/unistd.h linux-4.1.27-vs2.3.8.5.2/arch/s390/include/uapi/asm/unistd.h
546--- linux-4.1.27/arch/s390/include/uapi/asm/unistd.h 2015-04-12 22:12:50.000000000 +0000
547+++ linux-4.1.27-vs2.3.8.5.2/arch/s390/include/uapi/asm/unistd.h 2016-07-05 04:41:47.000000000 +0000
92598135 548@@ -200,7 +200,7 @@
0411181d
AM
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
f973f73f
AM
557diff -NurpP --minimal linux-4.1.27/arch/s390/kernel/ptrace.c linux-4.1.27-vs2.3.8.5.2/arch/s390/kernel/ptrace.c
558--- linux-4.1.27/arch/s390/kernel/ptrace.c 2015-07-06 20:41:37.000000000 +0000
559+++ linux-4.1.27-vs2.3.8.5.2/arch/s390/kernel/ptrace.c 2016-07-05 04:41:47.000000000 +0000
db55b927 560@@ -21,6 +21,7 @@
ec22aa5c
AM
561 #include <linux/tracehook.h>
562 #include <linux/seccomp.h>
969f5c41 563 #include <linux/compat.h>
db55b927 564+#include <linux/vs_base.h>
ec22aa5c 565 #include <trace/syscall.h>
d337f35e 566 #include <asm/segment.h>
db55b927 567 #include <asm/page.h>
f973f73f
AM
568diff -NurpP --minimal linux-4.1.27/arch/s390/kernel/syscalls.S linux-4.1.27-vs2.3.8.5.2/arch/s390/kernel/syscalls.S
569--- linux-4.1.27/arch/s390/kernel/syscalls.S 2015-07-06 20:41:37.000000000 +0000
570+++ linux-4.1.27-vs2.3.8.5.2/arch/s390/kernel/syscalls.S 2016-07-05 04:41:47.000000000 +0000
5eef5607
AM
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 */
d337f35e 576+SYSCALL(sys_vserver,sys_vserver,sys32_vserver)
5eef5607
AM
577 SYSCALL(sys_ni_syscall,compat_sys_s390_fadvise64_64)
578 SYSCALL(sys_statfs64,compat_sys_statfs64)
579 SYSCALL(sys_fstatfs64,compat_sys_fstatfs64)
f973f73f
AM
580diff -NurpP --minimal linux-4.1.27/arch/sh/Kconfig linux-4.1.27-vs2.3.8.5.2/arch/sh/Kconfig
581--- linux-4.1.27/arch/sh/Kconfig 2015-07-06 20:41:37.000000000 +0000
582+++ linux-4.1.27-vs2.3.8.5.2/arch/sh/Kconfig 2016-07-05 04:41:47.000000000 +0000
5eef5607 583@@ -882,6 +882,8 @@ source "fs/Kconfig"
d337f35e
JR
584
585 source "arch/sh/Kconfig.debug"
586
587+source "kernel/vserver/Kconfig"
588+
589 source "security/Kconfig"
590
591 source "crypto/Kconfig"
f973f73f
AM
592diff -NurpP --minimal linux-4.1.27/arch/sh/kernel/irq.c linux-4.1.27-vs2.3.8.5.2/arch/sh/kernel/irq.c
593--- linux-4.1.27/arch/sh/kernel/irq.c 2015-07-06 20:41:37.000000000 +0000
594+++ linux-4.1.27-vs2.3.8.5.2/arch/sh/kernel/irq.c 2016-07-05 04:41:47.000000000 +0000
f86f0b53 595@@ -14,6 +14,7 @@
7e46296a 596 #include <linux/ftrace.h>
76514441 597 #include <linux/delay.h>
763640ca 598 #include <linux/ratelimit.h>
f86f0b53 599+// #include <linux/vs_context.h>
d337f35e 600 #include <asm/processor.h>
2380c486 601 #include <asm/machvec.h>
f86f0b53 602 #include <asm/uaccess.h>
f973f73f
AM
603diff -NurpP --minimal linux-4.1.27/arch/sparc/Kconfig linux-4.1.27-vs2.3.8.5.2/arch/sparc/Kconfig
604--- linux-4.1.27/arch/sparc/Kconfig 2015-07-06 20:41:37.000000000 +0000
605+++ linux-4.1.27-vs2.3.8.5.2/arch/sparc/Kconfig 2016-07-05 04:41:47.000000000 +0000
5eef5607 606@@ -564,6 +564,8 @@ source "fs/Kconfig"
d33d7b00
AM
607
608 source "arch/sparc/Kconfig.debug"
609
610+source "kernel/vserver/Kconfig"
611+
612 source "security/Kconfig"
613
614 source "crypto/Kconfig"
f973f73f
AM
615diff -NurpP --minimal linux-4.1.27/arch/sparc/include/uapi/asm/unistd.h linux-4.1.27-vs2.3.8.5.2/arch/sparc/include/uapi/asm/unistd.h
616--- linux-4.1.27/arch/sparc/include/uapi/asm/unistd.h 2015-04-12 22:12:50.000000000 +0000
617+++ linux-4.1.27-vs2.3.8.5.2/arch/sparc/include/uapi/asm/unistd.h 2016-07-05 04:41:47.000000000 +0000
537831f9 618@@ -332,7 +332,7 @@
ec22aa5c
AM
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
f973f73f
AM
627diff -NurpP --minimal linux-4.1.27/arch/sparc/kernel/systbls_32.S linux-4.1.27-vs2.3.8.5.2/arch/sparc/kernel/systbls_32.S
628--- linux-4.1.27/arch/sparc/kernel/systbls_32.S 2015-04-12 22:12:50.000000000 +0000
629+++ linux-4.1.27-vs2.3.8.5.2/arch/sparc/kernel/systbls_32.S 2016-07-05 04:41:47.000000000 +0000
50e68740 630@@ -70,7 +70,7 @@ sys_call_table:
a168f21d 631 /*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_ni_syscall
50e68740
JR
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
f973f73f
AM
639diff -NurpP --minimal linux-4.1.27/arch/sparc/kernel/systbls_64.S linux-4.1.27-vs2.3.8.5.2/arch/sparc/kernel/systbls_64.S
640--- linux-4.1.27/arch/sparc/kernel/systbls_64.S 2015-04-12 22:12:50.000000000 +0000
641+++ linux-4.1.27-vs2.3.8.5.2/arch/sparc/kernel/systbls_64.S 2016-07-05 04:41:47.000000000 +0000
50e68740 642@@ -71,7 +71,7 @@ sys_call_table32:
b00e13aa 643 /*250*/ .word sys_mremap, compat_sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall
50e68740
JR
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
b00e13aa 650 /*280*/ .word sys_tee, sys_add_key, sys_request_key, compat_sys_keyctl, compat_sys_openat
5eef5607 651@@ -151,7 +151,7 @@ sys_call_table:
a168f21d 652 /*250*/ .word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall
50e68740
JR
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
f973f73f
AM
660diff -NurpP --minimal linux-4.1.27/arch/um/Kconfig.rest linux-4.1.27-vs2.3.8.5.2/arch/um/Kconfig.rest
661--- linux-4.1.27/arch/um/Kconfig.rest 2015-04-12 22:12:50.000000000 +0000
662+++ linux-4.1.27-vs2.3.8.5.2/arch/um/Kconfig.rest 2016-07-05 04:41:47.000000000 +0000
f6c5ef8b 663@@ -12,6 +12,8 @@ source "arch/um/Kconfig.net"
d33d7b00
AM
664
665 source "fs/Kconfig"
666
667+source "kernel/vserver/Kconfig"
668+
669 source "security/Kconfig"
670
671 source "crypto/Kconfig"
f973f73f
AM
672diff -NurpP --minimal linux-4.1.27/arch/x86/Kconfig linux-4.1.27-vs2.3.8.5.2/arch/x86/Kconfig
673--- linux-4.1.27/arch/x86/Kconfig 2015-07-06 20:41:37.000000000 +0000
674+++ linux-4.1.27-vs2.3.8.5.2/arch/x86/Kconfig 2016-07-05 04:41:47.000000000 +0000
5eef5607 675@@ -2587,6 +2587,8 @@ source "fs/Kconfig"
e03b8c3c 676
d33d7b00 677 source "arch/x86/Kconfig.debug"
e03b8c3c
AM
678
679+source "kernel/vserver/Kconfig"
680+
681 source "security/Kconfig"
682
683 source "crypto/Kconfig"
f973f73f
AM
684diff -NurpP --minimal linux-4.1.27/arch/x86/syscalls/syscall_32.tbl linux-4.1.27-vs2.3.8.5.2/arch/x86/syscalls/syscall_32.tbl
685--- linux-4.1.27/arch/x86/syscalls/syscall_32.tbl 2015-07-06 20:41:37.000000000 +0000
686+++ linux-4.1.27-vs2.3.8.5.2/arch/x86/syscalls/syscall_32.tbl 2016-07-05 04:41:47.000000000 +0000
db55b927
AM
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
f973f73f
AM
696diff -NurpP --minimal linux-4.1.27/arch/x86/syscalls/syscall_64.tbl linux-4.1.27-vs2.3.8.5.2/arch/x86/syscalls/syscall_64.tbl
697--- linux-4.1.27/arch/x86/syscalls/syscall_64.tbl 2015-07-06 20:41:37.000000000 +0000
698+++ linux-4.1.27-vs2.3.8.5.2/arch/x86/syscalls/syscall_64.tbl 2016-07-05 04:41:47.000000000 +0000
db55b927 699@@ -242,7 +242,7 @@
1e8b8f9b
AM
700 233 common epoll_ctl sys_epoll_ctl
701 234 common tgkill sys_tgkill
702 235 common utimes sys_utimes
db55b927
AM
703-236 64 vserver
704+236 64 vserver sys_vserver
1e8b8f9b
AM
705 237 common mbind sys_mbind
706 238 common set_mempolicy sys_set_mempolicy
707 239 common get_mempolicy sys_get_mempolicy
f973f73f
AM
708diff -NurpP --minimal linux-4.1.27/block/ioprio.c linux-4.1.27-vs2.3.8.5.2/block/ioprio.c
709--- linux-4.1.27/block/ioprio.c 2015-04-12 22:12:50.000000000 +0000
710+++ linux-4.1.27-vs2.3.8.5.2/block/ioprio.c 2016-07-05 04:41:47.000000000 +0000
bb20add7
AM
711@@ -28,6 +28,7 @@
712 #include <linux/syscalls.h>
713 #include <linux/security.h>
714 #include <linux/pid_namespace.h>
715+#include <linux/vs_base.h>
716
717 int set_task_ioprio(struct task_struct *task, int ioprio)
718 {
719@@ -105,6 +106,8 @@ SYSCALL_DEFINE3(ioprio_set, int, which,
720 else
721 pgrp = find_vpid(who);
722 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
723+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
724+ continue;
725 ret = set_task_ioprio(p, ioprio);
726 if (ret)
727 break;
728@@ -200,6 +203,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which,
729 else
730 pgrp = find_vpid(who);
731 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
732+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
733+ continue;
734 tmpio = get_task_ioprio(p);
735 if (tmpio < 0)
736 continue;
f973f73f
AM
737diff -NurpP --minimal linux-4.1.27/drivers/block/Kconfig linux-4.1.27-vs2.3.8.5.2/drivers/block/Kconfig
738--- linux-4.1.27/drivers/block/Kconfig 2015-07-06 20:41:37.000000000 +0000
739+++ linux-4.1.27-vs2.3.8.5.2/drivers/block/Kconfig 2016-07-05 04:41:47.000000000 +0000
bb20add7 740@@ -283,6 +283,13 @@ config BLK_DEV_CRYPTOLOOP
2bf5ad28
AM
741
742 source "drivers/block/drbd/Kconfig"
d337f35e
JR
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
f973f73f
AM
754diff -NurpP --minimal linux-4.1.27/drivers/block/Makefile linux-4.1.27-vs2.3.8.5.2/drivers/block/Makefile
755--- linux-4.1.27/drivers/block/Makefile 2015-07-06 20:41:37.000000000 +0000
756+++ linux-4.1.27-vs2.3.8.5.2/drivers/block/Makefile 2016-07-05 04:41:47.000000000 +0000
5eef5607 757@@ -34,6 +34,7 @@ obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o
bb20add7 758
d33d7b00 759 obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
d33d7b00
AM
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
763640ca 764 obj-$(CONFIG_XEN_BLKDEV_BACKEND) += xen-blkback/
f973f73f
AM
765diff -NurpP --minimal linux-4.1.27/drivers/block/loop.c linux-4.1.27-vs2.3.8.5.2/drivers/block/loop.c
766--- linux-4.1.27/drivers/block/loop.c 2016-07-05 04:28:18.000000000 +0000
767+++ linux-4.1.27-vs2.3.8.5.2/drivers/block/loop.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 768@@ -76,6 +76,7 @@
a168f21d 769 #include <linux/miscdevice.h>
f6c5ef8b 770 #include <linux/falloc.h>
5eef5607 771 #include <linux/uio.h>
d337f35e 772+#include <linux/vs_context.h>
c2e5f7c8 773 #include "loop.h"
f6c5ef8b 774
d337f35e 775 #include <asm/uaccess.h>
5eef5607 776@@ -737,6 +738,7 @@ static int loop_set_fd(struct loop_devic
d337f35e
JR
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;
5eef5607 782 lo->transfer = NULL;
d337f35e 783 lo->ioctl = NULL;
5eef5607
AM
784@@ -853,6 +855,7 @@ static int loop_clr_fd(struct loop_devic
785 lo->lo_offset = 0;
f6c5ef8b 786 lo->lo_sizelimit = 0;
2380c486 787 lo->lo_encrypt_key_size = 0;
2380c486
JR
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);
5eef5607 792@@ -898,7 +901,7 @@ loop_set_status(struct loop_device *lo,
2380c486 793
ec22aa5c 794 if (lo->lo_encrypt_key_size &&
537831f9 795 !uid_eq(lo->lo_key_owner, uid) &&
d337f35e
JR
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;
5eef5607 801@@ -988,7 +991,8 @@ loop_get_status(struct loop_device *lo,
d337f35e
JR
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);
5eef5607 811@@ -1330,6 +1334,11 @@ static int lo_open(struct block_device *
a168f21d
AM
812 goto out;
813 }
d337f35e 814
dd5f3080 815+ if (!vx_check(lo->lo_xid, VS_IDENT|VS_HOSTID|VS_ADMIN_P)) {
816+ err = -EACCES;
817+ goto out;
818+ }
d337f35e
JR
819+
820 mutex_lock(&lo->lo_ctl_mutex);
821 lo->lo_refcnt++;
2386b7a8 822 mutex_unlock(&lo->lo_ctl_mutex);
f973f73f
AM
823diff -NurpP --minimal linux-4.1.27/drivers/block/loop.h linux-4.1.27-vs2.3.8.5.2/drivers/block/loop.h
824--- linux-4.1.27/drivers/block/loop.h 2016-07-05 04:28:18.000000000 +0000
825+++ linux-4.1.27-vs2.3.8.5.2/drivers/block/loop.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 826@@ -43,6 +43,7 @@ struct loop_device {
c2e5f7c8
JR
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
f973f73f
AM
834diff -NurpP --minimal linux-4.1.27/drivers/block/vroot.c linux-4.1.27-vs2.3.8.5.2/drivers/block/vroot.c
835--- linux-4.1.27/drivers/block/vroot.c 1970-01-01 00:00:00.000000000 +0000
836+++ linux-4.1.27-vs2.3.8.5.2/drivers/block/vroot.c 2016-07-05 04:41:47.000000000 +0000
09be7631 837@@ -0,0 +1,290 @@
d337f35e
JR
838+/*
839+ * linux/drivers/block/vroot.c
840+ *
9e3e8383
AM
841+ * written by Herbert P?tzl, 9/11/2002
842+ * ported to 2.6.10 by Herbert P?tzl, 30/12/2004
d337f35e
JR
843+ *
844+ * based on the loop.c code by Theodore Ts'o.
845+ *
9e3e8383 846+ * Copyright (C) 2002-2007 by Herbert P?tzl.
d337f35e
JR
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>
76514441 857+#include <linux/slab.h>
d337f35e
JR
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,
d337f35e
JR
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;
5eef5607 889+ inode = file->f_path.dentry->d_inode;
d337f35e
JR
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,
d337f35e
JR
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+
ec22aa5c 936+static int vr_ioctl(struct block_device *bdev, fmode_t mode,
d337f35e
JR
937+ unsigned int cmd, unsigned long arg)
938+{
ec22aa5c 939+ struct vroot_device *vr = bdev->bd_disk->private_data;
d337f35e
JR
940+ int err;
941+
942+ down(&vr->vr_ctl_mutex);
943+ switch (cmd) {
944+ case VROOT_SET_DEV:
ec22aa5c 945+ err = vroot_set_dev(vr, bdev, arg);
d337f35e
JR
946+ break;
947+ case VROOT_CLR_DEV:
ec22aa5c 948+ err = vroot_clr_dev(vr, bdev);
d337f35e
JR
949+ break;
950+ default:
951+ err = -EINVAL;
952+ break;
953+ }
954+ up(&vr->vr_ctl_mutex);
955+ return err;
956+}
957+
ec22aa5c 958+static int vr_open(struct block_device *bdev, fmode_t mode)
d337f35e 959+{
ec22aa5c 960+ struct vroot_device *vr = bdev->bd_disk->private_data;
d337f35e
JR
961+
962+ down(&vr->vr_ctl_mutex);
963+ vr->vr_refcnt++;
964+ up(&vr->vr_ctl_mutex);
965+ return 0;
966+}
967+
09be7631 968+static void vr_release(struct gendisk *disk, fmode_t mode)
d337f35e 969+{
ec22aa5c 970+ struct vroot_device *vr = disk->private_data;
d337f35e
JR
971+
972+ down(&vr->vr_ctl_mutex);
973+ --vr->vr_refcnt;
974+ up(&vr->vr_ctl_mutex);
d337f35e
JR
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+
f6c5ef8b 984+static void vroot_make_request(struct request_queue *q, struct bio *bio)
b3b0d4fd
AM
985+{
986+ printk("vroot_make_request %p, %p\n", q, bio);
987+ bio_io_error(bio);
b3b0d4fd
AM
988+}
989+
d337f35e
JR
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+
b3b0d4fd
AM
1011+
1012+
d337f35e
JR
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+
9e3e8383 1023+MODULE_AUTHOR ("Herbert P?tzl");
d337f35e
JR
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;
2380c486
JR
1055+ disks[i]->queue = blk_alloc_queue(GFP_KERNEL);
1056+ if (!disks[i]->queue)
1057+ goto out_mem3;
b3b0d4fd 1058+ blk_queue_make_request(disks[i]->queue, vroot_make_request);
d337f35e
JR
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));
5a9fc8e8 1066+ sema_init(&vr->vr_ctl_mutex, 1);
d337f35e
JR
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+ }
2380c486 1107+ unregister_blkdev(VROOT_MAJOR, "vroot");
d337f35e
JR
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+
f973f73f
AM
1128diff -NurpP --minimal linux-4.1.27/drivers/infiniband/core/addr.c linux-4.1.27-vs2.3.8.5.2/drivers/infiniband/core/addr.c
1129--- linux-4.1.27/drivers/infiniband/core/addr.c 2015-07-06 20:41:38.000000000 +0000
1130+++ linux-4.1.27-vs2.3.8.5.2/drivers/infiniband/core/addr.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 1131@@ -284,7 +284,7 @@ static int addr6_resolve(struct sockaddr
5dd10c98 1132
763640ca 1133 if (ipv6_addr_any(&fl6.saddr)) {
5dd10c98 1134 ret = ipv6_dev_get_saddr(&init_net, ip6_dst_idev(dst)->dev,
763640ca
JR
1135- &fl6.daddr, 0, &fl6.saddr);
1136+ &fl6.daddr, 0, &fl6.saddr, NULL);
5dd10c98
AM
1137 if (ret)
1138 goto put;
1139
f973f73f
AM
1140diff -NurpP --minimal linux-4.1.27/drivers/md/dm-ioctl.c linux-4.1.27-vs2.3.8.5.2/drivers/md/dm-ioctl.c
1141--- linux-4.1.27/drivers/md/dm-ioctl.c 2015-07-06 20:41:38.000000000 +0000
1142+++ linux-4.1.27-vs2.3.8.5.2/drivers/md/dm-ioctl.c 2016-07-05 04:41:47.000000000 +0000
3bac966d
AM
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
c2e5f7c8 1151@@ -114,7 +115,8 @@ static struct hash_cell *__get_name_cell
3bac966d
AM
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 }
c2e5f7c8 1161@@ -128,7 +130,8 @@ static struct hash_cell *__get_uuid_cell
3bac966d
AM
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 }
c2e5f7c8 1171@@ -139,13 +142,15 @@ static struct hash_cell *__get_uuid_cell
a168f21d
AM
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;
c2e5f7c8 1189@@ -467,6 +472,9 @@ typedef int (*ioctl_fn)(struct dm_ioctl
3bac966d
AM
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+
c2e5f7c8 1196 dm_hash_remove_all(true, !!(param->flags & DM_DEFERRED_REMOVE), false);
3bac966d
AM
1197 param->data_size = 0;
1198 return 0;
c2e5f7c8 1199@@ -514,6 +522,8 @@ static int list_devices(struct dm_ioctl
3bac966d
AM
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;
c2e5f7c8 1208@@ -537,6 +547,8 @@ static int list_devices(struct dm_ioctl
3bac966d
AM
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);
5eef5607 1217@@ -1801,8 +1813,8 @@ static int ctl_ioctl(uint command, struc
763640ca 1218 size_t input_param_size;
b00e13aa 1219 struct dm_ioctl param_kernel;
3bac966d
AM
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)
f973f73f
AM
1228diff -NurpP --minimal linux-4.1.27/drivers/md/dm.c linux-4.1.27-vs2.3.8.5.2/drivers/md/dm.c
1229--- linux-4.1.27/drivers/md/dm.c 2016-07-05 04:28:21.000000000 +0000
1230+++ linux-4.1.27-vs2.3.8.5.2/drivers/md/dm.c 2016-07-05 04:41:47.000000000 +0000
5eef5607
AM
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>
d33d7b00
AM
1235+#include <linux/vs_base.h>
1236
1237 #include <trace/events/block.h>
1238
5eef5607 1239@@ -141,6 +142,7 @@ struct mapped_device {
c2e5f7c8 1240 struct mutex suspend_lock;
d33d7b00
AM
1241 atomic_t holders;
1242 atomic_t open_count;
61333608 1243+ vxid_t xid;
d33d7b00 1244
c2e5f7c8
JR
1245 /*
1246 * The current mapping.
5eef5607 1247@@ -442,6 +444,7 @@ int dm_deleting_md(struct mapped_device
d33d7b00
AM
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
5eef5607 1255@@ -450,17 +453,19 @@ static int dm_blk_open(struct block_devi
d33d7b00
AM
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);
d33d7b00
AM
1271+ ret = 0;
1272 out:
1273 spin_unlock(&_minor_lock);
1274-
1275- return md ? 0 : -ENXIO;
1276+ return ret;
1277 }
1278
09be7631 1279 static void dm_blk_close(struct gendisk *disk, fmode_t mode)
5eef5607 1280@@ -876,6 +881,14 @@ int dm_set_geometry(struct mapped_device
d33d7b00
AM
1281 return 0;
1282 }
1283
1284+/*
1285+ * Get the xid associated with a dm device
1286+ */
61333608 1287+vxid_t dm_get_xid(struct mapped_device *md)
d33d7b00
AM
1288+{
1289+ return md->xid;
1290+}
1291+
1292 /*-----------------------------------------------------------------
1293 * CRUD START:
1294 * A more elegant soln is in the works that uses the queue
f973f73f 1295@@ -2294,6 +2307,7 @@ static struct mapped_device *alloc_dev(i
bb20add7 1296 INIT_LIST_HEAD(&md->table_devices);
d33d7b00
AM
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;
f973f73f
AM
1303diff -NurpP --minimal linux-4.1.27/drivers/md/dm.h linux-4.1.27-vs2.3.8.5.2/drivers/md/dm.h
1304--- linux-4.1.27/drivers/md/dm.h 2015-07-06 20:41:38.000000000 +0000
1305+++ linux-4.1.27-vs2.3.8.5.2/drivers/md/dm.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 1306@@ -51,6 +51,8 @@ struct dm_dev_internal {
d33d7b00
AM
1307 struct dm_table;
1308 struct dm_md_mempools;
1309
61333608 1310+vxid_t dm_get_xid(struct mapped_device *md);
d33d7b00
AM
1311+
1312 /*-----------------------------------------------------------------
1313 * Internal table functions.
1314 *---------------------------------------------------------------*/
f973f73f
AM
1315diff -NurpP --minimal linux-4.1.27/drivers/net/tun.c linux-4.1.27-vs2.3.8.5.2/drivers/net/tun.c
1316--- linux-4.1.27/drivers/net/tun.c 2015-07-06 20:41:39.000000000 +0000
1317+++ linux-4.1.27-vs2.3.8.5.2/drivers/net/tun.c 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 1318@@ -65,6 +65,7 @@
d33d7b00
AM
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>
5eef5607
AM
1325 #include <net/rtnetlink.h>
1326@@ -181,6 +182,7 @@ struct tun_struct {
d33d7b00 1327 unsigned int flags;
537831f9
AM
1328 kuid_t owner;
1329 kgid_t group;
61333608 1330+ vnid_t nid;
d33d7b00
AM
1331
1332 struct net_device *dev;
db55b927 1333 netdev_features_t set_features;
5eef5607 1334@@ -421,6 +423,7 @@ static inline bool tun_not_capable(struc
b00e13aa
AM
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)
5eef5607 1342@@ -1408,6 +1411,7 @@ static void tun_setup(struct net_device
2380c486 1343
537831f9
AM
1344 tun->owner = INVALID_UID;
1345 tun->group = INVALID_GID;
1346+ tun->nid = nx_current_nid();
2380c486 1347
ec22aa5c
AM
1348 dev->ethtool_ops = &tun_ethtool_ops;
1349 dev->destructor = tun_free_netdev;
5eef5607 1350@@ -1608,7 +1612,7 @@ static int tun_set_iff(struct net *net,
b00e13aa
AM
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))
c2e5f7c8 1355+ if (!nx_ns_capable(net->user_ns, CAP_NET_ADMIN, NXC_TUN_CREATE))
b00e13aa
AM
1356 return -EPERM;
1357 err = security_tun_dev_create();
1358 if (err < 0)
5eef5607 1359@@ -1957,6 +1961,16 @@ static long __tun_chr_ioctl(struct file
537831f9 1360 from_kgid(&init_user_ns, tun->group));
2380c486 1361 break;
d337f35e 1362
2380c486
JR
1363+ case TUNSETNID:
1364+ if (!capable(CAP_CONTEXT))
1365+ return -EPERM;
d337f35e 1366+
2380c486 1367+ /* Set nid owner of the device */
61333608 1368+ tun->nid = (vnid_t) arg;
d337f35e 1369+
763640ca 1370+ tun_debug(KERN_INFO, tun, "nid owner set to %u\n", tun->nid);
2380c486 1371+ break;
d337f35e 1372+
2380c486
JR
1373 case TUNSETLINK:
1374 /* Only allow setting the type when the interface is down */
ec22aa5c 1375 if (tun->dev->flags & IFF_UP) {
f973f73f
AM
1376diff -NurpP --minimal linux-4.1.27/drivers/scsi/cxgbi/libcxgbi.c linux-4.1.27-vs2.3.8.5.2/drivers/scsi/cxgbi/libcxgbi.c
1377--- linux-4.1.27/drivers/scsi/cxgbi/libcxgbi.c 2015-04-12 22:12:50.000000000 +0000
1378+++ linux-4.1.27-vs2.3.8.5.2/drivers/scsi/cxgbi/libcxgbi.c 2016-07-05 04:41:47.000000000 +0000
bb20add7
AM
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);
f973f73f
AM
1389diff -NurpP --minimal linux-4.1.27/drivers/tty/sysrq.c linux-4.1.27-vs2.3.8.5.2/drivers/tty/sysrq.c
1390--- linux-4.1.27/drivers/tty/sysrq.c 2016-07-05 04:28:28.000000000 +0000
1391+++ linux-4.1.27-vs2.3.8.5.2/drivers/tty/sysrq.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 1392@@ -47,6 +47,7 @@
c2e5f7c8
JR
1393 #include <linux/syscalls.h>
1394 #include <linux/of.h>
bb20add7 1395 #include <linux/rcupdate.h>
ab30d09f
AM
1396+#include <linux/vserver/debug.h>
1397
1398 #include <asm/ptrace.h>
1399 #include <asm/irq_regs.h>
5eef5607 1400@@ -407,6 +408,21 @@ static struct sysrq_key_op sysrq_unrt_op
ab30d09f
AM
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
5eef5607 1422@@ -462,7 +478,11 @@ static struct sysrq_key_op *sysrq_key_ta
ab30d09f
AM
1423 &sysrq_showstate_blocked_op, /* w */
1424 /* x: May be registered on ppc/powerpc for xmon */
537831f9 1425 /* x: May be registered on sparc64 for global PMU dump */
ab30d09f
AM
1426+#ifdef CONFIG_VSERVER_DEBUG
1427+ &sysrq_showvxinfo_op, /* x */
1428+#else
4bf69007 1429 NULL, /* x */
ab30d09f
AM
1430+#endif
1431 /* y: May be registered on sparc64 for global register dump */
1432 NULL, /* y */
1433 &sysrq_ftrace_dump_op, /* z */
5eef5607 1434@@ -477,6 +497,8 @@ static int sysrq_key_table_key2index(int
ab30d09f
AM
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;
f973f73f
AM
1443diff -NurpP --minimal linux-4.1.27/drivers/tty/tty_io.c linux-4.1.27-vs2.3.8.5.2/drivers/tty/tty_io.c
1444--- linux-4.1.27/drivers/tty/tty_io.c 2016-07-05 04:28:28.000000000 +0000
1445+++ linux-4.1.27-vs2.3.8.5.2/drivers/tty/tty_io.c 2016-07-05 04:41:47.000000000 +0000
1e8b8f9b 1446@@ -104,6 +104,7 @@
ab30d09f
AM
1447
1448 #include <linux/kmod.h>
1449 #include <linux/nsproxy.h>
1450+#include <linux/vs_pid.h>
1451
1452 #undef TTY_DEBUG_HANGUP
1453
9e3e8383 1454@@ -2287,7 +2288,8 @@ static int tiocsti(struct tty_struct *tt
ab30d09f
AM
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;
9e3e8383 1464@@ -2601,6 +2603,7 @@ static int tiocspgrp(struct tty_struct *
ab30d09f
AM
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();
f973f73f
AM
1472diff -NurpP --minimal linux-4.1.27/fs/attr.c linux-4.1.27-vs2.3.8.5.2/fs/attr.c
1473--- linux-4.1.27/fs/attr.c 2015-04-12 22:12:50.000000000 +0000
1474+++ linux-4.1.27-vs2.3.8.5.2/fs/attr.c 2016-07-05 04:41:47.000000000 +0000
537831f9 1475@@ -15,6 +15,9 @@
d337f35e 1476 #include <linux/security.h>
f6c5ef8b 1477 #include <linux/evm.h>
537831f9 1478 #include <linux/ima.h>
d337f35e
JR
1479+#include <linux/proc_fs.h>
1480+#include <linux/devpts_fs.h>
2380c486 1481+#include <linux/vs_tag.h>
d337f35e 1482
93de0823 1483 /**
0e66e2fb
JR
1484 * setattr_prepare - check if attribute changes to a dentry are allowed
1485@@ -77,6 +80,10 @@ int setattr_prepare(struct dentry *dentry
93de0823 1486 return -EPERM;
d337f35e 1487 }
93de0823
AM
1488
1489+ /* check for inode tag permission */
2380c486 1490+ if (dx_permission(inode, MAY_WRITE))
93de0823 1491+ return -EACCES;
2380c486 1492+
0e66e2fb
JR
1493 kill_priv:
1494 /* User has permission for the change */
1495 if (ia_valid & ATTR_KILL_PRIV) {
b00e13aa 1496@@ -147,6 +154,8 @@ void setattr_copy(struct inode *inode, c
d337f35e
JR
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);
c2e5f7c8 1505@@ -197,7 +206,8 @@ int notify_change(struct dentry * dentry
92598135
AM
1506
1507 WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
78865d5b
AM
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 }
f973f73f
AM
1515diff -NurpP --minimal linux-4.1.27/fs/block_dev.c linux-4.1.27-vs2.3.8.5.2/fs/block_dev.c
1516--- linux-4.1.27/fs/block_dev.c 2016-07-05 04:28:29.000000000 +0000
1517+++ linux-4.1.27-vs2.3.8.5.2/fs/block_dev.c 2016-07-05 04:41:47.000000000 +0000
5eef5607
AM
1518@@ -27,6 +27,7 @@
1519 #include <linux/namei.h>
2380c486 1520 #include <linux/log2.h>
db55b927 1521 #include <linux/cleancache.h>
2380c486
JR
1522+#include <linux/vs_device.h>
1523 #include <asm/uaccess.h>
1524 #include "internal.h"
1525
5eef5607 1526@@ -611,6 +612,7 @@ struct block_device *bdget(dev_t dev)
2380c486
JR
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);
5eef5607 1534@@ -657,6 +659,11 @@ EXPORT_SYMBOL(bdput);
2380c486
JR
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;
5eef5607 1546@@ -667,7 +674,7 @@ static struct block_device *bd_acquire(s
2380c486
JR
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) {
f973f73f
AM
1555diff -NurpP --minimal linux-4.1.27/fs/btrfs/ctree.h linux-4.1.27-vs2.3.8.5.2/fs/btrfs/ctree.h
1556--- linux-4.1.27/fs/btrfs/ctree.h 2016-07-05 04:28:29.000000000 +0000
1557+++ linux-4.1.27-vs2.3.8.5.2/fs/btrfs/ctree.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 1558@@ -731,11 +731,14 @@ struct btrfs_inode_item {
e22b5178
AM
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;
5eef5607 1574@@ -2156,6 +2159,8 @@ struct btrfs_ioctl_defrag_range_args {
c2e5f7c8 1575 #define BTRFS_DEFAULT_COMMIT_INTERVAL (30)
bb20add7 1576 #define BTRFS_DEFAULT_MAX_INLINE (8192)
e22b5178
AM
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)
b00e13aa 1582 #define btrfs_raw_test_opt(o, opt) ((o) & BTRFS_MOUNT_##opt)
5eef5607 1583@@ -2483,6 +2488,7 @@ BTRFS_SETGET_FUNCS(inode_block_group, st
e22b5178
AM
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);
5eef5607 1591@@ -2530,6 +2536,10 @@ BTRFS_SETGET_FUNCS(extent_flags, struct
78865d5b
AM
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
f973f73f 1602@@ -3960,6 +3970,7 @@ long btrfs_compat_ioctl(struct file *fil
d4263eb0
JR
1603 void btrfs_update_iflags(struct inode *inode);
1604 void btrfs_inherit_iflags(struct inode *inode, struct inode *dir);
c2e5f7c8 1605 int btrfs_is_empty_uuid(u8 *uuid);
d4263eb0 1606+int btrfs_sync_flags(struct inode *inode, int, int);
763640ca
JR
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);
f973f73f
AM
1610diff -NurpP --minimal linux-4.1.27/fs/btrfs/disk-io.c linux-4.1.27-vs2.3.8.5.2/fs/btrfs/disk-io.c
1611--- linux-4.1.27/fs/btrfs/disk-io.c 2016-07-05 04:28:29.000000000 +0000
1612+++ linux-4.1.27-vs2.3.8.5.2/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,
763640ca 1614 goto fail_alloc;
e22b5178
AM
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) {
f973f73f
AM
1623diff -NurpP --minimal linux-4.1.27/fs/btrfs/inode.c linux-4.1.27-vs2.3.8.5.2/fs/btrfs/inode.c
1624--- linux-4.1.27/fs/btrfs/inode.c 2016-07-05 04:28:29.000000000 +0000
1625+++ linux-4.1.27-vs2.3.8.5.2/fs/btrfs/inode.c 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 1626@@ -43,6 +43,7 @@
b00e13aa 1627 #include <linux/blkdev.h>
c2e5f7c8 1628 #include <linux/posix_acl_xattr.h>
5eef5607 1629 #include <linux/uio.h>
e22b5178 1630+#include <linux/vs_tag.h>
e22b5178
AM
1631 #include "ctree.h"
1632 #include "disk-io.h"
c2e5f7c8 1633 #include "transaction.h"
9e3e8383 1634@@ -3579,6 +3580,9 @@ static void btrfs_read_locked_inode(stru
bb20add7 1635 unsigned long ptr;
e22b5178 1636 int maybe_acls;
e22b5178 1637 u32 rdev;
a4a22af8
AM
1638+ kuid_t kuid;
1639+ kgid_t kgid;
1640+ ktag_t ktag;
e22b5178 1641 int ret;
763640ca 1642 bool filled = false;
bb20add7 1643 int first_xattr_slot;
9e3e8383 1644@@ -3606,8 +3610,14 @@ static void btrfs_read_locked_inode(stru
a168f21d 1645 struct btrfs_inode_item);
e22b5178 1646 inode->i_mode = btrfs_inode_mode(leaf, inode_item);
f6c5ef8b 1647 set_nlink(inode, btrfs_inode_nlink(leaf, inode_item));
537831f9
AM
1648- i_uid_write(inode, btrfs_inode_uid(leaf, inode_item));
1649- i_gid_write(inode, btrfs_inode_gid(leaf, inode_item));
e22b5178 1650+
a4a22af8
AM
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);
e22b5178
AM
1658 btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item));
1659
5eef5607 1660 inode->i_atime.tv_sec = btrfs_timespec_sec(leaf, &inode_item->atime);
9e3e8383 1661@@ -3734,11 +3744,18 @@ static void fill_inode_item(struct btrfs
e22b5178
AM
1662 struct inode *inode)
1663 {
b00e13aa 1664 struct btrfs_map_token token;
a4a22af8
AM
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));
b00e13aa
AM
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);
e22b5178 1676+#ifdef CONFIG_TAGGING_INTERN
b00e13aa 1677+ btrfs_set_token_inode_tag(leaf, item, i_tag_read(inode), &token);
e22b5178 1678+#endif
b00e13aa
AM
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);
f973f73f 1682@@ -9875,6 +9892,7 @@ static const struct inode_operations btr
d4263eb0
JR
1683 .listxattr = btrfs_listxattr,
1684 .removexattr = btrfs_removexattr,
d4263eb0
JR
1685 .permission = btrfs_permission,
1686+ .sync_flags = btrfs_sync_flags,
a168f21d 1687 .get_acl = btrfs_get_acl,
f15949f2 1688 .set_acl = btrfs_set_acl,
c2e5f7c8 1689 .update_time = btrfs_update_time,
f973f73f 1690@@ -9883,6 +9901,7 @@ static const struct inode_operations btr
7e46296a 1691 static const struct inode_operations btrfs_dir_ro_inode_operations = {
d4263eb0 1692 .lookup = btrfs_lookup,
d4263eb0 1693 .permission = btrfs_permission,
d4263eb0 1694+ .sync_flags = btrfs_sync_flags,
a168f21d 1695 .get_acl = btrfs_get_acl,
f15949f2 1696 .set_acl = btrfs_set_acl,
c2e5f7c8 1697 .update_time = btrfs_update_time,
f973f73f 1698@@ -9953,6 +9972,7 @@ static const struct inode_operations btr
c2e5f7c8
JR
1699 .removexattr = btrfs_removexattr,
1700 .permission = btrfs_permission,
1701 .fiemap = btrfs_fiemap,
1702+ .sync_flags = btrfs_sync_flags,
1703 .get_acl = btrfs_get_acl,
bb20add7 1704 .set_acl = btrfs_set_acl,
c2e5f7c8 1705 .update_time = btrfs_update_time,
f973f73f
AM
1706diff -NurpP --minimal linux-4.1.27/fs/btrfs/ioctl.c linux-4.1.27-vs2.3.8.5.2/fs/btrfs/ioctl.c
1707--- linux-4.1.27/fs/btrfs/ioctl.c 2016-07-05 04:28:29.000000000 +0000
1708+++ linux-4.1.27-vs2.3.8.5.2/fs/btrfs/ioctl.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 1709@@ -107,10 +107,13 @@ static unsigned int btrfs_flags_to_ioctl
d4263eb0
JR
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)
bb20add7 1725@@ -127,34 +130,84 @@ static unsigned int btrfs_flags_to_ioctl
763640ca
JR
1726 else if (flags & BTRFS_INODE_NOCOMPRESS)
1727 iflags |= FS_NOCOMP_FL;
d4263eb0
JR
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);
bb20add7 1743 unsigned int new_fl = 0;
d4263eb0
JR
1744
1745- if (ip->flags & BTRFS_INODE_SYNC)
bb20add7 1746- new_fl |= S_SYNC;
d4263eb0 1747 if (ip->flags & BTRFS_INODE_IMMUTABLE)
bb20add7 1748 new_fl |= S_IMMUTABLE;
d4263eb0 1749+ if (ip->flags & BTRFS_INODE_IXUNLINK)
bb20add7 1750+ new_fl |= S_IXUNLINK;
d4263eb0
JR
1751+
1752+ if (ip->flags & BTRFS_INODE_SYNC)
bb20add7 1753+ new_fl |= S_SYNC;
d4263eb0 1754 if (ip->flags & BTRFS_INODE_APPEND)
bb20add7 1755 new_fl |= S_APPEND;
d4263eb0 1756 if (ip->flags & BTRFS_INODE_NOATIME)
bb20add7 1757 new_fl |= S_NOATIME;
d4263eb0 1758 if (ip->flags & BTRFS_INODE_DIRSYNC)
bb20add7
AM
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);
d4263eb0 1765+
bb20add7 1766+ new_fl = 0;
d4263eb0 1767+ if (ip->flags & BTRFS_INODE_BARRIER)
bb20add7 1768+ new_fl |= V_BARRIER;
d4263eb0 1769+ if (ip->flags & BTRFS_INODE_COW)
bb20add7 1770+ new_fl |= V_COW;
d4263eb0 1771+
bb20add7
AM
1772+ set_mask_bits(&inode->i_vflags,
1773+ V_BARRIER | V_COW, new_fl);
1774 }
1775
1776 /*
d4263eb0
JR
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;
bb20add7
AM
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 *
f6c5ef8b 1816 return;
d4263eb0 1817
f6c5ef8b
AM
1818 flags = BTRFS_I(dir)->flags;
1819+ flags &= ~BTRFS_INODE_BARRIER;
d4263eb0 1820
f6c5ef8b
AM
1821 if (flags & BTRFS_INODE_NOCOMPRESS) {
1822 BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS;
bb20add7 1823@@ -185,6 +239,30 @@ void btrfs_inherit_iflags(struct inode *
d4263eb0
JR
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+
763640ca 1834+ trans = btrfs_join_transaction(root);
d4263eb0
JR
1835+ BUG_ON(!trans);
1836+
d4263eb0
JR
1837+ inode->i_flags = flags;
1838+ inode->i_vflags = vflags;
1839+ btrfs_update_flags(inode);
e22b5178
AM
1840+
1841+ ret = btrfs_update_inode(trans, root, inode);
1842+ BUG_ON(ret);
1843+
1844+ btrfs_update_iflags(inode);
d4263eb0
JR
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 {
b00e13aa 1853 struct btrfs_inode *ip = BTRFS_I(file_inode(file));
bb20add7 1854@@ -247,21 +325,27 @@ static int btrfs_ioctl_setflags(struct f
d4263eb0
JR
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;
92598135
AM
1864 }
1865 }
d4263eb0
JR
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
f973f73f
AM
1887diff -NurpP --minimal linux-4.1.27/fs/btrfs/super.c linux-4.1.27-vs2.3.8.5.2/fs/btrfs/super.c
1888--- linux-4.1.27/fs/btrfs/super.c 2016-07-05 04:28:29.000000000 +0000
1889+++ linux-4.1.27-vs2.3.8.5.2/fs/btrfs/super.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 1890@@ -325,7 +325,7 @@ enum {
f15949f2
JR
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,
db55b927 1894- Opt_err,
f6c5ef8b 1895+ Opt_tag, Opt_notag, Opt_tagid, Opt_err,
e22b5178
AM
1896 };
1897
1898 static match_table_t tokens = {
bb20add7 1899@@ -377,6 +377,9 @@ static match_table_t tokens = {
c2e5f7c8 1900 {Opt_rescan_uuid_tree, "rescan_uuid_tree"},
1e8b8f9b 1901 {Opt_fatal_errors, "fatal_errors=%s"},
c2e5f7c8 1902 {Opt_commit_interval, "commit=%d"},
e22b5178
AM
1903+ {Opt_tag, "tag"},
1904+ {Opt_notag, "notag"},
1905+ {Opt_tagid, "tagid=%u"},
1906 {Opt_err, NULL},
1907 };
1908
bb20add7 1909@@ -743,6 +746,22 @@ int btrfs_parse_options(struct btrfs_roo
c2e5f7c8 1910 info->commit_interval = BTRFS_DEFAULT_COMMIT_INTERVAL;
1e8b8f9b
AM
1911 }
1912 break;
e22b5178
AM
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
2bf5ad28 1929 case Opt_err:
bb20add7
AM
1930 btrfs_info(root->fs_info, "unrecognized mount option '%s'", p);
1931 ret = -EINVAL;
5eef5607 1932@@ -1522,6 +1541,12 @@ static int btrfs_remount(struct super_bl
42bc425c
AM
1933 btrfs_resize_thread_pool(fs_info,
1934 fs_info->thread_pool_size, old_thread_pool_size);
e22b5178
AM
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))
b00e13aa 1943 goto out;
e22b5178 1944
f973f73f
AM
1945diff -NurpP --minimal linux-4.1.27/fs/char_dev.c linux-4.1.27-vs2.3.8.5.2/fs/char_dev.c
1946--- linux-4.1.27/fs/char_dev.c 2015-04-12 22:12:50.000000000 +0000
1947+++ linux-4.1.27-vs2.3.8.5.2/fs/char_dev.c 2016-07-05 04:41:47.000000000 +0000
4744a4b1 1948@@ -21,6 +21,8 @@
2380c486
JR
1949 #include <linux/mutex.h>
1950 #include <linux/backing-dev.h>
7942c842 1951 #include <linux/tty.h>
2380c486
JR
1952+#include <linux/vs_context.h>
1953+#include <linux/vs_device.h>
1954
ec22aa5c
AM
1955 #include "internal.h"
1956
5eef5607 1957@@ -350,14 +352,21 @@ static int chrdev_open(struct inode *ino
2380c486
JR
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);
f973f73f
AM
1980diff -NurpP --minimal linux-4.1.27/fs/dcache.c linux-4.1.27-vs2.3.8.5.2/fs/dcache.c
1981--- linux-4.1.27/fs/dcache.c 2016-07-05 04:28:30.000000000 +0000
1982+++ linux-4.1.27-vs2.3.8.5.2/fs/dcache.c 2016-07-06 06:40:31.000000000 +0000
5eef5607 1983@@ -39,6 +39,7 @@
f6c5ef8b 1984 #include <linux/ratelimit.h>
c2e5f7c8 1985 #include <linux/list_lru.h>
5eef5607 1986 #include <linux/kasan.h>
d337f35e 1987+#include <linux/vs_limit.h>
5eef5607 1988
d337f35e 1989 #include "internal.h"
db55b927 1990 #include "mount.h"
f973f73f
AM
1991@@ -651,6 +652,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@@ -778,6 +780,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@@ -793,6 +796,7 @@ EXPORT_SYMBOL(dput);
d33d7b00 2008 static inline void __dget_dlock(struct dentry *dentry)
2380c486 2009 {
c2e5f7c8 2010 dentry->d_lockref.count++;
2380c486 2011+ vx_dentry_inc(dentry);
d337f35e 2012 }
2380c486 2013
d33d7b00 2014 static inline void __dget(struct dentry *dentry)
f973f73f 2015@@ -805,6 +809,8 @@ struct dentry *dget_parent(struct dentry
bb20add7
AM
2016 int gotref;
2017 struct dentry *ret;
2018
2019+ vx_dentry_dec(dentry);
2020+
2021 /*
2022 * Do optimistic parent lookup without any
2023 * locking.
f973f73f
AM
2024@@ -835,6 +841,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@@ -989,6 +996,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@@ -1547,6 +1555,9 @@ struct dentry *__d_alloc(struct super_bl
d337f35e
JR
2041 struct dentry *dentry;
2042 char *dname;
2043
2044+ if (!vx_dentry_avail(1))
2045+ return NULL;
2046+
2380c486 2047 dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
d337f35e
JR
2048 if (!dentry)
2049 return NULL;
f973f73f 2050@@ -1585,6 +1596,7 @@ struct dentry *__d_alloc(struct super_bl
d337f35e 2051
c2e5f7c8 2052 dentry->d_lockref.count = 1;
763640ca 2053 dentry->d_flags = 0;
ab30d09f 2054+ vx_dentry_inc(dentry);
ab30d09f 2055 spin_lock_init(&dentry->d_lock);
d33d7b00 2056 seqcount_init(&dentry->d_seq);
763640ca 2057 dentry->d_inode = NULL;
f973f73f 2058@@ -2318,6 +2330,7 @@ struct dentry *__d_lookup(const struct d
d337f35e 2059 }
2380c486 2060
c2e5f7c8 2061 dentry->d_lockref.count++;
2380c486
JR
2062+ vx_dentry_inc(dentry);
2063 found = dentry;
d337f35e 2064 spin_unlock(&dentry->d_lock);
2380c486 2065 break;
f973f73f
AM
2066@@ -3335,6 +3348,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;
2074diff -NurpP --minimal linux-4.1.27/fs/devpts/inode.c linux-4.1.27-vs2.3.8.5.2/fs/devpts/inode.c
2075--- linux-4.1.27/fs/devpts/inode.c 2016-07-05 04:28:30.000000000 +0000
2076+++ linux-4.1.27-vs2.3.8.5.2/fs/devpts/inode.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 2077@@ -27,6 +27,7 @@
d337f35e 2078 #include <linux/parser.h>
2380c486
JR
2079 #include <linux/fsnotify.h>
2080 #include <linux/seq_file.h>
d337f35e
JR
2081+#include <linux/vs_base.h>
2082
2380c486 2083 #define DEVPTS_DEFAULT_MODE 0600
ec22aa5c 2084 /*
bb20add7 2085@@ -38,6 +39,21 @@
ec22aa5c
AM
2086 #define DEVPTS_DEFAULT_PTMX_MODE 0000
2087 #define PTMX_MINOR 2
2380c486 2088
a168f21d 2089+static int devpts_permission(struct inode *inode, int mask)
d337f35e
JR
2090+{
2091+ int ret = -EACCES;
2092+
2093+ /* devpts is xid tagged */
61333608 2094+ if (vx_check((vxid_t)i_tag_read(inode), VS_WATCH_P | VS_IDENT))
a168f21d 2095+ ret = generic_permission(inode, mask);
d337f35e
JR
2096+ return ret;
2097+}
2098+
2099+static struct inode_operations devpts_file_inode_operations = {
2100+ .permission = devpts_permission,
2101+};
2380c486 2102+
1e8b8f9b
AM
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.
bb20add7 2107@@ -350,6 +366,34 @@ static int devpts_show_options(struct se
d337f35e
JR
2108 return 0;
2109 }
2110
2111+static int devpts_filter(struct dentry *de)
2112+{
61333608 2113+ vxid_t xid = 0;
b3b0d4fd 2114+
d337f35e 2115+ /* devpts is xid tagged */
b3b0d4fd 2116+ if (de && de->d_inode)
61333608 2117+ xid = (vxid_t)i_tag_read(de->d_inode);
b3b0d4fd
AM
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);
d337f35e
JR
2124+}
2125+
c2e5f7c8 2126+static int devpts_readdir(struct file * filp, struct dir_context *ctx)
d337f35e 2127+{
c2e5f7c8 2128+ return dcache_readdir_filter(filp, ctx, devpts_filter);
d337f35e
JR
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,
c2e5f7c8 2136+ .iterate = devpts_readdir,
d337f35e
JR
2137+};
2138+
2380c486 2139 static const struct super_operations devpts_sops = {
d337f35e
JR
2140 .statfs = simple_statfs,
2141 .remount_fs = devpts_remount,
bb20add7 2142@@ -393,8 +437,10 @@ devpts_fill_super(struct super_block *s,
ec22aa5c 2143 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
d337f35e
JR
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;
f6c5ef8b 2148 set_nlink(inode, 2);
d337f35e 2149+ /* devpts is xid tagged */
61333608 2150+ i_tag_write(inode, (vtag_t)vx_current_xid());
d337f35e 2151
1e8b8f9b 2152 s->s_root = d_make_root(inode);
d337f35e 2153 if (s->s_root)
f973f73f 2154@@ -618,6 +664,9 @@ struct inode *devpts_pty_new(struct inod
ec22aa5c 2155 inode->i_gid = opts->setgid ? opts->gid : current_fsgid();
d337f35e 2156 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
ec22aa5c 2157 init_special_inode(inode, S_IFCHR|opts->mode, device);
d337f35e 2158+ /* devpts is xid tagged */
61333608 2159+ i_tag_write(inode, (vtag_t)vx_current_xid());
d337f35e 2160+ inode->i_op = &devpts_file_inode_operations;
b00e13aa 2161 inode->i_private = priv;
d337f35e 2162
b00e13aa 2163 sprintf(s, "%d", index);
f973f73f
AM
2164diff -NurpP --minimal linux-4.1.27/fs/ext2/balloc.c linux-4.1.27-vs2.3.8.5.2/fs/ext2/balloc.c
2165--- linux-4.1.27/fs/ext2/balloc.c 2015-04-12 22:12:50.000000000 +0000
2166+++ linux-4.1.27-vs2.3.8.5.2/fs/ext2/balloc.c 2016-07-05 04:41:47.000000000 +0000
b00e13aa 2167@@ -693,7 +693,6 @@ ext2_try_to_allocate(struct super_block
2380c486
JR
2168 start = 0;
2169 end = EXT2_BLOCKS_PER_GROUP(sb);
d337f35e 2170 }
2380c486
JR
2171-
2172 BUG_ON(start > EXT2_BLOCKS_PER_GROUP(sb));
2173
2174 repeat:
f973f73f
AM
2175diff -NurpP --minimal linux-4.1.27/fs/ext2/ext2.h linux-4.1.27-vs2.3.8.5.2/fs/ext2/ext2.h
2176--- linux-4.1.27/fs/ext2/ext2.h 2015-07-06 20:41:42.000000000 +0000
2177+++ linux-4.1.27-vs2.3.8.5.2/fs/ext2/ext2.h 2016-07-05 04:41:47.000000000 +0000
1e8b8f9b
AM
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 /*
5eef5607
AM
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 */
1e8b8f9b
AM
2214
2215
2216 #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
5eef5607 2217@@ -765,6 +772,7 @@ extern void ext2_set_inode_flags(struct
93de0823
AM
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);
d4263eb0
JR
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);
f973f73f
AM
2225diff -NurpP --minimal linux-4.1.27/fs/ext2/file.c linux-4.1.27-vs2.3.8.5.2/fs/ext2/file.c
2226--- linux-4.1.27/fs/ext2/file.c 2016-07-05 04:28:30.000000000 +0000
2227+++ linux-4.1.27-vs2.3.8.5.2/fs/ext2/file.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 2228@@ -118,4 +118,5 @@ const struct inode_operations ext2_file_
a168f21d 2229 .get_acl = ext2_get_acl,
bb20add7 2230 .set_acl = ext2_set_acl,
ec22aa5c 2231 .fiemap = ext2_fiemap,
d337f35e
JR
2232+ .sync_flags = ext2_sync_flags,
2233 };
f973f73f
AM
2234diff -NurpP --minimal linux-4.1.27/fs/ext2/ialloc.c linux-4.1.27-vs2.3.8.5.2/fs/ext2/ialloc.c
2235--- linux-4.1.27/fs/ext2/ialloc.c 2015-07-06 20:41:42.000000000 +0000
2236+++ linux-4.1.27-vs2.3.8.5.2/fs/ext2/ialloc.c 2016-07-05 04:41:47.000000000 +0000
e22b5178
AM
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"
a4a22af8 2245@@ -546,6 +547,7 @@ got:
76514441
AM
2246 inode->i_mode = mode;
2247 inode->i_uid = current_fsuid();
2248 inode->i_gid = dir->i_gid;
a4a22af8 2249+ i_tag_write(inode, dx_current_fstag(sb));
e22b5178 2250 } else
76514441 2251 inode_init_owner(inode, dir, mode);
e22b5178 2252
f973f73f
AM
2253diff -NurpP --minimal linux-4.1.27/fs/ext2/inode.c linux-4.1.27-vs2.3.8.5.2/fs/ext2/inode.c
2254--- linux-4.1.27/fs/ext2/inode.c 2015-07-06 20:41:42.000000000 +0000
2255+++ linux-4.1.27-vs2.3.8.5.2/fs/ext2/inode.c 2016-07-05 04:41:47.000000000 +0000
09be7631 2256@@ -32,6 +32,7 @@
ec22aa5c
AM
2257 #include <linux/fiemap.h>
2258 #include <linux/namei.h>
5eef5607 2259 #include <linux/uio.h>
d337f35e
JR
2260+#include <linux/vs_tag.h>
2261 #include "ext2.h"
2262 #include "acl.h"
5eef5607 2263 #include "xattr.h"
c2e5f7c8 2264@@ -1182,7 +1183,7 @@ static void ext2_truncate_blocks(struct
d337f35e
JR
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;
76514441
AM
2271 __ext2_truncate_blocks(inode, offset);
2272 }
5eef5607 2273@@ -1273,39 +1274,62 @@ void ext2_set_inode_flags(struct inode *
d337f35e
JR
2274 {
2275 unsigned int flags = EXT2_I(inode)->i_flags;
2276
5eef5607
AM
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 |
d337f35e
JR
2280+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2281+
2282+ if (flags & EXT2_IMMUTABLE_FL)
2283+ inode->i_flags |= S_IMMUTABLE;
2380c486
JR
2284+ if (flags & EXT2_IXUNLINK_FL)
2285+ inode->i_flags |= S_IXUNLINK;
d337f35e
JR
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;
5eef5607
AM
2297 if (test_opt(inode->i_sb, DAX))
2298 inode->i_flags |= S_DAX;
2380c486
JR
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;
d337f35e
JR
2341 }
2342
2380c486 2343 struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
5eef5607 2344@@ -1341,8 +1365,10 @@ struct inode *ext2_iget (struct super_bl
42bc425c
AM
2345 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
2346 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
d337f35e 2347 }
42bc425c
AM
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));
537831f9
AM
2352+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
2353+ le16_to_cpu(raw_inode->i_raw_tag)));
f6c5ef8b 2354 set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
d337f35e 2355 inode->i_size = le32_to_cpu(raw_inode->i_size);
2380c486 2356 inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
5eef5607 2357@@ -1437,8 +1463,10 @@ static int __ext2_write_inode(struct ino
d337f35e
JR
2358 struct ext2_inode_info *ei = EXT2_I(inode);
2359 struct super_block *sb = inode->i_sb;
2360 ino_t ino = inode->i_ino;
42bc425c
AM
2361- uid_t uid = i_uid_read(inode);
2362- gid_t gid = i_gid_read(inode);
a4a22af8
AM
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));
d337f35e
JR
2367 struct buffer_head * bh;
2368 struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);
2369 int n;
5eef5607 2370@@ -1474,6 +1502,9 @@ static int __ext2_write_inode(struct ino
d337f35e
JR
2371 raw_inode->i_uid_high = 0;
2372 raw_inode->i_gid_high = 0;
2373 }
2374+#ifdef CONFIG_TAGGING_INTERN
537831f9 2375+ raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
d337f35e
JR
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);
5eef5607 2380@@ -1554,7 +1585,8 @@ int ext2_setattr(struct dentry *dentry,
76514441 2381 if (is_quota_modification(inode, iattr))
78865d5b 2382 dquot_initialize(inode);
42bc425c
AM
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)) ||
537831f9 2386+ (iattr->ia_valid & ATTR_TAG && !tag_eq(iattr->ia_tag, inode->i_tag))) {
78865d5b 2387 error = dquot_transfer(inode, iattr);
d337f35e
JR
2388 if (error)
2389 return error;
f973f73f
AM
2390diff -NurpP --minimal linux-4.1.27/fs/ext2/ioctl.c linux-4.1.27-vs2.3.8.5.2/fs/ext2/ioctl.c
2391--- linux-4.1.27/fs/ext2/ioctl.c 2015-04-12 22:12:50.000000000 +0000
2392+++ linux-4.1.27-vs2.3.8.5.2/fs/ext2/ioctl.c 2016-07-05 04:41:47.000000000 +0000
d4263eb0
JR
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 {
b00e13aa 2409 struct inode *inode = file_inode(filp);
d4263eb0 2410@@ -51,6 +61,11 @@ long ext2_ioctl(struct file *filp, unsig
d337f35e 2411
ec22aa5c 2412 flags = ext2_mask_flags(inode->i_mode, flags);
d337f35e 2413
2380c486
JR
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)) {
d4263eb0 2422@@ -66,7 +81,9 @@ long ext2_ioctl(struct file *filp, unsig
d337f35e
JR
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 |
2380c486
JR
2429+ EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL))) {
2430 if (!capable(CAP_LINUX_IMMUTABLE)) {
2431 mutex_unlock(&inode->i_mutex);
2432 ret = -EPERM;
d4263eb0
JR
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;
db55b927 2441
f973f73f
AM
2442diff -NurpP --minimal linux-4.1.27/fs/ext2/namei.c linux-4.1.27-vs2.3.8.5.2/fs/ext2/namei.c
2443--- linux-4.1.27/fs/ext2/namei.c 2015-07-06 20:41:42.000000000 +0000
2444+++ linux-4.1.27-vs2.3.8.5.2/fs/ext2/namei.c 2016-07-05 04:41:47.000000000 +0000
78865d5b 2445@@ -32,6 +32,7 @@
d337f35e
JR
2446
2447 #include <linux/pagemap.h>
78865d5b 2448 #include <linux/quotaops.h>
d337f35e
JR
2449+#include <linux/vs_tag.h>
2450 #include "ext2.h"
2451 #include "xattr.h"
2452 #include "acl.h"
5eef5607 2453@@ -72,6 +73,7 @@ static struct dentry *ext2_lookup(struct
a168f21d
AM
2454 (unsigned long) ino);
2455 return ERR_PTR(-EIO);
ec22aa5c 2456 }
a168f21d 2457+ dx_propagate_tag(nd, inode);
d337f35e 2458 }
a168f21d
AM
2459 return d_splice_alias(inode, dentry);
2460 }
5eef5607 2461@@ -426,6 +428,7 @@ const struct inode_operations ext2_speci
a168f21d 2462 .removexattr = generic_removexattr,
d337f35e
JR
2463 #endif
2464 .setattr = ext2_setattr,
d337f35e 2465+ .sync_flags = ext2_sync_flags,
a168f21d 2466 .get_acl = ext2_get_acl,
bb20add7 2467 .set_acl = ext2_set_acl,
d337f35e 2468 };
f973f73f
AM
2469diff -NurpP --minimal linux-4.1.27/fs/ext2/super.c linux-4.1.27-vs2.3.8.5.2/fs/ext2/super.c
2470--- linux-4.1.27/fs/ext2/super.c 2015-04-12 22:12:50.000000000 +0000
2471+++ linux-4.1.27-vs2.3.8.5.2/fs/ext2/super.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 2472@@ -405,7 +405,8 @@ enum {
d337f35e
JR
2473 Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
2474 Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
5eef5607 2475 Opt_acl, Opt_noacl, Opt_xip, Opt_dax, Opt_ignore, Opt_err, Opt_quota,
2380c486
JR
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
d337f35e
JR
2479 };
2480
ec22aa5c 2481 static const match_table_t tokens = {
5eef5607 2482@@ -433,6 +434,9 @@ static const match_table_t tokens = {
d337f35e
JR
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"},
5eef5607 2489 {Opt_dax, "dax"},
d337f35e
JR
2490 {Opt_grpquota, "grpquota"},
2491 {Opt_ignore, "noquota"},
5eef5607 2492@@ -517,6 +521,20 @@ static int parse_options(char *options,
d337f35e
JR
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;
5eef5607 2513@@ -879,6 +897,8 @@ static int ext2_fill_super(struct super_
2bf5ad28 2514 if (!parse_options((char *) data, sb))
d337f35e
JR
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);
5eef5607 2522@@ -1288,6 +1308,14 @@ static int ext2_remount (struct super_bl
537831f9 2523 err = -EINVAL;
d337f35e
JR
2524 goto restore_opts;
2525 }
537831f9 2526+
d337f35e
JR
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);
d4263eb0
JR
2531+ err = -EINVAL;
2532+ goto restore_opts;
d337f35e 2533+ }
537831f9 2534
d337f35e
JR
2535 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2536 ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
f973f73f
AM
2537diff -NurpP --minimal linux-4.1.27/fs/ext3/ext3.h linux-4.1.27-vs2.3.8.5.2/fs/ext3/ext3.h
2538--- linux-4.1.27/fs/ext3/ext3.h 2015-04-12 22:12:50.000000000 +0000
2539+++ linux-4.1.27-vs2.3.8.5.2/fs/ext3/ext3.h 2016-07-05 04:41:47.000000000 +0000
1e8b8f9b
AM
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 |\
bb20add7 2557@@ -292,7 +296,8 @@ struct ext3_inode {
1e8b8f9b
AM
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 */
bb20add7 2567@@ -322,6 +327,7 @@ struct ext3_inode {
1e8b8f9b
AM
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 /*
bb20add7 2575@@ -366,6 +372,7 @@ struct ext3_inode {
1e8b8f9b
AM
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
5eef5607 2583@@ -1067,6 +1074,7 @@ extern void ext3_get_inode_flags(struct
1e8b8f9b
AM
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);
f973f73f
AM
2591diff -NurpP --minimal linux-4.1.27/fs/ext3/file.c linux-4.1.27-vs2.3.8.5.2/fs/ext3/file.c
2592--- linux-4.1.27/fs/ext3/file.c 2015-07-06 20:41:42.000000000 +0000
2593+++ linux-4.1.27-vs2.3.8.5.2/fs/ext3/file.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 2594@@ -75,5 +75,6 @@ const struct inode_operations ext3_file_
a168f21d 2595 .get_acl = ext3_get_acl,
bb20add7 2596 .set_acl = ext3_set_acl,
ec22aa5c
AM
2597 .fiemap = ext3_fiemap,
2598+ .sync_flags = ext3_sync_flags,
2599 };
2600
f973f73f
AM
2601diff -NurpP --minimal linux-4.1.27/fs/ext3/ialloc.c linux-4.1.27-vs2.3.8.5.2/fs/ext3/ialloc.c
2602--- linux-4.1.27/fs/ext3/ialloc.c 2015-07-06 20:41:42.000000000 +0000
2603+++ linux-4.1.27-vs2.3.8.5.2/fs/ext3/ialloc.c 2016-07-05 04:41:47.000000000 +0000
1e8b8f9b
AM
2604@@ -14,6 +14,7 @@
2605
2606 #include <linux/quotaops.h>
e22b5178 2607 #include <linux/random.h>
e22b5178
AM
2608+#include <linux/vs_tag.h>
2609
1e8b8f9b
AM
2610 #include "ext3.h"
2611 #include "xattr.h"
a4a22af8 2612@@ -469,6 +470,7 @@ got:
76514441
AM
2613 inode->i_mode = mode;
2614 inode->i_uid = current_fsuid();
2615 inode->i_gid = dir->i_gid;
a4a22af8 2616+ i_tag_write(inode, dx_current_fstag(sb));
e22b5178 2617 } else
76514441 2618 inode_init_owner(inode, dir, mode);
e22b5178 2619
f973f73f
AM
2620diff -NurpP --minimal linux-4.1.27/fs/ext3/inode.c linux-4.1.27-vs2.3.8.5.2/fs/ext3/inode.c
2621--- linux-4.1.27/fs/ext3/inode.c 2015-07-06 20:41:42.000000000 +0000
2622+++ linux-4.1.27-vs2.3.8.5.2/fs/ext3/inode.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 2623@@ -28,6 +28,7 @@
1e8b8f9b 2624 #include <linux/mpage.h>
ec22aa5c 2625 #include <linux/namei.h>
5eef5607 2626 #include <linux/uio.h>
ec22aa5c 2627+#include <linux/vs_tag.h>
1e8b8f9b 2628 #include "ext3.h"
d337f35e
JR
2629 #include "xattr.h"
2630 #include "acl.h"
5eef5607 2631@@ -2813,36 +2814,60 @@ void ext3_set_inode_flags(struct inode *
d337f35e
JR
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);
2380c486 2636+ inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK |
d337f35e
JR
2637+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2638+
2639+ if (flags & EXT3_IMMUTABLE_FL)
2640+ inode->i_flags |= S_IMMUTABLE;
2380c486
JR
2641+ if (flags & EXT3_IXUNLINK_FL)
2642+ inode->i_flags |= S_IXUNLINK;
d337f35e
JR
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;
2380c486
JR
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;
d337f35e
JR
2661 }
2662
2380c486
JR
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;
2380c486
JR
2696 }
2697
2698 struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
5eef5607 2699@@ -2880,8 +2905,10 @@ struct inode *ext3_iget(struct super_blo
42bc425c
AM
2700 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
2701 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
d337f35e 2702 }
42bc425c
AM
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));
537831f9
AM
2707+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
2708+ le16_to_cpu(raw_inode->i_raw_tag)));
f6c5ef8b 2709 set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
d337f35e 2710 inode->i_size = le32_to_cpu(raw_inode->i_size);
2380c486 2711 inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
5eef5607 2712@@ -3053,8 +3080,10 @@ again:
d337f35e 2713
2380c486 2714 ext3_get_inode_flags(ei);
d337f35e 2715 raw_inode->i_mode = cpu_to_le16(inode->i_mode);
42bc425c
AM
2716- i_uid = i_uid_read(inode);
2717- i_gid = i_gid_read(inode);
a4a22af8
AM
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));
d337f35e 2722 if(!(test_opt(inode->i_sb, NO_UID32))) {
42bc425c
AM
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));
5eef5607 2725@@ -3079,6 +3108,9 @@ again:
d337f35e
JR
2726 raw_inode->i_uid_high = 0;
2727 raw_inode->i_gid_high = 0;
2728 }
2729+#ifdef CONFIG_TAGGING_INTERN
537831f9 2730+ raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
d337f35e
JR
2731+#endif
2732 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
a5ed4567
AM
2733 disksize = cpu_to_le32(ei->i_disksize);
2734 if (disksize != raw_inode->i_size) {
5eef5607 2735@@ -3251,7 +3283,8 @@ int ext3_setattr(struct dentry *dentry,
76514441 2736 if (is_quota_modification(inode, attr))
78865d5b 2737 dquot_initialize(inode);
42bc425c
AM
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)) ||
537831f9 2741+ (ia_valid & ATTR_TAG && !tag_eq(attr->ia_tag, inode->i_tag))) {
d337f35e
JR
2742 handle_t *handle;
2743
2744 /* (user+group)*(old+new) structure, inode write (sb,
5eef5607 2745@@ -3273,6 +3306,8 @@ int ext3_setattr(struct dentry *dentry,
d337f35e
JR
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 }
f973f73f
AM
2754diff -NurpP --minimal linux-4.1.27/fs/ext3/ioctl.c linux-4.1.27-vs2.3.8.5.2/fs/ext3/ioctl.c
2755--- linux-4.1.27/fs/ext3/ioctl.c 2015-04-12 22:12:50.000000000 +0000
2756+++ linux-4.1.27-vs2.3.8.5.2/fs/ext3/ioctl.c 2016-07-05 04:41:47.000000000 +0000
1e8b8f9b 2757@@ -12,6 +12,34 @@
d337f35e 2758 #include <asm/uaccess.h>
1e8b8f9b 2759 #include "ext3.h"
d337f35e 2760
d4263eb0
JR
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+
ec22aa5c 2789 long ext3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
d4263eb0 2790 {
b00e13aa 2791 struct inode *inode = file_inode(filp);
1e8b8f9b 2792@@ -45,6 +73,11 @@ long ext3_ioctl(struct file *filp, unsig
ec22aa5c
AM
2793
2794 flags = ext3_mask_flags(inode->i_mode, flags);
d337f35e 2795
2380c486
JR
2796+ if (IS_BARRIER(inode)) {
2797+ vxwprintk_task(1, "messing with the barrier.");
2798+ return -EACCES;
2799+ }
2800+
2801 mutex_lock(&inode->i_mutex);
ec22aa5c 2802
2380c486 2803 /* Is it quota file? Do not allow user to mess with it */
1e8b8f9b 2804@@ -63,7 +96,9 @@ long ext3_ioctl(struct file *filp, unsig
d337f35e
JR
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 |
2380c486 2811+ EXT3_IMMUTABLE_FL | EXT3_IXUNLINK_FL))) {
ec22aa5c
AM
2812 if (!capable(CAP_LINUX_IMMUTABLE))
2813 goto flags_out;
2814 }
1e8b8f9b 2815@@ -88,7 +123,7 @@ long ext3_ioctl(struct file *filp, unsig
d4263eb0
JR
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
f973f73f
AM
2824diff -NurpP --minimal linux-4.1.27/fs/ext3/namei.c linux-4.1.27-vs2.3.8.5.2/fs/ext3/namei.c
2825--- linux-4.1.27/fs/ext3/namei.c 2015-07-06 20:41:42.000000000 +0000
2826+++ linux-4.1.27-vs2.3.8.5.2/fs/ext3/namei.c 2016-07-05 04:41:47.000000000 +0000
1e8b8f9b
AM
2827@@ -25,6 +25,8 @@
2828 */
2829
2380c486 2830 #include <linux/quotaops.h>
d337f35e 2831+#include <linux/vs_tag.h>
1e8b8f9b
AM
2832+
2833 #include "ext3.h"
d337f35e 2834 #include "namei.h"
1e8b8f9b 2835 #include "xattr.h"
09be7631 2836@@ -915,6 +917,7 @@ restart:
db55b927
AM
2837 submit_bh(READ | REQ_META | REQ_PRIO,
2838 bh);
2839 }
d337f35e 2840+ dx_propagate_tag(nd, inode);
db55b927 2841 }
2380c486
JR
2842 }
2843 if ((bh = bh_use[ra_ptr++]) == NULL)
c2e5f7c8 2844@@ -2568,6 +2571,7 @@ const struct inode_operations ext3_dir_i
a168f21d 2845 .listxattr = ext3_listxattr,
d337f35e
JR
2846 .removexattr = generic_removexattr,
2847 #endif
d337f35e 2848+ .sync_flags = ext3_sync_flags,
a168f21d 2849 .get_acl = ext3_get_acl,
bb20add7 2850 .set_acl = ext3_set_acl,
d337f35e 2851 };
f973f73f
AM
2852diff -NurpP --minimal linux-4.1.27/fs/ext3/super.c linux-4.1.27-vs2.3.8.5.2/fs/ext3/super.c
2853--- linux-4.1.27/fs/ext3/super.c 2015-07-06 20:41:42.000000000 +0000
2854+++ linux-4.1.27-vs2.3.8.5.2/fs/ext3/super.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 2855@@ -837,7 +837,8 @@ enum {
d337f35e 2856 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
2bf5ad28 2857 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
76514441
AM
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
d337f35e
JR
2862 };
2863
ec22aa5c 2864 static const match_table_t tokens = {
5eef5607 2865@@ -895,6 +896,9 @@ static const match_table_t tokens = {
76514441
AM
2866 {Opt_barrier, "barrier"},
2867 {Opt_nobarrier, "nobarrier"},
2380c486 2868 {Opt_resize, "resize"},
d337f35e
JR
2869+ {Opt_tag, "tag"},
2870+ {Opt_notag, "notag"},
2871+ {Opt_tagid, "tagid=%u"},
d337f35e 2872 {Opt_err, NULL},
d337f35e 2873 };
2380c486 2874
5eef5607 2875@@ -1067,6 +1071,20 @@ static int parse_options (char *options,
d337f35e
JR
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;
5eef5607 2896@@ -1792,6 +1810,9 @@ static int ext3_fill_super (struct super
d337f35e
JR
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) |
78865d5b 2904 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
d337f35e 2905
5eef5607 2906@@ -2690,6 +2711,14 @@ static int ext3_remount (struct super_bl
78865d5b 2907 if (test_opt(sb, ABORT))
2380c486
JR
2908 ext3_abort(sb, __func__, "Abort forced by user");
2909
d337f35e
JR
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);
d4263eb0
JR
2914+ err = -EINVAL;
2915+ goto restore_opts;
d337f35e 2916+ }
2380c486 2917+
d337f35e 2918 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
78865d5b
AM
2919 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
2920
f973f73f
AM
2921diff -NurpP --minimal linux-4.1.27/fs/ext4/ext4.h linux-4.1.27-vs2.3.8.5.2/fs/ext4/ext4.h
2922--- linux-4.1.27/fs/ext4/ext4.h 2016-07-05 04:28:30.000000000 +0000
2923+++ linux-4.1.27-vs2.3.8.5.2/fs/ext4/ext4.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 2924@@ -377,7 +377,10 @@ struct flex_groups {
2380c486 2925 #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
78865d5b
AM
2926 #define EXT4_EA_INODE_FL 0x00200000 /* Inode used for large EA */
2927 #define EXT4_EOFBLOCKS_FL 0x00400000 /* Blocks allocated beyond EOF */
b00e13aa 2928+#define EXT4_BARRIER_FL 0x04000000 /* Barrier for chroot() */
2380c486 2929+#define EXT4_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
b00e13aa
AM
2930 #define EXT4_INLINE_DATA_FL 0x10000000 /* Inode has inline data. */
2931+#define EXT4_COW_FL 0x20000000 /* Copy on Write marker */
2380c486 2932 #define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
d337f35e 2933
78865d5b 2934 #define EXT4_FL_USER_VISIBLE 0x004BDFFF /* User visible flags */
5eef5607 2935@@ -673,7 +676,7 @@ struct ext4_inode {
ec22aa5c
AM
2936 __le16 l_i_uid_high; /* these 2 fields */
2937 __le16 l_i_gid_high; /* were reserved2[0] */
42bc425c
AM
2938 __le16 l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
2939- __le16 l_i_reserved;
ec22aa5c 2940+ __le16 l_i_tag; /* Context Tag */
ec22aa5c
AM
2941 } linux2;
2942 struct {
2943 __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
5eef5607 2944@@ -793,6 +796,7 @@ do { \
ec22aa5c
AM
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
42bc425c 2949 #define i_checksum_lo osd2.linux2.l_i_checksum_lo
d337f35e 2950
ec22aa5c 2951 #elif defined(__GNU__)
f973f73f 2952@@ -1031,6 +1035,7 @@ struct ext4_inode_info {
ab30d09f
AM
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 */
f973f73f 2960@@ -2312,6 +2317,7 @@ extern int ext4_punch_hole(struct inode
5eef5607
AM
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 *);
d4263eb0 2964+extern int ext4_sync_flags(struct inode *, int, int);
5eef5607
AM
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 *);
f973f73f
AM
2968diff -NurpP --minimal linux-4.1.27/fs/ext4/file.c linux-4.1.27-vs2.3.8.5.2/fs/ext4/file.c
2969--- linux-4.1.27/fs/ext4/file.c 2016-07-05 04:28:30.000000000 +0000
2970+++ linux-4.1.27-vs2.3.8.5.2/fs/ext4/file.c 2016-07-05 04:41:47.000000000 +0000
2971@@ -659,5 +659,6 @@ const struct inode_operations ext4_file_
a168f21d 2972 .get_acl = ext4_get_acl,
bb20add7 2973 .set_acl = ext4_set_acl,
ec22aa5c 2974 .fiemap = ext4_fiemap,
d337f35e
JR
2975+ .sync_flags = ext4_sync_flags,
2976 };
2977
f973f73f
AM
2978diff -NurpP --minimal linux-4.1.27/fs/ext4/ialloc.c linux-4.1.27-vs2.3.8.5.2/fs/ext4/ialloc.c
2979--- linux-4.1.27/fs/ext4/ialloc.c 2016-07-05 04:28:30.000000000 +0000
2980+++ linux-4.1.27-vs2.3.8.5.2/fs/ext4/ialloc.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 2981@@ -21,6 +21,7 @@
e22b5178
AM
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"
5eef5607 2989@@ -753,6 +754,7 @@ struct inode *__ext4_new_inode(handle_t
76514441
AM
2990 inode->i_mode = mode;
2991 inode->i_uid = current_fsuid();
2992 inode->i_gid = dir->i_gid;
a4a22af8 2993+ i_tag_write(inode, dx_current_fstag(sb));
e22b5178 2994 } else
76514441 2995 inode_init_owner(inode, dir, mode);
09be7631 2996 dquot_initialize(inode);
f973f73f
AM
2997diff -NurpP --minimal linux-4.1.27/fs/ext4/inode.c linux-4.1.27-vs2.3.8.5.2/fs/ext4/inode.c
2998--- linux-4.1.27/fs/ext4/inode.c 2016-07-05 04:28:30.000000000 +0000
2999+++ linux-4.1.27-vs2.3.8.5.2/fs/ext4/inode.c 2016-07-05 04:41:47.000000000 +0000
5eef5607
AM
3000@@ -36,6 +36,7 @@
3001 #include <linux/printk.h>
3002 #include <linux/slab.h>
52afa9bd 3003 #include <linux/bitops.h>
d337f35e 3004+#include <linux/vs_tag.h>
ec22aa5c 3005
2380c486 3006 #include "ext4_jbd2.h"
d337f35e 3007 #include "xattr.h"
f973f73f 3008@@ -4020,12 +4021,15 @@ void ext4_set_inode_flags(struct inode *
d337f35e 3009 unsigned int flags = EXT4_I(inode)->i_flags;
52afa9bd 3010 unsigned int new_fl = 0;
978063ce 3011
d337f35e 3012+ if (flags & EXT4_IMMUTABLE_FL)
52afa9bd 3013+ new_fl |= S_IMMUTABLE;
2380c486 3014+ if (flags & EXT4_IXUNLINK_FL)
52afa9bd 3015+ new_fl |= S_IXUNLINK;
978063ce 3016+
d337f35e 3017 if (flags & EXT4_SYNC_FL)
52afa9bd 3018 new_fl |= S_SYNC;
d337f35e 3019 if (flags & EXT4_APPEND_FL)
52afa9bd 3020 new_fl |= S_APPEND;
d337f35e 3021- if (flags & EXT4_IMMUTABLE_FL)
52afa9bd 3022- new_fl |= S_IMMUTABLE;
d337f35e 3023 if (flags & EXT4_NOATIME_FL)
52afa9bd 3024 new_fl |= S_NOATIME;
d337f35e 3025 if (flags & EXT4_DIRSYNC_FL)
f973f73f 3026@@ -4033,31 +4037,52 @@ void ext4_set_inode_flags(struct inode *
5eef5607
AM
3027 if (test_opt(inode->i_sb, DAX))
3028 new_fl |= S_DAX;
ca5d134c 3029 inode_set_flags(inode, new_fl,
5eef5607
AM
3030- S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX);
3031+ S_IXUNLINK | S_IMMUTABLE | S_DAX |
ca5d134c 3032+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2380c486 3033+
978063ce 3034+ new_fl = 0;
2380c486 3035+ if (flags & EXT4_BARRIER_FL)
978063ce 3036+ new_fl |= V_BARRIER;
2380c486 3037+ if (flags & EXT4_COW_FL)
978063ce
JR
3038+ new_fl |= V_COW;
3039+
3040+ set_mask_bits(&inode->i_vflags,
3041+ V_BARRIER | V_COW, new_fl);
d337f35e
JR
3042 }
3043
2380c486
JR
3044 /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
3045 void ext4_get_inode_flags(struct ext4_inode_info *ei)
3046 {
76514441
AM
3047- unsigned int vfs_fl;
3048+ unsigned int vfs_fl, vfs_vf;
3049 unsigned long old_fl, new_fl;
2380c486 3050
76514441
AM
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);
ec22aa5c
AM
3082 }
3083
f973f73f 3084@@ -4161,8 +4186,10 @@ struct inode *ext4_iget(struct super_blo
42bc425c
AM
3085 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
3086 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
d337f35e 3087 }
42bc425c
AM
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));
537831f9
AM
3092+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
3093+ le16_to_cpu(raw_inode->i_raw_tag)));
f6c5ef8b 3094 set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
2380c486 3095
d33d7b00 3096 ext4_clear_state_flags(ei); /* Only relevant on 32-bit archs */
f973f73f 3097@@ -4467,8 +4494,10 @@ static int ext4_do_update_inode(handle_t
d337f35e 3098
2380c486 3099 ext4_get_inode_flags(ei);
d337f35e 3100 raw_inode->i_mode = cpu_to_le16(inode->i_mode);
42bc425c
AM
3101- i_uid = i_uid_read(inode);
3102- i_gid = i_gid_read(inode);
a4a22af8
AM
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));
ec22aa5c 3107 if (!(test_opt(inode->i_sb, NO_UID32))) {
42bc425c
AM
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));
f973f73f 3110@@ -4491,6 +4520,9 @@ static int ext4_do_update_inode(handle_t
d337f35e
JR
3111 raw_inode->i_uid_high = 0;
3112 raw_inode->i_gid_high = 0;
3113 }
3114+#ifdef CONFIG_TAGGING_INTERN
537831f9 3115+ raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
d337f35e
JR
3116+#endif
3117 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
2380c486
JR
3118
3119 EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode);
f973f73f 3120@@ -4735,7 +4767,8 @@ int ext4_setattr(struct dentry *dentry,
76514441 3121 if (is_quota_modification(inode, attr))
78865d5b 3122 dquot_initialize(inode);
42bc425c
AM
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)) ||
537831f9 3126+ (ia_valid & ATTR_TAG && !tag_eq(attr->ia_tag, inode->i_tag))) {
d337f35e
JR
3127 handle_t *handle;
3128
3129 /* (user+group)*(old+new) structure, inode write (sb,
f973f73f 3130@@ -4758,6 +4791,8 @@ int ext4_setattr(struct dentry *dentry,
d337f35e
JR
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 }
f973f73f
AM
3139diff -NurpP --minimal linux-4.1.27/fs/ext4/ioctl.c linux-4.1.27-vs2.3.8.5.2/fs/ext4/ioctl.c
3140--- linux-4.1.27/fs/ext4/ioctl.c 2015-07-06 20:41:42.000000000 +0000
3141+++ linux-4.1.27-vs2.3.8.5.2/fs/ext4/ioctl.c 2016-07-05 04:41:47.000000000 +0000
09be7631 3142@@ -14,6 +14,7 @@
2380c486 3143 #include <linux/mount.h>
ec22aa5c 3144 #include <linux/file.h>
5eef5607 3145 #include <linux/random.h>
d337f35e
JR
3146+#include <linux/vs_tag.h>
3147 #include <asm/uaccess.h>
2380c486
JR
3148 #include "ext4_jbd2.h"
3149 #include "ext4.h"
5eef5607
AM
3150@@ -206,6 +207,33 @@ static int uuid_is_zero(__u8 u[16])
3151 return 1;
09be7631 3152 }
db55b927 3153
d4263eb0
JR
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+
b00e13aa 3160+ handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
d4263eb0
JR
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 {
b00e13aa 3183 struct inode *inode = file_inode(filp);
5eef5607 3184@@ -239,6 +267,11 @@ long ext4_ioctl(struct file *filp, unsig
ec22aa5c
AM
3185
3186 flags = ext4_mask_flags(inode->i_mode, flags);
2380c486
JR
3187
3188+ if (IS_BARRIER(inode)) {
3189+ vxwprintk_task(1, "messing with the barrier.");
3190+ return -EACCES;
3191+ }
3192+
3193 err = -EPERM;
ec22aa5c
AM
3194 mutex_lock(&inode->i_mutex);
3195 /* Is it quota file? Do not allow user to mess with it */
5eef5607 3196@@ -256,7 +289,9 @@ long ext4_ioctl(struct file *filp, unsig
d337f35e
JR
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 |
2380c486
JR
3203+ EXT4_IMMUTABLE_FL | EXT4_IXUNLINK_FL))) {
3204 if (!capable(CAP_LINUX_IMMUTABLE))
3205 goto flags_out;
3206 }
f973f73f
AM
3207diff -NurpP --minimal linux-4.1.27/fs/ext4/namei.c linux-4.1.27-vs2.3.8.5.2/fs/ext4/namei.c
3208--- linux-4.1.27/fs/ext4/namei.c 2016-07-05 04:28:30.000000000 +0000
3209+++ linux-4.1.27-vs2.3.8.5.2/fs/ext4/namei.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 3210@@ -33,6 +33,7 @@
2380c486 3211 #include <linux/quotaops.h>
d337f35e
JR
3212 #include <linux/buffer_head.h>
3213 #include <linux/bio.h>
d337f35e 3214+#include <linux/vs_tag.h>
2380c486
JR
3215 #include "ext4.h"
3216 #include "ext4_jbd2.h"
d337f35e 3217
5eef5607 3218@@ -1447,6 +1448,7 @@ restart:
a168f21d
AM
3219 ll_rw_block(READ | REQ_META | REQ_PRIO,
3220 1, &bh);
2380c486 3221 }
d337f35e 3222+ dx_propagate_tag(nd, inode);
2380c486
JR
3223 }
3224 if ((bh = bh_use[ra_ptr++]) == NULL)
3225 goto next;
5eef5607 3226@@ -3905,6 +3907,7 @@ const struct inode_operations ext4_dir_i
a168f21d 3227 .get_acl = ext4_get_acl,
bb20add7 3228 .set_acl = ext4_set_acl,
d4263eb0 3229 .fiemap = ext4_fiemap,
d337f35e
JR
3230+ .sync_flags = ext4_sync_flags,
3231 };
d4263eb0
JR
3232
3233 const struct inode_operations ext4_special_inode_operations = {
f973f73f
AM
3234diff -NurpP --minimal linux-4.1.27/fs/ext4/super.c linux-4.1.27-vs2.3.8.5.2/fs/ext4/super.c
3235--- linux-4.1.27/fs/ext4/super.c 2016-07-05 04:28:30.000000000 +0000
3236+++ linux-4.1.27-vs2.3.8.5.2/fs/ext4/super.c 2016-07-05 04:41:47.000000000 +0000
3237@@ -1146,6 +1146,7 @@ enum {
78865d5b 3238 Opt_dioread_nolock, Opt_dioread_lock,
dd5f3080 3239 Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
5eef5607
AM
3240 Opt_max_dir_size_kb, Opt_nojournal_checksum,
3241+ Opt_tag, Opt_notag, Opt_tagid
d337f35e
JR
3242 };
3243
ec22aa5c 3244 static const match_table_t tokens = {
f973f73f 3245@@ -1231,6 +1232,9 @@ static const match_table_t tokens = {
1e8b8f9b
AM
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 */
d337f35e
JR
3249+ {Opt_tag, "tag"},
3250+ {Opt_notag, "notag"},
3251+ {Opt_tagid, "tagid=%u"},
d337f35e 3252 {Opt_err, NULL},
d337f35e 3253 };
2380c486 3254
f973f73f 3255@@ -1473,6 +1477,20 @@ static int handle_mount_opt(struct super
5eef5607
AM
3256 case Opt_nolazytime:
3257 sb->s_flags &= ~MS_LAZYTIME;
1e8b8f9b 3258 return 1;
d337f35e 3259+#ifndef CONFIG_TAGGING_NONE
1e8b8f9b
AM
3260+ case Opt_tag:
3261+ set_opt(sb, TAGGED);
3262+ return 1;
3263+ case Opt_notag:
3264+ clear_opt(sb, TAGGED);
3265+ return 1;
d337f35e
JR
3266+#endif
3267+#ifdef CONFIG_PROPAGATE
1e8b8f9b
AM
3268+ case Opt_tagid:
3269+ /* use args[0] */
3270+ set_opt(sb, TAGGED);
3271+ return 1;
d337f35e 3272+#endif
1e8b8f9b
AM
3273 }
3274
b00e13aa 3275 for (m = ext4_mount_opts; m->token != Opt_err; m++)
f973f73f 3276@@ -3652,6 +3670,9 @@ static int ext4_fill_super(struct super_
8d50a2ea 3277 clear_opt(sb, DELALLOC);
f6c5ef8b 3278 }
d337f35e
JR
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) |
78865d5b 3284 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
d337f35e 3285
f973f73f 3286@@ -4963,6 +4984,14 @@ static int ext4_remount(struct super_blo
ec22aa5c 3287 if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED)
93de0823 3288 ext4_abort(sb, "Abort forced by user");
2380c486 3289
d337f35e
JR
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);
d4263eb0
JR
3294+ err = -EINVAL;
3295+ goto restore_opts;
d337f35e 3296+ }
2380c486 3297+
d337f35e 3298 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
78865d5b 3299 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
d337f35e 3300
f973f73f
AM
3301diff -NurpP --minimal linux-4.1.27/fs/fcntl.c linux-4.1.27-vs2.3.8.5.2/fs/fcntl.c
3302--- linux-4.1.27/fs/fcntl.c 2015-04-12 22:12:50.000000000 +0000
3303+++ linux-4.1.27-vs2.3.8.5.2/fs/fcntl.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 3304@@ -22,6 +22,7 @@
2380c486 3305 #include <linux/pid_namespace.h>
92598135 3306 #include <linux/user_namespace.h>
bb20add7 3307 #include <linux/shmem_fs.h>
d337f35e
JR
3308+#include <linux/vs_limit.h>
3309
3310 #include <asm/poll.h>
3311 #include <asm/siginfo.h>
bb20add7 3312@@ -385,6 +386,8 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, f
d337f35e 3313
537831f9 3314 if (!f.file)
2380c486
JR
3315 goto out;
3316+ if (!vx_files_avail(1))
3317+ goto out;
3318
537831f9 3319 if (unlikely(f.file->f_mode & FMODE_PATH)) {
42bc425c 3320 if (!check_fcntl_cmd(cmd))
f973f73f
AM
3321diff -NurpP --minimal linux-4.1.27/fs/file.c linux-4.1.27-vs2.3.8.5.2/fs/file.c
3322--- linux-4.1.27/fs/file.c 2015-07-06 20:41:42.000000000 +0000
3323+++ linux-4.1.27-vs2.3.8.5.2/fs/file.c 2016-07-05 04:41:47.000000000 +0000
537831f9 3324@@ -22,6 +22,7 @@
2380c486
JR
3325 #include <linux/spinlock.h>
3326 #include <linux/rcupdate.h>
3327 #include <linux/workqueue.h>
3328+#include <linux/vs_limit.h>
3329
09be7631
JR
3330 int sysctl_nr_open __read_mostly = 1024*1024;
3331 int sysctl_nr_open_min = BITS_PER_LONG;
bb20add7 3332@@ -309,6 +310,8 @@ struct files_struct *dup_fd(struct files
2380c486
JR
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
bb20add7 3341@@ -369,9 +372,11 @@ static struct fdtable *close_files(struc
537831f9 3342 filp_close(file, files);
bb20add7 3343 cond_resched_rcu_qs();
537831f9
AM
3344 }
3345+ vx_openfd_dec(i);
3346 }
3347 i++;
3348 set >>= 1;
3349+ cond_resched();
3350 }
3351 }
bb20add7
AM
3352
3353@@ -487,6 +492,7 @@ repeat:
2380c486 3354 else
1e8b8f9b 3355 __clear_close_on_exec(fd, fdt);
2380c486
JR
3356 error = fd;
3357+ vx_openfd_inc(fd);
3358 #if 1
3359 /* Sanity check */
bb20add7
AM
3360 if (rcu_access_pointer(fdt->fd[fd]) != NULL) {
3361@@ -517,6 +523,7 @@ static void __put_unused_fd(struct files
537831f9
AM
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)
5eef5607 3369@@ -783,6 +790,8 @@ __releases(&files->file_lock)
537831f9
AM
3370
3371 if (tofree)
3372 filp_close(tofree, files);
3373+ else
3374+ vx_openfd_inc(fd); /* fd was unused */
3375
3376 return fd;
3377
f973f73f
AM
3378diff -NurpP --minimal linux-4.1.27/fs/file_table.c linux-4.1.27-vs2.3.8.5.2/fs/file_table.c
3379--- linux-4.1.27/fs/file_table.c 2015-07-06 20:41:42.000000000 +0000
3380+++ linux-4.1.27-vs2.3.8.5.2/fs/file_table.c 2016-07-05 04:41:47.000000000 +0000
92598135
AM
3381@@ -26,6 +26,8 @@
3382 #include <linux/hardirq.h>
3383 #include <linux/task_work.h>
2bf5ad28 3384 #include <linux/ima.h>
d337f35e
JR
3385+#include <linux/vs_limit.h>
3386+#include <linux/vs_context.h>
3387
a168f21d 3388 #include <linux/atomic.h>
d337f35e 3389
c2e5f7c8 3390@@ -137,6 +139,8 @@ struct file *get_empty_filp(void)
bb20add7 3391 mutex_init(&f->f_pos_lock);
d337f35e
JR
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:
bb20add7 3399@@ -219,6 +223,8 @@ static void __fput(struct file *file)
265de2f7
JR
3400 put_write_access(inode);
3401 __mnt_drop_write(mnt);
3402 }
d337f35e
JR
3403+ vx_files_dec(file);
3404+ file->f_xid = 0;
92598135
AM
3405 file->f_path.dentry = NULL;
3406 file->f_path.mnt = NULL;
b00e13aa 3407 file->f_inode = NULL;
bb20add7 3408@@ -305,6 +311,8 @@ void put_filp(struct file *file)
d337f35e 3409 {
2380c486 3410 if (atomic_long_dec_and_test(&file->f_count)) {
d337f35e
JR
3411 security_file_free(file);
3412+ vx_files_dec(file);
3413+ file->f_xid = 0;
d337f35e
JR
3414 file_free(file);
3415 }
c2e5f7c8 3416 }
f973f73f
AM
3417diff -NurpP --minimal linux-4.1.27/fs/fs_struct.c linux-4.1.27-vs2.3.8.5.2/fs/fs_struct.c
3418--- linux-4.1.27/fs/fs_struct.c 2015-04-12 22:12:50.000000000 +0000
3419+++ linux-4.1.27-vs2.3.8.5.2/fs/fs_struct.c 2016-07-05 04:41:47.000000000 +0000
ec22aa5c
AM
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>
d33d7b00 3425 #include "internal.h"
ec22aa5c 3426
92598135
AM
3427 /*
3428@@ -87,6 +88,7 @@ void free_fs_struct(struct fs_struct *fs
ec22aa5c 3429 {
92598135
AM
3430 path_put(&fs->root);
3431 path_put(&fs->pwd);
ec22aa5c
AM
3432+ atomic_dec(&vs_global_fs);
3433 kmem_cache_free(fs_cachep, fs);
3434 }
3435
537831f9 3436@@ -124,6 +126,7 @@ struct fs_struct *copy_fs_struct(struct
d33d7b00 3437 fs->pwd = old->pwd;
92598135 3438 path_get(&fs->pwd);
d33d7b00 3439 spin_unlock(&old->lock);
ec22aa5c
AM
3440+ atomic_inc(&vs_global_fs);
3441 }
3442 return fs;
3443 }
f973f73f
AM
3444diff -NurpP --minimal linux-4.1.27/fs/gfs2/file.c linux-4.1.27-vs2.3.8.5.2/fs/gfs2/file.c
3445--- linux-4.1.27/fs/gfs2/file.c 2015-07-06 20:41:42.000000000 +0000
3446+++ linux-4.1.27-vs2.3.8.5.2/fs/gfs2/file.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 3447@@ -137,6 +137,9 @@ static const u32 fsflags_to_gfs2[32] = {
e22b5178
AM
3448 [12] = GFS2_DIF_EXHASH,
3449 [14] = GFS2_DIF_INHERIT_JDATA,
92598135 3450 [17] = GFS2_DIF_TOPDIR,
e22b5178
AM
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] = {
5eef5607 3457@@ -147,6 +150,9 @@ static const u32 gfs2_to_fsflags[32] = {
e22b5178 3458 [gfs2fl_ExHash] = FS_INDEX_FL,
92598135 3459 [gfs2fl_TopLevel] = FS_TOPDIR_FL,
e22b5178
AM
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)
5eef5607 3467@@ -177,12 +183,18 @@ void gfs2_set_inode_flags(struct inode *
e22b5178
AM
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 |
a168f21d 3474+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC | S_NOSEC);
e22b5178 3475
a168f21d
AM
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;
e22b5178
AM
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)
5eef5607 3487@@ -190,6 +202,43 @@ void gfs2_set_inode_flags(struct inode *
e22b5178
AM
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 */
5eef5607 3531@@ -303,6 +352,37 @@ static int gfs2_set_flags(struct file *f
e22b5178
AM
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;
b00e13aa 3552+ gfs2_trans_add_meta(ip->i_gl, bh);
e22b5178
AM
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) {
f973f73f
AM
3569diff -NurpP --minimal linux-4.1.27/fs/gfs2/inode.h linux-4.1.27-vs2.3.8.5.2/fs/gfs2/inode.h
3570--- linux-4.1.27/fs/gfs2/inode.h 2015-04-12 22:12:50.000000000 +0000
3571+++ linux-4.1.27-vs2.3.8.5.2/fs/gfs2/inode.h 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 3572@@ -118,6 +118,7 @@ extern const struct file_operations gfs2
e22b5178
AM
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;
f973f73f
AM
3580diff -NurpP --minimal linux-4.1.27/fs/hostfs/hostfs.h linux-4.1.27-vs2.3.8.5.2/fs/hostfs/hostfs.h
3581--- linux-4.1.27/fs/hostfs/hostfs.h 2015-07-06 20:41:42.000000000 +0000
3582+++ linux-4.1.27-vs2.3.8.5.2/fs/hostfs/hostfs.h 2016-07-05 04:41:47.000000000 +0000
537831f9
AM
3583@@ -42,6 +42,7 @@ struct hostfs_iattr {
3584 unsigned short ia_mode;
3585 uid_t ia_uid;
3586 gid_t ia_gid;
61333608 3587+ vtag_t ia_tag;
537831f9
AM
3588 loff_t ia_size;
3589 struct timespec ia_atime;
3590 struct timespec ia_mtime;
f973f73f
AM
3591diff -NurpP --minimal linux-4.1.27/fs/inode.c linux-4.1.27-vs2.3.8.5.2/fs/inode.c
3592--- linux-4.1.27/fs/inode.c 2016-07-05 04:28:30.000000000 +0000
3593+++ linux-4.1.27-vs2.3.8.5.2/fs/inode.c 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 3594@@ -18,6 +18,7 @@
763640ca 3595 #include <linux/buffer_head.h> /* for inode_has_buffers */
db55b927 3596 #include <linux/ratelimit.h>
c2e5f7c8 3597 #include <linux/list_lru.h>
76514441 3598+#include <linux/vs_tag.h>
5eef5607 3599 #include <trace/events/writeback.h>
763640ca 3600 #include "internal.h"
76514441 3601
5eef5607 3602@@ -135,6 +136,8 @@ int inode_init_always(struct super_block
ec22aa5c
AM
3603 struct address_space *const mapping = &inode->i_data;
3604
3605 inode->i_sb = sb;
3606+
3607+ /* essential because of inode slab reuse */
ec22aa5c
AM
3608 inode->i_blkbits = sb->s_blocksize_bits;
3609 inode->i_flags = 0;
3610 atomic_set(&inode->i_count, 1);
5eef5607 3611@@ -144,6 +147,7 @@ int inode_init_always(struct super_block
537831f9
AM
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;
5eef5607 3619@@ -153,6 +157,7 @@ int inode_init_always(struct super_block
ec22aa5c
AM
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))
5eef5607 3627@@ -469,6 +474,8 @@ void __insert_inode_hash(struct inode *i
d337f35e 3628 }
763640ca 3629 EXPORT_SYMBOL(__insert_inode_hash);
d337f35e
JR
3630
3631+EXPORT_SYMBOL_GPL(__iget);
3632+
3633 /**
a168f21d 3634 * __remove_inode_hash - remove an inode from the hash
ab30d09f 3635 * @inode: inode to unhash
5eef5607 3636@@ -1857,9 +1864,11 @@ void init_special_inode(struct inode *in
2380c486
JR
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))
09be7631 3646 inode->i_fop = &pipefifo_fops;
2380c486 3647 else if (S_ISSOCK(mode))
5eef5607 3648@@ -1888,6 +1897,7 @@ void inode_init_owner(struct inode *inod
76514441
AM
3649 } else
3650 inode->i_gid = current_fsgid();
3651 inode->i_mode = mode;
8ce283e1 3652+ i_tag_write(inode, dx_current_fstag(inode->i_sb));
76514441
AM
3653 }
3654 EXPORT_SYMBOL(inode_init_owner);
763640ca 3655
f973f73f
AM
3656diff -NurpP --minimal linux-4.1.27/fs/ioctl.c linux-4.1.27-vs2.3.8.5.2/fs/ioctl.c
3657--- linux-4.1.27/fs/ioctl.c 2015-04-12 22:12:50.000000000 +0000
3658+++ linux-4.1.27-vs2.3.8.5.2/fs/ioctl.c 2016-07-05 04:41:47.000000000 +0000
ab30d09f 3659@@ -15,6 +15,9 @@
ec22aa5c
AM
3660 #include <linux/writeback.h>
3661 #include <linux/buffer_head.h>
3662 #include <linux/falloc.h>
d337f35e
JR
3663+#include <linux/proc_fs.h>
3664+#include <linux/vserver/inode.h>
3665+#include <linux/vs_tag.h>
3666
d337f35e
JR
3667 #include <asm/ioctls.h>
3668
f973f73f
AM
3669diff -NurpP --minimal linux-4.1.27/fs/jfs/file.c linux-4.1.27-vs2.3.8.5.2/fs/jfs/file.c
3670--- linux-4.1.27/fs/jfs/file.c 2015-07-06 20:41:42.000000000 +0000
3671+++ linux-4.1.27-vs2.3.8.5.2/fs/jfs/file.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 3672@@ -110,7 +110,8 @@ int jfs_setattr(struct dentry *dentry, s
76514441 3673 if (is_quota_modification(inode, iattr))
78865d5b 3674 dquot_initialize(inode);
537831f9
AM
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))) {
78865d5b
AM
3679 rc = dquot_transfer(inode, iattr);
3680 if (rc)
3681 return rc;
bb20add7 3682@@ -146,6 +147,7 @@ const struct inode_operations jfs_file_i
a168f21d 3683 .get_acl = jfs_get_acl,
bb20add7 3684 .set_acl = jfs_set_acl,
d337f35e
JR
3685 #endif
3686+ .sync_flags = jfs_sync_flags,
3687 };
3688
3689 const struct file_operations jfs_file_operations = {
f973f73f
AM
3690diff -NurpP --minimal linux-4.1.27/fs/jfs/ioctl.c linux-4.1.27-vs2.3.8.5.2/fs/jfs/ioctl.c
3691--- linux-4.1.27/fs/jfs/ioctl.c 2015-04-12 22:12:50.000000000 +0000
3692+++ linux-4.1.27-vs2.3.8.5.2/fs/jfs/ioctl.c 2016-07-05 04:41:47.000000000 +0000
537831f9 3693@@ -12,6 +12,7 @@
d337f35e 3694 #include <linux/time.h>
2380c486 3695 #include <linux/sched.h>
537831f9 3696 #include <linux/blkdev.h>
d337f35e
JR
3697+#include <linux/mount.h>
3698 #include <asm/current.h>
3699 #include <asm/uaccess.h>
3700
537831f9 3701@@ -56,6 +57,16 @@ static long jfs_map_ext2(unsigned long f
d4263eb0
JR
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 {
b00e13aa 3717 struct inode *inode = file_inode(filp);
537831f9 3718@@ -89,6 +100,11 @@ long jfs_ioctl(struct file *filp, unsign
2380c486
JR
3719 if (!S_ISDIR(inode->i_mode))
3720 flags &= ~JFS_DIRSYNC_FL;
d337f35e 3721
2380c486
JR
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;
537831f9 3730@@ -106,8 +122,8 @@ long jfs_ioctl(struct file *filp, unsign
d337f35e
JR
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 |
2380c486
JR
3737+ JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL))) {
3738 if (!capable(CAP_LINUX_IMMUTABLE)) {
3739 mutex_unlock(&inode->i_mutex);
3740 err = -EPERM;
537831f9 3741@@ -115,7 +131,7 @@ long jfs_ioctl(struct file *filp, unsign
d4263eb0
JR
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
f973f73f
AM
3750diff -NurpP --minimal linux-4.1.27/fs/jfs/jfs_dinode.h linux-4.1.27-vs2.3.8.5.2/fs/jfs/jfs_dinode.h
3751--- linux-4.1.27/fs/jfs/jfs_dinode.h 2015-04-12 22:12:50.000000000 +0000
3752+++ linux-4.1.27-vs2.3.8.5.2/fs/jfs/jfs_dinode.h 2016-07-05 04:41:47.000000000 +0000
2380c486
JR
3753@@ -161,9 +161,13 @@ struct dinode {
3754
d337f35e
JR
3755 #define JFS_APPEND_FL 0x01000000 /* writes to file may only append */
3756 #define JFS_IMMUTABLE_FL 0x02000000 /* Immutable file */
2380c486 3757+#define JFS_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
d337f35e
JR
3758
3759-#define JFS_FL_USER_VISIBLE 0x03F80000
2380c486 3760-#define JFS_FL_USER_MODIFIABLE 0x03F80000
d337f35e 3761+#define JFS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
2380c486 3762+#define JFS_COW_FL 0x20000000 /* Copy on Write marker */
d337f35e 3763+
2380c486
JR
3764+#define JFS_FL_USER_VISIBLE 0x07F80000
3765+#define JFS_FL_USER_MODIFIABLE 0x07F80000
3766 #define JFS_FL_INHERIT 0x03C80000
d337f35e
JR
3767
3768 /* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
f973f73f
AM
3769diff -NurpP --minimal linux-4.1.27/fs/jfs/jfs_filsys.h linux-4.1.27-vs2.3.8.5.2/fs/jfs/jfs_filsys.h
3770--- linux-4.1.27/fs/jfs/jfs_filsys.h 2015-04-12 22:12:50.000000000 +0000
3771+++ linux-4.1.27-vs2.3.8.5.2/fs/jfs/jfs_filsys.h 2016-07-05 04:41:47.000000000 +0000
537831f9 3772@@ -266,6 +266,7 @@
ec22aa5c
AM
3773 #define JFS_NAME_MAX 255
3774 #define JFS_PATH_MAX BPSIZE
bd427b06 3775
ec22aa5c 3776+#define JFS_TAGGED 0x00800000 /* Context Tagging */
bd427b06 3777
ec22aa5c
AM
3778 /*
3779 * file system state (superblock state)
f973f73f
AM
3780diff -NurpP --minimal linux-4.1.27/fs/jfs/jfs_imap.c linux-4.1.27-vs2.3.8.5.2/fs/jfs/jfs_imap.c
3781--- linux-4.1.27/fs/jfs/jfs_imap.c 2015-04-12 22:12:50.000000000 +0000
3782+++ linux-4.1.27-vs2.3.8.5.2/fs/jfs/jfs_imap.c 2016-07-05 04:41:47.000000000 +0000
78865d5b 3783@@ -46,6 +46,7 @@
ec22aa5c
AM
3784 #include <linux/pagemap.h>
3785 #include <linux/quotaops.h>
78865d5b 3786 #include <linux/slab.h>
ec22aa5c 3787+#include <linux/vs_tag.h>
bd427b06 3788
ec22aa5c
AM
3789 #include "jfs_incore.h"
3790 #include "jfs_inode.h"
c2e5f7c8 3791@@ -3047,6 +3048,8 @@ static int copy_from_dinode(struct dinod
ec22aa5c
AM
3792 {
3793 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3794 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
a4a22af8
AM
3795+ kuid_t kuid;
3796+ kgid_t kgid;
bd427b06 3797
ec22aa5c
AM
3798 jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
3799 jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
c2e5f7c8 3800@@ -3067,14 +3070,18 @@ static int copy_from_dinode(struct dinod
d337f35e 3801 }
f6c5ef8b 3802 set_nlink(ip, le32_to_cpu(dip->di_nlink));
bd427b06 3803
537831f9 3804- jfs_ip->saved_uid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
a4a22af8
AM
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);
ec22aa5c 3808+
a4a22af8 3809+ jfs_ip->saved_uid = INOTAG_KUID(DX_TAG(ip), kuid, kgid);
537831f9 3810 if (!uid_valid(sbi->uid))
ec22aa5c
AM
3811 ip->i_uid = jfs_ip->saved_uid;
3812 else {
3813 ip->i_uid = sbi->uid;
bd427b06
AM
3814 }
3815
537831f9 3816- jfs_ip->saved_gid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
a4a22af8 3817+ jfs_ip->saved_gid = INOTAG_KGID(DX_TAG(ip), kuid, kgid);
537831f9 3818 if (!gid_valid(sbi->gid))
d337f35e
JR
3819 ip->i_gid = jfs_ip->saved_gid;
3820 else {
c2e5f7c8 3821@@ -3139,16 +3146,14 @@ static void copy_to_dinode(struct dinode
d337f35e
JR
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);
537831f9
AM
3825- if (!uid_valid(sbi->uid))
3826- dip->di_uid = cpu_to_le32(i_uid_read(ip));
d337f35e 3827- else
537831f9
AM
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));
d337f35e 3832- else
537831f9
AM
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,
a4a22af8 3836+ TAGINO_KUID(DX_TAG(ip),
537831f9
AM
3837+ !uid_valid(sbi->uid) ? ip->i_uid : jfs_ip->saved_uid,
3838+ ip->i_tag)));
a4a22af8
AM
3839+ dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3840+ TAGINO_KGID(DX_TAG(ip),
537831f9
AM
3841+ !gid_valid(sbi->gid) ? ip->i_gid : jfs_ip->saved_gid,
3842+ ip->i_tag)));
2380c486 3843 jfs_get_inode_flags(jfs_ip);
d337f35e
JR
3844 /*
3845 * mode2 is only needed for storing the higher order bits.
f973f73f
AM
3846diff -NurpP --minimal linux-4.1.27/fs/jfs/jfs_inode.c linux-4.1.27-vs2.3.8.5.2/fs/jfs/jfs_inode.c
3847--- linux-4.1.27/fs/jfs/jfs_inode.c 2015-04-12 22:12:50.000000000 +0000
3848+++ linux-4.1.27-vs2.3.8.5.2/fs/jfs/jfs_inode.c 2016-07-05 04:41:47.000000000 +0000
e22b5178
AM
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"
bb20add7 3857@@ -33,26 +34,45 @@ void jfs_set_inode_flags(struct inode *i
d337f35e
JR
3858
3859 if (flags & JFS_IMMUTABLE_FL)
bb20add7 3860 new_fl |= S_IMMUTABLE;
2380c486
JR
3861+ if (flags & JFS_IXUNLINK_FL)
3862+ inode->i_flags |= S_IXUNLINK;
d337f35e
JR
3863+
3864+ if (flags & JFS_SYNC_FL)
3865+ inode->i_flags |= S_SYNC;
3866 if (flags & JFS_APPEND_FL)
bb20add7 3867 new_fl |= S_APPEND;
d337f35e 3868 if (flags & JFS_NOATIME_FL)
bb20add7 3869 new_fl |= S_NOATIME;
d337f35e 3870 if (flags & JFS_DIRSYNC_FL)
bb20add7 3871 new_fl |= S_DIRSYNC;
d337f35e 3872- if (flags & JFS_SYNC_FL)
bb20add7
AM
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);
2380c486 3877+
bb20add7 3878+ new_fl = 0;
2380c486 3879+ if (flags & JFS_BARRIER_FL)
bb20add7 3880+ new_fl |= V_BARRIER;
2380c486 3881+ if (flags & JFS_COW_FL)
bb20add7
AM
3882+ new_fl |= V_COW;
3883+
3884+ set_mask_bits(&inode->i_vflags,
3885+ V_BARRIER | V_COW, new_fl);
2380c486
JR
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)
bb20add7 3908@@ -61,6 +81,11 @@ void jfs_get_inode_flags(struct jfs_inod
2380c486
JR
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;
d337f35e
JR
3917 }
3918
3919 /*
f973f73f
AM
3920diff -NurpP --minimal linux-4.1.27/fs/jfs/jfs_inode.h linux-4.1.27-vs2.3.8.5.2/fs/jfs/jfs_inode.h
3921--- linux-4.1.27/fs/jfs/jfs_inode.h 2015-04-12 22:12:50.000000000 +0000
3922+++ linux-4.1.27-vs2.3.8.5.2/fs/jfs/jfs_inode.h 2016-07-05 04:41:47.000000000 +0000
2380c486
JR
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);
d337f35e 3926 extern void jfs_set_inode_flags(struct inode *);
d4263eb0 3927+extern int jfs_sync_flags(struct inode *, int, int);
d337f35e 3928 extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
78865d5b 3929 extern int jfs_setattr(struct dentry *, struct iattr *);
d337f35e 3930
f973f73f
AM
3931diff -NurpP --minimal linux-4.1.27/fs/jfs/namei.c linux-4.1.27-vs2.3.8.5.2/fs/jfs/namei.c
3932--- linux-4.1.27/fs/jfs/namei.c 2015-07-06 20:41:42.000000000 +0000
3933+++ linux-4.1.27-vs2.3.8.5.2/fs/jfs/namei.c 2016-07-05 04:41:47.000000000 +0000
d33d7b00 3934@@ -22,6 +22,7 @@
d337f35e
JR
3935 #include <linux/ctype.h>
3936 #include <linux/quotaops.h>
2380c486 3937 #include <linux/exportfs.h>
d337f35e
JR
3938+#include <linux/vs_tag.h>
3939 #include "jfs_incore.h"
3940 #include "jfs_superblock.h"
3941 #include "jfs_inode.h"
5eef5607 3942@@ -1459,6 +1460,7 @@ static struct dentry *jfs_lookup(struct
a168f21d 3943 jfs_err("jfs_lookup: iget failed on inum %d", (uint)inum);
d337f35e
JR
3944 }
3945
3946+ dx_propagate_tag(nd, ip);
d33d7b00
AM
3947 return d_splice_alias(ip, dentry);
3948 }
d337f35e 3949
5eef5607 3950@@ -1524,6 +1526,7 @@ const struct inode_operations jfs_dir_in
a168f21d 3951 .get_acl = jfs_get_acl,
bb20add7 3952 .set_acl = jfs_set_acl,
d337f35e
JR
3953 #endif
3954+ .sync_flags = jfs_sync_flags,
3955 };
3956
3957 const struct file_operations jfs_dir_operations = {
f973f73f
AM
3958diff -NurpP --minimal linux-4.1.27/fs/jfs/super.c linux-4.1.27-vs2.3.8.5.2/fs/jfs/super.c
3959--- linux-4.1.27/fs/jfs/super.c 2015-07-06 20:41:42.000000000 +0000
3960+++ linux-4.1.27-vs2.3.8.5.2/fs/jfs/super.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 3961@@ -206,7 +206,8 @@ enum {
d337f35e
JR
3962 Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
3963 Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
537831f9
AM
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,
d337f35e
JR
3967+ Opt_tag, Opt_notag, Opt_tagid
3968 };
3969
ec22aa5c 3970 static const match_table_t tokens = {
5eef5607 3971@@ -216,6 +217,10 @@ static const match_table_t tokens = {
d337f35e
JR
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"},
5eef5607 3982@@ -405,7 +410,20 @@ static int parse_options(char *options,
bb20add7 3983 pr_err("JFS: discard option not supported on device\n");
d337f35e
JR
3984 break;
3985 }
537831f9 3986-
d337f35e
JR
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:
bb20add7
AM
4002 printk("jfs: Unrecognized mount option \"%s\" or missing value\n",
4003 p);
5eef5607 4004@@ -437,6 +455,12 @@ static int jfs_remount(struct super_bloc
bb20add7 4005 if (!parse_options(data, sb, &newLVSize, &flag))
d337f35e 4006 return -EINVAL;
ab30d09f 4007
d337f35e
JR
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) {
bb20add7 4016 pr_err("JFS: resize requires volume to be mounted read-write\n");
5eef5607 4017@@ -520,6 +544,9 @@ static int jfs_fill_super(struct super_b
d337f35e
JR
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) {
537831f9 4026 pr_err("resize option for remount only\n");
f973f73f
AM
4027diff -NurpP --minimal linux-4.1.27/fs/libfs.c linux-4.1.27-vs2.3.8.5.2/fs/libfs.c
4028--- linux-4.1.27/fs/libfs.c 2016-07-05 04:28:30.000000000 +0000
4029+++ linux-4.1.27-vs2.3.8.5.2/fs/libfs.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 4030@@ -146,13 +146,14 @@ static inline unsigned char dt_type(stru
d337f35e
JR
4031 * both impossible due to the lock on directory.
4032 */
4033
c2e5f7c8 4034-int dcache_readdir(struct file *file, struct dir_context *ctx)
2380c486 4035+static inline int do_dcache_readdir_filter(struct file *filp,
c2e5f7c8 4036+ struct dir_context *ctx, int (*filter)(struct dentry *dentry))
d337f35e 4037 {
c2e5f7c8
JR
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;
bb20add7 4042 struct list_head *p, *q = &cursor->d_child;
c2e5f7c8
JR
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)
bb20add7 4049@@ -160,6 +161,8 @@ int dcache_readdir(struct file *file, st
c2e5f7c8
JR
4050
4051 for (p = q->next; p != &dentry->d_subdirs; p = p->next) {
bb20add7 4052 struct dentry *next = list_entry(p, struct dentry, d_child);
c2e5f7c8
JR
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);
bb20add7 4058@@ -182,8 +185,22 @@ int dcache_readdir(struct file *file, st
c2e5f7c8 4059 spin_unlock(&dentry->d_lock);
d337f35e
JR
4060 return 0;
4061 }
c2e5f7c8
JR
4062+
4063 EXPORT_SYMBOL(dcache_readdir);
d337f35e 4064
c2e5f7c8 4065+int dcache_readdir(struct file *filp, struct dir_context *ctx)
d337f35e 4066+{
c2e5f7c8 4067+ return do_dcache_readdir_filter(filp, ctx, NULL);
d337f35e
JR
4068+}
4069+
c2e5f7c8
JR
4070+EXPORT_SYMBOL(dcache_readdir_filter);
4071+
4072+int dcache_readdir_filter(struct file *filp, struct dir_context *ctx,
d337f35e
JR
4073+ int (*filter)(struct dentry *))
4074+{
c2e5f7c8 4075+ return do_dcache_readdir_filter(filp, ctx, filter);
d337f35e 4076+}
d337f35e
JR
4077+
4078 ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
4079 {
4080 return -EISDIR;
f973f73f
AM
4081diff -NurpP --minimal linux-4.1.27/fs/locks.c linux-4.1.27-vs2.3.8.5.2/fs/locks.c
4082--- linux-4.1.27/fs/locks.c 2016-07-05 04:28:30.000000000 +0000
4083+++ linux-4.1.27-vs2.3.8.5.2/fs/locks.c 2016-07-06 06:54:00.000000000 +0000
c2e5f7c8
JR
4084@@ -129,6 +129,8 @@
4085 #include <linux/hashtable.h>
4086 #include <linux/percpu.h>
4087 #include <linux/lglock.h>
d337f35e
JR
4088+#include <linux/vs_base.h>
4089+#include <linux/vs_limit.h>
4090
bb20add7
AM
4091 #define CREATE_TRACE_POINTS
4092 #include <trace/events/filelock.h>
f973f73f 4093@@ -251,11 +253,15 @@ static void locks_init_lock_heads(struct
d337f35e 4094 /* Allocate an empty lock structure. */
ab30d09f 4095 struct file_lock *locks_alloc_lock(void)
d337f35e 4096 {
a168f21d 4097- struct file_lock *fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
a0a3e0cf 4098+ struct file_lock *fl;
a168f21d
AM
4099
4100- if (fl)
4101- locks_init_lock_heads(fl);
a168f21d 4102+ fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
f973f73f 4103
a168f21d
AM
4104+ if (fl) {
4105+ locks_init_lock_heads(fl);
f973f73f 4106+ vx_locks_inc(fl);
a168f21d
AM
4107+ fl->fl_xid = -1;
4108+ }
4109 return fl;
4110 }
4111 EXPORT_SYMBOL_GPL(locks_alloc_lock);
f973f73f 4112@@ -307,6 +313,7 @@ void locks_init_lock(struct file_lock *f
a168f21d
AM
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);
f973f73f 4120@@ -324,6 +331,7 @@ void locks_copy_conflock(struct file_loc
bb20add7
AM
4121 new->fl_start = fl->fl_start;
4122 new->fl_end = fl->fl_end;
d337f35e
JR
4123 new->fl_lmops = fl->fl_lmops;
4124+ new->fl_xid = fl->fl_xid;
bb20add7 4125 new->fl_ops = NULL;
d337f35e 4126
bb20add7 4127 if (fl->fl_lmops) {
f973f73f 4128@@ -385,7 +393,10 @@ flock_make_lock(struct file *filp, unsig
d337f35e
JR
4129 fl->fl_flags = FL_FLOCK;
4130 fl->fl_type = type;
4131 fl->fl_end = OFFSET_MAX;
5eef5607 4132-
d337f35e
JR
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;
bb20add7
AM
4137 return fl;
4138 }
5eef5607 4139
f973f73f 4140@@ -507,6 +518,7 @@ static int lease_init(struct file *filp,
d337f35e 4141
bb20add7 4142 fl->fl_owner = filp;
d337f35e
JR
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;
f973f73f 4148@@ -526,6 +538,10 @@ static struct file_lock *lease_alloc(str
d337f35e 4149 if (fl == NULL)
2380c486 4150 return ERR_PTR(error);
d337f35e
JR
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);
d337f35e
JR
4156 error = lease_init(filp, type, fl);
4157 if (error) {
4158 locks_free_lock(fl);
f973f73f 4159@@ -904,6 +920,7 @@ static int flock_lock_inode(struct inode
d337f35e 4160 goto out;
5eef5607 4161 }
2380c486 4162
5eef5607
AM
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))
f973f73f 4167@@ -930,7 +947,8 @@ out:
d337f35e
JR
4168 return error;
4169 }
4170
2380c486
JR
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,
61333608 4173+ struct file_lock *conflock, vxid_t xid)
d337f35e 4174 {
5eef5607 4175 struct file_lock *fl, *tmp;
d337f35e 4176 struct file_lock *new_fl = NULL;
f973f73f 4177@@ -946,6 +964,9 @@ static int __posix_lock_file(struct inod
5eef5607
AM
4178 if (!ctx)
4179 return (request->fl_type == F_UNLCK) ? 0 : -ENOMEM;
d337f35e 4180
5eef5607
AM
4181+ if (xid)
4182+ vxd_assert(xid == vx_current_xid(),
4183+ "xid(%d) == current(%d)", xid, vx_current_xid());
d337f35e
JR
4184 /*
4185 * We may need two file_lock structures for this operation,
4186 * so we get them in advance to avoid races.
f973f73f 4187@@ -956,7 +977,11 @@ static int __posix_lock_file(struct inod
d337f35e
JR
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;
5eef5607 4192+ // vx_locks_inc(new_fl);
d337f35e
JR
4193 new_fl2 = locks_alloc_lock();
4194+ new_fl2->fl_xid = xid;
5eef5607 4195+ // vx_locks_inc(new_fl2);
d337f35e
JR
4196 }
4197
5eef5607 4198 spin_lock(&ctx->flc_lock);
f973f73f 4199@@ -1158,7 +1183,8 @@ static int __posix_lock_file(struct inod
2380c486 4200 int posix_lock_file(struct file *filp, struct file_lock *fl,
d337f35e
JR
4201 struct file_lock *conflock)
4202 {
b00e13aa
AM
4203- return __posix_lock_file(file_inode(filp), fl, conflock);
4204+ return __posix_lock_file(file_inode(filp),
d337f35e
JR
4205+ fl, conflock, filp->f_xid);
4206 }
2380c486 4207 EXPORT_SYMBOL(posix_lock_file);
d337f35e 4208
f973f73f 4209@@ -1175,7 +1201,7 @@ int posix_lock_inode_wait(struct inode *
5eef5607
AM
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);
f973f73f 4218@@ -1255,10 +1281,13 @@ int locks_mandatory_area(int read_write,
5eef5607
AM
4219 fl.fl_end = offset + count - 1;
4220
4221 for (;;) {
4222+ vxid_t f_xid = 0;
4223+
ca5d134c 4224 if (filp) {
bb20add7 4225 fl.fl_owner = filp;
ca5d134c
JR
4226 fl.fl_flags &= ~FL_SLEEP;
4227- error = __posix_lock_file(inode, &fl, NULL);
5eef5607
AM
4228+ f_xid = filp->f_xid;
4229+ error = __posix_lock_file(inode, &fl, NULL, f_xid);
ca5d134c
JR
4230 if (!error)
4231 break;
4232 }
f973f73f 4233@@ -1266,7 +1295,7 @@ int locks_mandatory_area(int read_write,
ca5d134c
JR
4234 if (sleep)
4235 fl.fl_flags |= FL_SLEEP;
4236 fl.fl_owner = current->files;
2380c486 4237- error = __posix_lock_file(inode, &fl, NULL);
5eef5607 4238+ error = __posix_lock_file(inode, &fl, NULL, f_xid);
2380c486 4239 if (error != FILE_LOCK_DEFERRED)
d337f35e 4240 break;
2380c486 4241 error = wait_event_interruptible(fl.fl_wait, !fl.fl_next);
f973f73f 4242@@ -2137,6 +2166,11 @@ int fcntl_setlk(unsigned int fd, struct
d337f35e
JR
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;
5eef5607 4249+ // vx_locks_inc(file_lock);
d337f35e
JR
4250+
4251 /*
4252 * This might block, so we do it before checking the inode.
4253 */
f973f73f 4254@@ -2279,6 +2313,11 @@ int fcntl_setlk64(unsigned int fd, struc
d337f35e
JR
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;
5eef5607 4261+ // vx_locks_inc(file_lock);
d337f35e
JR
4262+
4263 /*
4264 * This might block, so we do it before checking the inode.
4265 */
f973f73f 4266@@ -2591,8 +2630,11 @@ static int locks_show(struct seq_file *f
2380c486 4267
c2e5f7c8 4268 lock_get_status(f, fl, iter->li_pos, "");
2380c486
JR
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))
d337f35e 4273+ continue;
bb20add7 4274 lock_get_status(f, bfl, iter->li_pos, " ->");
2380c486 4275+ }
d337f35e 4276
2380c486 4277 return 0;
ab30d09f 4278 }
f973f73f
AM
4279diff -NurpP --minimal linux-4.1.27/fs/mount.h linux-4.1.27-vs2.3.8.5.2/fs/mount.h
4280--- linux-4.1.27/fs/mount.h 2015-04-12 22:12:50.000000000 +0000
4281+++ linux-4.1.27-vs2.3.8.5.2/fs/mount.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 4282@@ -65,6 +65,7 @@ struct mount {
bb20add7 4283 struct hlist_head mnt_pins;
5eef5607
AM
4284 struct fs_pin mnt_umount;
4285 struct dentry *mnt_ex_mountpoint;
61333608 4286+ vtag_t mnt_tag; /* tagging used for vfsmount */
db55b927
AM
4287 };
4288
92598135 4289 #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
f973f73f
AM
4290diff -NurpP --minimal linux-4.1.27/fs/namei.c linux-4.1.27-vs2.3.8.5.2/fs/namei.c
4291--- linux-4.1.27/fs/namei.c 2016-07-05 04:28:30.000000000 +0000
4292+++ linux-4.1.27-vs2.3.8.5.2/fs/namei.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 4293@@ -34,10 +34,20 @@
2380c486 4294 #include <linux/device_cgroup.h>
ec22aa5c 4295 #include <linux/fs_struct.h>
a168f21d 4296 #include <linux/posix_acl.h>
d337f35e 4297+#include <linux/proc_fs.h>
09be7631 4298+#include <linux/magic.h>
d337f35e
JR
4299+#include <linux/vserver/inode.h>
4300+#include <linux/vs_base.h>
4301+#include <linux/vs_tag.h>
4302+#include <linux/vs_cowbl.h>
2380c486
JR
4303+#include <linux/vs_device.h>
4304+#include <linux/vs_context.h>
4305+#include <linux/pid_namespace.h>
bb20add7 4306 #include <linux/hash.h>
d337f35e
JR
4307 #include <asm/uaccess.h>
4308
2bf5ad28 4309 #include "internal.h"
09be7631
JR
4310+#include "proc/internal.h"
4311 #include "mount.h"
4312
4313 /* [Feb-1997 T. Schoebel-Theuer]
5eef5607 4314@@ -283,6 +293,93 @@ static int check_acl(struct inode *inode
a168f21d
AM
4315 return -EAGAIN;
4316 }
d337f35e 4317
7e46296a 4318+static inline int dx_barrier(const struct inode *inode)
d337f35e 4319+{
2380c486
JR
4320+ if (IS_BARRIER(inode) && !vx_check(0, VS_ADMIN | VS_WATCH)) {
4321+ vxwprintk_task(1, "did hit the barrier.");
d337f35e
JR
4322+ return 1;
4323+ }
4324+ return 0;
4325+}
4326+
7e46296a 4327+static int __dx_permission(const struct inode *inode, int mask)
d337f35e
JR
4328+{
4329+ if (dx_barrier(inode))
4330+ return -EACCES;
d337f35e 4331+
2380c486
JR
4332+ if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) {
4333+ /* devpts is xid tagged */
4334+ if (S_ISDIR(inode->i_mode) ||
61333608 4335+ vx_check((vxid_t)i_tag_read(inode), VS_IDENT | VS_WATCH_P))
2380c486 4336+ return 0;
ba86f833 4337+
adc1caaa 4338+ /* just pretend we didn't find anything */
ba86f833 4339+ return -ENOENT;
2380c486
JR
4340+ }
4341+ else if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) {
4342+ struct proc_dir_entry *de = PDE(inode);
4343+
bb20add7
AM
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);
2380c486 4348+ goto out;
bb20add7 4349+ }
2380c486
JR
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+
c6ceaf95 4363+ rcu_read_lock();
2380c486
JR
4364+ tsk = pid_task(pid, PIDTYPE_PID);
4365+ vxdprintk(VXD_CBIT(tag, 0), "accessing %p[#%u]",
4366+ tsk, (tsk ? vx_task_xid(tsk) : 0));
c6ceaf95
AM
4367+ if (tsk &&
4368+ vx_check(vx_task_xid(tsk), VS_IDENT | VS_WATCH_P)) {
4369+ rcu_read_unlock();
2380c486 4370+ return 0;
c6ceaf95
AM
4371+ }
4372+ rcu_read_unlock();
2380c486
JR
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) ||
61333608 4381+ dx_check((vxid_t)i_tag_read(inode),
537831f9 4382+ DX_HOSTID | DX_ADMIN | DX_WATCH | DX_IDENT))
2380c486
JR
4383+ return 0;
4384+ }
4385+
4386+out:
d337f35e
JR
4387+ return -EACCES;
4388+}
4389+
7e46296a 4390+int dx_permission(const struct inode *inode, int mask)
2380c486
JR
4391+{
4392+ int ret = __dx_permission(inode, mask);
4393+ if (unlikely(ret)) {
ba86f833
AM
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]",
8ce283e1
AM
4399+ mask, inode->i_sb->s_id, inode,
4400+ i_tag_read(inode), inode->i_ino);
2380c486
JR
4401+ }
4402+ return ret;
4403+}
4404+
7e46296a 4405 /*
f6c5ef8b 4406 * This does the basic permission checking
7e46296a 4407 */
5eef5607 4408@@ -407,10 +504,14 @@ int __inode_permission(struct inode *ino
d337f35e
JR
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
2380c486
JR
4417+ retval = dx_permission(inode, mask);
4418+ if (retval)
d337f35e 4419+ return retval;
2380c486 4420+
a168f21d
AM
4421 retval = do_inode_permission(inode, mask);
4422 if (retval)
4423 return retval;
5eef5607
AM
4424@@ -1479,6 +1580,9 @@ static int lookup_fast(struct nameidata
4425 */
4426 if (negative)
4427 return -ENOENT;
be261992
AM
4428+
4429+ /* FIXME: check dx permission */
4430+
4431 path->mnt = mnt;
4432 path->dentry = dentry;
bb20add7 4433 if (likely(__follow_mount_rcu(nd, path, inode)))
5eef5607
AM
4434@@ -1509,6 +1613,8 @@ unlazy:
4435 dput(dentry);
4436 return -ENOENT;
be261992 4437 }
be261992 4438+
5eef5607 4439+ /* FIXME: check dx permission */
be261992
AM
4440 path->mnt = mnt;
4441 path->dentry = dentry;
42bc425c 4442 err = follow_managed(path, nd->flags);
5eef5607 4443@@ -2502,7 +2608,7 @@ static int may_delete(struct inode *dir,
d337f35e 4444 return -EPERM;
c2e5f7c8
JR
4445
4446 if (check_sticky(dir, inode) || IS_APPEND(inode) ||
4447- IS_IMMUTABLE(inode) || IS_SWAPFILE(inode))
4448+ IS_IXORUNLINK(inode) || IS_SWAPFILE(inode))
d337f35e
JR
4449 return -EPERM;
4450 if (isdir) {
bb20add7 4451 if (!d_is_dir(victim))
5eef5607 4452@@ -2584,19 +2690,25 @@ int vfs_create(struct inode *dir, struct
92598135 4453 bool want_excl)
a168f21d
AM
4454 {
4455 int error = may_create(dir, dentry);
a168f21d
AM
4456- if (error)
4457+ if (error) {
4458+ vxdprintk(VXD_CBIT(misc, 3), "may_create failed with %d", error);
537831f9 4459 return error;
a168f21d
AM
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);
537831f9 4470 return error;
a168f21d 4471+ }
92598135 4472 error = dir->i_op->create(dir, dentry, mode, want_excl);
a168f21d
AM
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 }
bb20add7 4479 EXPORT_SYMBOL(vfs_create);
5eef5607 4480@@ -2632,6 +2744,15 @@ static int may_open(struct path *path, i
ec22aa5c 4481 break;
2380c486 4482 }
d337f35e
JR
4483
4484+#ifdef CONFIG_VSERVER_COWBL
763640ca
JR
4485+ if (IS_COW(inode) &&
4486+ ((flag & O_ACCMODE) != O_RDONLY)) {
d337f35e
JR
4487+ if (IS_COW_LINK(inode))
4488+ return -EMLINK;
2380c486 4489+ inode->i_flags &= ~(S_IXUNLINK|S_IMMUTABLE);
d337f35e
JR
4490+ mark_inode_dirty(inode);
4491+ }
4492+#endif
ec22aa5c 4493 error = inode_permission(inode, acc_mode);
d337f35e
JR
4494 if (error)
4495 return error;
f973f73f 4496@@ -3115,6 +3236,16 @@ finish_open:
7b17263b 4497 }
92598135 4498 finish_open_created:
7b17263b
AM
4499 error = may_open(&nd->path, acc_mode, open_flag);
4500+#ifdef CONFIG_VSERVER_COWBL
4501+ if (error == -EMLINK) {
4502+ struct dentry *dentry;
537831f9 4503+ dentry = cow_break_link(name->name);
7b17263b
AM
4504+ if (IS_ERR(dentry))
4505+ error = PTR_ERR(dentry);
4506+ else
4507+ dput(dentry);
4508+ }
4509+#endif
4510 if (error)
92598135 4511 goto out;
bb20add7 4512
f973f73f 4513@@ -3247,6 +3378,9 @@ static struct file *path_openat(int dfd,
92598135 4514 int opened = 0;
7b17263b
AM
4515 int error;
4516
5eef5607 4517+#ifdef CONFIG_VSERVER_COWBL
7b17263b 4518+restart:
5eef5607 4519+#endif
92598135 4520 file = get_empty_filp();
b00e13aa
AM
4521 if (IS_ERR(file))
4522 return file;
f973f73f 4523@@ -3283,6 +3417,13 @@ static struct file *path_openat(int dfd,
92598135 4524 error = do_last(nd, &path, file, op, &opened, pathname);
7b17263b
AM
4525 put_link(nd, &link, cookie);
4526 }
4527+
4528+#ifdef CONFIG_VSERVER_COWBL
e915af4e 4529+ if (error == -EMLINK) {
5eef5607 4530+ path_cleanup(nd);
7b17263b
AM
4531+ goto restart;
4532+ }
4533+#endif
4534 out:
5eef5607
AM
4535 path_cleanup(nd);
4536 out2:
f973f73f 4537@@ -3401,6 +3542,11 @@ static struct dentry *filename_create(in
a168f21d
AM
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;
92598135 4547 fail:
a168f21d 4548 dput(dentry);
f973f73f 4549@@ -3970,7 +4116,7 @@ int vfs_link(struct dentry *old_dentry,
d337f35e
JR
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;
ec22aa5c 4556 if (!dir->i_op->link)
d337f35e 4557 return -EPERM;
f973f73f 4558@@ -4475,6 +4621,295 @@ int generic_readlink(struct dentry *dent
d337f35e 4559 }
bb20add7 4560 EXPORT_SYMBOL(generic_readlink);
d337f35e
JR
4561
4562+
4563+#ifdef CONFIG_VSERVER_COWBL
4564+
2380c486
JR
4565+static inline
4566+long do_cow_splice(struct file *in, struct file *out, size_t len)
4567+{
4568+ loff_t ppos = 0;
09be7631 4569+ loff_t opos = 0;
2380c486 4570+
09be7631 4571+ return do_splice_direct(in, &ppos, out, &opos, len, 0);
2380c486
JR
4572+}
4573+
d337f35e
JR
4574+struct dentry *cow_break_link(const char *pathname)
4575+{
b00e13aa 4576+ int ret, mode, pathlen, redo = 0, drop = 1;
d337f35e 4577+ struct nameidata old_nd, dir_nd;
e915af4e 4578+ struct path dir_path, *old_path, *new_path;
a168f21d 4579+ struct dentry *dir, *old_dentry, *new_dentry = NULL;
d337f35e
JR
4580+ struct file *old_file;
4581+ struct file *new_file;
4582+ char *to, *path, pad='\251';
4583+ loff_t size;
5eef5607
AM
4584+ struct filename *filename = getname_kernel(pathname);
4585+ struct filename *to_filename;
d337f35e 4586+
ba86f833
AM
4587+ vxdprintk(VXD_CBIT(misc, 1),
4588+ "cow_break_link(" VS_Q("%s") ")", pathname);
e915af4e 4589+
d337f35e 4590+ path = kmalloc(PATH_MAX, GFP_KERNEL);
2380c486 4591+ ret = -ENOMEM;
5eef5607 4592+ if (!path || IS_ERR(filename))
2380c486 4593+ goto out;
d337f35e 4594+
e915af4e 4595+ /* old_nd.path will have refs to dentry and mnt */
5eef5607 4596+ ret = filename_lookup(AT_FDCWD, filename, LOOKUP_FOLLOW, &old_nd);
a168f21d 4597+ vxdprintk(VXD_CBIT(misc, 2),
e915af4e 4598+ "do_path_lookup(old): %d", ret);
2380c486
JR
4599+ if (ret < 0)
4600+ goto out_free_path;
d337f35e 4601+
e915af4e
AM
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;
2380c486 4606+
e915af4e
AM
4607+ mode = old_dentry->d_inode->i_mode;
4608+ to = d_path(old_path, path, PATH_MAX-2);
d337f35e 4609+ pathlen = strlen(to);
ba86f833 4610+ vxdprintk(VXD_CBIT(misc, 2),
a168f21d
AM
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);
d337f35e 4615+
2380c486 4616+ to[pathlen + 1] = 0;
d337f35e 4617+retry:
a168f21d 4618+ new_dentry = NULL;
d337f35e 4619+ to[pathlen] = pad--;
a168f21d 4620+ ret = -ELOOP;
d337f35e
JR
4621+ if (pad <= '\240')
4622+ goto out_rel_old;
4623+
ba86f833 4624+ vxdprintk(VXD_CBIT(misc, 1), "temp copy " VS_Q("%s"), to);
e915af4e
AM
4625+
4626+ /* dir_nd.path will have refs to dentry and mnt */
5eef5607
AM
4627+ to_filename = getname_kernel(to);
4628+ ret = filename_lookup(AT_FDCWD, to_filename,
2380c486 4629+ LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE, &dir_nd);
5eef5607 4630+ putname(to_filename);
a168f21d 4631+ vxdprintk(VXD_CBIT(misc, 2), "do_path_lookup(new): %d", ret);
2380c486
JR
4632+ if (ret < 0)
4633+ goto retry;
4634+
e915af4e
AM
4635+ /* this puppy downs the dir inode mutex if successful.
4636+ dir_path will hold refs to dentry and mnt and
b00e13aa 4637+ we'll have write access to the mnt */
a168f21d
AM
4638+ new_dentry = kern_path_create(AT_FDCWD, to, &dir_path, 0);
4639+ if (!new_dentry || IS_ERR(new_dentry)) {
2380c486 4640+ path_put(&dir_nd.path);
a168f21d
AM
4641+ vxdprintk(VXD_CBIT(misc, 2),
4642+ "kern_path_create(new) failed with %ld",
4643+ PTR_ERR(new_dentry));
d337f35e
JR
4644+ goto retry;
4645+ }
2380c486 4646+ vxdprintk(VXD_CBIT(misc, 2),
a168f21d
AM
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+
e915af4e
AM
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 */
2380c486 4659+ dir = dir_nd.path.dentry;
d337f35e 4660+
e915af4e
AM
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);
d337f35e
JR
4668+ vxdprintk(VXD_CBIT(misc, 2),
4669+ "vfs_create(new): %d", ret);
4670+ if (ret == -EEXIST) {
2380c486 4671+ path_put(&dir_nd.path);
b00e13aa 4672+ mutex_unlock(&dir->d_inode->i_mutex);
e915af4e
AM
4673+ mnt_drop_write(new_path->mnt);
4674+ path_put(new_path);
4675+ new_dentry = NULL;
d337f35e
JR
4676+ goto retry;
4677+ }
2380c486
JR
4678+ else if (ret < 0)
4679+ goto out_unlock_new;
4680+
5eef5607 4681+ /* the old file went away */
2380c486 4682+ ret = -ENOENT;
a168f21d 4683+ if ((redo = d_unhashed(old_dentry)))
2380c486
JR
4684+ goto out_unlock_new;
4685+
e915af4e
AM
4686+ /* doesn't change refs for old_path */
4687+ old_file = dentry_open(old_path, O_RDONLY, current_cred());
d337f35e
JR
4688+ vxdprintk(VXD_CBIT(misc, 2),
4689+ "dentry_open(old): %p", old_file);
a168f21d
AM
4690+ if (IS_ERR(old_file)) {
4691+ ret = PTR_ERR(old_file);
2380c486
JR
4692+ goto out_unlock_new;
4693+ }
d337f35e 4694+
e915af4e
AM
4695+ /* doesn't change refs for new_path */
4696+ new_file = dentry_open(new_path, O_WRONLY, current_cred());
d337f35e
JR
4697+ vxdprintk(VXD_CBIT(misc, 2),
4698+ "dentry_open(new): %p", new_file);
a168f21d
AM
4699+ if (IS_ERR(new_file)) {
4700+ ret = PTR_ERR(new_file);
d337f35e 4701+ goto out_fput_old;
a168f21d 4702+ }
d337f35e 4703+
b00e13aa
AM
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+
5eef5607 4712+ size = i_size_read(old_file->f_path.dentry->d_inode);
2380c486
JR
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) {
d337f35e 4716+ goto out_fput_both;
2380c486
JR
4717+ } else if (ret < size) {
4718+ ret = -ENOSPC;
4719+ goto out_fput_both;
4720+ } else {
a168f21d
AM
4721+ struct inode *old_inode = old_dentry->d_inode;
4722+ struct inode *new_inode = new_dentry->d_inode;
2380c486
JR
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+
93de0823
AM
4729+ setattr_copy(new_inode, &attr);
4730+ mark_inode_dirty(new_inode);
2380c486 4731+ }
d337f35e 4732+
e915af4e 4733+ /* lock rename mutex */
a168f21d 4734+ mutex_lock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
2380c486
JR
4735+
4736+ /* drop out late */
4737+ ret = -ENOENT;
a168f21d 4738+ if ((redo = d_unhashed(old_dentry)))
2380c486
JR
4739+ goto out_unlock;
4740+
4741+ vxdprintk(VXD_CBIT(misc, 2),
ba86f833 4742+ "vfs_rename: [" VS_Q("%*s") ":%d] -> [" VS_Q("%*s") ":%d]",
a168f21d
AM
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,
eafa5b1d 4748+ old_dentry->d_parent->d_inode, old_dentry, NULL, 0);
d337f35e 4749+ vxdprintk(VXD_CBIT(misc, 2), "vfs_rename: %d", ret);
2380c486
JR
4750+
4751+out_unlock:
a168f21d 4752+ mutex_unlock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
d337f35e
JR
4753+
4754+out_fput_both:
4755+ vxdprintk(VXD_CBIT(misc, 3),
2380c486 4756+ "fput(new_file=%p[#%ld])", new_file,
4a036bed 4757+ atomic_long_read(&new_file->f_count));
d337f35e
JR
4758+ fput(new_file);
4759+
4760+out_fput_old:
4761+ vxdprintk(VXD_CBIT(misc, 3),
2380c486 4762+ "fput(old_file=%p[#%ld])", old_file,
4a036bed 4763+ atomic_long_read(&old_file->f_count));
d337f35e
JR
4764+ fput(old_file);
4765+
2380c486 4766+out_unlock_new:
e915af4e
AM
4767+ /* drop references from dir_nd.path */
4768+ path_put(&dir_nd.path);
4769+
b00e13aa
AM
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+ }
e915af4e 4777+
2380c486
JR
4778+ if (!ret)
4779+ goto out_redo;
4780+
4781+ /* error path cleanup */
c2e5f7c8 4782+ vfs_unlink(dir->d_inode, new_dentry, NULL);
2380c486
JR
4783+
4784+out_redo:
4785+ if (!redo)
4786+ goto out_rel_both;
e915af4e
AM
4787+
4788+ /* lookup dentry once again
4789+ old_nd.path will be freed as old_path in out_rel_old */
5eef5607 4790+ ret = filename_lookup(AT_FDCWD, filename, LOOKUP_FOLLOW, &old_nd);
2380c486
JR
4791+ if (ret)
4792+ goto out_rel_both;
d337f35e 4793+
e915af4e 4794+ /* drop reference on new_dentry */
a168f21d 4795+ dput(new_dentry);
e915af4e
AM
4796+ new_dentry = old_path->dentry;
4797+ dget(new_dentry);
2380c486 4798+ vxdprintk(VXD_CBIT(misc, 2),
763640ca 4799+ "do_path_lookup(redo): %p [" VS_Q("%.*s") ":%d]",
a168f21d
AM
4800+ new_dentry,
4801+ new_dentry->d_name.len, new_dentry->d_name.name,
4802+ new_dentry->d_name.len);
2380c486
JR
4803+
4804+out_rel_both:
e915af4e
AM
4805+ if (new_path)
4806+ path_put(new_path);
d337f35e 4807+out_rel_old:
e915af4e 4808+ path_put(old_path);
2380c486 4809+out_free_path:
d337f35e 4810+ kfree(path);
2380c486 4811+out:
a168f21d
AM
4812+ if (ret) {
4813+ dput(new_dentry);
4814+ new_dentry = ERR_PTR(ret);
4815+ }
5eef5607
AM
4816+ if (!IS_ERR(filename))
4817+ putname(filename);
a168f21d 4818+ vxdprintk(VXD_CBIT(misc, 3),
e915af4e 4819+ "cow_break_link returning with %p", new_dentry);
a168f21d 4820+ return new_dentry;
d337f35e
JR
4821+}
4822+
4823+#endif
1e8b8f9b
AM
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+}
bb20add7 4848+
265de2f7 4849+EXPORT_SYMBOL(vx_info_mnt_namespace);
d337f35e
JR
4850+
4851 /* get the link contents into pagecache */
4852 static char *page_getlink(struct dentry * dentry, struct page **ppage)
4853 {
f973f73f
AM
4854diff -NurpP --minimal linux-4.1.27/fs/namespace.c linux-4.1.27-vs2.3.8.5.2/fs/namespace.c
4855--- linux-4.1.27/fs/namespace.c 2016-07-05 04:28:30.000000000 +0000
4856+++ linux-4.1.27-vs2.3.8.5.2/fs/namespace.c 2016-07-05 04:41:47.000000000 +0000
978063ce 4857@@ -24,6 +24,11 @@
09be7631 4858 #include <linux/magic.h>
52afa9bd 4859 #include <linux/bootmem.h>
bb20add7 4860 #include <linux/task_work.h>
d337f35e 4861+#include <linux/vs_base.h>
d337f35e
JR
4862+#include <linux/vs_context.h>
4863+#include <linux/vs_tag.h>
2380c486
JR
4864+#include <linux/vserver/space.h>
4865+#include <linux/vserver/global.h>
d337f35e 4866 #include "pnode.h"
db55b927
AM
4867 #include "internal.h"
4868
5eef5607 4869@@ -927,6 +932,10 @@ vfs_kern_mount(struct file_system_type *
be261992
AM
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);
5eef5607 4880@@ -1002,6 +1011,7 @@ static struct mount *clone_mnt(struct mo
92598135
AM
4881 mnt->mnt.mnt_root = dget(root);
4882 mnt->mnt_mountpoint = mnt->mnt.mnt_root;
4883 mnt->mnt_parent = mnt;
c2e5f7c8
JR
4884+ mnt->mnt_tag = old->mnt_tag;
4885 lock_mount_hash();
92598135 4886 list_add_tail(&mnt->mnt_instance, &sb->s_mounts);
c2e5f7c8 4887 unlock_mount_hash();
5eef5607 4888@@ -1570,7 +1580,8 @@ out_unlock:
c2e5f7c8
JR
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 /*
5eef5607 4898@@ -2029,6 +2040,7 @@ static int do_change_type(struct path *p
763640ca
JR
4899 if (err)
4900 goto out_unlock;
4901 }
4902+ // mnt->mnt_flags = mnt_flags;
4903
c2e5f7c8 4904 lock_mount_hash();
763640ca 4905 for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))
5eef5607 4906@@ -2057,12 +2069,14 @@ static bool has_locked_children(struct m
ec22aa5c 4907 * do loopback mount.
d337f35e 4908 */
537831f9 4909 static int do_loopback(struct path *path, const char *old_name,
2380c486 4910- int recurse)
61333608 4911+ vtag_t tag, unsigned long flags, int mnt_flags)
d337f35e 4912 {
ec22aa5c 4913 struct path old_path;
09be7631
JR
4914 struct mount *mnt = NULL, *old, *parent;
4915 struct mountpoint *mp;
d337f35e 4916+ int recurse = flags & MS_REC;
b00e13aa 4917 int err;
2380c486 4918+
d337f35e 4919 if (!old_name || !*old_name)
b00e13aa
AM
4920 return -EINVAL;
4921 err = kern_path(old_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
5eef5607 4922@@ -2142,7 +2156,7 @@ static int change_mount_flags(struct vfs
ec22aa5c 4923 * on it - tough luck.
d337f35e 4924 */
ec22aa5c 4925 static int do_remount(struct path *path, int flags, int mnt_flags,
d337f35e 4926- void *data)
61333608 4927+ void *data, vxid_t xid)
d337f35e
JR
4928 {
4929 int err;
ec22aa5c 4930 struct super_block *sb = path->mnt->mnt_sb;
f973f73f 4931@@ -2650,6 +2664,7 @@ long do_mount(const char *dev_name, cons
ec22aa5c 4932 struct path path;
d337f35e
JR
4933 int retval = 0;
4934 int mnt_flags = 0;
61333608 4935+ vtag_t tag = 0;
d337f35e
JR
4936
4937 /* Discard magic */
4938 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
f973f73f 4939@@ -2675,6 +2690,12 @@ long do_mount(const char *dev_name, cons
ec22aa5c
AM
4940 if (!(flags & MS_NOATIME))
4941 mnt_flags |= MNT_RELATIME;
d337f35e 4942
2380c486
JR
4943+ if (dx_parse_tag(data_page, &tag, 1, &mnt_flags, &flags)) {
4944+ /* FIXME: bind and re-mounts get the tag flag? */
d337f35e
JR
4945+ if (flags & (MS_BIND|MS_REMOUNT))
4946+ flags |= MS_TAGID;
4947+ }
d337f35e
JR
4948+
4949 /* Separate the per-mountpoint flags */
d337f35e
JR
4950 if (flags & MS_NOSUID)
4951 mnt_flags |= MNT_NOSUID;
f973f73f 4952@@ -2699,15 +2720,17 @@ long do_mount(const char *dev_name, cons
bb20add7
AM
4953 mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK;
4954 }
d337f35e 4955
b00e13aa 4956+ if (!vx_capable(CAP_SYS_ADMIN, VXC_DEV_MOUNT))
d337f35e 4957+ mnt_flags |= MNT_NODEV;
c146dd73 4958 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN |
ec22aa5c
AM
4959 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
4960 MS_STRICTATIME);
d337f35e
JR
4961
4962 if (flags & MS_REMOUNT)
ec22aa5c 4963 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
d337f35e
JR
4964- data_page);
4965+ data_page, tag);
4966 else if (flags & MS_BIND)
ec22aa5c
AM
4967- retval = do_loopback(&path, dev_name, flags & MS_REC);
4968+ retval = do_loopback(&path, dev_name, tag, flags, mnt_flags);
d337f35e 4969 else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
ec22aa5c 4970 retval = do_change_type(&path, flags);
d337f35e 4971 else if (flags & MS_MOVE)
f973f73f 4972@@ -2824,6 +2847,7 @@ struct mnt_namespace *copy_mnt_ns(unsign
c2e5f7c8 4973 p = next_mnt(p, old);
d337f35e 4974 }
09be7631 4975 namespace_unlock();
2380c486
JR
4976+ atomic_inc(&vs_global_mnt_ns);
4977
4978 if (rootmnt)
4979 mntput(rootmnt);
f973f73f 4980@@ -2998,9 +3022,10 @@ SYSCALL_DEFINE2(pivot_root, const char _
db55b927
AM
4981 new_mnt = real_mount(new.mnt);
4982 root_mnt = real_mount(root.mnt);
09be7631
JR
4983 old_mnt = real_mount(old.mnt);
4984- if (IS_MNT_SHARED(old_mnt) ||
4985+ if ((IS_MNT_SHARED(old_mnt) ||
db55b927
AM
4986 IS_MNT_SHARED(new_mnt->mnt_parent) ||
4987- IS_MNT_SHARED(root_mnt->mnt_parent))
4988+ IS_MNT_SHARED(root_mnt->mnt_parent)) &&
50e68740 4989+ !vx_flags(VXF_STATE_SETUP, 0))
763640ca 4990 goto out4;
db55b927 4991 if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
763640ca 4992 goto out4;
f973f73f 4993@@ -3138,6 +3163,7 @@ void put_mnt_ns(struct mnt_namespace *ns
c2e5f7c8
JR
4994 if (!atomic_dec_and_test(&ns->count))
4995 return;
4996 drop_collected_mounts(&ns->root->mnt);
2380c486 4997+ atomic_dec(&vs_global_mnt_ns);
b00e13aa 4998 free_mnt_ns(ns);
2380c486 4999 }
db55b927 5000
f973f73f
AM
5001diff -NurpP --minimal linux-4.1.27/fs/nfs/client.c linux-4.1.27-vs2.3.8.5.2/fs/nfs/client.c
5002--- linux-4.1.27/fs/nfs/client.c 2016-07-05 04:28:30.000000000 +0000
5003+++ linux-4.1.27-vs2.3.8.5.2/fs/nfs/client.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 5004@@ -692,6 +692,9 @@ int nfs_init_server_rpcclient(struct nfs
2380c486
JR
5005 if (server->flags & NFS_MOUNT_SOFT)
5006 server->client->cl_softrtry = 1;
d337f35e
JR
5007
5008+ server->client->cl_tag = 0;
5009+ if (server->flags & NFS_MOUNT_TAGGED)
5010+ server->client->cl_tag = 1;
5011 return 0;
5012 }
92598135 5013 EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
5eef5607 5014@@ -870,6 +873,10 @@ static void nfs_server_set_fsinfo(struct
d337f35e
JR
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
ab30d09f 5024 server->time_delta = fsinfo->time_delta;
f973f73f
AM
5025diff -NurpP --minimal linux-4.1.27/fs/nfs/dir.c linux-4.1.27-vs2.3.8.5.2/fs/nfs/dir.c
5026--- linux-4.1.27/fs/nfs/dir.c 2015-07-06 20:41:42.000000000 +0000
5027+++ linux-4.1.27-vs2.3.8.5.2/fs/nfs/dir.c 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 5028@@ -37,6 +37,7 @@
2380c486 5029 #include <linux/sched.h>
ab30d09f 5030 #include <linux/kmemleak.h>
d33d7b00 5031 #include <linux/xattr.h>
d337f35e
JR
5032+#include <linux/vs_tag.h>
5033
d337f35e 5034 #include "delegation.h"
ab30d09f 5035 #include "iostat.h"
5eef5607 5036@@ -1411,6 +1412,7 @@ struct dentry *nfs_lookup(struct inode *
42bc425c
AM
5037 /* Success: notify readdir to use READDIRPLUS */
5038 nfs_advise_use_readdirplus(dir);
d337f35e
JR
5039
5040+ dx_propagate_tag(nd, inode);
5041 no_entry:
5eef5607 5042 res = d_splice_alias(inode, dentry);
d337f35e 5043 if (res != NULL) {
f973f73f
AM
5044diff -NurpP --minimal linux-4.1.27/fs/nfs/inode.c linux-4.1.27-vs2.3.8.5.2/fs/nfs/inode.c
5045--- linux-4.1.27/fs/nfs/inode.c 2016-07-05 04:28:30.000000000 +0000
5046+++ linux-4.1.27-vs2.3.8.5.2/fs/nfs/inode.c 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8
JR
5047@@ -38,6 +38,7 @@
5048 #include <linux/slab.h>
d33d7b00 5049 #include <linux/compat.h>
db55b927 5050 #include <linux/freezer.h>
d337f35e
JR
5051+#include <linux/vs_tag.h>
5052
d337f35e 5053 #include <asm/uaccess.h>
1e8b8f9b 5054
5eef5607 5055@@ -376,6 +377,8 @@ nfs_fhget(struct super_block *sb, struct
ec22aa5c
AM
5056 if (inode->i_state & I_NEW) {
5057 struct nfs_inode *nfsi = NFS_I(inode);
5058 unsigned long now = jiffies;
a4a22af8
AM
5059+ kuid_t kuid;
5060+ kgid_t kgid;
ec22aa5c
AM
5061
5062 /* We set i_ino for the few things that still rely on it,
5063 * such as stat(2) */
5eef5607 5064@@ -419,8 +422,8 @@ nfs_fhget(struct super_block *sb, struct
f6c5ef8b 5065 inode->i_version = 0;
ec22aa5c 5066 inode->i_size = 0;
f6c5ef8b 5067 clear_nlink(inode);
b00e13aa
AM
5068- inode->i_uid = make_kuid(&init_user_ns, -2);
5069- inode->i_gid = make_kgid(&init_user_ns, -2);
a4a22af8
AM
5070+ kuid = make_kuid(&init_user_ns, -2);
5071+ kgid = make_kgid(&init_user_ns, -2);
ec22aa5c
AM
5072 inode->i_blocks = 0;
5073 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
42bc425c 5074 nfsi->write_io = 0;
5eef5607 5075@@ -454,11 +457,11 @@ nfs_fhget(struct super_block *sb, struct
7e46296a 5076 else if (nfs_server_capable(inode, NFS_CAP_NLINK))
bb20add7 5077 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
ec22aa5c
AM
5078 if (fattr->valid & NFS_ATTR_FATTR_OWNER)
5079- inode->i_uid = fattr->uid;
a4a22af8 5080+ kuid = fattr->uid;
7e46296a 5081 else if (nfs_server_capable(inode, NFS_CAP_OWNER))
bb20add7 5082 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
ec22aa5c
AM
5083 if (fattr->valid & NFS_ATTR_FATTR_GROUP)
5084- inode->i_gid = fattr->gid;
a4a22af8 5085+ kgid = fattr->gid;
7e46296a 5086 else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
bb20add7 5087 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
42bc425c 5088 if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
5eef5607 5089@@ -469,6 +472,10 @@ nfs_fhget(struct super_block *sb, struct
ec22aa5c
AM
5090 */
5091 inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
5092 }
a4a22af8
AM
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);
ec22aa5c 5096+ /* maybe fattr->xid someday */
c2e5f7c8
JR
5097
5098 nfs_setsecurity(inode, fattr, label);
5099
5eef5607 5100@@ -608,6 +615,8 @@ void nfs_setattr_update_inode(struct ino
d337f35e
JR
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;
bb20add7
AM
5106 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS
5107 | NFS_INO_INVALID_ACL);
5eef5607
AM
5108 }
5109@@ -1221,7 +1230,9 @@ static int nfs_check_inode_attributes(st
d337f35e
JR
5110 struct nfs_inode *nfsi = NFS_I(inode);
5111 loff_t cur_size, new_isize;
2380c486 5112 unsigned long invalid = 0;
a4a22af8 5113-
b00e13aa
AM
5114+ kuid_t kuid;
5115+ kgid_t kgid;
5116+ ktag_t ktag;
d337f35e 5117
42bc425c 5118 if (nfs_have_delegated_attributes(inode))
a4a22af8 5119 return 0;
5eef5607
AM
5120@@ -1248,13 +1259,18 @@ static int nfs_check_inode_attributes(st
5121 if (nfsi->nrequests != 0)
5122 invalid &= ~NFS_INO_REVAL_PAGECACHE;
d337f35e 5123
a4a22af8
AM
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);
d337f35e
JR
5127+
5128 /* Have any file permissions changed? */
ec22aa5c 5129 if ((fattr->valid & NFS_ATTR_FATTR_MODE) && (inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO))
9474138d 5130 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
b00e13aa
AM
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))
ec22aa5c 5133 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
b00e13aa
AM
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))
ec22aa5c
AM
5136 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
5137+ /* maybe check for tag too? */
d337f35e
JR
5138
5139 /* Has the link count changed? */
ec22aa5c 5140 if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink)
9e3e8383 5141@@ -1628,6 +1644,9 @@ static int nfs_update_inode(struct inode
2380c486 5142 unsigned long now = jiffies;
7e46296a 5143 unsigned long save_cache_validity;
7b253bf8 5144 bool cache_revalidated = true;
a4a22af8
AM
5145+ kuid_t kuid;
5146+ kgid_t kgid;
5147+ ktag_t ktag;
d337f35e 5148
bb20add7 5149 dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
2380c486 5150 __func__, inode->i_sb->s_id, inode->i_ino,
9e3e8383
AM
5151@@ -1738,6 +1757,9 @@ static int nfs_update_inode(struct inode
5152 cache_revalidated = false;
5153 }
d337f35e 5154
a4a22af8
AM
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);
ec22aa5c
AM
5158
5159 if (fattr->valid & NFS_ATTR_FATTR_ATIME)
5160 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
9e3e8383
AM
5161@@ -1792,6 +1814,10 @@ static int nfs_update_inode(struct inode
5162 cache_revalidated = false;
5163 }
ec22aa5c 5164
a4a22af8
AM
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);
ec22aa5c
AM
5168+
5169 if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
5170 if (inode->i_nlink != fattr->nlink) {
5171 invalid |= NFS_INO_INVALID_ATTR;
f973f73f
AM
5172diff -NurpP --minimal linux-4.1.27/fs/nfs/nfs3xdr.c linux-4.1.27-vs2.3.8.5.2/fs/nfs/nfs3xdr.c
5173--- linux-4.1.27/fs/nfs/nfs3xdr.c 2016-07-05 04:28:30.000000000 +0000
5174+++ linux-4.1.27-vs2.3.8.5.2/fs/nfs/nfs3xdr.c 2016-07-05 04:41:47.000000000 +0000
78865d5b 5175@@ -20,6 +20,7 @@
d337f35e
JR
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
b00e13aa 5183@@ -558,7 +559,8 @@ static __be32 *xdr_decode_nfstime3(__be3
d33d7b00
AM
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)
d337f35e 5190 {
d33d7b00
AM
5191 u32 nbytes;
5192 __be32 *p;
b00e13aa 5193@@ -590,15 +592,19 @@ static void encode_sattr3(struct xdr_str
d33d7b00 5194 } else
d337f35e 5195 *p++ = xdr_zero;
d33d7b00 5196
d337f35e
JR
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;
b00e13aa 5201- *p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));
a4a22af8
AM
5202+ *p++ = cpu_to_be32(from_kuid(&init_user_ns,
5203+ TAGINO_KUID(tag, attr->ia_uid, attr->ia_tag)));
d33d7b00 5204 } else
d337f35e 5205 *p++ = xdr_zero;
d33d7b00 5206
d337f35e
JR
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;
b00e13aa 5211- *p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));
a4a22af8
AM
5212+ *p++ = cpu_to_be32(from_kgid(&init_user_ns,
5213+ TAGINO_KGID(tag, attr->ia_gid, attr->ia_tag)));
d33d7b00 5214 } else
d337f35e 5215 *p++ = xdr_zero;
d33d7b00 5216
b00e13aa 5217@@ -887,7 +893,7 @@ static void nfs3_xdr_enc_setattr3args(st
d33d7b00 5218 const struct nfs3_sattrargs *args)
d337f35e 5219 {
d33d7b00
AM
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 }
d337f35e 5225
b00e13aa 5226@@ -1037,13 +1043,13 @@ static void nfs3_xdr_enc_write3args(stru
d33d7b00
AM
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)
d337f35e 5232 {
d33d7b00
AM
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);
b00e13aa 5242@@ -1058,7 +1064,7 @@ static void nfs3_xdr_enc_create3args(str
d33d7b00
AM
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 /*
b00e13aa 5251@@ -1074,7 +1080,7 @@ static void nfs3_xdr_enc_mkdir3args(stru
d33d7b00
AM
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);
d337f35e 5257 }
d33d7b00
AM
5258
5259 /*
b00e13aa 5260@@ -1091,9 +1097,9 @@ static void nfs3_xdr_enc_mkdir3args(stru
d33d7b00
AM
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
b00e13aa 5272@@ -1102,7 +1108,7 @@ static void nfs3_xdr_enc_symlink3args(st
d33d7b00
AM
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 /*
b00e13aa 5281@@ -1130,24 +1136,24 @@ static void nfs3_xdr_enc_symlink3args(st
d33d7b00
AM
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:
b00e13aa 5311@@ -1162,7 +1168,7 @@ static void nfs3_xdr_enc_mknod3args(stru
d33d7b00 5312 const struct nfs3_mknodargs *args)
d337f35e 5313 {
d33d7b00
AM
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 /*
f973f73f
AM
5320diff -NurpP --minimal linux-4.1.27/fs/nfs/super.c linux-4.1.27-vs2.3.8.5.2/fs/nfs/super.c
5321--- linux-4.1.27/fs/nfs/super.c 2015-07-06 20:41:42.000000000 +0000
5322+++ linux-4.1.27-vs2.3.8.5.2/fs/nfs/super.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 5323@@ -54,6 +54,7 @@
b00e13aa 5324 #include <linux/parser.h>
1e8b8f9b
AM
5325 #include <linux/nsproxy.h>
5326 #include <linux/rcupdate.h>
d337f35e
JR
5327+#include <linux/vs_tag.h>
5328
d337f35e 5329 #include <asm/uaccess.h>
1e8b8f9b 5330
5eef5607 5331@@ -102,6 +103,7 @@ enum {
1e8b8f9b 5332 Opt_mountport,
ab30d09f 5333 Opt_mountvers,
ab30d09f
AM
5334 Opt_minorversion,
5335+ Opt_tagid,
5336
5337 /* Mount options that take string arguments */
1e8b8f9b 5338 Opt_nfsvers,
5eef5607 5339@@ -114,6 +116,9 @@ enum {
537831f9
AM
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
5eef5607 5349@@ -183,6 +188,10 @@ static const match_table_t nfs_mount_opt
537831f9
AM
5350 { Opt_fscache_uniq, "fsc=%s" },
5351 { Opt_local_lock, "local_lock=%s" },
ab30d09f
AM
5352
5353+ { Opt_tag, "tag" },
5354+ { Opt_notag, "notag" },
5355+ { Opt_tagid, "tagid=%u" },
5356+
537831f9
AM
5357 /* The following needs to be listed after all other options */
5358 { Opt_nfsvers, "v%s" },
ab30d09f 5359
5eef5607 5360@@ -639,6 +648,7 @@ static void nfs_show_mount_options(struc
2380c486 5361 { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
ec22aa5c
AM
5362 { NFS_MOUNT_UNSHARED, ",nosharecache", "" },
5363 { NFS_MOUNT_NORESVPORT, ",noresvport", "" },
d337f35e
JR
5364+ { NFS_MOUNT_TAGGED, ",tag", "" },
5365 { 0, NULL, NULL }
5366 };
5367 const struct proc_nfs_info *nfs_infop;
5eef5607 5368@@ -1321,6 +1331,14 @@ static int nfs_parse_mount_options(char
537831f9
AM
5369 case Opt_nomigration:
5370 mnt->options &= NFS_OPTION_MIGRATION;
ab30d09f
AM
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
5eef5607 5383@@ -1407,6 +1425,12 @@ static int nfs_parse_mount_options(char
ab30d09f
AM
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
f973f73f
AM
5396diff -NurpP --minimal linux-4.1.27/fs/nfsd/auth.c linux-4.1.27-vs2.3.8.5.2/fs/nfsd/auth.c
5397--- linux-4.1.27/fs/nfsd/auth.c 2015-04-12 22:12:50.000000000 +0000
5398+++ linux-4.1.27-vs2.3.8.5.2/fs/nfsd/auth.c 2016-07-05 04:41:47.000000000 +0000
bb20add7
AM
5399@@ -1,6 +1,7 @@
5400 /* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
2bf5ad28
AM
5401
5402 #include <linux/sched.h>
d337f35e 5403+#include <linux/vs_tag.h>
2bf5ad28 5404 #include "nfsd.h"
2380c486 5405 #include "auth.h"
d337f35e 5406
bb20add7 5407@@ -35,6 +36,9 @@ int nfsd_setuser(struct svc_rqst *rqstp,
d337f35e 5408
ec22aa5c
AM
5409 new->fsuid = rqstp->rq_cred.cr_uid;
5410 new->fsgid = rqstp->rq_cred.cr_gid;
5411+ /* FIXME: this desperately needs a tag :)
61333608 5412+ new->xid = (vxid_t)INOTAG_TAG(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid, 0);
ec22aa5c 5413+ */
d337f35e 5414
ec22aa5c
AM
5415 rqgi = rqstp->rq_cred.cr_group_info;
5416
f973f73f
AM
5417diff -NurpP --minimal linux-4.1.27/fs/nfsd/nfs3xdr.c linux-4.1.27-vs2.3.8.5.2/fs/nfsd/nfs3xdr.c
5418--- linux-4.1.27/fs/nfsd/nfs3xdr.c 2015-07-06 20:41:42.000000000 +0000
5419+++ linux-4.1.27-vs2.3.8.5.2/fs/nfsd/nfs3xdr.c 2016-07-05 04:41:47.000000000 +0000
b00e13aa 5420@@ -8,6 +8,7 @@
2bf5ad28
AM
5421
5422 #include <linux/namei.h>
b00e13aa 5423 #include <linux/sunrpc/svc_xprt.h>
d337f35e 5424+#include <linux/vs_tag.h>
2bf5ad28 5425 #include "xdr3.h"
2380c486 5426 #include "auth.h"
b00e13aa
AM
5427 #include "netns.h"
5428@@ -98,6 +99,8 @@ static __be32 *
d337f35e
JR
5429 decode_sattr3(__be32 *p, struct iattr *iap)
5430 {
5431 u32 tmp;
a4a22af8
AM
5432+ kuid_t kuid = GLOBAL_ROOT_UID;
5433+ kgid_t kgid = GLOBAL_ROOT_GID;
d337f35e
JR
5434
5435 iap->ia_valid = 0;
5436
b00e13aa
AM
5437@@ -106,15 +109,18 @@ decode_sattr3(__be32 *p, struct iattr *i
5438 iap->ia_mode = ntohl(*p++);
d337f35e
JR
5439 }
5440 if (*p++) {
b00e13aa 5441- iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++));
a4a22af8 5442+ kuid = make_kuid(&init_user_ns, ntohl(*p++));
b00e13aa
AM
5443 if (uid_valid(iap->ia_uid))
5444 iap->ia_valid |= ATTR_UID;
d337f35e
JR
5445 }
5446 if (*p++) {
b00e13aa 5447- iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++));
a4a22af8 5448+ kgid = make_kgid(&init_user_ns, ntohl(*p++));
b00e13aa
AM
5449 if (gid_valid(iap->ia_gid))
5450 iap->ia_valid |= ATTR_GID;
d337f35e 5451 }
a4a22af8
AM
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);
d337f35e
JR
5455 if (*p++) {
5456 u64 newsize;
5457
bb20add7 5458@@ -167,8 +173,12 @@ encode_fattr3(struct svc_rqst *rqstp, __
d337f35e 5459 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
bb20add7 5460 *p++ = htonl((u32) (stat->mode & S_IALLUGO));
d337f35e 5461 *p++ = htonl((u32) stat->nlink);
b00e13aa
AM
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,
a4a22af8 5465+ TAGINO_KUID(0 /* FIXME: DX_TAG(dentry->d_inode) */,
2380c486 5466+ stat->uid, stat->tag)));
b00e13aa 5467+ *p++ = htonl((u32) from_kgid(&init_user_ns,
a4a22af8 5468+ TAGINO_KGID(0 /* FIXME: DX_TAG(dentry->d_inode) */,
2380c486 5469+ stat->gid, stat->tag)));
d337f35e
JR
5470 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
5471 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
5472 } else {
f973f73f
AM
5473diff -NurpP --minimal linux-4.1.27/fs/nfsd/nfs4xdr.c linux-4.1.27-vs2.3.8.5.2/fs/nfsd/nfs4xdr.c
5474--- linux-4.1.27/fs/nfsd/nfs4xdr.c 2016-07-05 04:28:30.000000000 +0000
5475+++ linux-4.1.27-vs2.3.8.5.2/fs/nfsd/nfs4xdr.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 5476@@ -39,6 +39,7 @@
d33d7b00 5477 #include <linux/utsname.h>
a168f21d 5478 #include <linux/pagemap.h>
2380c486 5479 #include <linux/sunrpc/svcauth_gss.h>
d337f35e
JR
5480+#include <linux/vs_tag.h>
5481
d33d7b00
AM
5482 #include "idmap.h"
5483 #include "acl.h"
f973f73f 5484@@ -2629,12 +2630,16 @@ out_acl:
bb20add7 5485 *p++ = cpu_to_be32(stat.nlink);
d337f35e
JR
5486 }
5487 if (bmval1 & FATTR4_WORD1_OWNER) {
bb20add7
AM
5488- status = nfsd4_encode_user(xdr, rqstp, stat.uid);
5489+ status = nfsd4_encode_user(xdr, rqstp,
a4a22af8 5490+ TAGINO_KUID(DX_TAG(dentry->d_inode),
bb20add7 5491+ stat.uid, stat.tag));
d337f35e
JR
5492 if (status)
5493 goto out;
5494 }
5495 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
bb20add7
AM
5496- status = nfsd4_encode_group(xdr, rqstp, stat.gid);
5497+ status = nfsd4_encode_group(xdr, rqstp,
a4a22af8 5498+ TAGINO_KGID(DX_TAG(dentry->d_inode),
bb20add7 5499+ stat.gid, stat.tag));
d337f35e 5500 if (status)
f15949f2
JR
5501 goto out;
5502 }
f973f73f
AM
5503diff -NurpP --minimal linux-4.1.27/fs/nfsd/nfsxdr.c linux-4.1.27-vs2.3.8.5.2/fs/nfsd/nfsxdr.c
5504--- linux-4.1.27/fs/nfsd/nfsxdr.c 2015-07-06 20:41:42.000000000 +0000
5505+++ linux-4.1.27-vs2.3.8.5.2/fs/nfsd/nfsxdr.c 2016-07-05 04:41:47.000000000 +0000
b00e13aa
AM
5506@@ -7,6 +7,7 @@
5507 #include "vfs.h"
2bf5ad28 5508 #include "xdr.h"
2380c486 5509 #include "auth.h"
2bf5ad28 5510+#include <linux/vs_tag.h>
d337f35e
JR
5511
5512 #define NFSDDBG_FACILITY NFSDDBG_XDR
2bf5ad28 5513
b00e13aa 5514@@ -89,6 +90,8 @@ static __be32 *
d337f35e
JR
5515 decode_sattr(__be32 *p, struct iattr *iap)
5516 {
5517 u32 tmp, tmp1;
a4a22af8
AM
5518+ kuid_t kuid = GLOBAL_ROOT_UID;
5519+ kgid_t kgid = GLOBAL_ROOT_GID;
d337f35e
JR
5520
5521 iap->ia_valid = 0;
5522
b00e13aa
AM
5523@@ -101,15 +104,18 @@ decode_sattr(__be32 *p, struct iattr *ia
5524 iap->ia_mode = tmp;
d337f35e
JR
5525 }
5526 if ((tmp = ntohl(*p++)) != (u32)-1) {
b00e13aa 5527- iap->ia_uid = make_kuid(&init_user_ns, tmp);
a4a22af8 5528+ kuid = make_kuid(&init_user_ns, tmp);
b00e13aa
AM
5529 if (uid_valid(iap->ia_uid))
5530 iap->ia_valid |= ATTR_UID;
d337f35e
JR
5531 }
5532 if ((tmp = ntohl(*p++)) != (u32)-1) {
b00e13aa 5533- iap->ia_gid = make_kgid(&init_user_ns, tmp);
a4a22af8 5534+ kgid = make_kgid(&init_user_ns, tmp);
b00e13aa
AM
5535 if (gid_valid(iap->ia_gid))
5536 iap->ia_valid |= ATTR_GID;
d337f35e 5537 }
a4a22af8
AM
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);
d337f35e
JR
5541 if ((tmp = ntohl(*p++)) != (u32)-1) {
5542 iap->ia_valid |= ATTR_SIZE;
5543 iap->ia_size = tmp;
b00e13aa 5544@@ -154,8 +160,10 @@ encode_fattr(struct svc_rqst *rqstp, __b
d337f35e
JR
5545 *p++ = htonl(nfs_ftypes[type >> 12]);
5546 *p++ = htonl((u32) stat->mode);
5547 *p++ = htonl((u32) stat->nlink);
b00e13aa
AM
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,
a4a22af8 5551+ TAGINO_KUID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
b00e13aa 5552+ *p++ = htonl((u32) from_kgid(&init_user_ns,
a4a22af8 5553+ TAGINO_KGID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
d337f35e
JR
5554
5555 if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
5556 *p++ = htonl(NFS_MAXPATHLEN);
f973f73f
AM
5557diff -NurpP --minimal linux-4.1.27/fs/ocfs2/dlmglue.c linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/dlmglue.c
5558--- linux-4.1.27/fs/ocfs2/dlmglue.c 2016-07-05 04:28:30.000000000 +0000
5559+++ linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/dlmglue.c 2016-07-05 04:41:47.000000000 +0000
9e3e8383 5560@@ -2083,6 +2083,7 @@ static void __ocfs2_stuff_meta_lvb(struc
d337f35e 5561 lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
b00e13aa
AM
5562 lvb->lvb_iuid = cpu_to_be32(i_uid_read(inode));
5563 lvb->lvb_igid = cpu_to_be32(i_gid_read(inode));
a4a22af8 5564+ lvb->lvb_itag = cpu_to_be16(i_tag_read(inode));
d337f35e
JR
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 =
9e3e8383 5568@@ -2133,6 +2134,7 @@ static void ocfs2_refresh_inode_from_lvb
d337f35e 5569
b00e13aa
AM
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));
d337f35e 5573 inode->i_mode = be16_to_cpu(lvb->lvb_imode);
f6c5ef8b 5574 set_nlink(inode, be16_to_cpu(lvb->lvb_inlink));
d337f35e 5575 ocfs2_unpack_timespec(&inode->i_atime,
f973f73f
AM
5576diff -NurpP --minimal linux-4.1.27/fs/ocfs2/dlmglue.h linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/dlmglue.h
5577--- linux-4.1.27/fs/ocfs2/dlmglue.h 2015-04-12 22:12:50.000000000 +0000
5578+++ linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/dlmglue.h 2016-07-05 04:41:47.000000000 +0000
2380c486
JR
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;
d337f35e 5584+ __be16 lvb_itag;
2380c486
JR
5585+ __be16 lvb_reserved2;
5586 };
5587
ec22aa5c 5588 #define OCFS2_QINFO_LVB_VERSION 1
f973f73f
AM
5589diff -NurpP --minimal linux-4.1.27/fs/ocfs2/file.c linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/file.c
5590--- linux-4.1.27/fs/ocfs2/file.c 2016-07-05 04:28:30.000000000 +0000
5591+++ linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/file.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 5592@@ -1146,7 +1146,7 @@ int ocfs2_setattr(struct dentry *dentry,
763640ca 5593 attr->ia_valid &= ~ATTR_SIZE;
d337f35e
JR
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)
763640ca 5598 if (!(attr->ia_valid & OCFS2_VALID_ATTRS))
d337f35e 5599 return 0;
763640ca 5600
f973f73f
AM
5601diff -NurpP --minimal linux-4.1.27/fs/ocfs2/inode.c linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/inode.c
5602--- linux-4.1.27/fs/ocfs2/inode.c 2015-07-06 20:41:42.000000000 +0000
5603+++ linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/inode.c 2016-07-05 04:41:47.000000000 +0000
78865d5b 5604@@ -28,6 +28,7 @@
d337f35e
JR
5605 #include <linux/highmem.h>
5606 #include <linux/pagemap.h>
ec22aa5c 5607 #include <linux/quotaops.h>
d337f35e
JR
5608+#include <linux/vs_tag.h>
5609
5610 #include <asm/byteorder.h>
5611
537831f9 5612@@ -78,11 +79,13 @@ void ocfs2_set_inode_flags(struct inode
2380c486
JR
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);
d337f35e
JR
5619
5620 if (flags & OCFS2_IMMUTABLE_FL)
5621 inode->i_flags |= S_IMMUTABLE;
2380c486
JR
5622+ if (flags & OCFS2_IXUNLINK_FL)
5623+ inode->i_flags |= S_IXUNLINK;
d337f35e
JR
5624
5625 if (flags & OCFS2_SYNC_FL)
5626 inode->i_flags |= S_SYNC;
537831f9 5627@@ -92,25 +95,44 @@ void ocfs2_set_inode_flags(struct inode
2380c486
JR
5628 inode->i_flags |= S_NOATIME;
5629 if (flags & OCFS2_DIRSYNC_FL)
d337f35e 5630 inode->i_flags |= S_DIRSYNC;
2380c486
JR
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;
d337f35e
JR
5638 }
5639
2380c486
JR
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;
2380c486
JR
5673 }
5674
ec22aa5c 5675 struct inode *ocfs2_ilookup(struct super_block *sb, u64 blkno)
bb20add7 5676@@ -268,6 +290,8 @@ void ocfs2_populate_inode(struct inode *
d337f35e
JR
5677 struct super_block *sb;
5678 struct ocfs2_super *osb;
ec22aa5c 5679 int use_plocks = 1;
d337f35e
JR
5680+ uid_t uid;
5681+ gid_t gid;
5682
763640ca
JR
5683 sb = inode->i_sb;
5684 osb = OCFS2_SB(sb);
bb20add7 5685@@ -296,8 +320,12 @@ void ocfs2_populate_inode(struct inode *
d337f35e
JR
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);
b00e13aa
AM
5689- i_uid_write(inode, le32_to_cpu(fe->i_uid));
5690- i_gid_write(inode, le32_to_cpu(fe->i_gid));
d337f35e
JR
5691+ uid = le32_to_cpu(fe->i_uid);
5692+ gid = le32_to_cpu(fe->i_gid);
b00e13aa
AM
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));
d337f35e
JR
5697
5698 /* Fast symlinks will have i_size but no allocated clusters. */
42bc425c 5699 if (S_ISLNK(inode->i_mode) && !fe->i_clusters) {
f973f73f
AM
5700diff -NurpP --minimal linux-4.1.27/fs/ocfs2/inode.h linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/inode.h
5701--- linux-4.1.27/fs/ocfs2/inode.h 2015-04-12 22:12:50.000000000 +0000
5702+++ linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/inode.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 5703@@ -161,6 +161,7 @@ struct buffer_head *ocfs2_bread(struct i
d337f35e
JR
5704
5705 void ocfs2_set_inode_flags(struct inode *inode);
2380c486 5706 void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi);
d4263eb0 5707+int ocfs2_sync_flags(struct inode *inode, int, int);
d337f35e 5708
2380c486
JR
5709 static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode)
5710 {
f973f73f
AM
5711diff -NurpP --minimal linux-4.1.27/fs/ocfs2/ioctl.c linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/ioctl.c
5712--- linux-4.1.27/fs/ocfs2/ioctl.c 2015-04-12 22:12:50.000000000 +0000
5713+++ linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/ioctl.c 2016-07-05 04:41:47.000000000 +0000
1e8b8f9b 5714@@ -76,7 +76,41 @@ static int ocfs2_get_inode_attr(struct i
d337f35e
JR
5715 return status;
5716 }
5717
5718-static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
d4263eb0
JR
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+
d337f35e
JR
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);
09be7631
JR
5757@@ -116,6 +150,11 @@ static int ocfs2_set_inode_attr(struct i
5758 goto bail_unlock;
5759 }
2380c486
JR
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);
bb20add7 5769@@ -841,6 +880,7 @@ bail:
d4263eb0
JR
5770 return status;
5771 }
d337f35e 5772
d337f35e 5773+
d4263eb0
JR
5774 long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
5775 {
b00e13aa 5776 struct inode *inode = file_inode(filp);
f973f73f
AM
5777diff -NurpP --minimal linux-4.1.27/fs/ocfs2/namei.c linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/namei.c
5778--- linux-4.1.27/fs/ocfs2/namei.c 2016-07-05 04:28:30.000000000 +0000
5779+++ linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/namei.c 2016-07-05 04:41:47.000000000 +0000
ec22aa5c 5780@@ -41,6 +41,7 @@
d337f35e
JR
5781 #include <linux/slab.h>
5782 #include <linux/highmem.h>
ec22aa5c 5783 #include <linux/quotaops.h>
d337f35e
JR
5784+#include <linux/vs_tag.h>
5785
d337f35e 5786 #include <cluster/masklog.h>
763640ca 5787
f973f73f 5788@@ -509,6 +510,7 @@ static int __ocfs2_mknod_locked(struct i
93de0823 5789 struct ocfs2_extent_list *fel;
ec22aa5c 5790 u16 feat;
265de2f7 5791 struct ocfs2_inode_info *oi = OCFS2_I(inode);
a4a22af8 5792+ ktag_t ktag;
d337f35e 5793
7e46296a
AM
5794 *new_fe_bh = NULL;
5795
f973f73f 5796@@ -546,8 +548,13 @@ static int __ocfs2_mknod_locked(struct i
76514441 5797 fe->i_suballoc_loc = cpu_to_le64(suballoc_loc);
d337f35e 5798 fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
2380c486 5799 fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
b00e13aa
AM
5800- fe->i_uid = cpu_to_le32(i_uid_read(inode));
5801- fe->i_gid = cpu_to_le32(i_gid_read(inode));
d337f35e 5802+
a4a22af8
AM
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? */
ec22aa5c
AM
5809 fe->i_mode = cpu_to_le16(inode->i_mode);
5810 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
d337f35e 5811 fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
f973f73f
AM
5812diff -NurpP --minimal linux-4.1.27/fs/ocfs2/ocfs2.h linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/ocfs2.h
5813--- linux-4.1.27/fs/ocfs2/ocfs2.h 2015-04-12 22:12:50.000000000 +0000
5814+++ linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/ocfs2.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 5815@@ -286,6 +286,7 @@ enum ocfs2_mount_options
d33d7b00 5816 OCFS2_MOUNT_HB_GLOBAL = 1 << 14, /* Global heartbeat */
5eef5607
AM
5817
5818 OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT = 1 << 15, /* Journal Async Commit */
5819+ OCFS2_MOUNT_TAGGED = 1 << 16, /* use tagging */
d33d7b00
AM
5820 };
5821
bb20add7 5822 #define OCFS2_OSB_SOFT_RO 0x0001
f973f73f
AM
5823diff -NurpP --minimal linux-4.1.27/fs/ocfs2/ocfs2_fs.h linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/ocfs2_fs.h
5824--- linux-4.1.27/fs/ocfs2/ocfs2_fs.h 2015-04-12 22:12:50.000000000 +0000
5825+++ linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/ocfs2_fs.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 5826@@ -275,6 +275,11 @@
93de0823
AM
5827 #define OCFS2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
5828 #define OCFS2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */
2380c486 5829
93de0823
AM
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
f973f73f
AM
5838diff -NurpP --minimal linux-4.1.27/fs/ocfs2/super.c linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/super.c
5839--- linux-4.1.27/fs/ocfs2/super.c 2016-07-05 04:28:30.000000000 +0000
5840+++ linux-4.1.27-vs2.3.8.5.2/fs/ocfs2/super.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 5841@@ -192,6 +192,7 @@ enum {
76514441
AM
5842 Opt_resv_level,
5843 Opt_dir_resv_level,
5eef5607 5844 Opt_journal_async_commit,
d337f35e
JR
5845+ Opt_tag, Opt_notag, Opt_tagid,
5846 Opt_err,
5847 };
5848
5eef5607 5849@@ -224,6 +225,9 @@ static const match_table_t tokens = {
76514441
AM
5850 {Opt_resv_level, "resv_level=%u"},
5851 {Opt_dir_resv_level, "dir_resv_level=%u"},
5eef5607 5852 {Opt_journal_async_commit, "journal_async_commit"},
d337f35e 5853+ {Opt_tag, "tag"},
d337f35e
JR
5854+ {Opt_notag, "notag"},
5855+ {Opt_tagid, "tagid=%u"},
5856 {Opt_err, NULL}
5857 };
5858
5eef5607 5859@@ -675,6 +679,13 @@ static int ocfs2_remount(struct super_bl
d337f35e
JR
5860 goto out;
5861 }
5862
d4263eb0
JR
5863+ if ((osb->s_mount_opt & OCFS2_MOUNT_TAGGED) !=
5864+ (parsed_options.mount_opt & OCFS2_MOUNT_TAGGED)) {
d337f35e
JR
5865+ ret = -EINVAL;
5866+ mlog(ML_ERROR, "Cannot change tagging on remount\n");
5867+ goto out;
5868+ }
5869+
ab30d09f
AM
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 */
5eef5607 5873@@ -1164,6 +1175,9 @@ static int ocfs2_fill_super(struct super
d337f35e
JR
5874
5875 ocfs2_complete_mount_recovery(osb);
5876
5877+ if (osb->s_mount_opt & OCFS2_MOUNT_TAGGED)
5878+ sb->s_flags |= MS_TAGGED;
5879+
2380c486
JR
5880 if (ocfs2_mount_local(osb))
5881 snprintf(nodestr, sizeof(nodestr), "local");
5882 else
5eef5607
AM
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;
d337f35e
JR
5886 break;
5887+#ifndef CONFIG_TAGGING_NONE
5888+ case Opt_tag:
2380c486 5889+ mopt->mount_opt |= OCFS2_MOUNT_TAGGED;
d337f35e
JR
5890+ break;
5891+ case Opt_notag:
2380c486 5892+ mopt->mount_opt &= ~OCFS2_MOUNT_TAGGED;
d337f35e
JR
5893+ break;
5894+#endif
5895+#ifdef CONFIG_PROPAGATE
5896+ case Opt_tagid:
5897+ /* use args[0] */
2380c486 5898+ mopt->mount_opt |= OCFS2_MOUNT_TAGGED;
d337f35e
JR
5899+ break;
5900+#endif
5901 default:
5902 mlog(ML_ERROR,
5903 "Unrecognized mount option \"%s\" "
f973f73f
AM
5904diff -NurpP --minimal linux-4.1.27/fs/open.c linux-4.1.27-vs2.3.8.5.2/fs/open.c
5905--- linux-4.1.27/fs/open.c 2016-07-05 04:28:31.000000000 +0000
5906+++ linux-4.1.27-vs2.3.8.5.2/fs/open.c 2016-07-05 05:07:17.000000000 +0000
b00e13aa 5907@@ -31,6 +31,11 @@
2bf5ad28 5908 #include <linux/ima.h>
93de0823 5909 #include <linux/dnotify.h>
b00e13aa 5910 #include <linux/compat.h>
d337f35e
JR
5911+#include <linux/vs_base.h>
5912+#include <linux/vs_limit.h>
d337f35e
JR
5913+#include <linux/vs_tag.h>
5914+#include <linux/vs_cowbl.h>
78865d5b 5915+#include <linux/vserver/dlimit.h>
d337f35e 5916
2bf5ad28
AM
5917 #include "internal.h"
5918
c2e5f7c8 5919@@ -68,6 +73,11 @@ long vfs_truncate(struct path *path, lof
b00e13aa
AM
5920 struct inode *inode;
5921 long error;
5922
76514441 5923+#ifdef CONFIG_VSERVER_COWBL
b00e13aa 5924+ error = cow_check_and_break(path);
d337f35e 5925+ if (error)
b00e13aa 5926+ goto out;
76514441 5927+#endif
b00e13aa 5928 inode = path->dentry->d_inode;
d337f35e 5929
a168f21d 5930 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
5eef5607 5931@@ -546,6 +556,13 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
b00e13aa
AM
5932 unsigned int lookup_flags = LOOKUP_FOLLOW;
5933 retry:
5934 error = user_path_at(dfd, filename, lookup_flags, &path);
a168f21d 5935+#ifdef CONFIG_VSERVER_COWBL
b00e13aa 5936+ if (!error) {
a168f21d 5937+ error = cow_check_and_break(&path);
b00e13aa
AM
5938+ if (error)
5939+ path_put(&path);
5940+ }
a168f21d 5941+#endif
b00e13aa 5942 if (!error) {
a168f21d
AM
5943 error = chmod_common(&path, mode);
5944 path_put(&path);
5eef5607 5945@@ -580,13 +597,15 @@ retry_deleg:
42bc425c
AM
5946 if (!uid_valid(uid))
5947 return -EINVAL;
d337f35e 5948 newattrs.ia_valid |= ATTR_UID;
42bc425c 5949- newattrs.ia_uid = uid;
8ce283e1
AM
5950+ newattrs.ia_uid = make_kuid(&init_user_ns,
5951+ dx_map_uid(user));
d337f35e
JR
5952 }
5953 if (group != (gid_t) -1) {
42bc425c
AM
5954 if (!gid_valid(gid))
5955 return -EINVAL;
d337f35e 5956 newattrs.ia_valid |= ATTR_GID;
42bc425c 5957- newattrs.ia_gid = gid;
8ce283e1
AM
5958+ newattrs.ia_gid = make_kgid(&init_user_ns,
5959+ dx_map_gid(group));
d337f35e
JR
5960 }
5961 if (!S_ISDIR(inode->i_mode))
2380c486 5962 newattrs.ia_valid |=
f973f73f 5963@@ -624,6 +643,10 @@ retry:
2380c486 5964 error = mnt_want_write(path.mnt);
d337f35e 5965 if (error)
2380c486 5966 goto out_release;
d337f35e 5967+#ifdef CONFIG_VSERVER_COWBL
2380c486 5968+ error = cow_check_and_break(&path);
d337f35e 5969+ if (!error)
d337f35e 5970+#endif
2bf5ad28 5971 error = chown_common(&path, user, group);
2380c486
JR
5972 mnt_drop_write(path.mnt);
5973 out_release:
f973f73f
AM
5974diff -NurpP --minimal linux-4.1.27/fs/proc/array.c linux-4.1.27-vs2.3.8.5.2/fs/proc/array.c
5975--- linux-4.1.27/fs/proc/array.c 2016-07-05 04:28:31.000000000 +0000
5976+++ linux-4.1.27-vs2.3.8.5.2/fs/proc/array.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 5977@@ -83,6 +83,8 @@
2380c486 5978 #include <linux/tracehook.h>
5eef5607 5979 #include <linux/string_helpers.h>
42bc425c 5980 #include <linux/user_namespace.h>
d337f35e
JR
5981+#include <linux/vs_context.h>
5982+#include <linux/vs_network.h>
5983
d337f35e 5984 #include <asm/pgtable.h>
2380c486 5985 #include <asm/processor.h>
5eef5607 5986@@ -146,6 +148,9 @@ static inline void task_state(struct seq
2380c486
JR
5987 ppid = pid_alive(p) ?
5988 task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
5eef5607 5989
2380c486
JR
5990+ if (unlikely(vx_current_initpid(p->pid)))
5991+ ppid = 0;
5992+
5eef5607
AM
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
bb20add7 5997 render_sigset_t(m, "SigCgt:\t", &caught);
2380c486
JR
5998 }
5999
bb20add7 6000-static void render_cap_t(struct seq_file *m, const char *header,
2380c486 6001- kernel_cap_t *a)
bb20add7 6002+void render_cap_t(struct seq_file *m, const char *header,
2380c486 6003+ struct vx_info *vxi, kernel_cap_t *a)
d337f35e 6004 {
2380c486
JR
6005 unsigned __capi;
6006
5eef5607 6007@@ -310,10 +315,11 @@ static inline void task_cap(struct seq_f
bb20add7
AM
6008 cap_bset = cred->cap_bset;
6009 rcu_read_unlock();
2380c486 6010
ec22aa5c
AM
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);
d337f35e
JR
6020 }
6021
b00e13aa 6022 static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
5eef5607
AM
6023@@ -340,6 +346,43 @@ static void task_cpus_allowed(struct seq
6024 cpumask_pr_args(&task->cpus_allowed));
2380c486
JR
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' : '-'),
c2e5f7c8
JR
6046+ task->nsproxy->pid_ns_for_children,
6047+ (task->nsproxy->pid_ns_for_children ==
6048+ init_task.nsproxy->pid_ns_for_children ? 'I' : '-'),
2380c486
JR
6049+ task->nsproxy->net_ns,
6050+ (task->nsproxy->net_ns == init_task.nsproxy->net_ns ? 'I' : '-'));
6051+ return 0;
6052+}
d337f35e 6053+
2380c486
JR
6054+void task_vs_id(struct seq_file *m, struct task_struct *task)
6055+{
d337f35e 6056+ if (task_vx_flags(task, VXF_HIDE_VINFO, 0))
2380c486
JR
6057+ return;
6058+
bb20add7
AM
6059+ seq_printf(m, "VxID:\t%d\n", vx_task_xid(task));
6060+ seq_printf(m, "NxID:\t%d\n", nx_task_nid(task));
2380c486
JR
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 {
5eef5607 6067@@ -357,6 +400,7 @@ int proc_pid_status(struct seq_file *m,
b00e13aa 6068 task_seccomp(m, task);
2bf5ad28 6069 task_cpus_allowed(m, task);
2380c486
JR
6070 cpuset_task_status_allowed(m, task);
6071+ task_vs_id(m, task);
152aeb71
JR
6072 task_context_switch_counts(m, task);
6073 return 0;
6074 }
5eef5607 6075@@ -460,6 +504,17 @@ static int do_task_stat(struct seq_file
d337f35e 6076 /* convert nsec -> ticks */
bb20add7 6077 start_time = nsec_to_clock_t(task->real_start_time);
d337f35e
JR
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+
1e8b8f9b
AM
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);
f973f73f
AM
6093diff -NurpP --minimal linux-4.1.27/fs/proc/base.c linux-4.1.27-vs2.3.8.5.2/fs/proc/base.c
6094--- linux-4.1.27/fs/proc/base.c 2016-07-05 04:28:31.000000000 +0000
6095+++ linux-4.1.27-vs2.3.8.5.2/fs/proc/base.c 2016-07-05 04:41:47.000000000 +0000
09be7631 6096@@ -87,6 +87,8 @@
78865d5b 6097 #include <linux/slab.h>
db55b927 6098 #include <linux/flex_array.h>
09be7631 6099 #include <linux/posix-timers.h>
d337f35e
JR
6100+#include <linux/vs_context.h>
6101+#include <linux/vs_network.h>
763640ca
JR
6102 #ifdef CONFIG_HARDWALL
6103 #include <asm/hardwall.h>
6104 #endif
f973f73f 6105@@ -891,11 +893,15 @@ static ssize_t oom_adj_write(struct file
537831f9 6106 oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
7e46296a 6107
537831f9
AM
6108 if (oom_adj < task->signal->oom_score_adj &&
6109- !capable(CAP_SYS_RESOURCE)) {
6110+ !vx_capable(CAP_SYS_RESOURCE, VXC_OOM_ADJUST)) {
ab30d09f
AM
6111 err = -EACCES;
6112 goto err_sighand;
4a036bed 6113 }
7e46296a 6114
4a036bed 6115+ /* prevent guest processes from circumventing the oom killer */
537831f9
AM
6116+ if (vx_current_xid() && (oom_adj == OOM_DISABLE))
6117+ oom_adj = OOM_ADJUST_MIN;
7e46296a 6118+
f6c5ef8b 6119 /*
537831f9
AM
6120 * /proc/pid/oom_adj is provided for legacy purposes, ask users to use
6121 * /proc/pid/oom_score_adj instead.
f973f73f 6122@@ -1483,6 +1489,8 @@ struct inode *proc_pid_make_inode(struct
ec22aa5c
AM
6123 inode->i_gid = cred->egid;
6124 rcu_read_unlock();
d337f35e
JR
6125 }
6126+ /* procfs is xid tagged */
61333608 6127+ i_tag_write(inode, (vtag_t)vx_task_xid(task));
d337f35e
JR
6128 security_task_to_inode(task, inode);
6129
6130 out:
f973f73f 6131@@ -1528,6 +1536,8 @@ int pid_getattr(struct vfsmount *mnt, st
d33d7b00
AM
6132
6133 /* dentry stuff */
6134
bb20add7 6135+// static unsigned name_to_int(struct dentry *dentry);
d33d7b00
AM
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
f973f73f 6140@@ -1556,6 +1566,19 @@ int pid_revalidate(struct dentry *dentry
d33d7b00
AM
6141 task = get_proc_task(inode);
6142
6143 if (task) {
bb20add7
AM
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));
d33d7b00 6153+ put_task_struct(task);
bb20add7
AM
6154+ d_drop(dentry);
6155+ return 0;
d33d7b00
AM
6156+ }
6157 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
6158 task_dumpable(task)) {
6159 rcu_read_lock();
f973f73f 6160@@ -2093,6 +2116,13 @@ static struct dentry *proc_pident_lookup
d337f35e
JR
6161 if (!task)
6162 goto out_no_task;
6163
2380c486 6164+ /* TODO: maybe we can come up with a generic approach? */
d337f35e
JR
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.
f973f73f 6174@@ -2544,6 +2574,11 @@ static int proc_pid_personality(struct s
2380c486
JR
6175 static const struct file_operations proc_task_operations;
6176 static const struct inode_operations proc_task_inode_operations;
d337f35e 6177
bb20add7
AM
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 *);
d337f35e 6182+
2380c486 6183 static const struct pid_entry tgid_base_stuff[] = {
ec22aa5c
AM
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),
f973f73f 6186@@ -2610,6 +2645,8 @@ static const struct pid_entry tgid_base_
2380c486 6187 #ifdef CONFIG_CGROUPS
bb20add7 6188 ONE("cgroup", S_IRUGO, proc_cgroup_show),
d337f35e 6189 #endif
bb20add7
AM
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),
537831f9 6193 REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
93de0823 6194 REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
f973f73f 6195@@ -2824,7 +2861,7 @@ retry:
2380c486
JR
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
f973f73f 6204@@ -2882,8 +2919,10 @@ int proc_pid_readdir(struct file *file,
c2e5f7c8
JR
6205 if (!has_pid_permissions(ns, iter.task, 2))
6206 continue;
db55b927 6207
c2e5f7c8
JR
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;
2380c486 6211+ if (!vx_proc_task_visible(iter.task))
d337f35e 6212+ continue;
c2e5f7c8
JR
6213 if (!proc_fill_cache(file, ctx, name, len,
6214 proc_pid_instantiate, iter.task, NULL)) {
2380c486 6215 put_task_struct(iter.task);
f973f73f 6216@@ -2980,6 +3019,7 @@ static const struct pid_entry tid_base_s
09be7631 6217 REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
bb20add7 6218 REG("setgroups", S_IRUGO|S_IWUSR, proc_setgroups_operations),
09be7631
JR
6219 #endif
6220+ ONE("nsproxy", S_IRUGO, proc_pid_nsproxy),
6221 };
6222
c2e5f7c8 6223 static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)
f973f73f 6224@@ -3046,6 +3086,8 @@ static struct dentry *proc_task_lookup(s
bb20add7 6225 tid = name_to_int(&dentry->d_name);
d337f35e
JR
6226 if (tid == ~0U)
6227 goto out;
6228+ if (vx_current_initpid(tid))
6229+ goto out;
6230
2380c486 6231 ns = dentry->d_sb->s_fs_info;
d337f35e 6232 rcu_read_lock();
f973f73f
AM
6233diff -NurpP --minimal linux-4.1.27/fs/proc/generic.c linux-4.1.27-vs2.3.8.5.2/fs/proc/generic.c
6234--- linux-4.1.27/fs/proc/generic.c 2016-07-05 04:28:31.000000000 +0000
6235+++ linux-4.1.27-vs2.3.8.5.2/fs/proc/generic.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 6236@@ -22,6 +22,7 @@
d337f35e
JR
6237 #include <linux/bitops.h>
6238 #include <linux/spinlock.h>
2380c486 6239 #include <linux/completion.h>
d337f35e
JR
6240+#include <linux/vserver/inode.h>
6241 #include <asm/uaccess.h>
6242
6243 #include "internal.h"
5eef5607
AM
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;
bb20add7 6258+ }
5eef5607
AM
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);
ba86f833 6266+ /* generic proc entries belong to the host */
537831f9 6267+ i_tag_write(inode, 0);
5eef5607 6268 return NULL;
2380c486 6269 }
5eef5607
AM
6270 spin_unlock(&proc_subdir_lock);
6271@@ -287,6 +298,13 @@ int proc_readdir_de(struct proc_dir_entr
c2e5f7c8
JR
6272 do {
6273 struct proc_dir_entry *next;
6274 pde_get(de);
6275+
bb20add7
AM
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);
c2e5f7c8 6280+ goto skip;
bb20add7 6281+ }
c2e5f7c8
JR
6282 spin_unlock(&proc_subdir_lock);
6283 if (!dir_emit(ctx, de->name, de->namelen,
6284 de->low_ino, de->mode >> 12)) {
5eef5607 6285@@ -294,6 +312,7 @@ int proc_readdir_de(struct proc_dir_entr
c2e5f7c8
JR
6286 return 0;
6287 }
6288 spin_lock(&proc_subdir_lock);
6289+ skip:
6290 ctx->pos++;
5eef5607 6291 next = pde_subdir_next(de);
c2e5f7c8 6292 pde_put(de);
5eef5607 6293@@ -387,6 +406,7 @@ static struct proc_dir_entry *__proc_cre
537831f9 6294 ent->mode = mode;
d337f35e 6295 ent->nlink = nlink;
5eef5607 6296 ent->subdir = RB_ROOT;
d337f35e 6297+ ent->vx_flags = IATTR_PROC_DEFAULT;
537831f9 6298 atomic_set(&ent->count, 1);
2380c486 6299 spin_lock_init(&ent->pde_unload_lock);
2380c486 6300 INIT_LIST_HEAD(&ent->pde_openers);
5eef5607 6301@@ -411,7 +431,8 @@ struct proc_dir_entry *proc_symlink(cons
d337f35e
JR
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;
f973f73f
AM
6311diff -NurpP --minimal linux-4.1.27/fs/proc/inode.c linux-4.1.27-vs2.3.8.5.2/fs/proc/inode.c
6312--- linux-4.1.27/fs/proc/inode.c 2016-07-05 04:28:31.000000000 +0000
6313+++ linux-4.1.27-vs2.3.8.5.2/fs/proc/inode.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 6314@@ -432,6 +432,8 @@ struct inode *proc_get_inode(struct supe
d337f35e
JR
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)
f973f73f
AM
6323diff -NurpP --minimal linux-4.1.27/fs/proc/internal.h linux-4.1.27-vs2.3.8.5.2/fs/proc/internal.h
6324--- linux-4.1.27/fs/proc/internal.h 2016-07-05 04:28:31.000000000 +0000
6325+++ linux-4.1.27-vs2.3.8.5.2/fs/proc/internal.h 2016-07-05 04:41:47.000000000 +0000
09be7631
JR
6326@@ -14,6 +14,7 @@
6327 #include <linux/spinlock.h>
6328 #include <linux/atomic.h>
b00e13aa 6329 #include <linux/binfmts.h>
d337f35e
JR
6330+#include <linux/vs_pid.h>
6331
09be7631
JR
6332 struct ctl_table_header;
6333 struct mempolicy;
5eef5607 6334@@ -34,6 +35,7 @@ struct proc_dir_entry {
09be7631
JR
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;
5eef5607 6342@@ -51,15 +53,22 @@ struct proc_dir_entry {
09be7631
JR
6343 char name[];
6344 };
6345
6346+struct vx_info;
6347+struct nx_info;
2380c486 6348+
09be7631
JR
6349 union proc_op {
6350 int (*proc_get_link)(struct dentry *, struct path *);
09be7631
JR
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 };
2380c486 6358
09be7631
JR
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;
5eef5607 6365@@ -92,11 +101,16 @@ static inline struct pid *proc_pid(struc
d337f35e
JR
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+
09be7631 6380 static inline int task_dumpable(struct task_struct *task)
d337f35e 6381 {
09be7631 6382 int dumpable = 0;
5eef5607 6383@@ -155,6 +169,8 @@ extern int proc_pid_status(struct seq_fi
09be7631
JR
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
f973f73f
AM
6392diff -NurpP --minimal linux-4.1.27/fs/proc/loadavg.c linux-4.1.27-vs2.3.8.5.2/fs/proc/loadavg.c
6393--- linux-4.1.27/fs/proc/loadavg.c 2015-04-12 22:12:50.000000000 +0000
6394+++ linux-4.1.27-vs2.3.8.5.2/fs/proc/loadavg.c 2016-07-05 04:41:47.000000000 +0000
ec22aa5c 6395@@ -12,15 +12,27 @@
1bc743c0 6396
ec22aa5c 6397 static int loadavg_proc_show(struct seq_file *m, void *v)
1bc743c0
JR
6398 {
6399+ unsigned long running;
6400+ unsigned int threads;
ec22aa5c 6401 unsigned long avnrun[3];
1bc743c0 6402
ec22aa5c 6403 get_avenrun(avnrun, FIXED_1/200, 0);
bd427b06 6404
ec22aa5c 6405+ if (vx_flags(VXF_VIRT_LOAD, 0)) {
eab5a9a6 6406+ struct vx_info *vxi = current_vx_info();
ec22aa5c
AM
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]),
1bc743c0
JR
6419- nr_running(), nr_threads,
6420+ running, threads,
6421 task_active_pid_ns(current)->last_pid);
ec22aa5c 6422 return 0;
1bc743c0 6423 }
f973f73f
AM
6424diff -NurpP --minimal linux-4.1.27/fs/proc/meminfo.c linux-4.1.27-vs2.3.8.5.2/fs/proc/meminfo.c
6425--- linux-4.1.27/fs/proc/meminfo.c 2015-04-12 22:12:50.000000000 +0000
6426+++ linux-4.1.27-vs2.3.8.5.2/fs/proc/meminfo.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 6427@@ -44,7 +44,8 @@ static int meminfo_proc_show(struct seq_
c2e5f7c8
JR
6428 si_swapinfo(&i);
6429 committed = percpu_counter_read_positive(&vm_committed_as);
e3afe727
AM
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) -
b00e13aa 6434 total_swapcache_pages() - i.bufferram;
e3afe727 6435 if (cached < 0)
d337f35e 6436 cached = 0;
f973f73f
AM
6437diff -NurpP --minimal linux-4.1.27/fs/proc/root.c linux-4.1.27-vs2.3.8.5.2/fs/proc/root.c
6438--- linux-4.1.27/fs/proc/root.c 2016-07-05 04:28:31.000000000 +0000
6439+++ linux-4.1.27-vs2.3.8.5.2/fs/proc/root.c 2016-07-05 04:41:47.000000000 +0000
b00e13aa 6440@@ -20,9 +20,14 @@
2380c486
JR
6441 #include <linux/mount.h>
6442 #include <linux/pid_namespace.h>
db55b927 6443 #include <linux/parser.h>
2380c486 6444+#include <linux/vserver/inode.h>
d337f35e 6445
2380c486 6446 #include "internal.h"
d337f35e 6447
d337f35e
JR
6448+struct proc_dir_entry *proc_virtual;
6449+
6450+extern void proc_vx_init(void);
2380c486
JR
6451+
6452 static int proc_test_super(struct super_block *sb, void *data)
6453 {
6454 return sb->s_fs_info == data;
5eef5607
AM
6455@@ -113,7 +118,8 @@ static struct dentry *proc_mount(struct
6456 options = data;
c2e5f7c8
JR
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
f973f73f 6465@@ -194,6 +200,7 @@ void __init proc_root_init(void)
bb20add7 6466 proc_tty_init();
2380c486
JR
6467 proc_mkdir("bus", NULL);
6468 proc_sys_init();
d337f35e
JR
6469+ proc_vx_init();
6470 }
6471
6472 static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
f973f73f 6473@@ -255,6 +262,7 @@ struct proc_dir_entry proc_root = {
2380c486
JR
6474 .proc_iops = &proc_root_inode_operations,
6475 .proc_fops = &proc_root_operations,
6476 .parent = &proc_root,
6477+ .vx_flags = IATTR_ADMIN | IATTR_WATCH,
5eef5607 6478 .subdir = RB_ROOT,
a168f21d 6479 .name = "/proc",
2380c486 6480 };
f973f73f
AM
6481diff -NurpP --minimal linux-4.1.27/fs/proc/self.c linux-4.1.27-vs2.3.8.5.2/fs/proc/self.c
6482--- linux-4.1.27/fs/proc/self.c 2015-07-06 20:41:42.000000000 +0000
6483+++ linux-4.1.27-vs2.3.8.5.2/fs/proc/self.c 2016-07-05 04:41:47.000000000 +0000
09be7631 6484@@ -2,6 +2,7 @@
b00e13aa 6485 #include <linux/namei.h>
09be7631
JR
6486 #include <linux/slab.h>
6487 #include <linux/pid_namespace.h>
b00e13aa 6488+#include <linux/vserver/inode.h>
09be7631 6489 #include "internal.h"
b00e13aa
AM
6490
6491 /*
c2e5f7c8 6492@@ -54,6 +55,8 @@ int proc_setup_self(struct super_block *
09be7631
JR
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;
f973f73f
AM
6501diff -NurpP --minimal linux-4.1.27/fs/proc/stat.c linux-4.1.27-vs2.3.8.5.2/fs/proc/stat.c
6502--- linux-4.1.27/fs/proc/stat.c 2015-04-12 22:12:50.000000000 +0000
6503+++ linux-4.1.27-vs2.3.8.5.2/fs/proc/stat.c 2016-07-05 04:41:47.000000000 +0000
537831f9 6504@@ -9,8 +9,10 @@
1e8b8f9b
AM
6505 #include <linux/slab.h>
6506 #include <linux/time.h>
6507 #include <linux/irqnr.h>
6508+#include <linux/vserver/cvirt.h>
265de2f7 6509 #include <linux/cputime.h>
1e8b8f9b 6510 #include <linux/tick.h>
537831f9
AM
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 =
1e8b8f9b
AM
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);
537831f9
AM
6529+
6530+ if (virt_cpu)
6531+ cpuset_cpus_allowed(current, cpus_allowed);
1e8b8f9b
AM
6532+
6533 jif = boottime.tv_sec;
6534
6535 for_each_possible_cpu(i) {
537831f9
AM
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];
f973f73f
AM
6552diff -NurpP --minimal linux-4.1.27/fs/proc/uptime.c linux-4.1.27-vs2.3.8.5.2/fs/proc/uptime.c
6553--- linux-4.1.27/fs/proc/uptime.c 2015-04-12 22:12:50.000000000 +0000
6554+++ linux-4.1.27-vs2.3.8.5.2/fs/proc/uptime.c 2016-07-05 04:41:47.000000000 +0000
f6c5ef8b 6555@@ -5,6 +5,7 @@
ec22aa5c
AM
6556 #include <linux/seq_file.h>
6557 #include <linux/time.h>
f6c5ef8b 6558 #include <linux/kernel_stat.h>
ec22aa5c 6559+#include <linux/vserver/cvirt.h>
265de2f7 6560 #include <linux/cputime.h>
ec22aa5c
AM
6561
6562 static int uptime_proc_show(struct seq_file *m, void *v)
c2e5f7c8 6563@@ -24,6 +25,10 @@ static int uptime_proc_show(struct seq_f
f6c5ef8b
AM
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;
ec22aa5c
AM
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)),
f973f73f
AM
6574diff -NurpP --minimal linux-4.1.27/fs/proc_namespace.c linux-4.1.27-vs2.3.8.5.2/fs/proc_namespace.c
6575--- linux-4.1.27/fs/proc_namespace.c 2016-07-05 04:28:31.000000000 +0000
6576+++ linux-4.1.27-vs2.3.8.5.2/fs/proc_namespace.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 6577@@ -45,6 +45,8 @@ static int show_sb_opts(struct seq_file
db55b927
AM
6578 { MS_DIRSYNC, ",dirsync" },
6579 { MS_MANDLOCK, ",mand" },
5eef5607 6580 { MS_LAZYTIME, ",lazytime" },
db55b927
AM
6581+ { MS_TAGGED, ",tag" },
6582+ { MS_NOTAGCHECK, ",notagcheck" },
6583 { 0, NULL }
6584 };
6585 const struct proc_fs_info *fs_infop;
5eef5607 6586@@ -81,6 +83,38 @@ static inline void mangle(struct seq_fil
db55b927
AM
6587 seq_escape(m, s, " \t\n\\");
6588 }
6589
61b0c03f
JR
6590+#ifdef CONFIG_VSERVER_EXTRA_MNT_CHECK
6591+
db55b927
AM
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+
98d9a5b1 6603+ rcu_read_lock();
db55b927
AM
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+ }
98d9a5b1 6612+ rcu_read_unlock();
db55b927
AM
6613+
6614+ ret = (mnt == root_mnt) && is_subdir(point, root.dentry);
db55b927
AM
6615+ return ret;
6616+}
61b0c03f
JR
6617+
6618+#else
6619+#define mnt_is_reachable(v) (1)
6620+#endif
db55b927
AM
6621+
6622 static void show_type(struct seq_file *m, struct super_block *sb)
6623 {
6624 mangle(m, sb->s_type->name);
5eef5607 6625@@ -98,6 +132,17 @@ static int show_vfsmnt(struct seq_file *
db55b927
AM
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)
5eef5607
AM
6643@@ -111,6 +156,7 @@ static int show_vfsmnt(struct seq_file *
6644 if (err)
6645 goto out;
db55b927
AM
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);
5eef5607
AM
6651@@ -132,6 +178,11 @@ static int show_mountinfo(struct seq_fil
6652 struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
db55b927
AM
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)
5eef5607 6663@@ -192,6 +243,17 @@ static int show_vfsstat(struct seq_file
db55b927
AM
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 ");
f973f73f 6681@@ -213,7 +275,7 @@ static int show_vfsstat(struct seq_file
5eef5607
AM
6682 if (err)
6683 goto out;
db55b927
AM
6684 seq_putc(m, ' ');
6685-
6686+type:
6687 /* file system type */
6688 seq_puts(m, "with fstype ");
6689 show_type(m, sb);
f973f73f
AM
6690diff -NurpP --minimal linux-4.1.27/fs/quota/dquot.c linux-4.1.27-vs2.3.8.5.2/fs/quota/dquot.c
6691--- linux-4.1.27/fs/quota/dquot.c 2016-07-05 04:28:31.000000000 +0000
6692+++ linux-4.1.27-vs2.3.8.5.2/fs/quota/dquot.c 2016-07-05 04:41:47.000000000 +0000
6693@@ -1624,6 +1624,9 @@ int __dquot_alloc_space(struct inode *in
76514441 6694 int reserve = flags & DQUOT_SPACE_RESERVE;
5eef5607 6695 struct dquot **dquots;
76514441
AM
6696
6697+ if ((ret = dl_alloc_space(inode, number)))
6698+ return ret;
6699+
bb20add7
AM
6700 if (!dquot_active(inode)) {
6701 inode_incr_space(inode, number, reserve);
6702 goto out;
f973f73f 6703@@ -1676,6 +1679,9 @@ int dquot_alloc_inode(struct inode *inod
1e8b8f9b 6704 struct dquot_warn warn[MAXQUOTAS];
5eef5607 6705 struct dquot * const *dquots;
76514441
AM
6706
6707+ if ((ret = dl_alloc_inode(inode)))
6708+ return ret;
6709+
93de0823 6710 if (!dquot_active(inode))
bb20add7
AM
6711 return 0;
6712 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
f973f73f 6713@@ -1778,6 +1784,8 @@ void __dquot_free_space(struct inode *in
5eef5607 6714 struct dquot **dquots;
bb20add7 6715 int reserve = flags & DQUOT_SPACE_RESERVE, index;
76514441
AM
6716
6717+ dl_free_space(inode, number);
6718+
93de0823 6719 if (!dquot_active(inode)) {
bb20add7
AM
6720 inode_decr_space(inode, number, reserve);
6721 return;
f973f73f 6722@@ -1822,6 +1830,8 @@ void dquot_free_inode(struct inode *inod
5eef5607 6723 struct dquot * const *dquots;
bb20add7 6724 int index;
76514441
AM
6725
6726+ dl_free_inode(inode);
6727+
93de0823 6728 if (!dquot_active(inode))
bb20add7
AM
6729 return;
6730
f973f73f
AM
6731diff -NurpP --minimal linux-4.1.27/fs/quota/quota.c linux-4.1.27-vs2.3.8.5.2/fs/quota/quota.c
6732--- linux-4.1.27/fs/quota/quota.c 2015-07-06 20:41:42.000000000 +0000
6733+++ linux-4.1.27-vs2.3.8.5.2/fs/quota/quota.c 2016-07-05 04:41:47.000000000 +0000
78865d5b
AM
6734@@ -8,6 +8,7 @@
6735 #include <linux/fs.h>
6736 #include <linux/namei.h>
6737 #include <linux/slab.h>
d337f35e 6738+#include <linux/vs_context.h>
78865d5b 6739 #include <asm/current.h>
92598135 6740 #include <linux/uaccess.h>
78865d5b 6741 #include <linux/kernel.h>
c2e5f7c8 6742@@ -38,7 +39,7 @@ static int check_quotactl_permission(str
78865d5b
AM
6743 break;
6744 /*FALLTHROUGH*/
6745 default:
d337f35e
JR
6746- if (!capable(CAP_SYS_ADMIN))
6747+ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
6748 return -EPERM;
6749 }
6750
5eef5607 6751@@ -702,6 +703,46 @@ static int do_quotactl(struct super_bloc
b00e13aa
AM
6752
6753 #ifdef CONFIG_BLOCK
d337f35e 6754
d337f35e
JR
6755+#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
6756+
6757+#include <linux/vroot.h>
2380c486
JR
6758+#include <linux/major.h>
6759+#include <linux/module.h>
d337f35e 6760+#include <linux/kallsyms.h>
2380c486 6761+#include <linux/vserver/debug.h>
d337f35e
JR
6762+
6763+static vroot_grb_func *vroot_get_real_bdev = NULL;
6764+
763640ca 6765+static DEFINE_SPINLOCK(vroot_grb_lock);
d337f35e
JR
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+
db55b927
AM
6795 /* Return 1 if 'cmd' will block on frozen filesystem */
6796 static int quotactl_cmd_write(int cmd)
6797 {
5eef5607 6798@@ -737,6 +778,22 @@ static struct super_block *quotactl_bloc
2380c486
JR
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 &&
537831f9 6804+ imajor(bdev->bd_inode) == VROOT_MAJOR) {
2380c486
JR
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
db55b927
AM
6818 if (quotactl_cmd_write(cmd))
6819 sb = get_super_thawed(bdev);
6820 else
f973f73f
AM
6821diff -NurpP --minimal linux-4.1.27/fs/stat.c linux-4.1.27-vs2.3.8.5.2/fs/stat.c
6822--- linux-4.1.27/fs/stat.c 2015-07-06 20:41:42.000000000 +0000
6823+++ linux-4.1.27-vs2.3.8.5.2/fs/stat.c 2016-07-05 04:41:47.000000000 +0000
2380c486 6824@@ -26,6 +26,7 @@ void generic_fillattr(struct inode *inod
d337f35e
JR
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;
a168f21d 6830 stat->size = i_size_read(inode);
d337f35e 6831 stat->atime = inode->i_atime;
f973f73f
AM
6832diff -NurpP --minimal linux-4.1.27/fs/statfs.c linux-4.1.27-vs2.3.8.5.2/fs/statfs.c
6833--- linux-4.1.27/fs/statfs.c 2015-04-12 22:12:50.000000000 +0000
6834+++ linux-4.1.27-vs2.3.8.5.2/fs/statfs.c 2016-07-05 04:41:47.000000000 +0000
93de0823 6835@@ -7,6 +7,8 @@
76514441
AM
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>
db55b927 6841 #include "internal.h"
76514441 6842
93de0823 6843 static int flags_by_mnt(int mnt_flags)
db55b927 6844@@ -60,6 +62,8 @@ static int statfs_by_dentry(struct dentr
93de0823
AM
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);
76514441
AM
6850 return retval;
6851 }
93de0823 6852
f973f73f
AM
6853diff -NurpP --minimal linux-4.1.27/fs/super.c linux-4.1.27-vs2.3.8.5.2/fs/super.c
6854--- linux-4.1.27/fs/super.c 2015-07-06 20:41:42.000000000 +0000
6855+++ linux-4.1.27-vs2.3.8.5.2/fs/super.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 6856@@ -33,6 +33,8 @@
be261992 6857 #include <linux/cleancache.h>
1e8b8f9b 6858 #include <linux/fsnotify.h>
92598135 6859 #include <linux/lockdep.h>
1e8b8f9b 6860+#include <linux/magic.h>
be261992
AM
6861+#include <linux/vs_context.h>
6862 #include "internal.h"
6863
6864
5eef5607
AM
6865@@ -1115,6 +1117,13 @@ mount_fs(struct file_system_type *type,
6866 WARN_ON(!sb->s_bdi);
be261992
AM
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;
f973f73f
AM
6879diff -NurpP --minimal linux-4.1.27/fs/utimes.c linux-4.1.27-vs2.3.8.5.2/fs/utimes.c
6880--- linux-4.1.27/fs/utimes.c 2015-04-12 22:12:50.000000000 +0000
6881+++ linux-4.1.27-vs2.3.8.5.2/fs/utimes.c 2016-07-05 04:41:47.000000000 +0000
2380c486
JR
6882@@ -8,6 +8,8 @@
6883 #include <linux/stat.h>
d337f35e 6884 #include <linux/utime.h>
2380c486 6885 #include <linux/syscalls.h>
d337f35e
JR
6886+#include <linux/mount.h>
6887+#include <linux/vs_cowbl.h>
6888 #include <asm/uaccess.h>
6889 #include <asm/unistd.h>
6890
c2e5f7c8 6891@@ -52,13 +54,19 @@ static int utimes_common(struct path *pa
76514441
AM
6892 {
6893 int error;
6894 struct iattr newattrs;
6895- struct inode *inode = path->dentry->d_inode;
c2e5f7c8 6896 struct inode *delegated_inode = NULL;
76514441 6897+ struct inode *inode;
b00e13aa
AM
6898+
6899+ error = cow_check_and_break(path);
6900+ if (error)
6901+ goto out;
76514441
AM
6902
6903 error = mnt_want_write(path->mnt);
6904 if (error)
6905 goto out;
6906
76514441
AM
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;
f973f73f
AM
6912diff -NurpP --minimal linux-4.1.27/fs/xattr.c linux-4.1.27-vs2.3.8.5.2/fs/xattr.c
6913--- linux-4.1.27/fs/xattr.c 2015-04-12 22:12:50.000000000 +0000
6914+++ linux-4.1.27-vs2.3.8.5.2/fs/xattr.c 2016-07-05 04:41:47.000000000 +0000
537831f9 6915@@ -21,6 +21,7 @@
d337f35e 6916 #include <linux/audit.h>
1e8b8f9b 6917 #include <linux/vmalloc.h>
537831f9 6918 #include <linux/posix_acl_xattr.h>
d337f35e 6919+#include <linux/mount.h>
d337f35e 6920
1e8b8f9b 6921 #include <asm/uaccess.h>
d337f35e 6922
537831f9 6923@@ -52,7 +53,7 @@ xattr_permission(struct inode *inode, co
763640ca 6924 * The trusted.* namespace can only be accessed by privileged users.
e03b8c3c 6925 */
763640ca
JR
6926 if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
6927- if (!capable(CAP_SYS_ADMIN))
a168f21d
AM
6928+ if (!vx_capable(CAP_SYS_ADMIN, VXC_FS_TRUSTED))
6929 return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
6930 return 0;
6931 }
f973f73f
AM
6932diff -NurpP --minimal linux-4.1.27/include/linux/capability.h linux-4.1.27-vs2.3.8.5.2/include/linux/capability.h
6933--- linux-4.1.27/include/linux/capability.h 2015-07-06 20:41:42.000000000 +0000
6934+++ linux-4.1.27-vs2.3.8.5.2/include/linux/capability.h 2016-07-05 04:41:47.000000000 +0000
bb20add7
AM
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 }})
f973f73f
AM
6945diff -NurpP --minimal linux-4.1.27/include/linux/cred.h linux-4.1.27-vs2.3.8.5.2/include/linux/cred.h
6946--- linux-4.1.27/include/linux/cred.h 2015-07-06 20:41:42.000000000 +0000
6947+++ linux-4.1.27-vs2.3.8.5.2/include/linux/cred.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 6948@@ -159,6 +159,7 @@ extern void exit_creds(struct task_struc
1163e6ab
AM
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 *);
5eef5607 6956@@ -212,6 +213,31 @@ static inline void validate_process_cred
3bac966d
AM
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
f973f73f
AM
6988diff -NurpP --minimal linux-4.1.27/include/linux/dcache.h linux-4.1.27-vs2.3.8.5.2/include/linux/dcache.h
6989--- linux-4.1.27/include/linux/dcache.h 2016-07-05 04:28:31.000000000 +0000
6990+++ linux-4.1.27-vs2.3.8.5.2/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
7011diff -NurpP --minimal linux-4.1.27/include/linux/devpts_fs.h linux-4.1.27-vs2.3.8.5.2/include/linux/devpts_fs.h
7012--- linux-4.1.27/include/linux/devpts_fs.h 2016-07-05 04:28:31.000000000 +0000
7013+++ linux-4.1.27-vs2.3.8.5.2/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
2380c486
JR
7015
7016 #endif
d337f35e 7017
2380c486 7018-
d337f35e 7019 #endif /* _LINUX_DEVPTS_FS_H */
f973f73f
AM
7020diff -NurpP --minimal linux-4.1.27/include/linux/fs.h linux-4.1.27-vs2.3.8.5.2/include/linux/fs.h
7021--- linux-4.1.27/include/linux/fs.h 2016-07-05 04:28:31.000000000 +0000
7022+++ linux-4.1.27-vs2.3.8.5.2/include/linux/fs.h 2016-07-05 04:41:47.000000000 +0000
7023@@ -225,6 +225,7 @@ typedef void (dax_iodone_t)(struct buffe
2380c486
JR
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)
d337f35e
JR
7028
7029 /*
bb20add7 7030 * Whiteout is represented by a char device. The following constants define the
f973f73f 7031@@ -247,6 +248,7 @@ struct iattr {
d337f35e 7032 umode_t ia_mode;
42bc425c
AM
7033 kuid_t ia_uid;
7034 kgid_t ia_gid;
537831f9 7035+ ktag_t ia_tag;
d337f35e
JR
7036 loff_t ia_size;
7037 struct timespec ia_atime;
7038 struct timespec ia_mtime;
f973f73f 7039@@ -585,7 +587,9 @@ struct inode {
a168f21d 7040 unsigned short i_opflags;
42bc425c
AM
7041 kuid_t i_uid;
7042 kgid_t i_gid;
2380c486 7043- unsigned int i_flags;
537831f9 7044+ ktag_t i_tag;
2380c486
JR
7045+ unsigned short i_flags;
7046+ unsigned short i_vflags;
a168f21d
AM
7047
7048 #ifdef CONFIG_FS_POSIX_ACL
7049 struct posix_acl *i_acl;
f973f73f 7050@@ -614,6 +618,7 @@ struct inode {
f6c5ef8b
AM
7051 unsigned int __i_nlink;
7052 };
d33d7b00
AM
7053 dev_t i_rdev;
7054+ dev_t i_mdev;
42bc425c 7055 loff_t i_size;
a168f21d
AM
7056 struct timespec i_atime;
7057 struct timespec i_mtime;
f973f73f 7058@@ -773,6 +778,11 @@ static inline gid_t i_gid_read(const str
537831f9
AM
7059 return from_kgid(&init_user_ns, inode->i_gid);
7060 }
7061
61333608 7062+static inline vtag_t i_tag_read(const struct inode *inode)
537831f9
AM
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);
f973f73f 7070@@ -783,14 +793,19 @@ static inline void i_gid_write(struct in
537831f9
AM
7071 inode->i_gid = make_kgid(&init_user_ns, gid);
7072 }
2380c486 7073
61333608 7074+static inline void i_tag_write(struct inode *inode, vtag_t tag)
537831f9
AM
7075+{
7076+ inode->i_tag = make_ktag(&init_user_ns, tag);
7077+}
7078+
2380c486
JR
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);
f973f73f 7092@@ -847,6 +862,7 @@ struct file {
d337f35e
JR
7093 loff_t f_pos;
7094 struct fown_struct f_owner;
ec22aa5c 7095 const struct cred *f_cred;
61333608 7096+ vxid_t f_xid;
d337f35e
JR
7097 struct file_ra_state f_ra;
7098
2380c486 7099 u64 f_version;
f973f73f 7100@@ -975,6 +991,7 @@ struct file_lock {
2380c486 7101 struct file *fl_file;
d337f35e
JR
7102 loff_t fl_start;
7103 loff_t fl_end;
61333608 7104+ vxid_t fl_xid;
d337f35e
JR
7105
7106 struct fasync_struct * fl_fasync; /* for lease break notifications */
f6c5ef8b 7107 /* for lease breaks: */
f973f73f 7108@@ -1647,6 +1664,7 @@ struct inode_operations {
d4263eb0
JR
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);
d33d7b00
AM
7113 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
7114 u64 len);
42bc425c 7115 int (*update_time)(struct inode *, struct timespec *, int);
f973f73f 7116@@ -1663,6 +1681,7 @@ ssize_t rw_copy_check_uvector(int type,
537831f9
AM
7117 unsigned long nr_segs, unsigned long fast_segs,
7118 struct iovec *fast_pointer,
7119 struct iovec **ret_pointer);
d337f35e
JR
7120+ssize_t vfs_sendfile(struct file *, struct file *, loff_t *, size_t, loff_t);
7121
5eef5607
AM
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 *);
f973f73f 7124@@ -1728,6 +1747,14 @@ struct super_operations {
5eef5607
AM
7125 #else
7126 #define S_DAX 0 /* Make all the DAX code disappear */
7127 #endif
7128+#define S_IXUNLINK 16384 /* Immutable Invert on unlink */
537831f9
AM
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
f973f73f 7139@@ -1752,10 +1779,13 @@ struct super_operations {
537831f9
AM
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)
f973f73f 7153@@ -1770,6 +1800,16 @@ struct super_operations {
bb20add7
AM
7154 #define IS_WHITEOUT(inode) (S_ISCHR(inode->i_mode) && \
7155 (inode)->i_rdev == WHITEOUT_DEV)
537831f9
AM
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 *
f973f73f 7170@@ -2019,6 +2059,9 @@ extern struct kobject *fs_kobj;
bb20add7 7171 extern int locks_mandatory_locked(struct file *);
537831f9
AM
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.
f973f73f 7180@@ -2764,6 +2807,7 @@ extern int dcache_dir_open(struct inode
d337f35e
JR
7181 extern int dcache_dir_close(struct inode *, struct file *);
7182 extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
c2e5f7c8
JR
7183 extern int dcache_readdir(struct file *, struct dir_context *);
7184+extern int dcache_readdir_filter(struct file *, struct dir_context *, int (*)(struct dentry *));
76514441 7185 extern int simple_setattr(struct dentry *, struct iattr *);
d337f35e
JR
7186 extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
7187 extern int simple_statfs(struct dentry *, struct kstatfs *);
f973f73f
AM
7188diff -NurpP --minimal linux-4.1.27/include/linux/init_task.h linux-4.1.27-vs2.3.8.5.2/include/linux/init_task.h
7189--- linux-4.1.27/include/linux/init_task.h 2015-04-12 22:12:50.000000000 +0000
7190+++ linux-4.1.27-vs2.3.8.5.2/include/linux/init_task.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 7191@@ -258,6 +258,10 @@ extern struct task_group root_task_group
b00e13aa 7192 INIT_VTIME(tsk) \
5eef5607
AM
7193 INIT_NUMA_BALANCING(tsk) \
7194 INIT_KASAN(tsk) \
d337f35e
JR
7195+ .xid = 0, \
7196+ .vx_info = NULL, \
7197+ .nid = 0, \
7198+ .nx_info = NULL, \
7199 }
7200
7201
f973f73f
AM
7202diff -NurpP --minimal linux-4.1.27/include/linux/ipc.h linux-4.1.27-vs2.3.8.5.2/include/linux/ipc.h
7203--- linux-4.1.27/include/linux/ipc.h 2015-04-12 22:12:50.000000000 +0000
7204+++ linux-4.1.27-vs2.3.8.5.2/include/linux/ipc.h 2016-07-05 04:41:47.000000000 +0000
537831f9 7205@@ -16,6 +16,7 @@ struct kern_ipc_perm
d337f35e 7206 key_t key;
537831f9
AM
7207 kuid_t uid;
7208 kgid_t gid;
61333608 7209+ vxid_t xid;
537831f9
AM
7210 kuid_t cuid;
7211 kgid_t cgid;
db55b927 7212 umode_t mode;
f973f73f
AM
7213diff -NurpP --minimal linux-4.1.27/include/linux/memcontrol.h linux-4.1.27-vs2.3.8.5.2/include/linux/memcontrol.h
7214--- linux-4.1.27/include/linux/memcontrol.h 2015-07-06 20:41:42.000000000 +0000
7215+++ linux-4.1.27-vs2.3.8.5.2/include/linux/memcontrol.h 2016-07-06 06:59:44.000000000 +0000
5eef5607
AM
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,
f973f73f
AM
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 {
7236diff -NurpP --minimal linux-4.1.27/include/linux/mount.h linux-4.1.27-vs2.3.8.5.2/include/linux/mount.h
7237--- linux-4.1.27/include/linux/mount.h 2015-07-06 20:41:42.000000000 +0000
7238+++ linux-4.1.27-vs2.3.8.5.2/include/linux/mount.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 7239@@ -63,6 +63,9 @@ struct mnt_namespace;
bb20add7 7240 #define MNT_MARKED 0x4000000
5eef5607 7241 #define MNT_UMOUNT 0x8000000
d337f35e 7242
2380c486
JR
7243+#define MNT_TAGID 0x10000
7244+#define MNT_NOTAG 0x20000
7245+
d337f35e 7246 struct vfsmount {
db55b927
AM
7247 struct dentry *mnt_root; /* root of the mounted tree */
7248 struct super_block *mnt_sb; /* pointer to superblock */
f973f73f
AM
7249diff -NurpP --minimal linux-4.1.27/include/linux/net.h linux-4.1.27-vs2.3.8.5.2/include/linux/net.h
7250--- linux-4.1.27/include/linux/net.h 2015-07-06 20:41:42.000000000 +0000
7251+++ linux-4.1.27-vs2.3.8.5.2/include/linux/net.h 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 7252@@ -39,6 +39,7 @@ struct net;
d337f35e
JR
7253 #define SOCK_PASSCRED 3
7254 #define SOCK_PASSSEC 4
6b86c8e5
AM
7255 #define SOCK_EXTERNALLY_ALLOCATED 5
7256+#define SOCK_USER_SOCKET 6
d337f35e
JR
7257
7258 #ifndef ARCH_HAS_SOCKET_TYPES
7259 /**
f973f73f
AM
7260diff -NurpP --minimal linux-4.1.27/include/linux/netdevice.h linux-4.1.27-vs2.3.8.5.2/include/linux/netdevice.h
7261--- linux-4.1.27/include/linux/netdevice.h 2015-07-06 20:41:42.000000000 +0000
7262+++ linux-4.1.27-vs2.3.8.5.2/include/linux/netdevice.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 7263@@ -2200,6 +2200,7 @@ static inline int dev_recursion_level(vo
c2e5f7c8
JR
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);
f973f73f
AM
7271diff -NurpP --minimal linux-4.1.27/include/linux/nsproxy.h linux-4.1.27-vs2.3.8.5.2/include/linux/nsproxy.h
7272--- linux-4.1.27/include/linux/nsproxy.h 2015-04-12 22:12:50.000000000 +0000
7273+++ linux-4.1.27-vs2.3.8.5.2/include/linux/nsproxy.h 2016-07-05 04:41:47.000000000 +0000
2380c486 7274@@ -3,6 +3,7 @@
d337f35e 7275
2380c486
JR
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;
bb20add7
AM
7282@@ -63,6 +64,7 @@ extern struct nsproxy init_nsproxy;
7283 */
2380c486
JR
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);
bb20add7 7290@@ -70,16 +72,26 @@ int unshare_nsproxy_namespaces(unsigned
b00e13aa 7291 struct cred *, struct fs_struct *);
a168f21d 7292 int __init nsproxy_cache_init(void);
2380c486
JR
7293
7294-static inline void put_nsproxy(struct nsproxy *ns)
7295+#define get_nsproxy(n) __get_nsproxy(n, __FILE__, __LINE__)
d337f35e 7296+
2380c486
JR
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);
d337f35e 7305+ atomic_inc(&ns->count);
2380c486
JR
7306 }
7307
7308-static inline void get_nsproxy(struct nsproxy *ns)
7309+#define put_nsproxy(n) __put_nsproxy(n, __FILE__, __LINE__)
d337f35e 7310+
2380c486
JR
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 }
d337f35e 7321
763640ca 7322 #endif
f973f73f
AM
7323diff -NurpP --minimal linux-4.1.27/include/linux/pid.h linux-4.1.27-vs2.3.8.5.2/include/linux/pid.h
7324--- linux-4.1.27/include/linux/pid.h 2015-04-12 22:12:50.000000000 +0000
7325+++ linux-4.1.27-vs2.3.8.5.2/include/linux/pid.h 2016-07-05 04:41:47.000000000 +0000
d337f35e
JR
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 /*
c2e5f7c8 7336@@ -170,6 +171,7 @@ static inline pid_t pid_nr(struct pid *p
2380c486
JR
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) \
f973f73f
AM
7344diff -NurpP --minimal linux-4.1.27/include/linux/quotaops.h linux-4.1.27-vs2.3.8.5.2/include/linux/quotaops.h
7345--- linux-4.1.27/include/linux/quotaops.h 2015-07-06 20:41:43.000000000 +0000
7346+++ linux-4.1.27-vs2.3.8.5.2/include/linux/quotaops.h 2016-07-05 04:41:47.000000000 +0000
e22b5178
AM
7347@@ -8,6 +8,7 @@
7348 #define _LINUX_QUOTAOPS_
7349
7350 #include <linux/fs.h>
7351+#include <linux/vs_dlimit.h>
7352
76514441
AM
7353 #define DQUOT_SPACE_WARN 0x1
7354 #define DQUOT_SPACE_RESERVE 0x2
5eef5607 7355@@ -210,11 +211,12 @@ static inline void dquot_drop(struct ino
76514441 7356
5eef5607 7357 static inline int dquot_alloc_inode(struct inode *inode)
76514441
AM
7358 {
7359- return 0;
7360+ return dl_alloc_inode(inode);
7361 }
7362
5eef5607 7363 static inline void dquot_free_inode(struct inode *inode)
e22b5178 7364 {
76514441
AM
7365+ dl_free_inode(inode);
7366 }
7367
7368 static inline int dquot_transfer(struct inode *inode, struct iattr *iattr)
5eef5607 7369@@ -225,6 +227,10 @@ static inline int dquot_transfer(struct
76514441
AM
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;
5eef5607 7380@@ -235,6 +241,7 @@ static inline void __dquot_free_space(st
76514441
AM
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)
f973f73f
AM
7388diff -NurpP --minimal linux-4.1.27/include/linux/sched.h linux-4.1.27-vs2.3.8.5.2/include/linux/sched.h
7389--- linux-4.1.27/include/linux/sched.h 2016-07-05 04:28:31.000000000 +0000
7390+++ linux-4.1.27-vs2.3.8.5.2/include/linux/sched.h 2016-07-05 04:41:47.000000000 +0000
9e3e8383 7391@@ -1502,6 +1502,14 @@ struct task_struct {
2380c486 7392 #endif
42bc425c 7393 struct seccomp seccomp;
2380c486
JR
7394
7395+/* vserver context data */
7396+ struct vx_info *vx_info;
7397+ struct nx_info *nx_info;
d337f35e 7398+
61333608
AM
7399+ vxid_t xid;
7400+ vnid_t nid;
7401+ vtag_t tag;
2380c486
JR
7402+
7403 /* Thread group tracking */
7404 u32 parent_exec_id;
7405 u32 self_exec_id;
9e3e8383 7406@@ -1808,6 +1816,11 @@ struct pid_namespace;
ec22aa5c
AM
7407 pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
7408 struct pid_namespace *ns);
d337f35e 7409
2380c486
JR
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;
9e3e8383 7418@@ -1821,7 +1834,8 @@ static inline pid_t task_pid_nr_ns(struc
d337f35e 7419
2380c486
JR
7420 static inline pid_t task_pid_vnr(struct task_struct *tsk)
7421 {
ec22aa5c
AM
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));
2380c486 7425 }
d337f35e 7426
d337f35e 7427
9e3e8383 7428@@ -1834,7 +1848,7 @@ pid_t task_tgid_nr_ns(struct task_struct
2380c486
JR
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
f973f73f
AM
7437diff -NurpP --minimal linux-4.1.27/include/linux/shmem_fs.h linux-4.1.27-vs2.3.8.5.2/include/linux/shmem_fs.h
7438--- linux-4.1.27/include/linux/shmem_fs.h 2015-04-12 22:12:50.000000000 +0000
7439+++ linux-4.1.27-vs2.3.8.5.2/include/linux/shmem_fs.h 2016-07-05 04:41:47.000000000 +0000
bb20add7 7440@@ -10,6 +10,9 @@
2380c486 7441
a168f21d 7442 /* inode in-kernel data */
2380c486
JR
7443
7444+#define TMPFS_SUPER_MAGIC 0x01021994
7445+
7446+
7447 struct shmem_inode_info {
7448 spinlock_t lock;
bb20add7 7449 unsigned int seals; /* shmem seals */
f973f73f
AM
7450diff -NurpP --minimal linux-4.1.27/include/linux/stat.h linux-4.1.27-vs2.3.8.5.2/include/linux/stat.h
7451--- linux-4.1.27/include/linux/stat.h 2015-04-12 22:12:50.000000000 +0000
7452+++ linux-4.1.27-vs2.3.8.5.2/include/linux/stat.h 2016-07-05 04:41:47.000000000 +0000
537831f9 7453@@ -25,6 +25,7 @@ struct kstat {
2380c486 7454 unsigned int nlink;
42bc425c
AM
7455 kuid_t uid;
7456 kgid_t gid;
8ce283e1 7457+ ktag_t tag;
2380c486
JR
7458 dev_t rdev;
7459 loff_t size;
7460 struct timespec atime;
f973f73f
AM
7461diff -NurpP --minimal linux-4.1.27/include/linux/sunrpc/auth.h linux-4.1.27-vs2.3.8.5.2/include/linux/sunrpc/auth.h
7462--- linux-4.1.27/include/linux/sunrpc/auth.h 2015-04-12 22:12:50.000000000 +0000
7463+++ linux-4.1.27-vs2.3.8.5.2/include/linux/sunrpc/auth.h 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 7464@@ -36,6 +36,7 @@ enum {
2380c486 7465 struct auth_cred {
b00e13aa
AM
7466 kuid_t uid;
7467 kgid_t gid;
7468+ ktag_t tag;
2380c486 7469 struct group_info *group_info;
db55b927 7470 const char *principal;
c2e5f7c8 7471 unsigned long ac_flags;
f973f73f
AM
7472diff -NurpP --minimal linux-4.1.27/include/linux/sunrpc/clnt.h linux-4.1.27-vs2.3.8.5.2/include/linux/sunrpc/clnt.h
7473--- linux-4.1.27/include/linux/sunrpc/clnt.h 2015-04-12 22:12:50.000000000 +0000
7474+++ linux-4.1.27-vs2.3.8.5.2/include/linux/sunrpc/clnt.h 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 7475@@ -51,7 +51,8 @@ struct rpc_clnt {
2380c486 7476 cl_discrtry : 1,/* disconnect before retry */
c2e5f7c8 7477 cl_noretranstimeo: 1,/* No retransmit timeouts */
2380c486
JR
7478 cl_autobind : 1,/* use getport() */
7479- cl_chatty : 1;/* be verbose */
7480+ cl_chatty : 1,/* be verbose */
7481+ cl_tag : 1;/* context tagging */
d337f35e 7482
2380c486
JR
7483 struct rpc_rtt * cl_rtt; /* RTO estimator data */
7484 const struct rpc_timeout *cl_timeout; /* Timeout strategy */
f973f73f
AM
7485diff -NurpP --minimal linux-4.1.27/include/linux/types.h linux-4.1.27-vs2.3.8.5.2/include/linux/types.h
7486--- linux-4.1.27/include/linux/types.h 2016-07-05 04:28:31.000000000 +0000
7487+++ linux-4.1.27-vs2.3.8.5.2/include/linux/types.h 2016-07-05 04:41:47.000000000 +0000
537831f9 7488@@ -32,6 +32,9 @@ typedef __kernel_uid32_t uid_t;
2380c486
JR
7489 typedef __kernel_gid32_t gid_t;
7490 typedef __kernel_uid16_t uid16_t;
7491 typedef __kernel_gid16_t gid16_t;
61333608
AM
7492+typedef unsigned int vxid_t;
7493+typedef unsigned int vnid_t;
7494+typedef unsigned int vtag_t;
2380c486
JR
7495
7496 typedef unsigned long uintptr_t;
7497
f973f73f
AM
7498diff -NurpP --minimal linux-4.1.27/include/linux/uidgid.h linux-4.1.27-vs2.3.8.5.2/include/linux/uidgid.h
7499--- linux-4.1.27/include/linux/uidgid.h 2015-07-06 20:41:43.000000000 +0000
7500+++ linux-4.1.27-vs2.3.8.5.2/include/linux/uidgid.h 2016-07-05 04:41:47.000000000 +0000
bb20add7 7501@@ -21,13 +21,17 @@ typedef struct {
537831f9
AM
7502 uid_t val;
7503 } kuid_t;
7504
7505-
7506 typedef struct {
7507 gid_t val;
7508 } kgid_t;
7509
7510+typedef struct {
61333608 7511+ vtag_t val;
537831f9
AM
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
5eef5607 7518 #ifdef CONFIG_MULTIUSER
537831f9 7519 static inline uid_t __kuid_val(kuid_t uid)
5eef5607 7520@@ -51,11 +55,18 @@ static inline gid_t __kgid_val(kgid_t gi
537831f9 7521 }
5eef5607 7522 #endif
537831f9 7523
61333608 7524+static inline vtag_t __ktag_val(ktag_t tag)
537831f9
AM
7525+{
7526+ return tag.val;
7527+}
7528+
537831f9
AM
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 {
5eef5607 7539@@ -67,6 +78,11 @@ static inline bool gid_eq(kgid_t left, k
537831f9
AM
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);
5eef5607
AM
7551@@ -117,13 +133,21 @@ static inline bool gid_valid(kgid_t gid)
7552 return __kgid_val(gid) != (gid_t) -1;
537831f9
AM
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);
c90fe048 7564+extern ktag_t make_ktag(struct user_namespace *from, gid_t gid);
537831f9
AM
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);
61333608 7568+extern vtag_t from_ktag(struct user_namespace *to, ktag_t tag);
537831f9
AM
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
5eef5607 7573@@ -149,6 +173,11 @@ static inline kgid_t make_kgid(struct us
537831f9
AM
7574 return KGIDT_INIT(gid);
7575 }
7576
61333608 7577+static inline ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
537831f9
AM
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);
5eef5607 7585@@ -159,6 +188,11 @@ static inline gid_t from_kgid(struct use
537831f9
AM
7586 return __kgid_val(kgid);
7587 }
7588
61333608 7589+static inline vtag_t from_ktag(struct user_namespace *to, ktag_t ktag)
537831f9
AM
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);
f973f73f
AM
7597diff -NurpP --minimal linux-4.1.27/include/linux/vroot.h linux-4.1.27-vs2.3.8.5.2/include/linux/vroot.h
7598--- linux-4.1.27/include/linux/vroot.h 1970-01-01 00:00:00.000000000 +0000
7599+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vroot.h 2016-07-05 04:41:47.000000000 +0000
2380c486
JR
7600@@ -0,0 +1,51 @@
7601+
7602+/*
7603+ * include/linux/vroot.h
7604+ *
9e3e8383
AM
7605+ * written by Herbert P?tzl, 9/11/2002
7606+ * ported to 2.6 by Herbert P?tzl, 30/12/2004
2380c486 7607+ *
9e3e8383 7608+ * Copyright (C) 2002-2007 by Herbert P?tzl.
2380c486
JR
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 */
f973f73f
AM
7652diff -NurpP --minimal linux-4.1.27/include/linux/vs_base.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_base.h
7653--- linux-4.1.27/include/linux/vs_base.h 1970-01-01 00:00:00.000000000 +0000
7654+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_base.h 2016-07-05 04:41:47.000000000 +0000
2380c486
JR
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
f973f73f
AM
7666diff -NurpP --minimal linux-4.1.27/include/linux/vs_context.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_context.h
7667--- linux-4.1.27/include/linux/vs_context.h 1970-01-01 00:00:00.000000000 +0000
7668+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_context.h 2016-07-05 04:41:47.000000000 +0000
4a036bed 7669@@ -0,0 +1,242 @@
2380c486
JR
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);
61333608 7881+ vxis->xid = xchg(&current->xid, (vxid_t)0);
2380c486
JR
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+
4a036bed
AM
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+
2380c486
JR
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
f973f73f
AM
7912diff -NurpP --minimal linux-4.1.27/include/linux/vs_cowbl.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_cowbl.h
7913--- linux-4.1.27/include/linux/vs_cowbl.h 1970-01-01 00:00:00.000000000 +0000
7914+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_cowbl.h 2016-07-05 04:41:47.000000000 +0000
78865d5b 7915@@ -0,0 +1,48 @@
2380c486
JR
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>
78865d5b 7922+#include <linux/slab.h>
2380c486
JR
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
f973f73f
AM
7964diff -NurpP --minimal linux-4.1.27/include/linux/vs_cvirt.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_cvirt.h
7965--- linux-4.1.27/include/linux/vs_cvirt.h 1970-01-01 00:00:00.000000000 +0000
7966+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_cvirt.h 2016-07-05 04:41:47.000000000 +0000
2380c486
JR
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
f973f73f
AM
8018diff -NurpP --minimal linux-4.1.27/include/linux/vs_device.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_device.h
8019--- linux-4.1.27/include/linux/vs_device.h 1970-01-01 00:00:00.000000000 +0000
8020+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_device.h 2016-07-05 04:41:47.000000000 +0000
2380c486
JR
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
f973f73f
AM
8067diff -NurpP --minimal linux-4.1.27/include/linux/vs_dlimit.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_dlimit.h
8068--- linux-4.1.27/include/linux/vs_dlimit.h 1970-01-01 00:00:00.000000000 +0000
8069+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_dlimit.h 2016-07-05 04:41:47.000000000 +0000
2c8c5bc5 8070@@ -0,0 +1,215 @@
2380c486
JR
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,
61333608 8119+ vtag_t tag, dlsize_t nr, const char *file, int line)
2380c486
JR
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);
76514441 8141+ return ret ? -ENOSPC : 0;
2380c486
JR
8142+}
8143+
8144+static inline void __dl_free_space(struct super_block *sb,
61333608 8145+ vtag_t tag, dlsize_t nr, const char *_file, int _line)
2380c486
JR
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,
61333608 8170+ vtag_t tag, const char *_file, int _line)
2380c486
JR
8171+{
8172+ struct dl_info *dli;
8173+ int ret = 0;
d337f35e 8174+
2380c486
JR
8175+ dli = locate_dl_info(sb, tag);
8176+ if (!dli)
8177+ goto out;
d337f35e 8178+
2380c486 8179+ spin_lock(&dli->dl_lock);
2c8c5bc5
AM
8180+ dli->dl_inodes_used++;
8181+ ret = (dli->dl_inodes_used > dli->dl_inodes_total);
2380c486
JR
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);
76514441 8188+ return ret ? -ENOSPC : 0;
2380c486 8189+}
d337f35e 8190+
2380c486 8191+static inline void __dl_free_inode(struct super_block *sb,
61333608 8192+ vtag_t tag, const char *_file, int _line)
d337f35e 8193+{
2380c486
JR
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);
d337f35e
JR
8211+}
8212+
61333608 8213+static inline void __dl_adjust_block(struct super_block *sb, vtag_t tag,
2380c486
JR
8214+ unsigned long long *free_blocks, unsigned long long *root_blocks,
8215+ const char *_file, int _line)
d337f35e 8216+{
2380c486
JR
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);
d337f35e
JR
8246+}
8247+
e22b5178 8248+#define dl_prealloc_space(in, bytes) \
537831f9 8249+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 8250+ __FILE__, __LINE__ )
d337f35e 8251+
e22b5178 8252+#define dl_alloc_space(in, bytes) \
537831f9 8253+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 8254+ __FILE__, __LINE__ )
d337f35e 8255+
e22b5178 8256+#define dl_reserve_space(in, bytes) \
537831f9 8257+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 8258+ __FILE__, __LINE__ )
d337f35e 8259+
e22b5178
AM
8260+#define dl_claim_space(in, bytes) (0)
8261+
8262+#define dl_release_space(in, bytes) \
537831f9 8263+ __dl_free_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 8264+ __FILE__, __LINE__ )
d337f35e 8265+
e22b5178 8266+#define dl_free_space(in, bytes) \
537831f9 8267+ __dl_free_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
e22b5178
AM
8268+ __FILE__, __LINE__ )
8269+
8270+
d337f35e 8271+
e22b5178 8272+#define dl_alloc_inode(in) \
537831f9 8273+ __dl_alloc_inode((in)->i_sb, i_tag_read(in), __FILE__, __LINE__ )
d337f35e 8274+
e22b5178 8275+#define dl_free_inode(in) \
537831f9 8276+ __dl_free_inode((in)->i_sb, i_tag_read(in), __FILE__, __LINE__ )
d337f35e 8277+
d337f35e 8278+
e22b5178 8279+#define dl_adjust_block(sb, tag, fb, rb) \
2380c486 8280+ __dl_adjust_block(sb, tag, fb, rb, __FILE__, __LINE__ )
d337f35e 8281+
d337f35e 8282+
2380c486
JR
8283+#else
8284+#warning duplicate inclusion
8285+#endif
f973f73f
AM
8286diff -NurpP --minimal linux-4.1.27/include/linux/vs_inet.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_inet.h
8287--- linux-4.1.27/include/linux/vs_inet.h 1970-01-01 00:00:00.000000000 +0000
8288+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_inet.h 2016-07-05 04:41:47.000000000 +0000
5cb1760b 8289@@ -0,0 +1,364 @@
d33d7b00
AM
8290+#ifndef _VS_INET_H
8291+#define _VS_INET_H
d337f35e 8292+
d33d7b00
AM
8293+#include "vserver/base.h"
8294+#include "vserver/network.h"
8295+#include "vserver/debug.h"
d337f35e 8296+
d33d7b00 8297+#define IPI_LOOPBACK htonl(INADDR_LOOPBACK)
d337f35e 8298+
d33d7b00
AM
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]"
d337f35e 8302+
d33d7b00
AM
8303+#define NIPQUAD(addr) \
8304+ ((unsigned char *)&addr)[0], \
8305+ ((unsigned char *)&addr)[1], \
8306+ ((unsigned char *)&addr)[2], \
8307+ ((unsigned char *)&addr)[3]
d337f35e 8308+
d33d7b00 8309+#define NIPQUAD_FMT "%u.%u.%u.%u"
d337f35e 8310+
d337f35e 8311+
d33d7b00
AM
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;
d337f35e 8319+
d33d7b00
AM
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+ }
d337f35e 8340+
d33d7b00
AM
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+}
d337f35e 8346+
d33d7b00
AM
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;
7a9e40b8 8351+ unsigned long irqflags;
d33d7b00 8352+ int ret = 1;
d337f35e 8353+
d33d7b00
AM
8354+ if (!nxi)
8355+ goto out;
d337f35e 8356+
d33d7b00
AM
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;
4bf69007 8374+
d33d7b00 8375+ /* check for v4 addresses */
7a9e40b8 8376+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
8377+ for (nxa = &nxi->v4; nxa; nxa = nxa->next)
8378+ if (v4_addr_match(nxa, addr, tmask))
4bf69007 8379+ goto out_unlock;
d33d7b00 8380+ ret = 0;
4bf69007 8381+out_unlock:
7a9e40b8 8382+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
d33d7b00
AM
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+}
d337f35e 8389+
d33d7b00
AM
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+}
d337f35e 8396+
d33d7b00
AM
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;
7a9e40b8 8401+ unsigned long irqflags;
4bf69007 8402+ int ret = 1;
d337f35e 8403+
7a9e40b8 8404+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
8405+ for (ptr = &nxi->v4; ptr; ptr = ptr->next)
8406+ if (v4_nx_addr_match(ptr, nxa, mask))
4bf69007
AM
8407+ goto out_unlock;
8408+ ret = 0;
8409+out_unlock:
7a9e40b8 8410+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007 8411+ return ret;
d33d7b00 8412+}
d337f35e 8413+
d33d7b00 8414+#include <net/inet_sock.h>
d337f35e 8415+
d33d7b00
AM
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;
d337f35e 8430+
d33d7b00
AM
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+}
d337f35e 8437+
d337f35e 8438+
d33d7b00 8439+/* inet related checks and helpers */
d337f35e
JR
8440+
8441+
d33d7b00
AM
8442+struct in_ifaddr;
8443+struct net_device;
8444+struct sock;
d337f35e 8445+
d33d7b00 8446+#ifdef CONFIG_INET
d337f35e 8447+
d33d7b00
AM
8448+#include <linux/netdevice.h>
8449+#include <linux/inetdevice.h>
8450+#include <net/inet_sock.h>
8451+#include <net/inet_timewait_sock.h>
d337f35e 8452+
d337f35e 8453+
d33d7b00
AM
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 *);
d337f35e 8457+
d337f35e 8458+
d33d7b00
AM
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+ */
d337f35e 8465+
d33d7b00
AM
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;
c2e5f7c8 8470+ __be32 saddr = sk->sk_rcv_saddr;
d337f35e 8471+
d33d7b00
AM
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));
d337f35e 8476+
d33d7b00
AM
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+}
d337f35e
JR
8485+
8486+
d337f35e 8487+
d33d7b00
AM
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);
d337f35e 8495+
d33d7b00
AM
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+}
d337f35e
JR
8502+
8503+
d33d7b00
AM
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+}
d337f35e 8513+
d33d7b00
AM
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);
d337f35e 8520+
d33d7b00
AM
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+}
d337f35e 8527+
d337f35e 8528+
d33d7b00
AM
8529+struct nx_v4_sock_addr {
8530+ __be32 saddr; /* Address used for validation */
8531+ __be32 baddr; /* Address used for socket bind */
8532+};
d337f35e 8533+
d33d7b00
AM
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;
d337f35e 8542+
d33d7b00
AM
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));
d337f35e 8548+
d33d7b00
AM
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;
9795bf04
AM
8556+ } else if (!ipv4_is_multicast(saddr) ||
8557+ !nx_info_ncaps(nxi, NXC_MULTICAST)) {
8558+ /* normal address bind */
d33d7b00
AM
8559+ if (!v4_addr_in_nx_info(nxi, saddr, NXA_MASK_BIND))
8560+ return -EADDRNOTAVAIL;
8561+ }
8562+ }
d337f35e 8563+
d33d7b00
AM
8564+ vxdprintk(VXD_CBIT(net, 3),
8565+ "inet_bind(%p) " NIPQUAD_FMT ", " NIPQUAD_FMT,
8566+ sk, NIPQUAD(saddr), NIPQUAD(baddr));
d337f35e 8567+
d33d7b00
AM
8568+ nsa->saddr = saddr;
8569+ nsa->baddr = baddr;
8570+ return 0;
8571+}
d337f35e 8572+
d33d7b00
AM
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+}
d337f35e 8579+
d337f35e 8580+
d33d7b00
AM
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+}
d337f35e 8599+
d33d7b00
AM
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+}
d337f35e 8607+
d33d7b00
AM
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+}
d337f35e 8619+
d33d7b00 8620+#else /* CONFIG_INET */
d337f35e 8621+
d33d7b00
AM
8622+static inline
8623+int nx_dev_visible(struct nx_info *n, struct net_device *d)
8624+{
8625+ return 1;
8626+}
d337f35e 8627+
d33d7b00
AM
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+}
d337f35e 8633+
d33d7b00
AM
8634+static inline
8635+int v4_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
8636+{
8637+ return 1;
8638+}
d337f35e 8639+
d33d7b00
AM
8640+static inline
8641+int nx_info_has_v4(struct nx_info *nxi)
8642+{
8643+ return 0;
8644+}
d337f35e 8645+
d33d7b00 8646+#endif /* CONFIG_INET */
d337f35e 8647+
d33d7b00
AM
8648+#define current_nx_info_has_v4() \
8649+ nx_info_has_v4(current_nx_info())
d337f35e 8650+
d33d7b00
AM
8651+#else
8652+// #warning duplicate inclusion
3bac966d 8653+#endif
f973f73f
AM
8654diff -NurpP --minimal linux-4.1.27/include/linux/vs_inet6.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_inet6.h
8655--- linux-4.1.27/include/linux/vs_inet6.h 1970-01-01 00:00:00.000000000 +0000
8656+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_inet6.h 2016-07-05 04:41:47.000000000 +0000
5cb1760b 8657@@ -0,0 +1,257 @@
d33d7b00
AM
8658+#ifndef _VS_INET6_H
8659+#define _VS_INET6_H
4a036bed 8660+
d33d7b00
AM
8661+#include "vserver/base.h"
8662+#include "vserver/network.h"
8663+#include "vserver/debug.h"
d337f35e 8664+
d33d7b00 8665+#include <net/ipv6.h>
d337f35e 8666+
d33d7b00
AM
8667+#define NXAV6(a) &(a)->ip, &(a)->mask, (a)->prefix, (a)->type
8668+#define NXAV6_FMT "[%pI6/%pI6/%d:%04x]"
7e46296a 8669+
7e46296a 8670+
d33d7b00 8671+#ifdef CONFIG_IPV6
7e46296a 8672+
d33d7b00
AM
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;
7e46296a 8678+
d33d7b00
AM
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+}
7e46296a 8695+
d33d7b00
AM
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;
7a9e40b8 8701+ unsigned long irqflags;
d33d7b00 8702+ int ret = 1;
d337f35e 8703+
d33d7b00
AM
8704+ if (!nxi)
8705+ goto out;
4bf69007 8706+
7a9e40b8 8707+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
8708+ for (nxa = &nxi->v6; nxa; nxa = nxa->next)
8709+ if (v6_addr_match(nxa, addr, mask))
4bf69007 8710+ goto out_unlock;
d33d7b00 8711+ ret = 0;
4bf69007 8712+out_unlock:
7a9e40b8 8713+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
d33d7b00
AM
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+}
d337f35e 8720+
d33d7b00
AM
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+}
d337f35e 8727+
d33d7b00
AM
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;
7a9e40b8 8732+ unsigned long irqflags;
4bf69007 8733+ int ret = 1;
d337f35e 8734+
7a9e40b8 8735+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
8736+ for (ptr = &nxi->v6; ptr; ptr = ptr->next)
8737+ if (v6_nx_addr_match(ptr, nxa, mask))
4bf69007
AM
8738+ goto out_unlock;
8739+ ret = 0;
8740+out_unlock:
7a9e40b8 8741+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007 8742+ return ret;
d33d7b00 8743+}
d337f35e 8744+
d337f35e 8745+
d33d7b00
AM
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;
c2e5f7c8 8759+ const struct in6_addr *saddr = inet6_rcv_saddr(sk);
d337f35e 8760+
d33d7b00
AM
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+}
d337f35e 8768+
d33d7b00
AM
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+ */
d337f35e 8775+
d33d7b00
AM
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;
c2e5f7c8 8780+ const struct in6_addr *saddr = inet6_rcv_saddr(sk);
d337f35e 8781+
d33d7b00
AM
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));
d337f35e 8786+
d33d7b00
AM
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+}
d337f35e 8795+
d337f35e 8796+
d33d7b00 8797+/* inet related checks and helpers */
d337f35e 8798+
d337f35e 8799+
d33d7b00
AM
8800+struct in_ifaddr;
8801+struct net_device;
8802+struct sock;
d337f35e
JR
8803+
8804+
d33d7b00
AM
8805+#include <linux/netdevice.h>
8806+#include <linux/inetdevice.h>
8807+#include <net/inet_timewait_sock.h>
d337f35e 8808+
d337f35e 8809+
d33d7b00
AM
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 *);
d337f35e
JR
8813+
8814+
3bac966d 8815+
d33d7b00
AM
8816+static inline
8817+int v6_ifa_in_nx_info(struct inet6_ifaddr *ifa, struct nx_info *nxi)
adc1caaa 8818+{
d33d7b00
AM
8819+ if (!nxi)
8820+ return 1;
8821+ if (!ifa)
8822+ return 0;
8823+ return v6_addr_in_nx_info(nxi, &ifa->addr, -1);
8824+}
d337f35e 8825+
d33d7b00
AM
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);
d337f35e 8832+
d33d7b00
AM
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;
adc1caaa 8838+}
d337f35e 8839+
d337f35e 8840+
d33d7b00
AM
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;
3bac966d 8854+
d33d7b00
AM
8855+ nsa->saddr = saddr;
8856+ nsa->baddr = baddr;
8857+ return 0;
8858+}
3bac966d 8859+
d33d7b00
AM
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);
3bac966d 8865+
d33d7b00
AM
8866+ // *saddr = nsa->baddr;
8867+ // inet->inet_saddr = nsa->baddr;
8868+}
3bac966d 8869+
d33d7b00
AM
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+}
3bac966d 8879+
d33d7b00 8880+#else /* CONFIG_IPV6 */
d337f35e 8881+
2380c486 8882+static inline
d33d7b00 8883+int nx_v6_dev_visible(struct nx_info *n, struct net_device *d)
2380c486 8884+{
d33d7b00 8885+ return 1;
d337f35e
JR
8886+}
8887+
3bac966d 8888+
adc1caaa 8889+static inline
d33d7b00 8890+int nx_v6_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
adc1caaa 8891+{
d33d7b00 8892+ return 1;
adc1caaa 8893+}
2380c486 8894+
d33d7b00
AM
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+}
2380c486 8906+
d33d7b00 8907+#endif /* CONFIG_IPV6 */
d337f35e 8908+
d33d7b00
AM
8909+#define current_nx_info_has_v6() \
8910+ nx_info_has_v6(current_nx_info())
3bac966d 8911+
d337f35e 8912+#else
d33d7b00 8913+#warning duplicate inclusion
d337f35e 8914+#endif
f973f73f
AM
8915diff -NurpP --minimal linux-4.1.27/include/linux/vs_limit.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_limit.h
8916--- linux-4.1.27/include/linux/vs_limit.h 1970-01-01 00:00:00.000000000 +0000
8917+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_limit.h 2016-07-05 04:41:47.000000000 +0000
d33d7b00
AM
8918@@ -0,0 +1,140 @@
8919+#ifndef _VS_LIMIT_H
8920+#define _VS_LIMIT_H
d337f35e 8921+
d33d7b00
AM
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"
d337f35e
JR
8928+
8929+
d33d7b00
AM
8930+#define vx_acc_cres(v, d, p, r) \
8931+ __vx_acc_cres(v, r, d, p, __FILE__, __LINE__)
d337f35e 8932+
d33d7b00
AM
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__)
d337f35e
JR
8936+
8937+
d33d7b00
AM
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)
d337f35e 8941+
d33d7b00
AM
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)
d337f35e 8946+
d337f35e 8947+
d33d7b00 8948+/* process and file limits */
d337f35e 8949+
d33d7b00
AM
8950+#define vx_nproc_inc(p) \
8951+ vx_acc_cres((p)->vx_info, 1, p, RLIMIT_NPROC)
d337f35e 8952+
d33d7b00
AM
8953+#define vx_nproc_dec(p) \
8954+ vx_acc_cres((p)->vx_info,-1, p, RLIMIT_NPROC)
d337f35e 8955+
d33d7b00
AM
8956+#define vx_files_inc(f) \
8957+ vx_acc_cres_cond((f)->f_xid, 1, f, RLIMIT_NOFILE)
d337f35e 8958+
d33d7b00
AM
8959+#define vx_files_dec(f) \
8960+ vx_acc_cres_cond((f)->f_xid,-1, f, RLIMIT_NOFILE)
d337f35e 8961+
d33d7b00
AM
8962+#define vx_locks_inc(l) \
8963+ vx_acc_cres_cond((l)->fl_xid, 1, l, RLIMIT_LOCKS)
d337f35e 8964+
d33d7b00
AM
8965+#define vx_locks_dec(l) \
8966+ vx_acc_cres_cond((l)->fl_xid,-1, l, RLIMIT_LOCKS)
d337f35e 8967+
d33d7b00
AM
8968+#define vx_openfd_inc(f) \
8969+ vx_acc_cres(current_vx_info(), 1, (void *)(long)(f), VLIMIT_OPENFD)
d337f35e 8970+
d33d7b00
AM
8971+#define vx_openfd_dec(f) \
8972+ vx_acc_cres(current_vx_info(),-1, (void *)(long)(f), VLIMIT_OPENFD)
d337f35e 8973+
d337f35e 8974+
d33d7b00
AM
8975+#define vx_cres_avail(v, n, r) \
8976+ __vx_cres_avail(v, r, n, __FILE__, __LINE__)
d337f35e 8977+
d337f35e 8978+
d33d7b00
AM
8979+#define vx_nproc_avail(n) \
8980+ vx_cres_avail(current_vx_info(), n, RLIMIT_NPROC)
d337f35e 8981+
d33d7b00
AM
8982+#define vx_files_avail(n) \
8983+ vx_cres_avail(current_vx_info(), n, RLIMIT_NOFILE)
d337f35e 8984+
d33d7b00
AM
8985+#define vx_locks_avail(n) \
8986+ vx_cres_avail(current_vx_info(), n, RLIMIT_LOCKS)
d337f35e 8987+
d33d7b00
AM
8988+#define vx_openfd_avail(n) \
8989+ vx_cres_avail(current_vx_info(), n, VLIMIT_OPENFD)
d337f35e 8990+
d337f35e 8991+
d33d7b00 8992+/* dentry limits */
d337f35e 8993+
d33d7b00 8994+#define vx_dentry_inc(d) do { \
c2e5f7c8 8995+ if (d_count(d) == 1) \
d33d7b00
AM
8996+ vx_acc_cres(current_vx_info(), 1, d, VLIMIT_DENTRY); \
8997+ } while (0)
d337f35e 8998+
d33d7b00 8999+#define vx_dentry_dec(d) do { \
c2e5f7c8 9000+ if (d_count(d) == 0) \
d33d7b00
AM
9001+ vx_acc_cres(current_vx_info(),-1, d, VLIMIT_DENTRY); \
9002+ } while (0)
d337f35e 9003+
d33d7b00
AM
9004+#define vx_dentry_avail(n) \
9005+ vx_cres_avail(current_vx_info(), n, VLIMIT_DENTRY)
d337f35e 9006+
d337f35e 9007+
d33d7b00 9008+/* socket limits */
d337f35e 9009+
d33d7b00
AM
9010+#define vx_sock_inc(s) \
9011+ vx_acc_cres((s)->sk_vx_info, 1, s, VLIMIT_NSOCK)
d337f35e 9012+
d33d7b00
AM
9013+#define vx_sock_dec(s) \
9014+ vx_acc_cres((s)->sk_vx_info,-1, s, VLIMIT_NSOCK)
d337f35e 9015+
d33d7b00
AM
9016+#define vx_sock_avail(n) \
9017+ vx_cres_avail(current_vx_info(), n, VLIMIT_NSOCK)
d337f35e 9018+
d337f35e 9019+
d33d7b00 9020+/* ipc resource limits */
d337f35e 9021+
d33d7b00
AM
9022+#define vx_ipcmsg_add(v, u, a) \
9023+ vx_add_cres(v, a, u, RLIMIT_MSGQUEUE)
d337f35e 9024+
d33d7b00
AM
9025+#define vx_ipcmsg_sub(v, u, a) \
9026+ vx_sub_cres(v, a, u, RLIMIT_MSGQUEUE)
d337f35e 9027+
d33d7b00
AM
9028+#define vx_ipcmsg_avail(v, a) \
9029+ vx_cres_avail(v, a, RLIMIT_MSGQUEUE)
d337f35e 9030+
d337f35e 9031+
d33d7b00
AM
9032+#define vx_ipcshm_add(v, k, a) \
9033+ vx_add_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
d337f35e 9034+
d33d7b00
AM
9035+#define vx_ipcshm_sub(v, k, a) \
9036+ vx_sub_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
d337f35e 9037+
d33d7b00
AM
9038+#define vx_ipcshm_avail(v, a) \
9039+ vx_cres_avail(v, a, VLIMIT_SHMEM)
d337f35e
JR
9040+
9041+
d33d7b00
AM
9042+#define vx_semary_inc(a) \
9043+ vx_acc_cres(current_vx_info(), 1, a, VLIMIT_SEMARY)
d337f35e 9044+
d33d7b00
AM
9045+#define vx_semary_dec(a) \
9046+ vx_acc_cres(current_vx_info(), -1, a, VLIMIT_SEMARY)
d337f35e 9047+
d337f35e 9048+
d33d7b00
AM
9049+#define vx_nsems_add(a,n) \
9050+ vx_add_cres(current_vx_info(), n, a, VLIMIT_NSEMS)
d337f35e 9051+
d33d7b00
AM
9052+#define vx_nsems_sub(a,n) \
9053+ vx_sub_cres(current_vx_info(), n, a, VLIMIT_NSEMS)
d337f35e
JR
9054+
9055+
d33d7b00
AM
9056+#else
9057+#warning duplicate inclusion
9058+#endif
f973f73f
AM
9059diff -NurpP --minimal linux-4.1.27/include/linux/vs_network.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_network.h
9060--- linux-4.1.27/include/linux/vs_network.h 1970-01-01 00:00:00.000000000 +0000
9061+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_network.h 2016-07-05 04:41:47.000000000 +0000
d33d7b00
AM
9062@@ -0,0 +1,169 @@
9063+#ifndef _NX_VS_NETWORK_H
9064+#define _NX_VS_NETWORK_H
7e46296a 9065+
d33d7b00
AM
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"
2380c486 9071+
d33d7b00 9072+#include <linux/sched.h>
2380c486 9073+
2380c486 9074+
d33d7b00 9075+#define get_nx_info(i) __get_nx_info(i, __FILE__, __LINE__)
2380c486 9076+
d33d7b00
AM
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;
d337f35e 9082+
d33d7b00
AM
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);
d337f35e 9087+
d33d7b00
AM
9088+ atomic_inc(&nxi->nx_usecnt);
9089+ return nxi;
9090+}
d337f35e
JR
9091+
9092+
d33d7b00 9093+extern void free_nx_info(struct nx_info *);
d337f35e 9094+
d33d7b00 9095+#define put_nx_info(i) __put_nx_info(i, __FILE__, __LINE__)
d337f35e 9096+
d33d7b00
AM
9097+static inline void __put_nx_info(struct nx_info *nxi, const char *_file, int _line)
9098+{
9099+ if (!nxi)
9100+ return;
d337f35e 9101+
d33d7b00
AM
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);
d337f35e 9106+
d33d7b00
AM
9107+ if (atomic_dec_and_test(&nxi->nx_usecnt))
9108+ free_nx_info(nxi);
9109+}
d337f35e 9110+
d337f35e 9111+
d33d7b00 9112+#define init_nx_info(p, i) __init_nx_info(p, i, __FILE__, __LINE__)
d337f35e 9113+
d33d7b00
AM
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);
d337f35e 9123+
d33d7b00
AM
9124+ atomic_inc(&nxi->nx_usecnt);
9125+ }
9126+ *nxp = nxi;
9127+}
d337f35e 9128+
d337f35e 9129+
d33d7b00 9130+#define set_nx_info(p, i) __set_nx_info(p, i, __FILE__, __LINE__)
d337f35e 9131+
d33d7b00
AM
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;
d337f35e 9136+
d33d7b00
AM
9137+ if (!nxi)
9138+ return;
d337f35e 9139+
d33d7b00
AM
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);
d337f35e 9144+
d33d7b00
AM
9145+ atomic_inc(&nxi->nx_usecnt);
9146+ nxo = xchg(nxp, nxi);
9147+ BUG_ON(nxo);
9148+}
d337f35e 9149+
d33d7b00 9150+#define clr_nx_info(p) __clr_nx_info(p, __FILE__, __LINE__)
d337f35e 9151+
d33d7b00
AM
9152+static inline void __clr_nx_info(struct nx_info **nxp,
9153+ const char *_file, int _line)
9154+{
9155+ struct nx_info *nxo;
d337f35e 9156+
d33d7b00
AM
9157+ nxo = xchg(nxp, NULL);
9158+ if (!nxo)
9159+ return;
d337f35e 9160+
d33d7b00
AM
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);
d337f35e 9165+
d33d7b00
AM
9166+ if (atomic_dec_and_test(&nxo->nx_usecnt))
9167+ free_nx_info(nxo);
9168+}
d337f35e
JR
9169+
9170+
d33d7b00 9171+#define claim_nx_info(v, p) __claim_nx_info(v, p, __FILE__, __LINE__)
d337f35e 9172+
d33d7b00
AM
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);
d337f35e 9181+
d33d7b00
AM
9182+ atomic_inc(&nxi->nx_tasks);
9183+}
d337f35e 9184+
d337f35e 9185+
d33d7b00 9186+extern void unhash_nx_info(struct nx_info *);
d337f35e 9187+
d33d7b00 9188+#define release_nx_info(v, p) __release_nx_info(v, p, __FILE__, __LINE__)
d337f35e 9189+
d33d7b00
AM
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);
ab30d09f 9198+
d33d7b00 9199+ might_sleep();
d337f35e 9200+
d33d7b00
AM
9201+ if (atomic_dec_and_test(&nxi->nx_tasks))
9202+ unhash_nx_info(nxi);
9203+}
d337f35e
JR
9204+
9205+
d33d7b00 9206+#define task_get_nx_info(i) __task_get_nx_info(i, __FILE__, __LINE__)
d337f35e 9207+
d33d7b00
AM
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;
d337f35e 9212+
d33d7b00
AM
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+}
d337f35e 9220+
d337f35e 9221+
d33d7b00
AM
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+}
adc1caaa 9227+
d337f35e 9228+
2380c486 9229+#else
d33d7b00 9230+#warning duplicate inclusion
2380c486 9231+#endif
f973f73f
AM
9232diff -NurpP --minimal linux-4.1.27/include/linux/vs_pid.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_pid.h
9233--- linux-4.1.27/include/linux/vs_pid.h 1970-01-01 00:00:00.000000000 +0000
9234+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_pid.h 2016-07-05 04:41:47.000000000 +0000
b3b0d4fd 9235@@ -0,0 +1,50 @@
d33d7b00
AM
9236+#ifndef _VS_PID_H
9237+#define _VS_PID_H
d337f35e 9238+
d33d7b00
AM
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>
d337f35e 9245+
d337f35e 9246+
d33d7b00 9247+#define VXF_FAKE_INIT (VXF_INFO_INIT | VXF_STATE_INIT)
d337f35e 9248+
d33d7b00
AM
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+}
d337f35e 9262+
d33d7b00 9263+#define find_task_by_real_pid(pid) find_task_by_pid_ns(pid, &init_pid_ns)
d337f35e 9264+
d337f35e 9265+
d33d7b00
AM
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);
d337f35e 9270+
d33d7b00
AM
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+}
d337f35e 9281+
d337f35e 9282+
d33d7b00
AM
9283+#else
9284+#warning duplicate inclusion
9285+#endif
f973f73f
AM
9286diff -NurpP --minimal linux-4.1.27/include/linux/vs_sched.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_sched.h
9287--- linux-4.1.27/include/linux/vs_sched.h 1970-01-01 00:00:00.000000000 +0000
9288+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_sched.h 2016-07-05 04:41:47.000000000 +0000
d33d7b00
AM
9289@@ -0,0 +1,40 @@
9290+#ifndef _VS_SCHED_H
9291+#define _VS_SCHED_H
d337f35e 9292+
d33d7b00
AM
9293+#include "vserver/base.h"
9294+#include "vserver/context.h"
9295+#include "vserver/sched.h"
d337f35e
JR
9296+
9297+
d33d7b00
AM
9298+#define MAX_PRIO_BIAS 20
9299+#define MIN_PRIO_BIAS -20
d337f35e 9300+
d33d7b00
AM
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;
d337f35e 9305+
d33d7b00
AM
9306+ if (vxi)
9307+ prio += vx_cpu(vxi, sched_pc).prio_bias;
9308+ return prio;
9309+}
d337f35e 9310+
d33d7b00
AM
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+}
d337f35e 9318+
d33d7b00
AM
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+}
d337f35e 9326+
d33d7b00
AM
9327+#else
9328+#warning duplicate inclusion
9329+#endif
f973f73f
AM
9330diff -NurpP --minimal linux-4.1.27/include/linux/vs_socket.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_socket.h
9331--- linux-4.1.27/include/linux/vs_socket.h 1970-01-01 00:00:00.000000000 +0000
9332+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_socket.h 2016-07-05 04:41:47.000000000 +0000
d33d7b00
AM
9333@@ -0,0 +1,67 @@
9334+#ifndef _VS_SOCKET_H
9335+#define _VS_SOCKET_H
d337f35e 9336+
d33d7b00
AM
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"
d337f35e 9342+
d337f35e 9343+
d33d7b00 9344+/* socket accounting */
d337f35e 9345+
d33d7b00 9346+#include <linux/socket.h>
d337f35e 9347+
d33d7b00
AM
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+}
d337f35e 9365+
d33d7b00
AM
9366+#define vx_acc_sock(v, f, p, s) \
9367+ __vx_acc_sock(v, f, p, s, __FILE__, __LINE__)
d337f35e 9368+
d33d7b00
AM
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);
d337f35e 9374+
d33d7b00
AM
9375+ atomic_long_inc(&vxi->cacct.sock[type][pos].count);
9376+ atomic_long_add(size, &vxi->cacct.sock[type][pos].total);
9377+ }
9378+}
d337f35e 9379+
d33d7b00
AM
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)
d337f35e 9386+
d337f35e 9387+
d33d7b00
AM
9388+#define sock_vx_init(s) do { \
9389+ (s)->sk_xid = 0; \
9390+ (s)->sk_vx_info = NULL; \
9391+ } while (0)
d337f35e 9392+
d33d7b00
AM
9393+#define sock_nx_init(s) do { \
9394+ (s)->sk_nid = 0; \
9395+ (s)->sk_nx_info = NULL; \
9396+ } while (0)
d337f35e 9397+
d33d7b00
AM
9398+#else
9399+#warning duplicate inclusion
9400+#endif
f973f73f
AM
9401diff -NurpP --minimal linux-4.1.27/include/linux/vs_tag.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_tag.h
9402--- linux-4.1.27/include/linux/vs_tag.h 1970-01-01 00:00:00.000000000 +0000
9403+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_tag.h 2016-07-05 04:41:47.000000000 +0000
d33d7b00
AM
9404@@ -0,0 +1,47 @@
9405+#ifndef _VS_TAG_H
9406+#define _VS_TAG_H
d337f35e 9407+
d33d7b00 9408+#include <linux/vserver/tag.h>
d337f35e 9409+
d33d7b00 9410+/* check conditions */
d337f35e 9411+
d33d7b00
AM
9412+#define DX_ADMIN 0x0001
9413+#define DX_WATCH 0x0002
9414+#define DX_HOSTID 0x0008
d337f35e 9415+
d33d7b00 9416+#define DX_IDENT 0x0010
d337f35e 9417+
d33d7b00 9418+#define DX_ARG_MASK 0x0010
d337f35e 9419+
d337f35e 9420+
d33d7b00 9421+#define dx_task_tag(t) ((t)->tag)
d337f35e 9422+
d33d7b00 9423+#define dx_current_tag() dx_task_tag(current)
d337f35e 9424+
d33d7b00 9425+#define dx_check(c, m) __dx_check(dx_current_tag(), c, m)
d337f35e 9426+
d33d7b00 9427+#define dx_weak_check(c, m) ((m) ? dx_check(c, m) : 1)
d337f35e
JR
9428+
9429+
d33d7b00
AM
9430+/*
9431+ * check current context for ADMIN/WATCH and
9432+ * optionally against supplied argument
9433+ */
61333608 9434+static inline int __dx_check(vtag_t cid, vtag_t id, unsigned int mode)
d33d7b00
AM
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+}
d337f35e 9444+
d33d7b00
AM
9445+struct inode;
9446+int dx_permission(const struct inode *inode, int mask);
d337f35e 9447+
d337f35e 9448+
d33d7b00
AM
9449+#else
9450+#warning duplicate inclusion
9451+#endif
f973f73f
AM
9452diff -NurpP --minimal linux-4.1.27/include/linux/vs_time.h linux-4.1.27-vs2.3.8.5.2/include/linux/vs_time.h
9453--- linux-4.1.27/include/linux/vs_time.h 1970-01-01 00:00:00.000000000 +0000
9454+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vs_time.h 2016-07-05 04:41:47.000000000 +0000
d33d7b00
AM
9455@@ -0,0 +1,19 @@
9456+#ifndef _VS_TIME_H
9457+#define _VS_TIME_H
d337f35e 9458+
d337f35e 9459+
d33d7b00 9460+/* time faking stuff */
d337f35e 9461+
d33d7b00 9462+#ifdef CONFIG_VSERVER_VTIME
d337f35e 9463+
d33d7b00 9464+extern void vx_adjust_timespec(struct timespec *ts);
763640ca 9465+extern int vx_settimeofday(const struct timespec *ts);
d337f35e 9466+
d33d7b00
AM
9467+#else
9468+#define vx_adjust_timespec(t) do { } while (0)
9469+#define vx_settimeofday(t) do_settimeofday(t)
9470+#endif
d337f35e 9471+
d33d7b00
AM
9472+#else
9473+#warning duplicate inclusion
9474+#endif
f973f73f
AM
9475diff -NurpP --minimal linux-4.1.27/include/linux/vserver/base.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/base.h
9476--- linux-4.1.27/include/linux/vserver/base.h 1970-01-01 00:00:00.000000000 +0000
9477+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/base.h 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 9478@@ -0,0 +1,184 @@
4bf69007
AM
9479+#ifndef _VSERVER_BASE_H
9480+#define _VSERVER_BASE_H
d337f35e 9481+
d337f35e 9482+
d33d7b00 9483+/* context state changes */
d337f35e 9484+
d33d7b00
AM
9485+enum {
9486+ VSC_STARTUP = 1,
9487+ VSC_SHUTDOWN,
d337f35e 9488+
d33d7b00
AM
9489+ VSC_NETUP,
9490+ VSC_NETDOWN,
3bac966d 9491+};
d337f35e 9492+
d337f35e
JR
9493+
9494+
d33d7b00 9495+#define vx_task_xid(t) ((t)->xid)
d337f35e 9496+
d33d7b00 9497+#define vx_current_xid() vx_task_xid(current)
d337f35e 9498+
d33d7b00 9499+#define current_vx_info() (current->vx_info)
d337f35e 9500+
ba86f833 9501+
d33d7b00 9502+#define nx_task_nid(t) ((t)->nid)
ba86f833 9503+
d33d7b00 9504+#define nx_current_nid() nx_task_nid(current)
d337f35e 9505+
d33d7b00 9506+#define current_nx_info() (current->nx_info)
d337f35e 9507+
d337f35e 9508+
d33d7b00 9509+/* generic flag merging */
d337f35e 9510+
d33d7b00 9511+#define vs_check_flags(v, m, f) (((v) & (m)) ^ (f))
d337f35e 9512+
d33d7b00 9513+#define vs_mask_flags(v, f, m) (((v) & ~(m)) | ((f) & (m)))
d337f35e 9514+
d33d7b00 9515+#define vs_mask_mask(v, f, m) (((v) & ~(m)) | ((v) & (f) & (m)))
d337f35e 9516+
d33d7b00 9517+#define vs_check_bit(v, n) ((v) & (1LL << (n)))
d337f35e 9518+
d337f35e 9519+
d33d7b00 9520+/* context flags */
d337f35e 9521+
d33d7b00 9522+#define __vx_flags(v) ((v) ? (v)->vx_flags : 0)
d337f35e 9523+
d33d7b00 9524+#define vx_current_flags() __vx_flags(current_vx_info())
d337f35e 9525+
d33d7b00
AM
9526+#define vx_info_flags(v, m, f) \
9527+ vs_check_flags(__vx_flags(v), m, f)
d337f35e 9528+
d33d7b00
AM
9529+#define task_vx_flags(t, m, f) \
9530+ ((t) && vx_info_flags((t)->vx_info, m, f))
d337f35e 9531+
d33d7b00 9532+#define vx_flags(m, f) vx_info_flags(current_vx_info(), m, f)
d337f35e
JR
9533+
9534+
d33d7b00 9535+/* context caps */
d337f35e 9536+
d33d7b00 9537+#define __vx_ccaps(v) ((v) ? (v)->vx_ccaps : 0)
d337f35e 9538+
d33d7b00 9539+#define vx_current_ccaps() __vx_ccaps(current_vx_info())
d337f35e 9540+
d33d7b00 9541+#define vx_info_ccaps(v, c) (__vx_ccaps(v) & (c))
d337f35e 9542+
d33d7b00 9543+#define vx_ccaps(c) vx_info_ccaps(current_vx_info(), (c))
d337f35e 9544+
d337f35e
JR
9545+
9546+
d33d7b00 9547+/* network flags */
2380c486 9548+
d33d7b00 9549+#define __nx_flags(n) ((n) ? (n)->nx_flags : 0)
d337f35e 9550+
d33d7b00 9551+#define nx_current_flags() __nx_flags(current_nx_info())
d337f35e 9552+
d33d7b00
AM
9553+#define nx_info_flags(n, m, f) \
9554+ vs_check_flags(__nx_flags(n), m, f)
d337f35e 9555+
d33d7b00
AM
9556+#define task_nx_flags(t, m, f) \
9557+ ((t) && nx_info_flags((t)->nx_info, m, f))
d337f35e 9558+
d33d7b00 9559+#define nx_flags(m, f) nx_info_flags(current_nx_info(), m, f)
d337f35e 9560+
d337f35e 9561+
d33d7b00 9562+/* network caps */
d337f35e 9563+
d33d7b00 9564+#define __nx_ncaps(n) ((n) ? (n)->nx_ncaps : 0)
d337f35e 9565+
d33d7b00 9566+#define nx_current_ncaps() __nx_ncaps(current_nx_info())
d337f35e 9567+
d33d7b00 9568+#define nx_info_ncaps(n, c) (__nx_ncaps(n) & (c))
d337f35e 9569+
d33d7b00 9570+#define nx_ncaps(c) nx_info_ncaps(current_nx_info(), c)
d337f35e 9571+
d337f35e 9572+
d33d7b00 9573+/* context mask capabilities */
d337f35e 9574+
d33d7b00 9575+#define __vx_mcaps(v) ((v) ? (v)->vx_ccaps >> 32UL : ~0 )
d337f35e 9576+
d33d7b00 9577+#define vx_info_mcaps(v, c) (__vx_mcaps(v) & (c))
d337f35e 9578+
d33d7b00 9579+#define vx_mcaps(c) vx_info_mcaps(current_vx_info(), c)
d337f35e
JR
9580+
9581+
d33d7b00 9582+/* context bcap mask */
d337f35e 9583+
d33d7b00 9584+#define __vx_bcaps(v) ((v)->vx_bcaps)
d337f35e 9585+
d33d7b00 9586+#define vx_current_bcaps() __vx_bcaps(current_vx_info())
d337f35e 9587+
d337f35e 9588+
d33d7b00 9589+/* mask given bcaps */
adc1caaa 9590+
d33d7b00 9591+#define vx_info_mbcaps(v, c) ((v) ? cap_intersect(__vx_bcaps(v), c) : c)
2380c486 9592+
d33d7b00 9593+#define vx_mbcaps(c) vx_info_mbcaps(current_vx_info(), c)
d337f35e
JR
9594+
9595+
d33d7b00 9596+/* masked cap_bset */
2380c486 9597+
d33d7b00 9598+#define vx_info_cap_bset(v) vx_info_mbcaps(v, current->cap_bset)
2380c486 9599+
d33d7b00 9600+#define vx_current_cap_bset() vx_info_cap_bset(current_vx_info())
d337f35e 9601+
d33d7b00
AM
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))
d337f35e 9606+
d33d7b00
AM
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)
3bac966d 9611+#endif
d337f35e 9612+
d33d7b00 9613+#define vx_cap_raised(v, c, f) cap_raised(vx_info_mbcaps(v, c), f)
d337f35e 9614+
d33d7b00
AM
9615+#define vx_capable(b, c) (capable(b) || \
9616+ (cap_raised(current_cap(), b) && vx_ccaps(c)))
d337f35e 9617+
763640ca
JR
9618+#define vx_ns_capable(n, b, c) (ns_capable(n, b) || \
9619+ (cap_raised(current_cap(), b) && vx_ccaps(c)))
9620+
d33d7b00
AM
9621+#define nx_capable(b, c) (capable(b) || \
9622+ (cap_raised(current_cap(), b) && nx_ncaps(c)))
d337f35e 9623+
c2e5f7c8
JR
9624+#define nx_ns_capable(n, b, c) (ns_capable(n, b) || \
9625+ (cap_raised(current_cap(), b) && nx_ncaps(c)))
9626+
d33d7b00
AM
9627+#define vx_task_initpid(t, n) \
9628+ ((t)->vx_info && \
9629+ ((t)->vx_info->vx_initpid == (n)))
d337f35e 9630+
d33d7b00 9631+#define vx_current_initpid(n) vx_task_initpid(current, n)
d337f35e 9632+
d337f35e 9633+
d33d7b00 9634+/* context unshare mask */
d337f35e 9635+
d33d7b00 9636+#define __vx_umask(v) ((v)->vx_umask)
7e46296a 9637+
d33d7b00 9638+#define vx_current_umask() __vx_umask(current_vx_info())
7e46296a 9639+
d33d7b00
AM
9640+#define vx_can_unshare(b, f) (capable(b) || \
9641+ (cap_raised(current_cap(), b) && \
9642+ !((f) & ~vx_current_umask())))
7e46296a 9643+
b00e13aa
AM
9644+#define vx_ns_can_unshare(n, b, f) (ns_capable(n, b) || \
9645+ (cap_raised(current_cap(), b) && \
9646+ !((f) & ~vx_current_umask())))
7e46296a 9647+
265d6dcc
JR
9648+#define __vx_wmask(v) ((v)->vx_wmask)
9649+
9650+#define vx_current_wmask() __vx_wmask(current_vx_info())
9651+
9652+
d33d7b00 9653+#define __vx_state(v) ((v) ? ((v)->vx_state) : 0)
7e46296a 9654+
d33d7b00 9655+#define vx_info_state(v, m) (__vx_state(v) & (m))
d337f35e 9656+
d337f35e 9657+
d33d7b00 9658+#define __nx_state(n) ((n) ? ((n)->nx_state) : 0)
d337f35e 9659+
d33d7b00 9660+#define nx_info_state(n, m) (__nx_state(n) & (m))
d337f35e 9661+
d33d7b00 9662+#endif
f973f73f
AM
9663diff -NurpP --minimal linux-4.1.27/include/linux/vserver/cacct.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/cacct.h
9664--- linux-4.1.27/include/linux/vserver/cacct.h 1970-01-01 00:00:00.000000000 +0000
9665+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/cacct.h 2016-07-05 04:41:47.000000000 +0000
d33d7b00 9666@@ -0,0 +1,15 @@
4bf69007
AM
9667+#ifndef _VSERVER_CACCT_H
9668+#define _VSERVER_CACCT_H
d337f35e 9669+
d337f35e 9670+
d33d7b00
AM
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+};
d337f35e 9680+
4bf69007 9681+#endif /* _VSERVER_CACCT_H */
f973f73f
AM
9682diff -NurpP --minimal linux-4.1.27/include/linux/vserver/cacct_cmd.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/cacct_cmd.h
9683--- linux-4.1.27/include/linux/vserver/cacct_cmd.h 1970-01-01 00:00:00.000000000 +0000
9684+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/cacct_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
9685@@ -0,0 +1,10 @@
9686+#ifndef _VSERVER_CACCT_CMD_H
9687+#define _VSERVER_CACCT_CMD_H
d337f35e 9688+
d337f35e 9689+
3bac966d 9690+#include <linux/compiler.h>
4bf69007 9691+#include <uapi/vserver/cacct_cmd.h>
d337f35e 9692+
d33d7b00 9693+extern int vc_sock_stat(struct vx_info *, void __user *);
d337f35e 9694+
4bf69007 9695+#endif /* _VSERVER_CACCT_CMD_H */
f973f73f
AM
9696diff -NurpP --minimal linux-4.1.27/include/linux/vserver/cacct_def.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/cacct_def.h
9697--- linux-4.1.27/include/linux/vserver/cacct_def.h 1970-01-01 00:00:00.000000000 +0000
9698+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/cacct_def.h 2016-07-05 04:41:47.000000000 +0000
d33d7b00 9699@@ -0,0 +1,43 @@
4bf69007
AM
9700+#ifndef _VSERVER_CACCT_DEF_H
9701+#define _VSERVER_CACCT_DEF_H
d337f35e 9702+
d33d7b00
AM
9703+#include <asm/atomic.h>
9704+#include <linux/vserver/cacct.h>
d337f35e
JR
9705+
9706+
d33d7b00
AM
9707+struct _vx_sock_acc {
9708+ atomic_long_t count;
9709+ atomic_long_t total;
9710+};
d337f35e 9711+
d33d7b00 9712+/* context sub struct */
d337f35e 9713+
d33d7b00
AM
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+};
d337f35e 9719+
d33d7b00 9720+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 9721+
d33d7b00
AM
9722+static inline void __dump_vx_cacct(struct _vx_cacct *cacct)
9723+{
9724+ int i, j;
d337f35e 9725+
d33d7b00
AM
9726+ printk("\t_vx_cacct:");
9727+ for (i = 0; i < 6; i++) {
9728+ struct _vx_sock_acc *ptr = cacct->sock[i];
d337f35e 9729+
d33d7b00
AM
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+}
2380c486 9739+
d33d7b00 9740+#endif
d337f35e 9741+
4bf69007 9742+#endif /* _VSERVER_CACCT_DEF_H */
f973f73f
AM
9743diff -NurpP --minimal linux-4.1.27/include/linux/vserver/cacct_int.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/cacct_int.h
9744--- linux-4.1.27/include/linux/vserver/cacct_int.h 1970-01-01 00:00:00.000000000 +0000
9745+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/cacct_int.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
9746@@ -0,0 +1,17 @@
9747+#ifndef _VSERVER_CACCT_INT_H
9748+#define _VSERVER_CACCT_INT_H
d337f35e 9749+
d33d7b00
AM
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+}
d337f35e 9755+
d337f35e 9756+
d33d7b00
AM
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+}
d337f35e 9762+
4bf69007 9763+#endif /* _VSERVER_CACCT_INT_H */
f973f73f
AM
9764diff -NurpP --minimal linux-4.1.27/include/linux/vserver/check.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/check.h
9765--- linux-4.1.27/include/linux/vserver/check.h 1970-01-01 00:00:00.000000000 +0000
9766+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/check.h 2016-07-05 04:41:47.000000000 +0000
d33d7b00 9767@@ -0,0 +1,89 @@
4bf69007
AM
9768+#ifndef _VSERVER_CHECK_H
9769+#define _VSERVER_CHECK_H
d337f35e 9770+
d337f35e 9771+
d33d7b00 9772+#define MAX_S_CONTEXT 65535 /* Arbitrary limit */
d337f35e 9773+
d33d7b00
AM
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
d337f35e 9779+
d33d7b00 9780+/* check conditions */
d337f35e 9781+
d33d7b00
AM
9782+#define VS_ADMIN 0x0001
9783+#define VS_WATCH 0x0002
9784+#define VS_HIDE 0x0004
9785+#define VS_HOSTID 0x0008
d337f35e 9786+
d33d7b00
AM
9787+#define VS_IDENT 0x0010
9788+#define VS_EQUIV 0x0020
9789+#define VS_PARENT 0x0040
9790+#define VS_CHILD 0x0080
d337f35e 9791+
d33d7b00 9792+#define VS_ARG_MASK 0x00F0
d337f35e 9793+
d33d7b00
AM
9794+#define VS_DYNAMIC 0x0100
9795+#define VS_STATIC 0x0200
d337f35e 9796+
d33d7b00 9797+#define VS_ATR_MASK 0x0F00
d337f35e 9798+
d33d7b00
AM
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
d337f35e 9806+
d33d7b00
AM
9807+#define VS_HARDIRQ 0x1000
9808+#define VS_SOFTIRQ 0x2000
9809+#define VS_IRQ 0x4000
d337f35e 9810+
d33d7b00 9811+#define VS_IRQ_MASK 0xF000
d337f35e 9812+
d33d7b00 9813+#include <linux/hardirq.h>
d337f35e 9814+
d33d7b00
AM
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+}
d337f35e 9846+
d33d7b00 9847+#define vx_check(c, m) __vs_check(vx_current_xid(), c, (m) | VS_IRQ)
d337f35e 9848+
d33d7b00 9849+#define vx_weak_check(c, m) ((m) ? vx_check(c, m) : 1)
2380c486 9850+
d337f35e 9851+
d33d7b00 9852+#define nx_check(c, m) __vs_check(nx_current_nid(), c, m)
d337f35e 9853+
d33d7b00 9854+#define nx_weak_check(c, m) ((m) ? nx_check(c, m) : 1)
d337f35e 9855+
d33d7b00 9856+#endif
f973f73f
AM
9857diff -NurpP --minimal linux-4.1.27/include/linux/vserver/context.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/context.h
9858--- linux-4.1.27/include/linux/vserver/context.h 1970-01-01 00:00:00.000000000 +0000
9859+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/context.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
9860@@ -0,0 +1,110 @@
9861+#ifndef _VSERVER_CONTEXT_H
9862+#define _VSERVER_CONTEXT_H
d337f35e
JR
9863+
9864+
d33d7b00
AM
9865+#include <linux/list.h>
9866+#include <linux/spinlock.h>
9867+#include <linux/rcupdate.h>
4bf69007 9868+#include <uapi/vserver/context.h>
d337f35e 9869+
d33d7b00
AM
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"
d337f35e 9875+
d33d7b00 9876+#define VX_SPACES 2
d337f35e 9877+
d33d7b00
AM
9878+struct _vx_info_pc {
9879+ struct _vx_sched_pc sched_pc;
9880+ struct _vx_cvirt_pc cvirt_pc;
9881+};
d337f35e 9882+
d33d7b00
AM
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+};
d337f35e 9889+
d33d7b00
AM
9890+struct vx_info {
9891+ struct hlist_node vx_hlist; /* linked list of contexts */
61333608 9892+ vxid_t vx_id; /* context id */
d33d7b00
AM
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 */
d337f35e 9897+
d33d7b00 9898+ struct _vx_space space[VX_SPACES]; /* namespace store */
d337f35e 9899+
d33d7b00
AM
9900+ uint64_t vx_flags; /* context flags */
9901+ uint64_t vx_ccaps; /* context caps (vserver) */
763640ca 9902+ uint64_t vx_umask; /* unshare mask (guest) */
265d6dcc 9903+ uint64_t vx_wmask; /* warn mask (guest) */
d33d7b00 9904+ kernel_cap_t vx_bcaps; /* bounding caps (system) */
d337f35e 9905+
d33d7b00
AM
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 */
d337f35e 9909+
d33d7b00
AM
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 */
d337f35e 9914+
d33d7b00 9915+ struct _vx_device dmap; /* default device map targets */
d337f35e 9916+
d33d7b00
AM
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
d337f35e 9922+
d33d7b00
AM
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 */
d337f35e 9926+
d33d7b00
AM
9927+ char vx_name[65]; /* vserver name */
9928+};
d337f35e 9929+
d33d7b00
AM
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
d337f35e 9937+
d33d7b00 9938+#define vx_cpu(vxi, v) vx_per_cpu(vxi, v, smp_processor_id())
d337f35e 9939+
d337f35e 9940+
d33d7b00
AM
9941+struct vx_info_save {
9942+ struct vx_info *vxi;
61333608 9943+ vxid_t xid;
d33d7b00 9944+};
d337f35e
JR
9945+
9946+
d33d7b00 9947+/* status flags */
d337f35e 9948+
d33d7b00
AM
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
d337f35e 9954+
d337f35e 9955+
d33d7b00
AM
9956+extern void claim_vx_info(struct vx_info *, struct task_struct *);
9957+extern void release_vx_info(struct vx_info *, struct task_struct *);
adc1caaa 9958+
d33d7b00
AM
9959+extern struct vx_info *lookup_vx_info(int);
9960+extern struct vx_info *lookup_or_create_vx_info(int);
d337f35e 9961+
d33d7b00 9962+extern int get_xid_list(int, unsigned int *, int);
61333608 9963+extern int xid_is_hashed(vxid_t);
d337f35e 9964+
d33d7b00 9965+extern int vx_migrate_task(struct task_struct *, struct vx_info *, int);
d337f35e 9966+
d33d7b00 9967+extern long vs_state_change(struct vx_info *, unsigned int);
d337f35e 9968+
d337f35e 9969+
4bf69007 9970+#endif /* _VSERVER_CONTEXT_H */
f973f73f
AM
9971diff -NurpP --minimal linux-4.1.27/include/linux/vserver/context_cmd.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/context_cmd.h
9972--- linux-4.1.27/include/linux/vserver/context_cmd.h 1970-01-01 00:00:00.000000000 +0000
9973+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/context_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
9974@@ -0,0 +1,33 @@
9975+#ifndef _VSERVER_CONTEXT_CMD_H
9976+#define _VSERVER_CONTEXT_CMD_H
d337f35e 9977+
4bf69007 9978+#include <uapi/vserver/context_cmd.h>
d337f35e 9979+
d33d7b00 9980+extern int vc_task_xid(uint32_t);
d337f35e 9981+
d33d7b00 9982+extern int vc_vx_info(struct vx_info *, void __user *);
d337f35e 9983+
d33d7b00 9984+extern int vc_ctx_stat(struct vx_info *, void __user *);
d337f35e 9985+
4bf69007
AM
9986+extern int vc_ctx_create(uint32_t, void __user *);
9987+extern int vc_ctx_migrate(struct vx_info *, void __user *);
d337f35e 9988+
4bf69007
AM
9989+extern int vc_get_cflags(struct vx_info *, void __user *);
9990+extern int vc_set_cflags(struct vx_info *, void __user *);
d337f35e 9991+
4bf69007
AM
9992+extern int vc_get_ccaps(struct vx_info *, void __user *);
9993+extern int vc_set_ccaps(struct vx_info *, void __user *);
d337f35e 9994+
4bf69007
AM
9995+extern int vc_get_bcaps(struct vx_info *, void __user *);
9996+extern int vc_set_bcaps(struct vx_info *, void __user *);
d337f35e 9997+
4bf69007
AM
9998+extern int vc_get_umask(struct vx_info *, void __user *);
9999+extern int vc_set_umask(struct vx_info *, void __user *);
d33d7b00 10000+
4bf69007
AM
10001+extern int vc_get_wmask(struct vx_info *, void __user *);
10002+extern int vc_set_wmask(struct vx_info *, void __user *);
d33d7b00 10003+
4bf69007
AM
10004+extern int vc_get_badness(struct vx_info *, void __user *);
10005+extern int vc_set_badness(struct vx_info *, void __user *);
d337f35e 10006+
4bf69007 10007+#endif /* _VSERVER_CONTEXT_CMD_H */
f973f73f
AM
10008diff -NurpP --minimal linux-4.1.27/include/linux/vserver/cvirt.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/cvirt.h
10009--- linux-4.1.27/include/linux/vserver/cvirt.h 1970-01-01 00:00:00.000000000 +0000
10010+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/cvirt.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
10011@@ -0,0 +1,18 @@
10012+#ifndef _VSERVER_CVIRT_H
10013+#define _VSERVER_CVIRT_H
d337f35e 10014+
4bf69007 10015+struct timespec;
d337f35e 10016+
4bf69007 10017+void vx_vsi_boottime(struct timespec *);
d337f35e 10018+
4bf69007 10019+void vx_vsi_uptime(struct timespec *, struct timespec *);
d337f35e 10020+
d337f35e 10021+
4bf69007 10022+struct vx_info;
d337f35e 10023+
4bf69007 10024+void vx_update_load(struct vx_info *);
d337f35e 10025+
d337f35e 10026+
4bf69007 10027+int vx_do_syslog(int, char __user *, int);
d337f35e 10028+
4bf69007 10029+#endif /* _VSERVER_CVIRT_H */
f973f73f
AM
10030diff -NurpP --minimal linux-4.1.27/include/linux/vserver/cvirt_cmd.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/cvirt_cmd.h
10031--- linux-4.1.27/include/linux/vserver/cvirt_cmd.h 1970-01-01 00:00:00.000000000 +0000
10032+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/cvirt_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
10033@@ -0,0 +1,13 @@
10034+#ifndef _VSERVER_CVIRT_CMD_H
10035+#define _VSERVER_CVIRT_CMD_H
d337f35e 10036+
d337f35e 10037+
4bf69007
AM
10038+#include <linux/compiler.h>
10039+#include <uapi/vserver/cvirt_cmd.h>
d337f35e 10040+
4bf69007
AM
10041+extern int vc_set_vhi_name(struct vx_info *, void __user *);
10042+extern int vc_get_vhi_name(struct vx_info *, void __user *);
d337f35e 10043+
4bf69007 10044+extern int vc_virt_stat(struct vx_info *, void __user *);
d337f35e 10045+
4bf69007 10046+#endif /* _VSERVER_CVIRT_CMD_H */
f973f73f
AM
10047diff -NurpP --minimal linux-4.1.27/include/linux/vserver/cvirt_def.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/cvirt_def.h
10048--- linux-4.1.27/include/linux/vserver/cvirt_def.h 1970-01-01 00:00:00.000000000 +0000
10049+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/cvirt_def.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
10050@@ -0,0 +1,80 @@
10051+#ifndef _VSERVER_CVIRT_DEF_H
10052+#define _VSERVER_CVIRT_DEF_H
d337f35e 10053+
d33d7b00
AM
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>
d337f35e 10059+
d337f35e 10060+
d33d7b00
AM
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+};
d337f35e 10070+
d33d7b00
AM
10071+struct _vx_syslog {
10072+ wait_queue_head_t log_wait;
10073+ spinlock_t logbuf_lock; /* lock for the log buffer */
d337f35e 10074+
d33d7b00
AM
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 */
d337f35e 10079+
d33d7b00
AM
10080+ char log_buf[1024];
10081+};
d337f35e 10082+
d337f35e 10083+
d33d7b00 10084+/* context sub struct */
d337f35e 10085+
d33d7b00
AM
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 */
d337f35e 10090+
d33d7b00
AM
10091+ atomic_t nr_onhold; /* processes on hold */
10092+ uint32_t onhold_last; /* jiffies when put on hold */
d337f35e 10093+
d33d7b00
AM
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 */
3bac966d 10098+
d33d7b00
AM
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 */
d337f35e 10103+
d33d7b00 10104+ atomic_t total_forks; /* number of forks so far */
d337f35e 10105+
d33d7b00
AM
10106+ struct _vx_syslog syslog;
10107+};
d337f35e 10108+
d33d7b00
AM
10109+struct _vx_cvirt_pc {
10110+ struct _vx_usage_stat cpustat;
10111+};
3bac966d 10112+
d337f35e 10113+
d33d7b00 10114+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 10115+
d33d7b00 10116+static inline void __dump_vx_cvirt(struct _vx_cvirt *cvirt)
3bac966d 10117+{
d33d7b00
AM
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));
3bac966d 10126+}
d337f35e 10127+
d33d7b00 10128+#endif
d337f35e 10129+
4bf69007 10130+#endif /* _VSERVER_CVIRT_DEF_H */
f973f73f
AM
10131diff -NurpP --minimal linux-4.1.27/include/linux/vserver/debug.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/debug.h
10132--- linux-4.1.27/include/linux/vserver/debug.h 1970-01-01 00:00:00.000000000 +0000
10133+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/debug.h 2016-07-05 04:41:47.000000000 +0000
a4a22af8 10134@@ -0,0 +1,146 @@
4bf69007
AM
10135+#ifndef _VSERVER_DEBUG_H
10136+#define _VSERVER_DEBUG_H
d337f35e 10137+
d337f35e 10138+
dd5f3080 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))
d337f35e 10142+
d33d7b00
AM
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]"
d337f35e 10146+
d33d7b00
AM
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
d337f35e 10157+
d33d7b00 10158+#define VS_Q(f) VS_Q_LQM f VS_Q_RQM
d337f35e
JR
10159+
10160+
d33d7b00
AM
10161+#define vxd_path(p) \
10162+ ({ static char _buffer[PATH_MAX]; \
10163+ d_path(p, _buffer, sizeof(_buffer)); })
d337f35e 10164+
d33d7b00
AM
10165+#define vxd_cond_path(n) \
10166+ ((n) ? vxd_path(&(n)->path) : "<null>" )
d337f35e 10167+
d337f35e 10168+
d33d7b00 10169+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 10170+
dd5f3080 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;
d337f35e 10184+
d337f35e 10185+
d33d7b00
AM
10186+#define VX_LOGLEVEL "vxD: "
10187+#define VX_PROC_FMT "%p: "
10188+#define VX_PROCESS current
d337f35e 10189+
d33d7b00
AM
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)
d337f35e 10196+
d33d7b00
AM
10197+#define vxlprintk(c, f, x...) \
10198+ do { \
10199+ if (c) \
10200+ printk(VX_LOGLEVEL f " @%s:%d\n", x); \
10201+ } while (0)
d337f35e 10202+
d33d7b00
AM
10203+#define vxfprintk(c, f, x...) \
10204+ do { \
10205+ if (c) \
10206+ printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \
10207+ } while (0)
d337f35e 10208+
d337f35e 10209+
d33d7b00 10210+struct vx_info;
d337f35e 10211+
d33d7b00
AM
10212+void dump_vx_info(struct vx_info *, int);
10213+void dump_vx_info_inactive(int);
d337f35e 10214+
d33d7b00 10215+#else /* CONFIG_VSERVER_DEBUG */
d337f35e 10216+
dd5f3080 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
d337f35e 10230+
d33d7b00
AM
10231+#define vxdprintk(x...) do { } while (0)
10232+#define vxlprintk(x...) do { } while (0)
10233+#define vxfprintk(x...) do { } while (0)
2380c486 10234+
d33d7b00 10235+#endif /* CONFIG_VSERVER_DEBUG */
2380c486 10236+
d337f35e 10237+
d33d7b00 10238+#ifdef CONFIG_VSERVER_WARN
d337f35e 10239+
d33d7b00
AM
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] "
d337f35e 10245+
d33d7b00
AM
10246+#define vxwprintk(c, f, x...) \
10247+ do { \
10248+ if (c) \
10249+ printk(VX_WARNLEVEL f "\n", ##x); \
10250+ } while (0)
d337f35e 10251+
d33d7b00 10252+#else /* CONFIG_VSERVER_WARN */
d337f35e 10253+
d33d7b00 10254+#define vxwprintk(x...) do { } while (0)
d337f35e 10255+
d33d7b00 10256+#endif /* CONFIG_VSERVER_WARN */
d337f35e 10257+
d33d7b00
AM
10258+#define vxwprintk_task(c, f, x...) \
10259+ vxwprintk(c, VX_WARN_TASK f, \
10260+ current->comm, current->pid, \
a4a22af8
AM
10261+ current->xid, current->nid, \
10262+ current->tag, ##x)
d33d7b00
AM
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)
d337f35e 10269+
d33d7b00
AM
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
d337f35e 10278+
d337f35e 10279+
4bf69007 10280+#endif /* _VSERVER_DEBUG_H */
f973f73f
AM
10281diff -NurpP --minimal linux-4.1.27/include/linux/vserver/debug_cmd.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/debug_cmd.h
10282--- linux-4.1.27/include/linux/vserver/debug_cmd.h 1970-01-01 00:00:00.000000000 +0000
10283+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/debug_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
10284@@ -0,0 +1,37 @@
10285+#ifndef _VSERVER_DEBUG_CMD_H
10286+#define _VSERVER_DEBUG_CMD_H
d337f35e 10287+
4bf69007 10288+#include <uapi/vserver/debug_cmd.h>
d337f35e
JR
10289+
10290+
d33d7b00 10291+#ifdef CONFIG_COMPAT
d337f35e 10292+
d33d7b00 10293+#include <asm/compat.h>
d337f35e 10294+
d33d7b00
AM
10295+struct vcmd_read_history_v0_x32 {
10296+ uint32_t index;
10297+ uint32_t count;
10298+ compat_uptr_t data_ptr;
3bac966d 10299+};
d337f35e 10300+
d33d7b00
AM
10301+struct vcmd_read_monitor_v0_x32 {
10302+ uint32_t index;
10303+ uint32_t count;
10304+ compat_uptr_t data_ptr;
3bac966d 10305+};
d337f35e 10306+
d33d7b00 10307+#endif /* CONFIG_COMPAT */
d337f35e 10308+
d33d7b00 10309+extern int vc_dump_history(uint32_t);
d337f35e 10310+
d33d7b00
AM
10311+extern int vc_read_history(uint32_t, void __user *);
10312+extern int vc_read_monitor(uint32_t, void __user *);
d337f35e 10313+
d33d7b00 10314+#ifdef CONFIG_COMPAT
d337f35e 10315+
d33d7b00
AM
10316+extern int vc_read_history_x32(uint32_t, void __user *);
10317+extern int vc_read_monitor_x32(uint32_t, void __user *);
d337f35e 10318+
d33d7b00 10319+#endif /* CONFIG_COMPAT */
d337f35e 10320+
4bf69007 10321+#endif /* _VSERVER_DEBUG_CMD_H */
f973f73f
AM
10322diff -NurpP --minimal linux-4.1.27/include/linux/vserver/device.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/device.h
10323--- linux-4.1.27/include/linux/vserver/device.h 1970-01-01 00:00:00.000000000 +0000
10324+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/device.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
10325@@ -0,0 +1,9 @@
10326+#ifndef _VSERVER_DEVICE_H
10327+#define _VSERVER_DEVICE_H
d337f35e 10328+
d337f35e 10329+
4bf69007 10330+#include <uapi/vserver/device.h>
d337f35e 10331+
4bf69007 10332+#else /* _VSERVER_DEVICE_H */
d33d7b00 10333+#warning duplicate inclusion
4bf69007 10334+#endif /* _VSERVER_DEVICE_H */
f973f73f
AM
10335diff -NurpP --minimal linux-4.1.27/include/linux/vserver/device_cmd.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/device_cmd.h
10336--- linux-4.1.27/include/linux/vserver/device_cmd.h 1970-01-01 00:00:00.000000000 +0000
10337+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/device_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
10338@@ -0,0 +1,31 @@
10339+#ifndef _VSERVER_DEVICE_CMD_H
10340+#define _VSERVER_DEVICE_CMD_H
d337f35e 10341+
4bf69007 10342+#include <uapi/vserver/device_cmd.h>
d337f35e 10343+
d337f35e 10344+
d33d7b00 10345+#ifdef CONFIG_COMPAT
d337f35e 10346+
d33d7b00 10347+#include <asm/compat.h>
3bac966d 10348+
d33d7b00
AM
10349+struct vcmd_set_mapping_v0_x32 {
10350+ compat_uptr_t device_ptr;
10351+ compat_uptr_t target_ptr;
10352+ uint32_t flags;
d337f35e
JR
10353+};
10354+
d33d7b00 10355+#endif /* CONFIG_COMPAT */
d337f35e 10356+
d33d7b00 10357+#include <linux/compiler.h>
d337f35e 10358+
d33d7b00
AM
10359+extern int vc_set_mapping(struct vx_info *, void __user *);
10360+extern int vc_unset_mapping(struct vx_info *, void __user *);
d337f35e 10361+
d33d7b00 10362+#ifdef CONFIG_COMPAT
d337f35e 10363+
d33d7b00
AM
10364+extern int vc_set_mapping_x32(struct vx_info *, void __user *);
10365+extern int vc_unset_mapping_x32(struct vx_info *, void __user *);
d337f35e 10366+
d33d7b00 10367+#endif /* CONFIG_COMPAT */
d337f35e 10368+
4bf69007 10369+#endif /* _VSERVER_DEVICE_CMD_H */
f973f73f
AM
10370diff -NurpP --minimal linux-4.1.27/include/linux/vserver/device_def.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/device_def.h
10371--- linux-4.1.27/include/linux/vserver/device_def.h 1970-01-01 00:00:00.000000000 +0000
10372+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/device_def.h 2016-07-05 04:41:47.000000000 +0000
d33d7b00 10373@@ -0,0 +1,17 @@
4bf69007
AM
10374+#ifndef _VSERVER_DEVICE_DEF_H
10375+#define _VSERVER_DEVICE_DEF_H
d337f35e 10376+
d33d7b00 10377+#include <linux/types.h>
d337f35e 10378+
d33d7b00
AM
10379+struct vx_dmap_target {
10380+ dev_t target;
10381+ uint32_t flags;
10382+};
d337f35e 10383+
d33d7b00
AM
10384+struct _vx_device {
10385+#ifdef CONFIG_VSERVER_DEVICE
10386+ struct vx_dmap_target targets[2];
10387+#endif
10388+};
d337f35e 10389+
4bf69007 10390+#endif /* _VSERVER_DEVICE_DEF_H */
f973f73f
AM
10391diff -NurpP --minimal linux-4.1.27/include/linux/vserver/dlimit.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/dlimit.h
10392--- linux-4.1.27/include/linux/vserver/dlimit.h 1970-01-01 00:00:00.000000000 +0000
10393+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/dlimit.h 2016-07-05 04:41:47.000000000 +0000
d33d7b00 10394@@ -0,0 +1,54 @@
4bf69007
AM
10395+#ifndef _VSERVER_DLIMIT_H
10396+#define _VSERVER_DLIMIT_H
d337f35e 10397+
d33d7b00 10398+#include "switch.h"
3bac966d 10399+
d337f35e 10400+
3bac966d 10401+#ifdef __KERNEL__
d337f35e 10402+
d33d7b00 10403+/* keep in sync with CDLIM_INFINITY */
d337f35e 10404+
d33d7b00 10405+#define DLIM_INFINITY (~0ULL)
d337f35e 10406+
d33d7b00
AM
10407+#include <linux/spinlock.h>
10408+#include <linux/rcupdate.h>
d337f35e 10409+
d33d7b00 10410+struct super_block;
d337f35e 10411+
d33d7b00
AM
10412+struct dl_info {
10413+ struct hlist_node dl_hlist; /* linked list of contexts */
10414+ struct rcu_head dl_rcu; /* the rcu head */
61333608 10415+ vtag_t dl_tag; /* context tag */
d33d7b00
AM
10416+ atomic_t dl_usecnt; /* usage count */
10417+ atomic_t dl_refcnt; /* reference count */
d337f35e 10418+
d33d7b00 10419+ struct super_block *dl_sb; /* associated superblock */
d337f35e 10420+
d33d7b00 10421+ spinlock_t dl_lock; /* protect the values */
d337f35e 10422+
d33d7b00
AM
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 */
d337f35e 10427+
d33d7b00
AM
10428+ unsigned int dl_nrlmult; /* non root limit mult */
10429+};
d337f35e 10430+
d33d7b00 10431+struct rcu_head;
d337f35e 10432+
d33d7b00
AM
10433+extern void rcu_free_dl_info(struct rcu_head *);
10434+extern void unhash_dl_info(struct dl_info *);
d337f35e 10435+
61333608 10436+extern struct dl_info *locate_dl_info(struct super_block *, vtag_t);
d337f35e 10437+
d337f35e 10438+
d33d7b00 10439+struct kstatfs;
d337f35e 10440+
d33d7b00 10441+extern void vx_vsi_statfs(struct super_block *, struct kstatfs *);
d337f35e 10442+
d33d7b00 10443+typedef uint64_t dlsize_t;
d337f35e 10444+
d33d7b00 10445+#endif /* __KERNEL__ */
4bf69007 10446+#else /* _VSERVER_DLIMIT_H */
d33d7b00 10447+#warning duplicate inclusion
4bf69007 10448+#endif /* _VSERVER_DLIMIT_H */
f973f73f
AM
10449diff -NurpP --minimal linux-4.1.27/include/linux/vserver/dlimit_cmd.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/dlimit_cmd.h
10450--- linux-4.1.27/include/linux/vserver/dlimit_cmd.h 1970-01-01 00:00:00.000000000 +0000
10451+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/dlimit_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
10452@@ -0,0 +1,46 @@
10453+#ifndef _VSERVER_DLIMIT_CMD_H
10454+#define _VSERVER_DLIMIT_CMD_H
d337f35e 10455+
4bf69007 10456+#include <uapi/vserver/dlimit_cmd.h>
d337f35e 10457+
d337f35e 10458+
4bf69007 10459+#ifdef CONFIG_COMPAT
d337f35e 10460+
4bf69007 10461+#include <asm/compat.h>
2380c486 10462+
4bf69007
AM
10463+struct vcmd_ctx_dlimit_base_v0_x32 {
10464+ compat_uptr_t name_ptr;
d33d7b00
AM
10465+ uint32_t flags;
10466+};
adc1caaa 10467+
4bf69007
AM
10468+struct vcmd_ctx_dlimit_v0_x32 {
10469+ compat_uptr_t name_ptr;
d33d7b00
AM
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+};
d337f35e 10477+
4bf69007 10478+#endif /* CONFIG_COMPAT */
d337f35e 10479+
4bf69007 10480+#include <linux/compiler.h>
d337f35e 10481+
4bf69007
AM
10482+extern int vc_add_dlimit(uint32_t, void __user *);
10483+extern int vc_rem_dlimit(uint32_t, void __user *);
d337f35e 10484+
4bf69007
AM
10485+extern int vc_set_dlimit(uint32_t, void __user *);
10486+extern int vc_get_dlimit(uint32_t, void __user *);
d337f35e 10487+
4bf69007 10488+#ifdef CONFIG_COMPAT
d337f35e 10489+
4bf69007
AM
10490+extern int vc_add_dlimit_x32(uint32_t, void __user *);
10491+extern int vc_rem_dlimit_x32(uint32_t, void __user *);
2380c486 10492+
d33d7b00
AM
10493+extern int vc_set_dlimit_x32(uint32_t, void __user *);
10494+extern int vc_get_dlimit_x32(uint32_t, void __user *);
d337f35e 10495+
d33d7b00 10496+#endif /* CONFIG_COMPAT */
d337f35e 10497+
4bf69007 10498+#endif /* _VSERVER_DLIMIT_CMD_H */
f973f73f
AM
10499diff -NurpP --minimal linux-4.1.27/include/linux/vserver/global.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/global.h
10500--- linux-4.1.27/include/linux/vserver/global.h 1970-01-01 00:00:00.000000000 +0000
10501+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/global.h 2016-07-05 04:41:47.000000000 +0000
d33d7b00 10502@@ -0,0 +1,19 @@
4bf69007
AM
10503+#ifndef _VSERVER_GLOBAL_H
10504+#define _VSERVER_GLOBAL_H
d337f35e 10505+
d337f35e 10506+
d33d7b00
AM
10507+extern atomic_t vx_global_ctotal;
10508+extern atomic_t vx_global_cactive;
d337f35e 10509+
d33d7b00
AM
10510+extern atomic_t nx_global_ctotal;
10511+extern atomic_t nx_global_cactive;
d337f35e 10512+
d33d7b00
AM
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;
d337f35e
JR
10519+
10520+
4bf69007 10521+#endif /* _VSERVER_GLOBAL_H */
f973f73f
AM
10522diff -NurpP --minimal linux-4.1.27/include/linux/vserver/history.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/history.h
10523--- linux-4.1.27/include/linux/vserver/history.h 1970-01-01 00:00:00.000000000 +0000
10524+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/history.h 2016-07-05 04:41:47.000000000 +0000
d33d7b00 10525@@ -0,0 +1,197 @@
4bf69007
AM
10526+#ifndef _VSERVER_HISTORY_H
10527+#define _VSERVER_HISTORY_H
d337f35e 10528+
d337f35e 10529+
d33d7b00
AM
10530+enum {
10531+ VXH_UNUSED = 0,
10532+ VXH_THROW_OOPS = 1,
d337f35e 10533+
d33d7b00
AM
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+};
d337f35e 10549+
d33d7b00
AM
10550+struct _vxhe_vxi {
10551+ struct vx_info *ptr;
10552+ unsigned xid;
10553+ unsigned usecnt;
10554+ unsigned tasks;
10555+};
d337f35e 10556+
d33d7b00
AM
10557+struct _vxhe_set_clr {
10558+ void *data;
10559+};
d337f35e 10560+
d33d7b00
AM
10561+struct _vxhe_loc_lookup {
10562+ unsigned arg;
10563+};
d337f35e 10564+
d33d7b00
AM
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+ };
3bac966d 10574+};
d337f35e 10575+
d33d7b00 10576+#ifdef CONFIG_VSERVER_HISTORY
d337f35e 10577+
d33d7b00 10578+extern unsigned volatile int vxh_active;
d337f35e 10579+
d33d7b00 10580+struct _vx_hist_entry *vxh_advance(void *loc);
d337f35e 10581+
d337f35e 10582+
d33d7b00
AM
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+}
d337f35e 10593+
d337f35e 10594+
d33d7b00 10595+#define __HERE__ current_text_addr()
d337f35e 10596+
d33d7b00
AM
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();
d337f35e 10605+
d337f35e 10606+
d33d7b00 10607+ /* pass vxi only */
d337f35e 10608+
d33d7b00
AM
10609+#define __VXH_SMPL \
10610+ __vxh_copy_vxi(entry, vxi)
d337f35e 10611+
d33d7b00
AM
10612+static inline
10613+void __vxh_smpl(struct vx_info *vxi, int __type, void *__here)
10614+{
10615+ __VXH_BODY(__type, __VXH_SMPL, __here)
10616+}
d337f35e 10617+
d33d7b00 10618+ /* pass vxi and data (void *) */
d337f35e 10619+
d33d7b00
AM
10620+#define __VXH_DATA \
10621+ __vxh_copy_vxi(entry, vxi); \
10622+ entry->sc.data = data
d337f35e 10623+
d33d7b00
AM
10624+static inline
10625+void __vxh_data(struct vx_info *vxi, void *data,
10626+ int __type, void *__here)
3bac966d 10627+{
d33d7b00 10628+ __VXH_BODY(__type, __VXH_DATA, __here)
3bac966d 10629+}
d337f35e 10630+
d33d7b00 10631+ /* pass vxi and arg (long) */
d337f35e 10632+
d33d7b00
AM
10633+#define __VXH_LONG \
10634+ __vxh_copy_vxi(entry, vxi); \
10635+ entry->ll.arg = arg
d337f35e 10636+
d33d7b00
AM
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+}
d337f35e 10643+
d337f35e 10644+
d33d7b00
AM
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+}
d337f35e 10652+
d337f35e 10653+
d33d7b00 10654+#define vxh_throw_oops() __vxh_throw_oops(__HERE__);
d337f35e 10655+
d33d7b00
AM
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);
d337f35e 10658+
d33d7b00
AM
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);
d337f35e 10665+
d33d7b00
AM
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);
d337f35e 10670+
d33d7b00
AM
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__);
d337f35e 10675+
d33d7b00
AM
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__);
d337f35e 10680+
d33d7b00
AM
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__);
d337f35e 10687+
d33d7b00 10688+extern void vxh_dump_history(void);
d337f35e 10689+
d337f35e 10690+
d33d7b00 10691+#else /* CONFIG_VSERVER_HISTORY */
2380c486 10692+
d33d7b00 10693+#define __HERE__ 0
d337f35e 10694+
d33d7b00 10695+#define vxh_throw_oops() do { } while (0)
d337f35e 10696+
d33d7b00
AM
10697+#define __vxh_get_vx_info(v, h) do { } while (0)
10698+#define __vxh_put_vx_info(v, h) do { } while (0)
d337f35e 10699+
d33d7b00
AM
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)
d337f35e 10703+
d33d7b00
AM
10704+#define __vxh_claim_vx_info(v, d, h) do { } while (0)
10705+#define __vxh_release_vx_info(v, d, h) do { } while (0)
3bac966d 10706+
d33d7b00
AM
10707+#define vxh_alloc_vx_info(v) do { } while (0)
10708+#define vxh_dealloc_vx_info(v) do { } while (0)
d337f35e 10709+
d33d7b00
AM
10710+#define vxh_hash_vx_info(v) do { } while (0)
10711+#define vxh_unhash_vx_info(v) do { } while (0)
d337f35e 10712+
d33d7b00
AM
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)
d337f35e 10716+
d33d7b00 10717+#define vxh_dump_history() do { } while (0)
d337f35e 10718+
d337f35e 10719+
d33d7b00 10720+#endif /* CONFIG_VSERVER_HISTORY */
d337f35e 10721+
4bf69007 10722+#endif /* _VSERVER_HISTORY_H */
f973f73f
AM
10723diff -NurpP --minimal linux-4.1.27/include/linux/vserver/inode.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/inode.h
10724--- linux-4.1.27/include/linux/vserver/inode.h 1970-01-01 00:00:00.000000000 +0000
10725+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/inode.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
10726@@ -0,0 +1,19 @@
10727+#ifndef _VSERVER_INODE_H
10728+#define _VSERVER_INODE_H
d337f35e 10729+
4bf69007 10730+#include <uapi/vserver/inode.h>
d337f35e 10731+
d337f35e 10732+
d33d7b00
AM
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
d337f35e 10740+
d33d7b00 10741+#define vx_hide_check(c, m) (((m) & IATTR_HIDE) ? vx_check(c, m) : 1)
d337f35e 10742+
4bf69007 10743+#else /* _VSERVER_INODE_H */
3bac966d 10744+#warning duplicate inclusion
4bf69007 10745+#endif /* _VSERVER_INODE_H */
f973f73f
AM
10746diff -NurpP --minimal linux-4.1.27/include/linux/vserver/inode_cmd.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/inode_cmd.h
10747--- linux-4.1.27/include/linux/vserver/inode_cmd.h 1970-01-01 00:00:00.000000000 +0000
10748+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/inode_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
10749@@ -0,0 +1,36 @@
10750+#ifndef _VSERVER_INODE_CMD_H
10751+#define _VSERVER_INODE_CMD_H
d337f35e 10752+
4bf69007 10753+#include <uapi/vserver/inode_cmd.h>
d337f35e 10754+
d337f35e
JR
10755+
10756+
d33d7b00 10757+#ifdef CONFIG_COMPAT
d337f35e 10758+
d33d7b00 10759+#include <asm/compat.h>
d337f35e 10760+
d33d7b00
AM
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+};
d337f35e 10767+
d33d7b00 10768+#endif /* CONFIG_COMPAT */
d337f35e 10769+
d33d7b00 10770+#include <linux/compiler.h>
d337f35e 10771+
d33d7b00
AM
10772+extern int vc_get_iattr(void __user *);
10773+extern int vc_set_iattr(void __user *);
d337f35e 10774+
d33d7b00
AM
10775+extern int vc_fget_iattr(uint32_t, void __user *);
10776+extern int vc_fset_iattr(uint32_t, void __user *);
d337f35e 10777+
d33d7b00 10778+#ifdef CONFIG_COMPAT
d337f35e 10779+
d33d7b00
AM
10780+extern int vc_get_iattr_x32(void __user *);
10781+extern int vc_set_iattr_x32(void __user *);
d337f35e 10782+
d33d7b00 10783+#endif /* CONFIG_COMPAT */
d337f35e 10784+
4bf69007 10785+#endif /* _VSERVER_INODE_CMD_H */
f973f73f
AM
10786diff -NurpP --minimal linux-4.1.27/include/linux/vserver/limit.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/limit.h
10787--- linux-4.1.27/include/linux/vserver/limit.h 1970-01-01 00:00:00.000000000 +0000
10788+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/limit.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
10789@@ -0,0 +1,61 @@
10790+#ifndef _VSERVER_LIMIT_H
10791+#define _VSERVER_LIMIT_H
d337f35e 10792+
4bf69007 10793+#include <uapi/vserver/limit.h>
d337f35e 10794+
d337f35e 10795+
d33d7b00 10796+#define VLIM_NOCHECK ((1L << VLIMIT_DENTRY) | (1L << RLIMIT_RSS))
d337f35e 10797+
d33d7b00 10798+/* keep in sync with CRLIM_INFINITY */
d337f35e 10799+
d33d7b00 10800+#define VLIM_INFINITY (~0ULL)
d337f35e 10801+
d33d7b00
AM
10802+#include <asm/atomic.h>
10803+#include <asm/resource.h>
d337f35e 10804+
d33d7b00
AM
10805+#ifndef RLIM_INFINITY
10806+#warning RLIM_INFINITY is undefined
10807+#endif
d337f35e 10808+
d33d7b00 10809+#define __rlim_val(l, r, v) ((l)->res[r].v)
d337f35e 10810+
d33d7b00
AM
10811+#define __rlim_soft(l, r) __rlim_val(l, r, soft)
10812+#define __rlim_hard(l, r) __rlim_val(l, r, hard)
d337f35e 10813+
d33d7b00
AM
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)
d337f35e 10817+
d33d7b00
AM
10818+#define __rlim_lhit(l, r) __rlim_val(l, r, lhit)
10819+#define __rlim_hit(l, r) atomic_inc(&__rlim_lhit(l, r))
d337f35e 10820+
d33d7b00
AM
10821+typedef atomic_long_t rlim_atomic_t;
10822+typedef unsigned long rlim_t;
d337f35e 10823+
d33d7b00
AM
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))
d337f35e 10830+
d337f35e 10831+
d33d7b00
AM
10832+#if (RLIM_INFINITY == VLIM_INFINITY)
10833+#define VX_VLIM(r) ((long long)(long)(r))
10834+#define VX_RLIM(v) ((rlim_t)(v))
3bac966d 10835+#else
d33d7b00
AM
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))
3bac966d 10840+#endif
d337f35e 10841+
d33d7b00 10842+struct sysinfo;
d337f35e 10843+
d33d7b00
AM
10844+void vx_vsi_meminfo(struct sysinfo *);
10845+void vx_vsi_swapinfo(struct sysinfo *);
10846+long vx_vsi_cached(struct sysinfo *);
d337f35e 10847+
d33d7b00 10848+#define NUM_LIMITS 24
d337f35e 10849+
4bf69007 10850+#endif /* _VSERVER_LIMIT_H */
f973f73f
AM
10851diff -NurpP --minimal linux-4.1.27/include/linux/vserver/limit_cmd.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/limit_cmd.h
10852--- linux-4.1.27/include/linux/vserver/limit_cmd.h 1970-01-01 00:00:00.000000000 +0000
10853+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/limit_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
10854@@ -0,0 +1,35 @@
10855+#ifndef _VSERVER_LIMIT_CMD_H
10856+#define _VSERVER_LIMIT_CMD_H
d337f35e 10857+
4bf69007 10858+#include <uapi/vserver/limit_cmd.h>
d337f35e 10859+
d337f35e 10860+
d33d7b00 10861+#ifdef CONFIG_IA32_EMULATION
d337f35e 10862+
d33d7b00
AM
10863+struct vcmd_ctx_rlimit_v0_x32 {
10864+ uint32_t id;
10865+ uint64_t minimum;
10866+ uint64_t softlimit;
10867+ uint64_t maximum;
10868+} __attribute__ ((packed));
d337f35e 10869+
d33d7b00 10870+#endif /* CONFIG_IA32_EMULATION */
d337f35e 10871+
d33d7b00 10872+#include <linux/compiler.h>
d337f35e 10873+
d33d7b00
AM
10874+extern int vc_get_rlimit_mask(uint32_t, void __user *);
10875+extern int vc_get_rlimit(struct vx_info *, void __user *);
10876+extern int vc_set_rlimit(struct vx_info *, void __user *);
10877+extern int vc_reset_hits(struct vx_info *, void __user *);
10878+extern int vc_reset_minmax(struct vx_info *, void __user *);
d337f35e 10879+
d33d7b00 10880+extern int vc_rlimit_stat(struct vx_info *, void __user *);
d337f35e 10881+
d33d7b00 10882+#ifdef CONFIG_IA32_EMULATION
d337f35e 10883+
d33d7b00
AM
10884+extern int vc_get_rlimit_x32(struct vx_info *, void __user *);
10885+extern int vc_set_rlimit_x32(struct vx_info *, void __user *);
adc1caaa 10886+
d33d7b00 10887+#endif /* CONFIG_IA32_EMULATION */
d337f35e 10888+
4bf69007 10889+#endif /* _VSERVER_LIMIT_CMD_H */
f973f73f
AM
10890diff -NurpP --minimal linux-4.1.27/include/linux/vserver/limit_def.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/limit_def.h
10891--- linux-4.1.27/include/linux/vserver/limit_def.h 1970-01-01 00:00:00.000000000 +0000
10892+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/limit_def.h 2016-07-05 04:41:47.000000000 +0000
d33d7b00 10893@@ -0,0 +1,47 @@
4bf69007
AM
10894+#ifndef _VSERVER_LIMIT_DEF_H
10895+#define _VSERVER_LIMIT_DEF_H
d337f35e 10896+
d33d7b00
AM
10897+#include <asm/atomic.h>
10898+#include <asm/resource.h>
d337f35e 10899+
d33d7b00 10900+#include "limit.h"
d337f35e 10901+
d337f35e 10902+
d33d7b00
AM
10903+struct _vx_res_limit {
10904+ rlim_t soft; /* Context soft limit */
10905+ rlim_t hard; /* Context hard limit */
d337f35e 10906+
d33d7b00
AM
10907+ rlim_atomic_t rcur; /* Current value */
10908+ rlim_t rmin; /* Context minimum */
10909+ rlim_t rmax; /* Context maximum */
d337f35e 10910+
d33d7b00
AM
10911+ atomic_t lhit; /* Limit hits */
10912+};
d337f35e 10913+
d33d7b00 10914+/* context sub struct */
2380c486 10915+
d33d7b00
AM
10916+struct _vx_limit {
10917+ struct _vx_res_limit res[NUM_LIMITS];
10918+};
adc1caaa 10919+
d33d7b00 10920+#ifdef CONFIG_VSERVER_DEBUG
adc1caaa 10921+
d33d7b00 10922+static inline void __dump_vx_limit(struct _vx_limit *limit)
3bac966d 10923+{
d33d7b00 10924+ int i;
d337f35e 10925+
d33d7b00
AM
10926+ printk("\t_vx_limit:");
10927+ for (i = 0; i < NUM_LIMITS; i++) {
10928+ printk("\t [%2d] = %8lu %8lu/%8lu, %8ld/%8ld, %8d\n",
10929+ i, (unsigned long)__rlim_get(limit, i),
10930+ (unsigned long)__rlim_rmin(limit, i),
10931+ (unsigned long)__rlim_rmax(limit, i),
10932+ (long)__rlim_soft(limit, i),
10933+ (long)__rlim_hard(limit, i),
10934+ atomic_read(&__rlim_lhit(limit, i)));
10935+ }
3bac966d 10936+}
d337f35e 10937+
d33d7b00 10938+#endif
d337f35e 10939+
4bf69007 10940+#endif /* _VSERVER_LIMIT_DEF_H */
f973f73f
AM
10941diff -NurpP --minimal linux-4.1.27/include/linux/vserver/limit_int.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/limit_int.h
10942--- linux-4.1.27/include/linux/vserver/limit_int.h 1970-01-01 00:00:00.000000000 +0000
10943+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/limit_int.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
10944@@ -0,0 +1,193 @@
10945+#ifndef _VSERVER_LIMIT_INT_H
10946+#define _VSERVER_LIMIT_INT_H
d337f35e 10947+
d33d7b00
AM
10948+#define VXD_RCRES_COND(r) VXD_CBIT(cres, r)
10949+#define VXD_RLIMIT_COND(r) VXD_CBIT(limit, r)
d337f35e 10950+
d33d7b00 10951+extern const char *vlimit_name[NUM_LIMITS];
2380c486 10952+
d33d7b00
AM
10953+static inline void __vx_acc_cres(struct vx_info *vxi,
10954+ int res, int dir, void *_data, char *_file, int _line)
10955+{
10956+ if (VXD_RCRES_COND(res))
10957+ vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5ld%s (%p)",
10958+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10959+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10960+ (dir > 0) ? "++" : "--", _data, _file, _line);
10961+ if (!vxi)
10962+ return;
d337f35e 10963+
d33d7b00
AM
10964+ if (dir > 0)
10965+ __rlim_inc(&vxi->limit, res);
10966+ else
10967+ __rlim_dec(&vxi->limit, res);
10968+}
d337f35e 10969+
d33d7b00
AM
10970+static inline void __vx_add_cres(struct vx_info *vxi,
10971+ int res, int amount, void *_data, char *_file, int _line)
10972+{
10973+ if (VXD_RCRES_COND(res))
10974+ vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5ld += %5d (%p)",
10975+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10976+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10977+ amount, _data, _file, _line);
10978+ if (amount == 0)
10979+ return;
10980+ if (!vxi)
10981+ return;
10982+ __rlim_add(&vxi->limit, res, amount);
10983+}
d337f35e 10984+
3bac966d 10985+static inline
d33d7b00 10986+int __vx_cres_adjust_max(struct _vx_limit *limit, int res, rlim_t value)
3bac966d 10987+{
d33d7b00 10988+ int cond = (value > __rlim_rmax(limit, res));
d337f35e 10989+
d33d7b00
AM
10990+ if (cond)
10991+ __rlim_rmax(limit, res) = value;
10992+ return cond;
3bac966d 10993+}
d337f35e 10994+
3bac966d 10995+static inline
d33d7b00 10996+int __vx_cres_adjust_min(struct _vx_limit *limit, int res, rlim_t value)
3bac966d 10997+{
d33d7b00 10998+ int cond = (value < __rlim_rmin(limit, res));
d337f35e 10999+
d33d7b00
AM
11000+ if (cond)
11001+ __rlim_rmin(limit, res) = value;
11002+ return cond;
3bac966d 11003+}
d337f35e 11004+
3bac966d 11005+static inline
d33d7b00 11006+void __vx_cres_fixup(struct _vx_limit *limit, int res, rlim_t value)
3bac966d 11007+{
d33d7b00
AM
11008+ if (!__vx_cres_adjust_max(limit, res, value))
11009+ __vx_cres_adjust_min(limit, res, value);
3bac966d 11010+}
d337f35e 11011+
2380c486 11012+
d33d7b00
AM
11013+/* return values:
11014+ +1 ... no limit hit
11015+ -1 ... over soft limit
11016+ 0 ... over hard limit */
d337f35e 11017+
d33d7b00
AM
11018+static inline int __vx_cres_avail(struct vx_info *vxi,
11019+ int res, int num, char *_file, int _line)
3bac966d 11020+{
d33d7b00
AM
11021+ struct _vx_limit *limit;
11022+ rlim_t value;
d337f35e 11023+
d33d7b00
AM
11024+ if (VXD_RLIMIT_COND(res))
11025+ vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld/%5ld > %5ld + %5d",
11026+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
11027+ (vxi ? (long)__rlim_soft(&vxi->limit, res) : -1),
11028+ (vxi ? (long)__rlim_hard(&vxi->limit, res) : -1),
11029+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
11030+ num, _file, _line);
11031+ if (!vxi)
3bac966d 11032+ return 1;
d337f35e 11033+
d33d7b00
AM
11034+ limit = &vxi->limit;
11035+ value = __rlim_get(limit, res);
d337f35e 11036+
d33d7b00
AM
11037+ if (!__vx_cres_adjust_max(limit, res, value))
11038+ __vx_cres_adjust_min(limit, res, value);
d337f35e 11039+
d33d7b00 11040+ if (num == 0)
3bac966d 11041+ return 1;
d337f35e 11042+
d33d7b00
AM
11043+ if (__rlim_soft(limit, res) == RLIM_INFINITY)
11044+ return -1;
11045+ if (value + num <= __rlim_soft(limit, res))
11046+ return -1;
d337f35e 11047+
d33d7b00 11048+ if (__rlim_hard(limit, res) == RLIM_INFINITY)
3bac966d 11049+ return 1;
d33d7b00 11050+ if (value + num <= __rlim_hard(limit, res))
3bac966d 11051+ return 1;
d33d7b00
AM
11052+
11053+ __rlim_hit(limit, res);
3bac966d
AM
11054+ return 0;
11055+}
d337f35e 11056+
d337f35e 11057+
d33d7b00 11058+static const int VLA_RSS[] = { RLIMIT_RSS, VLIMIT_ANON, VLIMIT_MAPPED, 0 };
d337f35e 11059+
3bac966d 11060+static inline
d33d7b00 11061+rlim_t __vx_cres_array_sum(struct _vx_limit *limit, const int *array)
3bac966d 11062+{
d33d7b00
AM
11063+ rlim_t value, sum = 0;
11064+ int res;
d337f35e 11065+
d33d7b00
AM
11066+ while ((res = *array++)) {
11067+ value = __rlim_get(limit, res);
11068+ __vx_cres_fixup(limit, res, value);
11069+ sum += value;
11070+ }
11071+ return sum;
3bac966d 11072+}
d337f35e 11073+
3bac966d 11074+static inline
d33d7b00 11075+rlim_t __vx_cres_array_fixup(struct _vx_limit *limit, const int *array)
3bac966d 11076+{
d33d7b00
AM
11077+ rlim_t value = __vx_cres_array_sum(limit, array + 1);
11078+ int res = *array;
d337f35e 11079+
d33d7b00
AM
11080+ if (value == __rlim_get(limit, res))
11081+ return value;
11082+
11083+ __rlim_set(limit, res, value);
11084+ /* now adjust min/max */
11085+ if (!__vx_cres_adjust_max(limit, res, value))
11086+ __vx_cres_adjust_min(limit, res, value);
11087+
11088+ return value;
3bac966d 11089+}
d337f35e 11090+
d33d7b00
AM
11091+static inline int __vx_cres_array_avail(struct vx_info *vxi,
11092+ const int *array, int num, char *_file, int _line)
3bac966d 11093+{
d33d7b00
AM
11094+ struct _vx_limit *limit;
11095+ rlim_t value = 0;
11096+ int res;
11097+
11098+ if (num == 0)
3bac966d 11099+ return 1;
d33d7b00 11100+ if (!vxi)
3bac966d 11101+ return 1;
d337f35e 11102+
d33d7b00
AM
11103+ limit = &vxi->limit;
11104+ res = *array;
11105+ value = __vx_cres_array_sum(limit, array + 1);
d337f35e 11106+
d33d7b00
AM
11107+ __rlim_set(limit, res, value);
11108+ __vx_cres_fixup(limit, res, value);
11109+
11110+ return __vx_cres_avail(vxi, res, num, _file, _line);
3bac966d 11111+}
d337f35e 11112+
d337f35e 11113+
d33d7b00 11114+static inline void vx_limit_fixup(struct _vx_limit *limit, int id)
3bac966d 11115+{
d33d7b00
AM
11116+ rlim_t value;
11117+ int res;
d337f35e 11118+
d33d7b00
AM
11119+ /* complex resources first */
11120+ if ((id < 0) || (id == RLIMIT_RSS))
11121+ __vx_cres_array_fixup(limit, VLA_RSS);
d337f35e 11122+
d33d7b00
AM
11123+ for (res = 0; res < NUM_LIMITS; res++) {
11124+ if ((id > 0) && (res != id))
11125+ continue;
11126+
11127+ value = __rlim_get(limit, res);
11128+ __vx_cres_fixup(limit, res, value);
11129+
11130+ /* not supposed to happen, maybe warn? */
11131+ if (__rlim_rmax(limit, res) > __rlim_hard(limit, res))
11132+ __rlim_rmax(limit, res) = __rlim_hard(limit, res);
11133+ }
3bac966d 11134+}
d337f35e
JR
11135+
11136+
4bf69007 11137+#endif /* _VSERVER_LIMIT_INT_H */
f973f73f
AM
11138diff -NurpP --minimal linux-4.1.27/include/linux/vserver/monitor.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/monitor.h
11139--- linux-4.1.27/include/linux/vserver/monitor.h 1970-01-01 00:00:00.000000000 +0000
11140+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/monitor.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11141@@ -0,0 +1,6 @@
11142+#ifndef _VSERVER_MONITOR_H
11143+#define _VSERVER_MONITOR_H
d337f35e 11144+
4bf69007 11145+#include <uapi/vserver/monitor.h>
d337f35e 11146+
4bf69007 11147+#endif /* _VSERVER_MONITOR_H */
f973f73f
AM
11148diff -NurpP --minimal linux-4.1.27/include/linux/vserver/network.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/network.h
11149--- linux-4.1.27/include/linux/vserver/network.h 1970-01-01 00:00:00.000000000 +0000
11150+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/network.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11151@@ -0,0 +1,76 @@
11152+#ifndef _VSERVER_NETWORK_H
11153+#define _VSERVER_NETWORK_H
d337f35e 11154+
d337f35e 11155+
4bf69007
AM
11156+#include <linux/list.h>
11157+#include <linux/spinlock.h>
11158+#include <linux/rcupdate.h>
11159+#include <linux/in.h>
11160+#include <linux/in6.h>
11161+#include <asm/atomic.h>
11162+#include <uapi/vserver/network.h>
d337f35e 11163+
4bf69007
AM
11164+struct nx_addr_v4 {
11165+ struct nx_addr_v4 *next;
11166+ struct in_addr ip[2];
11167+ struct in_addr mask;
11168+ uint16_t type;
11169+ uint16_t flags;
11170+};
d337f35e 11171+
4bf69007
AM
11172+struct nx_addr_v6 {
11173+ struct nx_addr_v6 *next;
11174+ struct in6_addr ip;
11175+ struct in6_addr mask;
11176+ uint32_t prefix;
11177+ uint16_t type;
11178+ uint16_t flags;
11179+};
d337f35e 11180+
4bf69007
AM
11181+struct nx_info {
11182+ struct hlist_node nx_hlist; /* linked list of nxinfos */
61333608 11183+ vnid_t nx_id; /* vnet id */
4bf69007
AM
11184+ atomic_t nx_usecnt; /* usage count */
11185+ atomic_t nx_tasks; /* tasks count */
11186+ int nx_state; /* context state */
d337f35e 11187+
4bf69007
AM
11188+ uint64_t nx_flags; /* network flag word */
11189+ uint64_t nx_ncaps; /* network capabilities */
d337f35e 11190+
4bf69007
AM
11191+ spinlock_t addr_lock; /* protect address changes */
11192+ struct in_addr v4_lback; /* Loopback address */
11193+ struct in_addr v4_bcast; /* Broadcast address */
11194+ struct nx_addr_v4 v4; /* First/Single ipv4 address */
11195+#ifdef CONFIG_IPV6
11196+ struct nx_addr_v6 v6; /* First/Single ipv6 address */
11197+#endif
11198+ char nx_name[65]; /* network context name */
d33d7b00 11199+};
d337f35e 11200+
d337f35e 11201+
4bf69007 11202+/* status flags */
d337f35e 11203+
4bf69007
AM
11204+#define NXS_HASHED 0x0001
11205+#define NXS_SHUTDOWN 0x0100
11206+#define NXS_RELEASED 0x8000
d337f35e 11207+
4bf69007 11208+extern struct nx_info *lookup_nx_info(int);
d337f35e 11209+
4bf69007 11210+extern int get_nid_list(int, unsigned int *, int);
61333608 11211+extern int nid_is_hashed(vnid_t);
d337f35e 11212+
4bf69007 11213+extern int nx_migrate_task(struct task_struct *, struct nx_info *);
d337f35e 11214+
4bf69007 11215+extern long vs_net_change(struct nx_info *, unsigned int);
d337f35e 11216+
4bf69007 11217+struct sock;
d337f35e 11218+
d337f35e 11219+
4bf69007
AM
11220+#define NX_IPV4(n) ((n)->v4.type != NXA_TYPE_NONE)
11221+#ifdef CONFIG_IPV6
11222+#define NX_IPV6(n) ((n)->v6.type != NXA_TYPE_NONE)
11223+#else
11224+#define NX_IPV6(n) (0)
11225+#endif
d337f35e 11226+
4bf69007 11227+#endif /* _VSERVER_NETWORK_H */
f973f73f
AM
11228diff -NurpP --minimal linux-4.1.27/include/linux/vserver/network_cmd.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/network_cmd.h
11229--- linux-4.1.27/include/linux/vserver/network_cmd.h 1970-01-01 00:00:00.000000000 +0000
11230+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/network_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11231@@ -0,0 +1,37 @@
11232+#ifndef _VSERVER_NETWORK_CMD_H
11233+#define _VSERVER_NETWORK_CMD_H
d337f35e 11234+
4bf69007 11235+#include <uapi/vserver/network_cmd.h>
d337f35e 11236+
4bf69007 11237+extern int vc_task_nid(uint32_t);
d337f35e 11238+
4bf69007 11239+extern int vc_nx_info(struct nx_info *, void __user *);
d337f35e 11240+
4bf69007
AM
11241+extern int vc_net_create(uint32_t, void __user *);
11242+extern int vc_net_migrate(struct nx_info *, void __user *);
d337f35e 11243+
4bf69007
AM
11244+extern int vc_net_add(struct nx_info *, void __user *);
11245+extern int vc_net_remove(struct nx_info *, void __user *);
d337f35e 11246+
4bf69007
AM
11247+extern int vc_net_add_ipv4_v1(struct nx_info *, void __user *);
11248+extern int vc_net_add_ipv4(struct nx_info *, void __user *);
d337f35e 11249+
4bf69007
AM
11250+extern int vc_net_rem_ipv4_v1(struct nx_info *, void __user *);
11251+extern int vc_net_rem_ipv4(struct nx_info *, void __user *);
d337f35e 11252+
4bf69007
AM
11253+extern int vc_net_add_ipv6(struct nx_info *, void __user *);
11254+extern int vc_net_remove_ipv6(struct nx_info *, void __user *);
d337f35e 11255+
4bf69007
AM
11256+extern int vc_add_match_ipv4(struct nx_info *, void __user *);
11257+extern int vc_get_match_ipv4(struct nx_info *, void __user *);
d33d7b00 11258+
4bf69007
AM
11259+extern int vc_add_match_ipv6(struct nx_info *, void __user *);
11260+extern int vc_get_match_ipv6(struct nx_info *, void __user *);
d337f35e 11261+
4bf69007
AM
11262+extern int vc_get_nflags(struct nx_info *, void __user *);
11263+extern int vc_set_nflags(struct nx_info *, void __user *);
d337f35e 11264+
4bf69007
AM
11265+extern int vc_get_ncaps(struct nx_info *, void __user *);
11266+extern int vc_set_ncaps(struct nx_info *, void __user *);
d337f35e 11267+
4bf69007 11268+#endif /* _VSERVER_CONTEXT_CMD_H */
f973f73f
AM
11269diff -NurpP --minimal linux-4.1.27/include/linux/vserver/percpu.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/percpu.h
11270--- linux-4.1.27/include/linux/vserver/percpu.h 1970-01-01 00:00:00.000000000 +0000
11271+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/percpu.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11272@@ -0,0 +1,14 @@
11273+#ifndef _VSERVER_PERCPU_H
11274+#define _VSERVER_PERCPU_H
d337f35e 11275+
4bf69007
AM
11276+#include "cvirt_def.h"
11277+#include "sched_def.h"
d337f35e 11278+
4bf69007
AM
11279+struct _vx_percpu {
11280+ struct _vx_cvirt_pc cvirt;
11281+ struct _vx_sched_pc sched;
11282+};
9795bf04 11283+
4bf69007 11284+#define PERCPU_PERCTX (sizeof(struct _vx_percpu))
d337f35e 11285+
4bf69007 11286+#endif /* _VSERVER_PERCPU_H */
f973f73f
AM
11287diff -NurpP --minimal linux-4.1.27/include/linux/vserver/pid.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/pid.h
11288--- linux-4.1.27/include/linux/vserver/pid.h 1970-01-01 00:00:00.000000000 +0000
11289+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/pid.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11290@@ -0,0 +1,51 @@
11291+#ifndef _VSERVER_PID_H
11292+#define _VSERVER_PID_H
d337f35e 11293+
4bf69007 11294+/* pid faking stuff */
d337f35e 11295+
4bf69007
AM
11296+#define vx_info_map_pid(v, p) \
11297+ __vx_info_map_pid((v), (p), __func__, __FILE__, __LINE__)
11298+#define vx_info_map_tgid(v,p) vx_info_map_pid(v,p)
11299+#define vx_map_pid(p) vx_info_map_pid(current_vx_info(), p)
11300+#define vx_map_tgid(p) vx_map_pid(p)
d337f35e 11301+
4bf69007
AM
11302+static inline int __vx_info_map_pid(struct vx_info *vxi, int pid,
11303+ const char *func, const char *file, int line)
11304+{
11305+ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
11306+ vxfprintk(VXD_CBIT(cvirt, 2),
11307+ "vx_map_tgid: %p/%llx: %d -> %d",
11308+ vxi, (long long)vxi->vx_flags, pid,
11309+ (pid && pid == vxi->vx_initpid) ? 1 : pid,
11310+ func, file, line);
11311+ if (pid == 0)
11312+ return 0;
11313+ if (pid == vxi->vx_initpid)
11314+ return 1;
11315+ }
11316+ return pid;
11317+}
d337f35e 11318+
4bf69007
AM
11319+#define vx_info_rmap_pid(v, p) \
11320+ __vx_info_rmap_pid((v), (p), __func__, __FILE__, __LINE__)
11321+#define vx_rmap_pid(p) vx_info_rmap_pid(current_vx_info(), p)
11322+#define vx_rmap_tgid(p) vx_rmap_pid(p)
d337f35e 11323+
4bf69007
AM
11324+static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid,
11325+ const char *func, const char *file, int line)
11326+{
11327+ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
11328+ vxfprintk(VXD_CBIT(cvirt, 2),
11329+ "vx_rmap_tgid: %p/%llx: %d -> %d",
11330+ vxi, (long long)vxi->vx_flags, pid,
11331+ (pid == 1) ? vxi->vx_initpid : pid,
11332+ func, file, line);
11333+ if ((pid == 1) && vxi->vx_initpid)
11334+ return vxi->vx_initpid;
11335+ if (pid == vxi->vx_initpid)
11336+ return ~0U;
11337+ }
11338+ return pid;
11339+}
d337f35e 11340+
4bf69007 11341+#endif
f973f73f
AM
11342diff -NurpP --minimal linux-4.1.27/include/linux/vserver/sched.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/sched.h
11343--- linux-4.1.27/include/linux/vserver/sched.h 1970-01-01 00:00:00.000000000 +0000
11344+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/sched.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11345@@ -0,0 +1,23 @@
11346+#ifndef _VSERVER_SCHED_H
11347+#define _VSERVER_SCHED_H
d337f35e 11348+
d337f35e 11349+
d33d7b00 11350+#ifdef __KERNEL__
d337f35e 11351+
4bf69007 11352+struct timespec;
d337f35e 11353+
4bf69007 11354+void vx_vsi_uptime(struct timespec *, struct timespec *);
d337f35e
JR
11355+
11356+
4bf69007 11357+struct vx_info;
d337f35e 11358+
4bf69007 11359+void vx_update_load(struct vx_info *);
d337f35e 11360+
d337f35e 11361+
4bf69007
AM
11362+void vx_update_sched_param(struct _vx_sched *sched,
11363+ struct _vx_sched_pc *sched_pc);
d337f35e 11364+
4bf69007
AM
11365+#endif /* __KERNEL__ */
11366+#else /* _VSERVER_SCHED_H */
11367+#warning duplicate inclusion
11368+#endif /* _VSERVER_SCHED_H */
f973f73f
AM
11369diff -NurpP --minimal linux-4.1.27/include/linux/vserver/sched_cmd.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/sched_cmd.h
11370--- linux-4.1.27/include/linux/vserver/sched_cmd.h 1970-01-01 00:00:00.000000000 +0000
11371+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/sched_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11372@@ -0,0 +1,11 @@
11373+#ifndef _VSERVER_SCHED_CMD_H
11374+#define _VSERVER_SCHED_CMD_H
2380c486 11375+
2380c486 11376+
4bf69007
AM
11377+#include <linux/compiler.h>
11378+#include <uapi/vserver/sched_cmd.h>
d337f35e 11379+
4bf69007
AM
11380+extern int vc_set_prio_bias(struct vx_info *, void __user *);
11381+extern int vc_get_prio_bias(struct vx_info *, void __user *);
d337f35e 11382+
4bf69007 11383+#endif /* _VSERVER_SCHED_CMD_H */
f973f73f
AM
11384diff -NurpP --minimal linux-4.1.27/include/linux/vserver/sched_def.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/sched_def.h
11385--- linux-4.1.27/include/linux/vserver/sched_def.h 1970-01-01 00:00:00.000000000 +0000
11386+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/sched_def.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11387@@ -0,0 +1,38 @@
11388+#ifndef _VSERVER_SCHED_DEF_H
11389+#define _VSERVER_SCHED_DEF_H
d33d7b00 11390+
4bf69007
AM
11391+#include <linux/spinlock.h>
11392+#include <linux/jiffies.h>
11393+#include <linux/cpumask.h>
11394+#include <asm/atomic.h>
11395+#include <asm/param.h>
d33d7b00 11396+
d337f35e 11397+
4bf69007 11398+/* context sub struct */
d337f35e 11399+
4bf69007
AM
11400+struct _vx_sched {
11401+ int prio_bias; /* bias offset for priority */
d337f35e 11402+
4bf69007
AM
11403+ cpumask_t update; /* CPUs which should update */
11404+};
d337f35e 11405+
4bf69007
AM
11406+struct _vx_sched_pc {
11407+ int prio_bias; /* bias offset for priority */
d337f35e 11408+
4bf69007
AM
11409+ uint64_t user_ticks; /* token tick events */
11410+ uint64_t sys_ticks; /* token tick events */
11411+ uint64_t hold_ticks; /* token ticks paused */
11412+};
d337f35e 11413+
d337f35e 11414+
4bf69007 11415+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 11416+
4bf69007
AM
11417+static inline void __dump_vx_sched(struct _vx_sched *sched)
11418+{
11419+ printk("\t_vx_sched:\n");
11420+ printk("\t priority = %4d\n", sched->prio_bias);
11421+}
d337f35e 11422+
4bf69007
AM
11423+#endif
11424+
11425+#endif /* _VSERVER_SCHED_DEF_H */
f973f73f
AM
11426diff -NurpP --minimal linux-4.1.27/include/linux/vserver/signal.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/signal.h
11427--- linux-4.1.27/include/linux/vserver/signal.h 1970-01-01 00:00:00.000000000 +0000
11428+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/signal.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11429@@ -0,0 +1,14 @@
11430+#ifndef _VSERVER_SIGNAL_H
11431+#define _VSERVER_SIGNAL_H
d337f35e 11432+
d337f35e 11433+
d33d7b00 11434+#ifdef __KERNEL__
4bf69007
AM
11435+
11436+struct vx_info;
11437+
11438+int vx_info_kill(struct vx_info *, int, int);
d337f35e 11439+
d33d7b00 11440+#endif /* __KERNEL__ */
4bf69007
AM
11441+#else /* _VSERVER_SIGNAL_H */
11442+#warning duplicate inclusion
11443+#endif /* _VSERVER_SIGNAL_H */
f973f73f
AM
11444diff -NurpP --minimal linux-4.1.27/include/linux/vserver/signal_cmd.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/signal_cmd.h
11445--- linux-4.1.27/include/linux/vserver/signal_cmd.h 1970-01-01 00:00:00.000000000 +0000
11446+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/signal_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11447@@ -0,0 +1,14 @@
11448+#ifndef _VSERVER_SIGNAL_CMD_H
11449+#define _VSERVER_SIGNAL_CMD_H
d337f35e 11450+
4bf69007 11451+#include <uapi/vserver/signal_cmd.h>
d337f35e 11452+
d337f35e 11453+
4bf69007
AM
11454+extern int vc_ctx_kill(struct vx_info *, void __user *);
11455+extern int vc_wait_exit(struct vx_info *, void __user *);
d337f35e
JR
11456+
11457+
4bf69007
AM
11458+extern int vc_get_pflags(uint32_t pid, void __user *);
11459+extern int vc_set_pflags(uint32_t pid, void __user *);
adc1caaa 11460+
4bf69007 11461+#endif /* _VSERVER_SIGNAL_CMD_H */
f973f73f
AM
11462diff -NurpP --minimal linux-4.1.27/include/linux/vserver/space.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/space.h
11463--- linux-4.1.27/include/linux/vserver/space.h 1970-01-01 00:00:00.000000000 +0000
11464+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/space.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11465@@ -0,0 +1,12 @@
11466+#ifndef _VSERVER_SPACE_H
11467+#define _VSERVER_SPACE_H
d337f35e 11468+
4bf69007 11469+#include <linux/types.h>
d337f35e 11470+
4bf69007 11471+struct vx_info;
d337f35e 11472+
4bf69007 11473+int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index);
9f7054f1 11474+
4bf69007
AM
11475+#else /* _VSERVER_SPACE_H */
11476+#warning duplicate inclusion
11477+#endif /* _VSERVER_SPACE_H */
f973f73f
AM
11478diff -NurpP --minimal linux-4.1.27/include/linux/vserver/space_cmd.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/space_cmd.h
11479--- linux-4.1.27/include/linux/vserver/space_cmd.h 1970-01-01 00:00:00.000000000 +0000
11480+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/space_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11481@@ -0,0 +1,13 @@
11482+#ifndef _VSERVER_SPACE_CMD_H
11483+#define _VSERVER_SPACE_CMD_H
9f7054f1 11484+
4bf69007 11485+#include <uapi/vserver/space_cmd.h>
d337f35e 11486+
d337f35e 11487+
4bf69007
AM
11488+extern int vc_enter_space_v1(struct vx_info *, void __user *);
11489+extern int vc_set_space_v1(struct vx_info *, void __user *);
11490+extern int vc_enter_space(struct vx_info *, void __user *);
11491+extern int vc_set_space(struct vx_info *, void __user *);
11492+extern int vc_get_space_mask(void __user *, int);
d337f35e 11493+
4bf69007 11494+#endif /* _VSERVER_SPACE_CMD_H */
f973f73f
AM
11495diff -NurpP --minimal linux-4.1.27/include/linux/vserver/switch.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/switch.h
11496--- linux-4.1.27/include/linux/vserver/switch.h 1970-01-01 00:00:00.000000000 +0000
11497+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/switch.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11498@@ -0,0 +1,8 @@
11499+#ifndef _VSERVER_SWITCH_H
11500+#define _VSERVER_SWITCH_H
d337f35e 11501+
d337f35e 11502+
4bf69007
AM
11503+#include <linux/errno.h>
11504+#include <uapi/vserver/switch.h>
2380c486 11505+
4bf69007 11506+#endif /* _VSERVER_SWITCH_H */
f973f73f
AM
11507diff -NurpP --minimal linux-4.1.27/include/linux/vserver/tag.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/tag.h
11508--- linux-4.1.27/include/linux/vserver/tag.h 1970-01-01 00:00:00.000000000 +0000
11509+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/tag.h 2016-07-05 04:41:47.000000000 +0000
a4a22af8 11510@@ -0,0 +1,160 @@
4bf69007
AM
11511+#ifndef _DX_TAG_H
11512+#define _DX_TAG_H
d337f35e 11513+
4bf69007 11514+#include <linux/types.h>
a4a22af8 11515+#include <linux/uidgid.h>
d337f35e 11516+
d337f35e 11517+
4bf69007 11518+#define DX_TAG(in) (IS_TAGGED(in))
9f7054f1 11519+
d337f35e 11520+
4bf69007
AM
11521+#ifdef CONFIG_TAG_NFSD
11522+#define DX_TAG_NFSD 1
11523+#else
11524+#define DX_TAG_NFSD 0
11525+#endif
2380c486 11526+
2380c486 11527+
4bf69007 11528+#ifdef CONFIG_TAGGING_NONE
d337f35e 11529+
4bf69007
AM
11530+#define MAX_UID 0xFFFFFFFF
11531+#define MAX_GID 0xFFFFFFFF
d337f35e 11532+
4bf69007 11533+#define INOTAG_TAG(cond, uid, gid, tag) (0)
d337f35e 11534+
4bf69007
AM
11535+#define TAGINO_UID(cond, uid, tag) (uid)
11536+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 11537+
4bf69007 11538+#endif
d337f35e 11539+
d337f35e 11540+
4bf69007 11541+#ifdef CONFIG_TAGGING_GID16
d337f35e 11542+
4bf69007
AM
11543+#define MAX_UID 0xFFFFFFFF
11544+#define MAX_GID 0x0000FFFF
d337f35e 11545+
4bf69007
AM
11546+#define INOTAG_TAG(cond, uid, gid, tag) \
11547+ ((cond) ? (((gid) >> 16) & 0xFFFF) : 0)
d337f35e 11548+
4bf69007
AM
11549+#define TAGINO_UID(cond, uid, tag) (uid)
11550+#define TAGINO_GID(cond, gid, tag) \
11551+ ((cond) ? (((gid) & 0xFFFF) | ((tag) << 16)) : (gid))
d337f35e 11552+
4bf69007 11553+#endif
d337f35e 11554+
d337f35e 11555+
4bf69007 11556+#ifdef CONFIG_TAGGING_ID24
d337f35e 11557+
4bf69007
AM
11558+#define MAX_UID 0x00FFFFFF
11559+#define MAX_GID 0x00FFFFFF
d337f35e 11560+
4bf69007
AM
11561+#define INOTAG_TAG(cond, uid, gid, tag) \
11562+ ((cond) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0)
d337f35e 11563+
4bf69007
AM
11564+#define TAGINO_UID(cond, uid, tag) \
11565+ ((cond) ? (((uid) & 0xFFFFFF) | (((tag) & 0xFF00) << 16)) : (uid))
11566+#define TAGINO_GID(cond, gid, tag) \
11567+ ((cond) ? (((gid) & 0xFFFFFF) | (((tag) & 0x00FF) << 24)) : (gid))
d337f35e 11568+
4bf69007 11569+#endif
d337f35e 11570+
d337f35e 11571+
4bf69007 11572+#ifdef CONFIG_TAGGING_UID16
d337f35e 11573+
4bf69007
AM
11574+#define MAX_UID 0x0000FFFF
11575+#define MAX_GID 0xFFFFFFFF
3bac966d 11576+
4bf69007
AM
11577+#define INOTAG_TAG(cond, uid, gid, tag) \
11578+ ((cond) ? (((uid) >> 16) & 0xFFFF) : 0)
d337f35e 11579+
4bf69007
AM
11580+#define TAGINO_UID(cond, uid, tag) \
11581+ ((cond) ? (((uid) & 0xFFFF) | ((tag) << 16)) : (uid))
11582+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 11583+
d33d7b00 11584+#endif
d337f35e
JR
11585+
11586+
4bf69007 11587+#ifdef CONFIG_TAGGING_INTERN
d337f35e 11588+
4bf69007
AM
11589+#define MAX_UID 0xFFFFFFFF
11590+#define MAX_GID 0xFFFFFFFF
d337f35e 11591+
4bf69007
AM
11592+#define INOTAG_TAG(cond, uid, gid, tag) \
11593+ ((cond) ? (tag) : 0)
d337f35e 11594+
4bf69007
AM
11595+#define TAGINO_UID(cond, uid, tag) (uid)
11596+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 11597+
4bf69007 11598+#endif
d337f35e 11599+
d337f35e 11600+
4bf69007
AM
11601+#ifndef CONFIG_TAGGING_NONE
11602+#define dx_current_fstag(sb) \
11603+ ((sb)->s_flags & MS_TAGGED ? dx_current_tag() : 0)
11604+#else
11605+#define dx_current_fstag(sb) (0)
11606+#endif
d337f35e 11607+
4bf69007
AM
11608+#ifndef CONFIG_TAGGING_INTERN
11609+#define TAGINO_TAG(cond, tag) (0)
11610+#else
11611+#define TAGINO_TAG(cond, tag) ((cond) ? (tag) : 0)
11612+#endif
d337f35e 11613+
a4a22af8
AM
11614+#define TAGINO_KUID(cond, kuid, ktag) \
11615+ KUIDT_INIT(TAGINO_UID(cond, __kuid_val(kuid), __ktag_val(ktag)))
11616+#define TAGINO_KGID(cond, kgid, ktag) \
11617+ KGIDT_INIT(TAGINO_GID(cond, __kgid_val(kgid), __ktag_val(ktag)))
11618+#define TAGINO_KTAG(cond, ktag) \
11619+ KTAGT_INIT(TAGINO_TAG(cond, __ktag_val(ktag)))
11620+
11621+
4bf69007
AM
11622+#define INOTAG_UID(cond, uid, gid) \
11623+ ((cond) ? ((uid) & MAX_UID) : (uid))
11624+#define INOTAG_GID(cond, uid, gid) \
11625+ ((cond) ? ((gid) & MAX_GID) : (gid))
d337f35e 11626+
a4a22af8
AM
11627+#define INOTAG_KUID(cond, kuid, kgid) \
11628+ KUIDT_INIT(INOTAG_UID(cond, __kuid_val(kuid), __kgid_val(kgid)))
11629+#define INOTAG_KGID(cond, kuid, kgid) \
11630+ KGIDT_INIT(INOTAG_GID(cond, __kuid_val(kuid), __kgid_val(kgid)))
11631+#define INOTAG_KTAG(cond, kuid, kgid, ktag) \
11632+ KTAGT_INIT(INOTAG_TAG(cond, \
11633+ __kuid_val(kuid), __kgid_val(kgid), __ktag_val(ktag)))
11634+
d337f35e 11635+
4bf69007 11636+static inline uid_t dx_map_uid(uid_t uid)
3bac966d 11637+{
4bf69007
AM
11638+ if ((uid > MAX_UID) && (uid != -1))
11639+ uid = -2;
11640+ return (uid & MAX_UID);
d33d7b00 11641+}
d337f35e 11642+
4bf69007
AM
11643+static inline gid_t dx_map_gid(gid_t gid)
11644+{
11645+ if ((gid > MAX_GID) && (gid != -1))
11646+ gid = -2;
11647+ return (gid & MAX_GID);
11648+}
d337f35e 11649+
4bf69007
AM
11650+struct peer_tag {
11651+ int32_t xid;
11652+ int32_t nid;
d33d7b00 11653+};
d337f35e 11654+
4bf69007 11655+#define dx_notagcheck(sb) ((sb) && ((sb)->s_flags & MS_NOTAGCHECK))
2380c486 11656+
61333608 11657+int dx_parse_tag(char *string, vtag_t *tag, int remove, int *mnt_flags,
4bf69007 11658+ unsigned long *flags);
d337f35e 11659+
4bf69007 11660+#ifdef CONFIG_PROPAGATE
d337f35e 11661+
4bf69007 11662+void __dx_propagate_tag(struct nameidata *nd, struct inode *inode);
d337f35e 11663+
4bf69007 11664+#define dx_propagate_tag(n, i) __dx_propagate_tag(n, i)
d337f35e 11665+
4bf69007
AM
11666+#else
11667+#define dx_propagate_tag(n, i) do { } while (0)
11668+#endif
d337f35e 11669+
4bf69007 11670+#endif /* _DX_TAG_H */
f973f73f
AM
11671diff -NurpP --minimal linux-4.1.27/include/linux/vserver/tag_cmd.h linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/tag_cmd.h
11672--- linux-4.1.27/include/linux/vserver/tag_cmd.h 1970-01-01 00:00:00.000000000 +0000
11673+++ linux-4.1.27-vs2.3.8.5.2/include/linux/vserver/tag_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11674@@ -0,0 +1,10 @@
11675+#ifndef _VSERVER_TAG_CMD_H
11676+#define _VSERVER_TAG_CMD_H
d337f35e 11677+
4bf69007 11678+#include <uapi/vserver/tag_cmd.h>
d337f35e 11679+
4bf69007 11680+extern int vc_task_tag(uint32_t);
3bac966d 11681+
4bf69007 11682+extern int vc_tag_migrate(uint32_t);
3bac966d 11683+
4bf69007 11684+#endif /* _VSERVER_TAG_CMD_H */
f973f73f
AM
11685diff -NurpP --minimal linux-4.1.27/include/net/addrconf.h linux-4.1.27-vs2.3.8.5.2/include/net/addrconf.h
11686--- linux-4.1.27/include/net/addrconf.h 2015-04-12 22:12:50.000000000 +0000
11687+++ linux-4.1.27-vs2.3.8.5.2/include/net/addrconf.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 11688@@ -82,7 +82,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str
c2e5f7c8
JR
11689
11690 int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
11691 const struct in6_addr *daddr, unsigned int srcprefs,
11692- struct in6_addr *saddr);
11693+ struct in6_addr *saddr, struct nx_info *nxi);
11694 int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
bb20add7 11695 u32 banned_flags);
c2e5f7c8 11696 int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
f973f73f
AM
11697diff -NurpP --minimal linux-4.1.27/include/net/af_unix.h linux-4.1.27-vs2.3.8.5.2/include/net/af_unix.h
11698--- linux-4.1.27/include/net/af_unix.h 2016-07-05 04:28:31.000000000 +0000
11699+++ linux-4.1.27-vs2.3.8.5.2/include/net/af_unix.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11700@@ -4,6 +4,7 @@
11701 #include <linux/socket.h>
11702 #include <linux/un.h>
11703 #include <linux/mutex.h>
5eef5607 11704+// #include <linux/vs_base.h>
4bf69007
AM
11705 #include <net/sock.h>
11706
f973f73f
AM
11707 void unix_inflight(struct user_struct *user, struct file *fp);
11708diff -NurpP --minimal linux-4.1.27/include/net/inet_timewait_sock.h linux-4.1.27-vs2.3.8.5.2/include/net/inet_timewait_sock.h
11709--- linux-4.1.27/include/net/inet_timewait_sock.h 2016-07-05 04:28:31.000000000 +0000
11710+++ linux-4.1.27-vs2.3.8.5.2/include/net/inet_timewait_sock.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 11711@@ -70,6 +70,10 @@ struct inet_timewait_sock {
b00e13aa
AM
11712 #define tw_dport __tw_common.skc_dport
11713 #define tw_num __tw_common.skc_num
5eef5607 11714 #define tw_cookie __tw_common.skc_cookie
4bf69007
AM
11715+#define tw_xid __tw_common.skc_xid
11716+#define tw_vx_info __tw_common.skc_vx_info
11717+#define tw_nid __tw_common.skc_nid
11718+#define tw_nx_info __tw_common.skc_nx_info
b00e13aa 11719
4bf69007
AM
11720 int tw_timeout;
11721 volatile unsigned char tw_substate;
f973f73f
AM
11722diff -NurpP --minimal linux-4.1.27/include/net/ip6_route.h linux-4.1.27-vs2.3.8.5.2/include/net/ip6_route.h
11723--- linux-4.1.27/include/net/ip6_route.h 2016-07-05 04:28:31.000000000 +0000
11724+++ linux-4.1.27-vs2.3.8.5.2/include/net/ip6_route.h 2016-07-05 04:41:47.000000000 +0000
11725@@ -88,7 +88,7 @@ int ip6_del_rt(struct rt6_info *);
c2e5f7c8
JR
11726
11727 int ip6_route_get_saddr(struct net *net, struct rt6_info *rt,
11728 const struct in6_addr *daddr, unsigned int prefs,
11729- struct in6_addr *saddr);
11730+ struct in6_addr *saddr, struct nx_info *nxi);
11731
11732 struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
11733 const struct in6_addr *saddr, int oif, int flags);
f973f73f
AM
11734diff -NurpP --minimal linux-4.1.27/include/net/route.h linux-4.1.27-vs2.3.8.5.2/include/net/route.h
11735--- linux-4.1.27/include/net/route.h 2015-04-12 22:12:50.000000000 +0000
11736+++ linux-4.1.27-vs2.3.8.5.2/include/net/route.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 11737@@ -207,6 +207,9 @@ static inline void ip_rt_put(struct rtab
b00e13aa 11738 dst_release(&rt->dst);
4bf69007
AM
11739 }
11740
11741+#include <linux/vs_base.h>
11742+#include <linux/vs_inet.h>
d337f35e 11743+
4bf69007
AM
11744 #define IPTOS_RT_MASK (IPTOS_TOS_MASK & ~3)
11745
11746 extern const __u8 ip_tos2prio[16];
5eef5607 11747@@ -254,6 +257,9 @@ static inline void ip_route_connect_init
4bf69007
AM
11748 protocol, flow_flags, dst, src, dport, sport);
11749 }
11750
11751+extern struct rtable *ip_v4_find_src(struct net *net, struct nx_info *,
11752+ struct flowi4 *);
d337f35e 11753+
4bf69007
AM
11754 static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
11755 __be32 dst, __be32 src, u32 tos,
11756 int oif, u8 protocol,
5eef5607 11757@@ -262,11 +268,25 @@ static inline struct rtable *ip_route_co
4bf69007
AM
11758 {
11759 struct net *net = sock_net(sk);
11760 struct rtable *rt;
11761+ struct nx_info *nx_info = current_nx_info();
11762
11763 ip_route_connect_init(fl4, dst, src, tos, oif, protocol,
f15949f2 11764 sport, dport, sk);
4bf69007
AM
11765
11766- if (!dst || !src) {
11767+ if (sk)
11768+ nx_info = sk->sk_nx_info;
d337f35e 11769+
4bf69007
AM
11770+ vxdprintk(VXD_CBIT(net, 4),
11771+ "ip_route_connect(%p) %p,%p;%lx",
11772+ sk, nx_info, sk->sk_socket,
11773+ (sk->sk_socket?sk->sk_socket->flags:0));
d337f35e 11774+
4bf69007
AM
11775+ rt = ip_v4_find_src(net, nx_info, fl4);
11776+ if (IS_ERR(rt))
11777+ return rt;
11778+ ip_rt_put(rt);
d337f35e 11779+
4bf69007
AM
11780+ if (!fl4->daddr || !fl4->saddr) {
11781 rt = __ip_route_output_key(net, fl4);
11782 if (IS_ERR(rt))
11783 return rt;
f973f73f
AM
11784diff -NurpP --minimal linux-4.1.27/include/net/sock.h linux-4.1.27-vs2.3.8.5.2/include/net/sock.h
11785--- linux-4.1.27/include/net/sock.h 2016-07-05 04:28:32.000000000 +0000
11786+++ linux-4.1.27-vs2.3.8.5.2/include/net/sock.h 2016-07-05 04:41:47.000000000 +0000
5eef5607
AM
11787@@ -196,6 +196,10 @@ struct sock_common {
11788 struct in6_addr skc_v6_daddr;
11789 struct in6_addr skc_v6_rcv_saddr;
4bf69007 11790 #endif
61333608 11791+ vxid_t skc_xid;
4bf69007 11792+ struct vx_info *skc_vx_info;
61333608 11793+ vnid_t skc_nid;
4bf69007 11794+ struct nx_info *skc_nx_info;
c2e5f7c8 11795
5eef5607
AM
11796 atomic64_t skc_cookie;
11797
11798@@ -328,8 +332,12 @@ struct sock {
4bf69007
AM
11799 #define sk_prot __sk_common.skc_prot
11800 #define sk_net __sk_common.skc_net
c2e5f7c8
JR
11801 #define sk_v6_daddr __sk_common.skc_v6_daddr
11802-#define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr
11803+#define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr
5eef5607 11804 #define sk_cookie __sk_common.skc_cookie
4bf69007
AM
11805+#define sk_xid __sk_common.skc_xid
11806+#define sk_vx_info __sk_common.skc_vx_info
11807+#define sk_nid __sk_common.skc_nid
11808+#define sk_nx_info __sk_common.skc_nx_info
c2e5f7c8 11809
4bf69007
AM
11810 socket_lock_t sk_lock;
11811 struct sk_buff_head sk_receive_queue;
f973f73f
AM
11812diff -NurpP --minimal linux-4.1.27/include/uapi/Kbuild linux-4.1.27-vs2.3.8.5.2/include/uapi/Kbuild
11813--- linux-4.1.27/include/uapi/Kbuild 2015-04-12 22:12:50.000000000 +0000
11814+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/Kbuild 2016-07-05 04:41:47.000000000 +0000
bb20add7 11815@@ -13,3 +13,4 @@ header-y += drm/
4bf69007
AM
11816 header-y += xen/
11817 header-y += scsi/
bb20add7 11818 header-y += misc/
4bf69007 11819+header-y += vserver/
f973f73f
AM
11820diff -NurpP --minimal linux-4.1.27/include/uapi/linux/capability.h linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/capability.h
11821--- linux-4.1.27/include/uapi/linux/capability.h 2015-04-12 22:12:50.000000000 +0000
11822+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/capability.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11823@@ -259,6 +259,7 @@ struct vfs_cap_data {
11824 arbitrary SCSI commands */
11825 /* Allow setting encryption key on loopback filesystem */
11826 /* Allow setting zone reclaim policy */
11827+/* Allow the selection of a security context */
11828
11829 #define CAP_SYS_ADMIN 21
11830
bb20add7 11831@@ -354,7 +355,12 @@ struct vfs_cap_data {
4bf69007 11832
bb20add7 11833 #define CAP_LAST_CAP CAP_AUDIT_READ
4bf69007
AM
11834
11835-#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
11836+/* Allow context manipulations */
11837+/* Allow changing context info on files */
d337f35e 11838+
4bf69007 11839+#define CAP_CONTEXT 63
d337f35e 11840+
4bf69007
AM
11841+#define cap_valid(x) ((x) >= 0 && ((x) <= CAP_LAST_CAP || (x) == CAP_CONTEXT))
11842
11843 /*
11844 * Bit location of each capability (used by user-space library and kernel)
f973f73f
AM
11845diff -NurpP --minimal linux-4.1.27/include/uapi/linux/fs.h linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/fs.h
11846--- linux-4.1.27/include/uapi/linux/fs.h 2015-04-12 22:12:50.000000000 +0000
11847+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/fs.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 11848@@ -91,6 +91,9 @@ struct inodes_stat_t {
4bf69007
AM
11849 #define MS_I_VERSION (1<<23) /* Update inode I_version field */
11850 #define MS_STRICTATIME (1<<24) /* Always perform atime updates */
5eef5607 11851 #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */
b00e13aa
AM
11852+#define MS_TAGGED (1<<8) /* use generic inode tagging */
11853+#define MS_NOTAGCHECK (1<<9) /* don't check tags */
5eef5607 11854+#define MS_TAGID (1<<26) /* use specific tag for this mount */
b00e13aa
AM
11855
11856 /* These sb flags are internal to the kernel */
09be7631 11857 #define MS_NOSEC (1<<28)
5eef5607 11858@@ -197,11 +200,14 @@ struct inodes_stat_t {
4bf69007
AM
11859 #define FS_EXTENT_FL 0x00080000 /* Extents */
11860 #define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */
11861 #define FS_NOCOW_FL 0x00800000 /* Do not cow file */
11862+#define FS_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
11863 #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
11864
11865-#define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
11866-#define FS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
11867+#define FS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
11868+#define FS_COW_FL 0x20000000 /* Copy on Write marker */
11869
11870+#define FS_FL_USER_VISIBLE 0x0103DFFF /* User visible flags */
11871+#define FS_FL_USER_MODIFIABLE 0x010380FF /* User modifiable flags */
11872
11873 #define SYNC_FILE_RANGE_WAIT_BEFORE 1
11874 #define SYNC_FILE_RANGE_WRITE 2
f973f73f
AM
11875diff -NurpP --minimal linux-4.1.27/include/uapi/linux/gfs2_ondisk.h linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/gfs2_ondisk.h
11876--- linux-4.1.27/include/uapi/linux/gfs2_ondisk.h 2015-04-12 22:12:50.000000000 +0000
11877+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/gfs2_ondisk.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11878@@ -225,6 +225,9 @@ enum {
11879 gfs2fl_Sync = 8,
11880 gfs2fl_System = 9,
11881 gfs2fl_TopLevel = 10,
11882+ gfs2fl_IXUnlink = 16,
11883+ gfs2fl_Barrier = 17,
11884+ gfs2fl_Cow = 18,
11885 gfs2fl_TruncInProg = 29,
11886 gfs2fl_InheritDirectio = 30,
11887 gfs2fl_InheritJdata = 31,
11888@@ -242,6 +245,9 @@ enum {
11889 #define GFS2_DIF_SYNC 0x00000100
11890 #define GFS2_DIF_SYSTEM 0x00000200 /* New in gfs2 */
11891 #define GFS2_DIF_TOPDIR 0x00000400 /* New in gfs2 */
11892+#define GFS2_DIF_IXUNLINK 0x00010000
11893+#define GFS2_DIF_BARRIER 0x00020000
11894+#define GFS2_DIF_COW 0x00040000
11895 #define GFS2_DIF_TRUNC_IN_PROG 0x20000000 /* New in gfs2 */
11896 #define GFS2_DIF_INHERIT_DIRECTIO 0x40000000 /* only in gfs1 */
11897 #define GFS2_DIF_INHERIT_JDATA 0x80000000
f973f73f
AM
11898diff -NurpP --minimal linux-4.1.27/include/uapi/linux/if_tun.h linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/if_tun.h
11899--- linux-4.1.27/include/uapi/linux/if_tun.h 2015-04-12 22:12:50.000000000 +0000
11900+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/if_tun.h 2016-07-05 04:41:47.000000000 +0000
5eef5607 11901@@ -50,6 +50,7 @@
c2e5f7c8 11902 #define TUNGETFILTER _IOR('T', 219, struct sock_fprog)
5eef5607
AM
11903 #define TUNSETVNETLE _IOW('T', 220, int)
11904 #define TUNGETVNETLE _IOR('T', 221, int)
11905+#define TUNSETNID _IOW('T', 222, int)
4bf69007
AM
11906
11907 /* TUNSETIFF ifr flags */
11908 #define IFF_TUN 0x0001
f973f73f
AM
11909diff -NurpP --minimal linux-4.1.27/include/uapi/linux/major.h linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/major.h
11910--- linux-4.1.27/include/uapi/linux/major.h 2015-04-12 22:12:50.000000000 +0000
11911+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/major.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11912@@ -15,6 +15,7 @@
11913 #define HD_MAJOR IDE0_MAJOR
11914 #define PTY_SLAVE_MAJOR 3
11915 #define TTY_MAJOR 4
11916+#define VROOT_MAJOR 4
11917 #define TTYAUX_MAJOR 5
11918 #define LP_MAJOR 6
11919 #define VCS_MAJOR 7
f973f73f
AM
11920diff -NurpP --minimal linux-4.1.27/include/uapi/linux/nfs_mount.h linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/nfs_mount.h
11921--- linux-4.1.27/include/uapi/linux/nfs_mount.h 2015-04-12 22:12:50.000000000 +0000
11922+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/nfs_mount.h 2016-07-05 04:41:47.000000000 +0000
4bf69007 11923@@ -63,7 +63,8 @@ struct nfs_mount_data {
c2e5f7c8 11924 #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 non-text parsed mount data only */
4bf69007
AM
11925 #define NFS_MOUNT_NORDIRPLUS 0x4000 /* 5 */
11926 #define NFS_MOUNT_UNSHARED 0x8000 /* 5 */
11927-#define NFS_MOUNT_FLAGMASK 0xFFFF
11928+#define NFS_MOUNT_TAGGED 0x10000 /* context tagging */
11929+#define NFS_MOUNT_FLAGMASK 0x1FFFF
11930
11931 /* The following are for internal use only */
11932 #define NFS_MOUNT_LOOKUP_CACHE_NONEG 0x10000
f973f73f
AM
11933diff -NurpP --minimal linux-4.1.27/include/uapi/linux/reboot.h linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/reboot.h
11934--- linux-4.1.27/include/uapi/linux/reboot.h 2015-04-12 22:12:50.000000000 +0000
11935+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/reboot.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11936@@ -33,7 +33,7 @@
11937 #define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
11938 #define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
11939 #define LINUX_REBOOT_CMD_KEXEC 0x45584543
11940-
11941+#define LINUX_REBOOT_CMD_OOM 0xDEADBEEF
11942
11943
11944 #endif /* _UAPI_LINUX_REBOOT_H */
f973f73f
AM
11945diff -NurpP --minimal linux-4.1.27/include/uapi/linux/sysctl.h linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/sysctl.h
11946--- linux-4.1.27/include/uapi/linux/sysctl.h 2015-04-12 22:12:50.000000000 +0000
11947+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/linux/sysctl.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11948@@ -60,6 +60,7 @@ enum
11949 CTL_ABI=9, /* Binary emulation */
11950 CTL_CPU=10, /* CPU stuff (speed scaling, etc) */
11951 CTL_ARLAN=254, /* arlan wireless driver */
11952+ CTL_VSERVER=4242, /* Linux-VServer debug */
11953 CTL_S390DBF=5677, /* s390 debug */
11954 CTL_SUNRPC=7249, /* sunrpc debug */
11955 CTL_PM=9899, /* frv power management */
11956@@ -94,6 +95,7 @@ enum
11957
11958 KERN_PANIC=15, /* int: panic timeout */
11959 KERN_REALROOTDEV=16, /* real root device to mount after initrd */
11960+ KERN_VSHELPER=17, /* string: path to vshelper policy agent */
11961
11962 KERN_SPARC_REBOOT=21, /* reboot command on Sparc */
11963 KERN_CTLALTDEL=22, /* int: allow ctl-alt-del to reboot */
f973f73f
AM
11964diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/Kbuild linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/Kbuild
11965--- linux-4.1.27/include/uapi/vserver/Kbuild 1970-01-01 00:00:00.000000000 +0000
11966+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/Kbuild 2016-07-05 04:41:47.000000000 +0000
4bf69007 11967@@ -0,0 +1,9 @@
d337f35e 11968+
4bf69007
AM
11969+header-y += context_cmd.h network_cmd.h space_cmd.h \
11970+ cacct_cmd.h cvirt_cmd.h limit_cmd.h dlimit_cmd.h \
11971+ inode_cmd.h tag_cmd.h sched_cmd.h signal_cmd.h \
11972+ debug_cmd.h device_cmd.h
2380c486 11973+
4bf69007
AM
11974+header-y += switch.h context.h network.h monitor.h \
11975+ limit.h inode.h device.h
2380c486 11976+
f973f73f
AM
11977diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/cacct_cmd.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/cacct_cmd.h
11978--- linux-4.1.27/include/uapi/vserver/cacct_cmd.h 1970-01-01 00:00:00.000000000 +0000
11979+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/cacct_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
11980@@ -0,0 +1,15 @@
11981+#ifndef _UAPI_VS_CACCT_CMD_H
11982+#define _UAPI_VS_CACCT_CMD_H
d337f35e
JR
11983+
11984+
4bf69007 11985+/* virtual host info name commands */
d337f35e 11986+
4bf69007 11987+#define VCMD_sock_stat VC_CMD(VSTAT, 5, 0)
d337f35e 11988+
4bf69007
AM
11989+struct vcmd_sock_stat_v0 {
11990+ uint32_t field;
11991+ uint32_t count[3];
11992+ uint64_t total[3];
11993+};
d337f35e 11994+
4bf69007 11995+#endif /* _UAPI_VS_CACCT_CMD_H */
f973f73f
AM
11996diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/context.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/context.h
11997--- linux-4.1.27/include/uapi/vserver/context.h 1970-01-01 00:00:00.000000000 +0000
11998+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/context.h 2016-07-05 04:41:47.000000000 +0000
b00e13aa 11999@@ -0,0 +1,81 @@
4bf69007
AM
12000+#ifndef _UAPI_VS_CONTEXT_H
12001+#define _UAPI_VS_CONTEXT_H
d337f35e 12002+
4bf69007
AM
12003+#include <linux/types.h>
12004+#include <linux/capability.h>
d337f35e
JR
12005+
12006+
4bf69007 12007+/* context flags */
d337f35e 12008+
4bf69007
AM
12009+#define VXF_INFO_SCHED 0x00000002
12010+#define VXF_INFO_NPROC 0x00000004
12011+#define VXF_INFO_PRIVATE 0x00000008
d337f35e 12012+
4bf69007
AM
12013+#define VXF_INFO_INIT 0x00000010
12014+#define VXF_INFO_HIDE 0x00000020
12015+#define VXF_INFO_ULIMIT 0x00000040
12016+#define VXF_INFO_NSPACE 0x00000080
d337f35e 12017+
4bf69007
AM
12018+#define VXF_SCHED_HARD 0x00000100
12019+#define VXF_SCHED_PRIO 0x00000200
12020+#define VXF_SCHED_PAUSE 0x00000400
2380c486 12021+
4bf69007
AM
12022+#define VXF_VIRT_MEM 0x00010000
12023+#define VXF_VIRT_UPTIME 0x00020000
12024+#define VXF_VIRT_CPU 0x00040000
12025+#define VXF_VIRT_LOAD 0x00080000
12026+#define VXF_VIRT_TIME 0x00100000
d337f35e 12027+
4bf69007
AM
12028+#define VXF_HIDE_MOUNT 0x01000000
12029+/* was VXF_HIDE_NETIF 0x02000000 */
12030+#define VXF_HIDE_VINFO 0x04000000
d337f35e 12031+
4bf69007
AM
12032+#define VXF_STATE_SETUP (1ULL << 32)
12033+#define VXF_STATE_INIT (1ULL << 33)
12034+#define VXF_STATE_ADMIN (1ULL << 34)
d337f35e 12035+
4bf69007
AM
12036+#define VXF_SC_HELPER (1ULL << 36)
12037+#define VXF_REBOOT_KILL (1ULL << 37)
12038+#define VXF_PERSISTENT (1ULL << 38)
d337f35e 12039+
4bf69007
AM
12040+#define VXF_FORK_RSS (1ULL << 48)
12041+#define VXF_PROLIFIC (1ULL << 49)
d337f35e 12042+
4bf69007 12043+#define VXF_IGNEG_NICE (1ULL << 52)
d337f35e 12044+
4bf69007 12045+#define VXF_ONE_TIME (0x0007ULL << 32)
d337f35e 12046+
4bf69007 12047+#define VXF_INIT_SET (VXF_STATE_SETUP | VXF_STATE_INIT | VXF_STATE_ADMIN)
d337f35e
JR
12048+
12049+
4bf69007 12050+/* context migration */
d337f35e 12051+
4bf69007
AM
12052+#define VXM_SET_INIT 0x00000001
12053+#define VXM_SET_REAPER 0x00000002
d337f35e 12054+
4bf69007 12055+/* context caps */
d337f35e 12056+
4bf69007
AM
12057+#define VXC_SET_UTSNAME 0x00000001
12058+#define VXC_SET_RLIMIT 0x00000002
12059+#define VXC_FS_SECURITY 0x00000004
12060+#define VXC_FS_TRUSTED 0x00000008
12061+#define VXC_TIOCSTI 0x00000010
2380c486 12062+
4bf69007
AM
12063+/* was VXC_RAW_ICMP 0x00000100 */
12064+#define VXC_SYSLOG 0x00001000
12065+#define VXC_OOM_ADJUST 0x00002000
12066+#define VXC_AUDIT_CONTROL 0x00004000
d337f35e 12067+
c2e5f7c8
JR
12068+#define VXC_SECURE_MOUNT 0x00010000
12069+/* #define VXC_SECURE_REMOUNT 0x00020000 */
4bf69007 12070+#define VXC_BINARY_MOUNT 0x00040000
b00e13aa 12071+#define VXC_DEV_MOUNT 0x00080000
d337f35e 12072+
4bf69007
AM
12073+#define VXC_QUOTA_CTL 0x00100000
12074+#define VXC_ADMIN_MAPPER 0x00200000
12075+#define VXC_ADMIN_CLOOP 0x00400000
d337f35e 12076+
4bf69007
AM
12077+#define VXC_KTHREAD 0x01000000
12078+#define VXC_NAMESPACE 0x02000000
d337f35e 12079+
4bf69007 12080+#endif /* _UAPI_VS_CONTEXT_H */
f973f73f
AM
12081diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/context_cmd.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/context_cmd.h
12082--- linux-4.1.27/include/uapi/vserver/context_cmd.h 1970-01-01 00:00:00.000000000 +0000
12083+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/context_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12084@@ -0,0 +1,115 @@
12085+#ifndef _UAPI_VS_CONTEXT_CMD_H
12086+#define _UAPI_VS_CONTEXT_CMD_H
d33d7b00
AM
12087+
12088+
4bf69007 12089+/* vinfo commands */
3bac966d 12090+
4bf69007 12091+#define VCMD_task_xid VC_CMD(VINFO, 1, 0)
3bac966d 12092+
3bac966d 12093+
4bf69007 12094+#define VCMD_vx_info VC_CMD(VINFO, 5, 0)
3bac966d 12095+
4bf69007
AM
12096+struct vcmd_vx_info_v0 {
12097+ uint32_t xid;
12098+ uint32_t initpid;
12099+ /* more to come */
12100+};
3bac966d
AM
12101+
12102+
4bf69007 12103+#define VCMD_ctx_stat VC_CMD(VSTAT, 0, 0)
3bac966d 12104+
4bf69007
AM
12105+struct vcmd_ctx_stat_v0 {
12106+ uint32_t usecnt;
12107+ uint32_t tasks;
12108+ /* more to come */
12109+};
3bac966d 12110+
3bac966d 12111+
4bf69007 12112+/* context commands */
3bac966d 12113+
4bf69007
AM
12114+#define VCMD_ctx_create_v0 VC_CMD(VPROC, 1, 0)
12115+#define VCMD_ctx_create VC_CMD(VPROC, 1, 1)
3bac966d 12116+
4bf69007
AM
12117+struct vcmd_ctx_create {
12118+ uint64_t flagword;
12119+};
3bac966d 12120+
4bf69007
AM
12121+#define VCMD_ctx_migrate_v0 VC_CMD(PROCMIG, 1, 0)
12122+#define VCMD_ctx_migrate VC_CMD(PROCMIG, 1, 1)
3bac966d 12123+
4bf69007
AM
12124+struct vcmd_ctx_migrate {
12125+ uint64_t flagword;
12126+};
3bac966d 12127+
d33d7b00 12128+
d33d7b00 12129+
4bf69007 12130+/* flag commands */
d33d7b00 12131+
4bf69007
AM
12132+#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0)
12133+#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0)
d33d7b00 12134+
4bf69007
AM
12135+struct vcmd_ctx_flags_v0 {
12136+ uint64_t flagword;
12137+ uint64_t mask;
12138+};
3bac966d
AM
12139+
12140+
3bac966d 12141+
4bf69007 12142+/* context caps commands */
3bac966d 12143+
4bf69007
AM
12144+#define VCMD_get_ccaps VC_CMD(FLAGS, 3, 1)
12145+#define VCMD_set_ccaps VC_CMD(FLAGS, 4, 1)
d33d7b00 12146+
4bf69007
AM
12147+struct vcmd_ctx_caps_v1 {
12148+ uint64_t ccaps;
12149+ uint64_t cmask;
12150+};
d33d7b00 12151+
d33d7b00
AM
12152+
12153+
4bf69007 12154+/* bcaps commands */
d33d7b00 12155+
4bf69007
AM
12156+#define VCMD_get_bcaps VC_CMD(FLAGS, 9, 0)
12157+#define VCMD_set_bcaps VC_CMD(FLAGS, 10, 0)
d33d7b00 12158+
4bf69007
AM
12159+struct vcmd_bcaps {
12160+ uint64_t bcaps;
12161+ uint64_t bmask;
12162+};
3bac966d 12163+
d33d7b00 12164+
d33d7b00 12165+
4bf69007 12166+/* umask commands */
d33d7b00 12167+
4bf69007
AM
12168+#define VCMD_get_umask VC_CMD(FLAGS, 13, 0)
12169+#define VCMD_set_umask VC_CMD(FLAGS, 14, 0)
3bac966d 12170+
4bf69007
AM
12171+struct vcmd_umask {
12172+ uint64_t umask;
12173+ uint64_t mask;
12174+};
d33d7b00 12175+
d33d7b00
AM
12176+
12177+
4bf69007 12178+/* wmask commands */
d33d7b00 12179+
4bf69007
AM
12180+#define VCMD_get_wmask VC_CMD(FLAGS, 15, 0)
12181+#define VCMD_set_wmask VC_CMD(FLAGS, 16, 0)
d33d7b00 12182+
4bf69007
AM
12183+struct vcmd_wmask {
12184+ uint64_t wmask;
12185+ uint64_t mask;
d33d7b00
AM
12186+};
12187+
d33d7b00 12188+
d33d7b00 12189+
4bf69007 12190+/* OOM badness */
d33d7b00 12191+
4bf69007
AM
12192+#define VCMD_get_badness VC_CMD(MEMCTRL, 5, 0)
12193+#define VCMD_set_badness VC_CMD(MEMCTRL, 6, 0)
d33d7b00 12194+
4bf69007
AM
12195+struct vcmd_badness_v0 {
12196+ int64_t bias;
12197+};
d33d7b00 12198+
4bf69007 12199+#endif /* _UAPI_VS_CONTEXT_CMD_H */
f973f73f
AM
12200diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/cvirt_cmd.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/cvirt_cmd.h
12201--- linux-4.1.27/include/uapi/vserver/cvirt_cmd.h 1970-01-01 00:00:00.000000000 +0000
12202+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/cvirt_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12203@@ -0,0 +1,41 @@
12204+#ifndef _UAPI_VS_CVIRT_CMD_H
12205+#define _UAPI_VS_CVIRT_CMD_H
d33d7b00 12206+
d33d7b00 12207+
4bf69007 12208+/* virtual host info name commands */
d33d7b00 12209+
4bf69007
AM
12210+#define VCMD_set_vhi_name VC_CMD(VHOST, 1, 0)
12211+#define VCMD_get_vhi_name VC_CMD(VHOST, 2, 0)
d33d7b00 12212+
4bf69007
AM
12213+struct vcmd_vhi_name_v0 {
12214+ uint32_t field;
12215+ char name[65];
12216+};
d33d7b00 12217+
d33d7b00 12218+
4bf69007
AM
12219+enum vhi_name_field {
12220+ VHIN_CONTEXT = 0,
12221+ VHIN_SYSNAME,
12222+ VHIN_NODENAME,
12223+ VHIN_RELEASE,
12224+ VHIN_VERSION,
12225+ VHIN_MACHINE,
12226+ VHIN_DOMAINNAME,
12227+};
d33d7b00 12228+
d33d7b00 12229+
d33d7b00 12230+
4bf69007 12231+#define VCMD_virt_stat VC_CMD(VSTAT, 3, 0)
d33d7b00 12232+
4bf69007
AM
12233+struct vcmd_virt_stat_v0 {
12234+ uint64_t offset;
12235+ uint64_t uptime;
12236+ uint32_t nr_threads;
12237+ uint32_t nr_running;
12238+ uint32_t nr_uninterruptible;
12239+ uint32_t nr_onhold;
12240+ uint32_t nr_forks;
12241+ uint32_t load[3];
12242+};
2380c486 12243+
4bf69007 12244+#endif /* _UAPI_VS_CVIRT_CMD_H */
f973f73f
AM
12245diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/debug_cmd.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/debug_cmd.h
12246--- linux-4.1.27/include/uapi/vserver/debug_cmd.h 1970-01-01 00:00:00.000000000 +0000
12247+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/debug_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12248@@ -0,0 +1,24 @@
12249+#ifndef _UAPI_VS_DEBUG_CMD_H
12250+#define _UAPI_VS_DEBUG_CMD_H
537831f9 12251+
537831f9 12252+
4bf69007 12253+/* debug commands */
537831f9 12254+
4bf69007 12255+#define VCMD_dump_history VC_CMD(DEBUG, 1, 0)
537831f9 12256+
4bf69007
AM
12257+#define VCMD_read_history VC_CMD(DEBUG, 5, 0)
12258+#define VCMD_read_monitor VC_CMD(DEBUG, 6, 0)
537831f9 12259+
4bf69007
AM
12260+struct vcmd_read_history_v0 {
12261+ uint32_t index;
12262+ uint32_t count;
12263+ char __user *data;
12264+};
537831f9 12265+
4bf69007
AM
12266+struct vcmd_read_monitor_v0 {
12267+ uint32_t index;
12268+ uint32_t count;
12269+ char __user *data;
12270+};
537831f9 12271+
4bf69007 12272+#endif /* _UAPI_VS_DEBUG_CMD_H */
f973f73f
AM
12273diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/device.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/device.h
12274--- linux-4.1.27/include/uapi/vserver/device.h 1970-01-01 00:00:00.000000000 +0000
12275+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/device.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12276@@ -0,0 +1,12 @@
12277+#ifndef _UAPI_VS_DEVICE_H
12278+#define _UAPI_VS_DEVICE_H
d337f35e 12279+
d337f35e 12280+
4bf69007
AM
12281+#define DATTR_CREATE 0x00000001
12282+#define DATTR_OPEN 0x00000002
d337f35e 12283+
4bf69007 12284+#define DATTR_REMAP 0x00000010
d337f35e 12285+
4bf69007 12286+#define DATTR_MASK 0x00000013
ec22aa5c 12287+
4bf69007 12288+#endif /* _UAPI_VS_DEVICE_H */
f973f73f
AM
12289diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/device_cmd.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/device_cmd.h
12290--- linux-4.1.27/include/uapi/vserver/device_cmd.h 1970-01-01 00:00:00.000000000 +0000
12291+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/device_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12292@@ -0,0 +1,16 @@
12293+#ifndef _UAPI_VS_DEVICE_CMD_H
12294+#define _UAPI_VS_DEVICE_CMD_H
2380c486 12295+
1163e6ab 12296+
4bf69007 12297+/* device vserver commands */
1163e6ab 12298+
4bf69007
AM
12299+#define VCMD_set_mapping VC_CMD(DEVICE, 1, 0)
12300+#define VCMD_unset_mapping VC_CMD(DEVICE, 2, 0)
e915af4e 12301+
4bf69007
AM
12302+struct vcmd_set_mapping_v0 {
12303+ const char __user *device;
12304+ const char __user *target;
12305+ uint32_t flags;
12306+};
e915af4e 12307+
4bf69007 12308+#endif /* _UAPI_VS_DEVICE_CMD_H */
f973f73f
AM
12309diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/dlimit_cmd.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/dlimit_cmd.h
12310--- linux-4.1.27/include/uapi/vserver/dlimit_cmd.h 1970-01-01 00:00:00.000000000 +0000
12311+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/dlimit_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12312@@ -0,0 +1,67 @@
12313+#ifndef _UAPI_VS_DLIMIT_CMD_H
12314+#define _UAPI_VS_DLIMIT_CMD_H
e915af4e 12315+
42bc425c 12316+
4bf69007 12317+/* dlimit vserver commands */
d337f35e 12318+
4bf69007
AM
12319+#define VCMD_add_dlimit VC_CMD(DLIMIT, 1, 0)
12320+#define VCMD_rem_dlimit VC_CMD(DLIMIT, 2, 0)
d337f35e 12321+
4bf69007
AM
12322+#define VCMD_set_dlimit VC_CMD(DLIMIT, 5, 0)
12323+#define VCMD_get_dlimit VC_CMD(DLIMIT, 6, 0)
d337f35e 12324+
4bf69007
AM
12325+struct vcmd_ctx_dlimit_base_v0 {
12326+ const char __user *name;
12327+ uint32_t flags;
12328+};
12329+
12330+struct vcmd_ctx_dlimit_v0 {
12331+ const char __user *name;
12332+ uint32_t space_used; /* used space in kbytes */
12333+ uint32_t space_total; /* maximum space in kbytes */
12334+ uint32_t inodes_used; /* used inodes */
12335+ uint32_t inodes_total; /* maximum inodes */
12336+ uint32_t reserved; /* reserved for root in % */
12337+ uint32_t flags;
12338+};
12339+
12340+#define CDLIM_UNSET ((uint32_t)0UL)
12341+#define CDLIM_INFINITY ((uint32_t)~0UL)
12342+#define CDLIM_KEEP ((uint32_t)~1UL)
12343+
12344+#define DLIME_UNIT 0
12345+#define DLIME_KILO 1
12346+#define DLIME_MEGA 2
12347+#define DLIME_GIGA 3
12348+
12349+#define DLIMF_SHIFT 0x10
12350+
12351+#define DLIMS_USED 0
12352+#define DLIMS_TOTAL 2
12353+
12354+static inline
12355+uint64_t dlimit_space_32to64(uint32_t val, uint32_t flags, int shift)
2380c486 12356+{
4bf69007
AM
12357+ int exp = (flags & DLIMF_SHIFT) ?
12358+ (flags >> shift) & DLIME_GIGA : DLIME_KILO;
12359+ return ((uint64_t)val) << (10 * exp);
2380c486
JR
12360+}
12361+
4bf69007
AM
12362+static inline
12363+uint32_t dlimit_space_64to32(uint64_t val, uint32_t *flags, int shift)
2380c486 12364+{
4bf69007 12365+ int exp = 0;
ec22aa5c 12366+
4bf69007
AM
12367+ if (*flags & DLIMF_SHIFT) {
12368+ while (val > (1LL << 32) && (exp < 3)) {
12369+ val >>= 10;
12370+ exp++;
12371+ }
12372+ *flags &= ~(DLIME_GIGA << shift);
12373+ *flags |= exp << shift;
12374+ } else
12375+ val >>= 10;
12376+ return val;
2380c486
JR
12377+}
12378+
4bf69007 12379+#endif /* _UAPI_VS_DLIMIT_CMD_H */
f973f73f
AM
12380diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/inode.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/inode.h
12381--- linux-4.1.27/include/uapi/vserver/inode.h 1970-01-01 00:00:00.000000000 +0000
12382+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/inode.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12383@@ -0,0 +1,23 @@
12384+#ifndef _UAPI_VS_INODE_H
12385+#define _UAPI_VS_INODE_H
2380c486 12386+
d337f35e 12387+
4bf69007 12388+#define IATTR_TAG 0x01000000
2380c486 12389+
4bf69007
AM
12390+#define IATTR_ADMIN 0x00000001
12391+#define IATTR_WATCH 0x00000002
12392+#define IATTR_HIDE 0x00000004
12393+#define IATTR_FLAGS 0x00000007
2380c486 12394+
4bf69007
AM
12395+#define IATTR_BARRIER 0x00010000
12396+#define IATTR_IXUNLINK 0x00020000
12397+#define IATTR_IMMUTABLE 0x00040000
12398+#define IATTR_COW 0x00080000
d337f35e 12399+
ec22aa5c 12400+
4bf69007 12401+/* inode ioctls */
ec22aa5c 12402+
4bf69007
AM
12403+#define FIOC_GETXFLG _IOR('x', 5, long)
12404+#define FIOC_SETXFLG _IOW('x', 6, long)
d337f35e 12405+
4bf69007 12406+#endif /* _UAPI_VS_INODE_H */
f973f73f
AM
12407diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/inode_cmd.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/inode_cmd.h
12408--- linux-4.1.27/include/uapi/vserver/inode_cmd.h 1970-01-01 00:00:00.000000000 +0000
12409+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/inode_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12410@@ -0,0 +1,26 @@
12411+#ifndef _UAPI_VS_INODE_CMD_H
12412+#define _UAPI_VS_INODE_CMD_H
d337f35e 12413+
db55b927 12414+
4bf69007 12415+/* inode vserver commands */
2c8c5bc5 12416+
4bf69007
AM
12417+#define VCMD_get_iattr VC_CMD(INODE, 1, 1)
12418+#define VCMD_set_iattr VC_CMD(INODE, 2, 1)
2bf5ad28 12419+
4bf69007
AM
12420+#define VCMD_fget_iattr VC_CMD(INODE, 3, 0)
12421+#define VCMD_fset_iattr VC_CMD(INODE, 4, 0)
4a036bed 12422+
4bf69007
AM
12423+struct vcmd_ctx_iattr_v1 {
12424+ const char __user *name;
12425+ uint32_t tag;
12426+ uint32_t flags;
12427+ uint32_t mask;
12428+};
4a036bed 12429+
4bf69007
AM
12430+struct vcmd_ctx_fiattr_v0 {
12431+ uint32_t tag;
12432+ uint32_t flags;
12433+ uint32_t mask;
12434+};
4a036bed 12435+
4bf69007 12436+#endif /* _UAPI_VS_INODE_CMD_H */
f973f73f
AM
12437diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/limit.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/limit.h
12438--- linux-4.1.27/include/uapi/vserver/limit.h 1970-01-01 00:00:00.000000000 +0000
12439+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/limit.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12440@@ -0,0 +1,14 @@
12441+#ifndef _UAPI_VS_LIMIT_H
12442+#define _UAPI_VS_LIMIT_H
4a036bed 12443+
42bc425c 12444+
4bf69007
AM
12445+#define VLIMIT_NSOCK 16
12446+#define VLIMIT_OPENFD 17
12447+#define VLIMIT_ANON 18
12448+#define VLIMIT_SHMEM 19
12449+#define VLIMIT_SEMARY 20
12450+#define VLIMIT_NSEMS 21
12451+#define VLIMIT_DENTRY 22
12452+#define VLIMIT_MAPPED 23
adc1caaa 12453+
4bf69007 12454+#endif /* _UAPI_VS_LIMIT_H */
f973f73f
AM
12455diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/limit_cmd.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/limit_cmd.h
12456--- linux-4.1.27/include/uapi/vserver/limit_cmd.h 1970-01-01 00:00:00.000000000 +0000
12457+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/limit_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12458@@ -0,0 +1,40 @@
12459+#ifndef _UAPI_VS_LIMIT_CMD_H
12460+#define _UAPI_VS_LIMIT_CMD_H
adc1caaa 12461+
adc1caaa 12462+
4bf69007 12463+/* rlimit vserver commands */
adc1caaa 12464+
4bf69007
AM
12465+#define VCMD_get_rlimit VC_CMD(RLIMIT, 1, 0)
12466+#define VCMD_set_rlimit VC_CMD(RLIMIT, 2, 0)
12467+#define VCMD_get_rlimit_mask VC_CMD(RLIMIT, 3, 0)
12468+#define VCMD_reset_hits VC_CMD(RLIMIT, 7, 0)
12469+#define VCMD_reset_minmax VC_CMD(RLIMIT, 9, 0)
adc1caaa 12470+
4bf69007
AM
12471+struct vcmd_ctx_rlimit_v0 {
12472+ uint32_t id;
12473+ uint64_t minimum;
12474+ uint64_t softlimit;
12475+ uint64_t maximum;
12476+};
d33d7b00 12477+
4bf69007
AM
12478+struct vcmd_ctx_rlimit_mask_v0 {
12479+ uint32_t minimum;
12480+ uint32_t softlimit;
12481+ uint32_t maximum;
12482+};
d33d7b00 12483+
4bf69007 12484+#define VCMD_rlimit_stat VC_CMD(VSTAT, 1, 0)
d33d7b00 12485+
4bf69007
AM
12486+struct vcmd_rlimit_stat_v0 {
12487+ uint32_t id;
12488+ uint32_t hits;
12489+ uint64_t value;
12490+ uint64_t minimum;
12491+ uint64_t maximum;
12492+};
d33d7b00 12493+
4bf69007
AM
12494+#define CRLIM_UNSET (0ULL)
12495+#define CRLIM_INFINITY (~0ULL)
12496+#define CRLIM_KEEP (~1ULL)
d33d7b00 12497+
4bf69007 12498+#endif /* _UAPI_VS_LIMIT_CMD_H */
f973f73f
AM
12499diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/monitor.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/monitor.h
12500--- linux-4.1.27/include/uapi/vserver/monitor.h 1970-01-01 00:00:00.000000000 +0000
12501+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/monitor.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12502@@ -0,0 +1,96 @@
12503+#ifndef _UAPI_VS_MONITOR_H
12504+#define _UAPI_VS_MONITOR_H
d33d7b00 12505+
4bf69007 12506+#include <linux/types.h>
d33d7b00 12507+
d33d7b00 12508+
4bf69007
AM
12509+enum {
12510+ VXM_UNUSED = 0,
d33d7b00 12511+
4bf69007 12512+ VXM_SYNC = 0x10,
d33d7b00 12513+
4bf69007
AM
12514+ VXM_UPDATE = 0x20,
12515+ VXM_UPDATE_1,
12516+ VXM_UPDATE_2,
d33d7b00 12517+
4bf69007
AM
12518+ VXM_RQINFO_1 = 0x24,
12519+ VXM_RQINFO_2,
d33d7b00 12520+
4bf69007
AM
12521+ VXM_ACTIVATE = 0x40,
12522+ VXM_DEACTIVATE,
12523+ VXM_IDLE,
d33d7b00 12524+
4bf69007
AM
12525+ VXM_HOLD = 0x44,
12526+ VXM_UNHOLD,
d33d7b00 12527+
4bf69007
AM
12528+ VXM_MIGRATE = 0x48,
12529+ VXM_RESCHED,
d33d7b00 12530+
4bf69007
AM
12531+ /* all other bits are flags */
12532+ VXM_SCHED = 0x80,
12533+};
d33d7b00 12534+
4bf69007
AM
12535+struct _vxm_update_1 {
12536+ uint32_t tokens_max;
12537+ uint32_t fill_rate;
12538+ uint32_t interval;
12539+};
d33d7b00 12540+
4bf69007
AM
12541+struct _vxm_update_2 {
12542+ uint32_t tokens_min;
12543+ uint32_t fill_rate;
12544+ uint32_t interval;
12545+};
d33d7b00 12546+
4bf69007
AM
12547+struct _vxm_rqinfo_1 {
12548+ uint16_t running;
12549+ uint16_t onhold;
12550+ uint16_t iowait;
12551+ uint16_t uintr;
12552+ uint32_t idle_tokens;
12553+};
d33d7b00 12554+
4bf69007
AM
12555+struct _vxm_rqinfo_2 {
12556+ uint32_t norm_time;
12557+ uint32_t idle_time;
12558+ uint32_t idle_skip;
12559+};
d33d7b00 12560+
4bf69007
AM
12561+struct _vxm_sched {
12562+ uint32_t tokens;
12563+ uint32_t norm_time;
12564+ uint32_t idle_time;
12565+};
d33d7b00 12566+
4bf69007
AM
12567+struct _vxm_task {
12568+ uint16_t pid;
12569+ uint16_t state;
12570+};
d33d7b00 12571+
4bf69007
AM
12572+struct _vxm_event {
12573+ uint32_t jif;
12574+ union {
12575+ uint32_t seq;
12576+ uint32_t sec;
12577+ };
12578+ union {
12579+ uint32_t tokens;
12580+ uint32_t nsec;
12581+ struct _vxm_task tsk;
12582+ };
12583+};
61b0c03f 12584+
4bf69007
AM
12585+struct _vx_mon_entry {
12586+ uint16_t type;
12587+ uint16_t xid;
12588+ union {
12589+ struct _vxm_event ev;
12590+ struct _vxm_sched sd;
12591+ struct _vxm_update_1 u1;
12592+ struct _vxm_update_2 u2;
12593+ struct _vxm_rqinfo_1 q1;
12594+ struct _vxm_rqinfo_2 q2;
12595+ };
12596+};
d33d7b00 12597+
4bf69007 12598+#endif /* _UAPI_VS_MONITOR_H */
f973f73f
AM
12599diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/network.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/network.h
12600--- linux-4.1.27/include/uapi/vserver/network.h 1970-01-01 00:00:00.000000000 +0000
12601+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/network.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12602@@ -0,0 +1,76 @@
12603+#ifndef _UAPI_VS_NETWORK_H
12604+#define _UAPI_VS_NETWORK_H
d33d7b00 12605+
4bf69007 12606+#include <linux/types.h>
d33d7b00 12607+
d33d7b00 12608+
4bf69007 12609+#define MAX_N_CONTEXT 65535 /* Arbitrary limit */
d33d7b00 12610+
d33d7b00 12611+
4bf69007 12612+/* network flags */
d33d7b00 12613+
4bf69007 12614+#define NXF_INFO_PRIVATE 0x00000008
d33d7b00 12615+
4bf69007
AM
12616+#define NXF_SINGLE_IP 0x00000100
12617+#define NXF_LBACK_REMAP 0x00000200
12618+#define NXF_LBACK_ALLOW 0x00000400
d33d7b00 12619+
4bf69007
AM
12620+#define NXF_HIDE_NETIF 0x02000000
12621+#define NXF_HIDE_LBACK 0x04000000
265d6dcc 12622+
4bf69007
AM
12623+#define NXF_STATE_SETUP (1ULL << 32)
12624+#define NXF_STATE_ADMIN (1ULL << 34)
d33d7b00 12625+
4bf69007
AM
12626+#define NXF_SC_HELPER (1ULL << 36)
12627+#define NXF_PERSISTENT (1ULL << 38)
d33d7b00 12628+
4bf69007 12629+#define NXF_ONE_TIME (0x0005ULL << 32)
d33d7b00 12630+
d33d7b00 12631+
4bf69007 12632+#define NXF_INIT_SET (__nxf_init_set())
d33d7b00 12633+
4bf69007
AM
12634+static inline uint64_t __nxf_init_set(void) {
12635+ return NXF_STATE_ADMIN
12636+#ifdef CONFIG_VSERVER_AUTO_LBACK
12637+ | NXF_LBACK_REMAP
12638+ | NXF_HIDE_LBACK
12639+#endif
12640+#ifdef CONFIG_VSERVER_AUTO_SINGLE
12641+ | NXF_SINGLE_IP
12642+#endif
12643+ | NXF_HIDE_NETIF;
12644+}
d33d7b00 12645+
d33d7b00 12646+
4bf69007 12647+/* network caps */
d33d7b00 12648+
4bf69007 12649+#define NXC_TUN_CREATE 0x00000001
d33d7b00 12650+
4bf69007 12651+#define NXC_RAW_ICMP 0x00000100
d33d7b00 12652+
4bf69007 12653+#define NXC_MULTICAST 0x00001000
d33d7b00 12654+
adc1caaa 12655+
4bf69007 12656+/* address types */
adc1caaa 12657+
4bf69007
AM
12658+#define NXA_TYPE_IPV4 0x0001
12659+#define NXA_TYPE_IPV6 0x0002
adc1caaa 12660+
4bf69007
AM
12661+#define NXA_TYPE_NONE 0x0000
12662+#define NXA_TYPE_ANY 0x00FF
adc1caaa 12663+
4bf69007
AM
12664+#define NXA_TYPE_ADDR 0x0010
12665+#define NXA_TYPE_MASK 0x0020
12666+#define NXA_TYPE_RANGE 0x0040
adc1caaa 12667+
4bf69007 12668+#define NXA_MASK_ALL (NXA_TYPE_ADDR | NXA_TYPE_MASK | NXA_TYPE_RANGE)
adc1caaa 12669+
4bf69007
AM
12670+#define NXA_MOD_BCAST 0x0100
12671+#define NXA_MOD_LBACK 0x0200
adc1caaa 12672+
4bf69007 12673+#define NXA_LOOPBACK 0x1000
2380c486 12674+
4bf69007
AM
12675+#define NXA_MASK_BIND (NXA_MASK_ALL | NXA_MOD_BCAST | NXA_MOD_LBACK)
12676+#define NXA_MASK_SHOW (NXA_MASK_ALL | NXA_LOOPBACK)
2380c486 12677+
4bf69007 12678+#endif /* _UAPI_VS_NETWORK_H */
f973f73f
AM
12679diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/network_cmd.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/network_cmd.h
12680--- linux-4.1.27/include/uapi/vserver/network_cmd.h 1970-01-01 00:00:00.000000000 +0000
12681+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/network_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12682@@ -0,0 +1,123 @@
12683+#ifndef _UAPI_VS_NETWORK_CMD_H
12684+#define _UAPI_VS_NETWORK_CMD_H
2380c486 12685+
2380c486 12686+
4bf69007 12687+/* vinfo commands */
2380c486 12688+
4bf69007 12689+#define VCMD_task_nid VC_CMD(VINFO, 2, 0)
2380c486 12690+
2380c486 12691+
4bf69007 12692+#define VCMD_nx_info VC_CMD(VINFO, 6, 0)
2380c486 12693+
4bf69007
AM
12694+struct vcmd_nx_info_v0 {
12695+ uint32_t nid;
12696+ /* more to come */
12697+};
2380c486 12698+
2380c486 12699+
4bf69007
AM
12700+#include <linux/in.h>
12701+#include <linux/in6.h>
2380c486 12702+
4bf69007
AM
12703+#define VCMD_net_create_v0 VC_CMD(VNET, 1, 0)
12704+#define VCMD_net_create VC_CMD(VNET, 1, 1)
2380c486 12705+
4bf69007
AM
12706+struct vcmd_net_create {
12707+ uint64_t flagword;
12708+};
2380c486 12709+
4bf69007 12710+#define VCMD_net_migrate VC_CMD(NETMIG, 1, 0)
2380c486 12711+
4bf69007
AM
12712+#define VCMD_net_add VC_CMD(NETALT, 1, 0)
12713+#define VCMD_net_remove VC_CMD(NETALT, 2, 0)
2380c486 12714+
4bf69007
AM
12715+struct vcmd_net_addr_v0 {
12716+ uint16_t type;
12717+ uint16_t count;
12718+ struct in_addr ip[4];
12719+ struct in_addr mask[4];
12720+};
2380c486 12721+
4bf69007
AM
12722+#define VCMD_net_add_ipv4_v1 VC_CMD(NETALT, 1, 1)
12723+#define VCMD_net_rem_ipv4_v1 VC_CMD(NETALT, 2, 1)
2380c486 12724+
4bf69007
AM
12725+struct vcmd_net_addr_ipv4_v1 {
12726+ uint16_t type;
12727+ uint16_t flags;
12728+ struct in_addr ip;
12729+ struct in_addr mask;
12730+};
2380c486 12731+
4bf69007
AM
12732+#define VCMD_net_add_ipv4 VC_CMD(NETALT, 1, 2)
12733+#define VCMD_net_rem_ipv4 VC_CMD(NETALT, 2, 2)
2380c486 12734+
4bf69007
AM
12735+struct vcmd_net_addr_ipv4_v2 {
12736+ uint16_t type;
12737+ uint16_t flags;
12738+ struct in_addr ip;
12739+ struct in_addr ip2;
12740+ struct in_addr mask;
12741+};
2380c486 12742+
4bf69007
AM
12743+#define VCMD_net_add_ipv6 VC_CMD(NETALT, 3, 1)
12744+#define VCMD_net_remove_ipv6 VC_CMD(NETALT, 4, 1)
2380c486 12745+
4bf69007
AM
12746+struct vcmd_net_addr_ipv6_v1 {
12747+ uint16_t type;
12748+ uint16_t flags;
12749+ uint32_t prefix;
12750+ struct in6_addr ip;
12751+ struct in6_addr mask;
12752+};
2380c486 12753+
4bf69007
AM
12754+#define VCMD_add_match_ipv4 VC_CMD(NETALT, 5, 0)
12755+#define VCMD_get_match_ipv4 VC_CMD(NETALT, 6, 0)
2380c486 12756+
4bf69007
AM
12757+struct vcmd_match_ipv4_v0 {
12758+ uint16_t type;
12759+ uint16_t flags;
12760+ uint16_t parent;
12761+ uint16_t prefix;
12762+ struct in_addr ip;
12763+ struct in_addr ip2;
12764+ struct in_addr mask;
12765+};
2380c486 12766+
4bf69007
AM
12767+#define VCMD_add_match_ipv6 VC_CMD(NETALT, 7, 0)
12768+#define VCMD_get_match_ipv6 VC_CMD(NETALT, 8, 0)
2380c486 12769+
4bf69007
AM
12770+struct vcmd_match_ipv6_v0 {
12771+ uint16_t type;
12772+ uint16_t flags;
12773+ uint16_t parent;
12774+ uint16_t prefix;
12775+ struct in6_addr ip;
12776+ struct in6_addr ip2;
12777+ struct in6_addr mask;
12778+};
2380c486 12779+
2380c486 12780+
2380c486 12781+
2380c486 12782+
4bf69007 12783+/* flag commands */
2380c486 12784+
4bf69007
AM
12785+#define VCMD_get_nflags VC_CMD(FLAGS, 5, 0)
12786+#define VCMD_set_nflags VC_CMD(FLAGS, 6, 0)
2380c486 12787+
4bf69007
AM
12788+struct vcmd_net_flags_v0 {
12789+ uint64_t flagword;
12790+ uint64_t mask;
12791+};
2380c486 12792+
2380c486 12793+
ab30d09f 12794+
4bf69007 12795+/* network caps commands */
ab30d09f 12796+
4bf69007
AM
12797+#define VCMD_get_ncaps VC_CMD(FLAGS, 7, 0)
12798+#define VCMD_set_ncaps VC_CMD(FLAGS, 8, 0)
ec22aa5c 12799+
4bf69007
AM
12800+struct vcmd_net_caps_v0 {
12801+ uint64_t ncaps;
12802+ uint64_t cmask;
12803+};
3bac966d 12804+
4bf69007 12805+#endif /* _UAPI_VS_NETWORK_CMD_H */
f973f73f
AM
12806diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/sched_cmd.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/sched_cmd.h
12807--- linux-4.1.27/include/uapi/vserver/sched_cmd.h 1970-01-01 00:00:00.000000000 +0000
12808+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/sched_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12809@@ -0,0 +1,13 @@
12810+#ifndef _UAPI_VS_SCHED_CMD_H
12811+#define _UAPI_VS_SCHED_CMD_H
d337f35e 12812+
d337f35e 12813+
4bf69007
AM
12814+struct vcmd_prio_bias {
12815+ int32_t cpu_id;
12816+ int32_t prio_bias;
12817+};
2380c486 12818+
4bf69007
AM
12819+#define VCMD_set_prio_bias VC_CMD(SCHED, 4, 0)
12820+#define VCMD_get_prio_bias VC_CMD(SCHED, 5, 0)
d337f35e 12821+
4bf69007 12822+#endif /* _UAPI_VS_SCHED_CMD_H */
f973f73f
AM
12823diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/signal_cmd.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/signal_cmd.h
12824--- linux-4.1.27/include/uapi/vserver/signal_cmd.h 1970-01-01 00:00:00.000000000 +0000
12825+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/signal_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12826@@ -0,0 +1,31 @@
12827+#ifndef _UAPI_VS_SIGNAL_CMD_H
12828+#define _UAPI_VS_SIGNAL_CMD_H
d337f35e 12829+
d337f35e 12830+
4bf69007 12831+/* signalling vserver commands */
d337f35e 12832+
4bf69007
AM
12833+#define VCMD_ctx_kill VC_CMD(PROCTRL, 1, 0)
12834+#define VCMD_wait_exit VC_CMD(EVENT, 99, 0)
d337f35e 12835+
4bf69007
AM
12836+struct vcmd_ctx_kill_v0 {
12837+ int32_t pid;
12838+ int32_t sig;
12839+};
d337f35e 12840+
4bf69007
AM
12841+struct vcmd_wait_exit_v0 {
12842+ int32_t reboot_cmd;
12843+ int32_t exit_code;
12844+};
d337f35e 12845+
d337f35e 12846+
4bf69007 12847+/* process alteration commands */
ab30d09f 12848+
4bf69007
AM
12849+#define VCMD_get_pflags VC_CMD(PROCALT, 5, 0)
12850+#define VCMD_set_pflags VC_CMD(PROCALT, 6, 0)
d337f35e 12851+
4bf69007
AM
12852+struct vcmd_pflags_v0 {
12853+ uint32_t flagword;
12854+ uint32_t mask;
12855+};
3bac966d 12856+
4bf69007 12857+#endif /* _UAPI_VS_SIGNAL_CMD_H */
f973f73f
AM
12858diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/space_cmd.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/space_cmd.h
12859--- linux-4.1.27/include/uapi/vserver/space_cmd.h 1970-01-01 00:00:00.000000000 +0000
12860+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/space_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12861@@ -0,0 +1,28 @@
12862+#ifndef _UAPI_VS_SPACE_CMD_H
12863+#define _UAPI_VS_SPACE_CMD_H
d337f35e 12864+
d337f35e 12865+
4bf69007
AM
12866+#define VCMD_enter_space_v0 VC_CMD(PROCALT, 1, 0)
12867+#define VCMD_enter_space_v1 VC_CMD(PROCALT, 1, 1)
12868+#define VCMD_enter_space VC_CMD(PROCALT, 1, 2)
2380c486 12869+
4bf69007
AM
12870+#define VCMD_set_space_v0 VC_CMD(PROCALT, 3, 0)
12871+#define VCMD_set_space_v1 VC_CMD(PROCALT, 3, 1)
12872+#define VCMD_set_space VC_CMD(PROCALT, 3, 2)
d337f35e 12873+
4bf69007 12874+#define VCMD_get_space_mask_v0 VC_CMD(PROCALT, 4, 0)
d337f35e 12875+
4bf69007
AM
12876+#define VCMD_get_space_mask VC_CMD(VSPACE, 0, 1)
12877+#define VCMD_get_space_default VC_CMD(VSPACE, 1, 0)
d337f35e 12878+
d337f35e 12879+
4bf69007
AM
12880+struct vcmd_space_mask_v1 {
12881+ uint64_t mask;
12882+};
d337f35e 12883+
4bf69007
AM
12884+struct vcmd_space_mask_v2 {
12885+ uint64_t mask;
12886+ uint32_t index;
12887+};
d337f35e 12888+
4bf69007 12889+#endif /* _UAPI_VS_SPACE_CMD_H */
f973f73f
AM
12890diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/switch.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/switch.h
12891--- linux-4.1.27/include/uapi/vserver/switch.h 1970-01-01 00:00:00.000000000 +0000
12892+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/switch.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12893@@ -0,0 +1,90 @@
12894+#ifndef _UAPI_VS_SWITCH_H
12895+#define _UAPI_VS_SWITCH_H
d337f35e 12896+
4bf69007 12897+#include <linux/types.h>
d337f35e 12898+
d337f35e 12899+
4bf69007
AM
12900+#define VC_CATEGORY(c) (((c) >> 24) & 0x3F)
12901+#define VC_COMMAND(c) (((c) >> 16) & 0xFF)
12902+#define VC_VERSION(c) ((c) & 0xFFF)
d337f35e 12903+
4bf69007
AM
12904+#define VC_CMD(c, i, v) ((((VC_CAT_ ## c) & 0x3F) << 24) \
12905+ | (((i) & 0xFF) << 16) | ((v) & 0xFFF))
d337f35e 12906+
4bf69007 12907+/*
d337f35e 12908+
4bf69007 12909+ Syscall Matrix V2.8
d337f35e 12910+
4bf69007
AM
12911+ |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|
12912+ |STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | |
12913+ |INFO |SETUP | |MOVE | | | | | |
12914+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12915+ SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICE | |
12916+ HOST | 00| 01| 02| 03| 04| 05| | 06| 07|
12917+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12918+ CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | |
12919+ PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15|
12920+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12921+ MEMORY | | | | |MEMCTRL| | |SWAP | |
12922+ | 16| 17| 18| 19| 20| 21| | 22| 23|
12923+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12924+ NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | |
12925+ | 24| 25| 26| 27| 28| 29| | 30| 31|
12926+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12927+ DISK | | | |TAGMIG |DLIMIT | | |INODE | |
12928+ VFS | 32| 33| 34| 35| 36| 37| | 38| 39|
12929+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12930+ OTHER |VSTAT | | | | | | |VINFO | |
12931+ | 40| 41| 42| 43| 44| 45| | 46| 47|
12932+ =======+=======+=======+=======+=======+=======+=======+ +=======+=======+
12933+ SPECIAL|EVENT | | | |FLAGS | | |VSPACE | |
12934+ | 48| 49| 50| 51| 52| 53| | 54| 55|
12935+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12936+ SPECIAL|DEBUG | | | |RLIMIT |SYSCALL| | |COMPAT |
12937+ | 56| 57| 58| 59| 60|TEST 61| | 62| 63|
12938+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
d337f35e 12939+
4bf69007 12940+*/
d337f35e 12941+
4bf69007 12942+#define VC_CAT_VERSION 0
d337f35e 12943+
4bf69007
AM
12944+#define VC_CAT_VSETUP 1
12945+#define VC_CAT_VHOST 2
d337f35e 12946+
4bf69007 12947+#define VC_CAT_DEVICE 6
d337f35e 12948+
4bf69007
AM
12949+#define VC_CAT_VPROC 9
12950+#define VC_CAT_PROCALT 10
12951+#define VC_CAT_PROCMIG 11
12952+#define VC_CAT_PROCTRL 12
d337f35e 12953+
4bf69007
AM
12954+#define VC_CAT_SCHED 14
12955+#define VC_CAT_MEMCTRL 20
d337f35e 12956+
4bf69007
AM
12957+#define VC_CAT_VNET 25
12958+#define VC_CAT_NETALT 26
12959+#define VC_CAT_NETMIG 27
12960+#define VC_CAT_NETCTRL 28
d337f35e 12961+
4bf69007
AM
12962+#define VC_CAT_TAGMIG 35
12963+#define VC_CAT_DLIMIT 36
12964+#define VC_CAT_INODE 38
d337f35e 12965+
4bf69007
AM
12966+#define VC_CAT_VSTAT 40
12967+#define VC_CAT_VINFO 46
12968+#define VC_CAT_EVENT 48
d337f35e 12969+
4bf69007
AM
12970+#define VC_CAT_FLAGS 52
12971+#define VC_CAT_VSPACE 54
12972+#define VC_CAT_DEBUG 56
12973+#define VC_CAT_RLIMIT 60
d337f35e 12974+
4bf69007
AM
12975+#define VC_CAT_SYSTEST 61
12976+#define VC_CAT_COMPAT 63
d337f35e 12977+
4bf69007 12978+/* query version */
d337f35e 12979+
4bf69007
AM
12980+#define VCMD_get_version VC_CMD(VERSION, 0, 0)
12981+#define VCMD_get_vci VC_CMD(VERSION, 1, 0)
2380c486 12982+
4bf69007 12983+#endif /* _UAPI_VS_SWITCH_H */
f973f73f
AM
12984diff -NurpP --minimal linux-4.1.27/include/uapi/vserver/tag_cmd.h linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/tag_cmd.h
12985--- linux-4.1.27/include/uapi/vserver/tag_cmd.h 1970-01-01 00:00:00.000000000 +0000
12986+++ linux-4.1.27-vs2.3.8.5.2/include/uapi/vserver/tag_cmd.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
12987@@ -0,0 +1,14 @@
12988+#ifndef _UAPI_VS_TAG_CMD_H
12989+#define _UAPI_VS_TAG_CMD_H
d337f35e 12990+
d337f35e 12991+
4bf69007 12992+/* vinfo commands */
d337f35e 12993+
4bf69007 12994+#define VCMD_task_tag VC_CMD(VINFO, 3, 0)
d337f35e
JR
12995+
12996+
4bf69007 12997+/* context commands */
d337f35e 12998+
4bf69007 12999+#define VCMD_tag_migrate VC_CMD(TAGMIG, 1, 0)
2380c486 13000+
4bf69007 13001+#endif /* _UAPI_VS_TAG_CMD_H */
f973f73f
AM
13002diff -NurpP --minimal linux-4.1.27/init/Kconfig linux-4.1.27-vs2.3.8.5.2/init/Kconfig
13003--- linux-4.1.27/init/Kconfig 2015-07-06 20:41:43.000000000 +0000
13004+++ linux-4.1.27-vs2.3.8.5.2/init/Kconfig 2016-07-05 04:41:47.000000000 +0000
5eef5607 13005@@ -938,6 +938,7 @@ config NUMA_BALANCING_DEFAULT_ENABLED
4bf69007 13006 menuconfig CGROUPS
5eef5607 13007 bool "Control Group support"
265de2f7 13008 select KERNFS
4bf69007
AM
13009+ default y
13010 help
13011 This option adds support for grouping sets of processes together, for
13012 use with process control subsystems such as Cpusets, CFS, memory
f973f73f
AM
13013diff -NurpP --minimal linux-4.1.27/init/main.c linux-4.1.27-vs2.3.8.5.2/init/main.c
13014--- linux-4.1.27/init/main.c 2016-07-05 04:28:32.000000000 +0000
13015+++ linux-4.1.27-vs2.3.8.5.2/init/main.c 2016-07-05 04:41:47.000000000 +0000
5eef5607
AM
13016@@ -81,6 +81,7 @@
13017 #include <linux/integrity.h>
13018 #include <linux/proc_ns.h>
13019 #include <linux/io.h>
4bf69007
AM
13020+#include <linux/vserver/percpu.h>
13021
13022 #include <asm/io.h>
13023 #include <asm/bugs.h>
f973f73f
AM
13024diff -NurpP --minimal linux-4.1.27/ipc/mqueue.c linux-4.1.27-vs2.3.8.5.2/ipc/mqueue.c
13025--- linux-4.1.27/ipc/mqueue.c 2016-07-05 04:28:32.000000000 +0000
13026+++ linux-4.1.27-vs2.3.8.5.2/ipc/mqueue.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
13027@@ -35,6 +35,8 @@
13028 #include <linux/ipc_namespace.h>
13029 #include <linux/user_namespace.h>
13030 #include <linux/slab.h>
13031+#include <linux/vs_context.h>
13032+#include <linux/vs_limit.h>
13033
13034 #include <net/sock.h>
13035 #include "util.h"
13036@@ -76,6 +78,7 @@ struct mqueue_inode_info {
bb20add7 13037 struct pid *notify_owner;
4bf69007
AM
13038 struct user_namespace *notify_user_ns;
13039 struct user_struct *user; /* user who created, for accounting */
13040+ struct vx_info *vxi;
13041 struct sock *notify_sock;
13042 struct sk_buff *notify_cookie;
13043
5eef5607 13044@@ -231,6 +234,7 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
13045 if (S_ISREG(mode)) {
13046 struct mqueue_inode_info *info;
13047 unsigned long mq_bytes, mq_treesize;
13048+ struct vx_info *vxi = current_vx_info();
13049
13050 inode->i_fop = &mqueue_file_operations;
13051 inode->i_size = FILENT_SIZE;
5eef5607 13052@@ -244,6 +248,7 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
13053 info->notify_user_ns = NULL;
13054 info->qsize = 0;
13055 info->user = NULL; /* set when all is ok */
13056+ info->vxi = NULL;
13057 info->msg_tree = RB_ROOT;
13058 info->node_cache = NULL;
13059 memset(&info->attr, 0, sizeof(info->attr));
5eef5607 13060@@ -277,17 +282,20 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
13061
13062 spin_lock(&mq_lock);
13063 if (u->mq_bytes + mq_bytes < u->mq_bytes ||
13064- u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE)) {
13065+ u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE) ||
13066+ !vx_ipcmsg_avail(vxi, mq_bytes)) {
13067 spin_unlock(&mq_lock);
13068 /* mqueue_evict_inode() releases info->messages */
13069 ret = -EMFILE;
13070 goto out_inode;
13071 }
13072 u->mq_bytes += mq_bytes;
13073+ vx_ipcmsg_add(vxi, u, mq_bytes);
13074 spin_unlock(&mq_lock);
13075
13076 /* all is ok */
13077 info->user = get_uid(u);
13078+ info->vxi = get_vx_info(vxi);
13079 } else if (S_ISDIR(mode)) {
13080 inc_nlink(inode);
13081 /* Some things misbehave if size == 0 on a directory */
5eef5607 13082@@ -399,8 +407,11 @@ static void mqueue_evict_inode(struct in
4bf69007
AM
13083
13084 user = info->user;
13085 if (user) {
13086+ struct vx_info *vxi = info->vxi;
d337f35e 13087+
4bf69007
AM
13088 spin_lock(&mq_lock);
13089 user->mq_bytes -= mq_bytes;
13090+ vx_ipcmsg_sub(vxi, user, mq_bytes);
13091 /*
13092 * get_ns_from_inode() ensures that the
13093 * (ipc_ns = sb->s_fs_info) is either a valid ipc_ns
5eef5607 13094@@ -410,6 +421,7 @@ static void mqueue_evict_inode(struct in
4bf69007
AM
13095 if (ipc_ns)
13096 ipc_ns->mq_queues_count--;
13097 spin_unlock(&mq_lock);
13098+ put_vx_info(vxi);
13099 free_uid(user);
13100 }
13101 if (ipc_ns)
f973f73f
AM
13102diff -NurpP --minimal linux-4.1.27/ipc/msg.c linux-4.1.27-vs2.3.8.5.2/ipc/msg.c
13103--- linux-4.1.27/ipc/msg.c 2016-07-05 04:28:32.000000000 +0000
13104+++ linux-4.1.27-vs2.3.8.5.2/ipc/msg.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
13105@@ -37,6 +37,7 @@
13106 #include <linux/rwsem.h>
13107 #include <linux/nsproxy.h>
13108 #include <linux/ipc_namespace.h>
13109+#include <linux/vs_base.h>
13110
13111 #include <asm/current.h>
bb20add7
AM
13112 #include <linux/uaccess.h>
13113@@ -129,6 +130,7 @@ static int newque(struct ipc_namespace *
4bf69007
AM
13114
13115 msq->q_perm.mode = msgflg & S_IRWXUGO;
13116 msq->q_perm.key = key;
13117+ msq->q_perm.xid = vx_current_xid();
13118
13119 msq->q_perm.security = NULL;
13120 retval = security_msg_queue_alloc(msq);
f973f73f
AM
13121diff -NurpP --minimal linux-4.1.27/ipc/sem.c linux-4.1.27-vs2.3.8.5.2/ipc/sem.c
13122--- linux-4.1.27/ipc/sem.c 2016-07-05 04:28:32.000000000 +0000
13123+++ linux-4.1.27-vs2.3.8.5.2/ipc/sem.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 13124@@ -85,6 +85,8 @@
4bf69007
AM
13125 #include <linux/rwsem.h>
13126 #include <linux/nsproxy.h>
13127 #include <linux/ipc_namespace.h>
13128+#include <linux/vs_base.h>
13129+#include <linux/vs_limit.h>
13130
bb20add7 13131 #include <linux/uaccess.h>
4bf69007 13132 #include "util.h"
5eef5607 13133@@ -516,6 +518,7 @@ static int newary(struct ipc_namespace *
4bf69007
AM
13134
13135 sma->sem_perm.mode = (semflg & S_IRWXUGO);
13136 sma->sem_perm.key = key;
13137+ sma->sem_perm.xid = vx_current_xid();
13138
13139 sma->sem_perm.security = NULL;
13140 retval = security_sem_alloc(sma);
5eef5607 13141@@ -545,6 +548,9 @@ static int newary(struct ipc_namespace *
4bf69007
AM
13142 return id;
13143 }
13144 ns->used_sems += nsems;
13145+ /* FIXME: obsoleted? */
13146+ vx_semary_inc(sma);
13147+ vx_nsems_add(sma, nsems);
13148
bb20add7
AM
13149 sem_unlock(sma, -1);
13150 rcu_read_unlock();
5eef5607 13151@@ -1133,6 +1139,9 @@ static void freeary(struct ipc_namespace
4bf69007
AM
13152
13153 wake_up_sem_queue_do(&tasks);
13154 ns->used_sems -= sma->sem_nsems;
13155+ /* FIXME: obsoleted? */
13156+ vx_nsems_sub(sma, sma->sem_nsems);
13157+ vx_semary_dec(sma);
926e38e0 13158 ipc_rcu_putref(sma, sem_rcu_free);
4bf69007 13159 }
926e38e0 13160
f973f73f
AM
13161diff -NurpP --minimal linux-4.1.27/ipc/shm.c linux-4.1.27-vs2.3.8.5.2/ipc/shm.c
13162--- linux-4.1.27/ipc/shm.c 2016-07-05 04:28:32.000000000 +0000
13163+++ linux-4.1.27-vs2.3.8.5.2/ipc/shm.c 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 13164@@ -42,6 +42,8 @@
4bf69007
AM
13165 #include <linux/nsproxy.h>
13166 #include <linux/mount.h>
13167 #include <linux/ipc_namespace.h>
13168+#include <linux/vs_context.h>
13169+#include <linux/vs_limit.h>
13170
bb20add7 13171 #include <linux/uaccess.h>
4bf69007 13172
f973f73f 13173@@ -228,10 +230,14 @@ static void shm_open(struct vm_area_stru
4bf69007
AM
13174 static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
13175 {
c2e5f7c8 13176 struct file *shm_file;
4bf69007
AM
13177+ struct vx_info *vxi = lookup_vx_info(shp->shm_perm.xid);
13178+ int numpages = (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
c2e5f7c8
JR
13179
13180 shm_file = shp->shm_file;
13181 shp->shm_file = NULL;
13182- ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
4bf69007
AM
13183+ vx_ipcshm_sub(vxi, shp, numpages);
13184+ ns->shm_tot -= numpages;
d337f35e 13185+
4bf69007
AM
13186 shm_rmid(ns, shp);
13187 shm_unlock(shp);
c2e5f7c8 13188 if (!is_file_hugepages(shm_file))
f973f73f 13189@@ -240,6 +246,7 @@ static void shm_destroy(struct ipc_names
5eef5607
AM
13190 user_shm_unlock(i_size_read(file_inode(shm_file)),
13191 shp->mlock_user);
c2e5f7c8 13192 fput(shm_file);
4bf69007 13193+ put_vx_info(vxi);
926e38e0 13194 ipc_rcu_putref(shp, shm_rcu_free);
4bf69007
AM
13195 }
13196
f973f73f 13197@@ -537,11 +544,15 @@ static int newseg(struct ipc_namespace *
bb20add7 13198 ns->shm_tot + numpages > ns->shm_ctlall)
4bf69007
AM
13199 return -ENOSPC;
13200
13201+ if (!vx_ipcshm_avail(current_vx_info(), numpages))
13202+ return -ENOSPC;
d337f35e 13203+
4bf69007
AM
13204 shp = ipc_rcu_alloc(sizeof(*shp));
13205 if (!shp)
13206 return -ENOMEM;
13207
13208 shp->shm_perm.key = key;
13209+ shp->shm_perm.xid = vx_current_xid();
13210 shp->shm_perm.mode = (shmflg & S_IRWXUGO);
13211 shp->mlock_user = NULL;
13212
f973f73f 13213@@ -612,6 +623,7 @@ static int newseg(struct ipc_namespace *
926e38e0
JR
13214
13215 ipc_unlock_object(&shp->shm_perm);
13216 rcu_read_unlock();
4bf69007
AM
13217+ vx_ipcshm_add(current_vx_info(), key, numpages);
13218 return error;
13219
13220 no_id:
f973f73f
AM
13221diff -NurpP --minimal linux-4.1.27/kernel/Makefile linux-4.1.27-vs2.3.8.5.2/kernel/Makefile
13222--- linux-4.1.27/kernel/Makefile 2015-07-06 20:41:43.000000000 +0000
13223+++ linux-4.1.27-vs2.3.8.5.2/kernel/Makefile 2016-07-05 04:41:47.000000000 +0000
5eef5607 13224@@ -29,6 +29,7 @@ obj-y += printk/
c2e5f7c8
JR
13225 obj-y += irq/
13226 obj-y += rcu/
5eef5607 13227 obj-y += livepatch/
4bf69007
AM
13228+obj-y += vserver/
13229
b00e13aa
AM
13230 obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o
13231 obj-$(CONFIG_FREEZER) += freezer.o
f973f73f
AM
13232diff -NurpP --minimal linux-4.1.27/kernel/auditsc.c linux-4.1.27-vs2.3.8.5.2/kernel/auditsc.c
13233--- linux-4.1.27/kernel/auditsc.c 2015-07-06 20:41:43.000000000 +0000
13234+++ linux-4.1.27-vs2.3.8.5.2/kernel/auditsc.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 13235@@ -1966,7 +1966,7 @@ static int audit_set_loginuid_perm(kuid_
c2e5f7c8 13236 if (is_audit_feature_set(AUDIT_FEATURE_LOGINUID_IMMUTABLE))
4bf69007 13237 return -EPERM;
c2e5f7c8 13238 /* it is set, you need permission */
4bf69007
AM
13239- if (!capable(CAP_AUDIT_CONTROL))
13240+ if (!vx_capable(CAP_AUDIT_CONTROL, VXC_AUDIT_CONTROL))
13241 return -EPERM;
c2e5f7c8
JR
13242 /* reject if this is not an unset and we don't allow that */
13243 if (is_audit_feature_set(AUDIT_FEATURE_ONLY_UNSET_LOGINUID) && uid_valid(loginuid))
f973f73f
AM
13244diff -NurpP --minimal linux-4.1.27/kernel/capability.c linux-4.1.27-vs2.3.8.5.2/kernel/capability.c
13245--- linux-4.1.27/kernel/capability.c 2015-07-06 20:41:43.000000000 +0000
13246+++ linux-4.1.27-vs2.3.8.5.2/kernel/capability.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 13247@@ -17,6 +17,7 @@
4bf69007
AM
13248 #include <linux/syscalls.h>
13249 #include <linux/pid_namespace.h>
13250 #include <linux/user_namespace.h>
13251+#include <linux/vs_context.h>
13252 #include <asm/uaccess.h>
13253
13254 /*
5eef5607 13255@@ -107,6 +108,7 @@ static int cap_validate_magic(cap_user_h
4bf69007
AM
13256 return 0;
13257 }
13258
2380c486 13259+
4bf69007
AM
13260 /*
13261 * The only thing that can change the capabilities of the current
13262 * process is the current process. As such, we can't be in this code
5eef5607 13263@@ -344,6 +346,8 @@ bool has_ns_capability_noaudit(struct ta
4bf69007
AM
13264 return (ret == 0);
13265 }
13266
13267+#include <linux/vserver/base.h>
d337f35e 13268+
4bf69007
AM
13269 /**
13270 * has_capability_noaudit - Does a task have a capability (unaudited) in the
13271 * initial user ns
f973f73f
AM
13272diff -NurpP --minimal linux-4.1.27/kernel/compat.c linux-4.1.27-vs2.3.8.5.2/kernel/compat.c
13273--- linux-4.1.27/kernel/compat.c 2015-07-06 20:41:43.000000000 +0000
13274+++ linux-4.1.27-vs2.3.8.5.2/kernel/compat.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
13275@@ -27,6 +27,7 @@
13276 #include <linux/times.h>
13277 #include <linux/ptrace.h>
13278 #include <linux/gfp.h>
13279+#include <linux/vs_time.h>
13280
13281 #include <asm/uaccess.h>
13282
5eef5607 13283@@ -1059,7 +1060,7 @@ COMPAT_SYSCALL_DEFINE1(stime, compat_tim
4bf69007
AM
13284 if (err)
13285 return err;
13286
13287- do_settimeofday(&tv);
13288+ vx_settimeofday(&tv);
13289 return 0;
13290 }
13291
f973f73f
AM
13292diff -NurpP --minimal linux-4.1.27/kernel/cred.c linux-4.1.27-vs2.3.8.5.2/kernel/cred.c
13293--- linux-4.1.27/kernel/cred.c 2015-07-06 20:41:43.000000000 +0000
13294+++ linux-4.1.27-vs2.3.8.5.2/kernel/cred.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 13295@@ -59,31 +59,6 @@ struct cred init_cred = {
b00e13aa 13296 .group_info = &init_groups,
4bf69007
AM
13297 };
13298
13299-static inline void set_cred_subscribers(struct cred *cred, int n)
13300-{
13301-#ifdef CONFIG_DEBUG_CREDENTIALS
13302- atomic_set(&cred->subscribers, n);
13303-#endif
13304-}
13305-
13306-static inline int read_cred_subscribers(const struct cred *cred)
13307-{
13308-#ifdef CONFIG_DEBUG_CREDENTIALS
13309- return atomic_read(&cred->subscribers);
13310-#else
13311- return 0;
13312-#endif
13313-}
13314-
13315-static inline void alter_cred_subscribers(const struct cred *_cred, int n)
13316-{
13317-#ifdef CONFIG_DEBUG_CREDENTIALS
13318- struct cred *cred = (struct cred *) _cred;
13319-
13320- atomic_add(n, &cred->subscribers);
13321-#endif
13322-}
13323-
13324 /*
b00e13aa 13325 * The RCU callback to actually dispose of a set of credentials
4bf69007 13326 */
5eef5607 13327@@ -235,21 +210,16 @@ error:
4bf69007
AM
13328 *
13329 * Call commit_creds() or abort_creds() to clean up.
13330 */
13331-struct cred *prepare_creds(void)
13332+struct cred *__prepare_creds(const struct cred *old)
13333 {
13334- struct task_struct *task = current;
13335- const struct cred *old;
13336 struct cred *new;
13337
13338- validate_process_creds();
13339-
13340 new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
13341 if (!new)
13342 return NULL;
13343
13344 kdebug("prepare_creds() alloc %p", new);
13345
13346- old = task->cred;
13347 memcpy(new, old, sizeof(struct cred));
13348
13349 atomic_set(&new->usage, 1);
5eef5607 13350@@ -278,6 +248,13 @@ error:
4bf69007
AM
13351 abort_creds(new);
13352 return NULL;
13353 }
d337f35e 13354+
4bf69007 13355+struct cred *prepare_creds(void)
2380c486 13356+{
4bf69007 13357+ validate_process_creds();
d337f35e 13358+
4bf69007 13359+ return __prepare_creds(current->cred);
2380c486 13360+}
4bf69007
AM
13361 EXPORT_SYMBOL(prepare_creds);
13362
13363 /*
f973f73f
AM
13364diff -NurpP --minimal linux-4.1.27/kernel/exit.c linux-4.1.27-vs2.3.8.5.2/kernel/exit.c
13365--- linux-4.1.27/kernel/exit.c 2016-07-05 04:28:32.000000000 +0000
13366+++ linux-4.1.27-vs2.3.8.5.2/kernel/exit.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
13367@@ -48,6 +48,10 @@
13368 #include <linux/fs_struct.h>
13369 #include <linux/init_task.h>
13370 #include <linux/perf_event.h>
13371+#include <linux/vs_limit.h>
13372+#include <linux/vs_context.h>
13373+#include <linux/vs_network.h>
13374+#include <linux/vs_pid.h>
13375 #include <trace/events/sched.h>
13376 #include <linux/hw_breakpoint.h>
13377 #include <linux/oom.h>
5eef5607 13378@@ -456,14 +460,24 @@ static struct task_struct *find_child_re
4bf69007
AM
13379 {
13380 struct pid_namespace *pid_ns = task_active_pid_ns(father);
5eef5607 13381 struct task_struct *reaper = pid_ns->child_reaper;
4bf69007 13382+ struct vx_info *vxi = task_get_vx_info(father);
d337f35e 13383+
4bf69007
AM
13384+ if (vxi) {
13385+ BUG_ON(!vxi->vx_reaper);
13386+ if (vxi->vx_reaper != init_pid_ns.child_reaper &&
5eef5607 13387+ vxi->vx_reaper != father) {
4bf69007 13388+ reaper = vxi->vx_reaper;
5eef5607
AM
13389+ goto out_put;
13390+ }
13391+ }
4bf69007 13392
5eef5607
AM
13393 if (likely(reaper != father))
13394- return reaper;
13395+ goto out_put;
13396
13397 reaper = find_alive_thread(father);
13398 if (reaper) {
13399 pid_ns->child_reaper = reaper;
13400- return reaper;
13401+ goto out_put;
4bf69007
AM
13402 }
13403
5eef5607
AM
13404 write_unlock_irq(&tasklist_lock);
13405@@ -474,7 +488,10 @@ static struct task_struct *find_child_re
13406 zap_pid_ns_processes(pid_ns);
13407 write_lock_irq(&tasklist_lock);
13408
13409- return father;
13410+ reaper = father;
4bf69007
AM
13411+out_put:
13412+ put_vx_info(vxi);
13413+ return reaper;
13414 }
13415
13416 /*
9e3e8383
AM
13417@@ -562,9 +579,13 @@ static void forget_original_parent(struc
13418 return;
13419
13420 reaper = find_new_reaper(father, reaper);
13421- list_for_each_entry(p, &father->children, sibling) {
13422+ for (p = list_first_entry(&father->children, struct task_struct, sibling);
13423+ &p->sibling != &father->children; ) {
13424+ struct task_struct *next, *this_reaper = reaper;
13425+ if (p == reaper)
13426+ this_reaper = task_active_pid_ns(reaper)->child_reaper;
13427 for_each_thread(p, t) {
13428- t->real_parent = reaper;
13429+ t->real_parent = this_reaper;
13430 BUG_ON((!t->ptrace) != (t->parent == father));
13431 if (likely(!t->ptrace))
13432 t->parent = t->real_parent;
13433@@ -576,10 +597,13 @@ static void forget_original_parent(struc
13434 * If this is a threaded reparent there is no need to
13435 * notify anyone anything has happened.
13436 */
13437- if (!same_thread_group(reaper, father))
13438+ if (!same_thread_group(this_reaper, father))
13439 reparent_leader(father, p, dead);
13440+ next = list_next_entry(p, sibling);
13441+ list_add(&p->sibling, &this_reaper->children);
13442+ p = next;
13443 }
13444- list_splice_tail_init(&father->children, &reaper->children);
13445+ INIT_LIST_HEAD(&father->children);
13446 }
13447
13448 /*
13449@@ -761,6 +785,9 @@ void do_exit(long code)
4bf69007 13450 */
c2e5f7c8 13451 flush_ptrace_hw_breakpoint(tsk);
4bf69007
AM
13452
13453+ /* needs to stay before exit_notify() */
13454+ exit_vx_info_early(tsk, code);
d337f35e 13455+
bb20add7 13456 TASKS_RCU(tasks_rcu_i = __srcu_read_lock(&tasks_rcu_exit_srcu));
4bf69007 13457 exit_notify(tsk, group_dead);
bb20add7 13458 proc_exit_connector(tsk);
9e3e8383 13459@@ -818,10 +845,15 @@ void do_exit(long code)
4bf69007
AM
13460 smp_mb();
13461 raw_spin_unlock_wait(&tsk->pi_lock);
13462
13463+ /* needs to stay after exit_notify() */
13464+ exit_vx_info(tsk, code);
13465+ exit_nx_info(tsk);
d337f35e 13466+
4bf69007
AM
13467 /* causes final put_task_struct in finish_task_switch(). */
13468 tsk->state = TASK_DEAD;
13469 tsk->flags |= PF_NOFREEZE; /* tell freezer to ignore us */
13470 schedule();
13471+ printk("bad task: %p [%lx]\n", current, current->state);
13472 BUG();
13473 /* Avoid "noreturn function does return". */
13474 for (;;)
f973f73f
AM
13475diff -NurpP --minimal linux-4.1.27/kernel/fork.c linux-4.1.27-vs2.3.8.5.2/kernel/fork.c
13476--- linux-4.1.27/kernel/fork.c 2016-07-05 04:28:32.000000000 +0000
13477+++ linux-4.1.27-vs2.3.8.5.2/kernel/fork.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 13478@@ -75,6 +75,9 @@
09be7631 13479 #include <linux/aio.h>
265de2f7 13480 #include <linux/compiler.h>
5eef5607 13481 #include <linux/sysctl.h>
4bf69007
AM
13482+#include <linux/vs_context.h>
13483+#include <linux/vs_network.h>
13484+#include <linux/vs_limit.h>
13485
13486 #include <asm/pgtable.h>
13487 #include <asm/pgalloc.h>
5eef5607 13488@@ -225,6 +228,8 @@ void free_task(struct task_struct *tsk)
4bf69007
AM
13489 arch_release_thread_info(tsk->stack);
13490 free_thread_info(tsk->stack);
13491 rt_mutex_debug_task_free(tsk);
13492+ clr_vx_info(&tsk->vx_info);
13493+ clr_nx_info(&tsk->nx_info);
13494 ftrace_graph_exit_task(tsk);
13495 put_seccomp_filter(tsk);
13496 arch_release_task_struct(tsk);
5eef5607 13497@@ -1245,6 +1250,8 @@ static struct task_struct *copy_process(
8d50a2ea 13498 {
4bf69007
AM
13499 int retval;
13500 struct task_struct *p;
4bf69007
AM
13501+ struct vx_info *vxi;
13502+ struct nx_info *nxi;
13503
13504 if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
13505 return ERR_PTR(-EINVAL);
5eef5607 13506@@ -1306,7 +1313,12 @@ static struct task_struct *copy_process(
4bf69007
AM
13507 DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
13508 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
13509 #endif
13510+ init_vx_info(&p->vx_info, current_vx_info());
13511+ init_nx_info(&p->nx_info, current_nx_info());
13512+
13513 retval = -EAGAIN;
13514+ if (!vx_nproc_avail(1))
13515+ goto bad_fork_free;
13516 if (atomic_read(&p->real_cred->user->processes) >=
13517 task_rlimit(p, RLIMIT_NPROC)) {
c2e5f7c8 13518 if (p->real_cred->user != INIT_USER &&
5eef5607 13519@@ -1590,6 +1602,18 @@ static struct task_struct *copy_process(
4bf69007
AM
13520 total_forks++;
13521 spin_unlock(&current->sighand->siglock);
bb20add7 13522 syscall_tracepoint_update(p);
4bf69007
AM
13523+
13524+ /* p is copy of current */
13525+ vxi = p->vx_info;
13526+ if (vxi) {
13527+ claim_vx_info(vxi, p);
13528+ atomic_inc(&vxi->cvirt.nr_threads);
13529+ atomic_inc(&vxi->cvirt.total_forks);
13530+ vx_nproc_inc(p);
2380c486 13531+ }
4bf69007
AM
13532+ nxi = p->nx_info;
13533+ if (nxi)
13534+ claim_nx_info(nxi, p);
13535 write_unlock_irq(&tasklist_lock);
bb20add7 13536
4bf69007 13537 proc_fork_connector(p);
f973f73f
AM
13538diff -NurpP --minimal linux-4.1.27/kernel/kthread.c linux-4.1.27-vs2.3.8.5.2/kernel/kthread.c
13539--- linux-4.1.27/kernel/kthread.c 2015-04-12 22:12:50.000000000 +0000
13540+++ linux-4.1.27-vs2.3.8.5.2/kernel/kthread.c 2016-07-05 04:41:47.000000000 +0000
09be7631 13541@@ -18,6 +18,7 @@
4bf69007
AM
13542 #include <linux/freezer.h>
13543 #include <linux/ptrace.h>
09be7631 13544 #include <linux/uaccess.h>
4bf69007
AM
13545+#include <linux/vs_pid.h>
13546 #include <trace/events/sched.h>
13547
13548 static DEFINE_SPINLOCK(kthread_create_lock);
f973f73f
AM
13549diff -NurpP --minimal linux-4.1.27/kernel/nsproxy.c linux-4.1.27-vs2.3.8.5.2/kernel/nsproxy.c
13550--- linux-4.1.27/kernel/nsproxy.c 2015-04-12 22:12:50.000000000 +0000
13551+++ linux-4.1.27-vs2.3.8.5.2/kernel/nsproxy.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
13552@@ -20,11 +20,14 @@
13553 #include <linux/mnt_namespace.h>
13554 #include <linux/utsname.h>
13555 #include <linux/pid_namespace.h>
13556+#include <linux/vserver/global.h>
13557+#include <linux/vserver/debug.h>
13558 #include <net/net_namespace.h>
13559 #include <linux/ipc_namespace.h>
09be7631 13560 #include <linux/proc_ns.h>
4bf69007
AM
13561 #include <linux/file.h>
13562 #include <linux/syscalls.h>
13563+#include "../fs/mount.h"
13564
13565 static struct kmem_cache *nsproxy_cachep;
13566
13567@@ -46,8 +49,11 @@ static inline struct nsproxy *create_nsp
13568 struct nsproxy *nsproxy;
13569
13570 nsproxy = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL);
13571- if (nsproxy)
13572+ if (nsproxy) {
13573 atomic_set(&nsproxy->count, 1);
13574+ atomic_inc(&vs_global_nsproxy);
13575+ }
13576+ vxdprintk(VXD_CBIT(space, 2), "create_nsproxy = %p[1]", nsproxy);
13577 return nsproxy;
13578 }
13579
b00e13aa 13580@@ -56,9 +62,12 @@ static inline struct nsproxy *create_nsp
4bf69007
AM
13581 * Return the newly created nsproxy. Do not attach this to the task,
13582 * leave it to the caller to do proper locking and attach it to task.
13583 */
13584-static struct nsproxy *create_new_namespaces(unsigned long flags,
b00e13aa
AM
13585- struct task_struct *tsk, struct user_namespace *user_ns,
13586- struct fs_struct *new_fs)
13587+static struct nsproxy *unshare_namespaces(
13588+ unsigned long flags,
13589+ struct nsproxy *orig,
13590+ struct fs_struct *new_fs,
13591+ struct user_namespace *new_user,
13592+ struct pid_namespace *new_pid)
4bf69007
AM
13593 {
13594 struct nsproxy *new_nsp;
13595 int err;
c2e5f7c8 13596@@ -67,32 +76,31 @@ static struct nsproxy *create_new_namesp
4bf69007
AM
13597 if (!new_nsp)
13598 return ERR_PTR(-ENOMEM);
13599
b00e13aa
AM
13600- new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, user_ns, new_fs);
13601+ new_nsp->mnt_ns = copy_mnt_ns(flags, orig->mnt_ns, new_user, new_fs);
4bf69007
AM
13602 if (IS_ERR(new_nsp->mnt_ns)) {
13603 err = PTR_ERR(new_nsp->mnt_ns);
13604 goto out_ns;
13605 }
13606
b00e13aa
AM
13607- new_nsp->uts_ns = copy_utsname(flags, user_ns, tsk->nsproxy->uts_ns);
13608+ new_nsp->uts_ns = copy_utsname(flags, new_user, orig->uts_ns);
4bf69007
AM
13609 if (IS_ERR(new_nsp->uts_ns)) {
13610 err = PTR_ERR(new_nsp->uts_ns);
13611 goto out_uts;
13612 }
13613
b00e13aa
AM
13614- new_nsp->ipc_ns = copy_ipcs(flags, user_ns, tsk->nsproxy->ipc_ns);
13615+ new_nsp->ipc_ns = copy_ipcs(flags, new_user, orig->ipc_ns);
4bf69007
AM
13616 if (IS_ERR(new_nsp->ipc_ns)) {
13617 err = PTR_ERR(new_nsp->ipc_ns);
13618 goto out_ipc;
13619 }
13620
c2e5f7c8
JR
13621- new_nsp->pid_ns_for_children =
13622- copy_pid_ns(flags, user_ns, tsk->nsproxy->pid_ns_for_children);
13623+ new_nsp->pid_ns_for_children = copy_pid_ns(flags, new_user, new_pid);
13624 if (IS_ERR(new_nsp->pid_ns_for_children)) {
13625 err = PTR_ERR(new_nsp->pid_ns_for_children);
4bf69007
AM
13626 goto out_pid;
13627 }
13628
b00e13aa
AM
13629- new_nsp->net_ns = copy_net_ns(flags, user_ns, tsk->nsproxy->net_ns);
13630+ new_nsp->net_ns = copy_net_ns(flags, new_user, orig->net_ns);
4bf69007
AM
13631 if (IS_ERR(new_nsp->net_ns)) {
13632 err = PTR_ERR(new_nsp->net_ns);
13633 goto out_net;
c2e5f7c8 13634@@ -117,6 +125,41 @@ out_ns:
4bf69007
AM
13635 return ERR_PTR(err);
13636 }
13637
13638+static struct nsproxy *create_new_namespaces(unsigned long flags,
b00e13aa
AM
13639+ struct task_struct *tsk, struct user_namespace *user_ns,
13640+ struct fs_struct *new_fs)
13641+
4bf69007
AM
13642+{
13643+ return unshare_namespaces(flags, tsk->nsproxy,
b00e13aa 13644+ new_fs, user_ns, task_active_pid_ns(tsk));
2380c486 13645+}
d337f35e 13646+
4bf69007
AM
13647+/*
13648+ * copies the nsproxy, setting refcount to 1, and grabbing a
13649+ * reference to all contained namespaces.
13650+ */
13651+struct nsproxy *copy_nsproxy(struct nsproxy *orig)
2380c486 13652+{
4bf69007 13653+ struct nsproxy *ns = create_nsproxy();
d337f35e 13654+
4bf69007
AM
13655+ if (ns) {
13656+ memcpy(ns, orig, sizeof(struct nsproxy));
13657+ atomic_set(&ns->count, 1);
d337f35e 13658+
4bf69007
AM
13659+ if (ns->mnt_ns)
13660+ get_mnt_ns(ns->mnt_ns);
13661+ if (ns->uts_ns)
13662+ get_uts_ns(ns->uts_ns);
13663+ if (ns->ipc_ns)
13664+ get_ipc_ns(ns->ipc_ns);
c2e5f7c8
JR
13665+ if (ns->pid_ns_for_children)
13666+ get_pid_ns(ns->pid_ns_for_children);
4bf69007
AM
13667+ if (ns->net_ns)
13668+ get_net(ns->net_ns);
13669+ }
13670+ return ns;
13671+}
d337f35e 13672+
4bf69007
AM
13673 /*
13674 * called from clone. This now handles copy for nsproxy and all
13675 * namespaces therein.
c2e5f7c8 13676@@ -125,7 +168,10 @@ int copy_namespaces(unsigned long flags,
4bf69007
AM
13677 {
13678 struct nsproxy *old_ns = tsk->nsproxy;
b00e13aa 13679 struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns);
4bf69007
AM
13680- struct nsproxy *new_ns;
13681+ struct nsproxy *new_ns = NULL;
c2e5f7c8 13682+
4bf69007
AM
13683+ vxdprintk(VXD_CBIT(space, 7), "copy_namespaces(0x%08lx,%p[%p])",
13684+ flags, tsk, old_ns);
4bf69007 13685
c2e5f7c8
JR
13686 if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
13687 CLONE_NEWPID | CLONE_NEWNET)))) {
13688@@ -133,7 +179,7 @@ int copy_namespaces(unsigned long flags,
4bf69007 13689 return 0;
4bf69007 13690 }
4bf69007 13691
c2e5f7c8
JR
13692- if (!ns_capable(user_ns, CAP_SYS_ADMIN))
13693+ if (!vx_ns_can_unshare(user_ns, CAP_SYS_ADMIN, flags))
13694 return -EPERM;
13695
13696 /*
13697@@ -152,6 +198,9 @@ int copy_namespaces(unsigned long flags,
13698 return PTR_ERR(new_ns);
13699
13700 tsk->nsproxy = new_ns;
4bf69007 13701+ vxdprintk(VXD_CBIT(space, 3),
c2e5f7c8
JR
13702+ "copy_namespaces(0x%08lx,%p[%p]) = [%p]",
13703+ flags, tsk, old_ns, new_ns);
13704 return 0;
4bf69007
AM
13705 }
13706
c2e5f7c8 13707@@ -165,7 +214,9 @@ void free_nsproxy(struct nsproxy *ns)
4bf69007 13708 put_ipc_ns(ns->ipc_ns);
c2e5f7c8
JR
13709 if (ns->pid_ns_for_children)
13710 put_pid_ns(ns->pid_ns_for_children);
4bf69007
AM
13711- put_net(ns->net_ns);
13712+ if (ns->net_ns)
13713+ put_net(ns->net_ns);
13714+ atomic_dec(&vs_global_nsproxy);
13715 kmem_cache_free(nsproxy_cachep, ns);
13716 }
13717
c2e5f7c8 13718@@ -179,12 +230,16 @@ int unshare_nsproxy_namespaces(unsigned
b00e13aa 13719 struct user_namespace *user_ns;
4bf69007
AM
13720 int err = 0;
13721
13722+ vxdprintk(VXD_CBIT(space, 4),
13723+ "unshare_nsproxy_namespaces(0x%08lx,[%p])",
13724+ unshare_flags, current->nsproxy);
d337f35e 13725+
4bf69007 13726 if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
b00e13aa 13727 CLONE_NEWNET | CLONE_NEWPID)))
4bf69007
AM
13728 return 0;
13729
b00e13aa
AM
13730 user_ns = new_cred ? new_cred->user_ns : current_user_ns();
13731- if (!ns_capable(user_ns, CAP_SYS_ADMIN))
13732+ if (!vx_ns_can_unshare(user_ns, CAP_SYS_ADMIN, unshare_flags))
4bf69007
AM
13733 return -EPERM;
13734
b00e13aa 13735 *new_nsp = create_new_namespaces(unshare_flags, current, user_ns,
f973f73f
AM
13736diff -NurpP --minimal linux-4.1.27/kernel/pid.c linux-4.1.27-vs2.3.8.5.2/kernel/pid.c
13737--- linux-4.1.27/kernel/pid.c 2015-07-06 20:41:43.000000000 +0000
13738+++ linux-4.1.27-vs2.3.8.5.2/kernel/pid.c 2016-07-05 04:41:47.000000000 +0000
09be7631 13739@@ -38,6 +38,7 @@
4bf69007 13740 #include <linux/syscalls.h>
09be7631 13741 #include <linux/proc_ns.h>
b00e13aa 13742 #include <linux/proc_fs.h>
4bf69007
AM
13743+#include <linux/vs_pid.h>
13744
13745 #define pid_hashfn(nr, ns) \
13746 hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
5eef5607 13747@@ -379,7 +380,7 @@ EXPORT_SYMBOL_GPL(find_pid_ns);
4bf69007
AM
13748
13749 struct pid *find_vpid(int nr)
13750 {
b00e13aa
AM
13751- return find_pid_ns(nr, task_active_pid_ns(current));
13752+ return find_pid_ns(vx_rmap_pid(nr), task_active_pid_ns(current));
4bf69007
AM
13753 }
13754 EXPORT_SYMBOL_GPL(find_vpid);
13755
5eef5607 13756@@ -435,6 +436,9 @@ void transfer_pid(struct task_struct *ol
4bf69007
AM
13757 struct task_struct *pid_task(struct pid *pid, enum pid_type type)
13758 {
13759 struct task_struct *result = NULL;
d337f35e 13760+
4bf69007
AM
13761+ if (type == PIDTYPE_REALPID)
13762+ type = PIDTYPE_PID;
13763 if (pid) {
13764 struct hlist_node *first;
13765 first = rcu_dereference_check(hlist_first_rcu(&pid->tasks[type]),
5eef5607 13766@@ -454,7 +458,7 @@ struct task_struct *find_task_by_pid_ns(
4bf69007
AM
13767 rcu_lockdep_assert(rcu_read_lock_held(),
13768 "find_task_by_pid_ns() needs rcu_read_lock()"
13769 " protection");
13770- return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
13771+ return pid_task(find_pid_ns(vx_rmap_pid(nr), ns), PIDTYPE_PID);
13772 }
13773
13774 struct task_struct *find_task_by_vpid(pid_t vnr)
5eef5607 13775@@ -498,7 +502,7 @@ struct pid *find_get_pid(pid_t nr)
4bf69007
AM
13776 }
13777 EXPORT_SYMBOL_GPL(find_get_pid);
13778
13779-pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
13780+pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns)
13781 {
13782 struct upid *upid;
13783 pid_t nr = 0;
5eef5607 13784@@ -512,6 +516,11 @@ pid_t pid_nr_ns(struct pid *pid, struct
4bf69007
AM
13785 }
13786 EXPORT_SYMBOL_GPL(pid_nr_ns);
13787
13788+pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
2380c486 13789+{
4bf69007
AM
13790+ return vx_map_pid(pid_unmapped_nr_ns(pid, ns));
13791+}
d337f35e 13792+
4bf69007
AM
13793 pid_t pid_vnr(struct pid *pid)
13794 {
b00e13aa 13795 return pid_nr_ns(pid, task_active_pid_ns(current));
f973f73f
AM
13796diff -NurpP --minimal linux-4.1.27/kernel/pid_namespace.c linux-4.1.27-vs2.3.8.5.2/kernel/pid_namespace.c
13797--- linux-4.1.27/kernel/pid_namespace.c 2015-04-12 22:12:50.000000000 +0000
13798+++ linux-4.1.27-vs2.3.8.5.2/kernel/pid_namespace.c 2016-07-05 04:41:47.000000000 +0000
b00e13aa 13799@@ -18,6 +18,7 @@
09be7631 13800 #include <linux/proc_ns.h>
4bf69007
AM
13801 #include <linux/reboot.h>
13802 #include <linux/export.h>
13803+#include <linux/vserver/global.h>
13804
09be7631
JR
13805 struct pid_cache {
13806 int nr_ids;
5eef5607
AM
13807@@ -111,6 +112,7 @@ static struct pid_namespace *create_pid_
13808 ns->ns.ops = &pidns_operations;
4bf69007
AM
13809
13810 kref_init(&ns->kref);
13811+ atomic_inc(&vs_global_pid_ns);
13812 ns->level = level;
13813 ns->parent = get_pid_ns(parent_pid_ns);
b00e13aa 13814 ns->user_ns = get_user_ns(user_ns);
5eef5607 13815@@ -128,6 +130,7 @@ static struct pid_namespace *create_pid_
c2e5f7c8
JR
13816 out_free_map:
13817 kfree(ns->pidmap[0].page);
13818 out_free:
4bf69007
AM
13819+ atomic_dec(&vs_global_pid_ns);
13820 kmem_cache_free(pid_ns_cachep, ns);
c2e5f7c8
JR
13821 out:
13822 return ERR_PTR(err);
f973f73f
AM
13823diff -NurpP --minimal linux-4.1.27/kernel/printk/printk.c linux-4.1.27-vs2.3.8.5.2/kernel/printk/printk.c
13824--- linux-4.1.27/kernel/printk/printk.c 2016-07-05 04:28:32.000000000 +0000
13825+++ linux-4.1.27-vs2.3.8.5.2/kernel/printk/printk.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 13826@@ -46,6 +46,7 @@
09be7631 13827 #include <linux/utsname.h>
bb20add7 13828 #include <linux/ctype.h>
5eef5607 13829 #include <linux/uio.h>
4bf69007
AM
13830+#include <linux/vs_cvirt.h>
13831
13832 #include <asm/uaccess.h>
13833
5eef5607
AM
13834@@ -487,7 +488,7 @@ int check_syslog_permissions(int type, b
13835 goto ok;
4bf69007
AM
13836
13837 if (syslog_action_restricted(type)) {
13838- if (capable(CAP_SYSLOG))
13839+ if (vx_capable(CAP_SYSLOG, VXC_SYSLOG))
5eef5607 13840 goto ok;
092a4f51
JR
13841 /*
13842 * For historical reasons, accept CAP_SYS_ADMIN too, with
5eef5607 13843@@ -1264,12 +1265,9 @@ int do_syslog(int type, char __user *buf
4bf69007 13844 if (error)
5eef5607 13845 goto out;
4bf69007
AM
13846
13847- switch (type) {
13848- case SYSLOG_ACTION_CLOSE: /* Close log */
13849- break;
13850- case SYSLOG_ACTION_OPEN: /* Open log */
13851- break;
13852- case SYSLOG_ACTION_READ: /* Read from log */
13853+ if ((type == SYSLOG_ACTION_READ) ||
13854+ (type == SYSLOG_ACTION_READ_ALL) ||
13855+ (type == SYSLOG_ACTION_READ_CLEAR)) {
13856 error = -EINVAL;
13857 if (!buf || len < 0)
13858 goto out;
5eef5607 13859@@ -1280,6 +1278,16 @@ int do_syslog(int type, char __user *buf
4bf69007
AM
13860 error = -EFAULT;
13861 goto out;
13862 }
13863+ }
13864+ if (!vx_check(0, VS_ADMIN|VS_WATCH))
13865+ return vx_do_syslog(type, buf, len);
d337f35e 13866+
4bf69007
AM
13867+ switch (type) {
13868+ case SYSLOG_ACTION_CLOSE: /* Close log */
13869+ break;
13870+ case SYSLOG_ACTION_OPEN: /* Open log */
13871+ break;
13872+ case SYSLOG_ACTION_READ: /* Read from log */
13873 error = wait_event_interruptible(log_wait,
13874 syslog_seq != log_next_seq);
13875 if (error)
5eef5607 13876@@ -1292,16 +1300,6 @@ int do_syslog(int type, char __user *buf
4bf69007
AM
13877 /* FALL THRU */
13878 /* Read last kernel messages */
13879 case SYSLOG_ACTION_READ_ALL:
13880- error = -EINVAL;
13881- if (!buf || len < 0)
13882- goto out;
13883- error = 0;
13884- if (!len)
13885- goto out;
13886- if (!access_ok(VERIFY_WRITE, buf, len)) {
13887- error = -EFAULT;
13888- goto out;
13889- }
13890 error = syslog_print_all(buf, len, clear);
13891 break;
13892 /* Clear ring buffer */
f973f73f
AM
13893diff -NurpP --minimal linux-4.1.27/kernel/ptrace.c linux-4.1.27-vs2.3.8.5.2/kernel/ptrace.c
13894--- linux-4.1.27/kernel/ptrace.c 2016-07-05 04:28:32.000000000 +0000
13895+++ linux-4.1.27-vs2.3.8.5.2/kernel/ptrace.c 2016-07-05 04:41:47.000000000 +0000
09be7631 13896@@ -23,6 +23,7 @@
4bf69007
AM
13897 #include <linux/syscalls.h>
13898 #include <linux/uaccess.h>
13899 #include <linux/regset.h>
13900+#include <linux/vs_context.h>
13901 #include <linux/hw_breakpoint.h>
13902 #include <linux/cn_proc.h>
09be7631 13903 #include <linux/compat.h>
f973f73f 13904@@ -281,6 +282,11 @@ ok:
b00e13aa
AM
13905 }
13906 rcu_read_unlock();
13907
4bf69007
AM
13908+ if (!vx_check(task->xid, VS_ADMIN_P|VS_WATCH_P|VS_IDENT))
13909+ return -EPERM;
13910+ if (!vx_check(task->xid, VS_IDENT) &&
13911+ !task_vx_flags(task, VXF_STATE_ADMIN, 0))
13912+ return -EACCES;
4bf69007
AM
13913 return security_ptrace_access_check(task, mode);
13914 }
b00e13aa 13915
f973f73f
AM
13916diff -NurpP --minimal linux-4.1.27/kernel/reboot.c linux-4.1.27-vs2.3.8.5.2/kernel/reboot.c
13917--- linux-4.1.27/kernel/reboot.c 2015-07-06 20:41:43.000000000 +0000
13918+++ linux-4.1.27-vs2.3.8.5.2/kernel/reboot.c 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8
JR
13919@@ -16,6 +16,7 @@
13920 #include <linux/syscalls.h>
13921 #include <linux/syscore_ops.h>
13922 #include <linux/uaccess.h>
13923+#include <linux/vs_pid.h>
13924
13925 /*
13926 * this indicates whether you can reboot with ctrl-alt-del: the default is yes
bb20add7 13927@@ -269,6 +270,8 @@ EXPORT_SYMBOL_GPL(kernel_power_off);
c2e5f7c8
JR
13928
13929 static DEFINE_MUTEX(reboot_mutex);
13930
13931+long vs_reboot(unsigned int, void __user *);
13932+
13933 /*
13934 * Reboot system call: for obvious reasons only root may call it,
13935 * and even root needs to set up some magic numbers in the registers
bb20add7 13936@@ -311,6 +314,9 @@ SYSCALL_DEFINE4(reboot, int, magic1, int
c2e5f7c8
JR
13937 if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
13938 cmd = LINUX_REBOOT_CMD_HALT;
13939
13940+ if (!vx_check(0, VS_ADMIN|VS_WATCH))
13941+ return vs_reboot(cmd, arg);
13942+
13943 mutex_lock(&reboot_mutex);
13944 switch (cmd) {
13945 case LINUX_REBOOT_CMD_RESTART:
f973f73f
AM
13946diff -NurpP --minimal linux-4.1.27/kernel/sched/core.c linux-4.1.27-vs2.3.8.5.2/kernel/sched/core.c
13947--- linux-4.1.27/kernel/sched/core.c 2016-07-05 04:28:32.000000000 +0000
13948+++ linux-4.1.27-vs2.3.8.5.2/kernel/sched/core.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 13949@@ -74,6 +74,8 @@
4bf69007 13950 #include <linux/binfmts.h>
b00e13aa 13951 #include <linux/context_tracking.h>
265de2f7 13952 #include <linux/compiler.h>
4bf69007
AM
13953+#include <linux/vs_sched.h>
13954+#include <linux/vs_cvirt.h>
13955
13956 #include <asm/switch_to.h>
13957 #include <asm/tlb.h>
5eef5607 13958@@ -3163,7 +3165,7 @@ SYSCALL_DEFINE1(nice, int, increment)
4bf69007 13959
bb20add7 13960 nice = clamp_val(nice, MIN_NICE, MAX_NICE);
4bf69007
AM
13961 if (increment < 0 && !can_nice(current, nice))
13962- return -EPERM;
13963+ return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
13964
13965 retval = security_task_setnice(current, nice);
13966 if (retval)
f973f73f
AM
13967diff -NurpP --minimal linux-4.1.27/kernel/sched/cputime.c linux-4.1.27-vs2.3.8.5.2/kernel/sched/cputime.c
13968--- linux-4.1.27/kernel/sched/cputime.c 2016-07-05 04:28:32.000000000 +0000
13969+++ linux-4.1.27-vs2.3.8.5.2/kernel/sched/cputime.c 2016-07-05 04:41:47.000000000 +0000
b00e13aa 13970@@ -4,6 +4,7 @@
4bf69007
AM
13971 #include <linux/kernel_stat.h>
13972 #include <linux/static_key.h>
b00e13aa 13973 #include <linux/context_tracking.h>
4bf69007
AM
13974+#include <linux/vs_sched.h>
13975 #include "sched.h"
13976
13977
bb20add7 13978@@ -135,14 +136,17 @@ static inline void task_group_account_fi
4bf69007
AM
13979 void account_user_time(struct task_struct *p, cputime_t cputime,
13980 cputime_t cputime_scaled)
13981 {
13982+ struct vx_info *vxi = p->vx_info; /* p is _always_ current */
ca5d134c 13983+ int nice = (task_nice(p) > 0);
4bf69007
AM
13984 int index;
13985
13986 /* Add user time to process. */
13987 p->utime += cputime;
13988 p->utimescaled += cputime_scaled;
13989+ vx_account_user(vxi, cputime, nice);
13990 account_group_user_time(p, cputime);
13991
ca5d134c 13992- index = (task_nice(p) > 0) ? CPUTIME_NICE : CPUTIME_USER;
4bf69007
AM
13993+ index = (nice) ? CPUTIME_NICE : CPUTIME_USER;
13994
13995 /* Add user time to cpustat. */
13996 task_group_account_field(p, index, (__force u64) cputime);
bb20add7 13997@@ -189,9 +193,12 @@ static inline
ca5d134c
JR
13998 void __account_system_time(struct task_struct *p, cputime_t cputime,
13999 cputime_t cputime_scaled, int index)
14000 {
14001+ struct vx_info *vxi = p->vx_info; /* p is _always_ current */
14002+
14003 /* Add system time to process. */
14004 p->stime += cputime;
14005 p->stimescaled += cputime_scaled;
14006+ vx_account_system(vxi, cputime, 0 /* do we have idle time? */);
14007 account_group_system_time(p, cputime);
14008
14009 /* Add system time to cpustat. */
f973f73f
AM
14010diff -NurpP --minimal linux-4.1.27/kernel/sched/fair.c linux-4.1.27-vs2.3.8.5.2/kernel/sched/fair.c
14011--- linux-4.1.27/kernel/sched/fair.c 2016-07-05 04:28:32.000000000 +0000
14012+++ linux-4.1.27-vs2.3.8.5.2/kernel/sched/fair.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 14013@@ -30,6 +30,7 @@
b00e13aa
AM
14014 #include <linux/mempolicy.h>
14015 #include <linux/migrate.h>
14016 #include <linux/task_work.h>
4bf69007
AM
14017+#include <linux/vs_cvirt.h>
14018
14019 #include <trace/events/sched.h>
14020
5eef5607 14021@@ -3090,6 +3091,8 @@ enqueue_entity(struct cfs_rq *cfs_rq, st
4bf69007
AM
14022 __enqueue_entity(cfs_rq, se);
14023 se->on_rq = 1;
14024
14025+ if (entity_is_task(se))
14026+ vx_activate_task(task_of(se));
14027 if (cfs_rq->nr_running == 1) {
14028 list_add_leaf_cfs_rq(cfs_rq);
14029 check_enqueue_throttle(cfs_rq);
5eef5607 14030@@ -3171,6 +3174,8 @@ dequeue_entity(struct cfs_rq *cfs_rq, st
4bf69007
AM
14031 if (se != cfs_rq->curr)
14032 __dequeue_entity(cfs_rq, se);
14033 se->on_rq = 0;
14034+ if (entity_is_task(se))
14035+ vx_deactivate_task(task_of(se));
4bf69007
AM
14036 account_entity_dequeue(cfs_rq, se);
14037
b00e13aa 14038 /*
f973f73f
AM
14039diff -NurpP --minimal linux-4.1.27/kernel/sched/proc.c linux-4.1.27-vs2.3.8.5.2/kernel/sched/proc.c
14040--- linux-4.1.27/kernel/sched/proc.c 2016-07-05 04:28:32.000000000 +0000
14041+++ linux-4.1.27-vs2.3.8.5.2/kernel/sched/proc.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 14042@@ -71,9 +71,17 @@ EXPORT_SYMBOL(avenrun); /* should be rem
c2e5f7c8
JR
14043 */
14044 void get_avenrun(unsigned long *loads, unsigned long offset, int shift)
14045 {
14046- loads[0] = (avenrun[0] + offset) << shift;
14047- loads[1] = (avenrun[1] + offset) << shift;
14048- loads[2] = (avenrun[2] + offset) << shift;
14049+ if (vx_flags(VXF_VIRT_LOAD, 0)) {
14050+ struct vx_info *vxi = current_vx_info();
14051+
14052+ loads[0] = (vxi->cvirt.load[0] + offset) << shift;
14053+ loads[1] = (vxi->cvirt.load[1] + offset) << shift;
14054+ loads[2] = (vxi->cvirt.load[2] + offset) << shift;
14055+ } else {
14056+ loads[0] = (avenrun[0] + offset) << shift;
14057+ loads[1] = (avenrun[1] + offset) << shift;
14058+ loads[2] = (avenrun[2] + offset) << shift;
14059+ }
14060 }
14061
14062 long calc_load_fold_active(struct rq *this_rq)
f973f73f
AM
14063diff -NurpP --minimal linux-4.1.27/kernel/signal.c linux-4.1.27-vs2.3.8.5.2/kernel/signal.c
14064--- linux-4.1.27/kernel/signal.c 2016-07-05 04:28:32.000000000 +0000
14065+++ linux-4.1.27-vs2.3.8.5.2/kernel/signal.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 14066@@ -34,6 +34,8 @@
b00e13aa 14067 #include <linux/compat.h>
09be7631 14068 #include <linux/cn_proc.h>
265de2f7 14069 #include <linux/compiler.h>
4bf69007
AM
14070+#include <linux/vs_context.h>
14071+#include <linux/vs_pid.h>
265de2f7 14072
4bf69007
AM
14073 #define CREATE_TRACE_POINTS
14074 #include <trace/events/signal.h>
bb20add7 14075@@ -767,9 +769,18 @@ static int check_kill_permission(int sig
4bf69007
AM
14076 struct pid *sid;
14077 int error;
14078
14079+ vxdprintk(VXD_CBIT(misc, 7),
14080+ "check_kill_permission(%d,%p,%p[#%u,%u])",
14081+ sig, info, t, vx_task_xid(t), t->pid);
d337f35e 14082+
4bf69007
AM
14083 if (!valid_signal(sig))
14084 return -EINVAL;
14085
14086+/* FIXME: needed? if so, why?
14087+ if ((info != SEND_SIG_NOINFO) &&
14088+ (is_si_special(info) || !si_fromuser(info)))
14089+ goto skip; */
d337f35e 14090+
4bf69007
AM
14091 if (!si_fromuser(info))
14092 return 0;
14093
bb20add7 14094@@ -793,6 +804,20 @@ static int check_kill_permission(int sig
4bf69007
AM
14095 }
14096 }
14097
14098+ error = -EPERM;
14099+ if (t->pid == 1 && current->xid)
14100+ return error;
d337f35e 14101+
4bf69007
AM
14102+ error = -ESRCH;
14103+ /* FIXME: we shouldn't return ESRCH ever, to avoid
14104+ loops, maybe ENOENT or EACCES? */
14105+ if (!vx_check(vx_task_xid(t), VS_WATCH_P | VS_IDENT)) {
14106+ vxdprintk(current->xid || VXD_CBIT(misc, 7),
14107+ "signal %d[%p] xid mismatch %p[#%u,%u] xid=#%u",
14108+ sig, info, t, vx_task_xid(t), t->pid, current->xid);
14109+ return error;
2380c486 14110+ }
4bf69007
AM
14111+/* skip: */
14112 return security_task_kill(t, info, sig, 0);
14113 }
14114
9e3e8383 14115@@ -1344,8 +1369,14 @@ int kill_pid_info(int sig, struct siginf
5eef5607
AM
14116 for (;;) {
14117 rcu_read_lock();
14118 p = pid_task(pid, PIDTYPE_PID);
14119- if (p)
9e3e8383
AM
14120- error = group_send_sig_info(sig, info, p);
14121+ if (p) {
14122+ if (vx_check(vx_task_xid(p), VS_IDENT))
14123+ error = group_send_sig_info(sig, info, p);
14124+ else {
14125+ rcu_read_unlock();
14126+ return -ESRCH;
14127+ }
14128+ }
5eef5607
AM
14129 rcu_read_unlock();
14130 if (likely(!p || error != -ESRCH))
9e3e8383
AM
14131 return error;
14132@@ -1390,7 +1421,7 @@ int kill_pid_info_as_cred(int sig, struc
4bf69007
AM
14133
14134 rcu_read_lock();
14135 p = pid_task(pid, PIDTYPE_PID);
14136- if (!p) {
14137+ if (!p || !vx_check(vx_task_xid(p), VS_IDENT)) {
14138 ret = -ESRCH;
14139 goto out_unlock;
14140 }
9e3e8383 14141@@ -1442,8 +1473,10 @@ static int kill_something_info(int sig,
4bf69007
AM
14142 struct task_struct * p;
14143
14144 for_each_process(p) {
14145- if (task_pid_vnr(p) > 1 &&
14146- !same_thread_group(p, current)) {
14147+ if (vx_check(vx_task_xid(p), VS_ADMIN|VS_IDENT) &&
14148+ task_pid_vnr(p) > 1 &&
14149+ !same_thread_group(p, current) &&
14150+ !vx_current_initpid(p->pid)) {
14151 int err = group_send_sig_info(sig, info, p);
14152 ++count;
14153 if (err != -EPERM)
9e3e8383 14154@@ -2296,6 +2329,11 @@ relock:
4bf69007
AM
14155 !sig_kernel_only(signr))
14156 continue;
14157
14158+ /* virtual init is protected against user signals */
bb20add7 14159+ if ((ksig->info.si_code == SI_USER) &&
4bf69007
AM
14160+ vx_current_initpid(current->pid))
14161+ continue;
d337f35e 14162+
4bf69007
AM
14163 if (sig_kernel_stop(signr)) {
14164 /*
14165 * The default action is to stop all threads in
f973f73f
AM
14166diff -NurpP --minimal linux-4.1.27/kernel/softirq.c linux-4.1.27-vs2.3.8.5.2/kernel/softirq.c
14167--- linux-4.1.27/kernel/softirq.c 2015-04-12 22:12:50.000000000 +0000
14168+++ linux-4.1.27-vs2.3.8.5.2/kernel/softirq.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 14169@@ -26,6 +26,7 @@
4bf69007
AM
14170 #include <linux/smpboot.h>
14171 #include <linux/tick.h>
265de2f7 14172 #include <linux/irq.h>
4bf69007
AM
14173+#include <linux/vs_context.h>
14174
14175 #define CREATE_TRACE_POINTS
14176 #include <trace/events/irq.h>
f973f73f
AM
14177diff -NurpP --minimal linux-4.1.27/kernel/sys.c linux-4.1.27-vs2.3.8.5.2/kernel/sys.c
14178--- linux-4.1.27/kernel/sys.c 2016-07-05 04:28:32.000000000 +0000
14179+++ linux-4.1.27-vs2.3.8.5.2/kernel/sys.c 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 14180@@ -54,6 +54,7 @@
09be7631 14181 #include <linux/cred.h>
4bf69007
AM
14182
14183 #include <linux/kmsg_dump.h>
b00e13aa 14184+#include <linux/vs_pid.h>
4bf69007 14185 /* Move somewhere else to avoid recompiling? */
b00e13aa
AM
14186 #include <generated/utsrelease.h>
14187
5eef5607 14188@@ -157,7 +158,10 @@ static int set_one_prio(struct task_stru
4bf69007
AM
14189 goto out;
14190 }
14191 if (niceval < task_nice(p) && !can_nice(p, niceval)) {
14192- error = -EACCES;
14193+ if (vx_flags(VXF_IGNEG_NICE, 0))
14194+ error = 0;
14195+ else
14196+ error = -EACCES;
14197 goto out;
14198 }
14199 no_nice = security_task_setnice(p, niceval);
5eef5607 14200@@ -208,6 +212,8 @@ SYSCALL_DEFINE3(setpriority, int, which,
bb20add7
AM
14201 else
14202 pgrp = task_pgrp(current);
14203 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
14204+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
14205+ continue;
14206 error = set_one_prio(p, niceval, error);
14207 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
14208 break;
5eef5607 14209@@ -274,6 +280,8 @@ SYSCALL_DEFINE2(getpriority, int, which,
bb20add7
AM
14210 else
14211 pgrp = task_pgrp(current);
14212 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
14213+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
14214+ continue;
14215 niceval = nice_to_rlimit(task_nice(p));
14216 if (niceval > retval)
14217 retval = niceval;
5eef5607 14218@@ -290,6 +298,8 @@ SYSCALL_DEFINE2(getpriority, int, which,
bb20add7
AM
14219 goto out_unlock; /* No processes for this user */
14220 }
14221 do_each_thread(g, p) {
14222+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
14223+ continue;
14224 if (uid_eq(task_uid(p), uid)) {
14225 niceval = nice_to_rlimit(task_nice(p));
4bf69007 14226 if (niceval > retval)
5eef5607 14227@@ -1217,7 +1227,8 @@ SYSCALL_DEFINE2(sethostname, char __user
4bf69007
AM
14228 int errno;
14229 char tmp[__NEW_UTS_LEN];
14230
14231- if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
14232+ if (!vx_ns_capable(current->nsproxy->uts_ns->user_ns,
14233+ CAP_SYS_ADMIN, VXC_SET_UTSNAME))
14234 return -EPERM;
14235
14236 if (len < 0 || len > __NEW_UTS_LEN)
5eef5607 14237@@ -1268,7 +1279,8 @@ SYSCALL_DEFINE2(setdomainname, char __us
4bf69007
AM
14238 int errno;
14239 char tmp[__NEW_UTS_LEN];
14240
14241- if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
14242+ if (!vx_ns_capable(current->nsproxy->uts_ns->user_ns,
14243+ CAP_SYS_ADMIN, VXC_SET_UTSNAME))
14244 return -EPERM;
14245 if (len < 0 || len > __NEW_UTS_LEN)
14246 return -EINVAL;
5eef5607 14247@@ -1386,7 +1398,7 @@ int do_prlimit(struct task_struct *tsk,
4bf69007
AM
14248 /* Keep the capable check against init_user_ns until
14249 cgroups can contain all limits */
14250 if (new_rlim->rlim_max > rlim->rlim_max &&
14251- !capable(CAP_SYS_RESOURCE))
14252+ !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
14253 retval = -EPERM;
14254 if (!retval)
14255 retval = security_task_setrlimit(tsk->group_leader,
5eef5607 14256@@ -1439,7 +1451,8 @@ static int check_prlimit_permission(stru
4bf69007
AM
14257 gid_eq(cred->gid, tcred->sgid) &&
14258 gid_eq(cred->gid, tcred->gid))
14259 return 0;
14260- if (ns_capable(tcred->user_ns, CAP_SYS_RESOURCE))
14261+ if (vx_ns_capable(tcred->user_ns,
14262+ CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
14263 return 0;
14264
14265 return -EPERM;
f973f73f
AM
14266diff -NurpP --minimal linux-4.1.27/kernel/sysctl.c linux-4.1.27-vs2.3.8.5.2/kernel/sysctl.c
14267--- linux-4.1.27/kernel/sysctl.c 2016-07-05 04:28:32.000000000 +0000
14268+++ linux-4.1.27-vs2.3.8.5.2/kernel/sysctl.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 14269@@ -85,6 +85,7 @@
4bf69007
AM
14270 #if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_LOCK_STAT)
14271 #include <linux/lockdep.h>
14272 #endif
14273+extern char vshelper_path[];
14274 #ifdef CONFIG_CHR_DEV_SG
14275 #include <scsi/sg.h>
14276 #endif
5eef5607 14277@@ -277,6 +278,13 @@ static int max_extfrag_threshold = 1000;
bb20add7
AM
14278
14279 static struct ctl_table kern_table[] = {
14280 {
4bf69007
AM
14281+ .procname = "vshelper",
14282+ .data = &vshelper_path,
14283+ .maxlen = 256,
14284+ .mode = 0644,
bb20add7 14285+ .proc_handler = proc_dostring,
4bf69007 14286+ },
bb20add7
AM
14287+ {
14288 .procname = "sched_child_runs_first",
14289 .data = &sysctl_sched_child_runs_first,
14290 .maxlen = sizeof(unsigned int),
5eef5607
AM
14291@@ -1342,7 +1350,6 @@ static struct ctl_table vm_table[] = {
14292 .extra1 = &zero,
14293 .extra2 = &one,
bb20add7
AM
14294 },
14295-
14296 #endif /* CONFIG_COMPACTION */
4bf69007 14297 {
bb20add7 14298 .procname = "min_free_kbytes",
f973f73f
AM
14299diff -NurpP --minimal linux-4.1.27/kernel/sysctl_binary.c linux-4.1.27-vs2.3.8.5.2/kernel/sysctl_binary.c
14300--- linux-4.1.27/kernel/sysctl_binary.c 2016-07-05 04:28:32.000000000 +0000
14301+++ linux-4.1.27-vs2.3.8.5.2/kernel/sysctl_binary.c 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 14302@@ -73,6 +73,7 @@ static const struct bin_table bin_kern_t
4bf69007
AM
14303
14304 { CTL_INT, KERN_PANIC, "panic" },
14305 { CTL_INT, KERN_REALROOTDEV, "real-root-dev" },
14306+ { CTL_STR, KERN_VSHELPER, "vshelper" },
14307
14308 { CTL_STR, KERN_SPARC_REBOOT, "reboot-cmd" },
14309 { CTL_INT, KERN_CTLALTDEL, "ctrl-alt-del" },
f973f73f
AM
14310diff -NurpP --minimal linux-4.1.27/kernel/time/posix-timers.c linux-4.1.27-vs2.3.8.5.2/kernel/time/posix-timers.c
14311--- linux-4.1.27/kernel/time/posix-timers.c 2015-04-12 22:12:50.000000000 +0000
14312+++ linux-4.1.27-vs2.3.8.5.2/kernel/time/posix-timers.c 2016-07-05 04:41:47.000000000 +0000
bb20add7
AM
14313@@ -48,6 +48,7 @@
14314 #include <linux/workqueue.h>
14315 #include <linux/export.h>
14316 #include <linux/hashtable.h>
14317+#include <linux/vs_context.h>
4bf69007 14318
bb20add7 14319 #include "timekeeping.h"
4bf69007 14320
bb20add7
AM
14321@@ -400,6 +401,7 @@ int posix_timer_event(struct k_itimer *t
14322 {
14323 struct task_struct *task;
14324 int shared, ret = -1;
14325+
14326 /*
14327 * FIXME: if ->sigq is queued we can race with
14328 * dequeue_signal()->do_schedule_next_timer().
14329@@ -416,10 +418,18 @@ int posix_timer_event(struct k_itimer *t
14330 rcu_read_lock();
14331 task = pid_task(timr->it_pid, PIDTYPE_PID);
14332 if (task) {
14333+ struct vx_info_save vxis;
14334+ struct vx_info *vxi;
14335+
14336+ vxi = get_vx_info(task->vx_info);
14337+ enter_vx_info(vxi, &vxis);
14338 shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID);
14339 ret = send_sigqueue(timr->sigq, task, shared);
14340+ leave_vx_info(&vxis);
14341+ put_vx_info(vxi);
14342 }
14343 rcu_read_unlock();
14344+
14345 /* If we failed to send the signal the timer stops. */
14346 return ret > 0;
4bf69007 14347 }
f973f73f
AM
14348diff -NurpP --minimal linux-4.1.27/kernel/time/time.c linux-4.1.27-vs2.3.8.5.2/kernel/time/time.c
14349--- linux-4.1.27/kernel/time/time.c 2015-04-12 22:12:50.000000000 +0000
14350+++ linux-4.1.27-vs2.3.8.5.2/kernel/time/time.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
14351@@ -37,6 +37,7 @@
14352 #include <linux/fs.h>
14353 #include <linux/math64.h>
14354 #include <linux/ptrace.h>
14355+#include <linux/vs_time.h>
14356
14357 #include <asm/uaccess.h>
14358 #include <asm/unistd.h>
bb20add7 14359@@ -93,7 +94,7 @@ SYSCALL_DEFINE1(stime, time_t __user *,
4bf69007
AM
14360 if (err)
14361 return err;
14362
14363- do_settimeofday(&tv);
14364+ vx_settimeofday(&tv);
14365 return 0;
14366 }
14367
bb20add7 14368@@ -182,7 +183,7 @@ int do_sys_settimeofday(const struct tim
4bf69007
AM
14369 }
14370 }
14371 if (tv)
14372- return do_settimeofday(tv);
14373+ return vx_settimeofday(tv);
14374 return 0;
14375 }
14376
f973f73f
AM
14377diff -NurpP --minimal linux-4.1.27/kernel/time/timekeeping.c linux-4.1.27-vs2.3.8.5.2/kernel/time/timekeeping.c
14378--- linux-4.1.27/kernel/time/timekeeping.c 2016-07-05 04:28:32.000000000 +0000
14379+++ linux-4.1.27-vs2.3.8.5.2/kernel/time/timekeeping.c 2016-07-05 04:41:47.000000000 +0000
bb20add7
AM
14380@@ -23,6 +23,7 @@
14381 #include <linux/stop_machine.h>
14382 #include <linux/pvclock_gtod.h>
14383 #include <linux/compiler.h>
14384+#include <linux/vs_time.h>
14385
14386 #include "tick-internal.h"
14387 #include "ntp_internal.h"
9e3e8383 14388@@ -877,7 +878,9 @@ void getnstime_raw_and_real(struct times
bb20add7
AM
14389 } while (read_seqcount_retry(&tk_core.seq, seq));
14390
14391 timespec_add_ns(ts_raw, nsecs_raw);
14392+ vx_adjust_timespec(ts_raw);
14393 timespec_add_ns(ts_real, nsecs_real);
14394+ vx_adjust_timespec(ts_real);
14395 }
14396 EXPORT_SYMBOL(getnstime_raw_and_real);
14397
f973f73f
AM
14398diff -NurpP --minimal linux-4.1.27/kernel/time/timer.c linux-4.1.27-vs2.3.8.5.2/kernel/time/timer.c
14399--- linux-4.1.27/kernel/time/timer.c 2015-07-06 20:41:43.000000000 +0000
14400+++ linux-4.1.27-vs2.3.8.5.2/kernel/time/timer.c 2016-07-05 04:41:47.000000000 +0000
09be7631 14401@@ -42,6 +42,10 @@
b00e13aa 14402 #include <linux/sched/sysctl.h>
4bf69007 14403 #include <linux/slab.h>
09be7631 14404 #include <linux/compat.h>
4bf69007
AM
14405+#include <linux/vs_base.h>
14406+#include <linux/vs_cvirt.h>
14407+#include <linux/vs_pid.h>
14408+#include <linux/vserver/sched.h>
14409
14410 #include <asm/uaccess.h>
14411 #include <asm/unistd.h>
f973f73f
AM
14412diff -NurpP --minimal linux-4.1.27/kernel/user_namespace.c linux-4.1.27-vs2.3.8.5.2/kernel/user_namespace.c
14413--- linux-4.1.27/kernel/user_namespace.c 2015-04-12 22:12:50.000000000 +0000
14414+++ linux-4.1.27-vs2.3.8.5.2/kernel/user_namespace.c 2016-07-05 04:41:47.000000000 +0000
b00e13aa 14415@@ -22,6 +22,7 @@
4bf69007
AM
14416 #include <linux/ctype.h>
14417 #include <linux/projid.h>
b00e13aa 14418 #include <linux/fs_struct.h>
4bf69007
AM
14419+#include <linux/vserver/global.h>
14420
14421 static struct kmem_cache *user_ns_cachep __read_mostly;
bb20add7 14422 static DEFINE_MUTEX(userns_state_mutex);
5eef5607 14423@@ -96,6 +97,7 @@ int create_user_ns(struct cred *new)
4bf69007 14424
b00e13aa
AM
14425 atomic_set(&ns->count, 1);
14426 /* Leave the new->user_ns reference with the new user namespace. */
4bf69007
AM
14427+ atomic_inc(&vs_global_user_ns);
14428 ns->parent = parent_ns;
09be7631 14429 ns->level = parent_ns->level + 1;
4bf69007 14430 ns->owner = owner;
5eef5607
AM
14431@@ -144,6 +146,7 @@ void free_user_ns(struct user_namespace
14432 key_put(ns->persistent_keyring_register);
14433 #endif
14434 ns_free_inum(&ns->ns);
14435+ atomic_dec(&vs_global_user_ns);
14436 kmem_cache_free(user_ns_cachep, ns);
14437 ns = parent;
14438 } while (atomic_dec_and_test(&parent->count));
14439@@ -357,6 +360,18 @@ gid_t from_kgid_munged(struct user_names
bb20add7
AM
14440 }
14441 EXPORT_SYMBOL(from_kgid_munged);
14442
14443+ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
14444+{
14445+ return KTAGT_INIT(tag);
14446+}
14447+EXPORT_SYMBOL(make_ktag);
14448+
14449+vtag_t from_ktag(struct user_namespace *to, ktag_t tag)
14450+{
14451+ return __ktag_val(tag);
14452+}
14453+EXPORT_SYMBOL(from_ktag);
14454+
14455 /**
14456 * make_kprojid - Map a user-namespace projid pair into a kprojid.
14457 * @ns: User namespace that the projid is in
f973f73f
AM
14458diff -NurpP --minimal linux-4.1.27/kernel/utsname.c linux-4.1.27-vs2.3.8.5.2/kernel/utsname.c
14459--- linux-4.1.27/kernel/utsname.c 2015-04-12 22:12:50.000000000 +0000
14460+++ linux-4.1.27-vs2.3.8.5.2/kernel/utsname.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
14461@@ -16,14 +16,17 @@
14462 #include <linux/slab.h>
14463 #include <linux/user_namespace.h>
09be7631 14464 #include <linux/proc_ns.h>
4bf69007
AM
14465+#include <linux/vserver/global.h>
14466
14467 static struct uts_namespace *create_uts_ns(void)
14468 {
14469 struct uts_namespace *uts_ns;
14470
14471 uts_ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL);
14472- if (uts_ns)
14473+ if (uts_ns) {
c2e5f7c8 14474 kref_init(&uts_ns->kref);
4bf69007
AM
14475+ atomic_inc(&vs_global_uts_ns);
14476+ }
14477 return uts_ns;
14478 }
14479
5eef5607 14480@@ -87,6 +90,7 @@ void free_uts_ns(struct kref *kref)
4bf69007
AM
14481 ns = container_of(kref, struct uts_namespace, kref);
14482 put_user_ns(ns->user_ns);
5eef5607 14483 ns_free_inum(&ns->ns);
4bf69007
AM
14484+ atomic_dec(&vs_global_uts_ns);
14485 kfree(ns);
14486 }
14487
f973f73f
AM
14488diff -NurpP --minimal linux-4.1.27/kernel/vserver/Kconfig linux-4.1.27-vs2.3.8.5.2/kernel/vserver/Kconfig
14489--- linux-4.1.27/kernel/vserver/Kconfig 1970-01-01 00:00:00.000000000 +0000
14490+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/Kconfig 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 14491@@ -0,0 +1,230 @@
4bf69007
AM
14492+#
14493+# Linux VServer configuration
14494+#
d337f35e 14495+
4bf69007 14496+menu "Linux VServer"
d337f35e 14497+
4bf69007
AM
14498+config VSERVER_AUTO_LBACK
14499+ bool "Automatically Assign Loopback IP"
14500+ default y
14501+ help
14502+ Automatically assign a guest specific loopback
14503+ IP and add it to the kernel network stack on
14504+ startup.
d337f35e 14505+
4bf69007
AM
14506+config VSERVER_AUTO_SINGLE
14507+ bool "Automatic Single IP Special Casing"
c2e5f7c8 14508+ default n
4bf69007
AM
14509+ help
14510+ This allows network contexts with a single IP to
14511+ automatically remap 0.0.0.0 bindings to that IP,
14512+ avoiding further network checks and improving
14513+ performance.
d337f35e 14514+
4bf69007
AM
14515+ (note: such guests do not allow to change the ip
14516+ on the fly and do not show loopback addresses)
2380c486 14517+
4bf69007
AM
14518+config VSERVER_COWBL
14519+ bool "Enable COW Immutable Link Breaking"
14520+ default y
14521+ help
14522+ This enables the COW (Copy-On-Write) link break code.
14523+ It allows you to treat unified files like normal files
14524+ when writing to them (which will implicitely break the
14525+ link and create a copy of the unified file)
d337f35e 14526+
4bf69007 14527+config VSERVER_VTIME
c2e5f7c8 14528+ bool "Enable Virtualized Guest Time (EXPERIMENTAL)"
4bf69007
AM
14529+ default n
14530+ help
14531+ This enables per guest time offsets to allow for
14532+ adjusting the system clock individually per guest.
14533+ this adds some overhead to the time functions and
14534+ therefore should not be enabled without good reason.
d337f35e 14535+
4bf69007 14536+config VSERVER_DEVICE
c2e5f7c8 14537+ bool "Enable Guest Device Mapping (EXPERIMENTAL)"
4bf69007
AM
14538+ default n
14539+ help
14540+ This enables generic device remapping.
d337f35e 14541+
4bf69007
AM
14542+config VSERVER_PROC_SECURE
14543+ bool "Enable Proc Security"
14544+ depends on PROC_FS
14545+ default y
14546+ help
14547+ This configures ProcFS security to initially hide
14548+ non-process entries for all contexts except the main and
14549+ spectator context (i.e. for all guests), which is a secure
14550+ default.
d337f35e 14551+
4bf69007 14552+ (note: on 1.2x the entries were visible by default)
d337f35e 14553+
4bf69007
AM
14554+choice
14555+ prompt "Persistent Inode Tagging"
14556+ default TAGGING_ID24
14557+ help
14558+ This adds persistent context information to filesystems
14559+ mounted with the tagxid option. Tagging is a requirement
14560+ for per-context disk limits and per-context quota.
d337f35e 14561+
d337f35e 14562+
4bf69007
AM
14563+config TAGGING_NONE
14564+ bool "Disabled"
14565+ help
14566+ do not store per-context information in inodes.
d337f35e 14567+
4bf69007
AM
14568+config TAGGING_UID16
14569+ bool "UID16/GID32"
14570+ help
14571+ reduces UID to 16 bit, but leaves GID at 32 bit.
d337f35e 14572+
4bf69007
AM
14573+config TAGGING_GID16
14574+ bool "UID32/GID16"
14575+ help
14576+ reduces GID to 16 bit, but leaves UID at 32 bit.
d337f35e 14577+
4bf69007
AM
14578+config TAGGING_ID24
14579+ bool "UID24/GID24"
14580+ help
14581+ uses the upper 8bit from UID and GID for XID tagging
14582+ which leaves 24bit for UID/GID each, which should be
14583+ more than sufficient for normal use.
d337f35e 14584+
4bf69007
AM
14585+config TAGGING_INTERN
14586+ bool "UID32/GID32"
14587+ help
14588+ this uses otherwise reserved inode fields in the on
14589+ disk representation, which limits the use to a few
14590+ filesystems (currently ext2 and ext3)
d337f35e 14591+
4bf69007 14592+endchoice
d337f35e 14593+
4bf69007
AM
14594+config TAG_NFSD
14595+ bool "Tag NFSD User Auth and Files"
14596+ default n
14597+ help
14598+ Enable this if you do want the in-kernel NFS
14599+ Server to use the tagging specified above.
14600+ (will require patched clients too)
2380c486 14601+
4bf69007
AM
14602+config VSERVER_PRIVACY
14603+ bool "Honor Privacy Aspects of Guests"
14604+ default n
14605+ help
14606+ When enabled, most context checks will disallow
14607+ access to structures assigned to a specific context,
14608+ like ptys or loop devices.
2380c486 14609+
4bf69007
AM
14610+config VSERVER_CONTEXTS
14611+ int "Maximum number of Contexts (1-65533)" if EMBEDDED
14612+ range 1 65533
14613+ default "768" if 64BIT
14614+ default "256"
14615+ help
14616+ This setting will optimize certain data structures
14617+ and memory allocations according to the expected
14618+ maximum.
2380c486 14619+
4bf69007 14620+ note: this is not a strict upper limit.
2380c486 14621+
4bf69007
AM
14622+config VSERVER_WARN
14623+ bool "VServer Warnings"
14624+ default y
14625+ help
14626+ This enables various runtime warnings, which will
14627+ notify about potential manipulation attempts or
14628+ resource shortage. It is generally considered to
14629+ be a good idea to have that enabled.
2380c486 14630+
4bf69007
AM
14631+config VSERVER_WARN_DEVPTS
14632+ bool "VServer DevPTS Warnings"
14633+ depends on VSERVER_WARN
14634+ default y
14635+ help
14636+ This enables DevPTS related warnings, issued when a
14637+ process inside a context tries to lookup or access
14638+ a dynamic pts from the host or a different context.
d337f35e 14639+
4bf69007
AM
14640+config VSERVER_DEBUG
14641+ bool "VServer Debugging Code"
14642+ default n
14643+ help
14644+ Set this to yes if you want to be able to activate
14645+ debugging output at runtime. It adds a very small
14646+ overhead to all vserver related functions and
14647+ increases the kernel size by about 20k.
d337f35e 14648+
4bf69007
AM
14649+config VSERVER_HISTORY
14650+ bool "VServer History Tracing"
14651+ depends on VSERVER_DEBUG
14652+ default n
14653+ help
14654+ Set this to yes if you want to record the history of
14655+ linux-vserver activities, so they can be replayed in
14656+ the event of a kernel panic or oops.
d337f35e 14657+
4bf69007
AM
14658+config VSERVER_HISTORY_SIZE
14659+ int "Per-CPU History Size (32-65536)"
14660+ depends on VSERVER_HISTORY
14661+ range 32 65536
14662+ default 64
14663+ help
14664+ This allows you to specify the number of entries in
14665+ the per-CPU history buffer.
d337f35e 14666+
4bf69007
AM
14667+config VSERVER_EXTRA_MNT_CHECK
14668+ bool "Extra Checks for Reachability"
14669+ default n
14670+ help
14671+ Set this to yes if you want to do extra checks for
14672+ vfsmount reachability in the proc filesystem code.
14673+ This shouldn't be required on any setup utilizing
14674+ mnt namespaces.
d337f35e 14675+
4bf69007
AM
14676+choice
14677+ prompt "Quotes used in debug and warn messages"
14678+ default QUOTES_ISO8859
d337f35e 14679+
4bf69007
AM
14680+config QUOTES_ISO8859
14681+ bool "Extended ASCII (ISO 8859) angle quotes"
14682+ help
14683+ This uses the extended ASCII characters \xbb
14684+ and \xab for quoting file and process names.
d337f35e 14685+
4bf69007
AM
14686+config QUOTES_UTF8
14687+ bool "UTF-8 angle quotes"
14688+ help
14689+ This uses the the UTF-8 sequences for angle
14690+ quotes to quote file and process names.
d337f35e 14691+
4bf69007
AM
14692+config QUOTES_ASCII
14693+ bool "ASCII single quotes"
14694+ help
14695+ This uses the ASCII single quote character
14696+ (\x27) to quote file and process names.
d337f35e 14697+
4bf69007 14698+endchoice
d337f35e 14699+
4bf69007 14700+endmenu
d337f35e 14701+
d337f35e 14702+
4bf69007
AM
14703+config VSERVER
14704+ bool
14705+ default y
14706+ select NAMESPACES
14707+ select UTS_NS
14708+ select IPC_NS
14709+# select USER_NS
14710+ select SYSVIPC
d337f35e 14711+
4bf69007
AM
14712+config VSERVER_SECURITY
14713+ bool
14714+ depends on SECURITY
14715+ default y
14716+ select SECURITY_CAPABILITIES
d337f35e 14717+
4bf69007
AM
14718+config VSERVER_DISABLED
14719+ bool
14720+ default n
d337f35e 14721+
f973f73f
AM
14722diff -NurpP --minimal linux-4.1.27/kernel/vserver/Makefile linux-4.1.27-vs2.3.8.5.2/kernel/vserver/Makefile
14723--- linux-4.1.27/kernel/vserver/Makefile 1970-01-01 00:00:00.000000000 +0000
14724+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/Makefile 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
14725@@ -0,0 +1,18 @@
14726+#
14727+# Makefile for the Linux vserver routines.
14728+#
d337f35e 14729+
d337f35e 14730+
4bf69007 14731+obj-y += vserver.o
2380c486 14732+
4bf69007
AM
14733+vserver-y := switch.o context.o space.o sched.o network.o inode.o \
14734+ limit.o cvirt.o cacct.o signal.o helper.o init.o \
14735+ dlimit.o tag.o
d337f35e 14736+
4bf69007
AM
14737+vserver-$(CONFIG_INET) += inet.o
14738+vserver-$(CONFIG_PROC_FS) += proc.o
14739+vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o debug.o
14740+vserver-$(CONFIG_VSERVER_HISTORY) += history.o
14741+vserver-$(CONFIG_VSERVER_MONITOR) += monitor.o
14742+vserver-$(CONFIG_VSERVER_DEVICE) += device.o
d337f35e 14743+
f973f73f
AM
14744diff -NurpP --minimal linux-4.1.27/kernel/vserver/cacct.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/cacct.c
14745--- linux-4.1.27/kernel/vserver/cacct.c 1970-01-01 00:00:00.000000000 +0000
14746+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/cacct.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
14747@@ -0,0 +1,42 @@
14748+/*
14749+ * linux/kernel/vserver/cacct.c
14750+ *
14751+ * Virtual Server: Context Accounting
14752+ *
9e3e8383 14753+ * Copyright (C) 2006-2007 Herbert P?tzl
4bf69007
AM
14754+ *
14755+ * V0.01 added accounting stats
14756+ *
14757+ */
d337f35e 14758+
4bf69007
AM
14759+#include <linux/types.h>
14760+#include <linux/vs_context.h>
14761+#include <linux/vserver/cacct_cmd.h>
14762+#include <linux/vserver/cacct_int.h>
d337f35e 14763+
4bf69007
AM
14764+#include <asm/errno.h>
14765+#include <asm/uaccess.h>
14766+
14767+
14768+int vc_sock_stat(struct vx_info *vxi, void __user *data)
d337f35e 14769+{
4bf69007
AM
14770+ struct vcmd_sock_stat_v0 vc_data;
14771+ int j, field;
d337f35e 14772+
2380c486
JR
14773+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
14774+ return -EFAULT;
14775+
4bf69007
AM
14776+ field = vc_data.field;
14777+ if ((field < 0) || (field >= VXA_SOCK_SIZE))
14778+ return -EINVAL;
7e46296a 14779+
4bf69007
AM
14780+ for (j = 0; j < 3; j++) {
14781+ vc_data.count[j] = vx_sock_count(&vxi->cacct, field, j);
14782+ vc_data.total[j] = vx_sock_total(&vxi->cacct, field, j);
14783+ }
7e46296a
AM
14784+
14785+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
14786+ return -EFAULT;
14787+ return 0;
14788+}
14789+
f973f73f
AM
14790diff -NurpP --minimal linux-4.1.27/kernel/vserver/cacct_init.h linux-4.1.27-vs2.3.8.5.2/kernel/vserver/cacct_init.h
14791--- linux-4.1.27/kernel/vserver/cacct_init.h 1970-01-01 00:00:00.000000000 +0000
14792+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/cacct_init.h 2016-07-05 04:41:47.000000000 +0000
4bf69007 14793@@ -0,0 +1,25 @@
7e46296a
AM
14794+
14795+
4bf69007 14796+static inline void vx_info_init_cacct(struct _vx_cacct *cacct)
265d6dcc 14797+{
4bf69007 14798+ int i, j;
265d6dcc 14799+
265d6dcc 14800+
4bf69007
AM
14801+ for (i = 0; i < VXA_SOCK_SIZE; i++) {
14802+ for (j = 0; j < 3; j++) {
14803+ atomic_long_set(&cacct->sock[i][j].count, 0);
14804+ atomic_long_set(&cacct->sock[i][j].total, 0);
14805+ }
14806+ }
14807+ for (i = 0; i < 8; i++)
14808+ atomic_set(&cacct->slab[i], 0);
14809+ for (i = 0; i < 5; i++)
14810+ for (j = 0; j < 4; j++)
14811+ atomic_set(&cacct->page[i][j], 0);
265d6dcc
JR
14812+}
14813+
4bf69007 14814+static inline void vx_info_exit_cacct(struct _vx_cacct *cacct)
265d6dcc 14815+{
4bf69007 14816+ return;
265d6dcc
JR
14817+}
14818+
f973f73f
AM
14819diff -NurpP --minimal linux-4.1.27/kernel/vserver/cacct_proc.h linux-4.1.27-vs2.3.8.5.2/kernel/vserver/cacct_proc.h
14820--- linux-4.1.27/kernel/vserver/cacct_proc.h 1970-01-01 00:00:00.000000000 +0000
14821+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/cacct_proc.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
14822@@ -0,0 +1,53 @@
14823+#ifndef _VX_CACCT_PROC_H
14824+#define _VX_CACCT_PROC_H
265d6dcc 14825+
4bf69007 14826+#include <linux/vserver/cacct_int.h>
d337f35e 14827+
d337f35e 14828+
4bf69007
AM
14829+#define VX_SOCKA_TOP \
14830+ "Type\t recv #/bytes\t\t send #/bytes\t\t fail #/bytes\n"
d337f35e 14831+
4bf69007 14832+static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer)
d337f35e 14833+{
4bf69007
AM
14834+ int i, j, length = 0;
14835+ static char *type[VXA_SOCK_SIZE] = {
14836+ "UNSPEC", "UNIX", "INET", "INET6", "PACKET", "OTHER"
14837+ };
d337f35e 14838+
4bf69007
AM
14839+ length += sprintf(buffer + length, VX_SOCKA_TOP);
14840+ for (i = 0; i < VXA_SOCK_SIZE; i++) {
14841+ length += sprintf(buffer + length, "%s:", type[i]);
14842+ for (j = 0; j < 3; j++) {
14843+ length += sprintf(buffer + length,
14844+ "\t%10lu/%-10lu",
14845+ vx_sock_count(cacct, i, j),
14846+ vx_sock_total(cacct, i, j));
14847+ }
14848+ buffer[length++] = '\n';
14849+ }
d337f35e 14850+
4bf69007
AM
14851+ length += sprintf(buffer + length, "\n");
14852+ length += sprintf(buffer + length,
14853+ "slab:\t %8u %8u %8u %8u\n",
14854+ atomic_read(&cacct->slab[1]),
14855+ atomic_read(&cacct->slab[4]),
14856+ atomic_read(&cacct->slab[0]),
14857+ atomic_read(&cacct->slab[2]));
d337f35e 14858+
4bf69007
AM
14859+ length += sprintf(buffer + length, "\n");
14860+ for (i = 0; i < 5; i++) {
14861+ length += sprintf(buffer + length,
14862+ "page[%d]: %8u %8u %8u %8u\t %8u %8u %8u %8u\n", i,
14863+ atomic_read(&cacct->page[i][0]),
14864+ atomic_read(&cacct->page[i][1]),
14865+ atomic_read(&cacct->page[i][2]),
14866+ atomic_read(&cacct->page[i][3]),
14867+ atomic_read(&cacct->page[i][4]),
14868+ atomic_read(&cacct->page[i][5]),
14869+ atomic_read(&cacct->page[i][6]),
14870+ atomic_read(&cacct->page[i][7]));
14871+ }
14872+ return length;
14873+}
d337f35e 14874+
4bf69007 14875+#endif /* _VX_CACCT_PROC_H */
f973f73f
AM
14876diff -NurpP --minimal linux-4.1.27/kernel/vserver/context.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/context.c
14877--- linux-4.1.27/kernel/vserver/context.c 1970-01-01 00:00:00.000000000 +0000
14878+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/context.c 2016-07-05 04:41:47.000000000 +0000
4bf69007 14879@@ -0,0 +1,1119 @@
2380c486 14880+/*
4bf69007 14881+ * linux/kernel/vserver/context.c
2380c486 14882+ *
4bf69007 14883+ * Virtual Server: Context Support
2380c486 14884+ *
9e3e8383 14885+ * Copyright (C) 2003-2011 Herbert P?tzl
2380c486 14886+ *
4bf69007
AM
14887+ * V0.01 context helper
14888+ * V0.02 vx_ctx_kill syscall command
14889+ * V0.03 replaced context_info calls
14890+ * V0.04 redesign of struct (de)alloc
14891+ * V0.05 rlimit basic implementation
14892+ * V0.06 task_xid and info commands
14893+ * V0.07 context flags and caps
14894+ * V0.08 switch to RCU based hash
14895+ * V0.09 revert to non RCU for now
14896+ * V0.10 and back to working RCU hash
14897+ * V0.11 and back to locking again
14898+ * V0.12 referenced context store
14899+ * V0.13 separate per cpu data
14900+ * V0.14 changed vcmds to vxi arg
14901+ * V0.15 added context stat
14902+ * V0.16 have __create claim() the vxi
14903+ * V0.17 removed older and legacy stuff
14904+ * V0.18 added user credentials
14905+ * V0.19 added warn mask
2380c486
JR
14906+ *
14907+ */
d337f35e 14908+
4bf69007 14909+#include <linux/slab.h>
2380c486 14910+#include <linux/types.h>
4bf69007
AM
14911+#include <linux/security.h>
14912+#include <linux/pid_namespace.h>
14913+#include <linux/capability.h>
1e8b8f9b 14914+
4bf69007
AM
14915+#include <linux/vserver/context.h>
14916+#include <linux/vserver/network.h>
14917+#include <linux/vserver/debug.h>
14918+#include <linux/vserver/limit.h>
14919+#include <linux/vserver/limit_int.h>
14920+#include <linux/vserver/space.h>
14921+#include <linux/init_task.h>
14922+#include <linux/fs_struct.h>
14923+#include <linux/cred.h>
1e8b8f9b 14924+
4bf69007
AM
14925+#include <linux/vs_context.h>
14926+#include <linux/vs_limit.h>
14927+#include <linux/vs_pid.h>
14928+#include <linux/vserver/context_cmd.h>
d337f35e 14929+
4bf69007
AM
14930+#include "cvirt_init.h"
14931+#include "cacct_init.h"
14932+#include "limit_init.h"
14933+#include "sched_init.h"
d337f35e 14934+
d337f35e 14935+
4bf69007
AM
14936+atomic_t vx_global_ctotal = ATOMIC_INIT(0);
14937+atomic_t vx_global_cactive = ATOMIC_INIT(0);
d337f35e 14938+
d337f35e 14939+
4bf69007 14940+/* now inactive context structures */
d337f35e 14941+
4bf69007 14942+static struct hlist_head vx_info_inactive = HLIST_HEAD_INIT;
2380c486 14943+
4bf69007 14944+static DEFINE_SPINLOCK(vx_info_inactive_lock);
d337f35e 14945+
2380c486 14946+
4bf69007 14947+/* __alloc_vx_info()
d337f35e 14948+
4bf69007
AM
14949+ * allocate an initialized vx_info struct
14950+ * doesn't make it visible (hash) */
d337f35e 14951+
61333608 14952+static struct vx_info *__alloc_vx_info(vxid_t xid)
4bf69007
AM
14953+{
14954+ struct vx_info *new = NULL;
14955+ int cpu, index;
d337f35e 14956+
4bf69007 14957+ vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid);
d337f35e 14958+
4bf69007
AM
14959+ /* would this benefit from a slab cache? */
14960+ new = kmalloc(sizeof(struct vx_info), GFP_KERNEL);
14961+ if (!new)
14962+ return 0;
2380c486 14963+
4bf69007
AM
14964+ memset(new, 0, sizeof(struct vx_info));
14965+#ifdef CONFIG_SMP
14966+ new->ptr_pc = alloc_percpu(struct _vx_info_pc);
14967+ if (!new->ptr_pc)
14968+ goto error;
14969+#endif
14970+ new->vx_id = xid;
14971+ INIT_HLIST_NODE(&new->vx_hlist);
14972+ atomic_set(&new->vx_usecnt, 0);
14973+ atomic_set(&new->vx_tasks, 0);
14974+ new->vx_parent = NULL;
14975+ new->vx_state = 0;
14976+ init_waitqueue_head(&new->vx_wait);
2380c486 14977+
4bf69007
AM
14978+ /* prepare reaper */
14979+ get_task_struct(init_pid_ns.child_reaper);
14980+ new->vx_reaper = init_pid_ns.child_reaper;
14981+ new->vx_badness_bias = 0;
d337f35e 14982+
4bf69007
AM
14983+ /* rest of init goes here */
14984+ vx_info_init_limit(&new->limit);
14985+ vx_info_init_sched(&new->sched);
14986+ vx_info_init_cvirt(&new->cvirt);
14987+ vx_info_init_cacct(&new->cacct);
d337f35e 14988+
4bf69007
AM
14989+ /* per cpu data structures */
14990+ for_each_possible_cpu(cpu) {
14991+ vx_info_init_sched_pc(
14992+ &vx_per_cpu(new, sched_pc, cpu), cpu);
14993+ vx_info_init_cvirt_pc(
14994+ &vx_per_cpu(new, cvirt_pc, cpu), cpu);
14995+ }
d337f35e 14996+
4bf69007
AM
14997+ new->vx_flags = VXF_INIT_SET;
14998+ new->vx_bcaps = CAP_FULL_SET; // maybe ~CAP_SETPCAP
14999+ new->vx_ccaps = 0;
15000+ new->vx_umask = 0;
15001+ new->vx_wmask = 0;
d337f35e 15002+
4bf69007
AM
15003+ new->reboot_cmd = 0;
15004+ new->exit_code = 0;
d337f35e 15005+
4bf69007
AM
15006+ // preconfig spaces
15007+ for (index = 0; index < VX_SPACES; index++) {
15008+ struct _vx_space *space = &new->space[index];
d337f35e 15009+
4bf69007
AM
15010+ // filesystem
15011+ spin_lock(&init_fs.lock);
15012+ init_fs.users++;
15013+ spin_unlock(&init_fs.lock);
15014+ space->vx_fs = &init_fs;
2380c486 15015+
4bf69007
AM
15016+ /* FIXME: do we want defaults? */
15017+ // space->vx_real_cred = 0;
15018+ // space->vx_cred = 0;
2380c486 15019+ }
4bf69007
AM
15020+
15021+
15022+ vxdprintk(VXD_CBIT(xid, 0),
15023+ "alloc_vx_info(%d) = %p", xid, new);
15024+ vxh_alloc_vx_info(new);
15025+ atomic_inc(&vx_global_ctotal);
15026+ return new;
15027+#ifdef CONFIG_SMP
15028+error:
15029+ kfree(new);
15030+ return 0;
15031+#endif
d337f35e
JR
15032+}
15033+
4bf69007 15034+/* __dealloc_vx_info()
d337f35e 15035+
4bf69007 15036+ * final disposal of vx_info */
d337f35e 15037+
4bf69007 15038+static void __dealloc_vx_info(struct vx_info *vxi)
d337f35e 15039+{
4bf69007
AM
15040+#ifdef CONFIG_VSERVER_WARN
15041+ struct vx_info_save vxis;
15042+ int cpu;
15043+#endif
15044+ vxdprintk(VXD_CBIT(xid, 0),
15045+ "dealloc_vx_info(%p)", vxi);
15046+ vxh_dealloc_vx_info(vxi);
d337f35e 15047+
4bf69007
AM
15048+#ifdef CONFIG_VSERVER_WARN
15049+ enter_vx_info(vxi, &vxis);
15050+ vx_info_exit_limit(&vxi->limit);
15051+ vx_info_exit_sched(&vxi->sched);
15052+ vx_info_exit_cvirt(&vxi->cvirt);
15053+ vx_info_exit_cacct(&vxi->cacct);
d337f35e 15054+
4bf69007
AM
15055+ for_each_possible_cpu(cpu) {
15056+ vx_info_exit_sched_pc(
15057+ &vx_per_cpu(vxi, sched_pc, cpu), cpu);
15058+ vx_info_exit_cvirt_pc(
15059+ &vx_per_cpu(vxi, cvirt_pc, cpu), cpu);
15060+ }
15061+ leave_vx_info(&vxis);
15062+#endif
d337f35e 15063+
4bf69007
AM
15064+ vxi->vx_id = -1;
15065+ vxi->vx_state |= VXS_RELEASED;
d337f35e 15066+
4bf69007
AM
15067+#ifdef CONFIG_SMP
15068+ free_percpu(vxi->ptr_pc);
15069+#endif
15070+ kfree(vxi);
15071+ atomic_dec(&vx_global_ctotal);
d337f35e
JR
15072+}
15073+
4bf69007 15074+static void __shutdown_vx_info(struct vx_info *vxi)
d337f35e 15075+{
4bf69007
AM
15076+ struct nsproxy *nsproxy;
15077+ struct fs_struct *fs;
15078+ struct cred *cred;
15079+ int index, kill;
d337f35e 15080+
4bf69007 15081+ might_sleep();
d337f35e 15082+
4bf69007
AM
15083+ vxi->vx_state |= VXS_SHUTDOWN;
15084+ vs_state_change(vxi, VSC_SHUTDOWN);
d337f35e 15085+
4bf69007
AM
15086+ for (index = 0; index < VX_SPACES; index++) {
15087+ struct _vx_space *space = &vxi->space[index];
d337f35e 15088+
4bf69007
AM
15089+ nsproxy = xchg(&space->vx_nsproxy, NULL);
15090+ if (nsproxy)
15091+ put_nsproxy(nsproxy);
2380c486 15092+
4bf69007
AM
15093+ fs = xchg(&space->vx_fs, NULL);
15094+ spin_lock(&fs->lock);
15095+ kill = !--fs->users;
15096+ spin_unlock(&fs->lock);
15097+ if (kill)
15098+ free_fs_struct(fs);
d337f35e 15099+
4bf69007
AM
15100+ cred = (struct cred *)xchg(&space->vx_cred, NULL);
15101+ if (cred)
15102+ abort_creds(cred);
15103+ }
d337f35e
JR
15104+}
15105+
4bf69007 15106+/* exported stuff */
d337f35e 15107+
4bf69007 15108+void free_vx_info(struct vx_info *vxi)
d337f35e 15109+{
4bf69007
AM
15110+ unsigned long flags;
15111+ unsigned index;
d337f35e 15112+
4bf69007
AM
15113+ /* check for reference counts first */
15114+ BUG_ON(atomic_read(&vxi->vx_usecnt));
15115+ BUG_ON(atomic_read(&vxi->vx_tasks));
2380c486 15116+
4bf69007
AM
15117+ /* context must not be hashed */
15118+ BUG_ON(vx_info_state(vxi, VXS_HASHED));
d337f35e 15119+
4bf69007
AM
15120+ /* context shutdown is mandatory */
15121+ BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN));
d337f35e 15122+
4bf69007
AM
15123+ /* spaces check */
15124+ for (index = 0; index < VX_SPACES; index++) {
15125+ struct _vx_space *space = &vxi->space[index];
d337f35e 15126+
4bf69007
AM
15127+ BUG_ON(space->vx_nsproxy);
15128+ BUG_ON(space->vx_fs);
15129+ // BUG_ON(space->vx_real_cred);
15130+ // BUG_ON(space->vx_cred);
15131+ }
d337f35e 15132+
4bf69007
AM
15133+ spin_lock_irqsave(&vx_info_inactive_lock, flags);
15134+ hlist_del(&vxi->vx_hlist);
15135+ spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
d337f35e 15136+
4bf69007
AM
15137+ __dealloc_vx_info(vxi);
15138+}
eab5a9a6 15139+
d337f35e 15140+
4bf69007 15141+/* hash table for vx_info hash */
93de0823 15142+
4bf69007 15143+#define VX_HASH_SIZE 13
d337f35e 15144+
4bf69007
AM
15145+static struct hlist_head vx_info_hash[VX_HASH_SIZE] =
15146+ { [0 ... VX_HASH_SIZE-1] = HLIST_HEAD_INIT };
d337f35e 15147+
4bf69007 15148+static DEFINE_SPINLOCK(vx_info_hash_lock);
d337f35e 15149+
93de0823 15150+
61333608 15151+static inline unsigned int __hashval(vxid_t xid)
4bf69007
AM
15152+{
15153+ return (xid % VX_HASH_SIZE);
d337f35e
JR
15154+}
15155+
15156+
d337f35e 15157+
4bf69007 15158+/* __hash_vx_info()
d337f35e 15159+
4bf69007
AM
15160+ * add the vxi to the global hash table
15161+ * requires the hash_lock to be held */
d337f35e 15162+
4bf69007 15163+static inline void __hash_vx_info(struct vx_info *vxi)
d337f35e 15164+{
4bf69007 15165+ struct hlist_head *head;
d337f35e 15166+
4bf69007
AM
15167+ vxd_assert_lock(&vx_info_hash_lock);
15168+ vxdprintk(VXD_CBIT(xid, 4),
15169+ "__hash_vx_info: %p[#%d]", vxi, vxi->vx_id);
15170+ vxh_hash_vx_info(vxi);
d337f35e 15171+
4bf69007
AM
15172+ /* context must not be hashed */
15173+ BUG_ON(vx_info_state(vxi, VXS_HASHED));
d337f35e 15174+
4bf69007
AM
15175+ vxi->vx_state |= VXS_HASHED;
15176+ head = &vx_info_hash[__hashval(vxi->vx_id)];
15177+ hlist_add_head(&vxi->vx_hlist, head);
15178+ atomic_inc(&vx_global_cactive);
2380c486 15179+}
d337f35e 15180+
4bf69007 15181+/* __unhash_vx_info()
d337f35e 15182+
4bf69007
AM
15183+ * remove the vxi from the global hash table
15184+ * requires the hash_lock to be held */
d337f35e 15185+
4bf69007 15186+static inline void __unhash_vx_info(struct vx_info *vxi)
d337f35e 15187+{
4bf69007
AM
15188+ unsigned long flags;
15189+
15190+ vxd_assert_lock(&vx_info_hash_lock);
15191+ vxdprintk(VXD_CBIT(xid, 4),
15192+ "__unhash_vx_info: %p[#%d.%d.%d]", vxi, vxi->vx_id,
15193+ atomic_read(&vxi->vx_usecnt), atomic_read(&vxi->vx_tasks));
15194+ vxh_unhash_vx_info(vxi);
15195+
15196+ /* context must be hashed */
15197+ BUG_ON(!vx_info_state(vxi, VXS_HASHED));
15198+ /* but without tasks */
15199+ BUG_ON(atomic_read(&vxi->vx_tasks));
15200+
15201+ vxi->vx_state &= ~VXS_HASHED;
15202+ hlist_del_init(&vxi->vx_hlist);
15203+ spin_lock_irqsave(&vx_info_inactive_lock, flags);
15204+ hlist_add_head(&vxi->vx_hlist, &vx_info_inactive);
15205+ spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
15206+ atomic_dec(&vx_global_cactive);
2380c486 15207+}
d337f35e 15208+
d337f35e 15209+
4bf69007 15210+/* __lookup_vx_info()
d337f35e 15211+
4bf69007
AM
15212+ * requires the hash_lock to be held
15213+ * doesn't increment the vx_refcnt */
2380c486 15214+
61333608 15215+static inline struct vx_info *__lookup_vx_info(vxid_t xid)
d337f35e 15216+{
4bf69007
AM
15217+ struct hlist_head *head = &vx_info_hash[__hashval(xid)];
15218+ struct hlist_node *pos;
15219+ struct vx_info *vxi;
d337f35e 15220+
4bf69007
AM
15221+ vxd_assert_lock(&vx_info_hash_lock);
15222+ hlist_for_each(pos, head) {
15223+ vxi = hlist_entry(pos, struct vx_info, vx_hlist);
d337f35e 15224+
4bf69007
AM
15225+ if (vxi->vx_id == xid)
15226+ goto found;
15227+ }
15228+ vxi = NULL;
15229+found:
15230+ vxdprintk(VXD_CBIT(xid, 0),
15231+ "__lookup_vx_info(#%u): %p[#%u]",
15232+ xid, vxi, vxi ? vxi->vx_id : 0);
15233+ vxh_lookup_vx_info(vxi, xid);
15234+ return vxi;
15235+}
d337f35e 15236+
d337f35e 15237+
4bf69007 15238+/* __create_vx_info()
d337f35e 15239+
4bf69007
AM
15240+ * create the requested context
15241+ * get(), claim() and hash it */
2380c486 15242+
4bf69007
AM
15243+static struct vx_info *__create_vx_info(int id)
15244+{
15245+ struct vx_info *new, *vxi = NULL;
2380c486 15246+
4bf69007 15247+ vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id);
d337f35e 15248+
4bf69007
AM
15249+ if (!(new = __alloc_vx_info(id)))
15250+ return ERR_PTR(-ENOMEM);
d337f35e 15251+
4bf69007
AM
15252+ /* required to make dynamic xids unique */
15253+ spin_lock(&vx_info_hash_lock);
d337f35e 15254+
4bf69007
AM
15255+ /* static context requested */
15256+ if ((vxi = __lookup_vx_info(id))) {
15257+ vxdprintk(VXD_CBIT(xid, 0),
15258+ "create_vx_info(%d) = %p (already there)", id, vxi);
15259+ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0))
15260+ vxi = ERR_PTR(-EBUSY);
15261+ else
15262+ vxi = ERR_PTR(-EEXIST);
15263+ goto out_unlock;
15264+ }
15265+ /* new context */
15266+ vxdprintk(VXD_CBIT(xid, 0),
15267+ "create_vx_info(%d) = %p (new)", id, new);
15268+ claim_vx_info(new, NULL);
15269+ __hash_vx_info(get_vx_info(new));
15270+ vxi = new, new = NULL;
d337f35e 15271+
4bf69007
AM
15272+out_unlock:
15273+ spin_unlock(&vx_info_hash_lock);
15274+ vxh_create_vx_info(IS_ERR(vxi) ? NULL : vxi, id);
15275+ if (new)
15276+ __dealloc_vx_info(new);
15277+ return vxi;
15278+}
d337f35e 15279+
d337f35e 15280+
4bf69007 15281+/* exported stuff */
d337f35e 15282+
d337f35e 15283+
4bf69007 15284+void unhash_vx_info(struct vx_info *vxi)
d337f35e 15285+{
4bf69007
AM
15286+ spin_lock(&vx_info_hash_lock);
15287+ __unhash_vx_info(vxi);
15288+ spin_unlock(&vx_info_hash_lock);
15289+ __shutdown_vx_info(vxi);
15290+ __wakeup_vx_info(vxi);
2380c486 15291+}
d337f35e 15292+
2380c486 15293+
4bf69007 15294+/* lookup_vx_info()
2380c486 15295+
4bf69007
AM
15296+ * search for a vx_info and get() it
15297+ * negative id means current */
2380c486 15298+
4bf69007 15299+struct vx_info *lookup_vx_info(int id)
2380c486 15300+{
4bf69007
AM
15301+ struct vx_info *vxi = NULL;
15302+
15303+ if (id < 0) {
15304+ vxi = get_vx_info(current_vx_info());
15305+ } else if (id > 1) {
15306+ spin_lock(&vx_info_hash_lock);
15307+ vxi = get_vx_info(__lookup_vx_info(id));
15308+ spin_unlock(&vx_info_hash_lock);
2380c486 15309+ }
4bf69007 15310+ return vxi;
d337f35e
JR
15311+}
15312+
4bf69007 15313+/* xid_is_hashed()
d337f35e 15314+
4bf69007 15315+ * verify that xid is still hashed */
d337f35e 15316+
61333608 15317+int xid_is_hashed(vxid_t xid)
4bf69007
AM
15318+{
15319+ int hashed;
d337f35e 15320+
4bf69007
AM
15321+ spin_lock(&vx_info_hash_lock);
15322+ hashed = (__lookup_vx_info(xid) != NULL);
15323+ spin_unlock(&vx_info_hash_lock);
15324+ return hashed;
15325+}
d337f35e 15326+
4bf69007 15327+#ifdef CONFIG_PROC_FS
d337f35e 15328+
4bf69007 15329+/* get_xid_list()
d337f35e 15330+
4bf69007
AM
15331+ * get a subset of hashed xids for proc
15332+ * assumes size is at least one */
d337f35e 15333+
4bf69007
AM
15334+int get_xid_list(int index, unsigned int *xids, int size)
15335+{
15336+ int hindex, nr_xids = 0;
d337f35e 15337+
4bf69007
AM
15338+ /* only show current and children */
15339+ if (!vx_check(0, VS_ADMIN | VS_WATCH)) {
15340+ if (index > 0)
15341+ return 0;
15342+ xids[nr_xids] = vx_current_xid();
15343+ return 1;
15344+ }
d337f35e 15345+
4bf69007
AM
15346+ for (hindex = 0; hindex < VX_HASH_SIZE; hindex++) {
15347+ struct hlist_head *head = &vx_info_hash[hindex];
15348+ struct hlist_node *pos;
d337f35e 15349+
4bf69007
AM
15350+ spin_lock(&vx_info_hash_lock);
15351+ hlist_for_each(pos, head) {
15352+ struct vx_info *vxi;
d337f35e 15353+
4bf69007
AM
15354+ if (--index > 0)
15355+ continue;
d337f35e 15356+
4bf69007
AM
15357+ vxi = hlist_entry(pos, struct vx_info, vx_hlist);
15358+ xids[nr_xids] = vxi->vx_id;
15359+ if (++nr_xids >= size) {
15360+ spin_unlock(&vx_info_hash_lock);
15361+ goto out;
15362+ }
15363+ }
15364+ /* keep the lock time short */
15365+ spin_unlock(&vx_info_hash_lock);
15366+ }
15367+out:
15368+ return nr_xids;
15369+}
15370+#endif
d337f35e 15371+
4bf69007 15372+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 15373+
4bf69007 15374+void dump_vx_info_inactive(int level)
d337f35e 15375+{
4bf69007 15376+ struct hlist_node *entry, *next;
d337f35e 15377+
4bf69007
AM
15378+ hlist_for_each_safe(entry, next, &vx_info_inactive) {
15379+ struct vx_info *vxi =
15380+ list_entry(entry, struct vx_info, vx_hlist);
d337f35e 15381+
4bf69007
AM
15382+ dump_vx_info(vxi, level);
15383+ }
d337f35e
JR
15384+}
15385+
4bf69007 15386+#endif
d337f35e 15387+
4bf69007
AM
15388+#if 0
15389+int vx_migrate_user(struct task_struct *p, struct vx_info *vxi)
d337f35e 15390+{
4bf69007 15391+ struct user_struct *new_user, *old_user;
d337f35e 15392+
4bf69007
AM
15393+ if (!p || !vxi)
15394+ BUG();
d337f35e 15395+
4bf69007
AM
15396+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
15397+ return -EACCES;
d337f35e 15398+
4bf69007
AM
15399+ new_user = alloc_uid(vxi->vx_id, p->uid);
15400+ if (!new_user)
15401+ return -ENOMEM;
d337f35e 15402+
4bf69007
AM
15403+ old_user = p->user;
15404+ if (new_user != old_user) {
15405+ atomic_inc(&new_user->processes);
15406+ atomic_dec(&old_user->processes);
15407+ p->user = new_user;
d337f35e 15408+ }
4bf69007
AM
15409+ free_uid(old_user);
15410+ return 0;
d337f35e 15411+}
4bf69007 15412+#endif
d337f35e 15413+
4bf69007
AM
15414+#if 0
15415+void vx_mask_cap_bset(struct vx_info *vxi, struct task_struct *p)
d337f35e 15416+{
4bf69007
AM
15417+ // p->cap_effective &= vxi->vx_cap_bset;
15418+ p->cap_effective =
15419+ cap_intersect(p->cap_effective, vxi->cap_bset);
15420+ // p->cap_inheritable &= vxi->vx_cap_bset;
15421+ p->cap_inheritable =
15422+ cap_intersect(p->cap_inheritable, vxi->cap_bset);
15423+ // p->cap_permitted &= vxi->vx_cap_bset;
15424+ p->cap_permitted =
15425+ cap_intersect(p->cap_permitted, vxi->cap_bset);
15426+}
15427+#endif
d337f35e
JR
15428+
15429+
4bf69007
AM
15430+#include <linux/file.h>
15431+#include <linux/fdtable.h>
d337f35e 15432+
4bf69007
AM
15433+static int vx_openfd_task(struct task_struct *tsk)
15434+{
15435+ struct files_struct *files = tsk->files;
15436+ struct fdtable *fdt;
15437+ const unsigned long *bptr;
15438+ int count, total;
d337f35e 15439+
4bf69007
AM
15440+ /* no rcu_read_lock() because of spin_lock() */
15441+ spin_lock(&files->file_lock);
15442+ fdt = files_fdtable(files);
15443+ bptr = fdt->open_fds;
15444+ count = fdt->max_fds / (sizeof(unsigned long) * 8);
15445+ for (total = 0; count > 0; count--) {
15446+ if (*bptr)
15447+ total += hweight_long(*bptr);
15448+ bptr++;
15449+ }
15450+ spin_unlock(&files->file_lock);
15451+ return total;
d337f35e
JR
15452+}
15453+
d337f35e 15454+
4bf69007
AM
15455+/* for *space compatibility */
15456+
15457+asmlinkage long sys_unshare(unsigned long);
15458+
15459+/*
15460+ * migrate task to new context
15461+ * gets vxi, puts old_vxi on change
15462+ * optionally unshares namespaces (hack)
2380c486 15463+ */
4bf69007
AM
15464+
15465+int vx_migrate_task(struct task_struct *p, struct vx_info *vxi, int unshare)
2380c486 15466+{
4bf69007
AM
15467+ struct vx_info *old_vxi;
15468+ int ret = 0;
d337f35e 15469+
4bf69007
AM
15470+ if (!p || !vxi)
15471+ BUG();
d337f35e 15472+
4bf69007
AM
15473+ vxdprintk(VXD_CBIT(xid, 5),
15474+ "vx_migrate_task(%p,%p[#%d.%d])", p, vxi,
15475+ vxi->vx_id, atomic_read(&vxi->vx_usecnt));
d337f35e 15476+
4bf69007
AM
15477+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0) &&
15478+ !vx_info_flags(vxi, VXF_STATE_SETUP, 0))
15479+ return -EACCES;
2380c486 15480+
4bf69007
AM
15481+ if (vx_info_state(vxi, VXS_SHUTDOWN))
15482+ return -EFAULT;
d337f35e 15483+
4bf69007
AM
15484+ old_vxi = task_get_vx_info(p);
15485+ if (old_vxi == vxi)
15486+ goto out;
d337f35e 15487+
4bf69007
AM
15488+// if (!(ret = vx_migrate_user(p, vxi))) {
15489+ {
15490+ int openfd;
d337f35e 15491+
4bf69007
AM
15492+ task_lock(p);
15493+ openfd = vx_openfd_task(p);
15494+
15495+ if (old_vxi) {
15496+ atomic_dec(&old_vxi->cvirt.nr_threads);
15497+ atomic_dec(&old_vxi->cvirt.nr_running);
15498+ __rlim_dec(&old_vxi->limit, RLIMIT_NPROC);
15499+ /* FIXME: what about the struct files here? */
15500+ __rlim_sub(&old_vxi->limit, VLIMIT_OPENFD, openfd);
15501+ /* account for the executable */
15502+ __rlim_dec(&old_vxi->limit, VLIMIT_DENTRY);
2380c486 15503+ }
4bf69007
AM
15504+ atomic_inc(&vxi->cvirt.nr_threads);
15505+ atomic_inc(&vxi->cvirt.nr_running);
15506+ __rlim_inc(&vxi->limit, RLIMIT_NPROC);
15507+ /* FIXME: what about the struct files here? */
15508+ __rlim_add(&vxi->limit, VLIMIT_OPENFD, openfd);
15509+ /* account for the executable */
15510+ __rlim_inc(&vxi->limit, VLIMIT_DENTRY);
2380c486 15511+
4bf69007
AM
15512+ if (old_vxi) {
15513+ release_vx_info(old_vxi, p);
15514+ clr_vx_info(&p->vx_info);
15515+ }
15516+ claim_vx_info(vxi, p);
15517+ set_vx_info(&p->vx_info, vxi);
15518+ p->xid = vxi->vx_id;
d337f35e 15519+
4bf69007
AM
15520+ vxdprintk(VXD_CBIT(xid, 5),
15521+ "moved task %p into vxi:%p[#%d]",
15522+ p, vxi, vxi->vx_id);
d337f35e 15523+
4bf69007
AM
15524+ // vx_mask_cap_bset(vxi, p);
15525+ task_unlock(p);
d337f35e 15526+
4bf69007
AM
15527+ /* hack for *spaces to provide compatibility */
15528+ if (unshare) {
15529+ struct nsproxy *old_nsp, *new_nsp;
d337f35e 15530+
4bf69007
AM
15531+ ret = unshare_nsproxy_namespaces(
15532+ CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER,
b00e13aa 15533+ &new_nsp, NULL, NULL);
4bf69007
AM
15534+ if (ret)
15535+ goto out;
d337f35e 15536+
4bf69007
AM
15537+ old_nsp = xchg(&p->nsproxy, new_nsp);
15538+ vx_set_space(vxi,
15539+ CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER, 0);
15540+ put_nsproxy(old_nsp);
15541+ }
15542+ }
15543+out:
15544+ put_vx_info(old_vxi);
2380c486
JR
15545+ return ret;
15546+}
d337f35e 15547+
4bf69007 15548+int vx_set_reaper(struct vx_info *vxi, struct task_struct *p)
d337f35e 15549+{
4bf69007
AM
15550+ struct task_struct *old_reaper;
15551+ struct vx_info *reaper_vxi;
d337f35e 15552+
4bf69007
AM
15553+ if (!vxi)
15554+ return -EINVAL;
d337f35e 15555+
4bf69007
AM
15556+ vxdprintk(VXD_CBIT(xid, 6),
15557+ "vx_set_reaper(%p[#%d],%p[#%d,%d])",
15558+ vxi, vxi->vx_id, p, p->xid, p->pid);
d337f35e 15559+
4bf69007
AM
15560+ old_reaper = vxi->vx_reaper;
15561+ if (old_reaper == p)
15562+ return 0;
d337f35e 15563+
4bf69007
AM
15564+ reaper_vxi = task_get_vx_info(p);
15565+ if (reaper_vxi && reaper_vxi != vxi) {
15566+ vxwprintk(1,
15567+ "Unsuitable reaper [" VS_Q("%s") ",%u:#%u] "
15568+ "for [xid #%u]",
15569+ p->comm, p->pid, p->xid, vx_current_xid());
2380c486
JR
15570+ goto out;
15571+ }
4bf69007
AM
15572+
15573+ /* set new child reaper */
15574+ get_task_struct(p);
15575+ vxi->vx_reaper = p;
15576+ put_task_struct(old_reaper);
2380c486 15577+out:
4bf69007
AM
15578+ put_vx_info(reaper_vxi);
15579+ return 0;
2380c486 15580+}
d337f35e 15581+
4bf69007 15582+int vx_set_init(struct vx_info *vxi, struct task_struct *p)
d337f35e 15583+{
4bf69007
AM
15584+ if (!vxi)
15585+ return -EINVAL;
d337f35e 15586+
4bf69007
AM
15587+ vxdprintk(VXD_CBIT(xid, 6),
15588+ "vx_set_init(%p[#%d],%p[#%d,%d,%d])",
15589+ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
d337f35e 15590+
4bf69007
AM
15591+ vxi->vx_flags &= ~VXF_STATE_INIT;
15592+ // vxi->vx_initpid = p->tgid;
15593+ vxi->vx_initpid = p->pid;
2380c486 15594+ return 0;
d337f35e
JR
15595+}
15596+
4bf69007 15597+void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code)
d337f35e 15598+{
4bf69007
AM
15599+ vxdprintk(VXD_CBIT(xid, 6),
15600+ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])",
15601+ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
2380c486 15602+
4bf69007
AM
15603+ vxi->exit_code = code;
15604+ vxi->vx_initpid = 0;
d337f35e
JR
15605+}
15606+
2380c486 15607+
4bf69007 15608+void vx_set_persistent(struct vx_info *vxi)
d337f35e 15609+{
4bf69007
AM
15610+ vxdprintk(VXD_CBIT(xid, 6),
15611+ "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id);
2380c486 15612+
4bf69007
AM
15613+ get_vx_info(vxi);
15614+ claim_vx_info(vxi, NULL);
d337f35e
JR
15615+}
15616+
4bf69007 15617+void vx_clear_persistent(struct vx_info *vxi)
2380c486 15618+{
4bf69007
AM
15619+ vxdprintk(VXD_CBIT(xid, 6),
15620+ "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id);
d337f35e 15621+
4bf69007
AM
15622+ release_vx_info(vxi, NULL);
15623+ put_vx_info(vxi);
2380c486 15624+}
d337f35e 15625+
4bf69007 15626+void vx_update_persistent(struct vx_info *vxi)
d337f35e 15627+{
4bf69007
AM
15628+ if (vx_info_flags(vxi, VXF_PERSISTENT, 0))
15629+ vx_set_persistent(vxi);
2380c486 15630+ else
4bf69007 15631+ vx_clear_persistent(vxi);
2380c486 15632+}
d337f35e 15633+
d337f35e 15634+
4bf69007
AM
15635+/* task must be current or locked */
15636+
15637+void exit_vx_info(struct task_struct *p, int code)
2380c486 15638+{
4bf69007 15639+ struct vx_info *vxi = p->vx_info;
d337f35e 15640+
4bf69007
AM
15641+ if (vxi) {
15642+ atomic_dec(&vxi->cvirt.nr_threads);
15643+ vx_nproc_dec(p);
d337f35e 15644+
4bf69007
AM
15645+ vxi->exit_code = code;
15646+ release_vx_info(vxi, p);
15647+ }
2380c486 15648+}
d337f35e 15649+
4bf69007 15650+void exit_vx_info_early(struct task_struct *p, int code)
2380c486 15651+{
4bf69007 15652+ struct vx_info *vxi = p->vx_info;
d337f35e 15653+
4bf69007
AM
15654+ if (vxi) {
15655+ if (vxi->vx_initpid == p->pid)
15656+ vx_exit_init(vxi, p, code);
15657+ if (vxi->vx_reaper == p)
15658+ vx_set_reaper(vxi, init_pid_ns.child_reaper);
15659+ }
d337f35e
JR
15660+}
15661+
15662+
4bf69007 15663+/* vserver syscall commands below here */
d337f35e 15664+
4bf69007 15665+/* taks xid and vx_info functions */
d337f35e 15666+
4bf69007 15667+#include <asm/uaccess.h>
d337f35e 15668+
d337f35e 15669+
4bf69007 15670+int vc_task_xid(uint32_t id)
d337f35e 15671+{
61333608 15672+ vxid_t xid;
d337f35e 15673+
4bf69007
AM
15674+ if (id) {
15675+ struct task_struct *tsk;
d337f35e 15676+
4bf69007
AM
15677+ rcu_read_lock();
15678+ tsk = find_task_by_real_pid(id);
15679+ xid = (tsk) ? tsk->xid : -ESRCH;
15680+ rcu_read_unlock();
15681+ } else
15682+ xid = vx_current_xid();
15683+ return xid;
d337f35e
JR
15684+}
15685+
d337f35e 15686+
4bf69007
AM
15687+int vc_vx_info(struct vx_info *vxi, void __user *data)
15688+{
15689+ struct vcmd_vx_info_v0 vc_data;
d337f35e 15690+
4bf69007
AM
15691+ vc_data.xid = vxi->vx_id;
15692+ vc_data.initpid = vxi->vx_initpid;
d337f35e 15693+
4bf69007
AM
15694+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15695+ return -EFAULT;
15696+ return 0;
15697+}
d337f35e 15698+
d337f35e 15699+
4bf69007 15700+int vc_ctx_stat(struct vx_info *vxi, void __user *data)
d337f35e 15701+{
4bf69007 15702+ struct vcmd_ctx_stat_v0 vc_data;
d337f35e 15703+
4bf69007
AM
15704+ vc_data.usecnt = atomic_read(&vxi->vx_usecnt);
15705+ vc_data.tasks = atomic_read(&vxi->vx_tasks);
d337f35e 15706+
4bf69007
AM
15707+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15708+ return -EFAULT;
15709+ return 0;
d337f35e
JR
15710+}
15711+
d337f35e 15712+
4bf69007 15713+/* context functions */
d337f35e 15714+
4bf69007 15715+int vc_ctx_create(uint32_t xid, void __user *data)
d337f35e 15716+{
4bf69007
AM
15717+ struct vcmd_ctx_create vc_data = { .flagword = VXF_INIT_SET };
15718+ struct vx_info *new_vxi;
15719+ int ret;
d337f35e 15720+
4bf69007
AM
15721+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
15722+ return -EFAULT;
d337f35e 15723+
4bf69007
AM
15724+ if ((xid > MAX_S_CONTEXT) || (xid < 2))
15725+ return -EINVAL;
d337f35e 15726+
4bf69007
AM
15727+ new_vxi = __create_vx_info(xid);
15728+ if (IS_ERR(new_vxi))
15729+ return PTR_ERR(new_vxi);
d337f35e 15730+
4bf69007
AM
15731+ /* initial flags */
15732+ new_vxi->vx_flags = vc_data.flagword;
d337f35e 15733+
4bf69007
AM
15734+ ret = -ENOEXEC;
15735+ if (vs_state_change(new_vxi, VSC_STARTUP))
15736+ goto out;
d337f35e 15737+
4bf69007
AM
15738+ ret = vx_migrate_task(current, new_vxi, (!data));
15739+ if (ret)
15740+ goto out;
d337f35e 15741+
4bf69007
AM
15742+ /* return context id on success */
15743+ ret = new_vxi->vx_id;
d337f35e 15744+
4bf69007
AM
15745+ /* get a reference for persistent contexts */
15746+ if ((vc_data.flagword & VXF_PERSISTENT))
15747+ vx_set_persistent(new_vxi);
15748+out:
15749+ release_vx_info(new_vxi, NULL);
15750+ put_vx_info(new_vxi);
15751+ return ret;
15752+}
d337f35e
JR
15753+
15754+
4bf69007 15755+int vc_ctx_migrate(struct vx_info *vxi, void __user *data)
d337f35e 15756+{
4bf69007
AM
15757+ struct vcmd_ctx_migrate vc_data = { .flagword = 0 };
15758+ int ret;
d337f35e 15759+
4bf69007
AM
15760+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
15761+ return -EFAULT;
d337f35e 15762+
4bf69007
AM
15763+ ret = vx_migrate_task(current, vxi, 0);
15764+ if (ret)
15765+ return ret;
15766+ if (vc_data.flagword & VXM_SET_INIT)
15767+ ret = vx_set_init(vxi, current);
15768+ if (ret)
15769+ return ret;
15770+ if (vc_data.flagword & VXM_SET_REAPER)
15771+ ret = vx_set_reaper(vxi, current);
15772+ return ret;
15773+}
d337f35e 15774+
d337f35e 15775+
4bf69007 15776+int vc_get_cflags(struct vx_info *vxi, void __user *data)
d337f35e 15777+{
4bf69007 15778+ struct vcmd_ctx_flags_v0 vc_data;
d337f35e 15779+
4bf69007 15780+ vc_data.flagword = vxi->vx_flags;
d337f35e 15781+
4bf69007
AM
15782+ /* special STATE flag handling */
15783+ vc_data.mask = vs_mask_flags(~0ULL, vxi->vx_flags, VXF_ONE_TIME);
d337f35e 15784+
4bf69007
AM
15785+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15786+ return -EFAULT;
15787+ return 0;
d337f35e
JR
15788+}
15789+
4bf69007
AM
15790+int vc_set_cflags(struct vx_info *vxi, void __user *data)
15791+{
15792+ struct vcmd_ctx_flags_v0 vc_data;
15793+ uint64_t mask, trigger;
d337f35e 15794+
4bf69007
AM
15795+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15796+ return -EFAULT;
d337f35e 15797+
4bf69007
AM
15798+ /* special STATE flag handling */
15799+ mask = vs_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME);
15800+ trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword);
d337f35e 15801+
4bf69007
AM
15802+ if (vxi == current_vx_info()) {
15803+ /* if (trigger & VXF_STATE_SETUP)
15804+ vx_mask_cap_bset(vxi, current); */
15805+ if (trigger & VXF_STATE_INIT) {
15806+ int ret;
d337f35e 15807+
4bf69007
AM
15808+ ret = vx_set_init(vxi, current);
15809+ if (ret)
15810+ return ret;
15811+ ret = vx_set_reaper(vxi, current);
15812+ if (ret)
15813+ return ret;
d337f35e
JR
15814+ }
15815+ }
4bf69007
AM
15816+
15817+ vxi->vx_flags = vs_mask_flags(vxi->vx_flags,
15818+ vc_data.flagword, mask);
15819+ if (trigger & VXF_PERSISTENT)
15820+ vx_update_persistent(vxi);
15821+
15822+ return 0;
d337f35e
JR
15823+}
15824+
15825+
4bf69007 15826+static inline uint64_t caps_from_cap_t(kernel_cap_t c)
d337f35e 15827+{
4bf69007 15828+ uint64_t v = c.cap[0] | ((uint64_t)c.cap[1] << 32);
d337f35e 15829+
4bf69007
AM
15830+ // printk("caps_from_cap_t(%08x:%08x) = %016llx\n", c.cap[1], c.cap[0], v);
15831+ return v;
d337f35e
JR
15832+}
15833+
4bf69007 15834+static inline kernel_cap_t cap_t_from_caps(uint64_t v)
d337f35e 15835+{
4bf69007 15836+ kernel_cap_t c = __cap_empty_set;
d337f35e 15837+
4bf69007
AM
15838+ c.cap[0] = v & 0xFFFFFFFF;
15839+ c.cap[1] = (v >> 32) & 0xFFFFFFFF;
d337f35e 15840+
4bf69007
AM
15841+ // printk("cap_t_from_caps(%016llx) = %08x:%08x\n", v, c.cap[1], c.cap[0]);
15842+ return c;
d337f35e
JR
15843+}
15844+
15845+
4bf69007 15846+static int do_get_caps(struct vx_info *vxi, uint64_t *bcaps, uint64_t *ccaps)
d337f35e 15847+{
4bf69007
AM
15848+ if (bcaps)
15849+ *bcaps = caps_from_cap_t(vxi->vx_bcaps);
15850+ if (ccaps)
15851+ *ccaps = vxi->vx_ccaps;
d337f35e 15852+
4bf69007
AM
15853+ return 0;
15854+}
d337f35e 15855+
4bf69007
AM
15856+int vc_get_ccaps(struct vx_info *vxi, void __user *data)
15857+{
15858+ struct vcmd_ctx_caps_v1 vc_data;
15859+ int ret;
d337f35e 15860+
4bf69007
AM
15861+ ret = do_get_caps(vxi, NULL, &vc_data.ccaps);
15862+ if (ret)
15863+ return ret;
15864+ vc_data.cmask = ~0ULL;
d337f35e 15865+
4bf69007
AM
15866+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15867+ return -EFAULT;
15868+ return 0;
d337f35e
JR
15869+}
15870+
4bf69007
AM
15871+static int do_set_caps(struct vx_info *vxi,
15872+ uint64_t bcaps, uint64_t bmask, uint64_t ccaps, uint64_t cmask)
d337f35e 15873+{
4bf69007 15874+ uint64_t bcold = caps_from_cap_t(vxi->vx_bcaps);
d337f35e 15875+
4bf69007
AM
15876+#if 0
15877+ printk("do_set_caps(%16llx, %16llx, %16llx, %16llx)\n",
15878+ bcaps, bmask, ccaps, cmask);
15879+#endif
15880+ vxi->vx_bcaps = cap_t_from_caps(
15881+ vs_mask_flags(bcold, bcaps, bmask));
15882+ vxi->vx_ccaps = vs_mask_flags(vxi->vx_ccaps, ccaps, cmask);
d337f35e 15883+
4bf69007 15884+ return 0;
d337f35e
JR
15885+}
15886+
4bf69007 15887+int vc_set_ccaps(struct vx_info *vxi, void __user *data)
d337f35e 15888+{
4bf69007 15889+ struct vcmd_ctx_caps_v1 vc_data;
d337f35e 15890+
2380c486 15891+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15892+ return -EFAULT;
15893+
4bf69007 15894+ return do_set_caps(vxi, 0, 0, vc_data.ccaps, vc_data.cmask);
d337f35e
JR
15895+}
15896+
4bf69007 15897+int vc_get_bcaps(struct vx_info *vxi, void __user *data)
d337f35e 15898+{
4bf69007
AM
15899+ struct vcmd_bcaps vc_data;
15900+ int ret;
d337f35e 15901+
4bf69007
AM
15902+ ret = do_get_caps(vxi, &vc_data.bcaps, NULL);
15903+ if (ret)
15904+ return ret;
15905+ vc_data.bmask = ~0ULL;
d337f35e 15906+
4bf69007
AM
15907+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15908+ return -EFAULT;
15909+ return 0;
d337f35e
JR
15910+}
15911+
4bf69007 15912+int vc_set_bcaps(struct vx_info *vxi, void __user *data)
d337f35e 15913+{
4bf69007 15914+ struct vcmd_bcaps vc_data;
d337f35e 15915+
2380c486 15916+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15917+ return -EFAULT;
15918+
4bf69007 15919+ return do_set_caps(vxi, vc_data.bcaps, vc_data.bmask, 0, 0);
d337f35e
JR
15920+}
15921+
d337f35e 15922+
4bf69007 15923+int vc_get_umask(struct vx_info *vxi, void __user *data)
d337f35e 15924+{
4bf69007 15925+ struct vcmd_umask vc_data;
7e46296a 15926+
4bf69007
AM
15927+ vc_data.umask = vxi->vx_umask;
15928+ vc_data.mask = ~0ULL;
d337f35e 15929+
4bf69007
AM
15930+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15931+ return -EFAULT;
15932+ return 0;
15933+}
d337f35e 15934+
4bf69007
AM
15935+int vc_set_umask(struct vx_info *vxi, void __user *data)
15936+{
15937+ struct vcmd_umask vc_data;
d337f35e 15938+
4bf69007
AM
15939+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15940+ return -EFAULT;
7e46296a 15941+
4bf69007
AM
15942+ vxi->vx_umask = vs_mask_flags(vxi->vx_umask,
15943+ vc_data.umask, vc_data.mask);
15944+ return 0;
15945+}
7e46296a 15946+
d337f35e 15947+
4bf69007
AM
15948+int vc_get_wmask(struct vx_info *vxi, void __user *data)
15949+{
15950+ struct vcmd_wmask vc_data;
d337f35e 15951+
4bf69007
AM
15952+ vc_data.wmask = vxi->vx_wmask;
15953+ vc_data.mask = ~0ULL;
d337f35e 15954+
4bf69007
AM
15955+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15956+ return -EFAULT;
15957+ return 0;
d337f35e
JR
15958+}
15959+
4bf69007 15960+int vc_set_wmask(struct vx_info *vxi, void __user *data)
d337f35e 15961+{
4bf69007 15962+ struct vcmd_wmask vc_data;
d337f35e 15963+
2380c486 15964+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15965+ return -EFAULT;
15966+
4bf69007
AM
15967+ vxi->vx_wmask = vs_mask_flags(vxi->vx_wmask,
15968+ vc_data.wmask, vc_data.mask);
15969+ return 0;
d337f35e
JR
15970+}
15971+
d337f35e 15972+
4bf69007 15973+int vc_get_badness(struct vx_info *vxi, void __user *data)
d337f35e 15974+{
4bf69007
AM
15975+ struct vcmd_badness_v0 vc_data;
15976+
15977+ vc_data.bias = vxi->vx_badness_bias;
15978+
15979+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15980+ return -EFAULT;
15981+ return 0;
15982+}
15983+
15984+int vc_set_badness(struct vx_info *vxi, void __user *data)
15985+{
15986+ struct vcmd_badness_v0 vc_data;
d337f35e 15987+
2380c486 15988+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15989+ return -EFAULT;
15990+
4bf69007
AM
15991+ vxi->vx_badness_bias = vc_data.bias;
15992+ return 0;
d337f35e
JR
15993+}
15994+
4bf69007 15995+#include <linux/module.h>
d337f35e 15996+
4bf69007 15997+EXPORT_SYMBOL_GPL(free_vx_info);
d337f35e 15998+
f973f73f
AM
15999diff -NurpP --minimal linux-4.1.27/kernel/vserver/cvirt.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/cvirt.c
16000--- linux-4.1.27/kernel/vserver/cvirt.c 1970-01-01 00:00:00.000000000 +0000
16001+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/cvirt.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
16002@@ -0,0 +1,313 @@
16003+/*
16004+ * linux/kernel/vserver/cvirt.c
16005+ *
16006+ * Virtual Server: Context Virtualization
16007+ *
9e3e8383 16008+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
16009+ *
16010+ * V0.01 broken out from limit.c
16011+ * V0.02 added utsname stuff
16012+ * V0.03 changed vcmds to vxi arg
16013+ *
16014+ */
d337f35e 16015+
4bf69007
AM
16016+#include <linux/types.h>
16017+#include <linux/utsname.h>
16018+#include <linux/vs_cvirt.h>
16019+#include <linux/vserver/switch.h>
16020+#include <linux/vserver/cvirt_cmd.h>
d337f35e 16021+
4bf69007 16022+#include <asm/uaccess.h>
d337f35e 16023+
d337f35e 16024+
4bf69007
AM
16025+void vx_vsi_boottime(struct timespec *boottime)
16026+{
16027+ struct vx_info *vxi = current_vx_info();
d337f35e 16028+
4bf69007
AM
16029+ set_normalized_timespec(boottime,
16030+ boottime->tv_sec + vxi->cvirt.bias_uptime.tv_sec,
16031+ boottime->tv_nsec + vxi->cvirt.bias_uptime.tv_nsec);
16032+ return;
d337f35e
JR
16033+}
16034+
4bf69007 16035+void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle)
d337f35e 16036+{
4bf69007 16037+ struct vx_info *vxi = current_vx_info();
d337f35e 16038+
4bf69007
AM
16039+ set_normalized_timespec(uptime,
16040+ uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec,
16041+ uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec);
16042+ if (!idle)
16043+ return;
16044+ set_normalized_timespec(idle,
16045+ idle->tv_sec - vxi->cvirt.bias_idle.tv_sec,
16046+ idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec);
16047+ return;
d337f35e
JR
16048+}
16049+
4bf69007 16050+uint64_t vx_idle_jiffies(void)
d337f35e 16051+{
4bf69007 16052+ return init_task.utime + init_task.stime;
d337f35e
JR
16053+}
16054+
d337f35e
JR
16055+
16056+
4bf69007
AM
16057+static inline uint32_t __update_loadavg(uint32_t load,
16058+ int wsize, int delta, int n)
d337f35e 16059+{
4bf69007 16060+ unsigned long long calc, prev;
d337f35e 16061+
4bf69007
AM
16062+ /* just set it to n */
16063+ if (unlikely(delta >= wsize))
16064+ return (n << FSHIFT);
d337f35e 16065+
4bf69007
AM
16066+ calc = delta * n;
16067+ calc <<= FSHIFT;
16068+ prev = (wsize - delta);
16069+ prev *= load;
16070+ calc += prev;
16071+ do_div(calc, wsize);
16072+ return calc;
16073+}
d337f35e 16074+
d337f35e 16075+
4bf69007
AM
16076+void vx_update_load(struct vx_info *vxi)
16077+{
16078+ uint32_t now, last, delta;
16079+ unsigned int nr_running, nr_uninterruptible;
16080+ unsigned int total;
16081+ unsigned long flags;
d337f35e 16082+
4bf69007 16083+ spin_lock_irqsave(&vxi->cvirt.load_lock, flags);
d337f35e 16084+
4bf69007
AM
16085+ now = jiffies;
16086+ last = vxi->cvirt.load_last;
16087+ delta = now - last;
d337f35e 16088+
4bf69007
AM
16089+ if (delta < 5*HZ)
16090+ goto out;
d337f35e 16091+
4bf69007
AM
16092+ nr_running = atomic_read(&vxi->cvirt.nr_running);
16093+ nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible);
16094+ total = nr_running + nr_uninterruptible;
d337f35e 16095+
4bf69007
AM
16096+ vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0],
16097+ 60*HZ, delta, total);
16098+ vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
16099+ 5*60*HZ, delta, total);
16100+ vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
16101+ 15*60*HZ, delta, total);
d337f35e 16102+
4bf69007
AM
16103+ vxi->cvirt.load_last = now;
16104+out:
16105+ atomic_inc(&vxi->cvirt.load_updates);
16106+ spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags);
d337f35e
JR
16107+}
16108+
d337f35e 16109+
d337f35e 16110+/*
4bf69007 16111+ * Commands to do_syslog:
d337f35e 16112+ *
4bf69007
AM
16113+ * 0 -- Close the log. Currently a NOP.
16114+ * 1 -- Open the log. Currently a NOP.
16115+ * 2 -- Read from the log.
16116+ * 3 -- Read all messages remaining in the ring buffer.
16117+ * 4 -- Read and clear all messages remaining in the ring buffer
16118+ * 5 -- Clear ring buffer.
16119+ * 6 -- Disable printk's to console
16120+ * 7 -- Enable printk's to console
16121+ * 8 -- Set level of messages printed to console
16122+ * 9 -- Return number of unread characters in the log buffer
16123+ * 10 -- Return size of the log buffer
d337f35e 16124+ */
4bf69007
AM
16125+int vx_do_syslog(int type, char __user *buf, int len)
16126+{
16127+ int error = 0;
16128+ int do_clear = 0;
16129+ struct vx_info *vxi = current_vx_info();
16130+ struct _vx_syslog *log;
d337f35e 16131+
4bf69007
AM
16132+ if (!vxi)
16133+ return -EINVAL;
16134+ log = &vxi->cvirt.syslog;
16135+
16136+ switch (type) {
16137+ case 0: /* Close log */
16138+ case 1: /* Open log */
16139+ break;
16140+ case 2: /* Read from log */
16141+ error = wait_event_interruptible(log->log_wait,
16142+ (log->log_start - log->log_end));
16143+ if (error)
16144+ break;
16145+ spin_lock_irq(&log->logbuf_lock);
16146+ spin_unlock_irq(&log->logbuf_lock);
16147+ break;
16148+ case 4: /* Read/clear last kernel messages */
16149+ do_clear = 1;
16150+ /* fall through */
16151+ case 3: /* Read last kernel messages */
16152+ return 0;
d337f35e 16153+
4bf69007
AM
16154+ case 5: /* Clear ring buffer */
16155+ return 0;
d337f35e 16156+
4bf69007
AM
16157+ case 6: /* Disable logging to console */
16158+ case 7: /* Enable logging to console */
16159+ case 8: /* Set level of messages printed to console */
16160+ break;
d337f35e 16161+
4bf69007
AM
16162+ case 9: /* Number of chars in the log buffer */
16163+ return 0;
16164+ case 10: /* Size of the log buffer */
16165+ return 0;
16166+ default:
16167+ error = -EINVAL;
16168+ break;
16169+ }
16170+ return error;
1e8b8f9b 16171+}
d337f35e 16172+
4bf69007
AM
16173+
16174+/* virtual host info names */
16175+
16176+static char *vx_vhi_name(struct vx_info *vxi, int id)
d337f35e 16177+{
4bf69007
AM
16178+ struct nsproxy *nsproxy;
16179+ struct uts_namespace *uts;
d337f35e 16180+
4bf69007
AM
16181+ if (id == VHIN_CONTEXT)
16182+ return vxi->vx_name;
16183+
16184+ nsproxy = vxi->space[0].vx_nsproxy;
16185+ if (!nsproxy)
16186+ return NULL;
16187+
16188+ uts = nsproxy->uts_ns;
16189+ if (!uts)
16190+ return NULL;
16191+
16192+ switch (id) {
16193+ case VHIN_SYSNAME:
16194+ return uts->name.sysname;
16195+ case VHIN_NODENAME:
16196+ return uts->name.nodename;
16197+ case VHIN_RELEASE:
16198+ return uts->name.release;
16199+ case VHIN_VERSION:
16200+ return uts->name.version;
16201+ case VHIN_MACHINE:
16202+ return uts->name.machine;
16203+ case VHIN_DOMAINNAME:
16204+ return uts->name.domainname;
16205+ default:
16206+ return NULL;
d337f35e 16207+ }
4bf69007 16208+ return NULL;
d337f35e
JR
16209+}
16210+
4bf69007 16211+int vc_set_vhi_name(struct vx_info *vxi, void __user *data)
d337f35e 16212+{
4bf69007
AM
16213+ struct vcmd_vhi_name_v0 vc_data;
16214+ char *name;
d337f35e 16215+
4bf69007
AM
16216+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16217+ return -EFAULT;
d337f35e 16218+
4bf69007
AM
16219+ name = vx_vhi_name(vxi, vc_data.field);
16220+ if (!name)
16221+ return -EINVAL;
d337f35e 16222+
4bf69007
AM
16223+ memcpy(name, vc_data.name, 65);
16224+ return 0;
16225+}
d337f35e 16226+
4bf69007
AM
16227+int vc_get_vhi_name(struct vx_info *vxi, void __user *data)
16228+{
16229+ struct vcmd_vhi_name_v0 vc_data;
16230+ char *name;
d337f35e 16231+
4bf69007
AM
16232+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16233+ return -EFAULT;
d337f35e 16234+
4bf69007
AM
16235+ name = vx_vhi_name(vxi, vc_data.field);
16236+ if (!name)
16237+ return -EINVAL;
d337f35e 16238+
4bf69007
AM
16239+ memcpy(vc_data.name, name, 65);
16240+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
16241+ return -EFAULT;
16242+ return 0;
16243+}
d337f35e 16244+
d337f35e 16245+
4bf69007
AM
16246+int vc_virt_stat(struct vx_info *vxi, void __user *data)
16247+{
16248+ struct vcmd_virt_stat_v0 vc_data;
16249+ struct _vx_cvirt *cvirt = &vxi->cvirt;
16250+ struct timespec uptime;
99a884b4 16251+
4bf69007
AM
16252+ do_posix_clock_monotonic_gettime(&uptime);
16253+ set_normalized_timespec(&uptime,
16254+ uptime.tv_sec - cvirt->bias_uptime.tv_sec,
16255+ uptime.tv_nsec - cvirt->bias_uptime.tv_nsec);
d337f35e 16256+
4bf69007
AM
16257+ vc_data.offset = timespec_to_ns(&cvirt->bias_ts);
16258+ vc_data.uptime = timespec_to_ns(&uptime);
16259+ vc_data.nr_threads = atomic_read(&cvirt->nr_threads);
16260+ vc_data.nr_running = atomic_read(&cvirt->nr_running);
16261+ vc_data.nr_uninterruptible = atomic_read(&cvirt->nr_uninterruptible);
16262+ vc_data.nr_onhold = atomic_read(&cvirt->nr_onhold);
16263+ vc_data.nr_forks = atomic_read(&cvirt->total_forks);
16264+ vc_data.load[0] = cvirt->load[0];
16265+ vc_data.load[1] = cvirt->load[1];
16266+ vc_data.load[2] = cvirt->load[2];
16267+
16268+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
16269+ return -EFAULT;
16270+ return 0;
d337f35e
JR
16271+}
16272+
16273+
4bf69007
AM
16274+#ifdef CONFIG_VSERVER_VTIME
16275+
16276+/* virtualized time base */
16277+
16278+void vx_adjust_timespec(struct timespec *ts)
d337f35e 16279+{
4bf69007 16280+ struct vx_info *vxi;
d337f35e 16281+
4bf69007
AM
16282+ if (!vx_flags(VXF_VIRT_TIME, 0))
16283+ return;
d337f35e 16284+
4bf69007
AM
16285+ vxi = current_vx_info();
16286+ ts->tv_sec += vxi->cvirt.bias_ts.tv_sec;
16287+ ts->tv_nsec += vxi->cvirt.bias_ts.tv_nsec;
d337f35e 16288+
4bf69007
AM
16289+ if (ts->tv_nsec >= NSEC_PER_SEC) {
16290+ ts->tv_sec++;
16291+ ts->tv_nsec -= NSEC_PER_SEC;
16292+ } else if (ts->tv_nsec < 0) {
16293+ ts->tv_sec--;
16294+ ts->tv_nsec += NSEC_PER_SEC;
d337f35e 16295+ }
d337f35e
JR
16296+}
16297+
4bf69007 16298+int vx_settimeofday(const struct timespec *ts)
99a884b4 16299+{
4bf69007
AM
16300+ struct timespec ats, delta;
16301+ struct vx_info *vxi;
99a884b4 16302+
4bf69007
AM
16303+ if (!vx_flags(VXF_VIRT_TIME, 0))
16304+ return do_settimeofday(ts);
99a884b4 16305+
4bf69007
AM
16306+ getnstimeofday(&ats);
16307+ delta = timespec_sub(*ts, ats);
99a884b4 16308+
4bf69007
AM
16309+ vxi = current_vx_info();
16310+ vxi->cvirt.bias_ts = timespec_add(vxi->cvirt.bias_ts, delta);
99a884b4
AM
16311+ return 0;
16312+}
d337f35e 16313+
4bf69007 16314+#endif
d337f35e 16315+
f973f73f
AM
16316diff -NurpP --minimal linux-4.1.27/kernel/vserver/cvirt_init.h linux-4.1.27-vs2.3.8.5.2/kernel/vserver/cvirt_init.h
16317--- linux-4.1.27/kernel/vserver/cvirt_init.h 1970-01-01 00:00:00.000000000 +0000
16318+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/cvirt_init.h 2016-07-05 04:41:47.000000000 +0000
4bf69007 16319@@ -0,0 +1,70 @@
d337f35e 16320+
d337f35e 16321+
4bf69007 16322+extern uint64_t vx_idle_jiffies(void);
d337f35e 16323+
4bf69007
AM
16324+static inline void vx_info_init_cvirt(struct _vx_cvirt *cvirt)
16325+{
16326+ uint64_t idle_jiffies = vx_idle_jiffies();
16327+ uint64_t nsuptime;
d337f35e 16328+
4bf69007
AM
16329+ do_posix_clock_monotonic_gettime(&cvirt->bias_uptime);
16330+ nsuptime = (unsigned long long)cvirt->bias_uptime.tv_sec
16331+ * NSEC_PER_SEC + cvirt->bias_uptime.tv_nsec;
16332+ cvirt->bias_clock = nsec_to_clock_t(nsuptime);
16333+ cvirt->bias_ts.tv_sec = 0;
16334+ cvirt->bias_ts.tv_nsec = 0;
d337f35e 16335+
4bf69007
AM
16336+ jiffies_to_timespec(idle_jiffies, &cvirt->bias_idle);
16337+ atomic_set(&cvirt->nr_threads, 0);
16338+ atomic_set(&cvirt->nr_running, 0);
16339+ atomic_set(&cvirt->nr_uninterruptible, 0);
16340+ atomic_set(&cvirt->nr_onhold, 0);
d337f35e 16341+
4bf69007
AM
16342+ spin_lock_init(&cvirt->load_lock);
16343+ cvirt->load_last = jiffies;
16344+ atomic_set(&cvirt->load_updates, 0);
16345+ cvirt->load[0] = 0;
16346+ cvirt->load[1] = 0;
16347+ cvirt->load[2] = 0;
16348+ atomic_set(&cvirt->total_forks, 0);
d337f35e 16349+
4bf69007
AM
16350+ spin_lock_init(&cvirt->syslog.logbuf_lock);
16351+ init_waitqueue_head(&cvirt->syslog.log_wait);
16352+ cvirt->syslog.log_start = 0;
16353+ cvirt->syslog.log_end = 0;
16354+ cvirt->syslog.con_start = 0;
16355+ cvirt->syslog.logged_chars = 0;
16356+}
16357+
16358+static inline
16359+void vx_info_init_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
d337f35e 16360+{
4bf69007
AM
16361+ // cvirt_pc->cpustat = { 0 };
16362+}
d337f35e 16363+
4bf69007
AM
16364+static inline void vx_info_exit_cvirt(struct _vx_cvirt *cvirt)
16365+{
16366+#ifdef CONFIG_VSERVER_WARN
16367+ int value;
16368+#endif
16369+ vxwprintk_xid((value = atomic_read(&cvirt->nr_threads)),
16370+ "!!! cvirt: %p[nr_threads] = %d on exit.",
16371+ cvirt, value);
16372+ vxwprintk_xid((value = atomic_read(&cvirt->nr_running)),
16373+ "!!! cvirt: %p[nr_running] = %d on exit.",
16374+ cvirt, value);
16375+ vxwprintk_xid((value = atomic_read(&cvirt->nr_uninterruptible)),
16376+ "!!! cvirt: %p[nr_uninterruptible] = %d on exit.",
16377+ cvirt, value);
16378+ vxwprintk_xid((value = atomic_read(&cvirt->nr_onhold)),
16379+ "!!! cvirt: %p[nr_onhold] = %d on exit.",
16380+ cvirt, value);
16381+ return;
16382+}
d337f35e 16383+
4bf69007
AM
16384+static inline
16385+void vx_info_exit_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
16386+{
16387+ return;
16388+}
d337f35e 16389+
f973f73f
AM
16390diff -NurpP --minimal linux-4.1.27/kernel/vserver/cvirt_proc.h linux-4.1.27-vs2.3.8.5.2/kernel/vserver/cvirt_proc.h
16391--- linux-4.1.27/kernel/vserver/cvirt_proc.h 1970-01-01 00:00:00.000000000 +0000
16392+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/cvirt_proc.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
16393@@ -0,0 +1,123 @@
16394+#ifndef _VX_CVIRT_PROC_H
16395+#define _VX_CVIRT_PROC_H
d337f35e 16396+
4bf69007
AM
16397+#include <linux/nsproxy.h>
16398+#include <linux/mnt_namespace.h>
16399+#include <linux/ipc_namespace.h>
16400+#include <linux/utsname.h>
16401+#include <linux/ipc.h>
d337f35e 16402+
4bf69007 16403+extern int vx_info_mnt_namespace(struct mnt_namespace *, char *);
d337f35e 16404+
4bf69007
AM
16405+static inline
16406+int vx_info_proc_nsproxy(struct nsproxy *nsproxy, char *buffer)
16407+{
16408+ struct mnt_namespace *ns;
16409+ struct uts_namespace *uts;
16410+ struct ipc_namespace *ipc;
16411+ int length = 0;
d337f35e 16412+
4bf69007
AM
16413+ if (!nsproxy)
16414+ goto out;
d337f35e 16415+
4bf69007
AM
16416+ length += sprintf(buffer + length,
16417+ "NSProxy:\t%p [%p,%p,%p]\n",
16418+ nsproxy, nsproxy->mnt_ns,
16419+ nsproxy->uts_ns, nsproxy->ipc_ns);
d337f35e 16420+
4bf69007
AM
16421+ ns = nsproxy->mnt_ns;
16422+ if (!ns)
16423+ goto skip_ns;
d337f35e 16424+
4bf69007 16425+ length += vx_info_mnt_namespace(ns, buffer + length);
d337f35e 16426+
4bf69007 16427+skip_ns:
d337f35e 16428+
4bf69007
AM
16429+ uts = nsproxy->uts_ns;
16430+ if (!uts)
16431+ goto skip_uts;
d337f35e 16432+
4bf69007
AM
16433+ length += sprintf(buffer + length,
16434+ "SysName:\t%.*s\n"
16435+ "NodeName:\t%.*s\n"
16436+ "Release:\t%.*s\n"
16437+ "Version:\t%.*s\n"
16438+ "Machine:\t%.*s\n"
16439+ "DomainName:\t%.*s\n",
16440+ __NEW_UTS_LEN, uts->name.sysname,
16441+ __NEW_UTS_LEN, uts->name.nodename,
16442+ __NEW_UTS_LEN, uts->name.release,
16443+ __NEW_UTS_LEN, uts->name.version,
16444+ __NEW_UTS_LEN, uts->name.machine,
16445+ __NEW_UTS_LEN, uts->name.domainname);
16446+skip_uts:
d337f35e 16447+
4bf69007
AM
16448+ ipc = nsproxy->ipc_ns;
16449+ if (!ipc)
16450+ goto skip_ipc;
d337f35e 16451+
4bf69007
AM
16452+ length += sprintf(buffer + length,
16453+ "SEMS:\t\t%d %d %d %d %d\n"
16454+ "MSG:\t\t%d %d %d\n"
b00e13aa 16455+ "SHM:\t\t%lu %lu %d %ld\n",
4bf69007
AM
16456+ ipc->sem_ctls[0], ipc->sem_ctls[1],
16457+ ipc->sem_ctls[2], ipc->sem_ctls[3],
16458+ ipc->used_sems,
16459+ ipc->msg_ctlmax, ipc->msg_ctlmnb, ipc->msg_ctlmni,
16460+ (unsigned long)ipc->shm_ctlmax,
16461+ (unsigned long)ipc->shm_ctlall,
16462+ ipc->shm_ctlmni, ipc->shm_tot);
16463+skip_ipc:
16464+out:
16465+ return length;
16466+}
d337f35e
JR
16467+
16468+
4bf69007 16469+#include <linux/sched.h>
d337f35e 16470+
4bf69007
AM
16471+#define LOAD_INT(x) ((x) >> FSHIFT)
16472+#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1 - 1)) * 100)
d337f35e 16473+
4bf69007
AM
16474+static inline
16475+int vx_info_proc_cvirt(struct _vx_cvirt *cvirt, char *buffer)
d337f35e 16476+{
4bf69007
AM
16477+ int length = 0;
16478+ int a, b, c;
d337f35e 16479+
4bf69007
AM
16480+ length += sprintf(buffer + length,
16481+ "BiasUptime:\t%lu.%02lu\n",
16482+ (unsigned long)cvirt->bias_uptime.tv_sec,
16483+ (cvirt->bias_uptime.tv_nsec / (NSEC_PER_SEC / 100)));
d337f35e 16484+
4bf69007
AM
16485+ a = cvirt->load[0] + (FIXED_1 / 200);
16486+ b = cvirt->load[1] + (FIXED_1 / 200);
16487+ c = cvirt->load[2] + (FIXED_1 / 200);
16488+ length += sprintf(buffer + length,
16489+ "nr_threads:\t%d\n"
16490+ "nr_running:\t%d\n"
16491+ "nr_unintr:\t%d\n"
16492+ "nr_onhold:\t%d\n"
16493+ "load_updates:\t%d\n"
16494+ "loadavg:\t%d.%02d %d.%02d %d.%02d\n"
16495+ "total_forks:\t%d\n",
16496+ atomic_read(&cvirt->nr_threads),
16497+ atomic_read(&cvirt->nr_running),
16498+ atomic_read(&cvirt->nr_uninterruptible),
16499+ atomic_read(&cvirt->nr_onhold),
16500+ atomic_read(&cvirt->load_updates),
16501+ LOAD_INT(a), LOAD_FRAC(a),
16502+ LOAD_INT(b), LOAD_FRAC(b),
16503+ LOAD_INT(c), LOAD_FRAC(c),
16504+ atomic_read(&cvirt->total_forks));
16505+ return length;
d337f35e
JR
16506+}
16507+
4bf69007
AM
16508+static inline
16509+int vx_info_proc_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc,
16510+ char *buffer, int cpu)
16511+{
16512+ int length = 0;
16513+ return length;
16514+}
d337f35e 16515+
4bf69007 16516+#endif /* _VX_CVIRT_PROC_H */
f973f73f
AM
16517diff -NurpP --minimal linux-4.1.27/kernel/vserver/debug.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/debug.c
16518--- linux-4.1.27/kernel/vserver/debug.c 1970-01-01 00:00:00.000000000 +0000
16519+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/debug.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
16520@@ -0,0 +1,32 @@
16521+/*
16522+ * kernel/vserver/debug.c
16523+ *
9e3e8383 16524+ * Copyright (C) 2005-2007 Herbert P?tzl
4bf69007
AM
16525+ *
16526+ * V0.01 vx_info dump support
16527+ *
16528+ */
d337f35e 16529+
4bf69007 16530+#include <linux/module.h>
d337f35e 16531+
4bf69007 16532+#include <linux/vserver/context.h>
d337f35e 16533+
d337f35e 16534+
4bf69007 16535+void dump_vx_info(struct vx_info *vxi, int level)
d337f35e 16536+{
4bf69007
AM
16537+ printk("vx_info %p[#%d, %d.%d, %4x]\n", vxi, vxi->vx_id,
16538+ atomic_read(&vxi->vx_usecnt),
16539+ atomic_read(&vxi->vx_tasks),
16540+ vxi->vx_state);
16541+ if (level > 0) {
16542+ __dump_vx_limit(&vxi->limit);
16543+ __dump_vx_sched(&vxi->sched);
16544+ __dump_vx_cvirt(&vxi->cvirt);
16545+ __dump_vx_cacct(&vxi->cacct);
16546+ }
16547+ printk("---\n");
16548+}
d337f35e 16549+
d337f35e 16550+
4bf69007 16551+EXPORT_SYMBOL_GPL(dump_vx_info);
d337f35e 16552+
f973f73f
AM
16553diff -NurpP --minimal linux-4.1.27/kernel/vserver/device.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/device.c
16554--- linux-4.1.27/kernel/vserver/device.c 1970-01-01 00:00:00.000000000 +0000
16555+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/device.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
16556@@ -0,0 +1,443 @@
16557+/*
16558+ * linux/kernel/vserver/device.c
16559+ *
16560+ * Linux-VServer: Device Support
16561+ *
9e3e8383 16562+ * Copyright (C) 2006 Herbert P?tzl
4bf69007
AM
16563+ * Copyright (C) 2007 Daniel Hokka Zakrisson
16564+ *
16565+ * V0.01 device mapping basics
16566+ * V0.02 added defaults
16567+ *
16568+ */
d337f35e 16569+
4bf69007
AM
16570+#include <linux/slab.h>
16571+#include <linux/rcupdate.h>
16572+#include <linux/fs.h>
16573+#include <linux/namei.h>
16574+#include <linux/hash.h>
d337f35e 16575+
4bf69007
AM
16576+#include <asm/errno.h>
16577+#include <asm/uaccess.h>
16578+#include <linux/vserver/base.h>
16579+#include <linux/vserver/debug.h>
16580+#include <linux/vserver/context.h>
16581+#include <linux/vserver/device.h>
16582+#include <linux/vserver/device_cmd.h>
d337f35e 16583+
d337f35e 16584+
4bf69007 16585+#define DMAP_HASH_BITS 4
d337f35e 16586+
d337f35e 16587+
4bf69007
AM
16588+struct vs_mapping {
16589+ union {
16590+ struct hlist_node hlist;
16591+ struct list_head list;
16592+ } u;
16593+#define dm_hlist u.hlist
16594+#define dm_list u.list
61333608 16595+ vxid_t xid;
4bf69007
AM
16596+ dev_t device;
16597+ struct vx_dmap_target target;
16598+};
d337f35e 16599+
d337f35e 16600+
4bf69007 16601+static struct hlist_head dmap_main_hash[1 << DMAP_HASH_BITS];
d337f35e 16602+
4bf69007 16603+static DEFINE_SPINLOCK(dmap_main_hash_lock);
d337f35e 16604+
4bf69007
AM
16605+static struct vx_dmap_target dmap_defaults[2] = {
16606+ { .flags = DATTR_OPEN },
16607+ { .flags = DATTR_OPEN },
16608+};
d337f35e
JR
16609+
16610+
4bf69007 16611+struct kmem_cache *dmap_cachep __read_mostly;
d337f35e 16612+
4bf69007
AM
16613+int __init dmap_cache_init(void)
16614+{
16615+ dmap_cachep = kmem_cache_create("dmap_cache",
16616+ sizeof(struct vs_mapping), 0,
16617+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
d337f35e
JR
16618+ return 0;
16619+}
16620+
4bf69007 16621+__initcall(dmap_cache_init);
d337f35e 16622+
4bf69007
AM
16623+
16624+static inline unsigned int __hashval(dev_t dev, int bits)
d337f35e 16625+{
4bf69007
AM
16626+ return hash_long((unsigned long)dev, bits);
16627+}
d337f35e 16628+
d337f35e 16629+
4bf69007
AM
16630+/* __hash_mapping()
16631+ * add the mapping to the hash table
16632+ */
16633+static inline void __hash_mapping(struct vx_info *vxi, struct vs_mapping *vdm)
16634+{
16635+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16636+ struct hlist_head *head, *hash = dmap_main_hash;
16637+ int device = vdm->device;
d337f35e 16638+
4bf69007
AM
16639+ spin_lock(hash_lock);
16640+ vxdprintk(VXD_CBIT(misc, 8), "__hash_mapping: %p[#%d] %08x:%08x",
16641+ vxi, vxi ? vxi->vx_id : 0, device, vdm->target.target);
d337f35e 16642+
4bf69007
AM
16643+ head = &hash[__hashval(device, DMAP_HASH_BITS)];
16644+ hlist_add_head(&vdm->dm_hlist, head);
16645+ spin_unlock(hash_lock);
16646+}
16647+
16648+
16649+static inline int __mode_to_default(umode_t mode)
16650+{
16651+ switch (mode) {
16652+ case S_IFBLK:
16653+ return 0;
16654+ case S_IFCHR:
16655+ return 1;
16656+ default:
16657+ BUG();
d337f35e 16658+ }
d337f35e
JR
16659+}
16660+
4bf69007
AM
16661+
16662+/* __set_default()
16663+ * set a default
16664+ */
16665+static inline void __set_default(struct vx_info *vxi, umode_t mode,
16666+ struct vx_dmap_target *vdmt)
d337f35e 16667+{
4bf69007
AM
16668+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16669+ spin_lock(hash_lock);
d337f35e 16670+
4bf69007
AM
16671+ if (vxi)
16672+ vxi->dmap.targets[__mode_to_default(mode)] = *vdmt;
16673+ else
16674+ dmap_defaults[__mode_to_default(mode)] = *vdmt;
d337f35e 16675+
d337f35e 16676+
4bf69007 16677+ spin_unlock(hash_lock);
d337f35e 16678+
4bf69007
AM
16679+ vxdprintk(VXD_CBIT(misc, 8), "__set_default: %p[#%u] %08x %04x",
16680+ vxi, vxi ? vxi->vx_id : 0, vdmt->target, vdmt->flags);
d337f35e
JR
16681+}
16682+
d337f35e 16683+
4bf69007
AM
16684+/* __remove_default()
16685+ * remove a default
16686+ */
16687+static inline int __remove_default(struct vx_info *vxi, umode_t mode)
d337f35e 16688+{
4bf69007
AM
16689+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16690+ spin_lock(hash_lock);
d337f35e 16691+
4bf69007
AM
16692+ if (vxi)
16693+ vxi->dmap.targets[__mode_to_default(mode)].flags = 0;
16694+ else /* remove == reset */
16695+ dmap_defaults[__mode_to_default(mode)].flags = DATTR_OPEN | mode;
d337f35e 16696+
4bf69007
AM
16697+ spin_unlock(hash_lock);
16698+ return 0;
d337f35e
JR
16699+}
16700+
d337f35e 16701+
4bf69007
AM
16702+/* __find_mapping()
16703+ * find a mapping in the hash table
16704+ *
16705+ * caller must hold hash_lock
16706+ */
61333608 16707+static inline int __find_mapping(vxid_t xid, dev_t device, umode_t mode,
4bf69007
AM
16708+ struct vs_mapping **local, struct vs_mapping **global)
16709+{
16710+ struct hlist_head *hash = dmap_main_hash;
16711+ struct hlist_head *head = &hash[__hashval(device, DMAP_HASH_BITS)];
16712+ struct hlist_node *pos;
16713+ struct vs_mapping *vdm;
d337f35e 16714+
4bf69007
AM
16715+ *local = NULL;
16716+ if (global)
16717+ *global = NULL;
d337f35e 16718+
4bf69007
AM
16719+ hlist_for_each(pos, head) {
16720+ vdm = hlist_entry(pos, struct vs_mapping, dm_hlist);
d337f35e 16721+
4bf69007
AM
16722+ if ((vdm->device == device) &&
16723+ !((vdm->target.flags ^ mode) & S_IFMT)) {
16724+ if (vdm->xid == xid) {
16725+ *local = vdm;
16726+ return 1;
16727+ } else if (global && vdm->xid == 0)
16728+ *global = vdm;
2380c486
JR
16729+ }
16730+ }
16731+
4bf69007
AM
16732+ if (global && *global)
16733+ return 0;
16734+ else
16735+ return -ENOENT;
2380c486
JR
16736+}
16737+
16738+
4bf69007
AM
16739+/* __lookup_mapping()
16740+ * find a mapping and store the result in target and flags
16741+ */
16742+static inline int __lookup_mapping(struct vx_info *vxi,
16743+ dev_t device, dev_t *target, int *flags, umode_t mode)
2380c486 16744+{
4bf69007
AM
16745+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16746+ struct vs_mapping *vdm, *global;
16747+ struct vx_dmap_target *vdmt;
2380c486 16748+ int ret = 0;
61333608 16749+ vxid_t xid = vxi->vx_id;
4bf69007 16750+ int index;
2380c486 16751+
4bf69007
AM
16752+ spin_lock(hash_lock);
16753+ if (__find_mapping(xid, device, mode, &vdm, &global) > 0) {
2380c486 16754+ ret = 1;
4bf69007
AM
16755+ vdmt = &vdm->target;
16756+ goto found;
16757+ }
2380c486 16758+
4bf69007
AM
16759+ index = __mode_to_default(mode);
16760+ if (vxi && vxi->dmap.targets[index].flags) {
16761+ ret = 2;
16762+ vdmt = &vxi->dmap.targets[index];
16763+ } else if (global) {
16764+ ret = 3;
16765+ vdmt = &global->target;
16766+ goto found;
16767+ } else {
16768+ ret = 4;
16769+ vdmt = &dmap_defaults[index];
d337f35e 16770+ }
2380c486 16771+
4bf69007
AM
16772+found:
16773+ if (target && (vdmt->flags & DATTR_REMAP))
16774+ *target = vdmt->target;
16775+ else if (target)
16776+ *target = device;
16777+ if (flags)
16778+ *flags = vdmt->flags;
16779+
16780+ spin_unlock(hash_lock);
2380c486
JR
16781+
16782+ return ret;
d337f35e
JR
16783+}
16784+
16785+
4bf69007
AM
16786+/* __remove_mapping()
16787+ * remove a mapping from the hash table
16788+ */
16789+static inline int __remove_mapping(struct vx_info *vxi, dev_t device,
16790+ umode_t mode)
d337f35e 16791+{
4bf69007
AM
16792+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16793+ struct vs_mapping *vdm = NULL;
d337f35e
JR
16794+ int ret = 0;
16795+
4bf69007
AM
16796+ spin_lock(hash_lock);
16797+
16798+ ret = __find_mapping((vxi ? vxi->vx_id : 0), device, mode, &vdm,
16799+ NULL);
16800+ vxdprintk(VXD_CBIT(misc, 8), "__remove_mapping: %p[#%d] %08x %04x",
16801+ vxi, vxi ? vxi->vx_id : 0, device, mode);
16802+ if (ret < 0)
2380c486 16803+ goto out;
4bf69007 16804+ hlist_del(&vdm->dm_hlist);
2380c486 16805+
2380c486 16806+out:
4bf69007
AM
16807+ spin_unlock(hash_lock);
16808+ if (vdm)
16809+ kmem_cache_free(dmap_cachep, vdm);
2380c486
JR
16810+ return ret;
16811+}
16812+
16813+
2380c486 16814+
4bf69007
AM
16815+int vs_map_device(struct vx_info *vxi,
16816+ dev_t device, dev_t *target, umode_t mode)
2380c486 16817+{
4bf69007 16818+ int ret, flags = DATTR_MASK;
2380c486 16819+
4bf69007
AM
16820+ if (!vxi) {
16821+ if (target)
16822+ *target = device;
2380c486 16823+ goto out;
2380c486 16824+ }
4bf69007
AM
16825+ ret = __lookup_mapping(vxi, device, target, &flags, mode);
16826+ vxdprintk(VXD_CBIT(misc, 8), "vs_map_device: %08x target: %08x flags: %04x mode: %04x mapped=%d",
16827+ device, target ? *target : 0, flags, mode, ret);
2380c486 16828+out:
4bf69007 16829+ return (flags & DATTR_MASK);
2380c486
JR
16830+}
16831+
2380c486 16832+
4bf69007
AM
16833+
16834+static int do_set_mapping(struct vx_info *vxi,
16835+ dev_t device, dev_t target, int flags, umode_t mode)
2380c486 16836+{
4bf69007
AM
16837+ if (device) {
16838+ struct vs_mapping *new;
2380c486 16839+
4bf69007
AM
16840+ new = kmem_cache_alloc(dmap_cachep, GFP_KERNEL);
16841+ if (!new)
16842+ return -ENOMEM;
16843+
16844+ INIT_HLIST_NODE(&new->dm_hlist);
16845+ new->device = device;
16846+ new->target.target = target;
16847+ new->target.flags = flags | mode;
16848+ new->xid = (vxi ? vxi->vx_id : 0);
16849+
16850+ vxdprintk(VXD_CBIT(misc, 8), "do_set_mapping: %08x target: %08x flags: %04x", device, target, flags);
16851+ __hash_mapping(vxi, new);
16852+ } else {
16853+ struct vx_dmap_target new = {
16854+ .target = target,
16855+ .flags = flags | mode,
16856+ };
16857+ __set_default(vxi, mode, &new);
16858+ }
16859+ return 0;
2380c486
JR
16860+}
16861+
4bf69007
AM
16862+
16863+static int do_unset_mapping(struct vx_info *vxi,
16864+ dev_t device, dev_t target, int flags, umode_t mode)
2380c486 16865+{
4bf69007 16866+ int ret = -EINVAL;
763640ca 16867+
4bf69007
AM
16868+ if (device) {
16869+ ret = __remove_mapping(vxi, device, mode);
16870+ if (ret < 0)
16871+ goto out;
16872+ } else {
16873+ ret = __remove_default(vxi, mode);
16874+ if (ret < 0)
16875+ goto out;
16876+ }
2380c486 16877+
4bf69007
AM
16878+out:
16879+ return ret;
16880+}
2380c486 16881+
2380c486 16882+
4bf69007
AM
16883+static inline int __user_device(const char __user *name, dev_t *dev,
16884+ umode_t *mode)
16885+{
5eef5607 16886+ struct path path;
4bf69007 16887+ int ret;
2380c486 16888+
4bf69007
AM
16889+ if (!name) {
16890+ *dev = 0;
16891+ return 0;
16892+ }
5eef5607 16893+ ret = user_lpath(name, &path);
4bf69007
AM
16894+ if (ret)
16895+ return ret;
5eef5607
AM
16896+ if (path.dentry->d_inode) {
16897+ *dev = path.dentry->d_inode->i_rdev;
16898+ *mode = path.dentry->d_inode->i_mode;
4bf69007 16899+ }
5eef5607 16900+ path_put(&path);
4bf69007
AM
16901+ return 0;
16902+}
2380c486 16903+
4bf69007
AM
16904+static inline int __mapping_mode(dev_t device, dev_t target,
16905+ umode_t device_mode, umode_t target_mode, umode_t *mode)
16906+{
16907+ if (device)
16908+ *mode = device_mode & S_IFMT;
16909+ else if (target)
16910+ *mode = target_mode & S_IFMT;
16911+ else
16912+ return -EINVAL;
2380c486 16913+
4bf69007
AM
16914+ /* if both given, device and target mode have to match */
16915+ if (device && target &&
16916+ ((device_mode ^ target_mode) & S_IFMT))
16917+ return -EINVAL;
16918+ return 0;
16919+}
d337f35e 16920+
d337f35e 16921+
4bf69007
AM
16922+static inline int do_mapping(struct vx_info *vxi, const char __user *device_path,
16923+ const char __user *target_path, int flags, int set)
16924+{
16925+ dev_t device = ~0, target = ~0;
16926+ umode_t device_mode = 0, target_mode = 0, mode;
16927+ int ret;
2380c486 16928+
4bf69007
AM
16929+ ret = __user_device(device_path, &device, &device_mode);
16930+ if (ret)
16931+ return ret;
16932+ ret = __user_device(target_path, &target, &target_mode);
16933+ if (ret)
16934+ return ret;
2380c486 16935+
4bf69007
AM
16936+ ret = __mapping_mode(device, target,
16937+ device_mode, target_mode, &mode);
16938+ if (ret)
16939+ return ret;
2380c486 16940+
4bf69007
AM
16941+ if (set)
16942+ return do_set_mapping(vxi, device, target,
16943+ flags, mode);
16944+ else
16945+ return do_unset_mapping(vxi, device, target,
16946+ flags, mode);
d337f35e
JR
16947+}
16948+
d337f35e 16949+
4bf69007
AM
16950+int vc_set_mapping(struct vx_info *vxi, void __user *data)
16951+{
16952+ struct vcmd_set_mapping_v0 vc_data;
d337f35e 16953+
4bf69007
AM
16954+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16955+ return -EFAULT;
d337f35e 16956+
4bf69007
AM
16957+ return do_mapping(vxi, vc_data.device, vc_data.target,
16958+ vc_data.flags, 1);
16959+}
d337f35e 16960+
4bf69007 16961+int vc_unset_mapping(struct vx_info *vxi, void __user *data)
d337f35e 16962+{
4bf69007 16963+ struct vcmd_set_mapping_v0 vc_data;
d337f35e 16964+
4bf69007
AM
16965+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16966+ return -EFAULT;
16967+
16968+ return do_mapping(vxi, vc_data.device, vc_data.target,
16969+ vc_data.flags, 0);
d337f35e
JR
16970+}
16971+
16972+
4bf69007
AM
16973+#ifdef CONFIG_COMPAT
16974+
16975+int vc_set_mapping_x32(struct vx_info *vxi, void __user *data)
d337f35e 16976+{
4bf69007 16977+ struct vcmd_set_mapping_v0_x32 vc_data;
d337f35e 16978+
4bf69007
AM
16979+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16980+ return -EFAULT;
16981+
16982+ return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
16983+ compat_ptr(vc_data.target_ptr), vc_data.flags, 1);
d337f35e
JR
16984+}
16985+
4bf69007
AM
16986+int vc_unset_mapping_x32(struct vx_info *vxi, void __user *data)
16987+{
16988+ struct vcmd_set_mapping_v0_x32 vc_data;
16989+
16990+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16991+ return -EFAULT;
d337f35e 16992+
4bf69007
AM
16993+ return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
16994+ compat_ptr(vc_data.target_ptr), vc_data.flags, 0);
16995+}
d337f35e 16996+
4bf69007 16997+#endif /* CONFIG_COMPAT */
d337f35e 16998+
4bf69007 16999+
f973f73f
AM
17000diff -NurpP --minimal linux-4.1.27/kernel/vserver/dlimit.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/dlimit.c
17001--- linux-4.1.27/kernel/vserver/dlimit.c 1970-01-01 00:00:00.000000000 +0000
17002+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/dlimit.c 2016-07-05 04:41:47.000000000 +0000
b00e13aa 17003@@ -0,0 +1,528 @@
d337f35e 17004+/*
4bf69007 17005+ * linux/kernel/vserver/dlimit.c
d337f35e 17006+ *
4bf69007 17007+ * Virtual Server: Context Disk Limits
d337f35e 17008+ *
9e3e8383 17009+ * Copyright (C) 2004-2009 Herbert P?tzl
d337f35e 17010+ *
4bf69007
AM
17011+ * V0.01 initial version
17012+ * V0.02 compat32 splitup
17013+ * V0.03 extended interface
d337f35e
JR
17014+ *
17015+ */
17016+
4bf69007
AM
17017+#include <linux/statfs.h>
17018+#include <linux/sched.h>
2380c486 17019+#include <linux/namei.h>
d337f35e 17020+#include <linux/vs_tag.h>
4bf69007
AM
17021+#include <linux/vs_dlimit.h>
17022+#include <linux/vserver/dlimit_cmd.h>
17023+#include <linux/slab.h>
17024+// #include <linux/gfp.h>
d337f35e 17025+
d337f35e
JR
17026+#include <asm/uaccess.h>
17027+
4bf69007 17028+/* __alloc_dl_info()
d337f35e 17029+
4bf69007
AM
17030+ * allocate an initialized dl_info struct
17031+ * doesn't make it visible (hash) */
d337f35e 17032+
61333608 17033+static struct dl_info *__alloc_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
17034+{
17035+ struct dl_info *new = NULL;
d337f35e 17036+
4bf69007
AM
17037+ vxdprintk(VXD_CBIT(dlim, 5),
17038+ "alloc_dl_info(%p,%d)*", sb, tag);
d337f35e 17039+
4bf69007
AM
17040+ /* would this benefit from a slab cache? */
17041+ new = kmalloc(sizeof(struct dl_info), GFP_KERNEL);
17042+ if (!new)
17043+ return 0;
d337f35e 17044+
4bf69007
AM
17045+ memset(new, 0, sizeof(struct dl_info));
17046+ new->dl_tag = tag;
17047+ new->dl_sb = sb;
17048+ // INIT_RCU_HEAD(&new->dl_rcu);
17049+ INIT_HLIST_NODE(&new->dl_hlist);
17050+ spin_lock_init(&new->dl_lock);
17051+ atomic_set(&new->dl_refcnt, 0);
17052+ atomic_set(&new->dl_usecnt, 0);
d337f35e 17053+
4bf69007 17054+ /* rest of init goes here */
d337f35e 17055+
4bf69007
AM
17056+ vxdprintk(VXD_CBIT(dlim, 4),
17057+ "alloc_dl_info(%p,%d) = %p", sb, tag, new);
17058+ return new;
17059+}
d4263eb0 17060+
4bf69007 17061+/* __dealloc_dl_info()
d337f35e 17062+
4bf69007 17063+ * final disposal of dl_info */
d337f35e 17064+
4bf69007 17065+static void __dealloc_dl_info(struct dl_info *dli)
adc1caaa 17066+{
4bf69007
AM
17067+ vxdprintk(VXD_CBIT(dlim, 4),
17068+ "dealloc_dl_info(%p)", dli);
2380c486 17069+
4bf69007
AM
17070+ dli->dl_hlist.next = LIST_POISON1;
17071+ dli->dl_tag = -1;
17072+ dli->dl_sb = 0;
2380c486 17073+
4bf69007
AM
17074+ BUG_ON(atomic_read(&dli->dl_usecnt));
17075+ BUG_ON(atomic_read(&dli->dl_refcnt));
2380c486 17076+
4bf69007 17077+ kfree(dli);
adc1caaa 17078+}
2380c486 17079+
2380c486 17080+
4bf69007 17081+/* hash table for dl_info hash */
2380c486 17082+
4bf69007 17083+#define DL_HASH_SIZE 13
2380c486 17084+
4bf69007 17085+struct hlist_head dl_info_hash[DL_HASH_SIZE];
2380c486 17086+
4bf69007 17087+static DEFINE_SPINLOCK(dl_info_hash_lock);
2380c486 17088+
d33d7b00 17089+
61333608 17090+static inline unsigned int __hashval(struct super_block *sb, vtag_t tag)
adc1caaa 17091+{
4bf69007
AM
17092+ return ((tag ^ (unsigned long)sb) % DL_HASH_SIZE);
17093+}
2380c486 17094+
2380c486 17095+
2380c486 17096+
4bf69007 17097+/* __hash_dl_info()
2380c486 17098+
4bf69007
AM
17099+ * add the dli to the global hash table
17100+ * requires the hash_lock to be held */
2380c486 17101+
4bf69007
AM
17102+static inline void __hash_dl_info(struct dl_info *dli)
17103+{
17104+ struct hlist_head *head;
d337f35e 17105+
4bf69007
AM
17106+ vxdprintk(VXD_CBIT(dlim, 6),
17107+ "__hash_dl_info: %p[#%d]", dli, dli->dl_tag);
17108+ get_dl_info(dli);
17109+ head = &dl_info_hash[__hashval(dli->dl_sb, dli->dl_tag)];
17110+ hlist_add_head_rcu(&dli->dl_hlist, head);
17111+}
d337f35e 17112+
4bf69007 17113+/* __unhash_dl_info()
3bac966d 17114+
4bf69007
AM
17115+ * remove the dli from the global hash table
17116+ * requires the hash_lock to be held */
3bac966d 17117+
4bf69007
AM
17118+static inline void __unhash_dl_info(struct dl_info *dli)
17119+{
17120+ vxdprintk(VXD_CBIT(dlim, 6),
17121+ "__unhash_dl_info: %p[#%d]", dli, dli->dl_tag);
17122+ hlist_del_rcu(&dli->dl_hlist);
17123+ put_dl_info(dli);
17124+}
3bac966d 17125+
3bac966d 17126+
4bf69007 17127+/* __lookup_dl_info()
3bac966d 17128+
4bf69007
AM
17129+ * requires the rcu_read_lock()
17130+ * doesn't increment the dl_refcnt */
3bac966d 17131+
61333608 17132+static inline struct dl_info *__lookup_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
17133+{
17134+ struct hlist_head *head = &dl_info_hash[__hashval(sb, tag)];
4bf69007 17135+ struct dl_info *dli;
3bac966d 17136+
b00e13aa
AM
17137+ hlist_for_each_entry_rcu(dli, head, dl_hlist) {
17138+ if (dli->dl_tag == tag && dli->dl_sb == sb)
4bf69007 17139+ return dli;
d33d7b00 17140+ }
4bf69007
AM
17141+ return NULL;
17142+}
3bac966d 17143+
3bac966d 17144+
61333608 17145+struct dl_info *locate_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
17146+{
17147+ struct dl_info *dli;
17148+
17149+ rcu_read_lock();
17150+ dli = get_dl_info(__lookup_dl_info(sb, tag));
17151+ vxdprintk(VXD_CBIT(dlim, 7),
17152+ "locate_dl_info(%p,#%d) = %p", sb, tag, dli);
17153+ rcu_read_unlock();
17154+ return dli;
d33d7b00 17155+}
3bac966d 17156+
4bf69007 17157+void rcu_free_dl_info(struct rcu_head *head)
d33d7b00 17158+{
4bf69007
AM
17159+ struct dl_info *dli = container_of(head, struct dl_info, dl_rcu);
17160+ int usecnt, refcnt;
3bac966d 17161+
4bf69007 17162+ BUG_ON(!dli || !head);
3bac966d 17163+
4bf69007
AM
17164+ usecnt = atomic_read(&dli->dl_usecnt);
17165+ BUG_ON(usecnt < 0);
3bac966d 17166+
4bf69007
AM
17167+ refcnt = atomic_read(&dli->dl_refcnt);
17168+ BUG_ON(refcnt < 0);
17169+
17170+ vxdprintk(VXD_CBIT(dlim, 3),
17171+ "rcu_free_dl_info(%p)", dli);
17172+ if (!usecnt)
17173+ __dealloc_dl_info(dli);
17174+ else
17175+ printk("!!! rcu didn't free\n");
d33d7b00 17176+}
3bac966d 17177+
3bac966d 17178+
4bf69007
AM
17179+
17180+
17181+static int do_addrem_dlimit(uint32_t id, const char __user *name,
17182+ uint32_t flags, int add)
d33d7b00
AM
17183+{
17184+ struct path path;
d33d7b00 17185+ int ret;
3bac966d 17186+
4bf69007 17187+ ret = user_lpath(name, &path);
d33d7b00 17188+ if (!ret) {
4bf69007
AM
17189+ struct super_block *sb;
17190+ struct dl_info *dli;
17191+
17192+ ret = -EINVAL;
17193+ if (!path.dentry->d_inode)
17194+ goto out_release;
17195+ if (!(sb = path.dentry->d_inode->i_sb))
17196+ goto out_release;
17197+
17198+ if (add) {
17199+ dli = __alloc_dl_info(sb, id);
17200+ spin_lock(&dl_info_hash_lock);
17201+
17202+ ret = -EEXIST;
17203+ if (__lookup_dl_info(sb, id))
17204+ goto out_unlock;
17205+ __hash_dl_info(dli);
17206+ dli = NULL;
17207+ } else {
17208+ spin_lock(&dl_info_hash_lock);
17209+ dli = __lookup_dl_info(sb, id);
17210+
17211+ ret = -ESRCH;
17212+ if (!dli)
17213+ goto out_unlock;
17214+ __unhash_dl_info(dli);
17215+ }
17216+ ret = 0;
17217+ out_unlock:
17218+ spin_unlock(&dl_info_hash_lock);
17219+ if (add && dli)
17220+ __dealloc_dl_info(dli);
17221+ out_release:
d33d7b00
AM
17222+ path_put(&path);
17223+ }
d33d7b00
AM
17224+ return ret;
17225+}
3bac966d 17226+
4bf69007 17227+int vc_add_dlimit(uint32_t id, void __user *data)
d33d7b00 17228+{
4bf69007 17229+ struct vcmd_ctx_dlimit_base_v0 vc_data;
3bac966d 17230+
d33d7b00
AM
17231+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17232+ return -EFAULT;
3bac966d 17233+
4bf69007
AM
17234+ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1);
17235+}
3bac966d 17236+
4bf69007
AM
17237+int vc_rem_dlimit(uint32_t id, void __user *data)
17238+{
17239+ struct vcmd_ctx_dlimit_base_v0 vc_data;
3bac966d 17240+
4bf69007 17241+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d33d7b00 17242+ return -EFAULT;
4bf69007
AM
17243+
17244+ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0);
d33d7b00 17245+}
3bac966d 17246+
4bf69007 17247+#ifdef CONFIG_COMPAT
3bac966d 17248+
4bf69007
AM
17249+int vc_add_dlimit_x32(uint32_t id, void __user *data)
17250+{
17251+ struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
3bac966d 17252+
4bf69007
AM
17253+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17254+ return -EFAULT;
d337f35e 17255+
4bf69007
AM
17256+ return do_addrem_dlimit(id,
17257+ compat_ptr(vc_data.name_ptr), vc_data.flags, 1);
17258+}
d337f35e 17259+
4bf69007 17260+int vc_rem_dlimit_x32(uint32_t id, void __user *data)
d33d7b00 17261+{
4bf69007 17262+ struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
d337f35e 17263+
4bf69007
AM
17264+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17265+ return -EFAULT;
17266+
17267+ return do_addrem_dlimit(id,
17268+ compat_ptr(vc_data.name_ptr), vc_data.flags, 0);
d33d7b00 17269+}
d337f35e 17270+
4bf69007
AM
17271+#endif /* CONFIG_COMPAT */
17272+
17273+
17274+static inline
17275+int do_set_dlimit(uint32_t id, const char __user *name,
17276+ uint32_t space_used, uint32_t space_total,
17277+ uint32_t inodes_used, uint32_t inodes_total,
17278+ uint32_t reserved, uint32_t flags)
d33d7b00 17279+{
4bf69007
AM
17280+ struct path path;
17281+ int ret;
ba86f833 17282+
4bf69007
AM
17283+ ret = user_lpath(name, &path);
17284+ if (!ret) {
17285+ struct super_block *sb;
17286+ struct dl_info *dli;
d337f35e 17287+
4bf69007
AM
17288+ ret = -EINVAL;
17289+ if (!path.dentry->d_inode)
17290+ goto out_release;
17291+ if (!(sb = path.dentry->d_inode->i_sb))
17292+ goto out_release;
d337f35e 17293+
4bf69007
AM
17294+ /* sanity checks */
17295+ if ((reserved != CDLIM_KEEP &&
17296+ reserved > 100) ||
17297+ (inodes_used != CDLIM_KEEP &&
17298+ inodes_used > inodes_total) ||
17299+ (space_used != CDLIM_KEEP &&
17300+ space_used > space_total))
17301+ goto out_release;
d337f35e 17302+
4bf69007
AM
17303+ ret = -ESRCH;
17304+ dli = locate_dl_info(sb, id);
17305+ if (!dli)
17306+ goto out_release;
ba86f833 17307+
4bf69007 17308+ spin_lock(&dli->dl_lock);
d337f35e 17309+
4bf69007
AM
17310+ if (inodes_used != CDLIM_KEEP)
17311+ dli->dl_inodes_used = inodes_used;
17312+ if (inodes_total != CDLIM_KEEP)
17313+ dli->dl_inodes_total = inodes_total;
17314+ if (space_used != CDLIM_KEEP)
17315+ dli->dl_space_used = dlimit_space_32to64(
17316+ space_used, flags, DLIMS_USED);
d337f35e 17317+
4bf69007
AM
17318+ if (space_total == CDLIM_INFINITY)
17319+ dli->dl_space_total = DLIM_INFINITY;
17320+ else if (space_total != CDLIM_KEEP)
17321+ dli->dl_space_total = dlimit_space_32to64(
17322+ space_total, flags, DLIMS_TOTAL);
78865d5b 17323+
4bf69007
AM
17324+ if (reserved != CDLIM_KEEP)
17325+ dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100;
78865d5b 17326+
4bf69007 17327+ spin_unlock(&dli->dl_lock);
d337f35e 17328+
4bf69007
AM
17329+ put_dl_info(dli);
17330+ ret = 0;
d337f35e 17331+
4bf69007
AM
17332+ out_release:
17333+ path_put(&path);
17334+ }
17335+ return ret;
17336+}
d337f35e 17337+
4bf69007
AM
17338+int vc_set_dlimit(uint32_t id, void __user *data)
17339+{
17340+ struct vcmd_ctx_dlimit_v0 vc_data;
d337f35e 17341+
4bf69007
AM
17342+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17343+ return -EFAULT;
d337f35e 17344+
4bf69007
AM
17345+ return do_set_dlimit(id, vc_data.name,
17346+ vc_data.space_used, vc_data.space_total,
17347+ vc_data.inodes_used, vc_data.inodes_total,
17348+ vc_data.reserved, vc_data.flags);
17349+}
d337f35e 17350+
4bf69007 17351+#ifdef CONFIG_COMPAT
d337f35e 17352+
4bf69007
AM
17353+int vc_set_dlimit_x32(uint32_t id, void __user *data)
17354+{
17355+ struct vcmd_ctx_dlimit_v0_x32 vc_data;
d337f35e 17356+
4bf69007
AM
17357+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17358+ return -EFAULT;
d337f35e 17359+
4bf69007
AM
17360+ return do_set_dlimit(id, compat_ptr(vc_data.name_ptr),
17361+ vc_data.space_used, vc_data.space_total,
17362+ vc_data.inodes_used, vc_data.inodes_total,
17363+ vc_data.reserved, vc_data.flags);
17364+}
d337f35e 17365+
4bf69007 17366+#endif /* CONFIG_COMPAT */
d337f35e 17367+
d337f35e 17368+
4bf69007
AM
17369+static inline
17370+int do_get_dlimit(uint32_t id, const char __user *name,
17371+ uint32_t *space_used, uint32_t *space_total,
17372+ uint32_t *inodes_used, uint32_t *inodes_total,
17373+ uint32_t *reserved, uint32_t *flags)
17374+{
17375+ struct path path;
17376+ int ret;
d337f35e 17377+
4bf69007
AM
17378+ ret = user_lpath(name, &path);
17379+ if (!ret) {
17380+ struct super_block *sb;
17381+ struct dl_info *dli;
d337f35e 17382+
4bf69007
AM
17383+ ret = -EINVAL;
17384+ if (!path.dentry->d_inode)
17385+ goto out_release;
17386+ if (!(sb = path.dentry->d_inode->i_sb))
17387+ goto out_release;
d337f35e 17388+
4bf69007
AM
17389+ ret = -ESRCH;
17390+ dli = locate_dl_info(sb, id);
17391+ if (!dli)
17392+ goto out_release;
d337f35e 17393+
4bf69007
AM
17394+ spin_lock(&dli->dl_lock);
17395+ *inodes_used = dli->dl_inodes_used;
17396+ *inodes_total = dli->dl_inodes_total;
d337f35e 17397+
4bf69007
AM
17398+ *space_used = dlimit_space_64to32(
17399+ dli->dl_space_used, flags, DLIMS_USED);
d337f35e 17400+
4bf69007
AM
17401+ if (dli->dl_space_total == DLIM_INFINITY)
17402+ *space_total = CDLIM_INFINITY;
17403+ else
17404+ *space_total = dlimit_space_64to32(
17405+ dli->dl_space_total, flags, DLIMS_TOTAL);
d337f35e 17406+
4bf69007
AM
17407+ *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10);
17408+ spin_unlock(&dli->dl_lock);
d337f35e 17409+
4bf69007
AM
17410+ put_dl_info(dli);
17411+ ret = -EFAULT;
d337f35e 17412+
4bf69007
AM
17413+ ret = 0;
17414+ out_release:
17415+ path_put(&path);
17416+ }
17417+ return ret;
d337f35e
JR
17418+}
17419+
4bf69007
AM
17420+
17421+int vc_get_dlimit(uint32_t id, void __user *data)
d337f35e 17422+{
4bf69007 17423+ struct vcmd_ctx_dlimit_v0 vc_data;
d337f35e
JR
17424+ int ret;
17425+
2380c486 17426+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
17427+ return -EFAULT;
17428+
4bf69007
AM
17429+ ret = do_get_dlimit(id, vc_data.name,
17430+ &vc_data.space_used, &vc_data.space_total,
17431+ &vc_data.inodes_used, &vc_data.inodes_total,
17432+ &vc_data.reserved, &vc_data.flags);
d337f35e
JR
17433+ if (ret)
17434+ return ret;
17435+
2380c486 17436+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
17437+ return -EFAULT;
17438+ return 0;
17439+}
17440+
4bf69007 17441+#ifdef CONFIG_COMPAT
d337f35e 17442+
4bf69007 17443+int vc_get_dlimit_x32(uint32_t id, void __user *data)
d337f35e 17444+{
4bf69007 17445+ struct vcmd_ctx_dlimit_v0_x32 vc_data;
d337f35e
JR
17446+ int ret;
17447+
2380c486 17448+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
17449+ return -EFAULT;
17450+
4bf69007
AM
17451+ ret = do_get_dlimit(id, compat_ptr(vc_data.name_ptr),
17452+ &vc_data.space_used, &vc_data.space_total,
17453+ &vc_data.inodes_used, &vc_data.inodes_total,
17454+ &vc_data.reserved, &vc_data.flags);
d337f35e
JR
17455+ if (ret)
17456+ return ret;
17457+
2380c486 17458+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
17459+ return -EFAULT;
17460+ return 0;
17461+}
17462+
4bf69007 17463+#endif /* CONFIG_COMPAT */
ec22aa5c
AM
17464+
17465+
4bf69007 17466+void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf)
ec22aa5c 17467+{
4bf69007
AM
17468+ struct dl_info *dli;
17469+ __u64 blimit, bfree, bavail;
17470+ __u32 ifree;
ec22aa5c 17471+
4bf69007
AM
17472+ dli = locate_dl_info(sb, dx_current_tag());
17473+ if (!dli)
17474+ return;
ec22aa5c 17475+
4bf69007
AM
17476+ spin_lock(&dli->dl_lock);
17477+ if (dli->dl_inodes_total == (unsigned long)DLIM_INFINITY)
17478+ goto no_ilim;
ec22aa5c 17479+
4bf69007
AM
17480+ /* reduce max inodes available to limit */
17481+ if (buf->f_files > dli->dl_inodes_total)
17482+ buf->f_files = dli->dl_inodes_total;
ec22aa5c 17483+
4bf69007
AM
17484+ ifree = dli->dl_inodes_total - dli->dl_inodes_used;
17485+ /* reduce free inodes to min */
17486+ if (ifree < buf->f_ffree)
17487+ buf->f_ffree = ifree;
b2252bc2 17488+
4bf69007
AM
17489+no_ilim:
17490+ if (dli->dl_space_total == DLIM_INFINITY)
17491+ goto no_blim;
d337f35e 17492+
4bf69007 17493+ blimit = dli->dl_space_total >> sb->s_blocksize_bits;
d337f35e 17494+
4bf69007
AM
17495+ if (dli->dl_space_total < dli->dl_space_used)
17496+ bfree = 0;
17497+ else
17498+ bfree = (dli->dl_space_total - dli->dl_space_used)
17499+ >> sb->s_blocksize_bits;
d337f35e 17500+
4bf69007
AM
17501+ bavail = ((dli->dl_space_total >> 10) * dli->dl_nrlmult);
17502+ if (bavail < dli->dl_space_used)
17503+ bavail = 0;
17504+ else
17505+ bavail = (bavail - dli->dl_space_used)
17506+ >> sb->s_blocksize_bits;
d337f35e 17507+
4bf69007
AM
17508+ /* reduce max space available to limit */
17509+ if (buf->f_blocks > blimit)
17510+ buf->f_blocks = blimit;
d337f35e 17511+
4bf69007
AM
17512+ /* reduce free space to min */
17513+ if (bfree < buf->f_bfree)
17514+ buf->f_bfree = bfree;
d337f35e 17515+
4bf69007
AM
17516+ /* reduce avail space to min */
17517+ if (bavail < buf->f_bavail)
17518+ buf->f_bavail = bavail;
d337f35e 17519+
4bf69007
AM
17520+no_blim:
17521+ spin_unlock(&dli->dl_lock);
17522+ put_dl_info(dli);
d337f35e 17523+
4bf69007 17524+ return;
d337f35e
JR
17525+}
17526+
4bf69007 17527+#include <linux/module.h>
d337f35e 17528+
4bf69007
AM
17529+EXPORT_SYMBOL_GPL(locate_dl_info);
17530+EXPORT_SYMBOL_GPL(rcu_free_dl_info);
e3afe727 17531+
f973f73f
AM
17532diff -NurpP --minimal linux-4.1.27/kernel/vserver/helper.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/helper.c
17533--- linux-4.1.27/kernel/vserver/helper.c 1970-01-01 00:00:00.000000000 +0000
17534+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/helper.c 2016-07-05 04:41:47.000000000 +0000
09be7631 17535@@ -0,0 +1,242 @@
4bf69007
AM
17536+/*
17537+ * linux/kernel/vserver/helper.c
17538+ *
17539+ * Virtual Context Support
17540+ *
9e3e8383 17541+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
17542+ *
17543+ * V0.01 basic helper
17544+ *
17545+ */
e3afe727 17546+
4bf69007
AM
17547+#include <linux/kmod.h>
17548+#include <linux/reboot.h>
17549+#include <linux/vs_context.h>
17550+#include <linux/vs_network.h>
17551+#include <linux/vserver/signal.h>
e3afe727 17552+
4bf69007
AM
17553+
17554+char vshelper_path[255] = "/sbin/vshelper";
17555+
17556+static int vshelper_init(struct subprocess_info *info, struct cred *new_cred)
17557+{
09be7631 17558+ current->flags &= ~PF_NO_SETAFFINITY;
4bf69007 17559+ return 0;
d337f35e
JR
17560+}
17561+
09be7631
JR
17562+static int vs_call_usermodehelper(char *path, char **argv, char **envp, int wait)
17563+{
17564+ struct subprocess_info *info;
17565+ gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
17566+
17567+ info = call_usermodehelper_setup(path, argv, envp, gfp_mask,
17568+ vshelper_init, NULL, NULL);
17569+ if (info == NULL)
17570+ return -ENOMEM;
17571+
17572+ return call_usermodehelper_exec(info, wait);
17573+}
17574+
4bf69007 17575+static int do_vshelper(char *name, char *argv[], char *envp[], int sync)
d337f35e 17576+{
4bf69007 17577+ int ret;
e3afe727 17578+
09be7631
JR
17579+ if ((ret = vs_call_usermodehelper(name, argv, envp,
17580+ sync ? UMH_WAIT_PROC : UMH_WAIT_EXEC))) {
4bf69007
AM
17581+ printk(KERN_WARNING "%s: (%s %s) returned %s with %d\n",
17582+ name, argv[1], argv[2],
17583+ sync ? "sync" : "async", ret);
17584+ }
17585+ vxdprintk(VXD_CBIT(switch, 4),
17586+ "%s: (%s %s) returned %s with %d",
17587+ name, argv[1], argv[2], sync ? "sync" : "async", ret);
17588+ return ret;
17589+}
e3afe727 17590+
4bf69007
AM
17591+/*
17592+ * vshelper path is set via /proc/sys
17593+ * invoked by vserver sys_reboot(), with
17594+ * the following arguments
17595+ *
17596+ * argv [0] = vshelper_path;
17597+ * argv [1] = action: "restart", "halt", "poweroff", ...
17598+ * argv [2] = context identifier
17599+ *
17600+ * envp [*] = type-specific parameters
17601+ */
e3afe727 17602+
4bf69007
AM
17603+long vs_reboot_helper(struct vx_info *vxi, int cmd, void __user *arg)
17604+{
17605+ char id_buf[8], cmd_buf[16];
17606+ char uid_buf[16], pid_buf[16];
17607+ int ret;
e3afe727 17608+
4bf69007
AM
17609+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17610+ char *envp[] = {"HOME=/", "TERM=linux",
17611+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
17612+ uid_buf, pid_buf, cmd_buf, 0};
e3afe727 17613+
4bf69007
AM
17614+ if (vx_info_state(vxi, VXS_HELPER))
17615+ return -EAGAIN;
17616+ vxi->vx_state |= VXS_HELPER;
7b17263b 17617+
4bf69007 17618+ snprintf(id_buf, sizeof(id_buf), "%d", vxi->vx_id);
d337f35e 17619+
4bf69007 17620+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
8ce283e1
AM
17621+ snprintf(uid_buf, sizeof(uid_buf), "VS_UID=%d",
17622+ from_kuid(&init_user_ns, current_uid()));
4bf69007 17623+ snprintf(pid_buf, sizeof(pid_buf), "VS_PID=%d", current->pid);
e3afe727 17624+
4bf69007
AM
17625+ switch (cmd) {
17626+ case LINUX_REBOOT_CMD_RESTART:
17627+ argv[1] = "restart";
17628+ break;
07a627a5 17629+
4bf69007
AM
17630+ case LINUX_REBOOT_CMD_HALT:
17631+ argv[1] = "halt";
17632+ break;
e3afe727 17633+
4bf69007
AM
17634+ case LINUX_REBOOT_CMD_POWER_OFF:
17635+ argv[1] = "poweroff";
17636+ break;
d337f35e 17637+
4bf69007
AM
17638+ case LINUX_REBOOT_CMD_SW_SUSPEND:
17639+ argv[1] = "swsusp";
17640+ break;
d337f35e 17641+
4bf69007
AM
17642+ case LINUX_REBOOT_CMD_OOM:
17643+ argv[1] = "oom";
17644+ break;
d337f35e 17645+
4bf69007
AM
17646+ default:
17647+ vxi->vx_state &= ~VXS_HELPER;
17648+ return 0;
d337f35e 17649+ }
4bf69007
AM
17650+
17651+ ret = do_vshelper(vshelper_path, argv, envp, 0);
17652+ vxi->vx_state &= ~VXS_HELPER;
17653+ __wakeup_vx_info(vxi);
17654+ return (ret) ? -EPERM : 0;
d337f35e
JR
17655+}
17656+
4bf69007
AM
17657+
17658+long vs_reboot(unsigned int cmd, void __user *arg)
d337f35e 17659+{
4bf69007
AM
17660+ struct vx_info *vxi = current_vx_info();
17661+ long ret = 0;
d337f35e 17662+
4bf69007
AM
17663+ vxdprintk(VXD_CBIT(misc, 5),
17664+ "vs_reboot(%p[#%d],%u)",
17665+ vxi, vxi ? vxi->vx_id : 0, cmd);
17666+
17667+ ret = vs_reboot_helper(vxi, cmd, arg);
17668+ if (ret)
17669+ return ret;
17670+
17671+ vxi->reboot_cmd = cmd;
17672+ if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
17673+ switch (cmd) {
17674+ case LINUX_REBOOT_CMD_RESTART:
17675+ case LINUX_REBOOT_CMD_HALT:
17676+ case LINUX_REBOOT_CMD_POWER_OFF:
17677+ vx_info_kill(vxi, 0, SIGKILL);
17678+ vx_info_kill(vxi, 1, SIGKILL);
17679+ default:
17680+ break;
17681+ }
d337f35e 17682+ }
4bf69007 17683+ return 0;
d337f35e
JR
17684+}
17685+
4bf69007
AM
17686+long vs_oom_action(unsigned int cmd)
17687+{
17688+ struct vx_info *vxi = current_vx_info();
17689+ long ret = 0;
d337f35e 17690+
4bf69007
AM
17691+ vxdprintk(VXD_CBIT(misc, 5),
17692+ "vs_oom_action(%p[#%d],%u)",
17693+ vxi, vxi ? vxi->vx_id : 0, cmd);
d337f35e 17694+
4bf69007
AM
17695+ ret = vs_reboot_helper(vxi, cmd, NULL);
17696+ if (ret)
17697+ return ret;
d337f35e 17698+
4bf69007
AM
17699+ vxi->reboot_cmd = cmd;
17700+ if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
17701+ vx_info_kill(vxi, 0, SIGKILL);
17702+ vx_info_kill(vxi, 1, SIGKILL);
17703+ }
17704+ return 0;
17705+}
d337f35e 17706+
4bf69007
AM
17707+/*
17708+ * argv [0] = vshelper_path;
17709+ * argv [1] = action: "startup", "shutdown"
17710+ * argv [2] = context identifier
17711+ *
17712+ * envp [*] = type-specific parameters
17713+ */
d337f35e 17714+
4bf69007 17715+long vs_state_change(struct vx_info *vxi, unsigned int cmd)
d337f35e 17716+{
4bf69007
AM
17717+ char id_buf[8], cmd_buf[16];
17718+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17719+ char *envp[] = {"HOME=/", "TERM=linux",
17720+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
17721+
17722+ if (!vx_info_flags(vxi, VXF_SC_HELPER, 0))
17723+ return 0;
17724+
17725+ snprintf(id_buf, sizeof(id_buf), "%d", vxi->vx_id);
17726+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17727+
17728+ switch (cmd) {
17729+ case VSC_STARTUP:
17730+ argv[1] = "startup";
17731+ break;
17732+ case VSC_SHUTDOWN:
17733+ argv[1] = "shutdown";
17734+ break;
17735+ default:
17736+ return 0;
17737+ }
17738+
17739+ return do_vshelper(vshelper_path, argv, envp, 1);
d337f35e
JR
17740+}
17741+
d337f35e 17742+
4bf69007
AM
17743+/*
17744+ * argv [0] = vshelper_path;
17745+ * argv [1] = action: "netup", "netdown"
17746+ * argv [2] = context identifier
17747+ *
17748+ * envp [*] = type-specific parameters
17749+ */
17750+
17751+long vs_net_change(struct nx_info *nxi, unsigned int cmd)
17752+{
17753+ char id_buf[8], cmd_buf[16];
17754+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17755+ char *envp[] = {"HOME=/", "TERM=linux",
17756+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
17757+
17758+ if (!nx_info_flags(nxi, NXF_SC_HELPER, 0))
17759+ return 0;
17760+
17761+ snprintf(id_buf, sizeof(id_buf), "%d", nxi->nx_id);
17762+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17763+
17764+ switch (cmd) {
17765+ case VSC_NETUP:
17766+ argv[1] = "netup";
17767+ break;
17768+ case VSC_NETDOWN:
17769+ argv[1] = "netdown";
17770+ break;
17771+ default:
17772+ return 0;
17773+ }
17774+
17775+ return do_vshelper(vshelper_path, argv, envp, 1);
17776+}
d337f35e 17777+
f973f73f
AM
17778diff -NurpP --minimal linux-4.1.27/kernel/vserver/history.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/history.c
17779--- linux-4.1.27/kernel/vserver/history.c 1970-01-01 00:00:00.000000000 +0000
17780+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/history.c 2016-07-05 04:41:47.000000000 +0000
4bf69007 17781@@ -0,0 +1,258 @@
d337f35e 17782+/*
4bf69007 17783+ * kernel/vserver/history.c
d337f35e 17784+ *
4bf69007 17785+ * Virtual Context History Backtrace
d337f35e 17786+ *
9e3e8383 17787+ * Copyright (C) 2004-2007 Herbert P?tzl
d337f35e 17788+ *
4bf69007
AM
17789+ * V0.01 basic structure
17790+ * V0.02 hash/unhash and trace
17791+ * V0.03 preemption fixes
d337f35e
JR
17792+ *
17793+ */
17794+
4bf69007
AM
17795+#include <linux/module.h>
17796+#include <asm/uaccess.h>
d337f35e 17797+
4bf69007
AM
17798+#include <linux/vserver/context.h>
17799+#include <linux/vserver/debug.h>
17800+#include <linux/vserver/debug_cmd.h>
17801+#include <linux/vserver/history.h>
d337f35e
JR
17802+
17803+
4bf69007
AM
17804+#ifdef CONFIG_VSERVER_HISTORY
17805+#define VXH_SIZE CONFIG_VSERVER_HISTORY_SIZE
17806+#else
17807+#define VXH_SIZE 64
17808+#endif
d337f35e 17809+
4bf69007
AM
17810+struct _vx_history {
17811+ unsigned int counter;
2380c486 17812+
4bf69007
AM
17813+ struct _vx_hist_entry entry[VXH_SIZE + 1];
17814+};
2380c486 17815+
2380c486 17816+
4bf69007 17817+DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
2380c486 17818+
4bf69007 17819+unsigned volatile int vxh_active = 1;
2380c486 17820+
4bf69007 17821+static atomic_t sequence = ATOMIC_INIT(0);
2380c486 17822+
2380c486 17823+
4bf69007 17824+/* vxh_advance()
2380c486 17825+
4bf69007
AM
17826+ * requires disabled preemption */
17827+
17828+struct _vx_hist_entry *vxh_advance(void *loc)
2380c486 17829+{
4bf69007
AM
17830+ unsigned int cpu = smp_processor_id();
17831+ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
17832+ struct _vx_hist_entry *entry;
17833+ unsigned int index;
17834+
17835+ index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
17836+ entry = &hist->entry[index];
17837+
17838+ entry->seq = atomic_inc_return(&sequence);
17839+ entry->loc = loc;
17840+ return entry;
2380c486
JR
17841+}
17842+
4bf69007 17843+EXPORT_SYMBOL_GPL(vxh_advance);
2380c486 17844+
2380c486 17845+
4bf69007 17846+#define VXH_LOC_FMTS "(#%04x,*%d):%p"
2380c486 17847+
4bf69007 17848+#define VXH_LOC_ARGS(e) (e)->seq, cpu, (e)->loc
2380c486 17849+
2380c486 17850+
4bf69007 17851+#define VXH_VXI_FMTS "%p[#%d,%d.%d]"
2380c486 17852+
4bf69007
AM
17853+#define VXH_VXI_ARGS(e) (e)->vxi.ptr, \
17854+ (e)->vxi.ptr ? (e)->vxi.xid : 0, \
17855+ (e)->vxi.ptr ? (e)->vxi.usecnt : 0, \
17856+ (e)->vxi.ptr ? (e)->vxi.tasks : 0
17857+
17858+void vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
2380c486 17859+{
4bf69007
AM
17860+ switch (e->type) {
17861+ case VXH_THROW_OOPS:
17862+ printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
17863+ break;
2380c486 17864+
4bf69007
AM
17865+ case VXH_GET_VX_INFO:
17866+ case VXH_PUT_VX_INFO:
17867+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
17868+ VXH_LOC_ARGS(e),
17869+ (e->type == VXH_GET_VX_INFO) ? "get" : "put",
17870+ VXH_VXI_ARGS(e));
17871+ break;
2380c486 17872+
4bf69007
AM
17873+ case VXH_INIT_VX_INFO:
17874+ case VXH_SET_VX_INFO:
17875+ case VXH_CLR_VX_INFO:
17876+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
17877+ VXH_LOC_ARGS(e),
17878+ (e->type == VXH_INIT_VX_INFO) ? "init" :
17879+ ((e->type == VXH_SET_VX_INFO) ? "set" : "clr"),
17880+ VXH_VXI_ARGS(e), e->sc.data);
17881+ break;
2380c486 17882+
4bf69007
AM
17883+ case VXH_CLAIM_VX_INFO:
17884+ case VXH_RELEASE_VX_INFO:
17885+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
17886+ VXH_LOC_ARGS(e),
17887+ (e->type == VXH_CLAIM_VX_INFO) ? "claim" : "release",
17888+ VXH_VXI_ARGS(e), e->sc.data);
17889+ break;
2380c486 17890+
4bf69007
AM
17891+ case VXH_ALLOC_VX_INFO:
17892+ case VXH_DEALLOC_VX_INFO:
17893+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
17894+ VXH_LOC_ARGS(e),
17895+ (e->type == VXH_ALLOC_VX_INFO) ? "alloc" : "dealloc",
17896+ VXH_VXI_ARGS(e));
17897+ break;
2380c486 17898+
4bf69007
AM
17899+ case VXH_HASH_VX_INFO:
17900+ case VXH_UNHASH_VX_INFO:
17901+ printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
17902+ VXH_LOC_ARGS(e),
17903+ (e->type == VXH_HASH_VX_INFO) ? "hash" : "unhash",
17904+ VXH_VXI_ARGS(e));
17905+ break;
2380c486 17906+
4bf69007
AM
17907+ case VXH_LOC_VX_INFO:
17908+ case VXH_LOOKUP_VX_INFO:
17909+ case VXH_CREATE_VX_INFO:
17910+ printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
17911+ VXH_LOC_ARGS(e),
17912+ (e->type == VXH_CREATE_VX_INFO) ? "create" :
17913+ ((e->type == VXH_LOC_VX_INFO) ? "loc" : "lookup"),
17914+ e->ll.arg, VXH_VXI_ARGS(e));
17915+ break;
2380c486
JR
17916+ }
17917+}
17918+
4bf69007
AM
17919+static void __vxh_dump_history(void)
17920+{
17921+ unsigned int i, cpu;
d337f35e 17922+
4bf69007
AM
17923+ printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
17924+ atomic_read(&sequence), NR_CPUS);
d337f35e 17925+
4bf69007
AM
17926+ for (i = 0; i < VXH_SIZE; i++) {
17927+ for_each_online_cpu(cpu) {
17928+ struct _vx_history *hist =
17929+ &per_cpu(vx_history_buffer, cpu);
17930+ unsigned int index = (hist->counter - i) % VXH_SIZE;
17931+ struct _vx_hist_entry *entry = &hist->entry[index];
d337f35e 17932+
4bf69007
AM
17933+ vxh_dump_entry(entry, cpu);
17934+ }
17935+ }
17936+}
d337f35e 17937+
4bf69007
AM
17938+void vxh_dump_history(void)
17939+{
17940+ vxh_active = 0;
17941+#ifdef CONFIG_SMP
17942+ local_irq_enable();
17943+ smp_send_stop();
17944+ local_irq_disable();
17945+#endif
17946+ __vxh_dump_history();
17947+}
d337f35e 17948+
d337f35e 17949+
4bf69007 17950+/* vserver syscall commands below here */
d337f35e 17951+
d337f35e 17952+
4bf69007
AM
17953+int vc_dump_history(uint32_t id)
17954+{
17955+ vxh_active = 0;
17956+ __vxh_dump_history();
17957+ vxh_active = 1;
2380c486 17958+
4bf69007 17959+ return 0;
d337f35e
JR
17960+}
17961+
d337f35e 17962+
4bf69007
AM
17963+int do_read_history(struct __user _vx_hist_entry *data,
17964+ int cpu, uint32_t *index, uint32_t *count)
d337f35e 17965+{
4bf69007
AM
17966+ int pos, ret = 0;
17967+ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
17968+ int end = hist->counter;
17969+ int start = end - VXH_SIZE + 2;
17970+ int idx = *index;
d337f35e 17971+
4bf69007
AM
17972+ /* special case: get current pos */
17973+ if (!*count) {
17974+ *index = end;
17975+ return 0;
17976+ }
d337f35e 17977+
4bf69007
AM
17978+ /* have we lost some data? */
17979+ if (idx < start)
17980+ idx = start;
d337f35e 17981+
4bf69007
AM
17982+ for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
17983+ struct _vx_hist_entry *entry =
17984+ &hist->entry[idx % VXH_SIZE];
2380c486 17985+
4bf69007
AM
17986+ /* send entry to userspace */
17987+ ret = copy_to_user(&data[pos], entry, sizeof(*entry));
17988+ if (ret)
17989+ break;
17990+ }
17991+ /* save new index and count */
17992+ *index = idx;
17993+ *count = pos;
17994+ return ret ? ret : (*index < end);
d337f35e
JR
17995+}
17996+
4bf69007 17997+int vc_read_history(uint32_t id, void __user *data)
d337f35e 17998+{
4bf69007
AM
17999+ struct vcmd_read_history_v0 vc_data;
18000+ int ret;
d337f35e 18001+
4bf69007
AM
18002+ if (id >= NR_CPUS)
18003+ return -EINVAL;
d337f35e 18004+
4bf69007
AM
18005+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18006+ return -EFAULT;
d337f35e 18007+
4bf69007
AM
18008+ ret = do_read_history((struct __user _vx_hist_entry *)vc_data.data,
18009+ id, &vc_data.index, &vc_data.count);
d337f35e 18010+
4bf69007
AM
18011+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18012+ return -EFAULT;
18013+ return ret;
d337f35e
JR
18014+}
18015+
4bf69007 18016+#ifdef CONFIG_COMPAT
d337f35e 18017+
4bf69007 18018+int vc_read_history_x32(uint32_t id, void __user *data)
d337f35e 18019+{
4bf69007
AM
18020+ struct vcmd_read_history_v0_x32 vc_data;
18021+ int ret;
d337f35e 18022+
4bf69007
AM
18023+ if (id >= NR_CPUS)
18024+ return -EINVAL;
d337f35e 18025+
4bf69007
AM
18026+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18027+ return -EFAULT;
2380c486 18028+
4bf69007
AM
18029+ ret = do_read_history((struct __user _vx_hist_entry *)
18030+ compat_ptr(vc_data.data_ptr),
18031+ id, &vc_data.index, &vc_data.count);
d337f35e 18032+
4bf69007
AM
18033+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18034+ return -EFAULT;
18035+ return ret;
18036+}
d337f35e 18037+
4bf69007 18038+#endif /* CONFIG_COMPAT */
d337f35e 18039+
f973f73f
AM
18040diff -NurpP --minimal linux-4.1.27/kernel/vserver/inet.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/inet.c
18041--- linux-4.1.27/kernel/vserver/inet.c 1970-01-01 00:00:00.000000000 +0000
18042+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/inet.c 2016-07-05 04:41:47.000000000 +0000
7a9e40b8 18043@@ -0,0 +1,236 @@
d337f35e 18044+
4bf69007
AM
18045+#include <linux/in.h>
18046+#include <linux/inetdevice.h>
18047+#include <linux/export.h>
18048+#include <linux/vs_inet.h>
18049+#include <linux/vs_inet6.h>
18050+#include <linux/vserver/debug.h>
18051+#include <net/route.h>
18052+#include <net/addrconf.h>
d337f35e
JR
18053+
18054+
4bf69007 18055+int nx_v4_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
d337f35e 18056+{
4bf69007
AM
18057+ int ret = 0;
18058+
18059+ if (!nxi1 || !nxi2 || nxi1 == nxi2)
18060+ ret = 1;
18061+ else {
18062+ struct nx_addr_v4 *ptr;
7a9e40b8 18063+ unsigned long irqflags;
d337f35e 18064+
7a9e40b8 18065+ spin_lock_irqsave(&nxi1->addr_lock, irqflags);
4bf69007
AM
18066+ for (ptr = &nxi1->v4; ptr; ptr = ptr->next) {
18067+ if (v4_nx_addr_in_nx_info(nxi2, ptr, -1)) {
18068+ ret = 1;
18069+ break;
18070+ }
18071+ }
7a9e40b8 18072+ spin_unlock_irqrestore(&nxi1->addr_lock, irqflags);
4bf69007 18073+ }
d337f35e 18074+
4bf69007
AM
18075+ vxdprintk(VXD_CBIT(net, 2),
18076+ "nx_v4_addr_conflict(%p,%p): %d",
18077+ nxi1, nxi2, ret);
d337f35e 18078+
4bf69007
AM
18079+ return ret;
18080+}
d337f35e 18081+
d337f35e 18082+
4bf69007
AM
18083+#ifdef CONFIG_IPV6
18084+
18085+int nx_v6_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
d337f35e 18086+{
4bf69007 18087+ int ret = 0;
d337f35e 18088+
4bf69007
AM
18089+ if (!nxi1 || !nxi2 || nxi1 == nxi2)
18090+ ret = 1;
18091+ else {
18092+ struct nx_addr_v6 *ptr;
7a9e40b8 18093+ unsigned long irqflags;
d337f35e 18094+
7a9e40b8 18095+ spin_lock_irqsave(&nxi1->addr_lock, irqflags);
4bf69007
AM
18096+ for (ptr = &nxi1->v6; ptr; ptr = ptr->next) {
18097+ if (v6_nx_addr_in_nx_info(nxi2, ptr, -1)) {
18098+ ret = 1;
18099+ break;
18100+ }
18101+ }
7a9e40b8 18102+ spin_unlock_irqrestore(&nxi1->addr_lock, irqflags);
4bf69007 18103+ }
d337f35e 18104+
4bf69007
AM
18105+ vxdprintk(VXD_CBIT(net, 2),
18106+ "nx_v6_addr_conflict(%p,%p): %d",
18107+ nxi1, nxi2, ret);
d337f35e 18108+
4bf69007
AM
18109+ return ret;
18110+}
d337f35e 18111+
4bf69007 18112+#endif
d337f35e 18113+
4bf69007 18114+int v4_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
d337f35e 18115+{
4bf69007
AM
18116+ struct in_device *in_dev;
18117+ struct in_ifaddr **ifap;
18118+ struct in_ifaddr *ifa;
18119+ int ret = 0;
d337f35e 18120+
4bf69007
AM
18121+ if (!dev)
18122+ goto out;
18123+ in_dev = in_dev_get(dev);
18124+ if (!in_dev)
18125+ goto out;
d337f35e 18126+
4bf69007
AM
18127+ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
18128+ ifap = &ifa->ifa_next) {
18129+ if (v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW)) {
18130+ ret = 1;
18131+ break;
18132+ }
18133+ }
18134+ in_dev_put(in_dev);
18135+out:
18136+ return ret;
d337f35e
JR
18137+}
18138+
18139+
4bf69007 18140+#ifdef CONFIG_IPV6
d337f35e 18141+
4bf69007 18142+int v6_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
d337f35e 18143+{
4bf69007
AM
18144+ struct inet6_dev *in_dev;
18145+ struct inet6_ifaddr *ifa;
18146+ int ret = 0;
d337f35e 18147+
4bf69007
AM
18148+ if (!dev)
18149+ goto out;
18150+ in_dev = in6_dev_get(dev);
18151+ if (!in_dev)
18152+ goto out;
d337f35e 18153+
4bf69007
AM
18154+ // for (ifap = &in_dev->addr_list; (ifa = *ifap) != NULL;
18155+ list_for_each_entry(ifa, &in_dev->addr_list, if_list) {
18156+ if (v6_addr_in_nx_info(nxi, &ifa->addr, -1)) {
18157+ ret = 1;
18158+ break;
18159+ }
d337f35e 18160+ }
4bf69007
AM
18161+ in6_dev_put(in_dev);
18162+out:
18163+ return ret;
d337f35e
JR
18164+}
18165+
4bf69007 18166+#endif
d337f35e 18167+
4bf69007
AM
18168+int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
18169+{
18170+ int ret = 1;
d337f35e 18171+
4bf69007
AM
18172+ if (!nxi)
18173+ goto out;
18174+ if (nxi->v4.type && v4_dev_in_nx_info(dev, nxi))
18175+ goto out;
18176+#ifdef CONFIG_IPV6
18177+ ret = 2;
18178+ if (nxi->v6.type && v6_dev_in_nx_info(dev, nxi))
18179+ goto out;
18180+#endif
18181+ ret = 0;
18182+out:
18183+ vxdprintk(VXD_CBIT(net, 3),
18184+ "dev_in_nx_info(%p,%p[#%d]) = %d",
18185+ dev, nxi, nxi ? nxi->nx_id : 0, ret);
18186+ return ret;
18187+}
d337f35e 18188+
4bf69007
AM
18189+struct rtable *ip_v4_find_src(struct net *net, struct nx_info *nxi,
18190+ struct flowi4 *fl4)
d337f35e 18191+{
4bf69007 18192+ struct rtable *rt;
d337f35e 18193+
4bf69007
AM
18194+ if (!nxi)
18195+ return NULL;
d337f35e 18196+
4bf69007
AM
18197+ /* FIXME: handle lback only case */
18198+ if (!NX_IPV4(nxi))
18199+ return ERR_PTR(-EPERM);
d337f35e 18200+
4bf69007
AM
18201+ vxdprintk(VXD_CBIT(net, 4),
18202+ "ip_v4_find_src(%p[#%u]) " NIPQUAD_FMT " -> " NIPQUAD_FMT,
18203+ nxi, nxi ? nxi->nx_id : 0,
18204+ NIPQUAD(fl4->saddr), NIPQUAD(fl4->daddr));
d337f35e 18205+
4bf69007
AM
18206+ /* single IP is unconditional */
18207+ if (nx_info_flags(nxi, NXF_SINGLE_IP, 0) &&
18208+ (fl4->saddr == INADDR_ANY))
18209+ fl4->saddr = nxi->v4.ip[0].s_addr;
d337f35e 18210+
4bf69007
AM
18211+ if (fl4->saddr == INADDR_ANY) {
18212+ struct nx_addr_v4 *ptr;
18213+ __be32 found = 0;
18214+
18215+ rt = __ip_route_output_key(net, fl4);
18216+ if (!IS_ERR(rt)) {
18217+ found = fl4->saddr;
18218+ ip_rt_put(rt);
18219+ vxdprintk(VXD_CBIT(net, 4),
18220+ "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
18221+ nxi, nxi ? nxi->nx_id : 0, fl4->flowi4_oif, NIPQUAD(found));
18222+ if (v4_addr_in_nx_info(nxi, found, NXA_MASK_BIND))
18223+ goto found;
18224+ }
d337f35e 18225+
8d50a2ea 18226+ WARN_ON_ONCE(in_irq());
b00e13aa 18227+ spin_lock_bh(&nxi->addr_lock);
4bf69007
AM
18228+ for (ptr = &nxi->v4; ptr; ptr = ptr->next) {
18229+ __be32 primary = ptr->ip[0].s_addr;
18230+ __be32 mask = ptr->mask.s_addr;
18231+ __be32 neta = primary & mask;
d337f35e 18232+
4bf69007
AM
18233+ vxdprintk(VXD_CBIT(net, 4), "ip_v4_find_src(%p[#%u]) chk: "
18234+ NIPQUAD_FMT "/" NIPQUAD_FMT "/" NIPQUAD_FMT,
18235+ nxi, nxi ? nxi->nx_id : 0, NIPQUAD(primary),
18236+ NIPQUAD(mask), NIPQUAD(neta));
18237+ if ((found & mask) != neta)
18238+ continue;
d337f35e 18239+
4bf69007
AM
18240+ fl4->saddr = primary;
18241+ rt = __ip_route_output_key(net, fl4);
18242+ vxdprintk(VXD_CBIT(net, 4),
18243+ "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
18244+ nxi, nxi ? nxi->nx_id : 0, fl4->flowi4_oif, NIPQUAD(primary));
18245+ if (!IS_ERR(rt)) {
18246+ found = fl4->saddr;
18247+ ip_rt_put(rt);
18248+ if (found == primary)
5cb1760b 18249+ goto found_unlock;
4bf69007
AM
18250+ }
18251+ }
18252+ /* still no source ip? */
18253+ found = ipv4_is_loopback(fl4->daddr)
18254+ ? IPI_LOOPBACK : nxi->v4.ip[0].s_addr;
5cb1760b 18255+ found_unlock:
b00e13aa 18256+ spin_unlock_bh(&nxi->addr_lock);
4bf69007
AM
18257+ found:
18258+ /* assign src ip to flow */
18259+ fl4->saddr = found;
18260+
18261+ } else {
18262+ if (!v4_addr_in_nx_info(nxi, fl4->saddr, NXA_MASK_BIND))
18263+ return ERR_PTR(-EPERM);
18264+ }
d337f35e 18265+
4bf69007
AM
18266+ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0)) {
18267+ if (ipv4_is_loopback(fl4->daddr))
18268+ fl4->daddr = nxi->v4_lback.s_addr;
18269+ if (ipv4_is_loopback(fl4->saddr))
18270+ fl4->saddr = nxi->v4_lback.s_addr;
18271+ } else if (ipv4_is_loopback(fl4->daddr) &&
18272+ !nx_info_flags(nxi, NXF_LBACK_ALLOW, 0))
18273+ return ERR_PTR(-EPERM);
d337f35e 18274+
4bf69007 18275+ return NULL;
d337f35e
JR
18276+}
18277+
4bf69007 18278+EXPORT_SYMBOL_GPL(ip_v4_find_src);
d337f35e 18279+
f973f73f
AM
18280diff -NurpP --minimal linux-4.1.27/kernel/vserver/init.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/init.c
18281--- linux-4.1.27/kernel/vserver/init.c 1970-01-01 00:00:00.000000000 +0000
18282+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/init.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
18283@@ -0,0 +1,45 @@
18284+/*
18285+ * linux/kernel/init.c
18286+ *
18287+ * Virtual Server Init
18288+ *
9e3e8383 18289+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
18290+ *
18291+ * V0.01 basic structure
18292+ *
18293+ */
d337f35e 18294+
4bf69007
AM
18295+#include <linux/init.h>
18296+
18297+int vserver_register_sysctl(void);
18298+void vserver_unregister_sysctl(void);
18299+
18300+
18301+static int __init init_vserver(void)
d337f35e 18302+{
4bf69007 18303+ int ret = 0;
d337f35e 18304+
4bf69007
AM
18305+#ifdef CONFIG_VSERVER_DEBUG
18306+ vserver_register_sysctl();
18307+#endif
18308+ return ret;
d337f35e
JR
18309+}
18310+
d337f35e 18311+
4bf69007 18312+static void __exit exit_vserver(void)
d337f35e 18313+{
d337f35e 18314+
4bf69007
AM
18315+#ifdef CONFIG_VSERVER_DEBUG
18316+ vserver_unregister_sysctl();
18317+#endif
18318+ return;
d337f35e
JR
18319+}
18320+
4bf69007
AM
18321+/* FIXME: GFP_ZONETYPES gone
18322+long vx_slab[GFP_ZONETYPES]; */
18323+long vx_area;
d337f35e 18324+
d337f35e 18325+
4bf69007
AM
18326+module_init(init_vserver);
18327+module_exit(exit_vserver);
d337f35e 18328+
f973f73f
AM
18329diff -NurpP --minimal linux-4.1.27/kernel/vserver/inode.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/inode.c
18330--- linux-4.1.27/kernel/vserver/inode.c 1970-01-01 00:00:00.000000000 +0000
18331+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/inode.c 2016-07-05 04:41:47.000000000 +0000
09be7631 18332@@ -0,0 +1,440 @@
4bf69007
AM
18333+/*
18334+ * linux/kernel/vserver/inode.c
18335+ *
18336+ * Virtual Server: File System Support
18337+ *
9e3e8383 18338+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
18339+ *
18340+ * V0.01 separated from vcontext V0.05
18341+ * V0.02 moved to tag (instead of xid)
18342+ *
18343+ */
d337f35e 18344+
4bf69007
AM
18345+#include <linux/tty.h>
18346+#include <linux/proc_fs.h>
18347+#include <linux/devpts_fs.h>
18348+#include <linux/fs.h>
18349+#include <linux/file.h>
18350+#include <linux/mount.h>
18351+#include <linux/parser.h>
18352+#include <linux/namei.h>
09be7631
JR
18353+#include <linux/magic.h>
18354+#include <linux/slab.h>
4bf69007
AM
18355+#include <linux/vserver/inode.h>
18356+#include <linux/vserver/inode_cmd.h>
18357+#include <linux/vs_base.h>
18358+#include <linux/vs_tag.h>
d337f35e 18359+
4bf69007 18360+#include <asm/uaccess.h>
09be7631 18361+#include <../../fs/proc/internal.h>
d337f35e 18362+
d337f35e 18363+
4bf69007 18364+static int __vc_get_iattr(struct inode *in, uint32_t *tag, uint32_t *flags, uint32_t *mask)
d337f35e 18365+{
4bf69007 18366+ struct proc_dir_entry *entry;
d337f35e 18367+
4bf69007
AM
18368+ if (!in || !in->i_sb)
18369+ return -ESRCH;
d337f35e 18370+
4bf69007
AM
18371+ *flags = IATTR_TAG
18372+ | (IS_IMMUTABLE(in) ? IATTR_IMMUTABLE : 0)
18373+ | (IS_IXUNLINK(in) ? IATTR_IXUNLINK : 0)
18374+ | (IS_BARRIER(in) ? IATTR_BARRIER : 0)
18375+ | (IS_COW(in) ? IATTR_COW : 0);
18376+ *mask = IATTR_IXUNLINK | IATTR_IMMUTABLE | IATTR_COW;
d337f35e 18377+
4bf69007
AM
18378+ if (S_ISDIR(in->i_mode))
18379+ *mask |= IATTR_BARRIER;
d337f35e 18380+
4bf69007
AM
18381+ if (IS_TAGGED(in)) {
18382+ *tag = i_tag_read(in);
18383+ *mask |= IATTR_TAG;
18384+ }
2380c486 18385+
4bf69007
AM
18386+ switch (in->i_sb->s_magic) {
18387+ case PROC_SUPER_MAGIC:
18388+ entry = PROC_I(in)->pde;
d337f35e 18389+
4bf69007
AM
18390+ /* check for specific inodes? */
18391+ if (entry)
18392+ *mask |= IATTR_FLAGS;
18393+ if (entry)
18394+ *flags |= (entry->vx_flags & IATTR_FLAGS);
18395+ else
18396+ *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS);
18397+ break;
d337f35e 18398+
4bf69007
AM
18399+ case DEVPTS_SUPER_MAGIC:
18400+ *tag = i_tag_read(in);
18401+ *mask |= IATTR_TAG;
18402+ break;
d337f35e 18403+
4bf69007
AM
18404+ default:
18405+ break;
18406+ }
18407+ return 0;
d337f35e
JR
18408+}
18409+
4bf69007 18410+int vc_get_iattr(void __user *data)
d337f35e 18411+{
4bf69007
AM
18412+ struct path path;
18413+ struct vcmd_ctx_iattr_v1 vc_data = { .tag = -1 };
18414+ int ret;
d337f35e 18415+
4bf69007
AM
18416+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18417+ return -EFAULT;
d337f35e 18418+
4bf69007
AM
18419+ ret = user_lpath(vc_data.name, &path);
18420+ if (!ret) {
18421+ ret = __vc_get_iattr(path.dentry->d_inode,
18422+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18423+ path_put(&path);
18424+ }
18425+ if (ret)
18426+ return ret;
d337f35e 18427+
4bf69007
AM
18428+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18429+ ret = -EFAULT;
18430+ return ret;
d337f35e
JR
18431+}
18432+
4bf69007 18433+#ifdef CONFIG_COMPAT
d337f35e 18434+
4bf69007 18435+int vc_get_iattr_x32(void __user *data)
d337f35e 18436+{
4bf69007
AM
18437+ struct path path;
18438+ struct vcmd_ctx_iattr_v1_x32 vc_data = { .tag = -1 };
18439+ int ret;
d337f35e 18440+
4bf69007
AM
18441+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18442+ return -EFAULT;
d337f35e 18443+
4bf69007
AM
18444+ ret = user_lpath(compat_ptr(vc_data.name_ptr), &path);
18445+ if (!ret) {
18446+ ret = __vc_get_iattr(path.dentry->d_inode,
18447+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18448+ path_put(&path);
18449+ }
18450+ if (ret)
18451+ return ret;
d337f35e 18452+
2380c486 18453+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
4bf69007
AM
18454+ ret = -EFAULT;
18455+ return ret;
d337f35e
JR
18456+}
18457+
4bf69007 18458+#endif /* CONFIG_COMPAT */
d337f35e 18459+
d337f35e 18460+
4bf69007 18461+int vc_fget_iattr(uint32_t fd, void __user *data)
d337f35e 18462+{
4bf69007
AM
18463+ struct file *filp;
18464+ struct vcmd_ctx_fiattr_v0 vc_data = { .tag = -1 };
d337f35e
JR
18465+ int ret;
18466+
4bf69007 18467+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
18468+ return -EFAULT;
18469+
4bf69007 18470+ filp = fget(fd);
5eef5607 18471+ if (!filp || !filp->f_path.dentry || !filp->f_path.dentry->d_inode)
4bf69007 18472+ return -EBADF;
2380c486 18473+
5eef5607 18474+ ret = __vc_get_iattr(filp->f_path.dentry->d_inode,
4bf69007 18475+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
2380c486 18476+
4bf69007 18477+ fput(filp);
2380c486 18478+
4bf69007
AM
18479+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18480+ ret = -EFAULT;
d337f35e
JR
18481+ return ret;
18482+}
18483+
18484+
4bf69007 18485+static int __vc_set_iattr(struct dentry *de, uint32_t *tag, uint32_t *flags, uint32_t *mask)
2380c486 18486+{
4bf69007
AM
18487+ struct inode *in = de->d_inode;
18488+ int error = 0, is_proc = 0, has_tag = 0;
18489+ struct iattr attr = { 0 };
2380c486 18490+
4bf69007
AM
18491+ if (!in || !in->i_sb)
18492+ return -ESRCH;
2380c486 18493+
4bf69007
AM
18494+ is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC);
18495+ if ((*mask & IATTR_FLAGS) && !is_proc)
18496+ return -EINVAL;
2380c486 18497+
4bf69007
AM
18498+ has_tag = IS_TAGGED(in) ||
18499+ (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC);
18500+ if ((*mask & IATTR_TAG) && !has_tag)
18501+ return -EINVAL;
2380c486 18502+
4bf69007
AM
18503+ mutex_lock(&in->i_mutex);
18504+ if (*mask & IATTR_TAG) {
8ce283e1 18505+ attr.ia_tag = make_ktag(&init_user_ns, *tag);
4bf69007 18506+ attr.ia_valid |= ATTR_TAG;
2380c486
JR
18507+ }
18508+
4bf69007
AM
18509+ if (*mask & IATTR_FLAGS) {
18510+ struct proc_dir_entry *entry = PROC_I(in)->pde;
18511+ unsigned int iflags = PROC_I(in)->vx_flags;
2380c486 18512+
4bf69007
AM
18513+ iflags = (iflags & ~(*mask & IATTR_FLAGS))
18514+ | (*flags & IATTR_FLAGS);
18515+ PROC_I(in)->vx_flags = iflags;
18516+ if (entry)
18517+ entry->vx_flags = iflags;
18518+ }
9f7054f1 18519+
4bf69007
AM
18520+ if (*mask & (IATTR_IMMUTABLE | IATTR_IXUNLINK |
18521+ IATTR_BARRIER | IATTR_COW)) {
18522+ int iflags = in->i_flags;
18523+ int vflags = in->i_vflags;
9f7054f1 18524+
4bf69007
AM
18525+ if (*mask & IATTR_IMMUTABLE) {
18526+ if (*flags & IATTR_IMMUTABLE)
18527+ iflags |= S_IMMUTABLE;
18528+ else
18529+ iflags &= ~S_IMMUTABLE;
18530+ }
18531+ if (*mask & IATTR_IXUNLINK) {
18532+ if (*flags & IATTR_IXUNLINK)
18533+ iflags |= S_IXUNLINK;
18534+ else
18535+ iflags &= ~S_IXUNLINK;
18536+ }
18537+ if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) {
18538+ if (*flags & IATTR_BARRIER)
18539+ vflags |= V_BARRIER;
18540+ else
18541+ vflags &= ~V_BARRIER;
18542+ }
18543+ if (S_ISREG(in->i_mode) && (*mask & IATTR_COW)) {
18544+ if (*flags & IATTR_COW)
18545+ vflags |= V_COW;
18546+ else
18547+ vflags &= ~V_COW;
18548+ }
18549+ if (in->i_op && in->i_op->sync_flags) {
18550+ error = in->i_op->sync_flags(in, iflags, vflags);
18551+ if (error)
18552+ goto out;
18553+ }
18554+ }
9f7054f1 18555+
4bf69007
AM
18556+ if (attr.ia_valid) {
18557+ if (in->i_op && in->i_op->setattr)
18558+ error = in->i_op->setattr(de, &attr);
18559+ else {
0e66e2fb 18560+ error = setattr_prepare(de, &attr);
4bf69007
AM
18561+ if (!error) {
18562+ setattr_copy(in, &attr);
18563+ mark_inode_dirty(in);
18564+ }
18565+ }
9f7054f1 18566+ }
9f7054f1 18567+
4bf69007
AM
18568+out:
18569+ mutex_unlock(&in->i_mutex);
18570+ return error;
18571+}
2380c486 18572+
4bf69007 18573+int vc_set_iattr(void __user *data)
d337f35e 18574+{
4bf69007
AM
18575+ struct path path;
18576+ struct vcmd_ctx_iattr_v1 vc_data;
18577+ int ret;
d337f35e 18578+
4bf69007
AM
18579+ if (!capable(CAP_LINUX_IMMUTABLE))
18580+ return -EPERM;
18581+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
18582+ return -EFAULT;
18583+
4bf69007
AM
18584+ ret = user_lpath(vc_data.name, &path);
18585+ if (!ret) {
18586+ ret = __vc_set_iattr(path.dentry,
18587+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18588+ path_put(&path);
d337f35e 18589+ }
4bf69007
AM
18590+
18591+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18592+ ret = -EFAULT;
d337f35e
JR
18593+ return ret;
18594+}
18595+
4bf69007
AM
18596+#ifdef CONFIG_COMPAT
18597+
18598+int vc_set_iattr_x32(void __user *data)
d337f35e 18599+{
4bf69007
AM
18600+ struct path path;
18601+ struct vcmd_ctx_iattr_v1_x32 vc_data;
18602+ int ret;
d337f35e 18603+
4bf69007
AM
18604+ if (!capable(CAP_LINUX_IMMUTABLE))
18605+ return -EPERM;
18606+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
18607+ return -EFAULT;
18608+
4bf69007
AM
18609+ ret = user_lpath(compat_ptr(vc_data.name_ptr), &path);
18610+ if (!ret) {
18611+ ret = __vc_set_iattr(path.dentry,
18612+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18613+ path_put(&path);
2380c486 18614+ }
4bf69007
AM
18615+
18616+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18617+ ret = -EFAULT;
18618+ return ret;
2380c486
JR
18619+}
18620+
4bf69007 18621+#endif /* CONFIG_COMPAT */
2380c486 18622+
4bf69007 18623+int vc_fset_iattr(uint32_t fd, void __user *data)
2380c486 18624+{
4bf69007
AM
18625+ struct file *filp;
18626+ struct vcmd_ctx_fiattr_v0 vc_data;
18627+ int ret;
2380c486 18628+
4bf69007
AM
18629+ if (!capable(CAP_LINUX_IMMUTABLE))
18630+ return -EPERM;
18631+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
18632+ return -EFAULT;
18633+
4bf69007 18634+ filp = fget(fd);
5eef5607 18635+ if (!filp || !filp->f_path.dentry || !filp->f_path.dentry->d_inode)
4bf69007 18636+ return -EBADF;
2380c486 18637+
5eef5607 18638+ ret = __vc_set_iattr(filp->f_path.dentry, &vc_data.tag,
4bf69007 18639+ &vc_data.flags, &vc_data.mask);
2380c486 18640+
4bf69007 18641+ fput(filp);
2380c486 18642+
4bf69007
AM
18643+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18644+ return -EFAULT;
18645+ return ret;
2380c486
JR
18646+}
18647+
2380c486 18648+
4bf69007 18649+enum { Opt_notagcheck, Opt_tag, Opt_notag, Opt_tagid, Opt_err };
2380c486 18650+
4bf69007
AM
18651+static match_table_t tokens = {
18652+ {Opt_notagcheck, "notagcheck"},
18653+#ifdef CONFIG_PROPAGATE
18654+ {Opt_notag, "notag"},
18655+ {Opt_tag, "tag"},
18656+ {Opt_tagid, "tagid=%u"},
18657+#endif
18658+ {Opt_err, NULL}
18659+};
2380c486 18660+
9f7054f1 18661+
4bf69007
AM
18662+static void __dx_parse_remove(char *string, char *opt)
18663+{
18664+ char *p = strstr(string, opt);
18665+ char *q = p;
2380c486 18666+
4bf69007
AM
18667+ if (p) {
18668+ while (*q != '\0' && *q != ',')
18669+ q++;
18670+ while (*q)
18671+ *p++ = *q++;
18672+ while (*p)
18673+ *p++ = '\0';
2380c486 18674+ }
2380c486
JR
18675+}
18676+
61333608 18677+int dx_parse_tag(char *string, vtag_t *tag, int remove, int *mnt_flags,
4bf69007 18678+ unsigned long *flags)
9f7054f1 18679+{
4bf69007
AM
18680+ int set = 0;
18681+ substring_t args[MAX_OPT_ARGS];
18682+ int token;
18683+ char *s, *p, *opts;
18684+#if defined(CONFIG_PROPAGATE) || defined(CONFIG_VSERVER_DEBUG)
18685+ int option = 0;
18686+#endif
9f7054f1 18687+
4bf69007
AM
18688+ if (!string)
18689+ return 0;
18690+ s = kstrdup(string, GFP_KERNEL | GFP_ATOMIC);
18691+ if (!s)
18692+ return 0;
9f7054f1 18693+
4bf69007
AM
18694+ opts = s;
18695+ while ((p = strsep(&opts, ",")) != NULL) {
18696+ token = match_token(p, tokens, args);
9f7054f1 18697+
4bf69007
AM
18698+ switch (token) {
18699+#ifdef CONFIG_PROPAGATE
18700+ case Opt_tag:
18701+ if (tag)
18702+ *tag = 0;
18703+ if (remove)
18704+ __dx_parse_remove(s, "tag");
18705+ *mnt_flags |= MNT_TAGID;
18706+ set |= MNT_TAGID;
18707+ break;
18708+ case Opt_notag:
18709+ if (remove)
18710+ __dx_parse_remove(s, "notag");
18711+ *mnt_flags |= MNT_NOTAG;
18712+ set |= MNT_NOTAG;
18713+ break;
18714+ case Opt_tagid:
18715+ if (tag && !match_int(args, &option))
18716+ *tag = option;
18717+ if (remove)
18718+ __dx_parse_remove(s, "tagid");
18719+ *mnt_flags |= MNT_TAGID;
18720+ set |= MNT_TAGID;
18721+ break;
18722+#endif /* CONFIG_PROPAGATE */
18723+ case Opt_notagcheck:
18724+ if (remove)
18725+ __dx_parse_remove(s, "notagcheck");
18726+ *flags |= MS_NOTAGCHECK;
18727+ set |= MS_NOTAGCHECK;
18728+ break;
18729+ }
18730+ vxdprintk(VXD_CBIT(tag, 7),
18731+ "dx_parse_tag(" VS_Q("%s") "): %d:#%d",
18732+ p, token, option);
18733+ }
18734+ if (set)
18735+ strcpy(string, s);
18736+ kfree(s);
18737+ return set;
9f7054f1 18738+}
2380c486 18739+
4bf69007 18740+#ifdef CONFIG_PROPAGATE
2380c486 18741+
4bf69007 18742+void __dx_propagate_tag(struct nameidata *nd, struct inode *inode)
2380c486 18743+{
61333608 18744+ vtag_t new_tag = 0;
4bf69007
AM
18745+ struct vfsmount *mnt;
18746+ int propagate;
2380c486 18747+
4bf69007
AM
18748+ if (!nd)
18749+ return;
18750+ mnt = nd->path.mnt;
18751+ if (!mnt)
18752+ return;
2380c486 18753+
4bf69007
AM
18754+ propagate = (mnt->mnt_flags & MNT_TAGID);
18755+ if (propagate)
18756+ new_tag = mnt->mnt_tag;
2380c486 18757+
4bf69007
AM
18758+ vxdprintk(VXD_CBIT(tag, 7),
18759+ "dx_propagate_tag(%p[#%lu.%d]): %d,%d",
18760+ inode, inode->i_ino, inode->i_tag,
18761+ new_tag, (propagate) ? 1 : 0);
18762+
18763+ if (propagate)
18764+ i_tag_write(inode, new_tag);
2380c486
JR
18765+}
18766+
4bf69007 18767+#include <linux/module.h>
2380c486 18768+
4bf69007 18769+EXPORT_SYMBOL_GPL(__dx_propagate_tag);
2380c486 18770+
4bf69007 18771+#endif /* CONFIG_PROPAGATE */
2380c486 18772+
f973f73f
AM
18773diff -NurpP --minimal linux-4.1.27/kernel/vserver/limit.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/limit.c
18774--- linux-4.1.27/kernel/vserver/limit.c 1970-01-01 00:00:00.000000000 +0000
18775+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/limit.c 2016-07-06 05:40:59.000000000 +0000
18776@@ -0,0 +1,341 @@
4bf69007
AM
18777+/*
18778+ * linux/kernel/vserver/limit.c
18779+ *
18780+ * Virtual Server: Context Limits
18781+ *
9e3e8383 18782+ * Copyright (C) 2004-2010 Herbert P?tzl
4bf69007
AM
18783+ *
18784+ * V0.01 broken out from vcontext V0.05
18785+ * V0.02 changed vcmds to vxi arg
18786+ * V0.03 added memory cgroup support
18787+ *
18788+ */
2380c486 18789+
4bf69007
AM
18790+#include <linux/sched.h>
18791+#include <linux/module.h>
18792+#include <linux/memcontrol.h>
5eef5607 18793+#include <linux/page_counter.h>
4bf69007
AM
18794+#include <linux/vs_limit.h>
18795+#include <linux/vserver/limit.h>
18796+#include <linux/vserver/limit_cmd.h>
2380c486 18797+
4bf69007 18798+#include <asm/uaccess.h>
d337f35e 18799+
d337f35e 18800+
4bf69007
AM
18801+const char *vlimit_name[NUM_LIMITS] = {
18802+ [RLIMIT_CPU] = "CPU",
18803+ [RLIMIT_NPROC] = "NPROC",
18804+ [RLIMIT_NOFILE] = "NOFILE",
18805+ [RLIMIT_LOCKS] = "LOCKS",
18806+ [RLIMIT_SIGPENDING] = "SIGP",
18807+ [RLIMIT_MSGQUEUE] = "MSGQ",
d337f35e 18808+
4bf69007
AM
18809+ [VLIMIT_NSOCK] = "NSOCK",
18810+ [VLIMIT_OPENFD] = "OPENFD",
18811+ [VLIMIT_SHMEM] = "SHMEM",
18812+ [VLIMIT_DENTRY] = "DENTRY",
18813+};
2380c486 18814+
4bf69007 18815+EXPORT_SYMBOL_GPL(vlimit_name);
2380c486 18816+
4bf69007 18817+#define MASK_ENTRY(x) (1 << (x))
d337f35e 18818+
4bf69007
AM
18819+const struct vcmd_ctx_rlimit_mask_v0 vlimit_mask = {
18820+ /* minimum */
18821+ 0
18822+ , /* softlimit */
18823+ 0
18824+ , /* maximum */
18825+ MASK_ENTRY( RLIMIT_NPROC ) |
18826+ MASK_ENTRY( RLIMIT_NOFILE ) |
18827+ MASK_ENTRY( RLIMIT_LOCKS ) |
18828+ MASK_ENTRY( RLIMIT_MSGQUEUE ) |
d337f35e 18829+
4bf69007
AM
18830+ MASK_ENTRY( VLIMIT_NSOCK ) |
18831+ MASK_ENTRY( VLIMIT_OPENFD ) |
18832+ MASK_ENTRY( VLIMIT_SHMEM ) |
18833+ MASK_ENTRY( VLIMIT_DENTRY ) |
18834+ 0
18835+};
18836+ /* accounting only */
18837+uint32_t account_mask =
18838+ MASK_ENTRY( VLIMIT_SEMARY ) |
18839+ MASK_ENTRY( VLIMIT_NSEMS ) |
18840+ MASK_ENTRY( VLIMIT_MAPPED ) |
18841+ 0;
d337f35e 18842+
4bf69007
AM
18843+
18844+static int is_valid_vlimit(int id)
18845+{
18846+ uint32_t mask = vlimit_mask.minimum |
18847+ vlimit_mask.softlimit | vlimit_mask.maximum;
18848+ return mask & (1 << id);
d337f35e
JR
18849+}
18850+
4bf69007 18851+static int is_accounted_vlimit(int id)
d337f35e 18852+{
4bf69007
AM
18853+ if (is_valid_vlimit(id))
18854+ return 1;
18855+ return account_mask & (1 << id);
18856+}
d337f35e 18857+
d337f35e 18858+
4bf69007
AM
18859+static inline uint64_t vc_get_soft(struct vx_info *vxi, int id)
18860+{
18861+ rlim_t limit = __rlim_soft(&vxi->limit, id);
18862+ return VX_VLIM(limit);
18863+}
d337f35e 18864+
4bf69007
AM
18865+static inline uint64_t vc_get_hard(struct vx_info *vxi, int id)
18866+{
18867+ rlim_t limit = __rlim_hard(&vxi->limit, id);
18868+ return VX_VLIM(limit);
18869+}
d337f35e 18870+
4bf69007
AM
18871+static int do_get_rlimit(struct vx_info *vxi, uint32_t id,
18872+ uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
18873+{
18874+ if (!is_valid_vlimit(id))
18875+ return -EINVAL;
18876+
18877+ if (minimum)
18878+ *minimum = CRLIM_UNSET;
18879+ if (softlimit)
18880+ *softlimit = vc_get_soft(vxi, id);
18881+ if (maximum)
18882+ *maximum = vc_get_hard(vxi, id);
d337f35e
JR
18883+ return 0;
18884+}
18885+
4bf69007 18886+int vc_get_rlimit(struct vx_info *vxi, void __user *data)
d337f35e 18887+{
4bf69007
AM
18888+ struct vcmd_ctx_rlimit_v0 vc_data;
18889+ int ret;
d337f35e 18890+
4bf69007
AM
18891+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18892+ return -EFAULT;
18893+
18894+ ret = do_get_rlimit(vxi, vc_data.id,
18895+ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
18896+ if (ret)
18897+ return ret;
d337f35e 18898+
2380c486 18899+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
18900+ return -EFAULT;
18901+ return 0;
18902+}
18903+
4bf69007
AM
18904+static int do_set_rlimit(struct vx_info *vxi, uint32_t id,
18905+ uint64_t minimum, uint64_t softlimit, uint64_t maximum)
d337f35e 18906+{
4bf69007
AM
18907+ if (!is_valid_vlimit(id))
18908+ return -EINVAL;
d337f35e 18909+
4bf69007
AM
18910+ if (maximum != CRLIM_KEEP)
18911+ __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum);
18912+ if (softlimit != CRLIM_KEEP)
18913+ __rlim_soft(&vxi->limit, id) = VX_RLIM(softlimit);
18914+
18915+ /* clamp soft limit */
18916+ if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id))
18917+ __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id);
d337f35e 18918+
d337f35e
JR
18919+ return 0;
18920+}
18921+
4bf69007
AM
18922+int vc_set_rlimit(struct vx_info *vxi, void __user *data)
18923+{
18924+ struct vcmd_ctx_rlimit_v0 vc_data;
d337f35e 18925+
4bf69007
AM
18926+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18927+ return -EFAULT;
d337f35e 18928+
4bf69007
AM
18929+ return do_set_rlimit(vxi, vc_data.id,
18930+ vc_data.minimum, vc_data.softlimit, vc_data.maximum);
18931+}
d337f35e 18932+
4bf69007 18933+#ifdef CONFIG_IA32_EMULATION
2380c486 18934+
4bf69007
AM
18935+int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data)
18936+{
18937+ struct vcmd_ctx_rlimit_v0_x32 vc_data;
d337f35e 18938+
4bf69007
AM
18939+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18940+ return -EFAULT;
d337f35e 18941+
4bf69007
AM
18942+ return do_set_rlimit(vxi, vc_data.id,
18943+ vc_data.minimum, vc_data.softlimit, vc_data.maximum);
18944+}
d337f35e 18945+
4bf69007
AM
18946+int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data)
18947+{
18948+ struct vcmd_ctx_rlimit_v0_x32 vc_data;
18949+ int ret;
d337f35e 18950+
4bf69007
AM
18951+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18952+ return -EFAULT;
d337f35e 18953+
4bf69007
AM
18954+ ret = do_get_rlimit(vxi, vc_data.id,
18955+ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
18956+ if (ret)
18957+ return ret;
2380c486 18958+
4bf69007
AM
18959+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18960+ return -EFAULT;
18961+ return 0;
2380c486 18962+}
d337f35e 18963+
4bf69007 18964+#endif /* CONFIG_IA32_EMULATION */
d337f35e
JR
18965+
18966+
4bf69007
AM
18967+int vc_get_rlimit_mask(uint32_t id, void __user *data)
18968+{
18969+ if (copy_to_user(data, &vlimit_mask, sizeof(vlimit_mask)))
18970+ return -EFAULT;
18971+ return 0;
18972+}
d337f35e
JR
18973+
18974+
4bf69007
AM
18975+static inline void vx_reset_hits(struct _vx_limit *limit)
18976+{
18977+ int lim;
d337f35e 18978+
4bf69007
AM
18979+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18980+ atomic_set(&__rlim_lhit(limit, lim), 0);
18981+ }
18982+}
d337f35e 18983+
4bf69007 18984+int vc_reset_hits(struct vx_info *vxi, void __user *data)
d337f35e 18985+{
4bf69007
AM
18986+ vx_reset_hits(&vxi->limit);
18987+ return 0;
d337f35e
JR
18988+}
18989+
4bf69007 18990+static inline void vx_reset_minmax(struct _vx_limit *limit)
d337f35e 18991+{
4bf69007
AM
18992+ rlim_t value;
18993+ int lim;
18994+
18995+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18996+ value = __rlim_get(limit, lim);
18997+ __rlim_rmax(limit, lim) = value;
18998+ __rlim_rmin(limit, lim) = value;
18999+ }
d337f35e
JR
19000+}
19001+
4bf69007 19002+int vc_reset_minmax(struct vx_info *vxi, void __user *data)
d337f35e 19003+{
4bf69007
AM
19004+ vx_reset_minmax(&vxi->limit);
19005+ return 0;
d337f35e
JR
19006+}
19007+
19008+
4bf69007 19009+int vc_rlimit_stat(struct vx_info *vxi, void __user *data)
d337f35e 19010+{
4bf69007
AM
19011+ struct vcmd_rlimit_stat_v0 vc_data;
19012+ struct _vx_limit *limit = &vxi->limit;
19013+ int id;
d337f35e 19014+
4bf69007
AM
19015+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
19016+ return -EFAULT;
d337f35e 19017+
4bf69007
AM
19018+ id = vc_data.id;
19019+ if (!is_accounted_vlimit(id))
19020+ return -EINVAL;
2380c486 19021+
4bf69007
AM
19022+ vx_limit_fixup(limit, id);
19023+ vc_data.hits = atomic_read(&__rlim_lhit(limit, id));
19024+ vc_data.value = __rlim_get(limit, id);
19025+ vc_data.minimum = __rlim_rmin(limit, id);
19026+ vc_data.maximum = __rlim_rmax(limit, id);
2380c486 19027+
4bf69007
AM
19028+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
19029+ return -EFAULT;
19030+ return 0;
d337f35e
JR
19031+}
19032+
d337f35e 19033+
4bf69007 19034+void vx_vsi_meminfo(struct sysinfo *val)
d337f35e 19035+{
4bf69007
AM
19036+ struct mem_cgroup *mcg;
19037+ u64 res_limit, res_usage;
d337f35e 19038+
4bf69007
AM
19039+ rcu_read_lock();
19040+ mcg = mem_cgroup_from_task(current);
19041+ rcu_read_unlock();
19042+ if (!mcg)
19043+ goto out;
d337f35e 19044+
f973f73f
AM
19045+ res_limit = mem_cgroup_mem_limit_pages(mcg);
19046+ res_usage = mem_cgroup_mem_usage_pages(mcg);
2380c486 19047+
5eef5607 19048+ if (res_limit != PAGE_COUNTER_MAX)
f973f73f
AM
19049+ val->totalram = res_limit;
19050+ val->freeram = val->totalram - res_usage;
4bf69007
AM
19051+ val->bufferram = 0;
19052+ val->totalhigh = 0;
19053+ val->freehigh = 0;
19054+out:
4bf69007 19055+ return;
d337f35e
JR
19056+}
19057+
4bf69007 19058+void vx_vsi_swapinfo(struct sysinfo *val)
d337f35e 19059+{
4bf69007
AM
19060+#ifdef CONFIG_MEMCG_SWAP
19061+ struct mem_cgroup *mcg;
19062+ u64 res_limit, res_usage, memsw_limit, memsw_usage;
19063+ s64 swap_limit, swap_usage;
d337f35e 19064+
4bf69007
AM
19065+ rcu_read_lock();
19066+ mcg = mem_cgroup_from_task(current);
19067+ rcu_read_unlock();
19068+ if (!mcg)
19069+ goto out;
d337f35e 19070+
f973f73f
AM
19071+ res_limit = mem_cgroup_mem_limit_pages(mcg);
19072+ res_usage = mem_cgroup_mem_usage_pages(mcg);
19073+ memsw_limit = mem_cgroup_memsw_limit_pages(mcg);
19074+ memsw_usage = mem_cgroup_memsw_usage_pages(mcg);
d337f35e 19075+
4bf69007 19076+ /* memory unlimited */
5eef5607 19077+ if (res_limit == PAGE_COUNTER_MAX)
4bf69007 19078+ goto out;
d337f35e 19079+
4bf69007
AM
19080+ swap_limit = memsw_limit - res_limit;
19081+ /* we have a swap limit? */
5eef5607 19082+ if (memsw_limit != PAGE_COUNTER_MAX)
f973f73f 19083+ val->totalswap = swap_limit;
d337f35e 19084+
4bf69007
AM
19085+ /* calculate swap part */
19086+ swap_usage = (memsw_usage > res_usage) ?
19087+ memsw_usage - res_usage : 0;
19088+
19089+ /* total shown minus usage gives free swap */
19090+ val->freeswap = (swap_usage < swap_limit) ?
f973f73f 19091+ val->totalswap - swap_usage : 0;
4bf69007
AM
19092+out:
19093+#else /* !CONFIG_MEMCG_SWAP */
19094+ val->totalswap = 0;
19095+ val->freeswap = 0;
19096+#endif /* !CONFIG_MEMCG_SWAP */
4bf69007 19097+ return;
d337f35e
JR
19098+}
19099+
4bf69007 19100+long vx_vsi_cached(struct sysinfo *val)
d337f35e 19101+{
4bf69007 19102+ long cache = 0;
5eef5607 19103+#ifdef CONFIG_MEMCG_BROKEN
4bf69007 19104+ struct mem_cgroup *mcg;
d337f35e 19105+
4bf69007
AM
19106+ rcu_read_lock();
19107+ mcg = mem_cgroup_from_task(current);
19108+ rcu_read_unlock();
19109+ if (!mcg)
19110+ goto out;
2380c486 19111+
5eef5607 19112+ // cache = mem_cgroup_stat_read_cache(mcg);
4bf69007 19113+out:
2380c486 19114+#endif
4bf69007 19115+ return cache;
d337f35e
JR
19116+}
19117+
f973f73f
AM
19118diff -NurpP --minimal linux-4.1.27/kernel/vserver/limit_init.h linux-4.1.27-vs2.3.8.5.2/kernel/vserver/limit_init.h
19119--- linux-4.1.27/kernel/vserver/limit_init.h 1970-01-01 00:00:00.000000000 +0000
19120+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/limit_init.h 2016-07-05 04:41:47.000000000 +0000
4bf69007 19121@@ -0,0 +1,31 @@
d337f35e
JR
19122+
19123+
4bf69007
AM
19124+static inline void vx_info_init_limit(struct _vx_limit *limit)
19125+{
19126+ int lim;
d337f35e 19127+
4bf69007
AM
19128+ for (lim = 0; lim < NUM_LIMITS; lim++) {
19129+ __rlim_soft(limit, lim) = RLIM_INFINITY;
19130+ __rlim_hard(limit, lim) = RLIM_INFINITY;
19131+ __rlim_set(limit, lim, 0);
19132+ atomic_set(&__rlim_lhit(limit, lim), 0);
19133+ __rlim_rmin(limit, lim) = 0;
19134+ __rlim_rmax(limit, lim) = 0;
19135+ }
19136+}
d337f35e 19137+
4bf69007 19138+static inline void vx_info_exit_limit(struct _vx_limit *limit)
d337f35e 19139+{
4bf69007
AM
19140+ rlim_t value;
19141+ int lim;
d337f35e 19142+
4bf69007
AM
19143+ for (lim = 0; lim < NUM_LIMITS; lim++) {
19144+ if ((1 << lim) & VLIM_NOCHECK)
19145+ continue;
19146+ value = __rlim_get(limit, lim);
19147+ vxwprintk_xid(value,
19148+ "!!! limit: %p[%s,%d] = %ld on exit.",
19149+ limit, vlimit_name[lim], lim, (long)value);
19150+ }
19151+}
d337f35e 19152+
f973f73f
AM
19153diff -NurpP --minimal linux-4.1.27/kernel/vserver/limit_proc.h linux-4.1.27-vs2.3.8.5.2/kernel/vserver/limit_proc.h
19154--- linux-4.1.27/kernel/vserver/limit_proc.h 1970-01-01 00:00:00.000000000 +0000
19155+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/limit_proc.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
19156@@ -0,0 +1,57 @@
19157+#ifndef _VX_LIMIT_PROC_H
19158+#define _VX_LIMIT_PROC_H
d337f35e 19159+
4bf69007 19160+#include <linux/vserver/limit_int.h>
d337f35e 19161+
d337f35e 19162+
4bf69007
AM
19163+#define VX_LIMIT_FMT ":\t%8ld\t%8ld/%8ld\t%8lld/%8lld\t%6d\n"
19164+#define VX_LIMIT_TOP \
19165+ "Limit\t current\t min/max\t\t soft/hard\t\thits\n"
d337f35e 19166+
4bf69007
AM
19167+#define VX_LIMIT_ARG(r) \
19168+ (unsigned long)__rlim_get(limit, r), \
19169+ (unsigned long)__rlim_rmin(limit, r), \
19170+ (unsigned long)__rlim_rmax(limit, r), \
19171+ VX_VLIM(__rlim_soft(limit, r)), \
19172+ VX_VLIM(__rlim_hard(limit, r)), \
19173+ atomic_read(&__rlim_lhit(limit, r))
d337f35e 19174+
4bf69007
AM
19175+static inline int vx_info_proc_limit(struct _vx_limit *limit, char *buffer)
19176+{
19177+ vx_limit_fixup(limit, -1);
19178+ return sprintf(buffer, VX_LIMIT_TOP
19179+ "PROC" VX_LIMIT_FMT
19180+ "VM" VX_LIMIT_FMT
19181+ "VML" VX_LIMIT_FMT
19182+ "RSS" VX_LIMIT_FMT
19183+ "ANON" VX_LIMIT_FMT
19184+ "RMAP" VX_LIMIT_FMT
19185+ "FILES" VX_LIMIT_FMT
19186+ "OFD" VX_LIMIT_FMT
19187+ "LOCKS" VX_LIMIT_FMT
19188+ "SOCK" VX_LIMIT_FMT
19189+ "MSGQ" VX_LIMIT_FMT
19190+ "SHM" VX_LIMIT_FMT
19191+ "SEMA" VX_LIMIT_FMT
19192+ "SEMS" VX_LIMIT_FMT
19193+ "DENT" VX_LIMIT_FMT,
19194+ VX_LIMIT_ARG(RLIMIT_NPROC),
19195+ VX_LIMIT_ARG(RLIMIT_AS),
19196+ VX_LIMIT_ARG(RLIMIT_MEMLOCK),
19197+ VX_LIMIT_ARG(RLIMIT_RSS),
19198+ VX_LIMIT_ARG(VLIMIT_ANON),
19199+ VX_LIMIT_ARG(VLIMIT_MAPPED),
19200+ VX_LIMIT_ARG(RLIMIT_NOFILE),
19201+ VX_LIMIT_ARG(VLIMIT_OPENFD),
19202+ VX_LIMIT_ARG(RLIMIT_LOCKS),
19203+ VX_LIMIT_ARG(VLIMIT_NSOCK),
19204+ VX_LIMIT_ARG(RLIMIT_MSGQUEUE),
19205+ VX_LIMIT_ARG(VLIMIT_SHMEM),
19206+ VX_LIMIT_ARG(VLIMIT_SEMARY),
19207+ VX_LIMIT_ARG(VLIMIT_NSEMS),
19208+ VX_LIMIT_ARG(VLIMIT_DENTRY));
d337f35e
JR
19209+}
19210+
4bf69007 19211+#endif /* _VX_LIMIT_PROC_H */
d337f35e 19212+
d337f35e 19213+
f973f73f
AM
19214diff -NurpP --minimal linux-4.1.27/kernel/vserver/network.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/network.c
19215--- linux-4.1.27/kernel/vserver/network.c 1970-01-01 00:00:00.000000000 +0000
19216+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/network.c 2016-07-05 04:41:47.000000000 +0000
5cb1760b 19217@@ -0,0 +1,1053 @@
d337f35e 19218+/*
4bf69007 19219+ * linux/kernel/vserver/network.c
d337f35e 19220+ *
4bf69007
AM
19221+ * Virtual Server: Network Support
19222+ *
9e3e8383 19223+ * Copyright (C) 2003-2007 Herbert P?tzl
4bf69007
AM
19224+ *
19225+ * V0.01 broken out from vcontext V0.05
19226+ * V0.02 cleaned up implementation
19227+ * V0.03 added equiv nx commands
19228+ * V0.04 switch to RCU based hash
19229+ * V0.05 and back to locking again
19230+ * V0.06 changed vcmds to nxi arg
19231+ * V0.07 have __create claim() the nxi
d337f35e 19232+ *
d337f35e 19233+ */
d337f35e 19234+
4bf69007
AM
19235+#include <linux/err.h>
19236+#include <linux/slab.h>
19237+#include <linux/rcupdate.h>
19238+#include <net/ipv6.h>
d337f35e 19239+
4bf69007
AM
19240+#include <linux/vs_network.h>
19241+#include <linux/vs_pid.h>
19242+#include <linux/vserver/network_cmd.h>
d337f35e
JR
19243+
19244+
4bf69007
AM
19245+atomic_t nx_global_ctotal = ATOMIC_INIT(0);
19246+atomic_t nx_global_cactive = ATOMIC_INIT(0);
d337f35e 19247+
4bf69007
AM
19248+static struct kmem_cache *nx_addr_v4_cachep = NULL;
19249+static struct kmem_cache *nx_addr_v6_cachep = NULL;
d337f35e 19250+
d337f35e 19251+
4bf69007 19252+static int __init init_network(void)
d337f35e 19253+{
4bf69007
AM
19254+ nx_addr_v4_cachep = kmem_cache_create("nx_v4_addr_cache",
19255+ sizeof(struct nx_addr_v4), 0,
19256+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
19257+ nx_addr_v6_cachep = kmem_cache_create("nx_v6_addr_cache",
19258+ sizeof(struct nx_addr_v6), 0,
19259+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
d337f35e
JR
19260+ return 0;
19261+}
19262+
19263+
4bf69007 19264+/* __alloc_nx_addr_v4() */
d337f35e 19265+
4bf69007 19266+static inline struct nx_addr_v4 *__alloc_nx_addr_v4(void)
d337f35e 19267+{
4bf69007
AM
19268+ struct nx_addr_v4 *nxa = kmem_cache_alloc(
19269+ nx_addr_v4_cachep, GFP_KERNEL);
92598135 19270+
4bf69007
AM
19271+ if (!IS_ERR(nxa))
19272+ memset(nxa, 0, sizeof(*nxa));
19273+ return nxa;
d337f35e
JR
19274+}
19275+
4bf69007 19276+/* __dealloc_nx_addr_v4() */
d337f35e 19277+
4bf69007
AM
19278+static inline void __dealloc_nx_addr_v4(struct nx_addr_v4 *nxa)
19279+{
19280+ kmem_cache_free(nx_addr_v4_cachep, nxa);
19281+}
d337f35e 19282+
4bf69007 19283+/* __dealloc_nx_addr_v4_all() */
d337f35e 19284+
4bf69007 19285+static inline void __dealloc_nx_addr_v4_all(struct nx_addr_v4 *nxa)
d337f35e 19286+{
4bf69007
AM
19287+ while (nxa) {
19288+ struct nx_addr_v4 *next = nxa->next;
d337f35e 19289+
4bf69007
AM
19290+ __dealloc_nx_addr_v4(nxa);
19291+ nxa = next;
19292+ }
19293+}
d337f35e 19294+
d337f35e 19295+
4bf69007 19296+#ifdef CONFIG_IPV6
d337f35e 19297+
4bf69007 19298+/* __alloc_nx_addr_v6() */
d337f35e 19299+
4bf69007
AM
19300+static inline struct nx_addr_v6 *__alloc_nx_addr_v6(void)
19301+{
19302+ struct nx_addr_v6 *nxa = kmem_cache_alloc(
19303+ nx_addr_v6_cachep, GFP_KERNEL);
d337f35e 19304+
4bf69007
AM
19305+ if (!IS_ERR(nxa))
19306+ memset(nxa, 0, sizeof(*nxa));
19307+ return nxa;
d337f35e
JR
19308+}
19309+
4bf69007
AM
19310+/* __dealloc_nx_addr_v6() */
19311+
19312+static inline void __dealloc_nx_addr_v6(struct nx_addr_v6 *nxa)
d337f35e 19313+{
4bf69007
AM
19314+ kmem_cache_free(nx_addr_v6_cachep, nxa);
19315+}
d337f35e 19316+
4bf69007 19317+/* __dealloc_nx_addr_v6_all() */
d337f35e 19318+
4bf69007
AM
19319+static inline void __dealloc_nx_addr_v6_all(struct nx_addr_v6 *nxa)
19320+{
19321+ while (nxa) {
19322+ struct nx_addr_v6 *next = nxa->next;
d337f35e 19323+
4bf69007
AM
19324+ __dealloc_nx_addr_v6(nxa);
19325+ nxa = next;
19326+ }
19327+}
d337f35e 19328+
4bf69007 19329+#endif /* CONFIG_IPV6 */
d337f35e 19330+
4bf69007 19331+/* __alloc_nx_info()
d337f35e 19332+
4bf69007
AM
19333+ * allocate an initialized nx_info struct
19334+ * doesn't make it visible (hash) */
d337f35e 19335+
61333608 19336+static struct nx_info *__alloc_nx_info(vnid_t nid)
d337f35e 19337+{
4bf69007 19338+ struct nx_info *new = NULL;
d337f35e 19339+
4bf69007 19340+ vxdprintk(VXD_CBIT(nid, 1), "alloc_nx_info(%d)*", nid);
d337f35e 19341+
4bf69007
AM
19342+ /* would this benefit from a slab cache? */
19343+ new = kmalloc(sizeof(struct nx_info), GFP_KERNEL);
19344+ if (!new)
19345+ return 0;
d337f35e 19346+
4bf69007
AM
19347+ memset(new, 0, sizeof(struct nx_info));
19348+ new->nx_id = nid;
19349+ INIT_HLIST_NODE(&new->nx_hlist);
19350+ atomic_set(&new->nx_usecnt, 0);
19351+ atomic_set(&new->nx_tasks, 0);
19352+ spin_lock_init(&new->addr_lock);
19353+ new->nx_state = 0;
d337f35e 19354+
4bf69007 19355+ new->nx_flags = NXF_INIT_SET;
d337f35e 19356+
4bf69007 19357+ /* rest of init goes here */
d337f35e 19358+
4bf69007
AM
19359+ new->v4_lback.s_addr = htonl(INADDR_LOOPBACK);
19360+ new->v4_bcast.s_addr = htonl(INADDR_BROADCAST);
19361+
19362+ vxdprintk(VXD_CBIT(nid, 0),
19363+ "alloc_nx_info(%d) = %p", nid, new);
19364+ atomic_inc(&nx_global_ctotal);
19365+ return new;
d337f35e
JR
19366+}
19367+
4bf69007 19368+/* __dealloc_nx_info()
d337f35e 19369+
4bf69007 19370+ * final disposal of nx_info */
d337f35e 19371+
4bf69007
AM
19372+static void __dealloc_nx_info(struct nx_info *nxi)
19373+{
19374+ vxdprintk(VXD_CBIT(nid, 0),
19375+ "dealloc_nx_info(%p)", nxi);
d337f35e 19376+
4bf69007
AM
19377+ nxi->nx_hlist.next = LIST_POISON1;
19378+ nxi->nx_id = -1;
d337f35e 19379+
4bf69007
AM
19380+ BUG_ON(atomic_read(&nxi->nx_usecnt));
19381+ BUG_ON(atomic_read(&nxi->nx_tasks));
19382+
19383+ __dealloc_nx_addr_v4_all(nxi->v4.next);
19384+#ifdef CONFIG_IPV6
19385+ __dealloc_nx_addr_v6_all(nxi->v6.next);
19386+#endif
19387+
19388+ nxi->nx_state |= NXS_RELEASED;
19389+ kfree(nxi);
19390+ atomic_dec(&nx_global_ctotal);
d337f35e
JR
19391+}
19392+
4bf69007
AM
19393+static void __shutdown_nx_info(struct nx_info *nxi)
19394+{
19395+ nxi->nx_state |= NXS_SHUTDOWN;
19396+ vs_net_change(nxi, VSC_NETDOWN);
19397+}
d337f35e 19398+
4bf69007 19399+/* exported stuff */
d337f35e 19400+
4bf69007
AM
19401+void free_nx_info(struct nx_info *nxi)
19402+{
19403+ /* context shutdown is mandatory */
19404+ BUG_ON(nxi->nx_state != NXS_SHUTDOWN);
d337f35e 19405+
4bf69007
AM
19406+ /* context must not be hashed */
19407+ BUG_ON(nxi->nx_state & NXS_HASHED);
d337f35e 19408+
4bf69007
AM
19409+ BUG_ON(atomic_read(&nxi->nx_usecnt));
19410+ BUG_ON(atomic_read(&nxi->nx_tasks));
d337f35e 19411+
4bf69007
AM
19412+ __dealloc_nx_info(nxi);
19413+}
d337f35e 19414+
d337f35e 19415+
4bf69007
AM
19416+void __nx_set_lback(struct nx_info *nxi)
19417+{
19418+ int nid = nxi->nx_id;
19419+ __be32 lback = htonl(INADDR_LOOPBACK ^ ((nid & 0xFFFF) << 8));
d337f35e 19420+
4bf69007
AM
19421+ nxi->v4_lback.s_addr = lback;
19422+}
d337f35e 19423+
4bf69007
AM
19424+extern int __nx_inet_add_lback(__be32 addr);
19425+extern int __nx_inet_del_lback(__be32 addr);
d337f35e
JR
19426+
19427+
4bf69007 19428+/* hash table for nx_info hash */
d337f35e 19429+
4bf69007 19430+#define NX_HASH_SIZE 13
d337f35e 19431+
4bf69007
AM
19432+struct hlist_head nx_info_hash[NX_HASH_SIZE];
19433+
19434+static DEFINE_SPINLOCK(nx_info_hash_lock);
19435+
19436+
61333608 19437+static inline unsigned int __hashval(vnid_t nid)
d337f35e 19438+{
4bf69007 19439+ return (nid % NX_HASH_SIZE);
d337f35e
JR
19440+}
19441+
d337f35e 19442+
d337f35e 19443+
4bf69007 19444+/* __hash_nx_info()
d337f35e 19445+
4bf69007
AM
19446+ * add the nxi to the global hash table
19447+ * requires the hash_lock to be held */
19448+
19449+static inline void __hash_nx_info(struct nx_info *nxi)
d337f35e 19450+{
4bf69007 19451+ struct hlist_head *head;
d337f35e 19452+
4bf69007
AM
19453+ vxd_assert_lock(&nx_info_hash_lock);
19454+ vxdprintk(VXD_CBIT(nid, 4),
19455+ "__hash_nx_info: %p[#%d]", nxi, nxi->nx_id);
d337f35e 19456+
4bf69007
AM
19457+ /* context must not be hashed */
19458+ BUG_ON(nx_info_state(nxi, NXS_HASHED));
d337f35e 19459+
4bf69007
AM
19460+ nxi->nx_state |= NXS_HASHED;
19461+ head = &nx_info_hash[__hashval(nxi->nx_id)];
19462+ hlist_add_head(&nxi->nx_hlist, head);
19463+ atomic_inc(&nx_global_cactive);
19464+}
d337f35e 19465+
4bf69007 19466+/* __unhash_nx_info()
d337f35e 19467+
4bf69007
AM
19468+ * remove the nxi from the global hash table
19469+ * requires the hash_lock to be held */
d337f35e 19470+
4bf69007
AM
19471+static inline void __unhash_nx_info(struct nx_info *nxi)
19472+{
19473+ vxd_assert_lock(&nx_info_hash_lock);
19474+ vxdprintk(VXD_CBIT(nid, 4),
19475+ "__unhash_nx_info: %p[#%d.%d.%d]", nxi, nxi->nx_id,
19476+ atomic_read(&nxi->nx_usecnt), atomic_read(&nxi->nx_tasks));
d337f35e 19477+
4bf69007
AM
19478+ /* context must be hashed */
19479+ BUG_ON(!nx_info_state(nxi, NXS_HASHED));
19480+ /* but without tasks */
19481+ BUG_ON(atomic_read(&nxi->nx_tasks));
d337f35e 19482+
4bf69007
AM
19483+ nxi->nx_state &= ~NXS_HASHED;
19484+ hlist_del(&nxi->nx_hlist);
19485+ atomic_dec(&nx_global_cactive);
d337f35e
JR
19486+}
19487+
d337f35e 19488+
4bf69007 19489+/* __lookup_nx_info()
d337f35e 19490+
4bf69007
AM
19491+ * requires the hash_lock to be held
19492+ * doesn't increment the nx_refcnt */
d337f35e 19493+
61333608 19494+static inline struct nx_info *__lookup_nx_info(vnid_t nid)
d337f35e 19495+{
4bf69007
AM
19496+ struct hlist_head *head = &nx_info_hash[__hashval(nid)];
19497+ struct hlist_node *pos;
19498+ struct nx_info *nxi;
d337f35e 19499+
4bf69007
AM
19500+ vxd_assert_lock(&nx_info_hash_lock);
19501+ hlist_for_each(pos, head) {
19502+ nxi = hlist_entry(pos, struct nx_info, nx_hlist);
19503+
19504+ if (nxi->nx_id == nid)
19505+ goto found;
d337f35e 19506+ }
4bf69007
AM
19507+ nxi = NULL;
19508+found:
19509+ vxdprintk(VXD_CBIT(nid, 0),
19510+ "__lookup_nx_info(#%u): %p[#%u]",
19511+ nid, nxi, nxi ? nxi->nx_id : 0);
19512+ return nxi;
d337f35e
JR
19513+}
19514+
19515+
4bf69007 19516+/* __create_nx_info()
d337f35e 19517+
4bf69007
AM
19518+ * create the requested context
19519+ * get(), claim() and hash it */
d337f35e 19520+
4bf69007
AM
19521+static struct nx_info *__create_nx_info(int id)
19522+{
19523+ struct nx_info *new, *nxi = NULL;
d337f35e 19524+
4bf69007 19525+ vxdprintk(VXD_CBIT(nid, 1), "create_nx_info(%d)*", id);
d337f35e 19526+
4bf69007
AM
19527+ if (!(new = __alloc_nx_info(id)))
19528+ return ERR_PTR(-ENOMEM);
d337f35e 19529+
4bf69007
AM
19530+ /* required to make dynamic xids unique */
19531+ spin_lock(&nx_info_hash_lock);
d337f35e 19532+
4bf69007
AM
19533+ /* static context requested */
19534+ if ((nxi = __lookup_nx_info(id))) {
19535+ vxdprintk(VXD_CBIT(nid, 0),
19536+ "create_nx_info(%d) = %p (already there)", id, nxi);
19537+ if (nx_info_flags(nxi, NXF_STATE_SETUP, 0))
19538+ nxi = ERR_PTR(-EBUSY);
19539+ else
19540+ nxi = ERR_PTR(-EEXIST);
19541+ goto out_unlock;
19542+ }
19543+ /* new context */
19544+ vxdprintk(VXD_CBIT(nid, 0),
19545+ "create_nx_info(%d) = %p (new)", id, new);
19546+ claim_nx_info(new, NULL);
19547+ __nx_set_lback(new);
19548+ __hash_nx_info(get_nx_info(new));
19549+ nxi = new, new = NULL;
d337f35e 19550+
4bf69007
AM
19551+out_unlock:
19552+ spin_unlock(&nx_info_hash_lock);
19553+ if (new)
19554+ __dealloc_nx_info(new);
19555+ return nxi;
19556+}
d337f35e
JR
19557+
19558+
d337f35e 19559+
4bf69007 19560+/* exported stuff */
d337f35e 19561+
d337f35e 19562+
4bf69007
AM
19563+void unhash_nx_info(struct nx_info *nxi)
19564+{
19565+ __shutdown_nx_info(nxi);
19566+ spin_lock(&nx_info_hash_lock);
19567+ __unhash_nx_info(nxi);
19568+ spin_unlock(&nx_info_hash_lock);
d337f35e
JR
19569+}
19570+
4bf69007 19571+/* lookup_nx_info()
d337f35e 19572+
4bf69007
AM
19573+ * search for a nx_info and get() it
19574+ * negative id means current */
d337f35e 19575+
4bf69007 19576+struct nx_info *lookup_nx_info(int id)
d337f35e 19577+{
4bf69007 19578+ struct nx_info *nxi = NULL;
d337f35e 19579+
4bf69007
AM
19580+ if (id < 0) {
19581+ nxi = get_nx_info(current_nx_info());
19582+ } else if (id > 1) {
19583+ spin_lock(&nx_info_hash_lock);
19584+ nxi = get_nx_info(__lookup_nx_info(id));
19585+ spin_unlock(&nx_info_hash_lock);
d337f35e 19586+ }
4bf69007
AM
19587+ return nxi;
19588+}
d337f35e 19589+
4bf69007 19590+/* nid_is_hashed()
d337f35e 19591+
4bf69007
AM
19592+ * verify that nid is still hashed */
19593+
61333608 19594+int nid_is_hashed(vnid_t nid)
4bf69007
AM
19595+{
19596+ int hashed;
19597+
19598+ spin_lock(&nx_info_hash_lock);
19599+ hashed = (__lookup_nx_info(nid) != NULL);
19600+ spin_unlock(&nx_info_hash_lock);
19601+ return hashed;
d337f35e
JR
19602+}
19603+
19604+
4bf69007 19605+#ifdef CONFIG_PROC_FS
d337f35e 19606+
4bf69007
AM
19607+/* get_nid_list()
19608+
19609+ * get a subset of hashed nids for proc
19610+ * assumes size is at least one */
19611+
19612+int get_nid_list(int index, unsigned int *nids, int size)
d337f35e 19613+{
4bf69007 19614+ int hindex, nr_nids = 0;
d337f35e 19615+
4bf69007
AM
19616+ /* only show current and children */
19617+ if (!nx_check(0, VS_ADMIN | VS_WATCH)) {
19618+ if (index > 0)
19619+ return 0;
19620+ nids[nr_nids] = nx_current_nid();
19621+ return 1;
19622+ }
d337f35e 19623+
4bf69007
AM
19624+ for (hindex = 0; hindex < NX_HASH_SIZE; hindex++) {
19625+ struct hlist_head *head = &nx_info_hash[hindex];
19626+ struct hlist_node *pos;
d337f35e 19627+
4bf69007
AM
19628+ spin_lock(&nx_info_hash_lock);
19629+ hlist_for_each(pos, head) {
19630+ struct nx_info *nxi;
19631+
19632+ if (--index > 0)
19633+ continue;
19634+
19635+ nxi = hlist_entry(pos, struct nx_info, nx_hlist);
19636+ nids[nr_nids] = nxi->nx_id;
19637+ if (++nr_nids >= size) {
19638+ spin_unlock(&nx_info_hash_lock);
d337f35e 19639+ goto out;
4bf69007 19640+ }
d337f35e 19641+ }
4bf69007
AM
19642+ /* keep the lock time short */
19643+ spin_unlock(&nx_info_hash_lock);
d337f35e
JR
19644+ }
19645+out:
4bf69007 19646+ return nr_nids;
d337f35e 19647+}
4bf69007 19648+#endif
d337f35e 19649+
4bf69007
AM
19650+
19651+/*
19652+ * migrate task to new network
19653+ * gets nxi, puts old_nxi on change
19654+ */
19655+
19656+int nx_migrate_task(struct task_struct *p, struct nx_info *nxi)
2380c486 19657+{
4bf69007
AM
19658+ struct nx_info *old_nxi;
19659+ int ret = 0;
2380c486 19660+
4bf69007
AM
19661+ if (!p || !nxi)
19662+ BUG();
d337f35e 19663+
4bf69007
AM
19664+ vxdprintk(VXD_CBIT(nid, 5),
19665+ "nx_migrate_task(%p,%p[#%d.%d.%d])",
19666+ p, nxi, nxi->nx_id,
19667+ atomic_read(&nxi->nx_usecnt),
19668+ atomic_read(&nxi->nx_tasks));
d337f35e 19669+
4bf69007
AM
19670+ if (nx_info_flags(nxi, NXF_INFO_PRIVATE, 0) &&
19671+ !nx_info_flags(nxi, NXF_STATE_SETUP, 0))
19672+ return -EACCES;
d337f35e 19673+
4bf69007
AM
19674+ if (nx_info_state(nxi, NXS_SHUTDOWN))
19675+ return -EFAULT;
d337f35e 19676+
4bf69007
AM
19677+ /* maybe disallow this completely? */
19678+ old_nxi = task_get_nx_info(p);
19679+ if (old_nxi == nxi)
19680+ goto out;
d337f35e 19681+
4bf69007
AM
19682+ task_lock(p);
19683+ if (old_nxi)
19684+ clr_nx_info(&p->nx_info);
19685+ claim_nx_info(nxi, p);
19686+ set_nx_info(&p->nx_info, nxi);
19687+ p->nid = nxi->nx_id;
19688+ task_unlock(p);
d337f35e 19689+
4bf69007
AM
19690+ vxdprintk(VXD_CBIT(nid, 5),
19691+ "moved task %p into nxi:%p[#%d]",
19692+ p, nxi, nxi->nx_id);
d337f35e 19693+
4bf69007
AM
19694+ if (old_nxi)
19695+ release_nx_info(old_nxi, p);
19696+ ret = 0;
19697+out:
19698+ put_nx_info(old_nxi);
19699+ return ret;
19700+}
d337f35e 19701+
d337f35e 19702+
4bf69007
AM
19703+void nx_set_persistent(struct nx_info *nxi)
19704+{
19705+ vxdprintk(VXD_CBIT(nid, 6),
19706+ "nx_set_persistent(%p[#%d])", nxi, nxi->nx_id);
d337f35e 19707+
4bf69007
AM
19708+ get_nx_info(nxi);
19709+ claim_nx_info(nxi, NULL);
d337f35e
JR
19710+}
19711+
4bf69007 19712+void nx_clear_persistent(struct nx_info *nxi)
2380c486 19713+{
4bf69007
AM
19714+ vxdprintk(VXD_CBIT(nid, 6),
19715+ "nx_clear_persistent(%p[#%d])", nxi, nxi->nx_id);
2380c486 19716+
4bf69007
AM
19717+ release_nx_info(nxi, NULL);
19718+ put_nx_info(nxi);
2380c486 19719+}
d337f35e 19720+
4bf69007
AM
19721+void nx_update_persistent(struct nx_info *nxi)
19722+{
19723+ if (nx_info_flags(nxi, NXF_PERSISTENT, 0))
19724+ nx_set_persistent(nxi);
19725+ else
19726+ nx_clear_persistent(nxi);
19727+}
d337f35e 19728+
4bf69007
AM
19729+/* vserver syscall commands below here */
19730+
19731+/* taks nid and nx_info functions */
d337f35e 19732+
4bf69007 19733+#include <asm/uaccess.h>
d337f35e
JR
19734+
19735+
4bf69007 19736+int vc_task_nid(uint32_t id)
d337f35e 19737+{
61333608 19738+ vnid_t nid;
d337f35e 19739+
4bf69007
AM
19740+ if (id) {
19741+ struct task_struct *tsk;
d337f35e 19742+
4bf69007
AM
19743+ rcu_read_lock();
19744+ tsk = find_task_by_real_pid(id);
19745+ nid = (tsk) ? tsk->nid : -ESRCH;
19746+ rcu_read_unlock();
19747+ } else
19748+ nid = nx_current_nid();
19749+ return nid;
d337f35e
JR
19750+}
19751+
19752+
4bf69007
AM
19753+int vc_nx_info(struct nx_info *nxi, void __user *data)
19754+{
19755+ struct vcmd_nx_info_v0 vc_data;
d337f35e 19756+
4bf69007 19757+ vc_data.nid = nxi->nx_id;
d337f35e 19758+
4bf69007
AM
19759+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
19760+ return -EFAULT;
19761+ return 0;
19762+}
d337f35e 19763+
d337f35e 19764+
4bf69007 19765+/* network functions */
d337f35e 19766+
4bf69007
AM
19767+int vc_net_create(uint32_t nid, void __user *data)
19768+{
19769+ struct vcmd_net_create vc_data = { .flagword = NXF_INIT_SET };
19770+ struct nx_info *new_nxi;
19771+ int ret;
d337f35e 19772+
4bf69007
AM
19773+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19774+ return -EFAULT;
d337f35e 19775+
4bf69007
AM
19776+ if ((nid > MAX_S_CONTEXT) || (nid < 2))
19777+ return -EINVAL;
d337f35e 19778+
4bf69007
AM
19779+ new_nxi = __create_nx_info(nid);
19780+ if (IS_ERR(new_nxi))
19781+ return PTR_ERR(new_nxi);
d337f35e 19782+
4bf69007
AM
19783+ /* initial flags */
19784+ new_nxi->nx_flags = vc_data.flagword;
d337f35e 19785+
4bf69007
AM
19786+ ret = -ENOEXEC;
19787+ if (vs_net_change(new_nxi, VSC_NETUP))
19788+ goto out;
d337f35e 19789+
4bf69007
AM
19790+ ret = nx_migrate_task(current, new_nxi);
19791+ if (ret)
d337f35e
JR
19792+ goto out;
19793+
4bf69007
AM
19794+ /* return context id on success */
19795+ ret = new_nxi->nx_id;
d337f35e 19796+
4bf69007
AM
19797+ /* get a reference for persistent contexts */
19798+ if ((vc_data.flagword & NXF_PERSISTENT))
19799+ nx_set_persistent(new_nxi);
d337f35e 19800+out:
4bf69007
AM
19801+ release_nx_info(new_nxi, NULL);
19802+ put_nx_info(new_nxi);
19803+ return ret;
d337f35e
JR
19804+}
19805+
d337f35e 19806+
4bf69007
AM
19807+int vc_net_migrate(struct nx_info *nxi, void __user *data)
19808+{
19809+ return nx_migrate_task(current, nxi);
19810+}
d337f35e 19811+
2380c486 19812+
4bf69007
AM
19813+static inline
19814+struct nx_addr_v4 *__find_v4_addr(struct nx_info *nxi,
19815+ __be32 ip, __be32 ip2, __be32 mask, uint16_t type, uint16_t flags,
19816+ struct nx_addr_v4 **prev)
d337f35e 19817+{
4bf69007
AM
19818+ struct nx_addr_v4 *nxa = &nxi->v4;
19819+
19820+ for (; nxa; nxa = nxa->next) {
19821+ if ((nxa->ip[0].s_addr == ip) &&
19822+ (nxa->ip[1].s_addr == ip2) &&
19823+ (nxa->mask.s_addr == mask) &&
19824+ (nxa->type == type) &&
19825+ (nxa->flags == flags))
19826+ return nxa;
19827+
19828+ /* save previous entry */
19829+ if (prev)
19830+ *prev = nxa;
19831+ }
19832+ return NULL;
2380c486
JR
19833+}
19834+
4bf69007
AM
19835+int do_add_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
19836+ uint16_t type, uint16_t flags)
d337f35e 19837+{
4bf69007
AM
19838+ struct nx_addr_v4 *nxa = NULL;
19839+ struct nx_addr_v4 *new = __alloc_nx_addr_v4();
5cb1760b 19840+ unsigned long irqflags;
4bf69007 19841+ int ret = -EEXIST;
d337f35e 19842+
4bf69007
AM
19843+ if (IS_ERR(new))
19844+ return PTR_ERR(new);
d337f35e 19845+
5cb1760b 19846+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19847+ if (__find_v4_addr(nxi, ip, ip2, mask, type, flags, &nxa))
19848+ goto out_unlock;
2380c486 19849+
4bf69007
AM
19850+ if (NX_IPV4(nxi)) {
19851+ nxa->next = new;
19852+ nxa = new;
19853+ new = NULL;
19854+
19855+ /* remove single ip for ip list */
19856+ nxi->nx_flags &= ~NXF_SINGLE_IP;
19857+ }
19858+
19859+ nxa->ip[0].s_addr = ip;
19860+ nxa->ip[1].s_addr = ip2;
19861+ nxa->mask.s_addr = mask;
19862+ nxa->type = type;
19863+ nxa->flags = flags;
19864+ ret = 0;
19865+out_unlock:
5cb1760b 19866+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19867+ if (new)
19868+ __dealloc_nx_addr_v4(new);
19869+ return ret;
d337f35e
JR
19870+}
19871+
4bf69007
AM
19872+int do_remove_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
19873+ uint16_t type, uint16_t flags)
2380c486 19874+{
4bf69007
AM
19875+ struct nx_addr_v4 *nxa = NULL;
19876+ struct nx_addr_v4 *old = NULL;
5cb1760b 19877+ unsigned long irqflags;
4bf69007 19878+ int ret = 0;
2380c486 19879+
5cb1760b 19880+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19881+ switch (type) {
19882+ case NXA_TYPE_ADDR:
19883+ old = __find_v4_addr(nxi, ip, ip2, mask, type, flags, &nxa);
19884+ if (old) {
19885+ if (nxa) {
19886+ nxa->next = old->next;
19887+ old->next = NULL;
19888+ } else {
19889+ if (old->next) {
19890+ nxa = old;
19891+ old = old->next;
19892+ *nxa = *old;
19893+ old->next = NULL;
19894+ } else {
19895+ memset(old, 0, sizeof(*old));
19896+ old = NULL;
19897+ }
19898+ }
19899+ } else
19900+ ret = -ESRCH;
19901+ break;
2380c486 19902+
4bf69007
AM
19903+ case NXA_TYPE_ANY:
19904+ nxa = &nxi->v4;
19905+ old = nxa->next;
19906+ memset(nxa, 0, sizeof(*nxa));
19907+ break;
19908+
19909+ default:
19910+ ret = -EINVAL;
19911+ }
5cb1760b 19912+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19913+ __dealloc_nx_addr_v4_all(old);
19914+ return ret;
2380c486
JR
19915+}
19916+
4bf69007
AM
19917+
19918+int vc_net_add(struct nx_info *nxi, void __user *data)
2380c486 19919+{
4bf69007
AM
19920+ struct vcmd_net_addr_v0 vc_data;
19921+ int index, ret = 0;
2380c486 19922+
4bf69007 19923+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
19924+ return -EFAULT;
19925+
4bf69007
AM
19926+ switch (vc_data.type) {
19927+ case NXA_TYPE_IPV4:
19928+ if ((vc_data.count < 1) || (vc_data.count > 4))
19929+ return -EINVAL;
adc1caaa 19930+
4bf69007
AM
19931+ index = 0;
19932+ while (index < vc_data.count) {
19933+ ret = do_add_v4_addr(nxi, vc_data.ip[index].s_addr, 0,
19934+ vc_data.mask[index].s_addr, NXA_TYPE_ADDR, 0);
19935+ if (ret)
19936+ return ret;
19937+ index++;
19938+ }
19939+ ret = index;
19940+ break;
2380c486 19941+
4bf69007
AM
19942+ case NXA_TYPE_IPV4|NXA_MOD_BCAST:
19943+ nxi->v4_bcast = vc_data.ip[0];
19944+ ret = 1;
19945+ break;
2380c486 19946+
4bf69007
AM
19947+ case NXA_TYPE_IPV4|NXA_MOD_LBACK:
19948+ nxi->v4_lback = vc_data.ip[0];
19949+ ret = 1;
19950+ break;
19951+
19952+ default:
19953+ ret = -EINVAL;
19954+ break;
19955+ }
19956+ return ret;
19957+}
19958+
19959+int vc_net_remove(struct nx_info *nxi, void __user *data)
19960+{
19961+ struct vcmd_net_addr_v0 vc_data;
19962+
19963+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486 19964+ return -EFAULT;
4bf69007
AM
19965+
19966+ switch (vc_data.type) {
19967+ case NXA_TYPE_ANY:
19968+ return do_remove_v4_addr(nxi, 0, 0, 0, vc_data.type, 0);
19969+ default:
19970+ return -EINVAL;
19971+ }
2380c486
JR
19972+ return 0;
19973+}
19974+
d337f35e 19975+
4bf69007 19976+int vc_net_add_ipv4_v1(struct nx_info *nxi, void __user *data)
d337f35e 19977+{
4bf69007
AM
19978+ struct vcmd_net_addr_ipv4_v1 vc_data;
19979+
19980+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19981+ return -EFAULT;
19982+
19983+ switch (vc_data.type) {
19984+ case NXA_TYPE_ADDR:
19985+ case NXA_TYPE_MASK:
19986+ return do_add_v4_addr(nxi, vc_data.ip.s_addr, 0,
19987+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
19988+
19989+ case NXA_TYPE_ADDR | NXA_MOD_BCAST:
19990+ nxi->v4_bcast = vc_data.ip;
19991+ break;
19992+
19993+ case NXA_TYPE_ADDR | NXA_MOD_LBACK:
19994+ nxi->v4_lback = vc_data.ip;
19995+ break;
19996+
19997+ default:
19998+ return -EINVAL;
19999+ }
20000+ return 0;
d337f35e
JR
20001+}
20002+
4bf69007 20003+int vc_net_add_ipv4(struct nx_info *nxi, void __user *data)
d337f35e 20004+{
4bf69007 20005+ struct vcmd_net_addr_ipv4_v2 vc_data;
d337f35e 20006+
4bf69007
AM
20007+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
20008+ return -EFAULT;
20009+
20010+ switch (vc_data.type) {
20011+ case NXA_TYPE_ADDR:
20012+ case NXA_TYPE_MASK:
20013+ case NXA_TYPE_RANGE:
20014+ return do_add_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr,
20015+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
20016+
20017+ case NXA_TYPE_ADDR | NXA_MOD_BCAST:
20018+ nxi->v4_bcast = vc_data.ip;
20019+ break;
20020+
20021+ case NXA_TYPE_ADDR | NXA_MOD_LBACK:
20022+ nxi->v4_lback = vc_data.ip;
20023+ break;
20024+
20025+ default:
20026+ return -EINVAL;
20027+ }
20028+ return 0;
d337f35e
JR
20029+}
20030+
4bf69007 20031+int vc_net_rem_ipv4_v1(struct nx_info *nxi, void __user *data)
d337f35e 20032+{
4bf69007
AM
20033+ struct vcmd_net_addr_ipv4_v1 vc_data;
20034+
20035+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
20036+ return -EFAULT;
20037+
20038+ return do_remove_v4_addr(nxi, vc_data.ip.s_addr, 0,
20039+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
d337f35e
JR
20040+}
20041+
4bf69007 20042+int vc_net_rem_ipv4(struct nx_info *nxi, void __user *data)
d337f35e 20043+{
4bf69007
AM
20044+ struct vcmd_net_addr_ipv4_v2 vc_data;
20045+
20046+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
20047+ return -EFAULT;
20048+
20049+ return do_remove_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr,
20050+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
d337f35e 20051+}
d337f35e 20052+
4bf69007 20053+#ifdef CONFIG_IPV6
d337f35e
JR
20054+
20055+static inline
4bf69007
AM
20056+struct nx_addr_v6 *__find_v6_addr(struct nx_info *nxi,
20057+ struct in6_addr *ip, struct in6_addr *mask,
20058+ uint32_t prefix, uint16_t type, uint16_t flags,
20059+ struct nx_addr_v6 **prev)
d337f35e 20060+{
4bf69007 20061+ struct nx_addr_v6 *nxa = &nxi->v6;
d337f35e 20062+
4bf69007
AM
20063+ for (; nxa; nxa = nxa->next) {
20064+ if (ipv6_addr_equal(&nxa->ip, ip) &&
20065+ ipv6_addr_equal(&nxa->mask, mask) &&
20066+ (nxa->prefix == prefix) &&
20067+ (nxa->type == type) &&
20068+ (nxa->flags == flags))
20069+ return nxa;
20070+
20071+ /* save previous entry */
20072+ if (prev)
20073+ *prev = nxa;
20074+ }
20075+ return NULL;
d337f35e
JR
20076+}
20077+
d337f35e 20078+
4bf69007
AM
20079+int do_add_v6_addr(struct nx_info *nxi,
20080+ struct in6_addr *ip, struct in6_addr *mask,
20081+ uint32_t prefix, uint16_t type, uint16_t flags)
20082+{
20083+ struct nx_addr_v6 *nxa = NULL;
20084+ struct nx_addr_v6 *new = __alloc_nx_addr_v6();
5cb1760b 20085+ unsigned long irqflags;
4bf69007 20086+ int ret = -EEXIST;
d337f35e 20087+
4bf69007
AM
20088+ if (IS_ERR(new))
20089+ return PTR_ERR(new);
d337f35e 20090+
5cb1760b 20091+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
20092+ if (__find_v6_addr(nxi, ip, mask, prefix, type, flags, &nxa))
20093+ goto out_unlock;
d337f35e 20094+
4bf69007
AM
20095+ if (NX_IPV6(nxi)) {
20096+ nxa->next = new;
20097+ nxa = new;
20098+ new = NULL;
20099+ }
d337f35e 20100+
4bf69007
AM
20101+ nxa->ip = *ip;
20102+ nxa->mask = *mask;
20103+ nxa->prefix = prefix;
20104+ nxa->type = type;
20105+ nxa->flags = flags;
20106+ ret = 0;
20107+out_unlock:
5cb1760b 20108+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
20109+ if (new)
20110+ __dealloc_nx_addr_v6(new);
20111+ return ret;
20112+}
d337f35e 20113+
4bf69007
AM
20114+int do_remove_v6_addr(struct nx_info *nxi,
20115+ struct in6_addr *ip, struct in6_addr *mask,
20116+ uint32_t prefix, uint16_t type, uint16_t flags)
d337f35e 20117+{
4bf69007
AM
20118+ struct nx_addr_v6 *nxa = NULL;
20119+ struct nx_addr_v6 *old = NULL;
5cb1760b 20120+ unsigned long irqflags;
4bf69007 20121+ int ret = 0;
d337f35e 20122+
5cb1760b 20123+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
20124+ switch (type) {
20125+ case NXA_TYPE_ADDR:
20126+ old = __find_v6_addr(nxi, ip, mask, prefix, type, flags, &nxa);
20127+ if (old) {
20128+ if (nxa) {
20129+ nxa->next = old->next;
20130+ old->next = NULL;
20131+ } else {
20132+ if (old->next) {
20133+ nxa = old;
20134+ old = old->next;
20135+ *nxa = *old;
20136+ old->next = NULL;
20137+ } else {
20138+ memset(old, 0, sizeof(*old));
20139+ old = NULL;
20140+ }
20141+ }
20142+ } else
20143+ ret = -ESRCH;
20144+ break;
d337f35e 20145+
4bf69007
AM
20146+ case NXA_TYPE_ANY:
20147+ nxa = &nxi->v6;
20148+ old = nxa->next;
20149+ memset(nxa, 0, sizeof(*nxa));
d337f35e
JR
20150+ break;
20151+
d337f35e 20152+ default:
4bf69007 20153+ ret = -EINVAL;
d337f35e 20154+ }
5cb1760b 20155+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
20156+ __dealloc_nx_addr_v6_all(old);
20157+ return ret;
d337f35e
JR
20158+}
20159+
4bf69007 20160+int vc_net_add_ipv6(struct nx_info *nxi, void __user *data)
d337f35e 20161+{
4bf69007 20162+ struct vcmd_net_addr_ipv6_v1 vc_data;
d337f35e 20163+
4bf69007 20164+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
20165+ return -EFAULT;
20166+
4bf69007
AM
20167+ switch (vc_data.type) {
20168+ case NXA_TYPE_ADDR:
20169+ memset(&vc_data.mask, ~0, sizeof(vc_data.mask));
20170+ /* fallthrough */
20171+ case NXA_TYPE_MASK:
20172+ return do_add_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
20173+ vc_data.prefix, vc_data.type, vc_data.flags);
20174+ default:
20175+ return -EINVAL;
20176+ }
20177+ return 0;
20178+}
d337f35e 20179+
4bf69007
AM
20180+int vc_net_remove_ipv6(struct nx_info *nxi, void __user *data)
20181+{
20182+ struct vcmd_net_addr_ipv6_v1 vc_data;
20183+
20184+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
20185+ return -EFAULT;
20186+
20187+ switch (vc_data.type) {
20188+ case NXA_TYPE_ADDR:
20189+ memset(&vc_data.mask, ~0, sizeof(vc_data.mask));
20190+ /* fallthrough */
20191+ case NXA_TYPE_MASK:
20192+ return do_remove_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
20193+ vc_data.prefix, vc_data.type, vc_data.flags);
20194+ case NXA_TYPE_ANY:
20195+ return do_remove_v6_addr(nxi, NULL, NULL, 0, vc_data.type, 0);
20196+ default:
20197+ return -EINVAL;
20198+ }
20199+ return 0;
d337f35e
JR
20200+}
20201+
4bf69007 20202+#endif /* CONFIG_IPV6 */
d337f35e 20203+
4bf69007
AM
20204+
20205+int vc_get_nflags(struct nx_info *nxi, void __user *data)
d337f35e 20206+{
4bf69007 20207+ struct vcmd_net_flags_v0 vc_data;
d337f35e 20208+
4bf69007 20209+ vc_data.flagword = nxi->nx_flags;
d337f35e 20210+
4bf69007
AM
20211+ /* special STATE flag handling */
20212+ vc_data.mask = vs_mask_flags(~0ULL, nxi->nx_flags, NXF_ONE_TIME);
d337f35e 20213+
4bf69007
AM
20214+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
20215+ return -EFAULT;
20216+ return 0;
d337f35e
JR
20217+}
20218+
4bf69007
AM
20219+int vc_set_nflags(struct nx_info *nxi, void __user *data)
20220+{
20221+ struct vcmd_net_flags_v0 vc_data;
20222+ uint64_t mask, trigger;
20223+
20224+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
20225+ return -EFAULT;
d337f35e 20226+
4bf69007
AM
20227+ /* special STATE flag handling */
20228+ mask = vs_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME);
20229+ trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword);
d337f35e 20230+
4bf69007
AM
20231+ nxi->nx_flags = vs_mask_flags(nxi->nx_flags,
20232+ vc_data.flagword, mask);
20233+ if (trigger & NXF_PERSISTENT)
20234+ nx_update_persistent(nxi);
20235+
20236+ return 0;
20237+}
20238+
20239+int vc_get_ncaps(struct nx_info *nxi, void __user *data)
d337f35e 20240+{
4bf69007 20241+ struct vcmd_net_caps_v0 vc_data;
d337f35e 20242+
4bf69007
AM
20243+ vc_data.ncaps = nxi->nx_ncaps;
20244+ vc_data.cmask = ~0ULL;
d337f35e 20245+
2380c486 20246+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
4bf69007
AM
20247+ return -EFAULT;
20248+ return 0;
d337f35e
JR
20249+}
20250+
4bf69007
AM
20251+int vc_set_ncaps(struct nx_info *nxi, void __user *data)
20252+{
20253+ struct vcmd_net_caps_v0 vc_data;
20254+
20255+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
20256+ return -EFAULT;
20257+
20258+ nxi->nx_ncaps = vs_mask_flags(nxi->nx_ncaps,
20259+ vc_data.ncaps, vc_data.cmask);
20260+ return 0;
20261+}
20262+
20263+
20264+#include <linux/module.h>
20265+
20266+module_init(init_network);
20267+
20268+EXPORT_SYMBOL_GPL(free_nx_info);
20269+EXPORT_SYMBOL_GPL(unhash_nx_info);
20270+
f973f73f
AM
20271diff -NurpP --minimal linux-4.1.27/kernel/vserver/proc.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/proc.c
20272--- linux-4.1.27/kernel/vserver/proc.c 1970-01-01 00:00:00.000000000 +0000
20273+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/proc.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 20274@@ -0,0 +1,1100 @@
d337f35e 20275+/*
4bf69007 20276+ * linux/kernel/vserver/proc.c
d337f35e 20277+ *
4bf69007 20278+ * Virtual Context Support
d337f35e 20279+ *
9e3e8383 20280+ * Copyright (C) 2003-2011 Herbert P?tzl
d337f35e 20281+ *
4bf69007
AM
20282+ * V0.01 basic structure
20283+ * V0.02 adaptation vs1.3.0
20284+ * V0.03 proc permissions
20285+ * V0.04 locking/generic
20286+ * V0.05 next generation procfs
20287+ * V0.06 inode validation
20288+ * V0.07 generic rewrite vid
20289+ * V0.08 remove inode type
20290+ * V0.09 added u/wmask info
d337f35e
JR
20291+ *
20292+ */
20293+
4bf69007 20294+#include <linux/proc_fs.h>
ec22aa5c 20295+#include <linux/fs_struct.h>
4bf69007
AM
20296+#include <linux/mount.h>
20297+#include <linux/namei.h>
20298+#include <asm/unistd.h>
2380c486 20299+
d337f35e 20300+#include <linux/vs_context.h>
4bf69007
AM
20301+#include <linux/vs_network.h>
20302+#include <linux/vs_cvirt.h>
d337f35e 20303+
4bf69007
AM
20304+#include <linux/in.h>
20305+#include <linux/inetdevice.h>
20306+#include <linux/vs_inet.h>
20307+#include <linux/vs_inet6.h>
d337f35e 20308+
4bf69007 20309+#include <linux/vserver/global.h>
d337f35e 20310+
4bf69007
AM
20311+#include "cvirt_proc.h"
20312+#include "cacct_proc.h"
20313+#include "limit_proc.h"
20314+#include "sched_proc.h"
20315+#include "vci_config.h"
d337f35e 20316+
09be7631
JR
20317+#include <../../fs/proc/internal.h>
20318+
2380c486 20319+
4bf69007
AM
20320+static inline char *print_cap_t(char *buffer, kernel_cap_t *c)
20321+{
20322+ unsigned __capi;
2380c486 20323+
4bf69007
AM
20324+ CAP_FOR_EACH_U32(__capi) {
20325+ buffer += sprintf(buffer, "%08x",
20326+ c->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]);
20327+ }
20328+ return buffer;
20329+}
2380c486 20330+
d337f35e 20331+
4bf69007 20332+static struct proc_dir_entry *proc_virtual;
d337f35e 20333+
4bf69007 20334+static struct proc_dir_entry *proc_virtnet;
d337f35e 20335+
d337f35e 20336+
4bf69007 20337+/* first the actual feeds */
d337f35e 20338+
d337f35e 20339+
4bf69007
AM
20340+static int proc_vci(char *buffer)
20341+{
20342+ return sprintf(buffer,
20343+ "VCIVersion:\t%04x:%04x\n"
20344+ "VCISyscall:\t%d\n"
20345+ "VCIKernel:\t%08x\n",
20346+ VCI_VERSION >> 16,
20347+ VCI_VERSION & 0xFFFF,
20348+ __NR_vserver,
20349+ vci_kernel_config());
20350+}
d337f35e 20351+
4bf69007
AM
20352+static int proc_virtual_info(char *buffer)
20353+{
20354+ return proc_vci(buffer);
d337f35e
JR
20355+}
20356+
4bf69007
AM
20357+static int proc_virtual_status(char *buffer)
20358+{
20359+ return sprintf(buffer,
20360+ "#CTotal:\t%d\n"
20361+ "#CActive:\t%d\n"
20362+ "#NSProxy:\t%d\t%d %d %d %d %d %d\n"
20363+ "#InitTask:\t%d\t%d %d\n",
20364+ atomic_read(&vx_global_ctotal),
20365+ atomic_read(&vx_global_cactive),
20366+ atomic_read(&vs_global_nsproxy),
20367+ atomic_read(&vs_global_fs),
20368+ atomic_read(&vs_global_mnt_ns),
20369+ atomic_read(&vs_global_uts_ns),
20370+ atomic_read(&nr_ipc_ns),
20371+ atomic_read(&vs_global_user_ns),
20372+ atomic_read(&vs_global_pid_ns),
20373+ atomic_read(&init_task.usage),
20374+ atomic_read(&init_task.nsproxy->count),
20375+ init_task.fs->users);
20376+}
2380c486 20377+
2380c486 20378+
4bf69007 20379+int proc_vxi_info(struct vx_info *vxi, char *buffer)
d337f35e 20380+{
4bf69007 20381+ int length;
d337f35e 20382+
4bf69007
AM
20383+ length = sprintf(buffer,
20384+ "ID:\t%d\n"
20385+ "Info:\t%p\n"
20386+ "Init:\t%d\n"
20387+ "OOM:\t%lld\n",
20388+ vxi->vx_id,
20389+ vxi,
20390+ vxi->vx_initpid,
20391+ vxi->vx_badness_bias);
20392+ return length;
d337f35e
JR
20393+}
20394+
4bf69007 20395+int proc_vxi_status(struct vx_info *vxi, char *buffer)
d337f35e 20396+{
4bf69007 20397+ char *orig = buffer;
d337f35e 20398+
4bf69007
AM
20399+ buffer += sprintf(buffer,
20400+ "UseCnt:\t%d\n"
20401+ "Tasks:\t%d\n"
20402+ "Flags:\t%016llx\n",
20403+ atomic_read(&vxi->vx_usecnt),
20404+ atomic_read(&vxi->vx_tasks),
20405+ (unsigned long long)vxi->vx_flags);
d337f35e 20406+
4bf69007
AM
20407+ buffer += sprintf(buffer, "BCaps:\t");
20408+ buffer = print_cap_t(buffer, &vxi->vx_bcaps);
20409+ buffer += sprintf(buffer, "\n");
ab30d09f 20410+
4bf69007
AM
20411+ buffer += sprintf(buffer,
20412+ "CCaps:\t%016llx\n"
20413+ "Umask:\t%16llx\n"
20414+ "Wmask:\t%16llx\n"
20415+ "Spaces:\t%08lx %08lx\n",
20416+ (unsigned long long)vxi->vx_ccaps,
20417+ (unsigned long long)vxi->vx_umask,
20418+ (unsigned long long)vxi->vx_wmask,
20419+ vxi->space[0].vx_nsmask, vxi->space[1].vx_nsmask);
20420+ return buffer - orig;
20421+}
ab30d09f 20422+
4bf69007
AM
20423+int proc_vxi_limit(struct vx_info *vxi, char *buffer)
20424+{
20425+ return vx_info_proc_limit(&vxi->limit, buffer);
20426+}
d337f35e 20427+
4bf69007
AM
20428+int proc_vxi_sched(struct vx_info *vxi, char *buffer)
20429+{
20430+ int cpu, length;
d337f35e 20431+
4bf69007
AM
20432+ length = vx_info_proc_sched(&vxi->sched, buffer);
20433+ for_each_online_cpu(cpu) {
20434+ length += vx_info_proc_sched_pc(
20435+ &vx_per_cpu(vxi, sched_pc, cpu),
20436+ buffer + length, cpu);
ec22aa5c 20437+ }
4bf69007
AM
20438+ return length;
20439+}
ec22aa5c 20440+
4bf69007
AM
20441+int proc_vxi_nsproxy0(struct vx_info *vxi, char *buffer)
20442+{
20443+ return vx_info_proc_nsproxy(vxi->space[0].vx_nsproxy, buffer);
20444+}
d337f35e 20445+
4bf69007
AM
20446+int proc_vxi_nsproxy1(struct vx_info *vxi, char *buffer)
20447+{
20448+ return vx_info_proc_nsproxy(vxi->space[1].vx_nsproxy, buffer);
20449+}
ec22aa5c 20450+
4bf69007
AM
20451+int proc_vxi_cvirt(struct vx_info *vxi, char *buffer)
20452+{
20453+ int cpu, length;
d33d7b00 20454+
4bf69007
AM
20455+ vx_update_load(vxi);
20456+ length = vx_info_proc_cvirt(&vxi->cvirt, buffer);
20457+ for_each_online_cpu(cpu) {
20458+ length += vx_info_proc_cvirt_pc(
20459+ &vx_per_cpu(vxi, cvirt_pc, cpu),
20460+ buffer + length, cpu);
3bac966d 20461+ }
4bf69007
AM
20462+ return length;
20463+}
3bac966d 20464+
4bf69007
AM
20465+int proc_vxi_cacct(struct vx_info *vxi, char *buffer)
20466+{
20467+ return vx_info_proc_cacct(&vxi->cacct, buffer);
d337f35e
JR
20468+}
20469+
20470+
4bf69007 20471+static int proc_virtnet_info(char *buffer)
d337f35e 20472+{
4bf69007
AM
20473+ return proc_vci(buffer);
20474+}
ab30d09f 20475+
4bf69007
AM
20476+static int proc_virtnet_status(char *buffer)
20477+{
20478+ return sprintf(buffer,
20479+ "#CTotal:\t%d\n"
20480+ "#CActive:\t%d\n",
20481+ atomic_read(&nx_global_ctotal),
20482+ atomic_read(&nx_global_cactive));
20483+}
d337f35e 20484+
4bf69007
AM
20485+int proc_nxi_info(struct nx_info *nxi, char *buffer)
20486+{
20487+ struct nx_addr_v4 *v4a;
20488+#ifdef CONFIG_IPV6
20489+ struct nx_addr_v6 *v6a;
20490+#endif
20491+ int length, i;
ab30d09f 20492+
4bf69007
AM
20493+ length = sprintf(buffer,
20494+ "ID:\t%d\n"
20495+ "Info:\t%p\n"
20496+ "Bcast:\t" NIPQUAD_FMT "\n"
20497+ "Lback:\t" NIPQUAD_FMT "\n",
20498+ nxi->nx_id,
20499+ nxi,
20500+ NIPQUAD(nxi->v4_bcast.s_addr),
20501+ NIPQUAD(nxi->v4_lback.s_addr));
ab30d09f 20502+
4bf69007
AM
20503+ if (!NX_IPV4(nxi))
20504+ goto skip_v4;
20505+ for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
20506+ length += sprintf(buffer + length, "%d:\t" NXAV4_FMT "\n",
20507+ i, NXAV4(v4a));
20508+skip_v4:
20509+#ifdef CONFIG_IPV6
20510+ if (!NX_IPV6(nxi))
20511+ goto skip_v6;
20512+ for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
20513+ length += sprintf(buffer + length, "%d:\t" NXAV6_FMT "\n",
20514+ i, NXAV6(v6a));
20515+skip_v6:
20516+#endif
20517+ return length;
20518+}
2380c486 20519+
4bf69007
AM
20520+int proc_nxi_status(struct nx_info *nxi, char *buffer)
20521+{
20522+ int length;
ec22aa5c 20523+
4bf69007
AM
20524+ length = sprintf(buffer,
20525+ "UseCnt:\t%d\n"
20526+ "Tasks:\t%d\n"
20527+ "Flags:\t%016llx\n"
20528+ "NCaps:\t%016llx\n",
20529+ atomic_read(&nxi->nx_usecnt),
20530+ atomic_read(&nxi->nx_tasks),
20531+ (unsigned long long)nxi->nx_flags,
20532+ (unsigned long long)nxi->nx_ncaps);
20533+ return length;
20534+}
ec22aa5c 20535+
ec22aa5c 20536+
d337f35e 20537+
4bf69007 20538+/* here the inode helpers */
d337f35e 20539+
4bf69007
AM
20540+struct vs_entry {
20541+ int len;
20542+ char *name;
20543+ mode_t mode;
20544+ struct inode_operations *iop;
20545+ struct file_operations *fop;
20546+ union proc_op op;
20547+};
d337f35e 20548+
4bf69007
AM
20549+static struct inode *vs_proc_make_inode(struct super_block *sb, struct vs_entry *p)
20550+{
20551+ struct inode *inode = new_inode(sb);
3bac966d 20552+
4bf69007
AM
20553+ if (!inode)
20554+ goto out;
3bac966d 20555+
4bf69007
AM
20556+ inode->i_mode = p->mode;
20557+ if (p->iop)
20558+ inode->i_op = p->iop;
20559+ if (p->fop)
20560+ inode->i_fop = p->fop;
3bac966d 20561+
4bf69007
AM
20562+ set_nlink(inode, (p->mode & S_IFDIR) ? 2 : 1);
20563+ inode->i_flags |= S_IMMUTABLE;
3bac966d 20564+
4bf69007 20565+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
2380c486 20566+
8ce283e1
AM
20567+ i_uid_write(inode, 0);
20568+ i_gid_write(inode, 0);
20569+ i_tag_write(inode, 0);
4bf69007
AM
20570+out:
20571+ return inode;
d337f35e
JR
20572+}
20573+
4bf69007
AM
20574+static struct dentry *vs_proc_instantiate(struct inode *dir,
20575+ struct dentry *dentry, int id, void *ptr)
2380c486 20576+{
4bf69007
AM
20577+ struct vs_entry *p = ptr;
20578+ struct inode *inode = vs_proc_make_inode(dir->i_sb, p);
20579+ struct dentry *error = ERR_PTR(-EINVAL);
2380c486 20580+
4bf69007
AM
20581+ if (!inode)
20582+ goto out;
2380c486 20583+
4bf69007
AM
20584+ PROC_I(inode)->op = p->op;
20585+ PROC_I(inode)->fd = id;
20586+ d_add(dentry, inode);
20587+ error = NULL;
20588+out:
20589+ return error;
2380c486
JR
20590+}
20591+
4bf69007 20592+/* Lookups */
2380c486 20593+
09be7631
JR
20594+typedef struct dentry *vx_instantiate_t(struct inode *, struct dentry *, int, void *);
20595+
2380c486 20596+
4bf69007
AM
20597+/*
20598+ * Fill a directory entry.
20599+ *
20600+ * If possible create the dcache entry and derive our inode number and
20601+ * file type from dcache entry.
20602+ *
20603+ * Since all of the proc inode numbers are dynamically generated, the inode
20604+ * numbers do not exist until the inode is cache. This means creating the
c2e5f7c8
JR
20605+ * the dcache entry in iterate is necessary to keep the inode numbers
20606+ * reported by iterate in sync with the inode numbers reported
4bf69007
AM
20607+ * by stat.
20608+ */
c2e5f7c8 20609+static int vx_proc_fill_cache(struct file *filp, struct dir_context *ctx,
09be7631 20610+ char *name, int len, vx_instantiate_t instantiate, int id, void *ptr)
2380c486 20611+{
5eef5607 20612+ struct dentry *child, *dir = filp->f_path.dentry;
4bf69007
AM
20613+ struct inode *inode;
20614+ struct qstr qname;
20615+ ino_t ino = 0;
20616+ unsigned type = DT_UNKNOWN;
d337f35e 20617+
4bf69007
AM
20618+ qname.name = name;
20619+ qname.len = len;
20620+ qname.hash = full_name_hash(name, len);
d337f35e 20621+
4bf69007
AM
20622+ child = d_lookup(dir, &qname);
20623+ if (!child) {
20624+ struct dentry *new;
20625+ new = d_alloc(dir, &qname);
20626+ if (new) {
20627+ child = instantiate(dir->d_inode, new, id, ptr);
20628+ if (child)
20629+ dput(new);
20630+ else
20631+ child = new;
20632+ }
20633+ }
20634+ if (!child || IS_ERR(child) || !child->d_inode)
20635+ goto end_instantiate;
20636+ inode = child->d_inode;
20637+ if (inode) {
20638+ ino = inode->i_ino;
20639+ type = inode->i_mode >> 12;
20640+ }
20641+ dput(child);
20642+end_instantiate:
20643+ if (!ino)
4bf69007 20644+ ino = 1;
c2e5f7c8 20645+ return !dir_emit(ctx, name, len, ino, type);
4bf69007 20646+}
d337f35e 20647+
d337f35e 20648+
d337f35e 20649+
4bf69007 20650+/* get and revalidate vx_info/xid */
2380c486 20651+
4bf69007
AM
20652+static inline
20653+struct vx_info *get_proc_vx_info(struct inode *inode)
20654+{
20655+ return lookup_vx_info(PROC_I(inode)->fd);
d337f35e
JR
20656+}
20657+
4bf69007 20658+static int proc_xid_revalidate(struct dentry *dentry, unsigned int flags)
d337f35e 20659+{
4bf69007 20660+ struct inode *inode = dentry->d_inode;
61333608 20661+ vxid_t xid = PROC_I(inode)->fd;
2380c486 20662+
4bf69007
AM
20663+ if (flags & LOOKUP_RCU) /* FIXME: can be dropped? */
20664+ return -ECHILD;
2380c486 20665+
4bf69007
AM
20666+ if (!xid || xid_is_hashed(xid))
20667+ return 1;
20668+ d_drop(dentry);
d337f35e
JR
20669+ return 0;
20670+}
20671+
d337f35e 20672+
4bf69007 20673+/* get and revalidate nx_info/nid */
d337f35e 20674+
4bf69007
AM
20675+static int proc_nid_revalidate(struct dentry *dentry, unsigned int flags)
20676+{
20677+ struct inode *inode = dentry->d_inode;
61333608 20678+ vnid_t nid = PROC_I(inode)->fd;
2380c486 20679+
4bf69007
AM
20680+ if (flags & LOOKUP_RCU) /* FIXME: can be dropped? */
20681+ return -ECHILD;
2380c486 20682+
4bf69007
AM
20683+ if (!nid || nid_is_hashed(nid))
20684+ return 1;
20685+ d_drop(dentry);
20686+ return 0;
d337f35e
JR
20687+}
20688+
4bf69007
AM
20689+
20690+
20691+#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
20692+
20693+static ssize_t proc_vs_info_read(struct file *file, char __user *buf,
20694+ size_t count, loff_t *ppos)
d337f35e 20695+{
5eef5607 20696+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007
AM
20697+ unsigned long page;
20698+ ssize_t length = 0;
20699+
20700+ if (count > PROC_BLOCK_SIZE)
20701+ count = PROC_BLOCK_SIZE;
20702+
20703+ /* fade that out as soon as stable */
20704+ WARN_ON(PROC_I(inode)->fd);
20705+
20706+ if (!(page = __get_free_page(GFP_KERNEL)))
20707+ return -ENOMEM;
20708+
20709+ BUG_ON(!PROC_I(inode)->op.proc_vs_read);
20710+ length = PROC_I(inode)->op.proc_vs_read((char *)page);
20711+
20712+ if (length >= 0)
20713+ length = simple_read_from_buffer(buf, count, ppos,
20714+ (char *)page, length);
20715+
20716+ free_page(page);
20717+ return length;
d337f35e
JR
20718+}
20719+
4bf69007
AM
20720+static ssize_t proc_vx_info_read(struct file *file, char __user *buf,
20721+ size_t count, loff_t *ppos)
20722+{
5eef5607 20723+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007 20724+ struct vx_info *vxi = NULL;
61333608 20725+ vxid_t xid = PROC_I(inode)->fd;
4bf69007
AM
20726+ unsigned long page;
20727+ ssize_t length = 0;
d337f35e 20728+
4bf69007
AM
20729+ if (count > PROC_BLOCK_SIZE)
20730+ count = PROC_BLOCK_SIZE;
20731+
20732+ /* fade that out as soon as stable */
20733+ WARN_ON(!xid);
20734+ vxi = lookup_vx_info(xid);
20735+ if (!vxi)
20736+ goto out;
d337f35e 20737+
4bf69007
AM
20738+ length = -ENOMEM;
20739+ if (!(page = __get_free_page(GFP_KERNEL)))
20740+ goto out_put;
d337f35e 20741+
4bf69007
AM
20742+ BUG_ON(!PROC_I(inode)->op.proc_vxi_read);
20743+ length = PROC_I(inode)->op.proc_vxi_read(vxi, (char *)page);
d337f35e 20744+
4bf69007
AM
20745+ if (length >= 0)
20746+ length = simple_read_from_buffer(buf, count, ppos,
20747+ (char *)page, length);
d337f35e 20748+
4bf69007
AM
20749+ free_page(page);
20750+out_put:
20751+ put_vx_info(vxi);
20752+out:
20753+ return length;
20754+}
20755+
20756+static ssize_t proc_nx_info_read(struct file *file, char __user *buf,
20757+ size_t count, loff_t *ppos)
d337f35e 20758+{
5eef5607 20759+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007 20760+ struct nx_info *nxi = NULL;
61333608 20761+ vnid_t nid = PROC_I(inode)->fd;
4bf69007
AM
20762+ unsigned long page;
20763+ ssize_t length = 0;
d337f35e 20764+
4bf69007
AM
20765+ if (count > PROC_BLOCK_SIZE)
20766+ count = PROC_BLOCK_SIZE;
d337f35e 20767+
4bf69007
AM
20768+ /* fade that out as soon as stable */
20769+ WARN_ON(!nid);
20770+ nxi = lookup_nx_info(nid);
20771+ if (!nxi)
20772+ goto out;
d337f35e 20773+
4bf69007
AM
20774+ length = -ENOMEM;
20775+ if (!(page = __get_free_page(GFP_KERNEL)))
20776+ goto out_put;
d337f35e 20777+
4bf69007
AM
20778+ BUG_ON(!PROC_I(inode)->op.proc_nxi_read);
20779+ length = PROC_I(inode)->op.proc_nxi_read(nxi, (char *)page);
2380c486 20780+
4bf69007
AM
20781+ if (length >= 0)
20782+ length = simple_read_from_buffer(buf, count, ppos,
20783+ (char *)page, length);
d337f35e 20784+
4bf69007
AM
20785+ free_page(page);
20786+out_put:
20787+ put_nx_info(nxi);
20788+out:
20789+ return length;
20790+}
2380c486 20791+
d337f35e 20792+
763640ca 20793+
4bf69007 20794+/* here comes the lower level */
763640ca 20795+
265d6dcc 20796+
4bf69007
AM
20797+#define NOD(NAME, MODE, IOP, FOP, OP) { \
20798+ .len = sizeof(NAME) - 1, \
20799+ .name = (NAME), \
20800+ .mode = MODE, \
20801+ .iop = IOP, \
20802+ .fop = FOP, \
20803+ .op = OP, \
20804+}
d337f35e 20805+
d337f35e 20806+
4bf69007
AM
20807+#define DIR(NAME, MODE, OTYPE) \
20808+ NOD(NAME, (S_IFDIR | (MODE)), \
20809+ &proc_ ## OTYPE ## _inode_operations, \
20810+ &proc_ ## OTYPE ## _file_operations, { } )
d337f35e 20811+
4bf69007
AM
20812+#define INF(NAME, MODE, OTYPE) \
20813+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20814+ &proc_vs_info_file_operations, \
20815+ { .proc_vs_read = &proc_##OTYPE } )
d337f35e 20816+
4bf69007
AM
20817+#define VINF(NAME, MODE, OTYPE) \
20818+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20819+ &proc_vx_info_file_operations, \
20820+ { .proc_vxi_read = &proc_##OTYPE } )
2380c486 20821+
4bf69007
AM
20822+#define NINF(NAME, MODE, OTYPE) \
20823+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20824+ &proc_nx_info_file_operations, \
20825+ { .proc_nxi_read = &proc_##OTYPE } )
d337f35e 20826+
d337f35e 20827+
4bf69007
AM
20828+static struct file_operations proc_vs_info_file_operations = {
20829+ .read = proc_vs_info_read,
20830+};
d337f35e 20831+
4bf69007
AM
20832+static struct file_operations proc_vx_info_file_operations = {
20833+ .read = proc_vx_info_read,
20834+};
d337f35e 20835+
4bf69007
AM
20836+static struct dentry_operations proc_xid_dentry_operations = {
20837+ .d_revalidate = proc_xid_revalidate,
20838+};
d337f35e 20839+
4bf69007
AM
20840+static struct vs_entry vx_base_stuff[] = {
20841+ VINF("info", S_IRUGO, vxi_info),
20842+ VINF("status", S_IRUGO, vxi_status),
20843+ VINF("limit", S_IRUGO, vxi_limit),
20844+ VINF("sched", S_IRUGO, vxi_sched),
20845+ VINF("nsproxy", S_IRUGO, vxi_nsproxy0),
20846+ VINF("nsproxy1",S_IRUGO, vxi_nsproxy1),
20847+ VINF("cvirt", S_IRUGO, vxi_cvirt),
20848+ VINF("cacct", S_IRUGO, vxi_cacct),
20849+ {}
20850+};
2380c486 20851+
d337f35e 20852+
d337f35e 20853+
d337f35e 20854+
4bf69007
AM
20855+static struct dentry *proc_xid_instantiate(struct inode *dir,
20856+ struct dentry *dentry, int id, void *ptr)
20857+{
20858+ dentry->d_op = &proc_xid_dentry_operations;
20859+ return vs_proc_instantiate(dir, dentry, id, ptr);
20860+}
2380c486 20861+
4bf69007
AM
20862+static struct dentry *proc_xid_lookup(struct inode *dir,
20863+ struct dentry *dentry, unsigned int flags)
20864+{
20865+ struct vs_entry *p = vx_base_stuff;
20866+ struct dentry *error = ERR_PTR(-ENOENT);
2380c486 20867+
4bf69007
AM
20868+ for (; p->name; p++) {
20869+ if (p->len != dentry->d_name.len)
20870+ continue;
20871+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20872+ break;
20873+ }
20874+ if (!p->name)
20875+ goto out;
d337f35e 20876+
4bf69007
AM
20877+ error = proc_xid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
20878+out:
20879+ return error;
20880+}
9f7054f1 20881+
c2e5f7c8 20882+static int proc_xid_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 20883+{
5eef5607 20884+ struct dentry *dentry = filp->f_path.dentry;
4bf69007
AM
20885+ struct inode *inode = dentry->d_inode;
20886+ struct vs_entry *p = vx_base_stuff;
20887+ int size = sizeof(vx_base_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20888+ int index;
4bf69007 20889+ u64 ino;
2380c486 20890+
c2e5f7c8 20891+ switch (ctx->pos) {
4bf69007
AM
20892+ case 0:
20893+ ino = inode->i_ino;
c2e5f7c8 20894+ if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
4bf69007 20895+ goto out;
c2e5f7c8 20896+ ctx->pos++;
4bf69007
AM
20897+ /* fall through */
20898+ case 1:
20899+ ino = parent_ino(dentry);
c2e5f7c8 20900+ if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
4bf69007 20901+ goto out;
c2e5f7c8 20902+ ctx->pos++;
4bf69007 20903+ /* fall through */
d337f35e 20904+ default:
c2e5f7c8 20905+ index = ctx->pos - 2;
4bf69007
AM
20906+ if (index >= size)
20907+ goto out;
20908+ for (p += index; p->name; p++) {
c2e5f7c8 20909+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007
AM
20910+ vs_proc_instantiate, PROC_I(inode)->fd, p))
20911+ goto out;
c2e5f7c8 20912+ ctx->pos++;
4bf69007 20913+ }
d337f35e 20914+ }
4bf69007 20915+out:
4bf69007 20916+ return 1;
d337f35e
JR
20917+}
20918+
20919+
d337f35e 20920+
4bf69007
AM
20921+static struct file_operations proc_nx_info_file_operations = {
20922+ .read = proc_nx_info_read,
20923+};
d337f35e 20924+
4bf69007
AM
20925+static struct dentry_operations proc_nid_dentry_operations = {
20926+ .d_revalidate = proc_nid_revalidate,
20927+};
d337f35e 20928+
4bf69007
AM
20929+static struct vs_entry nx_base_stuff[] = {
20930+ NINF("info", S_IRUGO, nxi_info),
20931+ NINF("status", S_IRUGO, nxi_status),
20932+ {}
20933+};
2380c486 20934+
d337f35e 20935+
4bf69007
AM
20936+static struct dentry *proc_nid_instantiate(struct inode *dir,
20937+ struct dentry *dentry, int id, void *ptr)
d337f35e 20938+{
4bf69007
AM
20939+ dentry->d_op = &proc_nid_dentry_operations;
20940+ return vs_proc_instantiate(dir, dentry, id, ptr);
20941+}
d337f35e 20942+
4bf69007
AM
20943+static struct dentry *proc_nid_lookup(struct inode *dir,
20944+ struct dentry *dentry, unsigned int flags)
20945+{
20946+ struct vs_entry *p = nx_base_stuff;
20947+ struct dentry *error = ERR_PTR(-ENOENT);
d337f35e 20948+
4bf69007
AM
20949+ for (; p->name; p++) {
20950+ if (p->len != dentry->d_name.len)
20951+ continue;
20952+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20953+ break;
20954+ }
20955+ if (!p->name)
20956+ goto out;
d337f35e 20957+
4bf69007
AM
20958+ error = proc_nid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
20959+out:
20960+ return error;
20961+}
d337f35e 20962+
c2e5f7c8 20963+static int proc_nid_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 20964+{
5eef5607 20965+ struct dentry *dentry = filp->f_path.dentry;
4bf69007
AM
20966+ struct inode *inode = dentry->d_inode;
20967+ struct vs_entry *p = nx_base_stuff;
20968+ int size = sizeof(nx_base_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20969+ int index;
4bf69007 20970+ u64 ino;
d337f35e 20971+
c2e5f7c8 20972+ switch (ctx->pos) {
4bf69007
AM
20973+ case 0:
20974+ ino = inode->i_ino;
c2e5f7c8 20975+ if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
4bf69007 20976+ goto out;
c2e5f7c8 20977+ ctx->pos++;
4bf69007
AM
20978+ /* fall through */
20979+ case 1:
20980+ ino = parent_ino(dentry);
c2e5f7c8 20981+ if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
4bf69007 20982+ goto out;
c2e5f7c8 20983+ ctx->pos++;
4bf69007
AM
20984+ /* fall through */
20985+ default:
c2e5f7c8 20986+ index = ctx->pos - 2;
4bf69007
AM
20987+ if (index >= size)
20988+ goto out;
20989+ for (p += index; p->name; p++) {
c2e5f7c8 20990+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007
AM
20991+ vs_proc_instantiate, PROC_I(inode)->fd, p))
20992+ goto out;
c2e5f7c8 20993+ ctx->pos++;
4bf69007
AM
20994+ }
20995+ }
20996+out:
4bf69007
AM
20997+ return 1;
20998+}
2380c486 20999+
d337f35e 21000+
4bf69007 21001+#define MAX_MULBY10 ((~0U - 9) / 10)
d337f35e 21002+
4bf69007
AM
21003+static inline int atovid(const char *str, int len)
21004+{
21005+ int vid, c;
d337f35e 21006+
4bf69007
AM
21007+ vid = 0;
21008+ while (len-- > 0) {
21009+ c = *str - '0';
21010+ str++;
21011+ if (c > 9)
21012+ return -1;
21013+ if (vid >= MAX_MULBY10)
21014+ return -1;
21015+ vid *= 10;
21016+ vid += c;
21017+ if (!vid)
21018+ return -1;
21019+ }
21020+ return vid;
21021+}
2380c486 21022+
4bf69007 21023+/* now the upper level (virtual) */
2380c486 21024+
2380c486 21025+
4bf69007
AM
21026+static struct file_operations proc_xid_file_operations = {
21027+ .read = generic_read_dir,
c2e5f7c8 21028+ .iterate = proc_xid_iterate,
4bf69007 21029+};
2380c486 21030+
4bf69007
AM
21031+static struct inode_operations proc_xid_inode_operations = {
21032+ .lookup = proc_xid_lookup,
21033+};
d337f35e 21034+
4bf69007
AM
21035+static struct vs_entry vx_virtual_stuff[] = {
21036+ INF("info", S_IRUGO, virtual_info),
21037+ INF("status", S_IRUGO, virtual_status),
21038+ DIR(NULL, S_IRUGO | S_IXUGO, xid),
21039+};
2380c486 21040+
d337f35e 21041+
4bf69007
AM
21042+static struct dentry *proc_virtual_lookup(struct inode *dir,
21043+ struct dentry *dentry, unsigned int flags)
21044+{
21045+ struct vs_entry *p = vx_virtual_stuff;
21046+ struct dentry *error = ERR_PTR(-ENOENT);
21047+ int id = 0;
d337f35e 21048+
4bf69007
AM
21049+ for (; p->name; p++) {
21050+ if (p->len != dentry->d_name.len)
21051+ continue;
21052+ if (!memcmp(dentry->d_name.name, p->name, p->len))
21053+ break;
21054+ }
21055+ if (p->name)
21056+ goto instantiate;
d337f35e 21057+
4bf69007
AM
21058+ id = atovid(dentry->d_name.name, dentry->d_name.len);
21059+ if ((id < 0) || !xid_is_hashed(id))
d337f35e
JR
21060+ goto out;
21061+
4bf69007
AM
21062+instantiate:
21063+ error = proc_xid_instantiate(dir, dentry, id, p);
21064+out:
21065+ return error;
21066+}
d337f35e 21067+
4bf69007
AM
21068+static struct file_operations proc_nid_file_operations = {
21069+ .read = generic_read_dir,
c2e5f7c8 21070+ .iterate = proc_nid_iterate,
4bf69007 21071+};
d337f35e 21072+
4bf69007
AM
21073+static struct inode_operations proc_nid_inode_operations = {
21074+ .lookup = proc_nid_lookup,
21075+};
d337f35e 21076+
4bf69007
AM
21077+static struct vs_entry nx_virtnet_stuff[] = {
21078+ INF("info", S_IRUGO, virtnet_info),
21079+ INF("status", S_IRUGO, virtnet_status),
21080+ DIR(NULL, S_IRUGO | S_IXUGO, nid),
21081+};
d337f35e 21082+
d337f35e 21083+
4bf69007
AM
21084+static struct dentry *proc_virtnet_lookup(struct inode *dir,
21085+ struct dentry *dentry, unsigned int flags)
21086+{
21087+ struct vs_entry *p = nx_virtnet_stuff;
21088+ struct dentry *error = ERR_PTR(-ENOENT);
21089+ int id = 0;
d337f35e 21090+
4bf69007
AM
21091+ for (; p->name; p++) {
21092+ if (p->len != dentry->d_name.len)
21093+ continue;
21094+ if (!memcmp(dentry->d_name.name, p->name, p->len))
21095+ break;
21096+ }
21097+ if (p->name)
21098+ goto instantiate;
d337f35e 21099+
4bf69007
AM
21100+ id = atovid(dentry->d_name.name, dentry->d_name.len);
21101+ if ((id < 0) || !nid_is_hashed(id))
d337f35e
JR
21102+ goto out;
21103+
4bf69007
AM
21104+instantiate:
21105+ error = proc_nid_instantiate(dir, dentry, id, p);
21106+out:
21107+ return error;
21108+}
2380c486 21109+
d337f35e 21110+
4bf69007
AM
21111+#define PROC_MAXVIDS 32
21112+
c2e5f7c8 21113+int proc_virtual_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 21114+{
5eef5607 21115+ struct dentry *dentry = filp->f_path.dentry;
4bf69007
AM
21116+ struct inode *inode = dentry->d_inode;
21117+ struct vs_entry *p = vx_virtual_stuff;
21118+ int size = sizeof(vx_virtual_stuff) / sizeof(struct vs_entry);
c2e5f7c8 21119+ int index;
4bf69007
AM
21120+ unsigned int xid_array[PROC_MAXVIDS];
21121+ char buf[PROC_NUMBUF];
21122+ unsigned int nr_xids, i;
21123+ u64 ino;
21124+
c2e5f7c8 21125+ switch (ctx->pos) {
4bf69007
AM
21126+ case 0:
21127+ ino = inode->i_ino;
c2e5f7c8 21128+ if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
4bf69007 21129+ goto out;
c2e5f7c8 21130+ ctx->pos++;
4bf69007
AM
21131+ /* fall through */
21132+ case 1:
21133+ ino = parent_ino(dentry);
c2e5f7c8 21134+ if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
4bf69007 21135+ goto out;
c2e5f7c8 21136+ ctx->pos++;
4bf69007
AM
21137+ /* fall through */
21138+ default:
c2e5f7c8 21139+ index = ctx->pos - 2;
4bf69007
AM
21140+ if (index >= size)
21141+ goto entries;
21142+ for (p += index; p->name; p++) {
c2e5f7c8 21143+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007
AM
21144+ vs_proc_instantiate, 0, p))
21145+ goto out;
c2e5f7c8 21146+ ctx->pos++;
d337f35e 21147+ }
4bf69007 21148+ entries:
c2e5f7c8 21149+ index = ctx->pos - size;
4bf69007
AM
21150+ p = &vx_virtual_stuff[size - 1];
21151+ nr_xids = get_xid_list(index, xid_array, PROC_MAXVIDS);
21152+ for (i = 0; i < nr_xids; i++) {
21153+ int n, xid = xid_array[i];
21154+ unsigned int j = PROC_NUMBUF;
d337f35e 21155+
4bf69007
AM
21156+ n = xid;
21157+ do
21158+ buf[--j] = '0' + (n % 10);
21159+ while (n /= 10);
21160+
c2e5f7c8 21161+ if (vx_proc_fill_cache(filp, ctx,
4bf69007
AM
21162+ buf + j, PROC_NUMBUF - j,
21163+ vs_proc_instantiate, xid, p))
21164+ goto out;
c2e5f7c8 21165+ ctx->pos++;
d337f35e
JR
21166+ }
21167+ }
d337f35e 21168+out:
4bf69007 21169+ return 0;
d337f35e
JR
21170+}
21171+
4bf69007
AM
21172+static int proc_virtual_getattr(struct vfsmount *mnt,
21173+ struct dentry *dentry, struct kstat *stat)
d337f35e 21174+{
4bf69007 21175+ struct inode *inode = dentry->d_inode;
d337f35e 21176+
4bf69007
AM
21177+ generic_fillattr(inode, stat);
21178+ stat->nlink = 2 + atomic_read(&vx_global_cactive);
21179+ return 0;
d337f35e
JR
21180+}
21181+
4bf69007
AM
21182+static struct file_operations proc_virtual_dir_operations = {
21183+ .read = generic_read_dir,
c2e5f7c8 21184+ .iterate = proc_virtual_iterate,
d337f35e
JR
21185+};
21186+
4bf69007
AM
21187+static struct inode_operations proc_virtual_dir_inode_operations = {
21188+ .getattr = proc_virtual_getattr,
21189+ .lookup = proc_virtual_lookup,
21190+};
d337f35e 21191+
d337f35e
JR
21192+
21193+
c2e5f7c8 21194+int proc_virtnet_iterate(struct file *filp, struct dir_context *ctx)
d337f35e 21195+{
5eef5607 21196+ struct dentry *dentry = filp->f_path.dentry;
4bf69007
AM
21197+ struct inode *inode = dentry->d_inode;
21198+ struct vs_entry *p = nx_virtnet_stuff;
21199+ int size = sizeof(nx_virtnet_stuff) / sizeof(struct vs_entry);
c2e5f7c8 21200+ int index;
4bf69007
AM
21201+ unsigned int nid_array[PROC_MAXVIDS];
21202+ char buf[PROC_NUMBUF];
21203+ unsigned int nr_nids, i;
21204+ u64 ino;
d337f35e 21205+
c2e5f7c8 21206+ switch (ctx->pos) {
4bf69007
AM
21207+ case 0:
21208+ ino = inode->i_ino;
c2e5f7c8 21209+ if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
4bf69007 21210+ goto out;
c2e5f7c8 21211+ ctx->pos++;
4bf69007
AM
21212+ /* fall through */
21213+ case 1:
21214+ ino = parent_ino(dentry);
c2e5f7c8 21215+ if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
4bf69007 21216+ goto out;
c2e5f7c8 21217+ ctx->pos++;
4bf69007
AM
21218+ /* fall through */
21219+ default:
c2e5f7c8 21220+ index = ctx->pos - 2;
4bf69007
AM
21221+ if (index >= size)
21222+ goto entries;
21223+ for (p += index; p->name; p++) {
c2e5f7c8 21224+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007
AM
21225+ vs_proc_instantiate, 0, p))
21226+ goto out;
c2e5f7c8 21227+ ctx->pos++;
4bf69007
AM
21228+ }
21229+ entries:
c2e5f7c8 21230+ index = ctx->pos - size;
4bf69007
AM
21231+ p = &nx_virtnet_stuff[size - 1];
21232+ nr_nids = get_nid_list(index, nid_array, PROC_MAXVIDS);
21233+ for (i = 0; i < nr_nids; i++) {
21234+ int n, nid = nid_array[i];
21235+ unsigned int j = PROC_NUMBUF;
d337f35e 21236+
4bf69007
AM
21237+ n = nid;
21238+ do
21239+ buf[--j] = '0' + (n % 10);
21240+ while (n /= 10);
d337f35e 21241+
c2e5f7c8 21242+ if (vx_proc_fill_cache(filp, ctx,
4bf69007
AM
21243+ buf + j, PROC_NUMBUF - j,
21244+ vs_proc_instantiate, nid, p))
21245+ goto out;
c2e5f7c8 21246+ ctx->pos++;
d337f35e
JR
21247+ }
21248+ }
4bf69007 21249+out:
d337f35e
JR
21250+ return 0;
21251+}
21252+
4bf69007
AM
21253+static int proc_virtnet_getattr(struct vfsmount *mnt,
21254+ struct dentry *dentry, struct kstat *stat)
21255+{
21256+ struct inode *inode = dentry->d_inode;
d337f35e 21257+
4bf69007
AM
21258+ generic_fillattr(inode, stat);
21259+ stat->nlink = 2 + atomic_read(&nx_global_cactive);
21260+ return 0;
21261+}
d337f35e 21262+
4bf69007
AM
21263+static struct file_operations proc_virtnet_dir_operations = {
21264+ .read = generic_read_dir,
c2e5f7c8 21265+ .iterate = proc_virtnet_iterate,
d337f35e
JR
21266+};
21267+
4bf69007
AM
21268+static struct inode_operations proc_virtnet_dir_inode_operations = {
21269+ .getattr = proc_virtnet_getattr,
21270+ .lookup = proc_virtnet_lookup,
d337f35e
JR
21271+};
21272+
d337f35e
JR
21273+
21274+
4bf69007 21275+void proc_vx_init(void)
d337f35e 21276+{
4bf69007 21277+ struct proc_dir_entry *ent;
d337f35e 21278+
4bf69007
AM
21279+ ent = proc_mkdir("virtual", 0);
21280+ if (ent) {
21281+ ent->proc_fops = &proc_virtual_dir_operations;
21282+ ent->proc_iops = &proc_virtual_dir_inode_operations;
21283+ }
21284+ proc_virtual = ent;
d337f35e 21285+
4bf69007
AM
21286+ ent = proc_mkdir("virtnet", 0);
21287+ if (ent) {
21288+ ent->proc_fops = &proc_virtnet_dir_operations;
21289+ ent->proc_iops = &proc_virtnet_dir_inode_operations;
d337f35e 21290+ }
4bf69007 21291+ proc_virtnet = ent;
d337f35e
JR
21292+}
21293+
d337f35e 21294+
2380c486 21295+
2380c486 21296+
4bf69007 21297+/* per pid info */
2380c486 21298+
bb20add7
AM
21299+void render_cap_t(struct seq_file *, const char *,
21300+ struct vx_info *, kernel_cap_t *);
21301+
2380c486 21302+
bb20add7
AM
21303+int proc_pid_vx_info(
21304+ struct seq_file *m,
21305+ struct pid_namespace *ns,
21306+ struct pid *pid,
21307+ struct task_struct *p)
2380c486 21308+{
4bf69007 21309+ struct vx_info *vxi;
2380c486 21310+
bb20add7 21311+ seq_printf(m, "XID:\t%d\n", vx_task_xid(p));
2380c486 21312+
4bf69007
AM
21313+ vxi = task_get_vx_info(p);
21314+ if (!vxi)
bb20add7 21315+ return 0;
2380c486 21316+
bb20add7
AM
21317+ render_cap_t(m, "BCaps:\t", vxi, &vxi->vx_bcaps);
21318+ seq_printf(m, "CCaps:\t%016llx\n",
4bf69007 21319+ (unsigned long long)vxi->vx_ccaps);
bb20add7 21320+ seq_printf(m, "CFlags:\t%016llx\n",
4bf69007 21321+ (unsigned long long)vxi->vx_flags);
bb20add7 21322+ seq_printf(m, "CIPid:\t%d\n", vxi->vx_initpid);
4bf69007
AM
21323+
21324+ put_vx_info(vxi);
bb20add7 21325+ return 0;
2380c486
JR
21326+}
21327+
2380c486 21328+
bb20add7
AM
21329+int proc_pid_nx_info(
21330+ struct seq_file *m,
21331+ struct pid_namespace *ns,
21332+ struct pid *pid,
21333+ struct task_struct *p)
4bf69007
AM
21334+{
21335+ struct nx_info *nxi;
21336+ struct nx_addr_v4 *v4a;
21337+#ifdef CONFIG_IPV6
21338+ struct nx_addr_v6 *v6a;
21339+#endif
4bf69007 21340+ int i;
2380c486 21341+
bb20add7 21342+ seq_printf(m, "NID:\t%d\n", nx_task_nid(p));
2380c486 21343+
4bf69007
AM
21344+ nxi = task_get_nx_info(p);
21345+ if (!nxi)
bb20add7 21346+ return 0;
2380c486 21347+
bb20add7 21348+ seq_printf(m, "NCaps:\t%016llx\n",
4bf69007 21349+ (unsigned long long)nxi->nx_ncaps);
bb20add7 21350+ seq_printf(m, "NFlags:\t%016llx\n",
4bf69007
AM
21351+ (unsigned long long)nxi->nx_flags);
21352+
bb20add7 21353+ seq_printf(m, "V4Root[bcast]:\t" NIPQUAD_FMT "\n",
4bf69007 21354+ NIPQUAD(nxi->v4_bcast.s_addr));
bb20add7 21355+ seq_printf(m, "V4Root[lback]:\t" NIPQUAD_FMT "\n",
4bf69007
AM
21356+ NIPQUAD(nxi->v4_lback.s_addr));
21357+ if (!NX_IPV4(nxi))
21358+ goto skip_v4;
21359+ for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
bb20add7 21360+ seq_printf(m, "V4Root[%d]:\t" NXAV4_FMT "\n",
4bf69007
AM
21361+ i, NXAV4(v4a));
21362+skip_v4:
21363+#ifdef CONFIG_IPV6
21364+ if (!NX_IPV6(nxi))
21365+ goto skip_v6;
21366+ for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
bb20add7 21367+ seq_printf(m, "V6Root[%d]:\t" NXAV6_FMT "\n",
4bf69007
AM
21368+ i, NXAV6(v6a));
21369+skip_v6:
21370+#endif
21371+ put_nx_info(nxi);
bb20add7 21372+ return 0;
2380c486
JR
21373+}
21374+
f973f73f
AM
21375diff -NurpP --minimal linux-4.1.27/kernel/vserver/sched.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/sched.c
21376--- linux-4.1.27/kernel/vserver/sched.c 1970-01-01 00:00:00.000000000 +0000
21377+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/sched.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
21378@@ -0,0 +1,83 @@
21379+/*
21380+ * linux/kernel/vserver/sched.c
21381+ *
21382+ * Virtual Server: Scheduler Support
21383+ *
9e3e8383 21384+ * Copyright (C) 2004-2010 Herbert P?tzl
4bf69007
AM
21385+ *
21386+ * V0.01 adapted Sam Vilains version to 2.6.3
21387+ * V0.02 removed legacy interface
21388+ * V0.03 changed vcmds to vxi arg
21389+ * V0.04 removed older and legacy interfaces
21390+ * V0.05 removed scheduler code/commands
21391+ *
21392+ */
21393+
21394+#include <linux/vs_context.h>
21395+#include <linux/vs_sched.h>
21396+#include <linux/cpumask.h>
21397+#include <linux/vserver/sched_cmd.h>
2380c486 21398+
4bf69007
AM
21399+#include <asm/uaccess.h>
21400+
21401+
21402+void vx_update_sched_param(struct _vx_sched *sched,
21403+ struct _vx_sched_pc *sched_pc)
2380c486 21404+{
4bf69007 21405+ sched_pc->prio_bias = sched->prio_bias;
2380c486
JR
21406+}
21407+
4bf69007
AM
21408+static int do_set_prio_bias(struct vx_info *vxi, struct vcmd_prio_bias *data)
21409+{
21410+ int cpu;
2380c486 21411+
4bf69007
AM
21412+ if (data->prio_bias > MAX_PRIO_BIAS)
21413+ data->prio_bias = MAX_PRIO_BIAS;
21414+ if (data->prio_bias < MIN_PRIO_BIAS)
21415+ data->prio_bias = MIN_PRIO_BIAS;
2380c486 21416+
4bf69007 21417+ if (data->cpu_id != ~0) {
5eef5607 21418+ vxi->sched.update = *get_cpu_mask(data->cpu_id);
4bf69007
AM
21419+ cpumask_and(&vxi->sched.update, &vxi->sched.update,
21420+ cpu_online_mask);
21421+ } else
21422+ cpumask_copy(&vxi->sched.update, cpu_online_mask);
2380c486 21423+
5eef5607 21424+ for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)vxi->sched.update)
4bf69007
AM
21425+ vx_update_sched_param(&vxi->sched,
21426+ &vx_per_cpu(vxi, sched_pc, cpu));
21427+ return 0;
21428+}
2380c486 21429+
4bf69007
AM
21430+int vc_set_prio_bias(struct vx_info *vxi, void __user *data)
21431+{
21432+ struct vcmd_prio_bias vc_data;
d337f35e 21433+
4bf69007
AM
21434+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21435+ return -EFAULT;
d337f35e 21436+
4bf69007
AM
21437+ return do_set_prio_bias(vxi, &vc_data);
21438+}
d337f35e 21439+
4bf69007
AM
21440+int vc_get_prio_bias(struct vx_info *vxi, void __user *data)
21441+{
21442+ struct vcmd_prio_bias vc_data;
21443+ struct _vx_sched_pc *pcd;
21444+ int cpu;
d337f35e 21445+
4bf69007
AM
21446+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21447+ return -EFAULT;
2380c486 21448+
4bf69007 21449+ cpu = vc_data.cpu_id;
d337f35e 21450+
4bf69007
AM
21451+ if (!cpu_possible(cpu))
21452+ return -EINVAL;
d337f35e 21453+
4bf69007
AM
21454+ pcd = &vx_per_cpu(vxi, sched_pc, cpu);
21455+ vc_data.prio_bias = pcd->prio_bias;
d337f35e 21456+
4bf69007
AM
21457+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
21458+ return -EFAULT;
21459+ return 0;
21460+}
d337f35e 21461+
f973f73f
AM
21462diff -NurpP --minimal linux-4.1.27/kernel/vserver/sched_init.h linux-4.1.27-vs2.3.8.5.2/kernel/vserver/sched_init.h
21463--- linux-4.1.27/kernel/vserver/sched_init.h 1970-01-01 00:00:00.000000000 +0000
21464+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/sched_init.h 2016-07-05 04:41:47.000000000 +0000
4bf69007 21465@@ -0,0 +1,27 @@
2380c486 21466+
4bf69007
AM
21467+static inline void vx_info_init_sched(struct _vx_sched *sched)
21468+{
21469+ /* scheduling; hard code starting values as constants */
21470+ sched->prio_bias = 0;
d337f35e
JR
21471+}
21472+
4bf69007
AM
21473+static inline
21474+void vx_info_init_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
e3afe727 21475+{
4bf69007
AM
21476+ sched_pc->prio_bias = 0;
21477+
21478+ sched_pc->user_ticks = 0;
21479+ sched_pc->sys_ticks = 0;
21480+ sched_pc->hold_ticks = 0;
e3afe727
AM
21481+}
21482+
4bf69007 21483+static inline void vx_info_exit_sched(struct _vx_sched *sched)
e3afe727 21484+{
4bf69007 21485+ return;
e3afe727
AM
21486+}
21487+
4bf69007
AM
21488+static inline
21489+void vx_info_exit_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
e3afe727 21490+{
4bf69007 21491+ return;
e3afe727 21492+}
f973f73f
AM
21493diff -NurpP --minimal linux-4.1.27/kernel/vserver/sched_proc.h linux-4.1.27-vs2.3.8.5.2/kernel/vserver/sched_proc.h
21494--- linux-4.1.27/kernel/vserver/sched_proc.h 1970-01-01 00:00:00.000000000 +0000
21495+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/sched_proc.h 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
21496@@ -0,0 +1,32 @@
21497+#ifndef _VX_SCHED_PROC_H
21498+#define _VX_SCHED_PROC_H
e3afe727 21499+
4bf69007
AM
21500+
21501+static inline
21502+int vx_info_proc_sched(struct _vx_sched *sched, char *buffer)
e3afe727 21503+{
4bf69007
AM
21504+ int length = 0;
21505+
21506+ length += sprintf(buffer,
21507+ "PrioBias:\t%8d\n",
21508+ sched->prio_bias);
21509+ return length;
e3afe727
AM
21510+}
21511+
4bf69007
AM
21512+static inline
21513+int vx_info_proc_sched_pc(struct _vx_sched_pc *sched_pc,
21514+ char *buffer, int cpu)
e3afe727 21515+{
4bf69007 21516+ int length = 0;
e3afe727 21517+
4bf69007
AM
21518+ length += sprintf(buffer + length,
21519+ "cpu %d: %lld %lld %lld", cpu,
21520+ (unsigned long long)sched_pc->user_ticks,
21521+ (unsigned long long)sched_pc->sys_ticks,
21522+ (unsigned long long)sched_pc->hold_ticks);
21523+ length += sprintf(buffer + length,
21524+ " %d\n", sched_pc->prio_bias);
21525+ return length;
21526+}
93de0823 21527+
4bf69007 21528+#endif /* _VX_SCHED_PROC_H */
f973f73f
AM
21529diff -NurpP --minimal linux-4.1.27/kernel/vserver/signal.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/signal.c
21530--- linux-4.1.27/kernel/vserver/signal.c 1970-01-01 00:00:00.000000000 +0000
21531+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/signal.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
21532@@ -0,0 +1,134 @@
21533+/*
21534+ * linux/kernel/vserver/signal.c
21535+ *
21536+ * Virtual Server: Signal Support
21537+ *
9e3e8383 21538+ * Copyright (C) 2003-2007 Herbert P?tzl
4bf69007
AM
21539+ *
21540+ * V0.01 broken out from vcontext V0.05
21541+ * V0.02 changed vcmds to vxi arg
21542+ * V0.03 adjusted siginfo for kill
21543+ *
21544+ */
99a884b4 21545+
4bf69007 21546+#include <asm/uaccess.h>
93de0823 21547+
4bf69007
AM
21548+#include <linux/vs_context.h>
21549+#include <linux/vs_pid.h>
21550+#include <linux/vserver/signal_cmd.h>
d337f35e 21551+
d337f35e 21552+
4bf69007
AM
21553+int vx_info_kill(struct vx_info *vxi, int pid, int sig)
21554+{
21555+ int retval, count = 0;
21556+ struct task_struct *p;
21557+ struct siginfo *sip = SEND_SIG_PRIV;
d33d7b00 21558+
4bf69007
AM
21559+ retval = -ESRCH;
21560+ vxdprintk(VXD_CBIT(misc, 4),
21561+ "vx_info_kill(%p[#%d],%d,%d)*",
21562+ vxi, vxi->vx_id, pid, sig);
21563+ read_lock(&tasklist_lock);
21564+ switch (pid) {
21565+ case 0:
21566+ case -1:
21567+ for_each_process(p) {
21568+ int err = 0;
d337f35e 21569+
4bf69007
AM
21570+ if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
21571+ (pid && vxi->vx_initpid == p->pid))
21572+ continue;
d337f35e 21573+
4bf69007
AM
21574+ err = group_send_sig_info(sig, sip, p);
21575+ ++count;
21576+ if (err != -EPERM)
21577+ retval = err;
21578+ }
21579+ break;
d337f35e 21580+
4bf69007
AM
21581+ case 1:
21582+ if (vxi->vx_initpid) {
21583+ pid = vxi->vx_initpid;
21584+ /* for now, only SIGINT to private init ... */
21585+ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
21586+ /* ... as long as there are tasks left */
21587+ (atomic_read(&vxi->vx_tasks) > 1))
21588+ sig = SIGINT;
21589+ }
21590+ /* fallthrough */
21591+ default:
21592+ rcu_read_lock();
21593+ p = find_task_by_real_pid(pid);
21594+ rcu_read_unlock();
21595+ if (p) {
21596+ if (vx_task_xid(p) == vxi->vx_id)
21597+ retval = group_send_sig_info(sig, sip, p);
21598+ }
21599+ break;
21600+ }
21601+ read_unlock(&tasklist_lock);
21602+ vxdprintk(VXD_CBIT(misc, 4),
21603+ "vx_info_kill(%p[#%d],%d,%d,%ld) = %d",
21604+ vxi, vxi->vx_id, pid, sig, (long)sip, retval);
21605+ return retval;
21606+}
d337f35e 21607+
4bf69007 21608+int vc_ctx_kill(struct vx_info *vxi, void __user *data)
d337f35e 21609+{
4bf69007 21610+ struct vcmd_ctx_kill_v0 vc_data;
d337f35e 21611+
4bf69007
AM
21612+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21613+ return -EFAULT;
d337f35e 21614+
4bf69007
AM
21615+ /* special check to allow guest shutdown */
21616+ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
21617+ /* forbid killall pid=0 when init is present */
21618+ (((vc_data.pid < 1) && vxi->vx_initpid) ||
21619+ (vc_data.pid > 1)))
21620+ return -EACCES;
21621+
21622+ return vx_info_kill(vxi, vc_data.pid, vc_data.sig);
d337f35e
JR
21623+}
21624+
4bf69007
AM
21625+
21626+static int __wait_exit(struct vx_info *vxi)
d337f35e 21627+{
4bf69007
AM
21628+ DECLARE_WAITQUEUE(wait, current);
21629+ int ret = 0;
d337f35e 21630+
4bf69007
AM
21631+ add_wait_queue(&vxi->vx_wait, &wait);
21632+ set_current_state(TASK_INTERRUPTIBLE);
d337f35e 21633+
4bf69007
AM
21634+wait:
21635+ if (vx_info_state(vxi,
21636+ VXS_SHUTDOWN | VXS_HASHED | VXS_HELPER) == VXS_SHUTDOWN)
21637+ goto out;
21638+ if (signal_pending(current)) {
21639+ ret = -ERESTARTSYS;
21640+ goto out;
21641+ }
21642+ schedule();
21643+ goto wait;
21644+
21645+out:
21646+ set_current_state(TASK_RUNNING);
21647+ remove_wait_queue(&vxi->vx_wait, &wait);
21648+ return ret;
d337f35e
JR
21649+}
21650+
4a036bed 21651+
7b17263b 21652+
4bf69007 21653+int vc_wait_exit(struct vx_info *vxi, void __user *data)
7b17263b 21654+{
4bf69007
AM
21655+ struct vcmd_wait_exit_v0 vc_data;
21656+ int ret;
7b17263b 21657+
4bf69007
AM
21658+ ret = __wait_exit(vxi);
21659+ vc_data.reboot_cmd = vxi->reboot_cmd;
21660+ vc_data.exit_code = vxi->exit_code;
21661+
21662+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
21663+ ret = -EFAULT;
21664+ return ret;
7b17263b 21665+}
2380c486 21666+
f973f73f
AM
21667diff -NurpP --minimal linux-4.1.27/kernel/vserver/space.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/space.c
21668--- linux-4.1.27/kernel/vserver/space.c 1970-01-01 00:00:00.000000000 +0000
21669+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/space.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
21670@@ -0,0 +1,436 @@
21671+/*
21672+ * linux/kernel/vserver/space.c
21673+ *
21674+ * Virtual Server: Context Space Support
21675+ *
9e3e8383 21676+ * Copyright (C) 2003-2010 Herbert P?tzl
4bf69007
AM
21677+ *
21678+ * V0.01 broken out from context.c 0.07
21679+ * V0.02 added task locking for namespace
21680+ * V0.03 broken out vx_enter_namespace
21681+ * V0.04 added *space support and commands
21682+ * V0.05 added credential support
21683+ *
21684+ */
21685+
21686+#include <linux/utsname.h>
21687+#include <linux/nsproxy.h>
21688+#include <linux/err.h>
21689+#include <linux/fs_struct.h>
21690+#include <linux/cred.h>
21691+#include <asm/uaccess.h>
d337f35e 21692+
d337f35e 21693+#include <linux/vs_context.h>
4bf69007
AM
21694+#include <linux/vserver/space.h>
21695+#include <linux/vserver/space_cmd.h>
2380c486 21696+
4bf69007
AM
21697+atomic_t vs_global_nsproxy = ATOMIC_INIT(0);
21698+atomic_t vs_global_fs = ATOMIC_INIT(0);
21699+atomic_t vs_global_mnt_ns = ATOMIC_INIT(0);
21700+atomic_t vs_global_uts_ns = ATOMIC_INIT(0);
21701+atomic_t vs_global_user_ns = ATOMIC_INIT(0);
21702+atomic_t vs_global_pid_ns = ATOMIC_INIT(0);
d337f35e 21703+
2380c486 21704+
4bf69007 21705+/* namespace functions */
2380c486 21706+
4bf69007
AM
21707+#include <linux/mnt_namespace.h>
21708+#include <linux/user_namespace.h>
21709+#include <linux/pid_namespace.h>
21710+#include <linux/ipc_namespace.h>
21711+#include <net/net_namespace.h>
21712+#include "../fs/mount.h"
2380c486 21713+
2380c486 21714+
4bf69007
AM
21715+static const struct vcmd_space_mask_v1 space_mask_v0 = {
21716+ .mask = CLONE_FS |
21717+ CLONE_NEWNS |
21718+#ifdef CONFIG_UTS_NS
21719+ CLONE_NEWUTS |
21720+#endif
21721+#ifdef CONFIG_IPC_NS
21722+ CLONE_NEWIPC |
21723+#endif
21724+#ifdef CONFIG_USER_NS
21725+ CLONE_NEWUSER |
21726+#endif
21727+ 0
21728+};
2380c486 21729+
4bf69007
AM
21730+static const struct vcmd_space_mask_v1 space_mask = {
21731+ .mask = CLONE_FS |
21732+ CLONE_NEWNS |
21733+#ifdef CONFIG_UTS_NS
21734+ CLONE_NEWUTS |
21735+#endif
21736+#ifdef CONFIG_IPC_NS
21737+ CLONE_NEWIPC |
21738+#endif
21739+#ifdef CONFIG_USER_NS
21740+ CLONE_NEWUSER |
21741+#endif
21742+#ifdef CONFIG_PID_NS
21743+ CLONE_NEWPID |
21744+#endif
21745+#ifdef CONFIG_NET_NS
21746+ CLONE_NEWNET |
21747+#endif
21748+ 0
21749+};
2380c486 21750+
4bf69007
AM
21751+static const struct vcmd_space_mask_v1 default_space_mask = {
21752+ .mask = CLONE_FS |
21753+ CLONE_NEWNS |
21754+#ifdef CONFIG_UTS_NS
21755+ CLONE_NEWUTS |
21756+#endif
21757+#ifdef CONFIG_IPC_NS
21758+ CLONE_NEWIPC |
21759+#endif
21760+#ifdef CONFIG_USER_NS
bb20add7 21761+// CLONE_NEWUSER |
4bf69007
AM
21762+#endif
21763+#ifdef CONFIG_PID_NS
21764+// CLONE_NEWPID |
21765+#endif
21766+ 0
21767+};
2380c486 21768+
4bf69007
AM
21769+/*
21770+ * build a new nsproxy mix
21771+ * assumes that both proxies are 'const'
21772+ * does not touch nsproxy refcounts
21773+ * will hold a reference on the result.
21774+ */
7b17263b 21775+
4bf69007
AM
21776+struct nsproxy *vs_mix_nsproxy(struct nsproxy *old_nsproxy,
21777+ struct nsproxy *new_nsproxy, unsigned long mask)
21778+{
21779+ struct mnt_namespace *old_ns;
21780+ struct uts_namespace *old_uts;
21781+ struct ipc_namespace *old_ipc;
21782+#ifdef CONFIG_PID_NS
21783+ struct pid_namespace *old_pid;
21784+#endif
21785+#ifdef CONFIG_NET_NS
21786+ struct net *old_net;
21787+#endif
21788+ struct nsproxy *nsproxy;
d337f35e 21789+
4bf69007
AM
21790+ nsproxy = copy_nsproxy(old_nsproxy);
21791+ if (!nsproxy)
21792+ goto out;
bd0a9c15 21793+
4bf69007
AM
21794+ if (mask & CLONE_NEWNS) {
21795+ old_ns = nsproxy->mnt_ns;
21796+ nsproxy->mnt_ns = new_nsproxy->mnt_ns;
21797+ if (nsproxy->mnt_ns)
21798+ get_mnt_ns(nsproxy->mnt_ns);
21799+ } else
21800+ old_ns = NULL;
d337f35e 21801+
4bf69007
AM
21802+ if (mask & CLONE_NEWUTS) {
21803+ old_uts = nsproxy->uts_ns;
21804+ nsproxy->uts_ns = new_nsproxy->uts_ns;
21805+ if (nsproxy->uts_ns)
21806+ get_uts_ns(nsproxy->uts_ns);
21807+ } else
21808+ old_uts = NULL;
2380c486 21809+
4bf69007
AM
21810+ if (mask & CLONE_NEWIPC) {
21811+ old_ipc = nsproxy->ipc_ns;
21812+ nsproxy->ipc_ns = new_nsproxy->ipc_ns;
21813+ if (nsproxy->ipc_ns)
21814+ get_ipc_ns(nsproxy->ipc_ns);
21815+ } else
21816+ old_ipc = NULL;
ec22aa5c 21817+
4bf69007
AM
21818+#ifdef CONFIG_PID_NS
21819+ if (mask & CLONE_NEWPID) {
5f23d63e
AM
21820+ old_pid = nsproxy->pid_ns_for_children;
21821+ nsproxy->pid_ns_for_children = new_nsproxy->pid_ns_for_children;
21822+ if (nsproxy->pid_ns_for_children)
21823+ get_pid_ns(nsproxy->pid_ns_for_children);
4bf69007
AM
21824+ } else
21825+ old_pid = NULL;
21826+#endif
21827+#ifdef CONFIG_NET_NS
21828+ if (mask & CLONE_NEWNET) {
21829+ old_net = nsproxy->net_ns;
21830+ nsproxy->net_ns = new_nsproxy->net_ns;
21831+ if (nsproxy->net_ns)
21832+ get_net(nsproxy->net_ns);
21833+ } else
21834+ old_net = NULL;
21835+#endif
21836+ if (old_ns)
21837+ put_mnt_ns(old_ns);
21838+ if (old_uts)
21839+ put_uts_ns(old_uts);
21840+ if (old_ipc)
21841+ put_ipc_ns(old_ipc);
21842+#ifdef CONFIG_PID_NS
21843+ if (old_pid)
21844+ put_pid_ns(old_pid);
21845+#endif
21846+#ifdef CONFIG_NET_NS
21847+ if (old_net)
21848+ put_net(old_net);
21849+#endif
21850+out:
21851+ return nsproxy;
21852+}
2380c486 21853+
bd0a9c15 21854+
4bf69007
AM
21855+/*
21856+ * merge two nsproxy structs into a new one.
21857+ * will hold a reference on the result.
21858+ */
d337f35e 21859+
4bf69007
AM
21860+static inline
21861+struct nsproxy *__vs_merge_nsproxy(struct nsproxy *old,
21862+ struct nsproxy *proxy, unsigned long mask)
21863+{
21864+ struct nsproxy null_proxy = { .mnt_ns = NULL };
2380c486 21865+
4bf69007
AM
21866+ if (!proxy)
21867+ return NULL;
d337f35e 21868+
4bf69007
AM
21869+ if (mask) {
21870+ /* vs_mix_nsproxy returns with reference */
21871+ return vs_mix_nsproxy(old ? old : &null_proxy,
21872+ proxy, mask);
21873+ }
21874+ get_nsproxy(proxy);
21875+ return proxy;
21876+}
2380c486 21877+
ec22aa5c 21878+
4bf69007
AM
21879+int vx_enter_space(struct vx_info *vxi, unsigned long mask, unsigned index)
21880+{
21881+ struct nsproxy *proxy, *proxy_cur, *proxy_new;
21882+ struct fs_struct *fs_cur, *fs = NULL;
21883+ struct _vx_space *space;
21884+ int ret, kill = 0;
2380c486 21885+
4bf69007
AM
21886+ vxdprintk(VXD_CBIT(space, 8), "vx_enter_space(%p[#%u],0x%08lx,%d)",
21887+ vxi, vxi->vx_id, mask, index);
2380c486 21888+
4bf69007
AM
21889+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
21890+ return -EACCES;
2380c486 21891+
4bf69007
AM
21892+ if (index >= VX_SPACES)
21893+ return -EINVAL;
2380c486 21894+
4bf69007
AM
21895+ space = &vxi->space[index];
21896+
21897+ if (!mask)
21898+ mask = space->vx_nsmask;
21899+
21900+ if ((mask & space->vx_nsmask) != mask)
21901+ return -EINVAL;
21902+
21903+ if (mask & CLONE_FS) {
21904+ fs = copy_fs_struct(space->vx_fs);
21905+ if (!fs)
21906+ return -ENOMEM;
2380c486 21907+ }
4bf69007
AM
21908+ proxy = space->vx_nsproxy;
21909+
21910+ vxdprintk(VXD_CBIT(space, 9),
21911+ "vx_enter_space(%p[#%u],0x%08lx,%d) -> (%p,%p)",
21912+ vxi, vxi->vx_id, mask, index, proxy, fs);
21913+
21914+ task_lock(current);
21915+ fs_cur = current->fs;
21916+
21917+ if (mask & CLONE_FS) {
21918+ spin_lock(&fs_cur->lock);
21919+ current->fs = fs;
21920+ kill = !--fs_cur->users;
21921+ spin_unlock(&fs_cur->lock);
ec22aa5c 21922+ }
ec22aa5c 21923+
4bf69007
AM
21924+ proxy_cur = current->nsproxy;
21925+ get_nsproxy(proxy_cur);
21926+ task_unlock(current);
21927+
21928+ if (kill)
21929+ free_fs_struct(fs_cur);
21930+
21931+ proxy_new = __vs_merge_nsproxy(proxy_cur, proxy, mask);
21932+ if (IS_ERR(proxy_new)) {
21933+ ret = PTR_ERR(proxy_new);
21934+ goto out_put;
eab5a9a6 21935+ }
4bf69007
AM
21936+
21937+ proxy_new = xchg(&current->nsproxy, proxy_new);
21938+
21939+ if (mask & CLONE_NEWUSER) {
21940+ struct cred *cred;
21941+
21942+ vxdprintk(VXD_CBIT(space, 10),
21943+ "vx_enter_space(%p[#%u],%p) cred (%p,%p)",
21944+ vxi, vxi->vx_id, space->vx_cred,
21945+ current->real_cred, current->cred);
21946+
21947+ if (space->vx_cred) {
21948+ cred = __prepare_creds(space->vx_cred);
21949+ if (cred)
21950+ commit_creds(cred);
21951+ }
d337f35e 21952+ }
4bf69007
AM
21953+
21954+ ret = 0;
21955+
21956+ if (proxy_new)
21957+ put_nsproxy(proxy_new);
21958+out_put:
21959+ if (proxy_cur)
21960+ put_nsproxy(proxy_cur);
21961+ return ret;
21962+}
21963+
21964+
21965+int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index)
21966+{
21967+ struct nsproxy *proxy_vxi, *proxy_cur, *proxy_new;
21968+ struct fs_struct *fs_vxi, *fs = NULL;
21969+ struct _vx_space *space;
21970+ int ret, kill = 0;
21971+
21972+ vxdprintk(VXD_CBIT(space, 8), "vx_set_space(%p[#%u],0x%08lx,%d)",
21973+ vxi, vxi->vx_id, mask, index);
21974+
21975+ if ((mask & space_mask.mask) != mask)
21976+ return -EINVAL;
21977+
21978+ if (index >= VX_SPACES)
21979+ return -EINVAL;
21980+
21981+ space = &vxi->space[index];
21982+
21983+ proxy_vxi = space->vx_nsproxy;
21984+ fs_vxi = space->vx_fs;
21985+
21986+ if (mask & CLONE_FS) {
21987+ fs = copy_fs_struct(current->fs);
21988+ if (!fs)
21989+ return -ENOMEM;
2380c486 21990+ }
d337f35e 21991+
4bf69007 21992+ task_lock(current);
2ba6f0dd 21993+
4bf69007
AM
21994+ if (mask & CLONE_FS) {
21995+ spin_lock(&fs_vxi->lock);
21996+ space->vx_fs = fs;
21997+ kill = !--fs_vxi->users;
21998+ spin_unlock(&fs_vxi->lock);
21999+ }
2ba6f0dd 22000+
4bf69007
AM
22001+ proxy_cur = current->nsproxy;
22002+ get_nsproxy(proxy_cur);
22003+ task_unlock(current);
2ba6f0dd 22004+
4bf69007
AM
22005+ if (kill)
22006+ free_fs_struct(fs_vxi);
2ba6f0dd 22007+
4bf69007
AM
22008+ proxy_new = __vs_merge_nsproxy(proxy_vxi, proxy_cur, mask);
22009+ if (IS_ERR(proxy_new)) {
22010+ ret = PTR_ERR(proxy_new);
22011+ goto out_put;
22012+ }
2ba6f0dd 22013+
4bf69007
AM
22014+ proxy_new = xchg(&space->vx_nsproxy, proxy_new);
22015+ space->vx_nsmask |= mask;
2ba6f0dd 22016+
4bf69007
AM
22017+ if (mask & CLONE_NEWUSER) {
22018+ struct cred *cred;
2ba6f0dd 22019+
4bf69007
AM
22020+ vxdprintk(VXD_CBIT(space, 10),
22021+ "vx_set_space(%p[#%u],%p) cred (%p,%p)",
22022+ vxi, vxi->vx_id, space->vx_cred,
22023+ current->real_cred, current->cred);
2ba6f0dd 22024+
4bf69007
AM
22025+ cred = prepare_creds();
22026+ cred = (struct cred *)xchg(&space->vx_cred, cred);
22027+ if (cred)
22028+ abort_creds(cred);
22029+ }
2ba6f0dd 22030+
4bf69007 22031+ ret = 0;
2ba6f0dd 22032+
4bf69007
AM
22033+ if (proxy_new)
22034+ put_nsproxy(proxy_new);
22035+out_put:
22036+ if (proxy_cur)
22037+ put_nsproxy(proxy_cur);
22038+ return ret;
22039+}
2ba6f0dd
AM
22040+
22041+
4bf69007
AM
22042+int vc_enter_space_v1(struct vx_info *vxi, void __user *data)
22043+{
22044+ struct vcmd_space_mask_v1 vc_data = { .mask = 0 };
2ba6f0dd 22045+
4bf69007
AM
22046+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
22047+ return -EFAULT;
2ba6f0dd 22048+
4bf69007
AM
22049+ return vx_enter_space(vxi, vc_data.mask, 0);
22050+}
2ba6f0dd 22051+
4bf69007
AM
22052+int vc_enter_space(struct vx_info *vxi, void __user *data)
22053+{
22054+ struct vcmd_space_mask_v2 vc_data = { .mask = 0 };
2ba6f0dd 22055+
4bf69007
AM
22056+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
22057+ return -EFAULT;
2ba6f0dd 22058+
4bf69007
AM
22059+ if (vc_data.index >= VX_SPACES)
22060+ return -EINVAL;
2ba6f0dd 22061+
4bf69007
AM
22062+ return vx_enter_space(vxi, vc_data.mask, vc_data.index);
22063+}
2ba6f0dd 22064+
4bf69007
AM
22065+int vc_set_space_v1(struct vx_info *vxi, void __user *data)
22066+{
22067+ struct vcmd_space_mask_v1 vc_data = { .mask = 0 };
2ba6f0dd 22068+
4bf69007
AM
22069+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
22070+ return -EFAULT;
2ba6f0dd 22071+
4bf69007
AM
22072+ return vx_set_space(vxi, vc_data.mask, 0);
22073+}
2ba6f0dd 22074+
4bf69007
AM
22075+int vc_set_space(struct vx_info *vxi, void __user *data)
22076+{
22077+ struct vcmd_space_mask_v2 vc_data = { .mask = 0 };
2ba6f0dd 22078+
4bf69007
AM
22079+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
22080+ return -EFAULT;
2ba6f0dd 22081+
4bf69007
AM
22082+ if (vc_data.index >= VX_SPACES)
22083+ return -EINVAL;
2ba6f0dd 22084+
4bf69007
AM
22085+ return vx_set_space(vxi, vc_data.mask, vc_data.index);
22086+}
2ba6f0dd 22087+
4bf69007
AM
22088+int vc_get_space_mask(void __user *data, int type)
22089+{
22090+ const struct vcmd_space_mask_v1 *mask;
2ba6f0dd 22091+
4bf69007
AM
22092+ if (type == 0)
22093+ mask = &space_mask_v0;
22094+ else if (type == 1)
22095+ mask = &space_mask;
22096+ else
22097+ mask = &default_space_mask;
2ba6f0dd 22098+
4bf69007
AM
22099+ vxdprintk(VXD_CBIT(space, 10),
22100+ "vc_get_space_mask(%d) = %08llx", type, mask->mask);
2ba6f0dd 22101+
4bf69007
AM
22102+ if (copy_to_user(data, mask, sizeof(*mask)))
22103+ return -EFAULT;
22104+ return 0;
22105+}
2ba6f0dd 22106+
f973f73f
AM
22107diff -NurpP --minimal linux-4.1.27/kernel/vserver/switch.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/switch.c
22108--- linux-4.1.27/kernel/vserver/switch.c 1970-01-01 00:00:00.000000000 +0000
22109+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/switch.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
22110@@ -0,0 +1,556 @@
22111+/*
22112+ * linux/kernel/vserver/switch.c
22113+ *
22114+ * Virtual Server: Syscall Switch
22115+ *
9e3e8383 22116+ * Copyright (C) 2003-2011 Herbert P?tzl
4bf69007
AM
22117+ *
22118+ * V0.01 syscall switch
22119+ * V0.02 added signal to context
22120+ * V0.03 added rlimit functions
22121+ * V0.04 added iattr, task/xid functions
22122+ * V0.05 added debug/history stuff
22123+ * V0.06 added compat32 layer
22124+ * V0.07 vcmd args and perms
22125+ * V0.08 added status commands
22126+ * V0.09 added tag commands
22127+ * V0.10 added oom bias
22128+ * V0.11 added device commands
22129+ * V0.12 added warn mask
22130+ *
22131+ */
2ba6f0dd 22132+
4bf69007
AM
22133+#include <linux/vs_context.h>
22134+#include <linux/vs_network.h>
22135+#include <linux/vserver/switch.h>
2ba6f0dd 22136+
4bf69007 22137+#include "vci_config.h"
2ba6f0dd 22138+
2ba6f0dd 22139+
4bf69007
AM
22140+static inline
22141+int vc_get_version(uint32_t id)
22142+{
22143+ return VCI_VERSION;
22144+}
2ba6f0dd 22145+
4bf69007
AM
22146+static inline
22147+int vc_get_vci(uint32_t id)
22148+{
22149+ return vci_kernel_config();
22150+}
2ba6f0dd 22151+
4bf69007
AM
22152+#include <linux/vserver/context_cmd.h>
22153+#include <linux/vserver/cvirt_cmd.h>
22154+#include <linux/vserver/cacct_cmd.h>
22155+#include <linux/vserver/limit_cmd.h>
22156+#include <linux/vserver/network_cmd.h>
22157+#include <linux/vserver/sched_cmd.h>
22158+#include <linux/vserver/debug_cmd.h>
22159+#include <linux/vserver/inode_cmd.h>
22160+#include <linux/vserver/dlimit_cmd.h>
22161+#include <linux/vserver/signal_cmd.h>
22162+#include <linux/vserver/space_cmd.h>
22163+#include <linux/vserver/tag_cmd.h>
22164+#include <linux/vserver/device_cmd.h>
2ba6f0dd 22165+
4bf69007
AM
22166+#include <linux/vserver/inode.h>
22167+#include <linux/vserver/dlimit.h>
2ba6f0dd 22168+
2ba6f0dd 22169+
4bf69007
AM
22170+#ifdef CONFIG_COMPAT
22171+#define __COMPAT(name, id, data, compat) \
22172+ (compat) ? name ## _x32(id, data) : name(id, data)
22173+#define __COMPAT_NO_ID(name, data, compat) \
22174+ (compat) ? name ## _x32(data) : name(data)
22175+#else
22176+#define __COMPAT(name, id, data, compat) \
22177+ name(id, data)
22178+#define __COMPAT_NO_ID(name, data, compat) \
22179+ name(data)
22180+#endif
2ba6f0dd 22181+
2ba6f0dd 22182+
4bf69007
AM
22183+static inline
22184+long do_vcmd(uint32_t cmd, uint32_t id,
22185+ struct vx_info *vxi, struct nx_info *nxi,
22186+ void __user *data, int compat)
22187+{
22188+ switch (cmd) {
2ba6f0dd 22189+
4bf69007
AM
22190+ case VCMD_get_version:
22191+ return vc_get_version(id);
22192+ case VCMD_get_vci:
22193+ return vc_get_vci(id);
2ba6f0dd 22194+
4bf69007
AM
22195+ case VCMD_task_xid:
22196+ return vc_task_xid(id);
22197+ case VCMD_vx_info:
22198+ return vc_vx_info(vxi, data);
2ba6f0dd 22199+
4bf69007
AM
22200+ case VCMD_task_nid:
22201+ return vc_task_nid(id);
22202+ case VCMD_nx_info:
22203+ return vc_nx_info(nxi, data);
2ba6f0dd 22204+
4bf69007
AM
22205+ case VCMD_task_tag:
22206+ return vc_task_tag(id);
2ba6f0dd 22207+
4bf69007
AM
22208+ case VCMD_set_space_v1:
22209+ return vc_set_space_v1(vxi, data);
22210+ /* this is version 2 */
22211+ case VCMD_set_space:
22212+ return vc_set_space(vxi, data);
2ba6f0dd 22213+
4bf69007
AM
22214+ case VCMD_get_space_mask_v0:
22215+ return vc_get_space_mask(data, 0);
22216+ /* this is version 1 */
22217+ case VCMD_get_space_mask:
22218+ return vc_get_space_mask(data, 1);
2ba6f0dd 22219+
4bf69007
AM
22220+ case VCMD_get_space_default:
22221+ return vc_get_space_mask(data, -1);
2ba6f0dd 22222+
4bf69007
AM
22223+ case VCMD_set_umask:
22224+ return vc_set_umask(vxi, data);
2ba6f0dd 22225+
4bf69007
AM
22226+ case VCMD_get_umask:
22227+ return vc_get_umask(vxi, data);
2ba6f0dd 22228+
4bf69007
AM
22229+ case VCMD_set_wmask:
22230+ return vc_set_wmask(vxi, data);
2ba6f0dd 22231+
4bf69007
AM
22232+ case VCMD_get_wmask:
22233+ return vc_get_wmask(vxi, data);
22234+#ifdef CONFIG_IA32_EMULATION
22235+ case VCMD_get_rlimit:
22236+ return __COMPAT(vc_get_rlimit, vxi, data, compat);
22237+ case VCMD_set_rlimit:
22238+ return __COMPAT(vc_set_rlimit, vxi, data, compat);
22239+#else
22240+ case VCMD_get_rlimit:
22241+ return vc_get_rlimit(vxi, data);
22242+ case VCMD_set_rlimit:
22243+ return vc_set_rlimit(vxi, data);
22244+#endif
22245+ case VCMD_get_rlimit_mask:
22246+ return vc_get_rlimit_mask(id, data);
22247+ case VCMD_reset_hits:
22248+ return vc_reset_hits(vxi, data);
22249+ case VCMD_reset_minmax:
22250+ return vc_reset_minmax(vxi, data);
2ba6f0dd 22251+
4bf69007
AM
22252+ case VCMD_get_vhi_name:
22253+ return vc_get_vhi_name(vxi, data);
22254+ case VCMD_set_vhi_name:
22255+ return vc_set_vhi_name(vxi, data);
2ba6f0dd 22256+
4bf69007
AM
22257+ case VCMD_ctx_stat:
22258+ return vc_ctx_stat(vxi, data);
22259+ case VCMD_virt_stat:
22260+ return vc_virt_stat(vxi, data);
22261+ case VCMD_sock_stat:
22262+ return vc_sock_stat(vxi, data);
22263+ case VCMD_rlimit_stat:
22264+ return vc_rlimit_stat(vxi, data);
2ba6f0dd 22265+
4bf69007
AM
22266+ case VCMD_set_cflags:
22267+ return vc_set_cflags(vxi, data);
22268+ case VCMD_get_cflags:
22269+ return vc_get_cflags(vxi, data);
2ba6f0dd 22270+
4bf69007
AM
22271+ /* this is version 1 */
22272+ case VCMD_set_ccaps:
22273+ return vc_set_ccaps(vxi, data);
22274+ /* this is version 1 */
22275+ case VCMD_get_ccaps:
22276+ return vc_get_ccaps(vxi, data);
22277+ case VCMD_set_bcaps:
22278+ return vc_set_bcaps(vxi, data);
22279+ case VCMD_get_bcaps:
22280+ return vc_get_bcaps(vxi, data);
2ba6f0dd 22281+
4bf69007
AM
22282+ case VCMD_set_badness:
22283+ return vc_set_badness(vxi, data);
22284+ case VCMD_get_badness:
22285+ return vc_get_badness(vxi, data);
2ba6f0dd 22286+
4bf69007
AM
22287+ case VCMD_set_nflags:
22288+ return vc_set_nflags(nxi, data);
22289+ case VCMD_get_nflags:
22290+ return vc_get_nflags(nxi, data);
2ba6f0dd 22291+
4bf69007
AM
22292+ case VCMD_set_ncaps:
22293+ return vc_set_ncaps(nxi, data);
22294+ case VCMD_get_ncaps:
22295+ return vc_get_ncaps(nxi, data);
2ba6f0dd 22296+
4bf69007
AM
22297+ case VCMD_set_prio_bias:
22298+ return vc_set_prio_bias(vxi, data);
22299+ case VCMD_get_prio_bias:
22300+ return vc_get_prio_bias(vxi, data);
22301+ case VCMD_add_dlimit:
22302+ return __COMPAT(vc_add_dlimit, id, data, compat);
22303+ case VCMD_rem_dlimit:
22304+ return __COMPAT(vc_rem_dlimit, id, data, compat);
22305+ case VCMD_set_dlimit:
22306+ return __COMPAT(vc_set_dlimit, id, data, compat);
22307+ case VCMD_get_dlimit:
22308+ return __COMPAT(vc_get_dlimit, id, data, compat);
2ba6f0dd 22309+
4bf69007
AM
22310+ case VCMD_ctx_kill:
22311+ return vc_ctx_kill(vxi, data);
2ba6f0dd 22312+
4bf69007
AM
22313+ case VCMD_wait_exit:
22314+ return vc_wait_exit(vxi, data);
2ba6f0dd 22315+
4bf69007
AM
22316+ case VCMD_get_iattr:
22317+ return __COMPAT_NO_ID(vc_get_iattr, data, compat);
22318+ case VCMD_set_iattr:
22319+ return __COMPAT_NO_ID(vc_set_iattr, data, compat);
2ba6f0dd 22320+
4bf69007
AM
22321+ case VCMD_fget_iattr:
22322+ return vc_fget_iattr(id, data);
22323+ case VCMD_fset_iattr:
22324+ return vc_fset_iattr(id, data);
2ba6f0dd 22325+
4bf69007
AM
22326+ case VCMD_enter_space_v0:
22327+ return vc_enter_space_v1(vxi, NULL);
22328+ case VCMD_enter_space_v1:
22329+ return vc_enter_space_v1(vxi, data);
22330+ /* this is version 2 */
22331+ case VCMD_enter_space:
22332+ return vc_enter_space(vxi, data);
2ba6f0dd 22333+
4bf69007
AM
22334+ case VCMD_ctx_create_v0:
22335+ return vc_ctx_create(id, NULL);
22336+ case VCMD_ctx_create:
22337+ return vc_ctx_create(id, data);
22338+ case VCMD_ctx_migrate_v0:
22339+ return vc_ctx_migrate(vxi, NULL);
22340+ case VCMD_ctx_migrate:
22341+ return vc_ctx_migrate(vxi, data);
2ba6f0dd 22342+
4bf69007
AM
22343+ case VCMD_net_create_v0:
22344+ return vc_net_create(id, NULL);
22345+ case VCMD_net_create:
22346+ return vc_net_create(id, data);
22347+ case VCMD_net_migrate:
22348+ return vc_net_migrate(nxi, data);
2ba6f0dd 22349+
4bf69007
AM
22350+ case VCMD_tag_migrate:
22351+ return vc_tag_migrate(id);
2ba6f0dd 22352+
4bf69007
AM
22353+ case VCMD_net_add:
22354+ return vc_net_add(nxi, data);
22355+ case VCMD_net_remove:
22356+ return vc_net_remove(nxi, data);
2ba6f0dd 22357+
4bf69007
AM
22358+ case VCMD_net_add_ipv4_v1:
22359+ return vc_net_add_ipv4_v1(nxi, data);
22360+ /* this is version 2 */
22361+ case VCMD_net_add_ipv4:
22362+ return vc_net_add_ipv4(nxi, data);
2ba6f0dd 22363+
4bf69007
AM
22364+ case VCMD_net_rem_ipv4_v1:
22365+ return vc_net_rem_ipv4_v1(nxi, data);
22366+ /* this is version 2 */
22367+ case VCMD_net_rem_ipv4:
22368+ return vc_net_rem_ipv4(nxi, data);
22369+#ifdef CONFIG_IPV6
22370+ case VCMD_net_add_ipv6:
22371+ return vc_net_add_ipv6(nxi, data);
22372+ case VCMD_net_remove_ipv6:
22373+ return vc_net_remove_ipv6(nxi, data);
22374+#endif
22375+/* case VCMD_add_match_ipv4:
22376+ return vc_add_match_ipv4(nxi, data);
22377+ case VCMD_get_match_ipv4:
22378+ return vc_get_match_ipv4(nxi, data);
22379+#ifdef CONFIG_IPV6
22380+ case VCMD_add_match_ipv6:
22381+ return vc_add_match_ipv6(nxi, data);
22382+ case VCMD_get_match_ipv6:
22383+ return vc_get_match_ipv6(nxi, data);
22384+#endif */
2ba6f0dd 22385+
4bf69007
AM
22386+#ifdef CONFIG_VSERVER_DEVICE
22387+ case VCMD_set_mapping:
22388+ return __COMPAT(vc_set_mapping, vxi, data, compat);
22389+ case VCMD_unset_mapping:
22390+ return __COMPAT(vc_unset_mapping, vxi, data, compat);
22391+#endif
22392+#ifdef CONFIG_VSERVER_HISTORY
22393+ case VCMD_dump_history:
22394+ return vc_dump_history(id);
22395+ case VCMD_read_history:
22396+ return __COMPAT(vc_read_history, id, data, compat);
22397+#endif
22398+ default:
22399+ vxwprintk_task(1, "unimplemented VCMD_%02d_%d[%d]",
22400+ VC_CATEGORY(cmd), VC_COMMAND(cmd), VC_VERSION(cmd));
22401+ }
22402+ return -ENOSYS;
22403+}
2ba6f0dd 22404+
2ba6f0dd 22405+
4bf69007
AM
22406+#define __VCMD(vcmd, _perm, _args, _flags) \
22407+ case VCMD_ ## vcmd: perm = _perm; \
22408+ args = _args; flags = _flags; break
2ba6f0dd 22409+
2ba6f0dd 22410+
4bf69007
AM
22411+#define VCA_NONE 0x00
22412+#define VCA_VXI 0x01
22413+#define VCA_NXI 0x02
2ba6f0dd 22414+
4bf69007
AM
22415+#define VCF_NONE 0x00
22416+#define VCF_INFO 0x01
22417+#define VCF_ADMIN 0x02
22418+#define VCF_ARES 0x06 /* includes admin */
22419+#define VCF_SETUP 0x08
2ba6f0dd 22420+
4bf69007 22421+#define VCF_ZIDOK 0x10 /* zero id okay */
2ba6f0dd 22422+
2ba6f0dd
AM
22423+
22424+static inline
4bf69007 22425+long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
2ba6f0dd 22426+{
4bf69007
AM
22427+ long ret;
22428+ int permit = -1, state = 0;
22429+ int perm = -1, args = 0, flags = 0;
22430+ struct vx_info *vxi = NULL;
22431+ struct nx_info *nxi = NULL;
2ba6f0dd 22432+
4bf69007
AM
22433+ switch (cmd) {
22434+ /* unpriviledged commands */
22435+ __VCMD(get_version, 0, VCA_NONE, 0);
22436+ __VCMD(get_vci, 0, VCA_NONE, 0);
22437+ __VCMD(get_rlimit_mask, 0, VCA_NONE, 0);
22438+ __VCMD(get_space_mask_v0,0, VCA_NONE, 0);
22439+ __VCMD(get_space_mask, 0, VCA_NONE, 0);
22440+ __VCMD(get_space_default,0, VCA_NONE, 0);
2ba6f0dd 22441+
4bf69007
AM
22442+ /* info commands */
22443+ __VCMD(task_xid, 2, VCA_NONE, 0);
22444+ __VCMD(reset_hits, 2, VCA_VXI, 0);
22445+ __VCMD(reset_minmax, 2, VCA_VXI, 0);
22446+ __VCMD(vx_info, 3, VCA_VXI, VCF_INFO);
22447+ __VCMD(get_bcaps, 3, VCA_VXI, VCF_INFO);
22448+ __VCMD(get_ccaps, 3, VCA_VXI, VCF_INFO);
22449+ __VCMD(get_cflags, 3, VCA_VXI, VCF_INFO);
22450+ __VCMD(get_umask, 3, VCA_VXI, VCF_INFO);
22451+ __VCMD(get_wmask, 3, VCA_VXI, VCF_INFO);
22452+ __VCMD(get_badness, 3, VCA_VXI, VCF_INFO);
22453+ __VCMD(get_vhi_name, 3, VCA_VXI, VCF_INFO);
22454+ __VCMD(get_rlimit, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22455+
4bf69007
AM
22456+ __VCMD(ctx_stat, 3, VCA_VXI, VCF_INFO);
22457+ __VCMD(virt_stat, 3, VCA_VXI, VCF_INFO);
22458+ __VCMD(sock_stat, 3, VCA_VXI, VCF_INFO);
22459+ __VCMD(rlimit_stat, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22460+
4bf69007
AM
22461+ __VCMD(task_nid, 2, VCA_NONE, 0);
22462+ __VCMD(nx_info, 3, VCA_NXI, VCF_INFO);
22463+ __VCMD(get_ncaps, 3, VCA_NXI, VCF_INFO);
22464+ __VCMD(get_nflags, 3, VCA_NXI, VCF_INFO);
2ba6f0dd 22465+
4bf69007 22466+ __VCMD(task_tag, 2, VCA_NONE, 0);
2ba6f0dd 22467+
4bf69007
AM
22468+ __VCMD(get_iattr, 2, VCA_NONE, 0);
22469+ __VCMD(fget_iattr, 2, VCA_NONE, 0);
22470+ __VCMD(get_dlimit, 3, VCA_NONE, VCF_INFO);
22471+ __VCMD(get_prio_bias, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22472+
4bf69007
AM
22473+ /* lower admin commands */
22474+ __VCMD(wait_exit, 4, VCA_VXI, VCF_INFO);
22475+ __VCMD(ctx_create_v0, 5, VCA_NONE, 0);
22476+ __VCMD(ctx_create, 5, VCA_NONE, 0);
22477+ __VCMD(ctx_migrate_v0, 5, VCA_VXI, VCF_ADMIN);
22478+ __VCMD(ctx_migrate, 5, VCA_VXI, VCF_ADMIN);
22479+ __VCMD(enter_space_v0, 5, VCA_VXI, VCF_ADMIN);
22480+ __VCMD(enter_space_v1, 5, VCA_VXI, VCF_ADMIN);
22481+ __VCMD(enter_space, 5, VCA_VXI, VCF_ADMIN);
2ba6f0dd 22482+
4bf69007
AM
22483+ __VCMD(net_create_v0, 5, VCA_NONE, 0);
22484+ __VCMD(net_create, 5, VCA_NONE, 0);
22485+ __VCMD(net_migrate, 5, VCA_NXI, VCF_ADMIN);
2ba6f0dd 22486+
4bf69007 22487+ __VCMD(tag_migrate, 5, VCA_NONE, VCF_ADMIN);
2ba6f0dd 22488+
4bf69007
AM
22489+ /* higher admin commands */
22490+ __VCMD(ctx_kill, 6, VCA_VXI, VCF_ARES);
22491+ __VCMD(set_space_v1, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22492+ __VCMD(set_space, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22493+
4bf69007
AM
22494+ __VCMD(set_ccaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22495+ __VCMD(set_bcaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22496+ __VCMD(set_cflags, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22497+ __VCMD(set_umask, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22498+ __VCMD(set_wmask, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22499+ __VCMD(set_badness, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22500+
4bf69007
AM
22501+ __VCMD(set_vhi_name, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22502+ __VCMD(set_rlimit, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22503+ __VCMD(set_prio_bias, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22504+
4bf69007
AM
22505+ __VCMD(set_ncaps, 7, VCA_NXI, VCF_ARES | VCF_SETUP);
22506+ __VCMD(set_nflags, 7, VCA_NXI, VCF_ARES | VCF_SETUP);
22507+ __VCMD(net_add, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22508+ __VCMD(net_remove, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22509+ __VCMD(net_add_ipv4_v1, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22510+ __VCMD(net_rem_ipv4_v1, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22511+ __VCMD(net_add_ipv4, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22512+ __VCMD(net_rem_ipv4, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22513+#ifdef CONFIG_IPV6
22514+ __VCMD(net_add_ipv6, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22515+ __VCMD(net_remove_ipv6, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22516+#endif
22517+ __VCMD(set_iattr, 7, VCA_NONE, 0);
22518+ __VCMD(fset_iattr, 7, VCA_NONE, 0);
22519+ __VCMD(set_dlimit, 7, VCA_NONE, VCF_ARES);
22520+ __VCMD(add_dlimit, 8, VCA_NONE, VCF_ARES);
22521+ __VCMD(rem_dlimit, 8, VCA_NONE, VCF_ARES);
2ba6f0dd 22522+
4bf69007
AM
22523+#ifdef CONFIG_VSERVER_DEVICE
22524+ __VCMD(set_mapping, 8, VCA_VXI, VCF_ARES|VCF_ZIDOK);
22525+ __VCMD(unset_mapping, 8, VCA_VXI, VCF_ARES|VCF_ZIDOK);
22526+#endif
22527+ /* debug level admin commands */
22528+#ifdef CONFIG_VSERVER_HISTORY
22529+ __VCMD(dump_history, 9, VCA_NONE, 0);
22530+ __VCMD(read_history, 9, VCA_NONE, 0);
22531+#endif
2ba6f0dd 22532+
4bf69007
AM
22533+ default:
22534+ perm = -1;
22535+ }
2ba6f0dd 22536+
4bf69007
AM
22537+ vxdprintk(VXD_CBIT(switch, 0),
22538+ "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]",
22539+ VC_CATEGORY(cmd), VC_COMMAND(cmd),
22540+ VC_VERSION(cmd), id, data, compat,
22541+ perm, args, flags);
2ba6f0dd 22542+
4bf69007
AM
22543+ ret = -ENOSYS;
22544+ if (perm < 0)
22545+ goto out;
2ba6f0dd 22546+
4bf69007
AM
22547+ state = 1;
22548+ if (!capable(CAP_CONTEXT))
22549+ goto out;
2ba6f0dd 22550+
4bf69007
AM
22551+ state = 2;
22552+ /* moved here from the individual commands */
22553+ ret = -EPERM;
22554+ if ((perm > 1) && !capable(CAP_SYS_ADMIN))
22555+ goto out;
2ba6f0dd 22556+
4bf69007
AM
22557+ state = 3;
22558+ /* vcmd involves resource management */
22559+ ret = -EPERM;
22560+ if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE))
22561+ goto out;
2ba6f0dd 22562+
4bf69007
AM
22563+ state = 4;
22564+ /* various legacy exceptions */
22565+ switch (cmd) {
22566+ /* will go away when spectator is a cap */
22567+ case VCMD_ctx_migrate_v0:
22568+ case VCMD_ctx_migrate:
22569+ if (id == 1) {
22570+ current->xid = 1;
22571+ ret = 1;
22572+ goto out;
22573+ }
22574+ break;
2ba6f0dd 22575+
4bf69007
AM
22576+ /* will go away when spectator is a cap */
22577+ case VCMD_net_migrate:
22578+ if (id == 1) {
22579+ current->nid = 1;
22580+ ret = 1;
22581+ goto out;
22582+ }
22583+ break;
22584+ }
2ba6f0dd 22585+
4bf69007
AM
22586+ /* vcmds are fine by default */
22587+ permit = 1;
2ba6f0dd 22588+
4bf69007
AM
22589+ /* admin type vcmds require admin ... */
22590+ if (flags & VCF_ADMIN)
22591+ permit = vx_check(0, VS_ADMIN) ? 1 : 0;
2ba6f0dd 22592+
4bf69007
AM
22593+ /* ... but setup type vcmds override that */
22594+ if (!permit && (flags & VCF_SETUP))
22595+ permit = vx_flags(VXF_STATE_SETUP, 0) ? 2 : 0;
2ba6f0dd 22596+
4bf69007
AM
22597+ state = 5;
22598+ ret = -EPERM;
22599+ if (!permit)
22600+ goto out;
2ba6f0dd 22601+
4bf69007
AM
22602+ state = 6;
22603+ if (!id && (flags & VCF_ZIDOK))
22604+ goto skip_id;
2ba6f0dd 22605+
4bf69007
AM
22606+ ret = -ESRCH;
22607+ if (args & VCA_VXI) {
22608+ vxi = lookup_vx_info(id);
22609+ if (!vxi)
22610+ goto out;
2ba6f0dd 22611+
4bf69007
AM
22612+ if ((flags & VCF_ADMIN) &&
22613+ /* special case kill for shutdown */
22614+ (cmd != VCMD_ctx_kill) &&
22615+ /* can context be administrated? */
22616+ !vx_info_flags(vxi, VXF_STATE_ADMIN, 0)) {
22617+ ret = -EACCES;
22618+ goto out_vxi;
22619+ }
22620+ }
22621+ state = 7;
22622+ if (args & VCA_NXI) {
22623+ nxi = lookup_nx_info(id);
22624+ if (!nxi)
22625+ goto out_vxi;
2ba6f0dd 22626+
4bf69007
AM
22627+ if ((flags & VCF_ADMIN) &&
22628+ /* can context be administrated? */
22629+ !nx_info_flags(nxi, NXF_STATE_ADMIN, 0)) {
22630+ ret = -EACCES;
22631+ goto out_nxi;
22632+ }
22633+ }
22634+skip_id:
22635+ state = 8;
22636+ ret = do_vcmd(cmd, id, vxi, nxi, data, compat);
2ba6f0dd 22637+
4bf69007
AM
22638+out_nxi:
22639+ if ((args & VCA_NXI) && nxi)
22640+ put_nx_info(nxi);
22641+out_vxi:
22642+ if ((args & VCA_VXI) && vxi)
22643+ put_vx_info(vxi);
22644+out:
22645+ vxdprintk(VXD_CBIT(switch, 1),
22646+ "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]",
22647+ VC_CATEGORY(cmd), VC_COMMAND(cmd),
22648+ VC_VERSION(cmd), ret, ret, state, permit);
22649+ return ret;
22650+}
2ba6f0dd 22651+
4bf69007
AM
22652+asmlinkage long
22653+sys_vserver(uint32_t cmd, uint32_t id, void __user *data)
22654+{
22655+ return do_vserver(cmd, id, data, 0);
22656+}
2ba6f0dd 22657+
4bf69007 22658+#ifdef CONFIG_COMPAT
2ba6f0dd 22659+
4bf69007
AM
22660+asmlinkage long
22661+sys32_vserver(uint32_t cmd, uint32_t id, void __user *data)
22662+{
22663+ return do_vserver(cmd, id, data, 1);
22664+}
2ba6f0dd 22665+
4bf69007 22666+#endif /* CONFIG_COMPAT */
f973f73f
AM
22667diff -NurpP --minimal linux-4.1.27/kernel/vserver/sysctl.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/sysctl.c
22668--- linux-4.1.27/kernel/vserver/sysctl.c 1970-01-01 00:00:00.000000000 +0000
22669+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/sysctl.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
22670@@ -0,0 +1,247 @@
22671+/*
22672+ * kernel/vserver/sysctl.c
22673+ *
22674+ * Virtual Context Support
22675+ *
9e3e8383 22676+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
22677+ *
22678+ * V0.01 basic structure
22679+ *
22680+ */
2ba6f0dd 22681+
4bf69007
AM
22682+#include <linux/module.h>
22683+#include <linux/ctype.h>
22684+#include <linux/sysctl.h>
22685+#include <linux/parser.h>
22686+#include <asm/uaccess.h>
2ba6f0dd 22687+
4bf69007
AM
22688+enum {
22689+ CTL_DEBUG_ERROR = 0,
22690+ CTL_DEBUG_SWITCH = 1,
22691+ CTL_DEBUG_XID,
22692+ CTL_DEBUG_NID,
22693+ CTL_DEBUG_TAG,
22694+ CTL_DEBUG_NET,
22695+ CTL_DEBUG_LIMIT,
22696+ CTL_DEBUG_CRES,
22697+ CTL_DEBUG_DLIM,
22698+ CTL_DEBUG_QUOTA,
22699+ CTL_DEBUG_CVIRT,
22700+ CTL_DEBUG_SPACE,
22701+ CTL_DEBUG_PERM,
22702+ CTL_DEBUG_MISC,
2ba6f0dd
AM
22703+};
22704+
2ba6f0dd 22705+
4bf69007
AM
22706+unsigned int vs_debug_switch = 0;
22707+unsigned int vs_debug_xid = 0;
22708+unsigned int vs_debug_nid = 0;
22709+unsigned int vs_debug_tag = 0;
22710+unsigned int vs_debug_net = 0;
22711+unsigned int vs_debug_limit = 0;
22712+unsigned int vs_debug_cres = 0;
22713+unsigned int vs_debug_dlim = 0;
22714+unsigned int vs_debug_quota = 0;
22715+unsigned int vs_debug_cvirt = 0;
22716+unsigned int vs_debug_space = 0;
22717+unsigned int vs_debug_perm = 0;
22718+unsigned int vs_debug_misc = 0;
2ba6f0dd 22719+
2ba6f0dd 22720+
4bf69007 22721+static struct ctl_table_header *vserver_table_header;
bb20add7 22722+static struct ctl_table vserver_root_table[];
4bf69007 22723+
2ba6f0dd 22724+
4bf69007
AM
22725+void vserver_register_sysctl(void)
22726+{
22727+ if (!vserver_table_header) {
22728+ vserver_table_header = register_sysctl_table(vserver_root_table);
22729+ }
2ba6f0dd 22730+
4bf69007 22731+}
2ba6f0dd 22732+
4bf69007
AM
22733+void vserver_unregister_sysctl(void)
22734+{
22735+ if (vserver_table_header) {
22736+ unregister_sysctl_table(vserver_table_header);
22737+ vserver_table_header = NULL;
22738+ }
22739+}
2ba6f0dd 22740+
2ba6f0dd 22741+
bb20add7 22742+static int proc_dodebug(struct ctl_table *table, int write,
4bf69007
AM
22743+ void __user *buffer, size_t *lenp, loff_t *ppos)
22744+{
22745+ char tmpbuf[20], *p, c;
22746+ unsigned int value;
22747+ size_t left, len;
2ba6f0dd 22748+
4bf69007
AM
22749+ if ((*ppos && !write) || !*lenp) {
22750+ *lenp = 0;
22751+ return 0;
22752+ }
2ba6f0dd 22753+
4bf69007 22754+ left = *lenp;
2ba6f0dd 22755+
4bf69007
AM
22756+ if (write) {
22757+ if (!access_ok(VERIFY_READ, buffer, left))
22758+ return -EFAULT;
22759+ p = (char *)buffer;
22760+ while (left && __get_user(c, p) >= 0 && isspace(c))
22761+ left--, p++;
22762+ if (!left)
22763+ goto done;
2ba6f0dd 22764+
4bf69007
AM
22765+ if (left > sizeof(tmpbuf) - 1)
22766+ return -EINVAL;
22767+ if (copy_from_user(tmpbuf, p, left))
22768+ return -EFAULT;
22769+ tmpbuf[left] = '\0';
2ba6f0dd 22770+
4bf69007
AM
22771+ for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
22772+ value = 10 * value + (*p - '0');
22773+ if (*p && !isspace(*p))
22774+ return -EINVAL;
22775+ while (left && isspace(*p))
22776+ left--, p++;
22777+ *(unsigned int *)table->data = value;
22778+ } else {
22779+ if (!access_ok(VERIFY_WRITE, buffer, left))
22780+ return -EFAULT;
22781+ len = sprintf(tmpbuf, "%d", *(unsigned int *)table->data);
22782+ if (len > left)
22783+ len = left;
22784+ if (__copy_to_user(buffer, tmpbuf, len))
22785+ return -EFAULT;
22786+ if ((left -= len) > 0) {
22787+ if (put_user('\n', (char *)buffer + len))
22788+ return -EFAULT;
22789+ left--;
22790+ }
22791+ }
2ba6f0dd 22792+
4bf69007
AM
22793+done:
22794+ *lenp -= left;
22795+ *ppos += *lenp;
22796+ return 0;
22797+}
2ba6f0dd 22798+
4bf69007 22799+static int zero;
2ba6f0dd 22800+
4bf69007
AM
22801+#define CTL_ENTRY(ctl, name) \
22802+ { \
22803+ .procname = #name, \
22804+ .data = &vs_ ## name, \
22805+ .maxlen = sizeof(int), \
22806+ .mode = 0644, \
22807+ .proc_handler = &proc_dodebug, \
22808+ .extra1 = &zero, \
22809+ .extra2 = &zero, \
22810+ }
2ba6f0dd 22811+
bb20add7 22812+static struct ctl_table vserver_debug_table[] = {
4bf69007
AM
22813+ CTL_ENTRY(CTL_DEBUG_SWITCH, debug_switch),
22814+ CTL_ENTRY(CTL_DEBUG_XID, debug_xid),
22815+ CTL_ENTRY(CTL_DEBUG_NID, debug_nid),
22816+ CTL_ENTRY(CTL_DEBUG_TAG, debug_tag),
22817+ CTL_ENTRY(CTL_DEBUG_NET, debug_net),
22818+ CTL_ENTRY(CTL_DEBUG_LIMIT, debug_limit),
22819+ CTL_ENTRY(CTL_DEBUG_CRES, debug_cres),
22820+ CTL_ENTRY(CTL_DEBUG_DLIM, debug_dlim),
22821+ CTL_ENTRY(CTL_DEBUG_QUOTA, debug_quota),
22822+ CTL_ENTRY(CTL_DEBUG_CVIRT, debug_cvirt),
22823+ CTL_ENTRY(CTL_DEBUG_SPACE, debug_space),
22824+ CTL_ENTRY(CTL_DEBUG_PERM, debug_perm),
22825+ CTL_ENTRY(CTL_DEBUG_MISC, debug_misc),
22826+ { 0 }
22827+};
2ba6f0dd 22828+
bb20add7 22829+static struct ctl_table vserver_root_table[] = {
4bf69007
AM
22830+ {
22831+ .procname = "vserver",
22832+ .mode = 0555,
22833+ .child = vserver_debug_table
22834+ },
22835+ { 0 }
22836+};
2ba6f0dd 22837+
2ba6f0dd 22838+
4bf69007
AM
22839+static match_table_t tokens = {
22840+ { CTL_DEBUG_SWITCH, "switch=%x" },
22841+ { CTL_DEBUG_XID, "xid=%x" },
22842+ { CTL_DEBUG_NID, "nid=%x" },
22843+ { CTL_DEBUG_TAG, "tag=%x" },
22844+ { CTL_DEBUG_NET, "net=%x" },
22845+ { CTL_DEBUG_LIMIT, "limit=%x" },
22846+ { CTL_DEBUG_CRES, "cres=%x" },
22847+ { CTL_DEBUG_DLIM, "dlim=%x" },
22848+ { CTL_DEBUG_QUOTA, "quota=%x" },
22849+ { CTL_DEBUG_CVIRT, "cvirt=%x" },
22850+ { CTL_DEBUG_SPACE, "space=%x" },
22851+ { CTL_DEBUG_PERM, "perm=%x" },
22852+ { CTL_DEBUG_MISC, "misc=%x" },
22853+ { CTL_DEBUG_ERROR, NULL }
22854+};
2ba6f0dd 22855+
4bf69007
AM
22856+#define HANDLE_CASE(id, name, val) \
22857+ case CTL_DEBUG_ ## id: \
22858+ vs_debug_ ## name = val; \
22859+ printk("vs_debug_" #name "=0x%x\n", val); \
22860+ break
2ba6f0dd 22861+
2ba6f0dd 22862+
4bf69007
AM
22863+static int __init vs_debug_setup(char *str)
22864+{
22865+ char *p;
22866+ int token;
2ba6f0dd 22867+
4bf69007
AM
22868+ printk("vs_debug_setup(%s)\n", str);
22869+ while ((p = strsep(&str, ",")) != NULL) {
22870+ substring_t args[MAX_OPT_ARGS];
22871+ unsigned int value;
2ba6f0dd 22872+
4bf69007
AM
22873+ if (!*p)
22874+ continue;
2ba6f0dd 22875+
4bf69007
AM
22876+ token = match_token(p, tokens, args);
22877+ value = (token > 0) ? simple_strtoul(args[0].from, NULL, 0) : 0;
2ba6f0dd 22878+
4bf69007
AM
22879+ switch (token) {
22880+ HANDLE_CASE(SWITCH, switch, value);
22881+ HANDLE_CASE(XID, xid, value);
22882+ HANDLE_CASE(NID, nid, value);
22883+ HANDLE_CASE(TAG, tag, value);
22884+ HANDLE_CASE(NET, net, value);
22885+ HANDLE_CASE(LIMIT, limit, value);
22886+ HANDLE_CASE(CRES, cres, value);
22887+ HANDLE_CASE(DLIM, dlim, value);
22888+ HANDLE_CASE(QUOTA, quota, value);
22889+ HANDLE_CASE(CVIRT, cvirt, value);
22890+ HANDLE_CASE(SPACE, space, value);
22891+ HANDLE_CASE(PERM, perm, value);
22892+ HANDLE_CASE(MISC, misc, value);
22893+ default:
22894+ return -EINVAL;
22895+ break;
22896+ }
22897+ }
22898+ return 1;
22899+}
2ba6f0dd 22900+
4bf69007 22901+__setup("vsdebug=", vs_debug_setup);
2ba6f0dd 22902+
2ba6f0dd 22903+
2ba6f0dd 22904+
4bf69007
AM
22905+EXPORT_SYMBOL_GPL(vs_debug_switch);
22906+EXPORT_SYMBOL_GPL(vs_debug_xid);
22907+EXPORT_SYMBOL_GPL(vs_debug_nid);
22908+EXPORT_SYMBOL_GPL(vs_debug_net);
22909+EXPORT_SYMBOL_GPL(vs_debug_limit);
22910+EXPORT_SYMBOL_GPL(vs_debug_cres);
22911+EXPORT_SYMBOL_GPL(vs_debug_dlim);
22912+EXPORT_SYMBOL_GPL(vs_debug_quota);
22913+EXPORT_SYMBOL_GPL(vs_debug_cvirt);
22914+EXPORT_SYMBOL_GPL(vs_debug_space);
22915+EXPORT_SYMBOL_GPL(vs_debug_perm);
22916+EXPORT_SYMBOL_GPL(vs_debug_misc);
2ba6f0dd 22917+
f973f73f
AM
22918diff -NurpP --minimal linux-4.1.27/kernel/vserver/tag.c linux-4.1.27-vs2.3.8.5.2/kernel/vserver/tag.c
22919--- linux-4.1.27/kernel/vserver/tag.c 1970-01-01 00:00:00.000000000 +0000
22920+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/tag.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
22921@@ -0,0 +1,63 @@
22922+/*
22923+ * linux/kernel/vserver/tag.c
22924+ *
22925+ * Virtual Server: Shallow Tag Space
22926+ *
9e3e8383 22927+ * Copyright (C) 2007 Herbert P?tzl
4bf69007
AM
22928+ *
22929+ * V0.01 basic implementation
22930+ *
22931+ */
2ba6f0dd 22932+
4bf69007
AM
22933+#include <linux/sched.h>
22934+#include <linux/vserver/debug.h>
22935+#include <linux/vs_pid.h>
22936+#include <linux/vs_tag.h>
2ba6f0dd 22937+
4bf69007 22938+#include <linux/vserver/tag_cmd.h>
2ba6f0dd 22939+
2ba6f0dd 22940+
61333608 22941+int dx_migrate_task(struct task_struct *p, vtag_t tag)
4bf69007
AM
22942+{
22943+ if (!p)
22944+ BUG();
2ba6f0dd 22945+
4bf69007
AM
22946+ vxdprintk(VXD_CBIT(tag, 5),
22947+ "dx_migrate_task(%p[#%d],#%d)", p, p->tag, tag);
2ba6f0dd 22948+
4bf69007
AM
22949+ task_lock(p);
22950+ p->tag = tag;
22951+ task_unlock(p);
2ba6f0dd 22952+
4bf69007
AM
22953+ vxdprintk(VXD_CBIT(tag, 5),
22954+ "moved task %p into [#%d]", p, tag);
22955+ return 0;
22956+}
2ba6f0dd 22957+
4bf69007 22958+/* vserver syscall commands below here */
2ba6f0dd 22959+
4bf69007 22960+/* taks xid and vx_info functions */
2ba6f0dd 22961+
2ba6f0dd 22962+
4bf69007
AM
22963+int vc_task_tag(uint32_t id)
22964+{
61333608 22965+ vtag_t tag;
2ba6f0dd 22966+
4bf69007
AM
22967+ if (id) {
22968+ struct task_struct *tsk;
22969+ rcu_read_lock();
22970+ tsk = find_task_by_real_pid(id);
22971+ tag = (tsk) ? tsk->tag : -ESRCH;
22972+ rcu_read_unlock();
22973+ } else
22974+ tag = dx_current_tag();
22975+ return tag;
22976+}
2ba6f0dd 22977+
2ba6f0dd 22978+
4bf69007
AM
22979+int vc_tag_migrate(uint32_t tag)
22980+{
22981+ return dx_migrate_task(current, tag & 0xFFFF);
22982+}
2ba6f0dd 22983+
2ba6f0dd 22984+
f973f73f
AM
22985diff -NurpP --minimal linux-4.1.27/kernel/vserver/vci_config.h linux-4.1.27-vs2.3.8.5.2/kernel/vserver/vci_config.h
22986--- linux-4.1.27/kernel/vserver/vci_config.h 1970-01-01 00:00:00.000000000 +0000
22987+++ linux-4.1.27-vs2.3.8.5.2/kernel/vserver/vci_config.h 2016-07-05 04:41:47.000000000 +0000
4bf69007 22988@@ -0,0 +1,80 @@
2ba6f0dd 22989+
4bf69007 22990+/* interface version */
2ba6f0dd 22991+
4bf69007 22992+#define VCI_VERSION 0x00020308
2ba6f0dd 22993+
2ba6f0dd 22994+
4bf69007
AM
22995+enum {
22996+ VCI_KCBIT_NO_DYNAMIC = 0,
2ba6f0dd 22997+
4bf69007
AM
22998+ VCI_KCBIT_PROC_SECURE = 4,
22999+ /* VCI_KCBIT_HARDCPU = 5, */
23000+ /* VCI_KCBIT_IDLELIMIT = 6, */
23001+ /* VCI_KCBIT_IDLETIME = 7, */
2ba6f0dd 23002+
4bf69007
AM
23003+ VCI_KCBIT_COWBL = 8,
23004+ VCI_KCBIT_FULLCOWBL = 9,
23005+ VCI_KCBIT_SPACES = 10,
23006+ VCI_KCBIT_NETV2 = 11,
23007+ VCI_KCBIT_MEMCG = 12,
23008+ VCI_KCBIT_MEMCG_SWAP = 13,
2ba6f0dd 23009+
4bf69007
AM
23010+ VCI_KCBIT_DEBUG = 16,
23011+ VCI_KCBIT_HISTORY = 20,
23012+ VCI_KCBIT_TAGGED = 24,
23013+ VCI_KCBIT_PPTAG = 28,
2ba6f0dd 23014+
4bf69007 23015+ VCI_KCBIT_MORE = 31,
2ba6f0dd
AM
23016+};
23017+
2ba6f0dd 23018+
4bf69007
AM
23019+static inline uint32_t vci_kernel_config(void)
23020+{
23021+ return
23022+ (1 << VCI_KCBIT_NO_DYNAMIC) |
2ba6f0dd 23023+
4bf69007
AM
23024+ /* configured features */
23025+#ifdef CONFIG_VSERVER_PROC_SECURE
23026+ (1 << VCI_KCBIT_PROC_SECURE) |
23027+#endif
23028+#ifdef CONFIG_VSERVER_COWBL
23029+ (1 << VCI_KCBIT_COWBL) |
23030+ (1 << VCI_KCBIT_FULLCOWBL) |
23031+#endif
23032+ (1 << VCI_KCBIT_SPACES) |
23033+ (1 << VCI_KCBIT_NETV2) |
23034+#ifdef CONFIG_MEMCG
23035+ (1 << VCI_KCBIT_MEMCG) |
23036+#endif
23037+#ifdef CONFIG_MEMCG_SWAP
23038+ (1 << VCI_KCBIT_MEMCG_SWAP) |
23039+#endif
2ba6f0dd 23040+
4bf69007
AM
23041+ /* debug options */
23042+#ifdef CONFIG_VSERVER_DEBUG
23043+ (1 << VCI_KCBIT_DEBUG) |
23044+#endif
23045+#ifdef CONFIG_VSERVER_HISTORY
23046+ (1 << VCI_KCBIT_HISTORY) |
23047+#endif
2ba6f0dd 23048+
4bf69007
AM
23049+ /* inode context tagging */
23050+#if defined(CONFIG_TAGGING_NONE)
23051+ (0 << VCI_KCBIT_TAGGED) |
23052+#elif defined(CONFIG_TAGGING_UID16)
23053+ (1 << VCI_KCBIT_TAGGED) |
23054+#elif defined(CONFIG_TAGGING_GID16)
23055+ (2 << VCI_KCBIT_TAGGED) |
23056+#elif defined(CONFIG_TAGGING_ID24)
23057+ (3 << VCI_KCBIT_TAGGED) |
23058+#elif defined(CONFIG_TAGGING_INTERN)
23059+ (4 << VCI_KCBIT_TAGGED) |
23060+#elif defined(CONFIG_TAGGING_RUNTIME)
23061+ (5 << VCI_KCBIT_TAGGED) |
23062+#else
23063+ (7 << VCI_KCBIT_TAGGED) |
23064+#endif
23065+ (1 << VCI_KCBIT_PPTAG) |
23066+ 0;
23067+}
2ba6f0dd 23068+
f973f73f
AM
23069diff -NurpP --minimal linux-4.1.27/mm/memcontrol.c linux-4.1.27-vs2.3.8.5.2/mm/memcontrol.c
23070--- linux-4.1.27/mm/memcontrol.c 2016-07-05 04:28:32.000000000 +0000
23071+++ linux-4.1.27-vs2.3.8.5.2/mm/memcontrol.c 2016-07-05 18:27:07.000000000 +0000
23072@@ -3192,6 +3192,28 @@ static u64 mem_cgroup_read_u64(struct cg
23073 }
23074 }
23075
23076+u64 mem_cgroup_mem_usage_pages(struct mem_cgroup *memcg)
23077+{
23078+ return mem_cgroup_usage(memcg, false) >> PAGE_SHIFT;
23079+}
23080+
23081+u64 mem_cgroup_mem_limit_pages(struct mem_cgroup *memcg)
23082+{
23083+ return (u64)memcg->memory.limit;
23084+}
23085+
23086+u64 mem_cgroup_memsw_usage_pages(struct mem_cgroup *memcg)
23087+{
23088+ return mem_cgroup_usage(memcg, true) >> PAGE_SHIFT;
23089+}
23090+
23091+u64 mem_cgroup_memsw_limit_pages(struct mem_cgroup *memcg)
23092+{
23093+ return (u64)memcg->memsw.limit;
23094+}
23095+
23096+
23097+
23098 #ifdef CONFIG_MEMCG_KMEM
23099 static int memcg_activate_kmem(struct mem_cgroup *memcg,
23100 unsigned long nr_pages)
23101diff -NurpP --minimal linux-4.1.27/mm/oom_kill.c linux-4.1.27-vs2.3.8.5.2/mm/oom_kill.c
23102--- linux-4.1.27/mm/oom_kill.c 2015-07-06 20:41:43.000000000 +0000
23103+++ linux-4.1.27-vs2.3.8.5.2/mm/oom_kill.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
23104@@ -35,6 +35,8 @@
23105 #include <linux/freezer.h>
23106 #include <linux/ftrace.h>
23107 #include <linux/ratelimit.h>
23108+#include <linux/reboot.h>
23109+#include <linux/vs_context.h>
23110
23111 #define CREATE_TRACE_POINTS
23112 #include <trace/events/oom.h>
bb20add7 23113@@ -121,11 +123,18 @@ found:
4bf69007 23114 static bool oom_unkillable_task(struct task_struct *p,
5eef5607 23115 struct mem_cgroup *memcg, const nodemask_t *nodemask)
4bf69007
AM
23116 {
23117- if (is_global_init(p))
23118+ unsigned xid = vx_current_xid();
2ba6f0dd 23119+
4bf69007
AM
23120+ /* skip the init task, global and per guest */
23121+ if (task_is_init(p))
23122 return true;
23123 if (p->flags & PF_KTHREAD)
23124 return true;
23125
23126+ /* skip other guest and host processes if oom in guest */
23127+ if (xid && vx_task_xid(p) != xid)
23128+ return true;
2ba6f0dd 23129+
4bf69007
AM
23130 /* When mem_cgroup_out_of_memory() and p is not member of the group */
23131 if (memcg && !task_in_mem_cgroup(p, memcg))
23132 return true;
5eef5607 23133@@ -528,8 +537,8 @@ void oom_kill_process(struct task_struct
4bf69007
AM
23134 dump_header(p, gfp_mask, order, memcg, nodemask);
23135
23136 task_lock(p);
23137- pr_err("%s: Kill process %d (%s) score %d or sacrifice child\n",
23138- message, task_pid_nr(p), p->comm, points);
23139+ pr_err("%s: Kill process %d:#%u (%s) score %d or sacrifice child\n",
23140+ message, task_pid_nr(p), p->xid, p->comm, points);
23141 task_unlock(p);
23142
23143 /*
5eef5607 23144@@ -573,8 +582,8 @@ void oom_kill_process(struct task_struct
4bf69007
AM
23145 /* mm cannot safely be dereferenced after task_unlock(victim) */
23146 mm = victim->mm;
5eef5607 23147 mark_tsk_oom_victim(victim);
4bf69007
AM
23148- pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
23149- task_pid_nr(victim), victim->comm, K(victim->mm->total_vm),
5eef5607 23150+ pr_err("Killed process %d:%u (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
4bf69007
AM
23151+ task_pid_nr(victim), victim->xid, victim->comm, K(victim->mm->total_vm),
23152 K(get_mm_counter(victim->mm, MM_ANONPAGES)),
23153 K(get_mm_counter(victim->mm, MM_FILEPAGES)));
23154 task_unlock(victim);
5eef5607 23155@@ -645,6 +654,8 @@ int unregister_oom_notifier(struct notif
4bf69007
AM
23156 }
23157 EXPORT_SYMBOL_GPL(unregister_oom_notifier);
23158
23159+long vs_oom_action(unsigned int);
2ba6f0dd 23160+
4bf69007
AM
23161 /*
23162 * Try to acquire the OOM killer lock for the zones in zonelist. Returns zero
23163 * if a parallel OOM killing is already taking place that includes a zone in
5eef5607 23164@@ -757,7 +768,12 @@ static void __out_of_memory(struct zonel
4bf69007
AM
23165 /* Found nothing?!?! Either we hang forever, or we panic. */
23166 if (!p) {
23167 dump_header(NULL, gfp_mask, order, NULL, mpol_mask);
23168- panic("Out of memory and no killable processes...\n");
2ba6f0dd 23169+
4bf69007
AM
23170+ /* avoid panic for guest OOM */
23171+ if (vx_current_xid())
23172+ vs_oom_action(LINUX_REBOOT_CMD_OOM);
23173+ else
23174+ panic("Out of memory and no killable processes...\n");
23175 }
c2e5f7c8 23176 if (p != (void *)-1UL) {
4bf69007 23177 oom_kill_process(p, gfp_mask, order, points, totalpages, NULL,
f973f73f
AM
23178diff -NurpP --minimal linux-4.1.27/mm/page_alloc.c linux-4.1.27-vs2.3.8.5.2/mm/page_alloc.c
23179--- linux-4.1.27/mm/page_alloc.c 2016-07-05 04:28:33.000000000 +0000
23180+++ linux-4.1.27-vs2.3.8.5.2/mm/page_alloc.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 23181@@ -61,6 +61,8 @@
09be7631 23182 #include <linux/hugetlb.h>
b00e13aa 23183 #include <linux/sched/rt.h>
5eef5607 23184 #include <linux/page_owner.h>
4bf69007
AM
23185+#include <linux/vs_base.h>
23186+#include <linux/vs_limit.h>
23187
c2e5f7c8 23188 #include <asm/sections.h>
4bf69007 23189 #include <asm/tlbflush.h>
f973f73f 23190@@ -3189,6 +3191,9 @@ void si_meminfo(struct sysinfo *val)
4bf69007
AM
23191 val->totalhigh = totalhigh_pages;
23192 val->freehigh = nr_free_highpages();
23193 val->mem_unit = PAGE_SIZE;
2ba6f0dd 23194+
4bf69007
AM
23195+ if (vx_flags(VXF_VIRT_MEM, 0))
23196+ vx_vsi_meminfo(val);
23197 }
23198
23199 EXPORT_SYMBOL(si_meminfo);
f973f73f 23200@@ -3214,6 +3219,9 @@ void si_meminfo_node(struct sysinfo *val
4bf69007
AM
23201 val->freehigh = 0;
23202 #endif
23203 val->mem_unit = PAGE_SIZE;
2ba6f0dd 23204+
4bf69007
AM
23205+ if (vx_flags(VXF_VIRT_MEM, 0))
23206+ vx_vsi_meminfo(val);
23207 }
23208 #endif
23209
f973f73f
AM
23210diff -NurpP --minimal linux-4.1.27/mm/pgtable-generic.c linux-4.1.27-vs2.3.8.5.2/mm/pgtable-generic.c
23211--- linux-4.1.27/mm/pgtable-generic.c 2015-04-12 22:12:50.000000000 +0000
23212+++ linux-4.1.27-vs2.3.8.5.2/mm/pgtable-generic.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
23213@@ -6,6 +6,8 @@
23214 * Copyright (C) 2010 Linus Torvalds
23215 */
23216
23217+#include <linux/mm.h>
2ba6f0dd 23218+
4bf69007
AM
23219 #include <linux/pagemap.h>
23220 #include <asm/tlb.h>
23221 #include <asm-generic/pgtable.h>
f973f73f
AM
23222diff -NurpP --minimal linux-4.1.27/mm/shmem.c linux-4.1.27-vs2.3.8.5.2/mm/shmem.c
23223--- linux-4.1.27/mm/shmem.c 2015-07-06 20:41:43.000000000 +0000
23224+++ linux-4.1.27-vs2.3.8.5.2/mm/shmem.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 23225@@ -2180,7 +2180,7 @@ static int shmem_statfs(struct dentry *d
4bf69007
AM
23226 {
23227 struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
23228
23229- buf->f_type = TMPFS_MAGIC;
23230+ buf->f_type = TMPFS_SUPER_MAGIC;
23231 buf->f_bsize = PAGE_CACHE_SIZE;
23232 buf->f_namelen = NAME_MAX;
23233 if (sbinfo->max_blocks) {
5eef5607 23234@@ -3033,7 +3033,7 @@ int shmem_fill_super(struct super_block
4bf69007
AM
23235 sb->s_maxbytes = MAX_LFS_FILESIZE;
23236 sb->s_blocksize = PAGE_CACHE_SIZE;
23237 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
23238- sb->s_magic = TMPFS_MAGIC;
23239+ sb->s_magic = TMPFS_SUPER_MAGIC;
23240 sb->s_op = &shmem_ops;
23241 sb->s_time_gran = 1;
23242 #ifdef CONFIG_TMPFS_XATTR
f973f73f
AM
23243diff -NurpP --minimal linux-4.1.27/mm/slab.c linux-4.1.27-vs2.3.8.5.2/mm/slab.c
23244--- linux-4.1.27/mm/slab.c 2016-07-05 04:28:33.000000000 +0000
23245+++ linux-4.1.27-vs2.3.8.5.2/mm/slab.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 23246@@ -336,6 +336,8 @@ static void kmem_cache_node_init(struct
4bf69007
AM
23247 #define STATS_INC_FREEMISS(x) do { } while (0)
23248 #endif
23249
23250+#include "slab_vs.h"
2ba6f0dd 23251+
4bf69007
AM
23252 #if DEBUG
23253
23254 /*
5eef5607 23255@@ -3192,6 +3194,7 @@ slab_alloc_node(struct kmem_cache *cache
4bf69007
AM
23256 /* ___cache_alloc_node can fall back to other nodes */
23257 ptr = ____cache_alloc_node(cachep, flags, nodeid);
23258 out:
23259+ vx_slab_alloc(cachep, flags);
23260 local_irq_restore(save_flags);
23261 ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller);
23262 kmemleak_alloc_recursive(ptr, cachep->object_size, 1, cachep->flags,
5eef5607 23263@@ -3380,6 +3383,7 @@ static inline void __cache_free(struct k
4bf69007
AM
23264 check_irq_off();
23265 kmemleak_free_recursive(objp, cachep->flags);
23266 objp = cache_free_debugcheck(cachep, objp, caller);
23267+ vx_slab_free(cachep);
23268
23269 kmemcheck_slab_free(cachep, objp, cachep->object_size);
23270
f973f73f
AM
23271diff -NurpP --minimal linux-4.1.27/mm/slab_vs.h linux-4.1.27-vs2.3.8.5.2/mm/slab_vs.h
23272--- linux-4.1.27/mm/slab_vs.h 1970-01-01 00:00:00.000000000 +0000
23273+++ linux-4.1.27-vs2.3.8.5.2/mm/slab_vs.h 2016-07-05 04:41:47.000000000 +0000
4bf69007 23274@@ -0,0 +1,29 @@
2ba6f0dd 23275+
4bf69007 23276+#include <linux/vserver/context.h>
2ba6f0dd 23277+
4bf69007 23278+#include <linux/vs_context.h>
2ba6f0dd 23279+
4bf69007
AM
23280+static inline
23281+void vx_slab_alloc(struct kmem_cache *cachep, gfp_t flags)
23282+{
23283+ int what = gfp_zone(cachep->allocflags);
23284+ struct vx_info *vxi = current_vx_info();
2ba6f0dd 23285+
4bf69007
AM
23286+ if (!vxi)
23287+ return;
2ba6f0dd 23288+
4bf69007
AM
23289+ atomic_add(cachep->size, &vxi->cacct.slab[what]);
23290+}
2ba6f0dd 23291+
4bf69007
AM
23292+static inline
23293+void vx_slab_free(struct kmem_cache *cachep)
23294+{
23295+ int what = gfp_zone(cachep->allocflags);
23296+ struct vx_info *vxi = current_vx_info();
2ba6f0dd 23297+
4bf69007
AM
23298+ if (!vxi)
23299+ return;
2ba6f0dd 23300+
4bf69007
AM
23301+ atomic_sub(cachep->size, &vxi->cacct.slab[what]);
23302+}
2ba6f0dd 23303+
f973f73f
AM
23304diff -NurpP --minimal linux-4.1.27/mm/swapfile.c linux-4.1.27-vs2.3.8.5.2/mm/swapfile.c
23305--- linux-4.1.27/mm/swapfile.c 2015-07-06 20:41:43.000000000 +0000
23306+++ linux-4.1.27-vs2.3.8.5.2/mm/swapfile.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
23307@@ -39,6 +39,7 @@
23308 #include <asm/tlbflush.h>
23309 #include <linux/swapops.h>
5eef5607 23310 #include <linux/swap_cgroup.h>
4bf69007
AM
23311+#include <linux/vs_base.h>
23312
23313 static bool swap_count_continued(struct swap_info_struct *, pgoff_t,
23314 unsigned char);
bb20add7 23315@@ -2028,6 +2029,16 @@ static int swap_show(struct seq_file *sw
4bf69007
AM
23316
23317 if (si == SEQ_START_TOKEN) {
23318 seq_puts(swap,"Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
23319+ if (vx_flags(VXF_VIRT_MEM, 0)) {
23320+ struct sysinfo si;
2ba6f0dd 23321+
4bf69007
AM
23322+ vx_vsi_swapinfo(&si);
23323+ if (si.totalswap < (1 << 10))
23324+ return 0;
23325+ seq_printf(swap, "%s\t\t\t\t\t%s\t%lu\t%lu\t%d\n",
23326+ "hdv0", "partition", si.totalswap >> 10,
23327+ (si.totalswap - si.freeswap) >> 10, -1);
23328+ }
23329 return 0;
23330 }
23331
bb20add7 23332@@ -2576,6 +2587,8 @@ void si_swapinfo(struct sysinfo *val)
b00e13aa 23333 val->freeswap = atomic_long_read(&nr_swap_pages) + nr_to_be_unused;
4bf69007
AM
23334 val->totalswap = total_swap_pages + nr_to_be_unused;
23335 spin_unlock(&swap_lock);
23336+ if (vx_flags(VXF_VIRT_MEM, 0))
23337+ vx_vsi_swapinfo(val);
23338 }
23339
23340 /*
f973f73f
AM
23341diff -NurpP --minimal linux-4.1.27/net/bridge/br_multicast.c linux-4.1.27-vs2.3.8.5.2/net/bridge/br_multicast.c
23342--- linux-4.1.27/net/bridge/br_multicast.c 2016-07-05 04:28:33.000000000 +0000
23343+++ linux-4.1.27-vs2.3.8.5.2/net/bridge/br_multicast.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 23344@@ -448,7 +448,7 @@ static struct sk_buff *br_ip6_multicast_
4bf69007
AM
23345 ip6h->hop_limit = 1;
23346 ipv6_addr_set(&ip6h->daddr, htonl(0xff020000), 0, 0, htonl(1));
23347 if (ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0,
23348- &ip6h->saddr)) {
23349+ &ip6h->saddr, NULL)) {
23350 kfree_skb(skb);
23351 return NULL;
23352 }
f973f73f
AM
23353diff -NurpP --minimal linux-4.1.27/net/core/dev.c linux-4.1.27-vs2.3.8.5.2/net/core/dev.c
23354--- linux-4.1.27/net/core/dev.c 2016-07-05 04:28:33.000000000 +0000
23355+++ linux-4.1.27-vs2.3.8.5.2/net/core/dev.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 23356@@ -123,6 +123,7 @@
4bf69007
AM
23357 #include <linux/in.h>
23358 #include <linux/jhash.h>
23359 #include <linux/random.h>
23360+#include <linux/vs_inet.h>
23361 #include <trace/events/napi.h>
23362 #include <trace/events/net.h>
23363 #include <trace/events/skb.h>
5eef5607 23364@@ -694,7 +695,8 @@ struct net_device *__dev_get_by_name(str
4bf69007
AM
23365 struct hlist_head *head = dev_name_hash(net, name);
23366
b00e13aa 23367 hlist_for_each_entry(dev, head, name_hlist)
4bf69007
AM
23368- if (!strncmp(dev->name, name, IFNAMSIZ))
23369+ if (!strncmp(dev->name, name, IFNAMSIZ) &&
23370+ nx_dev_visible(current_nx_info(), dev))
23371 return dev;
23372
23373 return NULL;
5eef5607 23374@@ -719,7 +721,8 @@ struct net_device *dev_get_by_name_rcu(s
4bf69007
AM
23375 struct hlist_head *head = dev_name_hash(net, name);
23376
b00e13aa 23377 hlist_for_each_entry_rcu(dev, head, name_hlist)
4bf69007
AM
23378- if (!strncmp(dev->name, name, IFNAMSIZ))
23379+ if (!strncmp(dev->name, name, IFNAMSIZ) &&
23380+ nx_dev_visible(current_nx_info(), dev))
23381 return dev;
23382
23383 return NULL;
5eef5607 23384@@ -769,7 +772,8 @@ struct net_device *__dev_get_by_index(st
4bf69007
AM
23385 struct hlist_head *head = dev_index_hash(net, ifindex);
23386
b00e13aa 23387 hlist_for_each_entry(dev, head, index_hlist)
4bf69007
AM
23388- if (dev->ifindex == ifindex)
23389+ if ((dev->ifindex == ifindex) &&
23390+ nx_dev_visible(current_nx_info(), dev))
23391 return dev;
23392
23393 return NULL;
5eef5607 23394@@ -787,7 +791,7 @@ EXPORT_SYMBOL(__dev_get_by_index);
4bf69007
AM
23395 * about locking. The caller must hold RCU lock.
23396 */
23397
23398-struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
23399+struct net_device *dev_get_by_index_real_rcu(struct net *net, int ifindex)
23400 {
4bf69007 23401 struct net_device *dev;
b00e13aa 23402 struct hlist_head *head = dev_index_hash(net, ifindex);
5eef5607 23403@@ -798,6 +802,16 @@ struct net_device *dev_get_by_index_rcu(
4bf69007
AM
23404
23405 return NULL;
23406 }
23407+EXPORT_SYMBOL(dev_get_by_index_real_rcu);
2ba6f0dd 23408+
4bf69007
AM
23409+struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
23410+{
23411+ struct net_device *dev = dev_get_by_index_real_rcu(net, ifindex);
2ba6f0dd 23412+
4bf69007
AM
23413+ if (nx_dev_visible(current_nx_info(), dev))
23414+ return dev;
23415+ return NULL;
23416+}
23417 EXPORT_SYMBOL(dev_get_by_index_rcu);
23418
23419
5eef5607 23420@@ -880,7 +894,8 @@ struct net_device *dev_getbyhwaddr_rcu(s
4bf69007
AM
23421
23422 for_each_netdev_rcu(net, dev)
23423 if (dev->type == type &&
23424- !memcmp(dev->dev_addr, ha, dev->addr_len))
23425+ !memcmp(dev->dev_addr, ha, dev->addr_len) &&
23426+ nx_dev_visible(current_nx_info(), dev))
23427 return dev;
23428
23429 return NULL;
5eef5607 23430@@ -892,9 +907,11 @@ struct net_device *__dev_getfirstbyhwtyp
4bf69007
AM
23431 struct net_device *dev;
23432
23433 ASSERT_RTNL();
23434- for_each_netdev(net, dev)
23435- if (dev->type == type)
23436+ for_each_netdev(net, dev) {
23437+ if ((dev->type == type) &&
23438+ nx_dev_visible(current_nx_info(), dev))
23439 return dev;
23440+ }
23441
23442 return NULL;
23443 }
5eef5607 23444@@ -906,7 +923,8 @@ struct net_device *dev_getfirstbyhwtype(
b00e13aa
AM
23445
23446 rcu_read_lock();
23447 for_each_netdev_rcu(net, dev)
23448- if (dev->type == type) {
23449+ if ((dev->type == type) &&
23450+ nx_dev_visible(current_nx_info(), dev)) {
23451 dev_hold(dev);
23452 ret = dev;
23453 break;
5eef5607 23454@@ -936,7 +954,8 @@ struct net_device *__dev_get_by_flags(st
b00e13aa
AM
23455
23456 ret = NULL;
bb20add7 23457 for_each_netdev(net, dev) {
b00e13aa
AM
23458- if (((dev->flags ^ if_flags) & mask) == 0) {
23459+ if ((((dev->flags ^ if_flags) & mask) == 0) &&
23460+ nx_dev_visible(current_nx_info(), dev)) {
23461 ret = dev;
23462 break;
23463 }
5eef5607 23464@@ -1014,6 +1033,8 @@ static int __dev_alloc_name(struct net *
4bf69007
AM
23465 continue;
23466 if (i < 0 || i >= max_netdevices)
23467 continue;
23468+ if (!nx_dev_visible(current_nx_info(), d))
23469+ continue;
23470
23471 /* avoid cases where sscanf is not exact inverse of printf */
23472 snprintf(buf, IFNAMSIZ, name, i);
f973f73f
AM
23473diff -NurpP --minimal linux-4.1.27/net/core/net-procfs.c linux-4.1.27-vs2.3.8.5.2/net/core/net-procfs.c
23474--- linux-4.1.27/net/core/net-procfs.c 2015-04-12 22:12:50.000000000 +0000
23475+++ linux-4.1.27-vs2.3.8.5.2/net/core/net-procfs.c 2016-07-05 04:41:47.000000000 +0000
8ce283e1
AM
23476@@ -1,6 +1,7 @@
23477 #include <linux/netdevice.h>
23478 #include <linux/proc_fs.h>
23479 #include <linux/seq_file.h>
23480+#include <linux/vs_inet.h>
23481 #include <net/wext.h>
23482
23483 #define BUCKET_SPACE (32 - NETDEV_HASHBITS - 1)
23484@@ -77,8 +78,13 @@ static void dev_seq_stop(struct seq_file
23485 static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
23486 {
23487 struct rtnl_link_stats64 temp;
23488- const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);
23489+ const struct rtnl_link_stats64 *stats;
23490+
23491+ /* device visible inside network context? */
23492+ if (!nx_dev_visible(current_nx_info(), dev))
23493+ return;
23494
23495+ stats = dev_get_stats(dev, &temp);
23496 seq_printf(seq, "%6s: %7llu %7llu %4llu %4llu %4llu %5llu %10llu %9llu "
23497 "%8llu %7llu %4llu %4llu %4llu %5llu %7llu %10llu\n",
23498 dev->name, stats->rx_bytes, stats->rx_packets,
f973f73f
AM
23499diff -NurpP --minimal linux-4.1.27/net/core/rtnetlink.c linux-4.1.27-vs2.3.8.5.2/net/core/rtnetlink.c
23500--- linux-4.1.27/net/core/rtnetlink.c 2016-07-05 04:28:33.000000000 +0000
23501+++ linux-4.1.27-vs2.3.8.5.2/net/core/rtnetlink.c 2016-07-05 04:41:47.000000000 +0000
5eef5607
AM
23502@@ -1350,6 +1350,8 @@ static int rtnl_dump_ifinfo(struct sk_bu
23503 hlist_for_each_entry(dev, head, index_hlist) {
4bf69007
AM
23504 if (idx < s_idx)
23505 goto cont;
23506+ if (!nx_dev_visible(skb->sk->sk_nx_info, dev))
23507+ continue;
7ed51edd
JR
23508 err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
23509 NETLINK_CB(cb->skb).portid,
23510 cb->nlh->nlmsg_seq, 0,
5eef5607
AM
23511@@ -2421,6 +2423,9 @@ void rtmsg_ifinfo(int type, struct net_d
23512 {
23513 struct sk_buff *skb;
4bf69007
AM
23514
23515+ if (!nx_dev_visible(current_nx_info(), dev))
23516+ return;
2ba6f0dd 23517+
5eef5607
AM
23518 if (dev->reg_state != NETREG_REGISTERED)
23519 return;
23520
f973f73f
AM
23521diff -NurpP --minimal linux-4.1.27/net/core/sock.c linux-4.1.27-vs2.3.8.5.2/net/core/sock.c
23522--- linux-4.1.27/net/core/sock.c 2016-07-05 04:28:33.000000000 +0000
23523+++ linux-4.1.27-vs2.3.8.5.2/net/core/sock.c 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 23524@@ -133,6 +133,10 @@
4bf69007
AM
23525 #include <net/netprio_cgroup.h>
23526
23527 #include <linux/filter.h>
23528+#include <linux/vs_socket.h>
23529+#include <linux/vs_limit.h>
23530+#include <linux/vs_context.h>
23531+#include <linux/vs_network.h>
23532
23533 #include <trace/events/sock.h>
23534
9e3e8383 23535@@ -1346,6 +1350,8 @@ static struct sock *sk_prot_alloc(struct
4bf69007
AM
23536 goto out_free_sec;
23537 sk_tx_queue_clear(sk);
23538 }
23539+ sock_vx_init(sk);
23540+ sock_nx_init(sk);
23541
23542 return sk;
23543
9e3e8383 23544@@ -1442,6 +1448,11 @@ static void __sk_free(struct sock *sk)
4bf69007
AM
23545 put_cred(sk->sk_peer_cred);
23546 put_pid(sk->sk_peer_pid);
23547 put_net(sock_net(sk));
23548+ vx_sock_dec(sk);
23549+ clr_vx_info(&sk->sk_vx_info);
23550+ sk->sk_xid = -1;
23551+ clr_nx_info(&sk->sk_nx_info);
23552+ sk->sk_nid = -1;
23553 sk_prot_free(sk->sk_prot_creator, sk);
23554 }
23555
9e3e8383 23556@@ -1502,6 +1513,8 @@ struct sock *sk_clone_lock(const struct
4bf69007
AM
23557
23558 /* SANITY */
23559 get_net(sock_net(newsk));
23560+ sock_vx_init(newsk);
23561+ sock_nx_init(newsk);
23562 sk_node_init(&newsk->sk_node);
23563 sock_lock_init(newsk);
23564 bh_lock_sock(newsk);
9e3e8383 23565@@ -1561,6 +1574,12 @@ struct sock *sk_clone_lock(const struct
4bf69007
AM
23566 smp_wmb();
23567 atomic_set(&newsk->sk_refcnt, 2);
23568
23569+ set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info);
23570+ newsk->sk_xid = sk->sk_xid;
23571+ vx_sock_inc(newsk);
23572+ set_nx_info(&newsk->sk_nx_info, sk->sk_nx_info);
23573+ newsk->sk_nid = sk->sk_nid;
2ba6f0dd 23574+
4bf69007
AM
23575 /*
23576 * Increment the counter in the same struct proto as the master
23577 * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
9e3e8383 23578@@ -2345,6 +2364,12 @@ void sock_init_data(struct socket *sock,
4bf69007
AM
23579
23580 sk->sk_stamp = ktime_set(-1L, 0);
23581
23582+ set_vx_info(&sk->sk_vx_info, current_vx_info());
23583+ sk->sk_xid = vx_current_xid();
23584+ vx_sock_inc(sk);
23585+ set_nx_info(&sk->sk_nx_info, current_nx_info());
23586+ sk->sk_nid = nx_current_nid();
2ba6f0dd 23587+
c2e5f7c8
JR
23588 #ifdef CONFIG_NET_RX_BUSY_POLL
23589 sk->sk_napi_id = 0;
23590 sk->sk_ll_usec = sysctl_net_busy_read;
f973f73f
AM
23591diff -NurpP --minimal linux-4.1.27/net/ipv4/af_inet.c linux-4.1.27-vs2.3.8.5.2/net/ipv4/af_inet.c
23592--- linux-4.1.27/net/ipv4/af_inet.c 2016-07-05 04:28:33.000000000 +0000
23593+++ linux-4.1.27-vs2.3.8.5.2/net/ipv4/af_inet.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
23594@@ -118,6 +118,7 @@
23595 #ifdef CONFIG_IP_MROUTE
23596 #include <linux/mroute.h>
23597 #endif
23598+#include <linux/vs_limit.h>
23599
23600
23601 /* The inetsw table contains everything that inet_create needs to
9e3e8383 23602@@ -310,10 +311,13 @@ lookup_protocol:
4bf69007
AM
23603 }
23604
23605 err = -EPERM;
23606+ if ((protocol == IPPROTO_ICMP) &&
23607+ nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
23608+ goto override;
b00e13aa
AM
23609 if (sock->type == SOCK_RAW && !kern &&
23610 !ns_capable(net->user_ns, CAP_NET_RAW))
4bf69007 23611 goto out_rcu_unlock;
a4a22af8
AM
23612-
23613+override:
23614 sock->ops = answer->ops;
23615 answer_prot = answer->prot;
bb20add7 23616 answer_flags = answer->flags;
9e3e8383 23617@@ -426,6 +430,7 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23618 struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
23619 struct sock *sk = sock->sk;
23620 struct inet_sock *inet = inet_sk(sk);
23621+ struct nx_v4_sock_addr nsa;
b00e13aa 23622 struct net *net = sock_net(sk);
4bf69007
AM
23623 unsigned short snum;
23624 int chk_addr_ret;
9e3e8383 23625@@ -450,7 +455,11 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23626 goto out;
23627 }
23628
b00e13aa 23629- chk_addr_ret = inet_addr_type(net, addr->sin_addr.s_addr);
4bf69007
AM
23630+ err = v4_map_sock_addr(inet, addr, &nsa);
23631+ if (err)
23632+ goto out;
2ba6f0dd 23633+
b00e13aa 23634+ chk_addr_ret = inet_addr_type(net, nsa.saddr);
4bf69007
AM
23635
23636 /* Not specified by any standard per-se, however it breaks too
23637 * many applications when removed. It is unfortunate since
9e3e8383 23638@@ -462,7 +471,7 @@ int inet_bind(struct socket *sock, struc
4bf69007 23639 err = -EADDRNOTAVAIL;
bb20add7 23640 if (!net->ipv4.sysctl_ip_nonlocal_bind &&
4bf69007
AM
23641 !(inet->freebind || inet->transparent) &&
23642- addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
23643+ nsa.saddr != htonl(INADDR_ANY) &&
23644 chk_addr_ret != RTN_LOCAL &&
23645 chk_addr_ret != RTN_MULTICAST &&
23646 chk_addr_ret != RTN_BROADCAST)
9e3e8383 23647@@ -488,7 +497,7 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23648 if (sk->sk_state != TCP_CLOSE || inet->inet_num)
23649 goto out_release_sock;
23650
23651- inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
23652+ v4_set_sock_addr(inet, &nsa);
23653 if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
23654 inet->inet_saddr = 0; /* Use device */
23655
9e3e8383 23656@@ -707,11 +716,13 @@ int inet_getname(struct socket *sock, st
4bf69007
AM
23657 peer == 1))
23658 return -ENOTCONN;
23659 sin->sin_port = inet->inet_dport;
23660- sin->sin_addr.s_addr = inet->inet_daddr;
23661+ sin->sin_addr.s_addr =
23662+ nx_map_sock_lback(sk->sk_nx_info, inet->inet_daddr);
23663 } else {
23664 __be32 addr = inet->inet_rcv_saddr;
23665 if (!addr)
23666 addr = inet->inet_saddr;
23667+ addr = nx_map_sock_lback(sk->sk_nx_info, addr);
23668 sin->sin_port = inet->inet_sport;
23669 sin->sin_addr.s_addr = addr;
23670 }
f973f73f
AM
23671diff -NurpP --minimal linux-4.1.27/net/ipv4/arp.c linux-4.1.27-vs2.3.8.5.2/net/ipv4/arp.c
23672--- linux-4.1.27/net/ipv4/arp.c 2015-07-06 20:41:43.000000000 +0000
23673+++ linux-4.1.27-vs2.3.8.5.2/net/ipv4/arp.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 23674@@ -1257,6 +1257,7 @@ static void arp_format_neigh_entry(struc
4bf69007
AM
23675 struct net_device *dev = n->dev;
23676 int hatype = dev->type;
23677
23678+ /* FIXME: check for network context */
23679 read_lock(&n->lock);
23680 /* Convert hardware address to XX:XX:XX:XX ... form. */
23681 #if IS_ENABLED(CONFIG_AX25)
5eef5607 23682@@ -1288,6 +1289,7 @@ static void arp_format_pneigh_entry(stru
4bf69007
AM
23683 int hatype = dev ? dev->type : 0;
23684 char tbuf[16];
23685
23686+ /* FIXME: check for network context */
23687 sprintf(tbuf, "%pI4", n->key);
23688 seq_printf(seq, "%-16s 0x%-10x0x%-10x%s * %s\n",
23689 tbuf, hatype, ATF_PUBL | ATF_PERM, "00:00:00:00:00:00",
f973f73f
AM
23690diff -NurpP --minimal linux-4.1.27/net/ipv4/devinet.c linux-4.1.27-vs2.3.8.5.2/net/ipv4/devinet.c
23691--- linux-4.1.27/net/ipv4/devinet.c 2016-07-05 04:28:33.000000000 +0000
23692+++ linux-4.1.27-vs2.3.8.5.2/net/ipv4/devinet.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 23693@@ -534,6 +534,7 @@ struct in_device *inetdev_by_index(struc
4bf69007
AM
23694 }
23695 EXPORT_SYMBOL(inetdev_by_index);
23696
2ba6f0dd 23697+
4bf69007
AM
23698 /* Called only from RTNL semaphored context. No locks. */
23699
23700 struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
5eef5607 23701@@ -989,6 +990,8 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23702
23703 in_dev = __in_dev_get_rtnl(dev);
23704 if (in_dev) {
23705+ struct nx_info *nxi = current_nx_info();
2ba6f0dd 23706+
4bf69007
AM
23707 if (tryaddrmatch) {
23708 /* Matthias Andree */
23709 /* compare label and address (4.4BSD style) */
5eef5607 23710@@ -997,6 +1000,8 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23711 This is checked above. */
23712 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
23713 ifap = &ifa->ifa_next) {
23714+ if (!nx_v4_ifa_visible(nxi, ifa))
23715+ continue;
23716 if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
23717 sin_orig.sin_addr.s_addr ==
23718 ifa->ifa_local) {
5eef5607 23719@@ -1009,9 +1014,12 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23720 comparing just the label */
23721 if (!ifa) {
23722 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
23723- ifap = &ifa->ifa_next)
23724+ ifap = &ifa->ifa_next) {
23725+ if (!nx_v4_ifa_visible(nxi, ifa))
23726+ continue;
23727 if (!strcmp(ifr.ifr_name, ifa->ifa_label))
23728 break;
23729+ }
23730 }
23731 }
23732
5eef5607 23733@@ -1165,6 +1173,8 @@ static int inet_gifconf(struct net_devic
4bf69007
AM
23734 goto out;
23735
23736 for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
23737+ if (!nx_v4_ifa_visible(current_nx_info(), ifa))
23738+ continue;
23739 if (!buf) {
23740 done += sizeof(ifr);
23741 continue;
5eef5607 23742@@ -1570,6 +1580,7 @@ static int inet_dump_ifaddr(struct sk_bu
4bf69007
AM
23743 struct net_device *dev;
23744 struct in_device *in_dev;
23745 struct in_ifaddr *ifa;
23746+ struct sock *sk = skb->sk;
23747 struct hlist_head *head;
4bf69007 23748
b00e13aa 23749 s_h = cb->args[0];
5eef5607 23750@@ -1593,6 +1604,8 @@ static int inet_dump_ifaddr(struct sk_bu
4bf69007
AM
23751
23752 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
23753 ifa = ifa->ifa_next, ip_idx++) {
23754+ if (sk && !nx_v4_ifa_visible(sk->sk_nx_info, ifa))
23755+ continue;
23756 if (ip_idx < s_ip_idx)
23757 continue;
23758 if (inet_fill_ifaddr(skb, ifa,
f973f73f
AM
23759diff -NurpP --minimal linux-4.1.27/net/ipv4/fib_trie.c linux-4.1.27-vs2.3.8.5.2/net/ipv4/fib_trie.c
23760--- linux-4.1.27/net/ipv4/fib_trie.c 2016-07-05 04:28:33.000000000 +0000
23761+++ linux-4.1.27-vs2.3.8.5.2/net/ipv4/fib_trie.c 2016-07-05 04:41:47.000000000 +0000
5eef5607
AM
23762@@ -2576,6 +2576,7 @@ static int fib_route_seq_show(struct seq
23763
23764 seq_setwidth(seq, 127);
23765
23766+ /* FIXME: check for network context? */
23767 if (fi)
23768 seq_printf(seq,
23769 "%s\t%08X\t%08X\t%04X\t%d\t%u\t"
f973f73f
AM
23770diff -NurpP --minimal linux-4.1.27/net/ipv4/inet_connection_sock.c linux-4.1.27-vs2.3.8.5.2/net/ipv4/inet_connection_sock.c
23771--- linux-4.1.27/net/ipv4/inet_connection_sock.c 2016-07-05 04:28:33.000000000 +0000
23772+++ linux-4.1.27-vs2.3.8.5.2/net/ipv4/inet_connection_sock.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 23773@@ -43,6 +43,37 @@ void inet_get_local_port_range(struct ne
4bf69007
AM
23774 }
23775 EXPORT_SYMBOL(inet_get_local_port_range);
23776
23777+int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
23778+{
c2e5f7c8
JR
23779+ __be32 sk1_rcv_saddr = sk1->sk_rcv_saddr,
23780+ sk2_rcv_saddr = sk2->sk_rcv_saddr;
2ba6f0dd 23781+
4bf69007
AM
23782+ if (inet_v6_ipv6only(sk2))
23783+ return 0;
2ba6f0dd 23784+
4bf69007
AM
23785+ if (sk1_rcv_saddr &&
23786+ sk2_rcv_saddr &&
23787+ sk1_rcv_saddr == sk2_rcv_saddr)
23788+ return 1;
2ba6f0dd 23789+
4bf69007
AM
23790+ if (sk1_rcv_saddr &&
23791+ !sk2_rcv_saddr &&
23792+ v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, NXA_MASK_BIND))
23793+ return 1;
2ba6f0dd 23794+
4bf69007
AM
23795+ if (sk2_rcv_saddr &&
23796+ !sk1_rcv_saddr &&
23797+ v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, NXA_MASK_BIND))
23798+ return 1;
2ba6f0dd 23799+
4bf69007
AM
23800+ if (!sk1_rcv_saddr &&
23801+ !sk2_rcv_saddr &&
23802+ nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info))
23803+ return 1;
2ba6f0dd 23804+
4bf69007
AM
23805+ return 0;
23806+}
2ba6f0dd 23807+
4bf69007
AM
23808 int inet_csk_bind_conflict(const struct sock *sk,
23809 const struct inet_bind_bucket *tb, bool relax)
23810 {
5eef5607 23811@@ -70,15 +101,13 @@ int inet_csk_bind_conflict(const struct
b00e13aa
AM
23812 (sk2->sk_state != TCP_TIME_WAIT &&
23813 !uid_eq(uid, sock_i_uid(sk2))))) {
c2e5f7c8
JR
23814
23815- if (!sk2->sk_rcv_saddr || !sk->sk_rcv_saddr ||
23816- sk2->sk_rcv_saddr == sk->sk_rcv_saddr)
4bf69007
AM
23817+ if (ipv4_rcv_saddr_equal(sk, sk2))
23818 break;
23819 }
23820 if (!relax && reuse && sk2->sk_reuse &&
b00e13aa 23821 sk2->sk_state != TCP_LISTEN) {
c2e5f7c8
JR
23822
23823- if (!sk2->sk_rcv_saddr || !sk->sk_rcv_saddr ||
23824- sk2->sk_rcv_saddr == sk->sk_rcv_saddr)
b00e13aa
AM
23825+ if (ipv4_rcv_saddr_equal(sk, sk2))
23826 break;
23827 }
23828 }
f973f73f
AM
23829diff -NurpP --minimal linux-4.1.27/net/ipv4/inet_diag.c linux-4.1.27-vs2.3.8.5.2/net/ipv4/inet_diag.c
23830--- linux-4.1.27/net/ipv4/inet_diag.c 2015-07-06 20:41:43.000000000 +0000
23831+++ linux-4.1.27-vs2.3.8.5.2/net/ipv4/inet_diag.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
23832@@ -31,6 +31,8 @@
23833
23834 #include <linux/inet.h>
23835 #include <linux/stddef.h>
23836+#include <linux/vs_network.h>
23837+#include <linux/vs_inet.h>
23838
23839 #include <linux/inet_diag.h>
23840 #include <linux/sock_diag.h>
5eef5607 23841@@ -770,6 +772,7 @@ static int inet_diag_dump_reqs(struct sk
4bf69007
AM
23842 r->id.idiag_dport)
23843 continue;
23844
23845+ /* TODO: lback */
23846 if (bc) {
5eef5607
AM
23847 /* Note: entry.sport and entry.userlocks are already set */
23848 entry_fill_addrs(&entry, req_to_sk(req));
23849@@ -827,6 +830,8 @@ void inet_diag_dump_icsk(struct inet_has
4bf69007
AM
23850 if (!net_eq(sock_net(sk), net))
23851 continue;
23852
23853+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23854+ continue;
23855 if (num < s_num) {
23856 num++;
23857 continue;
5eef5607 23858@@ -898,6 +903,8 @@ skip_listen_ht:
4bf69007
AM
23859
23860 if (!net_eq(sock_net(sk), net))
23861 continue;
23862+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23863+ continue;
23864 if (num < s_num)
23865 goto next_normal;
c2e5f7c8 23866 state = (sk->sk_state == TCP_TIME_WAIT) ?
f973f73f
AM
23867diff -NurpP --minimal linux-4.1.27/net/ipv4/inet_hashtables.c linux-4.1.27-vs2.3.8.5.2/net/ipv4/inet_hashtables.c
23868--- linux-4.1.27/net/ipv4/inet_hashtables.c 2015-07-06 20:41:43.000000000 +0000
23869+++ linux-4.1.27-vs2.3.8.5.2/net/ipv4/inet_hashtables.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
23870@@ -22,6 +22,7 @@
23871 #include <net/inet_connection_sock.h>
23872 #include <net/inet_hashtables.h>
23873 #include <net/secure_seq.h>
23874+#include <net/route.h>
23875 #include <net/ip.h>
23876
5eef5607
AM
23877 static u32 inet_ehashfn(const struct net *net, const __be32 laddr,
23878@@ -184,6 +185,11 @@ static inline int compute_score(struct s
4bf69007
AM
23879 if (rcv_saddr != daddr)
23880 return -1;
b00e13aa 23881 score += 4;
4bf69007
AM
23882+ } else {
23883+ /* block non nx_info ips */
23884+ if (!v4_addr_in_nx_info(sk->sk_nx_info,
23885+ daddr, NXA_MASK_BIND))
23886+ return -1;
23887 }
23888 if (sk->sk_bound_dev_if) {
23889 if (sk->sk_bound_dev_if != dif)
5eef5607 23890@@ -201,7 +207,6 @@ static inline int compute_score(struct s
4bf69007
AM
23891 * wildcarded during the search since they can never be otherwise.
23892 */
23893
23894-
23895 struct sock *__inet_lookup_listener(struct net *net,
23896 struct inet_hashinfo *hashinfo,
b00e13aa 23897 const __be32 saddr, __be16 sport,
5eef5607 23898@@ -237,6 +242,7 @@ begin:
b00e13aa 23899 phash = next_pseudo_random32(phash);
4bf69007
AM
23900 }
23901 }
2ba6f0dd 23902+
4bf69007
AM
23903 /*
23904 * if the nulls value we got at the end of this lookup is
23905 * not the expected one, we must restart lookup.
f973f73f
AM
23906diff -NurpP --minimal linux-4.1.27/net/ipv4/netfilter.c linux-4.1.27-vs2.3.8.5.2/net/ipv4/netfilter.c
23907--- linux-4.1.27/net/ipv4/netfilter.c 2015-07-06 20:41:43.000000000 +0000
23908+++ linux-4.1.27-vs2.3.8.5.2/net/ipv4/netfilter.c 2016-07-05 04:41:47.000000000 +0000
09be7631 23909@@ -11,7 +11,7 @@
4bf69007
AM
23910 #include <linux/skbuff.h>
23911 #include <linux/gfp.h>
23912 #include <linux/export.h>
23913-#include <net/route.h>
23914+// #include <net/route.h>
23915 #include <net/xfrm.h>
23916 #include <net/ip.h>
23917 #include <net/netfilter/nf_queue.h>
f973f73f
AM
23918diff -NurpP --minimal linux-4.1.27/net/ipv4/raw.c linux-4.1.27-vs2.3.8.5.2/net/ipv4/raw.c
23919--- linux-4.1.27/net/ipv4/raw.c 2016-07-05 04:28:33.000000000 +0000
23920+++ linux-4.1.27-vs2.3.8.5.2/net/ipv4/raw.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 23921@@ -126,7 +126,7 @@ static struct sock *__raw_v4_lookup(stru
4bf69007
AM
23922
23923 if (net_eq(sock_net(sk), net) && inet->inet_num == num &&
23924 !(inet->inet_daddr && inet->inet_daddr != raddr) &&
23925- !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
23926+ v4_sock_addr_match(sk->sk_nx_info, inet, laddr) &&
23927 !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
23928 goto found; /* gotcha */
23929 }
5eef5607 23930@@ -411,6 +411,12 @@ static int raw_send_hdrinc(struct sock *
4bf69007
AM
23931 icmp_out_count(net, ((struct icmphdr *)
23932 skb_transport_header(skb))->type);
23933
23934+ err = -EPERM;
23935+ if (!nx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW) &&
23936+ sk->sk_nx_info &&
23937+ !v4_addr_in_nx_info(sk->sk_nx_info, iph->saddr, NXA_MASK_BIND))
23938+ goto error_free;
2ba6f0dd 23939+
5eef5607
AM
23940 err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, sk, skb,
23941 NULL, rt->dst.dev, dst_output_sk);
4bf69007 23942 if (err > 0)
f973f73f 23943@@ -608,6 +614,16 @@ static int raw_sendmsg(struct sock *sk,
4bf69007
AM
23944 goto done;
23945 }
23946
23947+ if (sk->sk_nx_info) {
23948+ rt = ip_v4_find_src(sock_net(sk), sk->sk_nx_info, &fl4);
23949+ if (IS_ERR(rt)) {
23950+ err = PTR_ERR(rt);
23951+ rt = NULL;
23952+ goto done;
23953+ }
23954+ ip_rt_put(rt);
23955+ }
2ba6f0dd 23956+
4bf69007
AM
23957 security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
23958 rt = ip_route_output_flow(sock_net(sk), &fl4, sk);
23959 if (IS_ERR(rt)) {
f973f73f 23960@@ -686,17 +702,19 @@ static int raw_bind(struct sock *sk, str
4bf69007
AM
23961 {
23962 struct inet_sock *inet = inet_sk(sk);
23963 struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
23964+ struct nx_v4_sock_addr nsa = { 0 };
23965 int ret = -EINVAL;
23966 int chk_addr_ret;
23967
23968 if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
23969 goto out;
23970- chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
23971+ v4_map_sock_addr(inet, addr, &nsa);
23972+ chk_addr_ret = inet_addr_type(sock_net(sk), nsa.saddr);
23973 ret = -EADDRNOTAVAIL;
23974- if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
23975+ if (nsa.saddr && chk_addr_ret != RTN_LOCAL &&
23976 chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
23977 goto out;
23978- inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
23979+ v4_set_sock_addr(inet, &nsa);
23980 if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
23981 inet->inet_saddr = 0; /* Use device */
23982 sk_dst_reset(sk);
f973f73f 23983@@ -745,7 +763,8 @@ static int raw_recvmsg(struct sock *sk,
4bf69007
AM
23984 /* Copy the address. */
23985 if (sin) {
23986 sin->sin_family = AF_INET;
23987- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
23988+ sin->sin_addr.s_addr =
23989+ nx_map_sock_lback(sk->sk_nx_info, ip_hdr(skb)->saddr);
23990 sin->sin_port = 0;
23991 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
c2e5f7c8 23992 *addr_len = sizeof(*sin);
f973f73f 23993@@ -941,7 +960,8 @@ static struct sock *raw_get_first(struct
b00e13aa
AM
23994 for (state->bucket = 0; state->bucket < RAW_HTABLE_SIZE;
23995 ++state->bucket) {
23996 sk_for_each(sk, &state->h->ht[state->bucket])
4bf69007
AM
23997- if (sock_net(sk) == seq_file_net(seq))
23998+ if ((sock_net(sk) == seq_file_net(seq)) &&
b00e13aa 23999+ nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
4bf69007
AM
24000 goto found;
24001 }
24002 sk = NULL;
f973f73f 24003@@ -957,7 +977,8 @@ static struct sock *raw_get_next(struct
4bf69007
AM
24004 sk = sk_next(sk);
24005 try_again:
24006 ;
24007- } while (sk && sock_net(sk) != seq_file_net(seq));
24008+ } while (sk && ((sock_net(sk) != seq_file_net(seq)) ||
24009+ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
24010
24011 if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
24012 sk = sk_head(&state->h->ht[state->bucket]);
f973f73f
AM
24013diff -NurpP --minimal linux-4.1.27/net/ipv4/route.c linux-4.1.27-vs2.3.8.5.2/net/ipv4/route.c
24014--- linux-4.1.27/net/ipv4/route.c 2016-07-05 04:28:33.000000000 +0000
24015+++ linux-4.1.27-vs2.3.8.5.2/net/ipv4/route.c 2016-07-05 04:41:47.000000000 +0000
24016@@ -2136,7 +2136,7 @@ struct rtable *__ip_route_output_key(str
4bf69007
AM
24017
24018
24019 if (fl4->flowi4_oif) {
24020- dev_out = dev_get_by_index_rcu(net, fl4->flowi4_oif);
24021+ dev_out = dev_get_by_index_real_rcu(net, fl4->flowi4_oif);
24022 rth = ERR_PTR(-ENODEV);
5eef5607 24023 if (!dev_out)
4bf69007 24024 goto out;
f973f73f
AM
24025diff -NurpP --minimal linux-4.1.27/net/ipv4/tcp.c linux-4.1.27-vs2.3.8.5.2/net/ipv4/tcp.c
24026--- linux-4.1.27/net/ipv4/tcp.c 2016-07-05 04:28:33.000000000 +0000
24027+++ linux-4.1.27-vs2.3.8.5.2/net/ipv4/tcp.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 24028@@ -269,6 +269,7 @@
4bf69007
AM
24029 #include <linux/crypto.h>
24030 #include <linux/time.h>
24031 #include <linux/slab.h>
24032+#include <linux/in.h>
24033
24034 #include <net/icmp.h>
24035 #include <net/inet_common.h>
f973f73f
AM
24036diff -NurpP --minimal linux-4.1.27/net/ipv4/tcp_ipv4.c linux-4.1.27-vs2.3.8.5.2/net/ipv4/tcp_ipv4.c
24037--- linux-4.1.27/net/ipv4/tcp_ipv4.c 2016-07-05 04:28:33.000000000 +0000
24038+++ linux-4.1.27-vs2.3.8.5.2/net/ipv4/tcp_ipv4.c 2016-07-05 04:41:47.000000000 +0000
24039@@ -1846,6 +1846,12 @@ static void *listening_get_next(struct s
4bf69007
AM
24040 req = req->dl_next;
24041 while (1) {
24042 while (req) {
24043+ vxdprintk(VXD_CBIT(net, 6),
24044+ "sk,req: %p [#%d] (from %d)", req->sk,
24045+ (req->sk)?req->sk->sk_nid:0, nx_current_nid());
24046+ if (req->sk &&
24047+ !nx_check(req->sk->sk_nid, VS_WATCH_P | VS_IDENT))
24048+ continue;
24049 if (req->rsk_ops->family == st->family) {
24050 cur = req;
24051 goto out;
f973f73f 24052@@ -1870,6 +1876,10 @@ get_req:
4bf69007
AM
24053 }
24054 get_sk:
24055 sk_nulls_for_each_from(sk, node) {
24056+ vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
24057+ sk, sk->sk_nid, nx_current_nid());
24058+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24059+ continue;
24060 if (!net_eq(sock_net(sk), net))
24061 continue;
24062 if (sk->sk_family == st->family) {
f973f73f 24063@@ -1944,6 +1954,11 @@ static void *established_get_first(struc
4bf69007
AM
24064
24065 spin_lock_bh(lock);
24066 sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
24067+ vxdprintk(VXD_CBIT(net, 6),
24068+ "sk,egf: %p [#%d] (from %d)",
24069+ sk, sk->sk_nid, nx_current_nid());
24070+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24071+ continue;
24072 if (sk->sk_family != st->family ||
24073 !net_eq(sock_net(sk), net)) {
24074 continue;
f973f73f 24075@@ -1970,6 +1985,11 @@ static void *established_get_next(struct
c2e5f7c8 24076 sk = sk_nulls_next(sk);
4bf69007
AM
24077
24078 sk_nulls_for_each_from(sk, node) {
24079+ vxdprintk(VXD_CBIT(net, 6),
24080+ "sk,egn: %p [#%d] (from %d)",
24081+ sk, sk->sk_nid, nx_current_nid());
24082+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24083+ continue;
24084 if (sk->sk_family == st->family && net_eq(sock_net(sk), net))
c2e5f7c8 24085 return sk;
4bf69007 24086 }
f973f73f 24087@@ -2168,9 +2188,9 @@ static void get_openreq4(const struct re
4bf69007 24088 seq_printf(f, "%4d: %08X:%04X %08X:%04X"
c2e5f7c8 24089 " %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK",
4bf69007 24090 i,
c2e5f7c8
JR
24091- ireq->ir_loc_addr,
24092+ nx_map_sock_lback(current_nx_info(), ireq->ir_loc_addr),
5eef5607 24093 ireq->ir_num,
c2e5f7c8
JR
24094- ireq->ir_rmt_addr,
24095+ nx_map_sock_lback(current_nx_info(), ireq->ir_rmt_addr),
24096 ntohs(ireq->ir_rmt_port),
4bf69007
AM
24097 TCP_SYN_RECV,
24098 0, 0, /* could print option size, but that is af dependent. */
f973f73f 24099@@ -2192,8 +2212,8 @@ static void get_tcp4_sock(struct sock *s
4bf69007
AM
24100 const struct inet_connection_sock *icsk = inet_csk(sk);
24101 const struct inet_sock *inet = inet_sk(sk);
24102 struct fastopen_queue *fastopenq = icsk->icsk_accept_queue.fastopenq;
24103- __be32 dest = inet->inet_daddr;
24104- __be32 src = inet->inet_rcv_saddr;
24105+ __be32 dest = nx_map_sock_lback(current_nx_info(), inet->inet_daddr);
24106+ __be32 src = nx_map_sock_lback(current_nx_info(), inet->inet_rcv_saddr);
24107 __u16 destp = ntohs(inet->inet_dport);
24108 __u16 srcp = ntohs(inet->inet_sport);
24109 int rx_queue;
f973f73f 24110@@ -2250,8 +2270,8 @@ static void get_timewait4_sock(const str
5eef5607 24111 __be32 dest, src;
4bf69007 24112 __u16 destp, srcp;
4bf69007
AM
24113
24114- dest = tw->tw_daddr;
24115- src = tw->tw_rcv_saddr;
24116+ dest = nx_map_sock_lback(current_nx_info(), tw->tw_daddr);
24117+ src = nx_map_sock_lback(current_nx_info(), tw->tw_rcv_saddr);
24118 destp = ntohs(tw->tw_dport);
24119 srcp = ntohs(tw->tw_sport);
24120
f973f73f
AM
24121diff -NurpP --minimal linux-4.1.27/net/ipv4/tcp_minisocks.c linux-4.1.27-vs2.3.8.5.2/net/ipv4/tcp_minisocks.c
24122--- linux-4.1.27/net/ipv4/tcp_minisocks.c 2016-07-05 04:28:33.000000000 +0000
24123+++ linux-4.1.27-vs2.3.8.5.2/net/ipv4/tcp_minisocks.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
24124@@ -23,6 +23,9 @@
24125 #include <linux/slab.h>
24126 #include <linux/sysctl.h>
24127 #include <linux/workqueue.h>
24128+#include <linux/vs_limit.h>
24129+#include <linux/vs_socket.h>
24130+#include <linux/vs_context.h>
24131 #include <net/tcp.h>
24132 #include <net/inet_common.h>
24133 #include <net/xfrm.h>
5eef5607 24134@@ -293,6 +296,11 @@ void tcp_time_wait(struct sock *sk, int
b00e13aa 24135 tcptw->tw_ts_offset = tp->tsoffset;
5eef5607 24136 tcptw->tw_last_oow_ack_time = 0;
4bf69007
AM
24137
24138+ tw->tw_xid = sk->sk_xid;
24139+ tw->tw_vx_info = NULL;
24140+ tw->tw_nid = sk->sk_nid;
24141+ tw->tw_nx_info = NULL;
2ba6f0dd 24142+
4bf69007
AM
24143 #if IS_ENABLED(CONFIG_IPV6)
24144 if (tw->tw_family == PF_INET6) {
24145 struct ipv6_pinfo *np = inet6_sk(sk);
f973f73f
AM
24146diff -NurpP --minimal linux-4.1.27/net/ipv4/udp.c linux-4.1.27-vs2.3.8.5.2/net/ipv4/udp.c
24147--- linux-4.1.27/net/ipv4/udp.c 2016-07-05 04:28:33.000000000 +0000
24148+++ linux-4.1.27-vs2.3.8.5.2/net/ipv4/udp.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 24149@@ -310,14 +310,7 @@ fail:
4bf69007
AM
24150 }
24151 EXPORT_SYMBOL(udp_lib_get_port);
24152
24153-static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
24154-{
24155- struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
24156-
24157- return (!ipv6_only_sock(sk2) &&
24158- (!inet1->inet_rcv_saddr || !inet2->inet_rcv_saddr ||
24159- inet1->inet_rcv_saddr == inet2->inet_rcv_saddr));
24160-}
24161+extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *);
24162
5eef5607
AM
24163 static u32 udp4_portaddr_hash(const struct net *net, __be32 saddr,
24164 unsigned int port)
24165@@ -356,6 +349,11 @@ static inline int compute_score(struct s
24166 if (inet->inet_rcv_saddr != daddr)
24167 return -1;
24168 score += 4;
4bf69007
AM
24169+ } else {
24170+ /* block non nx_info ips */
24171+ if (!v4_addr_in_nx_info(sk->sk_nx_info,
24172+ daddr, NXA_MASK_BIND))
24173+ return -1;
5eef5607
AM
24174 }
24175
24176 if (inet->inet_daddr) {
24177@@ -486,6 +484,7 @@ begin:
4bf69007
AM
24178 return result;
24179 }
24180
2ba6f0dd 24181+
4bf69007
AM
24182 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
24183 * harder than this. -DaveM
24184 */
5eef5607 24185@@ -532,6 +531,11 @@ begin:
4bf69007
AM
24186 sk_nulls_for_each_rcu(sk, node, &hslot->head) {
24187 score = compute_score(sk, net, saddr, hnum, sport,
24188 daddr, dport, dif);
24189+ /* FIXME: disabled?
24190+ if (score == 9) {
24191+ result = sk;
24192+ break;
24193+ } else */
24194 if (score > badness) {
24195 result = sk;
24196 badness = score;
5eef5607 24197@@ -556,6 +560,7 @@ begin:
4bf69007
AM
24198 if (get_nulls_value(node) != slot)
24199 goto begin;
24200
2ba6f0dd 24201+
4bf69007
AM
24202 if (result) {
24203 if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
24204 result = NULL;
5eef5607 24205@@ -565,6 +570,7 @@ begin:
4bf69007
AM
24206 goto begin;
24207 }
24208 }
2ba6f0dd 24209+
4bf69007
AM
24210 rcu_read_unlock();
24211 return result;
24212 }
5eef5607 24213@@ -599,7 +605,7 @@ static inline bool __udp_is_mcast_sock(s
c2e5f7c8
JR
24214 udp_sk(sk)->udp_port_hash != hnum ||
24215 (inet->inet_daddr && inet->inet_daddr != rmt_addr) ||
24216 (inet->inet_dport != rmt_port && inet->inet_dport) ||
24217- (inet->inet_rcv_saddr && inet->inet_rcv_saddr != loc_addr) ||
24218+ !v4_sock_addr_match(sk->sk_nx_info, inet, loc_addr) ||
24219 ipv6_only_sock(sk) ||
24220 (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
24221 return false;
f973f73f 24222@@ -1022,6 +1028,16 @@ int udp_sendmsg(struct sock *sk, struct
bb20add7 24223 inet_sk_flowi_flags(sk),
4bf69007
AM
24224 faddr, saddr, dport, inet->inet_sport);
24225
24226+ if (sk->sk_nx_info) {
24227+ rt = ip_v4_find_src(net, sk->sk_nx_info, fl4);
24228+ if (IS_ERR(rt)) {
24229+ err = PTR_ERR(rt);
24230+ rt = NULL;
24231+ goto out;
24232+ }
24233+ ip_rt_put(rt);
24234+ }
2ba6f0dd 24235+
4bf69007
AM
24236 security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
24237 rt = ip_route_output_flow(net, fl4, sk);
24238 if (IS_ERR(rt)) {
f973f73f 24239@@ -1324,7 +1340,8 @@ try_again:
4bf69007
AM
24240 if (sin) {
24241 sin->sin_family = AF_INET;
24242 sin->sin_port = udp_hdr(skb)->source;
24243- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
24244+ sin->sin_addr.s_addr = nx_map_sock_lback(
24245+ skb->sk->sk_nx_info, ip_hdr(skb)->saddr);
24246 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
c2e5f7c8 24247 *addr_len = sizeof(*sin);
4bf69007 24248 }
f973f73f 24249@@ -2302,6 +2319,8 @@ static struct sock *udp_get_first(struct
4bf69007
AM
24250 sk_nulls_for_each(sk, node, &hslot->head) {
24251 if (!net_eq(sock_net(sk), net))
24252 continue;
24253+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24254+ continue;
24255 if (sk->sk_family == state->family)
24256 goto found;
24257 }
f973f73f 24258@@ -2319,7 +2338,9 @@ static struct sock *udp_get_next(struct
4bf69007
AM
24259
24260 do {
24261 sk = sk_nulls_next(sk);
24262- } while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != state->family));
24263+ } while (sk && (!net_eq(sock_net(sk), net) ||
24264+ sk->sk_family != state->family ||
24265+ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
24266
24267 if (!sk) {
24268 if (state->bucket <= state->udp_table->mask)
f973f73f 24269@@ -2415,8 +2436,8 @@ static void udp4_format_sock(struct sock
c2e5f7c8 24270 int bucket)
4bf69007
AM
24271 {
24272 struct inet_sock *inet = inet_sk(sp);
24273- __be32 dest = inet->inet_daddr;
24274- __be32 src = inet->inet_rcv_saddr;
24275+ __be32 dest = nx_map_sock_lback(current_nx_info(), inet->inet_daddr);
24276+ __be32 src = nx_map_sock_lback(current_nx_info(), inet->inet_rcv_saddr);
24277 __u16 destp = ntohs(inet->inet_dport);
24278 __u16 srcp = ntohs(inet->inet_sport);
24279
f973f73f
AM
24280diff -NurpP --minimal linux-4.1.27/net/ipv6/Kconfig linux-4.1.27-vs2.3.8.5.2/net/ipv6/Kconfig
24281--- linux-4.1.27/net/ipv6/Kconfig 2015-04-12 22:12:50.000000000 +0000
24282+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/Kconfig 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
24283@@ -4,8 +4,8 @@
24284
24285 # IPv6 as module will cause a CRASH if you try to unload it
24286 menuconfig IPV6
24287- tristate "The IPv6 protocol"
24288- default m
24289+ bool "The IPv6 protocol"
24290+ default n
24291 ---help---
24292 This is complemental support for the IP version 6.
24293 You will still be able to do traditional IPv4 networking as well.
f973f73f
AM
24294diff -NurpP --minimal linux-4.1.27/net/ipv6/addrconf.c linux-4.1.27-vs2.3.8.5.2/net/ipv6/addrconf.c
24295--- linux-4.1.27/net/ipv6/addrconf.c 2016-07-05 04:28:33.000000000 +0000
24296+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/addrconf.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 24297@@ -91,6 +91,8 @@
4bf69007
AM
24298 #include <linux/proc_fs.h>
24299 #include <linux/seq_file.h>
24300 #include <linux/export.h>
24301+#include <linux/vs_network.h>
24302+#include <linux/vs_inet6.h>
24303
24304 /* Set to 3 to get tracing... */
24305 #define ACONF_DEBUG 2
f973f73f 24306@@ -1369,7 +1371,7 @@ out:
4bf69007
AM
24307
24308 int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
24309 const struct in6_addr *daddr, unsigned int prefs,
24310- struct in6_addr *saddr)
24311+ struct in6_addr *saddr, struct nx_info *nxi)
24312 {
24313 struct ipv6_saddr_score scores[2],
24314 *score = &scores[0], *hiscore = &scores[1];
f973f73f 24315@@ -1439,6 +1441,8 @@ int ipv6_dev_get_saddr(struct net *net,
5eef5607 24316 dev->name);
4bf69007
AM
24317 continue;
24318 }
24319+ if (!v6_addr_in_nx_info(nxi, &score->ifa->addr, -1))
24320+ continue;
24321
24322 score->rule = -1;
24323 bitmap_zero(score->scorebits, IPV6_SADDR_RULE_MAX);
f973f73f 24324@@ -3753,7 +3757,10 @@ static void if6_seq_stop(struct seq_file
4bf69007
AM
24325 static int if6_seq_show(struct seq_file *seq, void *v)
24326 {
24327 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
24328- seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
2ba6f0dd 24329+
4bf69007
AM
24330+ if (nx_check(0, VS_ADMIN|VS_WATCH) ||
24331+ v6_addr_in_nx_info(current_nx_info(), &ifp->addr, -1))
24332+ seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
24333 &ifp->addr,
24334 ifp->idev->dev->ifindex,
24335 ifp->prefix_len,
f973f73f 24336@@ -4337,6 +4344,11 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
24337 struct ifacaddr6 *ifaca;
24338 int err = 1;
24339 int ip_idx = *p_ip_idx;
24340+ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
2ba6f0dd 24341+
4bf69007
AM
24342+ /* disable ipv6 on non v6 guests */
24343+ if (nxi && !nx_info_has_v6(nxi))
24344+ return skb->len;
24345
24346 read_lock_bh(&idev->lock);
24347 switch (type) {
f973f73f 24348@@ -4347,6 +4359,8 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
24349 list_for_each_entry(ifa, &idev->addr_list, if_list) {
24350 if (++ip_idx < s_ip_idx)
24351 continue;
24352+ if (!v6_addr_in_nx_info(nxi, &ifa->addr, -1))
24353+ continue;
24354 err = inet6_fill_ifaddr(skb, ifa,
24355 NETLINK_CB(cb->skb).portid,
24356 cb->nlh->nlmsg_seq,
f973f73f 24357@@ -4364,6 +4378,8 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
24358 ifmca = ifmca->next, ip_idx++) {
24359 if (ip_idx < s_ip_idx)
24360 continue;
24361+ if (!v6_addr_in_nx_info(nxi, &ifmca->mca_addr, -1))
24362+ continue;
24363 err = inet6_fill_ifmcaddr(skb, ifmca,
24364 NETLINK_CB(cb->skb).portid,
24365 cb->nlh->nlmsg_seq,
f973f73f 24366@@ -4379,6 +4395,8 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
24367 ifaca = ifaca->aca_next, ip_idx++) {
24368 if (ip_idx < s_ip_idx)
24369 continue;
24370+ if (!v6_addr_in_nx_info(nxi, &ifaca->aca_addr, -1))
24371+ continue;
24372 err = inet6_fill_ifacaddr(skb, ifaca,
24373 NETLINK_CB(cb->skb).portid,
24374 cb->nlh->nlmsg_seq,
f973f73f 24375@@ -4407,6 +4425,10 @@ static int inet6_dump_addr(struct sk_buf
4bf69007
AM
24376 struct inet6_dev *idev;
24377 struct hlist_head *head;
b00e13aa 24378
4bf69007
AM
24379+ /* FIXME: maybe disable ipv6 on non v6 guests?
24380+ if (skb->sk && skb->sk->sk_vx_info)
24381+ return skb->len; */
b00e13aa
AM
24382+
24383 s_h = cb->args[0];
24384 s_idx = idx = cb->args[1];
24385 s_ip_idx = ip_idx = cb->args[2];
f973f73f 24386@@ -4898,6 +4920,7 @@ static int inet6_dump_ifinfo(struct sk_b
b00e13aa
AM
24387 struct net_device *dev;
24388 struct inet6_dev *idev;
24389 struct hlist_head *head;
24390+ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
4bf69007
AM
24391
24392 s_h = cb->args[0];
24393 s_idx = cb->args[1];
f973f73f 24394@@ -4909,6 +4932,8 @@ static int inet6_dump_ifinfo(struct sk_b
b00e13aa 24395 hlist_for_each_entry_rcu(dev, head, index_hlist) {
4bf69007
AM
24396 if (idx < s_idx)
24397 goto cont;
24398+ if (!v6_dev_in_nx_info(dev, nxi))
24399+ goto cont;
24400 idev = __in6_dev_get(dev);
24401 if (!idev)
24402 goto cont;
f973f73f
AM
24403diff -NurpP --minimal linux-4.1.27/net/ipv6/af_inet6.c linux-4.1.27-vs2.3.8.5.2/net/ipv6/af_inet6.c
24404--- linux-4.1.27/net/ipv6/af_inet6.c 2016-07-05 04:28:33.000000000 +0000
24405+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/af_inet6.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
24406@@ -43,6 +43,8 @@
24407 #include <linux/netdevice.h>
24408 #include <linux/icmpv6.h>
24409 #include <linux/netfilter_ipv6.h>
24410+#include <linux/vs_inet.h>
24411+#include <linux/vs_inet6.h>
24412
24413 #include <net/ip.h>
24414 #include <net/ipv6.h>
9e3e8383 24415@@ -158,10 +160,13 @@ lookup_protocol:
4bf69007
AM
24416 }
24417
24418 err = -EPERM;
24419+ if ((protocol == IPPROTO_ICMPV6) &&
24420+ nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
24421+ goto override;
b00e13aa
AM
24422 if (sock->type == SOCK_RAW && !kern &&
24423 !ns_capable(net->user_ns, CAP_NET_RAW))
4bf69007
AM
24424 goto out_rcu_unlock;
24425-
24426+override:
24427 sock->ops = answer->ops;
24428 answer_prot = answer->prot;
bb20add7 24429 answer_flags = answer->flags;
9e3e8383 24430@@ -259,6 +264,7 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24431 struct inet_sock *inet = inet_sk(sk);
24432 struct ipv6_pinfo *np = inet6_sk(sk);
24433 struct net *net = sock_net(sk);
24434+ struct nx_v6_sock_addr nsa;
24435 __be32 v4addr = 0;
24436 unsigned short snum;
24437 int addr_type = 0;
9e3e8383 24438@@ -274,6 +280,10 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24439 if (addr->sin6_family != AF_INET6)
24440 return -EAFNOSUPPORT;
24441
24442+ err = v6_map_sock_addr(inet, addr, &nsa);
24443+ if (err)
24444+ return err;
2ba6f0dd 24445+
4bf69007
AM
24446 addr_type = ipv6_addr_type(&addr->sin6_addr);
24447 if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
24448 return -EINVAL;
9e3e8383 24449@@ -314,6 +324,10 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24450 err = -EADDRNOTAVAIL;
24451 goto out;
24452 }
24453+ if (!v4_addr_in_nx_info(sk->sk_nx_info, v4addr, NXA_MASK_BIND)) {
24454+ err = -EADDRNOTAVAIL;
24455+ goto out;
24456+ }
24457 } else {
24458 if (addr_type != IPV6_ADDR_ANY) {
24459 struct net_device *dev = NULL;
9e3e8383 24460@@ -340,6 +354,11 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24461 }
24462 }
24463
24464+ if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
24465+ err = -EADDRNOTAVAIL;
24466+ goto out_unlock;
24467+ }
2ba6f0dd 24468+
4bf69007
AM
24469 /* ipv4 addr of the socket is invalid. Only the
24470 * unspecified and mapped address have a v4 equivalent.
24471 */
9e3e8383 24472@@ -356,6 +375,9 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24473 }
24474 }
24475
24476+ /* what's that for? */
24477+ v6_set_sock_addr(inet, &nsa);
2ba6f0dd 24478+
4bf69007
AM
24479 inet->inet_rcv_saddr = v4addr;
24480 inet->inet_saddr = v4addr;
24481
9e3e8383 24482@@ -459,9 +481,11 @@ int inet6_getname(struct socket *sock, s
4bf69007
AM
24483 return -ENOTCONN;
24484 sin->sin6_port = inet->inet_dport;
c2e5f7c8 24485 sin->sin6_addr = sk->sk_v6_daddr;
4bf69007
AM
24486+ /* FIXME: remap lback? */
24487 if (np->sndflow)
24488 sin->sin6_flowinfo = np->flow_label;
24489 } else {
24490+ /* FIXME: remap lback? */
c2e5f7c8 24491 if (ipv6_addr_any(&sk->sk_v6_rcv_saddr))
4bf69007
AM
24492 sin->sin6_addr = np->saddr;
24493 else
f973f73f
AM
24494diff -NurpP --minimal linux-4.1.27/net/ipv6/datagram.c linux-4.1.27-vs2.3.8.5.2/net/ipv6/datagram.c
24495--- linux-4.1.27/net/ipv6/datagram.c 2016-07-05 04:28:33.000000000 +0000
24496+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/datagram.c 2016-07-05 04:41:47.000000000 +0000
24497@@ -729,7 +729,7 @@ int ip6_datagram_send_ctl(struct net *ne
4bf69007
AM
24498
24499 rcu_read_lock();
24500 if (fl6->flowi6_oif) {
24501- dev = dev_get_by_index_rcu(net, fl6->flowi6_oif);
24502+ dev = dev_get_by_index_real_rcu(net, fl6->flowi6_oif);
24503 if (!dev) {
24504 rcu_read_unlock();
24505 return -ENODEV;
f973f73f
AM
24506diff -NurpP --minimal linux-4.1.27/net/ipv6/fib6_rules.c linux-4.1.27-vs2.3.8.5.2/net/ipv6/fib6_rules.c
24507--- linux-4.1.27/net/ipv6/fib6_rules.c 2015-07-06 20:41:43.000000000 +0000
24508+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/fib6_rules.c 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 24509@@ -97,7 +97,7 @@ static int fib6_rule_action(struct fib_r
4bf69007
AM
24510 ip6_dst_idev(&rt->dst)->dev,
24511 &flp6->daddr,
24512 rt6_flags2srcprefs(flags),
24513- &saddr))
24514+ &saddr, NULL))
24515 goto again;
24516 if (!ipv6_prefix_equal(&saddr, &r->src.addr,
24517 r->src.plen))
f973f73f
AM
24518diff -NurpP --minimal linux-4.1.27/net/ipv6/inet6_hashtables.c linux-4.1.27-vs2.3.8.5.2/net/ipv6/inet6_hashtables.c
24519--- linux-4.1.27/net/ipv6/inet6_hashtables.c 2015-07-06 20:41:43.000000000 +0000
24520+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/inet6_hashtables.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
24521@@ -16,6 +16,7 @@
24522
24523 #include <linux/module.h>
24524 #include <linux/random.h>
24525+#include <linux/vs_inet6.h>
24526
24527 #include <net/inet_connection_sock.h>
24528 #include <net/inet_hashtables.h>
5eef5607 24529@@ -66,7 +67,6 @@ struct sock *__inet6_lookup_established(
4bf69007
AM
24530 unsigned int slot = hash & hashinfo->ehash_mask;
24531 struct inet_ehash_bucket *head = &hashinfo->ehash[slot];
24532
24533-
24534 rcu_read_lock();
24535 begin:
24536 sk_nulls_for_each_rcu(sk, node, &head->chain) {
5eef5607 24537@@ -108,6 +108,9 @@ static inline int compute_score(struct s
c2e5f7c8 24538 if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))
4bf69007
AM
24539 return -1;
24540 score++;
24541+ } else {
24542+ if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
24543+ return -1;
24544 }
24545 if (sk->sk_bound_dev_if) {
24546 if (sk->sk_bound_dev_if != dif)
f973f73f
AM
24547diff -NurpP --minimal linux-4.1.27/net/ipv6/ip6_fib.c linux-4.1.27-vs2.3.8.5.2/net/ipv6/ip6_fib.c
24548--- linux-4.1.27/net/ipv6/ip6_fib.c 2015-07-06 20:41:43.000000000 +0000
24549+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/ip6_fib.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 24550@@ -1888,6 +1888,7 @@ static int ipv6_route_seq_show(struct se
c2e5f7c8
JR
24551 struct rt6_info *rt = v;
24552 struct ipv6_route_iter *iter = seq->private;
24553
24554+ /* FIXME: check for network context? */
24555 seq_printf(seq, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen);
24556
24557 #ifdef CONFIG_IPV6_SUBTREES
f973f73f
AM
24558diff -NurpP --minimal linux-4.1.27/net/ipv6/ip6_output.c linux-4.1.27-vs2.3.8.5.2/net/ipv6/ip6_output.c
24559--- linux-4.1.27/net/ipv6/ip6_output.c 2016-07-05 04:28:33.000000000 +0000
24560+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/ip6_output.c 2016-07-05 04:41:47.000000000 +0000
24561@@ -908,7 +908,8 @@ static int ip6_dst_lookup_tail(struct so
5eef5607 24562 rt = (*dst)->error ? NULL : (struct rt6_info *)*dst;
4bf69007
AM
24563 err = ip6_route_get_saddr(net, rt, &fl6->daddr,
24564 sk ? inet6_sk(sk)->srcprefs : 0,
24565- &fl6->saddr);
24566+ &fl6->saddr,
24567+ sk ? sk->sk_nx_info : NULL);
24568 if (err)
24569 goto out_err_release;
5eef5607 24570
f973f73f
AM
24571diff -NurpP --minimal linux-4.1.27/net/ipv6/ndisc.c linux-4.1.27-vs2.3.8.5.2/net/ipv6/ndisc.c
24572--- linux-4.1.27/net/ipv6/ndisc.c 2016-07-05 04:28:33.000000000 +0000
24573+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/ndisc.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 24574@@ -497,7 +497,7 @@ void ndisc_send_na(struct net_device *de
4bf69007
AM
24575 } else {
24576 if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
24577 inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
24578- &tmpaddr))
24579+ &tmpaddr, NULL))
24580 return;
24581 src_addr = &tmpaddr;
24582 }
f973f73f
AM
24583diff -NurpP --minimal linux-4.1.27/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c linux-4.1.27-vs2.3.8.5.2/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c
24584--- linux-4.1.27/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c 2015-04-12 22:12:50.000000000 +0000
24585+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 24586@@ -35,7 +35,7 @@ nf_nat_masquerade_ipv6(struct sk_buff *s
4bf69007
AM
24587 ctinfo == IP_CT_RELATED_REPLY));
24588
bb20add7 24589 if (ipv6_dev_get_saddr(dev_net(out), out,
4bf69007
AM
24590- &ipv6_hdr(skb)->daddr, 0, &src) < 0)
24591+ &ipv6_hdr(skb)->daddr, 0, &src, NULL) < 0)
24592 return NF_DROP;
24593
bb20add7 24594 nfct_nat(ct)->masq_index = out->ifindex;
f973f73f
AM
24595diff -NurpP --minimal linux-4.1.27/net/ipv6/raw.c linux-4.1.27-vs2.3.8.5.2/net/ipv6/raw.c
24596--- linux-4.1.27/net/ipv6/raw.c 2016-07-05 04:28:33.000000000 +0000
24597+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/raw.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
24598@@ -30,6 +30,7 @@
24599 #include <linux/icmpv6.h>
24600 #include <linux/netfilter.h>
24601 #include <linux/netfilter_ipv6.h>
24602+#include <linux/vs_inet6.h>
24603 #include <linux/skbuff.h>
24604 #include <linux/compat.h>
5eef5607 24605 #include <linux/uaccess.h>
bb20add7 24606@@ -291,6 +292,13 @@ static int rawv6_bind(struct sock *sk, s
4bf69007
AM
24607 goto out_unlock;
24608 }
24609
24610+ if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
24611+ err = -EADDRNOTAVAIL;
24612+ if (dev)
24613+ dev_put(dev);
24614+ goto out;
24615+ }
2ba6f0dd 24616+
4bf69007
AM
24617 /* ipv4 addr of the socket is invalid. Only the
24618 * unspecified and mapped address have a v4 equivalent.
24619 */
f973f73f
AM
24620diff -NurpP --minimal linux-4.1.27/net/ipv6/route.c linux-4.1.27-vs2.3.8.5.2/net/ipv6/route.c
24621--- linux-4.1.27/net/ipv6/route.c 2016-07-05 04:28:33.000000000 +0000
24622+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/route.c 2016-07-05 04:41:47.000000000 +0000
b00e13aa 24623@@ -58,6 +58,7 @@
4bf69007
AM
24624 #include <net/netevent.h>
24625 #include <net/netlink.h>
b00e13aa 24626 #include <net/nexthop.h>
4bf69007
AM
24627+#include <linux/vs_inet6.h>
24628
24629 #include <asm/uaccess.h>
24630
f973f73f 24631@@ -2264,16 +2265,18 @@ int ip6_route_get_saddr(struct net *net,
4bf69007
AM
24632 struct rt6_info *rt,
24633 const struct in6_addr *daddr,
24634 unsigned int prefs,
24635- struct in6_addr *saddr)
24636+ struct in6_addr *saddr,
24637+ struct nx_info *nxi)
24638 {
5eef5607
AM
24639 struct inet6_dev *idev =
24640 rt ? ip6_dst_idev((struct dst_entry *)rt) : NULL;
4bf69007 24641 int err = 0;
5eef5607
AM
24642- if (rt && rt->rt6i_prefsrc.plen)
24643+ if (rt && rt->rt6i_prefsrc.plen && (!nxi ||
4bf69007
AM
24644+ v6_addr_in_nx_info(nxi, &rt->rt6i_prefsrc.addr, NXA_TYPE_ADDR)))
24645 *saddr = rt->rt6i_prefsrc.addr;
24646 else
24647 err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
24648- daddr, prefs, saddr);
24649+ daddr, prefs, saddr, nxi);
24650 return err;
24651 }
24652
f973f73f 24653@@ -2856,7 +2859,8 @@ static int rt6_fill_node(struct net *net
4bf69007
AM
24654 goto nla_put_failure;
24655 } else if (dst) {
24656 struct in6_addr saddr_buf;
24657- if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0 &&
24658+ if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf,
24659+ (skb->sk ? skb->sk->sk_nx_info : NULL)) == 0 &&
5eef5607 24660 nla_put_in6_addr(skb, RTA_PREFSRC, &saddr_buf))
4bf69007
AM
24661 goto nla_put_failure;
24662 }
f973f73f
AM
24663diff -NurpP --minimal linux-4.1.27/net/ipv6/tcp_ipv6.c linux-4.1.27-vs2.3.8.5.2/net/ipv6/tcp_ipv6.c
24664--- linux-4.1.27/net/ipv6/tcp_ipv6.c 2016-07-05 04:28:33.000000000 +0000
24665+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/tcp_ipv6.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 24666@@ -69,6 +69,7 @@
4bf69007
AM
24667
24668 #include <linux/crypto.h>
24669 #include <linux/scatterlist.h>
24670+#include <linux/vs_inet6.h>
24671
24672 static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
24673 static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
5eef5607 24674@@ -151,8 +152,15 @@ static int tcp_v6_connect(struct sock *s
4bf69007
AM
24675 * connect() to INADDR_ANY means loopback (BSD'ism).
24676 */
24677
f15949f2 24678- if (ipv6_addr_any(&usin->sin6_addr))
4bf69007 24679- usin->sin6_addr.s6_addr[15] = 0x1;
bb20add7 24680+ if(ipv6_addr_any(&usin->sin6_addr)) {
4bf69007 24681+ struct nx_info *nxi = sk->sk_nx_info;
2ba6f0dd 24682+
4bf69007
AM
24683+ if (nxi && nx_info_has_v6(nxi))
24684+ /* FIXME: remap lback? */
24685+ usin->sin6_addr = nxi->v6.ip;
24686+ else
24687+ usin->sin6_addr.s6_addr[15] = 0x1;
24688+ }
24689
24690 addr_type = ipv6_addr_type(&usin->sin6_addr);
24691
f973f73f
AM
24692diff -NurpP --minimal linux-4.1.27/net/ipv6/udp.c linux-4.1.27-vs2.3.8.5.2/net/ipv6/udp.c
24693--- linux-4.1.27/net/ipv6/udp.c 2016-07-05 04:28:33.000000000 +0000
24694+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/udp.c 2016-07-05 04:41:47.000000000 +0000
c2e5f7c8 24695@@ -47,6 +47,7 @@
4bf69007 24696 #include <net/xfrm.h>
b00e13aa 24697 #include <net/inet6_hashtables.h>
c2e5f7c8 24698 #include <net/busy_poll.h>
4bf69007
AM
24699+#include <linux/vs_inet6.h>
24700
24701 #include <linux/proc_fs.h>
24702 #include <linux/seq_file.h>
5eef5607
AM
24703@@ -76,32 +77,60 @@ static u32 udp6_ehashfn(const struct net
24704 udp_ipv6_hash_secret + net_hash_mix(net));
24705 }
24706
24707-int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
24708+int ipv6_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
24709 {
24710+ const struct in6_addr *sk1_rcv_saddr6 = inet6_rcv_saddr(sk1);
24711 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
24712+ __be32 sk1_rcv_saddr = sk1->sk_rcv_saddr;
24713+ __be32 sk2_rcv_saddr = sk2->sk_rcv_saddr;
24714 int sk2_ipv6only = inet_v6_ipv6only(sk2);
24715- int addr_type = ipv6_addr_type(&sk->sk_v6_rcv_saddr);
24716+ int addr_type1 = ipv6_addr_type(sk1_rcv_saddr6);
24717 int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED;
24718
24719 /* if both are mapped, treat as IPv4 */
24720- if (addr_type == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED)
24721- return (!sk2_ipv6only &&
24722- (!sk->sk_rcv_saddr || !sk2->sk_rcv_saddr ||
24723- sk->sk_rcv_saddr == sk2->sk_rcv_saddr));
24724+ if (addr_type1 == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED) {
24725+ if (!sk2_ipv6only &&
24726+ (!sk1->sk_rcv_saddr || !sk2->sk_rcv_saddr ||
24727+ sk1->sk_rcv_saddr == sk2->sk_rcv_saddr))
24728+ goto vs_v4;
24729+ else
24730+ return 0;
24731+ }
24732
24733 if (addr_type2 == IPV6_ADDR_ANY &&
24734- !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED))
24735- return 1;
24736+ !(sk2_ipv6only && addr_type1 == IPV6_ADDR_MAPPED))
24737+ goto vs;
24738
24739- if (addr_type == IPV6_ADDR_ANY &&
24740- !(ipv6_only_sock(sk) && addr_type2 == IPV6_ADDR_MAPPED))
24741- return 1;
24742+ if (addr_type1 == IPV6_ADDR_ANY &&
24743+ !(ipv6_only_sock(sk1) && addr_type2 == IPV6_ADDR_MAPPED))
24744+ goto vs;
24745
24746 if (sk2_rcv_saddr6 &&
24747- ipv6_addr_equal(&sk->sk_v6_rcv_saddr, sk2_rcv_saddr6))
24748- return 1;
24749+ ipv6_addr_equal(&sk1->sk_v6_rcv_saddr, sk2_rcv_saddr6))
24750+ goto vs;
24751
24752 return 0;
24753+
24754+vs_v4:
24755+ if (!sk1_rcv_saddr && !sk2_rcv_saddr)
24756+ return nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24757+ if (!sk2_rcv_saddr)
24758+ return v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, -1);
24759+ if (!sk1_rcv_saddr)
24760+ return v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, -1);
24761+ return 1;
24762+vs:
24763+ if (addr_type2 == IPV6_ADDR_ANY && addr_type1 == IPV6_ADDR_ANY)
24764+ return nx_v6_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24765+ else if (addr_type2 == IPV6_ADDR_ANY)
24766+ return v6_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr6, -1);
24767+ else if (addr_type1 == IPV6_ADDR_ANY) {
24768+ if (addr_type2 == IPV6_ADDR_MAPPED)
24769+ return nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24770+ else
24771+ return v6_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr6, -1);
24772+ }
24773+ return 1;
24774 }
24775
24776 static u32 udp6_portaddr_hash(const struct net *net,
24777@@ -162,6 +191,10 @@ static inline int compute_score(struct s
24778 if (inet->inet_dport != sport)
24779 return -1;
24780 score++;
4bf69007
AM
24781+ } else {
24782+ /* block non nx_info ips */
24783+ if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
24784+ return -1;
5eef5607
AM
24785 }
24786
24787 if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
f973f73f
AM
24788diff -NurpP --minimal linux-4.1.27/net/ipv6/xfrm6_policy.c linux-4.1.27-vs2.3.8.5.2/net/ipv6/xfrm6_policy.c
24789--- linux-4.1.27/net/ipv6/xfrm6_policy.c 2016-07-05 04:28:33.000000000 +0000
24790+++ linux-4.1.27-vs2.3.8.5.2/net/ipv6/xfrm6_policy.c 2016-07-05 04:41:47.000000000 +0000
5eef5607
AM
24791@@ -61,7 +61,8 @@ static int xfrm6_get_saddr(struct net *n
24792 return -EHOSTUNREACH;
24793
4bf69007 24794 dev = ip6_dst_idev(dst)->dev;
5eef5607
AM
24795- ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6);
24796+ ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6,
24797+ 0, &saddr->in6, NULL);
4bf69007
AM
24798 dst_release(dst);
24799 return 0;
24800 }
f973f73f
AM
24801diff -NurpP --minimal linux-4.1.27/net/netfilter/ipvs/ip_vs_xmit.c linux-4.1.27-vs2.3.8.5.2/net/netfilter/ipvs/ip_vs_xmit.c
24802--- linux-4.1.27/net/netfilter/ipvs/ip_vs_xmit.c 2016-07-05 04:28:34.000000000 +0000
24803+++ linux-4.1.27-vs2.3.8.5.2/net/netfilter/ipvs/ip_vs_xmit.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 24804@@ -377,7 +377,7 @@ __ip_vs_route_output_v6(struct net *net,
4bf69007
AM
24805 return dst;
24806 if (ipv6_addr_any(&fl6.saddr) &&
24807 ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev,
24808- &fl6.daddr, 0, &fl6.saddr) < 0)
24809+ &fl6.daddr, 0, &fl6.saddr, NULL) < 0)
24810 goto out_err;
24811 if (do_xfrm) {
24812 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
f973f73f
AM
24813diff -NurpP --minimal linux-4.1.27/net/netlink/af_netlink.c linux-4.1.27-vs2.3.8.5.2/net/netlink/af_netlink.c
24814--- linux-4.1.27/net/netlink/af_netlink.c 2016-07-05 04:28:34.000000000 +0000
24815+++ linux-4.1.27-vs2.3.8.5.2/net/netlink/af_netlink.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 24816@@ -62,6 +62,8 @@
bb20add7
AM
24817 #include <asm/cacheflush.h>
24818 #include <linux/hash.h>
5eef5607 24819 #include <linux/genetlink.h>
4bf69007
AM
24820+#include <linux/vs_context.h>
24821+#include <linux/vs_network.h>
4bf69007
AM
24822
24823 #include <net/net_namespace.h>
bb20add7 24824 #include <net/sock.h>
9e3e8383 24825@@ -3019,7 +3021,8 @@ static void *__netlink_seq_next(struct s
5eef5607
AM
24826 if (err)
24827 return ERR_PTR(err);
24828 }
24829- } while (sock_net(&nlk->sk) != seq_file_net(seq));
24830+ } while ((sock_net(&nlk->sk) != seq_file_net(seq)) ||
24831+ !nx_check(nlk->sk.sk_nid, VS_WATCH_P | VS_IDENT));
bb20add7 24832
5eef5607
AM
24833 return nlk;
24834 }
f973f73f
AM
24835diff -NurpP --minimal linux-4.1.27/net/socket.c linux-4.1.27-vs2.3.8.5.2/net/socket.c
24836--- linux-4.1.27/net/socket.c 2016-07-05 04:28:34.000000000 +0000
24837+++ linux-4.1.27-vs2.3.8.5.2/net/socket.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 24838@@ -99,10 +99,12 @@
4bf69007
AM
24839
24840 #include <net/sock.h>
24841 #include <linux/netfilter.h>
4bf69007
AM
24842+#include <linux/vs_socket.h>
24843+#include <linux/vs_inet.h>
24844+#include <linux/vs_inet6.h>
24845
24846 #include <linux/if_tun.h>
24847 #include <linux/ipv6_route.h>
5eef5607
AM
24848-#include <linux/route.h>
24849 #include <linux/sockios.h>
24850 #include <linux/atalk.h>
24851 #include <net/busy_poll.h>
24852@@ -610,8 +612,24 @@ EXPORT_SYMBOL(__sock_tx_timestamp);
4bf69007 24853
5eef5607
AM
24854 static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
24855 {
24856- int ret = sock->ops->sendmsg(sock, msg, msg_data_left(msg));
24857- BUG_ON(ret == -EIOCBQUEUED);
24858+ size_t size = msg_data_left(msg);
24859+ int ret = sock->ops->sendmsg(sock, msg, size);
24860+#if 0
4bf69007 24861+ if (sock->sk) {
5eef5607 24862+ if (!ret)
4bf69007 24863+ vx_sock_fail(sock->sk, size);
5eef5607
AM
24864+ else
24865+ vx_sock_send(sock->sk, size);
4bf69007 24866+ }
5eef5607 24867+#endif
4bf69007 24868+ vxdprintk(VXD_CBIT(net, 7),
5eef5607 24869+ "sock_sendmsg_nosec: %p[%p,%p,%p;%d/%d]:%zu/%zu",
4bf69007
AM
24870+ sock, sock->sk,
24871+ (sock->sk)?sock->sk->sk_nx_info:0,
24872+ (sock->sk)?sock->sk->sk_vx_info:0,
24873+ (sock->sk)?sock->sk->sk_xid:0,
24874+ (sock->sk)?sock->sk->sk_nid:0,
5eef5607
AM
24875+ size, msg_data_left(msg));
24876 return ret;
4bf69007
AM
24877 }
24878
5eef5607 24879@@ -1109,6 +1127,13 @@ int __sock_create(struct net *net, int f
4bf69007
AM
24880 if (type < 0 || type >= SOCK_MAX)
24881 return -EINVAL;
24882
24883+ if (!nx_check(0, VS_ADMIN)) {
24884+ if (family == PF_INET && !current_nx_info_has_v4())
24885+ return -EAFNOSUPPORT;
24886+ if (family == PF_INET6 && !current_nx_info_has_v6())
24887+ return -EAFNOSUPPORT;
24888+ }
2ba6f0dd 24889+
4bf69007
AM
24890 /* Compatibility.
24891
24892 This uglymoron is moved from INET layer to here to avoid
5eef5607 24893@@ -1243,6 +1268,7 @@ SYSCALL_DEFINE3(socket, int, family, int
4bf69007
AM
24894 if (retval < 0)
24895 goto out;
24896
24897+ set_bit(SOCK_USER_SOCKET, &sock->flags);
24898 retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
24899 if (retval < 0)
24900 goto out_release;
5eef5607 24901@@ -1284,10 +1310,12 @@ SYSCALL_DEFINE4(socketpair, int, family,
4bf69007
AM
24902 err = sock_create(family, type, protocol, &sock1);
24903 if (err < 0)
24904 goto out;
24905+ set_bit(SOCK_USER_SOCKET, &sock1->flags);
24906
24907 err = sock_create(family, type, protocol, &sock2);
24908 if (err < 0)
24909 goto out_release_1;
24910+ set_bit(SOCK_USER_SOCKET, &sock2->flags);
24911
24912 err = sock1->ops->socketpair(sock1, sock2);
24913 if (err < 0)
f973f73f
AM
24914diff -NurpP --minimal linux-4.1.27/net/sunrpc/auth.c linux-4.1.27-vs2.3.8.5.2/net/sunrpc/auth.c
24915--- linux-4.1.27/net/sunrpc/auth.c 2015-04-12 22:12:50.000000000 +0000
24916+++ linux-4.1.27-vs2.3.8.5.2/net/sunrpc/auth.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
24917@@ -15,6 +15,7 @@
24918 #include <linux/sunrpc/clnt.h>
24919 #include <linux/sunrpc/gss_api.h>
24920 #include <linux/spinlock.h>
24921+#include <linux/vs_tag.h>
24922
5eef5607 24923 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
4bf69007 24924 # define RPCDBG_FACILITY RPCDBG_AUTH
bb20add7 24925@@ -630,6 +631,7 @@ rpcauth_lookupcred(struct rpc_auth *auth
4bf69007
AM
24926 memset(&acred, 0, sizeof(acred));
24927 acred.uid = cred->fsuid;
24928 acred.gid = cred->fsgid;
a4a22af8 24929+ acred.tag = make_ktag(&init_user_ns, dx_current_tag());
bb20add7 24930 acred.group_info = cred->group_info;
4bf69007 24931 ret = auth->au_ops->lookup_cred(auth, &acred, flags);
bb20add7
AM
24932 return ret;
24933@@ -669,6 +671,7 @@ rpcauth_bind_root_cred(struct rpc_task *
4bf69007 24934 struct auth_cred acred = {
b00e13aa
AM
24935 .uid = GLOBAL_ROOT_UID,
24936 .gid = GLOBAL_ROOT_GID,
a4a22af8 24937+ .tag = KTAGT_INIT(dx_current_tag()),
4bf69007
AM
24938 };
24939
24940 dprintk("RPC: %5u looking up %s cred\n",
f973f73f
AM
24941diff -NurpP --minimal linux-4.1.27/net/sunrpc/auth_unix.c linux-4.1.27-vs2.3.8.5.2/net/sunrpc/auth_unix.c
24942--- linux-4.1.27/net/sunrpc/auth_unix.c 2015-04-12 22:12:50.000000000 +0000
24943+++ linux-4.1.27-vs2.3.8.5.2/net/sunrpc/auth_unix.c 2016-07-05 04:41:47.000000000 +0000
4bf69007
AM
24944@@ -13,11 +13,13 @@
24945 #include <linux/sunrpc/clnt.h>
24946 #include <linux/sunrpc/auth.h>
24947 #include <linux/user_namespace.h>
24948+#include <linux/vs_tag.h>
24949
24950 #define NFS_NGROUPS 16
24951
24952 struct unx_cred {
24953 struct rpc_cred uc_base;
b00e13aa
AM
24954+ ktag_t uc_tag;
24955 kgid_t uc_gid;
24956 kgid_t uc_gids[NFS_NGROUPS];
4bf69007 24957 };
b00e13aa 24958@@ -80,6 +82,7 @@ unx_create_cred(struct rpc_auth *auth, s
4bf69007
AM
24959 groups = NFS_NGROUPS;
24960
24961 cred->uc_gid = acred->gid;
24962+ cred->uc_tag = acred->tag;
b00e13aa
AM
24963 for (i = 0; i < groups; i++)
24964 cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
24965 if (i < NFS_NGROUPS)
24966@@ -121,7 +124,9 @@ unx_match(struct auth_cred *acred, struc
4bf69007
AM
24967 unsigned int i;
24968
24969
b00e13aa
AM
24970- if (!uid_eq(cred->uc_uid, acred->uid) || !gid_eq(cred->uc_gid, acred->gid))
24971+ if (!uid_eq(cred->uc_uid, acred->uid) ||
24972+ !gid_eq(cred->uc_gid, acred->gid) ||
24973+ !tag_eq(cred->uc_tag, acred->tag))
4bf69007
AM
24974 return 0;
24975
24976 if (acred->group_info != NULL)
b00e13aa 24977@@ -146,7 +151,7 @@ unx_marshal(struct rpc_task *task, __be3
4bf69007
AM
24978 struct rpc_clnt *clnt = task->tk_client;
24979 struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base);
24980 __be32 *base, *hold;
24981- int i;
24982+ int i, tag;
24983
24984 *p++ = htonl(RPC_AUTH_UNIX);
24985 base = p++;
a4a22af8 24986@@ -157,8 +162,11 @@ unx_marshal(struct rpc_task *task, __be3
4bf69007
AM
24987 */
24988 p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
4bf69007 24989
b00e13aa
AM
24990- *p++ = htonl((u32) from_kuid(&init_user_ns, cred->uc_uid));
24991- *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gid));
24992+ tag = task->tk_client->cl_tag;
a4a22af8
AM
24993+ *p++ = htonl((u32) from_kuid(&init_user_ns,
24994+ TAGINO_KUID(tag, cred->uc_uid, cred->uc_tag)));
24995+ *p++ = htonl((u32) from_kgid(&init_user_ns,
24996+ TAGINO_KGID(tag, cred->uc_gid, cred->uc_tag)));
4bf69007 24997 hold = p++;
b00e13aa
AM
24998 for (i = 0; i < 16 && gid_valid(cred->uc_gids[i]); i++)
24999 *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gids[i]));
f973f73f
AM
25000diff -NurpP --minimal linux-4.1.27/net/sunrpc/clnt.c linux-4.1.27-vs2.3.8.5.2/net/sunrpc/clnt.c
25001--- linux-4.1.27/net/sunrpc/clnt.c 2015-04-12 22:12:50.000000000 +0000
25002+++ linux-4.1.27-vs2.3.8.5.2/net/sunrpc/clnt.c 2016-07-05 04:41:47.000000000 +0000
4bf69007 25003@@ -31,6 +31,7 @@
c2e5f7c8 25004 #include <linux/in.h>
4bf69007
AM
25005 #include <linux/in6.h>
25006 #include <linux/un.h>
4bf69007
AM
25007+#include <linux/vs_cvirt.h>
25008
25009 #include <linux/sunrpc/clnt.h>
b00e13aa 25010 #include <linux/sunrpc/addr.h>
5eef5607 25011@@ -472,6 +473,9 @@ struct rpc_clnt *rpc_create_xprt(struct
4bf69007
AM
25012 if (!(args->flags & RPC_CLNT_CREATE_QUIET))
25013 clnt->cl_chatty = 1;
25014
25015+ /* TODO: handle RPC_CLNT_CREATE_TAGGED
25016+ if (args->flags & RPC_CLNT_CREATE_TAGGED)
25017+ clnt->cl_tag = 1; */
25018 return clnt;
25019 }
bb20add7 25020 EXPORT_SYMBOL_GPL(rpc_create_xprt);
f973f73f
AM
25021diff -NurpP --minimal linux-4.1.27/net/unix/af_unix.c linux-4.1.27-vs2.3.8.5.2/net/unix/af_unix.c
25022--- linux-4.1.27/net/unix/af_unix.c 2016-07-05 04:28:34.000000000 +0000
25023+++ linux-4.1.27-vs2.3.8.5.2/net/unix/af_unix.c 2016-07-05 04:41:47.000000000 +0000
bb20add7 25024@@ -117,6 +117,8 @@
4bf69007
AM
25025 #include <net/checksum.h>
25026 #include <linux/security.h>
c2e5f7c8 25027 #include <linux/freezer.h>
4bf69007
AM
25028+#include <linux/vs_context.h>
25029+#include <linux/vs_limit.h>
25030
25031 struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
25032 EXPORT_SYMBOL_GPL(unix_socket_table);
bb20add7 25033@@ -272,6 +274,8 @@ static struct sock *__unix_find_socket_b
4bf69007
AM
25034 if (!net_eq(sock_net(s), net))
25035 continue;
25036
25037+ if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT))
25038+ continue;
25039 if (u->addr->len == len &&
25040 !memcmp(u->addr->name, sunname, len))
25041 goto found;
f973f73f 25042@@ -2441,6 +2445,8 @@ static struct sock *unix_from_bucket(str
4bf69007
AM
25043 for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
25044 if (sock_net(sk) != seq_file_net(seq))
25045 continue;
25046+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
25047+ continue;
25048 if (++count == offset)
25049 break;
25050 }
f973f73f 25051@@ -2458,6 +2464,8 @@ static struct sock *unix_next_socket(str
4bf69007
AM
25052 sk = sk_next(sk);
25053 if (!sk)
25054 goto next_bucket;
25055+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
25056+ continue;
25057 if (sock_net(sk) == seq_file_net(seq))
25058 return sk;
25059 }
f973f73f
AM
25060diff -NurpP --minimal linux-4.1.27/scripts/checksyscalls.sh linux-4.1.27-vs2.3.8.5.2/scripts/checksyscalls.sh
25061--- linux-4.1.27/scripts/checksyscalls.sh 2015-04-12 22:12:50.000000000 +0000
25062+++ linux-4.1.27-vs2.3.8.5.2/scripts/checksyscalls.sh 2016-07-05 04:41:47.000000000 +0000
bb20add7 25063@@ -196,7 +196,6 @@ cat << EOF
4bf69007
AM
25064 #define __IGNORE_afs_syscall
25065 #define __IGNORE_getpmsg
25066 #define __IGNORE_putpmsg
25067-#define __IGNORE_vserver
25068 EOF
25069 }
25070
f973f73f
AM
25071diff -NurpP --minimal linux-4.1.27/security/commoncap.c linux-4.1.27-vs2.3.8.5.2/security/commoncap.c
25072--- linux-4.1.27/security/commoncap.c 2016-07-05 04:28:34.000000000 +0000
25073+++ linux-4.1.27-vs2.3.8.5.2/security/commoncap.c 2016-07-05 04:41:47.000000000 +0000
b00e13aa 25074@@ -76,6 +76,7 @@ int cap_netlink_send(struct sock *sk, st
4bf69007
AM
25075 int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
25076 int cap, int audit)
25077 {
25078+ struct vx_info *vxi = current_vx_info(); /* FIXME: get vxi from cred? */
b00e13aa 25079 struct user_namespace *ns = targ_ns;
4bf69007 25080
b00e13aa
AM
25081 /* See if cred has the capability in the target user namespace
25082@@ -84,8 +85,12 @@ int cap_capable(const struct cred *cred,
25083 */
25084 for (;;) {
4bf69007 25085 /* Do we have the necessary capabilities? */
b00e13aa 25086- if (ns == cred->user_ns)
4bf69007 25087- return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM;
b00e13aa 25088+ if (ns == cred->user_ns) {
4bf69007
AM
25089+ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0) &&
25090+ cap_raised(cred->cap_effective, cap))
25091+ return 0;
25092+ return vx_cap_raised(vxi, cred->cap_effective, cap) ? 0 : -EPERM;
25093+ }
25094
25095 /* Have we tried all of the parent namespaces? */
b00e13aa 25096 if (ns == &init_user_ns)
f973f73f 25097@@ -632,7 +637,7 @@ int cap_inode_setxattr(struct dentry *de
4bf69007
AM
25098
25099 if (!strncmp(name, XATTR_SECURITY_PREFIX,
25100 sizeof(XATTR_SECURITY_PREFIX) - 1) &&
25101- !capable(CAP_SYS_ADMIN))
25102+ !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY))
25103 return -EPERM;
25104 return 0;
25105 }
f973f73f 25106@@ -658,7 +663,7 @@ int cap_inode_removexattr(struct dentry
4bf69007
AM
25107
25108 if (!strncmp(name, XATTR_SECURITY_PREFIX,
25109 sizeof(XATTR_SECURITY_PREFIX) - 1) &&
25110- !capable(CAP_SYS_ADMIN))
25111+ !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY))
25112 return -EPERM;
25113 return 0;
25114 }
f973f73f
AM
25115diff -NurpP --minimal linux-4.1.27/security/selinux/hooks.c linux-4.1.27-vs2.3.8.5.2/security/selinux/hooks.c
25116--- linux-4.1.27/security/selinux/hooks.c 2016-07-05 04:28:34.000000000 +0000
25117+++ linux-4.1.27-vs2.3.8.5.2/security/selinux/hooks.c 2016-07-05 04:41:47.000000000 +0000
5eef5607 25118@@ -67,7 +67,6 @@
4bf69007
AM
25119 #include <linux/dccp.h>
25120 #include <linux/quota.h>
25121 #include <linux/un.h> /* for Unix socket types */
25122-#include <net/af_unix.h> /* for Unix socket types */
25123 #include <linux/parser.h>
25124 #include <linux/nfs_mount.h>
25125 #include <net/ipv6.h>
This page took 5.167512 seconds and 4 git commands to generate.