Gentoo Archives: gentoo-commits

From: "Benedikt Boehm (hollow)" <hollow@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] vps r557 - in vserver-sources: . 2.2.0.7
Date: Mon, 17 Mar 2008 10:11:04
Message-Id: E1JbCIH-0007md-1r@stork.gentoo.org
1 Author: hollow
2 Date: 2008-03-17 10:10:12 +0000 (Mon, 17 Mar 2008)
3 New Revision: 557
4
5 Added:
6 vserver-sources/2.2.0.7/
7 vserver-sources/2.2.0.7/1012_linux-2.6.22.18.patch
8 vserver-sources/2.2.0.7/1013_linux-2.6.22.19.patch
9 vserver-sources/2.2.0.7/4410_vs2.2.0.7.patch
10 Log:
11 add 2.2.0.7
12
13 Copied: vserver-sources/2.2.0.7/1012_linux-2.6.22.18.patch (from rev 556, vserver-sources/2.2.0.6/1012_linux-2.6.22.18.patch)
14 ===================================================================
15 --- vserver-sources/2.2.0.7/1012_linux-2.6.22.18.patch (rev 0)
16 +++ vserver-sources/2.2.0.7/1012_linux-2.6.22.18.patch 2008-03-17 10:10:12 UTC (rev 557)
17 @@ -0,0 +1,3682 @@
18 +diff -NurpP linux-2.6.22.12/arch/i386/kernel/tsc.c linux-2.6.22.18/arch/i386/kernel/tsc.c
19 +--- linux-2.6.22.12/arch/i386/kernel/tsc.c 2007-11-05 18:59:33.000000000 +0100
20 ++++ linux-2.6.22.18/arch/i386/kernel/tsc.c 2008-02-11 08:31:19.000000000 +0100
21 +@@ -122,7 +122,7 @@ unsigned long native_calculate_cpu_khz(v
22 + {
23 + unsigned long long start, end;
24 + unsigned long count;
25 +- u64 delta64;
26 ++ u64 delta64 = (u64)ULLONG_MAX;
27 + int i;
28 + unsigned long flags;
29 +
30 +@@ -134,6 +134,7 @@ unsigned long native_calculate_cpu_khz(v
31 + rdtscll(start);
32 + mach_countup(&count);
33 + rdtscll(end);
34 ++ delta64 = min(delta64, (end - start));
35 + }
36 + /*
37 + * Error: ECTCNEVERSET
38 +@@ -144,8 +145,6 @@ unsigned long native_calculate_cpu_khz(v
39 + if (count <= 1)
40 + goto err;
41 +
42 +- delta64 = end - start;
43 +-
44 + /* cpu freq too fast: */
45 + if (delta64 > (1ULL<<32))
46 + goto err;
47 +diff -NurpP linux-2.6.22.12/arch/powerpc/mm/hash_utils_64.c linux-2.6.22.18/arch/powerpc/mm/hash_utils_64.c
48 +--- linux-2.6.22.12/arch/powerpc/mm/hash_utils_64.c 2007-11-05 18:59:33.000000000 +0100
49 ++++ linux-2.6.22.18/arch/powerpc/mm/hash_utils_64.c 2008-02-11 08:31:19.000000000 +0100
50 +@@ -795,7 +795,7 @@ void hash_preload(struct mm_struct *mm,
51 +
52 + #ifdef CONFIG_PPC_MM_SLICES
53 + /* We only prefault standard pages for now */
54 +- if (unlikely(get_slice_psize(mm, ea) != mm->context.user_psize));
55 ++ if (unlikely(get_slice_psize(mm, ea) != mm->context.user_psize))
56 + return;
57 + #endif
58 +
59 +diff -NurpP linux-2.6.22.12/arch/sparc64/kernel/chmc.c linux-2.6.22.18/arch/sparc64/kernel/chmc.c
60 +--- linux-2.6.22.12/arch/sparc64/kernel/chmc.c 2007-11-05 18:59:33.000000000 +0100
61 ++++ linux-2.6.22.18/arch/sparc64/kernel/chmc.c 2008-02-11 08:31:19.000000000 +0100
62 +@@ -1,7 +1,6 @@
63 +-/* $Id: chmc.c,v 1.4 2002/01/08 16:00:14 davem Exp $
64 +- * memctrlr.c: Driver for UltraSPARC-III memory controller.
65 ++/* memctrlr.c: Driver for UltraSPARC-III memory controller.
66 + *
67 +- * Copyright (C) 2001 David S. Miller (davem@××××××.com)
68 ++ * Copyright (C) 2001, 2007 David S. Miller (davem@×××××××××.net)
69 + */
70 +
71 + #include <linux/module.h>
72 +@@ -16,6 +15,7 @@
73 + #include <linux/init.h>
74 + #include <asm/spitfire.h>
75 + #include <asm/chmctrl.h>
76 ++#include <asm/cpudata.h>
77 + #include <asm/oplib.h>
78 + #include <asm/prom.h>
79 + #include <asm/io.h>
80 +@@ -242,8 +242,11 @@ int chmc_getunumber(int syndrome_code,
81 + */
82 + static u64 read_mcreg(struct mctrl_info *mp, unsigned long offset)
83 + {
84 +- unsigned long ret;
85 +- int this_cpu = get_cpu();
86 ++ unsigned long ret, this_cpu;
87 ++
88 ++ preempt_disable();
89 ++
90 ++ this_cpu = real_hard_smp_processor_id();
91 +
92 + if (mp->portid == this_cpu) {
93 + __asm__ __volatile__("ldxa [%1] %2, %0"
94 +@@ -255,7 +258,8 @@ static u64 read_mcreg(struct mctrl_info
95 + : "r" (mp->regs + offset),
96 + "i" (ASI_PHYS_BYPASS_EC_E));
97 + }
98 +- put_cpu();
99 ++
100 ++ preempt_enable();
101 +
102 + return ret;
103 + }
104 +diff -NurpP linux-2.6.22.12/arch/sparc64/kernel/entry.S linux-2.6.22.18/arch/sparc64/kernel/entry.S
105 +--- linux-2.6.22.12/arch/sparc64/kernel/entry.S 2007-11-05 18:59:33.000000000 +0100
106 ++++ linux-2.6.22.18/arch/sparc64/kernel/entry.S 2008-02-11 08:31:19.000000000 +0100
107 +@@ -2593,3 +2593,15 @@ sun4v_mmustat_info:
108 + retl
109 + nop
110 + .size sun4v_mmustat_info, .-sun4v_mmustat_info
111 ++
112 ++ .globl sun4v_mmu_demap_all
113 ++ .type sun4v_mmu_demap_all,#function
114 ++sun4v_mmu_demap_all:
115 ++ clr %o0
116 ++ clr %o1
117 ++ mov HV_MMU_ALL, %o2
118 ++ mov HV_FAST_MMU_DEMAP_ALL, %o5
119 ++ ta HV_FAST_TRAP
120 ++ retl
121 ++ nop
122 ++ .size sun4v_mmu_demap_all, .-sun4v_mmu_demap_all
123 +diff -NurpP linux-2.6.22.12/arch/sparc64/kernel/smp.c linux-2.6.22.18/arch/sparc64/kernel/smp.c
124 +--- linux-2.6.22.12/arch/sparc64/kernel/smp.c 2007-11-05 18:59:33.000000000 +0100
125 ++++ linux-2.6.22.18/arch/sparc64/kernel/smp.c 2008-02-11 08:31:19.000000000 +0100
126 +@@ -403,7 +403,7 @@ static __inline__ void spitfire_xcall_de
127 + */
128 + static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask)
129 + {
130 +- u64 pstate, ver;
131 ++ u64 pstate, ver, busy_mask;
132 + int nack_busy_id, is_jbus, need_more;
133 +
134 + if (cpus_empty(mask))
135 +@@ -435,14 +435,20 @@ retry:
136 + "i" (ASI_INTR_W));
137 +
138 + nack_busy_id = 0;
139 ++ busy_mask = 0;
140 + {
141 + int i;
142 +
143 + for_each_cpu_mask(i, mask) {
144 + u64 target = (i << 14) | 0x70;
145 +
146 +- if (!is_jbus)
147 ++ if (is_jbus) {
148 ++ busy_mask |= (0x1UL << (i * 2));
149 ++ } else {
150 + target |= (nack_busy_id << 24);
151 ++ busy_mask |= (0x1UL <<
152 ++ (nack_busy_id * 2));
153 ++ }
154 + __asm__ __volatile__(
155 + "stxa %%g0, [%0] %1\n\t"
156 + "membar #Sync\n\t"
157 +@@ -458,15 +464,16 @@ retry:
158 +
159 + /* Now, poll for completion. */
160 + {
161 +- u64 dispatch_stat;
162 ++ u64 dispatch_stat, nack_mask;
163 + long stuck;
164 +
165 + stuck = 100000 * nack_busy_id;
166 ++ nack_mask = busy_mask << 1;
167 + do {
168 + __asm__ __volatile__("ldxa [%%g0] %1, %0"
169 + : "=r" (dispatch_stat)
170 + : "i" (ASI_INTR_DISPATCH_STAT));
171 +- if (dispatch_stat == 0UL) {
172 ++ if (!(dispatch_stat & (busy_mask | nack_mask))) {
173 + __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
174 + : : "r" (pstate));
175 + if (unlikely(need_more)) {
176 +@@ -483,12 +490,12 @@ retry:
177 + }
178 + if (!--stuck)
179 + break;
180 +- } while (dispatch_stat & 0x5555555555555555UL);
181 ++ } while (dispatch_stat & busy_mask);
182 +
183 + __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
184 + : : "r" (pstate));
185 +
186 +- if ((dispatch_stat & ~(0x5555555555555555UL)) == 0) {
187 ++ if (dispatch_stat & busy_mask) {
188 + /* Busy bits will not clear, continue instead
189 + * of freezing up on this cpu.
190 + */
191 +diff -NurpP linux-2.6.22.12/arch/sparc64/mm/init.c linux-2.6.22.18/arch/sparc64/mm/init.c
192 +--- linux-2.6.22.12/arch/sparc64/mm/init.c 2007-11-05 18:59:33.000000000 +0100
193 ++++ linux-2.6.22.18/arch/sparc64/mm/init.c 2008-02-11 08:31:19.000000000 +0100
194 +@@ -1135,14 +1135,9 @@ static void __init mark_kpte_bitmap(unsi
195 + }
196 + }
197 +
198 +-static void __init kernel_physical_mapping_init(void)
199 ++static void __init init_kpte_bitmap(void)
200 + {
201 + unsigned long i;
202 +-#ifdef CONFIG_DEBUG_PAGEALLOC
203 +- unsigned long mem_alloced = 0UL;
204 +-#endif
205 +-
206 +- read_obp_memory("reg", &pall[0], &pall_ents);
207 +
208 + for (i = 0; i < pall_ents; i++) {
209 + unsigned long phys_start, phys_end;
210 +@@ -1151,14 +1146,24 @@ static void __init kernel_physical_mappi
211 + phys_end = phys_start + pall[i].reg_size;
212 +
213 + mark_kpte_bitmap(phys_start, phys_end);
214 ++ }
215 ++}
216 +
217 ++static void __init kernel_physical_mapping_init(void)
218 ++{
219 + #ifdef CONFIG_DEBUG_PAGEALLOC
220 ++ unsigned long i, mem_alloced = 0UL;
221 ++
222 ++ for (i = 0; i < pall_ents; i++) {
223 ++ unsigned long phys_start, phys_end;
224 ++
225 ++ phys_start = pall[i].phys_addr;
226 ++ phys_end = phys_start + pall[i].reg_size;
227 ++
228 + mem_alloced += kernel_map_range(phys_start, phys_end,
229 + PAGE_KERNEL);
230 +-#endif
231 + }
232 +
233 +-#ifdef CONFIG_DEBUG_PAGEALLOC
234 + printk("Allocated %ld bytes for kernel page tables.\n",
235 + mem_alloced);
236 +
237 +@@ -1400,6 +1405,10 @@ void __init paging_init(void)
238 +
239 + inherit_prom_mappings();
240 +
241 ++ read_obp_memory("reg", &pall[0], &pall_ents);
242 ++
243 ++ init_kpte_bitmap();
244 ++
245 + /* Ok, we can use our TLB miss and window trap handlers safely. */
246 + setup_tba();
247 +
248 +@@ -1854,7 +1863,9 @@ void __flush_tlb_all(void)
249 + "wrpr %0, %1, %%pstate"
250 + : "=r" (pstate)
251 + : "i" (PSTATE_IE));
252 +- if (tlb_type == spitfire) {
253 ++ if (tlb_type == hypervisor) {
254 ++ sun4v_mmu_demap_all();
255 ++ } else if (tlb_type == spitfire) {
256 + for (i = 0; i < 64; i++) {
257 + /* Spitfire Errata #32 workaround */
258 + /* NOTE: Always runs on spitfire, so no
259 +diff -NurpP linux-2.6.22.12/crypto/algapi.c linux-2.6.22.18/crypto/algapi.c
260 +--- linux-2.6.22.12/crypto/algapi.c 2007-11-05 18:59:33.000000000 +0100
261 ++++ linux-2.6.22.18/crypto/algapi.c 2008-02-11 08:31:19.000000000 +0100
262 +@@ -98,6 +98,9 @@ static void crypto_remove_spawn(struct c
263 + return;
264 +
265 + inst->alg.cra_flags |= CRYPTO_ALG_DEAD;
266 ++ if (hlist_unhashed(&inst->list))
267 ++ return;
268 ++
269 + if (!tmpl || !crypto_tmpl_get(tmpl))
270 + return;
271 +
272 +@@ -333,9 +336,6 @@ int crypto_register_instance(struct cryp
273 + LIST_HEAD(list);
274 + int err = -EINVAL;
275 +
276 +- if (inst->alg.cra_destroy)
277 +- goto err;
278 +-
279 + err = crypto_check_alg(&inst->alg);
280 + if (err)
281 + goto err;
282 +diff -NurpP linux-2.6.22.12/drivers/acpi/dispatcher/dsobject.c linux-2.6.22.18/drivers/acpi/dispatcher/dsobject.c
283 +--- linux-2.6.22.12/drivers/acpi/dispatcher/dsobject.c 2007-11-05 18:59:33.000000000 +0100
284 ++++ linux-2.6.22.18/drivers/acpi/dispatcher/dsobject.c 2008-02-11 08:31:19.000000000 +0100
285 +@@ -137,6 +137,71 @@ acpi_ds_build_internal_object(struct acp
286 + return_ACPI_STATUS(status);
287 + }
288 + }
289 ++
290 ++ /* Special object resolution for elements of a package */
291 ++
292 ++ if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
293 ++ (op->common.parent->common.aml_opcode ==
294 ++ AML_VAR_PACKAGE_OP)) {
295 ++ /*
296 ++ * Attempt to resolve the node to a value before we insert it into
297 ++ * the package. If this is a reference to a common data type,
298 ++ * resolve it immediately. According to the ACPI spec, package
299 ++ * elements can only be "data objects" or method references.
300 ++ * Attempt to resolve to an Integer, Buffer, String or Package.
301 ++ * If cannot, return the named reference (for things like Devices,
302 ++ * Methods, etc.) Buffer Fields and Fields will resolve to simple
303 ++ * objects (int/buf/str/pkg).
304 ++ *
305 ++ * NOTE: References to things like Devices, Methods, Mutexes, etc.
306 ++ * will remain as named references. This behavior is not described
307 ++ * in the ACPI spec, but it appears to be an oversight.
308 ++ */
309 ++ obj_desc = (union acpi_operand_object *)op->common.node;
310 ++
311 ++ status =
312 ++ acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
313 ++ (struct
314 ++ acpi_namespace_node,
315 ++ &obj_desc),
316 ++ walk_state);
317 ++ if (ACPI_FAILURE(status)) {
318 ++ return_ACPI_STATUS(status);
319 ++ }
320 ++
321 ++ switch (op->common.node->type) {
322 ++ /*
323 ++ * For these types, we need the actual node, not the subobject.
324 ++ * However, the subobject got an extra reference count above.
325 ++ */
326 ++ case ACPI_TYPE_MUTEX:
327 ++ case ACPI_TYPE_METHOD:
328 ++ case ACPI_TYPE_POWER:
329 ++ case ACPI_TYPE_PROCESSOR:
330 ++ case ACPI_TYPE_EVENT:
331 ++ case ACPI_TYPE_REGION:
332 ++ case ACPI_TYPE_DEVICE:
333 ++ case ACPI_TYPE_THERMAL:
334 ++
335 ++ obj_desc =
336 ++ (union acpi_operand_object *)op->common.
337 ++ node;
338 ++ break;
339 ++
340 ++ default:
341 ++ break;
342 ++ }
343 ++
344 ++ /*
345 ++ * If above resolved to an operand object, we are done. Otherwise,
346 ++ * we have a NS node, we must create the package entry as a named
347 ++ * reference.
348 ++ */
349 ++ if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) !=
350 ++ ACPI_DESC_TYPE_NAMED) {
351 ++ goto exit;
352 ++ }
353 ++ }
354 + }
355 +
356 + /* Create and init a new internal ACPI object */
357 +@@ -156,6 +221,7 @@ acpi_ds_build_internal_object(struct acp
358 + return_ACPI_STATUS(status);
359 + }
360 +
361 ++ exit:
362 + *obj_desc_ptr = obj_desc;
363 + return_ACPI_STATUS(AE_OK);
364 + }
365 +@@ -356,12 +422,25 @@ acpi_ds_build_internal_package_obj(struc
366 + arg = arg->common.next;
367 + for (i = 0; arg && (i < element_count); i++) {
368 + if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
369 +-
370 +- /* This package element is already built, just get it */
371 +-
372 +- obj_desc->package.elements[i] =
373 +- ACPI_CAST_PTR(union acpi_operand_object,
374 +- arg->common.node);
375 ++ if (arg->common.node->type == ACPI_TYPE_METHOD) {
376 ++ /*
377 ++ * A method reference "looks" to the parser to be a method
378 ++ * invocation, so we special case it here
379 ++ */
380 ++ arg->common.aml_opcode = AML_INT_NAMEPATH_OP;
381 ++ status =
382 ++ acpi_ds_build_internal_object(walk_state,
383 ++ arg,
384 ++ &obj_desc->
385 ++ package.
386 ++ elements[i]);
387 ++ } else {
388 ++ /* This package element is already built, just get it */
389 ++
390 ++ obj_desc->package.elements[i] =
391 ++ ACPI_CAST_PTR(union acpi_operand_object,
392 ++ arg->common.node);
393 ++ }
394 + } else {
395 + status = acpi_ds_build_internal_object(walk_state, arg,
396 + &obj_desc->
397 +diff -NurpP linux-2.6.22.12/drivers/ata/ahci.c linux-2.6.22.18/drivers/ata/ahci.c
398 +--- linux-2.6.22.12/drivers/ata/ahci.c 2007-11-05 18:59:33.000000000 +0100
399 ++++ linux-2.6.22.18/drivers/ata/ahci.c 2008-02-11 08:31:19.000000000 +0100
400 +@@ -1241,7 +1241,7 @@ static void ahci_host_intr(struct ata_po
401 + struct ata_eh_info *ehi = &ap->eh_info;
402 + struct ahci_port_priv *pp = ap->private_data;
403 + u32 status, qc_active;
404 +- int rc, known_irq = 0;
405 ++ int rc;
406 +
407 + status = readl(port_mmio + PORT_IRQ_STAT);
408 + writel(status, port_mmio + PORT_IRQ_STAT);
409 +@@ -1257,74 +1257,11 @@ static void ahci_host_intr(struct ata_po
410 + qc_active = readl(port_mmio + PORT_CMD_ISSUE);
411 +
412 + rc = ata_qc_complete_multiple(ap, qc_active, NULL);
413 +- if (rc > 0)
414 +- return;
415 + if (rc < 0) {
416 + ehi->err_mask |= AC_ERR_HSM;
417 + ehi->action |= ATA_EH_SOFTRESET;
418 + ata_port_freeze(ap);
419 +- return;
420 +- }
421 +-
422 +- /* hmmm... a spurious interupt */
423 +-
424 +- /* if !NCQ, ignore. No modern ATA device has broken HSM
425 +- * implementation for non-NCQ commands.
426 +- */
427 +- if (!ap->sactive)
428 +- return;
429 +-
430 +- if (status & PORT_IRQ_D2H_REG_FIS) {
431 +- if (!pp->ncq_saw_d2h)
432 +- ata_port_printk(ap, KERN_INFO,
433 +- "D2H reg with I during NCQ, "
434 +- "this message won't be printed again\n");
435 +- pp->ncq_saw_d2h = 1;
436 +- known_irq = 1;
437 +- }
438 +-
439 +- if (status & PORT_IRQ_DMAS_FIS) {
440 +- if (!pp->ncq_saw_dmas)
441 +- ata_port_printk(ap, KERN_INFO,
442 +- "DMAS FIS during NCQ, "
443 +- "this message won't be printed again\n");
444 +- pp->ncq_saw_dmas = 1;
445 +- known_irq = 1;
446 +- }
447 +-
448 +- if (status & PORT_IRQ_SDB_FIS) {
449 +- const __le32 *f = pp->rx_fis + RX_FIS_SDB;
450 +-
451 +- if (le32_to_cpu(f[1])) {
452 +- /* SDB FIS containing spurious completions
453 +- * might be dangerous, whine and fail commands
454 +- * with HSM violation. EH will turn off NCQ
455 +- * after several such failures.
456 +- */
457 +- ata_ehi_push_desc(ehi,
458 +- "spurious completions during NCQ "
459 +- "issue=0x%x SAct=0x%x FIS=%08x:%08x",
460 +- readl(port_mmio + PORT_CMD_ISSUE),
461 +- readl(port_mmio + PORT_SCR_ACT),
462 +- le32_to_cpu(f[0]), le32_to_cpu(f[1]));
463 +- ehi->err_mask |= AC_ERR_HSM;
464 +- ehi->action |= ATA_EH_SOFTRESET;
465 +- ata_port_freeze(ap);
466 +- } else {
467 +- if (!pp->ncq_saw_sdb)
468 +- ata_port_printk(ap, KERN_INFO,
469 +- "spurious SDB FIS %08x:%08x during NCQ, "
470 +- "this message won't be printed again\n",
471 +- le32_to_cpu(f[0]), le32_to_cpu(f[1]));
472 +- pp->ncq_saw_sdb = 1;
473 +- }
474 +- known_irq = 1;
475 + }
476 +-
477 +- if (!known_irq)
478 +- ata_port_printk(ap, KERN_INFO, "spurious interrupt "
479 +- "(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n",
480 +- status, ap->active_tag, ap->sactive);
481 + }
482 +
483 + static void ahci_irq_clear(struct ata_port *ap)
484 +diff -NurpP linux-2.6.22.12/drivers/ata/libata-core.c linux-2.6.22.18/drivers/ata/libata-core.c
485 +--- linux-2.6.22.12/drivers/ata/libata-core.c 2007-11-05 18:59:33.000000000 +0100
486 ++++ linux-2.6.22.18/drivers/ata/libata-core.c 2008-02-11 08:31:19.000000000 +0100
487 +@@ -3785,6 +3785,7 @@ static const struct ata_blacklist_entry
488 + /* Devices where NCQ should be avoided */
489 + /* NCQ is slow */
490 + { "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ },
491 ++ { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, },
492 + /* http://thread.gmane.org/gmane.linux.ide/14907 */
493 + { "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ },
494 + /* NCQ is broken */
495 +@@ -3803,15 +3804,6 @@ static const struct ata_blacklist_entry
496 + { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, },
497 + { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, },
498 + { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, },
499 +- /* Drives which do spurious command completion */
500 +- { "HTS541680J9SA00", "SB2IC7EP", ATA_HORKAGE_NONCQ, },
501 +- { "HTS541612J9SA00", "SBDIC7JP", ATA_HORKAGE_NONCQ, },
502 +- { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, },
503 +- { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, },
504 +- { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, },
505 +- { "ST9160821AS", "3.CLF", ATA_HORKAGE_NONCQ, },
506 +- { "ST3160812AS", "3.AD", ATA_HORKAGE_NONCQ, },
507 +- { "SAMSUNG HD401LJ", "ZZ100-15", ATA_HORKAGE_NONCQ, },
508 +
509 + /* End Marker */
510 + { }
511 +diff -NurpP linux-2.6.22.12/drivers/atm/he.c linux-2.6.22.18/drivers/atm/he.c
512 +--- linux-2.6.22.12/drivers/atm/he.c 2007-11-05 18:59:33.000000000 +0100
513 ++++ linux-2.6.22.18/drivers/atm/he.c 2008-02-11 08:31:19.000000000 +0100
514 +@@ -394,6 +394,11 @@ he_init_one(struct pci_dev *pci_dev, con
515 + he_dev->atm_dev->dev_data = he_dev;
516 + atm_dev->dev_data = he_dev;
517 + he_dev->number = atm_dev->number;
518 ++#ifdef USE_TASKLET
519 ++ tasklet_init(&he_dev->tasklet, he_tasklet, (unsigned long) he_dev);
520 ++#endif
521 ++ spin_lock_init(&he_dev->global_lock);
522 ++
523 + if (he_start(atm_dev)) {
524 + he_stop(he_dev);
525 + err = -ENODEV;
526 +@@ -1173,11 +1178,6 @@ he_start(struct atm_dev *dev)
527 + if ((err = he_init_irq(he_dev)) != 0)
528 + return err;
529 +
530 +-#ifdef USE_TASKLET
531 +- tasklet_init(&he_dev->tasklet, he_tasklet, (unsigned long) he_dev);
532 +-#endif
533 +- spin_lock_init(&he_dev->global_lock);
534 +-
535 + /* 4.11 enable pci bus controller state machines */
536 + host_cntl |= (OUTFF_ENB | CMDFF_ENB |
537 + QUICK_RD_RETRY | QUICK_WR_RETRY | PERR_INT_ENB);
538 +diff -NurpP linux-2.6.22.12/drivers/atm/nicstar.c linux-2.6.22.18/drivers/atm/nicstar.c
539 +--- linux-2.6.22.12/drivers/atm/nicstar.c 2007-11-05 18:59:33.000000000 +0100
540 ++++ linux-2.6.22.18/drivers/atm/nicstar.c 2008-02-11 08:31:19.000000000 +0100
541 +@@ -625,14 +625,6 @@ static int __devinit ns_init_card(int i,
542 + if (mac[i] == NULL)
543 + nicstar_init_eprom(card->membase);
544 +
545 +- if (request_irq(pcidev->irq, &ns_irq_handler, IRQF_DISABLED | IRQF_SHARED, "nicstar", card) != 0)
546 +- {
547 +- printk("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq);
548 +- error = 9;
549 +- ns_init_card_error(card, error);
550 +- return error;
551 +- }
552 +-
553 + /* Set the VPI/VCI MSb mask to zero so we can receive OAM cells */
554 + writel(0x00000000, card->membase + VPM);
555 +
556 +@@ -858,8 +850,6 @@ static int __devinit ns_init_card(int i,
557 + card->iovpool.count++;
558 + }
559 +
560 +- card->intcnt = 0;
561 +-
562 + /* Configure NICStAR */
563 + if (card->rct_size == 4096)
564 + ns_cfg_rctsize = NS_CFG_RCTSIZE_4096_ENTRIES;
565 +@@ -868,6 +858,15 @@ static int __devinit ns_init_card(int i,
566 +
567 + card->efbie = 1;
568 +
569 ++ card->intcnt = 0;
570 ++ if (request_irq(pcidev->irq, &ns_irq_handler, IRQF_DISABLED | IRQF_SHARED, "nicstar", card) != 0)
571 ++ {
572 ++ printk("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq);
573 ++ error = 9;
574 ++ ns_init_card_error(card, error);
575 ++ return error;
576 ++ }
577 ++
578 + /* Register device */
579 + card->atmdev = atm_dev_register("nicstar", &atm_ops, -1, NULL);
580 + if (card->atmdev == NULL)
581 +diff -NurpP linux-2.6.22.12/drivers/block/rd.c linux-2.6.22.18/drivers/block/rd.c
582 +--- linux-2.6.22.12/drivers/block/rd.c 2007-11-05 18:59:33.000000000 +0100
583 ++++ linux-2.6.22.18/drivers/block/rd.c 2008-02-11 08:31:19.000000000 +0100
584 +@@ -189,6 +189,18 @@ static int ramdisk_set_page_dirty(struct
585 + return 0;
586 + }
587 +
588 ++/*
589 ++ * releasepage is called by pagevec_strip/try_to_release_page if
590 ++ * buffers_heads_over_limit is true. Without a releasepage function
591 ++ * try_to_free_buffers is called instead. That can unset the dirty
592 ++ * bit of our ram disk pages, which will be eventually freed, even
593 ++ * if the page is still in use.
594 ++ */
595 ++static int ramdisk_releasepage(struct page *page, gfp_t dummy)
596 ++{
597 ++ return 0;
598 ++}
599 ++
600 + static const struct address_space_operations ramdisk_aops = {
601 + .readpage = ramdisk_readpage,
602 + .prepare_write = ramdisk_prepare_write,
603 +@@ -196,6 +208,7 @@ static const struct address_space_operat
604 + .writepage = ramdisk_writepage,
605 + .set_page_dirty = ramdisk_set_page_dirty,
606 + .writepages = ramdisk_writepages,
607 ++ .releasepage = ramdisk_releasepage,
608 + };
609 +
610 + static int rd_blkdev_pagecache_IO(int rw, struct bio_vec *vec, sector_t sector,
611 +diff -NurpP linux-2.6.22.12/drivers/char/drm/drm_vm.c linux-2.6.22.18/drivers/char/drm/drm_vm.c
612 +--- linux-2.6.22.12/drivers/char/drm/drm_vm.c 2007-11-05 18:59:33.000000000 +0100
613 ++++ linux-2.6.22.18/drivers/char/drm/drm_vm.c 2008-02-11 08:31:19.000000000 +0100
614 +@@ -520,6 +520,7 @@ static int drm_mmap_dma(struct file *fil
615 + vma->vm_ops = &drm_vm_dma_ops;
616 +
617 + vma->vm_flags |= VM_RESERVED; /* Don't swap */
618 ++ vma->vm_flags |= VM_DONTEXPAND;
619 +
620 + vma->vm_file = filp; /* Needed for drm_vm_open() */
621 + drm_vm_open_locked(vma);
622 +@@ -669,6 +670,7 @@ static int drm_mmap_locked(struct file *
623 + return -EINVAL; /* This should never happen. */
624 + }
625 + vma->vm_flags |= VM_RESERVED; /* Don't swap */
626 ++ vma->vm_flags |= VM_DONTEXPAND;
627 +
628 + vma->vm_file = filp; /* Needed for drm_vm_open() */
629 + drm_vm_open_locked(vma);
630 +diff -NurpP linux-2.6.22.12/drivers/char/mspec.c linux-2.6.22.18/drivers/char/mspec.c
631 +--- linux-2.6.22.12/drivers/char/mspec.c 2007-11-05 18:59:33.000000000 +0100
632 ++++ linux-2.6.22.18/drivers/char/mspec.c 2008-02-11 08:31:19.000000000 +0100
633 +@@ -265,7 +265,8 @@ mspec_mmap(struct file *file, struct vm_
634 + vdata->refcnt = ATOMIC_INIT(1);
635 + vma->vm_private_data = vdata;
636 +
637 +- vma->vm_flags |= (VM_IO | VM_LOCKED | VM_RESERVED | VM_PFNMAP);
638 ++ vma->vm_flags |= (VM_IO | VM_LOCKED | VM_RESERVED | VM_PFNMAP |
639 ++ VM_DONTEXPAND);
640 + if (vdata->type == MSPEC_FETCHOP || vdata->type == MSPEC_UNCACHED)
641 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
642 + vma->vm_ops = &mspec_vm_ops;
643 +diff -NurpP linux-2.6.22.12/drivers/connector/cn_queue.c linux-2.6.22.18/drivers/connector/cn_queue.c
644 +--- linux-2.6.22.12/drivers/connector/cn_queue.c 2007-11-05 18:59:33.000000000 +0100
645 ++++ linux-2.6.22.18/drivers/connector/cn_queue.c 2008-02-11 08:31:19.000000000 +0100
646 +@@ -99,8 +99,8 @@ int cn_queue_add_callback(struct cn_queu
647 + spin_unlock_bh(&dev->queue_lock);
648 +
649 + if (found) {
650 +- atomic_dec(&dev->refcnt);
651 + cn_queue_free_callback(cbq);
652 ++ atomic_dec(&dev->refcnt);
653 + return -EINVAL;
654 + }
655 +
656 +diff -NurpP linux-2.6.22.12/drivers/i2c/busses/i2c-pasemi.c linux-2.6.22.18/drivers/i2c/busses/i2c-pasemi.c
657 +--- linux-2.6.22.12/drivers/i2c/busses/i2c-pasemi.c 2007-11-05 18:59:33.000000000 +0100
658 ++++ linux-2.6.22.18/drivers/i2c/busses/i2c-pasemi.c 2008-02-11 08:31:19.000000000 +0100
659 +@@ -51,6 +51,7 @@ struct pasemi_smbus {
660 + #define MRXFIFO_DATA_M 0x000000ff
661 +
662 + #define SMSTA_XEN 0x08000000
663 ++#define SMSTA_MTN 0x00200000
664 +
665 + #define CTL_MRR 0x00000400
666 + #define CTL_MTR 0x00000200
667 +@@ -98,6 +99,10 @@ static unsigned int pasemi_smb_waitready
668 + status = reg_read(smbus, REG_SMSTA);
669 + }
670 +
671 ++ /* Got NACK? */
672 ++ if (status & SMSTA_MTN)
673 ++ return -ENXIO;
674 ++
675 + if (timeout < 0) {
676 + dev_warn(&smbus->dev->dev, "Timeout, status 0x%08x\n", status);
677 + reg_write(smbus, REG_SMSTA, status);
678 +diff -NurpP linux-2.6.22.12/drivers/i2c/chips/eeprom.c linux-2.6.22.18/drivers/i2c/chips/eeprom.c
679 +--- linux-2.6.22.12/drivers/i2c/chips/eeprom.c 2007-11-05 18:59:33.000000000 +0100
680 ++++ linux-2.6.22.18/drivers/i2c/chips/eeprom.c 2008-02-11 08:31:19.000000000 +0100
681 +@@ -125,13 +125,20 @@ static ssize_t eeprom_read(struct kobjec
682 + for (slice = off >> 5; slice <= (off + count - 1) >> 5; slice++)
683 + eeprom_update_client(client, slice);
684 +
685 +- /* Hide Vaio security settings to regular users (16 first bytes) */
686 +- if (data->nature == VAIO && off < 16 && !capable(CAP_SYS_ADMIN)) {
687 +- size_t in_row1 = 16 - off;
688 +- in_row1 = min(in_row1, count);
689 +- memset(buf, 0, in_row1);
690 +- if (count - in_row1 > 0)
691 +- memcpy(buf + in_row1, &data->data[16], count - in_row1);
692 ++ /* Hide Vaio private settings to regular users:
693 ++ - BIOS passwords: bytes 0x00 to 0x0f
694 ++ - UUID: bytes 0x10 to 0x1f
695 ++ - Serial number: 0xc0 to 0xdf */
696 ++ if (data->nature == VAIO && !capable(CAP_SYS_ADMIN)) {
697 ++ int i;
698 ++
699 ++ for (i = 0; i < count; i++) {
700 ++ if ((off + i <= 0x1f) ||
701 ++ (off + i >= 0xc0 && off + i <= 0xdf))
702 ++ buf[i] = 0;
703 ++ else
704 ++ buf[i] = data->data[off + i];
705 ++ }
706 + } else {
707 + memcpy(buf, &data->data[off], count);
708 + }
709 +@@ -195,14 +202,18 @@ static int eeprom_detect(struct i2c_adap
710 + goto exit_kfree;
711 +
712 + /* Detect the Vaio nature of EEPROMs.
713 +- We use the "PCG-" prefix as the signature. */
714 ++ We use the "PCG-" or "VGN-" prefix as the signature. */
715 + if (address == 0x57) {
716 +- if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P'
717 +- && i2c_smbus_read_byte(new_client) == 'C'
718 +- && i2c_smbus_read_byte(new_client) == 'G'
719 +- && i2c_smbus_read_byte(new_client) == '-') {
720 ++ char name[4];
721 ++
722 ++ name[0] = i2c_smbus_read_byte_data(new_client, 0x80);
723 ++ name[1] = i2c_smbus_read_byte(new_client);
724 ++ name[2] = i2c_smbus_read_byte(new_client);
725 ++ name[3] = i2c_smbus_read_byte(new_client);
726 ++
727 ++ if (!memcmp(name, "PCG-", 4) || !memcmp(name, "VGN-", 4)) {
728 + dev_info(&new_client->dev, "Vaio EEPROM detected, "
729 +- "enabling password protection\n");
730 ++ "enabling privacy protection\n");
731 + data->nature = VAIO;
732 + }
733 + }
734 +diff -NurpP linux-2.6.22.12/drivers/ide/pci/serverworks.c linux-2.6.22.18/drivers/ide/pci/serverworks.c
735 +--- linux-2.6.22.12/drivers/ide/pci/serverworks.c 2007-11-05 18:59:33.000000000 +0100
736 ++++ linux-2.6.22.18/drivers/ide/pci/serverworks.c 2008-02-11 08:31:19.000000000 +0100
737 +@@ -101,6 +101,7 @@ static u8 svwks_udma_filter(ide_drive_t
738 + mode = 2;
739 +
740 + switch(mode) {
741 ++ case 3: mask = 0x3f; break;
742 + case 2: mask = 0x1f; break;
743 + case 1: mask = 0x07; break;
744 + default: mask = 0x00; break;
745 +diff -NurpP linux-2.6.22.12/drivers/isdn/hardware/avm/b1.c linux-2.6.22.18/drivers/isdn/hardware/avm/b1.c
746 +--- linux-2.6.22.12/drivers/isdn/hardware/avm/b1.c 2007-11-05 18:59:33.000000000 +0100
747 ++++ linux-2.6.22.18/drivers/isdn/hardware/avm/b1.c 2008-02-11 08:31:19.000000000 +0100
748 +@@ -321,12 +321,15 @@ void b1_reset_ctr(struct capi_ctr *ctrl)
749 + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
750 + avmcard *card = cinfo->card;
751 + unsigned int port = card->port;
752 ++ unsigned long flags;
753 +
754 + b1_reset(port);
755 + b1_reset(port);
756 +
757 + memset(cinfo->version, 0, sizeof(cinfo->version));
758 ++ spin_lock_irqsave(&card->lock, flags);
759 + capilib_release(&cinfo->ncci_head);
760 ++ spin_unlock_irqrestore(&card->lock, flags);
761 + capi_ctr_reseted(ctrl);
762 + }
763 +
764 +@@ -361,9 +364,8 @@ void b1_release_appl(struct capi_ctr *ct
765 + unsigned int port = card->port;
766 + unsigned long flags;
767 +
768 +- capilib_release_appl(&cinfo->ncci_head, appl);
769 +-
770 + spin_lock_irqsave(&card->lock, flags);
771 ++ capilib_release_appl(&cinfo->ncci_head, appl);
772 + b1_put_byte(port, SEND_RELEASE);
773 + b1_put_word(port, appl);
774 + spin_unlock_irqrestore(&card->lock, flags);
775 +@@ -380,27 +382,27 @@ u16 b1_send_message(struct capi_ctr *ctr
776 + u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
777 + u16 dlen, retval;
778 +
779 ++ spin_lock_irqsave(&card->lock, flags);
780 + if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
781 + retval = capilib_data_b3_req(&cinfo->ncci_head,
782 + CAPIMSG_APPID(skb->data),
783 + CAPIMSG_NCCI(skb->data),
784 + CAPIMSG_MSGID(skb->data));
785 +- if (retval != CAPI_NOERROR)
786 ++ if (retval != CAPI_NOERROR) {
787 ++ spin_unlock_irqrestore(&card->lock, flags);
788 + return retval;
789 ++ }
790 +
791 + dlen = CAPIMSG_DATALEN(skb->data);
792 +
793 +- spin_lock_irqsave(&card->lock, flags);
794 + b1_put_byte(port, SEND_DATA_B3_REQ);
795 + b1_put_slice(port, skb->data, len);
796 + b1_put_slice(port, skb->data + len, dlen);
797 +- spin_unlock_irqrestore(&card->lock, flags);
798 + } else {
799 +- spin_lock_irqsave(&card->lock, flags);
800 + b1_put_byte(port, SEND_MESSAGE);
801 + b1_put_slice(port, skb->data, len);
802 +- spin_unlock_irqrestore(&card->lock, flags);
803 + }
804 ++ spin_unlock_irqrestore(&card->lock, flags);
805 +
806 + dev_kfree_skb_any(skb);
807 + return CAPI_NOERROR;
808 +@@ -534,17 +536,17 @@ irqreturn_t b1_interrupt(int interrupt,
809 +
810 + ApplId = (unsigned) b1_get_word(card->port);
811 + MsgLen = b1_get_slice(card->port, card->msgbuf);
812 +- spin_unlock_irqrestore(&card->lock, flags);
813 + if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
814 + printk(KERN_ERR "%s: incoming packet dropped\n",
815 + card->name);
816 ++ spin_unlock_irqrestore(&card->lock, flags);
817 + } else {
818 + memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
819 + if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
820 + capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
821 + CAPIMSG_NCCI(skb->data),
822 + CAPIMSG_MSGID(skb->data));
823 +-
824 ++ spin_unlock_irqrestore(&card->lock, flags);
825 + capi_ctr_handle_message(ctrl, ApplId, skb);
826 + }
827 + break;
828 +@@ -554,21 +556,17 @@ irqreturn_t b1_interrupt(int interrupt,
829 + ApplId = b1_get_word(card->port);
830 + NCCI = b1_get_word(card->port);
831 + WindowSize = b1_get_word(card->port);
832 +- spin_unlock_irqrestore(&card->lock, flags);
833 +-
834 + capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
835 +-
836 ++ spin_unlock_irqrestore(&card->lock, flags);
837 + break;
838 +
839 + case RECEIVE_FREE_NCCI:
840 +
841 + ApplId = b1_get_word(card->port);
842 + NCCI = b1_get_word(card->port);
843 +- spin_unlock_irqrestore(&card->lock, flags);
844 +-
845 + if (NCCI != 0xffffffff)
846 + capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
847 +-
848 ++ spin_unlock_irqrestore(&card->lock, flags);
849 + break;
850 +
851 + case RECEIVE_START:
852 +diff -NurpP linux-2.6.22.12/drivers/isdn/hardware/avm/c4.c linux-2.6.22.18/drivers/isdn/hardware/avm/c4.c
853 +--- linux-2.6.22.12/drivers/isdn/hardware/avm/c4.c 2007-11-05 18:59:33.000000000 +0100
854 ++++ linux-2.6.22.18/drivers/isdn/hardware/avm/c4.c 2008-02-11 08:31:19.000000000 +0100
855 +@@ -727,6 +727,7 @@ static void c4_send_init(avmcard *card)
856 + {
857 + struct sk_buff *skb;
858 + void *p;
859 ++ unsigned long flags;
860 +
861 + skb = alloc_skb(15, GFP_ATOMIC);
862 + if (!skb) {
863 +@@ -744,12 +745,15 @@ static void c4_send_init(avmcard *card)
864 + skb_put(skb, (u8 *)p - (u8 *)skb->data);
865 +
866 + skb_queue_tail(&card->dma->send_queue, skb);
867 ++ spin_lock_irqsave(&card->lock, flags);
868 + c4_dispatch_tx(card);
869 ++ spin_unlock_irqrestore(&card->lock, flags);
870 + }
871 +
872 + static int queue_sendconfigword(avmcard *card, u32 val)
873 + {
874 + struct sk_buff *skb;
875 ++ unsigned long flags;
876 + void *p;
877 +
878 + skb = alloc_skb(3+4, GFP_ATOMIC);
879 +@@ -766,7 +770,9 @@ static int queue_sendconfigword(avmcard
880 + skb_put(skb, (u8 *)p - (u8 *)skb->data);
881 +
882 + skb_queue_tail(&card->dma->send_queue, skb);
883 ++ spin_lock_irqsave(&card->lock, flags);
884 + c4_dispatch_tx(card);
885 ++ spin_unlock_irqrestore(&card->lock, flags);
886 + return 0;
887 + }
888 +
889 +@@ -986,7 +992,9 @@ static void c4_release_appl(struct capi_
890 + struct sk_buff *skb;
891 + void *p;
892 +
893 ++ spin_lock_irqsave(&card->lock, flags);
894 + capilib_release_appl(&cinfo->ncci_head, appl);
895 ++ spin_unlock_irqrestore(&card->lock, flags);
896 +
897 + if (ctrl->cnr == card->cardnr) {
898 + skb = alloc_skb(7, GFP_ATOMIC);
899 +@@ -1019,7 +1027,8 @@ static u16 c4_send_message(struct capi_c
900 + u16 retval = CAPI_NOERROR;
901 + unsigned long flags;
902 +
903 +- if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
904 ++ spin_lock_irqsave(&card->lock, flags);
905 ++ if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
906 + retval = capilib_data_b3_req(&cinfo->ncci_head,
907 + CAPIMSG_APPID(skb->data),
908 + CAPIMSG_NCCI(skb->data),
909 +@@ -1027,10 +1036,9 @@ static u16 c4_send_message(struct capi_c
910 + }
911 + if (retval == CAPI_NOERROR) {
912 + skb_queue_tail(&card->dma->send_queue, skb);
913 +- spin_lock_irqsave(&card->lock, flags);
914 + c4_dispatch_tx(card);
915 +- spin_unlock_irqrestore(&card->lock, flags);
916 + }
917 ++ spin_unlock_irqrestore(&card->lock, flags);
918 + return retval;
919 + }
920 +
921 +diff -NurpP linux-2.6.22.12/drivers/isdn/i4l/isdn_common.c linux-2.6.22.18/drivers/isdn/i4l/isdn_common.c
922 +--- linux-2.6.22.12/drivers/isdn/i4l/isdn_common.c 2007-11-05 18:59:33.000000000 +0100
923 ++++ linux-2.6.22.18/drivers/isdn/i4l/isdn_common.c 2008-02-11 08:31:19.000000000 +0100
924 +@@ -1514,6 +1514,7 @@ isdn_ioctl(struct inode *inode, struct f
925 + if (copy_from_user(&iocts, argp,
926 + sizeof(isdn_ioctl_struct)))
927 + return -EFAULT;
928 ++ iocts.drvid[sizeof(iocts.drvid)-1] = 0;
929 + if (strlen(iocts.drvid)) {
930 + if ((p = strchr(iocts.drvid, ',')))
931 + *p = 0;
932 +@@ -1598,6 +1599,7 @@ isdn_ioctl(struct inode *inode, struct f
933 + if (copy_from_user(&iocts, argp,
934 + sizeof(isdn_ioctl_struct)))
935 + return -EFAULT;
936 ++ iocts.drvid[sizeof(iocts.drvid)-1] = 0;
937 + if (strlen(iocts.drvid)) {
938 + drvidx = -1;
939 + for (i = 0; i < ISDN_MAX_DRIVERS; i++)
940 +@@ -1642,7 +1644,7 @@ isdn_ioctl(struct inode *inode, struct f
941 + } else {
942 + p = (char __user *) iocts.arg;
943 + for (i = 0; i < 10; i++) {
944 +- sprintf(bname, "%s%s",
945 ++ snprintf(bname, sizeof(bname), "%s%s",
946 + strlen(dev->drv[drvidx]->msn2eaz[i]) ?
947 + dev->drv[drvidx]->msn2eaz[i] : "_",
948 + (i < 9) ? "," : "\0");
949 +@@ -1672,6 +1674,7 @@ isdn_ioctl(struct inode *inode, struct f
950 + char *p;
951 + if (copy_from_user(&iocts, argp, sizeof(isdn_ioctl_struct)))
952 + return -EFAULT;
953 ++ iocts.drvid[sizeof(iocts.drvid)-1] = 0;
954 + if (strlen(iocts.drvid)) {
955 + if ((p = strchr(iocts.drvid, ',')))
956 + *p = 0;
957 +diff -NurpP linux-2.6.22.12/drivers/isdn/i4l/isdn_net.c linux-2.6.22.18/drivers/isdn/i4l/isdn_net.c
958 +--- linux-2.6.22.12/drivers/isdn/i4l/isdn_net.c 2007-11-05 18:59:33.000000000 +0100
959 ++++ linux-2.6.22.18/drivers/isdn/i4l/isdn_net.c 2008-02-11 08:31:19.000000000 +0100
960 +@@ -2126,7 +2126,7 @@ isdn_net_find_icall(int di, int ch, int
961 + u_long flags;
962 + isdn_net_dev *p;
963 + isdn_net_phone *n;
964 +- char nr[32];
965 ++ char nr[ISDN_MSNLEN];
966 + char *my_eaz;
967 +
968 + /* Search name in netdev-chain */
969 +@@ -2135,7 +2135,7 @@ isdn_net_find_icall(int di, int ch, int
970 + nr[1] = '\0';
971 + printk(KERN_INFO "isdn_net: Incoming call without OAD, assuming '0'\n");
972 + } else
973 +- strcpy(nr, setup->phone);
974 ++ strlcpy(nr, setup->phone, ISDN_MSNLEN);
975 + si1 = (int) setup->si1;
976 + si2 = (int) setup->si2;
977 + if (!setup->eazmsn[0]) {
978 +@@ -2802,7 +2802,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg
979 + chidx = -1;
980 + }
981 + }
982 +- strcpy(lp->msn, cfg->eaz);
983 ++ strlcpy(lp->msn, cfg->eaz, sizeof(lp->msn));
984 + lp->pre_device = drvidx;
985 + lp->pre_channel = chidx;
986 + lp->onhtime = cfg->onhtime;
987 +@@ -2951,7 +2951,7 @@ isdn_net_addphone(isdn_net_ioctl_phone *
988 + if (p) {
989 + if (!(n = kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
990 + return -ENOMEM;
991 +- strcpy(n->num, phone->phone);
992 ++ strlcpy(n->num, phone->phone, sizeof(n->num));
993 + n->next = p->local->phone[phone->outgoing & 1];
994 + p->local->phone[phone->outgoing & 1] = n;
995 + return 0;
996 +diff -NurpP linux-2.6.22.12/drivers/net/atl1/atl1_main.c linux-2.6.22.18/drivers/net/atl1/atl1_main.c
997 +--- linux-2.6.22.12/drivers/net/atl1/atl1_main.c 2007-11-05 18:59:33.000000000 +0100
998 ++++ linux-2.6.22.18/drivers/net/atl1/atl1_main.c 2008-02-11 08:31:19.000000000 +0100
999 +@@ -2097,21 +2097,26 @@ static int __devinit atl1_probe(struct p
1000 + struct net_device *netdev;
1001 + struct atl1_adapter *adapter;
1002 + static int cards_found = 0;
1003 +- bool pci_using_64 = true;
1004 + int err;
1005 +
1006 + err = pci_enable_device(pdev);
1007 + if (err)
1008 + return err;
1009 +
1010 +- err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
1011 ++ /*
1012 ++ * The atl1 chip can DMA to 64-bit addresses, but it uses a single
1013 ++ * shared register for the high 32 bits, so only a single, aligned,
1014 ++ * 4 GB physical address range can be used at a time.
1015 ++ *
1016 ++ * Supporting 64-bit DMA on this hardware is more trouble than it's
1017 ++ * worth. It is far easier to limit to 32-bit DMA than update
1018 ++ * various kernel subsystems to support the mechanics required by a
1019 ++ * fixed-high-32-bit system.
1020 ++ */
1021 ++ err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
1022 + if (err) {
1023 +- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
1024 +- if (err) {
1025 +- dev_err(&pdev->dev, "no usable DMA configuration\n");
1026 +- goto err_dma;
1027 +- }
1028 +- pci_using_64 = false;
1029 ++ dev_err(&pdev->dev, "no usable DMA configuration\n");
1030 ++ goto err_dma;
1031 + }
1032 + /* Mark all PCI regions associated with PCI device
1033 + * pdev as being reserved by owner atl1_driver_name
1034 +@@ -2176,7 +2181,6 @@ static int __devinit atl1_probe(struct p
1035 +
1036 + netdev->ethtool_ops = &atl1_ethtool_ops;
1037 + adapter->bd_number = cards_found;
1038 +- adapter->pci_using_64 = pci_using_64;
1039 +
1040 + /* setup the private structure */
1041 + err = atl1_sw_init(adapter);
1042 +@@ -2193,9 +2197,6 @@ static int __devinit atl1_probe(struct p
1043 + */
1044 + /* netdev->features |= NETIF_F_TSO; */
1045 +
1046 +- if (pci_using_64)
1047 +- netdev->features |= NETIF_F_HIGHDMA;
1048 +-
1049 + netdev->features |= NETIF_F_LLTX;
1050 +
1051 + /*
1052 +diff -NurpP linux-2.6.22.12/drivers/net/cassini.c linux-2.6.22.18/drivers/net/cassini.c
1053 +--- linux-2.6.22.12/drivers/net/cassini.c 2007-11-05 18:59:33.000000000 +0100
1054 ++++ linux-2.6.22.18/drivers/net/cassini.c 2008-02-11 08:31:19.000000000 +0100
1055 +@@ -336,30 +336,6 @@ static inline void cas_mask_intr(struct
1056 + cas_disable_irq(cp, i);
1057 + }
1058 +
1059 +-static inline void cas_buffer_init(cas_page_t *cp)
1060 +-{
1061 +- struct page *page = cp->buffer;
1062 +- atomic_set((atomic_t *)&page->lru.next, 1);
1063 +-}
1064 +-
1065 +-static inline int cas_buffer_count(cas_page_t *cp)
1066 +-{
1067 +- struct page *page = cp->buffer;
1068 +- return atomic_read((atomic_t *)&page->lru.next);
1069 +-}
1070 +-
1071 +-static inline void cas_buffer_inc(cas_page_t *cp)
1072 +-{
1073 +- struct page *page = cp->buffer;
1074 +- atomic_inc((atomic_t *)&page->lru.next);
1075 +-}
1076 +-
1077 +-static inline void cas_buffer_dec(cas_page_t *cp)
1078 +-{
1079 +- struct page *page = cp->buffer;
1080 +- atomic_dec((atomic_t *)&page->lru.next);
1081 +-}
1082 +-
1083 + static void cas_enable_irq(struct cas *cp, const int ring)
1084 + {
1085 + if (ring == 0) { /* all but TX_DONE */
1086 +@@ -497,7 +473,6 @@ static int cas_page_free(struct cas *cp,
1087 + {
1088 + pci_unmap_page(cp->pdev, page->dma_addr, cp->page_size,
1089 + PCI_DMA_FROMDEVICE);
1090 +- cas_buffer_dec(page);
1091 + __free_pages(page->buffer, cp->page_order);
1092 + kfree(page);
1093 + return 0;
1094 +@@ -527,7 +502,6 @@ static cas_page_t *cas_page_alloc(struct
1095 + page->buffer = alloc_pages(flags, cp->page_order);
1096 + if (!page->buffer)
1097 + goto page_err;
1098 +- cas_buffer_init(page);
1099 + page->dma_addr = pci_map_page(cp->pdev, page->buffer, 0,
1100 + cp->page_size, PCI_DMA_FROMDEVICE);
1101 + return page;
1102 +@@ -606,7 +580,7 @@ static void cas_spare_recover(struct cas
1103 + list_for_each_safe(elem, tmp, &list) {
1104 + cas_page_t *page = list_entry(elem, cas_page_t, list);
1105 +
1106 +- if (cas_buffer_count(page) > 1)
1107 ++ if (page_count(page->buffer) > 1)
1108 + continue;
1109 +
1110 + list_del(elem);
1111 +@@ -1374,7 +1348,7 @@ static inline cas_page_t *cas_page_spare
1112 + cas_page_t *page = cp->rx_pages[1][index];
1113 + cas_page_t *new;
1114 +
1115 +- if (cas_buffer_count(page) == 1)
1116 ++ if (page_count(page->buffer) == 1)
1117 + return page;
1118 +
1119 + new = cas_page_dequeue(cp);
1120 +@@ -1394,7 +1368,7 @@ static cas_page_t *cas_page_swap(struct
1121 + cas_page_t **page1 = cp->rx_pages[1];
1122 +
1123 + /* swap if buffer is in use */
1124 +- if (cas_buffer_count(page0[index]) > 1) {
1125 ++ if (page_count(page0[index]->buffer) > 1) {
1126 + cas_page_t *new = cas_page_spare(cp, index);
1127 + if (new) {
1128 + page1[index] = page0[index];
1129 +@@ -1979,6 +1953,7 @@ static int cas_rx_process_pkt(struct cas
1130 + struct cas_page *page;
1131 + struct sk_buff *skb;
1132 + void *addr, *crcaddr;
1133 ++ __sum16 csum;
1134 + char *p;
1135 +
1136 + hlen = CAS_VAL(RX_COMP2_HDR_SIZE, words[1]);
1137 +@@ -2062,10 +2037,10 @@ static int cas_rx_process_pkt(struct cas
1138 +
1139 + skb_shinfo(skb)->nr_frags++;
1140 + skb->data_len += hlen - swivel;
1141 ++ skb->truesize += hlen - swivel;
1142 + skb->len += hlen - swivel;
1143 +
1144 + get_page(page->buffer);
1145 +- cas_buffer_inc(page);
1146 + frag->page = page->buffer;
1147 + frag->page_offset = off;
1148 + frag->size = hlen - swivel;
1149 +@@ -2090,7 +2065,6 @@ static int cas_rx_process_pkt(struct cas
1150 + frag++;
1151 +
1152 + get_page(page->buffer);
1153 +- cas_buffer_inc(page);
1154 + frag->page = page->buffer;
1155 + frag->page_offset = 0;
1156 + frag->size = hlen;
1157 +@@ -2158,14 +2132,15 @@ end_copy_pkt:
1158 + skb_put(skb, alloclen);
1159 + }
1160 +
1161 +- i = CAS_VAL(RX_COMP4_TCP_CSUM, words[3]);
1162 ++ csum = (__force __sum16)htons(CAS_VAL(RX_COMP4_TCP_CSUM, words[3]));
1163 + if (cp->crc_size) {
1164 + /* checksum includes FCS. strip it out. */
1165 +- i = csum_fold(csum_partial(crcaddr, cp->crc_size, i));
1166 ++ csum = csum_fold(csum_partial(crcaddr, cp->crc_size,
1167 ++ csum_unfold(csum)));
1168 + if (addr)
1169 + cas_page_unmap(addr);
1170 + }
1171 +- skb->csum = ntohs(i ^ 0xffff);
1172 ++ skb->csum = csum_unfold(~csum);
1173 + skb->ip_summed = CHECKSUM_COMPLETE;
1174 + skb->protocol = eth_type_trans(skb, cp->dev);
1175 + return len;
1176 +@@ -2253,7 +2228,7 @@ static int cas_post_rxds_ringN(struct ca
1177 + released = 0;
1178 + while (entry != last) {
1179 + /* make a new buffer if it's still in use */
1180 +- if (cas_buffer_count(page[entry]) > 1) {
1181 ++ if (page_count(page[entry]->buffer) > 1) {
1182 + cas_page_t *new = cas_page_dequeue(cp);
1183 + if (!new) {
1184 + /* let the timer know that we need to
1185 +diff -NurpP linux-2.6.22.12/drivers/net/cassini.h linux-2.6.22.18/drivers/net/cassini.h
1186 +--- linux-2.6.22.12/drivers/net/cassini.h 2007-11-05 18:59:33.000000000 +0100
1187 ++++ linux-2.6.22.18/drivers/net/cassini.h 2008-02-11 08:31:19.000000000 +0100
1188 +@@ -4122,8 +4122,8 @@ cas_saturn_patch_t cas_saturn_patch[] =
1189 + inserted into
1190 + outgoing frame. */
1191 + struct cas_tx_desc {
1192 +- u64 control;
1193 +- u64 buffer;
1194 ++ __le64 control;
1195 ++ __le64 buffer;
1196 + };
1197 +
1198 + /* descriptor ring for free buffers contains page-sized buffers. the index
1199 +@@ -4131,8 +4131,8 @@ struct cas_tx_desc {
1200 + * the completion ring.
1201 + */
1202 + struct cas_rx_desc {
1203 +- u64 index;
1204 +- u64 buffer;
1205 ++ __le64 index;
1206 ++ __le64 buffer;
1207 + };
1208 +
1209 + /* received packets are put on the completion ring. */
1210 +@@ -4210,10 +4210,10 @@ struct cas_rx_desc {
1211 + #define RX_INDEX_RELEASE 0x0000000000002000ULL
1212 +
1213 + struct cas_rx_comp {
1214 +- u64 word1;
1215 +- u64 word2;
1216 +- u64 word3;
1217 +- u64 word4;
1218 ++ __le64 word1;
1219 ++ __le64 word2;
1220 ++ __le64 word3;
1221 ++ __le64 word4;
1222 + };
1223 +
1224 + enum link_state {
1225 +@@ -4252,7 +4252,7 @@ struct cas_init_block {
1226 + struct cas_rx_comp rxcs[N_RX_COMP_RINGS][INIT_BLOCK_RX_COMP];
1227 + struct cas_rx_desc rxds[N_RX_DESC_RINGS][INIT_BLOCK_RX_DESC];
1228 + struct cas_tx_desc txds[N_TX_RINGS][INIT_BLOCK_TX];
1229 +- u64 tx_compwb;
1230 ++ __le64 tx_compwb;
1231 + };
1232 +
1233 + /* tiny buffers to deal with target abort issue. we allocate a bit
1234 +diff -NurpP linux-2.6.22.12/drivers/net/chelsio/cxgb2.c linux-2.6.22.18/drivers/net/chelsio/cxgb2.c
1235 +--- linux-2.6.22.12/drivers/net/chelsio/cxgb2.c 2007-11-05 18:59:33.000000000 +0100
1236 ++++ linux-2.6.22.18/drivers/net/chelsio/cxgb2.c 2008-02-11 08:31:19.000000000 +0100
1237 +@@ -370,6 +370,8 @@ static char stats_strings[][ETH_GSTRING_
1238 + "TxInternalMACXmitError",
1239 + "TxFramesWithExcessiveDeferral",
1240 + "TxFCSErrors",
1241 ++ "TxJumboFramesOk",
1242 ++ "TxJumboOctetsOk",
1243 +
1244 + "RxOctetsOK",
1245 + "RxOctetsBad",
1246 +@@ -388,15 +390,16 @@ static char stats_strings[][ETH_GSTRING_
1247 + "RxInRangeLengthErrors",
1248 + "RxOutOfRangeLengthField",
1249 + "RxFrameTooLongErrors",
1250 ++ "RxJumboFramesOk",
1251 ++ "RxJumboOctetsOk",
1252 +
1253 + /* Port stats */
1254 +- "RxPackets",
1255 + "RxCsumGood",
1256 +- "TxPackets",
1257 + "TxCsumOffload",
1258 + "TxTso",
1259 + "RxVlan",
1260 + "TxVlan",
1261 ++ "TxNeedHeadroom",
1262 +
1263 + /* Interrupt stats */
1264 + "rx drops",
1265 +@@ -454,23 +457,56 @@ static void get_stats(struct net_device
1266 + const struct cmac_statistics *s;
1267 + const struct sge_intr_counts *t;
1268 + struct sge_port_stats ss;
1269 +- unsigned int len;
1270 +
1271 + s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL);
1272 +-
1273 +- len = sizeof(u64)*(&s->TxFCSErrors + 1 - &s->TxOctetsOK);
1274 +- memcpy(data, &s->TxOctetsOK, len);
1275 +- data += len;
1276 +-
1277 +- len = sizeof(u64)*(&s->RxFrameTooLongErrors + 1 - &s->RxOctetsOK);
1278 +- memcpy(data, &s->RxOctetsOK, len);
1279 +- data += len;
1280 +-
1281 ++ t = t1_sge_get_intr_counts(adapter->sge);
1282 + t1_sge_get_port_stats(adapter->sge, dev->if_port, &ss);
1283 +- memcpy(data, &ss, sizeof(ss));
1284 +- data += sizeof(ss);
1285 +
1286 +- t = t1_sge_get_intr_counts(adapter->sge);
1287 ++ *data++ = s->TxOctetsOK;
1288 ++ *data++ = s->TxOctetsBad;
1289 ++ *data++ = s->TxUnicastFramesOK;
1290 ++ *data++ = s->TxMulticastFramesOK;
1291 ++ *data++ = s->TxBroadcastFramesOK;
1292 ++ *data++ = s->TxPauseFrames;
1293 ++ *data++ = s->TxFramesWithDeferredXmissions;
1294 ++ *data++ = s->TxLateCollisions;
1295 ++ *data++ = s->TxTotalCollisions;
1296 ++ *data++ = s->TxFramesAbortedDueToXSCollisions;
1297 ++ *data++ = s->TxUnderrun;
1298 ++ *data++ = s->TxLengthErrors;
1299 ++ *data++ = s->TxInternalMACXmitError;
1300 ++ *data++ = s->TxFramesWithExcessiveDeferral;
1301 ++ *data++ = s->TxFCSErrors;
1302 ++ *data++ = s->TxJumboFramesOK;
1303 ++ *data++ = s->TxJumboOctetsOK;
1304 ++
1305 ++ *data++ = s->RxOctetsOK;
1306 ++ *data++ = s->RxOctetsBad;
1307 ++ *data++ = s->RxUnicastFramesOK;
1308 ++ *data++ = s->RxMulticastFramesOK;
1309 ++ *data++ = s->RxBroadcastFramesOK;
1310 ++ *data++ = s->RxPauseFrames;
1311 ++ *data++ = s->RxFCSErrors;
1312 ++ *data++ = s->RxAlignErrors;
1313 ++ *data++ = s->RxSymbolErrors;
1314 ++ *data++ = s->RxDataErrors;
1315 ++ *data++ = s->RxSequenceErrors;
1316 ++ *data++ = s->RxRuntErrors;
1317 ++ *data++ = s->RxJabberErrors;
1318 ++ *data++ = s->RxInternalMACRcvError;
1319 ++ *data++ = s->RxInRangeLengthErrors;
1320 ++ *data++ = s->RxOutOfRangeLengthField;
1321 ++ *data++ = s->RxFrameTooLongErrors;
1322 ++ *data++ = s->RxJumboFramesOK;
1323 ++ *data++ = s->RxJumboOctetsOK;
1324 ++
1325 ++ *data++ = ss.rx_cso_good;
1326 ++ *data++ = ss.tx_cso;
1327 ++ *data++ = ss.tx_tso;
1328 ++ *data++ = ss.vlan_xtract;
1329 ++ *data++ = ss.vlan_insert;
1330 ++ *data++ = ss.tx_need_hdrroom;
1331 ++
1332 + *data++ = t->rx_drops;
1333 + *data++ = t->pure_rsps;
1334 + *data++ = t->unhandled_irqs;
1335 +diff -NurpP linux-2.6.22.12/drivers/net/chelsio/pm3393.c linux-2.6.22.18/drivers/net/chelsio/pm3393.c
1336 +--- linux-2.6.22.12/drivers/net/chelsio/pm3393.c 2007-11-05 18:59:33.000000000 +0100
1337 ++++ linux-2.6.22.18/drivers/net/chelsio/pm3393.c 2008-02-11 08:31:19.000000000 +0100
1338 +@@ -45,7 +45,7 @@
1339 +
1340 + #include <linux/crc32.h>
1341 +
1342 +-#define OFFSET(REG_ADDR) (REG_ADDR << 2)
1343 ++#define OFFSET(REG_ADDR) ((REG_ADDR) << 2)
1344 +
1345 + /* Max frame size PM3393 can handle. Includes Ethernet header and CRC. */
1346 + #define MAX_FRAME_SIZE 9600
1347 +@@ -428,69 +428,26 @@ static int pm3393_set_speed_duplex_fc(st
1348 + return 0;
1349 + }
1350 +
1351 +-static void pm3393_rmon_update(struct adapter *adapter, u32 offs, u64 *val,
1352 +- int over)
1353 +-{
1354 +- u32 val0, val1, val2;
1355 +-
1356 +- t1_tpi_read(adapter, offs, &val0);
1357 +- t1_tpi_read(adapter, offs + 4, &val1);
1358 +- t1_tpi_read(adapter, offs + 8, &val2);
1359 +-
1360 +- *val &= ~0ull << 40;
1361 +- *val |= val0 & 0xffff;
1362 +- *val |= (val1 & 0xffff) << 16;
1363 +- *val |= (u64)(val2 & 0xff) << 32;
1364 +-
1365 +- if (over)
1366 +- *val += 1ull << 40;
1367 ++#define RMON_UPDATE(mac, name, stat_name) \
1368 ++{ \
1369 ++ t1_tpi_read((mac)->adapter, OFFSET(name), &val0); \
1370 ++ t1_tpi_read((mac)->adapter, OFFSET((name)+1), &val1); \
1371 ++ t1_tpi_read((mac)->adapter, OFFSET((name)+2), &val2); \
1372 ++ (mac)->stats.stat_name = (u64)(val0 & 0xffff) | \
1373 ++ ((u64)(val1 & 0xffff) << 16) | \
1374 ++ ((u64)(val2 & 0xff) << 32) | \
1375 ++ ((mac)->stats.stat_name & \
1376 ++ 0xffffff0000000000ULL); \
1377 ++ if (ro & \
1378 ++ (1ULL << ((name - SUNI1x10GEXP_REG_MSTAT_COUNTER_0_LOW) >> 2))) \
1379 ++ (mac)->stats.stat_name += 1ULL << 40; \
1380 + }
1381 +
1382 + static const struct cmac_statistics *pm3393_update_statistics(struct cmac *mac,
1383 + int flag)
1384 + {
1385 +- static struct {
1386 +- unsigned int reg;
1387 +- unsigned int offset;
1388 +- } hw_stats [] = {
1389 +-
1390 +-#define HW_STAT(name, stat_name) \
1391 +- { name, (&((struct cmac_statistics *)NULL)->stat_name) - (u64 *)NULL }
1392 +-
1393 +- /* Rx stats */
1394 +- HW_STAT(RxOctetsReceivedOK, RxOctetsOK),
1395 +- HW_STAT(RxUnicastFramesReceivedOK, RxUnicastFramesOK),
1396 +- HW_STAT(RxMulticastFramesReceivedOK, RxMulticastFramesOK),
1397 +- HW_STAT(RxBroadcastFramesReceivedOK, RxBroadcastFramesOK),
1398 +- HW_STAT(RxPAUSEMACCtrlFramesReceived, RxPauseFrames),
1399 +- HW_STAT(RxFrameCheckSequenceErrors, RxFCSErrors),
1400 +- HW_STAT(RxFramesLostDueToInternalMACErrors,
1401 +- RxInternalMACRcvError),
1402 +- HW_STAT(RxSymbolErrors, RxSymbolErrors),
1403 +- HW_STAT(RxInRangeLengthErrors, RxInRangeLengthErrors),
1404 +- HW_STAT(RxFramesTooLongErrors , RxFrameTooLongErrors),
1405 +- HW_STAT(RxJabbers, RxJabberErrors),
1406 +- HW_STAT(RxFragments, RxRuntErrors),
1407 +- HW_STAT(RxUndersizedFrames, RxRuntErrors),
1408 +- HW_STAT(RxJumboFramesReceivedOK, RxJumboFramesOK),
1409 +- HW_STAT(RxJumboOctetsReceivedOK, RxJumboOctetsOK),
1410 +-
1411 +- /* Tx stats */
1412 +- HW_STAT(TxOctetsTransmittedOK, TxOctetsOK),
1413 +- HW_STAT(TxFramesLostDueToInternalMACTransmissionError,
1414 +- TxInternalMACXmitError),
1415 +- HW_STAT(TxTransmitSystemError, TxFCSErrors),
1416 +- HW_STAT(TxUnicastFramesTransmittedOK, TxUnicastFramesOK),
1417 +- HW_STAT(TxMulticastFramesTransmittedOK, TxMulticastFramesOK),
1418 +- HW_STAT(TxBroadcastFramesTransmittedOK, TxBroadcastFramesOK),
1419 +- HW_STAT(TxPAUSEMACCtrlFramesTransmitted, TxPauseFrames),
1420 +- HW_STAT(TxJumboFramesReceivedOK, TxJumboFramesOK),
1421 +- HW_STAT(TxJumboOctetsReceivedOK, TxJumboOctetsOK)
1422 +- }, *p = hw_stats;
1423 +- u64 ro;
1424 +- u32 val0, val1, val2, val3;
1425 +- u64 *stats = (u64 *) &mac->stats;
1426 +- unsigned int i;
1427 ++ u64 ro;
1428 ++ u32 val0, val1, val2, val3;
1429 +
1430 + /* Snap the counters */
1431 + pmwrite(mac, SUNI1x10GEXP_REG_MSTAT_CONTROL,
1432 +@@ -504,14 +461,35 @@ static const struct cmac_statistics *pm3
1433 + ro = ((u64)val0 & 0xffff) | (((u64)val1 & 0xffff) << 16) |
1434 + (((u64)val2 & 0xffff) << 32) | (((u64)val3 & 0xffff) << 48);
1435 +
1436 +- for (i = 0; i < ARRAY_SIZE(hw_stats); i++) {
1437 +- unsigned reg = p->reg - SUNI1x10GEXP_REG_MSTAT_COUNTER_0_LOW;
1438 +-
1439 +- pm3393_rmon_update((mac)->adapter, OFFSET(p->reg),
1440 +- stats + p->offset, ro & (reg >> 2));
1441 +- }
1442 +-
1443 +-
1444 ++ /* Rx stats */
1445 ++ RMON_UPDATE(mac, RxOctetsReceivedOK, RxOctetsOK);
1446 ++ RMON_UPDATE(mac, RxUnicastFramesReceivedOK, RxUnicastFramesOK);
1447 ++ RMON_UPDATE(mac, RxMulticastFramesReceivedOK, RxMulticastFramesOK);
1448 ++ RMON_UPDATE(mac, RxBroadcastFramesReceivedOK, RxBroadcastFramesOK);
1449 ++ RMON_UPDATE(mac, RxPAUSEMACCtrlFramesReceived, RxPauseFrames);
1450 ++ RMON_UPDATE(mac, RxFrameCheckSequenceErrors, RxFCSErrors);
1451 ++ RMON_UPDATE(mac, RxFramesLostDueToInternalMACErrors,
1452 ++ RxInternalMACRcvError);
1453 ++ RMON_UPDATE(mac, RxSymbolErrors, RxSymbolErrors);
1454 ++ RMON_UPDATE(mac, RxInRangeLengthErrors, RxInRangeLengthErrors);
1455 ++ RMON_UPDATE(mac, RxFramesTooLongErrors , RxFrameTooLongErrors);
1456 ++ RMON_UPDATE(mac, RxJabbers, RxJabberErrors);
1457 ++ RMON_UPDATE(mac, RxFragments, RxRuntErrors);
1458 ++ RMON_UPDATE(mac, RxUndersizedFrames, RxRuntErrors);
1459 ++ RMON_UPDATE(mac, RxJumboFramesReceivedOK, RxJumboFramesOK);
1460 ++ RMON_UPDATE(mac, RxJumboOctetsReceivedOK, RxJumboOctetsOK);
1461 ++
1462 ++ /* Tx stats */
1463 ++ RMON_UPDATE(mac, TxOctetsTransmittedOK, TxOctetsOK);
1464 ++ RMON_UPDATE(mac, TxFramesLostDueToInternalMACTransmissionError,
1465 ++ TxInternalMACXmitError);
1466 ++ RMON_UPDATE(mac, TxTransmitSystemError, TxFCSErrors);
1467 ++ RMON_UPDATE(mac, TxUnicastFramesTransmittedOK, TxUnicastFramesOK);
1468 ++ RMON_UPDATE(mac, TxMulticastFramesTransmittedOK, TxMulticastFramesOK);
1469 ++ RMON_UPDATE(mac, TxBroadcastFramesTransmittedOK, TxBroadcastFramesOK);
1470 ++ RMON_UPDATE(mac, TxPAUSEMACCtrlFramesTransmitted, TxPauseFrames);
1471 ++ RMON_UPDATE(mac, TxJumboFramesReceivedOK, TxJumboFramesOK);
1472 ++ RMON_UPDATE(mac, TxJumboOctetsReceivedOK, TxJumboOctetsOK);
1473 +
1474 + return &mac->stats;
1475 + }
1476 +diff -NurpP linux-2.6.22.12/drivers/net/chelsio/sge.c linux-2.6.22.18/drivers/net/chelsio/sge.c
1477 +--- linux-2.6.22.12/drivers/net/chelsio/sge.c 2007-11-05 18:59:33.000000000 +0100
1478 ++++ linux-2.6.22.18/drivers/net/chelsio/sge.c 2008-02-11 08:31:19.000000000 +0100
1479 +@@ -986,11 +986,10 @@ void t1_sge_get_port_stats(const struct
1480 + for_each_possible_cpu(cpu) {
1481 + struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[port], cpu);
1482 +
1483 +- ss->rx_packets += st->rx_packets;
1484 + ss->rx_cso_good += st->rx_cso_good;
1485 +- ss->tx_packets += st->tx_packets;
1486 + ss->tx_cso += st->tx_cso;
1487 + ss->tx_tso += st->tx_tso;
1488 ++ ss->tx_need_hdrroom += st->tx_need_hdrroom;
1489 + ss->vlan_xtract += st->vlan_xtract;
1490 + ss->vlan_insert += st->vlan_insert;
1491 + }
1492 +@@ -1379,11 +1378,10 @@ static void sge_rx(struct sge *sge, stru
1493 + }
1494 + __skb_pull(skb, sizeof(*p));
1495 +
1496 +- skb->dev->last_rx = jiffies;
1497 + st = per_cpu_ptr(sge->port_stats[p->iff], smp_processor_id());
1498 +- st->rx_packets++;
1499 +
1500 + skb->protocol = eth_type_trans(skb, adapter->port[p->iff].dev);
1501 ++ skb->dev->last_rx = jiffies;
1502 + if ((adapter->flags & RX_CSUM_ENABLED) && p->csum == 0xffff &&
1503 + skb->protocol == htons(ETH_P_IP) &&
1504 + (skb->data[9] == IPPROTO_TCP || skb->data[9] == IPPROTO_UDP)) {
1505 +@@ -1851,7 +1849,8 @@ int t1_start_xmit(struct sk_buff *skb, s
1506 + {
1507 + struct adapter *adapter = dev->priv;
1508 + struct sge *sge = adapter->sge;
1509 +- struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[dev->if_port], smp_processor_id());
1510 ++ struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[dev->if_port],
1511 ++ smp_processor_id());
1512 + struct cpl_tx_pkt *cpl;
1513 + struct sk_buff *orig_skb = skb;
1514 + int ret;
1515 +@@ -1859,6 +1858,18 @@ int t1_start_xmit(struct sk_buff *skb, s
1516 + if (skb->protocol == htons(ETH_P_CPL5))
1517 + goto send;
1518 +
1519 ++ /*
1520 ++ * We are using a non-standard hard_header_len.
1521 ++ * Allocate more header room in the rare cases it is not big enough.
1522 ++ */
1523 ++ if (unlikely(skb_headroom(skb) < dev->hard_header_len - ETH_HLEN)) {
1524 ++ skb = skb_realloc_headroom(skb, sizeof(struct cpl_tx_pkt_lso));
1525 ++ ++st->tx_need_hdrroom;
1526 ++ dev_kfree_skb_any(orig_skb);
1527 ++ if (!skb)
1528 ++ return NETDEV_TX_OK;
1529 ++ }
1530 ++
1531 + if (skb_shinfo(skb)->gso_size) {
1532 + int eth_type;
1533 + struct cpl_tx_pkt_lso *hdr;
1534 +@@ -1892,24 +1903,6 @@ int t1_start_xmit(struct sk_buff *skb, s
1535 + return NETDEV_TX_OK;
1536 + }
1537 +
1538 +- /*
1539 +- * We are using a non-standard hard_header_len and some kernel
1540 +- * components, such as pktgen, do not handle it right.
1541 +- * Complain when this happens but try to fix things up.
1542 +- */
1543 +- if (unlikely(skb_headroom(skb) < dev->hard_header_len - ETH_HLEN)) {
1544 +- pr_debug("%s: headroom %d header_len %d\n", dev->name,
1545 +- skb_headroom(skb), dev->hard_header_len);
1546 +-
1547 +- if (net_ratelimit())
1548 +- printk(KERN_ERR "%s: inadequate headroom in "
1549 +- "Tx packet\n", dev->name);
1550 +- skb = skb_realloc_headroom(skb, sizeof(*cpl));
1551 +- dev_kfree_skb_any(orig_skb);
1552 +- if (!skb)
1553 +- return NETDEV_TX_OK;
1554 +- }
1555 +-
1556 + if (!(adapter->flags & UDP_CSUM_CAPABLE) &&
1557 + skb->ip_summed == CHECKSUM_PARTIAL &&
1558 + ip_hdr(skb)->protocol == IPPROTO_UDP) {
1559 +@@ -1955,7 +1948,6 @@ int t1_start_xmit(struct sk_buff *skb, s
1560 + cpl->vlan_valid = 0;
1561 +
1562 + send:
1563 +- st->tx_packets++;
1564 + dev->trans_start = jiffies;
1565 + ret = t1_sge_tx(skb, adapter, 0, dev);
1566 +
1567 +diff -NurpP linux-2.6.22.12/drivers/net/chelsio/sge.h linux-2.6.22.18/drivers/net/chelsio/sge.h
1568 +--- linux-2.6.22.12/drivers/net/chelsio/sge.h 2007-11-05 18:59:33.000000000 +0100
1569 ++++ linux-2.6.22.18/drivers/net/chelsio/sge.h 2008-02-11 08:31:19.000000000 +0100
1570 +@@ -57,13 +57,12 @@ struct sge_intr_counts {
1571 + };
1572 +
1573 + struct sge_port_stats {
1574 +- u64 rx_packets; /* # of Ethernet packets received */
1575 + u64 rx_cso_good; /* # of successful RX csum offloads */
1576 +- u64 tx_packets; /* # of TX packets */
1577 + u64 tx_cso; /* # of TX checksum offloads */
1578 + u64 tx_tso; /* # of TSO requests */
1579 + u64 vlan_xtract; /* # of VLAN tag extractions */
1580 + u64 vlan_insert; /* # of VLAN tag insertions */
1581 ++ u64 tx_need_hdrroom; /* # of TX skbs in need of more header room */
1582 + };
1583 +
1584 + struct sk_buff;
1585 +diff -NurpP linux-2.6.22.12/drivers/net/forcedeth.c linux-2.6.22.18/drivers/net/forcedeth.c
1586 +--- linux-2.6.22.12/drivers/net/forcedeth.c 2007-11-05 18:59:33.000000000 +0100
1587 ++++ linux-2.6.22.18/drivers/net/forcedeth.c 2008-02-11 08:31:19.000000000 +0100
1588 +@@ -987,7 +987,7 @@ static void nv_enable_irq(struct net_dev
1589 + if (np->msi_flags & NV_MSI_X_ENABLED)
1590 + enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
1591 + else
1592 +- enable_irq(dev->irq);
1593 ++ enable_irq(np->pci_dev->irq);
1594 + } else {
1595 + enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
1596 + enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
1597 +@@ -1003,7 +1003,7 @@ static void nv_disable_irq(struct net_de
1598 + if (np->msi_flags & NV_MSI_X_ENABLED)
1599 + disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
1600 + else
1601 +- disable_irq(dev->irq);
1602 ++ disable_irq(np->pci_dev->irq);
1603 + } else {
1604 + disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
1605 + disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
1606 +@@ -1600,7 +1600,7 @@ static void nv_do_rx_refill(unsigned lon
1607 + if (np->msi_flags & NV_MSI_X_ENABLED)
1608 + disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
1609 + else
1610 +- disable_irq(dev->irq);
1611 ++ disable_irq(np->pci_dev->irq);
1612 + } else {
1613 + disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
1614 + }
1615 +@@ -1618,7 +1618,7 @@ static void nv_do_rx_refill(unsigned lon
1616 + if (np->msi_flags & NV_MSI_X_ENABLED)
1617 + enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
1618 + else
1619 +- enable_irq(dev->irq);
1620 ++ enable_irq(np->pci_dev->irq);
1621 + } else {
1622 + enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
1623 + }
1624 +@@ -3556,10 +3556,12 @@ static int nv_request_irq(struct net_dev
1625 + if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
1626 + if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
1627 + np->msi_flags |= NV_MSI_ENABLED;
1628 ++ dev->irq = np->pci_dev->irq;
1629 + if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) {
1630 + printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
1631 + pci_disable_msi(np->pci_dev);
1632 + np->msi_flags &= ~NV_MSI_ENABLED;
1633 ++ dev->irq = np->pci_dev->irq;
1634 + goto out_err;
1635 + }
1636 +
1637 +@@ -3622,7 +3624,7 @@ static void nv_do_nic_poll(unsigned long
1638 + if (np->msi_flags & NV_MSI_X_ENABLED)
1639 + disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
1640 + else
1641 +- disable_irq_lockdep(dev->irq);
1642 ++ disable_irq_lockdep(np->pci_dev->irq);
1643 + mask = np->irqmask;
1644 + } else {
1645 + if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
1646 +@@ -3640,6 +3642,8 @@ static void nv_do_nic_poll(unsigned long
1647 + }
1648 + np->nic_poll_irq = 0;
1649 +
1650 ++ /* disable_irq() contains synchronize_irq, thus no irq handler can run now */
1651 ++
1652 + if (np->recover_error) {
1653 + np->recover_error = 0;
1654 + printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
1655 +@@ -3676,7 +3680,6 @@ static void nv_do_nic_poll(unsigned long
1656 + }
1657 + }
1658 +
1659 +- /* FIXME: Do we need synchronize_irq(dev->irq) here? */
1660 +
1661 + writel(mask, base + NvRegIrqMask);
1662 + pci_push(base);
1663 +@@ -3689,7 +3692,7 @@ static void nv_do_nic_poll(unsigned long
1664 + if (np->msi_flags & NV_MSI_X_ENABLED)
1665 + enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
1666 + else
1667 +- enable_irq_lockdep(dev->irq);
1668 ++ enable_irq_lockdep(np->pci_dev->irq);
1669 + } else {
1670 + if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
1671 + nv_nic_irq_rx(0, dev);
1672 +@@ -4943,7 +4946,7 @@ static int nv_close(struct net_device *d
1673 + np->in_shutdown = 1;
1674 + spin_unlock_irq(&np->lock);
1675 + netif_poll_disable(dev);
1676 +- synchronize_irq(dev->irq);
1677 ++ synchronize_irq(np->pci_dev->irq);
1678 +
1679 + del_timer_sync(&np->oom_kick);
1680 + del_timer_sync(&np->nic_poll);
1681 +@@ -5280,19 +5283,15 @@ static int __devinit nv_probe(struct pci
1682 + if (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_PHY_INIT) {
1683 + np->mac_in_use = readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_MGMT_ST;
1684 + dprintk(KERN_INFO "%s: mgmt unit is running. mac in use %x.\n", pci_name(pci_dev), np->mac_in_use);
1685 +- for (i = 0; i < 5000; i++) {
1686 +- msleep(1);
1687 +- if (nv_mgmt_acquire_sema(dev)) {
1688 +- /* management unit setup the phy already? */
1689 +- if ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
1690 +- NVREG_XMITCTL_SYNC_PHY_INIT) {
1691 +- /* phy is inited by mgmt unit */
1692 +- phyinitialized = 1;
1693 +- dprintk(KERN_INFO "%s: Phy already initialized by mgmt unit.\n", pci_name(pci_dev));
1694 +- } else {
1695 +- /* we need to init the phy */
1696 +- }
1697 +- break;
1698 ++ if (nv_mgmt_acquire_sema(dev)) {
1699 ++ /* management unit setup the phy already? */
1700 ++ if ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
1701 ++ NVREG_XMITCTL_SYNC_PHY_INIT) {
1702 ++ /* phy is inited by mgmt unit */
1703 ++ phyinitialized = 1;
1704 ++ dprintk(KERN_INFO "%s: Phy already initialized by mgmt unit.\n", pci_name(pci_dev));
1705 ++ } else {
1706 ++ /* we need to init the phy */
1707 + }
1708 + }
1709 + }
1710 +@@ -5550,6 +5549,22 @@ static struct pci_device_id pci_tbl[] =
1711 + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27),
1712 + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
1713 + },
1714 ++ { /* MCP79 Ethernet Controller */
1715 ++ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
1716 ++ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
1717 ++ },
1718 ++ { /* MCP79 Ethernet Controller */
1719 ++ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
1720 ++ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
1721 ++ },
1722 ++ { /* MCP79 Ethernet Controller */
1723 ++ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
1724 ++ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
1725 ++ },
1726 ++ { /* MCP79 Ethernet Controller */
1727 ++ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
1728 ++ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
1729 ++ },
1730 + {0,},
1731 + };
1732 +
1733 +diff -NurpP linux-2.6.22.12/drivers/net/usb/kaweth.c linux-2.6.22.18/drivers/net/usb/kaweth.c
1734 +--- linux-2.6.22.12/drivers/net/usb/kaweth.c 2007-11-05 18:59:33.000000000 +0100
1735 ++++ linux-2.6.22.18/drivers/net/usb/kaweth.c 2008-02-11 08:31:19.000000000 +0100
1736 +@@ -70,7 +70,7 @@
1737 + #define KAWETH_TX_TIMEOUT (5 * HZ)
1738 + #define KAWETH_SCRATCH_SIZE 32
1739 + #define KAWETH_FIRMWARE_BUF_SIZE 4096
1740 +-#define KAWETH_CONTROL_TIMEOUT (30 * HZ)
1741 ++#define KAWETH_CONTROL_TIMEOUT (30000)
1742 +
1743 + #define KAWETH_STATUS_BROKEN 0x0000001
1744 + #define KAWETH_STATUS_CLOSING 0x0000002
1745 +diff -NurpP linux-2.6.22.12/drivers/net/usb/mcs7830.c linux-2.6.22.18/drivers/net/usb/mcs7830.c
1746 +--- linux-2.6.22.12/drivers/net/usb/mcs7830.c 2007-11-05 18:59:33.000000000 +0100
1747 ++++ linux-2.6.22.18/drivers/net/usb/mcs7830.c 2008-02-11 08:31:19.000000000 +0100
1748 +@@ -94,7 +94,7 @@ static int mcs7830_get_reg(struct usbnet
1749 +
1750 + ret = usb_control_msg(xdev, usb_rcvctrlpipe(xdev, 0), MCS7830_RD_BREQ,
1751 + MCS7830_RD_BMREQ, 0x0000, index, data,
1752 +- size, msecs_to_jiffies(MCS7830_CTRL_TIMEOUT));
1753 ++ size, MCS7830_CTRL_TIMEOUT);
1754 + return ret;
1755 + }
1756 +
1757 +@@ -105,7 +105,7 @@ static int mcs7830_set_reg(struct usbnet
1758 +
1759 + ret = usb_control_msg(xdev, usb_sndctrlpipe(xdev, 0), MCS7830_WR_BREQ,
1760 + MCS7830_WR_BMREQ, 0x0000, index, data,
1761 +- size, msecs_to_jiffies(MCS7830_CTRL_TIMEOUT));
1762 ++ size, MCS7830_CTRL_TIMEOUT);
1763 + return ret;
1764 + }
1765 +
1766 +diff -NurpP linux-2.6.22.12/drivers/pci/quirks.c linux-2.6.22.18/drivers/pci/quirks.c
1767 +--- linux-2.6.22.12/drivers/pci/quirks.c 2007-11-05 18:59:33.000000000 +0100
1768 ++++ linux-2.6.22.18/drivers/pci/quirks.c 2008-02-11 08:31:19.000000000 +0100
1769 +@@ -465,6 +465,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
1770 + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, quirk_ich6_lpc_acpi );
1771 + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, quirk_ich6_lpc_acpi );
1772 + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, quirk_ich6_lpc_acpi );
1773 ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1, quirk_ich6_lpc_acpi );
1774 ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_4, quirk_ich6_lpc_acpi );
1775 ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_2, quirk_ich6_lpc_acpi );
1776 ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_4, quirk_ich6_lpc_acpi );
1777 ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_7, quirk_ich6_lpc_acpi );
1778 ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_8, quirk_ich6_lpc_acpi );
1779 +
1780 + /*
1781 + * VIA ACPI: One IO region pointed to by longword at
1782 +diff -NurpP linux-2.6.22.12/drivers/scsi/hptiop.c linux-2.6.22.18/drivers/scsi/hptiop.c
1783 +--- linux-2.6.22.12/drivers/scsi/hptiop.c 2007-11-05 18:59:33.000000000 +0100
1784 ++++ linux-2.6.22.18/drivers/scsi/hptiop.c 2008-02-11 08:31:19.000000000 +0100
1785 +@@ -377,8 +377,9 @@ static void hptiop_host_request_callback
1786 + scp->result = SAM_STAT_CHECK_CONDITION;
1787 + memset(&scp->sense_buffer,
1788 + 0, sizeof(scp->sense_buffer));
1789 +- memcpy(&scp->sense_buffer,
1790 +- &req->sg_list, le32_to_cpu(req->dataxfer_length));
1791 ++ memcpy(&scp->sense_buffer, &req->sg_list,
1792 ++ min(sizeof(scp->sense_buffer),
1793 ++ le32_to_cpu(req->dataxfer_length)));
1794 + break;
1795 +
1796 + default:
1797 +diff -NurpP linux-2.6.22.12/drivers/usb/core/hcd.h linux-2.6.22.18/drivers/usb/core/hcd.h
1798 +--- linux-2.6.22.12/drivers/usb/core/hcd.h 2007-11-05 18:59:33.000000000 +0100
1799 ++++ linux-2.6.22.18/drivers/usb/core/hcd.h 2008-02-11 08:31:19.000000000 +0100
1800 +@@ -19,6 +19,8 @@
1801 +
1802 + #ifdef __KERNEL__
1803 +
1804 ++#include <linux/rwsem.h>
1805 ++
1806 + /* This file contains declarations of usbcore internals that are mostly
1807 + * used or exposed by Host Controller Drivers.
1808 + */
1809 +@@ -464,5 +466,9 @@ static inline void usbmon_urb_complete(s
1810 + : (in_interrupt () ? "in_interrupt" : "can sleep"))
1811 +
1812 +
1813 +-#endif /* __KERNEL__ */
1814 ++/* This rwsem is for use only by the hub driver and ehci-hcd.
1815 ++ * Nobody else should touch it.
1816 ++ */
1817 ++extern struct rw_semaphore ehci_cf_port_reset_rwsem;
1818 +
1819 ++#endif /* __KERNEL__ */
1820 +diff -NurpP linux-2.6.22.12/drivers/usb/core/hub.c linux-2.6.22.18/drivers/usb/core/hub.c
1821 +--- linux-2.6.22.12/drivers/usb/core/hub.c 2007-11-05 18:59:33.000000000 +0100
1822 ++++ linux-2.6.22.18/drivers/usb/core/hub.c 2008-02-11 08:31:19.000000000 +0100
1823 +@@ -117,6 +117,12 @@ MODULE_PARM_DESC(use_both_schemes,
1824 + "try the other device initialization scheme if the "
1825 + "first one fails");
1826 +
1827 ++/* Mutual exclusion for EHCI CF initialization. This interferes with
1828 ++ * port reset on some companion controllers.
1829 ++ */
1830 ++DECLARE_RWSEM(ehci_cf_port_reset_rwsem);
1831 ++EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
1832 ++
1833 +
1834 + static inline char *portspeed(int portstatus)
1835 + {
1836 +@@ -1513,6 +1519,11 @@ static int hub_port_reset(struct usb_hub
1837 + {
1838 + int i, status;
1839 +
1840 ++ /* Block EHCI CF initialization during the port reset.
1841 ++ * Some companion controllers don't like it when they mix.
1842 ++ */
1843 ++ down_read(&ehci_cf_port_reset_rwsem);
1844 ++
1845 + /* Reset the port */
1846 + for (i = 0; i < PORT_RESET_TRIES; i++) {
1847 + status = set_port_feature(hub->hdev,
1848 +@@ -1543,7 +1554,7 @@ static int hub_port_reset(struct usb_hub
1849 + usb_set_device_state(udev, status
1850 + ? USB_STATE_NOTATTACHED
1851 + : USB_STATE_DEFAULT);
1852 +- return status;
1853 ++ goto done;
1854 + }
1855 +
1856 + dev_dbg (hub->intfdev,
1857 +@@ -1556,6 +1567,8 @@ static int hub_port_reset(struct usb_hub
1858 + "Cannot enable port %i. Maybe the USB cable is bad?\n",
1859 + port1);
1860 +
1861 ++ done:
1862 ++ up_read(&ehci_cf_port_reset_rwsem);
1863 + return status;
1864 + }
1865 +
1866 +diff -NurpP linux-2.6.22.12/drivers/usb/host/ehci-hcd.c linux-2.6.22.18/drivers/usb/host/ehci-hcd.c
1867 +--- linux-2.6.22.12/drivers/usb/host/ehci-hcd.c 2007-11-05 18:59:33.000000000 +0100
1868 ++++ linux-2.6.22.18/drivers/usb/host/ehci-hcd.c 2008-02-11 08:31:19.000000000 +0100
1869 +@@ -566,10 +566,21 @@ static int ehci_run (struct usb_hcd *hcd
1870 + * are explicitly handed to companion controller(s), so no TT is
1871 + * involved with the root hub. (Except where one is integrated,
1872 + * and there's no companion controller unless maybe for USB OTG.)
1873 ++ *
1874 ++ * Turning on the CF flag will transfer ownership of all ports
1875 ++ * from the companions to the EHCI controller. If any of the
1876 ++ * companions are in the middle of a port reset at the time, it
1877 ++ * could cause trouble. Write-locking ehci_cf_port_reset_rwsem
1878 ++ * guarantees that no resets are in progress. After we set CF,
1879 ++ * a short delay lets the hardware catch up; new resets shouldn't
1880 ++ * be started before the port switching actions could complete.
1881 + */
1882 ++ down_write(&ehci_cf_port_reset_rwsem);
1883 + hcd->state = HC_STATE_RUNNING;
1884 + ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
1885 + ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
1886 ++ msleep(5);
1887 ++ up_write(&ehci_cf_port_reset_rwsem);
1888 +
1889 + temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
1890 + ehci_info (ehci,
1891 +diff -NurpP linux-2.6.22.12/drivers/usb/image/microtek.c linux-2.6.22.18/drivers/usb/image/microtek.c
1892 +--- linux-2.6.22.12/drivers/usb/image/microtek.c 2007-11-05 18:59:33.000000000 +0100
1893 ++++ linux-2.6.22.18/drivers/usb/image/microtek.c 2008-02-11 08:31:19.000000000 +0100
1894 +@@ -823,7 +823,7 @@ static int mts_usb_probe(struct usb_inte
1895 + goto out_kfree2;
1896 +
1897 + new_desc->host->hostdata[0] = (unsigned long)new_desc;
1898 +- if (scsi_add_host(new_desc->host, NULL)) {
1899 ++ if (scsi_add_host(new_desc->host, &dev->dev)) {
1900 + err_retval = -EIO;
1901 + goto out_host_put;
1902 + }
1903 +diff -NurpP linux-2.6.22.12/drivers/usb/serial/generic.c linux-2.6.22.18/drivers/usb/serial/generic.c
1904 +--- linux-2.6.22.12/drivers/usb/serial/generic.c 2007-11-05 18:59:33.000000000 +0100
1905 ++++ linux-2.6.22.18/drivers/usb/serial/generic.c 2008-02-11 08:31:19.000000000 +0100
1906 +@@ -190,14 +190,15 @@ int usb_serial_generic_write(struct usb_
1907 +
1908 + /* only do something if we have a bulk out endpoint */
1909 + if (serial->num_bulk_out) {
1910 +- spin_lock_bh(&port->lock);
1911 ++ unsigned long flags;
1912 ++ spin_lock_irqsave(&port->lock, flags);
1913 + if (port->write_urb_busy) {
1914 +- spin_unlock_bh(&port->lock);
1915 ++ spin_unlock_irqrestore(&port->lock, flags);
1916 + dbg("%s - already writing", __FUNCTION__);
1917 + return 0;
1918 + }
1919 + port->write_urb_busy = 1;
1920 +- spin_unlock_bh(&port->lock);
1921 ++ spin_unlock_irqrestore(&port->lock, flags);
1922 +
1923 + count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
1924 +
1925 +diff -NurpP linux-2.6.22.12/drivers/usb/serial/kobil_sct.c linux-2.6.22.18/drivers/usb/serial/kobil_sct.c
1926 +--- linux-2.6.22.12/drivers/usb/serial/kobil_sct.c 2007-11-05 18:59:33.000000000 +0100
1927 ++++ linux-2.6.22.18/drivers/usb/serial/kobil_sct.c 2008-02-11 08:31:19.000000000 +0100
1928 +@@ -82,6 +82,7 @@ static int kobil_tiocmset(struct usb_se
1929 + unsigned int set, unsigned int clear);
1930 + static void kobil_read_int_callback( struct urb *urb );
1931 + static void kobil_write_callback( struct urb *purb );
1932 ++static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old);
1933 +
1934 +
1935 + static struct usb_device_id id_table [] = {
1936 +@@ -119,6 +120,7 @@ static struct usb_serial_driver kobil_de
1937 + .attach = kobil_startup,
1938 + .shutdown = kobil_shutdown,
1939 + .ioctl = kobil_ioctl,
1940 ++ .set_termios = kobil_set_termios,
1941 + .tiocmget = kobil_tiocmget,
1942 + .tiocmset = kobil_tiocmset,
1943 + .open = kobil_open,
1944 +@@ -137,7 +139,6 @@ struct kobil_private {
1945 + int cur_pos; // index of the next char to send in buf
1946 + __u16 device_type;
1947 + int line_state;
1948 +- struct ktermios internal_termios;
1949 + };
1950 +
1951 +
1952 +@@ -216,7 +217,7 @@ static void kobil_shutdown (struct usb_s
1953 +
1954 + static int kobil_open (struct usb_serial_port *port, struct file *filp)
1955 + {
1956 +- int i, result = 0;
1957 ++ int result = 0;
1958 + struct kobil_private *priv;
1959 + unsigned char *transfer_buffer;
1960 + int transfer_buffer_length = 8;
1961 +@@ -242,16 +243,6 @@ static int kobil_open (struct usb_serial
1962 + port->tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
1963 + port->tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D)
1964 +
1965 +- // set up internal termios structure
1966 +- priv->internal_termios.c_iflag = port->tty->termios->c_iflag;
1967 +- priv->internal_termios.c_oflag = port->tty->termios->c_oflag;
1968 +- priv->internal_termios.c_cflag = port->tty->termios->c_cflag;
1969 +- priv->internal_termios.c_lflag = port->tty->termios->c_lflag;
1970 +-
1971 +- for (i=0; i<NCCS; i++) {
1972 +- priv->internal_termios.c_cc[i] = port->tty->termios->c_cc[i];
1973 +- }
1974 +-
1975 + // allocate memory for transfer buffer
1976 + transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
1977 + if (! transfer_buffer) {
1978 +@@ -358,24 +349,26 @@ static void kobil_close (struct usb_seri
1979 + }
1980 +
1981 +
1982 +-static void kobil_read_int_callback( struct urb *purb)
1983 ++static void kobil_read_int_callback(struct urb *urb)
1984 + {
1985 + int result;
1986 +- struct usb_serial_port *port = (struct usb_serial_port *) purb->context;
1987 ++ struct usb_serial_port *port = urb->context;
1988 + struct tty_struct *tty;
1989 +- unsigned char *data = purb->transfer_buffer;
1990 ++ unsigned char *data = urb->transfer_buffer;
1991 ++ int status = urb->status;
1992 + // char *dbg_data;
1993 +
1994 + dbg("%s - port %d", __FUNCTION__, port->number);
1995 +
1996 +- if (purb->status) {
1997 +- dbg("%s - port %d Read int status not zero: %d", __FUNCTION__, port->number, purb->status);
1998 ++ if (status) {
1999 ++ dbg("%s - port %d Read int status not zero: %d",
2000 ++ __FUNCTION__, port->number, status);
2001 + return;
2002 + }
2003 +-
2004 +- tty = port->tty;
2005 +- if (purb->actual_length) {
2006 +-
2007 ++
2008 ++ tty = port->tty;
2009 ++ if (urb->actual_length) {
2010 ++
2011 + // BEGIN DEBUG
2012 + /*
2013 + dbg_data = kzalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL);
2014 +@@ -390,15 +383,15 @@ static void kobil_read_int_callback( str
2015 + */
2016 + // END DEBUG
2017 +
2018 +- tty_buffer_request_room(tty, purb->actual_length);
2019 +- tty_insert_flip_string(tty, data, purb->actual_length);
2020 ++ tty_buffer_request_room(tty, urb->actual_length);
2021 ++ tty_insert_flip_string(tty, data, urb->actual_length);
2022 + tty_flip_buffer_push(tty);
2023 + }
2024 +
2025 + // someone sets the dev to 0 if the close method has been called
2026 + port->interrupt_in_urb->dev = port->serial->dev;
2027 +
2028 +- result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC );
2029 ++ result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
2030 + dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
2031 + }
2032 +
2033 +@@ -605,102 +598,79 @@ static int kobil_tiocmset(struct usb_se
2034 + return (result < 0) ? result : 0;
2035 + }
2036 +
2037 +-
2038 +-static int kobil_ioctl(struct usb_serial_port *port, struct file *file,
2039 +- unsigned int cmd, unsigned long arg)
2040 ++static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old)
2041 + {
2042 + struct kobil_private * priv;
2043 + int result;
2044 + unsigned short urb_val = 0;
2045 +- unsigned char *transfer_buffer;
2046 +- int transfer_buffer_length = 8;
2047 +- char *settings;
2048 +- void __user *user_arg = (void __user *)arg;
2049 ++ int c_cflag = port->tty->termios->c_cflag;
2050 ++ speed_t speed;
2051 ++ void * settings;
2052 +
2053 + priv = usb_get_serial_port_data(port);
2054 +- if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
2055 ++ if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)
2056 + // This device doesn't support ioctl calls
2057 +- return 0;
2058 +- }
2059 +-
2060 +- switch (cmd) {
2061 +- case TCGETS: // 0x5401
2062 +- if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct ktermios))) {
2063 +- dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number);
2064 +- return -EFAULT;
2065 +- }
2066 +- if (kernel_termios_to_user_termios((struct ktermios __user *)arg,
2067 +- &priv->internal_termios))
2068 +- return -EFAULT;
2069 +- return 0;
2070 +-
2071 +- case TCSETS: // 0x5402
2072 +- if (!(port->tty->termios)) {
2073 +- dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number);
2074 +- return -ENOTTY;
2075 +- }
2076 +- if (!access_ok(VERIFY_READ, user_arg, sizeof(struct ktermios))) {
2077 +- dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number);
2078 +- return -EFAULT;
2079 +- }
2080 +- if (user_termios_to_kernel_termios(&priv->internal_termios,
2081 +- (struct ktermios __user *)arg))
2082 +- return -EFAULT;
2083 +-
2084 +- settings = kzalloc(50, GFP_KERNEL);
2085 +- if (! settings) {
2086 +- return -ENOBUFS;
2087 +- }
2088 ++ return;
2089 +
2090 +- switch (priv->internal_termios.c_cflag & CBAUD) {
2091 +- case B1200:
2092 ++ switch (speed = tty_get_baud_rate(port->tty)) {
2093 ++ case 1200:
2094 + urb_val = SUSBCR_SBR_1200;
2095 +- strcat(settings, "1200 ");
2096 + break;
2097 +- case B9600:
2098 ++ case 9600:
2099 + default:
2100 + urb_val = SUSBCR_SBR_9600;
2101 +- strcat(settings, "9600 ");
2102 + break;
2103 +- }
2104 ++ }
2105 ++ urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit;
2106 +
2107 +- urb_val |= (priv->internal_termios.c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit;
2108 +- strcat(settings, (priv->internal_termios.c_cflag & CSTOPB) ? "2 StopBits " : "1 StopBit ");
2109 ++ settings = kzalloc(50, GFP_KERNEL);
2110 ++ if (! settings)
2111 ++ return;
2112 +
2113 +- if (priv->internal_termios.c_cflag & PARENB) {
2114 +- if (priv->internal_termios.c_cflag & PARODD) {
2115 +- urb_val |= SUSBCR_SPASB_OddParity;
2116 +- strcat(settings, "Odd Parity");
2117 +- } else {
2118 +- urb_val |= SUSBCR_SPASB_EvenParity;
2119 +- strcat(settings, "Even Parity");
2120 +- }
2121 ++ sprintf(settings, "%d ", speed);
2122 ++
2123 ++ if (c_cflag & PARENB) {
2124 ++ if (c_cflag & PARODD) {
2125 ++ urb_val |= SUSBCR_SPASB_OddParity;
2126 ++ strcat(settings, "Odd Parity");
2127 + } else {
2128 +- urb_val |= SUSBCR_SPASB_NoParity;
2129 +- strcat(settings, "No Parity");
2130 ++ urb_val |= SUSBCR_SPASB_EvenParity;
2131 ++ strcat(settings, "Even Parity");
2132 + }
2133 +- dbg("%s - port %d setting port to: %s", __FUNCTION__, port->number, settings );
2134 ++ } else {
2135 ++ urb_val |= SUSBCR_SPASB_NoParity;
2136 ++ strcat(settings, "No Parity");
2137 ++ }
2138 +
2139 +- result = usb_control_msg( port->serial->dev,
2140 +- usb_rcvctrlpipe(port->serial->dev, 0 ),
2141 +- SUSBCRequest_SetBaudRateParityAndStopBits,
2142 +- USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
2143 +- urb_val,
2144 +- 0,
2145 +- settings,
2146 +- 0,
2147 +- KOBIL_TIMEOUT
2148 +- );
2149 ++ result = usb_control_msg( port->serial->dev,
2150 ++ usb_rcvctrlpipe(port->serial->dev, 0 ),
2151 ++ SUSBCRequest_SetBaudRateParityAndStopBits,
2152 ++ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
2153 ++ urb_val,
2154 ++ 0,
2155 ++ settings,
2156 ++ 0,
2157 ++ KOBIL_TIMEOUT
2158 ++ );
2159 ++ kfree(settings);
2160 ++}
2161 +
2162 +- dbg("%s - port %d Send set_baudrate URB returns: %i", __FUNCTION__, port->number, result);
2163 +- kfree(settings);
2164 ++static int kobil_ioctl(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
2165 ++{
2166 ++ struct kobil_private * priv = usb_get_serial_port_data(port);
2167 ++ unsigned char *transfer_buffer;
2168 ++ int transfer_buffer_length = 8;
2169 ++ int result;
2170 ++
2171 ++ if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)
2172 ++ // This device doesn't support ioctl calls
2173 + return 0;
2174 +
2175 ++ switch (cmd) {
2176 + case TCFLSH: // 0x540B
2177 + transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL);
2178 +- if (! transfer_buffer) {
2179 ++ if (! transfer_buffer)
2180 + return -ENOBUFS;
2181 +- }
2182 +
2183 + result = usb_control_msg( port->serial->dev,
2184 + usb_rcvctrlpipe(port->serial->dev, 0 ),
2185 +@@ -714,15 +684,13 @@ static int kobil_ioctl(struct usb_seria
2186 + );
2187 +
2188 + dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __FUNCTION__, port->number, result);
2189 +-
2190 + kfree(transfer_buffer);
2191 +- return ((result < 0) ? -EFAULT : 0);
2192 +-
2193 ++ return (result < 0) ? -EFAULT : 0;
2194 ++ default:
2195 ++ return -ENOIOCTLCMD;
2196 + }
2197 +- return -ENOIOCTLCMD;
2198 + }
2199 +
2200 +-
2201 + static int __init kobil_init (void)
2202 + {
2203 + int retval;
2204 +diff -NurpP linux-2.6.22.12/drivers/video/fb_ddc.c linux-2.6.22.18/drivers/video/fb_ddc.c
2205 +--- linux-2.6.22.12/drivers/video/fb_ddc.c 2007-11-05 18:59:33.000000000 +0100
2206 ++++ linux-2.6.22.18/drivers/video/fb_ddc.c 2008-02-11 08:31:19.000000000 +0100
2207 +@@ -56,13 +56,12 @@ unsigned char *fb_ddc_read(struct i2c_ad
2208 + int i, j;
2209 +
2210 + algo_data->setscl(algo_data->data, 1);
2211 +- algo_data->setscl(algo_data->data, 0);
2212 +
2213 + for (i = 0; i < 3; i++) {
2214 + /* For some old monitors we need the
2215 + * following process to initialize/stop DDC
2216 + */
2217 +- algo_data->setsda(algo_data->data, 0);
2218 ++ algo_data->setsda(algo_data->data, 1);
2219 + msleep(13);
2220 +
2221 + algo_data->setscl(algo_data->data, 1);
2222 +@@ -97,14 +96,15 @@ unsigned char *fb_ddc_read(struct i2c_ad
2223 + algo_data->setsda(algo_data->data, 1);
2224 + msleep(15);
2225 + algo_data->setscl(algo_data->data, 0);
2226 ++ algo_data->setsda(algo_data->data, 0);
2227 + if (edid)
2228 + break;
2229 + }
2230 + /* Release the DDC lines when done or the Apple Cinema HD display
2231 + * will switch off
2232 + */
2233 +- algo_data->setsda(algo_data->data, 0);
2234 +- algo_data->setscl(algo_data->data, 0);
2235 ++ algo_data->setsda(algo_data->data, 1);
2236 ++ algo_data->setscl(algo_data->data, 1);
2237 +
2238 + return edid;
2239 + }
2240 +diff -NurpP linux-2.6.22.12/fs/exec.c linux-2.6.22.18/fs/exec.c
2241 +--- linux-2.6.22.12/fs/exec.c 2007-11-05 18:59:33.000000000 +0100
2242 ++++ linux-2.6.22.18/fs/exec.c 2008-02-11 08:31:19.000000000 +0100
2243 +@@ -1561,6 +1561,12 @@ int do_coredump(long signr, int exit_cod
2244 + but keep the previous behaviour for now. */
2245 + if (!ispipe && !S_ISREG(inode->i_mode))
2246 + goto close_fail;
2247 ++ /*
2248 ++ * Dont allow local users get cute and trick others to coredump
2249 ++ * into their pre-created files:
2250 ++ */
2251 ++ if (inode->i_uid != current->fsuid)
2252 ++ goto close_fail;
2253 + if (!file->f_op)
2254 + goto close_fail;
2255 + if (!file->f_op->write)
2256 +diff -NurpP linux-2.6.22.12/fs/namei.c linux-2.6.22.18/fs/namei.c
2257 +--- linux-2.6.22.12/fs/namei.c 2007-11-05 18:59:33.000000000 +0100
2258 ++++ linux-2.6.22.18/fs/namei.c 2008-02-11 08:31:19.000000000 +0100
2259 +@@ -1543,7 +1543,7 @@ int may_open(struct nameidata *nd, int a
2260 + if (S_ISLNK(inode->i_mode))
2261 + return -ELOOP;
2262 +
2263 +- if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
2264 ++ if (S_ISDIR(inode->i_mode) && (acc_mode & MAY_WRITE))
2265 + return -EISDIR;
2266 +
2267 + error = vfs_permission(nd, acc_mode);
2268 +@@ -1562,7 +1562,7 @@ int may_open(struct nameidata *nd, int a
2269 + return -EACCES;
2270 +
2271 + flag &= ~O_TRUNC;
2272 +- } else if (IS_RDONLY(inode) && (flag & FMODE_WRITE))
2273 ++ } else if (IS_RDONLY(inode) && (acc_mode & MAY_WRITE))
2274 + return -EROFS;
2275 + /*
2276 + * An append-only file must be opened in append mode for writing.
2277 +diff -NurpP linux-2.6.22.12/fs/ncpfs/mmap.c linux-2.6.22.18/fs/ncpfs/mmap.c
2278 +--- linux-2.6.22.12/fs/ncpfs/mmap.c 2007-11-05 18:59:33.000000000 +0100
2279 ++++ linux-2.6.22.18/fs/ncpfs/mmap.c 2008-02-11 08:31:19.000000000 +0100
2280 +@@ -47,9 +47,6 @@ static struct page* ncp_file_mmap_nopage
2281 + pos = address - area->vm_start + (area->vm_pgoff << PAGE_SHIFT);
2282 +
2283 + count = PAGE_SIZE;
2284 +- if (address + PAGE_SIZE > area->vm_end) {
2285 +- count = area->vm_end - address;
2286 +- }
2287 + /* what we can read in one go */
2288 + bufsize = NCP_SERVER(inode)->buffer_size;
2289 +
2290 +diff -NurpP linux-2.6.22.12/fs/nfsd/nfsfh.c linux-2.6.22.18/fs/nfsd/nfsfh.c
2291 +--- linux-2.6.22.12/fs/nfsd/nfsfh.c 2007-11-05 18:59:33.000000000 +0100
2292 ++++ linux-2.6.22.18/fs/nfsd/nfsfh.c 2008-02-11 08:31:19.000000000 +0100
2293 +@@ -565,13 +565,23 @@ enum fsid_source fsid_source(struct svc_
2294 + case FSID_DEV:
2295 + case FSID_ENCODE_DEV:
2296 + case FSID_MAJOR_MINOR:
2297 +- return FSIDSOURCE_DEV;
2298 ++ if (fhp->fh_export->ex_dentry->d_inode->i_sb->s_type->fs_flags
2299 ++ & FS_REQUIRES_DEV)
2300 ++ return FSIDSOURCE_DEV;
2301 ++ break;
2302 + case FSID_NUM:
2303 +- return FSIDSOURCE_FSID;
2304 +- default:
2305 + if (fhp->fh_export->ex_flags & NFSEXP_FSID)
2306 + return FSIDSOURCE_FSID;
2307 +- else
2308 +- return FSIDSOURCE_UUID;
2309 ++ break;
2310 ++ default:
2311 ++ break;
2312 + }
2313 ++ /* either a UUID type filehandle, or the filehandle doesn't
2314 ++ * match the export.
2315 ++ */
2316 ++ if (fhp->fh_export->ex_flags & NFSEXP_FSID)
2317 ++ return FSIDSOURCE_FSID;
2318 ++ if (fhp->fh_export->ex_uuid)
2319 ++ return FSIDSOURCE_UUID;
2320 ++ return FSIDSOURCE_DEV;
2321 + }
2322 +diff -NurpP linux-2.6.22.12/fs/ocfs2/aops.c linux-2.6.22.18/fs/ocfs2/aops.c
2323 +--- linux-2.6.22.12/fs/ocfs2/aops.c 2007-11-05 18:59:33.000000000 +0100
2324 ++++ linux-2.6.22.18/fs/ocfs2/aops.c 2008-02-11 08:31:19.000000000 +0100
2325 +@@ -661,6 +661,27 @@ static void ocfs2_clear_page_regions(str
2326 + }
2327 +
2328 + /*
2329 ++ * Nonsparse file systems fully allocate before we get to the write
2330 ++ * code. This prevents ocfs2_write() from tagging the write as an
2331 ++ * allocating one, which means ocfs2_map_page_blocks() might try to
2332 ++ * read-in the blocks at the tail of our file. Avoid reading them by
2333 ++ * testing i_size against each block offset.
2334 ++ */
2335 ++static int ocfs2_should_read_blk(struct inode *inode, struct page *page,
2336 ++ unsigned int block_start)
2337 ++{
2338 ++ u64 offset = page_offset(page) + block_start;
2339 ++
2340 ++ if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
2341 ++ return 1;
2342 ++
2343 ++ if (i_size_read(inode) > offset)
2344 ++ return 1;
2345 ++
2346 ++ return 0;
2347 ++}
2348 ++
2349 ++/*
2350 + * Some of this taken from block_prepare_write(). We already have our
2351 + * mapping by now though, and the entire write will be allocating or
2352 + * it won't, so not much need to use BH_New.
2353 +@@ -711,7 +732,8 @@ int ocfs2_map_page_blocks(struct page *p
2354 + if (!buffer_uptodate(bh))
2355 + set_buffer_uptodate(bh);
2356 + } else if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
2357 +- (block_start < from || block_end > to)) {
2358 ++ ocfs2_should_read_blk(inode, page, block_start) &&
2359 ++ (block_start < from || block_end > to)) {
2360 + ll_rw_block(READ, 1, &bh);
2361 + *wait_bh++=bh;
2362 + }
2363 +diff -NurpP linux-2.6.22.12/fs/splice.c linux-2.6.22.18/fs/splice.c
2364 +--- linux-2.6.22.12/fs/splice.c 2007-11-05 18:59:33.000000000 +0100
2365 ++++ linux-2.6.22.18/fs/splice.c 2008-02-11 08:31:19.000000000 +0100
2366 +@@ -1182,6 +1182,9 @@ static int get_iovec_page_array(const st
2367 + if (unlikely(!base))
2368 + break;
2369 +
2370 ++ if (!access_ok(VERIFY_READ, base, len))
2371 ++ break;
2372 ++
2373 + /*
2374 + * Get this base offset and number of pages, then map
2375 + * in the user pages.
2376 +diff -NurpP linux-2.6.22.12/include/asm-sparc64/hypervisor.h linux-2.6.22.18/include/asm-sparc64/hypervisor.h
2377 +--- linux-2.6.22.12/include/asm-sparc64/hypervisor.h 2007-11-05 18:59:33.000000000 +0100
2378 ++++ linux-2.6.22.18/include/asm-sparc64/hypervisor.h 2008-02-11 08:31:19.000000000 +0100
2379 +@@ -709,6 +709,10 @@ extern unsigned long sun4v_mmu_tsb_ctx0(
2380 + */
2381 + #define HV_FAST_MMU_DEMAP_ALL 0x24
2382 +
2383 ++#ifndef __ASSEMBLY__
2384 ++extern void sun4v_mmu_demap_all(void);
2385 ++#endif
2386 ++
2387 + /* mmu_map_perm_addr()
2388 + * TRAP: HV_FAST_TRAP
2389 + * FUNCTION: HV_FAST_MMU_MAP_PERM_ADDR
2390 +diff -NurpP linux-2.6.22.12/include/linux/netlink.h linux-2.6.22.18/include/linux/netlink.h
2391 +--- linux-2.6.22.12/include/linux/netlink.h 2007-11-05 18:59:33.000000000 +0100
2392 ++++ linux-2.6.22.18/include/linux/netlink.h 2008-02-11 08:31:19.000000000 +0100
2393 +@@ -173,7 +173,7 @@ extern int netlink_unregister_notifier(s
2394 + /* finegrained unicast helpers: */
2395 + struct sock *netlink_getsockbyfilp(struct file *filp);
2396 + int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
2397 +- long timeo, struct sock *ssk);
2398 ++ long *timeo, struct sock *ssk);
2399 + void netlink_detachskb(struct sock *sk, struct sk_buff *skb);
2400 + int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol);
2401 +
2402 +diff -NurpP linux-2.6.22.12/include/linux/pci_ids.h linux-2.6.22.18/include/linux/pci_ids.h
2403 +--- linux-2.6.22.12/include/linux/pci_ids.h 2007-11-05 18:59:33.000000000 +0100
2404 ++++ linux-2.6.22.18/include/linux/pci_ids.h 2008-02-11 08:31:19.000000000 +0100
2405 +@@ -1239,6 +1239,10 @@
2406 + #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE 0x0560
2407 + #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE 0x056C
2408 + #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE 0x0759
2409 ++#define PCI_DEVICE_ID_NVIDIA_NVENET_36 0x0AB0
2410 ++#define PCI_DEVICE_ID_NVIDIA_NVENET_37 0x0AB1
2411 ++#define PCI_DEVICE_ID_NVIDIA_NVENET_38 0x0AB2
2412 ++#define PCI_DEVICE_ID_NVIDIA_NVENET_39 0x0AB3
2413 +
2414 + #define PCI_VENDOR_ID_IMS 0x10e0
2415 + #define PCI_DEVICE_ID_IMS_TT128 0x9128
2416 +@@ -2281,6 +2285,8 @@
2417 + #define PCI_DEVICE_ID_INTEL_ICH9_4 0x2914
2418 + #define PCI_DEVICE_ID_INTEL_ICH9_5 0x2919
2419 + #define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930
2420 ++#define PCI_DEVICE_ID_INTEL_ICH9_7 0x2916
2421 ++#define PCI_DEVICE_ID_INTEL_ICH9_8 0x2918
2422 + #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340
2423 + #define PCI_DEVICE_ID_INTEL_82830_HB 0x3575
2424 + #define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577
2425 +diff -NurpP linux-2.6.22.12/include/linux/thread_info.h linux-2.6.22.18/include/linux/thread_info.h
2426 +--- linux-2.6.22.12/include/linux/thread_info.h 2007-11-05 18:59:33.000000000 +0100
2427 ++++ linux-2.6.22.18/include/linux/thread_info.h 2008-02-11 08:31:19.000000000 +0100
2428 +@@ -7,12 +7,25 @@
2429 + #ifndef _LINUX_THREAD_INFO_H
2430 + #define _LINUX_THREAD_INFO_H
2431 +
2432 ++#include <linux/types.h>
2433 ++
2434 + /*
2435 +- * System call restart block.
2436 ++ * System call restart block.
2437 + */
2438 + struct restart_block {
2439 + long (*fn)(struct restart_block *);
2440 +- unsigned long arg0, arg1, arg2, arg3;
2441 ++ union {
2442 ++ struct {
2443 ++ unsigned long arg0, arg1, arg2, arg3;
2444 ++ };
2445 ++ /* For futex_wait */
2446 ++ struct {
2447 ++ u32 *uaddr;
2448 ++ u32 val;
2449 ++ u32 flags;
2450 ++ u64 time;
2451 ++ } futex;
2452 ++ };
2453 + };
2454 +
2455 + extern long do_no_restart_syscall(struct restart_block *parm);
2456 +diff -NurpP linux-2.6.22.12/include/net/tcp.h linux-2.6.22.18/include/net/tcp.h
2457 +--- linux-2.6.22.12/include/net/tcp.h 2007-11-05 18:59:33.000000000 +0100
2458 ++++ linux-2.6.22.18/include/net/tcp.h 2008-02-11 08:31:19.000000000 +0100
2459 +@@ -1258,6 +1258,9 @@ static inline void tcp_insert_write_queu
2460 + struct sock *sk)
2461 + {
2462 + __skb_insert(new, skb->prev, skb, &sk->sk_write_queue);
2463 ++
2464 ++ if (sk->sk_send_head == skb)
2465 ++ sk->sk_send_head = new;
2466 + }
2467 +
2468 + static inline void tcp_unlink_write_queue(struct sk_buff *skb, struct sock *sk)
2469 +diff -NurpP linux-2.6.22.12/ipc/mqueue.c linux-2.6.22.18/ipc/mqueue.c
2470 +--- linux-2.6.22.12/ipc/mqueue.c 2007-11-05 18:59:33.000000000 +0100
2471 ++++ linux-2.6.22.18/ipc/mqueue.c 2008-02-11 08:31:19.000000000 +0100
2472 +@@ -1014,6 +1014,8 @@ asmlinkage long sys_mq_notify(mqd_t mqde
2473 + return -EINVAL;
2474 + }
2475 + if (notification.sigev_notify == SIGEV_THREAD) {
2476 ++ long timeo;
2477 ++
2478 + /* create the notify skb */
2479 + nc = alloc_skb(NOTIFY_COOKIE_LEN, GFP_KERNEL);
2480 + ret = -ENOMEM;
2481 +@@ -1042,8 +1044,8 @@ retry:
2482 + goto out;
2483 + }
2484 +
2485 +- ret = netlink_attachskb(sock, nc, 0,
2486 +- MAX_SCHEDULE_TIMEOUT, NULL);
2487 ++ timeo = MAX_SCHEDULE_TIMEOUT;
2488 ++ ret = netlink_attachskb(sock, nc, 0, &timeo, NULL);
2489 + if (ret == 1)
2490 + goto retry;
2491 + if (ret) {
2492 +diff -NurpP linux-2.6.22.12/kernel/exit.c linux-2.6.22.18/kernel/exit.c
2493 +--- linux-2.6.22.12/kernel/exit.c 2007-11-05 18:59:33.000000000 +0100
2494 ++++ linux-2.6.22.18/kernel/exit.c 2008-02-11 08:31:19.000000000 +0100
2495 +@@ -1336,11 +1336,10 @@ static int wait_task_stopped(struct task
2496 + int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED;
2497 +
2498 + exit_code = p->exit_code;
2499 +- if (unlikely(!exit_code) ||
2500 +- unlikely(p->state & TASK_TRACED))
2501 ++ if (unlikely(!exit_code) || unlikely(p->exit_state))
2502 + goto bail_ref;
2503 + return wait_noreap_copyout(p, pid, uid,
2504 +- why, (exit_code << 8) | 0x7f,
2505 ++ why, exit_code,
2506 + infop, ru);
2507 + }
2508 +
2509 +diff -NurpP linux-2.6.22.12/kernel/futex.c linux-2.6.22.18/kernel/futex.c
2510 +--- linux-2.6.22.12/kernel/futex.c 2007-11-05 18:59:33.000000000 +0100
2511 ++++ linux-2.6.22.18/kernel/futex.c 2008-02-11 08:31:19.000000000 +0100
2512 +@@ -1129,9 +1129,9 @@ static int fixup_pi_state_owner(u32 __us
2513 +
2514 + /*
2515 + * In case we must use restart_block to restart a futex_wait,
2516 +- * we encode in the 'arg3' shared capability
2517 ++ * we encode in the 'flags' shared capability
2518 + */
2519 +-#define ARG3_SHARED 1
2520 ++#define FLAGS_SHARED 1
2521 +
2522 + static long futex_wait_restart(struct restart_block *restart);
2523 + static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared,
2524 +@@ -1272,12 +1272,13 @@ static int futex_wait(u32 __user *uaddr,
2525 + struct restart_block *restart;
2526 + restart = &current_thread_info()->restart_block;
2527 + restart->fn = futex_wait_restart;
2528 +- restart->arg0 = (unsigned long)uaddr;
2529 +- restart->arg1 = (unsigned long)val;
2530 +- restart->arg2 = (unsigned long)abs_time;
2531 +- restart->arg3 = 0;
2532 ++ restart->futex.uaddr = (u32 *)uaddr;
2533 ++ restart->futex.val = val;
2534 ++ restart->futex.time = abs_time->tv64;
2535 ++ restart->futex.flags = 0;
2536 ++
2537 + if (fshared)
2538 +- restart->arg3 |= ARG3_SHARED;
2539 ++ restart->futex.flags |= FLAGS_SHARED;
2540 + return -ERESTART_RESTARTBLOCK;
2541 + }
2542 +
2543 +@@ -1293,15 +1294,15 @@ static int futex_wait(u32 __user *uaddr,
2544 +
2545 + static long futex_wait_restart(struct restart_block *restart)
2546 + {
2547 +- u32 __user *uaddr = (u32 __user *)restart->arg0;
2548 +- u32 val = (u32)restart->arg1;
2549 +- ktime_t *abs_time = (ktime_t *)restart->arg2;
2550 ++ u32 __user *uaddr = (u32 __user *)restart->futex.uaddr;
2551 + struct rw_semaphore *fshared = NULL;
2552 ++ ktime_t t;
2553 +
2554 ++ t.tv64 = restart->futex.time;
2555 + restart->fn = do_no_restart_syscall;
2556 +- if (restart->arg3 & ARG3_SHARED)
2557 ++ if (restart->futex.flags & FLAGS_SHARED)
2558 + fshared = &current->mm->mmap_sem;
2559 +- return (long)futex_wait(uaddr, fshared, val, abs_time);
2560 ++ return (long)futex_wait(uaddr, fshared, restart->futex.val, &t);
2561 + }
2562 +
2563 +
2564 +diff -NurpP linux-2.6.22.12/kernel/futex_compat.c linux-2.6.22.18/kernel/futex_compat.c
2565 +--- linux-2.6.22.12/kernel/futex_compat.c 2007-11-05 18:59:33.000000000 +0100
2566 ++++ linux-2.6.22.18/kernel/futex_compat.c 2008-02-11 08:31:19.000000000 +0100
2567 +@@ -29,6 +29,15 @@ fetch_robust_entry(compat_uptr_t *uentry
2568 + return 0;
2569 + }
2570 +
2571 ++static void __user *futex_uaddr(struct robust_list *entry,
2572 ++ compat_long_t futex_offset)
2573 ++{
2574 ++ compat_uptr_t base = ptr_to_compat(entry);
2575 ++ void __user *uaddr = compat_ptr(base + futex_offset);
2576 ++
2577 ++ return uaddr;
2578 ++}
2579 ++
2580 + /*
2581 + * Walk curr->robust_list (very carefully, it's a userspace list!)
2582 + * and mark any locks found there dead, and notify any waiters.
2583 +@@ -61,18 +70,23 @@ void compat_exit_robust_list(struct task
2584 + if (fetch_robust_entry(&upending, &pending,
2585 + &head->list_op_pending, &pip))
2586 + return;
2587 +- if (pending)
2588 +- handle_futex_death((void __user *)pending + futex_offset, curr, pip);
2589 ++ if (pending) {
2590 ++ void __user *uaddr = futex_uaddr(pending,
2591 ++ futex_offset);
2592 ++ handle_futex_death(uaddr, curr, pip);
2593 ++ }
2594 +
2595 + while (entry != (struct robust_list __user *) &head->list) {
2596 + /*
2597 + * A pending lock might already be on the list, so
2598 + * dont process it twice:
2599 + */
2600 +- if (entry != pending)
2601 +- if (handle_futex_death((void __user *)entry + futex_offset,
2602 +- curr, pi))
2603 ++ if (entry != pending) {
2604 ++ void __user *uaddr = futex_uaddr(entry,
2605 ++ futex_offset);
2606 ++ if (handle_futex_death(uaddr, curr, pi))
2607 + return;
2608 ++ }
2609 +
2610 + /*
2611 + * Fetch the next entry in the list:
2612 +diff -NurpP linux-2.6.22.12/kernel/hrtimer.c linux-2.6.22.18/kernel/hrtimer.c
2613 +--- linux-2.6.22.12/kernel/hrtimer.c 2007-11-05 18:59:33.000000000 +0100
2614 ++++ linux-2.6.22.18/kernel/hrtimer.c 2008-02-11 08:31:19.000000000 +0100
2615 +@@ -825,6 +825,14 @@ hrtimer_start(struct hrtimer *timer, kti
2616 + #ifdef CONFIG_TIME_LOW_RES
2617 + tim = ktime_add(tim, base->resolution);
2618 + #endif
2619 ++ /*
2620 ++ * Careful here: User space might have asked for a
2621 ++ * very long sleep, so the add above might result in a
2622 ++ * negative number, which enqueues the timer in front
2623 ++ * of the queue.
2624 ++ */
2625 ++ if (tim.tv64 < 0)
2626 ++ tim.tv64 = KTIME_MAX;
2627 + }
2628 + timer->expires = tim;
2629 +
2630 +diff -NurpP linux-2.6.22.12/kernel/params.c linux-2.6.22.18/kernel/params.c
2631 +--- linux-2.6.22.12/kernel/params.c 2007-11-05 18:59:33.000000000 +0100
2632 ++++ linux-2.6.22.18/kernel/params.c 2008-02-11 08:31:19.000000000 +0100
2633 +@@ -591,19 +591,16 @@ static void __init param_sysfs_builtin(v
2634 +
2635 + for (i=0; i < __stop___param - __start___param; i++) {
2636 + char *dot;
2637 +- size_t kplen;
2638 ++ size_t max_name_len;
2639 +
2640 + kp = &__start___param[i];
2641 +- kplen = strlen(kp->name);
2642 ++ max_name_len =
2643 ++ min_t(size_t, MAX_KBUILD_MODNAME, strlen(kp->name));
2644 +
2645 +- /* We do not handle args without periods. */
2646 +- if (kplen > MAX_KBUILD_MODNAME) {
2647 +- DEBUGP("kernel parameter name is too long: %s\n", kp->name);
2648 +- continue;
2649 +- }
2650 +- dot = memchr(kp->name, '.', kplen);
2651 ++ dot = memchr(kp->name, '.', max_name_len);
2652 + if (!dot) {
2653 +- DEBUGP("couldn't find period in %s\n", kp->name);
2654 ++ DEBUGP("couldn't find period in first %d characters "
2655 ++ "of %s\n", MAX_KBUILD_MODNAME, kp->name);
2656 + continue;
2657 + }
2658 + name_len = dot - kp->name;
2659 +diff -NurpP linux-2.6.22.12/kernel/relay.c linux-2.6.22.18/kernel/relay.c
2660 +--- linux-2.6.22.12/kernel/relay.c 2007-11-05 18:59:33.000000000 +0100
2661 ++++ linux-2.6.22.18/kernel/relay.c 2008-02-11 08:31:19.000000000 +0100
2662 +@@ -91,6 +91,7 @@ int relay_mmap_buf(struct rchan_buf *buf
2663 + return -EINVAL;
2664 +
2665 + vma->vm_ops = &relay_file_mmap_ops;
2666 ++ vma->vm_flags |= VM_DONTEXPAND;
2667 + vma->vm_private_data = buf;
2668 + buf->chan->cb->buf_mapped(buf, filp);
2669 +
2670 +diff -NurpP linux-2.6.22.12/kernel/sys.c linux-2.6.22.18/kernel/sys.c
2671 +--- linux-2.6.22.12/kernel/sys.c 2007-11-05 18:59:33.000000000 +0100
2672 ++++ linux-2.6.22.18/kernel/sys.c 2008-02-11 08:31:19.000000000 +0100
2673 +@@ -31,7 +31,6 @@
2674 + #include <linux/cn_proc.h>
2675 + #include <linux/getcpu.h>
2676 + #include <linux/task_io_accounting_ops.h>
2677 +-#include <linux/cpu.h>
2678 +
2679 + #include <linux/compat.h>
2680 + #include <linux/syscalls.h>
2681 +@@ -866,7 +865,6 @@ EXPORT_SYMBOL_GPL(kernel_halt);
2682 + void kernel_power_off(void)
2683 + {
2684 + kernel_shutdown_prepare(SYSTEM_POWER_OFF);
2685 +- disable_nonboot_cpus();
2686 + printk(KERN_EMERG "Power down.\n");
2687 + machine_power_off();
2688 + }
2689 +diff -NurpP linux-2.6.22.12/lib/libcrc32c.c linux-2.6.22.18/lib/libcrc32c.c
2690 +--- linux-2.6.22.12/lib/libcrc32c.c 2007-11-05 18:59:33.000000000 +0100
2691 ++++ linux-2.6.22.18/lib/libcrc32c.c 2008-02-11 08:31:19.000000000 +0100
2692 +@@ -33,7 +33,6 @@
2693 + #include <linux/crc32c.h>
2694 + #include <linux/compiler.h>
2695 + #include <linux/module.h>
2696 +-#include <asm/byteorder.h>
2697 +
2698 + MODULE_AUTHOR("Clay Haapala <chaapala@×××××.com>");
2699 + MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
2700 +@@ -161,15 +160,13 @@ static const u32 crc32c_table[256] = {
2701 + */
2702 +
2703 + u32 __attribute_pure__
2704 +-crc32c_le(u32 seed, unsigned char const *data, size_t length)
2705 ++crc32c_le(u32 crc, unsigned char const *data, size_t length)
2706 + {
2707 +- u32 crc = __cpu_to_le32(seed);
2708 +-
2709 + while (length--)
2710 + crc =
2711 + crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
2712 +
2713 +- return __le32_to_cpu(crc);
2714 ++ return crc;
2715 + }
2716 +
2717 + #endif /* CRC_LE_BITS == 8 */
2718 +diff -NurpP linux-2.6.22.12/lib/textsearch.c linux-2.6.22.18/lib/textsearch.c
2719 +--- linux-2.6.22.12/lib/textsearch.c 2007-11-05 18:59:33.000000000 +0100
2720 ++++ linux-2.6.22.18/lib/textsearch.c 2008-02-11 08:31:19.000000000 +0100
2721 +@@ -7,7 +7,7 @@
2722 + * 2 of the License, or (at your option) any later version.
2723 + *
2724 + * Authors: Thomas Graf <tgraf@××××.ch>
2725 +- * Pablo Neira Ayuso <pablo@×××××××.net>
2726 ++ * Pablo Neira Ayuso <pablo@×××××××××.org>
2727 + *
2728 + * ==========================================================================
2729 + *
2730 +@@ -250,7 +250,8 @@ unsigned int textsearch_find_continuous(
2731 + * the various search algorithms.
2732 + *
2733 + * Returns a new textsearch configuration according to the specified
2734 +- * parameters or a ERR_PTR().
2735 ++ * parameters or a ERR_PTR(). If a zero length pattern is passed, this
2736 ++ * function returns EINVAL.
2737 + */
2738 + struct ts_config *textsearch_prepare(const char *algo, const void *pattern,
2739 + unsigned int len, gfp_t gfp_mask, int flags)
2740 +@@ -259,6 +260,9 @@ struct ts_config *textsearch_prepare(con
2741 + struct ts_config *conf;
2742 + struct ts_ops *ops;
2743 +
2744 ++ if (len == 0)
2745 ++ return ERR_PTR(-EINVAL);
2746 ++
2747 + ops = lookup_ts_algo(algo);
2748 + #ifdef CONFIG_KMOD
2749 + /*
2750 +diff -NurpP linux-2.6.22.12/mm/mmap.c linux-2.6.22.18/mm/mmap.c
2751 +--- linux-2.6.22.12/mm/mmap.c 2007-11-05 18:59:33.000000000 +0100
2752 ++++ linux-2.6.22.18/mm/mmap.c 2008-02-11 08:31:19.000000000 +0100
2753 +@@ -2157,7 +2157,7 @@ int install_special_mapping(struct mm_st
2754 + vma->vm_start = addr;
2755 + vma->vm_end = addr + len;
2756 +
2757 +- vma->vm_flags = vm_flags | mm->def_flags;
2758 ++ vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
2759 + vma->vm_page_prot = protection_map[vma->vm_flags & 7];
2760 +
2761 + vma->vm_ops = &special_mapping_vmops;
2762 +diff -NurpP linux-2.6.22.12/mm/page-writeback.c linux-2.6.22.18/mm/page-writeback.c
2763 +--- linux-2.6.22.12/mm/page-writeback.c 2007-11-05 18:59:33.000000000 +0100
2764 ++++ linux-2.6.22.18/mm/page-writeback.c 2008-02-11 08:31:19.000000000 +0100
2765 +@@ -674,8 +674,10 @@ retry:
2766 +
2767 + ret = (*writepage)(page, wbc, data);
2768 +
2769 +- if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE))
2770 ++ if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE)) {
2771 + unlock_page(page);
2772 ++ ret = 0;
2773 ++ }
2774 + if (ret || (--(wbc->nr_to_write) <= 0))
2775 + done = 1;
2776 + if (wbc->nonblocking && bdi_write_congested(bdi)) {
2777 +diff -NurpP linux-2.6.22.12/mm/shmem.c linux-2.6.22.18/mm/shmem.c
2778 +--- linux-2.6.22.12/mm/shmem.c 2007-11-05 18:59:33.000000000 +0100
2779 ++++ linux-2.6.22.18/mm/shmem.c 2008-02-11 08:31:19.000000000 +0100
2780 +@@ -911,6 +911,21 @@ static int shmem_writepage(struct page *
2781 + struct inode *inode;
2782 +
2783 + BUG_ON(!PageLocked(page));
2784 ++ /*
2785 ++ * shmem_backing_dev_info's capabilities prevent regular writeback or
2786 ++ * sync from ever calling shmem_writepage; but a stacking filesystem
2787 ++ * may use the ->writepage of its underlying filesystem, in which case
2788 ++ * we want to do nothing when that underlying filesystem is tmpfs
2789 ++ * (writing out to swap is useful as a response to memory pressure, but
2790 ++ * of no use to stabilize the data) - just redirty the page, unlock it
2791 ++ * and claim success in this case. AOP_WRITEPAGE_ACTIVATE, and the
2792 ++ * page_mapped check below, must be avoided unless we're in reclaim.
2793 ++ */
2794 ++ if (!wbc->for_reclaim) {
2795 ++ set_page_dirty(page);
2796 ++ unlock_page(page);
2797 ++ return 0;
2798 ++ }
2799 + BUG_ON(page_mapped(page));
2800 +
2801 + mapping = page->mapping;
2802 +@@ -1051,7 +1066,7 @@ shmem_alloc_page(gfp_t gfp, struct shmem
2803 + pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx);
2804 + pvma.vm_pgoff = idx;
2805 + pvma.vm_end = PAGE_SIZE;
2806 +- page = alloc_page_vma(gfp | __GFP_ZERO, &pvma, 0);
2807 ++ page = alloc_page_vma(gfp, &pvma, 0);
2808 + mpol_free(pvma.vm_policy);
2809 + return page;
2810 + }
2811 +@@ -1071,7 +1086,7 @@ shmem_swapin(struct shmem_inode_info *in
2812 + static inline struct page *
2813 + shmem_alloc_page(gfp_t gfp,struct shmem_inode_info *info, unsigned long idx)
2814 + {
2815 +- return alloc_page(gfp | __GFP_ZERO);
2816 ++ return alloc_page(gfp);
2817 + }
2818 + #endif
2819 +
2820 +@@ -1280,6 +1295,7 @@ repeat:
2821 +
2822 + info->alloced++;
2823 + spin_unlock(&info->lock);
2824 ++ clear_highpage(filepage);
2825 + flush_dcache_page(filepage);
2826 + SetPageUptodate(filepage);
2827 + }
2828 +diff -NurpP linux-2.6.22.12/mm/slub.c linux-2.6.22.18/mm/slub.c
2829 +--- linux-2.6.22.12/mm/slub.c 2007-11-05 18:59:33.000000000 +0100
2830 ++++ linux-2.6.22.18/mm/slub.c 2008-02-11 08:31:19.000000000 +0100
2831 +@@ -1431,28 +1431,8 @@ new_slab:
2832 + page = new_slab(s, gfpflags, node);
2833 + if (page) {
2834 + cpu = smp_processor_id();
2835 +- if (s->cpu_slab[cpu]) {
2836 +- /*
2837 +- * Someone else populated the cpu_slab while we
2838 +- * enabled interrupts, or we have gotten scheduled
2839 +- * on another cpu. The page may not be on the
2840 +- * requested node even if __GFP_THISNODE was
2841 +- * specified. So we need to recheck.
2842 +- */
2843 +- if (node == -1 ||
2844 +- page_to_nid(s->cpu_slab[cpu]) == node) {
2845 +- /*
2846 +- * Current cpuslab is acceptable and we
2847 +- * want the current one since its cache hot
2848 +- */
2849 +- discard_slab(s, page);
2850 +- page = s->cpu_slab[cpu];
2851 +- slab_lock(page);
2852 +- goto load_freelist;
2853 +- }
2854 +- /* New slab does not fit our expectations */
2855 ++ if (s->cpu_slab[cpu])
2856 + flush_slab(s, s->cpu_slab[cpu], cpu);
2857 +- }
2858 + slab_lock(page);
2859 + SetSlabFrozen(page);
2860 + s->cpu_slab[cpu] = page;
2861 +diff -NurpP linux-2.6.22.12/net/atm/mpc.c linux-2.6.22.18/net/atm/mpc.c
2862 +--- linux-2.6.22.12/net/atm/mpc.c 2007-11-05 18:59:33.000000000 +0100
2863 ++++ linux-2.6.22.18/net/atm/mpc.c 2008-02-11 08:31:19.000000000 +0100
2864 +@@ -542,6 +542,13 @@ static int mpc_send_packet(struct sk_buf
2865 + if (eth->h_proto != htons(ETH_P_IP))
2866 + goto non_ip; /* Multi-Protocol Over ATM :-) */
2867 +
2868 ++ /* Weed out funny packets (e.g., AF_PACKET or raw). */
2869 ++ if (skb->len < ETH_HLEN + sizeof(struct iphdr))
2870 ++ goto non_ip;
2871 ++ skb_set_network_header(skb, ETH_HLEN);
2872 ++ if (skb->len < ETH_HLEN + ip_hdr(skb)->ihl * 4 || ip_hdr(skb)->ihl < 5)
2873 ++ goto non_ip;
2874 ++
2875 + while (i < mpc->number_of_mps_macs) {
2876 + if (!compare_ether_addr(eth->h_dest, (mpc->mps_macs + i*ETH_ALEN)))
2877 + if ( send_via_shortcut(skb, mpc) == 0 ) /* try shortcut */
2878 +diff -NurpP linux-2.6.22.12/net/ax25/ax25_in.c linux-2.6.22.18/net/ax25/ax25_in.c
2879 +--- linux-2.6.22.12/net/ax25/ax25_in.c 2007-11-05 18:59:33.000000000 +0100
2880 ++++ linux-2.6.22.18/net/ax25/ax25_in.c 2008-02-11 08:31:19.000000000 +0100
2881 +@@ -124,7 +124,7 @@ int ax25_rx_iframe(ax25_cb *ax25, struct
2882 + }
2883 +
2884 + skb_pull(skb, 1); /* Remove PID */
2885 +- skb_reset_mac_header(skb);
2886 ++ skb->mac_header = skb->network_header;
2887 + skb_reset_network_header(skb);
2888 + skb->dev = ax25->ax25_dev->dev;
2889 + skb->pkt_type = PACKET_HOST;
2890 +diff -NurpP linux-2.6.22.12/net/bridge/br.c linux-2.6.22.18/net/bridge/br.c
2891 +--- linux-2.6.22.12/net/bridge/br.c 2007-11-05 18:59:33.000000000 +0100
2892 ++++ linux-2.6.22.18/net/bridge/br.c 2008-02-11 08:31:19.000000000 +0100
2893 +@@ -39,7 +39,7 @@ static int __init br_init(void)
2894 +
2895 + err = br_fdb_init();
2896 + if (err)
2897 +- goto err_out1;
2898 ++ goto err_out;
2899 +
2900 + err = br_netfilter_init();
2901 + if (err)
2902 +@@ -65,6 +65,8 @@ err_out3:
2903 + err_out2:
2904 + br_netfilter_fini();
2905 + err_out1:
2906 ++ br_fdb_fini();
2907 ++err_out:
2908 + llc_sap_put(br_stp_sap);
2909 + return err;
2910 + }
2911 +diff -NurpP linux-2.6.22.12/net/bridge/br_input.c linux-2.6.22.18/net/bridge/br_input.c
2912 +--- linux-2.6.22.12/net/bridge/br_input.c 2007-11-05 18:59:33.000000000 +0100
2913 ++++ linux-2.6.22.18/net/bridge/br_input.c 2008-02-11 08:31:19.000000000 +0100
2914 +@@ -127,6 +127,7 @@ static inline int is_link_local(const un
2915 + struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
2916 + {
2917 + const unsigned char *dest = eth_hdr(skb)->h_dest;
2918 ++ int (*rhook)(struct sk_buff **pskb);
2919 +
2920 + if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
2921 + goto drop;
2922 +@@ -148,9 +149,9 @@ struct sk_buff *br_handle_frame(struct n
2923 +
2924 + switch (p->state) {
2925 + case BR_STATE_FORWARDING:
2926 +-
2927 +- if (br_should_route_hook) {
2928 +- if (br_should_route_hook(&skb))
2929 ++ rhook = rcu_dereference(br_should_route_hook);
2930 ++ if (rhook != NULL) {
2931 ++ if (rhook(&skb))
2932 + return skb;
2933 + dest = eth_hdr(skb)->h_dest;
2934 + }
2935 +diff -NurpP linux-2.6.22.12/net/bridge/netfilter/ebtable_broute.c linux-2.6.22.18/net/bridge/netfilter/ebtable_broute.c
2936 +--- linux-2.6.22.12/net/bridge/netfilter/ebtable_broute.c 2007-11-05 18:59:33.000000000 +0100
2937 ++++ linux-2.6.22.18/net/bridge/netfilter/ebtable_broute.c 2008-02-11 08:31:19.000000000 +0100
2938 +@@ -70,13 +70,13 @@ static int __init ebtable_broute_init(vo
2939 + if (ret < 0)
2940 + return ret;
2941 + /* see br_input.c */
2942 +- br_should_route_hook = ebt_broute;
2943 ++ rcu_assign_pointer(br_should_route_hook, ebt_broute);
2944 + return ret;
2945 + }
2946 +
2947 + static void __exit ebtable_broute_fini(void)
2948 + {
2949 +- br_should_route_hook = NULL;
2950 ++ rcu_assign_pointer(br_should_route_hook, NULL);
2951 + synchronize_net();
2952 + ebt_unregister_table(&broute_table);
2953 + }
2954 +diff -NurpP linux-2.6.22.12/net/decnet/dn_dev.c linux-2.6.22.18/net/decnet/dn_dev.c
2955 +--- linux-2.6.22.12/net/decnet/dn_dev.c 2007-11-05 18:59:33.000000000 +0100
2956 ++++ linux-2.6.22.18/net/decnet/dn_dev.c 2008-02-11 08:31:19.000000000 +0100
2957 +@@ -651,16 +651,18 @@ static int dn_nl_deladdr(struct sk_buff
2958 + struct dn_dev *dn_db;
2959 + struct ifaddrmsg *ifm;
2960 + struct dn_ifaddr *ifa, **ifap;
2961 +- int err = -EADDRNOTAVAIL;
2962 ++ int err;
2963 +
2964 + err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy);
2965 + if (err < 0)
2966 + goto errout;
2967 +
2968 ++ err = -ENODEV;
2969 + ifm = nlmsg_data(nlh);
2970 + if ((dn_db = dn_dev_by_index(ifm->ifa_index)) == NULL)
2971 + goto errout;
2972 +
2973 ++ err = -EADDRNOTAVAIL;
2974 + for (ifap = &dn_db->ifa_list; (ifa = *ifap); ifap = &ifa->ifa_next) {
2975 + if (tb[IFA_LOCAL] &&
2976 + nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2))
2977 +diff -NurpP linux-2.6.22.12/net/ipv4/arp.c linux-2.6.22.18/net/ipv4/arp.c
2978 +--- linux-2.6.22.12/net/ipv4/arp.c 2007-11-05 18:59:33.000000000 +0100
2979 ++++ linux-2.6.22.18/net/ipv4/arp.c 2008-02-11 08:31:19.000000000 +0100
2980 +@@ -110,12 +110,8 @@
2981 + #include <net/tcp.h>
2982 + #include <net/sock.h>
2983 + #include <net/arp.h>
2984 +-#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
2985 + #include <net/ax25.h>
2986 +-#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
2987 + #include <net/netrom.h>
2988 +-#endif
2989 +-#endif
2990 + #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
2991 + #include <net/atmclip.h>
2992 + struct neigh_table *clip_tbl_hook;
2993 +@@ -729,20 +725,10 @@ static int arp_process(struct sk_buff *s
2994 + htons(dev_type) != arp->ar_hrd)
2995 + goto out;
2996 + break;
2997 +-#ifdef CONFIG_NET_ETHERNET
2998 + case ARPHRD_ETHER:
2999 +-#endif
3000 +-#ifdef CONFIG_TR
3001 + case ARPHRD_IEEE802_TR:
3002 +-#endif
3003 +-#ifdef CONFIG_FDDI
3004 + case ARPHRD_FDDI:
3005 +-#endif
3006 +-#ifdef CONFIG_NET_FC
3007 + case ARPHRD_IEEE802:
3008 +-#endif
3009 +-#if defined(CONFIG_NET_ETHERNET) || defined(CONFIG_TR) || \
3010 +- defined(CONFIG_FDDI) || defined(CONFIG_NET_FC)
3011 + /*
3012 + * ETHERNET, Token Ring and Fibre Channel (which are IEEE 802
3013 + * devices, according to RFC 2625) devices will accept ARP
3014 +@@ -757,21 +743,16 @@ static int arp_process(struct sk_buff *s
3015 + arp->ar_pro != htons(ETH_P_IP))
3016 + goto out;
3017 + break;
3018 +-#endif
3019 +-#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
3020 + case ARPHRD_AX25:
3021 + if (arp->ar_pro != htons(AX25_P_IP) ||
3022 + arp->ar_hrd != htons(ARPHRD_AX25))
3023 + goto out;
3024 + break;
3025 +-#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
3026 + case ARPHRD_NETROM:
3027 + if (arp->ar_pro != htons(AX25_P_IP) ||
3028 + arp->ar_hrd != htons(ARPHRD_NETROM))
3029 + goto out;
3030 + break;
3031 +-#endif
3032 +-#endif
3033 + }
3034 +
3035 + /* Understand only these message types */
3036 +diff -NurpP linux-2.6.22.12/net/ipv4/devinet.c linux-2.6.22.18/net/ipv4/devinet.c
3037 +--- linux-2.6.22.12/net/ipv4/devinet.c 2007-11-05 18:59:33.000000000 +0100
3038 ++++ linux-2.6.22.18/net/ipv4/devinet.c 2008-02-11 08:31:19.000000000 +0100
3039 +@@ -1030,7 +1030,7 @@ static void inetdev_changename(struct ne
3040 + memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
3041 + if (named++ == 0)
3042 + continue;
3043 +- dot = strchr(ifa->ifa_label, ':');
3044 ++ dot = strchr(old, ':');
3045 + if (dot == NULL) {
3046 + sprintf(old, ":%d", named);
3047 + dot = old;
3048 +diff -NurpP linux-2.6.22.12/net/ipv4/ipcomp.c linux-2.6.22.18/net/ipv4/ipcomp.c
3049 +--- linux-2.6.22.12/net/ipv4/ipcomp.c 2007-11-05 18:59:33.000000000 +0100
3050 ++++ linux-2.6.22.18/net/ipv4/ipcomp.c 2008-02-11 08:31:19.000000000 +0100
3051 +@@ -17,6 +17,7 @@
3052 + #include <asm/scatterlist.h>
3053 + #include <asm/semaphore.h>
3054 + #include <linux/crypto.h>
3055 ++#include <linux/err.h>
3056 + #include <linux/pfkeyv2.h>
3057 + #include <linux/percpu.h>
3058 + #include <linux/smp.h>
3059 +@@ -355,7 +356,7 @@ static struct crypto_comp **ipcomp_alloc
3060 + for_each_possible_cpu(cpu) {
3061 + struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0,
3062 + CRYPTO_ALG_ASYNC);
3063 +- if (!tfm)
3064 ++ if (IS_ERR(tfm))
3065 + goto error;
3066 + *per_cpu_ptr(tfms, cpu) = tfm;
3067 + }
3068 +diff -NurpP linux-2.6.22.12/net/ipv4/ip_gre.c linux-2.6.22.18/net/ipv4/ip_gre.c
3069 +--- linux-2.6.22.12/net/ipv4/ip_gre.c 2007-11-05 18:59:33.000000000 +0100
3070 ++++ linux-2.6.22.18/net/ipv4/ip_gre.c 2008-02-11 08:31:19.000000000 +0100
3071 +@@ -613,7 +613,7 @@ static int ipgre_rcv(struct sk_buff *skb
3072 + offset += 4;
3073 + }
3074 +
3075 +- skb_reset_mac_header(skb);
3076 ++ skb->mac_header = skb->network_header;
3077 + __pskb_pull(skb, offset);
3078 + skb_reset_network_header(skb);
3079 + skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
3080 +diff -NurpP linux-2.6.22.12/net/ipv4/netfilter/nf_nat_core.c linux-2.6.22.18/net/ipv4/netfilter/nf_nat_core.c
3081 +--- linux-2.6.22.12/net/ipv4/netfilter/nf_nat_core.c 2007-11-05 18:59:33.000000000 +0100
3082 ++++ linux-2.6.22.18/net/ipv4/netfilter/nf_nat_core.c 2008-02-11 08:31:19.000000000 +0100
3083 +@@ -633,7 +633,7 @@ static int clean_nat(struct nf_conn *i,
3084 +
3085 + if (!nat)
3086 + return 0;
3087 +- memset(nat, 0, sizeof(nat));
3088 ++ memset(nat, 0, sizeof(*nat));
3089 + i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST);
3090 + return 0;
3091 + }
3092 +diff -NurpP linux-2.6.22.12/net/ipv4/route.c linux-2.6.22.18/net/ipv4/route.c
3093 +--- linux-2.6.22.12/net/ipv4/route.c 2007-11-05 18:59:33.000000000 +0100
3094 ++++ linux-2.6.22.18/net/ipv4/route.c 2008-02-11 08:31:19.000000000 +0100
3095 +@@ -2885,11 +2885,10 @@ int ip_rt_dump(struct sk_buff *skb, str
3096 + int idx, s_idx;
3097 +
3098 + s_h = cb->args[0];
3099 ++ if (s_h < 0)
3100 ++ s_h = 0;
3101 + s_idx = idx = cb->args[1];
3102 +- for (h = 0; h <= rt_hash_mask; h++) {
3103 +- if (h < s_h) continue;
3104 +- if (h > s_h)
3105 +- s_idx = 0;
3106 ++ for (h = s_h; h <= rt_hash_mask; h++) {
3107 + rcu_read_lock_bh();
3108 + for (rt = rcu_dereference(rt_hash_table[h].chain), idx = 0; rt;
3109 + rt = rcu_dereference(rt->u.dst.rt_next), idx++) {
3110 +@@ -2906,6 +2905,7 @@ int ip_rt_dump(struct sk_buff *skb, str
3111 + dst_release(xchg(&skb->dst, NULL));
3112 + }
3113 + rcu_read_unlock_bh();
3114 ++ s_idx = 0;
3115 + }
3116 +
3117 + done:
3118 +@@ -3150,18 +3150,14 @@ static int ip_rt_acct_read(char *buffer,
3119 + offset /= sizeof(u32);
3120 +
3121 + if (length > 0) {
3122 +- u32 *src = ((u32 *) IP_RT_ACCT_CPU(0)) + offset;
3123 + u32 *dst = (u32 *) buffer;
3124 +
3125 +- /* Copy first cpu. */
3126 + *start = buffer;
3127 +- memcpy(dst, src, length);
3128 ++ memset(dst, 0, length);
3129 +
3130 +- /* Add the other cpus in, one int at a time */
3131 + for_each_possible_cpu(i) {
3132 + unsigned int j;
3133 +-
3134 +- src = ((u32 *) IP_RT_ACCT_CPU(i)) + offset;
3135 ++ u32 *src = ((u32 *) IP_RT_ACCT_CPU(i)) + offset;
3136 +
3137 + for (j = 0; j < length/4; j++)
3138 + dst[j] += src[j];
3139 +diff -NurpP linux-2.6.22.12/net/ipv4/sysctl_net_ipv4.c linux-2.6.22.18/net/ipv4/sysctl_net_ipv4.c
3140 +--- linux-2.6.22.12/net/ipv4/sysctl_net_ipv4.c 2007-11-05 18:59:33.000000000 +0100
3141 ++++ linux-2.6.22.18/net/ipv4/sysctl_net_ipv4.c 2008-02-11 08:31:19.000000000 +0100
3142 +@@ -121,7 +121,7 @@ static int sysctl_tcp_congestion_control
3143 +
3144 + tcp_get_default_congestion_control(val);
3145 + ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen);
3146 +- if (ret == 0 && newval && newlen)
3147 ++ if (ret == 1 && newval && newlen)
3148 + ret = tcp_set_default_congestion_control(val);
3149 + return ret;
3150 + }
3151 +diff -NurpP linux-2.6.22.12/net/ipv4/tcp_illinois.c linux-2.6.22.18/net/ipv4/tcp_illinois.c
3152 +--- linux-2.6.22.12/net/ipv4/tcp_illinois.c 2007-11-05 18:59:33.000000000 +0100
3153 ++++ linux-2.6.22.18/net/ipv4/tcp_illinois.c 2008-02-11 08:31:19.000000000 +0100
3154 +@@ -300,7 +300,7 @@ static u32 tcp_illinois_ssthresh(struct
3155 + struct illinois *ca = inet_csk_ca(sk);
3156 +
3157 + /* Multiplicative decrease */
3158 +- return max((tp->snd_cwnd * ca->beta) >> BETA_SHIFT, 2U);
3159 ++ return max(tp->snd_cwnd - ((tp->snd_cwnd * ca->beta) >> BETA_SHIFT), 2U);
3160 + }
3161 +
3162 +
3163 +diff -NurpP linux-2.6.22.12/net/ipv4/tcp_input.c linux-2.6.22.18/net/ipv4/tcp_input.c
3164 +--- linux-2.6.22.12/net/ipv4/tcp_input.c 2007-11-05 18:59:33.000000000 +0100
3165 ++++ linux-2.6.22.18/net/ipv4/tcp_input.c 2008-02-11 08:31:19.000000000 +0100
3166 +@@ -994,6 +994,9 @@ tcp_sacktag_write_queue(struct sock *sk,
3167 + if (before(TCP_SKB_CB(ack_skb)->ack_seq, prior_snd_una - tp->max_window))
3168 + return 0;
3169 +
3170 ++ if (!tp->packets_out)
3171 ++ goto out;
3172 ++
3173 + /* SACK fastpath:
3174 + * if the only SACK change is the increase of the end_seq of
3175 + * the first block then only apply that SACK block
3176 +@@ -1262,6 +1265,8 @@ tcp_sacktag_write_queue(struct sock *sk,
3177 + (!tp->frto_highmark || after(tp->snd_una, tp->frto_highmark)))
3178 + tcp_update_reordering(sk, ((tp->fackets_out + 1) - reord), 0);
3179 +
3180 ++out:
3181 ++
3182 + #if FASTRETRANS_DEBUG > 0
3183 + BUG_TRAP((int)tp->sacked_out >= 0);
3184 + BUG_TRAP((int)tp->lost_out >= 0);
3185 +diff -NurpP linux-2.6.22.12/net/ipv4/tcp_output.c linux-2.6.22.18/net/ipv4/tcp_output.c
3186 +--- linux-2.6.22.12/net/ipv4/tcp_output.c 2007-11-05 18:59:33.000000000 +0100
3187 ++++ linux-2.6.22.18/net/ipv4/tcp_output.c 2008-02-11 08:31:19.000000000 +0100
3188 +@@ -1279,7 +1279,6 @@ static int tcp_mtu_probe(struct sock *sk
3189 +
3190 + skb = tcp_send_head(sk);
3191 + tcp_insert_write_queue_before(nskb, skb, sk);
3192 +- tcp_advance_send_head(sk, skb);
3193 +
3194 + TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(skb)->seq;
3195 + TCP_SKB_CB(nskb)->end_seq = TCP_SKB_CB(skb)->seq + probe_size;
3196 +diff -NurpP linux-2.6.22.12/net/ipv6/addrconf.c linux-2.6.22.18/net/ipv6/addrconf.c
3197 +--- linux-2.6.22.12/net/ipv6/addrconf.c 2007-11-05 18:59:33.000000000 +0100
3198 ++++ linux-2.6.22.18/net/ipv6/addrconf.c 2008-02-11 08:31:19.000000000 +0100
3199 +@@ -2285,6 +2285,9 @@ static int addrconf_notify(struct notifi
3200 + break;
3201 + }
3202 +
3203 ++ if (!idev && dev->mtu >= IPV6_MIN_MTU)
3204 ++ idev = ipv6_add_dev(dev);
3205 ++
3206 + if (idev)
3207 + idev->if_flags |= IF_READY;
3208 + } else {
3209 +@@ -2349,12 +2352,18 @@ static int addrconf_notify(struct notifi
3210 + break;
3211 +
3212 + case NETDEV_CHANGEMTU:
3213 +- if ( idev && dev->mtu >= IPV6_MIN_MTU) {
3214 ++ if (idev && dev->mtu >= IPV6_MIN_MTU) {
3215 + rt6_mtu_change(dev, dev->mtu);
3216 + idev->cnf.mtu6 = dev->mtu;
3217 + break;
3218 + }
3219 +
3220 ++ if (!idev && dev->mtu >= IPV6_MIN_MTU) {
3221 ++ idev = ipv6_add_dev(dev);
3222 ++ if (idev)
3223 ++ break;
3224 ++ }
3225 ++
3226 + /* MTU falled under IPV6_MIN_MTU. Stop IPv6 on this interface. */
3227 +
3228 + case NETDEV_DOWN:
3229 +diff -NurpP linux-2.6.22.12/net/ipv6/ipcomp6.c linux-2.6.22.18/net/ipv6/ipcomp6.c
3230 +--- linux-2.6.22.12/net/ipv6/ipcomp6.c 2007-11-05 18:59:33.000000000 +0100
3231 ++++ linux-2.6.22.18/net/ipv6/ipcomp6.c 2008-02-11 08:31:19.000000000 +0100
3232 +@@ -37,6 +37,7 @@
3233 + #include <asm/scatterlist.h>
3234 + #include <asm/semaphore.h>
3235 + #include <linux/crypto.h>
3236 ++#include <linux/err.h>
3237 + #include <linux/pfkeyv2.h>
3238 + #include <linux/random.h>
3239 + #include <linux/percpu.h>
3240 +@@ -366,7 +367,7 @@ static struct crypto_comp **ipcomp6_allo
3241 + for_each_possible_cpu(cpu) {
3242 + struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0,
3243 + CRYPTO_ALG_ASYNC);
3244 +- if (!tfm)
3245 ++ if (IS_ERR(tfm))
3246 + goto error;
3247 + *per_cpu_ptr(tfms, cpu) = tfm;
3248 + }
3249 +diff -NurpP linux-2.6.22.12/net/irda/af_irda.c linux-2.6.22.18/net/irda/af_irda.c
3250 +--- linux-2.6.22.12/net/irda/af_irda.c 2007-11-05 18:59:33.000000000 +0100
3251 ++++ linux-2.6.22.18/net/irda/af_irda.c 2008-02-11 08:31:19.000000000 +0100
3252 +@@ -1115,8 +1115,6 @@ static int irda_create(struct socket *so
3253 + self->max_sdu_size_rx = TTP_SAR_UNBOUND;
3254 + break;
3255 + default:
3256 +- IRDA_ERROR("%s: protocol not supported!\n",
3257 +- __FUNCTION__);
3258 + return -ESOCKTNOSUPPORT;
3259 + }
3260 + break;
3261 +diff -NurpP linux-2.6.22.12/net/key/af_key.c linux-2.6.22.18/net/key/af_key.c
3262 +--- linux-2.6.22.12/net/key/af_key.c 2007-11-05 18:59:33.000000000 +0100
3263 ++++ linux-2.6.22.18/net/key/af_key.c 2008-02-11 08:31:19.000000000 +0100
3264 +@@ -1543,7 +1543,7 @@ static int pfkey_get(struct sock *sk, st
3265 +
3266 + out_hdr = (struct sadb_msg *) out_skb->data;
3267 + out_hdr->sadb_msg_version = hdr->sadb_msg_version;
3268 +- out_hdr->sadb_msg_type = SADB_DUMP;
3269 ++ out_hdr->sadb_msg_type = SADB_GET;
3270 + out_hdr->sadb_msg_satype = pfkey_proto2satype(proto);
3271 + out_hdr->sadb_msg_errno = 0;
3272 + out_hdr->sadb_msg_reserved = 0;
3273 +@@ -2777,12 +2777,22 @@ static struct sadb_msg *pfkey_get_base_m
3274 +
3275 + static inline int aalg_tmpl_set(struct xfrm_tmpl *t, struct xfrm_algo_desc *d)
3276 + {
3277 +- return t->aalgos & (1 << d->desc.sadb_alg_id);
3278 ++ unsigned int id = d->desc.sadb_alg_id;
3279 ++
3280 ++ if (id >= sizeof(t->aalgos) * 8)
3281 ++ return 0;
3282 ++
3283 ++ return (t->aalgos >> id) & 1;
3284 + }
3285 +
3286 + static inline int ealg_tmpl_set(struct xfrm_tmpl *t, struct xfrm_algo_desc *d)
3287 + {
3288 +- return t->ealgos & (1 << d->desc.sadb_alg_id);
3289 ++ unsigned int id = d->desc.sadb_alg_id;
3290 ++
3291 ++ if (id >= sizeof(t->ealgos) * 8)
3292 ++ return 0;
3293 ++
3294 ++ return (t->ealgos >> id) & 1;
3295 + }
3296 +
3297 + static int count_ah_combs(struct xfrm_tmpl *t)
3298 +diff -NurpP linux-2.6.22.12/net/netfilter/nf_conntrack_proto_tcp.c linux-2.6.22.18/net/netfilter/nf_conntrack_proto_tcp.c
3299 +--- linux-2.6.22.12/net/netfilter/nf_conntrack_proto_tcp.c 2007-11-05 18:59:33.000000000 +0100
3300 ++++ linux-2.6.22.18/net/netfilter/nf_conntrack_proto_tcp.c 2008-02-11 08:31:19.000000000 +0100
3301 +@@ -839,6 +839,22 @@ static int tcp_packet(struct nf_conn *co
3302 + new_state = tcp_conntracks[dir][index][old_state];
3303 +
3304 + switch (new_state) {
3305 ++ case TCP_CONNTRACK_SYN_SENT:
3306 ++ if (old_state < TCP_CONNTRACK_TIME_WAIT)
3307 ++ break;
3308 ++ if ((conntrack->proto.tcp.seen[!dir].flags &
3309 ++ IP_CT_TCP_FLAG_CLOSE_INIT)
3310 ++ || (conntrack->proto.tcp.last_dir == dir
3311 ++ && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
3312 ++ /* Attempt to reopen a closed/aborted connection.
3313 ++ * Delete this connection and look up again. */
3314 ++ write_unlock_bh(&tcp_lock);
3315 ++ if (del_timer(&conntrack->timeout))
3316 ++ conntrack->timeout.function((unsigned long)
3317 ++ conntrack);
3318 ++ return -NF_REPEAT;
3319 ++ }
3320 ++ /* Fall through */
3321 + case TCP_CONNTRACK_IGNORE:
3322 + /* Ignored packets:
3323 + *
3324 +@@ -888,27 +904,6 @@ static int tcp_packet(struct nf_conn *co
3325 + nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
3326 + "nf_ct_tcp: invalid state ");
3327 + return -NF_ACCEPT;
3328 +- case TCP_CONNTRACK_SYN_SENT:
3329 +- if (old_state < TCP_CONNTRACK_TIME_WAIT)
3330 +- break;
3331 +- if ((conntrack->proto.tcp.seen[dir].flags &
3332 +- IP_CT_TCP_FLAG_CLOSE_INIT)
3333 +- || after(ntohl(th->seq),
3334 +- conntrack->proto.tcp.seen[dir].td_end)) {
3335 +- /* Attempt to reopen a closed connection.
3336 +- * Delete this connection and look up again. */
3337 +- write_unlock_bh(&tcp_lock);
3338 +- if (del_timer(&conntrack->timeout))
3339 +- conntrack->timeout.function((unsigned long)
3340 +- conntrack);
3341 +- return -NF_REPEAT;
3342 +- } else {
3343 +- write_unlock_bh(&tcp_lock);
3344 +- if (LOG_INVALID(IPPROTO_TCP))
3345 +- nf_log_packet(pf, 0, skb, NULL, NULL,
3346 +- NULL, "nf_ct_tcp: invalid SYN");
3347 +- return -NF_ACCEPT;
3348 +- }
3349 + case TCP_CONNTRACK_CLOSE:
3350 + if (index == TCP_RST_SET
3351 + && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
3352 +@@ -941,6 +936,7 @@ static int tcp_packet(struct nf_conn *co
3353 + in_window:
3354 + /* From now on we have got in-window packets */
3355 + conntrack->proto.tcp.last_index = index;
3356 ++ conntrack->proto.tcp.last_dir = dir;
3357 +
3358 + DEBUGP("tcp_conntracks: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
3359 + "syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
3360 +diff -NurpP linux-2.6.22.12/net/netfilter/xt_TCPMSS.c linux-2.6.22.18/net/netfilter/xt_TCPMSS.c
3361 +--- linux-2.6.22.12/net/netfilter/xt_TCPMSS.c 2007-11-05 18:59:33.000000000 +0100
3362 ++++ linux-2.6.22.18/net/netfilter/xt_TCPMSS.c 2008-02-11 08:31:19.000000000 +0100
3363 +@@ -178,10 +178,8 @@ xt_tcpmss_target6(struct sk_buff **pskb,
3364 +
3365 + nexthdr = ipv6h->nexthdr;
3366 + tcphoff = ipv6_skip_exthdr(*pskb, sizeof(*ipv6h), &nexthdr);
3367 +- if (tcphoff < 0) {
3368 +- WARN_ON(1);
3369 ++ if (tcphoff < 0)
3370 + return NF_DROP;
3371 +- }
3372 + ret = tcpmss_mangle_packet(pskb, targinfo, tcphoff,
3373 + sizeof(*ipv6h) + sizeof(struct tcphdr));
3374 + if (ret < 0)
3375 +diff -NurpP linux-2.6.22.12/net/netlink/af_netlink.c linux-2.6.22.18/net/netlink/af_netlink.c
3376 +--- linux-2.6.22.12/net/netlink/af_netlink.c 2007-11-05 18:59:33.000000000 +0100
3377 ++++ linux-2.6.22.18/net/netlink/af_netlink.c 2008-02-11 08:31:19.000000000 +0100
3378 +@@ -732,7 +732,7 @@ struct sock *netlink_getsockbyfilp(struc
3379 + * 1: repeat lookup - reference dropped while waiting for socket memory.
3380 + */
3381 + int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
3382 +- long timeo, struct sock *ssk)
3383 ++ long *timeo, struct sock *ssk)
3384 + {
3385 + struct netlink_sock *nlk;
3386 +
3387 +@@ -741,7 +741,7 @@ int netlink_attachskb(struct sock *sk, s
3388 + if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
3389 + test_bit(0, &nlk->state)) {
3390 + DECLARE_WAITQUEUE(wait, current);
3391 +- if (!timeo) {
3392 ++ if (!*timeo) {
3393 + if (!ssk || nlk_sk(ssk)->pid == 0)
3394 + netlink_overrun(sk);
3395 + sock_put(sk);
3396 +@@ -755,7 +755,7 @@ int netlink_attachskb(struct sock *sk, s
3397 + if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
3398 + test_bit(0, &nlk->state)) &&
3399 + !sock_flag(sk, SOCK_DEAD))
3400 +- timeo = schedule_timeout(timeo);
3401 ++ *timeo = schedule_timeout(*timeo);
3402 +
3403 + __set_current_state(TASK_RUNNING);
3404 + remove_wait_queue(&nlk->wait, &wait);
3405 +@@ -763,7 +763,7 @@ int netlink_attachskb(struct sock *sk, s
3406 +
3407 + if (signal_pending(current)) {
3408 + kfree_skb(skb);
3409 +- return sock_intr_errno(timeo);
3410 ++ return sock_intr_errno(*timeo);
3411 + }
3412 + return 1;
3413 + }
3414 +@@ -827,7 +827,7 @@ retry:
3415 + kfree_skb(skb);
3416 + return PTR_ERR(sk);
3417 + }
3418 +- err = netlink_attachskb(sk, skb, nonblock, timeo, ssk);
3419 ++ err = netlink_attachskb(sk, skb, nonblock, &timeo, ssk);
3420 + if (err == 1)
3421 + goto retry;
3422 + if (err)
3423 +diff -NurpP linux-2.6.22.12/net/netrom/nr_dev.c linux-2.6.22.18/net/netrom/nr_dev.c
3424 +--- linux-2.6.22.12/net/netrom/nr_dev.c 2007-11-05 18:59:33.000000000 +0100
3425 ++++ linux-2.6.22.18/net/netrom/nr_dev.c 2008-02-11 08:31:19.000000000 +0100
3426 +@@ -56,7 +56,7 @@ int nr_rx_ip(struct sk_buff *skb, struct
3427 +
3428 + /* Spoof incoming device */
3429 + skb->dev = dev;
3430 +- skb_reset_mac_header(skb);
3431 ++ skb->mac_header = skb->network_header;
3432 + skb_reset_network_header(skb);
3433 + skb->pkt_type = PACKET_HOST;
3434 +
3435 +diff -NurpP linux-2.6.22.12/net/rxrpc/Kconfig linux-2.6.22.18/net/rxrpc/Kconfig
3436 +--- linux-2.6.22.12/net/rxrpc/Kconfig 2007-11-05 18:59:33.000000000 +0100
3437 ++++ linux-2.6.22.18/net/rxrpc/Kconfig 2008-02-11 08:31:19.000000000 +0100
3438 +@@ -5,6 +5,7 @@
3439 + config AF_RXRPC
3440 + tristate "RxRPC session sockets"
3441 + depends on INET && EXPERIMENTAL
3442 ++ select CRYPTO
3443 + select KEYS
3444 + help
3445 + Say Y or M here to include support for RxRPC session sockets (just
3446 +diff -NurpP linux-2.6.22.12/net/sched/cls_u32.c linux-2.6.22.18/net/sched/cls_u32.c
3447 +--- linux-2.6.22.12/net/sched/cls_u32.c 2007-11-05 18:59:33.000000000 +0100
3448 ++++ linux-2.6.22.18/net/sched/cls_u32.c 2008-02-11 08:31:19.000000000 +0100
3449 +@@ -107,7 +107,7 @@ static struct tc_u_common *u32_list;
3450 +
3451 + static __inline__ unsigned u32_hash_fold(u32 key, struct tc_u32_sel *sel, u8 fshift)
3452 + {
3453 +- unsigned h = (key & sel->hmask)>>fshift;
3454 ++ unsigned h = ntohl(key & sel->hmask)>>fshift;
3455 +
3456 + return h;
3457 + }
3458 +@@ -631,7 +631,7 @@ static int u32_change(struct tcf_proto *
3459 + n->handle = handle;
3460 + {
3461 + u8 i = 0;
3462 +- u32 mask = s->hmask;
3463 ++ u32 mask = ntohl(s->hmask);
3464 + if (mask) {
3465 + while (!(mask & 1)) {
3466 + i++;
3467 +diff -NurpP linux-2.6.22.12/net/sched/sch_teql.c linux-2.6.22.18/net/sched/sch_teql.c
3468 +--- linux-2.6.22.12/net/sched/sch_teql.c 2007-11-05 18:59:33.000000000 +0100
3469 ++++ linux-2.6.22.18/net/sched/sch_teql.c 2008-02-11 08:31:19.000000000 +0100
3470 +@@ -263,6 +263,9 @@ __teql_resolve(struct sk_buff *skb, stru
3471 + static __inline__ int
3472 + teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev)
3473 + {
3474 ++ if (dev->qdisc == &noop_qdisc)
3475 ++ return -ENODEV;
3476 ++
3477 + if (dev->hard_header == NULL ||
3478 + skb->dst == NULL ||
3479 + skb->dst->neighbour == NULL)
3480 +diff -NurpP linux-2.6.22.12/net/socket.c linux-2.6.22.18/net/socket.c
3481 +--- linux-2.6.22.12/net/socket.c 2007-11-05 18:59:33.000000000 +0100
3482 ++++ linux-2.6.22.18/net/socket.c 2008-02-11 08:31:19.000000000 +0100
3483 +@@ -1246,11 +1246,14 @@ asmlinkage long sys_socketpair(int famil
3484 + goto out_release_both;
3485 +
3486 + fd1 = sock_alloc_fd(&newfile1);
3487 +- if (unlikely(fd1 < 0))
3488 ++ if (unlikely(fd1 < 0)) {
3489 ++ err = fd1;
3490 + goto out_release_both;
3491 ++ }
3492 +
3493 + fd2 = sock_alloc_fd(&newfile2);
3494 + if (unlikely(fd2 < 0)) {
3495 ++ err = fd2;
3496 + put_filp(newfile1);
3497 + put_unused_fd(fd1);
3498 + goto out_release_both;
3499 +diff -NurpP linux-2.6.22.12/net/unix/af_unix.c linux-2.6.22.18/net/unix/af_unix.c
3500 +--- linux-2.6.22.12/net/unix/af_unix.c 2007-11-05 18:59:33.000000000 +0100
3501 ++++ linux-2.6.22.18/net/unix/af_unix.c 2008-02-11 08:31:19.000000000 +0100
3502 +@@ -1608,8 +1608,15 @@ static int unix_dgram_recvmsg(struct kio
3503 + mutex_lock(&u->readlock);
3504 +
3505 + skb = skb_recv_datagram(sk, flags, noblock, &err);
3506 +- if (!skb)
3507 ++ if (!skb) {
3508 ++ unix_state_lock(sk);
3509 ++ /* Signal EOF on disconnected non-blocking SEQPACKET socket. */
3510 ++ if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN &&
3511 ++ (sk->sk_shutdown & RCV_SHUTDOWN))
3512 ++ err = 0;
3513 ++ unix_state_unlock(sk);
3514 + goto out_unlock;
3515 ++ }
3516 +
3517 + wake_up_interruptible(&u->peer_wait);
3518 +
3519 +diff -NurpP linux-2.6.22.12/net/x25/x25_forward.c linux-2.6.22.18/net/x25/x25_forward.c
3520 +--- linux-2.6.22.12/net/x25/x25_forward.c 2007-11-05 18:59:33.000000000 +0100
3521 ++++ linux-2.6.22.18/net/x25/x25_forward.c 2008-02-11 08:31:19.000000000 +0100
3522 +@@ -118,13 +118,14 @@ int x25_forward_data(int lci, struct x25
3523 + goto out;
3524 +
3525 + if ( (skbn = pskb_copy(skb, GFP_ATOMIC)) == NULL){
3526 +- goto out;
3527 ++ goto output;
3528 +
3529 + }
3530 + x25_transmit_link(skbn, nb);
3531 +
3532 +- x25_neigh_put(nb);
3533 + rc = 1;
3534 ++output:
3535 ++ x25_neigh_put(nb);
3536 + out:
3537 + return rc;
3538 + }
3539 +diff -NurpP linux-2.6.22.12/net/xfrm/xfrm_policy.c linux-2.6.22.18/net/xfrm/xfrm_policy.c
3540 +--- linux-2.6.22.12/net/xfrm/xfrm_policy.c 2007-11-05 18:59:33.000000000 +0100
3541 ++++ linux-2.6.22.18/net/xfrm/xfrm_policy.c 2008-02-11 08:31:19.000000000 +0100
3542 +@@ -1479,8 +1479,9 @@ restart:
3543 +
3544 + if (sk && sk->sk_policy[1]) {
3545 + policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
3546 ++ err = PTR_ERR(policy);
3547 + if (IS_ERR(policy))
3548 +- return PTR_ERR(policy);
3549 ++ goto dropdst;
3550 + }
3551 +
3552 + if (!policy) {
3553 +@@ -1491,8 +1492,9 @@ restart:
3554 +
3555 + policy = flow_cache_lookup(fl, dst_orig->ops->family,
3556 + dir, xfrm_policy_lookup);
3557 ++ err = PTR_ERR(policy);
3558 + if (IS_ERR(policy))
3559 +- return PTR_ERR(policy);
3560 ++ goto dropdst;
3561 + }
3562 +
3563 + if (!policy)
3564 +@@ -1661,8 +1663,9 @@ restart:
3565 + return 0;
3566 +
3567 + error:
3568 +- dst_release(dst_orig);
3569 + xfrm_pols_put(pols, npols);
3570 ++dropdst:
3571 ++ dst_release(dst_orig);
3572 + *dst_p = NULL;
3573 + return err;
3574 + }
3575 +diff -NurpP linux-2.6.22.12/net/xfrm/xfrm_state.c linux-2.6.22.18/net/xfrm/xfrm_state.c
3576 +--- linux-2.6.22.12/net/xfrm/xfrm_state.c 2007-11-05 18:59:33.000000000 +0100
3577 ++++ linux-2.6.22.18/net/xfrm/xfrm_state.c 2008-02-11 08:31:19.000000000 +0100
3578 +@@ -371,7 +371,7 @@ int __xfrm_state_delete(struct xfrm_stat
3579 + * The xfrm_state_alloc call gives a reference, and that
3580 + * is what we are dropping here.
3581 + */
3582 +- __xfrm_state_put(x);
3583 ++ xfrm_state_put(x);
3584 + err = 0;
3585 + }
3586 +
3587 +diff -NurpP linux-2.6.22.12/sound/oss/via82cxxx_audio.c linux-2.6.22.18/sound/oss/via82cxxx_audio.c
3588 +--- linux-2.6.22.12/sound/oss/via82cxxx_audio.c 2007-11-05 18:59:33.000000000 +0100
3589 ++++ linux-2.6.22.18/sound/oss/via82cxxx_audio.c 2008-02-11 08:31:19.000000000 +0100
3590 +@@ -2104,6 +2104,7 @@ static struct page * via_mm_nopage (stru
3591 + {
3592 + struct via_info *card = vma->vm_private_data;
3593 + struct via_channel *chan = &card->ch_out;
3594 ++ unsigned long max_bufs;
3595 + struct page *dmapage;
3596 + unsigned long pgoff;
3597 + int rd, wr;
3598 +@@ -2127,14 +2128,11 @@ static struct page * via_mm_nopage (stru
3599 + rd = card->ch_in.is_mapped;
3600 + wr = card->ch_out.is_mapped;
3601 +
3602 +-#ifndef VIA_NDEBUG
3603 +- {
3604 +- unsigned long max_bufs = chan->frag_number;
3605 +- if (rd && wr) max_bufs *= 2;
3606 +- /* via_dsp_mmap() should ensure this */
3607 +- assert (pgoff < max_bufs);
3608 +- }
3609 +-#endif
3610 ++ max_bufs = chan->frag_number;
3611 ++ if (rd && wr)
3612 ++ max_bufs *= 2;
3613 ++ if (pgoff >= max_bufs)
3614 ++ return NOPAGE_SIGBUS;
3615 +
3616 + /* if full-duplex (read+write) and we have two sets of bufs,
3617 + * then the playback buffers come first, sez soundcard.c */
3618 +diff -NurpP linux-2.6.22.12/sound/pci/hda/patch_sigmatel.c linux-2.6.22.18/sound/pci/hda/patch_sigmatel.c
3619 +--- linux-2.6.22.12/sound/pci/hda/patch_sigmatel.c 2007-11-05 18:59:33.000000000 +0100
3620 ++++ linux-2.6.22.18/sound/pci/hda/patch_sigmatel.c 2008-02-11 08:31:19.000000000 +0100
3621 +@@ -153,8 +153,9 @@ static hda_nid_t stac925x_dac_nids[1] =
3622 + 0x02,
3623 + };
3624 +
3625 +-static hda_nid_t stac925x_dmic_nids[1] = {
3626 +- 0x15,
3627 ++#define STAC925X_NUM_DMICS 1
3628 ++static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
3629 ++ 0x15, 0
3630 + };
3631 +
3632 + static hda_nid_t stac922x_adc_nids[2] = {
3633 +@@ -181,8 +182,9 @@ static hda_nid_t stac9205_mux_nids[2] =
3634 + 0x19, 0x1a
3635 + };
3636 +
3637 +-static hda_nid_t stac9205_dmic_nids[2] = {
3638 +- 0x17, 0x18,
3639 ++#define STAC9205_NUM_DMICS 2
3640 ++static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
3641 ++ 0x17, 0x18, 0
3642 + };
3643 +
3644 + static hda_nid_t stac9200_pin_nids[8] = {
3645 +@@ -1972,7 +1974,7 @@ static int patch_stac925x(struct hda_cod
3646 + case 0x83847633: /* STAC9202D */
3647 + case 0x83847636: /* STAC9251 */
3648 + case 0x83847637: /* STAC9251D */
3649 +- spec->num_dmics = 1;
3650 ++ spec->num_dmics = STAC925X_NUM_DMICS;
3651 + spec->dmic_nids = stac925x_dmic_nids;
3652 + break;
3653 + default:
3654 +@@ -2202,7 +2204,7 @@ static int patch_stac9205(struct hda_cod
3655 + spec->mux_nids = stac9205_mux_nids;
3656 + spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
3657 + spec->dmic_nids = stac9205_dmic_nids;
3658 +- spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids);
3659 ++ spec->num_dmics = STAC9205_NUM_DMICS;
3660 + spec->dmux_nid = 0x1d;
3661 +
3662 + spec->init = stac9205_core_init;
3663 +diff -NurpP linux-2.6.22.12/sound/pci/rme9652/hdsp.c linux-2.6.22.18/sound/pci/rme9652/hdsp.c
3664 +--- linux-2.6.22.12/sound/pci/rme9652/hdsp.c 2007-11-05 18:59:33.000000000 +0100
3665 ++++ linux-2.6.22.18/sound/pci/rme9652/hdsp.c 2008-02-11 08:31:19.000000000 +0100
3666 +@@ -3108,6 +3108,9 @@ static int hdsp_dds_offset(struct hdsp *
3667 + unsigned int dds_value = hdsp->dds_value;
3668 + int system_sample_rate = hdsp->system_sample_rate;
3669 +
3670 ++ if (!dds_value)
3671 ++ return 0;
3672 ++
3673 + n = DDS_NUMERATOR;
3674 + /*
3675 + * dds_value = n / rate
3676 +diff -NurpP linux-2.6.22.12/sound/usb/usx2y/usX2Yhwdep.c linux-2.6.22.18/sound/usb/usx2y/usX2Yhwdep.c
3677 +--- linux-2.6.22.12/sound/usb/usx2y/usX2Yhwdep.c 2007-11-05 18:59:33.000000000 +0100
3678 ++++ linux-2.6.22.18/sound/usb/usx2y/usX2Yhwdep.c 2008-02-11 08:31:19.000000000 +0100
3679 +@@ -88,7 +88,7 @@ static int snd_us428ctls_mmap(struct snd
3680 + us428->us428ctls_sharedmem->CtlSnapShotLast = -2;
3681 + }
3682 + area->vm_ops = &us428ctls_vm_ops;
3683 +- area->vm_flags |= VM_RESERVED;
3684 ++ area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
3685 + area->vm_private_data = hw->private_data;
3686 + return 0;
3687 + }
3688 +diff -NurpP linux-2.6.22.12/sound/usb/usx2y/usx2yhwdeppcm.c linux-2.6.22.18/sound/usb/usx2y/usx2yhwdeppcm.c
3689 +--- linux-2.6.22.12/sound/usb/usx2y/usx2yhwdeppcm.c 2007-11-05 18:59:33.000000000 +0100
3690 ++++ linux-2.6.22.18/sound/usb/usx2y/usx2yhwdeppcm.c 2008-02-11 08:31:19.000000000 +0100
3691 +@@ -728,7 +728,7 @@ static int snd_usX2Y_hwdep_pcm_mmap(stru
3692 + return -ENODEV;
3693 + }
3694 + area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
3695 +- area->vm_flags |= VM_RESERVED;
3696 ++ area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
3697 + area->vm_private_data = hw->private_data;
3698 + return 0;
3699 + }
3700
3701 Added: vserver-sources/2.2.0.7/1013_linux-2.6.22.19.patch
3702 ===================================================================
3703 --- vserver-sources/2.2.0.7/1013_linux-2.6.22.19.patch (rev 0)
3704 +++ vserver-sources/2.2.0.7/1013_linux-2.6.22.19.patch 2008-03-17 10:10:12 UTC (rev 557)
3705 @@ -0,0 +1,1031 @@
3706 +diff -NurpP linux-2.6.22.18/arch/i386/kernel/entry.S linux-2.6.22.19/arch/i386/kernel/entry.S
3707 +--- linux-2.6.22.18/arch/i386/kernel/entry.S 2008-02-11 08:31:19.000000000 +0100
3708 ++++ linux-2.6.22.19/arch/i386/kernel/entry.S 2008-02-26 00:59:40.000000000 +0100
3709 +@@ -409,8 +409,6 @@ restore_nocheck_notrace:
3710 + 1: INTERRUPT_RETURN
3711 + .section .fixup,"ax"
3712 + iret_exc:
3713 +- TRACE_IRQS_ON
3714 +- ENABLE_INTERRUPTS(CLBR_NONE)
3715 + pushl $0 # no error code
3716 + pushl $do_iret_error
3717 + jmp error_code
3718 +diff -NurpP linux-2.6.22.18/arch/i386/kernel/ptrace.c linux-2.6.22.19/arch/i386/kernel/ptrace.c
3719 +--- linux-2.6.22.18/arch/i386/kernel/ptrace.c 2008-02-11 08:31:19.000000000 +0100
3720 ++++ linux-2.6.22.19/arch/i386/kernel/ptrace.c 2008-02-26 00:59:40.000000000 +0100
3721 +@@ -164,14 +164,22 @@ static unsigned long convert_eip_to_line
3722 + u32 *desc;
3723 + unsigned long base;
3724 +
3725 +- down(&child->mm->context.sem);
3726 +- desc = child->mm->context.ldt + (seg & ~7);
3727 +- base = (desc[0] >> 16) | ((desc[1] & 0xff) << 16) | (desc[1] & 0xff000000);
3728 ++ seg &= ~7UL;
3729 +
3730 +- /* 16-bit code segment? */
3731 +- if (!((desc[1] >> 22) & 1))
3732 +- addr &= 0xffff;
3733 +- addr += base;
3734 ++ down(&child->mm->context.sem);
3735 ++ if (unlikely((seg >> 3) >= child->mm->context.size))
3736 ++ addr = -1L; /* bogus selector, access would fault */
3737 ++ else {
3738 ++ desc = child->mm->context.ldt + seg;
3739 ++ base = ((desc[0] >> 16) |
3740 ++ ((desc[1] & 0xff) << 16) |
3741 ++ (desc[1] & 0xff000000));
3742 ++
3743 ++ /* 16-bit code segment? */
3744 ++ if (!((desc[1] >> 22) & 1))
3745 ++ addr &= 0xffff;
3746 ++ addr += base;
3747 ++ }
3748 + up(&child->mm->context.sem);
3749 + }
3750 + return addr;
3751 +diff -NurpP linux-2.6.22.18/arch/i386/kernel/traps.c linux-2.6.22.19/arch/i386/kernel/traps.c
3752 +--- linux-2.6.22.18/arch/i386/kernel/traps.c 2008-02-11 08:31:19.000000000 +0100
3753 ++++ linux-2.6.22.19/arch/i386/kernel/traps.c 2008-02-26 00:59:40.000000000 +0100
3754 +@@ -517,10 +517,12 @@ fastcall void do_##name(struct pt_regs *
3755 + do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \
3756 + }
3757 +
3758 +-#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
3759 ++#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr, irq) \
3760 + fastcall void do_##name(struct pt_regs * regs, long error_code) \
3761 + { \
3762 + siginfo_t info; \
3763 ++ if (irq) \
3764 ++ local_irq_enable(); \
3765 + info.si_signo = signr; \
3766 + info.si_errno = 0; \
3767 + info.si_code = sicode; \
3768 +@@ -560,13 +562,13 @@ DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
3769 + #endif
3770 + DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
3771 + DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
3772 +-DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->eip)
3773 ++DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->eip, 0)
3774 + DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun)
3775 + DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
3776 + DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
3777 + DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
3778 +-DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
3779 +-DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
3780 ++DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0)
3781 ++DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0, 1)
3782 +
3783 + fastcall void __kprobes do_general_protection(struct pt_regs * regs,
3784 + long error_code)
3785 +diff -NurpP linux-2.6.22.18/arch/x86_64/kernel/ptrace.c linux-2.6.22.19/arch/x86_64/kernel/ptrace.c
3786 +--- linux-2.6.22.18/arch/x86_64/kernel/ptrace.c 2008-02-11 08:31:19.000000000 +0100
3787 ++++ linux-2.6.22.19/arch/x86_64/kernel/ptrace.c 2008-02-26 00:59:40.000000000 +0100
3788 +@@ -102,16 +102,25 @@ unsigned long convert_rip_to_linear(stru
3789 + u32 *desc;
3790 + unsigned long base;
3791 +
3792 +- down(&child->mm->context.sem);
3793 +- desc = child->mm->context.ldt + (seg & ~7);
3794 +- base = (desc[0] >> 16) | ((desc[1] & 0xff) << 16) | (desc[1] & 0xff000000);
3795 ++ seg &= ~7UL;
3796 +
3797 +- /* 16-bit code segment? */
3798 +- if (!((desc[1] >> 22) & 1))
3799 +- addr &= 0xffff;
3800 +- addr += base;
3801 ++ down(&child->mm->context.sem);
3802 ++ if (unlikely((seg >> 3) >= child->mm->context.size))
3803 ++ addr = -1L; /* bogus selector, access would fault */
3804 ++ else {
3805 ++ desc = child->mm->context.ldt + seg;
3806 ++ base = ((desc[0] >> 16) |
3807 ++ ((desc[1] & 0xff) << 16) |
3808 ++ (desc[1] & 0xff000000));
3809 ++
3810 ++ /* 16-bit code segment? */
3811 ++ if (!((desc[1] >> 22) & 1))
3812 ++ addr &= 0xffff;
3813 ++ addr += base;
3814 ++ }
3815 + up(&child->mm->context.sem);
3816 + }
3817 ++
3818 + return addr;
3819 + }
3820 +
3821 +diff -NurpP linux-2.6.22.18/drivers/ata/sata_promise.c linux-2.6.22.19/drivers/ata/sata_promise.c
3822 +--- linux-2.6.22.18/drivers/ata/sata_promise.c 2008-02-11 08:31:19.000000000 +0100
3823 ++++ linux-2.6.22.19/drivers/ata/sata_promise.c 2008-02-26 00:59:40.000000000 +0100
3824 +@@ -51,6 +51,7 @@
3825 + enum {
3826 + PDC_MAX_PORTS = 4,
3827 + PDC_MMIO_BAR = 3,
3828 ++ PDC_MAX_PRD = LIBATA_MAX_PRD - 1, /* -1 for ASIC PRD bug workaround */
3829 +
3830 + /* register offsets */
3831 + PDC_FEATURE = 0x04, /* Feature/Error reg (per port) */
3832 +@@ -157,7 +158,7 @@ static struct scsi_host_template pdc_ata
3833 + .queuecommand = ata_scsi_queuecmd,
3834 + .can_queue = ATA_DEF_QUEUE,
3835 + .this_id = ATA_SHT_THIS_ID,
3836 +- .sg_tablesize = LIBATA_MAX_PRD,
3837 ++ .sg_tablesize = PDC_MAX_PRD,
3838 + .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
3839 + .emulated = ATA_SHT_EMULATED,
3840 + .use_clustering = ATA_SHT_USE_CLUSTERING,
3841 +@@ -330,8 +331,8 @@ static const struct pci_device_id pdc_at
3842 +
3843 + { PCI_VDEVICE(PROMISE, 0x3318), board_20319 },
3844 + { PCI_VDEVICE(PROMISE, 0x3319), board_20319 },
3845 +- { PCI_VDEVICE(PROMISE, 0x3515), board_20319 },
3846 +- { PCI_VDEVICE(PROMISE, 0x3519), board_20319 },
3847 ++ { PCI_VDEVICE(PROMISE, 0x3515), board_40518 },
3848 ++ { PCI_VDEVICE(PROMISE, 0x3519), board_40518 },
3849 + { PCI_VDEVICE(PROMISE, 0x3d17), board_40518 },
3850 + { PCI_VDEVICE(PROMISE, 0x3d18), board_40518 },
3851 +
3852 +@@ -531,6 +532,84 @@ static void pdc_atapi_pkt(struct ata_que
3853 + memcpy(buf+31, cdb, cdb_len);
3854 + }
3855 +
3856 ++/**
3857 ++ * pdc_fill_sg - Fill PCI IDE PRD table
3858 ++ * @qc: Metadata associated with taskfile to be transferred
3859 ++ *
3860 ++ * Fill PCI IDE PRD (scatter-gather) table with segments
3861 ++ * associated with the current disk command.
3862 ++ * Make sure hardware does not choke on it.
3863 ++ *
3864 ++ * LOCKING:
3865 ++ * spin_lock_irqsave(host lock)
3866 ++ *
3867 ++ */
3868 ++static void pdc_fill_sg(struct ata_queued_cmd *qc)
3869 ++{
3870 ++ struct ata_port *ap = qc->ap;
3871 ++ struct scatterlist *sg;
3872 ++ unsigned int idx;
3873 ++ const u32 SG_COUNT_ASIC_BUG = 41*4;
3874 ++
3875 ++ if (!(qc->flags & ATA_QCFLAG_DMAMAP))
3876 ++ return;
3877 ++
3878 ++ WARN_ON(qc->__sg == NULL);
3879 ++ WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
3880 ++
3881 ++ idx = 0;
3882 ++ ata_for_each_sg(sg, qc) {
3883 ++ u32 addr, offset;
3884 ++ u32 sg_len, len;
3885 ++
3886 ++ /* determine if physical DMA addr spans 64K boundary.
3887 ++ * Note h/w doesn't support 64-bit, so we unconditionally
3888 ++ * truncate dma_addr_t to u32.
3889 ++ */
3890 ++ addr = (u32) sg_dma_address(sg);
3891 ++ sg_len = sg_dma_len(sg);
3892 ++
3893 ++ while (sg_len) {
3894 ++ offset = addr & 0xffff;
3895 ++ len = sg_len;
3896 ++ if ((offset + sg_len) > 0x10000)
3897 ++ len = 0x10000 - offset;
3898 ++
3899 ++ ap->prd[idx].addr = cpu_to_le32(addr);
3900 ++ ap->prd[idx].flags_len = cpu_to_le32(len & 0xffff);
3901 ++ VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len);
3902 ++
3903 ++ idx++;
3904 ++ sg_len -= len;
3905 ++ addr += len;
3906 ++ }
3907 ++ }
3908 ++
3909 ++ if (idx) {
3910 ++ u32 len = le32_to_cpu(ap->prd[idx - 1].flags_len);
3911 ++
3912 ++ if (len > SG_COUNT_ASIC_BUG) {
3913 ++ u32 addr;
3914 ++
3915 ++ VPRINTK("Splitting last PRD.\n");
3916 ++
3917 ++ addr = le32_to_cpu(ap->prd[idx - 1].addr);
3918 ++ ap->prd[idx - 1].flags_len = cpu_to_le32(len - SG_COUNT_ASIC_BUG);
3919 ++ VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx - 1, addr, SG_COUNT_ASIC_BUG);
3920 ++
3921 ++ addr = addr + len - SG_COUNT_ASIC_BUG;
3922 ++ len = SG_COUNT_ASIC_BUG;
3923 ++ ap->prd[idx].addr = cpu_to_le32(addr);
3924 ++ ap->prd[idx].flags_len = cpu_to_le32(len);
3925 ++ VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len);
3926 ++
3927 ++ idx++;
3928 ++ }
3929 ++
3930 ++ ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
3931 ++ }
3932 ++}
3933 ++
3934 + static void pdc_qc_prep(struct ata_queued_cmd *qc)
3935 + {
3936 + struct pdc_port_priv *pp = qc->ap->private_data;
3937 +@@ -540,7 +619,7 @@ static void pdc_qc_prep(struct ata_queue
3938 +
3939 + switch (qc->tf.protocol) {
3940 + case ATA_PROT_DMA:
3941 +- ata_qc_prep(qc);
3942 ++ pdc_fill_sg(qc);
3943 + /* fall through */
3944 +
3945 + case ATA_PROT_NODATA:
3946 +@@ -556,11 +635,11 @@ static void pdc_qc_prep(struct ata_queue
3947 + break;
3948 +
3949 + case ATA_PROT_ATAPI:
3950 +- ata_qc_prep(qc);
3951 ++ pdc_fill_sg(qc);
3952 + break;
3953 +
3954 + case ATA_PROT_ATAPI_DMA:
3955 +- ata_qc_prep(qc);
3956 ++ pdc_fill_sg(qc);
3957 + /*FALLTHROUGH*/
3958 + case ATA_PROT_ATAPI_NODATA:
3959 + pdc_atapi_pkt(qc);
3960 +diff -NurpP linux-2.6.22.18/drivers/block/cciss.c linux-2.6.22.19/drivers/block/cciss.c
3961 +--- linux-2.6.22.18/drivers/block/cciss.c 2008-02-11 08:31:19.000000000 +0100
3962 ++++ linux-2.6.22.19/drivers/block/cciss.c 2008-02-26 00:59:40.000000000 +0100
3963 +@@ -3225,12 +3225,15 @@ static int alloc_cciss_hba(void)
3964 + for (i = 0; i < MAX_CTLR; i++) {
3965 + if (!hba[i]) {
3966 + ctlr_info_t *p;
3967 ++
3968 + p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL);
3969 + if (!p)
3970 + goto Enomem;
3971 + p->gendisk[0] = alloc_disk(1 << NWD_SHIFT);
3972 +- if (!p->gendisk[0])
3973 ++ if (!p->gendisk[0]) {
3974 ++ kfree(p);
3975 + goto Enomem;
3976 ++ }
3977 + hba[i] = p;
3978 + return i;
3979 + }
3980 +diff -NurpP linux-2.6.22.18/drivers/char/agp/intel-agp.c linux-2.6.22.19/drivers/char/agp/intel-agp.c
3981 +--- linux-2.6.22.18/drivers/char/agp/intel-agp.c 2008-02-11 08:31:19.000000000 +0100
3982 ++++ linux-2.6.22.19/drivers/char/agp/intel-agp.c 2008-02-26 00:59:40.000000000 +0100
3983 +@@ -20,7 +20,9 @@
3984 + #define PCI_DEVICE_ID_INTEL_82965G_IG 0x29A2
3985 + #define PCI_DEVICE_ID_INTEL_82965GM_HB 0x2A00
3986 + #define PCI_DEVICE_ID_INTEL_82965GM_IG 0x2A02
3987 ++#define PCI_DEVICE_ID_INTEL_82965GME_HB 0x2A10
3988 + #define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12
3989 ++#define PCI_DEVICE_ID_INTEL_82945GME_HB 0x27AC
3990 + #define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE
3991 + #define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0
3992 + #define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2
3993 +@@ -33,7 +35,8 @@
3994 + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \
3995 + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \
3996 + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
3997 +- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB)
3998 ++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \
3999 ++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB)
4000 +
4001 + #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
4002 + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
4003 +@@ -527,6 +530,7 @@ static void intel_i830_init_gtt_entries(
4004 + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
4005 + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
4006 + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
4007 ++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB ||
4008 + IS_I965 || IS_G33)
4009 + gtt_entries = MB(48) - KB(size);
4010 + else
4011 +@@ -538,6 +542,7 @@ static void intel_i830_init_gtt_entries(
4012 + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
4013 + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
4014 + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
4015 ++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB ||
4016 + IS_I965 || IS_G33)
4017 + gtt_entries = MB(64) - KB(size);
4018 + else
4019 +@@ -1848,9 +1853,9 @@ static const struct intel_driver_descrip
4020 + NULL, &intel_915_driver },
4021 + { PCI_DEVICE_ID_INTEL_82945G_HB, PCI_DEVICE_ID_INTEL_82945G_IG, 0, "945G",
4022 + NULL, &intel_915_driver },
4023 +- { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, 1, "945GM",
4024 ++ { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, 0, "945GM",
4025 + NULL, &intel_915_driver },
4026 +- { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, 0, "945GME",
4027 ++ { PCI_DEVICE_ID_INTEL_82945GME_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, 0, "945GME",
4028 + NULL, &intel_915_driver },
4029 + { PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, 0, "946GZ",
4030 + NULL, &intel_i965_driver },
4031 +@@ -1860,9 +1865,9 @@ static const struct intel_driver_descrip
4032 + NULL, &intel_i965_driver },
4033 + { PCI_DEVICE_ID_INTEL_82965G_HB, PCI_DEVICE_ID_INTEL_82965G_IG, 0, "965G",
4034 + NULL, &intel_i965_driver },
4035 +- { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, 1, "965GM",
4036 ++ { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, 0, "965GM",
4037 + NULL, &intel_i965_driver },
4038 +- { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, 0, "965GME/GLE",
4039 ++ { PCI_DEVICE_ID_INTEL_82965GME_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, 0, "965GME/GLE",
4040 + NULL, &intel_i965_driver },
4041 + { PCI_DEVICE_ID_INTEL_7505_0, 0, 0, "E7505", &intel_7505_driver, NULL },
4042 + { PCI_DEVICE_ID_INTEL_7205_0, 0, 0, "E7205", &intel_7505_driver, NULL },
4043 +@@ -2051,11 +2056,13 @@ static struct pci_device_id agp_intel_pc
4044 + ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
4045 + ID(PCI_DEVICE_ID_INTEL_82945G_HB),
4046 + ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
4047 ++ ID(PCI_DEVICE_ID_INTEL_82945GME_HB),
4048 + ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
4049 + ID(PCI_DEVICE_ID_INTEL_82965G_1_HB),
4050 + ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
4051 + ID(PCI_DEVICE_ID_INTEL_82965G_HB),
4052 + ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
4053 ++ ID(PCI_DEVICE_ID_INTEL_82965GME_HB),
4054 + ID(PCI_DEVICE_ID_INTEL_G33_HB),
4055 + ID(PCI_DEVICE_ID_INTEL_Q35_HB),
4056 + ID(PCI_DEVICE_ID_INTEL_Q33_HB),
4057 +diff -NurpP linux-2.6.22.18/drivers/char/ipmi/ipmi_si_intf.c linux-2.6.22.19/drivers/char/ipmi/ipmi_si_intf.c
4058 +--- linux-2.6.22.18/drivers/char/ipmi/ipmi_si_intf.c 2008-02-11 08:31:19.000000000 +0100
4059 ++++ linux-2.6.22.19/drivers/char/ipmi/ipmi_si_intf.c 2008-02-26 00:59:40.000000000 +0100
4060 +@@ -2214,7 +2214,8 @@ static int ipmi_pci_resume(struct pci_de
4061 +
4062 + static struct pci_device_id ipmi_pci_devices[] = {
4063 + { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) },
4064 +- { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) }
4065 ++ { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) },
4066 ++ { 0, }
4067 + };
4068 + MODULE_DEVICE_TABLE(pci, ipmi_pci_devices);
4069 +
4070 +diff -NurpP linux-2.6.22.18/drivers/media/video/usbvision/usbvision-cards.c linux-2.6.22.19/drivers/media/video/usbvision/usbvision-cards.c
4071 +--- linux-2.6.22.18/drivers/media/video/usbvision/usbvision-cards.c 2008-02-11 08:31:19.000000000 +0100
4072 ++++ linux-2.6.22.19/drivers/media/video/usbvision/usbvision-cards.c 2008-02-26 00:59:40.000000000 +0100
4073 +@@ -1081,6 +1081,7 @@ struct usb_device_id usbvision_table []
4074 + { USB_DEVICE(0x2304, 0x0301), .driver_info=PINNA_LINX_VD_IN_CAB_PAL },
4075 + { USB_DEVICE(0x2304, 0x0419), .driver_info=PINNA_PCTV_BUNGEE_PAL_FM },
4076 + { USB_DEVICE(0x2400, 0x4200), .driver_info=HPG_WINTV },
4077 ++ { }, /* terminate list */
4078 + };
4079 +
4080 + MODULE_DEVICE_TABLE (usb, usbvision_table);
4081 +diff -NurpP linux-2.6.22.18/drivers/misc/sony-laptop.c linux-2.6.22.19/drivers/misc/sony-laptop.c
4082 +--- linux-2.6.22.18/drivers/misc/sony-laptop.c 2008-02-11 08:31:19.000000000 +0100
4083 ++++ linux-2.6.22.19/drivers/misc/sony-laptop.c 2008-02-26 00:59:40.000000000 +0100
4084 +@@ -2056,8 +2056,6 @@ static int sony_pic_remove(struct acpi_d
4085 + struct sony_pic_ioport *io, *tmp_io;
4086 + struct sony_pic_irq *irq, *tmp_irq;
4087 +
4088 +- sonypi_compat_exit();
4089 +-
4090 + if (sony_pic_disable(device)) {
4091 + printk(KERN_ERR DRV_PFX "Couldn't disable device.\n");
4092 + return -ENXIO;
4093 +@@ -2067,6 +2065,8 @@ static int sony_pic_remove(struct acpi_d
4094 + release_region(spic_dev.cur_ioport->io.minimum,
4095 + spic_dev.cur_ioport->io.address_length);
4096 +
4097 ++ sonypi_compat_exit();
4098 ++
4099 + sony_laptop_remove_input();
4100 +
4101 + /* pf attrs */
4102 +@@ -2132,6 +2132,9 @@ static int sony_pic_add(struct acpi_devi
4103 + goto err_free_resources;
4104 + }
4105 +
4106 ++ if (sonypi_compat_init())
4107 ++ goto err_remove_input;
4108 ++
4109 + /* request io port */
4110 + list_for_each_entry(io, &spic_dev.ioports, list) {
4111 + if (request_region(io->io.minimum, io->io.address_length,
4112 +@@ -2146,7 +2149,7 @@ static int sony_pic_add(struct acpi_devi
4113 + if (!spic_dev.cur_ioport) {
4114 + printk(KERN_ERR DRV_PFX "Failed to request_region.\n");
4115 + result = -ENODEV;
4116 +- goto err_remove_input;
4117 ++ goto err_remove_compat;
4118 + }
4119 +
4120 + /* request IRQ */
4121 +@@ -2186,9 +2189,6 @@ static int sony_pic_add(struct acpi_devi
4122 + if (result)
4123 + goto err_remove_pf;
4124 +
4125 +- if (sonypi_compat_init())
4126 +- goto err_remove_pf;
4127 +-
4128 + return 0;
4129 +
4130 + err_remove_pf:
4131 +@@ -2204,6 +2204,9 @@ err_release_region:
4132 + release_region(spic_dev.cur_ioport->io.minimum,
4133 + spic_dev.cur_ioport->io.address_length);
4134 +
4135 ++err_remove_compat:
4136 ++ sonypi_compat_exit();
4137 ++
4138 + err_remove_input:
4139 + sony_laptop_remove_input();
4140 +
4141 +diff -NurpP linux-2.6.22.18/drivers/mtd/nand/cafe_nand.c linux-2.6.22.19/drivers/mtd/nand/cafe_nand.c
4142 +--- linux-2.6.22.18/drivers/mtd/nand/cafe_nand.c 2008-02-11 08:31:19.000000000 +0100
4143 ++++ linux-2.6.22.19/drivers/mtd/nand/cafe_nand.c 2008-02-26 00:59:40.000000000 +0100
4144 +@@ -816,7 +816,8 @@ static void __devexit cafe_nand_remove(s
4145 + }
4146 +
4147 + static struct pci_device_id cafe_nand_tbl[] = {
4148 +- { 0x11ab, 0x4100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MEMORY_FLASH << 8, 0xFFFF0 }
4149 ++ { 0x11ab, 0x4100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MEMORY_FLASH << 8, 0xFFFF0 },
4150 ++ { 0, }
4151 + };
4152 +
4153 + MODULE_DEVICE_TABLE(pci, cafe_nand_tbl);
4154 +diff -NurpP linux-2.6.22.18/drivers/net/via-velocity.c linux-2.6.22.19/drivers/net/via-velocity.c
4155 +--- linux-2.6.22.18/drivers/net/via-velocity.c 2008-02-11 08:31:19.000000000 +0100
4156 ++++ linux-2.6.22.19/drivers/net/via-velocity.c 2008-02-26 00:59:40.000000000 +0100
4157 +@@ -1075,6 +1075,9 @@ static int velocity_init_rd_ring(struct
4158 + int ret = -ENOMEM;
4159 + unsigned int rsize = sizeof(struct velocity_rd_info) *
4160 + vptr->options.numrx;
4161 ++ int mtu = vptr->dev->mtu;
4162 ++
4163 ++ vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
4164 +
4165 + vptr->rd_info = kmalloc(rsize, GFP_KERNEL);
4166 + if(vptr->rd_info == NULL)
4167 +@@ -1733,8 +1736,6 @@ static int velocity_open(struct net_devi
4168 + struct velocity_info *vptr = netdev_priv(dev);
4169 + int ret;
4170 +
4171 +- vptr->rx_buf_sz = (dev->mtu <= 1504 ? PKT_BUF_SZ : dev->mtu + 32);
4172 +-
4173 + ret = velocity_init_rings(vptr);
4174 + if (ret < 0)
4175 + goto out;
4176 +@@ -1798,6 +1799,11 @@ static int velocity_change_mtu(struct ne
4177 + return -EINVAL;
4178 + }
4179 +
4180 ++ if (!netif_running(dev)) {
4181 ++ dev->mtu = new_mtu;
4182 ++ return 0;
4183 ++ }
4184 ++
4185 + if (new_mtu != oldmtu) {
4186 + spin_lock_irqsave(&vptr->lock, flags);
4187 +
4188 +@@ -1808,12 +1814,6 @@ static int velocity_change_mtu(struct ne
4189 + velocity_free_rd_ring(vptr);
4190 +
4191 + dev->mtu = new_mtu;
4192 +- if (new_mtu > 8192)
4193 +- vptr->rx_buf_sz = 9 * 1024;
4194 +- else if (new_mtu > 4096)
4195 +- vptr->rx_buf_sz = 8192;
4196 +- else
4197 +- vptr->rx_buf_sz = 4 * 1024;
4198 +
4199 + ret = velocity_init_rd_ring(vptr);
4200 + if (ret < 0)
4201 +diff -NurpP linux-2.6.22.18/drivers/pci/hotplug/fakephp.c linux-2.6.22.19/drivers/pci/hotplug/fakephp.c
4202 +--- linux-2.6.22.18/drivers/pci/hotplug/fakephp.c 2008-02-11 08:31:19.000000000 +0100
4203 ++++ linux-2.6.22.19/drivers/pci/hotplug/fakephp.c 2008-02-26 00:59:40.000000000 +0100
4204 +@@ -39,6 +39,7 @@
4205 + #include <linux/init.h>
4206 + #include <linux/string.h>
4207 + #include <linux/slab.h>
4208 ++#include <linux/workqueue.h>
4209 + #include "../pci.h"
4210 +
4211 + #if !defined(MODULE)
4212 +@@ -63,10 +64,16 @@ struct dummy_slot {
4213 + struct list_head node;
4214 + struct hotplug_slot *slot;
4215 + struct pci_dev *dev;
4216 ++ struct work_struct remove_work;
4217 ++ unsigned long removed;
4218 + };
4219 +
4220 + static int debug;
4221 + static LIST_HEAD(slot_list);
4222 ++static struct workqueue_struct *dummyphp_wq;
4223 ++
4224 ++static void pci_rescan_worker(struct work_struct *work);
4225 ++static DECLARE_WORK(pci_rescan_work, pci_rescan_worker);
4226 +
4227 + static int enable_slot (struct hotplug_slot *slot);
4228 + static int disable_slot (struct hotplug_slot *slot);
4229 +@@ -109,7 +116,7 @@ static int add_slot(struct pci_dev *dev)
4230 + slot->name = &dev->dev.bus_id[0];
4231 + dbg("slot->name = %s\n", slot->name);
4232 +
4233 +- dslot = kmalloc(sizeof(struct dummy_slot), GFP_KERNEL);
4234 ++ dslot = kzalloc(sizeof(struct dummy_slot), GFP_KERNEL);
4235 + if (!dslot)
4236 + goto error_info;
4237 +
4238 +@@ -164,6 +171,14 @@ static void remove_slot(struct dummy_slo
4239 + err("Problem unregistering a slot %s\n", dslot->slot->name);
4240 + }
4241 +
4242 ++/* called from the single-threaded workqueue handler to remove a slot */
4243 ++static void remove_slot_worker(struct work_struct *work)
4244 ++{
4245 ++ struct dummy_slot *dslot =
4246 ++ container_of(work, struct dummy_slot, remove_work);
4247 ++ remove_slot(dslot);
4248 ++}
4249 ++
4250 + /**
4251 + * Rescan slot.
4252 + * Tries hard not to re-enable already existing devices
4253 +@@ -267,11 +282,17 @@ static inline void pci_rescan(void) {
4254 + pci_rescan_buses(&pci_root_buses);
4255 + }
4256 +
4257 ++/* called from the single-threaded workqueue handler to rescan all pci buses */
4258 ++static void pci_rescan_worker(struct work_struct *work)
4259 ++{
4260 ++ pci_rescan();
4261 ++}
4262 +
4263 + static int enable_slot(struct hotplug_slot *hotplug_slot)
4264 + {
4265 + /* mis-use enable_slot for rescanning of the pci bus */
4266 +- pci_rescan();
4267 ++ cancel_work_sync(&pci_rescan_work);
4268 ++ queue_work(dummyphp_wq, &pci_rescan_work);
4269 + return -ENODEV;
4270 + }
4271 +
4272 +@@ -306,6 +327,10 @@ static int disable_slot(struct hotplug_s
4273 + err("Can't remove PCI devices with other PCI devices behind it yet.\n");
4274 + return -ENODEV;
4275 + }
4276 ++ if (test_and_set_bit(0, &dslot->removed)) {
4277 ++ dbg("Slot already scheduled for removal\n");
4278 ++ return -ENODEV;
4279 ++ }
4280 + /* search for subfunctions and disable them first */
4281 + if (!(dslot->dev->devfn & 7)) {
4282 + for (func = 1; func < 8; func++) {
4283 +@@ -328,8 +353,9 @@ static int disable_slot(struct hotplug_s
4284 + /* remove the device from the pci core */
4285 + pci_remove_bus_device(dslot->dev);
4286 +
4287 +- /* blow away this sysfs entry and other parts. */
4288 +- remove_slot(dslot);
4289 ++ /* queue work item to blow away this sysfs entry and other parts. */
4290 ++ INIT_WORK(&dslot->remove_work, remove_slot_worker);
4291 ++ queue_work(dummyphp_wq, &dslot->remove_work);
4292 +
4293 + return 0;
4294 + }
4295 +@@ -340,6 +366,7 @@ static void cleanup_slots (void)
4296 + struct list_head *next;
4297 + struct dummy_slot *dslot;
4298 +
4299 ++ destroy_workqueue(dummyphp_wq);
4300 + list_for_each_safe (tmp, next, &slot_list) {
4301 + dslot = list_entry (tmp, struct dummy_slot, node);
4302 + remove_slot(dslot);
4303 +@@ -351,6 +378,10 @@ static int __init dummyphp_init(void)
4304 + {
4305 + info(DRIVER_DESC "\n");
4306 +
4307 ++ dummyphp_wq = create_singlethread_workqueue(MY_NAME);
4308 ++ if (!dummyphp_wq)
4309 ++ return -ENOMEM;
4310 ++
4311 + return pci_scan_buses();
4312 + }
4313 +
4314 +diff -NurpP linux-2.6.22.18/drivers/scsi/sd.c linux-2.6.22.19/drivers/scsi/sd.c
4315 +--- linux-2.6.22.18/drivers/scsi/sd.c 2008-02-11 08:31:19.000000000 +0100
4316 ++++ linux-2.6.22.19/drivers/scsi/sd.c 2008-02-26 00:59:40.000000000 +0100
4317 +@@ -895,6 +895,7 @@ static void sd_rw_intr(struct scsi_cmnd
4318 + unsigned int xfer_size = SCpnt->request_bufflen;
4319 + unsigned int good_bytes = result ? 0 : xfer_size;
4320 + u64 start_lba = SCpnt->request->sector;
4321 ++ u64 end_lba = SCpnt->request->sector + (xfer_size / 512);
4322 + u64 bad_lba;
4323 + struct scsi_sense_hdr sshdr;
4324 + int sense_valid = 0;
4325 +@@ -933,26 +934,23 @@ static void sd_rw_intr(struct scsi_cmnd
4326 + goto out;
4327 + if (xfer_size <= SCpnt->device->sector_size)
4328 + goto out;
4329 +- switch (SCpnt->device->sector_size) {
4330 +- case 256:
4331 ++ if (SCpnt->device->sector_size < 512) {
4332 ++ /* only legitimate sector_size here is 256 */
4333 + start_lba <<= 1;
4334 +- break;
4335 +- case 512:
4336 +- break;
4337 +- case 1024:
4338 +- start_lba >>= 1;
4339 +- break;
4340 +- case 2048:
4341 +- start_lba >>= 2;
4342 +- break;
4343 +- case 4096:
4344 +- start_lba >>= 3;
4345 +- break;
4346 +- default:
4347 +- /* Print something here with limiting frequency. */
4348 +- goto out;
4349 +- break;
4350 ++ end_lba <<= 1;
4351 ++ } else {
4352 ++ /* be careful ... don't want any overflows */
4353 ++ u64 factor = SCpnt->device->sector_size / 512;
4354 ++ do_div(start_lba, factor);
4355 ++ do_div(end_lba, factor);
4356 + }
4357 ++
4358 ++ if (bad_lba < start_lba || bad_lba >= end_lba)
4359 ++ /* the bad lba was reported incorrectly, we have
4360 ++ * no idea where the error is
4361 ++ */
4362 ++ goto out;
4363 ++
4364 + /* This computation should always be done in terms of
4365 + * the resolution of the device's medium.
4366 + */
4367 +diff -NurpP linux-2.6.22.18/fs/nfs/client.c linux-2.6.22.19/fs/nfs/client.c
4368 +--- linux-2.6.22.18/fs/nfs/client.c 2008-02-11 08:31:19.000000000 +0100
4369 ++++ linux-2.6.22.19/fs/nfs/client.c 2008-02-26 00:59:40.000000000 +0100
4370 +@@ -433,9 +433,6 @@ static int nfs_create_rpc_client(struct
4371 + */
4372 + static void nfs_destroy_server(struct nfs_server *server)
4373 + {
4374 +- if (!IS_ERR(server->client_acl))
4375 +- rpc_shutdown_client(server->client_acl);
4376 +-
4377 + if (!(server->flags & NFS_MOUNT_NONLM))
4378 + lockd_down(); /* release rpc.lockd */
4379 + }
4380 +@@ -614,16 +611,6 @@ static int nfs_init_server(struct nfs_se
4381 + server->namelen = data->namlen;
4382 + /* Create a client RPC handle for the NFSv3 ACL management interface */
4383 + nfs_init_server_aclclient(server);
4384 +- if (clp->cl_nfsversion == 3) {
4385 +- if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
4386 +- server->namelen = NFS3_MAXNAMLEN;
4387 +- if (!(data->flags & NFS_MOUNT_NORDIRPLUS))
4388 +- server->caps |= NFS_CAP_READDIRPLUS;
4389 +- } else {
4390 +- if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
4391 +- server->namelen = NFS2_MAXNAMLEN;
4392 +- }
4393 +-
4394 + dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp);
4395 + return 0;
4396 +
4397 +@@ -781,6 +768,9 @@ void nfs_free_server(struct nfs_server *
4398 +
4399 + if (server->destroy != NULL)
4400 + server->destroy(server);
4401 ++
4402 ++ if (!IS_ERR(server->client_acl))
4403 ++ rpc_shutdown_client(server->client_acl);
4404 + if (!IS_ERR(server->client))
4405 + rpc_shutdown_client(server->client);
4406 +
4407 +@@ -820,6 +810,16 @@ struct nfs_server *nfs_create_server(con
4408 + error = nfs_probe_fsinfo(server, mntfh, &fattr);
4409 + if (error < 0)
4410 + goto error;
4411 ++ if (server->nfs_client->rpc_ops->version == 3) {
4412 ++ if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
4413 ++ server->namelen = NFS3_MAXNAMLEN;
4414 ++ if (!(data->flags & NFS_MOUNT_NORDIRPLUS))
4415 ++ server->caps |= NFS_CAP_READDIRPLUS;
4416 ++ } else {
4417 ++ if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
4418 ++ server->namelen = NFS2_MAXNAMLEN;
4419 ++ }
4420 ++
4421 + if (!(fattr.valid & NFS_ATTR_FATTR)) {
4422 + error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr);
4423 + if (error < 0) {
4424 +@@ -1010,6 +1010,9 @@ struct nfs_server *nfs4_create_server(co
4425 + if (error < 0)
4426 + goto error;
4427 +
4428 ++ if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
4429 ++ server->namelen = NFS4_MAXNAMLEN;
4430 ++
4431 + BUG_ON(!server->nfs_client);
4432 + BUG_ON(!server->nfs_client->rpc_ops);
4433 + BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
4434 +@@ -1082,6 +1085,9 @@ struct nfs_server *nfs4_create_referral_
4435 + if (error < 0)
4436 + goto error;
4437 +
4438 ++ if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
4439 ++ server->namelen = NFS4_MAXNAMLEN;
4440 ++
4441 + dprintk("Referral FSID: %llx:%llx\n",
4442 + (unsigned long long) server->fsid.major,
4443 + (unsigned long long) server->fsid.minor);
4444 +@@ -1141,6 +1147,9 @@ struct nfs_server *nfs_clone_server(stru
4445 + if (error < 0)
4446 + goto out_free_server;
4447 +
4448 ++ if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
4449 ++ server->namelen = NFS4_MAXNAMLEN;
4450 ++
4451 + dprintk("Cloned FSID: %llx:%llx\n",
4452 + (unsigned long long) server->fsid.major,
4453 + (unsigned long long) server->fsid.minor);
4454 +diff -NurpP linux-2.6.22.18/fs/nfs/dir.c linux-2.6.22.19/fs/nfs/dir.c
4455 +--- linux-2.6.22.18/fs/nfs/dir.c 2008-02-11 08:31:19.000000000 +0100
4456 ++++ linux-2.6.22.19/fs/nfs/dir.c 2008-02-26 00:59:40.000000000 +0100
4457 +@@ -897,14 +897,13 @@ int nfs_is_exclusive_create(struct inode
4458 + return (nd->intent.open.flags & O_EXCL) != 0;
4459 + }
4460 +
4461 +-static inline int nfs_reval_fsid(struct vfsmount *mnt, struct inode *dir,
4462 +- struct nfs_fh *fh, struct nfs_fattr *fattr)
4463 ++static inline int nfs_reval_fsid(struct inode *dir, const struct nfs_fattr *fattr)
4464 + {
4465 + struct nfs_server *server = NFS_SERVER(dir);
4466 +
4467 + if (!nfs_fsid_equal(&server->fsid, &fattr->fsid))
4468 +- /* Revalidate fsid on root dir */
4469 +- return __nfs_revalidate_inode(server, mnt->mnt_root->d_inode);
4470 ++ /* Revalidate fsid using the parent directory */
4471 ++ return __nfs_revalidate_inode(server, dir);
4472 + return 0;
4473 + }
4474 +
4475 +@@ -946,7 +945,7 @@ static struct dentry *nfs_lookup(struct
4476 + res = ERR_PTR(error);
4477 + goto out_unlock;
4478 + }
4479 +- error = nfs_reval_fsid(nd->mnt, dir, &fhandle, &fattr);
4480 ++ error = nfs_reval_fsid(dir, &fattr);
4481 + if (error < 0) {
4482 + res = ERR_PTR(error);
4483 + goto out_unlock;
4484 +@@ -1163,6 +1162,8 @@ static struct dentry *nfs_readdir_lookup
4485 + }
4486 + if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR))
4487 + return NULL;
4488 ++ if (name.len > NFS_SERVER(dir)->namelen)
4489 ++ return NULL;
4490 + /* Note: caller is already holding the dir->i_mutex! */
4491 + dentry = d_alloc(parent, &name);
4492 + if (dentry == NULL)
4493 +diff -NurpP linux-2.6.22.18/fs/nfs/getroot.c linux-2.6.22.19/fs/nfs/getroot.c
4494 +--- linux-2.6.22.18/fs/nfs/getroot.c 2008-02-11 08:31:19.000000000 +0100
4495 ++++ linux-2.6.22.19/fs/nfs/getroot.c 2008-02-26 00:59:40.000000000 +0100
4496 +@@ -175,6 +175,9 @@ next_component:
4497 + path++;
4498 + name.len = path - (const char *) name.name;
4499 +
4500 ++ if (name.len > NFS4_MAXNAMLEN)
4501 ++ return -ENAMETOOLONG;
4502 ++
4503 + eat_dot_dir:
4504 + while (*path == '/')
4505 + path++;
4506 +diff -NurpP linux-2.6.22.18/fs/nfs/inode.c linux-2.6.22.19/fs/nfs/inode.c
4507 +--- linux-2.6.22.18/fs/nfs/inode.c 2008-02-11 08:31:19.000000000 +0100
4508 ++++ linux-2.6.22.19/fs/nfs/inode.c 2008-02-26 00:59:40.000000000 +0100
4509 +@@ -961,8 +961,8 @@ static int nfs_update_inode(struct inode
4510 + goto out_changed;
4511 +
4512 + server = NFS_SERVER(inode);
4513 +- /* Update the fsid if and only if this is the root directory */
4514 +- if (inode == inode->i_sb->s_root->d_inode
4515 ++ /* Update the fsid? */
4516 ++ if (S_ISDIR(inode->i_mode)
4517 + && !nfs_fsid_equal(&server->fsid, &fattr->fsid))
4518 + server->fsid = fattr->fsid;
4519 +
4520 +diff -NurpP linux-2.6.22.18/fs/nfs/write.c linux-2.6.22.19/fs/nfs/write.c
4521 +--- linux-2.6.22.18/fs/nfs/write.c 2008-02-11 08:31:19.000000000 +0100
4522 ++++ linux-2.6.22.19/fs/nfs/write.c 2008-02-26 00:59:40.000000000 +0100
4523 +@@ -710,6 +710,17 @@ int nfs_flush_incompatible(struct file *
4524 + }
4525 +
4526 + /*
4527 ++ * If the page cache is marked as unsafe or invalid, then we can't rely on
4528 ++ * the PageUptodate() flag. In this case, we will need to turn off
4529 ++ * write optimisations that depend on the page contents being correct.
4530 ++ */
4531 ++static int nfs_write_pageuptodate(struct page *page, struct inode *inode)
4532 ++{
4533 ++ return PageUptodate(page) &&
4534 ++ !(NFS_I(inode)->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA));
4535 ++}
4536 ++
4537 ++/*
4538 + * Update and possibly write a cached page of an NFS file.
4539 + *
4540 + * XXX: Keep an eye on generic_file_read to make sure it doesn't do bad
4541 +@@ -730,10 +741,13 @@ int nfs_updatepage(struct file *file, st
4542 + (long long)(page_offset(page) +offset));
4543 +
4544 + /* If we're not using byte range locks, and we know the page
4545 +- * is entirely in cache, it may be more efficient to avoid
4546 +- * fragmenting write requests.
4547 ++ * is up to date, it may be more efficient to extend the write
4548 ++ * to cover the entire page in order to avoid fragmentation
4549 ++ * inefficiencies.
4550 + */
4551 +- if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) {
4552 ++ if (nfs_write_pageuptodate(page, inode) &&
4553 ++ inode->i_flock == NULL &&
4554 ++ !(file->f_mode & O_SYNC)) {
4555 + count = max(count + offset, nfs_page_length(page));
4556 + offset = 0;
4557 + }
4558 +diff -NurpP linux-2.6.22.18/fs/nfsd/nfs2acl.c linux-2.6.22.19/fs/nfsd/nfs2acl.c
4559 +--- linux-2.6.22.18/fs/nfsd/nfs2acl.c 2008-02-11 08:31:19.000000000 +0100
4560 ++++ linux-2.6.22.19/fs/nfsd/nfs2acl.c 2008-02-26 00:59:40.000000000 +0100
4561 +@@ -41,7 +41,7 @@ static __be32 nfsacld_proc_getacl(struct
4562 +
4563 + fh = fh_copy(&resp->fh, &argp->fh);
4564 + if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP)))
4565 +- RETURN_STATUS(nfserr_inval);
4566 ++ RETURN_STATUS(nfserr);
4567 +
4568 + if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
4569 + RETURN_STATUS(nfserr_inval);
4570 +diff -NurpP linux-2.6.22.18/fs/nfsd/nfs3acl.c linux-2.6.22.19/fs/nfsd/nfs3acl.c
4571 +--- linux-2.6.22.18/fs/nfsd/nfs3acl.c 2008-02-11 08:31:19.000000000 +0100
4572 ++++ linux-2.6.22.19/fs/nfsd/nfs3acl.c 2008-02-26 00:59:40.000000000 +0100
4573 +@@ -37,7 +37,7 @@ static __be32 nfsd3_proc_getacl(struct s
4574 +
4575 + fh = fh_copy(&resp->fh, &argp->fh);
4576 + if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP)))
4577 +- RETURN_STATUS(nfserr_inval);
4578 ++ RETURN_STATUS(nfserr);
4579 +
4580 + if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
4581 + RETURN_STATUS(nfserr_inval);
4582 +diff -NurpP linux-2.6.22.18/fs/nfsd/nfs4xdr.c linux-2.6.22.19/fs/nfsd/nfs4xdr.c
4583 +--- linux-2.6.22.18/fs/nfsd/nfs4xdr.c 2008-02-11 08:31:19.000000000 +0100
4584 ++++ linux-2.6.22.19/fs/nfsd/nfs4xdr.c 2008-02-26 00:59:40.000000000 +0100
4585 +@@ -1453,7 +1453,8 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s
4586 + err = vfs_getattr(exp->ex_mnt, dentry, &stat);
4587 + if (err)
4588 + goto out_nfserr;
4589 +- if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) ||
4590 ++ if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL |
4591 ++ FATTR4_WORD0_MAXNAME)) ||
4592 + (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
4593 + FATTR4_WORD1_SPACE_TOTAL))) {
4594 + err = vfs_statfs(dentry, &statfs);
4595 +@@ -1699,7 +1700,7 @@ out_acl:
4596 + if (bmval0 & FATTR4_WORD0_MAXNAME) {
4597 + if ((buflen -= 4) < 0)
4598 + goto out_resource;
4599 +- WRITE32(~(u32) 0);
4600 ++ WRITE32(statfs.f_namelen);
4601 + }
4602 + if (bmval0 & FATTR4_WORD0_MAXREAD) {
4603 + if ((buflen -= 8) < 0)
4604 +diff -NurpP linux-2.6.22.18/include/linux/quicklist.h linux-2.6.22.19/include/linux/quicklist.h
4605 +--- linux-2.6.22.18/include/linux/quicklist.h 2008-02-11 08:31:19.000000000 +0100
4606 ++++ linux-2.6.22.19/include/linux/quicklist.h 2008-02-26 00:59:40.000000000 +0100
4607 +@@ -56,14 +56,6 @@ static inline void __quicklist_free(int
4608 + struct page *page)
4609 + {
4610 + struct quicklist *q;
4611 +- int nid = page_to_nid(page);
4612 +-
4613 +- if (unlikely(nid != numa_node_id())) {
4614 +- if (dtor)
4615 +- dtor(p);
4616 +- __free_page(page);
4617 +- return;
4618 +- }
4619 +
4620 + q = &get_cpu_var(quicklist)[nr];
4621 + *(void **)p = q->page;
4622 +diff -NurpP linux-2.6.22.18/mm/memory.c linux-2.6.22.19/mm/memory.c
4623 +--- linux-2.6.22.18/mm/memory.c 2008-02-11 08:31:19.000000000 +0100
4624 ++++ linux-2.6.22.19/mm/memory.c 2008-02-26 00:59:40.000000000 +0100
4625 +@@ -983,6 +983,8 @@ int get_user_pages(struct task_struct *t
4626 + int i;
4627 + unsigned int vm_flags;
4628 +
4629 ++ if (len <= 0)
4630 ++ return 0;
4631 + /*
4632 + * Require read or write permissions.
4633 + * If 'force' is set, we only require the "MAY" flags.
4634 +diff -NurpP linux-2.6.22.18/mm/quicklist.c linux-2.6.22.19/mm/quicklist.c
4635 +--- linux-2.6.22.18/mm/quicklist.c 2008-02-11 08:31:19.000000000 +0100
4636 ++++ linux-2.6.22.19/mm/quicklist.c 2008-02-26 00:59:40.000000000 +0100
4637 +@@ -26,9 +26,17 @@ DEFINE_PER_CPU(struct quicklist, quickli
4638 + static unsigned long max_pages(unsigned long min_pages)
4639 + {
4640 + unsigned long node_free_pages, max;
4641 ++ struct zone *zones = NODE_DATA(numa_node_id())->node_zones;
4642 ++
4643 ++ node_free_pages =
4644 ++#ifdef CONFIG_ZONE_DMA
4645 ++ zone_page_state(&zones[ZONE_DMA], NR_FREE_PAGES) +
4646 ++#endif
4647 ++#ifdef CONFIG_ZONE_DMA32
4648 ++ zone_page_state(&zones[ZONE_DMA32], NR_FREE_PAGES) +
4649 ++#endif
4650 ++ zone_page_state(&zones[ZONE_NORMAL], NR_FREE_PAGES);
4651 +
4652 +- node_free_pages = node_page_state(numa_node_id(),
4653 +- NR_FREE_PAGES);
4654 + max = node_free_pages / FRACTION_OF_NODE_MEM;
4655 + return max(max, min_pages);
4656 + }
4657 +diff -NurpP linux-2.6.22.18/net/netfilter/nf_conntrack_proto_tcp.c linux-2.6.22.19/net/netfilter/nf_conntrack_proto_tcp.c
4658 +--- linux-2.6.22.18/net/netfilter/nf_conntrack_proto_tcp.c 2008-02-11 08:31:19.000000000 +0100
4659 ++++ linux-2.6.22.19/net/netfilter/nf_conntrack_proto_tcp.c 2008-02-26 00:59:40.000000000 +0100
4660 +@@ -143,7 +143,7 @@ enum tcp_bit_set {
4661 + * CLOSE_WAIT: ACK seen (after FIN)
4662 + * LAST_ACK: FIN seen (after FIN)
4663 + * TIME_WAIT: last ACK seen
4664 +- * CLOSE: closed connection
4665 ++ * CLOSE: closed connection (RST)
4666 + *
4667 + * LISTEN state is not used.
4668 + *
4669 +@@ -842,8 +842,21 @@ static int tcp_packet(struct nf_conn *co
4670 + case TCP_CONNTRACK_SYN_SENT:
4671 + if (old_state < TCP_CONNTRACK_TIME_WAIT)
4672 + break;
4673 +- if ((conntrack->proto.tcp.seen[!dir].flags &
4674 +- IP_CT_TCP_FLAG_CLOSE_INIT)
4675 ++ /* RFC 1122: "When a connection is closed actively,
4676 ++ * it MUST linger in TIME-WAIT state for a time 2xMSL
4677 ++ * (Maximum Segment Lifetime). However, it MAY accept
4678 ++ * a new SYN from the remote TCP to reopen the connection
4679 ++ * directly from TIME-WAIT state, if..."
4680 ++ * We ignore the conditions because we are in the
4681 ++ * TIME-WAIT state anyway.
4682 ++ *
4683 ++ * Handle aborted connections: we and the server
4684 ++ * think there is an existing connection but the client
4685 ++ * aborts it and starts a new one.
4686 ++ */
4687 ++ if (((conntrack->proto.tcp.seen[dir].flags
4688 ++ | conntrack->proto.tcp.seen[!dir].flags)
4689 ++ & IP_CT_TCP_FLAG_CLOSE_INIT)
4690 + || (conntrack->proto.tcp.last_dir == dir
4691 + && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
4692 + /* Attempt to reopen a closed/aborted connection.
4693 +@@ -858,16 +871,23 @@ static int tcp_packet(struct nf_conn *co
4694 + case TCP_CONNTRACK_IGNORE:
4695 + /* Ignored packets:
4696 + *
4697 ++ * Our connection entry may be out of sync, so ignore
4698 ++ * packets which may signal the real connection between
4699 ++ * the client and the server.
4700 ++ *
4701 + * a) SYN in ORIGINAL
4702 + * b) SYN/ACK in REPLY
4703 + * c) ACK in reply direction after initial SYN in original.
4704 ++ *
4705 ++ * If the ignored packet is invalid, the receiver will send
4706 ++ * a RST we'll catch below.
4707 + */
4708 + if (index == TCP_SYNACK_SET
4709 + && conntrack->proto.tcp.last_index == TCP_SYN_SET
4710 + && conntrack->proto.tcp.last_dir != dir
4711 + && ntohl(th->ack_seq) ==
4712 + conntrack->proto.tcp.last_end) {
4713 +- /* This SYN/ACK acknowledges a SYN that we earlier
4714 ++ /* b) This SYN/ACK acknowledges a SYN that we earlier
4715 + * ignored as invalid. This means that the client and
4716 + * the server are both in sync, while the firewall is
4717 + * not. We kill this session and block the SYN/ACK so
4718 +@@ -892,7 +912,7 @@ static int tcp_packet(struct nf_conn *co
4719 + write_unlock_bh(&tcp_lock);
4720 + if (LOG_INVALID(IPPROTO_TCP))
4721 + nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
4722 +- "nf_ct_tcp: invalid packed ignored ");
4723 ++ "nf_ct_tcp: invalid packet ignored ");
4724 + return NF_ACCEPT;
4725 + case TCP_CONNTRACK_MAX:
4726 + /* Invalid packet */
4727 +@@ -948,8 +968,7 @@ static int tcp_packet(struct nf_conn *co
4728 +
4729 + conntrack->proto.tcp.state = new_state;
4730 + if (old_state != new_state
4731 +- && (new_state == TCP_CONNTRACK_FIN_WAIT
4732 +- || new_state == TCP_CONNTRACK_CLOSE))
4733 ++ && new_state == TCP_CONNTRACK_FIN_WAIT)
4734 + conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
4735 + timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans
4736 + && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
4737
4738 Added: vserver-sources/2.2.0.7/4410_vs2.2.0.7.patch
4739 ===================================================================
4740 --- vserver-sources/2.2.0.7/4410_vs2.2.0.7.patch (rev 0)
4741 +++ vserver-sources/2.2.0.7/4410_vs2.2.0.7.patch 2008-03-17 10:10:12 UTC (rev 557)
4742 @@ -0,0 +1,27957 @@
4743 +diff -NurpP --minimal linux-2.6.22.19/Documentation/vserver/debug.txt linux-2.6.22.19-vs2.2.0.7/Documentation/vserver/debug.txt
4744 +--- linux-2.6.22.19/Documentation/vserver/debug.txt 1970-01-01 01:00:00 +0100
4745 ++++ linux-2.6.22.19-vs2.2.0.7/Documentation/vserver/debug.txt 2007-06-15 02:37:02 +0200
4746 +@@ -0,0 +1,154 @@
4747 ++
4748 ++debug_cvirt:
4749 ++
4750 ++ 2 4 "vx_map_tgid: %p/%llx: %d -> %d"
4751 ++ "vx_rmap_tgid: %p/%llx: %d -> %d"
4752 ++
4753 ++debug_dlim:
4754 ++
4755 ++ 0 1 "ALLOC (%p,#%d)%c inode (%d)"
4756 ++ "FREE (%p,#%d)%c inode"
4757 ++ 1 2 "ALLOC (%p,#%d)%c %lld bytes (%d)"
4758 ++ "FREE (%p,#%d)%c %lld bytes"
4759 ++ 2 4 "ADJUST: %lld,%lld on %ld,%ld [mult=%d]"
4760 ++ 3 8 "ext3_has_free_blocks(%p): %lu<%lu+1, %c, %u!=%u r=%d"
4761 ++ "ext3_has_free_blocks(%p): free=%lu, root=%lu"
4762 ++ "rcu_free_dl_info(%p)"
4763 ++ 4 10 "alloc_dl_info(%p,%d) = %p"
4764 ++ "dealloc_dl_info(%p)"
4765 ++ "get_dl_info(%p[#%d.%d])"
4766 ++ "put_dl_info(%p[#%d.%d])"
4767 ++ 5 20 "alloc_dl_info(%p,%d)*"
4768 ++ 6 40 "__hash_dl_info: %p[#%d]"
4769 ++ "__unhash_dl_info: %p[#%d]"
4770 ++ 7 80 "locate_dl_info(%p,#%d) = %p"
4771 ++
4772 ++debug_misc:
4773 ++
4774 ++ 0 1 "destroy_dqhash: %p [#0x%08x] c=%d"
4775 ++ "new_dqhash: %p [#0x%08x]"
4776 ++ "vroot[%d]_clr_dev: dev=%p[%lu,%d:%d]"
4777 ++ "vroot[%d]_get_real_bdev: dev=%p[%lu,%d:%d]"
4778 ++ "vroot[%d]_set_dev: dev=%p[%lu,%d:%d]"
4779 ++ "vroot_get_real_bdev not set"
4780 ++ 1 2 "cow_break_link(»%s«)"
4781 ++ "temp copy »%s«"
4782 ++ 2 4 "dentry_open(new): %p"
4783 ++ "dentry_open(old): %p"
4784 ++ "lookup_create(new): %p"
4785 ++ "old path »%s«"
4786 ++ "path_lookup(old): %d"
4787 ++ "vfs_create(new): %d"
4788 ++ "vfs_rename: %d"
4789 ++ "vfs_sendfile: %d"
4790 ++ 3 8 "fput(new_file=%p[#%d])"
4791 ++ "fput(old_file=%p[#%d])"
4792 ++ 4 10 "vx_info_kill(%p[#%d],%d,%d) = %d"
4793 ++ "vx_info_kill(%p[#%d],%d,%d)*"
4794 ++ 5 20 "vs_reboot(%p[#%d],%d)"
4795 ++ 6 40 "dropping task %p[#%u,%u] for %p[#%u,%u]"
4796 ++
4797 ++debug_net:
4798 ++
4799 ++ 2 4 "nx_addr_conflict(%p,%p) %d.%d,%d.%d"
4800 ++ 3 8 "inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d"
4801 ++ "inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d"
4802 ++ 4 10 "ip_route_connect(%p) %p,%p;%lx"
4803 ++ 5 20 "__addr_in_socket(%p,%d.%d.%d.%d) %p:%d.%d.%d.%d %p;%lx"
4804 ++ 6 40 "sk,egf: %p [#%d] (from %d)"
4805 ++ "sk,egn: %p [#%d] (from %d)"
4806 ++ "sk,req: %p [#%d] (from %d)"
4807 ++ "sk: %p [#%d] (from %d)"
4808 ++ "tw: %p [#%d] (from %d)"
4809 ++ 7 80 "__sock_recvmsg: %p[%p,%p,%p;%d]:%d/%d"
4810 ++ "__sock_sendmsg: %p[%p,%p,%p;%d]:%d/%d"
4811 ++
4812 ++debug_nid:
4813 ++
4814 ++ 0 1 "__lookup_nx_info(#%u): %p[#%u]"
4815 ++ "alloc_nx_info(%d) = %p"
4816 ++ "create_nx_info(%d) (dynamic rejected)"
4817 ++ "create_nx_info(%d) = %p (already there)"
4818 ++ "create_nx_info(%d) = %p (new)"
4819 ++ "dealloc_nx_info(%p)"
4820 ++ 1 2 "alloc_nx_info(%d)*"
4821 ++ "create_nx_info(%d)*"
4822 ++ 2 4 "get_nx_info(%p[#%d.%d])"
4823 ++ "put_nx_info(%p[#%d.%d])"
4824 ++ 3 8 "claim_nx_info(%p[#%d.%d.%d]) %p"
4825 ++ "clr_nx_info(%p[#%d.%d])"
4826 ++ "init_nx_info(%p[#%d.%d])"
4827 ++ "release_nx_info(%p[#%d.%d.%d]) %p"
4828 ++ "set_nx_info(%p[#%d.%d])"
4829 ++ 4 10 "__hash_nx_info: %p[#%d]"
4830 ++ "__nx_dynamic_id: [#%d]"
4831 ++ "__unhash_nx_info: %p[#%d.%d.%d]"
4832 ++ 5 20 "moved task %p into nxi:%p[#%d]"
4833 ++ "nx_migrate_task(%p,%p[#%d.%d.%d])"
4834 ++ "task_get_nx_info(%p)"
4835 ++ 6 40 "nx_clear_persistent(%p[#%d])"
4836 ++
4837 ++debug_quota:
4838 ++
4839 ++ 0 1 "quota_sync_dqh(%p,%d) discard inode %p"
4840 ++ 1 2 "quota_sync_dqh(%p,%d)"
4841 ++ "sync_dquots(%p,%d)"
4842 ++ "sync_dquots_dqh(%p,%d)"
4843 ++ 3 8 "do_quotactl(%p,%d,cmd=%d,id=%d,%p)"
4844 ++
4845 ++debug_switch:
4846 ++
4847 ++ 0 1 "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]"
4848 ++ 1 2 "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]"
4849 ++ 4 10 "%s: (%s %s) returned %s with %d"
4850 ++
4851 ++debug_tag:
4852 ++
4853 ++ 7 80 "dx_parse_tag(»%s«): %d:#%d"
4854 ++ "dx_propagate_tag(%p[#%lu.%d]): %d,%d"
4855 ++
4856 ++debug_xid:
4857 ++
4858 ++ 0 1 "__lookup_vx_info(#%u): %p[#%u]"
4859 ++ "alloc_vx_info(%d) = %p"
4860 ++ "alloc_vx_info(%d)*"
4861 ++ "create_vx_info(%d) (dynamic rejected)"
4862 ++ "create_vx_info(%d) = %p (already there)"
4863 ++ "create_vx_info(%d) = %p (new)"
4864 ++ "dealloc_vx_info(%p)"
4865 ++ "loc_vx_info(%d) = %p (found)"
4866 ++ "loc_vx_info(%d) = %p (new)"
4867 ++ "loc_vx_info(%d) = %p (not available)"
4868 ++ 1 2 "create_vx_info(%d)*"
4869 ++ "loc_vx_info(%d)*"
4870 ++ 2 4 "get_vx_info(%p[#%d.%d])"
4871 ++ "put_vx_info(%p[#%d.%d])"
4872 ++ 3 8 "claim_vx_info(%p[#%d.%d.%d]) %p"
4873 ++ "clr_vx_info(%p[#%d.%d])"
4874 ++ "init_vx_info(%p[#%d.%d])"
4875 ++ "release_vx_info(%p[#%d.%d.%d]) %p"
4876 ++ "set_vx_info(%p[#%d.%d])"
4877 ++ 4 10 "__hash_vx_info: %p[#%d]"
4878 ++ "__unhash_vx_info: %p[#%d.%d.%d]"
4879 ++ "__vx_dynamic_id: [#%d]"
4880 ++ 5 20 "enter_vx_info(%p[#%d],%p) %p[#%d,%p]"
4881 ++ "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]"
4882 ++ "moved task %p into vxi:%p[#%d]"
4883 ++ "task_get_vx_info(%p)"
4884 ++ "vx_migrate_task(%p,%p[#%d.%d])"
4885 ++ 6 40 "vx_clear_persistent(%p[#%d])"
4886 ++ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])"
4887 ++ "vx_set_init(%p[#%d],%p[#%d,%d,%d])"
4888 ++ "vx_set_persistent(%p[#%d])"
4889 ++ "vx_set_reaper(%p[#%d],%p[#%d,%d])"
4890 ++ 7 80 "vx_child_reaper(%p[#%u,%u]) = %p[#%u,%u]"
4891 ++
4892 ++
4893 ++debug_limit:
4894 ++
4895 ++ n 2^n "vx_acc_cres[%5d,%s,%2d]: %5d%s"
4896 ++ "vx_cres_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
4897 ++
4898 ++ m 2^m "vx_acc_page[%5d,%s,%2d]: %5d%s"
4899 ++ "vx_acc_pages[%5d,%s,%2d]: %5d += %5d"
4900 ++ "vx_pages_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
4901 +diff -NurpP --minimal linux-2.6.22.19/Makefile linux-2.6.22.19-vs2.2.0.7/Makefile
4902 +--- linux-2.6.22.19/Makefile 2008-03-14 20:18:58 +0100
4903 ++++ linux-2.6.22.19-vs2.2.0.7/Makefile 2008-03-14 20:21:57 +0100
4904 +@@ -1,7 +1,7 @@
4905 + VERSION = 2
4906 + PATCHLEVEL = 6
4907 + SUBLEVEL = 22
4908 +-EXTRAVERSION =
4909 ++EXTRAVERSION = -vs2.2.0.7-gentoo
4910 + NAME = Holy Dancing Manatees, Batman!
4911 +
4912 + # *DOCUMENTATION*
4913 +diff -NurpP --minimal linux-2.6.22.19/arch/alpha/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/alpha/Kconfig
4914 +--- linux-2.6.22.19/arch/alpha/Kconfig 2007-07-09 13:17:31 +0200
4915 ++++ linux-2.6.22.19-vs2.2.0.7/arch/alpha/Kconfig 2007-06-15 02:37:02 +0200
4916 +@@ -662,6 +662,8 @@ config DUMMY_CONSOLE
4917 + depends on VGA_HOSE
4918 + default y
4919 +
4920 ++source "kernel/vserver/Kconfig"
4921 ++
4922 + source "security/Kconfig"
4923 +
4924 + source "crypto/Kconfig"
4925 +diff -NurpP --minimal linux-2.6.22.19/arch/alpha/kernel/asm-offsets.c linux-2.6.22.19-vs2.2.0.7/arch/alpha/kernel/asm-offsets.c
4926 +--- linux-2.6.22.19/arch/alpha/kernel/asm-offsets.c 2006-02-15 13:54:10 +0100
4927 ++++ linux-2.6.22.19-vs2.2.0.7/arch/alpha/kernel/asm-offsets.c 2007-06-15 02:37:02 +0200
4928 +@@ -36,6 +36,7 @@ void foo(void)
4929 + DEFINE(PT_PTRACED, PT_PTRACED);
4930 + DEFINE(CLONE_VM, CLONE_VM);
4931 + DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
4932 ++ DEFINE(CLONE_KTHREAD, CLONE_KTHREAD);
4933 + DEFINE(SIGCHLD, SIGCHLD);
4934 + BLANK();
4935 +
4936 +diff -NurpP --minimal linux-2.6.22.19/arch/alpha/kernel/entry.S linux-2.6.22.19-vs2.2.0.7/arch/alpha/kernel/entry.S
4937 +--- linux-2.6.22.19/arch/alpha/kernel/entry.S 2007-07-09 13:17:31 +0200
4938 ++++ linux-2.6.22.19-vs2.2.0.7/arch/alpha/kernel/entry.S 2007-06-15 02:37:02 +0200
4939 +@@ -643,7 +643,7 @@ kernel_thread:
4940 + stq $2, 152($sp) /* HAE */
4941 +
4942 + /* Shuffle FLAGS to the front; add CLONE_VM. */
4943 +- ldi $1, CLONE_VM|CLONE_UNTRACED
4944 ++ ldi $1, CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD;
4945 + or $18, $1, $16
4946 + bsr $26, sys_clone
4947 +
4948 +@@ -872,24 +872,15 @@ sys_getxgid:
4949 + .globl sys_getxpid
4950 + .ent sys_getxpid
4951 + sys_getxpid:
4952 ++ lda $sp, -16($sp)
4953 ++ stq $26, 0($sp)
4954 + .prologue 0
4955 +- ldq $2, TI_TASK($8)
4956 +
4957 +- /* See linux/kernel/timer.c sys_getppid for discussion
4958 +- about this loop. */
4959 +- ldq $3, TASK_GROUP_LEADER($2)
4960 +- ldq $4, TASK_REAL_PARENT($3)
4961 +- ldl $0, TASK_TGID($2)
4962 +-1: ldl $1, TASK_TGID($4)
4963 +-#ifdef CONFIG_SMP
4964 +- mov $4, $5
4965 +- mb
4966 +- ldq $3, TASK_GROUP_LEADER($2)
4967 +- ldq $4, TASK_REAL_PARENT($3)
4968 +- cmpeq $4, $5, $5
4969 +- beq $5, 1b
4970 +-#endif
4971 +- stq $1, 80($sp)
4972 ++ lda $16, 96($sp)
4973 ++ jsr $26, do_getxpid
4974 ++ ldq $26, 0($sp)
4975 ++
4976 ++ lda $sp, 16($sp)
4977 + ret
4978 + .end sys_getxpid
4979 +
4980 +diff -NurpP --minimal linux-2.6.22.19/arch/alpha/kernel/osf_sys.c linux-2.6.22.19-vs2.2.0.7/arch/alpha/kernel/osf_sys.c
4981 +--- linux-2.6.22.19/arch/alpha/kernel/osf_sys.c 2007-07-09 13:17:31 +0200
4982 ++++ linux-2.6.22.19-vs2.2.0.7/arch/alpha/kernel/osf_sys.c 2007-06-15 02:37:02 +0200
4983 +@@ -883,7 +883,7 @@ osf_gettimeofday(struct timeval32 __user
4984 + {
4985 + if (tv) {
4986 + struct timeval ktv;
4987 +- do_gettimeofday(&ktv);
4988 ++ vx_gettimeofday(&ktv);
4989 + if (put_tv32(tv, &ktv))
4990 + return -EFAULT;
4991 + }
4992 +diff -NurpP --minimal linux-2.6.22.19/arch/alpha/kernel/ptrace.c linux-2.6.22.19-vs2.2.0.7/arch/alpha/kernel/ptrace.c
4993 +--- linux-2.6.22.19/arch/alpha/kernel/ptrace.c 2006-04-09 13:49:39 +0200
4994 ++++ linux-2.6.22.19-vs2.2.0.7/arch/alpha/kernel/ptrace.c 2007-06-15 02:37:02 +0200
4995 +@@ -15,6 +15,7 @@
4996 + #include <linux/slab.h>
4997 + #include <linux/security.h>
4998 + #include <linux/signal.h>
4999 ++#include <linux/vs_base.h>
5000 +
5001 + #include <asm/uaccess.h>
5002 + #include <asm/pgtable.h>
5003 +@@ -283,6 +284,11 @@ do_sys_ptrace(long request, long pid, lo
5004 + goto out_notsk;
5005 + }
5006 +
5007 ++ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT)) {
5008 ++ ret = -EPERM;
5009 ++ goto out;
5010 ++ }
5011 ++
5012 + if (request == PTRACE_ATTACH) {
5013 + ret = ptrace_attach(child);
5014 + goto out;
5015 +diff -NurpP --minimal linux-2.6.22.19/arch/alpha/kernel/semaphore.c linux-2.6.22.19-vs2.2.0.7/arch/alpha/kernel/semaphore.c
5016 +--- linux-2.6.22.19/arch/alpha/kernel/semaphore.c 2004-08-14 12:55:32 +0200
5017 ++++ linux-2.6.22.19-vs2.2.0.7/arch/alpha/kernel/semaphore.c 2007-06-15 02:37:02 +0200
5018 +@@ -68,8 +68,8 @@ __down_failed(struct semaphore *sem)
5019 + DECLARE_WAITQUEUE(wait, tsk);
5020 +
5021 + #ifdef CONFIG_DEBUG_SEMAPHORE
5022 +- printk("%s(%d): down failed(%p)\n",
5023 +- tsk->comm, tsk->pid, sem);
5024 ++ printk("%s(%d:#%u): down failed(%p)\n",
5025 ++ tsk->comm, tsk->pid, tsk->xid, sem);
5026 + #endif
5027 +
5028 + tsk->state = TASK_UNINTERRUPTIBLE;
5029 +@@ -97,8 +97,8 @@ __down_failed(struct semaphore *sem)
5030 + wake_up(&sem->wait);
5031 +
5032 + #ifdef CONFIG_DEBUG_SEMAPHORE
5033 +- printk("%s(%d): down acquired(%p)\n",
5034 +- tsk->comm, tsk->pid, sem);
5035 ++ printk("%s(%d:#%u): down acquired(%p)\n",
5036 ++ tsk->comm, tsk->pid, tsk->xid, sem);
5037 + #endif
5038 + }
5039 +
5040 +@@ -110,8 +110,8 @@ __down_failed_interruptible(struct semap
5041 + long ret = 0;
5042 +
5043 + #ifdef CONFIG_DEBUG_SEMAPHORE
5044 +- printk("%s(%d): down failed(%p)\n",
5045 +- tsk->comm, tsk->pid, sem);
5046 ++ printk("%s(%d:#%u): down failed(%p)\n",
5047 ++ tsk->comm, tsk->pid, tsk->xid, sem);
5048 + #endif
5049 +
5050 + tsk->state = TASK_INTERRUPTIBLE;
5051 +diff -NurpP --minimal linux-2.6.22.19/arch/alpha/kernel/systbls.S linux-2.6.22.19-vs2.2.0.7/arch/alpha/kernel/systbls.S
5052 +--- linux-2.6.22.19/arch/alpha/kernel/systbls.S 2007-07-09 13:17:31 +0200
5053 ++++ linux-2.6.22.19-vs2.2.0.7/arch/alpha/kernel/systbls.S 2007-06-15 02:37:02 +0200
5054 +@@ -446,7 +446,7 @@ sys_call_table:
5055 + .quad sys_stat64 /* 425 */
5056 + .quad sys_lstat64
5057 + .quad sys_fstat64
5058 +- .quad sys_ni_syscall /* sys_vserver */
5059 ++ .quad sys_vserver /* sys_vserver */
5060 + .quad sys_ni_syscall /* sys_mbind */
5061 + .quad sys_ni_syscall /* sys_get_mempolicy */
5062 + .quad sys_ni_syscall /* sys_set_mempolicy */
5063 +diff -NurpP --minimal linux-2.6.22.19/arch/alpha/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/alpha/kernel/traps.c
5064 +--- linux-2.6.22.19/arch/alpha/kernel/traps.c 2006-09-20 16:57:57 +0200
5065 ++++ linux-2.6.22.19-vs2.2.0.7/arch/alpha/kernel/traps.c 2007-06-15 02:37:02 +0200
5066 +@@ -182,7 +182,8 @@ die_if_kernel(char * str, struct pt_regs
5067 + #ifdef CONFIG_SMP
5068 + printk("CPU %d ", hard_smp_processor_id());
5069 + #endif
5070 +- printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
5071 ++ printk("%s(%d[#%u]): %s %ld\n", current->comm,
5072 ++ current->pid, current->xid, str, err);
5073 + dik_show_regs(regs, r9_15);
5074 + dik_show_trace((unsigned long *)(regs+1));
5075 + dik_show_code((unsigned int *)regs->pc);
5076 +diff -NurpP --minimal linux-2.6.22.19/arch/alpha/mm/fault.c linux-2.6.22.19-vs2.2.0.7/arch/alpha/mm/fault.c
5077 +--- linux-2.6.22.19/arch/alpha/mm/fault.c 2007-07-09 13:17:32 +0200
5078 ++++ linux-2.6.22.19-vs2.2.0.7/arch/alpha/mm/fault.c 2007-06-15 02:37:02 +0200
5079 +@@ -197,8 +197,8 @@ do_page_fault(unsigned long address, uns
5080 + down_read(&mm->mmap_sem);
5081 + goto survive;
5082 + }
5083 +- printk(KERN_ALERT "VM: killing process %s(%d)\n",
5084 +- current->comm, current->pid);
5085 ++ printk(KERN_ALERT "VM: killing process %s(%d:#%u)\n",
5086 ++ current->comm, current->pid, current->xid);
5087 + if (!user_mode(regs))
5088 + goto no_context;
5089 + do_exit(SIGKILL);
5090 +diff -NurpP --minimal linux-2.6.22.19/arch/arm/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/arm/Kconfig
5091 +--- linux-2.6.22.19/arch/arm/Kconfig 2007-07-09 13:17:32 +0200
5092 ++++ linux-2.6.22.19-vs2.2.0.7/arch/arm/Kconfig 2007-06-15 02:37:02 +0200
5093 +@@ -1042,6 +1042,8 @@ source "arch/arm/oprofile/Kconfig"
5094 +
5095 + source "arch/arm/Kconfig.debug"
5096 +
5097 ++source "kernel/vserver/Kconfig"
5098 ++
5099 + source "security/Kconfig"
5100 +
5101 + source "crypto/Kconfig"
5102 +diff -NurpP --minimal linux-2.6.22.19/arch/arm/kernel/calls.S linux-2.6.22.19-vs2.2.0.7/arch/arm/kernel/calls.S
5103 +--- linux-2.6.22.19/arch/arm/kernel/calls.S 2007-07-09 13:17:32 +0200
5104 ++++ linux-2.6.22.19-vs2.2.0.7/arch/arm/kernel/calls.S 2007-07-07 03:52:53 +0200
5105 +@@ -322,7 +322,7 @@
5106 + /* 310 */ CALL(sys_request_key)
5107 + CALL(sys_keyctl)
5108 + CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
5109 +-/* vserver */ CALL(sys_ni_syscall)
5110 ++ CALL(sys_vserver)
5111 + CALL(sys_ioprio_set)
5112 + /* 315 */ CALL(sys_ioprio_get)
5113 + CALL(sys_inotify_init)
5114 +diff -NurpP --minimal linux-2.6.22.19/arch/arm/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/arm/kernel/process.c
5115 +--- linux-2.6.22.19/arch/arm/kernel/process.c 2007-07-09 13:17:32 +0200
5116 ++++ linux-2.6.22.19-vs2.2.0.7/arch/arm/kernel/process.c 2007-07-07 03:52:53 +0200
5117 +@@ -261,7 +261,8 @@ void __show_regs(struct pt_regs *regs)
5118 + void show_regs(struct pt_regs * regs)
5119 + {
5120 + printk("\n");
5121 +- printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
5122 ++ printk("Pid: %d[#%u], comm: %20s\n",
5123 ++ current->pid, current->xid, current->comm);
5124 + __show_regs(regs);
5125 + __backtrace();
5126 + }
5127 +@@ -423,7 +424,8 @@ pid_t kernel_thread(int (*fn)(void *), v
5128 + regs.ARM_pc = (unsigned long)kernel_thread_helper;
5129 + regs.ARM_cpsr = SVC_MODE;
5130 +
5131 +- return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
5132 ++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
5133 ++ 0, &regs, 0, NULL, NULL);
5134 + }
5135 + EXPORT_SYMBOL(kernel_thread);
5136 +
5137 +diff -NurpP --minimal linux-2.6.22.19/arch/arm/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/arm/kernel/traps.c
5138 +--- linux-2.6.22.19/arch/arm/kernel/traps.c 2007-07-09 13:17:32 +0200
5139 ++++ linux-2.6.22.19-vs2.2.0.7/arch/arm/kernel/traps.c 2007-07-09 13:11:53 +0200
5140 +@@ -222,8 +222,8 @@ static void __die(const char *str, int e
5141 + str, err, ++die_counter);
5142 + print_modules();
5143 + __show_regs(regs);
5144 +- printk("Process %s (pid: %d, stack limit = 0x%p)\n",
5145 +- tsk->comm, tsk->pid, thread + 1);
5146 ++ printk("Process %s (pid: %d:#%u, stack limit = 0x%p)\n",
5147 ++ tsk->comm, tsk->pid, tsk->xid, thread + 1);
5148 +
5149 + if (!user_mode(regs) || in_interrupt()) {
5150 + dump_mem("Stack: ", regs->ARM_sp,
5151 +diff -NurpP --minimal linux-2.6.22.19/arch/arm/mm/fault.c linux-2.6.22.19-vs2.2.0.7/arch/arm/mm/fault.c
5152 +--- linux-2.6.22.19/arch/arm/mm/fault.c 2007-07-09 13:17:39 +0200
5153 ++++ linux-2.6.22.19-vs2.2.0.7/arch/arm/mm/fault.c 2007-06-15 02:37:02 +0200
5154 +@@ -266,7 +266,8 @@ do_page_fault(unsigned long addr, unsign
5155 + * happened to us that made us unable to handle
5156 + * the page fault gracefully.
5157 + */
5158 +- printk("VM: killing process %s\n", tsk->comm);
5159 ++ printk("VM: killing process %s(%d:#%u)\n",
5160 ++ tsk->comm, tsk->pid, tsk->xid);
5161 + do_exit(SIGKILL);
5162 + return 0;
5163 +
5164 +diff -NurpP --minimal linux-2.6.22.19/arch/arm26/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/arm26/Kconfig
5165 +--- linux-2.6.22.19/arch/arm26/Kconfig 2007-07-09 13:17:40 +0200
5166 ++++ linux-2.6.22.19-vs2.2.0.7/arch/arm26/Kconfig 2007-06-15 02:37:02 +0200
5167 +@@ -243,6 +243,8 @@ source "drivers/usb/Kconfig"
5168 +
5169 + source "arch/arm26/Kconfig.debug"
5170 +
5171 ++source "kernel/vserver/Kconfig"
5172 ++
5173 + source "security/Kconfig"
5174 +
5175 + source "crypto/Kconfig"
5176 +diff -NurpP --minimal linux-2.6.22.19/arch/arm26/kernel/calls.S linux-2.6.22.19-vs2.2.0.7/arch/arm26/kernel/calls.S
5177 +--- linux-2.6.22.19/arch/arm26/kernel/calls.S 2005-03-02 12:38:19 +0100
5178 ++++ linux-2.6.22.19-vs2.2.0.7/arch/arm26/kernel/calls.S 2007-06-15 02:37:02 +0200
5179 +@@ -257,6 +257,11 @@ __syscall_start:
5180 + .long sys_lremovexattr
5181 + .long sys_fremovexattr
5182 + .long sys_tkill
5183 ++
5184 ++ .rept 313 - (. - __syscall_start) / 4
5185 ++ .long sys_ni_syscall
5186 ++ .endr
5187 ++ .long sys_vserver /* 313 */
5188 + __syscall_end:
5189 +
5190 + .rept NR_syscalls - (__syscall_end - __syscall_start) / 4
5191 +diff -NurpP --minimal linux-2.6.22.19/arch/arm26/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/arm26/kernel/process.c
5192 +--- linux-2.6.22.19/arch/arm26/kernel/process.c 2006-09-20 16:57:57 +0200
5193 ++++ linux-2.6.22.19-vs2.2.0.7/arch/arm26/kernel/process.c 2007-06-15 02:37:02 +0200
5194 +@@ -365,7 +365,8 @@ pid_t kernel_thread(int (*fn)(void *), v
5195 + regs.ARM_r3 = (unsigned long)do_exit;
5196 + regs.ARM_pc = (unsigned long)kernel_thread_helper | MODE_SVC26;
5197 +
5198 +- return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
5199 ++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
5200 ++ 0, &regs, 0, NULL, NULL);
5201 + }
5202 + EXPORT_SYMBOL(kernel_thread);
5203 +
5204 +diff -NurpP --minimal linux-2.6.22.19/arch/arm26/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/arm26/kernel/traps.c
5205 +--- linux-2.6.22.19/arch/arm26/kernel/traps.c 2006-09-20 16:57:57 +0200
5206 ++++ linux-2.6.22.19-vs2.2.0.7/arch/arm26/kernel/traps.c 2007-06-15 02:37:02 +0200
5207 +@@ -185,8 +185,9 @@ NORET_TYPE void die(const char *str, str
5208 + printk("Internal error: %s: %x\n", str, err);
5209 + printk("CPU: %d\n", smp_processor_id());
5210 + show_regs(regs);
5211 +- printk("Process %s (pid: %d, stack limit = 0x%p)\n",
5212 +- current->comm, current->pid, end_of_stack(tsk));
5213 ++ printk("Process %s (pid: %d[#%u], stack limit = 0x%p)\n",
5214 ++ current->comm, current->pid,
5215 ++ current->xid, end_of_stack(tsk));
5216 +
5217 + if (!user_mode(regs) || in_interrupt()) {
5218 + __dump_stack(tsk, (unsigned long)(regs + 1));
5219 +diff -NurpP --minimal linux-2.6.22.19/arch/cris/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/cris/Kconfig
5220 +--- linux-2.6.22.19/arch/cris/Kconfig 2007-05-02 19:24:19 +0200
5221 ++++ linux-2.6.22.19-vs2.2.0.7/arch/cris/Kconfig 2007-06-15 02:37:02 +0200
5222 +@@ -200,6 +200,8 @@ source "drivers/usb/Kconfig"
5223 +
5224 + source "arch/cris/Kconfig.debug"
5225 +
5226 ++source "kernel/vserver/Kconfig"
5227 ++
5228 + source "security/Kconfig"
5229 +
5230 + source "crypto/Kconfig"
5231 +diff -NurpP --minimal linux-2.6.22.19/arch/cris/arch-v10/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/cris/arch-v10/kernel/process.c
5232 +--- linux-2.6.22.19/arch/cris/arch-v10/kernel/process.c 2006-09-20 16:57:57 +0200
5233 ++++ linux-2.6.22.19-vs2.2.0.7/arch/cris/arch-v10/kernel/process.c 2007-06-15 02:37:02 +0200
5234 +@@ -103,7 +103,8 @@ int kernel_thread(int (*fn)(void *), voi
5235 + regs.dccr = 1 << I_DCCR_BITNR;
5236 +
5237 + /* Ok, create the new process.. */
5238 +- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
5239 ++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
5240 ++ 0, &regs, 0, NULL, NULL);
5241 + }
5242 +
5243 + /* setup the child's kernel stack with a pt_regs and switch_stack on it.
5244 +diff -NurpP --minimal linux-2.6.22.19/arch/cris/arch-v32/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/cris/arch-v32/kernel/process.c
5245 +--- linux-2.6.22.19/arch/cris/arch-v32/kernel/process.c 2006-09-20 16:57:57 +0200
5246 ++++ linux-2.6.22.19-vs2.2.0.7/arch/cris/arch-v32/kernel/process.c 2007-06-15 02:37:02 +0200
5247 +@@ -120,7 +120,8 @@ kernel_thread(int (*fn)(void *), void *
5248 + regs.ccs = 1 << (I_CCS_BITNR + CCS_SHIFT);
5249 +
5250 + /* Create the new process. */
5251 +- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
5252 ++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
5253 ++ 0, &regs, 0, NULL, NULL);
5254 + }
5255 +
5256 + /*
5257 +diff -NurpP --minimal linux-2.6.22.19/arch/frv/kernel/kernel_thread.S linux-2.6.22.19-vs2.2.0.7/arch/frv/kernel/kernel_thread.S
5258 +--- linux-2.6.22.19/arch/frv/kernel/kernel_thread.S 2005-03-02 12:38:20 +0100
5259 ++++ linux-2.6.22.19-vs2.2.0.7/arch/frv/kernel/kernel_thread.S 2007-06-15 02:37:02 +0200
5260 +@@ -13,6 +13,8 @@
5261 + #include <asm/unistd.h>
5262 +
5263 + #define CLONE_VM 0x00000100 /* set if VM shared between processes */
5264 ++#define CLONE_KTHREAD 0x10000000 /* kernel thread */
5265 ++#define CLONE_KT (CLONE_VM | CLONE_KTHREAD) /* kernel thread flags */
5266 + #define KERN_ERR "<3>"
5267 +
5268 + .section .rodata
5269 +@@ -37,7 +39,7 @@ kernel_thread:
5270 +
5271 + # start by forking the current process, but with shared VM
5272 + setlos.p #__NR_clone,gr7 ; syscall number
5273 +- ori gr10,#CLONE_VM,gr8 ; first syscall arg [clone_flags]
5274 ++ ori gr10,#CLONE_KT,gr8 ; first syscall arg [clone_flags]
5275 + sethi.p #0xe4e4,gr9 ; second syscall arg [newsp]
5276 + setlo #0xe4e4,gr9
5277 + setlos.p #0,gr10 ; third syscall arg [parent_tidptr]
5278 +diff -NurpP --minimal linux-2.6.22.19/arch/h8300/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/h8300/Kconfig
5279 +--- linux-2.6.22.19/arch/h8300/Kconfig 2007-07-09 13:17:41 +0200
5280 ++++ linux-2.6.22.19-vs2.2.0.7/arch/h8300/Kconfig 2007-06-15 02:37:02 +0200
5281 +@@ -222,6 +222,8 @@ source "fs/Kconfig"
5282 +
5283 + source "arch/h8300/Kconfig.debug"
5284 +
5285 ++source "kernel/vserver/Kconfig"
5286 ++
5287 + source "security/Kconfig"
5288 +
5289 + source "crypto/Kconfig"
5290 +diff -NurpP --minimal linux-2.6.22.19/arch/h8300/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/h8300/kernel/process.c
5291 +--- linux-2.6.22.19/arch/h8300/kernel/process.c 2006-09-20 16:57:58 +0200
5292 ++++ linux-2.6.22.19-vs2.2.0.7/arch/h8300/kernel/process.c 2007-06-15 02:37:03 +0200
5293 +@@ -134,7 +134,7 @@ int kernel_thread(int (*fn)(void *), voi
5294 +
5295 + fs = get_fs();
5296 + set_fs (KERNEL_DS);
5297 +- clone_arg = flags | CLONE_VM;
5298 ++ clone_arg = flags | CLONE_VM | CLONE_KTHREAD;
5299 + __asm__("mov.l sp,er3\n\t"
5300 + "sub.l er2,er2\n\t"
5301 + "mov.l %2,er1\n\t"
5302 +diff -NurpP --minimal linux-2.6.22.19/arch/i386/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/i386/Kconfig
5303 +--- linux-2.6.22.19/arch/i386/Kconfig 2007-07-09 13:17:41 +0200
5304 ++++ linux-2.6.22.19-vs2.2.0.7/arch/i386/Kconfig 2007-07-09 13:11:53 +0200
5305 +@@ -1230,6 +1230,8 @@ endmenu
5306 +
5307 + source "arch/i386/Kconfig.debug"
5308 +
5309 ++source "kernel/vserver/Kconfig"
5310 ++
5311 + source "security/Kconfig"
5312 +
5313 + source "crypto/Kconfig"
5314 +diff -NurpP --minimal linux-2.6.22.19/arch/i386/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/i386/kernel/process.c
5315 +--- linux-2.6.22.19/arch/i386/kernel/process.c 2007-07-09 13:17:42 +0200
5316 ++++ linux-2.6.22.19-vs2.2.0.7/arch/i386/kernel/process.c 2007-06-15 02:37:03 +0200
5317 +@@ -302,8 +302,10 @@ void show_regs(struct pt_regs * regs)
5318 + unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
5319 +
5320 + printk("\n");
5321 +- printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
5322 +- printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
5323 ++ printk("Pid: %d[#%u], comm: %20s\n",
5324 ++ current->pid, current->xid, current->comm);
5325 ++ printk("EIP: %04x:[<%08lx>] CPU: %d\n",
5326 ++ 0xffff & regs->xcs,regs->eip, smp_processor_id());
5327 + print_symbol("EIP is at %s\n", regs->eip);
5328 +
5329 + if (user_mode_vm(regs))
5330 +@@ -355,7 +357,8 @@ int kernel_thread(int (*fn)(void *), voi
5331 + regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
5332 +
5333 + /* Ok, create the new process.. */
5334 +- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
5335 ++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
5336 ++ 0, &regs, 0, NULL, NULL);
5337 + }
5338 + EXPORT_SYMBOL(kernel_thread);
5339 +
5340 +diff -NurpP --minimal linux-2.6.22.19/arch/i386/kernel/syscall_table.S linux-2.6.22.19-vs2.2.0.7/arch/i386/kernel/syscall_table.S
5341 +--- linux-2.6.22.19/arch/i386/kernel/syscall_table.S 2007-07-09 13:17:42 +0200
5342 ++++ linux-2.6.22.19-vs2.2.0.7/arch/i386/kernel/syscall_table.S 2007-06-15 02:37:03 +0200
5343 +@@ -272,7 +272,7 @@ ENTRY(sys_call_table)
5344 + .long sys_tgkill /* 270 */
5345 + .long sys_utimes
5346 + .long sys_fadvise64_64
5347 +- .long sys_ni_syscall /* sys_vserver */
5348 ++ .long sys_vserver
5349 + .long sys_mbind
5350 + .long sys_get_mempolicy
5351 + .long sys_set_mempolicy
5352 +diff -NurpP --minimal linux-2.6.22.19/arch/i386/kernel/sysenter.c linux-2.6.22.19-vs2.2.0.7/arch/i386/kernel/sysenter.c
5353 +--- linux-2.6.22.19/arch/i386/kernel/sysenter.c 2008-03-14 20:18:58 +0100
5354 ++++ linux-2.6.22.19-vs2.2.0.7/arch/i386/kernel/sysenter.c 2007-09-05 03:05:52 +0200
5355 +@@ -17,6 +17,7 @@
5356 + #include <linux/elf.h>
5357 + #include <linux/mm.h>
5358 + #include <linux/module.h>
5359 ++#include <linux/vs_memory.h>
5360 +
5361 + #include <asm/cpufeature.h>
5362 + #include <asm/msr.h>
5363 +diff -NurpP --minimal linux-2.6.22.19/arch/i386/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/i386/kernel/traps.c
5364 +--- linux-2.6.22.19/arch/i386/kernel/traps.c 2008-03-14 20:18:58 +0100
5365 ++++ linux-2.6.22.19-vs2.2.0.7/arch/i386/kernel/traps.c 2008-03-14 19:19:48 +0100
5366 +@@ -56,6 +56,8 @@
5367 + #include <asm/stacktrace.h>
5368 +
5369 + #include <linux/module.h>
5370 ++#include <linux/vs_context.h>
5371 ++#include <linux/vserver/history.h>
5372 +
5373 + #include "mach_traps.h"
5374 +
5375 +@@ -303,8 +305,8 @@ void show_registers(struct pt_regs *regs
5376 + regs->esi, regs->edi, regs->ebp, esp);
5377 + printk(KERN_EMERG "ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n",
5378 + regs->xds & 0xffff, regs->xes & 0xffff, regs->xfs & 0xffff, gs, ss);
5379 +- printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)",
5380 +- TASK_COMM_LEN, current->comm, current->pid,
5381 ++ printk(KERN_EMERG "Process %.*s (pid: %d[#%u], ti=%p task=%p task.ti=%p)",
5382 ++ TASK_COMM_LEN, current->comm, current->pid, current->xid,
5383 + current_thread_info(), current, task_thread_info(current));
5384 + /*
5385 + * When in-kernel, we also print out the stack and code at the
5386 +@@ -375,6 +377,8 @@ void die(const char * str, struct pt_reg
5387 +
5388 + oops_enter();
5389 +
5390 ++ vxh_throw_oops();
5391 ++
5392 + if (die.lock_owner != raw_smp_processor_id()) {
5393 + console_verbose();
5394 + spin_lock_irqsave(&die.lock, flags);
5395 +@@ -412,9 +416,9 @@ void die(const char * str, struct pt_reg
5396 + if (nl)
5397 + printk("\n");
5398 + if (notify_die(DIE_OOPS, str, regs, err,
5399 +- current->thread.trap_no, SIGSEGV) !=
5400 +- NOTIFY_STOP) {
5401 ++ current->thread.trap_no, SIGSEGV) != NOTIFY_STOP) {
5402 + show_registers(regs);
5403 ++ vxh_dump_history();
5404 + /* Executive summary in case the oops scrolled away */
5405 + esp = (unsigned long) (&regs->esp);
5406 + savesegment(ss, ss);
5407 +diff -NurpP --minimal linux-2.6.22.19/arch/i386/mm/fault.c linux-2.6.22.19-vs2.2.0.7/arch/i386/mm/fault.c
5408 +--- linux-2.6.22.19/arch/i386/mm/fault.c 2008-03-14 20:18:58 +0100
5409 ++++ linux-2.6.22.19-vs2.2.0.7/arch/i386/mm/fault.c 2007-09-05 03:05:52 +0200
5410 +@@ -587,7 +587,8 @@ out_of_memory:
5411 + down_read(&mm->mmap_sem);
5412 + goto survive;
5413 + }
5414 +- printk("VM: killing process %s\n", tsk->comm);
5415 ++ printk("VM: killing process %s(%d:#%u)\n",
5416 ++ tsk->comm, tsk->pid, tsk->xid);
5417 + if (error_code & 4)
5418 + do_exit(SIGKILL);
5419 + goto no_context;
5420 +diff -NurpP --minimal linux-2.6.22.19/arch/ia64/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/ia64/Kconfig
5421 +--- linux-2.6.22.19/arch/ia64/Kconfig 2007-07-09 13:17:43 +0200
5422 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ia64/Kconfig 2007-06-15 02:37:03 +0200
5423 +@@ -592,6 +592,8 @@ endmenu
5424 +
5425 + source "arch/ia64/Kconfig.debug"
5426 +
5427 ++source "kernel/vserver/Kconfig"
5428 ++
5429 + source "security/Kconfig"
5430 +
5431 + source "crypto/Kconfig"
5432 +diff -NurpP --minimal linux-2.6.22.19/arch/ia64/ia32/binfmt_elf32.c linux-2.6.22.19-vs2.2.0.7/arch/ia64/ia32/binfmt_elf32.c
5433 +--- linux-2.6.22.19/arch/ia64/ia32/binfmt_elf32.c 2007-05-02 19:24:20 +0200
5434 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ia64/ia32/binfmt_elf32.c 2007-06-15 02:37:03 +0200
5435 +@@ -233,7 +233,8 @@ ia32_setup_arg_pages (struct linux_binpr
5436 + kmem_cache_free(vm_area_cachep, mpnt);
5437 + return ret;
5438 + }
5439 +- current->mm->stack_vm = current->mm->total_vm = vma_pages(mpnt);
5440 ++ vx_vmpages_sub(current->mm, current->mm->total_vm - vma_pages(mpnt));
5441 ++ current->mm->stack_vm = current->mm->total_vm;
5442 + }
5443 +
5444 + for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
5445 +diff -NurpP --minimal linux-2.6.22.19/arch/ia64/ia32/ia32_entry.S linux-2.6.22.19-vs2.2.0.7/arch/ia64/ia32/ia32_entry.S
5446 +--- linux-2.6.22.19/arch/ia64/ia32/ia32_entry.S 2007-07-09 13:17:43 +0200
5447 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ia64/ia32/ia32_entry.S 2007-06-15 02:37:03 +0200
5448 +@@ -446,7 +446,7 @@ ia32_syscall_table:
5449 + data8 sys_tgkill /* 270 */
5450 + data8 compat_sys_utimes
5451 + data8 sys32_fadvise64_64
5452 +- data8 sys_ni_syscall
5453 ++ data8 sys32_vserver
5454 + data8 sys_ni_syscall
5455 + data8 sys_ni_syscall /* 275 */
5456 + data8 sys_ni_syscall
5457 +diff -NurpP --minimal linux-2.6.22.19/arch/ia64/ia32/sys_ia32.c linux-2.6.22.19-vs2.2.0.7/arch/ia64/ia32/sys_ia32.c
5458 +--- linux-2.6.22.19/arch/ia64/ia32/sys_ia32.c 2007-05-02 19:24:20 +0200
5459 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ia64/ia32/sys_ia32.c 2007-06-15 02:37:03 +0200
5460 +@@ -1182,7 +1182,7 @@ sys32_gettimeofday (struct compat_timeva
5461 + {
5462 + if (tv) {
5463 + struct timeval ktv;
5464 +- do_gettimeofday(&ktv);
5465 ++ vx_gettimeofday(&ktv);
5466 + if (put_tv32(tv, &ktv))
5467 + return -EFAULT;
5468 + }
5469 +diff -NurpP --minimal linux-2.6.22.19/arch/ia64/kernel/asm-offsets.c linux-2.6.22.19-vs2.2.0.7/arch/ia64/kernel/asm-offsets.c
5470 +--- linux-2.6.22.19/arch/ia64/kernel/asm-offsets.c 2007-05-02 19:24:20 +0200
5471 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ia64/kernel/asm-offsets.c 2007-06-15 02:37:03 +0200
5472 +@@ -192,6 +192,7 @@ void foo(void)
5473 + /* for assembly files which can't include sched.h: */
5474 + DEFINE(IA64_CLONE_VFORK, CLONE_VFORK);
5475 + DEFINE(IA64_CLONE_VM, CLONE_VM);
5476 ++ DEFINE(IA64_CLONE_KTHREAD, CLONE_KTHREAD);
5477 +
5478 + BLANK();
5479 + DEFINE(IA64_CPUINFO_NSEC_PER_CYC_OFFSET,
5480 +diff -NurpP --minimal linux-2.6.22.19/arch/ia64/kernel/entry.S linux-2.6.22.19-vs2.2.0.7/arch/ia64/kernel/entry.S
5481 +--- linux-2.6.22.19/arch/ia64/kernel/entry.S 2007-07-09 13:17:43 +0200
5482 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ia64/kernel/entry.S 2007-06-15 02:37:03 +0200
5483 +@@ -1547,7 +1547,7 @@ sys_call_table:
5484 + data8 sys_mq_notify
5485 + data8 sys_mq_getsetattr
5486 + data8 sys_kexec_load
5487 +- data8 sys_ni_syscall // reserved for vserver
5488 ++ data8 sys_vserver
5489 + data8 sys_waitid // 1270
5490 + data8 sys_add_key
5491 + data8 sys_request_key
5492 +diff -NurpP --minimal linux-2.6.22.19/arch/ia64/kernel/perfmon.c linux-2.6.22.19-vs2.2.0.7/arch/ia64/kernel/perfmon.c
5493 +--- linux-2.6.22.19/arch/ia64/kernel/perfmon.c 2007-07-09 13:17:43 +0200
5494 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ia64/kernel/perfmon.c 2007-06-15 02:37:03 +0200
5495 +@@ -40,6 +40,7 @@
5496 + #include <linux/capability.h>
5497 + #include <linux/rcupdate.h>
5498 + #include <linux/completion.h>
5499 ++#include <linux/vs_memory.h>
5500 +
5501 + #include <asm/errno.h>
5502 + #include <asm/intrinsics.h>
5503 +@@ -2395,7 +2396,7 @@ pfm_smpl_buffer_alloc(struct task_struct
5504 + */
5505 + insert_vm_struct(mm, vma);
5506 +
5507 +- mm->total_vm += size >> PAGE_SHIFT;
5508 ++ vx_vmpages_add(mm, size >> PAGE_SHIFT);
5509 + vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
5510 + vma_pages(vma));
5511 + up_write(&task->mm->mmap_sem);
5512 +diff -NurpP --minimal linux-2.6.22.19/arch/ia64/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/ia64/kernel/process.c
5513 +--- linux-2.6.22.19/arch/ia64/kernel/process.c 2007-07-09 13:17:43 +0200
5514 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ia64/kernel/process.c 2007-06-15 02:37:03 +0200
5515 +@@ -105,7 +105,8 @@ show_regs (struct pt_regs *regs)
5516 + unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
5517 +
5518 + print_modules();
5519 +- printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm);
5520 ++ printk("\nPid: %d[#%u], CPU %d, comm: %20s\n",
5521 ++ current->pid, current->xid, smp_processor_id(), current->comm);
5522 + printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s\n",
5523 + regs->cr_ipsr, regs->cr_ifs, ip, print_tainted());
5524 + print_symbol("ip is at %s\n", ip);
5525 +@@ -696,7 +697,8 @@ kernel_thread (int (*fn)(void *), void *
5526 + regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR);
5527 + regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET;
5528 + regs.sw.pr = (1 << PRED_KERNEL_STACK);
5529 +- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs.pt, 0, NULL, NULL);
5530 ++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
5531 ++ 0, &regs.pt, 0, NULL, NULL);
5532 + }
5533 + EXPORT_SYMBOL(kernel_thread);
5534 +
5535 +diff -NurpP --minimal linux-2.6.22.19/arch/ia64/kernel/ptrace.c linux-2.6.22.19-vs2.2.0.7/arch/ia64/kernel/ptrace.c
5536 +--- linux-2.6.22.19/arch/ia64/kernel/ptrace.c 2007-05-02 19:24:20 +0200
5537 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ia64/kernel/ptrace.c 2007-06-15 02:37:03 +0200
5538 +@@ -17,6 +17,7 @@
5539 + #include <linux/security.h>
5540 + #include <linux/audit.h>
5541 + #include <linux/signal.h>
5542 ++#include <linux/vs_base.h>
5543 +
5544 + #include <asm/pgtable.h>
5545 + #include <asm/processor.h>
5546 +@@ -1443,6 +1444,9 @@ sys_ptrace (long request, pid_t pid, uns
5547 + read_unlock(&tasklist_lock);
5548 + if (!child)
5549 + goto out;
5550 ++ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT))
5551 ++ goto out_tsk;
5552 ++
5553 + ret = -EPERM;
5554 + if (pid == 1) /* no messing around with init! */
5555 + goto out_tsk;
5556 +diff -NurpP --minimal linux-2.6.22.19/arch/ia64/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/ia64/kernel/traps.c
5557 +--- linux-2.6.22.19/arch/ia64/kernel/traps.c 2007-07-09 13:17:43 +0200
5558 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ia64/kernel/traps.c 2007-06-15 02:37:03 +0200
5559 +@@ -60,8 +60,9 @@ die (const char *str, struct pt_regs *re
5560 + put_cpu();
5561 +
5562 + if (++die.lock_owner_depth < 3) {
5563 +- printk("%s[%d]: %s %ld [%d]\n",
5564 +- current->comm, current->pid, str, err, ++die_counter);
5565 ++ printk("%s[%d[#%u]]: %s %ld [%d]\n",
5566 ++ current->comm, current->pid, current->xid,
5567 ++ str, err, ++die_counter);
5568 + (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
5569 + show_regs(regs);
5570 + } else
5571 +@@ -313,8 +314,9 @@ handle_fpu_swa (int fp_fault, struct pt_
5572 + if ((last.count & 15) < 5 && (ia64_fetchadd(1, &last.count, acq) & 15) < 5) {
5573 + last.time = current_jiffies + 5 * HZ;
5574 + printk(KERN_WARNING
5575 +- "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
5576 +- current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
5577 ++ "%s(%d[#%u]): floating-point assist fault at ip %016lx, isr %016lx\n",
5578 ++ current->comm, current->pid, current->xid,
5579 ++ regs->cr_iip + ia64_psr(regs)->ri, isr);
5580 + }
5581 + }
5582 + }
5583 +diff -NurpP --minimal linux-2.6.22.19/arch/ia64/mm/fault.c linux-2.6.22.19-vs2.2.0.7/arch/ia64/mm/fault.c
5584 +--- linux-2.6.22.19/arch/ia64/mm/fault.c 2007-07-09 13:17:43 +0200
5585 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ia64/mm/fault.c 2007-06-15 02:39:01 +0200
5586 +@@ -10,6 +10,7 @@
5587 + #include <linux/interrupt.h>
5588 + #include <linux/kprobes.h>
5589 + #include <linux/kdebug.h>
5590 ++#include <linux/vs_memory.h>
5591 +
5592 + #include <asm/pgtable.h>
5593 + #include <asm/processor.h>
5594 +diff -NurpP --minimal linux-2.6.22.19/arch/m32r/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/m32r/kernel/process.c
5595 +--- linux-2.6.22.19/arch/m32r/kernel/process.c 2007-05-02 19:24:21 +0200
5596 ++++ linux-2.6.22.19-vs2.2.0.7/arch/m32r/kernel/process.c 2007-06-15 02:37:03 +0200
5597 +@@ -211,8 +211,8 @@ int kernel_thread(int (*fn)(void *), voi
5598 + regs.psw = M32R_PSW_BIE;
5599 +
5600 + /* Ok, create the new process. */
5601 +- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL,
5602 +- NULL);
5603 ++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
5604 ++ 0, &regs, 0, NULL, NULL);
5605 + }
5606 +
5607 + /*
5608 +diff -NurpP --minimal linux-2.6.22.19/arch/m32r/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/m32r/kernel/traps.c
5609 +--- linux-2.6.22.19/arch/m32r/kernel/traps.c 2006-11-30 21:18:28 +0100
5610 ++++ linux-2.6.22.19-vs2.2.0.7/arch/m32r/kernel/traps.c 2007-06-15 02:37:03 +0200
5611 +@@ -195,8 +195,9 @@ static void show_registers(struct pt_reg
5612 + } else {
5613 + printk("SPI: %08lx\n", sp);
5614 + }
5615 +- printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
5616 +- current->comm, current->pid, 0xffff & i, 4096+(unsigned long)current);
5617 ++ printk("Process %s (pid: %d[#%u], process nr: %d, stackpage=%08lx)",
5618 ++ current->comm, current->pid, current->xid,
5619 ++ 0xffff & i, 4096+(unsigned long)current);
5620 +
5621 + /*
5622 + * When in-kernel, we also print out the stack and code at the
5623 +diff -NurpP --minimal linux-2.6.22.19/arch/m68k/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/m68k/Kconfig
5624 +--- linux-2.6.22.19/arch/m68k/Kconfig 2007-07-09 13:17:47 +0200
5625 ++++ linux-2.6.22.19-vs2.2.0.7/arch/m68k/Kconfig 2007-07-07 03:52:53 +0200
5626 +@@ -678,6 +678,8 @@ source "fs/Kconfig"
5627 +
5628 + source "arch/m68k/Kconfig.debug"
5629 +
5630 ++source "kernel/vserver/Kconfig"
5631 ++
5632 + source "security/Kconfig"
5633 +
5634 + source "crypto/Kconfig"
5635 +diff -NurpP --minimal linux-2.6.22.19/arch/m68k/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/m68k/kernel/process.c
5636 +--- linux-2.6.22.19/arch/m68k/kernel/process.c 2006-11-30 21:18:28 +0100
5637 ++++ linux-2.6.22.19-vs2.2.0.7/arch/m68k/kernel/process.c 2007-06-15 02:37:03 +0200
5638 +@@ -159,7 +159,8 @@ int kernel_thread(int (*fn)(void *), voi
5639 +
5640 + {
5641 + register long retval __asm__ ("d0");
5642 +- register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
5643 ++ register long clone_arg __asm__ ("d1") =
5644 ++ flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD;
5645 +
5646 + retval = __NR_clone;
5647 + __asm__ __volatile__
5648 +diff -NurpP --minimal linux-2.6.22.19/arch/m68k/kernel/ptrace.c linux-2.6.22.19-vs2.2.0.7/arch/m68k/kernel/ptrace.c
5649 +--- linux-2.6.22.19/arch/m68k/kernel/ptrace.c 2007-07-09 13:17:47 +0200
5650 ++++ linux-2.6.22.19-vs2.2.0.7/arch/m68k/kernel/ptrace.c 2007-06-15 02:37:03 +0200
5651 +@@ -18,6 +18,7 @@
5652 + #include <linux/ptrace.h>
5653 + #include <linux/user.h>
5654 + #include <linux/signal.h>
5655 ++#include <linux/vs_base.h>
5656 +
5657 + #include <asm/uaccess.h>
5658 + #include <asm/page.h>
5659 +@@ -278,6 +279,8 @@ long arch_ptrace(struct task_struct *chi
5660 + ret = ptrace_request(child, request, addr, data);
5661 + break;
5662 + }
5663 ++ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT))
5664 ++ goto out_tsk;
5665 +
5666 + return ret;
5667 + out_eio:
5668 +diff -NurpP --minimal linux-2.6.22.19/arch/m68k/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/m68k/kernel/traps.c
5669 +--- linux-2.6.22.19/arch/m68k/kernel/traps.c 2007-05-02 19:24:21 +0200
5670 ++++ linux-2.6.22.19-vs2.2.0.7/arch/m68k/kernel/traps.c 2007-06-15 02:37:03 +0200
5671 +@@ -899,8 +899,8 @@ void show_registers(struct pt_regs *regs
5672 + printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
5673 + regs->d4, regs->d5, regs->a0, regs->a1);
5674 +
5675 +- printk("Process %s (pid: %d, task=%p)\n",
5676 +- current->comm, current->pid, current);
5677 ++ printk("Process %s (pid: %d[#%u], task=%p)\n",
5678 ++ current->comm, current->pid, current->xid, current);
5679 + addr = (unsigned long)&fp->un;
5680 + printk("Frame format=%X ", regs->format);
5681 + switch (regs->format) {
5682 +diff -NurpP --minimal linux-2.6.22.19/arch/m68knommu/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/m68knommu/Kconfig
5683 +--- linux-2.6.22.19/arch/m68knommu/Kconfig 2007-07-09 13:17:47 +0200
5684 ++++ linux-2.6.22.19-vs2.2.0.7/arch/m68knommu/Kconfig 2007-06-15 02:37:03 +0200
5685 +@@ -670,6 +670,8 @@ source "fs/Kconfig"
5686 +
5687 + source "arch/m68knommu/Kconfig.debug"
5688 +
5689 ++source "kernel/vserver/Kconfig"
5690 ++
5691 + source "security/Kconfig"
5692 +
5693 + source "crypto/Kconfig"
5694 +diff -NurpP --minimal linux-2.6.22.19/arch/m68knommu/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/m68knommu/kernel/process.c
5695 +--- linux-2.6.22.19/arch/m68knommu/kernel/process.c 2007-02-06 03:00:08 +0100
5696 ++++ linux-2.6.22.19-vs2.2.0.7/arch/m68knommu/kernel/process.c 2007-06-15 02:37:03 +0200
5697 +@@ -122,7 +122,7 @@ void show_regs(struct pt_regs * regs)
5698 + int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
5699 + {
5700 + int retval;
5701 +- long clone_arg = flags | CLONE_VM;
5702 ++ long clone_arg = flags | CLONE_VM | CLONE_KTHREAD;
5703 + mm_segment_t fs;
5704 +
5705 + fs = get_fs();
5706 +diff -NurpP --minimal linux-2.6.22.19/arch/m68knommu/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/m68knommu/kernel/traps.c
5707 +--- linux-2.6.22.19/arch/m68knommu/kernel/traps.c 2007-05-02 19:24:21 +0200
5708 ++++ linux-2.6.22.19-vs2.2.0.7/arch/m68knommu/kernel/traps.c 2007-06-15 02:37:03 +0200
5709 +@@ -80,8 +80,9 @@ void die_if_kernel(char *str, struct pt_
5710 + printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
5711 + fp->d4, fp->d5, fp->a0, fp->a1);
5712 +
5713 +- printk(KERN_EMERG "Process %s (pid: %d, stackpage=%08lx)\n",
5714 +- current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
5715 ++ printk(KERN_EMERG "Process %s (pid: %d[#%u], stackpage=%08lx)\n",
5716 ++ current->comm, current->pid, current->xid,
5717 ++ PAGE_SIZE+(unsigned long)current);
5718 + show_stack(NULL, (unsigned long *)fp);
5719 + do_exit(SIGSEGV);
5720 + }
5721 +diff -NurpP --minimal linux-2.6.22.19/arch/mips/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/mips/Kconfig
5722 +--- linux-2.6.22.19/arch/mips/Kconfig 2007-07-09 13:17:47 +0200
5723 ++++ linux-2.6.22.19-vs2.2.0.7/arch/mips/Kconfig 2007-07-07 03:52:53 +0200
5724 +@@ -1959,6 +1959,8 @@ source "arch/mips/oprofile/Kconfig"
5725 +
5726 + source "arch/mips/Kconfig.debug"
5727 +
5728 ++source "kernel/vserver/Kconfig"
5729 ++
5730 + source "security/Kconfig"
5731 +
5732 + source "crypto/Kconfig"
5733 +diff -NurpP --minimal linux-2.6.22.19/arch/mips/kernel/linux32.c linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/linux32.c
5734 +--- linux-2.6.22.19/arch/mips/kernel/linux32.c 2007-07-09 13:17:48 +0200
5735 ++++ linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/linux32.c 2007-06-17 05:54:16 +0200
5736 +@@ -229,7 +229,7 @@ sys32_gettimeofday(struct compat_timeval
5737 + {
5738 + if (tv) {
5739 + struct timeval ktv;
5740 +- do_gettimeofday(&ktv);
5741 ++ vx_gettimeofday(&ktv);
5742 + if (put_tv32(tv, &ktv))
5743 + return -EFAULT;
5744 + }
5745 +diff -NurpP --minimal linux-2.6.22.19/arch/mips/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/process.c
5746 +--- linux-2.6.22.19/arch/mips/kernel/process.c 2007-05-02 19:24:23 +0200
5747 ++++ linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/process.c 2007-06-15 02:37:03 +0200
5748 +@@ -236,7 +236,8 @@ long kernel_thread(int (*fn)(void *), vo
5749 + #endif
5750 +
5751 + /* Ok, create the new process.. */
5752 +- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
5753 ++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
5754 ++ 0, &regs, 0, NULL, NULL);
5755 + }
5756 +
5757 + /*
5758 +diff -NurpP --minimal linux-2.6.22.19/arch/mips/kernel/ptrace.c linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/ptrace.c
5759 +--- linux-2.6.22.19/arch/mips/kernel/ptrace.c 2007-07-09 13:17:48 +0200
5760 ++++ linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/ptrace.c 2007-06-15 02:37:03 +0200
5761 +@@ -25,6 +25,7 @@
5762 + #include <linux/user.h>
5763 + #include <linux/security.h>
5764 + #include <linux/signal.h>
5765 ++#include <linux/vs_base.h>
5766 +
5767 + #include <asm/byteorder.h>
5768 + #include <asm/cpu.h>
5769 +@@ -171,6 +172,9 @@ long arch_ptrace(struct task_struct *chi
5770 + {
5771 + int ret;
5772 +
5773 ++ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT))
5774 ++ goto out;
5775 ++
5776 + switch (request) {
5777 + /* when I and D space are separate, these will need to be fixed. */
5778 + case PTRACE_PEEKTEXT: /* read word at location addr. */
5779 +diff -NurpP --minimal linux-2.6.22.19/arch/mips/kernel/scall32-o32.S linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/scall32-o32.S
5780 +--- linux-2.6.22.19/arch/mips/kernel/scall32-o32.S 2007-07-09 13:17:48 +0200
5781 ++++ linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/scall32-o32.S 2007-06-17 05:54:16 +0200
5782 +@@ -619,7 +619,7 @@ einval: li v0, -EINVAL
5783 + sys sys_mq_timedreceive 5
5784 + sys sys_mq_notify 2 /* 4275 */
5785 + sys sys_mq_getsetattr 3
5786 +- sys sys_ni_syscall 0 /* sys_vserver */
5787 ++ sys sys_vserver 3
5788 + sys sys_waitid 5
5789 + sys sys_ni_syscall 0 /* available, was setaltroot */
5790 + sys sys_add_key 5 /* 4280 */
5791 +diff -NurpP --minimal linux-2.6.22.19/arch/mips/kernel/scall64-64.S linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/scall64-64.S
5792 +--- linux-2.6.22.19/arch/mips/kernel/scall64-64.S 2007-07-09 13:17:48 +0200
5793 ++++ linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/scall64-64.S 2007-06-17 05:54:16 +0200
5794 +@@ -434,7 +434,7 @@ sys_call_table:
5795 + PTR sys_mq_timedreceive
5796 + PTR sys_mq_notify
5797 + PTR sys_mq_getsetattr /* 5235 */
5798 +- PTR sys_ni_syscall /* sys_vserver */
5799 ++ PTR sys_vserver
5800 + PTR sys_waitid
5801 + PTR sys_ni_syscall /* available, was setaltroot */
5802 + PTR sys_add_key
5803 +diff -NurpP --minimal linux-2.6.22.19/arch/mips/kernel/scall64-n32.S linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/scall64-n32.S
5804 +--- linux-2.6.22.19/arch/mips/kernel/scall64-n32.S 2007-07-09 13:17:48 +0200
5805 ++++ linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/scall64-n32.S 2007-06-17 05:54:16 +0200
5806 +@@ -360,7 +360,7 @@ EXPORT(sysn32_call_table)
5807 + PTR compat_sys_mq_timedreceive
5808 + PTR compat_sys_mq_notify
5809 + PTR compat_sys_mq_getsetattr
5810 +- PTR sys_ni_syscall /* 6240, sys_vserver */
5811 ++ PTR sys32_vserver /* 6240 */
5812 + PTR compat_sys_waitid
5813 + PTR sys_ni_syscall /* available, was setaltroot */
5814 + PTR sys_add_key
5815 +diff -NurpP --minimal linux-2.6.22.19/arch/mips/kernel/scall64-o32.S linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/scall64-o32.S
5816 +--- linux-2.6.22.19/arch/mips/kernel/scall64-o32.S 2007-07-09 13:17:48 +0200
5817 ++++ linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/scall64-o32.S 2007-06-17 05:54:16 +0200
5818 +@@ -482,7 +482,7 @@ sys_call_table:
5819 + PTR compat_sys_mq_timedreceive
5820 + PTR compat_sys_mq_notify /* 4275 */
5821 + PTR compat_sys_mq_getsetattr
5822 +- PTR sys_ni_syscall /* sys_vserver */
5823 ++ PTR sys32_vserver
5824 + PTR sys32_waitid
5825 + PTR sys_ni_syscall /* available, was setaltroot */
5826 + PTR sys_add_key /* 4280 */
5827 +diff -NurpP --minimal linux-2.6.22.19/arch/mips/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/traps.c
5828 +--- linux-2.6.22.19/arch/mips/kernel/traps.c 2007-07-09 13:17:48 +0200
5829 ++++ linux-2.6.22.19-vs2.2.0.7/arch/mips/kernel/traps.c 2007-07-09 13:11:53 +0200
5830 +@@ -302,8 +302,9 @@ void show_registers(struct pt_regs *regs
5831 + {
5832 + show_regs(regs);
5833 + print_modules();
5834 +- printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n",
5835 +- current->comm, current->pid, current_thread_info(), current);
5836 ++ printk("Process %s (pid: %d:#%u, threadinfo=%p, task=%p)\n",
5837 ++ current->comm, current->pid, current->xid,
5838 ++ current_thread_info(), current);
5839 + show_stacktrace(current, regs);
5840 + show_code((unsigned int *) regs->cp0_epc);
5841 + printk("\n");
5842 +diff -NurpP --minimal linux-2.6.22.19/arch/mips/mm/fault.c linux-2.6.22.19-vs2.2.0.7/arch/mips/mm/fault.c
5843 +--- linux-2.6.22.19/arch/mips/mm/fault.c 2007-07-09 13:17:48 +0200
5844 ++++ linux-2.6.22.19-vs2.2.0.7/arch/mips/mm/fault.c 2007-06-15 02:37:03 +0200
5845 +@@ -179,7 +179,8 @@ out_of_memory:
5846 + down_read(&mm->mmap_sem);
5847 + goto survive;
5848 + }
5849 +- printk("VM: killing process %s\n", tsk->comm);
5850 ++ printk("VM: killing process %s(%d:#%u)\n",
5851 ++ tsk->comm, tsk->pid, tsk->xid);
5852 + if (user_mode(regs))
5853 + do_exit(SIGKILL);
5854 + goto no_context;
5855 +diff -NurpP --minimal linux-2.6.22.19/arch/parisc/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/parisc/Kconfig
5856 +--- linux-2.6.22.19/arch/parisc/Kconfig 2007-05-02 19:24:26 +0200
5857 ++++ linux-2.6.22.19-vs2.2.0.7/arch/parisc/Kconfig 2007-06-15 02:37:03 +0200
5858 +@@ -271,6 +271,8 @@ source "arch/parisc/oprofile/Kconfig"
5859 +
5860 + source "arch/parisc/Kconfig.debug"
5861 +
5862 ++source "kernel/vserver/Kconfig"
5863 ++
5864 + source "security/Kconfig"
5865 +
5866 + source "crypto/Kconfig"
5867 +diff -NurpP --minimal linux-2.6.22.19/arch/parisc/kernel/entry.S linux-2.6.22.19-vs2.2.0.7/arch/parisc/kernel/entry.S
5868 +--- linux-2.6.22.19/arch/parisc/kernel/entry.S 2007-07-09 13:17:50 +0200
5869 ++++ linux-2.6.22.19-vs2.2.0.7/arch/parisc/kernel/entry.S 2007-06-17 05:54:16 +0200
5870 +@@ -761,6 +761,7 @@ END(fault_vector_11)
5871 +
5872 + #define CLONE_VM 0x100 /* Must agree with <linux/sched.h> */
5873 + #define CLONE_UNTRACED 0x00800000
5874 ++#define CLONE_KTHREAD 0x10000000
5875 +
5876 + .import do_fork
5877 + ENTRY(__kernel_thread)
5878 +diff -NurpP --minimal linux-2.6.22.19/arch/parisc/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/parisc/kernel/process.c
5879 +--- linux-2.6.22.19/arch/parisc/kernel/process.c 2007-07-09 13:17:50 +0200
5880 ++++ linux-2.6.22.19-vs2.2.0.7/arch/parisc/kernel/process.c 2007-06-17 05:54:16 +0200
5881 +@@ -173,7 +173,7 @@ pid_t kernel_thread(int (*fn)(void *), v
5882 + * kernel_thread can become a #define.
5883 + */
5884 +
5885 +- return __kernel_thread(fn, arg, flags);
5886 ++ return __kernel_thread(fn, arg, flags | CLONE_KTHREAD);
5887 + }
5888 + EXPORT_SYMBOL(kernel_thread);
5889 +
5890 +diff -NurpP --minimal linux-2.6.22.19/arch/parisc/kernel/sys_parisc32.c linux-2.6.22.19-vs2.2.0.7/arch/parisc/kernel/sys_parisc32.c
5891 +--- linux-2.6.22.19/arch/parisc/kernel/sys_parisc32.c 2007-07-09 13:17:50 +0200
5892 ++++ linux-2.6.22.19-vs2.2.0.7/arch/parisc/kernel/sys_parisc32.c 2007-06-17 05:54:16 +0200
5893 +@@ -204,11 +204,11 @@ static inline long get_ts32(struct times
5894 + asmlinkage int
5895 + sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
5896 + {
5897 +- extern void do_gettimeofday(struct timeval *tv);
5898 ++ extern void vx_gettimeofday(struct timeval *tv);
5899 +
5900 + if (tv) {
5901 + struct timeval ktv;
5902 +- do_gettimeofday(&ktv);
5903 ++ vx_gettimeofday(&ktv);
5904 + if (put_compat_timeval(tv, &ktv))
5905 + return -EFAULT;
5906 + }
5907 +diff -NurpP --minimal linux-2.6.22.19/arch/parisc/kernel/syscall_table.S linux-2.6.22.19-vs2.2.0.7/arch/parisc/kernel/syscall_table.S
5908 +--- linux-2.6.22.19/arch/parisc/kernel/syscall_table.S 2007-07-09 13:17:50 +0200
5909 ++++ linux-2.6.22.19-vs2.2.0.7/arch/parisc/kernel/syscall_table.S 2007-06-17 05:54:16 +0200
5910 +@@ -363,7 +363,7 @@
5911 + ENTRY_COMP(mbind) /* 260 */
5912 + ENTRY_COMP(get_mempolicy)
5913 + ENTRY_COMP(set_mempolicy)
5914 +- ENTRY_SAME(ni_syscall) /* 263: reserved for vserver */
5915 ++ ENTRY_DIFF(vserver)
5916 + ENTRY_SAME(add_key)
5917 + ENTRY_SAME(request_key) /* 265 */
5918 + ENTRY_SAME(keyctl)
5919 +diff -NurpP --minimal linux-2.6.22.19/arch/parisc/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/parisc/kernel/traps.c
5920 +--- linux-2.6.22.19/arch/parisc/kernel/traps.c 2007-07-09 13:17:50 +0200
5921 ++++ linux-2.6.22.19-vs2.2.0.7/arch/parisc/kernel/traps.c 2007-06-17 05:54:16 +0200
5922 +@@ -218,8 +218,9 @@ void die_if_kernel(char *str, struct pt_
5923 + if (err == 0)
5924 + return; /* STFU */
5925 +
5926 +- printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
5927 +- current->comm, current->pid, str, err, regs->iaoq[0]);
5928 ++ printk(KERN_CRIT "%s (pid %d:#%u): %s (code %ld) at " RFMT "\n",
5929 ++ current->comm, current->pid, current->xid,
5930 ++ str, err, regs->iaoq[0]);
5931 + #ifdef PRINT_USER_FAULTS
5932 + /* XXX for debugging only */
5933 + show_regs(regs);
5934 +@@ -251,8 +252,8 @@ KERN_CRIT " || |
5935 + pdc_console_restart();
5936 +
5937 + if (err)
5938 +- printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
5939 +- current->comm, current->pid, str, err);
5940 ++ printk(KERN_CRIT "%s (pid %d:#%u): %s (code %ld)\n",
5941 ++ current->comm, current->pid, current->xid, str, err);
5942 +
5943 + /* Wot's wrong wif bein' racy? */
5944 + if (current->thread.flags & PARISC_KERNEL_DEATH) {
5945 +diff -NurpP --minimal linux-2.6.22.19/arch/parisc/mm/fault.c linux-2.6.22.19-vs2.2.0.7/arch/parisc/mm/fault.c
5946 +--- linux-2.6.22.19/arch/parisc/mm/fault.c 2007-05-02 19:24:26 +0200
5947 ++++ linux-2.6.22.19-vs2.2.0.7/arch/parisc/mm/fault.c 2007-06-15 02:37:03 +0200
5948 +@@ -209,8 +209,9 @@ bad_area:
5949 +
5950 + #ifdef PRINT_USER_FAULTS
5951 + printk(KERN_DEBUG "\n");
5952 +- printk(KERN_DEBUG "do_page_fault() pid=%d command='%s' type=%lu address=0x%08lx\n",
5953 +- tsk->pid, tsk->comm, code, address);
5954 ++ printk(KERN_DEBUG "do_page_fault() pid=%d:#%u "
5955 ++ "command='%s' type=%lu address=0x%08lx\n",
5956 ++ tsk->pid, tsk->xid, tsk->comm, code, address);
5957 + if (vma) {
5958 + printk(KERN_DEBUG "vm_start = 0x%08lx, vm_end = 0x%08lx\n",
5959 + vma->vm_start, vma->vm_end);
5960 +@@ -260,7 +261,8 @@ no_context:
5961 +
5962 + out_of_memory:
5963 + up_read(&mm->mmap_sem);
5964 +- printk(KERN_CRIT "VM: killing process %s\n", current->comm);
5965 ++ printk(KERN_CRIT "VM: killing process %s(%d:#%u)\n",
5966 ++ current->comm, current->pid, current->xid);
5967 + if (user_mode(regs))
5968 + do_exit(SIGKILL);
5969 + goto no_context;
5970 +diff -NurpP --minimal linux-2.6.22.19/arch/powerpc/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/powerpc/Kconfig
5971 +--- linux-2.6.22.19/arch/powerpc/Kconfig 2007-07-09 13:17:50 +0200
5972 ++++ linux-2.6.22.19-vs2.2.0.7/arch/powerpc/Kconfig 2007-06-15 02:37:03 +0200
5973 +@@ -906,6 +906,8 @@ endmenu
5974 +
5975 + source "arch/powerpc/Kconfig.debug"
5976 +
5977 ++source "kernel/vserver/Kconfig"
5978 ++
5979 + source "security/Kconfig"
5980 +
5981 + config KEYS_COMPAT
5982 +diff -NurpP --minimal linux-2.6.22.19/arch/powerpc/kernel/asm-offsets.c linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/asm-offsets.c
5983 +--- linux-2.6.22.19/arch/powerpc/kernel/asm-offsets.c 2007-07-09 13:17:51 +0200
5984 ++++ linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/asm-offsets.c 2007-06-15 02:37:03 +0200
5985 +@@ -250,6 +250,7 @@ int main(void)
5986 +
5987 + DEFINE(CLONE_VM, CLONE_VM);
5988 + DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
5989 ++ DEFINE(CLONE_KTHREAD, CLONE_KTHREAD);
5990 +
5991 + #ifndef CONFIG_PPC64
5992 + DEFINE(MM_PGD, offsetof(struct mm_struct, pgd));
5993 +diff -NurpP --minimal linux-2.6.22.19/arch/powerpc/kernel/irq.c linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/irq.c
5994 +--- linux-2.6.22.19/arch/powerpc/kernel/irq.c 2007-07-09 13:17:51 +0200
5995 ++++ linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/irq.c 2007-07-09 13:11:53 +0200
5996 +@@ -53,6 +53,7 @@
5997 + #include <linux/mutex.h>
5998 + #include <linux/bootmem.h>
5999 + #include <linux/pci.h>
6000 ++#include <linux/vs_context.h>
6001 +
6002 + #include <asm/uaccess.h>
6003 + #include <asm/system.h>
6004 +diff -NurpP --minimal linux-2.6.22.19/arch/powerpc/kernel/misc_32.S linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/misc_32.S
6005 +--- linux-2.6.22.19/arch/powerpc/kernel/misc_32.S 2007-07-09 13:17:51 +0200
6006 ++++ linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/misc_32.S 2007-06-15 02:37:03 +0200
6007 +@@ -745,7 +745,7 @@ _GLOBAL(kernel_thread)
6008 + mr r30,r3 /* function */
6009 + mr r31,r4 /* argument */
6010 + ori r3,r5,CLONE_VM /* flags */
6011 +- oris r3,r3,CLONE_UNTRACED>>16
6012 ++ oris r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16
6013 + li r4,0 /* new sp (unused) */
6014 + li r0,__NR_clone
6015 + sc
6016 +diff -NurpP --minimal linux-2.6.22.19/arch/powerpc/kernel/misc_64.S linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/misc_64.S
6017 +--- linux-2.6.22.19/arch/powerpc/kernel/misc_64.S 2007-05-02 19:24:27 +0200
6018 ++++ linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/misc_64.S 2007-06-15 02:37:03 +0200
6019 +@@ -434,7 +434,7 @@ _GLOBAL(kernel_thread)
6020 + mr r29,r3
6021 + mr r30,r4
6022 + ori r3,r5,CLONE_VM /* flags */
6023 +- oris r3,r3,(CLONE_UNTRACED>>16)
6024 ++ oris r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16
6025 + li r4,0 /* new sp (unused) */
6026 + li r0,__NR_clone
6027 + sc
6028 +diff -NurpP --minimal linux-2.6.22.19/arch/powerpc/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/process.c
6029 +--- linux-2.6.22.19/arch/powerpc/kernel/process.c 2008-03-14 20:18:58 +0100
6030 ++++ linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/process.c 2007-10-01 15:25:34 +0200
6031 +@@ -422,8 +422,9 @@ void show_regs(struct pt_regs * regs)
6032 + trap = TRAP(regs);
6033 + if (trap == 0x300 || trap == 0x600)
6034 + printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
6035 +- printk("TASK = %p[%d] '%s' THREAD: %p",
6036 +- current, current->pid, current->comm, task_thread_info(current));
6037 ++ printk("TASK = %p[%d,#%u] '%s' THREAD: %p",
6038 ++ current, current->pid, current->xid,
6039 ++ current->comm, task_thread_info(current));
6040 +
6041 + #ifdef CONFIG_SMP
6042 + printk(" CPU: %d", smp_processor_id());
6043 +diff -NurpP --minimal linux-2.6.22.19/arch/powerpc/kernel/sys_ppc32.c linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/sys_ppc32.c
6044 +--- linux-2.6.22.19/arch/powerpc/kernel/sys_ppc32.c 2007-07-09 13:17:51 +0200
6045 ++++ linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/sys_ppc32.c 2007-07-07 03:52:53 +0200
6046 +@@ -205,7 +205,7 @@ asmlinkage long compat_sys_gettimeofday(
6047 + {
6048 + if (tv) {
6049 + struct timeval ktv;
6050 +- do_gettimeofday(&ktv);
6051 ++ vx_gettimeofday(&ktv);
6052 + if (put_tv32(tv, &ktv))
6053 + return -EFAULT;
6054 + }
6055 +diff -NurpP --minimal linux-2.6.22.19/arch/powerpc/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/traps.c
6056 +--- linux-2.6.22.19/arch/powerpc/kernel/traps.c 2007-07-09 13:17:51 +0200
6057 ++++ linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/traps.c 2007-06-15 02:37:03 +0200
6058 +@@ -878,8 +878,9 @@ void nonrecoverable_exception(struct pt_
6059 +
6060 + void trace_syscall(struct pt_regs *regs)
6061 + {
6062 +- printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
6063 +- current, current->pid, regs->nip, regs->link, regs->gpr[0],
6064 ++ printk("Task: %p(%d[#%u]), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
6065 ++ current, current->pid, current->xid,
6066 ++ regs->nip, regs->link, regs->gpr[0],
6067 + regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
6068 + }
6069 +
6070 +diff -NurpP --minimal linux-2.6.22.19/arch/powerpc/kernel/vdso.c linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/vdso.c
6071 +--- linux-2.6.22.19/arch/powerpc/kernel/vdso.c 2007-07-09 13:17:51 +0200
6072 ++++ linux-2.6.22.19-vs2.2.0.7/arch/powerpc/kernel/vdso.c 2007-06-15 02:37:03 +0200
6073 +@@ -21,6 +21,7 @@
6074 + #include <linux/elf.h>
6075 + #include <linux/security.h>
6076 + #include <linux/bootmem.h>
6077 ++#include <linux/vs_memory.h>
6078 +
6079 + #include <asm/pgtable.h>
6080 + #include <asm/system.h>
6081 +diff -NurpP --minimal linux-2.6.22.19/arch/powerpc/mm/fault.c linux-2.6.22.19-vs2.2.0.7/arch/powerpc/mm/fault.c
6082 +--- linux-2.6.22.19/arch/powerpc/mm/fault.c 2007-07-09 13:17:51 +0200
6083 ++++ linux-2.6.22.19-vs2.2.0.7/arch/powerpc/mm/fault.c 2007-07-07 03:52:53 +0200
6084 +@@ -378,7 +378,8 @@ out_of_memory:
6085 + down_read(&mm->mmap_sem);
6086 + goto survive;
6087 + }
6088 +- printk("VM: killing process %s\n", current->comm);
6089 ++ printk("VM: killing process %s(%d:#%u)\n",
6090 ++ current->comm, current->pid, current->xid);
6091 + if (user_mode(regs))
6092 + do_exit(SIGKILL);
6093 + return SIGKILL;
6094 +diff -NurpP --minimal linux-2.6.22.19/arch/ppc/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/ppc/Kconfig
6095 +--- linux-2.6.22.19/arch/ppc/Kconfig 2007-05-02 19:24:28 +0200
6096 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ppc/Kconfig 2007-06-15 02:37:03 +0200
6097 +@@ -1455,6 +1455,8 @@ source "arch/powerpc/oprofile/Kconfig"
6098 +
6099 + source "arch/ppc/Kconfig.debug"
6100 +
6101 ++source "kernel/vserver/Kconfig"
6102 ++
6103 + source "security/Kconfig"
6104 +
6105 + source "crypto/Kconfig"
6106 +diff -NurpP --minimal linux-2.6.22.19/arch/ppc/kernel/asm-offsets.c linux-2.6.22.19-vs2.2.0.7/arch/ppc/kernel/asm-offsets.c
6107 +--- linux-2.6.22.19/arch/ppc/kernel/asm-offsets.c 2007-07-09 13:18:01 +0200
6108 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ppc/kernel/asm-offsets.c 2007-06-15 02:37:03 +0200
6109 +@@ -120,6 +120,7 @@ main(void)
6110 + DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
6111 + DEFINE(CLONE_VM, CLONE_VM);
6112 + DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
6113 ++ DEFINE(CLONE_KTHREAD, CLONE_KTHREAD);
6114 + DEFINE(MM_PGD, offsetof(struct mm_struct, pgd));
6115 +
6116 + /* About the CPU features table */
6117 +diff -NurpP --minimal linux-2.6.22.19/arch/ppc/kernel/misc.S linux-2.6.22.19-vs2.2.0.7/arch/ppc/kernel/misc.S
6118 +--- linux-2.6.22.19/arch/ppc/kernel/misc.S 2006-11-30 21:18:32 +0100
6119 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ppc/kernel/misc.S 2007-06-15 02:37:03 +0200
6120 +@@ -848,7 +848,7 @@ _GLOBAL(kernel_thread)
6121 + mr r30,r3 /* function */
6122 + mr r31,r4 /* argument */
6123 + ori r3,r5,CLONE_VM /* flags */
6124 +- oris r3,r3,CLONE_UNTRACED>>16
6125 ++ oris r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16
6126 + li r4,0 /* new sp (unused) */
6127 + li r0,__NR_clone
6128 + sc
6129 +diff -NurpP --minimal linux-2.6.22.19/arch/ppc/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/ppc/kernel/traps.c
6130 +--- linux-2.6.22.19/arch/ppc/kernel/traps.c 2007-07-09 13:18:01 +0200
6131 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ppc/kernel/traps.c 2007-06-15 02:37:03 +0200
6132 +@@ -696,8 +696,9 @@ void nonrecoverable_exception(struct pt_
6133 +
6134 + void trace_syscall(struct pt_regs *regs)
6135 + {
6136 +- printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
6137 +- current, current->pid, regs->nip, regs->link, regs->gpr[0],
6138 ++ printk("Task: %p(%d[#%u]), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
6139 ++ current, current->pid, current->xid,
6140 ++ regs->nip, regs->link, regs->gpr[0],
6141 + regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
6142 + }
6143 +
6144 +diff -NurpP --minimal linux-2.6.22.19/arch/ppc/mm/fault.c linux-2.6.22.19-vs2.2.0.7/arch/ppc/mm/fault.c
6145 +--- linux-2.6.22.19/arch/ppc/mm/fault.c 2006-11-30 21:18:32 +0100
6146 ++++ linux-2.6.22.19-vs2.2.0.7/arch/ppc/mm/fault.c 2007-06-15 02:37:03 +0200
6147 +@@ -296,7 +296,8 @@ out_of_memory:
6148 + down_read(&mm->mmap_sem);
6149 + goto survive;
6150 + }
6151 +- printk("VM: killing process %s\n", current->comm);
6152 ++ printk("VM: killing process %s(%d:#%u)\n",
6153 ++ current->comm, current->pid, current->xid);
6154 + if (user_mode(regs))
6155 + do_exit(SIGKILL);
6156 + return SIGKILL;
6157 +diff -NurpP --minimal linux-2.6.22.19/arch/s390/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/s390/Kconfig
6158 +--- linux-2.6.22.19/arch/s390/Kconfig 2007-07-09 13:18:02 +0200
6159 ++++ linux-2.6.22.19-vs2.2.0.7/arch/s390/Kconfig 2007-06-15 02:37:03 +0200
6160 +@@ -551,6 +551,8 @@ endmenu
6161 +
6162 + source "arch/s390/Kconfig.debug"
6163 +
6164 ++source "kernel/vserver/Kconfig"
6165 ++
6166 + source "security/Kconfig"
6167 +
6168 + source "crypto/Kconfig"
6169 +diff -NurpP --minimal linux-2.6.22.19/arch/s390/kernel/compat_linux.c linux-2.6.22.19-vs2.2.0.7/arch/s390/kernel/compat_linux.c
6170 +--- linux-2.6.22.19/arch/s390/kernel/compat_linux.c 2007-07-09 13:18:02 +0200
6171 ++++ linux-2.6.22.19-vs2.2.0.7/arch/s390/kernel/compat_linux.c 2007-06-15 02:37:03 +0200
6172 +@@ -567,7 +567,7 @@ asmlinkage long sys32_gettimeofday(struc
6173 + {
6174 + if (tv) {
6175 + struct timeval ktv;
6176 +- do_gettimeofday(&ktv);
6177 ++ vx_gettimeofday(&ktv);
6178 + if (put_tv32(tv, &ktv))
6179 + return -EFAULT;
6180 + }
6181 +diff -NurpP --minimal linux-2.6.22.19/arch/s390/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/s390/kernel/process.c
6182 +--- linux-2.6.22.19/arch/s390/kernel/process.c 2007-07-09 13:18:02 +0200
6183 ++++ linux-2.6.22.19-vs2.2.0.7/arch/s390/kernel/process.c 2007-06-15 02:37:03 +0200
6184 +@@ -164,9 +164,9 @@ void show_regs(struct pt_regs *regs)
6185 + struct task_struct *tsk = current;
6186 +
6187 + printk("CPU: %d %s\n", task_thread_info(tsk)->cpu, print_tainted());
6188 +- printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
6189 +- current->comm, current->pid, (void *) tsk,
6190 +- (void *) tsk->thread.ksp);
6191 ++ printk("Process %s (pid: %d[#%u], task: %p, ksp: %p)\n",
6192 ++ current->comm, current->pid, current->xid,
6193 ++ (void *) tsk, (void *) tsk->thread.ksp);
6194 +
6195 + show_registers(regs);
6196 + /* Show stack backtrace if pt_regs is from kernel mode */
6197 +@@ -197,7 +197,7 @@ int kernel_thread(int (*fn)(void *), voi
6198 + regs.orig_gpr2 = -1;
6199 +
6200 + /* Ok, create the new process.. */
6201 +- return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
6202 ++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
6203 + 0, &regs, 0, NULL, NULL);
6204 + }
6205 +
6206 +diff -NurpP --minimal linux-2.6.22.19/arch/s390/kernel/ptrace.c linux-2.6.22.19-vs2.2.0.7/arch/s390/kernel/ptrace.c
6207 +--- linux-2.6.22.19/arch/s390/kernel/ptrace.c 2007-05-02 19:24:29 +0200
6208 ++++ linux-2.6.22.19-vs2.2.0.7/arch/s390/kernel/ptrace.c 2007-06-15 02:37:03 +0200
6209 +@@ -33,6 +33,7 @@
6210 + #include <linux/security.h>
6211 + #include <linux/audit.h>
6212 + #include <linux/signal.h>
6213 ++#include <linux/vs_base.h>
6214 +
6215 + #include <asm/segment.h>
6216 + #include <asm/page.h>
6217 +@@ -725,7 +726,13 @@ sys_ptrace(long request, long pid, long
6218 + goto out;
6219 + }
6220 +
6221 ++ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT)) {
6222 ++ ret = -EPERM;
6223 ++ goto out_tsk;
6224 ++ }
6225 ++
6226 + ret = do_ptrace(child, request, addr, data);
6227 ++out_tsk:
6228 + put_task_struct(child);
6229 + out:
6230 + unlock_kernel();
6231 +diff -NurpP --minimal linux-2.6.22.19/arch/s390/kernel/syscalls.S linux-2.6.22.19-vs2.2.0.7/arch/s390/kernel/syscalls.S
6232 +--- linux-2.6.22.19/arch/s390/kernel/syscalls.S 2007-07-09 13:18:02 +0200
6233 ++++ linux-2.6.22.19-vs2.2.0.7/arch/s390/kernel/syscalls.S 2007-06-15 02:37:03 +0200
6234 +@@ -271,7 +271,7 @@ SYSCALL(sys_clock_settime,sys_clock_sett
6235 + SYSCALL(sys_clock_gettime,sys_clock_gettime,sys32_clock_gettime_wrapper) /* 260 */
6236 + SYSCALL(sys_clock_getres,sys_clock_getres,sys32_clock_getres_wrapper)
6237 + SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,sys32_clock_nanosleep_wrapper)
6238 +-NI_SYSCALL /* reserved for vserver */
6239 ++SYSCALL(sys_vserver,sys_vserver,sys32_vserver)
6240 + SYSCALL(s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper)
6241 + SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper)
6242 + SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper)
6243 +diff -NurpP --minimal linux-2.6.22.19/arch/s390/mm/fault.c linux-2.6.22.19-vs2.2.0.7/arch/s390/mm/fault.c
6244 +--- linux-2.6.22.19/arch/s390/mm/fault.c 2007-07-09 13:18:02 +0200
6245 ++++ linux-2.6.22.19-vs2.2.0.7/arch/s390/mm/fault.c 2007-06-15 02:37:03 +0200
6246 +@@ -216,7 +216,8 @@ static int do_out_of_memory(struct pt_re
6247 + down_read(&mm->mmap_sem);
6248 + return 1;
6249 + }
6250 +- printk("VM: killing process %s\n", tsk->comm);
6251 ++ printk("VM: killing process %s(%d:#%u)\n",
6252 ++ tsk->comm, tsk->pid, tsk->xid);
6253 + if (regs->psw.mask & PSW_MASK_PSTATE)
6254 + do_exit(SIGKILL);
6255 + do_no_context(regs, error_code, address);
6256 +diff -NurpP --minimal linux-2.6.22.19/arch/sh/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/sh/Kconfig
6257 +--- linux-2.6.22.19/arch/sh/Kconfig 2007-07-09 13:18:02 +0200
6258 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sh/Kconfig 2007-06-15 02:37:03 +0200
6259 +@@ -723,6 +723,8 @@ source "arch/sh/oprofile/Kconfig"
6260 +
6261 + source "arch/sh/Kconfig.debug"
6262 +
6263 ++source "kernel/vserver/Kconfig"
6264 ++
6265 + source "security/Kconfig"
6266 +
6267 + source "crypto/Kconfig"
6268 +diff -NurpP --minimal linux-2.6.22.19/arch/sh/kernel/irq.c linux-2.6.22.19-vs2.2.0.7/arch/sh/kernel/irq.c
6269 +--- linux-2.6.22.19/arch/sh/kernel/irq.c 2007-07-09 13:18:03 +0200
6270 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sh/kernel/irq.c 2007-06-15 02:37:03 +0200
6271 +@@ -12,6 +12,7 @@
6272 + #include <linux/kernel_stat.h>
6273 + #include <linux/seq_file.h>
6274 + #include <linux/irq.h>
6275 ++#include <linux/vs_context.h>
6276 + #include <asm/processor.h>
6277 + #include <asm/machvec.h>
6278 + #include <asm/uaccess.h>
6279 +diff -NurpP --minimal linux-2.6.22.19/arch/sh/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/sh/kernel/process.c
6280 +--- linux-2.6.22.19/arch/sh/kernel/process.c 2007-07-09 13:18:03 +0200
6281 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sh/kernel/process.c 2007-06-15 02:37:03 +0200
6282 +@@ -118,7 +118,8 @@ void machine_power_off(void)
6283 + void show_regs(struct pt_regs * regs)
6284 + {
6285 + printk("\n");
6286 +- printk("Pid : %d, Comm: %20s\n", current->pid, current->comm);
6287 ++ printk("Pid : %d:#%u, Comm: %20s\n",
6288 ++ current->pid, current->xid, current->comm);
6289 + print_symbol("PC is at %s\n", instruction_pointer(regs));
6290 + printk("PC : %08lx SP : %08lx SR : %08lx ",
6291 + regs->pc, regs->regs[15], regs->sr);
6292 +@@ -179,7 +180,7 @@ int kernel_thread(int (*fn)(void *), voi
6293 + regs.sr = (1 << 30);
6294 +
6295 + /* Ok, create the new process.. */
6296 +- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
6297 ++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, 0,
6298 + &regs, 0, NULL, NULL);
6299 + }
6300 +
6301 +diff -NurpP --minimal linux-2.6.22.19/arch/sh/kernel/vsyscall/vsyscall.c linux-2.6.22.19-vs2.2.0.7/arch/sh/kernel/vsyscall/vsyscall.c
6302 +--- linux-2.6.22.19/arch/sh/kernel/vsyscall/vsyscall.c 2007-07-09 13:18:03 +0200
6303 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sh/kernel/vsyscall/vsyscall.c 2007-06-15 02:39:24 +0200
6304 +@@ -18,6 +18,7 @@
6305 + #include <linux/module.h>
6306 + #include <linux/elf.h>
6307 + #include <linux/sched.h>
6308 ++#include <linux/vs_memory.h>
6309 +
6310 + /*
6311 + * Should the kernel map a VDSO page into processes and pass its
6312 +diff -NurpP --minimal linux-2.6.22.19/arch/sh/mm/fault.c linux-2.6.22.19-vs2.2.0.7/arch/sh/mm/fault.c
6313 +--- linux-2.6.22.19/arch/sh/mm/fault.c 2007-07-09 13:18:03 +0200
6314 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sh/mm/fault.c 2007-06-15 02:37:03 +0200
6315 +@@ -201,7 +201,8 @@ out_of_memory:
6316 + down_read(&mm->mmap_sem);
6317 + goto survive;
6318 + }
6319 +- printk("VM: killing process %s\n", tsk->comm);
6320 ++ printk("VM: killing process %s(%d:#%u)\n",
6321 ++ tsk->comm, tsk->pid, tsk->xid);
6322 + if (user_mode(regs))
6323 + do_exit(SIGKILL);
6324 + goto no_context;
6325 +diff -NurpP --minimal linux-2.6.22.19/arch/sh64/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/sh64/kernel/process.c
6326 +--- linux-2.6.22.19/arch/sh64/kernel/process.c 2007-07-09 13:18:03 +0200
6327 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sh64/kernel/process.c 2007-06-15 02:37:03 +0200
6328 +@@ -400,8 +400,8 @@ int kernel_thread(int (*fn)(void *), voi
6329 + regs.pc = (unsigned long)kernel_thread_helper;
6330 + regs.sr = (1 << 30);
6331 +
6332 +- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
6333 +- &regs, 0, NULL, NULL);
6334 ++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
6335 ++ 0, &regs, 0, NULL, NULL);
6336 + }
6337 +
6338 + /*
6339 +diff -NurpP --minimal linux-2.6.22.19/arch/sh64/mm/fault.c linux-2.6.22.19-vs2.2.0.7/arch/sh64/mm/fault.c
6340 +--- linux-2.6.22.19/arch/sh64/mm/fault.c 2007-07-09 13:18:04 +0200
6341 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sh64/mm/fault.c 2007-06-15 02:37:03 +0200
6342 +@@ -81,7 +81,7 @@ static inline void print_vma(struct vm_a
6343 +
6344 + static inline void print_task(struct task_struct *tsk)
6345 + {
6346 +- printk("Task pid %d\n", tsk->pid);
6347 ++ printk("Task pid %d:#%u\n", tsk->pid, tsk->xid);
6348 + }
6349 +
6350 + static pte_t *lookup_pte(struct mm_struct *mm, unsigned long address)
6351 +@@ -330,7 +330,8 @@ out_of_memory:
6352 + down_read(&mm->mmap_sem);
6353 + goto survive;
6354 + }
6355 +- printk("VM: killing process %s\n", tsk->comm);
6356 ++ printk("VM: killing process %s(%d:#%u)\n",
6357 ++ tsk->comm, tsk->pid, tsk->xid);
6358 + if (user_mode(regs))
6359 + do_exit(SIGKILL);
6360 + goto no_context;
6361 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/sparc/Kconfig
6362 +--- linux-2.6.22.19/arch/sparc/Kconfig 2007-07-09 13:18:04 +0200
6363 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc/Kconfig 2007-06-15 02:37:03 +0200
6364 +@@ -317,6 +317,8 @@ endmenu
6365 +
6366 + source "arch/sparc/Kconfig.debug"
6367 +
6368 ++source "kernel/vserver/Kconfig"
6369 ++
6370 + source "security/Kconfig"
6371 +
6372 + source "crypto/Kconfig"
6373 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/sparc/kernel/process.c
6374 +--- linux-2.6.22.19/arch/sparc/kernel/process.c 2007-07-09 13:18:04 +0200
6375 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc/kernel/process.c 2007-06-15 02:37:03 +0200
6376 +@@ -705,7 +705,8 @@ pid_t kernel_thread(int (*fn)(void *), v
6377 + /* Notreached by child. */
6378 + "1: mov %%o0, %0\n\t" :
6379 + "=r" (retval) :
6380 +- "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED),
6381 ++ "i" (__NR_clone), "r" (flags |
6382 ++ CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD),
6383 + "i" (__NR_exit), "r" (fn), "r" (arg) :
6384 + "g1", "g2", "g3", "o0", "o1", "memory", "cc");
6385 + return retval;
6386 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc/kernel/ptrace.c linux-2.6.22.19-vs2.2.0.7/arch/sparc/kernel/ptrace.c
6387 +--- linux-2.6.22.19/arch/sparc/kernel/ptrace.c 2007-02-06 03:00:18 +0100
6388 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc/kernel/ptrace.c 2007-06-15 02:37:03 +0200
6389 +@@ -19,6 +19,7 @@
6390 + #include <linux/smp_lock.h>
6391 + #include <linux/security.h>
6392 + #include <linux/signal.h>
6393 ++#include <linux/vs_base.h>
6394 +
6395 + #include <asm/pgtable.h>
6396 + #include <asm/system.h>
6397 +@@ -302,6 +303,10 @@ asmlinkage void do_ptrace(struct pt_regs
6398 + pt_error_return(regs, -ret);
6399 + goto out;
6400 + }
6401 ++ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT)) {
6402 ++ pt_error_return(regs, ESRCH);
6403 ++ goto out_tsk;
6404 ++ }
6405 +
6406 + if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
6407 + || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
6408 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc/kernel/systbls.S linux-2.6.22.19-vs2.2.0.7/arch/sparc/kernel/systbls.S
6409 +--- linux-2.6.22.19/arch/sparc/kernel/systbls.S 2007-07-09 13:18:04 +0200
6410 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc/kernel/systbls.S 2007-06-15 02:37:03 +0200
6411 +@@ -71,7 +71,7 @@ sys_call_table:
6412 + /*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
6413 + /*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
6414 + /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
6415 +-/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
6416 ++/*265*/ .long sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
6417 + /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
6418 + /*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
6419 + /*280*/ .long sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
6420 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/sparc/kernel/traps.c
6421 +--- linux-2.6.22.19/arch/sparc/kernel/traps.c 2007-07-09 13:18:05 +0200
6422 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc/kernel/traps.c 2007-06-15 02:37:03 +0200
6423 +@@ -99,7 +99,8 @@ void die_if_kernel(char *str, struct pt_
6424 + " /_| \\__/ |_\\\n"
6425 + " \\__U_/\n");
6426 +
6427 +- printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
6428 ++ printk("%s(%d[#%u]): %s [#%d]\n", current->comm,
6429 ++ current->pid, current->xid, str, ++die_counter);
6430 + show_regs(regs);
6431 +
6432 + __SAVE; __SAVE; __SAVE; __SAVE;
6433 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc/mm/fault.c linux-2.6.22.19-vs2.2.0.7/arch/sparc/mm/fault.c
6434 +--- linux-2.6.22.19/arch/sparc/mm/fault.c 2007-07-09 13:18:05 +0200
6435 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc/mm/fault.c 2007-06-15 02:37:03 +0200
6436 +@@ -367,7 +367,8 @@ no_context:
6437 + */
6438 + out_of_memory:
6439 + up_read(&mm->mmap_sem);
6440 +- printk("VM: killing process %s\n", tsk->comm);
6441 ++ printk("VM: killing process %s(%d:#%u)\n",
6442 ++ tsk->comm, tsk->pid, tsk->xid);
6443 + if (from_user)
6444 + do_exit(SIGKILL);
6445 + goto no_context;
6446 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc64/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/sparc64/Kconfig
6447 +--- linux-2.6.22.19/arch/sparc64/Kconfig 2007-07-09 13:18:06 +0200
6448 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc64/Kconfig 2007-06-17 05:54:16 +0200
6449 +@@ -451,6 +451,8 @@ endmenu
6450 +
6451 + source "arch/sparc64/Kconfig.debug"
6452 +
6453 ++source "kernel/vserver/Kconfig"
6454 ++
6455 + source "security/Kconfig"
6456 +
6457 + source "crypto/Kconfig"
6458 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc64/kernel/binfmt_aout32.c linux-2.6.22.19-vs2.2.0.7/arch/sparc64/kernel/binfmt_aout32.c
6459 +--- linux-2.6.22.19/arch/sparc64/kernel/binfmt_aout32.c 2007-02-06 03:00:18 +0100
6460 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc64/kernel/binfmt_aout32.c 2007-06-15 02:37:03 +0200
6461 +@@ -27,6 +27,7 @@
6462 + #include <linux/binfmts.h>
6463 + #include <linux/personality.h>
6464 + #include <linux/init.h>
6465 ++#include <linux/vs_memory.h>
6466 +
6467 + #include <asm/system.h>
6468 + #include <asm/uaccess.h>
6469 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc64/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/sparc64/kernel/process.c
6470 +--- linux-2.6.22.19/arch/sparc64/kernel/process.c 2007-07-09 13:18:06 +0200
6471 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc64/kernel/process.c 2007-06-15 02:37:03 +0200
6472 +@@ -707,7 +707,8 @@ pid_t kernel_thread(int (*fn)(void *), v
6473 + /* Notreached by child. */
6474 + "1:" :
6475 + "=r" (retval) :
6476 +- "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED),
6477 ++ "i" (__NR_clone), "r" (flags |
6478 ++ CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD),
6479 + "i" (__NR_exit), "r" (fn), "r" (arg) :
6480 + "g1", "g2", "g3", "o0", "o1", "memory", "cc");
6481 + return retval;
6482 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc64/kernel/ptrace.c linux-2.6.22.19-vs2.2.0.7/arch/sparc64/kernel/ptrace.c
6483 +--- linux-2.6.22.19/arch/sparc64/kernel/ptrace.c 2007-02-06 03:00:18 +0100
6484 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc64/kernel/ptrace.c 2007-06-15 02:37:03 +0200
6485 +@@ -22,6 +22,7 @@
6486 + #include <linux/seccomp.h>
6487 + #include <linux/audit.h>
6488 + #include <linux/signal.h>
6489 ++#include <linux/vs_base.h>
6490 +
6491 + #include <asm/asi.h>
6492 + #include <asm/pgtable.h>
6493 +@@ -215,6 +216,10 @@ asmlinkage void do_ptrace(struct pt_regs
6494 + pt_error_return(regs, -ret);
6495 + goto out;
6496 + }
6497 ++ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT)) {
6498 ++ pt_error_return(regs, ESRCH);
6499 ++ goto out_tsk;
6500 ++ }
6501 +
6502 + if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
6503 + || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
6504 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc64/kernel/sys_sparc32.c linux-2.6.22.19-vs2.2.0.7/arch/sparc64/kernel/sys_sparc32.c
6505 +--- linux-2.6.22.19/arch/sparc64/kernel/sys_sparc32.c 2007-07-09 13:18:06 +0200
6506 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc64/kernel/sys_sparc32.c 2007-06-15 02:37:03 +0200
6507 +@@ -729,7 +729,7 @@ asmlinkage long sys32_gettimeofday(struc
6508 + {
6509 + if (tv) {
6510 + struct timeval ktv;
6511 +- do_gettimeofday(&ktv);
6512 ++ vx_gettimeofday(&ktv);
6513 + if (put_tv32(tv, &ktv))
6514 + return -EFAULT;
6515 + }
6516 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc64/kernel/systbls.S linux-2.6.22.19-vs2.2.0.7/arch/sparc64/kernel/systbls.S
6517 +--- linux-2.6.22.19/arch/sparc64/kernel/systbls.S 2007-07-09 13:18:06 +0200
6518 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc64/kernel/systbls.S 2007-06-15 02:37:03 +0200
6519 +@@ -72,7 +72,7 @@ sys_call_table32:
6520 + /*250*/ .word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
6521 + .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
6522 + /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
6523 +- .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
6524 ++ .word sys_timer_delete, compat_sys_timer_create, sys32_vserver, compat_sys_io_setup, sys_io_destroy
6525 + /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
6526 + .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
6527 + /*280*/ .word sys32_tee, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
6528 +@@ -144,7 +144,7 @@ sys_call_table:
6529 + /*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
6530 + .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
6531 + /*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
6532 +- .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
6533 ++ .word sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
6534 + /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
6535 + .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
6536 + /*280*/ .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
6537 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc64/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/sparc64/kernel/traps.c
6538 +--- linux-2.6.22.19/arch/sparc64/kernel/traps.c 2008-03-14 20:18:59 +0100
6539 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc64/kernel/traps.c 2007-09-05 03:05:52 +0200
6540 +@@ -2225,7 +2225,8 @@ void die_if_kernel(char *str, struct pt_
6541 + " /_| \\__/ |_\\\n"
6542 + " \\__U_/\n");
6543 +
6544 +- printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
6545 ++ printk("%s(%d[#%u]): %s [#%d]\n", current->comm,
6546 ++ current->pid, current->xid, str, ++die_counter);
6547 + notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV);
6548 + __asm__ __volatile__("flushw");
6549 + __show_regs(regs);
6550 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc64/mm/fault.c linux-2.6.22.19-vs2.2.0.7/arch/sparc64/mm/fault.c
6551 +--- linux-2.6.22.19/arch/sparc64/mm/fault.c 2008-03-14 20:18:59 +0100
6552 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc64/mm/fault.c 2007-09-05 03:05:52 +0200
6553 +@@ -463,7 +463,8 @@ handle_kernel_fault:
6554 + out_of_memory:
6555 + insn = get_fault_insn(regs, insn);
6556 + up_read(&mm->mmap_sem);
6557 +- printk("VM: killing process %s\n", current->comm);
6558 ++ printk("VM: killing process %s(%d:#%u)\n",
6559 ++ current->comm, current->pid, current->xid);
6560 + if (!(regs->tstate & TSTATE_PRIV))
6561 + do_exit(SIGKILL);
6562 + goto handle_kernel_fault;
6563 +diff -NurpP --minimal linux-2.6.22.19/arch/sparc64/solaris/fs.c linux-2.6.22.19-vs2.2.0.7/arch/sparc64/solaris/fs.c
6564 +--- linux-2.6.22.19/arch/sparc64/solaris/fs.c 2007-02-06 03:00:21 +0100
6565 ++++ linux-2.6.22.19-vs2.2.0.7/arch/sparc64/solaris/fs.c 2007-06-15 02:37:03 +0200
6566 +@@ -368,7 +368,7 @@ static int report_statvfs(struct vfsmoun
6567 + int j = strlen (p);
6568 +
6569 + if (j > 15) j = 15;
6570 +- if (IS_RDONLY(inode)) i = 1;
6571 ++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
6572 + if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
6573 + if (!sysv_valid_dev(inode->i_sb->s_dev))
6574 + return -EOVERFLOW;
6575 +@@ -404,7 +404,7 @@ static int report_statvfs64(struct vfsmo
6576 + int j = strlen (p);
6577 +
6578 + if (j > 15) j = 15;
6579 +- if (IS_RDONLY(inode)) i = 1;
6580 ++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
6581 + if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
6582 + if (!sysv_valid_dev(inode->i_sb->s_dev))
6583 + return -EOVERFLOW;
6584 +diff -NurpP --minimal linux-2.6.22.19/arch/um/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/um/Kconfig
6585 +--- linux-2.6.22.19/arch/um/Kconfig 2007-07-09 13:18:07 +0200
6586 ++++ linux-2.6.22.19-vs2.2.0.7/arch/um/Kconfig 2007-06-17 05:54:16 +0200
6587 +@@ -316,6 +316,8 @@ source "drivers/connector/Kconfig"
6588 +
6589 + source "fs/Kconfig"
6590 +
6591 ++source "kernel/vserver/Kconfig"
6592 ++
6593 + source "security/Kconfig"
6594 +
6595 + source "crypto/Kconfig"
6596 +diff -NurpP --minimal linux-2.6.22.19/arch/um/kernel/trap.c linux-2.6.22.19-vs2.2.0.7/arch/um/kernel/trap.c
6597 +--- linux-2.6.22.19/arch/um/kernel/trap.c 2007-07-09 13:18:07 +0200
6598 ++++ linux-2.6.22.19-vs2.2.0.7/arch/um/kernel/trap.c 2007-06-15 02:37:03 +0200
6599 +@@ -210,7 +210,8 @@ unsigned long segv(struct faultinfo fi,
6600 + current->thread.arch.faultinfo = fi;
6601 + force_sig_info(SIGBUS, &si, current);
6602 + } else if (err == -ENOMEM) {
6603 +- printk("VM: killing process %s\n", current->comm);
6604 ++ printk("VM: killing process %s(%d:#%u)\n",
6605 ++ current->comm, current->pid, current->xid);
6606 + do_exit(SIGKILL);
6607 + } else {
6608 + BUG_ON(err != -EFAULT);
6609 +diff -NurpP --minimal linux-2.6.22.19/arch/v850/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/v850/Kconfig
6610 +--- linux-2.6.22.19/arch/v850/Kconfig 2007-07-09 13:18:08 +0200
6611 ++++ linux-2.6.22.19-vs2.2.0.7/arch/v850/Kconfig 2007-06-15 02:37:03 +0200
6612 +@@ -333,6 +333,8 @@ source "drivers/usb/Kconfig"
6613 +
6614 + source "arch/v850/Kconfig.debug"
6615 +
6616 ++source "kernel/vserver/Kconfig"
6617 ++
6618 + source "security/Kconfig"
6619 +
6620 + source "crypto/Kconfig"
6621 +diff -NurpP --minimal linux-2.6.22.19/arch/v850/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/v850/kernel/process.c
6622 +--- linux-2.6.22.19/arch/v850/kernel/process.c 2007-07-09 13:18:08 +0200
6623 ++++ linux-2.6.22.19-vs2.2.0.7/arch/v850/kernel/process.c 2007-06-15 02:37:03 +0200
6624 +@@ -82,7 +82,7 @@ int kernel_thread (int (*fn)(void *), vo
6625 + /* Clone this thread. Note that we don't pass the clone syscall's
6626 + second argument -- it's ignored for calls from kernel mode (the
6627 + child's SP is always set to the top of the kernel stack). */
6628 +- arg0 = flags | CLONE_VM;
6629 ++ arg0 = flags | CLONE_VM | CLONE_KTHREAD;
6630 + syscall = __NR_clone;
6631 + asm volatile ("trap " SYSCALL_SHORT_TRAP
6632 + : "=r" (ret), "=r" (syscall)
6633 +diff -NurpP --minimal linux-2.6.22.19/arch/v850/kernel/ptrace.c linux-2.6.22.19-vs2.2.0.7/arch/v850/kernel/ptrace.c
6634 +--- linux-2.6.22.19/arch/v850/kernel/ptrace.c 2007-07-09 13:18:08 +0200
6635 ++++ linux-2.6.22.19-vs2.2.0.7/arch/v850/kernel/ptrace.c 2007-06-15 02:37:03 +0200
6636 +@@ -23,6 +23,7 @@
6637 + #include <linux/sched.h>
6638 + #include <linux/ptrace.h>
6639 + #include <linux/signal.h>
6640 ++#include <linux/vs_base.h>
6641 +
6642 + #include <asm/errno.h>
6643 + #include <asm/ptrace.h>
6644 +@@ -116,6 +117,9 @@ long arch_ptrace(struct task_struct *chi
6645 + {
6646 + int rval;
6647 +
6648 ++ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT))
6649 ++ goto out;
6650 ++
6651 + switch (request) {
6652 + unsigned long val, copied;
6653 +
6654 +diff -NurpP --minimal linux-2.6.22.19/arch/x86_64/Kconfig linux-2.6.22.19-vs2.2.0.7/arch/x86_64/Kconfig
6655 +--- linux-2.6.22.19/arch/x86_64/Kconfig 2007-07-09 13:18:08 +0200
6656 ++++ linux-2.6.22.19-vs2.2.0.7/arch/x86_64/Kconfig 2007-06-15 02:37:03 +0200
6657 +@@ -782,6 +782,8 @@ endmenu
6658 +
6659 + source "arch/x86_64/Kconfig.debug"
6660 +
6661 ++source "kernel/vserver/Kconfig"
6662 ++
6663 + source "security/Kconfig"
6664 +
6665 + source "crypto/Kconfig"
6666 +diff -NurpP --minimal linux-2.6.22.19/arch/x86_64/ia32/ia32_aout.c linux-2.6.22.19-vs2.2.0.7/arch/x86_64/ia32/ia32_aout.c
6667 +--- linux-2.6.22.19/arch/x86_64/ia32/ia32_aout.c 2007-02-06 03:00:21 +0100
6668 ++++ linux-2.6.22.19-vs2.2.0.7/arch/x86_64/ia32/ia32_aout.c 2007-06-15 02:37:03 +0200
6669 +@@ -25,6 +25,7 @@
6670 + #include <linux/binfmts.h>
6671 + #include <linux/personality.h>
6672 + #include <linux/init.h>
6673 ++#include <linux/vs_memory.h>
6674 +
6675 + #include <asm/system.h>
6676 + #include <asm/uaccess.h>
6677 +diff -NurpP --minimal linux-2.6.22.19/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.22.19-vs2.2.0.7/arch/x86_64/ia32/ia32_binfmt.c
6678 +--- linux-2.6.22.19/arch/x86_64/ia32/ia32_binfmt.c 2007-07-09 13:18:08 +0200
6679 ++++ linux-2.6.22.19-vs2.2.0.7/arch/x86_64/ia32/ia32_binfmt.c 2007-06-15 02:37:03 +0200
6680 +@@ -324,7 +324,8 @@ int ia32_setup_arg_pages(struct linux_bi
6681 + kmem_cache_free(vm_area_cachep, mpnt);
6682 + return ret;
6683 + }
6684 +- mm->stack_vm = mm->total_vm = vma_pages(mpnt);
6685 ++ vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
6686 ++ mm->stack_vm = mm->total_vm;
6687 + }
6688 +
6689 + for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
6690 +diff -NurpP --minimal linux-2.6.22.19/arch/x86_64/ia32/ia32entry.S linux-2.6.22.19-vs2.2.0.7/arch/x86_64/ia32/ia32entry.S
6691 +--- linux-2.6.22.19/arch/x86_64/ia32/ia32entry.S 2008-03-14 20:18:59 +0100
6692 ++++ linux-2.6.22.19-vs2.2.0.7/arch/x86_64/ia32/ia32entry.S 2007-10-01 15:25:34 +0200
6693 +@@ -680,7 +680,7 @@ ia32_sys_call_table:
6694 + .quad sys_tgkill /* 270 */
6695 + .quad compat_sys_utimes
6696 + .quad sys32_fadvise64_64
6697 +- .quad quiet_ni_syscall /* sys_vserver */
6698 ++ .quad sys32_vserver
6699 + .quad sys_mbind
6700 + .quad compat_sys_get_mempolicy /* 275 */
6701 + .quad sys_set_mempolicy
6702 +diff -NurpP --minimal linux-2.6.22.19/arch/x86_64/ia32/sys_ia32.c linux-2.6.22.19-vs2.2.0.7/arch/x86_64/ia32/sys_ia32.c
6703 +--- linux-2.6.22.19/arch/x86_64/ia32/sys_ia32.c 2007-07-09 13:18:08 +0200
6704 ++++ linux-2.6.22.19-vs2.2.0.7/arch/x86_64/ia32/sys_ia32.c 2007-07-07 03:52:53 +0200
6705 +@@ -454,7 +454,7 @@ sys32_gettimeofday(struct compat_timeval
6706 + {
6707 + if (tv) {
6708 + struct timeval ktv;
6709 +- do_gettimeofday(&ktv);
6710 ++ vx_gettimeofday(&ktv);
6711 + if (put_tv32(tv, &ktv))
6712 + return -EFAULT;
6713 + }
6714 +diff -NurpP --minimal linux-2.6.22.19/arch/x86_64/ia32/syscall32.c linux-2.6.22.19-vs2.2.0.7/arch/x86_64/ia32/syscall32.c
6715 +--- linux-2.6.22.19/arch/x86_64/ia32/syscall32.c 2007-07-09 13:18:08 +0200
6716 ++++ linux-2.6.22.19-vs2.2.0.7/arch/x86_64/ia32/syscall32.c 2007-06-15 02:37:03 +0200
6717 +@@ -10,6 +10,7 @@
6718 + #include <linux/init.h>
6719 + #include <linux/stringify.h>
6720 + #include <linux/security.h>
6721 ++#include <linux/vs_memory.h>
6722 + #include <asm/proto.h>
6723 + #include <asm/tlbflush.h>
6724 + #include <asm/ia32_unistd.h>
6725 +diff -NurpP --minimal linux-2.6.22.19/arch/x86_64/kernel/process.c linux-2.6.22.19-vs2.2.0.7/arch/x86_64/kernel/process.c
6726 +--- linux-2.6.22.19/arch/x86_64/kernel/process.c 2007-07-09 13:18:08 +0200
6727 ++++ linux-2.6.22.19-vs2.2.0.7/arch/x86_64/kernel/process.c 2007-06-15 02:37:03 +0200
6728 +@@ -54,7 +54,8 @@
6729 +
6730 + asmlinkage extern void ret_from_fork(void);
6731 +
6732 +-unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
6733 ++unsigned long kernel_thread_flags =
6734 ++ CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD;
6735 +
6736 + unsigned long boot_option_idle_override = 0;
6737 + EXPORT_SYMBOL(boot_option_idle_override);
6738 +@@ -310,8 +311,8 @@ void __show_regs(struct pt_regs * regs)
6739 +
6740 + printk("\n");
6741 + print_modules();
6742 +- printk("Pid: %d, comm: %.20s %s %s %.*s\n",
6743 +- current->pid, current->comm, print_tainted(),
6744 ++ printk("Pid: %d:#%u, comm: %.20s %s %s %.*s\n",
6745 ++ current->pid, current->xid, current->comm, print_tainted(),
6746 + init_utsname()->release,
6747 + (int)strcspn(init_utsname()->version, " "),
6748 + init_utsname()->version);
6749 +diff -NurpP --minimal linux-2.6.22.19/arch/x86_64/kernel/traps.c linux-2.6.22.19-vs2.2.0.7/arch/x86_64/kernel/traps.c
6750 +--- linux-2.6.22.19/arch/x86_64/kernel/traps.c 2007-07-09 13:18:08 +0200
6751 ++++ linux-2.6.22.19-vs2.2.0.7/arch/x86_64/kernel/traps.c 2007-06-17 05:54:16 +0200
6752 +@@ -413,8 +413,9 @@ void show_registers(struct pt_regs *regs
6753 + rsp = regs->rsp;
6754 + printk("CPU %d ", cpu);
6755 + __show_regs(regs);
6756 +- printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
6757 +- cur->comm, cur->pid, task_thread_info(cur), cur);
6758 ++ printk("Process %s (pid: %d[#%u], threadinfo %p, task %p)\n",
6759 ++ cur->comm, cur->pid, cur->xid,
6760 ++ task_thread_info(cur), cur);
6761 +
6762 + /*
6763 + * When in-kernel, we also print out the stack and code at the
6764 +@@ -580,8 +581,8 @@ static void __kprobes do_trap(int trapnr
6765 +
6766 + if (exception_trace && unhandled_signal(tsk, signr))
6767 + printk(KERN_INFO
6768 +- "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
6769 +- tsk->comm, tsk->pid, str,
6770 ++ "%s[%d:#%u] trap %s rip:%lx rsp:%lx error:%lx\n",
6771 ++ tsk->comm, tsk->pid, tsk->xid, str,
6772 + regs->rip, regs->rsp, error_code);
6773 +
6774 + if (info)
6775 +@@ -684,8 +685,8 @@ asmlinkage void __kprobes do_general_pro
6776 +
6777 + if (exception_trace && unhandled_signal(tsk, SIGSEGV))
6778 + printk(KERN_INFO
6779 +- "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
6780 +- tsk->comm, tsk->pid,
6781 ++ "%s[%d:#%u] general protection rip:%lx rsp:%lx error:%lx\n",
6782 ++ tsk->comm, tsk->pid, tsk->xid,
6783 + regs->rip, regs->rsp, error_code);
6784 +
6785 + force_sig(SIGSEGV, tsk);
6786 +diff -NurpP --minimal linux-2.6.22.19/arch/x86_64/mm/fault.c linux-2.6.22.19-vs2.2.0.7/arch/x86_64/mm/fault.c
6787 +--- linux-2.6.22.19/arch/x86_64/mm/fault.c 2007-07-09 13:18:08 +0200
6788 ++++ linux-2.6.22.19-vs2.2.0.7/arch/x86_64/mm/fault.c 2007-06-17 05:54:16 +0200
6789 +@@ -497,10 +497,10 @@ bad_area_nosemaphore:
6790 +
6791 + if (exception_trace && unhandled_signal(tsk, SIGSEGV)) {
6792 + printk(
6793 +- "%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
6794 ++ "%s%s[%d:#%u]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
6795 + tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
6796 +- tsk->comm, tsk->pid, address, regs->rip,
6797 +- regs->rsp, error_code);
6798 ++ tsk->comm, tsk->pid, tsk->xid, address,
6799 ++ regs->rip, regs->rsp, error_code);
6800 + }
6801 +
6802 + tsk->thread.cr2 = address;
6803 +@@ -567,7 +567,8 @@ out_of_memory:
6804 + yield();
6805 + goto again;
6806 + }
6807 +- printk("VM: killing process %s\n", tsk->comm);
6808 ++ printk("VM: killing process %s(%d:#%u)\n",
6809 ++ tsk->comm, tsk->pid, tsk->xid);
6810 + if (error_code & 4)
6811 + do_exit(SIGKILL);
6812 + goto no_context;
6813 +diff -NurpP --minimal linux-2.6.22.19/drivers/block/Kconfig linux-2.6.22.19-vs2.2.0.7/drivers/block/Kconfig
6814 +--- linux-2.6.22.19/drivers/block/Kconfig 2007-07-09 13:18:16 +0200
6815 ++++ linux-2.6.22.19-vs2.2.0.7/drivers/block/Kconfig 2007-06-15 02:37:03 +0200
6816 +@@ -311,6 +311,13 @@ config BLK_DEV_CRYPTOLOOP
6817 + instead, which can be configured to be on-disk compatible with the
6818 + cryptoloop device.
6819 +
6820 ++config BLK_DEV_VROOT
6821 ++ tristate "Virtual Root device support"
6822 ++ depends on QUOTACTL
6823 ++ ---help---
6824 ++ Saying Y here will allow you to use quota/fs ioctls on a shared
6825 ++ partition within a virtual server without compromising security.
6826 ++
6827 + config BLK_DEV_NBD
6828 + tristate "Network block device support"
6829 + depends on NET
6830 +diff -NurpP --minimal linux-2.6.22.19/drivers/block/Makefile linux-2.6.22.19-vs2.2.0.7/drivers/block/Makefile
6831 +--- linux-2.6.22.19/drivers/block/Makefile 2007-02-06 03:00:26 +0100
6832 ++++ linux-2.6.22.19-vs2.2.0.7/drivers/block/Makefile 2007-06-15 02:37:03 +0200
6833 +@@ -28,4 +28,5 @@ obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryp
6834 + obj-$(CONFIG_VIODASD) += viodasd.o
6835 + obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
6836 + obj-$(CONFIG_BLK_DEV_UB) += ub.o
6837 ++obj-$(CONFIG_BLK_DEV_VROOT) += vroot.o
6838 +
6839 +diff -NurpP --minimal linux-2.6.22.19/drivers/block/loop.c linux-2.6.22.19-vs2.2.0.7/drivers/block/loop.c
6840 +--- linux-2.6.22.19/drivers/block/loop.c 2007-07-09 13:18:16 +0200
6841 ++++ linux-2.6.22.19-vs2.2.0.7/drivers/block/loop.c 2007-08-16 04:07:14 +0200
6842 +@@ -74,6 +74,7 @@
6843 + #include <linux/highmem.h>
6844 + #include <linux/gfp.h>
6845 + #include <linux/kthread.h>
6846 ++#include <linux/vs_context.h>
6847 +
6848 + #include <asm/uaccess.h>
6849 +
6850 +@@ -790,6 +791,7 @@ static int loop_set_fd(struct loop_devic
6851 + lo->lo_blocksize = lo_blocksize;
6852 + lo->lo_device = bdev;
6853 + lo->lo_flags = lo_flags;
6854 ++ lo->lo_xid = vx_current_xid();
6855 + lo->lo_backing_file = file;
6856 + lo->transfer = transfer_none;
6857 + lo->ioctl = NULL;
6858 +@@ -909,6 +911,7 @@ static int loop_clr_fd(struct loop_devic
6859 + lo->lo_encrypt_key_size = 0;
6860 + lo->lo_flags = 0;
6861 + lo->lo_thread = NULL;
6862 ++ lo->lo_xid = 0;
6863 + memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
6864 + memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
6865 + memset(lo->lo_file_name, 0, LO_NAME_SIZE);
6866 +@@ -930,7 +933,7 @@ loop_set_status(struct loop_device *lo,
6867 + struct loop_func_table *xfer;
6868 +
6869 + if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid &&
6870 +- !capable(CAP_SYS_ADMIN))
6871 ++ !vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP))
6872 + return -EPERM;
6873 + if (lo->lo_state != Lo_bound)
6874 + return -ENXIO;
6875 +@@ -1010,7 +1013,8 @@ loop_get_status(struct loop_device *lo,
6876 + memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE);
6877 + info->lo_encrypt_type =
6878 + lo->lo_encryption ? lo->lo_encryption->number : 0;
6879 +- if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
6880 ++ if (lo->lo_encrypt_key_size &&
6881 ++ vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) {
6882 + info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
6883 + memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
6884 + lo->lo_encrypt_key_size);
6885 +@@ -1321,6 +1325,9 @@ static int lo_open(struct inode *inode,
6886 + {
6887 + struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
6888 +
6889 ++ if (!vx_check(lo->lo_xid, VS_IDENT|VS_HOSTID))
6890 ++ return -EACCES;
6891 ++
6892 + mutex_lock(&lo->lo_ctl_mutex);
6893 + lo->lo_refcnt++;
6894 + mutex_unlock(&lo->lo_ctl_mutex);
6895 +diff -NurpP --minimal linux-2.6.22.19/drivers/block/vroot.c linux-2.6.22.19-vs2.2.0.7/drivers/block/vroot.c
6896 +--- linux-2.6.22.19/drivers/block/vroot.c 1970-01-01 01:00:00 +0100
6897 ++++ linux-2.6.22.19-vs2.2.0.7/drivers/block/vroot.c 2007-06-15 02:37:03 +0200
6898 +@@ -0,0 +1,281 @@
6899 ++/*
6900 ++ * linux/drivers/block/vroot.c
6901 ++ *
6902 ++ * written by Herbert Pötzl, 9/11/2002
6903 ++ * ported to 2.6.10 by Herbert Pötzl, 30/12/2004
6904 ++ *
6905 ++ * based on the loop.c code by Theodore Ts'o.
6906 ++ *
6907 ++ * Copyright (C) 2002-2007 by Herbert Pötzl.
6908 ++ * Redistribution of this file is permitted under the
6909 ++ * GNU General Public License.
6910 ++ *
6911 ++ */
6912 ++
6913 ++#include <linux/module.h>
6914 ++#include <linux/moduleparam.h>
6915 ++#include <linux/file.h>
6916 ++#include <linux/major.h>
6917 ++#include <linux/blkdev.h>
6918 ++
6919 ++#include <linux/vroot.h>
6920 ++#include <linux/vs_context.h>
6921 ++
6922 ++
6923 ++static int max_vroot = 8;
6924 ++
6925 ++static struct vroot_device *vroot_dev;
6926 ++static struct gendisk **disks;
6927 ++
6928 ++
6929 ++static int vroot_set_dev(
6930 ++ struct vroot_device *vr,
6931 ++ struct file *vr_file,
6932 ++ struct block_device *bdev,
6933 ++ unsigned int arg)
6934 ++{
6935 ++ struct block_device *real_bdev;
6936 ++ struct file *file;
6937 ++ struct inode *inode;
6938 ++ int error;
6939 ++
6940 ++ error = -EBUSY;
6941 ++ if (vr->vr_state != Vr_unbound)
6942 ++ goto out;
6943 ++
6944 ++ error = -EBADF;
6945 ++ file = fget(arg);
6946 ++ if (!file)
6947 ++ goto out;
6948 ++
6949 ++ error = -EINVAL;
6950 ++ inode = file->f_dentry->d_inode;
6951 ++
6952 ++
6953 ++ if (S_ISBLK(inode->i_mode)) {
6954 ++ real_bdev = inode->i_bdev;
6955 ++ vr->vr_device = real_bdev;
6956 ++ __iget(real_bdev->bd_inode);
6957 ++ } else
6958 ++ goto out_fput;
6959 ++
6960 ++ vxdprintk(VXD_CBIT(misc, 0),
6961 ++ "vroot[%d]_set_dev: dev=" VXF_DEV,
6962 ++ vr->vr_number, VXD_DEV(real_bdev));
6963 ++
6964 ++ vr->vr_state = Vr_bound;
6965 ++ error = 0;
6966 ++
6967 ++ out_fput:
6968 ++ fput(file);
6969 ++ out:
6970 ++ return error;
6971 ++}
6972 ++
6973 ++static int vroot_clr_dev(
6974 ++ struct vroot_device *vr,
6975 ++ struct file *vr_file,
6976 ++ struct block_device *bdev)
6977 ++{
6978 ++ struct block_device *real_bdev;
6979 ++
6980 ++ if (vr->vr_state != Vr_bound)
6981 ++ return -ENXIO;
6982 ++ if (vr->vr_refcnt > 1) /* we needed one fd for the ioctl */
6983 ++ return -EBUSY;
6984 ++
6985 ++ real_bdev = vr->vr_device;
6986 ++
6987 ++ vxdprintk(VXD_CBIT(misc, 0),
6988 ++ "vroot[%d]_clr_dev: dev=" VXF_DEV,
6989 ++ vr->vr_number, VXD_DEV(real_bdev));
6990 ++
6991 ++ bdput(real_bdev);
6992 ++ vr->vr_state = Vr_unbound;
6993 ++ vr->vr_device = NULL;
6994 ++ return 0;
6995 ++}
6996 ++
6997 ++
6998 ++static int vr_ioctl(struct inode *inode, struct file *file,
6999 ++ unsigned int cmd, unsigned long arg)
7000 ++{
7001 ++ struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
7002 ++ int err;
7003 ++
7004 ++ down(&vr->vr_ctl_mutex);
7005 ++ switch (cmd) {
7006 ++ case VROOT_SET_DEV:
7007 ++ err = vroot_set_dev(vr, file, inode->i_bdev, arg);
7008 ++ break;
7009 ++ case VROOT_CLR_DEV:
7010 ++ err = vroot_clr_dev(vr, file, inode->i_bdev);
7011 ++ break;
7012 ++ default:
7013 ++ err = -EINVAL;
7014 ++ break;
7015 ++ }
7016 ++ up(&vr->vr_ctl_mutex);
7017 ++ return err;
7018 ++}
7019 ++
7020 ++static int vr_open(struct inode *inode, struct file *file)
7021 ++{
7022 ++ struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
7023 ++
7024 ++ down(&vr->vr_ctl_mutex);
7025 ++ vr->vr_refcnt++;
7026 ++ up(&vr->vr_ctl_mutex);
7027 ++ return 0;
7028 ++}
7029 ++
7030 ++static int vr_release(struct inode *inode, struct file *file)
7031 ++{
7032 ++ struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
7033 ++
7034 ++ down(&vr->vr_ctl_mutex);
7035 ++ --vr->vr_refcnt;
7036 ++ up(&vr->vr_ctl_mutex);
7037 ++ return 0;
7038 ++}
7039 ++
7040 ++static struct block_device_operations vr_fops = {
7041 ++ .owner = THIS_MODULE,
7042 ++ .open = vr_open,
7043 ++ .release = vr_release,
7044 ++ .ioctl = vr_ioctl,
7045 ++};
7046 ++
7047 ++struct block_device *__vroot_get_real_bdev(struct block_device *bdev)
7048 ++{
7049 ++ struct inode *inode = bdev->bd_inode;
7050 ++ struct vroot_device *vr;
7051 ++ struct block_device *real_bdev;
7052 ++ int minor = iminor(inode);
7053 ++
7054 ++ vr = &vroot_dev[minor];
7055 ++ real_bdev = vr->vr_device;
7056 ++
7057 ++ vxdprintk(VXD_CBIT(misc, 0),
7058 ++ "vroot[%d]_get_real_bdev: dev=" VXF_DEV,
7059 ++ vr->vr_number, VXD_DEV(real_bdev));
7060 ++
7061 ++ if (vr->vr_state != Vr_bound)
7062 ++ return ERR_PTR(-ENXIO);
7063 ++
7064 ++ __iget(real_bdev->bd_inode);
7065 ++ return real_bdev;
7066 ++}
7067 ++
7068 ++/*
7069 ++ * And now the modules code and kernel interface.
7070 ++ */
7071 ++
7072 ++module_param(max_vroot, int, 0);
7073 ++
7074 ++MODULE_PARM_DESC(max_vroot, "Maximum number of vroot devices (1-256)");
7075 ++MODULE_LICENSE("GPL");
7076 ++MODULE_ALIAS_BLOCKDEV_MAJOR(VROOT_MAJOR);
7077 ++
7078 ++MODULE_AUTHOR ("Herbert Pötzl");
7079 ++MODULE_DESCRIPTION ("Virtual Root Device Mapper");
7080 ++
7081 ++
7082 ++int __init vroot_init(void)
7083 ++{
7084 ++ int err, i;
7085 ++
7086 ++ if (max_vroot < 1 || max_vroot > 256) {
7087 ++ max_vroot = MAX_VROOT_DEFAULT;
7088 ++ printk(KERN_WARNING "vroot: invalid max_vroot "
7089 ++ "(must be between 1 and 256), "
7090 ++ "using default (%d)\n", max_vroot);
7091 ++ }
7092 ++
7093 ++ if (register_blkdev(VROOT_MAJOR, "vroot"))
7094 ++ return -EIO;
7095 ++
7096 ++ err = -ENOMEM;
7097 ++ vroot_dev = kmalloc(max_vroot * sizeof(struct vroot_device), GFP_KERNEL);
7098 ++ if (!vroot_dev)
7099 ++ goto out_mem1;
7100 ++ memset(vroot_dev, 0, max_vroot * sizeof(struct vroot_device));
7101 ++
7102 ++ disks = kmalloc(max_vroot * sizeof(struct gendisk *), GFP_KERNEL);
7103 ++ if (!disks)
7104 ++ goto out_mem2;
7105 ++
7106 ++ for (i = 0; i < max_vroot; i++) {
7107 ++ disks[i] = alloc_disk(1);
7108 ++ if (!disks[i])
7109 ++ goto out_mem3;
7110 ++ }
7111 ++
7112 ++ for (i = 0; i < max_vroot; i++) {
7113 ++ struct vroot_device *vr = &vroot_dev[i];
7114 ++ struct gendisk *disk = disks[i];
7115 ++
7116 ++ memset(vr, 0, sizeof(*vr));
7117 ++ init_MUTEX(&vr->vr_ctl_mutex);
7118 ++ vr->vr_number = i;
7119 ++ disk->major = VROOT_MAJOR;
7120 ++ disk->first_minor = i;
7121 ++ disk->fops = &vr_fops;
7122 ++ sprintf(disk->disk_name, "vroot%d", i);
7123 ++ disk->private_data = vr;
7124 ++ }
7125 ++
7126 ++ err = register_vroot_grb(&__vroot_get_real_bdev);
7127 ++ if (err)
7128 ++ goto out_mem3;
7129 ++
7130 ++ for (i = 0; i < max_vroot; i++)
7131 ++ add_disk(disks[i]);
7132 ++ printk(KERN_INFO "vroot: loaded (max %d devices)\n", max_vroot);
7133 ++ return 0;
7134 ++
7135 ++out_mem3:
7136 ++ while (i--)
7137 ++ put_disk(disks[i]);
7138 ++ kfree(disks);
7139 ++out_mem2:
7140 ++ kfree(vroot_dev);
7141 ++out_mem1:
7142 ++ unregister_blkdev(VROOT_MAJOR, "vroot");
7143 ++ printk(KERN_ERR "vroot: ran out of memory\n");
7144 ++ return err;
7145 ++}
7146 ++
7147 ++void vroot_exit(void)
7148 ++{
7149 ++ int i;
7150 ++
7151 ++ if (unregister_vroot_grb(&__vroot_get_real_bdev))
7152 ++ printk(KERN_WARNING "vroot: cannot unregister grb\n");
7153 ++
7154 ++ for (i = 0; i < max_vroot; i++) {
7155 ++ del_gendisk(disks[i]);
7156 ++ put_disk(disks[i]);
7157 ++ }
7158 ++ if (unregister_blkdev(VROOT_MAJOR, "vroot"))
7159 ++ printk(KERN_WARNING "vroot: cannot unregister blkdev\n");
7160 ++
7161 ++ kfree(disks);
7162 ++ kfree(vroot_dev);
7163 ++}
7164 ++
7165 ++module_init(vroot_init);
7166 ++module_exit(vroot_exit);
7167 ++
7168 ++#ifndef MODULE
7169 ++
7170 ++static int __init max_vroot_setup(char *str)
7171 ++{
7172 ++ max_vroot = simple_strtol(str, NULL, 0);
7173 ++ return 1;
7174 ++}
7175 ++
7176 ++__setup("max_vroot=", max_vroot_setup);
7177 ++
7178 ++#endif
7179 ++
7180 +diff -NurpP --minimal linux-2.6.22.19/drivers/char/sysrq.c linux-2.6.22.19-vs2.2.0.7/drivers/char/sysrq.c
7181 +--- linux-2.6.22.19/drivers/char/sysrq.c 2007-07-09 13:18:20 +0200
7182 ++++ linux-2.6.22.19-vs2.2.0.7/drivers/char/sysrq.c 2007-06-15 02:37:03 +0200
7183 +@@ -36,6 +36,7 @@
7184 + #include <linux/kexec.h>
7185 + #include <linux/irq.h>
7186 + #include <linux/hrtimer.h>
7187 ++#include <linux/vserver/debug.h>
7188 +
7189 + #include <asm/ptrace.h>
7190 + #include <asm/irq_regs.h>
7191 +@@ -309,6 +310,21 @@ static struct sysrq_key_op sysrq_unrt_op
7192 + .enable_mask = SYSRQ_ENABLE_RTNICE,
7193 + };
7194 +
7195 ++
7196 ++#ifdef CONFIG_VSERVER_DEBUG
7197 ++static void sysrq_handle_vxinfo(int key, struct tty_struct *tty)
7198 ++{
7199 ++ dump_vx_info_inactive((key == 'x')?0:1);
7200 ++}
7201 ++
7202 ++static struct sysrq_key_op sysrq_showvxinfo_op = {
7203 ++ .handler = sysrq_handle_vxinfo,
7204 ++ .help_msg = "conteXt",
7205 ++ .action_msg = "Show Context Info",
7206 ++ .enable_mask = SYSRQ_ENABLE_DUMP,
7207 ++};
7208 ++#endif
7209 ++
7210 + /* Key Operations table and lock */
7211 + static DEFINE_SPINLOCK(sysrq_key_table_lock);
7212 +
7213 +@@ -357,7 +373,11 @@ static struct sysrq_key_op *sysrq_key_ta
7214 + /* x: May be registered on ppc/powerpc for xmon */
7215 + NULL, /* x */
7216 + NULL, /* y */
7217 +- NULL /* z */
7218 ++#ifdef CONFIG_VSERVER_DEBUG
7219 ++ &sysrq_showvxinfo_op, /* z */
7220 ++#else
7221 ++ NULL, /* z */
7222 ++#endif
7223 + };
7224 +
7225 + /* key2index calculation, -1 on invalid index */
7226 +@@ -369,6 +389,8 @@ static int sysrq_key_table_key2index(int
7227 + retval = key - '0';
7228 + else if ((key >= 'a') && (key <= 'z'))
7229 + retval = key + 10 - 'a';
7230 ++ else if ((key >= 'A') && (key <= 'Z'))
7231 ++ retval = key + 10 - 'A';
7232 + else
7233 + retval = -1;
7234 + return retval;
7235 +diff -NurpP --minimal linux-2.6.22.19/drivers/char/tty_io.c linux-2.6.22.19-vs2.2.0.7/drivers/char/tty_io.c
7236 +--- linux-2.6.22.19/drivers/char/tty_io.c 2007-07-09 13:18:20 +0200
7237 ++++ linux-2.6.22.19-vs2.2.0.7/drivers/char/tty_io.c 2007-07-17 03:02:15 +0200
7238 +@@ -103,6 +103,7 @@
7239 + #include <linux/selection.h>
7240 +
7241 + #include <linux/kmod.h>
7242 ++#include <linux/vs_pid.h>
7243 +
7244 + #undef TTY_DEBUG_HANGUP
7245 +
7246 +@@ -3049,13 +3050,15 @@ unlock:
7247 +
7248 + static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
7249 + {
7250 ++ pid_t pgrp;
7251 + /*
7252 + * (tty == real_tty) is a cheap way of
7253 + * testing if the tty is NOT a master pty.
7254 + */
7255 + if (tty == real_tty && current->signal->tty != real_tty)
7256 + return -ENOTTY;
7257 +- return put_user(pid_nr(real_tty->pgrp), p);
7258 ++ pgrp = vx_map_pid(pid_nr(real_tty->pgrp));
7259 ++ return put_user(pgrp, p);
7260 + }
7261 +
7262 + /**
7263 +@@ -3086,6 +3089,7 @@ static int tiocspgrp(struct tty_struct *
7264 + return -ENOTTY;
7265 + if (get_user(pgrp_nr, p))
7266 + return -EFAULT;
7267 ++ pgrp_nr = vx_rmap_pid(pgrp_nr);
7268 + if (pgrp_nr < 0)
7269 + return -EINVAL;
7270 + rcu_read_lock();
7271 +diff -NurpP --minimal linux-2.6.22.19/drivers/infiniband/hw/ipath/ipath_user_pages.c linux-2.6.22.19-vs2.2.0.7/drivers/infiniband/hw/ipath/ipath_user_pages.c
7272 +--- linux-2.6.22.19/drivers/infiniband/hw/ipath/ipath_user_pages.c 2007-02-06 03:00:37 +0100
7273 ++++ linux-2.6.22.19-vs2.2.0.7/drivers/infiniband/hw/ipath/ipath_user_pages.c 2007-06-15 02:37:03 +0200
7274 +@@ -33,6 +33,7 @@
7275 +
7276 + #include <linux/mm.h>
7277 + #include <linux/device.h>
7278 ++#include <linux/vs_memory.h>
7279 +
7280 + #include "ipath_kernel.h"
7281 +
7282 +@@ -61,7 +62,8 @@ static int __get_user_pages(unsigned lon
7283 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >>
7284 + PAGE_SHIFT;
7285 +
7286 +- if (num_pages > lock_limit) {
7287 ++ if (num_pages > lock_limit ||
7288 ++ !vx_vmlocked_avail(current->mm, num_pages)) {
7289 + ret = -ENOMEM;
7290 + goto bail;
7291 + }
7292 +@@ -78,7 +80,7 @@ static int __get_user_pages(unsigned lon
7293 + goto bail_release;
7294 + }
7295 +
7296 +- current->mm->locked_vm += num_pages;
7297 ++ vx_vmlocked_add(current->mm, num_pages);
7298 +
7299 + ret = 0;
7300 + goto bail;
7301 +@@ -203,7 +205,7 @@ void ipath_release_user_pages(struct pag
7302 +
7303 + __ipath_release_user_pages(p, num_pages, 1);
7304 +
7305 +- current->mm->locked_vm -= num_pages;
7306 ++ vx_vmlocked_sub(current->mm, num_pages);
7307 +
7308 + up_write(&current->mm->mmap_sem);
7309 + }
7310 +@@ -220,7 +222,7 @@ static void user_pages_account(struct wo
7311 + container_of(_work, struct ipath_user_pages_work, work);
7312 +
7313 + down_write(&work->mm->mmap_sem);
7314 +- work->mm->locked_vm -= work->num_pages;
7315 ++ vx_vmlocked_sub(work->mm, work->num_pages);
7316 + up_write(&work->mm->mmap_sem);
7317 + mmput(work->mm);
7318 + kfree(work);
7319 +diff -NurpP --minimal linux-2.6.22.19/drivers/md/dm-ioctl.c linux-2.6.22.19-vs2.2.0.7/drivers/md/dm-ioctl.c
7320 +--- linux-2.6.22.19/drivers/md/dm-ioctl.c 2007-05-02 19:24:50 +0200
7321 ++++ linux-2.6.22.19-vs2.2.0.7/drivers/md/dm-ioctl.c 2007-06-15 02:37:03 +0200
7322 +@@ -15,6 +15,7 @@
7323 + #include <linux/slab.h>
7324 + #include <linux/dm-ioctl.h>
7325 + #include <linux/hdreg.h>
7326 ++#include <linux/vs_context.h>
7327 +
7328 + #include <asm/uaccess.h>
7329 +
7330 +@@ -100,7 +101,8 @@ static struct hash_cell *__get_name_cell
7331 + unsigned int h = hash_str(str);
7332 +
7333 + list_for_each_entry (hc, _name_buckets + h, name_list)
7334 +- if (!strcmp(hc->name, str)) {
7335 ++ if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) &&
7336 ++ !strcmp(hc->name, str)) {
7337 + dm_get(hc->md);
7338 + return hc;
7339 + }
7340 +@@ -114,7 +116,8 @@ static struct hash_cell *__get_uuid_cell
7341 + unsigned int h = hash_str(str);
7342 +
7343 + list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
7344 +- if (!strcmp(hc->uuid, str)) {
7345 ++ if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) &&
7346 ++ !strcmp(hc->uuid, str)) {
7347 + dm_get(hc->md);
7348 + return hc;
7349 + }
7350 +@@ -349,6 +352,9 @@ typedef int (*ioctl_fn)(struct dm_ioctl
7351 +
7352 + static int remove_all(struct dm_ioctl *param, size_t param_size)
7353 + {
7354 ++ if (!vx_check(0, VS_ADMIN))
7355 ++ return -EPERM;
7356 ++
7357 + dm_hash_remove_all(1);
7358 + param->data_size = 0;
7359 + return 0;
7360 +@@ -396,6 +402,8 @@ static int list_devices(struct dm_ioctl
7361 + */
7362 + for (i = 0; i < NUM_BUCKETS; i++) {
7363 + list_for_each_entry (hc, _name_buckets + i, name_list) {
7364 ++ if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT))
7365 ++ continue;
7366 + needed += sizeof(struct dm_name_list);
7367 + needed += strlen(hc->name) + 1;
7368 + needed += ALIGN_MASK;
7369 +@@ -419,6 +427,8 @@ static int list_devices(struct dm_ioctl
7370 + */
7371 + for (i = 0; i < NUM_BUCKETS; i++) {
7372 + list_for_each_entry (hc, _name_buckets + i, name_list) {
7373 ++ if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT))
7374 ++ continue;
7375 + if (old_nl)
7376 + old_nl->next = (uint32_t) ((void *) nl -
7377 + (void *) old_nl);
7378 +@@ -609,10 +619,11 @@ static struct hash_cell *__find_device_h
7379 + if (!md)
7380 + goto out;
7381 +
7382 +- mdptr = dm_get_mdptr(md);
7383 ++ if (vx_check(dm_get_xid(md), VS_WATCH_P | VS_IDENT))
7384 ++ mdptr = dm_get_mdptr(md);
7385 ++
7386 + if (!mdptr)
7387 + dm_put(md);
7388 +-
7389 + out:
7390 + return mdptr;
7391 + }
7392 +@@ -1409,8 +1420,8 @@ static int ctl_ioctl(struct inode *inode
7393 + ioctl_fn fn = NULL;
7394 + size_t param_size;
7395 +
7396 +- /* only root can play with this */
7397 +- if (!capable(CAP_SYS_ADMIN))
7398 ++ /* only root and certain contexts can play with this */
7399 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_MAPPER))
7400 + return -EACCES;
7401 +
7402 + if (_IOC_TYPE(command) != DM_IOCTL)
7403 +diff -NurpP --minimal linux-2.6.22.19/drivers/md/dm.c linux-2.6.22.19-vs2.2.0.7/drivers/md/dm.c
7404 +--- linux-2.6.22.19/drivers/md/dm.c 2008-03-14 20:19:00 +0100
7405 ++++ linux-2.6.22.19-vs2.2.0.7/drivers/md/dm.c 2007-08-12 12:21:50 +0200
7406 +@@ -21,6 +21,7 @@
7407 + #include <linux/hdreg.h>
7408 + #include <linux/blktrace_api.h>
7409 + #include <linux/smp_lock.h>
7410 ++#include <linux/vs_base.h>
7411 +
7412 + #define DM_MSG_PREFIX "core"
7413 +
7414 +@@ -77,6 +78,7 @@ struct mapped_device {
7415 + rwlock_t map_lock;
7416 + atomic_t holders;
7417 + atomic_t open_count;
7418 ++ xid_t xid;
7419 +
7420 + unsigned long flags;
7421 +
7422 +@@ -223,6 +225,7 @@ static void __exit dm_exit(void)
7423 + static int dm_blk_open(struct inode *inode, struct file *file)
7424 + {
7425 + struct mapped_device *md;
7426 ++ int ret = -ENXIO;
7427 +
7428 + spin_lock(&_minor_lock);
7429 +
7430 +@@ -231,18 +234,19 @@ static int dm_blk_open(struct inode *ino
7431 + goto out;
7432 +
7433 + if (test_bit(DMF_FREEING, &md->flags) ||
7434 +- test_bit(DMF_DELETING, &md->flags)) {
7435 +- md = NULL;
7436 ++ test_bit(DMF_DELETING, &md->flags))
7437 ++ goto out;
7438 ++
7439 ++ ret = -EACCES;
7440 ++ if (!vx_check(md->xid, VS_IDENT|VS_HOSTID))
7441 + goto out;
7442 +- }
7443 +
7444 + dm_get(md);
7445 + atomic_inc(&md->open_count);
7446 +-
7447 ++ ret = 0;
7448 + out:
7449 + spin_unlock(&_minor_lock);
7450 +-
7451 +- return md ? 0 : -ENXIO;
7452 ++ return ret;
7453 + }
7454 +
7455 + static int dm_blk_close(struct inode *inode, struct file *file)
7456 +@@ -438,6 +442,14 @@ int dm_set_geometry(struct mapped_device
7457 + return 0;
7458 + }
7459 +
7460 ++/*
7461 ++ * Get the xid associated with a dm device
7462 ++ */
7463 ++xid_t dm_get_xid(struct mapped_device *md)
7464 ++{
7465 ++ return md->xid;
7466 ++}
7467 ++
7468 + /*-----------------------------------------------------------------
7469 + * CRUD START:
7470 + * A more elegant soln is in the works that uses the queue
7471 +@@ -1000,6 +1012,7 @@ static struct mapped_device *alloc_dev(i
7472 + atomic_set(&md->holders, 1);
7473 + atomic_set(&md->open_count, 0);
7474 + atomic_set(&md->event_nr, 0);
7475 ++ md->xid = vx_current_xid();
7476 +
7477 + md->queue = blk_alloc_queue(GFP_KERNEL);
7478 + if (!md->queue)
7479 +diff -NurpP --minimal linux-2.6.22.19/drivers/md/dm.h linux-2.6.22.19-vs2.2.0.7/drivers/md/dm.h
7480 +--- linux-2.6.22.19/drivers/md/dm.h 2007-02-06 03:00:41 +0100
7481 ++++ linux-2.6.22.19-vs2.2.0.7/drivers/md/dm.h 2007-06-15 02:37:03 +0200
7482 +@@ -91,6 +91,8 @@ void dm_put_target_type(struct target_ty
7483 + int dm_target_iterate(void (*iter_func)(struct target_type *tt,
7484 + void *param), void *param);
7485 +
7486 ++xid_t dm_get_xid(struct mapped_device *md);
7487 ++
7488 + /*-----------------------------------------------------------------
7489 + * Useful inlines.
7490 + *---------------------------------------------------------------*/
7491 +diff -NurpP --minimal linux-2.6.22.19/fs/Kconfig linux-2.6.22.19-vs2.2.0.7/fs/Kconfig
7492 +--- linux-2.6.22.19/fs/Kconfig 2007-07-09 13:19:22 +0200
7493 ++++ linux-2.6.22.19-vs2.2.0.7/fs/Kconfig 2008-01-18 13:57:14 +0100
7494 +@@ -2026,7 +2026,7 @@ config CODA_FS_OLD_API
7495 +
7496 + config AFS_FS
7497 + tristate "Andrew File System support (AFS) (EXPERIMENTAL)"
7498 +- depends on INET && EXPERIMENTAL
7499 ++ depends on INET && EXPERIMENTAL && !VSERVER_SECURITY
7500 + select AF_RXRPC
7501 + help
7502 + If you say Y here, you will get an experimental Andrew File System
7503 +diff -NurpP --minimal linux-2.6.22.19/fs/attr.c linux-2.6.22.19-vs2.2.0.7/fs/attr.c
7504 +--- linux-2.6.22.19/fs/attr.c 2007-07-09 13:19:22 +0200
7505 ++++ linux-2.6.22.19-vs2.2.0.7/fs/attr.c 2007-10-29 23:34:23 +0100
7506 +@@ -14,6 +14,9 @@
7507 + #include <linux/fcntl.h>
7508 + #include <linux/quotaops.h>
7509 + #include <linux/security.h>
7510 ++#include <linux/proc_fs.h>
7511 ++#include <linux/devpts_fs.h>
7512 ++#include <linux/vs_base.h>
7513 +
7514 + /* Taken over from the old code... */
7515 +
7516 +@@ -55,6 +58,27 @@ int inode_change_ok(struct inode *inode,
7517 + if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER))
7518 + goto error;
7519 + }
7520 ++
7521 ++ /* Check for evil vserver activity */
7522 ++ if (vx_check(0, VS_ADMIN))
7523 ++ goto fine;
7524 ++
7525 ++ if (IS_BARRIER(inode)) {
7526 ++ vxwprintk_task(1, "messing with the barrier.");
7527 ++ goto error;
7528 ++ }
7529 ++ switch (inode->i_sb->s_magic) {
7530 ++ case PROC_SUPER_MAGIC:
7531 ++ /* maybe allow that in the future? */
7532 ++ vxwprintk_task(1, "messing with the procfs.");
7533 ++ goto error;
7534 ++ case DEVPTS_SUPER_MAGIC:
7535 ++ /* devpts is xid tagged */
7536 ++ if (vx_check((xid_t)inode->i_tag, VS_IDENT))
7537 ++ goto fine;
7538 ++ vxwprintk_task(1, "messing with the devpts.");
7539 ++ goto error;
7540 ++ }
7541 + fine:
7542 + retval = 0;
7543 + error:
7544 +@@ -78,6 +102,8 @@ int inode_setattr(struct inode * inode,
7545 + inode->i_uid = attr->ia_uid;
7546 + if (ia_valid & ATTR_GID)
7547 + inode->i_gid = attr->ia_gid;
7548 ++ if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode))
7549 ++ inode->i_tag = attr->ia_tag;
7550 + if (ia_valid & ATTR_ATIME)
7551 + inode->i_atime = timespec_trunc(attr->ia_atime,
7552 + inode->i_sb->s_time_gran);
7553 +@@ -152,7 +178,8 @@ int notify_change(struct dentry * dentry
7554 + error = security_inode_setattr(dentry, attr);
7555 + if (!error) {
7556 + if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
7557 +- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
7558 ++ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
7559 ++ (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag))
7560 + error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
7561 + if (!error)
7562 + error = inode_setattr(inode, attr);
7563 +diff -NurpP --minimal linux-2.6.22.19/fs/binfmt_aout.c linux-2.6.22.19-vs2.2.0.7/fs/binfmt_aout.c
7564 +--- linux-2.6.22.19/fs/binfmt_aout.c 2007-02-06 03:01:16 +0100
7565 ++++ linux-2.6.22.19-vs2.2.0.7/fs/binfmt_aout.c 2007-06-15 02:37:03 +0200
7566 +@@ -24,6 +24,7 @@
7567 + #include <linux/binfmts.h>
7568 + #include <linux/personality.h>
7569 + #include <linux/init.h>
7570 ++#include <linux/vs_memory.h>
7571 +
7572 + #include <asm/system.h>
7573 + #include <asm/uaccess.h>
7574 +diff -NurpP --minimal linux-2.6.22.19/fs/binfmt_elf.c linux-2.6.22.19-vs2.2.0.7/fs/binfmt_elf.c
7575 +--- linux-2.6.22.19/fs/binfmt_elf.c 2007-07-09 13:19:22 +0200
7576 ++++ linux-2.6.22.19-vs2.2.0.7/fs/binfmt_elf.c 2007-07-09 13:11:54 +0200
7577 +@@ -39,6 +39,7 @@
7578 + #include <linux/random.h>
7579 + #include <linux/elf.h>
7580 + #include <linux/utsname.h>
7581 ++#include <linux/vs_memory.h>
7582 + #include <asm/uaccess.h>
7583 + #include <asm/param.h>
7584 + #include <asm/page.h>
7585 +diff -NurpP --minimal linux-2.6.22.19/fs/binfmt_flat.c linux-2.6.22.19-vs2.2.0.7/fs/binfmt_flat.c
7586 +--- linux-2.6.22.19/fs/binfmt_flat.c 2007-07-09 13:19:22 +0200
7587 ++++ linux-2.6.22.19-vs2.2.0.7/fs/binfmt_flat.c 2007-06-17 05:54:17 +0200
7588 +@@ -36,6 +36,7 @@
7589 + #include <linux/init.h>
7590 + #include <linux/flat.h>
7591 + #include <linux/syscalls.h>
7592 ++#include <linux/vs_memory.h>
7593 +
7594 + #include <asm/byteorder.h>
7595 + #include <asm/system.h>
7596 +diff -NurpP --minimal linux-2.6.22.19/fs/binfmt_som.c linux-2.6.22.19-vs2.2.0.7/fs/binfmt_som.c
7597 +--- linux-2.6.22.19/fs/binfmt_som.c 2006-11-30 21:19:19 +0100
7598 ++++ linux-2.6.22.19-vs2.2.0.7/fs/binfmt_som.c 2007-06-15 02:37:03 +0200
7599 +@@ -28,6 +28,7 @@
7600 + #include <linux/shm.h>
7601 + #include <linux/personality.h>
7602 + #include <linux/init.h>
7603 ++#include <linux/vs_memory.h>
7604 +
7605 + #include <asm/a.out.h>
7606 + #include <asm/uaccess.h>
7607 +diff -NurpP --minimal linux-2.6.22.19/fs/dcache.c linux-2.6.22.19-vs2.2.0.7/fs/dcache.c
7608 +--- linux-2.6.22.19/fs/dcache.c 2007-07-09 13:19:23 +0200
7609 ++++ linux-2.6.22.19-vs2.2.0.7/fs/dcache.c 2007-06-15 02:37:03 +0200
7610 +@@ -31,6 +31,7 @@
7611 + #include <linux/seqlock.h>
7612 + #include <linux/swap.h>
7613 + #include <linux/bootmem.h>
7614 ++#include <linux/vs_limit.h>
7615 + #include "internal.h"
7616 +
7617 +
7618 +@@ -176,6 +177,7 @@ void dput(struct dentry *dentry)
7619 + if (!dentry)
7620 + return;
7621 +
7622 ++ vx_dentry_dec(dentry);
7623 + repeat:
7624 + if (atomic_read(&dentry->d_count) == 1)
7625 + might_sleep();
7626 +@@ -189,6 +191,8 @@ repeat:
7627 + return;
7628 + }
7629 +
7630 ++ vx_dentry_dec(dentry);
7631 ++
7632 + /*
7633 + * AV: ->d_delete() is _NOT_ allowed to block now.
7634 + */
7635 +@@ -288,6 +292,7 @@ static inline struct dentry * __dget_loc
7636 + if (!list_empty(&dentry->d_lru)) {
7637 + dentry_stat.nr_unused--;
7638 + list_del_init(&dentry->d_lru);
7639 ++ vx_dentry_inc(dentry);
7640 + }
7641 + return dentry;
7642 + }
7643 +@@ -898,6 +903,9 @@ struct dentry *d_alloc(struct dentry * p
7644 + struct dentry *dentry;
7645 + char *dname;
7646 +
7647 ++ if (!vx_dentry_avail(1))
7648 ++ return NULL;
7649 ++
7650 + dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
7651 + if (!dentry)
7652 + return NULL;
7653 +@@ -946,6 +954,7 @@ struct dentry *d_alloc(struct dentry * p
7654 + if (parent)
7655 + list_add(&dentry->d_u.d_child, &parent->d_subdirs);
7656 + dentry_stat.nr_dentry++;
7657 ++ vx_dentry_inc(dentry);
7658 + spin_unlock(&dcache_lock);
7659 +
7660 + return dentry;
7661 +@@ -1295,6 +1304,7 @@ struct dentry * __d_lookup(struct dentry
7662 +
7663 + if (!d_unhashed(dentry)) {
7664 + atomic_inc(&dentry->d_count);
7665 ++ vx_dentry_inc(dentry);
7666 + found = dentry;
7667 + }
7668 + spin_unlock(&dentry->d_lock);
7669 +diff -NurpP --minimal linux-2.6.22.19/fs/devpts/inode.c linux-2.6.22.19-vs2.2.0.7/fs/devpts/inode.c
7670 +--- linux-2.6.22.19/fs/devpts/inode.c 2007-07-09 13:19:23 +0200
7671 ++++ linux-2.6.22.19-vs2.2.0.7/fs/devpts/inode.c 2007-06-15 02:41:30 +0200
7672 +@@ -20,8 +20,22 @@
7673 + #include <linux/devpts_fs.h>
7674 + #include <linux/parser.h>
7675 + #include <linux/fsnotify.h>
7676 ++#include <linux/vs_base.h>
7677 ++
7678 +
7679 +-#define DEVPTS_SUPER_MAGIC 0x1cd1
7680 ++static int devpts_permission(struct inode *inode, int mask, struct nameidata *nd)
7681 ++{
7682 ++ int ret = -EACCES;
7683 ++
7684 ++ /* devpts is xid tagged */
7685 ++ if (vx_check((xid_t)inode->i_tag, VS_WATCH_P | VS_IDENT))
7686 ++ ret = generic_permission(inode, mask, NULL);
7687 ++ return ret;
7688 ++}
7689 ++
7690 ++static struct inode_operations devpts_file_inode_operations = {
7691 ++ .permission = devpts_permission,
7692 ++};
7693 +
7694 + static struct vfsmount *devpts_mnt;
7695 + static struct dentry *devpts_root;
7696 +@@ -92,6 +106,25 @@ static int devpts_remount(struct super_b
7697 + return 0;
7698 + }
7699 +
7700 ++static int devpts_filter(struct dentry *de)
7701 ++{
7702 ++ /* devpts is xid tagged */
7703 ++ return vx_check((xid_t)de->d_inode->i_tag, VS_WATCH_P | VS_IDENT);
7704 ++}
7705 ++
7706 ++static int devpts_readdir(struct file * filp, void * dirent, filldir_t filldir)
7707 ++{
7708 ++ return dcache_readdir_filter(filp, dirent, filldir, devpts_filter);
7709 ++}
7710 ++
7711 ++static struct file_operations devpts_dir_operations = {
7712 ++ .open = dcache_dir_open,
7713 ++ .release = dcache_dir_close,
7714 ++ .llseek = dcache_dir_lseek,
7715 ++ .read = generic_read_dir,
7716 ++ .readdir = devpts_readdir,
7717 ++};
7718 ++
7719 + static const struct super_operations devpts_sops = {
7720 + .statfs = simple_statfs,
7721 + .remount_fs = devpts_remount,
7722 +@@ -117,8 +150,10 @@ devpts_fill_super(struct super_block *s,
7723 + inode->i_uid = inode->i_gid = 0;
7724 + inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
7725 + inode->i_op = &simple_dir_inode_operations;
7726 +- inode->i_fop = &simple_dir_operations;
7727 ++ inode->i_fop = &devpts_dir_operations;
7728 + inode->i_nlink = 2;
7729 ++ /* devpts is xid tagged */
7730 ++ inode->i_tag = (tag_t)vx_current_xid();
7731 +
7732 + devpts_root = s->s_root = d_alloc_root(inode);
7733 + if (s->s_root)
7734 +@@ -176,6 +211,9 @@ int devpts_pty_new(struct tty_struct *tt
7735 + inode->i_gid = config.setgid ? config.gid : current->fsgid;
7736 + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
7737 + init_special_inode(inode, S_IFCHR|config.mode, device);
7738 ++ /* devpts is xid tagged */
7739 ++ inode->i_tag = (tag_t)vx_current_xid();
7740 ++ inode->i_op = &devpts_file_inode_operations;
7741 + inode->i_private = tty;
7742 +
7743 + dentry = get_node(number);
7744 +diff -NurpP --minimal linux-2.6.22.19/fs/ecryptfs/inode.c linux-2.6.22.19-vs2.2.0.7/fs/ecryptfs/inode.c
7745 +--- linux-2.6.22.19/fs/ecryptfs/inode.c 2008-03-14 20:19:03 +0100
7746 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ecryptfs/inode.c 2007-08-12 12:21:51 +0200
7747 +@@ -423,7 +423,7 @@ static int ecryptfs_link(struct dentry *
7748 + dget(lower_new_dentry);
7749 + lower_dir_dentry = lock_parent(lower_new_dentry);
7750 + rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
7751 +- lower_new_dentry);
7752 ++ lower_new_dentry, NULL);
7753 + if (rc || !lower_new_dentry->d_inode)
7754 + goto out_lock;
7755 + rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
7756 +@@ -451,7 +451,7 @@ static int ecryptfs_unlink(struct inode
7757 + struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
7758 +
7759 + lock_parent(lower_dentry);
7760 +- rc = vfs_unlink(lower_dir_inode, lower_dentry);
7761 ++ rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL);
7762 + if (rc) {
7763 + printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
7764 + goto out_unlock;
7765 +@@ -488,7 +488,7 @@ static int ecryptfs_symlink(struct inode
7766 + goto out_lock;
7767 + }
7768 + rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry,
7769 +- encoded_symname, mode);
7770 ++ encoded_symname, mode, NULL);
7771 + kfree(encoded_symname);
7772 + if (rc || !lower_dentry->d_inode)
7773 + goto out_lock;
7774 +@@ -513,7 +513,7 @@ static int ecryptfs_mkdir(struct inode *
7775 +
7776 + lower_dentry = ecryptfs_dentry_to_lower(dentry);
7777 + lower_dir_dentry = lock_parent(lower_dentry);
7778 +- rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode);
7779 ++ rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode, NULL);
7780 + if (rc || !lower_dentry->d_inode)
7781 + goto out;
7782 + rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
7783 +@@ -539,7 +539,7 @@ static int ecryptfs_rmdir(struct inode *
7784 + dget(dentry);
7785 + lower_dir_dentry = lock_parent(lower_dentry);
7786 + dget(lower_dentry);
7787 +- rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
7788 ++ rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry, NULL);
7789 + dput(lower_dentry);
7790 + if (!rc)
7791 + d_delete(lower_dentry);
7792 +@@ -561,7 +561,7 @@ ecryptfs_mknod(struct inode *dir, struct
7793 +
7794 + lower_dentry = ecryptfs_dentry_to_lower(dentry);
7795 + lower_dir_dentry = lock_parent(lower_dentry);
7796 +- rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev);
7797 ++ rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev, NULL);
7798 + if (rc || !lower_dentry->d_inode)
7799 + goto out;
7800 + rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
7801 +diff -NurpP --minimal linux-2.6.22.19/fs/exec.c linux-2.6.22.19-vs2.2.0.7/fs/exec.c
7802 +--- linux-2.6.22.19/fs/exec.c 2008-03-14 20:19:03 +0100
7803 ++++ linux-2.6.22.19-vs2.2.0.7/fs/exec.c 2008-03-14 19:19:48 +0100
7804 +@@ -51,6 +51,7 @@
7805 + #include <linux/cn_proc.h>
7806 + #include <linux/audit.h>
7807 + #include <linux/signalfd.h>
7808 ++#include <linux/vs_memory.h>
7809 +
7810 + #include <asm/uaccess.h>
7811 + #include <asm/mmu_context.h>
7812 +@@ -440,7 +441,8 @@ int setup_arg_pages(struct linux_binprm
7813 + kmem_cache_free(vm_area_cachep, mpnt);
7814 + return ret;
7815 + }
7816 +- mm->stack_vm = mm->total_vm = vma_pages(mpnt);
7817 ++ vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
7818 ++ mm->stack_vm = mm->total_vm;
7819 + }
7820 +
7821 + for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
7822 +@@ -1336,7 +1338,7 @@ static int format_corename(char *corenam
7823 + /* UNIX time of coredump */
7824 + case 't': {
7825 + struct timeval tv;
7826 +- do_gettimeofday(&tv);
7827 ++ vx_gettimeofday(&tv);
7828 + rc = snprintf(out_ptr, out_end - out_ptr,
7829 + "%lu", tv.tv_sec);
7830 + if (rc > out_end - out_ptr)
7831 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/balloc.c linux-2.6.22.19-vs2.2.0.7/fs/ext2/balloc.c
7832 +--- linux-2.6.22.19/fs/ext2/balloc.c 2007-05-02 19:25:17 +0200
7833 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext2/balloc.c 2007-06-15 02:37:03 +0200
7834 +@@ -16,6 +16,8 @@
7835 + #include <linux/sched.h>
7836 + #include <linux/buffer_head.h>
7837 + #include <linux/capability.h>
7838 ++#include <linux/vs_dlimit.h>
7839 ++#include <linux/vs_tag.h>
7840 +
7841 + /*
7842 + * balloc.c contains the blocks allocation and deallocation routines
7843 +@@ -102,12 +104,13 @@ static int reserve_blocks(struct super_b
7844 + {
7845 + struct ext2_sb_info *sbi = EXT2_SB(sb);
7846 + struct ext2_super_block *es = sbi->s_es;
7847 +- unsigned free_blocks;
7848 +- unsigned root_blocks;
7849 ++ unsigned long long free_blocks, root_blocks;
7850 +
7851 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
7852 + root_blocks = le32_to_cpu(es->s_r_blocks_count);
7853 +
7854 ++ DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
7855 ++
7856 + if (free_blocks < count)
7857 + count = free_blocks;
7858 +
7859 +@@ -258,6 +261,7 @@ do_more:
7860 + }
7861 + error_return:
7862 + brelse(bitmap_bh);
7863 ++ DLIMIT_FREE_BLOCK(inode, freed);
7864 + release_blocks(sb, freed);
7865 + DQUOT_FREE_BLOCK(inode, freed);
7866 + }
7867 +@@ -361,6 +365,10 @@ int ext2_new_block(struct inode *inode,
7868 + *err = -ENOSPC;
7869 + goto out_dquot;
7870 + }
7871 ++ if (DLIMIT_ALLOC_BLOCK(inode, es_alloc)) {
7872 ++ *err = -ENOSPC;
7873 ++ goto out_dlimit;
7874 ++ }
7875 +
7876 + ext2_debug ("goal=%lu.\n", goal);
7877 +
7878 +@@ -508,6 +516,8 @@ got_block:
7879 + *err = 0;
7880 + out_release:
7881 + group_release_blocks(sb, group_no, desc, gdp_bh, group_alloc);
7882 ++ DLIMIT_FREE_BLOCK(inode, es_alloc);
7883 ++out_dlimit:
7884 + release_blocks(sb, es_alloc);
7885 + out_dquot:
7886 + DQUOT_FREE_BLOCK(inode, dq_alloc);
7887 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/ext2.h linux-2.6.22.19-vs2.2.0.7/fs/ext2/ext2.h
7888 +--- linux-2.6.22.19/fs/ext2/ext2.h 2007-07-09 13:19:23 +0200
7889 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext2/ext2.h 2007-06-15 02:37:03 +0200
7890 +@@ -167,6 +167,7 @@ extern const struct file_operations ext2
7891 + extern const struct address_space_operations ext2_aops;
7892 + extern const struct address_space_operations ext2_aops_xip;
7893 + extern const struct address_space_operations ext2_nobh_aops;
7894 ++extern int ext2_sync_flags(struct inode *inode);
7895 +
7896 + /* namei.c */
7897 + extern const struct inode_operations ext2_dir_inode_operations;
7898 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/file.c linux-2.6.22.19-vs2.2.0.7/fs/ext2/file.c
7899 +--- linux-2.6.22.19/fs/ext2/file.c 2007-05-02 19:25:17 +0200
7900 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext2/file.c 2007-10-29 23:24:21 +0100
7901 +@@ -85,4 +85,5 @@ const struct inode_operations ext2_file_
7902 + #endif
7903 + .setattr = ext2_setattr,
7904 + .permission = ext2_permission,
7905 ++ .sync_flags = ext2_sync_flags,
7906 + };
7907 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/ialloc.c linux-2.6.22.19-vs2.2.0.7/fs/ext2/ialloc.c
7908 +--- linux-2.6.22.19/fs/ext2/ialloc.c 2006-11-30 21:19:19 +0100
7909 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext2/ialloc.c 2007-06-15 02:37:03 +0200
7910 +@@ -17,6 +17,8 @@
7911 + #include <linux/backing-dev.h>
7912 + #include <linux/buffer_head.h>
7913 + #include <linux/random.h>
7914 ++#include <linux/vs_dlimit.h>
7915 ++#include <linux/vs_tag.h>
7916 + #include "ext2.h"
7917 + #include "xattr.h"
7918 + #include "acl.h"
7919 +@@ -125,6 +127,7 @@ void ext2_free_inode (struct inode * ino
7920 + ext2_xattr_delete_inode(inode);
7921 + DQUOT_FREE_INODE(inode);
7922 + DQUOT_DROP(inode);
7923 ++ DLIMIT_FREE_INODE(inode);
7924 + }
7925 +
7926 + es = EXT2_SB(sb)->s_es;
7927 +@@ -464,6 +467,11 @@ struct inode *ext2_new_inode(struct inod
7928 + if (!inode)
7929 + return ERR_PTR(-ENOMEM);
7930 +
7931 ++ inode->i_tag = dx_current_fstag(sb);
7932 ++ if (DLIMIT_ALLOC_INODE(inode)) {
7933 ++ err = -ENOSPC;
7934 ++ goto fail_dlim;
7935 ++ }
7936 + ei = EXT2_I(inode);
7937 + sbi = EXT2_SB(sb);
7938 + es = sbi->s_es;
7939 +@@ -577,7 +585,8 @@ got:
7940 + inode->i_blocks = 0;
7941 + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
7942 + memset(ei->i_data, 0, sizeof(ei->i_data));
7943 +- ei->i_flags = EXT2_I(dir)->i_flags & ~EXT2_BTREE_FL;
7944 ++ ei->i_flags = EXT2_I(dir)->i_flags &
7945 ++ ~(EXT2_BTREE_FL|EXT2_IUNLINK_FL|EXT2_BARRIER_FL);
7946 + if (S_ISLNK(mode))
7947 + ei->i_flags &= ~(EXT2_IMMUTABLE_FL|EXT2_APPEND_FL);
7948 + /* dirsync is only applied to directories */
7949 +@@ -625,12 +634,15 @@ fail_free_drop:
7950 +
7951 + fail_drop:
7952 + DQUOT_DROP(inode);
7953 ++ DLIMIT_FREE_INODE(inode);
7954 + inode->i_flags |= S_NOQUOTA;
7955 + inode->i_nlink = 0;
7956 + iput(inode);
7957 + return ERR_PTR(err);
7958 +
7959 + fail:
7960 ++ DLIMIT_FREE_INODE(inode);
7961 ++fail_dlim:
7962 + make_bad_inode(inode);
7963 + iput(inode);
7964 + return ERR_PTR(err);
7965 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/inode.c linux-2.6.22.19-vs2.2.0.7/fs/ext2/inode.c
7966 +--- linux-2.6.22.19/fs/ext2/inode.c 2007-07-09 13:19:23 +0200
7967 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext2/inode.c 2007-06-15 02:57:56 +0200
7968 +@@ -31,6 +31,7 @@
7969 + #include <linux/writeback.h>
7970 + #include <linux/buffer_head.h>
7971 + #include <linux/mpage.h>
7972 ++#include <linux/vs_tag.h>
7973 + #include "ext2.h"
7974 + #include "acl.h"
7975 + #include "xip.h"
7976 +@@ -913,7 +914,7 @@ void ext2_truncate (struct inode * inode
7977 + return;
7978 + if (ext2_inode_is_fast_symlink(inode))
7979 + return;
7980 +- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
7981 ++ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
7982 + return;
7983 +
7984 + ext2_discard_prealloc(inode);
7985 +@@ -1042,13 +1043,20 @@ void ext2_set_inode_flags(struct inode *
7986 + {
7987 + unsigned int flags = EXT2_I(inode)->i_flags;
7988 +
7989 +- inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
7990 ++ inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
7991 ++ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
7992 ++
7993 ++ if (flags & EXT2_IMMUTABLE_FL)
7994 ++ inode->i_flags |= S_IMMUTABLE;
7995 ++ if (flags & EXT2_IUNLINK_FL)
7996 ++ inode->i_flags |= S_IUNLINK;
7997 ++ if (flags & EXT2_BARRIER_FL)
7998 ++ inode->i_flags |= S_BARRIER;
7999 ++
8000 + if (flags & EXT2_SYNC_FL)
8001 + inode->i_flags |= S_SYNC;
8002 + if (flags & EXT2_APPEND_FL)
8003 + inode->i_flags |= S_APPEND;
8004 +- if (flags & EXT2_IMMUTABLE_FL)
8005 +- inode->i_flags |= S_IMMUTABLE;
8006 + if (flags & EXT2_NOATIME_FL)
8007 + inode->i_flags |= S_NOATIME;
8008 + if (flags & EXT2_DIRSYNC_FL)
8009 +@@ -1074,12 +1082,37 @@ void ext2_get_inode_flags(struct ext2_in
8010 + ei->i_flags |= EXT2_DIRSYNC_FL;
8011 + }
8012 +
8013 ++int ext2_sync_flags(struct inode *inode)
8014 ++{
8015 ++ unsigned int oldflags, newflags;
8016 ++
8017 ++ oldflags = EXT2_I(inode)->i_flags;
8018 ++ newflags = oldflags & ~(EXT2_IMMUTABLE_FL |
8019 ++ EXT2_IUNLINK_FL | EXT2_BARRIER_FL);
8020 ++
8021 ++ if (IS_IMMUTABLE(inode))
8022 ++ newflags |= EXT2_IMMUTABLE_FL;
8023 ++ if (IS_IUNLINK(inode))
8024 ++ newflags |= EXT2_IUNLINK_FL;
8025 ++ if (IS_BARRIER(inode))
8026 ++ newflags |= EXT2_BARRIER_FL;
8027 ++
8028 ++ if (oldflags ^ newflags) {
8029 ++ EXT2_I(inode)->i_flags = newflags;
8030 ++ inode->i_ctime = CURRENT_TIME;
8031 ++ mark_inode_dirty(inode);
8032 ++ }
8033 ++ return 0;
8034 ++}
8035 ++
8036 + void ext2_read_inode (struct inode * inode)
8037 + {
8038 + struct ext2_inode_info *ei = EXT2_I(inode);
8039 + ino_t ino = inode->i_ino;
8040 + struct buffer_head * bh;
8041 + struct ext2_inode * raw_inode = ext2_get_inode(inode->i_sb, ino, &bh);
8042 ++ uid_t uid;
8043 ++ gid_t gid;
8044 + int n;
8045 +
8046 + #ifdef CONFIG_EXT2_FS_POSIX_ACL
8047 +@@ -1090,12 +1123,17 @@ void ext2_read_inode (struct inode * ino
8048 + goto bad_inode;
8049 +
8050 + inode->i_mode = le16_to_cpu(raw_inode->i_mode);
8051 +- inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
8052 +- inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
8053 ++ uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
8054 ++ gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
8055 + if (!(test_opt (inode->i_sb, NO_UID32))) {
8056 +- inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
8057 +- inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
8058 ++ uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
8059 ++ gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
8060 + }
8061 ++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
8062 ++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
8063 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
8064 ++ le16_to_cpu(raw_inode->i_raw_tag));
8065 ++
8066 + inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
8067 + inode->i_size = le32_to_cpu(raw_inode->i_size);
8068 + inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
8069 +@@ -1192,8 +1230,8 @@ static int ext2_update_inode(struct inod
8070 + struct ext2_inode_info *ei = EXT2_I(inode);
8071 + struct super_block *sb = inode->i_sb;
8072 + ino_t ino = inode->i_ino;
8073 +- uid_t uid = inode->i_uid;
8074 +- gid_t gid = inode->i_gid;
8075 ++ uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
8076 ++ gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
8077 + struct buffer_head * bh;
8078 + struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);
8079 + int n;
8080 +@@ -1229,6 +1267,9 @@ static int ext2_update_inode(struct inod
8081 + raw_inode->i_uid_high = 0;
8082 + raw_inode->i_gid_high = 0;
8083 + }
8084 ++#ifdef CONFIG_TAGGING_INTERN
8085 ++ raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag);
8086 ++#endif
8087 + raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
8088 + raw_inode->i_size = cpu_to_le32(inode->i_size);
8089 + raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
8090 +@@ -1315,7 +1356,8 @@ int ext2_setattr(struct dentry *dentry,
8091 + if (error)
8092 + return error;
8093 + if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
8094 +- (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
8095 ++ (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) ||
8096 ++ (iattr->ia_valid & ATTR_TAG && iattr->ia_tag != inode->i_tag)) {
8097 + error = DQUOT_TRANSFER(inode, iattr) ? -EDQUOT : 0;
8098 + if (error)
8099 + return error;
8100 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/ioctl.c linux-2.6.22.19-vs2.2.0.7/fs/ext2/ioctl.c
8101 +--- linux-2.6.22.19/fs/ext2/ioctl.c 2007-07-09 13:19:23 +0200
8102 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext2/ioctl.c 2007-06-15 02:37:03 +0200
8103 +@@ -13,6 +13,7 @@
8104 + #include <linux/sched.h>
8105 + #include <linux/compat.h>
8106 + #include <linux/smp_lock.h>
8107 ++#include <linux/mount.h>
8108 + #include <asm/current.h>
8109 + #include <asm/uaccess.h>
8110 +
8111 +@@ -33,7 +34,8 @@ int ext2_ioctl (struct inode * inode, st
8112 + case EXT2_IOC_SETFLAGS: {
8113 + unsigned int oldflags;
8114 +
8115 +- if (IS_RDONLY(inode))
8116 ++ if (IS_RDONLY(inode) ||
8117 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
8118 + return -EROFS;
8119 +
8120 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
8121 +@@ -54,7 +56,9 @@ int ext2_ioctl (struct inode * inode, st
8122 + *
8123 + * This test looks nicer. Thanks to Pauline Middelink
8124 + */
8125 +- if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
8126 ++ if ((oldflags & EXT2_IMMUTABLE_FL) ||
8127 ++ ((flags ^ oldflags) & (EXT2_APPEND_FL |
8128 ++ EXT2_IMMUTABLE_FL | EXT2_IUNLINK_FL))) {
8129 + if (!capable(CAP_LINUX_IMMUTABLE)) {
8130 + mutex_unlock(&inode->i_mutex);
8131 + return -EPERM;
8132 +@@ -76,7 +80,8 @@ int ext2_ioctl (struct inode * inode, st
8133 + case EXT2_IOC_SETVERSION:
8134 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
8135 + return -EPERM;
8136 +- if (IS_RDONLY(inode))
8137 ++ if (IS_RDONLY(inode) ||
8138 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
8139 + return -EROFS;
8140 + if (get_user(inode->i_generation, (int __user *) arg))
8141 + return -EFAULT;
8142 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/namei.c linux-2.6.22.19-vs2.2.0.7/fs/ext2/namei.c
8143 +--- linux-2.6.22.19/fs/ext2/namei.c 2007-05-02 19:25:17 +0200
8144 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext2/namei.c 2007-06-15 02:37:03 +0200
8145 +@@ -31,6 +31,7 @@
8146 + */
8147 +
8148 + #include <linux/pagemap.h>
8149 ++#include <linux/vs_tag.h>
8150 + #include "ext2.h"
8151 + #include "xattr.h"
8152 + #include "acl.h"
8153 +@@ -66,6 +67,7 @@ static struct dentry *ext2_lookup(struct
8154 + inode = iget(dir->i_sb, ino);
8155 + if (!inode)
8156 + return ERR_PTR(-EACCES);
8157 ++ dx_propagate_tag(nd, inode);
8158 + }
8159 + return d_splice_alias(inode, dentry);
8160 + }
8161 +@@ -391,6 +393,7 @@ const struct inode_operations ext2_dir_i
8162 + #endif
8163 + .setattr = ext2_setattr,
8164 + .permission = ext2_permission,
8165 ++ .sync_flags = ext2_sync_flags,
8166 + };
8167 +
8168 + const struct inode_operations ext2_special_inode_operations = {
8169 +@@ -402,4 +405,5 @@ const struct inode_operations ext2_speci
8170 + #endif
8171 + .setattr = ext2_setattr,
8172 + .permission = ext2_permission,
8173 ++ .sync_flags = ext2_sync_flags,
8174 + };
8175 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/super.c linux-2.6.22.19-vs2.2.0.7/fs/ext2/super.c
8176 +--- linux-2.6.22.19/fs/ext2/super.c 2007-07-09 13:19:23 +0200
8177 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext2/super.c 2007-07-07 03:52:53 +0200
8178 +@@ -321,7 +321,7 @@ enum {
8179 + Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
8180 + Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
8181 + Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota,
8182 +- Opt_usrquota, Opt_grpquota
8183 ++ Opt_usrquota, Opt_grpquota, Opt_tag, Opt_notag, Opt_tagid
8184 + };
8185 +
8186 + static match_table_t tokens = {
8187 +@@ -349,6 +349,10 @@ static match_table_t tokens = {
8188 + {Opt_acl, "acl"},
8189 + {Opt_noacl, "noacl"},
8190 + {Opt_xip, "xip"},
8191 ++ {Opt_tag, "tag"},
8192 ++ {Opt_notag, "notag"},
8193 ++ {Opt_tagid, "tagid=%u"},
8194 ++ {Opt_tag, "tagxid"},
8195 + {Opt_grpquota, "grpquota"},
8196 + {Opt_ignore, "noquota"},
8197 + {Opt_quota, "quota"},
8198 +@@ -417,6 +421,20 @@ static int parse_options (char * options
8199 + case Opt_nouid32:
8200 + set_opt (sbi->s_mount_opt, NO_UID32);
8201 + break;
8202 ++#ifndef CONFIG_TAGGING_NONE
8203 ++ case Opt_tag:
8204 ++ set_opt (sbi->s_mount_opt, TAGGED);
8205 ++ break;
8206 ++ case Opt_notag:
8207 ++ clear_opt (sbi->s_mount_opt, TAGGED);
8208 ++ break;
8209 ++#endif
8210 ++#ifdef CONFIG_PROPAGATE
8211 ++ case Opt_tagid:
8212 ++ /* use args[0] */
8213 ++ set_opt (sbi->s_mount_opt, TAGGED);
8214 ++ break;
8215 ++#endif
8216 + case Opt_nocheck:
8217 + clear_opt (sbi->s_mount_opt, CHECK);
8218 + break;
8219 +@@ -727,6 +745,8 @@ static int ext2_fill_super(struct super_
8220 + if (!parse_options ((char *) data, sbi))
8221 + goto failed_mount;
8222 +
8223 ++ if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAGGED)
8224 ++ sb->s_flags |= MS_TAGGED;
8225 + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
8226 + ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
8227 + MS_POSIXACL : 0);
8228 +@@ -1035,6 +1055,13 @@ static int ext2_remount (struct super_bl
8229 + goto restore_opts;
8230 + }
8231 +
8232 ++ if ((sbi->s_mount_opt & EXT2_MOUNT_TAGGED) &&
8233 ++ !(sb->s_flags & MS_TAGGED)) {
8234 ++ printk("EXT2-fs: %s: tagging not permitted on remount.\n",
8235 ++ sb->s_id);
8236 ++ return -EINVAL;
8237 ++ }
8238 ++
8239 + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
8240 + ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
8241 +
8242 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/symlink.c linux-2.6.22.19-vs2.2.0.7/fs/ext2/symlink.c
8243 +--- linux-2.6.22.19/fs/ext2/symlink.c 2007-05-02 19:25:17 +0200
8244 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext2/symlink.c 2007-06-15 02:37:03 +0200
8245 +@@ -38,6 +38,7 @@ const struct inode_operations ext2_symli
8246 + .listxattr = ext2_listxattr,
8247 + .removexattr = generic_removexattr,
8248 + #endif
8249 ++ .sync_flags = ext2_sync_flags,
8250 + };
8251 +
8252 + const struct inode_operations ext2_fast_symlink_inode_operations = {
8253 +@@ -49,4 +50,5 @@ const struct inode_operations ext2_fast_
8254 + .listxattr = ext2_listxattr,
8255 + .removexattr = generic_removexattr,
8256 + #endif
8257 ++ .sync_flags = ext2_sync_flags,
8258 + };
8259 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/xattr.c linux-2.6.22.19-vs2.2.0.7/fs/ext2/xattr.c
8260 +--- linux-2.6.22.19/fs/ext2/xattr.c 2007-02-06 03:01:18 +0100
8261 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext2/xattr.c 2007-06-15 02:37:03 +0200
8262 +@@ -60,6 +60,7 @@
8263 + #include <linux/mbcache.h>
8264 + #include <linux/quotaops.h>
8265 + #include <linux/rwsem.h>
8266 ++#include <linux/vs_dlimit.h>
8267 + #include "ext2.h"
8268 + #include "xattr.h"
8269 + #include "acl.h"
8270 +@@ -641,8 +642,12 @@ ext2_xattr_set2(struct inode *inode, str
8271 + the inode. */
8272 + ea_bdebug(new_bh, "reusing block");
8273 +
8274 ++ error = -ENOSPC;
8275 ++ if (DLIMIT_ALLOC_BLOCK(inode, 1))
8276 ++ goto cleanup;
8277 + error = -EDQUOT;
8278 + if (DQUOT_ALLOC_BLOCK(inode, 1)) {
8279 ++ DLIMIT_FREE_BLOCK(inode, 1);
8280 + unlock_buffer(new_bh);
8281 + goto cleanup;
8282 + }
8283 +@@ -736,6 +741,7 @@ ext2_xattr_set2(struct inode *inode, str
8284 + le32_to_cpu(HDR(old_bh)->h_refcount) - 1);
8285 + if (ce)
8286 + mb_cache_entry_release(ce);
8287 ++ DLIMIT_FREE_BLOCK(inode, 1);
8288 + DQUOT_FREE_BLOCK(inode, 1);
8289 + mark_buffer_dirty(old_bh);
8290 + ea_bdebug(old_bh, "refcount now=%d",
8291 +@@ -800,6 +806,7 @@ ext2_xattr_delete_inode(struct inode *in
8292 + mark_buffer_dirty(bh);
8293 + if (IS_SYNC(inode))
8294 + sync_dirty_buffer(bh);
8295 ++ DLIMIT_FREE_BLOCK(inode, 1);
8296 + DQUOT_FREE_BLOCK(inode, 1);
8297 + }
8298 + EXT2_I(inode)->i_file_acl = 0;
8299 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/balloc.c linux-2.6.22.19-vs2.2.0.7/fs/ext3/balloc.c
8300 +--- linux-2.6.22.19/fs/ext3/balloc.c 2007-05-02 19:25:17 +0200
8301 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext3/balloc.c 2007-07-16 06:31:34 +0200
8302 +@@ -19,6 +19,8 @@
8303 + #include <linux/ext3_jbd.h>
8304 + #include <linux/quotaops.h>
8305 + #include <linux/buffer_head.h>
8306 ++#include <linux/vs_dlimit.h>
8307 ++#include <linux/vs_tag.h>
8308 +
8309 + /*
8310 + * balloc.c contains the blocks allocation and deallocation routines
8311 +@@ -613,8 +615,10 @@ void ext3_free_blocks(handle_t *handle,
8312 + return;
8313 + }
8314 + ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks);
8315 +- if (dquot_freed_blocks)
8316 ++ if (dquot_freed_blocks) {
8317 ++ DLIMIT_FREE_BLOCK(inode, dquot_freed_blocks);
8318 + DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
8319 ++ }
8320 + return;
8321 + }
8322 +
8323 +@@ -1353,18 +1357,33 @@ out:
8324 + *
8325 + * Check if filesystem has at least 1 free block available for allocation.
8326 + */
8327 +-static int ext3_has_free_blocks(struct ext3_sb_info *sbi)
8328 ++static int ext3_has_free_blocks(struct super_block *sb)
8329 + {
8330 +- ext3_fsblk_t free_blocks, root_blocks;
8331 ++ struct ext3_sb_info *sbi = EXT3_SB(sb);
8332 ++ unsigned long long free_blocks, root_blocks;
8333 ++ int cond;
8334 +
8335 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
8336 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
8337 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
8338 ++
8339 ++ vxdprintk(VXD_CBIT(dlim, 3),
8340 ++ "ext3_has_free_blocks(%p): free=%llu, root=%llu",
8341 ++ sb, free_blocks, root_blocks);
8342 ++
8343 ++ DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
8344 ++
8345 ++ cond = (free_blocks < root_blocks + 1 &&
8346 ++ !capable(CAP_SYS_RESOURCE) &&
8347 + sbi->s_resuid != current->fsuid &&
8348 +- (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
8349 +- return 0;
8350 +- }
8351 +- return 1;
8352 ++ (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
8353 ++
8354 ++ vxdprintk(VXD_CBIT(dlim, 3),
8355 ++ "ext3_has_free_blocks(%p): %llu<%llu+1, %c, %u!=%u r=%d",
8356 ++ sb, free_blocks, root_blocks,
8357 ++ !capable(CAP_SYS_RESOURCE)?'1':'0',
8358 ++ sbi->s_resuid, current->fsuid, cond?0:1);
8359 ++
8360 ++ return (cond ? 0 : 1);
8361 + }
8362 +
8363 + /**
8364 +@@ -1381,7 +1400,7 @@ static int ext3_has_free_blocks(struct e
8365 + */
8366 + int ext3_should_retry_alloc(struct super_block *sb, int *retries)
8367 + {
8368 +- if (!ext3_has_free_blocks(EXT3_SB(sb)) || (*retries)++ > 3)
8369 ++ if (!ext3_has_free_blocks(sb) || (*retries)++ > 3)
8370 + return 0;
8371 +
8372 + jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
8373 +@@ -1444,6 +1463,8 @@ ext3_fsblk_t ext3_new_blocks(handle_t *h
8374 + *errp = -EDQUOT;
8375 + return 0;
8376 + }
8377 ++ if (DLIMIT_ALLOC_BLOCK(inode, num))
8378 ++ goto out_dlimit;
8379 +
8380 + sbi = EXT3_SB(sb);
8381 + es = EXT3_SB(sb)->s_es;
8382 +@@ -1460,7 +1481,7 @@ ext3_fsblk_t ext3_new_blocks(handle_t *h
8383 + if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0))
8384 + my_rsv = &block_i->rsv_window_node;
8385 +
8386 +- if (!ext3_has_free_blocks(sbi)) {
8387 ++ if (!ext3_has_free_blocks(sb)) {
8388 + *errp = -ENOSPC;
8389 + goto out;
8390 + }
8391 +@@ -1647,12 +1668,16 @@ allocated:
8392 + *errp = 0;
8393 + brelse(bitmap_bh);
8394 + DQUOT_FREE_BLOCK(inode, *count-num);
8395 ++ DLIMIT_FREE_BLOCK(inode, *count-num);
8396 + *count = num;
8397 + return ret_block;
8398 +
8399 + io_error:
8400 + *errp = -EIO;
8401 + out:
8402 ++ if (!performed_allocation)
8403 ++ DLIMIT_FREE_BLOCK(inode, *count);
8404 ++out_dlimit:
8405 + if (fatal) {
8406 + *errp = fatal;
8407 + ext3_std_error(sb, fatal);
8408 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/file.c linux-2.6.22.19-vs2.2.0.7/fs/ext3/file.c
8409 +--- linux-2.6.22.19/fs/ext3/file.c 2007-05-02 19:25:17 +0200
8410 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext3/file.c 2007-10-29 23:24:21 +0100
8411 +@@ -135,5 +135,6 @@ const struct inode_operations ext3_file_
8412 + .removexattr = generic_removexattr,
8413 + #endif
8414 + .permission = ext3_permission,
8415 ++ .sync_flags = ext3_sync_flags,
8416 + };
8417 +
8418 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/ialloc.c linux-2.6.22.19-vs2.2.0.7/fs/ext3/ialloc.c
8419 +--- linux-2.6.22.19/fs/ext3/ialloc.c 2006-11-30 21:19:19 +0100
8420 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext3/ialloc.c 2007-06-15 02:37:03 +0200
8421 +@@ -23,6 +23,8 @@
8422 + #include <linux/buffer_head.h>
8423 + #include <linux/random.h>
8424 + #include <linux/bitops.h>
8425 ++#include <linux/vs_dlimit.h>
8426 ++#include <linux/vs_tag.h>
8427 +
8428 + #include <asm/byteorder.h>
8429 +
8430 +@@ -127,6 +129,7 @@ void ext3_free_inode (handle_t *handle,
8431 + ext3_xattr_delete_inode(handle, inode);
8432 + DQUOT_FREE_INODE(inode);
8433 + DQUOT_DROP(inode);
8434 ++ DLIMIT_FREE_INODE(inode);
8435 +
8436 + is_directory = S_ISDIR(inode->i_mode);
8437 +
8438 +@@ -445,6 +448,12 @@ struct inode *ext3_new_inode(handle_t *h
8439 + inode = new_inode(sb);
8440 + if (!inode)
8441 + return ERR_PTR(-ENOMEM);
8442 ++
8443 ++ inode->i_tag = dx_current_fstag(sb);
8444 ++ if (DLIMIT_ALLOC_INODE(inode)) {
8445 ++ err = -ENOSPC;
8446 ++ goto out_dlimit;
8447 ++ }
8448 + ei = EXT3_I(inode);
8449 +
8450 + sbi = EXT3_SB(sb);
8451 +@@ -566,7 +575,8 @@ got:
8452 + ei->i_dir_start_lookup = 0;
8453 + ei->i_disksize = 0;
8454 +
8455 +- ei->i_flags = EXT3_I(dir)->i_flags & ~EXT3_INDEX_FL;
8456 ++ ei->i_flags = EXT3_I(dir)->i_flags &
8457 ++ ~(EXT3_INDEX_FL|EXT3_IUNLINK_FL|EXT3_BARRIER_FL);
8458 + if (S_ISLNK(mode))
8459 + ei->i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL);
8460 + /* dirsync only applies to directories */
8461 +@@ -621,6 +631,8 @@ got:
8462 + fail:
8463 + ext3_std_error(sb, err);
8464 + out:
8465 ++ DLIMIT_FREE_INODE(inode);
8466 ++out_dlimit:
8467 + iput(inode);
8468 + ret = ERR_PTR(err);
8469 + really_out:
8470 +@@ -632,6 +644,7 @@ fail_free_drop:
8471 +
8472 + fail_drop:
8473 + DQUOT_DROP(inode);
8474 ++ DLIMIT_FREE_INODE(inode);
8475 + inode->i_flags |= S_NOQUOTA;
8476 + inode->i_nlink = 0;
8477 + iput(inode);
8478 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/inode.c linux-2.6.22.19-vs2.2.0.7/fs/ext3/inode.c
8479 +--- linux-2.6.22.19/fs/ext3/inode.c 2007-07-09 13:19:23 +0200
8480 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext3/inode.c 2007-07-07 03:52:53 +0200
8481 +@@ -36,6 +36,7 @@
8482 + #include <linux/mpage.h>
8483 + #include <linux/uio.h>
8484 + #include <linux/bio.h>
8485 ++#include <linux/vs_tag.h>
8486 + #include "xattr.h"
8487 + #include "acl.h"
8488 +
8489 +@@ -2237,7 +2238,7 @@ void ext3_truncate(struct inode *inode)
8490 + return;
8491 + if (ext3_inode_is_fast_symlink(inode))
8492 + return;
8493 +- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
8494 ++ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
8495 + return;
8496 +
8497 + /*
8498 +@@ -2559,13 +2560,20 @@ void ext3_set_inode_flags(struct inode *
8499 + {
8500 + unsigned int flags = EXT3_I(inode)->i_flags;
8501 +
8502 +- inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
8503 ++ inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
8504 ++ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
8505 ++
8506 ++ if (flags & EXT3_IMMUTABLE_FL)
8507 ++ inode->i_flags |= S_IMMUTABLE;
8508 ++ if (flags & EXT3_IUNLINK_FL)
8509 ++ inode->i_flags |= S_IUNLINK;
8510 ++ if (flags & EXT3_BARRIER_FL)
8511 ++ inode->i_flags |= S_BARRIER;
8512 ++
8513 + if (flags & EXT3_SYNC_FL)
8514 + inode->i_flags |= S_SYNC;
8515 + if (flags & EXT3_APPEND_FL)
8516 + inode->i_flags |= S_APPEND;
8517 +- if (flags & EXT3_IMMUTABLE_FL)
8518 +- inode->i_flags |= S_IMMUTABLE;
8519 + if (flags & EXT3_NOATIME_FL)
8520 + inode->i_flags |= S_NOATIME;
8521 + if (flags & EXT3_DIRSYNC_FL)
8522 +@@ -2591,6 +2599,45 @@ void ext3_get_inode_flags(struct ext3_in
8523 + ei->i_flags |= EXT3_DIRSYNC_FL;
8524 + }
8525 +
8526 ++int ext3_sync_flags(struct inode *inode)
8527 ++{
8528 ++ unsigned int oldflags, newflags;
8529 ++ int err = 0;
8530 ++
8531 ++ oldflags = EXT3_I(inode)->i_flags;
8532 ++ newflags = oldflags & ~(EXT3_IMMUTABLE_FL |
8533 ++ EXT3_IUNLINK_FL | EXT3_BARRIER_FL);
8534 ++
8535 ++ if (IS_IMMUTABLE(inode))
8536 ++ newflags |= EXT3_IMMUTABLE_FL;
8537 ++ if (IS_IUNLINK(inode))
8538 ++ newflags |= EXT3_IUNLINK_FL;
8539 ++ if (IS_BARRIER(inode))
8540 ++ newflags |= EXT3_BARRIER_FL;
8541 ++
8542 ++ if (oldflags ^ newflags) {
8543 ++ handle_t *handle;
8544 ++ struct ext3_iloc iloc;
8545 ++
8546 ++ handle = ext3_journal_start(inode, 1);
8547 ++ if (IS_ERR(handle))
8548 ++ return PTR_ERR(handle);
8549 ++ if (IS_SYNC(inode))
8550 ++ handle->h_sync = 1;
8551 ++ err = ext3_reserve_inode_write(handle, inode, &iloc);
8552 ++ if (err)
8553 ++ goto flags_err;
8554 ++
8555 ++ EXT3_I(inode)->i_flags = newflags;
8556 ++ inode->i_ctime = CURRENT_TIME;
8557 ++
8558 ++ err = ext3_mark_iloc_dirty(handle, inode, &iloc);
8559 ++ flags_err:
8560 ++ ext3_journal_stop(handle);
8561 ++ }
8562 ++ return err;
8563 ++}
8564 ++
8565 + void ext3_read_inode(struct inode * inode)
8566 + {
8567 + struct ext3_iloc iloc;
8568 +@@ -2598,6 +2645,8 @@ void ext3_read_inode(struct inode * inod
8569 + struct ext3_inode_info *ei = EXT3_I(inode);
8570 + struct buffer_head *bh;
8571 + int block;
8572 ++ uid_t uid;
8573 ++ gid_t gid;
8574 +
8575 + #ifdef CONFIG_EXT3_FS_POSIX_ACL
8576 + ei->i_acl = EXT3_ACL_NOT_CACHED;
8577 +@@ -2610,12 +2659,17 @@ void ext3_read_inode(struct inode * inod
8578 + bh = iloc.bh;
8579 + raw_inode = ext3_raw_inode(&iloc);
8580 + inode->i_mode = le16_to_cpu(raw_inode->i_mode);
8581 +- inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
8582 +- inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
8583 ++ uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
8584 ++ gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
8585 + if(!(test_opt (inode->i_sb, NO_UID32))) {
8586 +- inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
8587 +- inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
8588 ++ uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
8589 ++ gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
8590 + }
8591 ++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
8592 ++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
8593 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
8594 ++ le16_to_cpu(raw_inode->i_raw_tag));
8595 ++
8596 + inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
8597 + inode->i_size = le32_to_cpu(raw_inode->i_size);
8598 + inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
8599 +@@ -2741,6 +2795,8 @@ static int ext3_do_update_inode(handle_t
8600 + struct ext3_inode *raw_inode = ext3_raw_inode(iloc);
8601 + struct ext3_inode_info *ei = EXT3_I(inode);
8602 + struct buffer_head *bh = iloc->bh;
8603 ++ uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
8604 ++ gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
8605 + int err = 0, rc, block;
8606 +
8607 + /* For fields not not tracking in the in-memory inode,
8608 +@@ -2751,29 +2807,32 @@ static int ext3_do_update_inode(handle_t
8609 + ext3_get_inode_flags(ei);
8610 + raw_inode->i_mode = cpu_to_le16(inode->i_mode);
8611 + if(!(test_opt(inode->i_sb, NO_UID32))) {
8612 +- raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
8613 +- raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid));
8614 ++ raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid));
8615 ++ raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid));
8616 + /*
8617 + * Fix up interoperability with old kernels. Otherwise, old inodes get
8618 + * re-used with the upper 16 bits of the uid/gid intact
8619 + */
8620 + if(!ei->i_dtime) {
8621 + raw_inode->i_uid_high =
8622 +- cpu_to_le16(high_16_bits(inode->i_uid));
8623 ++ cpu_to_le16(high_16_bits(uid));
8624 + raw_inode->i_gid_high =
8625 +- cpu_to_le16(high_16_bits(inode->i_gid));
8626 ++ cpu_to_le16(high_16_bits(gid));
8627 + } else {
8628 + raw_inode->i_uid_high = 0;
8629 + raw_inode->i_gid_high = 0;
8630 + }
8631 + } else {
8632 + raw_inode->i_uid_low =
8633 +- cpu_to_le16(fs_high2lowuid(inode->i_uid));
8634 ++ cpu_to_le16(fs_high2lowuid(uid));
8635 + raw_inode->i_gid_low =
8636 +- cpu_to_le16(fs_high2lowgid(inode->i_gid));
8637 ++ cpu_to_le16(fs_high2lowgid(gid));
8638 + raw_inode->i_uid_high = 0;
8639 + raw_inode->i_gid_high = 0;
8640 + }
8641 ++#ifdef CONFIG_TAGGING_INTERN
8642 ++ raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag);
8643 ++#endif
8644 + raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
8645 + raw_inode->i_size = cpu_to_le32(ei->i_disksize);
8646 + raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
8647 +@@ -2926,7 +2985,8 @@ int ext3_setattr(struct dentry *dentry,
8648 + return error;
8649 +
8650 + if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
8651 +- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
8652 ++ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
8653 ++ (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) {
8654 + handle_t *handle;
8655 +
8656 + /* (user+group)*(old+new) structure, inode write (sb,
8657 +@@ -2948,6 +3008,8 @@ int ext3_setattr(struct dentry *dentry,
8658 + inode->i_uid = attr->ia_uid;
8659 + if (attr->ia_valid & ATTR_GID)
8660 + inode->i_gid = attr->ia_gid;
8661 ++ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
8662 ++ inode->i_tag = attr->ia_tag;
8663 + error = ext3_mark_inode_dirty(handle, inode);
8664 + ext3_journal_stop(handle);
8665 + }
8666 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/ioctl.c linux-2.6.22.19-vs2.2.0.7/fs/ext3/ioctl.c
8667 +--- linux-2.6.22.19/fs/ext3/ioctl.c 2007-07-09 13:19:23 +0200
8668 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext3/ioctl.c 2007-06-15 02:37:03 +0200
8669 +@@ -8,6 +8,7 @@
8670 + */
8671 +
8672 + #include <linux/fs.h>
8673 ++#include <linux/mount.h>
8674 + #include <linux/jbd.h>
8675 + #include <linux/capability.h>
8676 + #include <linux/ext3_fs.h>
8677 +@@ -15,6 +16,7 @@
8678 + #include <linux/time.h>
8679 + #include <linux/compat.h>
8680 + #include <linux/smp_lock.h>
8681 ++#include <linux/vs_tag.h>
8682 + #include <asm/uaccess.h>
8683 +
8684 + int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
8685 +@@ -38,7 +40,8 @@ int ext3_ioctl (struct inode * inode, st
8686 + unsigned int oldflags;
8687 + unsigned int jflag;
8688 +
8689 +- if (IS_RDONLY(inode))
8690 ++ if (IS_RDONLY(inode) ||
8691 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
8692 + return -EROFS;
8693 +
8694 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
8695 +@@ -62,7 +65,9 @@ int ext3_ioctl (struct inode * inode, st
8696 + *
8697 + * This test looks nicer. Thanks to Pauline Middelink
8698 + */
8699 +- if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
8700 ++ if ((oldflags & EXT3_IMMUTABLE_FL) ||
8701 ++ ((flags ^ oldflags) & (EXT3_APPEND_FL |
8702 ++ EXT3_IMMUTABLE_FL | EXT3_IUNLINK_FL))) {
8703 + if (!capable(CAP_LINUX_IMMUTABLE)) {
8704 + mutex_unlock(&inode->i_mutex);
8705 + return -EPERM;
8706 +@@ -124,7 +129,8 @@ flags_err:
8707 +
8708 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
8709 + return -EPERM;
8710 +- if (IS_RDONLY(inode))
8711 ++ if (IS_RDONLY(inode) ||
8712 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
8713 + return -EROFS;
8714 + if (get_user(generation, (int __user *) arg))
8715 + return -EFAULT;
8716 +@@ -178,7 +184,8 @@ flags_err:
8717 + if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
8718 + return -ENOTTY;
8719 +
8720 +- if (IS_RDONLY(inode))
8721 ++ if (IS_RDONLY(inode) ||
8722 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
8723 + return -EROFS;
8724 +
8725 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
8726 +@@ -213,7 +220,8 @@ flags_err:
8727 + if (!capable(CAP_SYS_RESOURCE))
8728 + return -EPERM;
8729 +
8730 +- if (IS_RDONLY(inode))
8731 ++ if (IS_RDONLY(inode) ||
8732 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
8733 + return -EROFS;
8734 +
8735 + if (get_user(n_blocks_count, (__u32 __user *)arg))
8736 +@@ -234,7 +242,8 @@ flags_err:
8737 + if (!capable(CAP_SYS_RESOURCE))
8738 + return -EPERM;
8739 +
8740 +- if (IS_RDONLY(inode))
8741 ++ if (IS_RDONLY(inode) ||
8742 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
8743 + return -EROFS;
8744 +
8745 + if (copy_from_user(&input, (struct ext3_new_group_input __user *)arg,
8746 +@@ -249,6 +258,38 @@ flags_err:
8747 + return err;
8748 + }
8749 +
8750 ++#if defined(CONFIG_VSERVER_LEGACY) && !defined(CONFIG_TAGGING_NONE)
8751 ++ case EXT3_IOC_SETTAG: {
8752 ++ handle_t *handle;
8753 ++ struct ext3_iloc iloc;
8754 ++ int tag;
8755 ++ int err;
8756 ++
8757 ++ /* fixme: if stealth, return -ENOTTY */
8758 ++ if (!capable(CAP_CONTEXT))
8759 ++ return -EPERM;
8760 ++ if (IS_RDONLY(inode))
8761 ++ return -EROFS;
8762 ++ if (!(inode->i_sb->s_flags & MS_TAGGED))
8763 ++ return -ENOSYS;
8764 ++ if (get_user(tag, (int __user *) arg))
8765 ++ return -EFAULT;
8766 ++
8767 ++ handle = ext3_journal_start(inode, 1);
8768 ++ if (IS_ERR(handle))
8769 ++ return PTR_ERR(handle);
8770 ++ err = ext3_reserve_inode_write(handle, inode, &iloc);
8771 ++ if (err)
8772 ++ return err;
8773 ++
8774 ++ inode->i_tag = (tag & 0xFFFF);
8775 ++ inode->i_ctime = CURRENT_TIME;
8776 ++
8777 ++ err = ext3_mark_iloc_dirty(handle, inode, &iloc);
8778 ++ ext3_journal_stop(handle);
8779 ++ return err;
8780 ++ }
8781 ++#endif
8782 +
8783 + default:
8784 + return -ENOTTY;
8785 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/namei.c linux-2.6.22.19-vs2.2.0.7/fs/ext3/namei.c
8786 +--- linux-2.6.22.19/fs/ext3/namei.c 2008-03-14 20:19:03 +0100
8787 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext3/namei.c 2007-10-01 15:25:35 +0200
8788 +@@ -36,6 +36,7 @@
8789 + #include <linux/quotaops.h>
8790 + #include <linux/buffer_head.h>
8791 + #include <linux/bio.h>
8792 ++#include <linux/vs_tag.h>
8793 +
8794 + #include "namei.h"
8795 + #include "xattr.h"
8796 +@@ -1052,6 +1053,7 @@ static struct dentry *ext3_lookup(struct
8797 +
8798 + if (!inode)
8799 + return ERR_PTR(-EACCES);
8800 ++ dx_propagate_tag(nd, inode);
8801 + }
8802 + return d_splice_alias(inode, dentry);
8803 + }
8804 +@@ -2443,6 +2445,7 @@ const struct inode_operations ext3_dir_i
8805 + .removexattr = generic_removexattr,
8806 + #endif
8807 + .permission = ext3_permission,
8808 ++ .sync_flags = ext3_sync_flags,
8809 + };
8810 +
8811 + const struct inode_operations ext3_special_inode_operations = {
8812 +@@ -2454,4 +2457,5 @@ const struct inode_operations ext3_speci
8813 + .removexattr = generic_removexattr,
8814 + #endif
8815 + .permission = ext3_permission,
8816 ++ .sync_flags = ext3_sync_flags,
8817 + };
8818 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/super.c linux-2.6.22.19-vs2.2.0.7/fs/ext3/super.c
8819 +--- linux-2.6.22.19/fs/ext3/super.c 2007-07-09 13:19:23 +0200
8820 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext3/super.c 2007-06-15 02:37:03 +0200
8821 +@@ -674,7 +674,7 @@ enum {
8822 + Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
8823 + Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
8824 + Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
8825 +- Opt_grpquota
8826 ++ Opt_grpquota, Opt_tag, Opt_notag, Opt_tagid
8827 + };
8828 +
8829 + static match_table_t tokens = {
8830 +@@ -724,6 +724,10 @@ static match_table_t tokens = {
8831 + {Opt_quota, "quota"},
8832 + {Opt_usrquota, "usrquota"},
8833 + {Opt_barrier, "barrier=%u"},
8834 ++ {Opt_tag, "tag"},
8835 ++ {Opt_notag, "notag"},
8836 ++ {Opt_tagid, "tagid=%u"},
8837 ++ {Opt_tag, "tagxid"},
8838 + {Opt_err, NULL},
8839 + {Opt_resize, "resize"},
8840 + };
8841 +@@ -817,6 +821,20 @@ static int parse_options (char *options,
8842 + case Opt_nouid32:
8843 + set_opt (sbi->s_mount_opt, NO_UID32);
8844 + break;
8845 ++#ifndef CONFIG_TAGGING_NONE
8846 ++ case Opt_tag:
8847 ++ set_opt (sbi->s_mount_opt, TAGGED);
8848 ++ break;
8849 ++ case Opt_notag:
8850 ++ clear_opt (sbi->s_mount_opt, TAGGED);
8851 ++ break;
8852 ++#endif
8853 ++#ifdef CONFIG_PROPAGATE
8854 ++ case Opt_tagid:
8855 ++ /* use args[0] */
8856 ++ set_opt (sbi->s_mount_opt, TAGGED);
8857 ++ break;
8858 ++#endif
8859 + case Opt_nocheck:
8860 + clear_opt (sbi->s_mount_opt, CHECK);
8861 + break;
8862 +@@ -1487,6 +1505,9 @@ static int ext3_fill_super (struct super
8863 + NULL, 0))
8864 + goto failed_mount;
8865 +
8866 ++ if (EXT3_SB(sb)->s_mount_opt & EXT3_MOUNT_TAGGED)
8867 ++ sb->s_flags |= MS_TAGGED;
8868 ++
8869 + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
8870 + ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
8871 +
8872 +@@ -2302,6 +2323,12 @@ static int ext3_remount (struct super_bl
8873 +
8874 + if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
8875 + ext3_abort(sb, __FUNCTION__, "Abort forced by user");
8876 ++ if ((sbi->s_mount_opt & EXT3_MOUNT_TAGGED) &&
8877 ++ !(sb->s_flags & MS_TAGGED)) {
8878 ++ printk("EXT3-fs: %s: tagging not permitted on remount.\n",
8879 ++ sb->s_id);
8880 ++ return -EINVAL;
8881 ++ }
8882 +
8883 + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
8884 + ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
8885 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/symlink.c linux-2.6.22.19-vs2.2.0.7/fs/ext3/symlink.c
8886 +--- linux-2.6.22.19/fs/ext3/symlink.c 2007-05-02 19:25:17 +0200
8887 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext3/symlink.c 2007-06-15 02:37:03 +0200
8888 +@@ -40,6 +40,7 @@ const struct inode_operations ext3_symli
8889 + .listxattr = ext3_listxattr,
8890 + .removexattr = generic_removexattr,
8891 + #endif
8892 ++ .sync_flags = ext3_sync_flags,
8893 + };
8894 +
8895 + const struct inode_operations ext3_fast_symlink_inode_operations = {
8896 +@@ -51,4 +52,5 @@ const struct inode_operations ext3_fast_
8897 + .listxattr = ext3_listxattr,
8898 + .removexattr = generic_removexattr,
8899 + #endif
8900 ++ .sync_flags = ext3_sync_flags,
8901 + };
8902 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/xattr.c linux-2.6.22.19-vs2.2.0.7/fs/ext3/xattr.c
8903 +--- linux-2.6.22.19/fs/ext3/xattr.c 2007-05-02 19:25:17 +0200
8904 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext3/xattr.c 2007-06-15 02:37:03 +0200
8905 +@@ -58,6 +58,7 @@
8906 + #include <linux/mbcache.h>
8907 + #include <linux/quotaops.h>
8908 + #include <linux/rwsem.h>
8909 ++#include <linux/vs_dlimit.h>
8910 + #include "xattr.h"
8911 + #include "acl.h"
8912 +
8913 +@@ -497,6 +498,7 @@ ext3_xattr_release_block(handle_t *handl
8914 + error = ext3_journal_dirty_metadata(handle, bh);
8915 + if (IS_SYNC(inode))
8916 + handle->h_sync = 1;
8917 ++ DLIMIT_FREE_BLOCK(inode, 1);
8918 + DQUOT_FREE_BLOCK(inode, 1);
8919 + ea_bdebug(bh, "refcount now=%d; releasing",
8920 + le32_to_cpu(BHDR(bh)->h_refcount));
8921 +@@ -771,11 +773,14 @@ inserted:
8922 + if (new_bh == bs->bh)
8923 + ea_bdebug(new_bh, "keeping");
8924 + else {
8925 ++ error = -ENOSPC;
8926 ++ if (DLIMIT_ALLOC_BLOCK(inode, 1))
8927 ++ goto cleanup;
8928 + /* The old block is released after updating
8929 + the inode. */
8930 + error = -EDQUOT;
8931 + if (DQUOT_ALLOC_BLOCK(inode, 1))
8932 +- goto cleanup;
8933 ++ goto cleanup_dlimit;
8934 + error = ext3_journal_get_write_access(handle,
8935 + new_bh);
8936 + if (error)
8937 +@@ -852,6 +857,8 @@ cleanup:
8938 +
8939 + cleanup_dquot:
8940 + DQUOT_FREE_BLOCK(inode, 1);
8941 ++cleanup_dlimit:
8942 ++ DLIMIT_FREE_BLOCK(inode, 1);
8943 + goto cleanup;
8944 +
8945 + bad_block:
8946 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/balloc.c linux-2.6.22.19-vs2.2.0.7/fs/ext4/balloc.c
8947 +--- linux-2.6.22.19/fs/ext4/balloc.c 2007-07-09 13:19:23 +0200
8948 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext4/balloc.c 2007-07-16 06:31:34 +0200
8949 +@@ -19,6 +19,8 @@
8950 + #include <linux/ext4_jbd2.h>
8951 + #include <linux/quotaops.h>
8952 + #include <linux/buffer_head.h>
8953 ++#include <linux/vs_dlimit.h>
8954 ++#include <linux/vs_tag.h>
8955 +
8956 + /*
8957 + * balloc.c contains the blocks allocation and deallocation routines
8958 +@@ -630,8 +632,10 @@ void ext4_free_blocks(handle_t *handle,
8959 + return;
8960 + }
8961 + ext4_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks);
8962 +- if (dquot_freed_blocks)
8963 ++ if (dquot_freed_blocks) {
8964 ++ DLIMIT_FREE_BLOCK(inode, dquot_freed_blocks);
8965 + DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
8966 ++ }
8967 + return;
8968 + }
8969 +
8970 +@@ -1370,18 +1374,33 @@ out:
8971 + *
8972 + * Check if filesystem has at least 1 free block available for allocation.
8973 + */
8974 +-static int ext4_has_free_blocks(struct ext4_sb_info *sbi)
8975 ++static int ext4_has_free_blocks(struct super_block *sb)
8976 + {
8977 ++ struct ext4_sb_info *sbi = EXT4_SB(sb);
8978 + ext4_fsblk_t free_blocks, root_blocks;
8979 ++ int cond;
8980 +
8981 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
8982 + root_blocks = ext4_r_blocks_count(sbi->s_es);
8983 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
8984 ++
8985 ++ vxdprintk(VXD_CBIT(dlim, 3),
8986 ++ "ext4_has_free_blocks(%p): free=%llu, root=%llu",
8987 ++ sb, free_blocks, root_blocks);
8988 ++
8989 ++ DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
8990 ++
8991 ++ cond = (free_blocks < root_blocks + 1 &&
8992 ++ !capable(CAP_SYS_RESOURCE) &&
8993 + sbi->s_resuid != current->fsuid &&
8994 +- (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
8995 +- return 0;
8996 +- }
8997 +- return 1;
8998 ++ (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
8999 ++
9000 ++ vxdprintk(VXD_CBIT(dlim, 3),
9001 ++ "ext4_has_free_blocks(%p): %llu<%llu+1, %c, %u!=%u r=%d",
9002 ++ sb, free_blocks, root_blocks,
9003 ++ !capable(CAP_SYS_RESOURCE)?'1':'0',
9004 ++ sbi->s_resuid, current->fsuid, cond?0:1);
9005 ++
9006 ++ return (cond ? 0 : 1);
9007 + }
9008 +
9009 + /**
9010 +@@ -1398,7 +1417,7 @@ static int ext4_has_free_blocks(struct e
9011 + */
9012 + int ext4_should_retry_alloc(struct super_block *sb, int *retries)
9013 + {
9014 +- if (!ext4_has_free_blocks(EXT4_SB(sb)) || (*retries)++ > 3)
9015 ++ if (!ext4_has_free_blocks(sb) || (*retries)++ > 3)
9016 + return 0;
9017 +
9018 + jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
9019 +@@ -1461,6 +1480,8 @@ ext4_fsblk_t ext4_new_blocks(handle_t *h
9020 + *errp = -EDQUOT;
9021 + return 0;
9022 + }
9023 ++ if (DLIMIT_ALLOC_BLOCK(inode, num))
9024 ++ goto out_dlimit;
9025 +
9026 + sbi = EXT4_SB(sb);
9027 + es = EXT4_SB(sb)->s_es;
9028 +@@ -1477,7 +1498,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *h
9029 + if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0))
9030 + my_rsv = &block_i->rsv_window_node;
9031 +
9032 +- if (!ext4_has_free_blocks(sbi)) {
9033 ++ if (!ext4_has_free_blocks(sb)) {
9034 + *errp = -ENOSPC;
9035 + goto out;
9036 + }
9037 +@@ -1661,12 +1682,16 @@ allocated:
9038 + *errp = 0;
9039 + brelse(bitmap_bh);
9040 + DQUOT_FREE_BLOCK(inode, *count-num);
9041 ++ DLIMIT_FREE_BLOCK(inode, *count-num);
9042 + *count = num;
9043 + return ret_block;
9044 +
9045 + io_error:
9046 + *errp = -EIO;
9047 + out:
9048 ++ if (!performed_allocation)
9049 ++ DLIMIT_FREE_BLOCK(inode, *count);
9050 ++out_dlimit:
9051 + if (fatal) {
9052 + *errp = fatal;
9053 + ext4_std_error(sb, fatal);
9054 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/file.c linux-2.6.22.19-vs2.2.0.7/fs/ext4/file.c
9055 +--- linux-2.6.22.19/fs/ext4/file.c 2007-05-02 19:25:17 +0200
9056 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext4/file.c 2007-10-29 23:24:21 +0100
9057 +@@ -135,5 +135,6 @@ const struct inode_operations ext4_file_
9058 + .removexattr = generic_removexattr,
9059 + #endif
9060 + .permission = ext4_permission,
9061 ++ .sync_flags = ext4_sync_flags,
9062 + };
9063 +
9064 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/ialloc.c linux-2.6.22.19-vs2.2.0.7/fs/ext4/ialloc.c
9065 +--- linux-2.6.22.19/fs/ext4/ialloc.c 2006-11-30 21:19:20 +0100
9066 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext4/ialloc.c 2007-06-15 02:37:03 +0200
9067 +@@ -24,6 +24,8 @@
9068 + #include <linux/random.h>
9069 + #include <linux/bitops.h>
9070 + #include <linux/blkdev.h>
9071 ++#include <linux/vs_dlimit.h>
9072 ++#include <linux/vs_tag.h>
9073 + #include <asm/byteorder.h>
9074 +
9075 + #include "xattr.h"
9076 +@@ -127,6 +129,7 @@ void ext4_free_inode (handle_t *handle,
9077 + ext4_xattr_delete_inode(handle, inode);
9078 + DQUOT_FREE_INODE(inode);
9079 + DQUOT_DROP(inode);
9080 ++ DLIMIT_FREE_INODE(inode);
9081 +
9082 + is_directory = S_ISDIR(inode->i_mode);
9083 +
9084 +@@ -448,6 +451,12 @@ struct inode *ext4_new_inode(handle_t *h
9085 + inode = new_inode(sb);
9086 + if (!inode)
9087 + return ERR_PTR(-ENOMEM);
9088 ++
9089 ++ inode->i_tag = dx_current_fstag(sb);
9090 ++ if (DLIMIT_ALLOC_INODE(inode)) {
9091 ++ err = -ENOSPC;
9092 ++ goto out_dlimit;
9093 ++ }
9094 + ei = EXT4_I(inode);
9095 +
9096 + sbi = EXT4_SB(sb);
9097 +@@ -569,7 +578,8 @@ got:
9098 + ei->i_dir_start_lookup = 0;
9099 + ei->i_disksize = 0;
9100 +
9101 +- ei->i_flags = EXT4_I(dir)->i_flags & ~EXT4_INDEX_FL;
9102 ++ ei->i_flags = EXT4_I(dir)->i_flags &
9103 ++ ~(EXT4_INDEX_FL|EXT4_IUNLINK_FL|EXT4_BARRIER_FL);
9104 + if (S_ISLNK(mode))
9105 + ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL);
9106 + /* dirsync only applies to directories */
9107 +@@ -635,6 +645,8 @@ got:
9108 + fail:
9109 + ext4_std_error(sb, err);
9110 + out:
9111 ++ DLIMIT_FREE_INODE(inode);
9112 ++out_dlimit:
9113 + iput(inode);
9114 + ret = ERR_PTR(err);
9115 + really_out:
9116 +@@ -646,6 +658,7 @@ fail_free_drop:
9117 +
9118 + fail_drop:
9119 + DQUOT_DROP(inode);
9120 ++ DLIMIT_FREE_INODE(inode);
9121 + inode->i_flags |= S_NOQUOTA;
9122 + inode->i_nlink = 0;
9123 + iput(inode);
9124 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/inode.c linux-2.6.22.19-vs2.2.0.7/fs/ext4/inode.c
9125 +--- linux-2.6.22.19/fs/ext4/inode.c 2007-07-09 13:19:23 +0200
9126 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext4/inode.c 2007-07-07 03:52:53 +0200
9127 +@@ -36,6 +36,7 @@
9128 + #include <linux/mpage.h>
9129 + #include <linux/uio.h>
9130 + #include <linux/bio.h>
9131 ++#include <linux/vs_tag.h>
9132 + #include "xattr.h"
9133 + #include "acl.h"
9134 +
9135 +@@ -2244,7 +2245,7 @@ void ext4_truncate(struct inode *inode)
9136 + return;
9137 + if (ext4_inode_is_fast_symlink(inode))
9138 + return;
9139 +- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
9140 ++ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
9141 + return;
9142 +
9143 + /*
9144 +@@ -2570,19 +2571,65 @@ void ext4_set_inode_flags(struct inode *
9145 + {
9146 + unsigned int flags = EXT4_I(inode)->i_flags;
9147 +
9148 +- inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
9149 ++ inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
9150 ++ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
9151 ++
9152 ++ if (flags & EXT4_IMMUTABLE_FL)
9153 ++ inode->i_flags |= S_IMMUTABLE;
9154 ++ if (flags & EXT4_IUNLINK_FL)
9155 ++ inode->i_flags |= S_IUNLINK;
9156 ++ if (flags & EXT4_BARRIER_FL)
9157 ++ inode->i_flags |= S_BARRIER;
9158 ++
9159 + if (flags & EXT4_SYNC_FL)
9160 + inode->i_flags |= S_SYNC;
9161 + if (flags & EXT4_APPEND_FL)
9162 + inode->i_flags |= S_APPEND;
9163 +- if (flags & EXT4_IMMUTABLE_FL)
9164 +- inode->i_flags |= S_IMMUTABLE;
9165 + if (flags & EXT4_NOATIME_FL)
9166 + inode->i_flags |= S_NOATIME;
9167 + if (flags & EXT4_DIRSYNC_FL)
9168 + inode->i_flags |= S_DIRSYNC;
9169 + }
9170 +
9171 ++int ext4_sync_flags(struct inode *inode)
9172 ++{
9173 ++ unsigned int oldflags, newflags;
9174 ++ int err = 0;
9175 ++
9176 ++ oldflags = EXT4_I(inode)->i_flags;
9177 ++ newflags = oldflags & ~(EXT4_IMMUTABLE_FL |
9178 ++ EXT4_IUNLINK_FL | EXT4_BARRIER_FL);
9179 ++
9180 ++ if (IS_IMMUTABLE(inode))
9181 ++ newflags |= EXT4_IMMUTABLE_FL;
9182 ++ if (IS_IUNLINK(inode))
9183 ++ newflags |= EXT4_IUNLINK_FL;
9184 ++ if (IS_BARRIER(inode))
9185 ++ newflags |= EXT4_BARRIER_FL;
9186 ++
9187 ++ if (oldflags ^ newflags) {
9188 ++ handle_t *handle;
9189 ++ struct ext4_iloc iloc;
9190 ++
9191 ++ handle = ext4_journal_start(inode, 1);
9192 ++ if (IS_ERR(handle))
9193 ++ return PTR_ERR(handle);
9194 ++ if (IS_SYNC(inode))
9195 ++ handle->h_sync = 1;
9196 ++ err = ext4_reserve_inode_write(handle, inode, &iloc);
9197 ++ if (err)
9198 ++ goto flags_err;
9199 ++
9200 ++ EXT4_I(inode)->i_flags = newflags;
9201 ++ inode->i_ctime = CURRENT_TIME;
9202 ++
9203 ++ err = ext4_mark_iloc_dirty(handle, inode, &iloc);
9204 ++ flags_err:
9205 ++ ext4_journal_stop(handle);
9206 ++ }
9207 ++ return err;
9208 ++}
9209 ++
9210 + void ext4_read_inode(struct inode * inode)
9211 + {
9212 + struct ext4_iloc iloc;
9213 +@@ -2590,6 +2637,8 @@ void ext4_read_inode(struct inode * inod
9214 + struct ext4_inode_info *ei = EXT4_I(inode);
9215 + struct buffer_head *bh;
9216 + int block;
9217 ++ uid_t uid;
9218 ++ gid_t gid;
9219 +
9220 + #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
9221 + ei->i_acl = EXT4_ACL_NOT_CACHED;
9222 +@@ -2602,12 +2651,17 @@ void ext4_read_inode(struct inode * inod
9223 + bh = iloc.bh;
9224 + raw_inode = ext4_raw_inode(&iloc);
9225 + inode->i_mode = le16_to_cpu(raw_inode->i_mode);
9226 +- inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
9227 +- inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
9228 ++ uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
9229 ++ gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
9230 + if(!(test_opt (inode->i_sb, NO_UID32))) {
9231 +- inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
9232 +- inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
9233 ++ uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
9234 ++ gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
9235 + }
9236 ++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
9237 ++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
9238 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
9239 ++ le16_to_cpu(raw_inode->i_raw_tag));
9240 ++
9241 + inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
9242 + inode->i_size = le32_to_cpu(raw_inode->i_size);
9243 + inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
9244 +@@ -2737,6 +2791,8 @@ static int ext4_do_update_inode(handle_t
9245 + struct ext4_inode *raw_inode = ext4_raw_inode(iloc);
9246 + struct ext4_inode_info *ei = EXT4_I(inode);
9247 + struct buffer_head *bh = iloc->bh;
9248 ++ uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
9249 ++ gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
9250 + int err = 0, rc, block;
9251 +
9252 + /* For fields not not tracking in the in-memory inode,
9253 +@@ -2746,29 +2802,32 @@ static int ext4_do_update_inode(handle_t
9254 +
9255 + raw_inode->i_mode = cpu_to_le16(inode->i_mode);
9256 + if(!(test_opt(inode->i_sb, NO_UID32))) {
9257 +- raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
9258 +- raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid));
9259 ++ raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid));
9260 ++ raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid));
9261 + /*
9262 + * Fix up interoperability with old kernels. Otherwise, old inodes get
9263 + * re-used with the upper 16 bits of the uid/gid intact
9264 + */
9265 + if(!ei->i_dtime) {
9266 + raw_inode->i_uid_high =
9267 +- cpu_to_le16(high_16_bits(inode->i_uid));
9268 ++ cpu_to_le16(high_16_bits(uid));
9269 + raw_inode->i_gid_high =
9270 +- cpu_to_le16(high_16_bits(inode->i_gid));
9271 ++ cpu_to_le16(high_16_bits(gid));
9272 + } else {
9273 + raw_inode->i_uid_high = 0;
9274 + raw_inode->i_gid_high = 0;
9275 + }
9276 + } else {
9277 + raw_inode->i_uid_low =
9278 +- cpu_to_le16(fs_high2lowuid(inode->i_uid));
9279 ++ cpu_to_le16(fs_high2lowuid(uid));
9280 + raw_inode->i_gid_low =
9281 +- cpu_to_le16(fs_high2lowgid(inode->i_gid));
9282 ++ cpu_to_le16(fs_high2lowgid(gid));
9283 + raw_inode->i_uid_high = 0;
9284 + raw_inode->i_gid_high = 0;
9285 + }
9286 ++#ifdef CONFIG_TAGGING_INTERN
9287 ++ raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag);
9288 ++#endif
9289 + raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
9290 + raw_inode->i_size = cpu_to_le32(ei->i_disksize);
9291 + raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
9292 +@@ -2925,7 +2984,8 @@ int ext4_setattr(struct dentry *dentry,
9293 + return error;
9294 +
9295 + if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
9296 +- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
9297 ++ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
9298 ++ (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) {
9299 + handle_t *handle;
9300 +
9301 + /* (user+group)*(old+new) structure, inode write (sb,
9302 +@@ -2947,6 +3007,8 @@ int ext4_setattr(struct dentry *dentry,
9303 + inode->i_uid = attr->ia_uid;
9304 + if (attr->ia_valid & ATTR_GID)
9305 + inode->i_gid = attr->ia_gid;
9306 ++ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
9307 ++ inode->i_tag = attr->ia_tag;
9308 + error = ext4_mark_inode_dirty(handle, inode);
9309 + ext4_journal_stop(handle);
9310 + }
9311 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/ioctl.c linux-2.6.22.19-vs2.2.0.7/fs/ext4/ioctl.c
9312 +--- linux-2.6.22.19/fs/ext4/ioctl.c 2007-02-06 03:01:18 +0100
9313 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext4/ioctl.c 2007-06-15 02:37:03 +0200
9314 +@@ -8,6 +8,7 @@
9315 + */
9316 +
9317 + #include <linux/fs.h>
9318 ++#include <linux/mount.h>
9319 + #include <linux/jbd2.h>
9320 + #include <linux/capability.h>
9321 + #include <linux/ext4_fs.h>
9322 +@@ -15,6 +16,7 @@
9323 + #include <linux/time.h>
9324 + #include <linux/compat.h>
9325 + #include <linux/smp_lock.h>
9326 ++#include <linux/vs_tag.h>
9327 + #include <asm/uaccess.h>
9328 +
9329 + int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
9330 +@@ -37,7 +39,8 @@ int ext4_ioctl (struct inode * inode, st
9331 + unsigned int oldflags;
9332 + unsigned int jflag;
9333 +
9334 +- if (IS_RDONLY(inode))
9335 ++ if (IS_RDONLY(inode) ||
9336 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
9337 + return -EROFS;
9338 +
9339 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
9340 +@@ -61,7 +64,9 @@ int ext4_ioctl (struct inode * inode, st
9341 + *
9342 + * This test looks nicer. Thanks to Pauline Middelink
9343 + */
9344 +- if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
9345 ++ if ((oldflags & EXT4_IMMUTABLE_FL) ||
9346 ++ ((flags ^ oldflags) & (EXT4_APPEND_FL |
9347 ++ EXT4_IMMUTABLE_FL | EXT4_IUNLINK_FL))) {
9348 + if (!capable(CAP_LINUX_IMMUTABLE)) {
9349 + mutex_unlock(&inode->i_mutex);
9350 + return -EPERM;
9351 +@@ -123,7 +128,8 @@ flags_err:
9352 +
9353 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
9354 + return -EPERM;
9355 +- if (IS_RDONLY(inode))
9356 ++ if (IS_RDONLY(inode) ||
9357 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
9358 + return -EROFS;
9359 + if (get_user(generation, (int __user *) arg))
9360 + return -EFAULT;
9361 +@@ -177,7 +183,8 @@ flags_err:
9362 + if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
9363 + return -ENOTTY;
9364 +
9365 +- if (IS_RDONLY(inode))
9366 ++ if (IS_RDONLY(inode) ||
9367 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
9368 + return -EROFS;
9369 +
9370 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
9371 +@@ -212,7 +219,8 @@ flags_err:
9372 + if (!capable(CAP_SYS_RESOURCE))
9373 + return -EPERM;
9374 +
9375 +- if (IS_RDONLY(inode))
9376 ++ if (IS_RDONLY(inode) ||
9377 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
9378 + return -EROFS;
9379 +
9380 + if (get_user(n_blocks_count, (__u32 __user *)arg))
9381 +@@ -233,7 +241,8 @@ flags_err:
9382 + if (!capable(CAP_SYS_RESOURCE))
9383 + return -EPERM;
9384 +
9385 +- if (IS_RDONLY(inode))
9386 ++ if (IS_RDONLY(inode) ||
9387 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
9388 + return -EROFS;
9389 +
9390 + if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg,
9391 +@@ -248,6 +257,39 @@ flags_err:
9392 + return err;
9393 + }
9394 +
9395 ++#if defined(CONFIG_VSERVER_LEGACY) && !defined(CONFIG_TAGGING_NONE)
9396 ++ case EXT4_IOC_SETTAG: {
9397 ++ handle_t *handle;
9398 ++ struct ext4_iloc iloc;
9399 ++ int tag;
9400 ++ int err;
9401 ++
9402 ++ /* fixme: if stealth, return -ENOTTY */
9403 ++ if (!capable(CAP_CONTEXT))
9404 ++ return -EPERM;
9405 ++ if (IS_RDONLY(inode))
9406 ++ return -EROFS;
9407 ++ if (!(inode->i_sb->s_flags & MS_TAGGED))
9408 ++ return -ENOSYS;
9409 ++ if (get_user(tag, (int __user *) arg))
9410 ++ return -EFAULT;
9411 ++
9412 ++ handle = ext4_journal_start(inode, 1);
9413 ++ if (IS_ERR(handle))
9414 ++ return PTR_ERR(handle);
9415 ++ err = ext4_reserve_inode_write(handle, inode, &iloc);
9416 ++ if (err)
9417 ++ return err;
9418 ++
9419 ++ inode->i_tag = (tag & 0xFFFF);
9420 ++ inode->i_ctime = CURRENT_TIME;
9421 ++
9422 ++ err = ext4_mark_iloc_dirty(handle, inode, &iloc);
9423 ++ ext4_journal_stop(handle);
9424 ++ return err;
9425 ++ }
9426 ++#endif
9427 ++
9428 + default:
9429 + return -ENOTTY;
9430 + }
9431 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/namei.c linux-2.6.22.19-vs2.2.0.7/fs/ext4/namei.c
9432 +--- linux-2.6.22.19/fs/ext4/namei.c 2008-03-14 20:19:03 +0100
9433 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext4/namei.c 2007-10-01 15:25:35 +0200
9434 +@@ -36,6 +36,7 @@
9435 + #include <linux/quotaops.h>
9436 + #include <linux/buffer_head.h>
9437 + #include <linux/bio.h>
9438 ++#include <linux/vs_tag.h>
9439 +
9440 + #include "namei.h"
9441 + #include "xattr.h"
9442 +@@ -1050,6 +1051,7 @@ static struct dentry *ext4_lookup(struct
9443 +
9444 + if (!inode)
9445 + return ERR_PTR(-EACCES);
9446 ++ dx_propagate_tag(nd, inode);
9447 + }
9448 + return d_splice_alias(inode, dentry);
9449 + }
9450 +@@ -2441,6 +2443,7 @@ const struct inode_operations ext4_dir_i
9451 + .removexattr = generic_removexattr,
9452 + #endif
9453 + .permission = ext4_permission,
9454 ++ .sync_flags = ext4_sync_flags,
9455 + };
9456 +
9457 + const struct inode_operations ext4_special_inode_operations = {
9458 +@@ -2452,4 +2455,5 @@ const struct inode_operations ext4_speci
9459 + .removexattr = generic_removexattr,
9460 + #endif
9461 + .permission = ext4_permission,
9462 ++ .sync_flags = ext4_sync_flags,
9463 + };
9464 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/super.c linux-2.6.22.19-vs2.2.0.7/fs/ext4/super.c
9465 +--- linux-2.6.22.19/fs/ext4/super.c 2007-07-09 13:19:23 +0200
9466 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext4/super.c 2007-06-15 02:37:03 +0200
9467 +@@ -725,7 +725,7 @@ enum {
9468 + Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
9469 + Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
9470 + Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
9471 +- Opt_grpquota, Opt_extents,
9472 ++ Opt_grpquota, Opt_extents, Opt_tag, Opt_notag, Opt_tagid
9473 + };
9474 +
9475 + static match_table_t tokens = {
9476 +@@ -776,6 +776,10 @@ static match_table_t tokens = {
9477 + {Opt_usrquota, "usrquota"},
9478 + {Opt_barrier, "barrier=%u"},
9479 + {Opt_extents, "extents"},
9480 ++ {Opt_tag, "tag"},
9481 ++ {Opt_notag, "notag"},
9482 ++ {Opt_tagid, "tagid=%u"},
9483 ++ {Opt_tag, "tagxid"},
9484 + {Opt_err, NULL},
9485 + {Opt_resize, "resize"},
9486 + };
9487 +@@ -869,6 +873,20 @@ static int parse_options (char *options,
9488 + case Opt_nouid32:
9489 + set_opt (sbi->s_mount_opt, NO_UID32);
9490 + break;
9491 ++#ifndef CONFIG_TAGGING_NONE
9492 ++ case Opt_tag:
9493 ++ set_opt (sbi->s_mount_opt, TAGGED);
9494 ++ break;
9495 ++ case Opt_notag:
9496 ++ clear_opt (sbi->s_mount_opt, TAGGED);
9497 ++ break;
9498 ++#endif
9499 ++#ifdef CONFIG_PROPAGATE
9500 ++ case Opt_tagid:
9501 ++ /* use args[0] */
9502 ++ set_opt (sbi->s_mount_opt, TAGGED);
9503 ++ break;
9504 ++#endif
9505 + case Opt_nocheck:
9506 + clear_opt (sbi->s_mount_opt, CHECK);
9507 + break;
9508 +@@ -1546,6 +1564,9 @@ static int ext4_fill_super (struct super
9509 + NULL, 0))
9510 + goto failed_mount;
9511 +
9512 ++ if (EXT4_SB(sb)->s_mount_opt & EXT4_MOUNT_TAGGED)
9513 ++ sb->s_flags |= MS_TAGGED;
9514 ++
9515 + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
9516 + ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
9517 +
9518 +@@ -2377,6 +2398,12 @@ static int ext4_remount (struct super_bl
9519 +
9520 + if (sbi->s_mount_opt & EXT4_MOUNT_ABORT)
9521 + ext4_abort(sb, __FUNCTION__, "Abort forced by user");
9522 ++ if ((sbi->s_mount_opt & EXT4_MOUNT_TAGGED) &&
9523 ++ !(sb->s_flags & MS_TAGGED)) {
9524 ++ printk("EXT4-fs: %s: tagging not permitted on remount.\n",
9525 ++ sb->s_id);
9526 ++ return -EINVAL;
9527 ++ }
9528 +
9529 + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
9530 + ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
9531 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/symlink.c linux-2.6.22.19-vs2.2.0.7/fs/ext4/symlink.c
9532 +--- linux-2.6.22.19/fs/ext4/symlink.c 2007-05-02 19:25:17 +0200
9533 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext4/symlink.c 2007-06-15 02:37:03 +0200
9534 +@@ -40,6 +40,7 @@ const struct inode_operations ext4_symli
9535 + .listxattr = ext4_listxattr,
9536 + .removexattr = generic_removexattr,
9537 + #endif
9538 ++ .sync_flags = ext4_sync_flags,
9539 + };
9540 +
9541 + const struct inode_operations ext4_fast_symlink_inode_operations = {
9542 +@@ -51,4 +52,5 @@ const struct inode_operations ext4_fast_
9543 + .listxattr = ext4_listxattr,
9544 + .removexattr = generic_removexattr,
9545 + #endif
9546 ++ .sync_flags = ext4_sync_flags,
9547 + };
9548 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/xattr.c linux-2.6.22.19-vs2.2.0.7/fs/ext4/xattr.c
9549 +--- linux-2.6.22.19/fs/ext4/xattr.c 2007-05-02 19:25:17 +0200
9550 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ext4/xattr.c 2007-06-15 02:37:03 +0200
9551 +@@ -58,6 +58,7 @@
9552 + #include <linux/mbcache.h>
9553 + #include <linux/quotaops.h>
9554 + #include <linux/rwsem.h>
9555 ++#include <linux/vs_dlimit.h>
9556 + #include "xattr.h"
9557 + #include "acl.h"
9558 +
9559 +@@ -496,6 +497,7 @@ ext4_xattr_release_block(handle_t *handl
9560 + error = ext4_journal_dirty_metadata(handle, bh);
9561 + if (IS_SYNC(inode))
9562 + handle->h_sync = 1;
9563 ++ DLIMIT_FREE_BLOCK(inode, 1);
9564 + DQUOT_FREE_BLOCK(inode, 1);
9565 + ea_bdebug(bh, "refcount now=%d; releasing",
9566 + le32_to_cpu(BHDR(bh)->h_refcount));
9567 +@@ -769,11 +771,14 @@ inserted:
9568 + if (new_bh == bs->bh)
9569 + ea_bdebug(new_bh, "keeping");
9570 + else {
9571 ++ error = -ENOSPC;
9572 ++ if (DLIMIT_ALLOC_BLOCK(inode, 1))
9573 ++ goto cleanup;
9574 + /* The old block is released after updating
9575 + the inode. */
9576 + error = -EDQUOT;
9577 + if (DQUOT_ALLOC_BLOCK(inode, 1))
9578 +- goto cleanup;
9579 ++ goto cleanup_dlimit;
9580 + error = ext4_journal_get_write_access(handle,
9581 + new_bh);
9582 + if (error)
9583 +@@ -850,6 +855,8 @@ cleanup:
9584 +
9585 + cleanup_dquot:
9586 + DQUOT_FREE_BLOCK(inode, 1);
9587 ++cleanup_dlimit:
9588 ++ DLIMIT_FREE_BLOCK(inode, 1);
9589 + goto cleanup;
9590 +
9591 + bad_block:
9592 +diff -NurpP --minimal linux-2.6.22.19/fs/fcntl.c linux-2.6.22.19-vs2.2.0.7/fs/fcntl.c
9593 +--- linux-2.6.22.19/fs/fcntl.c 2007-02-06 03:01:18 +0100
9594 ++++ linux-2.6.22.19-vs2.2.0.7/fs/fcntl.c 2007-06-15 02:37:03 +0200
9595 +@@ -18,6 +18,7 @@
9596 + #include <linux/ptrace.h>
9597 + #include <linux/signal.h>
9598 + #include <linux/rcupdate.h>
9599 ++#include <linux/vs_limit.h>
9600 +
9601 + #include <asm/poll.h>
9602 + #include <asm/siginfo.h>
9603 +@@ -84,6 +85,8 @@ repeat:
9604 + error = -EMFILE;
9605 + if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
9606 + goto out;
9607 ++ if (!vx_files_avail(1))
9608 ++ goto out;
9609 +
9610 + error = expand_files(files, newfd);
9611 + if (error < 0)
9612 +@@ -124,6 +127,7 @@ static int dupfd(struct file *file, unsi
9613 + FD_SET(fd, fdt->open_fds);
9614 + FD_CLR(fd, fdt->close_on_exec);
9615 + spin_unlock(&files->file_lock);
9616 ++ vx_openfd_inc(fd);
9617 + fd_install(fd, file);
9618 + } else {
9619 + spin_unlock(&files->file_lock);
9620 +@@ -176,6 +180,9 @@ asmlinkage long sys_dup2(unsigned int ol
9621 +
9622 + if (tofree)
9623 + filp_close(tofree, files);
9624 ++ else
9625 ++ vx_openfd_inc(newfd); /* fd was unused */
9626 ++
9627 + err = newfd;
9628 + out:
9629 + return err;
9630 +diff -NurpP --minimal linux-2.6.22.19/fs/file_table.c linux-2.6.22.19-vs2.2.0.7/fs/file_table.c
9631 +--- linux-2.6.22.19/fs/file_table.c 2007-07-09 13:19:23 +0200
9632 ++++ linux-2.6.22.19-vs2.2.0.7/fs/file_table.c 2007-06-15 02:37:03 +0200
9633 +@@ -20,6 +20,8 @@
9634 + #include <linux/fsnotify.h>
9635 + #include <linux/sysctl.h>
9636 + #include <linux/percpu_counter.h>
9637 ++#include <linux/vs_limit.h>
9638 ++#include <linux/vs_context.h>
9639 +
9640 + #include <asm/atomic.h>
9641 +
9642 +@@ -119,6 +121,8 @@ struct file *get_empty_filp(void)
9643 + f->f_gid = tsk->fsgid;
9644 + eventpoll_init_file(f);
9645 + /* f->f_version: 0 */
9646 ++ f->f_xid = vx_current_xid();
9647 ++ vx_files_inc(f);
9648 + return f;
9649 +
9650 + over:
9651 +@@ -174,6 +178,8 @@ void fastcall __fput(struct file *file)
9652 + if (file->f_mode & FMODE_WRITE)
9653 + put_write_access(inode);
9654 + put_pid(file->f_owner.pid);
9655 ++ vx_files_dec(file);
9656 ++ file->f_xid = 0;
9657 + file_kill(file);
9658 + file->f_path.dentry = NULL;
9659 + file->f_path.mnt = NULL;
9660 +@@ -239,6 +245,8 @@ void put_filp(struct file *file)
9661 + {
9662 + if (atomic_dec_and_test(&file->f_count)) {
9663 + security_file_free(file);
9664 ++ vx_files_dec(file);
9665 ++ file->f_xid = 0;
9666 + file_kill(file);
9667 + file_free(file);
9668 + }
9669 +diff -NurpP --minimal linux-2.6.22.19/fs/hfsplus/ioctl.c linux-2.6.22.19-vs2.2.0.7/fs/hfsplus/ioctl.c
9670 +--- linux-2.6.22.19/fs/hfsplus/ioctl.c 2006-11-30 21:19:25 +0100
9671 ++++ linux-2.6.22.19-vs2.2.0.7/fs/hfsplus/ioctl.c 2007-06-15 02:37:03 +0200
9672 +@@ -16,6 +16,7 @@
9673 + #include <linux/fs.h>
9674 + #include <linux/sched.h>
9675 + #include <linux/xattr.h>
9676 ++#include <linux/mount.h>
9677 + #include <asm/uaccess.h>
9678 + #include "hfsplus_fs.h"
9679 +
9680 +@@ -35,7 +36,8 @@ int hfsplus_ioctl(struct inode *inode, s
9681 + flags |= FS_NODUMP_FL; /* EXT2_NODUMP_FL */
9682 + return put_user(flags, (int __user *)arg);
9683 + case HFSPLUS_IOC_EXT2_SETFLAGS: {
9684 +- if (IS_RDONLY(inode))
9685 ++ if (IS_RDONLY(inode) ||
9686 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
9687 + return -EROFS;
9688 +
9689 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
9690 +diff -NurpP --minimal linux-2.6.22.19/fs/inode.c linux-2.6.22.19-vs2.2.0.7/fs/inode.c
9691 +--- linux-2.6.22.19/fs/inode.c 2007-07-09 13:19:24 +0200
9692 ++++ linux-2.6.22.19-vs2.2.0.7/fs/inode.c 2007-06-15 02:37:03 +0200
9693 +@@ -115,6 +115,9 @@ static struct inode *alloc_inode(struct
9694 + struct address_space * const mapping = &inode->i_data;
9695 +
9696 + inode->i_sb = sb;
9697 ++
9698 ++ /* essential because of inode slab reuse */
9699 ++ inode->i_tag = 0;
9700 + inode->i_blkbits = sb->s_blocksize_bits;
9701 + inode->i_flags = 0;
9702 + atomic_set(&inode->i_count, 1);
9703 +@@ -231,6 +234,8 @@ void __iget(struct inode * inode)
9704 + inodes_stat.nr_unused--;
9705 + }
9706 +
9707 ++EXPORT_SYMBOL_GPL(__iget);
9708 ++
9709 + /**
9710 + * clear_inode - clear an inode
9711 + * @inode: inode to clear
9712 +diff -NurpP --minimal linux-2.6.22.19/fs/ioctl.c linux-2.6.22.19-vs2.2.0.7/fs/ioctl.c
9713 +--- linux-2.6.22.19/fs/ioctl.c 2007-07-09 13:19:24 +0200
9714 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ioctl.c 2007-06-15 03:12:40 +0200
9715 +@@ -13,10 +13,19 @@
9716 + #include <linux/security.h>
9717 + #include <linux/module.h>
9718 + #include <linux/kallsyms.h>
9719 ++#include <linux/proc_fs.h>
9720 ++#include <linux/vserver/inode.h>
9721 ++#include <linux/vs_tag.h>
9722 +
9723 + #include <asm/uaccess.h>
9724 + #include <asm/ioctls.h>
9725 +
9726 ++
9727 ++#ifdef CONFIG_VSERVER_LEGACY
9728 ++extern int vx_proc_ioctl(struct inode *, struct file *,
9729 ++ unsigned int, unsigned long);
9730 ++#endif
9731 ++
9732 + static long do_ioctl(struct file *filp, unsigned int cmd,
9733 + unsigned long arg)
9734 + {
9735 +@@ -152,6 +161,48 @@ int vfs_ioctl(struct file *filp, unsigne
9736 + else
9737 + error = -ENOTTY;
9738 + break;
9739 ++#ifdef CONFIG_VSERVER_LEGACY
9740 ++#ifndef CONFIG_TAGGING_NONE
9741 ++ case FIOC_GETTAG: {
9742 ++ struct inode *inode = filp->f_dentry->d_inode;
9743 ++
9744 ++ /* fixme: if stealth, return -ENOTTY */
9745 ++ error = -EPERM;
9746 ++ if (capable(CAP_CONTEXT))
9747 ++ error = put_user(inode->i_tag, (int __user *) arg);
9748 ++ break;
9749 ++ }
9750 ++ case FIOC_SETTAG: {
9751 ++ struct inode *inode = filp->f_dentry->d_inode;
9752 ++ int tag;
9753 ++
9754 ++ /* fixme: if stealth, return -ENOTTY */
9755 ++ error = -EPERM;
9756 ++ if (!capable(CAP_CONTEXT))
9757 ++ break;
9758 ++ error = -EROFS;
9759 ++ if (IS_RDONLY(inode))
9760 ++ break;
9761 ++ error = -ENOSYS;
9762 ++ if (!(inode->i_sb->s_flags & MS_TAGGED))
9763 ++ break;
9764 ++ error = -EFAULT;
9765 ++ if (get_user(tag, (int __user *) arg))
9766 ++ break;
9767 ++ error = 0;
9768 ++ inode->i_tag = (tag & 0xFFFF);
9769 ++ inode->i_ctime = CURRENT_TIME;
9770 ++ mark_inode_dirty(inode);
9771 ++ break;
9772 ++ }
9773 ++#endif
9774 ++ case FIOC_GETXFLG:
9775 ++ case FIOC_SETXFLG:
9776 ++ error = -ENOTTY;
9777 ++ if (filp->f_dentry->d_inode->i_sb->s_magic == PROC_SUPER_MAGIC)
9778 ++ error = vx_proc_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
9779 ++ break;
9780 ++#endif
9781 + default:
9782 + if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
9783 + error = file_ioctl(filp, cmd, arg);
9784 +diff -NurpP --minimal linux-2.6.22.19/fs/ioprio.c linux-2.6.22.19-vs2.2.0.7/fs/ioprio.c
9785 +--- linux-2.6.22.19/fs/ioprio.c 2007-05-02 19:25:18 +0200
9786 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ioprio.c 2007-06-15 02:37:03 +0200
9787 +@@ -25,6 +25,7 @@
9788 + #include <linux/capability.h>
9789 + #include <linux/syscalls.h>
9790 + #include <linux/security.h>
9791 ++#include <linux/vs_base.h>
9792 +
9793 + static int set_task_ioprio(struct task_struct *task, int ioprio)
9794 + {
9795 +@@ -103,6 +104,8 @@ asmlinkage long sys_ioprio_set(int which
9796 + else
9797 + pgrp = find_pid(who);
9798 + do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
9799 ++ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
9800 ++ continue;
9801 + ret = set_task_ioprio(p, ioprio);
9802 + if (ret)
9803 + break;
9804 +@@ -112,7 +115,7 @@ asmlinkage long sys_ioprio_set(int which
9805 + if (!who)
9806 + user = current->user;
9807 + else
9808 +- user = find_user(who);
9809 ++ user = find_user(vx_current_xid(), who);
9810 +
9811 + if (!user)
9812 + break;
9813 +@@ -190,6 +193,8 @@ asmlinkage long sys_ioprio_get(int which
9814 + else
9815 + pgrp = find_pid(who);
9816 + do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
9817 ++ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
9818 ++ continue;
9819 + tmpio = get_task_ioprio(p);
9820 + if (tmpio < 0)
9821 + continue;
9822 +@@ -203,7 +208,7 @@ asmlinkage long sys_ioprio_get(int which
9823 + if (!who)
9824 + user = current->user;
9825 + else
9826 +- user = find_user(who);
9827 ++ user = find_user(vx_current_xid(), who);
9828 +
9829 + if (!user)
9830 + break;
9831 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/acl.c linux-2.6.22.19-vs2.2.0.7/fs/jfs/acl.c
9832 +--- linux-2.6.22.19/fs/jfs/acl.c 2006-11-30 21:19:25 +0100
9833 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/acl.c 2007-06-15 02:37:03 +0200
9834 +@@ -232,7 +232,8 @@ int jfs_setattr(struct dentry *dentry, s
9835 + return rc;
9836 +
9837 + if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
9838 +- (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
9839 ++ (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) ||
9840 ++ (iattr->ia_valid & ATTR_TAG && iattr->ia_tag != inode->i_tag)) {
9841 + if (DQUOT_TRANSFER(inode, iattr))
9842 + return -EDQUOT;
9843 + }
9844 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/file.c linux-2.6.22.19-vs2.2.0.7/fs/jfs/file.c
9845 +--- linux-2.6.22.19/fs/jfs/file.c 2007-05-02 19:25:18 +0200
9846 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/file.c 2007-10-29 23:24:21 +0100
9847 +@@ -98,6 +98,7 @@ const struct inode_operations jfs_file_i
9848 + .setattr = jfs_setattr,
9849 + .permission = jfs_permission,
9850 + #endif
9851 ++ .sync_flags = jfs_sync_flags,
9852 + };
9853 +
9854 + const struct file_operations jfs_file_operations = {
9855 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/inode.c linux-2.6.22.19-vs2.2.0.7/fs/jfs/inode.c
9856 +--- linux-2.6.22.19/fs/jfs/inode.c 2007-07-09 13:19:26 +0200
9857 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/inode.c 2007-06-15 02:37:03 +0200
9858 +@@ -22,6 +22,7 @@
9859 + #include <linux/buffer_head.h>
9860 + #include <linux/pagemap.h>
9861 + #include <linux/quotaops.h>
9862 ++#include <linux/vs_dlimit.h>
9863 + #include "jfs_incore.h"
9864 + #include "jfs_inode.h"
9865 + #include "jfs_filsys.h"
9866 +@@ -143,6 +144,7 @@ void jfs_delete_inode(struct inode *inod
9867 + DQUOT_INIT(inode);
9868 + DQUOT_FREE_INODE(inode);
9869 + DQUOT_DROP(inode);
9870 ++ DLIMIT_FREE_INODE(inode);
9871 + }
9872 +
9873 + clear_inode(inode);
9874 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/ioctl.c linux-2.6.22.19-vs2.2.0.7/fs/jfs/ioctl.c
9875 +--- linux-2.6.22.19/fs/jfs/ioctl.c 2007-07-09 13:19:27 +0200
9876 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/ioctl.c 2007-06-15 02:37:03 +0200
9877 +@@ -10,6 +10,7 @@
9878 + #include <linux/capability.h>
9879 + #include <linux/time.h>
9880 + #include <linux/sched.h>
9881 ++#include <linux/mount.h>
9882 + #include <asm/current.h>
9883 + #include <asm/uaccess.h>
9884 +
9885 +@@ -66,7 +67,8 @@ int jfs_ioctl(struct inode * inode, stru
9886 + case JFS_IOC_SETFLAGS: {
9887 + unsigned int oldflags;
9888 +
9889 +- if (IS_RDONLY(inode))
9890 ++ if (IS_RDONLY(inode) ||
9891 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
9892 + return -EROFS;
9893 +
9894 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
9895 +@@ -87,8 +89,8 @@ int jfs_ioctl(struct inode * inode, stru
9896 + * the relevant capability.
9897 + */
9898 + if ((oldflags & JFS_IMMUTABLE_FL) ||
9899 +- ((flags ^ oldflags) &
9900 +- (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
9901 ++ ((flags ^ oldflags) & (JFS_APPEND_FL |
9902 ++ JFS_IMMUTABLE_FL | JFS_IUNLINK_FL))) {
9903 + if (!capable(CAP_LINUX_IMMUTABLE))
9904 + return -EPERM;
9905 + }
9906 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_dinode.h linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_dinode.h
9907 +--- linux-2.6.22.19/fs/jfs/jfs_dinode.h 2006-11-30 21:19:25 +0100
9908 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_dinode.h 2007-06-15 02:37:03 +0200
9909 +@@ -162,9 +162,12 @@ struct dinode {
9910 + #define JFS_APPEND_FL 0x01000000 /* writes to file may only append */
9911 + #define JFS_IMMUTABLE_FL 0x02000000 /* Immutable file */
9912 +
9913 +-#define JFS_FL_USER_VISIBLE 0x03F80000
9914 ++#define JFS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
9915 ++#define JFS_IUNLINK_FL 0x08000000 /* Immutable unlink */
9916 ++
9917 ++#define JFS_FL_USER_VISIBLE 0x0FF80000
9918 + #define JFS_FL_USER_MODIFIABLE 0x03F80000
9919 +-#define JFS_FL_INHERIT 0x03C80000
9920 ++#define JFS_FL_INHERIT 0x0BC80000
9921 +
9922 + /* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
9923 + #define JFS_IOC_GETFLAGS _IOR('f', 1, long)
9924 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_dtree.c linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_dtree.c
9925 +--- linux-2.6.22.19/fs/jfs/jfs_dtree.c 2007-02-06 03:01:24 +0100
9926 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_dtree.c 2007-06-15 02:37:03 +0200
9927 +@@ -102,6 +102,7 @@
9928 +
9929 + #include <linux/fs.h>
9930 + #include <linux/quotaops.h>
9931 ++#include <linux/vs_dlimit.h>
9932 + #include "jfs_incore.h"
9933 + #include "jfs_superblock.h"
9934 + #include "jfs_filsys.h"
9935 +@@ -383,10 +384,10 @@ static u32 add_index(tid_t tid, struct i
9936 + */
9937 + if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage))
9938 + goto clean_up;
9939 +- if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) {
9940 +- DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
9941 +- goto clean_up;
9942 +- }
9943 ++ if (DLIMIT_ALLOC_BLOCK(ip, sbi->nbperpage))
9944 ++ goto clean_up_dquot;
9945 ++ if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr))
9946 ++ goto clean_up_dlimit;
9947 +
9948 + /*
9949 + * Save the table, we're going to overwrite it with the
9950 +@@ -479,6 +480,12 @@ static u32 add_index(tid_t tid, struct i
9951 +
9952 + return index;
9953 +
9954 ++ clean_up_dlimit:
9955 ++ DLIMIT_FREE_BLOCK(ip, sbi->nbperpage);
9956 ++
9957 ++ clean_up_dquot:
9958 ++ DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
9959 ++
9960 + clean_up:
9961 +
9962 + jfs_ip->next_index--;
9963 +@@ -952,6 +959,7 @@ static int dtSplitUp(tid_t tid,
9964 + struct tlock *tlck;
9965 + struct lv *lv;
9966 + int quota_allocation = 0;
9967 ++ int dlimit_allocation = 0;
9968 +
9969 + /* get split page */
9970 + smp = split->mp;
9971 +@@ -1036,6 +1044,12 @@ static int dtSplitUp(tid_t tid,
9972 + }
9973 + quota_allocation += n;
9974 +
9975 ++ if (DLIMIT_ALLOC_BLOCK(ip, n)) {
9976 ++ rc = -ENOSPC;
9977 ++ goto extendOut;
9978 ++ }
9979 ++ dlimit_allocation += n;
9980 ++
9981 + if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen,
9982 + (s64) n, &nxaddr)))
9983 + goto extendOut;
9984 +@@ -1309,6 +1323,9 @@ static int dtSplitUp(tid_t tid,
9985 + freeKeyName:
9986 + kfree(key.name);
9987 +
9988 ++ /* Rollback dlimit allocation */
9989 ++ if (rc && dlimit_allocation)
9990 ++ DLIMIT_FREE_BLOCK(ip, dlimit_allocation);
9991 + /* Rollback quota allocation */
9992 + if (rc && quota_allocation)
9993 + DQUOT_FREE_BLOCK(ip, quota_allocation);
9994 +@@ -1376,6 +1393,12 @@ static int dtSplitPage(tid_t tid, struct
9995 + release_metapage(rmp);
9996 + return -EDQUOT;
9997 + }
9998 ++ /* Allocate blocks to dlimit. */
9999 ++ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
10000 ++ DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
10001 ++ release_metapage(rmp);
10002 ++ return -ENOSPC;
10003 ++ }
10004 +
10005 + jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
10006 +
10007 +@@ -1926,6 +1949,12 @@ static int dtSplitRoot(tid_t tid,
10008 + release_metapage(rmp);
10009 + return -EDQUOT;
10010 + }
10011 ++ /* Allocate blocks to dlimit. */
10012 ++ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
10013 ++ DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
10014 ++ release_metapage(rmp);
10015 ++ return -ENOSPC;
10016 ++ }
10017 +
10018 + BT_MARK_DIRTY(rmp, ip);
10019 + /*
10020 +@@ -2292,6 +2321,8 @@ static int dtDeleteUp(tid_t tid, struct
10021 +
10022 + xlen = lengthPXD(&fp->header.self);
10023 +
10024 ++ /* Free dlimit allocation. */
10025 ++ DLIMIT_FREE_BLOCK(ip, xlen);
10026 + /* Free quota allocation. */
10027 + DQUOT_FREE_BLOCK(ip, xlen);
10028 +
10029 +@@ -2368,6 +2399,8 @@ static int dtDeleteUp(tid_t tid, struct
10030 +
10031 + xlen = lengthPXD(&p->header.self);
10032 +
10033 ++ /* Free dlimit allocation */
10034 ++ DLIMIT_FREE_BLOCK(ip, xlen);
10035 + /* Free quota allocation */
10036 + DQUOT_FREE_BLOCK(ip, xlen);
10037 +
10038 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_extent.c linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_extent.c
10039 +--- linux-2.6.22.19/fs/jfs/jfs_extent.c 2006-11-30 21:19:25 +0100
10040 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_extent.c 2007-06-15 02:37:03 +0200
10041 +@@ -18,6 +18,7 @@
10042 +
10043 + #include <linux/fs.h>
10044 + #include <linux/quotaops.h>
10045 ++#include <linux/vs_dlimit.h>
10046 + #include "jfs_incore.h"
10047 + #include "jfs_inode.h"
10048 + #include "jfs_superblock.h"
10049 +@@ -147,6 +148,14 @@ extAlloc(struct inode *ip, s64 xlen, s64
10050 + return -EDQUOT;
10051 + }
10052 +
10053 ++ /* Allocate blocks to dlimit. */
10054 ++ if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) {
10055 ++ DQUOT_FREE_BLOCK(ip, nxlen);
10056 ++ dbFree(ip, nxaddr, (s64) nxlen);
10057 ++ mutex_unlock(&JFS_IP(ip)->commit_mutex);
10058 ++ return -ENOSPC;
10059 ++ }
10060 ++
10061 + /* determine the value of the extent flag */
10062 + xflag = abnr ? XAD_NOTRECORDED : 0;
10063 +
10064 +@@ -164,6 +173,7 @@ extAlloc(struct inode *ip, s64 xlen, s64
10065 + */
10066 + if (rc) {
10067 + dbFree(ip, nxaddr, nxlen);
10068 ++ DLIMIT_FREE_BLOCK(ip, nxlen);
10069 + DQUOT_FREE_BLOCK(ip, nxlen);
10070 + mutex_unlock(&JFS_IP(ip)->commit_mutex);
10071 + return (rc);
10072 +@@ -261,6 +271,13 @@ int extRealloc(struct inode *ip, s64 nxl
10073 + mutex_unlock(&JFS_IP(ip)->commit_mutex);
10074 + return -EDQUOT;
10075 + }
10076 ++ /* Allocate blocks to dlimit. */
10077 ++ if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) {
10078 ++ DQUOT_FREE_BLOCK(ip, nxlen);
10079 ++ dbFree(ip, nxaddr, (s64) nxlen);
10080 ++ up(&JFS_IP(ip)->commit_sem);
10081 ++ return -ENOSPC;
10082 ++ }
10083 +
10084 + delta = nxlen - xlen;
10085 +
10086 +@@ -297,6 +314,7 @@ int extRealloc(struct inode *ip, s64 nxl
10087 + /* extend the extent */
10088 + if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) {
10089 + dbFree(ip, xaddr + xlen, delta);
10090 ++ DLIMIT_FREE_BLOCK(ip, nxlen);
10091 + DQUOT_FREE_BLOCK(ip, nxlen);
10092 + goto exit;
10093 + }
10094 +@@ -308,6 +326,7 @@ int extRealloc(struct inode *ip, s64 nxl
10095 + */
10096 + if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) {
10097 + dbFree(ip, nxaddr, nxlen);
10098 ++ DLIMIT_FREE_BLOCK(ip, nxlen);
10099 + DQUOT_FREE_BLOCK(ip, nxlen);
10100 + goto exit;
10101 + }
10102 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_filsys.h linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_filsys.h
10103 +--- linux-2.6.22.19/fs/jfs/jfs_filsys.h 2007-02-06 03:01:24 +0100
10104 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_filsys.h 2007-06-15 02:37:03 +0200
10105 +@@ -264,6 +264,7 @@
10106 + #define JFS_NAME_MAX 255
10107 + #define JFS_PATH_MAX BPSIZE
10108 +
10109 ++#define JFS_TAGGED 0x00800000 /* Context Tagging */
10110 +
10111 + /*
10112 + * file system state (superblock state)
10113 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_imap.c linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_imap.c
10114 +--- linux-2.6.22.19/fs/jfs/jfs_imap.c 2007-07-09 13:19:27 +0200
10115 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_imap.c 2007-06-15 03:01:50 +0200
10116 +@@ -45,6 +45,7 @@
10117 + #include <linux/buffer_head.h>
10118 + #include <linux/pagemap.h>
10119 + #include <linux/quotaops.h>
10120 ++#include <linux/vs_tag.h>
10121 +
10122 + #include "jfs_incore.h"
10123 + #include "jfs_inode.h"
10124 +@@ -3075,6 +3076,8 @@ static int copy_from_dinode(struct dinod
10125 + {
10126 + struct jfs_inode_info *jfs_ip = JFS_IP(ip);
10127 + struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
10128 ++ uid_t uid;
10129 ++ gid_t gid;
10130 +
10131 + jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
10132 + jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
10133 +@@ -3095,14 +3098,18 @@ static int copy_from_dinode(struct dinod
10134 + }
10135 + ip->i_nlink = le32_to_cpu(dip->di_nlink);
10136 +
10137 +- jfs_ip->saved_uid = le32_to_cpu(dip->di_uid);
10138 ++ uid = le32_to_cpu(dip->di_uid);
10139 ++ gid = le32_to_cpu(dip->di_gid);
10140 ++ ip->i_tag = INOTAG_TAG(DX_TAG(ip), uid, gid, 0);
10141 ++
10142 ++ jfs_ip->saved_uid = INOTAG_UID(DX_TAG(ip), uid, gid);
10143 + if (sbi->uid == -1)
10144 + ip->i_uid = jfs_ip->saved_uid;
10145 + else {
10146 + ip->i_uid = sbi->uid;
10147 + }
10148 +
10149 +- jfs_ip->saved_gid = le32_to_cpu(dip->di_gid);
10150 ++ jfs_ip->saved_gid = INOTAG_GID(DX_TAG(ip), uid, gid);
10151 + if (sbi->gid == -1)
10152 + ip->i_gid = jfs_ip->saved_gid;
10153 + else {
10154 +@@ -3167,14 +3174,12 @@ static void copy_to_dinode(struct dinode
10155 + dip->di_size = cpu_to_le64(ip->i_size);
10156 + dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
10157 + dip->di_nlink = cpu_to_le32(ip->i_nlink);
10158 +- if (sbi->uid == -1)
10159 +- dip->di_uid = cpu_to_le32(ip->i_uid);
10160 +- else
10161 +- dip->di_uid = cpu_to_le32(jfs_ip->saved_uid);
10162 +- if (sbi->gid == -1)
10163 +- dip->di_gid = cpu_to_le32(ip->i_gid);
10164 +- else
10165 +- dip->di_gid = cpu_to_le32(jfs_ip->saved_gid);
10166 ++
10167 ++ dip->di_uid = cpu_to_le32(TAGINO_UID(DX_TAG(ip),
10168 ++ (sbi->uid == -1) ? ip->i_uid : jfs_ip->saved_uid, ip->i_tag));
10169 ++ dip->di_gid = cpu_to_le32(TAGINO_GID(DX_TAG(ip),
10170 ++ (sbi->gid == -1) ? ip->i_gid : jfs_ip->saved_gid, ip->i_tag));
10171 ++
10172 + jfs_get_inode_flags(jfs_ip);
10173 + /*
10174 + * mode2 is only needed for storing the higher order bits.
10175 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_inode.c linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_inode.c
10176 +--- linux-2.6.22.19/fs/jfs/jfs_inode.c 2007-07-09 13:19:27 +0200
10177 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_inode.c 2007-07-19 08:09:20 +0200
10178 +@@ -18,6 +18,8 @@
10179 +
10180 + #include <linux/fs.h>
10181 + #include <linux/quotaops.h>
10182 ++#include <linux/vs_dlimit.h>
10183 ++#include <linux/vs_tag.h>
10184 + #include "jfs_incore.h"
10185 + #include "jfs_inode.h"
10186 + #include "jfs_filsys.h"
10187 +@@ -30,19 +32,47 @@ void jfs_set_inode_flags(struct inode *i
10188 + {
10189 + unsigned int flags = JFS_IP(inode)->mode2;
10190 +
10191 +- inode->i_flags &= ~(S_IMMUTABLE | S_APPEND |
10192 +- S_NOATIME | S_DIRSYNC | S_SYNC);
10193 ++ inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
10194 ++ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
10195 +
10196 + if (flags & JFS_IMMUTABLE_FL)
10197 + inode->i_flags |= S_IMMUTABLE;
10198 ++ if (flags & JFS_IUNLINK_FL)
10199 ++ inode->i_flags |= S_IUNLINK;
10200 ++ if (flags & JFS_BARRIER_FL)
10201 ++ inode->i_flags |= S_BARRIER;
10202 ++
10203 ++ if (flags & JFS_SYNC_FL)
10204 ++ inode->i_flags |= S_SYNC;
10205 + if (flags & JFS_APPEND_FL)
10206 + inode->i_flags |= S_APPEND;
10207 + if (flags & JFS_NOATIME_FL)
10208 + inode->i_flags |= S_NOATIME;
10209 + if (flags & JFS_DIRSYNC_FL)
10210 + inode->i_flags |= S_DIRSYNC;
10211 +- if (flags & JFS_SYNC_FL)
10212 +- inode->i_flags |= S_SYNC;
10213 ++}
10214 ++
10215 ++int jfs_sync_flags(struct inode *inode)
10216 ++{
10217 ++ unsigned int oldflags, newflags;
10218 ++
10219 ++ oldflags = JFS_IP(inode)->mode2;
10220 ++ newflags = oldflags & ~(JFS_IMMUTABLE_FL |
10221 ++ JFS_IUNLINK_FL | JFS_BARRIER_FL);
10222 ++
10223 ++ if (IS_IMMUTABLE(inode))
10224 ++ newflags |= JFS_IMMUTABLE_FL;
10225 ++ if (IS_IUNLINK(inode))
10226 ++ newflags |= JFS_IUNLINK_FL;
10227 ++ if (IS_BARRIER(inode))
10228 ++ newflags |= JFS_BARRIER_FL;
10229 ++
10230 ++ if (oldflags ^ newflags) {
10231 ++ JFS_IP(inode)->mode2 = newflags;
10232 ++ inode->i_ctime = CURRENT_TIME;
10233 ++ mark_inode_dirty(inode);
10234 ++ }
10235 ++ return 0;
10236 + }
10237 +
10238 + void jfs_get_inode_flags(struct jfs_inode_info *jfs_ip)
10239 +@@ -108,10 +138,17 @@ struct inode *ialloc(struct inode *paren
10240 + jfs_inode->saved_uid = inode->i_uid;
10241 + jfs_inode->saved_gid = inode->i_gid;
10242 +
10243 ++ inode->i_tag = dx_current_fstag(sb);
10244 ++ if (DLIMIT_ALLOC_INODE(inode)) {
10245 ++ iput(inode);
10246 ++ return ERR_PTR(-ENOSPC);
10247 ++ }
10248 ++
10249 + /*
10250 + * Allocate inode to quota.
10251 + */
10252 + if (DQUOT_ALLOC_INODE(inode)) {
10253 ++ DLIMIT_FREE_INODE(inode);
10254 + DQUOT_DROP(inode);
10255 + inode->i_flags |= S_NOQUOTA;
10256 + inode->i_nlink = 0;
10257 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_inode.h linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_inode.h
10258 +--- linux-2.6.22.19/fs/jfs/jfs_inode.h 2007-07-09 13:19:27 +0200
10259 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_inode.h 2007-06-15 03:02:28 +0200
10260 +@@ -33,6 +33,7 @@ extern void jfs_free_zero_link(struct in
10261 + extern struct dentry *jfs_get_parent(struct dentry *dentry);
10262 + extern void jfs_get_inode_flags(struct jfs_inode_info *);
10263 + extern void jfs_set_inode_flags(struct inode *);
10264 ++extern int jfs_sync_flags(struct inode *);
10265 + extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
10266 +
10267 + extern const struct address_space_operations jfs_aops;
10268 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_xtree.c linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_xtree.c
10269 +--- linux-2.6.22.19/fs/jfs/jfs_xtree.c 2007-05-02 19:25:18 +0200
10270 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/jfs_xtree.c 2007-06-15 02:37:03 +0200
10271 +@@ -21,6 +21,7 @@
10272 +
10273 + #include <linux/fs.h>
10274 + #include <linux/quotaops.h>
10275 ++#include <linux/vs_dlimit.h>
10276 + #include "jfs_incore.h"
10277 + #include "jfs_filsys.h"
10278 + #include "jfs_metapage.h"
10279 +@@ -846,7 +847,12 @@ int xtInsert(tid_t tid, /* transaction
10280 + hint = 0;
10281 + if ((rc = DQUOT_ALLOC_BLOCK(ip, xlen)))
10282 + goto out;
10283 ++ if ((rc = DLIMIT_ALLOC_BLOCK(ip, xlen))) {
10284 ++ DQUOT_FREE_BLOCK(ip, xlen);
10285 ++ goto out;
10286 ++ }
10287 + if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) {
10288 ++ DLIMIT_FREE_BLOCK(ip, xlen);
10289 + DQUOT_FREE_BLOCK(ip, xlen);
10290 + goto out;
10291 + }
10292 +@@ -876,6 +882,7 @@ int xtInsert(tid_t tid, /* transaction
10293 + /* undo data extent allocation */
10294 + if (*xaddrp == 0) {
10295 + dbFree(ip, xaddr, (s64) xlen);
10296 ++ DLIMIT_FREE_BLOCK(ip, xlen);
10297 + DQUOT_FREE_BLOCK(ip, xlen);
10298 + }
10299 + return rc;
10300 +@@ -1236,6 +1243,7 @@ xtSplitPage(tid_t tid, struct inode *ip,
10301 + struct tlock *tlck;
10302 + struct xtlock *sxtlck = NULL, *rxtlck = NULL;
10303 + int quota_allocation = 0;
10304 ++ int dlimit_allocation = 0;
10305 +
10306 + smp = split->mp;
10307 + sp = XT_PAGE(ip, smp);
10308 +@@ -1255,6 +1263,13 @@ xtSplitPage(tid_t tid, struct inode *ip,
10309 +
10310 + quota_allocation += lengthPXD(pxd);
10311 +
10312 ++ /* Allocate blocks to dlimit. */
10313 ++ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
10314 ++ rc = -ENOSPC;
10315 ++ goto clean_up;
10316 ++ }
10317 ++ dlimit_allocation += lengthPXD(pxd);
10318 ++
10319 + /*
10320 + * allocate the new right page for the split
10321 + */
10322 +@@ -1456,6 +1471,9 @@ xtSplitPage(tid_t tid, struct inode *ip,
10323 +
10324 + clean_up:
10325 +
10326 ++ /* Rollback dlimit allocation. */
10327 ++ if (dlimit_allocation)
10328 ++ DLIMIT_FREE_BLOCK(ip, dlimit_allocation);
10329 + /* Rollback quota allocation. */
10330 + if (quota_allocation)
10331 + DQUOT_FREE_BLOCK(ip, quota_allocation);
10332 +@@ -1520,6 +1538,12 @@ xtSplitRoot(tid_t tid,
10333 + release_metapage(rmp);
10334 + return -EDQUOT;
10335 + }
10336 ++ /* Allocate blocks to dlimit. */
10337 ++ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
10338 ++ DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
10339 ++ release_metapage(rmp);
10340 ++ return -ENOSPC;
10341 ++ }
10342 +
10343 + jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp);
10344 +
10345 +@@ -3951,6 +3975,8 @@ s64 xtTruncate(tid_t tid, struct inode *
10346 + else
10347 + ip->i_size = newsize;
10348 +
10349 ++ /* update dlimit allocation to reflect freed blocks */
10350 ++ DLIMIT_FREE_BLOCK(ip, nfreed);
10351 + /* update quota allocation to reflect freed blocks */
10352 + DQUOT_FREE_BLOCK(ip, nfreed);
10353 +
10354 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/namei.c linux-2.6.22.19-vs2.2.0.7/fs/jfs/namei.c
10355 +--- linux-2.6.22.19/fs/jfs/namei.c 2007-05-02 19:25:18 +0200
10356 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/namei.c 2007-06-15 02:37:03 +0200
10357 +@@ -20,6 +20,7 @@
10358 + #include <linux/fs.h>
10359 + #include <linux/ctype.h>
10360 + #include <linux/quotaops.h>
10361 ++#include <linux/vs_tag.h>
10362 + #include "jfs_incore.h"
10363 + #include "jfs_superblock.h"
10364 + #include "jfs_inode.h"
10365 +@@ -1469,6 +1470,7 @@ static struct dentry *jfs_lookup(struct
10366 + return ERR_PTR(-EACCES);
10367 + }
10368 +
10369 ++ dx_propagate_tag(nd, ip);
10370 + dentry = d_splice_alias(ip, dentry);
10371 +
10372 + if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2))
10373 +@@ -1521,6 +1523,7 @@ const struct inode_operations jfs_dir_in
10374 + .setattr = jfs_setattr,
10375 + .permission = jfs_permission,
10376 + #endif
10377 ++ .sync_flags = jfs_sync_flags,
10378 + };
10379 +
10380 + const struct file_operations jfs_dir_operations = {
10381 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/super.c linux-2.6.22.19-vs2.2.0.7/fs/jfs/super.c
10382 +--- linux-2.6.22.19/fs/jfs/super.c 2007-07-09 13:19:27 +0200
10383 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/super.c 2007-06-15 02:37:03 +0200
10384 +@@ -194,7 +194,8 @@ static void jfs_put_super(struct super_b
10385 + enum {
10386 + Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
10387 + Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
10388 +- Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask
10389 ++ Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask,
10390 ++ Opt_tag, Opt_notag, Opt_tagid
10391 + };
10392 +
10393 + static match_table_t tokens = {
10394 +@@ -204,6 +205,10 @@ static match_table_t tokens = {
10395 + {Opt_resize, "resize=%u"},
10396 + {Opt_resize_nosize, "resize"},
10397 + {Opt_errors, "errors=%s"},
10398 ++ {Opt_tag, "tag"},
10399 ++ {Opt_notag, "notag"},
10400 ++ {Opt_tagid, "tagid=%u"},
10401 ++ {Opt_tag, "tagxid"},
10402 + {Opt_ignore, "noquota"},
10403 + {Opt_ignore, "quota"},
10404 + {Opt_usrquota, "usrquota"},
10405 +@@ -338,6 +343,20 @@ static int parse_options(char *options,
10406 + }
10407 + break;
10408 + }
10409 ++#ifndef CONFIG_TAGGING_NONE
10410 ++ case Opt_tag:
10411 ++ *flag |= JFS_TAGGED;
10412 ++ break;
10413 ++ case Opt_notag:
10414 ++ *flag &= JFS_TAGGED;
10415 ++ break;
10416 ++#endif
10417 ++#ifdef CONFIG_PROPAGATE
10418 ++ case Opt_tagid:
10419 ++ /* use args[0] */
10420 ++ *flag |= JFS_TAGGED;
10421 ++ break;
10422 ++#endif
10423 + default:
10424 + printk("jfs: Unrecognized mount option \"%s\" "
10425 + " or missing value\n", p);
10426 +@@ -368,6 +387,13 @@ static int jfs_remount(struct super_bloc
10427 + if (!parse_options(data, sb, &newLVSize, &flag)) {
10428 + return -EINVAL;
10429 + }
10430 ++
10431 ++ if ((flag & JFS_TAGGED) && !(sb->s_flags & MS_TAGGED)) {
10432 ++ printk(KERN_ERR "JFS: %s: tagging not permitted on remount.\n",
10433 ++ sb->s_id);
10434 ++ return -EINVAL;
10435 ++ }
10436 ++
10437 + if (newLVSize) {
10438 + if (sb->s_flags & MS_RDONLY) {
10439 + printk(KERN_ERR
10440 +@@ -439,6 +465,9 @@ static int jfs_fill_super(struct super_b
10441 + #ifdef CONFIG_JFS_POSIX_ACL
10442 + sb->s_flags |= MS_POSIXACL;
10443 + #endif
10444 ++ /* map mount option tagxid */
10445 ++ if (sbi->flag & JFS_TAGGED)
10446 ++ sb->s_flags |= MS_TAGGED;
10447 +
10448 + if (newLVSize) {
10449 + printk(KERN_ERR "resize option for remount only\n");
10450 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/xattr.c linux-2.6.22.19-vs2.2.0.7/fs/jfs/xattr.c
10451 +--- linux-2.6.22.19/fs/jfs/xattr.c 2006-11-30 21:19:26 +0100
10452 ++++ linux-2.6.22.19-vs2.2.0.7/fs/jfs/xattr.c 2007-06-15 02:37:03 +0200
10453 +@@ -23,6 +23,7 @@
10454 + #include <linux/posix_acl_xattr.h>
10455 + #include <linux/quotaops.h>
10456 + #include <linux/security.h>
10457 ++#include <linux/vs_dlimit.h>
10458 + #include "jfs_incore.h"
10459 + #include "jfs_superblock.h"
10460 + #include "jfs_dmap.h"
10461 +@@ -263,9 +264,16 @@ static int ea_write(struct inode *ip, st
10462 + if (DQUOT_ALLOC_BLOCK(ip, nblocks)) {
10463 + return -EDQUOT;
10464 + }
10465 ++ /* Allocate new blocks to dlimit. */
10466 ++ if (DLIMIT_ALLOC_BLOCK(ip, nblocks)) {
10467 ++ DQUOT_FREE_BLOCK(ip, nblocks);
10468 ++ return -ENOSPC;
10469 ++ }
10470 +
10471 + rc = dbAlloc(ip, INOHINT(ip), nblocks, &blkno);
10472 + if (rc) {
10473 ++ /*Rollback dlimit allocation. */
10474 ++ DLIMIT_FREE_BLOCK(ip, nblocks);
10475 + /*Rollback quota allocation. */
10476 + DQUOT_FREE_BLOCK(ip, nblocks);
10477 + return rc;
10478 +@@ -332,6 +340,8 @@ static int ea_write(struct inode *ip, st
10479 +
10480 + failed:
10481 + /* Rollback quota allocation. */
10482 ++ DLIMIT_FREE_BLOCK(ip, nblocks);
10483 ++ /* Rollback quota allocation. */
10484 + DQUOT_FREE_BLOCK(ip, nblocks);
10485 +
10486 + dbFree(ip, blkno, nblocks);
10487 +@@ -468,6 +478,7 @@ static int ea_get(struct inode *inode, s
10488 + s64 blkno;
10489 + int rc;
10490 + int quota_allocation = 0;
10491 ++ int dlimit_allocation = 0;
10492 +
10493 + /* When fsck.jfs clears a bad ea, it doesn't clear the size */
10494 + if (ji->ea.flag == 0)
10495 +@@ -543,6 +554,12 @@ static int ea_get(struct inode *inode, s
10496 +
10497 + quota_allocation = blocks_needed;
10498 +
10499 ++ /* Allocate new blocks to dlimit. */
10500 ++ rc = -ENOSPC;
10501 ++ if (DLIMIT_ALLOC_BLOCK(inode, blocks_needed))
10502 ++ goto clean_up;
10503 ++ dlimit_allocation = blocks_needed;
10504 ++
10505 + rc = dbAlloc(inode, INOHINT(inode), (s64) blocks_needed,
10506 + &blkno);
10507 + if (rc)
10508 +@@ -599,6 +616,9 @@ static int ea_get(struct inode *inode, s
10509 + return ea_size;
10510 +
10511 + clean_up:
10512 ++ /* Rollback dlimit allocation */
10513 ++ if (dlimit_allocation)
10514 ++ DLIMIT_FREE_BLOCK(inode, dlimit_allocation);
10515 + /* Rollback quota allocation */
10516 + if (quota_allocation)
10517 + DQUOT_FREE_BLOCK(inode, quota_allocation);
10518 +@@ -675,8 +695,10 @@ static int ea_put(tid_t tid, struct inod
10519 + }
10520 +
10521 + /* If old blocks exist, they must be removed from quota allocation. */
10522 +- if (old_blocks)
10523 ++ if (old_blocks) {
10524 ++ DLIMIT_FREE_BLOCK(inode, old_blocks);
10525 + DQUOT_FREE_BLOCK(inode, old_blocks);
10526 ++ }
10527 +
10528 + inode->i_ctime = CURRENT_TIME;
10529 +
10530 +diff -NurpP --minimal linux-2.6.22.19/fs/libfs.c linux-2.6.22.19-vs2.2.0.7/fs/libfs.c
10531 +--- linux-2.6.22.19/fs/libfs.c 2007-07-09 13:19:27 +0200
10532 ++++ linux-2.6.22.19-vs2.2.0.7/fs/libfs.c 2007-06-15 02:37:03 +0200
10533 +@@ -124,7 +124,8 @@ static inline unsigned char dt_type(stru
10534 + * both impossible due to the lock on directory.
10535 + */
10536 +
10537 +-int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
10538 ++static inline int do_dcache_readdir_filter(struct file *filp,
10539 ++ void *dirent, filldir_t filldir, int (*filter)(struct dentry *dentry))
10540 + {
10541 + struct dentry *dentry = filp->f_path.dentry;
10542 + struct dentry *cursor = filp->private_data;
10543 +@@ -157,6 +158,8 @@ int dcache_readdir(struct file * filp, v
10544 + next = list_entry(p, struct dentry, d_u.d_child);
10545 + if (d_unhashed(next) || !next->d_inode)
10546 + continue;
10547 ++ if (filter && !filter(next))
10548 ++ continue;
10549 +
10550 + spin_unlock(&dcache_lock);
10551 + if (filldir(dirent, next->d_name.name,
10552 +@@ -175,6 +178,18 @@ int dcache_readdir(struct file * filp, v
10553 + return 0;
10554 + }
10555 +
10556 ++int dcache_readdir(struct file *filp, void *dirent, filldir_t filldir)
10557 ++{
10558 ++ return do_dcache_readdir_filter(filp, dirent, filldir, NULL);
10559 ++}
10560 ++
10561 ++int dcache_readdir_filter(struct file *filp, void *dirent, filldir_t filldir,
10562 ++ int (*filter)(struct dentry *))
10563 ++{
10564 ++ return do_dcache_readdir_filter(filp, dirent, filldir, filter);
10565 ++}
10566 ++
10567 ++
10568 + ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
10569 + {
10570 + return -EISDIR;
10571 +@@ -640,6 +655,7 @@ EXPORT_SYMBOL(dcache_dir_close);
10572 + EXPORT_SYMBOL(dcache_dir_lseek);
10573 + EXPORT_SYMBOL(dcache_dir_open);
10574 + EXPORT_SYMBOL(dcache_readdir);
10575 ++EXPORT_SYMBOL(dcache_readdir_filter);
10576 + EXPORT_SYMBOL(generic_read_dir);
10577 + EXPORT_SYMBOL(get_sb_pseudo);
10578 + EXPORT_SYMBOL(simple_commit_write);
10579 +diff -NurpP --minimal linux-2.6.22.19/fs/locks.c linux-2.6.22.19-vs2.2.0.7/fs/locks.c
10580 +--- linux-2.6.22.19/fs/locks.c 2008-03-14 20:19:03 +0100
10581 ++++ linux-2.6.22.19-vs2.2.0.7/fs/locks.c 2007-10-01 15:26:40 +0200
10582 +@@ -125,6 +125,8 @@
10583 + #include <linux/syscalls.h>
10584 + #include <linux/time.h>
10585 + #include <linux/rcupdate.h>
10586 ++#include <linux/vs_base.h>
10587 ++#include <linux/vs_limit.h>
10588 +
10589 + #include <asm/semaphore.h>
10590 + #include <asm/uaccess.h>
10591 +@@ -147,6 +149,8 @@ static struct kmem_cache *filelock_cache
10592 + /* Allocate an empty lock structure. */
10593 + static struct file_lock *locks_alloc_lock(void)
10594 + {
10595 ++ if (!vx_locks_avail(1))
10596 ++ return NULL;
10597 + return kmem_cache_alloc(filelock_cache, GFP_KERNEL);
10598 + }
10599 +
10600 +@@ -172,6 +176,7 @@ static void locks_free_lock(struct file_
10601 + BUG_ON(!list_empty(&fl->fl_block));
10602 + BUG_ON(!list_empty(&fl->fl_link));
10603 +
10604 ++ vx_locks_dec(fl);
10605 + locks_release_private(fl);
10606 + kmem_cache_free(filelock_cache, fl);
10607 + }
10608 +@@ -191,6 +196,7 @@ void locks_init_lock(struct file_lock *f
10609 + fl->fl_start = fl->fl_end = 0;
10610 + fl->fl_ops = NULL;
10611 + fl->fl_lmops = NULL;
10612 ++ fl->fl_xid = -1;
10613 + }
10614 +
10615 + EXPORT_SYMBOL(locks_init_lock);
10616 +@@ -244,6 +250,7 @@ void locks_copy_lock(struct file_lock *n
10617 + new->fl_file = fl->fl_file;
10618 + new->fl_ops = fl->fl_ops;
10619 + new->fl_lmops = fl->fl_lmops;
10620 ++ new->fl_xid = fl->fl_xid;
10621 +
10622 + locks_copy_private(new, fl);
10623 + }
10624 +@@ -282,6 +289,11 @@ static int flock_make_lock(struct file *
10625 + fl->fl_flags = FL_FLOCK;
10626 + fl->fl_type = type;
10627 + fl->fl_end = OFFSET_MAX;
10628 ++
10629 ++ vxd_assert(filp->f_xid == vx_current_xid(),
10630 ++ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
10631 ++ fl->fl_xid = filp->f_xid;
10632 ++ vx_locks_inc(fl);
10633 +
10634 + *lock = fl;
10635 + return 0;
10636 +@@ -447,6 +459,7 @@ static int lease_init(struct file *filp,
10637 +
10638 + fl->fl_owner = current->files;
10639 + fl->fl_pid = current->tgid;
10640 ++ fl->fl_xid = vx_current_xid();
10641 +
10642 + fl->fl_file = filp;
10643 + fl->fl_flags = FL_LEASE;
10644 +@@ -466,6 +479,11 @@ static int lease_alloc(struct file *filp
10645 + if (fl == NULL)
10646 + goto out;
10647 +
10648 ++ fl->fl_xid = vx_current_xid();
10649 ++ if (filp)
10650 ++ vxd_assert(filp->f_xid == fl->fl_xid,
10651 ++ "f_xid(%d) == fl_xid(%d)", filp->f_xid, fl->fl_xid);
10652 ++ vx_locks_inc(fl);
10653 + error = lease_init(filp, type, fl);
10654 + if (error) {
10655 + locks_free_lock(fl);
10656 +@@ -769,6 +787,7 @@ static int flock_lock_file(struct file *
10657 + if (found)
10658 + cond_resched();
10659 +
10660 ++ new_fl->fl_xid = -1;
10661 + find_conflict:
10662 + for_each_lock(inode, before) {
10663 + struct file_lock *fl = *before;
10664 +@@ -787,6 +806,7 @@ find_conflict:
10665 + goto out;
10666 + locks_copy_lock(new_fl, request);
10667 + locks_insert_lock(before, new_fl);
10668 ++ vx_locks_inc(new_fl);
10669 + new_fl = NULL;
10670 + error = 0;
10671 +
10672 +@@ -797,7 +817,8 @@ out:
10673 + return error;
10674 + }
10675 +
10676 +-static int __posix_lock_file(struct inode *inode, struct file_lock *request, struct file_lock *conflock)
10677 ++static int __posix_lock_file(struct inode *inode, struct file_lock *request,
10678 ++ struct file_lock *conflock, xid_t xid)
10679 + {
10680 + struct file_lock *fl;
10681 + struct file_lock *new_fl = NULL;
10682 +@@ -807,6 +828,8 @@ static int __posix_lock_file(struct inod
10683 + struct file_lock **before;
10684 + int error, added = 0;
10685 +
10686 ++ vxd_assert(xid == vx_current_xid(),
10687 ++ "xid(%d) == current(%d)", xid, vx_current_xid());
10688 + /*
10689 + * We may need two file_lock structures for this operation,
10690 + * so we get them in advance to avoid races.
10691 +@@ -817,7 +840,11 @@ static int __posix_lock_file(struct inod
10692 + (request->fl_type != F_UNLCK ||
10693 + request->fl_start != 0 || request->fl_end != OFFSET_MAX)) {
10694 + new_fl = locks_alloc_lock();
10695 ++ new_fl->fl_xid = xid;
10696 ++ vx_locks_inc(new_fl);
10697 + new_fl2 = locks_alloc_lock();
10698 ++ new_fl2->fl_xid = xid;
10699 ++ vx_locks_inc(new_fl2);
10700 + }
10701 +
10702 + lock_kernel();
10703 +@@ -1016,7 +1043,8 @@ static int __posix_lock_file(struct inod
10704 + int posix_lock_file(struct file *filp, struct file_lock *fl,
10705 + struct file_lock *conflock)
10706 + {
10707 +- return __posix_lock_file(filp->f_path.dentry->d_inode, fl, conflock);
10708 ++ return __posix_lock_file(filp->f_path.dentry->d_inode,
10709 ++ fl, conflock, filp->f_xid);
10710 + }
10711 + EXPORT_SYMBOL(posix_lock_file);
10712 +
10713 +@@ -1106,7 +1134,7 @@ int locks_mandatory_area(int read_write,
10714 + fl.fl_end = offset + count - 1;
10715 +
10716 + for (;;) {
10717 +- error = __posix_lock_file(inode, &fl, NULL);
10718 ++ error = __posix_lock_file(inode, &fl, NULL, filp->f_xid);
10719 + if (error != -EAGAIN)
10720 + break;
10721 + if (!(fl.fl_flags & FL_SLEEP))
10722 +@@ -1410,8 +1438,8 @@ static int __setlease(struct file *filp,
10723 + goto out;
10724 +
10725 + locks_copy_lock(fl, lease);
10726 +-
10727 + locks_insert_lock(before, fl);
10728 ++ vx_locks_inc(fl);
10729 +
10730 + *flp = fl;
10731 + error = 0;
10732 +@@ -1738,6 +1766,11 @@ int fcntl_setlk(unsigned int fd, struct
10733 + if (file_lock == NULL)
10734 + return -ENOLCK;
10735 +
10736 ++ vxd_assert(filp->f_xid == vx_current_xid(),
10737 ++ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
10738 ++ file_lock->fl_xid = filp->f_xid;
10739 ++ vx_locks_inc(file_lock);
10740 ++
10741 + /*
10742 + * This might block, so we do it before checking the inode.
10743 + */
10744 +@@ -1864,6 +1897,11 @@ int fcntl_setlk64(unsigned int fd, struc
10745 + if (file_lock == NULL)
10746 + return -ENOLCK;
10747 +
10748 ++ vxd_assert(filp->f_xid == vx_current_xid(),
10749 ++ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
10750 ++ file_lock->fl_xid = filp->f_xid;
10751 ++ vx_locks_inc(file_lock);
10752 ++
10753 + /*
10754 + * This might block, so we do it before checking the inode.
10755 + */
10756 +@@ -2168,6 +2206,10 @@ int get_locks_status(char *buffer, char
10757 + list_for_each(tmp, &file_lock_list) {
10758 + struct list_head *btmp;
10759 + struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);
10760 ++
10761 ++ if (!vx_check(fl->fl_xid, VS_WATCH_P | VS_IDENT))
10762 ++ continue;
10763 ++
10764 + lock_get_status(q, fl, ++i, "");
10765 + move_lock_status(&q, &pos, offset);
10766 +
10767 +diff -NurpP --minimal linux-2.6.22.19/fs/namei.c linux-2.6.22.19-vs2.2.0.7/fs/namei.c
10768 +--- linux-2.6.22.19/fs/namei.c 2008-03-14 20:19:03 +0100
10769 ++++ linux-2.6.22.19-vs2.2.0.7/fs/namei.c 2008-01-18 12:59:22 +0100
10770 +@@ -31,6 +31,12 @@
10771 + #include <linux/file.h>
10772 + #include <linux/fcntl.h>
10773 + #include <linux/namei.h>
10774 ++#include <linux/proc_fs.h>
10775 ++#include <linux/vserver/inode.h>
10776 ++#include <linux/vs_base.h>
10777 ++#include <linux/vs_tag.h>
10778 ++#include <linux/vs_cowbl.h>
10779 ++#include <linux/vs_context.h>
10780 + #include <asm/namei.h>
10781 + #include <asm/uaccess.h>
10782 +
10783 +@@ -224,6 +230,29 @@ int generic_permission(struct inode *ino
10784 + return -EACCES;
10785 + }
10786 +
10787 ++static inline int dx_barrier(struct inode *inode)
10788 ++{
10789 ++ if (IS_BARRIER(inode) && !vx_check(0, VS_ADMIN)) {
10790 ++ vxwprintk_task(1, "did hit the barrier.");
10791 ++ return 1;
10792 ++ }
10793 ++ return 0;
10794 ++}
10795 ++
10796 ++static inline int dx_permission(struct inode *inode, int mask, struct nameidata *nd)
10797 ++{
10798 ++ if (dx_barrier(inode))
10799 ++ return -EACCES;
10800 ++ if (inode->i_tag == 0)
10801 ++ return 0;
10802 ++ if (dx_check(inode->i_tag, DX_ADMIN|DX_WATCH|DX_IDENT))
10803 ++ return 0;
10804 ++
10805 ++ vxwprintk_task(1, "denied access to %p[#%d,%lu] »%s«.",
10806 ++ inode, inode->i_tag, inode->i_ino, vxd_cond_path(nd));
10807 ++ return -EACCES;
10808 ++}
10809 ++
10810 + int permission(struct inode *inode, int mask, struct nameidata *nd)
10811 + {
10812 + umode_t mode = inode->i_mode;
10813 +@@ -234,14 +263,14 @@ int permission(struct inode *inode, int
10814 + /*
10815 + * Nobody gets write access to a read-only fs.
10816 + */
10817 +- if (IS_RDONLY(inode) &&
10818 ++ if ((IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))) &&
10819 + (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
10820 + return -EROFS;
10821 +
10822 + /*
10823 + * Nobody gets write access to an immutable file.
10824 + */
10825 +- if (IS_IMMUTABLE(inode))
10826 ++ if (IS_IMMUTABLE(inode) && !IS_COW(inode))
10827 + return -EACCES;
10828 + }
10829 +
10830 +@@ -257,6 +286,8 @@ int permission(struct inode *inode, int
10831 +
10832 + /* Ordinary permission routines do not understand MAY_APPEND. */
10833 + submask = mask & ~MAY_APPEND;
10834 ++ if ((retval = dx_permission(inode, mask, nd)))
10835 ++ return retval;
10836 + if (inode->i_op && inode->i_op->permission)
10837 + retval = inode->i_op->permission(inode, submask, nd);
10838 + else
10839 +@@ -432,6 +463,8 @@ static int exec_permission_lite(struct i
10840 + {
10841 + umode_t mode = inode->i_mode;
10842 +
10843 ++ if (dx_barrier(inode))
10844 ++ return -EACCES;
10845 + if (inode->i_op && inode->i_op->permission)
10846 + return -EAGAIN;
10847 +
10848 +@@ -732,7 +765,8 @@ static __always_inline void follow_dotdo
10849 + if (nd->dentry == fs->root &&
10850 + nd->mnt == fs->rootmnt) {
10851 + read_unlock(&fs->lock);
10852 +- break;
10853 ++ /* for sane '/' avoid follow_mount() */
10854 ++ return;
10855 + }
10856 + read_unlock(&fs->lock);
10857 + spin_lock(&dcache_lock);
10858 +@@ -769,16 +803,33 @@ static int do_lookup(struct nameidata *n
10859 + {
10860 + struct vfsmount *mnt = nd->mnt;
10861 + struct dentry *dentry = __d_lookup(nd->dentry, name);
10862 ++ struct inode *inode;
10863 +
10864 + if (!dentry)
10865 + goto need_lookup;
10866 + if (dentry->d_op && dentry->d_op->d_revalidate)
10867 + goto need_revalidate;
10868 ++ inode = dentry->d_inode;
10869 ++ if (!inode)
10870 ++ goto done;
10871 ++ if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) {
10872 ++ struct proc_dir_entry *de = PDE(inode);
10873 ++
10874 ++ if (de && !vx_hide_check(0, de->vx_flags))
10875 ++ goto hidden;
10876 ++ }
10877 ++ if (!dx_check(inode->i_tag, DX_WATCH|DX_ADMIN|DX_HOSTID|DX_IDENT))
10878 ++ goto hidden;
10879 + done:
10880 + path->mnt = mnt;
10881 + path->dentry = dentry;
10882 + __follow_mount(path);
10883 + return 0;
10884 ++hidden:
10885 ++ vxwprintk_task(1, "did lookup hidden %p[#%d,%lu] »%s«.",
10886 ++ inode, inode->i_tag, inode->i_ino, vxd_path(dentry, mnt));
10887 ++ dput(dentry);
10888 ++ return -ENOENT;
10889 +
10890 + need_lookup:
10891 + dentry = real_lookup(nd->dentry, name, nd);
10892 +@@ -1399,7 +1450,8 @@ static inline int check_sticky(struct in
10893 + * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
10894 + * nfs_async_unlink().
10895 + */
10896 +-static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
10897 ++static int may_delete(struct inode *dir, struct dentry *victim,
10898 ++ int isdir, struct nameidata *nd)
10899 + {
10900 + int error;
10901 +
10902 +@@ -1409,13 +1461,13 @@ static int may_delete(struct inode *dir,
10903 + BUG_ON(victim->d_parent->d_inode != dir);
10904 + audit_inode_child(victim->d_name.name, victim->d_inode, dir);
10905 +
10906 +- error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
10907 ++ error = permission(dir,MAY_WRITE | MAY_EXEC, nd);
10908 + if (error)
10909 + return error;
10910 + if (IS_APPEND(dir))
10911 + return -EPERM;
10912 + if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
10913 +- IS_IMMUTABLE(victim->d_inode))
10914 ++ IS_IXORUNLINK(victim->d_inode))
10915 + return -EPERM;
10916 + if (isdir) {
10917 + if (!S_ISDIR(victim->d_inode->i_mode))
10918 +@@ -1546,6 +1598,14 @@ int may_open(struct nameidata *nd, int a
10919 + if (S_ISDIR(inode->i_mode) && (acc_mode & MAY_WRITE))
10920 + return -EISDIR;
10921 +
10922 ++#ifdef CONFIG_VSERVER_COWBL
10923 ++ if (IS_COW(inode) && (acc_mode & MAY_WRITE)) {
10924 ++ if (IS_COW_LINK(inode))
10925 ++ return -EMLINK;
10926 ++ inode->i_flags &= ~(S_IUNLINK|S_IMMUTABLE);
10927 ++ mark_inode_dirty(inode);
10928 ++ }
10929 ++#endif
10930 + error = vfs_permission(nd, acc_mode);
10931 + if (error)
10932 + return error;
10933 +@@ -1562,7 +1622,8 @@ int may_open(struct nameidata *nd, int a
10934 + return -EACCES;
10935 +
10936 + flag &= ~O_TRUNC;
10937 +- } else if (IS_RDONLY(inode) && (acc_mode & MAY_WRITE))
10938 ++ } else if ((IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt))
10939 ++ && (acc_mode & MAY_WRITE))
10940 + return -EROFS;
10941 + /*
10942 + * An append-only file must be opened in append mode for writing.
10943 +@@ -1650,6 +1711,11 @@ int open_namei(int dfd, const char *path
10944 + struct dentry *dir;
10945 + int count = 0;
10946 +
10947 ++#ifdef CONFIG_VSERVER_COWBL
10948 ++ int rflag = flag;
10949 ++ int rmode = mode;
10950 ++restart:
10951 ++#endif
10952 + acc_mode = ACC_MODE(flag);
10953 +
10954 + /* O_TRUNC implies we need access checks for write permissions */
10955 +@@ -1743,6 +1809,22 @@ do_last:
10956 + goto exit;
10957 + ok:
10958 + error = may_open(nd, acc_mode, flag);
10959 ++#ifdef CONFIG_VSERVER_COWBL
10960 ++ if (error == -EMLINK) {
10961 ++ struct dentry *dentry;
10962 ++ dentry = cow_break_link(pathname);
10963 ++ if (IS_ERR(dentry)) {
10964 ++ error = PTR_ERR(dentry);
10965 ++ goto exit;
10966 ++ }
10967 ++ dput(dentry);
10968 ++ release_open_intent(nd);
10969 ++ path_release(nd);
10970 ++ flag = rflag;
10971 ++ mode = rmode;
10972 ++ goto restart;
10973 ++ }
10974 ++#endif
10975 + if (error)
10976 + goto exit;
10977 + return 0;
10978 +@@ -1854,9 +1936,10 @@ fail:
10979 + }
10980 + EXPORT_SYMBOL_GPL(lookup_create);
10981 +
10982 +-int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
10983 ++int vfs_mknod(struct inode *dir, struct dentry *dentry,
10984 ++ int mode, dev_t dev, struct nameidata *nd)
10985 + {
10986 +- int error = may_create(dir, dentry, NULL);
10987 ++ int error = may_create(dir, dentry, nd);
10988 +
10989 + if (error)
10990 + return error;
10991 +@@ -1906,11 +1989,12 @@ asmlinkage long sys_mknodat(int dfd, con
10992 + error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
10993 + break;
10994 + case S_IFCHR: case S_IFBLK:
10995 +- error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
10996 +- new_decode_dev(dev));
10997 ++ error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
10998 ++ new_decode_dev(dev), &nd);
10999 + break;
11000 + case S_IFIFO: case S_IFSOCK:
11001 +- error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
11002 ++ error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
11003 ++ 0, &nd);
11004 + break;
11005 + case S_IFDIR:
11006 + error = -EPERM;
11007 +@@ -1933,9 +2017,10 @@ asmlinkage long sys_mknod(const char __u
11008 + return sys_mknodat(AT_FDCWD, filename, mode, dev);
11009 + }
11010 +
11011 +-int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
11012 ++int vfs_mkdir(struct inode *dir, struct dentry *dentry,
11013 ++ int mode, struct nameidata *nd)
11014 + {
11015 +- int error = may_create(dir, dentry, NULL);
11016 ++ int error = may_create(dir, dentry, nd);
11017 +
11018 + if (error)
11019 + return error;
11020 +@@ -1977,7 +2062,7 @@ asmlinkage long sys_mkdirat(int dfd, con
11021 +
11022 + if (!IS_POSIXACL(nd.dentry->d_inode))
11023 + mode &= ~current->fs->umask;
11024 +- error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
11025 ++ error = vfs_mkdir(nd.dentry->d_inode, dentry, mode, &nd);
11026 + dput(dentry);
11027 + out_unlock:
11028 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
11029 +@@ -2020,9 +2105,10 @@ void dentry_unhash(struct dentry *dentry
11030 + spin_unlock(&dcache_lock);
11031 + }
11032 +
11033 +-int vfs_rmdir(struct inode *dir, struct dentry *dentry)
11034 ++int vfs_rmdir(struct inode *dir, struct dentry *dentry,
11035 ++ struct nameidata *nd)
11036 + {
11037 +- int error = may_delete(dir, dentry, 1);
11038 ++ int error = may_delete(dir, dentry, 1, nd);
11039 +
11040 + if (error)
11041 + return error;
11042 +@@ -2084,7 +2170,7 @@ static long do_rmdir(int dfd, const char
11043 + error = PTR_ERR(dentry);
11044 + if (IS_ERR(dentry))
11045 + goto exit2;
11046 +- error = vfs_rmdir(nd.dentry->d_inode, dentry);
11047 ++ error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
11048 + dput(dentry);
11049 + exit2:
11050 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
11051 +@@ -2100,9 +2186,10 @@ asmlinkage long sys_rmdir(const char __u
11052 + return do_rmdir(AT_FDCWD, pathname);
11053 + }
11054 +
11055 +-int vfs_unlink(struct inode *dir, struct dentry *dentry)
11056 ++int vfs_unlink(struct inode *dir, struct dentry *dentry,
11057 ++ struct nameidata *nd)
11058 + {
11059 +- int error = may_delete(dir, dentry, 0);
11060 ++ int error = may_delete(dir, dentry, 0, nd);
11061 +
11062 + if (error)
11063 + return error;
11064 +@@ -2164,7 +2251,7 @@ static long do_unlinkat(int dfd, const c
11065 + inode = dentry->d_inode;
11066 + if (inode)
11067 + atomic_inc(&inode->i_count);
11068 +- error = vfs_unlink(nd.dentry->d_inode, dentry);
11069 ++ error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
11070 + exit2:
11071 + dput(dentry);
11072 + }
11073 +@@ -2199,9 +2286,10 @@ asmlinkage long sys_unlink(const char __
11074 + return do_unlinkat(AT_FDCWD, pathname);
11075 + }
11076 +
11077 +-int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)
11078 ++int vfs_symlink(struct inode *dir, struct dentry *dentry,
11079 ++ const char *oldname, int mode, struct nameidata *nd)
11080 + {
11081 +- int error = may_create(dir, dentry, NULL);
11082 ++ int error = may_create(dir, dentry, nd);
11083 +
11084 + if (error)
11085 + return error;
11086 +@@ -2245,7 +2333,7 @@ asmlinkage long sys_symlinkat(const char
11087 + if (IS_ERR(dentry))
11088 + goto out_unlock;
11089 +
11090 +- error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
11091 ++ error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO, &nd);
11092 + dput(dentry);
11093 + out_unlock:
11094 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
11095 +@@ -2262,7 +2350,8 @@ asmlinkage long sys_symlink(const char _
11096 + return sys_symlinkat(oldname, AT_FDCWD, newname);
11097 + }
11098 +
11099 +-int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
11100 ++int vfs_link(struct dentry *old_dentry, struct inode *dir,
11101 ++ struct dentry *new_dentry, struct nameidata *nd)
11102 + {
11103 + struct inode *inode = old_dentry->d_inode;
11104 + int error;
11105 +@@ -2270,7 +2359,7 @@ int vfs_link(struct dentry *old_dentry,
11106 + if (!inode)
11107 + return -ENOENT;
11108 +
11109 +- error = may_create(dir, new_dentry, NULL);
11110 ++ error = may_create(dir, new_dentry, nd);
11111 + if (error)
11112 + return error;
11113 +
11114 +@@ -2280,7 +2369,7 @@ int vfs_link(struct dentry *old_dentry,
11115 + /*
11116 + * A link to an append-only or immutable file cannot be created.
11117 + */
11118 +- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
11119 ++ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
11120 + return -EPERM;
11121 + if (!dir->i_op || !dir->i_op->link)
11122 + return -EPERM;
11123 +@@ -2340,7 +2429,7 @@ asmlinkage long sys_linkat(int olddfd, c
11124 + error = PTR_ERR(new_dentry);
11125 + if (IS_ERR(new_dentry))
11126 + goto out_unlock;
11127 +- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
11128 ++ error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry, &nd);
11129 + dput(new_dentry);
11130 + out_unlock:
11131 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
11132 +@@ -2472,14 +2561,14 @@ int vfs_rename(struct inode *old_dir, st
11133 + if (old_dentry->d_inode == new_dentry->d_inode)
11134 + return 0;
11135 +
11136 +- error = may_delete(old_dir, old_dentry, is_dir);
11137 ++ error = may_delete(old_dir, old_dentry, is_dir, NULL);
11138 + if (error)
11139 + return error;
11140 +
11141 + if (!new_dentry->d_inode)
11142 + error = may_create(new_dir, new_dentry, NULL);
11143 + else
11144 +- error = may_delete(new_dir, new_dentry, is_dir);
11145 ++ error = may_delete(new_dir, new_dentry, is_dir, NULL);
11146 + if (error)
11147 + return error;
11148 +
11149 +@@ -2557,6 +2646,9 @@ static int do_rename(int olddfd, const c
11150 + error = -EINVAL;
11151 + if (old_dentry == trap)
11152 + goto exit4;
11153 ++ error = -EROFS;
11154 ++ if (MNT_IS_RDONLY(newnd.mnt))
11155 ++ goto exit4;
11156 + new_dentry = lookup_hash(&newnd);
11157 + error = PTR_ERR(new_dentry);
11158 + if (IS_ERR(new_dentry))
11159 +@@ -2650,6 +2742,217 @@ int vfs_follow_link(struct nameidata *nd
11160 + return __vfs_follow_link(nd, link);
11161 + }
11162 +
11163 ++
11164 ++#ifdef CONFIG_VSERVER_COWBL
11165 ++
11166 ++#include <linux/file.h>
11167 ++
11168 ++static inline
11169 ++long do_cow_splice(struct file *in, struct file *out, size_t len)
11170 ++{
11171 ++ loff_t ppos = 0;
11172 ++
11173 ++ return do_splice_direct(in, &ppos, out, len, 0);
11174 ++}
11175 ++
11176 ++struct dentry *cow_break_link(const char *pathname)
11177 ++{
11178 ++ int ret, mode, pathlen, redo = 0;
11179 ++ struct nameidata old_nd, dir_nd;
11180 ++ struct dentry *old_dentry, *new_dentry;
11181 ++ struct dentry *dir, *res = NULL;
11182 ++ struct vfsmount *old_mnt, *new_mnt;
11183 ++ struct file *old_file;
11184 ++ struct file *new_file;
11185 ++ char *to, *path, pad='\251';
11186 ++ loff_t ppos, size;
11187 ++
11188 ++ vxdprintk(VXD_CBIT(misc, 1), "cow_break_link(»%s«)", pathname);
11189 ++ path = kmalloc(PATH_MAX, GFP_KERNEL);
11190 ++ ret = -ENOMEM;
11191 ++ if (!path)
11192 ++ goto out;
11193 ++
11194 ++ /* old_nd will have refs to dentry and mnt */
11195 ++ ret = path_lookup(pathname, LOOKUP_FOLLOW, &old_nd);
11196 ++ vxdprintk(VXD_CBIT(misc, 2), "path_lookup(old): %d", ret);
11197 ++ if (ret < 0)
11198 ++ goto out_free_path;
11199 ++
11200 ++ old_dentry = old_nd.dentry;
11201 ++ old_mnt = old_nd.mnt;
11202 ++ mode = old_dentry->d_inode->i_mode;
11203 ++
11204 ++ to = d_path(old_dentry, old_mnt, path, PATH_MAX-2);
11205 ++ pathlen = strlen(to);
11206 ++ vxdprintk(VXD_CBIT(misc, 2), "old path »%s« [»%.*s«:%d]", to,
11207 ++ old_dentry->d_name.len, old_dentry->d_name.name,
11208 ++ old_dentry->d_name.len);
11209 ++
11210 ++ to[pathlen + 1] = 0;
11211 ++retry:
11212 ++ to[pathlen] = pad--;
11213 ++ ret = -EMLINK;
11214 ++ if (pad <= '\240')
11215 ++ goto out_rel_old;
11216 ++
11217 ++ vxdprintk(VXD_CBIT(misc, 1), "temp copy »%s«", to);
11218 ++ /* dir_nd will have refs to dentry and mnt */
11219 ++ ret = path_lookup(to,
11220 ++ LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE, &dir_nd);
11221 ++ vxdprintk(VXD_CBIT(misc, 2),
11222 ++ "path_lookup(new): %d", ret);
11223 ++ if (ret < 0)
11224 ++ goto retry;
11225 ++
11226 ++ /* this puppy downs the inode mutex */
11227 ++ new_dentry = lookup_create(&dir_nd, 0);
11228 ++ vxdprintk(VXD_CBIT(misc, 2),
11229 ++ "lookup_create(new): %p [»%.*s«:%d]", new_dentry,
11230 ++ new_dentry->d_name.len, new_dentry->d_name.name,
11231 ++ new_dentry->d_name.len);
11232 ++ if (!new_dentry || IS_ERR(new_dentry)) {
11233 ++ path_release(&dir_nd);
11234 ++ goto retry;
11235 ++ }
11236 ++ dir = dir_nd.dentry;
11237 ++
11238 ++ ret = vfs_create(dir_nd.dentry->d_inode, new_dentry, mode, &dir_nd);
11239 ++ vxdprintk(VXD_CBIT(misc, 2),
11240 ++ "vfs_create(new): %d", ret);
11241 ++ if (ret == -EEXIST) {
11242 ++ mutex_unlock(&dir->d_inode->i_mutex);
11243 ++ dput(new_dentry);
11244 ++ path_release(&dir_nd);
11245 ++ goto retry;
11246 ++ }
11247 ++ else if (ret < 0)
11248 ++ goto out_unlock_new;
11249 ++
11250 ++ /* drop out early, ret passes ENOENT */
11251 ++ ret = -ENOENT;
11252 ++ if ((redo = d_unhashed(old_dentry)))
11253 ++ goto out_unlock_new;
11254 ++
11255 ++ new_mnt = dir_nd.mnt;
11256 ++ dget(old_dentry);
11257 ++ mntget(old_mnt);
11258 ++ /* this one cleans up the dentry/mnt in case of failure */
11259 ++ old_file = dentry_open(old_dentry, old_mnt, O_RDONLY);
11260 ++ vxdprintk(VXD_CBIT(misc, 2),
11261 ++ "dentry_open(old): %p", old_file);
11262 ++ if (!old_file || IS_ERR(old_file)) {
11263 ++ res = IS_ERR(old_file) ? (void *) old_file : res;
11264 ++ goto out_unlock_new;
11265 ++ }
11266 ++
11267 ++ dget(new_dentry);
11268 ++ mntget(new_mnt);
11269 ++ /* this one cleans up the dentry/mnt in case of failure */
11270 ++ new_file = dentry_open(new_dentry, new_mnt, O_WRONLY);
11271 ++ vxdprintk(VXD_CBIT(misc, 2),
11272 ++ "dentry_open(new): %p", new_file);
11273 ++
11274 ++ ret = IS_ERR(new_file) ? PTR_ERR(new_file) : -ENOENT;
11275 ++ if (!new_file || IS_ERR(new_file))
11276 ++ goto out_fput_old;
11277 ++
11278 ++ size = i_size_read(old_file->f_dentry->d_inode);
11279 ++ ppos = 0;
11280 ++ ret = do_cow_splice(old_file, new_file, size);
11281 ++ vxdprintk(VXD_CBIT(misc, 2), "do_splice_direct: %d", ret);
11282 ++ if (ret < 0) {
11283 ++ goto out_fput_both;
11284 ++ } else if (ret < size) {
11285 ++ ret = -ENOSPC;
11286 ++ goto out_fput_both;
11287 ++ } else {
11288 ++ struct inode *old_inode = old_dentry->d_inode;
11289 ++ struct inode *new_inode = new_dentry->d_inode;
11290 ++ struct iattr attr = {
11291 ++ .ia_uid = old_inode->i_uid,
11292 ++ .ia_gid = old_inode->i_gid,
11293 ++ .ia_valid = ATTR_UID | ATTR_GID
11294 ++ };
11295 ++
11296 ++ ret = inode_setattr(new_inode, &attr);
11297 ++ if (ret)
11298 ++ goto out_fput_both;
11299 ++ }
11300 ++
11301 ++ mutex_lock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
11302 ++
11303 ++ /* drop out late */
11304 ++ ret = -ENOENT;
11305 ++ if ((redo = d_unhashed(old_dentry)))
11306 ++ goto out_unlock;
11307 ++
11308 ++ vxdprintk(VXD_CBIT(misc, 2),
11309 ++ "vfs_rename: [»%*s«:%d] -> [»%*s«:%d]",
11310 ++ new_dentry->d_name.len, new_dentry->d_name.name,
11311 ++ new_dentry->d_name.len,
11312 ++ old_dentry->d_name.len, old_dentry->d_name.name,
11313 ++ old_dentry->d_name.len);
11314 ++ ret = vfs_rename(dir_nd.dentry->d_inode, new_dentry,
11315 ++ old_nd.dentry->d_parent->d_inode, old_dentry);
11316 ++ vxdprintk(VXD_CBIT(misc, 2), "vfs_rename: %d", ret);
11317 ++ res = new_dentry;
11318 ++
11319 ++out_unlock:
11320 ++ mutex_unlock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
11321 ++
11322 ++out_fput_both:
11323 ++ vxdprintk(VXD_CBIT(misc, 3),
11324 ++ "fput(new_file=%p[#%d])", new_file,
11325 ++ atomic_read(&new_file->f_count));
11326 ++ fput(new_file);
11327 ++
11328 ++out_fput_old:
11329 ++ vxdprintk(VXD_CBIT(misc, 3),
11330 ++ "fput(old_file=%p[#%d])", old_file,
11331 ++ atomic_read(&old_file->f_count));
11332 ++ fput(old_file);
11333 ++
11334 ++out_unlock_new:
11335 ++ mutex_unlock(&dir->d_inode->i_mutex);
11336 ++ if (!ret)
11337 ++ goto out_redo;
11338 ++
11339 ++ /* error path cleanup */
11340 ++ vfs_unlink(dir->d_inode, new_dentry, &dir_nd);
11341 ++ dput(new_dentry);
11342 ++
11343 ++out_redo:
11344 ++ if (!redo)
11345 ++ goto out_rel_both;
11346 ++ /* lookup dentry once again */
11347 ++ path_release(&old_nd);
11348 ++ ret = path_lookup(pathname, LOOKUP_FOLLOW, &old_nd);
11349 ++ if (ret)
11350 ++ goto out_rel_both;
11351 ++
11352 ++ new_dentry = old_nd.dentry;
11353 ++ vxdprintk(VXD_CBIT(misc, 2),
11354 ++ "path_lookup(redo): %p [»%.*s«:%d]", new_dentry,
11355 ++ new_dentry->d_name.len, new_dentry->d_name.name,
11356 ++ new_dentry->d_name.len);
11357 ++ dget(new_dentry);
11358 ++ res = new_dentry;
11359 ++
11360 ++out_rel_both:
11361 ++ path_release(&dir_nd);
11362 ++out_rel_old:
11363 ++ path_release(&old_nd);
11364 ++out_free_path:
11365 ++ kfree(path);
11366 ++out:
11367 ++ if (ret)
11368 ++ res = ERR_PTR(ret);
11369 ++ return res;
11370 ++}
11371 ++
11372 ++#endif
11373 ++
11374 + /* get the link contents into pagecache */
11375 + static char *page_getlink(struct dentry * dentry, struct page **ppage)
11376 + {
11377 +diff -NurpP --minimal linux-2.6.22.19/fs/namespace.c linux-2.6.22.19-vs2.2.0.7/fs/namespace.c
11378 +--- linux-2.6.22.19/fs/namespace.c 2007-07-09 13:19:27 +0200
11379 ++++ linux-2.6.22.19-vs2.2.0.7/fs/namespace.c 2007-06-15 03:24:51 +0200
11380 +@@ -25,6 +25,11 @@
11381 + #include <linux/security.h>
11382 + #include <linux/mount.h>
11383 + #include <linux/ramfs.h>
11384 ++#include <linux/vs_base.h>
11385 ++#include <linux/vs_context.h>
11386 ++#include <linux/vs_tag.h>
11387 ++#include <linux/vserver/space.h>
11388 ++#include <linux/vserver/global.h>
11389 + #include <asm/uaccess.h>
11390 + #include <asm/unistd.h>
11391 + #include "pnode.h"
11392 +@@ -240,6 +245,7 @@ static struct vfsmount *clone_mnt(struct
11393 + mnt->mnt_root = dget(root);
11394 + mnt->mnt_mountpoint = mnt->mnt_root;
11395 + mnt->mnt_parent = mnt;
11396 ++ mnt->mnt_tag = old->mnt_tag;
11397 +
11398 + if (flag & CL_SLAVE) {
11399 + list_add(&mnt->mnt_slave, &old->mnt_slave_list);
11400 +@@ -348,48 +354,91 @@ static inline void mangle(struct seq_fil
11401 + seq_escape(m, s, " \t\n\\");
11402 + }
11403 +
11404 ++static int mnt_is_reachable(struct vfsmount *mnt)
11405 ++{
11406 ++ struct vfsmount *root_mnt;
11407 ++ struct dentry *root, *point;
11408 ++ int ret;
11409 ++
11410 ++ if (mnt == mnt->mnt_ns->root)
11411 ++ return 1;
11412 ++
11413 ++ spin_lock(&vfsmount_lock);
11414 ++ root_mnt = current->fs->rootmnt;
11415 ++ root = current->fs->root;
11416 ++ point = root;
11417 ++
11418 ++ while ((mnt != mnt->mnt_parent) && (mnt != root_mnt)) {
11419 ++ point = mnt->mnt_mountpoint;
11420 ++ mnt = mnt->mnt_parent;
11421 ++ }
11422 ++
11423 ++ ret = (mnt == root_mnt) && is_subdir(point, root);
11424 ++
11425 ++ spin_unlock(&vfsmount_lock);
11426 ++
11427 ++ return ret;
11428 ++}
11429 ++
11430 + static int show_vfsmnt(struct seq_file *m, void *v)
11431 + {
11432 + struct vfsmount *mnt = v;
11433 + int err = 0;
11434 + static struct proc_fs_info {
11435 +- int flag;
11436 +- char *str;
11437 ++ int s_flag;
11438 ++ int mnt_flag;
11439 ++ char *set_str;
11440 ++ char *unset_str;
11441 + } fs_info[] = {
11442 +- { MS_SYNCHRONOUS, ",sync" },
11443 +- { MS_DIRSYNC, ",dirsync" },
11444 +- { MS_MANDLOCK, ",mand" },
11445 +- { 0, NULL }
11446 +- };
11447 +- static struct proc_fs_info mnt_info[] = {
11448 +- { MNT_NOSUID, ",nosuid" },
11449 +- { MNT_NODEV, ",nodev" },
11450 +- { MNT_NOEXEC, ",noexec" },
11451 +- { MNT_NOATIME, ",noatime" },
11452 +- { MNT_NODIRATIME, ",nodiratime" },
11453 +- { MNT_RELATIME, ",relatime" },
11454 +- { 0, NULL }
11455 ++ { MS_RDONLY, MNT_RDONLY, "ro", "rw" },
11456 ++ { MS_SYNCHRONOUS, 0, ",sync", NULL },
11457 ++ { MS_DIRSYNC, 0, ",dirsync", NULL },
11458 ++ { MS_MANDLOCK, 0, ",mand", NULL },
11459 ++ { MS_TAGGED, 0, ",tag", NULL },
11460 ++ { MS_NOATIME, MNT_NOATIME, ",noatime", NULL },
11461 ++ { MS_NODIRATIME, MNT_NODIRATIME, ",nodiratime", NULL },
11462 ++ { MS_RELATIME, MNT_RELATIME, ",relatime", NULL },
11463 ++ { 0, MNT_NOSUID, ",nosuid", NULL },
11464 ++ { 0, MNT_NODEV, ",nodev", NULL },
11465 ++ { 0, MNT_NOEXEC, ",noexec", NULL },
11466 ++ { 0, 0, NULL, NULL }
11467 + };
11468 +- struct proc_fs_info *fs_infop;
11469 ++ struct proc_fs_info *p;
11470 ++ unsigned long s_flags = mnt->mnt_sb->s_flags;
11471 ++ int mnt_flags = mnt->mnt_flags;
11472 +
11473 +- mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
11474 +- seq_putc(m, ' ');
11475 +- seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
11476 +- seq_putc(m, ' ');
11477 +- mangle(m, mnt->mnt_sb->s_type->name);
11478 +- if (mnt->mnt_sb->s_subtype && mnt->mnt_sb->s_subtype[0]) {
11479 +- seq_putc(m, '.');
11480 +- mangle(m, mnt->mnt_sb->s_subtype);
11481 +- }
11482 +- seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
11483 +- for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
11484 +- if (mnt->mnt_sb->s_flags & fs_infop->flag)
11485 +- seq_puts(m, fs_infop->str);
11486 ++ if (vx_flags(VXF_HIDE_MOUNT, 0))
11487 ++ return 0;
11488 ++ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
11489 ++ return 0;
11490 ++
11491 ++ if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
11492 ++ mnt == current->fs->rootmnt) {
11493 ++ seq_puts(m, "/dev/root / ");
11494 ++ } else {
11495 ++ mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
11496 ++ seq_putc(m, ' ');
11497 ++ seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
11498 ++ seq_putc(m, ' ');
11499 ++
11500 ++ if (mnt->mnt_sb->s_subtype && mnt->mnt_sb->s_subtype[0]) {
11501 ++ seq_putc(m, '.');
11502 ++ mangle(m, mnt->mnt_sb->s_subtype);
11503 ++ }
11504 + }
11505 +- for (fs_infop = mnt_info; fs_infop->flag; fs_infop++) {
11506 +- if (mnt->mnt_flags & fs_infop->flag)
11507 +- seq_puts(m, fs_infop->str);
11508 ++ mangle(m, mnt->mnt_sb->s_type->name);
11509 ++ seq_putc(m, ' ');
11510 ++ for (p = fs_info; (p->s_flag | p->mnt_flag) ; p++) {
11511 ++ if ((s_flags & p->s_flag) || (mnt_flags & p->mnt_flag)) {
11512 ++ if (p->set_str)
11513 ++ seq_puts(m, p->set_str);
11514 ++ } else {
11515 ++ if (p->unset_str)
11516 ++ seq_puts(m, p->unset_str);
11517 ++ }
11518 + }
11519 ++ if (mnt->mnt_flags & MNT_TAGID)
11520 ++ seq_printf(m, ",tag=%d", mnt->mnt_tag);
11521 + if (mnt->mnt_sb->s_op->show_options)
11522 + err = mnt->mnt_sb->s_op->show_options(m, mnt);
11523 + seq_puts(m, " 0 0\n");
11524 +@@ -408,17 +457,27 @@ static int show_vfsstat(struct seq_file
11525 + struct vfsmount *mnt = v;
11526 + int err = 0;
11527 +
11528 +- /* device */
11529 +- if (mnt->mnt_devname) {
11530 +- seq_puts(m, "device ");
11531 +- mangle(m, mnt->mnt_devname);
11532 +- } else
11533 +- seq_puts(m, "no device");
11534 ++ if (vx_flags(VXF_HIDE_MOUNT, 0))
11535 ++ return 0;
11536 ++ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
11537 ++ return 0;
11538 +
11539 +- /* mount point */
11540 +- seq_puts(m, " mounted on ");
11541 +- seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
11542 +- seq_putc(m, ' ');
11543 ++ if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
11544 ++ mnt == current->fs->rootmnt) {
11545 ++ seq_puts(m, "device /dev/root mounted on / ");
11546 ++ } else {
11547 ++ /* device */
11548 ++ if (mnt->mnt_devname) {
11549 ++ seq_puts(m, "device ");
11550 ++ mangle(m, mnt->mnt_devname);
11551 ++ } else
11552 ++ seq_puts(m, "no device");
11553 ++
11554 ++ /* mount point */
11555 ++ seq_puts(m, " mounted on ");
11556 ++ seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
11557 ++ seq_putc(m, ' ');
11558 ++ }
11559 +
11560 + /* file system type */
11561 + seq_puts(m, "with fstype ");
11562 +@@ -648,7 +707,7 @@ asmlinkage long sys_umount(char __user *
11563 + goto dput_and_out;
11564 +
11565 + retval = -EPERM;
11566 +- if (!capable(CAP_SYS_ADMIN))
11567 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
11568 + goto dput_and_out;
11569 +
11570 + retval = do_umount(nd.mnt, flags);
11571 +@@ -672,7 +731,7 @@ asmlinkage long sys_oldumount(char __use
11572 +
11573 + static int mount_is_safe(struct nameidata *nd)
11574 + {
11575 +- if (capable(CAP_SYS_ADMIN))
11576 ++ if (vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
11577 + return 0;
11578 + return -EPERM;
11579 + #ifdef notyet
11580 +@@ -904,11 +963,13 @@ static int do_change_type(struct nameida
11581 + /*
11582 + * do loopback mount.
11583 + */
11584 +-static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
11585 ++static int do_loopback(struct nameidata *nd, char *old_name, tag_t tag,
11586 ++ unsigned long flags, int mnt_flags)
11587 + {
11588 + struct nameidata old_nd;
11589 + struct vfsmount *mnt = NULL;
11590 + int err = mount_is_safe(nd);
11591 ++ int recurse = flags & MS_REC;
11592 + if (err)
11593 + return err;
11594 + if (!old_name || !*old_name)
11595 +@@ -934,6 +995,12 @@ static int do_loopback(struct nameidata
11596 + if (!mnt)
11597 + goto out;
11598 +
11599 ++ mnt->mnt_flags = mnt_flags;
11600 ++ if (flags & MS_TAGID) {
11601 ++ mnt->mnt_tag = tag;
11602 ++ mnt->mnt_flags |= MNT_TAGID;
11603 ++ }
11604 ++
11605 + err = graft_tree(mnt, nd);
11606 + if (err) {
11607 + LIST_HEAD(umount_list);
11608 +@@ -942,6 +1009,7 @@ static int do_loopback(struct nameidata
11609 + spin_unlock(&vfsmount_lock);
11610 + release_mounts(&umount_list);
11611 + }
11612 ++ mnt->mnt_flags = mnt_flags;
11613 +
11614 + out:
11615 + up_write(&namespace_sem);
11616 +@@ -955,12 +1023,12 @@ out:
11617 + * on it - tough luck.
11618 + */
11619 + static int do_remount(struct nameidata *nd, int flags, int mnt_flags,
11620 +- void *data)
11621 ++ void *data, xid_t xid)
11622 + {
11623 + int err;
11624 + struct super_block *sb = nd->mnt->mnt_sb;
11625 +
11626 +- if (!capable(CAP_SYS_ADMIN))
11627 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_REMOUNT))
11628 + return -EPERM;
11629 +
11630 + if (!check_mnt(nd->mnt))
11631 +@@ -994,7 +1062,7 @@ static int do_move_mount(struct nameidat
11632 + struct nameidata old_nd, parent_nd;
11633 + struct vfsmount *p;
11634 + int err = 0;
11635 +- if (!capable(CAP_SYS_ADMIN))
11636 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
11637 + return -EPERM;
11638 + if (!old_name || !*old_name)
11639 + return -EINVAL;
11640 +@@ -1074,7 +1142,7 @@ static int do_new_mount(struct nameidata
11641 + return -EINVAL;
11642 +
11643 + /* we need capabilities... */
11644 +- if (!capable(CAP_SYS_ADMIN))
11645 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
11646 + return -EPERM;
11647 +
11648 + mnt = do_kern_mount(type, flags, name, data);
11649 +@@ -1386,6 +1454,7 @@ long do_mount(char *dev_name, char *dir_
11650 + struct nameidata nd;
11651 + int retval = 0;
11652 + int mnt_flags = 0;
11653 ++ tag_t tag = 0;
11654 +
11655 + /* Discard magic */
11656 + if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
11657 +@@ -1401,7 +1470,19 @@ long do_mount(char *dev_name, char *dir_
11658 + if (data_page)
11659 + ((char *)data_page)[PAGE_SIZE - 1] = 0;
11660 +
11661 ++#ifdef CONFIG_PROPAGATE
11662 ++ retval = dx_parse_tag(data_page, &tag, 1);
11663 ++ if (retval) {
11664 ++ mnt_flags |= MNT_TAGID;
11665 ++ /* bind and re-mounts get the tag flag */
11666 ++ if (flags & (MS_BIND|MS_REMOUNT))
11667 ++ flags |= MS_TAGID;
11668 ++ }
11669 ++#endif
11670 ++
11671 + /* Separate the per-mountpoint flags */
11672 ++ if (flags & MS_RDONLY)
11673 ++ mnt_flags |= MNT_RDONLY;
11674 + if (flags & MS_NOSUID)
11675 + mnt_flags |= MNT_NOSUID;
11676 + if (flags & MS_NODEV)
11677 +@@ -1415,6 +1496,8 @@ long do_mount(char *dev_name, char *dir_
11678 + if (flags & MS_RELATIME)
11679 + mnt_flags |= MNT_RELATIME;
11680 +
11681 ++ if (!capable(CAP_SYS_ADMIN))
11682 ++ mnt_flags |= MNT_NODEV;
11683 + flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
11684 + MS_NOATIME | MS_NODIRATIME | MS_RELATIME);
11685 +
11686 +@@ -1429,9 +1512,9 @@ long do_mount(char *dev_name, char *dir_
11687 +
11688 + if (flags & MS_REMOUNT)
11689 + retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
11690 +- data_page);
11691 ++ data_page, tag);
11692 + else if (flags & MS_BIND)
11693 +- retval = do_loopback(&nd, dev_name, flags & MS_REC);
11694 ++ retval = do_loopback(&nd, dev_name, tag, flags, mnt_flags);
11695 + else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
11696 + retval = do_change_type(&nd, flags);
11697 + else if (flags & MS_MOVE)
11698 +@@ -1504,6 +1587,7 @@ static struct mnt_namespace *dup_mnt_ns(
11699 + q = next_mnt(q, new_ns->root);
11700 + }
11701 + up_write(&namespace_sem);
11702 ++ atomic_inc(&vs_global_mnt_ns);
11703 +
11704 + if (rootmnt)
11705 + mntput(rootmnt);
11706 +@@ -1866,5 +1950,6 @@ void __put_mnt_ns(struct mnt_namespace *
11707 + spin_unlock(&vfsmount_lock);
11708 + up_write(&namespace_sem);
11709 + release_mounts(&umount_list);
11710 ++ atomic_dec(&vs_global_mnt_ns);
11711 + kfree(ns);
11712 + }
11713 +diff -NurpP --minimal linux-2.6.22.19/fs/nfs/client.c linux-2.6.22.19-vs2.2.0.7/fs/nfs/client.c
11714 +--- linux-2.6.22.19/fs/nfs/client.c 2008-03-14 20:19:03 +0100
11715 ++++ linux-2.6.22.19-vs2.2.0.7/fs/nfs/client.c 2008-03-14 19:19:48 +0100
11716 +@@ -518,6 +518,9 @@ static int nfs_init_server_rpcclient(str
11717 + if (server->flags & NFS4_MOUNT_INTR)
11718 + server->client->cl_intr = 1;
11719 +
11720 ++ server->client->cl_tag = 0;
11721 ++ if (server->flags & NFS_MOUNT_TAGGED)
11722 ++ server->client->cl_tag = 1;
11723 + return 0;
11724 + }
11725 +
11726 +@@ -665,6 +668,10 @@ static void nfs_server_set_fsinfo(struct
11727 + server->acdirmin = server->acdirmax = 0;
11728 + }
11729 +
11730 ++ /* FIXME: needs fsinfo
11731 ++ if (server->flags & NFS_MOUNT_TAGGED)
11732 ++ sb->s_flags |= MS_TAGGED; */
11733 ++
11734 + server->maxfilesize = fsinfo->maxfilesize;
11735 +
11736 + /* We're airborne Set socket buffersize */
11737 +diff -NurpP --minimal linux-2.6.22.19/fs/nfs/dir.c linux-2.6.22.19-vs2.2.0.7/fs/nfs/dir.c
11738 +--- linux-2.6.22.19/fs/nfs/dir.c 2008-03-14 20:19:03 +0100
11739 ++++ linux-2.6.22.19-vs2.2.0.7/fs/nfs/dir.c 2008-03-14 19:19:48 +0100
11740 +@@ -34,6 +34,7 @@
11741 + #include <linux/namei.h>
11742 + #include <linux/mount.h>
11743 + #include <linux/sched.h>
11744 ++#include <linux/vs_tag.h>
11745 +
11746 + #include "nfs4_fs.h"
11747 + #include "delegation.h"
11748 +@@ -955,6 +956,7 @@ static struct dentry *nfs_lookup(struct
11749 + if (IS_ERR(res))
11750 + goto out_unlock;
11751 +
11752 ++ dx_propagate_tag(nd, inode);
11753 + no_entry:
11754 + res = d_materialise_unique(dentry, inode);
11755 + if (res != NULL) {
11756 +@@ -997,7 +999,8 @@ static int is_atomic_open(struct inode *
11757 + if (nd->flags & LOOKUP_DIRECTORY)
11758 + return 0;
11759 + /* Are we trying to write to a read only partition? */
11760 +- if (IS_RDONLY(dir) && (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
11761 ++ if ((IS_RDONLY(dir) || MNT_IS_RDONLY(nd->mnt)) &&
11762 ++ (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
11763 + return 0;
11764 + return 1;
11765 + }
11766 +diff -NurpP --minimal linux-2.6.22.19/fs/nfs/inode.c linux-2.6.22.19-vs2.2.0.7/fs/nfs/inode.c
11767 +--- linux-2.6.22.19/fs/nfs/inode.c 2008-03-14 20:19:03 +0100
11768 ++++ linux-2.6.22.19-vs2.2.0.7/fs/nfs/inode.c 2008-03-14 19:19:48 +0100
11769 +@@ -37,6 +37,7 @@
11770 + #include <linux/vfs.h>
11771 + #include <linux/inet.h>
11772 + #include <linux/nfs_xdr.h>
11773 ++#include <linux/vs_tag.h>
11774 +
11775 + #include <asm/system.h>
11776 + #include <asm/uaccess.h>
11777 +@@ -285,8 +286,10 @@ nfs_fhget(struct super_block *sb, struct
11778 + nfsi->change_attr = fattr->change_attr;
11779 + inode->i_size = nfs_size_to_loff_t(fattr->size);
11780 + inode->i_nlink = fattr->nlink;
11781 +- inode->i_uid = fattr->uid;
11782 +- inode->i_gid = fattr->gid;
11783 ++ inode->i_uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
11784 ++ inode->i_gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
11785 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
11786 ++ /* maybe fattr->xid someday */
11787 + if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) {
11788 + /*
11789 + * report the blocks in 512byte units
11790 +@@ -377,6 +380,8 @@ void nfs_setattr_update_inode(struct ino
11791 + inode->i_uid = attr->ia_uid;
11792 + if ((attr->ia_valid & ATTR_GID) != 0)
11793 + inode->i_gid = attr->ia_gid;
11794 ++ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
11795 ++ inode->i_tag = attr->ia_tag;
11796 + spin_lock(&inode->i_lock);
11797 + NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
11798 + spin_unlock(&inode->i_lock);
11799 +@@ -825,6 +830,9 @@ static int nfs_check_inode_attributes(st
11800 + struct nfs_inode *nfsi = NFS_I(inode);
11801 + loff_t cur_size, new_isize;
11802 + int data_unstable;
11803 ++ uid_t uid;
11804 ++ gid_t gid;
11805 ++ tag_t tag;
11806 +
11807 +
11808 + /* Has the inode gone and changed behind our back? */
11809 +@@ -852,10 +860,15 @@ static int nfs_check_inode_attributes(st
11810 + if (cur_size != new_isize && nfsi->npages == 0)
11811 + nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
11812 +
11813 ++ uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
11814 ++ gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
11815 ++ tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
11816 ++
11817 + /* Have any file permissions changed? */
11818 + if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)
11819 +- || inode->i_uid != fattr->uid
11820 +- || inode->i_gid != fattr->gid)
11821 ++ || inode->i_uid != uid
11822 ++ || inode->i_gid != gid
11823 ++ || inode->i_tag != tag)
11824 + nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
11825 +
11826 + /* Has the link count changed? */
11827 +@@ -946,6 +959,9 @@ static int nfs_update_inode(struct inode
11828 + unsigned int invalid = 0;
11829 + unsigned long now = jiffies;
11830 + int data_stable;
11831 ++ uid_t uid;
11832 ++ gid_t gid;
11833 ++ tag_t tag;
11834 +
11835 + dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n",
11836 + __FUNCTION__, inode->i_sb->s_id, inode->i_ino,
11837 +@@ -1022,15 +1038,21 @@ static int nfs_update_inode(struct inode
11838 + }
11839 + memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
11840 +
11841 ++ uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
11842 ++ gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
11843 ++ tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
11844 ++
11845 + if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) ||
11846 +- inode->i_uid != fattr->uid ||
11847 +- inode->i_gid != fattr->gid)
11848 ++ inode->i_uid != uid ||
11849 ++ inode->i_gid != gid ||
11850 ++ inode->i_tag != tag)
11851 + invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
11852 +
11853 + inode->i_mode = fattr->mode;
11854 + inode->i_nlink = fattr->nlink;
11855 +- inode->i_uid = fattr->uid;
11856 +- inode->i_gid = fattr->gid;
11857 ++ inode->i_uid = uid;
11858 ++ inode->i_gid = gid;
11859 ++ inode->i_tag = tag;
11860 +
11861 + if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) {
11862 + /*
11863 +diff -NurpP --minimal linux-2.6.22.19/fs/nfs/nfs3xdr.c linux-2.6.22.19-vs2.2.0.7/fs/nfs/nfs3xdr.c
11864 +--- linux-2.6.22.19/fs/nfs/nfs3xdr.c 2007-07-09 13:19:27 +0200
11865 ++++ linux-2.6.22.19-vs2.2.0.7/fs/nfs/nfs3xdr.c 2007-06-15 02:37:03 +0200
11866 +@@ -22,6 +22,7 @@
11867 + #include <linux/nfs3.h>
11868 + #include <linux/nfs_fs.h>
11869 + #include <linux/nfsacl.h>
11870 ++#include <linux/vs_tag.h>
11871 + #include "internal.h"
11872 +
11873 + #define NFSDBG_FACILITY NFSDBG_XDR
11874 +@@ -178,7 +179,7 @@ xdr_decode_fattr(__be32 *p, struct nfs_f
11875 + }
11876 +
11877 + static inline __be32 *
11878 +-xdr_encode_sattr(__be32 *p, struct iattr *attr)
11879 ++xdr_encode_sattr(__be32 *p, struct iattr *attr, int tag)
11880 + {
11881 + if (attr->ia_valid & ATTR_MODE) {
11882 + *p++ = xdr_one;
11883 +@@ -186,15 +187,17 @@ xdr_encode_sattr(__be32 *p, struct iattr
11884 + } else {
11885 + *p++ = xdr_zero;
11886 + }
11887 +- if (attr->ia_valid & ATTR_UID) {
11888 ++ if (attr->ia_valid & ATTR_UID ||
11889 ++ (tag && (attr->ia_valid & ATTR_TAG))) {
11890 + *p++ = xdr_one;
11891 +- *p++ = htonl(attr->ia_uid);
11892 ++ *p++ = htonl(TAGINO_UID(tag, attr->ia_uid, attr->ia_tag));
11893 + } else {
11894 + *p++ = xdr_zero;
11895 + }
11896 +- if (attr->ia_valid & ATTR_GID) {
11897 ++ if (attr->ia_valid & ATTR_GID ||
11898 ++ (tag && (attr->ia_valid & ATTR_TAG))) {
11899 + *p++ = xdr_one;
11900 +- *p++ = htonl(attr->ia_gid);
11901 ++ *p++ = htonl(TAGINO_GID(tag, attr->ia_gid, attr->ia_tag));
11902 + } else {
11903 + *p++ = xdr_zero;
11904 + }
11905 +@@ -279,7 +282,8 @@ static int
11906 + nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args)
11907 + {
11908 + p = xdr_encode_fhandle(p, args->fh);
11909 +- p = xdr_encode_sattr(p, args->sattr);
11910 ++ p = xdr_encode_sattr(p, args->sattr,
11911 ++ req->rq_task->tk_client->cl_tag);
11912 + *p++ = htonl(args->guard);
11913 + if (args->guard)
11914 + p = xdr_encode_time3(p, &args->guardtime);
11915 +@@ -370,7 +374,8 @@ nfs3_xdr_createargs(struct rpc_rqst *req
11916 + *p++ = args->verifier[0];
11917 + *p++ = args->verifier[1];
11918 + } else
11919 +- p = xdr_encode_sattr(p, args->sattr);
11920 ++ p = xdr_encode_sattr(p, args->sattr,
11921 ++ req->rq_task->tk_client->cl_tag);
11922 +
11923 + req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
11924 + return 0;
11925 +@@ -384,7 +389,8 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req,
11926 + {
11927 + p = xdr_encode_fhandle(p, args->fh);
11928 + p = xdr_encode_array(p, args->name, args->len);
11929 +- p = xdr_encode_sattr(p, args->sattr);
11930 ++ p = xdr_encode_sattr(p, args->sattr,
11931 ++ req->rq_task->tk_client->cl_tag);
11932 + req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
11933 + return 0;
11934 + }
11935 +@@ -397,7 +403,8 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *re
11936 + {
11937 + p = xdr_encode_fhandle(p, args->fromfh);
11938 + p = xdr_encode_array(p, args->fromname, args->fromlen);
11939 +- p = xdr_encode_sattr(p, args->sattr);
11940 ++ p = xdr_encode_sattr(p, args->sattr,
11941 ++ req->rq_task->tk_client->cl_tag);
11942 + *p++ = htonl(args->pathlen);
11943 + req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
11944 +
11945 +@@ -415,7 +422,8 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req,
11946 + p = xdr_encode_fhandle(p, args->fh);
11947 + p = xdr_encode_array(p, args->name, args->len);
11948 + *p++ = htonl(args->type);
11949 +- p = xdr_encode_sattr(p, args->sattr);
11950 ++ p = xdr_encode_sattr(p, args->sattr,
11951 ++ req->rq_task->tk_client->cl_tag);
11952 + if (args->type == NF3CHR || args->type == NF3BLK) {
11953 + *p++ = htonl(MAJOR(args->rdev));
11954 + *p++ = htonl(MINOR(args->rdev));
11955 +diff -NurpP --minimal linux-2.6.22.19/fs/nfs/nfsroot.c linux-2.6.22.19-vs2.2.0.7/fs/nfs/nfsroot.c
11956 +--- linux-2.6.22.19/fs/nfs/nfsroot.c 2007-07-09 13:19:27 +0200
11957 ++++ linux-2.6.22.19-vs2.2.0.7/fs/nfs/nfsroot.c 2007-06-15 02:37:03 +0200
11958 +@@ -118,12 +118,12 @@ static int mount_port __initdata = 0; /
11959 + enum {
11960 + /* Options that take integer arguments */
11961 + Opt_port, Opt_rsize, Opt_wsize, Opt_timeo, Opt_retrans, Opt_acregmin,
11962 +- Opt_acregmax, Opt_acdirmin, Opt_acdirmax,
11963 ++ Opt_acregmax, Opt_acdirmin, Opt_acdirmax, Opt_tagid,
11964 + /* Options that take no arguments */
11965 + Opt_soft, Opt_hard, Opt_intr,
11966 + Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac,
11967 + Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp,
11968 +- Opt_acl, Opt_noacl,
11969 ++ Opt_acl, Opt_noacl, Opt_tag, Opt_notag,
11970 + /* Error token */
11971 + Opt_err
11972 + };
11973 +@@ -160,6 +160,10 @@ static match_table_t __initdata tokens =
11974 + {Opt_tcp, "tcp"},
11975 + {Opt_acl, "acl"},
11976 + {Opt_noacl, "noacl"},
11977 ++ {Opt_tag, "tag"},
11978 ++ {Opt_notag, "notag"},
11979 ++ {Opt_tagid, "tagid=%u"},
11980 ++ {Opt_tag, "tagxid"},
11981 + {Opt_err, NULL}
11982 +
11983 + };
11984 +@@ -274,6 +278,20 @@ static int __init root_nfs_parse(char *n
11985 + case Opt_noacl:
11986 + nfs_data.flags |= NFS_MOUNT_NOACL;
11987 + break;
11988 ++#ifndef CONFIG_TAGGING_NONE
11989 ++ case Opt_tag:
11990 ++ nfs_data.flags |= NFS_MOUNT_TAGGED;
11991 ++ break;
11992 ++ case Opt_notag:
11993 ++ nfs_data.flags &= ~NFS_MOUNT_TAGGED;
11994 ++ break;
11995 ++#endif
11996 ++#ifdef CONFIG_PROPAGATE
11997 ++ case Opt_tagid:
11998 ++ /* use args[0] */
11999 ++ nfs_data.flags |= NFS_MOUNT_TAGGED;
12000 ++ break;
12001 ++#endif
12002 + default:
12003 + printk(KERN_WARNING "Root-NFS: unknown "
12004 + "option: %s\n", p);
12005 +diff -NurpP --minimal linux-2.6.22.19/fs/nfs/super.c linux-2.6.22.19-vs2.2.0.7/fs/nfs/super.c
12006 +--- linux-2.6.22.19/fs/nfs/super.c 2008-03-14 20:19:03 +0100
12007 ++++ linux-2.6.22.19-vs2.2.0.7/fs/nfs/super.c 2007-10-01 15:25:35 +0200
12008 +@@ -45,6 +45,7 @@
12009 + #include <linux/inet.h>
12010 + #include <linux/nfs_xdr.h>
12011 + #include <linux/magic.h>
12012 ++#include <linux/vs_tag.h>
12013 +
12014 + #include <asm/system.h>
12015 + #include <asm/uaccess.h>
12016 +@@ -291,6 +292,7 @@ static void nfs_show_mount_options(struc
12017 + { NFS_MOUNT_NONLM, ",nolock", "" },
12018 + { NFS_MOUNT_NOACL, ",noacl", "" },
12019 + { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
12020 ++ { NFS_MOUNT_TAGGED, ",tag", "" },
12021 + { 0, NULL, NULL }
12022 + };
12023 + const struct proc_nfs_info *nfs_infop;
12024 +diff -NurpP --minimal linux-2.6.22.19/fs/nfsd/auth.c linux-2.6.22.19-vs2.2.0.7/fs/nfsd/auth.c
12025 +--- linux-2.6.22.19/fs/nfsd/auth.c 2006-06-18 04:54:42 +0200
12026 ++++ linux-2.6.22.19-vs2.2.0.7/fs/nfsd/auth.c 2007-06-15 02:37:03 +0200
12027 +@@ -9,6 +9,7 @@
12028 + #include <linux/sunrpc/svc.h>
12029 + #include <linux/sunrpc/svcauth.h>
12030 + #include <linux/nfsd/nfsd.h>
12031 ++#include <linux/vs_tag.h>
12032 +
12033 + #define CAP_NFSD_MASK (CAP_FS_MASK|CAP_TO_MASK(CAP_SYS_RESOURCE))
12034 +
12035 +@@ -41,19 +42,22 @@ int nfsd_setuser(struct svc_rqst *rqstp,
12036 + get_group_info(cred.cr_group_info);
12037 +
12038 + if (cred.cr_uid != (uid_t) -1)
12039 +- current->fsuid = cred.cr_uid;
12040 ++ current->fsuid = INOTAG_UID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid);
12041 + else
12042 + current->fsuid = exp->ex_anon_uid;
12043 + if (cred.cr_gid != (gid_t) -1)
12044 +- current->fsgid = cred.cr_gid;
12045 ++ current->fsgid = INOTAG_GID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid);
12046 + else
12047 + current->fsgid = exp->ex_anon_gid;
12048 +
12049 ++ /* this desperately needs a tag :) */
12050 ++ current->xid = (xid_t)INOTAG_TAG(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid, 0);
12051 ++
12052 + if (!cred.cr_group_info)
12053 + return -ENOMEM;
12054 + ret = set_current_groups(cred.cr_group_info);
12055 + put_group_info(cred.cr_group_info);
12056 +- if ((cred.cr_uid)) {
12057 ++ if (INOTAG_UID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid)) {
12058 + cap_t(current->cap_effective) &= ~CAP_NFSD_MASK;
12059 + } else {
12060 + cap_t(current->cap_effective) |= (CAP_NFSD_MASK &
12061 +diff -NurpP --minimal linux-2.6.22.19/fs/nfsd/nfs3xdr.c linux-2.6.22.19-vs2.2.0.7/fs/nfsd/nfs3xdr.c
12062 +--- linux-2.6.22.19/fs/nfsd/nfs3xdr.c 2007-07-09 13:19:27 +0200
12063 ++++ linux-2.6.22.19-vs2.2.0.7/fs/nfsd/nfs3xdr.c 2007-06-15 02:37:03 +0200
12064 +@@ -21,6 +21,7 @@
12065 + #include <linux/sunrpc/svc.h>
12066 + #include <linux/nfsd/nfsd.h>
12067 + #include <linux/nfsd/xdr3.h>
12068 ++#include <linux/vs_tag.h>
12069 +
12070 + #define NFSDDBG_FACILITY NFSDDBG_XDR
12071 +
12072 +@@ -107,6 +108,8 @@ static __be32 *
12073 + decode_sattr3(__be32 *p, struct iattr *iap)
12074 + {
12075 + u32 tmp;
12076 ++ uid_t uid = 0;
12077 ++ gid_t gid = 0;
12078 +
12079 + iap->ia_valid = 0;
12080 +
12081 +@@ -116,12 +119,15 @@ decode_sattr3(__be32 *p, struct iattr *i
12082 + }
12083 + if (*p++) {
12084 + iap->ia_valid |= ATTR_UID;
12085 +- iap->ia_uid = ntohl(*p++);
12086 ++ uid = ntohl(*p++);
12087 + }
12088 + if (*p++) {
12089 + iap->ia_valid |= ATTR_GID;
12090 +- iap->ia_gid = ntohl(*p++);
12091 ++ gid = ntohl(*p++);
12092 + }
12093 ++ iap->ia_uid = INOTAG_UID(DX_TAG_NFSD, uid, gid);
12094 ++ iap->ia_gid = INOTAG_GID(DX_TAG_NFSD, uid, gid);
12095 ++ iap->ia_tag = INOTAG_TAG(DX_TAG_NFSD, uid, gid, 0);
12096 + if (*p++) {
12097 + u64 newsize;
12098 +
12099 +@@ -180,8 +186,10 @@ encode_fattr3(struct svc_rqst *rqstp, __
12100 + *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
12101 + *p++ = htonl((u32) stat->mode);
12102 + *p++ = htonl((u32) stat->nlink);
12103 +- *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
12104 +- *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
12105 ++ *p++ = htonl((u32) nfsd_ruid(rqstp,
12106 ++ TAGINO_UID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
12107 ++ *p++ = htonl((u32) nfsd_rgid(rqstp,
12108 ++ TAGINO_GID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
12109 + if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
12110 + p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
12111 + } else {
12112 +diff -NurpP --minimal linux-2.6.22.19/fs/nfsd/nfs4recover.c linux-2.6.22.19-vs2.2.0.7/fs/nfsd/nfs4recover.c
12113 +--- linux-2.6.22.19/fs/nfsd/nfs4recover.c 2007-07-09 13:19:27 +0200
12114 ++++ linux-2.6.22.19-vs2.2.0.7/fs/nfsd/nfs4recover.c 2007-06-15 02:37:03 +0200
12115 +@@ -156,7 +156,7 @@ nfsd4_create_clid_dir(struct nfs4_client
12116 + dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
12117 + goto out_put;
12118 + }
12119 +- status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
12120 ++ status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU, NULL);
12121 + out_put:
12122 + dput(dentry);
12123 + out_unlock:
12124 +@@ -260,7 +260,7 @@ nfsd4_remove_clid_file(struct dentry *di
12125 + return -EINVAL;
12126 + }
12127 + mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
12128 +- status = vfs_unlink(dir->d_inode, dentry);
12129 ++ status = vfs_unlink(dir->d_inode, dentry, NULL);
12130 + mutex_unlock(&dir->d_inode->i_mutex);
12131 + return status;
12132 + }
12133 +@@ -275,7 +275,7 @@ nfsd4_clear_clid_dir(struct dentry *dir,
12134 + * a kernel from the future.... */
12135 + nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
12136 + mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
12137 +- status = vfs_rmdir(dir->d_inode, dentry);
12138 ++ status = vfs_rmdir(dir->d_inode, dentry, NULL);
12139 + mutex_unlock(&dir->d_inode->i_mutex);
12140 + return status;
12141 + }
12142 +diff -NurpP --minimal linux-2.6.22.19/fs/nfsd/nfs4xdr.c linux-2.6.22.19-vs2.2.0.7/fs/nfsd/nfs4xdr.c
12143 +--- linux-2.6.22.19/fs/nfsd/nfs4xdr.c 2008-03-14 20:19:03 +0100
12144 ++++ linux-2.6.22.19-vs2.2.0.7/fs/nfsd/nfs4xdr.c 2008-03-14 19:19:48 +0100
12145 +@@ -56,6 +56,7 @@
12146 + #include <linux/nfsd_idmap.h>
12147 + #include <linux/nfs4.h>
12148 + #include <linux/nfs4_acl.h>
12149 ++#include <linux/vs_tag.h>
12150 +
12151 + #define NFSDDBG_FACILITY NFSDDBG_XDR
12152 +
12153 +@@ -1728,14 +1729,18 @@ out_acl:
12154 + WRITE32(stat.nlink);
12155 + }
12156 + if (bmval1 & FATTR4_WORD1_OWNER) {
12157 +- status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);
12158 ++ status = nfsd4_encode_user(rqstp,
12159 ++ TAGINO_UID(DX_TAG(dentry->d_inode),
12160 ++ stat.uid, stat.tag), &p, &buflen);
12161 + if (status == nfserr_resource)
12162 + goto out_resource;
12163 + if (status)
12164 + goto out;
12165 + }
12166 + if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
12167 +- status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);
12168 ++ status = nfsd4_encode_group(rqstp,
12169 ++ TAGINO_GID(DX_TAG(dentry->d_inode),
12170 ++ stat.gid, stat.tag), &p, &buflen);
12171 + if (status == nfserr_resource)
12172 + goto out_resource;
12173 + if (status)
12174 +diff -NurpP --minimal linux-2.6.22.19/fs/nfsd/nfsxdr.c linux-2.6.22.19-vs2.2.0.7/fs/nfsd/nfsxdr.c
12175 +--- linux-2.6.22.19/fs/nfsd/nfsxdr.c 2007-07-09 13:19:27 +0200
12176 ++++ linux-2.6.22.19-vs2.2.0.7/fs/nfsd/nfsxdr.c 2007-06-15 02:37:03 +0200
12177 +@@ -15,6 +15,7 @@
12178 + #include <linux/nfsd/nfsd.h>
12179 + #include <linux/nfsd/xdr.h>
12180 + #include <linux/mm.h>
12181 ++#include <linux/vs_tag.h>
12182 +
12183 + #define NFSDDBG_FACILITY NFSDDBG_XDR
12184 +
12185 +@@ -97,6 +98,8 @@ static __be32 *
12186 + decode_sattr(__be32 *p, struct iattr *iap)
12187 + {
12188 + u32 tmp, tmp1;
12189 ++ uid_t uid = 0;
12190 ++ gid_t gid = 0;
12191 +
12192 + iap->ia_valid = 0;
12193 +
12194 +@@ -110,12 +113,15 @@ decode_sattr(__be32 *p, struct iattr *ia
12195 + }
12196 + if ((tmp = ntohl(*p++)) != (u32)-1) {
12197 + iap->ia_valid |= ATTR_UID;
12198 +- iap->ia_uid = tmp;
12199 ++ uid = tmp;
12200 + }
12201 + if ((tmp = ntohl(*p++)) != (u32)-1) {
12202 + iap->ia_valid |= ATTR_GID;
12203 +- iap->ia_gid = tmp;
12204 ++ gid = tmp;
12205 + }
12206 ++ iap->ia_uid = INOTAG_UID(DX_TAG_NFSD, uid, gid);
12207 ++ iap->ia_gid = INOTAG_GID(DX_TAG_NFSD, uid, gid);
12208 ++ iap->ia_tag = INOTAG_TAG(DX_TAG_NFSD, uid, gid, 0);
12209 + if ((tmp = ntohl(*p++)) != (u32)-1) {
12210 + iap->ia_valid |= ATTR_SIZE;
12211 + iap->ia_size = tmp;
12212 +@@ -160,8 +166,10 @@ encode_fattr(struct svc_rqst *rqstp, __b
12213 + *p++ = htonl(nfs_ftypes[type >> 12]);
12214 + *p++ = htonl((u32) stat->mode);
12215 + *p++ = htonl((u32) stat->nlink);
12216 +- *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
12217 +- *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
12218 ++ *p++ = htonl((u32) nfsd_ruid(rqstp,
12219 ++ TAGINO_UID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
12220 ++ *p++ = htonl((u32) nfsd_rgid(rqstp,
12221 ++ TAGINO_GID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
12222 +
12223 + if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
12224 + *p++ = htonl(NFS_MAXPATHLEN);
12225 +diff -NurpP --minimal linux-2.6.22.19/fs/nfsd/vfs.c linux-2.6.22.19-vs2.2.0.7/fs/nfsd/vfs.c
12226 +--- linux-2.6.22.19/fs/nfsd/vfs.c 2008-03-14 20:19:03 +0100
12227 ++++ linux-2.6.22.19-vs2.2.0.7/fs/nfsd/vfs.c 2007-08-12 12:21:51 +0200
12228 +@@ -1186,13 +1186,13 @@ nfsd_create(struct svc_rqst *rqstp, stru
12229 + host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
12230 + break;
12231 + case S_IFDIR:
12232 +- host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
12233 ++ host_err = vfs_mkdir(dirp, dchild, iap->ia_mode, NULL);
12234 + break;
12235 + case S_IFCHR:
12236 + case S_IFBLK:
12237 + case S_IFIFO:
12238 + case S_IFSOCK:
12239 +- host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
12240 ++ host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev, NULL);
12241 + break;
12242 + default:
12243 + printk("nfsd: bad file type %o in nfsd_create\n", type);
12244 +@@ -1466,11 +1466,13 @@ nfsd_symlink(struct svc_rqst *rqstp, str
12245 + else {
12246 + strncpy(path_alloced, path, plen);
12247 + path_alloced[plen] = 0;
12248 +- host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
12249 ++ host_err = vfs_symlink(dentry->d_inode, dnew,
12250 ++ path_alloced, mode, NULL);
12251 + kfree(path_alloced);
12252 + }
12253 + } else
12254 +- host_err = vfs_symlink(dentry->d_inode, dnew, path, mode);
12255 ++ host_err = vfs_symlink(dentry->d_inode, dnew,
12256 ++ path, mode, NULL);
12257 +
12258 + if (!host_err) {
12259 + if (EX_ISSYNC(fhp->fh_export))
12260 +@@ -1529,7 +1531,7 @@ nfsd_link(struct svc_rqst *rqstp, struct
12261 + dold = tfhp->fh_dentry;
12262 + dest = dold->d_inode;
12263 +
12264 +- host_err = vfs_link(dold, dirp, dnew);
12265 ++ host_err = vfs_link(dold, dirp, dnew, NULL);
12266 + if (!host_err) {
12267 + if (EX_ISSYNC(ffhp->fh_export)) {
12268 + err = nfserrno(nfsd_sync_dir(ddir));
12269 +@@ -1694,9 +1696,9 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
12270 + host_err = -EPERM;
12271 + } else
12272 + #endif
12273 +- host_err = vfs_unlink(dirp, rdentry);
12274 ++ host_err = vfs_unlink(dirp, rdentry, NULL);
12275 + } else { /* It's RMDIR */
12276 +- host_err = vfs_rmdir(dirp, rdentry);
12277 ++ host_err = vfs_rmdir(dirp, rdentry, NULL);
12278 + }
12279 +
12280 + dput(rdentry);
12281 +@@ -1807,7 +1809,8 @@ nfsd_permission(struct svc_export *exp,
12282 + */
12283 + if (!(acc & MAY_LOCAL_ACCESS))
12284 + if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) {
12285 +- if (EX_RDONLY(exp) || IS_RDONLY(inode))
12286 ++ if (EX_RDONLY(exp) || IS_RDONLY(inode)
12287 ++ || MNT_IS_RDONLY(exp->ex_mnt))
12288 + return nfserr_rofs;
12289 + if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
12290 + return nfserr_perm;
12291 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/dlm/dlmfs.c linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/dlm/dlmfs.c
12292 +--- linux-2.6.22.19/fs/ocfs2/dlm/dlmfs.c 2007-07-09 13:19:28 +0200
12293 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/dlm/dlmfs.c 2007-06-15 02:37:03 +0200
12294 +@@ -43,6 +43,7 @@
12295 + #include <linux/init.h>
12296 + #include <linux/string.h>
12297 + #include <linux/backing-dev.h>
12298 ++#include <linux/vs_tag.h>
12299 +
12300 + #include <asm/uaccess.h>
12301 +
12302 +@@ -331,6 +332,7 @@ static struct inode *dlmfs_get_root_inod
12303 + inode->i_mode = mode;
12304 + inode->i_uid = current->fsuid;
12305 + inode->i_gid = current->fsgid;
12306 ++ inode->i_tag = dx_current_fstag(sb);
12307 + inode->i_blocks = 0;
12308 + inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
12309 + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
12310 +@@ -357,6 +359,7 @@ static struct inode *dlmfs_get_inode(str
12311 + inode->i_mode = mode;
12312 + inode->i_uid = current->fsuid;
12313 + inode->i_gid = current->fsgid;
12314 ++ inode->i_tag = dx_current_fstag(sb);
12315 + inode->i_blocks = 0;
12316 + inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
12317 + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
12318 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/dlmglue.c linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/dlmglue.c
12319 +--- linux-2.6.22.19/fs/ocfs2/dlmglue.c 2007-07-09 13:19:28 +0200
12320 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/dlmglue.c 2007-06-15 02:37:03 +0200
12321 +@@ -1475,6 +1475,7 @@ static void __ocfs2_stuff_meta_lvb(struc
12322 + lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
12323 + lvb->lvb_iuid = cpu_to_be32(inode->i_uid);
12324 + lvb->lvb_igid = cpu_to_be32(inode->i_gid);
12325 ++ lvb->lvb_itag = cpu_to_be16(inode->i_tag);
12326 + lvb->lvb_imode = cpu_to_be16(inode->i_mode);
12327 + lvb->lvb_inlink = cpu_to_be16(inode->i_nlink);
12328 + lvb->lvb_iatime_packed =
12329 +@@ -1527,6 +1528,7 @@ static void ocfs2_refresh_inode_from_lvb
12330 +
12331 + inode->i_uid = be32_to_cpu(lvb->lvb_iuid);
12332 + inode->i_gid = be32_to_cpu(lvb->lvb_igid);
12333 ++ inode->i_tag = be16_to_cpu(lvb->lvb_itag);
12334 + inode->i_mode = be16_to_cpu(lvb->lvb_imode);
12335 + inode->i_nlink = be16_to_cpu(lvb->lvb_inlink);
12336 + ocfs2_unpack_timespec(&inode->i_atime,
12337 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/dlmglue.h linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/dlmglue.h
12338 +--- linux-2.6.22.19/fs/ocfs2/dlmglue.h 2007-07-09 13:19:28 +0200
12339 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/dlmglue.h 2007-06-15 02:37:03 +0200
12340 +@@ -34,7 +34,7 @@
12341 + struct ocfs2_meta_lvb {
12342 + __u8 lvb_version;
12343 + __u8 lvb_reserved0;
12344 +- __be16 lvb_reserved1;
12345 ++ __be16 lvb_itag;
12346 + __be32 lvb_iclusters;
12347 + __be32 lvb_iuid;
12348 + __be32 lvb_igid;
12349 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/file.c linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/file.c
12350 +--- linux-2.6.22.19/fs/ocfs2/file.c 2008-03-14 20:19:04 +0100
12351 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/file.c 2007-09-05 03:05:52 +0200
12352 +@@ -943,13 +943,15 @@ int ocfs2_setattr(struct dentry *dentry,
12353 + mlog(0, "uid change: %d\n", attr->ia_uid);
12354 + if (attr->ia_valid & ATTR_GID)
12355 + mlog(0, "gid change: %d\n", attr->ia_gid);
12356 ++ if (attr->ia_valid & ATTR_TAG)
12357 ++ mlog(0, "tag change: %d\n", attr->ia_tag);
12358 + if (attr->ia_valid & ATTR_SIZE)
12359 + mlog(0, "size change...\n");
12360 + if (attr->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME))
12361 + mlog(0, "time change...\n");
12362 +
12363 + #define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \
12364 +- | ATTR_GID | ATTR_UID | ATTR_MODE)
12365 ++ | ATTR_GID | ATTR_UID | ATTR_TAG | ATTR_MODE)
12366 + if (!(attr->ia_valid & OCFS2_VALID_ATTRS)) {
12367 + mlog(0, "can't handle attrs: 0x%x\n", attr->ia_valid);
12368 + return 0;
12369 +@@ -1805,6 +1807,7 @@ bail:
12370 + const struct inode_operations ocfs2_file_iops = {
12371 + .setattr = ocfs2_setattr,
12372 + .getattr = ocfs2_getattr,
12373 ++ .sync_flags = ocfs2_sync_flags,
12374 + .permission = ocfs2_permission,
12375 + };
12376 +
12377 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/inode.c linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/inode.c
12378 +--- linux-2.6.22.19/fs/ocfs2/inode.c 2007-07-09 13:19:28 +0200
12379 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/inode.c 2007-06-15 03:10:27 +0200
12380 +@@ -28,6 +28,7 @@
12381 + #include <linux/slab.h>
12382 + #include <linux/highmem.h>
12383 + #include <linux/pagemap.h>
12384 ++#include <linux/vs_tag.h>
12385 +
12386 + #include <asm/byteorder.h>
12387 +
12388 +@@ -42,6 +43,7 @@
12389 + #include "file.h"
12390 + #include "heartbeat.h"
12391 + #include "inode.h"
12392 ++#include "ioctl.h"
12393 + #include "journal.h"
12394 + #include "namei.h"
12395 + #include "suballoc.h"
12396 +@@ -77,6 +79,10 @@ void ocfs2_set_inode_flags(struct inode
12397 +
12398 + if (flags & OCFS2_IMMUTABLE_FL)
12399 + inode->i_flags |= S_IMMUTABLE;
12400 ++ if (flags & OCFS2_IUNLINK_FL)
12401 ++ inode->i_flags |= S_IUNLINK;
12402 ++ if (flags & OCFS2_BARRIER_FL)
12403 ++ inode->i_flags |= S_BARRIER;
12404 +
12405 + if (flags & OCFS2_SYNC_FL)
12406 + inode->i_flags |= S_SYNC;
12407 +@@ -107,6 +113,27 @@ void ocfs2_get_inode_flags(struct ocfs2_
12408 + oi->ip_attr |= OCFS2_DIRSYNC_FL;
12409 + }
12410 +
12411 ++int ocfs2_sync_flags(struct inode *inode)
12412 ++{
12413 ++ unsigned int oldflags, newflags;
12414 ++
12415 ++ oldflags = OCFS2_I(inode)->ip_flags;
12416 ++ newflags = oldflags & ~(OCFS2_IMMUTABLE_FL |
12417 ++ OCFS2_IUNLINK_FL | OCFS2_BARRIER_FL);
12418 ++
12419 ++ if (IS_IMMUTABLE(inode))
12420 ++ newflags |= OCFS2_IMMUTABLE_FL;
12421 ++ if (IS_IUNLINK(inode))
12422 ++ newflags |= OCFS2_IUNLINK_FL;
12423 ++ if (IS_BARRIER(inode))
12424 ++ newflags |= OCFS2_BARRIER_FL;
12425 ++
12426 ++ if (oldflags ^ newflags)
12427 ++ return ocfs2_set_inode_attr(inode,
12428 ++ newflags, OCFS2_FL_MASK);
12429 ++ return 0;
12430 ++}
12431 ++
12432 + struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, int flags)
12433 + {
12434 + struct inode *inode = NULL;
12435 +@@ -212,6 +239,8 @@ int ocfs2_populate_inode(struct inode *i
12436 + struct super_block *sb;
12437 + struct ocfs2_super *osb;
12438 + int status = -EINVAL;
12439 ++ uid_t uid;
12440 ++ gid_t gid;
12441 +
12442 + mlog_entry("(0x%p, size:%llu)\n", inode,
12443 + (unsigned long long)le64_to_cpu(fe->i_size));
12444 +@@ -246,8 +275,12 @@ int ocfs2_populate_inode(struct inode *i
12445 + inode->i_generation = le32_to_cpu(fe->i_generation);
12446 + inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
12447 + inode->i_mode = le16_to_cpu(fe->i_mode);
12448 +- inode->i_uid = le32_to_cpu(fe->i_uid);
12449 +- inode->i_gid = le32_to_cpu(fe->i_gid);
12450 ++ uid = le32_to_cpu(fe->i_uid);
12451 ++ gid = le32_to_cpu(fe->i_gid);
12452 ++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
12453 ++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
12454 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
12455 ++ /* le16_to_cpu(raw_inode->i_raw_tag)i */ 0);
12456 +
12457 + /* Fast symlinks will have i_size but no allocated clusters. */
12458 + if (S_ISLNK(inode->i_mode) && !fe->i_clusters)
12459 +@@ -1224,8 +1257,11 @@ int ocfs2_mark_inode_dirty(handle_t *han
12460 +
12461 + fe->i_size = cpu_to_le64(i_size_read(inode));
12462 + fe->i_links_count = cpu_to_le16(inode->i_nlink);
12463 +- fe->i_uid = cpu_to_le32(inode->i_uid);
12464 +- fe->i_gid = cpu_to_le32(inode->i_gid);
12465 ++ fe->i_uid = cpu_to_le32(TAGINO_UID(DX_TAG(inode),
12466 ++ inode->i_uid, inode->i_tag));
12467 ++ fe->i_gid = cpu_to_le32(TAGINO_GID(DX_TAG(inode),
12468 ++ inode->i_gid, inode->i_tag));
12469 ++ /* i_tag = = cpu_to_le16(inode->i_tag); */
12470 + fe->i_mode = cpu_to_le16(inode->i_mode);
12471 + fe->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
12472 + fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
12473 +@@ -1253,15 +1289,24 @@ leave:
12474 + void ocfs2_refresh_inode(struct inode *inode,
12475 + struct ocfs2_dinode *fe)
12476 + {
12477 ++ uid_t uid;
12478 ++ gid_t gid;
12479 ++
12480 + spin_lock(&OCFS2_I(inode)->ip_lock);
12481 +
12482 + OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
12483 + OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
12484 ++ /* OCFS2_I(inode)->ip_flags &= ~OCFS2_FL_MASK;
12485 ++ OCFS2_I(inode)->ip_flags |= le32_to_cpu(fe->i_flags) & OCFS2_FL_MASK; */
12486 + ocfs2_set_inode_flags(inode);
12487 + i_size_write(inode, le64_to_cpu(fe->i_size));
12488 + inode->i_nlink = le16_to_cpu(fe->i_links_count);
12489 +- inode->i_uid = le32_to_cpu(fe->i_uid);
12490 +- inode->i_gid = le32_to_cpu(fe->i_gid);
12491 ++ uid = le32_to_cpu(fe->i_uid);
12492 ++ gid = le32_to_cpu(fe->i_gid);
12493 ++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
12494 ++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
12495 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
12496 ++ /* le16_to_cpu(raw_inode->i_raw_tag)i */ 0);
12497 + inode->i_mode = le16_to_cpu(fe->i_mode);
12498 + if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0)
12499 + inode->i_blocks = 0;
12500 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/inode.h linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/inode.h
12501 +--- linux-2.6.22.19/fs/ocfs2/inode.h 2007-07-09 13:19:28 +0200
12502 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/inode.h 2007-06-15 03:10:53 +0200
12503 +@@ -142,6 +142,7 @@ int ocfs2_aio_write(struct file *file, s
12504 +
12505 + void ocfs2_set_inode_flags(struct inode *inode);
12506 + void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi);
12507 ++int ocfs2_sync_flags(struct inode *inode);
12508 +
12509 + static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode)
12510 + {
12511 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/ioctl.c linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/ioctl.c
12512 +--- linux-2.6.22.19/fs/ocfs2/ioctl.c 2007-07-09 13:19:28 +0200
12513 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/ioctl.c 2008-03-14 19:56:14 +0100
12514 +@@ -39,7 +39,8 @@ static int ocfs2_get_inode_attr(struct i
12515 + return status;
12516 + }
12517 +
12518 +-static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
12519 ++/* Called with inode->i_mutex locked */
12520 ++int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
12521 + unsigned mask)
12522 + {
12523 + struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
12524 +@@ -49,8 +50,6 @@ static int ocfs2_set_inode_attr(struct i
12525 + unsigned oldflags;
12526 + int status;
12527 +
12528 +- mutex_lock(&inode->i_mutex);
12529 +-
12530 + status = ocfs2_meta_lock(inode, &bh, 1);
12531 + if (status < 0) {
12532 + mlog_errno(status);
12533 +@@ -101,8 +100,6 @@ static int ocfs2_set_inode_attr(struct i
12534 + bail_unlock:
12535 + ocfs2_meta_unlock(inode, 1);
12536 + bail:
12537 +- mutex_unlock(&inode->i_mutex);
12538 +-
12539 + if (bh)
12540 + brelse(bh);
12541 +
12542 +@@ -110,6 +107,16 @@ bail:
12543 + return status;
12544 + }
12545 +
12546 ++static inline int ocfs2_set_inode_attr_lock(struct inode *inode,
12547 ++ unsigned flags, unsigned mask)
12548 ++{
12549 ++ int ret;
12550 ++ mutex_lock(&inode->i_mutex);
12551 ++ ret = ocfs2_set_inode_attr(inode, flags, mask);
12552 ++ mutex_unlock(&inode->i_mutex);
12553 ++ return ret;
12554 ++}
12555 ++
12556 + int ocfs2_ioctl(struct inode * inode, struct file * filp,
12557 + unsigned int cmd, unsigned long arg)
12558 + {
12559 +@@ -128,7 +135,7 @@ int ocfs2_ioctl(struct inode * inode, st
12560 + if (get_user(flags, (int __user *) arg))
12561 + return -EFAULT;
12562 +
12563 +- return ocfs2_set_inode_attr(inode, flags,
12564 ++ return ocfs2_set_inode_attr_lock(inode, flags,
12565 + OCFS2_FL_MODIFIABLE);
12566 + default:
12567 + return -ENOTTY;
12568 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/ioctl.h linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/ioctl.h
12569 +--- linux-2.6.22.19/fs/ocfs2/ioctl.h 2007-07-09 13:19:28 +0200
12570 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/ioctl.h 2007-06-15 02:37:03 +0200
12571 +@@ -10,6 +10,9 @@
12572 + #ifndef OCFS2_IOCTL_H
12573 + #define OCFS2_IOCTL_H
12574 +
12575 ++int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
12576 ++ unsigned mask);
12577 ++
12578 + int ocfs2_ioctl(struct inode * inode, struct file * filp,
12579 + unsigned int cmd, unsigned long arg);
12580 + long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg);
12581 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/namei.c linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/namei.c
12582 +--- linux-2.6.22.19/fs/ocfs2/namei.c 2007-07-09 13:19:28 +0200
12583 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/namei.c 2007-06-15 02:37:03 +0200
12584 +@@ -40,6 +40,7 @@
12585 + #include <linux/types.h>
12586 + #include <linux/slab.h>
12587 + #include <linux/highmem.h>
12588 ++#include <linux/vs_tag.h>
12589 +
12590 + #define MLOG_MASK_PREFIX ML_NAMEI
12591 + #include <cluster/masklog.h>
12592 +@@ -483,6 +484,9 @@ static int ocfs2_mknod_locked(struct ocf
12593 + u64 fe_blkno = 0;
12594 + u16 suballoc_bit;
12595 + struct inode *inode = NULL;
12596 ++ uid_t uid;
12597 ++ gid_t gid;
12598 ++ tag_t tag;
12599 +
12600 + mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode,
12601 + (unsigned long)dev, dentry->d_name.len,
12602 +@@ -542,13 +546,19 @@ static int ocfs2_mknod_locked(struct ocf
12603 + fe->i_blkno = cpu_to_le64(fe_blkno);
12604 + fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
12605 + fe->i_suballoc_slot = cpu_to_le16(osb->slot_num);
12606 +- fe->i_uid = cpu_to_le32(current->fsuid);
12607 ++
12608 ++ tag = dx_current_fstag(osb->sb);
12609 ++ uid = current->fsuid;
12610 + if (dir->i_mode & S_ISGID) {
12611 +- fe->i_gid = cpu_to_le32(dir->i_gid);
12612 ++ gid = dir->i_gid;
12613 + if (S_ISDIR(mode))
12614 + mode |= S_ISGID;
12615 + } else
12616 +- fe->i_gid = cpu_to_le32(current->fsgid);
12617 ++ gid = current->fsgid;
12618 ++
12619 ++ fe->i_uid = cpu_to_le32(TAGINO_UID(DX_TAG(inode), uid, tag));
12620 ++ fe->i_gid = cpu_to_le32(TAGINO_GID(DX_TAG(inode), gid, tag));
12621 ++ inode->i_tag = tag;
12622 + fe->i_mode = cpu_to_le16(mode);
12623 + if (S_ISCHR(mode) || S_ISBLK(mode))
12624 + fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
12625 +@@ -2316,5 +2326,6 @@ const struct inode_operations ocfs2_dir_
12626 + .rename = ocfs2_rename,
12627 + .setattr = ocfs2_setattr,
12628 + .getattr = ocfs2_getattr,
12629 ++ .sync_flags = ocfs2_sync_flags,
12630 + .permission = ocfs2_permission,
12631 + };
12632 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/ocfs2.h linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/ocfs2.h
12633 +--- linux-2.6.22.19/fs/ocfs2/ocfs2.h 2007-07-09 13:19:28 +0200
12634 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/ocfs2.h 2007-06-15 02:37:03 +0200
12635 +@@ -170,6 +170,7 @@ enum ocfs2_mount_options
12636 + OCFS2_MOUNT_NOINTR = 1 << 2, /* Don't catch signals */
12637 + OCFS2_MOUNT_ERRORS_PANIC = 1 << 3, /* Panic on errors */
12638 + OCFS2_MOUNT_DATA_WRITEBACK = 1 << 4, /* No data ordering */
12639 ++ OCFS2_MOUNT_TAGGED = 1 << 8, /* use tagging */
12640 + };
12641 +
12642 + #define OCFS2_OSB_SOFT_RO 0x0001
12643 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/ocfs2_fs.h linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/ocfs2_fs.h
12644 +--- linux-2.6.22.19/fs/ocfs2/ocfs2_fs.h 2007-07-09 13:19:28 +0200
12645 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/ocfs2_fs.h 2007-06-15 02:37:03 +0200
12646 +@@ -152,8 +152,12 @@
12647 + #define OCFS2_NOATIME_FL (0x00000080) /* do not update atime */
12648 + #define OCFS2_DIRSYNC_FL (0x00010000) /* dirsync behaviour (directories only) */
12649 +
12650 ++#define OCFS2_BARRIER_FL (0x04000000) /* Barrier for chroot() */
12651 ++#define OCFS2_IUNLINK_FL (0x08000000) /* Immutable unlink */
12652 ++
12653 + #define OCFS2_FL_VISIBLE (0x000100FF) /* User visible flags */
12654 + #define OCFS2_FL_MODIFIABLE (0x000100FF) /* User modifiable flags */
12655 ++#define OCFS2_FL_MASK (0x0F0100FF)
12656 +
12657 + /*
12658 + * Extent record flags (e_node.leaf.flags)
12659 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/super.c linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/super.c
12660 +--- linux-2.6.22.19/fs/ocfs2/super.c 2007-07-09 13:19:28 +0200
12661 ++++ linux-2.6.22.19-vs2.2.0.7/fs/ocfs2/super.c 2007-06-15 02:37:03 +0200
12662 +@@ -140,6 +140,7 @@ enum {
12663 + Opt_data_ordered,
12664 + Opt_data_writeback,
12665 + Opt_atime_quantum,
12666 ++ Opt_tag, Opt_notag, Opt_tagid,
12667 + Opt_err,
12668 + };
12669 +
12670 +@@ -154,6 +155,10 @@ static match_table_t tokens = {
12671 + {Opt_data_ordered, "data=ordered"},
12672 + {Opt_data_writeback, "data=writeback"},
12673 + {Opt_atime_quantum, "atime_quantum=%u"},
12674 ++ {Opt_tag, "tag"},
12675 ++ {Opt_tag, "tagxid"},
12676 ++ {Opt_notag, "notag"},
12677 ++ {Opt_tagid, "tagid=%u"},
12678 + {Opt_err, NULL}
12679 + };
12680 +
12681 +@@ -362,6 +367,14 @@ static int ocfs2_remount(struct super_bl
12682 + goto out;
12683 + }
12684 +
12685 ++ printk("ocfs2_remount: %lx,%lx\n", osb->s_mount_opt, sb->s_flags);
12686 ++ if ((parsed_options & OCFS2_MOUNT_TAGGED) &&
12687 ++ !(sb->s_flags & MS_TAGGED)) {
12688 ++ ret = -EINVAL;
12689 ++ mlog(ML_ERROR, "Cannot change tagging on remount\n");
12690 ++ goto out;
12691 ++ }
12692 ++
12693 + if ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) !=
12694 + (parsed_options & OCFS2_MOUNT_HB_LOCAL)) {
12695 + ret = -EINVAL;
12696 +@@ -654,6 +667,9 @@ static int ocfs2_fill_super(struct super
12697 +
12698 + ocfs2_complete_mount_recovery(osb);
12699 +
12700 ++ if (osb->s_mount_opt & OCFS2_MOUNT_TAGGED)
12701 ++ sb->s_flags |= MS_TAGGED;
12702 ++
12703 + if (ocfs2_mount_local(osb))
12704 + snprintf(nodestr, sizeof(nodestr), "local");
12705 + else
12706 +@@ -782,6 +798,20 @@ static int ocfs2_parse_options(struct su
12707 + else
12708 + osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM;
12709 + break;
12710 ++#ifndef CONFIG_TAGGING_NONE
12711 ++ case Opt_tag:
12712 ++ *mount_opt |= OCFS2_MOUNT_TAGGED;
12713 ++ break;
12714 ++ case Opt_notag:
12715 ++ *mount_opt &= ~OCFS2_MOUNT_TAGGED;
12716 ++ break;
12717 ++#endif
12718 ++#ifdef CONFIG_PROPAGATE
12719 ++ case Opt_tagid:
12720 ++ /* use args[0] */
12721 ++ *mount_opt |= OCFS2_MOUNT_TAGGED;
12722 ++ break;
12723 ++#endif
12724 + default:
12725 + mlog(ML_ERROR,
12726 + "Unrecognized mount option \"%s\" "
12727 +diff -NurpP --minimal linux-2.6.22.19/fs/open.c linux-2.6.22.19-vs2.2.0.7/fs/open.c
12728 +--- linux-2.6.22.19/fs/open.c 2007-07-09 13:19:28 +0200
12729 ++++ linux-2.6.22.19-vs2.2.0.7/fs/open.c 2007-06-15 02:37:03 +0200
12730 +@@ -26,22 +26,31 @@
12731 + #include <linux/syscalls.h>
12732 + #include <linux/rcupdate.h>
12733 + #include <linux/audit.h>
12734 ++#include <linux/vs_base.h>
12735 ++#include <linux/vs_limit.h>
12736 ++#include <linux/vs_dlimit.h>
12737 ++#include <linux/vs_tag.h>
12738 ++#include <linux/vs_cowbl.h>
12739 +
12740 + int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
12741 + {
12742 + int retval = -ENODEV;
12743 +
12744 + if (dentry) {
12745 ++ struct super_block *sb = dentry->d_sb;
12746 ++
12747 + retval = -ENOSYS;
12748 +- if (dentry->d_sb->s_op->statfs) {
12749 ++ if (sb->s_op->statfs) {
12750 + memset(buf, 0, sizeof(*buf));
12751 + retval = security_sb_statfs(dentry);
12752 + if (retval)
12753 + return retval;
12754 +- retval = dentry->d_sb->s_op->statfs(dentry, buf);
12755 ++ retval = sb->s_op->statfs(dentry, buf);
12756 + if (retval == 0 && buf->f_frsize == 0)
12757 + buf->f_frsize = buf->f_bsize;
12758 + }
12759 ++ if (!vx_check(0, VS_ADMIN|VS_WATCH))
12760 ++ vx_vsi_statfs(sb, buf);
12761 + }
12762 + return retval;
12763 + }
12764 +@@ -248,7 +257,7 @@ static long do_sys_truncate(const char _
12765 + goto dput_and_out;
12766 +
12767 + error = -EROFS;
12768 +- if (IS_RDONLY(inode))
12769 ++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
12770 + goto dput_and_out;
12771 +
12772 + error = -EPERM;
12773 +@@ -397,7 +406,7 @@ asmlinkage long sys_faccessat(int dfd, c
12774 + special_file(nd.dentry->d_inode->i_mode))
12775 + goto out_path_release;
12776 +
12777 +- if(IS_RDONLY(nd.dentry->d_inode))
12778 ++ if(IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))
12779 + res = -EROFS;
12780 +
12781 + out_path_release:
12782 +@@ -511,7 +520,7 @@ asmlinkage long sys_fchmod(unsigned int
12783 + audit_inode(NULL, inode);
12784 +
12785 + err = -EROFS;
12786 +- if (IS_RDONLY(inode))
12787 ++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(file->f_vfsmnt))
12788 + goto out_putf;
12789 + err = -EPERM;
12790 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
12791 +@@ -541,11 +550,11 @@ asmlinkage long sys_fchmodat(int dfd, co
12792 + error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
12793 + if (error)
12794 + goto out;
12795 +- inode = nd.dentry->d_inode;
12796 +
12797 +- error = -EROFS;
12798 +- if (IS_RDONLY(inode))
12799 ++ error = cow_check_and_break(&nd);
12800 ++ if (error)
12801 + goto dput_and_out;
12802 ++ inode = nd.dentry->d_inode;
12803 +
12804 + error = -EPERM;
12805 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
12806 +@@ -570,7 +579,8 @@ asmlinkage long sys_chmod(const char __u
12807 + return sys_fchmodat(AT_FDCWD, filename, mode);
12808 + }
12809 +
12810 +-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
12811 ++static int chown_common(struct dentry *dentry, struct vfsmount *mnt,
12812 ++ uid_t user, gid_t group)
12813 + {
12814 + struct inode * inode;
12815 + int error;
12816 +@@ -582,7 +592,7 @@ static int chown_common(struct dentry *
12817 + goto out;
12818 + }
12819 + error = -EROFS;
12820 +- if (IS_RDONLY(inode))
12821 ++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt))
12822 + goto out;
12823 + error = -EPERM;
12824 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
12825 +@@ -590,11 +600,11 @@ static int chown_common(struct dentry *
12826 + newattrs.ia_valid = ATTR_CTIME;
12827 + if (user != (uid_t) -1) {
12828 + newattrs.ia_valid |= ATTR_UID;
12829 +- newattrs.ia_uid = user;
12830 ++ newattrs.ia_uid = dx_map_uid(user);
12831 + }
12832 + if (group != (gid_t) -1) {
12833 + newattrs.ia_valid |= ATTR_GID;
12834 +- newattrs.ia_gid = group;
12835 ++ newattrs.ia_gid = dx_map_gid(group);
12836 + }
12837 + if (!S_ISDIR(inode->i_mode))
12838 + newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
12839 +@@ -613,7 +623,11 @@ asmlinkage long sys_chown(const char __u
12840 + error = user_path_walk(filename, &nd);
12841 + if (error)
12842 + goto out;
12843 +- error = chown_common(nd.dentry, user, group);
12844 ++#ifdef CONFIG_VSERVER_COWBL
12845 ++ error = cow_check_and_break(&nd);
12846 ++ if (!error)
12847 ++#endif
12848 ++ error = chown_common(nd.dentry, nd.mnt, user, group);
12849 + path_release(&nd);
12850 + out:
12851 + return error;
12852 +@@ -633,7 +647,11 @@ asmlinkage long sys_fchownat(int dfd, co
12853 + error = __user_walk_fd(dfd, filename, follow, &nd);
12854 + if (error)
12855 + goto out;
12856 +- error = chown_common(nd.dentry, user, group);
12857 ++#ifdef CONFIG_VSERVER_COWBL
12858 ++ error = cow_check_and_break(&nd);
12859 ++ if (!error)
12860 ++#endif
12861 ++ error = chown_common(nd.dentry, nd.mnt, user, group);
12862 + path_release(&nd);
12863 + out:
12864 + return error;
12865 +@@ -647,7 +665,11 @@ asmlinkage long sys_lchown(const char __
12866 + error = user_path_walk_link(filename, &nd);
12867 + if (error)
12868 + goto out;
12869 +- error = chown_common(nd.dentry, user, group);
12870 ++#ifdef CONFIG_VSERVER_COWBL
12871 ++ error = cow_check_and_break(&nd);
12872 ++ if (!error)
12873 ++#endif
12874 ++ error = chown_common(nd.dentry, nd.mnt, user, group);
12875 + path_release(&nd);
12876 + out:
12877 + return error;
12878 +@@ -666,7 +688,7 @@ asmlinkage long sys_fchown(unsigned int
12879 +
12880 + dentry = file->f_path.dentry;
12881 + audit_inode(NULL, dentry->d_inode);
12882 +- error = chown_common(dentry, user, group);
12883 ++ error = chown_common(dentry, file->f_vfsmnt, user, group);
12884 + fput(file);
12885 + out:
12886 + return error;
12887 +@@ -893,6 +915,7 @@ repeat:
12888 + FD_SET(fd, fdt->open_fds);
12889 + FD_CLR(fd, fdt->close_on_exec);
12890 + files->next_fd = fd + 1;
12891 ++ vx_openfd_inc(fd);
12892 + #if 1
12893 + /* Sanity check */
12894 + if (fdt->fd[fd] != NULL) {
12895 +@@ -915,6 +938,7 @@ static void __put_unused_fd(struct files
12896 + __FD_CLR(fd, fdt->open_fds);
12897 + if (fd < files->next_fd)
12898 + files->next_fd = fd;
12899 ++ vx_openfd_dec(fd);
12900 + }
12901 +
12902 + void fastcall put_unused_fd(unsigned int fd)
12903 +diff -NurpP --minimal linux-2.6.22.19/fs/proc/array.c linux-2.6.22.19-vs2.2.0.7/fs/proc/array.c
12904 +--- linux-2.6.22.19/fs/proc/array.c 2007-07-09 13:19:28 +0200
12905 ++++ linux-2.6.22.19-vs2.2.0.7/fs/proc/array.c 2007-06-15 03:04:38 +0200
12906 +@@ -75,6 +75,8 @@
12907 + #include <linux/cpuset.h>
12908 + #include <linux/rcupdate.h>
12909 + #include <linux/delayacct.h>
12910 ++#include <linux/vs_context.h>
12911 ++#include <linux/vs_network.h>
12912 +
12913 + #include <asm/uaccess.h>
12914 + #include <asm/pgtable.h>
12915 +@@ -134,8 +136,9 @@ static const char *task_state_array[] =
12916 + "D (disk sleep)", /* 2 */
12917 + "T (stopped)", /* 4 */
12918 + "T (tracing stop)", /* 8 */
12919 +- "Z (zombie)", /* 16 */
12920 +- "X (dead)" /* 32 */
12921 ++ "H (on hold)", /* 16 */
12922 ++ "Z (zombie)", /* 32 */
12923 ++ "X (dead)", /* 64 */
12924 + };
12925 +
12926 + static inline const char * get_task_state(struct task_struct *tsk)
12927 +@@ -144,7 +147,8 @@ static inline const char * get_task_stat
12928 + TASK_INTERRUPTIBLE |
12929 + TASK_UNINTERRUPTIBLE |
12930 + TASK_STOPPED |
12931 +- TASK_TRACED)) |
12932 ++ TASK_TRACED |
12933 ++ TASK_ONHOLD)) |
12934 + (tsk->exit_state & (EXIT_ZOMBIE |
12935 + EXIT_DEAD));
12936 + const char **p = &task_state_array[0];
12937 +@@ -161,8 +165,16 @@ static inline char * task_state(struct t
12938 + struct group_info *group_info;
12939 + int g;
12940 + struct fdtable *fdt = NULL;
12941 ++ pid_t pid, ptgid, tppid, tgid;
12942 +
12943 + rcu_read_lock();
12944 ++ tgid = vx_map_tgid(p->tgid);
12945 ++ pid = vx_map_pid(p->pid);
12946 ++ ptgid = vx_map_pid(pid_alive(p) ?
12947 ++ rcu_dereference(p->real_parent)->tgid : 0);
12948 ++ tppid = vx_map_pid(pid_alive(p) && p->ptrace ?
12949 ++ rcu_dereference(p->parent)->pid : 0);
12950 ++
12951 + buffer += sprintf(buffer,
12952 + "State:\t%s\n"
12953 + "SleepAVG:\t%lu%%\n"
12954 +@@ -174,9 +186,7 @@ static inline char * task_state(struct t
12955 + "Gid:\t%d\t%d\t%d\t%d\n",
12956 + get_task_state(p),
12957 + (p->sleep_avg/1024)*100/(1020000000/1024),
12958 +- p->tgid, p->pid,
12959 +- pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0,
12960 +- pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0,
12961 ++ tgid, pid, (pid > 1) ? ptgid : 0, tppid,
12962 + p->uid, p->euid, p->suid, p->fsuid,
12963 + p->gid, p->egid, p->sgid, p->fsgid);
12964 +
12965 +@@ -283,17 +293,26 @@ static inline char * task_sig(struct tas
12966 +
12967 + static inline char *task_cap(struct task_struct *p, char *buffer)
12968 + {
12969 +- return buffer + sprintf(buffer, "CapInh:\t%016x\n"
12970 +- "CapPrm:\t%016x\n"
12971 +- "CapEff:\t%016x\n",
12972 +- cap_t(p->cap_inheritable),
12973 +- cap_t(p->cap_permitted),
12974 +- cap_t(p->cap_effective));
12975 ++ struct vx_info *vxi = p->vx_info;
12976 ++
12977 ++ return buffer + sprintf(buffer,
12978 ++ "CapInh:\t%016x\n"
12979 ++ "CapPrm:\t%016x\n"
12980 ++ "CapEff:\t%016x\n",
12981 ++ (unsigned)vx_info_mbcap(vxi, p->cap_inheritable),
12982 ++ (unsigned)vx_info_mbcap(vxi, p->cap_permitted),
12983 ++ (unsigned)vx_info_mbcap(vxi, p->cap_effective));
12984 + }
12985 +
12986 + int proc_pid_status(struct task_struct *task, char * buffer)
12987 + {
12988 + char * orig = buffer;
12989 ++#ifdef CONFIG_VSERVER_LEGACY
12990 ++ struct vx_info *vxi;
12991 ++#endif
12992 ++#ifdef CONFIG_VSERVER_LEGACYNET
12993 ++ struct nx_info *nxi;
12994 ++#endif
12995 + struct mm_struct *mm = get_task_mm(task);
12996 +
12997 + buffer = task_name(task, buffer);
12998 +@@ -306,6 +325,46 @@ int proc_pid_status(struct task_struct *
12999 + buffer = task_sig(task, buffer);
13000 + buffer = task_cap(task, buffer);
13001 + buffer = cpuset_task_status_allowed(task, buffer);
13002 ++
13003 ++ if (task_vx_flags(task, VXF_HIDE_VINFO, 0))
13004 ++ goto skip;
13005 ++#ifdef CONFIG_VSERVER_LEGACY
13006 ++ buffer += sprintf (buffer,"s_context: %d\n", vx_task_xid(task));
13007 ++ vxi = task_get_vx_info(task);
13008 ++ if (vxi) {
13009 ++ buffer += sprintf (buffer,"ctxflags: %08llx\n"
13010 ++ ,(unsigned long long)vxi->vx_flags);
13011 ++ buffer += sprintf (buffer,"initpid: %d\n"
13012 ++ ,vxi->vx_initpid);
13013 ++ } else {
13014 ++ buffer += sprintf (buffer,"ctxflags: none\n");
13015 ++ buffer += sprintf (buffer,"initpid: none\n");
13016 ++ }
13017 ++ put_vx_info(vxi);
13018 ++#else
13019 ++ buffer += sprintf (buffer,"VxID: %d\n", vx_task_xid(task));
13020 ++#endif
13021 ++#ifdef CONFIG_VSERVER_LEGACYNET
13022 ++ nxi = task_get_nx_info(task);
13023 ++ if (nxi) {
13024 ++ int i;
13025 ++
13026 ++ buffer += sprintf (buffer,"ipv4root:");
13027 ++ for (i=0; i<nxi->nbipv4; i++){
13028 ++ buffer += sprintf (buffer," %08x/%08x"
13029 ++ ,nxi->ipv4[i]
13030 ++ ,nxi->mask[i]);
13031 ++ }
13032 ++ *buffer++ = '\n';
13033 ++ buffer += sprintf (buffer,"ipv4root_bcast: %08x\n"
13034 ++ ,nxi->v4_bcast);
13035 ++ } else {
13036 ++ buffer += sprintf (buffer,"ipv4root: 0\n");
13037 ++ buffer += sprintf (buffer,"ipv4root_bcast: 0\n");
13038 ++ }
13039 ++ put_nx_info(nxi);
13040 ++#endif
13041 ++skip:
13042 + #if defined(CONFIG_S390)
13043 + buffer = task_show_regs(task, buffer);
13044 + #endif
13045 +@@ -320,7 +379,7 @@ static int do_task_stat(struct task_stru
13046 + sigset_t sigign, sigcatch;
13047 + char state;
13048 + int res;
13049 +- pid_t ppid = 0, pgid = -1, sid = -1;
13050 ++ pid_t pid = 0, ppid = 0, pgid = -1, sid = -1;
13051 + int num_threads = 0;
13052 + struct mm_struct *mm;
13053 + unsigned long long start_time;
13054 +@@ -382,8 +441,10 @@ static int do_task_stat(struct task_stru
13055 + }
13056 +
13057 + sid = signal_session(sig);
13058 +- pgid = process_group(task);
13059 +- ppid = rcu_dereference(task->real_parent)->tgid;
13060 ++ pid = vx_info_map_pid(task->vx_info, task->pid);
13061 ++ pgid = vx_info_map_pid(task->vx_info, process_group(task));
13062 ++ ppid = (pid > 1) ? vx_info_map_tgid(task->vx_info,
13063 ++ rcu_dereference(task->real_parent)->tgid) : 0;
13064 +
13065 + unlock_task_sighand(task, &flags);
13066 + }
13067 +@@ -410,10 +471,21 @@ static int do_task_stat(struct task_stru
13068 + /* convert nsec -> ticks */
13069 + start_time = nsec_to_clock_t(start_time);
13070 +
13071 ++ /* fixup start time for virt uptime */
13072 ++ if (vx_flags(VXF_VIRT_UPTIME, 0)) {
13073 ++ unsigned long long bias =
13074 ++ current->vx_info->cvirt.bias_clock;
13075 ++
13076 ++ if (start_time > bias)
13077 ++ start_time -= bias;
13078 ++ else
13079 ++ start_time = 0;
13080 ++ }
13081 ++
13082 + res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %u %lu \
13083 + %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
13084 + %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu\n",
13085 +- task->pid,
13086 ++ pid,
13087 + tcomm,
13088 + state,
13089 + ppid,
13090 +diff -NurpP --minimal linux-2.6.22.19/fs/proc/base.c linux-2.6.22.19-vs2.2.0.7/fs/proc/base.c
13091 +--- linux-2.6.22.19/fs/proc/base.c 2007-07-09 13:19:28 +0200
13092 ++++ linux-2.6.22.19-vs2.2.0.7/fs/proc/base.c 2008-03-14 19:55:59 +0100
13093 +@@ -73,6 +73,9 @@
13094 + #include <linux/poll.h>
13095 + #include <linux/nsproxy.h>
13096 + #include <linux/oom.h>
13097 ++#include <linux/vs_context.h>
13098 ++#include <linux/vs_network.h>
13099 ++
13100 + #include "internal.h"
13101 +
13102 + /* NOTE:
13103 +@@ -1049,6 +1052,8 @@ static struct inode *proc_pid_make_inode
13104 + inode->i_uid = task->euid;
13105 + inode->i_gid = task->egid;
13106 + }
13107 ++ /* procfs is xid tagged */
13108 ++ inode->i_tag = (tag_t)vx_task_xid(task);
13109 + security_task_to_inode(task, inode);
13110 +
13111 + out:
13112 +@@ -1082,6 +1087,8 @@ static int pid_getattr(struct vfsmount *
13113 +
13114 + /* dentry stuff */
13115 +
13116 ++static unsigned name_to_int(struct dentry *dentry);
13117 ++
13118 + /*
13119 + * Exceptional case: normally we are not allowed to unhash a busy
13120 + * directory. In this case, however, we can do it - no aliasing problems
13121 +@@ -1102,6 +1109,12 @@ static int pid_revalidate(struct dentry
13122 + struct inode *inode = dentry->d_inode;
13123 + struct task_struct *task = get_proc_task(inode);
13124 + if (task) {
13125 ++ unsigned pid = name_to_int(dentry);
13126 ++ if (pid != ~0U && pid != vx_map_pid(task->pid)) {
13127 ++ put_task_struct(task);
13128 ++ goto drop;
13129 ++ }
13130 ++
13131 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
13132 + task_dumpable(task)) {
13133 + inode->i_uid = task->euid;
13134 +@@ -1115,6 +1128,7 @@ static int pid_revalidate(struct dentry
13135 + put_task_struct(task);
13136 + return 1;
13137 + }
13138 ++drop:
13139 + d_drop(dentry);
13140 + return 0;
13141 + }
13142 +@@ -1595,6 +1609,13 @@ static struct dentry *proc_pident_lookup
13143 + if (!task)
13144 + goto out_no_task;
13145 +
13146 ++ /* TODO: maybe we can come up with a generic approach? */
13147 ++ if (task_vx_flags(task, VXF_HIDE_VINFO, 0) &&
13148 ++ (dentry->d_name.len == 5) &&
13149 ++ (!memcmp(dentry->d_name.name, "vinfo", 5) ||
13150 ++ !memcmp(dentry->d_name.name, "ninfo", 5)))
13151 ++ goto out;
13152 ++
13153 + /*
13154 + * Yes, it does not scale. And it should not. Don't add
13155 + * new entries into /proc/<tgid>/ without very good reasons.
13156 +@@ -1790,14 +1811,14 @@ static int proc_self_readlink(struct den
13157 + int buflen)
13158 + {
13159 + char tmp[PROC_NUMBUF];
13160 +- sprintf(tmp, "%d", current->tgid);
13161 ++ sprintf(tmp, "%d", vx_map_tgid(current->tgid));
13162 + return vfs_readlink(dentry,buffer,buflen,tmp);
13163 + }
13164 +
13165 + static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
13166 + {
13167 + char tmp[PROC_NUMBUF];
13168 +- sprintf(tmp, "%d", current->tgid);
13169 ++ sprintf(tmp, "%d", vx_map_tgid(current->tgid));
13170 + return ERR_PTR(vfs_follow_link(nd,tmp));
13171 + }
13172 +
13173 +@@ -1891,7 +1912,7 @@ out_iput:
13174 + static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
13175 + {
13176 + struct dentry *error;
13177 +- struct task_struct *task = get_proc_task(dir);
13178 ++ struct task_struct *task = get_proc_task_real(dir);
13179 + const struct pid_entry *p, *last;
13180 +
13181 + error = ERR_PTR(-ENOENT);
13182 +@@ -1956,6 +1977,9 @@ static int proc_pid_io_accounting(struct
13183 + static const struct file_operations proc_task_operations;
13184 + static const struct inode_operations proc_task_inode_operations;
13185 +
13186 ++extern int proc_pid_vx_info(struct task_struct *, char *);
13187 ++extern int proc_pid_nx_info(struct task_struct *, char *);
13188 ++
13189 + static const struct pid_entry tgid_base_stuff[] = {
13190 + DIR("task", S_IRUGO|S_IXUGO, task),
13191 + DIR("fd", S_IRUSR|S_IXUSR, fd),
13192 +@@ -1995,6 +2019,8 @@ static const struct pid_entry tgid_base_
13193 + #ifdef CONFIG_CPUSETS
13194 + REG("cpuset", S_IRUGO, cpuset),
13195 + #endif
13196 ++ INF("vinfo", S_IRUGO, pid_vx_info),
13197 ++ INF("ninfo", S_IRUGO, pid_nx_info),
13198 + INF("oom_score", S_IRUGO, oom_score),
13199 + REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust),
13200 + #ifdef CONFIG_AUDITSYSCALL
13201 +@@ -2141,9 +2167,11 @@ struct dentry *proc_pid_lookup(struct in
13202 + tgid = name_to_int(dentry);
13203 + if (tgid == ~0U)
13204 + goto out;
13205 ++ if (vx_current_initpid(tgid))
13206 ++ goto out;
13207 +
13208 + rcu_read_lock();
13209 +- task = find_task_by_pid(tgid);
13210 ++ task = vx_find_proc_task_by_pid(tgid);
13211 + if (task)
13212 + get_task_struct(task);
13213 + rcu_read_unlock();
13214 +@@ -2198,7 +2226,7 @@ static int proc_pid_fill_cache(struct fi
13215 + struct task_struct *task, int tgid)
13216 + {
13217 + char name[PROC_NUMBUF];
13218 +- int len = snprintf(name, sizeof(name), "%d", tgid);
13219 ++ int len = snprintf(name, sizeof(name), "%d", vx_map_tgid(tgid));
13220 + return proc_fill_cache(filp, dirent, filldir, name, len,
13221 + proc_pid_instantiate, task, NULL);
13222 + }
13223 +@@ -2207,7 +2235,7 @@ static int proc_pid_fill_cache(struct fi
13224 + int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
13225 + {
13226 + unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
13227 +- struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
13228 ++ struct task_struct *reaper = get_proc_task_real(filp->f_path.dentry->d_inode);
13229 + struct task_struct *task;
13230 + int tgid;
13231 +
13232 +@@ -2226,6 +2254,8 @@ int proc_pid_readdir(struct file * filp,
13233 + put_task_struct(task), task = next_tgid(tgid + 1)) {
13234 + tgid = task->pid;
13235 + filp->f_pos = tgid + TGID_OFFSET;
13236 ++ if (!vx_proc_task_visible(task))
13237 ++ continue;
13238 + if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
13239 + put_task_struct(task);
13240 + goto out;
13241 +@@ -2352,9 +2382,11 @@ static struct dentry *proc_task_lookup(s
13242 + tid = name_to_int(dentry);
13243 + if (tid == ~0U)
13244 + goto out;
13245 ++ if (vx_current_initpid(tid))
13246 ++ goto out;
13247 +
13248 + rcu_read_lock();
13249 +- task = find_task_by_pid(tid);
13250 ++ task = vx_find_proc_task_by_pid(tid);
13251 + if (task)
13252 + get_task_struct(task);
13253 + rcu_read_unlock();
13254 +@@ -2499,7 +2531,7 @@ static int proc_task_readdir(struct file
13255 + for (task = first_tid(leader, tid, pos - 2);
13256 + task;
13257 + task = next_tid(task), pos++) {
13258 +- tid = task->pid;
13259 ++ tid = vx_map_pid(task->pid);
13260 + if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) {
13261 + /* returning this tgid failed, save it as the first
13262 + * pid for the next readir call */
13263 +diff -NurpP --minimal linux-2.6.22.19/fs/proc/generic.c linux-2.6.22.19-vs2.2.0.7/fs/proc/generic.c
13264 +--- linux-2.6.22.19/fs/proc/generic.c 2007-07-09 13:19:28 +0200
13265 ++++ linux-2.6.22.19-vs2.2.0.7/fs/proc/generic.c 2007-06-15 03:08:54 +0200
13266 +@@ -20,6 +20,7 @@
13267 + #include <linux/namei.h>
13268 + #include <linux/bitops.h>
13269 + #include <linux/spinlock.h>
13270 ++#include <linux/vserver/inode.h>
13271 + #include <asm/uaccess.h>
13272 +
13273 + #include "internal.h"
13274 +@@ -395,6 +396,8 @@ struct dentry *proc_lookup(struct inode
13275 + for (de = de->subdir; de ; de = de->next) {
13276 + if (de->namelen != dentry->d_name.len)
13277 + continue;
13278 ++ if (!vx_hide_check(0, de->vx_flags))
13279 ++ continue;
13280 + if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
13281 + unsigned int ino = de->low_ino;
13282 +
13283 +@@ -402,6 +405,8 @@ struct dentry *proc_lookup(struct inode
13284 + spin_unlock(&proc_subdir_lock);
13285 + error = -EINVAL;
13286 + inode = proc_get_inode(dir->i_sb, ino, de);
13287 ++ /* generic proc entries belong to the host */
13288 ++ inode->i_tag = 0;
13289 + spin_lock(&proc_subdir_lock);
13290 + break;
13291 + }
13292 +@@ -482,6 +487,8 @@ int proc_readdir(struct file * filp,
13293 +
13294 + /* filldir passes info to user space */
13295 + de_get(de);
13296 ++ if (!vx_hide_check(0, de->vx_flags))
13297 ++ goto skip;
13298 + spin_unlock(&proc_subdir_lock);
13299 + if (filldir(dirent, de->name, de->namelen, filp->f_pos,
13300 + de->low_ino, de->mode >> 12) < 0) {
13301 +@@ -489,6 +496,7 @@ int proc_readdir(struct file * filp,
13302 + goto out;
13303 + }
13304 + spin_lock(&proc_subdir_lock);
13305 ++ skip:
13306 + filp->f_pos++;
13307 + next = de->next;
13308 + de_put(de);
13309 +@@ -613,6 +621,7 @@ static struct proc_dir_entry *proc_creat
13310 + ent->namelen = len;
13311 + ent->mode = mode;
13312 + ent->nlink = nlink;
13313 ++ ent->vx_flags = IATTR_PROC_DEFAULT;
13314 + out:
13315 + return ent;
13316 + }
13317 +@@ -633,7 +642,8 @@ struct proc_dir_entry *proc_symlink(cons
13318 + kfree(ent->data);
13319 + kfree(ent);
13320 + ent = NULL;
13321 +- }
13322 ++ } else
13323 ++ ent->vx_flags = IATTR_PROC_SYMLINK;
13324 + } else {
13325 + kfree(ent);
13326 + ent = NULL;
13327 +diff -NurpP --minimal linux-2.6.22.19/fs/proc/inode.c linux-2.6.22.19-vs2.2.0.7/fs/proc/inode.c
13328 +--- linux-2.6.22.19/fs/proc/inode.c 2007-07-09 13:19:28 +0200
13329 ++++ linux-2.6.22.19-vs2.2.0.7/fs/proc/inode.c 2007-06-15 02:37:03 +0200
13330 +@@ -160,6 +160,8 @@ struct inode *proc_get_inode(struct supe
13331 + inode->i_uid = de->uid;
13332 + inode->i_gid = de->gid;
13333 + }
13334 ++ if (de->vx_flags)
13335 ++ PROC_I(inode)->vx_flags = de->vx_flags;
13336 + if (de->size)
13337 + inode->i_size = de->size;
13338 + if (de->nlink)
13339 +diff -NurpP --minimal linux-2.6.22.19/fs/proc/internal.h linux-2.6.22.19-vs2.2.0.7/fs/proc/internal.h
13340 +--- linux-2.6.22.19/fs/proc/internal.h 2007-07-09 13:19:28 +0200
13341 ++++ linux-2.6.22.19-vs2.2.0.7/fs/proc/internal.h 2007-06-15 02:37:03 +0200
13342 +@@ -10,6 +10,7 @@
13343 + */
13344 +
13345 + #include <linux/proc_fs.h>
13346 ++#include <linux/vs_pid.h>
13347 +
13348 + #ifdef CONFIG_PROC_SYSCTL
13349 + extern int proc_sys_init(void);
13350 +@@ -64,11 +65,16 @@ static inline struct pid *proc_pid(struc
13351 + return PROC_I(inode)->pid;
13352 + }
13353 +
13354 +-static inline struct task_struct *get_proc_task(struct inode *inode)
13355 ++static inline struct task_struct *get_proc_task_real(struct inode *inode)
13356 + {
13357 + return get_pid_task(proc_pid(inode), PIDTYPE_PID);
13358 + }
13359 +
13360 ++static inline struct task_struct *get_proc_task(struct inode *inode)
13361 ++{
13362 ++ return vx_get_proc_task(inode, proc_pid(inode));
13363 ++}
13364 ++
13365 + static inline int proc_fd(struct inode *inode)
13366 + {
13367 + return PROC_I(inode)->fd;
13368 +diff -NurpP --minimal linux-2.6.22.19/fs/proc/proc_misc.c linux-2.6.22.19-vs2.2.0.7/fs/proc/proc_misc.c
13369 +--- linux-2.6.22.19/fs/proc/proc_misc.c 2007-07-09 13:19:28 +0200
13370 ++++ linux-2.6.22.19-vs2.2.0.7/fs/proc/proc_misc.c 2007-06-15 02:37:03 +0200
13371 +@@ -53,6 +53,8 @@
13372 + #include <asm/div64.h>
13373 + #include "internal.h"
13374 +
13375 ++#include <linux/vs_cvirt.h>
13376 ++
13377 + #define LOAD_INT(x) ((x) >> FSHIFT)
13378 + #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
13379 + /*
13380 +@@ -82,17 +84,32 @@ static int proc_calc_metrics(char *page,
13381 + static int loadavg_read_proc(char *page, char **start, off_t off,
13382 + int count, int *eof, void *data)
13383 + {
13384 ++ unsigned int running, threads;
13385 + int a, b, c;
13386 + int len;
13387 +
13388 +- a = avenrun[0] + (FIXED_1/200);
13389 +- b = avenrun[1] + (FIXED_1/200);
13390 +- c = avenrun[2] + (FIXED_1/200);
13391 +- len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
13392 ++ if (vx_flags(VXF_VIRT_LOAD, 0)) {
13393 ++ struct vx_info *vxi = current->vx_info;
13394 ++
13395 ++ a = vxi->cvirt.load[0] + (FIXED_1/200);
13396 ++ b = vxi->cvirt.load[1] + (FIXED_1/200);
13397 ++ c = vxi->cvirt.load[2] + (FIXED_1/200);
13398 ++
13399 ++ running = atomic_read(&vxi->cvirt.nr_running);
13400 ++ threads = atomic_read(&vxi->cvirt.nr_threads);
13401 ++ } else {
13402 ++ a = avenrun[0] + (FIXED_1/200);
13403 ++ b = avenrun[1] + (FIXED_1/200);
13404 ++ c = avenrun[2] + (FIXED_1/200);
13405 ++
13406 ++ running = nr_running();
13407 ++ threads = nr_threads;
13408 ++ }
13409 ++ len = sprintf(page,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
13410 + LOAD_INT(a), LOAD_FRAC(a),
13411 + LOAD_INT(b), LOAD_FRAC(b),
13412 + LOAD_INT(c), LOAD_FRAC(c),
13413 +- nr_running(), nr_threads, current->nsproxy->pid_ns->last_pid);
13414 ++ running, threads, current->nsproxy->pid_ns->last_pid);
13415 + return proc_calc_metrics(page, start, off, count, eof, len);
13416 + }
13417 +
13418 +@@ -106,6 +123,9 @@ static int uptime_read_proc(char *page,
13419 +
13420 + do_posix_clock_monotonic_gettime(&uptime);
13421 + cputime_to_timespec(idletime, &idle);
13422 ++ if (vx_flags(VXF_VIRT_UPTIME, 0))
13423 ++ vx_vsi_uptime(&uptime, &idle);
13424 ++
13425 + len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
13426 + (unsigned long) uptime.tv_sec,
13427 + (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
13428 +@@ -137,7 +157,7 @@ static int meminfo_read_proc(char *page,
13429 +
13430 + cached = global_page_state(NR_FILE_PAGES) -
13431 + total_swapcache_pages - i.bufferram;
13432 +- if (cached < 0)
13433 ++ if (cached < 0 || vx_flags(VXF_VIRT_MEM, 0))
13434 + cached = 0;
13435 +
13436 + get_vmalloc_info(&vmi);
13437 +diff -NurpP --minimal linux-2.6.22.19/fs/proc/root.c linux-2.6.22.19-vs2.2.0.7/fs/proc/root.c
13438 +--- linux-2.6.22.19/fs/proc/root.c 2007-05-02 19:25:21 +0200
13439 ++++ linux-2.6.22.19-vs2.2.0.7/fs/proc/root.c 2007-06-15 02:37:03 +0200
13440 +@@ -22,6 +22,9 @@
13441 + #include "internal.h"
13442 +
13443 + struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver;
13444 ++struct proc_dir_entry *proc_virtual;
13445 ++
13446 ++extern void proc_vx_init(void);
13447 +
13448 + static int proc_get_sb(struct file_system_type *fs_type,
13449 + int flags, const char *dev_name, void *data, struct vfsmount *mnt)
13450 +@@ -79,6 +82,7 @@ void __init proc_root_init(void)
13451 + proc_device_tree_init();
13452 + #endif
13453 + proc_bus = proc_mkdir("bus", NULL);
13454 ++ proc_vx_init();
13455 + proc_sys_init();
13456 + }
13457 +
13458 +diff -NurpP --minimal linux-2.6.22.19/fs/quota.c linux-2.6.22.19-vs2.2.0.7/fs/quota.c
13459 +--- linux-2.6.22.19/fs/quota.c 2007-07-09 13:19:28 +0200
13460 ++++ linux-2.6.22.19-vs2.2.0.7/fs/quota.c 2007-06-15 02:37:03 +0200
13461 +@@ -16,6 +16,7 @@
13462 + #include <linux/buffer_head.h>
13463 + #include <linux/capability.h>
13464 + #include <linux/quotaops.h>
13465 ++#include <linux/vs_context.h>
13466 +
13467 + /* Check validity of generic quotactl commands */
13468 + static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
13469 +@@ -80,11 +81,11 @@ static int generic_quotactl_valid(struct
13470 + if (cmd == Q_GETQUOTA) {
13471 + if (((type == USRQUOTA && current->euid != id) ||
13472 + (type == GRPQUOTA && !in_egroup_p(id))) &&
13473 +- !capable(CAP_SYS_ADMIN))
13474 ++ !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
13475 + return -EPERM;
13476 + }
13477 + else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO)
13478 +- if (!capable(CAP_SYS_ADMIN))
13479 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
13480 + return -EPERM;
13481 +
13482 + return 0;
13483 +@@ -131,10 +132,10 @@ static int xqm_quotactl_valid(struct sup
13484 + if (cmd == Q_XGETQUOTA) {
13485 + if (((type == XQM_USRQUOTA && current->euid != id) ||
13486 + (type == XQM_GRPQUOTA && !in_egroup_p(id))) &&
13487 +- !capable(CAP_SYS_ADMIN))
13488 ++ !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
13489 + return -EPERM;
13490 + } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) {
13491 +- if (!capable(CAP_SYS_ADMIN))
13492 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
13493 + return -EPERM;
13494 + }
13495 +
13496 +@@ -327,6 +328,46 @@ static int do_quotactl(struct super_bloc
13497 + return 0;
13498 + }
13499 +
13500 ++#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
13501 ++
13502 ++#include <linux/vroot.h>
13503 ++#include <linux/major.h>
13504 ++#include <linux/module.h>
13505 ++#include <linux/kallsyms.h>
13506 ++#include <linux/vserver/debug.h>
13507 ++
13508 ++static vroot_grb_func *vroot_get_real_bdev = NULL;
13509 ++
13510 ++static spinlock_t vroot_grb_lock = SPIN_LOCK_UNLOCKED;
13511 ++
13512 ++int register_vroot_grb(vroot_grb_func *func) {
13513 ++ int ret = -EBUSY;
13514 ++
13515 ++ spin_lock(&vroot_grb_lock);
13516 ++ if (!vroot_get_real_bdev) {
13517 ++ vroot_get_real_bdev = func;
13518 ++ ret = 0;
13519 ++ }
13520 ++ spin_unlock(&vroot_grb_lock);
13521 ++ return ret;
13522 ++}
13523 ++EXPORT_SYMBOL(register_vroot_grb);
13524 ++
13525 ++int unregister_vroot_grb(vroot_grb_func *func) {
13526 ++ int ret = -EINVAL;
13527 ++
13528 ++ spin_lock(&vroot_grb_lock);
13529 ++ if (vroot_get_real_bdev) {
13530 ++ vroot_get_real_bdev = NULL;
13531 ++ ret = 0;
13532 ++ }
13533 ++ spin_unlock(&vroot_grb_lock);
13534 ++ return ret;
13535 ++}
13536 ++EXPORT_SYMBOL(unregister_vroot_grb);
13537 ++
13538 ++#endif
13539 ++
13540 + /*
13541 + * look up a superblock on which quota ops will be performed
13542 + * - use the name of a block device to find the superblock thereon
13543 +@@ -344,6 +385,22 @@ static inline struct super_block *quotac
13544 + putname(tmp);
13545 + if (IS_ERR(bdev))
13546 + return ERR_PTR(PTR_ERR(bdev));
13547 ++#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
13548 ++ if (bdev && bdev->bd_inode &&
13549 ++ imajor(bdev->bd_inode) == VROOT_MAJOR) {
13550 ++ struct block_device *bdnew = (void *)-EINVAL;
13551 ++
13552 ++ if (vroot_get_real_bdev)
13553 ++ bdnew = vroot_get_real_bdev(bdev);
13554 ++ else
13555 ++ vxdprintk(VXD_CBIT(misc, 0),
13556 ++ "vroot_get_real_bdev not set");
13557 ++ bdput(bdev);
13558 ++ if (IS_ERR(bdnew))
13559 ++ return ERR_PTR(PTR_ERR(bdnew));
13560 ++ bdev = bdnew;
13561 ++ }
13562 ++#endif
13563 + sb = get_super(bdev);
13564 + bdput(bdev);
13565 + if (!sb)
13566 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/bitmap.c linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/bitmap.c
13567 +--- linux-2.6.22.19/fs/reiserfs/bitmap.c 2007-02-06 03:01:29 +0100
13568 ++++ linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/bitmap.c 2007-06-15 02:37:03 +0200
13569 +@@ -13,6 +13,7 @@
13570 + #include <linux/reiserfs_fs_sb.h>
13571 + #include <linux/reiserfs_fs_i.h>
13572 + #include <linux/quotaops.h>
13573 ++#include <linux/vs_dlimit.h>
13574 +
13575 + #define PREALLOCATION_SIZE 9
13576 +
13577 +@@ -425,8 +426,10 @@ static void _reiserfs_free_block(struct
13578 + set_sb_free_blocks(rs, sb_free_blocks(rs) + 1);
13579 +
13580 + journal_mark_dirty(th, s, sbh);
13581 +- if (for_unformatted)
13582 ++ if (for_unformatted) {
13583 ++ DLIMIT_FREE_BLOCK(inode, 1);
13584 + DQUOT_FREE_BLOCK_NODIRTY(inode, 1);
13585 ++ }
13586 + }
13587 +
13588 + void reiserfs_free_block(struct reiserfs_transaction_handle *th,
13589 +@@ -1034,6 +1037,7 @@ static inline int blocknrs_and_prealloc_
13590 + b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1;
13591 + int passno = 0;
13592 + int nr_allocated = 0;
13593 ++ int blocks;
13594 +
13595 + determine_prealloc_size(hint);
13596 + if (!hint->formatted_node) {
13597 +@@ -1043,19 +1047,30 @@ static inline int blocknrs_and_prealloc_
13598 + "reiserquota: allocating %d blocks id=%u",
13599 + amount_needed, hint->inode->i_uid);
13600 + #endif
13601 +- quota_ret =
13602 +- DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, amount_needed);
13603 +- if (quota_ret) /* Quota exceeded? */
13604 ++ quota_ret = DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode,
13605 ++ amount_needed);
13606 ++ if (quota_ret)
13607 + return QUOTA_EXCEEDED;
13608 ++ if (DLIMIT_ALLOC_BLOCK(hint->inode, amount_needed)) {
13609 ++ DQUOT_FREE_BLOCK_NODIRTY(hint->inode,
13610 ++ amount_needed);
13611 ++ return NO_DISK_SPACE;
13612 ++ }
13613 ++
13614 + if (hint->preallocate && hint->prealloc_size) {
13615 + #ifdef REISERQUOTA_DEBUG
13616 + reiserfs_debug(s, REISERFS_DEBUG_CODE,
13617 + "reiserquota: allocating (prealloc) %d blocks id=%u",
13618 + hint->prealloc_size, hint->inode->i_uid);
13619 + #endif
13620 +- quota_ret =
13621 +- DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode,
13622 +- hint->prealloc_size);
13623 ++ quota_ret = DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode,
13624 ++ hint->prealloc_size);
13625 ++ if (!quota_ret &&
13626 ++ DLIMIT_ALLOC_BLOCK(hint->inode, hint->prealloc_size)) {
13627 ++ DQUOT_FREE_BLOCK_NODIRTY(hint->inode,
13628 ++ hint->prealloc_size);
13629 ++ quota_ret = 1;
13630 ++ }
13631 + if (quota_ret)
13632 + hint->preallocate = hint->prealloc_size = 0;
13633 + }
13634 +@@ -1087,7 +1102,10 @@ static inline int blocknrs_and_prealloc_
13635 + nr_allocated,
13636 + hint->inode->i_uid);
13637 + #endif
13638 +- DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated); /* Free not allocated blocks */
13639 ++ /* Free not allocated blocks */
13640 ++ blocks = amount_needed + hint->prealloc_size - nr_allocated;
13641 ++ DLIMIT_FREE_BLOCK(hint->inode, blocks);
13642 ++ DQUOT_FREE_BLOCK_NODIRTY(hint->inode, blocks);
13643 + }
13644 + while (nr_allocated--)
13645 + reiserfs_free_block(hint->th, hint->inode,
13646 +@@ -1118,10 +1136,10 @@ static inline int blocknrs_and_prealloc_
13647 + REISERFS_I(hint->inode)->i_prealloc_count,
13648 + hint->inode->i_uid);
13649 + #endif
13650 +- DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed +
13651 +- hint->prealloc_size - nr_allocated -
13652 +- REISERFS_I(hint->inode)->
13653 +- i_prealloc_count);
13654 ++ blocks = amount_needed + hint->prealloc_size - nr_allocated -
13655 ++ REISERFS_I(hint->inode)->i_prealloc_count;
13656 ++ DLIMIT_FREE_BLOCK(hint->inode, blocks);
13657 ++ DQUOT_FREE_BLOCK_NODIRTY(hint->inode, blocks);
13658 + }
13659 +
13660 + return CARRY_ON;
13661 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/file.c linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/file.c
13662 +--- linux-2.6.22.19/fs/reiserfs/file.c 2007-07-09 13:19:28 +0200
13663 ++++ linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/file.c 2007-10-29 23:24:21 +0100
13664 +@@ -1546,4 +1546,5 @@ const struct inode_operations reiserfs_f
13665 + .listxattr = reiserfs_listxattr,
13666 + .removexattr = reiserfs_removexattr,
13667 + .permission = reiserfs_permission,
13668 ++ .sync_flags = reiserfs_sync_flags,
13669 + };
13670 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/inode.c linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/inode.c
13671 +--- linux-2.6.22.19/fs/reiserfs/inode.c 2007-07-09 13:19:28 +0200
13672 ++++ linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/inode.c 2007-06-15 02:37:03 +0200
13673 +@@ -16,6 +16,8 @@
13674 + #include <linux/mpage.h>
13675 + #include <linux/writeback.h>
13676 + #include <linux/quotaops.h>
13677 ++#include <linux/vs_dlimit.h>
13678 ++#include <linux/vs_tag.h>
13679 +
13680 + static int reiserfs_commit_write(struct file *f, struct page *page,
13681 + unsigned from, unsigned to);
13682 +@@ -50,6 +52,7 @@ void reiserfs_delete_inode(struct inode
13683 + * stat data deletion */
13684 + if (!err)
13685 + DQUOT_FREE_INODE(inode);
13686 ++ DLIMIT_FREE_INODE(inode);
13687 +
13688 + if (journal_end(&th, inode->i_sb, jbegin_count))
13689 + goto out;
13690 +@@ -1112,6 +1115,8 @@ static void init_inode(struct inode *ino
13691 + struct buffer_head *bh;
13692 + struct item_head *ih;
13693 + __u32 rdev;
13694 ++ uid_t uid;
13695 ++ gid_t gid;
13696 + //int version = ITEM_VERSION_1;
13697 +
13698 + bh = PATH_PLAST_BUFFER(path);
13699 +@@ -1135,12 +1140,13 @@ static void init_inode(struct inode *ino
13700 + (struct stat_data_v1 *)B_I_PITEM(bh, ih);
13701 + unsigned long blocks;
13702 +
13703 ++ uid = sd_v1_uid(sd);
13704 ++ gid = sd_v1_gid(sd);
13705 ++
13706 + set_inode_item_key_version(inode, KEY_FORMAT_3_5);
13707 + set_inode_sd_version(inode, STAT_DATA_V1);
13708 + inode->i_mode = sd_v1_mode(sd);
13709 + inode->i_nlink = sd_v1_nlink(sd);
13710 +- inode->i_uid = sd_v1_uid(sd);
13711 +- inode->i_gid = sd_v1_gid(sd);
13712 + inode->i_size = sd_v1_size(sd);
13713 + inode->i_atime.tv_sec = sd_v1_atime(sd);
13714 + inode->i_mtime.tv_sec = sd_v1_mtime(sd);
13715 +@@ -1182,11 +1188,12 @@ static void init_inode(struct inode *ino
13716 + // (directories and symlinks)
13717 + struct stat_data *sd = (struct stat_data *)B_I_PITEM(bh, ih);
13718 +
13719 ++ uid = sd_v2_uid(sd);
13720 ++ gid = sd_v2_gid(sd);
13721 ++
13722 + inode->i_mode = sd_v2_mode(sd);
13723 + inode->i_nlink = sd_v2_nlink(sd);
13724 +- inode->i_uid = sd_v2_uid(sd);
13725 + inode->i_size = sd_v2_size(sd);
13726 +- inode->i_gid = sd_v2_gid(sd);
13727 + inode->i_mtime.tv_sec = sd_v2_mtime(sd);
13728 + inode->i_atime.tv_sec = sd_v2_atime(sd);
13729 + inode->i_ctime.tv_sec = sd_v2_ctime(sd);
13730 +@@ -1216,6 +1223,10 @@ static void init_inode(struct inode *ino
13731 + sd_attrs_to_i_attrs(sd_v2_attrs(sd), inode);
13732 + }
13733 +
13734 ++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
13735 ++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
13736 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid, 0);
13737 ++
13738 + pathrelse(path);
13739 + if (S_ISREG(inode->i_mode)) {
13740 + inode->i_op = &reiserfs_file_inode_operations;
13741 +@@ -1238,13 +1249,15 @@ static void init_inode(struct inode *ino
13742 + static void inode2sd(void *sd, struct inode *inode, loff_t size)
13743 + {
13744 + struct stat_data *sd_v2 = (struct stat_data *)sd;
13745 ++ uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
13746 ++ gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
13747 + __u16 flags;
13748 +
13749 ++ set_sd_v2_uid(sd_v2, uid);
13750 ++ set_sd_v2_gid(sd_v2, gid);
13751 + set_sd_v2_mode(sd_v2, inode->i_mode);
13752 + set_sd_v2_nlink(sd_v2, inode->i_nlink);
13753 +- set_sd_v2_uid(sd_v2, inode->i_uid);
13754 + set_sd_v2_size(sd_v2, size);
13755 +- set_sd_v2_gid(sd_v2, inode->i_gid);
13756 + set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec);
13757 + set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec);
13758 + set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec);
13759 +@@ -1775,6 +1788,10 @@ int reiserfs_new_inode(struct reiserfs_t
13760 +
13761 + BUG_ON(!th->t_trans_id);
13762 +
13763 ++ if (DLIMIT_ALLOC_INODE(inode)) {
13764 ++ err = -ENOSPC;
13765 ++ goto out_bad_dlimit;
13766 ++ }
13767 + if (DQUOT_ALLOC_INODE(inode)) {
13768 + err = -EDQUOT;
13769 + goto out_end_trans;
13770 +@@ -1960,6 +1977,9 @@ int reiserfs_new_inode(struct reiserfs_t
13771 + DQUOT_FREE_INODE(inode);
13772 +
13773 + out_end_trans:
13774 ++ DLIMIT_FREE_INODE(inode);
13775 ++
13776 ++ out_bad_dlimit:
13777 + journal_end(th, th->t_super, th->t_blocks_allocated);
13778 + /* Drop can be outside and it needs more credits so it's better to have it outside */
13779 + DQUOT_DROP(inode);
13780 +@@ -2690,6 +2710,14 @@ void sd_attrs_to_i_attrs(__u16 sd_attrs,
13781 + inode->i_flags |= S_IMMUTABLE;
13782 + else
13783 + inode->i_flags &= ~S_IMMUTABLE;
13784 ++ if (sd_attrs & REISERFS_IUNLINK_FL)
13785 ++ inode->i_flags |= S_IUNLINK;
13786 ++ else
13787 ++ inode->i_flags &= ~S_IUNLINK;
13788 ++ if (sd_attrs & REISERFS_BARRIER_FL)
13789 ++ inode->i_flags |= S_BARRIER;
13790 ++ else
13791 ++ inode->i_flags &= ~S_BARRIER;
13792 + if (sd_attrs & REISERFS_APPEND_FL)
13793 + inode->i_flags |= S_APPEND;
13794 + else
13795 +@@ -2712,6 +2740,14 @@ void i_attrs_to_sd_attrs(struct inode *i
13796 + *sd_attrs |= REISERFS_IMMUTABLE_FL;
13797 + else
13798 + *sd_attrs &= ~REISERFS_IMMUTABLE_FL;
13799 ++ if (inode->i_flags & S_IUNLINK)
13800 ++ *sd_attrs |= REISERFS_IUNLINK_FL;
13801 ++ else
13802 ++ *sd_attrs &= ~REISERFS_IUNLINK_FL;
13803 ++ if (inode->i_flags & S_BARRIER)
13804 ++ *sd_attrs |= REISERFS_BARRIER_FL;
13805 ++ else
13806 ++ *sd_attrs &= ~REISERFS_BARRIER_FL;
13807 + if (inode->i_flags & S_SYNC)
13808 + *sd_attrs |= REISERFS_SYNC_FL;
13809 + else
13810 +@@ -2891,6 +2927,22 @@ static ssize_t reiserfs_direct_IO(int rw
13811 + reiserfs_get_blocks_direct_io, NULL);
13812 + }
13813 +
13814 ++int reiserfs_sync_flags(struct inode *inode)
13815 ++{
13816 ++ u16 oldflags, newflags;
13817 ++
13818 ++ oldflags = REISERFS_I(inode)->i_attrs;
13819 ++ newflags = oldflags;
13820 ++ i_attrs_to_sd_attrs(inode, &newflags);
13821 ++
13822 ++ if (oldflags ^ newflags) {
13823 ++ REISERFS_I(inode)->i_attrs = newflags;
13824 ++ inode->i_ctime = CURRENT_TIME_SEC;
13825 ++ mark_inode_dirty(inode);
13826 ++ }
13827 ++ return 0;
13828 ++}
13829 ++
13830 + int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
13831 + {
13832 + struct inode *inode = dentry->d_inode;
13833 +@@ -2940,9 +2992,11 @@ int reiserfs_setattr(struct dentry *dent
13834 + }
13835 +
13836 + error = inode_change_ok(inode, attr);
13837 ++
13838 + if (!error) {
13839 + if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
13840 +- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
13841 ++ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
13842 ++ (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) {
13843 + error = reiserfs_chown_xattrs(inode, attr);
13844 +
13845 + if (!error) {
13846 +@@ -2972,6 +3026,9 @@ int reiserfs_setattr(struct dentry *dent
13847 + inode->i_uid = attr->ia_uid;
13848 + if (attr->ia_valid & ATTR_GID)
13849 + inode->i_gid = attr->ia_gid;
13850 ++ if ((attr->ia_valid & ATTR_TAG) &&
13851 ++ IS_TAGGED(inode))
13852 ++ inode->i_tag = attr->ia_tag;
13853 + mark_inode_dirty(inode);
13854 + error =
13855 + journal_end(&th, inode->i_sb, jbegin_count);
13856 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/ioctl.c linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/ioctl.c
13857 +--- linux-2.6.22.19/fs/reiserfs/ioctl.c 2007-02-06 03:01:29 +0100
13858 ++++ linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/ioctl.c 2007-06-15 02:37:03 +0200
13859 +@@ -4,6 +4,7 @@
13860 +
13861 + #include <linux/capability.h>
13862 + #include <linux/fs.h>
13863 ++#include <linux/mount.h>
13864 + #include <linux/reiserfs_fs.h>
13865 + #include <linux/time.h>
13866 + #include <asm/uaccess.h>
13867 +@@ -24,7 +25,7 @@ static int reiserfs_unpack(struct inode
13868 + int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
13869 + unsigned long arg)
13870 + {
13871 +- unsigned int flags;
13872 ++ unsigned int flags, oldflags;
13873 +
13874 + switch (cmd) {
13875 + case REISERFS_IOC_UNPACK:
13876 +@@ -43,12 +44,14 @@ int reiserfs_ioctl(struct inode *inode,
13877 +
13878 + flags = REISERFS_I(inode)->i_attrs;
13879 + i_attrs_to_sd_attrs(inode, (__u16 *) & flags);
13880 ++ flags &= REISERFS_FL_USER_VISIBLE;
13881 + return put_user(flags, (int __user *)arg);
13882 + case REISERFS_IOC_SETFLAGS:{
13883 + if (!reiserfs_attrs(inode->i_sb))
13884 + return -ENOTTY;
13885 +
13886 +- if (IS_RDONLY(inode))
13887 ++ if (IS_RDONLY(inode) ||
13888 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
13889 + return -EROFS;
13890 +
13891 + if ((current->fsuid != inode->i_uid)
13892 +@@ -58,10 +61,12 @@ int reiserfs_ioctl(struct inode *inode,
13893 + if (get_user(flags, (int __user *)arg))
13894 + return -EFAULT;
13895 +
13896 +- if (((flags ^ REISERFS_I(inode)->
13897 +- i_attrs) & (REISERFS_IMMUTABLE_FL |
13898 +- REISERFS_APPEND_FL))
13899 +- && !capable(CAP_LINUX_IMMUTABLE))
13900 ++ oldflags = REISERFS_I(inode) -> i_attrs;
13901 ++ if (((oldflags & REISERFS_IMMUTABLE_FL) ||
13902 ++ ((flags ^ oldflags) &
13903 ++ (REISERFS_IMMUTABLE_FL | REISERFS_IUNLINK_FL |
13904 ++ REISERFS_APPEND_FL))) &&
13905 ++ !capable(CAP_LINUX_IMMUTABLE))
13906 + return -EPERM;
13907 +
13908 + if ((flags & REISERFS_NOTAIL_FL) &&
13909 +@@ -72,6 +77,9 @@ int reiserfs_ioctl(struct inode *inode,
13910 + if (result)
13911 + return result;
13912 + }
13913 ++
13914 ++ flags = flags & REISERFS_FL_USER_MODIFIABLE;
13915 ++ flags |= oldflags & ~REISERFS_FL_USER_MODIFIABLE;
13916 + sd_attrs_to_i_attrs(flags, inode);
13917 + REISERFS_I(inode)->i_attrs = flags;
13918 + inode->i_ctime = CURRENT_TIME_SEC;
13919 +@@ -83,7 +91,8 @@ int reiserfs_ioctl(struct inode *inode,
13920 + case REISERFS_IOC_SETVERSION:
13921 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
13922 + return -EPERM;
13923 +- if (IS_RDONLY(inode))
13924 ++ if (IS_RDONLY(inode) ||
13925 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
13926 + return -EROFS;
13927 + if (get_user(inode->i_generation, (int __user *)arg))
13928 + return -EFAULT;
13929 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/namei.c linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/namei.c
13930 +--- linux-2.6.22.19/fs/reiserfs/namei.c 2007-07-09 13:19:28 +0200
13931 ++++ linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/namei.c 2007-06-15 02:37:03 +0200
13932 +@@ -17,6 +17,7 @@
13933 + #include <linux/reiserfs_acl.h>
13934 + #include <linux/reiserfs_xattr.h>
13935 + #include <linux/quotaops.h>
13936 ++#include <linux/vs_tag.h>
13937 +
13938 + #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { inc_nlink(i); if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; }
13939 + #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) drop_nlink(i);
13940 +@@ -360,6 +361,7 @@ static struct dentry *reiserfs_lookup(st
13941 + reiserfs_write_unlock(dir->i_sb);
13942 + return ERR_PTR(-EACCES);
13943 + }
13944 ++ dx_propagate_tag(nd, inode);
13945 +
13946 + /* Propogate the priv_object flag so we know we're in the priv tree */
13947 + if (is_reiserfs_priv_object(dir))
13948 +@@ -595,6 +597,7 @@ static int new_inode_init(struct inode *
13949 + } else {
13950 + inode->i_gid = current->fsgid;
13951 + }
13952 ++ inode->i_tag = dx_current_fstag(inode->i_sb);
13953 + DQUOT_INIT(inode);
13954 + return 0;
13955 + }
13956 +@@ -1541,6 +1544,7 @@ const struct inode_operations reiserfs_d
13957 + .listxattr = reiserfs_listxattr,
13958 + .removexattr = reiserfs_removexattr,
13959 + .permission = reiserfs_permission,
13960 ++ .sync_flags = reiserfs_sync_flags,
13961 + };
13962 +
13963 + /*
13964 +@@ -1557,6 +1561,7 @@ const struct inode_operations reiserfs_s
13965 + .listxattr = reiserfs_listxattr,
13966 + .removexattr = reiserfs_removexattr,
13967 + .permission = reiserfs_permission,
13968 ++ .sync_flags = reiserfs_sync_flags,
13969 +
13970 + };
13971 +
13972 +@@ -1570,5 +1575,6 @@ const struct inode_operations reiserfs_s
13973 + .listxattr = reiserfs_listxattr,
13974 + .removexattr = reiserfs_removexattr,
13975 + .permission = reiserfs_permission,
13976 ++ .sync_flags = reiserfs_sync_flags,
13977 +
13978 + };
13979 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/stree.c linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/stree.c
13980 +--- linux-2.6.22.19/fs/reiserfs/stree.c 2007-07-09 13:19:28 +0200
13981 ++++ linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/stree.c 2007-06-15 02:37:03 +0200
13982 +@@ -55,6 +55,7 @@
13983 + #include <linux/reiserfs_fs.h>
13984 + #include <linux/buffer_head.h>
13985 + #include <linux/quotaops.h>
13986 ++#include <linux/vs_dlimit.h>
13987 +
13988 + /* Does the buffer contain a disk block which is in the tree. */
13989 + inline int B_IS_IN_TREE(const struct buffer_head *p_s_bh)
13990 +@@ -1296,6 +1297,7 @@ int reiserfs_delete_item(struct reiserfs
13991 + "reiserquota delete_item(): freeing %u, id=%u type=%c",
13992 + quota_cut_bytes, p_s_inode->i_uid, head2type(&s_ih));
13993 + #endif
13994 ++ DLIMIT_FREE_SPACE(p_s_inode, quota_cut_bytes);
13995 + DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
13996 +
13997 + /* Return deleted body length */
13998 +@@ -1384,6 +1386,7 @@ void reiserfs_delete_solid_item(struct r
13999 + #endif
14000 + DQUOT_FREE_SPACE_NODIRTY(inode,
14001 + quota_cut_bytes);
14002 ++ DLIMIT_FREE_SPACE(inode, quota_cut_bytes);
14003 + }
14004 + break;
14005 + }
14006 +@@ -1737,6 +1740,7 @@ int reiserfs_cut_from_item(struct reiser
14007 + "reiserquota cut_from_item(): freeing %u id=%u type=%c",
14008 + quota_cut_bytes, p_s_inode->i_uid, '?');
14009 + #endif
14010 ++ DLIMIT_FREE_SPACE(p_s_inode, quota_cut_bytes);
14011 + DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
14012 + return n_ret_value;
14013 + }
14014 +@@ -1978,6 +1982,11 @@ int reiserfs_paste_into_item(struct reis
14015 + pathrelse(p_s_search_path);
14016 + return -EDQUOT;
14017 + }
14018 ++ if (DLIMIT_ALLOC_SPACE(inode, n_pasted_size)) {
14019 ++ DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
14020 ++ pathrelse(p_s_search_path);
14021 ++ return -ENOSPC;
14022 ++ }
14023 + init_tb_struct(th, &s_paste_balance, th->t_super, p_s_search_path,
14024 + n_pasted_size);
14025 + #ifdef DISPLACE_NEW_PACKING_LOCALITIES
14026 +@@ -2030,6 +2039,7 @@ int reiserfs_paste_into_item(struct reis
14027 + n_pasted_size, inode->i_uid,
14028 + key2type(&(p_s_key->on_disk_key)));
14029 + #endif
14030 ++ DLIMIT_FREE_SPACE(inode, n_pasted_size);
14031 + DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
14032 + return retval;
14033 + }
14034 +@@ -2067,6 +2077,11 @@ int reiserfs_insert_item(struct reiserfs
14035 + pathrelse(p_s_path);
14036 + return -EDQUOT;
14037 + }
14038 ++ if (DLIMIT_ALLOC_SPACE(inode, quota_bytes)) {
14039 ++ DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes);
14040 ++ pathrelse(p_s_path);
14041 ++ return -ENOSPC;
14042 ++ }
14043 + }
14044 + init_tb_struct(th, &s_ins_balance, th->t_super, p_s_path,
14045 + IH_SIZE + ih_item_len(p_s_ih));
14046 +@@ -2114,7 +2129,9 @@ int reiserfs_insert_item(struct reiserfs
14047 + "reiserquota insert_item(): freeing %u id=%u type=%c",
14048 + quota_bytes, inode->i_uid, head2type(p_s_ih));
14049 + #endif
14050 +- if (inode)
14051 ++ if (inode) {
14052 ++ DLIMIT_FREE_SPACE(inode, quota_bytes);
14053 + DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes);
14054 ++ }
14055 + return retval;
14056 + }
14057 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/super.c linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/super.c
14058 +--- linux-2.6.22.19/fs/reiserfs/super.c 2007-07-09 13:19:28 +0200
14059 ++++ linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/super.c 2007-06-15 02:37:03 +0200
14060 +@@ -882,6 +882,14 @@ static int reiserfs_parse_options(struct
14061 + {"user_xattr",.setmask = 1 << REISERFS_UNSUPPORTED_OPT},
14062 + {"nouser_xattr",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},
14063 + #endif
14064 ++#ifndef CONFIG_TAGGING_NONE
14065 ++ {"tagxid",.setmask = 1 << REISERFS_TAGGED},
14066 ++ {"tag",.setmask = 1 << REISERFS_TAGGED},
14067 ++ {"notag",.clrmask = 1 << REISERFS_TAGGED},
14068 ++#endif
14069 ++#ifdef CONFIG_PROPAGATE
14070 ++ {"tag",.arg_required = 'T',.values = NULL},
14071 ++#endif
14072 + #ifdef CONFIG_REISERFS_FS_POSIX_ACL
14073 + {"acl",.setmask = 1 << REISERFS_POSIXACL},
14074 + {"noacl",.clrmask = 1 << REISERFS_POSIXACL},
14075 +@@ -1143,6 +1151,12 @@ static int reiserfs_remount(struct super
14076 + return -EINVAL;
14077 + }
14078 +
14079 ++ if ((mount_options & (1 << REISERFS_TAGGED)) &&
14080 ++ !(s->s_flags & MS_TAGGED)) {
14081 ++ reiserfs_warning(s, "reiserfs: tagging not permitted on remount.");
14082 ++ return -EINVAL;
14083 ++ }
14084 ++
14085 + handle_attrs(s);
14086 +
14087 + /* Add options that are safe here */
14088 +@@ -1591,6 +1605,10 @@ static int reiserfs_fill_super(struct su
14089 + goto error;
14090 + }
14091 +
14092 ++ /* map mount option tagxid */
14093 ++ if (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_TAGGED))
14094 ++ s->s_flags |= MS_TAGGED;
14095 ++
14096 + rs = SB_DISK_SUPER_BLOCK(s);
14097 + /* Let's do basic sanity check to verify that underlying device is not
14098 + smaller than the filesystem. If the check fails then abort and scream,
14099 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/xattr.c linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/xattr.c
14100 +--- linux-2.6.22.19/fs/reiserfs/xattr.c 2007-07-09 13:19:28 +0200
14101 ++++ linux-2.6.22.19-vs2.2.0.7/fs/reiserfs/xattr.c 2007-06-15 02:37:04 +0200
14102 +@@ -35,6 +35,7 @@
14103 + #include <linux/namei.h>
14104 + #include <linux/errno.h>
14105 + #include <linux/fs.h>
14106 ++#include <linux/mount.h>
14107 + #include <linux/file.h>
14108 + #include <linux/pagemap.h>
14109 + #include <linux/xattr.h>
14110 +@@ -775,7 +776,7 @@ int reiserfs_delete_xattrs(struct inode
14111 + if (dir->d_inode->i_nlink <= 2) {
14112 + root = get_xa_root(inode->i_sb, XATTR_REPLACE);
14113 + reiserfs_write_lock_xattrs(inode->i_sb);
14114 +- err = vfs_rmdir(root->d_inode, dir);
14115 ++ err = vfs_rmdir(root->d_inode, dir, NULL);
14116 + reiserfs_write_unlock_xattrs(inode->i_sb);
14117 + dput(root);
14118 + } else {
14119 +diff -NurpP --minimal linux-2.6.22.19/fs/stat.c linux-2.6.22.19-vs2.2.0.7/fs/stat.c
14120 +--- linux-2.6.22.19/fs/stat.c 2007-07-09 13:19:28 +0200
14121 ++++ linux-2.6.22.19-vs2.2.0.7/fs/stat.c 2007-06-15 02:37:04 +0200
14122 +@@ -26,6 +26,7 @@ void generic_fillattr(struct inode *inod
14123 + stat->nlink = inode->i_nlink;
14124 + stat->uid = inode->i_uid;
14125 + stat->gid = inode->i_gid;
14126 ++ stat->tag = inode->i_tag;
14127 + stat->rdev = inode->i_rdev;
14128 + stat->atime = inode->i_atime;
14129 + stat->mtime = inode->i_mtime;
14130 +diff -NurpP --minimal linux-2.6.22.19/fs/super.c linux-2.6.22.19-vs2.2.0.7/fs/super.c
14131 +--- linux-2.6.22.19/fs/super.c 2007-07-09 13:19:28 +0200
14132 ++++ linux-2.6.22.19-vs2.2.0.7/fs/super.c 2007-06-15 03:26:55 +0200
14133 +@@ -37,6 +37,9 @@
14134 + #include <linux/idr.h>
14135 + #include <linux/kobject.h>
14136 + #include <linux/mutex.h>
14137 ++#include <linux/devpts_fs.h>
14138 ++#include <linux/proc_fs.h>
14139 ++#include <linux/vs_context.h>
14140 + #include <asm/uaccess.h>
14141 +
14142 +
14143 +@@ -860,12 +863,18 @@ struct vfsmount *
14144 + vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
14145 + {
14146 + struct vfsmount *mnt;
14147 ++ struct super_block *sb;
14148 + char *secdata = NULL;
14149 + int error;
14150 +
14151 + if (!type)
14152 + return ERR_PTR(-ENODEV);
14153 +
14154 ++ error = -EPERM;
14155 ++ if ((type->fs_flags & FS_BINARY_MOUNTDATA) &&
14156 ++ !vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT))
14157 ++ goto out;
14158 ++
14159 + error = -ENOMEM;
14160 + mnt = alloc_vfsmnt(name);
14161 + if (!mnt)
14162 +@@ -885,7 +894,14 @@ vfs_kern_mount(struct file_system_type *
14163 + if (error < 0)
14164 + goto out_free_secdata;
14165 +
14166 +- error = security_sb_kern_mount(mnt->mnt_sb, secdata);
14167 ++ sb = mnt->mnt_sb;
14168 ++ error = -EPERM;
14169 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT) && !sb->s_bdev &&
14170 ++ (sb->s_magic != PROC_SUPER_MAGIC) &&
14171 ++ (sb->s_magic != DEVPTS_SUPER_MAGIC))
14172 ++ goto out_sb;
14173 ++
14174 ++ error = security_sb_kern_mount(sb, secdata);
14175 + if (error)
14176 + goto out_sb;
14177 +
14178 +diff -NurpP --minimal linux-2.6.22.19/fs/sysfs/mount.c linux-2.6.22.19-vs2.2.0.7/fs/sysfs/mount.c
14179 +--- linux-2.6.22.19/fs/sysfs/mount.c 2007-07-09 13:19:28 +0200
14180 ++++ linux-2.6.22.19-vs2.2.0.7/fs/sysfs/mount.c 2007-06-17 05:54:17 +0200
14181 +@@ -12,8 +12,6 @@
14182 +
14183 + #include "sysfs.h"
14184 +
14185 +-/* Random magic number */
14186 +-#define SYSFS_MAGIC 0x62656572
14187 +
14188 + struct vfsmount *sysfs_mount;
14189 + struct super_block * sysfs_sb = NULL;
14190 +@@ -48,7 +46,7 @@ static int sysfs_fill_super(struct super
14191 +
14192 + sb->s_blocksize = PAGE_CACHE_SIZE;
14193 + sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
14194 +- sb->s_magic = SYSFS_MAGIC;
14195 ++ sb->s_magic = SYSFS_SUPER_MAGIC;
14196 + sb->s_op = &sysfs_ops;
14197 + sb->s_time_gran = 1;
14198 + sysfs_sb = sb;
14199 +diff -NurpP --minimal linux-2.6.22.19/fs/utimes.c linux-2.6.22.19-vs2.2.0.7/fs/utimes.c
14200 +--- linux-2.6.22.19/fs/utimes.c 2007-07-09 13:19:29 +0200
14201 ++++ linux-2.6.22.19-vs2.2.0.7/fs/utimes.c 2007-07-09 13:11:54 +0200
14202 +@@ -6,6 +6,8 @@
14203 + #include <linux/sched.h>
14204 + #include <linux/stat.h>
14205 + #include <linux/utime.h>
14206 ++#include <linux/mount.h>
14207 ++#include <linux/vs_cowbl.h>
14208 + #include <asm/uaccess.h>
14209 + #include <asm/unistd.h>
14210 +
14211 +@@ -70,14 +72,16 @@ long do_utimes(int dfd, char __user *fil
14212 + if (error)
14213 + goto out;
14214 +
14215 ++ error = cow_check_and_break(&nd);
14216 ++ if (error)
14217 ++ goto dput_and_out;
14218 + dentry = nd.dentry;
14219 + }
14220 +
14221 + inode = dentry->d_inode;
14222 +-
14223 + error = -EROFS;
14224 + if (IS_RDONLY(inode))
14225 +- goto dput_and_out;
14226 ++ goto dput_and_out;
14227 +
14228 + /* Don't worry, the checks are done in inode_change_ok() */
14229 + newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
14230 +diff -NurpP --minimal linux-2.6.22.19/fs/xattr.c linux-2.6.22.19-vs2.2.0.7/fs/xattr.c
14231 +--- linux-2.6.22.19/fs/xattr.c 2007-07-09 13:19:29 +0200
14232 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xattr.c 2007-06-15 02:37:04 +0200
14233 +@@ -17,6 +17,7 @@
14234 + #include <linux/module.h>
14235 + #include <linux/fsnotify.h>
14236 + #include <linux/audit.h>
14237 ++#include <linux/mount.h>
14238 + #include <asm/uaccess.h>
14239 +
14240 +
14241 +@@ -194,7 +195,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
14242 + */
14243 + static long
14244 + setxattr(struct dentry *d, char __user *name, void __user *value,
14245 +- size_t size, int flags)
14246 ++ size_t size, int flags, struct vfsmount *mnt)
14247 + {
14248 + int error;
14249 + void *kvalue = NULL;
14250 +@@ -221,6 +222,9 @@ setxattr(struct dentry *d, char __user *
14251 + }
14252 + }
14253 +
14254 ++ if (MNT_IS_RDONLY(mnt))
14255 ++ return -EROFS;
14256 ++
14257 + error = vfs_setxattr(d, kname, kvalue, size, flags);
14258 + kfree(kvalue);
14259 + return error;
14260 +@@ -236,7 +240,7 @@ sys_setxattr(char __user *path, char __u
14261 + error = user_path_walk(path, &nd);
14262 + if (error)
14263 + return error;
14264 +- error = setxattr(nd.dentry, name, value, size, flags);
14265 ++ error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
14266 + path_release(&nd);
14267 + return error;
14268 + }
14269 +@@ -251,7 +255,7 @@ sys_lsetxattr(char __user *path, char __
14270 + error = user_path_walk_link(path, &nd);
14271 + if (error)
14272 + return error;
14273 +- error = setxattr(nd.dentry, name, value, size, flags);
14274 ++ error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
14275 + path_release(&nd);
14276 + return error;
14277 + }
14278 +@@ -269,7 +273,7 @@ sys_fsetxattr(int fd, char __user *name,
14279 + return error;
14280 + dentry = f->f_path.dentry;
14281 + audit_inode(NULL, dentry->d_inode);
14282 +- error = setxattr(dentry, name, value, size, flags);
14283 ++ error = setxattr(dentry, name, value, size, flags, f->f_vfsmnt);
14284 + fput(f);
14285 + return error;
14286 + }
14287 +@@ -433,7 +437,7 @@ sys_flistxattr(int fd, char __user *list
14288 + * Extended attribute REMOVE operations
14289 + */
14290 + static long
14291 +-removexattr(struct dentry *d, char __user *name)
14292 ++removexattr(struct dentry *d, char __user *name, struct vfsmount *mnt)
14293 + {
14294 + int error;
14295 + char kname[XATTR_NAME_MAX + 1];
14296 +@@ -444,6 +448,9 @@ removexattr(struct dentry *d, char __use
14297 + if (error < 0)
14298 + return error;
14299 +
14300 ++ if (MNT_IS_RDONLY(mnt))
14301 ++ return -EROFS;
14302 ++
14303 + return vfs_removexattr(d, kname);
14304 + }
14305 +
14306 +@@ -456,7 +463,7 @@ sys_removexattr(char __user *path, char
14307 + error = user_path_walk(path, &nd);
14308 + if (error)
14309 + return error;
14310 +- error = removexattr(nd.dentry, name);
14311 ++ error = removexattr(nd.dentry, name, nd.mnt);
14312 + path_release(&nd);
14313 + return error;
14314 + }
14315 +@@ -470,7 +477,7 @@ sys_lremovexattr(char __user *path, char
14316 + error = user_path_walk_link(path, &nd);
14317 + if (error)
14318 + return error;
14319 +- error = removexattr(nd.dentry, name);
14320 ++ error = removexattr(nd.dentry, name, nd.mnt);
14321 + path_release(&nd);
14322 + return error;
14323 + }
14324 +@@ -487,7 +494,7 @@ sys_fremovexattr(int fd, char __user *na
14325 + return error;
14326 + dentry = f->f_path.dentry;
14327 + audit_inode(NULL, dentry->d_inode);
14328 +- error = removexattr(dentry, name);
14329 ++ error = removexattr(dentry, name, f->f_vfsmnt);
14330 + fput(f);
14331 + return error;
14332 + }
14333 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/linux-2.6/xfs_ioctl.c linux-2.6.22.19-vs2.2.0.7/fs/xfs/linux-2.6/xfs_ioctl.c
14334 +--- linux-2.6.22.19/fs/xfs/linux-2.6/xfs_ioctl.c 2007-05-02 19:25:22 +0200
14335 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/linux-2.6/xfs_ioctl.c 2007-06-15 02:37:04 +0200
14336 +@@ -1128,6 +1128,10 @@ xfs_di2lxflags(
14337 +
14338 + if (di_flags & XFS_DIFLAG_IMMUTABLE)
14339 + flags |= FS_IMMUTABLE_FL;
14340 ++ if (di_flags & XFS_DIFLAG_IUNLINK)
14341 ++ flags |= FS_IUNLINK_FL;
14342 ++ if (di_flags & XFS_DIFLAG_BARRIER)
14343 ++ flags |= FS_BARRIER_FL;
14344 + if (di_flags & XFS_DIFLAG_APPEND)
14345 + flags |= FS_APPEND_FL;
14346 + if (di_flags & XFS_DIFLAG_SYNC)
14347 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.22.19-vs2.2.0.7/fs/xfs/linux-2.6/xfs_iops.c
14348 +--- linux-2.6.22.19/fs/xfs/linux-2.6/xfs_iops.c 2007-05-02 19:25:22 +0200
14349 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/linux-2.6/xfs_iops.c 2007-06-15 02:37:04 +0200
14350 +@@ -51,6 +51,7 @@
14351 + #include <linux/xattr.h>
14352 + #include <linux/namei.h>
14353 + #include <linux/security.h>
14354 ++#include <linux/vs_tag.h>
14355 +
14356 + /*
14357 + * Get a XFS inode from a given vnode.
14358 +@@ -400,6 +401,7 @@ xfs_vn_lookup(
14359 + d_add(dentry, NULL);
14360 + return NULL;
14361 + }
14362 ++ dx_propagate_tag(nd, vn_to_inode(cvp));
14363 +
14364 + return d_splice_alias(vn_to_inode(cvp), dentry);
14365 + }
14366 +@@ -657,6 +659,10 @@ xfs_vn_setattr(
14367 + int flags = 0;
14368 + int error;
14369 +
14370 ++ error = inode_change_ok(inode, attr);
14371 ++ if (error)
14372 ++ return error;
14373 ++
14374 + if (ia_valid & ATTR_UID) {
14375 + vattr.va_mask |= XFS_AT_UID;
14376 + vattr.va_uid = attr->ia_uid;
14377 +@@ -665,6 +671,10 @@ xfs_vn_setattr(
14378 + vattr.va_mask |= XFS_AT_GID;
14379 + vattr.va_gid = attr->ia_gid;
14380 + }
14381 ++ if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode)) {
14382 ++ vattr.va_mask |= XFS_AT_TAG;
14383 ++ vattr.va_tag = attr->ia_tag;
14384 ++ }
14385 + if (ia_valid & ATTR_SIZE) {
14386 + vattr.va_mask |= XFS_AT_SIZE;
14387 + vattr.va_size = attr->ia_size;
14388 +@@ -710,6 +720,42 @@ xfs_vn_truncate(
14389 + }
14390 +
14391 + STATIC int
14392 ++xfs_vn_sync_flags(struct inode *inode)
14393 ++{
14394 ++ unsigned int oldflags, newflags;
14395 ++ int flags = 0;
14396 ++ int error;
14397 ++ bhv_vattr_t vattr;
14398 ++ bhv_vnode_t *vp = vn_from_inode(inode);
14399 ++
14400 ++ memset(&vattr, 0, sizeof vattr);
14401 ++
14402 ++ vattr.va_mask = XFS_AT_XFLAGS;
14403 ++ error = bhv_vop_getattr(vp, &vattr, 0, NULL);
14404 ++
14405 ++ if (error)
14406 ++ return error;
14407 ++ oldflags = vattr.va_xflags;
14408 ++ newflags = oldflags & ~(XFS_XFLAG_IMMUTABLE |
14409 ++ XFS_XFLAG_IUNLINK | XFS_XFLAG_BARRIER);
14410 ++
14411 ++ if (IS_IMMUTABLE(inode))
14412 ++ newflags |= XFS_XFLAG_IMMUTABLE;
14413 ++ if (IS_IUNLINK(inode))
14414 ++ newflags |= XFS_XFLAG_IUNLINK;
14415 ++ if (IS_BARRIER(inode))
14416 ++ newflags |= XFS_XFLAG_BARRIER;
14417 ++
14418 ++ if (oldflags ^ newflags) {
14419 ++ vattr.va_xflags = newflags;
14420 ++ vattr.va_mask |= XFS_AT_XFLAGS;
14421 ++ error = bhv_vop_setattr(vp, &vattr, flags, NULL);
14422 ++ }
14423 ++ vn_revalidate(vp);
14424 ++ return error;
14425 ++}
14426 ++
14427 ++STATIC int
14428 + xfs_vn_setxattr(
14429 + struct dentry *dentry,
14430 + const char *name,
14431 +@@ -822,6 +868,7 @@ const struct inode_operations xfs_inode_
14432 + .getxattr = xfs_vn_getxattr,
14433 + .listxattr = xfs_vn_listxattr,
14434 + .removexattr = xfs_vn_removexattr,
14435 ++ .sync_flags = xfs_vn_sync_flags,
14436 + };
14437 +
14438 + const struct inode_operations xfs_dir_inode_operations = {
14439 +@@ -841,6 +888,7 @@ const struct inode_operations xfs_dir_in
14440 + .getxattr = xfs_vn_getxattr,
14441 + .listxattr = xfs_vn_listxattr,
14442 + .removexattr = xfs_vn_removexattr,
14443 ++ .sync_flags = xfs_vn_sync_flags,
14444 + };
14445 +
14446 + const struct inode_operations xfs_symlink_inode_operations = {
14447 +@@ -854,4 +902,5 @@ const struct inode_operations xfs_symlin
14448 + .getxattr = xfs_vn_getxattr,
14449 + .listxattr = xfs_vn_listxattr,
14450 + .removexattr = xfs_vn_removexattr,
14451 ++ .sync_flags = xfs_vn_sync_flags,
14452 + };
14453 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/linux-2.6/xfs_linux.h linux-2.6.22.19-vs2.2.0.7/fs/xfs/linux-2.6/xfs_linux.h
14454 +--- linux-2.6.22.19/fs/xfs/linux-2.6/xfs_linux.h 2007-05-02 19:25:22 +0200
14455 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/linux-2.6/xfs_linux.h 2007-06-15 02:37:04 +0200
14456 +@@ -129,6 +129,7 @@
14457 + #define current_pid() (current->pid)
14458 + #define current_fsuid(cred) (current->fsuid)
14459 + #define current_fsgid(cred) (current->fsgid)
14460 ++#define current_fstag(cred,vp) (dx_current_fstag(vn_to_inode(vp)->i_sb))
14461 + #define current_test_flags(f) (current->flags & (f))
14462 + #define current_set_flags_nested(sp, f) \
14463 + (*(sp) = current->flags, current->flags |= (f))
14464 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/linux-2.6/xfs_super.c linux-2.6.22.19-vs2.2.0.7/fs/xfs/linux-2.6/xfs_super.c
14465 +--- linux-2.6.22.19/fs/xfs/linux-2.6/xfs_super.c 2007-07-09 13:19:29 +0200
14466 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/linux-2.6/xfs_super.c 2007-06-15 02:37:04 +0200
14467 +@@ -157,6 +157,7 @@ xfs_revalidate_inode(
14468 + inode->i_nlink = ip->i_d.di_nlink;
14469 + inode->i_uid = ip->i_d.di_uid;
14470 + inode->i_gid = ip->i_d.di_gid;
14471 ++ inode->i_tag = ip->i_d.di_tag;
14472 +
14473 + switch (inode->i_mode & S_IFMT) {
14474 + case S_IFBLK:
14475 +@@ -184,6 +185,14 @@ xfs_revalidate_inode(
14476 + inode->i_flags |= S_IMMUTABLE;
14477 + else
14478 + inode->i_flags &= ~S_IMMUTABLE;
14479 ++ if (ip->i_d.di_flags & XFS_DIFLAG_IUNLINK)
14480 ++ inode->i_flags |= S_IUNLINK;
14481 ++ else
14482 ++ inode->i_flags &= ~S_IUNLINK;
14483 ++ if (ip->i_d.di_flags & XFS_DIFLAG_BARRIER)
14484 ++ inode->i_flags |= S_BARRIER;
14485 ++ else
14486 ++ inode->i_flags &= ~S_BARRIER;
14487 + if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
14488 + inode->i_flags |= S_APPEND;
14489 + else
14490 +@@ -712,6 +721,12 @@ xfs_fs_remount(
14491 + int error;
14492 +
14493 + error = bhv_vfs_parseargs(vfsp, options, args, 1);
14494 ++ if ((args->flags2 & XFSMNT2_TAGGED) &&
14495 ++ !(sb->s_flags & MS_TAGGED)) {
14496 ++ printk("XFS: %s: tagging not permitted on remount.\n",
14497 ++ sb->s_id);
14498 ++ error = EINVAL;
14499 ++ }
14500 + if (!error)
14501 + error = bhv_vfs_mntupdate(vfsp, flags, args);
14502 + kmem_free(args, sizeof(*args));
14503 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/linux-2.6/xfs_vnode.c linux-2.6.22.19-vs2.2.0.7/fs/xfs/linux-2.6/xfs_vnode.c
14504 +--- linux-2.6.22.19/fs/xfs/linux-2.6/xfs_vnode.c 2007-05-02 19:25:22 +0200
14505 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/linux-2.6/xfs_vnode.c 2007-06-15 02:37:04 +0200
14506 +@@ -119,6 +119,7 @@ vn_revalidate_core(
14507 + inode->i_nlink = vap->va_nlink;
14508 + inode->i_uid = vap->va_uid;
14509 + inode->i_gid = vap->va_gid;
14510 ++ inode->i_tag = vap->va_tag;
14511 + inode->i_blocks = vap->va_nblocks;
14512 + inode->i_mtime = vap->va_mtime;
14513 + inode->i_ctime = vap->va_ctime;
14514 +@@ -126,6 +127,14 @@ vn_revalidate_core(
14515 + inode->i_flags |= S_IMMUTABLE;
14516 + else
14517 + inode->i_flags &= ~S_IMMUTABLE;
14518 ++ if (vap->va_xflags & XFS_XFLAG_IUNLINK)
14519 ++ inode->i_flags |= S_IUNLINK;
14520 ++ else
14521 ++ inode->i_flags &= ~S_IUNLINK;
14522 ++ if (vap->va_xflags & XFS_XFLAG_BARRIER)
14523 ++ inode->i_flags |= S_BARRIER;
14524 ++ else
14525 ++ inode->i_flags &= ~S_BARRIER;
14526 + if (vap->va_xflags & XFS_XFLAG_APPEND)
14527 + inode->i_flags |= S_APPEND;
14528 + else
14529 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/linux-2.6/xfs_vnode.h linux-2.6.22.19-vs2.2.0.7/fs/xfs/linux-2.6/xfs_vnode.h
14530 +--- linux-2.6.22.19/fs/xfs/linux-2.6/xfs_vnode.h 2007-07-09 13:19:29 +0200
14531 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/linux-2.6/xfs_vnode.h 2007-06-15 02:37:04 +0200
14532 +@@ -350,6 +350,7 @@ typedef struct bhv_vattr {
14533 + xfs_nlink_t va_nlink; /* number of references to file */
14534 + uid_t va_uid; /* owner user id */
14535 + gid_t va_gid; /* owner group id */
14536 ++ tag_t va_tag; /* owner group id */
14537 + xfs_ino_t va_nodeid; /* file id */
14538 + xfs_off_t va_size; /* file size in bytes */
14539 + u_long va_blocksize; /* blocksize preferred for i/o */
14540 +@@ -398,13 +399,15 @@ typedef struct bhv_vattr {
14541 + #define XFS_AT_PROJID 0x04000000
14542 + #define XFS_AT_SIZE_NOPERM 0x08000000
14543 + #define XFS_AT_GENCOUNT 0x10000000
14544 ++#define XFS_AT_TAG 0x20000000
14545 +
14546 + #define XFS_AT_ALL (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
14547 + XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
14548 + XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME|XFS_AT_RDEV|\
14549 + XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|XFS_AT_MAC|\
14550 + XFS_AT_ACL|XFS_AT_CAP|XFS_AT_INF|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|\
14551 +- XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT)
14552 ++ XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT\
14553 ++ XFS_AT_TAG)
14554 +
14555 + #define XFS_AT_STAT (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
14556 + XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
14557 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/quota/xfs_qm_syscalls.c linux-2.6.22.19-vs2.2.0.7/fs/xfs/quota/xfs_qm_syscalls.c
14558 +--- linux-2.6.22.19/fs/xfs/quota/xfs_qm_syscalls.c 2007-07-09 13:19:29 +0200
14559 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/quota/xfs_qm_syscalls.c 2007-06-15 02:37:04 +0200
14560 +@@ -17,6 +17,7 @@
14561 + */
14562 +
14563 + #include <linux/capability.h>
14564 ++#include <linux/vs_context.h>
14565 +
14566 + #include "xfs.h"
14567 + #include "xfs_fs.h"
14568 +@@ -211,7 +212,7 @@ xfs_qm_scall_quotaoff(
14569 + xfs_qoff_logitem_t *qoffstart;
14570 + int nculprits;
14571 +
14572 +- if (!force && !capable(CAP_SYS_ADMIN))
14573 ++ if (!force && !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
14574 + return XFS_ERROR(EPERM);
14575 + /*
14576 + * No file system can have quotas enabled on disk but not in core.
14577 +@@ -380,7 +381,7 @@ xfs_qm_scall_trunc_qfiles(
14578 + int error;
14579 + xfs_inode_t *qip;
14580 +
14581 +- if (!capable(CAP_SYS_ADMIN))
14582 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
14583 + return XFS_ERROR(EPERM);
14584 + error = 0;
14585 + if (!XFS_SB_VERSION_HASQUOTA(&mp->m_sb) || flags == 0) {
14586 +@@ -425,7 +426,7 @@ xfs_qm_scall_quotaon(
14587 + uint accflags;
14588 + __int64_t sbflags;
14589 +
14590 +- if (!capable(CAP_SYS_ADMIN))
14591 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
14592 + return XFS_ERROR(EPERM);
14593 +
14594 + flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
14595 +@@ -594,7 +595,7 @@ xfs_qm_scall_setqlim(
14596 + int error;
14597 + xfs_qcnt_t hard, soft;
14598 +
14599 +- if (!capable(CAP_SYS_ADMIN))
14600 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
14601 + return XFS_ERROR(EPERM);
14602 +
14603 + if ((newlim->d_fieldmask &
14604 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_clnt.h linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_clnt.h
14605 +--- linux-2.6.22.19/fs/xfs/xfs_clnt.h 2006-06-18 04:54:50 +0200
14606 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_clnt.h 2007-06-15 02:37:04 +0200
14607 +@@ -99,5 +99,7 @@ struct xfs_mount_args {
14608 + */
14609 + #define XFSMNT2_COMPAT_IOSIZE 0x00000001 /* don't report large preferred
14610 + * I/O size in stat(2) */
14611 ++#define XFSMNT2_TAGGED 0x80000000 /* context tagging */
14612 ++
14613 +
14614 + #endif /* __XFS_CLNT_H__ */
14615 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_dinode.h linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_dinode.h
14616 +--- linux-2.6.22.19/fs/xfs/xfs_dinode.h 2006-09-20 16:58:40 +0200
14617 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_dinode.h 2007-06-15 02:37:04 +0200
14618 +@@ -53,7 +53,8 @@ typedef struct xfs_dinode_core
14619 + __uint32_t di_gid; /* owner's group id */
14620 + __uint32_t di_nlink; /* number of links to file */
14621 + __uint16_t di_projid; /* owner's project id */
14622 +- __uint8_t di_pad[8]; /* unused, zeroed space */
14623 ++ __uint16_t di_tag; /* context tagging */
14624 ++ __uint8_t di_pad[6]; /* unused, zeroed space */
14625 + __uint16_t di_flushiter; /* incremented on flush */
14626 + xfs_timestamp_t di_atime; /* time last accessed */
14627 + xfs_timestamp_t di_mtime; /* time last modified */
14628 +@@ -257,6 +258,9 @@ typedef enum xfs_dinode_fmt
14629 + #define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */
14630 + #define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */
14631 + #define XFS_DIFLAG_NODEFRAG_BIT 13 /* do not reorganize/defragment */
14632 ++#define XFS_DIFLAG_BARRIER_BIT 14 /* chroot() barrier */
14633 ++#define XFS_DIFLAG_IUNLINK_BIT 15 /* immutable unlink */
14634 ++
14635 + #define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT)
14636 + #define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT)
14637 + #define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT)
14638 +@@ -271,12 +275,15 @@ typedef enum xfs_dinode_fmt
14639 + #define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT)
14640 + #define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
14641 + #define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT)
14642 ++#define XFS_DIFLAG_BARRIER (1 << XFS_DIFLAG_BARRIER_BIT)
14643 ++#define XFS_DIFLAG_IUNLINK (1 << XFS_DIFLAG_IUNLINK_BIT)
14644 +
14645 + #define XFS_DIFLAG_ANY \
14646 + (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
14647 + XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
14648 + XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
14649 + XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
14650 +- XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG)
14651 ++ XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_BARRIER | \
14652 ++ XFS_DIFLAG_IUNLINK)
14653 +
14654 + #endif /* __XFS_DINODE_H__ */
14655 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_fs.h linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_fs.h
14656 +--- linux-2.6.22.19/fs/xfs/xfs_fs.h 2006-11-30 21:19:29 +0100
14657 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_fs.h 2007-06-15 02:37:04 +0200
14658 +@@ -66,6 +66,8 @@ struct fsxattr {
14659 + #define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
14660 + #define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
14661 + #define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
14662 ++#define XFS_XFLAG_BARRIER 0x00004000 /* chroot() barrier */
14663 ++#define XFS_XFLAG_IUNLINK 0x00008000 /* immutable unlink */
14664 + #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
14665 +
14666 + /*
14667 +@@ -294,7 +296,8 @@ typedef struct xfs_bstat {
14668 + __s32 bs_extents; /* number of extents */
14669 + __u32 bs_gen; /* generation count */
14670 + __u16 bs_projid; /* project id */
14671 +- unsigned char bs_pad[14]; /* pad space, unused */
14672 ++ __u16 bs_tag; /* context tagging */
14673 ++ unsigned char bs_pad[12]; /* pad space, unused */
14674 + __u32 bs_dmevmask; /* DMIG event mask */
14675 + __u16 bs_dmstate; /* DMIG state info */
14676 + __u16 bs_aextents; /* attribute number of extents */
14677 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_inode.c linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_inode.c
14678 +--- linux-2.6.22.19/fs/xfs/xfs_inode.c 2007-07-09 13:19:34 +0200
14679 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_inode.c 2007-06-15 02:37:04 +0200
14680 +@@ -49,6 +49,7 @@
14681 + #include "xfs_quota.h"
14682 + #include "xfs_acl.h"
14683 +
14684 ++#include <linux/vs_tag.h>
14685 +
14686 + kmem_zone_t *xfs_ifork_zone;
14687 + kmem_zone_t *xfs_inode_zone;
14688 +@@ -736,20 +737,35 @@ xfs_xlate_dinode_core(
14689 + xfs_dinode_core_t *buf_core = (xfs_dinode_core_t *)buf;
14690 + xfs_dinode_core_t *mem_core = (xfs_dinode_core_t *)dip;
14691 + xfs_arch_t arch = ARCH_CONVERT;
14692 ++ uint32_t uid = 0, gid = 0;
14693 ++ uint16_t tag = 0;
14694 +
14695 + ASSERT(dir);
14696 +
14697 ++ if (dir < 0) {
14698 ++ tag = mem_core->di_tag;
14699 ++ /* FIXME: supposed to use superblock flag */
14700 ++ uid = TAGINO_UID(1, mem_core->di_uid, tag);
14701 ++ gid = TAGINO_GID(1, mem_core->di_gid, tag);
14702 ++ tag = TAGINO_TAG(1, tag);
14703 ++ }
14704 ++
14705 + INT_XLATE(buf_core->di_magic, mem_core->di_magic, dir, arch);
14706 + INT_XLATE(buf_core->di_mode, mem_core->di_mode, dir, arch);
14707 + INT_XLATE(buf_core->di_version, mem_core->di_version, dir, arch);
14708 + INT_XLATE(buf_core->di_format, mem_core->di_format, dir, arch);
14709 + INT_XLATE(buf_core->di_onlink, mem_core->di_onlink, dir, arch);
14710 +- INT_XLATE(buf_core->di_uid, mem_core->di_uid, dir, arch);
14711 +- INT_XLATE(buf_core->di_gid, mem_core->di_gid, dir, arch);
14712 ++ INT_XLATE(buf_core->di_uid, uid, dir, arch);
14713 ++ INT_XLATE(buf_core->di_gid, gid, dir, arch);
14714 ++ INT_XLATE(buf_core->di_tag, tag, dir, arch);
14715 + INT_XLATE(buf_core->di_nlink, mem_core->di_nlink, dir, arch);
14716 + INT_XLATE(buf_core->di_projid, mem_core->di_projid, dir, arch);
14717 +
14718 + if (dir > 0) {
14719 ++ /* FIXME: supposed to use superblock flag */
14720 ++ mem_core->di_uid = INOTAG_UID(1, uid, gid);
14721 ++ mem_core->di_gid = INOTAG_GID(1, uid, gid);
14722 ++ mem_core->di_tag = INOTAG_TAG(1, uid, gid, tag);
14723 + memcpy(mem_core->di_pad, buf_core->di_pad,
14724 + sizeof(buf_core->di_pad));
14725 + } else {
14726 +@@ -797,6 +813,10 @@ _xfs_dic2xflags(
14727 + flags |= XFS_XFLAG_PREALLOC;
14728 + if (di_flags & XFS_DIFLAG_IMMUTABLE)
14729 + flags |= XFS_XFLAG_IMMUTABLE;
14730 ++ if (di_flags & XFS_DIFLAG_IUNLINK)
14731 ++ flags |= XFS_XFLAG_IUNLINK;
14732 ++ if (di_flags & XFS_DIFLAG_BARRIER)
14733 ++ flags |= XFS_XFLAG_BARRIER;
14734 + if (di_flags & XFS_DIFLAG_APPEND)
14735 + flags |= XFS_XFLAG_APPEND;
14736 + if (di_flags & XFS_DIFLAG_SYNC)
14737 +@@ -1129,6 +1149,7 @@ xfs_ialloc(
14738 + ASSERT(ip->i_d.di_nlink == nlink);
14739 + ip->i_d.di_uid = current_fsuid(cr);
14740 + ip->i_d.di_gid = current_fsgid(cr);
14741 ++ ip->i_d.di_tag = current_fstag(cr, vp);
14742 + ip->i_d.di_projid = prid;
14743 + memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
14744 +
14745 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_itable.c linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_itable.c
14746 +--- linux-2.6.22.19/fs/xfs/xfs_itable.c 2007-07-09 13:19:34 +0200
14747 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_itable.c 2007-06-15 02:37:04 +0200
14748 +@@ -89,6 +89,7 @@ xfs_bulkstat_one_iget(
14749 + buf->bs_mode = dic->di_mode;
14750 + buf->bs_uid = dic->di_uid;
14751 + buf->bs_gid = dic->di_gid;
14752 ++ buf->bs_tag = dic->di_tag;
14753 + buf->bs_size = dic->di_size;
14754 + vn_atime_to_bstime(vp, &buf->bs_atime);
14755 + buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
14756 +@@ -163,6 +164,7 @@ xfs_bulkstat_one_dinode(
14757 + buf->bs_mode = INT_GET(dic->di_mode, ARCH_CONVERT);
14758 + buf->bs_uid = INT_GET(dic->di_uid, ARCH_CONVERT);
14759 + buf->bs_gid = INT_GET(dic->di_gid, ARCH_CONVERT);
14760 ++ buf->bs_tag = INT_GET(dic->di_tag, ARCH_CONVERT);
14761 + buf->bs_size = INT_GET(dic->di_size, ARCH_CONVERT);
14762 + buf->bs_atime.tv_sec = INT_GET(dic->di_atime.t_sec, ARCH_CONVERT);
14763 + buf->bs_atime.tv_nsec = INT_GET(dic->di_atime.t_nsec, ARCH_CONVERT);
14764 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_mount.h linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_mount.h
14765 +--- linux-2.6.22.19/fs/xfs/xfs_mount.h 2007-05-02 19:25:23 +0200
14766 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_mount.h 2007-06-15 02:37:04 +0200
14767 +@@ -464,6 +464,7 @@ typedef struct xfs_mount {
14768 + #define XFS_MOUNT_NO_PERCPU_SB (1ULL << 23) /* don't use per-cpu superblock
14769 + counters */
14770 +
14771 ++#define XFS_MOUNT_TAGGED (1ULL << 31) /* context tagging */
14772 +
14773 + /*
14774 + * Default minimum read and write sizes.
14775 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_vfsops.c linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_vfsops.c
14776 +--- linux-2.6.22.19/fs/xfs/xfs_vfsops.c 2007-07-09 13:19:34 +0200
14777 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_vfsops.c 2007-06-15 02:37:04 +0200
14778 +@@ -300,6 +300,8 @@ xfs_start_flags(
14779 +
14780 + if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE)
14781 + mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
14782 ++ if (ap->flags2 & XFSMNT2_TAGGED)
14783 ++ mp->m_flags |= XFS_MOUNT_TAGGED;
14784 +
14785 + /*
14786 + * no recovery flag requires a read-only mount
14787 +@@ -394,6 +396,8 @@ xfs_finish_flags(
14788 + return XFS_ERROR(EINVAL);
14789 + }
14790 +
14791 ++ if (ap->flags2 & XFSMNT2_TAGGED)
14792 ++ vfs->vfs_super->s_flags |= MS_TAGGED;
14793 + return 0;
14794 + }
14795 +
14796 +@@ -1645,6 +1649,9 @@ xfs_vget(
14797 + * in stat(). */
14798 + #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */
14799 + #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
14800 ++#define MNTOPT_TAGXID "tagxid" /* context tagging for inodes */
14801 ++#define MNTOPT_TAGGED "tag" /* context tagging for inodes */
14802 ++#define MNTOPT_NOTAGTAG "notag" /* do not use context tagging */
14803 +
14804 + STATIC unsigned long
14805 + suffix_strtoul(char *s, char **endp, unsigned int base)
14806 +@@ -1831,6 +1838,19 @@ xfs_parseargs(
14807 + args->flags |= XFSMNT_ATTR2;
14808 + } else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
14809 + args->flags &= ~XFSMNT_ATTR2;
14810 ++#ifndef CONFIG_TAGGING_NONE
14811 ++ } else if (!strcmp(this_char, MNTOPT_TAGGED)) {
14812 ++ args->flags2 |= XFSMNT2_TAGGED;
14813 ++ } else if (!strcmp(this_char, MNTOPT_NOTAGTAG)) {
14814 ++ args->flags2 &= ~XFSMNT2_TAGGED;
14815 ++ } else if (!strcmp(this_char, MNTOPT_TAGXID)) {
14816 ++ args->flags2 |= XFSMNT2_TAGGED;
14817 ++#endif
14818 ++#ifdef CONFIG_PROPAGATE
14819 ++ } else if (!strcmp(this_char, MNTOPT_TAGGED)) {
14820 ++ /* use value */
14821 ++ args->flags2 |= XFSMNT2_TAGGED;
14822 ++#endif
14823 + } else if (!strcmp(this_char, "osyncisdsync")) {
14824 + /* no-op, this is now the default */
14825 + cmn_err(CE_WARN,
14826 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_vnodeops.c linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_vnodeops.c
14827 +--- linux-2.6.22.19/fs/xfs/xfs_vnodeops.c 2007-07-09 13:19:34 +0200
14828 ++++ linux-2.6.22.19-vs2.2.0.7/fs/xfs/xfs_vnodeops.c 2007-06-15 02:37:04 +0200
14829 +@@ -159,6 +159,7 @@ xfs_getattr(
14830 + vap->va_mode = ip->i_d.di_mode;
14831 + vap->va_uid = ip->i_d.di_uid;
14832 + vap->va_gid = ip->i_d.di_gid;
14833 ++ vap->va_tag = ip->i_d.di_tag;
14834 + vap->va_projid = ip->i_d.di_projid;
14835 +
14836 + /*
14837 +@@ -259,6 +260,7 @@ xfs_setattr(
14838 + uint commit_flags=0;
14839 + uid_t uid=0, iuid=0;
14840 + gid_t gid=0, igid=0;
14841 ++ tag_t tag=0, itag=0;
14842 + int timeflags = 0;
14843 + bhv_vnode_t *vp;
14844 + xfs_prid_t projid=0, iprojid=0;
14845 +@@ -315,6 +317,7 @@ xfs_setattr(
14846 + (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) {
14847 + uint qflags = 0;
14848 +
14849 ++ /* TODO: handle tagging? */
14850 + if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) {
14851 + uid = vap->va_uid;
14852 + qflags |= XFS_QMOPT_UQUOTA;
14853 +@@ -394,6 +397,8 @@ xfs_setattr(
14854 + if (mask &
14855 + (XFS_AT_MODE|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_UID|
14856 + XFS_AT_GID|XFS_AT_PROJID)) {
14857 ++ /* TODO: handle tagging? */
14858 ++
14859 + /*
14860 + * CAP_FOWNER overrides the following restrictions:
14861 + *
14862 +@@ -442,7 +447,7 @@ xfs_setattr(
14863 + * and can change the group id only to a group of which he
14864 + * or she is a member.
14865 + */
14866 +- if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
14867 ++ if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_TAG|XFS_AT_PROJID)) {
14868 + /*
14869 + * These IDs could have changed since we last looked at them.
14870 + * But, we're assured that if the ownership did change
14871 +@@ -450,10 +455,12 @@ xfs_setattr(
14872 + * would have changed also.
14873 + */
14874 + iuid = ip->i_d.di_uid;
14875 +- iprojid = ip->i_d.di_projid;
14876 + igid = ip->i_d.di_gid;
14877 +- gid = (mask & XFS_AT_GID) ? vap->va_gid : igid;
14878 ++ itag = ip->i_d.di_tag;
14879 ++ iprojid = ip->i_d.di_projid;
14880 + uid = (mask & XFS_AT_UID) ? vap->va_uid : iuid;
14881 ++ gid = (mask & XFS_AT_GID) ? vap->va_gid : igid;
14882 ++ tag = (mask & XFS_AT_TAG) ? vap->va_tag : itag;
14883 + projid = (mask & XFS_AT_PROJID) ? (xfs_prid_t)vap->va_projid :
14884 + iprojid;
14885 +
14886 +@@ -481,6 +488,7 @@ xfs_setattr(
14887 + if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
14888 + (XFS_IS_PQUOTA_ON(mp) && iprojid != projid) ||
14889 + (XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
14890 ++ /* TODO: handle tagging? */
14891 + ASSERT(tp);
14892 + code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
14893 + capable(CAP_FOWNER) ?
14894 +@@ -706,7 +714,7 @@ xfs_setattr(
14895 + * and can change the group id only to a group of which he
14896 + * or she is a member.
14897 + */
14898 +- if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
14899 ++ if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_TAG|XFS_AT_PROJID)) {
14900 + /*
14901 + * CAP_FSETID overrides the following restrictions:
14902 + *
14903 +@@ -722,6 +730,9 @@ xfs_setattr(
14904 + * Change the ownerships and register quota modifications
14905 + * in the transaction.
14906 + */
14907 ++ if (itag != tag) {
14908 ++ ip->i_d.di_tag = tag;
14909 ++ }
14910 + if (iuid != uid) {
14911 + if (XFS_IS_UQUOTA_ON(mp)) {
14912 + ASSERT(mask & XFS_AT_UID);
14913 +@@ -802,6 +813,10 @@ xfs_setattr(
14914 + di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
14915 + if (vap->va_xflags & XFS_XFLAG_IMMUTABLE)
14916 + di_flags |= XFS_DIFLAG_IMMUTABLE;
14917 ++ if (vap->va_xflags & XFS_XFLAG_IUNLINK)
14918 ++ di_flags |= XFS_DIFLAG_IUNLINK;
14919 ++ if (vap->va_xflags & XFS_XFLAG_BARRIER)
14920 ++ di_flags |= XFS_DIFLAG_BARRIER;
14921 + if (vap->va_xflags & XFS_XFLAG_APPEND)
14922 + di_flags |= XFS_DIFLAG_APPEND;
14923 + if (vap->va_xflags & XFS_XFLAG_SYNC)
14924 +diff -NurpP --minimal linux-2.6.22.19/include/asm-arm/tlb.h linux-2.6.22.19-vs2.2.0.7/include/asm-arm/tlb.h
14925 +--- linux-2.6.22.19/include/asm-arm/tlb.h 2006-06-18 04:54:58 +0200
14926 ++++ linux-2.6.22.19-vs2.2.0.7/include/asm-arm/tlb.h 2007-06-15 02:37:04 +0200
14927 +@@ -28,6 +28,7 @@
14928 + #else /* !CONFIG_MMU */
14929 +
14930 + #include <asm/pgalloc.h>
14931 ++#include <linux/vs_memory.h>
14932 +
14933 + /*
14934 + * TLB handling. This allows us to remove pages from the page
14935 +diff -NurpP --minimal linux-2.6.22.19/include/asm-arm26/tlb.h linux-2.6.22.19-vs2.2.0.7/include/asm-arm26/tlb.h
14936 +--- linux-2.6.22.19/include/asm-arm26/tlb.h 2006-01-03 17:30:02 +0100
14937 ++++ linux-2.6.22.19-vs2.2.0.7/include/asm-arm26/tlb.h 2007-06-15 02:37:04 +0200
14938 +@@ -3,6 +3,7 @@
14939 +
14940 + #include <asm/pgalloc.h>
14941 + #include <asm/tlbflush.h>
14942 ++#include <linux/vs_memory.h>
14943 +
14944 + /*
14945 + * TLB handling. This allows us to remove pages from the page
14946 +diff -NurpP --minimal linux-2.6.22.19/include/asm-arm26/unistd.h linux-2.6.22.19-vs2.2.0.7/include/asm-arm26/unistd.h
14947 +--- linux-2.6.22.19/include/asm-arm26/unistd.h 2007-02-06 03:01:35 +0100
14948 ++++ linux-2.6.22.19-vs2.2.0.7/include/asm-arm26/unistd.h 2007-06-15 02:37:04 +0200
14949 +@@ -302,6 +302,8 @@
14950 + #define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279)
14951 + #define __NR_waitid (__NR_SYSCALL_BASE+280)
14952 +
14953 ++#define __NR_vserver (__NR_SYSCALL_BASE+313)
14954 ++
14955 + /*
14956 + * The following SWIs are ARM private. FIXME - make appropriate for arm26
14957 + */
14958 +diff -NurpP --minimal linux-2.6.22.19/include/asm-generic/tlb.h linux-2.6.22.19-vs2.2.0.7/include/asm-generic/tlb.h
14959 +--- linux-2.6.22.19/include/asm-generic/tlb.h 2006-11-30 21:19:31 +0100
14960 ++++ linux-2.6.22.19-vs2.2.0.7/include/asm-generic/tlb.h 2007-06-15 02:37:04 +0200
14961 +@@ -14,6 +14,7 @@
14962 + #define _ASM_GENERIC__TLB_H
14963 +
14964 + #include <linux/swap.h>
14965 ++#include <linux/vs_memory.h>
14966 + #include <asm/pgalloc.h>
14967 + #include <asm/tlbflush.h>
14968 +
14969 +diff -NurpP --minimal linux-2.6.22.19/include/asm-ia64/tlb.h linux-2.6.22.19-vs2.2.0.7/include/asm-ia64/tlb.h
14970 +--- linux-2.6.22.19/include/asm-ia64/tlb.h 2006-09-20 16:58:40 +0200
14971 ++++ linux-2.6.22.19-vs2.2.0.7/include/asm-ia64/tlb.h 2007-06-15 02:37:04 +0200
14972 +@@ -40,6 +40,7 @@
14973 + #include <linux/mm.h>
14974 + #include <linux/pagemap.h>
14975 + #include <linux/swap.h>
14976 ++#include <linux/vs_memory.h>
14977 +
14978 + #include <asm/pgalloc.h>
14979 + #include <asm/processor.h>
14980 +diff -NurpP --minimal linux-2.6.22.19/include/asm-powerpc/systbl.h linux-2.6.22.19-vs2.2.0.7/include/asm-powerpc/systbl.h
14981 +--- linux-2.6.22.19/include/asm-powerpc/systbl.h 2007-07-09 13:19:44 +0200
14982 ++++ linux-2.6.22.19-vs2.2.0.7/include/asm-powerpc/systbl.h 2007-07-07 03:52:53 +0200
14983 +@@ -260,7 +260,7 @@ COMPAT_SYS_SPU(fstatfs64)
14984 + SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64)
14985 + PPC_SYS_SPU(rtas)
14986 + OLDSYS(debug_setcontext)
14987 +-SYSCALL(ni_syscall)
14988 ++SYSX(sys_vserver, sys32_vserver, sys_vserver)
14989 + COMPAT_SYS(migrate_pages)
14990 + COMPAT_SYS(mbind)
14991 + COMPAT_SYS(get_mempolicy)
14992 +diff -NurpP --minimal linux-2.6.22.19/include/asm-powerpc/unistd.h linux-2.6.22.19-vs2.2.0.7/include/asm-powerpc/unistd.h
14993 +--- linux-2.6.22.19/include/asm-powerpc/unistd.h 2007-07-09 13:19:45 +0200
14994 ++++ linux-2.6.22.19-vs2.2.0.7/include/asm-powerpc/unistd.h 2007-07-07 03:52:53 +0200
14995 +@@ -275,7 +275,7 @@
14996 + #endif
14997 + #define __NR_rtas 255
14998 + #define __NR_sys_debug_setcontext 256
14999 +-/* Number 257 is reserved for vserver */
15000 ++#define __NR_vserver 257
15001 + #define __NR_migrate_pages 258
15002 + #define __NR_mbind 259
15003 + #define __NR_get_mempolicy 260
15004 +diff -NurpP --minimal linux-2.6.22.19/include/asm-s390/unistd.h linux-2.6.22.19-vs2.2.0.7/include/asm-s390/unistd.h
15005 +--- linux-2.6.22.19/include/asm-s390/unistd.h 2007-07-09 13:19:45 +0200
15006 ++++ linux-2.6.22.19-vs2.2.0.7/include/asm-s390/unistd.h 2007-06-15 02:37:04 +0200
15007 +@@ -202,7 +202,7 @@
15008 + #define __NR_clock_gettime (__NR_timer_create+6)
15009 + #define __NR_clock_getres (__NR_timer_create+7)
15010 + #define __NR_clock_nanosleep (__NR_timer_create+8)
15011 +-/* Number 263 is reserved for vserver */
15012 ++#define __NR_vserver 263
15013 + #define __NR_statfs64 265
15014 + #define __NR_fstatfs64 266
15015 + #define __NR_remap_file_pages 267
15016 +diff -NurpP --minimal linux-2.6.22.19/include/asm-sparc/unistd.h linux-2.6.22.19-vs2.2.0.7/include/asm-sparc/unistd.h
15017 +--- linux-2.6.22.19/include/asm-sparc/unistd.h 2007-07-09 13:19:54 +0200
15018 ++++ linux-2.6.22.19-vs2.2.0.7/include/asm-sparc/unistd.h 2007-06-15 02:37:04 +0200
15019 +@@ -283,7 +283,7 @@
15020 + #define __NR_timer_getoverrun 264
15021 + #define __NR_timer_delete 265
15022 + #define __NR_timer_create 266
15023 +-/* #define __NR_vserver 267 Reserved for VSERVER */
15024 ++#define __NR_vserver 267
15025 + #define __NR_io_setup 268
15026 + #define __NR_io_destroy 269
15027 + #define __NR_io_submit 270
15028 +diff -NurpP --minimal linux-2.6.22.19/include/asm-sparc64/tlb.h linux-2.6.22.19-vs2.2.0.7/include/asm-sparc64/tlb.h
15029 +--- linux-2.6.22.19/include/asm-sparc64/tlb.h 2007-07-09 13:19:54 +0200
15030 ++++ linux-2.6.22.19-vs2.2.0.7/include/asm-sparc64/tlb.h 2007-07-07 03:54:19 +0200
15031 +@@ -3,6 +3,7 @@
15032 +
15033 + #include <linux/swap.h>
15034 + #include <linux/pagemap.h>
15035 ++#include <linux/vs_memory.h>
15036 + #include <asm/pgalloc.h>
15037 + #include <asm/tlbflush.h>
15038 + #include <asm/mmu_context.h>
15039 +diff -NurpP --minimal linux-2.6.22.19/include/asm-sparc64/unistd.h linux-2.6.22.19-vs2.2.0.7/include/asm-sparc64/unistd.h
15040 +--- linux-2.6.22.19/include/asm-sparc64/unistd.h 2007-07-09 13:19:54 +0200
15041 ++++ linux-2.6.22.19-vs2.2.0.7/include/asm-sparc64/unistd.h 2007-06-15 02:37:04 +0200
15042 +@@ -285,7 +285,7 @@
15043 + #define __NR_timer_getoverrun 264
15044 + #define __NR_timer_delete 265
15045 + #define __NR_timer_create 266
15046 +-/* #define __NR_vserver 267 Reserved for VSERVER */
15047 ++#define __NR_vserver 267
15048 + #define __NR_io_setup 268
15049 + #define __NR_io_destroy 269
15050 + #define __NR_io_submit 270
15051 +diff -NurpP --minimal linux-2.6.22.19/include/asm-x86_64/unistd.h linux-2.6.22.19-vs2.2.0.7/include/asm-x86_64/unistd.h
15052 +--- linux-2.6.22.19/include/asm-x86_64/unistd.h 2007-07-09 13:19:55 +0200
15053 ++++ linux-2.6.22.19-vs2.2.0.7/include/asm-x86_64/unistd.h 2007-07-07 03:52:53 +0200
15054 +@@ -532,7 +532,7 @@ __SYSCALL(__NR_tgkill, sys_tgkill)
15055 + #define __NR_utimes 235
15056 + __SYSCALL(__NR_utimes, sys_utimes)
15057 + #define __NR_vserver 236
15058 +-__SYSCALL(__NR_vserver, sys_ni_syscall)
15059 ++__SYSCALL(__NR_vserver, sys_vserver)
15060 + #define __NR_mbind 237
15061 + __SYSCALL(__NR_mbind, sys_mbind)
15062 + #define __NR_set_mempolicy 238
15063 +diff -NurpP --minimal linux-2.6.22.19/include/linux/Kbuild linux-2.6.22.19-vs2.2.0.7/include/linux/Kbuild
15064 +--- linux-2.6.22.19/include/linux/Kbuild 2008-03-14 20:19:04 +0100
15065 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/Kbuild 2007-10-01 15:25:35 +0200
15066 +@@ -351,3 +351,6 @@ unifdef-y += xattr.h
15067 + unifdef-y += xfrm.h
15068 +
15069 + objhdr-y += version.h
15070 ++
15071 ++header-y += vserver/
15072 ++
15073 +diff -NurpP --minimal linux-2.6.22.19/include/linux/capability.h linux-2.6.22.19-vs2.2.0.7/include/linux/capability.h
15074 +--- linux-2.6.22.19/include/linux/capability.h 2007-07-09 13:19:55 +0200
15075 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/capability.h 2007-06-15 02:37:04 +0200
15076 +@@ -237,6 +237,7 @@ typedef __u32 kernel_cap_t;
15077 + arbitrary SCSI commands */
15078 + /* Allow setting encryption key on loopback filesystem */
15079 + /* Allow setting zone reclaim policy */
15080 ++/* Allow the selection of a security context */
15081 +
15082 + #define CAP_SYS_ADMIN 21
15083 +
15084 +@@ -290,6 +291,11 @@ typedef __u32 kernel_cap_t;
15085 +
15086 + #define CAP_AUDIT_CONTROL 30
15087 +
15088 ++/* Allow context manipulations */
15089 ++/* Allow changing context info on files */
15090 ++
15091 ++#define CAP_CONTEXT 31
15092 ++
15093 + #ifdef __KERNEL__
15094 + /*
15095 + * Bounding set
15096 +diff -NurpP --minimal linux-2.6.22.19/include/linux/devpts_fs.h linux-2.6.22.19-vs2.2.0.7/include/linux/devpts_fs.h
15097 +--- linux-2.6.22.19/include/linux/devpts_fs.h 2004-08-14 12:55:59 +0200
15098 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/devpts_fs.h 2007-06-15 02:37:04 +0200
15099 +@@ -30,5 +30,7 @@ static inline void devpts_pty_kill(int n
15100 +
15101 + #endif
15102 +
15103 ++#define DEVPTS_SUPER_MAGIC 0x00001cd1
15104 ++
15105 +
15106 + #endif /* _LINUX_DEVPTS_FS_H */
15107 +diff -NurpP --minimal linux-2.6.22.19/include/linux/ext2_fs.h linux-2.6.22.19-vs2.2.0.7/include/linux/ext2_fs.h
15108 +--- linux-2.6.22.19/include/linux/ext2_fs.h 2006-11-30 21:19:37 +0100
15109 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/ext2_fs.h 2007-06-15 02:37:04 +0200
15110 +@@ -188,6 +188,8 @@ struct ext2_group_desc
15111 + #define EXT2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */
15112 + #define EXT2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */
15113 + #define EXT2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
15114 ++#define EXT2_BARRIER_FL FS_BARRIER_FL /* Barrier for chroot() */
15115 ++#define EXT2_IUNLINK_FL FS_IUNLINK_FL /* Immutable unlink */
15116 + #define EXT2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */
15117 +
15118 + #define EXT2_FL_USER_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */
15119 +@@ -244,7 +246,7 @@ struct ext2_inode {
15120 + struct {
15121 + __u8 l_i_frag; /* Fragment number */
15122 + __u8 l_i_fsize; /* Fragment size */
15123 +- __u16 i_pad1;
15124 ++ __u16 l_i_tag; /* Context Tag */
15125 + __le16 l_i_uid_high; /* these 2 fields */
15126 + __le16 l_i_gid_high; /* were reserved2[0] */
15127 + __u32 l_i_reserved2;
15128 +@@ -276,6 +278,7 @@ struct ext2_inode {
15129 + #define i_gid_low i_gid
15130 + #define i_uid_high osd2.linux2.l_i_uid_high
15131 + #define i_gid_high osd2.linux2.l_i_gid_high
15132 ++#define i_raw_tag osd2.linux2.l_i_tag
15133 + #define i_reserved2 osd2.linux2.l_i_reserved2
15134 + #endif
15135 +
15136 +@@ -317,8 +320,9 @@ struct ext2_inode {
15137 + #define EXT2_MOUNT_XATTR_USER 0x004000 /* Extended user attributes */
15138 + #define EXT2_MOUNT_POSIX_ACL 0x008000 /* POSIX Access Control Lists */
15139 + #define EXT2_MOUNT_XIP 0x010000 /* Execute in place */
15140 +-#define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */
15141 +-#define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */
15142 ++#define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */
15143 ++#define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */
15144 ++#define EXT2_MOUNT_TAGGED (1<<24) /* Enable Context Tags */
15145 +
15146 +
15147 + #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
15148 +diff -NurpP --minimal linux-2.6.22.19/include/linux/ext3_fs.h linux-2.6.22.19-vs2.2.0.7/include/linux/ext3_fs.h
15149 +--- linux-2.6.22.19/include/linux/ext3_fs.h 2007-07-09 13:19:56 +0200
15150 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/ext3_fs.h 2007-06-15 02:37:04 +0200
15151 +@@ -177,10 +177,20 @@ struct ext3_group_desc
15152 + #define EXT3_NOTAIL_FL 0x00008000 /* file tail should not be merged */
15153 + #define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
15154 + #define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
15155 ++#define EXT3_BARRIER_FL 0x04000000 /* Barrier for chroot() */
15156 ++#define EXT3_IUNLINK_FL 0x08000000 /* Immutable unlink */
15157 + #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */
15158 +
15159 ++#ifdef CONFIG_VSERVER_LEGACY
15160 ++#define EXT3_FL_USER_VISIBLE 0x0803DFFF /* User visible flags */
15161 ++#define EXT3_FL_USER_MODIFIABLE 0x080380FF /* User modifiable flags */
15162 ++#else
15163 + #define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
15164 + #define EXT3_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
15165 ++#endif
15166 ++#ifdef CONFIG_VSERVER_LEGACY
15167 ++#define EXT3_IOC_SETTAG FIOC_SETTAGJ
15168 ++#endif
15169 +
15170 + /*
15171 + * Inode dynamic state flags
15172 +@@ -296,7 +306,7 @@ struct ext3_inode {
15173 + struct {
15174 + __u8 l_i_frag; /* Fragment number */
15175 + __u8 l_i_fsize; /* Fragment size */
15176 +- __u16 i_pad1;
15177 ++ __u16 l_i_tag; /* Context Tag */
15178 + __le16 l_i_uid_high; /* these 2 fields */
15179 + __le16 l_i_gid_high; /* were reserved2[0] */
15180 + __u32 l_i_reserved2;
15181 +@@ -330,6 +340,7 @@ struct ext3_inode {
15182 + #define i_gid_low i_gid
15183 + #define i_uid_high osd2.linux2.l_i_uid_high
15184 + #define i_gid_high osd2.linux2.l_i_gid_high
15185 ++#define i_raw_tag osd2.linux2.l_i_tag
15186 + #define i_reserved2 osd2.linux2.l_i_reserved2
15187 +
15188 + #elif defined(__GNU__)
15189 +@@ -384,6 +395,7 @@ struct ext3_inode {
15190 + #define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */
15191 + #define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
15192 + #define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
15193 ++#define EXT3_MOUNT_TAGGED (1<<24) /* Enable Context Tags */
15194 +
15195 + /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
15196 + #ifndef _LINUX_EXT2_FS_H
15197 +@@ -812,6 +824,7 @@ struct buffer_head * ext3_bread (handle_
15198 + int ext3_get_blocks_handle(handle_t *handle, struct inode *inode,
15199 + sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result,
15200 + int create, int extend_disksize);
15201 ++extern int ext3_sync_flags(struct inode *inode);
15202 +
15203 + extern void ext3_read_inode (struct inode *);
15204 + extern int ext3_write_inode (struct inode *, int);
15205 +diff -NurpP --minimal linux-2.6.22.19/include/linux/ext4_fs.h linux-2.6.22.19-vs2.2.0.7/include/linux/ext4_fs.h
15206 +--- linux-2.6.22.19/include/linux/ext4_fs.h 2007-07-09 13:19:56 +0200
15207 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/ext4_fs.h 2007-06-15 02:37:04 +0200
15208 +@@ -189,11 +189,21 @@ struct ext4_group_desc
15209 + #define EXT4_NOTAIL_FL 0x00008000 /* file tail should not be merged */
15210 + #define EXT4_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
15211 + #define EXT4_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
15212 +-#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
15213 + #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
15214 ++#define EXT4_BARRIER_FL 0x04000000 /* Barrier for chroot() */
15215 ++#define EXT4_IUNLINK_FL 0x08000000 /* Immutable unlink */
15216 ++#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
15217 +
15218 ++#ifdef CONFIG_VSERVER_LEGACY
15219 ++#define EXT4_FL_USER_VISIBLE 0x080BDFFF /* User visible flags */
15220 ++#define EXT4_FL_USER_MODIFIABLE 0x080380FF /* User modifiable flags */
15221 ++#else
15222 + #define EXT4_FL_USER_VISIBLE 0x000BDFFF /* User visible flags */
15223 + #define EXT4_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
15224 ++#endif
15225 ++#ifdef CONFIG_VSERVER_LEGACY
15226 ++#define EXT4_IOC_SETTAG FIOC_SETTAGJ
15227 ++#endif
15228 +
15229 + /*
15230 + * Inode dynamic state flags
15231 +@@ -312,7 +322,8 @@ struct ext4_inode {
15232 + __le16 l_i_file_acl_high;
15233 + __le16 l_i_uid_high; /* these 2 fields */
15234 + __le16 l_i_gid_high; /* were reserved2[0] */
15235 +- __u32 l_i_reserved2;
15236 ++ __u16 l_i_tag; /* Context Tag */
15237 ++ __u16 l_i_reserved2;
15238 + } linux2;
15239 + struct {
15240 + __u8 h_i_frag; /* Fragment number */
15241 +@@ -344,6 +355,7 @@ struct ext4_inode {
15242 + #define i_gid_low i_gid
15243 + #define i_uid_high osd2.linux2.l_i_uid_high
15244 + #define i_gid_high osd2.linux2.l_i_gid_high
15245 ++#define i_raw_tag osd2.linux2.l_i_tag
15246 + #define i_reserved2 osd2.linux2.l_i_reserved2
15247 +
15248 + #elif defined(__GNU__)
15249 +@@ -400,6 +412,7 @@ struct ext4_inode {
15250 + #define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
15251 + #define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
15252 + #define EXT4_MOUNT_EXTENTS 0x400000 /* Extents support */
15253 ++#define EXT4_MOUNT_TAGGED (1<<24) /* Enable Context Tags */
15254 +
15255 + /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */
15256 + #ifndef _LINUX_EXT2_FS_H
15257 +@@ -850,6 +863,7 @@ struct buffer_head * ext4_bread (handle_
15258 + int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
15259 + sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result,
15260 + int create, int extend_disksize);
15261 ++extern int ext4_sync_flags(struct inode *inode);
15262 +
15263 + extern void ext4_read_inode (struct inode *);
15264 + extern int ext4_write_inode (struct inode *, int);
15265 +diff -NurpP --minimal linux-2.6.22.19/include/linux/fs.h linux-2.6.22.19-vs2.2.0.7/include/linux/fs.h
15266 +--- linux-2.6.22.19/include/linux/fs.h 2007-07-09 13:19:56 +0200
15267 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/fs.h 2007-10-29 23:24:21 +0100
15268 +@@ -123,6 +123,8 @@ extern int dir_notify_enable;
15269 + #define MS_SLAVE (1<<19) /* change to slave */
15270 + #define MS_SHARED (1<<20) /* change to shared */
15271 + #define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */
15272 ++#define MS_TAGGED (1<<24) /* use generic inode tagging */
15273 ++#define MS_TAGID (1<<25) /* use specific tag for this mount */
15274 + #define MS_ACTIVE (1<<30)
15275 + #define MS_NOUSER (1<<31)
15276 +
15277 +@@ -149,6 +151,8 @@ extern int dir_notify_enable;
15278 + #define S_NOCMTIME 128 /* Do not update file c/mtime */
15279 + #define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */
15280 + #define S_PRIVATE 512 /* Inode is fs-internal */
15281 ++#define S_BARRIER 1024 /* Barrier for chroot() */
15282 ++#define S_IUNLINK 2048 /* Immutable unlink */
15283 +
15284 + /*
15285 + * Note that nosuid etc flags are inode-specific: setting some file-system
15286 +@@ -165,24 +169,36 @@ extern int dir_notify_enable;
15287 + */
15288 + #define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg))
15289 +
15290 +-#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
15291 ++#define IS_RDONLY(inode) __IS_FLG(inode, MS_RDONLY)
15292 + #define IS_SYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS) || \
15293 + ((inode)->i_flags & S_SYNC))
15294 + #define IS_DIRSYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \
15295 + ((inode)->i_flags & (S_SYNC|S_DIRSYNC)))
15296 + #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK)
15297 +-#define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
15298 ++#define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
15299 ++#define IS_TAGGED(inode) __IS_FLG(inode, MS_TAGGED)
15300 +
15301 + #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
15302 + #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
15303 + #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
15304 ++#define IS_IUNLINK(inode) ((inode)->i_flags & S_IUNLINK)
15305 ++#define IS_IXORUNLINK(inode) ((IS_IUNLINK(inode) ? S_IMMUTABLE : 0) ^ IS_IMMUTABLE(inode))
15306 + #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
15307 +
15308 ++#define IS_BARRIER(inode) (S_ISDIR((inode)->i_mode) && ((inode)->i_flags & S_BARRIER))
15309 + #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
15310 + #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME)
15311 + #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE)
15312 + #define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE)
15313 +
15314 ++#ifdef CONFIG_VSERVER_COWBL
15315 ++# define IS_COW(inode) (IS_IUNLINK(inode) && IS_IMMUTABLE(inode))
15316 ++# define IS_COW_LINK(inode) (S_ISREG((inode)->i_mode) && ((inode)->i_nlink > 1))
15317 ++#else
15318 ++# define IS_COW(inode) (0)
15319 ++# define IS_COW_LINK(inode) (0)
15320 ++#endif
15321 ++
15322 + /* the read-only stuff doesn't really belong here, but any other place is
15323 + probably as bad and I don't want to create yet another include file. */
15324 +
15325 +@@ -256,11 +272,17 @@ extern int dir_notify_enable;
15326 + #define FS_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
15327 + #define FS_EXTENT_FL 0x00080000 /* Extents */
15328 + #define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */
15329 ++#define FS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
15330 ++#define FS_IUNLINK_FL 0x08000000 /* Immutable unlink */
15331 + #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
15332 +
15333 ++#ifdef CONFIG_VSERVER_LEGACY
15334 ++#define FS_FL_USER_VISIBLE 0x0803DFFF /* User visible flags */
15335 ++#define FS_FL_USER_MODIFIABLE 0x080380FF /* User modifiable flags */
15336 ++#else
15337 + #define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
15338 + #define FS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
15339 +-
15340 ++#endif
15341 +
15342 + #define SYNC_FILE_RANGE_WAIT_BEFORE 1
15343 + #define SYNC_FILE_RANGE_WRITE 2
15344 +@@ -327,6 +349,7 @@ typedef void (dio_iodone_t)(struct kiocb
15345 + #define ATTR_KILL_SUID 2048
15346 + #define ATTR_KILL_SGID 4096
15347 + #define ATTR_FILE 8192
15348 ++#define ATTR_TAG 16384
15349 +
15350 + /*
15351 + * This is the Inode Attributes structure, used for notify_change(). It
15352 +@@ -342,6 +365,7 @@ struct iattr {
15353 + umode_t ia_mode;
15354 + uid_t ia_uid;
15355 + gid_t ia_gid;
15356 ++ tag_t ia_tag;
15357 + loff_t ia_size;
15358 + struct timespec ia_atime;
15359 + struct timespec ia_mtime;
15360 +@@ -355,6 +379,9 @@ struct iattr {
15361 + struct file *ia_file;
15362 + };
15363 +
15364 ++#define ATTR_FLAG_BARRIER 512 /* Barrier for chroot() */
15365 ++#define ATTR_FLAG_IUNLINK 1024 /* Immutable unlink */
15366 ++
15367 + /*
15368 + * Includes for diskquotas.
15369 + */
15370 +@@ -537,6 +564,7 @@ struct inode {
15371 + unsigned int i_nlink;
15372 + uid_t i_uid;
15373 + gid_t i_gid;
15374 ++ tag_t i_tag;
15375 + dev_t i_rdev;
15376 + unsigned long i_version;
15377 + loff_t i_size;
15378 +@@ -728,6 +756,7 @@ struct file {
15379 + loff_t f_pos;
15380 + struct fown_struct f_owner;
15381 + unsigned int f_uid, f_gid;
15382 ++ xid_t f_xid;
15383 + struct file_ra_state f_ra;
15384 +
15385 + unsigned long f_version;
15386 +@@ -811,6 +840,7 @@ struct file_lock {
15387 + unsigned char fl_type;
15388 + loff_t fl_start;
15389 + loff_t fl_end;
15390 ++ xid_t fl_xid;
15391 +
15392 + struct fasync_struct * fl_fasync; /* for lease break notifications */
15393 + unsigned long fl_break_time; /* for nonblocking lease breaks */
15394 +@@ -993,12 +1023,12 @@ extern void unlock_super(struct super_bl
15395 + */
15396 + extern int vfs_permission(struct nameidata *, int);
15397 + extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
15398 +-extern int vfs_mkdir(struct inode *, struct dentry *, int);
15399 +-extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
15400 +-extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
15401 +-extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
15402 +-extern int vfs_rmdir(struct inode *, struct dentry *);
15403 +-extern int vfs_unlink(struct inode *, struct dentry *);
15404 ++extern int vfs_mkdir(struct inode *, struct dentry *, int, struct nameidata *);
15405 ++extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t, struct nameidata *);
15406 ++extern int vfs_symlink(struct inode *, struct dentry *, const char *, int, struct nameidata *);
15407 ++extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct nameidata *);
15408 ++extern int vfs_rmdir(struct inode *, struct dentry *, struct nameidata *);
15409 ++extern int vfs_unlink(struct inode *, struct dentry *, struct nameidata *);
15410 + extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
15411 +
15412 + /*
15413 +@@ -1138,6 +1168,7 @@ struct inode_operations {
15414 + ssize_t (*listxattr) (struct dentry *, char *, size_t);
15415 + int (*removexattr) (struct dentry *, const char *);
15416 + void (*truncate_range)(struct inode *, loff_t, loff_t);
15417 ++ int (*sync_flags) (struct inode *);
15418 + };
15419 +
15420 + struct seq_file;
15421 +@@ -1153,6 +1184,7 @@ extern ssize_t vfs_readv(struct file *,
15422 + unsigned long, loff_t *);
15423 + extern ssize_t vfs_writev(struct file *, const struct iovec __user *,
15424 + unsigned long, loff_t *);
15425 ++ssize_t vfs_sendfile(struct file *, struct file *, loff_t *, size_t, loff_t);
15426 +
15427 + /*
15428 + * NOTE: write_inode, delete_inode, clear_inode, put_inode can be called
15429 +@@ -1898,6 +1930,7 @@ extern int dcache_dir_open(struct inode
15430 + extern int dcache_dir_close(struct inode *, struct file *);
15431 + extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
15432 + extern int dcache_readdir(struct file *, void *, filldir_t);
15433 ++extern int dcache_readdir_filter(struct file *, void *, filldir_t, int (*)(struct dentry *));
15434 + extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
15435 + extern int simple_statfs(struct dentry *, struct kstatfs *);
15436 + extern int simple_link(struct dentry *, struct inode *, struct dentry *);
15437 +diff -NurpP --minimal linux-2.6.22.19/include/linux/init_task.h linux-2.6.22.19-vs2.2.0.7/include/linux/init_task.h
15438 +--- linux-2.6.22.19/include/linux/init_task.h 2007-07-09 13:19:56 +0200
15439 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/init_task.h 2007-06-15 02:37:04 +0200
15440 +@@ -169,6 +169,10 @@ extern struct group_info init_groups;
15441 + }, \
15442 + INIT_TRACE_IRQFLAGS \
15443 + INIT_LOCKDEP \
15444 ++ .xid = 0, \
15445 ++ .vx_info = NULL, \
15446 ++ .nid = 0, \
15447 ++ .nx_info = NULL, \
15448 + }
15449 +
15450 +
15451 +diff -NurpP --minimal linux-2.6.22.19/include/linux/ipc.h linux-2.6.22.19-vs2.2.0.7/include/linux/ipc.h
15452 +--- linux-2.6.22.19/include/linux/ipc.h 2007-07-09 13:19:56 +0200
15453 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/ipc.h 2007-06-15 02:37:04 +0200
15454 +@@ -63,6 +63,7 @@ struct kern_ipc_perm
15455 + key_t key;
15456 + uid_t uid;
15457 + gid_t gid;
15458 ++ xid_t xid;
15459 + uid_t cuid;
15460 + gid_t cgid;
15461 + mode_t mode;
15462 +diff -NurpP --minimal linux-2.6.22.19/include/linux/loop.h linux-2.6.22.19-vs2.2.0.7/include/linux/loop.h
15463 +--- linux-2.6.22.19/include/linux/loop.h 2007-07-09 13:19:56 +0200
15464 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/loop.h 2007-06-15 02:37:04 +0200
15465 +@@ -45,6 +45,7 @@ struct loop_device {
15466 + struct loop_func_table *lo_encryption;
15467 + __u32 lo_init[2];
15468 + uid_t lo_key_owner; /* Who set the key */
15469 ++ xid_t lo_xid;
15470 + int (*ioctl)(struct loop_device *, int cmd,
15471 + unsigned long arg);
15472 +
15473 +diff -NurpP --minimal linux-2.6.22.19/include/linux/major.h linux-2.6.22.19-vs2.2.0.7/include/linux/major.h
15474 +--- linux-2.6.22.19/include/linux/major.h 2007-07-09 13:19:56 +0200
15475 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/major.h 2007-06-15 02:37:04 +0200
15476 +@@ -15,6 +15,7 @@
15477 + #define HD_MAJOR IDE0_MAJOR
15478 + #define PTY_SLAVE_MAJOR 3
15479 + #define TTY_MAJOR 4
15480 ++#define VROOT_MAJOR 4
15481 + #define TTYAUX_MAJOR 5
15482 + #define LP_MAJOR 6
15483 + #define VCS_MAJOR 7
15484 +diff -NurpP --minimal linux-2.6.22.19/include/linux/mount.h linux-2.6.22.19-vs2.2.0.7/include/linux/mount.h
15485 +--- linux-2.6.22.19/include/linux/mount.h 2007-07-09 13:19:56 +0200
15486 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/mount.h 2007-06-15 03:54:15 +0200
15487 +@@ -28,12 +28,16 @@ struct mnt_namespace;
15488 + #define MNT_NOATIME 0x08
15489 + #define MNT_NODIRATIME 0x10
15490 + #define MNT_RELATIME 0x20
15491 ++#define MNT_RDONLY 0x40
15492 ++
15493 ++#define MNT_IS_RDONLY(m) ((m) && ((m)->mnt_flags & MNT_RDONLY))
15494 +
15495 + #define MNT_SHRINKABLE 0x100
15496 +
15497 + #define MNT_SHARED 0x1000 /* if the vfsmount is a shared mount */
15498 + #define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */
15499 + #define MNT_PNODE_MASK 0x3000 /* propagation flag mask */
15500 ++#define MNT_TAGID 0x8000
15501 +
15502 + struct vfsmount {
15503 + struct list_head mnt_hash;
15504 +@@ -61,6 +65,7 @@ struct vfsmount {
15505 + atomic_t mnt_count;
15506 + int mnt_expiry_mark; /* true if marked for expiry */
15507 + int mnt_pinned;
15508 ++ tag_t mnt_tag; /* tagging used for vfsmount */
15509 + };
15510 +
15511 + static inline struct vfsmount *mntget(struct vfsmount *mnt)
15512 +diff -NurpP --minimal linux-2.6.22.19/include/linux/net.h linux-2.6.22.19-vs2.2.0.7/include/linux/net.h
15513 +--- linux-2.6.22.19/include/linux/net.h 2007-07-09 13:19:56 +0200
15514 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/net.h 2007-06-15 02:37:04 +0200
15515 +@@ -63,6 +63,7 @@ typedef enum {
15516 + #define SOCK_NOSPACE 2
15517 + #define SOCK_PASSCRED 3
15518 + #define SOCK_PASSSEC 4
15519 ++#define SOCK_USER_SOCKET 5
15520 +
15521 + #ifndef ARCH_HAS_SOCKET_TYPES
15522 + /**
15523 +diff -NurpP --minimal linux-2.6.22.19/include/linux/nfs_mount.h linux-2.6.22.19-vs2.2.0.7/include/linux/nfs_mount.h
15524 +--- linux-2.6.22.19/include/linux/nfs_mount.h 2007-07-09 13:20:00 +0200
15525 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/nfs_mount.h 2007-06-15 03:54:39 +0200
15526 +@@ -62,6 +62,7 @@ struct nfs_mount_data {
15527 + #define NFS_MOUNT_STRICTLOCK 0x1000 /* reserved for NFSv4 */
15528 + #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */
15529 + #define NFS_MOUNT_NORDIRPLUS 0x4000 /* 5 */
15530 ++#define NFS_MOUNT_TAGGED 0x8000 /* context tagging */
15531 + #define NFS_MOUNT_FLAGMASK 0xFFFF
15532 +
15533 + #endif
15534 +diff -NurpP --minimal linux-2.6.22.19/include/linux/nsproxy.h linux-2.6.22.19-vs2.2.0.7/include/linux/nsproxy.h
15535 +--- linux-2.6.22.19/include/linux/nsproxy.h 2007-07-09 13:20:00 +0200
15536 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/nsproxy.h 2007-07-17 03:02:15 +0200
15537 +@@ -3,6 +3,7 @@
15538 +
15539 + #include <linux/spinlock.h>
15540 + #include <linux/sched.h>
15541 ++#include <linux/vserver/debug.h>
15542 +
15543 + struct mnt_namespace;
15544 + struct uts_namespace;
15545 +@@ -32,26 +33,46 @@ struct nsproxy {
15546 + extern struct nsproxy init_nsproxy;
15547 +
15548 + int copy_namespaces(int flags, struct task_struct *tsk);
15549 ++struct nsproxy *copy_nsproxy(struct nsproxy *orig);
15550 + void get_task_namespaces(struct task_struct *tsk);
15551 + void free_nsproxy(struct nsproxy *ns);
15552 + int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **,
15553 + struct fs_struct *);
15554 +
15555 +-static inline void put_nsproxy(struct nsproxy *ns)
15556 ++#define get_nsproxy(n) __get_nsproxy(n, __FILE__, __LINE__)
15557 ++
15558 ++static inline void __get_nsproxy(struct nsproxy *ns,
15559 ++ const char *_file, int _line)
15560 + {
15561 ++ vxlprintk(VXD_CBIT(space, 0), "get_nsproxy(%p[%u])",
15562 ++ ns, atomic_read(&ns->count), _file, _line);
15563 ++ atomic_inc(&ns->count);
15564 ++}
15565 ++
15566 ++#define put_nsproxy(n) __put_nsproxy(n, __FILE__, __LINE__)
15567 ++
15568 ++static inline void __put_nsproxy(struct nsproxy *ns,
15569 ++ const char *_file, int _line)
15570 ++{
15571 ++ vxlprintk(VXD_CBIT(space, 0), "put_nsproxy(%p[%u])",
15572 ++ ns, atomic_read(&ns->count), _file, _line);
15573 + if (atomic_dec_and_test(&ns->count)) {
15574 + free_nsproxy(ns);
15575 + }
15576 + }
15577 +
15578 +-static inline void exit_task_namespaces(struct task_struct *p)
15579 ++#define exit_task_namespaces(p) __exit_task_namespaces(p, __FILE__, __LINE__)
15580 ++
15581 ++static inline void __exit_task_namespaces(struct task_struct *p,
15582 ++ const char *_file, int _line)
15583 + {
15584 + struct nsproxy *ns = p->nsproxy;
15585 + if (ns) {
15586 + task_lock(p);
15587 + p->nsproxy = NULL;
15588 + task_unlock(p);
15589 +- put_nsproxy(ns);
15590 ++ __put_nsproxy(ns, _file, _line);
15591 + }
15592 + }
15593 ++
15594 + #endif
15595 +diff -NurpP --minimal linux-2.6.22.19/include/linux/pid.h linux-2.6.22.19-vs2.2.0.7/include/linux/pid.h
15596 +--- linux-2.6.22.19/include/linux/pid.h 2007-07-09 13:20:00 +0200
15597 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/pid.h 2007-06-15 02:37:04 +0200
15598 +@@ -8,7 +8,8 @@ enum pid_type
15599 + PIDTYPE_PID,
15600 + PIDTYPE_PGID,
15601 + PIDTYPE_SID,
15602 +- PIDTYPE_MAX
15603 ++ PIDTYPE_MAX,
15604 ++ PIDTYPE_REALPID
15605 + };
15606 +
15607 + /*
15608 +diff -NurpP --minimal linux-2.6.22.19/include/linux/proc_fs.h linux-2.6.22.19-vs2.2.0.7/include/linux/proc_fs.h
15609 +--- linux-2.6.22.19/include/linux/proc_fs.h 2007-07-09 13:20:00 +0200
15610 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/proc_fs.h 2007-06-15 02:37:04 +0200
15611 +@@ -54,6 +54,7 @@ struct proc_dir_entry {
15612 + nlink_t nlink;
15613 + uid_t uid;
15614 + gid_t gid;
15615 ++ int vx_flags;
15616 + loff_t size;
15617 + const struct inode_operations *proc_iops;
15618 + const struct file_operations *proc_fops;
15619 +@@ -246,13 +247,20 @@ static inline void kclist_add(struct kco
15620 + extern void kclist_add(struct kcore_list *, void *, size_t);
15621 + #endif
15622 +
15623 ++struct vx_info;
15624 ++struct nx_info;
15625 ++
15626 + union proc_op {
15627 + int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
15628 + int (*proc_read)(struct task_struct *task, char *page);
15629 ++ int (*proc_vs_read)(char *page);
15630 ++ int (*proc_vxi_read)(struct vx_info *vxi, char *page);
15631 ++ int (*proc_nxi_read)(struct nx_info *nxi, char *page);
15632 + };
15633 +
15634 + struct proc_inode {
15635 + struct pid *pid;
15636 ++ int vx_flags;
15637 + int fd;
15638 + union proc_op op;
15639 + struct proc_dir_entry *pde;
15640 +diff -NurpP --minimal linux-2.6.22.19/include/linux/reiserfs_fs.h linux-2.6.22.19-vs2.2.0.7/include/linux/reiserfs_fs.h
15641 +--- linux-2.6.22.19/include/linux/reiserfs_fs.h 2007-05-02 19:25:34 +0200
15642 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/reiserfs_fs.h 2007-06-15 02:37:04 +0200
15643 +@@ -821,6 +821,10 @@ struct stat_data_v1 {
15644 + #define REISERFS_COMPR_FL FS_COMPR_FL
15645 + #define REISERFS_NOTAIL_FL FS_NOTAIL_FL
15646 +
15647 ++/* unfortunately reiserfs sdattr is only 16 bit */
15648 ++#define REISERFS_BARRIER_FL (FS_BARRIER_FL >> 16)
15649 ++#define REISERFS_IUNLINK_FL (FS_IUNLINK_FL >> 16)
15650 ++
15651 + /* persistent flags that file inherits from the parent directory */
15652 + #define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FL | \
15653 + REISERFS_SYNC_FL | \
15654 +@@ -830,6 +834,14 @@ struct stat_data_v1 {
15655 + REISERFS_COMPR_FL | \
15656 + REISERFS_NOTAIL_FL )
15657 +
15658 ++#ifdef CONFIG_VSERVER_LEGACY
15659 ++#define REISERFS_FL_USER_VISIBLE (REISERFS_IUNLINK_FL|0x80FF)
15660 ++#define REISERFS_FL_USER_MODIFIABLE (REISERFS_IUNLINK_FL|0x80FF)
15661 ++#else
15662 ++#define REISERFS_FL_USER_VISIBLE 0x80FF
15663 ++#define REISERFS_FL_USER_MODIFIABLE 0x80FF
15664 ++#endif
15665 ++
15666 + /* Stat Data on disk (reiserfs version of UFS disk inode minus the
15667 + address blocks) */
15668 + struct stat_data {
15669 +@@ -1901,6 +1913,7 @@ static inline void reiserfs_update_sd(st
15670 + void sd_attrs_to_i_attrs(__u16 sd_attrs, struct inode *inode);
15671 + void i_attrs_to_sd_attrs(struct inode *inode, __u16 * sd_attrs);
15672 + int reiserfs_setattr(struct dentry *dentry, struct iattr *attr);
15673 ++int reiserfs_sync_flags(struct inode *inode);
15674 +
15675 + /* namei.c */
15676 + void set_de_name_and_namelen(struct reiserfs_dir_entry *de);
15677 +diff -NurpP --minimal linux-2.6.22.19/include/linux/reiserfs_fs_sb.h linux-2.6.22.19-vs2.2.0.7/include/linux/reiserfs_fs_sb.h
15678 +--- linux-2.6.22.19/include/linux/reiserfs_fs_sb.h 2007-07-09 13:20:00 +0200
15679 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/reiserfs_fs_sb.h 2007-06-15 02:37:04 +0200
15680 +@@ -458,6 +458,7 @@ enum reiserfs_mount_options {
15681 + REISERFS_POSIXACL,
15682 + REISERFS_BARRIER_NONE,
15683 + REISERFS_BARRIER_FLUSH,
15684 ++ REISERFS_TAGGED,
15685 +
15686 + /* Actions on error */
15687 + REISERFS_ERROR_PANIC,
15688 +diff -NurpP --minimal linux-2.6.22.19/include/linux/sched.h linux-2.6.22.19-vs2.2.0.7/include/linux/sched.h
15689 +--- linux-2.6.22.19/include/linux/sched.h 2007-07-09 13:20:01 +0200
15690 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/sched.h 2007-06-17 05:54:19 +0200
15691 +@@ -26,6 +26,7 @@
15692 + #define CLONE_STOPPED 0x02000000 /* Start in stopped state */
15693 + #define CLONE_NEWUTS 0x04000000 /* New utsname group? */
15694 + #define CLONE_NEWIPC 0x08000000 /* New ipcs */
15695 ++#define CLONE_KTHREAD 0x10000000 /* clone a kernel thread */
15696 +
15697 + /*
15698 + * Scheduling policies
15699 +@@ -94,7 +95,7 @@ struct bio;
15700 + * List of flags we want to share for kernel threads,
15701 + * if only because they are not used by them anyway.
15702 + */
15703 +-#define CLONE_KERNEL (CLONE_FS | CLONE_FILES | CLONE_SIGHAND)
15704 ++#define CLONE_KERNEL (CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_KTHREAD)
15705 +
15706 + /*
15707 + * These are the constant used to fake the fixed-point load-average
15708 +@@ -146,12 +147,13 @@ extern unsigned long weighted_cpuload(co
15709 + #define TASK_UNINTERRUPTIBLE 2
15710 + #define TASK_STOPPED 4
15711 + #define TASK_TRACED 8
15712 ++#define TASK_ONHOLD 16
15713 + /* in tsk->exit_state */
15714 +-#define EXIT_ZOMBIE 16
15715 +-#define EXIT_DEAD 32
15716 ++#define EXIT_ZOMBIE 32
15717 ++#define EXIT_DEAD 64
15718 + /* in tsk->state again */
15719 +-#define TASK_NONINTERACTIVE 64
15720 +-#define TASK_DEAD 128
15721 ++#define TASK_NONINTERACTIVE 128
15722 ++#define TASK_DEAD 256
15723 +
15724 + #define __set_task_state(tsk, state_value) \
15725 + do { (tsk)->state = (state_value); } while (0)
15726 +@@ -287,27 +289,30 @@ extern void arch_unmap_area_topdown(stru
15727 + * The mm counters are not protected by its page_table_lock,
15728 + * so must be incremented atomically.
15729 + */
15730 +-#define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value)
15731 +-#define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member))
15732 +-#define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member)
15733 +-#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member)
15734 +-#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member)
15735 + typedef atomic_long_t mm_counter_t;
15736 ++#define __set_mm_counter(mm, member, value) \
15737 ++ atomic_long_set(&(mm)->_##member, value)
15738 ++#define get_mm_counter(mm, member) \
15739 ++ ((unsigned long)atomic_long_read(&(mm)->_##member))
15740 +
15741 + #else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
15742 + /*
15743 + * The mm counters are protected by its page_table_lock,
15744 + * so can be incremented directly.
15745 + */
15746 +-#define set_mm_counter(mm, member, value) (mm)->_##member = (value)
15747 +-#define get_mm_counter(mm, member) ((mm)->_##member)
15748 +-#define add_mm_counter(mm, member, value) (mm)->_##member += (value)
15749 +-#define inc_mm_counter(mm, member) (mm)->_##member++
15750 +-#define dec_mm_counter(mm, member) (mm)->_##member--
15751 + typedef unsigned long mm_counter_t;
15752 ++#define __set_mm_counter(mm, member, value) (mm)->_##member = (value)
15753 ++#define get_mm_counter(mm, member) ((mm)->_##member)
15754 +
15755 + #endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
15756 +
15757 ++#define set_mm_counter(mm, member, value) \
15758 ++ vx_ ## member ## pages_sub((mm), (get_mm_counter(mm, member) - value))
15759 ++#define add_mm_counter(mm, member, value) \
15760 ++ vx_ ## member ## pages_add((mm), (value))
15761 ++#define inc_mm_counter(mm, member) vx_ ## member ## pages_inc((mm))
15762 ++#define dec_mm_counter(mm, member) vx_ ## member ## pages_dec((mm))
15763 ++
15764 + #define get_mm_rss(mm) \
15765 + (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
15766 + #define update_hiwater_rss(mm) do { \
15767 +@@ -365,6 +370,7 @@ struct mm_struct {
15768 +
15769 + /* Architecture-specific MM context */
15770 + mm_context_t context;
15771 ++ struct vx_info *mm_vx_info;
15772 +
15773 + /* Swap token stuff */
15774 + /*
15775 +@@ -570,9 +576,10 @@ struct user_struct {
15776 + /* Hash table maintenance information */
15777 + struct list_head uidhash_list;
15778 + uid_t uid;
15779 ++ xid_t xid;
15780 + };
15781 +
15782 +-extern struct user_struct *find_user(uid_t);
15783 ++extern struct user_struct *find_user(xid_t, uid_t);
15784 +
15785 + extern struct user_struct root_user;
15786 + #define INIT_USER (&root_user)
15787 +@@ -969,6 +976,14 @@ struct task_struct {
15788 +
15789 + void *security;
15790 + struct audit_context *audit_context;
15791 ++
15792 ++/* vserver context data */
15793 ++ struct vx_info *vx_info;
15794 ++ struct nx_info *nx_info;
15795 ++
15796 ++ xid_t xid;
15797 ++ nid_t nid;
15798 ++
15799 + seccomp_t seccomp;
15800 +
15801 + /* Thread group tracking */
15802 +@@ -1290,12 +1305,16 @@ extern struct task_struct init_task;
15803 +
15804 + extern struct mm_struct init_mm;
15805 +
15806 +-#define find_task_by_pid(nr) find_task_by_pid_type(PIDTYPE_PID, nr)
15807 ++#define find_task_by_real_pid(nr) \
15808 ++ find_task_by_pid_type(PIDTYPE_REALPID, nr)
15809 ++#define find_task_by_pid(nr) \
15810 ++ find_task_by_pid_type(PIDTYPE_PID, nr)
15811 ++
15812 + extern struct task_struct *find_task_by_pid_type(int type, int pid);
15813 + extern void __set_special_pids(pid_t session, pid_t pgrp);
15814 +
15815 + /* per-UID process charging. */
15816 +-extern struct user_struct * alloc_uid(uid_t);
15817 ++extern struct user_struct * alloc_uid(xid_t, uid_t);
15818 + static inline struct user_struct *get_uid(struct user_struct *u)
15819 + {
15820 + atomic_inc(&u->__count);
15821 +diff -NurpP --minimal linux-2.6.22.19/include/linux/shmem_fs.h linux-2.6.22.19-vs2.2.0.7/include/linux/shmem_fs.h
15822 +--- linux-2.6.22.19/include/linux/shmem_fs.h 2006-11-30 21:19:39 +0100
15823 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/shmem_fs.h 2007-06-15 02:37:04 +0200
15824 +@@ -8,6 +8,9 @@
15825 +
15826 + #define SHMEM_NR_DIRECT 16
15827 +
15828 ++#define TMPFS_SUPER_MAGIC 0x01021994
15829 ++
15830 ++
15831 + struct shmem_inode_info {
15832 + spinlock_t lock;
15833 + unsigned long flags;
15834 +diff -NurpP --minimal linux-2.6.22.19/include/linux/stat.h linux-2.6.22.19-vs2.2.0.7/include/linux/stat.h
15835 +--- linux-2.6.22.19/include/linux/stat.h 2007-07-09 13:20:01 +0200
15836 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/stat.h 2007-06-15 02:37:04 +0200
15837 +@@ -66,6 +66,7 @@ struct kstat {
15838 + unsigned int nlink;
15839 + uid_t uid;
15840 + gid_t gid;
15841 ++ tag_t tag;
15842 + dev_t rdev;
15843 + loff_t size;
15844 + struct timespec atime;
15845 +diff -NurpP --minimal linux-2.6.22.19/include/linux/sunrpc/auth.h linux-2.6.22.19-vs2.2.0.7/include/linux/sunrpc/auth.h
15846 +--- linux-2.6.22.19/include/linux/sunrpc/auth.h 2006-11-30 21:19:40 +0100
15847 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/sunrpc/auth.h 2007-06-15 02:37:04 +0200
15848 +@@ -24,6 +24,7 @@
15849 + struct auth_cred {
15850 + uid_t uid;
15851 + gid_t gid;
15852 ++ tag_t tag;
15853 + struct group_info *group_info;
15854 + };
15855 +
15856 +diff -NurpP --minimal linux-2.6.22.19/include/linux/sunrpc/clnt.h linux-2.6.22.19-vs2.2.0.7/include/linux/sunrpc/clnt.h
15857 +--- linux-2.6.22.19/include/linux/sunrpc/clnt.h 2007-07-09 13:20:01 +0200
15858 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/sunrpc/clnt.h 2007-06-15 02:37:04 +0200
15859 +@@ -43,7 +43,8 @@ struct rpc_clnt {
15860 + cl_discrtry : 1,/* disconnect before retry */
15861 + cl_autobind : 1,/* use getport() */
15862 + cl_oneshot : 1,/* dispose after use */
15863 +- cl_dead : 1;/* abandoned */
15864 ++ cl_dead : 1,/* abandoned */
15865 ++ cl_tag : 1;/* context tagging */
15866 +
15867 + struct rpc_rtt * cl_rtt; /* RTO estimator data */
15868 +
15869 +diff -NurpP --minimal linux-2.6.22.19/include/linux/syscalls.h linux-2.6.22.19-vs2.2.0.7/include/linux/syscalls.h
15870 +--- linux-2.6.22.19/include/linux/syscalls.h 2007-07-09 13:20:01 +0200
15871 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/syscalls.h 2007-07-07 03:52:54 +0200
15872 +@@ -294,6 +294,8 @@ asmlinkage long sys_symlink(const char _
15873 + asmlinkage long sys_unlink(const char __user *pathname);
15874 + asmlinkage long sys_rename(const char __user *oldname,
15875 + const char __user *newname);
15876 ++asmlinkage long sys_copyfile(const char __user *from, const char __user *to,
15877 ++ umode_t mode);
15878 + asmlinkage long sys_chmod(const char __user *filename, mode_t mode);
15879 + asmlinkage long sys_fchmod(unsigned int fd, mode_t mode);
15880 +
15881 +diff -NurpP --minimal linux-2.6.22.19/include/linux/sysctl.h linux-2.6.22.19-vs2.2.0.7/include/linux/sysctl.h
15882 +--- linux-2.6.22.19/include/linux/sysctl.h 2007-07-09 13:20:01 +0200
15883 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/sysctl.h 2007-06-15 02:37:04 +0200
15884 +@@ -106,6 +106,7 @@ enum
15885 + KERN_CAP_BSET=14, /* int: capability bounding set */
15886 + KERN_PANIC=15, /* int: panic timeout */
15887 + KERN_REALROOTDEV=16, /* real root device to mount after initrd */
15888 ++ KERN_VSHELPER=17, /* string: path to vshelper policy agent */
15889 +
15890 + KERN_SPARC_REBOOT=21, /* reboot command on Sparc */
15891 + KERN_CTLALTDEL=22, /* int: allow ctl-alt-del to reboot */
15892 +diff -NurpP --minimal linux-2.6.22.19/include/linux/sysfs.h linux-2.6.22.19-vs2.2.0.7/include/linux/sysfs.h
15893 +--- linux-2.6.22.19/include/linux/sysfs.h 2007-07-09 13:20:01 +0200
15894 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/sysfs.h 2007-06-15 02:37:04 +0200
15895 +@@ -15,6 +15,8 @@
15896 + #include <linux/list.h>
15897 + #include <asm/atomic.h>
15898 +
15899 ++#define SYSFS_SUPER_MAGIC 0x62656572
15900 ++
15901 + struct kobject;
15902 + struct module;
15903 + struct nameidata;
15904 +diff -NurpP --minimal linux-2.6.22.19/include/linux/time.h linux-2.6.22.19-vs2.2.0.7/include/linux/time.h
15905 +--- linux-2.6.22.19/include/linux/time.h 2007-07-09 13:20:01 +0200
15906 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/time.h 2007-06-15 02:37:04 +0200
15907 +@@ -176,6 +176,9 @@ static inline void timespec_add_ns(struc
15908 + }
15909 + a->tv_nsec = ns;
15910 + }
15911 ++
15912 ++#include <linux/vs_time.h>
15913 ++
15914 + #endif /* __KERNEL__ */
15915 +
15916 + #define NFDBITS __NFDBITS
15917 +diff -NurpP --minimal linux-2.6.22.19/include/linux/types.h linux-2.6.22.19-vs2.2.0.7/include/linux/types.h
15918 +--- linux-2.6.22.19/include/linux/types.h 2007-02-06 03:01:52 +0100
15919 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/types.h 2007-06-15 02:37:04 +0200
15920 +@@ -39,6 +39,9 @@ typedef __kernel_uid32_t uid_t;
15921 + typedef __kernel_gid32_t gid_t;
15922 + typedef __kernel_uid16_t uid16_t;
15923 + typedef __kernel_gid16_t gid16_t;
15924 ++typedef unsigned int xid_t;
15925 ++typedef unsigned int nid_t;
15926 ++typedef unsigned int tag_t;
15927 +
15928 + #ifdef CONFIG_UID16
15929 + /* This is defined by include/asm-{arch}/posix_types.h */
15930 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vroot.h linux-2.6.22.19-vs2.2.0.7/include/linux/vroot.h
15931 +--- linux-2.6.22.19/include/linux/vroot.h 1970-01-01 01:00:00 +0100
15932 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vroot.h 2007-06-15 02:37:04 +0200
15933 +@@ -0,0 +1,51 @@
15934 ++
15935 ++/*
15936 ++ * include/linux/vroot.h
15937 ++ *
15938 ++ * written by Herbert Pötzl, 9/11/2002
15939 ++ * ported to 2.6 by Herbert Pötzl, 30/12/2004
15940 ++ *
15941 ++ * Copyright (C) 2002-2007 by Herbert Pötzl.
15942 ++ * Redistribution of this file is permitted under the
15943 ++ * GNU General Public License.
15944 ++ */
15945 ++
15946 ++#ifndef _LINUX_VROOT_H
15947 ++#define _LINUX_VROOT_H
15948 ++
15949 ++
15950 ++#ifdef __KERNEL__
15951 ++
15952 ++/* Possible states of device */
15953 ++enum {
15954 ++ Vr_unbound,
15955 ++ Vr_bound,
15956 ++};
15957 ++
15958 ++struct vroot_device {
15959 ++ int vr_number;
15960 ++ int vr_refcnt;
15961 ++
15962 ++ struct semaphore vr_ctl_mutex;
15963 ++ struct block_device *vr_device;
15964 ++ int vr_state;
15965 ++};
15966 ++
15967 ++
15968 ++typedef struct block_device *(vroot_grb_func)(struct block_device *);
15969 ++
15970 ++extern int register_vroot_grb(vroot_grb_func *);
15971 ++extern int unregister_vroot_grb(vroot_grb_func *);
15972 ++
15973 ++#endif /* __KERNEL__ */
15974 ++
15975 ++#define MAX_VROOT_DEFAULT 8
15976 ++
15977 ++/*
15978 ++ * IOCTL commands --- we will commandeer 0x56 ('V')
15979 ++ */
15980 ++
15981 ++#define VROOT_SET_DEV 0x5600
15982 ++#define VROOT_CLR_DEV 0x5601
15983 ++
15984 ++#endif /* _LINUX_VROOT_H */
15985 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_base.h linux-2.6.22.19-vs2.2.0.7/include/linux/vs_base.h
15986 +--- linux-2.6.22.19/include/linux/vs_base.h 1970-01-01 01:00:00 +0100
15987 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vs_base.h 2007-06-15 02:37:04 +0200
15988 +@@ -0,0 +1,9 @@
15989 ++#ifndef _VS_BASE_H
15990 ++#define _VS_BASE_H
15991 ++
15992 ++#include "vserver/base.h"
15993 ++#include "vserver/debug.h"
15994 ++
15995 ++#else
15996 ++#warning duplicate inclusion
15997 ++#endif
15998 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_context.h linux-2.6.22.19-vs2.2.0.7/include/linux/vs_context.h
15999 +--- linux-2.6.22.19/include/linux/vs_context.h 1970-01-01 01:00:00 +0100
16000 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vs_context.h 2007-06-15 02:37:04 +0200
16001 +@@ -0,0 +1,224 @@
16002 ++#ifndef _VS_CONTEXT_H
16003 ++#define _VS_CONTEXT_H
16004 ++
16005 ++#include "vserver/base.h"
16006 ++#include "vserver/context.h"
16007 ++#include "vserver/history.h"
16008 ++#include "vserver/debug.h"
16009 ++
16010 ++
16011 ++#define get_vx_info(i) __get_vx_info(i, __FILE__, __LINE__, __HERE__)
16012 ++
16013 ++static inline struct vx_info *__get_vx_info(struct vx_info *vxi,
16014 ++ const char *_file, int _line, void *_here)
16015 ++{
16016 ++ if (!vxi)
16017 ++ return NULL;
16018 ++
16019 ++ vxlprintk(VXD_CBIT(xid, 2), "get_vx_info(%p[#%d.%d])",
16020 ++ vxi, vxi ? vxi->vx_id : 0,
16021 ++ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
16022 ++ _file, _line);
16023 ++ __vxh_get_vx_info(vxi, _here);
16024 ++
16025 ++ atomic_inc(&vxi->vx_usecnt);
16026 ++ return vxi;
16027 ++}
16028 ++
16029 ++
16030 ++extern void free_vx_info(struct vx_info *);
16031 ++
16032 ++#define put_vx_info(i) __put_vx_info(i, __FILE__, __LINE__, __HERE__)
16033 ++
16034 ++static inline void __put_vx_info(struct vx_info *vxi,
16035 ++ const char *_file, int _line, void *_here)
16036 ++{
16037 ++ if (!vxi)
16038 ++ return;
16039 ++
16040 ++ vxlprintk(VXD_CBIT(xid, 2), "put_vx_info(%p[#%d.%d])",
16041 ++ vxi, vxi ? vxi->vx_id : 0,
16042 ++ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
16043 ++ _file, _line);
16044 ++ __vxh_put_vx_info(vxi, _here);
16045 ++
16046 ++ if (atomic_dec_and_test(&vxi->vx_usecnt))
16047 ++ free_vx_info(vxi);
16048 ++}
16049 ++
16050 ++
16051 ++#define init_vx_info(p, i) \
16052 ++ __init_vx_info(p, i, __FILE__, __LINE__, __HERE__)
16053 ++
16054 ++static inline void __init_vx_info(struct vx_info **vxp, struct vx_info *vxi,
16055 ++ const char *_file, int _line, void *_here)
16056 ++{
16057 ++ if (vxi) {
16058 ++ vxlprintk(VXD_CBIT(xid, 3),
16059 ++ "init_vx_info(%p[#%d.%d])",
16060 ++ vxi, vxi ? vxi->vx_id : 0,
16061 ++ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
16062 ++ _file, _line);
16063 ++ __vxh_init_vx_info(vxi, vxp, _here);
16064 ++
16065 ++ atomic_inc(&vxi->vx_usecnt);
16066 ++ }
16067 ++ *vxp = vxi;
16068 ++}
16069 ++
16070 ++
16071 ++#define set_vx_info(p, i) \
16072 ++ __set_vx_info(p, i, __FILE__, __LINE__, __HERE__)
16073 ++
16074 ++static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi,
16075 ++ const char *_file, int _line, void *_here)
16076 ++{
16077 ++ struct vx_info *vxo;
16078 ++
16079 ++ if (!vxi)
16080 ++ return;
16081 ++
16082 ++ vxlprintk(VXD_CBIT(xid, 3), "set_vx_info(%p[#%d.%d])",
16083 ++ vxi, vxi ? vxi->vx_id : 0,
16084 ++ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
16085 ++ _file, _line);
16086 ++ __vxh_set_vx_info(vxi, vxp, _here);
16087 ++
16088 ++ atomic_inc(&vxi->vx_usecnt);
16089 ++ vxo = xchg(vxp, vxi);
16090 ++ BUG_ON(vxo);
16091 ++}
16092 ++
16093 ++
16094 ++#define clr_vx_info(p) __clr_vx_info(p, __FILE__, __LINE__, __HERE__)
16095 ++
16096 ++static inline void __clr_vx_info(struct vx_info **vxp,
16097 ++ const char *_file, int _line, void *_here)
16098 ++{
16099 ++ struct vx_info *vxo;
16100 ++
16101 ++ vxo = xchg(vxp, NULL);
16102 ++ if (!vxo)
16103 ++ return;
16104 ++
16105 ++ vxlprintk(VXD_CBIT(xid, 3), "clr_vx_info(%p[#%d.%d])",
16106 ++ vxo, vxo ? vxo->vx_id : 0,
16107 ++ vxo ? atomic_read(&vxo->vx_usecnt) : 0,
16108 ++ _file, _line);
16109 ++ __vxh_clr_vx_info(vxo, vxp, _here);
16110 ++
16111 ++ if (atomic_dec_and_test(&vxo->vx_usecnt))
16112 ++ free_vx_info(vxo);
16113 ++}
16114 ++
16115 ++
16116 ++#define claim_vx_info(v, p) \
16117 ++ __claim_vx_info(v, p, __FILE__, __LINE__, __HERE__)
16118 ++
16119 ++static inline void __claim_vx_info(struct vx_info *vxi,
16120 ++ struct task_struct *task,
16121 ++ const char *_file, int _line, void *_here)
16122 ++{
16123 ++ vxlprintk(VXD_CBIT(xid, 3), "claim_vx_info(%p[#%d.%d.%d]) %p",
16124 ++ vxi, vxi ? vxi->vx_id : 0,
16125 ++ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
16126 ++ vxi ? atomic_read(&vxi->vx_tasks) : 0,
16127 ++ task, _file, _line);
16128 ++ __vxh_claim_vx_info(vxi, task, _here);
16129 ++
16130 ++ atomic_inc(&vxi->vx_tasks);
16131 ++}
16132 ++
16133 ++
16134 ++extern void unhash_vx_info(struct vx_info *);
16135 ++
16136 ++#define release_vx_info(v, p) \
16137 ++ __release_vx_info(v, p, __FILE__, __LINE__, __HERE__)
16138 ++
16139 ++static inline void __release_vx_info(struct vx_info *vxi,
16140 ++ struct task_struct *task,
16141 ++ const char *_file, int _line, void *_here)
16142 ++{
16143 ++ vxlprintk(VXD_CBIT(xid, 3), "release_vx_info(%p[#%d.%d.%d]) %p",
16144 ++ vxi, vxi ? vxi->vx_id : 0,
16145 ++ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
16146 ++ vxi ? atomic_read(&vxi->vx_tasks) : 0,
16147 ++ task, _file, _line);
16148 ++ __vxh_release_vx_info(vxi, task, _here);
16149 ++
16150 ++ might_sleep();
16151 ++
16152 ++ if (atomic_dec_and_test(&vxi->vx_tasks))
16153 ++ unhash_vx_info(vxi);
16154 ++}
16155 ++
16156 ++
16157 ++#define task_get_vx_info(p) \
16158 ++ __task_get_vx_info(p, __FILE__, __LINE__, __HERE__)
16159 ++
16160 ++static inline struct vx_info *__task_get_vx_info(struct task_struct *p,
16161 ++ const char *_file, int _line, void *_here)
16162 ++{
16163 ++ struct vx_info *vxi;
16164 ++
16165 ++ task_lock(p);
16166 ++ vxlprintk(VXD_CBIT(xid, 5), "task_get_vx_info(%p)",
16167 ++ p, _file, _line);
16168 ++ vxi = __get_vx_info(p->vx_info, _file, _line, _here);
16169 ++ task_unlock(p);
16170 ++ return vxi;
16171 ++}
16172 ++
16173 ++
16174 ++static inline void __wakeup_vx_info(struct vx_info *vxi)
16175 ++{
16176 ++ if (waitqueue_active(&vxi->vx_wait))
16177 ++ wake_up_interruptible(&vxi->vx_wait);
16178 ++}
16179 ++
16180 ++
16181 ++#define enter_vx_info(v, s) __enter_vx_info(v, s, __FILE__, __LINE__)
16182 ++
16183 ++static inline void __enter_vx_info(struct vx_info *vxi,
16184 ++ struct vx_info_save *vxis, const char *_file, int _line)
16185 ++{
16186 ++ vxlprintk(VXD_CBIT(xid, 5), "enter_vx_info(%p[#%d],%p) %p[#%d,%p]",
16187 ++ vxi, vxi ? vxi->vx_id : 0, vxis, current,
16188 ++ current->xid, current->vx_info, _file, _line);
16189 ++ vxis->vxi = xchg(&current->vx_info, vxi);
16190 ++ vxis->xid = current->xid;
16191 ++ current->xid = vxi ? vxi->vx_id : 0;
16192 ++}
16193 ++
16194 ++#define leave_vx_info(s) __leave_vx_info(s, __FILE__, __LINE__)
16195 ++
16196 ++static inline void __leave_vx_info(struct vx_info_save *vxis,
16197 ++ const char *_file, int _line)
16198 ++{
16199 ++ vxlprintk(VXD_CBIT(xid, 5), "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]",
16200 ++ vxis, vxis->xid, vxis->vxi, current,
16201 ++ current->xid, current->vx_info, _file, _line);
16202 ++ (void)xchg(&current->vx_info, vxis->vxi);
16203 ++ current->xid = vxis->xid;
16204 ++}
16205 ++
16206 ++
16207 ++static inline void __enter_vx_admin(struct vx_info_save *vxis)
16208 ++{
16209 ++ vxis->vxi = xchg(&current->vx_info, NULL);
16210 ++ vxis->xid = xchg(&current->xid, (xid_t)0);
16211 ++}
16212 ++
16213 ++static inline void __leave_vx_admin(struct vx_info_save *vxis)
16214 ++{
16215 ++ (void)xchg(&current->xid, vxis->xid);
16216 ++ (void)xchg(&current->vx_info, vxis->vxi);
16217 ++}
16218 ++
16219 ++extern void exit_vx_info(struct task_struct *, int);
16220 ++extern void exit_vx_info_early(struct task_struct *, int);
16221 ++
16222 ++
16223 ++#else
16224 ++#warning duplicate inclusion
16225 ++#endif
16226 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_cowbl.h linux-2.6.22.19-vs2.2.0.7/include/linux/vs_cowbl.h
16227 +--- linux-2.6.22.19/include/linux/vs_cowbl.h 1970-01-01 01:00:00 +0100
16228 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vs_cowbl.h 2007-06-15 02:37:04 +0200
16229 +@@ -0,0 +1,44 @@
16230 ++#ifndef _VS_COWBL_H
16231 ++#define _VS_COWBL_H
16232 ++
16233 ++#include <linux/fs.h>
16234 ++#include <linux/dcache.h>
16235 ++#include <linux/namei.h>
16236 ++
16237 ++extern struct dentry *cow_break_link(const char *pathname);
16238 ++
16239 ++static inline int cow_check_and_break(struct nameidata *nd)
16240 ++{
16241 ++ struct inode *inode = nd->dentry->d_inode;
16242 ++ int error = 0;
16243 ++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt))
16244 ++ return -EROFS;
16245 ++ if (IS_COW(inode)) {
16246 ++ if (IS_COW_LINK(inode)) {
16247 ++ struct dentry *new_dentry, *old_dentry = nd->dentry;
16248 ++ char *path, *buf;
16249 ++
16250 ++ buf = kmalloc(PATH_MAX, GFP_KERNEL);
16251 ++ if (!buf) {
16252 ++ return -ENOMEM;
16253 ++ }
16254 ++ path = d_path(nd->dentry, nd->mnt, buf, PATH_MAX);
16255 ++ new_dentry = cow_break_link(path);
16256 ++ kfree(buf);
16257 ++ if (!IS_ERR(new_dentry)) {
16258 ++ nd->dentry = new_dentry;
16259 ++ dput(old_dentry);
16260 ++ } else
16261 ++ error = PTR_ERR(new_dentry);
16262 ++ } else {
16263 ++ inode->i_flags &= ~(S_IUNLINK | S_IMMUTABLE);
16264 ++ inode->i_ctime = CURRENT_TIME;
16265 ++ mark_inode_dirty(inode);
16266 ++ }
16267 ++ }
16268 ++ return error;
16269 ++}
16270 ++
16271 ++#else
16272 ++#warning duplicate inclusion
16273 ++#endif
16274 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_cvirt.h linux-2.6.22.19-vs2.2.0.7/include/linux/vs_cvirt.h
16275 +--- linux-2.6.22.19/include/linux/vs_cvirt.h 1970-01-01 01:00:00 +0100
16276 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vs_cvirt.h 2007-06-15 02:37:04 +0200
16277 +@@ -0,0 +1,49 @@
16278 ++#ifndef _VS_CVIRT_H
16279 ++#define _VS_CVIRT_H
16280 ++
16281 ++#include "vserver/cvirt.h"
16282 ++#include "vserver/context.h"
16283 ++#include "vserver/base.h"
16284 ++#include "vserver/debug.h"
16285 ++
16286 ++
16287 ++static inline void vx_activate_task(struct task_struct *p)
16288 ++{
16289 ++ struct vx_info *vxi;
16290 ++
16291 ++ if ((vxi = p->vx_info)) {
16292 ++ vx_update_load(vxi);
16293 ++ atomic_inc(&vxi->cvirt.nr_running);
16294 ++ }
16295 ++}
16296 ++
16297 ++static inline void vx_deactivate_task(struct task_struct *p)
16298 ++{
16299 ++ struct vx_info *vxi;
16300 ++
16301 ++ if ((vxi = p->vx_info)) {
16302 ++ vx_update_load(vxi);
16303 ++ atomic_dec(&vxi->cvirt.nr_running);
16304 ++ }
16305 ++}
16306 ++
16307 ++static inline void vx_uninterruptible_inc(struct task_struct *p)
16308 ++{
16309 ++ struct vx_info *vxi;
16310 ++
16311 ++ if ((vxi = p->vx_info))
16312 ++ atomic_inc(&vxi->cvirt.nr_uninterruptible);
16313 ++}
16314 ++
16315 ++static inline void vx_uninterruptible_dec(struct task_struct *p)
16316 ++{
16317 ++ struct vx_info *vxi;
16318 ++
16319 ++ if ((vxi = p->vx_info))
16320 ++ atomic_dec(&vxi->cvirt.nr_uninterruptible);
16321 ++}
16322 ++
16323 ++
16324 ++#else
16325 ++#warning duplicate inclusion
16326 ++#endif
16327 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_dlimit.h linux-2.6.22.19-vs2.2.0.7/include/linux/vs_dlimit.h
16328 +--- linux-2.6.22.19/include/linux/vs_dlimit.h 1970-01-01 01:00:00 +0100
16329 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vs_dlimit.h 2007-06-15 02:37:04 +0200
16330 +@@ -0,0 +1,209 @@
16331 ++#ifndef _VS_DLIMIT_H
16332 ++#define _VS_DLIMIT_H
16333 ++
16334 ++#include "vserver/dlimit.h"
16335 ++#include "vserver/base.h"
16336 ++#include "vserver/debug.h"
16337 ++
16338 ++
16339 ++#define get_dl_info(i) __get_dl_info(i, __FILE__, __LINE__)
16340 ++
16341 ++static inline struct dl_info *__get_dl_info(struct dl_info *dli,
16342 ++ const char *_file, int _line)
16343 ++{
16344 ++ if (!dli)
16345 ++ return NULL;
16346 ++ vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])",
16347 ++ dli, dli ? dli->dl_tag : 0,
16348 ++ dli ? atomic_read(&dli->dl_usecnt) : 0,
16349 ++ _file, _line);
16350 ++ atomic_inc(&dli->dl_usecnt);
16351 ++ return dli;
16352 ++}
16353 ++
16354 ++
16355 ++#define free_dl_info(i) \
16356 ++ call_rcu(&(i)->dl_rcu, rcu_free_dl_info)
16357 ++
16358 ++#define put_dl_info(i) __put_dl_info(i, __FILE__, __LINE__)
16359 ++
16360 ++static inline void __put_dl_info(struct dl_info *dli,
16361 ++ const char *_file, int _line)
16362 ++{
16363 ++ if (!dli)
16364 ++ return;
16365 ++ vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])",
16366 ++ dli, dli ? dli->dl_tag : 0,
16367 ++ dli ? atomic_read(&dli->dl_usecnt) : 0,
16368 ++ _file, _line);
16369 ++ if (atomic_dec_and_test(&dli->dl_usecnt))
16370 ++ free_dl_info(dli);
16371 ++}
16372 ++
16373 ++
16374 ++#define __dlimit_char(d) ((d) ? '*' : ' ')
16375 ++
16376 ++static inline int __dl_alloc_space(struct super_block *sb,
16377 ++ tag_t tag, dlsize_t nr, const char *file, int line)
16378 ++{
16379 ++ struct dl_info *dli = NULL;
16380 ++ int ret = 0;
16381 ++
16382 ++ if (nr == 0)
16383 ++ goto out;
16384 ++ dli = locate_dl_info(sb, tag);
16385 ++ if (!dli)
16386 ++ goto out;
16387 ++
16388 ++ spin_lock(&dli->dl_lock);
16389 ++ ret = (dli->dl_space_used + nr > dli->dl_space_total);
16390 ++ if (!ret)
16391 ++ dli->dl_space_used += nr;
16392 ++ spin_unlock(&dli->dl_lock);
16393 ++ put_dl_info(dli);
16394 ++out:
16395 ++ vxlprintk(VXD_CBIT(dlim, 1),
16396 ++ "ALLOC (%p,#%d)%c %lld bytes (%d)",
16397 ++ sb, tag, __dlimit_char(dli), (long long)nr,
16398 ++ ret, file, line);
16399 ++ return ret;
16400 ++}
16401 ++
16402 ++static inline void __dl_free_space(struct super_block *sb,
16403 ++ tag_t tag, dlsize_t nr, const char *_file, int _line)
16404 ++{
16405 ++ struct dl_info *dli = NULL;
16406 ++
16407 ++ if (nr == 0)
16408 ++ goto out;
16409 ++ dli = locate_dl_info(sb, tag);
16410 ++ if (!dli)
16411 ++ goto out;
16412 ++
16413 ++ spin_lock(&dli->dl_lock);
16414 ++ if (dli->dl_space_used > nr)
16415 ++ dli->dl_space_used -= nr;
16416 ++ else
16417 ++ dli->dl_space_used = 0;
16418 ++ spin_unlock(&dli->dl_lock);
16419 ++ put_dl_info(dli);
16420 ++out:
16421 ++ vxlprintk(VXD_CBIT(dlim, 1),
16422 ++ "FREE (%p,#%d)%c %lld bytes",
16423 ++ sb, tag, __dlimit_char(dli), (long long)nr,
16424 ++ _file, _line);
16425 ++}
16426 ++
16427 ++static inline int __dl_alloc_inode(struct super_block *sb,
16428 ++ tag_t tag, const char *_file, int _line)
16429 ++{
16430 ++ struct dl_info *dli;
16431 ++ int ret = 0;
16432 ++
16433 ++ dli = locate_dl_info(sb, tag);
16434 ++ if (!dli)
16435 ++ goto out;
16436 ++
16437 ++ spin_lock(&dli->dl_lock);
16438 ++ ret = (dli->dl_inodes_used >= dli->dl_inodes_total);
16439 ++ if (!ret)
16440 ++ dli->dl_inodes_used++;
16441 ++ spin_unlock(&dli->dl_lock);
16442 ++ put_dl_info(dli);
16443 ++out:
16444 ++ vxlprintk(VXD_CBIT(dlim, 0),
16445 ++ "ALLOC (%p,#%d)%c inode (%d)",
16446 ++ sb, tag, __dlimit_char(dli), ret, _file, _line);
16447 ++ return ret;
16448 ++}
16449 ++
16450 ++static inline void __dl_free_inode(struct super_block *sb,
16451 ++ tag_t tag, const char *_file, int _line)
16452 ++{
16453 ++ struct dl_info *dli;
16454 ++
16455 ++ dli = locate_dl_info(sb, tag);
16456 ++ if (!dli)
16457 ++ goto out;
16458 ++
16459 ++ spin_lock(&dli->dl_lock);
16460 ++ if (dli->dl_inodes_used > 1)
16461 ++ dli->dl_inodes_used--;
16462 ++ else
16463 ++ dli->dl_inodes_used = 0;
16464 ++ spin_unlock(&dli->dl_lock);
16465 ++ put_dl_info(dli);
16466 ++out:
16467 ++ vxlprintk(VXD_CBIT(dlim, 0),
16468 ++ "FREE (%p,#%d)%c inode",
16469 ++ sb, tag, __dlimit_char(dli), _file, _line);
16470 ++}
16471 ++
16472 ++static inline void __dl_adjust_block(struct super_block *sb, tag_t tag,
16473 ++ unsigned long long *free_blocks, unsigned long long *root_blocks,
16474 ++ const char *_file, int _line)
16475 ++{
16476 ++ struct dl_info *dli;
16477 ++ uint64_t broot, bfree;
16478 ++
16479 ++ dli = locate_dl_info(sb, tag);
16480 ++ if (!dli)
16481 ++ return;
16482 ++
16483 ++ spin_lock(&dli->dl_lock);
16484 ++ broot = (dli->dl_space_total -
16485 ++ (dli->dl_space_total >> 10) * dli->dl_nrlmult)
16486 ++ >> sb->s_blocksize_bits;
16487 ++ bfree = (dli->dl_space_total - dli->dl_space_used)
16488 ++ >> sb->s_blocksize_bits;
16489 ++ spin_unlock(&dli->dl_lock);
16490 ++
16491 ++ vxlprintk(VXD_CBIT(dlim, 2),
16492 ++ "ADJUST: %lld,%lld on %lld,%lld [mult=%d]",
16493 ++ (long long)bfree, (long long)broot,
16494 ++ *free_blocks, *root_blocks, dli->dl_nrlmult,
16495 ++ _file, _line);
16496 ++ if (free_blocks) {
16497 ++ if (*free_blocks > bfree)
16498 ++ *free_blocks = bfree;
16499 ++ }
16500 ++ if (root_blocks) {
16501 ++ if (*root_blocks > broot)
16502 ++ *root_blocks = broot;
16503 ++ }
16504 ++ put_dl_info(dli);
16505 ++}
16506 ++
16507 ++#define DLIMIT_ALLOC_SPACE(in, bytes) \
16508 ++ __dl_alloc_space((in)->i_sb, (in)->i_tag, (dlsize_t)(bytes), \
16509 ++ __FILE__, __LINE__ )
16510 ++
16511 ++#define DLIMIT_FREE_SPACE(in, bytes) \
16512 ++ __dl_free_space((in)->i_sb, (in)->i_tag, (dlsize_t)(bytes), \
16513 ++ __FILE__, __LINE__ )
16514 ++
16515 ++#define DLIMIT_ALLOC_BLOCK(in, nr) \
16516 ++ __dl_alloc_space((in)->i_sb, (in)->i_tag, \
16517 ++ ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \
16518 ++ __FILE__, __LINE__ )
16519 ++
16520 ++#define DLIMIT_FREE_BLOCK(in, nr) \
16521 ++ __dl_free_space((in)->i_sb, (in)->i_tag, \
16522 ++ ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \
16523 ++ __FILE__, __LINE__ )
16524 ++
16525 ++
16526 ++#define DLIMIT_ALLOC_INODE(in) \
16527 ++ __dl_alloc_inode((in)->i_sb, (in)->i_tag, __FILE__, __LINE__ )
16528 ++
16529 ++#define DLIMIT_FREE_INODE(in) \
16530 ++ __dl_free_inode((in)->i_sb, (in)->i_tag, __FILE__, __LINE__ )
16531 ++
16532 ++
16533 ++#define DLIMIT_ADJUST_BLOCK(sb, tag, fb, rb) \
16534 ++ __dl_adjust_block(sb, tag, fb, rb, __FILE__, __LINE__ )
16535 ++
16536 ++
16537 ++#else
16538 ++#warning duplicate inclusion
16539 ++#endif
16540 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_limit.h linux-2.6.22.19-vs2.2.0.7/include/linux/vs_limit.h
16541 +--- linux-2.6.22.19/include/linux/vs_limit.h 1970-01-01 01:00:00 +0100
16542 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vs_limit.h 2007-06-15 02:37:04 +0200
16543 +@@ -0,0 +1,140 @@
16544 ++#ifndef _VS_LIMIT_H
16545 ++#define _VS_LIMIT_H
16546 ++
16547 ++#include "vserver/limit.h"
16548 ++#include "vserver/base.h"
16549 ++#include "vserver/context.h"
16550 ++#include "vserver/debug.h"
16551 ++#include "vserver/context.h"
16552 ++#include "vserver/limit_int.h"
16553 ++
16554 ++
16555 ++#define vx_acc_cres(v, d, p, r) \
16556 ++ __vx_acc_cres(v, r, d, p, __FILE__, __LINE__)
16557 ++
16558 ++#define vx_acc_cres_cond(x, d, p, r) \
16559 ++ __vx_acc_cres(((x) == vx_current_xid()) ? current->vx_info : 0, \
16560 ++ r, d, p, __FILE__, __LINE__)
16561 ++
16562 ++
16563 ++#define vx_add_cres(v, a, p, r) \
16564 ++ __vx_add_cres(v, r, a, p, __FILE__, __LINE__)
16565 ++#define vx_sub_cres(v, a, p, r) vx_add_cres(v, -(a), p, r)
16566 ++
16567 ++#define vx_add_cres_cond(x, a, p, r) \
16568 ++ __vx_add_cres(((x) == vx_current_xid()) ? current->vx_info : 0, \
16569 ++ r, a, p, __FILE__, __LINE__)
16570 ++#define vx_sub_cres_cond(x, a, p, r) vx_add_cres_cond(x, -(a), p, r)
16571 ++
16572 ++
16573 ++/* process and file limits */
16574 ++
16575 ++#define vx_nproc_inc(p) \
16576 ++ vx_acc_cres((p)->vx_info, 1, p, RLIMIT_NPROC)
16577 ++
16578 ++#define vx_nproc_dec(p) \
16579 ++ vx_acc_cres((p)->vx_info,-1, p, RLIMIT_NPROC)
16580 ++
16581 ++#define vx_files_inc(f) \
16582 ++ vx_acc_cres_cond((f)->f_xid, 1, f, RLIMIT_NOFILE)
16583 ++
16584 ++#define vx_files_dec(f) \
16585 ++ vx_acc_cres_cond((f)->f_xid,-1, f, RLIMIT_NOFILE)
16586 ++
16587 ++#define vx_locks_inc(l) \
16588 ++ vx_acc_cres_cond((l)->fl_xid, 1, l, RLIMIT_LOCKS)
16589 ++
16590 ++#define vx_locks_dec(l) \
16591 ++ vx_acc_cres_cond((l)->fl_xid,-1, l, RLIMIT_LOCKS)
16592 ++
16593 ++#define vx_openfd_inc(f) \
16594 ++ vx_acc_cres(current->vx_info, 1, (void *)(long)(f), VLIMIT_OPENFD)
16595 ++
16596 ++#define vx_openfd_dec(f) \
16597 ++ vx_acc_cres(current->vx_info,-1, (void *)(long)(f), VLIMIT_OPENFD)
16598 ++
16599 ++
16600 ++#define vx_cres_avail(v, n, r) \
16601 ++ __vx_cres_avail(v, r, n, __FILE__, __LINE__)
16602 ++
16603 ++
16604 ++#define vx_nproc_avail(n) \
16605 ++ vx_cres_avail(current->vx_info, n, RLIMIT_NPROC)
16606 ++
16607 ++#define vx_files_avail(n) \
16608 ++ vx_cres_avail(current->vx_info, n, RLIMIT_NOFILE)
16609 ++
16610 ++#define vx_locks_avail(n) \
16611 ++ vx_cres_avail(current->vx_info, n, RLIMIT_LOCKS)
16612 ++
16613 ++#define vx_openfd_avail(n) \
16614 ++ vx_cres_avail(current->vx_info, n, VLIMIT_OPENFD)
16615 ++
16616 ++
16617 ++/* dentry limits */
16618 ++
16619 ++#define vx_dentry_inc(d) do { \
16620 ++ if (atomic_read(&d->d_count) == 1) \
16621 ++ vx_acc_cres(current->vx_info, 1, d, VLIMIT_DENTRY); \
16622 ++ } while (0)
16623 ++
16624 ++#define vx_dentry_dec(d) do { \
16625 ++ if (atomic_read(&d->d_count) == 0) \
16626 ++ vx_acc_cres(current->vx_info,-1, d, VLIMIT_DENTRY); \
16627 ++ } while (0)
16628 ++
16629 ++#define vx_dentry_avail(n) \
16630 ++ vx_cres_avail(current->vx_info, n, VLIMIT_DENTRY)
16631 ++
16632 ++
16633 ++/* socket limits */
16634 ++
16635 ++#define vx_sock_inc(s) \
16636 ++ vx_acc_cres((s)->sk_vx_info, 1, s, VLIMIT_NSOCK)
16637 ++
16638 ++#define vx_sock_dec(s) \
16639 ++ vx_acc_cres((s)->sk_vx_info,-1, s, VLIMIT_NSOCK)
16640 ++
16641 ++#define vx_sock_avail(n) \
16642 ++ vx_cres_avail(current->vx_info, n, VLIMIT_NSOCK)
16643 ++
16644 ++
16645 ++/* ipc resource limits */
16646 ++
16647 ++#define vx_ipcmsg_add(v, u, a) \
16648 ++ vx_add_cres(v, a, u, RLIMIT_MSGQUEUE)
16649 ++
16650 ++#define vx_ipcmsg_sub(v, u, a) \
16651 ++ vx_sub_cres(v, a, u, RLIMIT_MSGQUEUE)
16652 ++
16653 ++#define vx_ipcmsg_avail(v, a) \
16654 ++ vx_cres_avail(v, a, RLIMIT_MSGQUEUE)
16655 ++
16656 ++
16657 ++#define vx_ipcshm_add(v, k, a) \
16658 ++ vx_add_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
16659 ++
16660 ++#define vx_ipcshm_sub(v, k, a) \
16661 ++ vx_sub_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
16662 ++
16663 ++#define vx_ipcshm_avail(v, a) \
16664 ++ vx_cres_avail(v, a, VLIMIT_SHMEM)
16665 ++
16666 ++
16667 ++#define vx_semary_inc(a) \
16668 ++ vx_acc_cres(current->vx_info, 1, a, VLIMIT_SEMARY)
16669 ++
16670 ++#define vx_semary_dec(a) \
16671 ++ vx_acc_cres(current->vx_info, -1, a, VLIMIT_SEMARY)
16672 ++
16673 ++
16674 ++#define vx_nsems_add(a,n) \
16675 ++ vx_add_cres(current->vx_info, n, a, VLIMIT_NSEMS)
16676 ++
16677 ++#define vx_nsems_sub(a,n) \
16678 ++ vx_sub_cres(current->vx_info, n, a, VLIMIT_NSEMS)
16679 ++
16680 ++
16681 ++#else
16682 ++#warning duplicate inclusion
16683 ++#endif
16684 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_memory.h linux-2.6.22.19-vs2.2.0.7/include/linux/vs_memory.h
16685 +--- linux-2.6.22.19/include/linux/vs_memory.h 1970-01-01 01:00:00 +0100
16686 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vs_memory.h 2007-06-15 02:37:04 +0200
16687 +@@ -0,0 +1,159 @@
16688 ++#ifndef _VS_MEMORY_H
16689 ++#define _VS_MEMORY_H
16690 ++
16691 ++#include "vserver/limit.h"
16692 ++#include "vserver/base.h"
16693 ++#include "vserver/context.h"
16694 ++#include "vserver/debug.h"
16695 ++#include "vserver/context.h"
16696 ++#include "vserver/limit_int.h"
16697 ++
16698 ++
16699 ++#define __acc_add_long(a, v) (*(v) += (a))
16700 ++#define __acc_inc_long(v) (++*(v))
16701 ++#define __acc_dec_long(v) (--*(v))
16702 ++
16703 ++#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
16704 ++#define __acc_add_atomic(a, v) atomic_long_add(a, v)
16705 ++#define __acc_inc_atomic(v) atomic_long_inc(v)
16706 ++#define __acc_dec_atomic(v) atomic_long_dec(v)
16707 ++#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
16708 ++#define __acc_add_atomic(a, v) __acc_add_long(a, v)
16709 ++#define __acc_inc_atomic(v) __acc_inc_long(v)
16710 ++#define __acc_dec_atomic(v) __acc_dec_long(v)
16711 ++#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
16712 ++
16713 ++
16714 ++#define vx_acc_page(m, d, v, r) do { \
16715 ++ if ((d) > 0) \
16716 ++ __acc_inc_long(&(m)->v); \
16717 ++ else \
16718 ++ __acc_dec_long(&(m)->v); \
16719 ++ __vx_acc_cres(m->mm_vx_info, r, d, m, __FILE__, __LINE__); \
16720 ++} while (0)
16721 ++
16722 ++#define vx_acc_page_atomic(m, d, v, r) do { \
16723 ++ if ((d) > 0) \
16724 ++ __acc_inc_atomic(&(m)->v); \
16725 ++ else \
16726 ++ __acc_dec_atomic(&(m)->v); \
16727 ++ __vx_acc_cres(m->mm_vx_info, r, d, m, __FILE__, __LINE__); \
16728 ++} while (0)
16729 ++
16730 ++
16731 ++#define vx_acc_pages(m, p, v, r) do { \
16732 ++ unsigned long __p = (p); \
16733 ++ __acc_add_long(__p, &(m)->v); \
16734 ++ __vx_add_cres(m->mm_vx_info, r, __p, m, __FILE__, __LINE__); \
16735 ++} while (0)
16736 ++
16737 ++#define vx_acc_pages_atomic(m, p, v, r) do { \
16738 ++ unsigned long __p = (p); \
16739 ++ __acc_add_atomic(__p, &(m)->v); \
16740 ++ __vx_add_cres(m->mm_vx_info, r, __p, m, __FILE__, __LINE__); \
16741 ++} while (0)
16742 ++
16743 ++
16744 ++
16745 ++#define vx_acc_vmpage(m, d) \
16746 ++ vx_acc_page(m, d, total_vm, RLIMIT_AS)
16747 ++#define vx_acc_vmlpage(m, d) \
16748 ++ vx_acc_page(m, d, locked_vm, RLIMIT_MEMLOCK)
16749 ++#define vx_acc_file_rsspage(m, d) \
16750 ++ vx_acc_page_atomic(m, d, _file_rss, VLIMIT_MAPPED)
16751 ++#define vx_acc_anon_rsspage(m, d) \
16752 ++ vx_acc_page_atomic(m, d, _anon_rss, VLIMIT_ANON)
16753 ++
16754 ++#define vx_acc_vmpages(m, p) \
16755 ++ vx_acc_pages(m, p, total_vm, RLIMIT_AS)
16756 ++#define vx_acc_vmlpages(m, p) \
16757 ++ vx_acc_pages(m, p, locked_vm, RLIMIT_MEMLOCK)
16758 ++#define vx_acc_file_rsspages(m, p) \
16759 ++ vx_acc_pages_atomic(m, p, _file_rss, VLIMIT_MAPPED)
16760 ++#define vx_acc_anon_rsspages(m, p) \
16761 ++ vx_acc_pages_atomic(m, p, _anon_rss, VLIMIT_ANON)
16762 ++
16763 ++#define vx_pages_add(s, r, p) __vx_add_cres(s, r, p, 0, __FILE__, __LINE__)
16764 ++#define vx_pages_sub(s, r, p) vx_pages_add(s, r, -(p))
16765 ++
16766 ++#define vx_vmpages_inc(m) vx_acc_vmpage(m, 1)
16767 ++#define vx_vmpages_dec(m) vx_acc_vmpage(m, -1)
16768 ++#define vx_vmpages_add(m, p) vx_acc_vmpages(m, p)
16769 ++#define vx_vmpages_sub(m, p) vx_acc_vmpages(m, -(p))
16770 ++
16771 ++#define vx_vmlocked_inc(m) vx_acc_vmlpage(m, 1)
16772 ++#define vx_vmlocked_dec(m) vx_acc_vmlpage(m, -1)
16773 ++#define vx_vmlocked_add(m, p) vx_acc_vmlpages(m, p)
16774 ++#define vx_vmlocked_sub(m, p) vx_acc_vmlpages(m, -(p))
16775 ++
16776 ++#define vx_file_rsspages_inc(m) vx_acc_file_rsspage(m, 1)
16777 ++#define vx_file_rsspages_dec(m) vx_acc_file_rsspage(m, -1)
16778 ++#define vx_file_rsspages_add(m, p) vx_acc_file_rsspages(m, p)
16779 ++#define vx_file_rsspages_sub(m, p) vx_acc_file_rsspages(m, -(p))
16780 ++
16781 ++#define vx_anon_rsspages_inc(m) vx_acc_anon_rsspage(m, 1)
16782 ++#define vx_anon_rsspages_dec(m) vx_acc_anon_rsspage(m, -1)
16783 ++#define vx_anon_rsspages_add(m, p) vx_acc_anon_rsspages(m, p)
16784 ++#define vx_anon_rsspages_sub(m, p) vx_acc_anon_rsspages(m, -(p))
16785 ++
16786 ++
16787 ++#define vx_pages_avail(m, p, r) \
16788 ++ __vx_cres_avail((m)->mm_vx_info, r, p, __FILE__, __LINE__)
16789 ++
16790 ++#define vx_vmpages_avail(m, p) vx_pages_avail(m, p, RLIMIT_AS)
16791 ++#define vx_vmlocked_avail(m, p) vx_pages_avail(m, p, RLIMIT_MEMLOCK)
16792 ++#define vx_anon_avail(m, p) vx_pages_avail(m, p, VLIMIT_ANON)
16793 ++#define vx_mapped_avail(m, p) vx_pages_avail(m, p, VLIMIT_MAPPED)
16794 ++
16795 ++#define vx_rss_avail(m, p) \
16796 ++ __vx_cres_array_avail((m)->mm_vx_info, VLA_RSS, p, __FILE__, __LINE__)
16797 ++
16798 ++
16799 ++enum {
16800 ++ VXPT_UNKNOWN = 0,
16801 ++ VXPT_ANON,
16802 ++ VXPT_NONE,
16803 ++ VXPT_FILE,
16804 ++ VXPT_SWAP,
16805 ++ VXPT_WRITE
16806 ++};
16807 ++
16808 ++#if 0
16809 ++#define vx_page_fault(mm, vma, type, ret)
16810 ++#else
16811 ++
16812 ++static inline
16813 ++void __vx_page_fault(struct mm_struct *mm,
16814 ++ struct vm_area_struct *vma, int type, int ret)
16815 ++{
16816 ++ struct vx_info *vxi = mm->mm_vx_info;
16817 ++ int what;
16818 ++/*
16819 ++ static char *page_type[6] =
16820 ++ { "UNKNOWN", "ANON", "NONE", "FILE", "SWAP", "WRITE" };
16821 ++ static char *page_what[4] =
16822 ++ { "FAULT_OOM", "FAULT_SIGBUS", "FAULT_MINOR", "FAULT_MAJOR" };
16823 ++*/
16824 ++
16825 ++ if (!vxi)
16826 ++ return;
16827 ++
16828 ++ what = (ret & 0x3);
16829 ++
16830 ++/* printk("[%d] page[%d][%d] %2x %s %s\n", vxi->vx_id,
16831 ++ type, what, ret, page_type[type], page_what[what]);
16832 ++*/
16833 ++ if (ret & VM_FAULT_WRITE)
16834 ++ what |= 0x4;
16835 ++ atomic_inc(&vxi->cacct.page[type][what]);
16836 ++}
16837 ++
16838 ++#define vx_page_fault(mm, vma, type, ret) __vx_page_fault(mm, vma, type, ret)
16839 ++#endif
16840 ++
16841 ++
16842 ++extern unsigned long vx_badness(struct task_struct *task, struct mm_struct *mm);
16843 ++
16844 ++#else
16845 ++#warning duplicate inclusion
16846 ++#endif
16847 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_network.h linux-2.6.22.19-vs2.2.0.7/include/linux/vs_network.h
16848 +--- linux-2.6.22.19/include/linux/vs_network.h 1970-01-01 01:00:00 +0100
16849 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vs_network.h 2007-06-15 02:37:04 +0200
16850 +@@ -0,0 +1,185 @@
16851 ++#ifndef _NX_VS_NETWORK_H
16852 ++#define _NX_VS_NETWORK_H
16853 ++
16854 ++#include "vserver/context.h"
16855 ++#include "vserver/network.h"
16856 ++#include "vserver/base.h"
16857 ++#include "vserver/debug.h"
16858 ++
16859 ++
16860 ++#define get_nx_info(i) __get_nx_info(i, __FILE__, __LINE__)
16861 ++
16862 ++static inline struct nx_info *__get_nx_info(struct nx_info *nxi,
16863 ++ const char *_file, int _line)
16864 ++{
16865 ++ if (!nxi)
16866 ++ return NULL;
16867 ++
16868 ++ vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])",
16869 ++ nxi, nxi ? nxi->nx_id : 0,
16870 ++ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
16871 ++ _file, _line);
16872 ++
16873 ++ atomic_inc(&nxi->nx_usecnt);
16874 ++ return nxi;
16875 ++}
16876 ++
16877 ++
16878 ++extern void free_nx_info(struct nx_info *);
16879 ++
16880 ++#define put_nx_info(i) __put_nx_info(i, __FILE__, __LINE__)
16881 ++
16882 ++static inline void __put_nx_info(struct nx_info *nxi, const char *_file, int _line)
16883 ++{
16884 ++ if (!nxi)
16885 ++ return;
16886 ++
16887 ++ vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])",
16888 ++ nxi, nxi ? nxi->nx_id : 0,
16889 ++ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
16890 ++ _file, _line);
16891 ++
16892 ++ if (atomic_dec_and_test(&nxi->nx_usecnt))
16893 ++ free_nx_info(nxi);
16894 ++}
16895 ++
16896 ++
16897 ++#define init_nx_info(p, i) __init_nx_info(p, i, __FILE__, __LINE__)
16898 ++
16899 ++static inline void __init_nx_info(struct nx_info **nxp, struct nx_info *nxi,
16900 ++ const char *_file, int _line)
16901 ++{
16902 ++ if (nxi) {
16903 ++ vxlprintk(VXD_CBIT(nid, 3),
16904 ++ "init_nx_info(%p[#%d.%d])",
16905 ++ nxi, nxi ? nxi->nx_id : 0,
16906 ++ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
16907 ++ _file, _line);
16908 ++
16909 ++ atomic_inc(&nxi->nx_usecnt);
16910 ++ }
16911 ++ *nxp = nxi;
16912 ++}
16913 ++
16914 ++
16915 ++#define set_nx_info(p, i) __set_nx_info(p, i, __FILE__, __LINE__)
16916 ++
16917 ++static inline void __set_nx_info(struct nx_info **nxp, struct nx_info *nxi,
16918 ++ const char *_file, int _line)
16919 ++{
16920 ++ struct nx_info *nxo;
16921 ++
16922 ++ if (!nxi)
16923 ++ return;
16924 ++
16925 ++ vxlprintk(VXD_CBIT(nid, 3), "set_nx_info(%p[#%d.%d])",
16926 ++ nxi, nxi ? nxi->nx_id : 0,
16927 ++ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
16928 ++ _file, _line);
16929 ++
16930 ++ atomic_inc(&nxi->nx_usecnt);
16931 ++ nxo = xchg(nxp, nxi);
16932 ++ BUG_ON(nxo);
16933 ++}
16934 ++
16935 ++#define clr_nx_info(p) __clr_nx_info(p, __FILE__, __LINE__)
16936 ++
16937 ++static inline void __clr_nx_info(struct nx_info **nxp,
16938 ++ const char *_file, int _line)
16939 ++{
16940 ++ struct nx_info *nxo;
16941 ++
16942 ++ nxo = xchg(nxp, NULL);
16943 ++ if (!nxo)
16944 ++ return;
16945 ++
16946 ++ vxlprintk(VXD_CBIT(nid, 3), "clr_nx_info(%p[#%d.%d])",
16947 ++ nxo, nxo ? nxo->nx_id : 0,
16948 ++ nxo ? atomic_read(&nxo->nx_usecnt) : 0,
16949 ++ _file, _line);
16950 ++
16951 ++ if (atomic_dec_and_test(&nxo->nx_usecnt))
16952 ++ free_nx_info(nxo);
16953 ++}
16954 ++
16955 ++
16956 ++#define claim_nx_info(v, p) __claim_nx_info(v, p, __FILE__, __LINE__)
16957 ++
16958 ++static inline void __claim_nx_info(struct nx_info *nxi,
16959 ++ struct task_struct *task, const char *_file, int _line)
16960 ++{
16961 ++ vxlprintk(VXD_CBIT(nid, 3), "claim_nx_info(%p[#%d.%d.%d]) %p",
16962 ++ nxi, nxi ? nxi->nx_id : 0,
16963 ++ nxi?atomic_read(&nxi->nx_usecnt):0,
16964 ++ nxi?atomic_read(&nxi->nx_tasks):0,
16965 ++ task, _file, _line);
16966 ++
16967 ++ atomic_inc(&nxi->nx_tasks);
16968 ++}
16969 ++
16970 ++
16971 ++extern void unhash_nx_info(struct nx_info *);
16972 ++
16973 ++#define release_nx_info(v, p) __release_nx_info(v, p, __FILE__, __LINE__)
16974 ++
16975 ++static inline void __release_nx_info(struct nx_info *nxi,
16976 ++ struct task_struct *task, const char *_file, int _line)
16977 ++{
16978 ++ vxlprintk(VXD_CBIT(nid, 3), "release_nx_info(%p[#%d.%d.%d]) %p",
16979 ++ nxi, nxi ? nxi->nx_id : 0,
16980 ++ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
16981 ++ nxi ? atomic_read(&nxi->nx_tasks) : 0,
16982 ++ task, _file, _line);
16983 ++
16984 ++ might_sleep();
16985 ++
16986 ++ if (atomic_dec_and_test(&nxi->nx_tasks))
16987 ++ unhash_nx_info(nxi);
16988 ++}
16989 ++
16990 ++
16991 ++#define task_get_nx_info(i) __task_get_nx_info(i, __FILE__, __LINE__)
16992 ++
16993 ++static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p,
16994 ++ const char *_file, int _line)
16995 ++{
16996 ++ struct nx_info *nxi;
16997 ++
16998 ++ task_lock(p);
16999 ++ vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)",
17000 ++ p, _file, _line);
17001 ++ nxi = __get_nx_info(p->nx_info, _file, _line);
17002 ++ task_unlock(p);
17003 ++ return nxi;
17004 ++}
17005 ++
17006 ++
17007 ++
17008 ++
17009 ++static inline int addr_in_nx_info(struct nx_info *nxi, uint32_t addr)
17010 ++{
17011 ++ int n, i;
17012 ++
17013 ++ if (!nxi)
17014 ++ return 1;
17015 ++
17016 ++ n = nxi->nbipv4;
17017 ++ if (n && (nxi->ipv4[0] == 0))
17018 ++ return 1;
17019 ++ for (i = 0; i < n; i++) {
17020 ++ if (nxi->ipv4[i] == addr)
17021 ++ return 1;
17022 ++ }
17023 ++ return 0;
17024 ++}
17025 ++
17026 ++static inline void exit_nx_info(struct task_struct *p)
17027 ++{
17028 ++ if (p->nx_info)
17029 ++ release_nx_info(p->nx_info, p);
17030 ++}
17031 ++
17032 ++
17033 ++#else
17034 ++#warning duplicate inclusion
17035 ++#endif
17036 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_pid.h linux-2.6.22.19-vs2.2.0.7/include/linux/vs_pid.h
17037 +--- linux-2.6.22.19/include/linux/vs_pid.h 1970-01-01 01:00:00 +0100
17038 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vs_pid.h 2008-03-14 19:55:59 +0100
17039 +@@ -0,0 +1,133 @@
17040 ++#ifndef _VS_PID_H
17041 ++#define _VS_PID_H
17042 ++
17043 ++#include "vserver/base.h"
17044 ++#include "vserver/context.h"
17045 ++#include "vserver/debug.h"
17046 ++#include <linux/pid_namespace.h>
17047 ++
17048 ++
17049 ++/* pid faking stuff */
17050 ++
17051 ++
17052 ++#define vx_info_map_pid(v, p) \
17053 ++ __vx_info_map_pid((v), (p), __FUNC__, __FILE__, __LINE__)
17054 ++#define vx_info_map_tgid(v,p) vx_info_map_pid(v,p)
17055 ++#define vx_map_pid(p) vx_info_map_pid(current->vx_info, p)
17056 ++#define vx_map_tgid(p) vx_map_pid(p)
17057 ++
17058 ++static inline int __vx_info_map_pid(struct vx_info *vxi, int pid,
17059 ++ const char *func, const char *file, int line)
17060 ++{
17061 ++ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
17062 ++ vxfprintk(VXD_CBIT(cvirt, 2),
17063 ++ "vx_map_tgid: %p/%llx: %d -> %d",
17064 ++ vxi, (long long)vxi->vx_flags, pid,
17065 ++ (pid && pid == vxi->vx_initpid) ? 1 : pid,
17066 ++ func, file, line);
17067 ++ if (pid == 0)
17068 ++ return 0;
17069 ++ if (pid == vxi->vx_initpid)
17070 ++ return 1;
17071 ++ }
17072 ++ return pid;
17073 ++}
17074 ++
17075 ++#define vx_info_rmap_pid(v, p) \
17076 ++ __vx_info_rmap_pid((v), (p), __FUNC__, __FILE__, __LINE__)
17077 ++#define vx_rmap_pid(p) vx_info_rmap_pid(current->vx_info, p)
17078 ++#define vx_rmap_tgid(p) vx_rmap_pid(p)
17079 ++
17080 ++static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid,
17081 ++ const char *func, const char *file, int line)
17082 ++{
17083 ++ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
17084 ++ vxfprintk(VXD_CBIT(cvirt, 2),
17085 ++ "vx_rmap_tgid: %p/%llx: %d -> %d",
17086 ++ vxi, (long long)vxi->vx_flags, pid,
17087 ++ (pid == 1) ? vxi->vx_initpid : pid,
17088 ++ func, file, line);
17089 ++ if ((pid == 1) && vxi->vx_initpid)
17090 ++ return vxi->vx_initpid;
17091 ++ if (pid == vxi->vx_initpid)
17092 ++ return ~0U;
17093 ++ }
17094 ++ return pid;
17095 ++}
17096 ++
17097 ++
17098 ++#define VXF_FAKE_INIT (VXF_INFO_INIT | VXF_STATE_INIT)
17099 ++
17100 ++static inline
17101 ++int vx_proc_task_visible(struct task_struct *task)
17102 ++{
17103 ++ if ((task->pid == 1) &&
17104 ++ !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT))
17105 ++ /* show a blend through init */
17106 ++ goto visible;
17107 ++ if (vx_check(vx_task_xid(task), VS_WATCH | VS_IDENT))
17108 ++ goto visible;
17109 ++ return 0;
17110 ++visible:
17111 ++ return 1;
17112 ++}
17113 ++
17114 ++static inline
17115 ++struct task_struct *vx_find_proc_task_by_pid(int pid)
17116 ++{
17117 ++ struct task_struct *task = find_task_by_pid(pid);
17118 ++
17119 ++ if (task && !vx_proc_task_visible(task)) {
17120 ++ vxdprintk(VXD_CBIT(misc, 6),
17121 ++ "dropping task (find) %p[#%u,%u] for %p[#%u,%u]",
17122 ++ task, task->xid, task->pid,
17123 ++ current, current->xid, current->pid);
17124 ++ task = NULL;
17125 ++ }
17126 ++ return task;
17127 ++}
17128 ++
17129 ++static inline
17130 ++struct task_struct *vx_get_proc_task(struct inode *inode, struct pid *pid)
17131 ++{
17132 ++ struct task_struct *task = get_pid_task(pid, PIDTYPE_PID);
17133 ++
17134 ++ if (task && !vx_proc_task_visible(task)) {
17135 ++ vxdprintk(VXD_CBIT(misc, 6),
17136 ++ "dropping task (get) %p[#%u,%u] for %p[#%u,%u]",
17137 ++ task, task->xid, task->pid,
17138 ++ current, current->xid, current->pid);
17139 ++ put_task_struct(task);
17140 ++ task = NULL;
17141 ++ }
17142 ++ return task;
17143 ++}
17144 ++
17145 ++
17146 ++static inline
17147 ++struct task_struct *vx_child_reaper(struct task_struct *p)
17148 ++{
17149 ++ struct vx_info *vxi = p->vx_info;
17150 ++ struct task_struct *reaper = child_reaper(p);
17151 ++
17152 ++ if (!vxi)
17153 ++ goto out;
17154 ++
17155 ++ BUG_ON(!p->vx_info->vx_reaper);
17156 ++
17157 ++ /* child reaper for the guest reaper */
17158 ++ if (vxi->vx_reaper == p)
17159 ++ goto out;
17160 ++
17161 ++ reaper = vxi->vx_reaper;
17162 ++out:
17163 ++ vxdprintk(VXD_CBIT(xid, 7),
17164 ++ "vx_child_reaper(%p[#%u,%u]) = %p[#%u,%u]",
17165 ++ p, p->xid, p->pid, reaper, reaper->xid, reaper->pid);
17166 ++ return reaper;
17167 ++}
17168 ++
17169 ++
17170 ++#else
17171 ++#warning duplicate inclusion
17172 ++#endif
17173 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_sched.h linux-2.6.22.19-vs2.2.0.7/include/linux/vs_sched.h
17174 +--- linux-2.6.22.19/include/linux/vs_sched.h 1970-01-01 01:00:00 +0100
17175 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vs_sched.h 2007-06-15 02:37:04 +0200
17176 +@@ -0,0 +1,110 @@
17177 ++#ifndef _VS_SCHED_H
17178 ++#define _VS_SCHED_H
17179 ++
17180 ++#include "vserver/base.h"
17181 ++#include "vserver/context.h"
17182 ++#include "vserver/sched.h"
17183 ++
17184 ++
17185 ++#define VAVAVOOM_RATIO 50
17186 ++
17187 ++#define MAX_PRIO_BIAS 20
17188 ++#define MIN_PRIO_BIAS -20
17189 ++
17190 ++
17191 ++#ifdef CONFIG_VSERVER_HARDCPU
17192 ++
17193 ++/*
17194 ++ * effective_prio - return the priority that is based on the static
17195 ++ * priority but is modified by bonuses/penalties.
17196 ++ *
17197 ++ * We scale the actual sleep average [0 .... MAX_SLEEP_AVG]
17198 ++ * into a -4 ... 0 ... +4 bonus/penalty range.
17199 ++ *
17200 ++ * Additionally, we scale another amount based on the number of
17201 ++ * CPU tokens currently held by the context, if the process is
17202 ++ * part of a context (and the appropriate SCHED flag is set).
17203 ++ * This ranges from -5 ... 0 ... +15, quadratically.
17204 ++ *
17205 ++ * So, the total bonus is -9 .. 0 .. +19
17206 ++ * We use ~50% of the full 0...39 priority range so that:
17207 ++ *
17208 ++ * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs.
17209 ++ * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks.
17210 ++ * unless that context is far exceeding its CPU allocation.
17211 ++ *
17212 ++ * Both properties are important to certain workloads.
17213 ++ */
17214 ++static inline
17215 ++int vx_effective_vavavoom(struct _vx_sched_pc *sched_pc, int max_prio)
17216 ++{
17217 ++ int vavavoom, max;
17218 ++
17219 ++ /* lots of tokens = lots of vavavoom
17220 ++ * no tokens = no vavavoom */
17221 ++ if ((vavavoom = sched_pc->tokens) >= 0) {
17222 ++ max = sched_pc->tokens_max;
17223 ++ vavavoom = max - vavavoom;
17224 ++ max = max * max;
17225 ++ vavavoom = max_prio * VAVAVOOM_RATIO / 100
17226 ++ * (vavavoom*vavavoom - (max >> 2)) / max;
17227 ++ return vavavoom;
17228 ++ }
17229 ++ return 0;
17230 ++}
17231 ++
17232 ++
17233 ++static inline
17234 ++int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
17235 ++{
17236 ++ struct vx_info *vxi = p->vx_info;
17237 ++ struct _vx_sched_pc *sched_pc;
17238 ++
17239 ++ if (!vxi)
17240 ++ return prio;
17241 ++
17242 ++ sched_pc = &vx_cpu(vxi, sched_pc);
17243 ++ if (vx_info_flags(vxi, VXF_SCHED_PRIO, 0)) {
17244 ++ int vavavoom = vx_effective_vavavoom(sched_pc, max_user);
17245 ++
17246 ++ sched_pc->vavavoom = vavavoom;
17247 ++ prio += vavavoom;
17248 ++ }
17249 ++ prio += sched_pc->prio_bias;
17250 ++ return prio;
17251 ++}
17252 ++
17253 ++#else /* !CONFIG_VSERVER_HARDCPU */
17254 ++
17255 ++static inline
17256 ++int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
17257 ++{
17258 ++ struct vx_info *vxi = p->vx_info;
17259 ++
17260 ++ if (vxi)
17261 ++ prio += vx_cpu(vxi, sched_pc).prio_bias;
17262 ++ return prio;
17263 ++}
17264 ++
17265 ++#endif /* CONFIG_VSERVER_HARDCPU */
17266 ++
17267 ++
17268 ++static inline void vx_account_user(struct vx_info *vxi,
17269 ++ cputime_t cputime, int nice)
17270 ++{
17271 ++ if (!vxi)
17272 ++ return;
17273 ++ vx_cpu(vxi, sched_pc).user_ticks += cputime;
17274 ++}
17275 ++
17276 ++static inline void vx_account_system(struct vx_info *vxi,
17277 ++ cputime_t cputime, int idle)
17278 ++{
17279 ++ if (!vxi)
17280 ++ return;
17281 ++ vx_cpu(vxi, sched_pc).sys_ticks += cputime;
17282 ++}
17283 ++
17284 ++#else
17285 ++#warning duplicate inclusion
17286 ++#endif
17287 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_socket.h linux-2.6.22.19-vs2.2.0.7/include/linux/vs_socket.h
17288 +--- linux-2.6.22.19/include/linux/vs_socket.h 1970-01-01 01:00:00 +0100
17289 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vs_socket.h 2007-06-15 02:37:04 +0200
17290 +@@ -0,0 +1,67 @@
17291 ++#ifndef _VS_SOCKET_H
17292 ++#define _VS_SOCKET_H
17293 ++
17294 ++#include "vserver/debug.h"
17295 ++#include "vserver/base.h"
17296 ++#include "vserver/cacct.h"
17297 ++#include "vserver/context.h"
17298 ++
17299 ++
17300 ++/* socket accounting */
17301 ++
17302 ++#include <linux/socket.h>
17303 ++
17304 ++static inline int vx_sock_type(int family)
17305 ++{
17306 ++ switch (family) {
17307 ++ case PF_UNSPEC:
17308 ++ return VXA_SOCK_UNSPEC;
17309 ++ case PF_UNIX:
17310 ++ return VXA_SOCK_UNIX;
17311 ++ case PF_INET:
17312 ++ return VXA_SOCK_INET;
17313 ++ case PF_INET6:
17314 ++ return VXA_SOCK_INET6;
17315 ++ case PF_PACKET:
17316 ++ return VXA_SOCK_PACKET;
17317 ++ default:
17318 ++ return VXA_SOCK_OTHER;
17319 ++ }
17320 ++}
17321 ++
17322 ++#define vx_acc_sock(v, f, p, s) \
17323 ++ __vx_acc_sock(v, f, p, s, __FILE__, __LINE__)
17324 ++
17325 ++static inline void __vx_acc_sock(struct vx_info *vxi,
17326 ++ int family, int pos, int size, char *file, int line)
17327 ++{
17328 ++ if (vxi) {
17329 ++ int type = vx_sock_type(family);
17330 ++
17331 ++ atomic_long_inc(&vxi->cacct.sock[type][pos].count);
17332 ++ atomic_long_add(size, &vxi->cacct.sock[type][pos].total);
17333 ++ }
17334 ++}
17335 ++
17336 ++#define vx_sock_recv(sk, s) \
17337 ++ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, s)
17338 ++#define vx_sock_send(sk, s) \
17339 ++ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, s)
17340 ++#define vx_sock_fail(sk, s) \
17341 ++ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, s)
17342 ++
17343 ++
17344 ++#define sock_vx_init(s) do { \
17345 ++ (s)->sk_xid = 0; \
17346 ++ (s)->sk_vx_info = NULL; \
17347 ++ } while (0)
17348 ++
17349 ++#define sock_nx_init(s) do { \
17350 ++ (s)->sk_nid = 0; \
17351 ++ (s)->sk_nx_info = NULL; \
17352 ++ } while (0)
17353 ++
17354 ++
17355 ++#else
17356 ++#warning duplicate inclusion
17357 ++#endif
17358 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_tag.h linux-2.6.22.19-vs2.2.0.7/include/linux/vs_tag.h
17359 +--- linux-2.6.22.19/include/linux/vs_tag.h 1970-01-01 01:00:00 +0100
17360 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vs_tag.h 2007-06-15 02:37:04 +0200
17361 +@@ -0,0 +1,43 @@
17362 ++#ifndef _VS_TAG_H
17363 ++#define _VS_TAG_H
17364 ++
17365 ++#include <linux/vserver/tag.h>
17366 ++
17367 ++/* check conditions */
17368 ++
17369 ++#define DX_ADMIN 0x0001
17370 ++#define DX_WATCH 0x0002
17371 ++#define DX_HOSTID 0x0008
17372 ++
17373 ++#define DX_IDENT 0x0010
17374 ++
17375 ++#define DX_ARG_MASK 0x0010
17376 ++
17377 ++
17378 ++#define dx_task_tag(t) ((t)->xid)
17379 ++
17380 ++#define dx_current_tag() dx_task_tag(current)
17381 ++
17382 ++#define dx_check(c, m) __dx_check(dx_current_tag(), c, m)
17383 ++
17384 ++#define dx_weak_check(c, m) ((m) ? dx_check(c, m) : 1)
17385 ++
17386 ++
17387 ++/*
17388 ++ * check current context for ADMIN/WATCH and
17389 ++ * optionally against supplied argument
17390 ++ */
17391 ++static inline int __dx_check(tag_t cid, tag_t id, unsigned int mode)
17392 ++{
17393 ++ if (mode & DX_ARG_MASK) {
17394 ++ if ((mode & DX_IDENT) && (id == cid))
17395 ++ return 1;
17396 ++ }
17397 ++ return (((mode & DX_ADMIN) && (cid == 0)) ||
17398 ++ ((mode & DX_WATCH) && (cid == 1)) ||
17399 ++ ((mode & DX_HOSTID) && (id == 0)));
17400 ++}
17401 ++
17402 ++#else
17403 ++#warning duplicate inclusion
17404 ++#endif
17405 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_time.h linux-2.6.22.19-vs2.2.0.7/include/linux/vs_time.h
17406 +--- linux-2.6.22.19/include/linux/vs_time.h 1970-01-01 01:00:00 +0100
17407 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vs_time.h 2007-06-15 02:37:04 +0200
17408 +@@ -0,0 +1,19 @@
17409 ++#ifndef _VS_TIME_H
17410 ++#define _VS_TIME_H
17411 ++
17412 ++
17413 ++/* time faking stuff */
17414 ++
17415 ++#ifdef CONFIG_VSERVER_VTIME
17416 ++
17417 ++extern void vx_gettimeofday(struct timeval *tv);
17418 ++extern int vx_settimeofday(struct timespec *ts);
17419 ++
17420 ++#else
17421 ++#define vx_gettimeofday(t) do_gettimeofday(t)
17422 ++#define vx_settimeofday(t) do_settimeofday(t)
17423 ++#endif
17424 ++
17425 ++#else
17426 ++#warning duplicate inclusion
17427 ++#endif
17428 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/Kbuild linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/Kbuild
17429 +--- linux-2.6.22.19/include/linux/vserver/Kbuild 1970-01-01 01:00:00 +0100
17430 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/Kbuild 2007-06-16 19:48:30 +0200
17431 +@@ -0,0 +1,9 @@
17432 ++
17433 ++unifdef-y += context_cmd.h network_cmd.h space_cmd.h \
17434 ++ cacct_cmd.h cvirt_cmd.h limit_cmd.h dlimit_cmd.h \
17435 ++ inode_cmd.h sched_cmd.h signal_cmd.h debug_cmd.h
17436 ++
17437 ++unifdef-y += switch.h network.h monitor.h inode.h
17438 ++
17439 ++unifdef-y += legacy.h
17440 ++
17441 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/base.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/base.h
17442 +--- linux-2.6.22.19/include/linux/vserver/base.h 1970-01-01 01:00:00 +0100
17443 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/base.h 2007-06-15 02:37:04 +0200
17444 +@@ -0,0 +1,236 @@
17445 ++#ifndef _VX_BASE_H
17446 ++#define _VX_BASE_H
17447 ++
17448 ++
17449 ++/* context state changes */
17450 ++
17451 ++enum {
17452 ++ VSC_STARTUP = 1,
17453 ++ VSC_SHUTDOWN,
17454 ++
17455 ++ VSC_NETUP,
17456 ++ VSC_NETDOWN,
17457 ++};
17458 ++
17459 ++
17460 ++#define MAX_S_CONTEXT 65535 /* Arbitrary limit */
17461 ++
17462 ++#ifdef CONFIG_VSERVER_DYNAMIC_IDS
17463 ++#define MIN_D_CONTEXT 49152 /* dynamic contexts start here */
17464 ++#else
17465 ++#define MIN_D_CONTEXT 65536
17466 ++#endif
17467 ++
17468 ++/* check conditions */
17469 ++
17470 ++#define VS_ADMIN 0x0001
17471 ++#define VS_WATCH 0x0002
17472 ++#define VS_HIDE 0x0004
17473 ++#define VS_HOSTID 0x0008
17474 ++
17475 ++#define VS_IDENT 0x0010
17476 ++#define VS_EQUIV 0x0020
17477 ++#define VS_PARENT 0x0040
17478 ++#define VS_CHILD 0x0080
17479 ++
17480 ++#define VS_ARG_MASK 0x00F0
17481 ++
17482 ++#define VS_DYNAMIC 0x0100
17483 ++#define VS_STATIC 0x0200
17484 ++
17485 ++#define VS_ATR_MASK 0x0F00
17486 ++
17487 ++#ifdef CONFIG_VSERVER_PRIVACY
17488 ++#define VS_ADMIN_P (0)
17489 ++#define VS_WATCH_P (0)
17490 ++#else
17491 ++#define VS_ADMIN_P VS_ADMIN
17492 ++#define VS_WATCH_P VS_WATCH
17493 ++#endif
17494 ++
17495 ++#define VS_HARDIRQ 0x1000
17496 ++#define VS_SOFTIRQ 0x2000
17497 ++#define VS_IRQ 0x4000
17498 ++
17499 ++#define VS_IRQ_MASK 0xF000
17500 ++
17501 ++#include <linux/hardirq.h>
17502 ++
17503 ++/*
17504 ++ * check current context for ADMIN/WATCH and
17505 ++ * optionally against supplied argument
17506 ++ */
17507 ++static inline int __vs_check(int cid, int id, unsigned int mode)
17508 ++{
17509 ++ if (mode & VS_ARG_MASK) {
17510 ++ if ((mode & VS_IDENT) && (id == cid))
17511 ++ return 1;
17512 ++ }
17513 ++ if (mode & VS_ATR_MASK) {
17514 ++ if ((mode & VS_DYNAMIC) &&
17515 ++ (id >= MIN_D_CONTEXT) &&
17516 ++ (id <= MAX_S_CONTEXT))
17517 ++ return 1;
17518 ++ if ((mode & VS_STATIC) &&
17519 ++ (id > 1) && (id < MIN_D_CONTEXT))
17520 ++ return 1;
17521 ++ }
17522 ++ if (mode & VS_IRQ_MASK) {
17523 ++ if ((mode & VS_IRQ) && unlikely(in_interrupt()))
17524 ++ return 1;
17525 ++ if ((mode & VS_HARDIRQ) && unlikely(in_irq()))
17526 ++ return 1;
17527 ++ if ((mode & VS_SOFTIRQ) && unlikely(in_softirq()))
17528 ++ return 1;
17529 ++ }
17530 ++ return (((mode & VS_ADMIN) && (cid == 0)) ||
17531 ++ ((mode & VS_WATCH) && (cid == 1)) ||
17532 ++ ((mode & VS_HOSTID) && (id == 0)));
17533 ++}
17534 ++
17535 ++#define vx_task_xid(t) ((t)->xid)
17536 ++
17537 ++#define vx_current_xid() vx_task_xid(current)
17538 ++
17539 ++#define current_vx_info() (current->vx_info)
17540 ++
17541 ++
17542 ++#define vx_check(c, m) __vs_check(vx_current_xid(), c, (m) | VS_IRQ)
17543 ++
17544 ++#define vx_weak_check(c, m) ((m) ? vx_check(c, m) : 1)
17545 ++
17546 ++
17547 ++#define nx_task_nid(t) ((t)->nid)
17548 ++
17549 ++#define nx_current_nid() nx_task_nid(current)
17550 ++
17551 ++#define current_nx_info() (current->nx_info)
17552 ++
17553 ++
17554 ++#define nx_check(c, m) __vs_check(nx_current_nid(), c, m)
17555 ++
17556 ++#define nx_weak_check(c, m) ((m) ? nx_check(c, m) : 1)
17557 ++
17558 ++
17559 ++
17560 ++/* generic flag merging */
17561 ++
17562 ++#define vs_check_flags(v, m, f) (((v) & (m)) ^ (f))
17563 ++
17564 ++#define vs_mask_flags(v, f, m) (((v) & ~(m)) | ((f) & (m)))
17565 ++
17566 ++#define vs_mask_mask(v, f, m) (((v) & ~(m)) | ((v) & (f) & (m)))
17567 ++
17568 ++#define vs_check_bit(v, n) ((v) & (1LL << (n)))
17569 ++
17570 ++
17571 ++/* context flags */
17572 ++
17573 ++#define __vx_flags(v) ((v) ? (v)->vx_flags : 0)
17574 ++
17575 ++#define vx_current_flags() __vx_flags(current->vx_info)
17576 ++
17577 ++#define vx_info_flags(v, m, f) \
17578 ++ vs_check_flags(__vx_flags(v), m, f)
17579 ++
17580 ++#define task_vx_flags(t, m, f) \
17581 ++ ((t) && vx_info_flags((t)->vx_info, m, f))
17582 ++
17583 ++#define vx_flags(m, f) vx_info_flags(current->vx_info, m, f)
17584 ++
17585 ++
17586 ++/* context caps */
17587 ++
17588 ++#define __vx_ccaps(v) ((v) ? (v)->vx_ccaps : 0)
17589 ++
17590 ++#define vx_current_ccaps() __vx_ccaps(current->vx_info)
17591 ++
17592 ++#define vx_info_ccaps(v, c) (__vx_ccaps(v) & (c))
17593 ++
17594 ++#define vx_ccaps(c) vx_info_ccaps(current->vx_info, (c))
17595 ++
17596 ++
17597 ++
17598 ++/* network flags */
17599 ++
17600 ++#define __nx_flags(v) ((v) ? (v)->nx_flags : 0)
17601 ++
17602 ++#define nx_current_flags() __nx_flags(current->nx_info)
17603 ++
17604 ++#define nx_info_flags(v, m, f) \
17605 ++ vs_check_flags(__nx_flags(v), m, f)
17606 ++
17607 ++#define task_nx_flags(t, m, f) \
17608 ++ ((t) && nx_info_flags((t)->nx_info, m, f))
17609 ++
17610 ++#define nx_flags(m, f) nx_info_flags(current->nx_info, m, f)
17611 ++
17612 ++
17613 ++/* network caps */
17614 ++
17615 ++#define __nx_ncaps(v) ((v) ? (v)->nx_ncaps : 0)
17616 ++
17617 ++#define nx_current_ncaps() __nx_ncaps(current->nx_info)
17618 ++
17619 ++#define nx_info_ncaps(v, c) (__nx_ncaps(v) & (c))
17620 ++
17621 ++#define nx_ncaps(c) nx_info_ncaps(current->nx_info, c)
17622 ++
17623 ++
17624 ++/* context mask capabilities */
17625 ++
17626 ++#define __vx_mcaps(v) ((v) ? (v)->vx_ccaps >> 32UL : ~0 )
17627 ++
17628 ++#define vx_info_mcaps(v, c) (__vx_mcaps(v) & (c))
17629 ++
17630 ++#define vx_mcaps(c) vx_info_mcaps(current->vx_info, c)
17631 ++
17632 ++
17633 ++/* context bcap mask */
17634 ++
17635 ++#define __vx_bcaps(v) ((v) ? (v)->vx_bcaps : ~0 )
17636 ++
17637 ++#define vx_current_bcaps() __vx_bcaps(current->vx_info)
17638 ++
17639 ++#define vx_info_bcaps(v, c) (__vx_bcaps(v) & (c))
17640 ++
17641 ++#define vx_bcaps(c) vx_info_bcaps(current->vx_info, c)
17642 ++
17643 ++
17644 ++#define vx_info_cap_bset(v) ((v) ? (v)->vx_cap_bset : cap_bset)
17645 ++
17646 ++#define vx_current_cap_bset() vx_info_cap_bset(current->vx_info)
17647 ++
17648 ++
17649 ++#define __vx_info_mbcap(v, b) \
17650 ++ (!vx_info_flags(v, VXF_STATE_SETUP, 0) ? \
17651 ++ vx_info_bcaps(v, b) : (b))
17652 ++
17653 ++#define vx_info_mbcap(v, b) __vx_info_mbcap(v, cap_t(b))
17654 ++
17655 ++#define task_vx_mbcap(t, b) \
17656 ++ vx_info_mbcap((t)->vx_info, (t)->b)
17657 ++
17658 ++#define vx_mbcap(b) task_vx_mbcap(current, b)
17659 ++
17660 ++#define vx_cap_raised(v, c, f) (vx_info_mbcap(v, c) & CAP_TO_MASK(f))
17661 ++
17662 ++#define vx_capable(b, c) (capable(b) || \
17663 ++ (cap_raised(current->cap_effective, b) && vx_ccaps(c)))
17664 ++
17665 ++
17666 ++#define vx_current_initpid(n) \
17667 ++ (current->vx_info && \
17668 ++ (current->vx_info->vx_initpid == (n)))
17669 ++
17670 ++
17671 ++#define __vx_state(v) ((v) ? ((v)->vx_state) : 0)
17672 ++
17673 ++#define vx_info_state(v, m) (__vx_state(v) & (m))
17674 ++
17675 ++
17676 ++#define __nx_state(v) ((v) ? ((v)->nx_state) : 0)
17677 ++
17678 ++#define nx_info_state(v, m) (__nx_state(v) & (m))
17679 ++
17680 ++#endif
17681 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/cacct.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/cacct.h
17682 +--- linux-2.6.22.19/include/linux/vserver/cacct.h 1970-01-01 01:00:00 +0100
17683 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/cacct.h 2007-06-15 02:37:04 +0200
17684 +@@ -0,0 +1,15 @@
17685 ++#ifndef _VX_CACCT_H
17686 ++#define _VX_CACCT_H
17687 ++
17688 ++
17689 ++enum sock_acc_field {
17690 ++ VXA_SOCK_UNSPEC = 0,
17691 ++ VXA_SOCK_UNIX,
17692 ++ VXA_SOCK_INET,
17693 ++ VXA_SOCK_INET6,
17694 ++ VXA_SOCK_PACKET,
17695 ++ VXA_SOCK_OTHER,
17696 ++ VXA_SOCK_SIZE /* array size */
17697 ++};
17698 ++
17699 ++#endif /* _VX_CACCT_H */
17700 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/cacct_cmd.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/cacct_cmd.h
17701 +--- linux-2.6.22.19/include/linux/vserver/cacct_cmd.h 1970-01-01 01:00:00 +0100
17702 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/cacct_cmd.h 2007-06-15 02:37:04 +0200
17703 +@@ -0,0 +1,23 @@
17704 ++#ifndef _VX_CACCT_CMD_H
17705 ++#define _VX_CACCT_CMD_H
17706 ++
17707 ++
17708 ++/* virtual host info name commands */
17709 ++
17710 ++#define VCMD_sock_stat VC_CMD(VSTAT, 5, 0)
17711 ++
17712 ++struct vcmd_sock_stat_v0 {
17713 ++ uint32_t field;
17714 ++ uint32_t count[3];
17715 ++ uint64_t total[3];
17716 ++};
17717 ++
17718 ++
17719 ++#ifdef __KERNEL__
17720 ++
17721 ++#include <linux/compiler.h>
17722 ++
17723 ++extern int vc_sock_stat(struct vx_info *, void __user *);
17724 ++
17725 ++#endif /* __KERNEL__ */
17726 ++#endif /* _VX_CACCT_CMD_H */
17727 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/cacct_def.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/cacct_def.h
17728 +--- linux-2.6.22.19/include/linux/vserver/cacct_def.h 1970-01-01 01:00:00 +0100
17729 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/cacct_def.h 2007-06-15 02:37:04 +0200
17730 +@@ -0,0 +1,43 @@
17731 ++#ifndef _VX_CACCT_DEF_H
17732 ++#define _VX_CACCT_DEF_H
17733 ++
17734 ++#include <asm/atomic.h>
17735 ++#include <linux/vserver/cacct.h>
17736 ++
17737 ++
17738 ++struct _vx_sock_acc {
17739 ++ atomic_long_t count;
17740 ++ atomic_long_t total;
17741 ++};
17742 ++
17743 ++/* context sub struct */
17744 ++
17745 ++struct _vx_cacct {
17746 ++ struct _vx_sock_acc sock[VXA_SOCK_SIZE][3];
17747 ++ atomic_t slab[8];
17748 ++ atomic_t page[6][8];
17749 ++};
17750 ++
17751 ++#ifdef CONFIG_VSERVER_DEBUG
17752 ++
17753 ++static inline void __dump_vx_cacct(struct _vx_cacct *cacct)
17754 ++{
17755 ++ int i, j;
17756 ++
17757 ++ printk("\t_vx_cacct:");
17758 ++ for (i = 0; i < 6; i++) {
17759 ++ struct _vx_sock_acc *ptr = cacct->sock[i];
17760 ++
17761 ++ printk("\t [%d] =", i);
17762 ++ for (j = 0; j < 3; j++) {
17763 ++ printk(" [%d] = %8lu, %8lu", j,
17764 ++ atomic_long_read(&ptr[j].count),
17765 ++ atomic_long_read(&ptr[j].total));
17766 ++ }
17767 ++ printk("\n");
17768 ++ }
17769 ++}
17770 ++
17771 ++#endif
17772 ++
17773 ++#endif /* _VX_CACCT_DEF_H */
17774 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/cacct_int.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/cacct_int.h
17775 +--- linux-2.6.22.19/include/linux/vserver/cacct_int.h 1970-01-01 01:00:00 +0100
17776 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/cacct_int.h 2007-06-15 02:37:04 +0200
17777 +@@ -0,0 +1,21 @@
17778 ++#ifndef _VX_CACCT_INT_H
17779 ++#define _VX_CACCT_INT_H
17780 ++
17781 ++
17782 ++#ifdef __KERNEL__
17783 ++
17784 ++static inline
17785 ++unsigned long vx_sock_count(struct _vx_cacct *cacct, int type, int pos)
17786 ++{
17787 ++ return atomic_long_read(&cacct->sock[type][pos].count);
17788 ++}
17789 ++
17790 ++
17791 ++static inline
17792 ++unsigned long vx_sock_total(struct _vx_cacct *cacct, int type, int pos)
17793 ++{
17794 ++ return atomic_long_read(&cacct->sock[type][pos].total);
17795 ++}
17796 ++
17797 ++#endif /* __KERNEL__ */
17798 ++#endif /* _VX_CACCT_INT_H */
17799 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/context.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/context.h
17800 +--- linux-2.6.22.19/include/linux/vserver/context.h 1970-01-01 01:00:00 +0100
17801 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/context.h 2007-06-15 02:37:04 +0200
17802 +@@ -0,0 +1,172 @@
17803 ++#ifndef _VX_CONTEXT_H
17804 ++#define _VX_CONTEXT_H
17805 ++
17806 ++#include <linux/types.h>
17807 ++#include <linux/capability.h>
17808 ++
17809 ++
17810 ++#define VX_DYNAMIC_ID ((uint32_t)-1) /* id for dynamic context */
17811 ++
17812 ++/* context flags */
17813 ++
17814 ++#define VXF_INFO_SCHED 0x00000002
17815 ++#define VXF_INFO_NPROC 0x00000004
17816 ++#define VXF_INFO_PRIVATE 0x00000008
17817 ++
17818 ++#define VXF_INFO_INIT 0x00000010
17819 ++#define VXF_INFO_HIDE 0x00000020
17820 ++#define VXF_INFO_ULIMIT 0x00000040
17821 ++#define VXF_INFO_NSPACE 0x00000080
17822 ++
17823 ++#define VXF_SCHED_HARD 0x00000100
17824 ++#define VXF_SCHED_PRIO 0x00000200
17825 ++#define VXF_SCHED_PAUSE 0x00000400
17826 ++
17827 ++#define VXF_VIRT_MEM 0x00010000
17828 ++#define VXF_VIRT_UPTIME 0x00020000
17829 ++#define VXF_VIRT_CPU 0x00040000
17830 ++#define VXF_VIRT_LOAD 0x00080000
17831 ++#define VXF_VIRT_TIME 0x00100000
17832 ++
17833 ++#define VXF_HIDE_MOUNT 0x01000000
17834 ++#define VXF_HIDE_NETIF 0x02000000
17835 ++#define VXF_HIDE_VINFO 0x04000000
17836 ++
17837 ++#define VXF_STATE_SETUP (1ULL << 32)
17838 ++#define VXF_STATE_INIT (1ULL << 33)
17839 ++#define VXF_STATE_ADMIN (1ULL << 34)
17840 ++
17841 ++#define VXF_SC_HELPER (1ULL << 36)
17842 ++#define VXF_REBOOT_KILL (1ULL << 37)
17843 ++#define VXF_PERSISTENT (1ULL << 38)
17844 ++
17845 ++#define VXF_FORK_RSS (1ULL << 48)
17846 ++#define VXF_PROLIFIC (1ULL << 49)
17847 ++
17848 ++#define VXF_IGNEG_NICE (1ULL << 52)
17849 ++
17850 ++#define VXF_ONE_TIME (0x0007ULL << 32)
17851 ++
17852 ++#define VXF_INIT_SET (VXF_STATE_SETUP | VXF_STATE_INIT | VXF_STATE_ADMIN)
17853 ++
17854 ++
17855 ++/* context migration */
17856 ++
17857 ++#define VXM_SET_INIT 0x00000001
17858 ++#define VXM_SET_REAPER 0x00000002
17859 ++
17860 ++/* context caps */
17861 ++
17862 ++#define VXC_CAP_MASK 0x00000000
17863 ++
17864 ++#define VXC_SET_UTSNAME 0x00000001
17865 ++#define VXC_SET_RLIMIT 0x00000002
17866 ++
17867 ++#define VXC_RAW_ICMP 0x00000100
17868 ++#define VXC_SYSLOG 0x00001000
17869 ++
17870 ++#define VXC_SECURE_MOUNT 0x00010000
17871 ++#define VXC_SECURE_REMOUNT 0x00020000
17872 ++#define VXC_BINARY_MOUNT 0x00040000
17873 ++
17874 ++#define VXC_QUOTA_CTL 0x00100000
17875 ++#define VXC_ADMIN_MAPPER 0x00200000
17876 ++#define VXC_ADMIN_CLOOP 0x00400000
17877 ++
17878 ++
17879 ++#ifdef __KERNEL__
17880 ++
17881 ++#include <linux/list.h>
17882 ++#include <linux/spinlock.h>
17883 ++#include <linux/rcupdate.h>
17884 ++
17885 ++#include "limit_def.h"
17886 ++#include "sched_def.h"
17887 ++#include "cvirt_def.h"
17888 ++#include "cacct_def.h"
17889 ++
17890 ++struct _vx_info_pc {
17891 ++ struct _vx_sched_pc sched_pc;
17892 ++ struct _vx_cvirt_pc cvirt_pc;
17893 ++};
17894 ++
17895 ++struct vx_info {
17896 ++ struct hlist_node vx_hlist; /* linked list of contexts */
17897 ++ xid_t vx_id; /* context id */
17898 ++ atomic_t vx_usecnt; /* usage count */
17899 ++ atomic_t vx_tasks; /* tasks count */
17900 ++ struct vx_info *vx_parent; /* parent context */
17901 ++ int vx_state; /* context state */
17902 ++
17903 ++ unsigned long vx_nsmask; /* assignment mask */
17904 ++ struct nsproxy *vx_nsproxy; /* private namespace */
17905 ++ struct fs_struct *vx_fs; /* private namespace fs */
17906 ++
17907 ++ uint64_t vx_flags; /* context flags */
17908 ++ uint64_t vx_bcaps; /* bounding caps (system) */
17909 ++ uint64_t vx_ccaps; /* context caps (vserver) */
17910 ++ kernel_cap_t vx_cap_bset; /* the guest's bset */
17911 ++
17912 ++ struct task_struct *vx_reaper; /* guest reaper process */
17913 ++ pid_t vx_initpid; /* PID of guest init */
17914 ++
17915 ++ struct _vx_limit limit; /* vserver limits */
17916 ++ struct _vx_sched sched; /* vserver scheduler */
17917 ++ struct _vx_cvirt cvirt; /* virtual/bias stuff */
17918 ++ struct _vx_cacct cacct; /* context accounting */
17919 ++
17920 ++#ifndef CONFIG_SMP
17921 ++ struct _vx_info_pc info_pc; /* per cpu data */
17922 ++#else
17923 ++ struct _vx_info_pc *ptr_pc; /* per cpu array */
17924 ++#endif
17925 ++
17926 ++ wait_queue_head_t vx_wait; /* context exit waitqueue */
17927 ++ int reboot_cmd; /* last sys_reboot() cmd */
17928 ++ int exit_code; /* last process exit code */
17929 ++
17930 ++ char vx_name[65]; /* vserver name */
17931 ++};
17932 ++
17933 ++#ifndef CONFIG_SMP
17934 ++#define vx_ptr_pc(vxi) (&(vxi)->info_pc)
17935 ++#define vx_per_cpu(vxi, v, id) vx_ptr_pc(vxi)->v
17936 ++#else
17937 ++#define vx_ptr_pc(vxi) ((vxi)->ptr_pc)
17938 ++#define vx_per_cpu(vxi, v, id) per_cpu_ptr(vx_ptr_pc(vxi), id)->v
17939 ++#endif
17940 ++
17941 ++#define vx_cpu(vxi, v) vx_per_cpu(vxi, v, smp_processor_id())
17942 ++
17943 ++
17944 ++struct vx_info_save {
17945 ++ struct vx_info *vxi;
17946 ++ xid_t xid;
17947 ++};
17948 ++
17949 ++
17950 ++/* status flags */
17951 ++
17952 ++#define VXS_HASHED 0x0001
17953 ++#define VXS_PAUSED 0x0010
17954 ++#define VXS_SHUTDOWN 0x0100
17955 ++#define VXS_HELPER 0x1000
17956 ++#define VXS_RELEASED 0x8000
17957 ++
17958 ++
17959 ++extern void claim_vx_info(struct vx_info *, struct task_struct *);
17960 ++extern void release_vx_info(struct vx_info *, struct task_struct *);
17961 ++
17962 ++extern struct vx_info *lookup_vx_info(int);
17963 ++extern struct vx_info *lookup_or_create_vx_info(int);
17964 ++
17965 ++extern int get_xid_list(int, unsigned int *, int);
17966 ++extern int xid_is_hashed(xid_t);
17967 ++
17968 ++extern int vx_migrate_task(struct task_struct *, struct vx_info *, int);
17969 ++
17970 ++extern long vs_state_change(struct vx_info *, unsigned int);
17971 ++
17972 ++
17973 ++#endif /* __KERNEL__ */
17974 ++#endif /* _VX_CONTEXT_H */
17975 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/context_cmd.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/context_cmd.h
17976 +--- linux-2.6.22.19/include/linux/vserver/context_cmd.h 1970-01-01 01:00:00 +0100
17977 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/context_cmd.h 2007-06-15 02:37:04 +0200
17978 +@@ -0,0 +1,123 @@
17979 ++#ifndef _VX_CONTEXT_CMD_H
17980 ++#define _VX_CONTEXT_CMD_H
17981 ++
17982 ++
17983 ++/* vinfo commands */
17984 ++
17985 ++#define VCMD_task_xid VC_CMD(VINFO, 1, 0)
17986 ++
17987 ++#ifdef __KERNEL__
17988 ++extern int vc_task_xid(uint32_t, void __user *);
17989 ++
17990 ++#endif /* __KERNEL__ */
17991 ++
17992 ++#define VCMD_vx_info VC_CMD(VINFO, 5, 0)
17993 ++
17994 ++struct vcmd_vx_info_v0 {
17995 ++ uint32_t xid;
17996 ++ uint32_t initpid;
17997 ++ /* more to come */
17998 ++};
17999 ++
18000 ++#ifdef __KERNEL__
18001 ++extern int vc_vx_info(struct vx_info *, void __user *);
18002 ++
18003 ++#endif /* __KERNEL__ */
18004 ++
18005 ++#define VCMD_ctx_stat VC_CMD(VSTAT, 0, 0)
18006 ++
18007 ++struct vcmd_ctx_stat_v0 {
18008 ++ uint32_t usecnt;
18009 ++ uint32_t tasks;
18010 ++ /* more to come */
18011 ++};
18012 ++
18013 ++#ifdef __KERNEL__
18014 ++extern int vc_ctx_stat(struct vx_info *, void __user *);
18015 ++
18016 ++#endif /* __KERNEL__ */
18017 ++
18018 ++/* context commands */
18019 ++
18020 ++#define VCMD_ctx_create_v0 VC_CMD(VPROC, 1, 0)
18021 ++#define VCMD_ctx_create VC_CMD(VPROC, 1, 1)
18022 ++
18023 ++struct vcmd_ctx_create {
18024 ++ uint64_t flagword;
18025 ++};
18026 ++
18027 ++#define VCMD_ctx_migrate_v0 VC_CMD(PROCMIG, 1, 0)
18028 ++#define VCMD_ctx_migrate VC_CMD(PROCMIG, 1, 1)
18029 ++
18030 ++struct vcmd_ctx_migrate {
18031 ++ uint64_t flagword;
18032 ++};
18033 ++
18034 ++#ifdef __KERNEL__
18035 ++extern int vc_ctx_create(uint32_t, void __user *);
18036 ++extern int vc_ctx_migrate(struct vx_info *, void __user *);
18037 ++
18038 ++#endif /* __KERNEL__ */
18039 ++
18040 ++
18041 ++/* flag commands */
18042 ++
18043 ++#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0)
18044 ++#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0)
18045 ++
18046 ++struct vcmd_ctx_flags_v0 {
18047 ++ uint64_t flagword;
18048 ++ uint64_t mask;
18049 ++};
18050 ++
18051 ++#ifdef __KERNEL__
18052 ++extern int vc_get_cflags(struct vx_info *, void __user *);
18053 ++extern int vc_set_cflags(struct vx_info *, void __user *);
18054 ++
18055 ++#endif /* __KERNEL__ */
18056 ++
18057 ++
18058 ++/* context caps commands */
18059 ++
18060 ++#define VCMD_get_ccaps_v0 VC_CMD(FLAGS, 3, 0)
18061 ++#define VCMD_set_ccaps_v0 VC_CMD(FLAGS, 4, 0)
18062 ++
18063 ++struct vcmd_ctx_caps_v0 {
18064 ++ uint64_t bcaps;
18065 ++ uint64_t ccaps;
18066 ++ uint64_t cmask;
18067 ++};
18068 ++
18069 ++#define VCMD_get_ccaps VC_CMD(FLAGS, 3, 1)
18070 ++#define VCMD_set_ccaps VC_CMD(FLAGS, 4, 1)
18071 ++
18072 ++struct vcmd_ctx_caps_v1 {
18073 ++ uint64_t ccaps;
18074 ++ uint64_t cmask;
18075 ++};
18076 ++
18077 ++#ifdef __KERNEL__
18078 ++extern int vc_get_ccaps_v0(struct vx_info *, void __user *);
18079 ++extern int vc_set_ccaps_v0(struct vx_info *, void __user *);
18080 ++extern int vc_get_ccaps(struct vx_info *, void __user *);
18081 ++extern int vc_set_ccaps(struct vx_info *, void __user *);
18082 ++
18083 ++#endif /* __KERNEL__ */
18084 ++
18085 ++
18086 ++/* bcaps commands */
18087 ++
18088 ++#define VCMD_get_bcaps VC_CMD(FLAGS, 9, 0)
18089 ++#define VCMD_set_bcaps VC_CMD(FLAGS, 10, 0)
18090 ++
18091 ++struct vcmd_bcaps {
18092 ++ uint64_t bcaps;
18093 ++ uint64_t bmask;
18094 ++};
18095 ++
18096 ++#ifdef __KERNEL__
18097 ++extern int vc_get_bcaps(struct vx_info *, void __user *);
18098 ++extern int vc_set_bcaps(struct vx_info *, void __user *);
18099 ++
18100 ++#endif /* __KERNEL__ */
18101 ++#endif /* _VX_CONTEXT_CMD_H */
18102 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/cvirt.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/cvirt.h
18103 +--- linux-2.6.22.19/include/linux/vserver/cvirt.h 1970-01-01 01:00:00 +0100
18104 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/cvirt.h 2007-06-15 02:37:04 +0200
18105 +@@ -0,0 +1,20 @@
18106 ++#ifndef _VX_CVIRT_H
18107 ++#define _VX_CVIRT_H
18108 ++
18109 ++
18110 ++#ifdef __KERNEL__
18111 ++
18112 ++struct timespec;
18113 ++
18114 ++void vx_vsi_uptime(struct timespec *, struct timespec *);
18115 ++
18116 ++
18117 ++struct vx_info;
18118 ++
18119 ++void vx_update_load(struct vx_info *);
18120 ++
18121 ++
18122 ++int vx_do_syslog(int, char __user *, int);
18123 ++
18124 ++#endif /* __KERNEL__ */
18125 ++#endif /* _VX_CVIRT_H */
18126 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/cvirt_cmd.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/cvirt_cmd.h
18127 +--- linux-2.6.22.19/include/linux/vserver/cvirt_cmd.h 1970-01-01 01:00:00 +0100
18128 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/cvirt_cmd.h 2007-06-15 02:37:04 +0200
18129 +@@ -0,0 +1,53 @@
18130 ++#ifndef _VX_CVIRT_CMD_H
18131 ++#define _VX_CVIRT_CMD_H
18132 ++
18133 ++
18134 ++/* virtual host info name commands */
18135 ++
18136 ++#define VCMD_set_vhi_name VC_CMD(VHOST, 1, 0)
18137 ++#define VCMD_get_vhi_name VC_CMD(VHOST, 2, 0)
18138 ++
18139 ++struct vcmd_vhi_name_v0 {
18140 ++ uint32_t field;
18141 ++ char name[65];
18142 ++};
18143 ++
18144 ++
18145 ++enum vhi_name_field {
18146 ++ VHIN_CONTEXT = 0,
18147 ++ VHIN_SYSNAME,
18148 ++ VHIN_NODENAME,
18149 ++ VHIN_RELEASE,
18150 ++ VHIN_VERSION,
18151 ++ VHIN_MACHINE,
18152 ++ VHIN_DOMAINNAME,
18153 ++};
18154 ++
18155 ++
18156 ++#ifdef __KERNEL__
18157 ++
18158 ++#include <linux/compiler.h>
18159 ++
18160 ++extern int vc_set_vhi_name(struct vx_info *, void __user *);
18161 ++extern int vc_get_vhi_name(struct vx_info *, void __user *);
18162 ++
18163 ++#endif /* __KERNEL__ */
18164 ++
18165 ++#define VCMD_virt_stat VC_CMD(VSTAT, 3, 0)
18166 ++
18167 ++struct vcmd_virt_stat_v0 {
18168 ++ uint64_t offset;
18169 ++ uint64_t uptime;
18170 ++ uint32_t nr_threads;
18171 ++ uint32_t nr_running;
18172 ++ uint32_t nr_uninterruptible;
18173 ++ uint32_t nr_onhold;
18174 ++ uint32_t nr_forks;
18175 ++ uint32_t load[3];
18176 ++};
18177 ++
18178 ++#ifdef __KERNEL__
18179 ++extern int vc_virt_stat(struct vx_info *, void __user *);
18180 ++
18181 ++#endif /* __KERNEL__ */
18182 ++#endif /* _VX_CVIRT_CMD_H */
18183 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/cvirt_def.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/cvirt_def.h
18184 +--- linux-2.6.22.19/include/linux/vserver/cvirt_def.h 1970-01-01 01:00:00 +0100
18185 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/cvirt_def.h 2007-06-15 02:37:04 +0200
18186 +@@ -0,0 +1,81 @@
18187 ++#ifndef _VX_CVIRT_DEF_H
18188 ++#define _VX_CVIRT_DEF_H
18189 ++
18190 ++#include <linux/jiffies.h>
18191 ++#include <linux/spinlock.h>
18192 ++#include <linux/wait.h>
18193 ++#include <linux/time.h>
18194 ++#include <linux/utsname.h>
18195 ++#include <asm/atomic.h>
18196 ++
18197 ++
18198 ++struct _vx_usage_stat {
18199 ++ uint64_t user;
18200 ++ uint64_t nice;
18201 ++ uint64_t system;
18202 ++ uint64_t softirq;
18203 ++ uint64_t irq;
18204 ++ uint64_t idle;
18205 ++ uint64_t iowait;
18206 ++};
18207 ++
18208 ++struct _vx_syslog {
18209 ++ wait_queue_head_t log_wait;
18210 ++ spinlock_t logbuf_lock; /* lock for the log buffer */
18211 ++
18212 ++ unsigned long log_start; /* next char to be read by syslog() */
18213 ++ unsigned long con_start; /* next char to be sent to consoles */
18214 ++ unsigned long log_end; /* most-recently-written-char + 1 */
18215 ++ unsigned long logged_chars; /* #chars since last read+clear operation */
18216 ++
18217 ++ char log_buf[1024];
18218 ++};
18219 ++
18220 ++
18221 ++/* context sub struct */
18222 ++
18223 ++struct _vx_cvirt {
18224 ++ atomic_t nr_threads; /* number of current threads */
18225 ++ atomic_t nr_running; /* number of running threads */
18226 ++ atomic_t nr_uninterruptible; /* number of uninterruptible threads */
18227 ++
18228 ++ atomic_t nr_onhold; /* processes on hold */
18229 ++ uint32_t onhold_last; /* jiffies when put on hold */
18230 ++
18231 ++ struct timeval bias_tv; /* time offset to the host */
18232 ++ struct timespec bias_idle;
18233 ++ struct timespec bias_uptime; /* context creation point */
18234 ++ uint64_t bias_clock; /* offset in clock_t */
18235 ++
18236 ++ spinlock_t load_lock; /* lock for the load averages */
18237 ++ atomic_t load_updates; /* nr of load updates done so far */
18238 ++ uint32_t load_last; /* last time load was calculated */
18239 ++ uint32_t load[3]; /* load averages 1,5,15 */
18240 ++
18241 ++ atomic_t total_forks; /* number of forks so far */
18242 ++
18243 ++ struct _vx_syslog syslog;
18244 ++};
18245 ++
18246 ++struct _vx_cvirt_pc {
18247 ++ struct _vx_usage_stat cpustat;
18248 ++};
18249 ++
18250 ++
18251 ++#ifdef CONFIG_VSERVER_DEBUG
18252 ++
18253 ++static inline void __dump_vx_cvirt(struct _vx_cvirt *cvirt)
18254 ++{
18255 ++ printk("\t_vx_cvirt:\n");
18256 ++ printk("\t threads: %4d, %4d, %4d, %4d\n",
18257 ++ atomic_read(&cvirt->nr_threads),
18258 ++ atomic_read(&cvirt->nr_running),
18259 ++ atomic_read(&cvirt->nr_uninterruptible),
18260 ++ atomic_read(&cvirt->nr_onhold));
18261 ++ /* add rest here */
18262 ++ printk("\t total_forks = %d\n", atomic_read(&cvirt->total_forks));
18263 ++}
18264 ++
18265 ++#endif
18266 ++
18267 ++#endif /* _VX_CVIRT_DEF_H */
18268 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/debug.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/debug.h
18269 +--- linux-2.6.22.19/include/linux/vserver/debug.h 1970-01-01 01:00:00 +0100
18270 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/debug.h 2007-10-29 23:39:46 +0100
18271 +@@ -0,0 +1,124 @@
18272 ++#ifndef _VX_DEBUG_H
18273 ++#define _VX_DEBUG_H
18274 ++
18275 ++
18276 ++#define VXD_CBIT(n, m) (vx_debug_ ## n & (1 << (m)))
18277 ++#define VXD_CMIN(n, m) (vx_debug_ ## n > (m))
18278 ++#define VXD_MASK(n, m) (vx_debug_ ## n & (m))
18279 ++
18280 ++#define VXD_DEV(d) (d), (d)->bd_inode->i_ino, \
18281 ++ imajor((d)->bd_inode), iminor((d)->bd_inode)
18282 ++#define VXF_DEV "%p[%lu,%d:%d]"
18283 ++
18284 ++
18285 ++#define __FUNC__ __func__
18286 ++
18287 ++
18288 ++#define vxd_path(d, m) \
18289 ++ ({ static char _buffer[PATH_MAX]; \
18290 ++ d_path(d, m, _buffer, sizeof(_buffer)); })
18291 ++
18292 ++#define vxd_cond_path(n) \
18293 ++ ((n) ? vxd_path((n)->dentry, (n)->mnt) : "<null>" )
18294 ++
18295 ++
18296 ++#ifdef CONFIG_VSERVER_DEBUG
18297 ++
18298 ++extern unsigned int vx_debug_switch;
18299 ++extern unsigned int vx_debug_xid;
18300 ++extern unsigned int vx_debug_nid;
18301 ++extern unsigned int vx_debug_tag;
18302 ++extern unsigned int vx_debug_net;
18303 ++extern unsigned int vx_debug_limit;
18304 ++extern unsigned int vx_debug_cres;
18305 ++extern unsigned int vx_debug_dlim;
18306 ++extern unsigned int vx_debug_quota;
18307 ++extern unsigned int vx_debug_cvirt;
18308 ++extern unsigned int vx_debug_space;
18309 ++extern unsigned int vx_debug_misc;
18310 ++
18311 ++
18312 ++#define VX_LOGLEVEL "vxD: "
18313 ++
18314 ++#define vxdprintk(c, f, x...) \
18315 ++ do { \
18316 ++ if (c) \
18317 ++ printk(VX_LOGLEVEL f "\n" , ##x); \
18318 ++ } while (0)
18319 ++
18320 ++#define vxlprintk(c, f, x...) \
18321 ++ do { \
18322 ++ if (c) \
18323 ++ printk(VX_LOGLEVEL f " @%s:%d\n", x); \
18324 ++ } while (0)
18325 ++
18326 ++#define vxfprintk(c, f, x...) \
18327 ++ do { \
18328 ++ if (c) \
18329 ++ printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \
18330 ++ } while (0)
18331 ++
18332 ++
18333 ++struct vx_info;
18334 ++
18335 ++void dump_vx_info(struct vx_info *, int);
18336 ++void dump_vx_info_inactive(int);
18337 ++
18338 ++#else /* CONFIG_VSERVER_DEBUG */
18339 ++
18340 ++#define vx_debug_switch 0
18341 ++#define vx_debug_xid 0
18342 ++#define vx_debug_nid 0
18343 ++#define vx_debug_tag 0
18344 ++#define vx_debug_net 0
18345 ++#define vx_debug_limit 0
18346 ++#define vx_debug_cres 0
18347 ++#define vx_debug_dlim 0
18348 ++#define vx_debug_cvirt 0
18349 ++
18350 ++#define vxdprintk(x...) do { } while (0)
18351 ++#define vxlprintk(x...) do { } while (0)
18352 ++#define vxfprintk(x...) do { } while (0)
18353 ++
18354 ++#endif /* CONFIG_VSERVER_DEBUG */
18355 ++
18356 ++
18357 ++#ifdef CONFIG_VSERVER_WARN
18358 ++
18359 ++#define VX_WARNLEVEL KERN_WARNING "vxW: "
18360 ++#define VX_WARN_TASK "[»%s«,%u:#%u|%u] "
18361 ++#define VX_WARN_XID "[xid #%u] "
18362 ++#define VX_WARN_NID "[nid #%u] "
18363 ++
18364 ++#define vxwprintk(c, f, x...) \
18365 ++ do { \
18366 ++ if (c) \
18367 ++ printk(VX_WARNLEVEL f "\n", ##x); \
18368 ++ } while (0)
18369 ++
18370 ++#else /* CONFIG_VSERVER_WARN */
18371 ++
18372 ++#define vxwprintk(x...) do { } while (0)
18373 ++
18374 ++#endif /* CONFIG_VSERVER_WARN */
18375 ++
18376 ++#define vxwprintk_task(c, f, x...) \
18377 ++ vxwprintk(c, VX_WARN_TASK f, \
18378 ++ current->comm, current->pid, \
18379 ++ current->xid, current->nid, ##x)
18380 ++#define vxwprintk_xid(c, f, x...) \
18381 ++ vxwprintk(c, VX_WARN_XID f, current->xid, x)
18382 ++#define vxwprintk_nid(c, f, x...) \
18383 ++ vxwprintk(c, VX_WARN_NID f, current->nid, x)
18384 ++
18385 ++#ifdef CONFIG_VSERVER_DEBUG
18386 ++#define vxd_assert_lock(l) assert_spin_locked(l)
18387 ++#define vxd_assert(c, f, x...) vxlprintk(!(c), \
18388 ++ "assertion [" f "] failed.", ##x, __FILE__, __LINE__)
18389 ++#else
18390 ++#define vxd_assert_lock(l) do { } while (0)
18391 ++#define vxd_assert(c, f, x...) do { } while (0)
18392 ++#endif
18393 ++
18394 ++
18395 ++#endif /* _VX_DEBUG_H */
18396 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/debug_cmd.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/debug_cmd.h
18397 +--- linux-2.6.22.19/include/linux/vserver/debug_cmd.h 1970-01-01 01:00:00 +0100
18398 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/debug_cmd.h 2007-06-15 02:37:04 +0200
18399 +@@ -0,0 +1,58 @@
18400 ++#ifndef _VX_DEBUG_CMD_H
18401 ++#define _VX_DEBUG_CMD_H
18402 ++
18403 ++
18404 ++/* debug commands */
18405 ++
18406 ++#define VCMD_dump_history VC_CMD(DEBUG, 1, 0)
18407 ++
18408 ++#define VCMD_read_history VC_CMD(DEBUG, 5, 0)
18409 ++#define VCMD_read_monitor VC_CMD(DEBUG, 6, 0)
18410 ++
18411 ++struct vcmd_read_history_v0 {
18412 ++ uint32_t index;
18413 ++ uint32_t count;
18414 ++ char __user *data;
18415 ++};
18416 ++
18417 ++struct vcmd_read_monitor_v0 {
18418 ++ uint32_t index;
18419 ++ uint32_t count;
18420 ++ char __user *data;
18421 ++};
18422 ++
18423 ++
18424 ++#ifdef __KERNEL__
18425 ++
18426 ++#ifdef CONFIG_COMPAT
18427 ++
18428 ++#include <asm/compat.h>
18429 ++
18430 ++struct vcmd_read_history_v0_x32 {
18431 ++ uint32_t index;
18432 ++ uint32_t count;
18433 ++ compat_uptr_t data_ptr;
18434 ++};
18435 ++
18436 ++struct vcmd_read_monitor_v0_x32 {
18437 ++ uint32_t index;
18438 ++ uint32_t count;
18439 ++ compat_uptr_t data_ptr;
18440 ++};
18441 ++
18442 ++#endif /* CONFIG_COMPAT */
18443 ++
18444 ++extern int vc_dump_history(uint32_t);
18445 ++
18446 ++extern int vc_read_history(uint32_t, void __user *);
18447 ++extern int vc_read_monitor(uint32_t, void __user *);
18448 ++
18449 ++#ifdef CONFIG_COMPAT
18450 ++
18451 ++extern int vc_read_history_x32(uint32_t, void __user *);
18452 ++extern int vc_read_monitor_x32(uint32_t, void __user *);
18453 ++
18454 ++#endif /* CONFIG_COMPAT */
18455 ++
18456 ++#endif /* __KERNEL__ */
18457 ++#endif /* _VX_DEBUG_CMD_H */
18458 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/dlimit.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/dlimit.h
18459 +--- linux-2.6.22.19/include/linux/vserver/dlimit.h 1970-01-01 01:00:00 +0100
18460 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/dlimit.h 2007-06-15 02:37:04 +0200
18461 +@@ -0,0 +1,53 @@
18462 ++#ifndef _VX_DLIMIT_H
18463 ++#define _VX_DLIMIT_H
18464 ++
18465 ++#include "switch.h"
18466 ++
18467 ++
18468 ++#ifdef __KERNEL__
18469 ++
18470 ++/* keep in sync with CDLIM_INFINITY */
18471 ++
18472 ++#define DLIM_INFINITY (~0ULL)
18473 ++
18474 ++#include <linux/spinlock.h>
18475 ++
18476 ++struct super_block;
18477 ++
18478 ++struct dl_info {
18479 ++ struct hlist_node dl_hlist; /* linked list of contexts */
18480 ++ struct rcu_head dl_rcu; /* the rcu head */
18481 ++ tag_t dl_tag; /* context tag */
18482 ++ atomic_t dl_usecnt; /* usage count */
18483 ++ atomic_t dl_refcnt; /* reference count */
18484 ++
18485 ++ struct super_block *dl_sb; /* associated superblock */
18486 ++
18487 ++ spinlock_t dl_lock; /* protect the values */
18488 ++
18489 ++ unsigned long long dl_space_used; /* used space in bytes */
18490 ++ unsigned long long dl_space_total; /* maximum space in bytes */
18491 ++ unsigned long dl_inodes_used; /* used inodes */
18492 ++ unsigned long dl_inodes_total; /* maximum inodes */
18493 ++
18494 ++ unsigned int dl_nrlmult; /* non root limit mult */
18495 ++};
18496 ++
18497 ++struct rcu_head;
18498 ++
18499 ++extern void rcu_free_dl_info(struct rcu_head *);
18500 ++extern void unhash_dl_info(struct dl_info *);
18501 ++
18502 ++extern struct dl_info *locate_dl_info(struct super_block *, tag_t);
18503 ++
18504 ++
18505 ++struct kstatfs;
18506 ++
18507 ++extern void vx_vsi_statfs(struct super_block *, struct kstatfs *);
18508 ++
18509 ++typedef uint64_t dlsize_t;
18510 ++
18511 ++#endif /* __KERNEL__ */
18512 ++#else /* _VX_DLIMIT_H */
18513 ++#warning duplicate inclusion
18514 ++#endif /* _VX_DLIMIT_H */
18515 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/dlimit_cmd.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/dlimit_cmd.h
18516 +--- linux-2.6.22.19/include/linux/vserver/dlimit_cmd.h 1970-01-01 01:00:00 +0100
18517 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/dlimit_cmd.h 2007-06-15 02:37:04 +0200
18518 +@@ -0,0 +1,74 @@
18519 ++#ifndef _VX_DLIMIT_CMD_H
18520 ++#define _VX_DLIMIT_CMD_H
18521 ++
18522 ++
18523 ++/* dlimit vserver commands */
18524 ++
18525 ++#define VCMD_add_dlimit VC_CMD(DLIMIT, 1, 0)
18526 ++#define VCMD_rem_dlimit VC_CMD(DLIMIT, 2, 0)
18527 ++
18528 ++#define VCMD_set_dlimit VC_CMD(DLIMIT, 5, 0)
18529 ++#define VCMD_get_dlimit VC_CMD(DLIMIT, 6, 0)
18530 ++
18531 ++struct vcmd_ctx_dlimit_base_v0 {
18532 ++ const char __user *name;
18533 ++ uint32_t flags;
18534 ++};
18535 ++
18536 ++struct vcmd_ctx_dlimit_v0 {
18537 ++ const char __user *name;
18538 ++ uint32_t space_used; /* used space in kbytes */
18539 ++ uint32_t space_total; /* maximum space in kbytes */
18540 ++ uint32_t inodes_used; /* used inodes */
18541 ++ uint32_t inodes_total; /* maximum inodes */
18542 ++ uint32_t reserved; /* reserved for root in % */
18543 ++ uint32_t flags;
18544 ++};
18545 ++
18546 ++#define CDLIM_UNSET ((uint32_t)0UL)
18547 ++#define CDLIM_INFINITY ((uint32_t)~0UL)
18548 ++#define CDLIM_KEEP ((uint32_t)~1UL)
18549 ++
18550 ++#ifdef __KERNEL__
18551 ++
18552 ++#ifdef CONFIG_COMPAT
18553 ++
18554 ++#include <asm/compat.h>
18555 ++
18556 ++struct vcmd_ctx_dlimit_base_v0_x32 {
18557 ++ compat_uptr_t name_ptr;
18558 ++ uint32_t flags;
18559 ++};
18560 ++
18561 ++struct vcmd_ctx_dlimit_v0_x32 {
18562 ++ compat_uptr_t name_ptr;
18563 ++ uint32_t space_used; /* used space in kbytes */
18564 ++ uint32_t space_total; /* maximum space in kbytes */
18565 ++ uint32_t inodes_used; /* used inodes */
18566 ++ uint32_t inodes_total; /* maximum inodes */
18567 ++ uint32_t reserved; /* reserved for root in % */
18568 ++ uint32_t flags;
18569 ++};
18570 ++
18571 ++#endif /* CONFIG_COMPAT */
18572 ++
18573 ++#include <linux/compiler.h>
18574 ++
18575 ++extern int vc_add_dlimit(uint32_t, void __user *);
18576 ++extern int vc_rem_dlimit(uint32_t, void __user *);
18577 ++
18578 ++extern int vc_set_dlimit(uint32_t, void __user *);
18579 ++extern int vc_get_dlimit(uint32_t, void __user *);
18580 ++
18581 ++#ifdef CONFIG_COMPAT
18582 ++
18583 ++extern int vc_add_dlimit_x32(uint32_t, void __user *);
18584 ++extern int vc_rem_dlimit_x32(uint32_t, void __user *);
18585 ++
18586 ++extern int vc_set_dlimit_x32(uint32_t, void __user *);
18587 ++extern int vc_get_dlimit_x32(uint32_t, void __user *);
18588 ++
18589 ++#endif /* CONFIG_COMPAT */
18590 ++
18591 ++#endif /* __KERNEL__ */
18592 ++#endif /* _VX_DLIMIT_CMD_H */
18593 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/global.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/global.h
18594 +--- linux-2.6.22.19/include/linux/vserver/global.h 1970-01-01 01:00:00 +0100
18595 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/global.h 2007-06-15 02:37:04 +0200
18596 +@@ -0,0 +1,18 @@
18597 ++#ifndef _VX_GLOBAL_H
18598 ++#define _VX_GLOBAL_H
18599 ++
18600 ++
18601 ++extern atomic_t vx_global_ctotal;
18602 ++extern atomic_t vx_global_cactive;
18603 ++
18604 ++extern atomic_t nx_global_ctotal;
18605 ++extern atomic_t nx_global_cactive;
18606 ++
18607 ++extern atomic_t vs_global_nsproxy;
18608 ++extern atomic_t vs_global_fs;
18609 ++extern atomic_t vs_global_mnt_ns;
18610 ++extern atomic_t vs_global_uts_ns;
18611 ++extern atomic_t vs_global_ipc_ns;
18612 ++
18613 ++
18614 ++#endif /* _VX_GLOBAL_H */
18615 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/history.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/history.h
18616 +--- linux-2.6.22.19/include/linux/vserver/history.h 1970-01-01 01:00:00 +0100
18617 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/history.h 2007-06-15 02:37:04 +0200
18618 +@@ -0,0 +1,197 @@
18619 ++#ifndef _VX_HISTORY_H
18620 ++#define _VX_HISTORY_H
18621 ++
18622 ++
18623 ++enum {
18624 ++ VXH_UNUSED = 0,
18625 ++ VXH_THROW_OOPS = 1,
18626 ++
18627 ++ VXH_GET_VX_INFO,
18628 ++ VXH_PUT_VX_INFO,
18629 ++ VXH_INIT_VX_INFO,
18630 ++ VXH_SET_VX_INFO,
18631 ++ VXH_CLR_VX_INFO,
18632 ++ VXH_CLAIM_VX_INFO,
18633 ++ VXH_RELEASE_VX_INFO,
18634 ++ VXH_ALLOC_VX_INFO,
18635 ++ VXH_DEALLOC_VX_INFO,
18636 ++ VXH_HASH_VX_INFO,
18637 ++ VXH_UNHASH_VX_INFO,
18638 ++ VXH_LOC_VX_INFO,
18639 ++ VXH_LOOKUP_VX_INFO,
18640 ++ VXH_CREATE_VX_INFO,
18641 ++};
18642 ++
18643 ++struct _vxhe_vxi {
18644 ++ struct vx_info *ptr;
18645 ++ unsigned xid;
18646 ++ unsigned usecnt;
18647 ++ unsigned tasks;
18648 ++};
18649 ++
18650 ++struct _vxhe_set_clr {
18651 ++ void *data;
18652 ++};
18653 ++
18654 ++struct _vxhe_loc_lookup {
18655 ++ unsigned arg;
18656 ++};
18657 ++
18658 ++struct _vx_hist_entry {
18659 ++ void *loc;
18660 ++ unsigned short seq;
18661 ++ unsigned short type;
18662 ++ struct _vxhe_vxi vxi;
18663 ++ union {
18664 ++ struct _vxhe_set_clr sc;
18665 ++ struct _vxhe_loc_lookup ll;
18666 ++ };
18667 ++};
18668 ++
18669 ++#ifdef CONFIG_VSERVER_HISTORY
18670 ++
18671 ++extern unsigned volatile int vxh_active;
18672 ++
18673 ++struct _vx_hist_entry *vxh_advance(void *loc);
18674 ++
18675 ++
18676 ++static inline
18677 ++void __vxh_copy_vxi(struct _vx_hist_entry *entry, struct vx_info *vxi)
18678 ++{
18679 ++ entry->vxi.ptr = vxi;
18680 ++ if (vxi) {
18681 ++ entry->vxi.usecnt = atomic_read(&vxi->vx_usecnt);
18682 ++ entry->vxi.tasks = atomic_read(&vxi->vx_tasks);
18683 ++ entry->vxi.xid = vxi->vx_id;
18684 ++ }
18685 ++}
18686 ++
18687 ++
18688 ++#define __HERE__ current_text_addr()
18689 ++
18690 ++#define __VXH_BODY(__type, __data, __here) \
18691 ++ struct _vx_hist_entry *entry; \
18692 ++ \
18693 ++ preempt_disable(); \
18694 ++ entry = vxh_advance(__here); \
18695 ++ __data; \
18696 ++ entry->type = __type; \
18697 ++ preempt_enable();
18698 ++
18699 ++
18700 ++ /* pass vxi only */
18701 ++
18702 ++#define __VXH_SMPL \
18703 ++ __vxh_copy_vxi(entry, vxi)
18704 ++
18705 ++static inline
18706 ++void __vxh_smpl(struct vx_info *vxi, int __type, void *__here)
18707 ++{
18708 ++ __VXH_BODY(__type, __VXH_SMPL, __here)
18709 ++}
18710 ++
18711 ++ /* pass vxi and data (void *) */
18712 ++
18713 ++#define __VXH_DATA \
18714 ++ __vxh_copy_vxi(entry, vxi); \
18715 ++ entry->sc.data = data
18716 ++
18717 ++static inline
18718 ++void __vxh_data(struct vx_info *vxi, void *data,
18719 ++ int __type, void *__here)
18720 ++{
18721 ++ __VXH_BODY(__type, __VXH_DATA, __here)
18722 ++}
18723 ++
18724 ++ /* pass vxi and arg (long) */
18725 ++
18726 ++#define __VXH_LONG \
18727 ++ __vxh_copy_vxi(entry, vxi); \
18728 ++ entry->ll.arg = arg
18729 ++
18730 ++static inline
18731 ++void __vxh_long(struct vx_info *vxi, long arg,
18732 ++ int __type, void *__here)
18733 ++{
18734 ++ __VXH_BODY(__type, __VXH_LONG, __here)
18735 ++}
18736 ++
18737 ++
18738 ++static inline
18739 ++void __vxh_throw_oops(void *__here)
18740 ++{
18741 ++ __VXH_BODY(VXH_THROW_OOPS, {}, __here);
18742 ++ /* prevent further acquisition */
18743 ++ vxh_active = 0;
18744 ++}
18745 ++
18746 ++
18747 ++#define vxh_throw_oops() __vxh_throw_oops(__HERE__);
18748 ++
18749 ++#define __vxh_get_vx_info(v, h) __vxh_smpl(v, VXH_GET_VX_INFO, h);
18750 ++#define __vxh_put_vx_info(v, h) __vxh_smpl(v, VXH_PUT_VX_INFO, h);
18751 ++
18752 ++#define __vxh_init_vx_info(v, d, h) \
18753 ++ __vxh_data(v, d, VXH_INIT_VX_INFO, h);
18754 ++#define __vxh_set_vx_info(v, d, h) \
18755 ++ __vxh_data(v, d, VXH_SET_VX_INFO, h);
18756 ++#define __vxh_clr_vx_info(v, d, h) \
18757 ++ __vxh_data(v, d, VXH_CLR_VX_INFO, h);
18758 ++
18759 ++#define __vxh_claim_vx_info(v, d, h) \
18760 ++ __vxh_data(v, d, VXH_CLAIM_VX_INFO, h);
18761 ++#define __vxh_release_vx_info(v, d, h) \
18762 ++ __vxh_data(v, d, VXH_RELEASE_VX_INFO, h);
18763 ++
18764 ++#define vxh_alloc_vx_info(v) \
18765 ++ __vxh_smpl(v, VXH_ALLOC_VX_INFO, __HERE__);
18766 ++#define vxh_dealloc_vx_info(v) \
18767 ++ __vxh_smpl(v, VXH_DEALLOC_VX_INFO, __HERE__);
18768 ++
18769 ++#define vxh_hash_vx_info(v) \
18770 ++ __vxh_smpl(v, VXH_HASH_VX_INFO, __HERE__);
18771 ++#define vxh_unhash_vx_info(v) \
18772 ++ __vxh_smpl(v, VXH_UNHASH_VX_INFO, __HERE__);
18773 ++
18774 ++#define vxh_loc_vx_info(v, l) \
18775 ++ __vxh_long(v, l, VXH_LOC_VX_INFO, __HERE__);
18776 ++#define vxh_lookup_vx_info(v, l) \
18777 ++ __vxh_long(v, l, VXH_LOOKUP_VX_INFO, __HERE__);
18778 ++#define vxh_create_vx_info(v, l) \
18779 ++ __vxh_long(v, l, VXH_CREATE_VX_INFO, __HERE__);
18780 ++
18781 ++extern void vxh_dump_history(void);
18782 ++
18783 ++
18784 ++#else /* CONFIG_VSERVER_HISTORY */
18785 ++
18786 ++#define __HERE__ 0
18787 ++
18788 ++#define vxh_throw_oops() do { } while (0)
18789 ++
18790 ++#define __vxh_get_vx_info(v, h) do { } while (0)
18791 ++#define __vxh_put_vx_info(v, h) do { } while (0)
18792 ++
18793 ++#define __vxh_init_vx_info(v, d, h) do { } while (0)
18794 ++#define __vxh_set_vx_info(v, d, h) do { } while (0)
18795 ++#define __vxh_clr_vx_info(v, d, h) do { } while (0)
18796 ++
18797 ++#define __vxh_claim_vx_info(v, d, h) do { } while (0)
18798 ++#define __vxh_release_vx_info(v, d, h) do { } while (0)
18799 ++
18800 ++#define vxh_alloc_vx_info(v) do { } while (0)
18801 ++#define vxh_dealloc_vx_info(v) do { } while (0)
18802 ++
18803 ++#define vxh_hash_vx_info(v) do { } while (0)
18804 ++#define vxh_unhash_vx_info(v) do { } while (0)
18805 ++
18806 ++#define vxh_loc_vx_info(v, l) do { } while (0)
18807 ++#define vxh_lookup_vx_info(v, l) do { } while (0)
18808 ++#define vxh_create_vx_info(v, l) do { } while (0)
18809 ++
18810 ++#define vxh_dump_history() do { } while (0)
18811 ++
18812 ++
18813 ++#endif /* CONFIG_VSERVER_HISTORY */
18814 ++
18815 ++#endif /* _VX_HISTORY_H */
18816 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/inode.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/inode.h
18817 +--- linux-2.6.22.19/include/linux/vserver/inode.h 1970-01-01 01:00:00 +0100
18818 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/inode.h 2007-06-15 02:37:04 +0200
18819 +@@ -0,0 +1,38 @@
18820 ++#ifndef _VX_INODE_H
18821 ++#define _VX_INODE_H
18822 ++
18823 ++
18824 ++#define IATTR_TAG 0x01000000
18825 ++
18826 ++#define IATTR_ADMIN 0x00000001
18827 ++#define IATTR_WATCH 0x00000002
18828 ++#define IATTR_HIDE 0x00000004
18829 ++#define IATTR_FLAGS 0x00000007
18830 ++
18831 ++#define IATTR_BARRIER 0x00010000
18832 ++#define IATTR_IUNLINK 0x00020000
18833 ++#define IATTR_IMMUTABLE 0x00040000
18834 ++
18835 ++#ifdef __KERNEL__
18836 ++
18837 ++
18838 ++#ifdef CONFIG_VSERVER_PROC_SECURE
18839 ++#define IATTR_PROC_DEFAULT ( IATTR_ADMIN | IATTR_HIDE )
18840 ++#define IATTR_PROC_SYMLINK ( IATTR_ADMIN )
18841 ++#else
18842 ++#define IATTR_PROC_DEFAULT ( IATTR_ADMIN )
18843 ++#define IATTR_PROC_SYMLINK ( IATTR_ADMIN )
18844 ++#endif
18845 ++
18846 ++#define vx_hide_check(c, m) (((m) & IATTR_HIDE) ? vx_check(c, m) : 1)
18847 ++
18848 ++#endif /* __KERNEL__ */
18849 ++
18850 ++/* inode ioctls */
18851 ++
18852 ++#define FIOC_GETXFLG _IOR('x', 5, long)
18853 ++#define FIOC_SETXFLG _IOW('x', 6, long)
18854 ++
18855 ++#else /* _VX_INODE_H */
18856 ++#warning duplicate inclusion
18857 ++#endif /* _VX_INODE_H */
18858 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/inode_cmd.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/inode_cmd.h
18859 +--- linux-2.6.22.19/include/linux/vserver/inode_cmd.h 1970-01-01 01:00:00 +0100
18860 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/inode_cmd.h 2007-07-16 06:38:22 +0200
18861 +@@ -0,0 +1,59 @@
18862 ++#ifndef _VX_INODE_CMD_H
18863 ++#define _VX_INODE_CMD_H
18864 ++
18865 ++
18866 ++/* inode vserver commands */
18867 ++
18868 ++#define VCMD_get_iattr VC_CMD(INODE, 1, 1)
18869 ++#define VCMD_set_iattr VC_CMD(INODE, 2, 1)
18870 ++
18871 ++#define VCMD_fget_iattr VC_CMD(INODE, 3, 0)
18872 ++#define VCMD_fset_iattr VC_CMD(INODE, 4, 0)
18873 ++
18874 ++struct vcmd_ctx_iattr_v1 {
18875 ++ const char __user *name;
18876 ++ uint32_t xid;
18877 ++ uint32_t flags;
18878 ++ uint32_t mask;
18879 ++};
18880 ++
18881 ++struct vcmd_ctx_fiattr_v0 {
18882 ++ uint32_t xid;
18883 ++ uint32_t flags;
18884 ++ uint32_t mask;
18885 ++};
18886 ++
18887 ++
18888 ++#ifdef __KERNEL__
18889 ++
18890 ++
18891 ++#ifdef CONFIG_COMPAT
18892 ++
18893 ++#include <asm/compat.h>
18894 ++
18895 ++struct vcmd_ctx_iattr_v1_x32 {
18896 ++ compat_uptr_t name_ptr;
18897 ++ uint32_t xid;
18898 ++ uint32_t flags;
18899 ++ uint32_t mask;
18900 ++};
18901 ++
18902 ++#endif /* CONFIG_COMPAT */
18903 ++
18904 ++#include <linux/compiler.h>
18905 ++
18906 ++extern int vc_get_iattr(void __user *);
18907 ++extern int vc_set_iattr(void __user *);
18908 ++
18909 ++extern int vc_fget_iattr(uint32_t, void __user *);
18910 ++extern int vc_fset_iattr(uint32_t, void __user *);
18911 ++
18912 ++#ifdef CONFIG_COMPAT
18913 ++
18914 ++extern int vc_get_iattr_x32(void __user *);
18915 ++extern int vc_set_iattr_x32(void __user *);
18916 ++
18917 ++#endif /* CONFIG_COMPAT */
18918 ++
18919 ++#endif /* __KERNEL__ */
18920 ++#endif /* _VX_INODE_CMD_H */
18921 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/legacy.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/legacy.h
18922 +--- linux-2.6.22.19/include/linux/vserver/legacy.h 1970-01-01 01:00:00 +0100
18923 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/legacy.h 2007-06-15 02:37:04 +0200
18924 +@@ -0,0 +1,49 @@
18925 ++#ifndef _VX_LEGACY_H
18926 ++#define _VX_LEGACY_H
18927 ++
18928 ++#include "switch.h"
18929 ++
18930 ++
18931 ++/* compatibiliy vserver commands */
18932 ++
18933 ++#define VCMD_new_s_context VC_CMD(COMPAT, 1, 1)
18934 ++#define VCMD_set_ipv4root VC_CMD(COMPAT, 2, 3)
18935 ++
18936 ++#define VCMD_create_context VC_CMD(VSETUP, 1, 0)
18937 ++
18938 ++/* compatibiliy vserver arguments */
18939 ++
18940 ++struct vcmd_new_s_context_v1 {
18941 ++ uint32_t remove_cap;
18942 ++ uint32_t flags;
18943 ++};
18944 ++
18945 ++struct vcmd_set_ipv4root_v3 {
18946 ++ /* number of pairs in id */
18947 ++ uint32_t broadcast;
18948 ++ struct {
18949 ++ uint32_t ip;
18950 ++ uint32_t mask;
18951 ++ } nx_mask_pair[NB_IPV4ROOT];
18952 ++};
18953 ++
18954 ++
18955 ++#define VX_INFO_LOCK 1 /* Can't request a new vx_id */
18956 ++#define VX_INFO_NPROC 4 /* Limit number of processes in a context */
18957 ++#define VX_INFO_PRIVATE 8 /* Noone can join this security context */
18958 ++#define VX_INFO_INIT 16 /* This process wants to become the */
18959 ++ /* logical process 1 of the security */
18960 ++ /* context */
18961 ++#define VX_INFO_HIDEINFO 32 /* Hide some information in /proc */
18962 ++#define VX_INFO_ULIMIT 64 /* Use ulimit of the current process */
18963 ++ /* to become the global limits */
18964 ++ /* of the context */
18965 ++#define VX_INFO_NAMESPACE 128 /* save private namespace */
18966 ++
18967 ++
18968 ++#ifdef __KERNEL__
18969 ++extern int vc_new_s_context(uint32_t, void __user *);
18970 ++extern int vc_set_ipv4root(uint32_t, void __user *);
18971 ++
18972 ++#endif /* __KERNEL__ */
18973 ++#endif /* _VX_LEGACY_H */
18974 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/limit.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/limit.h
18975 +--- linux-2.6.22.19/include/linux/vserver/limit.h 1970-01-01 01:00:00 +0100
18976 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/limit.h 2007-06-15 02:37:04 +0200
18977 +@@ -0,0 +1,68 @@
18978 ++#ifndef _VX_LIMIT_H
18979 ++#define _VX_LIMIT_H
18980 ++
18981 ++
18982 ++#define VLIMIT_NSOCK 16
18983 ++#define VLIMIT_OPENFD 17
18984 ++#define VLIMIT_ANON 18
18985 ++#define VLIMIT_SHMEM 19
18986 ++#define VLIMIT_SEMARY 20
18987 ++#define VLIMIT_NSEMS 21
18988 ++#define VLIMIT_DENTRY 22
18989 ++#define VLIMIT_MAPPED 23
18990 ++
18991 ++
18992 ++#ifdef __KERNEL__
18993 ++
18994 ++#define VLIM_NOCHECK ((1L << VLIMIT_DENTRY) | (1L << RLIMIT_RSS))
18995 ++
18996 ++/* keep in sync with CRLIM_INFINITY */
18997 ++
18998 ++#define VLIM_INFINITY (~0ULL)
18999 ++
19000 ++#ifndef RLIM_INFINITY
19001 ++#warning RLIM_INFINITY is undefined
19002 ++#endif
19003 ++
19004 ++#define __rlim_val(l, r, v) ((l)->res[r].v)
19005 ++
19006 ++#define __rlim_soft(l, r) __rlim_val(l, r, soft)
19007 ++#define __rlim_hard(l, r) __rlim_val(l, r, hard)
19008 ++
19009 ++#define __rlim_rcur(l, r) __rlim_val(l, r, rcur)
19010 ++#define __rlim_rmin(l, r) __rlim_val(l, r, rmin)
19011 ++#define __rlim_rmax(l, r) __rlim_val(l, r, rmax)
19012 ++
19013 ++#define __rlim_lhit(l, r) __rlim_val(l, r, lhit)
19014 ++#define __rlim_hit(l, r) atomic_inc(&__rlim_lhit(l, r))
19015 ++
19016 ++typedef atomic_long_t rlim_atomic_t;
19017 ++typedef unsigned long rlim_t;
19018 ++
19019 ++#define __rlim_get(l, r) atomic_long_read(&__rlim_rcur(l, r))
19020 ++#define __rlim_set(l, r, v) atomic_long_set(&__rlim_rcur(l, r), v)
19021 ++#define __rlim_inc(l, r) atomic_long_inc(&__rlim_rcur(l, r))
19022 ++#define __rlim_dec(l, r) atomic_long_dec(&__rlim_rcur(l, r))
19023 ++#define __rlim_add(l, r, v) atomic_long_add(v, &__rlim_rcur(l, r))
19024 ++#define __rlim_sub(l, r, v) atomic_long_sub(v, &__rlim_rcur(l, r))
19025 ++
19026 ++
19027 ++#if (RLIM_INFINITY == VLIM_INFINITY)
19028 ++#define VX_VLIM(r) ((long long)(long)(r))
19029 ++#define VX_RLIM(v) ((rlim_t)(v))
19030 ++#else
19031 ++#define VX_VLIM(r) (((r) == RLIM_INFINITY) \
19032 ++ ? VLIM_INFINITY : (long long)(r))
19033 ++#define VX_RLIM(v) (((v) == VLIM_INFINITY) \
19034 ++ ? RLIM_INFINITY : (rlim_t)(v))
19035 ++#endif
19036 ++
19037 ++struct sysinfo;
19038 ++
19039 ++void vx_vsi_meminfo(struct sysinfo *);
19040 ++void vx_vsi_swapinfo(struct sysinfo *);
19041 ++
19042 ++#define NUM_LIMITS 24
19043 ++
19044 ++#endif /* __KERNEL__ */
19045 ++#endif /* _VX_LIMIT_H */
19046 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/limit_cmd.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/limit_cmd.h
19047 +--- linux-2.6.22.19/include/linux/vserver/limit_cmd.h 1970-01-01 01:00:00 +0100
19048 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/limit_cmd.h 2007-06-15 02:37:04 +0200
19049 +@@ -0,0 +1,69 @@
19050 ++#ifndef _VX_LIMIT_CMD_H
19051 ++#define _VX_LIMIT_CMD_H
19052 ++
19053 ++
19054 ++/* rlimit vserver commands */
19055 ++
19056 ++#define VCMD_get_rlimit VC_CMD(RLIMIT, 1, 0)
19057 ++#define VCMD_set_rlimit VC_CMD(RLIMIT, 2, 0)
19058 ++#define VCMD_get_rlimit_mask VC_CMD(RLIMIT, 3, 0)
19059 ++#define VCMD_reset_minmax VC_CMD(RLIMIT, 9, 0)
19060 ++
19061 ++struct vcmd_ctx_rlimit_v0 {
19062 ++ uint32_t id;
19063 ++ uint64_t minimum;
19064 ++ uint64_t softlimit;
19065 ++ uint64_t maximum;
19066 ++};
19067 ++
19068 ++struct vcmd_ctx_rlimit_mask_v0 {
19069 ++ uint32_t minimum;
19070 ++ uint32_t softlimit;
19071 ++ uint32_t maximum;
19072 ++};
19073 ++
19074 ++#define VCMD_rlimit_stat VC_CMD(VSTAT, 1, 0)
19075 ++
19076 ++struct vcmd_rlimit_stat_v0 {
19077 ++ uint32_t id;
19078 ++ uint32_t hits;
19079 ++ uint64_t value;
19080 ++ uint64_t minimum;
19081 ++ uint64_t maximum;
19082 ++};
19083 ++
19084 ++#define CRLIM_UNSET (0ULL)
19085 ++#define CRLIM_INFINITY (~0ULL)
19086 ++#define CRLIM_KEEP (~1ULL)
19087 ++
19088 ++#ifdef __KERNEL__
19089 ++
19090 ++#ifdef CONFIG_IA32_EMULATION
19091 ++
19092 ++struct vcmd_ctx_rlimit_v0_x32 {
19093 ++ uint32_t id;
19094 ++ uint64_t minimum;
19095 ++ uint64_t softlimit;
19096 ++ uint64_t maximum;
19097 ++} __attribute__ ((aligned (4)));
19098 ++
19099 ++#endif /* CONFIG_IA32_EMULATION */
19100 ++
19101 ++#include <linux/compiler.h>
19102 ++
19103 ++extern int vc_get_rlimit_mask(uint32_t, void __user *);
19104 ++extern int vc_get_rlimit(struct vx_info *, void __user *);
19105 ++extern int vc_set_rlimit(struct vx_info *, void __user *);
19106 ++extern int vc_reset_minmax(struct vx_info *, void __user *);
19107 ++
19108 ++extern int vc_rlimit_stat(struct vx_info *, void __user *);
19109 ++
19110 ++#ifdef CONFIG_IA32_EMULATION
19111 ++
19112 ++extern int vc_get_rlimit_x32(struct vx_info *, void __user *);
19113 ++extern int vc_set_rlimit_x32(struct vx_info *, void __user *);
19114 ++
19115 ++#endif /* CONFIG_IA32_EMULATION */
19116 ++
19117 ++#endif /* __KERNEL__ */
19118 ++#endif /* _VX_LIMIT_CMD_H */
19119 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/limit_def.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/limit_def.h
19120 +--- linux-2.6.22.19/include/linux/vserver/limit_def.h 1970-01-01 01:00:00 +0100
19121 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/limit_def.h 2007-06-15 02:37:04 +0200
19122 +@@ -0,0 +1,47 @@
19123 ++#ifndef _VX_LIMIT_DEF_H
19124 ++#define _VX_LIMIT_DEF_H
19125 ++
19126 ++#include <asm/atomic.h>
19127 ++#include <asm/resource.h>
19128 ++
19129 ++#include "limit.h"
19130 ++
19131 ++
19132 ++struct _vx_res_limit {
19133 ++ rlim_t soft; /* Context soft limit */
19134 ++ rlim_t hard; /* Context hard limit */
19135 ++
19136 ++ rlim_atomic_t rcur; /* Current value */
19137 ++ rlim_t rmin; /* Context minimum */
19138 ++ rlim_t rmax; /* Context maximum */
19139 ++
19140 ++ atomic_t lhit; /* Limit hits */
19141 ++};
19142 ++
19143 ++/* context sub struct */
19144 ++
19145 ++struct _vx_limit {
19146 ++ struct _vx_res_limit res[NUM_LIMITS];
19147 ++};
19148 ++
19149 ++#ifdef CONFIG_VSERVER_DEBUG
19150 ++
19151 ++static inline void __dump_vx_limit(struct _vx_limit *limit)
19152 ++{
19153 ++ int i;
19154 ++
19155 ++ printk("\t_vx_limit:");
19156 ++ for (i = 0; i < NUM_LIMITS; i++) {
19157 ++ printk("\t [%2d] = %8lu %8lu/%8lu, %8ld/%8ld, %8d\n",
19158 ++ i, (unsigned long)__rlim_get(limit, i),
19159 ++ (unsigned long)__rlim_rmin(limit, i),
19160 ++ (unsigned long)__rlim_rmax(limit, i),
19161 ++ (long)__rlim_soft(limit, i),
19162 ++ (long)__rlim_hard(limit, i),
19163 ++ atomic_read(&__rlim_lhit(limit, i)));
19164 ++ }
19165 ++}
19166 ++
19167 ++#endif
19168 ++
19169 ++#endif /* _VX_LIMIT_DEF_H */
19170 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/limit_int.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/limit_int.h
19171 +--- linux-2.6.22.19/include/linux/vserver/limit_int.h 1970-01-01 01:00:00 +0100
19172 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/limit_int.h 2007-06-15 02:37:04 +0200
19173 +@@ -0,0 +1,198 @@
19174 ++#ifndef _VX_LIMIT_INT_H
19175 ++#define _VX_LIMIT_INT_H
19176 ++
19177 ++#include "context.h"
19178 ++
19179 ++#ifdef __KERNEL__
19180 ++
19181 ++#define VXD_RCRES_COND(r) VXD_CBIT(cres, r)
19182 ++#define VXD_RLIMIT_COND(r) VXD_CBIT(limit, r)
19183 ++
19184 ++extern const char *vlimit_name[NUM_LIMITS];
19185 ++
19186 ++static inline void __vx_acc_cres(struct vx_info *vxi,
19187 ++ int res, int dir, void *_data, char *_file, int _line)
19188 ++{
19189 ++ if (VXD_RCRES_COND(res))
19190 ++ vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5ld%s (%p)",
19191 ++ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
19192 ++ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
19193 ++ (dir > 0) ? "++" : "--", _data, _file, _line);
19194 ++ if (!vxi)
19195 ++ return;
19196 ++
19197 ++ if (dir > 0)
19198 ++ __rlim_inc(&vxi->limit, res);
19199 ++ else
19200 ++ __rlim_dec(&vxi->limit, res);
19201 ++}
19202 ++
19203 ++static inline void __vx_add_cres(struct vx_info *vxi,
19204 ++ int res, int amount, void *_data, char *_file, int _line)
19205 ++{
19206 ++ if (VXD_RCRES_COND(res))
19207 ++ vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5ld += %5d (%p)",
19208 ++ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
19209 ++ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
19210 ++ amount, _data, _file, _line);
19211 ++ if (amount == 0)
19212 ++ return;
19213 ++ if (!vxi)
19214 ++ return;
19215 ++ __rlim_add(&vxi->limit, res, amount);
19216 ++}
19217 ++
19218 ++static inline
19219 ++int __vx_cres_adjust_max(struct _vx_limit *limit, int res, rlim_t value)
19220 ++{
19221 ++ int cond = (value > __rlim_rmax(limit, res));
19222 ++
19223 ++ if (cond)
19224 ++ __rlim_rmax(limit, res) = value;
19225 ++ return cond;
19226 ++}
19227 ++
19228 ++static inline
19229 ++int __vx_cres_adjust_min(struct _vx_limit *limit, int res, rlim_t value)
19230 ++{
19231 ++ int cond = (value < __rlim_rmin(limit, res));
19232 ++
19233 ++ if (cond)
19234 ++ __rlim_rmin(limit, res) = value;
19235 ++ return cond;
19236 ++}
19237 ++
19238 ++static inline
19239 ++void __vx_cres_fixup(struct _vx_limit *limit, int res, rlim_t value)
19240 ++{
19241 ++ if (!__vx_cres_adjust_max(limit, res, value))
19242 ++ __vx_cres_adjust_min(limit, res, value);
19243 ++}
19244 ++
19245 ++
19246 ++/* return values:
19247 ++ +1 ... no limit hit
19248 ++ -1 ... over soft limit
19249 ++ 0 ... over hard limit */
19250 ++
19251 ++static inline int __vx_cres_avail(struct vx_info *vxi,
19252 ++ int res, int num, char *_file, int _line)
19253 ++{
19254 ++ struct _vx_limit *limit;
19255 ++ rlim_t value;
19256 ++
19257 ++ if (VXD_RLIMIT_COND(res))
19258 ++ vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld/%5ld > %5ld + %5d",
19259 ++ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
19260 ++ (vxi ? (long)__rlim_soft(&vxi->limit, res) : -1),
19261 ++ (vxi ? (long)__rlim_hard(&vxi->limit, res) : -1),
19262 ++ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
19263 ++ num, _file, _line);
19264 ++ if (!vxi)
19265 ++ return 1;
19266 ++
19267 ++ limit = &vxi->limit;
19268 ++ value = __rlim_get(limit, res);
19269 ++
19270 ++ if (!__vx_cres_adjust_max(limit, res, value))
19271 ++ __vx_cres_adjust_min(limit, res, value);
19272 ++
19273 ++ if (num == 0)
19274 ++ return 1;
19275 ++
19276 ++ if (__rlim_soft(limit, res) == RLIM_INFINITY)
19277 ++ return -1;
19278 ++ if (value + num <= __rlim_soft(limit, res))
19279 ++ return -1;
19280 ++
19281 ++ if (__rlim_hard(limit, res) == RLIM_INFINITY)
19282 ++ return 1;
19283 ++ if (value + num <= __rlim_hard(limit, res))
19284 ++ return 1;
19285 ++
19286 ++ __rlim_hit(limit, res);
19287 ++ return 0;
19288 ++}
19289 ++
19290 ++
19291 ++static const int VLA_RSS[] = { RLIMIT_RSS, VLIMIT_ANON, VLIMIT_MAPPED, 0 };
19292 ++
19293 ++static inline
19294 ++rlim_t __vx_cres_array_sum(struct _vx_limit *limit, const int *array)
19295 ++{
19296 ++ rlim_t value, sum = 0;
19297 ++ int res;
19298 ++
19299 ++ while ((res = *array++)) {
19300 ++ value = __rlim_get(limit, res);
19301 ++ __vx_cres_fixup(limit, res, value);
19302 ++ sum += value;
19303 ++ }
19304 ++ return sum;
19305 ++}
19306 ++
19307 ++static inline
19308 ++rlim_t __vx_cres_array_fixup(struct _vx_limit *limit, const int *array)
19309 ++{
19310 ++ rlim_t value = __vx_cres_array_sum(limit, array + 1);
19311 ++ int res = *array;
19312 ++
19313 ++ if (value == __rlim_get(limit, res))
19314 ++ return value;
19315 ++
19316 ++ __rlim_set(limit, res, value);
19317 ++ /* now adjust min/max */
19318 ++ if (!__vx_cres_adjust_max(limit, res, value))
19319 ++ __vx_cres_adjust_min(limit, res, value);
19320 ++
19321 ++ return value;
19322 ++}
19323 ++
19324 ++static inline int __vx_cres_array_avail(struct vx_info *vxi,
19325 ++ const int *array, int num, char *_file, int _line)
19326 ++{
19327 ++ struct _vx_limit *limit;
19328 ++ rlim_t value = 0;
19329 ++ int res;
19330 ++
19331 ++ if (num == 0)
19332 ++ return 1;
19333 ++ if (!vxi)
19334 ++ return 1;
19335 ++
19336 ++ limit = &vxi->limit;
19337 ++ res = *array;
19338 ++ value = __vx_cres_array_sum(limit, array + 1);
19339 ++
19340 ++ __rlim_set(limit, res, value);
19341 ++ __vx_cres_fixup(limit, res, value);
19342 ++
19343 ++ return __vx_cres_avail(vxi, res, num, _file, _line);
19344 ++}
19345 ++
19346 ++
19347 ++static inline void vx_limit_fixup(struct _vx_limit *limit, int id)
19348 ++{
19349 ++ rlim_t value;
19350 ++ int res;
19351 ++
19352 ++ /* complex resources first */
19353 ++ if ((id < 0) || (id == RLIMIT_RSS))
19354 ++ __vx_cres_array_fixup(limit, VLA_RSS);
19355 ++
19356 ++ for (res = 0; res < NUM_LIMITS; res++) {
19357 ++ if ((id > 0) && (res != id))
19358 ++ continue;
19359 ++
19360 ++ value = __rlim_get(limit, res);
19361 ++ __vx_cres_fixup(limit, res, value);
19362 ++
19363 ++ /* not supposed to happen, maybe warn? */
19364 ++ if (__rlim_rmax(limit, res) > __rlim_hard(limit, res))
19365 ++ __rlim_rmax(limit, res) = __rlim_hard(limit, res);
19366 ++ }
19367 ++}
19368 ++
19369 ++
19370 ++#endif /* __KERNEL__ */
19371 ++#endif /* _VX_LIMIT_INT_H */
19372 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/monitor.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/monitor.h
19373 +--- linux-2.6.22.19/include/linux/vserver/monitor.h 1970-01-01 01:00:00 +0100
19374 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/monitor.h 2007-06-15 02:37:04 +0200
19375 +@@ -0,0 +1,95 @@
19376 ++#ifndef _VX_MONITOR_H
19377 ++#define _VX_MONITOR_H
19378 ++
19379 ++
19380 ++enum {
19381 ++ VXM_UNUSED = 0,
19382 ++
19383 ++ VXM_SYNC = 0x10,
19384 ++
19385 ++ VXM_UPDATE = 0x20,
19386 ++ VXM_UPDATE_1,
19387 ++ VXM_UPDATE_2,
19388 ++
19389 ++ VXM_RQINFO_1 = 0x24,
19390 ++ VXM_RQINFO_2,
19391 ++
19392 ++ VXM_ACTIVATE = 0x40,
19393 ++ VXM_DEACTIVATE,
19394 ++ VXM_IDLE,
19395 ++
19396 ++ VXM_HOLD = 0x44,
19397 ++ VXM_UNHOLD,
19398 ++
19399 ++ VXM_MIGRATE = 0x48,
19400 ++ VXM_RESCHED,
19401 ++
19402 ++ /* all other bits are flags */
19403 ++ VXM_SCHED = 0x80,
19404 ++};
19405 ++
19406 ++struct _vxm_update_1 {
19407 ++ uint32_t tokens_max;
19408 ++ uint32_t fill_rate;
19409 ++ uint32_t interval;
19410 ++};
19411 ++
19412 ++struct _vxm_update_2 {
19413 ++ uint32_t tokens_min;
19414 ++ uint32_t fill_rate;
19415 ++ uint32_t interval;
19416 ++};
19417 ++
19418 ++struct _vxm_rqinfo_1 {
19419 ++ uint16_t running;
19420 ++ uint16_t onhold;
19421 ++ uint16_t iowait;
19422 ++ uint16_t uintr;
19423 ++ uint32_t idle_tokens;
19424 ++};
19425 ++
19426 ++struct _vxm_rqinfo_2 {
19427 ++ uint32_t norm_time;
19428 ++ uint32_t idle_time;
19429 ++ uint32_t idle_skip;
19430 ++};
19431 ++
19432 ++struct _vxm_sched {
19433 ++ uint32_t tokens;
19434 ++ uint32_t norm_time;
19435 ++ uint32_t idle_time;
19436 ++};
19437 ++
19438 ++struct _vxm_task {
19439 ++ uint16_t pid;
19440 ++ uint16_t state;
19441 ++};
19442 ++
19443 ++struct _vxm_event {
19444 ++ uint32_t jif;
19445 ++ union {
19446 ++ uint32_t seq;
19447 ++ uint32_t sec;
19448 ++ };
19449 ++ union {
19450 ++ uint32_t tokens;
19451 ++ uint32_t nsec;
19452 ++ struct _vxm_task tsk;
19453 ++ };
19454 ++};
19455 ++
19456 ++struct _vx_mon_entry {
19457 ++ uint16_t type;
19458 ++ uint16_t xid;
19459 ++ union {
19460 ++ struct _vxm_event ev;
19461 ++ struct _vxm_sched sd;
19462 ++ struct _vxm_update_1 u1;
19463 ++ struct _vxm_update_2 u2;
19464 ++ struct _vxm_rqinfo_1 q1;
19465 ++ struct _vxm_rqinfo_2 q2;
19466 ++ };
19467 ++};
19468 ++
19469 ++
19470 ++#endif /* _VX_MONITOR_H */
19471 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/network.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/network.h
19472 +--- linux-2.6.22.19/include/linux/vserver/network.h 1970-01-01 01:00:00 +0100
19473 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/network.h 2007-06-15 02:37:04 +0200
19474 +@@ -0,0 +1,142 @@
19475 ++#ifndef _VX_NETWORK_H
19476 ++#define _VX_NETWORK_H
19477 ++
19478 ++#include <linux/types.h>
19479 ++
19480 ++
19481 ++#define MAX_N_CONTEXT 65535 /* Arbitrary limit */
19482 ++
19483 ++#define NX_DYNAMIC_ID ((uint32_t)-1) /* id for dynamic context */
19484 ++
19485 ++#define NB_IPV4ROOT 16
19486 ++
19487 ++
19488 ++/* network flags */
19489 ++
19490 ++#define NXF_INFO_PRIVATE 0x00000008
19491 ++
19492 ++#define NXF_STATE_SETUP (1ULL << 32)
19493 ++#define NXF_STATE_ADMIN (1ULL << 34)
19494 ++
19495 ++#define NXF_SC_HELPER (1ULL << 36)
19496 ++#define NXF_PERSISTENT (1ULL << 38)
19497 ++
19498 ++#define NXF_ONE_TIME (0x0005ULL << 32)
19499 ++
19500 ++#define NXF_INIT_SET (NXF_STATE_ADMIN)
19501 ++
19502 ++
19503 ++/* address types */
19504 ++
19505 ++#define NXA_TYPE_IPV4 1
19506 ++#define NXA_TYPE_IPV6 2
19507 ++
19508 ++#define NXA_MOD_BCAST (1 << 8)
19509 ++
19510 ++#define NXA_TYPE_ANY ((uint16_t)-1)
19511 ++
19512 ++
19513 ++#ifdef __KERNEL__
19514 ++
19515 ++#include <linux/list.h>
19516 ++#include <linux/spinlock.h>
19517 ++#include <linux/rcupdate.h>
19518 ++#include <asm/atomic.h>
19519 ++
19520 ++
19521 ++struct nx_info {
19522 ++ struct hlist_node nx_hlist; /* linked list of nxinfos */
19523 ++ nid_t nx_id; /* vnet id */
19524 ++ atomic_t nx_usecnt; /* usage count */
19525 ++ atomic_t nx_tasks; /* tasks count */
19526 ++ int nx_state; /* context state */
19527 ++
19528 ++ uint64_t nx_flags; /* network flag word */
19529 ++ uint64_t nx_ncaps; /* network capabilities */
19530 ++
19531 ++ int nbipv4;
19532 ++ __u32 ipv4[NB_IPV4ROOT]; /* Process can only bind to these IPs */
19533 ++ /* The first one is used to connect */
19534 ++ /* and for bind any service */
19535 ++ /* The other must be used explicity */
19536 ++ __u32 mask[NB_IPV4ROOT]; /* Netmask for each ipv4 */
19537 ++ /* Used to select the proper source */
19538 ++ /* address for sockets */
19539 ++ __u32 v4_bcast; /* Broadcast address to receive UDP */
19540 ++
19541 ++ char nx_name[65]; /* network context name */
19542 ++};
19543 ++
19544 ++
19545 ++/* status flags */
19546 ++
19547 ++#define NXS_HASHED 0x0001
19548 ++#define NXS_SHUTDOWN 0x0100
19549 ++#define NXS_RELEASED 0x8000
19550 ++
19551 ++/* check conditions */
19552 ++
19553 ++#define NX_ADMIN 0x0001
19554 ++#define NX_WATCH 0x0002
19555 ++#define NX_BLEND 0x0004
19556 ++#define NX_HOSTID 0x0008
19557 ++
19558 ++#define NX_IDENT 0x0010
19559 ++#define NX_EQUIV 0x0020
19560 ++#define NX_PARENT 0x0040
19561 ++#define NX_CHILD 0x0080
19562 ++
19563 ++#define NX_ARG_MASK 0x00F0
19564 ++
19565 ++#define NX_DYNAMIC 0x0100
19566 ++#define NX_STATIC 0x0200
19567 ++
19568 ++#define NX_ATR_MASK 0x0F00
19569 ++
19570 ++
19571 ++extern struct nx_info *lookup_nx_info(int);
19572 ++
19573 ++extern int get_nid_list(int, unsigned int *, int);
19574 ++extern int nid_is_hashed(nid_t);
19575 ++
19576 ++extern int nx_migrate_task(struct task_struct *, struct nx_info *);
19577 ++
19578 ++extern long vs_net_change(struct nx_info *, unsigned int);
19579 ++
19580 ++struct in_ifaddr;
19581 ++struct net_device;
19582 ++
19583 ++#ifdef CONFIG_INET
19584 ++int ifa_in_nx_info(struct in_ifaddr *, struct nx_info *);
19585 ++int dev_in_nx_info(struct net_device *, struct nx_info *);
19586 ++
19587 ++#else /* CONFIG_INET */
19588 ++static inline
19589 ++int ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
19590 ++{
19591 ++ return 1;
19592 ++}
19593 ++
19594 ++static inline
19595 ++int dev_in_nx_info(struct net_device *d, struct nx_info *n)
19596 ++{
19597 ++ return 1;
19598 ++}
19599 ++#endif /* CONFIG_INET */
19600 ++
19601 ++struct sock;
19602 ++
19603 ++#ifdef CONFIG_INET
19604 ++int nx_addr_conflict(struct nx_info *, uint32_t, const struct sock *);
19605 ++#else /* CONFIG_INET */
19606 ++static inline
19607 ++int nx_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
19608 ++{
19609 ++ return 1;
19610 ++}
19611 ++#endif /* CONFIG_INET */
19612 ++
19613 ++#endif /* __KERNEL__ */
19614 ++#else /* _VX_NETWORK_H */
19615 ++#warning duplicate inclusion
19616 ++#endif /* _VX_NETWORK_H */
19617 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/network_cmd.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/network_cmd.h
19618 +--- linux-2.6.22.19/include/linux/vserver/network_cmd.h 1970-01-01 01:00:00 +0100
19619 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/network_cmd.h 2007-06-15 02:37:04 +0200
19620 +@@ -0,0 +1,89 @@
19621 ++#ifndef _VX_NETWORK_CMD_H
19622 ++#define _VX_NETWORK_CMD_H
19623 ++
19624 ++
19625 ++/* vinfo commands */
19626 ++
19627 ++#define VCMD_task_nid VC_CMD(VINFO, 2, 0)
19628 ++
19629 ++#ifdef __KERNEL__
19630 ++extern int vc_task_nid(uint32_t, void __user *);
19631 ++
19632 ++#endif /* __KERNEL__ */
19633 ++
19634 ++#define VCMD_nx_info VC_CMD(VINFO, 6, 0)
19635 ++
19636 ++struct vcmd_nx_info_v0 {
19637 ++ uint32_t nid;
19638 ++ /* more to come */
19639 ++};
19640 ++
19641 ++#ifdef __KERNEL__
19642 ++extern int vc_nx_info(struct nx_info *, void __user *);
19643 ++
19644 ++#endif /* __KERNEL__ */
19645 ++
19646 ++#define VCMD_net_create_v0 VC_CMD(VNET, 1, 0)
19647 ++#define VCMD_net_create VC_CMD(VNET, 1, 1)
19648 ++
19649 ++struct vcmd_net_create {
19650 ++ uint64_t flagword;
19651 ++};
19652 ++
19653 ++#define VCMD_net_migrate VC_CMD(NETMIG, 1, 0)
19654 ++
19655 ++#define VCMD_net_add VC_CMD(NETALT, 1, 0)
19656 ++#define VCMD_net_remove VC_CMD(NETALT, 2, 0)
19657 ++
19658 ++struct vcmd_net_addr_v0 {
19659 ++ uint16_t type;
19660 ++ uint16_t count;
19661 ++ uint32_t ip[4];
19662 ++ uint32_t mask[4];
19663 ++ /* more to come */
19664 ++};
19665 ++
19666 ++
19667 ++#ifdef __KERNEL__
19668 ++extern int vc_net_create(uint32_t, void __user *);
19669 ++extern int vc_net_migrate(struct nx_info *, void __user *);
19670 ++
19671 ++extern int vc_net_add(struct nx_info *, void __user *);
19672 ++extern int vc_net_remove(struct nx_info *, void __user *);
19673 ++
19674 ++#endif /* __KERNEL__ */
19675 ++
19676 ++
19677 ++/* flag commands */
19678 ++
19679 ++#define VCMD_get_nflags VC_CMD(FLAGS, 5, 0)
19680 ++#define VCMD_set_nflags VC_CMD(FLAGS, 6, 0)
19681 ++
19682 ++struct vcmd_net_flags_v0 {
19683 ++ uint64_t flagword;
19684 ++ uint64_t mask;
19685 ++};
19686 ++
19687 ++#ifdef __KERNEL__
19688 ++extern int vc_get_nflags(struct nx_info *, void __user *);
19689 ++extern int vc_set_nflags(struct nx_info *, void __user *);
19690 ++
19691 ++#endif /* __KERNEL__ */
19692 ++
19693 ++
19694 ++/* network caps commands */
19695 ++
19696 ++#define VCMD_get_ncaps VC_CMD(FLAGS, 7, 0)
19697 ++#define VCMD_set_ncaps VC_CMD(FLAGS, 8, 0)
19698 ++
19699 ++struct vcmd_net_caps_v0 {
19700 ++ uint64_t ncaps;
19701 ++ uint64_t cmask;
19702 ++};
19703 ++
19704 ++#ifdef __KERNEL__
19705 ++extern int vc_get_ncaps(struct nx_info *, void __user *);
19706 ++extern int vc_set_ncaps(struct nx_info *, void __user *);
19707 ++
19708 ++#endif /* __KERNEL__ */
19709 ++#endif /* _VX_CONTEXT_CMD_H */
19710 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/percpu.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/percpu.h
19711 +--- linux-2.6.22.19/include/linux/vserver/percpu.h 1970-01-01 01:00:00 +0100
19712 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/percpu.h 2007-06-15 02:37:04 +0200
19713 +@@ -0,0 +1,14 @@
19714 ++#ifndef _VX_PERCPU_H
19715 ++#define _VX_PERCPU_H
19716 ++
19717 ++#include "cvirt_def.h"
19718 ++#include "sched_def.h"
19719 ++
19720 ++struct _vx_percpu {
19721 ++ struct _vx_cvirt_pc cvirt;
19722 ++ struct _vx_sched_pc sched;
19723 ++};
19724 ++
19725 ++#define PERCPU_PERCTX (sizeof(struct _vx_percpu))
19726 ++
19727 ++#endif /* _VX_PERCPU_H */
19728 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/sched.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/sched.h
19729 +--- linux-2.6.22.19/include/linux/vserver/sched.h 1970-01-01 01:00:00 +0100
19730 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/sched.h 2007-06-15 02:37:04 +0200
19731 +@@ -0,0 +1,26 @@
19732 ++#ifndef _VX_SCHED_H
19733 ++#define _VX_SCHED_H
19734 ++
19735 ++
19736 ++#ifdef __KERNEL__
19737 ++
19738 ++struct timespec;
19739 ++
19740 ++void vx_vsi_uptime(struct timespec *, struct timespec *);
19741 ++
19742 ++
19743 ++struct vx_info;
19744 ++
19745 ++void vx_update_load(struct vx_info *);
19746 ++
19747 ++
19748 ++int vx_tokens_recalc(struct _vx_sched_pc *,
19749 ++ unsigned long *, unsigned long *, int [2]);
19750 ++
19751 ++void vx_update_sched_param(struct _vx_sched *sched,
19752 ++ struct _vx_sched_pc *sched_pc);
19753 ++
19754 ++#endif /* __KERNEL__ */
19755 ++#else /* _VX_SCHED_H */
19756 ++#warning duplicate inclusion
19757 ++#endif /* _VX_SCHED_H */
19758 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/sched_cmd.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/sched_cmd.h
19759 +--- linux-2.6.22.19/include/linux/vserver/sched_cmd.h 1970-01-01 01:00:00 +0100
19760 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/sched_cmd.h 2007-06-15 02:37:04 +0200
19761 +@@ -0,0 +1,108 @@
19762 ++#ifndef _VX_SCHED_CMD_H
19763 ++#define _VX_SCHED_CMD_H
19764 ++
19765 ++
19766 ++/* sched vserver commands */
19767 ++
19768 ++#define VCMD_set_sched_v2 VC_CMD(SCHED, 1, 2)
19769 ++#define VCMD_set_sched_v3 VC_CMD(SCHED, 1, 3)
19770 ++#define VCMD_set_sched_v4 VC_CMD(SCHED, 1, 4)
19771 ++
19772 ++struct vcmd_set_sched_v2 {
19773 ++ int32_t fill_rate;
19774 ++ int32_t interval;
19775 ++ int32_t tokens;
19776 ++ int32_t tokens_min;
19777 ++ int32_t tokens_max;
19778 ++ uint64_t cpu_mask;
19779 ++};
19780 ++
19781 ++struct vcmd_set_sched_v3 {
19782 ++ uint32_t set_mask;
19783 ++ int32_t fill_rate;
19784 ++ int32_t interval;
19785 ++ int32_t tokens;
19786 ++ int32_t tokens_min;
19787 ++ int32_t tokens_max;
19788 ++ int32_t priority_bias;
19789 ++};
19790 ++
19791 ++struct vcmd_set_sched_v4 {
19792 ++ uint32_t set_mask;
19793 ++ int32_t fill_rate;
19794 ++ int32_t interval;
19795 ++ int32_t tokens;
19796 ++ int32_t tokens_min;
19797 ++ int32_t tokens_max;
19798 ++ int32_t prio_bias;
19799 ++ int32_t cpu_id;
19800 ++ int32_t bucket_id;
19801 ++};
19802 ++
19803 ++#define VCMD_set_sched VC_CMD(SCHED, 1, 5)
19804 ++#define VCMD_get_sched VC_CMD(SCHED, 2, 5)
19805 ++
19806 ++struct vcmd_sched_v5 {
19807 ++ uint32_t mask;
19808 ++ int32_t cpu_id;
19809 ++ int32_t bucket_id;
19810 ++ int32_t fill_rate[2];
19811 ++ int32_t interval[2];
19812 ++ int32_t tokens;
19813 ++ int32_t tokens_min;
19814 ++ int32_t tokens_max;
19815 ++ int32_t prio_bias;
19816 ++};
19817 ++
19818 ++#define VXSM_FILL_RATE 0x0001
19819 ++#define VXSM_INTERVAL 0x0002
19820 ++#define VXSM_FILL_RATE2 0x0004
19821 ++#define VXSM_INTERVAL2 0x0008
19822 ++#define VXSM_TOKENS 0x0010
19823 ++#define VXSM_TOKENS_MIN 0x0020
19824 ++#define VXSM_TOKENS_MAX 0x0040
19825 ++#define VXSM_PRIO_BIAS 0x0100
19826 ++
19827 ++#define VXSM_IDLE_TIME 0x0200
19828 ++#define VXSM_FORCE 0x0400
19829 ++
19830 ++#define VXSM_V3_MASK 0x0173
19831 ++#define VXSM_SET_MASK 0x01FF
19832 ++
19833 ++#define VXSM_CPU_ID 0x1000
19834 ++#define VXSM_BUCKET_ID 0x2000
19835 ++
19836 ++#define VXSM_MSEC 0x4000
19837 ++
19838 ++#define SCHED_KEEP (-2) /* only for v2 */
19839 ++
19840 ++#ifdef __KERNEL__
19841 ++
19842 ++#include <linux/compiler.h>
19843 ++
19844 ++extern int vc_set_sched_v2(struct vx_info *, void __user *);
19845 ++extern int vc_set_sched_v3(struct vx_info *, void __user *);
19846 ++extern int vc_set_sched_v4(struct vx_info *, void __user *);
19847 ++extern int vc_set_sched(struct vx_info *, void __user *);
19848 ++extern int vc_get_sched(struct vx_info *, void __user *);
19849 ++
19850 ++#endif /* __KERNEL__ */
19851 ++
19852 ++#define VCMD_sched_info VC_CMD(SCHED, 3, 0)
19853 ++
19854 ++struct vcmd_sched_info {
19855 ++ int32_t cpu_id;
19856 ++ int32_t bucket_id;
19857 ++ uint64_t user_msec;
19858 ++ uint64_t sys_msec;
19859 ++ uint64_t hold_msec;
19860 ++ uint32_t token_usec;
19861 ++ int32_t vavavoom;
19862 ++};
19863 ++
19864 ++#ifdef __KERNEL__
19865 ++
19866 ++extern int vc_sched_info(struct vx_info *, void __user *);
19867 ++
19868 ++#endif /* __KERNEL__ */
19869 ++#endif /* _VX_SCHED_CMD_H */
19870 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/sched_def.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/sched_def.h
19871 +--- linux-2.6.22.19/include/linux/vserver/sched_def.h 1970-01-01 01:00:00 +0100
19872 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/sched_def.h 2007-06-15 02:37:04 +0200
19873 +@@ -0,0 +1,68 @@
19874 ++#ifndef _VX_SCHED_DEF_H
19875 ++#define _VX_SCHED_DEF_H
19876 ++
19877 ++#include <linux/spinlock.h>
19878 ++#include <linux/jiffies.h>
19879 ++#include <linux/cpumask.h>
19880 ++#include <asm/atomic.h>
19881 ++#include <asm/param.h>
19882 ++
19883 ++
19884 ++/* context sub struct */
19885 ++
19886 ++struct _vx_sched {
19887 ++ spinlock_t tokens_lock; /* lock for token bucket */
19888 ++
19889 ++ int tokens; /* number of CPU tokens */
19890 ++ int fill_rate[2]; /* Fill rate: add X tokens... */
19891 ++ int interval[2]; /* Divisor: per Y jiffies */
19892 ++ int tokens_min; /* Limit: minimum for unhold */
19893 ++ int tokens_max; /* Limit: no more than N tokens */
19894 ++
19895 ++ int prio_bias; /* bias offset for priority */
19896 ++
19897 ++ unsigned update_mask; /* which features should be updated */
19898 ++ cpumask_t update; /* CPUs which should update */
19899 ++};
19900 ++
19901 ++struct _vx_sched_pc {
19902 ++ int tokens; /* number of CPU tokens */
19903 ++ int flags; /* bucket flags */
19904 ++
19905 ++ int fill_rate[2]; /* Fill rate: add X tokens... */
19906 ++ int interval[2]; /* Divisor: per Y jiffies */
19907 ++ int tokens_min; /* Limit: minimum for unhold */
19908 ++ int tokens_max; /* Limit: no more than N tokens */
19909 ++
19910 ++ int prio_bias; /* bias offset for priority */
19911 ++ int vavavoom; /* last calculated vavavoom */
19912 ++
19913 ++ unsigned long norm_time; /* last time accounted */
19914 ++ unsigned long idle_time; /* non linear time for fair sched */
19915 ++ unsigned long token_time; /* token time for accounting */
19916 ++ unsigned long onhold; /* jiffies when put on hold */
19917 ++
19918 ++ uint64_t user_ticks; /* token tick events */
19919 ++ uint64_t sys_ticks; /* token tick events */
19920 ++ uint64_t hold_ticks; /* token ticks paused */
19921 ++};
19922 ++
19923 ++
19924 ++#define VXSF_ONHOLD 0x0001
19925 ++#define VXSF_IDLE_TIME 0x0100
19926 ++
19927 ++#ifdef CONFIG_VSERVER_DEBUG
19928 ++
19929 ++static inline void __dump_vx_sched(struct _vx_sched *sched)
19930 ++{
19931 ++ printk("\t_vx_sched:\n");
19932 ++ printk("\t tokens: %4d/%4d, %4d/%4d, %4d, %4d\n",
19933 ++ sched->fill_rate[0], sched->interval[0],
19934 ++ sched->fill_rate[1], sched->interval[1],
19935 ++ sched->tokens_min, sched->tokens_max);
19936 ++ printk("\t priority = %4d\n", sched->prio_bias);
19937 ++}
19938 ++
19939 ++#endif
19940 ++
19941 ++#endif /* _VX_SCHED_DEF_H */
19942 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/signal.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/signal.h
19943 +--- linux-2.6.22.19/include/linux/vserver/signal.h 1970-01-01 01:00:00 +0100
19944 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/signal.h 2007-06-15 02:37:04 +0200
19945 +@@ -0,0 +1,14 @@
19946 ++#ifndef _VX_SIGNAL_H
19947 ++#define _VX_SIGNAL_H
19948 ++
19949 ++
19950 ++#ifdef __KERNEL__
19951 ++
19952 ++struct vx_info;
19953 ++
19954 ++int vx_info_kill(struct vx_info *, int, int);
19955 ++
19956 ++#endif /* __KERNEL__ */
19957 ++#else /* _VX_SIGNAL_H */
19958 ++#warning duplicate inclusion
19959 ++#endif /* _VX_SIGNAL_H */
19960 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/signal_cmd.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/signal_cmd.h
19961 +--- linux-2.6.22.19/include/linux/vserver/signal_cmd.h 1970-01-01 01:00:00 +0100
19962 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/signal_cmd.h 2007-06-15 02:37:04 +0200
19963 +@@ -0,0 +1,43 @@
19964 ++#ifndef _VX_SIGNAL_CMD_H
19965 ++#define _VX_SIGNAL_CMD_H
19966 ++
19967 ++
19968 ++/* signalling vserver commands */
19969 ++
19970 ++#define VCMD_ctx_kill VC_CMD(PROCTRL, 1, 0)
19971 ++#define VCMD_wait_exit VC_CMD(EVENT, 99, 0)
19972 ++
19973 ++struct vcmd_ctx_kill_v0 {
19974 ++ int32_t pid;
19975 ++ int32_t sig;
19976 ++};
19977 ++
19978 ++struct vcmd_wait_exit_v0 {
19979 ++ int32_t reboot_cmd;
19980 ++ int32_t exit_code;
19981 ++};
19982 ++
19983 ++#ifdef __KERNEL__
19984 ++
19985 ++extern int vc_ctx_kill(struct vx_info *, void __user *);
19986 ++extern int vc_wait_exit(struct vx_info *, void __user *);
19987 ++
19988 ++#endif /* __KERNEL__ */
19989 ++
19990 ++/* process alteration commands */
19991 ++
19992 ++#define VCMD_get_pflags VC_CMD(PROCALT, 5, 0)
19993 ++#define VCMD_set_pflags VC_CMD(PROCALT, 6, 0)
19994 ++
19995 ++struct vcmd_pflags_v0 {
19996 ++ uint32_t flagword;
19997 ++ uint32_t mask;
19998 ++};
19999 ++
20000 ++#ifdef __KERNEL__
20001 ++
20002 ++extern int vc_get_pflags(uint32_t pid, void __user *);
20003 ++extern int vc_set_pflags(uint32_t pid, void __user *);
20004 ++
20005 ++#endif /* __KERNEL__ */
20006 ++#endif /* _VX_SIGNAL_CMD_H */
20007 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/space.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/space.h
20008 +--- linux-2.6.22.19/include/linux/vserver/space.h 1970-01-01 01:00:00 +0100
20009 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/space.h 2007-06-15 02:37:04 +0200
20010 +@@ -0,0 +1,13 @@
20011 ++#ifndef _VX_SPACE_H
20012 ++#define _VX_SPACE_H
20013 ++
20014 ++
20015 ++#include <linux/types.h>
20016 ++
20017 ++struct vx_info;
20018 ++
20019 ++int vx_set_space(struct vx_info *vxi, unsigned long mask);
20020 ++
20021 ++#else /* _VX_SPACE_H */
20022 ++#warning duplicate inclusion
20023 ++#endif /* _VX_SPACE_H */
20024 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/space_cmd.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/space_cmd.h
20025 +--- linux-2.6.22.19/include/linux/vserver/space_cmd.h 1970-01-01 01:00:00 +0100
20026 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/space_cmd.h 2007-06-15 02:37:04 +0200
20027 +@@ -0,0 +1,26 @@
20028 ++#ifndef _VX_SPACE_CMD_H
20029 ++#define _VX_SPACE_CMD_H
20030 ++
20031 ++
20032 ++#define VCMD_enter_space_v0 VC_CMD(PROCALT, 1, 0)
20033 ++#define VCMD_enter_space VC_CMD(PROCALT, 1, 1)
20034 ++
20035 ++#define VCMD_set_space_v0 VC_CMD(PROCALT, 3, 0)
20036 ++#define VCMD_set_space VC_CMD(PROCALT, 3, 1)
20037 ++
20038 ++#define VCMD_get_space_mask VC_CMD(PROCALT, 4, 0)
20039 ++
20040 ++
20041 ++struct vcmd_space_mask {
20042 ++ uint64_t mask;
20043 ++};
20044 ++
20045 ++
20046 ++#ifdef __KERNEL__
20047 ++
20048 ++extern int vc_enter_space(struct vx_info *, void __user *);
20049 ++extern int vc_set_space(struct vx_info *, void __user *);
20050 ++extern int vc_get_space_mask(struct vx_info *, void __user *);
20051 ++
20052 ++#endif /* __KERNEL__ */
20053 ++#endif /* _VX_SPACE_CMD_H */
20054 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/switch.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/switch.h
20055 +--- linux-2.6.22.19/include/linux/vserver/switch.h 1970-01-01 01:00:00 +0100
20056 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/switch.h 2007-06-15 02:37:04 +0200
20057 +@@ -0,0 +1,95 @@
20058 ++#ifndef _VX_SWITCH_H
20059 ++#define _VX_SWITCH_H
20060 ++
20061 ++#include <linux/types.h>
20062 ++
20063 ++
20064 ++#define VC_CATEGORY(c) (((c) >> 24) & 0x3F)
20065 ++#define VC_COMMAND(c) (((c) >> 16) & 0xFF)
20066 ++#define VC_VERSION(c) ((c) & 0xFFF)
20067 ++
20068 ++#define VC_CMD(c, i, v) ((((VC_CAT_ ## c) & 0x3F) << 24) \
20069 ++ | (((i) & 0xFF) << 16) | ((v) & 0xFFF))
20070 ++
20071 ++/*
20072 ++
20073 ++ Syscall Matrix V2.8
20074 ++
20075 ++ |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|
20076 ++ |STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | |
20077 ++ |INFO |SETUP | |MOVE | | | | | |
20078 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
20079 ++ SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICES| |
20080 ++ HOST | 00| 01| 02| 03| 04| 05| | 06| 07|
20081 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
20082 ++ CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | |
20083 ++ PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15|
20084 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
20085 ++ MEMORY | | | | | | | |SWAP | |
20086 ++ | 16| 17| 18| 19| 20| 21| | 22| 23|
20087 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
20088 ++ NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | |
20089 ++ | 24| 25| 26| 27| 28| 29| | 30| 31|
20090 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
20091 ++ DISK | | | | |DLIMIT | | |INODE | |
20092 ++ VFS | 32| 33| 34| 35| 36| 37| | 38| 39|
20093 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
20094 ++ OTHER |VSTAT | | | | | | |VINFO | |
20095 ++ | 40| 41| 42| 43| 44| 45| | 46| 47|
20096 ++ =======+=======+=======+=======+=======+=======+=======+ +=======+=======+
20097 ++ SPECIAL|EVENT | | | |FLAGS | | | | |
20098 ++ | 48| 49| 50| 51| 52| 53| | 54| 55|
20099 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
20100 ++ SPECIAL|DEBUG | | | |RLIMIT |SYSCALL| | |COMPAT |
20101 ++ | 56| 57| 58| 59| 60|TEST 61| | 62| 63|
20102 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
20103 ++
20104 ++*/
20105 ++
20106 ++#define VC_CAT_VERSION 0
20107 ++
20108 ++#define VC_CAT_VSETUP 1
20109 ++#define VC_CAT_VHOST 2
20110 ++
20111 ++#define VC_CAT_VPROC 9
20112 ++#define VC_CAT_PROCALT 10
20113 ++#define VC_CAT_PROCMIG 11
20114 ++#define VC_CAT_PROCTRL 12
20115 ++
20116 ++#define VC_CAT_SCHED 14
20117 ++
20118 ++#define VC_CAT_VNET 25
20119 ++#define VC_CAT_NETALT 26
20120 ++#define VC_CAT_NETMIG 27
20121 ++#define VC_CAT_NETCTRL 28
20122 ++
20123 ++#define VC_CAT_DLIMIT 36
20124 ++#define VC_CAT_INODE 38
20125 ++
20126 ++#define VC_CAT_VSTAT 40
20127 ++#define VC_CAT_VINFO 46
20128 ++#define VC_CAT_EVENT 48
20129 ++
20130 ++#define VC_CAT_FLAGS 52
20131 ++#define VC_CAT_DEBUG 56
20132 ++#define VC_CAT_RLIMIT 60
20133 ++
20134 ++#define VC_CAT_SYSTEST 61
20135 ++#define VC_CAT_COMPAT 63
20136 ++
20137 ++/* query version */
20138 ++
20139 ++#define VCMD_get_version VC_CMD(VERSION, 0, 0)
20140 ++#define VCMD_get_vci VC_CMD(VERSION, 1, 0)
20141 ++
20142 ++
20143 ++#ifdef __KERNEL__
20144 ++
20145 ++#include <linux/errno.h>
20146 ++
20147 ++
20148 ++#else /* __KERNEL__ */
20149 ++#define __user
20150 ++#endif /* __KERNEL__ */
20151 ++
20152 ++#endif /* _VX_SWITCH_H */
20153 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/tag.h linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/tag.h
20154 +--- linux-2.6.22.19/include/linux/vserver/tag.h 1970-01-01 01:00:00 +0100
20155 ++++ linux-2.6.22.19-vs2.2.0.7/include/linux/vserver/tag.h 2007-06-15 02:37:04 +0200
20156 +@@ -0,0 +1,140 @@
20157 ++#ifndef _DX_TAG_H
20158 ++#define _DX_TAG_H
20159 ++
20160 ++
20161 ++#define DX_TAG(in) (IS_TAGGED(in))
20162 ++
20163 ++
20164 ++#ifdef CONFIG_DX_TAG_NFSD
20165 ++#define DX_TAG_NFSD 1
20166 ++#else
20167 ++#define DX_TAG_NFSD 0
20168 ++#endif
20169 ++
20170 ++
20171 ++#ifdef CONFIG_TAGGING_NONE
20172 ++
20173 ++#define MAX_UID 0xFFFFFFFF
20174 ++#define MAX_GID 0xFFFFFFFF
20175 ++
20176 ++#define INOTAG_TAG(cond, uid, gid, tag) (0)
20177 ++
20178 ++#define TAGINO_UID(cond, uid, tag) (uid)
20179 ++#define TAGINO_GID(cond, gid, tag) (gid)
20180 ++
20181 ++#endif
20182 ++
20183 ++
20184 ++#ifdef CONFIG_TAGGING_GID16
20185 ++
20186 ++#define MAX_UID 0xFFFFFFFF
20187 ++#define MAX_GID 0x0000FFFF
20188 ++
20189 ++#define INOTAG_TAG(cond, uid, gid, tag) \
20190 ++ ((cond) ? (((gid) >> 16) & 0xFFFF) : 0)
20191 ++
20192 ++#define TAGINO_UID(cond, uid, tag) (uid)
20193 ++#define TAGINO_GID(cond, gid, tag) \
20194 ++ ((cond) ? (((gid) & 0xFFFF) | ((tag) << 16)) : (gid))
20195 ++
20196 ++#endif
20197 ++
20198 ++
20199 ++#ifdef CONFIG_TAGGING_ID24
20200 ++
20201 ++#define MAX_UID 0x00FFFFFF
20202 ++#define MAX_GID 0x00FFFFFF
20203 ++
20204 ++#define INOTAG_TAG(cond, uid, gid, tag) \
20205 ++ ((cond) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0)
20206 ++
20207 ++#define TAGINO_UID(cond, uid, tag) \
20208 ++ ((cond) ? (((uid) & 0xFFFFFF) | (((tag) & 0xFF00) << 16)) : (uid))
20209 ++#define TAGINO_GID(cond, gid, tag) \
20210 ++ ((cond) ? (((gid) & 0xFFFFFF) | (((tag) & 0x00FF) << 24)) : (gid))
20211 ++
20212 ++#endif
20213 ++
20214 ++
20215 ++#ifdef CONFIG_TAGGING_UID16
20216 ++
20217 ++#define MAX_UID 0x0000FFFF
20218 ++#define MAX_GID 0xFFFFFFFF
20219 ++
20220 ++#define INOTAG_TAG(cond, uid, gid, tag) \
20221 ++ ((cond) ? (((uid) >> 16) & 0xFFFF) : 0)
20222 ++
20223 ++#define TAGINO_UID(cond, uid, tag) \
20224 ++ ((cond) ? (((uid) & 0xFFFF) | ((tag) << 16)) : (uid))
20225 ++#define TAGINO_GID(cond, gid, tag) (gid)
20226 ++
20227 ++#endif
20228 ++
20229 ++
20230 ++#ifdef CONFIG_TAGGING_INTERN
20231 ++
20232 ++#define MAX_UID 0xFFFFFFFF
20233 ++#define MAX_GID 0xFFFFFFFF
20234 ++
20235 ++#define INOTAG_TAG(cond, uid, gid, tag) \
20236 ++ ((cond) ? (tag) : 0)
20237 ++
20238 ++#define TAGINO_UID(cond, uid, tag) (uid)
20239 ++#define TAGINO_GID(cond, gid, tag) (gid)
20240 ++
20241 ++#endif
20242 ++
20243 ++
20244 ++#ifndef CONFIG_TAGGING_NONE
20245 ++#define dx_current_fstag(sb) \
20246 ++ ((sb)->s_flags & MS_TAGGED ? dx_current_tag() : 0)
20247 ++#else
20248 ++#define dx_current_fstag(sb) (0)
20249 ++#endif
20250 ++
20251 ++#ifndef CONFIG_TAGGING_INTERN
20252 ++#define TAGINO_TAG(cond, tag) (0)
20253 ++#else
20254 ++#define TAGINO_TAG(cond, tag) ((cond) ? (tag) : 0)
20255 ++#endif
20256 ++
20257 ++#define INOTAG_UID(cond, uid, gid) \
20258 ++ ((cond) ? ((uid) & MAX_UID) : (uid))
20259 ++#define INOTAG_GID(cond, uid, gid) \
20260 ++ ((cond) ? ((gid) & MAX_GID) : (gid))
20261 ++
20262 ++
20263 ++static inline uid_t dx_map_uid(uid_t uid)
20264 ++{
20265 ++ if ((uid > MAX_UID) && (uid != -1))
20266 ++ uid = -2;
20267 ++ return (uid & MAX_UID);
20268 ++}
20269 ++
20270 ++static inline gid_t dx_map_gid(gid_t gid)
20271 ++{
20272 ++ if ((gid > MAX_GID) && (gid != -1))
20273 ++ gid = -2;
20274 ++ return (gid & MAX_GID);
20275 ++}
20276 ++
20277 ++
20278 ++#ifdef CONFIG_VSERVER_LEGACY
20279 ++#define FIOC_GETTAG _IOR('x', 1, long)
20280 ++#define FIOC_SETTAG _IOW('x', 2, long)
20281 ++#define FIOC_SETTAGJ _IOW('x', 3, long)
20282 ++#endif
20283 ++
20284 ++#ifdef CONFIG_PROPAGATE
20285 ++
20286 ++int dx_parse_tag(char *string, tag_t *tag, int remove);
20287 ++
20288 ++void __dx_propagate_tag(struct nameidata *nd, struct inode *inode);
20289 ++
20290 ++#define dx_propagate_tag(n, i) __dx_propagate_tag(n, i)
20291 ++
20292 ++#else
20293 ++#define dx_propagate_tag(n, i) do { } while (0)
20294 ++#endif
20295 ++
20296 ++#endif /* _DX_TAG_H */
20297 +diff -NurpP --minimal linux-2.6.22.19/include/net/af_unix.h linux-2.6.22.19-vs2.2.0.7/include/net/af_unix.h
20298 +--- linux-2.6.22.19/include/net/af_unix.h 2007-07-09 13:20:01 +0200
20299 ++++ linux-2.6.22.19-vs2.2.0.7/include/net/af_unix.h 2007-06-15 02:37:04 +0200
20300 +@@ -4,6 +4,7 @@
20301 + #include <linux/socket.h>
20302 + #include <linux/un.h>
20303 + #include <linux/mutex.h>
20304 ++#include <linux/vs_base.h>
20305 + #include <net/sock.h>
20306 +
20307 + extern void unix_inflight(struct file *fp);
20308 +@@ -17,9 +18,9 @@ extern spinlock_t unix_table_lock;
20309 +
20310 + extern atomic_t unix_tot_inflight;
20311 +
20312 +-static inline struct sock *first_unix_socket(int *i)
20313 ++static inline struct sock *next_unix_socket_table(int *i)
20314 + {
20315 +- for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) {
20316 ++ for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
20317 + if (!hlist_empty(&unix_socket_table[*i]))
20318 + return __sk_head(&unix_socket_table[*i]);
20319 + }
20320 +@@ -28,16 +29,19 @@ static inline struct sock *first_unix_so
20321 +
20322 + static inline struct sock *next_unix_socket(int *i, struct sock *s)
20323 + {
20324 +- struct sock *next = sk_next(s);
20325 +- /* More in this chain? */
20326 +- if (next)
20327 +- return next;
20328 +- /* Look for next non-empty chain. */
20329 +- for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
20330 +- if (!hlist_empty(&unix_socket_table[*i]))
20331 +- return __sk_head(&unix_socket_table[*i]);
20332 +- }
20333 +- return NULL;
20334 ++ do {
20335 ++ if (s)
20336 ++ s = sk_next(s);
20337 ++ if (!s)
20338 ++ s = next_unix_socket_table(i);
20339 ++ } while (s && !nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT));
20340 ++ return s;
20341 ++}
20342 ++
20343 ++static inline struct sock *first_unix_socket(int *i)
20344 ++{
20345 ++ *i = 0;
20346 ++ return next_unix_socket(i, NULL);
20347 + }
20348 +
20349 + #define forall_unix_sockets(i, s) \
20350 +diff -NurpP --minimal linux-2.6.22.19/include/net/inet_hashtables.h linux-2.6.22.19-vs2.2.0.7/include/net/inet_hashtables.h
20351 +--- linux-2.6.22.19/include/net/inet_hashtables.h 2007-05-02 19:25:35 +0200
20352 ++++ linux-2.6.22.19-vs2.2.0.7/include/net/inet_hashtables.h 2007-06-15 02:37:04 +0200
20353 +@@ -271,6 +271,26 @@ static inline int inet_iif(const struct
20354 + return ((struct rtable *)skb->dst)->rt_iif;
20355 + }
20356 +
20357 ++/*
20358 ++ * Check if a given address matches for an inet socket
20359 ++ *
20360 ++ * nxi: the socket's nx_info if any
20361 ++ * addr: to be verified address
20362 ++ * saddr: socket addresses
20363 ++ */
20364 ++static inline int inet_addr_match (
20365 ++ struct nx_info *nxi,
20366 ++ uint32_t addr,
20367 ++ uint32_t saddr)
20368 ++{
20369 ++ if (addr && (saddr == addr))
20370 ++ return 1;
20371 ++ if (!saddr)
20372 ++ return addr_in_nx_info(nxi, addr);
20373 ++ return 0;
20374 ++}
20375 ++
20376 ++
20377 + extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
20378 + const __be32 daddr,
20379 + const unsigned short hnum,
20380 +diff -NurpP --minimal linux-2.6.22.19/include/net/inet_sock.h linux-2.6.22.19-vs2.2.0.7/include/net/inet_sock.h
20381 +--- linux-2.6.22.19/include/net/inet_sock.h 2007-07-09 13:20:01 +0200
20382 ++++ linux-2.6.22.19-vs2.2.0.7/include/net/inet_sock.h 2007-06-15 02:37:04 +0200
20383 +@@ -113,6 +113,7 @@ struct inet_sock {
20384 + /* Socket demultiplex comparisons on incoming packets. */
20385 + __be32 daddr;
20386 + __be32 rcv_saddr;
20387 ++ __be32 rcv_saddr2; /* Second bound ipv4 addr, for ipv4root */
20388 + __be16 dport;
20389 + __u16 num;
20390 + __be32 saddr;
20391 +diff -NurpP --minimal linux-2.6.22.19/include/net/inet_timewait_sock.h linux-2.6.22.19-vs2.2.0.7/include/net/inet_timewait_sock.h
20392 +--- linux-2.6.22.19/include/net/inet_timewait_sock.h 2007-05-02 19:25:35 +0200
20393 ++++ linux-2.6.22.19-vs2.2.0.7/include/net/inet_timewait_sock.h 2007-06-15 02:37:04 +0200
20394 +@@ -115,6 +115,10 @@ struct inet_timewait_sock {
20395 + #define tw_refcnt __tw_common.skc_refcnt
20396 + #define tw_hash __tw_common.skc_hash
20397 + #define tw_prot __tw_common.skc_prot
20398 ++#define tw_xid __tw_common.skc_xid
20399 ++#define tw_vx_info __tw_common.skc_vx_info
20400 ++#define tw_nid __tw_common.skc_nid
20401 ++#define tw_nx_info __tw_common.skc_nx_info
20402 + volatile unsigned char tw_substate;
20403 + /* 3 bits hole, try to pack */
20404 + unsigned char tw_rcv_wscale;
20405 +diff -NurpP --minimal linux-2.6.22.19/include/net/route.h linux-2.6.22.19-vs2.2.0.7/include/net/route.h
20406 +--- linux-2.6.22.19/include/net/route.h 2007-05-02 19:25:35 +0200
20407 ++++ linux-2.6.22.19-vs2.2.0.7/include/net/route.h 2007-06-15 02:37:04 +0200
20408 +@@ -27,12 +27,16 @@
20409 + #include <net/dst.h>
20410 + #include <net/inetpeer.h>
20411 + #include <net/flow.h>
20412 ++#include <net/inet_sock.h>
20413 + #include <linux/in_route.h>
20414 + #include <linux/rtnetlink.h>
20415 + #include <linux/route.h>
20416 + #include <linux/ip.h>
20417 + #include <linux/cache.h>
20418 + #include <linux/security.h>
20419 ++#include <linux/vs_base.h>
20420 ++#include <linux/vs_network.h>
20421 ++#include <linux/in.h>
20422 +
20423 + #ifndef __KERNEL__
20424 + #warning This file is not supposed to be used outside of kernel.
20425 +@@ -143,6 +147,59 @@ static inline char rt_tos2priority(u8 to
20426 + return ip_tos2prio[IPTOS_TOS(tos)>>1];
20427 + }
20428 +
20429 ++#define IPI_LOOPBACK htonl(INADDR_LOOPBACK)
20430 ++
20431 ++static inline int ip_find_src(struct nx_info *nxi, struct rtable **rp, struct flowi *fl)
20432 ++{
20433 ++ int err;
20434 ++ int i, n = nxi->nbipv4;
20435 ++ u32 ipv4root = nxi->ipv4[0];
20436 ++
20437 ++ if (ipv4root == 0)
20438 ++ return 0;
20439 ++
20440 ++ if (fl->fl4_src == 0) {
20441 ++ if (n > 1) {
20442 ++ u32 foundsrc;
20443 ++
20444 ++ err = __ip_route_output_key(rp, fl);
20445 ++ if (err) {
20446 ++ fl->fl4_src = ipv4root;
20447 ++ err = __ip_route_output_key(rp, fl);
20448 ++ }
20449 ++ if (err)
20450 ++ return err;
20451 ++
20452 ++ foundsrc = (*rp)->rt_src;
20453 ++ ip_rt_put(*rp);
20454 ++
20455 ++ for (i=0; i<n; i++){
20456 ++ u32 mask = nxi->mask[i];
20457 ++ u32 ipv4 = nxi->ipv4[i];
20458 ++ u32 net4 = ipv4 & mask;
20459 ++
20460 ++ if (foundsrc == ipv4) {
20461 ++ fl->fl4_src = ipv4;
20462 ++ break;
20463 ++ }
20464 ++ if (!fl->fl4_src && (foundsrc & mask) == net4)
20465 ++ fl->fl4_src = ipv4;
20466 ++ }
20467 ++ }
20468 ++ if (fl->fl4_src == 0)
20469 ++ fl->fl4_src = (fl->fl4_dst == IPI_LOOPBACK)
20470 ++ ? IPI_LOOPBACK : ipv4root;
20471 ++ } else {
20472 ++ for (i=0; i<n; i++) {
20473 ++ if (nxi->ipv4[i] == fl->fl4_src)
20474 ++ break;
20475 ++ }
20476 ++ if (i == n)
20477 ++ return -EPERM;
20478 ++ }
20479 ++ return 0;
20480 ++}
20481 ++
20482 + static inline int ip_route_connect(struct rtable **rp, __be32 dst,
20483 + __be32 src, u32 tos, int oif, u8 protocol,
20484 + __be16 sport, __be16 dport, struct sock *sk,
20485 +@@ -158,7 +215,27 @@ static inline int ip_route_connect(struc
20486 + .dport = dport } } };
20487 +
20488 + int err;
20489 +- if (!dst || !src) {
20490 ++ struct nx_info *nx_info = current->nx_info;
20491 ++
20492 ++ if (sk)
20493 ++ nx_info = sk->sk_nx_info;
20494 ++ vxdprintk(VXD_CBIT(net, 4),
20495 ++ "ip_route_connect(%p) %p,%p;%lx",
20496 ++ sk, nx_info, sk->sk_socket,
20497 ++ (sk->sk_socket?sk->sk_socket->flags:0));
20498 ++
20499 ++ if (nx_info) {
20500 ++ err = ip_find_src(nx_info, rp, &fl);
20501 ++ if (err)
20502 ++ return err;
20503 ++ if (fl.fl4_dst == IPI_LOOPBACK && !nx_check(0, VS_ADMIN))
20504 ++ fl.fl4_dst = nx_info->ipv4[0];
20505 ++#ifdef CONFIG_VSERVER_REMAP_SADDR
20506 ++ if (fl.fl4_src == IPI_LOOPBACK && !nx_check(0, VS_ADMIN))
20507 ++ fl.fl4_src = nx_info->ipv4[0];
20508 ++#endif
20509 ++ }
20510 ++ if (!fl.fl4_dst || !fl.fl4_src) {
20511 + err = __ip_route_output_key(rp, &fl);
20512 + if (err)
20513 + return err;
20514 +diff -NurpP --minimal linux-2.6.22.19/include/net/sock.h linux-2.6.22.19-vs2.2.0.7/include/net/sock.h
20515 +--- linux-2.6.22.19/include/net/sock.h 2007-07-09 13:20:02 +0200
20516 ++++ linux-2.6.22.19-vs2.2.0.7/include/net/sock.h 2007-06-15 02:37:04 +0200
20517 +@@ -119,6 +119,10 @@ struct sock_common {
20518 + atomic_t skc_refcnt;
20519 + unsigned int skc_hash;
20520 + struct proto *skc_prot;
20521 ++ xid_t skc_xid;
20522 ++ struct vx_info *skc_vx_info;
20523 ++ nid_t skc_nid;
20524 ++ struct nx_info *skc_nx_info;
20525 + };
20526 +
20527 + /**
20528 +@@ -195,6 +199,10 @@ struct sock {
20529 + #define sk_refcnt __sk_common.skc_refcnt
20530 + #define sk_hash __sk_common.skc_hash
20531 + #define sk_prot __sk_common.skc_prot
20532 ++#define sk_xid __sk_common.skc_xid
20533 ++#define sk_vx_info __sk_common.skc_vx_info
20534 ++#define sk_nid __sk_common.skc_nid
20535 ++#define sk_nx_info __sk_common.skc_nx_info
20536 + unsigned char sk_shutdown : 2,
20537 + sk_no_check : 2,
20538 + sk_userlocks : 4;
20539 +diff -NurpP --minimal linux-2.6.22.19/init/main.c linux-2.6.22.19-vs2.2.0.7/init/main.c
20540 +--- linux-2.6.22.19/init/main.c 2007-07-09 13:20:03 +0200
20541 ++++ linux-2.6.22.19-vs2.2.0.7/init/main.c 2007-06-15 04:03:00 +0200
20542 +@@ -55,6 +55,7 @@
20543 + #include <linux/pid_namespace.h>
20544 + #include <linux/device.h>
20545 + #include <linux/kthread.h>
20546 ++#include <linux/vserver/percpu.h>
20547 +
20548 + #include <asm/io.h>
20549 + #include <asm/bugs.h>
20550 +@@ -364,12 +365,14 @@ EXPORT_SYMBOL(__per_cpu_offset);
20551 +
20552 + static void __init setup_per_cpu_areas(void)
20553 + {
20554 +- unsigned long size, i;
20555 ++ unsigned long size, vspc, i;
20556 + char *ptr;
20557 + unsigned long nr_possible_cpus = num_possible_cpus();
20558 +
20559 ++ vspc = PERCPU_PERCTX * CONFIG_VSERVER_CONTEXTS;
20560 ++
20561 + /* Copy section for each CPU (we discard the original) */
20562 +- size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
20563 ++ size = ALIGN(PERCPU_ENOUGH_ROOM + vspc, PAGE_SIZE);
20564 + ptr = alloc_bootmem_pages(size * nr_possible_cpus);
20565 +
20566 + for_each_possible_cpu(i) {
20567 +diff -NurpP --minimal linux-2.6.22.19/ipc/mqueue.c linux-2.6.22.19-vs2.2.0.7/ipc/mqueue.c
20568 +--- linux-2.6.22.19/ipc/mqueue.c 2008-03-14 20:19:04 +0100
20569 ++++ linux-2.6.22.19-vs2.2.0.7/ipc/mqueue.c 2008-01-09 20:53:07 +0100
20570 +@@ -29,6 +29,8 @@
20571 + #include <linux/audit.h>
20572 + #include <linux/signal.h>
20573 + #include <linux/mutex.h>
20574 ++#include <linux/vs_context.h>
20575 ++#include <linux/vs_limit.h>
20576 +
20577 + #include <net/sock.h>
20578 + #include "util.h"
20579 +@@ -151,17 +153,20 @@ static struct inode *mqueue_get_inode(st
20580 + spin_lock(&mq_lock);
20581 + if (u->mq_bytes + mq_bytes < u->mq_bytes ||
20582 + u->mq_bytes + mq_bytes >
20583 +- p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) {
20584 ++ p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur ||
20585 ++ !vx_ipcmsg_avail(p->vx_info, mq_bytes)) {
20586 + spin_unlock(&mq_lock);
20587 + goto out_inode;
20588 + }
20589 + u->mq_bytes += mq_bytes;
20590 ++ vx_ipcmsg_add(p->vx_info, u, mq_bytes);
20591 + spin_unlock(&mq_lock);
20592 +
20593 + info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL);
20594 + if (!info->messages) {
20595 + spin_lock(&mq_lock);
20596 + u->mq_bytes -= mq_bytes;
20597 ++ vx_ipcmsg_sub(p->vx_info, u, mq_bytes);
20598 + spin_unlock(&mq_lock);
20599 + goto out_inode;
20600 + }
20601 +@@ -257,10 +262,14 @@ static void mqueue_delete_inode(struct i
20602 + (info->attr.mq_maxmsg * info->attr.mq_msgsize));
20603 + user = info->user;
20604 + if (user) {
20605 ++ struct vx_info *vxi = lookup_vx_info(user->xid);
20606 ++
20607 + spin_lock(&mq_lock);
20608 + user->mq_bytes -= mq_bytes;
20609 ++ vx_ipcmsg_sub(vxi, user, mq_bytes);
20610 + queues_count--;
20611 + spin_unlock(&mq_lock);
20612 ++ put_vx_info(vxi);
20613 + free_uid(user);
20614 + }
20615 + }
20616 +@@ -748,7 +757,7 @@ asmlinkage long sys_mq_unlink(const char
20617 + if (inode)
20618 + atomic_inc(&inode->i_count);
20619 +
20620 +- err = vfs_unlink(dentry->d_parent->d_inode, dentry);
20621 ++ err = vfs_unlink(dentry->d_parent->d_inode, dentry, NULL);
20622 + out_err:
20623 + dput(dentry);
20624 +
20625 +diff -NurpP --minimal linux-2.6.22.19/ipc/msg.c linux-2.6.22.19-vs2.2.0.7/ipc/msg.c
20626 +--- linux-2.6.22.19/ipc/msg.c 2007-02-06 03:01:55 +0100
20627 ++++ linux-2.6.22.19-vs2.2.0.7/ipc/msg.c 2007-06-15 02:37:04 +0200
20628 +@@ -36,6 +36,7 @@
20629 + #include <linux/seq_file.h>
20630 + #include <linux/mutex.h>
20631 + #include <linux/nsproxy.h>
20632 ++#include <linux/vs_base.h>
20633 +
20634 + #include <asm/current.h>
20635 + #include <asm/uaccess.h>
20636 +@@ -149,6 +150,7 @@ static int newque (struct ipc_namespace
20637 +
20638 + msq->q_perm.mode = msgflg & S_IRWXUGO;
20639 + msq->q_perm.key = key;
20640 ++ msq->q_perm.xid = vx_current_xid();
20641 +
20642 + msq->q_perm.security = NULL;
20643 + retval = security_msg_queue_alloc(msq);
20644 +diff -NurpP --minimal linux-2.6.22.19/ipc/sem.c linux-2.6.22.19-vs2.2.0.7/ipc/sem.c
20645 +--- linux-2.6.22.19/ipc/sem.c 2007-07-09 13:20:03 +0200
20646 ++++ linux-2.6.22.19-vs2.2.0.7/ipc/sem.c 2007-06-15 02:37:04 +0200
20647 +@@ -82,6 +82,8 @@
20648 + #include <linux/seq_file.h>
20649 + #include <linux/mutex.h>
20650 + #include <linux/nsproxy.h>
20651 ++#include <linux/vs_base.h>
20652 ++#include <linux/vs_limit.h>
20653 +
20654 + #include <asm/uaccess.h>
20655 + #include "util.h"
20656 +@@ -229,6 +231,7 @@ static int newary (struct ipc_namespace
20657 +
20658 + sma->sem_perm.mode = (semflg & S_IRWXUGO);
20659 + sma->sem_perm.key = key;
20660 ++ sma->sem_perm.xid = vx_current_xid();
20661 +
20662 + sma->sem_perm.security = NULL;
20663 + retval = security_sem_alloc(sma);
20664 +@@ -244,6 +247,9 @@ static int newary (struct ipc_namespace
20665 + return -ENOSPC;
20666 + }
20667 + ns->used_sems += nsems;
20668 ++ /* FIXME: obsoleted? */
20669 ++ vx_semary_inc(sma);
20670 ++ vx_nsems_add(sma, nsems);
20671 +
20672 + sma->sem_id = sem_buildid(ns, id, sma->sem_perm.seq);
20673 + sma->sem_base = (struct sem *) &sma[1];
20674 +@@ -525,6 +531,9 @@ static void freeary (struct ipc_namespac
20675 + sem_unlock(sma);
20676 +
20677 + ns->used_sems -= sma->sem_nsems;
20678 ++ /* FIXME: obsoleted? */
20679 ++ vx_nsems_sub(sma, sma->sem_nsems);
20680 ++ vx_semary_dec(sma);
20681 + size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem);
20682 + security_sem_free(sma);
20683 + ipc_rcu_putref(sma);
20684 +diff -NurpP --minimal linux-2.6.22.19/ipc/shm.c linux-2.6.22.19-vs2.2.0.7/ipc/shm.c
20685 +--- linux-2.6.22.19/ipc/shm.c 2008-03-14 20:19:04 +0100
20686 ++++ linux-2.6.22.19-vs2.2.0.7/ipc/shm.c 2007-08-12 12:21:52 +0200
20687 +@@ -38,6 +38,8 @@
20688 + #include <linux/mutex.h>
20689 + #include <linux/nsproxy.h>
20690 + #include <linux/mount.h>
20691 ++#include <linux/vs_context.h>
20692 ++#include <linux/vs_limit.h>
20693 +
20694 + #include <asm/uaccess.h>
20695 +
20696 +@@ -185,7 +187,12 @@ static void shm_open(struct vm_area_stru
20697 + */
20698 + static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
20699 + {
20700 +- ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
20701 ++ struct vx_info *vxi = lookup_vx_info(shp->shm_perm.xid);
20702 ++ int numpages = (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
20703 ++
20704 ++ vx_ipcshm_sub(vxi, shp, numpages);
20705 ++ ns->shm_tot -= numpages;
20706 ++
20707 + shm_rmid(ns, shp->id);
20708 + shm_unlock(shp);
20709 + if (!is_file_hugepages(shp->shm_file))
20710 +@@ -195,6 +202,7 @@ static void shm_destroy(struct ipc_names
20711 + shp->mlock_user);
20712 + fput (shp->shm_file);
20713 + security_shm_free(shp);
20714 ++ put_vx_info(vxi);
20715 + ipc_rcu_putref(shp);
20716 + }
20717 +
20718 +@@ -351,11 +359,15 @@ static int newseg (struct ipc_namespace
20719 + if (ns->shm_tot + numpages > ns->shm_ctlall)
20720 + return -ENOSPC;
20721 +
20722 ++ if (!vx_ipcshm_avail(current->vx_info, numpages))
20723 ++ return -ENOSPC;
20724 ++
20725 + shp = ipc_rcu_alloc(sizeof(*shp));
20726 + if (!shp)
20727 + return -ENOMEM;
20728 +
20729 + shp->shm_perm.key = key;
20730 ++ shp->shm_perm.xid = vx_current_xid();
20731 + shp->shm_perm.mode = (shmflg & S_IRWXUGO);
20732 + shp->mlock_user = NULL;
20733 +
20734 +@@ -406,6 +418,7 @@ static int newseg (struct ipc_namespace
20735 + file->f_dentry->d_inode->i_ino = shp->id;
20736 +
20737 + ns->shm_tot += numpages;
20738 ++ vx_ipcshm_add(current->vx_info, key, numpages);
20739 + shm_unlock(shp);
20740 + return shp->id;
20741 +
20742 +diff -NurpP --minimal linux-2.6.22.19/ipc/util.c linux-2.6.22.19-vs2.2.0.7/ipc/util.c
20743 +--- linux-2.6.22.19/ipc/util.c 2007-07-09 13:20:03 +0200
20744 ++++ linux-2.6.22.19-vs2.2.0.7/ipc/util.c 2007-06-15 02:37:04 +0200
20745 +@@ -32,6 +32,8 @@
20746 + #include <linux/proc_fs.h>
20747 + #include <linux/audit.h>
20748 + #include <linux/nsproxy.h>
20749 ++#include <linux/vs_base.h>
20750 ++#include <linux/vserver/global.h>
20751 +
20752 + #include <asm/unistd.h>
20753 +
20754 +@@ -72,6 +74,7 @@ static struct ipc_namespace *clone_ipc_n
20755 + goto err_shm;
20756 +
20757 + kref_init(&ns->kref);
20758 ++ atomic_inc(&vs_global_ipc_ns);
20759 + return ns;
20760 +
20761 + err_shm:
20762 +@@ -108,6 +111,7 @@ void free_ipc_ns(struct kref *kref)
20763 + sem_exit_ns(ns);
20764 + msg_exit_ns(ns);
20765 + shm_exit_ns(ns);
20766 ++ atomic_dec(&vs_global_ipc_ns);
20767 + kfree(ns);
20768 + }
20769 + #else
20770 +diff -NurpP --minimal linux-2.6.22.19/kernel/Makefile linux-2.6.22.19-vs2.2.0.7/kernel/Makefile
20771 +--- linux-2.6.22.19/kernel/Makefile 2007-07-09 13:20:03 +0200
20772 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/Makefile 2007-06-15 02:37:04 +0200
20773 +@@ -10,6 +10,8 @@ obj-y = sched.o fork.o exec_domain.o
20774 + kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
20775 + hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o
20776 +
20777 ++obj-y += vserver/
20778 ++
20779 + obj-$(CONFIG_STACKTRACE) += stacktrace.o
20780 + obj-y += time/
20781 + obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
20782 +diff -NurpP --minimal linux-2.6.22.19/kernel/capability.c linux-2.6.22.19-vs2.2.0.7/kernel/capability.c
20783 +--- linux-2.6.22.19/kernel/capability.c 2007-05-02 19:25:37 +0200
20784 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/capability.c 2007-06-15 02:37:04 +0200
20785 +@@ -12,6 +12,7 @@
20786 + #include <linux/module.h>
20787 + #include <linux/security.h>
20788 + #include <linux/syscalls.h>
20789 ++#include <linux/vs_context.h>
20790 + #include <asm/uaccess.h>
20791 +
20792 + unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
20793 +@@ -103,6 +104,8 @@ static inline int cap_set_pg(int pgrp_nr
20794 +
20795 + pgrp = find_pid(pgrp_nr);
20796 + do_each_pid_task(pgrp, PIDTYPE_PGID, g) {
20797 ++ if (!vx_check(g->xid, VS_ADMIN_P | VS_IDENT))
20798 ++ continue;
20799 + target = g;
20800 + while_each_thread(g, target) {
20801 + if (!security_capset_check(target, effective,
20802 +@@ -246,8 +249,12 @@ int __capable(struct task_struct *t, int
20803 + }
20804 + EXPORT_SYMBOL(__capable);
20805 +
20806 ++#include <linux/vserver/base.h>
20807 + int capable(int cap)
20808 + {
20809 ++ /* here for now so we don't require task locking */
20810 ++ if (vs_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap))
20811 ++ return 0;
20812 + return __capable(current, cap);
20813 + }
20814 + EXPORT_SYMBOL(capable);
20815 +diff -NurpP --minimal linux-2.6.22.19/kernel/compat.c linux-2.6.22.19-vs2.2.0.7/kernel/compat.c
20816 +--- linux-2.6.22.19/kernel/compat.c 2007-07-09 13:20:03 +0200
20817 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/compat.c 2007-06-15 02:37:04 +0200
20818 +@@ -846,7 +846,7 @@ asmlinkage long compat_sys_time(compat_t
20819 + compat_time_t i;
20820 + struct timeval tv;
20821 +
20822 +- do_gettimeofday(&tv);
20823 ++ vx_gettimeofday(&tv);
20824 + i = tv.tv_sec;
20825 +
20826 + if (tloc) {
20827 +@@ -870,7 +870,7 @@ asmlinkage long compat_sys_stime(compat_
20828 + if (err)
20829 + return err;
20830 +
20831 +- do_settimeofday(&tv);
20832 ++ vx_settimeofday(&tv);
20833 + return 0;
20834 + }
20835 +
20836 +diff -NurpP --minimal linux-2.6.22.19/kernel/exit.c linux-2.6.22.19-vs2.2.0.7/kernel/exit.c
20837 +--- linux-2.6.22.19/kernel/exit.c 2008-03-14 20:19:04 +0100
20838 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/exit.c 2008-01-09 20:53:07 +0100
20839 +@@ -44,6 +44,11 @@
20840 + #include <linux/resource.h>
20841 + #include <linux/blkdev.h>
20842 + #include <linux/task_io_accounting_ops.h>
20843 ++#include <linux/vs_limit.h>
20844 ++#include <linux/vs_context.h>
20845 ++#include <linux/vs_network.h>
20846 ++#include <linux/vs_pid.h>
20847 ++#include <linux/vserver/global.h>
20848 +
20849 + #include <asm/uaccess.h>
20850 + #include <asm/unistd.h>
20851 +@@ -443,9 +448,11 @@ static void close_files(struct files_str
20852 + filp_close(file, files);
20853 + cond_resched();
20854 + }
20855 ++ vx_openfd_dec(i);
20856 + }
20857 + i++;
20858 + set >>= 1;
20859 ++ cond_resched();
20860 + }
20861 + }
20862 + }
20863 +@@ -525,6 +532,7 @@ static inline void __put_fs_struct(struc
20864 + dput(fs->altroot);
20865 + mntput(fs->altrootmnt);
20866 + }
20867 ++ atomic_dec(&vs_global_fs);
20868 + kmem_cache_free(fs_cachep, fs);
20869 + }
20870 + }
20871 +@@ -596,6 +604,14 @@ static void exit_mm(struct task_struct *
20872 + static inline void
20873 + choose_new_parent(struct task_struct *p, struct task_struct *reaper)
20874 + {
20875 ++ /* check for reaper context */
20876 ++ vxwprintk((p->xid != reaper->xid) && (reaper != child_reaper(p)),
20877 ++ "rogue reaper: %p[%d,#%u] <> %p[%d,#%u]",
20878 ++ p, p->pid, p->xid, reaper, reaper->pid, reaper->xid);
20879 ++
20880 ++ if (p == reaper)
20881 ++ reaper = vx_child_reaper(p);
20882 ++
20883 + /*
20884 + * Make sure we're not reparenting to ourselves and that
20885 + * the parent is not a zombie.
20886 +@@ -687,7 +703,7 @@ forget_original_parent(struct task_struc
20887 + do {
20888 + reaper = next_thread(reaper);
20889 + if (reaper == father) {
20890 +- reaper = child_reaper(father);
20891 ++ reaper = vx_child_reaper(father);
20892 + break;
20893 + }
20894 + } while (reaper->exit_state);
20895 +@@ -964,6 +980,8 @@ fastcall NORET_TYPE void do_exit(long co
20896 + tsk->exit_code = code;
20897 + proc_exit_connector(tsk);
20898 + exit_task_namespaces(tsk);
20899 ++ /* needs to stay before exit_notify() */
20900 ++ exit_vx_info_early(tsk, code);
20901 + exit_notify(tsk);
20902 + #ifdef CONFIG_NUMA
20903 + mpol_free(tsk->mempolicy);
20904 +@@ -994,6 +1012,10 @@ fastcall NORET_TYPE void do_exit(long co
20905 + if (tsk->splice_pipe)
20906 + __free_pipe_info(tsk->splice_pipe);
20907 +
20908 ++ /* needs to stay after exit_notify() */
20909 ++ exit_vx_info(tsk, code);
20910 ++ exit_nx_info(tsk);
20911 ++
20912 + preempt_disable();
20913 + /* causes final put_task_struct in finish_task_switch(). */
20914 + tsk->state = TASK_DEAD;
20915 +diff -NurpP --minimal linux-2.6.22.19/kernel/fork.c linux-2.6.22.19-vs2.2.0.7/kernel/fork.c
20916 +--- linux-2.6.22.19/kernel/fork.c 2007-07-09 13:20:03 +0200
20917 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/fork.c 2007-10-29 23:35:00 +0100
20918 +@@ -49,6 +49,11 @@
20919 + #include <linux/delayacct.h>
20920 + #include <linux/taskstats_kern.h>
20921 + #include <linux/random.h>
20922 ++#include <linux/vs_context.h>
20923 ++#include <linux/vs_network.h>
20924 ++#include <linux/vs_limit.h>
20925 ++#include <linux/vs_memory.h>
20926 ++#include <linux/vserver/global.h>
20927 +
20928 + #include <asm/pgtable.h>
20929 + #include <asm/pgalloc.h>
20930 +@@ -108,6 +113,8 @@ void free_task(struct task_struct *tsk)
20931 + {
20932 + free_thread_info(tsk->stack);
20933 + rt_mutex_debug_task_free(tsk);
20934 ++ clr_vx_info(&tsk->vx_info);
20935 ++ clr_nx_info(&tsk->nx_info);
20936 + free_task_struct(tsk);
20937 + }
20938 + EXPORT_SYMBOL(free_task);
20939 +@@ -215,6 +222,8 @@ static inline int dup_mmap(struct mm_str
20940 + mm->free_area_cache = oldmm->mmap_base;
20941 + mm->cached_hole_size = ~0UL;
20942 + mm->map_count = 0;
20943 ++ __set_mm_counter(mm, file_rss, 0);
20944 ++ __set_mm_counter(mm, anon_rss, 0);
20945 + cpus_clear(mm->cpu_vm_mask);
20946 + mm->mm_rb = RB_ROOT;
20947 + rb_link = &mm->mm_rb.rb_node;
20948 +@@ -226,7 +235,7 @@ static inline int dup_mmap(struct mm_str
20949 +
20950 + if (mpnt->vm_flags & VM_DONTCOPY) {
20951 + long pages = vma_pages(mpnt);
20952 +- mm->total_vm -= pages;
20953 ++ vx_vmpages_sub(mm, pages);
20954 + vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
20955 + -pages);
20956 + continue;
20957 +@@ -327,7 +336,7 @@ static inline void mm_free_pgd(struct mm
20958 +
20959 + #include <linux/init_task.h>
20960 +
20961 +-static struct mm_struct * mm_init(struct mm_struct * mm)
20962 ++static struct mm_struct * mm_init(struct mm_struct * mm, struct vx_info *vxi)
20963 + {
20964 + atomic_set(&mm->mm_users, 1);
20965 + atomic_set(&mm->mm_count, 1);
20966 +@@ -335,8 +344,8 @@ static struct mm_struct * mm_init(struct
20967 + INIT_LIST_HEAD(&mm->mmlist);
20968 + mm->core_waiters = 0;
20969 + mm->nr_ptes = 0;
20970 +- set_mm_counter(mm, file_rss, 0);
20971 +- set_mm_counter(mm, anon_rss, 0);
20972 ++ __set_mm_counter(mm, file_rss, 0);
20973 ++ __set_mm_counter(mm, anon_rss, 0);
20974 + spin_lock_init(&mm->page_table_lock);
20975 + rwlock_init(&mm->ioctx_list_lock);
20976 + mm->ioctx_list = NULL;
20977 +@@ -345,6 +354,7 @@ static struct mm_struct * mm_init(struct
20978 +
20979 + if (likely(!mm_alloc_pgd(mm))) {
20980 + mm->def_flags = 0;
20981 ++ set_vx_info(&mm->mm_vx_info, vxi);
20982 + return mm;
20983 + }
20984 + free_mm(mm);
20985 +@@ -361,7 +371,7 @@ struct mm_struct * mm_alloc(void)
20986 + mm = allocate_mm();
20987 + if (mm) {
20988 + memset(mm, 0, sizeof(*mm));
20989 +- mm = mm_init(mm);
20990 ++ mm = mm_init(mm, current->vx_info);
20991 + }
20992 + return mm;
20993 + }
20994 +@@ -376,6 +386,7 @@ void fastcall __mmdrop(struct mm_struct
20995 + BUG_ON(mm == &init_mm);
20996 + mm_free_pgd(mm);
20997 + destroy_context(mm);
20998 ++ clr_vx_info(&mm->mm_vx_info);
20999 + free_mm(mm);
21000 + }
21001 +
21002 +@@ -490,12 +501,13 @@ static struct mm_struct *dup_mm(struct t
21003 + goto fail_nomem;
21004 +
21005 + memcpy(mm, oldmm, sizeof(*mm));
21006 ++ mm->mm_vx_info = NULL;
21007 +
21008 + /* Initializing for Swap token stuff */
21009 + mm->token_priority = 0;
21010 + mm->last_interval = 0;
21011 +
21012 +- if (!mm_init(mm))
21013 ++ if (!mm_init(mm, oldmm->mm_vx_info))
21014 + goto fail_nomem;
21015 +
21016 + if (init_new_context(tsk, mm))
21017 +@@ -521,6 +533,7 @@ fail_nocontext:
21018 + * If init_new_context() failed, we cannot use mmput() to free the mm
21019 + * because it calls destroy_context()
21020 + */
21021 ++ clr_vx_info(&mm->mm_vx_info);
21022 + mm_free_pgd(mm);
21023 + free_mm(mm);
21024 + return NULL;
21025 +@@ -591,6 +604,7 @@ static inline struct fs_struct *__copy_f
21026 + fs->altroot = NULL;
21027 + }
21028 + read_unlock(&old->lock);
21029 ++ atomic_inc(&vs_global_fs);
21030 + }
21031 + return fs;
21032 + }
21033 +@@ -709,6 +723,8 @@ static struct files_struct *dup_fd(struc
21034 + struct file *f = *old_fds++;
21035 + if (f) {
21036 + get_file(f);
21037 ++ /* TODO: sum it first for check and performance */
21038 ++ vx_openfd_inc(open_files - i);
21039 + } else {
21040 + /*
21041 + * The fd may be claimed in the fd bitmap but not yet
21042 +@@ -961,6 +977,8 @@ static struct task_struct *copy_process(
21043 + {
21044 + int retval;
21045 + struct task_struct *p = NULL;
21046 ++ struct vx_info *vxi;
21047 ++ struct nx_info *nxi;
21048 +
21049 + if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
21050 + return ERR_PTR(-EINVAL);
21051 +@@ -995,12 +1013,30 @@ static struct task_struct *copy_process(
21052 + DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
21053 + DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
21054 + #endif
21055 ++ init_vx_info(&p->vx_info, current->vx_info);
21056 ++ init_nx_info(&p->nx_info, current->nx_info);
21057 ++
21058 ++ /* check vserver memory */
21059 ++ if (p->mm && !(clone_flags & CLONE_VM)) {
21060 ++ if (vx_vmpages_avail(p->mm, p->mm->total_vm))
21061 ++ vx_pages_add(p->vx_info, RLIMIT_AS, p->mm->total_vm);
21062 ++ else
21063 ++ goto bad_fork_free;
21064 ++ }
21065 ++ if (p->mm && vx_flags(VXF_FORK_RSS, 0)) {
21066 ++ if (!vx_rss_avail(p->mm, get_mm_counter(p->mm, file_rss)))
21067 ++ goto bad_fork_cleanup_vm;
21068 ++ }
21069 ++
21070 + retval = -EAGAIN;
21071 ++ if (!vx_nproc_avail(1))
21072 ++ goto bad_fork_cleanup_vm;
21073 ++
21074 + if (atomic_read(&p->user->processes) >=
21075 + p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
21076 + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
21077 + p->user != &root_user)
21078 +- goto bad_fork_free;
21079 ++ goto bad_fork_cleanup_vm;
21080 + }
21081 +
21082 + atomic_inc(&p->user->__count);
21083 +@@ -1265,6 +1301,18 @@ static struct task_struct *copy_process(
21084 +
21085 + total_forks++;
21086 + spin_unlock(&current->sighand->siglock);
21087 ++
21088 ++ /* p is copy of current */
21089 ++ vxi = p->vx_info;
21090 ++ if (vxi) {
21091 ++ claim_vx_info(vxi, p);
21092 ++ atomic_inc(&vxi->cvirt.nr_threads);
21093 ++ atomic_inc(&vxi->cvirt.total_forks);
21094 ++ vx_nproc_inc(p);
21095 ++ }
21096 ++ nxi = p->nx_info;
21097 ++ if (nxi)
21098 ++ claim_nx_info(nxi, p);
21099 + write_unlock_irq(&tasklist_lock);
21100 + proc_fork_connector(p);
21101 + return p;
21102 +@@ -1306,6 +1354,9 @@ bad_fork_cleanup_count:
21103 + put_group_info(p->group_info);
21104 + atomic_dec(&p->user->processes);
21105 + free_uid(p->user);
21106 ++bad_fork_cleanup_vm:
21107 ++ if (p->mm && !(clone_flags & CLONE_VM))
21108 ++ vx_pages_sub(p->vx_info, RLIMIT_AS, p->mm->total_vm);
21109 + bad_fork_free:
21110 + free_task(p);
21111 + fork_out:
21112 +@@ -1367,6 +1418,14 @@ long do_fork(unsigned long clone_flags,
21113 +
21114 + if (!pid)
21115 + return -EAGAIN;
21116 ++
21117 ++ /* kernel threads are host only */
21118 ++ if ((clone_flags & CLONE_KTHREAD) && !vx_check(0, VS_ADMIN)) {
21119 ++ vxwprintk_task(1, "tried to spawn a kernel thread.");
21120 ++ free_pid(pid);
21121 ++ return -EPERM;
21122 ++ }
21123 ++
21124 + nr = pid->nr;
21125 + if (unlikely(current->ptrace)) {
21126 + trace = fork_traceflag (clone_flags);
21127 +diff -NurpP --minimal linux-2.6.22.19/kernel/kthread.c linux-2.6.22.19-vs2.2.0.7/kernel/kthread.c
21128 +--- linux-2.6.22.19/kernel/kthread.c 2007-07-09 13:20:03 +0200
21129 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/kthread.c 2007-06-15 02:37:04 +0200
21130 +@@ -96,7 +96,7 @@ static void create_kthread(struct kthrea
21131 + } else {
21132 + wait_for_completion(&create->started);
21133 + read_lock(&tasklist_lock);
21134 +- create->result = find_task_by_pid(pid);
21135 ++ create->result = find_task_by_real_pid(pid);
21136 + read_unlock(&tasklist_lock);
21137 + }
21138 + complete(&create->done);
21139 +diff -NurpP --minimal linux-2.6.22.19/kernel/nsproxy.c linux-2.6.22.19-vs2.2.0.7/kernel/nsproxy.c
21140 +--- linux-2.6.22.19/kernel/nsproxy.c 2007-07-09 13:20:03 +0200
21141 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/nsproxy.c 2007-07-07 04:12:31 +0200
21142 +@@ -20,14 +20,11 @@
21143 + #include <linux/mnt_namespace.h>
21144 + #include <linux/utsname.h>
21145 + #include <linux/pid_namespace.h>
21146 ++#include <linux/vserver/global.h>
21147 ++#include <linux/vserver/debug.h>
21148 +
21149 + struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
21150 +
21151 +-static inline void get_nsproxy(struct nsproxy *ns)
21152 +-{
21153 +- atomic_inc(&ns->count);
21154 +-}
21155 +-
21156 + void get_task_namespaces(struct task_struct *tsk)
21157 + {
21158 + struct nsproxy *ns = tsk->nsproxy;
21159 +@@ -46,6 +43,9 @@ static inline struct nsproxy *clone_nspr
21160 + ns = kmemdup(orig, sizeof(struct nsproxy), GFP_KERNEL);
21161 + if (ns)
21162 + atomic_set(&ns->count, 1);
21163 ++ vxdprintk(VXD_CBIT(space, 2), "clone_nsproxy(%p[%u] = %p[1]",
21164 ++ orig, atomic_read(&orig->count), ns);
21165 ++ atomic_inc(&vs_global_nsproxy);
21166 + return ns;
21167 + }
21168 +
21169 +@@ -54,28 +54,32 @@ static inline struct nsproxy *clone_nspr
21170 + * Return the newly created nsproxy. Do not attach this to the task,
21171 + * leave it to the caller to do proper locking and attach it to task.
21172 + */
21173 +-static struct nsproxy *create_new_namespaces(int flags, struct task_struct *tsk,
21174 ++static struct nsproxy *unshare_namespaces(int flags, struct nsproxy *orig,
21175 + struct fs_struct *new_fs)
21176 + {
21177 + struct nsproxy *new_nsp;
21178 +
21179 +- new_nsp = clone_nsproxy(tsk->nsproxy);
21180 ++ vxdprintk(VXD_CBIT(space, 4),
21181 ++ "unshare_namespaces(0x%08x,%p,%p)",
21182 ++ flags, orig, new_fs);
21183 ++
21184 ++ new_nsp = clone_nsproxy(orig);
21185 + if (!new_nsp)
21186 + return ERR_PTR(-ENOMEM);
21187 +
21188 +- new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, new_fs);
21189 ++ new_nsp->mnt_ns = copy_mnt_ns(flags, orig->mnt_ns, new_fs);
21190 + if (IS_ERR(new_nsp->mnt_ns))
21191 + goto out_ns;
21192 +
21193 +- new_nsp->uts_ns = copy_utsname(flags, tsk->nsproxy->uts_ns);
21194 ++ new_nsp->uts_ns = copy_utsname(flags, orig->uts_ns);
21195 + if (IS_ERR(new_nsp->uts_ns))
21196 + goto out_uts;
21197 +
21198 +- new_nsp->ipc_ns = copy_ipcs(flags, tsk->nsproxy->ipc_ns);
21199 ++ new_nsp->ipc_ns = copy_ipcs(flags, orig->ipc_ns);
21200 + if (IS_ERR(new_nsp->ipc_ns))
21201 + goto out_ipc;
21202 +
21203 +- new_nsp->pid_ns = copy_pid_ns(flags, tsk->nsproxy->pid_ns);
21204 ++ new_nsp->pid_ns = copy_pid_ns(flags, orig->pid_ns);
21205 + if (IS_ERR(new_nsp->pid_ns))
21206 + goto out_pid;
21207 +
21208 +@@ -95,6 +99,33 @@ out_ns:
21209 + return ERR_PTR(-ENOMEM);
21210 + }
21211 +
21212 ++static struct nsproxy *create_new_namespaces(int flags, struct task_struct *tsk,
21213 ++ struct fs_struct *new_fs)
21214 ++{
21215 ++ return unshare_namespaces(flags, tsk->nsproxy, new_fs);
21216 ++}
21217 ++
21218 ++/*
21219 ++ * copies the nsproxy, setting refcount to 1, and grabbing a
21220 ++ * reference to all contained namespaces.
21221 ++ */
21222 ++struct nsproxy *copy_nsproxy(struct nsproxy *orig)
21223 ++{
21224 ++ struct nsproxy *ns = clone_nsproxy(orig);
21225 ++
21226 ++ if (ns) {
21227 ++ if (ns->mnt_ns)
21228 ++ get_mnt_ns(ns->mnt_ns);
21229 ++ if (ns->uts_ns)
21230 ++ get_uts_ns(ns->uts_ns);
21231 ++ if (ns->ipc_ns)
21232 ++ get_ipc_ns(ns->ipc_ns);
21233 ++ if (ns->pid_ns)
21234 ++ get_pid_ns(ns->pid_ns);
21235 ++ }
21236 ++ return ns;
21237 ++}
21238 ++
21239 + /*
21240 + * called from clone. This now handles copy for nsproxy and all
21241 + * namespaces therein.
21242 +@@ -102,9 +133,12 @@ out_ns:
21243 + int copy_namespaces(int flags, struct task_struct *tsk)
21244 + {
21245 + struct nsproxy *old_ns = tsk->nsproxy;
21246 +- struct nsproxy *new_ns;
21247 ++ struct nsproxy *new_ns = NULL;
21248 + int err = 0;
21249 +
21250 ++ vxdprintk(VXD_CBIT(space, 7), "copy_namespaces(0x%08x,%p[%p])",
21251 ++ flags, tsk, old_ns);
21252 ++
21253 + if (!old_ns)
21254 + return 0;
21255 +
21256 +@@ -127,6 +161,9 @@ int copy_namespaces(int flags, struct ta
21257 + tsk->nsproxy = new_ns;
21258 + out:
21259 + put_nsproxy(old_ns);
21260 ++ vxdprintk(VXD_CBIT(space, 3),
21261 ++ "copy_namespaces(0x%08x,%p[%p]) = %d [%p]",
21262 ++ flags, tsk, old_ns, err, new_ns);
21263 + return err;
21264 + }
21265 +
21266 +@@ -140,6 +177,7 @@ void free_nsproxy(struct nsproxy *ns)
21267 + put_ipc_ns(ns->ipc_ns);
21268 + if (ns->pid_ns)
21269 + put_pid_ns(ns->pid_ns);
21270 ++ atomic_dec(&vs_global_nsproxy);
21271 + kfree(ns);
21272 + }
21273 +
21274 +@@ -152,6 +190,10 @@ int unshare_nsproxy_namespaces(unsigned
21275 + {
21276 + int err = 0;
21277 +
21278 ++ vxdprintk(VXD_CBIT(space, 4),
21279 ++ "unshare_nsproxy_namespaces(0x%08lx,[%p])",
21280 ++ unshare_flags, current->nsproxy);
21281 ++
21282 + if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC)))
21283 + return 0;
21284 +
21285 +diff -NurpP --minimal linux-2.6.22.19/kernel/pid.c linux-2.6.22.19-vs2.2.0.7/kernel/pid.c
21286 +--- linux-2.6.22.19/kernel/pid.c 2007-07-09 13:20:03 +0200
21287 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/pid.c 2007-06-15 04:04:09 +0200
21288 +@@ -28,6 +28,7 @@
21289 + #include <linux/hash.h>
21290 + #include <linux/pid_namespace.h>
21291 + #include <linux/init_task.h>
21292 ++#include <linux/vs_pid.h>
21293 +
21294 + #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
21295 + static struct hlist_head *pid_hash;
21296 +@@ -295,6 +296,9 @@ void fastcall transfer_pid(struct task_s
21297 + struct task_struct * fastcall pid_task(struct pid *pid, enum pid_type type)
21298 + {
21299 + struct task_struct *result = NULL;
21300 ++
21301 ++ if (type == PIDTYPE_REALPID)
21302 ++ type = PIDTYPE_PID;
21303 + if (pid) {
21304 + struct hlist_node *first;
21305 + first = rcu_dereference(pid->tasks[type].first);
21306 +@@ -309,7 +313,17 @@ struct task_struct * fastcall pid_task(s
21307 + */
21308 + struct task_struct *find_task_by_pid_type(int type, int nr)
21309 + {
21310 +- return pid_task(find_pid(nr), type);
21311 ++ struct task_struct *task;
21312 ++
21313 ++ if (type == PIDTYPE_PID)
21314 ++ nr = vx_rmap_pid(nr);
21315 ++
21316 ++ task = pid_task(find_pid(nr), type);
21317 ++ if (task && (type != PIDTYPE_REALPID) &&
21318 ++ /* maybe VS_WATCH_P in the future? */
21319 ++ !vx_check(task->xid, VS_WATCH|VS_IDENT))
21320 ++ return NULL;
21321 ++ return task;
21322 + }
21323 +
21324 + EXPORT_SYMBOL(find_task_by_pid_type);
21325 +diff -NurpP --minimal linux-2.6.22.19/kernel/posix-timers.c linux-2.6.22.19-vs2.2.0.7/kernel/posix-timers.c
21326 +--- linux-2.6.22.19/kernel/posix-timers.c 2007-07-09 13:20:03 +0200
21327 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/posix-timers.c 2007-10-11 14:14:00 +0200
21328 +@@ -47,6 +47,7 @@
21329 + #include <linux/wait.h>
21330 + #include <linux/workqueue.h>
21331 + #include <linux/module.h>
21332 ++#include <linux/vs_context.h>
21333 +
21334 + /*
21335 + * Management arrays for POSIX timers. Timers are kept in slab memory
21336 +@@ -297,6 +298,12 @@ void do_schedule_next_timer(struct sigin
21337 +
21338 + int posix_timer_event(struct k_itimer *timr,int si_private)
21339 + {
21340 ++ struct vx_info_save vxis;
21341 ++ struct vx_info *vxi;
21342 ++ int ret;
21343 ++
21344 ++ vxi = task_get_vx_info(timr->it_process);
21345 ++ enter_vx_info(vxi, &vxis);
21346 + memset(&timr->sigq->info, 0, sizeof(siginfo_t));
21347 + timr->sigq->info.si_sys_private = si_private;
21348 + /* Send signal to the process that owns this timer.*/
21349 +@@ -309,11 +316,11 @@ int posix_timer_event(struct k_itimer *t
21350 +
21351 + if (timr->it_sigev_notify & SIGEV_THREAD_ID) {
21352 + struct task_struct *leader;
21353 +- int ret = send_sigqueue(timr->it_sigev_signo, timr->sigq,
21354 +- timr->it_process);
21355 +
21356 ++ ret = send_sigqueue(timr->it_sigev_signo, timr->sigq,
21357 ++ timr->it_process);
21358 + if (likely(ret >= 0))
21359 +- return ret;
21360 ++ goto out;
21361 +
21362 + timr->it_sigev_notify = SIGEV_SIGNAL;
21363 + leader = timr->it_process->group_leader;
21364 +@@ -321,8 +328,12 @@ int posix_timer_event(struct k_itimer *t
21365 + timr->it_process = leader;
21366 + }
21367 +
21368 +- return send_group_sigqueue(timr->it_sigev_signo, timr->sigq,
21369 ++ ret = send_group_sigqueue(timr->it_sigev_signo, timr->sigq,
21370 + timr->it_process);
21371 ++out:
21372 ++ leave_vx_info(&vxis);
21373 ++ put_vx_info(vxi);
21374 ++ return ret;
21375 + }
21376 + EXPORT_SYMBOL_GPL(posix_timer_event);
21377 +
21378 +@@ -402,7 +413,7 @@ static struct task_struct * good_sigeven
21379 + struct task_struct *rtn = current->group_leader;
21380 +
21381 + if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
21382 +- (!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) ||
21383 ++ (!(rtn = find_task_by_real_pid(event->sigev_notify_thread_id)) ||
21384 + rtn->tgid != current->tgid ||
21385 + (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
21386 + return NULL;
21387 +diff -NurpP --minimal linux-2.6.22.19/kernel/printk.c linux-2.6.22.19-vs2.2.0.7/kernel/printk.c
21388 +--- linux-2.6.22.19/kernel/printk.c 2007-07-09 13:20:03 +0200
21389 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/printk.c 2007-06-15 02:37:04 +0200
21390 +@@ -31,6 +31,7 @@
21391 + #include <linux/bootmem.h>
21392 + #include <linux/syscalls.h>
21393 + #include <linux/jiffies.h>
21394 ++#include <linux/vs_cvirt.h>
21395 +
21396 + #include <asm/uaccess.h>
21397 +
21398 +@@ -182,18 +183,13 @@ int do_syslog(int type, char __user *buf
21399 + unsigned long i, j, limit, count;
21400 + int do_clear = 0;
21401 + char c;
21402 +- int error = 0;
21403 ++ int error;
21404 +
21405 + error = security_syslog(type);
21406 + if (error)
21407 + return error;
21408 +
21409 +- switch (type) {
21410 +- case 0: /* Close log */
21411 +- break;
21412 +- case 1: /* Open log */
21413 +- break;
21414 +- case 2: /* Read from log */
21415 ++ if ((type >= 2) && (type <= 4)) {
21416 + error = -EINVAL;
21417 + if (!buf || len < 0)
21418 + goto out;
21419 +@@ -204,6 +200,16 @@ int do_syslog(int type, char __user *buf
21420 + error = -EFAULT;
21421 + goto out;
21422 + }
21423 ++ }
21424 ++ if (!vx_check(0, VS_ADMIN|VS_WATCH))
21425 ++ return vx_do_syslog(type, buf, len);
21426 ++
21427 ++ switch (type) {
21428 ++ case 0: /* Close log */
21429 ++ break;
21430 ++ case 1: /* Open log */
21431 ++ break;
21432 ++ case 2: /* Read from log */
21433 + error = wait_event_interruptible(log_wait,
21434 + (log_start - log_end));
21435 + if (error)
21436 +@@ -228,16 +234,6 @@ int do_syslog(int type, char __user *buf
21437 + do_clear = 1;
21438 + /* FALL THRU */
21439 + case 3: /* Read last kernel messages */
21440 +- error = -EINVAL;
21441 +- if (!buf || len < 0)
21442 +- goto out;
21443 +- error = 0;
21444 +- if (!len)
21445 +- goto out;
21446 +- if (!access_ok(VERIFY_WRITE, buf, len)) {
21447 +- error = -EFAULT;
21448 +- goto out;
21449 +- }
21450 + count = len;
21451 + if (count > log_buf_len)
21452 + count = log_buf_len;
21453 +diff -NurpP --minimal linux-2.6.22.19/kernel/ptrace.c linux-2.6.22.19-vs2.2.0.7/kernel/ptrace.c
21454 +--- linux-2.6.22.19/kernel/ptrace.c 2007-07-09 13:20:03 +0200
21455 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/ptrace.c 2007-06-15 04:28:02 +0200
21456 +@@ -19,6 +19,7 @@
21457 + #include <linux/security.h>
21458 + #include <linux/signal.h>
21459 + #include <linux/audit.h>
21460 ++#include <linux/vs_context.h>
21461 +
21462 + #include <asm/pgtable.h>
21463 + #include <asm/uaccess.h>
21464 +@@ -145,6 +146,11 @@ static int may_attach(struct task_struct
21465 + dumpable = task->mm->dumpable;
21466 + if (!dumpable && !capable(CAP_SYS_PTRACE))
21467 + return -EPERM;
21468 ++ if (!vx_check(task->xid, VS_ADMIN_P|VS_IDENT))
21469 ++ return -EPERM;
21470 ++ if (!vx_check(task->xid, VS_IDENT) &&
21471 ++ !task_vx_flags(task, VXF_STATE_ADMIN, 0))
21472 ++ return -EACCES;
21473 +
21474 + return security_ptrace(current, task);
21475 + }
21476 +@@ -471,6 +477,10 @@ asmlinkage long sys_ptrace(long request,
21477 + goto out;
21478 + }
21479 +
21480 ++ ret = -EPERM;
21481 ++ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT))
21482 ++ goto out_put_task_struct;
21483 ++
21484 + if (request == PTRACE_ATTACH) {
21485 + ret = ptrace_attach(child);
21486 + goto out_put_task_struct;
21487 +diff -NurpP --minimal linux-2.6.22.19/kernel/sched.c linux-2.6.22.19-vs2.2.0.7/kernel/sched.c
21488 +--- linux-2.6.22.19/kernel/sched.c 2007-07-09 13:20:03 +0200
21489 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/sched.c 2007-07-07 03:52:54 +0200
21490 +@@ -56,6 +56,8 @@
21491 +
21492 + #include <asm/tlb.h>
21493 + #include <asm/unistd.h>
21494 ++#include <linux/vs_sched.h>
21495 ++#include <linux/vs_cvirt.h>
21496 +
21497 + /*
21498 + * Scheduler clock - returns current time in nanosec units.
21499 +@@ -281,6 +283,16 @@ struct rq {
21500 + struct task_struct *migration_thread;
21501 + struct list_head migration_queue;
21502 + #endif
21503 ++ unsigned long norm_time;
21504 ++ unsigned long idle_time;
21505 ++#ifdef CONFIG_VSERVER_IDLETIME
21506 ++ int idle_skip;
21507 ++#endif
21508 ++#ifdef CONFIG_VSERVER_HARDCPU
21509 ++ struct list_head hold_queue;
21510 ++ unsigned long nr_onhold;
21511 ++ int idle_tokens;
21512 ++#endif
21513 +
21514 + #ifdef CONFIG_SCHEDSTATS
21515 + /* latency stats */
21516 +@@ -714,6 +726,7 @@ sched_info_switch(struct task_struct *pr
21517 + */
21518 + static void dequeue_task(struct task_struct *p, struct prio_array *array)
21519 + {
21520 ++ BUG_ON(p->state & TASK_ONHOLD);
21521 + array->nr_active--;
21522 + list_del(&p->run_list);
21523 + if (list_empty(array->queue + p->prio))
21524 +@@ -722,6 +735,7 @@ static void dequeue_task(struct task_str
21525 +
21526 + static void enqueue_task(struct task_struct *p, struct prio_array *array)
21527 + {
21528 ++ BUG_ON(p->state & TASK_ONHOLD);
21529 + sched_info_queued(p);
21530 + list_add_tail(&p->run_list, array->queue + p->prio);
21531 + __set_bit(p->prio, array->bitmap);
21532 +@@ -735,12 +749,14 @@ static void enqueue_task(struct task_str
21533 + */
21534 + static void requeue_task(struct task_struct *p, struct prio_array *array)
21535 + {
21536 ++ BUG_ON(p->state & TASK_ONHOLD);
21537 + list_move_tail(&p->run_list, array->queue + p->prio);
21538 + }
21539 +
21540 + static inline void
21541 + enqueue_task_head(struct task_struct *p, struct prio_array *array)
21542 + {
21543 ++ BUG_ON(p->state & TASK_ONHOLD);
21544 + list_add(&p->run_list, array->queue + p->prio);
21545 + __set_bit(p->prio, array->bitmap);
21546 + array->nr_active++;
21547 +@@ -769,6 +785,10 @@ static inline int __normal_prio(struct t
21548 + bonus = CURRENT_BONUS(p) - MAX_BONUS / 2;
21549 +
21550 + prio = p->static_prio - bonus;
21551 ++
21552 ++ /* adjust effective priority */
21553 ++ prio = vx_adjust_prio(p, prio, MAX_USER_PRIO);
21554 ++
21555 + if (prio < MAX_RT_PRIO)
21556 + prio = MAX_RT_PRIO;
21557 + if (prio > MAX_PRIO-1)
21558 +@@ -878,6 +898,9 @@ static int effective_prio(struct task_st
21559 + return p->prio;
21560 + }
21561 +
21562 ++#include "sched_mon.h"
21563 ++
21564 ++
21565 + /*
21566 + * __activate_task - move a task to the runqueue.
21567 + */
21568 +@@ -887,6 +910,7 @@ static void __activate_task(struct task_
21569 +
21570 + if (batch_task(p))
21571 + target = rq->expired;
21572 ++ vxm_activate_task(p, rq);
21573 + enqueue_task(p, target);
21574 + inc_nr_running(p, rq);
21575 + }
21576 +@@ -896,6 +920,7 @@ static void __activate_task(struct task_
21577 + */
21578 + static inline void __activate_idle_task(struct task_struct *p, struct rq *rq)
21579 + {
21580 ++ vxm_activate_idle(p, rq);
21581 + enqueue_task_head(p, rq->active);
21582 + inc_nr_running(p, rq);
21583 + }
21584 +@@ -1030,19 +1055,30 @@ static void activate_task(struct task_st
21585 + }
21586 + p->timestamp = now;
21587 + out:
21588 ++ vx_activate_task(p);
21589 + __activate_task(p, rq);
21590 + }
21591 +
21592 + /*
21593 +- * deactivate_task - remove a task from the runqueue.
21594 ++ * __deactivate_task - remove a task from the runqueue.
21595 + */
21596 +-static void deactivate_task(struct task_struct *p, struct rq *rq)
21597 ++static void __deactivate_task(struct task_struct *p, struct rq *rq)
21598 + {
21599 + dec_nr_running(p, rq);
21600 + dequeue_task(p, p->array);
21601 ++ vxm_deactivate_task(p, rq);
21602 + p->array = NULL;
21603 + }
21604 +
21605 ++static inline
21606 ++void deactivate_task(struct task_struct *p, struct rq *rq)
21607 ++{
21608 ++ vx_deactivate_task(p);
21609 ++ __deactivate_task(p, rq);
21610 ++}
21611 ++
21612 ++#include "sched_hard.h"
21613 ++
21614 + /*
21615 + * resched_task - mark a task 'to be rescheduled now'.
21616 + *
21617 +@@ -1129,6 +1165,7 @@ migrate_task(struct task_struct *p, int
21618 + {
21619 + struct rq *rq = task_rq(p);
21620 +
21621 ++ vxm_migrate_task(p, rq, dest_cpu);
21622 + /*
21623 + * If the task is not on a runqueue (and not running), then
21624 + * it is sufficient to simply update the task's cpu field.
21625 +@@ -1518,6 +1555,12 @@ static int try_to_wake_up(struct task_st
21626 +
21627 + rq = task_rq_lock(p, &flags);
21628 + old_state = p->state;
21629 ++
21630 ++ /* we need to unhold suspended tasks */
21631 ++ if (old_state & TASK_ONHOLD) {
21632 ++ vx_unhold_task(p, rq);
21633 ++ old_state = p->state;
21634 ++ }
21635 + if (!(old_state & state))
21636 + goto out;
21637 +
21638 +@@ -1625,6 +1668,7 @@ out_activate:
21639 + #endif /* CONFIG_SMP */
21640 + if (old_state == TASK_UNINTERRUPTIBLE) {
21641 + rq->nr_uninterruptible--;
21642 ++ vx_uninterruptible_dec(p);
21643 + /*
21644 + * Tasks on involuntary sleep don't earn
21645 + * sleep_avg beyond just interactive state.
21646 +@@ -1676,7 +1720,7 @@ int fastcall wake_up_state(struct task_s
21647 + return try_to_wake_up(p, state, 0);
21648 + }
21649 +
21650 +-static void task_running_tick(struct rq *rq, struct task_struct *p);
21651 ++static void task_running_tick(struct rq *rq, struct task_struct *p, int cpu);
21652 + /*
21653 + * Perform scheduler related setup for a newly forked process p.
21654 + * p is forked by current.
21655 +@@ -1737,7 +1781,7 @@ void fastcall sched_fork(struct task_str
21656 + * runqueue lock is not a problem.
21657 + */
21658 + current->time_slice = 1;
21659 +- task_running_tick(cpu_rq(cpu), current);
21660 ++ task_running_tick(cpu_rq(cpu), current, cpu);
21661 + }
21662 + local_irq_enable();
21663 + put_cpu();
21664 +@@ -1772,6 +1816,7 @@ void fastcall wake_up_new_task(struct ta
21665 +
21666 + p->prio = effective_prio(p);
21667 +
21668 ++ vx_activate_task(p);
21669 + if (likely(cpu == this_cpu)) {
21670 + if (!(clone_flags & CLONE_VM)) {
21671 + /*
21672 +@@ -1783,6 +1828,7 @@ void fastcall wake_up_new_task(struct ta
21673 + __activate_task(p, rq);
21674 + else {
21675 + p->prio = current->prio;
21676 ++ BUG_ON(p->state & TASK_ONHOLD);
21677 + p->normal_prio = current->normal_prio;
21678 + list_add_tail(&p->run_list, &current->run_list);
21679 + p->array = current->array;
21680 +@@ -3351,13 +3397,16 @@ static inline int expired_starving(struc
21681 + void account_user_time(struct task_struct *p, cputime_t cputime)
21682 + {
21683 + struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
21684 ++ struct vx_info *vxi = p->vx_info; /* p is _always_ current */
21685 + cputime64_t tmp;
21686 ++ int nice = (TASK_NICE(p) > 0);
21687 +
21688 + p->utime = cputime_add(p->utime, cputime);
21689 ++ vx_account_user(vxi, cputime, nice);
21690 +
21691 + /* Add user time to cpustat. */
21692 + tmp = cputime_to_cputime64(cputime);
21693 +- if (TASK_NICE(p) > 0)
21694 ++ if (nice)
21695 + cpustat->nice = cputime64_add(cpustat->nice, tmp);
21696 + else
21697 + cpustat->user = cputime64_add(cpustat->user, tmp);
21698 +@@ -3373,10 +3422,12 @@ void account_system_time(struct task_str
21699 + cputime_t cputime)
21700 + {
21701 + struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
21702 ++ struct vx_info *vxi = p->vx_info; /* p is _always_ current */
21703 + struct rq *rq = this_rq();
21704 + cputime64_t tmp;
21705 +
21706 + p->stime = cputime_add(p->stime, cputime);
21707 ++ vx_account_system(vxi, cputime, (p == rq->idle));
21708 +
21709 + /* Add system time to cpustat. */
21710 + tmp = cputime_to_cputime64(cputime);
21711 +@@ -3415,7 +3466,7 @@ void account_steal_time(struct task_stru
21712 + cpustat->steal = cputime64_add(cpustat->steal, tmp);
21713 + }
21714 +
21715 +-static void task_running_tick(struct rq *rq, struct task_struct *p)
21716 ++static void task_running_tick(struct rq *rq, struct task_struct *p, int cpu)
21717 + {
21718 + if (p->array != rq->active) {
21719 + /* Task has expired but was not scheduled yet */
21720 +@@ -3445,7 +3496,7 @@ static void task_running_tick(struct rq
21721 + }
21722 + goto out_unlock;
21723 + }
21724 +- if (!--p->time_slice) {
21725 ++ if (vx_need_resched(p, --p->time_slice, cpu)) {
21726 + dequeue_task(p, rq->active);
21727 + set_tsk_need_resched(p);
21728 + p->prio = effective_prio(p);
21729 +@@ -3506,9 +3557,12 @@ void scheduler_tick(void)
21730 + struct rq *rq = cpu_rq(cpu);
21731 +
21732 + update_cpu_clock(p, rq, now);
21733 +-
21734 +- if (!idle_at_tick)
21735 +- task_running_tick(rq, p);
21736 ++ vxm_sync(now, cpu);
21737 ++
21738 ++ if (idle_at_tick)
21739 ++ vx_idle_resched(rq);
21740 ++ else
21741 ++ task_running_tick(rq, p, cpu);
21742 + #ifdef CONFIG_SMP
21743 + update_load(rq);
21744 + rq->idle_at_tick = idle_at_tick;
21745 +@@ -3630,14 +3684,25 @@ need_resched_nonpreemptible:
21746 + unlikely(signal_pending(prev))))
21747 + prev->state = TASK_RUNNING;
21748 + else {
21749 +- if (prev->state == TASK_UNINTERRUPTIBLE)
21750 ++ if (prev->state == TASK_UNINTERRUPTIBLE) {
21751 + rq->nr_uninterruptible++;
21752 ++ vx_uninterruptible_inc(prev);
21753 ++ }
21754 + deactivate_task(prev, rq);
21755 + }
21756 + }
21757 +
21758 + cpu = smp_processor_id();
21759 ++ vx_set_rq_time(rq, jiffies);
21760 ++try_unhold:
21761 ++ vx_try_unhold(rq, cpu);
21762 ++pick_next:
21763 ++
21764 + if (unlikely(!rq->nr_running)) {
21765 ++ /* can we skip idle time? */
21766 ++ if (vx_try_skip(rq, cpu))
21767 ++ goto try_unhold;
21768 ++
21769 + idle_balance(cpu, rq);
21770 + if (!rq->nr_running) {
21771 + next = rq->idle;
21772 +@@ -3663,6 +3728,10 @@ need_resched_nonpreemptible:
21773 + queue = array->queue + idx;
21774 + next = list_entry(queue->next, struct task_struct, run_list);
21775 +
21776 ++ /* check before we schedule this context */
21777 ++ if (!vx_schedule(next, rq, cpu))
21778 ++ goto pick_next;
21779 ++
21780 + if (!rt_task(next) && interactive_sleep(next->sleep_type)) {
21781 + unsigned long long delta = now - next->timestamp;
21782 + if (unlikely((long long)(now - next->timestamp) < 0))
21783 +@@ -4263,7 +4332,7 @@ asmlinkage long sys_nice(int increment)
21784 + nice = 19;
21785 +
21786 + if (increment < 0 && !can_nice(current, nice))
21787 +- return -EPERM;
21788 ++ return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
21789 +
21790 + retval = security_task_setnice(current, nice);
21791 + if (retval)
21792 +@@ -4435,6 +4504,7 @@ recheck:
21793 + oldprio = p->prio;
21794 + __setscheduler(p, policy, param->sched_priority);
21795 + if (array) {
21796 ++ vx_activate_task(p);
21797 + __activate_task(p, rq);
21798 + /*
21799 + * Reschedule if we are currently running on this runqueue and
21800 +@@ -5188,6 +5258,7 @@ static int __migrate_task(struct task_st
21801 + p->timestamp = p->timestamp - rq_src->most_recent_timestamp
21802 + + rq_dest->most_recent_timestamp;
21803 + deactivate_task(p, rq_src);
21804 ++ vx_activate_task(p);
21805 + __activate_task(p, rq_dest);
21806 + if (TASK_PREEMPTS_CURR(p, rq_dest))
21807 + resched_task(rq_dest->curr);
21808 +@@ -7058,7 +7129,10 @@ void __init sched_init(void)
21809 + INIT_LIST_HEAD(&rq->migration_queue);
21810 + #endif
21811 + atomic_set(&rq->nr_iowait, 0);
21812 +-
21813 ++#ifdef CONFIG_VSERVER_HARDCPU
21814 ++ INIT_LIST_HEAD(&rq->hold_queue);
21815 ++ rq->nr_onhold = 0;
21816 ++#endif
21817 + for (j = 0; j < 2; j++) {
21818 + array = rq->arrays + j;
21819 + for (k = 0; k < MAX_PRIO; k++) {
21820 +@@ -7144,6 +7218,7 @@ void normalize_rt_tasks(void)
21821 + deactivate_task(p, task_rq(p));
21822 + __setscheduler(p, SCHED_NORMAL, 0);
21823 + if (array) {
21824 ++ vx_activate_task(p);
21825 + __activate_task(p, task_rq(p));
21826 + resched_task(rq->curr);
21827 + }
21828 +diff -NurpP --minimal linux-2.6.22.19/kernel/sched_hard.h linux-2.6.22.19-vs2.2.0.7/kernel/sched_hard.h
21829 +--- linux-2.6.22.19/kernel/sched_hard.h 1970-01-01 01:00:00 +0100
21830 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/sched_hard.h 2007-06-15 19:20:10 +0200
21831 +@@ -0,0 +1,324 @@
21832 ++
21833 ++#ifdef CONFIG_VSERVER_IDLELIMIT
21834 ++
21835 ++/*
21836 ++ * vx_idle_resched - reschedule after maxidle
21837 ++ */
21838 ++static inline
21839 ++void vx_idle_resched(struct rq *rq)
21840 ++{
21841 ++ /* maybe have a better criterion for paused */
21842 ++ if (!--rq->idle_tokens && !list_empty(&rq->hold_queue))
21843 ++ set_need_resched();
21844 ++}
21845 ++
21846 ++#else /* !CONFIG_VSERVER_IDLELIMIT */
21847 ++
21848 ++#define vx_idle_resched(rq)
21849 ++
21850 ++#endif /* CONFIG_VSERVER_IDLELIMIT */
21851 ++
21852 ++
21853 ++
21854 ++#ifdef CONFIG_VSERVER_IDLETIME
21855 ++
21856 ++#define vx_set_rq_min_skip(rq, min) \
21857 ++ (rq)->idle_skip = (min)
21858 ++
21859 ++#define vx_save_min_skip(ret, min, val) \
21860 ++ __vx_save_min_skip(ret, min, val)
21861 ++
21862 ++static inline
21863 ++void __vx_save_min_skip(int ret, int *min, int val)
21864 ++{
21865 ++ if (ret > -2)
21866 ++ return;
21867 ++ if ((*min > val) || !*min)
21868 ++ *min = val;
21869 ++}
21870 ++
21871 ++static inline
21872 ++int vx_try_skip(struct rq *rq, int cpu)
21873 ++{
21874 ++ /* artificially advance time */
21875 ++ if (rq->idle_skip > 0) {
21876 ++ vxdprintk(list_empty(&rq->hold_queue),
21877 ++ "hold queue empty on cpu %d", cpu);
21878 ++ rq->idle_time += rq->idle_skip;
21879 ++ vxm_idle_skip(rq, cpu);
21880 ++ return 1;
21881 ++ }
21882 ++ return 0;
21883 ++}
21884 ++
21885 ++#else /* !CONFIG_VSERVER_IDLETIME */
21886 ++
21887 ++#define vx_set_rq_min_skip(rq, min) \
21888 ++ ({ int dummy = (min); dummy; })
21889 ++
21890 ++#define vx_save_min_skip(ret, min, val)
21891 ++
21892 ++static inline
21893 ++int vx_try_skip(struct rq *rq, int cpu)
21894 ++{
21895 ++ return 0;
21896 ++}
21897 ++
21898 ++#endif /* CONFIG_VSERVER_IDLETIME */
21899 ++
21900 ++
21901 ++
21902 ++#ifdef CONFIG_VSERVER_HARDCPU
21903 ++
21904 ++#define vx_set_rq_max_idle(rq, max) \
21905 ++ (rq)->idle_tokens = (max)
21906 ++
21907 ++#define vx_save_max_idle(ret, min, val) \
21908 ++ __vx_save_max_idle(ret, min, val)
21909 ++
21910 ++static inline
21911 ++void __vx_save_max_idle(int ret, int *min, int val)
21912 ++{
21913 ++ if (*min > val)
21914 ++ *min = val;
21915 ++}
21916 ++
21917 ++
21918 ++/*
21919 ++ * vx_hold_task - put a task on the hold queue
21920 ++ */
21921 ++static inline
21922 ++void vx_hold_task(struct task_struct *p, struct rq *rq)
21923 ++{
21924 ++ __deactivate_task(p, rq);
21925 ++ p->state |= TASK_ONHOLD;
21926 ++ /* a new one on hold */
21927 ++ rq->nr_onhold++;
21928 ++ vxm_hold_task(p, rq);
21929 ++ list_add_tail(&p->run_list, &rq->hold_queue);
21930 ++}
21931 ++
21932 ++/*
21933 ++ * vx_unhold_task - put a task back to the runqueue
21934 ++ */
21935 ++static inline
21936 ++void vx_unhold_task(struct task_struct *p, struct rq *rq)
21937 ++{
21938 ++ list_del(&p->run_list);
21939 ++ /* one less waiting */
21940 ++ rq->nr_onhold--;
21941 ++ p->state &= ~TASK_ONHOLD;
21942 ++ enqueue_task(p, rq->expired);
21943 ++ inc_nr_running(p, rq);
21944 ++ vxm_unhold_task(p, rq);
21945 ++
21946 ++ if (p->static_prio < rq->best_expired_prio)
21947 ++ rq->best_expired_prio = p->static_prio;
21948 ++}
21949 ++
21950 ++unsigned long nr_onhold(void)
21951 ++{
21952 ++ unsigned long i, sum = 0;
21953 ++
21954 ++ for_each_online_cpu(i)
21955 ++ sum += cpu_rq(i)->nr_onhold;
21956 ++
21957 ++ return sum;
21958 ++}
21959 ++
21960 ++
21961 ++
21962 ++static inline
21963 ++int __vx_tokens_avail(struct _vx_sched_pc *sched_pc)
21964 ++{
21965 ++ return sched_pc->tokens;
21966 ++}
21967 ++
21968 ++static inline
21969 ++void __vx_consume_token(struct _vx_sched_pc *sched_pc)
21970 ++{
21971 ++ sched_pc->tokens--;
21972 ++}
21973 ++
21974 ++static inline
21975 ++int vx_need_resched(struct task_struct *p, int slice, int cpu)
21976 ++{
21977 ++ struct vx_info *vxi = p->vx_info;
21978 ++
21979 ++ if (vx_info_flags(vxi, VXF_SCHED_HARD|VXF_SCHED_PRIO, 0)) {
21980 ++ struct _vx_sched_pc *sched_pc =
21981 ++ &vx_per_cpu(vxi, sched_pc, cpu);
21982 ++ int tokens;
21983 ++
21984 ++ /* maybe we can simplify that to decrement
21985 ++ the token counter unconditional? */
21986 ++
21987 ++ if ((tokens = __vx_tokens_avail(sched_pc)) > 0)
21988 ++ __vx_consume_token(sched_pc);
21989 ++
21990 ++ /* for tokens > 0, one token was consumed */
21991 ++ if (tokens < 2)
21992 ++ slice = 0;
21993 ++ }
21994 ++ vxm_need_resched(p, slice, cpu);
21995 ++ return (slice == 0);
21996 ++}
21997 ++
21998 ++
21999 ++#define vx_set_rq_time(rq, time) do { \
22000 ++ rq->norm_time = time; \
22001 ++} while (0)
22002 ++
22003 ++
22004 ++static inline
22005 ++void vx_try_unhold(struct rq *rq, int cpu)
22006 ++{
22007 ++ struct vx_info *vxi = NULL;
22008 ++ struct list_head *l, *n;
22009 ++ int maxidle = HZ;
22010 ++ int minskip = 0;
22011 ++
22012 ++ /* nothing to do? what about pause? */
22013 ++ if (list_empty(&rq->hold_queue))
22014 ++ return;
22015 ++
22016 ++ list_for_each_safe(l, n, &rq->hold_queue) {
22017 ++ int ret, delta_min[2];
22018 ++ struct _vx_sched_pc *sched_pc;
22019 ++ struct task_struct *p;
22020 ++
22021 ++ p = list_entry(l, struct task_struct, run_list);
22022 ++ /* don't bother with same context */
22023 ++ if (vxi == p->vx_info)
22024 ++ continue;
22025 ++
22026 ++ vxi = p->vx_info;
22027 ++ /* ignore paused contexts */
22028 ++ if (vx_info_flags(vxi, VXF_SCHED_PAUSE, 0))
22029 ++ continue;
22030 ++
22031 ++ sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
22032 ++
22033 ++ /* recalc tokens */
22034 ++ vxm_sched_info(sched_pc, vxi, cpu);
22035 ++ ret = vx_tokens_recalc(sched_pc,
22036 ++ &rq->norm_time, &rq->idle_time, delta_min);
22037 ++ vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
22038 ++
22039 ++ if (ret > 0) {
22040 ++ /* we found a runable context */
22041 ++ vx_unhold_task(p, rq);
22042 ++ break;
22043 ++ }
22044 ++ vx_save_max_idle(ret, &maxidle, delta_min[0]);
22045 ++ vx_save_min_skip(ret, &minskip, delta_min[1]);
22046 ++ }
22047 ++ vx_set_rq_max_idle(rq, maxidle);
22048 ++ vx_set_rq_min_skip(rq, minskip);
22049 ++ vxm_rq_max_min(rq, cpu);
22050 ++}
22051 ++
22052 ++
22053 ++static inline
22054 ++int vx_schedule(struct task_struct *next, struct rq *rq, int cpu)
22055 ++{
22056 ++ struct vx_info *vxi = next->vx_info;
22057 ++ struct _vx_sched_pc *sched_pc;
22058 ++ int delta_min[2];
22059 ++ int flags, ret;
22060 ++
22061 ++ if (!vxi)
22062 ++ return 1;
22063 ++
22064 ++ flags = vxi->vx_flags;
22065 ++
22066 ++ if (unlikely(vs_check_flags(flags, VXF_SCHED_PAUSE, 0)))
22067 ++ goto put_on_hold;
22068 ++ if (!vs_check_flags(flags, VXF_SCHED_HARD | VXF_SCHED_PRIO, 0))
22069 ++ return 1;
22070 ++
22071 ++ sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
22072 ++#ifdef CONFIG_SMP
22073 ++ /* update scheduler params */
22074 ++ if (cpu_isset(cpu, vxi->sched.update)) {
22075 ++ vx_update_sched_param(&vxi->sched, sched_pc);
22076 ++ vxm_update_sched(sched_pc, vxi, cpu);
22077 ++ cpu_clear(cpu, vxi->sched.update);
22078 ++ }
22079 ++#endif
22080 ++ vxm_sched_info(sched_pc, vxi, cpu);
22081 ++ ret = vx_tokens_recalc(sched_pc,
22082 ++ &rq->norm_time, &rq->idle_time, delta_min);
22083 ++ vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
22084 ++
22085 ++ if (!vs_check_flags(flags, VXF_SCHED_HARD, 0))
22086 ++ return 1;
22087 ++
22088 ++ if (unlikely(ret < 0)) {
22089 ++ vx_save_max_idle(ret, &rq->idle_tokens, delta_min[0]);
22090 ++ vx_save_min_skip(ret, &rq->idle_skip, delta_min[1]);
22091 ++ vxm_rq_max_min(rq, cpu);
22092 ++ put_on_hold:
22093 ++ vx_hold_task(next, rq);
22094 ++ return 0;
22095 ++ }
22096 ++ return 1;
22097 ++}
22098 ++
22099 ++
22100 ++#else /* CONFIG_VSERVER_HARDCPU */
22101 ++
22102 ++static inline
22103 ++void vx_hold_task(struct task_struct *p, struct rq *rq)
22104 ++{
22105 ++ return;
22106 ++}
22107 ++
22108 ++static inline
22109 ++void vx_unhold_task(struct task_struct *p, struct rq *rq)
22110 ++{
22111 ++ return;
22112 ++}
22113 ++
22114 ++unsigned long nr_onhold(void)
22115 ++{
22116 ++ return 0;
22117 ++}
22118 ++
22119 ++
22120 ++static inline
22121 ++int vx_need_resched(struct task_struct *p, int slice, int cpu)
22122 ++{
22123 ++ return (slice == 0);
22124 ++}
22125 ++
22126 ++
22127 ++#define vx_set_rq_time(rq, time)
22128 ++
22129 ++static inline
22130 ++void vx_try_unhold(struct rq *rq, int cpu)
22131 ++{
22132 ++ return;
22133 ++}
22134 ++
22135 ++static inline
22136 ++int vx_schedule(struct task_struct *next, struct rq *rq, int cpu)
22137 ++{
22138 ++ struct vx_info *vxi = next->vx_info;
22139 ++ struct _vx_sched_pc *sched_pc;
22140 ++ int delta_min[2];
22141 ++ int ret;
22142 ++
22143 ++ if (!vx_info_flags(vxi, VXF_SCHED_PRIO, 0))
22144 ++ return 1;
22145 ++
22146 ++ sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
22147 ++ vxm_sched_info(sched_pc, vxi, cpu);
22148 ++ ret = vx_tokens_recalc(sched_pc,
22149 ++ &rq->norm_time, &rq->idle_time, delta_min);
22150 ++ vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
22151 ++ return 1;
22152 ++}
22153 ++
22154 ++#endif /* CONFIG_VSERVER_HARDCPU */
22155 ++
22156 +diff -NurpP --minimal linux-2.6.22.19/kernel/sched_mon.h linux-2.6.22.19-vs2.2.0.7/kernel/sched_mon.h
22157 +--- linux-2.6.22.19/kernel/sched_mon.h 1970-01-01 01:00:00 +0100
22158 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/sched_mon.h 2007-06-15 02:37:04 +0200
22159 +@@ -0,0 +1,200 @@
22160 ++
22161 ++#include <linux/vserver/monitor.h>
22162 ++
22163 ++#ifdef CONFIG_VSERVER_MONITOR
22164 ++
22165 ++#ifdef CONFIG_VSERVER_HARDCPU
22166 ++#define HARDCPU(x) (x)
22167 ++#else
22168 ++#define HARDCPU(x) (0)
22169 ++#endif
22170 ++
22171 ++#ifdef CONFIG_VSERVER_IDLETIME
22172 ++#define IDLETIME(x) (x)
22173 ++#else
22174 ++#define IDLETIME(x) (0)
22175 ++#endif
22176 ++
22177 ++struct _vx_mon_entry *vxm_advance(int cpu);
22178 ++
22179 ++
22180 ++static inline
22181 ++void __vxm_basic(struct _vx_mon_entry *entry, xid_t xid, int type)
22182 ++{
22183 ++ entry->type = type;
22184 ++ entry->xid = xid;
22185 ++}
22186 ++
22187 ++static inline
22188 ++void __vxm_sync(int cpu)
22189 ++{
22190 ++ struct _vx_mon_entry *entry = vxm_advance(cpu);
22191 ++
22192 ++ __vxm_basic(entry, 0, VXM_SYNC);
22193 ++ entry->ev.sec = xtime.tv_sec;
22194 ++ entry->ev.nsec = xtime.tv_nsec;
22195 ++}
22196 ++
22197 ++static inline
22198 ++void __vxm_task(struct task_struct *p, int type)
22199 ++{
22200 ++ struct _vx_mon_entry *entry = vxm_advance(task_cpu(p));
22201 ++
22202 ++ __vxm_basic(entry, p->xid, type);
22203 ++ entry->ev.tsk.pid = p->pid;
22204 ++ entry->ev.tsk.state = p->state;
22205 ++}
22206 ++
22207 ++static inline
22208 ++void __vxm_sched(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
22209 ++{
22210 ++ struct _vx_mon_entry *entry = vxm_advance(cpu);
22211 ++
22212 ++ __vxm_basic(entry, vxi->vx_id, (VXM_SCHED | s->flags));
22213 ++ entry->sd.tokens = s->tokens;
22214 ++ entry->sd.norm_time = s->norm_time;
22215 ++ entry->sd.idle_time = s->idle_time;
22216 ++}
22217 ++
22218 ++static inline
22219 ++void __vxm_rqinfo1(struct rq *q, int cpu)
22220 ++{
22221 ++ struct _vx_mon_entry *entry = vxm_advance(cpu);
22222 ++
22223 ++ entry->type = VXM_RQINFO_1;
22224 ++ entry->xid = ((unsigned long)q >> 16) & 0xffff;
22225 ++ entry->q1.running = q->nr_running;
22226 ++ entry->q1.onhold = HARDCPU(q->nr_onhold);
22227 ++ entry->q1.iowait = atomic_read(&q->nr_iowait);
22228 ++ entry->q1.uintr = q->nr_uninterruptible;
22229 ++ entry->q1.idle_tokens = IDLETIME(q->idle_tokens);
22230 ++}
22231 ++
22232 ++static inline
22233 ++void __vxm_rqinfo2(struct rq *q, int cpu)
22234 ++{
22235 ++ struct _vx_mon_entry *entry = vxm_advance(cpu);
22236 ++
22237 ++ entry->type = VXM_RQINFO_2;
22238 ++ entry->xid = (unsigned long)q & 0xffff;
22239 ++ entry->q2.norm_time = q->norm_time;
22240 ++ entry->q2.idle_time = q->idle_time;
22241 ++ entry->q2.idle_skip = IDLETIME(q->idle_skip);
22242 ++}
22243 ++
22244 ++static inline
22245 ++void __vxm_update(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
22246 ++{
22247 ++ struct _vx_mon_entry *entry = vxm_advance(cpu);
22248 ++
22249 ++ __vxm_basic(entry, vxi->vx_id, VXM_UPDATE);
22250 ++ entry->ev.tokens = s->tokens;
22251 ++}
22252 ++
22253 ++static inline
22254 ++void __vxm_update1(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
22255 ++{
22256 ++ struct _vx_mon_entry *entry = vxm_advance(cpu);
22257 ++
22258 ++ __vxm_basic(entry, vxi->vx_id, VXM_UPDATE_1);
22259 ++ entry->u1.tokens_max = s->tokens_max;
22260 ++ entry->u1.fill_rate = s->fill_rate[0];
22261 ++ entry->u1.interval = s->interval[0];
22262 ++}
22263 ++
22264 ++static inline
22265 ++void __vxm_update2(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
22266 ++{
22267 ++ struct _vx_mon_entry *entry = vxm_advance(cpu);
22268 ++
22269 ++ __vxm_basic(entry, vxi->vx_id, VXM_UPDATE_2);
22270 ++ entry->u2.tokens_min = s->tokens_min;
22271 ++ entry->u2.fill_rate = s->fill_rate[1];
22272 ++ entry->u2.interval = s->interval[1];
22273 ++}
22274 ++
22275 ++
22276 ++#define vxm_activate_task(p,q) __vxm_task(p, VXM_ACTIVATE)
22277 ++#define vxm_activate_idle(p,q) __vxm_task(p, VXM_IDLE)
22278 ++#define vxm_deactivate_task(p,q) __vxm_task(p, VXM_DEACTIVATE)
22279 ++#define vxm_hold_task(p,q) __vxm_task(p, VXM_HOLD)
22280 ++#define vxm_unhold_task(p,q) __vxm_task(p, VXM_UNHOLD)
22281 ++
22282 ++static inline
22283 ++void vxm_migrate_task(struct task_struct *p, struct rq *rq, int dest)
22284 ++{
22285 ++ __vxm_task(p, VXM_MIGRATE);
22286 ++ __vxm_rqinfo1(rq, task_cpu(p));
22287 ++ __vxm_rqinfo2(rq, task_cpu(p));
22288 ++}
22289 ++
22290 ++static inline
22291 ++void vxm_idle_skip(struct rq *rq, int cpu)
22292 ++{
22293 ++ __vxm_rqinfo1(rq, cpu);
22294 ++ __vxm_rqinfo2(rq, cpu);
22295 ++}
22296 ++
22297 ++static inline
22298 ++void vxm_need_resched(struct task_struct *p, int slice, int cpu)
22299 ++{
22300 ++ if (slice)
22301 ++ return;
22302 ++
22303 ++ __vxm_task(p, VXM_RESCHED);
22304 ++}
22305 ++
22306 ++static inline
22307 ++void vxm_sync(unsigned long now, int cpu)
22308 ++{
22309 ++ if (!CONFIG_VSERVER_MONITOR_SYNC ||
22310 ++ (now % CONFIG_VSERVER_MONITOR_SYNC))
22311 ++ return;
22312 ++
22313 ++ __vxm_sync(cpu);
22314 ++}
22315 ++
22316 ++#define vxm_sched_info(s,v,c) __vxm_sched(s,v,c)
22317 ++
22318 ++static inline
22319 ++void vxm_tokens_recalc(struct _vx_sched_pc *s, struct rq *rq,
22320 ++ struct vx_info *vxi, int cpu)
22321 ++{
22322 ++ __vxm_sched(s, vxi, cpu);
22323 ++ __vxm_rqinfo2(rq, cpu);
22324 ++}
22325 ++
22326 ++static inline
22327 ++void vxm_update_sched(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
22328 ++{
22329 ++ __vxm_sched(s, vxi, cpu);
22330 ++ __vxm_update(s, vxi, cpu);
22331 ++ __vxm_update1(s, vxi, cpu);
22332 ++ __vxm_update2(s, vxi, cpu);
22333 ++}
22334 ++
22335 ++static inline
22336 ++void vxm_rq_max_min(struct rq *rq, int cpu)
22337 ++{
22338 ++ __vxm_rqinfo1(rq, cpu);
22339 ++ __vxm_rqinfo2(rq, cpu);
22340 ++}
22341 ++
22342 ++#else /* CONFIG_VSERVER_MONITOR */
22343 ++
22344 ++#define vxm_activate_task(t,q) do { } while (0)
22345 ++#define vxm_activate_idle(t,q) do { } while (0)
22346 ++#define vxm_deactivate_task(t,q) do { } while (0)
22347 ++#define vxm_hold_task(t,q) do { } while (0)
22348 ++#define vxm_unhold_task(t,q) do { } while (0)
22349 ++#define vxm_migrate_task(t,q,d) do { } while (0)
22350 ++#define vxm_idle_skip(q,c) do { } while (0)
22351 ++#define vxm_need_resched(t,s,c) do { } while (0)
22352 ++#define vxm_sync(s,c) do { } while (0)
22353 ++#define vxm_sched_info(s,v,c) do { } while (0)
22354 ++#define vxm_tokens_recalc(s,q,v,c) do { } while (0)
22355 ++#define vxm_update_sched(s,v,c) do { } while (0)
22356 ++#define vxm_rq_max_min(q,c) do { } while (0)
22357 ++
22358 ++#endif /* CONFIG_VSERVER_MONITOR */
22359 ++
22360 +diff -NurpP --minimal linux-2.6.22.19/kernel/signal.c linux-2.6.22.19-vs2.2.0.7/kernel/signal.c
22361 +--- linux-2.6.22.19/kernel/signal.c 2008-03-14 20:19:04 +0100
22362 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/signal.c 2008-01-18 13:34:41 +0100
22363 +@@ -26,6 +26,8 @@
22364 + #include <linux/freezer.h>
22365 + #include <linux/pid_namespace.h>
22366 + #include <linux/nsproxy.h>
22367 ++#include <linux/vs_context.h>
22368 ++#include <linux/vs_pid.h>
22369 +
22370 + #include <asm/param.h>
22371 + #include <asm/uaccess.h>
22372 +@@ -523,19 +525,34 @@ static int check_kill_permission(int sig
22373 + if (!valid_signal(sig))
22374 + return error;
22375 +
22376 ++ if ((info != SEND_SIG_NOINFO) &&
22377 ++ (is_si_special(info) || !SI_FROMUSER(info)))
22378 ++ goto skip;
22379 ++
22380 ++ vxdprintk(VXD_CBIT(misc, 7),
22381 ++ "check_kill_permission(%d,%p,%p[#%u,%u])",
22382 ++ sig, info, t, vx_task_xid(t), t->pid);
22383 ++
22384 + error = audit_signal_info(sig, t); /* Let audit system see the signal */
22385 + if (error)
22386 + return error;
22387 +
22388 + error = -EPERM;
22389 +- if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
22390 +- && ((sig != SIGCONT) ||
22391 ++ if (((sig != SIGCONT) ||
22392 + (process_session(current) != process_session(t)))
22393 + && (current->euid ^ t->suid) && (current->euid ^ t->uid)
22394 + && (current->uid ^ t->suid) && (current->uid ^ t->uid)
22395 + && !capable(CAP_KILL))
22396 + return error;
22397 +
22398 ++ error = -ESRCH;
22399 ++ if (!vx_check(vx_task_xid(t), VS_WATCH_P | VS_IDENT)) {
22400 ++ vxdprintk(current->xid || VXD_CBIT(misc, 7),
22401 ++ "signal %d[%p] xid mismatch %p[#%u,%u] xid=#%u",
22402 ++ sig, info, t, vx_task_xid(t), t->pid, current->xid);
22403 ++ return error;
22404 ++ }
22405 ++skip:
22406 + return security_task_kill(t, info, sig, 0);
22407 + }
22408 +
22409 +@@ -1043,7 +1060,7 @@ int kill_pid_info(int sig, struct siginf
22410 +
22411 + p = pid_task(pid, PIDTYPE_PID);
22412 + error = -ESRCH;
22413 +- if (p)
22414 ++ if (p && vx_check(vx_task_xid(p), VS_IDENT))
22415 + error = group_send_sig_info(sig, info, p);
22416 +
22417 + if (unlikely(sig_needs_tasklist(sig)))
22418 +@@ -1057,7 +1074,7 @@ kill_proc_info(int sig, struct siginfo *
22419 + {
22420 + int error;
22421 + rcu_read_lock();
22422 +- error = kill_pid_info(sig, info, find_pid(pid));
22423 ++ error = kill_pid_info(sig, info, find_pid(vx_rmap_pid(pid)));
22424 + rcu_read_unlock();
22425 + return error;
22426 + }
22427 +@@ -1118,7 +1135,9 @@ static int kill_something_info(int sig,
22428 +
22429 + read_lock(&tasklist_lock);
22430 + for_each_process(p) {
22431 +- if (p->pid > 1 && p->tgid != current->tgid) {
22432 ++ if (vx_check(vx_task_xid(p), VS_ADMIN_P|VS_IDENT) &&
22433 ++ p->pid > 1 && p->tgid != current->tgid &&
22434 ++ !vx_current_initpid(p->pid)) {
22435 + int err = group_send_sig_info(sig, info, p);
22436 + ++count;
22437 + if (err != -EPERM)
22438 +@@ -1128,9 +1147,9 @@ static int kill_something_info(int sig,
22439 + read_unlock(&tasklist_lock);
22440 + ret = count ? retval : -ESRCH;
22441 + } else if (pid < 0) {
22442 +- ret = kill_pgrp_info(sig, info, find_pid(-pid));
22443 ++ ret = kill_pgrp_info(sig, info, find_pid(vx_rmap_pid(-pid)));
22444 + } else {
22445 +- ret = kill_pid_info(sig, info, find_pid(pid));
22446 ++ ret = kill_pid_info(sig, info, find_pid(vx_rmap_pid(pid)));
22447 + }
22448 + rcu_read_unlock();
22449 + return ret;
22450 +@@ -1814,6 +1833,11 @@ relock:
22451 + if (current == child_reaper(current))
22452 + continue;
22453 +
22454 ++ /* virtual init is protected against user signals */
22455 ++ if ((info->si_code == SI_USER) &&
22456 ++ vx_current_initpid(current->pid))
22457 ++ continue;
22458 ++
22459 + if (sig_kernel_stop(signr)) {
22460 + /*
22461 + * The default action is to stop all threads in
22462 +diff -NurpP --minimal linux-2.6.22.19/kernel/softirq.c linux-2.6.22.19-vs2.2.0.7/kernel/softirq.c
22463 +--- linux-2.6.22.19/kernel/softirq.c 2007-07-09 13:20:03 +0200
22464 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/softirq.c 2007-06-15 02:37:04 +0200
22465 +@@ -18,6 +18,7 @@
22466 + #include <linux/rcupdate.h>
22467 + #include <linux/smp.h>
22468 + #include <linux/tick.h>
22469 ++#include <linux/vs_context.h>
22470 +
22471 + #include <asm/irq.h>
22472 + /*
22473 +diff -NurpP --minimal linux-2.6.22.19/kernel/sys.c linux-2.6.22.19-vs2.2.0.7/kernel/sys.c
22474 +--- linux-2.6.22.19/kernel/sys.c 2008-03-14 20:19:04 +0100
22475 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/sys.c 2008-01-09 20:53:07 +0100
22476 +@@ -35,6 +35,7 @@
22477 + #include <linux/compat.h>
22478 + #include <linux/syscalls.h>
22479 + #include <linux/kprobes.h>
22480 ++#include <linux/vs_pid.h>
22481 +
22482 + #include <asm/uaccess.h>
22483 + #include <asm/io.h>
22484 +@@ -638,7 +639,10 @@ static int set_one_prio(struct task_stru
22485 + goto out;
22486 + }
22487 + if (niceval < task_nice(p) && !can_nice(p, niceval)) {
22488 +- error = -EACCES;
22489 ++ if (vx_flags(VXF_IGNEG_NICE, 0))
22490 ++ error = 0;
22491 ++ else
22492 ++ error = -EACCES;
22493 + goto out;
22494 + }
22495 + no_nice = security_task_setnice(p, niceval);
22496 +@@ -686,6 +690,8 @@ asmlinkage long sys_setpriority(int whic
22497 + else
22498 + pgrp = task_pgrp(current);
22499 + do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
22500 ++ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
22501 ++ continue;
22502 + error = set_one_prio(p, niceval, error);
22503 + } while_each_pid_task(pgrp, PIDTYPE_PGID, p);
22504 + break;
22505 +@@ -694,7 +700,8 @@ asmlinkage long sys_setpriority(int whic
22506 + if (!who)
22507 + who = current->uid;
22508 + else
22509 +- if ((who != current->uid) && !(user = find_user(who)))
22510 ++ if ((who != current->uid) &&
22511 ++ !(user = find_user(vx_current_xid(), who)))
22512 + goto out_unlock; /* No processes for this user */
22513 +
22514 + do_each_thread(g, p)
22515 +@@ -746,6 +753,8 @@ asmlinkage long sys_getpriority(int whic
22516 + else
22517 + pgrp = task_pgrp(current);
22518 + do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
22519 ++ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
22520 ++ continue;
22521 + niceval = 20 - task_nice(p);
22522 + if (niceval > retval)
22523 + retval = niceval;
22524 +@@ -756,7 +765,8 @@ asmlinkage long sys_getpriority(int whic
22525 + if (!who)
22526 + who = current->uid;
22527 + else
22528 +- if ((who != current->uid) && !(user = find_user(who)))
22529 ++ if ((who != current->uid) &&
22530 ++ !(user = find_user(vx_current_xid(), who)))
22531 + goto out_unlock; /* No processes for this user */
22532 +
22533 + do_each_thread(g, p)
22534 +@@ -869,6 +879,9 @@ void kernel_power_off(void)
22535 + machine_power_off();
22536 + }
22537 + EXPORT_SYMBOL_GPL(kernel_power_off);
22538 ++
22539 ++long vs_reboot(unsigned int, void __user *);
22540 ++
22541 + /*
22542 + * Reboot system call: for obvious reasons only root may call it,
22543 + * and even root needs to set up some magic numbers in the registers
22544 +@@ -899,6 +912,9 @@ asmlinkage long sys_reboot(int magic1, i
22545 + if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
22546 + cmd = LINUX_REBOOT_CMD_HALT;
22547 +
22548 ++ if (!vx_check(0, VS_ADMIN|VS_WATCH))
22549 ++ return vs_reboot(cmd, arg);
22550 ++
22551 + lock_kernel();
22552 + switch (cmd) {
22553 + case LINUX_REBOOT_CMD_RESTART:
22554 +@@ -1078,7 +1094,7 @@ static int set_user(uid_t new_ruid, int
22555 + {
22556 + struct user_struct *new_user;
22557 +
22558 +- new_user = alloc_uid(new_ruid);
22559 ++ new_user = alloc_uid(vx_current_xid(), new_ruid);
22560 + if (!new_user)
22561 + return -EAGAIN;
22562 +
22563 +@@ -1432,15 +1448,18 @@ asmlinkage long sys_setpgid(pid_t pid, p
22564 + {
22565 + struct task_struct *p;
22566 + struct task_struct *group_leader = current->group_leader;
22567 ++ pid_t rpgid;
22568 + int err = -EINVAL;
22569 +
22570 + if (!pid)
22571 +- pid = group_leader->pid;
22572 ++ pid = vx_map_pid(group_leader->pid);
22573 + if (!pgid)
22574 + pgid = pid;
22575 + if (pgid < 0)
22576 + return -EINVAL;
22577 +
22578 ++ rpgid = vx_rmap_pid(pgid);
22579 ++
22580 + /* From this point forward we keep holding onto the tasklist lock
22581 + * so that our parent does not change from under us. -DaveM
22582 + */
22583 +@@ -1474,20 +1493,20 @@ asmlinkage long sys_setpgid(pid_t pid, p
22584 +
22585 + if (pgid != pid) {
22586 + struct task_struct *g =
22587 +- find_task_by_pid_type(PIDTYPE_PGID, pgid);
22588 ++ find_task_by_pid_type(PIDTYPE_PGID, rpgid);
22589 +
22590 + if (!g || task_session(g) != task_session(group_leader))
22591 + goto out;
22592 + }
22593 +
22594 +- err = security_task_setpgid(p, pgid);
22595 ++ err = security_task_setpgid(p, rpgid);
22596 + if (err)
22597 + goto out;
22598 +
22599 +- if (process_group(p) != pgid) {
22600 ++ if (process_group(p) != rpgid) {
22601 + detach_pid(p, PIDTYPE_PGID);
22602 +- p->signal->pgrp = pgid;
22603 +- attach_pid(p, PIDTYPE_PGID, find_pid(pgid));
22604 ++ p->signal->pgrp = rpgid;
22605 ++ attach_pid(p, PIDTYPE_PGID, find_pid(rpgid));
22606 + }
22607 +
22608 + err = 0;
22609 +@@ -1500,7 +1519,7 @@ out:
22610 + asmlinkage long sys_getpgid(pid_t pid)
22611 + {
22612 + if (!pid)
22613 +- return process_group(current);
22614 ++ return vx_rmap_pid(process_group(current));
22615 + else {
22616 + int retval;
22617 + struct task_struct *p;
22618 +@@ -1512,7 +1531,7 @@ asmlinkage long sys_getpgid(pid_t pid)
22619 + if (p) {
22620 + retval = security_task_getpgid(p);
22621 + if (!retval)
22622 +- retval = process_group(p);
22623 ++ retval = vx_rmap_pid(process_group(p));
22624 + }
22625 + read_unlock(&tasklist_lock);
22626 + return retval;
22627 +@@ -1863,7 +1882,7 @@ asmlinkage long sys_sethostname(char __u
22628 + int errno;
22629 + char tmp[__NEW_UTS_LEN];
22630 +
22631 +- if (!capable(CAP_SYS_ADMIN))
22632 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME))
22633 + return -EPERM;
22634 + if (len < 0 || len > __NEW_UTS_LEN)
22635 + return -EINVAL;
22636 +@@ -1908,7 +1927,7 @@ asmlinkage long sys_setdomainname(char _
22637 + int errno;
22638 + char tmp[__NEW_UTS_LEN];
22639 +
22640 +- if (!capable(CAP_SYS_ADMIN))
22641 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME))
22642 + return -EPERM;
22643 + if (len < 0 || len > __NEW_UTS_LEN)
22644 + return -EINVAL;
22645 +@@ -1975,7 +1994,7 @@ asmlinkage long sys_setrlimit(unsigned i
22646 + return -EINVAL;
22647 + old_rlim = current->signal->rlim + resource;
22648 + if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
22649 +- !capable(CAP_SYS_RESOURCE))
22650 ++ !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
22651 + return -EPERM;
22652 + if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN)
22653 + return -EPERM;
22654 +diff -NurpP --minimal linux-2.6.22.19/kernel/sysctl.c linux-2.6.22.19-vs2.2.0.7/kernel/sysctl.c
22655 +--- linux-2.6.22.19/kernel/sysctl.c 2007-07-09 13:20:03 +0200
22656 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/sysctl.c 2007-06-15 02:37:04 +0200
22657 +@@ -89,6 +89,7 @@ static int ngroups_max = NGROUPS_MAX;
22658 + #ifdef CONFIG_KMOD
22659 + extern char modprobe_path[];
22660 + #endif
22661 ++extern char vshelper_path[];
22662 + #ifdef CONFIG_CHR_DEV_SG
22663 + extern int sg_big_buff;
22664 + #endif
22665 +@@ -343,6 +344,15 @@ static ctl_table kern_table[] = {
22666 + .strategy = &sysctl_string,
22667 + },
22668 + #endif
22669 ++ {
22670 ++ .ctl_name = KERN_VSHELPER,
22671 ++ .procname = "vshelper",
22672 ++ .data = &vshelper_path,
22673 ++ .maxlen = 256,
22674 ++ .mode = 0644,
22675 ++ .proc_handler = &proc_dostring,
22676 ++ .strategy = &sysctl_string,
22677 ++ },
22678 + #ifdef CONFIG_CHR_DEV_SG
22679 + {
22680 + .ctl_name = KERN_SG_BIG_BUFF,
22681 +diff -NurpP --minimal linux-2.6.22.19/kernel/time.c linux-2.6.22.19-vs2.2.0.7/kernel/time.c
22682 +--- linux-2.6.22.19/kernel/time.c 2007-07-09 13:20:03 +0200
22683 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/time.c 2007-06-15 02:37:04 +0200
22684 +@@ -60,7 +60,7 @@ asmlinkage long sys_time(time_t __user *
22685 + time_t i;
22686 + struct timeval tv;
22687 +
22688 +- do_gettimeofday(&tv);
22689 ++ vx_gettimeofday(&tv);
22690 + i = tv.tv_sec;
22691 +
22692 + if (tloc) {
22693 +@@ -91,7 +91,7 @@ asmlinkage long sys_stime(time_t __user
22694 + if (err)
22695 + return err;
22696 +
22697 +- do_settimeofday(&tv);
22698 ++ vx_settimeofday(&tv);
22699 + return 0;
22700 + }
22701 +
22702 +@@ -101,7 +101,7 @@ asmlinkage long sys_gettimeofday(struct
22703 + {
22704 + if (likely(tv != NULL)) {
22705 + struct timeval ktv;
22706 +- do_gettimeofday(&ktv);
22707 ++ vx_gettimeofday(&ktv);
22708 + if (copy_to_user(tv, &ktv, sizeof(ktv)))
22709 + return -EFAULT;
22710 + }
22711 +@@ -175,7 +175,7 @@ int do_sys_settimeofday(struct timespec
22712 + /* SMP safe, again the code in arch/foo/time.c should
22713 + * globally block out interrupts when it runs.
22714 + */
22715 +- return do_settimeofday(tv);
22716 ++ return vx_settimeofday(tv);
22717 + }
22718 + return 0;
22719 + }
22720 +@@ -388,7 +388,7 @@ void getnstimeofday(struct timespec *tv)
22721 + {
22722 + struct timeval x;
22723 +
22724 +- do_gettimeofday(&x);
22725 ++ vx_gettimeofday(&x);
22726 + tv->tv_sec = x.tv_sec;
22727 + tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
22728 + }
22729 +diff -NurpP --minimal linux-2.6.22.19/kernel/timer.c linux-2.6.22.19-vs2.2.0.7/kernel/timer.c
22730 +--- linux-2.6.22.19/kernel/timer.c 2007-07-09 13:20:04 +0200
22731 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/timer.c 2007-06-15 02:37:04 +0200
22732 +@@ -36,6 +36,10 @@
22733 + #include <linux/delay.h>
22734 + #include <linux/tick.h>
22735 + #include <linux/kallsyms.h>
22736 ++#include <linux/vs_base.h>
22737 ++#include <linux/vs_cvirt.h>
22738 ++#include <linux/vs_pid.h>
22739 ++#include <linux/vserver/sched.h>
22740 +
22741 + #include <asm/uaccess.h>
22742 + #include <asm/unistd.h>
22743 +@@ -921,12 +925,6 @@ asmlinkage unsigned long sys_alarm(unsig
22744 +
22745 + #endif
22746 +
22747 +-#ifndef __alpha__
22748 +-
22749 +-/*
22750 +- * The Alpha uses getxpid, getxuid, and getxgid instead. Maybe this
22751 +- * should be moved into arch/i386 instead?
22752 +- */
22753 +
22754 + /**
22755 + * sys_getpid - return the thread group id of the current process
22756 +@@ -939,7 +937,7 @@ asmlinkage unsigned long sys_alarm(unsig
22757 + */
22758 + asmlinkage long sys_getpid(void)
22759 + {
22760 +- return current->tgid;
22761 ++ return vx_map_tgid(current->tgid);
22762 + }
22763 +
22764 + /*
22765 +@@ -955,10 +953,23 @@ asmlinkage long sys_getppid(void)
22766 + rcu_read_lock();
22767 + pid = rcu_dereference(current->real_parent)->tgid;
22768 + rcu_read_unlock();
22769 ++ return vx_map_pid(pid);
22770 ++}
22771 +
22772 +- return pid;
22773 ++#ifdef __alpha__
22774 ++
22775 ++/*
22776 ++ * The Alpha uses getxpid, getxuid, and getxgid instead.
22777 ++ */
22778 ++
22779 ++asmlinkage long do_getxpid(long *ppid)
22780 ++{
22781 ++ *ppid = sys_getppid();
22782 ++ return sys_getpid();
22783 + }
22784 +
22785 ++#else /* _alpha_ */
22786 ++
22787 + asmlinkage long sys_getuid(void)
22788 + {
22789 + /* Only we change this so SMP safe */
22790 +@@ -1118,6 +1129,8 @@ int do_sysinfo(struct sysinfo *info)
22791 + tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC;
22792 + tp.tv_sec++;
22793 + }
22794 ++ if (vx_flags(VXF_VIRT_UPTIME, 0))
22795 ++ vx_vsi_uptime(&tp, NULL);
22796 + info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0);
22797 +
22798 + info->loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
22799 +diff -NurpP --minimal linux-2.6.22.19/kernel/user.c linux-2.6.22.19-vs2.2.0.7/kernel/user.c
22800 +--- linux-2.6.22.19/kernel/user.c 2007-02-06 03:01:56 +0100
22801 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/user.c 2007-06-15 02:37:04 +0200
22802 +@@ -23,8 +23,8 @@
22803 + #define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 8)
22804 + #define UIDHASH_SZ (1 << UIDHASH_BITS)
22805 + #define UIDHASH_MASK (UIDHASH_SZ - 1)
22806 +-#define __uidhashfn(uid) (((uid >> UIDHASH_BITS) + uid) & UIDHASH_MASK)
22807 +-#define uidhashentry(uid) (uidhash_table + __uidhashfn((uid)))
22808 ++#define __uidhashfn(xid,uid) ((((uid) >> UIDHASH_BITS) + ((uid)^(xid))) & UIDHASH_MASK)
22809 ++#define uidhashentry(xid,uid) (uidhash_table + __uidhashfn((xid),(uid)))
22810 +
22811 + static struct kmem_cache *uid_cachep;
22812 + static struct list_head uidhash_table[UIDHASH_SZ];
22813 +@@ -66,7 +66,7 @@ static inline void uid_hash_remove(struc
22814 + list_del(&up->uidhash_list);
22815 + }
22816 +
22817 +-static inline struct user_struct *uid_hash_find(uid_t uid, struct list_head *hashent)
22818 ++static inline struct user_struct *uid_hash_find(xid_t xid, uid_t uid, struct list_head *hashent)
22819 + {
22820 + struct list_head *up;
22821 +
22822 +@@ -75,7 +75,7 @@ static inline struct user_struct *uid_ha
22823 +
22824 + user = list_entry(up, struct user_struct, uidhash_list);
22825 +
22826 +- if(user->uid == uid) {
22827 ++ if(user->uid == uid && user->xid == xid) {
22828 + atomic_inc(&user->__count);
22829 + return user;
22830 + }
22831 +@@ -90,13 +90,13 @@ static inline struct user_struct *uid_ha
22832 + *
22833 + * If the user_struct could not be found, return NULL.
22834 + */
22835 +-struct user_struct *find_user(uid_t uid)
22836 ++struct user_struct *find_user(xid_t xid, uid_t uid)
22837 + {
22838 + struct user_struct *ret;
22839 + unsigned long flags;
22840 +
22841 + spin_lock_irqsave(&uidhash_lock, flags);
22842 +- ret = uid_hash_find(uid, uidhashentry(uid));
22843 ++ ret = uid_hash_find(xid, uid, uidhashentry(xid, uid));
22844 + spin_unlock_irqrestore(&uidhash_lock, flags);
22845 + return ret;
22846 + }
22847 +@@ -120,13 +120,13 @@ void free_uid(struct user_struct *up)
22848 + }
22849 + }
22850 +
22851 +-struct user_struct * alloc_uid(uid_t uid)
22852 ++struct user_struct * alloc_uid(xid_t xid, uid_t uid)
22853 + {
22854 +- struct list_head *hashent = uidhashentry(uid);
22855 ++ struct list_head *hashent = uidhashentry(xid, uid);
22856 + struct user_struct *up;
22857 +
22858 + spin_lock_irq(&uidhash_lock);
22859 +- up = uid_hash_find(uid, hashent);
22860 ++ up = uid_hash_find(xid, uid, hashent);
22861 + spin_unlock_irq(&uidhash_lock);
22862 +
22863 + if (!up) {
22864 +@@ -136,6 +136,7 @@ struct user_struct * alloc_uid(uid_t uid
22865 + if (!new)
22866 + return NULL;
22867 + new->uid = uid;
22868 ++ new->xid = xid;
22869 + atomic_set(&new->__count, 1);
22870 + atomic_set(&new->processes, 0);
22871 + atomic_set(&new->files, 0);
22872 +@@ -158,7 +159,7 @@ struct user_struct * alloc_uid(uid_t uid
22873 + * on adding the same user already..
22874 + */
22875 + spin_lock_irq(&uidhash_lock);
22876 +- up = uid_hash_find(uid, hashent);
22877 ++ up = uid_hash_find(xid, uid, hashent);
22878 + if (up) {
22879 + key_put(new->uid_keyring);
22880 + key_put(new->session_keyring);
22881 +@@ -215,7 +216,7 @@ static int __init uid_cache_init(void)
22882 +
22883 + /* Insert the root user immediately (init already runs as root) */
22884 + spin_lock_irq(&uidhash_lock);
22885 +- uid_hash_insert(&root_user, uidhashentry(0));
22886 ++ uid_hash_insert(&root_user, uidhashentry(0,0));
22887 + spin_unlock_irq(&uidhash_lock);
22888 +
22889 + return 0;
22890 +diff -NurpP --minimal linux-2.6.22.19/kernel/utsname.c linux-2.6.22.19-vs2.2.0.7/kernel/utsname.c
22891 +--- linux-2.6.22.19/kernel/utsname.c 2007-07-09 13:20:04 +0200
22892 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/utsname.c 2007-06-15 02:37:04 +0200
22893 +@@ -13,6 +13,7 @@
22894 + #include <linux/uts.h>
22895 + #include <linux/utsname.h>
22896 + #include <linux/version.h>
22897 ++#include <linux/vserver/global.h>
22898 +
22899 + /*
22900 + * Clone a new ns copying an original utsname, setting refcount to 1
22901 +@@ -27,6 +28,7 @@ static struct uts_namespace *clone_uts_n
22902 + if (ns) {
22903 + memcpy(&ns->name, &old_ns->name, sizeof(ns->name));
22904 + kref_init(&ns->kref);
22905 ++ atomic_inc(&vs_global_uts_ns);
22906 + }
22907 + return ns;
22908 + }
22909 +@@ -58,5 +60,6 @@ void free_uts_ns(struct kref *kref)
22910 + struct uts_namespace *ns;
22911 +
22912 + ns = container_of(kref, struct uts_namespace, kref);
22913 ++ atomic_dec(&vs_global_uts_ns);
22914 + kfree(ns);
22915 + }
22916 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/Kconfig linux-2.6.22.19-vs2.2.0.7/kernel/vserver/Kconfig
22917 +--- linux-2.6.22.19/kernel/vserver/Kconfig 1970-01-01 01:00:00 +0100
22918 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/Kconfig 2007-06-15 02:37:04 +0200
22919 +@@ -0,0 +1,284 @@
22920 ++#
22921 ++# Linux VServer configuration
22922 ++#
22923 ++
22924 ++menu "Linux VServer"
22925 ++
22926 ++config VSERVER_LEGACY
22927 ++ bool "Enable Legacy Kernel API"
22928 ++ depends on EXPERIMENTAL
22929 ++ default n
22930 ++ help
22931 ++ This enables the legacy API used in vs1.xx, maintaining
22932 ++ compatibility with older vserver tools, and guest images
22933 ++ that are configured using the legacy method.
22934 ++
22935 ++config VSERVER_LEGACY_VERSION
22936 ++ bool "Show a Legacy Version ID"
22937 ++ depends on VSERVER_LEGACY
22938 ++ default n
22939 ++ help
22940 ++ This shows a special legacy version to very old tools
22941 ++ which do not handle the current version correctly.
22942 ++
22943 ++ Warning: recent tools are not able to utilize the
22944 ++ newer APIs when this is enabled, so some features will
22945 ++ not be available. Better avoid it, unless you really,
22946 ++ really need it for backwards compatibility.
22947 ++
22948 ++config VSERVER_DYNAMIC_IDS
22949 ++ bool "Enable dynamic context IDs"
22950 ++ depends on EXPERIMENTAL && VSERVER_LEGACY
22951 ++ default n
22952 ++ help
22953 ++ This enables support of in kernel dynamic context IDs,
22954 ++ which is deprecated and will probably be removed in the
22955 ++ next release.
22956 ++
22957 ++config VSERVER_LEGACYNET
22958 ++ bool "Enable Legacy Networking Kernel API"
22959 ++ depends on EXPERIMENTAL
22960 ++ default n
22961 ++ help
22962 ++ This enables the legacy networking API which is used
22963 ++ by older tools (pre 0.30.210) to set up the network
22964 ++ context (chbind).
22965 ++
22966 ++config VSERVER_REMAP_SADDR
22967 ++ bool "Remap Source IP Address"
22968 ++ depends on EXPERIMENTAL
22969 ++ default n
22970 ++ help
22971 ++ This allows to remap the source IP address of 'local'
22972 ++ connections from 127.0.0.1 to the first assigned
22973 ++ guest IP.
22974 ++
22975 ++config VSERVER_COWBL
22976 ++ bool "Enable COW Immutable Link Breaking"
22977 ++ default y
22978 ++ help
22979 ++ This enables the COW (Copy-On-Write) link break code.
22980 ++ It allows you to treat unified files like normal files
22981 ++ when writing to them (which will implicitely break the
22982 ++ link and create a copy of the unified file)
22983 ++
22984 ++config VSERVER_VTIME
22985 ++ bool "Enable Virtualized Guest Time"
22986 ++ depends on EXPERIMENTAL
22987 ++ default n
22988 ++ help
22989 ++ This enables per guest time offsets to allow for
22990 ++ adjusting the system clock individually per guest.
22991 ++ this adds some overhead to the time functions and
22992 ++ therefore should not be enabled without good reason.
22993 ++
22994 ++config VSERVER_PROC_SECURE
22995 ++ bool "Enable Proc Security"
22996 ++ depends on PROC_FS
22997 ++ default y
22998 ++ help
22999 ++ This configures ProcFS security to initially hide
23000 ++ non-process entries for all contexts except the main and
23001 ++ spectator context (i.e. for all guests), which is a secure
23002 ++ default.
23003 ++
23004 ++ (note: on 1.2x the entries were visible by default)
23005 ++
23006 ++config VSERVER_HARDCPU
23007 ++ bool "Enable Hard CPU Limits"
23008 ++ default y
23009 ++ help
23010 ++ Activate the Hard CPU Limits
23011 ++
23012 ++ This will compile in code that allows the Token Bucket
23013 ++ Scheduler to put processes on hold when a context's
23014 ++ tokens are depleted (provided that its per-context
23015 ++ sched_hard flag is set).
23016 ++
23017 ++ Processes belonging to that context will not be able
23018 ++ to consume CPU resources again until a per-context
23019 ++ configured minimum of tokens has been reached.
23020 ++
23021 ++config VSERVER_IDLETIME
23022 ++ bool "Avoid idle CPUs by skipping Time"
23023 ++ depends on VSERVER_HARDCPU
23024 ++ default y
23025 ++ help
23026 ++ This option allows the scheduler to artificially
23027 ++ advance time (per cpu) when otherwise the idle
23028 ++ task would be scheduled, thus keeping the cpu
23029 ++ busy and sharing the available resources among
23030 ++ certain contexts.
23031 ++
23032 ++config VSERVER_IDLELIMIT
23033 ++ bool "Limit the IDLE task"
23034 ++ depends on VSERVER_HARDCPU
23035 ++ default n
23036 ++ help
23037 ++ Limit the idle slices, so the the next context
23038 ++ will be scheduled as soon as possible.
23039 ++
23040 ++ This might improve interactivity and latency, but
23041 ++ will also marginally increase scheduling overhead.
23042 ++
23043 ++choice
23044 ++ prompt "Persistent Inode Tagging"
23045 ++ default TAGGING_ID24
23046 ++ help
23047 ++ This adds persistent context information to filesystems
23048 ++ mounted with the tagxid option. Tagging is a requirement
23049 ++ for per-context disk limits and per-context quota.
23050 ++
23051 ++
23052 ++config TAGGING_NONE
23053 ++ bool "Disabled"
23054 ++ help
23055 ++ do not store per-context information in inodes.
23056 ++
23057 ++config TAGGING_UID16
23058 ++ bool "UID16/GID32"
23059 ++ help
23060 ++ reduces UID to 16 bit, but leaves GID at 32 bit.
23061 ++
23062 ++config TAGGING_GID16
23063 ++ bool "UID32/GID16"
23064 ++ help
23065 ++ reduces GID to 16 bit, but leaves UID at 32 bit.
23066 ++
23067 ++config TAGGING_ID24
23068 ++ bool "UID24/GID24"
23069 ++ help
23070 ++ uses the upper 8bit from UID and GID for XID tagging
23071 ++ which leaves 24bit for UID/GID each, which should be
23072 ++ more than sufficient for normal use.
23073 ++
23074 ++config TAGGING_INTERN
23075 ++ bool "UID32/GID32"
23076 ++ help
23077 ++ this uses otherwise reserved inode fields in the on
23078 ++ disk representation, which limits the use to a few
23079 ++ filesystems (currently ext2 and ext3)
23080 ++
23081 ++endchoice
23082 ++
23083 ++config TAG_NFSD
23084 ++ bool "Tag NFSD User Auth and Files"
23085 ++ default n
23086 ++ help
23087 ++ Enable this if you do want the in-kernel NFS
23088 ++ Server to use the tagging specified above.
23089 ++ (will require patched clients too)
23090 ++
23091 ++config PROPAGATE
23092 ++ bool "Enable Inode Tag Propagation"
23093 ++ default n
23094 ++ depends on EXPERIMENTAL
23095 ++ help
23096 ++ This allows for the tagid= mount option to specify
23097 ++ a tagid which is to be used for the entire mount
23098 ++ tree.
23099 ++
23100 ++config VSERVER_PRIVACY
23101 ++ bool "Honor Privacy Aspects of Guests"
23102 ++ default y
23103 ++ help
23104 ++ When enabled, most context checks will disallow
23105 ++ access to structures assigned to a specific context,
23106 ++ like ptys or loop devices.
23107 ++
23108 ++config VSERVER_CONTEXTS
23109 ++ int "Maximum number of Contexts (1-65533)" if EMBEDDED
23110 ++ range 1 65533
23111 ++ default "768" if 64BIT
23112 ++ default "256"
23113 ++ help
23114 ++ This setting will optimize certain data structures
23115 ++ and memory allocations according to the expected
23116 ++ maximum.
23117 ++
23118 ++ note: this is not a strict upper limit.
23119 ++
23120 ++config VSERVER_WARN
23121 ++ bool "VServer Warnings"
23122 ++ default y
23123 ++ help
23124 ++ This enables various runtime warnings, which will
23125 ++ notify about potential manipulation attempts or
23126 ++ resource shortage. It is generally considered to
23127 ++ be a good idea to have that enabled.
23128 ++
23129 ++config VSERVER_DEBUG
23130 ++ bool "VServer Debugging Code"
23131 ++ default n
23132 ++ help
23133 ++ Set this to yes if you want to be able to activate
23134 ++ debugging output at runtime. It adds a very small
23135 ++ overhead to all vserver related functions and
23136 ++ increases the kernel size by about 20k.
23137 ++
23138 ++config VSERVER_HISTORY
23139 ++ bool "VServer History Tracing"
23140 ++ depends on VSERVER_DEBUG
23141 ++ default n
23142 ++ help
23143 ++ Set this to yes if you want to record the history of
23144 ++ linux-vserver activities, so they can be replayed in
23145 ++ the event of a kernel panic or oops.
23146 ++
23147 ++config VSERVER_HISTORY_SIZE
23148 ++ int "Per-CPU History Size (32-65536)"
23149 ++ depends on VSERVER_HISTORY
23150 ++ range 32 65536
23151 ++ default 64
23152 ++ help
23153 ++ This allows you to specify the number of entries in
23154 ++ the per-CPU history buffer.
23155 ++
23156 ++config VSERVER_MONITOR
23157 ++ bool "VServer Scheduling Monitor"
23158 ++ depends on VSERVER_DEBUG
23159 ++ default n
23160 ++ help
23161 ++ Set this to yes if you want to record the scheduling
23162 ++ decisions, so that they can be relayed to userspace
23163 ++ for detailed analysis.
23164 ++
23165 ++config VSERVER_MONITOR_SIZE
23166 ++ int "Per-CPU Monitor Queue Size (32-65536)"
23167 ++ depends on VSERVER_MONITOR
23168 ++ range 32 65536
23169 ++ default 1024
23170 ++ help
23171 ++ This allows you to specify the number of entries in
23172 ++ the per-CPU scheduling monitor buffer.
23173 ++
23174 ++config VSERVER_MONITOR_SYNC
23175 ++ int "Per-CPU Monitor Sync Interval (0-65536)"
23176 ++ depends on VSERVER_MONITOR
23177 ++ range 0 65536
23178 ++ default 256
23179 ++ help
23180 ++ This allows you to specify the interval in ticks
23181 ++ when a time sync entry is inserted.
23182 ++
23183 ++endmenu
23184 ++
23185 ++
23186 ++config VSERVER
23187 ++ bool
23188 ++ default y
23189 ++ select UTS_NS
23190 ++ select SYSVIPC
23191 ++ select IPC_NS
23192 ++
23193 ++config VSERVER_SECURITY
23194 ++ bool
23195 ++ depends on SECURITY
23196 ++ default y
23197 ++ select SECURITY_CAPABILITIES
23198 ++
23199 ++config VSERVER_NGNET
23200 ++ bool
23201 ++ depends on EXPERIMENTAL && !VSERVER_LEGACYNET
23202 ++ default y
23203 ++
23204 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/Makefile linux-2.6.22.19-vs2.2.0.7/kernel/vserver/Makefile
23205 +--- linux-2.6.22.19/kernel/vserver/Makefile 1970-01-01 01:00:00 +0100
23206 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/Makefile 2007-06-15 02:37:04 +0200
23207 +@@ -0,0 +1,17 @@
23208 ++#
23209 ++# Makefile for the Linux vserver routines.
23210 ++#
23211 ++
23212 ++
23213 ++obj-y += vserver.o
23214 ++
23215 ++vserver-y := switch.o context.o space.o sched.o network.o inode.o \
23216 ++ limit.o cvirt.o cacct.o signal.o helper.o init.o dlimit.o
23217 ++
23218 ++vserver-$(CONFIG_PROC_FS) += proc.o
23219 ++vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o debug.o
23220 ++vserver-$(CONFIG_VSERVER_LEGACY) += legacy.o
23221 ++vserver-$(CONFIG_VSERVER_LEGACYNET) += legacynet.o
23222 ++vserver-$(CONFIG_VSERVER_HISTORY) += history.o
23223 ++vserver-$(CONFIG_VSERVER_MONITOR) += monitor.o
23224 ++
23225 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/cacct.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/cacct.c
23226 +--- linux-2.6.22.19/kernel/vserver/cacct.c 1970-01-01 01:00:00 +0100
23227 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/cacct.c 2007-06-15 02:37:04 +0200
23228 +@@ -0,0 +1,44 @@
23229 ++/*
23230 ++ * linux/kernel/vserver/cacct.c
23231 ++ *
23232 ++ * Virtual Server: Context Accounting
23233 ++ *
23234 ++ * Copyright (C) 2006-2007 Herbert Pötzl
23235 ++ *
23236 ++ * V0.01 added accounting stats
23237 ++ *
23238 ++ */
23239 ++
23240 ++#include <linux/types.h>
23241 ++#include <linux/sched.h>
23242 ++#include <linux/vs_context.h>
23243 ++#include <linux/vserver/switch.h>
23244 ++#include <linux/vserver/cacct_cmd.h>
23245 ++#include <linux/vserver/cacct_int.h>
23246 ++
23247 ++#include <asm/errno.h>
23248 ++#include <asm/uaccess.h>
23249 ++
23250 ++
23251 ++int vc_sock_stat(struct vx_info *vxi, void __user *data)
23252 ++{
23253 ++ struct vcmd_sock_stat_v0 vc_data;
23254 ++ int j, field;
23255 ++
23256 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
23257 ++ return -EFAULT;
23258 ++
23259 ++ field = vc_data.field;
23260 ++ if ((field < 0) || (field >= VXA_SOCK_SIZE))
23261 ++ return -EINVAL;
23262 ++
23263 ++ for (j = 0; j < 3; j++) {
23264 ++ vc_data.count[j] = vx_sock_count(&vxi->cacct, field, j);
23265 ++ vc_data.total[j] = vx_sock_total(&vxi->cacct, field, j);
23266 ++ }
23267 ++
23268 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
23269 ++ return -EFAULT;
23270 ++ return 0;
23271 ++}
23272 ++
23273 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/cacct_init.h linux-2.6.22.19-vs2.2.0.7/kernel/vserver/cacct_init.h
23274 +--- linux-2.6.22.19/kernel/vserver/cacct_init.h 1970-01-01 01:00:00 +0100
23275 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/cacct_init.h 2007-06-15 02:37:04 +0200
23276 +@@ -0,0 +1,25 @@
23277 ++
23278 ++
23279 ++static inline void vx_info_init_cacct(struct _vx_cacct *cacct)
23280 ++{
23281 ++ int i, j;
23282 ++
23283 ++
23284 ++ for (i = 0; i < VXA_SOCK_SIZE; i++) {
23285 ++ for (j = 0; j < 3; j++) {
23286 ++ atomic_set(&cacct->sock[i][j].count, 0);
23287 ++ atomic_set(&cacct->sock[i][j].total, 0);
23288 ++ }
23289 ++ }
23290 ++ for (i = 0; i < 8; i++)
23291 ++ atomic_set(&cacct->slab[i], 0);
23292 ++ for (i = 0; i < 5; i++)
23293 ++ for (j = 0; j < 4; j++)
23294 ++ atomic_set(&cacct->page[i][j], 0);
23295 ++}
23296 ++
23297 ++static inline void vx_info_exit_cacct(struct _vx_cacct *cacct)
23298 ++{
23299 ++ return;
23300 ++}
23301 ++
23302 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/cacct_proc.h linux-2.6.22.19-vs2.2.0.7/kernel/vserver/cacct_proc.h
23303 +--- linux-2.6.22.19/kernel/vserver/cacct_proc.h 1970-01-01 01:00:00 +0100
23304 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/cacct_proc.h 2007-06-15 02:37:04 +0200
23305 +@@ -0,0 +1,53 @@
23306 ++#ifndef _VX_CACCT_PROC_H
23307 ++#define _VX_CACCT_PROC_H
23308 ++
23309 ++#include <linux/vserver/cacct_int.h>
23310 ++
23311 ++
23312 ++#define VX_SOCKA_TOP \
23313 ++ "Type\t recv #/bytes\t\t send #/bytes\t\t fail #/bytes\n"
23314 ++
23315 ++static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer)
23316 ++{
23317 ++ int i, j, length = 0;
23318 ++ static char *type[VXA_SOCK_SIZE] = {
23319 ++ "UNSPEC", "UNIX", "INET", "INET6", "PACKET", "OTHER"
23320 ++ };
23321 ++
23322 ++ length += sprintf(buffer + length, VX_SOCKA_TOP);
23323 ++ for (i = 0; i < VXA_SOCK_SIZE; i++) {
23324 ++ length += sprintf(buffer + length, "%s:", type[i]);
23325 ++ for (j = 0; j < 3; j++) {
23326 ++ length += sprintf(buffer + length,
23327 ++ "\t%10lu/%-10lu",
23328 ++ vx_sock_count(cacct, i, j),
23329 ++ vx_sock_total(cacct, i, j));
23330 ++ }
23331 ++ buffer[length++] = '\n';
23332 ++ }
23333 ++
23334 ++ length += sprintf(buffer + length, "\n");
23335 ++ length += sprintf(buffer + length,
23336 ++ "slab:\t %8u %8u %8u %8u\n",
23337 ++ atomic_read(&cacct->slab[1]),
23338 ++ atomic_read(&cacct->slab[4]),
23339 ++ atomic_read(&cacct->slab[0]),
23340 ++ atomic_read(&cacct->slab[2]));
23341 ++
23342 ++ length += sprintf(buffer + length, "\n");
23343 ++ for (i = 0; i < 5; i++) {
23344 ++ length += sprintf(buffer + length,
23345 ++ "page[%d]: %8u %8u %8u %8u\t %8u %8u %8u %8u\n", i,
23346 ++ atomic_read(&cacct->page[i][0]),
23347 ++ atomic_read(&cacct->page[i][1]),
23348 ++ atomic_read(&cacct->page[i][2]),
23349 ++ atomic_read(&cacct->page[i][3]),
23350 ++ atomic_read(&cacct->page[i][4]),
23351 ++ atomic_read(&cacct->page[i][5]),
23352 ++ atomic_read(&cacct->page[i][6]),
23353 ++ atomic_read(&cacct->page[i][7]));
23354 ++ }
23355 ++ return length;
23356 ++}
23357 ++
23358 ++#endif /* _VX_CACCT_PROC_H */
23359 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/context.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/context.c
23360 +--- linux-2.6.22.19/kernel/vserver/context.c 1970-01-01 01:00:00 +0100
23361 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/context.c 2007-10-01 15:47:53 +0200
23362 +@@ -0,0 +1,1106 @@
23363 ++/*
23364 ++ * linux/kernel/vserver/context.c
23365 ++ *
23366 ++ * Virtual Server: Context Support
23367 ++ *
23368 ++ * Copyright (C) 2003-2007 Herbert Pötzl
23369 ++ *
23370 ++ * V0.01 context helper
23371 ++ * V0.02 vx_ctx_kill syscall command
23372 ++ * V0.03 replaced context_info calls
23373 ++ * V0.04 redesign of struct (de)alloc
23374 ++ * V0.05 rlimit basic implementation
23375 ++ * V0.06 task_xid and info commands
23376 ++ * V0.07 context flags and caps
23377 ++ * V0.08 switch to RCU based hash
23378 ++ * V0.09 revert to non RCU for now
23379 ++ * V0.10 and back to working RCU hash
23380 ++ * V0.11 and back to locking again
23381 ++ * V0.12 referenced context store
23382 ++ * V0.13 separate per cpu data
23383 ++ * V0.14 changed vcmds to vxi arg
23384 ++ * V0.15 added context stat
23385 ++ * V0.16 have __create claim() the vxi
23386 ++ *
23387 ++ */
23388 ++
23389 ++#include <linux/slab.h>
23390 ++#include <linux/types.h>
23391 ++#include <linux/mnt_namespace.h>
23392 ++#include <linux/pid_namespace.h>
23393 ++
23394 ++#include <linux/sched.h>
23395 ++#include <linux/vserver/context.h>
23396 ++#include <linux/vserver/network.h>
23397 ++#include <linux/vserver/legacy.h>
23398 ++#include <linux/vserver/debug.h>
23399 ++#include <linux/vserver/limit.h>
23400 ++#include <linux/vserver/limit_int.h>
23401 ++#include <linux/vserver/space.h>
23402 ++
23403 ++#include <linux/vs_context.h>
23404 ++#include <linux/vs_limit.h>
23405 ++#include <linux/vserver/context_cmd.h>
23406 ++
23407 ++#include <linux/err.h>
23408 ++#include <asm/errno.h>
23409 ++
23410 ++#include "cvirt_init.h"
23411 ++#include "cacct_init.h"
23412 ++#include "limit_init.h"
23413 ++#include "sched_init.h"
23414 ++
23415 ++
23416 ++atomic_t vx_global_ctotal = ATOMIC_INIT(0);
23417 ++atomic_t vx_global_cactive = ATOMIC_INIT(0);
23418 ++
23419 ++
23420 ++/* now inactive context structures */
23421 ++
23422 ++static struct hlist_head vx_info_inactive = HLIST_HEAD_INIT;
23423 ++
23424 ++static spinlock_t vx_info_inactive_lock = SPIN_LOCK_UNLOCKED;
23425 ++
23426 ++
23427 ++/* __alloc_vx_info()
23428 ++
23429 ++ * allocate an initialized vx_info struct
23430 ++ * doesn't make it visible (hash) */
23431 ++
23432 ++static struct vx_info *__alloc_vx_info(xid_t xid)
23433 ++{
23434 ++ struct vx_info *new = NULL;
23435 ++ int cpu;
23436 ++
23437 ++ vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid);
23438 ++
23439 ++ /* would this benefit from a slab cache? */
23440 ++ new = kmalloc(sizeof(struct vx_info), GFP_KERNEL);
23441 ++ if (!new)
23442 ++ return 0;
23443 ++
23444 ++ memset(new, 0, sizeof(struct vx_info));
23445 ++#ifdef CONFIG_SMP
23446 ++ new->ptr_pc = alloc_percpu(struct _vx_info_pc);
23447 ++ if (!new->ptr_pc)
23448 ++ goto error;
23449 ++#endif
23450 ++ new->vx_id = xid;
23451 ++ INIT_HLIST_NODE(&new->vx_hlist);
23452 ++ atomic_set(&new->vx_usecnt, 0);
23453 ++ atomic_set(&new->vx_tasks, 0);
23454 ++ new->vx_parent = NULL;
23455 ++ new->vx_state = 0;
23456 ++ init_waitqueue_head(&new->vx_wait);
23457 ++
23458 ++ /* prepare reaper */
23459 ++ get_task_struct(init_pid_ns.child_reaper);
23460 ++ new->vx_reaper = init_pid_ns.child_reaper;
23461 ++
23462 ++ /* rest of init goes here */
23463 ++ vx_info_init_limit(&new->limit);
23464 ++ vx_info_init_sched(&new->sched);
23465 ++ vx_info_init_cvirt(&new->cvirt);
23466 ++ vx_info_init_cacct(&new->cacct);
23467 ++
23468 ++ /* per cpu data structures */
23469 ++ for_each_possible_cpu(cpu) {
23470 ++ vx_info_init_sched_pc(
23471 ++ &vx_per_cpu(new, sched_pc, cpu), cpu);
23472 ++ vx_info_init_cvirt_pc(
23473 ++ &vx_per_cpu(new, cvirt_pc, cpu), cpu);
23474 ++ }
23475 ++
23476 ++ new->vx_flags = VXF_INIT_SET;
23477 ++ new->vx_bcaps = CAP_INIT_EFF_SET;
23478 ++ new->vx_ccaps = 0;
23479 ++ new->vx_cap_bset = cap_bset;
23480 ++
23481 ++ new->reboot_cmd = 0;
23482 ++ new->exit_code = 0;
23483 ++
23484 ++ vxdprintk(VXD_CBIT(xid, 0),
23485 ++ "alloc_vx_info(%d) = %p", xid, new);
23486 ++ vxh_alloc_vx_info(new);
23487 ++ atomic_inc(&vx_global_ctotal);
23488 ++ return new;
23489 ++#ifdef CONFIG_SMP
23490 ++error:
23491 ++ kfree(new);
23492 ++ return 0;
23493 ++#endif
23494 ++}
23495 ++
23496 ++/* __dealloc_vx_info()
23497 ++
23498 ++ * final disposal of vx_info */
23499 ++
23500 ++static void __dealloc_vx_info(struct vx_info *vxi)
23501 ++{
23502 ++ int cpu;
23503 ++
23504 ++ vxdprintk(VXD_CBIT(xid, 0),
23505 ++ "dealloc_vx_info(%p)", vxi);
23506 ++ vxh_dealloc_vx_info(vxi);
23507 ++
23508 ++ vxi->vx_id = -1;
23509 ++
23510 ++ vx_info_exit_limit(&vxi->limit);
23511 ++ vx_info_exit_sched(&vxi->sched);
23512 ++ vx_info_exit_cvirt(&vxi->cvirt);
23513 ++ vx_info_exit_cacct(&vxi->cacct);
23514 ++
23515 ++ for_each_possible_cpu(cpu) {
23516 ++ vx_info_exit_sched_pc(
23517 ++ &vx_per_cpu(vxi, sched_pc, cpu), cpu);
23518 ++ vx_info_exit_cvirt_pc(
23519 ++ &vx_per_cpu(vxi, cvirt_pc, cpu), cpu);
23520 ++ }
23521 ++
23522 ++ vxi->vx_state |= VXS_RELEASED;
23523 ++
23524 ++#ifdef CONFIG_SMP
23525 ++ free_percpu(vxi->ptr_pc);
23526 ++#endif
23527 ++ kfree(vxi);
23528 ++ atomic_dec(&vx_global_ctotal);
23529 ++}
23530 ++
23531 ++static void __shutdown_vx_info(struct vx_info *vxi)
23532 ++{
23533 ++ struct nsproxy *nsproxy;
23534 ++ struct fs_struct *fs;
23535 ++
23536 ++ might_sleep();
23537 ++
23538 ++ vxi->vx_state |= VXS_SHUTDOWN;
23539 ++ vs_state_change(vxi, VSC_SHUTDOWN);
23540 ++
23541 ++ nsproxy = xchg(&vxi->vx_nsproxy, NULL);
23542 ++ fs = xchg(&vxi->vx_fs, NULL);
23543 ++
23544 ++ if (nsproxy)
23545 ++ put_nsproxy(nsproxy);
23546 ++ if (fs)
23547 ++ put_fs_struct(fs);
23548 ++}
23549 ++
23550 ++/* exported stuff */
23551 ++
23552 ++void free_vx_info(struct vx_info *vxi)
23553 ++{
23554 ++ unsigned long flags;
23555 ++
23556 ++ /* check for reference counts first */
23557 ++ BUG_ON(atomic_read(&vxi->vx_usecnt));
23558 ++ BUG_ON(atomic_read(&vxi->vx_tasks));
23559 ++
23560 ++ /* context must not be hashed */
23561 ++ BUG_ON(vx_info_state(vxi, VXS_HASHED));
23562 ++
23563 ++ /* context shutdown is mandatory */
23564 ++ BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN));
23565 ++
23566 ++ BUG_ON(vxi->vx_nsproxy);
23567 ++ BUG_ON(vxi->vx_fs);
23568 ++
23569 ++ spin_lock_irqsave(&vx_info_inactive_lock, flags);
23570 ++ hlist_del(&vxi->vx_hlist);
23571 ++ spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
23572 ++
23573 ++ __dealloc_vx_info(vxi);
23574 ++}
23575 ++
23576 ++
23577 ++/* hash table for vx_info hash */
23578 ++
23579 ++#define VX_HASH_SIZE 13
23580 ++
23581 ++static struct hlist_head vx_info_hash[VX_HASH_SIZE] =
23582 ++ { [0 ... VX_HASH_SIZE-1] = HLIST_HEAD_INIT };
23583 ++
23584 ++static spinlock_t vx_info_hash_lock = SPIN_LOCK_UNLOCKED;
23585 ++
23586 ++
23587 ++static inline unsigned int __hashval(xid_t xid)
23588 ++{
23589 ++ return (xid % VX_HASH_SIZE);
23590 ++}
23591 ++
23592 ++
23593 ++
23594 ++/* __hash_vx_info()
23595 ++
23596 ++ * add the vxi to the global hash table
23597 ++ * requires the hash_lock to be held */
23598 ++
23599 ++static inline void __hash_vx_info(struct vx_info *vxi)
23600 ++{
23601 ++ struct hlist_head *head;
23602 ++
23603 ++ vxd_assert_lock(&vx_info_hash_lock);
23604 ++ vxdprintk(VXD_CBIT(xid, 4),
23605 ++ "__hash_vx_info: %p[#%d]", vxi, vxi->vx_id);
23606 ++ vxh_hash_vx_info(vxi);
23607 ++
23608 ++ /* context must not be hashed */
23609 ++ BUG_ON(vx_info_state(vxi, VXS_HASHED));
23610 ++
23611 ++ vxi->vx_state |= VXS_HASHED;
23612 ++ head = &vx_info_hash[__hashval(vxi->vx_id)];
23613 ++ hlist_add_head(&vxi->vx_hlist, head);
23614 ++ atomic_inc(&vx_global_cactive);
23615 ++}
23616 ++
23617 ++/* __unhash_vx_info()
23618 ++
23619 ++ * remove the vxi from the global hash table
23620 ++ * requires the hash_lock to be held */
23621 ++
23622 ++static inline void __unhash_vx_info(struct vx_info *vxi)
23623 ++{
23624 ++ unsigned long flags;
23625 ++
23626 ++ vxd_assert_lock(&vx_info_hash_lock);
23627 ++ vxdprintk(VXD_CBIT(xid, 4),
23628 ++ "__unhash_vx_info: %p[#%d.%d.%d]", vxi, vxi->vx_id,
23629 ++ atomic_read(&vxi->vx_usecnt), atomic_read(&vxi->vx_tasks));
23630 ++ vxh_unhash_vx_info(vxi);
23631 ++
23632 ++ /* context must be hashed */
23633 ++ BUG_ON(!vx_info_state(vxi, VXS_HASHED));
23634 ++ /* but without tasks */
23635 ++ BUG_ON(atomic_read(&vxi->vx_tasks));
23636 ++
23637 ++ vxi->vx_state &= ~VXS_HASHED;
23638 ++ hlist_del_init(&vxi->vx_hlist);
23639 ++ spin_lock_irqsave(&vx_info_inactive_lock, flags);
23640 ++ hlist_add_head(&vxi->vx_hlist, &vx_info_inactive);
23641 ++ spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
23642 ++ atomic_dec(&vx_global_cactive);
23643 ++}
23644 ++
23645 ++
23646 ++/* __lookup_vx_info()
23647 ++
23648 ++ * requires the hash_lock to be held
23649 ++ * doesn't increment the vx_refcnt */
23650 ++
23651 ++static inline struct vx_info *__lookup_vx_info(xid_t xid)
23652 ++{
23653 ++ struct hlist_head *head = &vx_info_hash[__hashval(xid)];
23654 ++ struct hlist_node *pos;
23655 ++ struct vx_info *vxi;
23656 ++
23657 ++ vxd_assert_lock(&vx_info_hash_lock);
23658 ++ hlist_for_each(pos, head) {
23659 ++ vxi = hlist_entry(pos, struct vx_info, vx_hlist);
23660 ++
23661 ++ if (vxi->vx_id == xid)
23662 ++ goto found;
23663 ++ }
23664 ++ vxi = NULL;
23665 ++found:
23666 ++ vxdprintk(VXD_CBIT(xid, 0),
23667 ++ "__lookup_vx_info(#%u): %p[#%u]",
23668 ++ xid, vxi, vxi ? vxi->vx_id : 0);
23669 ++ vxh_lookup_vx_info(vxi, xid);
23670 ++ return vxi;
23671 ++}
23672 ++
23673 ++
23674 ++/* __vx_dynamic_id()
23675 ++
23676 ++ * find unused dynamic xid
23677 ++ * requires the hash_lock to be held */
23678 ++
23679 ++static inline xid_t __vx_dynamic_id(void)
23680 ++{
23681 ++ static xid_t seq = MAX_S_CONTEXT;
23682 ++ xid_t barrier = seq;
23683 ++
23684 ++ vxd_assert_lock(&vx_info_hash_lock);
23685 ++ do {
23686 ++ if (++seq > MAX_S_CONTEXT)
23687 ++ seq = MIN_D_CONTEXT;
23688 ++ if (!__lookup_vx_info(seq)) {
23689 ++ vxdprintk(VXD_CBIT(xid, 4),
23690 ++ "__vx_dynamic_id: [#%d]", seq);
23691 ++ return seq;
23692 ++ }
23693 ++ } while (barrier != seq);
23694 ++ return 0;
23695 ++}
23696 ++
23697 ++#ifdef CONFIG_VSERVER_LEGACY
23698 ++
23699 ++/* __loc_vx_info()
23700 ++
23701 ++ * locate or create the requested context
23702 ++ * get() it and if new hash it */
23703 ++
23704 ++static struct vx_info *__loc_vx_info(int id, int *err)
23705 ++{
23706 ++ struct vx_info *new, *vxi = NULL;
23707 ++
23708 ++ vxdprintk(VXD_CBIT(xid, 1), "loc_vx_info(%d)*", id);
23709 ++
23710 ++ if (!(new = __alloc_vx_info(id))) {
23711 ++ *err = -ENOMEM;
23712 ++ return NULL;
23713 ++ }
23714 ++
23715 ++ /* required to make dynamic xids unique */
23716 ++ spin_lock(&vx_info_hash_lock);
23717 ++
23718 ++ /* dynamic context requested */
23719 ++ if (id == VX_DYNAMIC_ID) {
23720 ++#ifdef CONFIG_VSERVER_DYNAMIC_IDS
23721 ++ id = __vx_dynamic_id();
23722 ++ if (!id) {
23723 ++ printk(KERN_ERR "no dynamic context available.\n");
23724 ++ goto out_unlock;
23725 ++ }
23726 ++ new->vx_id = id;
23727 ++#else
23728 ++ printk(KERN_ERR "dynamic contexts disabled.\n");
23729 ++ goto out_unlock;
23730 ++#endif
23731 ++ }
23732 ++ /* existing context requested */
23733 ++ else if ((vxi = __lookup_vx_info(id))) {
23734 ++ /* context in setup is not available */
23735 ++ if (vxi->vx_flags & VXF_STATE_SETUP) {
23736 ++ vxdprintk(VXD_CBIT(xid, 0),
23737 ++ "loc_vx_info(%d) = %p (not available)", id, vxi);
23738 ++ vxi = NULL;
23739 ++ *err = -EBUSY;
23740 ++ } else {
23741 ++ vxdprintk(VXD_CBIT(xid, 0),
23742 ++ "loc_vx_info(%d) = %p (found)", id, vxi);
23743 ++ get_vx_info(vxi);
23744 ++ *err = 0;
23745 ++ }
23746 ++ goto out_unlock;
23747 ++ }
23748 ++
23749 ++ /* new context requested */
23750 ++ vxdprintk(VXD_CBIT(xid, 0),
23751 ++ "loc_vx_info(%d) = %p (new)", id, new);
23752 ++ __hash_vx_info(get_vx_info(new));
23753 ++ vxi = new, new = NULL;
23754 ++ *err = 1;
23755 ++
23756 ++out_unlock:
23757 ++ spin_unlock(&vx_info_hash_lock);
23758 ++ vxh_loc_vx_info(vxi, id);
23759 ++ if (new)
23760 ++ __dealloc_vx_info(new);
23761 ++ return vxi;
23762 ++}
23763 ++
23764 ++#endif
23765 ++
23766 ++/* __create_vx_info()
23767 ++
23768 ++ * create the requested context
23769 ++ * get(), claim() and hash it */
23770 ++
23771 ++static struct vx_info *__create_vx_info(int id)
23772 ++{
23773 ++ struct vx_info *new, *vxi = NULL;
23774 ++
23775 ++ vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id);
23776 ++
23777 ++ if (!(new = __alloc_vx_info(id)))
23778 ++ return ERR_PTR(-ENOMEM);
23779 ++
23780 ++ /* required to make dynamic xids unique */
23781 ++ spin_lock(&vx_info_hash_lock);
23782 ++
23783 ++ /* dynamic context requested */
23784 ++ if (id == VX_DYNAMIC_ID) {
23785 ++#ifdef CONFIG_VSERVER_DYNAMIC_IDS
23786 ++ id = __vx_dynamic_id();
23787 ++ if (!id) {
23788 ++ printk(KERN_ERR "no dynamic context available.\n");
23789 ++ vxi = ERR_PTR(-EAGAIN);
23790 ++ goto out_unlock;
23791 ++ }
23792 ++ new->vx_id = id;
23793 ++#else
23794 ++ printk(KERN_ERR "dynamic contexts disabled.\n");
23795 ++ vxi = ERR_PTR(-EINVAL);
23796 ++ goto out_unlock;
23797 ++#endif
23798 ++ }
23799 ++ /* static context requested */
23800 ++ else if ((vxi = __lookup_vx_info(id))) {
23801 ++ vxdprintk(VXD_CBIT(xid, 0),
23802 ++ "create_vx_info(%d) = %p (already there)", id, vxi);
23803 ++ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0))
23804 ++ vxi = ERR_PTR(-EBUSY);
23805 ++ else
23806 ++ vxi = ERR_PTR(-EEXIST);
23807 ++ goto out_unlock;
23808 ++ }
23809 ++#ifdef CONFIG_VSERVER_DYNAMIC_IDS
23810 ++ /* dynamic xid creation blocker */
23811 ++ else if (id >= MIN_D_CONTEXT) {
23812 ++ vxdprintk(VXD_CBIT(xid, 0),
23813 ++ "create_vx_info(%d) (dynamic rejected)", id);
23814 ++ vxi = ERR_PTR(-EINVAL);
23815 ++ goto out_unlock;
23816 ++ }
23817 ++#endif
23818 ++
23819 ++ /* new context */
23820 ++ vxdprintk(VXD_CBIT(xid, 0),
23821 ++ "create_vx_info(%d) = %p (new)", id, new);
23822 ++ claim_vx_info(new, NULL);
23823 ++ __hash_vx_info(get_vx_info(new));
23824 ++ vxi = new, new = NULL;
23825 ++
23826 ++out_unlock:
23827 ++ spin_unlock(&vx_info_hash_lock);
23828 ++ vxh_create_vx_info(IS_ERR(vxi) ? NULL : vxi, id);
23829 ++ if (new)
23830 ++ __dealloc_vx_info(new);
23831 ++ return vxi;
23832 ++}
23833 ++
23834 ++
23835 ++/* exported stuff */
23836 ++
23837 ++
23838 ++void unhash_vx_info(struct vx_info *vxi)
23839 ++{
23840 ++ __shutdown_vx_info(vxi);
23841 ++ spin_lock(&vx_info_hash_lock);
23842 ++ __unhash_vx_info(vxi);
23843 ++ spin_unlock(&vx_info_hash_lock);
23844 ++ __wakeup_vx_info(vxi);
23845 ++}
23846 ++
23847 ++
23848 ++/* lookup_vx_info()
23849 ++
23850 ++ * search for a vx_info and get() it
23851 ++ * negative id means current */
23852 ++
23853 ++struct vx_info *lookup_vx_info(int id)
23854 ++{
23855 ++ struct vx_info *vxi = NULL;
23856 ++
23857 ++ if (id < 0) {
23858 ++ vxi = get_vx_info(current->vx_info);
23859 ++ } else if (id > 1) {
23860 ++ spin_lock(&vx_info_hash_lock);
23861 ++ vxi = get_vx_info(__lookup_vx_info(id));
23862 ++ spin_unlock(&vx_info_hash_lock);
23863 ++ }
23864 ++ return vxi;
23865 ++}
23866 ++
23867 ++/* xid_is_hashed()
23868 ++
23869 ++ * verify that xid is still hashed */
23870 ++
23871 ++int xid_is_hashed(xid_t xid)
23872 ++{
23873 ++ int hashed;
23874 ++
23875 ++ spin_lock(&vx_info_hash_lock);
23876 ++ hashed = (__lookup_vx_info(xid) != NULL);
23877 ++ spin_unlock(&vx_info_hash_lock);
23878 ++ return hashed;
23879 ++}
23880 ++
23881 ++#ifdef CONFIG_VSERVER_LEGACY
23882 ++
23883 ++struct vx_info *lookup_or_create_vx_info(int id)
23884 ++{
23885 ++ int err;
23886 ++
23887 ++ return __loc_vx_info(id, &err);
23888 ++}
23889 ++
23890 ++#endif
23891 ++
23892 ++#ifdef CONFIG_PROC_FS
23893 ++
23894 ++/* get_xid_list()
23895 ++
23896 ++ * get a subset of hashed xids for proc
23897 ++ * assumes size is at least one */
23898 ++
23899 ++int get_xid_list(int index, unsigned int *xids, int size)
23900 ++{
23901 ++ int hindex, nr_xids = 0;
23902 ++
23903 ++ /* only show current and children */
23904 ++ if (!vx_check(0, VS_ADMIN | VS_WATCH)) {
23905 ++ if (index > 0)
23906 ++ return 0;
23907 ++ xids[nr_xids] = vx_current_xid();
23908 ++ return 1;
23909 ++ }
23910 ++
23911 ++ for (hindex = 0; hindex < VX_HASH_SIZE; hindex++) {
23912 ++ struct hlist_head *head = &vx_info_hash[hindex];
23913 ++ struct hlist_node *pos;
23914 ++
23915 ++ spin_lock(&vx_info_hash_lock);
23916 ++ hlist_for_each(pos, head) {
23917 ++ struct vx_info *vxi;
23918 ++
23919 ++ if (--index > 0)
23920 ++ continue;
23921 ++
23922 ++ vxi = hlist_entry(pos, struct vx_info, vx_hlist);
23923 ++ xids[nr_xids] = vxi->vx_id;
23924 ++ if (++nr_xids >= size) {
23925 ++ spin_unlock(&vx_info_hash_lock);
23926 ++ goto out;
23927 ++ }
23928 ++ }
23929 ++ /* keep the lock time short */
23930 ++ spin_unlock(&vx_info_hash_lock);
23931 ++ }
23932 ++out:
23933 ++ return nr_xids;
23934 ++}
23935 ++#endif
23936 ++
23937 ++#ifdef CONFIG_VSERVER_DEBUG
23938 ++
23939 ++void dump_vx_info_inactive(int level)
23940 ++{
23941 ++ struct hlist_node *entry, *next;
23942 ++
23943 ++ hlist_for_each_safe(entry, next, &vx_info_inactive) {
23944 ++ struct vx_info *vxi =
23945 ++ list_entry(entry, struct vx_info, vx_hlist);
23946 ++
23947 ++ dump_vx_info(vxi, level);
23948 ++ }
23949 ++}
23950 ++
23951 ++#endif
23952 ++
23953 ++int vx_migrate_user(struct task_struct *p, struct vx_info *vxi)
23954 ++{
23955 ++ struct user_struct *new_user, *old_user;
23956 ++
23957 ++ if (!p || !vxi)
23958 ++ BUG();
23959 ++
23960 ++ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
23961 ++ return -EACCES;
23962 ++
23963 ++ new_user = alloc_uid(vxi->vx_id, p->uid);
23964 ++ if (!new_user)
23965 ++ return -ENOMEM;
23966 ++
23967 ++ old_user = p->user;
23968 ++ if (new_user != old_user) {
23969 ++ atomic_inc(&new_user->processes);
23970 ++ atomic_dec(&old_user->processes);
23971 ++ p->user = new_user;
23972 ++ }
23973 ++ free_uid(old_user);
23974 ++ return 0;
23975 ++}
23976 ++
23977 ++void vx_mask_cap_bset(struct vx_info *vxi, struct task_struct *p)
23978 ++{
23979 ++ p->cap_effective &= vxi->vx_cap_bset;
23980 ++ p->cap_inheritable &= vxi->vx_cap_bset;
23981 ++ p->cap_permitted &= vxi->vx_cap_bset;
23982 ++}
23983 ++
23984 ++
23985 ++#include <linux/file.h>
23986 ++
23987 ++static int vx_openfd_task(struct task_struct *tsk)
23988 ++{
23989 ++ struct files_struct *files = tsk->files;
23990 ++ struct fdtable *fdt;
23991 ++ const unsigned long *bptr;
23992 ++ int count, total;
23993 ++
23994 ++ /* no rcu_read_lock() because of spin_lock() */
23995 ++ spin_lock(&files->file_lock);
23996 ++ fdt = files_fdtable(files);
23997 ++ bptr = fdt->open_fds->fds_bits;
23998 ++ count = fdt->max_fds / (sizeof(unsigned long) * 8);
23999 ++ for (total = 0; count > 0; count--) {
24000 ++ if (*bptr)
24001 ++ total += hweight_long(*bptr);
24002 ++ bptr++;
24003 ++ }
24004 ++ spin_unlock(&files->file_lock);
24005 ++ return total;
24006 ++}
24007 ++
24008 ++
24009 ++/* for *space compatibility */
24010 ++
24011 ++asmlinkage long sys_unshare(unsigned long);
24012 ++
24013 ++/*
24014 ++ * migrate task to new context
24015 ++ * gets vxi, puts old_vxi on change
24016 ++ * optionally unshares namespaces (hack)
24017 ++ */
24018 ++
24019 ++int vx_migrate_task(struct task_struct *p, struct vx_info *vxi, int unshare)
24020 ++{
24021 ++ struct vx_info *old_vxi;
24022 ++ int ret = 0;
24023 ++
24024 ++ if (!p || !vxi)
24025 ++ BUG();
24026 ++
24027 ++ vxdprintk(VXD_CBIT(xid, 5),
24028 ++ "vx_migrate_task(%p,%p[#%d.%d])", p, vxi,
24029 ++ vxi->vx_id, atomic_read(&vxi->vx_usecnt));
24030 ++
24031 ++ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0) &&
24032 ++ !vx_info_flags(vxi, VXF_STATE_SETUP, 0))
24033 ++ return -EACCES;
24034 ++
24035 ++ if (vx_info_state(vxi, VXS_SHUTDOWN))
24036 ++ return -EFAULT;
24037 ++
24038 ++ old_vxi = task_get_vx_info(p);
24039 ++ if (old_vxi == vxi)
24040 ++ goto out;
24041 ++
24042 ++ if (!(ret = vx_migrate_user(p, vxi))) {
24043 ++ int openfd;
24044 ++
24045 ++ task_lock(p);
24046 ++ openfd = vx_openfd_task(p);
24047 ++
24048 ++ if (old_vxi) {
24049 ++ atomic_dec(&old_vxi->cvirt.nr_threads);
24050 ++ atomic_dec(&old_vxi->cvirt.nr_running);
24051 ++ __rlim_dec(&old_vxi->limit, RLIMIT_NPROC);
24052 ++ /* FIXME: what about the struct files here? */
24053 ++ __rlim_sub(&old_vxi->limit, VLIMIT_OPENFD, openfd);
24054 ++ /* account for the executable */
24055 ++ __rlim_dec(&old_vxi->limit, VLIMIT_DENTRY);
24056 ++ }
24057 ++ atomic_inc(&vxi->cvirt.nr_threads);
24058 ++ atomic_inc(&vxi->cvirt.nr_running);
24059 ++ __rlim_inc(&vxi->limit, RLIMIT_NPROC);
24060 ++ /* FIXME: what about the struct files here? */
24061 ++ __rlim_add(&vxi->limit, VLIMIT_OPENFD, openfd);
24062 ++ /* account for the executable */
24063 ++ __rlim_inc(&vxi->limit, VLIMIT_DENTRY);
24064 ++
24065 ++ if (old_vxi) {
24066 ++ release_vx_info(old_vxi, p);
24067 ++ clr_vx_info(&p->vx_info);
24068 ++ }
24069 ++ claim_vx_info(vxi, p);
24070 ++ set_vx_info(&p->vx_info, vxi);
24071 ++ p->xid = vxi->vx_id;
24072 ++
24073 ++ vxdprintk(VXD_CBIT(xid, 5),
24074 ++ "moved task %p into vxi:%p[#%d]",
24075 ++ p, vxi, vxi->vx_id);
24076 ++
24077 ++ vx_mask_cap_bset(vxi, p);
24078 ++ task_unlock(p);
24079 ++
24080 ++ /* hack for *spaces to provide compatibility */
24081 ++ if (unshare) {
24082 ++ struct nsproxy *old_nsp, *new_nsp;
24083 ++
24084 ++ ret = unshare_nsproxy_namespaces(
24085 ++ CLONE_NEWUTS | CLONE_NEWIPC,
24086 ++ &new_nsp, NULL);
24087 ++ if (ret)
24088 ++ goto out;
24089 ++
24090 ++ old_nsp = xchg(&p->nsproxy, new_nsp);
24091 ++ vx_set_space(vxi, CLONE_NEWUTS | CLONE_NEWIPC);
24092 ++ put_nsproxy(old_nsp);
24093 ++ }
24094 ++ }
24095 ++out:
24096 ++ put_vx_info(old_vxi);
24097 ++ return ret;
24098 ++}
24099 ++
24100 ++int vx_set_reaper(struct vx_info *vxi, struct task_struct *p)
24101 ++{
24102 ++ struct task_struct *old_reaper;
24103 ++
24104 ++ if (!vxi)
24105 ++ return -EINVAL;
24106 ++
24107 ++ vxdprintk(VXD_CBIT(xid, 6),
24108 ++ "vx_set_reaper(%p[#%d],%p[#%d,%d])",
24109 ++ vxi, vxi->vx_id, p, p->xid, p->pid);
24110 ++
24111 ++ old_reaper = vxi->vx_reaper;
24112 ++ if (old_reaper == p)
24113 ++ return 0;
24114 ++
24115 ++ /* set new child reaper */
24116 ++ get_task_struct(p);
24117 ++ vxi->vx_reaper = p;
24118 ++ put_task_struct(old_reaper);
24119 ++ return 0;
24120 ++}
24121 ++
24122 ++int vx_set_init(struct vx_info *vxi, struct task_struct *p)
24123 ++{
24124 ++ if (!vxi)
24125 ++ return -EINVAL;
24126 ++
24127 ++ vxdprintk(VXD_CBIT(xid, 6),
24128 ++ "vx_set_init(%p[#%d],%p[#%d,%d,%d])",
24129 ++ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
24130 ++
24131 ++ vxi->vx_flags &= ~VXF_STATE_INIT;
24132 ++ vxi->vx_initpid = p->tgid;
24133 ++ return 0;
24134 ++}
24135 ++
24136 ++void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code)
24137 ++{
24138 ++ vxdprintk(VXD_CBIT(xid, 6),
24139 ++ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])",
24140 ++ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
24141 ++
24142 ++ vxi->exit_code = code;
24143 ++ vxi->vx_initpid = 0;
24144 ++}
24145 ++
24146 ++
24147 ++void vx_set_persistent(struct vx_info *vxi)
24148 ++{
24149 ++ vxdprintk(VXD_CBIT(xid, 6),
24150 ++ "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id);
24151 ++
24152 ++ get_vx_info(vxi);
24153 ++ claim_vx_info(vxi, NULL);
24154 ++}
24155 ++
24156 ++void vx_clear_persistent(struct vx_info *vxi)
24157 ++{
24158 ++ vxdprintk(VXD_CBIT(xid, 6),
24159 ++ "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id);
24160 ++
24161 ++ release_vx_info(vxi, NULL);
24162 ++ put_vx_info(vxi);
24163 ++}
24164 ++
24165 ++void vx_update_persistent(struct vx_info *vxi)
24166 ++{
24167 ++ if (vx_info_flags(vxi, VXF_PERSISTENT, 0))
24168 ++ vx_set_persistent(vxi);
24169 ++ else
24170 ++ vx_clear_persistent(vxi);
24171 ++}
24172 ++
24173 ++
24174 ++/* task must be current or locked */
24175 ++
24176 ++void exit_vx_info(struct task_struct *p, int code)
24177 ++{
24178 ++ struct vx_info *vxi = p->vx_info;
24179 ++
24180 ++ if (vxi) {
24181 ++ atomic_dec(&vxi->cvirt.nr_threads);
24182 ++ vx_nproc_dec(p);
24183 ++
24184 ++ vxi->exit_code = code;
24185 ++ release_vx_info(vxi, p);
24186 ++ }
24187 ++}
24188 ++
24189 ++void exit_vx_info_early(struct task_struct *p, int code)
24190 ++{
24191 ++ struct vx_info *vxi = p->vx_info;
24192 ++
24193 ++ if (vxi) {
24194 ++ if (vxi->vx_initpid == p->tgid)
24195 ++ vx_exit_init(vxi, p, code);
24196 ++ if (vxi->vx_reaper == p)
24197 ++ vx_set_reaper(vxi, init_pid_ns.child_reaper);
24198 ++ }
24199 ++}
24200 ++
24201 ++
24202 ++/* vserver syscall commands below here */
24203 ++
24204 ++/* taks xid and vx_info functions */
24205 ++
24206 ++#include <asm/uaccess.h>
24207 ++
24208 ++
24209 ++int vc_task_xid(uint32_t id, void __user *data)
24210 ++{
24211 ++ xid_t xid;
24212 ++
24213 ++ if (id) {
24214 ++ struct task_struct *tsk;
24215 ++
24216 ++ if (!vx_check(0, VS_ADMIN | VS_WATCH))
24217 ++ return -EPERM;
24218 ++
24219 ++ read_lock(&tasklist_lock);
24220 ++ tsk = find_task_by_real_pid(id);
24221 ++ xid = (tsk) ? tsk->xid : -ESRCH;
24222 ++ read_unlock(&tasklist_lock);
24223 ++ } else
24224 ++ xid = vx_current_xid();
24225 ++ return xid;
24226 ++}
24227 ++
24228 ++
24229 ++int vc_vx_info(struct vx_info *vxi, void __user *data)
24230 ++{
24231 ++ struct vcmd_vx_info_v0 vc_data;
24232 ++
24233 ++ vc_data.xid = vxi->vx_id;
24234 ++ vc_data.initpid = vxi->vx_initpid;
24235 ++
24236 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
24237 ++ return -EFAULT;
24238 ++ return 0;
24239 ++}
24240 ++
24241 ++
24242 ++int vc_ctx_stat(struct vx_info *vxi, void __user *data)
24243 ++{
24244 ++ struct vcmd_ctx_stat_v0 vc_data;
24245 ++
24246 ++ vc_data.usecnt = atomic_read(&vxi->vx_usecnt);
24247 ++ vc_data.tasks = atomic_read(&vxi->vx_tasks);
24248 ++
24249 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
24250 ++ return -EFAULT;
24251 ++ return 0;
24252 ++}
24253 ++
24254 ++
24255 ++/* context functions */
24256 ++
24257 ++int vc_ctx_create(uint32_t xid, void __user *data)
24258 ++{
24259 ++ struct vcmd_ctx_create vc_data = { .flagword = VXF_INIT_SET };
24260 ++ struct vx_info *new_vxi;
24261 ++ int ret;
24262 ++
24263 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
24264 ++ return -EFAULT;
24265 ++
24266 ++ if ((xid > MAX_S_CONTEXT) && (xid != VX_DYNAMIC_ID))
24267 ++ return -EINVAL;
24268 ++ if (xid < 2)
24269 ++ return -EINVAL;
24270 ++
24271 ++ new_vxi = __create_vx_info(xid);
24272 ++ if (IS_ERR(new_vxi))
24273 ++ return PTR_ERR(new_vxi);
24274 ++
24275 ++ /* initial flags */
24276 ++ new_vxi->vx_flags = vc_data.flagword;
24277 ++
24278 ++ ret = -ENOEXEC;
24279 ++ if (vs_state_change(new_vxi, VSC_STARTUP))
24280 ++ goto out;
24281 ++
24282 ++ ret = vx_migrate_task(current, new_vxi, (!data));
24283 ++ if (ret)
24284 ++ goto out;
24285 ++
24286 ++ /* return context id on success */
24287 ++ ret = new_vxi->vx_id;
24288 ++
24289 ++ /* get a reference for persistent contexts */
24290 ++ if ((vc_data.flagword & VXF_PERSISTENT))
24291 ++ vx_set_persistent(new_vxi);
24292 ++out:
24293 ++ release_vx_info(new_vxi, NULL);
24294 ++ put_vx_info(new_vxi);
24295 ++ return ret;
24296 ++}
24297 ++
24298 ++
24299 ++int vc_ctx_migrate(struct vx_info *vxi, void __user *data)
24300 ++{
24301 ++ struct vcmd_ctx_migrate vc_data = { .flagword = 0 };
24302 ++ int ret;
24303 ++
24304 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
24305 ++ return -EFAULT;
24306 ++
24307 ++ ret = vx_migrate_task(current, vxi, 0);
24308 ++ if (ret)
24309 ++ return ret;
24310 ++ if (vc_data.flagword & VXM_SET_INIT)
24311 ++ ret = vx_set_init(vxi, current);
24312 ++ if (ret)
24313 ++ return ret;
24314 ++ if (vc_data.flagword & VXM_SET_REAPER)
24315 ++ ret = vx_set_reaper(vxi, current);
24316 ++ return ret;
24317 ++}
24318 ++
24319 ++
24320 ++int vc_get_cflags(struct vx_info *vxi, void __user *data)
24321 ++{
24322 ++ struct vcmd_ctx_flags_v0 vc_data;
24323 ++
24324 ++ vc_data.flagword = vxi->vx_flags;
24325 ++
24326 ++ /* special STATE flag handling */
24327 ++ vc_data.mask = vs_mask_flags(~0ULL, vxi->vx_flags, VXF_ONE_TIME);
24328 ++
24329 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
24330 ++ return -EFAULT;
24331 ++ return 0;
24332 ++}
24333 ++
24334 ++int vc_set_cflags(struct vx_info *vxi, void __user *data)
24335 ++{
24336 ++ struct vcmd_ctx_flags_v0 vc_data;
24337 ++ uint64_t mask, trigger;
24338 ++
24339 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
24340 ++ return -EFAULT;
24341 ++
24342 ++ /* special STATE flag handling */
24343 ++ mask = vs_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME);
24344 ++ trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword);
24345 ++
24346 ++ if (vxi == current->vx_info) {
24347 ++ if (trigger & VXF_STATE_SETUP)
24348 ++ vx_mask_cap_bset(vxi, current);
24349 ++ if (trigger & VXF_STATE_INIT) {
24350 ++ int ret;
24351 ++
24352 ++ ret = vx_set_init(vxi, current);
24353 ++ if (ret)
24354 ++ return ret;
24355 ++ ret = vx_set_reaper(vxi, current);
24356 ++ if (ret)
24357 ++ return ret;
24358 ++ }
24359 ++ }
24360 ++
24361 ++ vxi->vx_flags = vs_mask_flags(vxi->vx_flags,
24362 ++ vc_data.flagword, mask);
24363 ++ if (trigger & VXF_PERSISTENT)
24364 ++ vx_update_persistent(vxi);
24365 ++
24366 ++ return 0;
24367 ++}
24368 ++
24369 ++static int do_get_caps(struct vx_info *vxi, uint64_t *bcaps, uint64_t *ccaps)
24370 ++{
24371 ++ if (bcaps)
24372 ++ *bcaps = vxi->vx_bcaps;
24373 ++ if (ccaps)
24374 ++ *ccaps = vxi->vx_ccaps;
24375 ++
24376 ++ return 0;
24377 ++}
24378 ++
24379 ++int vc_get_ccaps_v0(struct vx_info *vxi, void __user *data)
24380 ++{
24381 ++ struct vcmd_ctx_caps_v0 vc_data;
24382 ++ int ret;
24383 ++
24384 ++ ret = do_get_caps(vxi, &vc_data.bcaps, &vc_data.ccaps);
24385 ++ if (ret)
24386 ++ return ret;
24387 ++ vc_data.cmask = ~0ULL;
24388 ++
24389 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
24390 ++ return -EFAULT;
24391 ++ return 0;
24392 ++}
24393 ++
24394 ++int vc_get_ccaps(struct vx_info *vxi, void __user *data)
24395 ++{
24396 ++ struct vcmd_ctx_caps_v1 vc_data;
24397 ++ int ret;
24398 ++
24399 ++ ret = do_get_caps(vxi, NULL, &vc_data.ccaps);
24400 ++ if (ret)
24401 ++ return ret;
24402 ++ vc_data.cmask = ~0ULL;
24403 ++
24404 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
24405 ++ return -EFAULT;
24406 ++ return 0;
24407 ++}
24408 ++
24409 ++static int do_set_caps(struct vx_info *vxi,
24410 ++ uint64_t bcaps, uint64_t bmask, uint64_t ccaps, uint64_t cmask)
24411 ++{
24412 ++ vxi->vx_bcaps = vs_mask_flags(vxi->vx_bcaps, bcaps, bmask);
24413 ++ vxi->vx_ccaps = vs_mask_flags(vxi->vx_ccaps, ccaps, cmask);
24414 ++
24415 ++ return 0;
24416 ++}
24417 ++
24418 ++int vc_set_ccaps_v0(struct vx_info *vxi, void __user *data)
24419 ++{
24420 ++ struct vcmd_ctx_caps_v0 vc_data;
24421 ++
24422 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
24423 ++ return -EFAULT;
24424 ++
24425 ++ /* simulate old &= behaviour for bcaps */
24426 ++ return do_set_caps(vxi, 0, ~vc_data.bcaps,
24427 ++ vc_data.ccaps, vc_data.cmask);
24428 ++}
24429 ++
24430 ++int vc_set_ccaps(struct vx_info *vxi, void __user *data)
24431 ++{
24432 ++ struct vcmd_ctx_caps_v1 vc_data;
24433 ++
24434 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
24435 ++ return -EFAULT;
24436 ++
24437 ++ return do_set_caps(vxi, 0, 0, vc_data.ccaps, vc_data.cmask);
24438 ++}
24439 ++
24440 ++int vc_get_bcaps(struct vx_info *vxi, void __user *data)
24441 ++{
24442 ++ struct vcmd_bcaps vc_data;
24443 ++ int ret;
24444 ++
24445 ++ ret = do_get_caps(vxi, &vc_data.bcaps, NULL);
24446 ++ if (ret)
24447 ++ return ret;
24448 ++ vc_data.bmask = ~0ULL;
24449 ++
24450 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
24451 ++ return -EFAULT;
24452 ++ return 0;
24453 ++}
24454 ++
24455 ++int vc_set_bcaps(struct vx_info *vxi, void __user *data)
24456 ++{
24457 ++ struct vcmd_bcaps vc_data;
24458 ++
24459 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
24460 ++ return -EFAULT;
24461 ++
24462 ++ return do_set_caps(vxi, vc_data.bcaps, vc_data.bmask, 0, 0);
24463 ++}
24464 ++
24465 ++#include <linux/module.h>
24466 ++
24467 ++EXPORT_SYMBOL_GPL(free_vx_info);
24468 ++
24469 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/cvirt.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/cvirt.c
24470 +--- linux-2.6.22.19/kernel/vserver/cvirt.c 1970-01-01 01:00:00 +0100
24471 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/cvirt.c 2007-06-15 02:37:04 +0200
24472 +@@ -0,0 +1,304 @@
24473 ++/*
24474 ++ * linux/kernel/vserver/cvirt.c
24475 ++ *
24476 ++ * Virtual Server: Context Virtualization
24477 ++ *
24478 ++ * Copyright (C) 2004-2007 Herbert Pötzl
24479 ++ *
24480 ++ * V0.01 broken out from limit.c
24481 ++ * V0.02 added utsname stuff
24482 ++ * V0.03 changed vcmds to vxi arg
24483 ++ *
24484 ++ */
24485 ++
24486 ++#include <linux/sched.h>
24487 ++#include <linux/sysctl.h>
24488 ++#include <linux/types.h>
24489 ++#include <linux/vs_context.h>
24490 ++#include <linux/vs_cvirt.h>
24491 ++#include <linux/vserver/switch.h>
24492 ++#include <linux/vserver/cvirt_cmd.h>
24493 ++
24494 ++#include <asm/errno.h>
24495 ++#include <asm/uaccess.h>
24496 ++
24497 ++
24498 ++void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle)
24499 ++{
24500 ++ struct vx_info *vxi = current->vx_info;
24501 ++
24502 ++ set_normalized_timespec(uptime,
24503 ++ uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec,
24504 ++ uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec);
24505 ++ if (!idle)
24506 ++ return;
24507 ++ set_normalized_timespec(idle,
24508 ++ idle->tv_sec - vxi->cvirt.bias_idle.tv_sec,
24509 ++ idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec);
24510 ++ return;
24511 ++}
24512 ++
24513 ++uint64_t vx_idle_jiffies(void)
24514 ++{
24515 ++ return init_task.utime + init_task.stime;
24516 ++}
24517 ++
24518 ++
24519 ++
24520 ++static inline uint32_t __update_loadavg(uint32_t load,
24521 ++ int wsize, int delta, int n)
24522 ++{
24523 ++ unsigned long long calc, prev;
24524 ++
24525 ++ /* just set it to n */
24526 ++ if (unlikely(delta >= wsize))
24527 ++ return (n << FSHIFT);
24528 ++
24529 ++ calc = delta * n;
24530 ++ calc <<= FSHIFT;
24531 ++ prev = (wsize - delta);
24532 ++ prev *= load;
24533 ++ calc += prev;
24534 ++ do_div(calc, wsize);
24535 ++ return calc;
24536 ++}
24537 ++
24538 ++
24539 ++void vx_update_load(struct vx_info *vxi)
24540 ++{
24541 ++ uint32_t now, last, delta;
24542 ++ unsigned int nr_running, nr_uninterruptible;
24543 ++ unsigned int total;
24544 ++ unsigned long flags;
24545 ++
24546 ++ spin_lock_irqsave(&vxi->cvirt.load_lock, flags);
24547 ++
24548 ++ now = jiffies;
24549 ++ last = vxi->cvirt.load_last;
24550 ++ delta = now - last;
24551 ++
24552 ++ if (delta < 5*HZ)
24553 ++ goto out;
24554 ++
24555 ++ nr_running = atomic_read(&vxi->cvirt.nr_running);
24556 ++ nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible);
24557 ++ total = nr_running + nr_uninterruptible;
24558 ++
24559 ++ vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0],
24560 ++ 60*HZ, delta, total);
24561 ++ vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
24562 ++ 5*60*HZ, delta, total);
24563 ++ vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
24564 ++ 15*60*HZ, delta, total);
24565 ++
24566 ++ vxi->cvirt.load_last = now;
24567 ++out:
24568 ++ atomic_inc(&vxi->cvirt.load_updates);
24569 ++ spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags);
24570 ++}
24571 ++
24572 ++
24573 ++/*
24574 ++ * Commands to do_syslog:
24575 ++ *
24576 ++ * 0 -- Close the log. Currently a NOP.
24577 ++ * 1 -- Open the log. Currently a NOP.
24578 ++ * 2 -- Read from the log.
24579 ++ * 3 -- Read all messages remaining in the ring buffer.
24580 ++ * 4 -- Read and clear all messages remaining in the ring buffer
24581 ++ * 5 -- Clear ring buffer.
24582 ++ * 6 -- Disable printk's to console
24583 ++ * 7 -- Enable printk's to console
24584 ++ * 8 -- Set level of messages printed to console
24585 ++ * 9 -- Return number of unread characters in the log buffer
24586 ++ * 10 -- Return size of the log buffer
24587 ++ */
24588 ++int vx_do_syslog(int type, char __user *buf, int len)
24589 ++{
24590 ++ int error = 0;
24591 ++ int do_clear = 0;
24592 ++ struct vx_info *vxi = current->vx_info;
24593 ++ struct _vx_syslog *log;
24594 ++
24595 ++ if (!vxi)
24596 ++ return -EINVAL;
24597 ++ log = &vxi->cvirt.syslog;
24598 ++
24599 ++ switch (type) {
24600 ++ case 0: /* Close log */
24601 ++ case 1: /* Open log */
24602 ++ break;
24603 ++ case 2: /* Read from log */
24604 ++ error = wait_event_interruptible(log->log_wait,
24605 ++ (log->log_start - log->log_end));
24606 ++ if (error)
24607 ++ break;
24608 ++ spin_lock_irq(&log->logbuf_lock);
24609 ++ spin_unlock_irq(&log->logbuf_lock);
24610 ++ break;
24611 ++ case 4: /* Read/clear last kernel messages */
24612 ++ do_clear = 1;
24613 ++ /* fall through */
24614 ++ case 3: /* Read last kernel messages */
24615 ++ return 0;
24616 ++
24617 ++ case 5: /* Clear ring buffer */
24618 ++ return 0;
24619 ++
24620 ++ case 6: /* Disable logging to console */
24621 ++ case 7: /* Enable logging to console */
24622 ++ case 8: /* Set level of messages printed to console */
24623 ++ break;
24624 ++
24625 ++ case 9: /* Number of chars in the log buffer */
24626 ++ return 0;
24627 ++ case 10: /* Size of the log buffer */
24628 ++ return 0;
24629 ++ default:
24630 ++ error = -EINVAL;
24631 ++ break;
24632 ++ }
24633 ++ return error;
24634 ++}
24635 ++
24636 ++
24637 ++/* virtual host info names */
24638 ++
24639 ++static char *vx_vhi_name(struct vx_info *vxi, int id)
24640 ++{
24641 ++ struct nsproxy *nsproxy;
24642 ++ struct uts_namespace *uts;
24643 ++
24644 ++
24645 ++ if (id == VHIN_CONTEXT)
24646 ++ return vxi->vx_name;
24647 ++
24648 ++ nsproxy = vxi->vx_nsproxy;
24649 ++ if (!nsproxy)
24650 ++ return NULL;
24651 ++
24652 ++ uts = nsproxy->uts_ns;
24653 ++ if (!uts)
24654 ++ return NULL;
24655 ++
24656 ++ switch (id) {
24657 ++ case VHIN_SYSNAME:
24658 ++ return uts->name.sysname;
24659 ++ case VHIN_NODENAME:
24660 ++ return uts->name.nodename;
24661 ++ case VHIN_RELEASE:
24662 ++ return uts->name.release;
24663 ++ case VHIN_VERSION:
24664 ++ return uts->name.version;
24665 ++ case VHIN_MACHINE:
24666 ++ return uts->name.machine;
24667 ++ case VHIN_DOMAINNAME:
24668 ++ return uts->name.domainname;
24669 ++ default:
24670 ++ return NULL;
24671 ++ }
24672 ++ return NULL;
24673 ++}
24674 ++
24675 ++int vc_set_vhi_name(struct vx_info *vxi, void __user *data)
24676 ++{
24677 ++ struct vcmd_vhi_name_v0 vc_data;
24678 ++ char *name;
24679 ++
24680 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
24681 ++ return -EFAULT;
24682 ++
24683 ++ name = vx_vhi_name(vxi, vc_data.field);
24684 ++ if (!name)
24685 ++ return -EINVAL;
24686 ++
24687 ++ memcpy(name, vc_data.name, 65);
24688 ++ return 0;
24689 ++}
24690 ++
24691 ++int vc_get_vhi_name(struct vx_info *vxi, void __user *data)
24692 ++{
24693 ++ struct vcmd_vhi_name_v0 vc_data;
24694 ++ char *name;
24695 ++
24696 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
24697 ++ return -EFAULT;
24698 ++
24699 ++ name = vx_vhi_name(vxi, vc_data.field);
24700 ++ if (!name)
24701 ++ return -EINVAL;
24702 ++
24703 ++ memcpy(vc_data.name, name, 65);
24704 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
24705 ++ return -EFAULT;
24706 ++ return 0;
24707 ++}
24708 ++
24709 ++
24710 ++int vc_virt_stat(struct vx_info *vxi, void __user *data)
24711 ++{
24712 ++ struct vcmd_virt_stat_v0 vc_data;
24713 ++ struct _vx_cvirt *cvirt = &vxi->cvirt;
24714 ++ struct timespec uptime;
24715 ++
24716 ++ do_posix_clock_monotonic_gettime(&uptime);
24717 ++ set_normalized_timespec(&uptime,
24718 ++ uptime.tv_sec - cvirt->bias_uptime.tv_sec,
24719 ++ uptime.tv_nsec - cvirt->bias_uptime.tv_nsec);
24720 ++
24721 ++ vc_data.offset = timeval_to_ns(&cvirt->bias_tv);
24722 ++ vc_data.uptime = timespec_to_ns(&uptime);
24723 ++ vc_data.nr_threads = atomic_read(&cvirt->nr_threads);
24724 ++ vc_data.nr_running = atomic_read(&cvirt->nr_running);
24725 ++ vc_data.nr_uninterruptible = atomic_read(&cvirt->nr_uninterruptible);
24726 ++ vc_data.nr_onhold = atomic_read(&cvirt->nr_onhold);
24727 ++ vc_data.nr_forks = atomic_read(&cvirt->total_forks);
24728 ++ vc_data.load[0] = cvirt->load[0];
24729 ++ vc_data.load[1] = cvirt->load[1];
24730 ++ vc_data.load[2] = cvirt->load[2];
24731 ++
24732 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
24733 ++ return -EFAULT;
24734 ++ return 0;
24735 ++}
24736 ++
24737 ++
24738 ++#ifdef CONFIG_VSERVER_VTIME
24739 ++
24740 ++/* virtualized time base */
24741 ++
24742 ++void vx_gettimeofday(struct timeval *tv)
24743 ++{
24744 ++ do_gettimeofday(tv);
24745 ++ if (!vx_flags(VXF_VIRT_TIME, 0))
24746 ++ return;
24747 ++
24748 ++ tv->tv_sec += current->vx_info->cvirt.bias_tv.tv_sec;
24749 ++ tv->tv_usec += current->vx_info->cvirt.bias_tv.tv_usec;
24750 ++
24751 ++ if (tv->tv_usec >= USEC_PER_SEC) {
24752 ++ tv->tv_sec++;
24753 ++ tv->tv_usec -= USEC_PER_SEC;
24754 ++ } else if (tv->tv_usec < 0) {
24755 ++ tv->tv_sec--;
24756 ++ tv->tv_usec += USEC_PER_SEC;
24757 ++ }
24758 ++}
24759 ++
24760 ++int vx_settimeofday(struct timespec *ts)
24761 ++{
24762 ++ struct timeval tv;
24763 ++
24764 ++ if (!vx_flags(VXF_VIRT_TIME, 0))
24765 ++ return do_settimeofday(ts);
24766 ++
24767 ++ do_gettimeofday(&tv);
24768 ++ current->vx_info->cvirt.bias_tv.tv_sec =
24769 ++ ts->tv_sec - tv.tv_sec;
24770 ++ current->vx_info->cvirt.bias_tv.tv_usec =
24771 ++ (ts->tv_nsec/NSEC_PER_USEC) - tv.tv_usec;
24772 ++ return 0;
24773 ++}
24774 ++
24775 ++#endif
24776 ++
24777 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/cvirt_init.h linux-2.6.22.19-vs2.2.0.7/kernel/vserver/cvirt_init.h
24778 +--- linux-2.6.22.19/kernel/vserver/cvirt_init.h 1970-01-01 01:00:00 +0100
24779 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/cvirt_init.h 2007-10-29 23:34:24 +0100
24780 +@@ -0,0 +1,69 @@
24781 ++
24782 ++
24783 ++extern uint64_t vx_idle_jiffies(void);
24784 ++
24785 ++static inline void vx_info_init_cvirt(struct _vx_cvirt *cvirt)
24786 ++{
24787 ++ uint64_t idle_jiffies = vx_idle_jiffies();
24788 ++ uint64_t nsuptime;
24789 ++
24790 ++ do_posix_clock_monotonic_gettime(&cvirt->bias_uptime);
24791 ++ nsuptime = (unsigned long long)cvirt->bias_uptime.tv_sec
24792 ++ * NSEC_PER_SEC + cvirt->bias_uptime.tv_nsec;
24793 ++ cvirt->bias_clock = nsec_to_clock_t(nsuptime);
24794 ++ cvirt->bias_tv.tv_sec = 0;
24795 ++ cvirt->bias_tv.tv_usec = 0;
24796 ++
24797 ++ jiffies_to_timespec(idle_jiffies, &cvirt->bias_idle);
24798 ++ atomic_set(&cvirt->nr_threads, 0);
24799 ++ atomic_set(&cvirt->nr_running, 0);
24800 ++ atomic_set(&cvirt->nr_uninterruptible, 0);
24801 ++ atomic_set(&cvirt->nr_onhold, 0);
24802 ++
24803 ++ spin_lock_init(&cvirt->load_lock);
24804 ++ cvirt->load_last = jiffies;
24805 ++ atomic_set(&cvirt->load_updates, 0);
24806 ++ cvirt->load[0] = 0;
24807 ++ cvirt->load[1] = 0;
24808 ++ cvirt->load[2] = 0;
24809 ++ atomic_set(&cvirt->total_forks, 0);
24810 ++
24811 ++ spin_lock_init(&cvirt->syslog.logbuf_lock);
24812 ++ init_waitqueue_head(&cvirt->syslog.log_wait);
24813 ++ cvirt->syslog.log_start = 0;
24814 ++ cvirt->syslog.log_end = 0;
24815 ++ cvirt->syslog.con_start = 0;
24816 ++ cvirt->syslog.logged_chars = 0;
24817 ++}
24818 ++
24819 ++static inline
24820 ++void vx_info_init_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
24821 ++{
24822 ++ // cvirt_pc->cpustat = { 0 };
24823 ++}
24824 ++
24825 ++static inline void vx_info_exit_cvirt(struct _vx_cvirt *cvirt)
24826 ++{
24827 ++ int value;
24828 ++
24829 ++ vxwprintk_xid((value = atomic_read(&cvirt->nr_threads)),
24830 ++ "!!! cvirt: %p[nr_threads] = %d on exit.",
24831 ++ cvirt, value);
24832 ++ vxwprintk_xid((value = atomic_read(&cvirt->nr_running)),
24833 ++ "!!! cvirt: %p[nr_running] = %d on exit.",
24834 ++ cvirt, value);
24835 ++ vxwprintk_xid((value = atomic_read(&cvirt->nr_uninterruptible)),
24836 ++ "!!! cvirt: %p[nr_uninterruptible] = %d on exit.",
24837 ++ cvirt, value);
24838 ++ vxwprintk_xid((value = atomic_read(&cvirt->nr_onhold)),
24839 ++ "!!! cvirt: %p[nr_onhold] = %d on exit.",
24840 ++ cvirt, value);
24841 ++ return;
24842 ++}
24843 ++
24844 ++static inline
24845 ++void vx_info_exit_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
24846 ++{
24847 ++ return;
24848 ++}
24849 ++
24850 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/cvirt_proc.h linux-2.6.22.19-vs2.2.0.7/kernel/vserver/cvirt_proc.h
24851 +--- linux-2.6.22.19/kernel/vserver/cvirt_proc.h 1970-01-01 01:00:00 +0100
24852 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/cvirt_proc.h 2007-06-15 02:37:04 +0200
24853 +@@ -0,0 +1,133 @@
24854 ++#ifndef _VX_CVIRT_PROC_H
24855 ++#define _VX_CVIRT_PROC_H
24856 ++
24857 ++#include <linux/nsproxy.h>
24858 ++#include <linux/mnt_namespace.h>
24859 ++#include <linux/utsname.h>
24860 ++#include <linux/ipc.h>
24861 ++
24862 ++
24863 ++static inline
24864 ++int vx_info_proc_nsproxy(struct nsproxy *nsproxy, char *buffer)
24865 ++{
24866 ++ struct mnt_namespace *ns;
24867 ++ struct uts_namespace *uts;
24868 ++ struct ipc_namespace *ipc;
24869 ++ struct vfsmount *mnt;
24870 ++ char *path, *root;
24871 ++ int length = 0;
24872 ++
24873 ++ if (!nsproxy)
24874 ++ goto out;
24875 ++
24876 ++ length += sprintf(buffer + length,
24877 ++ "NSProxy:\t%p [%p,%p,%p]\n",
24878 ++ nsproxy, nsproxy->mnt_ns,
24879 ++ nsproxy->uts_ns, nsproxy->ipc_ns);
24880 ++
24881 ++ ns = nsproxy->mnt_ns;
24882 ++ if (!ns)
24883 ++ goto skip_ns;
24884 ++
24885 ++ path = kmalloc(PATH_MAX, GFP_KERNEL);
24886 ++ if (!path)
24887 ++ goto skip_ns;
24888 ++
24889 ++ mnt = ns->root;
24890 ++ root = d_path(mnt->mnt_root, mnt->mnt_parent, path, PATH_MAX - 2);
24891 ++ length += sprintf(buffer + length,
24892 ++ "Namespace:\t%p [#%u]\n"
24893 ++ "RootPath:\t%s\n",
24894 ++ ns, atomic_read(&ns->count),
24895 ++ root);
24896 ++ kfree(path);
24897 ++skip_ns:
24898 ++
24899 ++ uts = nsproxy->uts_ns;
24900 ++ if (!uts)
24901 ++ goto skip_uts;
24902 ++
24903 ++ length += sprintf(buffer + length,
24904 ++ "SysName:\t%.*s\n"
24905 ++ "NodeName:\t%.*s\n"
24906 ++ "Release:\t%.*s\n"
24907 ++ "Version:\t%.*s\n"
24908 ++ "Machine:\t%.*s\n"
24909 ++ "DomainName:\t%.*s\n",
24910 ++ __NEW_UTS_LEN, uts->name.sysname,
24911 ++ __NEW_UTS_LEN, uts->name.nodename,
24912 ++ __NEW_UTS_LEN, uts->name.release,
24913 ++ __NEW_UTS_LEN, uts->name.version,
24914 ++ __NEW_UTS_LEN, uts->name.machine,
24915 ++ __NEW_UTS_LEN, uts->name.domainname);
24916 ++skip_uts:
24917 ++
24918 ++ ipc = nsproxy->ipc_ns;
24919 ++ if (!ipc)
24920 ++ goto skip_ipc;
24921 ++
24922 ++ length += sprintf(buffer + length,
24923 ++ "SEMS:\t\t%d %d %d %d %d\n"
24924 ++ "MSG:\t\t%d %d %d\n"
24925 ++ "SHM:\t\t%lu %lu %d %d\n",
24926 ++ ipc->sem_ctls[0], ipc->sem_ctls[1],
24927 ++ ipc->sem_ctls[2], ipc->sem_ctls[3],
24928 ++ ipc->used_sems,
24929 ++ ipc->msg_ctlmax, ipc->msg_ctlmnb, ipc->msg_ctlmni,
24930 ++ (unsigned long)ipc->shm_ctlmax,
24931 ++ (unsigned long)ipc->shm_ctlall,
24932 ++ ipc->shm_ctlmni, ipc->shm_tot);
24933 ++skip_ipc:
24934 ++out:
24935 ++ return length;
24936 ++}
24937 ++
24938 ++
24939 ++#include <linux/sched.h>
24940 ++
24941 ++#define LOAD_INT(x) ((x) >> FSHIFT)
24942 ++#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1 - 1)) * 100)
24943 ++
24944 ++static inline
24945 ++int vx_info_proc_cvirt(struct _vx_cvirt *cvirt, char *buffer)
24946 ++{
24947 ++ int length = 0;
24948 ++ int a, b, c;
24949 ++
24950 ++ length += sprintf(buffer + length,
24951 ++ "BiasUptime:\t%lu.%02lu\n",
24952 ++ (unsigned long)cvirt->bias_uptime.tv_sec,
24953 ++ (cvirt->bias_uptime.tv_nsec / (NSEC_PER_SEC / 100)));
24954 ++
24955 ++ a = cvirt->load[0] + (FIXED_1 / 200);
24956 ++ b = cvirt->load[1] + (FIXED_1 / 200);
24957 ++ c = cvirt->load[2] + (FIXED_1 / 200);
24958 ++ length += sprintf(buffer + length,
24959 ++ "nr_threads:\t%d\n"
24960 ++ "nr_running:\t%d\n"
24961 ++ "nr_unintr:\t%d\n"
24962 ++ "nr_onhold:\t%d\n"
24963 ++ "load_updates:\t%d\n"
24964 ++ "loadavg:\t%d.%02d %d.%02d %d.%02d\n"
24965 ++ "total_forks:\t%d\n",
24966 ++ atomic_read(&cvirt->nr_threads),
24967 ++ atomic_read(&cvirt->nr_running),
24968 ++ atomic_read(&cvirt->nr_uninterruptible),
24969 ++ atomic_read(&cvirt->nr_onhold),
24970 ++ atomic_read(&cvirt->load_updates),
24971 ++ LOAD_INT(a), LOAD_FRAC(a),
24972 ++ LOAD_INT(b), LOAD_FRAC(b),
24973 ++ LOAD_INT(c), LOAD_FRAC(c),
24974 ++ atomic_read(&cvirt->total_forks));
24975 ++ return length;
24976 ++}
24977 ++
24978 ++static inline
24979 ++int vx_info_proc_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc,
24980 ++ char *buffer, int cpu)
24981 ++{
24982 ++ int length = 0;
24983 ++ return length;
24984 ++}
24985 ++
24986 ++#endif /* _VX_CVIRT_PROC_H */
24987 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/debug.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/debug.c
24988 +--- linux-2.6.22.19/kernel/vserver/debug.c 1970-01-01 01:00:00 +0100
24989 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/debug.c 2007-06-15 02:37:04 +0200
24990 +@@ -0,0 +1,35 @@
24991 ++/*
24992 ++ * kernel/vserver/debug.c
24993 ++ *
24994 ++ * Copyright (C) 2005-2007 Herbert Pötzl
24995 ++ *
24996 ++ * V0.01 vx_info dump support
24997 ++ *
24998 ++ */
24999 ++
25000 ++#include <linux/errno.h>
25001 ++#include <linux/kernel.h>
25002 ++#include <linux/module.h>
25003 ++#include <linux/vs_base.h>
25004 ++
25005 ++#include <linux/vserver/context.h>
25006 ++
25007 ++
25008 ++void dump_vx_info(struct vx_info *vxi, int level)
25009 ++{
25010 ++ printk("vx_info %p[#%d, %d.%d, %4x]\n", vxi, vxi->vx_id,
25011 ++ atomic_read(&vxi->vx_usecnt),
25012 ++ atomic_read(&vxi->vx_tasks),
25013 ++ vxi->vx_state);
25014 ++ if (level > 0) {
25015 ++ __dump_vx_limit(&vxi->limit);
25016 ++ __dump_vx_sched(&vxi->sched);
25017 ++ __dump_vx_cvirt(&vxi->cvirt);
25018 ++ __dump_vx_cacct(&vxi->cacct);
25019 ++ }
25020 ++ printk("---\n");
25021 ++}
25022 ++
25023 ++
25024 ++EXPORT_SYMBOL_GPL(dump_vx_info);
25025 ++
25026 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/dlimit.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/dlimit.c
25027 +--- linux-2.6.22.19/kernel/vserver/dlimit.c 1970-01-01 01:00:00 +0100
25028 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/dlimit.c 2007-07-17 03:02:15 +0200
25029 +@@ -0,0 +1,526 @@
25030 ++/*
25031 ++ * linux/kernel/vserver/dlimit.c
25032 ++ *
25033 ++ * Virtual Server: Context Disk Limits
25034 ++ *
25035 ++ * Copyright (C) 2004-2007 Herbert Pötzl
25036 ++ *
25037 ++ * V0.01 initial version
25038 ++ * V0.02 compat32 splitup
25039 ++ *
25040 ++ */
25041 ++
25042 ++#include <linux/fs.h>
25043 ++#include <linux/namei.h>
25044 ++#include <linux/statfs.h>
25045 ++#include <linux/compat.h>
25046 ++#include <linux/vserver/switch.h>
25047 ++#include <linux/vs_context.h>
25048 ++#include <linux/vs_tag.h>
25049 ++#include <linux/vs_dlimit.h>
25050 ++#include <linux/vserver/dlimit_cmd.h>
25051 ++
25052 ++#include <asm/errno.h>
25053 ++#include <asm/uaccess.h>
25054 ++
25055 ++/* __alloc_dl_info()
25056 ++
25057 ++ * allocate an initialized dl_info struct
25058 ++ * doesn't make it visible (hash) */
25059 ++
25060 ++static struct dl_info *__alloc_dl_info(struct super_block *sb, tag_t tag)
25061 ++{
25062 ++ struct dl_info *new = NULL;
25063 ++
25064 ++ vxdprintk(VXD_CBIT(dlim, 5),
25065 ++ "alloc_dl_info(%p,%d)*", sb, tag);
25066 ++
25067 ++ /* would this benefit from a slab cache? */
25068 ++ new = kmalloc(sizeof(struct dl_info), GFP_KERNEL);
25069 ++ if (!new)
25070 ++ return 0;
25071 ++
25072 ++ memset(new, 0, sizeof(struct dl_info));
25073 ++ new->dl_tag = tag;
25074 ++ new->dl_sb = sb;
25075 ++ INIT_RCU_HEAD(&new->dl_rcu);
25076 ++ INIT_HLIST_NODE(&new->dl_hlist);
25077 ++ spin_lock_init(&new->dl_lock);
25078 ++ atomic_set(&new->dl_refcnt, 0);
25079 ++ atomic_set(&new->dl_usecnt, 0);
25080 ++
25081 ++ /* rest of init goes here */
25082 ++
25083 ++ vxdprintk(VXD_CBIT(dlim, 4),
25084 ++ "alloc_dl_info(%p,%d) = %p", sb, tag, new);
25085 ++ return new;
25086 ++}
25087 ++
25088 ++/* __dealloc_dl_info()
25089 ++
25090 ++ * final disposal of dl_info */
25091 ++
25092 ++static void __dealloc_dl_info(struct dl_info *dli)
25093 ++{
25094 ++ vxdprintk(VXD_CBIT(dlim, 4),
25095 ++ "dealloc_dl_info(%p)", dli);
25096 ++
25097 ++ dli->dl_hlist.next = LIST_POISON1;
25098 ++ dli->dl_tag = -1;
25099 ++ dli->dl_sb = 0;
25100 ++
25101 ++ BUG_ON(atomic_read(&dli->dl_usecnt));
25102 ++ BUG_ON(atomic_read(&dli->dl_refcnt));
25103 ++
25104 ++ kfree(dli);
25105 ++}
25106 ++
25107 ++
25108 ++/* hash table for dl_info hash */
25109 ++
25110 ++#define DL_HASH_SIZE 13
25111 ++
25112 ++struct hlist_head dl_info_hash[DL_HASH_SIZE];
25113 ++
25114 ++static spinlock_t dl_info_hash_lock = SPIN_LOCK_UNLOCKED;
25115 ++
25116 ++
25117 ++static inline unsigned int __hashval(struct super_block *sb, tag_t tag)
25118 ++{
25119 ++ return ((tag ^ (unsigned long)sb) % DL_HASH_SIZE);
25120 ++}
25121 ++
25122 ++
25123 ++
25124 ++/* __hash_dl_info()
25125 ++
25126 ++ * add the dli to the global hash table
25127 ++ * requires the hash_lock to be held */
25128 ++
25129 ++static inline void __hash_dl_info(struct dl_info *dli)
25130 ++{
25131 ++ struct hlist_head *head;
25132 ++
25133 ++ vxdprintk(VXD_CBIT(dlim, 6),
25134 ++ "__hash_dl_info: %p[#%d]", dli, dli->dl_tag);
25135 ++ get_dl_info(dli);
25136 ++ head = &dl_info_hash[__hashval(dli->dl_sb, dli->dl_tag)];
25137 ++ hlist_add_head_rcu(&dli->dl_hlist, head);
25138 ++}
25139 ++
25140 ++/* __unhash_dl_info()
25141 ++
25142 ++ * remove the dli from the global hash table
25143 ++ * requires the hash_lock to be held */
25144 ++
25145 ++static inline void __unhash_dl_info(struct dl_info *dli)
25146 ++{
25147 ++ vxdprintk(VXD_CBIT(dlim, 6),
25148 ++ "__unhash_dl_info: %p[#%d]", dli, dli->dl_tag);
25149 ++ hlist_del_rcu(&dli->dl_hlist);
25150 ++ put_dl_info(dli);
25151 ++}
25152 ++
25153 ++
25154 ++/* __lookup_dl_info()
25155 ++
25156 ++ * requires the rcu_read_lock()
25157 ++ * doesn't increment the dl_refcnt */
25158 ++
25159 ++static inline struct dl_info *__lookup_dl_info(struct super_block *sb, tag_t tag)
25160 ++{
25161 ++ struct hlist_head *head = &dl_info_hash[__hashval(sb, tag)];
25162 ++ struct hlist_node *pos;
25163 ++ struct dl_info *dli;
25164 ++
25165 ++ hlist_for_each_entry_rcu(dli, pos, head, dl_hlist) {
25166 ++
25167 ++ if (dli->dl_tag == tag && dli->dl_sb == sb) {
25168 ++ return dli;
25169 ++ }
25170 ++ }
25171 ++ return NULL;
25172 ++}
25173 ++
25174 ++
25175 ++struct dl_info *locate_dl_info(struct super_block *sb, tag_t tag)
25176 ++{
25177 ++ struct dl_info *dli;
25178 ++
25179 ++ rcu_read_lock();
25180 ++ dli = get_dl_info(__lookup_dl_info(sb, tag));
25181 ++ vxdprintk(VXD_CBIT(dlim, 7),
25182 ++ "locate_dl_info(%p,#%d) = %p", sb, tag, dli);
25183 ++ rcu_read_unlock();
25184 ++ return dli;
25185 ++}
25186 ++
25187 ++void rcu_free_dl_info(struct rcu_head *head)
25188 ++{
25189 ++ struct dl_info *dli = container_of(head, struct dl_info, dl_rcu);
25190 ++ int usecnt, refcnt;
25191 ++
25192 ++ BUG_ON(!dli || !head);
25193 ++
25194 ++ usecnt = atomic_read(&dli->dl_usecnt);
25195 ++ BUG_ON(usecnt < 0);
25196 ++
25197 ++ refcnt = atomic_read(&dli->dl_refcnt);
25198 ++ BUG_ON(refcnt < 0);
25199 ++
25200 ++ vxdprintk(VXD_CBIT(dlim, 3),
25201 ++ "rcu_free_dl_info(%p)", dli);
25202 ++ if (!usecnt)
25203 ++ __dealloc_dl_info(dli);
25204 ++ else
25205 ++ printk("!!! rcu didn't free\n");
25206 ++}
25207 ++
25208 ++
25209 ++
25210 ++
25211 ++static int do_addrem_dlimit(uint32_t id, const char __user *name,
25212 ++ uint32_t flags, int add)
25213 ++{
25214 ++ struct nameidata nd;
25215 ++ int ret;
25216 ++
25217 ++ ret = user_path_walk_link(name, &nd);
25218 ++ if (!ret) {
25219 ++ struct super_block *sb;
25220 ++ struct dl_info *dli;
25221 ++
25222 ++ ret = -EINVAL;
25223 ++ if (!nd.dentry->d_inode)
25224 ++ goto out_release;
25225 ++ if (!(sb = nd.dentry->d_inode->i_sb))
25226 ++ goto out_release;
25227 ++
25228 ++ if (add) {
25229 ++ dli = __alloc_dl_info(sb, id);
25230 ++ spin_lock(&dl_info_hash_lock);
25231 ++
25232 ++ ret = -EEXIST;
25233 ++ if (__lookup_dl_info(sb, id))
25234 ++ goto out_unlock;
25235 ++ __hash_dl_info(dli);
25236 ++ dli = NULL;
25237 ++ } else {
25238 ++ spin_lock(&dl_info_hash_lock);
25239 ++ dli = __lookup_dl_info(sb, id);
25240 ++
25241 ++ ret = -ESRCH;
25242 ++ if (!dli)
25243 ++ goto out_unlock;
25244 ++ __unhash_dl_info(dli);
25245 ++ }
25246 ++ ret = 0;
25247 ++ out_unlock:
25248 ++ spin_unlock(&dl_info_hash_lock);
25249 ++ if (add && dli)
25250 ++ __dealloc_dl_info(dli);
25251 ++ out_release:
25252 ++ path_release(&nd);
25253 ++ }
25254 ++ return ret;
25255 ++}
25256 ++
25257 ++int vc_add_dlimit(uint32_t id, void __user *data)
25258 ++{
25259 ++ struct vcmd_ctx_dlimit_base_v0 vc_data;
25260 ++
25261 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
25262 ++ return -EFAULT;
25263 ++
25264 ++ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1);
25265 ++}
25266 ++
25267 ++int vc_rem_dlimit(uint32_t id, void __user *data)
25268 ++{
25269 ++ struct vcmd_ctx_dlimit_base_v0 vc_data;
25270 ++
25271 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
25272 ++ return -EFAULT;
25273 ++
25274 ++ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0);
25275 ++}
25276 ++
25277 ++#ifdef CONFIG_COMPAT
25278 ++
25279 ++int vc_add_dlimit_x32(uint32_t id, void __user *data)
25280 ++{
25281 ++ struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
25282 ++
25283 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
25284 ++ return -EFAULT;
25285 ++
25286 ++ return do_addrem_dlimit(id,
25287 ++ compat_ptr(vc_data.name_ptr), vc_data.flags, 1);
25288 ++}
25289 ++
25290 ++int vc_rem_dlimit_x32(uint32_t id, void __user *data)
25291 ++{
25292 ++ struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
25293 ++
25294 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
25295 ++ return -EFAULT;
25296 ++
25297 ++ return do_addrem_dlimit(id,
25298 ++ compat_ptr(vc_data.name_ptr), vc_data.flags, 0);
25299 ++}
25300 ++
25301 ++#endif /* CONFIG_COMPAT */
25302 ++
25303 ++
25304 ++static inline
25305 ++int do_set_dlimit(uint32_t id, const char __user *name,
25306 ++ uint32_t space_used, uint32_t space_total,
25307 ++ uint32_t inodes_used, uint32_t inodes_total,
25308 ++ uint32_t reserved, uint32_t flags)
25309 ++{
25310 ++ struct nameidata nd;
25311 ++ int ret;
25312 ++
25313 ++ ret = user_path_walk_link(name, &nd);
25314 ++ if (!ret) {
25315 ++ struct super_block *sb;
25316 ++ struct dl_info *dli;
25317 ++
25318 ++ ret = -EINVAL;
25319 ++ if (!nd.dentry->d_inode)
25320 ++ goto out_release;
25321 ++ if (!(sb = nd.dentry->d_inode->i_sb))
25322 ++ goto out_release;
25323 ++ if ((reserved != CDLIM_KEEP &&
25324 ++ reserved > 100) ||
25325 ++ (inodes_used != CDLIM_KEEP &&
25326 ++ inodes_used > inodes_total) ||
25327 ++ (space_used != CDLIM_KEEP &&
25328 ++ space_used > space_total))
25329 ++ goto out_release;
25330 ++
25331 ++ ret = -ESRCH;
25332 ++ dli = locate_dl_info(sb, id);
25333 ++ if (!dli)
25334 ++ goto out_release;
25335 ++
25336 ++ spin_lock(&dli->dl_lock);
25337 ++
25338 ++ if (inodes_used != CDLIM_KEEP)
25339 ++ dli->dl_inodes_used = inodes_used;
25340 ++ if (inodes_total != CDLIM_KEEP)
25341 ++ dli->dl_inodes_total = inodes_total;
25342 ++ if (space_used != CDLIM_KEEP) {
25343 ++ dli->dl_space_used = space_used;
25344 ++ dli->dl_space_used <<= 10;
25345 ++ }
25346 ++ if (space_total == CDLIM_INFINITY)
25347 ++ dli->dl_space_total = DLIM_INFINITY;
25348 ++ else if (space_total != CDLIM_KEEP) {
25349 ++ dli->dl_space_total = space_total;
25350 ++ dli->dl_space_total <<= 10;
25351 ++ }
25352 ++ if (reserved != CDLIM_KEEP)
25353 ++ dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100;
25354 ++
25355 ++ spin_unlock(&dli->dl_lock);
25356 ++
25357 ++ put_dl_info(dli);
25358 ++ ret = 0;
25359 ++
25360 ++ out_release:
25361 ++ path_release(&nd);
25362 ++ }
25363 ++ return ret;
25364 ++}
25365 ++
25366 ++int vc_set_dlimit(uint32_t id, void __user *data)
25367 ++{
25368 ++ struct vcmd_ctx_dlimit_v0 vc_data;
25369 ++
25370 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
25371 ++ return -EFAULT;
25372 ++
25373 ++ return do_set_dlimit(id, vc_data.name,
25374 ++ vc_data.space_used, vc_data.space_total,
25375 ++ vc_data.inodes_used, vc_data.inodes_total,
25376 ++ vc_data.reserved, vc_data.flags);
25377 ++}
25378 ++
25379 ++#ifdef CONFIG_COMPAT
25380 ++
25381 ++int vc_set_dlimit_x32(uint32_t id, void __user *data)
25382 ++{
25383 ++ struct vcmd_ctx_dlimit_v0_x32 vc_data;
25384 ++
25385 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
25386 ++ return -EFAULT;
25387 ++
25388 ++ return do_set_dlimit(id, compat_ptr(vc_data.name_ptr),
25389 ++ vc_data.space_used, vc_data.space_total,
25390 ++ vc_data.inodes_used, vc_data.inodes_total,
25391 ++ vc_data.reserved, vc_data.flags);
25392 ++}
25393 ++
25394 ++#endif /* CONFIG_COMPAT */
25395 ++
25396 ++
25397 ++static inline
25398 ++int do_get_dlimit(uint32_t id, const char __user *name,
25399 ++ uint32_t *space_used, uint32_t *space_total,
25400 ++ uint32_t *inodes_used, uint32_t *inodes_total,
25401 ++ uint32_t *reserved, uint32_t *flags)
25402 ++{
25403 ++ struct nameidata nd;
25404 ++ int ret;
25405 ++
25406 ++ ret = user_path_walk_link(name, &nd);
25407 ++ if (!ret) {
25408 ++ struct super_block *sb;
25409 ++ struct dl_info *dli;
25410 ++
25411 ++ ret = -EINVAL;
25412 ++ if (!nd.dentry->d_inode)
25413 ++ goto out_release;
25414 ++ if (!(sb = nd.dentry->d_inode->i_sb))
25415 ++ goto out_release;
25416 ++
25417 ++ ret = -ESRCH;
25418 ++ dli = locate_dl_info(sb, id);
25419 ++ if (!dli)
25420 ++ goto out_release;
25421 ++
25422 ++ spin_lock(&dli->dl_lock);
25423 ++ *inodes_used = dli->dl_inodes_used;
25424 ++ *inodes_total = dli->dl_inodes_total;
25425 ++ *space_used = dli->dl_space_used >> 10;
25426 ++ if (dli->dl_space_total == DLIM_INFINITY)
25427 ++ *space_total = CDLIM_INFINITY;
25428 ++ else
25429 ++ *space_total = dli->dl_space_total >> 10;
25430 ++
25431 ++ *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10);
25432 ++ spin_unlock(&dli->dl_lock);
25433 ++
25434 ++ put_dl_info(dli);
25435 ++ ret = -EFAULT;
25436 ++
25437 ++ ret = 0;
25438 ++ out_release:
25439 ++ path_release(&nd);
25440 ++ }
25441 ++ return ret;
25442 ++}
25443 ++
25444 ++
25445 ++int vc_get_dlimit(uint32_t id, void __user *data)
25446 ++{
25447 ++ struct vcmd_ctx_dlimit_v0 vc_data;
25448 ++ int ret;
25449 ++
25450 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
25451 ++ return -EFAULT;
25452 ++
25453 ++ ret = do_get_dlimit(id, vc_data.name,
25454 ++ &vc_data.space_used, &vc_data.space_total,
25455 ++ &vc_data.inodes_used, &vc_data.inodes_total,
25456 ++ &vc_data.reserved, &vc_data.flags);
25457 ++ if (ret)
25458 ++ return ret;
25459 ++
25460 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
25461 ++ return -EFAULT;
25462 ++ return 0;
25463 ++}
25464 ++
25465 ++#ifdef CONFIG_COMPAT
25466 ++
25467 ++int vc_get_dlimit_x32(uint32_t id, void __user *data)
25468 ++{
25469 ++ struct vcmd_ctx_dlimit_v0_x32 vc_data;
25470 ++ int ret;
25471 ++
25472 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
25473 ++ return -EFAULT;
25474 ++
25475 ++ ret = do_get_dlimit(id, compat_ptr(vc_data.name_ptr),
25476 ++ &vc_data.space_used, &vc_data.space_total,
25477 ++ &vc_data.inodes_used, &vc_data.inodes_total,
25478 ++ &vc_data.reserved, &vc_data.flags);
25479 ++ if (ret)
25480 ++ return ret;
25481 ++
25482 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
25483 ++ return -EFAULT;
25484 ++ return 0;
25485 ++}
25486 ++
25487 ++#endif /* CONFIG_COMPAT */
25488 ++
25489 ++
25490 ++void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf)
25491 ++{
25492 ++ struct dl_info *dli;
25493 ++ __u64 blimit, bfree, bavail;
25494 ++ __u32 ifree;
25495 ++
25496 ++ dli = locate_dl_info(sb, dx_current_tag());
25497 ++ if (!dli)
25498 ++ return;
25499 ++
25500 ++ spin_lock(&dli->dl_lock);
25501 ++ if (dli->dl_inodes_total == (unsigned long)DLIM_INFINITY)
25502 ++ goto no_ilim;
25503 ++
25504 ++ /* reduce max inodes available to limit */
25505 ++ if (buf->f_files > dli->dl_inodes_total)
25506 ++ buf->f_files = dli->dl_inodes_total;
25507 ++
25508 ++ ifree = dli->dl_inodes_total - dli->dl_inodes_used;
25509 ++ /* reduce free inodes to min */
25510 ++ if (ifree < buf->f_ffree)
25511 ++ buf->f_ffree = ifree;
25512 ++
25513 ++no_ilim:
25514 ++ if (dli->dl_space_total == DLIM_INFINITY)
25515 ++ goto no_blim;
25516 ++
25517 ++ blimit = dli->dl_space_total >> sb->s_blocksize_bits;
25518 ++
25519 ++ if (dli->dl_space_total < dli->dl_space_used)
25520 ++ bfree = 0;
25521 ++ else
25522 ++ bfree = (dli->dl_space_total - dli->dl_space_used)
25523 ++ >> sb->s_blocksize_bits;
25524 ++
25525 ++ bavail = ((dli->dl_space_total >> 10) * dli->dl_nrlmult);
25526 ++ if (bavail < dli->dl_space_used)
25527 ++ bavail = 0;
25528 ++ else
25529 ++ bavail = (bavail - dli->dl_space_used)
25530 ++ >> sb->s_blocksize_bits;
25531 ++
25532 ++ /* reduce max space available to limit */
25533 ++ if (buf->f_blocks > blimit)
25534 ++ buf->f_blocks = blimit;
25535 ++
25536 ++ /* reduce free space to min */
25537 ++ if (bfree < buf->f_bfree)
25538 ++ buf->f_bfree = bfree;
25539 ++
25540 ++ /* reduce avail space to min */
25541 ++ if (bavail < buf->f_bavail)
25542 ++ buf->f_bavail = bavail;
25543 ++
25544 ++no_blim:
25545 ++ spin_unlock(&dli->dl_lock);
25546 ++ put_dl_info(dli);
25547 ++
25548 ++ return;
25549 ++}
25550 ++
25551 ++#include <linux/module.h>
25552 ++
25553 ++EXPORT_SYMBOL_GPL(locate_dl_info);
25554 ++EXPORT_SYMBOL_GPL(rcu_free_dl_info);
25555 ++
25556 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/helper.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/helper.c
25557 +--- linux-2.6.22.19/kernel/vserver/helper.c 1970-01-01 01:00:00 +0100
25558 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/helper.c 2007-06-15 02:37:04 +0200
25559 +@@ -0,0 +1,208 @@
25560 ++/*
25561 ++ * linux/kernel/vserver/helper.c
25562 ++ *
25563 ++ * Virtual Context Support
25564 ++ *
25565 ++ * Copyright (C) 2004-2007 Herbert Pötzl
25566 ++ *
25567 ++ * V0.01 basic helper
25568 ++ *
25569 ++ */
25570 ++
25571 ++#include <linux/errno.h>
25572 ++#include <linux/kmod.h>
25573 ++#include <linux/sched.h>
25574 ++#include <linux/reboot.h>
25575 ++#include <linux/vs_context.h>
25576 ++#include <linux/vs_network.h>
25577 ++#include <linux/vserver/signal.h>
25578 ++
25579 ++#include <asm/uaccess.h>
25580 ++#include <asm/unistd.h>
25581 ++
25582 ++
25583 ++char vshelper_path[255] = "/sbin/vshelper";
25584 ++
25585 ++
25586 ++static int do_vshelper(char *name, char *argv[], char *envp[], int sync)
25587 ++{
25588 ++ int ret;
25589 ++
25590 ++ if ((ret = call_usermodehelper(name, argv, envp, sync))) {
25591 ++ printk( KERN_WARNING
25592 ++ "%s: (%s %s) returned %s with %d\n",
25593 ++ name, argv[1], argv[2],
25594 ++ sync ? "sync" : "async", ret);
25595 ++ }
25596 ++ vxdprintk(VXD_CBIT(switch, 4),
25597 ++ "%s: (%s %s) returned %s with %d",
25598 ++ name, argv[1], argv[2], sync ? "sync" : "async", ret);
25599 ++ return ret;
25600 ++}
25601 ++
25602 ++/*
25603 ++ * vshelper path is set via /proc/sys
25604 ++ * invoked by vserver sys_reboot(), with
25605 ++ * the following arguments
25606 ++ *
25607 ++ * argv [0] = vshelper_path;
25608 ++ * argv [1] = action: "restart", "halt", "poweroff", ...
25609 ++ * argv [2] = context identifier
25610 ++ *
25611 ++ * envp [*] = type-specific parameters
25612 ++ */
25613 ++
25614 ++long vs_reboot_helper(struct vx_info *vxi, int cmd, void __user *arg)
25615 ++{
25616 ++ char id_buf[8], cmd_buf[16];
25617 ++ char uid_buf[16], pid_buf[16];
25618 ++ int ret;
25619 ++
25620 ++ char *argv[] = {vshelper_path, NULL, id_buf, 0};
25621 ++ char *envp[] = {"HOME=/", "TERM=linux",
25622 ++ "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
25623 ++ uid_buf, pid_buf, cmd_buf, 0};
25624 ++
25625 ++ if (vx_info_state(vxi, VXS_HELPER))
25626 ++ return -EAGAIN;
25627 ++ vxi->vx_state |= VXS_HELPER;
25628 ++
25629 ++ snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id);
25630 ++
25631 ++ snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
25632 ++ snprintf(uid_buf, sizeof(uid_buf)-1, "VS_UID=%d", current->uid);
25633 ++ snprintf(pid_buf, sizeof(pid_buf)-1, "VS_PID=%d", current->pid);
25634 ++
25635 ++ switch (cmd) {
25636 ++ case LINUX_REBOOT_CMD_RESTART:
25637 ++ argv[1] = "restart";
25638 ++ break;
25639 ++
25640 ++ case LINUX_REBOOT_CMD_HALT:
25641 ++ argv[1] = "halt";
25642 ++ break;
25643 ++
25644 ++ case LINUX_REBOOT_CMD_POWER_OFF:
25645 ++ argv[1] = "poweroff";
25646 ++ break;
25647 ++
25648 ++ case LINUX_REBOOT_CMD_SW_SUSPEND:
25649 ++ argv[1] = "swsusp";
25650 ++ break;
25651 ++
25652 ++ default:
25653 ++ vxi->vx_state &= ~VXS_HELPER;
25654 ++ return 0;
25655 ++ }
25656 ++
25657 ++#ifndef CONFIG_VSERVER_LEGACY
25658 ++ ret = do_vshelper(vshelper_path, argv, envp, 1);
25659 ++#else
25660 ++ ret = do_vshelper(vshelper_path, argv, envp, 0);
25661 ++#endif
25662 ++ vxi->vx_state &= ~VXS_HELPER;
25663 ++ __wakeup_vx_info(vxi);
25664 ++ return (ret) ? -EPERM : 0;
25665 ++}
25666 ++
25667 ++
25668 ++long vs_reboot(unsigned int cmd, void __user *arg)
25669 ++{
25670 ++ struct vx_info *vxi = current->vx_info;
25671 ++ long ret = 0;
25672 ++
25673 ++ vxdprintk(VXD_CBIT(misc, 5),
25674 ++ "vs_reboot(%p[#%d],%d)",
25675 ++ vxi, vxi ? vxi->vx_id : 0, cmd);
25676 ++
25677 ++ ret = vs_reboot_helper(vxi, cmd, arg);
25678 ++ if (ret)
25679 ++ return ret;
25680 ++
25681 ++ vxi->reboot_cmd = cmd;
25682 ++ if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
25683 ++ switch (cmd) {
25684 ++ case LINUX_REBOOT_CMD_RESTART:
25685 ++ case LINUX_REBOOT_CMD_HALT:
25686 ++ case LINUX_REBOOT_CMD_POWER_OFF:
25687 ++ vx_info_kill(vxi, 0, SIGKILL);
25688 ++ vx_info_kill(vxi, 1, SIGKILL);
25689 ++ default:
25690 ++ break;
25691 ++ }
25692 ++ }
25693 ++ return 0;
25694 ++}
25695 ++
25696 ++
25697 ++/*
25698 ++ * argv [0] = vshelper_path;
25699 ++ * argv [1] = action: "startup", "shutdown"
25700 ++ * argv [2] = context identifier
25701 ++ *
25702 ++ * envp [*] = type-specific parameters
25703 ++ */
25704 ++
25705 ++long vs_state_change(struct vx_info *vxi, unsigned int cmd)
25706 ++{
25707 ++ char id_buf[8], cmd_buf[16];
25708 ++ char *argv[] = {vshelper_path, NULL, id_buf, 0};
25709 ++ char *envp[] = {"HOME=/", "TERM=linux",
25710 ++ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
25711 ++
25712 ++ if (!vx_info_flags(vxi, VXF_SC_HELPER, 0))
25713 ++ return 0;
25714 ++
25715 ++ snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id);
25716 ++ snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
25717 ++
25718 ++ switch (cmd) {
25719 ++ case VSC_STARTUP:
25720 ++ argv[1] = "startup";
25721 ++ break;
25722 ++ case VSC_SHUTDOWN:
25723 ++ argv[1] = "shutdown";
25724 ++ break;
25725 ++ default:
25726 ++ return 0;
25727 ++ }
25728 ++
25729 ++ return do_vshelper(vshelper_path, argv, envp, 1);
25730 ++}
25731 ++
25732 ++
25733 ++/*
25734 ++ * argv [0] = vshelper_path;
25735 ++ * argv [1] = action: "netup", "netdown"
25736 ++ * argv [2] = context identifier
25737 ++ *
25738 ++ * envp [*] = type-specific parameters
25739 ++ */
25740 ++
25741 ++long vs_net_change(struct nx_info *nxi, unsigned int cmd)
25742 ++{
25743 ++ char id_buf[8], cmd_buf[16];
25744 ++ char *argv[] = {vshelper_path, NULL, id_buf, 0};
25745 ++ char *envp[] = {"HOME=/", "TERM=linux",
25746 ++ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
25747 ++
25748 ++ if (!nx_info_flags(nxi, NXF_SC_HELPER, 0))
25749 ++ return 0;
25750 ++
25751 ++ snprintf(id_buf, sizeof(id_buf)-1, "%d", nxi->nx_id);
25752 ++ snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
25753 ++
25754 ++ switch (cmd) {
25755 ++ case VSC_NETUP:
25756 ++ argv[1] = "netup";
25757 ++ break;
25758 ++ case VSC_NETDOWN:
25759 ++ argv[1] = "netdown";
25760 ++ break;
25761 ++ default:
25762 ++ return 0;
25763 ++ }
25764 ++
25765 ++ return do_vshelper(vshelper_path, argv, envp, 1);
25766 ++}
25767 ++
25768 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/history.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/history.c
25769 +--- linux-2.6.22.19/kernel/vserver/history.c 1970-01-01 01:00:00 +0100
25770 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/history.c 2007-06-15 02:37:04 +0200
25771 +@@ -0,0 +1,264 @@
25772 ++/*
25773 ++ * kernel/vserver/history.c
25774 ++ *
25775 ++ * Virtual Context History Backtrace
25776 ++ *
25777 ++ * Copyright (C) 2004-2007 Herbert Pötzl
25778 ++ *
25779 ++ * V0.01 basic structure
25780 ++ * V0.02 hash/unhash and trace
25781 ++ * V0.03 preemption fixes
25782 ++ *
25783 ++ */
25784 ++
25785 ++#include <linux/errno.h>
25786 ++#include <linux/module.h>
25787 ++#include <linux/types.h>
25788 ++#include <linux/ctype.h>
25789 ++
25790 ++#include <asm/uaccess.h>
25791 ++#include <asm/atomic.h>
25792 ++#include <asm/unistd.h>
25793 ++
25794 ++#include <linux/vserver/context.h>
25795 ++#include <linux/vserver/debug.h>
25796 ++#include <linux/vserver/debug_cmd.h>
25797 ++#include <linux/vserver/history.h>
25798 ++
25799 ++
25800 ++#ifdef CONFIG_VSERVER_HISTORY
25801 ++#define VXH_SIZE CONFIG_VSERVER_HISTORY_SIZE
25802 ++#else
25803 ++#define VXH_SIZE 64
25804 ++#endif
25805 ++
25806 ++struct _vx_history {
25807 ++ unsigned int counter;
25808 ++
25809 ++ struct _vx_hist_entry entry[VXH_SIZE + 1];
25810 ++};
25811 ++
25812 ++
25813 ++DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
25814 ++
25815 ++unsigned volatile int vxh_active = 1;
25816 ++
25817 ++static atomic_t sequence = ATOMIC_INIT(0);
25818 ++
25819 ++
25820 ++/* vxh_advance()
25821 ++
25822 ++ * requires disabled preemption */
25823 ++
25824 ++struct _vx_hist_entry *vxh_advance(void *loc)
25825 ++{
25826 ++ unsigned int cpu = smp_processor_id();
25827 ++ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
25828 ++ struct _vx_hist_entry *entry;
25829 ++ unsigned int index;
25830 ++
25831 ++ index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
25832 ++ entry = &hist->entry[index];
25833 ++
25834 ++ entry->seq = atomic_inc_return(&sequence);
25835 ++ entry->loc = loc;
25836 ++ return entry;
25837 ++}
25838 ++
25839 ++EXPORT_SYMBOL_GPL(vxh_advance);
25840 ++
25841 ++
25842 ++#define VXH_LOC_FMTS "(#%04x,*%d):%p"
25843 ++
25844 ++#define VXH_LOC_ARGS(e) (e)->seq, cpu, (e)->loc
25845 ++
25846 ++
25847 ++#define VXH_VXI_FMTS "%p[#%d,%d.%d]"
25848 ++
25849 ++#define VXH_VXI_ARGS(e) (e)->vxi.ptr, \
25850 ++ (e)->vxi.ptr ? (e)->vxi.xid : 0, \
25851 ++ (e)->vxi.ptr ? (e)->vxi.usecnt : 0, \
25852 ++ (e)->vxi.ptr ? (e)->vxi.tasks : 0
25853 ++
25854 ++void vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
25855 ++{
25856 ++ switch (e->type) {
25857 ++ case VXH_THROW_OOPS:
25858 ++ printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
25859 ++ break;
25860 ++
25861 ++ case VXH_GET_VX_INFO:
25862 ++ case VXH_PUT_VX_INFO:
25863 ++ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
25864 ++ VXH_LOC_ARGS(e),
25865 ++ (e->type == VXH_GET_VX_INFO) ? "get" : "put",
25866 ++ VXH_VXI_ARGS(e));
25867 ++ break;
25868 ++
25869 ++ case VXH_INIT_VX_INFO:
25870 ++ case VXH_SET_VX_INFO:
25871 ++ case VXH_CLR_VX_INFO:
25872 ++ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
25873 ++ VXH_LOC_ARGS(e),
25874 ++ (e->type == VXH_INIT_VX_INFO) ? "init" :
25875 ++ ((e->type == VXH_SET_VX_INFO) ? "set" : "clr"),
25876 ++ VXH_VXI_ARGS(e), e->sc.data);
25877 ++ break;
25878 ++
25879 ++ case VXH_CLAIM_VX_INFO:
25880 ++ case VXH_RELEASE_VX_INFO:
25881 ++ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
25882 ++ VXH_LOC_ARGS(e),
25883 ++ (e->type == VXH_CLAIM_VX_INFO) ? "claim" : "release",
25884 ++ VXH_VXI_ARGS(e), e->sc.data);
25885 ++ break;
25886 ++
25887 ++ case VXH_ALLOC_VX_INFO:
25888 ++ case VXH_DEALLOC_VX_INFO:
25889 ++ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
25890 ++ VXH_LOC_ARGS(e),
25891 ++ (e->type == VXH_ALLOC_VX_INFO) ? "alloc" : "dealloc",
25892 ++ VXH_VXI_ARGS(e));
25893 ++ break;
25894 ++
25895 ++ case VXH_HASH_VX_INFO:
25896 ++ case VXH_UNHASH_VX_INFO:
25897 ++ printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
25898 ++ VXH_LOC_ARGS(e),
25899 ++ (e->type == VXH_HASH_VX_INFO) ? "hash" : "unhash",
25900 ++ VXH_VXI_ARGS(e));
25901 ++ break;
25902 ++
25903 ++ case VXH_LOC_VX_INFO:
25904 ++ case VXH_LOOKUP_VX_INFO:
25905 ++ case VXH_CREATE_VX_INFO:
25906 ++ printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
25907 ++ VXH_LOC_ARGS(e),
25908 ++ (e->type == VXH_CREATE_VX_INFO) ? "create" :
25909 ++ ((e->type == VXH_LOC_VX_INFO) ? "loc" : "lookup"),
25910 ++ e->ll.arg, VXH_VXI_ARGS(e));
25911 ++ break;
25912 ++ }
25913 ++}
25914 ++
25915 ++static void __vxh_dump_history(void)
25916 ++{
25917 ++ unsigned int i, cpu;
25918 ++
25919 ++ printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
25920 ++ atomic_read(&sequence), NR_CPUS);
25921 ++
25922 ++ for (i = 0; i < VXH_SIZE; i++) {
25923 ++ for_each_online_cpu(cpu) {
25924 ++ struct _vx_history *hist =
25925 ++ &per_cpu(vx_history_buffer, cpu);
25926 ++ unsigned int index = (hist->counter - i) % VXH_SIZE;
25927 ++ struct _vx_hist_entry *entry = &hist->entry[index];
25928 ++
25929 ++ vxh_dump_entry(entry, cpu);
25930 ++ }
25931 ++ }
25932 ++}
25933 ++
25934 ++void vxh_dump_history(void)
25935 ++{
25936 ++ vxh_active = 0;
25937 ++#ifdef CONFIG_SMP
25938 ++ local_irq_enable();
25939 ++ smp_send_stop();
25940 ++ local_irq_disable();
25941 ++#endif
25942 ++ __vxh_dump_history();
25943 ++}
25944 ++
25945 ++
25946 ++/* vserver syscall commands below here */
25947 ++
25948 ++
25949 ++int vc_dump_history(uint32_t id)
25950 ++{
25951 ++ vxh_active = 0;
25952 ++ __vxh_dump_history();
25953 ++ vxh_active = 1;
25954 ++
25955 ++ return 0;
25956 ++}
25957 ++
25958 ++
25959 ++int do_read_history(struct __user _vx_hist_entry *data,
25960 ++ int cpu, uint32_t *index, uint32_t *count)
25961 ++{
25962 ++ int pos, ret = 0;
25963 ++ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
25964 ++ int end = hist->counter;
25965 ++ int start = end - VXH_SIZE + 2;
25966 ++ int idx = *index;
25967 ++
25968 ++ /* special case: get current pos */
25969 ++ if (!*count) {
25970 ++ *index = end;
25971 ++ return 0;
25972 ++ }
25973 ++
25974 ++ /* have we lost some data? */
25975 ++ if (idx < start)
25976 ++ idx = start;
25977 ++
25978 ++ for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
25979 ++ struct _vx_hist_entry *entry =
25980 ++ &hist->entry[idx % VXH_SIZE];
25981 ++
25982 ++ /* send entry to userspace */
25983 ++ ret = copy_to_user(&data[pos], entry, sizeof(*entry));
25984 ++ if (ret)
25985 ++ break;
25986 ++ }
25987 ++ /* save new index and count */
25988 ++ *index = idx;
25989 ++ *count = pos;
25990 ++ return ret ? ret : (*index < end);
25991 ++}
25992 ++
25993 ++int vc_read_history(uint32_t id, void __user *data)
25994 ++{
25995 ++ struct vcmd_read_history_v0 vc_data;
25996 ++ int ret;
25997 ++
25998 ++ if (id >= NR_CPUS)
25999 ++ return -EINVAL;
26000 ++
26001 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26002 ++ return -EFAULT;
26003 ++
26004 ++ ret = do_read_history((struct __user _vx_hist_entry *)vc_data.data,
26005 ++ id, &vc_data.index, &vc_data.count);
26006 ++
26007 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
26008 ++ return -EFAULT;
26009 ++ return ret;
26010 ++}
26011 ++
26012 ++#ifdef CONFIG_COMPAT
26013 ++
26014 ++int vc_read_history_x32(uint32_t id, void __user *data)
26015 ++{
26016 ++ struct vcmd_read_history_v0_x32 vc_data;
26017 ++ int ret;
26018 ++
26019 ++ if (id >= NR_CPUS)
26020 ++ return -EINVAL;
26021 ++
26022 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26023 ++ return -EFAULT;
26024 ++
26025 ++ ret = do_read_history((struct __user _vx_hist_entry *)
26026 ++ compat_ptr(vc_data.data_ptr),
26027 ++ id, &vc_data.index, &vc_data.count);
26028 ++
26029 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
26030 ++ return -EFAULT;
26031 ++ return ret;
26032 ++}
26033 ++
26034 ++#endif /* CONFIG_COMPAT */
26035 ++
26036 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/init.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/init.c
26037 +--- linux-2.6.22.19/kernel/vserver/init.c 1970-01-01 01:00:00 +0100
26038 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/init.c 2007-06-15 02:37:04 +0200
26039 +@@ -0,0 +1,47 @@
26040 ++/*
26041 ++ * linux/kernel/init.c
26042 ++ *
26043 ++ * Virtual Server Init
26044 ++ *
26045 ++ * Copyright (C) 2004-2007 Herbert Pötzl
26046 ++ *
26047 ++ * V0.01 basic structure
26048 ++ *
26049 ++ */
26050 ++
26051 ++#include <linux/errno.h>
26052 ++#include <linux/init.h>
26053 ++#include <linux/module.h>
26054 ++
26055 ++int vserver_register_sysctl(void);
26056 ++void vserver_unregister_sysctl(void);
26057 ++
26058 ++
26059 ++static int __init init_vserver(void)
26060 ++{
26061 ++ int ret = 0;
26062 ++
26063 ++#ifdef CONFIG_VSERVER_DEBUG
26064 ++ vserver_register_sysctl();
26065 ++#endif
26066 ++ return ret;
26067 ++}
26068 ++
26069 ++
26070 ++static void __exit exit_vserver(void)
26071 ++{
26072 ++
26073 ++#ifdef CONFIG_VSERVER_DEBUG
26074 ++ vserver_unregister_sysctl();
26075 ++#endif
26076 ++ return;
26077 ++}
26078 ++
26079 ++/* FIXME: GFP_ZONETYPES gone
26080 ++long vx_slab[GFP_ZONETYPES]; */
26081 ++long vx_area;
26082 ++
26083 ++
26084 ++module_init(init_vserver);
26085 ++module_exit(exit_vserver);
26086 ++
26087 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/inode.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/inode.c
26088 +--- linux-2.6.22.19/kernel/vserver/inode.c 1970-01-01 01:00:00 +0100
26089 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/inode.c 2007-07-16 06:39:15 +0200
26090 +@@ -0,0 +1,417 @@
26091 ++/*
26092 ++ * linux/kernel/vserver/inode.c
26093 ++ *
26094 ++ * Virtual Server: File System Support
26095 ++ *
26096 ++ * Copyright (C) 2004-2007 Herbert Pötzl
26097 ++ *
26098 ++ * V0.01 separated from vcontext V0.05
26099 ++ *
26100 ++ */
26101 ++
26102 ++#include <linux/sched.h>
26103 ++#include <linux/proc_fs.h>
26104 ++#include <linux/devpts_fs.h>
26105 ++#include <linux/namei.h>
26106 ++#include <linux/mount.h>
26107 ++#include <linux/parser.h>
26108 ++#include <linux/file.h>
26109 ++#include <linux/compat.h>
26110 ++#include <linux/vserver/inode.h>
26111 ++#include <linux/vserver/inode_cmd.h>
26112 ++#include <linux/vs_base.h>
26113 ++#include <linux/vs_tag.h>
26114 ++
26115 ++#include <asm/errno.h>
26116 ++#include <asm/uaccess.h>
26117 ++
26118 ++
26119 ++static int __vc_get_iattr(struct inode *in, uint32_t *tag, uint32_t *flags, uint32_t *mask)
26120 ++{
26121 ++ struct proc_dir_entry *entry;
26122 ++
26123 ++ if (!in || !in->i_sb)
26124 ++ return -ESRCH;
26125 ++
26126 ++ *flags = IATTR_TAG
26127 ++ | (IS_BARRIER(in) ? IATTR_BARRIER : 0)
26128 ++ | (IS_IUNLINK(in) ? IATTR_IUNLINK : 0)
26129 ++ | (IS_IMMUTABLE(in) ? IATTR_IMMUTABLE : 0);
26130 ++ *mask = IATTR_IUNLINK | IATTR_IMMUTABLE;
26131 ++
26132 ++ if (S_ISDIR(in->i_mode))
26133 ++ *mask |= IATTR_BARRIER;
26134 ++
26135 ++ if (IS_TAGGED(in)) {
26136 ++ *tag = in->i_tag;
26137 ++ *mask |= IATTR_TAG;
26138 ++ }
26139 ++
26140 ++ switch (in->i_sb->s_magic) {
26141 ++ case PROC_SUPER_MAGIC:
26142 ++ entry = PROC_I(in)->pde;
26143 ++
26144 ++ /* check for specific inodes? */
26145 ++ if (entry)
26146 ++ *mask |= IATTR_FLAGS;
26147 ++ if (entry)
26148 ++ *flags |= (entry->vx_flags & IATTR_FLAGS);
26149 ++ else
26150 ++ *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS);
26151 ++ break;
26152 ++
26153 ++ case DEVPTS_SUPER_MAGIC:
26154 ++ *tag = in->i_tag;
26155 ++ *mask |= IATTR_TAG;
26156 ++ break;
26157 ++
26158 ++ default:
26159 ++ break;
26160 ++ }
26161 ++ return 0;
26162 ++}
26163 ++
26164 ++int vc_get_iattr(void __user *data)
26165 ++{
26166 ++ struct nameidata nd;
26167 ++ struct vcmd_ctx_iattr_v1 vc_data = { .xid = -1 };
26168 ++ int ret;
26169 ++
26170 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26171 ++ return -EFAULT;
26172 ++
26173 ++ ret = user_path_walk_link(vc_data.name, &nd);
26174 ++ if (!ret) {
26175 ++ ret = __vc_get_iattr(nd.dentry->d_inode,
26176 ++ &vc_data.xid, &vc_data.flags, &vc_data.mask);
26177 ++ path_release(&nd);
26178 ++ }
26179 ++ if (ret)
26180 ++ return ret;
26181 ++
26182 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
26183 ++ ret = -EFAULT;
26184 ++ return ret;
26185 ++}
26186 ++
26187 ++#ifdef CONFIG_COMPAT
26188 ++
26189 ++int vc_get_iattr_x32(void __user *data)
26190 ++{
26191 ++ struct nameidata nd;
26192 ++ struct vcmd_ctx_iattr_v1_x32 vc_data = { .xid = -1 };
26193 ++ int ret;
26194 ++
26195 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26196 ++ return -EFAULT;
26197 ++
26198 ++ ret = user_path_walk_link(compat_ptr(vc_data.name_ptr), &nd);
26199 ++ if (!ret) {
26200 ++ ret = __vc_get_iattr(nd.dentry->d_inode,
26201 ++ &vc_data.xid, &vc_data.flags, &vc_data.mask);
26202 ++ path_release(&nd);
26203 ++ }
26204 ++ if (ret)
26205 ++ return ret;
26206 ++
26207 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
26208 ++ ret = -EFAULT;
26209 ++ return ret;
26210 ++}
26211 ++
26212 ++#endif /* CONFIG_COMPAT */
26213 ++
26214 ++
26215 ++int vc_fget_iattr(uint32_t fd, void __user *data)
26216 ++{
26217 ++ struct file *filp;
26218 ++ struct vcmd_ctx_fiattr_v0 vc_data = { .xid = -1 };
26219 ++ int ret;
26220 ++
26221 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26222 ++ return -EFAULT;
26223 ++
26224 ++ filp = fget(fd);
26225 ++ if (!filp || !filp->f_dentry || !filp->f_dentry->d_inode)
26226 ++ return -EBADF;
26227 ++
26228 ++ ret = __vc_get_iattr(filp->f_dentry->d_inode,
26229 ++ &vc_data.xid, &vc_data.flags, &vc_data.mask);
26230 ++
26231 ++ fput(filp);
26232 ++
26233 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
26234 ++ ret = -EFAULT;
26235 ++ return ret;
26236 ++}
26237 ++
26238 ++
26239 ++static int __vc_set_iattr(struct dentry *de, uint32_t *tag, uint32_t *flags, uint32_t *mask)
26240 ++{
26241 ++ struct inode *in = de->d_inode;
26242 ++ int error = 0, is_proc = 0, has_tag = 0;
26243 ++ struct iattr attr = { 0 };
26244 ++
26245 ++ if (!in || !in->i_sb)
26246 ++ return -ESRCH;
26247 ++
26248 ++ is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC);
26249 ++ if ((*mask & IATTR_FLAGS) && !is_proc)
26250 ++ return -EINVAL;
26251 ++
26252 ++ has_tag = IS_TAGGED(in) ||
26253 ++ (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC);
26254 ++ if ((*mask & IATTR_TAG) && !has_tag)
26255 ++ return -EINVAL;
26256 ++
26257 ++ mutex_lock(&in->i_mutex);
26258 ++ if (*mask & IATTR_TAG) {
26259 ++ attr.ia_tag = *tag;
26260 ++ attr.ia_valid |= ATTR_TAG;
26261 ++ }
26262 ++
26263 ++ if (*mask & IATTR_FLAGS) {
26264 ++ struct proc_dir_entry *entry = PROC_I(in)->pde;
26265 ++ unsigned int iflags = PROC_I(in)->vx_flags;
26266 ++
26267 ++ iflags = (iflags & ~(*mask & IATTR_FLAGS))
26268 ++ | (*flags & IATTR_FLAGS);
26269 ++ PROC_I(in)->vx_flags = iflags;
26270 ++ if (entry)
26271 ++ entry->vx_flags = iflags;
26272 ++ }
26273 ++
26274 ++ if (*mask & (IATTR_BARRIER | IATTR_IUNLINK | IATTR_IMMUTABLE)) {
26275 ++ if (*mask & IATTR_IMMUTABLE) {
26276 ++ if (*flags & IATTR_IMMUTABLE)
26277 ++ in->i_flags |= S_IMMUTABLE;
26278 ++ else
26279 ++ in->i_flags &= ~S_IMMUTABLE;
26280 ++ }
26281 ++ if (*mask & IATTR_IUNLINK) {
26282 ++ if (*flags & IATTR_IUNLINK)
26283 ++ in->i_flags |= S_IUNLINK;
26284 ++ else
26285 ++ in->i_flags &= ~S_IUNLINK;
26286 ++ }
26287 ++ if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) {
26288 ++ if (*flags & IATTR_BARRIER)
26289 ++ in->i_flags |= S_BARRIER;
26290 ++ else
26291 ++ in->i_flags &= ~S_BARRIER;
26292 ++ }
26293 ++ if (in->i_op && in->i_op->sync_flags) {
26294 ++ error = in->i_op->sync_flags(in);
26295 ++ if (error)
26296 ++ goto out;
26297 ++ }
26298 ++ }
26299 ++
26300 ++ if (attr.ia_valid) {
26301 ++ if (in->i_op && in->i_op->setattr)
26302 ++ error = in->i_op->setattr(de, &attr);
26303 ++ else {
26304 ++ error = inode_change_ok(in, &attr);
26305 ++ if (!error)
26306 ++ error = inode_setattr(in, &attr);
26307 ++ }
26308 ++ }
26309 ++
26310 ++out:
26311 ++ mutex_unlock(&in->i_mutex);
26312 ++ return error;
26313 ++}
26314 ++
26315 ++int vc_set_iattr(void __user *data)
26316 ++{
26317 ++ struct nameidata nd;
26318 ++ struct vcmd_ctx_iattr_v1 vc_data;
26319 ++ int ret;
26320 ++
26321 ++ if (!capable(CAP_LINUX_IMMUTABLE))
26322 ++ return -EPERM;
26323 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26324 ++ return -EFAULT;
26325 ++
26326 ++ ret = user_path_walk_link(vc_data.name, &nd);
26327 ++ if (!ret) {
26328 ++ ret = __vc_set_iattr(nd.dentry,
26329 ++ &vc_data.xid, &vc_data.flags, &vc_data.mask);
26330 ++ path_release(&nd);
26331 ++ }
26332 ++
26333 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
26334 ++ ret = -EFAULT;
26335 ++ return ret;
26336 ++}
26337 ++
26338 ++#ifdef CONFIG_COMPAT
26339 ++
26340 ++int vc_set_iattr_x32(void __user *data)
26341 ++{
26342 ++ struct nameidata nd;
26343 ++ struct vcmd_ctx_iattr_v1_x32 vc_data;
26344 ++ int ret;
26345 ++
26346 ++ if (!capable(CAP_LINUX_IMMUTABLE))
26347 ++ return -EPERM;
26348 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26349 ++ return -EFAULT;
26350 ++
26351 ++ ret = user_path_walk_link(compat_ptr(vc_data.name_ptr), &nd);
26352 ++ if (!ret) {
26353 ++ ret = __vc_set_iattr(nd.dentry,
26354 ++ &vc_data.xid, &vc_data.flags, &vc_data.mask);
26355 ++ path_release(&nd);
26356 ++ }
26357 ++
26358 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
26359 ++ ret = -EFAULT;
26360 ++ return ret;
26361 ++}
26362 ++
26363 ++#endif /* CONFIG_COMPAT */
26364 ++
26365 ++int vc_fset_iattr(uint32_t fd, void __user *data)
26366 ++{
26367 ++ struct file *filp;
26368 ++ struct vcmd_ctx_fiattr_v0 vc_data;
26369 ++ int ret;
26370 ++
26371 ++ if (!capable(CAP_LINUX_IMMUTABLE))
26372 ++ return -EPERM;
26373 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26374 ++ return -EFAULT;
26375 ++
26376 ++ filp = fget(fd);
26377 ++ if (!filp || !filp->f_dentry || !filp->f_dentry->d_inode)
26378 ++ return -EBADF;
26379 ++
26380 ++ ret = __vc_set_iattr(filp->f_dentry, &vc_data.xid,
26381 ++ &vc_data.flags, &vc_data.mask);
26382 ++
26383 ++ fput(filp);
26384 ++
26385 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
26386 ++ return -EFAULT;
26387 ++ return ret;
26388 ++}
26389 ++
26390 ++#ifdef CONFIG_VSERVER_LEGACY
26391 ++
26392 ++#define PROC_DYNAMIC_FIRST 0xF0000000UL
26393 ++
26394 ++int vx_proc_ioctl(struct inode *inode, struct file *filp,
26395 ++ unsigned int cmd, unsigned long arg)
26396 ++{
26397 ++ struct proc_dir_entry *entry;
26398 ++ int error = 0;
26399 ++ int flags;
26400 ++
26401 ++ if (inode->i_ino < PROC_DYNAMIC_FIRST)
26402 ++ return -ENOTTY;
26403 ++
26404 ++ entry = PROC_I(inode)->pde;
26405 ++ if (!entry)
26406 ++ return -ENOTTY;
26407 ++
26408 ++ switch(cmd) {
26409 ++ case FIOC_GETXFLG: {
26410 ++ /* fixme: if stealth, return -ENOTTY */
26411 ++ error = -EPERM;
26412 ++ flags = entry->vx_flags;
26413 ++ if (capable(CAP_CONTEXT))
26414 ++ error = put_user(flags, (int __user *) arg);
26415 ++ break;
26416 ++ }
26417 ++ case FIOC_SETXFLG: {
26418 ++ /* fixme: if stealth, return -ENOTTY */
26419 ++ error = -EPERM;
26420 ++ if (!capable(CAP_CONTEXT))
26421 ++ break;
26422 ++ error = -EROFS;
26423 ++ if (IS_RDONLY(inode))
26424 ++ break;
26425 ++ error = -EFAULT;
26426 ++ if (get_user(flags, (int __user *) arg))
26427 ++ break;
26428 ++ error = 0;
26429 ++ entry->vx_flags = flags;
26430 ++ break;
26431 ++ }
26432 ++ default:
26433 ++ return -ENOTTY;
26434 ++ }
26435 ++ return error;
26436 ++}
26437 ++#endif /* CONFIG_VSERVER_LEGACY */
26438 ++
26439 ++#ifdef CONFIG_PROPAGATE
26440 ++
26441 ++int dx_parse_tag(char *string, tag_t *tag, int remove)
26442 ++{
26443 ++ static match_table_t tokens = {
26444 ++ {1, "tagid=%u"},
26445 ++ {0, NULL}
26446 ++ };
26447 ++ substring_t args[MAX_OPT_ARGS];
26448 ++ int token, option = 0;
26449 ++
26450 ++ if (!string)
26451 ++ return 0;
26452 ++
26453 ++ token = match_token(string, tokens, args);
26454 ++ if (token && tag && !match_int(args, &option))
26455 ++ *tag = option;
26456 ++
26457 ++ vxdprintk(VXD_CBIT(tag, 7),
26458 ++ "dx_parse_tag(»%s«): %d:#%d",
26459 ++ string, token, option);
26460 ++
26461 ++ if ((token == 1) && remove) {
26462 ++ char *p = strstr(string, "tagid=");
26463 ++ char *q = p;
26464 ++
26465 ++ if (p) {
26466 ++ while (*q != '\0' && *q != ',')
26467 ++ q++;
26468 ++ while (*q)
26469 ++ *p++ = *q++;
26470 ++ while (*p)
26471 ++ *p++ = '\0';
26472 ++ }
26473 ++ }
26474 ++ return token;
26475 ++}
26476 ++
26477 ++void __dx_propagate_tag(struct nameidata *nd, struct inode *inode)
26478 ++{
26479 ++ tag_t new_tag = 0;
26480 ++ struct vfsmount *mnt;
26481 ++ int propagate;
26482 ++
26483 ++ if (!nd)
26484 ++ return;
26485 ++ mnt = nd->mnt;
26486 ++ if (!mnt)
26487 ++ return;
26488 ++
26489 ++ propagate = (mnt->mnt_flags & MNT_TAGID);
26490 ++ if (propagate)
26491 ++ new_tag = mnt->mnt_tag;
26492 ++
26493 ++ vxdprintk(VXD_CBIT(tag, 7),
26494 ++ "dx_propagate_tag(%p[#%lu.%d]): %d,%d",
26495 ++ inode, inode->i_ino, inode->i_tag,
26496 ++ new_tag, (propagate) ? 1 : 0);
26497 ++
26498 ++ if (propagate)
26499 ++ inode->i_tag = new_tag;
26500 ++}
26501 ++
26502 ++#include <linux/module.h>
26503 ++
26504 ++EXPORT_SYMBOL_GPL(__dx_propagate_tag);
26505 ++
26506 ++#endif /* CONFIG_PROPAGATE */
26507 ++
26508 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/legacy.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/legacy.c
26509 +--- linux-2.6.22.19/kernel/vserver/legacy.c 1970-01-01 01:00:00 +0100
26510 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/legacy.c 2007-06-15 02:37:04 +0200
26511 +@@ -0,0 +1,114 @@
26512 ++/*
26513 ++ * linux/kernel/vserver/legacy.c
26514 ++ *
26515 ++ * Virtual Server: Legacy Funtions
26516 ++ *
26517 ++ * Copyright (C) 2001-2003 Jacques Gelinas
26518 ++ * Copyright (C) 2003-2007 Herbert Pötzl
26519 ++ *
26520 ++ * V0.01 broken out from vcontext.c V0.05
26521 ++ * V0.02 updated to spaces *sigh*
26522 ++ *
26523 ++ */
26524 ++
26525 ++#include <linux/sched.h>
26526 ++#include <linux/vs_context.h>
26527 ++#include <linux/vs_network.h>
26528 ++#include <linux/vserver/legacy.h>
26529 ++#include <linux/vserver/space.h>
26530 ++// #include <linux/mnt_namespace.h>
26531 ++
26532 ++#include <asm/errno.h>
26533 ++#include <asm/uaccess.h>
26534 ++
26535 ++
26536 ++extern int vx_set_init(struct vx_info *, struct task_struct *);
26537 ++
26538 ++static int vx_set_initpid(struct vx_info *vxi, int pid)
26539 ++{
26540 ++ struct task_struct *init;
26541 ++
26542 ++ init = find_task_by_real_pid(pid);
26543 ++ if (!init)
26544 ++ return -ESRCH;
26545 ++ return vx_set_init(vxi, init);
26546 ++}
26547 ++
26548 ++int vc_new_s_context(uint32_t ctx, void __user *data)
26549 ++{
26550 ++ int ret = -ENOMEM;
26551 ++ struct vcmd_new_s_context_v1 vc_data;
26552 ++ struct vx_info *new_vxi;
26553 ++
26554 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26555 ++ return -EFAULT;
26556 ++
26557 ++ /* legacy hack, will be removed soon */
26558 ++ if (ctx == -2) {
26559 ++ /* assign flags and initpid */
26560 ++ if (!current->vx_info)
26561 ++ return -EINVAL;
26562 ++ ret = 0;
26563 ++ if (vc_data.flags & VX_INFO_INIT)
26564 ++ ret = vx_set_initpid(current->vx_info, current->tgid);
26565 ++ if (ret == 0) {
26566 ++ /* We keep the same vx_id, but lower the capabilities */
26567 ++ current->vx_info->vx_bcaps &= (~vc_data.remove_cap);
26568 ++ ret = vx_current_xid();
26569 ++ current->vx_info->vx_flags |= vc_data.flags;
26570 ++ }
26571 ++ return ret;
26572 ++ }
26573 ++
26574 ++ if (!vx_check(0, VS_ADMIN) || !capable(CAP_SYS_ADMIN)
26575 ++ /* might make sense in the future, or not ... */
26576 ++ || vx_flags(VX_INFO_PRIVATE, 0))
26577 ++ return -EPERM;
26578 ++
26579 ++ /* ugly hack for Spectator */
26580 ++ if (ctx == 1) {
26581 ++ current->xid = 1;
26582 ++ return 0;
26583 ++ }
26584 ++
26585 ++ if (((ctx > MAX_S_CONTEXT) && (ctx != VX_DYNAMIC_ID)) ||
26586 ++ (ctx == 0))
26587 ++ return -EINVAL;
26588 ++
26589 ++ if ((ctx == VX_DYNAMIC_ID) || (ctx < MIN_D_CONTEXT))
26590 ++ new_vxi = lookup_or_create_vx_info(ctx);
26591 ++ else
26592 ++ new_vxi = lookup_vx_info(ctx);
26593 ++
26594 ++ if (!new_vxi)
26595 ++ return -EINVAL;
26596 ++
26597 ++ ret = -EPERM;
26598 ++ if (!vx_info_flags(new_vxi, VXF_STATE_SETUP, 0) &&
26599 ++ vx_info_flags(new_vxi, VX_INFO_PRIVATE, 0))
26600 ++ goto out_put;
26601 ++
26602 ++ ret = vx_migrate_task(current, new_vxi,
26603 ++ vx_info_flags(new_vxi, VXF_STATE_SETUP, 0));
26604 ++ new_vxi->vx_flags &= ~VXF_STATE_SETUP;
26605 ++
26606 ++ if (ret == 0) {
26607 ++ current->vx_info->vx_bcaps &= (~vc_data.remove_cap);
26608 ++ new_vxi->vx_flags |= vc_data.flags;
26609 ++ if (vc_data.flags & VX_INFO_INIT)
26610 ++ vx_set_initpid(new_vxi, current->tgid);
26611 ++ if (vc_data.flags & VX_INFO_NAMESPACE)
26612 ++ vx_set_space(new_vxi, CLONE_NEWNS | CLONE_FS);
26613 ++ if (vc_data.flags & VX_INFO_NPROC)
26614 ++ __rlim_set(&new_vxi->limit, RLIMIT_NPROC,
26615 ++ current->signal->rlim[RLIMIT_NPROC].rlim_max);
26616 ++
26617 ++ /* tweak some defaults for legacy */
26618 ++ new_vxi->vx_flags |= (VXF_HIDE_NETIF | VXF_INFO_INIT);
26619 ++ ret = new_vxi->vx_id;
26620 ++ }
26621 ++out_put:
26622 ++ put_vx_info(new_vxi);
26623 ++ return ret;
26624 ++}
26625 ++
26626 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/legacynet.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/legacynet.c
26627 +--- linux-2.6.22.19/kernel/vserver/legacynet.c 1970-01-01 01:00:00 +0100
26628 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/legacynet.c 2007-06-15 02:37:04 +0200
26629 +@@ -0,0 +1,85 @@
26630 ++
26631 ++/*
26632 ++ * linux/kernel/vserver/legacynet.c
26633 ++ *
26634 ++ * Virtual Server: Legacy Network Funtions
26635 ++ *
26636 ++ * Copyright (C) 2001-2003 Jacques Gelinas
26637 ++ * Copyright (C) 2003-2007 Herbert Pötzl
26638 ++ *
26639 ++ * V0.01 broken out from legacy.c
26640 ++ *
26641 ++ */
26642 ++
26643 ++#include <linux/sched.h>
26644 ++#include <linux/vs_context.h>
26645 ++#include <linux/vs_network.h>
26646 ++#include <linux/vserver/legacy.h>
26647 ++// #include <linux/mnt_namespace.h>
26648 ++#include <linux/err.h>
26649 ++
26650 ++#include <asm/errno.h>
26651 ++#include <asm/uaccess.h>
26652 ++
26653 ++
26654 ++extern struct nx_info *create_nx_info(void);
26655 ++
26656 ++/* set ipv4 root (syscall) */
26657 ++
26658 ++int vc_set_ipv4root(uint32_t nbip, void __user *data)
26659 ++{
26660 ++ int i, err = -EPERM;
26661 ++ struct vcmd_set_ipv4root_v3 vc_data;
26662 ++ struct nx_info *new_nxi, *nxi = current->nx_info;
26663 ++
26664 ++ if (nbip < 0 || nbip > NB_IPV4ROOT)
26665 ++ return -EINVAL;
26666 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26667 ++ return -EFAULT;
26668 ++
26669 ++ if (!nxi || nxi->ipv4[0] == 0 || capable(CAP_NET_ADMIN))
26670 ++ /* We are allowed to change everything */
26671 ++ err = 0;
26672 ++ else if (nxi) {
26673 ++ int found = 0;
26674 ++
26675 ++ /* We are allowed to select a subset of the currently
26676 ++ installed IP numbers. No new one are allowed
26677 ++ We can't change the broadcast address though */
26678 ++ for (i = 0; i < nbip; i++) {
26679 ++ int j;
26680 ++ __u32 nxip = vc_data.nx_mask_pair[i].ip;
26681 ++ for (j = 0; j < nxi->nbipv4; j++) {
26682 ++ if (nxip == nxi->ipv4[j]) {
26683 ++ found++;
26684 ++ break;
26685 ++ }
26686 ++ }
26687 ++ }
26688 ++ if ((found == nbip) &&
26689 ++ (vc_data.broadcast == nxi->v4_bcast))
26690 ++ err = 0;
26691 ++ }
26692 ++ if (err)
26693 ++ return err;
26694 ++
26695 ++ new_nxi = create_nx_info();
26696 ++ if (IS_ERR(new_nxi))
26697 ++ return -EINVAL;
26698 ++
26699 ++ new_nxi->nbipv4 = nbip;
26700 ++ for (i = 0; i < nbip; i++) {
26701 ++ new_nxi->ipv4[i] = vc_data.nx_mask_pair[i].ip;
26702 ++ new_nxi->mask[i] = vc_data.nx_mask_pair[i].mask;
26703 ++ }
26704 ++ new_nxi->v4_bcast = vc_data.broadcast;
26705 ++ if (nxi)
26706 ++ printk("!!! switching nx_info %p->%p\n", nxi, new_nxi);
26707 ++
26708 ++ nx_migrate_task(current, new_nxi);
26709 ++ release_nx_info(new_nxi, NULL);
26710 ++ put_nx_info(new_nxi);
26711 ++ return 0;
26712 ++}
26713 ++
26714 ++
26715 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/limit.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/limit.c
26716 +--- linux-2.6.22.19/kernel/vserver/limit.c 1970-01-01 01:00:00 +0100
26717 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/limit.c 2007-06-15 02:37:04 +0200
26718 +@@ -0,0 +1,319 @@
26719 ++/*
26720 ++ * linux/kernel/vserver/limit.c
26721 ++ *
26722 ++ * Virtual Server: Context Limits
26723 ++ *
26724 ++ * Copyright (C) 2004-2007 Herbert Pötzl
26725 ++ *
26726 ++ * V0.01 broken out from vcontext V0.05
26727 ++ * V0.02 changed vcmds to vxi arg
26728 ++ *
26729 ++ */
26730 ++
26731 ++#include <linux/module.h>
26732 ++#include <linux/vs_context.h>
26733 ++#include <linux/vs_limit.h>
26734 ++#include <linux/vserver/limit.h>
26735 ++#include <linux/vserver/switch.h>
26736 ++#include <linux/vserver/limit_cmd.h>
26737 ++
26738 ++#include <asm/errno.h>
26739 ++#include <asm/uaccess.h>
26740 ++
26741 ++
26742 ++const char *vlimit_name[NUM_LIMITS] = {
26743 ++ [RLIMIT_CPU] = "CPU",
26744 ++ [RLIMIT_RSS] = "RSS",
26745 ++ [RLIMIT_NPROC] = "NPROC",
26746 ++ [RLIMIT_NOFILE] = "NOFILE",
26747 ++ [RLIMIT_MEMLOCK] = "VML",
26748 ++ [RLIMIT_AS] = "VM",
26749 ++ [RLIMIT_LOCKS] = "LOCKS",
26750 ++ [RLIMIT_SIGPENDING] = "SIGP",
26751 ++ [RLIMIT_MSGQUEUE] = "MSGQ",
26752 ++
26753 ++ [VLIMIT_NSOCK] = "NSOCK",
26754 ++ [VLIMIT_OPENFD] = "OPENFD",
26755 ++ [VLIMIT_ANON] = "ANON",
26756 ++ [VLIMIT_SHMEM] = "SHMEM",
26757 ++ [VLIMIT_DENTRY] = "DENTRY",
26758 ++};
26759 ++
26760 ++EXPORT_SYMBOL_GPL(vlimit_name);
26761 ++
26762 ++#define MASK_ENTRY(x) (1 << (x))
26763 ++
26764 ++const struct vcmd_ctx_rlimit_mask_v0 vlimit_mask = {
26765 ++ /* minimum */
26766 ++ 0
26767 ++ , /* softlimit */
26768 ++ MASK_ENTRY( RLIMIT_RSS ) |
26769 ++ MASK_ENTRY( VLIMIT_ANON ) |
26770 ++ 0
26771 ++ , /* maximum */
26772 ++ MASK_ENTRY( RLIMIT_RSS ) |
26773 ++ MASK_ENTRY( RLIMIT_NPROC ) |
26774 ++ MASK_ENTRY( RLIMIT_NOFILE ) |
26775 ++ MASK_ENTRY( RLIMIT_MEMLOCK ) |
26776 ++ MASK_ENTRY( RLIMIT_AS ) |
26777 ++ MASK_ENTRY( RLIMIT_LOCKS ) |
26778 ++ MASK_ENTRY( RLIMIT_MSGQUEUE ) |
26779 ++
26780 ++ MASK_ENTRY( VLIMIT_NSOCK ) |
26781 ++ MASK_ENTRY( VLIMIT_OPENFD ) |
26782 ++ MASK_ENTRY( VLIMIT_ANON ) |
26783 ++ MASK_ENTRY( VLIMIT_SHMEM ) |
26784 ++ MASK_ENTRY( VLIMIT_DENTRY ) |
26785 ++ 0
26786 ++};
26787 ++ /* accounting only */
26788 ++uint32_t account_mask =
26789 ++ MASK_ENTRY( VLIMIT_SEMARY ) |
26790 ++ MASK_ENTRY( VLIMIT_NSEMS ) |
26791 ++ MASK_ENTRY( VLIMIT_MAPPED ) |
26792 ++ 0;
26793 ++
26794 ++
26795 ++static int is_valid_vlimit(int id)
26796 ++{
26797 ++ uint32_t mask = vlimit_mask.minimum |
26798 ++ vlimit_mask.softlimit | vlimit_mask.maximum;
26799 ++ return mask & (1 << id);
26800 ++}
26801 ++
26802 ++static int is_accounted_vlimit(int id)
26803 ++{
26804 ++ if (is_valid_vlimit(id))
26805 ++ return 1;
26806 ++ return account_mask & (1 << id);
26807 ++}
26808 ++
26809 ++
26810 ++static inline uint64_t vc_get_soft(struct vx_info *vxi, int id)
26811 ++{
26812 ++ rlim_t limit = __rlim_soft(&vxi->limit, id);
26813 ++ return VX_VLIM(limit);
26814 ++}
26815 ++
26816 ++static inline uint64_t vc_get_hard(struct vx_info *vxi, int id)
26817 ++{
26818 ++ rlim_t limit = __rlim_hard(&vxi->limit, id);
26819 ++ return VX_VLIM(limit);
26820 ++}
26821 ++
26822 ++static int do_get_rlimit(struct vx_info *vxi, uint32_t id,
26823 ++ uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
26824 ++{
26825 ++ if (!is_valid_vlimit(id))
26826 ++ return -EINVAL;
26827 ++
26828 ++ if (minimum)
26829 ++ *minimum = CRLIM_UNSET;
26830 ++ if (softlimit)
26831 ++ *softlimit = vc_get_soft(vxi, id);
26832 ++ if (maximum)
26833 ++ *maximum = vc_get_hard(vxi, id);
26834 ++ return 0;
26835 ++}
26836 ++
26837 ++int vc_get_rlimit(struct vx_info *vxi, void __user *data)
26838 ++{
26839 ++ struct vcmd_ctx_rlimit_v0 vc_data;
26840 ++ int ret;
26841 ++
26842 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26843 ++ return -EFAULT;
26844 ++
26845 ++ ret = do_get_rlimit(vxi, vc_data.id,
26846 ++ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
26847 ++ if (ret)
26848 ++ return ret;
26849 ++
26850 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
26851 ++ return -EFAULT;
26852 ++ return 0;
26853 ++}
26854 ++
26855 ++static int do_set_rlimit(struct vx_info *vxi, uint32_t id,
26856 ++ uint64_t minimum, uint64_t softlimit, uint64_t maximum)
26857 ++{
26858 ++ if (!is_valid_vlimit(id))
26859 ++ return -EINVAL;
26860 ++
26861 ++ if (maximum != CRLIM_KEEP)
26862 ++ __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum);
26863 ++ if (softlimit != CRLIM_KEEP)
26864 ++ __rlim_soft(&vxi->limit, id) = VX_RLIM(softlimit);
26865 ++
26866 ++ /* clamp soft limit */
26867 ++ if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id))
26868 ++ __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id);
26869 ++
26870 ++ return 0;
26871 ++}
26872 ++
26873 ++int vc_set_rlimit(struct vx_info *vxi, void __user *data)
26874 ++{
26875 ++ struct vcmd_ctx_rlimit_v0 vc_data;
26876 ++
26877 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26878 ++ return -EFAULT;
26879 ++
26880 ++ return do_set_rlimit(vxi, vc_data.id,
26881 ++ vc_data.minimum, vc_data.softlimit, vc_data.maximum);
26882 ++}
26883 ++
26884 ++#ifdef CONFIG_IA32_EMULATION
26885 ++
26886 ++int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data)
26887 ++{
26888 ++ struct vcmd_ctx_rlimit_v0_x32 vc_data;
26889 ++
26890 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26891 ++ return -EFAULT;
26892 ++
26893 ++ return do_set_rlimit(vxi, vc_data.id,
26894 ++ vc_data.minimum, vc_data.softlimit, vc_data.maximum);
26895 ++}
26896 ++
26897 ++int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data)
26898 ++{
26899 ++ struct vcmd_ctx_rlimit_v0_x32 vc_data;
26900 ++ int ret;
26901 ++
26902 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26903 ++ return -EFAULT;
26904 ++
26905 ++ ret = do_get_rlimit(vxi, vc_data.id,
26906 ++ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
26907 ++ if (ret)
26908 ++ return ret;
26909 ++
26910 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
26911 ++ return -EFAULT;
26912 ++ return 0;
26913 ++}
26914 ++
26915 ++#endif /* CONFIG_IA32_EMULATION */
26916 ++
26917 ++
26918 ++int vc_get_rlimit_mask(uint32_t id, void __user *data)
26919 ++{
26920 ++ if (copy_to_user(data, &vlimit_mask, sizeof(vlimit_mask)))
26921 ++ return -EFAULT;
26922 ++ return 0;
26923 ++}
26924 ++
26925 ++
26926 ++static inline void vx_reset_minmax(struct _vx_limit *limit)
26927 ++{
26928 ++ rlim_t value;
26929 ++ int lim;
26930 ++
26931 ++ for (lim = 0; lim < NUM_LIMITS; lim++) {
26932 ++ value = __rlim_get(limit, lim);
26933 ++ __rlim_rmax(limit, lim) = value;
26934 ++ __rlim_rmin(limit, lim) = value;
26935 ++ }
26936 ++}
26937 ++
26938 ++
26939 ++int vc_reset_minmax(struct vx_info *vxi, void __user *data)
26940 ++{
26941 ++ vx_reset_minmax(&vxi->limit);
26942 ++ return 0;
26943 ++}
26944 ++
26945 ++
26946 ++int vc_rlimit_stat(struct vx_info *vxi, void __user *data)
26947 ++{
26948 ++ struct vcmd_rlimit_stat_v0 vc_data;
26949 ++ struct _vx_limit *limit = &vxi->limit;
26950 ++ int id;
26951 ++
26952 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26953 ++ return -EFAULT;
26954 ++
26955 ++ id = vc_data.id;
26956 ++ if (!is_accounted_vlimit(id))
26957 ++ return -EINVAL;
26958 ++
26959 ++ vx_limit_fixup(limit, id);
26960 ++ vc_data.hits = atomic_read(&__rlim_lhit(limit, id));
26961 ++ vc_data.value = __rlim_get(limit, id);
26962 ++ vc_data.minimum = __rlim_rmin(limit, id);
26963 ++ vc_data.maximum = __rlim_rmax(limit, id);
26964 ++
26965 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
26966 ++ return -EFAULT;
26967 ++ return 0;
26968 ++}
26969 ++
26970 ++
26971 ++void vx_vsi_meminfo(struct sysinfo *val)
26972 ++{
26973 ++ struct vx_info *vxi = current->vx_info;
26974 ++ unsigned long totalram, freeram;
26975 ++ rlim_t v;
26976 ++
26977 ++ /* we blindly accept the max */
26978 ++ v = __rlim_soft(&vxi->limit, RLIMIT_RSS);
26979 ++ totalram = (v != RLIM_INFINITY) ? v : val->totalram;
26980 ++
26981 ++ /* total minus used equals free */
26982 ++ v = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
26983 ++ freeram = (v < totalram) ? totalram - v : 0;
26984 ++
26985 ++ val->totalram = totalram;
26986 ++ val->freeram = freeram;
26987 ++ val->bufferram = 0;
26988 ++ val->totalhigh = 0;
26989 ++ val->freehigh = 0;
26990 ++ return;
26991 ++}
26992 ++
26993 ++void vx_vsi_swapinfo(struct sysinfo *val)
26994 ++{
26995 ++ struct vx_info *vxi = current->vx_info;
26996 ++ unsigned long totalswap, freeswap;
26997 ++ rlim_t v, w;
26998 ++
26999 ++ v = __rlim_soft(&vxi->limit, RLIMIT_RSS);
27000 ++ if (v == RLIM_INFINITY) {
27001 ++ val->freeswap = val->totalswap;
27002 ++ return;
27003 ++ }
27004 ++
27005 ++ /* we blindly accept the max */
27006 ++ w = __rlim_hard(&vxi->limit, RLIMIT_RSS);
27007 ++ totalswap = (w != RLIM_INFINITY) ? (w - v) : val->totalswap;
27008 ++
27009 ++ /* currently 'used' swap */
27010 ++ w = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
27011 ++ w -= (w > v) ? v : w;
27012 ++
27013 ++ /* total minus used equals free */
27014 ++ freeswap = (w < totalswap) ? totalswap - w : 0;
27015 ++
27016 ++ val->totalswap = totalswap;
27017 ++ val->freeswap = freeswap;
27018 ++ return;
27019 ++}
27020 ++
27021 ++
27022 ++unsigned long vx_badness(struct task_struct *task, struct mm_struct *mm)
27023 ++{
27024 ++ struct vx_info *vxi = mm->mm_vx_info;
27025 ++ unsigned long points;
27026 ++ rlim_t v, w;
27027 ++
27028 ++ if (!vxi)
27029 ++ return 0;
27030 ++
27031 ++ v = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
27032 ++ w = __rlim_soft(&vxi->limit, RLIMIT_RSS);
27033 ++ points = (v > w) ? (v - w) : 0;
27034 ++
27035 ++ return points;
27036 ++}
27037 ++
27038 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/limit_init.h linux-2.6.22.19-vs2.2.0.7/kernel/vserver/limit_init.h
27039 +--- linux-2.6.22.19/kernel/vserver/limit_init.h 1970-01-01 01:00:00 +0100
27040 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/limit_init.h 2007-10-29 23:34:24 +0100
27041 +@@ -0,0 +1,33 @@
27042 ++
27043 ++
27044 ++static inline void vx_info_init_limit(struct _vx_limit *limit)
27045 ++{
27046 ++ int lim;
27047 ++
27048 ++ for (lim = 0; lim < NUM_LIMITS; lim++) {
27049 ++ __rlim_soft(limit, lim) = RLIM_INFINITY;
27050 ++ __rlim_hard(limit, lim) = RLIM_INFINITY;
27051 ++ __rlim_set(limit, lim, 0);
27052 ++ atomic_set(&__rlim_lhit(limit, lim), 0);
27053 ++ __rlim_rmin(limit, lim) = 0;
27054 ++ __rlim_rmax(limit, lim) = 0;
27055 ++ }
27056 ++}
27057 ++
27058 ++static inline void vx_info_exit_limit(struct _vx_limit *limit)
27059 ++{
27060 ++#ifdef CONFIG_VSERVER_WARN
27061 ++ rlim_t value;
27062 ++ int lim;
27063 ++
27064 ++ for (lim = 0; lim < NUM_LIMITS; lim++) {
27065 ++ if ((1 << lim) & VLIM_NOCHECK)
27066 ++ continue;
27067 ++ value = __rlim_get(limit, lim);
27068 ++ vxwprintk_xid(value,
27069 ++ "!!! limit: %p[%s,%d] = %ld on exit.",
27070 ++ limit, vlimit_name[lim], lim, (long)value);
27071 ++ }
27072 ++#endif
27073 ++}
27074 ++
27075 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/limit_proc.h linux-2.6.22.19-vs2.2.0.7/kernel/vserver/limit_proc.h
27076 +--- linux-2.6.22.19/kernel/vserver/limit_proc.h 1970-01-01 01:00:00 +0100
27077 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/limit_proc.h 2007-06-15 02:37:04 +0200
27078 +@@ -0,0 +1,57 @@
27079 ++#ifndef _VX_LIMIT_PROC_H
27080 ++#define _VX_LIMIT_PROC_H
27081 ++
27082 ++#include <linux/vserver/limit_int.h>
27083 ++
27084 ++
27085 ++#define VX_LIMIT_FMT ":\t%8ld\t%8ld/%8ld\t%8lld/%8lld\t%6d\n"
27086 ++#define VX_LIMIT_TOP \
27087 ++ "Limit\t current\t min/max\t\t soft/hard\t\thits\n"
27088 ++
27089 ++#define VX_LIMIT_ARG(r) \
27090 ++ (unsigned long)__rlim_get(limit, r), \
27091 ++ (unsigned long)__rlim_rmin(limit, r), \
27092 ++ (unsigned long)__rlim_rmax(limit, r), \
27093 ++ VX_VLIM(__rlim_soft(limit, r)), \
27094 ++ VX_VLIM(__rlim_hard(limit, r)), \
27095 ++ atomic_read(&__rlim_lhit(limit, r))
27096 ++
27097 ++static inline int vx_info_proc_limit(struct _vx_limit *limit, char *buffer)
27098 ++{
27099 ++ vx_limit_fixup(limit, -1);
27100 ++ return sprintf(buffer, VX_LIMIT_TOP
27101 ++ "PROC" VX_LIMIT_FMT
27102 ++ "VM" VX_LIMIT_FMT
27103 ++ "VML" VX_LIMIT_FMT
27104 ++ "RSS" VX_LIMIT_FMT
27105 ++ "ANON" VX_LIMIT_FMT
27106 ++ "RMAP" VX_LIMIT_FMT
27107 ++ "FILES" VX_LIMIT_FMT
27108 ++ "OFD" VX_LIMIT_FMT
27109 ++ "LOCKS" VX_LIMIT_FMT
27110 ++ "SOCK" VX_LIMIT_FMT
27111 ++ "MSGQ" VX_LIMIT_FMT
27112 ++ "SHM" VX_LIMIT_FMT
27113 ++ "SEMA" VX_LIMIT_FMT
27114 ++ "SEMS" VX_LIMIT_FMT
27115 ++ "DENT" VX_LIMIT_FMT,
27116 ++ VX_LIMIT_ARG(RLIMIT_NPROC),
27117 ++ VX_LIMIT_ARG(RLIMIT_AS),
27118 ++ VX_LIMIT_ARG(RLIMIT_MEMLOCK),
27119 ++ VX_LIMIT_ARG(RLIMIT_RSS),
27120 ++ VX_LIMIT_ARG(VLIMIT_ANON),
27121 ++ VX_LIMIT_ARG(VLIMIT_MAPPED),
27122 ++ VX_LIMIT_ARG(RLIMIT_NOFILE),
27123 ++ VX_LIMIT_ARG(VLIMIT_OPENFD),
27124 ++ VX_LIMIT_ARG(RLIMIT_LOCKS),
27125 ++ VX_LIMIT_ARG(VLIMIT_NSOCK),
27126 ++ VX_LIMIT_ARG(RLIMIT_MSGQUEUE),
27127 ++ VX_LIMIT_ARG(VLIMIT_SHMEM),
27128 ++ VX_LIMIT_ARG(VLIMIT_SEMARY),
27129 ++ VX_LIMIT_ARG(VLIMIT_NSEMS),
27130 ++ VX_LIMIT_ARG(VLIMIT_DENTRY));
27131 ++}
27132 ++
27133 ++#endif /* _VX_LIMIT_PROC_H */
27134 ++
27135 ++
27136 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/monitor.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/monitor.c
27137 +--- linux-2.6.22.19/kernel/vserver/monitor.c 1970-01-01 01:00:00 +0100
27138 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/monitor.c 2007-06-15 05:59:57 +0200
27139 +@@ -0,0 +1,143 @@
27140 ++/*
27141 ++ * kernel/vserver/monitor.c
27142 ++ *
27143 ++ * Virtual Context Scheduler Monitor
27144 ++ *
27145 ++ * Copyright (C) 2006-2007 Herbert Pötzl
27146 ++ *
27147 ++ * V0.01 basic design
27148 ++ *
27149 ++ */
27150 ++
27151 ++#include <linux/errno.h>
27152 ++#include <linux/module.h>
27153 ++#include <linux/types.h>
27154 ++#include <linux/ctype.h>
27155 ++#include <linux/jiffies.h>
27156 ++
27157 ++#include <asm/uaccess.h>
27158 ++#include <asm/atomic.h>
27159 ++#include <asm/unistd.h>
27160 ++
27161 ++#include <linux/vserver/monitor.h>
27162 ++#include <linux/vserver/debug_cmd.h>
27163 ++
27164 ++
27165 ++#ifdef CONFIG_VSERVER_MONITOR
27166 ++#define VXM_SIZE CONFIG_VSERVER_MONITOR_SIZE
27167 ++#else
27168 ++#define VXM_SIZE 64
27169 ++#endif
27170 ++
27171 ++struct _vx_monitor {
27172 ++ unsigned int counter;
27173 ++
27174 ++ struct _vx_mon_entry entry[VXM_SIZE+1];
27175 ++};
27176 ++
27177 ++
27178 ++DEFINE_PER_CPU(struct _vx_monitor, vx_monitor_buffer);
27179 ++
27180 ++unsigned volatile int vxm_active = 1;
27181 ++
27182 ++static atomic_t sequence = ATOMIC_INIT(0);
27183 ++
27184 ++
27185 ++/* vxm_advance()
27186 ++
27187 ++ * requires disabled preemption */
27188 ++
27189 ++struct _vx_mon_entry *vxm_advance(int cpu)
27190 ++{
27191 ++ struct _vx_monitor *mon = &per_cpu(vx_monitor_buffer, cpu);
27192 ++ struct _vx_mon_entry *entry;
27193 ++ unsigned int index;
27194 ++
27195 ++ index = vxm_active ? (mon->counter++ % VXM_SIZE) : VXM_SIZE;
27196 ++ entry = &mon->entry[index];
27197 ++
27198 ++ entry->ev.seq = atomic_inc_return(&sequence);
27199 ++ entry->ev.jif = jiffies;
27200 ++ return entry;
27201 ++}
27202 ++
27203 ++EXPORT_SYMBOL_GPL(vxm_advance);
27204 ++
27205 ++
27206 ++int do_read_monitor(struct __user _vx_mon_entry *data,
27207 ++ int cpu, uint32_t *index, uint32_t *count)
27208 ++{
27209 ++ int pos, ret = 0;
27210 ++ struct _vx_monitor *mon = &per_cpu(vx_monitor_buffer, cpu);
27211 ++ int end = mon->counter;
27212 ++ int start = end - VXM_SIZE + 2;
27213 ++ int idx = *index;
27214 ++
27215 ++ /* special case: get current pos */
27216 ++ if (!*count) {
27217 ++ *index = end;
27218 ++ return 0;
27219 ++ }
27220 ++
27221 ++ /* have we lost some data? */
27222 ++ if (idx < start)
27223 ++ idx = start;
27224 ++
27225 ++ for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
27226 ++ struct _vx_mon_entry *entry =
27227 ++ &mon->entry[idx % VXM_SIZE];
27228 ++
27229 ++ /* send entry to userspace */
27230 ++ ret = copy_to_user(&data[pos], entry, sizeof(*entry));
27231 ++ if (ret)
27232 ++ break;
27233 ++ }
27234 ++ /* save new index and count */
27235 ++ *index = idx;
27236 ++ *count = pos;
27237 ++ return ret ? ret : (*index < end);
27238 ++}
27239 ++
27240 ++int vc_read_monitor(uint32_t id, void __user *data)
27241 ++{
27242 ++ struct vcmd_read_monitor_v0 vc_data;
27243 ++ int ret;
27244 ++
27245 ++ if (id >= NR_CPUS)
27246 ++ return -EINVAL;
27247 ++
27248 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
27249 ++ return -EFAULT;
27250 ++
27251 ++ ret = do_read_monitor((struct __user _vx_mon_entry *)vc_data.data,
27252 ++ id, &vc_data.index, &vc_data.count);
27253 ++
27254 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
27255 ++ return -EFAULT;
27256 ++ return ret;
27257 ++}
27258 ++
27259 ++#ifdef CONFIG_COMPAT
27260 ++
27261 ++int vc_read_monitor_x32(uint32_t id, void __user *data)
27262 ++{
27263 ++ struct vcmd_read_monitor_v0_x32 vc_data;
27264 ++ int ret;
27265 ++
27266 ++ if (id >= NR_CPUS)
27267 ++ return -EINVAL;
27268 ++
27269 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
27270 ++ return -EFAULT;
27271 ++
27272 ++ ret = do_read_monitor((struct __user _vx_mon_entry *)
27273 ++ compat_ptr(vc_data.data_ptr),
27274 ++ id, &vc_data.index, &vc_data.count);
27275 ++
27276 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
27277 ++ return -EFAULT;
27278 ++ return ret;
27279 ++}
27280 ++
27281 ++#endif /* CONFIG_COMPAT */
27282 ++
27283 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/network.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/network.c
27284 +--- linux-2.6.22.19/kernel/vserver/network.c 1970-01-01 01:00:00 +0100
27285 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/network.c 2007-07-19 07:08:54 +0200
27286 +@@ -0,0 +1,771 @@
27287 ++/*
27288 ++ * linux/kernel/vserver/network.c
27289 ++ *
27290 ++ * Virtual Server: Network Support
27291 ++ *
27292 ++ * Copyright (C) 2003-2007 Herbert Pötzl
27293 ++ *
27294 ++ * V0.01 broken out from vcontext V0.05
27295 ++ * V0.02 cleaned up implementation
27296 ++ * V0.03 added equiv nx commands
27297 ++ * V0.04 switch to RCU based hash
27298 ++ * V0.05 and back to locking again
27299 ++ * V0.06 changed vcmds to nxi arg
27300 ++ * V0.07 have __create claim() the nxi
27301 ++ *
27302 ++ */
27303 ++
27304 ++#include <linux/slab.h>
27305 ++#include <linux/rcupdate.h>
27306 ++#include <net/tcp.h>
27307 ++
27308 ++#include <asm/errno.h>
27309 ++#include <linux/vserver/base.h>
27310 ++#include <linux/vserver/network_cmd.h>
27311 ++
27312 ++
27313 ++atomic_t nx_global_ctotal = ATOMIC_INIT(0);
27314 ++atomic_t nx_global_cactive = ATOMIC_INIT(0);
27315 ++
27316 ++
27317 ++/* __alloc_nx_info()
27318 ++
27319 ++ * allocate an initialized nx_info struct
27320 ++ * doesn't make it visible (hash) */
27321 ++
27322 ++static struct nx_info *__alloc_nx_info(nid_t nid)
27323 ++{
27324 ++ struct nx_info *new = NULL;
27325 ++
27326 ++ vxdprintk(VXD_CBIT(nid, 1), "alloc_nx_info(%d)*", nid);
27327 ++
27328 ++ /* would this benefit from a slab cache? */
27329 ++ new = kmalloc(sizeof(struct nx_info), GFP_KERNEL);
27330 ++ if (!new)
27331 ++ return 0;
27332 ++
27333 ++ memset(new, 0, sizeof(struct nx_info));
27334 ++ new->nx_id = nid;
27335 ++ INIT_HLIST_NODE(&new->nx_hlist);
27336 ++ atomic_set(&new->nx_usecnt, 0);
27337 ++ atomic_set(&new->nx_tasks, 0);
27338 ++ new->nx_state = 0;
27339 ++
27340 ++ new->nx_flags = NXF_INIT_SET;
27341 ++
27342 ++ /* rest of init goes here */
27343 ++
27344 ++ vxdprintk(VXD_CBIT(nid, 0),
27345 ++ "alloc_nx_info(%d) = %p", nid, new);
27346 ++ atomic_inc(&nx_global_ctotal);
27347 ++ return new;
27348 ++}
27349 ++
27350 ++/* __dealloc_nx_info()
27351 ++
27352 ++ * final disposal of nx_info */
27353 ++
27354 ++static void __dealloc_nx_info(struct nx_info *nxi)
27355 ++{
27356 ++ vxdprintk(VXD_CBIT(nid, 0),
27357 ++ "dealloc_nx_info(%p)", nxi);
27358 ++
27359 ++ nxi->nx_hlist.next = LIST_POISON1;
27360 ++ nxi->nx_id = -1;
27361 ++
27362 ++ BUG_ON(atomic_read(&nxi->nx_usecnt));
27363 ++ BUG_ON(atomic_read(&nxi->nx_tasks));
27364 ++
27365 ++ nxi->nx_state |= NXS_RELEASED;
27366 ++ kfree(nxi);
27367 ++ atomic_dec(&nx_global_ctotal);
27368 ++}
27369 ++
27370 ++static void __shutdown_nx_info(struct nx_info *nxi)
27371 ++{
27372 ++ nxi->nx_state |= NXS_SHUTDOWN;
27373 ++ vs_net_change(nxi, VSC_NETDOWN);
27374 ++}
27375 ++
27376 ++/* exported stuff */
27377 ++
27378 ++void free_nx_info(struct nx_info *nxi)
27379 ++{
27380 ++ /* context shutdown is mandatory */
27381 ++ BUG_ON(nxi->nx_state != NXS_SHUTDOWN);
27382 ++
27383 ++ /* context must not be hashed */
27384 ++ BUG_ON(nxi->nx_state & NXS_HASHED);
27385 ++
27386 ++ BUG_ON(atomic_read(&nxi->nx_usecnt));
27387 ++ BUG_ON(atomic_read(&nxi->nx_tasks));
27388 ++
27389 ++ __dealloc_nx_info(nxi);
27390 ++}
27391 ++
27392 ++
27393 ++/* hash table for nx_info hash */
27394 ++
27395 ++#define NX_HASH_SIZE 13
27396 ++
27397 ++struct hlist_head nx_info_hash[NX_HASH_SIZE];
27398 ++
27399 ++static spinlock_t nx_info_hash_lock = SPIN_LOCK_UNLOCKED;
27400 ++
27401 ++
27402 ++static inline unsigned int __hashval(nid_t nid)
27403 ++{
27404 ++ return (nid % NX_HASH_SIZE);
27405 ++}
27406 ++
27407 ++
27408 ++
27409 ++/* __hash_nx_info()
27410 ++
27411 ++ * add the nxi to the global hash table
27412 ++ * requires the hash_lock to be held */
27413 ++
27414 ++static inline void __hash_nx_info(struct nx_info *nxi)
27415 ++{
27416 ++ struct hlist_head *head;
27417 ++
27418 ++ vxd_assert_lock(&nx_info_hash_lock);
27419 ++ vxdprintk(VXD_CBIT(nid, 4),
27420 ++ "__hash_nx_info: %p[#%d]", nxi, nxi->nx_id);
27421 ++
27422 ++ /* context must not be hashed */
27423 ++ BUG_ON(nx_info_state(nxi, NXS_HASHED));
27424 ++
27425 ++ nxi->nx_state |= NXS_HASHED;
27426 ++ head = &nx_info_hash[__hashval(nxi->nx_id)];
27427 ++ hlist_add_head(&nxi->nx_hlist, head);
27428 ++ atomic_inc(&nx_global_cactive);
27429 ++}
27430 ++
27431 ++/* __unhash_nx_info()
27432 ++
27433 ++ * remove the nxi from the global hash table
27434 ++ * requires the hash_lock to be held */
27435 ++
27436 ++static inline void __unhash_nx_info(struct nx_info *nxi)
27437 ++{
27438 ++ vxd_assert_lock(&nx_info_hash_lock);
27439 ++ vxdprintk(VXD_CBIT(nid, 4),
27440 ++ "__unhash_nx_info: %p[#%d.%d.%d]", nxi, nxi->nx_id,
27441 ++ atomic_read(&nxi->nx_usecnt), atomic_read(&nxi->nx_tasks));
27442 ++
27443 ++ /* context must be hashed */
27444 ++ BUG_ON(!nx_info_state(nxi, NXS_HASHED));
27445 ++ /* but without tasks */
27446 ++ BUG_ON(atomic_read(&nxi->nx_tasks));
27447 ++
27448 ++ nxi->nx_state &= ~NXS_HASHED;
27449 ++ hlist_del(&nxi->nx_hlist);
27450 ++ atomic_dec(&nx_global_cactive);
27451 ++}
27452 ++
27453 ++
27454 ++/* __lookup_nx_info()
27455 ++
27456 ++ * requires the hash_lock to be held
27457 ++ * doesn't increment the nx_refcnt */
27458 ++
27459 ++static inline struct nx_info *__lookup_nx_info(nid_t nid)
27460 ++{
27461 ++ struct hlist_head *head = &nx_info_hash[__hashval(nid)];
27462 ++ struct hlist_node *pos;
27463 ++ struct nx_info *nxi;
27464 ++
27465 ++ vxd_assert_lock(&nx_info_hash_lock);
27466 ++ hlist_for_each(pos, head) {
27467 ++ nxi = hlist_entry(pos, struct nx_info, nx_hlist);
27468 ++
27469 ++ if (nxi->nx_id == nid)
27470 ++ goto found;
27471 ++ }
27472 ++ nxi = NULL;
27473 ++found:
27474 ++ vxdprintk(VXD_CBIT(nid, 0),
27475 ++ "__lookup_nx_info(#%u): %p[#%u]",
27476 ++ nid, nxi, nxi ? nxi->nx_id : 0);
27477 ++ return nxi;
27478 ++}
27479 ++
27480 ++
27481 ++/* __nx_dynamic_id()
27482 ++
27483 ++ * find unused dynamic nid
27484 ++ * requires the hash_lock to be held */
27485 ++
27486 ++static inline nid_t __nx_dynamic_id(void)
27487 ++{
27488 ++ static nid_t seq = MAX_N_CONTEXT;
27489 ++ nid_t barrier = seq;
27490 ++
27491 ++ vxd_assert_lock(&nx_info_hash_lock);
27492 ++ do {
27493 ++ if (++seq > MAX_N_CONTEXT)
27494 ++ seq = MIN_D_CONTEXT;
27495 ++ if (!__lookup_nx_info(seq)) {
27496 ++ vxdprintk(VXD_CBIT(nid, 4),
27497 ++ "__nx_dynamic_id: [#%d]", seq);
27498 ++ return seq;
27499 ++ }
27500 ++ } while (barrier != seq);
27501 ++ return 0;
27502 ++}
27503 ++
27504 ++/* __create_nx_info()
27505 ++
27506 ++ * create the requested context
27507 ++ * get(), claim() and hash it */
27508 ++
27509 ++static struct nx_info *__create_nx_info(int id)
27510 ++{
27511 ++ struct nx_info *new, *nxi = NULL;
27512 ++
27513 ++ vxdprintk(VXD_CBIT(nid, 1), "create_nx_info(%d)*", id);
27514 ++
27515 ++ if (!(new = __alloc_nx_info(id)))
27516 ++ return ERR_PTR(-ENOMEM);
27517 ++
27518 ++ /* required to make dynamic xids unique */
27519 ++ spin_lock(&nx_info_hash_lock);
27520 ++
27521 ++ /* dynamic context requested */
27522 ++ if (id == NX_DYNAMIC_ID) {
27523 ++#ifdef CONFIG_VSERVER_DYNAMIC_IDS
27524 ++ id = __nx_dynamic_id();
27525 ++ if (!id) {
27526 ++ printk(KERN_ERR "no dynamic context available.\n");
27527 ++ nxi = ERR_PTR(-EAGAIN);
27528 ++ goto out_unlock;
27529 ++ }
27530 ++ new->nx_id = id;
27531 ++#else
27532 ++ printk(KERN_ERR "dynamic contexts disabled.\n");
27533 ++ nxi = ERR_PTR(-EINVAL);
27534 ++ goto out_unlock;
27535 ++#endif
27536 ++ }
27537 ++ /* static context requested */
27538 ++ else if ((nxi = __lookup_nx_info(id))) {
27539 ++ vxdprintk(VXD_CBIT(nid, 0),
27540 ++ "create_nx_info(%d) = %p (already there)", id, nxi);
27541 ++ if (nx_info_flags(nxi, NXF_STATE_SETUP, 0))
27542 ++ nxi = ERR_PTR(-EBUSY);
27543 ++ else
27544 ++ nxi = ERR_PTR(-EEXIST);
27545 ++ goto out_unlock;
27546 ++ }
27547 ++ /* dynamic nid creation blocker */
27548 ++ else if (id >= MIN_D_CONTEXT) {
27549 ++ vxdprintk(VXD_CBIT(nid, 0),
27550 ++ "create_nx_info(%d) (dynamic rejected)", id);
27551 ++ nxi = ERR_PTR(-EINVAL);
27552 ++ goto out_unlock;
27553 ++ }
27554 ++
27555 ++ /* new context */
27556 ++ vxdprintk(VXD_CBIT(nid, 0),
27557 ++ "create_nx_info(%d) = %p (new)", id, new);
27558 ++ claim_nx_info(new, NULL);
27559 ++ __hash_nx_info(get_nx_info(new));
27560 ++ nxi = new, new = NULL;
27561 ++
27562 ++out_unlock:
27563 ++ spin_unlock(&nx_info_hash_lock);
27564 ++ if (new)
27565 ++ __dealloc_nx_info(new);
27566 ++ return nxi;
27567 ++}
27568 ++
27569 ++
27570 ++
27571 ++/* exported stuff */
27572 ++
27573 ++
27574 ++void unhash_nx_info(struct nx_info *nxi)
27575 ++{
27576 ++ __shutdown_nx_info(nxi);
27577 ++ spin_lock(&nx_info_hash_lock);
27578 ++ __unhash_nx_info(nxi);
27579 ++ spin_unlock(&nx_info_hash_lock);
27580 ++}
27581 ++
27582 ++#ifdef CONFIG_VSERVER_LEGACYNET
27583 ++
27584 ++struct nx_info *create_nx_info(void)
27585 ++{
27586 ++ return __create_nx_info(NX_DYNAMIC_ID);
27587 ++}
27588 ++
27589 ++#endif
27590 ++
27591 ++/* lookup_nx_info()
27592 ++
27593 ++ * search for a nx_info and get() it
27594 ++ * negative id means current */
27595 ++
27596 ++struct nx_info *lookup_nx_info(int id)
27597 ++{
27598 ++ struct nx_info *nxi = NULL;
27599 ++
27600 ++ if (id < 0) {
27601 ++ nxi = get_nx_info(current->nx_info);
27602 ++ } else if (id > 1) {
27603 ++ spin_lock(&nx_info_hash_lock);
27604 ++ nxi = get_nx_info(__lookup_nx_info(id));
27605 ++ spin_unlock(&nx_info_hash_lock);
27606 ++ }
27607 ++ return nxi;
27608 ++}
27609 ++
27610 ++/* nid_is_hashed()
27611 ++
27612 ++ * verify that nid is still hashed */
27613 ++
27614 ++int nid_is_hashed(nid_t nid)
27615 ++{
27616 ++ int hashed;
27617 ++
27618 ++ spin_lock(&nx_info_hash_lock);
27619 ++ hashed = (__lookup_nx_info(nid) != NULL);
27620 ++ spin_unlock(&nx_info_hash_lock);
27621 ++ return hashed;
27622 ++}
27623 ++
27624 ++
27625 ++#ifdef CONFIG_PROC_FS
27626 ++
27627 ++/* get_nid_list()
27628 ++
27629 ++ * get a subset of hashed nids for proc
27630 ++ * assumes size is at least one */
27631 ++
27632 ++int get_nid_list(int index, unsigned int *nids, int size)
27633 ++{
27634 ++ int hindex, nr_nids = 0;
27635 ++
27636 ++ /* only show current and children */
27637 ++ if (!nx_check(0, VS_ADMIN | VS_WATCH)) {
27638 ++ if (index > 0)
27639 ++ return 0;
27640 ++ nids[nr_nids] = nx_current_nid();
27641 ++ return 1;
27642 ++ }
27643 ++
27644 ++ for (hindex = 0; hindex < NX_HASH_SIZE; hindex++) {
27645 ++ struct hlist_head *head = &nx_info_hash[hindex];
27646 ++ struct hlist_node *pos;
27647 ++
27648 ++ spin_lock(&nx_info_hash_lock);
27649 ++ hlist_for_each(pos, head) {
27650 ++ struct nx_info *nxi;
27651 ++
27652 ++ if (--index > 0)
27653 ++ continue;
27654 ++
27655 ++ nxi = hlist_entry(pos, struct nx_info, nx_hlist);
27656 ++ nids[nr_nids] = nxi->nx_id;
27657 ++ if (++nr_nids >= size) {
27658 ++ spin_unlock(&nx_info_hash_lock);
27659 ++ goto out;
27660 ++ }
27661 ++ }
27662 ++ /* keep the lock time short */
27663 ++ spin_unlock(&nx_info_hash_lock);
27664 ++ }
27665 ++out:
27666 ++ return nr_nids;
27667 ++}
27668 ++#endif
27669 ++
27670 ++
27671 ++/*
27672 ++ * migrate task to new network
27673 ++ * gets nxi, puts old_nxi on change
27674 ++ */
27675 ++
27676 ++int nx_migrate_task(struct task_struct *p, struct nx_info *nxi)
27677 ++{
27678 ++ struct nx_info *old_nxi;
27679 ++ int ret = 0;
27680 ++
27681 ++ if (!p || !nxi)
27682 ++ BUG();
27683 ++
27684 ++ vxdprintk(VXD_CBIT(nid, 5),
27685 ++ "nx_migrate_task(%p,%p[#%d.%d.%d])",
27686 ++ p, nxi, nxi->nx_id,
27687 ++ atomic_read(&nxi->nx_usecnt),
27688 ++ atomic_read(&nxi->nx_tasks));
27689 ++
27690 ++ if (nx_info_flags(nxi, NXF_INFO_PRIVATE, 0) &&
27691 ++ !nx_info_flags(nxi, NXF_STATE_SETUP, 0))
27692 ++ return -EACCES;
27693 ++
27694 ++ if (nx_info_state(nxi, NXS_SHUTDOWN))
27695 ++ return -EFAULT;
27696 ++
27697 ++ /* maybe disallow this completely? */
27698 ++ old_nxi = task_get_nx_info(p);
27699 ++ if (old_nxi == nxi)
27700 ++ goto out;
27701 ++
27702 ++ task_lock(p);
27703 ++ if (old_nxi)
27704 ++ clr_nx_info(&p->nx_info);
27705 ++ claim_nx_info(nxi, p);
27706 ++ set_nx_info(&p->nx_info, nxi);
27707 ++ p->nid = nxi->nx_id;
27708 ++ task_unlock(p);
27709 ++
27710 ++ vxdprintk(VXD_CBIT(nid, 5),
27711 ++ "moved task %p into nxi:%p[#%d]",
27712 ++ p, nxi, nxi->nx_id);
27713 ++
27714 ++ if (old_nxi)
27715 ++ release_nx_info(old_nxi, p);
27716 ++ ret = 0;
27717 ++out:
27718 ++ put_nx_info(old_nxi);
27719 ++ return ret;
27720 ++}
27721 ++
27722 ++
27723 ++#ifdef CONFIG_INET
27724 ++
27725 ++#include <linux/netdevice.h>
27726 ++#include <linux/inetdevice.h>
27727 ++
27728 ++int ifa_in_nx_info(struct in_ifaddr *ifa, struct nx_info *nxi)
27729 ++{
27730 ++ if (!nxi)
27731 ++ return 1;
27732 ++ if (!ifa)
27733 ++ return 0;
27734 ++ return addr_in_nx_info(nxi, ifa->ifa_local);
27735 ++}
27736 ++
27737 ++int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
27738 ++{
27739 ++ struct in_device *in_dev;
27740 ++ struct in_ifaddr **ifap;
27741 ++ struct in_ifaddr *ifa;
27742 ++ int ret = 0;
27743 ++
27744 ++ if (!nxi)
27745 ++ return 1;
27746 ++
27747 ++ if (!dev)
27748 ++ goto out;
27749 ++ in_dev = in_dev_get(dev);
27750 ++ if (!in_dev)
27751 ++ goto out;
27752 ++
27753 ++ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
27754 ++ ifap = &ifa->ifa_next) {
27755 ++ if (addr_in_nx_info(nxi, ifa->ifa_local)) {
27756 ++ ret = 1;
27757 ++ break;
27758 ++ }
27759 ++ }
27760 ++ in_dev_put(in_dev);
27761 ++out:
27762 ++ return ret;
27763 ++}
27764 ++
27765 ++/*
27766 ++ * check if address is covered by socket
27767 ++ *
27768 ++ * sk: the socket to check against
27769 ++ * addr: the address in question (must be != 0)
27770 ++ */
27771 ++static inline int __addr_in_socket(const struct sock *sk, uint32_t addr)
27772 ++{
27773 ++ struct nx_info *nxi = sk->sk_nx_info;
27774 ++ uint32_t saddr = inet_rcv_saddr(sk);
27775 ++
27776 ++ vxdprintk(VXD_CBIT(net, 5),
27777 ++ "__addr_in_socket(%p," NIPQUAD_FMT ") %p:" NIPQUAD_FMT " %p;%lx",
27778 ++ sk, NIPQUAD(addr), nxi, NIPQUAD(saddr), sk->sk_socket,
27779 ++ (sk->sk_socket ? sk->sk_socket->flags : 0));
27780 ++
27781 ++ if (saddr) {
27782 ++ /* direct address match */
27783 ++ return (saddr == addr);
27784 ++ } else if (nxi) {
27785 ++ /* match against nx_info */
27786 ++ return addr_in_nx_info(nxi, addr);
27787 ++ } else {
27788 ++ /* unrestricted any socket */
27789 ++ return 1;
27790 ++ }
27791 ++}
27792 ++
27793 ++
27794 ++int nx_addr_conflict(struct nx_info *nxi, uint32_t addr, const struct sock *sk)
27795 ++{
27796 ++ vxdprintk(VXD_CBIT(net, 2),
27797 ++ "nx_addr_conflict(%p,%p) " NIPQUAD_FMT,
27798 ++ nxi, sk, NIPQUAD(addr));
27799 ++
27800 ++ if (addr) {
27801 ++ /* check real address */
27802 ++ return __addr_in_socket(sk, addr);
27803 ++ } else if (nxi) {
27804 ++ /* check against nx_info */
27805 ++ int i, n = nxi->nbipv4;
27806 ++
27807 ++ for (i = 0; i < n; i++)
27808 ++ if (__addr_in_socket(sk, nxi->ipv4[i]))
27809 ++ return 1;
27810 ++ return 0;
27811 ++ } else {
27812 ++ /* check against any */
27813 ++ return 1;
27814 ++ }
27815 ++}
27816 ++
27817 ++#endif /* CONFIG_INET */
27818 ++
27819 ++void nx_set_persistent(struct nx_info *nxi)
27820 ++{
27821 ++ vxdprintk(VXD_CBIT(nid, 6),
27822 ++ "nx_set_persistent(%p[#%d])", nxi, nxi->nx_id);
27823 ++
27824 ++ get_nx_info(nxi);
27825 ++ claim_nx_info(nxi, NULL);
27826 ++}
27827 ++
27828 ++void nx_clear_persistent(struct nx_info *nxi)
27829 ++{
27830 ++ vxdprintk(VXD_CBIT(nid, 6),
27831 ++ "nx_clear_persistent(%p[#%d])", nxi, nxi->nx_id);
27832 ++
27833 ++ release_nx_info(nxi, NULL);
27834 ++ put_nx_info(nxi);
27835 ++}
27836 ++
27837 ++void nx_update_persistent(struct nx_info *nxi)
27838 ++{
27839 ++ if (nx_info_flags(nxi, NXF_PERSISTENT, 0))
27840 ++ nx_set_persistent(nxi);
27841 ++ else
27842 ++ nx_clear_persistent(nxi);
27843 ++}
27844 ++
27845 ++/* vserver syscall commands below here */
27846 ++
27847 ++/* taks nid and nx_info functions */
27848 ++
27849 ++#include <asm/uaccess.h>
27850 ++
27851 ++
27852 ++int vc_task_nid(uint32_t id, void __user *data)
27853 ++{
27854 ++ nid_t nid;
27855 ++
27856 ++ if (id) {
27857 ++ struct task_struct *tsk;
27858 ++
27859 ++ if (!nx_check(0, VS_ADMIN | VS_WATCH))
27860 ++ return -EPERM;
27861 ++
27862 ++ read_lock(&tasklist_lock);
27863 ++ tsk = find_task_by_real_pid(id);
27864 ++ nid = (tsk) ? tsk->nid : -ESRCH;
27865 ++ read_unlock(&tasklist_lock);
27866 ++ } else
27867 ++ nid = nx_current_nid();
27868 ++ return nid;
27869 ++}
27870 ++
27871 ++
27872 ++int vc_nx_info(struct nx_info *nxi, void __user *data)
27873 ++{
27874 ++ struct vcmd_nx_info_v0 vc_data;
27875 ++
27876 ++ vc_data.nid = nxi->nx_id;
27877 ++
27878 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
27879 ++ return -EFAULT;
27880 ++ return 0;
27881 ++}
27882 ++
27883 ++
27884 ++/* network functions */
27885 ++
27886 ++int vc_net_create(uint32_t nid, void __user *data)
27887 ++{
27888 ++ struct vcmd_net_create vc_data = { .flagword = NXF_INIT_SET };
27889 ++ struct nx_info *new_nxi;
27890 ++ int ret;
27891 ++
27892 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
27893 ++ return -EFAULT;
27894 ++
27895 ++ if ((nid > MAX_S_CONTEXT) && (nid != NX_DYNAMIC_ID))
27896 ++ return -EINVAL;
27897 ++ if (nid < 2)
27898 ++ return -EINVAL;
27899 ++
27900 ++ new_nxi = __create_nx_info(nid);
27901 ++ if (IS_ERR(new_nxi))
27902 ++ return PTR_ERR(new_nxi);
27903 ++
27904 ++ /* initial flags */
27905 ++ new_nxi->nx_flags = vc_data.flagword;
27906 ++
27907 ++ ret = -ENOEXEC;
27908 ++ if (vs_net_change(new_nxi, VSC_NETUP))
27909 ++ goto out;
27910 ++
27911 ++ ret = nx_migrate_task(current, new_nxi);
27912 ++ if (ret)
27913 ++ goto out;
27914 ++
27915 ++ /* return context id on success */
27916 ++ ret = new_nxi->nx_id;
27917 ++
27918 ++ /* get a reference for persistent contexts */
27919 ++ if ((vc_data.flagword & NXF_PERSISTENT))
27920 ++ nx_set_persistent(new_nxi);
27921 ++out:
27922 ++ release_nx_info(new_nxi, NULL);
27923 ++ put_nx_info(new_nxi);
27924 ++ return ret;
27925 ++}
27926 ++
27927 ++
27928 ++int vc_net_migrate(struct nx_info *nxi, void __user *data)
27929 ++{
27930 ++ return nx_migrate_task(current, nxi);
27931 ++}
27932 ++
27933 ++int vc_net_add(struct nx_info *nxi, void __user *data)
27934 ++{
27935 ++ struct vcmd_net_addr_v0 vc_data;
27936 ++ int index, pos, ret = 0;
27937 ++
27938 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
27939 ++ return -EFAULT;
27940 ++
27941 ++ switch (vc_data.type) {
27942 ++ case NXA_TYPE_IPV4:
27943 ++ if ((vc_data.count < 1) || (vc_data.count > 4))
27944 ++ return -EINVAL;
27945 ++ break;
27946 ++
27947 ++ default:
27948 ++ break;
27949 ++ }
27950 ++
27951 ++ switch (vc_data.type) {
27952 ++ case NXA_TYPE_IPV4:
27953 ++ index = 0;
27954 ++ while ((index < vc_data.count) &&
27955 ++ ((pos = nxi->nbipv4) < NB_IPV4ROOT)) {
27956 ++ nxi->ipv4[pos] = vc_data.ip[index];
27957 ++ nxi->mask[pos] = vc_data.mask[index];
27958 ++ index++;
27959 ++ nxi->nbipv4++;
27960 ++ }
27961 ++ ret = index;
27962 ++ break;
27963 ++
27964 ++ case NXA_TYPE_IPV4|NXA_MOD_BCAST:
27965 ++ nxi->v4_bcast = vc_data.ip[0];
27966 ++ ret = 1;
27967 ++ break;
27968 ++
27969 ++ default:
27970 ++ ret = -EINVAL;
27971 ++ break;
27972 ++ }
27973 ++ return ret;
27974 ++}
27975 ++
27976 ++int vc_net_remove(struct nx_info *nxi, void __user *data)
27977 ++{
27978 ++ struct vcmd_net_addr_v0 vc_data;
27979 ++
27980 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
27981 ++ return -EFAULT;
27982 ++
27983 ++ switch (vc_data.type) {
27984 ++ case NXA_TYPE_ANY:
27985 ++ nxi->nbipv4 = 0;
27986 ++ break;
27987 ++
27988 ++ default:
27989 ++ return -EINVAL;
27990 ++ }
27991 ++ return 0;
27992 ++}
27993 ++
27994 ++int vc_get_nflags(struct nx_info *nxi, void __user *data)
27995 ++{
27996 ++ struct vcmd_net_flags_v0 vc_data;
27997 ++
27998 ++ vc_data.flagword = nxi->nx_flags;
27999 ++
28000 ++ /* special STATE flag handling */
28001 ++ vc_data.mask = vs_mask_flags(~0ULL, nxi->nx_flags, NXF_ONE_TIME);
28002 ++
28003 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
28004 ++ return -EFAULT;
28005 ++ return 0;
28006 ++}
28007 ++
28008 ++int vc_set_nflags(struct nx_info *nxi, void __user *data)
28009 ++{
28010 ++ struct vcmd_net_flags_v0 vc_data;
28011 ++ uint64_t mask, trigger;
28012 ++
28013 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
28014 ++ return -EFAULT;
28015 ++
28016 ++ /* special STATE flag handling */
28017 ++ mask = vs_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME);
28018 ++ trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword);
28019 ++
28020 ++ nxi->nx_flags = vs_mask_flags(nxi->nx_flags,
28021 ++ vc_data.flagword, mask);
28022 ++ if (trigger & NXF_PERSISTENT)
28023 ++ nx_update_persistent(nxi);
28024 ++
28025 ++ return 0;
28026 ++}
28027 ++
28028 ++int vc_get_ncaps(struct nx_info *nxi, void __user *data)
28029 ++{
28030 ++ struct vcmd_net_caps_v0 vc_data;
28031 ++
28032 ++ vc_data.ncaps = nxi->nx_ncaps;
28033 ++ vc_data.cmask = ~0ULL;
28034 ++
28035 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
28036 ++ return -EFAULT;
28037 ++ return 0;
28038 ++}
28039 ++
28040 ++int vc_set_ncaps(struct nx_info *nxi, void __user *data)
28041 ++{
28042 ++ struct vcmd_net_caps_v0 vc_data;
28043 ++
28044 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
28045 ++ return -EFAULT;
28046 ++
28047 ++ nxi->nx_ncaps = vs_mask_flags(nxi->nx_ncaps,
28048 ++ vc_data.ncaps, vc_data.cmask);
28049 ++ return 0;
28050 ++}
28051 ++
28052 ++
28053 ++#include <linux/module.h>
28054 ++
28055 ++EXPORT_SYMBOL_GPL(free_nx_info);
28056 ++EXPORT_SYMBOL_GPL(unhash_nx_info);
28057 ++
28058 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/proc.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/proc.c
28059 +--- linux-2.6.22.19/kernel/vserver/proc.c 1970-01-01 01:00:00 +0100
28060 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/proc.c 2007-06-15 19:20:10 +0200
28061 +@@ -0,0 +1,1033 @@
28062 ++/*
28063 ++ * linux/kernel/vserver/proc.c
28064 ++ *
28065 ++ * Virtual Context Support
28066 ++ *
28067 ++ * Copyright (C) 2003-2007 Herbert Pötzl
28068 ++ *
28069 ++ * V0.01 basic structure
28070 ++ * V0.02 adaptation vs1.3.0
28071 ++ * V0.03 proc permissions
28072 ++ * V0.04 locking/generic
28073 ++ * V0.05 next generation procfs
28074 ++ * V0.06 inode validation
28075 ++ * V0.07 generic rewrite vid
28076 ++ * V0.08 remove inode type
28077 ++ *
28078 ++ */
28079 ++
28080 ++#include <linux/errno.h>
28081 ++#include <linux/proc_fs.h>
28082 ++#include <linux/sched.h>
28083 ++#include <linux/vs_context.h>
28084 ++#include <linux/vs_network.h>
28085 ++#include <linux/vs_cvirt.h>
28086 ++
28087 ++#include <linux/vserver/switch.h>
28088 ++#include <linux/vserver/global.h>
28089 ++
28090 ++#include <asm/uaccess.h>
28091 ++#include <asm/unistd.h>
28092 ++
28093 ++#include "cvirt_proc.h"
28094 ++#include "cacct_proc.h"
28095 ++#include "limit_proc.h"
28096 ++#include "sched_proc.h"
28097 ++#include "vci_config.h"
28098 ++
28099 ++static struct proc_dir_entry *proc_virtual;
28100 ++
28101 ++static struct proc_dir_entry *proc_virtnet;
28102 ++
28103 ++
28104 ++/* first the actual feeds */
28105 ++
28106 ++
28107 ++static int proc_vci(char *buffer)
28108 ++{
28109 ++ return sprintf(buffer,
28110 ++ "VCIVersion:\t%04x:%04x\n"
28111 ++ "VCISyscall:\t%d\n"
28112 ++ "VCIKernel:\t%08x\n",
28113 ++ VCI_VERSION >> 16,
28114 ++ VCI_VERSION & 0xFFFF,
28115 ++ __NR_vserver,
28116 ++ vci_kernel_config());
28117 ++}
28118 ++
28119 ++static int proc_virtual_info(char *buffer)
28120 ++{
28121 ++ return proc_vci(buffer);
28122 ++}
28123 ++
28124 ++static int proc_virtual_status(char *buffer)
28125 ++{
28126 ++ return sprintf(buffer,
28127 ++ "#CTotal:\t%d\n"
28128 ++ "#CActive:\t%d\n"
28129 ++ "#NSProxy:\t%d\t%d %d %d %d\n",
28130 ++ atomic_read(&vx_global_ctotal),
28131 ++ atomic_read(&vx_global_cactive),
28132 ++ atomic_read(&vs_global_nsproxy),
28133 ++ atomic_read(&vs_global_fs),
28134 ++ atomic_read(&vs_global_mnt_ns),
28135 ++ atomic_read(&vs_global_uts_ns),
28136 ++ atomic_read(&vs_global_ipc_ns));
28137 ++}
28138 ++
28139 ++
28140 ++int proc_vxi_info(struct vx_info *vxi, char *buffer)
28141 ++{
28142 ++ int length;
28143 ++
28144 ++ length = sprintf(buffer,
28145 ++ "ID:\t%d\n"
28146 ++ "Info:\t%p\n"
28147 ++ "Init:\t%d\n",
28148 ++ vxi->vx_id,
28149 ++ vxi,
28150 ++ vxi->vx_initpid);
28151 ++ return length;
28152 ++}
28153 ++
28154 ++int proc_vxi_status(struct vx_info *vxi, char *buffer)
28155 ++{
28156 ++ int length;
28157 ++
28158 ++ length = sprintf(buffer,
28159 ++ "UseCnt:\t%d\n"
28160 ++ "Tasks:\t%d\n"
28161 ++ "Flags:\t%016llx\n"
28162 ++ "BCaps:\t%016llx\n"
28163 ++ "CCaps:\t%016llx\n"
28164 ++ "Spaces:\t%08lx\n",
28165 ++ atomic_read(&vxi->vx_usecnt),
28166 ++ atomic_read(&vxi->vx_tasks),
28167 ++ (unsigned long long)vxi->vx_flags,
28168 ++ (unsigned long long)vxi->vx_bcaps,
28169 ++ (unsigned long long)vxi->vx_ccaps,
28170 ++ vxi->vx_nsmask);
28171 ++ return length;
28172 ++}
28173 ++
28174 ++int proc_vxi_limit(struct vx_info *vxi, char *buffer)
28175 ++{
28176 ++ return vx_info_proc_limit(&vxi->limit, buffer);
28177 ++}
28178 ++
28179 ++int proc_vxi_sched(struct vx_info *vxi, char *buffer)
28180 ++{
28181 ++ int cpu, length;
28182 ++
28183 ++ length = vx_info_proc_sched(&vxi->sched, buffer);
28184 ++ for_each_online_cpu(cpu) {
28185 ++ length += vx_info_proc_sched_pc(
28186 ++ &vx_per_cpu(vxi, sched_pc, cpu),
28187 ++ buffer + length, cpu);
28188 ++ }
28189 ++ return length;
28190 ++}
28191 ++
28192 ++int proc_vxi_nsproxy(struct vx_info *vxi, char *buffer)
28193 ++{
28194 ++ return vx_info_proc_nsproxy(vxi->vx_nsproxy, buffer);
28195 ++}
28196 ++
28197 ++int proc_vxi_cvirt(struct vx_info *vxi, char *buffer)
28198 ++{
28199 ++ int cpu, length;
28200 ++
28201 ++ vx_update_load(vxi);
28202 ++ length = vx_info_proc_cvirt(&vxi->cvirt, buffer);
28203 ++ for_each_online_cpu(cpu) {
28204 ++ length += vx_info_proc_cvirt_pc(
28205 ++ &vx_per_cpu(vxi, cvirt_pc, cpu),
28206 ++ buffer + length, cpu);
28207 ++ }
28208 ++ return length;
28209 ++}
28210 ++
28211 ++int proc_vxi_cacct(struct vx_info *vxi, char *buffer)
28212 ++{
28213 ++ return vx_info_proc_cacct(&vxi->cacct, buffer);
28214 ++}
28215 ++
28216 ++
28217 ++static int proc_virtnet_info(char *buffer)
28218 ++{
28219 ++ return proc_vci(buffer);
28220 ++}
28221 ++
28222 ++static int proc_virtnet_status(char *buffer)
28223 ++{
28224 ++ return sprintf(buffer,
28225 ++ "#CTotal:\t%d\n"
28226 ++ "#CActive:\t%d\n",
28227 ++ atomic_read(&nx_global_ctotal),
28228 ++ atomic_read(&nx_global_cactive));
28229 ++}
28230 ++
28231 ++int proc_nxi_info(struct nx_info *nxi, char *buffer)
28232 ++{
28233 ++ int length, i;
28234 ++
28235 ++ length = sprintf(buffer,
28236 ++ "ID:\t%d\n"
28237 ++ "Info:\t%p\n",
28238 ++ nxi->nx_id,
28239 ++ nxi);
28240 ++ for (i = 0; i < nxi->nbipv4; i++) {
28241 ++ length += sprintf(buffer + length,
28242 ++ "%d:\t" NIPQUAD_FMT "/" NIPQUAD_FMT "\n", i,
28243 ++ NIPQUAD(nxi->ipv4[i]), NIPQUAD(nxi->mask[i]));
28244 ++ }
28245 ++ return length;
28246 ++}
28247 ++
28248 ++int proc_nxi_status(struct nx_info *nxi, char *buffer)
28249 ++{
28250 ++ int length;
28251 ++
28252 ++ length = sprintf(buffer,
28253 ++ "UseCnt:\t%d\n"
28254 ++ "Tasks:\t%d\n"
28255 ++ "Flags:\t%016llx\n"
28256 ++ "NCaps:\t%016llx\n",
28257 ++ atomic_read(&nxi->nx_usecnt),
28258 ++ atomic_read(&nxi->nx_tasks),
28259 ++ (unsigned long long)nxi->nx_flags,
28260 ++ (unsigned long long)nxi->nx_ncaps);
28261 ++ return length;
28262 ++}
28263 ++
28264 ++
28265 ++
28266 ++/* here the inode helpers */
28267 ++
28268 ++struct vs_entry {
28269 ++ int len;
28270 ++ char *name;
28271 ++ mode_t mode;
28272 ++ struct inode_operations *iop;
28273 ++ struct file_operations *fop;
28274 ++ union proc_op op;
28275 ++};
28276 ++
28277 ++static struct inode *vs_proc_make_inode(struct super_block *sb, struct vs_entry *p)
28278 ++{
28279 ++ struct inode *inode = new_inode(sb);
28280 ++
28281 ++ if (!inode)
28282 ++ goto out;
28283 ++
28284 ++ inode->i_mode = p->mode;
28285 ++ if (p->iop)
28286 ++ inode->i_op = p->iop;
28287 ++ if (p->fop)
28288 ++ inode->i_fop = p->fop;
28289 ++
28290 ++ inode->i_nlink = (p->mode & S_IFDIR) ? 2 : 1;
28291 ++ inode->i_flags |= S_IMMUTABLE;
28292 ++
28293 ++ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
28294 ++
28295 ++ inode->i_uid = 0;
28296 ++ inode->i_gid = 0;
28297 ++ inode->i_tag = 0;
28298 ++out:
28299 ++ return inode;
28300 ++}
28301 ++
28302 ++static struct dentry *vs_proc_instantiate(struct inode *dir,
28303 ++ struct dentry *dentry, int id, void *ptr)
28304 ++{
28305 ++ struct vs_entry *p = ptr;
28306 ++ struct inode *inode = vs_proc_make_inode(dir->i_sb, p);
28307 ++ struct dentry *error = ERR_PTR(-EINVAL);
28308 ++
28309 ++ if (!inode)
28310 ++ goto out;
28311 ++
28312 ++ PROC_I(inode)->op = p->op;
28313 ++ PROC_I(inode)->fd = id;
28314 ++ d_add(dentry, inode);
28315 ++ error = NULL;
28316 ++out:
28317 ++ return error;
28318 ++}
28319 ++
28320 ++/* Lookups */
28321 ++
28322 ++typedef struct dentry *instantiate_t(struct inode *, struct dentry *, int, void *);
28323 ++
28324 ++/*
28325 ++ * Fill a directory entry.
28326 ++ *
28327 ++ * If possible create the dcache entry and derive our inode number and
28328 ++ * file type from dcache entry.
28329 ++ *
28330 ++ * Since all of the proc inode numbers are dynamically generated, the inode
28331 ++ * numbers do not exist until the inode is cache. This means creating the
28332 ++ * the dcache entry in readdir is necessary to keep the inode numbers
28333 ++ * reported by readdir in sync with the inode numbers reported
28334 ++ * by stat.
28335 ++ */
28336 ++static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
28337 ++ char *name, int len, instantiate_t instantiate, int id, void *ptr)
28338 ++{
28339 ++ struct dentry *child, *dir = filp->f_dentry;
28340 ++ struct inode *inode;
28341 ++ struct qstr qname;
28342 ++ ino_t ino = 0;
28343 ++ unsigned type = DT_UNKNOWN;
28344 ++
28345 ++ qname.name = name;
28346 ++ qname.len = len;
28347 ++ qname.hash = full_name_hash(name, len);
28348 ++
28349 ++ child = d_lookup(dir, &qname);
28350 ++ if (!child) {
28351 ++ struct dentry *new;
28352 ++ new = d_alloc(dir, &qname);
28353 ++ if (new) {
28354 ++ child = instantiate(dir->d_inode, new, id, ptr);
28355 ++ if (child)
28356 ++ dput(new);
28357 ++ else
28358 ++ child = new;
28359 ++ }
28360 ++ }
28361 ++ if (!child || IS_ERR(child) || !child->d_inode)
28362 ++ goto end_instantiate;
28363 ++ inode = child->d_inode;
28364 ++ if (inode) {
28365 ++ ino = inode->i_ino;
28366 ++ type = inode->i_mode >> 12;
28367 ++ }
28368 ++ dput(child);
28369 ++end_instantiate:
28370 ++ if (!ino)
28371 ++ ino = find_inode_number(dir, &qname);
28372 ++ if (!ino)
28373 ++ ino = 1;
28374 ++ return filldir(dirent, name, len, filp->f_pos, ino, type);
28375 ++}
28376 ++
28377 ++
28378 ++
28379 ++/* get and revalidate vx_info/xid */
28380 ++
28381 ++static inline
28382 ++struct vx_info *get_proc_vx_info(struct inode *inode)
28383 ++{
28384 ++ return lookup_vx_info(PROC_I(inode)->fd);
28385 ++}
28386 ++
28387 ++static int proc_xid_revalidate(struct dentry *dentry, struct nameidata *nd)
28388 ++{
28389 ++ struct inode *inode = dentry->d_inode;
28390 ++ xid_t xid = PROC_I(inode)->fd;
28391 ++
28392 ++ if (!xid || xid_is_hashed(xid))
28393 ++ return 1;
28394 ++ d_drop(dentry);
28395 ++ return 0;
28396 ++}
28397 ++
28398 ++
28399 ++/* get and revalidate nx_info/nid */
28400 ++
28401 ++static int proc_nid_revalidate(struct dentry *dentry, struct nameidata *nd)
28402 ++{
28403 ++ struct inode *inode = dentry->d_inode;
28404 ++ nid_t nid = PROC_I(inode)->fd;
28405 ++
28406 ++ if (!nid || nid_is_hashed(nid))
28407 ++ return 1;
28408 ++ d_drop(dentry);
28409 ++ return 0;
28410 ++}
28411 ++
28412 ++
28413 ++
28414 ++#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
28415 ++
28416 ++static ssize_t proc_vs_info_read(struct file *file, char __user *buf,
28417 ++ size_t count, loff_t *ppos)
28418 ++{
28419 ++ struct inode *inode = file->f_dentry->d_inode;
28420 ++ unsigned long page;
28421 ++ ssize_t length = 0;
28422 ++
28423 ++ if (count > PROC_BLOCK_SIZE)
28424 ++ count = PROC_BLOCK_SIZE;
28425 ++
28426 ++ /* fade that out as soon as stable */
28427 ++ WARN_ON(PROC_I(inode)->fd);
28428 ++
28429 ++ if (!(page = __get_free_page(GFP_KERNEL)))
28430 ++ return -ENOMEM;
28431 ++
28432 ++ BUG_ON(!PROC_I(inode)->op.proc_vs_read);
28433 ++ length = PROC_I(inode)->op.proc_vs_read((char *)page);
28434 ++
28435 ++ if (length >= 0)
28436 ++ length = simple_read_from_buffer(buf, count, ppos,
28437 ++ (char *)page, length);
28438 ++
28439 ++ free_page(page);
28440 ++ return length;
28441 ++}
28442 ++
28443 ++static ssize_t proc_vx_info_read(struct file *file, char __user *buf,
28444 ++ size_t count, loff_t *ppos)
28445 ++{
28446 ++ struct inode *inode = file->f_dentry->d_inode;
28447 ++ struct vx_info *vxi = NULL;
28448 ++ xid_t xid = PROC_I(inode)->fd;
28449 ++ unsigned long page;
28450 ++ ssize_t length = 0;
28451 ++
28452 ++ if (count > PROC_BLOCK_SIZE)
28453 ++ count = PROC_BLOCK_SIZE;
28454 ++
28455 ++ /* fade that out as soon as stable */
28456 ++ WARN_ON(!xid);
28457 ++ vxi = lookup_vx_info(xid);
28458 ++ if (!vxi)
28459 ++ goto out;
28460 ++
28461 ++ length = -ENOMEM;
28462 ++ if (!(page = __get_free_page(GFP_KERNEL)))
28463 ++ goto out_put;
28464 ++
28465 ++ BUG_ON(!PROC_I(inode)->op.proc_vxi_read);
28466 ++ length = PROC_I(inode)->op.proc_vxi_read(vxi, (char *)page);
28467 ++
28468 ++ if (length >= 0)
28469 ++ length = simple_read_from_buffer(buf, count, ppos,
28470 ++ (char *)page, length);
28471 ++
28472 ++ free_page(page);
28473 ++out_put:
28474 ++ put_vx_info(vxi);
28475 ++out:
28476 ++ return length;
28477 ++}
28478 ++
28479 ++static ssize_t proc_nx_info_read(struct file *file, char __user *buf,
28480 ++ size_t count, loff_t *ppos)
28481 ++{
28482 ++ struct inode *inode = file->f_dentry->d_inode;
28483 ++ struct nx_info *nxi = NULL;
28484 ++ nid_t nid = PROC_I(inode)->fd;
28485 ++ unsigned long page;
28486 ++ ssize_t length = 0;
28487 ++
28488 ++ if (count > PROC_BLOCK_SIZE)
28489 ++ count = PROC_BLOCK_SIZE;
28490 ++
28491 ++ /* fade that out as soon as stable */
28492 ++ WARN_ON(!nid);
28493 ++ nxi = lookup_nx_info(nid);
28494 ++ if (!nxi)
28495 ++ goto out;
28496 ++
28497 ++ length = -ENOMEM;
28498 ++ if (!(page = __get_free_page(GFP_KERNEL)))
28499 ++ goto out_put;
28500 ++
28501 ++ BUG_ON(!PROC_I(inode)->op.proc_nxi_read);
28502 ++ length = PROC_I(inode)->op.proc_nxi_read(nxi, (char *)page);
28503 ++
28504 ++ if (length >= 0)
28505 ++ length = simple_read_from_buffer(buf, count, ppos,
28506 ++ (char *)page, length);
28507 ++
28508 ++ free_page(page);
28509 ++out_put:
28510 ++ put_nx_info(nxi);
28511 ++out:
28512 ++ return length;
28513 ++}
28514 ++
28515 ++
28516 ++
28517 ++/* here comes the lower level */
28518 ++
28519 ++
28520 ++#define NOD(NAME, MODE, IOP, FOP, OP) { \
28521 ++ .len = sizeof(NAME) - 1, \
28522 ++ .name = (NAME), \
28523 ++ .mode = MODE, \
28524 ++ .iop = IOP, \
28525 ++ .fop = FOP, \
28526 ++ .op = OP, \
28527 ++}
28528 ++
28529 ++
28530 ++#define DIR(NAME, MODE, OTYPE) \
28531 ++ NOD(NAME, (S_IFDIR | (MODE)), \
28532 ++ &proc_ ## OTYPE ## _inode_operations, \
28533 ++ &proc_ ## OTYPE ## _file_operations, { } )
28534 ++
28535 ++#define INF(NAME, MODE, OTYPE) \
28536 ++ NOD(NAME, (S_IFREG | (MODE)), NULL, \
28537 ++ &proc_vs_info_file_operations, \
28538 ++ { .proc_vs_read = &proc_##OTYPE } )
28539 ++
28540 ++#define VINF(NAME, MODE, OTYPE) \
28541 ++ NOD(NAME, (S_IFREG | (MODE)), NULL, \
28542 ++ &proc_vx_info_file_operations, \
28543 ++ { .proc_vxi_read = &proc_##OTYPE } )
28544 ++
28545 ++#define NINF(NAME, MODE, OTYPE) \
28546 ++ NOD(NAME, (S_IFREG | (MODE)), NULL, \
28547 ++ &proc_nx_info_file_operations, \
28548 ++ { .proc_nxi_read = &proc_##OTYPE } )
28549 ++
28550 ++
28551 ++static struct file_operations proc_vs_info_file_operations = {
28552 ++ .read = proc_vs_info_read,
28553 ++};
28554 ++
28555 ++static struct file_operations proc_vx_info_file_operations = {
28556 ++ .read = proc_vx_info_read,
28557 ++};
28558 ++
28559 ++static struct dentry_operations proc_xid_dentry_operations = {
28560 ++ .d_revalidate = proc_xid_revalidate,
28561 ++};
28562 ++
28563 ++static struct vs_entry vx_base_stuff[] = {
28564 ++ VINF("info", S_IRUGO, vxi_info),
28565 ++ VINF("status", S_IRUGO, vxi_status),
28566 ++ VINF("limit", S_IRUGO, vxi_limit),
28567 ++ VINF("sched", S_IRUGO, vxi_sched),
28568 ++ VINF("nsproxy", S_IRUGO, vxi_nsproxy),
28569 ++ VINF("cvirt", S_IRUGO, vxi_cvirt),
28570 ++ VINF("cacct", S_IRUGO, vxi_cacct),
28571 ++ {}
28572 ++};
28573 ++
28574 ++
28575 ++
28576 ++
28577 ++static struct dentry *proc_xid_instantiate(struct inode *dir,
28578 ++ struct dentry *dentry, int id, void *ptr)
28579 ++{
28580 ++ dentry->d_op = &proc_xid_dentry_operations;
28581 ++ return vs_proc_instantiate(dir, dentry, id, ptr);
28582 ++}
28583 ++
28584 ++static struct dentry *proc_xid_lookup(struct inode *dir,
28585 ++ struct dentry *dentry, struct nameidata *nd)
28586 ++{
28587 ++ struct vs_entry *p = vx_base_stuff;
28588 ++ struct dentry *error = ERR_PTR(-ENOENT);
28589 ++
28590 ++ for (; p->name; p++) {
28591 ++ if (p->len != dentry->d_name.len)
28592 ++ continue;
28593 ++ if (!memcmp(dentry->d_name.name, p->name, p->len))
28594 ++ break;
28595 ++ }
28596 ++ if (!p->name)
28597 ++ goto out;
28598 ++
28599 ++ error = proc_xid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
28600 ++out:
28601 ++ return error;
28602 ++}
28603 ++
28604 ++static int proc_xid_readdir(struct file *filp,
28605 ++ void *dirent, filldir_t filldir)
28606 ++{
28607 ++ struct dentry *dentry = filp->f_dentry;
28608 ++ struct inode *inode = dentry->d_inode;
28609 ++ struct vs_entry *p = vx_base_stuff;
28610 ++ int size = sizeof(vx_base_stuff) / sizeof(struct vs_entry);
28611 ++ int pos, index;
28612 ++ u64 ino;
28613 ++
28614 ++ pos = filp->f_pos;
28615 ++ switch (pos) {
28616 ++ case 0:
28617 ++ ino = inode->i_ino;
28618 ++ if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
28619 ++ goto out;
28620 ++ pos++;
28621 ++ /* fall through */
28622 ++ case 1:
28623 ++ ino = parent_ino(dentry);
28624 ++ if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
28625 ++ goto out;
28626 ++ pos++;
28627 ++ /* fall through */
28628 ++ default:
28629 ++ index = pos - 2;
28630 ++ if (index >= size)
28631 ++ goto out;
28632 ++ for (p += index; p->name; p++) {
28633 ++ if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
28634 ++ vs_proc_instantiate, PROC_I(inode)->fd, p))
28635 ++ goto out;
28636 ++ pos++;
28637 ++ }
28638 ++ }
28639 ++out:
28640 ++ filp->f_pos = pos;
28641 ++ return 1;
28642 ++}
28643 ++
28644 ++
28645 ++
28646 ++static struct file_operations proc_nx_info_file_operations = {
28647 ++ .read = proc_nx_info_read,
28648 ++};
28649 ++
28650 ++static struct dentry_operations proc_nid_dentry_operations = {
28651 ++ .d_revalidate = proc_nid_revalidate,
28652 ++};
28653 ++
28654 ++static struct vs_entry nx_base_stuff[] = {
28655 ++ NINF("info", S_IRUGO, nxi_info),
28656 ++ NINF("status", S_IRUGO, nxi_status),
28657 ++ {}
28658 ++};
28659 ++
28660 ++
28661 ++static struct dentry *proc_nid_instantiate(struct inode *dir,
28662 ++ struct dentry *dentry, int id, void *ptr)
28663 ++{
28664 ++ dentry->d_op = &proc_nid_dentry_operations;
28665 ++ return vs_proc_instantiate(dir, dentry, id, ptr);
28666 ++}
28667 ++
28668 ++static struct dentry *proc_nid_lookup(struct inode *dir,
28669 ++ struct dentry *dentry, struct nameidata *nd)
28670 ++{
28671 ++ struct vs_entry *p = nx_base_stuff;
28672 ++ struct dentry *error = ERR_PTR(-ENOENT);
28673 ++
28674 ++ for (; p->name; p++) {
28675 ++ if (p->len != dentry->d_name.len)
28676 ++ continue;
28677 ++ if (!memcmp(dentry->d_name.name, p->name, p->len))
28678 ++ break;
28679 ++ }
28680 ++ if (!p->name)
28681 ++ goto out;
28682 ++
28683 ++ error = proc_nid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
28684 ++out:
28685 ++ return error;
28686 ++}
28687 ++
28688 ++static int proc_nid_readdir(struct file *filp,
28689 ++ void *dirent, filldir_t filldir)
28690 ++{
28691 ++ struct dentry *dentry = filp->f_dentry;
28692 ++ struct inode *inode = dentry->d_inode;
28693 ++ struct vs_entry *p = nx_base_stuff;
28694 ++ int size = sizeof(nx_base_stuff) / sizeof(struct vs_entry);
28695 ++ int pos, index;
28696 ++ u64 ino;
28697 ++
28698 ++ pos = filp->f_pos;
28699 ++ switch (pos) {
28700 ++ case 0:
28701 ++ ino = inode->i_ino;
28702 ++ if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
28703 ++ goto out;
28704 ++ pos++;
28705 ++ /* fall through */
28706 ++ case 1:
28707 ++ ino = parent_ino(dentry);
28708 ++ if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
28709 ++ goto out;
28710 ++ pos++;
28711 ++ /* fall through */
28712 ++ default:
28713 ++ index = pos - 2;
28714 ++ if (index >= size)
28715 ++ goto out;
28716 ++ for (p += index; p->name; p++) {
28717 ++ if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
28718 ++ vs_proc_instantiate, PROC_I(inode)->fd, p))
28719 ++ goto out;
28720 ++ pos++;
28721 ++ }
28722 ++ }
28723 ++out:
28724 ++ filp->f_pos = pos;
28725 ++ return 1;
28726 ++}
28727 ++
28728 ++
28729 ++#define MAX_MULBY10 ((~0U - 9) / 10)
28730 ++
28731 ++static inline int atovid(const char *str, int len)
28732 ++{
28733 ++ int vid, c;
28734 ++
28735 ++ vid = 0;
28736 ++ while (len-- > 0) {
28737 ++ c = *str - '0';
28738 ++ str++;
28739 ++ if (c > 9)
28740 ++ return -1;
28741 ++ if (vid >= MAX_MULBY10)
28742 ++ return -1;
28743 ++ vid *= 10;
28744 ++ vid += c;
28745 ++ if (!vid)
28746 ++ return -1;
28747 ++ }
28748 ++ return vid;
28749 ++}
28750 ++
28751 ++/* now the upper level (virtual) */
28752 ++
28753 ++
28754 ++static struct file_operations proc_xid_file_operations = {
28755 ++ .read = generic_read_dir,
28756 ++ .readdir = proc_xid_readdir,
28757 ++};
28758 ++
28759 ++static struct inode_operations proc_xid_inode_operations = {
28760 ++ .lookup = proc_xid_lookup,
28761 ++};
28762 ++
28763 ++static struct vs_entry vx_virtual_stuff[] = {
28764 ++ INF("info", S_IRUGO, virtual_info),
28765 ++ INF("status", S_IRUGO, virtual_status),
28766 ++ DIR(NULL, S_IRUGO | S_IXUGO, xid),
28767 ++};
28768 ++
28769 ++
28770 ++static struct dentry *proc_virtual_lookup(struct inode *dir,
28771 ++ struct dentry *dentry, struct nameidata *nd)
28772 ++{
28773 ++ struct vs_entry *p = vx_virtual_stuff;
28774 ++ struct dentry *error = ERR_PTR(-ENOENT);
28775 ++ int id = 0;
28776 ++
28777 ++ for (; p->name; p++) {
28778 ++ if (p->len != dentry->d_name.len)
28779 ++ continue;
28780 ++ if (!memcmp(dentry->d_name.name, p->name, p->len))
28781 ++ break;
28782 ++ }
28783 ++ if (p->name)
28784 ++ goto instantiate;
28785 ++
28786 ++ id = atovid(dentry->d_name.name, dentry->d_name.len);
28787 ++ if ((id < 0) || !xid_is_hashed(id))
28788 ++ goto out;
28789 ++
28790 ++instantiate:
28791 ++ error = proc_xid_instantiate(dir, dentry, id, p);
28792 ++out:
28793 ++ return error;
28794 ++}
28795 ++
28796 ++static struct file_operations proc_nid_file_operations = {
28797 ++ .read = generic_read_dir,
28798 ++ .readdir = proc_nid_readdir,
28799 ++};
28800 ++
28801 ++static struct inode_operations proc_nid_inode_operations = {
28802 ++ .lookup = proc_nid_lookup,
28803 ++};
28804 ++
28805 ++static struct vs_entry nx_virtnet_stuff[] = {
28806 ++ INF("info", S_IRUGO, virtnet_info),
28807 ++ INF("status", S_IRUGO, virtnet_status),
28808 ++ DIR(NULL, S_IRUGO | S_IXUGO, nid),
28809 ++};
28810 ++
28811 ++
28812 ++static struct dentry *proc_virtnet_lookup(struct inode *dir,
28813 ++ struct dentry *dentry, struct nameidata *nd)
28814 ++{
28815 ++ struct vs_entry *p = nx_virtnet_stuff;
28816 ++ struct dentry *error = ERR_PTR(-ENOENT);
28817 ++ int id = 0;
28818 ++
28819 ++ for (; p->name; p++) {
28820 ++ if (p->len != dentry->d_name.len)
28821 ++ continue;
28822 ++ if (!memcmp(dentry->d_name.name, p->name, p->len))
28823 ++ break;
28824 ++ }
28825 ++ if (p->name)
28826 ++ goto instantiate;
28827 ++
28828 ++ id = atovid(dentry->d_name.name, dentry->d_name.len);
28829 ++ if ((id < 0) || !nid_is_hashed(id))
28830 ++ goto out;
28831 ++
28832 ++instantiate:
28833 ++ error = proc_nid_instantiate(dir, dentry, id, p);
28834 ++out:
28835 ++ return error;
28836 ++}
28837 ++
28838 ++
28839 ++
28840 ++#define PROC_NUMBUF 10
28841 ++#define PROC_MAXVIDS 32
28842 ++
28843 ++int proc_virtual_readdir(struct file *filp,
28844 ++ void *dirent, filldir_t filldir)
28845 ++{
28846 ++ struct dentry *dentry = filp->f_dentry;
28847 ++ struct inode *inode = dentry->d_inode;
28848 ++ struct vs_entry *p = vx_virtual_stuff;
28849 ++ int size = sizeof(vx_virtual_stuff) / sizeof(struct vs_entry);
28850 ++ int pos, index;
28851 ++ unsigned int xid_array[PROC_MAXVIDS];
28852 ++ char buf[PROC_NUMBUF];
28853 ++ unsigned int nr_xids, i;
28854 ++ u64 ino;
28855 ++
28856 ++ pos = filp->f_pos;
28857 ++ switch (pos) {
28858 ++ case 0:
28859 ++ ino = inode->i_ino;
28860 ++ if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
28861 ++ goto out;
28862 ++ pos++;
28863 ++ /* fall through */
28864 ++ case 1:
28865 ++ ino = parent_ino(dentry);
28866 ++ if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
28867 ++ goto out;
28868 ++ pos++;
28869 ++ /* fall through */
28870 ++ default:
28871 ++ index = pos - 2;
28872 ++ if (index >= size)
28873 ++ goto entries;
28874 ++ for (p += index; p->name; p++) {
28875 ++ if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
28876 ++ vs_proc_instantiate, 0, p))
28877 ++ goto out;
28878 ++ pos++;
28879 ++ }
28880 ++ entries:
28881 ++ index = pos - size;
28882 ++ p = &vx_virtual_stuff[size - 1];
28883 ++ nr_xids = get_xid_list(index, xid_array, PROC_MAXVIDS);
28884 ++ for (i = 0; i < nr_xids; i++) {
28885 ++ int n, xid = xid_array[i];
28886 ++ unsigned int j = PROC_NUMBUF;
28887 ++
28888 ++ n = xid;
28889 ++ do
28890 ++ buf[--j] = '0' + (n % 10);
28891 ++ while (n /= 10);
28892 ++
28893 ++ if (proc_fill_cache(filp, dirent, filldir,
28894 ++ buf + j, PROC_NUMBUF - j,
28895 ++ vs_proc_instantiate, xid, p))
28896 ++ goto out;
28897 ++ pos++;
28898 ++ }
28899 ++ }
28900 ++out:
28901 ++ filp->f_pos = pos;
28902 ++ return 0;
28903 ++}
28904 ++
28905 ++static int proc_virtual_getattr(struct vfsmount *mnt,
28906 ++ struct dentry *dentry, struct kstat *stat)
28907 ++{
28908 ++ struct inode *inode = dentry->d_inode;
28909 ++
28910 ++ generic_fillattr(inode, stat);
28911 ++ stat->nlink = 2 + atomic_read(&vx_global_cactive);
28912 ++ return 0;
28913 ++}
28914 ++
28915 ++static struct file_operations proc_virtual_dir_operations = {
28916 ++ .read = generic_read_dir,
28917 ++ .readdir = proc_virtual_readdir,
28918 ++};
28919 ++
28920 ++static struct inode_operations proc_virtual_dir_inode_operations = {
28921 ++ .getattr = proc_virtual_getattr,
28922 ++ .lookup = proc_virtual_lookup,
28923 ++};
28924 ++
28925 ++
28926 ++
28927 ++
28928 ++
28929 ++int proc_virtnet_readdir(struct file *filp,
28930 ++ void *dirent, filldir_t filldir)
28931 ++{
28932 ++ struct dentry *dentry = filp->f_dentry;
28933 ++ struct inode *inode = dentry->d_inode;
28934 ++ struct vs_entry *p = nx_virtnet_stuff;
28935 ++ int size = sizeof(nx_virtnet_stuff) / sizeof(struct vs_entry);
28936 ++ int pos, index;
28937 ++ unsigned int nid_array[PROC_MAXVIDS];
28938 ++ char buf[PROC_NUMBUF];
28939 ++ unsigned int nr_nids, i;
28940 ++ u64 ino;
28941 ++
28942 ++ pos = filp->f_pos;
28943 ++ switch (pos) {
28944 ++ case 0:
28945 ++ ino = inode->i_ino;
28946 ++ if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
28947 ++ goto out;
28948 ++ pos++;
28949 ++ /* fall through */
28950 ++ case 1:
28951 ++ ino = parent_ino(dentry);
28952 ++ if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
28953 ++ goto out;
28954 ++ pos++;
28955 ++ /* fall through */
28956 ++ default:
28957 ++ index = pos - 2;
28958 ++ if (index >= size)
28959 ++ goto entries;
28960 ++ for (p += index; p->name; p++) {
28961 ++ if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
28962 ++ vs_proc_instantiate, 0, p))
28963 ++ goto out;
28964 ++ pos++;
28965 ++ }
28966 ++ entries:
28967 ++ index = pos - size;
28968 ++ p = &nx_virtnet_stuff[size - 1];
28969 ++ nr_nids = get_nid_list(index, nid_array, PROC_MAXVIDS);
28970 ++ for (i = 0; i < nr_nids; i++) {
28971 ++ int n, nid = nid_array[i];
28972 ++ unsigned int j = PROC_NUMBUF;
28973 ++
28974 ++ n = nid;
28975 ++ do
28976 ++ buf[--j] = '0' + (n % 10);
28977 ++ while (n /= 10);
28978 ++
28979 ++ if (proc_fill_cache(filp, dirent, filldir,
28980 ++ buf + j, PROC_NUMBUF - j,
28981 ++ vs_proc_instantiate, nid, p))
28982 ++ goto out;
28983 ++ pos++;
28984 ++ }
28985 ++ }
28986 ++out:
28987 ++ filp->f_pos = pos;
28988 ++ return 0;
28989 ++}
28990 ++
28991 ++static int proc_virtnet_getattr(struct vfsmount *mnt,
28992 ++ struct dentry *dentry, struct kstat *stat)
28993 ++{
28994 ++ struct inode *inode = dentry->d_inode;
28995 ++
28996 ++ generic_fillattr(inode, stat);
28997 ++ stat->nlink = 2 + atomic_read(&nx_global_cactive);
28998 ++ return 0;
28999 ++}
29000 ++
29001 ++static struct file_operations proc_virtnet_dir_operations = {
29002 ++ .read = generic_read_dir,
29003 ++ .readdir = proc_virtnet_readdir,
29004 ++};
29005 ++
29006 ++static struct inode_operations proc_virtnet_dir_inode_operations = {
29007 ++ .getattr = proc_virtnet_getattr,
29008 ++ .lookup = proc_virtnet_lookup,
29009 ++};
29010 ++
29011 ++
29012 ++
29013 ++void proc_vx_init(void)
29014 ++{
29015 ++ struct proc_dir_entry *ent;
29016 ++
29017 ++ ent = proc_mkdir("virtual", 0);
29018 ++ if (ent) {
29019 ++ ent->proc_fops = &proc_virtual_dir_operations;
29020 ++ ent->proc_iops = &proc_virtual_dir_inode_operations;
29021 ++ }
29022 ++ proc_virtual = ent;
29023 ++
29024 ++ ent = proc_mkdir("virtnet", 0);
29025 ++ if (ent) {
29026 ++ ent->proc_fops = &proc_virtnet_dir_operations;
29027 ++ ent->proc_iops = &proc_virtnet_dir_inode_operations;
29028 ++ }
29029 ++ proc_virtnet = ent;
29030 ++}
29031 ++
29032 ++
29033 ++
29034 ++
29035 ++/* per pid info */
29036 ++
29037 ++
29038 ++int proc_pid_vx_info(struct task_struct *p, char *buffer)
29039 ++{
29040 ++ struct vx_info *vxi;
29041 ++ char *orig = buffer;
29042 ++
29043 ++ buffer += sprintf(buffer, "XID:\t%d\n", vx_task_xid(p));
29044 ++
29045 ++ vxi = task_get_vx_info(p);
29046 ++ if (!vxi)
29047 ++ goto out;
29048 ++
29049 ++ buffer += sprintf(buffer, "BCaps:\t%016llx\n",
29050 ++ (unsigned long long)vxi->vx_bcaps);
29051 ++ buffer += sprintf(buffer, "CCaps:\t%016llx\n",
29052 ++ (unsigned long long)vxi->vx_ccaps);
29053 ++ buffer += sprintf(buffer, "CFlags:\t%016llx\n",
29054 ++ (unsigned long long)vxi->vx_flags);
29055 ++ buffer += sprintf(buffer, "CIPid:\t%d\n", vxi->vx_initpid);
29056 ++
29057 ++ put_vx_info(vxi);
29058 ++out:
29059 ++ return buffer - orig;
29060 ++}
29061 ++
29062 ++
29063 ++int proc_pid_nx_info(struct task_struct *p, char *buffer)
29064 ++{
29065 ++ struct nx_info *nxi;
29066 ++ char *orig = buffer;
29067 ++ int i;
29068 ++
29069 ++ buffer += sprintf(buffer, "NID:\t%d\n", nx_task_nid(p));
29070 ++
29071 ++ nxi = task_get_nx_info(p);
29072 ++ if (!nxi)
29073 ++ goto out;
29074 ++
29075 ++ buffer += sprintf(buffer, "NCaps:\t%016llx\n",
29076 ++ (unsigned long long)nxi->nx_ncaps);
29077 ++ buffer += sprintf(buffer, "NFlags:\t%016llx\n",
29078 ++ (unsigned long long)nxi->nx_flags);
29079 ++
29080 ++ for (i = 0; i < nxi->nbipv4; i++){
29081 ++ buffer += sprintf(buffer,
29082 ++ "V4Root[%d]:\t" NIPQUAD_FMT "/" NIPQUAD_FMT "\n", i,
29083 ++ NIPQUAD(nxi->ipv4[i]),
29084 ++ NIPQUAD(nxi->mask[i]));
29085 ++ }
29086 ++ buffer += sprintf(buffer,
29087 ++ "V4Root[bcast]:\t" NIPQUAD_FMT "\n",
29088 ++ NIPQUAD(nxi->v4_bcast));
29089 ++
29090 ++ put_nx_info(nxi);
29091 ++out:
29092 ++ return buffer - orig;
29093 ++}
29094 ++
29095 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/sched.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/sched.c
29096 +--- linux-2.6.22.19/kernel/vserver/sched.c 1970-01-01 01:00:00 +0100
29097 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/sched.c 2007-06-15 02:37:04 +0200
29098 +@@ -0,0 +1,447 @@
29099 ++/*
29100 ++ * linux/kernel/vserver/sched.c
29101 ++ *
29102 ++ * Virtual Server: Scheduler Support
29103 ++ *
29104 ++ * Copyright (C) 2004-2007 Herbert Pötzl
29105 ++ *
29106 ++ * V0.01 adapted Sam Vilains version to 2.6.3
29107 ++ * V0.02 removed legacy interface
29108 ++ * V0.03 changed vcmds to vxi arg
29109 ++ *
29110 ++ */
29111 ++
29112 ++#include <linux/sched.h>
29113 ++#include <linux/vs_context.h>
29114 ++#include <linux/vs_sched.h>
29115 ++#include <linux/vserver/sched_cmd.h>
29116 ++
29117 ++#include <asm/errno.h>
29118 ++#include <asm/uaccess.h>
29119 ++
29120 ++#define vxd_check_range(val, min, max) do { \
29121 ++ vxlprintk((val < min) || (val > max), \
29122 ++ "check_range(%ld,%ld,%ld)", \
29123 ++ (long)val, (long)min, (long)max, \
29124 ++ __FILE__, __LINE__); \
29125 ++ } while (0)
29126 ++
29127 ++
29128 ++void vx_update_sched_param(struct _vx_sched *sched,
29129 ++ struct _vx_sched_pc *sched_pc)
29130 ++{
29131 ++ unsigned int set_mask = sched->update_mask;
29132 ++
29133 ++ if (set_mask & VXSM_FILL_RATE)
29134 ++ sched_pc->fill_rate[0] = sched->fill_rate[0];
29135 ++ if (set_mask & VXSM_INTERVAL)
29136 ++ sched_pc->interval[0] = sched->interval[0];
29137 ++ if (set_mask & VXSM_FILL_RATE2)
29138 ++ sched_pc->fill_rate[1] = sched->fill_rate[1];
29139 ++ if (set_mask & VXSM_INTERVAL2)
29140 ++ sched_pc->interval[1] = sched->interval[1];
29141 ++ if (set_mask & VXSM_TOKENS)
29142 ++ sched_pc->tokens = sched->tokens;
29143 ++ if (set_mask & VXSM_TOKENS_MIN)
29144 ++ sched_pc->tokens_min = sched->tokens_min;
29145 ++ if (set_mask & VXSM_TOKENS_MAX)
29146 ++ sched_pc->tokens_max = sched->tokens_max;
29147 ++ if (set_mask & VXSM_PRIO_BIAS)
29148 ++ sched_pc->prio_bias = sched->prio_bias;
29149 ++
29150 ++ if (set_mask & VXSM_IDLE_TIME)
29151 ++ sched_pc->flags |= VXSF_IDLE_TIME;
29152 ++ else
29153 ++ sched_pc->flags &= ~VXSF_IDLE_TIME;
29154 ++
29155 ++ /* reset time */
29156 ++ sched_pc->norm_time = jiffies;
29157 ++}
29158 ++
29159 ++
29160 ++/*
29161 ++ * recalculate the context's scheduling tokens
29162 ++ *
29163 ++ * ret > 0 : number of tokens available
29164 ++ * ret < 0 : on hold, check delta_min[]
29165 ++ * -1 only jiffies
29166 ++ * -2 also idle time
29167 ++ *
29168 ++ */
29169 ++int vx_tokens_recalc(struct _vx_sched_pc *sched_pc,
29170 ++ unsigned long *norm_time, unsigned long *idle_time, int delta_min[2])
29171 ++{
29172 ++ long delta;
29173 ++ long tokens = 0;
29174 ++ int flags = sched_pc->flags;
29175 ++
29176 ++ /* how much time did pass? */
29177 ++ delta = *norm_time - sched_pc->norm_time;
29178 ++ vxd_check_range(delta, 0, INT_MAX);
29179 ++
29180 ++ if (delta >= sched_pc->interval[0]) {
29181 ++ long tokens, integral;
29182 ++
29183 ++ /* calc integral token part */
29184 ++ tokens = delta / sched_pc->interval[0];
29185 ++ integral = tokens * sched_pc->interval[0];
29186 ++ tokens *= sched_pc->fill_rate[0];
29187 ++#ifdef CONFIG_VSERVER_HARDCPU
29188 ++ delta_min[0] = delta - integral;
29189 ++ vxd_check_range(delta_min[0], 0, sched_pc->interval[0]);
29190 ++#endif
29191 ++ /* advance time */
29192 ++ sched_pc->norm_time += delta;
29193 ++
29194 ++ /* add tokens */
29195 ++ sched_pc->tokens += tokens;
29196 ++ sched_pc->token_time += tokens;
29197 ++ } else
29198 ++ delta_min[0] = delta;
29199 ++
29200 ++#ifdef CONFIG_VSERVER_IDLETIME
29201 ++ if (!(flags & VXSF_IDLE_TIME))
29202 ++ goto skip_idle;
29203 ++
29204 ++ /* how much was the idle skip? */
29205 ++ delta = *idle_time - sched_pc->idle_time;
29206 ++ vxd_check_range(delta, 0, INT_MAX);
29207 ++
29208 ++ if (delta >= sched_pc->interval[1]) {
29209 ++ long tokens, integral;
29210 ++
29211 ++ /* calc fair share token part */
29212 ++ tokens = delta / sched_pc->interval[1];
29213 ++ integral = tokens * sched_pc->interval[1];
29214 ++ tokens *= sched_pc->fill_rate[1];
29215 ++ delta_min[1] = delta - integral;
29216 ++ vxd_check_range(delta_min[1], 0, sched_pc->interval[1]);
29217 ++
29218 ++ /* advance idle time */
29219 ++ sched_pc->idle_time += integral;
29220 ++
29221 ++ /* add tokens */
29222 ++ sched_pc->tokens += tokens;
29223 ++ sched_pc->token_time += tokens;
29224 ++ } else
29225 ++ delta_min[1] = delta;
29226 ++skip_idle:
29227 ++#endif
29228 ++
29229 ++ /* clip at maximum */
29230 ++ if (sched_pc->tokens > sched_pc->tokens_max)
29231 ++ sched_pc->tokens = sched_pc->tokens_max;
29232 ++ tokens = sched_pc->tokens;
29233 ++
29234 ++ if ((flags & VXSF_ONHOLD)) {
29235 ++ /* can we unhold? */
29236 ++ if (tokens >= sched_pc->tokens_min) {
29237 ++ flags &= ~VXSF_ONHOLD;
29238 ++ sched_pc->hold_ticks +=
29239 ++ *norm_time - sched_pc->onhold;
29240 ++ } else
29241 ++ goto on_hold;
29242 ++ } else {
29243 ++ /* put on hold? */
29244 ++ if (tokens <= 0) {
29245 ++ flags |= VXSF_ONHOLD;
29246 ++ sched_pc->onhold = *norm_time;
29247 ++ goto on_hold;
29248 ++ }
29249 ++ }
29250 ++ sched_pc->flags = flags;
29251 ++ return tokens;
29252 ++
29253 ++on_hold:
29254 ++ tokens = sched_pc->tokens_min - tokens;
29255 ++ sched_pc->flags = flags;
29256 ++ BUG_ON(tokens < 0);
29257 ++
29258 ++#ifdef CONFIG_VSERVER_HARDCPU
29259 ++ /* next interval? */
29260 ++ if (!sched_pc->fill_rate[0])
29261 ++ delta_min[0] = HZ;
29262 ++ else if (tokens > sched_pc->fill_rate[0])
29263 ++ delta_min[0] += sched_pc->interval[0] *
29264 ++ tokens / sched_pc->fill_rate[0];
29265 ++ else
29266 ++ delta_min[0] = sched_pc->interval[0] - delta_min[0];
29267 ++ vxd_check_range(delta_min[0], 0, INT_MAX);
29268 ++
29269 ++#ifdef CONFIG_VSERVER_IDLETIME
29270 ++ if (!(flags & VXSF_IDLE_TIME))
29271 ++ return -1;
29272 ++
29273 ++ /* next interval? */
29274 ++ if (!sched_pc->fill_rate[1])
29275 ++ delta_min[1] = HZ;
29276 ++ else if (tokens > sched_pc->fill_rate[1])
29277 ++ delta_min[1] += sched_pc->interval[1] *
29278 ++ tokens / sched_pc->fill_rate[1];
29279 ++ else
29280 ++ delta_min[1] = sched_pc->interval[1] - delta_min[1];
29281 ++ vxd_check_range(delta_min[1], 0, INT_MAX);
29282 ++
29283 ++ return -2;
29284 ++#else
29285 ++ return -1;
29286 ++#endif /* CONFIG_VSERVER_IDLETIME */
29287 ++#else
29288 ++ return 0;
29289 ++#endif /* CONFIG_VSERVER_HARDCPU */
29290 ++}
29291 ++
29292 ++static inline unsigned long msec_to_ticks(unsigned long msec)
29293 ++{
29294 ++ return msecs_to_jiffies(msec);
29295 ++}
29296 ++
29297 ++static inline unsigned long ticks_to_msec(unsigned long ticks)
29298 ++{
29299 ++ return jiffies_to_msecs(ticks);
29300 ++}
29301 ++
29302 ++static inline unsigned long ticks_to_usec(unsigned long ticks)
29303 ++{
29304 ++ return jiffies_to_usecs(ticks);
29305 ++}
29306 ++
29307 ++
29308 ++static int do_set_sched(struct vx_info *vxi, struct vcmd_sched_v5 *data)
29309 ++{
29310 ++ unsigned int set_mask = data->mask;
29311 ++ unsigned int update_mask;
29312 ++ int i, cpu;
29313 ++
29314 ++ /* Sanity check data values */
29315 ++ if (data->tokens_max <= 0)
29316 ++ data->tokens_max = HZ;
29317 ++ if (data->tokens_min < 0)
29318 ++ data->tokens_min = HZ / 3;
29319 ++ if (data->tokens_min >= data->tokens_max)
29320 ++ data->tokens_min = data->tokens_max;
29321 ++
29322 ++ if (data->prio_bias > MAX_PRIO_BIAS)
29323 ++ data->prio_bias = MAX_PRIO_BIAS;
29324 ++ if (data->prio_bias < MIN_PRIO_BIAS)
29325 ++ data->prio_bias = MIN_PRIO_BIAS;
29326 ++
29327 ++ spin_lock(&vxi->sched.tokens_lock);
29328 ++
29329 ++ /* sync up on delayed updates */
29330 ++ for_each_cpu_mask(cpu, vxi->sched.update)
29331 ++ vx_update_sched_param(&vxi->sched,
29332 ++ &vx_per_cpu(vxi, sched_pc, cpu));
29333 ++
29334 ++ if (set_mask & VXSM_FILL_RATE)
29335 ++ vxi->sched.fill_rate[0] = data->fill_rate[0];
29336 ++ if (set_mask & VXSM_FILL_RATE2)
29337 ++ vxi->sched.fill_rate[1] = data->fill_rate[1];
29338 ++ if (set_mask & VXSM_INTERVAL)
29339 ++ vxi->sched.interval[0] = (set_mask & VXSM_MSEC) ?
29340 ++ msec_to_ticks(data->interval[0]) : data->interval[0];
29341 ++ if (set_mask & VXSM_INTERVAL2)
29342 ++ vxi->sched.interval[1] = (set_mask & VXSM_MSEC) ?
29343 ++ msec_to_ticks(data->interval[1]) : data->interval[1];
29344 ++ if (set_mask & VXSM_TOKENS)
29345 ++ vxi->sched.tokens = data->tokens;
29346 ++ if (set_mask & VXSM_TOKENS_MIN)
29347 ++ vxi->sched.tokens_min = data->tokens_min;
29348 ++ if (set_mask & VXSM_TOKENS_MAX)
29349 ++ vxi->sched.tokens_max = data->tokens_max;
29350 ++ if (set_mask & VXSM_PRIO_BIAS)
29351 ++ vxi->sched.prio_bias = data->prio_bias;
29352 ++
29353 ++ /* Sanity check rate/interval */
29354 ++ for (i = 0; i < 2; i++) {
29355 ++ if (data->fill_rate[i] < 0)
29356 ++ data->fill_rate[i] = 0;
29357 ++ if (data->interval[i] <= 0)
29358 ++ data->interval[i] = HZ;
29359 ++ }
29360 ++
29361 ++ update_mask = vxi->sched.update_mask & VXSM_SET_MASK;
29362 ++ update_mask |= (set_mask & (VXSM_SET_MASK | VXSM_IDLE_TIME));
29363 ++ vxi->sched.update_mask = update_mask;
29364 ++#ifdef CONFIG_SMP
29365 ++ rmb();
29366 ++ if (set_mask & VXSM_CPU_ID) {
29367 ++ vxi->sched.update = cpumask_of_cpu(data->cpu_id);
29368 ++ cpus_and(vxi->sched.update, cpu_online_map,
29369 ++ vxi->sched.update);
29370 ++ } else
29371 ++ vxi->sched.update = cpu_online_map;
29372 ++
29373 ++ /* forced reload? */
29374 ++ if (set_mask & VXSM_FORCE) {
29375 ++ for_each_cpu_mask(cpu, vxi->sched.update)
29376 ++ vx_update_sched_param(&vxi->sched,
29377 ++ &vx_per_cpu(vxi, sched_pc, cpu));
29378 ++ vxi->sched.update = CPU_MASK_NONE;
29379 ++ }
29380 ++#else
29381 ++ /* on UP we update immediately */
29382 ++ vx_update_sched_param(&vxi->sched,
29383 ++ &vx_per_cpu(vxi, sched_pc, 0));
29384 ++#endif
29385 ++
29386 ++ spin_unlock(&vxi->sched.tokens_lock);
29387 ++ return 0;
29388 ++}
29389 ++
29390 ++#define COPY_IDS(C) C(cpu_id); C(bucket_id)
29391 ++#define COPY_PRI(C) C(prio_bias)
29392 ++#define COPY_TOK(C) C(tokens); C(tokens_min); C(tokens_max)
29393 ++#define COPY_FRI(C) C(fill_rate[0]); C(interval[0]); \
29394 ++ C(fill_rate[1]); C(interval[1]);
29395 ++
29396 ++#define COPY_VALUE(name) vc_data.name = data->name
29397 ++
29398 ++static int do_set_sched_v4(struct vx_info *vxi, struct vcmd_set_sched_v4 *data)
29399 ++{
29400 ++ struct vcmd_sched_v5 vc_data;
29401 ++
29402 ++ vc_data.mask = data->set_mask;
29403 ++ COPY_IDS(COPY_VALUE);
29404 ++ COPY_PRI(COPY_VALUE);
29405 ++ COPY_TOK(COPY_VALUE);
29406 ++ vc_data.fill_rate[0] = vc_data.fill_rate[1] = data->fill_rate;
29407 ++ vc_data.interval[0] = vc_data.interval[1] = data->interval;
29408 ++ return do_set_sched(vxi, &vc_data);
29409 ++}
29410 ++
29411 ++#ifdef CONFIG_VSERVER_LEGACY
29412 ++
29413 ++#define COPY_MASK_V2(name, mask) \
29414 ++ if (vc_data.name != SCHED_KEEP) { \
29415 ++ vc_data_v4.name = vc_data.name; \
29416 ++ vc_data_v4.set_mask |= mask; \
29417 ++ }
29418 ++
29419 ++int vc_set_sched_v2(struct vx_info *vxi, void __user *data)
29420 ++{
29421 ++ struct vcmd_set_sched_v2 vc_data;
29422 ++ struct vcmd_set_sched_v4 vc_data_v4 = { .set_mask = 0 };
29423 ++
29424 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
29425 ++ return -EFAULT;
29426 ++
29427 ++ COPY_MASK_V2(fill_rate, VXSM_FILL_RATE);
29428 ++ COPY_MASK_V2(interval, VXSM_INTERVAL);
29429 ++ COPY_MASK_V2(tokens, VXSM_TOKENS);
29430 ++ COPY_MASK_V2(tokens_min, VXSM_TOKENS_MIN);
29431 ++ COPY_MASK_V2(tokens_max, VXSM_TOKENS_MAX);
29432 ++ vc_data_v4.bucket_id = 0;
29433 ++
29434 ++ do_set_sched_v4(vxi, &vc_data_v4);
29435 ++ return 0;
29436 ++}
29437 ++#endif
29438 ++
29439 ++int vc_set_sched_v3(struct vx_info *vxi, void __user *data)
29440 ++{
29441 ++ struct vcmd_set_sched_v3 vc_data;
29442 ++ struct vcmd_set_sched_v4 vc_data_v4;
29443 ++
29444 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
29445 ++ return -EFAULT;
29446 ++
29447 ++ /* structures are binary compatible */
29448 ++ memcpy(&vc_data_v4, &vc_data, sizeof(vc_data));
29449 ++ vc_data_v4.set_mask &= VXSM_V3_MASK;
29450 ++ vc_data_v4.bucket_id = 0;
29451 ++
29452 ++ return do_set_sched_v4(vxi, &vc_data_v4);
29453 ++}
29454 ++
29455 ++int vc_set_sched_v4(struct vx_info *vxi, void __user *data)
29456 ++{
29457 ++ struct vcmd_set_sched_v4 vc_data;
29458 ++
29459 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
29460 ++ return -EFAULT;
29461 ++
29462 ++ return do_set_sched_v4(vxi, &vc_data);
29463 ++}
29464 ++
29465 ++ /* latest interface is v5 */
29466 ++
29467 ++int vc_set_sched(struct vx_info *vxi, void __user *data)
29468 ++{
29469 ++ struct vcmd_sched_v5 vc_data;
29470 ++
29471 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
29472 ++ return -EFAULT;
29473 ++
29474 ++ return do_set_sched(vxi, &vc_data);
29475 ++}
29476 ++
29477 ++
29478 ++int vc_get_sched(struct vx_info *vxi, void __user *data)
29479 ++{
29480 ++ struct vcmd_sched_v5 vc_data;
29481 ++
29482 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
29483 ++ return -EFAULT;
29484 ++
29485 ++ if (vc_data.mask & VXSM_CPU_ID) {
29486 ++ int cpu = vc_data.cpu_id;
29487 ++ struct _vx_sched_pc *data;
29488 ++
29489 ++ if (!cpu_possible(cpu))
29490 ++ return -EINVAL;
29491 ++
29492 ++ data = &vx_per_cpu(vxi, sched_pc, cpu);
29493 ++ COPY_TOK(COPY_VALUE);
29494 ++ COPY_PRI(COPY_VALUE);
29495 ++ COPY_FRI(COPY_VALUE);
29496 ++
29497 ++ if (data->flags & VXSF_IDLE_TIME)
29498 ++ vc_data.mask |= VXSM_IDLE_TIME;
29499 ++ } else {
29500 ++ struct _vx_sched *data = &vxi->sched;
29501 ++
29502 ++ COPY_TOK(COPY_VALUE);
29503 ++ COPY_PRI(COPY_VALUE);
29504 ++ COPY_FRI(COPY_VALUE);
29505 ++ }
29506 ++
29507 ++ if (vc_data.mask & VXSM_MSEC) {
29508 ++ vc_data.interval[0] = ticks_to_msec(vc_data.interval[0]);
29509 ++ vc_data.interval[1] = ticks_to_msec(vc_data.interval[1]);
29510 ++ }
29511 ++
29512 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
29513 ++ return -EFAULT;
29514 ++ return 0;
29515 ++}
29516 ++
29517 ++
29518 ++int vc_sched_info(struct vx_info *vxi, void __user *data)
29519 ++{
29520 ++ struct vcmd_sched_info vc_data;
29521 ++ int cpu;
29522 ++
29523 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
29524 ++ return -EFAULT;
29525 ++
29526 ++ cpu = vc_data.cpu_id;
29527 ++ if (!cpu_possible(cpu))
29528 ++ return -EINVAL;
29529 ++
29530 ++ if (vxi) {
29531 ++ struct _vx_sched_pc *sched_pc =
29532 ++ &vx_per_cpu(vxi, sched_pc, cpu);
29533 ++
29534 ++ vc_data.user_msec = ticks_to_msec(sched_pc->user_ticks);
29535 ++ vc_data.sys_msec = ticks_to_msec(sched_pc->sys_ticks);
29536 ++ vc_data.hold_msec = ticks_to_msec(sched_pc->hold_ticks);
29537 ++ vc_data.vavavoom = sched_pc->vavavoom;
29538 ++ }
29539 ++ vc_data.token_usec = ticks_to_usec(1);
29540 ++
29541 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
29542 ++ return -EFAULT;
29543 ++ return 0;
29544 ++}
29545 ++
29546 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/sched_init.h linux-2.6.22.19-vs2.2.0.7/kernel/vserver/sched_init.h
29547 +--- linux-2.6.22.19/kernel/vserver/sched_init.h 1970-01-01 01:00:00 +0100
29548 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/sched_init.h 2007-06-15 02:37:04 +0200
29549 +@@ -0,0 +1,50 @@
29550 ++
29551 ++static inline void vx_info_init_sched(struct _vx_sched *sched)
29552 ++{
29553 ++ static struct lock_class_key tokens_lock_key;
29554 ++
29555 ++ /* scheduling; hard code starting values as constants */
29556 ++ sched->fill_rate[0] = 1;
29557 ++ sched->interval[0] = 4;
29558 ++ sched->fill_rate[1] = 1;
29559 ++ sched->interval[1] = 8;
29560 ++ sched->tokens = HZ >> 2;
29561 ++ sched->tokens_min = HZ >> 4;
29562 ++ sched->tokens_max = HZ >> 1;
29563 ++ sched->tokens_lock = SPIN_LOCK_UNLOCKED;
29564 ++ sched->prio_bias = 0;
29565 ++
29566 ++ lockdep_set_class(&sched->tokens_lock, &tokens_lock_key);
29567 ++}
29568 ++
29569 ++static inline
29570 ++void vx_info_init_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
29571 ++{
29572 ++ sched_pc->fill_rate[0] = 1;
29573 ++ sched_pc->interval[0] = 4;
29574 ++ sched_pc->fill_rate[1] = 1;
29575 ++ sched_pc->interval[1] = 8;
29576 ++ sched_pc->tokens = HZ >> 2;
29577 ++ sched_pc->tokens_min = HZ >> 4;
29578 ++ sched_pc->tokens_max = HZ >> 1;
29579 ++ sched_pc->prio_bias = 0;
29580 ++ sched_pc->vavavoom = 0;
29581 ++ sched_pc->token_time = 0;
29582 ++ sched_pc->idle_time = 0;
29583 ++ sched_pc->norm_time = jiffies;
29584 ++
29585 ++ sched_pc->user_ticks = 0;
29586 ++ sched_pc->sys_ticks = 0;
29587 ++ sched_pc->hold_ticks = 0;
29588 ++}
29589 ++
29590 ++static inline void vx_info_exit_sched(struct _vx_sched *sched)
29591 ++{
29592 ++ return;
29593 ++}
29594 ++
29595 ++static inline
29596 ++void vx_info_exit_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
29597 ++{
29598 ++ return;
29599 ++}
29600 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/sched_proc.h linux-2.6.22.19-vs2.2.0.7/kernel/vserver/sched_proc.h
29601 +--- linux-2.6.22.19/kernel/vserver/sched_proc.h 1970-01-01 01:00:00 +0100
29602 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/sched_proc.h 2007-06-15 02:37:04 +0200
29603 +@@ -0,0 +1,57 @@
29604 ++#ifndef _VX_SCHED_PROC_H
29605 ++#define _VX_SCHED_PROC_H
29606 ++
29607 ++
29608 ++static inline
29609 ++int vx_info_proc_sched(struct _vx_sched *sched, char *buffer)
29610 ++{
29611 ++ int length = 0;
29612 ++
29613 ++ length += sprintf(buffer,
29614 ++ "FillRate:\t%8d,%d\n"
29615 ++ "Interval:\t%8d,%d\n"
29616 ++ "TokensMin:\t%8d\n"
29617 ++ "TokensMax:\t%8d\n"
29618 ++ "PrioBias:\t%8d\n",
29619 ++ sched->fill_rate[0],
29620 ++ sched->fill_rate[1],
29621 ++ sched->interval[0],
29622 ++ sched->interval[1],
29623 ++ sched->tokens_min,
29624 ++ sched->tokens_max,
29625 ++ sched->prio_bias);
29626 ++ return length;
29627 ++}
29628 ++
29629 ++static inline
29630 ++int vx_info_proc_sched_pc(struct _vx_sched_pc *sched_pc,
29631 ++ char *buffer, int cpu)
29632 ++{
29633 ++ int length = 0;
29634 ++
29635 ++ length += sprintf(buffer + length,
29636 ++ "cpu %d: %lld %lld %lld %ld %ld", cpu,
29637 ++ (unsigned long long)sched_pc->user_ticks,
29638 ++ (unsigned long long)sched_pc->sys_ticks,
29639 ++ (unsigned long long)sched_pc->hold_ticks,
29640 ++ sched_pc->token_time,
29641 ++ sched_pc->idle_time);
29642 ++ length += sprintf(buffer + length,
29643 ++ " %c%c %d %d %d %d/%d %d/%d",
29644 ++ (sched_pc->flags & VXSF_ONHOLD) ? 'H' : 'R',
29645 ++ (sched_pc->flags & VXSF_IDLE_TIME) ? 'I' : '-',
29646 ++ sched_pc->tokens,
29647 ++ sched_pc->tokens_min,
29648 ++ sched_pc->tokens_max,
29649 ++ sched_pc->fill_rate[0],
29650 ++ sched_pc->interval[0],
29651 ++ sched_pc->fill_rate[1],
29652 ++ sched_pc->interval[1]);
29653 ++ length += sprintf(buffer + length,
29654 ++ " %d %d\n",
29655 ++ sched_pc->prio_bias,
29656 ++ sched_pc->vavavoom);
29657 ++ return length;
29658 ++}
29659 ++
29660 ++#endif /* _VX_SCHED_PROC_H */
29661 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/signal.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/signal.c
29662 +--- linux-2.6.22.19/kernel/vserver/signal.c 1970-01-01 01:00:00 +0100
29663 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/signal.c 2007-06-15 02:37:04 +0200
29664 +@@ -0,0 +1,134 @@
29665 ++/*
29666 ++ * linux/kernel/vserver/signal.c
29667 ++ *
29668 ++ * Virtual Server: Signal Support
29669 ++ *
29670 ++ * Copyright (C) 2003-2007 Herbert Pötzl
29671 ++ *
29672 ++ * V0.01 broken out from vcontext V0.05
29673 ++ * V0.02 changed vcmds to vxi arg
29674 ++ * V0.03 adjusted siginfo for kill
29675 ++ *
29676 ++ */
29677 ++
29678 ++#include <linux/sched.h>
29679 ++
29680 ++#include <asm/errno.h>
29681 ++#include <asm/uaccess.h>
29682 ++
29683 ++#include <linux/vs_context.h>
29684 ++#include <linux/vserver/signal_cmd.h>
29685 ++
29686 ++
29687 ++int vx_info_kill(struct vx_info *vxi, int pid, int sig)
29688 ++{
29689 ++ int retval, count = 0;
29690 ++ struct task_struct *p;
29691 ++ struct siginfo *sip = SEND_SIG_PRIV;
29692 ++
29693 ++ retval = -ESRCH;
29694 ++ vxdprintk(VXD_CBIT(misc, 4),
29695 ++ "vx_info_kill(%p[#%d],%d,%d)*",
29696 ++ vxi, vxi->vx_id, pid, sig);
29697 ++ read_lock(&tasklist_lock);
29698 ++ switch (pid) {
29699 ++ case 0:
29700 ++ case -1:
29701 ++ for_each_process(p) {
29702 ++ int err = 0;
29703 ++
29704 ++ if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
29705 ++ (pid && vxi->vx_initpid == p->pid))
29706 ++ continue;
29707 ++
29708 ++ err = group_send_sig_info(sig, sip, p);
29709 ++ ++count;
29710 ++ if (err != -EPERM)
29711 ++ retval = err;
29712 ++ }
29713 ++ break;
29714 ++
29715 ++ case 1:
29716 ++ if (vxi->vx_initpid) {
29717 ++ pid = vxi->vx_initpid;
29718 ++ /* for now, only SIGINT to private init ... */
29719 ++ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
29720 ++ /* ... as long as there are tasks left */
29721 ++ (atomic_read(&vxi->vx_tasks) > 1))
29722 ++ sig = SIGINT;
29723 ++ }
29724 ++ /* fallthrough */
29725 ++ default:
29726 ++ p = find_task_by_real_pid(pid);
29727 ++ if (p) {
29728 ++ if (vx_task_xid(p) == vxi->vx_id)
29729 ++ retval = group_send_sig_info(sig, sip, p);
29730 ++ }
29731 ++ break;
29732 ++ }
29733 ++ read_unlock(&tasklist_lock);
29734 ++ vxdprintk(VXD_CBIT(misc, 4),
29735 ++ "vx_info_kill(%p[#%d],%d,%d,%ld) = %d",
29736 ++ vxi, vxi->vx_id, pid, sig, (long)sip, retval);
29737 ++ return retval;
29738 ++}
29739 ++
29740 ++int vc_ctx_kill(struct vx_info *vxi, void __user *data)
29741 ++{
29742 ++ struct vcmd_ctx_kill_v0 vc_data;
29743 ++
29744 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
29745 ++ return -EFAULT;
29746 ++
29747 ++ /* special check to allow guest shutdown */
29748 ++ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
29749 ++ /* forbid killall pid=0 when init is present */
29750 ++ (((vc_data.pid < 1) && vxi->vx_initpid) ||
29751 ++ (vc_data.pid > 1)))
29752 ++ return -EACCES;
29753 ++
29754 ++ return vx_info_kill(vxi, vc_data.pid, vc_data.sig);
29755 ++}
29756 ++
29757 ++
29758 ++static int __wait_exit(struct vx_info *vxi)
29759 ++{
29760 ++ DECLARE_WAITQUEUE(wait, current);
29761 ++ int ret = 0;
29762 ++
29763 ++ add_wait_queue(&vxi->vx_wait, &wait);
29764 ++ set_current_state(TASK_INTERRUPTIBLE);
29765 ++
29766 ++wait:
29767 ++ if (vx_info_state(vxi,
29768 ++ VXS_SHUTDOWN | VXS_HASHED | VXS_HELPER) == VXS_SHUTDOWN)
29769 ++ goto out;
29770 ++ if (signal_pending(current)) {
29771 ++ ret = -ERESTARTSYS;
29772 ++ goto out;
29773 ++ }
29774 ++ schedule();
29775 ++ goto wait;
29776 ++
29777 ++out:
29778 ++ set_current_state(TASK_RUNNING);
29779 ++ remove_wait_queue(&vxi->vx_wait, &wait);
29780 ++ return ret;
29781 ++}
29782 ++
29783 ++
29784 ++
29785 ++int vc_wait_exit(struct vx_info *vxi, void __user *data)
29786 ++{
29787 ++ struct vcmd_wait_exit_v0 vc_data;
29788 ++ int ret;
29789 ++
29790 ++ ret = __wait_exit(vxi);
29791 ++ vc_data.reboot_cmd = vxi->reboot_cmd;
29792 ++ vc_data.exit_code = vxi->exit_code;
29793 ++
29794 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
29795 ++ ret = -EFAULT;
29796 ++ return ret;
29797 ++}
29798 ++
29799 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/space.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/space.c
29800 +--- linux-2.6.22.19/kernel/vserver/space.c 1970-01-01 01:00:00 +0100
29801 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/space.c 2007-06-16 19:12:02 +0200
29802 +@@ -0,0 +1,281 @@
29803 ++/*
29804 ++ * linux/kernel/vserver/space.c
29805 ++ *
29806 ++ * Virtual Server: Context Space Support
29807 ++ *
29808 ++ * Copyright (C) 2003-2007 Herbert Pötzl
29809 ++ *
29810 ++ * V0.01 broken out from context.c 0.07
29811 ++ * V0.02 added task locking for namespace
29812 ++ * V0.03 broken out vx_enter_namespace
29813 ++ * V0.04 added *space support and commands
29814 ++ *
29815 ++ */
29816 ++
29817 ++#include <linux/utsname.h>
29818 ++#include <linux/sched.h>
29819 ++#include <linux/vs_context.h>
29820 ++#include <linux/vserver/space.h>
29821 ++#include <linux/vserver/space_cmd.h>
29822 ++#include <linux/dcache.h>
29823 ++#include <linux/mount.h>
29824 ++#include <linux/nsproxy.h>
29825 ++#include <linux/fs.h>
29826 ++
29827 ++#include <asm/errno.h>
29828 ++#include <asm/uaccess.h>
29829 ++
29830 ++
29831 ++atomic_t vs_global_nsproxy = ATOMIC_INIT(0);
29832 ++atomic_t vs_global_fs = ATOMIC_INIT(0);
29833 ++atomic_t vs_global_mnt_ns = ATOMIC_INIT(0);
29834 ++atomic_t vs_global_uts_ns = ATOMIC_INIT(0);
29835 ++atomic_t vs_global_ipc_ns = ATOMIC_INIT(0);
29836 ++
29837 ++
29838 ++/* namespace functions */
29839 ++
29840 ++#include <linux/mnt_namespace.h>
29841 ++
29842 ++const struct vcmd_space_mask space_mask = {
29843 ++ .mask = CLONE_NEWNS |
29844 ++ CLONE_NEWUTS |
29845 ++ CLONE_NEWIPC |
29846 ++ CLONE_FS
29847 ++};
29848 ++
29849 ++
29850 ++/*
29851 ++ * build a new nsproxy mix
29852 ++ * assumes that both proxies are 'const'
29853 ++ * does not touch nsproxy refcounts
29854 ++ * will hold a reference on the result.
29855 ++ */
29856 ++
29857 ++struct nsproxy *vs_mix_nsproxy(struct nsproxy *old_nsproxy,
29858 ++ struct nsproxy *new_nsproxy, unsigned long mask)
29859 ++{
29860 ++ struct mnt_namespace *old_ns;
29861 ++ struct uts_namespace *old_uts;
29862 ++ struct ipc_namespace *old_ipc;
29863 ++ struct nsproxy *nsproxy;
29864 ++
29865 ++ nsproxy = copy_nsproxy(old_nsproxy);
29866 ++ if (!nsproxy)
29867 ++ goto out;
29868 ++
29869 ++ if (mask & CLONE_NEWNS) {
29870 ++ old_ns = nsproxy->mnt_ns;
29871 ++ nsproxy->mnt_ns = new_nsproxy->mnt_ns;
29872 ++ if (nsproxy->mnt_ns)
29873 ++ get_mnt_ns(nsproxy->mnt_ns);
29874 ++ } else
29875 ++ old_ns = NULL;
29876 ++
29877 ++ if (mask & CLONE_NEWUTS) {
29878 ++ old_uts = nsproxy->uts_ns;
29879 ++ nsproxy->uts_ns = new_nsproxy->uts_ns;
29880 ++ if (nsproxy->uts_ns)
29881 ++ get_uts_ns(nsproxy->uts_ns);
29882 ++ } else
29883 ++ old_uts = NULL;
29884 ++
29885 ++ if (mask & CLONE_NEWIPC) {
29886 ++ old_ipc = nsproxy->ipc_ns;
29887 ++ nsproxy->ipc_ns = new_nsproxy->ipc_ns;
29888 ++ if (nsproxy->ipc_ns)
29889 ++ get_ipc_ns(nsproxy->ipc_ns);
29890 ++ } else
29891 ++ old_ipc = NULL;
29892 ++
29893 ++ if (old_ns)
29894 ++ put_mnt_ns(old_ns);
29895 ++ if (old_uts)
29896 ++ put_uts_ns(old_uts);
29897 ++ if (old_ipc)
29898 ++ put_ipc_ns(old_ipc);
29899 ++out:
29900 ++ return nsproxy;
29901 ++}
29902 ++
29903 ++
29904 ++/*
29905 ++ * merge two nsproxy structs into a new one.
29906 ++ * will hold a reference on the result.
29907 ++ */
29908 ++
29909 ++static inline
29910 ++struct nsproxy *__vs_merge_nsproxy(struct nsproxy *old,
29911 ++ struct nsproxy *proxy, unsigned long mask)
29912 ++{
29913 ++ struct nsproxy null_proxy = { .mnt_ns = NULL };
29914 ++
29915 ++ if (!proxy)
29916 ++ return NULL;
29917 ++
29918 ++ if (mask) {
29919 ++ /* vs_mix_nsproxy returns with reference */
29920 ++ return vs_mix_nsproxy(old ? old : &null_proxy,
29921 ++ proxy, mask);
29922 ++ }
29923 ++ get_nsproxy(proxy);
29924 ++ return proxy;
29925 ++}
29926 ++
29927 ++/*
29928 ++ * merge two fs structs into a new one.
29929 ++ * will take a reference on the result.
29930 ++ */
29931 ++
29932 ++static inline
29933 ++struct fs_struct *__vs_merge_fs(struct fs_struct *old,
29934 ++ struct fs_struct *fs, unsigned long mask)
29935 ++{
29936 ++ if (!(mask & CLONE_FS)) {
29937 ++ if (old)
29938 ++ atomic_inc(&old->count);
29939 ++ return old;
29940 ++ }
29941 ++
29942 ++ if (!fs)
29943 ++ return NULL;
29944 ++
29945 ++ return copy_fs_struct(fs);
29946 ++}
29947 ++
29948 ++
29949 ++int vx_enter_space(struct vx_info *vxi, unsigned long mask)
29950 ++{
29951 ++ struct nsproxy *proxy, *proxy_cur, *proxy_new;
29952 ++ struct fs_struct *fs, *fs_cur, *fs_new;
29953 ++ int ret;
29954 ++
29955 ++ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
29956 ++ return -EACCES;
29957 ++
29958 ++ if (!mask)
29959 ++ mask = vxi->vx_nsmask;
29960 ++
29961 ++ if ((mask & vxi->vx_nsmask) != mask)
29962 ++ return -EINVAL;
29963 ++
29964 ++ proxy = vxi->vx_nsproxy;
29965 ++ fs = vxi->vx_fs;
29966 ++
29967 ++ task_lock(current);
29968 ++ fs_cur = current->fs;
29969 ++ atomic_inc(&fs_cur->count);
29970 ++ proxy_cur = current->nsproxy;
29971 ++ get_nsproxy(proxy_cur);
29972 ++ task_unlock(current);
29973 ++
29974 ++ fs_new = __vs_merge_fs(fs_cur, fs, mask);
29975 ++ if (IS_ERR(fs_new)) {
29976 ++ ret = PTR_ERR(fs_new);
29977 ++ goto out_put;
29978 ++ }
29979 ++
29980 ++ proxy_new = __vs_merge_nsproxy(proxy_cur, proxy, mask);
29981 ++ if (IS_ERR(proxy_new)) {
29982 ++ ret = PTR_ERR(proxy_new);
29983 ++ goto out_put_fs;
29984 ++ }
29985 ++
29986 ++ fs_new = xchg(&current->fs, fs_new);
29987 ++ proxy_new = xchg(&current->nsproxy, proxy_new);
29988 ++ ret = 0;
29989 ++
29990 ++ if (proxy_new)
29991 ++ put_nsproxy(proxy_new);
29992 ++out_put_fs:
29993 ++ if (fs_new)
29994 ++ put_fs_struct(fs_new);
29995 ++out_put:
29996 ++ if (proxy_cur)
29997 ++ put_nsproxy(proxy_cur);
29998 ++ if (fs_cur)
29999 ++ put_fs_struct(fs_cur);
30000 ++ return ret;
30001 ++}
30002 ++
30003 ++
30004 ++int vx_set_space(struct vx_info *vxi, unsigned long mask)
30005 ++{
30006 ++ struct nsproxy *proxy_vxi, *proxy_cur, *proxy_new;
30007 ++ struct fs_struct *fs_vxi, *fs_cur, *fs_new;
30008 ++ int ret;
30009 ++
30010 ++ if (!mask)
30011 ++ mask = space_mask.mask;
30012 ++
30013 ++ if ((mask & space_mask.mask) != mask)
30014 ++ return -EINVAL;
30015 ++
30016 ++ proxy_vxi = vxi->vx_nsproxy;
30017 ++ fs_vxi = vxi->vx_fs;
30018 ++
30019 ++ task_lock(current);
30020 ++ fs_cur = current->fs;
30021 ++ atomic_inc(&fs_cur->count);
30022 ++ proxy_cur = current->nsproxy;
30023 ++ get_nsproxy(proxy_cur);
30024 ++ task_unlock(current);
30025 ++
30026 ++ fs_new = __vs_merge_fs(fs_vxi, fs_cur, mask);
30027 ++ if (IS_ERR(fs_new)) {
30028 ++ ret = PTR_ERR(fs_new);
30029 ++ goto out_put;
30030 ++ }
30031 ++
30032 ++ proxy_new = __vs_merge_nsproxy(proxy_vxi, proxy_cur, mask);
30033 ++ if (IS_ERR(proxy_new)) {
30034 ++ ret = PTR_ERR(proxy_new);
30035 ++ goto out_put_fs;
30036 ++ }
30037 ++
30038 ++ fs_new = xchg(&vxi->vx_fs, fs_new);
30039 ++ proxy_new = xchg(&vxi->vx_nsproxy, proxy_new);
30040 ++ vxi->vx_nsmask |= mask;
30041 ++ ret = 0;
30042 ++
30043 ++ if (proxy_new)
30044 ++ put_nsproxy(proxy_new);
30045 ++out_put_fs:
30046 ++ if (fs_new)
30047 ++ put_fs_struct(fs_new);
30048 ++out_put:
30049 ++ if (proxy_cur)
30050 ++ put_nsproxy(proxy_cur);
30051 ++ if (fs_cur)
30052 ++ put_fs_struct(fs_cur);
30053 ++ return ret;
30054 ++}
30055 ++
30056 ++
30057 ++int vc_enter_space(struct vx_info *vxi, void __user *data)
30058 ++{
30059 ++ struct vcmd_space_mask vc_data = { .mask = 0 };
30060 ++
30061 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
30062 ++ return -EFAULT;
30063 ++
30064 ++ return vx_enter_space(vxi, vc_data.mask);
30065 ++}
30066 ++
30067 ++int vc_set_space(struct vx_info *vxi, void __user *data)
30068 ++{
30069 ++ struct vcmd_space_mask vc_data = { .mask = 0 };
30070 ++
30071 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
30072 ++ return -EFAULT;
30073 ++
30074 ++ return vx_set_space(vxi, vc_data.mask);
30075 ++}
30076 ++
30077 ++int vc_get_space_mask(struct vx_info *vxi, void __user *data)
30078 ++{
30079 ++ if (copy_to_user(data, &space_mask, sizeof(space_mask)))
30080 ++ return -EFAULT;
30081 ++ return 0;
30082 ++}
30083 ++
30084 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/switch.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/switch.c
30085 +--- linux-2.6.22.19/kernel/vserver/switch.c 1970-01-01 01:00:00 +0100
30086 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/switch.c 2007-10-29 23:34:24 +0100
30087 +@@ -0,0 +1,538 @@
30088 ++/*
30089 ++ * linux/kernel/vserver/switch.c
30090 ++ *
30091 ++ * Virtual Server: Syscall Switch
30092 ++ *
30093 ++ * Copyright (C) 2003-2007 Herbert Pötzl
30094 ++ *
30095 ++ * V0.01 syscall switch
30096 ++ * V0.02 added signal to context
30097 ++ * V0.03 added rlimit functions
30098 ++ * V0.04 added iattr, task/xid functions
30099 ++ * V0.05 added debug/history stuff
30100 ++ * V0.06 added compat32 layer
30101 ++ * V0.07 vcmd args and perms
30102 ++ * V0.08 added status commands
30103 ++ *
30104 ++ */
30105 ++
30106 ++#include <linux/linkage.h>
30107 ++#include <linux/sched.h>
30108 ++#include <linux/compat.h>
30109 ++#include <asm/errno.h>
30110 ++
30111 ++#include <linux/vs_context.h>
30112 ++#include <linux/vs_network.h>
30113 ++#include <linux/vserver/switch.h>
30114 ++
30115 ++#include "vci_config.h"
30116 ++
30117 ++static inline
30118 ++int vc_get_version(uint32_t id)
30119 ++{
30120 ++#ifdef CONFIG_VSERVER_LEGACY_VERSION
30121 ++ if (id == 63)
30122 ++ return VCI_LEGACY_VERSION;
30123 ++#endif
30124 ++ return VCI_VERSION;
30125 ++}
30126 ++
30127 ++static inline
30128 ++int vc_get_vci(uint32_t id)
30129 ++{
30130 ++ return vci_kernel_config();
30131 ++}
30132 ++
30133 ++#include <linux/vserver/context_cmd.h>
30134 ++#include <linux/vserver/cvirt_cmd.h>
30135 ++#include <linux/vserver/cacct_cmd.h>
30136 ++#include <linux/vserver/limit_cmd.h>
30137 ++#include <linux/vserver/network_cmd.h>
30138 ++#include <linux/vserver/sched_cmd.h>
30139 ++#include <linux/vserver/debug_cmd.h>
30140 ++#include <linux/vserver/inode_cmd.h>
30141 ++#include <linux/vserver/dlimit_cmd.h>
30142 ++#include <linux/vserver/signal_cmd.h>
30143 ++#include <linux/vserver/space_cmd.h>
30144 ++
30145 ++#include <linux/vserver/legacy.h>
30146 ++#include <linux/vserver/inode.h>
30147 ++#include <linux/vserver/dlimit.h>
30148 ++
30149 ++
30150 ++#ifdef CONFIG_COMPAT
30151 ++#define __COMPAT(name, id, data, compat) \
30152 ++ (compat) ? name ## _x32(id, data) : name(id, data)
30153 ++#define __COMPAT_NO_ID(name, data, compat) \
30154 ++ (compat) ? name ## _x32(data) : name(data)
30155 ++#else
30156 ++#define __COMPAT(name, id, data, compat) \
30157 ++ name(id, data)
30158 ++#define __COMPAT_NO_ID(name, data, compat) \
30159 ++ name(data)
30160 ++#endif
30161 ++
30162 ++
30163 ++static inline
30164 ++long do_vcmd(uint32_t cmd, uint32_t id,
30165 ++ struct vx_info *vxi, struct nx_info *nxi,
30166 ++ void __user *data, int compat)
30167 ++{
30168 ++ switch (cmd) {
30169 ++
30170 ++ case VCMD_get_version:
30171 ++ return vc_get_version(id);
30172 ++ case VCMD_get_vci:
30173 ++ return vc_get_vci(id);
30174 ++
30175 ++ case VCMD_task_xid:
30176 ++ return vc_task_xid(id, data);
30177 ++ case VCMD_vx_info:
30178 ++ return vc_vx_info(vxi, data);
30179 ++
30180 ++ case VCMD_task_nid:
30181 ++ return vc_task_nid(id, data);
30182 ++ case VCMD_nx_info:
30183 ++ return vc_nx_info(nxi, data);
30184 ++
30185 ++ case VCMD_set_space_v0:
30186 ++ /* this is version 1 */
30187 ++ case VCMD_set_space:
30188 ++ return vc_set_space(vxi, data);
30189 ++
30190 ++ case VCMD_get_space_mask:
30191 ++ return vc_get_space_mask(vxi, data);
30192 ++
30193 ++#ifdef CONFIG_IA32_EMULATION
30194 ++ case VCMD_get_rlimit:
30195 ++ return __COMPAT(vc_get_rlimit, vxi, data, compat);
30196 ++ case VCMD_set_rlimit:
30197 ++ return __COMPAT(vc_set_rlimit, vxi, data, compat);
30198 ++#else
30199 ++ case VCMD_get_rlimit:
30200 ++ return vc_get_rlimit(vxi, data);
30201 ++ case VCMD_set_rlimit:
30202 ++ return vc_set_rlimit(vxi, data);
30203 ++#endif
30204 ++ case VCMD_get_rlimit_mask:
30205 ++ return vc_get_rlimit_mask(id, data);
30206 ++ case VCMD_reset_minmax:
30207 ++ return vc_reset_minmax(vxi, data);
30208 ++
30209 ++ case VCMD_get_vhi_name:
30210 ++ return vc_get_vhi_name(vxi, data);
30211 ++ case VCMD_set_vhi_name:
30212 ++ return vc_set_vhi_name(vxi, data);
30213 ++
30214 ++ case VCMD_ctx_stat:
30215 ++ return vc_ctx_stat(vxi, data);
30216 ++ case VCMD_virt_stat:
30217 ++ return vc_virt_stat(vxi, data);
30218 ++ case VCMD_sock_stat:
30219 ++ return vc_sock_stat(vxi, data);
30220 ++ case VCMD_rlimit_stat:
30221 ++ return vc_rlimit_stat(vxi, data);
30222 ++
30223 ++ case VCMD_set_cflags:
30224 ++ return vc_set_cflags(vxi, data);
30225 ++ case VCMD_get_cflags:
30226 ++ return vc_get_cflags(vxi, data);
30227 ++
30228 ++ case VCMD_set_ccaps_v0:
30229 ++ return vc_set_ccaps_v0(vxi, data);
30230 ++ /* this is version 1 */
30231 ++ case VCMD_set_ccaps:
30232 ++ return vc_set_ccaps(vxi, data);
30233 ++ case VCMD_get_ccaps_v0:
30234 ++ return vc_get_ccaps_v0(vxi, data);
30235 ++ /* this is version 1 */
30236 ++ case VCMD_get_ccaps:
30237 ++ return vc_get_ccaps(vxi, data);
30238 ++ case VCMD_set_bcaps:
30239 ++ return vc_set_bcaps(vxi, data);
30240 ++ case VCMD_get_bcaps:
30241 ++ return vc_get_bcaps(vxi, data);
30242 ++
30243 ++ case VCMD_set_nflags:
30244 ++ return vc_set_nflags(nxi, data);
30245 ++ case VCMD_get_nflags:
30246 ++ return vc_get_nflags(nxi, data);
30247 ++
30248 ++ case VCMD_set_ncaps:
30249 ++ return vc_set_ncaps(nxi, data);
30250 ++ case VCMD_get_ncaps:
30251 ++ return vc_get_ncaps(nxi, data);
30252 ++
30253 ++#ifdef CONFIG_VSERVER_LEGACY
30254 ++ case VCMD_set_sched_v2:
30255 ++ return vc_set_sched_v2(vxi, data);
30256 ++#endif
30257 ++ case VCMD_set_sched_v3:
30258 ++ return vc_set_sched_v3(vxi, data);
30259 ++ case VCMD_set_sched_v4:
30260 ++ return vc_set_sched_v4(vxi, data);
30261 ++ /* this is version 5 */
30262 ++ case VCMD_set_sched:
30263 ++ return vc_set_sched(vxi, data);
30264 ++ case VCMD_get_sched:
30265 ++ return vc_get_sched(vxi, data);
30266 ++ case VCMD_sched_info:
30267 ++ return vc_sched_info(vxi, data);
30268 ++
30269 ++ case VCMD_add_dlimit:
30270 ++ return __COMPAT(vc_add_dlimit, id, data, compat);
30271 ++ case VCMD_rem_dlimit:
30272 ++ return __COMPAT(vc_rem_dlimit, id, data, compat);
30273 ++ case VCMD_set_dlimit:
30274 ++ return __COMPAT(vc_set_dlimit, id, data, compat);
30275 ++ case VCMD_get_dlimit:
30276 ++ return __COMPAT(vc_get_dlimit, id, data, compat);
30277 ++
30278 ++ case VCMD_ctx_kill:
30279 ++ return vc_ctx_kill(vxi, data);
30280 ++
30281 ++ case VCMD_wait_exit:
30282 ++ return vc_wait_exit(vxi, data);
30283 ++
30284 ++#ifdef CONFIG_VSERVER_LEGACY
30285 ++ case VCMD_create_context:
30286 ++ return vc_ctx_create(id, NULL);
30287 ++#endif
30288 ++
30289 ++ case VCMD_get_iattr:
30290 ++ return __COMPAT_NO_ID(vc_get_iattr, data, compat);
30291 ++ case VCMD_set_iattr:
30292 ++ return __COMPAT_NO_ID(vc_set_iattr, data, compat);
30293 ++
30294 ++ case VCMD_fget_iattr:
30295 ++ return vc_fget_iattr(id, data);
30296 ++ case VCMD_fset_iattr:
30297 ++ return vc_fset_iattr(id, data);
30298 ++
30299 ++ case VCMD_enter_space_v0:
30300 ++ return vc_enter_space(vxi, NULL);
30301 ++ /* this is version 1 */
30302 ++ case VCMD_enter_space:
30303 ++ return vc_enter_space(vxi, data);
30304 ++
30305 ++ case VCMD_ctx_create_v0:
30306 ++ return vc_ctx_create(id, NULL);
30307 ++ case VCMD_ctx_create:
30308 ++ return vc_ctx_create(id, data);
30309 ++ case VCMD_ctx_migrate_v0:
30310 ++ return vc_ctx_migrate(vxi, NULL);
30311 ++ case VCMD_ctx_migrate:
30312 ++ return vc_ctx_migrate(vxi, data);
30313 ++
30314 ++ case VCMD_net_create_v0:
30315 ++ return vc_net_create(id, NULL);
30316 ++ case VCMD_net_create:
30317 ++ return vc_net_create(id, data);
30318 ++ case VCMD_net_migrate:
30319 ++ return vc_net_migrate(nxi, data);
30320 ++ case VCMD_net_add:
30321 ++ return vc_net_add(nxi, data);
30322 ++ case VCMD_net_remove:
30323 ++ return vc_net_remove(nxi, data);
30324 ++
30325 ++#ifdef CONFIG_VSERVER_HISTORY
30326 ++ case VCMD_dump_history:
30327 ++ return vc_dump_history(id);
30328 ++ case VCMD_read_history:
30329 ++ return __COMPAT(vc_read_history, id, data, compat);
30330 ++#endif
30331 ++#ifdef CONFIG_VSERVER_MONITOR
30332 ++ case VCMD_read_monitor:
30333 ++ return __COMPAT(vc_read_monitor, id, data, compat);
30334 ++#endif
30335 ++#ifdef CONFIG_VSERVER_LEGACY
30336 ++ case VCMD_new_s_context:
30337 ++ return vc_new_s_context(id, data);
30338 ++#endif
30339 ++#ifdef CONFIG_VSERVER_LEGACYNET
30340 ++ case VCMD_set_ipv4root:
30341 ++ return vc_set_ipv4root(id, data);
30342 ++#endif
30343 ++ default:
30344 ++ vxwprintk_task(1, "unimplemented VCMD_%02d_%d[%d]",
30345 ++ VC_CATEGORY(cmd), VC_COMMAND(cmd), VC_VERSION(cmd));
30346 ++ }
30347 ++ return -ENOSYS;
30348 ++}
30349 ++
30350 ++
30351 ++#define __VCMD(vcmd, _perm, _args, _flags) \
30352 ++ case VCMD_ ## vcmd: perm = _perm; \
30353 ++ args = _args; flags = _flags; break
30354 ++
30355 ++
30356 ++#define VCA_NONE 0x00
30357 ++#define VCA_VXI 0x01
30358 ++#define VCA_NXI 0x02
30359 ++
30360 ++#define VCF_NONE 0x00
30361 ++#define VCF_INFO 0x01
30362 ++#define VCF_ADMIN 0x02
30363 ++#define VCF_ARES 0x06 /* includes admin */
30364 ++#define VCF_SETUP 0x08
30365 ++
30366 ++#define VCF_ZIDOK 0x10 /* zero id okay */
30367 ++
30368 ++
30369 ++static inline
30370 ++long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
30371 ++{
30372 ++ long ret;
30373 ++ int permit = -1, state = 0;
30374 ++ int perm = -1, args = 0, flags = 0;
30375 ++ struct vx_info *vxi = NULL;
30376 ++ struct nx_info *nxi = NULL;
30377 ++
30378 ++ switch (cmd) {
30379 ++ /* unpriviledged commands */
30380 ++ __VCMD(get_version, 0, VCA_NONE, 0);
30381 ++ __VCMD(get_vci, 0, VCA_NONE, 0);
30382 ++ __VCMD(get_rlimit_mask, 0, VCA_NONE, 0);
30383 ++ __VCMD(get_space_mask, 0, VCA_NONE, 0);
30384 ++
30385 ++ /* info commands */
30386 ++ __VCMD(task_xid, 2, VCA_NONE, 0);
30387 ++ __VCMD(reset_minmax, 2, VCA_VXI, 0);
30388 ++ __VCMD(vx_info, 3, VCA_VXI, VCF_INFO);
30389 ++ __VCMD(get_bcaps, 3, VCA_VXI, VCF_INFO);
30390 ++ __VCMD(get_ccaps_v0, 3, VCA_VXI, VCF_INFO);
30391 ++ __VCMD(get_ccaps, 3, VCA_VXI, VCF_INFO);
30392 ++ __VCMD(get_cflags, 3, VCA_VXI, VCF_INFO);
30393 ++ __VCMD(get_vhi_name, 3, VCA_VXI, VCF_INFO);
30394 ++ __VCMD(get_rlimit, 3, VCA_VXI, VCF_INFO);
30395 ++
30396 ++ __VCMD(ctx_stat, 3, VCA_VXI, VCF_INFO);
30397 ++ __VCMD(virt_stat, 3, VCA_VXI, VCF_INFO);
30398 ++ __VCMD(sock_stat, 3, VCA_VXI, VCF_INFO);
30399 ++ __VCMD(rlimit_stat, 3, VCA_VXI, VCF_INFO);
30400 ++
30401 ++ __VCMD(task_nid, 2, VCA_NONE, 0);
30402 ++ __VCMD(nx_info, 3, VCA_NXI, VCF_INFO);
30403 ++ __VCMD(get_ncaps, 3, VCA_NXI, VCF_INFO);
30404 ++ __VCMD(get_nflags, 3, VCA_NXI, VCF_INFO);
30405 ++
30406 ++ __VCMD(get_iattr, 2, VCA_NONE, 0);
30407 ++ __VCMD(fget_iattr, 2, VCA_NONE, 0);
30408 ++ __VCMD(get_dlimit, 3, VCA_NONE, VCF_INFO);
30409 ++ __VCMD(get_sched, 3, VCA_VXI, VCF_INFO);
30410 ++ __VCMD(sched_info, 3, VCA_VXI, VCF_INFO | VCF_ZIDOK);
30411 ++
30412 ++ /* lower admin commands */
30413 ++ __VCMD(wait_exit, 4, VCA_VXI, VCF_INFO);
30414 ++ __VCMD(ctx_create_v0, 5, VCA_NONE, 0);
30415 ++ __VCMD(ctx_create, 5, VCA_NONE, 0);
30416 ++ __VCMD(ctx_migrate_v0, 5, VCA_VXI, VCF_ADMIN);
30417 ++ __VCMD(ctx_migrate, 5, VCA_VXI, VCF_ADMIN);
30418 ++ __VCMD(enter_space_v0, 5, VCA_VXI, VCF_ADMIN);
30419 ++ __VCMD(enter_space, 5, VCA_VXI, VCF_ADMIN);
30420 ++
30421 ++ __VCMD(net_create_v0, 5, VCA_NONE, 0);
30422 ++ __VCMD(net_create, 5, VCA_NONE, 0);
30423 ++ __VCMD(net_migrate, 5, VCA_NXI, VCF_ADMIN);
30424 ++
30425 ++ /* higher admin commands */
30426 ++ __VCMD(ctx_kill, 6, VCA_VXI, VCF_ARES);
30427 ++ __VCMD(set_space_v0, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
30428 ++ __VCMD(set_space, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
30429 ++
30430 ++ __VCMD(set_ccaps_v0, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
30431 ++ __VCMD(set_ccaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
30432 ++ __VCMD(set_bcaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
30433 ++ __VCMD(set_cflags, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
30434 ++
30435 ++ __VCMD(set_vhi_name, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
30436 ++ __VCMD(set_rlimit, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
30437 ++ __VCMD(set_sched, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
30438 ++ __VCMD(set_sched_v2, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
30439 ++ __VCMD(set_sched_v3, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
30440 ++ __VCMD(set_sched_v4, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
30441 ++
30442 ++ __VCMD(set_ncaps, 7, VCA_NXI, VCF_ARES | VCF_SETUP);
30443 ++ __VCMD(set_nflags, 7, VCA_NXI, VCF_ARES | VCF_SETUP);
30444 ++ __VCMD(net_add, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
30445 ++ __VCMD(net_remove, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
30446 ++
30447 ++ __VCMD(set_iattr, 7, VCA_NONE, 0);
30448 ++ __VCMD(fset_iattr, 7, VCA_NONE, 0);
30449 ++ __VCMD(set_dlimit, 7, VCA_NONE, VCF_ARES);
30450 ++ __VCMD(add_dlimit, 8, VCA_NONE, VCF_ARES);
30451 ++ __VCMD(rem_dlimit, 8, VCA_NONE, VCF_ARES);
30452 ++
30453 ++ /* debug level admin commands */
30454 ++#ifdef CONFIG_VSERVER_HISTORY
30455 ++ __VCMD(dump_history, 9, VCA_NONE, 0);
30456 ++ __VCMD(read_history, 9, VCA_NONE, 0);
30457 ++#endif
30458 ++#ifdef CONFIG_VSERVER_MONITOR
30459 ++ __VCMD(read_monitor, 9, VCA_NONE, 0);
30460 ++#endif
30461 ++
30462 ++ /* legacy commands */
30463 ++#ifdef CONFIG_VSERVER_LEGACY
30464 ++ __VCMD(new_s_context, 1, VCA_NONE, 0);
30465 ++ __VCMD(create_context, 5, VCA_NONE, 0);
30466 ++#endif
30467 ++#ifdef CONFIG_VSERVER_LEGACYNET
30468 ++ __VCMD(set_ipv4root, 5, VCA_NONE, 0);
30469 ++#endif
30470 ++ default:
30471 ++ perm = -1;
30472 ++ }
30473 ++
30474 ++ vxdprintk(VXD_CBIT(switch, 0),
30475 ++ "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]",
30476 ++ VC_CATEGORY(cmd), VC_COMMAND(cmd),
30477 ++ VC_VERSION(cmd), id, data, compat,
30478 ++ perm, args, flags);
30479 ++
30480 ++ ret = -ENOSYS;
30481 ++ if (perm < 0)
30482 ++ goto out;
30483 ++
30484 ++ state = 1;
30485 ++#ifdef CONFIG_VSERVER_LEGACY
30486 ++ if (!capable(CAP_CONTEXT) &&
30487 ++ /* dirty hack for capremove */
30488 ++ !(cmd == VCMD_new_s_context && id == -2))
30489 ++ goto out;
30490 ++#else
30491 ++ if (!capable(CAP_CONTEXT))
30492 ++ goto out;
30493 ++#endif
30494 ++
30495 ++ state = 2;
30496 ++ /* moved here from the individual commands */
30497 ++ ret = -EPERM;
30498 ++ if ((perm > 1) && !capable(CAP_SYS_ADMIN))
30499 ++ goto out;
30500 ++
30501 ++ state = 3;
30502 ++ /* vcmd involves resource management */
30503 ++ ret = -EPERM;
30504 ++ if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE))
30505 ++ goto out;
30506 ++
30507 ++ state = 4;
30508 ++ /* various legacy exceptions */
30509 ++ switch (cmd) {
30510 ++#ifdef CONFIG_VSERVER_LEGACY
30511 ++ case VCMD_set_cflags:
30512 ++ case VCMD_set_ccaps_v0:
30513 ++ ret = 0;
30514 ++ if (vx_check(0, VS_WATCH))
30515 ++ goto out;
30516 ++ break;
30517 ++
30518 ++ case VCMD_ctx_create_v0:
30519 ++#endif
30520 ++ /* will go away when spectator is a cap */
30521 ++ case VCMD_ctx_migrate_v0:
30522 ++ case VCMD_ctx_migrate:
30523 ++ if (id == 1) {
30524 ++ current->xid = 1;
30525 ++ ret = 1;
30526 ++ goto out;
30527 ++ }
30528 ++ break;
30529 ++
30530 ++ /* will go away when spectator is a cap */
30531 ++ case VCMD_net_migrate:
30532 ++ if (id == 1) {
30533 ++ current->nid = 1;
30534 ++ ret = 1;
30535 ++ goto out;
30536 ++ }
30537 ++ break;
30538 ++
30539 ++ /* legacy special casing */
30540 ++ case VCMD_set_space_v0:
30541 ++ id = -1;
30542 ++ break;
30543 ++ }
30544 ++
30545 ++ /* vcmds are fine by default */
30546 ++ permit = 1;
30547 ++
30548 ++ /* admin type vcmds require admin ... */
30549 ++ if (flags & VCF_ADMIN)
30550 ++ permit = vx_check(0, VS_ADMIN) ? 1 : 0;
30551 ++
30552 ++ /* ... but setup type vcmds override that */
30553 ++ if (!permit && (flags & VCF_SETUP))
30554 ++ permit = vx_flags(VXF_STATE_SETUP, 0) ? 2 : 0;
30555 ++
30556 ++ state = 5;
30557 ++ ret = -EPERM;
30558 ++ if (!permit)
30559 ++ goto out;
30560 ++
30561 ++ state = 6;
30562 ++ if (!id && (flags & VCF_ZIDOK))
30563 ++ goto skip_id;
30564 ++
30565 ++ ret = -ESRCH;
30566 ++ if (args & VCA_VXI) {
30567 ++ vxi = lookup_vx_info(id);
30568 ++ if (!vxi)
30569 ++ goto out;
30570 ++
30571 ++ if ((flags & VCF_ADMIN) &&
30572 ++ /* special case kill for shutdown */
30573 ++ (cmd != VCMD_ctx_kill) &&
30574 ++ /* can context be administrated? */
30575 ++ !vx_info_flags(vxi, VXF_STATE_ADMIN, 0)) {
30576 ++ ret = -EACCES;
30577 ++ goto out_vxi;
30578 ++ }
30579 ++ }
30580 ++ state = 7;
30581 ++ if (args & VCA_NXI) {
30582 ++ nxi = lookup_nx_info(id);
30583 ++ if (!nxi)
30584 ++ goto out_vxi;
30585 ++
30586 ++ if ((flags & VCF_ADMIN) &&
30587 ++ /* can context be administrated? */
30588 ++ !nx_info_flags(nxi, NXF_STATE_ADMIN, 0)) {
30589 ++ ret = -EACCES;
30590 ++ goto out_nxi;
30591 ++ }
30592 ++ }
30593 ++skip_id:
30594 ++ state = 8;
30595 ++ ret = do_vcmd(cmd, id, vxi, nxi, data, compat);
30596 ++
30597 ++out_nxi:
30598 ++ if ((args & VCA_NXI) && nxi)
30599 ++ put_nx_info(nxi);
30600 ++out_vxi:
30601 ++ if ((args & VCA_VXI) && vxi)
30602 ++ put_vx_info(vxi);
30603 ++out:
30604 ++ vxdprintk(VXD_CBIT(switch, 1),
30605 ++ "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]",
30606 ++ VC_CATEGORY(cmd), VC_COMMAND(cmd),
30607 ++ VC_VERSION(cmd), ret, ret, state, permit);
30608 ++ return ret;
30609 ++}
30610 ++
30611 ++asmlinkage long
30612 ++sys_vserver(uint32_t cmd, uint32_t id, void __user *data)
30613 ++{
30614 ++ return do_vserver(cmd, id, data, 0);
30615 ++}
30616 ++
30617 ++#ifdef CONFIG_COMPAT
30618 ++
30619 ++asmlinkage long
30620 ++sys32_vserver(uint32_t cmd, uint32_t id, void __user *data)
30621 ++{
30622 ++ return do_vserver(cmd, id, data, 1);
30623 ++}
30624 ++
30625 ++#endif /* CONFIG_COMPAT */
30626 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/sysctl.c linux-2.6.22.19-vs2.2.0.7/kernel/vserver/sysctl.c
30627 +--- linux-2.6.22.19/kernel/vserver/sysctl.c 1970-01-01 01:00:00 +0100
30628 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/sysctl.c 2007-06-16 05:31:20 +0200
30629 +@@ -0,0 +1,248 @@
30630 ++/*
30631 ++ * kernel/vserver/sysctl.c
30632 ++ *
30633 ++ * Virtual Context Support
30634 ++ *
30635 ++ * Copyright (C) 2004-2007 Herbert Pötzl
30636 ++ *
30637 ++ * V0.01 basic structure
30638 ++ *
30639 ++ */
30640 ++
30641 ++#include <linux/errno.h>
30642 ++#include <linux/module.h>
30643 ++#include <linux/types.h>
30644 ++#include <linux/ctype.h>
30645 ++#include <linux/sysctl.h>
30646 ++#include <linux/parser.h>
30647 ++#include <linux/fs.h>
30648 ++
30649 ++#include <asm/uaccess.h>
30650 ++#include <asm/unistd.h>
30651 ++
30652 ++
30653 ++#define CTL_VSERVER 4242 /* unused? */
30654 ++
30655 ++enum {
30656 ++ CTL_DEBUG_ERROR = 0,
30657 ++ CTL_DEBUG_SWITCH = 1,
30658 ++ CTL_DEBUG_XID,
30659 ++ CTL_DEBUG_NID,
30660 ++ CTL_DEBUG_TAG,
30661 ++ CTL_DEBUG_NET,
30662 ++ CTL_DEBUG_LIMIT,
30663 ++ CTL_DEBUG_CRES,
30664 ++ CTL_DEBUG_DLIM,
30665 ++ CTL_DEBUG_QUOTA,
30666 ++ CTL_DEBUG_CVIRT,
30667 ++ CTL_DEBUG_SPACE,
30668 ++ CTL_DEBUG_MISC,
30669 ++};
30670 ++
30671 ++
30672 ++unsigned int vx_debug_switch = 0;
30673 ++unsigned int vx_debug_xid = 0;
30674 ++unsigned int vx_debug_nid = 0;
30675 ++unsigned int vx_debug_tag = 0;
30676 ++unsigned int vx_debug_net = 0;
30677 ++unsigned int vx_debug_limit = 0;
30678 ++unsigned int vx_debug_cres = 0;
30679 ++unsigned int vx_debug_dlim = 0;
30680 ++unsigned int vx_debug_quota = 0;
30681 ++unsigned int vx_debug_cvirt = 0;
30682 ++unsigned int vx_debug_space = 0;
30683 ++unsigned int vx_debug_misc = 0;
30684 ++
30685 ++
30686 ++static struct ctl_table_header *vserver_table_header;
30687 ++static ctl_table vserver_table[];
30688 ++
30689 ++
30690 ++void vserver_register_sysctl(void)
30691 ++{
30692 ++ if (!vserver_table_header) {
30693 ++ vserver_table_header = register_sysctl_table(vserver_table);
30694 ++ }
30695 ++
30696 ++}
30697 ++
30698 ++void vserver_unregister_sysctl(void)
30699 ++{
30700 ++ if (vserver_table_header) {
30701 ++ unregister_sysctl_table(vserver_table_header);
30702 ++ vserver_table_header = NULL;
30703 ++ }
30704 ++}
30705 ++
30706 ++
30707 ++static int proc_dodebug(ctl_table *table, int write,
30708 ++ struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
30709 ++{
30710 ++ char tmpbuf[20], *p, c;
30711 ++ unsigned int value;
30712 ++ size_t left, len;
30713 ++
30714 ++ if ((*ppos && !write) || !*lenp) {
30715 ++ *lenp = 0;
30716 ++ return 0;
30717 ++ }
30718 ++
30719 ++ left = *lenp;
30720 ++
30721 ++ if (write) {
30722 ++ if (!access_ok(VERIFY_READ, buffer, left))
30723 ++ return -EFAULT;
30724 ++ p = (char *)buffer;
30725 ++ while (left && __get_user(c, p) >= 0 && isspace(c))
30726 ++ left--, p++;
30727 ++ if (!left)
30728 ++ goto done;
30729 ++
30730 ++ if (left > sizeof(tmpbuf) - 1)
30731 ++ return -EINVAL;
30732 ++ if (copy_from_user(tmpbuf, p, left))
30733 ++ return -EFAULT;
30734 ++ tmpbuf[left] = '\0';
30735 ++
30736 ++ for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
30737 ++ value = 10 * value + (*p - '0');
30738 ++ if (*p && !isspace(*p))
30739 ++ return -EINVAL;
30740 ++ while (left && isspace(*p))
30741 ++ left--, p++;
30742 ++ *(unsigned int *)table->data = value;
30743 ++ } else {
30744 ++ if (!access_ok(VERIFY_WRITE, buffer, left))
30745 ++ return -EFAULT;
30746 ++ len = sprintf(tmpbuf, "%d", *(unsigned int *)table->data);
30747 ++ if (len > left)
30748 ++ len = left;
30749 ++ if (__copy_to_user(buffer, tmpbuf, len))
30750 ++ return -EFAULT;
30751 ++ if ((left -= len) > 0) {
30752 ++ if (put_user('\n', (char *)buffer + len))
30753 ++ return -EFAULT;
30754 ++ left--;
30755 ++ }
30756 ++ }
30757 ++
30758 ++done:
30759 ++ *lenp -= left;
30760 ++ *ppos += *lenp;
30761 ++ return 0;
30762 ++}
30763 ++
30764 ++
30765 ++#define CTL_ENTRY(ctl, name) \
30766 ++ { \
30767 ++ .ctl_name = ctl, \
30768 ++ .procname = #name, \
30769 ++ .data = &vx_ ## name, \
30770 ++ .maxlen = sizeof(int), \
30771 ++ .mode = 0644, \
30772 ++ .proc_handler = &proc_dodebug \
30773 ++ }
30774 ++
30775 ++static ctl_table debug_table[] = {
30776 ++ CTL_ENTRY(CTL_DEBUG_SWITCH, debug_switch),
30777 ++ CTL_ENTRY(CTL_DEBUG_XID, debug_xid),
30778 ++ CTL_ENTRY(CTL_DEBUG_NID, debug_nid),
30779 ++ CTL_ENTRY(CTL_DEBUG_TAG, debug_tag),
30780 ++ CTL_ENTRY(CTL_DEBUG_NET, debug_net),
30781 ++ CTL_ENTRY(CTL_DEBUG_LIMIT, debug_limit),
30782 ++ CTL_ENTRY(CTL_DEBUG_CRES, debug_cres),
30783 ++ CTL_ENTRY(CTL_DEBUG_DLIM, debug_dlim),
30784 ++ CTL_ENTRY(CTL_DEBUG_QUOTA, debug_quota),
30785 ++ CTL_ENTRY(CTL_DEBUG_CVIRT, debug_cvirt),
30786 ++ CTL_ENTRY(CTL_DEBUG_SPACE, debug_space),
30787 ++ CTL_ENTRY(CTL_DEBUG_MISC, debug_misc),
30788 ++ { .ctl_name = 0 }
30789 ++};
30790 ++
30791 ++static ctl_table vserver_table[] = {
30792 ++ {
30793 ++ .ctl_name = CTL_VSERVER,
30794 ++ .procname = "vserver",
30795 ++ .mode = 0555,
30796 ++ .child = debug_table
30797 ++ },
30798 ++ { .ctl_name = 0 }
30799 ++};
30800 ++
30801 ++
30802 ++static match_table_t tokens = {
30803 ++ { CTL_DEBUG_SWITCH, "switch=%x" },
30804 ++ { CTL_DEBUG_XID, "xid=%x" },
30805 ++ { CTL_DEBUG_NID, "nid=%x" },
30806 ++ { CTL_DEBUG_TAG, "tag=%x" },
30807 ++ { CTL_DEBUG_NET, "net=%x" },
30808 ++ { CTL_DEBUG_LIMIT, "limit=%x" },
30809 ++ { CTL_DEBUG_CRES, "cres=%x" },
30810 ++ { CTL_DEBUG_DLIM, "dlim=%x" },
30811 ++ { CTL_DEBUG_QUOTA, "quota=%x" },
30812 ++ { CTL_DEBUG_CVIRT, "cvirt=%x" },
30813 ++ { CTL_DEBUG_SPACE, "space=%x" },
30814 ++ { CTL_DEBUG_MISC, "misc=%x" },
30815 ++ { CTL_DEBUG_ERROR, NULL }
30816 ++};
30817 ++
30818 ++#define HANDLE_CASE(id, name, val) \
30819 ++ case CTL_DEBUG_ ## id: \
30820 ++ vx_debug_ ## name = val; \
30821 ++ printk("vs_debug_" #name "=0x%x\n", val); \
30822 ++ break
30823 ++
30824 ++
30825 ++static int __init vs_debug_setup(char *str)
30826 ++{
30827 ++ char *p;
30828 ++ int token;
30829 ++
30830 ++ printk("vs_debug_setup(%s)\n", str);
30831 ++ while ((p = strsep(&str, ",")) != NULL) {
30832 ++ substring_t args[MAX_OPT_ARGS];
30833 ++ unsigned int value;
30834 ++
30835 ++ if (!*p)
30836 ++ continue;
30837 ++
30838 ++ token = match_token(p, tokens, args);
30839 ++ value = (token > 0) ? simple_strtoul(args[0].from, NULL, 0) : 0;
30840 ++
30841 ++ switch (token) {
30842 ++ HANDLE_CASE(SWITCH, switch, value);
30843 ++ HANDLE_CASE(XID, xid, value);
30844 ++ HANDLE_CASE(NID, nid, value);
30845 ++ HANDLE_CASE(TAG, tag, value);
30846 ++ HANDLE_CASE(NET, net, value);
30847 ++ HANDLE_CASE(LIMIT, limit, value);
30848 ++ HANDLE_CASE(CRES, cres, value);
30849 ++ HANDLE_CASE(DLIM, dlim, value);
30850 ++ HANDLE_CASE(QUOTA, quota, value);
30851 ++ HANDLE_CASE(CVIRT, cvirt, value);
30852 ++ HANDLE_CASE(SPACE, space, value);
30853 ++ HANDLE_CASE(MISC, misc, value);
30854 ++ default:
30855 ++ return -EINVAL;
30856 ++ break;
30857 ++ }
30858 ++ }
30859 ++ return 1;
30860 ++}
30861 ++
30862 ++__setup("vsdebug=", vs_debug_setup);
30863 ++
30864 ++
30865 ++
30866 ++EXPORT_SYMBOL_GPL(vx_debug_switch);
30867 ++EXPORT_SYMBOL_GPL(vx_debug_xid);
30868 ++EXPORT_SYMBOL_GPL(vx_debug_nid);
30869 ++EXPORT_SYMBOL_GPL(vx_debug_net);
30870 ++EXPORT_SYMBOL_GPL(vx_debug_limit);
30871 ++EXPORT_SYMBOL_GPL(vx_debug_cres);
30872 ++EXPORT_SYMBOL_GPL(vx_debug_dlim);
30873 ++EXPORT_SYMBOL_GPL(vx_debug_quota);
30874 ++EXPORT_SYMBOL_GPL(vx_debug_cvirt);
30875 ++EXPORT_SYMBOL_GPL(vx_debug_space);
30876 ++EXPORT_SYMBOL_GPL(vx_debug_misc);
30877 ++
30878 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/vci_config.h linux-2.6.22.19-vs2.2.0.7/kernel/vserver/vci_config.h
30879 +--- linux-2.6.22.19/kernel/vserver/vci_config.h 1970-01-01 01:00:00 +0100
30880 ++++ linux-2.6.22.19-vs2.2.0.7/kernel/vserver/vci_config.h 2007-06-15 02:37:04 +0200
30881 +@@ -0,0 +1,92 @@
30882 ++
30883 ++/* interface version */
30884 ++
30885 ++#define VCI_VERSION 0x00020200
30886 ++#define VCI_LEGACY_VERSION 0x000100FF
30887 ++
30888 ++
30889 ++enum {
30890 ++ VCI_KCBIT_NO_DYNAMIC = 0,
30891 ++ VCI_KCBIT_LEGACY = 1,
30892 ++ VCI_KCBIT_LEGACYNET = 2,
30893 ++ VCI_KCBIT_NGNET = 3,
30894 ++
30895 ++ VCI_KCBIT_PROC_SECURE = 4,
30896 ++ VCI_KCBIT_HARDCPU = 5,
30897 ++ VCI_KCBIT_IDLELIMIT = 6,
30898 ++ VCI_KCBIT_IDLETIME = 7,
30899 ++
30900 ++ VCI_KCBIT_COWBL = 8,
30901 ++ VCI_KCBIT_FULLCOWBL = 9,
30902 ++ VCI_KCBIT_SPACES = 10,
30903 ++
30904 ++ VCI_KCBIT_LEGACY_VERSION = 15,
30905 ++ VCI_KCBIT_DEBUG = 16,
30906 ++ VCI_KCBIT_HISTORY = 20,
30907 ++ VCI_KCBIT_TAGGED = 24,
30908 ++};
30909 ++
30910 ++
30911 ++static inline uint32_t vci_kernel_config(void)
30912 ++{
30913 ++ return
30914 ++ /* various legacy options */
30915 ++#ifndef CONFIG_VSERVER_DYNAMIC_IDS
30916 ++ (1 << VCI_KCBIT_NO_DYNAMIC) |
30917 ++#endif
30918 ++#ifdef CONFIG_VSERVER_LEGACY
30919 ++ (1 << VCI_KCBIT_LEGACY) |
30920 ++#endif
30921 ++#ifdef CONFIG_VSERVER_LEGACYNET
30922 ++ (1 << VCI_KCBIT_LEGACYNET) |
30923 ++#endif
30924 ++#ifdef CONFIG_VSERVER_LEGACY_VERSION
30925 ++ (1 << VCI_KCBIT_LEGACY_VERSION) |
30926 ++#endif
30927 ++
30928 ++ /* configured features */
30929 ++#ifdef CONFIG_VSERVER_PROC_SECURE
30930 ++ (1 << VCI_KCBIT_PROC_SECURE) |
30931 ++#endif
30932 ++#ifdef CONFIG_VSERVER_HARDCPU
30933 ++ (1 << VCI_KCBIT_HARDCPU) |
30934 ++#endif
30935 ++#ifdef CONFIG_VSERVER_IDLELIMIT
30936 ++ (1 << VCI_KCBIT_IDLELIMIT) |
30937 ++#endif
30938 ++#ifdef CONFIG_VSERVER_IDLETIME
30939 ++ (1 << VCI_KCBIT_IDLETIME) |
30940 ++#endif
30941 ++#ifdef CONFIG_VSERVER_COWBL
30942 ++ (1 << VCI_KCBIT_COWBL) |
30943 ++ (1 << VCI_KCBIT_FULLCOWBL) |
30944 ++#endif
30945 ++ (1 << VCI_KCBIT_SPACES) |
30946 ++
30947 ++ /* debug options */
30948 ++#ifdef CONFIG_VSERVER_DEBUG
30949 ++ (1 << VCI_KCBIT_DEBUG) |
30950 ++#endif
30951 ++#ifdef CONFIG_VSERVER_HISTORY
30952 ++ (1 << VCI_KCBIT_HISTORY) |
30953 ++#endif
30954 ++
30955 ++ /* inode context tagging */
30956 ++#if defined(CONFIG_TAGGING_NONE)
30957 ++ (0 << VCI_KCBIT_TAGGED) |
30958 ++#elif defined(CONFIG_TAGGING_UID16)
30959 ++ (1 << VCI_KCBIT_TAGGED) |
30960 ++#elif defined(CONFIG_TAGGING_GID16)
30961 ++ (2 << VCI_KCBIT_TAGGED) |
30962 ++#elif defined(CONFIG_TAGGING_ID24)
30963 ++ (3 << VCI_KCBIT_TAGGED) |
30964 ++#elif defined(CONFIG_TAGGING_INTERN)
30965 ++ (4 << VCI_KCBIT_TAGGED) |
30966 ++#elif defined(CONFIG_TAGGING_RUNTIME)
30967 ++ (5 << VCI_KCBIT_TAGGED) |
30968 ++#else
30969 ++ (7 << VCI_KCBIT_TAGGED) |
30970 ++#endif
30971 ++ 0;
30972 ++}
30973 ++
30974 +diff -NurpP --minimal linux-2.6.22.19/mm/filemap_xip.c linux-2.6.22.19-vs2.2.0.7/mm/filemap_xip.c
30975 +--- linux-2.6.22.19/mm/filemap_xip.c 2007-07-09 13:20:04 +0200
30976 ++++ linux-2.6.22.19-vs2.2.0.7/mm/filemap_xip.c 2007-06-15 05:30:21 +0200
30977 +@@ -14,6 +14,7 @@
30978 + #include <linux/uio.h>
30979 + #include <linux/rmap.h>
30980 + #include <linux/sched.h>
30981 ++#include <linux/vs_memory.h>
30982 + #include <asm/tlbflush.h>
30983 + #include "filemap.h"
30984 +
30985 +diff -NurpP --minimal linux-2.6.22.19/mm/fremap.c linux-2.6.22.19-vs2.2.0.7/mm/fremap.c
30986 +--- linux-2.6.22.19/mm/fremap.c 2007-02-06 03:01:56 +0100
30987 ++++ linux-2.6.22.19-vs2.2.0.7/mm/fremap.c 2007-06-15 02:37:04 +0200
30988 +@@ -15,6 +15,7 @@
30989 + #include <linux/rmap.h>
30990 + #include <linux/module.h>
30991 + #include <linux/syscalls.h>
30992 ++#include <linux/vs_memory.h>
30993 +
30994 + #include <asm/mmu_context.h>
30995 + #include <asm/cacheflush.h>
30996 +@@ -74,6 +75,8 @@ int install_page(struct mm_struct *mm, s
30997 + err = -ENOMEM;
30998 + if (page_mapcount(page) > INT_MAX/2)
30999 + goto unlock;
31000 ++ if (!vx_rss_avail(mm, 1))
31001 ++ goto unlock;
31002 +
31003 + if (pte_none(*pte) || !zap_pte(mm, vma, addr, pte))
31004 + inc_mm_counter(mm, file_rss);
31005 +diff -NurpP --minimal linux-2.6.22.19/mm/hugetlb.c linux-2.6.22.19-vs2.2.0.7/mm/hugetlb.c
31006 +--- linux-2.6.22.19/mm/hugetlb.c 2008-03-14 20:19:04 +0100
31007 ++++ linux-2.6.22.19-vs2.2.0.7/mm/hugetlb.c 2007-08-12 12:21:52 +0200
31008 +@@ -19,6 +19,7 @@
31009 + #include <asm/pgtable.h>
31010 +
31011 + #include <linux/hugetlb.h>
31012 ++#include <linux/vs_memory.h>
31013 + #include "internal.h"
31014 +
31015 + const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
31016 +diff -NurpP --minimal linux-2.6.22.19/mm/memory.c linux-2.6.22.19-vs2.2.0.7/mm/memory.c
31017 +--- linux-2.6.22.19/mm/memory.c 2008-03-14 20:19:04 +0100
31018 ++++ linux-2.6.22.19-vs2.2.0.7/mm/memory.c 2008-03-14 19:19:48 +0100
31019 +@@ -498,6 +498,9 @@ static int copy_pte_range(struct mm_stru
31020 + int progress = 0;
31021 + int rss[2];
31022 +
31023 ++ if (!vx_rss_avail(dst_mm, ((end - addr)/PAGE_SIZE + 1)))
31024 ++ return -ENOMEM;
31025 ++
31026 + again:
31027 + rss[1] = rss[0] = 0;
31028 + dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl);
31029 +@@ -2159,6 +2162,11 @@ static int do_swap_page(struct mm_struct
31030 + count_vm_event(PGMAJFAULT);
31031 + }
31032 +
31033 ++ if (!vx_rss_avail(mm, 1)) {
31034 ++ ret = VM_FAULT_OOM;
31035 ++ goto out;
31036 ++ }
31037 ++
31038 + delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
31039 + mark_page_accessed(page);
31040 + lock_page(page);
31041 +@@ -2231,6 +2239,8 @@ static int do_anonymous_page(struct mm_s
31042 + /* Allocate our own private page. */
31043 + pte_unmap(page_table);
31044 +
31045 ++ if (!vx_rss_avail(mm, 1))
31046 ++ goto oom;
31047 + if (unlikely(anon_vma_prepare(vma)))
31048 + goto oom;
31049 + page = alloc_zeroed_user_highpage(vma, address);
31050 +@@ -2304,6 +2314,9 @@ static int do_no_page(struct mm_struct *
31051 + pte_unmap(page_table);
31052 + BUG_ON(vma->vm_flags & VM_PFNMAP);
31053 +
31054 ++ if (!vx_rss_avail(mm, 1))
31055 ++ return VM_FAULT_OOM;
31056 ++
31057 + if (vma->vm_file) {
31058 + mapping = vma->vm_file->f_mapping;
31059 + sequence = mapping->truncate_count;
31060 +@@ -2529,6 +2542,7 @@ static inline int handle_pte_fault(struc
31061 + {
31062 + pte_t entry;
31063 + spinlock_t *ptl;
31064 ++ int ret, type = VXPT_UNKNOWN;
31065 +
31066 + entry = *pte;
31067 + if (!pte_present(entry)) {
31068 +@@ -2557,9 +2571,12 @@ static inline int handle_pte_fault(struc
31069 + if (unlikely(!pte_same(*pte, entry)))
31070 + goto unlock;
31071 + if (write_access) {
31072 +- if (!pte_write(entry))
31073 +- return do_wp_page(mm, vma, address,
31074 ++ if (!pte_write(entry)) {
31075 ++ ret = do_wp_page(mm, vma, address,
31076 + pte, pmd, ptl, entry);
31077 ++ type = VXPT_WRITE;
31078 ++ goto out;
31079 ++ }
31080 + entry = pte_mkdirty(entry);
31081 + }
31082 + entry = pte_mkyoung(entry);
31083 +@@ -2578,7 +2595,10 @@ static inline int handle_pte_fault(struc
31084 + }
31085 + unlock:
31086 + pte_unmap_unlock(pte, ptl);
31087 +- return VM_FAULT_MINOR;
31088 ++ ret = VM_FAULT_MINOR;
31089 ++out:
31090 ++ vx_page_fault(mm, vma, type, ret);
31091 ++ return ret;
31092 + }
31093 +
31094 + /*
31095 +diff -NurpP --minimal linux-2.6.22.19/mm/mlock.c linux-2.6.22.19-vs2.2.0.7/mm/mlock.c
31096 +--- linux-2.6.22.19/mm/mlock.c 2008-03-14 20:19:04 +0100
31097 ++++ linux-2.6.22.19-vs2.2.0.7/mm/mlock.c 2007-08-12 12:21:52 +0200
31098 +@@ -12,6 +12,7 @@
31099 + #include <linux/syscalls.h>
31100 + #include <linux/sched.h>
31101 + #include <linux/module.h>
31102 ++#include <linux/vs_memory.h>
31103 +
31104 + int can_do_mlock(void)
31105 + {
31106 +@@ -76,7 +77,7 @@ success:
31107 + ret = make_pages_present(start, end);
31108 + }
31109 +
31110 +- mm->locked_vm -= pages;
31111 ++ vx_vmlocked_sub(mm, pages);
31112 + out:
31113 + if (ret == -ENOMEM)
31114 + ret = -EAGAIN;
31115 +@@ -134,7 +135,7 @@ static int do_mlock(unsigned long start,
31116 +
31117 + asmlinkage long sys_mlock(unsigned long start, size_t len)
31118 + {
31119 +- unsigned long locked;
31120 ++ unsigned long locked, grow;
31121 + unsigned long lock_limit;
31122 + int error = -ENOMEM;
31123 +
31124 +@@ -145,8 +146,10 @@ asmlinkage long sys_mlock(unsigned long
31125 + len = PAGE_ALIGN(len + (start & ~PAGE_MASK));
31126 + start &= PAGE_MASK;
31127 +
31128 +- locked = len >> PAGE_SHIFT;
31129 +- locked += current->mm->locked_vm;
31130 ++ grow = len >> PAGE_SHIFT;
31131 ++ if (!vx_vmlocked_avail(current->mm, grow))
31132 ++ goto out;
31133 ++ locked = current->mm->locked_vm + grow;
31134 +
31135 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
31136 + lock_limit >>= PAGE_SHIFT;
31137 +@@ -154,6 +157,7 @@ asmlinkage long sys_mlock(unsigned long
31138 + /* check against resource limits */
31139 + if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
31140 + error = do_mlock(start, len, 1);
31141 ++out:
31142 + up_write(&current->mm->mmap_sem);
31143 + return error;
31144 + }
31145 +@@ -213,6 +217,8 @@ asmlinkage long sys_mlockall(int flags)
31146 + lock_limit >>= PAGE_SHIFT;
31147 +
31148 + ret = -ENOMEM;
31149 ++ if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
31150 ++ goto out;
31151 + if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
31152 + capable(CAP_IPC_LOCK))
31153 + ret = do_mlockall(flags);
31154 +diff -NurpP --minimal linux-2.6.22.19/mm/mmap.c linux-2.6.22.19-vs2.2.0.7/mm/mmap.c
31155 +--- linux-2.6.22.19/mm/mmap.c 2008-03-14 20:19:04 +0100
31156 ++++ linux-2.6.22.19-vs2.2.0.7/mm/mmap.c 2008-03-14 19:19:48 +0100
31157 +@@ -1144,10 +1144,10 @@ munmap_back:
31158 + kmem_cache_free(vm_area_cachep, vma);
31159 + }
31160 + out:
31161 +- mm->total_vm += len >> PAGE_SHIFT;
31162 ++ vx_vmpages_add(mm, len >> PAGE_SHIFT);
31163 + vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
31164 + if (vm_flags & VM_LOCKED) {
31165 +- mm->locked_vm += len >> PAGE_SHIFT;
31166 ++ vx_vmlocked_add(mm, len >> PAGE_SHIFT);
31167 + make_pages_present(addr, addr + len);
31168 + }
31169 + if (flags & MAP_POPULATE) {
31170 +@@ -1502,9 +1502,9 @@ static int acct_stack_growth(struct vm_a
31171 + return -ENOMEM;
31172 +
31173 + /* Ok, everything looks good - let it rip */
31174 +- mm->total_vm += grow;
31175 ++ vx_vmpages_add(mm, grow);
31176 + if (vma->vm_flags & VM_LOCKED)
31177 +- mm->locked_vm += grow;
31178 ++ vx_vmlocked_add(mm, grow);
31179 + vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow);
31180 + return 0;
31181 + }
31182 +@@ -1662,9 +1662,9 @@ static void remove_vma_list(struct mm_st
31183 + do {
31184 + long nrpages = vma_pages(vma);
31185 +
31186 +- mm->total_vm -= nrpages;
31187 ++ vx_vmpages_sub(mm, nrpages);
31188 + if (vma->vm_flags & VM_LOCKED)
31189 +- mm->locked_vm -= nrpages;
31190 ++ vx_vmlocked_sub(mm, nrpages);
31191 + vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
31192 + vma = remove_vma(vma);
31193 + } while (vma);
31194 +@@ -1903,6 +1903,8 @@ unsigned long do_brk(unsigned long addr,
31195 + lock_limit >>= PAGE_SHIFT;
31196 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
31197 + return -EAGAIN;
31198 ++ if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT))
31199 ++ return -ENOMEM;
31200 + }
31201 +
31202 + /*
31203 +@@ -1929,7 +1931,8 @@ unsigned long do_brk(unsigned long addr,
31204 + if (mm->map_count > sysctl_max_map_count)
31205 + return -ENOMEM;
31206 +
31207 +- if (security_vm_enough_memory(len >> PAGE_SHIFT))
31208 ++ if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
31209 ++ !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
31210 + return -ENOMEM;
31211 +
31212 + /* Can we just expand an old private anonymous mapping? */
31213 +@@ -1955,9 +1958,9 @@ unsigned long do_brk(unsigned long addr,
31214 + (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
31215 + vma_link(mm, vma, prev, rb_link, rb_parent);
31216 + out:
31217 +- mm->total_vm += len >> PAGE_SHIFT;
31218 ++ vx_vmpages_add(mm, len >> PAGE_SHIFT);
31219 + if (flags & VM_LOCKED) {
31220 +- mm->locked_vm += len >> PAGE_SHIFT;
31221 ++ vx_vmlocked_add(mm, len >> PAGE_SHIFT);
31222 + make_pages_present(addr, addr + len);
31223 + }
31224 + return addr;
31225 +@@ -1986,6 +1989,11 @@ void exit_mmap(struct mm_struct *mm)
31226 + free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0);
31227 + tlb_finish_mmu(tlb, 0, end);
31228 +
31229 ++ set_mm_counter(mm, file_rss, 0);
31230 ++ set_mm_counter(mm, anon_rss, 0);
31231 ++ vx_vmpages_sub(mm, mm->total_vm);
31232 ++ vx_vmlocked_sub(mm, mm->locked_vm);
31233 ++
31234 + /*
31235 + * Walk the list again, actually closing and freeing it,
31236 + * with preemption enabled, without holding any MM locks.
31237 +@@ -2025,7 +2033,8 @@ int insert_vm_struct(struct mm_struct *
31238 + if (__vma && __vma->vm_start < vma->vm_end)
31239 + return -ENOMEM;
31240 + if ((vma->vm_flags & VM_ACCOUNT) &&
31241 +- security_vm_enough_memory(vma_pages(vma)))
31242 ++ (security_vm_enough_memory(vma_pages(vma)) ||
31243 ++ !vx_vmpages_avail(mm, vma_pages(vma))))
31244 + return -ENOMEM;
31245 + vma_link(mm, vma, prev, rb_link, rb_parent);
31246 + return 0;
31247 +@@ -2098,6 +2107,8 @@ int may_expand_vm(struct mm_struct *mm,
31248 +
31249 + if (cur + npages > lim)
31250 + return 0;
31251 ++ if (!vx_vmpages_avail(mm, npages))
31252 ++ return 0;
31253 + return 1;
31254 + }
31255 +
31256 +@@ -2168,7 +2179,6 @@ int install_special_mapping(struct mm_st
31257 + return -ENOMEM;
31258 + }
31259 +
31260 +- mm->total_vm += len >> PAGE_SHIFT;
31261 +-
31262 ++ vx_vmpages_add(mm, len >> PAGE_SHIFT);
31263 + return 0;
31264 + }
31265 +diff -NurpP --minimal linux-2.6.22.19/mm/mremap.c linux-2.6.22.19-vs2.2.0.7/mm/mremap.c
31266 +--- linux-2.6.22.19/mm/mremap.c 2007-02-06 03:01:56 +0100
31267 ++++ linux-2.6.22.19-vs2.2.0.7/mm/mremap.c 2007-06-15 02:37:04 +0200
31268 +@@ -18,6 +18,7 @@
31269 + #include <linux/highmem.h>
31270 + #include <linux/security.h>
31271 + #include <linux/syscalls.h>
31272 ++#include <linux/vs_memory.h>
31273 +
31274 + #include <asm/uaccess.h>
31275 + #include <asm/cacheflush.h>
31276 +@@ -212,7 +213,7 @@ static unsigned long move_vma(struct vm_
31277 + * If this were a serious issue, we'd add a flag to do_munmap().
31278 + */
31279 + hiwater_vm = mm->hiwater_vm;
31280 +- mm->total_vm += new_len >> PAGE_SHIFT;
31281 ++ vx_vmpages_add(mm, new_len >> PAGE_SHIFT);
31282 + vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
31283 +
31284 + if (do_munmap(mm, old_addr, old_len) < 0) {
31285 +@@ -230,7 +231,7 @@ static unsigned long move_vma(struct vm_
31286 + }
31287 +
31288 + if (vm_flags & VM_LOCKED) {
31289 +- mm->locked_vm += new_len >> PAGE_SHIFT;
31290 ++ vx_vmlocked_add(mm, new_len >> PAGE_SHIFT);
31291 + if (new_len > old_len)
31292 + make_pages_present(new_addr + old_len,
31293 + new_addr + new_len);
31294 +@@ -337,6 +338,9 @@ unsigned long do_mremap(unsigned long ad
31295 + ret = -EAGAIN;
31296 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
31297 + goto out;
31298 ++ if (!vx_vmlocked_avail(current->mm,
31299 ++ (new_len - old_len) >> PAGE_SHIFT))
31300 ++ goto out;
31301 + }
31302 + if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) {
31303 + ret = -ENOMEM;
31304 +@@ -365,10 +369,10 @@ unsigned long do_mremap(unsigned long ad
31305 + vma_adjust(vma, vma->vm_start,
31306 + addr + new_len, vma->vm_pgoff, NULL);
31307 +
31308 +- mm->total_vm += pages;
31309 ++ vx_vmpages_add(mm, pages);
31310 + vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
31311 + if (vma->vm_flags & VM_LOCKED) {
31312 +- mm->locked_vm += pages;
31313 ++ vx_vmlocked_add(mm, pages);
31314 + make_pages_present(addr + old_len,
31315 + addr + new_len);
31316 + }
31317 +diff -NurpP --minimal linux-2.6.22.19/mm/nommu.c linux-2.6.22.19-vs2.2.0.7/mm/nommu.c
31318 +--- linux-2.6.22.19/mm/nommu.c 2007-07-09 13:20:04 +0200
31319 ++++ linux-2.6.22.19-vs2.2.0.7/mm/nommu.c 2007-06-15 02:37:04 +0200
31320 +@@ -936,7 +936,7 @@ unsigned long do_mmap_pgoff(struct file
31321 + realalloc += kobjsize(vma);
31322 + askedalloc += sizeof(*vma);
31323 +
31324 +- current->mm->total_vm += len >> PAGE_SHIFT;
31325 ++ vx_vmpages_add(current->mm, len >> PAGE_SHIFT);
31326 +
31327 + add_nommu_vma(vma);
31328 +
31329 +@@ -1061,7 +1061,7 @@ int do_munmap(struct mm_struct *mm, unsi
31330 + kfree(vml);
31331 +
31332 + update_hiwater_vm(mm);
31333 +- mm->total_vm -= len >> PAGE_SHIFT;
31334 ++ vx_vmpages_sub(mm, len >> PAGE_SHIFT);
31335 +
31336 + #ifdef DEBUG
31337 + show_process_blocks();
31338 +@@ -1093,7 +1093,7 @@ void exit_mmap(struct mm_struct * mm)
31339 + printk("Exit_mmap:\n");
31340 + #endif
31341 +
31342 +- mm->total_vm = 0;
31343 ++ vx_vmpages_sub(mm, mm->total_vm);
31344 +
31345 + while ((tmp = mm->context.vmlist)) {
31346 + mm->context.vmlist = tmp->next;
31347 +diff -NurpP --minimal linux-2.6.22.19/mm/oom_kill.c linux-2.6.22.19-vs2.2.0.7/mm/oom_kill.c
31348 +--- linux-2.6.22.19/mm/oom_kill.c 2007-07-09 13:20:04 +0200
31349 ++++ linux-2.6.22.19-vs2.2.0.7/mm/oom_kill.c 2007-06-15 02:37:04 +0200
31350 +@@ -24,6 +24,7 @@
31351 + #include <linux/cpuset.h>
31352 + #include <linux/module.h>
31353 + #include <linux/notifier.h>
31354 ++#include <linux/vs_memory.h>
31355 +
31356 + int sysctl_panic_on_oom;
31357 + /* #define DEBUG */
31358 +@@ -66,6 +67,12 @@ unsigned long badness(struct task_struct
31359 + points = mm->total_vm;
31360 +
31361 + /*
31362 ++ * add points for context badness
31363 ++ */
31364 ++
31365 ++ points += vx_badness(p, mm);
31366 ++
31367 ++ /*
31368 + * After this unlock we can no longer dereference local variable `mm'
31369 + */
31370 + task_unlock(p);
31371 +@@ -156,8 +163,8 @@ unsigned long badness(struct task_struct
31372 + }
31373 +
31374 + #ifdef DEBUG
31375 +- printk(KERN_DEBUG "OOMkill: task %d (%s) got %d points\n",
31376 +- p->pid, p->comm, points);
31377 ++ printk(KERN_DEBUG "OOMkill: task %d:#%u (%s) got %d points\n",
31378 ++ p->pid, p->xid, p->comm, points);
31379 + #endif
31380 + return points;
31381 + }
31382 +@@ -288,7 +295,8 @@ static void __oom_kill_task(struct task_
31383 + }
31384 +
31385 + if (verbose)
31386 +- printk(KERN_ERR "Killed process %d (%s)\n", p->pid, p->comm);
31387 ++ printk(KERN_ERR "Killed process %d:#%u (%s)\n",
31388 ++ p->pid, p->xid, p->comm);
31389 +
31390 + /*
31391 + * We give our sacrificial lamb high priority and access to
31392 +@@ -358,8 +366,8 @@ static int oom_kill_process(struct task_
31393 + return 0;
31394 + }
31395 +
31396 +- printk(KERN_ERR "%s: kill process %d (%s) score %li or a child\n",
31397 +- message, p->pid, p->comm, points);
31398 ++ printk(KERN_ERR "%s: kill process %d:#%u (%s) score %li or a child\n",
31399 ++ message, p->pid, p->xid, p->comm, points);
31400 +
31401 + /* Try to kill a child first */
31402 + list_for_each(tsk, &p->children) {
31403 +diff -NurpP --minimal linux-2.6.22.19/mm/page_alloc.c linux-2.6.22.19-vs2.2.0.7/mm/page_alloc.c
31404 +--- linux-2.6.22.19/mm/page_alloc.c 2007-07-09 13:20:04 +0200
31405 ++++ linux-2.6.22.19-vs2.2.0.7/mm/page_alloc.c 2007-06-17 05:54:20 +0200
31406 +@@ -41,6 +41,8 @@
31407 + #include <linux/pfn.h>
31408 + #include <linux/backing-dev.h>
31409 + #include <linux/fault-inject.h>
31410 ++#include <linux/vs_base.h>
31411 ++#include <linux/vs_limit.h>
31412 +
31413 + #include <asm/tlbflush.h>
31414 + #include <asm/div64.h>
31415 +@@ -1488,6 +1490,9 @@ void si_meminfo(struct sysinfo *val)
31416 + val->totalhigh = totalhigh_pages;
31417 + val->freehigh = nr_free_highpages();
31418 + val->mem_unit = PAGE_SIZE;
31419 ++
31420 ++ if (vx_flags(VXF_VIRT_MEM, 0))
31421 ++ vx_vsi_meminfo(val);
31422 + }
31423 +
31424 + EXPORT_SYMBOL(si_meminfo);
31425 +@@ -1508,6 +1513,9 @@ void si_meminfo_node(struct sysinfo *val
31426 + val->freehigh = 0;
31427 + #endif
31428 + val->mem_unit = PAGE_SIZE;
31429 ++
31430 ++ if (vx_flags(VXF_VIRT_MEM, 0))
31431 ++ vx_vsi_meminfo(val);
31432 + }
31433 + #endif
31434 +
31435 +diff -NurpP --minimal linux-2.6.22.19/mm/rmap.c linux-2.6.22.19-vs2.2.0.7/mm/rmap.c
31436 +--- linux-2.6.22.19/mm/rmap.c 2007-07-09 13:20:04 +0200
31437 ++++ linux-2.6.22.19-vs2.2.0.7/mm/rmap.c 2007-07-07 03:52:54 +0200
31438 +@@ -48,6 +48,7 @@
31439 + #include <linux/rcupdate.h>
31440 + #include <linux/module.h>
31441 + #include <linux/kallsyms.h>
31442 ++#include <linux/vs_memory.h>
31443 +
31444 + #include <asm/tlbflush.h>
31445 +
31446 +diff -NurpP --minimal linux-2.6.22.19/mm/shmem.c linux-2.6.22.19-vs2.2.0.7/mm/shmem.c
31447 +--- linux-2.6.22.19/mm/shmem.c 2008-03-14 20:19:04 +0100
31448 ++++ linux-2.6.22.19-vs2.2.0.7/mm/shmem.c 2008-01-09 20:53:07 +0100
31449 +@@ -55,7 +55,6 @@
31450 + #include <asm/pgtable.h>
31451 +
31452 + /* This magic number is used in glibc for posix shared memory */
31453 +-#define TMPFS_MAGIC 0x01021994
31454 +
31455 + #define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
31456 + #define ENTRIES_PER_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
31457 +@@ -1750,7 +1749,7 @@ static int shmem_statfs(struct dentry *d
31458 + {
31459 + struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
31460 +
31461 +- buf->f_type = TMPFS_MAGIC;
31462 ++ buf->f_type = TMPFS_SUPER_MAGIC;
31463 + buf->f_bsize = PAGE_CACHE_SIZE;
31464 + buf->f_namelen = NAME_MAX;
31465 + spin_lock(&sbinfo->stat_lock);
31466 +@@ -2324,7 +2323,7 @@ static int shmem_fill_super(struct super
31467 + sb->s_maxbytes = SHMEM_MAX_BYTES;
31468 + sb->s_blocksize = PAGE_CACHE_SIZE;
31469 + sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
31470 +- sb->s_magic = TMPFS_MAGIC;
31471 ++ sb->s_magic = TMPFS_SUPER_MAGIC;
31472 + sb->s_op = &shmem_ops;
31473 + sb->s_time_gran = 1;
31474 + #ifdef CONFIG_TMPFS_POSIX_ACL
31475 +diff -NurpP --minimal linux-2.6.22.19/mm/slab.c linux-2.6.22.19-vs2.2.0.7/mm/slab.c
31476 +--- linux-2.6.22.19/mm/slab.c 2007-07-09 13:20:04 +0200
31477 ++++ linux-2.6.22.19-vs2.2.0.7/mm/slab.c 2007-07-09 13:11:54 +0200
31478 +@@ -510,6 +510,8 @@ struct kmem_cache {
31479 + #define STATS_INC_FREEMISS(x) do { } while (0)
31480 + #endif
31481 +
31482 ++#include "slab_vs.h"
31483 ++
31484 + #if DEBUG
31485 +
31486 + /*
31487 +@@ -3314,6 +3316,7 @@ retry:
31488 +
31489 + obj = slab_get_obj(cachep, slabp, nodeid);
31490 + check_slabp(cachep, slabp);
31491 ++ vx_slab_alloc(cachep, flags);
31492 + l3->free_objects--;
31493 + /* move slabp to correct slabp list: */
31494 + list_del(&slabp->list);
31495 +@@ -3386,6 +3389,7 @@ __cache_alloc_node(struct kmem_cache *ca
31496 + /* ___cache_alloc_node can fall back to other nodes */
31497 + ptr = ____cache_alloc_node(cachep, flags, nodeid);
31498 + out:
31499 ++ vx_slab_alloc(cachep, flags);
31500 + local_irq_restore(save_flags);
31501 + ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller);
31502 +
31503 +@@ -3551,6 +3555,7 @@ static inline void __cache_free(struct k
31504 +
31505 + check_irq_off();
31506 + objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
31507 ++ vx_slab_free(cachep);
31508 +
31509 + if (cache_free_alien(cachep, objp))
31510 + return;
31511 +diff -NurpP --minimal linux-2.6.22.19/mm/slab_vs.h linux-2.6.22.19-vs2.2.0.7/mm/slab_vs.h
31512 +--- linux-2.6.22.19/mm/slab_vs.h 1970-01-01 01:00:00 +0100
31513 ++++ linux-2.6.22.19-vs2.2.0.7/mm/slab_vs.h 2007-06-15 02:37:04 +0200
31514 +@@ -0,0 +1,27 @@
31515 ++
31516 ++#include <linux/vserver/context.h>
31517 ++
31518 ++#include <linux/vs_context.h>
31519 ++
31520 ++static inline
31521 ++void vx_slab_alloc(struct kmem_cache *cachep, gfp_t flags)
31522 ++{
31523 ++ int what = gfp_zone(cachep->gfpflags);
31524 ++
31525 ++ if (!current->vx_info)
31526 ++ return;
31527 ++
31528 ++ atomic_add(cachep->buffer_size, &current->vx_info->cacct.slab[what]);
31529 ++}
31530 ++
31531 ++static inline
31532 ++void vx_slab_free(struct kmem_cache *cachep)
31533 ++{
31534 ++ int what = gfp_zone(cachep->gfpflags);
31535 ++
31536 ++ if (!current->vx_info)
31537 ++ return;
31538 ++
31539 ++ atomic_sub(cachep->buffer_size, &current->vx_info->cacct.slab[what]);
31540 ++}
31541 ++
31542 +diff -NurpP --minimal linux-2.6.22.19/mm/swapfile.c linux-2.6.22.19-vs2.2.0.7/mm/swapfile.c
31543 +--- linux-2.6.22.19/mm/swapfile.c 2007-07-09 13:20:04 +0200
31544 ++++ linux-2.6.22.19-vs2.2.0.7/mm/swapfile.c 2007-06-15 02:37:04 +0200
31545 +@@ -31,6 +31,8 @@
31546 + #include <asm/pgtable.h>
31547 + #include <asm/tlbflush.h>
31548 + #include <linux/swapops.h>
31549 ++#include <linux/vs_base.h>
31550 ++#include <linux/vs_memory.h>
31551 +
31552 + DEFINE_SPINLOCK(swap_lock);
31553 + unsigned int nr_swapfiles;
31554 +@@ -1712,6 +1714,8 @@ void si_swapinfo(struct sysinfo *val)
31555 + val->freeswap = nr_swap_pages + nr_to_be_unused;
31556 + val->totalswap = total_swap_pages + nr_to_be_unused;
31557 + spin_unlock(&swap_lock);
31558 ++ if (vx_flags(VXF_VIRT_MEM, 0))
31559 ++ vx_vsi_swapinfo(val);
31560 + }
31561 +
31562 + /*
31563 +diff -NurpP --minimal linux-2.6.22.19/net/core/dev.c linux-2.6.22.19-vs2.2.0.7/net/core/dev.c
31564 +--- linux-2.6.22.19/net/core/dev.c 2008-03-14 20:19:05 +0100
31565 ++++ linux-2.6.22.19-vs2.2.0.7/net/core/dev.c 2007-09-05 03:05:53 +0200
31566 +@@ -117,6 +117,8 @@
31567 + #include <linux/err.h>
31568 + #include <linux/ctype.h>
31569 + #include <linux/if_arp.h>
31570 ++#include <linux/vs_context.h> /* remove with NXF_HIDE_NETIF */
31571 ++#include <linux/vs_network.h>
31572 +
31573 + /*
31574 + * The list of packet types we will receive (as opposed to discard)
31575 +@@ -2120,6 +2122,9 @@ static int dev_ifconf(char __user *arg)
31576 +
31577 + total = 0;
31578 + for_each_netdev(dev) {
31579 ++ if (vx_flags(VXF_HIDE_NETIF, 0) &&
31580 ++ !dev_in_nx_info(dev, current->nx_info))
31581 ++ continue;
31582 + for (i = 0; i < NPROTO; i++) {
31583 + if (gifconf_list[i]) {
31584 + int done;
31585 +@@ -2183,6 +2188,10 @@ void dev_seq_stop(struct seq_file *seq,
31586 + static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
31587 + {
31588 + struct net_device_stats *stats = dev->get_stats(dev);
31589 ++ struct nx_info *nxi = current->nx_info;
31590 ++
31591 ++ if (vx_flags(VXF_HIDE_NETIF, 0) && !dev_in_nx_info(dev, nxi))
31592 ++ return;
31593 +
31594 + seq_printf(seq, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu "
31595 + "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n",
31596 +diff -NurpP --minimal linux-2.6.22.19/net/core/rtnetlink.c linux-2.6.22.19-vs2.2.0.7/net/core/rtnetlink.c
31597 +--- linux-2.6.22.19/net/core/rtnetlink.c 2007-07-09 13:20:05 +0200
31598 ++++ linux-2.6.22.19-vs2.2.0.7/net/core/rtnetlink.c 2007-06-17 05:54:20 +0200
31599 +@@ -35,6 +35,7 @@
31600 + #include <linux/security.h>
31601 + #include <linux/mutex.h>
31602 + #include <linux/if_addr.h>
31603 ++#include <linux/vs_context.h> /* remove with NXF_HIDE_NETIF */
31604 +
31605 + #include <asm/uaccess.h>
31606 + #include <asm/system.h>
31607 +@@ -537,6 +538,9 @@ static int rtnl_dump_ifinfo(struct sk_bu
31608 +
31609 + idx = 0;
31610 + for_each_netdev(dev) {
31611 ++ if (vx_info_flags(skb->sk->sk_vx_info, VXF_HIDE_NETIF, 0) &&
31612 ++ !dev_in_nx_info(dev, skb->sk->sk_nx_info))
31613 ++ continue;
31614 + if (idx < s_idx)
31615 + goto cont;
31616 + if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
31617 +diff -NurpP --minimal linux-2.6.22.19/net/core/sock.c linux-2.6.22.19-vs2.2.0.7/net/core/sock.c
31618 +--- linux-2.6.22.19/net/core/sock.c 2007-07-09 13:20:05 +0200
31619 ++++ linux-2.6.22.19-vs2.2.0.7/net/core/sock.c 2007-06-15 02:37:04 +0200
31620 +@@ -125,6 +125,9 @@
31621 + #include <linux/ipsec.h>
31622 +
31623 + #include <linux/filter.h>
31624 ++#include <linux/vs_socket.h>
31625 ++#include <linux/vs_limit.h>
31626 ++#include <linux/vs_context.h>
31627 +
31628 + #ifdef CONFIG_INET
31629 + #include <net/tcp.h>
31630 +@@ -869,6 +872,8 @@ struct sock *sk_alloc(int family, gfp_t
31631 + sk->sk_prot = sk->sk_prot_creator = prot;
31632 + sock_lock_init(sk);
31633 + }
31634 ++ sock_vx_init(sk);
31635 ++ sock_nx_init(sk);
31636 +
31637 + if (security_sk_alloc(sk, family, priority))
31638 + goto out_free;
31639 +@@ -907,6 +912,11 @@ void sk_free(struct sock *sk)
31640 + __FUNCTION__, atomic_read(&sk->sk_omem_alloc));
31641 +
31642 + security_sk_free(sk);
31643 ++ vx_sock_dec(sk);
31644 ++ clr_vx_info(&sk->sk_vx_info);
31645 ++ sk->sk_xid = -1;
31646 ++ clr_nx_info(&sk->sk_nx_info);
31647 ++ sk->sk_nid = -1;
31648 + if (sk->sk_prot_creator->slab != NULL)
31649 + kmem_cache_free(sk->sk_prot_creator->slab, sk);
31650 + else
31651 +@@ -924,6 +934,8 @@ struct sock *sk_clone(const struct sock
31652 + sock_copy(newsk, sk);
31653 +
31654 + /* SANITY */
31655 ++ sock_vx_init(newsk);
31656 ++ sock_nx_init(newsk);
31657 + sk_node_init(&newsk->sk_node);
31658 + sock_lock_init(newsk);
31659 + bh_lock_sock(newsk);
31660 +@@ -969,6 +981,12 @@ struct sock *sk_clone(const struct sock
31661 + newsk->sk_priority = 0;
31662 + atomic_set(&newsk->sk_refcnt, 2);
31663 +
31664 ++ set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info);
31665 ++ newsk->sk_xid = sk->sk_xid;
31666 ++ vx_sock_inc(newsk);
31667 ++ set_nx_info(&newsk->sk_nx_info, sk->sk_nx_info);
31668 ++ newsk->sk_nid = sk->sk_nid;
31669 ++
31670 + /*
31671 + * Increment the counter in the same struct proto as the master
31672 + * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
31673 +@@ -1551,6 +1569,11 @@ void sock_init_data(struct socket *sock,
31674 +
31675 + sk->sk_stamp = ktime_set(-1L, -1L);
31676 +
31677 ++ set_vx_info(&sk->sk_vx_info, current->vx_info);
31678 ++ sk->sk_xid = vx_current_xid();
31679 ++ vx_sock_inc(sk);
31680 ++ set_nx_info(&sk->sk_nx_info, current->nx_info);
31681 ++ sk->sk_nid = nx_current_nid();
31682 + atomic_set(&sk->sk_refcnt, 1);
31683 + }
31684 +
31685 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/af_inet.c linux-2.6.22.19-vs2.2.0.7/net/ipv4/af_inet.c
31686 +--- linux-2.6.22.19/net/ipv4/af_inet.c 2008-03-14 20:19:05 +0100
31687 ++++ linux-2.6.22.19-vs2.2.0.7/net/ipv4/af_inet.c 2007-09-05 03:05:54 +0200
31688 +@@ -115,6 +115,7 @@
31689 + #ifdef CONFIG_IP_MROUTE
31690 + #include <linux/mroute.h>
31691 + #endif
31692 ++#include <linux/vs_limit.h>
31693 +
31694 + DEFINE_SNMP_STAT(struct linux_mib, net_statistics) __read_mostly;
31695 +
31696 +@@ -308,9 +309,11 @@ lookup_protocol:
31697 + }
31698 +
31699 + err = -EPERM;
31700 ++ if ((protocol == IPPROTO_ICMP) && vx_ccaps(VXC_RAW_ICMP))
31701 ++ goto override;
31702 + if (answer->capability > 0 && !capable(answer->capability))
31703 + goto out_rcu_unlock;
31704 +-
31705 ++override:
31706 + sock->ops = answer->ops;
31707 + answer_prot = answer->prot;
31708 + answer_no_check = answer->no_check;
31709 +@@ -427,6 +430,10 @@ int inet_bind(struct socket *sock, struc
31710 + unsigned short snum;
31711 + int chk_addr_ret;
31712 + int err;
31713 ++ __u32 s_addr; /* Address used for validation */
31714 ++ __u32 s_addr1; /* Address used for socket */
31715 ++ __u32 s_addr2; /* Broadcast address for the socket */
31716 ++ struct nx_info *nxi = sk->sk_nx_info;
31717 +
31718 + /* If the socket has its own bind function then use it. (RAW) */
31719 + if (sk->sk_prot->bind) {
31720 +@@ -437,7 +444,40 @@ int inet_bind(struct socket *sock, struc
31721 + if (addr_len < sizeof(struct sockaddr_in))
31722 + goto out;
31723 +
31724 +- chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
31725 ++ s_addr = addr->sin_addr.s_addr;
31726 ++ s_addr1 = s_addr;
31727 ++ s_addr2 = 0xffffffffl;
31728 ++
31729 ++ vxdprintk(VXD_CBIT(net, 3),
31730 ++ "inet_bind(%p)* %p,%p;%lx " NIPQUAD_FMT,
31731 ++ sk, sk->sk_nx_info, sk->sk_socket,
31732 ++ (sk->sk_socket?sk->sk_socket->flags:0),
31733 ++ NIPQUAD(s_addr));
31734 ++ if (nxi) {
31735 ++ __u32 v4_bcast = nxi->v4_bcast;
31736 ++ __u32 ipv4root = nxi->ipv4[0];
31737 ++ int nbipv4 = nxi->nbipv4;
31738 ++
31739 ++ if (s_addr == 0) {
31740 ++ /* bind to any for 1-n */
31741 ++ s_addr = ipv4root;
31742 ++ s_addr1 = (nbipv4 > 1) ? 0 : s_addr;
31743 ++ s_addr2 = v4_bcast;
31744 ++ } else if (s_addr == IPI_LOOPBACK) {
31745 ++ /* rewrite localhost to ipv4root */
31746 ++ s_addr = ipv4root;
31747 ++ s_addr1 = ipv4root;
31748 ++ } else if (s_addr != v4_bcast) {
31749 ++ /* normal address bind */
31750 ++ if (!addr_in_nx_info(nxi, s_addr))
31751 ++ return -EADDRNOTAVAIL;
31752 ++ }
31753 ++ }
31754 ++ chk_addr_ret = inet_addr_type(s_addr);
31755 ++
31756 ++ vxdprintk(VXD_CBIT(net, 3),
31757 ++ "inet_bind(%p) " NIPQUAD_FMT ", " NIPQUAD_FMT ", " NIPQUAD_FMT,
31758 ++ sk, NIPQUAD(s_addr), NIPQUAD(s_addr1), NIPQUAD(s_addr2));
31759 +
31760 + /* Not specified by any standard per-se, however it breaks too
31761 + * many applications when removed. It is unfortunate since
31762 +@@ -449,7 +489,7 @@ int inet_bind(struct socket *sock, struc
31763 + err = -EADDRNOTAVAIL;
31764 + if (!sysctl_ip_nonlocal_bind &&
31765 + !inet->freebind &&
31766 +- addr->sin_addr.s_addr != INADDR_ANY &&
31767 ++ s_addr != INADDR_ANY &&
31768 + chk_addr_ret != RTN_LOCAL &&
31769 + chk_addr_ret != RTN_MULTICAST &&
31770 + chk_addr_ret != RTN_BROADCAST)
31771 +@@ -474,7 +514,8 @@ int inet_bind(struct socket *sock, struc
31772 + if (sk->sk_state != TCP_CLOSE || inet->num)
31773 + goto out_release_sock;
31774 +
31775 +- inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr;
31776 ++ inet->rcv_saddr = inet->saddr = s_addr1;
31777 ++ inet->rcv_saddr2 = s_addr2;
31778 + if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
31779 + inet->saddr = 0; /* Use device */
31780 +
31781 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/devinet.c linux-2.6.22.19-vs2.2.0.7/net/ipv4/devinet.c
31782 +--- linux-2.6.22.19/net/ipv4/devinet.c 2008-03-14 20:19:05 +0100
31783 ++++ linux-2.6.22.19-vs2.2.0.7/net/ipv4/devinet.c 2008-03-14 19:19:48 +0100
31784 +@@ -56,6 +56,7 @@
31785 + #include <linux/sysctl.h>
31786 + #endif
31787 + #include <linux/kmod.h>
31788 ++#include <linux/vs_context.h>
31789 +
31790 + #include <net/arp.h>
31791 + #include <net/ip.h>
31792 +@@ -676,6 +677,9 @@ int devinet_ioctl(unsigned int cmd, void
31793 + *colon = ':';
31794 +
31795 + if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) {
31796 ++ struct nx_info *nxi = current->nx_info;
31797 ++ int hide_netif = vx_flags(VXF_HIDE_NETIF, 0);
31798 ++
31799 + if (tryaddrmatch) {
31800 + /* Matthias Andree */
31801 + /* compare label and address (4.4BSD style) */
31802 +@@ -684,6 +688,8 @@ int devinet_ioctl(unsigned int cmd, void
31803 + This is checked above. */
31804 + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
31805 + ifap = &ifa->ifa_next) {
31806 ++ if (hide_netif && !ifa_in_nx_info(ifa, nxi))
31807 ++ continue;
31808 + if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
31809 + sin_orig.sin_addr.s_addr ==
31810 + ifa->ifa_address) {
31811 +@@ -696,9 +702,12 @@ int devinet_ioctl(unsigned int cmd, void
31812 + comparing just the label */
31813 + if (!ifa) {
31814 + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
31815 +- ifap = &ifa->ifa_next)
31816 ++ ifap = &ifa->ifa_next) {
31817 ++ if (hide_netif && !ifa_in_nx_info(ifa, nxi))
31818 ++ continue;
31819 + if (!strcmp(ifr.ifr_name, ifa->ifa_label))
31820 + break;
31821 ++ }
31822 + }
31823 + }
31824 +
31825 +@@ -849,6 +858,9 @@ static int inet_gifconf(struct net_devic
31826 + goto out;
31827 +
31828 + for (; ifa; ifa = ifa->ifa_next) {
31829 ++ if (vx_flags(VXF_HIDE_NETIF, 0) &&
31830 ++ !ifa_in_nx_info(ifa, current->nx_info))
31831 ++ continue;
31832 + if (!buf) {
31833 + done += sizeof(ifr);
31834 + continue;
31835 +@@ -1179,6 +1191,7 @@ static int inet_dump_ifaddr(struct sk_bu
31836 + struct net_device *dev;
31837 + struct in_device *in_dev;
31838 + struct in_ifaddr *ifa;
31839 ++ struct sock *sk = skb->sk;
31840 + int s_ip_idx, s_idx = cb->args[0];
31841 +
31842 + s_ip_idx = ip_idx = cb->args[1];
31843 +@@ -1193,6 +1206,9 @@ static int inet_dump_ifaddr(struct sk_bu
31844 +
31845 + for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
31846 + ifa = ifa->ifa_next, ip_idx++) {
31847 ++ if (sk && vx_info_flags(sk->sk_vx_info, VXF_HIDE_NETIF, 0) &&
31848 ++ !ifa_in_nx_info(ifa, sk->sk_nx_info))
31849 ++ continue;
31850 + if (ip_idx < s_ip_idx)
31851 + continue;
31852 + if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
31853 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/fib_hash.c linux-2.6.22.19-vs2.2.0.7/net/ipv4/fib_hash.c
31854 +--- linux-2.6.22.19/net/ipv4/fib_hash.c 2007-07-09 13:20:05 +0200
31855 ++++ linux-2.6.22.19-vs2.2.0.7/net/ipv4/fib_hash.c 2007-06-15 02:37:04 +0200
31856 +@@ -34,6 +34,7 @@
31857 + #include <linux/skbuff.h>
31858 + #include <linux/netlink.h>
31859 + #include <linux/init.h>
31860 ++#include <linux/vs_context.h>
31861 +
31862 + #include <net/ip.h>
31863 + #include <net/protocol.h>
31864 +@@ -982,6 +983,8 @@ static unsigned fib_flag_trans(int type,
31865 + return flags;
31866 + }
31867 +
31868 ++extern int dev_in_nx_info(struct net_device *, struct nx_info *);
31869 ++
31870 + /*
31871 + * This outputs /proc/net/route.
31872 + *
31873 +@@ -1012,7 +1015,8 @@ static int fib_seq_show(struct seq_file
31874 + prefix = f->fn_key;
31875 + mask = FZ_MASK(iter->zone);
31876 + flags = fib_flag_trans(fa->fa_type, mask, fi);
31877 +- if (fi)
31878 ++ if (fi && (!vx_flags(VXF_HIDE_NETIF, 0) ||
31879 ++ dev_in_nx_info(fi->fib_dev, current->nx_info)))
31880 + snprintf(bf, sizeof(bf),
31881 + "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
31882 + fi->fib_dev ? fi->fib_dev->name : "*", prefix,
31883 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/inet_connection_sock.c linux-2.6.22.19-vs2.2.0.7/net/ipv4/inet_connection_sock.c
31884 +--- linux-2.6.22.19/net/ipv4/inet_connection_sock.c 2007-07-09 13:20:05 +0200
31885 ++++ linux-2.6.22.19-vs2.2.0.7/net/ipv4/inet_connection_sock.c 2007-06-15 02:37:04 +0200
31886 +@@ -37,7 +37,6 @@ int sysctl_local_port_range[2] = { 32768
31887 + int inet_csk_bind_conflict(const struct sock *sk,
31888 + const struct inet_bind_bucket *tb)
31889 + {
31890 +- const __be32 sk_rcv_saddr = inet_rcv_saddr(sk);
31891 + struct sock *sk2;
31892 + struct hlist_node *node;
31893 + int reuse = sk->sk_reuse;
31894 +@@ -50,9 +49,8 @@ int inet_csk_bind_conflict(const struct
31895 + sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
31896 + if (!reuse || !sk2->sk_reuse ||
31897 + sk2->sk_state == TCP_LISTEN) {
31898 +- const __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
31899 +- if (!sk2_rcv_saddr || !sk_rcv_saddr ||
31900 +- sk2_rcv_saddr == sk_rcv_saddr)
31901 ++ if (nx_addr_conflict(sk->sk_nx_info,
31902 ++ inet_rcv_saddr(sk), sk2))
31903 + break;
31904 + }
31905 + }
31906 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/inet_diag.c linux-2.6.22.19-vs2.2.0.7/net/ipv4/inet_diag.c
31907 +--- linux-2.6.22.19/net/ipv4/inet_diag.c 2008-03-14 20:19:05 +0100
31908 ++++ linux-2.6.22.19-vs2.2.0.7/net/ipv4/inet_diag.c 2007-10-01 15:25:35 +0200
31909 +@@ -697,6 +697,8 @@ static int inet_diag_dump(struct sk_buff
31910 + sk_for_each(sk, node, &hashinfo->listening_hash[i]) {
31911 + struct inet_sock *inet = inet_sk(sk);
31912 +
31913 ++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
31914 ++ continue;
31915 + if (num < s_num) {
31916 + num++;
31917 + continue;
31918 +@@ -757,6 +759,8 @@ skip_listen_ht:
31919 + sk_for_each(sk, node, &head->chain) {
31920 + struct inet_sock *inet = inet_sk(sk);
31921 +
31922 ++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
31923 ++ continue;
31924 + if (num < s_num)
31925 + goto next_normal;
31926 + if (!(r->idiag_states & (1 << sk->sk_state)))
31927 +@@ -781,6 +785,8 @@ next_normal:
31928 + inet_twsk_for_each(tw, node,
31929 + &head->twchain) {
31930 +
31931 ++ if (!nx_check(tw->tw_nid, VS_WATCH_P | VS_IDENT))
31932 ++ continue;
31933 + if (num < s_num)
31934 + goto next_dying;
31935 + if (r->id.idiag_sport != tw->tw_sport &&
31936 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/inet_hashtables.c linux-2.6.22.19-vs2.2.0.7/net/ipv4/inet_hashtables.c
31937 +--- linux-2.6.22.19/net/ipv4/inet_hashtables.c 2007-05-02 19:25:40 +0200
31938 ++++ linux-2.6.22.19-vs2.2.0.7/net/ipv4/inet_hashtables.c 2007-06-15 02:37:04 +0200
31939 +@@ -140,11 +140,10 @@ static struct sock *inet_lookup_listener
31940 + const __be32 rcv_saddr = inet->rcv_saddr;
31941 + int score = sk->sk_family == PF_INET ? 1 : 0;
31942 +
31943 +- if (rcv_saddr) {
31944 +- if (rcv_saddr != daddr)
31945 +- continue;
31946 ++ if (inet_addr_match(sk->sk_nx_info, daddr, rcv_saddr))
31947 + score += 2;
31948 +- }
31949 ++ else
31950 ++ continue;
31951 + if (sk->sk_bound_dev_if) {
31952 + if (sk->sk_bound_dev_if != dif)
31953 + continue;
31954 +@@ -175,7 +174,7 @@ struct sock *__inet_lookup_listener(stru
31955 + const struct inet_sock *inet = inet_sk((sk = __sk_head(head)));
31956 +
31957 + if (inet->num == hnum && !sk->sk_node.next &&
31958 +- (!inet->rcv_saddr || inet->rcv_saddr == daddr) &&
31959 ++ inet_addr_match(sk->sk_nx_info, daddr, inet->rcv_saddr) &&
31960 + (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
31961 + !sk->sk_bound_dev_if)
31962 + goto sherry_cache;
31963 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/raw.c linux-2.6.22.19-vs2.2.0.7/net/ipv4/raw.c
31964 +--- linux-2.6.22.19/net/ipv4/raw.c 2007-07-09 13:20:06 +0200
31965 ++++ linux-2.6.22.19-vs2.2.0.7/net/ipv4/raw.c 2007-06-15 02:37:04 +0200
31966 +@@ -101,6 +101,27 @@ static void raw_v4_unhash(struct sock *s
31967 + write_unlock_bh(&raw_v4_lock);
31968 + }
31969 +
31970 ++
31971 ++/*
31972 ++ * Check if a given address matches for a socket
31973 ++ *
31974 ++ * nxi: the socket's nx_info if any
31975 ++ * addr: to be verified address
31976 ++ * saddr/baddr: socket addresses
31977 ++ */
31978 ++static inline int raw_addr_match (
31979 ++ struct nx_info *nxi,
31980 ++ uint32_t addr,
31981 ++ uint32_t saddr,
31982 ++ uint32_t baddr)
31983 ++{
31984 ++ if (addr && (saddr == addr || baddr == addr))
31985 ++ return 1;
31986 ++ if (!saddr)
31987 ++ return addr_in_nx_info(nxi, addr);
31988 ++ return 0;
31989 ++}
31990 ++
31991 + struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
31992 + __be32 raddr, __be32 laddr,
31993 + int dif)
31994 +@@ -112,7 +133,8 @@ struct sock *__raw_v4_lookup(struct sock
31995 +
31996 + if (inet->num == num &&
31997 + !(inet->daddr && inet->daddr != raddr) &&
31998 +- !(inet->rcv_saddr && inet->rcv_saddr != laddr) &&
31999 ++ raw_addr_match(sk->sk_nx_info, laddr,
32000 ++ inet->rcv_saddr, inet->rcv_saddr2) &&
32001 + !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
32002 + goto found; /* gotcha */
32003 + }
32004 +@@ -314,6 +336,11 @@ static int raw_send_hdrinc(struct sock *
32005 + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
32006 + }
32007 +
32008 ++ err = -EPERM;
32009 ++ if (!nx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW)
32010 ++ && (!addr_in_nx_info(sk->sk_nx_info, iph->saddr)))
32011 ++ goto error_free;
32012 ++
32013 + err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
32014 + dst_output);
32015 + if (err > 0)
32016 +@@ -325,6 +352,7 @@ out:
32017 +
32018 + error_fault:
32019 + err = -EFAULT;
32020 ++error_free:
32021 + kfree_skb(skb);
32022 + error:
32023 + IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS);
32024 +@@ -491,6 +519,12 @@ static int raw_sendmsg(struct kiocb *ioc
32025 + }
32026 +
32027 + security_sk_classify_flow(sk, &fl);
32028 ++ if (sk->sk_nx_info) {
32029 ++ err = ip_find_src(sk->sk_nx_info, &rt, &fl);
32030 ++
32031 ++ if (err)
32032 ++ goto done;
32033 ++ }
32034 + err = ip_route_output_flow(&rt, &fl, sk, 1);
32035 + }
32036 + if (err)
32037 +@@ -795,7 +829,8 @@ static struct sock *raw_get_first(struct
32038 + struct hlist_node *node;
32039 +
32040 + sk_for_each(sk, node, &raw_v4_htable[state->bucket])
32041 +- if (sk->sk_family == PF_INET)
32042 ++ if (sk->sk_family == PF_INET &&
32043 ++ nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
32044 + goto found;
32045 + }
32046 + sk = NULL;
32047 +@@ -811,7 +846,8 @@ static struct sock *raw_get_next(struct
32048 + sk = sk_next(sk);
32049 + try_again:
32050 + ;
32051 +- } while (sk && sk->sk_family != PF_INET);
32052 ++ } while (sk && (sk->sk_family != PF_INET ||
32053 ++ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
32054 +
32055 + if (!sk && ++state->bucket < RAWV4_HTABLE_SIZE) {
32056 + sk = sk_head(&raw_v4_htable[state->bucket]);
32057 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/tcp.c linux-2.6.22.19-vs2.2.0.7/net/ipv4/tcp.c
32058 +--- linux-2.6.22.19/net/ipv4/tcp.c 2008-03-14 20:19:05 +0100
32059 ++++ linux-2.6.22.19-vs2.2.0.7/net/ipv4/tcp.c 2007-09-05 03:05:54 +0200
32060 +@@ -258,6 +258,7 @@
32061 + #include <linux/cache.h>
32062 + #include <linux/err.h>
32063 + #include <linux/crypto.h>
32064 ++#include <linux/in.h>
32065 +
32066 + #include <net/icmp.h>
32067 + #include <net/tcp.h>
32068 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/tcp_ipv4.c linux-2.6.22.19-vs2.2.0.7/net/ipv4/tcp_ipv4.c
32069 +--- linux-2.6.22.19/net/ipv4/tcp_ipv4.c 2008-03-14 20:19:05 +0100
32070 ++++ linux-2.6.22.19-vs2.2.0.7/net/ipv4/tcp_ipv4.c 2008-01-09 20:53:07 +0100
32071 +@@ -1974,6 +1974,12 @@ static void *listening_get_next(struct s
32072 + req = req->dl_next;
32073 + while (1) {
32074 + while (req) {
32075 ++ vxdprintk(VXD_CBIT(net, 6),
32076 ++ "sk,req: %p [#%d] (from %d)", req->sk,
32077 ++ (req->sk)?req->sk->sk_nid:0, nx_current_nid());
32078 ++ if (req->sk &&
32079 ++ !nx_check(req->sk->sk_nid, VS_WATCH_P | VS_IDENT))
32080 ++ continue;
32081 + if (req->rsk_ops->family == st->family) {
32082 + cur = req;
32083 + goto out;
32084 +@@ -1998,6 +2004,10 @@ get_req:
32085 + }
32086 + get_sk:
32087 + sk_for_each_from(sk, node) {
32088 ++ vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
32089 ++ sk, sk->sk_nid, nx_current_nid());
32090 ++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
32091 ++ continue;
32092 + if (sk->sk_family == st->family) {
32093 + cur = sk;
32094 + goto out;
32095 +@@ -2049,18 +2059,26 @@ static void *established_get_first(struc
32096 +
32097 + read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
32098 + sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
32099 +- if (sk->sk_family != st->family) {
32100 ++ vxdprintk(VXD_CBIT(net, 6),
32101 ++ "sk,egf: %p [#%d] (from %d)",
32102 ++ sk, sk->sk_nid, nx_current_nid());
32103 ++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
32104 ++ continue;
32105 ++ if (sk->sk_family != st->family)
32106 + continue;
32107 +- }
32108 + rc = sk;
32109 + goto out;
32110 + }
32111 + st->state = TCP_SEQ_STATE_TIME_WAIT;
32112 + inet_twsk_for_each(tw, node,
32113 + &tcp_hashinfo.ehash[st->bucket].twchain) {
32114 +- if (tw->tw_family != st->family) {
32115 ++ vxdprintk(VXD_CBIT(net, 6),
32116 ++ "tw: %p [#%d] (from %d)",
32117 ++ tw, tw->tw_nid, nx_current_nid());
32118 ++ if (!nx_check(tw->tw_nid, VS_WATCH_P | VS_IDENT))
32119 ++ continue;
32120 ++ if (tw->tw_family != st->family)
32121 + continue;
32122 +- }
32123 + rc = tw;
32124 + goto out;
32125 + }
32126 +@@ -2084,7 +2102,8 @@ static void *established_get_next(struct
32127 + tw = cur;
32128 + tw = tw_next(tw);
32129 + get_tw:
32130 +- while (tw && tw->tw_family != st->family) {
32131 ++ while (tw && (tw->tw_family != st->family ||
32132 ++ !nx_check(tw->tw_nid, VS_WATCH_P | VS_IDENT))) {
32133 + tw = tw_next(tw);
32134 + }
32135 + if (tw) {
32136 +@@ -2108,6 +2127,11 @@ get_tw:
32137 + sk = sk_next(sk);
32138 +
32139 + sk_for_each_from(sk, node) {
32140 ++ vxdprintk(VXD_CBIT(net, 6),
32141 ++ "sk,egn: %p [#%d] (from %d)",
32142 ++ sk, sk->sk_nid, nx_current_nid());
32143 ++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
32144 ++ continue;
32145 + if (sk->sk_family == st->family)
32146 + goto found;
32147 + }
32148 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/tcp_minisocks.c linux-2.6.22.19-vs2.2.0.7/net/ipv4/tcp_minisocks.c
32149 +--- linux-2.6.22.19/net/ipv4/tcp_minisocks.c 2007-07-09 13:20:06 +0200
32150 ++++ linux-2.6.22.19-vs2.2.0.7/net/ipv4/tcp_minisocks.c 2007-06-15 02:37:04 +0200
32151 +@@ -28,6 +28,10 @@
32152 + #include <net/inet_common.h>
32153 + #include <net/xfrm.h>
32154 +
32155 ++#include <linux/vs_limit.h>
32156 ++#include <linux/vs_socket.h>
32157 ++#include <linux/vs_context.h>
32158 ++
32159 + #ifdef CONFIG_SYSCTL
32160 + #define SYNC_INIT 0 /* let the user enable it */
32161 + #else
32162 +@@ -293,6 +297,11 @@ void tcp_time_wait(struct sock *sk, int
32163 + tcptw->tw_ts_recent = tp->rx_opt.ts_recent;
32164 + tcptw->tw_ts_recent_stamp = tp->rx_opt.ts_recent_stamp;
32165 +
32166 ++ tw->tw_xid = sk->sk_xid;
32167 ++ tw->tw_vx_info = NULL;
32168 ++ tw->tw_nid = sk->sk_nid;
32169 ++ tw->tw_nx_info = NULL;
32170 ++
32171 + #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
32172 + if (tw->tw_family == PF_INET6) {
32173 + struct ipv6_pinfo *np = inet6_sk(sk);
32174 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/udp.c linux-2.6.22.19-vs2.2.0.7/net/ipv4/udp.c
32175 +--- linux-2.6.22.19/net/ipv4/udp.c 2007-07-09 13:20:06 +0200
32176 ++++ linux-2.6.22.19-vs2.2.0.7/net/ipv4/udp.c 2007-06-17 06:02:02 +0200
32177 +@@ -221,11 +221,8 @@ int udp_get_port(struct sock *sk, unsign
32178 +
32179 + int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
32180 + {
32181 +- struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
32182 +-
32183 + return ( !ipv6_only_sock(sk2) &&
32184 +- (!inet1->rcv_saddr || !inet2->rcv_saddr ||
32185 +- inet1->rcv_saddr == inet2->rcv_saddr ));
32186 ++ nx_addr_conflict(sk1->sk_nx_info, inet_rcv_saddr(sk1), sk2));
32187 + }
32188 +
32189 + static inline int udp_v4_get_port(struct sock *sk, unsigned short snum)
32190 +@@ -246,15 +243,22 @@ static struct sock *__udp4_lib_lookup(__
32191 + int badness = -1;
32192 +
32193 + read_lock(&udp_hash_lock);
32194 ++
32195 + sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
32196 + struct inet_sock *inet = inet_sk(sk);
32197 +
32198 + if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) {
32199 + int score = (sk->sk_family == PF_INET ? 1 : 0);
32200 ++
32201 + if (inet->rcv_saddr) {
32202 + if (inet->rcv_saddr != daddr)
32203 + continue;
32204 + score+=2;
32205 ++ } else if (sk->sk_nx_info) {
32206 ++ if (addr_in_nx_info(sk->sk_nx_info, daddr))
32207 ++ score+=2;
32208 ++ else
32209 ++ continue;
32210 + }
32211 + if (inet->daddr) {
32212 + if (inet->daddr != saddr)
32213 +@@ -280,6 +284,7 @@ static struct sock *__udp4_lib_lookup(__
32214 + }
32215 + }
32216 + }
32217 ++
32218 + if (result)
32219 + sock_hold(result);
32220 + read_unlock(&udp_hash_lock);
32221 +@@ -301,7 +306,8 @@ static inline struct sock *udp_v4_mcast_
32222 + if (s->sk_hash != hnum ||
32223 + (inet->daddr && inet->daddr != rmt_addr) ||
32224 + (inet->dport != rmt_port && inet->dport) ||
32225 +- (inet->rcv_saddr && inet->rcv_saddr != loc_addr) ||
32226 ++ (inet->rcv_saddr && inet->rcv_saddr != loc_addr &&
32227 ++ inet->rcv_saddr2 && inet->rcv_saddr2 != loc_addr) ||
32228 + ipv6_only_sock(s) ||
32229 + (s->sk_bound_dev_if && s->sk_bound_dev_if != dif))
32230 + continue;
32231 +@@ -631,7 +637,20 @@ int udp_sendmsg(struct kiocb *iocb, stru
32232 + .uli_u = { .ports =
32233 + { .sport = inet->sport,
32234 + .dport = dport } } };
32235 ++ struct nx_info *nxi = sk->sk_nx_info;
32236 ++
32237 + security_sk_classify_flow(sk, &fl);
32238 ++ if (nxi) {
32239 ++ err = ip_find_src(nxi, &rt, &fl);
32240 ++ if (err)
32241 ++ goto out;
32242 ++ if (daddr == IPI_LOOPBACK && !nx_check(0, VS_ADMIN))
32243 ++ daddr = fl.fl4_dst = nxi->ipv4[0];
32244 ++#ifdef CONFIG_VSERVER_REMAP_SADDR
32245 ++ if (saddr == IPI_LOOPBACK && !nx_check(0, VS_ADMIN))
32246 ++ saddr = fl.fl4_src = nxi->ipv4[0];
32247 ++#endif
32248 ++ }
32249 + err = ip_route_output_flow(&rt, &fl, sk, 1);
32250 + if (err) {
32251 + if (err == -ENETUNREACH)
32252 +@@ -1551,7 +1570,8 @@ static struct sock *udp_get_first(struct
32253 + for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
32254 + struct hlist_node *node;
32255 + sk_for_each(sk, node, state->hashtable + state->bucket) {
32256 +- if (sk->sk_family == state->family)
32257 ++ if (sk->sk_family == state->family &&
32258 ++ nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
32259 + goto found;
32260 + }
32261 + }
32262 +@@ -1568,7 +1588,8 @@ static struct sock *udp_get_next(struct
32263 + sk = sk_next(sk);
32264 + try_again:
32265 + ;
32266 +- } while (sk && sk->sk_family != state->family);
32267 ++ } while (sk && (sk->sk_family != state->family ||
32268 ++ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
32269 +
32270 + if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
32271 + sk = sk_head(state->hashtable + state->bucket);
32272 +diff -NurpP --minimal linux-2.6.22.19/net/ipv6/addrconf.c linux-2.6.22.19-vs2.2.0.7/net/ipv6/addrconf.c
32273 +--- linux-2.6.22.19/net/ipv6/addrconf.c 2008-03-14 20:19:05 +0100
32274 ++++ linux-2.6.22.19-vs2.2.0.7/net/ipv6/addrconf.c 2008-01-09 20:53:07 +0100
32275 +@@ -2788,7 +2788,10 @@ static void if6_seq_stop(struct seq_file
32276 + static int if6_seq_show(struct seq_file *seq, void *v)
32277 + {
32278 + struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
32279 +- seq_printf(seq,
32280 ++
32281 ++ /* no ipv6 inside a vserver for now */
32282 ++ if (nx_check(0, VS_ADMIN|VS_WATCH))
32283 ++ seq_printf(seq,
32284 + NIP6_SEQFMT " %02x %02x %02x %02x %8s\n",
32285 + NIP6(ifp->addr),
32286 + ifp->idev->dev->ifindex,
32287 +@@ -3271,6 +3274,10 @@ static int inet6_dump_addr(struct sk_buf
32288 + struct ifmcaddr6 *ifmca;
32289 + struct ifacaddr6 *ifaca;
32290 +
32291 ++ /* no ipv6 inside a vserver for now */
32292 ++ if (skb->sk && skb->sk->sk_vx_info)
32293 ++ return skb->len;
32294 ++
32295 + s_idx = cb->args[0];
32296 + s_ip_idx = ip_idx = cb->args[1];
32297 +
32298 +@@ -3594,6 +3601,10 @@ static int inet6_dump_ifinfo(struct sk_b
32299 + struct net_device *dev;
32300 + struct inet6_dev *idev;
32301 +
32302 ++ /* no ipv6 inside a vserver for now */
32303 ++ if (skb->sk && skb->sk->sk_vx_info)
32304 ++ return skb->len;
32305 ++
32306 + read_lock(&dev_base_lock);
32307 + idx = 0;
32308 + for_each_netdev(dev) {
32309 +diff -NurpP --minimal linux-2.6.22.19/net/netlink/af_netlink.c linux-2.6.22.19-vs2.2.0.7/net/netlink/af_netlink.c
32310 +--- linux-2.6.22.19/net/netlink/af_netlink.c 2008-03-14 20:19:05 +0100
32311 ++++ linux-2.6.22.19-vs2.2.0.7/net/netlink/af_netlink.c 2008-01-18 12:08:14 +0100
32312 +@@ -56,6 +56,9 @@
32313 + #include <linux/audit.h>
32314 + #include <linux/selinux.h>
32315 + #include <linux/mutex.h>
32316 ++#include <linux/vs_context.h>
32317 ++#include <linux/vs_network.h>
32318 ++#include <linux/vs_limit.h>
32319 +
32320 + #include <net/sock.h>
32321 + #include <net/scm.h>
32322 +@@ -885,6 +888,10 @@ static inline int do_one_broadcast(struc
32323 + !test_bit(p->group - 1, nlk->groups))
32324 + goto out;
32325 +
32326 ++ if (sk->sk_nx_info &&
32327 ++ (p->group == RTNLGRP_IPV4_IFADDR || p->group == RTNLGRP_IPV6_IFADDR))
32328 ++ goto out;
32329 ++
32330 + if (p->failure) {
32331 + netlink_overrun(sk);
32332 + goto out;
32333 +diff -NurpP --minimal linux-2.6.22.19/net/rxrpc/Kconfig linux-2.6.22.19-vs2.2.0.7/net/rxrpc/Kconfig
32334 +--- linux-2.6.22.19/net/rxrpc/Kconfig 2008-03-14 20:19:05 +0100
32335 ++++ linux-2.6.22.19-vs2.2.0.7/net/rxrpc/Kconfig 2008-03-14 19:57:11 +0100
32336 +@@ -4,7 +4,7 @@
32337 +
32338 + config AF_RXRPC
32339 + tristate "RxRPC session sockets"
32340 +- depends on INET && EXPERIMENTAL
32341 ++ depends on INET && EXPERIMENTAL && !VSERVER_SECURITY
32342 + select CRYPTO
32343 + select KEYS
32344 + help
32345 +diff -NurpP --minimal linux-2.6.22.19/net/socket.c linux-2.6.22.19-vs2.2.0.7/net/socket.c
32346 +--- linux-2.6.22.19/net/socket.c 2008-03-14 20:19:05 +0100
32347 ++++ linux-2.6.22.19-vs2.2.0.7/net/socket.c 2008-01-09 20:53:07 +0100
32348 +@@ -92,6 +92,8 @@
32349 +
32350 + #include <net/sock.h>
32351 + #include <linux/netfilter.h>
32352 ++#include <linux/vs_base.h>
32353 ++#include <linux/vs_socket.h>
32354 +
32355 + static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
32356 + static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
32357 +@@ -543,7 +545,7 @@ static inline int __sock_sendmsg(struct
32358 + struct msghdr *msg, size_t size)
32359 + {
32360 + struct sock_iocb *si = kiocb_to_siocb(iocb);
32361 +- int err;
32362 ++ int err, len;
32363 +
32364 + si->sock = sock;
32365 + si->scm = NULL;
32366 +@@ -554,7 +556,22 @@ static inline int __sock_sendmsg(struct
32367 + if (err)
32368 + return err;
32369 +
32370 +- return sock->ops->sendmsg(iocb, sock, msg, size);
32371 ++ len = sock->ops->sendmsg(iocb, sock, msg, size);
32372 ++ if (sock->sk) {
32373 ++ if (len == size)
32374 ++ vx_sock_send(sock->sk, size);
32375 ++ else
32376 ++ vx_sock_fail(sock->sk, size);
32377 ++ }
32378 ++ vxdprintk(VXD_CBIT(net, 7),
32379 ++ "__sock_sendmsg: %p[%p,%p,%p;%d/%d]:%d/%d",
32380 ++ sock, sock->sk,
32381 ++ (sock->sk)?sock->sk->sk_nx_info:0,
32382 ++ (sock->sk)?sock->sk->sk_vx_info:0,
32383 ++ (sock->sk)?sock->sk->sk_xid:0,
32384 ++ (sock->sk)?sock->sk->sk_nid:0,
32385 ++ (unsigned int)size, len);
32386 ++ return len;
32387 + }
32388 +
32389 + int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
32390 +@@ -623,7 +640,7 @@ EXPORT_SYMBOL_GPL(__sock_recv_timestamp)
32391 + static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
32392 + struct msghdr *msg, size_t size, int flags)
32393 + {
32394 +- int err;
32395 ++ int err, len;
32396 + struct sock_iocb *si = kiocb_to_siocb(iocb);
32397 +
32398 + si->sock = sock;
32399 +@@ -636,7 +653,18 @@ static inline int __sock_recvmsg(struct
32400 + if (err)
32401 + return err;
32402 +
32403 +- return sock->ops->recvmsg(iocb, sock, msg, size, flags);
32404 ++ len = sock->ops->recvmsg(iocb, sock, msg, size, flags);
32405 ++ if ((len >= 0) && sock->sk)
32406 ++ vx_sock_recv(sock->sk, len);
32407 ++ vxdprintk(VXD_CBIT(net, 7),
32408 ++ "__sock_recvmsg: %p[%p,%p,%p;%d/%d]:%d/%d",
32409 ++ sock, sock->sk,
32410 ++ (sock->sk)?sock->sk->sk_nx_info:0,
32411 ++ (sock->sk)?sock->sk->sk_vx_info:0,
32412 ++ (sock->sk)?sock->sk->sk_xid:0,
32413 ++ (sock->sk)?sock->sk->sk_nid:0,
32414 ++ (unsigned int)size, len);
32415 ++ return len;
32416 + }
32417 +
32418 + int sock_recvmsg(struct socket *sock, struct msghdr *msg,
32419 +@@ -1087,6 +1115,10 @@ static int __sock_create(int family, int
32420 + if (type < 0 || type >= SOCK_MAX)
32421 + return -EINVAL;
32422 +
32423 ++ /* disable IPv6 inside vservers for now */
32424 ++ if (family == PF_INET6 && !nx_check(0, VS_ADMIN))
32425 ++ return -EAFNOSUPPORT;
32426 ++
32427 + /* Compatibility.
32428 +
32429 + This uglymoron is moved from INET layer to here to avoid
32430 +@@ -1204,6 +1236,7 @@ asmlinkage long sys_socket(int family, i
32431 + if (retval < 0)
32432 + goto out;
32433 +
32434 ++ set_bit(SOCK_USER_SOCKET, &sock->flags);
32435 + retval = sock_map_fd(sock);
32436 + if (retval < 0)
32437 + goto out_release;
32438 +@@ -1236,10 +1269,12 @@ asmlinkage long sys_socketpair(int famil
32439 + err = sock_create(family, type, protocol, &sock1);
32440 + if (err < 0)
32441 + goto out;
32442 ++ set_bit(SOCK_USER_SOCKET, &sock1->flags);
32443 +
32444 + err = sock_create(family, type, protocol, &sock2);
32445 + if (err < 0)
32446 + goto out_release_1;
32447 ++ set_bit(SOCK_USER_SOCKET, &sock2->flags);
32448 +
32449 + err = sock1->ops->socketpair(sock1, sock2);
32450 + if (err < 0)
32451 +diff -NurpP --minimal linux-2.6.22.19/net/sunrpc/auth.c linux-2.6.22.19-vs2.2.0.7/net/sunrpc/auth.c
32452 +--- linux-2.6.22.19/net/sunrpc/auth.c 2007-05-02 19:25:48 +0200
32453 ++++ linux-2.6.22.19-vs2.2.0.7/net/sunrpc/auth.c 2007-06-15 02:37:04 +0200
32454 +@@ -13,6 +13,7 @@
32455 + #include <linux/errno.h>
32456 + #include <linux/sunrpc/clnt.h>
32457 + #include <linux/spinlock.h>
32458 ++#include <linux/vs_tag.h>
32459 +
32460 + #ifdef RPC_DEBUG
32461 + # define RPCDBG_FACILITY RPCDBG_AUTH
32462 +@@ -263,6 +264,7 @@ rpcauth_lookupcred(struct rpc_auth *auth
32463 + struct auth_cred acred = {
32464 + .uid = current->fsuid,
32465 + .gid = current->fsgid,
32466 ++ .tag = dx_current_tag(),
32467 + .group_info = current->group_info,
32468 + };
32469 + struct rpc_cred *ret;
32470 +@@ -282,6 +284,7 @@ rpcauth_bindcred(struct rpc_task *task)
32471 + struct auth_cred acred = {
32472 + .uid = current->fsuid,
32473 + .gid = current->fsgid,
32474 ++ .tag = dx_current_tag(),
32475 + .group_info = current->group_info,
32476 + };
32477 + struct rpc_cred *ret;
32478 +diff -NurpP --minimal linux-2.6.22.19/net/sunrpc/auth_unix.c linux-2.6.22.19-vs2.2.0.7/net/sunrpc/auth_unix.c
32479 +--- linux-2.6.22.19/net/sunrpc/auth_unix.c 2007-05-02 19:25:48 +0200
32480 ++++ linux-2.6.22.19-vs2.2.0.7/net/sunrpc/auth_unix.c 2007-06-15 02:37:04 +0200
32481 +@@ -11,12 +11,14 @@
32482 + #include <linux/module.h>
32483 + #include <linux/sunrpc/clnt.h>
32484 + #include <linux/sunrpc/auth.h>
32485 ++#include <linux/vs_tag.h>
32486 +
32487 + #define NFS_NGROUPS 16
32488 +
32489 + struct unx_cred {
32490 + struct rpc_cred uc_base;
32491 + gid_t uc_gid;
32492 ++ tag_t uc_tag;
32493 + gid_t uc_gids[NFS_NGROUPS];
32494 + };
32495 + #define uc_uid uc_base.cr_uid
32496 +@@ -79,6 +81,7 @@ unx_create_cred(struct rpc_auth *auth, s
32497 + if (flags & RPCAUTH_LOOKUP_ROOTCREDS) {
32498 + cred->uc_uid = 0;
32499 + cred->uc_gid = 0;
32500 ++ cred->uc_tag = dx_current_tag();
32501 + cred->uc_gids[0] = NOGROUP;
32502 + } else {
32503 + int groups = acred->group_info->ngroups;
32504 +@@ -87,6 +90,7 @@ unx_create_cred(struct rpc_auth *auth, s
32505 +
32506 + cred->uc_uid = acred->uid;
32507 + cred->uc_gid = acred->gid;
32508 ++ cred->uc_tag = acred->tag;
32509 + for (i = 0; i < groups; i++)
32510 + cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
32511 + if (i < NFS_NGROUPS)
32512 +@@ -118,7 +122,8 @@ unx_match(struct auth_cred *acred, struc
32513 + int groups;
32514 +
32515 + if (cred->uc_uid != acred->uid
32516 +- || cred->uc_gid != acred->gid)
32517 ++ || cred->uc_gid != acred->gid
32518 ++ || cred->uc_tag != acred->tag)
32519 + return 0;
32520 +
32521 + groups = acred->group_info->ngroups;
32522 +@@ -144,7 +149,7 @@ unx_marshal(struct rpc_task *task, __be3
32523 + struct rpc_clnt *clnt = task->tk_client;
32524 + struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred;
32525 + __be32 *base, *hold;
32526 +- int i;
32527 ++ int i, tag;
32528 +
32529 + *p++ = htonl(RPC_AUTH_UNIX);
32530 + base = p++;
32531 +@@ -154,9 +159,12 @@ unx_marshal(struct rpc_task *task, __be3
32532 + * Copy the UTS nodename captured when the client was created.
32533 + */
32534 + p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
32535 ++ tag = task->tk_client->cl_tag;
32536 +
32537 +- *p++ = htonl((u32) cred->uc_uid);
32538 +- *p++ = htonl((u32) cred->uc_gid);
32539 ++ *p++ = htonl((u32) TAGINO_UID(tag,
32540 ++ cred->uc_uid, cred->uc_tag));
32541 ++ *p++ = htonl((u32) TAGINO_GID(tag,
32542 ++ cred->uc_gid, cred->uc_tag));
32543 + hold = p++;
32544 + for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++)
32545 + *p++ = htonl((u32) cred->uc_gids[i]);
32546 +diff -NurpP --minimal linux-2.6.22.19/net/sunrpc/clnt.c linux-2.6.22.19-vs2.2.0.7/net/sunrpc/clnt.c
32547 +--- linux-2.6.22.19/net/sunrpc/clnt.c 2007-07-09 13:20:13 +0200
32548 ++++ linux-2.6.22.19-vs2.2.0.7/net/sunrpc/clnt.c 2007-06-15 02:37:04 +0200
32549 +@@ -30,6 +30,7 @@
32550 + #include <linux/smp_lock.h>
32551 + #include <linux/utsname.h>
32552 + #include <linux/workqueue.h>
32553 ++#include <linux/vs_cvirt.h>
32554 +
32555 + #include <linux/sunrpc/clnt.h>
32556 + #include <linux/sunrpc/rpc_pipe_fs.h>
32557 +@@ -249,7 +250,9 @@ struct rpc_clnt *rpc_create(struct rpc_c
32558 + clnt->cl_oneshot = 1;
32559 + if (args->flags & RPC_CLNT_CREATE_DISCRTRY)
32560 + clnt->cl_discrtry = 1;
32561 +-
32562 ++ /* TODO: handle RPC_CLNT_CREATE_TAGGED
32563 ++ if (args->flags & RPC_CLNT_CREATE_TAGGED)
32564 ++ clnt->cl_tag = 1; */
32565 + return clnt;
32566 + }
32567 + EXPORT_SYMBOL_GPL(rpc_create);
32568 +diff -NurpP --minimal linux-2.6.22.19/net/unix/af_unix.c linux-2.6.22.19-vs2.2.0.7/net/unix/af_unix.c
32569 +--- linux-2.6.22.19/net/unix/af_unix.c 2008-03-14 20:19:05 +0100
32570 ++++ linux-2.6.22.19-vs2.2.0.7/net/unix/af_unix.c 2008-01-09 20:53:07 +0100
32571 +@@ -115,6 +115,8 @@
32572 + #include <linux/mount.h>
32573 + #include <net/checksum.h>
32574 + #include <linux/security.h>
32575 ++#include <linux/vs_context.h>
32576 ++#include <linux/vs_limit.h>
32577 +
32578 + int sysctl_unix_max_dgram_qlen __read_mostly = 10;
32579 +
32580 +@@ -252,6 +254,8 @@ static struct sock *__unix_find_socket_b
32581 + sk_for_each(s, node, &unix_socket_table[hash ^ type]) {
32582 + struct unix_sock *u = unix_sk(s);
32583 +
32584 ++ if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT))
32585 ++ continue;
32586 + if (u->addr->len == len &&
32587 + !memcmp(u->addr->name, sunname, len))
32588 + goto found;
32589 +@@ -807,7 +811,7 @@ static int unix_bind(struct socket *sock
32590 + */
32591 + mode = S_IFSOCK |
32592 + (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
32593 +- err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
32594 ++ err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
32595 + if (err)
32596 + goto out_mknod_dput;
32597 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
32598 +diff -NurpP --minimal linux-2.6.22.19/net/x25/af_x25.c linux-2.6.22.19-vs2.2.0.7/net/x25/af_x25.c
32599 +--- linux-2.6.22.19/net/x25/af_x25.c 2007-07-09 13:20:13 +0200
32600 ++++ linux-2.6.22.19-vs2.2.0.7/net/x25/af_x25.c 2007-06-15 02:37:04 +0200
32601 +@@ -500,7 +500,10 @@ static int x25_create(struct socket *soc
32602 +
32603 + x25 = x25_sk(sk);
32604 +
32605 +- sock_init_data(sock, sk);
32606 ++ sk->sk_socket = sock;
32607 ++ sk->sk_type = sock->type;
32608 ++ sk->sk_sleep = &sock->wait;
32609 ++ sock->sk = sk;
32610 +
32611 + x25_init_timers(sk);
32612 +
32613 +diff -NurpP --minimal linux-2.6.22.19/security/Kconfig linux-2.6.22.19-vs2.2.0.7/security/Kconfig
32614 +--- linux-2.6.22.19/security/Kconfig 2006-11-30 21:19:47 +0100
32615 ++++ linux-2.6.22.19-vs2.2.0.7/security/Kconfig 2007-06-15 02:37:04 +0200
32616 +@@ -6,6 +6,7 @@ menu "Security options"
32617 +
32618 + config KEYS
32619 + bool "Enable access key retention support"
32620 ++ depends on !VSERVER_SECURITY
32621 + help
32622 + This option provides support for retaining authentication tokens and
32623 + access keys in the kernel.
32624 +diff -NurpP --minimal linux-2.6.22.19/security/commoncap.c linux-2.6.22.19-vs2.2.0.7/security/commoncap.c
32625 +--- linux-2.6.22.19/security/commoncap.c 2007-07-09 13:20:14 +0200
32626 ++++ linux-2.6.22.19-vs2.2.0.7/security/commoncap.c 2007-06-15 02:37:04 +0200
32627 +@@ -22,10 +22,11 @@
32628 + #include <linux/ptrace.h>
32629 + #include <linux/xattr.h>
32630 + #include <linux/hugetlb.h>
32631 ++#include <linux/vs_context.h>
32632 +
32633 + int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
32634 + {
32635 +- NETLINK_CB(skb).eff_cap = current->cap_effective;
32636 ++ cap_t(NETLINK_CB(skb).eff_cap) = vx_mbcap(cap_effective);
32637 + return 0;
32638 + }
32639 +
32640 +@@ -43,7 +44,7 @@ EXPORT_SYMBOL(cap_netlink_recv);
32641 + int cap_capable (struct task_struct *tsk, int cap)
32642 + {
32643 + /* Derived from include/linux/sched.h:capable. */
32644 +- if (cap_raised(tsk->cap_effective, cap))
32645 ++ if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
32646 + return 0;
32647 + return -EPERM;
32648 + }
32649 +@@ -141,7 +142,8 @@ void cap_bprm_apply_creds (struct linux_
32650 + /* Derived from fs/exec.c:compute_creds. */
32651 + kernel_cap_t new_permitted, working;
32652 +
32653 +- new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
32654 ++ new_permitted = cap_intersect (bprm->cap_permitted,
32655 ++ vx_current_cap_bset());
32656 + working = cap_intersect (bprm->cap_inheritable,
32657 + current->cap_inheritable);
32658 + new_permitted = cap_combine (new_permitted, working);
32659 +@@ -310,7 +312,8 @@ void cap_task_reparent_to_init (struct t
32660 +
32661 + int cap_syslog (int type)
32662 + {
32663 +- if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
32664 ++ if ((type != 3 && type != 10) &&
32665 ++ !vx_capable(CAP_SYS_ADMIN, VXC_SYSLOG))
32666 + return -EPERM;
32667 + return 0;
32668 + }
32669 +diff -NurpP --minimal linux-2.6.22.19/security/dummy.c linux-2.6.22.19-vs2.2.0.7/security/dummy.c
32670 +--- linux-2.6.22.19/security/dummy.c 2007-05-02 19:25:51 +0200
32671 ++++ linux-2.6.22.19-vs2.2.0.7/security/dummy.c 2007-06-15 02:37:04 +0200
32672 +@@ -28,6 +28,7 @@
32673 + #include <linux/hugetlb.h>
32674 + #include <linux/ptrace.h>
32675 + #include <linux/file.h>
32676 ++#include <linux/vs_context.h>
32677 +
32678 + static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
32679 + {
32680 +@@ -678,7 +679,7 @@ static int dummy_sem_semop (struct sem_a
32681 +
32682 + static int dummy_netlink_send (struct sock *sk, struct sk_buff *skb)
32683 + {
32684 +- NETLINK_CB(skb).eff_cap = current->cap_effective;
32685 ++ cap_t(NETLINK_CB(skb).eff_cap) = vx_mbcap(cap_effective);
32686 + return 0;
32687 + }
32688 +
32689 +diff -NurpP --minimal linux-2.6.22.19/security/selinux/hooks.c linux-2.6.22.19-vs2.2.0.7/security/selinux/hooks.c
32690 +--- linux-2.6.22.19/security/selinux/hooks.c 2008-03-14 20:19:05 +0100
32691 ++++ linux-2.6.22.19-vs2.2.0.7/security/selinux/hooks.c 2007-10-30 01:24:36 +0100
32692 +@@ -60,7 +60,6 @@
32693 + #include <linux/dccp.h>
32694 + #include <linux/quota.h>
32695 + #include <linux/un.h> /* for Unix socket types */
32696 +-#include <net/af_unix.h> /* for Unix socket types */
32697 + #include <linux/parser.h>
32698 + #include <linux/nfs_mount.h>
32699 + #include <net/ipv6.h>
32700
32701 --
32702 gentoo-commits@l.g.o mailing list