Gentoo Archives: gentoo-commits

From: "Benedikt Boehm (hollow)" <hollow@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] vps r558 - in vserver-sources: . 2.3.0.34
Date: Mon, 17 Mar 2008 10:16:05
Message-Id: E1JbCN8-0007nx-St@stork.gentoo.org
1 Author: hollow
2 Date: 2008-03-17 10:15:13 +0000 (Mon, 17 Mar 2008)
3 New Revision: 558
4
5 Added:
6 vserver-sources/2.3.0.34/
7 vserver-sources/2.3.0.34/1012_linux-2.6.22.18.patch
8 vserver-sources/2.3.0.34/1013_linux-2.6.22.19.patch
9 vserver-sources/2.3.0.34/4410_vs2.3.0.34.patch
10 Log:
11 add 2.3.0.34
12
13 Copied: vserver-sources/2.3.0.34/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.3.0.34/1012_linux-2.6.22.18.patch (rev 0)
16 +++ vserver-sources/2.3.0.34/1012_linux-2.6.22.18.patch 2008-03-17 10:15:13 UTC (rev 558)
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 Copied: vserver-sources/2.3.0.34/1013_linux-2.6.22.19.patch (from rev 557, vserver-sources/2.2.0.7/1013_linux-2.6.22.19.patch)
3702 ===================================================================
3703 --- vserver-sources/2.3.0.34/1013_linux-2.6.22.19.patch (rev 0)
3704 +++ vserver-sources/2.3.0.34/1013_linux-2.6.22.19.patch 2008-03-17 10:15:13 UTC (rev 558)
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.3.0.34/4410_vs2.3.0.34.patch
4739 ===================================================================
4740 --- vserver-sources/2.3.0.34/4410_vs2.3.0.34.patch (rev 0)
4741 +++ vserver-sources/2.3.0.34/4410_vs2.3.0.34.patch 2008-03-17 10:15:13 UTC (rev 558)
4742 @@ -0,0 +1,30343 @@
4743 +diff -NurpP --minimal linux-2.6.22.19/Documentation/vserver/debug.txt linux-2.6.22.19-vs2.3.0.34/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.3.0.34/Documentation/vserver/debug.txt 2007-08-05 20:53:12 +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.3.0.34/Makefile
4902 +--- linux-2.6.22.19/Makefile 2008-03-14 20:18:58 +0100
4903 ++++ linux-2.6.22.19-vs2.3.0.34/Makefile 2008-03-17 00:59:45 +0100
4904 +@@ -1,7 +1,7 @@
4905 + VERSION = 2
4906 + PATCHLEVEL = 6
4907 + SUBLEVEL = 22
4908 +-EXTRAVERSION =
4909 ++EXTRAVERSION = -vs2.3.0.34-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.3.0.34/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.3.0.34/arch/alpha/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/alpha/kernel/asm-offsets.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/alpha/kernel/entry.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/alpha/kernel/osf_sys.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/alpha/kernel/ptrace.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/alpha/kernel/semaphore.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/alpha/kernel/systbls.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/alpha/kernel/traps.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/alpha/mm/fault.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/arm/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/arm/kernel/calls.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/arm/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/arm/kernel/traps.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/arm/mm/fault.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/arm26/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/arm26/kernel/calls.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/arm26/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/arm26/kernel/traps.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/cris/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/cris/arch-v10/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/cris/arch-v32/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/frv/kernel/kernel_thread.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/h8300/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/h8300/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/i386/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/i386/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/i386/kernel/syscall_table.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/i386/kernel/sysenter.c 2007-09-05 03:06:10 +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.3.0.34/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.3.0.34/arch/i386/kernel/traps.c 2008-03-14 21:11:29 +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.3.0.34/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.3.0.34/arch/i386/mm/fault.c 2007-09-05 03:06:10 +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.3.0.34/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.3.0.34/arch/ia64/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ia64/ia32/binfmt_elf32.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ia64/ia32/ia32_entry.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ia64/ia32/sys_ia32.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ia64/kernel/asm-offsets.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ia64/kernel/entry.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ia64/kernel/perfmon.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ia64/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ia64/kernel/ptrace.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ia64/kernel/traps.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ia64/mm/fault.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/m32r/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/m32r/kernel/traps.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/m68k/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/m68k/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/m68k/kernel/ptrace.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/m68k/kernel/traps.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/m68knommu/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/m68knommu/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/m68knommu/kernel/traps.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/mips/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/mips/kernel/linux32.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/mips/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/mips/kernel/ptrace.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/mips/kernel/scall32-o32.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/mips/kernel/scall64-64.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/mips/kernel/scall64-n32.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/mips/kernel/scall64-o32.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/mips/kernel/traps.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/mips/mm/fault.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/parisc/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/parisc/kernel/entry.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/parisc/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/parisc/kernel/sys_parisc32.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/parisc/kernel/syscall_table.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/parisc/kernel/traps.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/parisc/mm/fault.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/powerpc/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/powerpc/kernel/asm-offsets.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/powerpc/kernel/irq.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/powerpc/kernel/misc_32.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/powerpc/kernel/misc_64.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/powerpc/kernel/process.c 2007-09-30 14:57:55 +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.3.0.34/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.3.0.34/arch/powerpc/kernel/sys_ppc32.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/powerpc/kernel/traps.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/powerpc/kernel/vdso.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/powerpc/mm/fault.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ppc/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ppc/kernel/asm-offsets.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ppc/kernel/misc.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ppc/kernel/traps.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/ppc/mm/fault.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/s390/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/s390/kernel/compat_linux.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/s390/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/s390/kernel/ptrace.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/s390/kernel/syscalls.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/s390/mm/fault.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sh/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sh/kernel/irq.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sh/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sh/kernel/vsyscall/vsyscall.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sh/mm/fault.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sh64/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sh64/mm/fault.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sparc/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sparc/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sparc/kernel/ptrace.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sparc/kernel/systbls.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sparc/kernel/traps.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sparc/mm/fault.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sparc64/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sparc64/kernel/binfmt_aout32.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sparc64/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sparc64/kernel/ptrace.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sparc64/kernel/sys_sparc32.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sparc64/kernel/systbls.S 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/sparc64/kernel/traps.c 2007-09-05 03:06:11 +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.3.0.34/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.3.0.34/arch/sparc64/mm/fault.c 2007-09-05 03:06:11 +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.3.0.34/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.3.0.34/arch/sparc64/solaris/fs.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/um/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/um/kernel/trap.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/v850/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/v850/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/v850/kernel/ptrace.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/x86_64/Kconfig 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/x86_64/ia32/ia32_aout.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/x86_64/ia32/ia32_binfmt.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/x86_64/ia32/ia32entry.S 2007-09-30 14:57:59 +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.3.0.34/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.3.0.34/arch/x86_64/ia32/sys_ia32.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/x86_64/ia32/syscall32.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/x86_64/kernel/process.c 2007-08-05 20:53:12 +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.3.0.34/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.3.0.34/arch/x86_64/kernel/traps.c 2007-09-30 17:11:18 +0200
6752 +@@ -33,6 +33,8 @@
6753 + #include <linux/uaccess.h>
6754 + #include <linux/bug.h>
6755 + #include <linux/kdebug.h>
6756 ++#include <linux/vs_context.h>
6757 ++#include <linux/vserver/history.h>
6758 +
6759 + #include <asm/system.h>
6760 + #include <asm/io.h>
6761 +@@ -413,8 +415,9 @@ void show_registers(struct pt_regs *regs
6762 + rsp = regs->rsp;
6763 + printk("CPU %d ", cpu);
6764 + __show_regs(regs);
6765 +- printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
6766 +- cur->comm, cur->pid, task_thread_info(cur), cur);
6767 ++ printk("Process %s (pid: %d[#%u], threadinfo %p, task %p)\n",
6768 ++ cur->comm, cur->pid, cur->xid,
6769 ++ task_thread_info(cur), cur);
6770 +
6771 + /*
6772 + * When in-kernel, we also print out the stack and code at the
6773 +@@ -518,6 +521,7 @@ void __kprobes __die(const char * str, s
6774 + printk("\n");
6775 + notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
6776 + show_registers(regs);
6777 ++ vxh_dump_history();
6778 + /* Executive summary in case the oops scrolled away */
6779 + printk(KERN_ALERT "RIP ");
6780 + printk_address(regs->rip);
6781 +@@ -530,6 +534,7 @@ void die(const char * str, struct pt_reg
6782 + {
6783 + unsigned long flags = oops_begin();
6784 +
6785 ++ vxh_throw_oops();
6786 + if (!user_mode(regs))
6787 + report_bug(regs->rip);
6788 +
6789 +@@ -542,12 +547,14 @@ void __kprobes die_nmi(char *str, struct
6790 + {
6791 + unsigned long flags = oops_begin();
6792 +
6793 ++ vxh_throw_oops();
6794 + /*
6795 + * We are in trouble anyway, lets at least try
6796 + * to get a message out.
6797 + */
6798 + printk(str, smp_processor_id());
6799 + show_registers(regs);
6800 ++ vxh_dump_history();
6801 + if (kexec_should_crash(current))
6802 + crash_kexec(regs);
6803 + if (do_panic || panic_on_oops)
6804 +@@ -580,8 +587,8 @@ static void __kprobes do_trap(int trapnr
6805 +
6806 + if (exception_trace && unhandled_signal(tsk, signr))
6807 + printk(KERN_INFO
6808 +- "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
6809 +- tsk->comm, tsk->pid, str,
6810 ++ "%s[%d:#%u] trap %s rip:%lx rsp:%lx error:%lx\n",
6811 ++ tsk->comm, tsk->pid, tsk->xid, str,
6812 + regs->rip, regs->rsp, error_code);
6813 +
6814 + if (info)
6815 +@@ -684,8 +691,8 @@ asmlinkage void __kprobes do_general_pro
6816 +
6817 + if (exception_trace && unhandled_signal(tsk, SIGSEGV))
6818 + printk(KERN_INFO
6819 +- "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
6820 +- tsk->comm, tsk->pid,
6821 ++ "%s[%d:#%u] general protection rip:%lx rsp:%lx error:%lx\n",
6822 ++ tsk->comm, tsk->pid, tsk->xid,
6823 + regs->rip, regs->rsp, error_code);
6824 +
6825 + force_sig(SIGSEGV, tsk);
6826 +diff -NurpP --minimal linux-2.6.22.19/arch/x86_64/mm/fault.c linux-2.6.22.19-vs2.3.0.34/arch/x86_64/mm/fault.c
6827 +--- linux-2.6.22.19/arch/x86_64/mm/fault.c 2007-07-09 13:18:08 +0200
6828 ++++ linux-2.6.22.19-vs2.3.0.34/arch/x86_64/mm/fault.c 2007-08-05 20:53:12 +0200
6829 +@@ -497,10 +497,10 @@ bad_area_nosemaphore:
6830 +
6831 + if (exception_trace && unhandled_signal(tsk, SIGSEGV)) {
6832 + printk(
6833 +- "%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
6834 ++ "%s%s[%d:#%u]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
6835 + tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
6836 +- tsk->comm, tsk->pid, address, regs->rip,
6837 +- regs->rsp, error_code);
6838 ++ tsk->comm, tsk->pid, tsk->xid, address,
6839 ++ regs->rip, regs->rsp, error_code);
6840 + }
6841 +
6842 + tsk->thread.cr2 = address;
6843 +@@ -567,7 +567,8 @@ out_of_memory:
6844 + yield();
6845 + goto again;
6846 + }
6847 +- printk("VM: killing process %s\n", tsk->comm);
6848 ++ printk("VM: killing process %s(%d:#%u)\n",
6849 ++ tsk->comm, tsk->pid, tsk->xid);
6850 + if (error_code & 4)
6851 + do_exit(SIGKILL);
6852 + goto no_context;
6853 +Files linux-2.6.22.19/core and linux-2.6.22.19-vs2.3.0.34/core differ
6854 +diff -NurpP --minimal linux-2.6.22.19/drivers/block/Kconfig linux-2.6.22.19-vs2.3.0.34/drivers/block/Kconfig
6855 +--- linux-2.6.22.19/drivers/block/Kconfig 2007-07-09 13:18:16 +0200
6856 ++++ linux-2.6.22.19-vs2.3.0.34/drivers/block/Kconfig 2007-08-05 20:53:12 +0200
6857 +@@ -311,6 +311,13 @@ config BLK_DEV_CRYPTOLOOP
6858 + instead, which can be configured to be on-disk compatible with the
6859 + cryptoloop device.
6860 +
6861 ++config BLK_DEV_VROOT
6862 ++ tristate "Virtual Root device support"
6863 ++ depends on QUOTACTL
6864 ++ ---help---
6865 ++ Saying Y here will allow you to use quota/fs ioctls on a shared
6866 ++ partition within a virtual server without compromising security.
6867 ++
6868 + config BLK_DEV_NBD
6869 + tristate "Network block device support"
6870 + depends on NET
6871 +diff -NurpP --minimal linux-2.6.22.19/drivers/block/Makefile linux-2.6.22.19-vs2.3.0.34/drivers/block/Makefile
6872 +--- linux-2.6.22.19/drivers/block/Makefile 2007-02-06 03:00:26 +0100
6873 ++++ linux-2.6.22.19-vs2.3.0.34/drivers/block/Makefile 2007-08-05 20:53:12 +0200
6874 +@@ -28,4 +28,5 @@ obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryp
6875 + obj-$(CONFIG_VIODASD) += viodasd.o
6876 + obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
6877 + obj-$(CONFIG_BLK_DEV_UB) += ub.o
6878 ++obj-$(CONFIG_BLK_DEV_VROOT) += vroot.o
6879 +
6880 +diff -NurpP --minimal linux-2.6.22.19/drivers/block/loop.c linux-2.6.22.19-vs2.3.0.34/drivers/block/loop.c
6881 +--- linux-2.6.22.19/drivers/block/loop.c 2007-07-09 13:18:16 +0200
6882 ++++ linux-2.6.22.19-vs2.3.0.34/drivers/block/loop.c 2008-03-17 00:55:07 +0100
6883 +@@ -74,6 +74,7 @@
6884 + #include <linux/highmem.h>
6885 + #include <linux/gfp.h>
6886 + #include <linux/kthread.h>
6887 ++#include <linux/vs_context.h>
6888 +
6889 + #include <asm/uaccess.h>
6890 +
6891 +@@ -790,6 +791,7 @@ static int loop_set_fd(struct loop_devic
6892 + lo->lo_blocksize = lo_blocksize;
6893 + lo->lo_device = bdev;
6894 + lo->lo_flags = lo_flags;
6895 ++ lo->lo_xid = vx_current_xid();
6896 + lo->lo_backing_file = file;
6897 + lo->transfer = transfer_none;
6898 + lo->ioctl = NULL;
6899 +@@ -909,6 +911,7 @@ static int loop_clr_fd(struct loop_devic
6900 + lo->lo_encrypt_key_size = 0;
6901 + lo->lo_flags = 0;
6902 + lo->lo_thread = NULL;
6903 ++ lo->lo_xid = 0;
6904 + memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
6905 + memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
6906 + memset(lo->lo_file_name, 0, LO_NAME_SIZE);
6907 +@@ -930,7 +933,7 @@ loop_set_status(struct loop_device *lo,
6908 + struct loop_func_table *xfer;
6909 +
6910 + if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid &&
6911 +- !capable(CAP_SYS_ADMIN))
6912 ++ !vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP))
6913 + return -EPERM;
6914 + if (lo->lo_state != Lo_bound)
6915 + return -ENXIO;
6916 +@@ -1010,7 +1013,8 @@ loop_get_status(struct loop_device *lo,
6917 + memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE);
6918 + info->lo_encrypt_type =
6919 + lo->lo_encryption ? lo->lo_encryption->number : 0;
6920 +- if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
6921 ++ if (lo->lo_encrypt_key_size &&
6922 ++ vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) {
6923 + info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
6924 + memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
6925 + lo->lo_encrypt_key_size);
6926 +@@ -1321,6 +1325,9 @@ static int lo_open(struct inode *inode,
6927 + {
6928 + struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
6929 +
6930 ++ if (!vx_check(lo->lo_xid, VS_IDENT|VS_HOSTID|VS_ADMIN_P))
6931 ++ return -EACCES;
6932 ++
6933 + mutex_lock(&lo->lo_ctl_mutex);
6934 + lo->lo_refcnt++;
6935 + mutex_unlock(&lo->lo_ctl_mutex);
6936 +diff -NurpP --minimal linux-2.6.22.19/drivers/block/vroot.c linux-2.6.22.19-vs2.3.0.34/drivers/block/vroot.c
6937 +--- linux-2.6.22.19/drivers/block/vroot.c 1970-01-01 01:00:00 +0100
6938 ++++ linux-2.6.22.19-vs2.3.0.34/drivers/block/vroot.c 2007-08-05 20:53:12 +0200
6939 +@@ -0,0 +1,281 @@
6940 ++/*
6941 ++ * linux/drivers/block/vroot.c
6942 ++ *
6943 ++ * written by Herbert Pötzl, 9/11/2002
6944 ++ * ported to 2.6.10 by Herbert Pötzl, 30/12/2004
6945 ++ *
6946 ++ * based on the loop.c code by Theodore Ts'o.
6947 ++ *
6948 ++ * Copyright (C) 2002-2007 by Herbert Pötzl.
6949 ++ * Redistribution of this file is permitted under the
6950 ++ * GNU General Public License.
6951 ++ *
6952 ++ */
6953 ++
6954 ++#include <linux/module.h>
6955 ++#include <linux/moduleparam.h>
6956 ++#include <linux/file.h>
6957 ++#include <linux/major.h>
6958 ++#include <linux/blkdev.h>
6959 ++
6960 ++#include <linux/vroot.h>
6961 ++#include <linux/vs_context.h>
6962 ++
6963 ++
6964 ++static int max_vroot = 8;
6965 ++
6966 ++static struct vroot_device *vroot_dev;
6967 ++static struct gendisk **disks;
6968 ++
6969 ++
6970 ++static int vroot_set_dev(
6971 ++ struct vroot_device *vr,
6972 ++ struct file *vr_file,
6973 ++ struct block_device *bdev,
6974 ++ unsigned int arg)
6975 ++{
6976 ++ struct block_device *real_bdev;
6977 ++ struct file *file;
6978 ++ struct inode *inode;
6979 ++ int error;
6980 ++
6981 ++ error = -EBUSY;
6982 ++ if (vr->vr_state != Vr_unbound)
6983 ++ goto out;
6984 ++
6985 ++ error = -EBADF;
6986 ++ file = fget(arg);
6987 ++ if (!file)
6988 ++ goto out;
6989 ++
6990 ++ error = -EINVAL;
6991 ++ inode = file->f_dentry->d_inode;
6992 ++
6993 ++
6994 ++ if (S_ISBLK(inode->i_mode)) {
6995 ++ real_bdev = inode->i_bdev;
6996 ++ vr->vr_device = real_bdev;
6997 ++ __iget(real_bdev->bd_inode);
6998 ++ } else
6999 ++ goto out_fput;
7000 ++
7001 ++ vxdprintk(VXD_CBIT(misc, 0),
7002 ++ "vroot[%d]_set_dev: dev=" VXF_DEV,
7003 ++ vr->vr_number, VXD_DEV(real_bdev));
7004 ++
7005 ++ vr->vr_state = Vr_bound;
7006 ++ error = 0;
7007 ++
7008 ++ out_fput:
7009 ++ fput(file);
7010 ++ out:
7011 ++ return error;
7012 ++}
7013 ++
7014 ++static int vroot_clr_dev(
7015 ++ struct vroot_device *vr,
7016 ++ struct file *vr_file,
7017 ++ struct block_device *bdev)
7018 ++{
7019 ++ struct block_device *real_bdev;
7020 ++
7021 ++ if (vr->vr_state != Vr_bound)
7022 ++ return -ENXIO;
7023 ++ if (vr->vr_refcnt > 1) /* we needed one fd for the ioctl */
7024 ++ return -EBUSY;
7025 ++
7026 ++ real_bdev = vr->vr_device;
7027 ++
7028 ++ vxdprintk(VXD_CBIT(misc, 0),
7029 ++ "vroot[%d]_clr_dev: dev=" VXF_DEV,
7030 ++ vr->vr_number, VXD_DEV(real_bdev));
7031 ++
7032 ++ bdput(real_bdev);
7033 ++ vr->vr_state = Vr_unbound;
7034 ++ vr->vr_device = NULL;
7035 ++ return 0;
7036 ++}
7037 ++
7038 ++
7039 ++static int vr_ioctl(struct inode *inode, struct file *file,
7040 ++ unsigned int cmd, unsigned long arg)
7041 ++{
7042 ++ struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
7043 ++ int err;
7044 ++
7045 ++ down(&vr->vr_ctl_mutex);
7046 ++ switch (cmd) {
7047 ++ case VROOT_SET_DEV:
7048 ++ err = vroot_set_dev(vr, file, inode->i_bdev, arg);
7049 ++ break;
7050 ++ case VROOT_CLR_DEV:
7051 ++ err = vroot_clr_dev(vr, file, inode->i_bdev);
7052 ++ break;
7053 ++ default:
7054 ++ err = -EINVAL;
7055 ++ break;
7056 ++ }
7057 ++ up(&vr->vr_ctl_mutex);
7058 ++ return err;
7059 ++}
7060 ++
7061 ++static int vr_open(struct inode *inode, struct file *file)
7062 ++{
7063 ++ struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
7064 ++
7065 ++ down(&vr->vr_ctl_mutex);
7066 ++ vr->vr_refcnt++;
7067 ++ up(&vr->vr_ctl_mutex);
7068 ++ return 0;
7069 ++}
7070 ++
7071 ++static int vr_release(struct inode *inode, struct file *file)
7072 ++{
7073 ++ struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
7074 ++
7075 ++ down(&vr->vr_ctl_mutex);
7076 ++ --vr->vr_refcnt;
7077 ++ up(&vr->vr_ctl_mutex);
7078 ++ return 0;
7079 ++}
7080 ++
7081 ++static struct block_device_operations vr_fops = {
7082 ++ .owner = THIS_MODULE,
7083 ++ .open = vr_open,
7084 ++ .release = vr_release,
7085 ++ .ioctl = vr_ioctl,
7086 ++};
7087 ++
7088 ++struct block_device *__vroot_get_real_bdev(struct block_device *bdev)
7089 ++{
7090 ++ struct inode *inode = bdev->bd_inode;
7091 ++ struct vroot_device *vr;
7092 ++ struct block_device *real_bdev;
7093 ++ int minor = iminor(inode);
7094 ++
7095 ++ vr = &vroot_dev[minor];
7096 ++ real_bdev = vr->vr_device;
7097 ++
7098 ++ vxdprintk(VXD_CBIT(misc, 0),
7099 ++ "vroot[%d]_get_real_bdev: dev=" VXF_DEV,
7100 ++ vr->vr_number, VXD_DEV(real_bdev));
7101 ++
7102 ++ if (vr->vr_state != Vr_bound)
7103 ++ return ERR_PTR(-ENXIO);
7104 ++
7105 ++ __iget(real_bdev->bd_inode);
7106 ++ return real_bdev;
7107 ++}
7108 ++
7109 ++/*
7110 ++ * And now the modules code and kernel interface.
7111 ++ */
7112 ++
7113 ++module_param(max_vroot, int, 0);
7114 ++
7115 ++MODULE_PARM_DESC(max_vroot, "Maximum number of vroot devices (1-256)");
7116 ++MODULE_LICENSE("GPL");
7117 ++MODULE_ALIAS_BLOCKDEV_MAJOR(VROOT_MAJOR);
7118 ++
7119 ++MODULE_AUTHOR ("Herbert Pötzl");
7120 ++MODULE_DESCRIPTION ("Virtual Root Device Mapper");
7121 ++
7122 ++
7123 ++int __init vroot_init(void)
7124 ++{
7125 ++ int err, i;
7126 ++
7127 ++ if (max_vroot < 1 || max_vroot > 256) {
7128 ++ max_vroot = MAX_VROOT_DEFAULT;
7129 ++ printk(KERN_WARNING "vroot: invalid max_vroot "
7130 ++ "(must be between 1 and 256), "
7131 ++ "using default (%d)\n", max_vroot);
7132 ++ }
7133 ++
7134 ++ if (register_blkdev(VROOT_MAJOR, "vroot"))
7135 ++ return -EIO;
7136 ++
7137 ++ err = -ENOMEM;
7138 ++ vroot_dev = kmalloc(max_vroot * sizeof(struct vroot_device), GFP_KERNEL);
7139 ++ if (!vroot_dev)
7140 ++ goto out_mem1;
7141 ++ memset(vroot_dev, 0, max_vroot * sizeof(struct vroot_device));
7142 ++
7143 ++ disks = kmalloc(max_vroot * sizeof(struct gendisk *), GFP_KERNEL);
7144 ++ if (!disks)
7145 ++ goto out_mem2;
7146 ++
7147 ++ for (i = 0; i < max_vroot; i++) {
7148 ++ disks[i] = alloc_disk(1);
7149 ++ if (!disks[i])
7150 ++ goto out_mem3;
7151 ++ }
7152 ++
7153 ++ for (i = 0; i < max_vroot; i++) {
7154 ++ struct vroot_device *vr = &vroot_dev[i];
7155 ++ struct gendisk *disk = disks[i];
7156 ++
7157 ++ memset(vr, 0, sizeof(*vr));
7158 ++ init_MUTEX(&vr->vr_ctl_mutex);
7159 ++ vr->vr_number = i;
7160 ++ disk->major = VROOT_MAJOR;
7161 ++ disk->first_minor = i;
7162 ++ disk->fops = &vr_fops;
7163 ++ sprintf(disk->disk_name, "vroot%d", i);
7164 ++ disk->private_data = vr;
7165 ++ }
7166 ++
7167 ++ err = register_vroot_grb(&__vroot_get_real_bdev);
7168 ++ if (err)
7169 ++ goto out_mem3;
7170 ++
7171 ++ for (i = 0; i < max_vroot; i++)
7172 ++ add_disk(disks[i]);
7173 ++ printk(KERN_INFO "vroot: loaded (max %d devices)\n", max_vroot);
7174 ++ return 0;
7175 ++
7176 ++out_mem3:
7177 ++ while (i--)
7178 ++ put_disk(disks[i]);
7179 ++ kfree(disks);
7180 ++out_mem2:
7181 ++ kfree(vroot_dev);
7182 ++out_mem1:
7183 ++ unregister_blkdev(VROOT_MAJOR, "vroot");
7184 ++ printk(KERN_ERR "vroot: ran out of memory\n");
7185 ++ return err;
7186 ++}
7187 ++
7188 ++void vroot_exit(void)
7189 ++{
7190 ++ int i;
7191 ++
7192 ++ if (unregister_vroot_grb(&__vroot_get_real_bdev))
7193 ++ printk(KERN_WARNING "vroot: cannot unregister grb\n");
7194 ++
7195 ++ for (i = 0; i < max_vroot; i++) {
7196 ++ del_gendisk(disks[i]);
7197 ++ put_disk(disks[i]);
7198 ++ }
7199 ++ if (unregister_blkdev(VROOT_MAJOR, "vroot"))
7200 ++ printk(KERN_WARNING "vroot: cannot unregister blkdev\n");
7201 ++
7202 ++ kfree(disks);
7203 ++ kfree(vroot_dev);
7204 ++}
7205 ++
7206 ++module_init(vroot_init);
7207 ++module_exit(vroot_exit);
7208 ++
7209 ++#ifndef MODULE
7210 ++
7211 ++static int __init max_vroot_setup(char *str)
7212 ++{
7213 ++ max_vroot = simple_strtol(str, NULL, 0);
7214 ++ return 1;
7215 ++}
7216 ++
7217 ++__setup("max_vroot=", max_vroot_setup);
7218 ++
7219 ++#endif
7220 ++
7221 +diff -NurpP --minimal linux-2.6.22.19/drivers/char/sysrq.c linux-2.6.22.19-vs2.3.0.34/drivers/char/sysrq.c
7222 +--- linux-2.6.22.19/drivers/char/sysrq.c 2007-07-09 13:18:20 +0200
7223 ++++ linux-2.6.22.19-vs2.3.0.34/drivers/char/sysrq.c 2007-08-05 20:53:12 +0200
7224 +@@ -36,6 +36,7 @@
7225 + #include <linux/kexec.h>
7226 + #include <linux/irq.h>
7227 + #include <linux/hrtimer.h>
7228 ++#include <linux/vserver/debug.h>
7229 +
7230 + #include <asm/ptrace.h>
7231 + #include <asm/irq_regs.h>
7232 +@@ -309,6 +310,21 @@ static struct sysrq_key_op sysrq_unrt_op
7233 + .enable_mask = SYSRQ_ENABLE_RTNICE,
7234 + };
7235 +
7236 ++
7237 ++#ifdef CONFIG_VSERVER_DEBUG
7238 ++static void sysrq_handle_vxinfo(int key, struct tty_struct *tty)
7239 ++{
7240 ++ dump_vx_info_inactive((key == 'x')?0:1);
7241 ++}
7242 ++
7243 ++static struct sysrq_key_op sysrq_showvxinfo_op = {
7244 ++ .handler = sysrq_handle_vxinfo,
7245 ++ .help_msg = "conteXt",
7246 ++ .action_msg = "Show Context Info",
7247 ++ .enable_mask = SYSRQ_ENABLE_DUMP,
7248 ++};
7249 ++#endif
7250 ++
7251 + /* Key Operations table and lock */
7252 + static DEFINE_SPINLOCK(sysrq_key_table_lock);
7253 +
7254 +@@ -357,7 +373,11 @@ static struct sysrq_key_op *sysrq_key_ta
7255 + /* x: May be registered on ppc/powerpc for xmon */
7256 + NULL, /* x */
7257 + NULL, /* y */
7258 +- NULL /* z */
7259 ++#ifdef CONFIG_VSERVER_DEBUG
7260 ++ &sysrq_showvxinfo_op, /* z */
7261 ++#else
7262 ++ NULL, /* z */
7263 ++#endif
7264 + };
7265 +
7266 + /* key2index calculation, -1 on invalid index */
7267 +@@ -369,6 +389,8 @@ static int sysrq_key_table_key2index(int
7268 + retval = key - '0';
7269 + else if ((key >= 'a') && (key <= 'z'))
7270 + retval = key + 10 - 'a';
7271 ++ else if ((key >= 'A') && (key <= 'Z'))
7272 ++ retval = key + 10 - 'A';
7273 + else
7274 + retval = -1;
7275 + return retval;
7276 +diff -NurpP --minimal linux-2.6.22.19/drivers/char/tty_io.c linux-2.6.22.19-vs2.3.0.34/drivers/char/tty_io.c
7277 +--- linux-2.6.22.19/drivers/char/tty_io.c 2007-07-09 13:18:20 +0200
7278 ++++ linux-2.6.22.19-vs2.3.0.34/drivers/char/tty_io.c 2007-08-05 20:53:12 +0200
7279 +@@ -103,6 +103,7 @@
7280 + #include <linux/selection.h>
7281 +
7282 + #include <linux/kmod.h>
7283 ++#include <linux/vs_pid.h>
7284 +
7285 + #undef TTY_DEBUG_HANGUP
7286 +
7287 +@@ -3049,13 +3050,15 @@ unlock:
7288 +
7289 + static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
7290 + {
7291 ++ pid_t pgrp;
7292 + /*
7293 + * (tty == real_tty) is a cheap way of
7294 + * testing if the tty is NOT a master pty.
7295 + */
7296 + if (tty == real_tty && current->signal->tty != real_tty)
7297 + return -ENOTTY;
7298 +- return put_user(pid_nr(real_tty->pgrp), p);
7299 ++ pgrp = vx_map_pid(pid_nr(real_tty->pgrp));
7300 ++ return put_user(pgrp, p);
7301 + }
7302 +
7303 + /**
7304 +@@ -3086,6 +3089,7 @@ static int tiocspgrp(struct tty_struct *
7305 + return -ENOTTY;
7306 + if (get_user(pgrp_nr, p))
7307 + return -EFAULT;
7308 ++ pgrp_nr = vx_rmap_pid(pgrp_nr);
7309 + if (pgrp_nr < 0)
7310 + return -EINVAL;
7311 + rcu_read_lock();
7312 +diff -NurpP --minimal linux-2.6.22.19/drivers/infiniband/hw/ipath/ipath_user_pages.c linux-2.6.22.19-vs2.3.0.34/drivers/infiniband/hw/ipath/ipath_user_pages.c
7313 +--- linux-2.6.22.19/drivers/infiniband/hw/ipath/ipath_user_pages.c 2007-02-06 03:00:37 +0100
7314 ++++ linux-2.6.22.19-vs2.3.0.34/drivers/infiniband/hw/ipath/ipath_user_pages.c 2007-08-05 20:53:12 +0200
7315 +@@ -33,6 +33,7 @@
7316 +
7317 + #include <linux/mm.h>
7318 + #include <linux/device.h>
7319 ++#include <linux/vs_memory.h>
7320 +
7321 + #include "ipath_kernel.h"
7322 +
7323 +@@ -61,7 +62,8 @@ static int __get_user_pages(unsigned lon
7324 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >>
7325 + PAGE_SHIFT;
7326 +
7327 +- if (num_pages > lock_limit) {
7328 ++ if (num_pages > lock_limit ||
7329 ++ !vx_vmlocked_avail(current->mm, num_pages)) {
7330 + ret = -ENOMEM;
7331 + goto bail;
7332 + }
7333 +@@ -78,7 +80,7 @@ static int __get_user_pages(unsigned lon
7334 + goto bail_release;
7335 + }
7336 +
7337 +- current->mm->locked_vm += num_pages;
7338 ++ vx_vmlocked_add(current->mm, num_pages);
7339 +
7340 + ret = 0;
7341 + goto bail;
7342 +@@ -203,7 +205,7 @@ void ipath_release_user_pages(struct pag
7343 +
7344 + __ipath_release_user_pages(p, num_pages, 1);
7345 +
7346 +- current->mm->locked_vm -= num_pages;
7347 ++ vx_vmlocked_sub(current->mm, num_pages);
7348 +
7349 + up_write(&current->mm->mmap_sem);
7350 + }
7351 +@@ -220,7 +222,7 @@ static void user_pages_account(struct wo
7352 + container_of(_work, struct ipath_user_pages_work, work);
7353 +
7354 + down_write(&work->mm->mmap_sem);
7355 +- work->mm->locked_vm -= work->num_pages;
7356 ++ vx_vmlocked_sub(work->mm, work->num_pages);
7357 + up_write(&work->mm->mmap_sem);
7358 + mmput(work->mm);
7359 + kfree(work);
7360 +diff -NurpP --minimal linux-2.6.22.19/drivers/md/dm-ioctl.c linux-2.6.22.19-vs2.3.0.34/drivers/md/dm-ioctl.c
7361 +--- linux-2.6.22.19/drivers/md/dm-ioctl.c 2007-05-02 19:24:50 +0200
7362 ++++ linux-2.6.22.19-vs2.3.0.34/drivers/md/dm-ioctl.c 2007-08-05 20:53:12 +0200
7363 +@@ -15,6 +15,7 @@
7364 + #include <linux/slab.h>
7365 + #include <linux/dm-ioctl.h>
7366 + #include <linux/hdreg.h>
7367 ++#include <linux/vs_context.h>
7368 +
7369 + #include <asm/uaccess.h>
7370 +
7371 +@@ -100,7 +101,8 @@ static struct hash_cell *__get_name_cell
7372 + unsigned int h = hash_str(str);
7373 +
7374 + list_for_each_entry (hc, _name_buckets + h, name_list)
7375 +- if (!strcmp(hc->name, str)) {
7376 ++ if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) &&
7377 ++ !strcmp(hc->name, str)) {
7378 + dm_get(hc->md);
7379 + return hc;
7380 + }
7381 +@@ -114,7 +116,8 @@ static struct hash_cell *__get_uuid_cell
7382 + unsigned int h = hash_str(str);
7383 +
7384 + list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
7385 +- if (!strcmp(hc->uuid, str)) {
7386 ++ if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) &&
7387 ++ !strcmp(hc->uuid, str)) {
7388 + dm_get(hc->md);
7389 + return hc;
7390 + }
7391 +@@ -349,6 +352,9 @@ typedef int (*ioctl_fn)(struct dm_ioctl
7392 +
7393 + static int remove_all(struct dm_ioctl *param, size_t param_size)
7394 + {
7395 ++ if (!vx_check(0, VS_ADMIN))
7396 ++ return -EPERM;
7397 ++
7398 + dm_hash_remove_all(1);
7399 + param->data_size = 0;
7400 + return 0;
7401 +@@ -396,6 +402,8 @@ static int list_devices(struct dm_ioctl
7402 + */
7403 + for (i = 0; i < NUM_BUCKETS; i++) {
7404 + list_for_each_entry (hc, _name_buckets + i, name_list) {
7405 ++ if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT))
7406 ++ continue;
7407 + needed += sizeof(struct dm_name_list);
7408 + needed += strlen(hc->name) + 1;
7409 + needed += ALIGN_MASK;
7410 +@@ -419,6 +427,8 @@ static int list_devices(struct dm_ioctl
7411 + */
7412 + for (i = 0; i < NUM_BUCKETS; i++) {
7413 + list_for_each_entry (hc, _name_buckets + i, name_list) {
7414 ++ if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT))
7415 ++ continue;
7416 + if (old_nl)
7417 + old_nl->next = (uint32_t) ((void *) nl -
7418 + (void *) old_nl);
7419 +@@ -609,10 +619,11 @@ static struct hash_cell *__find_device_h
7420 + if (!md)
7421 + goto out;
7422 +
7423 +- mdptr = dm_get_mdptr(md);
7424 ++ if (vx_check(dm_get_xid(md), VS_WATCH_P | VS_IDENT))
7425 ++ mdptr = dm_get_mdptr(md);
7426 ++
7427 + if (!mdptr)
7428 + dm_put(md);
7429 +-
7430 + out:
7431 + return mdptr;
7432 + }
7433 +@@ -1409,8 +1420,8 @@ static int ctl_ioctl(struct inode *inode
7434 + ioctl_fn fn = NULL;
7435 + size_t param_size;
7436 +
7437 +- /* only root can play with this */
7438 +- if (!capable(CAP_SYS_ADMIN))
7439 ++ /* only root and certain contexts can play with this */
7440 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_MAPPER))
7441 + return -EACCES;
7442 +
7443 + if (_IOC_TYPE(command) != DM_IOCTL)
7444 +diff -NurpP --minimal linux-2.6.22.19/drivers/md/dm.c linux-2.6.22.19-vs2.3.0.34/drivers/md/dm.c
7445 +--- linux-2.6.22.19/drivers/md/dm.c 2008-03-14 20:19:00 +0100
7446 ++++ linux-2.6.22.19-vs2.3.0.34/drivers/md/dm.c 2007-08-11 22:41:50 +0200
7447 +@@ -21,6 +21,7 @@
7448 + #include <linux/hdreg.h>
7449 + #include <linux/blktrace_api.h>
7450 + #include <linux/smp_lock.h>
7451 ++#include <linux/vs_base.h>
7452 +
7453 + #define DM_MSG_PREFIX "core"
7454 +
7455 +@@ -77,6 +78,7 @@ struct mapped_device {
7456 + rwlock_t map_lock;
7457 + atomic_t holders;
7458 + atomic_t open_count;
7459 ++ xid_t xid;
7460 +
7461 + unsigned long flags;
7462 +
7463 +@@ -223,6 +225,7 @@ static void __exit dm_exit(void)
7464 + static int dm_blk_open(struct inode *inode, struct file *file)
7465 + {
7466 + struct mapped_device *md;
7467 ++ int ret = -ENXIO;
7468 +
7469 + spin_lock(&_minor_lock);
7470 +
7471 +@@ -231,18 +234,19 @@ static int dm_blk_open(struct inode *ino
7472 + goto out;
7473 +
7474 + if (test_bit(DMF_FREEING, &md->flags) ||
7475 +- test_bit(DMF_DELETING, &md->flags)) {
7476 +- md = NULL;
7477 ++ test_bit(DMF_DELETING, &md->flags))
7478 ++ goto out;
7479 ++
7480 ++ ret = -EACCES;
7481 ++ if (!vx_check(md->xid, VS_IDENT|VS_HOSTID))
7482 + goto out;
7483 +- }
7484 +
7485 + dm_get(md);
7486 + atomic_inc(&md->open_count);
7487 +-
7488 ++ ret = 0;
7489 + out:
7490 + spin_unlock(&_minor_lock);
7491 +-
7492 +- return md ? 0 : -ENXIO;
7493 ++ return ret;
7494 + }
7495 +
7496 + static int dm_blk_close(struct inode *inode, struct file *file)
7497 +@@ -438,6 +442,14 @@ int dm_set_geometry(struct mapped_device
7498 + return 0;
7499 + }
7500 +
7501 ++/*
7502 ++ * Get the xid associated with a dm device
7503 ++ */
7504 ++xid_t dm_get_xid(struct mapped_device *md)
7505 ++{
7506 ++ return md->xid;
7507 ++}
7508 ++
7509 + /*-----------------------------------------------------------------
7510 + * CRUD START:
7511 + * A more elegant soln is in the works that uses the queue
7512 +@@ -1000,6 +1012,7 @@ static struct mapped_device *alloc_dev(i
7513 + atomic_set(&md->holders, 1);
7514 + atomic_set(&md->open_count, 0);
7515 + atomic_set(&md->event_nr, 0);
7516 ++ md->xid = vx_current_xid();
7517 +
7518 + md->queue = blk_alloc_queue(GFP_KERNEL);
7519 + if (!md->queue)
7520 +diff -NurpP --minimal linux-2.6.22.19/drivers/md/dm.h linux-2.6.22.19-vs2.3.0.34/drivers/md/dm.h
7521 +--- linux-2.6.22.19/drivers/md/dm.h 2007-02-06 03:00:41 +0100
7522 ++++ linux-2.6.22.19-vs2.3.0.34/drivers/md/dm.h 2007-08-05 20:53:12 +0200
7523 +@@ -91,6 +91,8 @@ void dm_put_target_type(struct target_ty
7524 + int dm_target_iterate(void (*iter_func)(struct target_type *tt,
7525 + void *param), void *param);
7526 +
7527 ++xid_t dm_get_xid(struct mapped_device *md);
7528 ++
7529 + /*-----------------------------------------------------------------
7530 + * Useful inlines.
7531 + *---------------------------------------------------------------*/
7532 +diff -NurpP --minimal linux-2.6.22.19/drivers/net/tun.c linux-2.6.22.19-vs2.3.0.34/drivers/net/tun.c
7533 +--- linux-2.6.22.19/drivers/net/tun.c 2007-07-09 13:19:05 +0200
7534 ++++ linux-2.6.22.19-vs2.3.0.34/drivers/net/tun.c 2008-03-17 00:08:25 +0100
7535 +@@ -62,6 +62,7 @@
7536 + #include <linux/if_ether.h>
7537 + #include <linux/if_tun.h>
7538 + #include <linux/crc32.h>
7539 ++#include <linux/vs_network.h>
7540 +
7541 + #include <asm/system.h>
7542 + #include <asm/uaccess.h>
7543 +@@ -432,6 +433,7 @@ static void tun_setup(struct net_device
7544 + init_waitqueue_head(&tun->read_wait);
7545 +
7546 + tun->owner = -1;
7547 ++ tun->nid = current->nid;
7548 +
7549 + SET_MODULE_OWNER(dev);
7550 + dev->open = tun_net_open;
7551 +@@ -463,12 +465,16 @@ static int tun_set_iff(struct file *file
7552 +
7553 + tun = tun_get_by_name(ifr->ifr_name);
7554 + if (tun) {
7555 ++ if (!nx_check(tun->nid, VS_IDENT | VS_HOSTID | VS_ADMIN_P))
7556 ++ return -EPERM;
7557 ++
7558 + if (tun->attached)
7559 + return -EBUSY;
7560 +
7561 + /* Check permissions */
7562 + if (tun->owner != -1 &&
7563 +- current->euid != tun->owner && !capable(CAP_NET_ADMIN))
7564 ++ current->euid != tun->owner &&
7565 ++ !cap_raised(current->cap_effective, CAP_NET_ADMIN))
7566 + return -EPERM;
7567 + }
7568 + else if (__dev_get_by_name(ifr->ifr_name))
7569 +@@ -479,7 +485,7 @@ static int tun_set_iff(struct file *file
7570 +
7571 + err = -EINVAL;
7572 +
7573 +- if (!capable(CAP_NET_ADMIN))
7574 ++ if (!nx_capable(CAP_NET_ADMIN, NXC_TUN_CREATE))
7575 + return -EPERM;
7576 +
7577 + /* Set dev type */
7578 +@@ -610,6 +616,16 @@ static int tun_chr_ioctl(struct inode *i
7579 + DBG(KERN_INFO "%s: owner set to %d\n", tun->dev->name, tun->owner);
7580 + break;
7581 +
7582 ++ case TUNSETNID:
7583 ++ if (!capable(CAP_CONTEXT))
7584 ++ return -EPERM;
7585 ++
7586 ++ /* Set nid owner of the device */
7587 ++ tun->nid = (nid_t) arg;
7588 ++
7589 ++ DBG(KERN_INFO "%s: nid owner set to %u\n", tun->dev->name, tun->nid);
7590 ++ break;
7591 ++
7592 + case TUNSETLINK:
7593 + /* Only allow setting the type when the interface is down */
7594 + if (tun->dev->flags & IFF_UP) {
7595 +diff -NurpP --minimal linux-2.6.22.19/fs/Kconfig linux-2.6.22.19-vs2.3.0.34/fs/Kconfig
7596 +--- linux-2.6.22.19/fs/Kconfig 2007-07-09 13:19:22 +0200
7597 ++++ linux-2.6.22.19-vs2.3.0.34/fs/Kconfig 2008-01-18 14:44:53 +0100
7598 +@@ -2026,7 +2026,7 @@ config CODA_FS_OLD_API
7599 +
7600 + config AFS_FS
7601 + tristate "Andrew File System support (AFS) (EXPERIMENTAL)"
7602 +- depends on INET && EXPERIMENTAL
7603 ++ depends on INET && EXPERIMENTAL && !VSERVER_SECURITY
7604 + select AF_RXRPC
7605 + help
7606 + If you say Y here, you will get an experimental Andrew File System
7607 +diff -NurpP --minimal linux-2.6.22.19/fs/attr.c linux-2.6.22.19-vs2.3.0.34/fs/attr.c
7608 +--- linux-2.6.22.19/fs/attr.c 2007-07-09 13:19:22 +0200
7609 ++++ linux-2.6.22.19-vs2.3.0.34/fs/attr.c 2007-10-25 17:05:55 +0200
7610 +@@ -14,6 +14,9 @@
7611 + #include <linux/fcntl.h>
7612 + #include <linux/quotaops.h>
7613 + #include <linux/security.h>
7614 ++#include <linux/proc_fs.h>
7615 ++#include <linux/devpts_fs.h>
7616 ++#include <linux/vs_base.h>
7617 +
7618 + /* Taken over from the old code... */
7619 +
7620 +@@ -55,6 +58,27 @@ int inode_change_ok(struct inode *inode,
7621 + if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER))
7622 + goto error;
7623 + }
7624 ++
7625 ++ /* Check for evil vserver activity */
7626 ++ if (vx_check(0, VS_ADMIN))
7627 ++ goto fine;
7628 ++
7629 ++ if (IS_BARRIER(inode)) {
7630 ++ vxwprintk_task(1, "messing with the barrier.");
7631 ++ goto error;
7632 ++ }
7633 ++ switch (inode->i_sb->s_magic) {
7634 ++ case PROC_SUPER_MAGIC:
7635 ++ /* maybe allow that in the future? */
7636 ++ vxwprintk_task(1, "messing with the procfs.");
7637 ++ goto error;
7638 ++ case DEVPTS_SUPER_MAGIC:
7639 ++ /* devpts is xid tagged */
7640 ++ if (vx_check((xid_t)inode->i_tag, VS_IDENT))
7641 ++ goto fine;
7642 ++ vxwprintk_task(1, "messing with the devpts.");
7643 ++ goto error;
7644 ++ }
7645 + fine:
7646 + retval = 0;
7647 + error:
7648 +@@ -78,6 +102,8 @@ int inode_setattr(struct inode * inode,
7649 + inode->i_uid = attr->ia_uid;
7650 + if (ia_valid & ATTR_GID)
7651 + inode->i_gid = attr->ia_gid;
7652 ++ if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode))
7653 ++ inode->i_tag = attr->ia_tag;
7654 + if (ia_valid & ATTR_ATIME)
7655 + inode->i_atime = timespec_trunc(attr->ia_atime,
7656 + inode->i_sb->s_time_gran);
7657 +@@ -152,7 +178,8 @@ int notify_change(struct dentry * dentry
7658 + error = security_inode_setattr(dentry, attr);
7659 + if (!error) {
7660 + if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
7661 +- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
7662 ++ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
7663 ++ (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag))
7664 + error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
7665 + if (!error)
7666 + error = inode_setattr(inode, attr);
7667 +diff -NurpP --minimal linux-2.6.22.19/fs/binfmt_aout.c linux-2.6.22.19-vs2.3.0.34/fs/binfmt_aout.c
7668 +--- linux-2.6.22.19/fs/binfmt_aout.c 2007-02-06 03:01:16 +0100
7669 ++++ linux-2.6.22.19-vs2.3.0.34/fs/binfmt_aout.c 2007-08-05 20:53:12 +0200
7670 +@@ -24,6 +24,7 @@
7671 + #include <linux/binfmts.h>
7672 + #include <linux/personality.h>
7673 + #include <linux/init.h>
7674 ++#include <linux/vs_memory.h>
7675 +
7676 + #include <asm/system.h>
7677 + #include <asm/uaccess.h>
7678 +diff -NurpP --minimal linux-2.6.22.19/fs/binfmt_elf.c linux-2.6.22.19-vs2.3.0.34/fs/binfmt_elf.c
7679 +--- linux-2.6.22.19/fs/binfmt_elf.c 2007-07-09 13:19:22 +0200
7680 ++++ linux-2.6.22.19-vs2.3.0.34/fs/binfmt_elf.c 2007-08-05 20:53:12 +0200
7681 +@@ -39,6 +39,7 @@
7682 + #include <linux/random.h>
7683 + #include <linux/elf.h>
7684 + #include <linux/utsname.h>
7685 ++#include <linux/vs_memory.h>
7686 + #include <asm/uaccess.h>
7687 + #include <asm/param.h>
7688 + #include <asm/page.h>
7689 +diff -NurpP --minimal linux-2.6.22.19/fs/binfmt_flat.c linux-2.6.22.19-vs2.3.0.34/fs/binfmt_flat.c
7690 +--- linux-2.6.22.19/fs/binfmt_flat.c 2007-07-09 13:19:22 +0200
7691 ++++ linux-2.6.22.19-vs2.3.0.34/fs/binfmt_flat.c 2007-08-05 20:53:12 +0200
7692 +@@ -36,6 +36,7 @@
7693 + #include <linux/init.h>
7694 + #include <linux/flat.h>
7695 + #include <linux/syscalls.h>
7696 ++#include <linux/vs_memory.h>
7697 +
7698 + #include <asm/byteorder.h>
7699 + #include <asm/system.h>
7700 +diff -NurpP --minimal linux-2.6.22.19/fs/binfmt_som.c linux-2.6.22.19-vs2.3.0.34/fs/binfmt_som.c
7701 +--- linux-2.6.22.19/fs/binfmt_som.c 2006-11-30 21:19:19 +0100
7702 ++++ linux-2.6.22.19-vs2.3.0.34/fs/binfmt_som.c 2007-08-05 20:53:12 +0200
7703 +@@ -28,6 +28,7 @@
7704 + #include <linux/shm.h>
7705 + #include <linux/personality.h>
7706 + #include <linux/init.h>
7707 ++#include <linux/vs_memory.h>
7708 +
7709 + #include <asm/a.out.h>
7710 + #include <asm/uaccess.h>
7711 +diff -NurpP --minimal linux-2.6.22.19/fs/block_dev.c linux-2.6.22.19-vs2.3.0.34/fs/block_dev.c
7712 +--- linux-2.6.22.19/fs/block_dev.c 2007-07-09 13:19:22 +0200
7713 ++++ linux-2.6.22.19-vs2.3.0.34/fs/block_dev.c 2007-10-11 01:10:22 +0200
7714 +@@ -23,6 +23,7 @@
7715 + #include <linux/uio.h>
7716 + #include <linux/namei.h>
7717 + #include <linux/log2.h>
7718 ++#include <linux/vs_device.h>
7719 + #include <asm/uaccess.h>
7720 + #include "internal.h"
7721 +
7722 +@@ -572,6 +573,7 @@ struct block_device *bdget(dev_t dev)
7723 + bdev->bd_invalidated = 0;
7724 + inode->i_mode = S_IFBLK;
7725 + inode->i_rdev = dev;
7726 ++ inode->i_mdev = dev;
7727 + inode->i_bdev = bdev;
7728 + inode->i_data.a_ops = &def_blk_aops;
7729 + mapping_set_gfp_mask(&inode->i_data, GFP_USER);
7730 +@@ -610,6 +612,11 @@ EXPORT_SYMBOL(bdput);
7731 + static struct block_device *bd_acquire(struct inode *inode)
7732 + {
7733 + struct block_device *bdev;
7734 ++ dev_t mdev;
7735 ++
7736 ++ if (!vs_map_blkdev(inode->i_rdev, &mdev, DATTR_OPEN))
7737 ++ return NULL;
7738 ++ inode->i_mdev = mdev;
7739 +
7740 + spin_lock(&bdev_lock);
7741 + bdev = inode->i_bdev;
7742 +@@ -620,7 +627,7 @@ static struct block_device *bd_acquire(s
7743 + }
7744 + spin_unlock(&bdev_lock);
7745 +
7746 +- bdev = bdget(inode->i_rdev);
7747 ++ bdev = bdget(mdev);
7748 + if (bdev) {
7749 + spin_lock(&bdev_lock);
7750 + if (!inode->i_bdev) {
7751 +diff -NurpP --minimal linux-2.6.22.19/fs/char_dev.c linux-2.6.22.19-vs2.3.0.34/fs/char_dev.c
7752 +--- linux-2.6.22.19/fs/char_dev.c 2007-05-02 19:25:16 +0200
7753 ++++ linux-2.6.22.19-vs2.3.0.34/fs/char_dev.c 2007-10-11 01:10:22 +0200
7754 +@@ -21,6 +21,7 @@
7755 + #include <linux/cdev.h>
7756 + #include <linux/mutex.h>
7757 + #include <linux/backing-dev.h>
7758 ++#include <linux/vs_device.h>
7759 +
7760 + #ifdef CONFIG_KMOD
7761 + #include <linux/kmod.h>
7762 +@@ -363,14 +364,21 @@ int chrdev_open(struct inode * inode, st
7763 + struct cdev *p;
7764 + struct cdev *new = NULL;
7765 + int ret = 0;
7766 ++ dev_t mdev;
7767 ++
7768 ++ if (!vs_map_chrdev(inode->i_rdev, &mdev, DATTR_OPEN))
7769 ++ return -EPERM;
7770 ++ inode->i_mdev = mdev;
7771 +
7772 + spin_lock(&cdev_lock);
7773 + p = inode->i_cdev;
7774 + if (!p) {
7775 + struct kobject *kobj;
7776 + int idx;
7777 ++
7778 + spin_unlock(&cdev_lock);
7779 +- kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
7780 ++
7781 ++ kobj = kobj_lookup(cdev_map, mdev, &idx);
7782 + if (!kobj)
7783 + return -ENXIO;
7784 + new = container_of(kobj, struct cdev, kobj);
7785 +diff -NurpP --minimal linux-2.6.22.19/fs/dcache.c linux-2.6.22.19-vs2.3.0.34/fs/dcache.c
7786 +--- linux-2.6.22.19/fs/dcache.c 2007-07-09 13:19:23 +0200
7787 ++++ linux-2.6.22.19-vs2.3.0.34/fs/dcache.c 2007-08-05 20:53:12 +0200
7788 +@@ -31,6 +31,7 @@
7789 + #include <linux/seqlock.h>
7790 + #include <linux/swap.h>
7791 + #include <linux/bootmem.h>
7792 ++#include <linux/vs_limit.h>
7793 + #include "internal.h"
7794 +
7795 +
7796 +@@ -176,6 +177,7 @@ void dput(struct dentry *dentry)
7797 + if (!dentry)
7798 + return;
7799 +
7800 ++ vx_dentry_dec(dentry);
7801 + repeat:
7802 + if (atomic_read(&dentry->d_count) == 1)
7803 + might_sleep();
7804 +@@ -189,6 +191,8 @@ repeat:
7805 + return;
7806 + }
7807 +
7808 ++ vx_dentry_dec(dentry);
7809 ++
7810 + /*
7811 + * AV: ->d_delete() is _NOT_ allowed to block now.
7812 + */
7813 +@@ -288,6 +292,7 @@ static inline struct dentry * __dget_loc
7814 + if (!list_empty(&dentry->d_lru)) {
7815 + dentry_stat.nr_unused--;
7816 + list_del_init(&dentry->d_lru);
7817 ++ vx_dentry_inc(dentry);
7818 + }
7819 + return dentry;
7820 + }
7821 +@@ -898,6 +903,9 @@ struct dentry *d_alloc(struct dentry * p
7822 + struct dentry *dentry;
7823 + char *dname;
7824 +
7825 ++ if (!vx_dentry_avail(1))
7826 ++ return NULL;
7827 ++
7828 + dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
7829 + if (!dentry)
7830 + return NULL;
7831 +@@ -946,6 +954,7 @@ struct dentry *d_alloc(struct dentry * p
7832 + if (parent)
7833 + list_add(&dentry->d_u.d_child, &parent->d_subdirs);
7834 + dentry_stat.nr_dentry++;
7835 ++ vx_dentry_inc(dentry);
7836 + spin_unlock(&dcache_lock);
7837 +
7838 + return dentry;
7839 +@@ -1295,6 +1304,7 @@ struct dentry * __d_lookup(struct dentry
7840 +
7841 + if (!d_unhashed(dentry)) {
7842 + atomic_inc(&dentry->d_count);
7843 ++ vx_dentry_inc(dentry);
7844 + found = dentry;
7845 + }
7846 + spin_unlock(&dentry->d_lock);
7847 +diff -NurpP --minimal linux-2.6.22.19/fs/devpts/inode.c linux-2.6.22.19-vs2.3.0.34/fs/devpts/inode.c
7848 +--- linux-2.6.22.19/fs/devpts/inode.c 2007-07-09 13:19:23 +0200
7849 ++++ linux-2.6.22.19-vs2.3.0.34/fs/devpts/inode.c 2007-10-18 00:59:53 +0200
7850 +@@ -17,11 +17,26 @@
7851 + #include <linux/namei.h>
7852 + #include <linux/mount.h>
7853 + #include <linux/tty.h>
7854 ++#include <linux/magic.h>
7855 + #include <linux/devpts_fs.h>
7856 + #include <linux/parser.h>
7857 + #include <linux/fsnotify.h>
7858 ++#include <linux/vs_base.h>
7859 +
7860 +-#define DEVPTS_SUPER_MAGIC 0x1cd1
7861 ++
7862 ++static int devpts_permission(struct inode *inode, int mask, struct nameidata *nd)
7863 ++{
7864 ++ int ret = -EACCES;
7865 ++
7866 ++ /* devpts is xid tagged */
7867 ++ if (vx_check((xid_t)inode->i_tag, VS_WATCH_P | VS_IDENT))
7868 ++ ret = generic_permission(inode, mask, NULL);
7869 ++ return ret;
7870 ++}
7871 ++
7872 ++static struct inode_operations devpts_file_inode_operations = {
7873 ++ .permission = devpts_permission,
7874 ++};
7875 +
7876 + static struct vfsmount *devpts_mnt;
7877 + static struct dentry *devpts_root;
7878 +@@ -92,6 +107,25 @@ static int devpts_remount(struct super_b
7879 + return 0;
7880 + }
7881 +
7882 ++static int devpts_filter(struct dentry *de)
7883 ++{
7884 ++ /* devpts is xid tagged */
7885 ++ return vx_check((xid_t)de->d_inode->i_tag, VS_WATCH_P | VS_IDENT);
7886 ++}
7887 ++
7888 ++static int devpts_readdir(struct file * filp, void * dirent, filldir_t filldir)
7889 ++{
7890 ++ return dcache_readdir_filter(filp, dirent, filldir, devpts_filter);
7891 ++}
7892 ++
7893 ++static struct file_operations devpts_dir_operations = {
7894 ++ .open = dcache_dir_open,
7895 ++ .release = dcache_dir_close,
7896 ++ .llseek = dcache_dir_lseek,
7897 ++ .read = generic_read_dir,
7898 ++ .readdir = devpts_readdir,
7899 ++};
7900 ++
7901 + static const struct super_operations devpts_sops = {
7902 + .statfs = simple_statfs,
7903 + .remount_fs = devpts_remount,
7904 +@@ -117,8 +151,10 @@ devpts_fill_super(struct super_block *s,
7905 + inode->i_uid = inode->i_gid = 0;
7906 + inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
7907 + inode->i_op = &simple_dir_inode_operations;
7908 +- inode->i_fop = &simple_dir_operations;
7909 ++ inode->i_fop = &devpts_dir_operations;
7910 + inode->i_nlink = 2;
7911 ++ /* devpts is xid tagged */
7912 ++ inode->i_tag = (tag_t)vx_current_xid();
7913 +
7914 + devpts_root = s->s_root = d_alloc_root(inode);
7915 + if (s->s_root)
7916 +@@ -176,6 +212,9 @@ int devpts_pty_new(struct tty_struct *tt
7917 + inode->i_gid = config.setgid ? config.gid : current->fsgid;
7918 + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
7919 + init_special_inode(inode, S_IFCHR|config.mode, device);
7920 ++ /* devpts is xid tagged */
7921 ++ inode->i_tag = (tag_t)vx_current_xid();
7922 ++ inode->i_op = &devpts_file_inode_operations;
7923 + inode->i_private = tty;
7924 +
7925 + dentry = get_node(number);
7926 +diff -NurpP --minimal linux-2.6.22.19/fs/ecryptfs/inode.c linux-2.6.22.19-vs2.3.0.34/fs/ecryptfs/inode.c
7927 +--- linux-2.6.22.19/fs/ecryptfs/inode.c 2008-03-14 20:19:03 +0100
7928 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ecryptfs/inode.c 2007-08-11 22:41:51 +0200
7929 +@@ -423,7 +423,7 @@ static int ecryptfs_link(struct dentry *
7930 + dget(lower_new_dentry);
7931 + lower_dir_dentry = lock_parent(lower_new_dentry);
7932 + rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
7933 +- lower_new_dentry);
7934 ++ lower_new_dentry, NULL);
7935 + if (rc || !lower_new_dentry->d_inode)
7936 + goto out_lock;
7937 + rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
7938 +@@ -451,7 +451,7 @@ static int ecryptfs_unlink(struct inode
7939 + struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
7940 +
7941 + lock_parent(lower_dentry);
7942 +- rc = vfs_unlink(lower_dir_inode, lower_dentry);
7943 ++ rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL);
7944 + if (rc) {
7945 + printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
7946 + goto out_unlock;
7947 +@@ -488,7 +488,7 @@ static int ecryptfs_symlink(struct inode
7948 + goto out_lock;
7949 + }
7950 + rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry,
7951 +- encoded_symname, mode);
7952 ++ encoded_symname, mode, NULL);
7953 + kfree(encoded_symname);
7954 + if (rc || !lower_dentry->d_inode)
7955 + goto out_lock;
7956 +@@ -513,7 +513,7 @@ static int ecryptfs_mkdir(struct inode *
7957 +
7958 + lower_dentry = ecryptfs_dentry_to_lower(dentry);
7959 + lower_dir_dentry = lock_parent(lower_dentry);
7960 +- rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode);
7961 ++ rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode, NULL);
7962 + if (rc || !lower_dentry->d_inode)
7963 + goto out;
7964 + rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
7965 +@@ -539,7 +539,7 @@ static int ecryptfs_rmdir(struct inode *
7966 + dget(dentry);
7967 + lower_dir_dentry = lock_parent(lower_dentry);
7968 + dget(lower_dentry);
7969 +- rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
7970 ++ rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry, NULL);
7971 + dput(lower_dentry);
7972 + if (!rc)
7973 + d_delete(lower_dentry);
7974 +@@ -561,7 +561,7 @@ ecryptfs_mknod(struct inode *dir, struct
7975 +
7976 + lower_dentry = ecryptfs_dentry_to_lower(dentry);
7977 + lower_dir_dentry = lock_parent(lower_dentry);
7978 +- rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev);
7979 ++ rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev, NULL);
7980 + if (rc || !lower_dentry->d_inode)
7981 + goto out;
7982 + rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
7983 +diff -NurpP --minimal linux-2.6.22.19/fs/exec.c linux-2.6.22.19-vs2.3.0.34/fs/exec.c
7984 +--- linux-2.6.22.19/fs/exec.c 2008-03-14 20:19:03 +0100
7985 ++++ linux-2.6.22.19-vs2.3.0.34/fs/exec.c 2008-03-14 21:11:30 +0100
7986 +@@ -51,6 +51,7 @@
7987 + #include <linux/cn_proc.h>
7988 + #include <linux/audit.h>
7989 + #include <linux/signalfd.h>
7990 ++#include <linux/vs_memory.h>
7991 +
7992 + #include <asm/uaccess.h>
7993 + #include <asm/mmu_context.h>
7994 +@@ -440,7 +441,8 @@ int setup_arg_pages(struct linux_binprm
7995 + kmem_cache_free(vm_area_cachep, mpnt);
7996 + return ret;
7997 + }
7998 +- mm->stack_vm = mm->total_vm = vma_pages(mpnt);
7999 ++ vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
8000 ++ mm->stack_vm = mm->total_vm;
8001 + }
8002 +
8003 + for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
8004 +@@ -1336,7 +1338,7 @@ static int format_corename(char *corenam
8005 + /* UNIX time of coredump */
8006 + case 't': {
8007 + struct timeval tv;
8008 +- do_gettimeofday(&tv);
8009 ++ vx_gettimeofday(&tv);
8010 + rc = snprintf(out_ptr, out_end - out_ptr,
8011 + "%lu", tv.tv_sec);
8012 + if (rc > out_end - out_ptr)
8013 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/balloc.c linux-2.6.22.19-vs2.3.0.34/fs/ext2/balloc.c
8014 +--- linux-2.6.22.19/fs/ext2/balloc.c 2007-05-02 19:25:17 +0200
8015 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext2/balloc.c 2007-08-05 20:53:12 +0200
8016 +@@ -16,6 +16,8 @@
8017 + #include <linux/sched.h>
8018 + #include <linux/buffer_head.h>
8019 + #include <linux/capability.h>
8020 ++#include <linux/vs_dlimit.h>
8021 ++#include <linux/vs_tag.h>
8022 +
8023 + /*
8024 + * balloc.c contains the blocks allocation and deallocation routines
8025 +@@ -102,12 +104,13 @@ static int reserve_blocks(struct super_b
8026 + {
8027 + struct ext2_sb_info *sbi = EXT2_SB(sb);
8028 + struct ext2_super_block *es = sbi->s_es;
8029 +- unsigned free_blocks;
8030 +- unsigned root_blocks;
8031 ++ unsigned long long free_blocks, root_blocks;
8032 +
8033 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
8034 + root_blocks = le32_to_cpu(es->s_r_blocks_count);
8035 +
8036 ++ DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
8037 ++
8038 + if (free_blocks < count)
8039 + count = free_blocks;
8040 +
8041 +@@ -258,6 +261,7 @@ do_more:
8042 + }
8043 + error_return:
8044 + brelse(bitmap_bh);
8045 ++ DLIMIT_FREE_BLOCK(inode, freed);
8046 + release_blocks(sb, freed);
8047 + DQUOT_FREE_BLOCK(inode, freed);
8048 + }
8049 +@@ -361,6 +365,10 @@ int ext2_new_block(struct inode *inode,
8050 + *err = -ENOSPC;
8051 + goto out_dquot;
8052 + }
8053 ++ if (DLIMIT_ALLOC_BLOCK(inode, es_alloc)) {
8054 ++ *err = -ENOSPC;
8055 ++ goto out_dlimit;
8056 ++ }
8057 +
8058 + ext2_debug ("goal=%lu.\n", goal);
8059 +
8060 +@@ -508,6 +516,8 @@ got_block:
8061 + *err = 0;
8062 + out_release:
8063 + group_release_blocks(sb, group_no, desc, gdp_bh, group_alloc);
8064 ++ DLIMIT_FREE_BLOCK(inode, es_alloc);
8065 ++out_dlimit:
8066 + release_blocks(sb, es_alloc);
8067 + out_dquot:
8068 + DQUOT_FREE_BLOCK(inode, dq_alloc);
8069 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/ext2.h linux-2.6.22.19-vs2.3.0.34/fs/ext2/ext2.h
8070 +--- linux-2.6.22.19/fs/ext2/ext2.h 2007-07-09 13:19:23 +0200
8071 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext2/ext2.h 2007-08-05 20:53:12 +0200
8072 +@@ -167,6 +167,7 @@ extern const struct file_operations ext2
8073 + extern const struct address_space_operations ext2_aops;
8074 + extern const struct address_space_operations ext2_aops_xip;
8075 + extern const struct address_space_operations ext2_nobh_aops;
8076 ++extern int ext2_sync_flags(struct inode *inode);
8077 +
8078 + /* namei.c */
8079 + extern const struct inode_operations ext2_dir_inode_operations;
8080 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/file.c linux-2.6.22.19-vs2.3.0.34/fs/ext2/file.c
8081 +--- linux-2.6.22.19/fs/ext2/file.c 2007-05-02 19:25:17 +0200
8082 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext2/file.c 2007-09-12 20:04:16 +0200
8083 +@@ -85,4 +85,5 @@ const struct inode_operations ext2_file_
8084 + #endif
8085 + .setattr = ext2_setattr,
8086 + .permission = ext2_permission,
8087 ++ .sync_flags = ext2_sync_flags,
8088 + };
8089 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/ialloc.c linux-2.6.22.19-vs2.3.0.34/fs/ext2/ialloc.c
8090 +--- linux-2.6.22.19/fs/ext2/ialloc.c 2006-11-30 21:19:19 +0100
8091 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext2/ialloc.c 2007-08-05 20:53:12 +0200
8092 +@@ -17,6 +17,8 @@
8093 + #include <linux/backing-dev.h>
8094 + #include <linux/buffer_head.h>
8095 + #include <linux/random.h>
8096 ++#include <linux/vs_dlimit.h>
8097 ++#include <linux/vs_tag.h>
8098 + #include "ext2.h"
8099 + #include "xattr.h"
8100 + #include "acl.h"
8101 +@@ -125,6 +127,7 @@ void ext2_free_inode (struct inode * ino
8102 + ext2_xattr_delete_inode(inode);
8103 + DQUOT_FREE_INODE(inode);
8104 + DQUOT_DROP(inode);
8105 ++ DLIMIT_FREE_INODE(inode);
8106 + }
8107 +
8108 + es = EXT2_SB(sb)->s_es;
8109 +@@ -464,6 +467,11 @@ struct inode *ext2_new_inode(struct inod
8110 + if (!inode)
8111 + return ERR_PTR(-ENOMEM);
8112 +
8113 ++ inode->i_tag = dx_current_fstag(sb);
8114 ++ if (DLIMIT_ALLOC_INODE(inode)) {
8115 ++ err = -ENOSPC;
8116 ++ goto fail_dlim;
8117 ++ }
8118 + ei = EXT2_I(inode);
8119 + sbi = EXT2_SB(sb);
8120 + es = sbi->s_es;
8121 +@@ -577,7 +585,8 @@ got:
8122 + inode->i_blocks = 0;
8123 + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
8124 + memset(ei->i_data, 0, sizeof(ei->i_data));
8125 +- ei->i_flags = EXT2_I(dir)->i_flags & ~EXT2_BTREE_FL;
8126 ++ ei->i_flags = EXT2_I(dir)->i_flags &
8127 ++ ~(EXT2_BTREE_FL|EXT2_IUNLINK_FL|EXT2_BARRIER_FL);
8128 + if (S_ISLNK(mode))
8129 + ei->i_flags &= ~(EXT2_IMMUTABLE_FL|EXT2_APPEND_FL);
8130 + /* dirsync is only applied to directories */
8131 +@@ -625,12 +634,15 @@ fail_free_drop:
8132 +
8133 + fail_drop:
8134 + DQUOT_DROP(inode);
8135 ++ DLIMIT_FREE_INODE(inode);
8136 + inode->i_flags |= S_NOQUOTA;
8137 + inode->i_nlink = 0;
8138 + iput(inode);
8139 + return ERR_PTR(err);
8140 +
8141 + fail:
8142 ++ DLIMIT_FREE_INODE(inode);
8143 ++fail_dlim:
8144 + make_bad_inode(inode);
8145 + iput(inode);
8146 + return ERR_PTR(err);
8147 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/inode.c linux-2.6.22.19-vs2.3.0.34/fs/ext2/inode.c
8148 +--- linux-2.6.22.19/fs/ext2/inode.c 2007-07-09 13:19:23 +0200
8149 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext2/inode.c 2007-08-18 02:52:34 +0200
8150 +@@ -31,6 +31,7 @@
8151 + #include <linux/writeback.h>
8152 + #include <linux/buffer_head.h>
8153 + #include <linux/mpage.h>
8154 ++#include <linux/vs_tag.h>
8155 + #include "ext2.h"
8156 + #include "acl.h"
8157 + #include "xip.h"
8158 +@@ -913,7 +914,7 @@ void ext2_truncate (struct inode * inode
8159 + return;
8160 + if (ext2_inode_is_fast_symlink(inode))
8161 + return;
8162 +- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
8163 ++ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
8164 + return;
8165 +
8166 + ext2_discard_prealloc(inode);
8167 +@@ -1042,13 +1043,20 @@ void ext2_set_inode_flags(struct inode *
8168 + {
8169 + unsigned int flags = EXT2_I(inode)->i_flags;
8170 +
8171 +- inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
8172 ++ inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
8173 ++ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
8174 ++
8175 ++ if (flags & EXT2_IMMUTABLE_FL)
8176 ++ inode->i_flags |= S_IMMUTABLE;
8177 ++ if (flags & EXT2_IUNLINK_FL)
8178 ++ inode->i_flags |= S_IUNLINK;
8179 ++ if (flags & EXT2_BARRIER_FL)
8180 ++ inode->i_flags |= S_BARRIER;
8181 ++
8182 + if (flags & EXT2_SYNC_FL)
8183 + inode->i_flags |= S_SYNC;
8184 + if (flags & EXT2_APPEND_FL)
8185 + inode->i_flags |= S_APPEND;
8186 +- if (flags & EXT2_IMMUTABLE_FL)
8187 +- inode->i_flags |= S_IMMUTABLE;
8188 + if (flags & EXT2_NOATIME_FL)
8189 + inode->i_flags |= S_NOATIME;
8190 + if (flags & EXT2_DIRSYNC_FL)
8191 +@@ -1074,12 +1082,37 @@ void ext2_get_inode_flags(struct ext2_in
8192 + ei->i_flags |= EXT2_DIRSYNC_FL;
8193 + }
8194 +
8195 ++int ext2_sync_flags(struct inode *inode)
8196 ++{
8197 ++ unsigned int oldflags, newflags;
8198 ++
8199 ++ oldflags = EXT2_I(inode)->i_flags;
8200 ++ newflags = oldflags & ~(EXT2_IMMUTABLE_FL |
8201 ++ EXT2_IUNLINK_FL | EXT2_BARRIER_FL);
8202 ++
8203 ++ if (IS_IMMUTABLE(inode))
8204 ++ newflags |= EXT2_IMMUTABLE_FL;
8205 ++ if (IS_IUNLINK(inode))
8206 ++ newflags |= EXT2_IUNLINK_FL;
8207 ++ if (IS_BARRIER(inode))
8208 ++ newflags |= EXT2_BARRIER_FL;
8209 ++
8210 ++ if (oldflags ^ newflags) {
8211 ++ EXT2_I(inode)->i_flags = newflags;
8212 ++ inode->i_ctime = CURRENT_TIME;
8213 ++ mark_inode_dirty(inode);
8214 ++ }
8215 ++ return 0;
8216 ++}
8217 ++
8218 + void ext2_read_inode (struct inode * inode)
8219 + {
8220 + struct ext2_inode_info *ei = EXT2_I(inode);
8221 + ino_t ino = inode->i_ino;
8222 + struct buffer_head * bh;
8223 + struct ext2_inode * raw_inode = ext2_get_inode(inode->i_sb, ino, &bh);
8224 ++ uid_t uid;
8225 ++ gid_t gid;
8226 + int n;
8227 +
8228 + #ifdef CONFIG_EXT2_FS_POSIX_ACL
8229 +@@ -1090,12 +1123,17 @@ void ext2_read_inode (struct inode * ino
8230 + goto bad_inode;
8231 +
8232 + inode->i_mode = le16_to_cpu(raw_inode->i_mode);
8233 +- inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
8234 +- inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
8235 ++ uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
8236 ++ gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
8237 + if (!(test_opt (inode->i_sb, NO_UID32))) {
8238 +- inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
8239 +- inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
8240 ++ uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
8241 ++ gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
8242 + }
8243 ++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
8244 ++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
8245 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
8246 ++ le16_to_cpu(raw_inode->i_raw_tag));
8247 ++
8248 + inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
8249 + inode->i_size = le32_to_cpu(raw_inode->i_size);
8250 + inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
8251 +@@ -1192,8 +1230,8 @@ static int ext2_update_inode(struct inod
8252 + struct ext2_inode_info *ei = EXT2_I(inode);
8253 + struct super_block *sb = inode->i_sb;
8254 + ino_t ino = inode->i_ino;
8255 +- uid_t uid = inode->i_uid;
8256 +- gid_t gid = inode->i_gid;
8257 ++ uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
8258 ++ gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
8259 + struct buffer_head * bh;
8260 + struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);
8261 + int n;
8262 +@@ -1229,6 +1267,9 @@ static int ext2_update_inode(struct inod
8263 + raw_inode->i_uid_high = 0;
8264 + raw_inode->i_gid_high = 0;
8265 + }
8266 ++#ifdef CONFIG_TAGGING_INTERN
8267 ++ raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag);
8268 ++#endif
8269 + raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
8270 + raw_inode->i_size = cpu_to_le32(inode->i_size);
8271 + raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
8272 +@@ -1315,7 +1356,8 @@ int ext2_setattr(struct dentry *dentry,
8273 + if (error)
8274 + return error;
8275 + if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
8276 +- (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
8277 ++ (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) ||
8278 ++ (iattr->ia_valid & ATTR_TAG && iattr->ia_tag != inode->i_tag)) {
8279 + error = DQUOT_TRANSFER(inode, iattr) ? -EDQUOT : 0;
8280 + if (error)
8281 + return error;
8282 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/ioctl.c linux-2.6.22.19-vs2.3.0.34/fs/ext2/ioctl.c
8283 +--- linux-2.6.22.19/fs/ext2/ioctl.c 2007-07-09 13:19:23 +0200
8284 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext2/ioctl.c 2007-08-05 20:53:12 +0200
8285 +@@ -13,6 +13,7 @@
8286 + #include <linux/sched.h>
8287 + #include <linux/compat.h>
8288 + #include <linux/smp_lock.h>
8289 ++#include <linux/mount.h>
8290 + #include <asm/current.h>
8291 + #include <asm/uaccess.h>
8292 +
8293 +@@ -33,7 +34,8 @@ int ext2_ioctl (struct inode * inode, st
8294 + case EXT2_IOC_SETFLAGS: {
8295 + unsigned int oldflags;
8296 +
8297 +- if (IS_RDONLY(inode))
8298 ++ if (IS_RDONLY(inode) ||
8299 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
8300 + return -EROFS;
8301 +
8302 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
8303 +@@ -54,7 +56,9 @@ int ext2_ioctl (struct inode * inode, st
8304 + *
8305 + * This test looks nicer. Thanks to Pauline Middelink
8306 + */
8307 +- if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
8308 ++ if ((oldflags & EXT2_IMMUTABLE_FL) ||
8309 ++ ((flags ^ oldflags) & (EXT2_APPEND_FL |
8310 ++ EXT2_IMMUTABLE_FL | EXT2_IUNLINK_FL))) {
8311 + if (!capable(CAP_LINUX_IMMUTABLE)) {
8312 + mutex_unlock(&inode->i_mutex);
8313 + return -EPERM;
8314 +@@ -76,7 +80,8 @@ int ext2_ioctl (struct inode * inode, st
8315 + case EXT2_IOC_SETVERSION:
8316 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
8317 + return -EPERM;
8318 +- if (IS_RDONLY(inode))
8319 ++ if (IS_RDONLY(inode) ||
8320 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
8321 + return -EROFS;
8322 + if (get_user(inode->i_generation, (int __user *) arg))
8323 + return -EFAULT;
8324 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/namei.c linux-2.6.22.19-vs2.3.0.34/fs/ext2/namei.c
8325 +--- linux-2.6.22.19/fs/ext2/namei.c 2007-05-02 19:25:17 +0200
8326 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext2/namei.c 2007-08-05 20:53:12 +0200
8327 +@@ -31,6 +31,7 @@
8328 + */
8329 +
8330 + #include <linux/pagemap.h>
8331 ++#include <linux/vs_tag.h>
8332 + #include "ext2.h"
8333 + #include "xattr.h"
8334 + #include "acl.h"
8335 +@@ -66,6 +67,7 @@ static struct dentry *ext2_lookup(struct
8336 + inode = iget(dir->i_sb, ino);
8337 + if (!inode)
8338 + return ERR_PTR(-EACCES);
8339 ++ dx_propagate_tag(nd, inode);
8340 + }
8341 + return d_splice_alias(inode, dentry);
8342 + }
8343 +@@ -391,6 +393,7 @@ const struct inode_operations ext2_dir_i
8344 + #endif
8345 + .setattr = ext2_setattr,
8346 + .permission = ext2_permission,
8347 ++ .sync_flags = ext2_sync_flags,
8348 + };
8349 +
8350 + const struct inode_operations ext2_special_inode_operations = {
8351 +@@ -402,4 +405,5 @@ const struct inode_operations ext2_speci
8352 + #endif
8353 + .setattr = ext2_setattr,
8354 + .permission = ext2_permission,
8355 ++ .sync_flags = ext2_sync_flags,
8356 + };
8357 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/super.c linux-2.6.22.19-vs2.3.0.34/fs/ext2/super.c
8358 +--- linux-2.6.22.19/fs/ext2/super.c 2007-07-09 13:19:23 +0200
8359 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext2/super.c 2007-08-05 20:53:12 +0200
8360 +@@ -321,7 +321,7 @@ enum {
8361 + Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
8362 + Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
8363 + Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota,
8364 +- Opt_usrquota, Opt_grpquota
8365 ++ Opt_usrquota, Opt_grpquota, Opt_tag, Opt_notag, Opt_tagid
8366 + };
8367 +
8368 + static match_table_t tokens = {
8369 +@@ -349,6 +349,9 @@ static match_table_t tokens = {
8370 + {Opt_acl, "acl"},
8371 + {Opt_noacl, "noacl"},
8372 + {Opt_xip, "xip"},
8373 ++ {Opt_tag, "tag"},
8374 ++ {Opt_notag, "notag"},
8375 ++ {Opt_tagid, "tagid=%u"},
8376 + {Opt_grpquota, "grpquota"},
8377 + {Opt_ignore, "noquota"},
8378 + {Opt_quota, "quota"},
8379 +@@ -417,6 +420,20 @@ static int parse_options (char * options
8380 + case Opt_nouid32:
8381 + set_opt (sbi->s_mount_opt, NO_UID32);
8382 + break;
8383 ++#ifndef CONFIG_TAGGING_NONE
8384 ++ case Opt_tag:
8385 ++ set_opt (sbi->s_mount_opt, TAGGED);
8386 ++ break;
8387 ++ case Opt_notag:
8388 ++ clear_opt (sbi->s_mount_opt, TAGGED);
8389 ++ break;
8390 ++#endif
8391 ++#ifdef CONFIG_PROPAGATE
8392 ++ case Opt_tagid:
8393 ++ /* use args[0] */
8394 ++ set_opt (sbi->s_mount_opt, TAGGED);
8395 ++ break;
8396 ++#endif
8397 + case Opt_nocheck:
8398 + clear_opt (sbi->s_mount_opt, CHECK);
8399 + break;
8400 +@@ -727,6 +744,8 @@ static int ext2_fill_super(struct super_
8401 + if (!parse_options ((char *) data, sbi))
8402 + goto failed_mount;
8403 +
8404 ++ if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAGGED)
8405 ++ sb->s_flags |= MS_TAGGED;
8406 + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
8407 + ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
8408 + MS_POSIXACL : 0);
8409 +@@ -1035,6 +1054,13 @@ static int ext2_remount (struct super_bl
8410 + goto restore_opts;
8411 + }
8412 +
8413 ++ if ((sbi->s_mount_opt & EXT2_MOUNT_TAGGED) &&
8414 ++ !(sb->s_flags & MS_TAGGED)) {
8415 ++ printk("EXT2-fs: %s: tagging not permitted on remount.\n",
8416 ++ sb->s_id);
8417 ++ return -EINVAL;
8418 ++ }
8419 ++
8420 + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
8421 + ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
8422 +
8423 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/symlink.c linux-2.6.22.19-vs2.3.0.34/fs/ext2/symlink.c
8424 +--- linux-2.6.22.19/fs/ext2/symlink.c 2007-05-02 19:25:17 +0200
8425 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext2/symlink.c 2007-08-05 20:53:12 +0200
8426 +@@ -38,6 +38,7 @@ const struct inode_operations ext2_symli
8427 + .listxattr = ext2_listxattr,
8428 + .removexattr = generic_removexattr,
8429 + #endif
8430 ++ .sync_flags = ext2_sync_flags,
8431 + };
8432 +
8433 + const struct inode_operations ext2_fast_symlink_inode_operations = {
8434 +@@ -49,4 +50,5 @@ const struct inode_operations ext2_fast_
8435 + .listxattr = ext2_listxattr,
8436 + .removexattr = generic_removexattr,
8437 + #endif
8438 ++ .sync_flags = ext2_sync_flags,
8439 + };
8440 +diff -NurpP --minimal linux-2.6.22.19/fs/ext2/xattr.c linux-2.6.22.19-vs2.3.0.34/fs/ext2/xattr.c
8441 +--- linux-2.6.22.19/fs/ext2/xattr.c 2007-02-06 03:01:18 +0100
8442 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext2/xattr.c 2007-08-05 20:53:12 +0200
8443 +@@ -60,6 +60,7 @@
8444 + #include <linux/mbcache.h>
8445 + #include <linux/quotaops.h>
8446 + #include <linux/rwsem.h>
8447 ++#include <linux/vs_dlimit.h>
8448 + #include "ext2.h"
8449 + #include "xattr.h"
8450 + #include "acl.h"
8451 +@@ -641,8 +642,12 @@ ext2_xattr_set2(struct inode *inode, str
8452 + the inode. */
8453 + ea_bdebug(new_bh, "reusing block");
8454 +
8455 ++ error = -ENOSPC;
8456 ++ if (DLIMIT_ALLOC_BLOCK(inode, 1))
8457 ++ goto cleanup;
8458 + error = -EDQUOT;
8459 + if (DQUOT_ALLOC_BLOCK(inode, 1)) {
8460 ++ DLIMIT_FREE_BLOCK(inode, 1);
8461 + unlock_buffer(new_bh);
8462 + goto cleanup;
8463 + }
8464 +@@ -736,6 +741,7 @@ ext2_xattr_set2(struct inode *inode, str
8465 + le32_to_cpu(HDR(old_bh)->h_refcount) - 1);
8466 + if (ce)
8467 + mb_cache_entry_release(ce);
8468 ++ DLIMIT_FREE_BLOCK(inode, 1);
8469 + DQUOT_FREE_BLOCK(inode, 1);
8470 + mark_buffer_dirty(old_bh);
8471 + ea_bdebug(old_bh, "refcount now=%d",
8472 +@@ -800,6 +806,7 @@ ext2_xattr_delete_inode(struct inode *in
8473 + mark_buffer_dirty(bh);
8474 + if (IS_SYNC(inode))
8475 + sync_dirty_buffer(bh);
8476 ++ DLIMIT_FREE_BLOCK(inode, 1);
8477 + DQUOT_FREE_BLOCK(inode, 1);
8478 + }
8479 + EXT2_I(inode)->i_file_acl = 0;
8480 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/balloc.c linux-2.6.22.19-vs2.3.0.34/fs/ext3/balloc.c
8481 +--- linux-2.6.22.19/fs/ext3/balloc.c 2007-05-02 19:25:17 +0200
8482 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext3/balloc.c 2007-08-05 20:53:12 +0200
8483 +@@ -19,6 +19,8 @@
8484 + #include <linux/ext3_jbd.h>
8485 + #include <linux/quotaops.h>
8486 + #include <linux/buffer_head.h>
8487 ++#include <linux/vs_dlimit.h>
8488 ++#include <linux/vs_tag.h>
8489 +
8490 + /*
8491 + * balloc.c contains the blocks allocation and deallocation routines
8492 +@@ -613,8 +615,10 @@ void ext3_free_blocks(handle_t *handle,
8493 + return;
8494 + }
8495 + ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks);
8496 +- if (dquot_freed_blocks)
8497 ++ if (dquot_freed_blocks) {
8498 ++ DLIMIT_FREE_BLOCK(inode, dquot_freed_blocks);
8499 + DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
8500 ++ }
8501 + return;
8502 + }
8503 +
8504 +@@ -1353,18 +1357,33 @@ out:
8505 + *
8506 + * Check if filesystem has at least 1 free block available for allocation.
8507 + */
8508 +-static int ext3_has_free_blocks(struct ext3_sb_info *sbi)
8509 ++static int ext3_has_free_blocks(struct super_block *sb)
8510 + {
8511 +- ext3_fsblk_t free_blocks, root_blocks;
8512 ++ struct ext3_sb_info *sbi = EXT3_SB(sb);
8513 ++ unsigned long long free_blocks, root_blocks;
8514 ++ int cond;
8515 +
8516 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
8517 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
8518 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
8519 ++
8520 ++ vxdprintk(VXD_CBIT(dlim, 3),
8521 ++ "ext3_has_free_blocks(%p): free=%llu, root=%llu",
8522 ++ sb, free_blocks, root_blocks);
8523 ++
8524 ++ DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
8525 ++
8526 ++ cond = (free_blocks < root_blocks + 1 &&
8527 ++ !capable(CAP_SYS_RESOURCE) &&
8528 + sbi->s_resuid != current->fsuid &&
8529 +- (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
8530 +- return 0;
8531 +- }
8532 +- return 1;
8533 ++ (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
8534 ++
8535 ++ vxdprintk(VXD_CBIT(dlim, 3),
8536 ++ "ext3_has_free_blocks(%p): %llu<%llu+1, %c, %u!=%u r=%d",
8537 ++ sb, free_blocks, root_blocks,
8538 ++ !capable(CAP_SYS_RESOURCE)?'1':'0',
8539 ++ sbi->s_resuid, current->fsuid, cond?0:1);
8540 ++
8541 ++ return (cond ? 0 : 1);
8542 + }
8543 +
8544 + /**
8545 +@@ -1381,7 +1400,7 @@ static int ext3_has_free_blocks(struct e
8546 + */
8547 + int ext3_should_retry_alloc(struct super_block *sb, int *retries)
8548 + {
8549 +- if (!ext3_has_free_blocks(EXT3_SB(sb)) || (*retries)++ > 3)
8550 ++ if (!ext3_has_free_blocks(sb) || (*retries)++ > 3)
8551 + return 0;
8552 +
8553 + jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
8554 +@@ -1444,6 +1463,8 @@ ext3_fsblk_t ext3_new_blocks(handle_t *h
8555 + *errp = -EDQUOT;
8556 + return 0;
8557 + }
8558 ++ if (DLIMIT_ALLOC_BLOCK(inode, num))
8559 ++ goto out_dlimit;
8560 +
8561 + sbi = EXT3_SB(sb);
8562 + es = EXT3_SB(sb)->s_es;
8563 +@@ -1460,7 +1481,7 @@ ext3_fsblk_t ext3_new_blocks(handle_t *h
8564 + if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0))
8565 + my_rsv = &block_i->rsv_window_node;
8566 +
8567 +- if (!ext3_has_free_blocks(sbi)) {
8568 ++ if (!ext3_has_free_blocks(sb)) {
8569 + *errp = -ENOSPC;
8570 + goto out;
8571 + }
8572 +@@ -1647,12 +1668,16 @@ allocated:
8573 + *errp = 0;
8574 + brelse(bitmap_bh);
8575 + DQUOT_FREE_BLOCK(inode, *count-num);
8576 ++ DLIMIT_FREE_BLOCK(inode, *count-num);
8577 + *count = num;
8578 + return ret_block;
8579 +
8580 + io_error:
8581 + *errp = -EIO;
8582 + out:
8583 ++ if (!performed_allocation)
8584 ++ DLIMIT_FREE_BLOCK(inode, *count);
8585 ++out_dlimit:
8586 + if (fatal) {
8587 + *errp = fatal;
8588 + ext3_std_error(sb, fatal);
8589 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/file.c linux-2.6.22.19-vs2.3.0.34/fs/ext3/file.c
8590 +--- linux-2.6.22.19/fs/ext3/file.c 2007-05-02 19:25:17 +0200
8591 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext3/file.c 2007-09-12 20:04:16 +0200
8592 +@@ -135,5 +135,6 @@ const struct inode_operations ext3_file_
8593 + .removexattr = generic_removexattr,
8594 + #endif
8595 + .permission = ext3_permission,
8596 ++ .sync_flags = ext3_sync_flags,
8597 + };
8598 +
8599 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/ialloc.c linux-2.6.22.19-vs2.3.0.34/fs/ext3/ialloc.c
8600 +--- linux-2.6.22.19/fs/ext3/ialloc.c 2006-11-30 21:19:19 +0100
8601 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext3/ialloc.c 2007-08-05 20:53:12 +0200
8602 +@@ -23,6 +23,8 @@
8603 + #include <linux/buffer_head.h>
8604 + #include <linux/random.h>
8605 + #include <linux/bitops.h>
8606 ++#include <linux/vs_dlimit.h>
8607 ++#include <linux/vs_tag.h>
8608 +
8609 + #include <asm/byteorder.h>
8610 +
8611 +@@ -127,6 +129,7 @@ void ext3_free_inode (handle_t *handle,
8612 + ext3_xattr_delete_inode(handle, inode);
8613 + DQUOT_FREE_INODE(inode);
8614 + DQUOT_DROP(inode);
8615 ++ DLIMIT_FREE_INODE(inode);
8616 +
8617 + is_directory = S_ISDIR(inode->i_mode);
8618 +
8619 +@@ -445,6 +448,12 @@ struct inode *ext3_new_inode(handle_t *h
8620 + inode = new_inode(sb);
8621 + if (!inode)
8622 + return ERR_PTR(-ENOMEM);
8623 ++
8624 ++ inode->i_tag = dx_current_fstag(sb);
8625 ++ if (DLIMIT_ALLOC_INODE(inode)) {
8626 ++ err = -ENOSPC;
8627 ++ goto out_dlimit;
8628 ++ }
8629 + ei = EXT3_I(inode);
8630 +
8631 + sbi = EXT3_SB(sb);
8632 +@@ -566,7 +575,8 @@ got:
8633 + ei->i_dir_start_lookup = 0;
8634 + ei->i_disksize = 0;
8635 +
8636 +- ei->i_flags = EXT3_I(dir)->i_flags & ~EXT3_INDEX_FL;
8637 ++ ei->i_flags = EXT3_I(dir)->i_flags &
8638 ++ ~(EXT3_INDEX_FL|EXT3_IUNLINK_FL|EXT3_BARRIER_FL);
8639 + if (S_ISLNK(mode))
8640 + ei->i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL);
8641 + /* dirsync only applies to directories */
8642 +@@ -621,6 +631,8 @@ got:
8643 + fail:
8644 + ext3_std_error(sb, err);
8645 + out:
8646 ++ DLIMIT_FREE_INODE(inode);
8647 ++out_dlimit:
8648 + iput(inode);
8649 + ret = ERR_PTR(err);
8650 + really_out:
8651 +@@ -632,6 +644,7 @@ fail_free_drop:
8652 +
8653 + fail_drop:
8654 + DQUOT_DROP(inode);
8655 ++ DLIMIT_FREE_INODE(inode);
8656 + inode->i_flags |= S_NOQUOTA;
8657 + inode->i_nlink = 0;
8658 + iput(inode);
8659 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/inode.c linux-2.6.22.19-vs2.3.0.34/fs/ext3/inode.c
8660 +--- linux-2.6.22.19/fs/ext3/inode.c 2007-07-09 13:19:23 +0200
8661 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext3/inode.c 2007-08-18 02:52:34 +0200
8662 +@@ -36,6 +36,7 @@
8663 + #include <linux/mpage.h>
8664 + #include <linux/uio.h>
8665 + #include <linux/bio.h>
8666 ++#include <linux/vs_tag.h>
8667 + #include "xattr.h"
8668 + #include "acl.h"
8669 +
8670 +@@ -2237,7 +2238,7 @@ void ext3_truncate(struct inode *inode)
8671 + return;
8672 + if (ext3_inode_is_fast_symlink(inode))
8673 + return;
8674 +- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
8675 ++ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
8676 + return;
8677 +
8678 + /*
8679 +@@ -2559,13 +2560,20 @@ void ext3_set_inode_flags(struct inode *
8680 + {
8681 + unsigned int flags = EXT3_I(inode)->i_flags;
8682 +
8683 +- inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
8684 ++ inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
8685 ++ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
8686 ++
8687 ++ if (flags & EXT3_IMMUTABLE_FL)
8688 ++ inode->i_flags |= S_IMMUTABLE;
8689 ++ if (flags & EXT3_IUNLINK_FL)
8690 ++ inode->i_flags |= S_IUNLINK;
8691 ++ if (flags & EXT3_BARRIER_FL)
8692 ++ inode->i_flags |= S_BARRIER;
8693 ++
8694 + if (flags & EXT3_SYNC_FL)
8695 + inode->i_flags |= S_SYNC;
8696 + if (flags & EXT3_APPEND_FL)
8697 + inode->i_flags |= S_APPEND;
8698 +- if (flags & EXT3_IMMUTABLE_FL)
8699 +- inode->i_flags |= S_IMMUTABLE;
8700 + if (flags & EXT3_NOATIME_FL)
8701 + inode->i_flags |= S_NOATIME;
8702 + if (flags & EXT3_DIRSYNC_FL)
8703 +@@ -2591,6 +2599,45 @@ void ext3_get_inode_flags(struct ext3_in
8704 + ei->i_flags |= EXT3_DIRSYNC_FL;
8705 + }
8706 +
8707 ++int ext3_sync_flags(struct inode *inode)
8708 ++{
8709 ++ unsigned int oldflags, newflags;
8710 ++ int err = 0;
8711 ++
8712 ++ oldflags = EXT3_I(inode)->i_flags;
8713 ++ newflags = oldflags & ~(EXT3_IMMUTABLE_FL |
8714 ++ EXT3_IUNLINK_FL | EXT3_BARRIER_FL);
8715 ++
8716 ++ if (IS_IMMUTABLE(inode))
8717 ++ newflags |= EXT3_IMMUTABLE_FL;
8718 ++ if (IS_IUNLINK(inode))
8719 ++ newflags |= EXT3_IUNLINK_FL;
8720 ++ if (IS_BARRIER(inode))
8721 ++ newflags |= EXT3_BARRIER_FL;
8722 ++
8723 ++ if (oldflags ^ newflags) {
8724 ++ handle_t *handle;
8725 ++ struct ext3_iloc iloc;
8726 ++
8727 ++ handle = ext3_journal_start(inode, 1);
8728 ++ if (IS_ERR(handle))
8729 ++ return PTR_ERR(handle);
8730 ++ if (IS_SYNC(inode))
8731 ++ handle->h_sync = 1;
8732 ++ err = ext3_reserve_inode_write(handle, inode, &iloc);
8733 ++ if (err)
8734 ++ goto flags_err;
8735 ++
8736 ++ EXT3_I(inode)->i_flags = newflags;
8737 ++ inode->i_ctime = CURRENT_TIME;
8738 ++
8739 ++ err = ext3_mark_iloc_dirty(handle, inode, &iloc);
8740 ++ flags_err:
8741 ++ ext3_journal_stop(handle);
8742 ++ }
8743 ++ return err;
8744 ++}
8745 ++
8746 + void ext3_read_inode(struct inode * inode)
8747 + {
8748 + struct ext3_iloc iloc;
8749 +@@ -2598,6 +2645,8 @@ void ext3_read_inode(struct inode * inod
8750 + struct ext3_inode_info *ei = EXT3_I(inode);
8751 + struct buffer_head *bh;
8752 + int block;
8753 ++ uid_t uid;
8754 ++ gid_t gid;
8755 +
8756 + #ifdef CONFIG_EXT3_FS_POSIX_ACL
8757 + ei->i_acl = EXT3_ACL_NOT_CACHED;
8758 +@@ -2610,12 +2659,17 @@ void ext3_read_inode(struct inode * inod
8759 + bh = iloc.bh;
8760 + raw_inode = ext3_raw_inode(&iloc);
8761 + inode->i_mode = le16_to_cpu(raw_inode->i_mode);
8762 +- inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
8763 +- inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
8764 ++ uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
8765 ++ gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
8766 + if(!(test_opt (inode->i_sb, NO_UID32))) {
8767 +- inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
8768 +- inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
8769 ++ uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
8770 ++ gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
8771 + }
8772 ++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
8773 ++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
8774 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
8775 ++ le16_to_cpu(raw_inode->i_raw_tag));
8776 ++
8777 + inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
8778 + inode->i_size = le32_to_cpu(raw_inode->i_size);
8779 + inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
8780 +@@ -2741,6 +2795,8 @@ static int ext3_do_update_inode(handle_t
8781 + struct ext3_inode *raw_inode = ext3_raw_inode(iloc);
8782 + struct ext3_inode_info *ei = EXT3_I(inode);
8783 + struct buffer_head *bh = iloc->bh;
8784 ++ uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
8785 ++ gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
8786 + int err = 0, rc, block;
8787 +
8788 + /* For fields not not tracking in the in-memory inode,
8789 +@@ -2751,29 +2807,32 @@ static int ext3_do_update_inode(handle_t
8790 + ext3_get_inode_flags(ei);
8791 + raw_inode->i_mode = cpu_to_le16(inode->i_mode);
8792 + if(!(test_opt(inode->i_sb, NO_UID32))) {
8793 +- raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
8794 +- raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid));
8795 ++ raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid));
8796 ++ raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid));
8797 + /*
8798 + * Fix up interoperability with old kernels. Otherwise, old inodes get
8799 + * re-used with the upper 16 bits of the uid/gid intact
8800 + */
8801 + if(!ei->i_dtime) {
8802 + raw_inode->i_uid_high =
8803 +- cpu_to_le16(high_16_bits(inode->i_uid));
8804 ++ cpu_to_le16(high_16_bits(uid));
8805 + raw_inode->i_gid_high =
8806 +- cpu_to_le16(high_16_bits(inode->i_gid));
8807 ++ cpu_to_le16(high_16_bits(gid));
8808 + } else {
8809 + raw_inode->i_uid_high = 0;
8810 + raw_inode->i_gid_high = 0;
8811 + }
8812 + } else {
8813 + raw_inode->i_uid_low =
8814 +- cpu_to_le16(fs_high2lowuid(inode->i_uid));
8815 ++ cpu_to_le16(fs_high2lowuid(uid));
8816 + raw_inode->i_gid_low =
8817 +- cpu_to_le16(fs_high2lowgid(inode->i_gid));
8818 ++ cpu_to_le16(fs_high2lowgid(gid));
8819 + raw_inode->i_uid_high = 0;
8820 + raw_inode->i_gid_high = 0;
8821 + }
8822 ++#ifdef CONFIG_TAGGING_INTERN
8823 ++ raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag);
8824 ++#endif
8825 + raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
8826 + raw_inode->i_size = cpu_to_le32(ei->i_disksize);
8827 + raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
8828 +@@ -2926,7 +2985,8 @@ int ext3_setattr(struct dentry *dentry,
8829 + return error;
8830 +
8831 + if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
8832 +- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
8833 ++ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
8834 ++ (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) {
8835 + handle_t *handle;
8836 +
8837 + /* (user+group)*(old+new) structure, inode write (sb,
8838 +@@ -2948,6 +3008,8 @@ int ext3_setattr(struct dentry *dentry,
8839 + inode->i_uid = attr->ia_uid;
8840 + if (attr->ia_valid & ATTR_GID)
8841 + inode->i_gid = attr->ia_gid;
8842 ++ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
8843 ++ inode->i_tag = attr->ia_tag;
8844 + error = ext3_mark_inode_dirty(handle, inode);
8845 + ext3_journal_stop(handle);
8846 + }
8847 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/ioctl.c linux-2.6.22.19-vs2.3.0.34/fs/ext3/ioctl.c
8848 +--- linux-2.6.22.19/fs/ext3/ioctl.c 2007-07-09 13:19:23 +0200
8849 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext3/ioctl.c 2007-08-05 20:53:12 +0200
8850 +@@ -8,6 +8,7 @@
8851 + */
8852 +
8853 + #include <linux/fs.h>
8854 ++#include <linux/mount.h>
8855 + #include <linux/jbd.h>
8856 + #include <linux/capability.h>
8857 + #include <linux/ext3_fs.h>
8858 +@@ -15,6 +16,7 @@
8859 + #include <linux/time.h>
8860 + #include <linux/compat.h>
8861 + #include <linux/smp_lock.h>
8862 ++#include <linux/vs_tag.h>
8863 + #include <asm/uaccess.h>
8864 +
8865 + int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
8866 +@@ -38,7 +40,8 @@ int ext3_ioctl (struct inode * inode, st
8867 + unsigned int oldflags;
8868 + unsigned int jflag;
8869 +
8870 +- if (IS_RDONLY(inode))
8871 ++ if (IS_RDONLY(inode) ||
8872 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
8873 + return -EROFS;
8874 +
8875 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
8876 +@@ -62,7 +65,9 @@ int ext3_ioctl (struct inode * inode, st
8877 + *
8878 + * This test looks nicer. Thanks to Pauline Middelink
8879 + */
8880 +- if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
8881 ++ if ((oldflags & EXT3_IMMUTABLE_FL) ||
8882 ++ ((flags ^ oldflags) & (EXT3_APPEND_FL |
8883 ++ EXT3_IMMUTABLE_FL | EXT3_IUNLINK_FL))) {
8884 + if (!capable(CAP_LINUX_IMMUTABLE)) {
8885 + mutex_unlock(&inode->i_mutex);
8886 + return -EPERM;
8887 +@@ -124,7 +129,8 @@ flags_err:
8888 +
8889 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
8890 + return -EPERM;
8891 +- if (IS_RDONLY(inode))
8892 ++ if (IS_RDONLY(inode) ||
8893 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
8894 + return -EROFS;
8895 + if (get_user(generation, (int __user *) arg))
8896 + return -EFAULT;
8897 +@@ -178,7 +184,8 @@ flags_err:
8898 + if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
8899 + return -ENOTTY;
8900 +
8901 +- if (IS_RDONLY(inode))
8902 ++ if (IS_RDONLY(inode) ||
8903 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
8904 + return -EROFS;
8905 +
8906 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
8907 +@@ -213,7 +220,8 @@ flags_err:
8908 + if (!capable(CAP_SYS_RESOURCE))
8909 + return -EPERM;
8910 +
8911 +- if (IS_RDONLY(inode))
8912 ++ if (IS_RDONLY(inode) ||
8913 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
8914 + return -EROFS;
8915 +
8916 + if (get_user(n_blocks_count, (__u32 __user *)arg))
8917 +@@ -234,7 +242,8 @@ flags_err:
8918 + if (!capable(CAP_SYS_RESOURCE))
8919 + return -EPERM;
8920 +
8921 +- if (IS_RDONLY(inode))
8922 ++ if (IS_RDONLY(inode) ||
8923 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
8924 + return -EROFS;
8925 +
8926 + if (copy_from_user(&input, (struct ext3_new_group_input __user *)arg,
8927 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/namei.c linux-2.6.22.19-vs2.3.0.34/fs/ext3/namei.c
8928 +--- linux-2.6.22.19/fs/ext3/namei.c 2008-03-14 20:19:03 +0100
8929 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext3/namei.c 2007-09-30 14:58:01 +0200
8930 +@@ -36,6 +36,7 @@
8931 + #include <linux/quotaops.h>
8932 + #include <linux/buffer_head.h>
8933 + #include <linux/bio.h>
8934 ++#include <linux/vs_tag.h>
8935 +
8936 + #include "namei.h"
8937 + #include "xattr.h"
8938 +@@ -1052,6 +1053,7 @@ static struct dentry *ext3_lookup(struct
8939 +
8940 + if (!inode)
8941 + return ERR_PTR(-EACCES);
8942 ++ dx_propagate_tag(nd, inode);
8943 + }
8944 + return d_splice_alias(inode, dentry);
8945 + }
8946 +@@ -2443,6 +2445,7 @@ const struct inode_operations ext3_dir_i
8947 + .removexattr = generic_removexattr,
8948 + #endif
8949 + .permission = ext3_permission,
8950 ++ .sync_flags = ext3_sync_flags,
8951 + };
8952 +
8953 + const struct inode_operations ext3_special_inode_operations = {
8954 +@@ -2454,4 +2457,5 @@ const struct inode_operations ext3_speci
8955 + .removexattr = generic_removexattr,
8956 + #endif
8957 + .permission = ext3_permission,
8958 ++ .sync_flags = ext3_sync_flags,
8959 + };
8960 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/super.c linux-2.6.22.19-vs2.3.0.34/fs/ext3/super.c
8961 +--- linux-2.6.22.19/fs/ext3/super.c 2007-07-09 13:19:23 +0200
8962 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext3/super.c 2007-08-05 20:53:12 +0200
8963 +@@ -674,7 +674,7 @@ enum {
8964 + Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
8965 + Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
8966 + Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
8967 +- Opt_grpquota
8968 ++ Opt_grpquota, Opt_tag, Opt_notag, Opt_tagid
8969 + };
8970 +
8971 + static match_table_t tokens = {
8972 +@@ -724,6 +724,9 @@ static match_table_t tokens = {
8973 + {Opt_quota, "quota"},
8974 + {Opt_usrquota, "usrquota"},
8975 + {Opt_barrier, "barrier=%u"},
8976 ++ {Opt_tag, "tag"},
8977 ++ {Opt_notag, "notag"},
8978 ++ {Opt_tagid, "tagid=%u"},
8979 + {Opt_err, NULL},
8980 + {Opt_resize, "resize"},
8981 + };
8982 +@@ -817,6 +820,20 @@ static int parse_options (char *options,
8983 + case Opt_nouid32:
8984 + set_opt (sbi->s_mount_opt, NO_UID32);
8985 + break;
8986 ++#ifndef CONFIG_TAGGING_NONE
8987 ++ case Opt_tag:
8988 ++ set_opt (sbi->s_mount_opt, TAGGED);
8989 ++ break;
8990 ++ case Opt_notag:
8991 ++ clear_opt (sbi->s_mount_opt, TAGGED);
8992 ++ break;
8993 ++#endif
8994 ++#ifdef CONFIG_PROPAGATE
8995 ++ case Opt_tagid:
8996 ++ /* use args[0] */
8997 ++ set_opt (sbi->s_mount_opt, TAGGED);
8998 ++ break;
8999 ++#endif
9000 + case Opt_nocheck:
9001 + clear_opt (sbi->s_mount_opt, CHECK);
9002 + break;
9003 +@@ -1487,6 +1504,9 @@ static int ext3_fill_super (struct super
9004 + NULL, 0))
9005 + goto failed_mount;
9006 +
9007 ++ if (EXT3_SB(sb)->s_mount_opt & EXT3_MOUNT_TAGGED)
9008 ++ sb->s_flags |= MS_TAGGED;
9009 ++
9010 + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
9011 + ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
9012 +
9013 +@@ -2302,6 +2322,12 @@ static int ext3_remount (struct super_bl
9014 +
9015 + if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
9016 + ext3_abort(sb, __FUNCTION__, "Abort forced by user");
9017 ++ if ((sbi->s_mount_opt & EXT3_MOUNT_TAGGED) &&
9018 ++ !(sb->s_flags & MS_TAGGED)) {
9019 ++ printk("EXT3-fs: %s: tagging not permitted on remount.\n",
9020 ++ sb->s_id);
9021 ++ return -EINVAL;
9022 ++ }
9023 +
9024 + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
9025 + ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
9026 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/symlink.c linux-2.6.22.19-vs2.3.0.34/fs/ext3/symlink.c
9027 +--- linux-2.6.22.19/fs/ext3/symlink.c 2007-05-02 19:25:17 +0200
9028 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext3/symlink.c 2007-08-05 20:53:12 +0200
9029 +@@ -40,6 +40,7 @@ const struct inode_operations ext3_symli
9030 + .listxattr = ext3_listxattr,
9031 + .removexattr = generic_removexattr,
9032 + #endif
9033 ++ .sync_flags = ext3_sync_flags,
9034 + };
9035 +
9036 + const struct inode_operations ext3_fast_symlink_inode_operations = {
9037 +@@ -51,4 +52,5 @@ const struct inode_operations ext3_fast_
9038 + .listxattr = ext3_listxattr,
9039 + .removexattr = generic_removexattr,
9040 + #endif
9041 ++ .sync_flags = ext3_sync_flags,
9042 + };
9043 +diff -NurpP --minimal linux-2.6.22.19/fs/ext3/xattr.c linux-2.6.22.19-vs2.3.0.34/fs/ext3/xattr.c
9044 +--- linux-2.6.22.19/fs/ext3/xattr.c 2007-05-02 19:25:17 +0200
9045 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext3/xattr.c 2007-08-05 20:53:12 +0200
9046 +@@ -58,6 +58,7 @@
9047 + #include <linux/mbcache.h>
9048 + #include <linux/quotaops.h>
9049 + #include <linux/rwsem.h>
9050 ++#include <linux/vs_dlimit.h>
9051 + #include "xattr.h"
9052 + #include "acl.h"
9053 +
9054 +@@ -497,6 +498,7 @@ ext3_xattr_release_block(handle_t *handl
9055 + error = ext3_journal_dirty_metadata(handle, bh);
9056 + if (IS_SYNC(inode))
9057 + handle->h_sync = 1;
9058 ++ DLIMIT_FREE_BLOCK(inode, 1);
9059 + DQUOT_FREE_BLOCK(inode, 1);
9060 + ea_bdebug(bh, "refcount now=%d; releasing",
9061 + le32_to_cpu(BHDR(bh)->h_refcount));
9062 +@@ -771,11 +773,14 @@ inserted:
9063 + if (new_bh == bs->bh)
9064 + ea_bdebug(new_bh, "keeping");
9065 + else {
9066 ++ error = -ENOSPC;
9067 ++ if (DLIMIT_ALLOC_BLOCK(inode, 1))
9068 ++ goto cleanup;
9069 + /* The old block is released after updating
9070 + the inode. */
9071 + error = -EDQUOT;
9072 + if (DQUOT_ALLOC_BLOCK(inode, 1))
9073 +- goto cleanup;
9074 ++ goto cleanup_dlimit;
9075 + error = ext3_journal_get_write_access(handle,
9076 + new_bh);
9077 + if (error)
9078 +@@ -852,6 +857,8 @@ cleanup:
9079 +
9080 + cleanup_dquot:
9081 + DQUOT_FREE_BLOCK(inode, 1);
9082 ++cleanup_dlimit:
9083 ++ DLIMIT_FREE_BLOCK(inode, 1);
9084 + goto cleanup;
9085 +
9086 + bad_block:
9087 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/balloc.c linux-2.6.22.19-vs2.3.0.34/fs/ext4/balloc.c
9088 +--- linux-2.6.22.19/fs/ext4/balloc.c 2007-07-09 13:19:23 +0200
9089 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext4/balloc.c 2007-08-05 20:53:12 +0200
9090 +@@ -19,6 +19,8 @@
9091 + #include <linux/ext4_jbd2.h>
9092 + #include <linux/quotaops.h>
9093 + #include <linux/buffer_head.h>
9094 ++#include <linux/vs_dlimit.h>
9095 ++#include <linux/vs_tag.h>
9096 +
9097 + /*
9098 + * balloc.c contains the blocks allocation and deallocation routines
9099 +@@ -630,8 +632,10 @@ void ext4_free_blocks(handle_t *handle,
9100 + return;
9101 + }
9102 + ext4_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks);
9103 +- if (dquot_freed_blocks)
9104 ++ if (dquot_freed_blocks) {
9105 ++ DLIMIT_FREE_BLOCK(inode, dquot_freed_blocks);
9106 + DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
9107 ++ }
9108 + return;
9109 + }
9110 +
9111 +@@ -1370,18 +1374,33 @@ out:
9112 + *
9113 + * Check if filesystem has at least 1 free block available for allocation.
9114 + */
9115 +-static int ext4_has_free_blocks(struct ext4_sb_info *sbi)
9116 ++static int ext4_has_free_blocks(struct super_block *sb)
9117 + {
9118 ++ struct ext4_sb_info *sbi = EXT4_SB(sb);
9119 + ext4_fsblk_t free_blocks, root_blocks;
9120 ++ int cond;
9121 +
9122 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
9123 + root_blocks = ext4_r_blocks_count(sbi->s_es);
9124 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
9125 ++
9126 ++ vxdprintk(VXD_CBIT(dlim, 3),
9127 ++ "ext4_has_free_blocks(%p): free=%llu, root=%llu",
9128 ++ sb, free_blocks, root_blocks);
9129 ++
9130 ++ DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
9131 ++
9132 ++ cond = (free_blocks < root_blocks + 1 &&
9133 ++ !capable(CAP_SYS_RESOURCE) &&
9134 + sbi->s_resuid != current->fsuid &&
9135 +- (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
9136 +- return 0;
9137 +- }
9138 +- return 1;
9139 ++ (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
9140 ++
9141 ++ vxdprintk(VXD_CBIT(dlim, 3),
9142 ++ "ext4_has_free_blocks(%p): %llu<%llu+1, %c, %u!=%u r=%d",
9143 ++ sb, free_blocks, root_blocks,
9144 ++ !capable(CAP_SYS_RESOURCE)?'1':'0',
9145 ++ sbi->s_resuid, current->fsuid, cond?0:1);
9146 ++
9147 ++ return (cond ? 0 : 1);
9148 + }
9149 +
9150 + /**
9151 +@@ -1398,7 +1417,7 @@ static int ext4_has_free_blocks(struct e
9152 + */
9153 + int ext4_should_retry_alloc(struct super_block *sb, int *retries)
9154 + {
9155 +- if (!ext4_has_free_blocks(EXT4_SB(sb)) || (*retries)++ > 3)
9156 ++ if (!ext4_has_free_blocks(sb) || (*retries)++ > 3)
9157 + return 0;
9158 +
9159 + jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
9160 +@@ -1461,6 +1480,8 @@ ext4_fsblk_t ext4_new_blocks(handle_t *h
9161 + *errp = -EDQUOT;
9162 + return 0;
9163 + }
9164 ++ if (DLIMIT_ALLOC_BLOCK(inode, num))
9165 ++ goto out_dlimit;
9166 +
9167 + sbi = EXT4_SB(sb);
9168 + es = EXT4_SB(sb)->s_es;
9169 +@@ -1477,7 +1498,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *h
9170 + if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0))
9171 + my_rsv = &block_i->rsv_window_node;
9172 +
9173 +- if (!ext4_has_free_blocks(sbi)) {
9174 ++ if (!ext4_has_free_blocks(sb)) {
9175 + *errp = -ENOSPC;
9176 + goto out;
9177 + }
9178 +@@ -1661,12 +1682,16 @@ allocated:
9179 + *errp = 0;
9180 + brelse(bitmap_bh);
9181 + DQUOT_FREE_BLOCK(inode, *count-num);
9182 ++ DLIMIT_FREE_BLOCK(inode, *count-num);
9183 + *count = num;
9184 + return ret_block;
9185 +
9186 + io_error:
9187 + *errp = -EIO;
9188 + out:
9189 ++ if (!performed_allocation)
9190 ++ DLIMIT_FREE_BLOCK(inode, *count);
9191 ++out_dlimit:
9192 + if (fatal) {
9193 + *errp = fatal;
9194 + ext4_std_error(sb, fatal);
9195 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/file.c linux-2.6.22.19-vs2.3.0.34/fs/ext4/file.c
9196 +--- linux-2.6.22.19/fs/ext4/file.c 2007-05-02 19:25:17 +0200
9197 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext4/file.c 2007-09-12 20:04:16 +0200
9198 +@@ -135,5 +135,6 @@ const struct inode_operations ext4_file_
9199 + .removexattr = generic_removexattr,
9200 + #endif
9201 + .permission = ext4_permission,
9202 ++ .sync_flags = ext4_sync_flags,
9203 + };
9204 +
9205 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/ialloc.c linux-2.6.22.19-vs2.3.0.34/fs/ext4/ialloc.c
9206 +--- linux-2.6.22.19/fs/ext4/ialloc.c 2006-11-30 21:19:20 +0100
9207 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext4/ialloc.c 2007-08-05 20:53:12 +0200
9208 +@@ -24,6 +24,8 @@
9209 + #include <linux/random.h>
9210 + #include <linux/bitops.h>
9211 + #include <linux/blkdev.h>
9212 ++#include <linux/vs_dlimit.h>
9213 ++#include <linux/vs_tag.h>
9214 + #include <asm/byteorder.h>
9215 +
9216 + #include "xattr.h"
9217 +@@ -127,6 +129,7 @@ void ext4_free_inode (handle_t *handle,
9218 + ext4_xattr_delete_inode(handle, inode);
9219 + DQUOT_FREE_INODE(inode);
9220 + DQUOT_DROP(inode);
9221 ++ DLIMIT_FREE_INODE(inode);
9222 +
9223 + is_directory = S_ISDIR(inode->i_mode);
9224 +
9225 +@@ -448,6 +451,12 @@ struct inode *ext4_new_inode(handle_t *h
9226 + inode = new_inode(sb);
9227 + if (!inode)
9228 + return ERR_PTR(-ENOMEM);
9229 ++
9230 ++ inode->i_tag = dx_current_fstag(sb);
9231 ++ if (DLIMIT_ALLOC_INODE(inode)) {
9232 ++ err = -ENOSPC;
9233 ++ goto out_dlimit;
9234 ++ }
9235 + ei = EXT4_I(inode);
9236 +
9237 + sbi = EXT4_SB(sb);
9238 +@@ -569,7 +578,8 @@ got:
9239 + ei->i_dir_start_lookup = 0;
9240 + ei->i_disksize = 0;
9241 +
9242 +- ei->i_flags = EXT4_I(dir)->i_flags & ~EXT4_INDEX_FL;
9243 ++ ei->i_flags = EXT4_I(dir)->i_flags &
9244 ++ ~(EXT4_INDEX_FL|EXT4_IUNLINK_FL|EXT4_BARRIER_FL);
9245 + if (S_ISLNK(mode))
9246 + ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL);
9247 + /* dirsync only applies to directories */
9248 +@@ -635,6 +645,8 @@ got:
9249 + fail:
9250 + ext4_std_error(sb, err);
9251 + out:
9252 ++ DLIMIT_FREE_INODE(inode);
9253 ++out_dlimit:
9254 + iput(inode);
9255 + ret = ERR_PTR(err);
9256 + really_out:
9257 +@@ -646,6 +658,7 @@ fail_free_drop:
9258 +
9259 + fail_drop:
9260 + DQUOT_DROP(inode);
9261 ++ DLIMIT_FREE_INODE(inode);
9262 + inode->i_flags |= S_NOQUOTA;
9263 + inode->i_nlink = 0;
9264 + iput(inode);
9265 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/inode.c linux-2.6.22.19-vs2.3.0.34/fs/ext4/inode.c
9266 +--- linux-2.6.22.19/fs/ext4/inode.c 2007-07-09 13:19:23 +0200
9267 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext4/inode.c 2007-08-18 02:52:34 +0200
9268 +@@ -36,6 +36,7 @@
9269 + #include <linux/mpage.h>
9270 + #include <linux/uio.h>
9271 + #include <linux/bio.h>
9272 ++#include <linux/vs_tag.h>
9273 + #include "xattr.h"
9274 + #include "acl.h"
9275 +
9276 +@@ -2244,7 +2245,7 @@ void ext4_truncate(struct inode *inode)
9277 + return;
9278 + if (ext4_inode_is_fast_symlink(inode))
9279 + return;
9280 +- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
9281 ++ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
9282 + return;
9283 +
9284 + /*
9285 +@@ -2570,19 +2571,65 @@ void ext4_set_inode_flags(struct inode *
9286 + {
9287 + unsigned int flags = EXT4_I(inode)->i_flags;
9288 +
9289 +- inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
9290 ++ inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
9291 ++ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
9292 ++
9293 ++ if (flags & EXT4_IMMUTABLE_FL)
9294 ++ inode->i_flags |= S_IMMUTABLE;
9295 ++ if (flags & EXT4_IUNLINK_FL)
9296 ++ inode->i_flags |= S_IUNLINK;
9297 ++ if (flags & EXT4_BARRIER_FL)
9298 ++ inode->i_flags |= S_BARRIER;
9299 ++
9300 + if (flags & EXT4_SYNC_FL)
9301 + inode->i_flags |= S_SYNC;
9302 + if (flags & EXT4_APPEND_FL)
9303 + inode->i_flags |= S_APPEND;
9304 +- if (flags & EXT4_IMMUTABLE_FL)
9305 +- inode->i_flags |= S_IMMUTABLE;
9306 + if (flags & EXT4_NOATIME_FL)
9307 + inode->i_flags |= S_NOATIME;
9308 + if (flags & EXT4_DIRSYNC_FL)
9309 + inode->i_flags |= S_DIRSYNC;
9310 + }
9311 +
9312 ++int ext4_sync_flags(struct inode *inode)
9313 ++{
9314 ++ unsigned int oldflags, newflags;
9315 ++ int err = 0;
9316 ++
9317 ++ oldflags = EXT4_I(inode)->i_flags;
9318 ++ newflags = oldflags & ~(EXT4_IMMUTABLE_FL |
9319 ++ EXT4_IUNLINK_FL | EXT4_BARRIER_FL);
9320 ++
9321 ++ if (IS_IMMUTABLE(inode))
9322 ++ newflags |= EXT4_IMMUTABLE_FL;
9323 ++ if (IS_IUNLINK(inode))
9324 ++ newflags |= EXT4_IUNLINK_FL;
9325 ++ if (IS_BARRIER(inode))
9326 ++ newflags |= EXT4_BARRIER_FL;
9327 ++
9328 ++ if (oldflags ^ newflags) {
9329 ++ handle_t *handle;
9330 ++ struct ext4_iloc iloc;
9331 ++
9332 ++ handle = ext4_journal_start(inode, 1);
9333 ++ if (IS_ERR(handle))
9334 ++ return PTR_ERR(handle);
9335 ++ if (IS_SYNC(inode))
9336 ++ handle->h_sync = 1;
9337 ++ err = ext4_reserve_inode_write(handle, inode, &iloc);
9338 ++ if (err)
9339 ++ goto flags_err;
9340 ++
9341 ++ EXT4_I(inode)->i_flags = newflags;
9342 ++ inode->i_ctime = CURRENT_TIME;
9343 ++
9344 ++ err = ext4_mark_iloc_dirty(handle, inode, &iloc);
9345 ++ flags_err:
9346 ++ ext4_journal_stop(handle);
9347 ++ }
9348 ++ return err;
9349 ++}
9350 ++
9351 + void ext4_read_inode(struct inode * inode)
9352 + {
9353 + struct ext4_iloc iloc;
9354 +@@ -2590,6 +2637,8 @@ void ext4_read_inode(struct inode * inod
9355 + struct ext4_inode_info *ei = EXT4_I(inode);
9356 + struct buffer_head *bh;
9357 + int block;
9358 ++ uid_t uid;
9359 ++ gid_t gid;
9360 +
9361 + #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
9362 + ei->i_acl = EXT4_ACL_NOT_CACHED;
9363 +@@ -2602,12 +2651,17 @@ void ext4_read_inode(struct inode * inod
9364 + bh = iloc.bh;
9365 + raw_inode = ext4_raw_inode(&iloc);
9366 + inode->i_mode = le16_to_cpu(raw_inode->i_mode);
9367 +- inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
9368 +- inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
9369 ++ uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
9370 ++ gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
9371 + if(!(test_opt (inode->i_sb, NO_UID32))) {
9372 +- inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
9373 +- inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
9374 ++ uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
9375 ++ gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
9376 + }
9377 ++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
9378 ++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
9379 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
9380 ++ le16_to_cpu(raw_inode->i_raw_tag));
9381 ++
9382 + inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
9383 + inode->i_size = le32_to_cpu(raw_inode->i_size);
9384 + inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
9385 +@@ -2737,6 +2791,8 @@ static int ext4_do_update_inode(handle_t
9386 + struct ext4_inode *raw_inode = ext4_raw_inode(iloc);
9387 + struct ext4_inode_info *ei = EXT4_I(inode);
9388 + struct buffer_head *bh = iloc->bh;
9389 ++ uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
9390 ++ gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
9391 + int err = 0, rc, block;
9392 +
9393 + /* For fields not not tracking in the in-memory inode,
9394 +@@ -2746,29 +2802,32 @@ static int ext4_do_update_inode(handle_t
9395 +
9396 + raw_inode->i_mode = cpu_to_le16(inode->i_mode);
9397 + if(!(test_opt(inode->i_sb, NO_UID32))) {
9398 +- raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
9399 +- raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid));
9400 ++ raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid));
9401 ++ raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid));
9402 + /*
9403 + * Fix up interoperability with old kernels. Otherwise, old inodes get
9404 + * re-used with the upper 16 bits of the uid/gid intact
9405 + */
9406 + if(!ei->i_dtime) {
9407 + raw_inode->i_uid_high =
9408 +- cpu_to_le16(high_16_bits(inode->i_uid));
9409 ++ cpu_to_le16(high_16_bits(uid));
9410 + raw_inode->i_gid_high =
9411 +- cpu_to_le16(high_16_bits(inode->i_gid));
9412 ++ cpu_to_le16(high_16_bits(gid));
9413 + } else {
9414 + raw_inode->i_uid_high = 0;
9415 + raw_inode->i_gid_high = 0;
9416 + }
9417 + } else {
9418 + raw_inode->i_uid_low =
9419 +- cpu_to_le16(fs_high2lowuid(inode->i_uid));
9420 ++ cpu_to_le16(fs_high2lowuid(uid));
9421 + raw_inode->i_gid_low =
9422 +- cpu_to_le16(fs_high2lowgid(inode->i_gid));
9423 ++ cpu_to_le16(fs_high2lowgid(gid));
9424 + raw_inode->i_uid_high = 0;
9425 + raw_inode->i_gid_high = 0;
9426 + }
9427 ++#ifdef CONFIG_TAGGING_INTERN
9428 ++ raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag);
9429 ++#endif
9430 + raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
9431 + raw_inode->i_size = cpu_to_le32(ei->i_disksize);
9432 + raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
9433 +@@ -2925,7 +2984,8 @@ int ext4_setattr(struct dentry *dentry,
9434 + return error;
9435 +
9436 + if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
9437 +- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
9438 ++ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
9439 ++ (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) {
9440 + handle_t *handle;
9441 +
9442 + /* (user+group)*(old+new) structure, inode write (sb,
9443 +@@ -2947,6 +3007,8 @@ int ext4_setattr(struct dentry *dentry,
9444 + inode->i_uid = attr->ia_uid;
9445 + if (attr->ia_valid & ATTR_GID)
9446 + inode->i_gid = attr->ia_gid;
9447 ++ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
9448 ++ inode->i_tag = attr->ia_tag;
9449 + error = ext4_mark_inode_dirty(handle, inode);
9450 + ext4_journal_stop(handle);
9451 + }
9452 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/ioctl.c linux-2.6.22.19-vs2.3.0.34/fs/ext4/ioctl.c
9453 +--- linux-2.6.22.19/fs/ext4/ioctl.c 2007-02-06 03:01:18 +0100
9454 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext4/ioctl.c 2007-08-05 20:53:12 +0200
9455 +@@ -8,6 +8,7 @@
9456 + */
9457 +
9458 + #include <linux/fs.h>
9459 ++#include <linux/mount.h>
9460 + #include <linux/jbd2.h>
9461 + #include <linux/capability.h>
9462 + #include <linux/ext4_fs.h>
9463 +@@ -15,6 +16,7 @@
9464 + #include <linux/time.h>
9465 + #include <linux/compat.h>
9466 + #include <linux/smp_lock.h>
9467 ++#include <linux/vs_tag.h>
9468 + #include <asm/uaccess.h>
9469 +
9470 + int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
9471 +@@ -37,7 +39,8 @@ int ext4_ioctl (struct inode * inode, st
9472 + unsigned int oldflags;
9473 + unsigned int jflag;
9474 +
9475 +- if (IS_RDONLY(inode))
9476 ++ if (IS_RDONLY(inode) ||
9477 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
9478 + return -EROFS;
9479 +
9480 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
9481 +@@ -61,7 +64,9 @@ int ext4_ioctl (struct inode * inode, st
9482 + *
9483 + * This test looks nicer. Thanks to Pauline Middelink
9484 + */
9485 +- if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
9486 ++ if ((oldflags & EXT4_IMMUTABLE_FL) ||
9487 ++ ((flags ^ oldflags) & (EXT4_APPEND_FL |
9488 ++ EXT4_IMMUTABLE_FL | EXT4_IUNLINK_FL))) {
9489 + if (!capable(CAP_LINUX_IMMUTABLE)) {
9490 + mutex_unlock(&inode->i_mutex);
9491 + return -EPERM;
9492 +@@ -123,7 +128,8 @@ flags_err:
9493 +
9494 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
9495 + return -EPERM;
9496 +- if (IS_RDONLY(inode))
9497 ++ if (IS_RDONLY(inode) ||
9498 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
9499 + return -EROFS;
9500 + if (get_user(generation, (int __user *) arg))
9501 + return -EFAULT;
9502 +@@ -177,7 +183,8 @@ flags_err:
9503 + if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
9504 + return -ENOTTY;
9505 +
9506 +- if (IS_RDONLY(inode))
9507 ++ if (IS_RDONLY(inode) ||
9508 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
9509 + return -EROFS;
9510 +
9511 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
9512 +@@ -212,7 +219,8 @@ flags_err:
9513 + if (!capable(CAP_SYS_RESOURCE))
9514 + return -EPERM;
9515 +
9516 +- if (IS_RDONLY(inode))
9517 ++ if (IS_RDONLY(inode) ||
9518 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
9519 + return -EROFS;
9520 +
9521 + if (get_user(n_blocks_count, (__u32 __user *)arg))
9522 +@@ -233,7 +241,8 @@ flags_err:
9523 + if (!capable(CAP_SYS_RESOURCE))
9524 + return -EPERM;
9525 +
9526 +- if (IS_RDONLY(inode))
9527 ++ if (IS_RDONLY(inode) ||
9528 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
9529 + return -EROFS;
9530 +
9531 + if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg,
9532 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/namei.c linux-2.6.22.19-vs2.3.0.34/fs/ext4/namei.c
9533 +--- linux-2.6.22.19/fs/ext4/namei.c 2008-03-14 20:19:03 +0100
9534 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext4/namei.c 2007-09-30 14:58:01 +0200
9535 +@@ -36,6 +36,7 @@
9536 + #include <linux/quotaops.h>
9537 + #include <linux/buffer_head.h>
9538 + #include <linux/bio.h>
9539 ++#include <linux/vs_tag.h>
9540 +
9541 + #include "namei.h"
9542 + #include "xattr.h"
9543 +@@ -1050,6 +1051,7 @@ static struct dentry *ext4_lookup(struct
9544 +
9545 + if (!inode)
9546 + return ERR_PTR(-EACCES);
9547 ++ dx_propagate_tag(nd, inode);
9548 + }
9549 + return d_splice_alias(inode, dentry);
9550 + }
9551 +@@ -2441,6 +2443,7 @@ const struct inode_operations ext4_dir_i
9552 + .removexattr = generic_removexattr,
9553 + #endif
9554 + .permission = ext4_permission,
9555 ++ .sync_flags = ext4_sync_flags,
9556 + };
9557 +
9558 + const struct inode_operations ext4_special_inode_operations = {
9559 +@@ -2452,4 +2455,5 @@ const struct inode_operations ext4_speci
9560 + .removexattr = generic_removexattr,
9561 + #endif
9562 + .permission = ext4_permission,
9563 ++ .sync_flags = ext4_sync_flags,
9564 + };
9565 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/super.c linux-2.6.22.19-vs2.3.0.34/fs/ext4/super.c
9566 +--- linux-2.6.22.19/fs/ext4/super.c 2007-07-09 13:19:23 +0200
9567 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext4/super.c 2007-08-05 20:53:12 +0200
9568 +@@ -725,7 +725,7 @@ enum {
9569 + Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
9570 + Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
9571 + Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
9572 +- Opt_grpquota, Opt_extents,
9573 ++ Opt_grpquota, Opt_extents, Opt_tag, Opt_notag, Opt_tagid
9574 + };
9575 +
9576 + static match_table_t tokens = {
9577 +@@ -776,6 +776,9 @@ static match_table_t tokens = {
9578 + {Opt_usrquota, "usrquota"},
9579 + {Opt_barrier, "barrier=%u"},
9580 + {Opt_extents, "extents"},
9581 ++ {Opt_tag, "tag"},
9582 ++ {Opt_notag, "notag"},
9583 ++ {Opt_tagid, "tagid=%u"},
9584 + {Opt_err, NULL},
9585 + {Opt_resize, "resize"},
9586 + };
9587 +@@ -869,6 +872,20 @@ static int parse_options (char *options,
9588 + case Opt_nouid32:
9589 + set_opt (sbi->s_mount_opt, NO_UID32);
9590 + break;
9591 ++#ifndef CONFIG_TAGGING_NONE
9592 ++ case Opt_tag:
9593 ++ set_opt (sbi->s_mount_opt, TAGGED);
9594 ++ break;
9595 ++ case Opt_notag:
9596 ++ clear_opt (sbi->s_mount_opt, TAGGED);
9597 ++ break;
9598 ++#endif
9599 ++#ifdef CONFIG_PROPAGATE
9600 ++ case Opt_tagid:
9601 ++ /* use args[0] */
9602 ++ set_opt (sbi->s_mount_opt, TAGGED);
9603 ++ break;
9604 ++#endif
9605 + case Opt_nocheck:
9606 + clear_opt (sbi->s_mount_opt, CHECK);
9607 + break;
9608 +@@ -1546,6 +1563,9 @@ static int ext4_fill_super (struct super
9609 + NULL, 0))
9610 + goto failed_mount;
9611 +
9612 ++ if (EXT4_SB(sb)->s_mount_opt & EXT4_MOUNT_TAGGED)
9613 ++ sb->s_flags |= MS_TAGGED;
9614 ++
9615 + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
9616 + ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
9617 +
9618 +@@ -2377,6 +2397,12 @@ static int ext4_remount (struct super_bl
9619 +
9620 + if (sbi->s_mount_opt & EXT4_MOUNT_ABORT)
9621 + ext4_abort(sb, __FUNCTION__, "Abort forced by user");
9622 ++ if ((sbi->s_mount_opt & EXT4_MOUNT_TAGGED) &&
9623 ++ !(sb->s_flags & MS_TAGGED)) {
9624 ++ printk("EXT4-fs: %s: tagging not permitted on remount.\n",
9625 ++ sb->s_id);
9626 ++ return -EINVAL;
9627 ++ }
9628 +
9629 + sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
9630 + ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
9631 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/symlink.c linux-2.6.22.19-vs2.3.0.34/fs/ext4/symlink.c
9632 +--- linux-2.6.22.19/fs/ext4/symlink.c 2007-05-02 19:25:17 +0200
9633 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext4/symlink.c 2007-08-05 20:53:12 +0200
9634 +@@ -40,6 +40,7 @@ const struct inode_operations ext4_symli
9635 + .listxattr = ext4_listxattr,
9636 + .removexattr = generic_removexattr,
9637 + #endif
9638 ++ .sync_flags = ext4_sync_flags,
9639 + };
9640 +
9641 + const struct inode_operations ext4_fast_symlink_inode_operations = {
9642 +@@ -51,4 +52,5 @@ const struct inode_operations ext4_fast_
9643 + .listxattr = ext4_listxattr,
9644 + .removexattr = generic_removexattr,
9645 + #endif
9646 ++ .sync_flags = ext4_sync_flags,
9647 + };
9648 +diff -NurpP --minimal linux-2.6.22.19/fs/ext4/xattr.c linux-2.6.22.19-vs2.3.0.34/fs/ext4/xattr.c
9649 +--- linux-2.6.22.19/fs/ext4/xattr.c 2007-05-02 19:25:17 +0200
9650 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ext4/xattr.c 2007-08-05 20:53:12 +0200
9651 +@@ -58,6 +58,7 @@
9652 + #include <linux/mbcache.h>
9653 + #include <linux/quotaops.h>
9654 + #include <linux/rwsem.h>
9655 ++#include <linux/vs_dlimit.h>
9656 + #include "xattr.h"
9657 + #include "acl.h"
9658 +
9659 +@@ -496,6 +497,7 @@ ext4_xattr_release_block(handle_t *handl
9660 + error = ext4_journal_dirty_metadata(handle, bh);
9661 + if (IS_SYNC(inode))
9662 + handle->h_sync = 1;
9663 ++ DLIMIT_FREE_BLOCK(inode, 1);
9664 + DQUOT_FREE_BLOCK(inode, 1);
9665 + ea_bdebug(bh, "refcount now=%d; releasing",
9666 + le32_to_cpu(BHDR(bh)->h_refcount));
9667 +@@ -769,11 +771,14 @@ inserted:
9668 + if (new_bh == bs->bh)
9669 + ea_bdebug(new_bh, "keeping");
9670 + else {
9671 ++ error = -ENOSPC;
9672 ++ if (DLIMIT_ALLOC_BLOCK(inode, 1))
9673 ++ goto cleanup;
9674 + /* The old block is released after updating
9675 + the inode. */
9676 + error = -EDQUOT;
9677 + if (DQUOT_ALLOC_BLOCK(inode, 1))
9678 +- goto cleanup;
9679 ++ goto cleanup_dlimit;
9680 + error = ext4_journal_get_write_access(handle,
9681 + new_bh);
9682 + if (error)
9683 +@@ -850,6 +855,8 @@ cleanup:
9684 +
9685 + cleanup_dquot:
9686 + DQUOT_FREE_BLOCK(inode, 1);
9687 ++cleanup_dlimit:
9688 ++ DLIMIT_FREE_BLOCK(inode, 1);
9689 + goto cleanup;
9690 +
9691 + bad_block:
9692 +diff -NurpP --minimal linux-2.6.22.19/fs/fcntl.c linux-2.6.22.19-vs2.3.0.34/fs/fcntl.c
9693 +--- linux-2.6.22.19/fs/fcntl.c 2007-02-06 03:01:18 +0100
9694 ++++ linux-2.6.22.19-vs2.3.0.34/fs/fcntl.c 2007-08-05 20:53:12 +0200
9695 +@@ -18,6 +18,7 @@
9696 + #include <linux/ptrace.h>
9697 + #include <linux/signal.h>
9698 + #include <linux/rcupdate.h>
9699 ++#include <linux/vs_limit.h>
9700 +
9701 + #include <asm/poll.h>
9702 + #include <asm/siginfo.h>
9703 +@@ -84,6 +85,8 @@ repeat:
9704 + error = -EMFILE;
9705 + if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
9706 + goto out;
9707 ++ if (!vx_files_avail(1))
9708 ++ goto out;
9709 +
9710 + error = expand_files(files, newfd);
9711 + if (error < 0)
9712 +@@ -124,6 +127,7 @@ static int dupfd(struct file *file, unsi
9713 + FD_SET(fd, fdt->open_fds);
9714 + FD_CLR(fd, fdt->close_on_exec);
9715 + spin_unlock(&files->file_lock);
9716 ++ vx_openfd_inc(fd);
9717 + fd_install(fd, file);
9718 + } else {
9719 + spin_unlock(&files->file_lock);
9720 +@@ -176,6 +180,9 @@ asmlinkage long sys_dup2(unsigned int ol
9721 +
9722 + if (tofree)
9723 + filp_close(tofree, files);
9724 ++ else
9725 ++ vx_openfd_inc(newfd); /* fd was unused */
9726 ++
9727 + err = newfd;
9728 + out:
9729 + return err;
9730 +diff -NurpP --minimal linux-2.6.22.19/fs/file_table.c linux-2.6.22.19-vs2.3.0.34/fs/file_table.c
9731 +--- linux-2.6.22.19/fs/file_table.c 2007-07-09 13:19:23 +0200
9732 ++++ linux-2.6.22.19-vs2.3.0.34/fs/file_table.c 2007-08-05 20:53:12 +0200
9733 +@@ -20,6 +20,8 @@
9734 + #include <linux/fsnotify.h>
9735 + #include <linux/sysctl.h>
9736 + #include <linux/percpu_counter.h>
9737 ++#include <linux/vs_limit.h>
9738 ++#include <linux/vs_context.h>
9739 +
9740 + #include <asm/atomic.h>
9741 +
9742 +@@ -119,6 +121,8 @@ struct file *get_empty_filp(void)
9743 + f->f_gid = tsk->fsgid;
9744 + eventpoll_init_file(f);
9745 + /* f->f_version: 0 */
9746 ++ f->f_xid = vx_current_xid();
9747 ++ vx_files_inc(f);
9748 + return f;
9749 +
9750 + over:
9751 +@@ -174,6 +178,8 @@ void fastcall __fput(struct file *file)
9752 + if (file->f_mode & FMODE_WRITE)
9753 + put_write_access(inode);
9754 + put_pid(file->f_owner.pid);
9755 ++ vx_files_dec(file);
9756 ++ file->f_xid = 0;
9757 + file_kill(file);
9758 + file->f_path.dentry = NULL;
9759 + file->f_path.mnt = NULL;
9760 +@@ -239,6 +245,8 @@ void put_filp(struct file *file)
9761 + {
9762 + if (atomic_dec_and_test(&file->f_count)) {
9763 + security_file_free(file);
9764 ++ vx_files_dec(file);
9765 ++ file->f_xid = 0;
9766 + file_kill(file);
9767 + file_free(file);
9768 + }
9769 +diff -NurpP --minimal linux-2.6.22.19/fs/hfsplus/ioctl.c linux-2.6.22.19-vs2.3.0.34/fs/hfsplus/ioctl.c
9770 +--- linux-2.6.22.19/fs/hfsplus/ioctl.c 2006-11-30 21:19:25 +0100
9771 ++++ linux-2.6.22.19-vs2.3.0.34/fs/hfsplus/ioctl.c 2007-08-05 20:53:12 +0200
9772 +@@ -16,6 +16,7 @@
9773 + #include <linux/fs.h>
9774 + #include <linux/sched.h>
9775 + #include <linux/xattr.h>
9776 ++#include <linux/mount.h>
9777 + #include <asm/uaccess.h>
9778 + #include "hfsplus_fs.h"
9779 +
9780 +@@ -35,7 +36,8 @@ int hfsplus_ioctl(struct inode *inode, s
9781 + flags |= FS_NODUMP_FL; /* EXT2_NODUMP_FL */
9782 + return put_user(flags, (int __user *)arg);
9783 + case HFSPLUS_IOC_EXT2_SETFLAGS: {
9784 +- if (IS_RDONLY(inode))
9785 ++ if (IS_RDONLY(inode) ||
9786 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
9787 + return -EROFS;
9788 +
9789 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
9790 +diff -NurpP --minimal linux-2.6.22.19/fs/inode.c linux-2.6.22.19-vs2.3.0.34/fs/inode.c
9791 +--- linux-2.6.22.19/fs/inode.c 2007-07-09 13:19:24 +0200
9792 ++++ linux-2.6.22.19-vs2.3.0.34/fs/inode.c 2007-10-11 01:10:22 +0200
9793 +@@ -115,6 +115,9 @@ static struct inode *alloc_inode(struct
9794 + struct address_space * const mapping = &inode->i_data;
9795 +
9796 + inode->i_sb = sb;
9797 ++
9798 ++ /* essential because of inode slab reuse */
9799 ++ inode->i_tag = 0;
9800 + inode->i_blkbits = sb->s_blocksize_bits;
9801 + inode->i_flags = 0;
9802 + atomic_set(&inode->i_count, 1);
9803 +@@ -133,6 +136,7 @@ static struct inode *alloc_inode(struct
9804 + inode->i_bdev = NULL;
9805 + inode->i_cdev = NULL;
9806 + inode->i_rdev = 0;
9807 ++ inode->i_mdev = 0;
9808 + inode->dirtied_when = 0;
9809 + if (security_inode_alloc(inode)) {
9810 + if (inode->i_sb->s_op->destroy_inode)
9811 +@@ -231,6 +235,8 @@ void __iget(struct inode * inode)
9812 + inodes_stat.nr_unused--;
9813 + }
9814 +
9815 ++EXPORT_SYMBOL_GPL(__iget);
9816 ++
9817 + /**
9818 + * clear_inode - clear an inode
9819 + * @inode: inode to clear
9820 +@@ -1405,9 +1411,11 @@ void init_special_inode(struct inode *in
9821 + if (S_ISCHR(mode)) {
9822 + inode->i_fop = &def_chr_fops;
9823 + inode->i_rdev = rdev;
9824 ++ inode->i_mdev = rdev;
9825 + } else if (S_ISBLK(mode)) {
9826 + inode->i_fop = &def_blk_fops;
9827 + inode->i_rdev = rdev;
9828 ++ inode->i_mdev = rdev;
9829 + } else if (S_ISFIFO(mode))
9830 + inode->i_fop = &def_fifo_fops;
9831 + else if (S_ISSOCK(mode))
9832 +diff -NurpP --minimal linux-2.6.22.19/fs/ioctl.c linux-2.6.22.19-vs2.3.0.34/fs/ioctl.c
9833 +--- linux-2.6.22.19/fs/ioctl.c 2007-07-09 13:19:24 +0200
9834 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ioctl.c 2007-08-05 20:53:12 +0200
9835 +@@ -13,6 +13,9 @@
9836 + #include <linux/security.h>
9837 + #include <linux/module.h>
9838 + #include <linux/kallsyms.h>
9839 ++#include <linux/proc_fs.h>
9840 ++#include <linux/vserver/inode.h>
9841 ++#include <linux/vs_tag.h>
9842 +
9843 + #include <asm/uaccess.h>
9844 + #include <asm/ioctls.h>
9845 +diff -NurpP --minimal linux-2.6.22.19/fs/ioprio.c linux-2.6.22.19-vs2.3.0.34/fs/ioprio.c
9846 +--- linux-2.6.22.19/fs/ioprio.c 2007-05-02 19:25:18 +0200
9847 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ioprio.c 2007-08-05 20:53:12 +0200
9848 +@@ -25,6 +25,7 @@
9849 + #include <linux/capability.h>
9850 + #include <linux/syscalls.h>
9851 + #include <linux/security.h>
9852 ++#include <linux/vs_base.h>
9853 +
9854 + static int set_task_ioprio(struct task_struct *task, int ioprio)
9855 + {
9856 +@@ -103,6 +104,8 @@ asmlinkage long sys_ioprio_set(int which
9857 + else
9858 + pgrp = find_pid(who);
9859 + do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
9860 ++ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
9861 ++ continue;
9862 + ret = set_task_ioprio(p, ioprio);
9863 + if (ret)
9864 + break;
9865 +@@ -112,7 +115,7 @@ asmlinkage long sys_ioprio_set(int which
9866 + if (!who)
9867 + user = current->user;
9868 + else
9869 +- user = find_user(who);
9870 ++ user = find_user(vx_current_xid(), who);
9871 +
9872 + if (!user)
9873 + break;
9874 +@@ -190,6 +193,8 @@ asmlinkage long sys_ioprio_get(int which
9875 + else
9876 + pgrp = find_pid(who);
9877 + do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
9878 ++ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
9879 ++ continue;
9880 + tmpio = get_task_ioprio(p);
9881 + if (tmpio < 0)
9882 + continue;
9883 +@@ -203,7 +208,7 @@ asmlinkage long sys_ioprio_get(int which
9884 + if (!who)
9885 + user = current->user;
9886 + else
9887 +- user = find_user(who);
9888 ++ user = find_user(vx_current_xid(), who);
9889 +
9890 + if (!user)
9891 + break;
9892 +diff -NurpP --minimal linux-2.6.22.19/fs/jffs2/dir.c linux-2.6.22.19-vs2.3.0.34/fs/jffs2/dir.c
9893 +--- linux-2.6.22.19/fs/jffs2/dir.c 2007-07-09 13:19:26 +0200
9894 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jffs2/dir.c 2007-10-05 15:07:22 +0200
9895 +@@ -32,7 +32,9 @@ static int jffs2_mkdir (struct inode *,s
9896 + static int jffs2_rmdir (struct inode *,struct dentry *);
9897 + static int jffs2_mknod (struct inode *,struct dentry *,int,dev_t);
9898 + static int jffs2_rename (struct inode *, struct dentry *,
9899 +- struct inode *, struct dentry *);
9900 ++ struct inode *, struct dentry *);
9901 ++
9902 ++extern int jffs2_sync_flags(struct inode *);
9903 +
9904 + const struct file_operations jffs2_dir_operations =
9905 + {
9906 +@@ -56,6 +58,7 @@ const struct inode_operations jffs2_dir_
9907 + .rename = jffs2_rename,
9908 + .permission = jffs2_permission,
9909 + .setattr = jffs2_setattr,
9910 ++ .sync_flags = jffs2_sync_flags,
9911 + .setxattr = jffs2_setxattr,
9912 + .getxattr = jffs2_getxattr,
9913 + .listxattr = jffs2_listxattr,
9914 +diff -NurpP --minimal linux-2.6.22.19/fs/jffs2/file.c linux-2.6.22.19-vs2.3.0.34/fs/jffs2/file.c
9915 +--- linux-2.6.22.19/fs/jffs2/file.c 2007-07-09 13:19:26 +0200
9916 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jffs2/file.c 2007-10-01 20:52:25 +0200
9917 +@@ -17,6 +17,7 @@
9918 + #include <linux/highmem.h>
9919 + #include <linux/crc32.h>
9920 + #include <linux/jffs2.h>
9921 ++#include <linux/vs_tag.h>
9922 + #include "nodelist.h"
9923 +
9924 + static int jffs2_commit_write (struct file *filp, struct page *pg,
9925 +@@ -25,6 +26,9 @@ static int jffs2_prepare_write (struct f
9926 + unsigned start, unsigned end);
9927 + static int jffs2_readpage (struct file *filp, struct page *pg);
9928 +
9929 ++extern int jffs2_sync_flags(struct inode *);
9930 ++
9931 ++
9932 + int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync)
9933 + {
9934 + struct inode *inode = dentry->d_inode;
9935 +@@ -47,7 +51,9 @@ const struct file_operations jffs2_file_
9936 + .ioctl = jffs2_ioctl,
9937 + .mmap = generic_file_readonly_mmap,
9938 + .fsync = jffs2_fsync,
9939 +- .sendfile = generic_file_sendfile
9940 ++ .sendfile = generic_file_sendfile,
9941 ++ .splice_read = generic_file_splice_read,
9942 ++ .splice_write = generic_file_splice_write
9943 + };
9944 +
9945 + /* jffs2_file_inode_operations */
9946 +@@ -56,6 +62,7 @@ const struct inode_operations jffs2_file
9947 + {
9948 + .permission = jffs2_permission,
9949 + .setattr = jffs2_setattr,
9950 ++ .sync_flags = jffs2_sync_flags,
9951 + .setxattr = jffs2_setxattr,
9952 + .getxattr = jffs2_getxattr,
9953 + .listxattr = jffs2_listxattr,
9954 +@@ -157,12 +164,14 @@ static int jffs2_prepare_write (struct f
9955 + ri.mode = cpu_to_jemode(inode->i_mode);
9956 + ri.uid = cpu_to_je16(inode->i_uid);
9957 + ri.gid = cpu_to_je16(inode->i_gid);
9958 ++ ri.tag = cpu_to_je16(TAGINO_TAG(DX_TAG(inode), inode->i_tag));
9959 + ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs));
9960 + ri.atime = ri.ctime = ri.mtime = cpu_to_je32(get_seconds());
9961 + ri.offset = cpu_to_je32(inode->i_size);
9962 + ri.dsize = cpu_to_je32(pageofs - inode->i_size);
9963 + ri.csize = cpu_to_je32(0);
9964 + ri.compr = JFFS2_COMPR_ZERO;
9965 ++ ri.flags = cpu_to_je16(f->flags);
9966 + ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
9967 + ri.data_crc = cpu_to_je32(0);
9968 +
9969 +@@ -248,8 +257,10 @@ static int jffs2_commit_write (struct fi
9970 + ri->mode = cpu_to_jemode(inode->i_mode);
9971 + ri->uid = cpu_to_je16(inode->i_uid);
9972 + ri->gid = cpu_to_je16(inode->i_gid);
9973 ++ ri->tag = cpu_to_je16(TAGINO_TAG(DX_TAG(inode), inode->i_tag));
9974 + ri->isize = cpu_to_je32((uint32_t)inode->i_size);
9975 + ri->atime = ri->ctime = ri->mtime = cpu_to_je32(get_seconds());
9976 ++ ri->flags = cpu_to_je16(f->flags);
9977 +
9978 + /* In 2.4, it was already kmapped by generic_file_write(). Doesn't
9979 + hurt to do it again. The alternative is ifdefs, which are ugly. */
9980 +diff -NurpP --minimal linux-2.6.22.19/fs/jffs2/fs.c linux-2.6.22.19-vs2.3.0.34/fs/jffs2/fs.c
9981 +--- linux-2.6.22.19/fs/jffs2/fs.c 2008-03-14 20:19:03 +0100
9982 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jffs2/fs.c 2007-09-30 14:58:01 +0200
9983 +@@ -20,6 +20,7 @@
9984 + #include <linux/vmalloc.h>
9985 + #include <linux/vfs.h>
9986 + #include <linux/crc32.h>
9987 ++#include <linux/vs_tag.h>
9988 + #include "nodelist.h"
9989 +
9990 + static int jffs2_flash_setup(struct jffs2_sb_info *c);
9991 +@@ -97,6 +98,7 @@ static int jffs2_do_setattr (struct inod
9992 +
9993 + ri->uid = cpu_to_je16((ivalid & ATTR_UID)?iattr->ia_uid:inode->i_uid);
9994 + ri->gid = cpu_to_je16((ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid);
9995 ++ ri->tag = cpu_to_je16((ivalid & ATTR_TAG)?iattr->ia_tag:inode->i_tag);
9996 +
9997 + if (ivalid & ATTR_MODE)
9998 + if (iattr->ia_mode & S_ISGID &&
9999 +@@ -116,6 +118,8 @@ static int jffs2_do_setattr (struct inod
10000 + ri->offset = cpu_to_je32(0);
10001 + ri->csize = ri->dsize = cpu_to_je32(mdatalen);
10002 + ri->compr = JFFS2_COMPR_NONE;
10003 ++ ri->flags = cpu_to_je16(f->flags);
10004 ++
10005 + if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
10006 + /* It's an extension. Make it a hole node */
10007 + ri->compr = JFFS2_COMPR_ZERO;
10008 +@@ -145,6 +149,7 @@ static int jffs2_do_setattr (struct inod
10009 + inode->i_mode = jemode_to_cpu(ri->mode);
10010 + inode->i_uid = je16_to_cpu(ri->uid);
10011 + inode->i_gid = je16_to_cpu(ri->gid);
10012 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), 0, 0, je16_to_cpu(ri->tag));
10013 +
10014 +
10015 + old_metadata = f->metadata;
10016 +@@ -179,6 +184,48 @@ static int jffs2_do_setattr (struct inod
10017 + return 0;
10018 + }
10019 +
10020 ++void jffs2_set_inode_flags(struct inode *inode)
10021 ++{
10022 ++ struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
10023 ++ unsigned int flags = f->flags;
10024 ++
10025 ++ inode->i_flags &= ~(JFFS2_INO_FLAG_IMMUTABLE |
10026 ++ JFFS2_INO_FLAG_IUNLINK | JFFS2_INO_FLAG_BARRIER);
10027 ++
10028 ++ if (flags & JFFS2_INO_FLAG_IMMUTABLE)
10029 ++ inode->i_flags |= S_IMMUTABLE;
10030 ++ if (flags & JFFS2_INO_FLAG_IUNLINK)
10031 ++ inode->i_flags |= S_IUNLINK;
10032 ++ if (flags & JFFS2_INO_FLAG_BARRIER)
10033 ++ inode->i_flags |= S_BARRIER;
10034 ++}
10035 ++
10036 ++int jffs2_sync_flags(struct inode *inode)
10037 ++{
10038 ++ struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
10039 ++ unsigned int oldflags, newflags;
10040 ++
10041 ++ oldflags = f->flags;
10042 ++ newflags = oldflags & ~(JFFS2_INO_FLAG_IMMUTABLE |
10043 ++ JFFS2_INO_FLAG_IUNLINK | JFFS2_INO_FLAG_BARRIER);
10044 ++
10045 ++ if (IS_IMMUTABLE(inode))
10046 ++ newflags |= JFFS2_INO_FLAG_IMMUTABLE;
10047 ++ if (IS_IUNLINK(inode))
10048 ++ newflags |= JFFS2_INO_FLAG_IUNLINK;
10049 ++ if (IS_BARRIER(inode))
10050 ++ newflags |= JFFS2_INO_FLAG_BARRIER;
10051 ++
10052 ++ if (oldflags ^ newflags) {
10053 ++ f->flags = newflags;
10054 ++ inode->i_ctime = CURRENT_TIME;
10055 ++ /* strange requirement, see jffs2_dirty_inode() */
10056 ++ inode->i_state |= I_DIRTY_DATASYNC;
10057 ++ mark_inode_dirty(inode);
10058 ++ }
10059 ++ return 0;
10060 ++}
10061 ++
10062 + int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
10063 + {
10064 + int rc;
10065 +@@ -254,6 +301,8 @@ void jffs2_read_inode (struct inode *ino
10066 + inode->i_mode = jemode_to_cpu(latest_node.mode);
10067 + inode->i_uid = je16_to_cpu(latest_node.uid);
10068 + inode->i_gid = je16_to_cpu(latest_node.gid);
10069 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), 0, 0,
10070 ++ je16_to_cpu(latest_node.tag));
10071 + inode->i_size = je32_to_cpu(latest_node.isize);
10072 + inode->i_atime = ITIME(je32_to_cpu(latest_node.atime));
10073 + inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime));
10074 +@@ -285,6 +334,7 @@ void jffs2_read_inode (struct inode *ino
10075 +
10076 + inode->i_op = &jffs2_dir_inode_operations;
10077 + inode->i_fop = &jffs2_dir_operations;
10078 ++ f->flags = je16_to_cpu(latest_node.flags);
10079 + break;
10080 + }
10081 + case S_IFREG:
10082 +@@ -292,6 +342,7 @@ void jffs2_read_inode (struct inode *ino
10083 + inode->i_fop = &jffs2_file_operations;
10084 + inode->i_mapping->a_ops = &jffs2_file_address_operations;
10085 + inode->i_mapping->nrpages = 0;
10086 ++ f->flags = je16_to_cpu(latest_node.flags);
10087 + break;
10088 +
10089 + case S_IFBLK:
10090 +@@ -328,7 +379,7 @@ void jffs2_read_inode (struct inode *ino
10091 + default:
10092 + printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino);
10093 + }
10094 +-
10095 ++ jffs2_set_inode_flags(inode);
10096 + up(&f->sem);
10097 +
10098 + D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
10099 +@@ -345,10 +396,11 @@ void jffs2_dirty_inode(struct inode *ino
10100 +
10101 + D1(printk(KERN_DEBUG "jffs2_dirty_inode() calling setattr() for ino #%lu\n", inode->i_ino));
10102 +
10103 +- iattr.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME;
10104 ++ iattr.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME|ATTR_TAG;
10105 + iattr.ia_mode = inode->i_mode;
10106 + iattr.ia_uid = inode->i_uid;
10107 + iattr.ia_gid = inode->i_gid;
10108 ++ iattr.ia_tag = inode->i_tag;
10109 + iattr.ia_atime = inode->i_atime;
10110 + iattr.ia_mtime = inode->i_mtime;
10111 + iattr.ia_ctime = inode->i_ctime;
10112 +@@ -422,6 +474,7 @@ struct inode *jffs2_new_inode (struct in
10113 +
10114 + memset(ri, 0, sizeof(*ri));
10115 + /* Set OS-specific defaults for new inodes */
10116 ++ ri->tag = cpu_to_je16(dx_current_tag());
10117 + ri->uid = cpu_to_je16(current->fsuid);
10118 +
10119 + if (dir_i->i_mode & S_ISGID) {
10120 +@@ -443,14 +496,16 @@ struct inode *jffs2_new_inode (struct in
10121 + inode->i_mode = jemode_to_cpu(ri->mode);
10122 + inode->i_gid = je16_to_cpu(ri->gid);
10123 + inode->i_uid = je16_to_cpu(ri->uid);
10124 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), 0, 0, je16_to_cpu(ri->tag));
10125 + inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
10126 + ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode->i_mtime));
10127 +
10128 + inode->i_blocks = 0;
10129 + inode->i_size = 0;
10130 +
10131 ++ f->flags = je16_to_cpu(ri->flags);
10132 ++ jffs2_set_inode_flags(inode);
10133 + insert_inode_hash(inode);
10134 +-
10135 + return inode;
10136 + }
10137 +
10138 +diff -NurpP --minimal linux-2.6.22.19/fs/jffs2/gc.c linux-2.6.22.19-vs2.3.0.34/fs/jffs2/gc.c
10139 +--- linux-2.6.22.19/fs/jffs2/gc.c 2007-07-09 13:19:26 +0200
10140 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jffs2/gc.c 2007-08-05 20:53:12 +0200
10141 +@@ -735,6 +735,7 @@ static int jffs2_garbage_collect_metadat
10142 + ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
10143 + ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
10144 + ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
10145 ++ ri.tag = cpu_to_je16(JFFS2_F_I_TAG(f));
10146 + ri.isize = cpu_to_je32(ilen);
10147 + ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
10148 + ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
10149 +@@ -998,6 +999,7 @@ static int jffs2_garbage_collect_hole(st
10150 + ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
10151 + ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
10152 + ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
10153 ++ ri.tag = cpu_to_je16(JFFS2_F_I_TAG(f));
10154 + ri.isize = cpu_to_je32(ilen);
10155 + ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
10156 + ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
10157 +@@ -1256,6 +1258,7 @@ static int jffs2_garbage_collect_dnode(s
10158 + ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
10159 + ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
10160 + ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
10161 ++ ri.tag = cpu_to_je16(JFFS2_F_I_TAG(f));
10162 + ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f));
10163 + ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
10164 + ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
10165 +diff -NurpP --minimal linux-2.6.22.19/fs/jffs2/ioctl.c linux-2.6.22.19-vs2.3.0.34/fs/jffs2/ioctl.c
10166 +--- linux-2.6.22.19/fs/jffs2/ioctl.c 2007-07-09 13:19:26 +0200
10167 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jffs2/ioctl.c 2007-08-05 20:53:12 +0200
10168 +@@ -10,12 +10,67 @@
10169 + */
10170 +
10171 + #include <linux/fs.h>
10172 ++#include <linux/types.h>
10173 ++#include <linux/mount.h>
10174 ++#include <linux/jffs2.h>
10175 ++#include <linux/uaccess.h>
10176 ++#include <linux/vs_base.h>
10177 ++#include "jffs2_fs_sb.h"
10178 ++#include "jffs2_fs_i.h"
10179 ++#include "acl.h"
10180 ++#include "os-linux.h"
10181 ++
10182 ++extern void jffs2_set_inode_flags(struct inode *);
10183 +
10184 + int jffs2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
10185 + unsigned long arg)
10186 + {
10187 +- /* Later, this will provide for lsattr.jffs2 and chattr.jffs2, which
10188 +- will include compression support etc. */
10189 +- return -ENOTTY;
10190 ++ struct jffs2_inode_info *j = JFFS2_INODE_INFO(inode);
10191 ++ unsigned int flags, oldflags, newflags;
10192 ++
10193 ++ switch (cmd) {
10194 ++ case JFFS2_IOC_GETFLAGS:
10195 ++ flags = j->flags & JFFS2_USER_VISIBLE;
10196 ++ return put_user(flags, (int __user *) arg);
10197 ++
10198 ++ case JFFS2_IOC_SETFLAGS:
10199 ++ if (IS_RDONLY(inode) ||
10200 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
10201 ++ return -EROFS;
10202 ++
10203 ++ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
10204 ++ return -EACCES;
10205 ++
10206 ++ if (get_user(flags, (int __user *) arg))
10207 ++ return -EFAULT;
10208 ++
10209 ++ oldflags = j->flags;
10210 ++ newflags = flags & JFFS2_USER_MODIFIABLE;
10211 ++ newflags |= oldflags & ~JFFS2_USER_MODIFIABLE;
10212 ++
10213 ++ /*
10214 ++ * The IMMUTABLE flags can only be changed by
10215 ++ * the relevant capability.
10216 ++ */
10217 ++ if (((oldflags ^ newflags) &
10218 ++ (JFFS2_INO_FLAG_IMMUTABLE | JFFS2_INO_FLAG_IUNLINK)) ||
10219 ++ (oldflags & JFFS2_INO_FLAG_IMMUTABLE)) {
10220 ++ if (!capable(CAP_LINUX_IMMUTABLE))
10221 ++ return -EPERM;
10222 ++ }
10223 ++
10224 ++ if (oldflags ^ newflags) {
10225 ++ j->flags = newflags;
10226 ++ inode->i_ctime = CURRENT_TIME;
10227 ++ /* strange requirement, see jffs2_dirty_inode() */
10228 ++ inode->i_state |= I_DIRTY_DATASYNC;
10229 ++ mark_inode_dirty(inode);
10230 ++ jffs2_set_inode_flags(inode);
10231 ++ }
10232 ++ return 0;
10233 ++
10234 ++ default:
10235 ++ return -ENOTTY;
10236 ++ }
10237 + }
10238 +
10239 +diff -NurpP --minimal linux-2.6.22.19/fs/jffs2/jffs2_fs_sb.h linux-2.6.22.19-vs2.3.0.34/fs/jffs2/jffs2_fs_sb.h
10240 +--- linux-2.6.22.19/fs/jffs2/jffs2_fs_sb.h 2007-07-09 13:19:26 +0200
10241 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jffs2/jffs2_fs_sb.h 2007-08-05 20:53:12 +0200
10242 +@@ -39,6 +39,7 @@ struct jffs2_sb_info {
10243 + uint32_t checked_ino;
10244 +
10245 + unsigned int flags;
10246 ++ unsigned int s_mount_opt;
10247 +
10248 + struct task_struct *gc_task; /* GC task struct */
10249 + struct completion gc_thread_start; /* GC thread start completion */
10250 +diff -NurpP --minimal linux-2.6.22.19/fs/jffs2/nodelist.h linux-2.6.22.19-vs2.3.0.34/fs/jffs2/nodelist.h
10251 +--- linux-2.6.22.19/fs/jffs2/nodelist.h 2007-07-09 13:19:26 +0200
10252 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jffs2/nodelist.h 2007-08-05 20:53:12 +0200
10253 +@@ -47,25 +47,25 @@
10254 + #elif defined(JFFS2_BIG_ENDIAN)
10255 + #define cpu_to_je16(x) ((jint16_t){cpu_to_be16(x)})
10256 + #define cpu_to_je32(x) ((jint32_t){cpu_to_be32(x)})
10257 +-#define cpu_to_jemode(x) ((jmode_t){cpu_to_be32(os_to_jffs2_mode(x))})
10258 ++#define cpu_to_jemode(x) ((jmode_t){cpu_to_be16(os_to_jffs2_mode(x))})
10259 +
10260 + #define constant_cpu_to_je16(x) ((jint16_t){__constant_cpu_to_be16(x)})
10261 + #define constant_cpu_to_je32(x) ((jint32_t){__constant_cpu_to_be32(x)})
10262 +
10263 + #define je16_to_cpu(x) (be16_to_cpu(x.v16))
10264 + #define je32_to_cpu(x) (be32_to_cpu(x.v32))
10265 +-#define jemode_to_cpu(x) (be32_to_cpu(jffs2_to_os_mode((x).m)))
10266 ++#define jemode_to_cpu(x) (be16_to_cpu(jffs2_to_os_mode((x).m)))
10267 + #elif defined(JFFS2_LITTLE_ENDIAN)
10268 + #define cpu_to_je16(x) ((jint16_t){cpu_to_le16(x)})
10269 + #define cpu_to_je32(x) ((jint32_t){cpu_to_le32(x)})
10270 +-#define cpu_to_jemode(x) ((jmode_t){cpu_to_le32(os_to_jffs2_mode(x))})
10271 ++#define cpu_to_jemode(x) ((jmode_t){cpu_to_le16(os_to_jffs2_mode(x))})
10272 +
10273 + #define constant_cpu_to_je16(x) ((jint16_t){__constant_cpu_to_le16(x)})
10274 + #define constant_cpu_to_je32(x) ((jint32_t){__constant_cpu_to_le32(x)})
10275 +
10276 + #define je16_to_cpu(x) (le16_to_cpu(x.v16))
10277 + #define je32_to_cpu(x) (le32_to_cpu(x.v32))
10278 +-#define jemode_to_cpu(x) (le32_to_cpu(jffs2_to_os_mode((x).m)))
10279 ++#define jemode_to_cpu(x) (le16_to_cpu(jffs2_to_os_mode((x).m)))
10280 + #else
10281 + #error wibble
10282 + #endif
10283 +diff -NurpP --minimal linux-2.6.22.19/fs/jffs2/os-linux.h linux-2.6.22.19-vs2.3.0.34/fs/jffs2/os-linux.h
10284 +--- linux-2.6.22.19/fs/jffs2/os-linux.h 2007-07-09 13:19:26 +0200
10285 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jffs2/os-linux.h 2007-08-05 20:53:12 +0200
10286 +@@ -29,6 +29,7 @@ struct kvec;
10287 + #define JFFS2_F_I_MODE(f) (OFNI_EDONI_2SFFJ(f)->i_mode)
10288 + #define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid)
10289 + #define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid)
10290 ++#define JFFS2_F_I_TAG(f) (OFNI_EDONI_2SFFJ(f)->i_tag)
10291 + #define JFFS2_F_I_RDEV(f) (OFNI_EDONI_2SFFJ(f)->i_rdev)
10292 +
10293 + #define ITIME(sec) ((struct timespec){sec, 0})
10294 +@@ -204,6 +205,9 @@ int jffs2_flash_direct_writev(struct jff
10295 + int jffs2_flash_direct_write(struct jffs2_sb_info *c, loff_t ofs, size_t len,
10296 + size_t *retlen, const u_char *buf);
10297 +
10298 ++#define JFFS2_IOC_GETFLAGS FS_IOC_GETFLAGS
10299 ++#define JFFS2_IOC_SETFLAGS FS_IOC_SETFLAGS
10300 ++
10301 + #endif /* __JFFS2_OS_LINUX_H__ */
10302 +
10303 +
10304 +diff -NurpP --minimal linux-2.6.22.19/fs/jffs2/readinode.c linux-2.6.22.19-vs2.3.0.34/fs/jffs2/readinode.c
10305 +--- linux-2.6.22.19/fs/jffs2/readinode.c 2007-07-09 13:19:26 +0200
10306 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jffs2/readinode.c 2007-08-05 20:53:12 +0200
10307 +@@ -1182,6 +1182,8 @@ static int jffs2_do_read_inode_internal(
10308 + latest_node->isize = cpu_to_je32(0);
10309 + latest_node->gid = cpu_to_je16(0);
10310 + latest_node->uid = cpu_to_je16(0);
10311 ++ latest_node->tag = cpu_to_je16(0);
10312 ++ latest_node->flags = cpu_to_je16(0);
10313 + if (f->inocache->state == INO_STATE_READING)
10314 + jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
10315 + return 0;
10316 +diff -NurpP --minimal linux-2.6.22.19/fs/jffs2/super.c linux-2.6.22.19-vs2.3.0.34/fs/jffs2/super.c
10317 +--- linux-2.6.22.19/fs/jffs2/super.c 2007-07-09 13:19:26 +0200
10318 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jffs2/super.c 2007-08-05 20:53:12 +0200
10319 +@@ -22,6 +22,7 @@
10320 + #include <linux/mtd/super.h>
10321 + #include <linux/ctype.h>
10322 + #include <linux/namei.h>
10323 ++#include <linux/parser.h>
10324 + #include "compr.h"
10325 + #include "nodelist.h"
10326 +
10327 +@@ -75,6 +76,49 @@ static const struct super_operations jff
10328 + .sync_fs = jffs2_sync_fs,
10329 + };
10330 +
10331 ++enum {
10332 ++ Opt_tag, Opt_notag, Opt_ignore, Opt_err
10333 ++};
10334 ++
10335 ++static match_table_t tokens = {
10336 ++ {Opt_tag, "tag"},
10337 ++ {Opt_notag, "notag"},
10338 ++ {Opt_err, NULL}
10339 ++};
10340 ++
10341 ++static int parse_options (char * options,
10342 ++ struct jffs2_sb_info *sbi)
10343 ++{
10344 ++ char * p;
10345 ++ substring_t args[MAX_OPT_ARGS];
10346 ++
10347 ++ if (!options)
10348 ++ return 1;
10349 ++
10350 ++ while ((p = strsep (&options, ",")) != NULL) {
10351 ++ int token;
10352 ++ if (!*p)
10353 ++ continue;
10354 ++
10355 ++ token = match_token(p, tokens, args);
10356 ++ switch (token) {
10357 ++#ifndef CONFIG_TAGGING_NONE
10358 ++ case Opt_tag:
10359 ++ set_opt (sbi->s_mount_opt, TAGGED);
10360 ++ break;
10361 ++ case Opt_notag:
10362 ++ clear_opt (sbi->s_mount_opt, TAGGED);
10363 ++ break;
10364 ++#endif
10365 ++ case Opt_ignore:
10366 ++ break;
10367 ++ default:
10368 ++ return 0;
10369 ++ }
10370 ++ }
10371 ++ return 1;
10372 ++}
10373 ++
10374 + /*
10375 + * fill in the superblock
10376 + */
10377 +@@ -109,6 +153,12 @@ static int jffs2_fill_super(struct super
10378 + #ifdef CONFIG_JFFS2_FS_POSIX_ACL
10379 + sb->s_flags |= MS_POSIXACL;
10380 + #endif
10381 ++ if (!parse_options ((char *) data, c))
10382 ++ return -EINVAL;
10383 ++
10384 ++ if (c->s_mount_opt & JFFS2_MOUNT_TAGGED)
10385 ++ sb->s_flags |= MS_TAGGED;
10386 ++
10387 + return jffs2_do_fill_super(sb, data, silent);
10388 + }
10389 +
10390 +diff -NurpP --minimal linux-2.6.22.19/fs/jffs2/write.c linux-2.6.22.19-vs2.3.0.34/fs/jffs2/write.c
10391 +--- linux-2.6.22.19/fs/jffs2/write.c 2008-03-14 20:19:03 +0100
10392 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jffs2/write.c 2007-09-05 03:06:11 +0200
10393 +@@ -44,6 +44,7 @@ int jffs2_do_new_inode(struct jffs2_sb_i
10394 + ri->totlen = cpu_to_je32(PAD(sizeof(*ri)));
10395 + ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
10396 + ri->mode = cpu_to_jemode(mode);
10397 ++ ri->flags = cpu_to_je16(0);
10398 +
10399 + f->highest_version = 1;
10400 + ri->version = cpu_to_je32(f->highest_version);
10401 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/acl.c linux-2.6.22.19-vs2.3.0.34/fs/jfs/acl.c
10402 +--- linux-2.6.22.19/fs/jfs/acl.c 2006-11-30 21:19:25 +0100
10403 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/acl.c 2007-08-05 20:53:12 +0200
10404 +@@ -232,7 +232,8 @@ int jfs_setattr(struct dentry *dentry, s
10405 + return rc;
10406 +
10407 + if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
10408 +- (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
10409 ++ (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) ||
10410 ++ (iattr->ia_valid & ATTR_TAG && iattr->ia_tag != inode->i_tag)) {
10411 + if (DQUOT_TRANSFER(inode, iattr))
10412 + return -EDQUOT;
10413 + }
10414 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/file.c linux-2.6.22.19-vs2.3.0.34/fs/jfs/file.c
10415 +--- linux-2.6.22.19/fs/jfs/file.c 2007-05-02 19:25:18 +0200
10416 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/file.c 2007-09-12 20:04:16 +0200
10417 +@@ -98,6 +98,7 @@ const struct inode_operations jfs_file_i
10418 + .setattr = jfs_setattr,
10419 + .permission = jfs_permission,
10420 + #endif
10421 ++ .sync_flags = jfs_sync_flags,
10422 + };
10423 +
10424 + const struct file_operations jfs_file_operations = {
10425 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/inode.c linux-2.6.22.19-vs2.3.0.34/fs/jfs/inode.c
10426 +--- linux-2.6.22.19/fs/jfs/inode.c 2007-07-09 13:19:26 +0200
10427 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/inode.c 2007-08-05 20:53:12 +0200
10428 +@@ -22,6 +22,7 @@
10429 + #include <linux/buffer_head.h>
10430 + #include <linux/pagemap.h>
10431 + #include <linux/quotaops.h>
10432 ++#include <linux/vs_dlimit.h>
10433 + #include "jfs_incore.h"
10434 + #include "jfs_inode.h"
10435 + #include "jfs_filsys.h"
10436 +@@ -143,6 +144,7 @@ void jfs_delete_inode(struct inode *inod
10437 + DQUOT_INIT(inode);
10438 + DQUOT_FREE_INODE(inode);
10439 + DQUOT_DROP(inode);
10440 ++ DLIMIT_FREE_INODE(inode);
10441 + }
10442 +
10443 + clear_inode(inode);
10444 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/ioctl.c linux-2.6.22.19-vs2.3.0.34/fs/jfs/ioctl.c
10445 +--- linux-2.6.22.19/fs/jfs/ioctl.c 2007-07-09 13:19:27 +0200
10446 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/ioctl.c 2007-08-05 20:53:12 +0200
10447 +@@ -10,6 +10,7 @@
10448 + #include <linux/capability.h>
10449 + #include <linux/time.h>
10450 + #include <linux/sched.h>
10451 ++#include <linux/mount.h>
10452 + #include <asm/current.h>
10453 + #include <asm/uaccess.h>
10454 +
10455 +@@ -66,7 +67,8 @@ int jfs_ioctl(struct inode * inode, stru
10456 + case JFS_IOC_SETFLAGS: {
10457 + unsigned int oldflags;
10458 +
10459 +- if (IS_RDONLY(inode))
10460 ++ if (IS_RDONLY(inode) ||
10461 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
10462 + return -EROFS;
10463 +
10464 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
10465 +@@ -87,8 +89,8 @@ int jfs_ioctl(struct inode * inode, stru
10466 + * the relevant capability.
10467 + */
10468 + if ((oldflags & JFS_IMMUTABLE_FL) ||
10469 +- ((flags ^ oldflags) &
10470 +- (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
10471 ++ ((flags ^ oldflags) & (JFS_APPEND_FL |
10472 ++ JFS_IMMUTABLE_FL | JFS_IUNLINK_FL))) {
10473 + if (!capable(CAP_LINUX_IMMUTABLE))
10474 + return -EPERM;
10475 + }
10476 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_dinode.h linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_dinode.h
10477 +--- linux-2.6.22.19/fs/jfs/jfs_dinode.h 2006-11-30 21:19:25 +0100
10478 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_dinode.h 2007-08-05 20:53:12 +0200
10479 +@@ -162,9 +162,12 @@ struct dinode {
10480 + #define JFS_APPEND_FL 0x01000000 /* writes to file may only append */
10481 + #define JFS_IMMUTABLE_FL 0x02000000 /* Immutable file */
10482 +
10483 +-#define JFS_FL_USER_VISIBLE 0x03F80000
10484 ++#define JFS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
10485 ++#define JFS_IUNLINK_FL 0x08000000 /* Immutable unlink */
10486 ++
10487 ++#define JFS_FL_USER_VISIBLE 0x0FF80000
10488 + #define JFS_FL_USER_MODIFIABLE 0x03F80000
10489 +-#define JFS_FL_INHERIT 0x03C80000
10490 ++#define JFS_FL_INHERIT 0x0BC80000
10491 +
10492 + /* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
10493 + #define JFS_IOC_GETFLAGS _IOR('f', 1, long)
10494 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_dtree.c linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_dtree.c
10495 +--- linux-2.6.22.19/fs/jfs/jfs_dtree.c 2007-02-06 03:01:24 +0100
10496 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_dtree.c 2007-08-05 20:53:12 +0200
10497 +@@ -102,6 +102,7 @@
10498 +
10499 + #include <linux/fs.h>
10500 + #include <linux/quotaops.h>
10501 ++#include <linux/vs_dlimit.h>
10502 + #include "jfs_incore.h"
10503 + #include "jfs_superblock.h"
10504 + #include "jfs_filsys.h"
10505 +@@ -383,10 +384,10 @@ static u32 add_index(tid_t tid, struct i
10506 + */
10507 + if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage))
10508 + goto clean_up;
10509 +- if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) {
10510 +- DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
10511 +- goto clean_up;
10512 +- }
10513 ++ if (DLIMIT_ALLOC_BLOCK(ip, sbi->nbperpage))
10514 ++ goto clean_up_dquot;
10515 ++ if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr))
10516 ++ goto clean_up_dlimit;
10517 +
10518 + /*
10519 + * Save the table, we're going to overwrite it with the
10520 +@@ -479,6 +480,12 @@ static u32 add_index(tid_t tid, struct i
10521 +
10522 + return index;
10523 +
10524 ++ clean_up_dlimit:
10525 ++ DLIMIT_FREE_BLOCK(ip, sbi->nbperpage);
10526 ++
10527 ++ clean_up_dquot:
10528 ++ DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
10529 ++
10530 + clean_up:
10531 +
10532 + jfs_ip->next_index--;
10533 +@@ -952,6 +959,7 @@ static int dtSplitUp(tid_t tid,
10534 + struct tlock *tlck;
10535 + struct lv *lv;
10536 + int quota_allocation = 0;
10537 ++ int dlimit_allocation = 0;
10538 +
10539 + /* get split page */
10540 + smp = split->mp;
10541 +@@ -1036,6 +1044,12 @@ static int dtSplitUp(tid_t tid,
10542 + }
10543 + quota_allocation += n;
10544 +
10545 ++ if (DLIMIT_ALLOC_BLOCK(ip, n)) {
10546 ++ rc = -ENOSPC;
10547 ++ goto extendOut;
10548 ++ }
10549 ++ dlimit_allocation += n;
10550 ++
10551 + if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen,
10552 + (s64) n, &nxaddr)))
10553 + goto extendOut;
10554 +@@ -1309,6 +1323,9 @@ static int dtSplitUp(tid_t tid,
10555 + freeKeyName:
10556 + kfree(key.name);
10557 +
10558 ++ /* Rollback dlimit allocation */
10559 ++ if (rc && dlimit_allocation)
10560 ++ DLIMIT_FREE_BLOCK(ip, dlimit_allocation);
10561 + /* Rollback quota allocation */
10562 + if (rc && quota_allocation)
10563 + DQUOT_FREE_BLOCK(ip, quota_allocation);
10564 +@@ -1376,6 +1393,12 @@ static int dtSplitPage(tid_t tid, struct
10565 + release_metapage(rmp);
10566 + return -EDQUOT;
10567 + }
10568 ++ /* Allocate blocks to dlimit. */
10569 ++ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
10570 ++ DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
10571 ++ release_metapage(rmp);
10572 ++ return -ENOSPC;
10573 ++ }
10574 +
10575 + jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
10576 +
10577 +@@ -1926,6 +1949,12 @@ static int dtSplitRoot(tid_t tid,
10578 + release_metapage(rmp);
10579 + return -EDQUOT;
10580 + }
10581 ++ /* Allocate blocks to dlimit. */
10582 ++ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
10583 ++ DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
10584 ++ release_metapage(rmp);
10585 ++ return -ENOSPC;
10586 ++ }
10587 +
10588 + BT_MARK_DIRTY(rmp, ip);
10589 + /*
10590 +@@ -2292,6 +2321,8 @@ static int dtDeleteUp(tid_t tid, struct
10591 +
10592 + xlen = lengthPXD(&fp->header.self);
10593 +
10594 ++ /* Free dlimit allocation. */
10595 ++ DLIMIT_FREE_BLOCK(ip, xlen);
10596 + /* Free quota allocation. */
10597 + DQUOT_FREE_BLOCK(ip, xlen);
10598 +
10599 +@@ -2368,6 +2399,8 @@ static int dtDeleteUp(tid_t tid, struct
10600 +
10601 + xlen = lengthPXD(&p->header.self);
10602 +
10603 ++ /* Free dlimit allocation */
10604 ++ DLIMIT_FREE_BLOCK(ip, xlen);
10605 + /* Free quota allocation */
10606 + DQUOT_FREE_BLOCK(ip, xlen);
10607 +
10608 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_extent.c linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_extent.c
10609 +--- linux-2.6.22.19/fs/jfs/jfs_extent.c 2006-11-30 21:19:25 +0100
10610 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_extent.c 2007-08-05 20:53:12 +0200
10611 +@@ -18,6 +18,7 @@
10612 +
10613 + #include <linux/fs.h>
10614 + #include <linux/quotaops.h>
10615 ++#include <linux/vs_dlimit.h>
10616 + #include "jfs_incore.h"
10617 + #include "jfs_inode.h"
10618 + #include "jfs_superblock.h"
10619 +@@ -147,6 +148,14 @@ extAlloc(struct inode *ip, s64 xlen, s64
10620 + return -EDQUOT;
10621 + }
10622 +
10623 ++ /* Allocate blocks to dlimit. */
10624 ++ if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) {
10625 ++ DQUOT_FREE_BLOCK(ip, nxlen);
10626 ++ dbFree(ip, nxaddr, (s64) nxlen);
10627 ++ mutex_unlock(&JFS_IP(ip)->commit_mutex);
10628 ++ return -ENOSPC;
10629 ++ }
10630 ++
10631 + /* determine the value of the extent flag */
10632 + xflag = abnr ? XAD_NOTRECORDED : 0;
10633 +
10634 +@@ -164,6 +173,7 @@ extAlloc(struct inode *ip, s64 xlen, s64
10635 + */
10636 + if (rc) {
10637 + dbFree(ip, nxaddr, nxlen);
10638 ++ DLIMIT_FREE_BLOCK(ip, nxlen);
10639 + DQUOT_FREE_BLOCK(ip, nxlen);
10640 + mutex_unlock(&JFS_IP(ip)->commit_mutex);
10641 + return (rc);
10642 +@@ -261,6 +271,13 @@ int extRealloc(struct inode *ip, s64 nxl
10643 + mutex_unlock(&JFS_IP(ip)->commit_mutex);
10644 + return -EDQUOT;
10645 + }
10646 ++ /* Allocate blocks to dlimit. */
10647 ++ if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) {
10648 ++ DQUOT_FREE_BLOCK(ip, nxlen);
10649 ++ dbFree(ip, nxaddr, (s64) nxlen);
10650 ++ up(&JFS_IP(ip)->commit_sem);
10651 ++ return -ENOSPC;
10652 ++ }
10653 +
10654 + delta = nxlen - xlen;
10655 +
10656 +@@ -297,6 +314,7 @@ int extRealloc(struct inode *ip, s64 nxl
10657 + /* extend the extent */
10658 + if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) {
10659 + dbFree(ip, xaddr + xlen, delta);
10660 ++ DLIMIT_FREE_BLOCK(ip, nxlen);
10661 + DQUOT_FREE_BLOCK(ip, nxlen);
10662 + goto exit;
10663 + }
10664 +@@ -308,6 +326,7 @@ int extRealloc(struct inode *ip, s64 nxl
10665 + */
10666 + if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) {
10667 + dbFree(ip, nxaddr, nxlen);
10668 ++ DLIMIT_FREE_BLOCK(ip, nxlen);
10669 + DQUOT_FREE_BLOCK(ip, nxlen);
10670 + goto exit;
10671 + }
10672 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_filsys.h linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_filsys.h
10673 +--- linux-2.6.22.19/fs/jfs/jfs_filsys.h 2007-02-06 03:01:24 +0100
10674 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_filsys.h 2007-08-05 20:53:12 +0200
10675 +@@ -264,6 +264,7 @@
10676 + #define JFS_NAME_MAX 255
10677 + #define JFS_PATH_MAX BPSIZE
10678 +
10679 ++#define JFS_TAGGED 0x00800000 /* Context Tagging */
10680 +
10681 + /*
10682 + * file system state (superblock state)
10683 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_imap.c linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_imap.c
10684 +--- linux-2.6.22.19/fs/jfs/jfs_imap.c 2007-07-09 13:19:27 +0200
10685 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_imap.c 2007-08-05 20:53:12 +0200
10686 +@@ -45,6 +45,7 @@
10687 + #include <linux/buffer_head.h>
10688 + #include <linux/pagemap.h>
10689 + #include <linux/quotaops.h>
10690 ++#include <linux/vs_tag.h>
10691 +
10692 + #include "jfs_incore.h"
10693 + #include "jfs_inode.h"
10694 +@@ -3075,6 +3076,8 @@ static int copy_from_dinode(struct dinod
10695 + {
10696 + struct jfs_inode_info *jfs_ip = JFS_IP(ip);
10697 + struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
10698 ++ uid_t uid;
10699 ++ gid_t gid;
10700 +
10701 + jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
10702 + jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
10703 +@@ -3095,14 +3098,18 @@ static int copy_from_dinode(struct dinod
10704 + }
10705 + ip->i_nlink = le32_to_cpu(dip->di_nlink);
10706 +
10707 +- jfs_ip->saved_uid = le32_to_cpu(dip->di_uid);
10708 ++ uid = le32_to_cpu(dip->di_uid);
10709 ++ gid = le32_to_cpu(dip->di_gid);
10710 ++ ip->i_tag = INOTAG_TAG(DX_TAG(ip), uid, gid, 0);
10711 ++
10712 ++ jfs_ip->saved_uid = INOTAG_UID(DX_TAG(ip), uid, gid);
10713 + if (sbi->uid == -1)
10714 + ip->i_uid = jfs_ip->saved_uid;
10715 + else {
10716 + ip->i_uid = sbi->uid;
10717 + }
10718 +
10719 +- jfs_ip->saved_gid = le32_to_cpu(dip->di_gid);
10720 ++ jfs_ip->saved_gid = INOTAG_GID(DX_TAG(ip), uid, gid);
10721 + if (sbi->gid == -1)
10722 + ip->i_gid = jfs_ip->saved_gid;
10723 + else {
10724 +@@ -3167,14 +3174,12 @@ static void copy_to_dinode(struct dinode
10725 + dip->di_size = cpu_to_le64(ip->i_size);
10726 + dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
10727 + dip->di_nlink = cpu_to_le32(ip->i_nlink);
10728 +- if (sbi->uid == -1)
10729 +- dip->di_uid = cpu_to_le32(ip->i_uid);
10730 +- else
10731 +- dip->di_uid = cpu_to_le32(jfs_ip->saved_uid);
10732 +- if (sbi->gid == -1)
10733 +- dip->di_gid = cpu_to_le32(ip->i_gid);
10734 +- else
10735 +- dip->di_gid = cpu_to_le32(jfs_ip->saved_gid);
10736 ++
10737 ++ dip->di_uid = cpu_to_le32(TAGINO_UID(DX_TAG(ip),
10738 ++ (sbi->uid == -1) ? ip->i_uid : jfs_ip->saved_uid, ip->i_tag));
10739 ++ dip->di_gid = cpu_to_le32(TAGINO_GID(DX_TAG(ip),
10740 ++ (sbi->gid == -1) ? ip->i_gid : jfs_ip->saved_gid, ip->i_tag));
10741 ++
10742 + jfs_get_inode_flags(jfs_ip);
10743 + /*
10744 + * mode2 is only needed for storing the higher order bits.
10745 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_inode.c linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_inode.c
10746 +--- linux-2.6.22.19/fs/jfs/jfs_inode.c 2007-07-09 13:19:27 +0200
10747 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_inode.c 2007-08-05 20:53:12 +0200
10748 +@@ -18,6 +18,8 @@
10749 +
10750 + #include <linux/fs.h>
10751 + #include <linux/quotaops.h>
10752 ++#include <linux/vs_dlimit.h>
10753 ++#include <linux/vs_tag.h>
10754 + #include "jfs_incore.h"
10755 + #include "jfs_inode.h"
10756 + #include "jfs_filsys.h"
10757 +@@ -30,19 +32,47 @@ void jfs_set_inode_flags(struct inode *i
10758 + {
10759 + unsigned int flags = JFS_IP(inode)->mode2;
10760 +
10761 +- inode->i_flags &= ~(S_IMMUTABLE | S_APPEND |
10762 +- S_NOATIME | S_DIRSYNC | S_SYNC);
10763 ++ inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
10764 ++ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
10765 +
10766 + if (flags & JFS_IMMUTABLE_FL)
10767 + inode->i_flags |= S_IMMUTABLE;
10768 ++ if (flags & JFS_IUNLINK_FL)
10769 ++ inode->i_flags |= S_IUNLINK;
10770 ++ if (flags & JFS_BARRIER_FL)
10771 ++ inode->i_flags |= S_BARRIER;
10772 ++
10773 ++ if (flags & JFS_SYNC_FL)
10774 ++ inode->i_flags |= S_SYNC;
10775 + if (flags & JFS_APPEND_FL)
10776 + inode->i_flags |= S_APPEND;
10777 + if (flags & JFS_NOATIME_FL)
10778 + inode->i_flags |= S_NOATIME;
10779 + if (flags & JFS_DIRSYNC_FL)
10780 + inode->i_flags |= S_DIRSYNC;
10781 +- if (flags & JFS_SYNC_FL)
10782 +- inode->i_flags |= S_SYNC;
10783 ++}
10784 ++
10785 ++int jfs_sync_flags(struct inode *inode)
10786 ++{
10787 ++ unsigned int oldflags, newflags;
10788 ++
10789 ++ oldflags = JFS_IP(inode)->mode2;
10790 ++ newflags = oldflags & ~(JFS_IMMUTABLE_FL |
10791 ++ JFS_IUNLINK_FL | JFS_BARRIER_FL);
10792 ++
10793 ++ if (IS_IMMUTABLE(inode))
10794 ++ newflags |= JFS_IMMUTABLE_FL;
10795 ++ if (IS_IUNLINK(inode))
10796 ++ newflags |= JFS_IUNLINK_FL;
10797 ++ if (IS_BARRIER(inode))
10798 ++ newflags |= JFS_BARRIER_FL;
10799 ++
10800 ++ if (oldflags ^ newflags) {
10801 ++ JFS_IP(inode)->mode2 = newflags;
10802 ++ inode->i_ctime = CURRENT_TIME;
10803 ++ mark_inode_dirty(inode);
10804 ++ }
10805 ++ return 0;
10806 + }
10807 +
10808 + void jfs_get_inode_flags(struct jfs_inode_info *jfs_ip)
10809 +@@ -108,10 +138,17 @@ struct inode *ialloc(struct inode *paren
10810 + jfs_inode->saved_uid = inode->i_uid;
10811 + jfs_inode->saved_gid = inode->i_gid;
10812 +
10813 ++ inode->i_tag = dx_current_fstag(sb);
10814 ++ if (DLIMIT_ALLOC_INODE(inode)) {
10815 ++ iput(inode);
10816 ++ return ERR_PTR(-ENOSPC);
10817 ++ }
10818 ++
10819 + /*
10820 + * Allocate inode to quota.
10821 + */
10822 + if (DQUOT_ALLOC_INODE(inode)) {
10823 ++ DLIMIT_FREE_INODE(inode);
10824 + DQUOT_DROP(inode);
10825 + inode->i_flags |= S_NOQUOTA;
10826 + inode->i_nlink = 0;
10827 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_inode.h linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_inode.h
10828 +--- linux-2.6.22.19/fs/jfs/jfs_inode.h 2007-07-09 13:19:27 +0200
10829 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_inode.h 2007-08-05 20:53:12 +0200
10830 +@@ -33,6 +33,7 @@ extern void jfs_free_zero_link(struct in
10831 + extern struct dentry *jfs_get_parent(struct dentry *dentry);
10832 + extern void jfs_get_inode_flags(struct jfs_inode_info *);
10833 + extern void jfs_set_inode_flags(struct inode *);
10834 ++extern int jfs_sync_flags(struct inode *);
10835 + extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
10836 +
10837 + extern const struct address_space_operations jfs_aops;
10838 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/jfs_xtree.c linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_xtree.c
10839 +--- linux-2.6.22.19/fs/jfs/jfs_xtree.c 2007-05-02 19:25:18 +0200
10840 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/jfs_xtree.c 2007-08-05 20:53:12 +0200
10841 +@@ -21,6 +21,7 @@
10842 +
10843 + #include <linux/fs.h>
10844 + #include <linux/quotaops.h>
10845 ++#include <linux/vs_dlimit.h>
10846 + #include "jfs_incore.h"
10847 + #include "jfs_filsys.h"
10848 + #include "jfs_metapage.h"
10849 +@@ -846,7 +847,12 @@ int xtInsert(tid_t tid, /* transaction
10850 + hint = 0;
10851 + if ((rc = DQUOT_ALLOC_BLOCK(ip, xlen)))
10852 + goto out;
10853 ++ if ((rc = DLIMIT_ALLOC_BLOCK(ip, xlen))) {
10854 ++ DQUOT_FREE_BLOCK(ip, xlen);
10855 ++ goto out;
10856 ++ }
10857 + if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) {
10858 ++ DLIMIT_FREE_BLOCK(ip, xlen);
10859 + DQUOT_FREE_BLOCK(ip, xlen);
10860 + goto out;
10861 + }
10862 +@@ -876,6 +882,7 @@ int xtInsert(tid_t tid, /* transaction
10863 + /* undo data extent allocation */
10864 + if (*xaddrp == 0) {
10865 + dbFree(ip, xaddr, (s64) xlen);
10866 ++ DLIMIT_FREE_BLOCK(ip, xlen);
10867 + DQUOT_FREE_BLOCK(ip, xlen);
10868 + }
10869 + return rc;
10870 +@@ -1236,6 +1243,7 @@ xtSplitPage(tid_t tid, struct inode *ip,
10871 + struct tlock *tlck;
10872 + struct xtlock *sxtlck = NULL, *rxtlck = NULL;
10873 + int quota_allocation = 0;
10874 ++ int dlimit_allocation = 0;
10875 +
10876 + smp = split->mp;
10877 + sp = XT_PAGE(ip, smp);
10878 +@@ -1255,6 +1263,13 @@ xtSplitPage(tid_t tid, struct inode *ip,
10879 +
10880 + quota_allocation += lengthPXD(pxd);
10881 +
10882 ++ /* Allocate blocks to dlimit. */
10883 ++ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
10884 ++ rc = -ENOSPC;
10885 ++ goto clean_up;
10886 ++ }
10887 ++ dlimit_allocation += lengthPXD(pxd);
10888 ++
10889 + /*
10890 + * allocate the new right page for the split
10891 + */
10892 +@@ -1456,6 +1471,9 @@ xtSplitPage(tid_t tid, struct inode *ip,
10893 +
10894 + clean_up:
10895 +
10896 ++ /* Rollback dlimit allocation. */
10897 ++ if (dlimit_allocation)
10898 ++ DLIMIT_FREE_BLOCK(ip, dlimit_allocation);
10899 + /* Rollback quota allocation. */
10900 + if (quota_allocation)
10901 + DQUOT_FREE_BLOCK(ip, quota_allocation);
10902 +@@ -1520,6 +1538,12 @@ xtSplitRoot(tid_t tid,
10903 + release_metapage(rmp);
10904 + return -EDQUOT;
10905 + }
10906 ++ /* Allocate blocks to dlimit. */
10907 ++ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
10908 ++ DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
10909 ++ release_metapage(rmp);
10910 ++ return -ENOSPC;
10911 ++ }
10912 +
10913 + jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp);
10914 +
10915 +@@ -3951,6 +3975,8 @@ s64 xtTruncate(tid_t tid, struct inode *
10916 + else
10917 + ip->i_size = newsize;
10918 +
10919 ++ /* update dlimit allocation to reflect freed blocks */
10920 ++ DLIMIT_FREE_BLOCK(ip, nfreed);
10921 + /* update quota allocation to reflect freed blocks */
10922 + DQUOT_FREE_BLOCK(ip, nfreed);
10923 +
10924 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/namei.c linux-2.6.22.19-vs2.3.0.34/fs/jfs/namei.c
10925 +--- linux-2.6.22.19/fs/jfs/namei.c 2007-05-02 19:25:18 +0200
10926 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/namei.c 2007-08-05 20:53:12 +0200
10927 +@@ -20,6 +20,7 @@
10928 + #include <linux/fs.h>
10929 + #include <linux/ctype.h>
10930 + #include <linux/quotaops.h>
10931 ++#include <linux/vs_tag.h>
10932 + #include "jfs_incore.h"
10933 + #include "jfs_superblock.h"
10934 + #include "jfs_inode.h"
10935 +@@ -1469,6 +1470,7 @@ static struct dentry *jfs_lookup(struct
10936 + return ERR_PTR(-EACCES);
10937 + }
10938 +
10939 ++ dx_propagate_tag(nd, ip);
10940 + dentry = d_splice_alias(ip, dentry);
10941 +
10942 + if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2))
10943 +@@ -1521,6 +1523,7 @@ const struct inode_operations jfs_dir_in
10944 + .setattr = jfs_setattr,
10945 + .permission = jfs_permission,
10946 + #endif
10947 ++ .sync_flags = jfs_sync_flags,
10948 + };
10949 +
10950 + const struct file_operations jfs_dir_operations = {
10951 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/super.c linux-2.6.22.19-vs2.3.0.34/fs/jfs/super.c
10952 +--- linux-2.6.22.19/fs/jfs/super.c 2007-07-09 13:19:27 +0200
10953 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/super.c 2007-08-05 20:53:12 +0200
10954 +@@ -194,7 +194,8 @@ static void jfs_put_super(struct super_b
10955 + enum {
10956 + Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
10957 + Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
10958 +- Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask
10959 ++ Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask,
10960 ++ Opt_tag, Opt_notag, Opt_tagid
10961 + };
10962 +
10963 + static match_table_t tokens = {
10964 +@@ -204,6 +205,10 @@ static match_table_t tokens = {
10965 + {Opt_resize, "resize=%u"},
10966 + {Opt_resize_nosize, "resize"},
10967 + {Opt_errors, "errors=%s"},
10968 ++ {Opt_tag, "tag"},
10969 ++ {Opt_notag, "notag"},
10970 ++ {Opt_tagid, "tagid=%u"},
10971 ++ {Opt_tag, "tagxid"},
10972 + {Opt_ignore, "noquota"},
10973 + {Opt_ignore, "quota"},
10974 + {Opt_usrquota, "usrquota"},
10975 +@@ -338,6 +343,20 @@ static int parse_options(char *options,
10976 + }
10977 + break;
10978 + }
10979 ++#ifndef CONFIG_TAGGING_NONE
10980 ++ case Opt_tag:
10981 ++ *flag |= JFS_TAGGED;
10982 ++ break;
10983 ++ case Opt_notag:
10984 ++ *flag &= JFS_TAGGED;
10985 ++ break;
10986 ++#endif
10987 ++#ifdef CONFIG_PROPAGATE
10988 ++ case Opt_tagid:
10989 ++ /* use args[0] */
10990 ++ *flag |= JFS_TAGGED;
10991 ++ break;
10992 ++#endif
10993 + default:
10994 + printk("jfs: Unrecognized mount option \"%s\" "
10995 + " or missing value\n", p);
10996 +@@ -368,6 +387,13 @@ static int jfs_remount(struct super_bloc
10997 + if (!parse_options(data, sb, &newLVSize, &flag)) {
10998 + return -EINVAL;
10999 + }
11000 ++
11001 ++ if ((flag & JFS_TAGGED) && !(sb->s_flags & MS_TAGGED)) {
11002 ++ printk(KERN_ERR "JFS: %s: tagging not permitted on remount.\n",
11003 ++ sb->s_id);
11004 ++ return -EINVAL;
11005 ++ }
11006 ++
11007 + if (newLVSize) {
11008 + if (sb->s_flags & MS_RDONLY) {
11009 + printk(KERN_ERR
11010 +@@ -439,6 +465,9 @@ static int jfs_fill_super(struct super_b
11011 + #ifdef CONFIG_JFS_POSIX_ACL
11012 + sb->s_flags |= MS_POSIXACL;
11013 + #endif
11014 ++ /* map mount option tagxid */
11015 ++ if (sbi->flag & JFS_TAGGED)
11016 ++ sb->s_flags |= MS_TAGGED;
11017 +
11018 + if (newLVSize) {
11019 + printk(KERN_ERR "resize option for remount only\n");
11020 +diff -NurpP --minimal linux-2.6.22.19/fs/jfs/xattr.c linux-2.6.22.19-vs2.3.0.34/fs/jfs/xattr.c
11021 +--- linux-2.6.22.19/fs/jfs/xattr.c 2006-11-30 21:19:26 +0100
11022 ++++ linux-2.6.22.19-vs2.3.0.34/fs/jfs/xattr.c 2007-08-05 20:53:12 +0200
11023 +@@ -23,6 +23,7 @@
11024 + #include <linux/posix_acl_xattr.h>
11025 + #include <linux/quotaops.h>
11026 + #include <linux/security.h>
11027 ++#include <linux/vs_dlimit.h>
11028 + #include "jfs_incore.h"
11029 + #include "jfs_superblock.h"
11030 + #include "jfs_dmap.h"
11031 +@@ -263,9 +264,16 @@ static int ea_write(struct inode *ip, st
11032 + if (DQUOT_ALLOC_BLOCK(ip, nblocks)) {
11033 + return -EDQUOT;
11034 + }
11035 ++ /* Allocate new blocks to dlimit. */
11036 ++ if (DLIMIT_ALLOC_BLOCK(ip, nblocks)) {
11037 ++ DQUOT_FREE_BLOCK(ip, nblocks);
11038 ++ return -ENOSPC;
11039 ++ }
11040 +
11041 + rc = dbAlloc(ip, INOHINT(ip), nblocks, &blkno);
11042 + if (rc) {
11043 ++ /*Rollback dlimit allocation. */
11044 ++ DLIMIT_FREE_BLOCK(ip, nblocks);
11045 + /*Rollback quota allocation. */
11046 + DQUOT_FREE_BLOCK(ip, nblocks);
11047 + return rc;
11048 +@@ -332,6 +340,8 @@ static int ea_write(struct inode *ip, st
11049 +
11050 + failed:
11051 + /* Rollback quota allocation. */
11052 ++ DLIMIT_FREE_BLOCK(ip, nblocks);
11053 ++ /* Rollback quota allocation. */
11054 + DQUOT_FREE_BLOCK(ip, nblocks);
11055 +
11056 + dbFree(ip, blkno, nblocks);
11057 +@@ -468,6 +478,7 @@ static int ea_get(struct inode *inode, s
11058 + s64 blkno;
11059 + int rc;
11060 + int quota_allocation = 0;
11061 ++ int dlimit_allocation = 0;
11062 +
11063 + /* When fsck.jfs clears a bad ea, it doesn't clear the size */
11064 + if (ji->ea.flag == 0)
11065 +@@ -543,6 +554,12 @@ static int ea_get(struct inode *inode, s
11066 +
11067 + quota_allocation = blocks_needed;
11068 +
11069 ++ /* Allocate new blocks to dlimit. */
11070 ++ rc = -ENOSPC;
11071 ++ if (DLIMIT_ALLOC_BLOCK(inode, blocks_needed))
11072 ++ goto clean_up;
11073 ++ dlimit_allocation = blocks_needed;
11074 ++
11075 + rc = dbAlloc(inode, INOHINT(inode), (s64) blocks_needed,
11076 + &blkno);
11077 + if (rc)
11078 +@@ -599,6 +616,9 @@ static int ea_get(struct inode *inode, s
11079 + return ea_size;
11080 +
11081 + clean_up:
11082 ++ /* Rollback dlimit allocation */
11083 ++ if (dlimit_allocation)
11084 ++ DLIMIT_FREE_BLOCK(inode, dlimit_allocation);
11085 + /* Rollback quota allocation */
11086 + if (quota_allocation)
11087 + DQUOT_FREE_BLOCK(inode, quota_allocation);
11088 +@@ -675,8 +695,10 @@ static int ea_put(tid_t tid, struct inod
11089 + }
11090 +
11091 + /* If old blocks exist, they must be removed from quota allocation. */
11092 +- if (old_blocks)
11093 ++ if (old_blocks) {
11094 ++ DLIMIT_FREE_BLOCK(inode, old_blocks);
11095 + DQUOT_FREE_BLOCK(inode, old_blocks);
11096 ++ }
11097 +
11098 + inode->i_ctime = CURRENT_TIME;
11099 +
11100 +diff -NurpP --minimal linux-2.6.22.19/fs/libfs.c linux-2.6.22.19-vs2.3.0.34/fs/libfs.c
11101 +--- linux-2.6.22.19/fs/libfs.c 2007-07-09 13:19:27 +0200
11102 ++++ linux-2.6.22.19-vs2.3.0.34/fs/libfs.c 2007-08-05 20:53:12 +0200
11103 +@@ -124,7 +124,8 @@ static inline unsigned char dt_type(stru
11104 + * both impossible due to the lock on directory.
11105 + */
11106 +
11107 +-int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
11108 ++static inline int do_dcache_readdir_filter(struct file *filp,
11109 ++ void *dirent, filldir_t filldir, int (*filter)(struct dentry *dentry))
11110 + {
11111 + struct dentry *dentry = filp->f_path.dentry;
11112 + struct dentry *cursor = filp->private_data;
11113 +@@ -157,6 +158,8 @@ int dcache_readdir(struct file * filp, v
11114 + next = list_entry(p, struct dentry, d_u.d_child);
11115 + if (d_unhashed(next) || !next->d_inode)
11116 + continue;
11117 ++ if (filter && !filter(next))
11118 ++ continue;
11119 +
11120 + spin_unlock(&dcache_lock);
11121 + if (filldir(dirent, next->d_name.name,
11122 +@@ -175,6 +178,18 @@ int dcache_readdir(struct file * filp, v
11123 + return 0;
11124 + }
11125 +
11126 ++int dcache_readdir(struct file *filp, void *dirent, filldir_t filldir)
11127 ++{
11128 ++ return do_dcache_readdir_filter(filp, dirent, filldir, NULL);
11129 ++}
11130 ++
11131 ++int dcache_readdir_filter(struct file *filp, void *dirent, filldir_t filldir,
11132 ++ int (*filter)(struct dentry *))
11133 ++{
11134 ++ return do_dcache_readdir_filter(filp, dirent, filldir, filter);
11135 ++}
11136 ++
11137 ++
11138 + ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
11139 + {
11140 + return -EISDIR;
11141 +@@ -640,6 +655,7 @@ EXPORT_SYMBOL(dcache_dir_close);
11142 + EXPORT_SYMBOL(dcache_dir_lseek);
11143 + EXPORT_SYMBOL(dcache_dir_open);
11144 + EXPORT_SYMBOL(dcache_readdir);
11145 ++EXPORT_SYMBOL(dcache_readdir_filter);
11146 + EXPORT_SYMBOL(generic_read_dir);
11147 + EXPORT_SYMBOL(get_sb_pseudo);
11148 + EXPORT_SYMBOL(simple_commit_write);
11149 +diff -NurpP --minimal linux-2.6.22.19/fs/locks.c linux-2.6.22.19-vs2.3.0.34/fs/locks.c
11150 +--- linux-2.6.22.19/fs/locks.c 2008-03-14 20:19:03 +0100
11151 ++++ linux-2.6.22.19-vs2.3.0.34/fs/locks.c 2007-10-05 15:07:22 +0200
11152 +@@ -125,6 +125,8 @@
11153 + #include <linux/syscalls.h>
11154 + #include <linux/time.h>
11155 + #include <linux/rcupdate.h>
11156 ++#include <linux/vs_base.h>
11157 ++#include <linux/vs_limit.h>
11158 +
11159 + #include <asm/semaphore.h>
11160 + #include <asm/uaccess.h>
11161 +@@ -147,6 +149,8 @@ static struct kmem_cache *filelock_cache
11162 + /* Allocate an empty lock structure. */
11163 + static struct file_lock *locks_alloc_lock(void)
11164 + {
11165 ++ if (!vx_locks_avail(1))
11166 ++ return NULL;
11167 + return kmem_cache_alloc(filelock_cache, GFP_KERNEL);
11168 + }
11169 +
11170 +@@ -172,6 +176,7 @@ static void locks_free_lock(struct file_
11171 + BUG_ON(!list_empty(&fl->fl_block));
11172 + BUG_ON(!list_empty(&fl->fl_link));
11173 +
11174 ++ vx_locks_dec(fl);
11175 + locks_release_private(fl);
11176 + kmem_cache_free(filelock_cache, fl);
11177 + }
11178 +@@ -191,6 +196,7 @@ void locks_init_lock(struct file_lock *f
11179 + fl->fl_start = fl->fl_end = 0;
11180 + fl->fl_ops = NULL;
11181 + fl->fl_lmops = NULL;
11182 ++ fl->fl_xid = -1;
11183 + }
11184 +
11185 + EXPORT_SYMBOL(locks_init_lock);
11186 +@@ -244,6 +250,7 @@ void locks_copy_lock(struct file_lock *n
11187 + new->fl_file = fl->fl_file;
11188 + new->fl_ops = fl->fl_ops;
11189 + new->fl_lmops = fl->fl_lmops;
11190 ++ new->fl_xid = fl->fl_xid;
11191 +
11192 + locks_copy_private(new, fl);
11193 + }
11194 +@@ -282,6 +289,11 @@ static int flock_make_lock(struct file *
11195 + fl->fl_flags = FL_FLOCK;
11196 + fl->fl_type = type;
11197 + fl->fl_end = OFFSET_MAX;
11198 ++
11199 ++ vxd_assert(filp->f_xid == vx_current_xid(),
11200 ++ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
11201 ++ fl->fl_xid = filp->f_xid;
11202 ++ vx_locks_inc(fl);
11203 +
11204 + *lock = fl;
11205 + return 0;
11206 +@@ -447,6 +459,7 @@ static int lease_init(struct file *filp,
11207 +
11208 + fl->fl_owner = current->files;
11209 + fl->fl_pid = current->tgid;
11210 ++ fl->fl_xid = vx_current_xid();
11211 +
11212 + fl->fl_file = filp;
11213 + fl->fl_flags = FL_LEASE;
11214 +@@ -466,6 +479,11 @@ static int lease_alloc(struct file *filp
11215 + if (fl == NULL)
11216 + goto out;
11217 +
11218 ++ fl->fl_xid = vx_current_xid();
11219 ++ if (filp)
11220 ++ vxd_assert(filp->f_xid == fl->fl_xid,
11221 ++ "f_xid(%d) == fl_xid(%d)", filp->f_xid, fl->fl_xid);
11222 ++ vx_locks_inc(fl);
11223 + error = lease_init(filp, type, fl);
11224 + if (error) {
11225 + locks_free_lock(fl);
11226 +@@ -769,6 +787,7 @@ static int flock_lock_file(struct file *
11227 + if (found)
11228 + cond_resched();
11229 +
11230 ++ new_fl->fl_xid = -1;
11231 + find_conflict:
11232 + for_each_lock(inode, before) {
11233 + struct file_lock *fl = *before;
11234 +@@ -787,6 +806,7 @@ find_conflict:
11235 + goto out;
11236 + locks_copy_lock(new_fl, request);
11237 + locks_insert_lock(before, new_fl);
11238 ++ vx_locks_inc(new_fl);
11239 + new_fl = NULL;
11240 + error = 0;
11241 +
11242 +@@ -797,7 +817,8 @@ out:
11243 + return error;
11244 + }
11245 +
11246 +-static int __posix_lock_file(struct inode *inode, struct file_lock *request, struct file_lock *conflock)
11247 ++static int __posix_lock_file(struct inode *inode, struct file_lock *request,
11248 ++ struct file_lock *conflock, xid_t xid)
11249 + {
11250 + struct file_lock *fl;
11251 + struct file_lock *new_fl = NULL;
11252 +@@ -807,6 +828,8 @@ static int __posix_lock_file(struct inod
11253 + struct file_lock **before;
11254 + int error, added = 0;
11255 +
11256 ++ vxd_assert(xid == vx_current_xid(),
11257 ++ "xid(%d) == current(%d)", xid, vx_current_xid());
11258 + /*
11259 + * We may need two file_lock structures for this operation,
11260 + * so we get them in advance to avoid races.
11261 +@@ -817,7 +840,11 @@ static int __posix_lock_file(struct inod
11262 + (request->fl_type != F_UNLCK ||
11263 + request->fl_start != 0 || request->fl_end != OFFSET_MAX)) {
11264 + new_fl = locks_alloc_lock();
11265 ++ new_fl->fl_xid = xid;
11266 ++ vx_locks_inc(new_fl);
11267 + new_fl2 = locks_alloc_lock();
11268 ++ new_fl2->fl_xid = xid;
11269 ++ vx_locks_inc(new_fl2);
11270 + }
11271 +
11272 + lock_kernel();
11273 +@@ -1016,7 +1043,8 @@ static int __posix_lock_file(struct inod
11274 + int posix_lock_file(struct file *filp, struct file_lock *fl,
11275 + struct file_lock *conflock)
11276 + {
11277 +- return __posix_lock_file(filp->f_path.dentry->d_inode, fl, conflock);
11278 ++ return __posix_lock_file(filp->f_path.dentry->d_inode,
11279 ++ fl, conflock, filp->f_xid);
11280 + }
11281 + EXPORT_SYMBOL(posix_lock_file);
11282 +
11283 +@@ -1106,7 +1134,7 @@ int locks_mandatory_area(int read_write,
11284 + fl.fl_end = offset + count - 1;
11285 +
11286 + for (;;) {
11287 +- error = __posix_lock_file(inode, &fl, NULL);
11288 ++ error = __posix_lock_file(inode, &fl, NULL, filp->f_xid);
11289 + if (error != -EAGAIN)
11290 + break;
11291 + if (!(fl.fl_flags & FL_SLEEP))
11292 +@@ -1410,8 +1438,8 @@ static int __setlease(struct file *filp,
11293 + goto out;
11294 +
11295 + locks_copy_lock(fl, lease);
11296 +-
11297 + locks_insert_lock(before, fl);
11298 ++ vx_locks_inc(fl);
11299 +
11300 + *flp = fl;
11301 + error = 0;
11302 +@@ -1738,6 +1766,11 @@ int fcntl_setlk(unsigned int fd, struct
11303 + if (file_lock == NULL)
11304 + return -ENOLCK;
11305 +
11306 ++ vxd_assert(filp->f_xid == vx_current_xid(),
11307 ++ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
11308 ++ file_lock->fl_xid = filp->f_xid;
11309 ++ vx_locks_inc(file_lock);
11310 ++
11311 + /*
11312 + * This might block, so we do it before checking the inode.
11313 + */
11314 +@@ -1864,6 +1897,11 @@ int fcntl_setlk64(unsigned int fd, struc
11315 + if (file_lock == NULL)
11316 + return -ENOLCK;
11317 +
11318 ++ vxd_assert(filp->f_xid == vx_current_xid(),
11319 ++ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
11320 ++ file_lock->fl_xid = filp->f_xid;
11321 ++ vx_locks_inc(file_lock);
11322 ++
11323 + /*
11324 + * This might block, so we do it before checking the inode.
11325 + */
11326 +@@ -2168,6 +2206,10 @@ int get_locks_status(char *buffer, char
11327 + list_for_each(tmp, &file_lock_list) {
11328 + struct list_head *btmp;
11329 + struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);
11330 ++
11331 ++ if (!vx_check(fl->fl_xid, VS_WATCH_P | VS_IDENT))
11332 ++ continue;
11333 ++
11334 + lock_get_status(q, fl, ++i, "");
11335 + move_lock_status(&q, &pos, offset);
11336 +
11337 +diff -NurpP --minimal linux-2.6.22.19/fs/namei.c linux-2.6.22.19-vs2.3.0.34/fs/namei.c
11338 +--- linux-2.6.22.19/fs/namei.c 2008-03-14 20:19:03 +0100
11339 ++++ linux-2.6.22.19-vs2.3.0.34/fs/namei.c 2008-01-18 12:45:05 +0100
11340 +@@ -31,6 +31,13 @@
11341 + #include <linux/file.h>
11342 + #include <linux/fcntl.h>
11343 + #include <linux/namei.h>
11344 ++#include <linux/proc_fs.h>
11345 ++#include <linux/vserver/inode.h>
11346 ++#include <linux/vs_base.h>
11347 ++#include <linux/vs_tag.h>
11348 ++#include <linux/vs_cowbl.h>
11349 ++#include <linux/vs_device.h>
11350 ++#include <linux/vs_context.h>
11351 + #include <asm/namei.h>
11352 + #include <asm/uaccess.h>
11353 +
11354 +@@ -224,6 +231,28 @@ int generic_permission(struct inode *ino
11355 + return -EACCES;
11356 + }
11357 +
11358 ++static inline int dx_barrier(struct inode *inode)
11359 ++{
11360 ++ if (IS_BARRIER(inode) && !vx_check(0, VS_ADMIN)) {
11361 ++ vxwprintk_task(1, "did hit the barrier.");
11362 ++ return 1;
11363 ++ }
11364 ++ return 0;
11365 ++}
11366 ++
11367 ++static inline int dx_permission(struct inode *inode, int mask, struct nameidata *nd)
11368 ++{
11369 ++ if (dx_barrier(inode))
11370 ++ return -EACCES;
11371 ++ if (dx_notagcheck(nd) ||
11372 ++ dx_check(inode->i_tag, DX_HOSTID|DX_ADMIN|DX_WATCH|DX_IDENT))
11373 ++ return 0;
11374 ++
11375 ++ vxwprintk_task(1, "denied access to %p[#%d,%lu] »%s«.",
11376 ++ inode, inode->i_tag, inode->i_ino, vxd_cond_path(nd));
11377 ++ return -EACCES;
11378 ++}
11379 ++
11380 + int permission(struct inode *inode, int mask, struct nameidata *nd)
11381 + {
11382 + umode_t mode = inode->i_mode;
11383 +@@ -234,14 +263,14 @@ int permission(struct inode *inode, int
11384 + /*
11385 + * Nobody gets write access to a read-only fs.
11386 + */
11387 +- if (IS_RDONLY(inode) &&
11388 ++ if ((IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))) &&
11389 + (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
11390 + return -EROFS;
11391 +
11392 + /*
11393 + * Nobody gets write access to an immutable file.
11394 + */
11395 +- if (IS_IMMUTABLE(inode))
11396 ++ if (IS_IMMUTABLE(inode) && !IS_COW(inode))
11397 + return -EACCES;
11398 + }
11399 +
11400 +@@ -257,6 +286,12 @@ int permission(struct inode *inode, int
11401 +
11402 + /* Ordinary permission routines do not understand MAY_APPEND. */
11403 + submask = mask & ~MAY_APPEND;
11404 ++
11405 ++ if ((inode->i_sb->s_magic != DEVPTS_SUPER_MAGIC) &&
11406 ++ (inode->i_sb->s_magic != PROC_SUPER_MAGIC) &&
11407 ++ (retval = dx_permission(inode, mask, nd)))
11408 ++ return retval;
11409 ++
11410 + if (inode->i_op && inode->i_op->permission)
11411 + retval = inode->i_op->permission(inode, submask, nd);
11412 + else
11413 +@@ -432,6 +467,8 @@ static int exec_permission_lite(struct i
11414 + {
11415 + umode_t mode = inode->i_mode;
11416 +
11417 ++ if (dx_barrier(inode))
11418 ++ return -EACCES;
11419 + if (inode->i_op && inode->i_op->permission)
11420 + return -EAGAIN;
11421 +
11422 +@@ -732,7 +769,8 @@ static __always_inline void follow_dotdo
11423 + if (nd->dentry == fs->root &&
11424 + nd->mnt == fs->rootmnt) {
11425 + read_unlock(&fs->lock);
11426 +- break;
11427 ++ /* for sane '/' avoid follow_mount() */
11428 ++ return;
11429 + }
11430 + read_unlock(&fs->lock);
11431 + spin_lock(&dcache_lock);
11432 +@@ -769,16 +807,39 @@ static int do_lookup(struct nameidata *n
11433 + {
11434 + struct vfsmount *mnt = nd->mnt;
11435 + struct dentry *dentry = __d_lookup(nd->dentry, name);
11436 ++ struct inode *inode;
11437 +
11438 + if (!dentry)
11439 + goto need_lookup;
11440 + if (dentry->d_op && dentry->d_op->d_revalidate)
11441 + goto need_revalidate;
11442 ++ inode = dentry->d_inode;
11443 ++ if (!inode)
11444 ++ goto done;
11445 ++
11446 ++ if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) {
11447 ++ struct proc_dir_entry *de = PDE(inode);
11448 ++
11449 ++ if (de && !vx_hide_check(0, de->vx_flags))
11450 ++ goto hidden;
11451 ++ } else if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) {
11452 ++ if (!vx_check((xid_t)inode->i_tag, VS_WATCH_P | VS_IDENT))
11453 ++ goto hidden;
11454 ++ } else {
11455 ++ if (!dx_notagcheck(nd) && !dx_check(inode->i_tag,
11456 ++ DX_WATCH | DX_ADMIN | DX_HOSTID | DX_IDENT))
11457 ++ goto hidden;
11458 ++ }
11459 + done:
11460 + path->mnt = mnt;
11461 + path->dentry = dentry;
11462 + __follow_mount(path);
11463 + return 0;
11464 ++hidden:
11465 ++ vxwprintk_task(1, "did lookup hidden %p[#%d,%lu] »%s«.",
11466 ++ inode, inode->i_tag, inode->i_ino, vxd_path(dentry, mnt));
11467 ++ dput(dentry);
11468 ++ return -ENOENT;
11469 +
11470 + need_lookup:
11471 + dentry = real_lookup(nd->dentry, name, nd);
11472 +@@ -1399,7 +1460,8 @@ static inline int check_sticky(struct in
11473 + * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
11474 + * nfs_async_unlink().
11475 + */
11476 +-static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
11477 ++static int may_delete(struct inode *dir, struct dentry *victim,
11478 ++ int isdir, struct nameidata *nd)
11479 + {
11480 + int error;
11481 +
11482 +@@ -1409,13 +1471,13 @@ static int may_delete(struct inode *dir,
11483 + BUG_ON(victim->d_parent->d_inode != dir);
11484 + audit_inode_child(victim->d_name.name, victim->d_inode, dir);
11485 +
11486 +- error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
11487 ++ error = permission(dir,MAY_WRITE | MAY_EXEC, nd);
11488 + if (error)
11489 + return error;
11490 + if (IS_APPEND(dir))
11491 + return -EPERM;
11492 + if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
11493 +- IS_IMMUTABLE(victim->d_inode))
11494 ++ IS_IXORUNLINK(victim->d_inode))
11495 + return -EPERM;
11496 + if (isdir) {
11497 + if (!S_ISDIR(victim->d_inode->i_mode))
11498 +@@ -1546,6 +1608,14 @@ int may_open(struct nameidata *nd, int a
11499 + if (S_ISDIR(inode->i_mode) && (acc_mode & MAY_WRITE))
11500 + return -EISDIR;
11501 +
11502 ++#ifdef CONFIG_VSERVER_COWBL
11503 ++ if (IS_COW(inode) && (acc_mode & MAY_WRITE)) {
11504 ++ if (IS_COW_LINK(inode))
11505 ++ return -EMLINK;
11506 ++ inode->i_flags &= ~(S_IUNLINK|S_IMMUTABLE);
11507 ++ mark_inode_dirty(inode);
11508 ++ }
11509 ++#endif
11510 + error = vfs_permission(nd, acc_mode);
11511 + if (error)
11512 + return error;
11513 +@@ -1562,7 +1632,8 @@ int may_open(struct nameidata *nd, int a
11514 + return -EACCES;
11515 +
11516 + flag &= ~O_TRUNC;
11517 +- } else if (IS_RDONLY(inode) && (acc_mode & MAY_WRITE))
11518 ++ } else if ((IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt))
11519 ++ && (acc_mode & MAY_WRITE))
11520 + return -EROFS;
11521 + /*
11522 + * An append-only file must be opened in append mode for writing.
11523 +@@ -1650,6 +1721,11 @@ int open_namei(int dfd, const char *path
11524 + struct dentry *dir;
11525 + int count = 0;
11526 +
11527 ++#ifdef CONFIG_VSERVER_COWBL
11528 ++ int rflag = flag;
11529 ++ int rmode = mode;
11530 ++restart:
11531 ++#endif
11532 + acc_mode = ACC_MODE(flag);
11533 +
11534 + /* O_TRUNC implies we need access checks for write permissions */
11535 +@@ -1743,6 +1819,22 @@ do_last:
11536 + goto exit;
11537 + ok:
11538 + error = may_open(nd, acc_mode, flag);
11539 ++#ifdef CONFIG_VSERVER_COWBL
11540 ++ if (error == -EMLINK) {
11541 ++ struct dentry *dentry;
11542 ++ dentry = cow_break_link(pathname);
11543 ++ if (IS_ERR(dentry)) {
11544 ++ error = PTR_ERR(dentry);
11545 ++ goto exit;
11546 ++ }
11547 ++ dput(dentry);
11548 ++ release_open_intent(nd);
11549 ++ path_release(nd);
11550 ++ flag = rflag;
11551 ++ mode = rmode;
11552 ++ goto restart;
11553 ++ }
11554 ++#endif
11555 + if (error)
11556 + goto exit;
11557 + return 0;
11558 +@@ -1854,16 +1946,25 @@ fail:
11559 + }
11560 + EXPORT_SYMBOL_GPL(lookup_create);
11561 +
11562 +-int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
11563 ++int vfs_mknod(struct inode *dir, struct dentry *dentry,
11564 ++ int mode, dev_t dev, struct nameidata *nd)
11565 + {
11566 +- int error = may_create(dir, dentry, NULL);
11567 ++ int error = may_create(dir, dentry, nd);
11568 +
11569 + if (error)
11570 + return error;
11571 +
11572 +- if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD))
11573 ++ if (!(S_ISCHR(mode) || S_ISBLK(mode)))
11574 ++ goto okay;
11575 ++
11576 ++ if (!capable(CAP_MKNOD))
11577 + return -EPERM;
11578 +
11579 ++ if (S_ISCHR(mode) && !vs_chrdev_perm(dev, DATTR_CREATE))
11580 ++ return -EPERM;
11581 ++ if (S_ISBLK(mode) && !vs_blkdev_perm(dev, DATTR_CREATE))
11582 ++ return -EPERM;
11583 ++okay:
11584 + if (!dir->i_op || !dir->i_op->mknod)
11585 + return -EPERM;
11586 +
11587 +@@ -1906,11 +2007,12 @@ asmlinkage long sys_mknodat(int dfd, con
11588 + error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
11589 + break;
11590 + case S_IFCHR: case S_IFBLK:
11591 +- error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
11592 +- new_decode_dev(dev));
11593 ++ error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
11594 ++ new_decode_dev(dev), &nd);
11595 + break;
11596 + case S_IFIFO: case S_IFSOCK:
11597 +- error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
11598 ++ error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
11599 ++ 0, &nd);
11600 + break;
11601 + case S_IFDIR:
11602 + error = -EPERM;
11603 +@@ -1933,9 +2035,10 @@ asmlinkage long sys_mknod(const char __u
11604 + return sys_mknodat(AT_FDCWD, filename, mode, dev);
11605 + }
11606 +
11607 +-int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
11608 ++int vfs_mkdir(struct inode *dir, struct dentry *dentry,
11609 ++ int mode, struct nameidata *nd)
11610 + {
11611 +- int error = may_create(dir, dentry, NULL);
11612 ++ int error = may_create(dir, dentry, nd);
11613 +
11614 + if (error)
11615 + return error;
11616 +@@ -1977,7 +2080,7 @@ asmlinkage long sys_mkdirat(int dfd, con
11617 +
11618 + if (!IS_POSIXACL(nd.dentry->d_inode))
11619 + mode &= ~current->fs->umask;
11620 +- error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
11621 ++ error = vfs_mkdir(nd.dentry->d_inode, dentry, mode, &nd);
11622 + dput(dentry);
11623 + out_unlock:
11624 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
11625 +@@ -2020,9 +2123,10 @@ void dentry_unhash(struct dentry *dentry
11626 + spin_unlock(&dcache_lock);
11627 + }
11628 +
11629 +-int vfs_rmdir(struct inode *dir, struct dentry *dentry)
11630 ++int vfs_rmdir(struct inode *dir, struct dentry *dentry,
11631 ++ struct nameidata *nd)
11632 + {
11633 +- int error = may_delete(dir, dentry, 1);
11634 ++ int error = may_delete(dir, dentry, 1, nd);
11635 +
11636 + if (error)
11637 + return error;
11638 +@@ -2084,7 +2188,7 @@ static long do_rmdir(int dfd, const char
11639 + error = PTR_ERR(dentry);
11640 + if (IS_ERR(dentry))
11641 + goto exit2;
11642 +- error = vfs_rmdir(nd.dentry->d_inode, dentry);
11643 ++ error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
11644 + dput(dentry);
11645 + exit2:
11646 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
11647 +@@ -2100,9 +2204,10 @@ asmlinkage long sys_rmdir(const char __u
11648 + return do_rmdir(AT_FDCWD, pathname);
11649 + }
11650 +
11651 +-int vfs_unlink(struct inode *dir, struct dentry *dentry)
11652 ++int vfs_unlink(struct inode *dir, struct dentry *dentry,
11653 ++ struct nameidata *nd)
11654 + {
11655 +- int error = may_delete(dir, dentry, 0);
11656 ++ int error = may_delete(dir, dentry, 0, nd);
11657 +
11658 + if (error)
11659 + return error;
11660 +@@ -2164,7 +2269,7 @@ static long do_unlinkat(int dfd, const c
11661 + inode = dentry->d_inode;
11662 + if (inode)
11663 + atomic_inc(&inode->i_count);
11664 +- error = vfs_unlink(nd.dentry->d_inode, dentry);
11665 ++ error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
11666 + exit2:
11667 + dput(dentry);
11668 + }
11669 +@@ -2199,9 +2304,10 @@ asmlinkage long sys_unlink(const char __
11670 + return do_unlinkat(AT_FDCWD, pathname);
11671 + }
11672 +
11673 +-int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)
11674 ++int vfs_symlink(struct inode *dir, struct dentry *dentry,
11675 ++ const char *oldname, int mode, struct nameidata *nd)
11676 + {
11677 +- int error = may_create(dir, dentry, NULL);
11678 ++ int error = may_create(dir, dentry, nd);
11679 +
11680 + if (error)
11681 + return error;
11682 +@@ -2245,7 +2351,7 @@ asmlinkage long sys_symlinkat(const char
11683 + if (IS_ERR(dentry))
11684 + goto out_unlock;
11685 +
11686 +- error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
11687 ++ error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO, &nd);
11688 + dput(dentry);
11689 + out_unlock:
11690 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
11691 +@@ -2262,7 +2368,8 @@ asmlinkage long sys_symlink(const char _
11692 + return sys_symlinkat(oldname, AT_FDCWD, newname);
11693 + }
11694 +
11695 +-int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
11696 ++int vfs_link(struct dentry *old_dentry, struct inode *dir,
11697 ++ struct dentry *new_dentry, struct nameidata *nd)
11698 + {
11699 + struct inode *inode = old_dentry->d_inode;
11700 + int error;
11701 +@@ -2270,7 +2377,7 @@ int vfs_link(struct dentry *old_dentry,
11702 + if (!inode)
11703 + return -ENOENT;
11704 +
11705 +- error = may_create(dir, new_dentry, NULL);
11706 ++ error = may_create(dir, new_dentry, nd);
11707 + if (error)
11708 + return error;
11709 +
11710 +@@ -2280,7 +2387,7 @@ int vfs_link(struct dentry *old_dentry,
11711 + /*
11712 + * A link to an append-only or immutable file cannot be created.
11713 + */
11714 +- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
11715 ++ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
11716 + return -EPERM;
11717 + if (!dir->i_op || !dir->i_op->link)
11718 + return -EPERM;
11719 +@@ -2340,7 +2447,7 @@ asmlinkage long sys_linkat(int olddfd, c
11720 + error = PTR_ERR(new_dentry);
11721 + if (IS_ERR(new_dentry))
11722 + goto out_unlock;
11723 +- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
11724 ++ error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry, &nd);
11725 + dput(new_dentry);
11726 + out_unlock:
11727 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
11728 +@@ -2472,14 +2579,14 @@ int vfs_rename(struct inode *old_dir, st
11729 + if (old_dentry->d_inode == new_dentry->d_inode)
11730 + return 0;
11731 +
11732 +- error = may_delete(old_dir, old_dentry, is_dir);
11733 ++ error = may_delete(old_dir, old_dentry, is_dir, NULL);
11734 + if (error)
11735 + return error;
11736 +
11737 + if (!new_dentry->d_inode)
11738 + error = may_create(new_dir, new_dentry, NULL);
11739 + else
11740 +- error = may_delete(new_dir, new_dentry, is_dir);
11741 ++ error = may_delete(new_dir, new_dentry, is_dir, NULL);
11742 + if (error)
11743 + return error;
11744 +
11745 +@@ -2557,6 +2664,9 @@ static int do_rename(int olddfd, const c
11746 + error = -EINVAL;
11747 + if (old_dentry == trap)
11748 + goto exit4;
11749 ++ error = -EROFS;
11750 ++ if (MNT_IS_RDONLY(newnd.mnt))
11751 ++ goto exit4;
11752 + new_dentry = lookup_hash(&newnd);
11753 + error = PTR_ERR(new_dentry);
11754 + if (IS_ERR(new_dentry))
11755 +@@ -2650,6 +2760,216 @@ int vfs_follow_link(struct nameidata *nd
11756 + return __vfs_follow_link(nd, link);
11757 + }
11758 +
11759 ++
11760 ++#ifdef CONFIG_VSERVER_COWBL
11761 ++
11762 ++#include <linux/file.h>
11763 ++
11764 ++static inline
11765 ++long do_cow_splice(struct file *in, struct file *out, size_t len)
11766 ++{
11767 ++ loff_t ppos = 0;
11768 ++
11769 ++ return do_splice_direct(in, &ppos, out, len, 0);
11770 ++}
11771 ++
11772 ++struct dentry *cow_break_link(const char *pathname)
11773 ++{
11774 ++ int ret, mode, pathlen, redo = 0;
11775 ++ struct nameidata old_nd, dir_nd;
11776 ++ struct dentry *old_dentry, *new_dentry;
11777 ++ struct dentry *dir, *res = NULL;
11778 ++ struct vfsmount *old_mnt, *new_mnt;
11779 ++ struct file *old_file;
11780 ++ struct file *new_file;
11781 ++ char *to, *path, pad='\251';
11782 ++ loff_t size;
11783 ++
11784 ++ vxdprintk(VXD_CBIT(misc, 1), "cow_break_link(»%s«)", pathname);
11785 ++ path = kmalloc(PATH_MAX, GFP_KERNEL);
11786 ++ ret = -ENOMEM;
11787 ++ if (!path)
11788 ++ goto out;
11789 ++
11790 ++ /* old_nd will have refs to dentry and mnt */
11791 ++ ret = path_lookup(pathname, LOOKUP_FOLLOW, &old_nd);
11792 ++ vxdprintk(VXD_CBIT(misc, 2), "path_lookup(old): %d", ret);
11793 ++ if (ret < 0)
11794 ++ goto out_free_path;
11795 ++
11796 ++ old_dentry = old_nd.dentry;
11797 ++ old_mnt = old_nd.mnt;
11798 ++ mode = old_dentry->d_inode->i_mode;
11799 ++
11800 ++ to = d_path(old_dentry, old_mnt, path, PATH_MAX-2);
11801 ++ pathlen = strlen(to);
11802 ++ vxdprintk(VXD_CBIT(misc, 2), "old path »%s« [»%.*s«:%d]", to,
11803 ++ old_dentry->d_name.len, old_dentry->d_name.name,
11804 ++ old_dentry->d_name.len);
11805 ++
11806 ++ to[pathlen + 1] = 0;
11807 ++retry:
11808 ++ to[pathlen] = pad--;
11809 ++ ret = -EMLINK;
11810 ++ if (pad <= '\240')
11811 ++ goto out_rel_old;
11812 ++
11813 ++ vxdprintk(VXD_CBIT(misc, 1), "temp copy »%s«", to);
11814 ++ /* dir_nd will have refs to dentry and mnt */
11815 ++ ret = path_lookup(to,
11816 ++ LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE, &dir_nd);
11817 ++ vxdprintk(VXD_CBIT(misc, 2),
11818 ++ "path_lookup(new): %d", ret);
11819 ++ if (ret < 0)
11820 ++ goto retry;
11821 ++
11822 ++ /* this puppy downs the inode mutex */
11823 ++ new_dentry = lookup_create(&dir_nd, 0);
11824 ++ vxdprintk(VXD_CBIT(misc, 2),
11825 ++ "lookup_create(new): %p [»%.*s«:%d]", new_dentry,
11826 ++ new_dentry->d_name.len, new_dentry->d_name.name,
11827 ++ new_dentry->d_name.len);
11828 ++ if (!new_dentry || IS_ERR(new_dentry)) {
11829 ++ path_release(&dir_nd);
11830 ++ goto retry;
11831 ++ }
11832 ++ dir = dir_nd.dentry;
11833 ++
11834 ++ ret = vfs_create(dir_nd.dentry->d_inode, new_dentry, mode, &dir_nd);
11835 ++ vxdprintk(VXD_CBIT(misc, 2),
11836 ++ "vfs_create(new): %d", ret);
11837 ++ if (ret == -EEXIST) {
11838 ++ mutex_unlock(&dir->d_inode->i_mutex);
11839 ++ dput(new_dentry);
11840 ++ path_release(&dir_nd);
11841 ++ goto retry;
11842 ++ }
11843 ++ else if (ret < 0)
11844 ++ goto out_unlock_new;
11845 ++
11846 ++ /* drop out early, ret passes ENOENT */
11847 ++ ret = -ENOENT;
11848 ++ if ((redo = d_unhashed(old_dentry)))
11849 ++ goto out_unlock_new;
11850 ++
11851 ++ new_mnt = dir_nd.mnt;
11852 ++ dget(old_dentry);
11853 ++ mntget(old_mnt);
11854 ++ /* this one cleans up the dentry/mnt in case of failure */
11855 ++ old_file = dentry_open(old_dentry, old_mnt, O_RDONLY);
11856 ++ vxdprintk(VXD_CBIT(misc, 2),
11857 ++ "dentry_open(old): %p", old_file);
11858 ++ if (!old_file || IS_ERR(old_file)) {
11859 ++ res = IS_ERR(old_file) ? (void *) old_file : res;
11860 ++ goto out_unlock_new;
11861 ++ }
11862 ++
11863 ++ dget(new_dentry);
11864 ++ mntget(new_mnt);
11865 ++ /* this one cleans up the dentry/mnt in case of failure */
11866 ++ new_file = dentry_open(new_dentry, new_mnt, O_WRONLY);
11867 ++ vxdprintk(VXD_CBIT(misc, 2),
11868 ++ "dentry_open(new): %p", new_file);
11869 ++
11870 ++ ret = IS_ERR(new_file) ? PTR_ERR(new_file) : -ENOENT;
11871 ++ if (!new_file || IS_ERR(new_file))
11872 ++ goto out_fput_old;
11873 ++
11874 ++ size = i_size_read(old_file->f_dentry->d_inode);
11875 ++ ret = do_cow_splice(old_file, new_file, size);
11876 ++ vxdprintk(VXD_CBIT(misc, 2), "do_splice_direct: %d", ret);
11877 ++ if (ret < 0) {
11878 ++ goto out_fput_both;
11879 ++ } else if (ret < size) {
11880 ++ ret = -ENOSPC;
11881 ++ goto out_fput_both;
11882 ++ } else {
11883 ++ struct inode *old_inode = old_dentry->d_inode;
11884 ++ struct inode *new_inode = new_dentry->d_inode;
11885 ++ struct iattr attr = {
11886 ++ .ia_uid = old_inode->i_uid,
11887 ++ .ia_gid = old_inode->i_gid,
11888 ++ .ia_valid = ATTR_UID | ATTR_GID
11889 ++ };
11890 ++
11891 ++ ret = inode_setattr(new_inode, &attr);
11892 ++ if (ret)
11893 ++ goto out_fput_both;
11894 ++ }
11895 ++
11896 ++ mutex_lock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
11897 ++
11898 ++ /* drop out late */
11899 ++ ret = -ENOENT;
11900 ++ if ((redo = d_unhashed(old_dentry)))
11901 ++ goto out_unlock;
11902 ++
11903 ++ vxdprintk(VXD_CBIT(misc, 2),
11904 ++ "vfs_rename: [»%*s«:%d] -> [»%*s«:%d]",
11905 ++ new_dentry->d_name.len, new_dentry->d_name.name,
11906 ++ new_dentry->d_name.len,
11907 ++ old_dentry->d_name.len, old_dentry->d_name.name,
11908 ++ old_dentry->d_name.len);
11909 ++ ret = vfs_rename(dir_nd.dentry->d_inode, new_dentry,
11910 ++ old_nd.dentry->d_parent->d_inode, old_dentry);
11911 ++ vxdprintk(VXD_CBIT(misc, 2), "vfs_rename: %d", ret);
11912 ++ res = new_dentry;
11913 ++
11914 ++out_unlock:
11915 ++ mutex_unlock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
11916 ++
11917 ++out_fput_both:
11918 ++ vxdprintk(VXD_CBIT(misc, 3),
11919 ++ "fput(new_file=%p[#%d])", new_file,
11920 ++ atomic_read(&new_file->f_count));
11921 ++ fput(new_file);
11922 ++
11923 ++out_fput_old:
11924 ++ vxdprintk(VXD_CBIT(misc, 3),
11925 ++ "fput(old_file=%p[#%d])", old_file,
11926 ++ atomic_read(&old_file->f_count));
11927 ++ fput(old_file);
11928 ++
11929 ++out_unlock_new:
11930 ++ mutex_unlock(&dir->d_inode->i_mutex);
11931 ++ if (!ret)
11932 ++ goto out_redo;
11933 ++
11934 ++ /* error path cleanup */
11935 ++ vfs_unlink(dir->d_inode, new_dentry, &dir_nd);
11936 ++ dput(new_dentry);
11937 ++
11938 ++out_redo:
11939 ++ if (!redo)
11940 ++ goto out_rel_both;
11941 ++ /* lookup dentry once again */
11942 ++ path_release(&old_nd);
11943 ++ ret = path_lookup(pathname, LOOKUP_FOLLOW, &old_nd);
11944 ++ if (ret)
11945 ++ goto out_rel_both;
11946 ++
11947 ++ new_dentry = old_nd.dentry;
11948 ++ vxdprintk(VXD_CBIT(misc, 2),
11949 ++ "path_lookup(redo): %p [»%.*s«:%d]", new_dentry,
11950 ++ new_dentry->d_name.len, new_dentry->d_name.name,
11951 ++ new_dentry->d_name.len);
11952 ++ dget(new_dentry);
11953 ++ res = new_dentry;
11954 ++
11955 ++out_rel_both:
11956 ++ path_release(&dir_nd);
11957 ++out_rel_old:
11958 ++ path_release(&old_nd);
11959 ++out_free_path:
11960 ++ kfree(path);
11961 ++out:
11962 ++ if (ret)
11963 ++ res = ERR_PTR(ret);
11964 ++ return res;
11965 ++}
11966 ++
11967 ++#endif
11968 ++
11969 + /* get the link contents into pagecache */
11970 + static char *page_getlink(struct dentry * dentry, struct page **ppage)
11971 + {
11972 +diff -NurpP --minimal linux-2.6.22.19/fs/namespace.c linux-2.6.22.19-vs2.3.0.34/fs/namespace.c
11973 +--- linux-2.6.22.19/fs/namespace.c 2007-07-09 13:19:27 +0200
11974 ++++ linux-2.6.22.19-vs2.3.0.34/fs/namespace.c 2007-09-05 02:29:17 +0200
11975 +@@ -25,6 +25,11 @@
11976 + #include <linux/security.h>
11977 + #include <linux/mount.h>
11978 + #include <linux/ramfs.h>
11979 ++#include <linux/vs_base.h>
11980 ++#include <linux/vs_context.h>
11981 ++#include <linux/vs_tag.h>
11982 ++#include <linux/vserver/space.h>
11983 ++#include <linux/vserver/global.h>
11984 + #include <asm/uaccess.h>
11985 + #include <asm/unistd.h>
11986 + #include "pnode.h"
11987 +@@ -240,6 +245,7 @@ static struct vfsmount *clone_mnt(struct
11988 + mnt->mnt_root = dget(root);
11989 + mnt->mnt_mountpoint = mnt->mnt_root;
11990 + mnt->mnt_parent = mnt;
11991 ++ mnt->mnt_tag = old->mnt_tag;
11992 +
11993 + if (flag & CL_SLAVE) {
11994 + list_add(&mnt->mnt_slave, &old->mnt_slave_list);
11995 +@@ -348,48 +354,91 @@ static inline void mangle(struct seq_fil
11996 + seq_escape(m, s, " \t\n\\");
11997 + }
11998 +
11999 ++static int mnt_is_reachable(struct vfsmount *mnt)
12000 ++{
12001 ++ struct vfsmount *root_mnt;
12002 ++ struct dentry *root, *point;
12003 ++ int ret;
12004 ++
12005 ++ if (mnt == mnt->mnt_ns->root)
12006 ++ return 1;
12007 ++
12008 ++ spin_lock(&vfsmount_lock);
12009 ++ root_mnt = current->fs->rootmnt;
12010 ++ root = current->fs->root;
12011 ++ point = root;
12012 ++
12013 ++ while ((mnt != mnt->mnt_parent) && (mnt != root_mnt)) {
12014 ++ point = mnt->mnt_mountpoint;
12015 ++ mnt = mnt->mnt_parent;
12016 ++ }
12017 ++
12018 ++ ret = (mnt == root_mnt) && is_subdir(point, root);
12019 ++
12020 ++ spin_unlock(&vfsmount_lock);
12021 ++
12022 ++ return ret;
12023 ++}
12024 ++
12025 + static int show_vfsmnt(struct seq_file *m, void *v)
12026 + {
12027 + struct vfsmount *mnt = v;
12028 + int err = 0;
12029 + static struct proc_fs_info {
12030 +- int flag;
12031 +- char *str;
12032 ++ int s_flag;
12033 ++ int mnt_flag;
12034 ++ char *set_str;
12035 ++ char *unset_str;
12036 + } fs_info[] = {
12037 +- { MS_SYNCHRONOUS, ",sync" },
12038 +- { MS_DIRSYNC, ",dirsync" },
12039 +- { MS_MANDLOCK, ",mand" },
12040 +- { 0, NULL }
12041 +- };
12042 +- static struct proc_fs_info mnt_info[] = {
12043 +- { MNT_NOSUID, ",nosuid" },
12044 +- { MNT_NODEV, ",nodev" },
12045 +- { MNT_NOEXEC, ",noexec" },
12046 +- { MNT_NOATIME, ",noatime" },
12047 +- { MNT_NODIRATIME, ",nodiratime" },
12048 +- { MNT_RELATIME, ",relatime" },
12049 +- { 0, NULL }
12050 ++ { MS_RDONLY, MNT_RDONLY, "ro", "rw" },
12051 ++ { MS_SYNCHRONOUS, 0, ",sync", NULL },
12052 ++ { MS_DIRSYNC, 0, ",dirsync", NULL },
12053 ++ { MS_MANDLOCK, 0, ",mand", NULL },
12054 ++ { MS_TAGGED, 0, ",tag", NULL },
12055 ++ { MS_NOATIME, MNT_NOATIME, ",noatime", NULL },
12056 ++ { MS_NODIRATIME, MNT_NODIRATIME, ",nodiratime", NULL },
12057 ++ { MS_RELATIME, MNT_RELATIME, ",relatime", NULL },
12058 ++ { 0, MNT_NOSUID, ",nosuid", NULL },
12059 ++ { 0, MNT_NODEV, ",nodev", NULL },
12060 ++ { 0, MNT_NOEXEC, ",noexec", NULL },
12061 ++ { 0, 0, NULL, NULL }
12062 + };
12063 +- struct proc_fs_info *fs_infop;
12064 ++ struct proc_fs_info *p;
12065 ++ unsigned long s_flags = mnt->mnt_sb->s_flags;
12066 ++ int mnt_flags = mnt->mnt_flags;
12067 +
12068 +- mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
12069 +- seq_putc(m, ' ');
12070 +- seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
12071 +- seq_putc(m, ' ');
12072 +- mangle(m, mnt->mnt_sb->s_type->name);
12073 +- if (mnt->mnt_sb->s_subtype && mnt->mnt_sb->s_subtype[0]) {
12074 +- seq_putc(m, '.');
12075 +- mangle(m, mnt->mnt_sb->s_subtype);
12076 +- }
12077 +- seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
12078 +- for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
12079 +- if (mnt->mnt_sb->s_flags & fs_infop->flag)
12080 +- seq_puts(m, fs_infop->str);
12081 ++ if (vx_flags(VXF_HIDE_MOUNT, 0))
12082 ++ return 0;
12083 ++ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
12084 ++ return 0;
12085 ++
12086 ++ if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
12087 ++ mnt == current->fs->rootmnt) {
12088 ++ seq_puts(m, "/dev/root / ");
12089 ++ } else {
12090 ++ mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
12091 ++ seq_putc(m, ' ');
12092 ++ seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
12093 ++ seq_putc(m, ' ');
12094 ++
12095 ++ if (mnt->mnt_sb->s_subtype && mnt->mnt_sb->s_subtype[0]) {
12096 ++ seq_putc(m, '.');
12097 ++ mangle(m, mnt->mnt_sb->s_subtype);
12098 ++ }
12099 + }
12100 +- for (fs_infop = mnt_info; fs_infop->flag; fs_infop++) {
12101 +- if (mnt->mnt_flags & fs_infop->flag)
12102 +- seq_puts(m, fs_infop->str);
12103 ++ mangle(m, mnt->mnt_sb->s_type->name);
12104 ++ seq_putc(m, ' ');
12105 ++ for (p = fs_info; (p->s_flag | p->mnt_flag) ; p++) {
12106 ++ if ((s_flags & p->s_flag) || (mnt_flags & p->mnt_flag)) {
12107 ++ if (p->set_str)
12108 ++ seq_puts(m, p->set_str);
12109 ++ } else {
12110 ++ if (p->unset_str)
12111 ++ seq_puts(m, p->unset_str);
12112 ++ }
12113 + }
12114 ++ if (mnt->mnt_flags & MNT_TAGID)
12115 ++ seq_printf(m, ",tag=%d", mnt->mnt_tag);
12116 + if (mnt->mnt_sb->s_op->show_options)
12117 + err = mnt->mnt_sb->s_op->show_options(m, mnt);
12118 + seq_puts(m, " 0 0\n");
12119 +@@ -408,17 +457,27 @@ static int show_vfsstat(struct seq_file
12120 + struct vfsmount *mnt = v;
12121 + int err = 0;
12122 +
12123 +- /* device */
12124 +- if (mnt->mnt_devname) {
12125 +- seq_puts(m, "device ");
12126 +- mangle(m, mnt->mnt_devname);
12127 +- } else
12128 +- seq_puts(m, "no device");
12129 ++ if (vx_flags(VXF_HIDE_MOUNT, 0))
12130 ++ return 0;
12131 ++ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
12132 ++ return 0;
12133 +
12134 +- /* mount point */
12135 +- seq_puts(m, " mounted on ");
12136 +- seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
12137 +- seq_putc(m, ' ');
12138 ++ if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
12139 ++ mnt == current->fs->rootmnt) {
12140 ++ seq_puts(m, "device /dev/root mounted on / ");
12141 ++ } else {
12142 ++ /* device */
12143 ++ if (mnt->mnt_devname) {
12144 ++ seq_puts(m, "device ");
12145 ++ mangle(m, mnt->mnt_devname);
12146 ++ } else
12147 ++ seq_puts(m, "no device");
12148 ++
12149 ++ /* mount point */
12150 ++ seq_puts(m, " mounted on ");
12151 ++ seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
12152 ++ seq_putc(m, ' ');
12153 ++ }
12154 +
12155 + /* file system type */
12156 + seq_puts(m, "with fstype ");
12157 +@@ -648,7 +707,7 @@ asmlinkage long sys_umount(char __user *
12158 + goto dput_and_out;
12159 +
12160 + retval = -EPERM;
12161 +- if (!capable(CAP_SYS_ADMIN))
12162 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
12163 + goto dput_and_out;
12164 +
12165 + retval = do_umount(nd.mnt, flags);
12166 +@@ -672,7 +731,7 @@ asmlinkage long sys_oldumount(char __use
12167 +
12168 + static int mount_is_safe(struct nameidata *nd)
12169 + {
12170 +- if (capable(CAP_SYS_ADMIN))
12171 ++ if (vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
12172 + return 0;
12173 + return -EPERM;
12174 + #ifdef notyet
12175 +@@ -904,11 +963,13 @@ static int do_change_type(struct nameida
12176 + /*
12177 + * do loopback mount.
12178 + */
12179 +-static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
12180 ++static int do_loopback(struct nameidata *nd, char *old_name, tag_t tag,
12181 ++ unsigned long flags, int mnt_flags)
12182 + {
12183 + struct nameidata old_nd;
12184 + struct vfsmount *mnt = NULL;
12185 + int err = mount_is_safe(nd);
12186 ++ int recurse = flags & MS_REC;
12187 + if (err)
12188 + return err;
12189 + if (!old_name || !*old_name)
12190 +@@ -934,6 +995,12 @@ static int do_loopback(struct nameidata
12191 + if (!mnt)
12192 + goto out;
12193 +
12194 ++ mnt->mnt_flags = mnt_flags;
12195 ++ if (flags & MS_TAGID) {
12196 ++ mnt->mnt_tag = tag;
12197 ++ mnt->mnt_flags |= MNT_TAGID;
12198 ++ }
12199 ++
12200 + err = graft_tree(mnt, nd);
12201 + if (err) {
12202 + LIST_HEAD(umount_list);
12203 +@@ -942,6 +1009,7 @@ static int do_loopback(struct nameidata
12204 + spin_unlock(&vfsmount_lock);
12205 + release_mounts(&umount_list);
12206 + }
12207 ++ mnt->mnt_flags = mnt_flags;
12208 +
12209 + out:
12210 + up_write(&namespace_sem);
12211 +@@ -955,12 +1023,12 @@ out:
12212 + * on it - tough luck.
12213 + */
12214 + static int do_remount(struct nameidata *nd, int flags, int mnt_flags,
12215 +- void *data)
12216 ++ void *data, xid_t xid)
12217 + {
12218 + int err;
12219 + struct super_block *sb = nd->mnt->mnt_sb;
12220 +
12221 +- if (!capable(CAP_SYS_ADMIN))
12222 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_REMOUNT))
12223 + return -EPERM;
12224 +
12225 + if (!check_mnt(nd->mnt))
12226 +@@ -994,7 +1062,7 @@ static int do_move_mount(struct nameidat
12227 + struct nameidata old_nd, parent_nd;
12228 + struct vfsmount *p;
12229 + int err = 0;
12230 +- if (!capable(CAP_SYS_ADMIN))
12231 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
12232 + return -EPERM;
12233 + if (!old_name || !*old_name)
12234 + return -EINVAL;
12235 +@@ -1074,7 +1142,7 @@ static int do_new_mount(struct nameidata
12236 + return -EINVAL;
12237 +
12238 + /* we need capabilities... */
12239 +- if (!capable(CAP_SYS_ADMIN))
12240 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
12241 + return -EPERM;
12242 +
12243 + mnt = do_kern_mount(type, flags, name, data);
12244 +@@ -1386,6 +1454,7 @@ long do_mount(char *dev_name, char *dir_
12245 + struct nameidata nd;
12246 + int retval = 0;
12247 + int mnt_flags = 0;
12248 ++ tag_t tag = 0;
12249 +
12250 + /* Discard magic */
12251 + if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
12252 +@@ -1401,7 +1470,17 @@ long do_mount(char *dev_name, char *dir_
12253 + if (data_page)
12254 + ((char *)data_page)[PAGE_SIZE - 1] = 0;
12255 +
12256 ++ retval = dx_parse_tag(data_page, &tag, 1);
12257 ++ if (retval) {
12258 ++ mnt_flags |= retval;
12259 ++ /* FIXME: bind and re-mounts get the tag flag? */
12260 ++ if (flags & (MS_BIND|MS_REMOUNT))
12261 ++ flags |= MS_TAGID;
12262 ++ }
12263 ++
12264 + /* Separate the per-mountpoint flags */
12265 ++ if (flags & MS_RDONLY)
12266 ++ mnt_flags |= MNT_RDONLY;
12267 + if (flags & MS_NOSUID)
12268 + mnt_flags |= MNT_NOSUID;
12269 + if (flags & MS_NODEV)
12270 +@@ -1415,6 +1494,8 @@ long do_mount(char *dev_name, char *dir_
12271 + if (flags & MS_RELATIME)
12272 + mnt_flags |= MNT_RELATIME;
12273 +
12274 ++ if (!capable(CAP_SYS_ADMIN))
12275 ++ mnt_flags |= MNT_NODEV;
12276 + flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
12277 + MS_NOATIME | MS_NODIRATIME | MS_RELATIME);
12278 +
12279 +@@ -1429,9 +1510,9 @@ long do_mount(char *dev_name, char *dir_
12280 +
12281 + if (flags & MS_REMOUNT)
12282 + retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
12283 +- data_page);
12284 ++ data_page, tag);
12285 + else if (flags & MS_BIND)
12286 +- retval = do_loopback(&nd, dev_name, flags & MS_REC);
12287 ++ retval = do_loopback(&nd, dev_name, tag, flags, mnt_flags);
12288 + else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
12289 + retval = do_change_type(&nd, flags);
12290 + else if (flags & MS_MOVE)
12291 +@@ -1504,6 +1585,7 @@ static struct mnt_namespace *dup_mnt_ns(
12292 + q = next_mnt(q, new_ns->root);
12293 + }
12294 + up_write(&namespace_sem);
12295 ++ atomic_inc(&vs_global_mnt_ns);
12296 +
12297 + if (rootmnt)
12298 + mntput(rootmnt);
12299 +@@ -1866,5 +1948,6 @@ void __put_mnt_ns(struct mnt_namespace *
12300 + spin_unlock(&vfsmount_lock);
12301 + up_write(&namespace_sem);
12302 + release_mounts(&umount_list);
12303 ++ atomic_dec(&vs_global_mnt_ns);
12304 + kfree(ns);
12305 + }
12306 +diff -NurpP --minimal linux-2.6.22.19/fs/nfs/client.c linux-2.6.22.19-vs2.3.0.34/fs/nfs/client.c
12307 +--- linux-2.6.22.19/fs/nfs/client.c 2008-03-14 20:19:03 +0100
12308 ++++ linux-2.6.22.19-vs2.3.0.34/fs/nfs/client.c 2008-03-14 21:11:30 +0100
12309 +@@ -518,6 +518,9 @@ static int nfs_init_server_rpcclient(str
12310 + if (server->flags & NFS4_MOUNT_INTR)
12311 + server->client->cl_intr = 1;
12312 +
12313 ++ server->client->cl_tag = 0;
12314 ++ if (server->flags & NFS_MOUNT_TAGGED)
12315 ++ server->client->cl_tag = 1;
12316 + return 0;
12317 + }
12318 +
12319 +@@ -665,6 +668,10 @@ static void nfs_server_set_fsinfo(struct
12320 + server->acdirmin = server->acdirmax = 0;
12321 + }
12322 +
12323 ++ /* FIXME: needs fsinfo
12324 ++ if (server->flags & NFS_MOUNT_TAGGED)
12325 ++ sb->s_flags |= MS_TAGGED; */
12326 ++
12327 + server->maxfilesize = fsinfo->maxfilesize;
12328 +
12329 + /* We're airborne Set socket buffersize */
12330 +diff -NurpP --minimal linux-2.6.22.19/fs/nfs/dir.c linux-2.6.22.19-vs2.3.0.34/fs/nfs/dir.c
12331 +--- linux-2.6.22.19/fs/nfs/dir.c 2008-03-14 20:19:03 +0100
12332 ++++ linux-2.6.22.19-vs2.3.0.34/fs/nfs/dir.c 2008-03-14 21:11:30 +0100
12333 +@@ -34,6 +34,7 @@
12334 + #include <linux/namei.h>
12335 + #include <linux/mount.h>
12336 + #include <linux/sched.h>
12337 ++#include <linux/vs_tag.h>
12338 +
12339 + #include "nfs4_fs.h"
12340 + #include "delegation.h"
12341 +@@ -955,6 +956,7 @@ static struct dentry *nfs_lookup(struct
12342 + if (IS_ERR(res))
12343 + goto out_unlock;
12344 +
12345 ++ dx_propagate_tag(nd, inode);
12346 + no_entry:
12347 + res = d_materialise_unique(dentry, inode);
12348 + if (res != NULL) {
12349 +@@ -997,7 +999,8 @@ static int is_atomic_open(struct inode *
12350 + if (nd->flags & LOOKUP_DIRECTORY)
12351 + return 0;
12352 + /* Are we trying to write to a read only partition? */
12353 +- if (IS_RDONLY(dir) && (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
12354 ++ if ((IS_RDONLY(dir) || MNT_IS_RDONLY(nd->mnt)) &&
12355 ++ (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
12356 + return 0;
12357 + return 1;
12358 + }
12359 +diff -NurpP --minimal linux-2.6.22.19/fs/nfs/inode.c linux-2.6.22.19-vs2.3.0.34/fs/nfs/inode.c
12360 +--- linux-2.6.22.19/fs/nfs/inode.c 2008-03-14 20:19:03 +0100
12361 ++++ linux-2.6.22.19-vs2.3.0.34/fs/nfs/inode.c 2008-03-14 21:11:30 +0100
12362 +@@ -37,6 +37,7 @@
12363 + #include <linux/vfs.h>
12364 + #include <linux/inet.h>
12365 + #include <linux/nfs_xdr.h>
12366 ++#include <linux/vs_tag.h>
12367 +
12368 + #include <asm/system.h>
12369 + #include <asm/uaccess.h>
12370 +@@ -285,8 +286,10 @@ nfs_fhget(struct super_block *sb, struct
12371 + nfsi->change_attr = fattr->change_attr;
12372 + inode->i_size = nfs_size_to_loff_t(fattr->size);
12373 + inode->i_nlink = fattr->nlink;
12374 +- inode->i_uid = fattr->uid;
12375 +- inode->i_gid = fattr->gid;
12376 ++ inode->i_uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
12377 ++ inode->i_gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
12378 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
12379 ++ /* maybe fattr->xid someday */
12380 + if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) {
12381 + /*
12382 + * report the blocks in 512byte units
12383 +@@ -377,6 +380,8 @@ void nfs_setattr_update_inode(struct ino
12384 + inode->i_uid = attr->ia_uid;
12385 + if ((attr->ia_valid & ATTR_GID) != 0)
12386 + inode->i_gid = attr->ia_gid;
12387 ++ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
12388 ++ inode->i_tag = attr->ia_tag;
12389 + spin_lock(&inode->i_lock);
12390 + NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
12391 + spin_unlock(&inode->i_lock);
12392 +@@ -825,6 +830,9 @@ static int nfs_check_inode_attributes(st
12393 + struct nfs_inode *nfsi = NFS_I(inode);
12394 + loff_t cur_size, new_isize;
12395 + int data_unstable;
12396 ++ uid_t uid;
12397 ++ gid_t gid;
12398 ++ tag_t tag;
12399 +
12400 +
12401 + /* Has the inode gone and changed behind our back? */
12402 +@@ -852,10 +860,15 @@ static int nfs_check_inode_attributes(st
12403 + if (cur_size != new_isize && nfsi->npages == 0)
12404 + nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
12405 +
12406 ++ uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
12407 ++ gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
12408 ++ tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
12409 ++
12410 + /* Have any file permissions changed? */
12411 + if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)
12412 +- || inode->i_uid != fattr->uid
12413 +- || inode->i_gid != fattr->gid)
12414 ++ || inode->i_uid != uid
12415 ++ || inode->i_gid != gid
12416 ++ || inode->i_tag != tag)
12417 + nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
12418 +
12419 + /* Has the link count changed? */
12420 +@@ -946,6 +959,9 @@ static int nfs_update_inode(struct inode
12421 + unsigned int invalid = 0;
12422 + unsigned long now = jiffies;
12423 + int data_stable;
12424 ++ uid_t uid;
12425 ++ gid_t gid;
12426 ++ tag_t tag;
12427 +
12428 + dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n",
12429 + __FUNCTION__, inode->i_sb->s_id, inode->i_ino,
12430 +@@ -1022,15 +1038,21 @@ static int nfs_update_inode(struct inode
12431 + }
12432 + memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
12433 +
12434 ++ uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
12435 ++ gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
12436 ++ tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
12437 ++
12438 + if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) ||
12439 +- inode->i_uid != fattr->uid ||
12440 +- inode->i_gid != fattr->gid)
12441 ++ inode->i_uid != uid ||
12442 ++ inode->i_gid != gid ||
12443 ++ inode->i_tag != tag)
12444 + invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
12445 +
12446 + inode->i_mode = fattr->mode;
12447 + inode->i_nlink = fattr->nlink;
12448 +- inode->i_uid = fattr->uid;
12449 +- inode->i_gid = fattr->gid;
12450 ++ inode->i_uid = uid;
12451 ++ inode->i_gid = gid;
12452 ++ inode->i_tag = tag;
12453 +
12454 + if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) {
12455 + /*
12456 +diff -NurpP --minimal linux-2.6.22.19/fs/nfs/nfs3xdr.c linux-2.6.22.19-vs2.3.0.34/fs/nfs/nfs3xdr.c
12457 +--- linux-2.6.22.19/fs/nfs/nfs3xdr.c 2007-07-09 13:19:27 +0200
12458 ++++ linux-2.6.22.19-vs2.3.0.34/fs/nfs/nfs3xdr.c 2007-08-05 20:53:13 +0200
12459 +@@ -22,6 +22,7 @@
12460 + #include <linux/nfs3.h>
12461 + #include <linux/nfs_fs.h>
12462 + #include <linux/nfsacl.h>
12463 ++#include <linux/vs_tag.h>
12464 + #include "internal.h"
12465 +
12466 + #define NFSDBG_FACILITY NFSDBG_XDR
12467 +@@ -178,7 +179,7 @@ xdr_decode_fattr(__be32 *p, struct nfs_f
12468 + }
12469 +
12470 + static inline __be32 *
12471 +-xdr_encode_sattr(__be32 *p, struct iattr *attr)
12472 ++xdr_encode_sattr(__be32 *p, struct iattr *attr, int tag)
12473 + {
12474 + if (attr->ia_valid & ATTR_MODE) {
12475 + *p++ = xdr_one;
12476 +@@ -186,15 +187,17 @@ xdr_encode_sattr(__be32 *p, struct iattr
12477 + } else {
12478 + *p++ = xdr_zero;
12479 + }
12480 +- if (attr->ia_valid & ATTR_UID) {
12481 ++ if (attr->ia_valid & ATTR_UID ||
12482 ++ (tag && (attr->ia_valid & ATTR_TAG))) {
12483 + *p++ = xdr_one;
12484 +- *p++ = htonl(attr->ia_uid);
12485 ++ *p++ = htonl(TAGINO_UID(tag, attr->ia_uid, attr->ia_tag));
12486 + } else {
12487 + *p++ = xdr_zero;
12488 + }
12489 +- if (attr->ia_valid & ATTR_GID) {
12490 ++ if (attr->ia_valid & ATTR_GID ||
12491 ++ (tag && (attr->ia_valid & ATTR_TAG))) {
12492 + *p++ = xdr_one;
12493 +- *p++ = htonl(attr->ia_gid);
12494 ++ *p++ = htonl(TAGINO_GID(tag, attr->ia_gid, attr->ia_tag));
12495 + } else {
12496 + *p++ = xdr_zero;
12497 + }
12498 +@@ -279,7 +282,8 @@ static int
12499 + nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args)
12500 + {
12501 + p = xdr_encode_fhandle(p, args->fh);
12502 +- p = xdr_encode_sattr(p, args->sattr);
12503 ++ p = xdr_encode_sattr(p, args->sattr,
12504 ++ req->rq_task->tk_client->cl_tag);
12505 + *p++ = htonl(args->guard);
12506 + if (args->guard)
12507 + p = xdr_encode_time3(p, &args->guardtime);
12508 +@@ -370,7 +374,8 @@ nfs3_xdr_createargs(struct rpc_rqst *req
12509 + *p++ = args->verifier[0];
12510 + *p++ = args->verifier[1];
12511 + } else
12512 +- p = xdr_encode_sattr(p, args->sattr);
12513 ++ p = xdr_encode_sattr(p, args->sattr,
12514 ++ req->rq_task->tk_client->cl_tag);
12515 +
12516 + req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
12517 + return 0;
12518 +@@ -384,7 +389,8 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req,
12519 + {
12520 + p = xdr_encode_fhandle(p, args->fh);
12521 + p = xdr_encode_array(p, args->name, args->len);
12522 +- p = xdr_encode_sattr(p, args->sattr);
12523 ++ p = xdr_encode_sattr(p, args->sattr,
12524 ++ req->rq_task->tk_client->cl_tag);
12525 + req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
12526 + return 0;
12527 + }
12528 +@@ -397,7 +403,8 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *re
12529 + {
12530 + p = xdr_encode_fhandle(p, args->fromfh);
12531 + p = xdr_encode_array(p, args->fromname, args->fromlen);
12532 +- p = xdr_encode_sattr(p, args->sattr);
12533 ++ p = xdr_encode_sattr(p, args->sattr,
12534 ++ req->rq_task->tk_client->cl_tag);
12535 + *p++ = htonl(args->pathlen);
12536 + req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
12537 +
12538 +@@ -415,7 +422,8 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req,
12539 + p = xdr_encode_fhandle(p, args->fh);
12540 + p = xdr_encode_array(p, args->name, args->len);
12541 + *p++ = htonl(args->type);
12542 +- p = xdr_encode_sattr(p, args->sattr);
12543 ++ p = xdr_encode_sattr(p, args->sattr,
12544 ++ req->rq_task->tk_client->cl_tag);
12545 + if (args->type == NF3CHR || args->type == NF3BLK) {
12546 + *p++ = htonl(MAJOR(args->rdev));
12547 + *p++ = htonl(MINOR(args->rdev));
12548 +diff -NurpP --minimal linux-2.6.22.19/fs/nfs/nfsroot.c linux-2.6.22.19-vs2.3.0.34/fs/nfs/nfsroot.c
12549 +--- linux-2.6.22.19/fs/nfs/nfsroot.c 2007-07-09 13:19:27 +0200
12550 ++++ linux-2.6.22.19-vs2.3.0.34/fs/nfs/nfsroot.c 2007-08-05 20:53:13 +0200
12551 +@@ -118,12 +118,12 @@ static int mount_port __initdata = 0; /
12552 + enum {
12553 + /* Options that take integer arguments */
12554 + Opt_port, Opt_rsize, Opt_wsize, Opt_timeo, Opt_retrans, Opt_acregmin,
12555 +- Opt_acregmax, Opt_acdirmin, Opt_acdirmax,
12556 ++ Opt_acregmax, Opt_acdirmin, Opt_acdirmax, Opt_tagid,
12557 + /* Options that take no arguments */
12558 + Opt_soft, Opt_hard, Opt_intr,
12559 + Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac,
12560 + Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp,
12561 +- Opt_acl, Opt_noacl,
12562 ++ Opt_acl, Opt_noacl, Opt_tag, Opt_notag,
12563 + /* Error token */
12564 + Opt_err
12565 + };
12566 +@@ -160,6 +160,9 @@ static match_table_t __initdata tokens =
12567 + {Opt_tcp, "tcp"},
12568 + {Opt_acl, "acl"},
12569 + {Opt_noacl, "noacl"},
12570 ++ {Opt_tag, "tag"},
12571 ++ {Opt_notag, "notag"},
12572 ++ {Opt_tagid, "tagid=%u"},
12573 + {Opt_err, NULL}
12574 +
12575 + };
12576 +@@ -274,6 +277,20 @@ static int __init root_nfs_parse(char *n
12577 + case Opt_noacl:
12578 + nfs_data.flags |= NFS_MOUNT_NOACL;
12579 + break;
12580 ++#ifndef CONFIG_TAGGING_NONE
12581 ++ case Opt_tag:
12582 ++ nfs_data.flags |= NFS_MOUNT_TAGGED;
12583 ++ break;
12584 ++ case Opt_notag:
12585 ++ nfs_data.flags &= ~NFS_MOUNT_TAGGED;
12586 ++ break;
12587 ++#endif
12588 ++#ifdef CONFIG_PROPAGATE
12589 ++ case Opt_tagid:
12590 ++ /* use args[0] */
12591 ++ nfs_data.flags |= NFS_MOUNT_TAGGED;
12592 ++ break;
12593 ++#endif
12594 + default:
12595 + printk(KERN_WARNING "Root-NFS: unknown "
12596 + "option: %s\n", p);
12597 +diff -NurpP --minimal linux-2.6.22.19/fs/nfs/super.c linux-2.6.22.19-vs2.3.0.34/fs/nfs/super.c
12598 +--- linux-2.6.22.19/fs/nfs/super.c 2008-03-14 20:19:03 +0100
12599 ++++ linux-2.6.22.19-vs2.3.0.34/fs/nfs/super.c 2007-09-30 14:58:01 +0200
12600 +@@ -45,6 +45,7 @@
12601 + #include <linux/inet.h>
12602 + #include <linux/nfs_xdr.h>
12603 + #include <linux/magic.h>
12604 ++#include <linux/vs_tag.h>
12605 +
12606 + #include <asm/system.h>
12607 + #include <asm/uaccess.h>
12608 +@@ -291,6 +292,7 @@ static void nfs_show_mount_options(struc
12609 + { NFS_MOUNT_NONLM, ",nolock", "" },
12610 + { NFS_MOUNT_NOACL, ",noacl", "" },
12611 + { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
12612 ++ { NFS_MOUNT_TAGGED, ",tag", "" },
12613 + { 0, NULL, NULL }
12614 + };
12615 + const struct proc_nfs_info *nfs_infop;
12616 +diff -NurpP --minimal linux-2.6.22.19/fs/nfsd/auth.c linux-2.6.22.19-vs2.3.0.34/fs/nfsd/auth.c
12617 +--- linux-2.6.22.19/fs/nfsd/auth.c 2006-06-18 04:54:42 +0200
12618 ++++ linux-2.6.22.19-vs2.3.0.34/fs/nfsd/auth.c 2007-08-05 20:53:13 +0200
12619 +@@ -9,6 +9,7 @@
12620 + #include <linux/sunrpc/svc.h>
12621 + #include <linux/sunrpc/svcauth.h>
12622 + #include <linux/nfsd/nfsd.h>
12623 ++#include <linux/vs_tag.h>
12624 +
12625 + #define CAP_NFSD_MASK (CAP_FS_MASK|CAP_TO_MASK(CAP_SYS_RESOURCE))
12626 +
12627 +@@ -41,19 +42,22 @@ int nfsd_setuser(struct svc_rqst *rqstp,
12628 + get_group_info(cred.cr_group_info);
12629 +
12630 + if (cred.cr_uid != (uid_t) -1)
12631 +- current->fsuid = cred.cr_uid;
12632 ++ current->fsuid = INOTAG_UID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid);
12633 + else
12634 + current->fsuid = exp->ex_anon_uid;
12635 + if (cred.cr_gid != (gid_t) -1)
12636 +- current->fsgid = cred.cr_gid;
12637 ++ current->fsgid = INOTAG_GID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid);
12638 + else
12639 + current->fsgid = exp->ex_anon_gid;
12640 +
12641 ++ /* this desperately needs a tag :) */
12642 ++ current->xid = (xid_t)INOTAG_TAG(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid, 0);
12643 ++
12644 + if (!cred.cr_group_info)
12645 + return -ENOMEM;
12646 + ret = set_current_groups(cred.cr_group_info);
12647 + put_group_info(cred.cr_group_info);
12648 +- if ((cred.cr_uid)) {
12649 ++ if (INOTAG_UID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid)) {
12650 + cap_t(current->cap_effective) &= ~CAP_NFSD_MASK;
12651 + } else {
12652 + cap_t(current->cap_effective) |= (CAP_NFSD_MASK &
12653 +diff -NurpP --minimal linux-2.6.22.19/fs/nfsd/nfs3xdr.c linux-2.6.22.19-vs2.3.0.34/fs/nfsd/nfs3xdr.c
12654 +--- linux-2.6.22.19/fs/nfsd/nfs3xdr.c 2007-07-09 13:19:27 +0200
12655 ++++ linux-2.6.22.19-vs2.3.0.34/fs/nfsd/nfs3xdr.c 2007-08-05 20:53:13 +0200
12656 +@@ -21,6 +21,7 @@
12657 + #include <linux/sunrpc/svc.h>
12658 + #include <linux/nfsd/nfsd.h>
12659 + #include <linux/nfsd/xdr3.h>
12660 ++#include <linux/vs_tag.h>
12661 +
12662 + #define NFSDDBG_FACILITY NFSDDBG_XDR
12663 +
12664 +@@ -107,6 +108,8 @@ static __be32 *
12665 + decode_sattr3(__be32 *p, struct iattr *iap)
12666 + {
12667 + u32 tmp;
12668 ++ uid_t uid = 0;
12669 ++ gid_t gid = 0;
12670 +
12671 + iap->ia_valid = 0;
12672 +
12673 +@@ -116,12 +119,15 @@ decode_sattr3(__be32 *p, struct iattr *i
12674 + }
12675 + if (*p++) {
12676 + iap->ia_valid |= ATTR_UID;
12677 +- iap->ia_uid = ntohl(*p++);
12678 ++ uid = ntohl(*p++);
12679 + }
12680 + if (*p++) {
12681 + iap->ia_valid |= ATTR_GID;
12682 +- iap->ia_gid = ntohl(*p++);
12683 ++ gid = ntohl(*p++);
12684 + }
12685 ++ iap->ia_uid = INOTAG_UID(DX_TAG_NFSD, uid, gid);
12686 ++ iap->ia_gid = INOTAG_GID(DX_TAG_NFSD, uid, gid);
12687 ++ iap->ia_tag = INOTAG_TAG(DX_TAG_NFSD, uid, gid, 0);
12688 + if (*p++) {
12689 + u64 newsize;
12690 +
12691 +@@ -180,8 +186,10 @@ encode_fattr3(struct svc_rqst *rqstp, __
12692 + *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
12693 + *p++ = htonl((u32) stat->mode);
12694 + *p++ = htonl((u32) stat->nlink);
12695 +- *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
12696 +- *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
12697 ++ *p++ = htonl((u32) nfsd_ruid(rqstp,
12698 ++ TAGINO_UID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
12699 ++ *p++ = htonl((u32) nfsd_rgid(rqstp,
12700 ++ TAGINO_GID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
12701 + if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
12702 + p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
12703 + } else {
12704 +diff -NurpP --minimal linux-2.6.22.19/fs/nfsd/nfs4recover.c linux-2.6.22.19-vs2.3.0.34/fs/nfsd/nfs4recover.c
12705 +--- linux-2.6.22.19/fs/nfsd/nfs4recover.c 2007-07-09 13:19:27 +0200
12706 ++++ linux-2.6.22.19-vs2.3.0.34/fs/nfsd/nfs4recover.c 2007-08-05 20:53:13 +0200
12707 +@@ -156,7 +156,7 @@ nfsd4_create_clid_dir(struct nfs4_client
12708 + dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
12709 + goto out_put;
12710 + }
12711 +- status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
12712 ++ status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU, NULL);
12713 + out_put:
12714 + dput(dentry);
12715 + out_unlock:
12716 +@@ -260,7 +260,7 @@ nfsd4_remove_clid_file(struct dentry *di
12717 + return -EINVAL;
12718 + }
12719 + mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
12720 +- status = vfs_unlink(dir->d_inode, dentry);
12721 ++ status = vfs_unlink(dir->d_inode, dentry, NULL);
12722 + mutex_unlock(&dir->d_inode->i_mutex);
12723 + return status;
12724 + }
12725 +@@ -275,7 +275,7 @@ nfsd4_clear_clid_dir(struct dentry *dir,
12726 + * a kernel from the future.... */
12727 + nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
12728 + mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
12729 +- status = vfs_rmdir(dir->d_inode, dentry);
12730 ++ status = vfs_rmdir(dir->d_inode, dentry, NULL);
12731 + mutex_unlock(&dir->d_inode->i_mutex);
12732 + return status;
12733 + }
12734 +diff -NurpP --minimal linux-2.6.22.19/fs/nfsd/nfs4xdr.c linux-2.6.22.19-vs2.3.0.34/fs/nfsd/nfs4xdr.c
12735 +--- linux-2.6.22.19/fs/nfsd/nfs4xdr.c 2008-03-14 20:19:03 +0100
12736 ++++ linux-2.6.22.19-vs2.3.0.34/fs/nfsd/nfs4xdr.c 2008-03-14 21:11:30 +0100
12737 +@@ -56,6 +56,7 @@
12738 + #include <linux/nfsd_idmap.h>
12739 + #include <linux/nfs4.h>
12740 + #include <linux/nfs4_acl.h>
12741 ++#include <linux/vs_tag.h>
12742 +
12743 + #define NFSDDBG_FACILITY NFSDDBG_XDR
12744 +
12745 +@@ -1728,14 +1729,18 @@ out_acl:
12746 + WRITE32(stat.nlink);
12747 + }
12748 + if (bmval1 & FATTR4_WORD1_OWNER) {
12749 +- status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);
12750 ++ status = nfsd4_encode_user(rqstp,
12751 ++ TAGINO_UID(DX_TAG(dentry->d_inode),
12752 ++ stat.uid, stat.tag), &p, &buflen);
12753 + if (status == nfserr_resource)
12754 + goto out_resource;
12755 + if (status)
12756 + goto out;
12757 + }
12758 + if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
12759 +- status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);
12760 ++ status = nfsd4_encode_group(rqstp,
12761 ++ TAGINO_GID(DX_TAG(dentry->d_inode),
12762 ++ stat.gid, stat.tag), &p, &buflen);
12763 + if (status == nfserr_resource)
12764 + goto out_resource;
12765 + if (status)
12766 +diff -NurpP --minimal linux-2.6.22.19/fs/nfsd/nfsxdr.c linux-2.6.22.19-vs2.3.0.34/fs/nfsd/nfsxdr.c
12767 +--- linux-2.6.22.19/fs/nfsd/nfsxdr.c 2007-07-09 13:19:27 +0200
12768 ++++ linux-2.6.22.19-vs2.3.0.34/fs/nfsd/nfsxdr.c 2007-08-05 20:53:13 +0200
12769 +@@ -15,6 +15,7 @@
12770 + #include <linux/nfsd/nfsd.h>
12771 + #include <linux/nfsd/xdr.h>
12772 + #include <linux/mm.h>
12773 ++#include <linux/vs_tag.h>
12774 +
12775 + #define NFSDDBG_FACILITY NFSDDBG_XDR
12776 +
12777 +@@ -97,6 +98,8 @@ static __be32 *
12778 + decode_sattr(__be32 *p, struct iattr *iap)
12779 + {
12780 + u32 tmp, tmp1;
12781 ++ uid_t uid = 0;
12782 ++ gid_t gid = 0;
12783 +
12784 + iap->ia_valid = 0;
12785 +
12786 +@@ -110,12 +113,15 @@ decode_sattr(__be32 *p, struct iattr *ia
12787 + }
12788 + if ((tmp = ntohl(*p++)) != (u32)-1) {
12789 + iap->ia_valid |= ATTR_UID;
12790 +- iap->ia_uid = tmp;
12791 ++ uid = tmp;
12792 + }
12793 + if ((tmp = ntohl(*p++)) != (u32)-1) {
12794 + iap->ia_valid |= ATTR_GID;
12795 +- iap->ia_gid = tmp;
12796 ++ gid = tmp;
12797 + }
12798 ++ iap->ia_uid = INOTAG_UID(DX_TAG_NFSD, uid, gid);
12799 ++ iap->ia_gid = INOTAG_GID(DX_TAG_NFSD, uid, gid);
12800 ++ iap->ia_tag = INOTAG_TAG(DX_TAG_NFSD, uid, gid, 0);
12801 + if ((tmp = ntohl(*p++)) != (u32)-1) {
12802 + iap->ia_valid |= ATTR_SIZE;
12803 + iap->ia_size = tmp;
12804 +@@ -160,8 +166,10 @@ encode_fattr(struct svc_rqst *rqstp, __b
12805 + *p++ = htonl(nfs_ftypes[type >> 12]);
12806 + *p++ = htonl((u32) stat->mode);
12807 + *p++ = htonl((u32) stat->nlink);
12808 +- *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
12809 +- *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
12810 ++ *p++ = htonl((u32) nfsd_ruid(rqstp,
12811 ++ TAGINO_UID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
12812 ++ *p++ = htonl((u32) nfsd_rgid(rqstp,
12813 ++ TAGINO_GID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
12814 +
12815 + if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
12816 + *p++ = htonl(NFS_MAXPATHLEN);
12817 +diff -NurpP --minimal linux-2.6.22.19/fs/nfsd/vfs.c linux-2.6.22.19-vs2.3.0.34/fs/nfsd/vfs.c
12818 +--- linux-2.6.22.19/fs/nfsd/vfs.c 2008-03-14 20:19:03 +0100
12819 ++++ linux-2.6.22.19-vs2.3.0.34/fs/nfsd/vfs.c 2007-08-11 22:41:51 +0200
12820 +@@ -1186,13 +1186,13 @@ nfsd_create(struct svc_rqst *rqstp, stru
12821 + host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
12822 + break;
12823 + case S_IFDIR:
12824 +- host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
12825 ++ host_err = vfs_mkdir(dirp, dchild, iap->ia_mode, NULL);
12826 + break;
12827 + case S_IFCHR:
12828 + case S_IFBLK:
12829 + case S_IFIFO:
12830 + case S_IFSOCK:
12831 +- host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
12832 ++ host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev, NULL);
12833 + break;
12834 + default:
12835 + printk("nfsd: bad file type %o in nfsd_create\n", type);
12836 +@@ -1466,11 +1466,13 @@ nfsd_symlink(struct svc_rqst *rqstp, str
12837 + else {
12838 + strncpy(path_alloced, path, plen);
12839 + path_alloced[plen] = 0;
12840 +- host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
12841 ++ host_err = vfs_symlink(dentry->d_inode, dnew,
12842 ++ path_alloced, mode, NULL);
12843 + kfree(path_alloced);
12844 + }
12845 + } else
12846 +- host_err = vfs_symlink(dentry->d_inode, dnew, path, mode);
12847 ++ host_err = vfs_symlink(dentry->d_inode, dnew,
12848 ++ path, mode, NULL);
12849 +
12850 + if (!host_err) {
12851 + if (EX_ISSYNC(fhp->fh_export))
12852 +@@ -1529,7 +1531,7 @@ nfsd_link(struct svc_rqst *rqstp, struct
12853 + dold = tfhp->fh_dentry;
12854 + dest = dold->d_inode;
12855 +
12856 +- host_err = vfs_link(dold, dirp, dnew);
12857 ++ host_err = vfs_link(dold, dirp, dnew, NULL);
12858 + if (!host_err) {
12859 + if (EX_ISSYNC(ffhp->fh_export)) {
12860 + err = nfserrno(nfsd_sync_dir(ddir));
12861 +@@ -1694,9 +1696,9 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
12862 + host_err = -EPERM;
12863 + } else
12864 + #endif
12865 +- host_err = vfs_unlink(dirp, rdentry);
12866 ++ host_err = vfs_unlink(dirp, rdentry, NULL);
12867 + } else { /* It's RMDIR */
12868 +- host_err = vfs_rmdir(dirp, rdentry);
12869 ++ host_err = vfs_rmdir(dirp, rdentry, NULL);
12870 + }
12871 +
12872 + dput(rdentry);
12873 +@@ -1807,7 +1809,8 @@ nfsd_permission(struct svc_export *exp,
12874 + */
12875 + if (!(acc & MAY_LOCAL_ACCESS))
12876 + if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) {
12877 +- if (EX_RDONLY(exp) || IS_RDONLY(inode))
12878 ++ if (EX_RDONLY(exp) || IS_RDONLY(inode)
12879 ++ || MNT_IS_RDONLY(exp->ex_mnt))
12880 + return nfserr_rofs;
12881 + if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
12882 + return nfserr_perm;
12883 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/dlm/dlmfs.c linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/dlm/dlmfs.c
12884 +--- linux-2.6.22.19/fs/ocfs2/dlm/dlmfs.c 2007-07-09 13:19:28 +0200
12885 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/dlm/dlmfs.c 2007-08-05 20:53:13 +0200
12886 +@@ -43,6 +43,7 @@
12887 + #include <linux/init.h>
12888 + #include <linux/string.h>
12889 + #include <linux/backing-dev.h>
12890 ++#include <linux/vs_tag.h>
12891 +
12892 + #include <asm/uaccess.h>
12893 +
12894 +@@ -331,6 +332,7 @@ static struct inode *dlmfs_get_root_inod
12895 + inode->i_mode = mode;
12896 + inode->i_uid = current->fsuid;
12897 + inode->i_gid = current->fsgid;
12898 ++ inode->i_tag = dx_current_fstag(sb);
12899 + inode->i_blocks = 0;
12900 + inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
12901 + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
12902 +@@ -357,6 +359,7 @@ static struct inode *dlmfs_get_inode(str
12903 + inode->i_mode = mode;
12904 + inode->i_uid = current->fsuid;
12905 + inode->i_gid = current->fsgid;
12906 ++ inode->i_tag = dx_current_fstag(sb);
12907 + inode->i_blocks = 0;
12908 + inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
12909 + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
12910 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/dlmglue.c linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/dlmglue.c
12911 +--- linux-2.6.22.19/fs/ocfs2/dlmglue.c 2007-07-09 13:19:28 +0200
12912 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/dlmglue.c 2007-08-05 20:53:13 +0200
12913 +@@ -1475,6 +1475,7 @@ static void __ocfs2_stuff_meta_lvb(struc
12914 + lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
12915 + lvb->lvb_iuid = cpu_to_be32(inode->i_uid);
12916 + lvb->lvb_igid = cpu_to_be32(inode->i_gid);
12917 ++ lvb->lvb_itag = cpu_to_be16(inode->i_tag);
12918 + lvb->lvb_imode = cpu_to_be16(inode->i_mode);
12919 + lvb->lvb_inlink = cpu_to_be16(inode->i_nlink);
12920 + lvb->lvb_iatime_packed =
12921 +@@ -1527,6 +1528,7 @@ static void ocfs2_refresh_inode_from_lvb
12922 +
12923 + inode->i_uid = be32_to_cpu(lvb->lvb_iuid);
12924 + inode->i_gid = be32_to_cpu(lvb->lvb_igid);
12925 ++ inode->i_tag = be16_to_cpu(lvb->lvb_itag);
12926 + inode->i_mode = be16_to_cpu(lvb->lvb_imode);
12927 + inode->i_nlink = be16_to_cpu(lvb->lvb_inlink);
12928 + ocfs2_unpack_timespec(&inode->i_atime,
12929 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/dlmglue.h linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/dlmglue.h
12930 +--- linux-2.6.22.19/fs/ocfs2/dlmglue.h 2007-07-09 13:19:28 +0200
12931 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/dlmglue.h 2007-08-05 20:53:13 +0200
12932 +@@ -34,7 +34,7 @@
12933 + struct ocfs2_meta_lvb {
12934 + __u8 lvb_version;
12935 + __u8 lvb_reserved0;
12936 +- __be16 lvb_reserved1;
12937 ++ __be16 lvb_itag;
12938 + __be32 lvb_iclusters;
12939 + __be32 lvb_iuid;
12940 + __be32 lvb_igid;
12941 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/file.c linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/file.c
12942 +--- linux-2.6.22.19/fs/ocfs2/file.c 2008-03-14 20:19:04 +0100
12943 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/file.c 2007-09-05 03:06:11 +0200
12944 +@@ -943,13 +943,15 @@ int ocfs2_setattr(struct dentry *dentry,
12945 + mlog(0, "uid change: %d\n", attr->ia_uid);
12946 + if (attr->ia_valid & ATTR_GID)
12947 + mlog(0, "gid change: %d\n", attr->ia_gid);
12948 ++ if (attr->ia_valid & ATTR_TAG)
12949 ++ mlog(0, "tag change: %d\n", attr->ia_tag);
12950 + if (attr->ia_valid & ATTR_SIZE)
12951 + mlog(0, "size change...\n");
12952 + if (attr->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME))
12953 + mlog(0, "time change...\n");
12954 +
12955 + #define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \
12956 +- | ATTR_GID | ATTR_UID | ATTR_MODE)
12957 ++ | ATTR_GID | ATTR_UID | ATTR_TAG | ATTR_MODE)
12958 + if (!(attr->ia_valid & OCFS2_VALID_ATTRS)) {
12959 + mlog(0, "can't handle attrs: 0x%x\n", attr->ia_valid);
12960 + return 0;
12961 +@@ -1805,6 +1807,7 @@ bail:
12962 + const struct inode_operations ocfs2_file_iops = {
12963 + .setattr = ocfs2_setattr,
12964 + .getattr = ocfs2_getattr,
12965 ++ .sync_flags = ocfs2_sync_flags,
12966 + .permission = ocfs2_permission,
12967 + };
12968 +
12969 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/inode.c linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/inode.c
12970 +--- linux-2.6.22.19/fs/ocfs2/inode.c 2007-07-09 13:19:28 +0200
12971 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/inode.c 2007-08-05 20:53:13 +0200
12972 +@@ -28,6 +28,7 @@
12973 + #include <linux/slab.h>
12974 + #include <linux/highmem.h>
12975 + #include <linux/pagemap.h>
12976 ++#include <linux/vs_tag.h>
12977 +
12978 + #include <asm/byteorder.h>
12979 +
12980 +@@ -42,6 +43,7 @@
12981 + #include "file.h"
12982 + #include "heartbeat.h"
12983 + #include "inode.h"
12984 ++#include "ioctl.h"
12985 + #include "journal.h"
12986 + #include "namei.h"
12987 + #include "suballoc.h"
12988 +@@ -77,6 +79,10 @@ void ocfs2_set_inode_flags(struct inode
12989 +
12990 + if (flags & OCFS2_IMMUTABLE_FL)
12991 + inode->i_flags |= S_IMMUTABLE;
12992 ++ if (flags & OCFS2_IUNLINK_FL)
12993 ++ inode->i_flags |= S_IUNLINK;
12994 ++ if (flags & OCFS2_BARRIER_FL)
12995 ++ inode->i_flags |= S_BARRIER;
12996 +
12997 + if (flags & OCFS2_SYNC_FL)
12998 + inode->i_flags |= S_SYNC;
12999 +@@ -107,6 +113,27 @@ void ocfs2_get_inode_flags(struct ocfs2_
13000 + oi->ip_attr |= OCFS2_DIRSYNC_FL;
13001 + }
13002 +
13003 ++int ocfs2_sync_flags(struct inode *inode)
13004 ++{
13005 ++ unsigned int oldflags, newflags;
13006 ++
13007 ++ oldflags = OCFS2_I(inode)->ip_flags;
13008 ++ newflags = oldflags & ~(OCFS2_IMMUTABLE_FL |
13009 ++ OCFS2_IUNLINK_FL | OCFS2_BARRIER_FL);
13010 ++
13011 ++ if (IS_IMMUTABLE(inode))
13012 ++ newflags |= OCFS2_IMMUTABLE_FL;
13013 ++ if (IS_IUNLINK(inode))
13014 ++ newflags |= OCFS2_IUNLINK_FL;
13015 ++ if (IS_BARRIER(inode))
13016 ++ newflags |= OCFS2_BARRIER_FL;
13017 ++
13018 ++ if (oldflags ^ newflags)
13019 ++ return ocfs2_set_inode_attr(inode,
13020 ++ newflags, OCFS2_FL_MASK);
13021 ++ return 0;
13022 ++}
13023 ++
13024 + struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, int flags)
13025 + {
13026 + struct inode *inode = NULL;
13027 +@@ -212,6 +239,8 @@ int ocfs2_populate_inode(struct inode *i
13028 + struct super_block *sb;
13029 + struct ocfs2_super *osb;
13030 + int status = -EINVAL;
13031 ++ uid_t uid;
13032 ++ gid_t gid;
13033 +
13034 + mlog_entry("(0x%p, size:%llu)\n", inode,
13035 + (unsigned long long)le64_to_cpu(fe->i_size));
13036 +@@ -246,8 +275,12 @@ int ocfs2_populate_inode(struct inode *i
13037 + inode->i_generation = le32_to_cpu(fe->i_generation);
13038 + inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
13039 + inode->i_mode = le16_to_cpu(fe->i_mode);
13040 +- inode->i_uid = le32_to_cpu(fe->i_uid);
13041 +- inode->i_gid = le32_to_cpu(fe->i_gid);
13042 ++ uid = le32_to_cpu(fe->i_uid);
13043 ++ gid = le32_to_cpu(fe->i_gid);
13044 ++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
13045 ++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
13046 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
13047 ++ /* le16_to_cpu(raw_inode->i_raw_tag)i */ 0);
13048 +
13049 + /* Fast symlinks will have i_size but no allocated clusters. */
13050 + if (S_ISLNK(inode->i_mode) && !fe->i_clusters)
13051 +@@ -1224,8 +1257,11 @@ int ocfs2_mark_inode_dirty(handle_t *han
13052 +
13053 + fe->i_size = cpu_to_le64(i_size_read(inode));
13054 + fe->i_links_count = cpu_to_le16(inode->i_nlink);
13055 +- fe->i_uid = cpu_to_le32(inode->i_uid);
13056 +- fe->i_gid = cpu_to_le32(inode->i_gid);
13057 ++ fe->i_uid = cpu_to_le32(TAGINO_UID(DX_TAG(inode),
13058 ++ inode->i_uid, inode->i_tag));
13059 ++ fe->i_gid = cpu_to_le32(TAGINO_GID(DX_TAG(inode),
13060 ++ inode->i_gid, inode->i_tag));
13061 ++ /* i_tag = = cpu_to_le16(inode->i_tag); */
13062 + fe->i_mode = cpu_to_le16(inode->i_mode);
13063 + fe->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
13064 + fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
13065 +@@ -1253,15 +1289,24 @@ leave:
13066 + void ocfs2_refresh_inode(struct inode *inode,
13067 + struct ocfs2_dinode *fe)
13068 + {
13069 ++ uid_t uid;
13070 ++ gid_t gid;
13071 ++
13072 + spin_lock(&OCFS2_I(inode)->ip_lock);
13073 +
13074 + OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
13075 + OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
13076 ++ /* OCFS2_I(inode)->ip_flags &= ~OCFS2_FL_MASK;
13077 ++ OCFS2_I(inode)->ip_flags |= le32_to_cpu(fe->i_flags) & OCFS2_FL_MASK; */
13078 + ocfs2_set_inode_flags(inode);
13079 + i_size_write(inode, le64_to_cpu(fe->i_size));
13080 + inode->i_nlink = le16_to_cpu(fe->i_links_count);
13081 +- inode->i_uid = le32_to_cpu(fe->i_uid);
13082 +- inode->i_gid = le32_to_cpu(fe->i_gid);
13083 ++ uid = le32_to_cpu(fe->i_uid);
13084 ++ gid = le32_to_cpu(fe->i_gid);
13085 ++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
13086 ++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
13087 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
13088 ++ /* le16_to_cpu(raw_inode->i_raw_tag)i */ 0);
13089 + inode->i_mode = le16_to_cpu(fe->i_mode);
13090 + if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0)
13091 + inode->i_blocks = 0;
13092 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/inode.h linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/inode.h
13093 +--- linux-2.6.22.19/fs/ocfs2/inode.h 2007-07-09 13:19:28 +0200
13094 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/inode.h 2007-08-05 20:53:13 +0200
13095 +@@ -142,6 +142,7 @@ int ocfs2_aio_write(struct file *file, s
13096 +
13097 + void ocfs2_set_inode_flags(struct inode *inode);
13098 + void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi);
13099 ++int ocfs2_sync_flags(struct inode *inode);
13100 +
13101 + static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode)
13102 + {
13103 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/ioctl.c linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/ioctl.c
13104 +--- linux-2.6.22.19/fs/ocfs2/ioctl.c 2007-07-09 13:19:28 +0200
13105 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/ioctl.c 2008-01-19 01:28:33 +0100
13106 +@@ -39,7 +39,8 @@ static int ocfs2_get_inode_attr(struct i
13107 + return status;
13108 + }
13109 +
13110 +-static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
13111 ++/* Called with inode->i_mutex locked */
13112 ++int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
13113 + unsigned mask)
13114 + {
13115 + struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
13116 +@@ -49,8 +50,6 @@ static int ocfs2_set_inode_attr(struct i
13117 + unsigned oldflags;
13118 + int status;
13119 +
13120 +- mutex_lock(&inode->i_mutex);
13121 +-
13122 + status = ocfs2_meta_lock(inode, &bh, 1);
13123 + if (status < 0) {
13124 + mlog_errno(status);
13125 +@@ -101,8 +100,6 @@ static int ocfs2_set_inode_attr(struct i
13126 + bail_unlock:
13127 + ocfs2_meta_unlock(inode, 1);
13128 + bail:
13129 +- mutex_unlock(&inode->i_mutex);
13130 +-
13131 + if (bh)
13132 + brelse(bh);
13133 +
13134 +@@ -110,6 +107,16 @@ bail:
13135 + return status;
13136 + }
13137 +
13138 ++static inline int ocfs2_set_inode_attr_lock(struct inode *inode,
13139 ++ unsigned flags, unsigned mask)
13140 ++{
13141 ++ int ret;
13142 ++ mutex_lock(&inode->i_mutex);
13143 ++ ret = ocfs2_set_inode_attr(inode, flags, mask);
13144 ++ mutex_unlock(&inode->i_mutex);
13145 ++ return ret;
13146 ++}
13147 ++
13148 + int ocfs2_ioctl(struct inode * inode, struct file * filp,
13149 + unsigned int cmd, unsigned long arg)
13150 + {
13151 +@@ -128,7 +135,7 @@ int ocfs2_ioctl(struct inode * inode, st
13152 + if (get_user(flags, (int __user *) arg))
13153 + return -EFAULT;
13154 +
13155 +- return ocfs2_set_inode_attr(inode, flags,
13156 ++ return ocfs2_set_inode_attr_lock(inode, flags,
13157 + OCFS2_FL_MODIFIABLE);
13158 + default:
13159 + return -ENOTTY;
13160 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/ioctl.h linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/ioctl.h
13161 +--- linux-2.6.22.19/fs/ocfs2/ioctl.h 2007-07-09 13:19:28 +0200
13162 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/ioctl.h 2007-08-05 20:53:13 +0200
13163 +@@ -10,6 +10,9 @@
13164 + #ifndef OCFS2_IOCTL_H
13165 + #define OCFS2_IOCTL_H
13166 +
13167 ++int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
13168 ++ unsigned mask);
13169 ++
13170 + int ocfs2_ioctl(struct inode * inode, struct file * filp,
13171 + unsigned int cmd, unsigned long arg);
13172 + long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg);
13173 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/namei.c linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/namei.c
13174 +--- linux-2.6.22.19/fs/ocfs2/namei.c 2007-07-09 13:19:28 +0200
13175 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/namei.c 2007-08-05 20:53:13 +0200
13176 +@@ -40,6 +40,7 @@
13177 + #include <linux/types.h>
13178 + #include <linux/slab.h>
13179 + #include <linux/highmem.h>
13180 ++#include <linux/vs_tag.h>
13181 +
13182 + #define MLOG_MASK_PREFIX ML_NAMEI
13183 + #include <cluster/masklog.h>
13184 +@@ -483,6 +484,9 @@ static int ocfs2_mknod_locked(struct ocf
13185 + u64 fe_blkno = 0;
13186 + u16 suballoc_bit;
13187 + struct inode *inode = NULL;
13188 ++ uid_t uid;
13189 ++ gid_t gid;
13190 ++ tag_t tag;
13191 +
13192 + mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode,
13193 + (unsigned long)dev, dentry->d_name.len,
13194 +@@ -542,13 +546,19 @@ static int ocfs2_mknod_locked(struct ocf
13195 + fe->i_blkno = cpu_to_le64(fe_blkno);
13196 + fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
13197 + fe->i_suballoc_slot = cpu_to_le16(osb->slot_num);
13198 +- fe->i_uid = cpu_to_le32(current->fsuid);
13199 ++
13200 ++ tag = dx_current_fstag(osb->sb);
13201 ++ uid = current->fsuid;
13202 + if (dir->i_mode & S_ISGID) {
13203 +- fe->i_gid = cpu_to_le32(dir->i_gid);
13204 ++ gid = dir->i_gid;
13205 + if (S_ISDIR(mode))
13206 + mode |= S_ISGID;
13207 + } else
13208 +- fe->i_gid = cpu_to_le32(current->fsgid);
13209 ++ gid = current->fsgid;
13210 ++
13211 ++ fe->i_uid = cpu_to_le32(TAGINO_UID(DX_TAG(inode), uid, tag));
13212 ++ fe->i_gid = cpu_to_le32(TAGINO_GID(DX_TAG(inode), gid, tag));
13213 ++ inode->i_tag = tag;
13214 + fe->i_mode = cpu_to_le16(mode);
13215 + if (S_ISCHR(mode) || S_ISBLK(mode))
13216 + fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
13217 +@@ -2316,5 +2326,6 @@ const struct inode_operations ocfs2_dir_
13218 + .rename = ocfs2_rename,
13219 + .setattr = ocfs2_setattr,
13220 + .getattr = ocfs2_getattr,
13221 ++ .sync_flags = ocfs2_sync_flags,
13222 + .permission = ocfs2_permission,
13223 + };
13224 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/ocfs2.h linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/ocfs2.h
13225 +--- linux-2.6.22.19/fs/ocfs2/ocfs2.h 2007-07-09 13:19:28 +0200
13226 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/ocfs2.h 2007-08-05 20:53:13 +0200
13227 +@@ -170,6 +170,7 @@ enum ocfs2_mount_options
13228 + OCFS2_MOUNT_NOINTR = 1 << 2, /* Don't catch signals */
13229 + OCFS2_MOUNT_ERRORS_PANIC = 1 << 3, /* Panic on errors */
13230 + OCFS2_MOUNT_DATA_WRITEBACK = 1 << 4, /* No data ordering */
13231 ++ OCFS2_MOUNT_TAGGED = 1 << 8, /* use tagging */
13232 + };
13233 +
13234 + #define OCFS2_OSB_SOFT_RO 0x0001
13235 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/ocfs2_fs.h linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/ocfs2_fs.h
13236 +--- linux-2.6.22.19/fs/ocfs2/ocfs2_fs.h 2007-07-09 13:19:28 +0200
13237 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/ocfs2_fs.h 2007-08-05 20:53:13 +0200
13238 +@@ -152,8 +152,12 @@
13239 + #define OCFS2_NOATIME_FL (0x00000080) /* do not update atime */
13240 + #define OCFS2_DIRSYNC_FL (0x00010000) /* dirsync behaviour (directories only) */
13241 +
13242 ++#define OCFS2_BARRIER_FL (0x04000000) /* Barrier for chroot() */
13243 ++#define OCFS2_IUNLINK_FL (0x08000000) /* Immutable unlink */
13244 ++
13245 + #define OCFS2_FL_VISIBLE (0x000100FF) /* User visible flags */
13246 + #define OCFS2_FL_MODIFIABLE (0x000100FF) /* User modifiable flags */
13247 ++#define OCFS2_FL_MASK (0x0F0100FF)
13248 +
13249 + /*
13250 + * Extent record flags (e_node.leaf.flags)
13251 +diff -NurpP --minimal linux-2.6.22.19/fs/ocfs2/super.c linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/super.c
13252 +--- linux-2.6.22.19/fs/ocfs2/super.c 2007-07-09 13:19:28 +0200
13253 ++++ linux-2.6.22.19-vs2.3.0.34/fs/ocfs2/super.c 2007-08-05 20:53:13 +0200
13254 +@@ -140,6 +140,7 @@ enum {
13255 + Opt_data_ordered,
13256 + Opt_data_writeback,
13257 + Opt_atime_quantum,
13258 ++ Opt_tag, Opt_notag, Opt_tagid,
13259 + Opt_err,
13260 + };
13261 +
13262 +@@ -154,6 +155,9 @@ static match_table_t tokens = {
13263 + {Opt_data_ordered, "data=ordered"},
13264 + {Opt_data_writeback, "data=writeback"},
13265 + {Opt_atime_quantum, "atime_quantum=%u"},
13266 ++ {Opt_tag, "tag"},
13267 ++ {Opt_notag, "notag"},
13268 ++ {Opt_tagid, "tagid=%u"},
13269 + {Opt_err, NULL}
13270 + };
13271 +
13272 +@@ -362,6 +366,13 @@ static int ocfs2_remount(struct super_bl
13273 + goto out;
13274 + }
13275 +
13276 ++ if ((parsed_options & OCFS2_MOUNT_TAGGED) &&
13277 ++ !(sb->s_flags & MS_TAGGED)) {
13278 ++ ret = -EINVAL;
13279 ++ mlog(ML_ERROR, "Cannot change tagging on remount\n");
13280 ++ goto out;
13281 ++ }
13282 ++
13283 + if ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) !=
13284 + (parsed_options & OCFS2_MOUNT_HB_LOCAL)) {
13285 + ret = -EINVAL;
13286 +@@ -654,6 +665,9 @@ static int ocfs2_fill_super(struct super
13287 +
13288 + ocfs2_complete_mount_recovery(osb);
13289 +
13290 ++ if (osb->s_mount_opt & OCFS2_MOUNT_TAGGED)
13291 ++ sb->s_flags |= MS_TAGGED;
13292 ++
13293 + if (ocfs2_mount_local(osb))
13294 + snprintf(nodestr, sizeof(nodestr), "local");
13295 + else
13296 +@@ -782,6 +796,20 @@ static int ocfs2_parse_options(struct su
13297 + else
13298 + osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM;
13299 + break;
13300 ++#ifndef CONFIG_TAGGING_NONE
13301 ++ case Opt_tag:
13302 ++ *mount_opt |= OCFS2_MOUNT_TAGGED;
13303 ++ break;
13304 ++ case Opt_notag:
13305 ++ *mount_opt &= ~OCFS2_MOUNT_TAGGED;
13306 ++ break;
13307 ++#endif
13308 ++#ifdef CONFIG_PROPAGATE
13309 ++ case Opt_tagid:
13310 ++ /* use args[0] */
13311 ++ *mount_opt |= OCFS2_MOUNT_TAGGED;
13312 ++ break;
13313 ++#endif
13314 + default:
13315 + mlog(ML_ERROR,
13316 + "Unrecognized mount option \"%s\" "
13317 +diff -NurpP --minimal linux-2.6.22.19/fs/open.c linux-2.6.22.19-vs2.3.0.34/fs/open.c
13318 +--- linux-2.6.22.19/fs/open.c 2007-07-09 13:19:28 +0200
13319 ++++ linux-2.6.22.19-vs2.3.0.34/fs/open.c 2007-08-05 20:53:13 +0200
13320 +@@ -26,22 +26,31 @@
13321 + #include <linux/syscalls.h>
13322 + #include <linux/rcupdate.h>
13323 + #include <linux/audit.h>
13324 ++#include <linux/vs_base.h>
13325 ++#include <linux/vs_limit.h>
13326 ++#include <linux/vs_dlimit.h>
13327 ++#include <linux/vs_tag.h>
13328 ++#include <linux/vs_cowbl.h>
13329 +
13330 + int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
13331 + {
13332 + int retval = -ENODEV;
13333 +
13334 + if (dentry) {
13335 ++ struct super_block *sb = dentry->d_sb;
13336 ++
13337 + retval = -ENOSYS;
13338 +- if (dentry->d_sb->s_op->statfs) {
13339 ++ if (sb->s_op->statfs) {
13340 + memset(buf, 0, sizeof(*buf));
13341 + retval = security_sb_statfs(dentry);
13342 + if (retval)
13343 + return retval;
13344 +- retval = dentry->d_sb->s_op->statfs(dentry, buf);
13345 ++ retval = sb->s_op->statfs(dentry, buf);
13346 + if (retval == 0 && buf->f_frsize == 0)
13347 + buf->f_frsize = buf->f_bsize;
13348 + }
13349 ++ if (!vx_check(0, VS_ADMIN|VS_WATCH))
13350 ++ vx_vsi_statfs(sb, buf);
13351 + }
13352 + return retval;
13353 + }
13354 +@@ -248,7 +257,7 @@ static long do_sys_truncate(const char _
13355 + goto dput_and_out;
13356 +
13357 + error = -EROFS;
13358 +- if (IS_RDONLY(inode))
13359 ++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
13360 + goto dput_and_out;
13361 +
13362 + error = -EPERM;
13363 +@@ -397,7 +406,7 @@ asmlinkage long sys_faccessat(int dfd, c
13364 + special_file(nd.dentry->d_inode->i_mode))
13365 + goto out_path_release;
13366 +
13367 +- if(IS_RDONLY(nd.dentry->d_inode))
13368 ++ if(IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))
13369 + res = -EROFS;
13370 +
13371 + out_path_release:
13372 +@@ -511,7 +520,7 @@ asmlinkage long sys_fchmod(unsigned int
13373 + audit_inode(NULL, inode);
13374 +
13375 + err = -EROFS;
13376 +- if (IS_RDONLY(inode))
13377 ++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(file->f_vfsmnt))
13378 + goto out_putf;
13379 + err = -EPERM;
13380 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
13381 +@@ -541,11 +550,11 @@ asmlinkage long sys_fchmodat(int dfd, co
13382 + error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
13383 + if (error)
13384 + goto out;
13385 +- inode = nd.dentry->d_inode;
13386 +
13387 +- error = -EROFS;
13388 +- if (IS_RDONLY(inode))
13389 ++ error = cow_check_and_break(&nd);
13390 ++ if (error)
13391 + goto dput_and_out;
13392 ++ inode = nd.dentry->d_inode;
13393 +
13394 + error = -EPERM;
13395 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
13396 +@@ -570,7 +579,8 @@ asmlinkage long sys_chmod(const char __u
13397 + return sys_fchmodat(AT_FDCWD, filename, mode);
13398 + }
13399 +
13400 +-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
13401 ++static int chown_common(struct dentry *dentry, struct vfsmount *mnt,
13402 ++ uid_t user, gid_t group)
13403 + {
13404 + struct inode * inode;
13405 + int error;
13406 +@@ -582,7 +592,7 @@ static int chown_common(struct dentry *
13407 + goto out;
13408 + }
13409 + error = -EROFS;
13410 +- if (IS_RDONLY(inode))
13411 ++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt))
13412 + goto out;
13413 + error = -EPERM;
13414 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
13415 +@@ -590,11 +600,11 @@ static int chown_common(struct dentry *
13416 + newattrs.ia_valid = ATTR_CTIME;
13417 + if (user != (uid_t) -1) {
13418 + newattrs.ia_valid |= ATTR_UID;
13419 +- newattrs.ia_uid = user;
13420 ++ newattrs.ia_uid = dx_map_uid(user);
13421 + }
13422 + if (group != (gid_t) -1) {
13423 + newattrs.ia_valid |= ATTR_GID;
13424 +- newattrs.ia_gid = group;
13425 ++ newattrs.ia_gid = dx_map_gid(group);
13426 + }
13427 + if (!S_ISDIR(inode->i_mode))
13428 + newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
13429 +@@ -613,7 +623,11 @@ asmlinkage long sys_chown(const char __u
13430 + error = user_path_walk(filename, &nd);
13431 + if (error)
13432 + goto out;
13433 +- error = chown_common(nd.dentry, user, group);
13434 ++#ifdef CONFIG_VSERVER_COWBL
13435 ++ error = cow_check_and_break(&nd);
13436 ++ if (!error)
13437 ++#endif
13438 ++ error = chown_common(nd.dentry, nd.mnt, user, group);
13439 + path_release(&nd);
13440 + out:
13441 + return error;
13442 +@@ -633,7 +647,11 @@ asmlinkage long sys_fchownat(int dfd, co
13443 + error = __user_walk_fd(dfd, filename, follow, &nd);
13444 + if (error)
13445 + goto out;
13446 +- error = chown_common(nd.dentry, user, group);
13447 ++#ifdef CONFIG_VSERVER_COWBL
13448 ++ error = cow_check_and_break(&nd);
13449 ++ if (!error)
13450 ++#endif
13451 ++ error = chown_common(nd.dentry, nd.mnt, user, group);
13452 + path_release(&nd);
13453 + out:
13454 + return error;
13455 +@@ -647,7 +665,11 @@ asmlinkage long sys_lchown(const char __
13456 + error = user_path_walk_link(filename, &nd);
13457 + if (error)
13458 + goto out;
13459 +- error = chown_common(nd.dentry, user, group);
13460 ++#ifdef CONFIG_VSERVER_COWBL
13461 ++ error = cow_check_and_break(&nd);
13462 ++ if (!error)
13463 ++#endif
13464 ++ error = chown_common(nd.dentry, nd.mnt, user, group);
13465 + path_release(&nd);
13466 + out:
13467 + return error;
13468 +@@ -666,7 +688,7 @@ asmlinkage long sys_fchown(unsigned int
13469 +
13470 + dentry = file->f_path.dentry;
13471 + audit_inode(NULL, dentry->d_inode);
13472 +- error = chown_common(dentry, user, group);
13473 ++ error = chown_common(dentry, file->f_vfsmnt, user, group);
13474 + fput(file);
13475 + out:
13476 + return error;
13477 +@@ -893,6 +915,7 @@ repeat:
13478 + FD_SET(fd, fdt->open_fds);
13479 + FD_CLR(fd, fdt->close_on_exec);
13480 + files->next_fd = fd + 1;
13481 ++ vx_openfd_inc(fd);
13482 + #if 1
13483 + /* Sanity check */
13484 + if (fdt->fd[fd] != NULL) {
13485 +@@ -915,6 +938,7 @@ static void __put_unused_fd(struct files
13486 + __FD_CLR(fd, fdt->open_fds);
13487 + if (fd < files->next_fd)
13488 + files->next_fd = fd;
13489 ++ vx_openfd_dec(fd);
13490 + }
13491 +
13492 + void fastcall put_unused_fd(unsigned int fd)
13493 +diff -NurpP --minimal linux-2.6.22.19/fs/proc/array.c linux-2.6.22.19-vs2.3.0.34/fs/proc/array.c
13494 +--- linux-2.6.22.19/fs/proc/array.c 2007-07-09 13:19:28 +0200
13495 ++++ linux-2.6.22.19-vs2.3.0.34/fs/proc/array.c 2007-10-05 15:07:22 +0200
13496 +@@ -75,6 +75,8 @@
13497 + #include <linux/cpuset.h>
13498 + #include <linux/rcupdate.h>
13499 + #include <linux/delayacct.h>
13500 ++#include <linux/vs_context.h>
13501 ++#include <linux/vs_network.h>
13502 +
13503 + #include <asm/uaccess.h>
13504 + #include <asm/pgtable.h>
13505 +@@ -134,8 +136,9 @@ static const char *task_state_array[] =
13506 + "D (disk sleep)", /* 2 */
13507 + "T (stopped)", /* 4 */
13508 + "T (tracing stop)", /* 8 */
13509 +- "Z (zombie)", /* 16 */
13510 +- "X (dead)" /* 32 */
13511 ++ "H (on hold)", /* 16 */
13512 ++ "Z (zombie)", /* 32 */
13513 ++ "X (dead)", /* 64 */
13514 + };
13515 +
13516 + static inline const char * get_task_state(struct task_struct *tsk)
13517 +@@ -144,7 +147,8 @@ static inline const char * get_task_stat
13518 + TASK_INTERRUPTIBLE |
13519 + TASK_UNINTERRUPTIBLE |
13520 + TASK_STOPPED |
13521 +- TASK_TRACED)) |
13522 ++ TASK_TRACED |
13523 ++ TASK_ONHOLD)) |
13524 + (tsk->exit_state & (EXIT_ZOMBIE |
13525 + EXIT_DEAD));
13526 + const char **p = &task_state_array[0];
13527 +@@ -161,8 +165,16 @@ static inline char * task_state(struct t
13528 + struct group_info *group_info;
13529 + int g;
13530 + struct fdtable *fdt = NULL;
13531 ++ pid_t pid, ptgid, tppid, tgid;
13532 +
13533 + rcu_read_lock();
13534 ++ tgid = vx_map_tgid(p->tgid);
13535 ++ pid = vx_map_pid(p->pid);
13536 ++ ptgid = vx_map_pid(pid_alive(p) ?
13537 ++ rcu_dereference(p->real_parent)->tgid : 0);
13538 ++ tppid = vx_map_pid(pid_alive(p) && p->ptrace ?
13539 ++ rcu_dereference(p->parent)->pid : 0);
13540 ++
13541 + buffer += sprintf(buffer,
13542 + "State:\t%s\n"
13543 + "SleepAVG:\t%lu%%\n"
13544 +@@ -174,9 +186,7 @@ static inline char * task_state(struct t
13545 + "Gid:\t%d\t%d\t%d\t%d\n",
13546 + get_task_state(p),
13547 + (p->sleep_avg/1024)*100/(1020000000/1024),
13548 +- p->tgid, p->pid,
13549 +- pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0,
13550 +- pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0,
13551 ++ tgid, pid, (pid > 1) ? ptgid : 0, tppid,
13552 + p->uid, p->euid, p->suid, p->fsuid,
13553 + p->gid, p->egid, p->sgid, p->fsgid);
13554 +
13555 +@@ -283,12 +293,15 @@ static inline char * task_sig(struct tas
13556 +
13557 + static inline char *task_cap(struct task_struct *p, char *buffer)
13558 + {
13559 +- return buffer + sprintf(buffer, "CapInh:\t%016x\n"
13560 +- "CapPrm:\t%016x\n"
13561 +- "CapEff:\t%016x\n",
13562 +- cap_t(p->cap_inheritable),
13563 +- cap_t(p->cap_permitted),
13564 +- cap_t(p->cap_effective));
13565 ++ struct vx_info *vxi = p->vx_info;
13566 ++
13567 ++ return buffer + sprintf(buffer,
13568 ++ "CapInh:\t%016x\n"
13569 ++ "CapPrm:\t%016x\n"
13570 ++ "CapEff:\t%016x\n",
13571 ++ (unsigned)vx_info_mbcap(vxi, p->cap_inheritable),
13572 ++ (unsigned)vx_info_mbcap(vxi, p->cap_permitted),
13573 ++ (unsigned)vx_info_mbcap(vxi, p->cap_effective));
13574 + }
13575 +
13576 + int proc_pid_status(struct task_struct *task, char * buffer)
13577 +@@ -306,6 +319,12 @@ int proc_pid_status(struct task_struct *
13578 + buffer = task_sig(task, buffer);
13579 + buffer = task_cap(task, buffer);
13580 + buffer = cpuset_task_status_allowed(task, buffer);
13581 ++
13582 ++ if (task_vx_flags(task, VXF_HIDE_VINFO, 0))
13583 ++ goto skip;
13584 ++ buffer += sprintf (buffer,"VxID: %d\n", vx_task_xid(task));
13585 ++ buffer += sprintf (buffer,"NxID: %d\n", nx_task_nid(task));
13586 ++skip:
13587 + #if defined(CONFIG_S390)
13588 + buffer = task_show_regs(task, buffer);
13589 + #endif
13590 +@@ -320,7 +339,7 @@ static int do_task_stat(struct task_stru
13591 + sigset_t sigign, sigcatch;
13592 + char state;
13593 + int res;
13594 +- pid_t ppid = 0, pgid = -1, sid = -1;
13595 ++ pid_t pid = 0, ppid = 0, pgid = -1, sid = -1;
13596 + int num_threads = 0;
13597 + struct mm_struct *mm;
13598 + unsigned long long start_time;
13599 +@@ -382,8 +401,10 @@ static int do_task_stat(struct task_stru
13600 + }
13601 +
13602 + sid = signal_session(sig);
13603 +- pgid = process_group(task);
13604 +- ppid = rcu_dereference(task->real_parent)->tgid;
13605 ++ pid = vx_info_map_pid(task->vx_info, task->pid);
13606 ++ pgid = vx_info_map_pid(task->vx_info, process_group(task));
13607 ++ ppid = (pid > 1) ? vx_info_map_tgid(task->vx_info,
13608 ++ rcu_dereference(task->real_parent)->tgid) : 0;
13609 +
13610 + unlock_task_sighand(task, &flags);
13611 + }
13612 +@@ -410,10 +431,21 @@ static int do_task_stat(struct task_stru
13613 + /* convert nsec -> ticks */
13614 + start_time = nsec_to_clock_t(start_time);
13615 +
13616 ++ /* fixup start time for virt uptime */
13617 ++ if (vx_flags(VXF_VIRT_UPTIME, 0)) {
13618 ++ unsigned long long bias =
13619 ++ current->vx_info->cvirt.bias_clock;
13620 ++
13621 ++ if (start_time > bias)
13622 ++ start_time -= bias;
13623 ++ else
13624 ++ start_time = 0;
13625 ++ }
13626 ++
13627 + res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %u %lu \
13628 + %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
13629 + %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu\n",
13630 +- task->pid,
13631 ++ pid,
13632 + tcomm,
13633 + state,
13634 + ppid,
13635 +diff -NurpP --minimal linux-2.6.22.19/fs/proc/base.c linux-2.6.22.19-vs2.3.0.34/fs/proc/base.c
13636 +--- linux-2.6.22.19/fs/proc/base.c 2007-07-09 13:19:28 +0200
13637 ++++ linux-2.6.22.19-vs2.3.0.34/fs/proc/base.c 2007-09-05 02:49:29 +0200
13638 +@@ -73,6 +73,9 @@
13639 + #include <linux/poll.h>
13640 + #include <linux/nsproxy.h>
13641 + #include <linux/oom.h>
13642 ++#include <linux/vs_context.h>
13643 ++#include <linux/vs_network.h>
13644 ++
13645 + #include "internal.h"
13646 +
13647 + /* NOTE:
13648 +@@ -1049,6 +1052,8 @@ static struct inode *proc_pid_make_inode
13649 + inode->i_uid = task->euid;
13650 + inode->i_gid = task->egid;
13651 + }
13652 ++ /* procfs is xid tagged */
13653 ++ inode->i_tag = (tag_t)vx_task_xid(task);
13654 + security_task_to_inode(task, inode);
13655 +
13656 + out:
13657 +@@ -1082,6 +1087,8 @@ static int pid_getattr(struct vfsmount *
13658 +
13659 + /* dentry stuff */
13660 +
13661 ++static unsigned name_to_int(struct dentry *dentry);
13662 ++
13663 + /*
13664 + * Exceptional case: normally we are not allowed to unhash a busy
13665 + * directory. In this case, however, we can do it - no aliasing problems
13666 +@@ -1102,6 +1109,12 @@ static int pid_revalidate(struct dentry
13667 + struct inode *inode = dentry->d_inode;
13668 + struct task_struct *task = get_proc_task(inode);
13669 + if (task) {
13670 ++ unsigned pid = name_to_int(dentry);
13671 ++ if (pid != ~0U && pid != vx_map_pid(task->pid)) {
13672 ++ put_task_struct(task);
13673 ++ goto drop;
13674 ++ }
13675 ++
13676 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
13677 + task_dumpable(task)) {
13678 + inode->i_uid = task->euid;
13679 +@@ -1115,6 +1128,7 @@ static int pid_revalidate(struct dentry
13680 + put_task_struct(task);
13681 + return 1;
13682 + }
13683 ++drop:
13684 + d_drop(dentry);
13685 + return 0;
13686 + }
13687 +@@ -1595,6 +1609,13 @@ static struct dentry *proc_pident_lookup
13688 + if (!task)
13689 + goto out_no_task;
13690 +
13691 ++ /* TODO: maybe we can come up with a generic approach? */
13692 ++ if (task_vx_flags(task, VXF_HIDE_VINFO, 0) &&
13693 ++ (dentry->d_name.len == 5) &&
13694 ++ (!memcmp(dentry->d_name.name, "vinfo", 5) ||
13695 ++ !memcmp(dentry->d_name.name, "ninfo", 5)))
13696 ++ goto out;
13697 ++
13698 + /*
13699 + * Yes, it does not scale. And it should not. Don't add
13700 + * new entries into /proc/<tgid>/ without very good reasons.
13701 +@@ -1790,14 +1811,14 @@ static int proc_self_readlink(struct den
13702 + int buflen)
13703 + {
13704 + char tmp[PROC_NUMBUF];
13705 +- sprintf(tmp, "%d", current->tgid);
13706 ++ sprintf(tmp, "%d", vx_map_tgid(current->tgid));
13707 + return vfs_readlink(dentry,buffer,buflen,tmp);
13708 + }
13709 +
13710 + static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
13711 + {
13712 + char tmp[PROC_NUMBUF];
13713 +- sprintf(tmp, "%d", current->tgid);
13714 ++ sprintf(tmp, "%d", vx_map_tgid(current->tgid));
13715 + return ERR_PTR(vfs_follow_link(nd,tmp));
13716 + }
13717 +
13718 +@@ -1891,7 +1912,7 @@ out_iput:
13719 + static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
13720 + {
13721 + struct dentry *error;
13722 +- struct task_struct *task = get_proc_task(dir);
13723 ++ struct task_struct *task = get_proc_task_real(dir);
13724 + const struct pid_entry *p, *last;
13725 +
13726 + error = ERR_PTR(-ENOENT);
13727 +@@ -1956,6 +1977,9 @@ static int proc_pid_io_accounting(struct
13728 + static const struct file_operations proc_task_operations;
13729 + static const struct inode_operations proc_task_inode_operations;
13730 +
13731 ++extern int proc_pid_vx_info(struct task_struct *, char *);
13732 ++extern int proc_pid_nx_info(struct task_struct *, char *);
13733 ++
13734 + static const struct pid_entry tgid_base_stuff[] = {
13735 + DIR("task", S_IRUGO|S_IXUGO, task),
13736 + DIR("fd", S_IRUSR|S_IXUSR, fd),
13737 +@@ -1995,6 +2019,8 @@ static const struct pid_entry tgid_base_
13738 + #ifdef CONFIG_CPUSETS
13739 + REG("cpuset", S_IRUGO, cpuset),
13740 + #endif
13741 ++ INF("vinfo", S_IRUGO, pid_vx_info),
13742 ++ INF("ninfo", S_IRUGO, pid_nx_info),
13743 + INF("oom_score", S_IRUGO, oom_score),
13744 + REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust),
13745 + #ifdef CONFIG_AUDITSYSCALL
13746 +@@ -2141,9 +2167,11 @@ struct dentry *proc_pid_lookup(struct in
13747 + tgid = name_to_int(dentry);
13748 + if (tgid == ~0U)
13749 + goto out;
13750 ++ if (vx_current_initpid(tgid))
13751 ++ goto out;
13752 +
13753 + rcu_read_lock();
13754 +- task = find_task_by_pid(tgid);
13755 ++ task = vx_find_proc_task_by_pid(tgid);
13756 + if (task)
13757 + get_task_struct(task);
13758 + rcu_read_unlock();
13759 +@@ -2198,7 +2226,7 @@ static int proc_pid_fill_cache(struct fi
13760 + struct task_struct *task, int tgid)
13761 + {
13762 + char name[PROC_NUMBUF];
13763 +- int len = snprintf(name, sizeof(name), "%d", tgid);
13764 ++ int len = snprintf(name, sizeof(name), "%d", vx_map_tgid(tgid));
13765 + return proc_fill_cache(filp, dirent, filldir, name, len,
13766 + proc_pid_instantiate, task, NULL);
13767 + }
13768 +@@ -2207,7 +2235,7 @@ static int proc_pid_fill_cache(struct fi
13769 + int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
13770 + {
13771 + unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
13772 +- struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
13773 ++ struct task_struct *reaper = get_proc_task_real(filp->f_path.dentry->d_inode);
13774 + struct task_struct *task;
13775 + int tgid;
13776 +
13777 +@@ -2226,6 +2254,8 @@ int proc_pid_readdir(struct file * filp,
13778 + put_task_struct(task), task = next_tgid(tgid + 1)) {
13779 + tgid = task->pid;
13780 + filp->f_pos = tgid + TGID_OFFSET;
13781 ++ if (!vx_proc_task_visible(task))
13782 ++ continue;
13783 + if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
13784 + put_task_struct(task);
13785 + goto out;
13786 +@@ -2352,9 +2382,11 @@ static struct dentry *proc_task_lookup(s
13787 + tid = name_to_int(dentry);
13788 + if (tid == ~0U)
13789 + goto out;
13790 ++ if (vx_current_initpid(tid))
13791 ++ goto out;
13792 +
13793 + rcu_read_lock();
13794 +- task = find_task_by_pid(tid);
13795 ++ task = vx_find_proc_task_by_pid(tid);
13796 + if (task)
13797 + get_task_struct(task);
13798 + rcu_read_unlock();
13799 +@@ -2499,7 +2531,7 @@ static int proc_task_readdir(struct file
13800 + for (task = first_tid(leader, tid, pos - 2);
13801 + task;
13802 + task = next_tid(task), pos++) {
13803 +- tid = task->pid;
13804 ++ tid = vx_map_pid(task->pid);
13805 + if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) {
13806 + /* returning this tgid failed, save it as the first
13807 + * pid for the next readir call */
13808 +diff -NurpP --minimal linux-2.6.22.19/fs/proc/generic.c linux-2.6.22.19-vs2.3.0.34/fs/proc/generic.c
13809 +--- linux-2.6.22.19/fs/proc/generic.c 2007-07-09 13:19:28 +0200
13810 ++++ linux-2.6.22.19-vs2.3.0.34/fs/proc/generic.c 2007-08-05 20:53:13 +0200
13811 +@@ -20,6 +20,7 @@
13812 + #include <linux/namei.h>
13813 + #include <linux/bitops.h>
13814 + #include <linux/spinlock.h>
13815 ++#include <linux/vserver/inode.h>
13816 + #include <asm/uaccess.h>
13817 +
13818 + #include "internal.h"
13819 +@@ -395,6 +396,8 @@ struct dentry *proc_lookup(struct inode
13820 + for (de = de->subdir; de ; de = de->next) {
13821 + if (de->namelen != dentry->d_name.len)
13822 + continue;
13823 ++ if (!vx_hide_check(0, de->vx_flags))
13824 ++ continue;
13825 + if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
13826 + unsigned int ino = de->low_ino;
13827 +
13828 +@@ -402,6 +405,8 @@ struct dentry *proc_lookup(struct inode
13829 + spin_unlock(&proc_subdir_lock);
13830 + error = -EINVAL;
13831 + inode = proc_get_inode(dir->i_sb, ino, de);
13832 ++ /* generic proc entries belong to the host */
13833 ++ inode->i_tag = 0;
13834 + spin_lock(&proc_subdir_lock);
13835 + break;
13836 + }
13837 +@@ -482,6 +487,8 @@ int proc_readdir(struct file * filp,
13838 +
13839 + /* filldir passes info to user space */
13840 + de_get(de);
13841 ++ if (!vx_hide_check(0, de->vx_flags))
13842 ++ goto skip;
13843 + spin_unlock(&proc_subdir_lock);
13844 + if (filldir(dirent, de->name, de->namelen, filp->f_pos,
13845 + de->low_ino, de->mode >> 12) < 0) {
13846 +@@ -489,6 +496,7 @@ int proc_readdir(struct file * filp,
13847 + goto out;
13848 + }
13849 + spin_lock(&proc_subdir_lock);
13850 ++ skip:
13851 + filp->f_pos++;
13852 + next = de->next;
13853 + de_put(de);
13854 +@@ -613,6 +621,7 @@ static struct proc_dir_entry *proc_creat
13855 + ent->namelen = len;
13856 + ent->mode = mode;
13857 + ent->nlink = nlink;
13858 ++ ent->vx_flags = IATTR_PROC_DEFAULT;
13859 + out:
13860 + return ent;
13861 + }
13862 +@@ -633,7 +642,8 @@ struct proc_dir_entry *proc_symlink(cons
13863 + kfree(ent->data);
13864 + kfree(ent);
13865 + ent = NULL;
13866 +- }
13867 ++ } else
13868 ++ ent->vx_flags = IATTR_PROC_SYMLINK;
13869 + } else {
13870 + kfree(ent);
13871 + ent = NULL;
13872 +diff -NurpP --minimal linux-2.6.22.19/fs/proc/inode.c linux-2.6.22.19-vs2.3.0.34/fs/proc/inode.c
13873 +--- linux-2.6.22.19/fs/proc/inode.c 2007-07-09 13:19:28 +0200
13874 ++++ linux-2.6.22.19-vs2.3.0.34/fs/proc/inode.c 2007-08-05 20:53:13 +0200
13875 +@@ -160,6 +160,8 @@ struct inode *proc_get_inode(struct supe
13876 + inode->i_uid = de->uid;
13877 + inode->i_gid = de->gid;
13878 + }
13879 ++ if (de->vx_flags)
13880 ++ PROC_I(inode)->vx_flags = de->vx_flags;
13881 + if (de->size)
13882 + inode->i_size = de->size;
13883 + if (de->nlink)
13884 +diff -NurpP --minimal linux-2.6.22.19/fs/proc/internal.h linux-2.6.22.19-vs2.3.0.34/fs/proc/internal.h
13885 +--- linux-2.6.22.19/fs/proc/internal.h 2007-07-09 13:19:28 +0200
13886 ++++ linux-2.6.22.19-vs2.3.0.34/fs/proc/internal.h 2007-08-05 20:53:13 +0200
13887 +@@ -10,6 +10,7 @@
13888 + */
13889 +
13890 + #include <linux/proc_fs.h>
13891 ++#include <linux/vs_pid.h>
13892 +
13893 + #ifdef CONFIG_PROC_SYSCTL
13894 + extern int proc_sys_init(void);
13895 +@@ -64,11 +65,16 @@ static inline struct pid *proc_pid(struc
13896 + return PROC_I(inode)->pid;
13897 + }
13898 +
13899 +-static inline struct task_struct *get_proc_task(struct inode *inode)
13900 ++static inline struct task_struct *get_proc_task_real(struct inode *inode)
13901 + {
13902 + return get_pid_task(proc_pid(inode), PIDTYPE_PID);
13903 + }
13904 +
13905 ++static inline struct task_struct *get_proc_task(struct inode *inode)
13906 ++{
13907 ++ return vx_get_proc_task(inode, proc_pid(inode));
13908 ++}
13909 ++
13910 + static inline int proc_fd(struct inode *inode)
13911 + {
13912 + return PROC_I(inode)->fd;
13913 +diff -NurpP --minimal linux-2.6.22.19/fs/proc/proc_misc.c linux-2.6.22.19-vs2.3.0.34/fs/proc/proc_misc.c
13914 +--- linux-2.6.22.19/fs/proc/proc_misc.c 2007-07-09 13:19:28 +0200
13915 ++++ linux-2.6.22.19-vs2.3.0.34/fs/proc/proc_misc.c 2007-08-05 20:53:13 +0200
13916 +@@ -53,6 +53,8 @@
13917 + #include <asm/div64.h>
13918 + #include "internal.h"
13919 +
13920 ++#include <linux/vs_cvirt.h>
13921 ++
13922 + #define LOAD_INT(x) ((x) >> FSHIFT)
13923 + #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
13924 + /*
13925 +@@ -82,17 +84,32 @@ static int proc_calc_metrics(char *page,
13926 + static int loadavg_read_proc(char *page, char **start, off_t off,
13927 + int count, int *eof, void *data)
13928 + {
13929 ++ unsigned int running, threads;
13930 + int a, b, c;
13931 + int len;
13932 +
13933 +- a = avenrun[0] + (FIXED_1/200);
13934 +- b = avenrun[1] + (FIXED_1/200);
13935 +- c = avenrun[2] + (FIXED_1/200);
13936 +- len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
13937 ++ if (vx_flags(VXF_VIRT_LOAD, 0)) {
13938 ++ struct vx_info *vxi = current->vx_info;
13939 ++
13940 ++ a = vxi->cvirt.load[0] + (FIXED_1/200);
13941 ++ b = vxi->cvirt.load[1] + (FIXED_1/200);
13942 ++ c = vxi->cvirt.load[2] + (FIXED_1/200);
13943 ++
13944 ++ running = atomic_read(&vxi->cvirt.nr_running);
13945 ++ threads = atomic_read(&vxi->cvirt.nr_threads);
13946 ++ } else {
13947 ++ a = avenrun[0] + (FIXED_1/200);
13948 ++ b = avenrun[1] + (FIXED_1/200);
13949 ++ c = avenrun[2] + (FIXED_1/200);
13950 ++
13951 ++ running = nr_running();
13952 ++ threads = nr_threads;
13953 ++ }
13954 ++ len = sprintf(page,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
13955 + LOAD_INT(a), LOAD_FRAC(a),
13956 + LOAD_INT(b), LOAD_FRAC(b),
13957 + LOAD_INT(c), LOAD_FRAC(c),
13958 +- nr_running(), nr_threads, current->nsproxy->pid_ns->last_pid);
13959 ++ running, threads, current->nsproxy->pid_ns->last_pid);
13960 + return proc_calc_metrics(page, start, off, count, eof, len);
13961 + }
13962 +
13963 +@@ -106,6 +123,9 @@ static int uptime_read_proc(char *page,
13964 +
13965 + do_posix_clock_monotonic_gettime(&uptime);
13966 + cputime_to_timespec(idletime, &idle);
13967 ++ if (vx_flags(VXF_VIRT_UPTIME, 0))
13968 ++ vx_vsi_uptime(&uptime, &idle);
13969 ++
13970 + len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
13971 + (unsigned long) uptime.tv_sec,
13972 + (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
13973 +@@ -137,7 +157,7 @@ static int meminfo_read_proc(char *page,
13974 +
13975 + cached = global_page_state(NR_FILE_PAGES) -
13976 + total_swapcache_pages - i.bufferram;
13977 +- if (cached < 0)
13978 ++ if (cached < 0 || vx_flags(VXF_VIRT_MEM, 0))
13979 + cached = 0;
13980 +
13981 + get_vmalloc_info(&vmi);
13982 +diff -NurpP --minimal linux-2.6.22.19/fs/proc/root.c linux-2.6.22.19-vs2.3.0.34/fs/proc/root.c
13983 +--- linux-2.6.22.19/fs/proc/root.c 2007-05-02 19:25:21 +0200
13984 ++++ linux-2.6.22.19-vs2.3.0.34/fs/proc/root.c 2007-08-05 20:53:13 +0200
13985 +@@ -22,6 +22,9 @@
13986 + #include "internal.h"
13987 +
13988 + struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver;
13989 ++struct proc_dir_entry *proc_virtual;
13990 ++
13991 ++extern void proc_vx_init(void);
13992 +
13993 + static int proc_get_sb(struct file_system_type *fs_type,
13994 + int flags, const char *dev_name, void *data, struct vfsmount *mnt)
13995 +@@ -79,6 +82,7 @@ void __init proc_root_init(void)
13996 + proc_device_tree_init();
13997 + #endif
13998 + proc_bus = proc_mkdir("bus", NULL);
13999 ++ proc_vx_init();
14000 + proc_sys_init();
14001 + }
14002 +
14003 +diff -NurpP --minimal linux-2.6.22.19/fs/quota.c linux-2.6.22.19-vs2.3.0.34/fs/quota.c
14004 +--- linux-2.6.22.19/fs/quota.c 2007-07-09 13:19:28 +0200
14005 ++++ linux-2.6.22.19-vs2.3.0.34/fs/quota.c 2007-08-05 20:53:13 +0200
14006 +@@ -16,6 +16,7 @@
14007 + #include <linux/buffer_head.h>
14008 + #include <linux/capability.h>
14009 + #include <linux/quotaops.h>
14010 ++#include <linux/vs_context.h>
14011 +
14012 + /* Check validity of generic quotactl commands */
14013 + static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
14014 +@@ -80,11 +81,11 @@ static int generic_quotactl_valid(struct
14015 + if (cmd == Q_GETQUOTA) {
14016 + if (((type == USRQUOTA && current->euid != id) ||
14017 + (type == GRPQUOTA && !in_egroup_p(id))) &&
14018 +- !capable(CAP_SYS_ADMIN))
14019 ++ !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
14020 + return -EPERM;
14021 + }
14022 + else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO)
14023 +- if (!capable(CAP_SYS_ADMIN))
14024 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
14025 + return -EPERM;
14026 +
14027 + return 0;
14028 +@@ -131,10 +132,10 @@ static int xqm_quotactl_valid(struct sup
14029 + if (cmd == Q_XGETQUOTA) {
14030 + if (((type == XQM_USRQUOTA && current->euid != id) ||
14031 + (type == XQM_GRPQUOTA && !in_egroup_p(id))) &&
14032 +- !capable(CAP_SYS_ADMIN))
14033 ++ !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
14034 + return -EPERM;
14035 + } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) {
14036 +- if (!capable(CAP_SYS_ADMIN))
14037 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
14038 + return -EPERM;
14039 + }
14040 +
14041 +@@ -327,6 +328,46 @@ static int do_quotactl(struct super_bloc
14042 + return 0;
14043 + }
14044 +
14045 ++#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
14046 ++
14047 ++#include <linux/vroot.h>
14048 ++#include <linux/major.h>
14049 ++#include <linux/module.h>
14050 ++#include <linux/kallsyms.h>
14051 ++#include <linux/vserver/debug.h>
14052 ++
14053 ++static vroot_grb_func *vroot_get_real_bdev = NULL;
14054 ++
14055 ++static spinlock_t vroot_grb_lock = SPIN_LOCK_UNLOCKED;
14056 ++
14057 ++int register_vroot_grb(vroot_grb_func *func) {
14058 ++ int ret = -EBUSY;
14059 ++
14060 ++ spin_lock(&vroot_grb_lock);
14061 ++ if (!vroot_get_real_bdev) {
14062 ++ vroot_get_real_bdev = func;
14063 ++ ret = 0;
14064 ++ }
14065 ++ spin_unlock(&vroot_grb_lock);
14066 ++ return ret;
14067 ++}
14068 ++EXPORT_SYMBOL(register_vroot_grb);
14069 ++
14070 ++int unregister_vroot_grb(vroot_grb_func *func) {
14071 ++ int ret = -EINVAL;
14072 ++
14073 ++ spin_lock(&vroot_grb_lock);
14074 ++ if (vroot_get_real_bdev) {
14075 ++ vroot_get_real_bdev = NULL;
14076 ++ ret = 0;
14077 ++ }
14078 ++ spin_unlock(&vroot_grb_lock);
14079 ++ return ret;
14080 ++}
14081 ++EXPORT_SYMBOL(unregister_vroot_grb);
14082 ++
14083 ++#endif
14084 ++
14085 + /*
14086 + * look up a superblock on which quota ops will be performed
14087 + * - use the name of a block device to find the superblock thereon
14088 +@@ -344,6 +385,22 @@ static inline struct super_block *quotac
14089 + putname(tmp);
14090 + if (IS_ERR(bdev))
14091 + return ERR_PTR(PTR_ERR(bdev));
14092 ++#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
14093 ++ if (bdev && bdev->bd_inode &&
14094 ++ imajor(bdev->bd_inode) == VROOT_MAJOR) {
14095 ++ struct block_device *bdnew = (void *)-EINVAL;
14096 ++
14097 ++ if (vroot_get_real_bdev)
14098 ++ bdnew = vroot_get_real_bdev(bdev);
14099 ++ else
14100 ++ vxdprintk(VXD_CBIT(misc, 0),
14101 ++ "vroot_get_real_bdev not set");
14102 ++ bdput(bdev);
14103 ++ if (IS_ERR(bdnew))
14104 ++ return ERR_PTR(PTR_ERR(bdnew));
14105 ++ bdev = bdnew;
14106 ++ }
14107 ++#endif
14108 + sb = get_super(bdev);
14109 + bdput(bdev);
14110 + if (!sb)
14111 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/bitmap.c linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/bitmap.c
14112 +--- linux-2.6.22.19/fs/reiserfs/bitmap.c 2007-02-06 03:01:29 +0100
14113 ++++ linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/bitmap.c 2007-10-05 15:07:22 +0200
14114 +@@ -13,6 +13,7 @@
14115 + #include <linux/reiserfs_fs_sb.h>
14116 + #include <linux/reiserfs_fs_i.h>
14117 + #include <linux/quotaops.h>
14118 ++#include <linux/vs_dlimit.h>
14119 +
14120 + #define PREALLOCATION_SIZE 9
14121 +
14122 +@@ -425,8 +426,10 @@ static void _reiserfs_free_block(struct
14123 + set_sb_free_blocks(rs, sb_free_blocks(rs) + 1);
14124 +
14125 + journal_mark_dirty(th, s, sbh);
14126 +- if (for_unformatted)
14127 ++ if (for_unformatted) {
14128 ++ DLIMIT_FREE_BLOCK(inode, 1);
14129 + DQUOT_FREE_BLOCK_NODIRTY(inode, 1);
14130 ++ }
14131 + }
14132 +
14133 + void reiserfs_free_block(struct reiserfs_transaction_handle *th,
14134 +@@ -1034,6 +1037,7 @@ static inline int blocknrs_and_prealloc_
14135 + b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1;
14136 + int passno = 0;
14137 + int nr_allocated = 0;
14138 ++ int blocks;
14139 +
14140 + determine_prealloc_size(hint);
14141 + if (!hint->formatted_node) {
14142 +@@ -1043,19 +1047,30 @@ static inline int blocknrs_and_prealloc_
14143 + "reiserquota: allocating %d blocks id=%u",
14144 + amount_needed, hint->inode->i_uid);
14145 + #endif
14146 +- quota_ret =
14147 +- DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, amount_needed);
14148 +- if (quota_ret) /* Quota exceeded? */
14149 ++ quota_ret = DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode,
14150 ++ amount_needed);
14151 ++ if (quota_ret)
14152 + return QUOTA_EXCEEDED;
14153 ++ if (DLIMIT_ALLOC_BLOCK(hint->inode, amount_needed)) {
14154 ++ DQUOT_FREE_BLOCK_NODIRTY(hint->inode,
14155 ++ amount_needed);
14156 ++ return NO_DISK_SPACE;
14157 ++ }
14158 ++
14159 + if (hint->preallocate && hint->prealloc_size) {
14160 + #ifdef REISERQUOTA_DEBUG
14161 + reiserfs_debug(s, REISERFS_DEBUG_CODE,
14162 + "reiserquota: allocating (prealloc) %d blocks id=%u",
14163 + hint->prealloc_size, hint->inode->i_uid);
14164 + #endif
14165 +- quota_ret =
14166 +- DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode,
14167 +- hint->prealloc_size);
14168 ++ quota_ret = DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode,
14169 ++ hint->prealloc_size);
14170 ++ if (!quota_ret &&
14171 ++ DLIMIT_ALLOC_BLOCK(hint->inode, hint->prealloc_size)) {
14172 ++ DQUOT_FREE_BLOCK_NODIRTY(hint->inode,
14173 ++ hint->prealloc_size);
14174 ++ quota_ret = 1;
14175 ++ }
14176 + if (quota_ret)
14177 + hint->preallocate = hint->prealloc_size = 0;
14178 + }
14179 +@@ -1087,7 +1102,10 @@ static inline int blocknrs_and_prealloc_
14180 + nr_allocated,
14181 + hint->inode->i_uid);
14182 + #endif
14183 +- DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated); /* Free not allocated blocks */
14184 ++ /* Free not allocated blocks */
14185 ++ blocks = amount_needed + hint->prealloc_size - nr_allocated;
14186 ++ DLIMIT_FREE_BLOCK(hint->inode, blocks);
14187 ++ DQUOT_FREE_BLOCK_NODIRTY(hint->inode, blocks);
14188 + }
14189 + while (nr_allocated--)
14190 + reiserfs_free_block(hint->th, hint->inode,
14191 +@@ -1118,10 +1136,10 @@ static inline int blocknrs_and_prealloc_
14192 + REISERFS_I(hint->inode)->i_prealloc_count,
14193 + hint->inode->i_uid);
14194 + #endif
14195 +- DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed +
14196 +- hint->prealloc_size - nr_allocated -
14197 +- REISERFS_I(hint->inode)->
14198 +- i_prealloc_count);
14199 ++ blocks = amount_needed + hint->prealloc_size - nr_allocated -
14200 ++ REISERFS_I(hint->inode)->i_prealloc_count;
14201 ++ DLIMIT_FREE_BLOCK(hint->inode, blocks);
14202 ++ DQUOT_FREE_BLOCK_NODIRTY(hint->inode, blocks);
14203 + }
14204 +
14205 + return CARRY_ON;
14206 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/file.c linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/file.c
14207 +--- linux-2.6.22.19/fs/reiserfs/file.c 2007-07-09 13:19:28 +0200
14208 ++++ linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/file.c 2007-09-12 20:04:16 +0200
14209 +@@ -1546,4 +1546,5 @@ const struct inode_operations reiserfs_f
14210 + .listxattr = reiserfs_listxattr,
14211 + .removexattr = reiserfs_removexattr,
14212 + .permission = reiserfs_permission,
14213 ++ .sync_flags = reiserfs_sync_flags,
14214 + };
14215 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/inode.c linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/inode.c
14216 +--- linux-2.6.22.19/fs/reiserfs/inode.c 2007-07-09 13:19:28 +0200
14217 ++++ linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/inode.c 2007-08-05 20:53:13 +0200
14218 +@@ -16,6 +16,8 @@
14219 + #include <linux/mpage.h>
14220 + #include <linux/writeback.h>
14221 + #include <linux/quotaops.h>
14222 ++#include <linux/vs_dlimit.h>
14223 ++#include <linux/vs_tag.h>
14224 +
14225 + static int reiserfs_commit_write(struct file *f, struct page *page,
14226 + unsigned from, unsigned to);
14227 +@@ -50,6 +52,7 @@ void reiserfs_delete_inode(struct inode
14228 + * stat data deletion */
14229 + if (!err)
14230 + DQUOT_FREE_INODE(inode);
14231 ++ DLIMIT_FREE_INODE(inode);
14232 +
14233 + if (journal_end(&th, inode->i_sb, jbegin_count))
14234 + goto out;
14235 +@@ -1112,6 +1115,8 @@ static void init_inode(struct inode *ino
14236 + struct buffer_head *bh;
14237 + struct item_head *ih;
14238 + __u32 rdev;
14239 ++ uid_t uid;
14240 ++ gid_t gid;
14241 + //int version = ITEM_VERSION_1;
14242 +
14243 + bh = PATH_PLAST_BUFFER(path);
14244 +@@ -1135,12 +1140,13 @@ static void init_inode(struct inode *ino
14245 + (struct stat_data_v1 *)B_I_PITEM(bh, ih);
14246 + unsigned long blocks;
14247 +
14248 ++ uid = sd_v1_uid(sd);
14249 ++ gid = sd_v1_gid(sd);
14250 ++
14251 + set_inode_item_key_version(inode, KEY_FORMAT_3_5);
14252 + set_inode_sd_version(inode, STAT_DATA_V1);
14253 + inode->i_mode = sd_v1_mode(sd);
14254 + inode->i_nlink = sd_v1_nlink(sd);
14255 +- inode->i_uid = sd_v1_uid(sd);
14256 +- inode->i_gid = sd_v1_gid(sd);
14257 + inode->i_size = sd_v1_size(sd);
14258 + inode->i_atime.tv_sec = sd_v1_atime(sd);
14259 + inode->i_mtime.tv_sec = sd_v1_mtime(sd);
14260 +@@ -1182,11 +1188,12 @@ static void init_inode(struct inode *ino
14261 + // (directories and symlinks)
14262 + struct stat_data *sd = (struct stat_data *)B_I_PITEM(bh, ih);
14263 +
14264 ++ uid = sd_v2_uid(sd);
14265 ++ gid = sd_v2_gid(sd);
14266 ++
14267 + inode->i_mode = sd_v2_mode(sd);
14268 + inode->i_nlink = sd_v2_nlink(sd);
14269 +- inode->i_uid = sd_v2_uid(sd);
14270 + inode->i_size = sd_v2_size(sd);
14271 +- inode->i_gid = sd_v2_gid(sd);
14272 + inode->i_mtime.tv_sec = sd_v2_mtime(sd);
14273 + inode->i_atime.tv_sec = sd_v2_atime(sd);
14274 + inode->i_ctime.tv_sec = sd_v2_ctime(sd);
14275 +@@ -1216,6 +1223,10 @@ static void init_inode(struct inode *ino
14276 + sd_attrs_to_i_attrs(sd_v2_attrs(sd), inode);
14277 + }
14278 +
14279 ++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
14280 ++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
14281 ++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid, 0);
14282 ++
14283 + pathrelse(path);
14284 + if (S_ISREG(inode->i_mode)) {
14285 + inode->i_op = &reiserfs_file_inode_operations;
14286 +@@ -1238,13 +1249,15 @@ static void init_inode(struct inode *ino
14287 + static void inode2sd(void *sd, struct inode *inode, loff_t size)
14288 + {
14289 + struct stat_data *sd_v2 = (struct stat_data *)sd;
14290 ++ uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
14291 ++ gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
14292 + __u16 flags;
14293 +
14294 ++ set_sd_v2_uid(sd_v2, uid);
14295 ++ set_sd_v2_gid(sd_v2, gid);
14296 + set_sd_v2_mode(sd_v2, inode->i_mode);
14297 + set_sd_v2_nlink(sd_v2, inode->i_nlink);
14298 +- set_sd_v2_uid(sd_v2, inode->i_uid);
14299 + set_sd_v2_size(sd_v2, size);
14300 +- set_sd_v2_gid(sd_v2, inode->i_gid);
14301 + set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec);
14302 + set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec);
14303 + set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec);
14304 +@@ -1775,6 +1788,10 @@ int reiserfs_new_inode(struct reiserfs_t
14305 +
14306 + BUG_ON(!th->t_trans_id);
14307 +
14308 ++ if (DLIMIT_ALLOC_INODE(inode)) {
14309 ++ err = -ENOSPC;
14310 ++ goto out_bad_dlimit;
14311 ++ }
14312 + if (DQUOT_ALLOC_INODE(inode)) {
14313 + err = -EDQUOT;
14314 + goto out_end_trans;
14315 +@@ -1960,6 +1977,9 @@ int reiserfs_new_inode(struct reiserfs_t
14316 + DQUOT_FREE_INODE(inode);
14317 +
14318 + out_end_trans:
14319 ++ DLIMIT_FREE_INODE(inode);
14320 ++
14321 ++ out_bad_dlimit:
14322 + journal_end(th, th->t_super, th->t_blocks_allocated);
14323 + /* Drop can be outside and it needs more credits so it's better to have it outside */
14324 + DQUOT_DROP(inode);
14325 +@@ -2690,6 +2710,14 @@ void sd_attrs_to_i_attrs(__u16 sd_attrs,
14326 + inode->i_flags |= S_IMMUTABLE;
14327 + else
14328 + inode->i_flags &= ~S_IMMUTABLE;
14329 ++ if (sd_attrs & REISERFS_IUNLINK_FL)
14330 ++ inode->i_flags |= S_IUNLINK;
14331 ++ else
14332 ++ inode->i_flags &= ~S_IUNLINK;
14333 ++ if (sd_attrs & REISERFS_BARRIER_FL)
14334 ++ inode->i_flags |= S_BARRIER;
14335 ++ else
14336 ++ inode->i_flags &= ~S_BARRIER;
14337 + if (sd_attrs & REISERFS_APPEND_FL)
14338 + inode->i_flags |= S_APPEND;
14339 + else
14340 +@@ -2712,6 +2740,14 @@ void i_attrs_to_sd_attrs(struct inode *i
14341 + *sd_attrs |= REISERFS_IMMUTABLE_FL;
14342 + else
14343 + *sd_attrs &= ~REISERFS_IMMUTABLE_FL;
14344 ++ if (inode->i_flags & S_IUNLINK)
14345 ++ *sd_attrs |= REISERFS_IUNLINK_FL;
14346 ++ else
14347 ++ *sd_attrs &= ~REISERFS_IUNLINK_FL;
14348 ++ if (inode->i_flags & S_BARRIER)
14349 ++ *sd_attrs |= REISERFS_BARRIER_FL;
14350 ++ else
14351 ++ *sd_attrs &= ~REISERFS_BARRIER_FL;
14352 + if (inode->i_flags & S_SYNC)
14353 + *sd_attrs |= REISERFS_SYNC_FL;
14354 + else
14355 +@@ -2891,6 +2927,22 @@ static ssize_t reiserfs_direct_IO(int rw
14356 + reiserfs_get_blocks_direct_io, NULL);
14357 + }
14358 +
14359 ++int reiserfs_sync_flags(struct inode *inode)
14360 ++{
14361 ++ u16 oldflags, newflags;
14362 ++
14363 ++ oldflags = REISERFS_I(inode)->i_attrs;
14364 ++ newflags = oldflags;
14365 ++ i_attrs_to_sd_attrs(inode, &newflags);
14366 ++
14367 ++ if (oldflags ^ newflags) {
14368 ++ REISERFS_I(inode)->i_attrs = newflags;
14369 ++ inode->i_ctime = CURRENT_TIME_SEC;
14370 ++ mark_inode_dirty(inode);
14371 ++ }
14372 ++ return 0;
14373 ++}
14374 ++
14375 + int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
14376 + {
14377 + struct inode *inode = dentry->d_inode;
14378 +@@ -2940,9 +2992,11 @@ int reiserfs_setattr(struct dentry *dent
14379 + }
14380 +
14381 + error = inode_change_ok(inode, attr);
14382 ++
14383 + if (!error) {
14384 + if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
14385 +- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
14386 ++ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
14387 ++ (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) {
14388 + error = reiserfs_chown_xattrs(inode, attr);
14389 +
14390 + if (!error) {
14391 +@@ -2972,6 +3026,9 @@ int reiserfs_setattr(struct dentry *dent
14392 + inode->i_uid = attr->ia_uid;
14393 + if (attr->ia_valid & ATTR_GID)
14394 + inode->i_gid = attr->ia_gid;
14395 ++ if ((attr->ia_valid & ATTR_TAG) &&
14396 ++ IS_TAGGED(inode))
14397 ++ inode->i_tag = attr->ia_tag;
14398 + mark_inode_dirty(inode);
14399 + error =
14400 + journal_end(&th, inode->i_sb, jbegin_count);
14401 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/ioctl.c linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/ioctl.c
14402 +--- linux-2.6.22.19/fs/reiserfs/ioctl.c 2007-02-06 03:01:29 +0100
14403 ++++ linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/ioctl.c 2007-08-05 20:53:13 +0200
14404 +@@ -6,6 +6,7 @@
14405 + #include <linux/fs.h>
14406 + #include <linux/reiserfs_fs.h>
14407 + #include <linux/time.h>
14408 ++#include <linux/mount.h>
14409 + #include <asm/uaccess.h>
14410 + #include <linux/pagemap.h>
14411 + #include <linux/smp_lock.h>
14412 +@@ -24,7 +25,7 @@ static int reiserfs_unpack(struct inode
14413 + int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
14414 + unsigned long arg)
14415 + {
14416 +- unsigned int flags;
14417 ++ unsigned int flags, oldflags;
14418 +
14419 + switch (cmd) {
14420 + case REISERFS_IOC_UNPACK:
14421 +@@ -43,12 +44,14 @@ int reiserfs_ioctl(struct inode *inode,
14422 +
14423 + flags = REISERFS_I(inode)->i_attrs;
14424 + i_attrs_to_sd_attrs(inode, (__u16 *) & flags);
14425 ++ flags &= REISERFS_FL_USER_VISIBLE;
14426 + return put_user(flags, (int __user *)arg);
14427 + case REISERFS_IOC_SETFLAGS:{
14428 + if (!reiserfs_attrs(inode->i_sb))
14429 + return -ENOTTY;
14430 +
14431 +- if (IS_RDONLY(inode))
14432 ++ if (IS_RDONLY(inode) ||
14433 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
14434 + return -EROFS;
14435 +
14436 + if ((current->fsuid != inode->i_uid)
14437 +@@ -58,10 +61,12 @@ int reiserfs_ioctl(struct inode *inode,
14438 + if (get_user(flags, (int __user *)arg))
14439 + return -EFAULT;
14440 +
14441 +- if (((flags ^ REISERFS_I(inode)->
14442 +- i_attrs) & (REISERFS_IMMUTABLE_FL |
14443 +- REISERFS_APPEND_FL))
14444 +- && !capable(CAP_LINUX_IMMUTABLE))
14445 ++ oldflags = REISERFS_I(inode) -> i_attrs;
14446 ++ if (((oldflags & REISERFS_IMMUTABLE_FL) ||
14447 ++ ((flags ^ oldflags) &
14448 ++ (REISERFS_IMMUTABLE_FL | REISERFS_IUNLINK_FL |
14449 ++ REISERFS_APPEND_FL))) &&
14450 ++ !capable(CAP_LINUX_IMMUTABLE))
14451 + return -EPERM;
14452 +
14453 + if ((flags & REISERFS_NOTAIL_FL) &&
14454 +@@ -72,6 +77,9 @@ int reiserfs_ioctl(struct inode *inode,
14455 + if (result)
14456 + return result;
14457 + }
14458 ++
14459 ++ flags = flags & REISERFS_FL_USER_MODIFIABLE;
14460 ++ flags |= oldflags & ~REISERFS_FL_USER_MODIFIABLE;
14461 + sd_attrs_to_i_attrs(flags, inode);
14462 + REISERFS_I(inode)->i_attrs = flags;
14463 + inode->i_ctime = CURRENT_TIME_SEC;
14464 +@@ -83,7 +91,8 @@ int reiserfs_ioctl(struct inode *inode,
14465 + case REISERFS_IOC_SETVERSION:
14466 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
14467 + return -EPERM;
14468 +- if (IS_RDONLY(inode))
14469 ++ if (IS_RDONLY(inode) ||
14470 ++ (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
14471 + return -EROFS;
14472 + if (get_user(inode->i_generation, (int __user *)arg))
14473 + return -EFAULT;
14474 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/namei.c linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/namei.c
14475 +--- linux-2.6.22.19/fs/reiserfs/namei.c 2007-07-09 13:19:28 +0200
14476 ++++ linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/namei.c 2007-08-05 20:53:13 +0200
14477 +@@ -17,6 +17,7 @@
14478 + #include <linux/reiserfs_acl.h>
14479 + #include <linux/reiserfs_xattr.h>
14480 + #include <linux/quotaops.h>
14481 ++#include <linux/vs_tag.h>
14482 +
14483 + #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; }
14484 + #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) drop_nlink(i);
14485 +@@ -360,6 +361,7 @@ static struct dentry *reiserfs_lookup(st
14486 + reiserfs_write_unlock(dir->i_sb);
14487 + return ERR_PTR(-EACCES);
14488 + }
14489 ++ dx_propagate_tag(nd, inode);
14490 +
14491 + /* Propogate the priv_object flag so we know we're in the priv tree */
14492 + if (is_reiserfs_priv_object(dir))
14493 +@@ -595,6 +597,7 @@ static int new_inode_init(struct inode *
14494 + } else {
14495 + inode->i_gid = current->fsgid;
14496 + }
14497 ++ inode->i_tag = dx_current_fstag(inode->i_sb);
14498 + DQUOT_INIT(inode);
14499 + return 0;
14500 + }
14501 +@@ -1541,6 +1544,7 @@ const struct inode_operations reiserfs_d
14502 + .listxattr = reiserfs_listxattr,
14503 + .removexattr = reiserfs_removexattr,
14504 + .permission = reiserfs_permission,
14505 ++ .sync_flags = reiserfs_sync_flags,
14506 + };
14507 +
14508 + /*
14509 +@@ -1557,6 +1561,7 @@ const struct inode_operations reiserfs_s
14510 + .listxattr = reiserfs_listxattr,
14511 + .removexattr = reiserfs_removexattr,
14512 + .permission = reiserfs_permission,
14513 ++ .sync_flags = reiserfs_sync_flags,
14514 +
14515 + };
14516 +
14517 +@@ -1570,5 +1575,6 @@ const struct inode_operations reiserfs_s
14518 + .listxattr = reiserfs_listxattr,
14519 + .removexattr = reiserfs_removexattr,
14520 + .permission = reiserfs_permission,
14521 ++ .sync_flags = reiserfs_sync_flags,
14522 +
14523 + };
14524 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/stree.c linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/stree.c
14525 +--- linux-2.6.22.19/fs/reiserfs/stree.c 2007-07-09 13:19:28 +0200
14526 ++++ linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/stree.c 2007-08-05 20:53:13 +0200
14527 +@@ -55,6 +55,7 @@
14528 + #include <linux/reiserfs_fs.h>
14529 + #include <linux/buffer_head.h>
14530 + #include <linux/quotaops.h>
14531 ++#include <linux/vs_dlimit.h>
14532 +
14533 + /* Does the buffer contain a disk block which is in the tree. */
14534 + inline int B_IS_IN_TREE(const struct buffer_head *p_s_bh)
14535 +@@ -1296,6 +1297,7 @@ int reiserfs_delete_item(struct reiserfs
14536 + "reiserquota delete_item(): freeing %u, id=%u type=%c",
14537 + quota_cut_bytes, p_s_inode->i_uid, head2type(&s_ih));
14538 + #endif
14539 ++ DLIMIT_FREE_SPACE(p_s_inode, quota_cut_bytes);
14540 + DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
14541 +
14542 + /* Return deleted body length */
14543 +@@ -1384,6 +1386,7 @@ void reiserfs_delete_solid_item(struct r
14544 + #endif
14545 + DQUOT_FREE_SPACE_NODIRTY(inode,
14546 + quota_cut_bytes);
14547 ++ DLIMIT_FREE_SPACE(inode, quota_cut_bytes);
14548 + }
14549 + break;
14550 + }
14551 +@@ -1737,6 +1740,7 @@ int reiserfs_cut_from_item(struct reiser
14552 + "reiserquota cut_from_item(): freeing %u id=%u type=%c",
14553 + quota_cut_bytes, p_s_inode->i_uid, '?');
14554 + #endif
14555 ++ DLIMIT_FREE_SPACE(p_s_inode, quota_cut_bytes);
14556 + DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
14557 + return n_ret_value;
14558 + }
14559 +@@ -1978,6 +1982,11 @@ int reiserfs_paste_into_item(struct reis
14560 + pathrelse(p_s_search_path);
14561 + return -EDQUOT;
14562 + }
14563 ++ if (DLIMIT_ALLOC_SPACE(inode, n_pasted_size)) {
14564 ++ DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
14565 ++ pathrelse(p_s_search_path);
14566 ++ return -ENOSPC;
14567 ++ }
14568 + init_tb_struct(th, &s_paste_balance, th->t_super, p_s_search_path,
14569 + n_pasted_size);
14570 + #ifdef DISPLACE_NEW_PACKING_LOCALITIES
14571 +@@ -2030,6 +2039,7 @@ int reiserfs_paste_into_item(struct reis
14572 + n_pasted_size, inode->i_uid,
14573 + key2type(&(p_s_key->on_disk_key)));
14574 + #endif
14575 ++ DLIMIT_FREE_SPACE(inode, n_pasted_size);
14576 + DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
14577 + return retval;
14578 + }
14579 +@@ -2067,6 +2077,11 @@ int reiserfs_insert_item(struct reiserfs
14580 + pathrelse(p_s_path);
14581 + return -EDQUOT;
14582 + }
14583 ++ if (DLIMIT_ALLOC_SPACE(inode, quota_bytes)) {
14584 ++ DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes);
14585 ++ pathrelse(p_s_path);
14586 ++ return -ENOSPC;
14587 ++ }
14588 + }
14589 + init_tb_struct(th, &s_ins_balance, th->t_super, p_s_path,
14590 + IH_SIZE + ih_item_len(p_s_ih));
14591 +@@ -2114,7 +2129,9 @@ int reiserfs_insert_item(struct reiserfs
14592 + "reiserquota insert_item(): freeing %u id=%u type=%c",
14593 + quota_bytes, inode->i_uid, head2type(p_s_ih));
14594 + #endif
14595 +- if (inode)
14596 ++ if (inode) {
14597 ++ DLIMIT_FREE_SPACE(inode, quota_bytes);
14598 + DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes);
14599 ++ }
14600 + return retval;
14601 + }
14602 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/super.c linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/super.c
14603 +--- linux-2.6.22.19/fs/reiserfs/super.c 2007-07-09 13:19:28 +0200
14604 ++++ linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/super.c 2007-08-05 20:53:13 +0200
14605 +@@ -882,6 +882,14 @@ static int reiserfs_parse_options(struct
14606 + {"user_xattr",.setmask = 1 << REISERFS_UNSUPPORTED_OPT},
14607 + {"nouser_xattr",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},
14608 + #endif
14609 ++#ifndef CONFIG_TAGGING_NONE
14610 ++ {"tagxid",.setmask = 1 << REISERFS_TAGGED},
14611 ++ {"tag",.setmask = 1 << REISERFS_TAGGED},
14612 ++ {"notag",.clrmask = 1 << REISERFS_TAGGED},
14613 ++#endif
14614 ++#ifdef CONFIG_PROPAGATE
14615 ++ {"tag",.arg_required = 'T',.values = NULL},
14616 ++#endif
14617 + #ifdef CONFIG_REISERFS_FS_POSIX_ACL
14618 + {"acl",.setmask = 1 << REISERFS_POSIXACL},
14619 + {"noacl",.clrmask = 1 << REISERFS_POSIXACL},
14620 +@@ -1143,6 +1151,12 @@ static int reiserfs_remount(struct super
14621 + return -EINVAL;
14622 + }
14623 +
14624 ++ if ((mount_options & (1 << REISERFS_TAGGED)) &&
14625 ++ !(s->s_flags & MS_TAGGED)) {
14626 ++ reiserfs_warning(s, "reiserfs: tagging not permitted on remount.");
14627 ++ return -EINVAL;
14628 ++ }
14629 ++
14630 + handle_attrs(s);
14631 +
14632 + /* Add options that are safe here */
14633 +@@ -1591,6 +1605,10 @@ static int reiserfs_fill_super(struct su
14634 + goto error;
14635 + }
14636 +
14637 ++ /* map mount option tagxid */
14638 ++ if (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_TAGGED))
14639 ++ s->s_flags |= MS_TAGGED;
14640 ++
14641 + rs = SB_DISK_SUPER_BLOCK(s);
14642 + /* Let's do basic sanity check to verify that underlying device is not
14643 + smaller than the filesystem. If the check fails then abort and scream,
14644 +diff -NurpP --minimal linux-2.6.22.19/fs/reiserfs/xattr.c linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/xattr.c
14645 +--- linux-2.6.22.19/fs/reiserfs/xattr.c 2007-07-09 13:19:28 +0200
14646 ++++ linux-2.6.22.19-vs2.3.0.34/fs/reiserfs/xattr.c 2007-08-05 20:53:13 +0200
14647 +@@ -35,6 +35,7 @@
14648 + #include <linux/namei.h>
14649 + #include <linux/errno.h>
14650 + #include <linux/fs.h>
14651 ++#include <linux/mount.h>
14652 + #include <linux/file.h>
14653 + #include <linux/pagemap.h>
14654 + #include <linux/xattr.h>
14655 +@@ -775,7 +776,7 @@ int reiserfs_delete_xattrs(struct inode
14656 + if (dir->d_inode->i_nlink <= 2) {
14657 + root = get_xa_root(inode->i_sb, XATTR_REPLACE);
14658 + reiserfs_write_lock_xattrs(inode->i_sb);
14659 +- err = vfs_rmdir(root->d_inode, dir);
14660 ++ err = vfs_rmdir(root->d_inode, dir, NULL);
14661 + reiserfs_write_unlock_xattrs(inode->i_sb);
14662 + dput(root);
14663 + } else {
14664 +diff -NurpP --minimal linux-2.6.22.19/fs/stat.c linux-2.6.22.19-vs2.3.0.34/fs/stat.c
14665 +--- linux-2.6.22.19/fs/stat.c 2007-07-09 13:19:28 +0200
14666 ++++ linux-2.6.22.19-vs2.3.0.34/fs/stat.c 2007-08-05 20:53:13 +0200
14667 +@@ -26,6 +26,7 @@ void generic_fillattr(struct inode *inod
14668 + stat->nlink = inode->i_nlink;
14669 + stat->uid = inode->i_uid;
14670 + stat->gid = inode->i_gid;
14671 ++ stat->tag = inode->i_tag;
14672 + stat->rdev = inode->i_rdev;
14673 + stat->atime = inode->i_atime;
14674 + stat->mtime = inode->i_mtime;
14675 +diff -NurpP --minimal linux-2.6.22.19/fs/super.c linux-2.6.22.19-vs2.3.0.34/fs/super.c
14676 +--- linux-2.6.22.19/fs/super.c 2007-07-09 13:19:28 +0200
14677 ++++ linux-2.6.22.19-vs2.3.0.34/fs/super.c 2007-10-20 00:00:59 +0200
14678 +@@ -37,6 +37,9 @@
14679 + #include <linux/idr.h>
14680 + #include <linux/kobject.h>
14681 + #include <linux/mutex.h>
14682 ++#include <linux/devpts_fs.h>
14683 ++#include <linux/proc_fs.h>
14684 ++#include <linux/vs_context.h>
14685 + #include <asm/uaccess.h>
14686 +
14687 +
14688 +@@ -860,12 +863,18 @@ struct vfsmount *
14689 + vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
14690 + {
14691 + struct vfsmount *mnt;
14692 ++ struct super_block *sb;
14693 + char *secdata = NULL;
14694 + int error;
14695 +
14696 + if (!type)
14697 + return ERR_PTR(-ENODEV);
14698 +
14699 ++ error = -EPERM;
14700 ++ if ((type->fs_flags & FS_BINARY_MOUNTDATA) &&
14701 ++ !vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT))
14702 ++ goto out;
14703 ++
14704 + error = -ENOMEM;
14705 + mnt = alloc_vfsmnt(name);
14706 + if (!mnt)
14707 +@@ -885,7 +894,14 @@ vfs_kern_mount(struct file_system_type *
14708 + if (error < 0)
14709 + goto out_free_secdata;
14710 +
14711 +- error = security_sb_kern_mount(mnt->mnt_sb, secdata);
14712 ++ sb = mnt->mnt_sb;
14713 ++ error = -EPERM;
14714 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT) && !sb->s_bdev &&
14715 ++ (sb->s_magic != PROC_SUPER_MAGIC) &&
14716 ++ (sb->s_magic != DEVPTS_SUPER_MAGIC))
14717 ++ goto out_sb;
14718 ++
14719 ++ error = security_sb_kern_mount(sb, secdata);
14720 + if (error)
14721 + goto out_sb;
14722 +
14723 +diff -NurpP --minimal linux-2.6.22.19/fs/sysfs/mount.c linux-2.6.22.19-vs2.3.0.34/fs/sysfs/mount.c
14724 +--- linux-2.6.22.19/fs/sysfs/mount.c 2007-07-09 13:19:28 +0200
14725 ++++ linux-2.6.22.19-vs2.3.0.34/fs/sysfs/mount.c 2007-08-05 20:53:13 +0200
14726 +@@ -12,8 +12,6 @@
14727 +
14728 + #include "sysfs.h"
14729 +
14730 +-/* Random magic number */
14731 +-#define SYSFS_MAGIC 0x62656572
14732 +
14733 + struct vfsmount *sysfs_mount;
14734 + struct super_block * sysfs_sb = NULL;
14735 +@@ -48,7 +46,7 @@ static int sysfs_fill_super(struct super
14736 +
14737 + sb->s_blocksize = PAGE_CACHE_SIZE;
14738 + sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
14739 +- sb->s_magic = SYSFS_MAGIC;
14740 ++ sb->s_magic = SYSFS_SUPER_MAGIC;
14741 + sb->s_op = &sysfs_ops;
14742 + sb->s_time_gran = 1;
14743 + sysfs_sb = sb;
14744 +diff -NurpP --minimal linux-2.6.22.19/fs/utimes.c linux-2.6.22.19-vs2.3.0.34/fs/utimes.c
14745 +--- linux-2.6.22.19/fs/utimes.c 2007-07-09 13:19:29 +0200
14746 ++++ linux-2.6.22.19-vs2.3.0.34/fs/utimes.c 2007-08-05 20:53:13 +0200
14747 +@@ -6,6 +6,8 @@
14748 + #include <linux/sched.h>
14749 + #include <linux/stat.h>
14750 + #include <linux/utime.h>
14751 ++#include <linux/mount.h>
14752 ++#include <linux/vs_cowbl.h>
14753 + #include <asm/uaccess.h>
14754 + #include <asm/unistd.h>
14755 +
14756 +@@ -70,11 +72,13 @@ long do_utimes(int dfd, char __user *fil
14757 + if (error)
14758 + goto out;
14759 +
14760 ++ error = cow_check_and_break(&nd);
14761 ++ if (error)
14762 ++ goto dput_and_out;
14763 + dentry = nd.dentry;
14764 + }
14765 +
14766 + inode = dentry->d_inode;
14767 +-
14768 + error = -EROFS;
14769 + if (IS_RDONLY(inode))
14770 + goto dput_and_out;
14771 +diff -NurpP --minimal linux-2.6.22.19/fs/xattr.c linux-2.6.22.19-vs2.3.0.34/fs/xattr.c
14772 +--- linux-2.6.22.19/fs/xattr.c 2007-07-09 13:19:29 +0200
14773 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xattr.c 2007-08-05 20:53:13 +0200
14774 +@@ -17,6 +17,7 @@
14775 + #include <linux/module.h>
14776 + #include <linux/fsnotify.h>
14777 + #include <linux/audit.h>
14778 ++#include <linux/mount.h>
14779 + #include <asm/uaccess.h>
14780 +
14781 +
14782 +@@ -194,7 +195,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
14783 + */
14784 + static long
14785 + setxattr(struct dentry *d, char __user *name, void __user *value,
14786 +- size_t size, int flags)
14787 ++ size_t size, int flags, struct vfsmount *mnt)
14788 + {
14789 + int error;
14790 + void *kvalue = NULL;
14791 +@@ -221,6 +222,9 @@ setxattr(struct dentry *d, char __user *
14792 + }
14793 + }
14794 +
14795 ++ if (MNT_IS_RDONLY(mnt))
14796 ++ return -EROFS;
14797 ++
14798 + error = vfs_setxattr(d, kname, kvalue, size, flags);
14799 + kfree(kvalue);
14800 + return error;
14801 +@@ -236,7 +240,7 @@ sys_setxattr(char __user *path, char __u
14802 + error = user_path_walk(path, &nd);
14803 + if (error)
14804 + return error;
14805 +- error = setxattr(nd.dentry, name, value, size, flags);
14806 ++ error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
14807 + path_release(&nd);
14808 + return error;
14809 + }
14810 +@@ -251,7 +255,7 @@ sys_lsetxattr(char __user *path, char __
14811 + error = user_path_walk_link(path, &nd);
14812 + if (error)
14813 + return error;
14814 +- error = setxattr(nd.dentry, name, value, size, flags);
14815 ++ error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
14816 + path_release(&nd);
14817 + return error;
14818 + }
14819 +@@ -269,7 +273,7 @@ sys_fsetxattr(int fd, char __user *name,
14820 + return error;
14821 + dentry = f->f_path.dentry;
14822 + audit_inode(NULL, dentry->d_inode);
14823 +- error = setxattr(dentry, name, value, size, flags);
14824 ++ error = setxattr(dentry, name, value, size, flags, f->f_vfsmnt);
14825 + fput(f);
14826 + return error;
14827 + }
14828 +@@ -433,7 +437,7 @@ sys_flistxattr(int fd, char __user *list
14829 + * Extended attribute REMOVE operations
14830 + */
14831 + static long
14832 +-removexattr(struct dentry *d, char __user *name)
14833 ++removexattr(struct dentry *d, char __user *name, struct vfsmount *mnt)
14834 + {
14835 + int error;
14836 + char kname[XATTR_NAME_MAX + 1];
14837 +@@ -444,6 +448,9 @@ removexattr(struct dentry *d, char __use
14838 + if (error < 0)
14839 + return error;
14840 +
14841 ++ if (MNT_IS_RDONLY(mnt))
14842 ++ return -EROFS;
14843 ++
14844 + return vfs_removexattr(d, kname);
14845 + }
14846 +
14847 +@@ -456,7 +463,7 @@ sys_removexattr(char __user *path, char
14848 + error = user_path_walk(path, &nd);
14849 + if (error)
14850 + return error;
14851 +- error = removexattr(nd.dentry, name);
14852 ++ error = removexattr(nd.dentry, name, nd.mnt);
14853 + path_release(&nd);
14854 + return error;
14855 + }
14856 +@@ -470,7 +477,7 @@ sys_lremovexattr(char __user *path, char
14857 + error = user_path_walk_link(path, &nd);
14858 + if (error)
14859 + return error;
14860 +- error = removexattr(nd.dentry, name);
14861 ++ error = removexattr(nd.dentry, name, nd.mnt);
14862 + path_release(&nd);
14863 + return error;
14864 + }
14865 +@@ -487,7 +494,7 @@ sys_fremovexattr(int fd, char __user *na
14866 + return error;
14867 + dentry = f->f_path.dentry;
14868 + audit_inode(NULL, dentry->d_inode);
14869 +- error = removexattr(dentry, name);
14870 ++ error = removexattr(dentry, name, f->f_vfsmnt);
14871 + fput(f);
14872 + return error;
14873 + }
14874 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/linux-2.6/xfs_ioctl.c linux-2.6.22.19-vs2.3.0.34/fs/xfs/linux-2.6/xfs_ioctl.c
14875 +--- linux-2.6.22.19/fs/xfs/linux-2.6/xfs_ioctl.c 2007-05-02 19:25:22 +0200
14876 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/linux-2.6/xfs_ioctl.c 2007-08-05 20:53:13 +0200
14877 +@@ -1128,6 +1128,10 @@ xfs_di2lxflags(
14878 +
14879 + if (di_flags & XFS_DIFLAG_IMMUTABLE)
14880 + flags |= FS_IMMUTABLE_FL;
14881 ++ if (di_flags & XFS_DIFLAG_IUNLINK)
14882 ++ flags |= FS_IUNLINK_FL;
14883 ++ if (di_flags & XFS_DIFLAG_BARRIER)
14884 ++ flags |= FS_BARRIER_FL;
14885 + if (di_flags & XFS_DIFLAG_APPEND)
14886 + flags |= FS_APPEND_FL;
14887 + if (di_flags & XFS_DIFLAG_SYNC)
14888 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.22.19-vs2.3.0.34/fs/xfs/linux-2.6/xfs_iops.c
14889 +--- linux-2.6.22.19/fs/xfs/linux-2.6/xfs_iops.c 2007-05-02 19:25:22 +0200
14890 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/linux-2.6/xfs_iops.c 2007-08-05 20:53:13 +0200
14891 +@@ -51,6 +51,7 @@
14892 + #include <linux/xattr.h>
14893 + #include <linux/namei.h>
14894 + #include <linux/security.h>
14895 ++#include <linux/vs_tag.h>
14896 +
14897 + /*
14898 + * Get a XFS inode from a given vnode.
14899 +@@ -400,6 +401,7 @@ xfs_vn_lookup(
14900 + d_add(dentry, NULL);
14901 + return NULL;
14902 + }
14903 ++ dx_propagate_tag(nd, vn_to_inode(cvp));
14904 +
14905 + return d_splice_alias(vn_to_inode(cvp), dentry);
14906 + }
14907 +@@ -657,6 +659,10 @@ xfs_vn_setattr(
14908 + int flags = 0;
14909 + int error;
14910 +
14911 ++ error = inode_change_ok(inode, attr);
14912 ++ if (error)
14913 ++ return error;
14914 ++
14915 + if (ia_valid & ATTR_UID) {
14916 + vattr.va_mask |= XFS_AT_UID;
14917 + vattr.va_uid = attr->ia_uid;
14918 +@@ -665,6 +671,10 @@ xfs_vn_setattr(
14919 + vattr.va_mask |= XFS_AT_GID;
14920 + vattr.va_gid = attr->ia_gid;
14921 + }
14922 ++ if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode)) {
14923 ++ vattr.va_mask |= XFS_AT_TAG;
14924 ++ vattr.va_tag = attr->ia_tag;
14925 ++ }
14926 + if (ia_valid & ATTR_SIZE) {
14927 + vattr.va_mask |= XFS_AT_SIZE;
14928 + vattr.va_size = attr->ia_size;
14929 +@@ -710,6 +720,42 @@ xfs_vn_truncate(
14930 + }
14931 +
14932 + STATIC int
14933 ++xfs_vn_sync_flags(struct inode *inode)
14934 ++{
14935 ++ unsigned int oldflags, newflags;
14936 ++ int flags = 0;
14937 ++ int error;
14938 ++ bhv_vattr_t vattr;
14939 ++ bhv_vnode_t *vp = vn_from_inode(inode);
14940 ++
14941 ++ memset(&vattr, 0, sizeof vattr);
14942 ++
14943 ++ vattr.va_mask = XFS_AT_XFLAGS;
14944 ++ error = bhv_vop_getattr(vp, &vattr, 0, NULL);
14945 ++
14946 ++ if (error)
14947 ++ return error;
14948 ++ oldflags = vattr.va_xflags;
14949 ++ newflags = oldflags & ~(XFS_XFLAG_IMMUTABLE |
14950 ++ XFS_XFLAG_IUNLINK | XFS_XFLAG_BARRIER);
14951 ++
14952 ++ if (IS_IMMUTABLE(inode))
14953 ++ newflags |= XFS_XFLAG_IMMUTABLE;
14954 ++ if (IS_IUNLINK(inode))
14955 ++ newflags |= XFS_XFLAG_IUNLINK;
14956 ++ if (IS_BARRIER(inode))
14957 ++ newflags |= XFS_XFLAG_BARRIER;
14958 ++
14959 ++ if (oldflags ^ newflags) {
14960 ++ vattr.va_xflags = newflags;
14961 ++ vattr.va_mask |= XFS_AT_XFLAGS;
14962 ++ error = bhv_vop_setattr(vp, &vattr, flags, NULL);
14963 ++ }
14964 ++ vn_revalidate(vp);
14965 ++ return error;
14966 ++}
14967 ++
14968 ++STATIC int
14969 + xfs_vn_setxattr(
14970 + struct dentry *dentry,
14971 + const char *name,
14972 +@@ -822,6 +868,7 @@ const struct inode_operations xfs_inode_
14973 + .getxattr = xfs_vn_getxattr,
14974 + .listxattr = xfs_vn_listxattr,
14975 + .removexattr = xfs_vn_removexattr,
14976 ++ .sync_flags = xfs_vn_sync_flags,
14977 + };
14978 +
14979 + const struct inode_operations xfs_dir_inode_operations = {
14980 +@@ -841,6 +888,7 @@ const struct inode_operations xfs_dir_in
14981 + .getxattr = xfs_vn_getxattr,
14982 + .listxattr = xfs_vn_listxattr,
14983 + .removexattr = xfs_vn_removexattr,
14984 ++ .sync_flags = xfs_vn_sync_flags,
14985 + };
14986 +
14987 + const struct inode_operations xfs_symlink_inode_operations = {
14988 +@@ -854,4 +902,5 @@ const struct inode_operations xfs_symlin
14989 + .getxattr = xfs_vn_getxattr,
14990 + .listxattr = xfs_vn_listxattr,
14991 + .removexattr = xfs_vn_removexattr,
14992 ++ .sync_flags = xfs_vn_sync_flags,
14993 + };
14994 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/linux-2.6/xfs_linux.h linux-2.6.22.19-vs2.3.0.34/fs/xfs/linux-2.6/xfs_linux.h
14995 +--- linux-2.6.22.19/fs/xfs/linux-2.6/xfs_linux.h 2007-05-02 19:25:22 +0200
14996 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/linux-2.6/xfs_linux.h 2007-08-05 20:53:13 +0200
14997 +@@ -129,6 +129,7 @@
14998 + #define current_pid() (current->pid)
14999 + #define current_fsuid(cred) (current->fsuid)
15000 + #define current_fsgid(cred) (current->fsgid)
15001 ++#define current_fstag(cred,vp) (dx_current_fstag(vn_to_inode(vp)->i_sb))
15002 + #define current_test_flags(f) (current->flags & (f))
15003 + #define current_set_flags_nested(sp, f) \
15004 + (*(sp) = current->flags, current->flags |= (f))
15005 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/linux-2.6/xfs_super.c linux-2.6.22.19-vs2.3.0.34/fs/xfs/linux-2.6/xfs_super.c
15006 +--- linux-2.6.22.19/fs/xfs/linux-2.6/xfs_super.c 2007-07-09 13:19:29 +0200
15007 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/linux-2.6/xfs_super.c 2007-08-05 20:53:13 +0200
15008 +@@ -157,6 +157,7 @@ xfs_revalidate_inode(
15009 + inode->i_nlink = ip->i_d.di_nlink;
15010 + inode->i_uid = ip->i_d.di_uid;
15011 + inode->i_gid = ip->i_d.di_gid;
15012 ++ inode->i_tag = ip->i_d.di_tag;
15013 +
15014 + switch (inode->i_mode & S_IFMT) {
15015 + case S_IFBLK:
15016 +@@ -184,6 +185,14 @@ xfs_revalidate_inode(
15017 + inode->i_flags |= S_IMMUTABLE;
15018 + else
15019 + inode->i_flags &= ~S_IMMUTABLE;
15020 ++ if (ip->i_d.di_flags & XFS_DIFLAG_IUNLINK)
15021 ++ inode->i_flags |= S_IUNLINK;
15022 ++ else
15023 ++ inode->i_flags &= ~S_IUNLINK;
15024 ++ if (ip->i_d.di_flags & XFS_DIFLAG_BARRIER)
15025 ++ inode->i_flags |= S_BARRIER;
15026 ++ else
15027 ++ inode->i_flags &= ~S_BARRIER;
15028 + if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
15029 + inode->i_flags |= S_APPEND;
15030 + else
15031 +@@ -712,6 +721,12 @@ xfs_fs_remount(
15032 + int error;
15033 +
15034 + error = bhv_vfs_parseargs(vfsp, options, args, 1);
15035 ++ if ((args->flags2 & XFSMNT2_TAGGED) &&
15036 ++ !(sb->s_flags & MS_TAGGED)) {
15037 ++ printk("XFS: %s: tagging not permitted on remount.\n",
15038 ++ sb->s_id);
15039 ++ error = EINVAL;
15040 ++ }
15041 + if (!error)
15042 + error = bhv_vfs_mntupdate(vfsp, flags, args);
15043 + kmem_free(args, sizeof(*args));
15044 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/linux-2.6/xfs_vnode.c linux-2.6.22.19-vs2.3.0.34/fs/xfs/linux-2.6/xfs_vnode.c
15045 +--- linux-2.6.22.19/fs/xfs/linux-2.6/xfs_vnode.c 2007-05-02 19:25:22 +0200
15046 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/linux-2.6/xfs_vnode.c 2007-08-05 20:53:13 +0200
15047 +@@ -119,6 +119,7 @@ vn_revalidate_core(
15048 + inode->i_nlink = vap->va_nlink;
15049 + inode->i_uid = vap->va_uid;
15050 + inode->i_gid = vap->va_gid;
15051 ++ inode->i_tag = vap->va_tag;
15052 + inode->i_blocks = vap->va_nblocks;
15053 + inode->i_mtime = vap->va_mtime;
15054 + inode->i_ctime = vap->va_ctime;
15055 +@@ -126,6 +127,14 @@ vn_revalidate_core(
15056 + inode->i_flags |= S_IMMUTABLE;
15057 + else
15058 + inode->i_flags &= ~S_IMMUTABLE;
15059 ++ if (vap->va_xflags & XFS_XFLAG_IUNLINK)
15060 ++ inode->i_flags |= S_IUNLINK;
15061 ++ else
15062 ++ inode->i_flags &= ~S_IUNLINK;
15063 ++ if (vap->va_xflags & XFS_XFLAG_BARRIER)
15064 ++ inode->i_flags |= S_BARRIER;
15065 ++ else
15066 ++ inode->i_flags &= ~S_BARRIER;
15067 + if (vap->va_xflags & XFS_XFLAG_APPEND)
15068 + inode->i_flags |= S_APPEND;
15069 + else
15070 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/linux-2.6/xfs_vnode.h linux-2.6.22.19-vs2.3.0.34/fs/xfs/linux-2.6/xfs_vnode.h
15071 +--- linux-2.6.22.19/fs/xfs/linux-2.6/xfs_vnode.h 2007-07-09 13:19:29 +0200
15072 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/linux-2.6/xfs_vnode.h 2007-08-05 20:53:13 +0200
15073 +@@ -350,6 +350,7 @@ typedef struct bhv_vattr {
15074 + xfs_nlink_t va_nlink; /* number of references to file */
15075 + uid_t va_uid; /* owner user id */
15076 + gid_t va_gid; /* owner group id */
15077 ++ tag_t va_tag; /* owner group id */
15078 + xfs_ino_t va_nodeid; /* file id */
15079 + xfs_off_t va_size; /* file size in bytes */
15080 + u_long va_blocksize; /* blocksize preferred for i/o */
15081 +@@ -398,13 +399,15 @@ typedef struct bhv_vattr {
15082 + #define XFS_AT_PROJID 0x04000000
15083 + #define XFS_AT_SIZE_NOPERM 0x08000000
15084 + #define XFS_AT_GENCOUNT 0x10000000
15085 ++#define XFS_AT_TAG 0x20000000
15086 +
15087 + #define XFS_AT_ALL (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
15088 + XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
15089 + XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME|XFS_AT_RDEV|\
15090 + XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|XFS_AT_MAC|\
15091 + XFS_AT_ACL|XFS_AT_CAP|XFS_AT_INF|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|\
15092 +- XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT)
15093 ++ XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT\
15094 ++ XFS_AT_TAG)
15095 +
15096 + #define XFS_AT_STAT (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
15097 + XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
15098 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/quota/xfs_qm_syscalls.c linux-2.6.22.19-vs2.3.0.34/fs/xfs/quota/xfs_qm_syscalls.c
15099 +--- linux-2.6.22.19/fs/xfs/quota/xfs_qm_syscalls.c 2007-07-09 13:19:29 +0200
15100 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/quota/xfs_qm_syscalls.c 2007-08-05 20:53:13 +0200
15101 +@@ -17,6 +17,7 @@
15102 + */
15103 +
15104 + #include <linux/capability.h>
15105 ++#include <linux/vs_context.h>
15106 +
15107 + #include "xfs.h"
15108 + #include "xfs_fs.h"
15109 +@@ -211,7 +212,7 @@ xfs_qm_scall_quotaoff(
15110 + xfs_qoff_logitem_t *qoffstart;
15111 + int nculprits;
15112 +
15113 +- if (!force && !capable(CAP_SYS_ADMIN))
15114 ++ if (!force && !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
15115 + return XFS_ERROR(EPERM);
15116 + /*
15117 + * No file system can have quotas enabled on disk but not in core.
15118 +@@ -380,7 +381,7 @@ xfs_qm_scall_trunc_qfiles(
15119 + int error;
15120 + xfs_inode_t *qip;
15121 +
15122 +- if (!capable(CAP_SYS_ADMIN))
15123 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
15124 + return XFS_ERROR(EPERM);
15125 + error = 0;
15126 + if (!XFS_SB_VERSION_HASQUOTA(&mp->m_sb) || flags == 0) {
15127 +@@ -425,7 +426,7 @@ xfs_qm_scall_quotaon(
15128 + uint accflags;
15129 + __int64_t sbflags;
15130 +
15131 +- if (!capable(CAP_SYS_ADMIN))
15132 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
15133 + return XFS_ERROR(EPERM);
15134 +
15135 + flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
15136 +@@ -594,7 +595,7 @@ xfs_qm_scall_setqlim(
15137 + int error;
15138 + xfs_qcnt_t hard, soft;
15139 +
15140 +- if (!capable(CAP_SYS_ADMIN))
15141 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
15142 + return XFS_ERROR(EPERM);
15143 +
15144 + if ((newlim->d_fieldmask &
15145 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_clnt.h linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_clnt.h
15146 +--- linux-2.6.22.19/fs/xfs/xfs_clnt.h 2006-06-18 04:54:50 +0200
15147 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_clnt.h 2007-08-05 20:53:13 +0200
15148 +@@ -99,5 +99,7 @@ struct xfs_mount_args {
15149 + */
15150 + #define XFSMNT2_COMPAT_IOSIZE 0x00000001 /* don't report large preferred
15151 + * I/O size in stat(2) */
15152 ++#define XFSMNT2_TAGGED 0x80000000 /* context tagging */
15153 ++
15154 +
15155 + #endif /* __XFS_CLNT_H__ */
15156 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_dinode.h linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_dinode.h
15157 +--- linux-2.6.22.19/fs/xfs/xfs_dinode.h 2006-09-20 16:58:40 +0200
15158 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_dinode.h 2007-08-05 20:53:13 +0200
15159 +@@ -53,7 +53,8 @@ typedef struct xfs_dinode_core
15160 + __uint32_t di_gid; /* owner's group id */
15161 + __uint32_t di_nlink; /* number of links to file */
15162 + __uint16_t di_projid; /* owner's project id */
15163 +- __uint8_t di_pad[8]; /* unused, zeroed space */
15164 ++ __uint16_t di_tag; /* context tagging */
15165 ++ __uint8_t di_pad[6]; /* unused, zeroed space */
15166 + __uint16_t di_flushiter; /* incremented on flush */
15167 + xfs_timestamp_t di_atime; /* time last accessed */
15168 + xfs_timestamp_t di_mtime; /* time last modified */
15169 +@@ -257,6 +258,9 @@ typedef enum xfs_dinode_fmt
15170 + #define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */
15171 + #define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */
15172 + #define XFS_DIFLAG_NODEFRAG_BIT 13 /* do not reorganize/defragment */
15173 ++#define XFS_DIFLAG_BARRIER_BIT 14 /* chroot() barrier */
15174 ++#define XFS_DIFLAG_IUNLINK_BIT 15 /* immutable unlink */
15175 ++
15176 + #define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT)
15177 + #define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT)
15178 + #define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT)
15179 +@@ -271,12 +275,15 @@ typedef enum xfs_dinode_fmt
15180 + #define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT)
15181 + #define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
15182 + #define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT)
15183 ++#define XFS_DIFLAG_BARRIER (1 << XFS_DIFLAG_BARRIER_BIT)
15184 ++#define XFS_DIFLAG_IUNLINK (1 << XFS_DIFLAG_IUNLINK_BIT)
15185 +
15186 + #define XFS_DIFLAG_ANY \
15187 + (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
15188 + XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
15189 + XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
15190 + XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
15191 +- XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG)
15192 ++ XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_BARRIER | \
15193 ++ XFS_DIFLAG_IUNLINK)
15194 +
15195 + #endif /* __XFS_DINODE_H__ */
15196 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_fs.h linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_fs.h
15197 +--- linux-2.6.22.19/fs/xfs/xfs_fs.h 2006-11-30 21:19:29 +0100
15198 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_fs.h 2007-08-05 20:53:13 +0200
15199 +@@ -66,6 +66,8 @@ struct fsxattr {
15200 + #define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
15201 + #define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
15202 + #define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
15203 ++#define XFS_XFLAG_BARRIER 0x00004000 /* chroot() barrier */
15204 ++#define XFS_XFLAG_IUNLINK 0x00008000 /* immutable unlink */
15205 + #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
15206 +
15207 + /*
15208 +@@ -294,7 +296,8 @@ typedef struct xfs_bstat {
15209 + __s32 bs_extents; /* number of extents */
15210 + __u32 bs_gen; /* generation count */
15211 + __u16 bs_projid; /* project id */
15212 +- unsigned char bs_pad[14]; /* pad space, unused */
15213 ++ __u16 bs_tag; /* context tagging */
15214 ++ unsigned char bs_pad[12]; /* pad space, unused */
15215 + __u32 bs_dmevmask; /* DMIG event mask */
15216 + __u16 bs_dmstate; /* DMIG state info */
15217 + __u16 bs_aextents; /* attribute number of extents */
15218 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_inode.c linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_inode.c
15219 +--- linux-2.6.22.19/fs/xfs/xfs_inode.c 2007-07-09 13:19:34 +0200
15220 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_inode.c 2007-08-05 20:53:13 +0200
15221 +@@ -49,6 +49,7 @@
15222 + #include "xfs_quota.h"
15223 + #include "xfs_acl.h"
15224 +
15225 ++#include <linux/vs_tag.h>
15226 +
15227 + kmem_zone_t *xfs_ifork_zone;
15228 + kmem_zone_t *xfs_inode_zone;
15229 +@@ -736,20 +737,35 @@ xfs_xlate_dinode_core(
15230 + xfs_dinode_core_t *buf_core = (xfs_dinode_core_t *)buf;
15231 + xfs_dinode_core_t *mem_core = (xfs_dinode_core_t *)dip;
15232 + xfs_arch_t arch = ARCH_CONVERT;
15233 ++ uint32_t uid = 0, gid = 0;
15234 ++ uint16_t tag = 0;
15235 +
15236 + ASSERT(dir);
15237 +
15238 ++ if (dir < 0) {
15239 ++ tag = mem_core->di_tag;
15240 ++ /* FIXME: supposed to use superblock flag */
15241 ++ uid = TAGINO_UID(1, mem_core->di_uid, tag);
15242 ++ gid = TAGINO_GID(1, mem_core->di_gid, tag);
15243 ++ tag = TAGINO_TAG(1, tag);
15244 ++ }
15245 ++
15246 + INT_XLATE(buf_core->di_magic, mem_core->di_magic, dir, arch);
15247 + INT_XLATE(buf_core->di_mode, mem_core->di_mode, dir, arch);
15248 + INT_XLATE(buf_core->di_version, mem_core->di_version, dir, arch);
15249 + INT_XLATE(buf_core->di_format, mem_core->di_format, dir, arch);
15250 + INT_XLATE(buf_core->di_onlink, mem_core->di_onlink, dir, arch);
15251 +- INT_XLATE(buf_core->di_uid, mem_core->di_uid, dir, arch);
15252 +- INT_XLATE(buf_core->di_gid, mem_core->di_gid, dir, arch);
15253 ++ INT_XLATE(buf_core->di_uid, uid, dir, arch);
15254 ++ INT_XLATE(buf_core->di_gid, gid, dir, arch);
15255 ++ INT_XLATE(buf_core->di_tag, tag, dir, arch);
15256 + INT_XLATE(buf_core->di_nlink, mem_core->di_nlink, dir, arch);
15257 + INT_XLATE(buf_core->di_projid, mem_core->di_projid, dir, arch);
15258 +
15259 + if (dir > 0) {
15260 ++ /* FIXME: supposed to use superblock flag */
15261 ++ mem_core->di_uid = INOTAG_UID(1, uid, gid);
15262 ++ mem_core->di_gid = INOTAG_GID(1, uid, gid);
15263 ++ mem_core->di_tag = INOTAG_TAG(1, uid, gid, tag);
15264 + memcpy(mem_core->di_pad, buf_core->di_pad,
15265 + sizeof(buf_core->di_pad));
15266 + } else {
15267 +@@ -797,6 +813,10 @@ _xfs_dic2xflags(
15268 + flags |= XFS_XFLAG_PREALLOC;
15269 + if (di_flags & XFS_DIFLAG_IMMUTABLE)
15270 + flags |= XFS_XFLAG_IMMUTABLE;
15271 ++ if (di_flags & XFS_DIFLAG_IUNLINK)
15272 ++ flags |= XFS_XFLAG_IUNLINK;
15273 ++ if (di_flags & XFS_DIFLAG_BARRIER)
15274 ++ flags |= XFS_XFLAG_BARRIER;
15275 + if (di_flags & XFS_DIFLAG_APPEND)
15276 + flags |= XFS_XFLAG_APPEND;
15277 + if (di_flags & XFS_DIFLAG_SYNC)
15278 +@@ -1129,6 +1149,7 @@ xfs_ialloc(
15279 + ASSERT(ip->i_d.di_nlink == nlink);
15280 + ip->i_d.di_uid = current_fsuid(cr);
15281 + ip->i_d.di_gid = current_fsgid(cr);
15282 ++ ip->i_d.di_tag = current_fstag(cr, vp);
15283 + ip->i_d.di_projid = prid;
15284 + memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
15285 +
15286 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_itable.c linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_itable.c
15287 +--- linux-2.6.22.19/fs/xfs/xfs_itable.c 2007-07-09 13:19:34 +0200
15288 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_itable.c 2007-08-05 20:53:13 +0200
15289 +@@ -89,6 +89,7 @@ xfs_bulkstat_one_iget(
15290 + buf->bs_mode = dic->di_mode;
15291 + buf->bs_uid = dic->di_uid;
15292 + buf->bs_gid = dic->di_gid;
15293 ++ buf->bs_tag = dic->di_tag;
15294 + buf->bs_size = dic->di_size;
15295 + vn_atime_to_bstime(vp, &buf->bs_atime);
15296 + buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
15297 +@@ -163,6 +164,7 @@ xfs_bulkstat_one_dinode(
15298 + buf->bs_mode = INT_GET(dic->di_mode, ARCH_CONVERT);
15299 + buf->bs_uid = INT_GET(dic->di_uid, ARCH_CONVERT);
15300 + buf->bs_gid = INT_GET(dic->di_gid, ARCH_CONVERT);
15301 ++ buf->bs_tag = INT_GET(dic->di_tag, ARCH_CONVERT);
15302 + buf->bs_size = INT_GET(dic->di_size, ARCH_CONVERT);
15303 + buf->bs_atime.tv_sec = INT_GET(dic->di_atime.t_sec, ARCH_CONVERT);
15304 + buf->bs_atime.tv_nsec = INT_GET(dic->di_atime.t_nsec, ARCH_CONVERT);
15305 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_mount.h linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_mount.h
15306 +--- linux-2.6.22.19/fs/xfs/xfs_mount.h 2007-05-02 19:25:23 +0200
15307 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_mount.h 2007-08-05 20:53:13 +0200
15308 +@@ -464,6 +464,7 @@ typedef struct xfs_mount {
15309 + #define XFS_MOUNT_NO_PERCPU_SB (1ULL << 23) /* don't use per-cpu superblock
15310 + counters */
15311 +
15312 ++#define XFS_MOUNT_TAGGED (1ULL << 31) /* context tagging */
15313 +
15314 + /*
15315 + * Default minimum read and write sizes.
15316 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_vfsops.c linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_vfsops.c
15317 +--- linux-2.6.22.19/fs/xfs/xfs_vfsops.c 2007-07-09 13:19:34 +0200
15318 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_vfsops.c 2007-08-05 20:53:13 +0200
15319 +@@ -300,6 +300,8 @@ xfs_start_flags(
15320 +
15321 + if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE)
15322 + mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
15323 ++ if (ap->flags2 & XFSMNT2_TAGGED)
15324 ++ mp->m_flags |= XFS_MOUNT_TAGGED;
15325 +
15326 + /*
15327 + * no recovery flag requires a read-only mount
15328 +@@ -394,6 +396,8 @@ xfs_finish_flags(
15329 + return XFS_ERROR(EINVAL);
15330 + }
15331 +
15332 ++ if (ap->flags2 & XFSMNT2_TAGGED)
15333 ++ vfs->vfs_super->s_flags |= MS_TAGGED;
15334 + return 0;
15335 + }
15336 +
15337 +@@ -1645,6 +1649,9 @@ xfs_vget(
15338 + * in stat(). */
15339 + #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */
15340 + #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
15341 ++#define MNTOPT_TAGXID "tagxid" /* context tagging for inodes */
15342 ++#define MNTOPT_TAGGED "tag" /* context tagging for inodes */
15343 ++#define MNTOPT_NOTAGTAG "notag" /* do not use context tagging */
15344 +
15345 + STATIC unsigned long
15346 + suffix_strtoul(char *s, char **endp, unsigned int base)
15347 +@@ -1831,6 +1838,19 @@ xfs_parseargs(
15348 + args->flags |= XFSMNT_ATTR2;
15349 + } else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
15350 + args->flags &= ~XFSMNT_ATTR2;
15351 ++#ifndef CONFIG_TAGGING_NONE
15352 ++ } else if (!strcmp(this_char, MNTOPT_TAGGED)) {
15353 ++ args->flags2 |= XFSMNT2_TAGGED;
15354 ++ } else if (!strcmp(this_char, MNTOPT_NOTAGTAG)) {
15355 ++ args->flags2 &= ~XFSMNT2_TAGGED;
15356 ++ } else if (!strcmp(this_char, MNTOPT_TAGXID)) {
15357 ++ args->flags2 |= XFSMNT2_TAGGED;
15358 ++#endif
15359 ++#ifdef CONFIG_PROPAGATE
15360 ++ } else if (!strcmp(this_char, MNTOPT_TAGGED)) {
15361 ++ /* use value */
15362 ++ args->flags2 |= XFSMNT2_TAGGED;
15363 ++#endif
15364 + } else if (!strcmp(this_char, "osyncisdsync")) {
15365 + /* no-op, this is now the default */
15366 + cmn_err(CE_WARN,
15367 +diff -NurpP --minimal linux-2.6.22.19/fs/xfs/xfs_vnodeops.c linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_vnodeops.c
15368 +--- linux-2.6.22.19/fs/xfs/xfs_vnodeops.c 2007-07-09 13:19:34 +0200
15369 ++++ linux-2.6.22.19-vs2.3.0.34/fs/xfs/xfs_vnodeops.c 2007-08-05 20:53:13 +0200
15370 +@@ -159,6 +159,7 @@ xfs_getattr(
15371 + vap->va_mode = ip->i_d.di_mode;
15372 + vap->va_uid = ip->i_d.di_uid;
15373 + vap->va_gid = ip->i_d.di_gid;
15374 ++ vap->va_tag = ip->i_d.di_tag;
15375 + vap->va_projid = ip->i_d.di_projid;
15376 +
15377 + /*
15378 +@@ -259,6 +260,7 @@ xfs_setattr(
15379 + uint commit_flags=0;
15380 + uid_t uid=0, iuid=0;
15381 + gid_t gid=0, igid=0;
15382 ++ tag_t tag=0, itag=0;
15383 + int timeflags = 0;
15384 + bhv_vnode_t *vp;
15385 + xfs_prid_t projid=0, iprojid=0;
15386 +@@ -315,6 +317,7 @@ xfs_setattr(
15387 + (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) {
15388 + uint qflags = 0;
15389 +
15390 ++ /* TODO: handle tagging? */
15391 + if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) {
15392 + uid = vap->va_uid;
15393 + qflags |= XFS_QMOPT_UQUOTA;
15394 +@@ -394,6 +397,8 @@ xfs_setattr(
15395 + if (mask &
15396 + (XFS_AT_MODE|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_UID|
15397 + XFS_AT_GID|XFS_AT_PROJID)) {
15398 ++ /* TODO: handle tagging? */
15399 ++
15400 + /*
15401 + * CAP_FOWNER overrides the following restrictions:
15402 + *
15403 +@@ -442,7 +447,7 @@ xfs_setattr(
15404 + * and can change the group id only to a group of which he
15405 + * or she is a member.
15406 + */
15407 +- if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
15408 ++ if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_TAG|XFS_AT_PROJID)) {
15409 + /*
15410 + * These IDs could have changed since we last looked at them.
15411 + * But, we're assured that if the ownership did change
15412 +@@ -450,10 +455,12 @@ xfs_setattr(
15413 + * would have changed also.
15414 + */
15415 + iuid = ip->i_d.di_uid;
15416 +- iprojid = ip->i_d.di_projid;
15417 + igid = ip->i_d.di_gid;
15418 +- gid = (mask & XFS_AT_GID) ? vap->va_gid : igid;
15419 ++ itag = ip->i_d.di_tag;
15420 ++ iprojid = ip->i_d.di_projid;
15421 + uid = (mask & XFS_AT_UID) ? vap->va_uid : iuid;
15422 ++ gid = (mask & XFS_AT_GID) ? vap->va_gid : igid;
15423 ++ tag = (mask & XFS_AT_TAG) ? vap->va_tag : itag;
15424 + projid = (mask & XFS_AT_PROJID) ? (xfs_prid_t)vap->va_projid :
15425 + iprojid;
15426 +
15427 +@@ -481,6 +488,7 @@ xfs_setattr(
15428 + if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
15429 + (XFS_IS_PQUOTA_ON(mp) && iprojid != projid) ||
15430 + (XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
15431 ++ /* TODO: handle tagging? */
15432 + ASSERT(tp);
15433 + code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
15434 + capable(CAP_FOWNER) ?
15435 +@@ -706,7 +714,7 @@ xfs_setattr(
15436 + * and can change the group id only to a group of which he
15437 + * or she is a member.
15438 + */
15439 +- if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
15440 ++ if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_TAG|XFS_AT_PROJID)) {
15441 + /*
15442 + * CAP_FSETID overrides the following restrictions:
15443 + *
15444 +@@ -722,6 +730,9 @@ xfs_setattr(
15445 + * Change the ownerships and register quota modifications
15446 + * in the transaction.
15447 + */
15448 ++ if (itag != tag) {
15449 ++ ip->i_d.di_tag = tag;
15450 ++ }
15451 + if (iuid != uid) {
15452 + if (XFS_IS_UQUOTA_ON(mp)) {
15453 + ASSERT(mask & XFS_AT_UID);
15454 +@@ -802,6 +813,10 @@ xfs_setattr(
15455 + di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
15456 + if (vap->va_xflags & XFS_XFLAG_IMMUTABLE)
15457 + di_flags |= XFS_DIFLAG_IMMUTABLE;
15458 ++ if (vap->va_xflags & XFS_XFLAG_IUNLINK)
15459 ++ di_flags |= XFS_DIFLAG_IUNLINK;
15460 ++ if (vap->va_xflags & XFS_XFLAG_BARRIER)
15461 ++ di_flags |= XFS_DIFLAG_BARRIER;
15462 + if (vap->va_xflags & XFS_XFLAG_APPEND)
15463 + di_flags |= XFS_DIFLAG_APPEND;
15464 + if (vap->va_xflags & XFS_XFLAG_SYNC)
15465 +diff -NurpP --minimal linux-2.6.22.19/include/asm-alpha/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-alpha/socket.h
15466 +--- linux-2.6.22.19/include/asm-alpha/socket.h 2007-07-09 13:19:35 +0200
15467 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-alpha/socket.h 2007-08-05 20:53:13 +0200
15468 +@@ -55,6 +55,8 @@
15469 + #define SO_TIMESTAMPNS 35
15470 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15471 +
15472 ++#define SO_PEERTAG 36
15473 ++
15474 + /* Security levels - as per NRL IPv6 - don't actually do anything */
15475 + #define SO_SECURITY_AUTHENTICATION 19
15476 + #define SO_SECURITY_ENCRYPTION_TRANSPORT 20
15477 +diff -NurpP --minimal linux-2.6.22.19/include/asm-arm/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-arm/socket.h
15478 +--- linux-2.6.22.19/include/asm-arm/socket.h 2007-07-09 13:19:39 +0200
15479 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-arm/socket.h 2007-08-05 20:53:13 +0200
15480 +@@ -52,4 +52,6 @@
15481 + #define SO_TIMESTAMPNS 35
15482 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15483 +
15484 ++#define SO_PEERTAG 36
15485 ++
15486 + #endif /* _ASM_SOCKET_H */
15487 +diff -NurpP --minimal linux-2.6.22.19/include/asm-arm/tlb.h linux-2.6.22.19-vs2.3.0.34/include/asm-arm/tlb.h
15488 +--- linux-2.6.22.19/include/asm-arm/tlb.h 2006-06-18 04:54:58 +0200
15489 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-arm/tlb.h 2007-08-05 20:53:13 +0200
15490 +@@ -28,6 +28,7 @@
15491 + #else /* !CONFIG_MMU */
15492 +
15493 + #include <asm/pgalloc.h>
15494 ++#include <linux/vs_memory.h>
15495 +
15496 + /*
15497 + * TLB handling. This allows us to remove pages from the page
15498 +diff -NurpP --minimal linux-2.6.22.19/include/asm-arm26/tlb.h linux-2.6.22.19-vs2.3.0.34/include/asm-arm26/tlb.h
15499 +--- linux-2.6.22.19/include/asm-arm26/tlb.h 2006-01-03 17:30:02 +0100
15500 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-arm26/tlb.h 2007-08-05 20:53:13 +0200
15501 +@@ -3,6 +3,7 @@
15502 +
15503 + #include <asm/pgalloc.h>
15504 + #include <asm/tlbflush.h>
15505 ++#include <linux/vs_memory.h>
15506 +
15507 + /*
15508 + * TLB handling. This allows us to remove pages from the page
15509 +diff -NurpP --minimal linux-2.6.22.19/include/asm-arm26/unistd.h linux-2.6.22.19-vs2.3.0.34/include/asm-arm26/unistd.h
15510 +--- linux-2.6.22.19/include/asm-arm26/unistd.h 2007-02-06 03:01:35 +0100
15511 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-arm26/unistd.h 2007-08-05 20:53:13 +0200
15512 +@@ -302,6 +302,8 @@
15513 + #define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279)
15514 + #define __NR_waitid (__NR_SYSCALL_BASE+280)
15515 +
15516 ++#define __NR_vserver (__NR_SYSCALL_BASE+313)
15517 ++
15518 + /*
15519 + * The following SWIs are ARM private. FIXME - make appropriate for arm26
15520 + */
15521 +diff -NurpP --minimal linux-2.6.22.19/include/asm-cris/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-cris/socket.h
15522 +--- linux-2.6.22.19/include/asm-cris/socket.h 2007-07-09 13:19:40 +0200
15523 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-cris/socket.h 2007-08-05 20:53:13 +0200
15524 +@@ -54,6 +54,8 @@
15525 + #define SO_TIMESTAMPNS 35
15526 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15527 +
15528 ++#define SO_PEERTAG 36
15529 ++
15530 + #endif /* _ASM_SOCKET_H */
15531 +
15532 +
15533 +diff -NurpP --minimal linux-2.6.22.19/include/asm-frv/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-frv/socket.h
15534 +--- linux-2.6.22.19/include/asm-frv/socket.h 2007-07-09 13:19:40 +0200
15535 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-frv/socket.h 2007-08-05 20:53:13 +0200
15536 +@@ -52,5 +52,7 @@
15537 + #define SO_TIMESTAMPNS 35
15538 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15539 +
15540 ++#define SO_PEERTAG 36
15541 ++
15542 + #endif /* _ASM_SOCKET_H */
15543 +
15544 +diff -NurpP --minimal linux-2.6.22.19/include/asm-generic/tlb.h linux-2.6.22.19-vs2.3.0.34/include/asm-generic/tlb.h
15545 +--- linux-2.6.22.19/include/asm-generic/tlb.h 2006-11-30 21:19:31 +0100
15546 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-generic/tlb.h 2007-08-05 20:53:13 +0200
15547 +@@ -14,6 +14,7 @@
15548 + #define _ASM_GENERIC__TLB_H
15549 +
15550 + #include <linux/swap.h>
15551 ++#include <linux/vs_memory.h>
15552 + #include <asm/pgalloc.h>
15553 + #include <asm/tlbflush.h>
15554 +
15555 +diff -NurpP --minimal linux-2.6.22.19/include/asm-h8300/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-h8300/socket.h
15556 +--- linux-2.6.22.19/include/asm-h8300/socket.h 2007-07-09 13:19:40 +0200
15557 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-h8300/socket.h 2007-08-05 20:53:13 +0200
15558 +@@ -52,4 +52,6 @@
15559 + #define SO_TIMESTAMPNS 35
15560 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15561 +
15562 ++#define SO_PEERTAG 36
15563 ++
15564 + #endif /* _ASM_SOCKET_H */
15565 +diff -NurpP --minimal linux-2.6.22.19/include/asm-i386/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-i386/socket.h
15566 +--- linux-2.6.22.19/include/asm-i386/socket.h 2007-07-09 13:19:42 +0200
15567 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-i386/socket.h 2007-08-05 20:53:13 +0200
15568 +@@ -52,4 +52,6 @@
15569 + #define SO_TIMESTAMPNS 35
15570 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15571 +
15572 ++#define SO_PEERTAG 36
15573 ++
15574 + #endif /* _ASM_SOCKET_H */
15575 +diff -NurpP --minimal linux-2.6.22.19/include/asm-ia64/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-ia64/socket.h
15576 +--- linux-2.6.22.19/include/asm-ia64/socket.h 2007-07-09 13:19:43 +0200
15577 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-ia64/socket.h 2007-08-05 20:53:13 +0200
15578 +@@ -61,4 +61,6 @@
15579 + #define SO_TIMESTAMPNS 35
15580 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15581 +
15582 ++#define SO_PEERTAG 36
15583 ++
15584 + #endif /* _ASM_IA64_SOCKET_H */
15585 +diff -NurpP --minimal linux-2.6.22.19/include/asm-ia64/tlb.h linux-2.6.22.19-vs2.3.0.34/include/asm-ia64/tlb.h
15586 +--- linux-2.6.22.19/include/asm-ia64/tlb.h 2006-09-20 16:58:40 +0200
15587 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-ia64/tlb.h 2007-08-05 20:53:13 +0200
15588 +@@ -40,6 +40,7 @@
15589 + #include <linux/mm.h>
15590 + #include <linux/pagemap.h>
15591 + #include <linux/swap.h>
15592 ++#include <linux/vs_memory.h>
15593 +
15594 + #include <asm/pgalloc.h>
15595 + #include <asm/processor.h>
15596 +diff -NurpP --minimal linux-2.6.22.19/include/asm-m32r/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-m32r/socket.h
15597 +--- linux-2.6.22.19/include/asm-m32r/socket.h 2007-07-09 13:19:43 +0200
15598 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-m32r/socket.h 2007-08-05 20:53:13 +0200
15599 +@@ -52,4 +52,6 @@
15600 + #define SO_TIMESTAMPNS 35
15601 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15602 +
15603 ++#define SO_PEERTAG 36
15604 ++
15605 + #endif /* _ASM_M32R_SOCKET_H */
15606 +diff -NurpP --minimal linux-2.6.22.19/include/asm-mips/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-mips/socket.h
15607 +--- linux-2.6.22.19/include/asm-mips/socket.h 2007-07-09 13:19:44 +0200
15608 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-mips/socket.h 2007-08-05 20:53:13 +0200
15609 +@@ -73,6 +73,8 @@ To add: #define SO_REUSEPORT 0x0200 /* A
15610 + #define SO_TIMESTAMPNS 35
15611 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15612 +
15613 ++#define SO_PEERTAG 36
15614 ++
15615 + #ifdef __KERNEL__
15616 +
15617 + /** sock_type - Socket types
15618 +diff -NurpP --minimal linux-2.6.22.19/include/asm-parisc/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-parisc/socket.h
15619 +--- linux-2.6.22.19/include/asm-parisc/socket.h 2007-07-09 13:19:44 +0200
15620 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-parisc/socket.h 2007-08-05 20:53:13 +0200
15621 +@@ -51,5 +51,6 @@
15622 +
15623 + #define SO_PEERSEC 0x401d
15624 + #define SO_PASSSEC 0x401e
15625 ++#define SO_PEERTAG 0x401f
15626 +
15627 + #endif /* _ASM_SOCKET_H */
15628 +diff -NurpP --minimal linux-2.6.22.19/include/asm-powerpc/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-powerpc/socket.h
15629 +--- linux-2.6.22.19/include/asm-powerpc/socket.h 2007-07-09 13:19:44 +0200
15630 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-powerpc/socket.h 2007-08-05 20:53:13 +0200
15631 +@@ -59,4 +59,6 @@
15632 + #define SO_TIMESTAMPNS 35
15633 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15634 +
15635 ++#define SO_PEERTAG 36
15636 ++
15637 + #endif /* _ASM_POWERPC_SOCKET_H */
15638 +diff -NurpP --minimal linux-2.6.22.19/include/asm-powerpc/systbl.h linux-2.6.22.19-vs2.3.0.34/include/asm-powerpc/systbl.h
15639 +--- linux-2.6.22.19/include/asm-powerpc/systbl.h 2007-07-09 13:19:44 +0200
15640 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-powerpc/systbl.h 2007-08-05 20:53:13 +0200
15641 +@@ -260,7 +260,7 @@ COMPAT_SYS_SPU(fstatfs64)
15642 + SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64)
15643 + PPC_SYS_SPU(rtas)
15644 + OLDSYS(debug_setcontext)
15645 +-SYSCALL(ni_syscall)
15646 ++SYSX(sys_vserver, sys32_vserver, sys_vserver)
15647 + COMPAT_SYS(migrate_pages)
15648 + COMPAT_SYS(mbind)
15649 + COMPAT_SYS(get_mempolicy)
15650 +diff -NurpP --minimal linux-2.6.22.19/include/asm-powerpc/unistd.h linux-2.6.22.19-vs2.3.0.34/include/asm-powerpc/unistd.h
15651 +--- linux-2.6.22.19/include/asm-powerpc/unistd.h 2007-07-09 13:19:45 +0200
15652 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-powerpc/unistd.h 2007-08-05 20:53:13 +0200
15653 +@@ -275,7 +275,7 @@
15654 + #endif
15655 + #define __NR_rtas 255
15656 + #define __NR_sys_debug_setcontext 256
15657 +-/* Number 257 is reserved for vserver */
15658 ++#define __NR_vserver 257
15659 + #define __NR_migrate_pages 258
15660 + #define __NR_mbind 259
15661 + #define __NR_get_mempolicy 260
15662 +diff -NurpP --minimal linux-2.6.22.19/include/asm-s390/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-s390/socket.h
15663 +--- linux-2.6.22.19/include/asm-s390/socket.h 2007-07-09 13:19:45 +0200
15664 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-s390/socket.h 2007-08-05 20:53:13 +0200
15665 +@@ -60,4 +60,6 @@
15666 + #define SO_TIMESTAMPNS 35
15667 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15668 +
15669 ++#define SO_PEERTAG 36
15670 ++
15671 + #endif /* _ASM_SOCKET_H */
15672 +diff -NurpP --minimal linux-2.6.22.19/include/asm-s390/unistd.h linux-2.6.22.19-vs2.3.0.34/include/asm-s390/unistd.h
15673 +--- linux-2.6.22.19/include/asm-s390/unistd.h 2007-07-09 13:19:45 +0200
15674 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-s390/unistd.h 2007-08-05 20:53:13 +0200
15675 +@@ -202,7 +202,7 @@
15676 + #define __NR_clock_gettime (__NR_timer_create+6)
15677 + #define __NR_clock_getres (__NR_timer_create+7)
15678 + #define __NR_clock_nanosleep (__NR_timer_create+8)
15679 +-/* Number 263 is reserved for vserver */
15680 ++#define __NR_vserver 263
15681 + #define __NR_statfs64 265
15682 + #define __NR_fstatfs64 266
15683 + #define __NR_remap_file_pages 267
15684 +diff -NurpP --minimal linux-2.6.22.19/include/asm-sh/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-sh/socket.h
15685 +--- linux-2.6.22.19/include/asm-sh/socket.h 2007-07-09 13:19:45 +0200
15686 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-sh/socket.h 2007-08-05 20:53:13 +0200
15687 +@@ -52,4 +52,6 @@
15688 + #define SO_TIMESTAMPNS 35
15689 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15690 +
15691 ++#define SO_PEERTAG 36
15692 ++
15693 + #endif /* __ASM_SH_SOCKET_H */
15694 +diff -NurpP --minimal linux-2.6.22.19/include/asm-sparc/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-sparc/socket.h
15695 +--- linux-2.6.22.19/include/asm-sparc/socket.h 2007-07-09 13:19:54 +0200
15696 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-sparc/socket.h 2007-08-05 20:53:13 +0200
15697 +@@ -52,6 +52,8 @@
15698 + #define SO_TIMESTAMPNS 0x0021
15699 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15700 +
15701 ++#define SO_PEERTAG 36
15702 ++
15703 + /* Security levels - as per NRL IPv6 - don't actually do anything */
15704 + #define SO_SECURITY_AUTHENTICATION 0x5001
15705 + #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
15706 +diff -NurpP --minimal linux-2.6.22.19/include/asm-sparc/unistd.h linux-2.6.22.19-vs2.3.0.34/include/asm-sparc/unistd.h
15707 +--- linux-2.6.22.19/include/asm-sparc/unistd.h 2007-07-09 13:19:54 +0200
15708 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-sparc/unistd.h 2007-08-05 20:53:13 +0200
15709 +@@ -283,7 +283,7 @@
15710 + #define __NR_timer_getoverrun 264
15711 + #define __NR_timer_delete 265
15712 + #define __NR_timer_create 266
15713 +-/* #define __NR_vserver 267 Reserved for VSERVER */
15714 ++#define __NR_vserver 267
15715 + #define __NR_io_setup 268
15716 + #define __NR_io_destroy 269
15717 + #define __NR_io_submit 270
15718 +diff -NurpP --minimal linux-2.6.22.19/include/asm-sparc64/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-sparc64/socket.h
15719 +--- linux-2.6.22.19/include/asm-sparc64/socket.h 2007-07-09 13:19:54 +0200
15720 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-sparc64/socket.h 2007-08-05 20:53:13 +0200
15721 +@@ -52,6 +52,8 @@
15722 + #define SO_TIMESTAMPNS 0x0021
15723 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15724 +
15725 ++#define SO_PEERTAG 0x0022
15726 ++
15727 + /* Security levels - as per NRL IPv6 - don't actually do anything */
15728 + #define SO_SECURITY_AUTHENTICATION 0x5001
15729 + #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
15730 +diff -NurpP --minimal linux-2.6.22.19/include/asm-sparc64/tlb.h linux-2.6.22.19-vs2.3.0.34/include/asm-sparc64/tlb.h
15731 +--- linux-2.6.22.19/include/asm-sparc64/tlb.h 2007-07-09 13:19:54 +0200
15732 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-sparc64/tlb.h 2007-08-05 20:53:13 +0200
15733 +@@ -3,6 +3,7 @@
15734 +
15735 + #include <linux/swap.h>
15736 + #include <linux/pagemap.h>
15737 ++#include <linux/vs_memory.h>
15738 + #include <asm/pgalloc.h>
15739 + #include <asm/tlbflush.h>
15740 + #include <asm/mmu_context.h>
15741 +diff -NurpP --minimal linux-2.6.22.19/include/asm-sparc64/unistd.h linux-2.6.22.19-vs2.3.0.34/include/asm-sparc64/unistd.h
15742 +--- linux-2.6.22.19/include/asm-sparc64/unistd.h 2007-07-09 13:19:54 +0200
15743 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-sparc64/unistd.h 2007-08-05 20:53:13 +0200
15744 +@@ -285,7 +285,7 @@
15745 + #define __NR_timer_getoverrun 264
15746 + #define __NR_timer_delete 265
15747 + #define __NR_timer_create 266
15748 +-/* #define __NR_vserver 267 Reserved for VSERVER */
15749 ++#define __NR_vserver 267
15750 + #define __NR_io_setup 268
15751 + #define __NR_io_destroy 269
15752 + #define __NR_io_submit 270
15753 +diff -NurpP --minimal linux-2.6.22.19/include/asm-v850/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-v850/socket.h
15754 +--- linux-2.6.22.19/include/asm-v850/socket.h 2007-07-09 13:19:55 +0200
15755 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-v850/socket.h 2007-08-05 20:53:13 +0200
15756 +@@ -52,4 +52,6 @@
15757 + #define SO_TIMESTAMPNS 35
15758 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15759 +
15760 ++#define SO_PEERTAG 36
15761 ++
15762 + #endif /* __V850_SOCKET_H__ */
15763 +diff -NurpP --minimal linux-2.6.22.19/include/asm-x86_64/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-x86_64/socket.h
15764 +--- linux-2.6.22.19/include/asm-x86_64/socket.h 2007-07-09 13:19:55 +0200
15765 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-x86_64/socket.h 2007-08-05 20:53:13 +0200
15766 +@@ -52,4 +52,6 @@
15767 + #define SO_TIMESTAMPNS 35
15768 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15769 +
15770 ++#define SO_PEERTAG 36
15771 ++
15772 + #endif /* _ASM_SOCKET_H */
15773 +diff -NurpP --minimal linux-2.6.22.19/include/asm-x86_64/unistd.h linux-2.6.22.19-vs2.3.0.34/include/asm-x86_64/unistd.h
15774 +--- linux-2.6.22.19/include/asm-x86_64/unistd.h 2007-07-09 13:19:55 +0200
15775 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-x86_64/unistd.h 2007-08-05 20:53:13 +0200
15776 +@@ -532,7 +532,7 @@ __SYSCALL(__NR_tgkill, sys_tgkill)
15777 + #define __NR_utimes 235
15778 + __SYSCALL(__NR_utimes, sys_utimes)
15779 + #define __NR_vserver 236
15780 +-__SYSCALL(__NR_vserver, sys_ni_syscall)
15781 ++__SYSCALL(__NR_vserver, sys_vserver)
15782 + #define __NR_mbind 237
15783 + __SYSCALL(__NR_mbind, sys_mbind)
15784 + #define __NR_set_mempolicy 238
15785 +diff -NurpP --minimal linux-2.6.22.19/include/asm-xtensa/socket.h linux-2.6.22.19-vs2.3.0.34/include/asm-xtensa/socket.h
15786 +--- linux-2.6.22.19/include/asm-xtensa/socket.h 2007-07-09 13:19:55 +0200
15787 ++++ linux-2.6.22.19-vs2.3.0.34/include/asm-xtensa/socket.h 2007-08-05 20:53:13 +0200
15788 +@@ -63,4 +63,6 @@
15789 + #define SO_TIMESTAMPNS 35
15790 + #define SCM_TIMESTAMPNS SO_TIMESTAMPNS
15791 +
15792 ++#define SO_PEERTAG 36
15793 ++
15794 + #endif /* _XTENSA_SOCKET_H */
15795 +diff -NurpP --minimal linux-2.6.22.19/include/linux/Kbuild linux-2.6.22.19-vs2.3.0.34/include/linux/Kbuild
15796 +--- linux-2.6.22.19/include/linux/Kbuild 2008-03-14 20:19:04 +0100
15797 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/Kbuild 2007-09-30 14:58:01 +0200
15798 +@@ -351,3 +351,6 @@ unifdef-y += xattr.h
15799 + unifdef-y += xfrm.h
15800 +
15801 + objhdr-y += version.h
15802 ++
15803 ++header-y += vserver/
15804 ++
15805 +diff -NurpP --minimal linux-2.6.22.19/include/linux/capability.h linux-2.6.22.19-vs2.3.0.34/include/linux/capability.h
15806 +--- linux-2.6.22.19/include/linux/capability.h 2007-07-09 13:19:55 +0200
15807 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/capability.h 2007-08-05 20:53:13 +0200
15808 +@@ -237,6 +237,7 @@ typedef __u32 kernel_cap_t;
15809 + arbitrary SCSI commands */
15810 + /* Allow setting encryption key on loopback filesystem */
15811 + /* Allow setting zone reclaim policy */
15812 ++/* Allow the selection of a security context */
15813 +
15814 + #define CAP_SYS_ADMIN 21
15815 +
15816 +@@ -290,6 +291,11 @@ typedef __u32 kernel_cap_t;
15817 +
15818 + #define CAP_AUDIT_CONTROL 30
15819 +
15820 ++/* Allow context manipulations */
15821 ++/* Allow changing context info on files */
15822 ++
15823 ++#define CAP_CONTEXT 31
15824 ++
15825 + #ifdef __KERNEL__
15826 + /*
15827 + * Bounding set
15828 +diff -NurpP --minimal linux-2.6.22.19/include/linux/devpts_fs.h linux-2.6.22.19-vs2.3.0.34/include/linux/devpts_fs.h
15829 +--- linux-2.6.22.19/include/linux/devpts_fs.h 2004-08-14 12:55:59 +0200
15830 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/devpts_fs.h 2007-10-06 18:19:52 +0200
15831 +@@ -30,5 +30,4 @@ static inline void devpts_pty_kill(int n
15832 +
15833 + #endif
15834 +
15835 +-
15836 + #endif /* _LINUX_DEVPTS_FS_H */
15837 +diff -NurpP --minimal linux-2.6.22.19/include/linux/ext2_fs.h linux-2.6.22.19-vs2.3.0.34/include/linux/ext2_fs.h
15838 +--- linux-2.6.22.19/include/linux/ext2_fs.h 2006-11-30 21:19:37 +0100
15839 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/ext2_fs.h 2007-10-05 15:07:22 +0200
15840 +@@ -188,6 +188,8 @@ struct ext2_group_desc
15841 + #define EXT2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */
15842 + #define EXT2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */
15843 + #define EXT2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
15844 ++#define EXT2_BARRIER_FL FS_BARRIER_FL /* Barrier for chroot() */
15845 ++#define EXT2_IUNLINK_FL FS_IUNLINK_FL /* Immutable unlink */
15846 + #define EXT2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */
15847 +
15848 + #define EXT2_FL_USER_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */
15849 +@@ -244,7 +246,7 @@ struct ext2_inode {
15850 + struct {
15851 + __u8 l_i_frag; /* Fragment number */
15852 + __u8 l_i_fsize; /* Fragment size */
15853 +- __u16 i_pad1;
15854 ++ __u16 l_i_tag; /* Context Tag */
15855 + __le16 l_i_uid_high; /* these 2 fields */
15856 + __le16 l_i_gid_high; /* were reserved2[0] */
15857 + __u32 l_i_reserved2;
15858 +@@ -276,6 +278,7 @@ struct ext2_inode {
15859 + #define i_gid_low i_gid
15860 + #define i_uid_high osd2.linux2.l_i_uid_high
15861 + #define i_gid_high osd2.linux2.l_i_gid_high
15862 ++#define i_raw_tag osd2.linux2.l_i_tag
15863 + #define i_reserved2 osd2.linux2.l_i_reserved2
15864 + #endif
15865 +
15866 +@@ -317,8 +320,9 @@ struct ext2_inode {
15867 + #define EXT2_MOUNT_XATTR_USER 0x004000 /* Extended user attributes */
15868 + #define EXT2_MOUNT_POSIX_ACL 0x008000 /* POSIX Access Control Lists */
15869 + #define EXT2_MOUNT_XIP 0x010000 /* Execute in place */
15870 +-#define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */
15871 +-#define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */
15872 ++#define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */
15873 ++#define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */
15874 ++#define EXT2_MOUNT_TAGGED (1<<24) /* Enable Context Tags */
15875 +
15876 +
15877 + #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
15878 +diff -NurpP --minimal linux-2.6.22.19/include/linux/ext3_fs.h linux-2.6.22.19-vs2.3.0.34/include/linux/ext3_fs.h
15879 +--- linux-2.6.22.19/include/linux/ext3_fs.h 2007-07-09 13:19:56 +0200
15880 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/ext3_fs.h 2007-08-05 20:53:13 +0200
15881 +@@ -177,6 +177,8 @@ struct ext3_group_desc
15882 + #define EXT3_NOTAIL_FL 0x00008000 /* file tail should not be merged */
15883 + #define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
15884 + #define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
15885 ++#define EXT3_BARRIER_FL 0x04000000 /* Barrier for chroot() */
15886 ++#define EXT3_IUNLINK_FL 0x08000000 /* Immutable unlink */
15887 + #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */
15888 +
15889 + #define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
15890 +@@ -296,7 +298,7 @@ struct ext3_inode {
15891 + struct {
15892 + __u8 l_i_frag; /* Fragment number */
15893 + __u8 l_i_fsize; /* Fragment size */
15894 +- __u16 i_pad1;
15895 ++ __u16 l_i_tag; /* Context Tag */
15896 + __le16 l_i_uid_high; /* these 2 fields */
15897 + __le16 l_i_gid_high; /* were reserved2[0] */
15898 + __u32 l_i_reserved2;
15899 +@@ -330,6 +332,7 @@ struct ext3_inode {
15900 + #define i_gid_low i_gid
15901 + #define i_uid_high osd2.linux2.l_i_uid_high
15902 + #define i_gid_high osd2.linux2.l_i_gid_high
15903 ++#define i_raw_tag osd2.linux2.l_i_tag
15904 + #define i_reserved2 osd2.linux2.l_i_reserved2
15905 +
15906 + #elif defined(__GNU__)
15907 +@@ -384,6 +387,7 @@ struct ext3_inode {
15908 + #define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */
15909 + #define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
15910 + #define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
15911 ++#define EXT3_MOUNT_TAGGED (1<<24) /* Enable Context Tags */
15912 +
15913 + /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
15914 + #ifndef _LINUX_EXT2_FS_H
15915 +@@ -812,6 +816,7 @@ struct buffer_head * ext3_bread (handle_
15916 + int ext3_get_blocks_handle(handle_t *handle, struct inode *inode,
15917 + sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result,
15918 + int create, int extend_disksize);
15919 ++extern int ext3_sync_flags(struct inode *inode);
15920 +
15921 + extern void ext3_read_inode (struct inode *);
15922 + extern int ext3_write_inode (struct inode *, int);
15923 +diff -NurpP --minimal linux-2.6.22.19/include/linux/ext4_fs.h linux-2.6.22.19-vs2.3.0.34/include/linux/ext4_fs.h
15924 +--- linux-2.6.22.19/include/linux/ext4_fs.h 2007-07-09 13:19:56 +0200
15925 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/ext4_fs.h 2007-08-05 20:53:13 +0200
15926 +@@ -189,8 +189,10 @@ struct ext4_group_desc
15927 + #define EXT4_NOTAIL_FL 0x00008000 /* file tail should not be merged */
15928 + #define EXT4_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
15929 + #define EXT4_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
15930 +-#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
15931 + #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
15932 ++#define EXT4_BARRIER_FL 0x04000000 /* Barrier for chroot() */
15933 ++#define EXT4_IUNLINK_FL 0x08000000 /* Immutable unlink */
15934 ++#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
15935 +
15936 + #define EXT4_FL_USER_VISIBLE 0x000BDFFF /* User visible flags */
15937 + #define EXT4_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
15938 +@@ -312,7 +314,8 @@ struct ext4_inode {
15939 + __le16 l_i_file_acl_high;
15940 + __le16 l_i_uid_high; /* these 2 fields */
15941 + __le16 l_i_gid_high; /* were reserved2[0] */
15942 +- __u32 l_i_reserved2;
15943 ++ __u16 l_i_tag; /* Context Tag */
15944 ++ __u16 l_i_reserved2;
15945 + } linux2;
15946 + struct {
15947 + __u8 h_i_frag; /* Fragment number */
15948 +@@ -344,6 +347,7 @@ struct ext4_inode {
15949 + #define i_gid_low i_gid
15950 + #define i_uid_high osd2.linux2.l_i_uid_high
15951 + #define i_gid_high osd2.linux2.l_i_gid_high
15952 ++#define i_raw_tag osd2.linux2.l_i_tag
15953 + #define i_reserved2 osd2.linux2.l_i_reserved2
15954 +
15955 + #elif defined(__GNU__)
15956 +@@ -400,6 +404,7 @@ struct ext4_inode {
15957 + #define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
15958 + #define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
15959 + #define EXT4_MOUNT_EXTENTS 0x400000 /* Extents support */
15960 ++#define EXT4_MOUNT_TAGGED (1<<24) /* Enable Context Tags */
15961 +
15962 + /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */
15963 + #ifndef _LINUX_EXT2_FS_H
15964 +@@ -850,6 +855,7 @@ struct buffer_head * ext4_bread (handle_
15965 + int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
15966 + sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result,
15967 + int create, int extend_disksize);
15968 ++extern int ext4_sync_flags(struct inode *inode);
15969 +
15970 + extern void ext4_read_inode (struct inode *);
15971 + extern int ext4_write_inode (struct inode *, int);
15972 +diff -NurpP --minimal linux-2.6.22.19/include/linux/fs.h linux-2.6.22.19-vs2.3.0.34/include/linux/fs.h
15973 +--- linux-2.6.22.19/include/linux/fs.h 2007-07-09 13:19:56 +0200
15974 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/fs.h 2007-10-20 00:01:05 +0200
15975 +@@ -123,6 +123,8 @@ extern int dir_notify_enable;
15976 + #define MS_SLAVE (1<<19) /* change to slave */
15977 + #define MS_SHARED (1<<20) /* change to shared */
15978 + #define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */
15979 ++#define MS_TAGGED (1<<24) /* use generic inode tagging */
15980 ++#define MS_TAGID (1<<25) /* use specific tag for this mount */
15981 + #define MS_ACTIVE (1<<30)
15982 + #define MS_NOUSER (1<<31)
15983 +
15984 +@@ -149,6 +151,8 @@ extern int dir_notify_enable;
15985 + #define S_NOCMTIME 128 /* Do not update file c/mtime */
15986 + #define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */
15987 + #define S_PRIVATE 512 /* Inode is fs-internal */
15988 ++#define S_BARRIER 1024 /* Barrier for chroot() */
15989 ++#define S_IUNLINK 2048 /* Immutable unlink */
15990 +
15991 + /*
15992 + * Note that nosuid etc flags are inode-specific: setting some file-system
15993 +@@ -165,24 +169,36 @@ extern int dir_notify_enable;
15994 + */
15995 + #define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg))
15996 +
15997 +-#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
15998 ++#define IS_RDONLY(inode) __IS_FLG(inode, MS_RDONLY)
15999 + #define IS_SYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS) || \
16000 + ((inode)->i_flags & S_SYNC))
16001 + #define IS_DIRSYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \
16002 + ((inode)->i_flags & (S_SYNC|S_DIRSYNC)))
16003 + #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK)
16004 +-#define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
16005 ++#define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
16006 ++#define IS_TAGGED(inode) __IS_FLG(inode, MS_TAGGED)
16007 +
16008 + #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
16009 + #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
16010 + #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
16011 ++#define IS_IUNLINK(inode) ((inode)->i_flags & S_IUNLINK)
16012 ++#define IS_IXORUNLINK(inode) ((IS_IUNLINK(inode) ? S_IMMUTABLE : 0) ^ IS_IMMUTABLE(inode))
16013 + #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
16014 +
16015 ++#define IS_BARRIER(inode) (S_ISDIR((inode)->i_mode) && ((inode)->i_flags & S_BARRIER))
16016 + #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
16017 + #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME)
16018 + #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE)
16019 + #define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE)
16020 +
16021 ++#ifdef CONFIG_VSERVER_COWBL
16022 ++# define IS_COW(inode) (IS_IUNLINK(inode) && IS_IMMUTABLE(inode))
16023 ++# define IS_COW_LINK(inode) (S_ISREG((inode)->i_mode) && ((inode)->i_nlink > 1))
16024 ++#else
16025 ++# define IS_COW(inode) (0)
16026 ++# define IS_COW_LINK(inode) (0)
16027 ++#endif
16028 ++
16029 + /* the read-only stuff doesn't really belong here, but any other place is
16030 + probably as bad and I don't want to create yet another include file. */
16031 +
16032 +@@ -256,12 +272,13 @@ extern int dir_notify_enable;
16033 + #define FS_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
16034 + #define FS_EXTENT_FL 0x00080000 /* Extents */
16035 + #define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */
16036 ++#define FS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
16037 ++#define FS_IUNLINK_FL 0x08000000 /* Immutable unlink */
16038 + #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
16039 +
16040 + #define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
16041 + #define FS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
16042 +
16043 +-
16044 + #define SYNC_FILE_RANGE_WAIT_BEFORE 1
16045 + #define SYNC_FILE_RANGE_WRITE 2
16046 + #define SYNC_FILE_RANGE_WAIT_AFTER 4
16047 +@@ -327,6 +344,7 @@ typedef void (dio_iodone_t)(struct kiocb
16048 + #define ATTR_KILL_SUID 2048
16049 + #define ATTR_KILL_SGID 4096
16050 + #define ATTR_FILE 8192
16051 ++#define ATTR_TAG 16384
16052 +
16053 + /*
16054 + * This is the Inode Attributes structure, used for notify_change(). It
16055 +@@ -342,6 +360,7 @@ struct iattr {
16056 + umode_t ia_mode;
16057 + uid_t ia_uid;
16058 + gid_t ia_gid;
16059 ++ tag_t ia_tag;
16060 + loff_t ia_size;
16061 + struct timespec ia_atime;
16062 + struct timespec ia_mtime;
16063 +@@ -355,6 +374,9 @@ struct iattr {
16064 + struct file *ia_file;
16065 + };
16066 +
16067 ++#define ATTR_FLAG_BARRIER 512 /* Barrier for chroot() */
16068 ++#define ATTR_FLAG_IUNLINK 1024 /* Immutable unlink */
16069 ++
16070 + /*
16071 + * Includes for diskquotas.
16072 + */
16073 +@@ -537,7 +559,9 @@ struct inode {
16074 + unsigned int i_nlink;
16075 + uid_t i_uid;
16076 + gid_t i_gid;
16077 ++ tag_t i_tag;
16078 + dev_t i_rdev;
16079 ++ dev_t i_mdev;
16080 + unsigned long i_version;
16081 + loff_t i_size;
16082 + #ifdef __NEED_I_SIZE_ORDERED
16083 +@@ -672,12 +696,12 @@ static inline void i_size_write(struct i
16084 +
16085 + static inline unsigned iminor(const struct inode *inode)
16086 + {
16087 +- return MINOR(inode->i_rdev);
16088 ++ return MINOR(inode->i_mdev);
16089 + }
16090 +
16091 + static inline unsigned imajor(const struct inode *inode)
16092 + {
16093 +- return MAJOR(inode->i_rdev);
16094 ++ return MAJOR(inode->i_mdev);
16095 + }
16096 +
16097 + extern struct block_device *I_BDEV(struct inode *inode);
16098 +@@ -728,6 +752,7 @@ struct file {
16099 + loff_t f_pos;
16100 + struct fown_struct f_owner;
16101 + unsigned int f_uid, f_gid;
16102 ++ xid_t f_xid;
16103 + struct file_ra_state f_ra;
16104 +
16105 + unsigned long f_version;
16106 +@@ -811,6 +836,7 @@ struct file_lock {
16107 + unsigned char fl_type;
16108 + loff_t fl_start;
16109 + loff_t fl_end;
16110 ++ xid_t fl_xid;
16111 +
16112 + struct fasync_struct * fl_fasync; /* for lease break notifications */
16113 + unsigned long fl_break_time; /* for nonblocking lease breaks */
16114 +@@ -993,12 +1019,12 @@ extern void unlock_super(struct super_bl
16115 + */
16116 + extern int vfs_permission(struct nameidata *, int);
16117 + extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
16118 +-extern int vfs_mkdir(struct inode *, struct dentry *, int);
16119 +-extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
16120 +-extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
16121 +-extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
16122 +-extern int vfs_rmdir(struct inode *, struct dentry *);
16123 +-extern int vfs_unlink(struct inode *, struct dentry *);
16124 ++extern int vfs_mkdir(struct inode *, struct dentry *, int, struct nameidata *);
16125 ++extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t, struct nameidata *);
16126 ++extern int vfs_symlink(struct inode *, struct dentry *, const char *, int, struct nameidata *);
16127 ++extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct nameidata *);
16128 ++extern int vfs_rmdir(struct inode *, struct dentry *, struct nameidata *);
16129 ++extern int vfs_unlink(struct inode *, struct dentry *, struct nameidata *);
16130 + extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
16131 +
16132 + /*
16133 +@@ -1138,6 +1164,7 @@ struct inode_operations {
16134 + ssize_t (*listxattr) (struct dentry *, char *, size_t);
16135 + int (*removexattr) (struct dentry *, const char *);
16136 + void (*truncate_range)(struct inode *, loff_t, loff_t);
16137 ++ int (*sync_flags) (struct inode *);
16138 + };
16139 +
16140 + struct seq_file;
16141 +@@ -1153,6 +1180,7 @@ extern ssize_t vfs_readv(struct file *,
16142 + unsigned long, loff_t *);
16143 + extern ssize_t vfs_writev(struct file *, const struct iovec __user *,
16144 + unsigned long, loff_t *);
16145 ++ssize_t vfs_sendfile(struct file *, struct file *, loff_t *, size_t, loff_t);
16146 +
16147 + /*
16148 + * NOTE: write_inode, delete_inode, clear_inode, put_inode can be called
16149 +@@ -1898,6 +1926,7 @@ extern int dcache_dir_open(struct inode
16150 + extern int dcache_dir_close(struct inode *, struct file *);
16151 + extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
16152 + extern int dcache_readdir(struct file *, void *, filldir_t);
16153 ++extern int dcache_readdir_filter(struct file *, void *, filldir_t, int (*)(struct dentry *));
16154 + extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
16155 + extern int simple_statfs(struct dentry *, struct kstatfs *);
16156 + extern int simple_link(struct dentry *, struct inode *, struct dentry *);
16157 +diff -NurpP --minimal linux-2.6.22.19/include/linux/if_tun.h linux-2.6.22.19-vs2.3.0.34/include/linux/if_tun.h
16158 +--- linux-2.6.22.19/include/linux/if_tun.h 2005-10-28 20:49:54 +0200
16159 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/if_tun.h 2008-03-17 00:08:25 +0100
16160 +@@ -36,6 +36,7 @@ struct tun_struct {
16161 + unsigned long flags;
16162 + int attached;
16163 + uid_t owner;
16164 ++ nid_t nid;
16165 +
16166 + wait_queue_head_t read_wait;
16167 + struct sk_buff_head readq;
16168 +@@ -78,6 +79,7 @@ struct tun_struct {
16169 + #define TUNSETPERSIST _IOW('T', 203, int)
16170 + #define TUNSETOWNER _IOW('T', 204, int)
16171 + #define TUNSETLINK _IOW('T', 205, int)
16172 ++#define TUNSETNID _IOW('T', 215, int)
16173 +
16174 + /* TUNSETIFF ifr flags */
16175 + #define IFF_TUN 0x0001
16176 +diff -NurpP --minimal linux-2.6.22.19/include/linux/init_task.h linux-2.6.22.19-vs2.3.0.34/include/linux/init_task.h
16177 +--- linux-2.6.22.19/include/linux/init_task.h 2007-07-09 13:19:56 +0200
16178 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/init_task.h 2007-08-05 20:53:13 +0200
16179 +@@ -169,6 +169,10 @@ extern struct group_info init_groups;
16180 + }, \
16181 + INIT_TRACE_IRQFLAGS \
16182 + INIT_LOCKDEP \
16183 ++ .xid = 0, \
16184 ++ .vx_info = NULL, \
16185 ++ .nid = 0, \
16186 ++ .nx_info = NULL, \
16187 + }
16188 +
16189 +
16190 +diff -NurpP --minimal linux-2.6.22.19/include/linux/ipc.h linux-2.6.22.19-vs2.3.0.34/include/linux/ipc.h
16191 +--- linux-2.6.22.19/include/linux/ipc.h 2007-07-09 13:19:56 +0200
16192 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/ipc.h 2007-08-05 20:53:13 +0200
16193 +@@ -63,6 +63,7 @@ struct kern_ipc_perm
16194 + key_t key;
16195 + uid_t uid;
16196 + gid_t gid;
16197 ++ xid_t xid;
16198 + uid_t cuid;
16199 + gid_t cgid;
16200 + mode_t mode;
16201 +diff -NurpP --minimal linux-2.6.22.19/include/linux/jffs2.h linux-2.6.22.19-vs2.3.0.34/include/linux/jffs2.h
16202 +--- linux-2.6.22.19/include/linux/jffs2.h 2006-11-30 21:19:38 +0100
16203 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/jffs2.h 2007-10-05 15:07:22 +0200
16204 +@@ -82,12 +82,36 @@
16205 + //#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4)
16206 +
16207 +
16208 +-#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at
16209 ++#define JFFS2_INO_FLAG_PREREAD 0x01 /* Do read_inode() for this one at
16210 + mount time, don't wait for it to
16211 + happen later */
16212 +-#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific
16213 ++#define JFFS2_INO_FLAG_USERCOMPR 0x02 /* User has requested a specific
16214 + compression type */
16215 +
16216 ++#define JFFS2_INO_FLAG_IMMUTABLE 0x10 /* immutable node */
16217 ++#define JFFS2_INO_FLAG_IUNLINK 0x20 /* immutable unlink */
16218 ++#define JFFS2_INO_FLAG_BARRIER 0x40 /* barrier */
16219 ++
16220 ++#define JFFS2_USER_VISIBLE 0x10
16221 ++#define JFFS2_USER_MODIFIABLE 0x10
16222 ++
16223 ++/*
16224 ++ * Mount flags
16225 ++ */
16226 ++#define JFFS2_MOUNT_TAGGED (1<<24) /* Enable Context Tags */
16227 ++
16228 ++#define clear_opt(o, opt) o &= ~JFFS2_MOUNT_##opt
16229 ++#define set_opt(o, opt) o |= JFFS2_MOUNT_##opt
16230 ++
16231 ++/*
16232 ++ * Maximal mount counts between two filesystem checks
16233 ++ */
16234 ++#define EXT2_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */
16235 ++#define EXT2_DFL_CHECKINTERVAL 0 /* Don't use interval check */
16236 ++
16237 ++/*
16238 ++ * Behaviour when detecting errors
16239 ++ */
16240 +
16241 + /* These can go once we've made sure we've caught all uses without
16242 + byteswapping */
16243 +@@ -97,7 +121,7 @@ typedef struct {
16244 + } __attribute__((packed)) jint32_t;
16245 +
16246 + typedef struct {
16247 +- uint32_t m;
16248 ++ uint16_t m;
16249 + } __attribute__((packed)) jmode_t;
16250 +
16251 + typedef struct {
16252 +@@ -145,7 +169,8 @@ struct jffs2_raw_inode
16253 + jint32_t hdr_crc;
16254 + jint32_t ino; /* Inode number. */
16255 + jint32_t version; /* Version number. */
16256 +- jmode_t mode; /* The file's type or mode. */
16257 ++ jmode_t mode; /* The file's type or mode. */
16258 ++ jint16_t tag; /* context tagging */
16259 + jint16_t uid; /* The file's owner. */
16260 + jint16_t gid; /* The file's group. */
16261 + jint32_t isize; /* Total resultant size of this inode (used for truncations) */
16262 +diff -NurpP --minimal linux-2.6.22.19/include/linux/loop.h linux-2.6.22.19-vs2.3.0.34/include/linux/loop.h
16263 +--- linux-2.6.22.19/include/linux/loop.h 2007-07-09 13:19:56 +0200
16264 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/loop.h 2007-08-05 20:53:13 +0200
16265 +@@ -45,6 +45,7 @@ struct loop_device {
16266 + struct loop_func_table *lo_encryption;
16267 + __u32 lo_init[2];
16268 + uid_t lo_key_owner; /* Who set the key */
16269 ++ xid_t lo_xid;
16270 + int (*ioctl)(struct loop_device *, int cmd,
16271 + unsigned long arg);
16272 +
16273 +diff -NurpP --minimal linux-2.6.22.19/include/linux/magic.h linux-2.6.22.19-vs2.3.0.34/include/linux/magic.h
16274 +--- linux-2.6.22.19/include/linux/magic.h 2007-07-09 13:19:56 +0200
16275 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/magic.h 2007-10-06 18:19:33 +0200
16276 +@@ -3,7 +3,7 @@
16277 +
16278 + #define ADFS_SUPER_MAGIC 0xadf5
16279 + #define AFFS_SUPER_MAGIC 0xadff
16280 +-#define AFS_SUPER_MAGIC 0x5346414F
16281 ++#define AFS_SUPER_MAGIC 0x5346414F
16282 + #define AUTOFS_SUPER_MAGIC 0x0187
16283 + #define CODA_SUPER_MAGIC 0x73757245
16284 + #define EFS_SUPER_MAGIC 0x414A53
16285 +@@ -27,6 +27,7 @@
16286 + #define NFS_SUPER_MAGIC 0x6969
16287 + #define OPENPROM_SUPER_MAGIC 0x9fa1
16288 + #define PROC_SUPER_MAGIC 0x9fa0
16289 ++#define DEVPTS_SUPER_MAGIC 0x1cd1
16290 + #define QNX4_SUPER_MAGIC 0x002f /* qnx4 fs detection */
16291 +
16292 + #define REISERFS_SUPER_MAGIC 0x52654973 /* used by gcc */
16293 +diff -NurpP --minimal linux-2.6.22.19/include/linux/major.h linux-2.6.22.19-vs2.3.0.34/include/linux/major.h
16294 +--- linux-2.6.22.19/include/linux/major.h 2007-07-09 13:19:56 +0200
16295 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/major.h 2007-08-05 20:53:13 +0200
16296 +@@ -15,6 +15,7 @@
16297 + #define HD_MAJOR IDE0_MAJOR
16298 + #define PTY_SLAVE_MAJOR 3
16299 + #define TTY_MAJOR 4
16300 ++#define VROOT_MAJOR 4
16301 + #define TTYAUX_MAJOR 5
16302 + #define LP_MAJOR 6
16303 + #define VCS_MAJOR 7
16304 +diff -NurpP --minimal linux-2.6.22.19/include/linux/mount.h linux-2.6.22.19-vs2.3.0.34/include/linux/mount.h
16305 +--- linux-2.6.22.19/include/linux/mount.h 2007-07-09 13:19:56 +0200
16306 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/mount.h 2007-09-05 02:29:04 +0200
16307 +@@ -28,6 +28,9 @@ struct mnt_namespace;
16308 + #define MNT_NOATIME 0x08
16309 + #define MNT_NODIRATIME 0x10
16310 + #define MNT_RELATIME 0x20
16311 ++#define MNT_RDONLY 0x40
16312 ++
16313 ++#define MNT_IS_RDONLY(m) ((m) && ((m)->mnt_flags & MNT_RDONLY))
16314 +
16315 + #define MNT_SHRINKABLE 0x100
16316 +
16317 +@@ -35,6 +38,10 @@ struct mnt_namespace;
16318 + #define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */
16319 + #define MNT_PNODE_MASK 0x3000 /* propagation flag mask */
16320 +
16321 ++#define MNT_TAGID 0x10000
16322 ++#define MNT_NOTAG 0x20000
16323 ++#define MNT_NOTAGCHECK 0x40000
16324 ++
16325 + struct vfsmount {
16326 + struct list_head mnt_hash;
16327 + struct vfsmount *mnt_parent; /* fs we are mounted on */
16328 +@@ -61,6 +68,7 @@ struct vfsmount {
16329 + atomic_t mnt_count;
16330 + int mnt_expiry_mark; /* true if marked for expiry */
16331 + int mnt_pinned;
16332 ++ tag_t mnt_tag; /* tagging used for vfsmount */
16333 + };
16334 +
16335 + static inline struct vfsmount *mntget(struct vfsmount *mnt)
16336 +diff -NurpP --minimal linux-2.6.22.19/include/linux/net.h linux-2.6.22.19-vs2.3.0.34/include/linux/net.h
16337 +--- linux-2.6.22.19/include/linux/net.h 2007-07-09 13:19:56 +0200
16338 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/net.h 2007-08-05 20:53:13 +0200
16339 +@@ -63,6 +63,7 @@ typedef enum {
16340 + #define SOCK_NOSPACE 2
16341 + #define SOCK_PASSCRED 3
16342 + #define SOCK_PASSSEC 4
16343 ++#define SOCK_USER_SOCKET 5
16344 +
16345 + #ifndef ARCH_HAS_SOCKET_TYPES
16346 + /**
16347 +diff -NurpP --minimal linux-2.6.22.19/include/linux/nfs_mount.h linux-2.6.22.19-vs2.3.0.34/include/linux/nfs_mount.h
16348 +--- linux-2.6.22.19/include/linux/nfs_mount.h 2007-07-09 13:20:00 +0200
16349 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/nfs_mount.h 2007-08-05 20:53:13 +0200
16350 +@@ -62,6 +62,7 @@ struct nfs_mount_data {
16351 + #define NFS_MOUNT_STRICTLOCK 0x1000 /* reserved for NFSv4 */
16352 + #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */
16353 + #define NFS_MOUNT_NORDIRPLUS 0x4000 /* 5 */
16354 ++#define NFS_MOUNT_TAGGED 0x8000 /* context tagging */
16355 + #define NFS_MOUNT_FLAGMASK 0xFFFF
16356 +
16357 + #endif
16358 +diff -NurpP --minimal linux-2.6.22.19/include/linux/nsproxy.h linux-2.6.22.19-vs2.3.0.34/include/linux/nsproxy.h
16359 +--- linux-2.6.22.19/include/linux/nsproxy.h 2007-07-09 13:20:00 +0200
16360 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/nsproxy.h 2007-08-05 20:53:13 +0200
16361 +@@ -3,6 +3,7 @@
16362 +
16363 + #include <linux/spinlock.h>
16364 + #include <linux/sched.h>
16365 ++#include <linux/vserver/debug.h>
16366 +
16367 + struct mnt_namespace;
16368 + struct uts_namespace;
16369 +@@ -32,26 +33,46 @@ struct nsproxy {
16370 + extern struct nsproxy init_nsproxy;
16371 +
16372 + int copy_namespaces(int flags, struct task_struct *tsk);
16373 ++struct nsproxy *copy_nsproxy(struct nsproxy *orig);
16374 + void get_task_namespaces(struct task_struct *tsk);
16375 + void free_nsproxy(struct nsproxy *ns);
16376 + int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **,
16377 + struct fs_struct *);
16378 +
16379 +-static inline void put_nsproxy(struct nsproxy *ns)
16380 ++#define get_nsproxy(n) __get_nsproxy(n, __FILE__, __LINE__)
16381 ++
16382 ++static inline void __get_nsproxy(struct nsproxy *ns,
16383 ++ const char *_file, int _line)
16384 + {
16385 ++ vxlprintk(VXD_CBIT(space, 0), "get_nsproxy(%p[%u])",
16386 ++ ns, atomic_read(&ns->count), _file, _line);
16387 ++ atomic_inc(&ns->count);
16388 ++}
16389 ++
16390 ++#define put_nsproxy(n) __put_nsproxy(n, __FILE__, __LINE__)
16391 ++
16392 ++static inline void __put_nsproxy(struct nsproxy *ns,
16393 ++ const char *_file, int _line)
16394 ++{
16395 ++ vxlprintk(VXD_CBIT(space, 0), "put_nsproxy(%p[%u])",
16396 ++ ns, atomic_read(&ns->count), _file, _line);
16397 + if (atomic_dec_and_test(&ns->count)) {
16398 + free_nsproxy(ns);
16399 + }
16400 + }
16401 +
16402 +-static inline void exit_task_namespaces(struct task_struct *p)
16403 ++#define exit_task_namespaces(p) __exit_task_namespaces(p, __FILE__, __LINE__)
16404 ++
16405 ++static inline void __exit_task_namespaces(struct task_struct *p,
16406 ++ const char *_file, int _line)
16407 + {
16408 + struct nsproxy *ns = p->nsproxy;
16409 + if (ns) {
16410 + task_lock(p);
16411 + p->nsproxy = NULL;
16412 + task_unlock(p);
16413 +- put_nsproxy(ns);
16414 ++ __put_nsproxy(ns, _file, _line);
16415 + }
16416 + }
16417 ++
16418 + #endif
16419 +diff -NurpP --minimal linux-2.6.22.19/include/linux/pid.h linux-2.6.22.19-vs2.3.0.34/include/linux/pid.h
16420 +--- linux-2.6.22.19/include/linux/pid.h 2007-07-09 13:20:00 +0200
16421 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/pid.h 2007-08-05 20:53:13 +0200
16422 +@@ -8,7 +8,8 @@ enum pid_type
16423 + PIDTYPE_PID,
16424 + PIDTYPE_PGID,
16425 + PIDTYPE_SID,
16426 +- PIDTYPE_MAX
16427 ++ PIDTYPE_MAX,
16428 ++ PIDTYPE_REALPID
16429 + };
16430 +
16431 + /*
16432 +diff -NurpP --minimal linux-2.6.22.19/include/linux/proc_fs.h linux-2.6.22.19-vs2.3.0.34/include/linux/proc_fs.h
16433 +--- linux-2.6.22.19/include/linux/proc_fs.h 2007-07-09 13:20:00 +0200
16434 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/proc_fs.h 2007-08-05 20:53:13 +0200
16435 +@@ -54,6 +54,7 @@ struct proc_dir_entry {
16436 + nlink_t nlink;
16437 + uid_t uid;
16438 + gid_t gid;
16439 ++ int vx_flags;
16440 + loff_t size;
16441 + const struct inode_operations *proc_iops;
16442 + const struct file_operations *proc_fops;
16443 +@@ -246,13 +247,20 @@ static inline void kclist_add(struct kco
16444 + extern void kclist_add(struct kcore_list *, void *, size_t);
16445 + #endif
16446 +
16447 ++struct vx_info;
16448 ++struct nx_info;
16449 ++
16450 + union proc_op {
16451 + int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
16452 + int (*proc_read)(struct task_struct *task, char *page);
16453 ++ int (*proc_vs_read)(char *page);
16454 ++ int (*proc_vxi_read)(struct vx_info *vxi, char *page);
16455 ++ int (*proc_nxi_read)(struct nx_info *nxi, char *page);
16456 + };
16457 +
16458 + struct proc_inode {
16459 + struct pid *pid;
16460 ++ int vx_flags;
16461 + int fd;
16462 + union proc_op op;
16463 + struct proc_dir_entry *pde;
16464 +diff -NurpP --minimal linux-2.6.22.19/include/linux/reiserfs_fs.h linux-2.6.22.19-vs2.3.0.34/include/linux/reiserfs_fs.h
16465 +--- linux-2.6.22.19/include/linux/reiserfs_fs.h 2007-05-02 19:25:34 +0200
16466 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/reiserfs_fs.h 2007-08-05 20:53:13 +0200
16467 +@@ -821,6 +821,10 @@ struct stat_data_v1 {
16468 + #define REISERFS_COMPR_FL FS_COMPR_FL
16469 + #define REISERFS_NOTAIL_FL FS_NOTAIL_FL
16470 +
16471 ++/* unfortunately reiserfs sdattr is only 16 bit */
16472 ++#define REISERFS_BARRIER_FL (FS_BARRIER_FL >> 16)
16473 ++#define REISERFS_IUNLINK_FL (FS_IUNLINK_FL >> 16)
16474 ++
16475 + /* persistent flags that file inherits from the parent directory */
16476 + #define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FL | \
16477 + REISERFS_SYNC_FL | \
16478 +@@ -830,6 +834,9 @@ struct stat_data_v1 {
16479 + REISERFS_COMPR_FL | \
16480 + REISERFS_NOTAIL_FL )
16481 +
16482 ++#define REISERFS_FL_USER_VISIBLE 0x80FF
16483 ++#define REISERFS_FL_USER_MODIFIABLE 0x80FF
16484 ++
16485 + /* Stat Data on disk (reiserfs version of UFS disk inode minus the
16486 + address blocks) */
16487 + struct stat_data {
16488 +@@ -1901,6 +1908,7 @@ static inline void reiserfs_update_sd(st
16489 + void sd_attrs_to_i_attrs(__u16 sd_attrs, struct inode *inode);
16490 + void i_attrs_to_sd_attrs(struct inode *inode, __u16 * sd_attrs);
16491 + int reiserfs_setattr(struct dentry *dentry, struct iattr *attr);
16492 ++int reiserfs_sync_flags(struct inode *inode);
16493 +
16494 + /* namei.c */
16495 + void set_de_name_and_namelen(struct reiserfs_dir_entry *de);
16496 +diff -NurpP --minimal linux-2.6.22.19/include/linux/reiserfs_fs_sb.h linux-2.6.22.19-vs2.3.0.34/include/linux/reiserfs_fs_sb.h
16497 +--- linux-2.6.22.19/include/linux/reiserfs_fs_sb.h 2007-07-09 13:20:00 +0200
16498 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/reiserfs_fs_sb.h 2007-08-05 20:53:13 +0200
16499 +@@ -458,6 +458,7 @@ enum reiserfs_mount_options {
16500 + REISERFS_POSIXACL,
16501 + REISERFS_BARRIER_NONE,
16502 + REISERFS_BARRIER_FLUSH,
16503 ++ REISERFS_TAGGED,
16504 +
16505 + /* Actions on error */
16506 + REISERFS_ERROR_PANIC,
16507 +diff -NurpP --minimal linux-2.6.22.19/include/linux/sched.h linux-2.6.22.19-vs2.3.0.34/include/linux/sched.h
16508 +--- linux-2.6.22.19/include/linux/sched.h 2007-07-09 13:20:01 +0200
16509 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/sched.h 2007-10-04 23:47:06 +0200
16510 +@@ -26,6 +26,7 @@
16511 + #define CLONE_STOPPED 0x02000000 /* Start in stopped state */
16512 + #define CLONE_NEWUTS 0x04000000 /* New utsname group? */
16513 + #define CLONE_NEWIPC 0x08000000 /* New ipcs */
16514 ++#define CLONE_KTHREAD 0x10000000 /* clone a kernel thread */
16515 +
16516 + /*
16517 + * Scheduling policies
16518 +@@ -94,7 +95,7 @@ struct bio;
16519 + * List of flags we want to share for kernel threads,
16520 + * if only because they are not used by them anyway.
16521 + */
16522 +-#define CLONE_KERNEL (CLONE_FS | CLONE_FILES | CLONE_SIGHAND)
16523 ++#define CLONE_KERNEL (CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_KTHREAD)
16524 +
16525 + /*
16526 + * These are the constant used to fake the fixed-point load-average
16527 +@@ -146,12 +147,13 @@ extern unsigned long weighted_cpuload(co
16528 + #define TASK_UNINTERRUPTIBLE 2
16529 + #define TASK_STOPPED 4
16530 + #define TASK_TRACED 8
16531 ++#define TASK_ONHOLD 16
16532 + /* in tsk->exit_state */
16533 +-#define EXIT_ZOMBIE 16
16534 +-#define EXIT_DEAD 32
16535 ++#define EXIT_ZOMBIE 32
16536 ++#define EXIT_DEAD 64
16537 + /* in tsk->state again */
16538 +-#define TASK_NONINTERACTIVE 64
16539 +-#define TASK_DEAD 128
16540 ++#define TASK_NONINTERACTIVE 128
16541 ++#define TASK_DEAD 256
16542 +
16543 + #define __set_task_state(tsk, state_value) \
16544 + do { (tsk)->state = (state_value); } while (0)
16545 +@@ -287,27 +289,30 @@ extern void arch_unmap_area_topdown(stru
16546 + * The mm counters are not protected by its page_table_lock,
16547 + * so must be incremented atomically.
16548 + */
16549 +-#define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value)
16550 +-#define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member))
16551 +-#define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member)
16552 +-#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member)
16553 +-#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member)
16554 + typedef atomic_long_t mm_counter_t;
16555 ++#define __set_mm_counter(mm, member, value) \
16556 ++ atomic_long_set(&(mm)->_##member, value)
16557 ++#define get_mm_counter(mm, member) \
16558 ++ ((unsigned long)atomic_long_read(&(mm)->_##member))
16559 +
16560 + #else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
16561 + /*
16562 + * The mm counters are protected by its page_table_lock,
16563 + * so can be incremented directly.
16564 + */
16565 +-#define set_mm_counter(mm, member, value) (mm)->_##member = (value)
16566 +-#define get_mm_counter(mm, member) ((mm)->_##member)
16567 +-#define add_mm_counter(mm, member, value) (mm)->_##member += (value)
16568 +-#define inc_mm_counter(mm, member) (mm)->_##member++
16569 +-#define dec_mm_counter(mm, member) (mm)->_##member--
16570 + typedef unsigned long mm_counter_t;
16571 ++#define __set_mm_counter(mm, member, value) (mm)->_##member = (value)
16572 ++#define get_mm_counter(mm, member) ((mm)->_##member)
16573 +
16574 + #endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
16575 +
16576 ++#define set_mm_counter(mm, member, value) \
16577 ++ vx_ ## member ## pages_sub((mm), (get_mm_counter(mm, member) - value))
16578 ++#define add_mm_counter(mm, member, value) \
16579 ++ vx_ ## member ## pages_add((mm), (value))
16580 ++#define inc_mm_counter(mm, member) vx_ ## member ## pages_inc((mm))
16581 ++#define dec_mm_counter(mm, member) vx_ ## member ## pages_dec((mm))
16582 ++
16583 + #define get_mm_rss(mm) \
16584 + (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
16585 + #define update_hiwater_rss(mm) do { \
16586 +@@ -365,6 +370,7 @@ struct mm_struct {
16587 +
16588 + /* Architecture-specific MM context */
16589 + mm_context_t context;
16590 ++ struct vx_info *mm_vx_info;
16591 +
16592 + /* Swap token stuff */
16593 + /*
16594 +@@ -570,9 +576,10 @@ struct user_struct {
16595 + /* Hash table maintenance information */
16596 + struct list_head uidhash_list;
16597 + uid_t uid;
16598 ++ xid_t xid;
16599 + };
16600 +
16601 +-extern struct user_struct *find_user(uid_t);
16602 ++extern struct user_struct *find_user(xid_t, uid_t);
16603 +
16604 + extern struct user_struct root_user;
16605 + #define INIT_USER (&root_user)
16606 +@@ -969,6 +976,15 @@ struct task_struct {
16607 +
16608 + void *security;
16609 + struct audit_context *audit_context;
16610 ++
16611 ++/* vserver context data */
16612 ++ struct vx_info *vx_info;
16613 ++ struct nx_info *nx_info;
16614 ++
16615 ++ xid_t xid;
16616 ++ nid_t nid;
16617 ++ tag_t tag;
16618 ++
16619 + seccomp_t seccomp;
16620 +
16621 + /* Thread group tracking */
16622 +@@ -1290,12 +1306,16 @@ extern struct task_struct init_task;
16623 +
16624 + extern struct mm_struct init_mm;
16625 +
16626 +-#define find_task_by_pid(nr) find_task_by_pid_type(PIDTYPE_PID, nr)
16627 ++#define find_task_by_real_pid(nr) \
16628 ++ find_task_by_pid_type(PIDTYPE_REALPID, nr)
16629 ++#define find_task_by_pid(nr) \
16630 ++ find_task_by_pid_type(PIDTYPE_PID, nr)
16631 ++
16632 + extern struct task_struct *find_task_by_pid_type(int type, int pid);
16633 + extern void __set_special_pids(pid_t session, pid_t pgrp);
16634 +
16635 + /* per-UID process charging. */
16636 +-extern struct user_struct * alloc_uid(uid_t);
16637 ++extern struct user_struct * alloc_uid(xid_t, uid_t);
16638 + static inline struct user_struct *get_uid(struct user_struct *u)
16639 + {
16640 + atomic_inc(&u->__count);
16641 +diff -NurpP --minimal linux-2.6.22.19/include/linux/shmem_fs.h linux-2.6.22.19-vs2.3.0.34/include/linux/shmem_fs.h
16642 +--- linux-2.6.22.19/include/linux/shmem_fs.h 2006-11-30 21:19:39 +0100
16643 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/shmem_fs.h 2007-08-05 20:53:13 +0200
16644 +@@ -8,6 +8,9 @@
16645 +
16646 + #define SHMEM_NR_DIRECT 16
16647 +
16648 ++#define TMPFS_SUPER_MAGIC 0x01021994
16649 ++
16650 ++
16651 + struct shmem_inode_info {
16652 + spinlock_t lock;
16653 + unsigned long flags;
16654 +diff -NurpP --minimal linux-2.6.22.19/include/linux/stat.h linux-2.6.22.19-vs2.3.0.34/include/linux/stat.h
16655 +--- linux-2.6.22.19/include/linux/stat.h 2007-07-09 13:20:01 +0200
16656 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/stat.h 2007-08-05 20:53:13 +0200
16657 +@@ -66,6 +66,7 @@ struct kstat {
16658 + unsigned int nlink;
16659 + uid_t uid;
16660 + gid_t gid;
16661 ++ tag_t tag;
16662 + dev_t rdev;
16663 + loff_t size;
16664 + struct timespec atime;
16665 +diff -NurpP --minimal linux-2.6.22.19/include/linux/sunrpc/auth.h linux-2.6.22.19-vs2.3.0.34/include/linux/sunrpc/auth.h
16666 +--- linux-2.6.22.19/include/linux/sunrpc/auth.h 2006-11-30 21:19:40 +0100
16667 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/sunrpc/auth.h 2007-08-05 20:53:13 +0200
16668 +@@ -24,6 +24,7 @@
16669 + struct auth_cred {
16670 + uid_t uid;
16671 + gid_t gid;
16672 ++ tag_t tag;
16673 + struct group_info *group_info;
16674 + };
16675 +
16676 +diff -NurpP --minimal linux-2.6.22.19/include/linux/sunrpc/clnt.h linux-2.6.22.19-vs2.3.0.34/include/linux/sunrpc/clnt.h
16677 +--- linux-2.6.22.19/include/linux/sunrpc/clnt.h 2007-07-09 13:20:01 +0200
16678 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/sunrpc/clnt.h 2007-08-05 20:53:13 +0200
16679 +@@ -43,7 +43,8 @@ struct rpc_clnt {
16680 + cl_discrtry : 1,/* disconnect before retry */
16681 + cl_autobind : 1,/* use getport() */
16682 + cl_oneshot : 1,/* dispose after use */
16683 +- cl_dead : 1;/* abandoned */
16684 ++ cl_dead : 1,/* abandoned */
16685 ++ cl_tag : 1;/* context tagging */
16686 +
16687 + struct rpc_rtt * cl_rtt; /* RTO estimator data */
16688 +
16689 +diff -NurpP --minimal linux-2.6.22.19/include/linux/syscalls.h linux-2.6.22.19-vs2.3.0.34/include/linux/syscalls.h
16690 +--- linux-2.6.22.19/include/linux/syscalls.h 2007-07-09 13:20:01 +0200
16691 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/syscalls.h 2007-08-05 20:53:13 +0200
16692 +@@ -294,6 +294,8 @@ asmlinkage long sys_symlink(const char _
16693 + asmlinkage long sys_unlink(const char __user *pathname);
16694 + asmlinkage long sys_rename(const char __user *oldname,
16695 + const char __user *newname);
16696 ++asmlinkage long sys_copyfile(const char __user *from, const char __user *to,
16697 ++ umode_t mode);
16698 + asmlinkage long sys_chmod(const char __user *filename, mode_t mode);
16699 + asmlinkage long sys_fchmod(unsigned int fd, mode_t mode);
16700 +
16701 +diff -NurpP --minimal linux-2.6.22.19/include/linux/sysctl.h linux-2.6.22.19-vs2.3.0.34/include/linux/sysctl.h
16702 +--- linux-2.6.22.19/include/linux/sysctl.h 2007-07-09 13:20:01 +0200
16703 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/sysctl.h 2007-08-05 20:53:13 +0200
16704 +@@ -106,6 +106,7 @@ enum
16705 + KERN_CAP_BSET=14, /* int: capability bounding set */
16706 + KERN_PANIC=15, /* int: panic timeout */
16707 + KERN_REALROOTDEV=16, /* real root device to mount after initrd */
16708 ++ KERN_VSHELPER=17, /* string: path to vshelper policy agent */
16709 +
16710 + KERN_SPARC_REBOOT=21, /* reboot command on Sparc */
16711 + KERN_CTLALTDEL=22, /* int: allow ctl-alt-del to reboot */
16712 +diff -NurpP --minimal linux-2.6.22.19/include/linux/sysfs.h linux-2.6.22.19-vs2.3.0.34/include/linux/sysfs.h
16713 +--- linux-2.6.22.19/include/linux/sysfs.h 2007-07-09 13:20:01 +0200
16714 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/sysfs.h 2007-08-05 20:53:13 +0200
16715 +@@ -15,6 +15,8 @@
16716 + #include <linux/list.h>
16717 + #include <asm/atomic.h>
16718 +
16719 ++#define SYSFS_SUPER_MAGIC 0x62656572
16720 ++
16721 + struct kobject;
16722 + struct module;
16723 + struct nameidata;
16724 +diff -NurpP --minimal linux-2.6.22.19/include/linux/time.h linux-2.6.22.19-vs2.3.0.34/include/linux/time.h
16725 +--- linux-2.6.22.19/include/linux/time.h 2007-07-09 13:20:01 +0200
16726 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/time.h 2007-08-05 20:53:13 +0200
16727 +@@ -176,6 +176,9 @@ static inline void timespec_add_ns(struc
16728 + }
16729 + a->tv_nsec = ns;
16730 + }
16731 ++
16732 ++#include <linux/vs_time.h>
16733 ++
16734 + #endif /* __KERNEL__ */
16735 +
16736 + #define NFDBITS __NFDBITS
16737 +diff -NurpP --minimal linux-2.6.22.19/include/linux/types.h linux-2.6.22.19-vs2.3.0.34/include/linux/types.h
16738 +--- linux-2.6.22.19/include/linux/types.h 2007-02-06 03:01:52 +0100
16739 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/types.h 2007-08-05 20:53:13 +0200
16740 +@@ -39,6 +39,9 @@ typedef __kernel_uid32_t uid_t;
16741 + typedef __kernel_gid32_t gid_t;
16742 + typedef __kernel_uid16_t uid16_t;
16743 + typedef __kernel_gid16_t gid16_t;
16744 ++typedef unsigned int xid_t;
16745 ++typedef unsigned int nid_t;
16746 ++typedef unsigned int tag_t;
16747 +
16748 + #ifdef CONFIG_UID16
16749 + /* This is defined by include/asm-{arch}/posix_types.h */
16750 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vroot.h linux-2.6.22.19-vs2.3.0.34/include/linux/vroot.h
16751 +--- linux-2.6.22.19/include/linux/vroot.h 1970-01-01 01:00:00 +0100
16752 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vroot.h 2007-08-05 20:53:13 +0200
16753 +@@ -0,0 +1,51 @@
16754 ++
16755 ++/*
16756 ++ * include/linux/vroot.h
16757 ++ *
16758 ++ * written by Herbert Pötzl, 9/11/2002
16759 ++ * ported to 2.6 by Herbert Pötzl, 30/12/2004
16760 ++ *
16761 ++ * Copyright (C) 2002-2007 by Herbert Pötzl.
16762 ++ * Redistribution of this file is permitted under the
16763 ++ * GNU General Public License.
16764 ++ */
16765 ++
16766 ++#ifndef _LINUX_VROOT_H
16767 ++#define _LINUX_VROOT_H
16768 ++
16769 ++
16770 ++#ifdef __KERNEL__
16771 ++
16772 ++/* Possible states of device */
16773 ++enum {
16774 ++ Vr_unbound,
16775 ++ Vr_bound,
16776 ++};
16777 ++
16778 ++struct vroot_device {
16779 ++ int vr_number;
16780 ++ int vr_refcnt;
16781 ++
16782 ++ struct semaphore vr_ctl_mutex;
16783 ++ struct block_device *vr_device;
16784 ++ int vr_state;
16785 ++};
16786 ++
16787 ++
16788 ++typedef struct block_device *(vroot_grb_func)(struct block_device *);
16789 ++
16790 ++extern int register_vroot_grb(vroot_grb_func *);
16791 ++extern int unregister_vroot_grb(vroot_grb_func *);
16792 ++
16793 ++#endif /* __KERNEL__ */
16794 ++
16795 ++#define MAX_VROOT_DEFAULT 8
16796 ++
16797 ++/*
16798 ++ * IOCTL commands --- we will commandeer 0x56 ('V')
16799 ++ */
16800 ++
16801 ++#define VROOT_SET_DEV 0x5600
16802 ++#define VROOT_CLR_DEV 0x5601
16803 ++
16804 ++#endif /* _LINUX_VROOT_H */
16805 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_base.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_base.h
16806 +--- linux-2.6.22.19/include/linux/vs_base.h 1970-01-01 01:00:00 +0100
16807 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_base.h 2007-08-05 20:53:13 +0200
16808 +@@ -0,0 +1,9 @@
16809 ++#ifndef _VS_BASE_H
16810 ++#define _VS_BASE_H
16811 ++
16812 ++#include "vserver/base.h"
16813 ++#include "vserver/debug.h"
16814 ++
16815 ++#else
16816 ++#warning duplicate inclusion
16817 ++#endif
16818 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_context.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_context.h
16819 +--- linux-2.6.22.19/include/linux/vs_context.h 1970-01-01 01:00:00 +0100
16820 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_context.h 2007-10-01 14:57:41 +0200
16821 +@@ -0,0 +1,224 @@
16822 ++#ifndef _VS_CONTEXT_H
16823 ++#define _VS_CONTEXT_H
16824 ++
16825 ++#include "vserver/base.h"
16826 ++#include "vserver/context.h"
16827 ++#include "vserver/history.h"
16828 ++#include "vserver/debug.h"
16829 ++
16830 ++
16831 ++#define get_vx_info(i) __get_vx_info(i, __FILE__, __LINE__, __HERE__)
16832 ++
16833 ++static inline struct vx_info *__get_vx_info(struct vx_info *vxi,
16834 ++ const char *_file, int _line, void *_here)
16835 ++{
16836 ++ if (!vxi)
16837 ++ return NULL;
16838 ++
16839 ++ vxlprintk(VXD_CBIT(xid, 2), "get_vx_info(%p[#%d.%d])",
16840 ++ vxi, vxi ? vxi->vx_id : 0,
16841 ++ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
16842 ++ _file, _line);
16843 ++ __vxh_get_vx_info(vxi, _here);
16844 ++
16845 ++ atomic_inc(&vxi->vx_usecnt);
16846 ++ return vxi;
16847 ++}
16848 ++
16849 ++
16850 ++extern void free_vx_info(struct vx_info *);
16851 ++
16852 ++#define put_vx_info(i) __put_vx_info(i, __FILE__, __LINE__, __HERE__)
16853 ++
16854 ++static inline void __put_vx_info(struct vx_info *vxi,
16855 ++ const char *_file, int _line, void *_here)
16856 ++{
16857 ++ if (!vxi)
16858 ++ return;
16859 ++
16860 ++ vxlprintk(VXD_CBIT(xid, 2), "put_vx_info(%p[#%d.%d])",
16861 ++ vxi, vxi ? vxi->vx_id : 0,
16862 ++ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
16863 ++ _file, _line);
16864 ++ __vxh_put_vx_info(vxi, _here);
16865 ++
16866 ++ if (atomic_dec_and_test(&vxi->vx_usecnt))
16867 ++ free_vx_info(vxi);
16868 ++}
16869 ++
16870 ++
16871 ++#define init_vx_info(p, i) \
16872 ++ __init_vx_info(p, i, __FILE__, __LINE__, __HERE__)
16873 ++
16874 ++static inline void __init_vx_info(struct vx_info **vxp, struct vx_info *vxi,
16875 ++ const char *_file, int _line, void *_here)
16876 ++{
16877 ++ if (vxi) {
16878 ++ vxlprintk(VXD_CBIT(xid, 3),
16879 ++ "init_vx_info(%p[#%d.%d])",
16880 ++ vxi, vxi ? vxi->vx_id : 0,
16881 ++ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
16882 ++ _file, _line);
16883 ++ __vxh_init_vx_info(vxi, vxp, _here);
16884 ++
16885 ++ atomic_inc(&vxi->vx_usecnt);
16886 ++ }
16887 ++ *vxp = vxi;
16888 ++}
16889 ++
16890 ++
16891 ++#define set_vx_info(p, i) \
16892 ++ __set_vx_info(p, i, __FILE__, __LINE__, __HERE__)
16893 ++
16894 ++static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi,
16895 ++ const char *_file, int _line, void *_here)
16896 ++{
16897 ++ struct vx_info *vxo;
16898 ++
16899 ++ if (!vxi)
16900 ++ return;
16901 ++
16902 ++ vxlprintk(VXD_CBIT(xid, 3), "set_vx_info(%p[#%d.%d])",
16903 ++ vxi, vxi ? vxi->vx_id : 0,
16904 ++ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
16905 ++ _file, _line);
16906 ++ __vxh_set_vx_info(vxi, vxp, _here);
16907 ++
16908 ++ atomic_inc(&vxi->vx_usecnt);
16909 ++ vxo = xchg(vxp, vxi);
16910 ++ BUG_ON(vxo);
16911 ++}
16912 ++
16913 ++
16914 ++#define clr_vx_info(p) __clr_vx_info(p, __FILE__, __LINE__, __HERE__)
16915 ++
16916 ++static inline void __clr_vx_info(struct vx_info **vxp,
16917 ++ const char *_file, int _line, void *_here)
16918 ++{
16919 ++ struct vx_info *vxo;
16920 ++
16921 ++ vxo = xchg(vxp, NULL);
16922 ++ if (!vxo)
16923 ++ return;
16924 ++
16925 ++ vxlprintk(VXD_CBIT(xid, 3), "clr_vx_info(%p[#%d.%d])",
16926 ++ vxo, vxo ? vxo->vx_id : 0,
16927 ++ vxo ? atomic_read(&vxo->vx_usecnt) : 0,
16928 ++ _file, _line);
16929 ++ __vxh_clr_vx_info(vxo, vxp, _here);
16930 ++
16931 ++ if (atomic_dec_and_test(&vxo->vx_usecnt))
16932 ++ free_vx_info(vxo);
16933 ++}
16934 ++
16935 ++
16936 ++#define claim_vx_info(v, p) \
16937 ++ __claim_vx_info(v, p, __FILE__, __LINE__, __HERE__)
16938 ++
16939 ++static inline void __claim_vx_info(struct vx_info *vxi,
16940 ++ struct task_struct *task,
16941 ++ const char *_file, int _line, void *_here)
16942 ++{
16943 ++ vxlprintk(VXD_CBIT(xid, 3), "claim_vx_info(%p[#%d.%d.%d]) %p",
16944 ++ vxi, vxi ? vxi->vx_id : 0,
16945 ++ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
16946 ++ vxi ? atomic_read(&vxi->vx_tasks) : 0,
16947 ++ task, _file, _line);
16948 ++ __vxh_claim_vx_info(vxi, task, _here);
16949 ++
16950 ++ atomic_inc(&vxi->vx_tasks);
16951 ++}
16952 ++
16953 ++
16954 ++extern void unhash_vx_info(struct vx_info *);
16955 ++
16956 ++#define release_vx_info(v, p) \
16957 ++ __release_vx_info(v, p, __FILE__, __LINE__, __HERE__)
16958 ++
16959 ++static inline void __release_vx_info(struct vx_info *vxi,
16960 ++ struct task_struct *task,
16961 ++ const char *_file, int _line, void *_here)
16962 ++{
16963 ++ vxlprintk(VXD_CBIT(xid, 3), "release_vx_info(%p[#%d.%d.%d]) %p",
16964 ++ vxi, vxi ? vxi->vx_id : 0,
16965 ++ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
16966 ++ vxi ? atomic_read(&vxi->vx_tasks) : 0,
16967 ++ task, _file, _line);
16968 ++ __vxh_release_vx_info(vxi, task, _here);
16969 ++
16970 ++ might_sleep();
16971 ++
16972 ++ if (atomic_dec_and_test(&vxi->vx_tasks))
16973 ++ unhash_vx_info(vxi);
16974 ++}
16975 ++
16976 ++
16977 ++#define task_get_vx_info(p) \
16978 ++ __task_get_vx_info(p, __FILE__, __LINE__, __HERE__)
16979 ++
16980 ++static inline struct vx_info *__task_get_vx_info(struct task_struct *p,
16981 ++ const char *_file, int _line, void *_here)
16982 ++{
16983 ++ struct vx_info *vxi;
16984 ++
16985 ++ task_lock(p);
16986 ++ vxlprintk(VXD_CBIT(xid, 5), "task_get_vx_info(%p)",
16987 ++ p, _file, _line);
16988 ++ vxi = __get_vx_info(p->vx_info, _file, _line, _here);
16989 ++ task_unlock(p);
16990 ++ return vxi;
16991 ++}
16992 ++
16993 ++
16994 ++static inline void __wakeup_vx_info(struct vx_info *vxi)
16995 ++{
16996 ++ if (waitqueue_active(&vxi->vx_wait))
16997 ++ wake_up_interruptible(&vxi->vx_wait);
16998 ++}
16999 ++
17000 ++
17001 ++#define enter_vx_info(v, s) __enter_vx_info(v, s, __FILE__, __LINE__)
17002 ++
17003 ++static inline void __enter_vx_info(struct vx_info *vxi,
17004 ++ struct vx_info_save *vxis, const char *_file, int _line)
17005 ++{
17006 ++ vxlprintk(VXD_CBIT(xid, 5), "enter_vx_info(%p[#%d],%p) %p[#%d,%p]",
17007 ++ vxi, vxi ? vxi->vx_id : 0, vxis, current,
17008 ++ current->xid, current->vx_info, _file, _line);
17009 ++ vxis->vxi = xchg(&current->vx_info, vxi);
17010 ++ vxis->xid = current->xid;
17011 ++ current->xid = vxi ? vxi->vx_id : 0;
17012 ++}
17013 ++
17014 ++#define leave_vx_info(s) __leave_vx_info(s, __FILE__, __LINE__)
17015 ++
17016 ++static inline void __leave_vx_info(struct vx_info_save *vxis,
17017 ++ const char *_file, int _line)
17018 ++{
17019 ++ vxlprintk(VXD_CBIT(xid, 5), "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]",
17020 ++ vxis, vxis->xid, vxis->vxi, current,
17021 ++ current->xid, current->vx_info, _file, _line);
17022 ++ (void)xchg(&current->vx_info, vxis->vxi);
17023 ++ current->xid = vxis->xid;
17024 ++}
17025 ++
17026 ++
17027 ++static inline void __enter_vx_admin(struct vx_info_save *vxis)
17028 ++{
17029 ++ vxis->vxi = xchg(&current->vx_info, NULL);
17030 ++ vxis->xid = xchg(&current->xid, (xid_t)0);
17031 ++}
17032 ++
17033 ++static inline void __leave_vx_admin(struct vx_info_save *vxis)
17034 ++{
17035 ++ (void)xchg(&current->xid, vxis->xid);
17036 ++ (void)xchg(&current->vx_info, vxis->vxi);
17037 ++}
17038 ++
17039 ++extern void exit_vx_info(struct task_struct *, int);
17040 ++extern void exit_vx_info_early(struct task_struct *, int);
17041 ++
17042 ++
17043 ++#else
17044 ++#warning duplicate inclusion
17045 ++#endif
17046 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_cowbl.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_cowbl.h
17047 +--- linux-2.6.22.19/include/linux/vs_cowbl.h 1970-01-01 01:00:00 +0100
17048 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_cowbl.h 2007-08-05 20:53:13 +0200
17049 +@@ -0,0 +1,44 @@
17050 ++#ifndef _VS_COWBL_H
17051 ++#define _VS_COWBL_H
17052 ++
17053 ++#include <linux/fs.h>
17054 ++#include <linux/dcache.h>
17055 ++#include <linux/namei.h>
17056 ++
17057 ++extern struct dentry *cow_break_link(const char *pathname);
17058 ++
17059 ++static inline int cow_check_and_break(struct nameidata *nd)
17060 ++{
17061 ++ struct inode *inode = nd->dentry->d_inode;
17062 ++ int error = 0;
17063 ++ if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt))
17064 ++ return -EROFS;
17065 ++ if (IS_COW(inode)) {
17066 ++ if (IS_COW_LINK(inode)) {
17067 ++ struct dentry *new_dentry, *old_dentry = nd->dentry;
17068 ++ char *path, *buf;
17069 ++
17070 ++ buf = kmalloc(PATH_MAX, GFP_KERNEL);
17071 ++ if (!buf) {
17072 ++ return -ENOMEM;
17073 ++ }
17074 ++ path = d_path(nd->dentry, nd->mnt, buf, PATH_MAX);
17075 ++ new_dentry = cow_break_link(path);
17076 ++ kfree(buf);
17077 ++ if (!IS_ERR(new_dentry)) {
17078 ++ nd->dentry = new_dentry;
17079 ++ dput(old_dentry);
17080 ++ } else
17081 ++ error = PTR_ERR(new_dentry);
17082 ++ } else {
17083 ++ inode->i_flags &= ~(S_IUNLINK | S_IMMUTABLE);
17084 ++ inode->i_ctime = CURRENT_TIME;
17085 ++ mark_inode_dirty(inode);
17086 ++ }
17087 ++ }
17088 ++ return error;
17089 ++}
17090 ++
17091 ++#else
17092 ++#warning duplicate inclusion
17093 ++#endif
17094 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_cvirt.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_cvirt.h
17095 +--- linux-2.6.22.19/include/linux/vs_cvirt.h 1970-01-01 01:00:00 +0100
17096 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_cvirt.h 2007-08-05 20:53:13 +0200
17097 +@@ -0,0 +1,49 @@
17098 ++#ifndef _VS_CVIRT_H
17099 ++#define _VS_CVIRT_H
17100 ++
17101 ++#include "vserver/cvirt.h"
17102 ++#include "vserver/context.h"
17103 ++#include "vserver/base.h"
17104 ++#include "vserver/debug.h"
17105 ++
17106 ++
17107 ++static inline void vx_activate_task(struct task_struct *p)
17108 ++{
17109 ++ struct vx_info *vxi;
17110 ++
17111 ++ if ((vxi = p->vx_info)) {
17112 ++ vx_update_load(vxi);
17113 ++ atomic_inc(&vxi->cvirt.nr_running);
17114 ++ }
17115 ++}
17116 ++
17117 ++static inline void vx_deactivate_task(struct task_struct *p)
17118 ++{
17119 ++ struct vx_info *vxi;
17120 ++
17121 ++ if ((vxi = p->vx_info)) {
17122 ++ vx_update_load(vxi);
17123 ++ atomic_dec(&vxi->cvirt.nr_running);
17124 ++ }
17125 ++}
17126 ++
17127 ++static inline void vx_uninterruptible_inc(struct task_struct *p)
17128 ++{
17129 ++ struct vx_info *vxi;
17130 ++
17131 ++ if ((vxi = p->vx_info))
17132 ++ atomic_inc(&vxi->cvirt.nr_uninterruptible);
17133 ++}
17134 ++
17135 ++static inline void vx_uninterruptible_dec(struct task_struct *p)
17136 ++{
17137 ++ struct vx_info *vxi;
17138 ++
17139 ++ if ((vxi = p->vx_info))
17140 ++ atomic_dec(&vxi->cvirt.nr_uninterruptible);
17141 ++}
17142 ++
17143 ++
17144 ++#else
17145 ++#warning duplicate inclusion
17146 ++#endif
17147 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_device.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_device.h
17148 +--- linux-2.6.22.19/include/linux/vs_device.h 1970-01-01 01:00:00 +0100
17149 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_device.h 2007-10-11 01:10:22 +0200
17150 +@@ -0,0 +1,45 @@
17151 ++#ifndef _VS_DEVICE_H
17152 ++#define _VS_DEVICE_H
17153 ++
17154 ++#include "vserver/base.h"
17155 ++#include "vserver/device.h"
17156 ++#include "vserver/debug.h"
17157 ++
17158 ++
17159 ++#ifdef CONFIG_VSERVER_DEVICE
17160 ++
17161 ++int vs_map_device(struct vx_info *, dev_t, dev_t *, umode_t);
17162 ++
17163 ++#define vs_device_perm(v, d, m, p) \
17164 ++ ((vs_map_device(current_vx_info(), d, NULL, m) & (p)) == (p))
17165 ++
17166 ++#else
17167 ++
17168 ++static inline
17169 ++int vs_map_device(struct vx_info *vxi,
17170 ++ dev_t device, dev_t *target, umode_t mode)
17171 ++{
17172 ++ if (target)
17173 ++ *target = device;
17174 ++ return ~0;
17175 ++}
17176 ++
17177 ++#define vs_device_perm(v, d, m, p) ((p) == (p))
17178 ++
17179 ++#endif
17180 ++
17181 ++
17182 ++#define vs_map_chrdev(d, t, p) \
17183 ++ ((vs_map_device(current_vx_info(), d, t, S_IFCHR) & (p)) == (p))
17184 ++#define vs_map_blkdev(d, t, p) \
17185 ++ ((vs_map_device(current_vx_info(), d, t, S_IFBLK) & (p)) == (p))
17186 ++
17187 ++#define vs_chrdev_perm(d, p) \
17188 ++ vs_device_perm(current_vx_info(), d, S_IFCHR, p)
17189 ++#define vs_blkdev_perm(d, p) \
17190 ++ vs_device_perm(current_vx_info(), d, S_IFBLK, p)
17191 ++
17192 ++
17193 ++#else
17194 ++#warning duplicate inclusion
17195 ++#endif
17196 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_dlimit.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_dlimit.h
17197 +--- linux-2.6.22.19/include/linux/vs_dlimit.h 1970-01-01 01:00:00 +0100
17198 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_dlimit.h 2007-08-15 22:04:43 +0200
17199 +@@ -0,0 +1,211 @@
17200 ++#ifndef _VS_DLIMIT_H
17201 ++#define _VS_DLIMIT_H
17202 ++
17203 ++#include <linux/fs.h>
17204 ++
17205 ++#include "vserver/dlimit.h"
17206 ++#include "vserver/base.h"
17207 ++#include "vserver/debug.h"
17208 ++
17209 ++
17210 ++#define get_dl_info(i) __get_dl_info(i, __FILE__, __LINE__)
17211 ++
17212 ++static inline struct dl_info *__get_dl_info(struct dl_info *dli,
17213 ++ const char *_file, int _line)
17214 ++{
17215 ++ if (!dli)
17216 ++ return NULL;
17217 ++ vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])",
17218 ++ dli, dli ? dli->dl_tag : 0,
17219 ++ dli ? atomic_read(&dli->dl_usecnt) : 0,
17220 ++ _file, _line);
17221 ++ atomic_inc(&dli->dl_usecnt);
17222 ++ return dli;
17223 ++}
17224 ++
17225 ++
17226 ++#define free_dl_info(i) \
17227 ++ call_rcu(&(i)->dl_rcu, rcu_free_dl_info)
17228 ++
17229 ++#define put_dl_info(i) __put_dl_info(i, __FILE__, __LINE__)
17230 ++
17231 ++static inline void __put_dl_info(struct dl_info *dli,
17232 ++ const char *_file, int _line)
17233 ++{
17234 ++ if (!dli)
17235 ++ return;
17236 ++ vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])",
17237 ++ dli, dli ? dli->dl_tag : 0,
17238 ++ dli ? atomic_read(&dli->dl_usecnt) : 0,
17239 ++ _file, _line);
17240 ++ if (atomic_dec_and_test(&dli->dl_usecnt))
17241 ++ free_dl_info(dli);
17242 ++}
17243 ++
17244 ++
17245 ++#define __dlimit_char(d) ((d) ? '*' : ' ')
17246 ++
17247 ++static inline int __dl_alloc_space(struct super_block *sb,
17248 ++ tag_t tag, dlsize_t nr, const char *file, int line)
17249 ++{
17250 ++ struct dl_info *dli = NULL;
17251 ++ int ret = 0;
17252 ++
17253 ++ if (nr == 0)
17254 ++ goto out;
17255 ++ dli = locate_dl_info(sb, tag);
17256 ++ if (!dli)
17257 ++ goto out;
17258 ++
17259 ++ spin_lock(&dli->dl_lock);
17260 ++ ret = (dli->dl_space_used + nr > dli->dl_space_total);
17261 ++ if (!ret)
17262 ++ dli->dl_space_used += nr;
17263 ++ spin_unlock(&dli->dl_lock);
17264 ++ put_dl_info(dli);
17265 ++out:
17266 ++ vxlprintk(VXD_CBIT(dlim, 1),
17267 ++ "ALLOC (%p,#%d)%c %lld bytes (%d)",
17268 ++ sb, tag, __dlimit_char(dli), (long long)nr,
17269 ++ ret, file, line);
17270 ++ return ret;
17271 ++}
17272 ++
17273 ++static inline void __dl_free_space(struct super_block *sb,
17274 ++ tag_t tag, dlsize_t nr, const char *_file, int _line)
17275 ++{
17276 ++ struct dl_info *dli = NULL;
17277 ++
17278 ++ if (nr == 0)
17279 ++ goto out;
17280 ++ dli = locate_dl_info(sb, tag);
17281 ++ if (!dli)
17282 ++ goto out;
17283 ++
17284 ++ spin_lock(&dli->dl_lock);
17285 ++ if (dli->dl_space_used > nr)
17286 ++ dli->dl_space_used -= nr;
17287 ++ else
17288 ++ dli->dl_space_used = 0;
17289 ++ spin_unlock(&dli->dl_lock);
17290 ++ put_dl_info(dli);
17291 ++out:
17292 ++ vxlprintk(VXD_CBIT(dlim, 1),
17293 ++ "FREE (%p,#%d)%c %lld bytes",
17294 ++ sb, tag, __dlimit_char(dli), (long long)nr,
17295 ++ _file, _line);
17296 ++}
17297 ++
17298 ++static inline int __dl_alloc_inode(struct super_block *sb,
17299 ++ tag_t tag, const char *_file, int _line)
17300 ++{
17301 ++ struct dl_info *dli;
17302 ++ int ret = 0;
17303 ++
17304 ++ dli = locate_dl_info(sb, tag);
17305 ++ if (!dli)
17306 ++ goto out;
17307 ++
17308 ++ spin_lock(&dli->dl_lock);
17309 ++ ret = (dli->dl_inodes_used >= dli->dl_inodes_total);
17310 ++ if (!ret)
17311 ++ dli->dl_inodes_used++;
17312 ++ spin_unlock(&dli->dl_lock);
17313 ++ put_dl_info(dli);
17314 ++out:
17315 ++ vxlprintk(VXD_CBIT(dlim, 0),
17316 ++ "ALLOC (%p,#%d)%c inode (%d)",
17317 ++ sb, tag, __dlimit_char(dli), ret, _file, _line);
17318 ++ return ret;
17319 ++}
17320 ++
17321 ++static inline void __dl_free_inode(struct super_block *sb,
17322 ++ tag_t tag, const char *_file, int _line)
17323 ++{
17324 ++ struct dl_info *dli;
17325 ++
17326 ++ dli = locate_dl_info(sb, tag);
17327 ++ if (!dli)
17328 ++ goto out;
17329 ++
17330 ++ spin_lock(&dli->dl_lock);
17331 ++ if (dli->dl_inodes_used > 1)
17332 ++ dli->dl_inodes_used--;
17333 ++ else
17334 ++ dli->dl_inodes_used = 0;
17335 ++ spin_unlock(&dli->dl_lock);
17336 ++ put_dl_info(dli);
17337 ++out:
17338 ++ vxlprintk(VXD_CBIT(dlim, 0),
17339 ++ "FREE (%p,#%d)%c inode",
17340 ++ sb, tag, __dlimit_char(dli), _file, _line);
17341 ++}
17342 ++
17343 ++static inline void __dl_adjust_block(struct super_block *sb, tag_t tag,
17344 ++ unsigned long long *free_blocks, unsigned long long *root_blocks,
17345 ++ const char *_file, int _line)
17346 ++{
17347 ++ struct dl_info *dli;
17348 ++ uint64_t broot, bfree;
17349 ++
17350 ++ dli = locate_dl_info(sb, tag);
17351 ++ if (!dli)
17352 ++ return;
17353 ++
17354 ++ spin_lock(&dli->dl_lock);
17355 ++ broot = (dli->dl_space_total -
17356 ++ (dli->dl_space_total >> 10) * dli->dl_nrlmult)
17357 ++ >> sb->s_blocksize_bits;
17358 ++ bfree = (dli->dl_space_total - dli->dl_space_used)
17359 ++ >> sb->s_blocksize_bits;
17360 ++ spin_unlock(&dli->dl_lock);
17361 ++
17362 ++ vxlprintk(VXD_CBIT(dlim, 2),
17363 ++ "ADJUST: %lld,%lld on %lld,%lld [mult=%d]",
17364 ++ (long long)bfree, (long long)broot,
17365 ++ *free_blocks, *root_blocks, dli->dl_nrlmult,
17366 ++ _file, _line);
17367 ++ if (free_blocks) {
17368 ++ if (*free_blocks > bfree)
17369 ++ *free_blocks = bfree;
17370 ++ }
17371 ++ if (root_blocks) {
17372 ++ if (*root_blocks > broot)
17373 ++ *root_blocks = broot;
17374 ++ }
17375 ++ put_dl_info(dli);
17376 ++}
17377 ++
17378 ++#define DLIMIT_ALLOC_SPACE(in, bytes) \
17379 ++ __dl_alloc_space((in)->i_sb, (in)->i_tag, (dlsize_t)(bytes), \
17380 ++ __FILE__, __LINE__ )
17381 ++
17382 ++#define DLIMIT_FREE_SPACE(in, bytes) \
17383 ++ __dl_free_space((in)->i_sb, (in)->i_tag, (dlsize_t)(bytes), \
17384 ++ __FILE__, __LINE__ )
17385 ++
17386 ++#define DLIMIT_ALLOC_BLOCK(in, nr) \
17387 ++ __dl_alloc_space((in)->i_sb, (in)->i_tag, \
17388 ++ ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \
17389 ++ __FILE__, __LINE__ )
17390 ++
17391 ++#define DLIMIT_FREE_BLOCK(in, nr) \
17392 ++ __dl_free_space((in)->i_sb, (in)->i_tag, \
17393 ++ ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \
17394 ++ __FILE__, __LINE__ )
17395 ++
17396 ++
17397 ++#define DLIMIT_ALLOC_INODE(in) \
17398 ++ __dl_alloc_inode((in)->i_sb, (in)->i_tag, __FILE__, __LINE__ )
17399 ++
17400 ++#define DLIMIT_FREE_INODE(in) \
17401 ++ __dl_free_inode((in)->i_sb, (in)->i_tag, __FILE__, __LINE__ )
17402 ++
17403 ++
17404 ++#define DLIMIT_ADJUST_BLOCK(sb, tag, fb, rb) \
17405 ++ __dl_adjust_block(sb, tag, fb, rb, __FILE__, __LINE__ )
17406 ++
17407 ++
17408 ++#else
17409 ++#warning duplicate inclusion
17410 ++#endif
17411 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_inet.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_inet.h
17412 +--- linux-2.6.22.19/include/linux/vs_inet.h 1970-01-01 01:00:00 +0100
17413 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_inet.h 2007-10-05 15:07:22 +0200
17414 +@@ -0,0 +1,341 @@
17415 ++#ifndef _VS_INET_H
17416 ++#define _VS_INET_H
17417 ++
17418 ++#include "vserver/base.h"
17419 ++#include "vserver/network.h"
17420 ++#include "vserver/debug.h"
17421 ++
17422 ++#define IPI_LOOPBACK htonl(INADDR_LOOPBACK)
17423 ++
17424 ++#define NXAV4(a) NIPQUAD((a)->ip[0]), NIPQUAD((a)->ip[1]), \
17425 ++ NIPQUAD((a)->mask), (a)->type
17426 ++#define NXAV4_FMT "[" NIPQUAD_FMT "-" NIPQUAD_FMT "/" NIPQUAD_FMT ":%04x]"
17427 ++
17428 ++
17429 ++static inline
17430 ++int v4_addr_match(struct nx_addr_v4 *nxa, __be32 addr, uint16_t tmask)
17431 ++{
17432 ++ __be32 ip = nxa->ip[0].s_addr;
17433 ++ __be32 mask = nxa->mask.s_addr;
17434 ++ __be32 bcast = ip | ~mask;
17435 ++ int ret = 0;
17436 ++
17437 ++ switch (nxa->type & tmask) {
17438 ++ case NXA_TYPE_MASK:
17439 ++ ret = (ip == (addr & mask));
17440 ++ break;
17441 ++ case NXA_TYPE_ADDR:
17442 ++ ret = 3;
17443 ++ if (addr == ip)
17444 ++ break;
17445 ++ /* fall through to broadcast */
17446 ++ case NXA_MOD_BCAST:
17447 ++ ret = ((tmask & NXA_MOD_BCAST) && (addr == bcast));
17448 ++ break;
17449 ++ case NXA_TYPE_RANGE:
17450 ++ ret = ((nxa->ip[0].s_addr <= addr) &&
17451 ++ (nxa->ip[1].s_addr > addr));
17452 ++ break;
17453 ++ case NXA_TYPE_ANY:
17454 ++ ret = 2;
17455 ++ break;
17456 ++ }
17457 ++
17458 ++ vxdprintk(VXD_CBIT(net, 0),
17459 ++ "v4_addr_match(%p" NXAV4_FMT "," NIPQUAD_FMT ",%04x) = %d",
17460 ++ nxa, NXAV4(nxa), NIPQUAD(addr), tmask, ret);
17461 ++ return ret;
17462 ++}
17463 ++
17464 ++static inline
17465 ++int v4_addr_in_nx_info(struct nx_info *nxi, __be32 addr, uint16_t tmask)
17466 ++{
17467 ++ struct nx_addr_v4 *nxa;
17468 ++ int ret = 1;
17469 ++
17470 ++ if (!nxi)
17471 ++ goto out;
17472 ++
17473 ++ ret = 2;
17474 ++ /* allow 127.0.0.1 when remapping lback */
17475 ++ if ((tmask & NXA_LOOPBACK) &&
17476 ++ (addr == IPI_LOOPBACK) &&
17477 ++ nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
17478 ++ goto out;
17479 ++ ret = 3;
17480 ++ /* check for lback address */
17481 ++ if ((tmask & NXA_MOD_LBACK) &&
17482 ++ (nxi->v4_lback.s_addr == addr))
17483 ++ goto out;
17484 ++ ret = 4;
17485 ++ /* check for broadcast address */
17486 ++ if ((tmask & NXA_MOD_BCAST) &&
17487 ++ (nxi->v4_bcast.s_addr == addr))
17488 ++ goto out;
17489 ++ ret = 5;
17490 ++ /* check for v4 addresses */
17491 ++ for (nxa = &nxi->v4; nxa; nxa = nxa->next)
17492 ++ if (v4_addr_match(nxa, addr, tmask))
17493 ++ goto out;
17494 ++ ret = 0;
17495 ++out:
17496 ++ vxdprintk(VXD_CBIT(net, 0),
17497 ++ "v4_addr_in_nx_info(%p[#%u]," NIPQUAD_FMT ",%04x) = %d",
17498 ++ nxi, nxi ? nxi->nx_id : 0, NIPQUAD(addr), tmask, ret);
17499 ++ return ret;
17500 ++}
17501 ++
17502 ++static inline
17503 ++int v4_nx_addr_match(struct nx_addr_v4 *nxa, struct nx_addr_v4 *addr, uint16_t mask)
17504 ++{
17505 ++ /* FIXME: needs full range checks */
17506 ++ return v4_addr_match(nxa, addr->ip[0].s_addr, mask);
17507 ++}
17508 ++
17509 ++static inline
17510 ++int v4_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v4 *nxa, uint16_t mask)
17511 ++{
17512 ++ struct nx_addr_v4 *ptr;
17513 ++
17514 ++ for (ptr = &nxi->v4; ptr; ptr = ptr->next)
17515 ++ if (v4_nx_addr_match(ptr, nxa, mask))
17516 ++ return 1;
17517 ++ return 0;
17518 ++}
17519 ++
17520 ++#include <net/inet_sock.h>
17521 ++
17522 ++/*
17523 ++ * Check if a given address matches for a socket
17524 ++ *
17525 ++ * nxi: the socket's nx_info if any
17526 ++ * addr: to be verified address
17527 ++ */
17528 ++static inline
17529 ++int v4_sock_addr_match (
17530 ++ struct nx_info *nxi,
17531 ++ struct inet_sock *inet,
17532 ++ __be32 addr)
17533 ++{
17534 ++ __be32 saddr = inet->rcv_saddr;
17535 ++ __be32 bcast = nxi ? nxi->v4_bcast.s_addr : INADDR_BROADCAST;
17536 ++
17537 ++ if (addr && (saddr == addr || bcast == addr))
17538 ++ return 1;
17539 ++ if (!saddr)
17540 ++ return v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND);
17541 ++ return 0;
17542 ++}
17543 ++
17544 ++
17545 ++/* inet related checks and helpers */
17546 ++
17547 ++
17548 ++struct in_ifaddr;
17549 ++struct net_device;
17550 ++struct sock;
17551 ++
17552 ++#ifdef CONFIG_INET
17553 ++
17554 ++#include <linux/netdevice.h>
17555 ++#include <linux/inetdevice.h>
17556 ++#include <net/inet_timewait_sock.h>
17557 ++
17558 ++
17559 ++int dev_in_nx_info(struct net_device *, struct nx_info *);
17560 ++int v4_dev_in_nx_info(struct net_device *, struct nx_info *);
17561 ++int nx_v4_addr_conflict(struct nx_info *, struct nx_info *);
17562 ++
17563 ++
17564 ++/*
17565 ++ * check if address is covered by socket
17566 ++ *
17567 ++ * sk: the socket to check against
17568 ++ * addr: the address in question (must be != 0)
17569 ++ */
17570 ++
17571 ++static inline
17572 ++int __v4_addr_match_socket(const struct sock *sk, struct nx_addr_v4 *nxa)
17573 ++{
17574 ++ struct nx_info *nxi = sk->sk_nx_info;
17575 ++ __be32 saddr = inet_rcv_saddr(sk);
17576 ++
17577 ++ vxdprintk(VXD_CBIT(net, 5),
17578 ++ "__v4_addr_in_socket(%p," NXAV4_FMT ") %p:" NIPQUAD_FMT " %p;%lx",
17579 ++ sk, NXAV4(nxa), nxi, NIPQUAD(saddr), sk->sk_socket,
17580 ++ (sk->sk_socket?sk->sk_socket->flags:0));
17581 ++
17582 ++ if (saddr) { /* direct address match */
17583 ++ return v4_addr_match(nxa, saddr, -1);
17584 ++ } else if (nxi) { /* match against nx_info */
17585 ++ return v4_nx_addr_in_nx_info(nxi, nxa, -1);
17586 ++ } else { /* unrestricted any socket */
17587 ++ return 1;
17588 ++ }
17589 ++}
17590 ++
17591 ++
17592 ++
17593 ++static inline
17594 ++int nx_dev_visible(struct nx_info *nxi, struct net_device *dev)
17595 ++{
17596 ++ vxdprintk(VXD_CBIT(net, 1), "nx_dev_visible(%p[#%u],%p »%s«) %d",
17597 ++ nxi, nxi ? nxi->nx_id : 0, dev, dev->name,
17598 ++ nxi ? dev_in_nx_info(dev, nxi) : 0);
17599 ++
17600 ++ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
17601 ++ return 1;
17602 ++ if (dev_in_nx_info(dev, nxi))
17603 ++ return 1;
17604 ++ return 0;
17605 ++}
17606 ++
17607 ++
17608 ++static inline
17609 ++int v4_ifa_in_nx_info(struct in_ifaddr *ifa, struct nx_info *nxi)
17610 ++{
17611 ++ if (!nxi)
17612 ++ return 1;
17613 ++ if (!ifa)
17614 ++ return 0;
17615 ++ return v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW);
17616 ++}
17617 ++
17618 ++static inline
17619 ++int nx_v4_ifa_visible(struct nx_info *nxi, struct in_ifaddr *ifa)
17620 ++{
17621 ++ vxdprintk(VXD_CBIT(net, 1), "nx_v4_ifa_visible(%p[#%u],%p) %d",
17622 ++ nxi, nxi ? nxi->nx_id : 0, ifa,
17623 ++ nxi ? v4_ifa_in_nx_info(ifa, nxi) : 0);
17624 ++
17625 ++ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
17626 ++ return 1;
17627 ++ if (v4_ifa_in_nx_info(ifa, nxi))
17628 ++ return 1;
17629 ++ return 0;
17630 ++}
17631 ++
17632 ++
17633 ++struct nx_v4_sock_addr {
17634 ++ __be32 saddr; /* Address used for validation */
17635 ++ __be32 baddr; /* Address used for socket bind */
17636 ++};
17637 ++
17638 ++static inline
17639 ++int v4_map_sock_addr(struct inet_sock *inet, struct sockaddr_in *addr,
17640 ++ struct nx_v4_sock_addr *nsa)
17641 ++{
17642 ++ struct sock *sk = &inet->sk;
17643 ++ struct nx_info *nxi = sk->sk_nx_info;
17644 ++ __be32 saddr = addr->sin_addr.s_addr;
17645 ++ __be32 baddr = saddr;
17646 ++
17647 ++ vxdprintk(VXD_CBIT(net, 3),
17648 ++ "inet_bind(%p)* %p,%p;%lx " NIPQUAD_FMT,
17649 ++ sk, sk->sk_nx_info, sk->sk_socket,
17650 ++ (sk->sk_socket ? sk->sk_socket->flags : 0),
17651 ++ NIPQUAD(saddr));
17652 ++
17653 ++ if (nxi) {
17654 ++ if (saddr == INADDR_ANY) {
17655 ++ if (nx_info_flags(nxi, NXF_SINGLE_IP, 0))
17656 ++ baddr = nxi->v4.ip[0].s_addr;
17657 ++ } else if (saddr == IPI_LOOPBACK) {
17658 ++ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
17659 ++ baddr = nxi->v4_lback.s_addr;
17660 ++ } else { /* normal address bind */
17661 ++ if (!v4_addr_in_nx_info(nxi, saddr, NXA_MASK_BIND))
17662 ++ return -EADDRNOTAVAIL;
17663 ++ }
17664 ++ }
17665 ++
17666 ++ vxdprintk(VXD_CBIT(net, 3),
17667 ++ "inet_bind(%p) " NIPQUAD_FMT ", " NIPQUAD_FMT,
17668 ++ sk, NIPQUAD(saddr), NIPQUAD(baddr));
17669 ++
17670 ++ nsa->saddr = saddr;
17671 ++ nsa->baddr = baddr;
17672 ++ return 0;
17673 ++}
17674 ++
17675 ++static inline
17676 ++void v4_set_sock_addr(struct inet_sock *inet, struct nx_v4_sock_addr *nsa)
17677 ++{
17678 ++ inet->saddr = nsa->baddr;
17679 ++ inet->rcv_saddr = nsa->baddr;
17680 ++}
17681 ++
17682 ++
17683 ++/*
17684 ++ * helper to simplify inet_lookup_listener
17685 ++ *
17686 ++ * nxi: the socket's nx_info if any
17687 ++ * addr: to be verified address
17688 ++ * saddr: socket address
17689 ++ */
17690 ++static inline int v4_inet_addr_match (
17691 ++ struct nx_info *nxi,
17692 ++ __be32 addr,
17693 ++ __be32 saddr)
17694 ++{
17695 ++ if (addr && (saddr == addr))
17696 ++ return 1;
17697 ++ if (!saddr)
17698 ++ return nxi ? v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND) : 1;
17699 ++ return 0;
17700 ++}
17701 ++
17702 ++static inline __be32 nx_map_sock_lback(struct nx_info *nxi, __be32 addr)
17703 ++{
17704 ++ if (nx_info_flags(nxi, NXF_HIDE_LBACK, 0) &&
17705 ++ (addr == nxi->v4_lback.s_addr))
17706 ++ return IPI_LOOPBACK;
17707 ++ return addr;
17708 ++}
17709 ++
17710 ++static inline
17711 ++int nx_info_has_v4(struct nx_info *nxi)
17712 ++{
17713 ++ if (!nxi)
17714 ++ return 1;
17715 ++ if (NX_IPV4(nxi))
17716 ++ return 1;
17717 ++ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
17718 ++ return 1;
17719 ++ return 0;
17720 ++}
17721 ++
17722 ++#else /* CONFIG_INET */
17723 ++
17724 ++static inline
17725 ++int nx_dev_visible(struct nx_info *n, struct net_device *d)
17726 ++{
17727 ++ return 1;
17728 ++}
17729 ++
17730 ++static inline
17731 ++int nx_v4_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
17732 ++{
17733 ++ return 1;
17734 ++}
17735 ++
17736 ++static inline
17737 ++int v4_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
17738 ++{
17739 ++ return 1;
17740 ++}
17741 ++
17742 ++static inline
17743 ++int nx_info_has_v4(struct nx_info *nxi)
17744 ++{
17745 ++ return 0;
17746 ++}
17747 ++
17748 ++#endif /* CONFIG_INET */
17749 ++
17750 ++#define current_nx_info_has_v4() \
17751 ++ nx_info_has_v4(current_nx_info())
17752 ++
17753 ++#else
17754 ++#warning duplicate inclusion
17755 ++#endif
17756 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_inet6.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_inet6.h
17757 +--- linux-2.6.22.19/include/linux/vs_inet6.h 1970-01-01 01:00:00 +0100
17758 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_inet6.h 2007-10-05 14:54:36 +0200
17759 +@@ -0,0 +1,228 @@
17760 ++#ifndef _VS_INET6_H
17761 ++#define _VS_INET6_H
17762 ++
17763 ++#include <net/ipv6.h>
17764 ++#include "vserver/base.h"
17765 ++#include "vserver/network.h"
17766 ++#include "vserver/debug.h"
17767 ++
17768 ++#define NXAV6(a) NIP6((a)->ip), NIP6((a)->mask), (a)->prefix, (a)->type
17769 ++#define NXAV6_FMT "[" NIP6_FMT "/" NIP6_FMT "/%d:%04x]"
17770 ++
17771 ++
17772 ++#ifdef CONFIG_IPV6
17773 ++
17774 ++static inline
17775 ++int v6_addr_match(struct nx_addr_v6 *nxa,
17776 ++ const struct in6_addr *addr, uint16_t mask)
17777 ++{
17778 ++ switch (nxa->type & mask) {
17779 ++ case NXA_TYPE_MASK:
17780 ++ return ipv6_masked_addr_cmp(&nxa->ip, &nxa->mask, addr);
17781 ++ case NXA_TYPE_ADDR:
17782 ++ return ipv6_addr_equal(&nxa->ip, addr);
17783 ++ case NXA_TYPE_ANY:
17784 ++ return 1;
17785 ++ default:
17786 ++ return 0;
17787 ++ }
17788 ++}
17789 ++
17790 ++static inline
17791 ++int v6_addr_in_nx_info(struct nx_info *nxi,
17792 ++ const struct in6_addr *addr, uint16_t mask)
17793 ++{
17794 ++ struct nx_addr_v6 *nxa;
17795 ++
17796 ++ if (!nxi)
17797 ++ return 1;
17798 ++ for (nxa = &nxi->v6; nxa; nxa = nxa->next)
17799 ++ if (v6_addr_match(nxa, addr, mask))
17800 ++ return 1;
17801 ++ return 0;
17802 ++}
17803 ++
17804 ++static inline
17805 ++int v6_nx_addr_match(struct nx_addr_v6 *nxa, struct nx_addr_v6 *addr, uint16_t mask)
17806 ++{
17807 ++ /* FIXME: needs full range checks */
17808 ++ return v6_addr_match(nxa, &addr->ip, mask);
17809 ++}
17810 ++
17811 ++static inline
17812 ++int v6_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v6 *nxa, uint16_t mask)
17813 ++{
17814 ++ struct nx_addr_v6 *ptr;
17815 ++
17816 ++ for (ptr = &nxi->v6; ptr; ptr = ptr->next)
17817 ++ if (v6_nx_addr_match(ptr, nxa, mask))
17818 ++ return 1;
17819 ++ return 0;
17820 ++}
17821 ++
17822 ++
17823 ++/*
17824 ++ * Check if a given address matches for a socket
17825 ++ *
17826 ++ * nxi: the socket's nx_info if any
17827 ++ * addr: to be verified address
17828 ++ */
17829 ++static inline
17830 ++int v6_sock_addr_match (
17831 ++ struct nx_info *nxi,
17832 ++ struct inet_sock *inet,
17833 ++ struct in6_addr *addr)
17834 ++{
17835 ++ struct sock *sk = &inet->sk;
17836 ++ struct in6_addr *saddr = inet6_rcv_saddr(sk);
17837 ++
17838 ++ if (!ipv6_addr_any(addr) &&
17839 ++ ipv6_addr_equal(saddr, addr))
17840 ++ return 1;
17841 ++ if (ipv6_addr_any(saddr))
17842 ++ return v6_addr_in_nx_info(nxi, addr, -1);
17843 ++ return 0;
17844 ++}
17845 ++
17846 ++/*
17847 ++ * check if address is covered by socket
17848 ++ *
17849 ++ * sk: the socket to check against
17850 ++ * addr: the address in question (must be != 0)
17851 ++ */
17852 ++
17853 ++static inline
17854 ++int __v6_addr_match_socket(const struct sock *sk, struct nx_addr_v6 *nxa)
17855 ++{
17856 ++ struct nx_info *nxi = sk->sk_nx_info;
17857 ++ struct in6_addr *saddr = inet6_rcv_saddr(sk);
17858 ++
17859 ++ vxdprintk(VXD_CBIT(net, 5),
17860 ++ "__v6_addr_in_socket(%p," NXAV6_FMT ") %p:" NIP6_FMT " %p;%lx",
17861 ++ sk, NXAV6(nxa), nxi, NIP6(*saddr), sk->sk_socket,
17862 ++ (sk->sk_socket?sk->sk_socket->flags:0));
17863 ++
17864 ++ if (!ipv6_addr_any(saddr)) { /* direct address match */
17865 ++ return v6_addr_match(nxa, saddr, -1);
17866 ++ } else if (nxi) { /* match against nx_info */
17867 ++ return v6_nx_addr_in_nx_info(nxi, nxa, -1);
17868 ++ } else { /* unrestricted any socket */
17869 ++ return 1;
17870 ++ }
17871 ++}
17872 ++
17873 ++
17874 ++/* inet related checks and helpers */
17875 ++
17876 ++
17877 ++struct in_ifaddr;
17878 ++struct net_device;
17879 ++struct sock;
17880 ++
17881 ++
17882 ++#include <linux/netdevice.h>
17883 ++#include <linux/inetdevice.h>
17884 ++#include <net/inet_timewait_sock.h>
17885 ++
17886 ++
17887 ++int dev_in_nx_info(struct net_device *, struct nx_info *);
17888 ++int v6_dev_in_nx_info(struct net_device *, struct nx_info *);
17889 ++int nx_v6_addr_conflict(struct nx_info *, struct nx_info *);
17890 ++
17891 ++
17892 ++
17893 ++static inline
17894 ++int v6_ifa_in_nx_info(struct inet6_ifaddr *ifa, struct nx_info *nxi)
17895 ++{
17896 ++ if (!nxi)
17897 ++ return 1;
17898 ++ if (!ifa)
17899 ++ return 0;
17900 ++ return v6_addr_in_nx_info(nxi, &ifa->addr, -1);
17901 ++}
17902 ++
17903 ++static inline
17904 ++int nx_v6_ifa_visible(struct nx_info *nxi, struct inet6_ifaddr *ifa)
17905 ++{
17906 ++ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
17907 ++ return 1;
17908 ++ if (v6_ifa_in_nx_info(ifa, nxi))
17909 ++ return 1;
17910 ++ return 0;
17911 ++}
17912 ++
17913 ++
17914 ++struct nx_v6_sock_addr {
17915 ++ struct in6_addr saddr; /* Address used for validation */
17916 ++ struct in6_addr baddr; /* Address used for socket bind */
17917 ++};
17918 ++
17919 ++static inline
17920 ++int v6_map_sock_addr(struct inet_sock *inet, struct sockaddr_in6 *addr,
17921 ++ struct nx_v6_sock_addr *nsa)
17922 ++{
17923 ++ // struct sock *sk = &inet->sk;
17924 ++ // struct nx_info *nxi = sk->sk_nx_info;
17925 ++ struct in6_addr saddr = addr->sin6_addr;
17926 ++ struct in6_addr baddr = saddr;
17927 ++
17928 ++ nsa->saddr = saddr;
17929 ++ nsa->baddr = baddr;
17930 ++ return 0;
17931 ++}
17932 ++
17933 ++static inline
17934 ++void v6_set_sock_addr(struct inet_sock *inet, struct nx_v6_sock_addr *nsa)
17935 ++{
17936 ++ // struct sock *sk = &inet->sk;
17937 ++ // struct in6_addr *saddr = inet6_rcv_saddr(sk);
17938 ++
17939 ++ // *saddr = nsa->baddr;
17940 ++ // inet->saddr = nsa->baddr;
17941 ++}
17942 ++
17943 ++static inline
17944 ++int nx_info_has_v6(struct nx_info *nxi)
17945 ++{
17946 ++ if (!nxi)
17947 ++ return 1;
17948 ++ if (NX_IPV6(nxi))
17949 ++ return 1;
17950 ++ return 0;
17951 ++}
17952 ++
17953 ++#else /* CONFIG_IPV6 */
17954 ++
17955 ++static inline
17956 ++int nx_v6_dev_visible(struct nx_info *n, struct net_device *d)
17957 ++{
17958 ++ return 1;
17959 ++}
17960 ++
17961 ++
17962 ++static inline
17963 ++int nx_v6_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
17964 ++{
17965 ++ return 1;
17966 ++}
17967 ++
17968 ++static inline
17969 ++int v6_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
17970 ++{
17971 ++ return 1;
17972 ++}
17973 ++
17974 ++static inline
17975 ++int nx_info_has_v6(struct nx_info *nxi)
17976 ++{
17977 ++ return 0;
17978 ++}
17979 ++
17980 ++#endif /* CONFIG_IPV6 */
17981 ++
17982 ++#define current_nx_info_has_v6() \
17983 ++ nx_info_has_v6(current_nx_info())
17984 ++
17985 ++#else
17986 ++#warning duplicate inclusion
17987 ++#endif
17988 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_limit.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_limit.h
17989 +--- linux-2.6.22.19/include/linux/vs_limit.h 1970-01-01 01:00:00 +0100
17990 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_limit.h 2007-08-05 20:53:13 +0200
17991 +@@ -0,0 +1,140 @@
17992 ++#ifndef _VS_LIMIT_H
17993 ++#define _VS_LIMIT_H
17994 ++
17995 ++#include "vserver/limit.h"
17996 ++#include "vserver/base.h"
17997 ++#include "vserver/context.h"
17998 ++#include "vserver/debug.h"
17999 ++#include "vserver/context.h"
18000 ++#include "vserver/limit_int.h"
18001 ++
18002 ++
18003 ++#define vx_acc_cres(v, d, p, r) \
18004 ++ __vx_acc_cres(v, r, d, p, __FILE__, __LINE__)
18005 ++
18006 ++#define vx_acc_cres_cond(x, d, p, r) \
18007 ++ __vx_acc_cres(((x) == vx_current_xid()) ? current->vx_info : 0, \
18008 ++ r, d, p, __FILE__, __LINE__)
18009 ++
18010 ++
18011 ++#define vx_add_cres(v, a, p, r) \
18012 ++ __vx_add_cres(v, r, a, p, __FILE__, __LINE__)
18013 ++#define vx_sub_cres(v, a, p, r) vx_add_cres(v, -(a), p, r)
18014 ++
18015 ++#define vx_add_cres_cond(x, a, p, r) \
18016 ++ __vx_add_cres(((x) == vx_current_xid()) ? current->vx_info : 0, \
18017 ++ r, a, p, __FILE__, __LINE__)
18018 ++#define vx_sub_cres_cond(x, a, p, r) vx_add_cres_cond(x, -(a), p, r)
18019 ++
18020 ++
18021 ++/* process and file limits */
18022 ++
18023 ++#define vx_nproc_inc(p) \
18024 ++ vx_acc_cres((p)->vx_info, 1, p, RLIMIT_NPROC)
18025 ++
18026 ++#define vx_nproc_dec(p) \
18027 ++ vx_acc_cres((p)->vx_info,-1, p, RLIMIT_NPROC)
18028 ++
18029 ++#define vx_files_inc(f) \
18030 ++ vx_acc_cres_cond((f)->f_xid, 1, f, RLIMIT_NOFILE)
18031 ++
18032 ++#define vx_files_dec(f) \
18033 ++ vx_acc_cres_cond((f)->f_xid,-1, f, RLIMIT_NOFILE)
18034 ++
18035 ++#define vx_locks_inc(l) \
18036 ++ vx_acc_cres_cond((l)->fl_xid, 1, l, RLIMIT_LOCKS)
18037 ++
18038 ++#define vx_locks_dec(l) \
18039 ++ vx_acc_cres_cond((l)->fl_xid,-1, l, RLIMIT_LOCKS)
18040 ++
18041 ++#define vx_openfd_inc(f) \
18042 ++ vx_acc_cres(current->vx_info, 1, (void *)(long)(f), VLIMIT_OPENFD)
18043 ++
18044 ++#define vx_openfd_dec(f) \
18045 ++ vx_acc_cres(current->vx_info,-1, (void *)(long)(f), VLIMIT_OPENFD)
18046 ++
18047 ++
18048 ++#define vx_cres_avail(v, n, r) \
18049 ++ __vx_cres_avail(v, r, n, __FILE__, __LINE__)
18050 ++
18051 ++
18052 ++#define vx_nproc_avail(n) \
18053 ++ vx_cres_avail(current->vx_info, n, RLIMIT_NPROC)
18054 ++
18055 ++#define vx_files_avail(n) \
18056 ++ vx_cres_avail(current->vx_info, n, RLIMIT_NOFILE)
18057 ++
18058 ++#define vx_locks_avail(n) \
18059 ++ vx_cres_avail(current->vx_info, n, RLIMIT_LOCKS)
18060 ++
18061 ++#define vx_openfd_avail(n) \
18062 ++ vx_cres_avail(current->vx_info, n, VLIMIT_OPENFD)
18063 ++
18064 ++
18065 ++/* dentry limits */
18066 ++
18067 ++#define vx_dentry_inc(d) do { \
18068 ++ if (atomic_read(&d->d_count) == 1) \
18069 ++ vx_acc_cres(current->vx_info, 1, d, VLIMIT_DENTRY); \
18070 ++ } while (0)
18071 ++
18072 ++#define vx_dentry_dec(d) do { \
18073 ++ if (atomic_read(&d->d_count) == 0) \
18074 ++ vx_acc_cres(current->vx_info,-1, d, VLIMIT_DENTRY); \
18075 ++ } while (0)
18076 ++
18077 ++#define vx_dentry_avail(n) \
18078 ++ vx_cres_avail(current->vx_info, n, VLIMIT_DENTRY)
18079 ++
18080 ++
18081 ++/* socket limits */
18082 ++
18083 ++#define vx_sock_inc(s) \
18084 ++ vx_acc_cres((s)->sk_vx_info, 1, s, VLIMIT_NSOCK)
18085 ++
18086 ++#define vx_sock_dec(s) \
18087 ++ vx_acc_cres((s)->sk_vx_info,-1, s, VLIMIT_NSOCK)
18088 ++
18089 ++#define vx_sock_avail(n) \
18090 ++ vx_cres_avail(current->vx_info, n, VLIMIT_NSOCK)
18091 ++
18092 ++
18093 ++/* ipc resource limits */
18094 ++
18095 ++#define vx_ipcmsg_add(v, u, a) \
18096 ++ vx_add_cres(v, a, u, RLIMIT_MSGQUEUE)
18097 ++
18098 ++#define vx_ipcmsg_sub(v, u, a) \
18099 ++ vx_sub_cres(v, a, u, RLIMIT_MSGQUEUE)
18100 ++
18101 ++#define vx_ipcmsg_avail(v, a) \
18102 ++ vx_cres_avail(v, a, RLIMIT_MSGQUEUE)
18103 ++
18104 ++
18105 ++#define vx_ipcshm_add(v, k, a) \
18106 ++ vx_add_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
18107 ++
18108 ++#define vx_ipcshm_sub(v, k, a) \
18109 ++ vx_sub_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
18110 ++
18111 ++#define vx_ipcshm_avail(v, a) \
18112 ++ vx_cres_avail(v, a, VLIMIT_SHMEM)
18113 ++
18114 ++
18115 ++#define vx_semary_inc(a) \
18116 ++ vx_acc_cres(current->vx_info, 1, a, VLIMIT_SEMARY)
18117 ++
18118 ++#define vx_semary_dec(a) \
18119 ++ vx_acc_cres(current->vx_info, -1, a, VLIMIT_SEMARY)
18120 ++
18121 ++
18122 ++#define vx_nsems_add(a,n) \
18123 ++ vx_add_cres(current->vx_info, n, a, VLIMIT_NSEMS)
18124 ++
18125 ++#define vx_nsems_sub(a,n) \
18126 ++ vx_sub_cres(current->vx_info, n, a, VLIMIT_NSEMS)
18127 ++
18128 ++
18129 ++#else
18130 ++#warning duplicate inclusion
18131 ++#endif
18132 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_memory.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_memory.h
18133 +--- linux-2.6.22.19/include/linux/vs_memory.h 1970-01-01 01:00:00 +0100
18134 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_memory.h 2007-08-05 20:53:13 +0200
18135 +@@ -0,0 +1,159 @@
18136 ++#ifndef _VS_MEMORY_H
18137 ++#define _VS_MEMORY_H
18138 ++
18139 ++#include "vserver/limit.h"
18140 ++#include "vserver/base.h"
18141 ++#include "vserver/context.h"
18142 ++#include "vserver/debug.h"
18143 ++#include "vserver/context.h"
18144 ++#include "vserver/limit_int.h"
18145 ++
18146 ++
18147 ++#define __acc_add_long(a, v) (*(v) += (a))
18148 ++#define __acc_inc_long(v) (++*(v))
18149 ++#define __acc_dec_long(v) (--*(v))
18150 ++
18151 ++#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
18152 ++#define __acc_add_atomic(a, v) atomic_long_add(a, v)
18153 ++#define __acc_inc_atomic(v) atomic_long_inc(v)
18154 ++#define __acc_dec_atomic(v) atomic_long_dec(v)
18155 ++#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
18156 ++#define __acc_add_atomic(a, v) __acc_add_long(a, v)
18157 ++#define __acc_inc_atomic(v) __acc_inc_long(v)
18158 ++#define __acc_dec_atomic(v) __acc_dec_long(v)
18159 ++#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
18160 ++
18161 ++
18162 ++#define vx_acc_page(m, d, v, r) do { \
18163 ++ if ((d) > 0) \
18164 ++ __acc_inc_long(&(m)->v); \
18165 ++ else \
18166 ++ __acc_dec_long(&(m)->v); \
18167 ++ __vx_acc_cres(m->mm_vx_info, r, d, m, __FILE__, __LINE__); \
18168 ++} while (0)
18169 ++
18170 ++#define vx_acc_page_atomic(m, d, v, r) do { \
18171 ++ if ((d) > 0) \
18172 ++ __acc_inc_atomic(&(m)->v); \
18173 ++ else \
18174 ++ __acc_dec_atomic(&(m)->v); \
18175 ++ __vx_acc_cres(m->mm_vx_info, r, d, m, __FILE__, __LINE__); \
18176 ++} while (0)
18177 ++
18178 ++
18179 ++#define vx_acc_pages(m, p, v, r) do { \
18180 ++ unsigned long __p = (p); \
18181 ++ __acc_add_long(__p, &(m)->v); \
18182 ++ __vx_add_cres(m->mm_vx_info, r, __p, m, __FILE__, __LINE__); \
18183 ++} while (0)
18184 ++
18185 ++#define vx_acc_pages_atomic(m, p, v, r) do { \
18186 ++ unsigned long __p = (p); \
18187 ++ __acc_add_atomic(__p, &(m)->v); \
18188 ++ __vx_add_cres(m->mm_vx_info, r, __p, m, __FILE__, __LINE__); \
18189 ++} while (0)
18190 ++
18191 ++
18192 ++
18193 ++#define vx_acc_vmpage(m, d) \
18194 ++ vx_acc_page(m, d, total_vm, RLIMIT_AS)
18195 ++#define vx_acc_vmlpage(m, d) \
18196 ++ vx_acc_page(m, d, locked_vm, RLIMIT_MEMLOCK)
18197 ++#define vx_acc_file_rsspage(m, d) \
18198 ++ vx_acc_page_atomic(m, d, _file_rss, VLIMIT_MAPPED)
18199 ++#define vx_acc_anon_rsspage(m, d) \
18200 ++ vx_acc_page_atomic(m, d, _anon_rss, VLIMIT_ANON)
18201 ++
18202 ++#define vx_acc_vmpages(m, p) \
18203 ++ vx_acc_pages(m, p, total_vm, RLIMIT_AS)
18204 ++#define vx_acc_vmlpages(m, p) \
18205 ++ vx_acc_pages(m, p, locked_vm, RLIMIT_MEMLOCK)
18206 ++#define vx_acc_file_rsspages(m, p) \
18207 ++ vx_acc_pages_atomic(m, p, _file_rss, VLIMIT_MAPPED)
18208 ++#define vx_acc_anon_rsspages(m, p) \
18209 ++ vx_acc_pages_atomic(m, p, _anon_rss, VLIMIT_ANON)
18210 ++
18211 ++#define vx_pages_add(s, r, p) __vx_add_cres(s, r, p, 0, __FILE__, __LINE__)
18212 ++#define vx_pages_sub(s, r, p) vx_pages_add(s, r, -(p))
18213 ++
18214 ++#define vx_vmpages_inc(m) vx_acc_vmpage(m, 1)
18215 ++#define vx_vmpages_dec(m) vx_acc_vmpage(m, -1)
18216 ++#define vx_vmpages_add(m, p) vx_acc_vmpages(m, p)
18217 ++#define vx_vmpages_sub(m, p) vx_acc_vmpages(m, -(p))
18218 ++
18219 ++#define vx_vmlocked_inc(m) vx_acc_vmlpage(m, 1)
18220 ++#define vx_vmlocked_dec(m) vx_acc_vmlpage(m, -1)
18221 ++#define vx_vmlocked_add(m, p) vx_acc_vmlpages(m, p)
18222 ++#define vx_vmlocked_sub(m, p) vx_acc_vmlpages(m, -(p))
18223 ++
18224 ++#define vx_file_rsspages_inc(m) vx_acc_file_rsspage(m, 1)
18225 ++#define vx_file_rsspages_dec(m) vx_acc_file_rsspage(m, -1)
18226 ++#define vx_file_rsspages_add(m, p) vx_acc_file_rsspages(m, p)
18227 ++#define vx_file_rsspages_sub(m, p) vx_acc_file_rsspages(m, -(p))
18228 ++
18229 ++#define vx_anon_rsspages_inc(m) vx_acc_anon_rsspage(m, 1)
18230 ++#define vx_anon_rsspages_dec(m) vx_acc_anon_rsspage(m, -1)
18231 ++#define vx_anon_rsspages_add(m, p) vx_acc_anon_rsspages(m, p)
18232 ++#define vx_anon_rsspages_sub(m, p) vx_acc_anon_rsspages(m, -(p))
18233 ++
18234 ++
18235 ++#define vx_pages_avail(m, p, r) \
18236 ++ __vx_cres_avail((m)->mm_vx_info, r, p, __FILE__, __LINE__)
18237 ++
18238 ++#define vx_vmpages_avail(m, p) vx_pages_avail(m, p, RLIMIT_AS)
18239 ++#define vx_vmlocked_avail(m, p) vx_pages_avail(m, p, RLIMIT_MEMLOCK)
18240 ++#define vx_anon_avail(m, p) vx_pages_avail(m, p, VLIMIT_ANON)
18241 ++#define vx_mapped_avail(m, p) vx_pages_avail(m, p, VLIMIT_MAPPED)
18242 ++
18243 ++#define vx_rss_avail(m, p) \
18244 ++ __vx_cres_array_avail((m)->mm_vx_info, VLA_RSS, p, __FILE__, __LINE__)
18245 ++
18246 ++
18247 ++enum {
18248 ++ VXPT_UNKNOWN = 0,
18249 ++ VXPT_ANON,
18250 ++ VXPT_NONE,
18251 ++ VXPT_FILE,
18252 ++ VXPT_SWAP,
18253 ++ VXPT_WRITE
18254 ++};
18255 ++
18256 ++#if 0
18257 ++#define vx_page_fault(mm, vma, type, ret)
18258 ++#else
18259 ++
18260 ++static inline
18261 ++void __vx_page_fault(struct mm_struct *mm,
18262 ++ struct vm_area_struct *vma, int type, int ret)
18263 ++{
18264 ++ struct vx_info *vxi = mm->mm_vx_info;
18265 ++ int what;
18266 ++/*
18267 ++ static char *page_type[6] =
18268 ++ { "UNKNOWN", "ANON", "NONE", "FILE", "SWAP", "WRITE" };
18269 ++ static char *page_what[4] =
18270 ++ { "FAULT_OOM", "FAULT_SIGBUS", "FAULT_MINOR", "FAULT_MAJOR" };
18271 ++*/
18272 ++
18273 ++ if (!vxi)
18274 ++ return;
18275 ++
18276 ++ what = (ret & 0x3);
18277 ++
18278 ++/* printk("[%d] page[%d][%d] %2x %s %s\n", vxi->vx_id,
18279 ++ type, what, ret, page_type[type], page_what[what]);
18280 ++*/
18281 ++ if (ret & VM_FAULT_WRITE)
18282 ++ what |= 0x4;
18283 ++ atomic_inc(&vxi->cacct.page[type][what]);
18284 ++}
18285 ++
18286 ++#define vx_page_fault(mm, vma, type, ret) __vx_page_fault(mm, vma, type, ret)
18287 ++#endif
18288 ++
18289 ++
18290 ++extern unsigned long vx_badness(struct task_struct *task, struct mm_struct *mm);
18291 ++
18292 ++#else
18293 ++#warning duplicate inclusion
18294 ++#endif
18295 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_network.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_network.h
18296 +--- linux-2.6.22.19/include/linux/vs_network.h 1970-01-01 01:00:00 +0100
18297 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_network.h 2007-08-05 20:53:13 +0200
18298 +@@ -0,0 +1,166 @@
18299 ++#ifndef _NX_VS_NETWORK_H
18300 ++#define _NX_VS_NETWORK_H
18301 ++
18302 ++#include "vserver/context.h"
18303 ++#include "vserver/network.h"
18304 ++#include "vserver/base.h"
18305 ++#include "vserver/debug.h"
18306 ++
18307 ++
18308 ++#define get_nx_info(i) __get_nx_info(i, __FILE__, __LINE__)
18309 ++
18310 ++static inline struct nx_info *__get_nx_info(struct nx_info *nxi,
18311 ++ const char *_file, int _line)
18312 ++{
18313 ++ if (!nxi)
18314 ++ return NULL;
18315 ++
18316 ++ vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])",
18317 ++ nxi, nxi ? nxi->nx_id : 0,
18318 ++ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
18319 ++ _file, _line);
18320 ++
18321 ++ atomic_inc(&nxi->nx_usecnt);
18322 ++ return nxi;
18323 ++}
18324 ++
18325 ++
18326 ++extern void free_nx_info(struct nx_info *);
18327 ++
18328 ++#define put_nx_info(i) __put_nx_info(i, __FILE__, __LINE__)
18329 ++
18330 ++static inline void __put_nx_info(struct nx_info *nxi, const char *_file, int _line)
18331 ++{
18332 ++ if (!nxi)
18333 ++ return;
18334 ++
18335 ++ vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])",
18336 ++ nxi, nxi ? nxi->nx_id : 0,
18337 ++ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
18338 ++ _file, _line);
18339 ++
18340 ++ if (atomic_dec_and_test(&nxi->nx_usecnt))
18341 ++ free_nx_info(nxi);
18342 ++}
18343 ++
18344 ++
18345 ++#define init_nx_info(p, i) __init_nx_info(p, i, __FILE__, __LINE__)
18346 ++
18347 ++static inline void __init_nx_info(struct nx_info **nxp, struct nx_info *nxi,
18348 ++ const char *_file, int _line)
18349 ++{
18350 ++ if (nxi) {
18351 ++ vxlprintk(VXD_CBIT(nid, 3),
18352 ++ "init_nx_info(%p[#%d.%d])",
18353 ++ nxi, nxi ? nxi->nx_id : 0,
18354 ++ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
18355 ++ _file, _line);
18356 ++
18357 ++ atomic_inc(&nxi->nx_usecnt);
18358 ++ }
18359 ++ *nxp = nxi;
18360 ++}
18361 ++
18362 ++
18363 ++#define set_nx_info(p, i) __set_nx_info(p, i, __FILE__, __LINE__)
18364 ++
18365 ++static inline void __set_nx_info(struct nx_info **nxp, struct nx_info *nxi,
18366 ++ const char *_file, int _line)
18367 ++{
18368 ++ struct nx_info *nxo;
18369 ++
18370 ++ if (!nxi)
18371 ++ return;
18372 ++
18373 ++ vxlprintk(VXD_CBIT(nid, 3), "set_nx_info(%p[#%d.%d])",
18374 ++ nxi, nxi ? nxi->nx_id : 0,
18375 ++ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
18376 ++ _file, _line);
18377 ++
18378 ++ atomic_inc(&nxi->nx_usecnt);
18379 ++ nxo = xchg(nxp, nxi);
18380 ++ BUG_ON(nxo);
18381 ++}
18382 ++
18383 ++#define clr_nx_info(p) __clr_nx_info(p, __FILE__, __LINE__)
18384 ++
18385 ++static inline void __clr_nx_info(struct nx_info **nxp,
18386 ++ const char *_file, int _line)
18387 ++{
18388 ++ struct nx_info *nxo;
18389 ++
18390 ++ nxo = xchg(nxp, NULL);
18391 ++ if (!nxo)
18392 ++ return;
18393 ++
18394 ++ vxlprintk(VXD_CBIT(nid, 3), "clr_nx_info(%p[#%d.%d])",
18395 ++ nxo, nxo ? nxo->nx_id : 0,
18396 ++ nxo ? atomic_read(&nxo->nx_usecnt) : 0,
18397 ++ _file, _line);
18398 ++
18399 ++ if (atomic_dec_and_test(&nxo->nx_usecnt))
18400 ++ free_nx_info(nxo);
18401 ++}
18402 ++
18403 ++
18404 ++#define claim_nx_info(v, p) __claim_nx_info(v, p, __FILE__, __LINE__)
18405 ++
18406 ++static inline void __claim_nx_info(struct nx_info *nxi,
18407 ++ struct task_struct *task, const char *_file, int _line)
18408 ++{
18409 ++ vxlprintk(VXD_CBIT(nid, 3), "claim_nx_info(%p[#%d.%d.%d]) %p",
18410 ++ nxi, nxi ? nxi->nx_id : 0,
18411 ++ nxi?atomic_read(&nxi->nx_usecnt):0,
18412 ++ nxi?atomic_read(&nxi->nx_tasks):0,
18413 ++ task, _file, _line);
18414 ++
18415 ++ atomic_inc(&nxi->nx_tasks);
18416 ++}
18417 ++
18418 ++
18419 ++extern void unhash_nx_info(struct nx_info *);
18420 ++
18421 ++#define release_nx_info(v, p) __release_nx_info(v, p, __FILE__, __LINE__)
18422 ++
18423 ++static inline void __release_nx_info(struct nx_info *nxi,
18424 ++ struct task_struct *task, const char *_file, int _line)
18425 ++{
18426 ++ vxlprintk(VXD_CBIT(nid, 3), "release_nx_info(%p[#%d.%d.%d]) %p",
18427 ++ nxi, nxi ? nxi->nx_id : 0,
18428 ++ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
18429 ++ nxi ? atomic_read(&nxi->nx_tasks) : 0,
18430 ++ task, _file, _line);
18431 ++
18432 ++ might_sleep();
18433 ++
18434 ++ if (atomic_dec_and_test(&nxi->nx_tasks))
18435 ++ unhash_nx_info(nxi);
18436 ++}
18437 ++
18438 ++
18439 ++#define task_get_nx_info(i) __task_get_nx_info(i, __FILE__, __LINE__)
18440 ++
18441 ++static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p,
18442 ++ const char *_file, int _line)
18443 ++{
18444 ++ struct nx_info *nxi;
18445 ++
18446 ++ task_lock(p);
18447 ++ vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)",
18448 ++ p, _file, _line);
18449 ++ nxi = __get_nx_info(p->nx_info, _file, _line);
18450 ++ task_unlock(p);
18451 ++ return nxi;
18452 ++}
18453 ++
18454 ++
18455 ++static inline void exit_nx_info(struct task_struct *p)
18456 ++{
18457 ++ if (p->nx_info)
18458 ++ release_nx_info(p->nx_info, p);
18459 ++}
18460 ++
18461 ++
18462 ++#else
18463 ++#warning duplicate inclusion
18464 ++#endif
18465 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_pid.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_pid.h
18466 +--- linux-2.6.22.19/include/linux/vs_pid.h 1970-01-01 01:00:00 +0100
18467 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_pid.h 2007-09-05 02:49:29 +0200
18468 +@@ -0,0 +1,133 @@
18469 ++#ifndef _VS_PID_H
18470 ++#define _VS_PID_H
18471 ++
18472 ++#include "vserver/base.h"
18473 ++#include "vserver/context.h"
18474 ++#include "vserver/debug.h"
18475 ++#include <linux/pid_namespace.h>
18476 ++
18477 ++
18478 ++/* pid faking stuff */
18479 ++
18480 ++
18481 ++#define vx_info_map_pid(v, p) \
18482 ++ __vx_info_map_pid((v), (p), __FUNC__, __FILE__, __LINE__)
18483 ++#define vx_info_map_tgid(v,p) vx_info_map_pid(v,p)
18484 ++#define vx_map_pid(p) vx_info_map_pid(current->vx_info, p)
18485 ++#define vx_map_tgid(p) vx_map_pid(p)
18486 ++
18487 ++static inline int __vx_info_map_pid(struct vx_info *vxi, int pid,
18488 ++ const char *func, const char *file, int line)
18489 ++{
18490 ++ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
18491 ++ vxfprintk(VXD_CBIT(cvirt, 2),
18492 ++ "vx_map_tgid: %p/%llx: %d -> %d",
18493 ++ vxi, (long long)vxi->vx_flags, pid,
18494 ++ (pid && pid == vxi->vx_initpid) ? 1 : pid,
18495 ++ func, file, line);
18496 ++ if (pid == 0)
18497 ++ return 0;
18498 ++ if (pid == vxi->vx_initpid)
18499 ++ return 1;
18500 ++ }
18501 ++ return pid;
18502 ++}
18503 ++
18504 ++#define vx_info_rmap_pid(v, p) \
18505 ++ __vx_info_rmap_pid((v), (p), __FUNC__, __FILE__, __LINE__)
18506 ++#define vx_rmap_pid(p) vx_info_rmap_pid(current->vx_info, p)
18507 ++#define vx_rmap_tgid(p) vx_rmap_pid(p)
18508 ++
18509 ++static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid,
18510 ++ const char *func, const char *file, int line)
18511 ++{
18512 ++ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
18513 ++ vxfprintk(VXD_CBIT(cvirt, 2),
18514 ++ "vx_rmap_tgid: %p/%llx: %d -> %d",
18515 ++ vxi, (long long)vxi->vx_flags, pid,
18516 ++ (pid == 1) ? vxi->vx_initpid : pid,
18517 ++ func, file, line);
18518 ++ if ((pid == 1) && vxi->vx_initpid)
18519 ++ return vxi->vx_initpid;
18520 ++ if (pid == vxi->vx_initpid)
18521 ++ return ~0U;
18522 ++ }
18523 ++ return pid;
18524 ++}
18525 ++
18526 ++
18527 ++#define VXF_FAKE_INIT (VXF_INFO_INIT | VXF_STATE_INIT)
18528 ++
18529 ++static inline
18530 ++int vx_proc_task_visible(struct task_struct *task)
18531 ++{
18532 ++ if ((task->pid == 1) &&
18533 ++ !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT))
18534 ++ /* show a blend through init */
18535 ++ goto visible;
18536 ++ if (vx_check(vx_task_xid(task), VS_WATCH | VS_IDENT))
18537 ++ goto visible;
18538 ++ return 0;
18539 ++visible:
18540 ++ return 1;
18541 ++}
18542 ++
18543 ++static inline
18544 ++struct task_struct *vx_find_proc_task_by_pid(int pid)
18545 ++{
18546 ++ struct task_struct *task = find_task_by_pid(pid);
18547 ++
18548 ++ if (task && !vx_proc_task_visible(task)) {
18549 ++ vxdprintk(VXD_CBIT(misc, 6),
18550 ++ "dropping task (find) %p[#%u,%u] for %p[#%u,%u]",
18551 ++ task, task->xid, task->pid,
18552 ++ current, current->xid, current->pid);
18553 ++ task = NULL;
18554 ++ }
18555 ++ return task;
18556 ++}
18557 ++
18558 ++static inline
18559 ++struct task_struct *vx_get_proc_task(struct inode *inode, struct pid *pid)
18560 ++{
18561 ++ struct task_struct *task = get_pid_task(pid, PIDTYPE_PID);
18562 ++
18563 ++ if (task && !vx_proc_task_visible(task)) {
18564 ++ vxdprintk(VXD_CBIT(misc, 6),
18565 ++ "dropping task (get) %p[#%u,%u] for %p[#%u,%u]",
18566 ++ task, task->xid, task->pid,
18567 ++ current, current->xid, current->pid);
18568 ++ put_task_struct(task);
18569 ++ task = NULL;
18570 ++ }
18571 ++ return task;
18572 ++}
18573 ++
18574 ++
18575 ++static inline
18576 ++struct task_struct *vx_child_reaper(struct task_struct *p)
18577 ++{
18578 ++ struct vx_info *vxi = p->vx_info;
18579 ++ struct task_struct *reaper = child_reaper(p);
18580 ++
18581 ++ if (!vxi)
18582 ++ goto out;
18583 ++
18584 ++ BUG_ON(!p->vx_info->vx_reaper);
18585 ++
18586 ++ /* child reaper for the guest reaper */
18587 ++ if (vxi->vx_reaper == p)
18588 ++ goto out;
18589 ++
18590 ++ reaper = vxi->vx_reaper;
18591 ++out:
18592 ++ vxdprintk(VXD_CBIT(xid, 7),
18593 ++ "vx_child_reaper(%p[#%u,%u]) = %p[#%u,%u]",
18594 ++ p, p->xid, p->pid, reaper, reaper->xid, reaper->pid);
18595 ++ return reaper;
18596 ++}
18597 ++
18598 ++
18599 ++#else
18600 ++#warning duplicate inclusion
18601 ++#endif
18602 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_sched.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_sched.h
18603 +--- linux-2.6.22.19/include/linux/vs_sched.h 1970-01-01 01:00:00 +0100
18604 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_sched.h 2007-08-05 20:53:13 +0200
18605 +@@ -0,0 +1,110 @@
18606 ++#ifndef _VS_SCHED_H
18607 ++#define _VS_SCHED_H
18608 ++
18609 ++#include "vserver/base.h"
18610 ++#include "vserver/context.h"
18611 ++#include "vserver/sched.h"
18612 ++
18613 ++
18614 ++#define VAVAVOOM_RATIO 50
18615 ++
18616 ++#define MAX_PRIO_BIAS 20
18617 ++#define MIN_PRIO_BIAS -20
18618 ++
18619 ++
18620 ++#ifdef CONFIG_VSERVER_HARDCPU
18621 ++
18622 ++/*
18623 ++ * effective_prio - return the priority that is based on the static
18624 ++ * priority but is modified by bonuses/penalties.
18625 ++ *
18626 ++ * We scale the actual sleep average [0 .... MAX_SLEEP_AVG]
18627 ++ * into a -4 ... 0 ... +4 bonus/penalty range.
18628 ++ *
18629 ++ * Additionally, we scale another amount based on the number of
18630 ++ * CPU tokens currently held by the context, if the process is
18631 ++ * part of a context (and the appropriate SCHED flag is set).
18632 ++ * This ranges from -5 ... 0 ... +15, quadratically.
18633 ++ *
18634 ++ * So, the total bonus is -9 .. 0 .. +19
18635 ++ * We use ~50% of the full 0...39 priority range so that:
18636 ++ *
18637 ++ * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs.
18638 ++ * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks.
18639 ++ * unless that context is far exceeding its CPU allocation.
18640 ++ *
18641 ++ * Both properties are important to certain workloads.
18642 ++ */
18643 ++static inline
18644 ++int vx_effective_vavavoom(struct _vx_sched_pc *sched_pc, int max_prio)
18645 ++{
18646 ++ int vavavoom, max;
18647 ++
18648 ++ /* lots of tokens = lots of vavavoom
18649 ++ * no tokens = no vavavoom */
18650 ++ if ((vavavoom = sched_pc->tokens) >= 0) {
18651 ++ max = sched_pc->tokens_max;
18652 ++ vavavoom = max - vavavoom;
18653 ++ max = max * max;
18654 ++ vavavoom = max_prio * VAVAVOOM_RATIO / 100
18655 ++ * (vavavoom*vavavoom - (max >> 2)) / max;
18656 ++ return vavavoom;
18657 ++ }
18658 ++ return 0;
18659 ++}
18660 ++
18661 ++
18662 ++static inline
18663 ++int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
18664 ++{
18665 ++ struct vx_info *vxi = p->vx_info;
18666 ++ struct _vx_sched_pc *sched_pc;
18667 ++
18668 ++ if (!vxi)
18669 ++ return prio;
18670 ++
18671 ++ sched_pc = &vx_cpu(vxi, sched_pc);
18672 ++ if (vx_info_flags(vxi, VXF_SCHED_PRIO, 0)) {
18673 ++ int vavavoom = vx_effective_vavavoom(sched_pc, max_user);
18674 ++
18675 ++ sched_pc->vavavoom = vavavoom;
18676 ++ prio += vavavoom;
18677 ++ }
18678 ++ prio += sched_pc->prio_bias;
18679 ++ return prio;
18680 ++}
18681 ++
18682 ++#else /* !CONFIG_VSERVER_HARDCPU */
18683 ++
18684 ++static inline
18685 ++int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
18686 ++{
18687 ++ struct vx_info *vxi = p->vx_info;
18688 ++
18689 ++ if (vxi)
18690 ++ prio += vx_cpu(vxi, sched_pc).prio_bias;
18691 ++ return prio;
18692 ++}
18693 ++
18694 ++#endif /* CONFIG_VSERVER_HARDCPU */
18695 ++
18696 ++
18697 ++static inline void vx_account_user(struct vx_info *vxi,
18698 ++ cputime_t cputime, int nice)
18699 ++{
18700 ++ if (!vxi)
18701 ++ return;
18702 ++ vx_cpu(vxi, sched_pc).user_ticks += cputime;
18703 ++}
18704 ++
18705 ++static inline void vx_account_system(struct vx_info *vxi,
18706 ++ cputime_t cputime, int idle)
18707 ++{
18708 ++ if (!vxi)
18709 ++ return;
18710 ++ vx_cpu(vxi, sched_pc).sys_ticks += cputime;
18711 ++}
18712 ++
18713 ++#else
18714 ++#warning duplicate inclusion
18715 ++#endif
18716 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_socket.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_socket.h
18717 +--- linux-2.6.22.19/include/linux/vs_socket.h 1970-01-01 01:00:00 +0100
18718 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_socket.h 2007-08-05 20:53:13 +0200
18719 +@@ -0,0 +1,80 @@
18720 ++#ifndef _VS_SOCKET_H
18721 ++#define _VS_SOCKET_H
18722 ++
18723 ++#include "vserver/debug.h"
18724 ++#include "vserver/base.h"
18725 ++#include "vserver/cacct.h"
18726 ++#include "vserver/context.h"
18727 ++#include "vserver/tag.h"
18728 ++
18729 ++
18730 ++/* socket accounting */
18731 ++
18732 ++#include <linux/socket.h>
18733 ++
18734 ++static inline int vx_sock_type(int family)
18735 ++{
18736 ++ switch (family) {
18737 ++ case PF_UNSPEC:
18738 ++ return VXA_SOCK_UNSPEC;
18739 ++ case PF_UNIX:
18740 ++ return VXA_SOCK_UNIX;
18741 ++ case PF_INET:
18742 ++ return VXA_SOCK_INET;
18743 ++ case PF_INET6:
18744 ++ return VXA_SOCK_INET6;
18745 ++ case PF_PACKET:
18746 ++ return VXA_SOCK_PACKET;
18747 ++ default:
18748 ++ return VXA_SOCK_OTHER;
18749 ++ }
18750 ++}
18751 ++
18752 ++#define vx_acc_sock(v, f, p, s) \
18753 ++ __vx_acc_sock(v, f, p, s, __FILE__, __LINE__)
18754 ++
18755 ++static inline void __vx_acc_sock(struct vx_info *vxi,
18756 ++ int family, int pos, int size, char *file, int line)
18757 ++{
18758 ++ if (vxi) {
18759 ++ int type = vx_sock_type(family);
18760 ++
18761 ++ atomic_long_inc(&vxi->cacct.sock[type][pos].count);
18762 ++ atomic_long_add(size, &vxi->cacct.sock[type][pos].total);
18763 ++ }
18764 ++}
18765 ++
18766 ++#define vx_sock_recv(sk, s) \
18767 ++ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, s)
18768 ++#define vx_sock_send(sk, s) \
18769 ++ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, s)
18770 ++#define vx_sock_fail(sk, s) \
18771 ++ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, s)
18772 ++
18773 ++
18774 ++#define sock_vx_init(s) do { \
18775 ++ (s)->sk_xid = 0; \
18776 ++ (s)->sk_vx_info = NULL; \
18777 ++ } while (0)
18778 ++
18779 ++#define sock_nx_init(s) do { \
18780 ++ (s)->sk_nid = 0; \
18781 ++ (s)->sk_nx_info = NULL; \
18782 ++ } while (0)
18783 ++
18784 ++static inline
18785 ++int vx_socket_peer_tag(struct socket *sock, int level,
18786 ++ char __user *optval, int __user *optlen, int len)
18787 ++{
18788 ++ struct peer_tag tag;
18789 ++
18790 ++ tag.xid = sock->sk->sk_xid;
18791 ++ tag.nid = sock->sk->sk_nid;
18792 ++ if (copy_to_user(optval, &tag, sizeof(tag)))
18793 ++ return -EFAULT;
18794 ++ return 0;
18795 ++}
18796 ++
18797 ++#else
18798 ++#warning duplicate inclusion
18799 ++#endif
18800 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_tag.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_tag.h
18801 +--- linux-2.6.22.19/include/linux/vs_tag.h 1970-01-01 01:00:00 +0100
18802 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_tag.h 2007-08-15 19:11:32 +0200
18803 +@@ -0,0 +1,43 @@
18804 ++#ifndef _VS_TAG_H
18805 ++#define _VS_TAG_H
18806 ++
18807 ++#include <linux/vserver/tag.h>
18808 ++
18809 ++/* check conditions */
18810 ++
18811 ++#define DX_ADMIN 0x0001
18812 ++#define DX_WATCH 0x0002
18813 ++#define DX_HOSTID 0x0008
18814 ++
18815 ++#define DX_IDENT 0x0010
18816 ++
18817 ++#define DX_ARG_MASK 0x0010
18818 ++
18819 ++
18820 ++#define dx_task_tag(t) ((t)->tag)
18821 ++
18822 ++#define dx_current_tag() dx_task_tag(current)
18823 ++
18824 ++#define dx_check(c, m) __dx_check(dx_current_tag(), c, m)
18825 ++
18826 ++#define dx_weak_check(c, m) ((m) ? dx_check(c, m) : 1)
18827 ++
18828 ++
18829 ++/*
18830 ++ * check current context for ADMIN/WATCH and
18831 ++ * optionally against supplied argument
18832 ++ */
18833 ++static inline int __dx_check(tag_t cid, tag_t id, unsigned int mode)
18834 ++{
18835 ++ if (mode & DX_ARG_MASK) {
18836 ++ if ((mode & DX_IDENT) && (id == cid))
18837 ++ return 1;
18838 ++ }
18839 ++ return (((mode & DX_ADMIN) && (cid == 0)) ||
18840 ++ ((mode & DX_WATCH) && (cid == 1)) ||
18841 ++ ((mode & DX_HOSTID) && (id == 0)));
18842 ++}
18843 ++
18844 ++#else
18845 ++#warning duplicate inclusion
18846 ++#endif
18847 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vs_time.h linux-2.6.22.19-vs2.3.0.34/include/linux/vs_time.h
18848 +--- linux-2.6.22.19/include/linux/vs_time.h 1970-01-01 01:00:00 +0100
18849 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vs_time.h 2007-08-05 20:53:13 +0200
18850 +@@ -0,0 +1,19 @@
18851 ++#ifndef _VS_TIME_H
18852 ++#define _VS_TIME_H
18853 ++
18854 ++
18855 ++/* time faking stuff */
18856 ++
18857 ++#ifdef CONFIG_VSERVER_VTIME
18858 ++
18859 ++extern void vx_gettimeofday(struct timeval *tv);
18860 ++extern int vx_settimeofday(struct timespec *ts);
18861 ++
18862 ++#else
18863 ++#define vx_gettimeofday(t) do_gettimeofday(t)
18864 ++#define vx_settimeofday(t) do_settimeofday(t)
18865 ++#endif
18866 ++
18867 ++#else
18868 ++#warning duplicate inclusion
18869 ++#endif
18870 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/Kbuild linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/Kbuild
18871 +--- linux-2.6.22.19/include/linux/vserver/Kbuild 1970-01-01 01:00:00 +0100
18872 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/Kbuild 2007-10-11 01:10:22 +0200
18873 +@@ -0,0 +1,8 @@
18874 ++
18875 ++unifdef-y += context_cmd.h network_cmd.h space_cmd.h \
18876 ++ cacct_cmd.h cvirt_cmd.h limit_cmd.h dlimit_cmd.h \
18877 ++ inode_cmd.h tag_cmd.h sched_cmd.h signal_cmd.h \
18878 ++ debug_cmd.h device_cmd.h
18879 ++
18880 ++unifdef-y += switch.h network.h monitor.h inode.h device.h
18881 ++
18882 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/base.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/base.h
18883 +--- linux-2.6.22.19/include/linux/vserver/base.h 1970-01-01 01:00:00 +0100
18884 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/base.h 2007-09-17 14:07:30 +0200
18885 +@@ -0,0 +1,218 @@
18886 ++#ifndef _VX_BASE_H
18887 ++#define _VX_BASE_H
18888 ++
18889 ++
18890 ++/* context state changes */
18891 ++
18892 ++enum {
18893 ++ VSC_STARTUP = 1,
18894 ++ VSC_SHUTDOWN,
18895 ++
18896 ++ VSC_NETUP,
18897 ++ VSC_NETDOWN,
18898 ++};
18899 ++
18900 ++
18901 ++#define MAX_S_CONTEXT 65535 /* Arbitrary limit */
18902 ++
18903 ++/* check conditions */
18904 ++
18905 ++#define VS_ADMIN 0x0001
18906 ++#define VS_WATCH 0x0002
18907 ++#define VS_HIDE 0x0004
18908 ++#define VS_HOSTID 0x0008
18909 ++
18910 ++#define VS_IDENT 0x0010
18911 ++#define VS_EQUIV 0x0020
18912 ++#define VS_PARENT 0x0040
18913 ++#define VS_CHILD 0x0080
18914 ++
18915 ++#define VS_ARG_MASK 0x00F0
18916 ++
18917 ++#ifdef CONFIG_VSERVER_PRIVACY
18918 ++#define VS_ADMIN_P (0)
18919 ++#define VS_WATCH_P (0)
18920 ++#else
18921 ++#define VS_ADMIN_P VS_ADMIN
18922 ++#define VS_WATCH_P VS_WATCH
18923 ++#endif
18924 ++
18925 ++#define VS_HARDIRQ 0x1000
18926 ++#define VS_SOFTIRQ 0x2000
18927 ++#define VS_IRQ 0x4000
18928 ++
18929 ++#define VS_IRQ_MASK 0xF000
18930 ++
18931 ++#include <linux/hardirq.h>
18932 ++
18933 ++/*
18934 ++ * check current context for ADMIN/WATCH and
18935 ++ * optionally against supplied argument
18936 ++ */
18937 ++static inline int __vs_check(int cid, int id, unsigned int mode)
18938 ++{
18939 ++ if (mode & VS_ARG_MASK) {
18940 ++ if ((mode & VS_IDENT) && (id == cid))
18941 ++ return 1;
18942 ++ }
18943 ++ if (mode & VS_IRQ_MASK) {
18944 ++ if ((mode & VS_IRQ) && unlikely(in_interrupt()))
18945 ++ return 1;
18946 ++ if ((mode & VS_HARDIRQ) && unlikely(in_irq()))
18947 ++ return 1;
18948 ++ if ((mode & VS_SOFTIRQ) && unlikely(in_softirq()))
18949 ++ return 1;
18950 ++ }
18951 ++ return (((mode & VS_ADMIN) && (cid == 0)) ||
18952 ++ ((mode & VS_WATCH) && (cid == 1)) ||
18953 ++ ((mode & VS_HOSTID) && (id == 0)));
18954 ++}
18955 ++
18956 ++#define vx_task_xid(t) ((t)->xid)
18957 ++
18958 ++#define vx_current_xid() vx_task_xid(current)
18959 ++
18960 ++#define current_vx_info() (current->vx_info)
18961 ++
18962 ++
18963 ++#define vx_check(c, m) __vs_check(vx_current_xid(), c, (m) | VS_IRQ)
18964 ++
18965 ++#define vx_weak_check(c, m) ((m) ? vx_check(c, m) : 1)
18966 ++
18967 ++
18968 ++#define nx_task_nid(t) ((t)->nid)
18969 ++
18970 ++#define nx_current_nid() nx_task_nid(current)
18971 ++
18972 ++#define current_nx_info() (current->nx_info)
18973 ++
18974 ++
18975 ++#define nx_check(c, m) __vs_check(nx_current_nid(), c, m)
18976 ++
18977 ++#define nx_weak_check(c, m) ((m) ? nx_check(c, m) : 1)
18978 ++
18979 ++
18980 ++
18981 ++/* generic flag merging */
18982 ++
18983 ++#define vs_check_flags(v, m, f) (((v) & (m)) ^ (f))
18984 ++
18985 ++#define vs_mask_flags(v, f, m) (((v) & ~(m)) | ((f) & (m)))
18986 ++
18987 ++#define vs_mask_mask(v, f, m) (((v) & ~(m)) | ((v) & (f) & (m)))
18988 ++
18989 ++#define vs_check_bit(v, n) ((v) & (1LL << (n)))
18990 ++
18991 ++
18992 ++/* context flags */
18993 ++
18994 ++#define __vx_flags(v) ((v) ? (v)->vx_flags : 0)
18995 ++
18996 ++#define vx_current_flags() __vx_flags(current->vx_info)
18997 ++
18998 ++#define vx_info_flags(v, m, f) \
18999 ++ vs_check_flags(__vx_flags(v), m, f)
19000 ++
19001 ++#define task_vx_flags(t, m, f) \
19002 ++ ((t) && vx_info_flags((t)->vx_info, m, f))
19003 ++
19004 ++#define vx_flags(m, f) vx_info_flags(current->vx_info, m, f)
19005 ++
19006 ++
19007 ++/* context caps */
19008 ++
19009 ++#define __vx_ccaps(v) ((v) ? (v)->vx_ccaps : 0)
19010 ++
19011 ++#define vx_current_ccaps() __vx_ccaps(current->vx_info)
19012 ++
19013 ++#define vx_info_ccaps(v, c) (__vx_ccaps(v) & (c))
19014 ++
19015 ++#define vx_ccaps(c) vx_info_ccaps(current->vx_info, (c))
19016 ++
19017 ++
19018 ++
19019 ++/* network flags */
19020 ++
19021 ++#define __nx_flags(n) ((n) ? (n)->nx_flags : 0)
19022 ++
19023 ++#define nx_current_flags() __nx_flags(current->nx_info)
19024 ++
19025 ++#define nx_info_flags(n, m, f) \
19026 ++ vs_check_flags(__nx_flags(n), m, f)
19027 ++
19028 ++#define task_nx_flags(t, m, f) \
19029 ++ ((t) && nx_info_flags((t)->nx_info, m, f))
19030 ++
19031 ++#define nx_flags(m, f) nx_info_flags(current->nx_info, m, f)
19032 ++
19033 ++
19034 ++/* network caps */
19035 ++
19036 ++#define __nx_ncaps(n) ((n) ? (n)->nx_ncaps : 0)
19037 ++
19038 ++#define nx_current_ncaps() __nx_ncaps(current->nx_info)
19039 ++
19040 ++#define nx_info_ncaps(n, c) (__nx_ncaps(n) & (c))
19041 ++
19042 ++#define nx_ncaps(c) nx_info_ncaps(current->nx_info, c)
19043 ++
19044 ++
19045 ++/* context mask capabilities */
19046 ++
19047 ++#define __vx_mcaps(v) ((v) ? (v)->vx_ccaps >> 32UL : ~0 )
19048 ++
19049 ++#define vx_info_mcaps(v, c) (__vx_mcaps(v) & (c))
19050 ++
19051 ++#define vx_mcaps(c) vx_info_mcaps(current->vx_info, c)
19052 ++
19053 ++
19054 ++/* context bcap mask */
19055 ++
19056 ++#define __vx_bcaps(v) ((v) ? (v)->vx_bcaps : ~0 )
19057 ++
19058 ++#define vx_current_bcaps() __vx_bcaps(current->vx_info)
19059 ++
19060 ++#define vx_info_bcaps(v, c) (__vx_bcaps(v) & (c))
19061 ++
19062 ++#define vx_bcaps(c) vx_info_bcaps(current->vx_info, c)
19063 ++
19064 ++
19065 ++#define vx_info_cap_bset(v) ((v) ? (v)->vx_cap_bset : cap_bset)
19066 ++
19067 ++#define vx_current_cap_bset() vx_info_cap_bset(current->vx_info)
19068 ++
19069 ++
19070 ++#define __vx_info_mbcap(v, b) \
19071 ++ (!vx_info_flags(v, VXF_STATE_SETUP, 0) ? \
19072 ++ vx_info_bcaps(v, b) : (b))
19073 ++
19074 ++#define vx_info_mbcap(v, b) __vx_info_mbcap(v, cap_t(b))
19075 ++
19076 ++#define task_vx_mbcap(t, b) \
19077 ++ vx_info_mbcap((t)->vx_info, (t)->b)
19078 ++
19079 ++#define vx_mbcap(b) task_vx_mbcap(current, b)
19080 ++
19081 ++#define vx_cap_raised(v, c, f) (vx_info_mbcap(v, c) & CAP_TO_MASK(f))
19082 ++
19083 ++#define vx_capable(b, c) (capable(b) || \
19084 ++ (cap_raised(current->cap_effective, b) && vx_ccaps(c)))
19085 ++
19086 ++#define nx_capable(b, c) (capable(b) || \
19087 ++ (cap_raised(current->cap_effective, b) && nx_ncaps(c)))
19088 ++
19089 ++#define vx_current_initpid(n) \
19090 ++ (current->vx_info && \
19091 ++ (current->vx_info->vx_initpid == (n)))
19092 ++
19093 ++
19094 ++#define __vx_state(v) ((v) ? ((v)->vx_state) : 0)
19095 ++
19096 ++#define vx_info_state(v, m) (__vx_state(v) & (m))
19097 ++
19098 ++
19099 ++#define __nx_state(n) ((n) ? ((n)->nx_state) : 0)
19100 ++
19101 ++#define nx_info_state(n, m) (__nx_state(n) & (m))
19102 ++
19103 ++#endif
19104 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/cacct.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/cacct.h
19105 +--- linux-2.6.22.19/include/linux/vserver/cacct.h 1970-01-01 01:00:00 +0100
19106 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/cacct.h 2007-08-05 20:53:13 +0200
19107 +@@ -0,0 +1,15 @@
19108 ++#ifndef _VX_CACCT_H
19109 ++#define _VX_CACCT_H
19110 ++
19111 ++
19112 ++enum sock_acc_field {
19113 ++ VXA_SOCK_UNSPEC = 0,
19114 ++ VXA_SOCK_UNIX,
19115 ++ VXA_SOCK_INET,
19116 ++ VXA_SOCK_INET6,
19117 ++ VXA_SOCK_PACKET,
19118 ++ VXA_SOCK_OTHER,
19119 ++ VXA_SOCK_SIZE /* array size */
19120 ++};
19121 ++
19122 ++#endif /* _VX_CACCT_H */
19123 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/cacct_cmd.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/cacct_cmd.h
19124 +--- linux-2.6.22.19/include/linux/vserver/cacct_cmd.h 1970-01-01 01:00:00 +0100
19125 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/cacct_cmd.h 2007-08-05 20:53:13 +0200
19126 +@@ -0,0 +1,23 @@
19127 ++#ifndef _VX_CACCT_CMD_H
19128 ++#define _VX_CACCT_CMD_H
19129 ++
19130 ++
19131 ++/* virtual host info name commands */
19132 ++
19133 ++#define VCMD_sock_stat VC_CMD(VSTAT, 5, 0)
19134 ++
19135 ++struct vcmd_sock_stat_v0 {
19136 ++ uint32_t field;
19137 ++ uint32_t count[3];
19138 ++ uint64_t total[3];
19139 ++};
19140 ++
19141 ++
19142 ++#ifdef __KERNEL__
19143 ++
19144 ++#include <linux/compiler.h>
19145 ++
19146 ++extern int vc_sock_stat(struct vx_info *, void __user *);
19147 ++
19148 ++#endif /* __KERNEL__ */
19149 ++#endif /* _VX_CACCT_CMD_H */
19150 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/cacct_def.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/cacct_def.h
19151 +--- linux-2.6.22.19/include/linux/vserver/cacct_def.h 1970-01-01 01:00:00 +0100
19152 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/cacct_def.h 2007-08-05 20:53:13 +0200
19153 +@@ -0,0 +1,43 @@
19154 ++#ifndef _VX_CACCT_DEF_H
19155 ++#define _VX_CACCT_DEF_H
19156 ++
19157 ++#include <asm/atomic.h>
19158 ++#include <linux/vserver/cacct.h>
19159 ++
19160 ++
19161 ++struct _vx_sock_acc {
19162 ++ atomic_long_t count;
19163 ++ atomic_long_t total;
19164 ++};
19165 ++
19166 ++/* context sub struct */
19167 ++
19168 ++struct _vx_cacct {
19169 ++ struct _vx_sock_acc sock[VXA_SOCK_SIZE][3];
19170 ++ atomic_t slab[8];
19171 ++ atomic_t page[6][8];
19172 ++};
19173 ++
19174 ++#ifdef CONFIG_VSERVER_DEBUG
19175 ++
19176 ++static inline void __dump_vx_cacct(struct _vx_cacct *cacct)
19177 ++{
19178 ++ int i, j;
19179 ++
19180 ++ printk("\t_vx_cacct:");
19181 ++ for (i = 0; i < 6; i++) {
19182 ++ struct _vx_sock_acc *ptr = cacct->sock[i];
19183 ++
19184 ++ printk("\t [%d] =", i);
19185 ++ for (j = 0; j < 3; j++) {
19186 ++ printk(" [%d] = %8lu, %8lu", j,
19187 ++ atomic_long_read(&ptr[j].count),
19188 ++ atomic_long_read(&ptr[j].total));
19189 ++ }
19190 ++ printk("\n");
19191 ++ }
19192 ++}
19193 ++
19194 ++#endif
19195 ++
19196 ++#endif /* _VX_CACCT_DEF_H */
19197 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/cacct_int.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/cacct_int.h
19198 +--- linux-2.6.22.19/include/linux/vserver/cacct_int.h 1970-01-01 01:00:00 +0100
19199 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/cacct_int.h 2007-08-05 20:53:13 +0200
19200 +@@ -0,0 +1,21 @@
19201 ++#ifndef _VX_CACCT_INT_H
19202 ++#define _VX_CACCT_INT_H
19203 ++
19204 ++
19205 ++#ifdef __KERNEL__
19206 ++
19207 ++static inline
19208 ++unsigned long vx_sock_count(struct _vx_cacct *cacct, int type, int pos)
19209 ++{
19210 ++ return atomic_long_read(&cacct->sock[type][pos].count);
19211 ++}
19212 ++
19213 ++
19214 ++static inline
19215 ++unsigned long vx_sock_total(struct _vx_cacct *cacct, int type, int pos)
19216 ++{
19217 ++ return atomic_long_read(&cacct->sock[type][pos].total);
19218 ++}
19219 ++
19220 ++#endif /* __KERNEL__ */
19221 ++#endif /* _VX_CACCT_INT_H */
19222 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/context.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/context.h
19223 +--- linux-2.6.22.19/include/linux/vserver/context.h 1970-01-01 01:00:00 +0100
19224 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/context.h 2007-10-11 01:10:22 +0200
19225 +@@ -0,0 +1,176 @@
19226 ++#ifndef _VX_CONTEXT_H
19227 ++#define _VX_CONTEXT_H
19228 ++
19229 ++#include <linux/types.h>
19230 ++#include <linux/capability.h>
19231 ++
19232 ++
19233 ++/* context flags */
19234 ++
19235 ++#define VXF_INFO_SCHED 0x00000002
19236 ++#define VXF_INFO_NPROC 0x00000004
19237 ++#define VXF_INFO_PRIVATE 0x00000008
19238 ++
19239 ++#define VXF_INFO_INIT 0x00000010
19240 ++#define VXF_INFO_HIDE 0x00000020
19241 ++#define VXF_INFO_ULIMIT 0x00000040
19242 ++#define VXF_INFO_NSPACE 0x00000080
19243 ++
19244 ++#define VXF_SCHED_HARD 0x00000100
19245 ++#define VXF_SCHED_PRIO 0x00000200
19246 ++#define VXF_SCHED_PAUSE 0x00000400
19247 ++
19248 ++#define VXF_VIRT_MEM 0x00010000
19249 ++#define VXF_VIRT_UPTIME 0x00020000
19250 ++#define VXF_VIRT_CPU 0x00040000
19251 ++#define VXF_VIRT_LOAD 0x00080000
19252 ++#define VXF_VIRT_TIME 0x00100000
19253 ++
19254 ++#define VXF_HIDE_MOUNT 0x01000000
19255 ++/* was VXF_HIDE_NETIF 0x02000000 */
19256 ++#define VXF_HIDE_VINFO 0x04000000
19257 ++
19258 ++#define VXF_STATE_SETUP (1ULL << 32)
19259 ++#define VXF_STATE_INIT (1ULL << 33)
19260 ++#define VXF_STATE_ADMIN (1ULL << 34)
19261 ++
19262 ++#define VXF_SC_HELPER (1ULL << 36)
19263 ++#define VXF_REBOOT_KILL (1ULL << 37)
19264 ++#define VXF_PERSISTENT (1ULL << 38)
19265 ++
19266 ++#define VXF_FORK_RSS (1ULL << 48)
19267 ++#define VXF_PROLIFIC (1ULL << 49)
19268 ++
19269 ++#define VXF_IGNEG_NICE (1ULL << 52)
19270 ++
19271 ++#define VXF_ONE_TIME (0x0007ULL << 32)
19272 ++
19273 ++#define VXF_INIT_SET (VXF_STATE_SETUP | VXF_STATE_INIT | VXF_STATE_ADMIN)
19274 ++
19275 ++
19276 ++/* context migration */
19277 ++
19278 ++#define VXM_SET_INIT 0x00000001
19279 ++#define VXM_SET_REAPER 0x00000002
19280 ++
19281 ++/* context caps */
19282 ++
19283 ++#define VXC_CAP_MASK 0x00000000
19284 ++
19285 ++#define VXC_SET_UTSNAME 0x00000001
19286 ++#define VXC_SET_RLIMIT 0x00000002
19287 ++
19288 ++/* was VXC_RAW_ICMP 0x00000100 */
19289 ++#define VXC_SYSLOG 0x00001000
19290 ++
19291 ++#define VXC_SECURE_MOUNT 0x00010000
19292 ++#define VXC_SECURE_REMOUNT 0x00020000
19293 ++#define VXC_BINARY_MOUNT 0x00040000
19294 ++
19295 ++#define VXC_QUOTA_CTL 0x00100000
19296 ++#define VXC_ADMIN_MAPPER 0x00200000
19297 ++#define VXC_ADMIN_CLOOP 0x00400000
19298 ++
19299 ++#define VXC_KTHREAD 0x01000000
19300 ++
19301 ++
19302 ++#ifdef __KERNEL__
19303 ++
19304 ++#include <linux/list.h>
19305 ++#include <linux/spinlock.h>
19306 ++#include <linux/rcupdate.h>
19307 ++
19308 ++#include "limit_def.h"
19309 ++#include "sched_def.h"
19310 ++#include "cvirt_def.h"
19311 ++#include "cacct_def.h"
19312 ++#include "device_def.h"
19313 ++
19314 ++struct _vx_info_pc {
19315 ++ struct _vx_sched_pc sched_pc;
19316 ++ struct _vx_cvirt_pc cvirt_pc;
19317 ++};
19318 ++
19319 ++struct vx_info {
19320 ++ struct hlist_node vx_hlist; /* linked list of contexts */
19321 ++ xid_t vx_id; /* context id */
19322 ++ atomic_t vx_usecnt; /* usage count */
19323 ++ atomic_t vx_tasks; /* tasks count */
19324 ++ struct vx_info *vx_parent; /* parent context */
19325 ++ int vx_state; /* context state */
19326 ++
19327 ++ unsigned long vx_nsmask; /* assignment mask */
19328 ++ struct nsproxy *vx_nsproxy; /* private namespace */
19329 ++ struct fs_struct *vx_fs; /* private namespace fs */
19330 ++
19331 ++ uint64_t vx_flags; /* context flags */
19332 ++ uint64_t vx_bcaps; /* bounding caps (system) */
19333 ++ uint64_t vx_ccaps; /* context caps (vserver) */
19334 ++ kernel_cap_t vx_cap_bset; /* the guest's bset */
19335 ++
19336 ++ struct task_struct *vx_reaper; /* guest reaper process */
19337 ++ pid_t vx_initpid; /* PID of guest init */
19338 ++ int64_t vx_badness_bias; /* OOM points bias */
19339 ++
19340 ++ struct _vx_limit limit; /* vserver limits */
19341 ++ struct _vx_sched sched; /* vserver scheduler */
19342 ++ struct _vx_cvirt cvirt; /* virtual/bias stuff */
19343 ++ struct _vx_cacct cacct; /* context accounting */
19344 ++
19345 ++ struct _vx_device dmap; /* default device map targets */
19346 ++
19347 ++#ifndef CONFIG_SMP
19348 ++ struct _vx_info_pc info_pc; /* per cpu data */
19349 ++#else
19350 ++ struct _vx_info_pc *ptr_pc; /* per cpu array */
19351 ++#endif
19352 ++
19353 ++ wait_queue_head_t vx_wait; /* context exit waitqueue */
19354 ++ int reboot_cmd; /* last sys_reboot() cmd */
19355 ++ int exit_code; /* last process exit code */
19356 ++
19357 ++ char vx_name[65]; /* vserver name */
19358 ++};
19359 ++
19360 ++#ifndef CONFIG_SMP
19361 ++#define vx_ptr_pc(vxi) (&(vxi)->info_pc)
19362 ++#define vx_per_cpu(vxi, v, id) vx_ptr_pc(vxi)->v
19363 ++#else
19364 ++#define vx_ptr_pc(vxi) ((vxi)->ptr_pc)
19365 ++#define vx_per_cpu(vxi, v, id) per_cpu_ptr(vx_ptr_pc(vxi), id)->v
19366 ++#endif
19367 ++
19368 ++#define vx_cpu(vxi, v) vx_per_cpu(vxi, v, smp_processor_id())
19369 ++
19370 ++
19371 ++struct vx_info_save {
19372 ++ struct vx_info *vxi;
19373 ++ xid_t xid;
19374 ++};
19375 ++
19376 ++
19377 ++/* status flags */
19378 ++
19379 ++#define VXS_HASHED 0x0001
19380 ++#define VXS_PAUSED 0x0010
19381 ++#define VXS_SHUTDOWN 0x0100
19382 ++#define VXS_HELPER 0x1000
19383 ++#define VXS_RELEASED 0x8000
19384 ++
19385 ++
19386 ++extern void claim_vx_info(struct vx_info *, struct task_struct *);
19387 ++extern void release_vx_info(struct vx_info *, struct task_struct *);
19388 ++
19389 ++extern struct vx_info *lookup_vx_info(int);
19390 ++extern struct vx_info *lookup_or_create_vx_info(int);
19391 ++
19392 ++extern int get_xid_list(int, unsigned int *, int);
19393 ++extern int xid_is_hashed(xid_t);
19394 ++
19395 ++extern int vx_migrate_task(struct task_struct *, struct vx_info *, int);
19396 ++
19397 ++extern long vs_state_change(struct vx_info *, unsigned int);
19398 ++
19399 ++
19400 ++#endif /* __KERNEL__ */
19401 ++#endif /* _VX_CONTEXT_H */
19402 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/context_cmd.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/context_cmd.h
19403 +--- linux-2.6.22.19/include/linux/vserver/context_cmd.h 1970-01-01 01:00:00 +0100
19404 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/context_cmd.h 2007-08-19 00:40:28 +0200
19405 +@@ -0,0 +1,128 @@
19406 ++#ifndef _VX_CONTEXT_CMD_H
19407 ++#define _VX_CONTEXT_CMD_H
19408 ++
19409 ++
19410 ++/* vinfo commands */
19411 ++
19412 ++#define VCMD_task_xid VC_CMD(VINFO, 1, 0)
19413 ++
19414 ++#ifdef __KERNEL__
19415 ++extern int vc_task_xid(uint32_t);
19416 ++
19417 ++#endif /* __KERNEL__ */
19418 ++
19419 ++#define VCMD_vx_info VC_CMD(VINFO, 5, 0)
19420 ++
19421 ++struct vcmd_vx_info_v0 {
19422 ++ uint32_t xid;
19423 ++ uint32_t initpid;
19424 ++ /* more to come */
19425 ++};
19426 ++
19427 ++#ifdef __KERNEL__
19428 ++extern int vc_vx_info(struct vx_info *, void __user *);
19429 ++
19430 ++#endif /* __KERNEL__ */
19431 ++
19432 ++#define VCMD_ctx_stat VC_CMD(VSTAT, 0, 0)
19433 ++
19434 ++struct vcmd_ctx_stat_v0 {
19435 ++ uint32_t usecnt;
19436 ++ uint32_t tasks;
19437 ++ /* more to come */
19438 ++};
19439 ++
19440 ++#ifdef __KERNEL__
19441 ++extern int vc_ctx_stat(struct vx_info *, void __user *);
19442 ++
19443 ++#endif /* __KERNEL__ */
19444 ++
19445 ++/* context commands */
19446 ++
19447 ++#define VCMD_ctx_create_v0 VC_CMD(VPROC, 1, 0)
19448 ++#define VCMD_ctx_create VC_CMD(VPROC, 1, 1)
19449 ++
19450 ++struct vcmd_ctx_create {
19451 ++ uint64_t flagword;
19452 ++};
19453 ++
19454 ++#define VCMD_ctx_migrate_v0 VC_CMD(PROCMIG, 1, 0)
19455 ++#define VCMD_ctx_migrate VC_CMD(PROCMIG, 1, 1)
19456 ++
19457 ++struct vcmd_ctx_migrate {
19458 ++ uint64_t flagword;
19459 ++};
19460 ++
19461 ++#ifdef __KERNEL__
19462 ++extern int vc_ctx_create(uint32_t, void __user *);
19463 ++extern int vc_ctx_migrate(struct vx_info *, void __user *);
19464 ++
19465 ++#endif /* __KERNEL__ */
19466 ++
19467 ++
19468 ++/* flag commands */
19469 ++
19470 ++#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0)
19471 ++#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0)
19472 ++
19473 ++struct vcmd_ctx_flags_v0 {
19474 ++ uint64_t flagword;
19475 ++ uint64_t mask;
19476 ++};
19477 ++
19478 ++#ifdef __KERNEL__
19479 ++extern int vc_get_cflags(struct vx_info *, void __user *);
19480 ++extern int vc_set_cflags(struct vx_info *, void __user *);
19481 ++
19482 ++#endif /* __KERNEL__ */
19483 ++
19484 ++
19485 ++/* context caps commands */
19486 ++
19487 ++#define VCMD_get_ccaps VC_CMD(FLAGS, 3, 1)
19488 ++#define VCMD_set_ccaps VC_CMD(FLAGS, 4, 1)
19489 ++
19490 ++struct vcmd_ctx_caps_v1 {
19491 ++ uint64_t ccaps;
19492 ++ uint64_t cmask;
19493 ++};
19494 ++
19495 ++#ifdef __KERNEL__
19496 ++extern int vc_get_ccaps(struct vx_info *, void __user *);
19497 ++extern int vc_set_ccaps(struct vx_info *, void __user *);
19498 ++
19499 ++#endif /* __KERNEL__ */
19500 ++
19501 ++
19502 ++/* bcaps commands */
19503 ++
19504 ++#define VCMD_get_bcaps VC_CMD(FLAGS, 9, 0)
19505 ++#define VCMD_set_bcaps VC_CMD(FLAGS, 10, 0)
19506 ++
19507 ++struct vcmd_bcaps {
19508 ++ uint64_t bcaps;
19509 ++ uint64_t bmask;
19510 ++};
19511 ++
19512 ++#ifdef __KERNEL__
19513 ++extern int vc_get_bcaps(struct vx_info *, void __user *);
19514 ++extern int vc_set_bcaps(struct vx_info *, void __user *);
19515 ++
19516 ++#endif /* __KERNEL__ */
19517 ++
19518 ++
19519 ++/* OOM badness */
19520 ++
19521 ++#define VCMD_get_badness VC_CMD(MEMCTRL, 5, 0)
19522 ++#define VCMD_set_badness VC_CMD(MEMCTRL, 6, 0)
19523 ++
19524 ++struct vcmd_badness_v0 {
19525 ++ int64_t bias;
19526 ++};
19527 ++
19528 ++#ifdef __KERNEL__
19529 ++extern int vc_get_badness(struct vx_info *, void __user *);
19530 ++extern int vc_set_badness(struct vx_info *, void __user *);
19531 ++
19532 ++#endif /* __KERNEL__ */
19533 ++#endif /* _VX_CONTEXT_CMD_H */
19534 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/cvirt.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/cvirt.h
19535 +--- linux-2.6.22.19/include/linux/vserver/cvirt.h 1970-01-01 01:00:00 +0100
19536 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/cvirt.h 2007-08-05 20:53:13 +0200
19537 +@@ -0,0 +1,20 @@
19538 ++#ifndef _VX_CVIRT_H
19539 ++#define _VX_CVIRT_H
19540 ++
19541 ++
19542 ++#ifdef __KERNEL__
19543 ++
19544 ++struct timespec;
19545 ++
19546 ++void vx_vsi_uptime(struct timespec *, struct timespec *);
19547 ++
19548 ++
19549 ++struct vx_info;
19550 ++
19551 ++void vx_update_load(struct vx_info *);
19552 ++
19553 ++
19554 ++int vx_do_syslog(int, char __user *, int);
19555 ++
19556 ++#endif /* __KERNEL__ */
19557 ++#endif /* _VX_CVIRT_H */
19558 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/cvirt_cmd.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/cvirt_cmd.h
19559 +--- linux-2.6.22.19/include/linux/vserver/cvirt_cmd.h 1970-01-01 01:00:00 +0100
19560 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/cvirt_cmd.h 2007-08-05 20:53:13 +0200
19561 +@@ -0,0 +1,53 @@
19562 ++#ifndef _VX_CVIRT_CMD_H
19563 ++#define _VX_CVIRT_CMD_H
19564 ++
19565 ++
19566 ++/* virtual host info name commands */
19567 ++
19568 ++#define VCMD_set_vhi_name VC_CMD(VHOST, 1, 0)
19569 ++#define VCMD_get_vhi_name VC_CMD(VHOST, 2, 0)
19570 ++
19571 ++struct vcmd_vhi_name_v0 {
19572 ++ uint32_t field;
19573 ++ char name[65];
19574 ++};
19575 ++
19576 ++
19577 ++enum vhi_name_field {
19578 ++ VHIN_CONTEXT = 0,
19579 ++ VHIN_SYSNAME,
19580 ++ VHIN_NODENAME,
19581 ++ VHIN_RELEASE,
19582 ++ VHIN_VERSION,
19583 ++ VHIN_MACHINE,
19584 ++ VHIN_DOMAINNAME,
19585 ++};
19586 ++
19587 ++
19588 ++#ifdef __KERNEL__
19589 ++
19590 ++#include <linux/compiler.h>
19591 ++
19592 ++extern int vc_set_vhi_name(struct vx_info *, void __user *);
19593 ++extern int vc_get_vhi_name(struct vx_info *, void __user *);
19594 ++
19595 ++#endif /* __KERNEL__ */
19596 ++
19597 ++#define VCMD_virt_stat VC_CMD(VSTAT, 3, 0)
19598 ++
19599 ++struct vcmd_virt_stat_v0 {
19600 ++ uint64_t offset;
19601 ++ uint64_t uptime;
19602 ++ uint32_t nr_threads;
19603 ++ uint32_t nr_running;
19604 ++ uint32_t nr_uninterruptible;
19605 ++ uint32_t nr_onhold;
19606 ++ uint32_t nr_forks;
19607 ++ uint32_t load[3];
19608 ++};
19609 ++
19610 ++#ifdef __KERNEL__
19611 ++extern int vc_virt_stat(struct vx_info *, void __user *);
19612 ++
19613 ++#endif /* __KERNEL__ */
19614 ++#endif /* _VX_CVIRT_CMD_H */
19615 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/cvirt_def.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/cvirt_def.h
19616 +--- linux-2.6.22.19/include/linux/vserver/cvirt_def.h 1970-01-01 01:00:00 +0100
19617 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/cvirt_def.h 2007-08-05 20:53:13 +0200
19618 +@@ -0,0 +1,81 @@
19619 ++#ifndef _VX_CVIRT_DEF_H
19620 ++#define _VX_CVIRT_DEF_H
19621 ++
19622 ++#include <linux/jiffies.h>
19623 ++#include <linux/spinlock.h>
19624 ++#include <linux/wait.h>
19625 ++#include <linux/time.h>
19626 ++#include <linux/utsname.h>
19627 ++#include <asm/atomic.h>
19628 ++
19629 ++
19630 ++struct _vx_usage_stat {
19631 ++ uint64_t user;
19632 ++ uint64_t nice;
19633 ++ uint64_t system;
19634 ++ uint64_t softirq;
19635 ++ uint64_t irq;
19636 ++ uint64_t idle;
19637 ++ uint64_t iowait;
19638 ++};
19639 ++
19640 ++struct _vx_syslog {
19641 ++ wait_queue_head_t log_wait;
19642 ++ spinlock_t logbuf_lock; /* lock for the log buffer */
19643 ++
19644 ++ unsigned long log_start; /* next char to be read by syslog() */
19645 ++ unsigned long con_start; /* next char to be sent to consoles */
19646 ++ unsigned long log_end; /* most-recently-written-char + 1 */
19647 ++ unsigned long logged_chars; /* #chars since last read+clear operation */
19648 ++
19649 ++ char log_buf[1024];
19650 ++};
19651 ++
19652 ++
19653 ++/* context sub struct */
19654 ++
19655 ++struct _vx_cvirt {
19656 ++ atomic_t nr_threads; /* number of current threads */
19657 ++ atomic_t nr_running; /* number of running threads */
19658 ++ atomic_t nr_uninterruptible; /* number of uninterruptible threads */
19659 ++
19660 ++ atomic_t nr_onhold; /* processes on hold */
19661 ++ uint32_t onhold_last; /* jiffies when put on hold */
19662 ++
19663 ++ struct timeval bias_tv; /* time offset to the host */
19664 ++ struct timespec bias_idle;
19665 ++ struct timespec bias_uptime; /* context creation point */
19666 ++ uint64_t bias_clock; /* offset in clock_t */
19667 ++
19668 ++ spinlock_t load_lock; /* lock for the load averages */
19669 ++ atomic_t load_updates; /* nr of load updates done so far */
19670 ++ uint32_t load_last; /* last time load was calculated */
19671 ++ uint32_t load[3]; /* load averages 1,5,15 */
19672 ++
19673 ++ atomic_t total_forks; /* number of forks so far */
19674 ++
19675 ++ struct _vx_syslog syslog;
19676 ++};
19677 ++
19678 ++struct _vx_cvirt_pc {
19679 ++ struct _vx_usage_stat cpustat;
19680 ++};
19681 ++
19682 ++
19683 ++#ifdef CONFIG_VSERVER_DEBUG
19684 ++
19685 ++static inline void __dump_vx_cvirt(struct _vx_cvirt *cvirt)
19686 ++{
19687 ++ printk("\t_vx_cvirt:\n");
19688 ++ printk("\t threads: %4d, %4d, %4d, %4d\n",
19689 ++ atomic_read(&cvirt->nr_threads),
19690 ++ atomic_read(&cvirt->nr_running),
19691 ++ atomic_read(&cvirt->nr_uninterruptible),
19692 ++ atomic_read(&cvirt->nr_onhold));
19693 ++ /* add rest here */
19694 ++ printk("\t total_forks = %d\n", atomic_read(&cvirt->total_forks));
19695 ++}
19696 ++
19697 ++#endif
19698 ++
19699 ++#endif /* _VX_CVIRT_DEF_H */
19700 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/debug.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/debug.h
19701 +--- linux-2.6.22.19/include/linux/vserver/debug.h 1970-01-01 01:00:00 +0100
19702 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/debug.h 2007-10-25 17:05:55 +0200
19703 +@@ -0,0 +1,130 @@
19704 ++#ifndef _VX_DEBUG_H
19705 ++#define _VX_DEBUG_H
19706 ++
19707 ++
19708 ++#define VXD_CBIT(n, m) (vx_debug_ ## n & (1 << (m)))
19709 ++#define VXD_CMIN(n, m) (vx_debug_ ## n > (m))
19710 ++#define VXD_MASK(n, m) (vx_debug_ ## n & (m))
19711 ++
19712 ++#define VXD_DEV(d) (d), (d)->bd_inode->i_ino, \
19713 ++ imajor((d)->bd_inode), iminor((d)->bd_inode)
19714 ++#define VXF_DEV "%p[%lu,%d:%d]"
19715 ++
19716 ++
19717 ++#define __FUNC__ __func__
19718 ++
19719 ++
19720 ++#define vxd_path(d, m) \
19721 ++ ({ static char _buffer[PATH_MAX]; \
19722 ++ d_path(d, m, _buffer, sizeof(_buffer)); })
19723 ++
19724 ++#define vxd_cond_path(n) \
19725 ++ ((n) ? vxd_path((n)->dentry, (n)->mnt) : "<null>" )
19726 ++
19727 ++
19728 ++#ifdef CONFIG_VSERVER_DEBUG
19729 ++
19730 ++extern unsigned int vx_debug_switch;
19731 ++extern unsigned int vx_debug_xid;
19732 ++extern unsigned int vx_debug_nid;
19733 ++extern unsigned int vx_debug_tag;
19734 ++extern unsigned int vx_debug_net;
19735 ++extern unsigned int vx_debug_limit;
19736 ++extern unsigned int vx_debug_cres;
19737 ++extern unsigned int vx_debug_dlim;
19738 ++extern unsigned int vx_debug_quota;
19739 ++extern unsigned int vx_debug_cvirt;
19740 ++extern unsigned int vx_debug_space;
19741 ++extern unsigned int vx_debug_misc;
19742 ++
19743 ++
19744 ++#define VX_LOGLEVEL "vxD: "
19745 ++#define VX_PROC_FMT "%p: "
19746 ++#define VX_PROCESS current
19747 ++
19748 ++#define vxdprintk(c, f, x...) \
19749 ++ do { \
19750 ++ if (c) \
19751 ++ printk(VX_LOGLEVEL VX_PROC_FMT f "\n", \
19752 ++ VX_PROCESS , ##x); \
19753 ++ } while (0)
19754 ++
19755 ++#define vxlprintk(c, f, x...) \
19756 ++ do { \
19757 ++ if (c) \
19758 ++ printk(VX_LOGLEVEL f " @%s:%d\n", x); \
19759 ++ } while (0)
19760 ++
19761 ++#define vxfprintk(c, f, x...) \
19762 ++ do { \
19763 ++ if (c) \
19764 ++ printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \
19765 ++ } while (0)
19766 ++
19767 ++
19768 ++struct vx_info;
19769 ++
19770 ++void dump_vx_info(struct vx_info *, int);
19771 ++void dump_vx_info_inactive(int);
19772 ++
19773 ++#else /* CONFIG_VSERVER_DEBUG */
19774 ++
19775 ++#define vx_debug_switch 0
19776 ++#define vx_debug_xid 0
19777 ++#define vx_debug_nid 0
19778 ++#define vx_debug_tag 0
19779 ++#define vx_debug_net 0
19780 ++#define vx_debug_limit 0
19781 ++#define vx_debug_cres 0
19782 ++#define vx_debug_dlim 0
19783 ++#define vx_debug_cvirt 0
19784 ++
19785 ++#define vxdprintk(x...) do { } while (0)
19786 ++#define vxlprintk(x...) do { } while (0)
19787 ++#define vxfprintk(x...) do { } while (0)
19788 ++
19789 ++#endif /* CONFIG_VSERVER_DEBUG */
19790 ++
19791 ++
19792 ++#ifdef CONFIG_VSERVER_WARN
19793 ++
19794 ++#define VX_WARNLEVEL KERN_WARNING "vxW: "
19795 ++#define VX_WARN_TASK "[»%s«,%u:#%u|%u|%u] "
19796 ++#define VX_WARN_XID "[xid #%u] "
19797 ++#define VX_WARN_NID "[nid #%u] "
19798 ++#define VX_WARN_TAG "[tag #%u] "
19799 ++
19800 ++#define vxwprintk(c, f, x...) \
19801 ++ do { \
19802 ++ if (c) \
19803 ++ printk(VX_WARNLEVEL f "\n", ##x); \
19804 ++ } while (0)
19805 ++
19806 ++#else /* CONFIG_VSERVER_WARN */
19807 ++
19808 ++#define vxwprintk(x...) do { } while (0)
19809 ++
19810 ++#endif /* CONFIG_VSERVER_WARN */
19811 ++
19812 ++#define vxwprintk_task(c, f, x...) \
19813 ++ vxwprintk(c, VX_WARN_TASK f, \
19814 ++ current->comm, current->pid, \
19815 ++ current->xid, current->nid, current->tag, ##x)
19816 ++#define vxwprintk_xid(c, f, x...) \
19817 ++ vxwprintk(c, VX_WARN_XID f, current->xid, x)
19818 ++#define vxwprintk_nid(c, f, x...) \
19819 ++ vxwprintk(c, VX_WARN_NID f, current->nid, x)
19820 ++#define vxwprintk_tag(c, f, x...) \
19821 ++ vxwprintk(c, VX_WARN_TAG f, current->tag, x)
19822 ++
19823 ++#ifdef CONFIG_VSERVER_DEBUG
19824 ++#define vxd_assert_lock(l) assert_spin_locked(l)
19825 ++#define vxd_assert(c, f, x...) vxlprintk(!(c), \
19826 ++ "assertion [" f "] failed.", ##x, __FILE__, __LINE__)
19827 ++#else
19828 ++#define vxd_assert_lock(l) do { } while (0)
19829 ++#define vxd_assert(c, f, x...) do { } while (0)
19830 ++#endif
19831 ++
19832 ++
19833 ++#endif /* _VX_DEBUG_H */
19834 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/debug_cmd.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/debug_cmd.h
19835 +--- linux-2.6.22.19/include/linux/vserver/debug_cmd.h 1970-01-01 01:00:00 +0100
19836 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/debug_cmd.h 2007-08-05 20:53:13 +0200
19837 +@@ -0,0 +1,58 @@
19838 ++#ifndef _VX_DEBUG_CMD_H
19839 ++#define _VX_DEBUG_CMD_H
19840 ++
19841 ++
19842 ++/* debug commands */
19843 ++
19844 ++#define VCMD_dump_history VC_CMD(DEBUG, 1, 0)
19845 ++
19846 ++#define VCMD_read_history VC_CMD(DEBUG, 5, 0)
19847 ++#define VCMD_read_monitor VC_CMD(DEBUG, 6, 0)
19848 ++
19849 ++struct vcmd_read_history_v0 {
19850 ++ uint32_t index;
19851 ++ uint32_t count;
19852 ++ char __user *data;
19853 ++};
19854 ++
19855 ++struct vcmd_read_monitor_v0 {
19856 ++ uint32_t index;
19857 ++ uint32_t count;
19858 ++ char __user *data;
19859 ++};
19860 ++
19861 ++
19862 ++#ifdef __KERNEL__
19863 ++
19864 ++#ifdef CONFIG_COMPAT
19865 ++
19866 ++#include <asm/compat.h>
19867 ++
19868 ++struct vcmd_read_history_v0_x32 {
19869 ++ uint32_t index;
19870 ++ uint32_t count;
19871 ++ compat_uptr_t data_ptr;
19872 ++};
19873 ++
19874 ++struct vcmd_read_monitor_v0_x32 {
19875 ++ uint32_t index;
19876 ++ uint32_t count;
19877 ++ compat_uptr_t data_ptr;
19878 ++};
19879 ++
19880 ++#endif /* CONFIG_COMPAT */
19881 ++
19882 ++extern int vc_dump_history(uint32_t);
19883 ++
19884 ++extern int vc_read_history(uint32_t, void __user *);
19885 ++extern int vc_read_monitor(uint32_t, void __user *);
19886 ++
19887 ++#ifdef CONFIG_COMPAT
19888 ++
19889 ++extern int vc_read_history_x32(uint32_t, void __user *);
19890 ++extern int vc_read_monitor_x32(uint32_t, void __user *);
19891 ++
19892 ++#endif /* CONFIG_COMPAT */
19893 ++
19894 ++#endif /* __KERNEL__ */
19895 ++#endif /* _VX_DEBUG_CMD_H */
19896 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/device.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/device.h
19897 +--- linux-2.6.22.19/include/linux/vserver/device.h 1970-01-01 01:00:00 +0100
19898 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/device.h 2007-10-11 01:10:22 +0200
19899 +@@ -0,0 +1,15 @@
19900 ++#ifndef _VX_DEVICE_H
19901 ++#define _VX_DEVICE_H
19902 ++
19903 ++
19904 ++#define DATTR_CREATE 0x00000001
19905 ++#define DATTR_OPEN 0x00000002
19906 ++
19907 ++#define DATTR_REMAP 0x00000010
19908 ++
19909 ++#define DATTR_MASK 0x00000013
19910 ++
19911 ++
19912 ++#else /* _VX_DEVICE_H */
19913 ++#warning duplicate inclusion
19914 ++#endif /* _VX_DEVICE_H */
19915 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/device_cmd.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/device_cmd.h
19916 +--- linux-2.6.22.19/include/linux/vserver/device_cmd.h 1970-01-01 01:00:00 +0100
19917 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/device_cmd.h 2007-10-11 01:10:22 +0200
19918 +@@ -0,0 +1,44 @@
19919 ++#ifndef _VX_DEVICE_CMD_H
19920 ++#define _VX_DEVICE_CMD_H
19921 ++
19922 ++
19923 ++/* device vserver commands */
19924 ++
19925 ++#define VCMD_set_mapping VC_CMD(DEVICE, 1, 0)
19926 ++#define VCMD_unset_mapping VC_CMD(DEVICE, 2, 0)
19927 ++
19928 ++struct vcmd_set_mapping_v0 {
19929 ++ const char __user *device;
19930 ++ const char __user *target;
19931 ++ uint32_t flags;
19932 ++};
19933 ++
19934 ++
19935 ++#ifdef __KERNEL__
19936 ++
19937 ++#ifdef CONFIG_COMPAT
19938 ++
19939 ++#include <asm/compat.h>
19940 ++
19941 ++struct vcmd_set_mapping_v0_x32 {
19942 ++ compat_uptr_t device_ptr;
19943 ++ compat_uptr_t target_ptr;
19944 ++ uint32_t flags;
19945 ++};
19946 ++
19947 ++#endif /* CONFIG_COMPAT */
19948 ++
19949 ++#include <linux/compiler.h>
19950 ++
19951 ++extern int vc_set_mapping(struct vx_info *, void __user *);
19952 ++extern int vc_unset_mapping(struct vx_info *, void __user *);
19953 ++
19954 ++#ifdef CONFIG_COMPAT
19955 ++
19956 ++extern int vc_set_mapping_x32(struct vx_info *, void __user *);
19957 ++extern int vc_unset_mapping_x32(struct vx_info *, void __user *);
19958 ++
19959 ++#endif /* CONFIG_COMPAT */
19960 ++
19961 ++#endif /* __KERNEL__ */
19962 ++#endif /* _VX_DEVICE_CMD_H */
19963 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/device_def.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/device_def.h
19964 +--- linux-2.6.22.19/include/linux/vserver/device_def.h 1970-01-01 01:00:00 +0100
19965 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/device_def.h 2007-10-11 01:10:22 +0200
19966 +@@ -0,0 +1,17 @@
19967 ++#ifndef _VX_DEVICE_DEF_H
19968 ++#define _VX_DEVICE_DEF_H
19969 ++
19970 ++#include <linux/types.h>
19971 ++
19972 ++struct vx_dmap_target {
19973 ++ dev_t target;
19974 ++ uint32_t flags;
19975 ++};
19976 ++
19977 ++struct _vx_device {
19978 ++#ifdef CONFIG_VSERVER_DEVICE
19979 ++ struct vx_dmap_target targets[2];
19980 ++#endif
19981 ++};
19982 ++
19983 ++#endif /* _VX_DEVICE_DEF_H */
19984 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/dlimit.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/dlimit.h
19985 +--- linux-2.6.22.19/include/linux/vserver/dlimit.h 1970-01-01 01:00:00 +0100
19986 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/dlimit.h 2007-08-15 22:03:58 +0200
19987 +@@ -0,0 +1,54 @@
19988 ++#ifndef _VX_DLIMIT_H
19989 ++#define _VX_DLIMIT_H
19990 ++
19991 ++#include "switch.h"
19992 ++
19993 ++
19994 ++#ifdef __KERNEL__
19995 ++
19996 ++/* keep in sync with CDLIM_INFINITY */
19997 ++
19998 ++#define DLIM_INFINITY (~0ULL)
19999 ++
20000 ++#include <linux/spinlock.h>
20001 ++#include <linux/rcupdate.h>
20002 ++
20003 ++struct super_block;
20004 ++
20005 ++struct dl_info {
20006 ++ struct hlist_node dl_hlist; /* linked list of contexts */
20007 ++ struct rcu_head dl_rcu; /* the rcu head */
20008 ++ tag_t dl_tag; /* context tag */
20009 ++ atomic_t dl_usecnt; /* usage count */
20010 ++ atomic_t dl_refcnt; /* reference count */
20011 ++
20012 ++ struct super_block *dl_sb; /* associated superblock */
20013 ++
20014 ++ spinlock_t dl_lock; /* protect the values */
20015 ++
20016 ++ unsigned long long dl_space_used; /* used space in bytes */
20017 ++ unsigned long long dl_space_total; /* maximum space in bytes */
20018 ++ unsigned long dl_inodes_used; /* used inodes */
20019 ++ unsigned long dl_inodes_total; /* maximum inodes */
20020 ++
20021 ++ unsigned int dl_nrlmult; /* non root limit mult */
20022 ++};
20023 ++
20024 ++struct rcu_head;
20025 ++
20026 ++extern void rcu_free_dl_info(struct rcu_head *);
20027 ++extern void unhash_dl_info(struct dl_info *);
20028 ++
20029 ++extern struct dl_info *locate_dl_info(struct super_block *, tag_t);
20030 ++
20031 ++
20032 ++struct kstatfs;
20033 ++
20034 ++extern void vx_vsi_statfs(struct super_block *, struct kstatfs *);
20035 ++
20036 ++typedef uint64_t dlsize_t;
20037 ++
20038 ++#endif /* __KERNEL__ */
20039 ++#else /* _VX_DLIMIT_H */
20040 ++#warning duplicate inclusion
20041 ++#endif /* _VX_DLIMIT_H */
20042 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/dlimit_cmd.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/dlimit_cmd.h
20043 +--- linux-2.6.22.19/include/linux/vserver/dlimit_cmd.h 1970-01-01 01:00:00 +0100
20044 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/dlimit_cmd.h 2007-08-05 20:53:13 +0200
20045 +@@ -0,0 +1,74 @@
20046 ++#ifndef _VX_DLIMIT_CMD_H
20047 ++#define _VX_DLIMIT_CMD_H
20048 ++
20049 ++
20050 ++/* dlimit vserver commands */
20051 ++
20052 ++#define VCMD_add_dlimit VC_CMD(DLIMIT, 1, 0)
20053 ++#define VCMD_rem_dlimit VC_CMD(DLIMIT, 2, 0)
20054 ++
20055 ++#define VCMD_set_dlimit VC_CMD(DLIMIT, 5, 0)
20056 ++#define VCMD_get_dlimit VC_CMD(DLIMIT, 6, 0)
20057 ++
20058 ++struct vcmd_ctx_dlimit_base_v0 {
20059 ++ const char __user *name;
20060 ++ uint32_t flags;
20061 ++};
20062 ++
20063 ++struct vcmd_ctx_dlimit_v0 {
20064 ++ const char __user *name;
20065 ++ uint32_t space_used; /* used space in kbytes */
20066 ++ uint32_t space_total; /* maximum space in kbytes */
20067 ++ uint32_t inodes_used; /* used inodes */
20068 ++ uint32_t inodes_total; /* maximum inodes */
20069 ++ uint32_t reserved; /* reserved for root in % */
20070 ++ uint32_t flags;
20071 ++};
20072 ++
20073 ++#define CDLIM_UNSET ((uint32_t)0UL)
20074 ++#define CDLIM_INFINITY ((uint32_t)~0UL)
20075 ++#define CDLIM_KEEP ((uint32_t)~1UL)
20076 ++
20077 ++#ifdef __KERNEL__
20078 ++
20079 ++#ifdef CONFIG_COMPAT
20080 ++
20081 ++#include <asm/compat.h>
20082 ++
20083 ++struct vcmd_ctx_dlimit_base_v0_x32 {
20084 ++ compat_uptr_t name_ptr;
20085 ++ uint32_t flags;
20086 ++};
20087 ++
20088 ++struct vcmd_ctx_dlimit_v0_x32 {
20089 ++ compat_uptr_t name_ptr;
20090 ++ uint32_t space_used; /* used space in kbytes */
20091 ++ uint32_t space_total; /* maximum space in kbytes */
20092 ++ uint32_t inodes_used; /* used inodes */
20093 ++ uint32_t inodes_total; /* maximum inodes */
20094 ++ uint32_t reserved; /* reserved for root in % */
20095 ++ uint32_t flags;
20096 ++};
20097 ++
20098 ++#endif /* CONFIG_COMPAT */
20099 ++
20100 ++#include <linux/compiler.h>
20101 ++
20102 ++extern int vc_add_dlimit(uint32_t, void __user *);
20103 ++extern int vc_rem_dlimit(uint32_t, void __user *);
20104 ++
20105 ++extern int vc_set_dlimit(uint32_t, void __user *);
20106 ++extern int vc_get_dlimit(uint32_t, void __user *);
20107 ++
20108 ++#ifdef CONFIG_COMPAT
20109 ++
20110 ++extern int vc_add_dlimit_x32(uint32_t, void __user *);
20111 ++extern int vc_rem_dlimit_x32(uint32_t, void __user *);
20112 ++
20113 ++extern int vc_set_dlimit_x32(uint32_t, void __user *);
20114 ++extern int vc_get_dlimit_x32(uint32_t, void __user *);
20115 ++
20116 ++#endif /* CONFIG_COMPAT */
20117 ++
20118 ++#endif /* __KERNEL__ */
20119 ++#endif /* _VX_DLIMIT_CMD_H */
20120 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/global.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/global.h
20121 +--- linux-2.6.22.19/include/linux/vserver/global.h 1970-01-01 01:00:00 +0100
20122 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/global.h 2007-08-05 20:53:13 +0200
20123 +@@ -0,0 +1,18 @@
20124 ++#ifndef _VX_GLOBAL_H
20125 ++#define _VX_GLOBAL_H
20126 ++
20127 ++
20128 ++extern atomic_t vx_global_ctotal;
20129 ++extern atomic_t vx_global_cactive;
20130 ++
20131 ++extern atomic_t nx_global_ctotal;
20132 ++extern atomic_t nx_global_cactive;
20133 ++
20134 ++extern atomic_t vs_global_nsproxy;
20135 ++extern atomic_t vs_global_fs;
20136 ++extern atomic_t vs_global_mnt_ns;
20137 ++extern atomic_t vs_global_uts_ns;
20138 ++extern atomic_t vs_global_ipc_ns;
20139 ++
20140 ++
20141 ++#endif /* _VX_GLOBAL_H */
20142 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/history.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/history.h
20143 +--- linux-2.6.22.19/include/linux/vserver/history.h 1970-01-01 01:00:00 +0100
20144 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/history.h 2007-08-05 20:53:13 +0200
20145 +@@ -0,0 +1,197 @@
20146 ++#ifndef _VX_HISTORY_H
20147 ++#define _VX_HISTORY_H
20148 ++
20149 ++
20150 ++enum {
20151 ++ VXH_UNUSED = 0,
20152 ++ VXH_THROW_OOPS = 1,
20153 ++
20154 ++ VXH_GET_VX_INFO,
20155 ++ VXH_PUT_VX_INFO,
20156 ++ VXH_INIT_VX_INFO,
20157 ++ VXH_SET_VX_INFO,
20158 ++ VXH_CLR_VX_INFO,
20159 ++ VXH_CLAIM_VX_INFO,
20160 ++ VXH_RELEASE_VX_INFO,
20161 ++ VXH_ALLOC_VX_INFO,
20162 ++ VXH_DEALLOC_VX_INFO,
20163 ++ VXH_HASH_VX_INFO,
20164 ++ VXH_UNHASH_VX_INFO,
20165 ++ VXH_LOC_VX_INFO,
20166 ++ VXH_LOOKUP_VX_INFO,
20167 ++ VXH_CREATE_VX_INFO,
20168 ++};
20169 ++
20170 ++struct _vxhe_vxi {
20171 ++ struct vx_info *ptr;
20172 ++ unsigned xid;
20173 ++ unsigned usecnt;
20174 ++ unsigned tasks;
20175 ++};
20176 ++
20177 ++struct _vxhe_set_clr {
20178 ++ void *data;
20179 ++};
20180 ++
20181 ++struct _vxhe_loc_lookup {
20182 ++ unsigned arg;
20183 ++};
20184 ++
20185 ++struct _vx_hist_entry {
20186 ++ void *loc;
20187 ++ unsigned short seq;
20188 ++ unsigned short type;
20189 ++ struct _vxhe_vxi vxi;
20190 ++ union {
20191 ++ struct _vxhe_set_clr sc;
20192 ++ struct _vxhe_loc_lookup ll;
20193 ++ };
20194 ++};
20195 ++
20196 ++#ifdef CONFIG_VSERVER_HISTORY
20197 ++
20198 ++extern unsigned volatile int vxh_active;
20199 ++
20200 ++struct _vx_hist_entry *vxh_advance(void *loc);
20201 ++
20202 ++
20203 ++static inline
20204 ++void __vxh_copy_vxi(struct _vx_hist_entry *entry, struct vx_info *vxi)
20205 ++{
20206 ++ entry->vxi.ptr = vxi;
20207 ++ if (vxi) {
20208 ++ entry->vxi.usecnt = atomic_read(&vxi->vx_usecnt);
20209 ++ entry->vxi.tasks = atomic_read(&vxi->vx_tasks);
20210 ++ entry->vxi.xid = vxi->vx_id;
20211 ++ }
20212 ++}
20213 ++
20214 ++
20215 ++#define __HERE__ current_text_addr()
20216 ++
20217 ++#define __VXH_BODY(__type, __data, __here) \
20218 ++ struct _vx_hist_entry *entry; \
20219 ++ \
20220 ++ preempt_disable(); \
20221 ++ entry = vxh_advance(__here); \
20222 ++ __data; \
20223 ++ entry->type = __type; \
20224 ++ preempt_enable();
20225 ++
20226 ++
20227 ++ /* pass vxi only */
20228 ++
20229 ++#define __VXH_SMPL \
20230 ++ __vxh_copy_vxi(entry, vxi)
20231 ++
20232 ++static inline
20233 ++void __vxh_smpl(struct vx_info *vxi, int __type, void *__here)
20234 ++{
20235 ++ __VXH_BODY(__type, __VXH_SMPL, __here)
20236 ++}
20237 ++
20238 ++ /* pass vxi and data (void *) */
20239 ++
20240 ++#define __VXH_DATA \
20241 ++ __vxh_copy_vxi(entry, vxi); \
20242 ++ entry->sc.data = data
20243 ++
20244 ++static inline
20245 ++void __vxh_data(struct vx_info *vxi, void *data,
20246 ++ int __type, void *__here)
20247 ++{
20248 ++ __VXH_BODY(__type, __VXH_DATA, __here)
20249 ++}
20250 ++
20251 ++ /* pass vxi and arg (long) */
20252 ++
20253 ++#define __VXH_LONG \
20254 ++ __vxh_copy_vxi(entry, vxi); \
20255 ++ entry->ll.arg = arg
20256 ++
20257 ++static inline
20258 ++void __vxh_long(struct vx_info *vxi, long arg,
20259 ++ int __type, void *__here)
20260 ++{
20261 ++ __VXH_BODY(__type, __VXH_LONG, __here)
20262 ++}
20263 ++
20264 ++
20265 ++static inline
20266 ++void __vxh_throw_oops(void *__here)
20267 ++{
20268 ++ __VXH_BODY(VXH_THROW_OOPS, {}, __here);
20269 ++ /* prevent further acquisition */
20270 ++ vxh_active = 0;
20271 ++}
20272 ++
20273 ++
20274 ++#define vxh_throw_oops() __vxh_throw_oops(__HERE__);
20275 ++
20276 ++#define __vxh_get_vx_info(v, h) __vxh_smpl(v, VXH_GET_VX_INFO, h);
20277 ++#define __vxh_put_vx_info(v, h) __vxh_smpl(v, VXH_PUT_VX_INFO, h);
20278 ++
20279 ++#define __vxh_init_vx_info(v, d, h) \
20280 ++ __vxh_data(v, d, VXH_INIT_VX_INFO, h);
20281 ++#define __vxh_set_vx_info(v, d, h) \
20282 ++ __vxh_data(v, d, VXH_SET_VX_INFO, h);
20283 ++#define __vxh_clr_vx_info(v, d, h) \
20284 ++ __vxh_data(v, d, VXH_CLR_VX_INFO, h);
20285 ++
20286 ++#define __vxh_claim_vx_info(v, d, h) \
20287 ++ __vxh_data(v, d, VXH_CLAIM_VX_INFO, h);
20288 ++#define __vxh_release_vx_info(v, d, h) \
20289 ++ __vxh_data(v, d, VXH_RELEASE_VX_INFO, h);
20290 ++
20291 ++#define vxh_alloc_vx_info(v) \
20292 ++ __vxh_smpl(v, VXH_ALLOC_VX_INFO, __HERE__);
20293 ++#define vxh_dealloc_vx_info(v) \
20294 ++ __vxh_smpl(v, VXH_DEALLOC_VX_INFO, __HERE__);
20295 ++
20296 ++#define vxh_hash_vx_info(v) \
20297 ++ __vxh_smpl(v, VXH_HASH_VX_INFO, __HERE__);
20298 ++#define vxh_unhash_vx_info(v) \
20299 ++ __vxh_smpl(v, VXH_UNHASH_VX_INFO, __HERE__);
20300 ++
20301 ++#define vxh_loc_vx_info(v, l) \
20302 ++ __vxh_long(v, l, VXH_LOC_VX_INFO, __HERE__);
20303 ++#define vxh_lookup_vx_info(v, l) \
20304 ++ __vxh_long(v, l, VXH_LOOKUP_VX_INFO, __HERE__);
20305 ++#define vxh_create_vx_info(v, l) \
20306 ++ __vxh_long(v, l, VXH_CREATE_VX_INFO, __HERE__);
20307 ++
20308 ++extern void vxh_dump_history(void);
20309 ++
20310 ++
20311 ++#else /* CONFIG_VSERVER_HISTORY */
20312 ++
20313 ++#define __HERE__ 0
20314 ++
20315 ++#define vxh_throw_oops() do { } while (0)
20316 ++
20317 ++#define __vxh_get_vx_info(v, h) do { } while (0)
20318 ++#define __vxh_put_vx_info(v, h) do { } while (0)
20319 ++
20320 ++#define __vxh_init_vx_info(v, d, h) do { } while (0)
20321 ++#define __vxh_set_vx_info(v, d, h) do { } while (0)
20322 ++#define __vxh_clr_vx_info(v, d, h) do { } while (0)
20323 ++
20324 ++#define __vxh_claim_vx_info(v, d, h) do { } while (0)
20325 ++#define __vxh_release_vx_info(v, d, h) do { } while (0)
20326 ++
20327 ++#define vxh_alloc_vx_info(v) do { } while (0)
20328 ++#define vxh_dealloc_vx_info(v) do { } while (0)
20329 ++
20330 ++#define vxh_hash_vx_info(v) do { } while (0)
20331 ++#define vxh_unhash_vx_info(v) do { } while (0)
20332 ++
20333 ++#define vxh_loc_vx_info(v, l) do { } while (0)
20334 ++#define vxh_lookup_vx_info(v, l) do { } while (0)
20335 ++#define vxh_create_vx_info(v, l) do { } while (0)
20336 ++
20337 ++#define vxh_dump_history() do { } while (0)
20338 ++
20339 ++
20340 ++#endif /* CONFIG_VSERVER_HISTORY */
20341 ++
20342 ++#endif /* _VX_HISTORY_H */
20343 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/inode.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/inode.h
20344 +--- linux-2.6.22.19/include/linux/vserver/inode.h 1970-01-01 01:00:00 +0100
20345 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/inode.h 2007-08-05 20:53:13 +0200
20346 +@@ -0,0 +1,38 @@
20347 ++#ifndef _VX_INODE_H
20348 ++#define _VX_INODE_H
20349 ++
20350 ++
20351 ++#define IATTR_TAG 0x01000000
20352 ++
20353 ++#define IATTR_ADMIN 0x00000001
20354 ++#define IATTR_WATCH 0x00000002
20355 ++#define IATTR_HIDE 0x00000004
20356 ++#define IATTR_FLAGS 0x00000007
20357 ++
20358 ++#define IATTR_BARRIER 0x00010000
20359 ++#define IATTR_IUNLINK 0x00020000
20360 ++#define IATTR_IMMUTABLE 0x00040000
20361 ++
20362 ++#ifdef __KERNEL__
20363 ++
20364 ++
20365 ++#ifdef CONFIG_VSERVER_PROC_SECURE
20366 ++#define IATTR_PROC_DEFAULT ( IATTR_ADMIN | IATTR_HIDE )
20367 ++#define IATTR_PROC_SYMLINK ( IATTR_ADMIN )
20368 ++#else
20369 ++#define IATTR_PROC_DEFAULT ( IATTR_ADMIN )
20370 ++#define IATTR_PROC_SYMLINK ( IATTR_ADMIN )
20371 ++#endif
20372 ++
20373 ++#define vx_hide_check(c, m) (((m) & IATTR_HIDE) ? vx_check(c, m) : 1)
20374 ++
20375 ++#endif /* __KERNEL__ */
20376 ++
20377 ++/* inode ioctls */
20378 ++
20379 ++#define FIOC_GETXFLG _IOR('x', 5, long)
20380 ++#define FIOC_SETXFLG _IOW('x', 6, long)
20381 ++
20382 ++#else /* _VX_INODE_H */
20383 ++#warning duplicate inclusion
20384 ++#endif /* _VX_INODE_H */
20385 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/inode_cmd.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/inode_cmd.h
20386 +--- linux-2.6.22.19/include/linux/vserver/inode_cmd.h 1970-01-01 01:00:00 +0100
20387 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/inode_cmd.h 2007-08-15 18:08:31 +0200
20388 +@@ -0,0 +1,59 @@
20389 ++#ifndef _VX_INODE_CMD_H
20390 ++#define _VX_INODE_CMD_H
20391 ++
20392 ++
20393 ++/* inode vserver commands */
20394 ++
20395 ++#define VCMD_get_iattr VC_CMD(INODE, 1, 1)
20396 ++#define VCMD_set_iattr VC_CMD(INODE, 2, 1)
20397 ++
20398 ++#define VCMD_fget_iattr VC_CMD(INODE, 3, 0)
20399 ++#define VCMD_fset_iattr VC_CMD(INODE, 4, 0)
20400 ++
20401 ++struct vcmd_ctx_iattr_v1 {
20402 ++ const char __user *name;
20403 ++ uint32_t tag;
20404 ++ uint32_t flags;
20405 ++ uint32_t mask;
20406 ++};
20407 ++
20408 ++struct vcmd_ctx_fiattr_v0 {
20409 ++ uint32_t tag;
20410 ++ uint32_t flags;
20411 ++ uint32_t mask;
20412 ++};
20413 ++
20414 ++
20415 ++#ifdef __KERNEL__
20416 ++
20417 ++
20418 ++#ifdef CONFIG_COMPAT
20419 ++
20420 ++#include <asm/compat.h>
20421 ++
20422 ++struct vcmd_ctx_iattr_v1_x32 {
20423 ++ compat_uptr_t name_ptr;
20424 ++ uint32_t tag;
20425 ++ uint32_t flags;
20426 ++ uint32_t mask;
20427 ++};
20428 ++
20429 ++#endif /* CONFIG_COMPAT */
20430 ++
20431 ++#include <linux/compiler.h>
20432 ++
20433 ++extern int vc_get_iattr(void __user *);
20434 ++extern int vc_set_iattr(void __user *);
20435 ++
20436 ++extern int vc_fget_iattr(uint32_t, void __user *);
20437 ++extern int vc_fset_iattr(uint32_t, void __user *);
20438 ++
20439 ++#ifdef CONFIG_COMPAT
20440 ++
20441 ++extern int vc_get_iattr_x32(void __user *);
20442 ++extern int vc_set_iattr_x32(void __user *);
20443 ++
20444 ++#endif /* CONFIG_COMPAT */
20445 ++
20446 ++#endif /* __KERNEL__ */
20447 ++#endif /* _VX_INODE_CMD_H */
20448 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/limit.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/limit.h
20449 +--- linux-2.6.22.19/include/linux/vserver/limit.h 1970-01-01 01:00:00 +0100
20450 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/limit.h 2007-08-15 22:27:29 +0200
20451 +@@ -0,0 +1,70 @@
20452 ++#ifndef _VX_LIMIT_H
20453 ++#define _VX_LIMIT_H
20454 ++
20455 ++#define VLIMIT_NSOCK 16
20456 ++#define VLIMIT_OPENFD 17
20457 ++#define VLIMIT_ANON 18
20458 ++#define VLIMIT_SHMEM 19
20459 ++#define VLIMIT_SEMARY 20
20460 ++#define VLIMIT_NSEMS 21
20461 ++#define VLIMIT_DENTRY 22
20462 ++#define VLIMIT_MAPPED 23
20463 ++
20464 ++
20465 ++#ifdef __KERNEL__
20466 ++
20467 ++#define VLIM_NOCHECK ((1L << VLIMIT_DENTRY) | (1L << RLIMIT_RSS))
20468 ++
20469 ++/* keep in sync with CRLIM_INFINITY */
20470 ++
20471 ++#define VLIM_INFINITY (~0ULL)
20472 ++
20473 ++#include <asm/atomic.h>
20474 ++#include <asm/resource.h>
20475 ++
20476 ++#ifndef RLIM_INFINITY
20477 ++#warning RLIM_INFINITY is undefined
20478 ++#endif
20479 ++
20480 ++#define __rlim_val(l, r, v) ((l)->res[r].v)
20481 ++
20482 ++#define __rlim_soft(l, r) __rlim_val(l, r, soft)
20483 ++#define __rlim_hard(l, r) __rlim_val(l, r, hard)
20484 ++
20485 ++#define __rlim_rcur(l, r) __rlim_val(l, r, rcur)
20486 ++#define __rlim_rmin(l, r) __rlim_val(l, r, rmin)
20487 ++#define __rlim_rmax(l, r) __rlim_val(l, r, rmax)
20488 ++
20489 ++#define __rlim_lhit(l, r) __rlim_val(l, r, lhit)
20490 ++#define __rlim_hit(l, r) atomic_inc(&__rlim_lhit(l, r))
20491 ++
20492 ++typedef atomic_long_t rlim_atomic_t;
20493 ++typedef unsigned long rlim_t;
20494 ++
20495 ++#define __rlim_get(l, r) atomic_long_read(&__rlim_rcur(l, r))
20496 ++#define __rlim_set(l, r, v) atomic_long_set(&__rlim_rcur(l, r), v)
20497 ++#define __rlim_inc(l, r) atomic_long_inc(&__rlim_rcur(l, r))
20498 ++#define __rlim_dec(l, r) atomic_long_dec(&__rlim_rcur(l, r))
20499 ++#define __rlim_add(l, r, v) atomic_long_add(v, &__rlim_rcur(l, r))
20500 ++#define __rlim_sub(l, r, v) atomic_long_sub(v, &__rlim_rcur(l, r))
20501 ++
20502 ++
20503 ++#if (RLIM_INFINITY == VLIM_INFINITY)
20504 ++#define VX_VLIM(r) ((long long)(long)(r))
20505 ++#define VX_RLIM(v) ((rlim_t)(v))
20506 ++#else
20507 ++#define VX_VLIM(r) (((r) == RLIM_INFINITY) \
20508 ++ ? VLIM_INFINITY : (long long)(r))
20509 ++#define VX_RLIM(v) (((v) == VLIM_INFINITY) \
20510 ++ ? RLIM_INFINITY : (rlim_t)(v))
20511 ++#endif
20512 ++
20513 ++struct sysinfo;
20514 ++
20515 ++void vx_vsi_meminfo(struct sysinfo *);
20516 ++void vx_vsi_swapinfo(struct sysinfo *);
20517 ++
20518 ++#define NUM_LIMITS 24
20519 ++
20520 ++#endif /* __KERNEL__ */
20521 ++#endif /* _VX_LIMIT_H */
20522 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/limit_cmd.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/limit_cmd.h
20523 +--- linux-2.6.22.19/include/linux/vserver/limit_cmd.h 1970-01-01 01:00:00 +0100
20524 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/limit_cmd.h 2007-08-05 20:53:13 +0200
20525 +@@ -0,0 +1,69 @@
20526 ++#ifndef _VX_LIMIT_CMD_H
20527 ++#define _VX_LIMIT_CMD_H
20528 ++
20529 ++
20530 ++/* rlimit vserver commands */
20531 ++
20532 ++#define VCMD_get_rlimit VC_CMD(RLIMIT, 1, 0)
20533 ++#define VCMD_set_rlimit VC_CMD(RLIMIT, 2, 0)
20534 ++#define VCMD_get_rlimit_mask VC_CMD(RLIMIT, 3, 0)
20535 ++#define VCMD_reset_minmax VC_CMD(RLIMIT, 9, 0)
20536 ++
20537 ++struct vcmd_ctx_rlimit_v0 {
20538 ++ uint32_t id;
20539 ++ uint64_t minimum;
20540 ++ uint64_t softlimit;
20541 ++ uint64_t maximum;
20542 ++};
20543 ++
20544 ++struct vcmd_ctx_rlimit_mask_v0 {
20545 ++ uint32_t minimum;
20546 ++ uint32_t softlimit;
20547 ++ uint32_t maximum;
20548 ++};
20549 ++
20550 ++#define VCMD_rlimit_stat VC_CMD(VSTAT, 1, 0)
20551 ++
20552 ++struct vcmd_rlimit_stat_v0 {
20553 ++ uint32_t id;
20554 ++ uint32_t hits;
20555 ++ uint64_t value;
20556 ++ uint64_t minimum;
20557 ++ uint64_t maximum;
20558 ++};
20559 ++
20560 ++#define CRLIM_UNSET (0ULL)
20561 ++#define CRLIM_INFINITY (~0ULL)
20562 ++#define CRLIM_KEEP (~1ULL)
20563 ++
20564 ++#ifdef __KERNEL__
20565 ++
20566 ++#ifdef CONFIG_IA32_EMULATION
20567 ++
20568 ++struct vcmd_ctx_rlimit_v0_x32 {
20569 ++ uint32_t id;
20570 ++ uint64_t minimum;
20571 ++ uint64_t softlimit;
20572 ++ uint64_t maximum;
20573 ++} __attribute__ ((aligned (4)));
20574 ++
20575 ++#endif /* CONFIG_IA32_EMULATION */
20576 ++
20577 ++#include <linux/compiler.h>
20578 ++
20579 ++extern int vc_get_rlimit_mask(uint32_t, void __user *);
20580 ++extern int vc_get_rlimit(struct vx_info *, void __user *);
20581 ++extern int vc_set_rlimit(struct vx_info *, void __user *);
20582 ++extern int vc_reset_minmax(struct vx_info *, void __user *);
20583 ++
20584 ++extern int vc_rlimit_stat(struct vx_info *, void __user *);
20585 ++
20586 ++#ifdef CONFIG_IA32_EMULATION
20587 ++
20588 ++extern int vc_get_rlimit_x32(struct vx_info *, void __user *);
20589 ++extern int vc_set_rlimit_x32(struct vx_info *, void __user *);
20590 ++
20591 ++#endif /* CONFIG_IA32_EMULATION */
20592 ++
20593 ++#endif /* __KERNEL__ */
20594 ++#endif /* _VX_LIMIT_CMD_H */
20595 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/limit_def.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/limit_def.h
20596 +--- linux-2.6.22.19/include/linux/vserver/limit_def.h 1970-01-01 01:00:00 +0100
20597 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/limit_def.h 2007-08-05 20:53:13 +0200
20598 +@@ -0,0 +1,47 @@
20599 ++#ifndef _VX_LIMIT_DEF_H
20600 ++#define _VX_LIMIT_DEF_H
20601 ++
20602 ++#include <asm/atomic.h>
20603 ++#include <asm/resource.h>
20604 ++
20605 ++#include "limit.h"
20606 ++
20607 ++
20608 ++struct _vx_res_limit {
20609 ++ rlim_t soft; /* Context soft limit */
20610 ++ rlim_t hard; /* Context hard limit */
20611 ++
20612 ++ rlim_atomic_t rcur; /* Current value */
20613 ++ rlim_t rmin; /* Context minimum */
20614 ++ rlim_t rmax; /* Context maximum */
20615 ++
20616 ++ atomic_t lhit; /* Limit hits */
20617 ++};
20618 ++
20619 ++/* context sub struct */
20620 ++
20621 ++struct _vx_limit {
20622 ++ struct _vx_res_limit res[NUM_LIMITS];
20623 ++};
20624 ++
20625 ++#ifdef CONFIG_VSERVER_DEBUG
20626 ++
20627 ++static inline void __dump_vx_limit(struct _vx_limit *limit)
20628 ++{
20629 ++ int i;
20630 ++
20631 ++ printk("\t_vx_limit:");
20632 ++ for (i = 0; i < NUM_LIMITS; i++) {
20633 ++ printk("\t [%2d] = %8lu %8lu/%8lu, %8ld/%8ld, %8d\n",
20634 ++ i, (unsigned long)__rlim_get(limit, i),
20635 ++ (unsigned long)__rlim_rmin(limit, i),
20636 ++ (unsigned long)__rlim_rmax(limit, i),
20637 ++ (long)__rlim_soft(limit, i),
20638 ++ (long)__rlim_hard(limit, i),
20639 ++ atomic_read(&__rlim_lhit(limit, i)));
20640 ++ }
20641 ++}
20642 ++
20643 ++#endif
20644 ++
20645 ++#endif /* _VX_LIMIT_DEF_H */
20646 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/limit_int.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/limit_int.h
20647 +--- linux-2.6.22.19/include/linux/vserver/limit_int.h 1970-01-01 01:00:00 +0100
20648 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/limit_int.h 2007-08-05 20:53:13 +0200
20649 +@@ -0,0 +1,198 @@
20650 ++#ifndef _VX_LIMIT_INT_H
20651 ++#define _VX_LIMIT_INT_H
20652 ++
20653 ++#include "context.h"
20654 ++
20655 ++#ifdef __KERNEL__
20656 ++
20657 ++#define VXD_RCRES_COND(r) VXD_CBIT(cres, r)
20658 ++#define VXD_RLIMIT_COND(r) VXD_CBIT(limit, r)
20659 ++
20660 ++extern const char *vlimit_name[NUM_LIMITS];
20661 ++
20662 ++static inline void __vx_acc_cres(struct vx_info *vxi,
20663 ++ int res, int dir, void *_data, char *_file, int _line)
20664 ++{
20665 ++ if (VXD_RCRES_COND(res))
20666 ++ vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5ld%s (%p)",
20667 ++ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
20668 ++ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
20669 ++ (dir > 0) ? "++" : "--", _data, _file, _line);
20670 ++ if (!vxi)
20671 ++ return;
20672 ++
20673 ++ if (dir > 0)
20674 ++ __rlim_inc(&vxi->limit, res);
20675 ++ else
20676 ++ __rlim_dec(&vxi->limit, res);
20677 ++}
20678 ++
20679 ++static inline void __vx_add_cres(struct vx_info *vxi,
20680 ++ int res, int amount, void *_data, char *_file, int _line)
20681 ++{
20682 ++ if (VXD_RCRES_COND(res))
20683 ++ vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5ld += %5d (%p)",
20684 ++ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
20685 ++ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
20686 ++ amount, _data, _file, _line);
20687 ++ if (amount == 0)
20688 ++ return;
20689 ++ if (!vxi)
20690 ++ return;
20691 ++ __rlim_add(&vxi->limit, res, amount);
20692 ++}
20693 ++
20694 ++static inline
20695 ++int __vx_cres_adjust_max(struct _vx_limit *limit, int res, rlim_t value)
20696 ++{
20697 ++ int cond = (value > __rlim_rmax(limit, res));
20698 ++
20699 ++ if (cond)
20700 ++ __rlim_rmax(limit, res) = value;
20701 ++ return cond;
20702 ++}
20703 ++
20704 ++static inline
20705 ++int __vx_cres_adjust_min(struct _vx_limit *limit, int res, rlim_t value)
20706 ++{
20707 ++ int cond = (value < __rlim_rmin(limit, res));
20708 ++
20709 ++ if (cond)
20710 ++ __rlim_rmin(limit, res) = value;
20711 ++ return cond;
20712 ++}
20713 ++
20714 ++static inline
20715 ++void __vx_cres_fixup(struct _vx_limit *limit, int res, rlim_t value)
20716 ++{
20717 ++ if (!__vx_cres_adjust_max(limit, res, value))
20718 ++ __vx_cres_adjust_min(limit, res, value);
20719 ++}
20720 ++
20721 ++
20722 ++/* return values:
20723 ++ +1 ... no limit hit
20724 ++ -1 ... over soft limit
20725 ++ 0 ... over hard limit */
20726 ++
20727 ++static inline int __vx_cres_avail(struct vx_info *vxi,
20728 ++ int res, int num, char *_file, int _line)
20729 ++{
20730 ++ struct _vx_limit *limit;
20731 ++ rlim_t value;
20732 ++
20733 ++ if (VXD_RLIMIT_COND(res))
20734 ++ vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld/%5ld > %5ld + %5d",
20735 ++ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
20736 ++ (vxi ? (long)__rlim_soft(&vxi->limit, res) : -1),
20737 ++ (vxi ? (long)__rlim_hard(&vxi->limit, res) : -1),
20738 ++ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
20739 ++ num, _file, _line);
20740 ++ if (!vxi)
20741 ++ return 1;
20742 ++
20743 ++ limit = &vxi->limit;
20744 ++ value = __rlim_get(limit, res);
20745 ++
20746 ++ if (!__vx_cres_adjust_max(limit, res, value))
20747 ++ __vx_cres_adjust_min(limit, res, value);
20748 ++
20749 ++ if (num == 0)
20750 ++ return 1;
20751 ++
20752 ++ if (__rlim_soft(limit, res) == RLIM_INFINITY)
20753 ++ return -1;
20754 ++ if (value + num <= __rlim_soft(limit, res))
20755 ++ return -1;
20756 ++
20757 ++ if (__rlim_hard(limit, res) == RLIM_INFINITY)
20758 ++ return 1;
20759 ++ if (value + num <= __rlim_hard(limit, res))
20760 ++ return 1;
20761 ++
20762 ++ __rlim_hit(limit, res);
20763 ++ return 0;
20764 ++}
20765 ++
20766 ++
20767 ++static const int VLA_RSS[] = { RLIMIT_RSS, VLIMIT_ANON, VLIMIT_MAPPED, 0 };
20768 ++
20769 ++static inline
20770 ++rlim_t __vx_cres_array_sum(struct _vx_limit *limit, const int *array)
20771 ++{
20772 ++ rlim_t value, sum = 0;
20773 ++ int res;
20774 ++
20775 ++ while ((res = *array++)) {
20776 ++ value = __rlim_get(limit, res);
20777 ++ __vx_cres_fixup(limit, res, value);
20778 ++ sum += value;
20779 ++ }
20780 ++ return sum;
20781 ++}
20782 ++
20783 ++static inline
20784 ++rlim_t __vx_cres_array_fixup(struct _vx_limit *limit, const int *array)
20785 ++{
20786 ++ rlim_t value = __vx_cres_array_sum(limit, array + 1);
20787 ++ int res = *array;
20788 ++
20789 ++ if (value == __rlim_get(limit, res))
20790 ++ return value;
20791 ++
20792 ++ __rlim_set(limit, res, value);
20793 ++ /* now adjust min/max */
20794 ++ if (!__vx_cres_adjust_max(limit, res, value))
20795 ++ __vx_cres_adjust_min(limit, res, value);
20796 ++
20797 ++ return value;
20798 ++}
20799 ++
20800 ++static inline int __vx_cres_array_avail(struct vx_info *vxi,
20801 ++ const int *array, int num, char *_file, int _line)
20802 ++{
20803 ++ struct _vx_limit *limit;
20804 ++ rlim_t value = 0;
20805 ++ int res;
20806 ++
20807 ++ if (num == 0)
20808 ++ return 1;
20809 ++ if (!vxi)
20810 ++ return 1;
20811 ++
20812 ++ limit = &vxi->limit;
20813 ++ res = *array;
20814 ++ value = __vx_cres_array_sum(limit, array + 1);
20815 ++
20816 ++ __rlim_set(limit, res, value);
20817 ++ __vx_cres_fixup(limit, res, value);
20818 ++
20819 ++ return __vx_cres_avail(vxi, res, num, _file, _line);
20820 ++}
20821 ++
20822 ++
20823 ++static inline void vx_limit_fixup(struct _vx_limit *limit, int id)
20824 ++{
20825 ++ rlim_t value;
20826 ++ int res;
20827 ++
20828 ++ /* complex resources first */
20829 ++ if ((id < 0) || (id == RLIMIT_RSS))
20830 ++ __vx_cres_array_fixup(limit, VLA_RSS);
20831 ++
20832 ++ for (res = 0; res < NUM_LIMITS; res++) {
20833 ++ if ((id > 0) && (res != id))
20834 ++ continue;
20835 ++
20836 ++ value = __rlim_get(limit, res);
20837 ++ __vx_cres_fixup(limit, res, value);
20838 ++
20839 ++ /* not supposed to happen, maybe warn? */
20840 ++ if (__rlim_rmax(limit, res) > __rlim_hard(limit, res))
20841 ++ __rlim_rmax(limit, res) = __rlim_hard(limit, res);
20842 ++ }
20843 ++}
20844 ++
20845 ++
20846 ++#endif /* __KERNEL__ */
20847 ++#endif /* _VX_LIMIT_INT_H */
20848 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/monitor.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/monitor.h
20849 +--- linux-2.6.22.19/include/linux/vserver/monitor.h 1970-01-01 01:00:00 +0100
20850 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/monitor.h 2007-08-15 23:16:12 +0200
20851 +@@ -0,0 +1,96 @@
20852 ++#ifndef _VX_MONITOR_H
20853 ++#define _VX_MONITOR_H
20854 ++
20855 ++#include <linux/types.h>
20856 ++
20857 ++enum {
20858 ++ VXM_UNUSED = 0,
20859 ++
20860 ++ VXM_SYNC = 0x10,
20861 ++
20862 ++ VXM_UPDATE = 0x20,
20863 ++ VXM_UPDATE_1,
20864 ++ VXM_UPDATE_2,
20865 ++
20866 ++ VXM_RQINFO_1 = 0x24,
20867 ++ VXM_RQINFO_2,
20868 ++
20869 ++ VXM_ACTIVATE = 0x40,
20870 ++ VXM_DEACTIVATE,
20871 ++ VXM_IDLE,
20872 ++
20873 ++ VXM_HOLD = 0x44,
20874 ++ VXM_UNHOLD,
20875 ++
20876 ++ VXM_MIGRATE = 0x48,
20877 ++ VXM_RESCHED,
20878 ++
20879 ++ /* all other bits are flags */
20880 ++ VXM_SCHED = 0x80,
20881 ++};
20882 ++
20883 ++struct _vxm_update_1 {
20884 ++ uint32_t tokens_max;
20885 ++ uint32_t fill_rate;
20886 ++ uint32_t interval;
20887 ++};
20888 ++
20889 ++struct _vxm_update_2 {
20890 ++ uint32_t tokens_min;
20891 ++ uint32_t fill_rate;
20892 ++ uint32_t interval;
20893 ++};
20894 ++
20895 ++struct _vxm_rqinfo_1 {
20896 ++ uint16_t running;
20897 ++ uint16_t onhold;
20898 ++ uint16_t iowait;
20899 ++ uint16_t uintr;
20900 ++ uint32_t idle_tokens;
20901 ++};
20902 ++
20903 ++struct _vxm_rqinfo_2 {
20904 ++ uint32_t norm_time;
20905 ++ uint32_t idle_time;
20906 ++ uint32_t idle_skip;
20907 ++};
20908 ++
20909 ++struct _vxm_sched {
20910 ++ uint32_t tokens;
20911 ++ uint32_t norm_time;
20912 ++ uint32_t idle_time;
20913 ++};
20914 ++
20915 ++struct _vxm_task {
20916 ++ uint16_t pid;
20917 ++ uint16_t state;
20918 ++};
20919 ++
20920 ++struct _vxm_event {
20921 ++ uint32_t jif;
20922 ++ union {
20923 ++ uint32_t seq;
20924 ++ uint32_t sec;
20925 ++ };
20926 ++ union {
20927 ++ uint32_t tokens;
20928 ++ uint32_t nsec;
20929 ++ struct _vxm_task tsk;
20930 ++ };
20931 ++};
20932 ++
20933 ++struct _vx_mon_entry {
20934 ++ uint16_t type;
20935 ++ uint16_t xid;
20936 ++ union {
20937 ++ struct _vxm_event ev;
20938 ++ struct _vxm_sched sd;
20939 ++ struct _vxm_update_1 u1;
20940 ++ struct _vxm_update_2 u2;
20941 ++ struct _vxm_rqinfo_1 q1;
20942 ++ struct _vxm_rqinfo_2 q2;
20943 ++ };
20944 ++};
20945 ++
20946 ++
20947 ++#endif /* _VX_MONITOR_H */
20948 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/network.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/network.h
20949 +--- linux-2.6.22.19/include/linux/vserver/network.h 1970-01-01 01:00:00 +0100
20950 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/network.h 2008-03-17 00:08:25 +0100
20951 +@@ -0,0 +1,146 @@
20952 ++#ifndef _VX_NETWORK_H
20953 ++#define _VX_NETWORK_H
20954 ++
20955 ++#include <linux/types.h>
20956 ++
20957 ++
20958 ++#define MAX_N_CONTEXT 65535 /* Arbitrary limit */
20959 ++
20960 ++
20961 ++/* network flags */
20962 ++
20963 ++#define NXF_INFO_PRIVATE 0x00000008
20964 ++
20965 ++#define NXF_SINGLE_IP 0x00000100
20966 ++#define NXF_LBACK_REMAP 0x00000200
20967 ++#define NXF_LBACK_ALLOW 0x00000400
20968 ++
20969 ++#define NXF_HIDE_NETIF 0x02000000
20970 ++#define NXF_HIDE_LBACK 0x04000000
20971 ++
20972 ++#define NXF_STATE_SETUP (1ULL << 32)
20973 ++#define NXF_STATE_ADMIN (1ULL << 34)
20974 ++
20975 ++#define NXF_SC_HELPER (1ULL << 36)
20976 ++#define NXF_PERSISTENT (1ULL << 38)
20977 ++
20978 ++#define NXF_ONE_TIME (0x0005ULL << 32)
20979 ++
20980 ++
20981 ++#define NXF_INIT_SET (__nxf_init_set())
20982 ++
20983 ++static inline uint64_t __nxf_init_set(void) {
20984 ++ return NXF_STATE_ADMIN
20985 ++#ifdef CONFIG_VSERVER_AUTO_LBACK
20986 ++ | NXF_LBACK_REMAP
20987 ++ | NXF_HIDE_LBACK
20988 ++#endif
20989 ++#ifdef CONFIG_VSERVER_AUTO_SINGLE
20990 ++ | NXF_SINGLE_IP
20991 ++#endif
20992 ++ | NXF_HIDE_NETIF;
20993 ++}
20994 ++
20995 ++
20996 ++/* network caps */
20997 ++
20998 ++#define NXC_TUN_CREATE 0x00000001
20999 ++
21000 ++#define NXC_RAW_ICMP 0x00000100
21001 ++
21002 ++
21003 ++/* address types */
21004 ++
21005 ++#define NXA_TYPE_IPV4 0x0001
21006 ++#define NXA_TYPE_IPV6 0x0002
21007 ++
21008 ++#define NXA_TYPE_NONE 0x0000
21009 ++#define NXA_TYPE_ANY 0x00FF
21010 ++
21011 ++#define NXA_TYPE_ADDR 0x0010
21012 ++#define NXA_TYPE_MASK 0x0020
21013 ++#define NXA_TYPE_RANGE 0x0040
21014 ++
21015 ++#define NXA_MASK_ALL (NXA_TYPE_ADDR | NXA_TYPE_MASK | NXA_TYPE_RANGE)
21016 ++
21017 ++#define NXA_MOD_BCAST 0x0100
21018 ++#define NXA_MOD_LBACK 0x0200
21019 ++
21020 ++#define NXA_LOOPBACK 0x1000
21021 ++
21022 ++#define NXA_MASK_BIND (NXA_MASK_ALL | NXA_MOD_BCAST | NXA_MOD_LBACK)
21023 ++#define NXA_MASK_SHOW (NXA_MASK_ALL | NXA_LOOPBACK)
21024 ++
21025 ++#ifdef __KERNEL__
21026 ++
21027 ++#include <linux/list.h>
21028 ++#include <linux/spinlock.h>
21029 ++#include <linux/rcupdate.h>
21030 ++#include <linux/in.h>
21031 ++#include <linux/in6.h>
21032 ++#include <asm/atomic.h>
21033 ++
21034 ++struct nx_addr_v4 {
21035 ++ struct nx_addr_v4 *next;
21036 ++ struct in_addr ip[2];
21037 ++ struct in_addr mask;
21038 ++ uint16_t type;
21039 ++ uint16_t flags;
21040 ++};
21041 ++
21042 ++struct nx_addr_v6 {
21043 ++ struct nx_addr_v6 *next;
21044 ++ struct in6_addr ip;
21045 ++ struct in6_addr mask;
21046 ++ uint32_t prefix;
21047 ++ uint16_t type;
21048 ++ uint16_t flags;
21049 ++};
21050 ++
21051 ++struct nx_info {
21052 ++ struct hlist_node nx_hlist; /* linked list of nxinfos */
21053 ++ nid_t nx_id; /* vnet id */
21054 ++ atomic_t nx_usecnt; /* usage count */
21055 ++ atomic_t nx_tasks; /* tasks count */
21056 ++ int nx_state; /* context state */
21057 ++
21058 ++ uint64_t nx_flags; /* network flag word */
21059 ++ uint64_t nx_ncaps; /* network capabilities */
21060 ++
21061 ++ struct in_addr v4_lback; /* Loopback address */
21062 ++ struct in_addr v4_bcast; /* Broadcast address */
21063 ++ struct nx_addr_v4 v4; /* First/Single ipv4 address */
21064 ++#ifdef CONFIG_IPV6
21065 ++ struct nx_addr_v6 v6; /* First/Single ipv6 address */
21066 ++#endif
21067 ++ char nx_name[65]; /* network context name */
21068 ++};
21069 ++
21070 ++
21071 ++/* status flags */
21072 ++
21073 ++#define NXS_HASHED 0x0001
21074 ++#define NXS_SHUTDOWN 0x0100
21075 ++#define NXS_RELEASED 0x8000
21076 ++
21077 ++extern struct nx_info *lookup_nx_info(int);
21078 ++
21079 ++extern int get_nid_list(int, unsigned int *, int);
21080 ++extern int nid_is_hashed(nid_t);
21081 ++
21082 ++extern int nx_migrate_task(struct task_struct *, struct nx_info *);
21083 ++
21084 ++extern long vs_net_change(struct nx_info *, unsigned int);
21085 ++
21086 ++struct sock;
21087 ++
21088 ++
21089 ++#define NX_IPV4(n) ((n)->v4.type != NXA_TYPE_NONE)
21090 ++#ifdef CONFIG_IPV6
21091 ++#define NX_IPV6(n) ((n)->v6.type != NXA_TYPE_NONE)
21092 ++#else
21093 ++#define NX_IPV6(n) (0)
21094 ++#endif
21095 ++
21096 ++#endif /* __KERNEL__ */
21097 ++#endif /* _VX_NETWORK_H */
21098 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/network_cmd.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/network_cmd.h
21099 +--- linux-2.6.22.19/include/linux/vserver/network_cmd.h 1970-01-01 01:00:00 +0100
21100 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/network_cmd.h 2007-08-15 20:08:10 +0200
21101 +@@ -0,0 +1,150 @@
21102 ++#ifndef _VX_NETWORK_CMD_H
21103 ++#define _VX_NETWORK_CMD_H
21104 ++
21105 ++
21106 ++/* vinfo commands */
21107 ++
21108 ++#define VCMD_task_nid VC_CMD(VINFO, 2, 0)
21109 ++
21110 ++#ifdef __KERNEL__
21111 ++extern int vc_task_nid(uint32_t);
21112 ++
21113 ++#endif /* __KERNEL__ */
21114 ++
21115 ++#define VCMD_nx_info VC_CMD(VINFO, 6, 0)
21116 ++
21117 ++struct vcmd_nx_info_v0 {
21118 ++ uint32_t nid;
21119 ++ /* more to come */
21120 ++};
21121 ++
21122 ++#ifdef __KERNEL__
21123 ++extern int vc_nx_info(struct nx_info *, void __user *);
21124 ++
21125 ++#endif /* __KERNEL__ */
21126 ++
21127 ++#include <linux/in.h>
21128 ++#include <linux/in6.h>
21129 ++
21130 ++#define VCMD_net_create_v0 VC_CMD(VNET, 1, 0)
21131 ++#define VCMD_net_create VC_CMD(VNET, 1, 1)
21132 ++
21133 ++struct vcmd_net_create {
21134 ++ uint64_t flagword;
21135 ++};
21136 ++
21137 ++#define VCMD_net_migrate VC_CMD(NETMIG, 1, 0)
21138 ++
21139 ++#define VCMD_net_add VC_CMD(NETALT, 1, 0)
21140 ++#define VCMD_net_remove VC_CMD(NETALT, 2, 0)
21141 ++
21142 ++struct vcmd_net_addr_v0 {
21143 ++ uint16_t type;
21144 ++ uint16_t count;
21145 ++ struct in_addr ip[4];
21146 ++ struct in_addr mask[4];
21147 ++};
21148 ++
21149 ++#define VCMD_net_add_ipv4 VC_CMD(NETALT, 1, 1)
21150 ++#define VCMD_net_remove_ipv4 VC_CMD(NETALT, 2, 1)
21151 ++
21152 ++struct vcmd_net_addr_ipv4_v1 {
21153 ++ uint16_t type;
21154 ++ uint16_t flags;
21155 ++ struct in_addr ip;
21156 ++ struct in_addr mask;
21157 ++};
21158 ++
21159 ++#define VCMD_net_add_ipv6 VC_CMD(NETALT, 3, 1)
21160 ++#define VCMD_net_remove_ipv6 VC_CMD(NETALT, 4, 1)
21161 ++
21162 ++struct vcmd_net_addr_ipv6_v1 {
21163 ++ uint16_t type;
21164 ++ uint16_t flags;
21165 ++ uint32_t prefix;
21166 ++ struct in6_addr ip;
21167 ++ struct in6_addr mask;
21168 ++};
21169 ++
21170 ++#define VCMD_add_match_ipv4 VC_CMD(NETALT, 5, 0)
21171 ++#define VCMD_get_match_ipv4 VC_CMD(NETALT, 6, 0)
21172 ++
21173 ++struct vcmd_match_ipv4_v0 {
21174 ++ uint16_t type;
21175 ++ uint16_t flags;
21176 ++ uint16_t parent;
21177 ++ uint16_t prefix;
21178 ++ struct in_addr ip;
21179 ++ struct in_addr ip2;
21180 ++ struct in_addr mask;
21181 ++};
21182 ++
21183 ++#define VCMD_add_match_ipv6 VC_CMD(NETALT, 7, 0)
21184 ++#define VCMD_get_match_ipv6 VC_CMD(NETALT, 8, 0)
21185 ++
21186 ++struct vcmd_match_ipv6_v0 {
21187 ++ uint16_t type;
21188 ++ uint16_t flags;
21189 ++ uint16_t parent;
21190 ++ uint16_t prefix;
21191 ++ struct in6_addr ip;
21192 ++ struct in6_addr ip2;
21193 ++ struct in6_addr mask;
21194 ++};
21195 ++
21196 ++
21197 ++#ifdef __KERNEL__
21198 ++extern int vc_net_create(uint32_t, void __user *);
21199 ++extern int vc_net_migrate(struct nx_info *, void __user *);
21200 ++
21201 ++extern int vc_net_add(struct nx_info *, void __user *);
21202 ++extern int vc_net_remove(struct nx_info *, void __user *);
21203 ++
21204 ++extern int vc_net_add_ipv4(struct nx_info *, void __user *);
21205 ++extern int vc_net_remove_ipv4(struct nx_info *, void __user *);
21206 ++
21207 ++extern int vc_net_add_ipv6(struct nx_info *, void __user *);
21208 ++extern int vc_net_remove_ipv6(struct nx_info *, void __user *);
21209 ++
21210 ++extern int vc_add_match_ipv4(struct nx_info *, void __user *);
21211 ++extern int vc_get_match_ipv4(struct nx_info *, void __user *);
21212 ++
21213 ++extern int vc_add_match_ipv6(struct nx_info *, void __user *);
21214 ++extern int vc_get_match_ipv6(struct nx_info *, void __user *);
21215 ++
21216 ++#endif /* __KERNEL__ */
21217 ++
21218 ++
21219 ++/* flag commands */
21220 ++
21221 ++#define VCMD_get_nflags VC_CMD(FLAGS, 5, 0)
21222 ++#define VCMD_set_nflags VC_CMD(FLAGS, 6, 0)
21223 ++
21224 ++struct vcmd_net_flags_v0 {
21225 ++ uint64_t flagword;
21226 ++ uint64_t mask;
21227 ++};
21228 ++
21229 ++#ifdef __KERNEL__
21230 ++extern int vc_get_nflags(struct nx_info *, void __user *);
21231 ++extern int vc_set_nflags(struct nx_info *, void __user *);
21232 ++
21233 ++#endif /* __KERNEL__ */
21234 ++
21235 ++
21236 ++/* network caps commands */
21237 ++
21238 ++#define VCMD_get_ncaps VC_CMD(FLAGS, 7, 0)
21239 ++#define VCMD_set_ncaps VC_CMD(FLAGS, 8, 0)
21240 ++
21241 ++struct vcmd_net_caps_v0 {
21242 ++ uint64_t ncaps;
21243 ++ uint64_t cmask;
21244 ++};
21245 ++
21246 ++#ifdef __KERNEL__
21247 ++extern int vc_get_ncaps(struct nx_info *, void __user *);
21248 ++extern int vc_set_ncaps(struct nx_info *, void __user *);
21249 ++
21250 ++#endif /* __KERNEL__ */
21251 ++#endif /* _VX_CONTEXT_CMD_H */
21252 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/percpu.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/percpu.h
21253 +--- linux-2.6.22.19/include/linux/vserver/percpu.h 1970-01-01 01:00:00 +0100
21254 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/percpu.h 2007-08-05 20:53:13 +0200
21255 +@@ -0,0 +1,14 @@
21256 ++#ifndef _VX_PERCPU_H
21257 ++#define _VX_PERCPU_H
21258 ++
21259 ++#include "cvirt_def.h"
21260 ++#include "sched_def.h"
21261 ++
21262 ++struct _vx_percpu {
21263 ++ struct _vx_cvirt_pc cvirt;
21264 ++ struct _vx_sched_pc sched;
21265 ++};
21266 ++
21267 ++#define PERCPU_PERCTX (sizeof(struct _vx_percpu))
21268 ++
21269 ++#endif /* _VX_PERCPU_H */
21270 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/sched.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/sched.h
21271 +--- linux-2.6.22.19/include/linux/vserver/sched.h 1970-01-01 01:00:00 +0100
21272 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/sched.h 2007-08-05 20:53:13 +0200
21273 +@@ -0,0 +1,26 @@
21274 ++#ifndef _VX_SCHED_H
21275 ++#define _VX_SCHED_H
21276 ++
21277 ++
21278 ++#ifdef __KERNEL__
21279 ++
21280 ++struct timespec;
21281 ++
21282 ++void vx_vsi_uptime(struct timespec *, struct timespec *);
21283 ++
21284 ++
21285 ++struct vx_info;
21286 ++
21287 ++void vx_update_load(struct vx_info *);
21288 ++
21289 ++
21290 ++int vx_tokens_recalc(struct _vx_sched_pc *,
21291 ++ unsigned long *, unsigned long *, int [2]);
21292 ++
21293 ++void vx_update_sched_param(struct _vx_sched *sched,
21294 ++ struct _vx_sched_pc *sched_pc);
21295 ++
21296 ++#endif /* __KERNEL__ */
21297 ++#else /* _VX_SCHED_H */
21298 ++#warning duplicate inclusion
21299 ++#endif /* _VX_SCHED_H */
21300 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/sched_cmd.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/sched_cmd.h
21301 +--- linux-2.6.22.19/include/linux/vserver/sched_cmd.h 1970-01-01 01:00:00 +0100
21302 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/sched_cmd.h 2007-08-05 20:53:13 +0200
21303 +@@ -0,0 +1,108 @@
21304 ++#ifndef _VX_SCHED_CMD_H
21305 ++#define _VX_SCHED_CMD_H
21306 ++
21307 ++
21308 ++/* sched vserver commands */
21309 ++
21310 ++#define VCMD_set_sched_v2 VC_CMD(SCHED, 1, 2)
21311 ++#define VCMD_set_sched_v3 VC_CMD(SCHED, 1, 3)
21312 ++#define VCMD_set_sched_v4 VC_CMD(SCHED, 1, 4)
21313 ++
21314 ++struct vcmd_set_sched_v2 {
21315 ++ int32_t fill_rate;
21316 ++ int32_t interval;
21317 ++ int32_t tokens;
21318 ++ int32_t tokens_min;
21319 ++ int32_t tokens_max;
21320 ++ uint64_t cpu_mask;
21321 ++};
21322 ++
21323 ++struct vcmd_set_sched_v3 {
21324 ++ uint32_t set_mask;
21325 ++ int32_t fill_rate;
21326 ++ int32_t interval;
21327 ++ int32_t tokens;
21328 ++ int32_t tokens_min;
21329 ++ int32_t tokens_max;
21330 ++ int32_t priority_bias;
21331 ++};
21332 ++
21333 ++struct vcmd_set_sched_v4 {
21334 ++ uint32_t set_mask;
21335 ++ int32_t fill_rate;
21336 ++ int32_t interval;
21337 ++ int32_t tokens;
21338 ++ int32_t tokens_min;
21339 ++ int32_t tokens_max;
21340 ++ int32_t prio_bias;
21341 ++ int32_t cpu_id;
21342 ++ int32_t bucket_id;
21343 ++};
21344 ++
21345 ++#define VCMD_set_sched VC_CMD(SCHED, 1, 5)
21346 ++#define VCMD_get_sched VC_CMD(SCHED, 2, 5)
21347 ++
21348 ++struct vcmd_sched_v5 {
21349 ++ uint32_t mask;
21350 ++ int32_t cpu_id;
21351 ++ int32_t bucket_id;
21352 ++ int32_t fill_rate[2];
21353 ++ int32_t interval[2];
21354 ++ int32_t tokens;
21355 ++ int32_t tokens_min;
21356 ++ int32_t tokens_max;
21357 ++ int32_t prio_bias;
21358 ++};
21359 ++
21360 ++#define VXSM_FILL_RATE 0x0001
21361 ++#define VXSM_INTERVAL 0x0002
21362 ++#define VXSM_FILL_RATE2 0x0004
21363 ++#define VXSM_INTERVAL2 0x0008
21364 ++#define VXSM_TOKENS 0x0010
21365 ++#define VXSM_TOKENS_MIN 0x0020
21366 ++#define VXSM_TOKENS_MAX 0x0040
21367 ++#define VXSM_PRIO_BIAS 0x0100
21368 ++
21369 ++#define VXSM_IDLE_TIME 0x0200
21370 ++#define VXSM_FORCE 0x0400
21371 ++
21372 ++#define VXSM_V3_MASK 0x0173
21373 ++#define VXSM_SET_MASK 0x01FF
21374 ++
21375 ++#define VXSM_CPU_ID 0x1000
21376 ++#define VXSM_BUCKET_ID 0x2000
21377 ++
21378 ++#define VXSM_MSEC 0x4000
21379 ++
21380 ++#define SCHED_KEEP (-2) /* only for v2 */
21381 ++
21382 ++#ifdef __KERNEL__
21383 ++
21384 ++#include <linux/compiler.h>
21385 ++
21386 ++extern int vc_set_sched_v2(struct vx_info *, void __user *);
21387 ++extern int vc_set_sched_v3(struct vx_info *, void __user *);
21388 ++extern int vc_set_sched_v4(struct vx_info *, void __user *);
21389 ++extern int vc_set_sched(struct vx_info *, void __user *);
21390 ++extern int vc_get_sched(struct vx_info *, void __user *);
21391 ++
21392 ++#endif /* __KERNEL__ */
21393 ++
21394 ++#define VCMD_sched_info VC_CMD(SCHED, 3, 0)
21395 ++
21396 ++struct vcmd_sched_info {
21397 ++ int32_t cpu_id;
21398 ++ int32_t bucket_id;
21399 ++ uint64_t user_msec;
21400 ++ uint64_t sys_msec;
21401 ++ uint64_t hold_msec;
21402 ++ uint32_t token_usec;
21403 ++ int32_t vavavoom;
21404 ++};
21405 ++
21406 ++#ifdef __KERNEL__
21407 ++
21408 ++extern int vc_sched_info(struct vx_info *, void __user *);
21409 ++
21410 ++#endif /* __KERNEL__ */
21411 ++#endif /* _VX_SCHED_CMD_H */
21412 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/sched_def.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/sched_def.h
21413 +--- linux-2.6.22.19/include/linux/vserver/sched_def.h 1970-01-01 01:00:00 +0100
21414 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/sched_def.h 2007-08-05 20:53:13 +0200
21415 +@@ -0,0 +1,68 @@
21416 ++#ifndef _VX_SCHED_DEF_H
21417 ++#define _VX_SCHED_DEF_H
21418 ++
21419 ++#include <linux/spinlock.h>
21420 ++#include <linux/jiffies.h>
21421 ++#include <linux/cpumask.h>
21422 ++#include <asm/atomic.h>
21423 ++#include <asm/param.h>
21424 ++
21425 ++
21426 ++/* context sub struct */
21427 ++
21428 ++struct _vx_sched {
21429 ++ spinlock_t tokens_lock; /* lock for token bucket */
21430 ++
21431 ++ int tokens; /* number of CPU tokens */
21432 ++ int fill_rate[2]; /* Fill rate: add X tokens... */
21433 ++ int interval[2]; /* Divisor: per Y jiffies */
21434 ++ int tokens_min; /* Limit: minimum for unhold */
21435 ++ int tokens_max; /* Limit: no more than N tokens */
21436 ++
21437 ++ int prio_bias; /* bias offset for priority */
21438 ++
21439 ++ unsigned update_mask; /* which features should be updated */
21440 ++ cpumask_t update; /* CPUs which should update */
21441 ++};
21442 ++
21443 ++struct _vx_sched_pc {
21444 ++ int tokens; /* number of CPU tokens */
21445 ++ int flags; /* bucket flags */
21446 ++
21447 ++ int fill_rate[2]; /* Fill rate: add X tokens... */
21448 ++ int interval[2]; /* Divisor: per Y jiffies */
21449 ++ int tokens_min; /* Limit: minimum for unhold */
21450 ++ int tokens_max; /* Limit: no more than N tokens */
21451 ++
21452 ++ int prio_bias; /* bias offset for priority */
21453 ++ int vavavoom; /* last calculated vavavoom */
21454 ++
21455 ++ unsigned long norm_time; /* last time accounted */
21456 ++ unsigned long idle_time; /* non linear time for fair sched */
21457 ++ unsigned long token_time; /* token time for accounting */
21458 ++ unsigned long onhold; /* jiffies when put on hold */
21459 ++
21460 ++ uint64_t user_ticks; /* token tick events */
21461 ++ uint64_t sys_ticks; /* token tick events */
21462 ++ uint64_t hold_ticks; /* token ticks paused */
21463 ++};
21464 ++
21465 ++
21466 ++#define VXSF_ONHOLD 0x0001
21467 ++#define VXSF_IDLE_TIME 0x0100
21468 ++
21469 ++#ifdef CONFIG_VSERVER_DEBUG
21470 ++
21471 ++static inline void __dump_vx_sched(struct _vx_sched *sched)
21472 ++{
21473 ++ printk("\t_vx_sched:\n");
21474 ++ printk("\t tokens: %4d/%4d, %4d/%4d, %4d, %4d\n",
21475 ++ sched->fill_rate[0], sched->interval[0],
21476 ++ sched->fill_rate[1], sched->interval[1],
21477 ++ sched->tokens_min, sched->tokens_max);
21478 ++ printk("\t priority = %4d\n", sched->prio_bias);
21479 ++}
21480 ++
21481 ++#endif
21482 ++
21483 ++#endif /* _VX_SCHED_DEF_H */
21484 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/signal.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/signal.h
21485 +--- linux-2.6.22.19/include/linux/vserver/signal.h 1970-01-01 01:00:00 +0100
21486 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/signal.h 2007-08-05 20:53:13 +0200
21487 +@@ -0,0 +1,14 @@
21488 ++#ifndef _VX_SIGNAL_H
21489 ++#define _VX_SIGNAL_H
21490 ++
21491 ++
21492 ++#ifdef __KERNEL__
21493 ++
21494 ++struct vx_info;
21495 ++
21496 ++int vx_info_kill(struct vx_info *, int, int);
21497 ++
21498 ++#endif /* __KERNEL__ */
21499 ++#else /* _VX_SIGNAL_H */
21500 ++#warning duplicate inclusion
21501 ++#endif /* _VX_SIGNAL_H */
21502 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/signal_cmd.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/signal_cmd.h
21503 +--- linux-2.6.22.19/include/linux/vserver/signal_cmd.h 1970-01-01 01:00:00 +0100
21504 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/signal_cmd.h 2007-08-05 20:53:13 +0200
21505 +@@ -0,0 +1,43 @@
21506 ++#ifndef _VX_SIGNAL_CMD_H
21507 ++#define _VX_SIGNAL_CMD_H
21508 ++
21509 ++
21510 ++/* signalling vserver commands */
21511 ++
21512 ++#define VCMD_ctx_kill VC_CMD(PROCTRL, 1, 0)
21513 ++#define VCMD_wait_exit VC_CMD(EVENT, 99, 0)
21514 ++
21515 ++struct vcmd_ctx_kill_v0 {
21516 ++ int32_t pid;
21517 ++ int32_t sig;
21518 ++};
21519 ++
21520 ++struct vcmd_wait_exit_v0 {
21521 ++ int32_t reboot_cmd;
21522 ++ int32_t exit_code;
21523 ++};
21524 ++
21525 ++#ifdef __KERNEL__
21526 ++
21527 ++extern int vc_ctx_kill(struct vx_info *, void __user *);
21528 ++extern int vc_wait_exit(struct vx_info *, void __user *);
21529 ++
21530 ++#endif /* __KERNEL__ */
21531 ++
21532 ++/* process alteration commands */
21533 ++
21534 ++#define VCMD_get_pflags VC_CMD(PROCALT, 5, 0)
21535 ++#define VCMD_set_pflags VC_CMD(PROCALT, 6, 0)
21536 ++
21537 ++struct vcmd_pflags_v0 {
21538 ++ uint32_t flagword;
21539 ++ uint32_t mask;
21540 ++};
21541 ++
21542 ++#ifdef __KERNEL__
21543 ++
21544 ++extern int vc_get_pflags(uint32_t pid, void __user *);
21545 ++extern int vc_set_pflags(uint32_t pid, void __user *);
21546 ++
21547 ++#endif /* __KERNEL__ */
21548 ++#endif /* _VX_SIGNAL_CMD_H */
21549 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/space.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/space.h
21550 +--- linux-2.6.22.19/include/linux/vserver/space.h 1970-01-01 01:00:00 +0100
21551 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/space.h 2007-08-05 20:53:13 +0200
21552 +@@ -0,0 +1,13 @@
21553 ++#ifndef _VX_SPACE_H
21554 ++#define _VX_SPACE_H
21555 ++
21556 ++
21557 ++#include <linux/types.h>
21558 ++
21559 ++struct vx_info;
21560 ++
21561 ++int vx_set_space(struct vx_info *vxi, unsigned long mask);
21562 ++
21563 ++#else /* _VX_SPACE_H */
21564 ++#warning duplicate inclusion
21565 ++#endif /* _VX_SPACE_H */
21566 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/space_cmd.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/space_cmd.h
21567 +--- linux-2.6.22.19/include/linux/vserver/space_cmd.h 1970-01-01 01:00:00 +0100
21568 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/space_cmd.h 2007-08-05 20:53:13 +0200
21569 +@@ -0,0 +1,26 @@
21570 ++#ifndef _VX_SPACE_CMD_H
21571 ++#define _VX_SPACE_CMD_H
21572 ++
21573 ++
21574 ++#define VCMD_enter_space_v0 VC_CMD(PROCALT, 1, 0)
21575 ++#define VCMD_enter_space VC_CMD(PROCALT, 1, 1)
21576 ++
21577 ++#define VCMD_set_space_v0 VC_CMD(PROCALT, 3, 0)
21578 ++#define VCMD_set_space VC_CMD(PROCALT, 3, 1)
21579 ++
21580 ++#define VCMD_get_space_mask VC_CMD(PROCALT, 4, 0)
21581 ++
21582 ++
21583 ++struct vcmd_space_mask {
21584 ++ uint64_t mask;
21585 ++};
21586 ++
21587 ++
21588 ++#ifdef __KERNEL__
21589 ++
21590 ++extern int vc_enter_space(struct vx_info *, void __user *);
21591 ++extern int vc_set_space(struct vx_info *, void __user *);
21592 ++extern int vc_get_space_mask(struct vx_info *, void __user *);
21593 ++
21594 ++#endif /* __KERNEL__ */
21595 ++#endif /* _VX_SPACE_CMD_H */
21596 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/switch.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/switch.h
21597 +--- linux-2.6.22.19/include/linux/vserver/switch.h 1970-01-01 01:00:00 +0100
21598 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/switch.h 2007-10-11 01:10:22 +0200
21599 +@@ -0,0 +1,99 @@
21600 ++#ifndef _VX_SWITCH_H
21601 ++#define _VX_SWITCH_H
21602 ++
21603 ++#include <linux/types.h>
21604 ++
21605 ++
21606 ++#define VC_CATEGORY(c) (((c) >> 24) & 0x3F)
21607 ++#define VC_COMMAND(c) (((c) >> 16) & 0xFF)
21608 ++#define VC_VERSION(c) ((c) & 0xFFF)
21609 ++
21610 ++#define VC_CMD(c, i, v) ((((VC_CAT_ ## c) & 0x3F) << 24) \
21611 ++ | (((i) & 0xFF) << 16) | ((v) & 0xFFF))
21612 ++
21613 ++/*
21614 ++
21615 ++ Syscall Matrix V2.8
21616 ++
21617 ++ |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|
21618 ++ |STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | |
21619 ++ |INFO |SETUP | |MOVE | | | | | |
21620 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
21621 ++ SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICE | |
21622 ++ HOST | 00| 01| 02| 03| 04| 05| | 06| 07|
21623 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
21624 ++ CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | |
21625 ++ PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15|
21626 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
21627 ++ MEMORY | | | | |MEMCTRL| | |SWAP | |
21628 ++ | 16| 17| 18| 19| 20| 21| | 22| 23|
21629 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
21630 ++ NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | |
21631 ++ | 24| 25| 26| 27| 28| 29| | 30| 31|
21632 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
21633 ++ DISK | | | |TAGMIG |DLIMIT | | |INODE | |
21634 ++ VFS | 32| 33| 34| 35| 36| 37| | 38| 39|
21635 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
21636 ++ OTHER |VSTAT | | | | | | |VINFO | |
21637 ++ | 40| 41| 42| 43| 44| 45| | 46| 47|
21638 ++ =======+=======+=======+=======+=======+=======+=======+ +=======+=======+
21639 ++ SPECIAL|EVENT | | | |FLAGS | | | | |
21640 ++ | 48| 49| 50| 51| 52| 53| | 54| 55|
21641 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
21642 ++ SPECIAL|DEBUG | | | |RLIMIT |SYSCALL| | |COMPAT |
21643 ++ | 56| 57| 58| 59| 60|TEST 61| | 62| 63|
21644 ++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
21645 ++
21646 ++*/
21647 ++
21648 ++#define VC_CAT_VERSION 0
21649 ++
21650 ++#define VC_CAT_VSETUP 1
21651 ++#define VC_CAT_VHOST 2
21652 ++
21653 ++#define VC_CAT_DEVICE 6
21654 ++
21655 ++#define VC_CAT_VPROC 9
21656 ++#define VC_CAT_PROCALT 10
21657 ++#define VC_CAT_PROCMIG 11
21658 ++#define VC_CAT_PROCTRL 12
21659 ++
21660 ++#define VC_CAT_SCHED 14
21661 ++#define VC_CAT_MEMCTRL 20
21662 ++
21663 ++#define VC_CAT_VNET 25
21664 ++#define VC_CAT_NETALT 26
21665 ++#define VC_CAT_NETMIG 27
21666 ++#define VC_CAT_NETCTRL 28
21667 ++
21668 ++#define VC_CAT_TAGMIG 35
21669 ++#define VC_CAT_DLIMIT 36
21670 ++#define VC_CAT_INODE 38
21671 ++
21672 ++#define VC_CAT_VSTAT 40
21673 ++#define VC_CAT_VINFO 46
21674 ++#define VC_CAT_EVENT 48
21675 ++
21676 ++#define VC_CAT_FLAGS 52
21677 ++#define VC_CAT_DEBUG 56
21678 ++#define VC_CAT_RLIMIT 60
21679 ++
21680 ++#define VC_CAT_SYSTEST 61
21681 ++#define VC_CAT_COMPAT 63
21682 ++
21683 ++/* query version */
21684 ++
21685 ++#define VCMD_get_version VC_CMD(VERSION, 0, 0)
21686 ++#define VCMD_get_vci VC_CMD(VERSION, 1, 0)
21687 ++
21688 ++
21689 ++#ifdef __KERNEL__
21690 ++
21691 ++#include <linux/errno.h>
21692 ++
21693 ++
21694 ++#else /* __KERNEL__ */
21695 ++#define __user
21696 ++#endif /* __KERNEL__ */
21697 ++
21698 ++#endif /* _VX_SWITCH_H */
21699 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/tag.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/tag.h
21700 +--- linux-2.6.22.19/include/linux/vserver/tag.h 1970-01-01 01:00:00 +0100
21701 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/tag.h 2007-10-10 19:05:04 +0200
21702 +@@ -0,0 +1,143 @@
21703 ++#ifndef _DX_TAG_H
21704 ++#define _DX_TAG_H
21705 ++
21706 ++#include <linux/types.h>
21707 ++
21708 ++
21709 ++#define DX_TAG(in) (IS_TAGGED(in))
21710 ++
21711 ++
21712 ++#ifdef CONFIG_DX_TAG_NFSD
21713 ++#define DX_TAG_NFSD 1
21714 ++#else
21715 ++#define DX_TAG_NFSD 0
21716 ++#endif
21717 ++
21718 ++
21719 ++#ifdef CONFIG_TAGGING_NONE
21720 ++
21721 ++#define MAX_UID 0xFFFFFFFF
21722 ++#define MAX_GID 0xFFFFFFFF
21723 ++
21724 ++#define INOTAG_TAG(cond, uid, gid, tag) (0)
21725 ++
21726 ++#define TAGINO_UID(cond, uid, tag) (uid)
21727 ++#define TAGINO_GID(cond, gid, tag) (gid)
21728 ++
21729 ++#endif
21730 ++
21731 ++
21732 ++#ifdef CONFIG_TAGGING_GID16
21733 ++
21734 ++#define MAX_UID 0xFFFFFFFF
21735 ++#define MAX_GID 0x0000FFFF
21736 ++
21737 ++#define INOTAG_TAG(cond, uid, gid, tag) \
21738 ++ ((cond) ? (((gid) >> 16) & 0xFFFF) : 0)
21739 ++
21740 ++#define TAGINO_UID(cond, uid, tag) (uid)
21741 ++#define TAGINO_GID(cond, gid, tag) \
21742 ++ ((cond) ? (((gid) & 0xFFFF) | ((tag) << 16)) : (gid))
21743 ++
21744 ++#endif
21745 ++
21746 ++
21747 ++#ifdef CONFIG_TAGGING_ID24
21748 ++
21749 ++#define MAX_UID 0x00FFFFFF
21750 ++#define MAX_GID 0x00FFFFFF
21751 ++
21752 ++#define INOTAG_TAG(cond, uid, gid, tag) \
21753 ++ ((cond) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0)
21754 ++
21755 ++#define TAGINO_UID(cond, uid, tag) \
21756 ++ ((cond) ? (((uid) & 0xFFFFFF) | (((tag) & 0xFF00) << 16)) : (uid))
21757 ++#define TAGINO_GID(cond, gid, tag) \
21758 ++ ((cond) ? (((gid) & 0xFFFFFF) | (((tag) & 0x00FF) << 24)) : (gid))
21759 ++
21760 ++#endif
21761 ++
21762 ++
21763 ++#ifdef CONFIG_TAGGING_UID16
21764 ++
21765 ++#define MAX_UID 0x0000FFFF
21766 ++#define MAX_GID 0xFFFFFFFF
21767 ++
21768 ++#define INOTAG_TAG(cond, uid, gid, tag) \
21769 ++ ((cond) ? (((uid) >> 16) & 0xFFFF) : 0)
21770 ++
21771 ++#define TAGINO_UID(cond, uid, tag) \
21772 ++ ((cond) ? (((uid) & 0xFFFF) | ((tag) << 16)) : (uid))
21773 ++#define TAGINO_GID(cond, gid, tag) (gid)
21774 ++
21775 ++#endif
21776 ++
21777 ++
21778 ++#ifdef CONFIG_TAGGING_INTERN
21779 ++
21780 ++#define MAX_UID 0xFFFFFFFF
21781 ++#define MAX_GID 0xFFFFFFFF
21782 ++
21783 ++#define INOTAG_TAG(cond, uid, gid, tag) \
21784 ++ ((cond) ? (tag) : 0)
21785 ++
21786 ++#define TAGINO_UID(cond, uid, tag) (uid)
21787 ++#define TAGINO_GID(cond, gid, tag) (gid)
21788 ++
21789 ++#endif
21790 ++
21791 ++
21792 ++#ifndef CONFIG_TAGGING_NONE
21793 ++#define dx_current_fstag(sb) \
21794 ++ ((sb)->s_flags & MS_TAGGED ? dx_current_tag() : 0)
21795 ++#else
21796 ++#define dx_current_fstag(sb) (0)
21797 ++#endif
21798 ++
21799 ++#ifndef CONFIG_TAGGING_INTERN
21800 ++#define TAGINO_TAG(cond, tag) (0)
21801 ++#else
21802 ++#define TAGINO_TAG(cond, tag) ((cond) ? (tag) : 0)
21803 ++#endif
21804 ++
21805 ++#define INOTAG_UID(cond, uid, gid) \
21806 ++ ((cond) ? ((uid) & MAX_UID) : (uid))
21807 ++#define INOTAG_GID(cond, uid, gid) \
21808 ++ ((cond) ? ((gid) & MAX_GID) : (gid))
21809 ++
21810 ++
21811 ++static inline uid_t dx_map_uid(uid_t uid)
21812 ++{
21813 ++ if ((uid > MAX_UID) && (uid != -1))
21814 ++ uid = -2;
21815 ++ return (uid & MAX_UID);
21816 ++}
21817 ++
21818 ++static inline gid_t dx_map_gid(gid_t gid)
21819 ++{
21820 ++ if ((gid > MAX_GID) && (gid != -1))
21821 ++ gid = -2;
21822 ++ return (gid & MAX_GID);
21823 ++}
21824 ++
21825 ++struct peer_tag {
21826 ++ int32_t xid;
21827 ++ int32_t nid;
21828 ++};
21829 ++
21830 ++#define dx_notagcheck(nd) \
21831 ++ ((nd) && (nd)->mnt && ((nd)->mnt->mnt_flags & MNT_NOTAGCHECK))
21832 ++
21833 ++int dx_parse_tag(char *string, tag_t *tag, int remove);
21834 ++
21835 ++#ifdef CONFIG_PROPAGATE
21836 ++
21837 ++void __dx_propagate_tag(struct nameidata *nd, struct inode *inode);
21838 ++
21839 ++#define dx_propagate_tag(n, i) __dx_propagate_tag(n, i)
21840 ++
21841 ++#else
21842 ++#define dx_propagate_tag(n, i) do { } while (0)
21843 ++#endif
21844 ++
21845 ++#endif /* _DX_TAG_H */
21846 +diff -NurpP --minimal linux-2.6.22.19/include/linux/vserver/tag_cmd.h linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/tag_cmd.h
21847 +--- linux-2.6.22.19/include/linux/vserver/tag_cmd.h 1970-01-01 01:00:00 +0100
21848 ++++ linux-2.6.22.19-vs2.3.0.34/include/linux/vserver/tag_cmd.h 2007-08-15 20:16:43 +0200
21849 +@@ -0,0 +1,22 @@
21850 ++#ifndef _VX_TAG_CMD_H
21851 ++#define _VX_TAG_CMD_H
21852 ++
21853 ++
21854 ++/* vinfo commands */
21855 ++
21856 ++#define VCMD_task_tag VC_CMD(VINFO, 3, 0)
21857 ++
21858 ++#ifdef __KERNEL__
21859 ++extern int vc_task_tag(uint32_t);
21860 ++
21861 ++#endif /* __KERNEL__ */
21862 ++
21863 ++/* context commands */
21864 ++
21865 ++#define VCMD_tag_migrate VC_CMD(TAGMIG, 1, 0)
21866 ++
21867 ++#ifdef __KERNEL__
21868 ++extern int vc_tag_migrate(uint32_t);
21869 ++
21870 ++#endif /* __KERNEL__ */
21871 ++#endif /* _VX_TAG_CMD_H */
21872 +diff -NurpP --minimal linux-2.6.22.19/include/net/addrconf.h linux-2.6.22.19-vs2.3.0.34/include/net/addrconf.h
21873 +--- linux-2.6.22.19/include/net/addrconf.h 2007-07-09 13:20:01 +0200
21874 ++++ linux-2.6.22.19-vs2.3.0.34/include/net/addrconf.h 2007-08-12 00:22:19 +0200
21875 +@@ -69,10 +69,12 @@ extern struct inet6_ifaddr * ipv6_get_if
21876 + int strict);
21877 + extern int ipv6_get_saddr(struct dst_entry *dst,
21878 + struct in6_addr *daddr,
21879 +- struct in6_addr *saddr);
21880 ++ struct in6_addr *saddr,
21881 ++ struct nx_info *nxi);
21882 + extern int ipv6_dev_get_saddr(struct net_device *dev,
21883 + struct in6_addr *daddr,
21884 +- struct in6_addr *saddr);
21885 ++ struct in6_addr *saddr,
21886 ++ struct nx_info *nxi);
21887 + extern int ipv6_get_lladdr(struct net_device *dev,
21888 + struct in6_addr *addr,
21889 + unsigned char banned_flags);
21890 +diff -NurpP --minimal linux-2.6.22.19/include/net/af_unix.h linux-2.6.22.19-vs2.3.0.34/include/net/af_unix.h
21891 +--- linux-2.6.22.19/include/net/af_unix.h 2007-07-09 13:20:01 +0200
21892 ++++ linux-2.6.22.19-vs2.3.0.34/include/net/af_unix.h 2007-08-05 20:53:13 +0200
21893 +@@ -4,6 +4,7 @@
21894 + #include <linux/socket.h>
21895 + #include <linux/un.h>
21896 + #include <linux/mutex.h>
21897 ++#include <linux/vs_base.h>
21898 + #include <net/sock.h>
21899 +
21900 + extern void unix_inflight(struct file *fp);
21901 +@@ -17,9 +18,9 @@ extern spinlock_t unix_table_lock;
21902 +
21903 + extern atomic_t unix_tot_inflight;
21904 +
21905 +-static inline struct sock *first_unix_socket(int *i)
21906 ++static inline struct sock *next_unix_socket_table(int *i)
21907 + {
21908 +- for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) {
21909 ++ for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
21910 + if (!hlist_empty(&unix_socket_table[*i]))
21911 + return __sk_head(&unix_socket_table[*i]);
21912 + }
21913 +@@ -28,16 +29,19 @@ static inline struct sock *first_unix_so
21914 +
21915 + static inline struct sock *next_unix_socket(int *i, struct sock *s)
21916 + {
21917 +- struct sock *next = sk_next(s);
21918 +- /* More in this chain? */
21919 +- if (next)
21920 +- return next;
21921 +- /* Look for next non-empty chain. */
21922 +- for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
21923 +- if (!hlist_empty(&unix_socket_table[*i]))
21924 +- return __sk_head(&unix_socket_table[*i]);
21925 +- }
21926 +- return NULL;
21927 ++ do {
21928 ++ if (s)
21929 ++ s = sk_next(s);
21930 ++ if (!s)
21931 ++ s = next_unix_socket_table(i);
21932 ++ } while (s && !nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT));
21933 ++ return s;
21934 ++}
21935 ++
21936 ++static inline struct sock *first_unix_socket(int *i)
21937 ++{
21938 ++ *i = 0;
21939 ++ return next_unix_socket(i, NULL);
21940 + }
21941 +
21942 + #define forall_unix_sockets(i, s) \
21943 +diff -NurpP --minimal linux-2.6.22.19/include/net/inet_timewait_sock.h linux-2.6.22.19-vs2.3.0.34/include/net/inet_timewait_sock.h
21944 +--- linux-2.6.22.19/include/net/inet_timewait_sock.h 2007-05-02 19:25:35 +0200
21945 ++++ linux-2.6.22.19-vs2.3.0.34/include/net/inet_timewait_sock.h 2007-08-05 20:53:13 +0200
21946 +@@ -115,6 +115,10 @@ struct inet_timewait_sock {
21947 + #define tw_refcnt __tw_common.skc_refcnt
21948 + #define tw_hash __tw_common.skc_hash
21949 + #define tw_prot __tw_common.skc_prot
21950 ++#define tw_xid __tw_common.skc_xid
21951 ++#define tw_vx_info __tw_common.skc_vx_info
21952 ++#define tw_nid __tw_common.skc_nid
21953 ++#define tw_nx_info __tw_common.skc_nx_info
21954 + volatile unsigned char tw_substate;
21955 + /* 3 bits hole, try to pack */
21956 + unsigned char tw_rcv_wscale;
21957 +diff -NurpP --minimal linux-2.6.22.19/include/net/route.h linux-2.6.22.19-vs2.3.0.34/include/net/route.h
21958 +--- linux-2.6.22.19/include/net/route.h 2007-05-02 19:25:35 +0200
21959 ++++ linux-2.6.22.19-vs2.3.0.34/include/net/route.h 2007-09-18 03:52:05 +0200
21960 +@@ -27,12 +27,16 @@
21961 + #include <net/dst.h>
21962 + #include <net/inetpeer.h>
21963 + #include <net/flow.h>
21964 ++#include <net/inet_sock.h>
21965 + #include <linux/in_route.h>
21966 + #include <linux/rtnetlink.h>
21967 + #include <linux/route.h>
21968 + #include <linux/ip.h>
21969 + #include <linux/cache.h>
21970 + #include <linux/security.h>
21971 ++#include <linux/vs_base.h>
21972 ++#include <linux/vs_inet.h>
21973 ++#include <linux/in.h>
21974 +
21975 + #ifndef __KERNEL__
21976 + #warning This file is not supposed to be used outside of kernel.
21977 +@@ -143,6 +147,8 @@ static inline char rt_tos2priority(u8 to
21978 + return ip_tos2prio[IPTOS_TOS(tos)>>1];
21979 + }
21980 +
21981 ++extern int ip_v4_find_src(struct nx_info *, struct rtable **, struct flowi *);
21982 ++
21983 + static inline int ip_route_connect(struct rtable **rp, __be32 dst,
21984 + __be32 src, u32 tos, int oif, u8 protocol,
21985 + __be16 sport, __be16 dport, struct sock *sk,
21986 +@@ -158,7 +164,21 @@ static inline int ip_route_connect(struc
21987 + .dport = dport } } };
21988 +
21989 + int err;
21990 +- if (!dst || !src) {
21991 ++ struct nx_info *nx_info = current->nx_info;
21992 ++
21993 ++ if (sk)
21994 ++ nx_info = sk->sk_nx_info;
21995 ++
21996 ++ vxdprintk(VXD_CBIT(net, 4),
21997 ++ "ip_route_connect(%p) %p,%p;%lx",
21998 ++ sk, nx_info, sk->sk_socket,
21999 ++ (sk->sk_socket?sk->sk_socket->flags:0));
22000 ++
22001 ++ err = ip_v4_find_src(nx_info, rp, &fl);
22002 ++ if (err)
22003 ++ return err;
22004 ++
22005 ++ if (!fl.fl4_dst || !fl.fl4_src) {
22006 + err = __ip_route_output_key(rp, &fl);
22007 + if (err)
22008 + return err;
22009 +diff -NurpP --minimal linux-2.6.22.19/include/net/sock.h linux-2.6.22.19-vs2.3.0.34/include/net/sock.h
22010 +--- linux-2.6.22.19/include/net/sock.h 2007-07-09 13:20:02 +0200
22011 ++++ linux-2.6.22.19-vs2.3.0.34/include/net/sock.h 2007-08-05 20:53:13 +0200
22012 +@@ -119,6 +119,10 @@ struct sock_common {
22013 + atomic_t skc_refcnt;
22014 + unsigned int skc_hash;
22015 + struct proto *skc_prot;
22016 ++ xid_t skc_xid;
22017 ++ struct vx_info *skc_vx_info;
22018 ++ nid_t skc_nid;
22019 ++ struct nx_info *skc_nx_info;
22020 + };
22021 +
22022 + /**
22023 +@@ -195,6 +199,10 @@ struct sock {
22024 + #define sk_refcnt __sk_common.skc_refcnt
22025 + #define sk_hash __sk_common.skc_hash
22026 + #define sk_prot __sk_common.skc_prot
22027 ++#define sk_xid __sk_common.skc_xid
22028 ++#define sk_vx_info __sk_common.skc_vx_info
22029 ++#define sk_nid __sk_common.skc_nid
22030 ++#define sk_nx_info __sk_common.skc_nx_info
22031 + unsigned char sk_shutdown : 2,
22032 + sk_no_check : 2,
22033 + sk_userlocks : 4;
22034 +diff -NurpP --minimal linux-2.6.22.19/init/main.c linux-2.6.22.19-vs2.3.0.34/init/main.c
22035 +--- linux-2.6.22.19/init/main.c 2007-07-09 13:20:03 +0200
22036 ++++ linux-2.6.22.19-vs2.3.0.34/init/main.c 2007-11-02 20:59:59 +0100
22037 +@@ -55,6 +55,7 @@
22038 + #include <linux/pid_namespace.h>
22039 + #include <linux/device.h>
22040 + #include <linux/kthread.h>
22041 ++#include <linux/vserver/percpu.h>
22042 +
22043 + #include <asm/io.h>
22044 + #include <asm/bugs.h>
22045 +@@ -364,12 +365,14 @@ EXPORT_SYMBOL(__per_cpu_offset);
22046 +
22047 + static void __init setup_per_cpu_areas(void)
22048 + {
22049 +- unsigned long size, i;
22050 ++ unsigned long size, vspc, i;
22051 + char *ptr;
22052 + unsigned long nr_possible_cpus = num_possible_cpus();
22053 +
22054 ++ vspc = PERCPU_PERCTX * CONFIG_VSERVER_CONTEXTS;
22055 ++
22056 + /* Copy section for each CPU (we discard the original) */
22057 +- size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
22058 ++ size = ALIGN(PERCPU_ENOUGH_ROOM + vspc, PAGE_SIZE);
22059 + ptr = alloc_bootmem_pages(size * nr_possible_cpus);
22060 +
22061 + for_each_possible_cpu(i) {
22062 +diff -NurpP --minimal linux-2.6.22.19/ipc/mqueue.c linux-2.6.22.19-vs2.3.0.34/ipc/mqueue.c
22063 +--- linux-2.6.22.19/ipc/mqueue.c 2008-03-14 20:19:04 +0100
22064 ++++ linux-2.6.22.19-vs2.3.0.34/ipc/mqueue.c 2008-01-18 12:36:58 +0100
22065 +@@ -29,6 +29,8 @@
22066 + #include <linux/audit.h>
22067 + #include <linux/signal.h>
22068 + #include <linux/mutex.h>
22069 ++#include <linux/vs_context.h>
22070 ++#include <linux/vs_limit.h>
22071 +
22072 + #include <net/sock.h>
22073 + #include "util.h"
22074 +@@ -151,17 +153,20 @@ static struct inode *mqueue_get_inode(st
22075 + spin_lock(&mq_lock);
22076 + if (u->mq_bytes + mq_bytes < u->mq_bytes ||
22077 + u->mq_bytes + mq_bytes >
22078 +- p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) {
22079 ++ p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur ||
22080 ++ !vx_ipcmsg_avail(p->vx_info, mq_bytes)) {
22081 + spin_unlock(&mq_lock);
22082 + goto out_inode;
22083 + }
22084 + u->mq_bytes += mq_bytes;
22085 ++ vx_ipcmsg_add(p->vx_info, u, mq_bytes);
22086 + spin_unlock(&mq_lock);
22087 +
22088 + info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL);
22089 + if (!info->messages) {
22090 + spin_lock(&mq_lock);
22091 + u->mq_bytes -= mq_bytes;
22092 ++ vx_ipcmsg_sub(p->vx_info, u, mq_bytes);
22093 + spin_unlock(&mq_lock);
22094 + goto out_inode;
22095 + }
22096 +@@ -257,10 +262,14 @@ static void mqueue_delete_inode(struct i
22097 + (info->attr.mq_maxmsg * info->attr.mq_msgsize));
22098 + user = info->user;
22099 + if (user) {
22100 ++ struct vx_info *vxi = lookup_vx_info(user->xid);
22101 ++
22102 + spin_lock(&mq_lock);
22103 + user->mq_bytes -= mq_bytes;
22104 ++ vx_ipcmsg_sub(vxi, user, mq_bytes);
22105 + queues_count--;
22106 + spin_unlock(&mq_lock);
22107 ++ put_vx_info(vxi);
22108 + free_uid(user);
22109 + }
22110 + }
22111 +@@ -748,7 +757,7 @@ asmlinkage long sys_mq_unlink(const char
22112 + if (inode)
22113 + atomic_inc(&inode->i_count);
22114 +
22115 +- err = vfs_unlink(dentry->d_parent->d_inode, dentry);
22116 ++ err = vfs_unlink(dentry->d_parent->d_inode, dentry, NULL);
22117 + out_err:
22118 + dput(dentry);
22119 +
22120 +diff -NurpP --minimal linux-2.6.22.19/ipc/msg.c linux-2.6.22.19-vs2.3.0.34/ipc/msg.c
22121 +--- linux-2.6.22.19/ipc/msg.c 2007-02-06 03:01:55 +0100
22122 ++++ linux-2.6.22.19-vs2.3.0.34/ipc/msg.c 2007-08-05 20:53:13 +0200
22123 +@@ -36,6 +36,7 @@
22124 + #include <linux/seq_file.h>
22125 + #include <linux/mutex.h>
22126 + #include <linux/nsproxy.h>
22127 ++#include <linux/vs_base.h>
22128 +
22129 + #include <asm/current.h>
22130 + #include <asm/uaccess.h>
22131 +@@ -149,6 +150,7 @@ static int newque (struct ipc_namespace
22132 +
22133 + msq->q_perm.mode = msgflg & S_IRWXUGO;
22134 + msq->q_perm.key = key;
22135 ++ msq->q_perm.xid = vx_current_xid();
22136 +
22137 + msq->q_perm.security = NULL;
22138 + retval = security_msg_queue_alloc(msq);
22139 +diff -NurpP --minimal linux-2.6.22.19/ipc/sem.c linux-2.6.22.19-vs2.3.0.34/ipc/sem.c
22140 +--- linux-2.6.22.19/ipc/sem.c 2007-07-09 13:20:03 +0200
22141 ++++ linux-2.6.22.19-vs2.3.0.34/ipc/sem.c 2007-08-05 20:53:13 +0200
22142 +@@ -82,6 +82,8 @@
22143 + #include <linux/seq_file.h>
22144 + #include <linux/mutex.h>
22145 + #include <linux/nsproxy.h>
22146 ++#include <linux/vs_base.h>
22147 ++#include <linux/vs_limit.h>
22148 +
22149 + #include <asm/uaccess.h>
22150 + #include "util.h"
22151 +@@ -229,6 +231,7 @@ static int newary (struct ipc_namespace
22152 +
22153 + sma->sem_perm.mode = (semflg & S_IRWXUGO);
22154 + sma->sem_perm.key = key;
22155 ++ sma->sem_perm.xid = vx_current_xid();
22156 +
22157 + sma->sem_perm.security = NULL;
22158 + retval = security_sem_alloc(sma);
22159 +@@ -244,6 +247,9 @@ static int newary (struct ipc_namespace
22160 + return -ENOSPC;
22161 + }
22162 + ns->used_sems += nsems;
22163 ++ /* FIXME: obsoleted? */
22164 ++ vx_semary_inc(sma);
22165 ++ vx_nsems_add(sma, nsems);
22166 +
22167 + sma->sem_id = sem_buildid(ns, id, sma->sem_perm.seq);
22168 + sma->sem_base = (struct sem *) &sma[1];
22169 +@@ -525,6 +531,9 @@ static void freeary (struct ipc_namespac
22170 + sem_unlock(sma);
22171 +
22172 + ns->used_sems -= sma->sem_nsems;
22173 ++ /* FIXME: obsoleted? */
22174 ++ vx_nsems_sub(sma, sma->sem_nsems);
22175 ++ vx_semary_dec(sma);
22176 + size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem);
22177 + security_sem_free(sma);
22178 + ipc_rcu_putref(sma);
22179 +diff -NurpP --minimal linux-2.6.22.19/ipc/shm.c linux-2.6.22.19-vs2.3.0.34/ipc/shm.c
22180 +--- linux-2.6.22.19/ipc/shm.c 2008-03-14 20:19:04 +0100
22181 ++++ linux-2.6.22.19-vs2.3.0.34/ipc/shm.c 2007-10-01 14:57:41 +0200
22182 +@@ -38,6 +38,8 @@
22183 + #include <linux/mutex.h>
22184 + #include <linux/nsproxy.h>
22185 + #include <linux/mount.h>
22186 ++#include <linux/vs_context.h>
22187 ++#include <linux/vs_limit.h>
22188 +
22189 + #include <asm/uaccess.h>
22190 +
22191 +@@ -185,7 +187,12 @@ static void shm_open(struct vm_area_stru
22192 + */
22193 + static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
22194 + {
22195 +- ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
22196 ++ struct vx_info *vxi = lookup_vx_info(shp->shm_perm.xid);
22197 ++ int numpages = (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
22198 ++
22199 ++ vx_ipcshm_sub(vxi, shp, numpages);
22200 ++ ns->shm_tot -= numpages;
22201 ++
22202 + shm_rmid(ns, shp->id);
22203 + shm_unlock(shp);
22204 + if (!is_file_hugepages(shp->shm_file))
22205 +@@ -195,6 +202,7 @@ static void shm_destroy(struct ipc_names
22206 + shp->mlock_user);
22207 + fput (shp->shm_file);
22208 + security_shm_free(shp);
22209 ++ put_vx_info(vxi);
22210 + ipc_rcu_putref(shp);
22211 + }
22212 +
22213 +@@ -351,11 +359,15 @@ static int newseg (struct ipc_namespace
22214 + if (ns->shm_tot + numpages > ns->shm_ctlall)
22215 + return -ENOSPC;
22216 +
22217 ++ if (!vx_ipcshm_avail(current->vx_info, numpages))
22218 ++ return -ENOSPC;
22219 ++
22220 + shp = ipc_rcu_alloc(sizeof(*shp));
22221 + if (!shp)
22222 + return -ENOMEM;
22223 +
22224 + shp->shm_perm.key = key;
22225 ++ shp->shm_perm.xid = vx_current_xid();
22226 + shp->shm_perm.mode = (shmflg & S_IRWXUGO);
22227 + shp->mlock_user = NULL;
22228 +
22229 +@@ -406,6 +418,7 @@ static int newseg (struct ipc_namespace
22230 + file->f_dentry->d_inode->i_ino = shp->id;
22231 +
22232 + ns->shm_tot += numpages;
22233 ++ vx_ipcshm_add(current->vx_info, key, numpages);
22234 + shm_unlock(shp);
22235 + return shp->id;
22236 +
22237 +diff -NurpP --minimal linux-2.6.22.19/ipc/util.c linux-2.6.22.19-vs2.3.0.34/ipc/util.c
22238 +--- linux-2.6.22.19/ipc/util.c 2007-07-09 13:20:03 +0200
22239 ++++ linux-2.6.22.19-vs2.3.0.34/ipc/util.c 2007-08-05 20:53:13 +0200
22240 +@@ -32,6 +32,8 @@
22241 + #include <linux/proc_fs.h>
22242 + #include <linux/audit.h>
22243 + #include <linux/nsproxy.h>
22244 ++#include <linux/vs_base.h>
22245 ++#include <linux/vserver/global.h>
22246 +
22247 + #include <asm/unistd.h>
22248 +
22249 +@@ -72,6 +74,7 @@ static struct ipc_namespace *clone_ipc_n
22250 + goto err_shm;
22251 +
22252 + kref_init(&ns->kref);
22253 ++ atomic_inc(&vs_global_ipc_ns);
22254 + return ns;
22255 +
22256 + err_shm:
22257 +@@ -108,6 +111,7 @@ void free_ipc_ns(struct kref *kref)
22258 + sem_exit_ns(ns);
22259 + msg_exit_ns(ns);
22260 + shm_exit_ns(ns);
22261 ++ atomic_dec(&vs_global_ipc_ns);
22262 + kfree(ns);
22263 + }
22264 + #else
22265 +diff -NurpP --minimal linux-2.6.22.19/kernel/Makefile linux-2.6.22.19-vs2.3.0.34/kernel/Makefile
22266 +--- linux-2.6.22.19/kernel/Makefile 2007-07-09 13:20:03 +0200
22267 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/Makefile 2007-08-05 20:53:13 +0200
22268 +@@ -10,6 +10,8 @@ obj-y = sched.o fork.o exec_domain.o
22269 + kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
22270 + hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o
22271 +
22272 ++obj-y += vserver/
22273 ++
22274 + obj-$(CONFIG_STACKTRACE) += stacktrace.o
22275 + obj-y += time/
22276 + obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
22277 +diff -NurpP --minimal linux-2.6.22.19/kernel/capability.c linux-2.6.22.19-vs2.3.0.34/kernel/capability.c
22278 +--- linux-2.6.22.19/kernel/capability.c 2007-05-02 19:25:37 +0200
22279 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/capability.c 2007-08-05 20:53:13 +0200
22280 +@@ -12,6 +12,7 @@
22281 + #include <linux/module.h>
22282 + #include <linux/security.h>
22283 + #include <linux/syscalls.h>
22284 ++#include <linux/vs_context.h>
22285 + #include <asm/uaccess.h>
22286 +
22287 + unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
22288 +@@ -103,6 +104,8 @@ static inline int cap_set_pg(int pgrp_nr
22289 +
22290 + pgrp = find_pid(pgrp_nr);
22291 + do_each_pid_task(pgrp, PIDTYPE_PGID, g) {
22292 ++ if (!vx_check(g->xid, VS_ADMIN_P | VS_IDENT))
22293 ++ continue;
22294 + target = g;
22295 + while_each_thread(g, target) {
22296 + if (!security_capset_check(target, effective,
22297 +@@ -246,8 +249,12 @@ int __capable(struct task_struct *t, int
22298 + }
22299 + EXPORT_SYMBOL(__capable);
22300 +
22301 ++#include <linux/vserver/base.h>
22302 + int capable(int cap)
22303 + {
22304 ++ /* here for now so we don't require task locking */
22305 ++ if (vs_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap))
22306 ++ return 0;
22307 + return __capable(current, cap);
22308 + }
22309 + EXPORT_SYMBOL(capable);
22310 +diff -NurpP --minimal linux-2.6.22.19/kernel/compat.c linux-2.6.22.19-vs2.3.0.34/kernel/compat.c
22311 +--- linux-2.6.22.19/kernel/compat.c 2007-07-09 13:20:03 +0200
22312 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/compat.c 2007-08-05 20:53:13 +0200
22313 +@@ -846,7 +846,7 @@ asmlinkage long compat_sys_time(compat_t
22314 + compat_time_t i;
22315 + struct timeval tv;
22316 +
22317 +- do_gettimeofday(&tv);
22318 ++ vx_gettimeofday(&tv);
22319 + i = tv.tv_sec;
22320 +
22321 + if (tloc) {
22322 +@@ -870,7 +870,7 @@ asmlinkage long compat_sys_stime(compat_
22323 + if (err)
22324 + return err;
22325 +
22326 +- do_settimeofday(&tv);
22327 ++ vx_settimeofday(&tv);
22328 + return 0;
22329 + }
22330 +
22331 +diff -NurpP --minimal linux-2.6.22.19/kernel/exit.c linux-2.6.22.19-vs2.3.0.34/kernel/exit.c
22332 +--- linux-2.6.22.19/kernel/exit.c 2008-03-14 20:19:04 +0100
22333 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/exit.c 2008-01-18 12:36:58 +0100
22334 +@@ -44,6 +44,11 @@
22335 + #include <linux/resource.h>
22336 + #include <linux/blkdev.h>
22337 + #include <linux/task_io_accounting_ops.h>
22338 ++#include <linux/vs_limit.h>
22339 ++#include <linux/vs_context.h>
22340 ++#include <linux/vs_network.h>
22341 ++#include <linux/vs_pid.h>
22342 ++#include <linux/vserver/global.h>
22343 +
22344 + #include <asm/uaccess.h>
22345 + #include <asm/unistd.h>
22346 +@@ -443,9 +448,11 @@ static void close_files(struct files_str
22347 + filp_close(file, files);
22348 + cond_resched();
22349 + }
22350 ++ vx_openfd_dec(i);
22351 + }
22352 + i++;
22353 + set >>= 1;
22354 ++ cond_resched();
22355 + }
22356 + }
22357 + }
22358 +@@ -525,6 +532,7 @@ static inline void __put_fs_struct(struc
22359 + dput(fs->altroot);
22360 + mntput(fs->altrootmnt);
22361 + }
22362 ++ atomic_dec(&vs_global_fs);
22363 + kmem_cache_free(fs_cachep, fs);
22364 + }
22365 + }
22366 +@@ -596,6 +604,14 @@ static void exit_mm(struct task_struct *
22367 + static inline void
22368 + choose_new_parent(struct task_struct *p, struct task_struct *reaper)
22369 + {
22370 ++ /* check for reaper context */
22371 ++ vxwprintk((p->xid != reaper->xid) && (reaper != child_reaper(p)),
22372 ++ "rogue reaper: %p[%d,#%u] <> %p[%d,#%u]",
22373 ++ p, p->pid, p->xid, reaper, reaper->pid, reaper->xid);
22374 ++
22375 ++ if (p == reaper)
22376 ++ reaper = vx_child_reaper(p);
22377 ++
22378 + /*
22379 + * Make sure we're not reparenting to ourselves and that
22380 + * the parent is not a zombie.
22381 +@@ -687,7 +703,7 @@ forget_original_parent(struct task_struc
22382 + do {
22383 + reaper = next_thread(reaper);
22384 + if (reaper == father) {
22385 +- reaper = child_reaper(father);
22386 ++ reaper = vx_child_reaper(father);
22387 + break;
22388 + }
22389 + } while (reaper->exit_state);
22390 +@@ -964,6 +980,8 @@ fastcall NORET_TYPE void do_exit(long co
22391 + tsk->exit_code = code;
22392 + proc_exit_connector(tsk);
22393 + exit_task_namespaces(tsk);
22394 ++ /* needs to stay before exit_notify() */
22395 ++ exit_vx_info_early(tsk, code);
22396 + exit_notify(tsk);
22397 + #ifdef CONFIG_NUMA
22398 + mpol_free(tsk->mempolicy);
22399 +@@ -994,6 +1012,10 @@ fastcall NORET_TYPE void do_exit(long co
22400 + if (tsk->splice_pipe)
22401 + __free_pipe_info(tsk->splice_pipe);
22402 +
22403 ++ /* needs to stay after exit_notify() */
22404 ++ exit_vx_info(tsk, code);
22405 ++ exit_nx_info(tsk);
22406 ++
22407 + preempt_disable();
22408 + /* causes final put_task_struct in finish_task_switch(). */
22409 + tsk->state = TASK_DEAD;
22410 +diff -NurpP --minimal linux-2.6.22.19/kernel/fork.c linux-2.6.22.19-vs2.3.0.34/kernel/fork.c
22411 +--- linux-2.6.22.19/kernel/fork.c 2007-07-09 13:20:03 +0200
22412 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/fork.c 2007-10-25 17:05:55 +0200
22413 +@@ -49,6 +49,11 @@
22414 + #include <linux/delayacct.h>
22415 + #include <linux/taskstats_kern.h>
22416 + #include <linux/random.h>
22417 ++#include <linux/vs_context.h>
22418 ++#include <linux/vs_network.h>
22419 ++#include <linux/vs_limit.h>
22420 ++#include <linux/vs_memory.h>
22421 ++#include <linux/vserver/global.h>
22422 +
22423 + #include <asm/pgtable.h>
22424 + #include <asm/pgalloc.h>
22425 +@@ -108,6 +113,8 @@ void free_task(struct task_struct *tsk)
22426 + {
22427 + free_thread_info(tsk->stack);
22428 + rt_mutex_debug_task_free(tsk);
22429 ++ clr_vx_info(&tsk->vx_info);
22430 ++ clr_nx_info(&tsk->nx_info);
22431 + free_task_struct(tsk);
22432 + }
22433 + EXPORT_SYMBOL(free_task);
22434 +@@ -215,6 +222,8 @@ static inline int dup_mmap(struct mm_str
22435 + mm->free_area_cache = oldmm->mmap_base;
22436 + mm->cached_hole_size = ~0UL;
22437 + mm->map_count = 0;
22438 ++ __set_mm_counter(mm, file_rss, 0);
22439 ++ __set_mm_counter(mm, anon_rss, 0);
22440 + cpus_clear(mm->cpu_vm_mask);
22441 + mm->mm_rb = RB_ROOT;
22442 + rb_link = &mm->mm_rb.rb_node;
22443 +@@ -226,7 +235,7 @@ static inline int dup_mmap(struct mm_str
22444 +
22445 + if (mpnt->vm_flags & VM_DONTCOPY) {
22446 + long pages = vma_pages(mpnt);
22447 +- mm->total_vm -= pages;
22448 ++ vx_vmpages_sub(mm, pages);
22449 + vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
22450 + -pages);
22451 + continue;
22452 +@@ -327,7 +336,7 @@ static inline void mm_free_pgd(struct mm
22453 +
22454 + #include <linux/init_task.h>
22455 +
22456 +-static struct mm_struct * mm_init(struct mm_struct * mm)
22457 ++static struct mm_struct * mm_init(struct mm_struct * mm, struct vx_info *vxi)
22458 + {
22459 + atomic_set(&mm->mm_users, 1);
22460 + atomic_set(&mm->mm_count, 1);
22461 +@@ -335,8 +344,8 @@ static struct mm_struct * mm_init(struct
22462 + INIT_LIST_HEAD(&mm->mmlist);
22463 + mm->core_waiters = 0;
22464 + mm->nr_ptes = 0;
22465 +- set_mm_counter(mm, file_rss, 0);
22466 +- set_mm_counter(mm, anon_rss, 0);
22467 ++ __set_mm_counter(mm, file_rss, 0);
22468 ++ __set_mm_counter(mm, anon_rss, 0);
22469 + spin_lock_init(&mm->page_table_lock);
22470 + rwlock_init(&mm->ioctx_list_lock);
22471 + mm->ioctx_list = NULL;
22472 +@@ -345,6 +354,7 @@ static struct mm_struct * mm_init(struct
22473 +
22474 + if (likely(!mm_alloc_pgd(mm))) {
22475 + mm->def_flags = 0;
22476 ++ set_vx_info(&mm->mm_vx_info, vxi);
22477 + return mm;
22478 + }
22479 + free_mm(mm);
22480 +@@ -361,7 +371,7 @@ struct mm_struct * mm_alloc(void)
22481 + mm = allocate_mm();
22482 + if (mm) {
22483 + memset(mm, 0, sizeof(*mm));
22484 +- mm = mm_init(mm);
22485 ++ mm = mm_init(mm, current->vx_info);
22486 + }
22487 + return mm;
22488 + }
22489 +@@ -376,6 +386,7 @@ void fastcall __mmdrop(struct mm_struct
22490 + BUG_ON(mm == &init_mm);
22491 + mm_free_pgd(mm);
22492 + destroy_context(mm);
22493 ++ clr_vx_info(&mm->mm_vx_info);
22494 + free_mm(mm);
22495 + }
22496 +
22497 +@@ -490,12 +501,13 @@ static struct mm_struct *dup_mm(struct t
22498 + goto fail_nomem;
22499 +
22500 + memcpy(mm, oldmm, sizeof(*mm));
22501 ++ mm->mm_vx_info = NULL;
22502 +
22503 + /* Initializing for Swap token stuff */
22504 + mm->token_priority = 0;
22505 + mm->last_interval = 0;
22506 +
22507 +- if (!mm_init(mm))
22508 ++ if (!mm_init(mm, oldmm->mm_vx_info))
22509 + goto fail_nomem;
22510 +
22511 + if (init_new_context(tsk, mm))
22512 +@@ -521,6 +533,7 @@ fail_nocontext:
22513 + * If init_new_context() failed, we cannot use mmput() to free the mm
22514 + * because it calls destroy_context()
22515 + */
22516 ++ clr_vx_info(&mm->mm_vx_info);
22517 + mm_free_pgd(mm);
22518 + free_mm(mm);
22519 + return NULL;
22520 +@@ -591,6 +604,7 @@ static inline struct fs_struct *__copy_f
22521 + fs->altroot = NULL;
22522 + }
22523 + read_unlock(&old->lock);
22524 ++ atomic_inc(&vs_global_fs);
22525 + }
22526 + return fs;
22527 + }
22528 +@@ -709,6 +723,8 @@ static struct files_struct *dup_fd(struc
22529 + struct file *f = *old_fds++;
22530 + if (f) {
22531 + get_file(f);
22532 ++ /* TODO: sum it first for check and performance */
22533 ++ vx_openfd_inc(open_files - i);
22534 + } else {
22535 + /*
22536 + * The fd may be claimed in the fd bitmap but not yet
22537 +@@ -961,6 +977,8 @@ static struct task_struct *copy_process(
22538 + {
22539 + int retval;
22540 + struct task_struct *p = NULL;
22541 ++ struct vx_info *vxi;
22542 ++ struct nx_info *nxi;
22543 +
22544 + if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
22545 + return ERR_PTR(-EINVAL);
22546 +@@ -995,12 +1013,30 @@ static struct task_struct *copy_process(
22547 + DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
22548 + DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
22549 + #endif
22550 ++ init_vx_info(&p->vx_info, current->vx_info);
22551 ++ init_nx_info(&p->nx_info, current->nx_info);
22552 ++
22553 ++ /* check vserver memory */
22554 ++ if (p->mm && !(clone_flags & CLONE_VM)) {
22555 ++ if (vx_vmpages_avail(p->mm, p->mm->total_vm))
22556 ++ vx_pages_add(p->vx_info, RLIMIT_AS, p->mm->total_vm);
22557 ++ else
22558 ++ goto bad_fork_free;
22559 ++ }
22560 ++ if (p->mm && vx_flags(VXF_FORK_RSS, 0)) {
22561 ++ if (!vx_rss_avail(p->mm, get_mm_counter(p->mm, file_rss)))
22562 ++ goto bad_fork_cleanup_vm;
22563 ++ }
22564 ++
22565 + retval = -EAGAIN;
22566 ++ if (!vx_nproc_avail(1))
22567 ++ goto bad_fork_cleanup_vm;
22568 ++
22569 + if (atomic_read(&p->user->processes) >=
22570 + p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
22571 + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
22572 + p->user != &root_user)
22573 +- goto bad_fork_free;
22574 ++ goto bad_fork_cleanup_vm;
22575 + }
22576 +
22577 + atomic_inc(&p->user->__count);
22578 +@@ -1265,6 +1301,18 @@ static struct task_struct *copy_process(
22579 +
22580 + total_forks++;
22581 + spin_unlock(&current->sighand->siglock);
22582 ++
22583 ++ /* p is copy of current */
22584 ++ vxi = p->vx_info;
22585 ++ if (vxi) {
22586 ++ claim_vx_info(vxi, p);
22587 ++ atomic_inc(&vxi->cvirt.nr_threads);
22588 ++ atomic_inc(&vxi->cvirt.total_forks);
22589 ++ vx_nproc_inc(p);
22590 ++ }
22591 ++ nxi = p->nx_info;
22592 ++ if (nxi)
22593 ++ claim_nx_info(nxi, p);
22594 + write_unlock_irq(&tasklist_lock);
22595 + proc_fork_connector(p);
22596 + return p;
22597 +@@ -1306,6 +1354,9 @@ bad_fork_cleanup_count:
22598 + put_group_info(p->group_info);
22599 + atomic_dec(&p->user->processes);
22600 + free_uid(p->user);
22601 ++bad_fork_cleanup_vm:
22602 ++ if (p->mm && !(clone_flags & CLONE_VM))
22603 ++ vx_pages_sub(p->vx_info, RLIMIT_AS, p->mm->total_vm);
22604 + bad_fork_free:
22605 + free_task(p);
22606 + fork_out:
22607 +@@ -1367,6 +1418,15 @@ long do_fork(unsigned long clone_flags,
22608 +
22609 + if (!pid)
22610 + return -EAGAIN;
22611 ++
22612 ++ /* kernel threads are host only */
22613 ++ if ((clone_flags & CLONE_KTHREAD) &&
22614 ++ !vx_capable(CAP_SYS_ADMIN, VXC_KTHREAD)) {
22615 ++ vxwprintk_task(1, "tried to spawn a kernel thread.");
22616 ++ free_pid(pid);
22617 ++ return -EPERM;
22618 ++ }
22619 ++
22620 + nr = pid->nr;
22621 + if (unlikely(current->ptrace)) {
22622 + trace = fork_traceflag (clone_flags);
22623 +diff -NurpP --minimal linux-2.6.22.19/kernel/kthread.c linux-2.6.22.19-vs2.3.0.34/kernel/kthread.c
22624 +--- linux-2.6.22.19/kernel/kthread.c 2007-07-09 13:20:03 +0200
22625 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/kthread.c 2007-08-05 20:53:13 +0200
22626 +@@ -96,7 +96,7 @@ static void create_kthread(struct kthrea
22627 + } else {
22628 + wait_for_completion(&create->started);
22629 + read_lock(&tasklist_lock);
22630 +- create->result = find_task_by_pid(pid);
22631 ++ create->result = find_task_by_real_pid(pid);
22632 + read_unlock(&tasklist_lock);
22633 + }
22634 + complete(&create->done);
22635 +diff -NurpP --minimal linux-2.6.22.19/kernel/nsproxy.c linux-2.6.22.19-vs2.3.0.34/kernel/nsproxy.c
22636 +--- linux-2.6.22.19/kernel/nsproxy.c 2007-07-09 13:20:03 +0200
22637 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/nsproxy.c 2007-08-05 20:53:13 +0200
22638 +@@ -20,14 +20,11 @@
22639 + #include <linux/mnt_namespace.h>
22640 + #include <linux/utsname.h>
22641 + #include <linux/pid_namespace.h>
22642 ++#include <linux/vserver/global.h>
22643 ++#include <linux/vserver/debug.h>
22644 +
22645 + struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
22646 +
22647 +-static inline void get_nsproxy(struct nsproxy *ns)
22648 +-{
22649 +- atomic_inc(&ns->count);
22650 +-}
22651 +-
22652 + void get_task_namespaces(struct task_struct *tsk)
22653 + {
22654 + struct nsproxy *ns = tsk->nsproxy;
22655 +@@ -46,6 +43,9 @@ static inline struct nsproxy *clone_nspr
22656 + ns = kmemdup(orig, sizeof(struct nsproxy), GFP_KERNEL);
22657 + if (ns)
22658 + atomic_set(&ns->count, 1);
22659 ++ vxdprintk(VXD_CBIT(space, 2), "clone_nsproxy(%p[%u] = %p[1]",
22660 ++ orig, atomic_read(&orig->count), ns);
22661 ++ atomic_inc(&vs_global_nsproxy);
22662 + return ns;
22663 + }
22664 +
22665 +@@ -54,28 +54,32 @@ static inline struct nsproxy *clone_nspr
22666 + * Return the newly created nsproxy. Do not attach this to the task,
22667 + * leave it to the caller to do proper locking and attach it to task.
22668 + */
22669 +-static struct nsproxy *create_new_namespaces(int flags, struct task_struct *tsk,
22670 ++static struct nsproxy *unshare_namespaces(int flags, struct nsproxy *orig,
22671 + struct fs_struct *new_fs)
22672 + {
22673 + struct nsproxy *new_nsp;
22674 +
22675 +- new_nsp = clone_nsproxy(tsk->nsproxy);
22676 ++ vxdprintk(VXD_CBIT(space, 4),
22677 ++ "unshare_namespaces(0x%08x,%p,%p)",
22678 ++ flags, orig, new_fs);
22679 ++
22680 ++ new_nsp = clone_nsproxy(orig);
22681 + if (!new_nsp)
22682 + return ERR_PTR(-ENOMEM);
22683 +
22684 +- new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, new_fs);
22685 ++ new_nsp->mnt_ns = copy_mnt_ns(flags, orig->mnt_ns, new_fs);
22686 + if (IS_ERR(new_nsp->mnt_ns))
22687 + goto out_ns;
22688 +
22689 +- new_nsp->uts_ns = copy_utsname(flags, tsk->nsproxy->uts_ns);
22690 ++ new_nsp->uts_ns = copy_utsname(flags, orig->uts_ns);
22691 + if (IS_ERR(new_nsp->uts_ns))
22692 + goto out_uts;
22693 +
22694 +- new_nsp->ipc_ns = copy_ipcs(flags, tsk->nsproxy->ipc_ns);
22695 ++ new_nsp->ipc_ns = copy_ipcs(flags, orig->ipc_ns);
22696 + if (IS_ERR(new_nsp->ipc_ns))
22697 + goto out_ipc;
22698 +
22699 +- new_nsp->pid_ns = copy_pid_ns(flags, tsk->nsproxy->pid_ns);
22700 ++ new_nsp->pid_ns = copy_pid_ns(flags, orig->pid_ns);
22701 + if (IS_ERR(new_nsp->pid_ns))
22702 + goto out_pid;
22703 +
22704 +@@ -95,6 +99,33 @@ out_ns:
22705 + return ERR_PTR(-ENOMEM);
22706 + }
22707 +
22708 ++static struct nsproxy *create_new_namespaces(int flags, struct task_struct *tsk,
22709 ++ struct fs_struct *new_fs)
22710 ++{
22711 ++ return unshare_namespaces(flags, tsk->nsproxy, new_fs);
22712 ++}
22713 ++
22714 ++/*
22715 ++ * copies the nsproxy, setting refcount to 1, and grabbing a
22716 ++ * reference to all contained namespaces.
22717 ++ */
22718 ++struct nsproxy *copy_nsproxy(struct nsproxy *orig)
22719 ++{
22720 ++ struct nsproxy *ns = clone_nsproxy(orig);
22721 ++
22722 ++ if (ns) {
22723 ++ if (ns->mnt_ns)
22724 ++ get_mnt_ns(ns->mnt_ns);
22725 ++ if (ns->uts_ns)
22726 ++ get_uts_ns(ns->uts_ns);
22727 ++ if (ns->ipc_ns)
22728 ++ get_ipc_ns(ns->ipc_ns);
22729 ++ if (ns->pid_ns)
22730 ++ get_pid_ns(ns->pid_ns);
22731 ++ }
22732 ++ return ns;
22733 ++}
22734 ++
22735 + /*
22736 + * called from clone. This now handles copy for nsproxy and all
22737 + * namespaces therein.
22738 +@@ -102,9 +133,12 @@ out_ns:
22739 + int copy_namespaces(int flags, struct task_struct *tsk)
22740 + {
22741 + struct nsproxy *old_ns = tsk->nsproxy;
22742 +- struct nsproxy *new_ns;
22743 ++ struct nsproxy *new_ns = NULL;
22744 + int err = 0;
22745 +
22746 ++ vxdprintk(VXD_CBIT(space, 7), "copy_namespaces(0x%08x,%p[%p])",
22747 ++ flags, tsk, old_ns);
22748 ++
22749 + if (!old_ns)
22750 + return 0;
22751 +
22752 +@@ -127,6 +161,9 @@ int copy_namespaces(int flags, struct ta
22753 + tsk->nsproxy = new_ns;
22754 + out:
22755 + put_nsproxy(old_ns);
22756 ++ vxdprintk(VXD_CBIT(space, 3),
22757 ++ "copy_namespaces(0x%08x,%p[%p]) = %d [%p]",
22758 ++ flags, tsk, old_ns, err, new_ns);
22759 + return err;
22760 + }
22761 +
22762 +@@ -140,6 +177,7 @@ void free_nsproxy(struct nsproxy *ns)
22763 + put_ipc_ns(ns->ipc_ns);
22764 + if (ns->pid_ns)
22765 + put_pid_ns(ns->pid_ns);
22766 ++ atomic_dec(&vs_global_nsproxy);
22767 + kfree(ns);
22768 + }
22769 +
22770 +@@ -152,6 +190,10 @@ int unshare_nsproxy_namespaces(unsigned
22771 + {
22772 + int err = 0;
22773 +
22774 ++ vxdprintk(VXD_CBIT(space, 4),
22775 ++ "unshare_nsproxy_namespaces(0x%08lx,[%p])",
22776 ++ unshare_flags, current->nsproxy);
22777 ++
22778 + if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC)))
22779 + return 0;
22780 +
22781 +diff -NurpP --minimal linux-2.6.22.19/kernel/pid.c linux-2.6.22.19-vs2.3.0.34/kernel/pid.c
22782 +--- linux-2.6.22.19/kernel/pid.c 2007-07-09 13:20:03 +0200
22783 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/pid.c 2007-08-05 20:53:13 +0200
22784 +@@ -28,6 +28,7 @@
22785 + #include <linux/hash.h>
22786 + #include <linux/pid_namespace.h>
22787 + #include <linux/init_task.h>
22788 ++#include <linux/vs_pid.h>
22789 +
22790 + #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
22791 + static struct hlist_head *pid_hash;
22792 +@@ -295,6 +296,9 @@ void fastcall transfer_pid(struct task_s
22793 + struct task_struct * fastcall pid_task(struct pid *pid, enum pid_type type)
22794 + {
22795 + struct task_struct *result = NULL;
22796 ++
22797 ++ if (type == PIDTYPE_REALPID)
22798 ++ type = PIDTYPE_PID;
22799 + if (pid) {
22800 + struct hlist_node *first;
22801 + first = rcu_dereference(pid->tasks[type].first);
22802 +@@ -309,7 +313,17 @@ struct task_struct * fastcall pid_task(s
22803 + */
22804 + struct task_struct *find_task_by_pid_type(int type, int nr)
22805 + {
22806 +- return pid_task(find_pid(nr), type);
22807 ++ struct task_struct *task;
22808 ++
22809 ++ if (type == PIDTYPE_PID)
22810 ++ nr = vx_rmap_pid(nr);
22811 ++
22812 ++ task = pid_task(find_pid(nr), type);
22813 ++ if (task && (type != PIDTYPE_REALPID) &&
22814 ++ /* maybe VS_WATCH_P in the future? */
22815 ++ !vx_check(task->xid, VS_WATCH|VS_IDENT))
22816 ++ return NULL;
22817 ++ return task;
22818 + }
22819 +
22820 + EXPORT_SYMBOL(find_task_by_pid_type);
22821 +diff -NurpP --minimal linux-2.6.22.19/kernel/posix-timers.c linux-2.6.22.19-vs2.3.0.34/kernel/posix-timers.c
22822 +--- linux-2.6.22.19/kernel/posix-timers.c 2007-07-09 13:20:03 +0200
22823 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/posix-timers.c 2007-10-01 15:41:45 +0200
22824 +@@ -47,6 +47,7 @@
22825 + #include <linux/wait.h>
22826 + #include <linux/workqueue.h>
22827 + #include <linux/module.h>
22828 ++#include <linux/vs_context.h>
22829 +
22830 + /*
22831 + * Management arrays for POSIX timers. Timers are kept in slab memory
22832 +@@ -297,6 +298,12 @@ void do_schedule_next_timer(struct sigin
22833 +
22834 + int posix_timer_event(struct k_itimer *timr,int si_private)
22835 + {
22836 ++ struct vx_info_save vxis;
22837 ++ struct vx_info *vxi;
22838 ++ int ret;
22839 ++
22840 ++ vxi = task_get_vx_info(timr->it_process);
22841 ++ enter_vx_info(vxi, &vxis);
22842 + memset(&timr->sigq->info, 0, sizeof(siginfo_t));
22843 + timr->sigq->info.si_sys_private = si_private;
22844 + /* Send signal to the process that owns this timer.*/
22845 +@@ -309,11 +316,11 @@ int posix_timer_event(struct k_itimer *t
22846 +
22847 + if (timr->it_sigev_notify & SIGEV_THREAD_ID) {
22848 + struct task_struct *leader;
22849 +- int ret = send_sigqueue(timr->it_sigev_signo, timr->sigq,
22850 +- timr->it_process);
22851 +
22852 ++ ret = send_sigqueue(timr->it_sigev_signo, timr->sigq,
22853 ++ timr->it_process);
22854 + if (likely(ret >= 0))
22855 +- return ret;
22856 ++ goto out;
22857 +
22858 + timr->it_sigev_notify = SIGEV_SIGNAL;
22859 + leader = timr->it_process->group_leader;
22860 +@@ -321,8 +328,12 @@ int posix_timer_event(struct k_itimer *t
22861 + timr->it_process = leader;
22862 + }
22863 +
22864 +- return send_group_sigqueue(timr->it_sigev_signo, timr->sigq,
22865 ++ ret = send_group_sigqueue(timr->it_sigev_signo, timr->sigq,
22866 + timr->it_process);
22867 ++out:
22868 ++ leave_vx_info(&vxis);
22869 ++ put_vx_info(vxi);
22870 ++ return ret;
22871 + }
22872 + EXPORT_SYMBOL_GPL(posix_timer_event);
22873 +
22874 +@@ -402,7 +413,7 @@ static struct task_struct * good_sigeven
22875 + struct task_struct *rtn = current->group_leader;
22876 +
22877 + if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
22878 +- (!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) ||
22879 ++ (!(rtn = find_task_by_real_pid(event->sigev_notify_thread_id)) ||
22880 + rtn->tgid != current->tgid ||
22881 + (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
22882 + return NULL;
22883 +diff -NurpP --minimal linux-2.6.22.19/kernel/printk.c linux-2.6.22.19-vs2.3.0.34/kernel/printk.c
22884 +--- linux-2.6.22.19/kernel/printk.c 2007-07-09 13:20:03 +0200
22885 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/printk.c 2007-08-05 20:53:13 +0200
22886 +@@ -31,6 +31,7 @@
22887 + #include <linux/bootmem.h>
22888 + #include <linux/syscalls.h>
22889 + #include <linux/jiffies.h>
22890 ++#include <linux/vs_cvirt.h>
22891 +
22892 + #include <asm/uaccess.h>
22893 +
22894 +@@ -182,18 +183,13 @@ int do_syslog(int type, char __user *buf
22895 + unsigned long i, j, limit, count;
22896 + int do_clear = 0;
22897 + char c;
22898 +- int error = 0;
22899 ++ int error;
22900 +
22901 + error = security_syslog(type);
22902 + if (error)
22903 + return error;
22904 +
22905 +- switch (type) {
22906 +- case 0: /* Close log */
22907 +- break;
22908 +- case 1: /* Open log */
22909 +- break;
22910 +- case 2: /* Read from log */
22911 ++ if ((type >= 2) && (type <= 4)) {
22912 + error = -EINVAL;
22913 + if (!buf || len < 0)
22914 + goto out;
22915 +@@ -204,6 +200,16 @@ int do_syslog(int type, char __user *buf
22916 + error = -EFAULT;
22917 + goto out;
22918 + }
22919 ++ }
22920 ++ if (!vx_check(0, VS_ADMIN|VS_WATCH))
22921 ++ return vx_do_syslog(type, buf, len);
22922 ++
22923 ++ switch (type) {
22924 ++ case 0: /* Close log */
22925 ++ break;
22926 ++ case 1: /* Open log */
22927 ++ break;
22928 ++ case 2: /* Read from log */
22929 + error = wait_event_interruptible(log_wait,
22930 + (log_start - log_end));
22931 + if (error)
22932 +@@ -228,16 +234,6 @@ int do_syslog(int type, char __user *buf
22933 + do_clear = 1;
22934 + /* FALL THRU */
22935 + case 3: /* Read last kernel messages */
22936 +- error = -EINVAL;
22937 +- if (!buf || len < 0)
22938 +- goto out;
22939 +- error = 0;
22940 +- if (!len)
22941 +- goto out;
22942 +- if (!access_ok(VERIFY_WRITE, buf, len)) {
22943 +- error = -EFAULT;
22944 +- goto out;
22945 +- }
22946 + count = len;
22947 + if (count > log_buf_len)
22948 + count = log_buf_len;
22949 +diff -NurpP --minimal linux-2.6.22.19/kernel/ptrace.c linux-2.6.22.19-vs2.3.0.34/kernel/ptrace.c
22950 +--- linux-2.6.22.19/kernel/ptrace.c 2007-07-09 13:20:03 +0200
22951 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/ptrace.c 2007-08-05 20:53:13 +0200
22952 +@@ -19,6 +19,7 @@
22953 + #include <linux/security.h>
22954 + #include <linux/signal.h>
22955 + #include <linux/audit.h>
22956 ++#include <linux/vs_context.h>
22957 +
22958 + #include <asm/pgtable.h>
22959 + #include <asm/uaccess.h>
22960 +@@ -145,6 +146,11 @@ static int may_attach(struct task_struct
22961 + dumpable = task->mm->dumpable;
22962 + if (!dumpable && !capable(CAP_SYS_PTRACE))
22963 + return -EPERM;
22964 ++ if (!vx_check(task->xid, VS_ADMIN_P|VS_IDENT))
22965 ++ return -EPERM;
22966 ++ if (!vx_check(task->xid, VS_IDENT) &&
22967 ++ !task_vx_flags(task, VXF_STATE_ADMIN, 0))
22968 ++ return -EACCES;
22969 +
22970 + return security_ptrace(current, task);
22971 + }
22972 +@@ -471,6 +477,10 @@ asmlinkage long sys_ptrace(long request,
22973 + goto out;
22974 + }
22975 +
22976 ++ ret = -EPERM;
22977 ++ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT))
22978 ++ goto out_put_task_struct;
22979 ++
22980 + if (request == PTRACE_ATTACH) {
22981 + ret = ptrace_attach(child);
22982 + goto out_put_task_struct;
22983 +diff -NurpP --minimal linux-2.6.22.19/kernel/sched.c linux-2.6.22.19-vs2.3.0.34/kernel/sched.c
22984 +--- linux-2.6.22.19/kernel/sched.c 2007-07-09 13:20:03 +0200
22985 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/sched.c 2007-08-05 20:53:13 +0200
22986 +@@ -56,6 +56,8 @@
22987 +
22988 + #include <asm/tlb.h>
22989 + #include <asm/unistd.h>
22990 ++#include <linux/vs_sched.h>
22991 ++#include <linux/vs_cvirt.h>
22992 +
22993 + /*
22994 + * Scheduler clock - returns current time in nanosec units.
22995 +@@ -281,6 +283,16 @@ struct rq {
22996 + struct task_struct *migration_thread;
22997 + struct list_head migration_queue;
22998 + #endif
22999 ++ unsigned long norm_time;
23000 ++ unsigned long idle_time;
23001 ++#ifdef CONFIG_VSERVER_IDLETIME
23002 ++ int idle_skip;
23003 ++#endif
23004 ++#ifdef CONFIG_VSERVER_HARDCPU
23005 ++ struct list_head hold_queue;
23006 ++ unsigned long nr_onhold;
23007 ++ int idle_tokens;
23008 ++#endif
23009 +
23010 + #ifdef CONFIG_SCHEDSTATS
23011 + /* latency stats */
23012 +@@ -714,6 +726,7 @@ sched_info_switch(struct task_struct *pr
23013 + */
23014 + static void dequeue_task(struct task_struct *p, struct prio_array *array)
23015 + {
23016 ++ BUG_ON(p->state & TASK_ONHOLD);
23017 + array->nr_active--;
23018 + list_del(&p->run_list);
23019 + if (list_empty(array->queue + p->prio))
23020 +@@ -722,6 +735,7 @@ static void dequeue_task(struct task_str
23021 +
23022 + static void enqueue_task(struct task_struct *p, struct prio_array *array)
23023 + {
23024 ++ BUG_ON(p->state & TASK_ONHOLD);
23025 + sched_info_queued(p);
23026 + list_add_tail(&p->run_list, array->queue + p->prio);
23027 + __set_bit(p->prio, array->bitmap);
23028 +@@ -735,12 +749,14 @@ static void enqueue_task(struct task_str
23029 + */
23030 + static void requeue_task(struct task_struct *p, struct prio_array *array)
23031 + {
23032 ++ BUG_ON(p->state & TASK_ONHOLD);
23033 + list_move_tail(&p->run_list, array->queue + p->prio);
23034 + }
23035 +
23036 + static inline void
23037 + enqueue_task_head(struct task_struct *p, struct prio_array *array)
23038 + {
23039 ++ BUG_ON(p->state & TASK_ONHOLD);
23040 + list_add(&p->run_list, array->queue + p->prio);
23041 + __set_bit(p->prio, array->bitmap);
23042 + array->nr_active++;
23043 +@@ -769,6 +785,10 @@ static inline int __normal_prio(struct t
23044 + bonus = CURRENT_BONUS(p) - MAX_BONUS / 2;
23045 +
23046 + prio = p->static_prio - bonus;
23047 ++
23048 ++ /* adjust effective priority */
23049 ++ prio = vx_adjust_prio(p, prio, MAX_USER_PRIO);
23050 ++
23051 + if (prio < MAX_RT_PRIO)
23052 + prio = MAX_RT_PRIO;
23053 + if (prio > MAX_PRIO-1)
23054 +@@ -878,6 +898,9 @@ static int effective_prio(struct task_st
23055 + return p->prio;
23056 + }
23057 +
23058 ++#include "sched_mon.h"
23059 ++
23060 ++
23061 + /*
23062 + * __activate_task - move a task to the runqueue.
23063 + */
23064 +@@ -887,6 +910,7 @@ static void __activate_task(struct task_
23065 +
23066 + if (batch_task(p))
23067 + target = rq->expired;
23068 ++ vxm_activate_task(p, rq);
23069 + enqueue_task(p, target);
23070 + inc_nr_running(p, rq);
23071 + }
23072 +@@ -896,6 +920,7 @@ static void __activate_task(struct task_
23073 + */
23074 + static inline void __activate_idle_task(struct task_struct *p, struct rq *rq)
23075 + {
23076 ++ vxm_activate_idle(p, rq);
23077 + enqueue_task_head(p, rq->active);
23078 + inc_nr_running(p, rq);
23079 + }
23080 +@@ -1030,19 +1055,30 @@ static void activate_task(struct task_st
23081 + }
23082 + p->timestamp = now;
23083 + out:
23084 ++ vx_activate_task(p);
23085 + __activate_task(p, rq);
23086 + }
23087 +
23088 + /*
23089 +- * deactivate_task - remove a task from the runqueue.
23090 ++ * __deactivate_task - remove a task from the runqueue.
23091 + */
23092 +-static void deactivate_task(struct task_struct *p, struct rq *rq)
23093 ++static void __deactivate_task(struct task_struct *p, struct rq *rq)
23094 + {
23095 + dec_nr_running(p, rq);
23096 + dequeue_task(p, p->array);
23097 ++ vxm_deactivate_task(p, rq);
23098 + p->array = NULL;
23099 + }
23100 +
23101 ++static inline
23102 ++void deactivate_task(struct task_struct *p, struct rq *rq)
23103 ++{
23104 ++ vx_deactivate_task(p);
23105 ++ __deactivate_task(p, rq);
23106 ++}
23107 ++
23108 ++#include "sched_hard.h"
23109 ++
23110 + /*
23111 + * resched_task - mark a task 'to be rescheduled now'.
23112 + *
23113 +@@ -1129,6 +1165,7 @@ migrate_task(struct task_struct *p, int
23114 + {
23115 + struct rq *rq = task_rq(p);
23116 +
23117 ++ vxm_migrate_task(p, rq, dest_cpu);
23118 + /*
23119 + * If the task is not on a runqueue (and not running), then
23120 + * it is sufficient to simply update the task's cpu field.
23121 +@@ -1518,6 +1555,12 @@ static int try_to_wake_up(struct task_st
23122 +
23123 + rq = task_rq_lock(p, &flags);
23124 + old_state = p->state;
23125 ++
23126 ++ /* we need to unhold suspended tasks */
23127 ++ if (old_state & TASK_ONHOLD) {
23128 ++ vx_unhold_task(p, rq);
23129 ++ old_state = p->state;
23130 ++ }
23131 + if (!(old_state & state))
23132 + goto out;
23133 +
23134 +@@ -1625,6 +1668,7 @@ out_activate:
23135 + #endif /* CONFIG_SMP */
23136 + if (old_state == TASK_UNINTERRUPTIBLE) {
23137 + rq->nr_uninterruptible--;
23138 ++ vx_uninterruptible_dec(p);
23139 + /*
23140 + * Tasks on involuntary sleep don't earn
23141 + * sleep_avg beyond just interactive state.
23142 +@@ -1676,7 +1720,7 @@ int fastcall wake_up_state(struct task_s
23143 + return try_to_wake_up(p, state, 0);
23144 + }
23145 +
23146 +-static void task_running_tick(struct rq *rq, struct task_struct *p);
23147 ++static void task_running_tick(struct rq *rq, struct task_struct *p, int cpu);
23148 + /*
23149 + * Perform scheduler related setup for a newly forked process p.
23150 + * p is forked by current.
23151 +@@ -1737,7 +1781,7 @@ void fastcall sched_fork(struct task_str
23152 + * runqueue lock is not a problem.
23153 + */
23154 + current->time_slice = 1;
23155 +- task_running_tick(cpu_rq(cpu), current);
23156 ++ task_running_tick(cpu_rq(cpu), current, cpu);
23157 + }
23158 + local_irq_enable();
23159 + put_cpu();
23160 +@@ -1772,6 +1816,7 @@ void fastcall wake_up_new_task(struct ta
23161 +
23162 + p->prio = effective_prio(p);
23163 +
23164 ++ vx_activate_task(p);
23165 + if (likely(cpu == this_cpu)) {
23166 + if (!(clone_flags & CLONE_VM)) {
23167 + /*
23168 +@@ -1783,6 +1828,7 @@ void fastcall wake_up_new_task(struct ta
23169 + __activate_task(p, rq);
23170 + else {
23171 + p->prio = current->prio;
23172 ++ BUG_ON(p->state & TASK_ONHOLD);
23173 + p->normal_prio = current->normal_prio;
23174 + list_add_tail(&p->run_list, &current->run_list);
23175 + p->array = current->array;
23176 +@@ -3351,13 +3397,16 @@ static inline int expired_starving(struc
23177 + void account_user_time(struct task_struct *p, cputime_t cputime)
23178 + {
23179 + struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
23180 ++ struct vx_info *vxi = p->vx_info; /* p is _always_ current */
23181 + cputime64_t tmp;
23182 ++ int nice = (TASK_NICE(p) > 0);
23183 +
23184 + p->utime = cputime_add(p->utime, cputime);
23185 ++ vx_account_user(vxi, cputime, nice);
23186 +
23187 + /* Add user time to cpustat. */
23188 + tmp = cputime_to_cputime64(cputime);
23189 +- if (TASK_NICE(p) > 0)
23190 ++ if (nice)
23191 + cpustat->nice = cputime64_add(cpustat->nice, tmp);
23192 + else
23193 + cpustat->user = cputime64_add(cpustat->user, tmp);
23194 +@@ -3373,10 +3422,12 @@ void account_system_time(struct task_str
23195 + cputime_t cputime)
23196 + {
23197 + struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
23198 ++ struct vx_info *vxi = p->vx_info; /* p is _always_ current */
23199 + struct rq *rq = this_rq();
23200 + cputime64_t tmp;
23201 +
23202 + p->stime = cputime_add(p->stime, cputime);
23203 ++ vx_account_system(vxi, cputime, (p == rq->idle));
23204 +
23205 + /* Add system time to cpustat. */
23206 + tmp = cputime_to_cputime64(cputime);
23207 +@@ -3415,7 +3466,7 @@ void account_steal_time(struct task_stru
23208 + cpustat->steal = cputime64_add(cpustat->steal, tmp);
23209 + }
23210 +
23211 +-static void task_running_tick(struct rq *rq, struct task_struct *p)
23212 ++static void task_running_tick(struct rq *rq, struct task_struct *p, int cpu)
23213 + {
23214 + if (p->array != rq->active) {
23215 + /* Task has expired but was not scheduled yet */
23216 +@@ -3445,7 +3496,7 @@ static void task_running_tick(struct rq
23217 + }
23218 + goto out_unlock;
23219 + }
23220 +- if (!--p->time_slice) {
23221 ++ if (vx_need_resched(p, --p->time_slice, cpu)) {
23222 + dequeue_task(p, rq->active);
23223 + set_tsk_need_resched(p);
23224 + p->prio = effective_prio(p);
23225 +@@ -3506,9 +3557,12 @@ void scheduler_tick(void)
23226 + struct rq *rq = cpu_rq(cpu);
23227 +
23228 + update_cpu_clock(p, rq, now);
23229 ++ vxm_sync(now, cpu);
23230 +
23231 +- if (!idle_at_tick)
23232 +- task_running_tick(rq, p);
23233 ++ if (idle_at_tick)
23234 ++ vx_idle_resched(rq);
23235 ++ else
23236 ++ task_running_tick(rq, p, cpu);
23237 + #ifdef CONFIG_SMP
23238 + update_load(rq);
23239 + rq->idle_at_tick = idle_at_tick;
23240 +@@ -3630,14 +3684,25 @@ need_resched_nonpreemptible:
23241 + unlikely(signal_pending(prev))))
23242 + prev->state = TASK_RUNNING;
23243 + else {
23244 +- if (prev->state == TASK_UNINTERRUPTIBLE)
23245 ++ if (prev->state == TASK_UNINTERRUPTIBLE) {
23246 + rq->nr_uninterruptible++;
23247 ++ vx_uninterruptible_inc(prev);
23248 ++ }
23249 + deactivate_task(prev, rq);
23250 + }
23251 + }
23252 +
23253 + cpu = smp_processor_id();
23254 ++ vx_set_rq_time(rq, jiffies);
23255 ++try_unhold:
23256 ++ vx_try_unhold(rq, cpu);
23257 ++pick_next:
23258 ++
23259 + if (unlikely(!rq->nr_running)) {
23260 ++ /* can we skip idle time? */
23261 ++ if (vx_try_skip(rq, cpu))
23262 ++ goto try_unhold;
23263 ++
23264 + idle_balance(cpu, rq);
23265 + if (!rq->nr_running) {
23266 + next = rq->idle;
23267 +@@ -3663,6 +3728,10 @@ need_resched_nonpreemptible:
23268 + queue = array->queue + idx;
23269 + next = list_entry(queue->next, struct task_struct, run_list);
23270 +
23271 ++ /* check before we schedule this context */
23272 ++ if (!vx_schedule(next, rq, cpu))
23273 ++ goto pick_next;
23274 ++
23275 + if (!rt_task(next) && interactive_sleep(next->sleep_type)) {
23276 + unsigned long long delta = now - next->timestamp;
23277 + if (unlikely((long long)(now - next->timestamp) < 0))
23278 +@@ -4263,7 +4332,7 @@ asmlinkage long sys_nice(int increment)
23279 + nice = 19;
23280 +
23281 + if (increment < 0 && !can_nice(current, nice))
23282 +- return -EPERM;
23283 ++ return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
23284 +
23285 + retval = security_task_setnice(current, nice);
23286 + if (retval)
23287 +@@ -4435,6 +4504,7 @@ recheck:
23288 + oldprio = p->prio;
23289 + __setscheduler(p, policy, param->sched_priority);
23290 + if (array) {
23291 ++ vx_activate_task(p);
23292 + __activate_task(p, rq);
23293 + /*
23294 + * Reschedule if we are currently running on this runqueue and
23295 +@@ -5188,6 +5258,7 @@ static int __migrate_task(struct task_st
23296 + p->timestamp = p->timestamp - rq_src->most_recent_timestamp
23297 + + rq_dest->most_recent_timestamp;
23298 + deactivate_task(p, rq_src);
23299 ++ vx_activate_task(p);
23300 + __activate_task(p, rq_dest);
23301 + if (TASK_PREEMPTS_CURR(p, rq_dest))
23302 + resched_task(rq_dest->curr);
23303 +@@ -7058,7 +7129,10 @@ void __init sched_init(void)
23304 + INIT_LIST_HEAD(&rq->migration_queue);
23305 + #endif
23306 + atomic_set(&rq->nr_iowait, 0);
23307 +-
23308 ++#ifdef CONFIG_VSERVER_HARDCPU
23309 ++ INIT_LIST_HEAD(&rq->hold_queue);
23310 ++ rq->nr_onhold = 0;
23311 ++#endif
23312 + for (j = 0; j < 2; j++) {
23313 + array = rq->arrays + j;
23314 + for (k = 0; k < MAX_PRIO; k++) {
23315 +@@ -7144,6 +7218,7 @@ void normalize_rt_tasks(void)
23316 + deactivate_task(p, task_rq(p));
23317 + __setscheduler(p, SCHED_NORMAL, 0);
23318 + if (array) {
23319 ++ vx_activate_task(p);
23320 + __activate_task(p, task_rq(p));
23321 + resched_task(rq->curr);
23322 + }
23323 +diff -NurpP --minimal linux-2.6.22.19/kernel/sched_hard.h linux-2.6.22.19-vs2.3.0.34/kernel/sched_hard.h
23324 +--- linux-2.6.22.19/kernel/sched_hard.h 1970-01-01 01:00:00 +0100
23325 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/sched_hard.h 2007-08-05 20:53:13 +0200
23326 +@@ -0,0 +1,324 @@
23327 ++
23328 ++#ifdef CONFIG_VSERVER_IDLELIMIT
23329 ++
23330 ++/*
23331 ++ * vx_idle_resched - reschedule after maxidle
23332 ++ */
23333 ++static inline
23334 ++void vx_idle_resched(struct rq *rq)
23335 ++{
23336 ++ /* maybe have a better criterion for paused */
23337 ++ if (!--rq->idle_tokens && !list_empty(&rq->hold_queue))
23338 ++ set_need_resched();
23339 ++}
23340 ++
23341 ++#else /* !CONFIG_VSERVER_IDLELIMIT */
23342 ++
23343 ++#define vx_idle_resched(rq)
23344 ++
23345 ++#endif /* CONFIG_VSERVER_IDLELIMIT */
23346 ++
23347 ++
23348 ++
23349 ++#ifdef CONFIG_VSERVER_IDLETIME
23350 ++
23351 ++#define vx_set_rq_min_skip(rq, min) \
23352 ++ (rq)->idle_skip = (min)
23353 ++
23354 ++#define vx_save_min_skip(ret, min, val) \
23355 ++ __vx_save_min_skip(ret, min, val)
23356 ++
23357 ++static inline
23358 ++void __vx_save_min_skip(int ret, int *min, int val)
23359 ++{
23360 ++ if (ret > -2)
23361 ++ return;
23362 ++ if ((*min > val) || !*min)
23363 ++ *min = val;
23364 ++}
23365 ++
23366 ++static inline
23367 ++int vx_try_skip(struct rq *rq, int cpu)
23368 ++{
23369 ++ /* artificially advance time */
23370 ++ if (rq->idle_skip > 0) {
23371 ++ vxdprintk(list_empty(&rq->hold_queue),
23372 ++ "hold queue empty on cpu %d", cpu);
23373 ++ rq->idle_time += rq->idle_skip;
23374 ++ vxm_idle_skip(rq, cpu);
23375 ++ return 1;
23376 ++ }
23377 ++ return 0;
23378 ++}
23379 ++
23380 ++#else /* !CONFIG_VSERVER_IDLETIME */
23381 ++
23382 ++#define vx_set_rq_min_skip(rq, min) \
23383 ++ ({ int dummy = (min); dummy; })
23384 ++
23385 ++#define vx_save_min_skip(ret, min, val)
23386 ++
23387 ++static inline
23388 ++int vx_try_skip(struct rq *rq, int cpu)
23389 ++{
23390 ++ return 0;
23391 ++}
23392 ++
23393 ++#endif /* CONFIG_VSERVER_IDLETIME */
23394 ++
23395 ++
23396 ++
23397 ++#ifdef CONFIG_VSERVER_HARDCPU
23398 ++
23399 ++#define vx_set_rq_max_idle(rq, max) \
23400 ++ (rq)->idle_tokens = (max)
23401 ++
23402 ++#define vx_save_max_idle(ret, min, val) \
23403 ++ __vx_save_max_idle(ret, min, val)
23404 ++
23405 ++static inline
23406 ++void __vx_save_max_idle(int ret, int *min, int val)
23407 ++{
23408 ++ if (*min > val)
23409 ++ *min = val;
23410 ++}
23411 ++
23412 ++
23413 ++/*
23414 ++ * vx_hold_task - put a task on the hold queue
23415 ++ */
23416 ++static inline
23417 ++void vx_hold_task(struct task_struct *p, struct rq *rq)
23418 ++{
23419 ++ __deactivate_task(p, rq);
23420 ++ p->state |= TASK_ONHOLD;
23421 ++ /* a new one on hold */
23422 ++ rq->nr_onhold++;
23423 ++ vxm_hold_task(p, rq);
23424 ++ list_add_tail(&p->run_list, &rq->hold_queue);
23425 ++}
23426 ++
23427 ++/*
23428 ++ * vx_unhold_task - put a task back to the runqueue
23429 ++ */
23430 ++static inline
23431 ++void vx_unhold_task(struct task_struct *p, struct rq *rq)
23432 ++{
23433 ++ list_del(&p->run_list);
23434 ++ /* one less waiting */
23435 ++ rq->nr_onhold--;
23436 ++ p->state &= ~TASK_ONHOLD;
23437 ++ enqueue_task(p, rq->expired);
23438 ++ inc_nr_running(p, rq);
23439 ++ vxm_unhold_task(p, rq);
23440 ++
23441 ++ if (p->static_prio < rq->best_expired_prio)
23442 ++ rq->best_expired_prio = p->static_prio;
23443 ++}
23444 ++
23445 ++unsigned long nr_onhold(void)
23446 ++{
23447 ++ unsigned long i, sum = 0;
23448 ++
23449 ++ for_each_online_cpu(i)
23450 ++ sum += cpu_rq(i)->nr_onhold;
23451 ++
23452 ++ return sum;
23453 ++}
23454 ++
23455 ++
23456 ++
23457 ++static inline
23458 ++int __vx_tokens_avail(struct _vx_sched_pc *sched_pc)
23459 ++{
23460 ++ return sched_pc->tokens;
23461 ++}
23462 ++
23463 ++static inline
23464 ++void __vx_consume_token(struct _vx_sched_pc *sched_pc)
23465 ++{
23466 ++ sched_pc->tokens--;
23467 ++}
23468 ++
23469 ++static inline
23470 ++int vx_need_resched(struct task_struct *p, int slice, int cpu)
23471 ++{
23472 ++ struct vx_info *vxi = p->vx_info;
23473 ++
23474 ++ if (vx_info_flags(vxi, VXF_SCHED_HARD|VXF_SCHED_PRIO, 0)) {
23475 ++ struct _vx_sched_pc *sched_pc =
23476 ++ &vx_per_cpu(vxi, sched_pc, cpu);
23477 ++ int tokens;
23478 ++
23479 ++ /* maybe we can simplify that to decrement
23480 ++ the token counter unconditional? */
23481 ++
23482 ++ if ((tokens = __vx_tokens_avail(sched_pc)) > 0)
23483 ++ __vx_consume_token(sched_pc);
23484 ++
23485 ++ /* for tokens > 0, one token was consumed */
23486 ++ if (tokens < 2)
23487 ++ slice = 0;
23488 ++ }
23489 ++ vxm_need_resched(p, slice, cpu);
23490 ++ return (slice == 0);
23491 ++}
23492 ++
23493 ++
23494 ++#define vx_set_rq_time(rq, time) do { \
23495 ++ rq->norm_time = time; \
23496 ++} while (0)
23497 ++
23498 ++
23499 ++static inline
23500 ++void vx_try_unhold(struct rq *rq, int cpu)
23501 ++{
23502 ++ struct vx_info *vxi = NULL;
23503 ++ struct list_head *l, *n;
23504 ++ int maxidle = HZ;
23505 ++ int minskip = 0;
23506 ++
23507 ++ /* nothing to do? what about pause? */
23508 ++ if (list_empty(&rq->hold_queue))
23509 ++ return;
23510 ++
23511 ++ list_for_each_safe(l, n, &rq->hold_queue) {
23512 ++ int ret, delta_min[2];
23513 ++ struct _vx_sched_pc *sched_pc;
23514 ++ struct task_struct *p;
23515 ++
23516 ++ p = list_entry(l, struct task_struct, run_list);
23517 ++ /* don't bother with same context */
23518 ++ if (vxi == p->vx_info)
23519 ++ continue;
23520 ++
23521 ++ vxi = p->vx_info;
23522 ++ /* ignore paused contexts */
23523 ++ if (vx_info_flags(vxi, VXF_SCHED_PAUSE, 0))
23524 ++ continue;
23525 ++
23526 ++ sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
23527 ++
23528 ++ /* recalc tokens */
23529 ++ vxm_sched_info(sched_pc, vxi, cpu);
23530 ++ ret = vx_tokens_recalc(sched_pc,
23531 ++ &rq->norm_time, &rq->idle_time, delta_min);
23532 ++ vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
23533 ++
23534 ++ if (ret > 0) {
23535 ++ /* we found a runable context */
23536 ++ vx_unhold_task(p, rq);
23537 ++ break;
23538 ++ }
23539 ++ vx_save_max_idle(ret, &maxidle, delta_min[0]);
23540 ++ vx_save_min_skip(ret, &minskip, delta_min[1]);
23541 ++ }
23542 ++ vx_set_rq_max_idle(rq, maxidle);
23543 ++ vx_set_rq_min_skip(rq, minskip);
23544 ++ vxm_rq_max_min(rq, cpu);
23545 ++}
23546 ++
23547 ++
23548 ++static inline
23549 ++int vx_schedule(struct task_struct *next, struct rq *rq, int cpu)
23550 ++{
23551 ++ struct vx_info *vxi = next->vx_info;
23552 ++ struct _vx_sched_pc *sched_pc;
23553 ++ int delta_min[2];
23554 ++ int flags, ret;
23555 ++
23556 ++ if (!vxi)
23557 ++ return 1;
23558 ++
23559 ++ flags = vxi->vx_flags;
23560 ++
23561 ++ if (unlikely(vs_check_flags(flags, VXF_SCHED_PAUSE, 0)))
23562 ++ goto put_on_hold;
23563 ++ if (!vs_check_flags(flags, VXF_SCHED_HARD | VXF_SCHED_PRIO, 0))
23564 ++ return 1;
23565 ++
23566 ++ sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
23567 ++#ifdef CONFIG_SMP
23568 ++ /* update scheduler params */
23569 ++ if (cpu_isset(cpu, vxi->sched.update)) {
23570 ++ vx_update_sched_param(&vxi->sched, sched_pc);
23571 ++ vxm_update_sched(sched_pc, vxi, cpu);
23572 ++ cpu_clear(cpu, vxi->sched.update);
23573 ++ }
23574 ++#endif
23575 ++ vxm_sched_info(sched_pc, vxi, cpu);
23576 ++ ret = vx_tokens_recalc(sched_pc,
23577 ++ &rq->norm_time, &rq->idle_time, delta_min);
23578 ++ vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
23579 ++
23580 ++ if (!vs_check_flags(flags, VXF_SCHED_HARD, 0))
23581 ++ return 1;
23582 ++
23583 ++ if (unlikely(ret < 0)) {
23584 ++ vx_save_max_idle(ret, &rq->idle_tokens, delta_min[0]);
23585 ++ vx_save_min_skip(ret, &rq->idle_skip, delta_min[1]);
23586 ++ vxm_rq_max_min(rq, cpu);
23587 ++ put_on_hold:
23588 ++ vx_hold_task(next, rq);
23589 ++ return 0;
23590 ++ }
23591 ++ return 1;
23592 ++}
23593 ++
23594 ++
23595 ++#else /* CONFIG_VSERVER_HARDCPU */
23596 ++
23597 ++static inline
23598 ++void vx_hold_task(struct task_struct *p, struct rq *rq)
23599 ++{
23600 ++ return;
23601 ++}
23602 ++
23603 ++static inline
23604 ++void vx_unhold_task(struct task_struct *p, struct rq *rq)
23605 ++{
23606 ++ return;
23607 ++}
23608 ++
23609 ++unsigned long nr_onhold(void)
23610 ++{
23611 ++ return 0;
23612 ++}
23613 ++
23614 ++
23615 ++static inline
23616 ++int vx_need_resched(struct task_struct *p, int slice, int cpu)
23617 ++{
23618 ++ return (slice == 0);
23619 ++}
23620 ++
23621 ++
23622 ++#define vx_set_rq_time(rq, time)
23623 ++
23624 ++static inline
23625 ++void vx_try_unhold(struct rq *rq, int cpu)
23626 ++{
23627 ++ return;
23628 ++}
23629 ++
23630 ++static inline
23631 ++int vx_schedule(struct task_struct *next, struct rq *rq, int cpu)
23632 ++{
23633 ++ struct vx_info *vxi = next->vx_info;
23634 ++ struct _vx_sched_pc *sched_pc;
23635 ++ int delta_min[2];
23636 ++ int ret;
23637 ++
23638 ++ if (!vx_info_flags(vxi, VXF_SCHED_PRIO, 0))
23639 ++ return 1;
23640 ++
23641 ++ sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
23642 ++ vxm_sched_info(sched_pc, vxi, cpu);
23643 ++ ret = vx_tokens_recalc(sched_pc,
23644 ++ &rq->norm_time, &rq->idle_time, delta_min);
23645 ++ vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
23646 ++ return 1;
23647 ++}
23648 ++
23649 ++#endif /* CONFIG_VSERVER_HARDCPU */
23650 ++
23651 +diff -NurpP --minimal linux-2.6.22.19/kernel/sched_mon.h linux-2.6.22.19-vs2.3.0.34/kernel/sched_mon.h
23652 +--- linux-2.6.22.19/kernel/sched_mon.h 1970-01-01 01:00:00 +0100
23653 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/sched_mon.h 2007-08-05 20:53:13 +0200
23654 +@@ -0,0 +1,200 @@
23655 ++
23656 ++#include <linux/vserver/monitor.h>
23657 ++
23658 ++#ifdef CONFIG_VSERVER_MONITOR
23659 ++
23660 ++#ifdef CONFIG_VSERVER_HARDCPU
23661 ++#define HARDCPU(x) (x)
23662 ++#else
23663 ++#define HARDCPU(x) (0)
23664 ++#endif
23665 ++
23666 ++#ifdef CONFIG_VSERVER_IDLETIME
23667 ++#define IDLETIME(x) (x)
23668 ++#else
23669 ++#define IDLETIME(x) (0)
23670 ++#endif
23671 ++
23672 ++struct _vx_mon_entry *vxm_advance(int cpu);
23673 ++
23674 ++
23675 ++static inline
23676 ++void __vxm_basic(struct _vx_mon_entry *entry, xid_t xid, int type)
23677 ++{
23678 ++ entry->type = type;
23679 ++ entry->xid = xid;
23680 ++}
23681 ++
23682 ++static inline
23683 ++void __vxm_sync(int cpu)
23684 ++{
23685 ++ struct _vx_mon_entry *entry = vxm_advance(cpu);
23686 ++
23687 ++ __vxm_basic(entry, 0, VXM_SYNC);
23688 ++ entry->ev.sec = xtime.tv_sec;
23689 ++ entry->ev.nsec = xtime.tv_nsec;
23690 ++}
23691 ++
23692 ++static inline
23693 ++void __vxm_task(struct task_struct *p, int type)
23694 ++{
23695 ++ struct _vx_mon_entry *entry = vxm_advance(task_cpu(p));
23696 ++
23697 ++ __vxm_basic(entry, p->xid, type);
23698 ++ entry->ev.tsk.pid = p->pid;
23699 ++ entry->ev.tsk.state = p->state;
23700 ++}
23701 ++
23702 ++static inline
23703 ++void __vxm_sched(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
23704 ++{
23705 ++ struct _vx_mon_entry *entry = vxm_advance(cpu);
23706 ++
23707 ++ __vxm_basic(entry, vxi->vx_id, (VXM_SCHED | s->flags));
23708 ++ entry->sd.tokens = s->tokens;
23709 ++ entry->sd.norm_time = s->norm_time;
23710 ++ entry->sd.idle_time = s->idle_time;
23711 ++}
23712 ++
23713 ++static inline
23714 ++void __vxm_rqinfo1(struct rq *q, int cpu)
23715 ++{
23716 ++ struct _vx_mon_entry *entry = vxm_advance(cpu);
23717 ++
23718 ++ entry->type = VXM_RQINFO_1;
23719 ++ entry->xid = ((unsigned long)q >> 16) & 0xffff;
23720 ++ entry->q1.running = q->nr_running;
23721 ++ entry->q1.onhold = HARDCPU(q->nr_onhold);
23722 ++ entry->q1.iowait = atomic_read(&q->nr_iowait);
23723 ++ entry->q1.uintr = q->nr_uninterruptible;
23724 ++ entry->q1.idle_tokens = IDLETIME(q->idle_tokens);
23725 ++}
23726 ++
23727 ++static inline
23728 ++void __vxm_rqinfo2(struct rq *q, int cpu)
23729 ++{
23730 ++ struct _vx_mon_entry *entry = vxm_advance(cpu);
23731 ++
23732 ++ entry->type = VXM_RQINFO_2;
23733 ++ entry->xid = (unsigned long)q & 0xffff;
23734 ++ entry->q2.norm_time = q->norm_time;
23735 ++ entry->q2.idle_time = q->idle_time;
23736 ++ entry->q2.idle_skip = IDLETIME(q->idle_skip);
23737 ++}
23738 ++
23739 ++static inline
23740 ++void __vxm_update(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
23741 ++{
23742 ++ struct _vx_mon_entry *entry = vxm_advance(cpu);
23743 ++
23744 ++ __vxm_basic(entry, vxi->vx_id, VXM_UPDATE);
23745 ++ entry->ev.tokens = s->tokens;
23746 ++}
23747 ++
23748 ++static inline
23749 ++void __vxm_update1(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
23750 ++{
23751 ++ struct _vx_mon_entry *entry = vxm_advance(cpu);
23752 ++
23753 ++ __vxm_basic(entry, vxi->vx_id, VXM_UPDATE_1);
23754 ++ entry->u1.tokens_max = s->tokens_max;
23755 ++ entry->u1.fill_rate = s->fill_rate[0];
23756 ++ entry->u1.interval = s->interval[0];
23757 ++}
23758 ++
23759 ++static inline
23760 ++void __vxm_update2(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
23761 ++{
23762 ++ struct _vx_mon_entry *entry = vxm_advance(cpu);
23763 ++
23764 ++ __vxm_basic(entry, vxi->vx_id, VXM_UPDATE_2);
23765 ++ entry->u2.tokens_min = s->tokens_min;
23766 ++ entry->u2.fill_rate = s->fill_rate[1];
23767 ++ entry->u2.interval = s->interval[1];
23768 ++}
23769 ++
23770 ++
23771 ++#define vxm_activate_task(p,q) __vxm_task(p, VXM_ACTIVATE)
23772 ++#define vxm_activate_idle(p,q) __vxm_task(p, VXM_IDLE)
23773 ++#define vxm_deactivate_task(p,q) __vxm_task(p, VXM_DEACTIVATE)
23774 ++#define vxm_hold_task(p,q) __vxm_task(p, VXM_HOLD)
23775 ++#define vxm_unhold_task(p,q) __vxm_task(p, VXM_UNHOLD)
23776 ++
23777 ++static inline
23778 ++void vxm_migrate_task(struct task_struct *p, struct rq *rq, int dest)
23779 ++{
23780 ++ __vxm_task(p, VXM_MIGRATE);
23781 ++ __vxm_rqinfo1(rq, task_cpu(p));
23782 ++ __vxm_rqinfo2(rq, task_cpu(p));
23783 ++}
23784 ++
23785 ++static inline
23786 ++void vxm_idle_skip(struct rq *rq, int cpu)
23787 ++{
23788 ++ __vxm_rqinfo1(rq, cpu);
23789 ++ __vxm_rqinfo2(rq, cpu);
23790 ++}
23791 ++
23792 ++static inline
23793 ++void vxm_need_resched(struct task_struct *p, int slice, int cpu)
23794 ++{
23795 ++ if (slice)
23796 ++ return;
23797 ++
23798 ++ __vxm_task(p, VXM_RESCHED);
23799 ++}
23800 ++
23801 ++static inline
23802 ++void vxm_sync(unsigned long now, int cpu)
23803 ++{
23804 ++ if (!CONFIG_VSERVER_MONITOR_SYNC ||
23805 ++ (now % CONFIG_VSERVER_MONITOR_SYNC))
23806 ++ return;
23807 ++
23808 ++ __vxm_sync(cpu);
23809 ++}
23810 ++
23811 ++#define vxm_sched_info(s,v,c) __vxm_sched(s,v,c)
23812 ++
23813 ++static inline
23814 ++void vxm_tokens_recalc(struct _vx_sched_pc *s, struct rq *rq,
23815 ++ struct vx_info *vxi, int cpu)
23816 ++{
23817 ++ __vxm_sched(s, vxi, cpu);
23818 ++ __vxm_rqinfo2(rq, cpu);
23819 ++}
23820 ++
23821 ++static inline
23822 ++void vxm_update_sched(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
23823 ++{
23824 ++ __vxm_sched(s, vxi, cpu);
23825 ++ __vxm_update(s, vxi, cpu);
23826 ++ __vxm_update1(s, vxi, cpu);
23827 ++ __vxm_update2(s, vxi, cpu);
23828 ++}
23829 ++
23830 ++static inline
23831 ++void vxm_rq_max_min(struct rq *rq, int cpu)
23832 ++{
23833 ++ __vxm_rqinfo1(rq, cpu);
23834 ++ __vxm_rqinfo2(rq, cpu);
23835 ++}
23836 ++
23837 ++#else /* CONFIG_VSERVER_MONITOR */
23838 ++
23839 ++#define vxm_activate_task(t,q) do { } while (0)
23840 ++#define vxm_activate_idle(t,q) do { } while (0)
23841 ++#define vxm_deactivate_task(t,q) do { } while (0)
23842 ++#define vxm_hold_task(t,q) do { } while (0)
23843 ++#define vxm_unhold_task(t,q) do { } while (0)
23844 ++#define vxm_migrate_task(t,q,d) do { } while (0)
23845 ++#define vxm_idle_skip(q,c) do { } while (0)
23846 ++#define vxm_need_resched(t,s,c) do { } while (0)
23847 ++#define vxm_sync(s,c) do { } while (0)
23848 ++#define vxm_sched_info(s,v,c) do { } while (0)
23849 ++#define vxm_tokens_recalc(s,q,v,c) do { } while (0)
23850 ++#define vxm_update_sched(s,v,c) do { } while (0)
23851 ++#define vxm_rq_max_min(q,c) do { } while (0)
23852 ++
23853 ++#endif /* CONFIG_VSERVER_MONITOR */
23854 ++
23855 +diff -NurpP --minimal linux-2.6.22.19/kernel/signal.c linux-2.6.22.19-vs2.3.0.34/kernel/signal.c
23856 +--- linux-2.6.22.19/kernel/signal.c 2008-03-14 20:19:04 +0100
23857 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/signal.c 2008-01-18 13:43:35 +0100
23858 +@@ -26,6 +26,8 @@
23859 + #include <linux/freezer.h>
23860 + #include <linux/pid_namespace.h>
23861 + #include <linux/nsproxy.h>
23862 ++#include <linux/vs_context.h>
23863 ++#include <linux/vs_pid.h>
23864 +
23865 + #include <asm/param.h>
23866 + #include <asm/uaccess.h>
23867 +@@ -523,19 +525,34 @@ static int check_kill_permission(int sig
23868 + if (!valid_signal(sig))
23869 + return error;
23870 +
23871 ++ if ((info != SEND_SIG_NOINFO) &&
23872 ++ (is_si_special(info) || !SI_FROMUSER(info)))
23873 ++ goto skip;
23874 ++
23875 ++ vxdprintk(VXD_CBIT(misc, 7),
23876 ++ "check_kill_permission(%d,%p,%p[#%u,%u])",
23877 ++ sig, info, t, vx_task_xid(t), t->pid);
23878 ++
23879 + error = audit_signal_info(sig, t); /* Let audit system see the signal */
23880 + if (error)
23881 + return error;
23882 +
23883 + error = -EPERM;
23884 +- if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
23885 +- && ((sig != SIGCONT) ||
23886 ++ if (((sig != SIGCONT) ||
23887 + (process_session(current) != process_session(t)))
23888 + && (current->euid ^ t->suid) && (current->euid ^ t->uid)
23889 + && (current->uid ^ t->suid) && (current->uid ^ t->uid)
23890 + && !capable(CAP_KILL))
23891 + return error;
23892 +
23893 ++ error = -ESRCH;
23894 ++ if (!vx_check(vx_task_xid(t), VS_WATCH_P | VS_IDENT)) {
23895 ++ vxdprintk(current->xid || VXD_CBIT(misc, 7),
23896 ++ "signal %d[%p] xid mismatch %p[#%u,%u] xid=#%u",
23897 ++ sig, info, t, vx_task_xid(t), t->pid, current->xid);
23898 ++ return error;
23899 ++ }
23900 ++skip:
23901 + return security_task_kill(t, info, sig, 0);
23902 + }
23903 +
23904 +@@ -1043,7 +1060,7 @@ int kill_pid_info(int sig, struct siginf
23905 +
23906 + p = pid_task(pid, PIDTYPE_PID);
23907 + error = -ESRCH;
23908 +- if (p)
23909 ++ if (p && vx_check(vx_task_xid(p), VS_IDENT))
23910 + error = group_send_sig_info(sig, info, p);
23911 +
23912 + if (unlikely(sig_needs_tasklist(sig)))
23913 +@@ -1057,7 +1074,7 @@ kill_proc_info(int sig, struct siginfo *
23914 + {
23915 + int error;
23916 + rcu_read_lock();
23917 +- error = kill_pid_info(sig, info, find_pid(pid));
23918 ++ error = kill_pid_info(sig, info, find_pid(vx_rmap_pid(pid)));
23919 + rcu_read_unlock();
23920 + return error;
23921 + }
23922 +@@ -1118,7 +1135,9 @@ static int kill_something_info(int sig,
23923 +
23924 + read_lock(&tasklist_lock);
23925 + for_each_process(p) {
23926 +- if (p->pid > 1 && p->tgid != current->tgid) {
23927 ++ if (vx_check(vx_task_xid(p), VS_ADMIN_P|VS_IDENT) &&
23928 ++ p->pid > 1 && p->tgid != current->tgid &&
23929 ++ !vx_current_initpid(p->pid)) {
23930 + int err = group_send_sig_info(sig, info, p);
23931 + ++count;
23932 + if (err != -EPERM)
23933 +@@ -1128,9 +1147,9 @@ static int kill_something_info(int sig,
23934 + read_unlock(&tasklist_lock);
23935 + ret = count ? retval : -ESRCH;
23936 + } else if (pid < 0) {
23937 +- ret = kill_pgrp_info(sig, info, find_pid(-pid));
23938 ++ ret = kill_pgrp_info(sig, info, find_pid(vx_rmap_pid(-pid)));
23939 + } else {
23940 +- ret = kill_pid_info(sig, info, find_pid(pid));
23941 ++ ret = kill_pid_info(sig, info, find_pid(vx_rmap_pid(pid)));
23942 + }
23943 + rcu_read_unlock();
23944 + return ret;
23945 +@@ -1814,6 +1833,11 @@ relock:
23946 + if (current == child_reaper(current))
23947 + continue;
23948 +
23949 ++ /* virtual init is protected against user signals */
23950 ++ if ((info->si_code == SI_USER) &&
23951 ++ vx_current_initpid(current->pid))
23952 ++ continue;
23953 ++
23954 + if (sig_kernel_stop(signr)) {
23955 + /*
23956 + * The default action is to stop all threads in
23957 +diff -NurpP --minimal linux-2.6.22.19/kernel/softirq.c linux-2.6.22.19-vs2.3.0.34/kernel/softirq.c
23958 +--- linux-2.6.22.19/kernel/softirq.c 2007-07-09 13:20:03 +0200
23959 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/softirq.c 2007-08-05 20:53:13 +0200
23960 +@@ -18,6 +18,7 @@
23961 + #include <linux/rcupdate.h>
23962 + #include <linux/smp.h>
23963 + #include <linux/tick.h>
23964 ++#include <linux/vs_context.h>
23965 +
23966 + #include <asm/irq.h>
23967 + /*
23968 +diff -NurpP --minimal linux-2.6.22.19/kernel/sys.c linux-2.6.22.19-vs2.3.0.34/kernel/sys.c
23969 +--- linux-2.6.22.19/kernel/sys.c 2008-03-14 20:19:04 +0100
23970 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/sys.c 2008-01-18 12:36:58 +0100
23971 +@@ -35,6 +35,7 @@
23972 + #include <linux/compat.h>
23973 + #include <linux/syscalls.h>
23974 + #include <linux/kprobes.h>
23975 ++#include <linux/vs_pid.h>
23976 +
23977 + #include <asm/uaccess.h>
23978 + #include <asm/io.h>
23979 +@@ -638,7 +639,10 @@ static int set_one_prio(struct task_stru
23980 + goto out;
23981 + }
23982 + if (niceval < task_nice(p) && !can_nice(p, niceval)) {
23983 +- error = -EACCES;
23984 ++ if (vx_flags(VXF_IGNEG_NICE, 0))
23985 ++ error = 0;
23986 ++ else
23987 ++ error = -EACCES;
23988 + goto out;
23989 + }
23990 + no_nice = security_task_setnice(p, niceval);
23991 +@@ -686,6 +690,8 @@ asmlinkage long sys_setpriority(int whic
23992 + else
23993 + pgrp = task_pgrp(current);
23994 + do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
23995 ++ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
23996 ++ continue;
23997 + error = set_one_prio(p, niceval, error);
23998 + } while_each_pid_task(pgrp, PIDTYPE_PGID, p);
23999 + break;
24000 +@@ -694,7 +700,8 @@ asmlinkage long sys_setpriority(int whic
24001 + if (!who)
24002 + who = current->uid;
24003 + else
24004 +- if ((who != current->uid) && !(user = find_user(who)))
24005 ++ if ((who != current->uid) &&
24006 ++ !(user = find_user(vx_current_xid(), who)))
24007 + goto out_unlock; /* No processes for this user */
24008 +
24009 + do_each_thread(g, p)
24010 +@@ -746,6 +753,8 @@ asmlinkage long sys_getpriority(int whic
24011 + else
24012 + pgrp = task_pgrp(current);
24013 + do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
24014 ++ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
24015 ++ continue;
24016 + niceval = 20 - task_nice(p);
24017 + if (niceval > retval)
24018 + retval = niceval;
24019 +@@ -756,7 +765,8 @@ asmlinkage long sys_getpriority(int whic
24020 + if (!who)
24021 + who = current->uid;
24022 + else
24023 +- if ((who != current->uid) && !(user = find_user(who)))
24024 ++ if ((who != current->uid) &&
24025 ++ !(user = find_user(vx_current_xid(), who)))
24026 + goto out_unlock; /* No processes for this user */
24027 +
24028 + do_each_thread(g, p)
24029 +@@ -869,6 +879,9 @@ void kernel_power_off(void)
24030 + machine_power_off();
24031 + }
24032 + EXPORT_SYMBOL_GPL(kernel_power_off);
24033 ++
24034 ++long vs_reboot(unsigned int, void __user *);
24035 ++
24036 + /*
24037 + * Reboot system call: for obvious reasons only root may call it,
24038 + * and even root needs to set up some magic numbers in the registers
24039 +@@ -899,6 +912,9 @@ asmlinkage long sys_reboot(int magic1, i
24040 + if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
24041 + cmd = LINUX_REBOOT_CMD_HALT;
24042 +
24043 ++ if (!vx_check(0, VS_ADMIN|VS_WATCH))
24044 ++ return vs_reboot(cmd, arg);
24045 ++
24046 + lock_kernel();
24047 + switch (cmd) {
24048 + case LINUX_REBOOT_CMD_RESTART:
24049 +@@ -1078,7 +1094,7 @@ static int set_user(uid_t new_ruid, int
24050 + {
24051 + struct user_struct *new_user;
24052 +
24053 +- new_user = alloc_uid(new_ruid);
24054 ++ new_user = alloc_uid(vx_current_xid(), new_ruid);
24055 + if (!new_user)
24056 + return -EAGAIN;
24057 +
24058 +@@ -1432,15 +1448,18 @@ asmlinkage long sys_setpgid(pid_t pid, p
24059 + {
24060 + struct task_struct *p;
24061 + struct task_struct *group_leader = current->group_leader;
24062 ++ pid_t rpgid;
24063 + int err = -EINVAL;
24064 +
24065 + if (!pid)
24066 +- pid = group_leader->pid;
24067 ++ pid = vx_map_pid(group_leader->pid);
24068 + if (!pgid)
24069 + pgid = pid;
24070 + if (pgid < 0)
24071 + return -EINVAL;
24072 +
24073 ++ rpgid = vx_rmap_pid(pgid);
24074 ++
24075 + /* From this point forward we keep holding onto the tasklist lock
24076 + * so that our parent does not change from under us. -DaveM
24077 + */
24078 +@@ -1474,20 +1493,20 @@ asmlinkage long sys_setpgid(pid_t pid, p
24079 +
24080 + if (pgid != pid) {
24081 + struct task_struct *g =
24082 +- find_task_by_pid_type(PIDTYPE_PGID, pgid);
24083 ++ find_task_by_pid_type(PIDTYPE_PGID, rpgid);
24084 +
24085 + if (!g || task_session(g) != task_session(group_leader))
24086 + goto out;
24087 + }
24088 +
24089 +- err = security_task_setpgid(p, pgid);
24090 ++ err = security_task_setpgid(p, rpgid);
24091 + if (err)
24092 + goto out;
24093 +
24094 +- if (process_group(p) != pgid) {
24095 ++ if (process_group(p) != rpgid) {
24096 + detach_pid(p, PIDTYPE_PGID);
24097 +- p->signal->pgrp = pgid;
24098 +- attach_pid(p, PIDTYPE_PGID, find_pid(pgid));
24099 ++ p->signal->pgrp = rpgid;
24100 ++ attach_pid(p, PIDTYPE_PGID, find_pid(rpgid));
24101 + }
24102 +
24103 + err = 0;
24104 +@@ -1500,7 +1519,7 @@ out:
24105 + asmlinkage long sys_getpgid(pid_t pid)
24106 + {
24107 + if (!pid)
24108 +- return process_group(current);
24109 ++ return vx_rmap_pid(process_group(current));
24110 + else {
24111 + int retval;
24112 + struct task_struct *p;
24113 +@@ -1512,7 +1531,7 @@ asmlinkage long sys_getpgid(pid_t pid)
24114 + if (p) {
24115 + retval = security_task_getpgid(p);
24116 + if (!retval)
24117 +- retval = process_group(p);
24118 ++ retval = vx_rmap_pid(process_group(p));
24119 + }
24120 + read_unlock(&tasklist_lock);
24121 + return retval;
24122 +@@ -1863,7 +1882,7 @@ asmlinkage long sys_sethostname(char __u
24123 + int errno;
24124 + char tmp[__NEW_UTS_LEN];
24125 +
24126 +- if (!capable(CAP_SYS_ADMIN))
24127 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME))
24128 + return -EPERM;
24129 + if (len < 0 || len > __NEW_UTS_LEN)
24130 + return -EINVAL;
24131 +@@ -1908,7 +1927,7 @@ asmlinkage long sys_setdomainname(char _
24132 + int errno;
24133 + char tmp[__NEW_UTS_LEN];
24134 +
24135 +- if (!capable(CAP_SYS_ADMIN))
24136 ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME))
24137 + return -EPERM;
24138 + if (len < 0 || len > __NEW_UTS_LEN)
24139 + return -EINVAL;
24140 +@@ -1975,7 +1994,7 @@ asmlinkage long sys_setrlimit(unsigned i
24141 + return -EINVAL;
24142 + old_rlim = current->signal->rlim + resource;
24143 + if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
24144 +- !capable(CAP_SYS_RESOURCE))
24145 ++ !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
24146 + return -EPERM;
24147 + if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN)
24148 + return -EPERM;
24149 +diff -NurpP --minimal linux-2.6.22.19/kernel/sysctl.c linux-2.6.22.19-vs2.3.0.34/kernel/sysctl.c
24150 +--- linux-2.6.22.19/kernel/sysctl.c 2007-07-09 13:20:03 +0200
24151 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/sysctl.c 2007-08-05 20:53:13 +0200
24152 +@@ -89,6 +89,7 @@ static int ngroups_max = NGROUPS_MAX;
24153 + #ifdef CONFIG_KMOD
24154 + extern char modprobe_path[];
24155 + #endif
24156 ++extern char vshelper_path[];
24157 + #ifdef CONFIG_CHR_DEV_SG
24158 + extern int sg_big_buff;
24159 + #endif
24160 +@@ -343,6 +344,15 @@ static ctl_table kern_table[] = {
24161 + .strategy = &sysctl_string,
24162 + },
24163 + #endif
24164 ++ {
24165 ++ .ctl_name = KERN_VSHELPER,
24166 ++ .procname = "vshelper",
24167 ++ .data = &vshelper_path,
24168 ++ .maxlen = 256,
24169 ++ .mode = 0644,
24170 ++ .proc_handler = &proc_dostring,
24171 ++ .strategy = &sysctl_string,
24172 ++ },
24173 + #ifdef CONFIG_CHR_DEV_SG
24174 + {
24175 + .ctl_name = KERN_SG_BIG_BUFF,
24176 +diff -NurpP --minimal linux-2.6.22.19/kernel/time.c linux-2.6.22.19-vs2.3.0.34/kernel/time.c
24177 +--- linux-2.6.22.19/kernel/time.c 2007-07-09 13:20:03 +0200
24178 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/time.c 2007-08-05 20:53:13 +0200
24179 +@@ -60,7 +60,7 @@ asmlinkage long sys_time(time_t __user *
24180 + time_t i;
24181 + struct timeval tv;
24182 +
24183 +- do_gettimeofday(&tv);
24184 ++ vx_gettimeofday(&tv);
24185 + i = tv.tv_sec;
24186 +
24187 + if (tloc) {
24188 +@@ -91,7 +91,7 @@ asmlinkage long sys_stime(time_t __user
24189 + if (err)
24190 + return err;
24191 +
24192 +- do_settimeofday(&tv);
24193 ++ vx_settimeofday(&tv);
24194 + return 0;
24195 + }
24196 +
24197 +@@ -101,7 +101,7 @@ asmlinkage long sys_gettimeofday(struct
24198 + {
24199 + if (likely(tv != NULL)) {
24200 + struct timeval ktv;
24201 +- do_gettimeofday(&ktv);
24202 ++ vx_gettimeofday(&ktv);
24203 + if (copy_to_user(tv, &ktv, sizeof(ktv)))
24204 + return -EFAULT;
24205 + }
24206 +@@ -175,7 +175,7 @@ int do_sys_settimeofday(struct timespec
24207 + /* SMP safe, again the code in arch/foo/time.c should
24208 + * globally block out interrupts when it runs.
24209 + */
24210 +- return do_settimeofday(tv);
24211 ++ return vx_settimeofday(tv);
24212 + }
24213 + return 0;
24214 + }
24215 +@@ -388,7 +388,7 @@ void getnstimeofday(struct timespec *tv)
24216 + {
24217 + struct timeval x;
24218 +
24219 +- do_gettimeofday(&x);
24220 ++ vx_gettimeofday(&x);
24221 + tv->tv_sec = x.tv_sec;
24222 + tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
24223 + }
24224 +diff -NurpP --minimal linux-2.6.22.19/kernel/timer.c linux-2.6.22.19-vs2.3.0.34/kernel/timer.c
24225 +--- linux-2.6.22.19/kernel/timer.c 2007-07-09 13:20:04 +0200
24226 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/timer.c 2007-08-05 20:53:13 +0200
24227 +@@ -36,6 +36,10 @@
24228 + #include <linux/delay.h>
24229 + #include <linux/tick.h>
24230 + #include <linux/kallsyms.h>
24231 ++#include <linux/vs_base.h>
24232 ++#include <linux/vs_cvirt.h>
24233 ++#include <linux/vs_pid.h>
24234 ++#include <linux/vserver/sched.h>
24235 +
24236 + #include <asm/uaccess.h>
24237 + #include <asm/unistd.h>
24238 +@@ -921,12 +925,6 @@ asmlinkage unsigned long sys_alarm(unsig
24239 +
24240 + #endif
24241 +
24242 +-#ifndef __alpha__
24243 +-
24244 +-/*
24245 +- * The Alpha uses getxpid, getxuid, and getxgid instead. Maybe this
24246 +- * should be moved into arch/i386 instead?
24247 +- */
24248 +
24249 + /**
24250 + * sys_getpid - return the thread group id of the current process
24251 +@@ -939,7 +937,7 @@ asmlinkage unsigned long sys_alarm(unsig
24252 + */
24253 + asmlinkage long sys_getpid(void)
24254 + {
24255 +- return current->tgid;
24256 ++ return vx_map_tgid(current->tgid);
24257 + }
24258 +
24259 + /*
24260 +@@ -955,10 +953,23 @@ asmlinkage long sys_getppid(void)
24261 + rcu_read_lock();
24262 + pid = rcu_dereference(current->real_parent)->tgid;
24263 + rcu_read_unlock();
24264 ++ return vx_map_pid(pid);
24265 ++}
24266 +
24267 +- return pid;
24268 ++#ifdef __alpha__
24269 ++
24270 ++/*
24271 ++ * The Alpha uses getxpid, getxuid, and getxgid instead.
24272 ++ */
24273 ++
24274 ++asmlinkage long do_getxpid(long *ppid)
24275 ++{
24276 ++ *ppid = sys_getppid();
24277 ++ return sys_getpid();
24278 + }
24279 +
24280 ++#else /* _alpha_ */
24281 ++
24282 + asmlinkage long sys_getuid(void)
24283 + {
24284 + /* Only we change this so SMP safe */
24285 +@@ -1118,6 +1129,8 @@ int do_sysinfo(struct sysinfo *info)
24286 + tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC;
24287 + tp.tv_sec++;
24288 + }
24289 ++ if (vx_flags(VXF_VIRT_UPTIME, 0))
24290 ++ vx_vsi_uptime(&tp, NULL);
24291 + info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0);
24292 +
24293 + info->loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
24294 +diff -NurpP --minimal linux-2.6.22.19/kernel/user.c linux-2.6.22.19-vs2.3.0.34/kernel/user.c
24295 +--- linux-2.6.22.19/kernel/user.c 2007-02-06 03:01:56 +0100
24296 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/user.c 2007-08-05 20:53:13 +0200
24297 +@@ -23,8 +23,8 @@
24298 + #define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 8)
24299 + #define UIDHASH_SZ (1 << UIDHASH_BITS)
24300 + #define UIDHASH_MASK (UIDHASH_SZ - 1)
24301 +-#define __uidhashfn(uid) (((uid >> UIDHASH_BITS) + uid) & UIDHASH_MASK)
24302 +-#define uidhashentry(uid) (uidhash_table + __uidhashfn((uid)))
24303 ++#define __uidhashfn(xid,uid) ((((uid) >> UIDHASH_BITS) + ((uid)^(xid))) & UIDHASH_MASK)
24304 ++#define uidhashentry(xid,uid) (uidhash_table + __uidhashfn((xid),(uid)))
24305 +
24306 + static struct kmem_cache *uid_cachep;
24307 + static struct list_head uidhash_table[UIDHASH_SZ];
24308 +@@ -66,7 +66,7 @@ static inline void uid_hash_remove(struc
24309 + list_del(&up->uidhash_list);
24310 + }
24311 +
24312 +-static inline struct user_struct *uid_hash_find(uid_t uid, struct list_head *hashent)
24313 ++static inline struct user_struct *uid_hash_find(xid_t xid, uid_t uid, struct list_head *hashent)
24314 + {
24315 + struct list_head *up;
24316 +
24317 +@@ -75,7 +75,7 @@ static inline struct user_struct *uid_ha
24318 +
24319 + user = list_entry(up, struct user_struct, uidhash_list);
24320 +
24321 +- if(user->uid == uid) {
24322 ++ if(user->uid == uid && user->xid == xid) {
24323 + atomic_inc(&user->__count);
24324 + return user;
24325 + }
24326 +@@ -90,13 +90,13 @@ static inline struct user_struct *uid_ha
24327 + *
24328 + * If the user_struct could not be found, return NULL.
24329 + */
24330 +-struct user_struct *find_user(uid_t uid)
24331 ++struct user_struct *find_user(xid_t xid, uid_t uid)
24332 + {
24333 + struct user_struct *ret;
24334 + unsigned long flags;
24335 +
24336 + spin_lock_irqsave(&uidhash_lock, flags);
24337 +- ret = uid_hash_find(uid, uidhashentry(uid));
24338 ++ ret = uid_hash_find(xid, uid, uidhashentry(xid, uid));
24339 + spin_unlock_irqrestore(&uidhash_lock, flags);
24340 + return ret;
24341 + }
24342 +@@ -120,13 +120,13 @@ void free_uid(struct user_struct *up)
24343 + }
24344 + }
24345 +
24346 +-struct user_struct * alloc_uid(uid_t uid)
24347 ++struct user_struct * alloc_uid(xid_t xid, uid_t uid)
24348 + {
24349 +- struct list_head *hashent = uidhashentry(uid);
24350 ++ struct list_head *hashent = uidhashentry(xid, uid);
24351 + struct user_struct *up;
24352 +
24353 + spin_lock_irq(&uidhash_lock);
24354 +- up = uid_hash_find(uid, hashent);
24355 ++ up = uid_hash_find(xid, uid, hashent);
24356 + spin_unlock_irq(&uidhash_lock);
24357 +
24358 + if (!up) {
24359 +@@ -136,6 +136,7 @@ struct user_struct * alloc_uid(uid_t uid
24360 + if (!new)
24361 + return NULL;
24362 + new->uid = uid;
24363 ++ new->xid = xid;
24364 + atomic_set(&new->__count, 1);
24365 + atomic_set(&new->processes, 0);
24366 + atomic_set(&new->files, 0);
24367 +@@ -158,7 +159,7 @@ struct user_struct * alloc_uid(uid_t uid
24368 + * on adding the same user already..
24369 + */
24370 + spin_lock_irq(&uidhash_lock);
24371 +- up = uid_hash_find(uid, hashent);
24372 ++ up = uid_hash_find(xid, uid, hashent);
24373 + if (up) {
24374 + key_put(new->uid_keyring);
24375 + key_put(new->session_keyring);
24376 +@@ -215,7 +216,7 @@ static int __init uid_cache_init(void)
24377 +
24378 + /* Insert the root user immediately (init already runs as root) */
24379 + spin_lock_irq(&uidhash_lock);
24380 +- uid_hash_insert(&root_user, uidhashentry(0));
24381 ++ uid_hash_insert(&root_user, uidhashentry(0,0));
24382 + spin_unlock_irq(&uidhash_lock);
24383 +
24384 + return 0;
24385 +diff -NurpP --minimal linux-2.6.22.19/kernel/utsname.c linux-2.6.22.19-vs2.3.0.34/kernel/utsname.c
24386 +--- linux-2.6.22.19/kernel/utsname.c 2007-07-09 13:20:04 +0200
24387 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/utsname.c 2007-08-05 20:53:13 +0200
24388 +@@ -13,6 +13,7 @@
24389 + #include <linux/uts.h>
24390 + #include <linux/utsname.h>
24391 + #include <linux/version.h>
24392 ++#include <linux/vserver/global.h>
24393 +
24394 + /*
24395 + * Clone a new ns copying an original utsname, setting refcount to 1
24396 +@@ -27,6 +28,7 @@ static struct uts_namespace *clone_uts_n
24397 + if (ns) {
24398 + memcpy(&ns->name, &old_ns->name, sizeof(ns->name));
24399 + kref_init(&ns->kref);
24400 ++ atomic_inc(&vs_global_uts_ns);
24401 + }
24402 + return ns;
24403 + }
24404 +@@ -58,5 +60,6 @@ void free_uts_ns(struct kref *kref)
24405 + struct uts_namespace *ns;
24406 +
24407 + ns = container_of(kref, struct uts_namespace, kref);
24408 ++ atomic_dec(&vs_global_uts_ns);
24409 + kfree(ns);
24410 + }
24411 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/Kconfig linux-2.6.22.19-vs2.3.0.34/kernel/vserver/Kconfig
24412 +--- linux-2.6.22.19/kernel/vserver/Kconfig 1970-01-01 01:00:00 +0100
24413 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/Kconfig 2007-10-11 01:10:22 +0200
24414 +@@ -0,0 +1,249 @@
24415 ++#
24416 ++# Linux VServer configuration
24417 ++#
24418 ++
24419 ++menu "Linux VServer"
24420 ++
24421 ++config VSERVER_AUTO_LBACK
24422 ++ bool "Automatically Assign Loopback IP"
24423 ++ default y
24424 ++ help
24425 ++ Automatically assign a guest specific loopback
24426 ++ IP and add it to the kernel network stack on
24427 ++ startup.
24428 ++
24429 ++config VSERVER_AUTO_SINGLE
24430 ++ bool "Automatic Single IP Special Casing"
24431 ++ depends on EXPERIMENTAL
24432 ++ default y
24433 ++ help
24434 ++ This allows network contexts with a single IP to
24435 ++ automatically remap 0.0.0.0 bindings to that IP,
24436 ++ avoiding further network checks and improving
24437 ++ performance.
24438 ++
24439 ++ (note: such guests do not allow to change the ip
24440 ++ on the fly and do not show loopback addresses)
24441 ++
24442 ++config VSERVER_COWBL
24443 ++ bool "Enable COW Immutable Link Breaking"
24444 ++ default y
24445 ++ help
24446 ++ This enables the COW (Copy-On-Write) link break code.
24447 ++ It allows you to treat unified files like normal files
24448 ++ when writing to them (which will implicitely break the
24449 ++ link and create a copy of the unified file)
24450 ++
24451 ++config VSERVER_VTIME
24452 ++ bool "Enable Virtualized Guest Time"
24453 ++ depends on EXPERIMENTAL
24454 ++ default n
24455 ++ help
24456 ++ This enables per guest time offsets to allow for
24457 ++ adjusting the system clock individually per guest.
24458 ++ this adds some overhead to the time functions and
24459 ++ therefore should not be enabled without good reason.
24460 ++
24461 ++config VSERVER_DEVICE
24462 ++ bool "Enable Guest Device Mapping"
24463 ++ depends on EXPERIMENTAL
24464 ++ default n
24465 ++ help
24466 ++ This enables generic device remapping.
24467 ++
24468 ++config VSERVER_PROC_SECURE
24469 ++ bool "Enable Proc Security"
24470 ++ depends on PROC_FS
24471 ++ default y
24472 ++ help
24473 ++ This configures ProcFS security to initially hide
24474 ++ non-process entries for all contexts except the main and
24475 ++ spectator context (i.e. for all guests), which is a secure
24476 ++ default.
24477 ++
24478 ++ (note: on 1.2x the entries were visible by default)
24479 ++
24480 ++config VSERVER_HARDCPU
24481 ++ bool "Enable Hard CPU Limits"
24482 ++ default y
24483 ++ help
24484 ++ Activate the Hard CPU Limits
24485 ++
24486 ++ This will compile in code that allows the Token Bucket
24487 ++ Scheduler to put processes on hold when a context's
24488 ++ tokens are depleted (provided that its per-context
24489 ++ sched_hard flag is set).
24490 ++
24491 ++ Processes belonging to that context will not be able
24492 ++ to consume CPU resources again until a per-context
24493 ++ configured minimum of tokens has been reached.
24494 ++
24495 ++config VSERVER_IDLETIME
24496 ++ bool "Avoid idle CPUs by skipping Time"
24497 ++ depends on VSERVER_HARDCPU
24498 ++ default y
24499 ++ help
24500 ++ This option allows the scheduler to artificially
24501 ++ advance time (per cpu) when otherwise the idle
24502 ++ task would be scheduled, thus keeping the cpu
24503 ++ busy and sharing the available resources among
24504 ++ certain contexts.
24505 ++
24506 ++config VSERVER_IDLELIMIT
24507 ++ bool "Limit the IDLE task"
24508 ++ depends on VSERVER_HARDCPU
24509 ++ default n
24510 ++ help
24511 ++ Limit the idle slices, so the the next context
24512 ++ will be scheduled as soon as possible.
24513 ++
24514 ++ This might improve interactivity and latency, but
24515 ++ will also marginally increase scheduling overhead.
24516 ++
24517 ++choice
24518 ++ prompt "Persistent Inode Tagging"
24519 ++ default TAGGING_ID24
24520 ++ help
24521 ++ This adds persistent context information to filesystems
24522 ++ mounted with the tagxid option. Tagging is a requirement
24523 ++ for per-context disk limits and per-context quota.
24524 ++
24525 ++
24526 ++config TAGGING_NONE
24527 ++ bool "Disabled"
24528 ++ help
24529 ++ do not store per-context information in inodes.
24530 ++
24531 ++config TAGGING_UID16
24532 ++ bool "UID16/GID32"
24533 ++ help
24534 ++ reduces UID to 16 bit, but leaves GID at 32 bit.
24535 ++
24536 ++config TAGGING_GID16
24537 ++ bool "UID32/GID16"
24538 ++ help
24539 ++ reduces GID to 16 bit, but leaves UID at 32 bit.
24540 ++
24541 ++config TAGGING_ID24
24542 ++ bool "UID24/GID24"
24543 ++ help
24544 ++ uses the upper 8bit from UID and GID for XID tagging
24545 ++ which leaves 24bit for UID/GID each, which should be
24546 ++ more than sufficient for normal use.
24547 ++
24548 ++config TAGGING_INTERN
24549 ++ bool "UID32/GID32"
24550 ++ help
24551 ++ this uses otherwise reserved inode fields in the on
24552 ++ disk representation, which limits the use to a few
24553 ++ filesystems (currently ext2 and ext3)
24554 ++
24555 ++endchoice
24556 ++
24557 ++config TAG_NFSD
24558 ++ bool "Tag NFSD User Auth and Files"
24559 ++ default n
24560 ++ help
24561 ++ Enable this if you do want the in-kernel NFS
24562 ++ Server to use the tagging specified above.
24563 ++ (will require patched clients too)
24564 ++
24565 ++config VSERVER_PRIVACY
24566 ++ bool "Honor Privacy Aspects of Guests"
24567 ++ default n
24568 ++ help
24569 ++ When enabled, most context checks will disallow
24570 ++ access to structures assigned to a specific context,
24571 ++ like ptys or loop devices.
24572 ++
24573 ++config VSERVER_CONTEXTS
24574 ++ int "Maximum number of Contexts (1-65533)" if EMBEDDED
24575 ++ range 1 65533
24576 ++ default "768" if 64BIT
24577 ++ default "256"
24578 ++ help
24579 ++ This setting will optimize certain data structures
24580 ++ and memory allocations according to the expected
24581 ++ maximum.
24582 ++
24583 ++ note: this is not a strict upper limit.
24584 ++
24585 ++config VSERVER_WARN
24586 ++ bool "VServer Warnings"
24587 ++ default y
24588 ++ help
24589 ++ This enables various runtime warnings, which will
24590 ++ notify about potential manipulation attempts or
24591 ++ resource shortage. It is generally considered to
24592 ++ be a good idea to have that enabled.
24593 ++
24594 ++config VSERVER_DEBUG
24595 ++ bool "VServer Debugging Code"
24596 ++ default n
24597 ++ help
24598 ++ Set this to yes if you want to be able to activate
24599 ++ debugging output at runtime. It adds a very small
24600 ++ overhead to all vserver related functions and
24601 ++ increases the kernel size by about 20k.
24602 ++
24603 ++config VSERVER_HISTORY
24604 ++ bool "VServer History Tracing"
24605 ++ depends on VSERVER_DEBUG
24606 ++ default n
24607 ++ help
24608 ++ Set this to yes if you want to record the history of
24609 ++ linux-vserver activities, so they can be replayed in
24610 ++ the event of a kernel panic or oops.
24611 ++
24612 ++config VSERVER_HISTORY_SIZE
24613 ++ int "Per-CPU History Size (32-65536)"
24614 ++ depends on VSERVER_HISTORY
24615 ++ range 32 65536
24616 ++ default 64
24617 ++ help
24618 ++ This allows you to specify the number of entries in
24619 ++ the per-CPU history buffer.
24620 ++
24621 ++config VSERVER_MONITOR
24622 ++ bool "VServer Scheduling Monitor"
24623 ++ depends on VSERVER_DEBUG
24624 ++ default n
24625 ++ help
24626 ++ Set this to yes if you want to record the scheduling
24627 ++ decisions, so that they can be relayed to userspace
24628 ++ for detailed analysis.
24629 ++
24630 ++config VSERVER_MONITOR_SIZE
24631 ++ int "Per-CPU Monitor Queue Size (32-65536)"
24632 ++ depends on VSERVER_MONITOR
24633 ++ range 32 65536
24634 ++ default 1024
24635 ++ help
24636 ++ This allows you to specify the number of entries in
24637 ++ the per-CPU scheduling monitor buffer.
24638 ++
24639 ++config VSERVER_MONITOR_SYNC
24640 ++ int "Per-CPU Monitor Sync Interval (0-65536)"
24641 ++ depends on VSERVER_MONITOR
24642 ++ range 0 65536
24643 ++ default 256
24644 ++ help
24645 ++ This allows you to specify the interval in ticks
24646 ++ when a time sync entry is inserted.
24647 ++
24648 ++endmenu
24649 ++
24650 ++
24651 ++config VSERVER
24652 ++ bool
24653 ++ default y
24654 ++ select UTS_NS
24655 ++ select SYSVIPC
24656 ++ select IPC_NS
24657 ++
24658 ++config VSERVER_SECURITY
24659 ++ bool
24660 ++ depends on SECURITY
24661 ++ default y
24662 ++ select SECURITY_CAPABILITIES
24663 ++
24664 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/Makefile linux-2.6.22.19-vs2.3.0.34/kernel/vserver/Makefile
24665 +--- linux-2.6.22.19/kernel/vserver/Makefile 1970-01-01 01:00:00 +0100
24666 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/Makefile 2007-10-11 01:10:22 +0200
24667 +@@ -0,0 +1,18 @@
24668 ++#
24669 ++# Makefile for the Linux vserver routines.
24670 ++#
24671 ++
24672 ++
24673 ++obj-y += vserver.o
24674 ++
24675 ++vserver-y := switch.o context.o space.o sched.o network.o inode.o \
24676 ++ limit.o cvirt.o cacct.o signal.o helper.o init.o \
24677 ++ dlimit.o tag.o
24678 ++
24679 ++vserver-$(CONFIG_INET) += inet.o
24680 ++vserver-$(CONFIG_PROC_FS) += proc.o
24681 ++vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o debug.o
24682 ++vserver-$(CONFIG_VSERVER_HISTORY) += history.o
24683 ++vserver-$(CONFIG_VSERVER_MONITOR) += monitor.o
24684 ++vserver-$(CONFIG_VSERVER_DEVICE) += device.o
24685 ++
24686 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/cacct.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/cacct.c
24687 +--- linux-2.6.22.19/kernel/vserver/cacct.c 1970-01-01 01:00:00 +0100
24688 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/cacct.c 2007-08-15 21:54:31 +0200
24689 +@@ -0,0 +1,42 @@
24690 ++/*
24691 ++ * linux/kernel/vserver/cacct.c
24692 ++ *
24693 ++ * Virtual Server: Context Accounting
24694 ++ *
24695 ++ * Copyright (C) 2006-2007 Herbert Pötzl
24696 ++ *
24697 ++ * V0.01 added accounting stats
24698 ++ *
24699 ++ */
24700 ++
24701 ++#include <linux/types.h>
24702 ++#include <linux/vs_context.h>
24703 ++#include <linux/vserver/cacct_cmd.h>
24704 ++#include <linux/vserver/cacct_int.h>
24705 ++
24706 ++#include <asm/errno.h>
24707 ++#include <asm/uaccess.h>
24708 ++
24709 ++
24710 ++int vc_sock_stat(struct vx_info *vxi, void __user *data)
24711 ++{
24712 ++ struct vcmd_sock_stat_v0 vc_data;
24713 ++ int j, field;
24714 ++
24715 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
24716 ++ return -EFAULT;
24717 ++
24718 ++ field = vc_data.field;
24719 ++ if ((field < 0) || (field >= VXA_SOCK_SIZE))
24720 ++ return -EINVAL;
24721 ++
24722 ++ for (j = 0; j < 3; j++) {
24723 ++ vc_data.count[j] = vx_sock_count(&vxi->cacct, field, j);
24724 ++ vc_data.total[j] = vx_sock_total(&vxi->cacct, field, j);
24725 ++ }
24726 ++
24727 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
24728 ++ return -EFAULT;
24729 ++ return 0;
24730 ++}
24731 ++
24732 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/cacct_init.h linux-2.6.22.19-vs2.3.0.34/kernel/vserver/cacct_init.h
24733 +--- linux-2.6.22.19/kernel/vserver/cacct_init.h 1970-01-01 01:00:00 +0100
24734 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/cacct_init.h 2007-08-05 20:53:13 +0200
24735 +@@ -0,0 +1,25 @@
24736 ++
24737 ++
24738 ++static inline void vx_info_init_cacct(struct _vx_cacct *cacct)
24739 ++{
24740 ++ int i, j;
24741 ++
24742 ++
24743 ++ for (i = 0; i < VXA_SOCK_SIZE; i++) {
24744 ++ for (j = 0; j < 3; j++) {
24745 ++ atomic_set(&cacct->sock[i][j].count, 0);
24746 ++ atomic_set(&cacct->sock[i][j].total, 0);
24747 ++ }
24748 ++ }
24749 ++ for (i = 0; i < 8; i++)
24750 ++ atomic_set(&cacct->slab[i], 0);
24751 ++ for (i = 0; i < 5; i++)
24752 ++ for (j = 0; j < 4; j++)
24753 ++ atomic_set(&cacct->page[i][j], 0);
24754 ++}
24755 ++
24756 ++static inline void vx_info_exit_cacct(struct _vx_cacct *cacct)
24757 ++{
24758 ++ return;
24759 ++}
24760 ++
24761 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/cacct_proc.h linux-2.6.22.19-vs2.3.0.34/kernel/vserver/cacct_proc.h
24762 +--- linux-2.6.22.19/kernel/vserver/cacct_proc.h 1970-01-01 01:00:00 +0100
24763 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/cacct_proc.h 2007-08-05 20:53:13 +0200
24764 +@@ -0,0 +1,53 @@
24765 ++#ifndef _VX_CACCT_PROC_H
24766 ++#define _VX_CACCT_PROC_H
24767 ++
24768 ++#include <linux/vserver/cacct_int.h>
24769 ++
24770 ++
24771 ++#define VX_SOCKA_TOP \
24772 ++ "Type\t recv #/bytes\t\t send #/bytes\t\t fail #/bytes\n"
24773 ++
24774 ++static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer)
24775 ++{
24776 ++ int i, j, length = 0;
24777 ++ static char *type[VXA_SOCK_SIZE] = {
24778 ++ "UNSPEC", "UNIX", "INET", "INET6", "PACKET", "OTHER"
24779 ++ };
24780 ++
24781 ++ length += sprintf(buffer + length, VX_SOCKA_TOP);
24782 ++ for (i = 0; i < VXA_SOCK_SIZE; i++) {
24783 ++ length += sprintf(buffer + length, "%s:", type[i]);
24784 ++ for (j = 0; j < 3; j++) {
24785 ++ length += sprintf(buffer + length,
24786 ++ "\t%10lu/%-10lu",
24787 ++ vx_sock_count(cacct, i, j),
24788 ++ vx_sock_total(cacct, i, j));
24789 ++ }
24790 ++ buffer[length++] = '\n';
24791 ++ }
24792 ++
24793 ++ length += sprintf(buffer + length, "\n");
24794 ++ length += sprintf(buffer + length,
24795 ++ "slab:\t %8u %8u %8u %8u\n",
24796 ++ atomic_read(&cacct->slab[1]),
24797 ++ atomic_read(&cacct->slab[4]),
24798 ++ atomic_read(&cacct->slab[0]),
24799 ++ atomic_read(&cacct->slab[2]));
24800 ++
24801 ++ length += sprintf(buffer + length, "\n");
24802 ++ for (i = 0; i < 5; i++) {
24803 ++ length += sprintf(buffer + length,
24804 ++ "page[%d]: %8u %8u %8u %8u\t %8u %8u %8u %8u\n", i,
24805 ++ atomic_read(&cacct->page[i][0]),
24806 ++ atomic_read(&cacct->page[i][1]),
24807 ++ atomic_read(&cacct->page[i][2]),
24808 ++ atomic_read(&cacct->page[i][3]),
24809 ++ atomic_read(&cacct->page[i][4]),
24810 ++ atomic_read(&cacct->page[i][5]),
24811 ++ atomic_read(&cacct->page[i][6]),
24812 ++ atomic_read(&cacct->page[i][7]));
24813 ++ }
24814 ++ return length;
24815 ++}
24816 ++
24817 ++#endif /* _VX_CACCT_PROC_H */
24818 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/context.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/context.c
24819 +--- linux-2.6.22.19/kernel/vserver/context.c 1970-01-01 01:00:00 +0100
24820 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/context.c 2008-01-19 01:28:23 +0100
24821 +@@ -0,0 +1,964 @@
24822 ++/*
24823 ++ * linux/kernel/vserver/context.c
24824 ++ *
24825 ++ * Virtual Server: Context Support
24826 ++ *
24827 ++ * Copyright (C) 2003-2007 Herbert Pötzl
24828 ++ *
24829 ++ * V0.01 context helper
24830 ++ * V0.02 vx_ctx_kill syscall command
24831 ++ * V0.03 replaced context_info calls
24832 ++ * V0.04 redesign of struct (de)alloc
24833 ++ * V0.05 rlimit basic implementation
24834 ++ * V0.06 task_xid and info commands
24835 ++ * V0.07 context flags and caps
24836 ++ * V0.08 switch to RCU based hash
24837 ++ * V0.09 revert to non RCU for now
24838 ++ * V0.10 and back to working RCU hash
24839 ++ * V0.11 and back to locking again
24840 ++ * V0.12 referenced context store
24841 ++ * V0.13 separate per cpu data
24842 ++ * V0.14 changed vcmds to vxi arg
24843 ++ * V0.15 added context stat
24844 ++ * V0.16 have __create claim() the vxi
24845 ++ * V0.17 removed older and legacy stuff
24846 ++ *
24847 ++ */
24848 ++
24849 ++#include <linux/slab.h>
24850 ++#include <linux/types.h>
24851 ++#include <linux/pid_namespace.h>
24852 ++
24853 ++#include <linux/vserver/context.h>
24854 ++#include <linux/vserver/network.h>
24855 ++#include <linux/vserver/debug.h>
24856 ++#include <linux/vserver/limit.h>
24857 ++#include <linux/vserver/limit_int.h>
24858 ++#include <linux/vserver/space.h>
24859 ++
24860 ++#include <linux/vs_context.h>
24861 ++#include <linux/vs_limit.h>
24862 ++#include <linux/vserver/context_cmd.h>
24863 ++
24864 ++#include "cvirt_init.h"
24865 ++#include "cacct_init.h"
24866 ++#include "limit_init.h"
24867 ++#include "sched_init.h"
24868 ++
24869 ++
24870 ++atomic_t vx_global_ctotal = ATOMIC_INIT(0);
24871 ++atomic_t vx_global_cactive = ATOMIC_INIT(0);
24872 ++
24873 ++
24874 ++/* now inactive context structures */
24875 ++
24876 ++static struct hlist_head vx_info_inactive = HLIST_HEAD_INIT;
24877 ++
24878 ++static spinlock_t vx_info_inactive_lock = SPIN_LOCK_UNLOCKED;
24879 ++
24880 ++
24881 ++/* __alloc_vx_info()
24882 ++
24883 ++ * allocate an initialized vx_info struct
24884 ++ * doesn't make it visible (hash) */
24885 ++
24886 ++static struct vx_info *__alloc_vx_info(xid_t xid)
24887 ++{
24888 ++ struct vx_info *new = NULL;
24889 ++ int cpu;
24890 ++
24891 ++ vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid);
24892 ++
24893 ++ /* would this benefit from a slab cache? */
24894 ++ new = kmalloc(sizeof(struct vx_info), GFP_KERNEL);
24895 ++ if (!new)
24896 ++ return 0;
24897 ++
24898 ++ memset(new, 0, sizeof(struct vx_info));
24899 ++#ifdef CONFIG_SMP
24900 ++ new->ptr_pc = alloc_percpu(struct _vx_info_pc);
24901 ++ if (!new->ptr_pc)
24902 ++ goto error;
24903 ++#endif
24904 ++ new->vx_id = xid;
24905 ++ INIT_HLIST_NODE(&new->vx_hlist);
24906 ++ atomic_set(&new->vx_usecnt, 0);
24907 ++ atomic_set(&new->vx_tasks, 0);
24908 ++ new->vx_parent = NULL;
24909 ++ new->vx_state = 0;
24910 ++ init_waitqueue_head(&new->vx_wait);
24911 ++
24912 ++ /* prepare reaper */
24913 ++ get_task_struct(init_pid_ns.child_reaper);
24914 ++ new->vx_reaper = init_pid_ns.child_reaper;
24915 ++ new->vx_badness_bias = 0;
24916 ++
24917 ++ /* rest of init goes here */
24918 ++ vx_info_init_limit(&new->limit);
24919 ++ vx_info_init_sched(&new->sched);
24920 ++ vx_info_init_cvirt(&new->cvirt);
24921 ++ vx_info_init_cacct(&new->cacct);
24922 ++
24923 ++ /* per cpu data structures */
24924 ++ for_each_possible_cpu(cpu) {
24925 ++ vx_info_init_sched_pc(
24926 ++ &vx_per_cpu(new, sched_pc, cpu), cpu);
24927 ++ vx_info_init_cvirt_pc(
24928 ++ &vx_per_cpu(new, cvirt_pc, cpu), cpu);
24929 ++ }
24930 ++
24931 ++ new->vx_flags = VXF_INIT_SET;
24932 ++ new->vx_bcaps = CAP_INIT_EFF_SET;
24933 ++ new->vx_ccaps = 0;
24934 ++ new->vx_cap_bset = cap_bset;
24935 ++
24936 ++ new->reboot_cmd = 0;
24937 ++ new->exit_code = 0;
24938 ++
24939 ++ vxdprintk(VXD_CBIT(xid, 0),
24940 ++ "alloc_vx_info(%d) = %p", xid, new);
24941 ++ vxh_alloc_vx_info(new);
24942 ++ atomic_inc(&vx_global_ctotal);
24943 ++ return new;
24944 ++#ifdef CONFIG_SMP
24945 ++error:
24946 ++ kfree(new);
24947 ++ return 0;
24948 ++#endif
24949 ++}
24950 ++
24951 ++/* __dealloc_vx_info()
24952 ++
24953 ++ * final disposal of vx_info */
24954 ++
24955 ++static void __dealloc_vx_info(struct vx_info *vxi)
24956 ++{
24957 ++ int cpu;
24958 ++
24959 ++ vxdprintk(VXD_CBIT(xid, 0),
24960 ++ "dealloc_vx_info(%p)", vxi);
24961 ++ vxh_dealloc_vx_info(vxi);
24962 ++
24963 ++ vxi->vx_id = -1;
24964 ++
24965 ++ vx_info_exit_limit(&vxi->limit);
24966 ++ vx_info_exit_sched(&vxi->sched);
24967 ++ vx_info_exit_cvirt(&vxi->cvirt);
24968 ++ vx_info_exit_cacct(&vxi->cacct);
24969 ++
24970 ++ for_each_possible_cpu(cpu) {
24971 ++ vx_info_exit_sched_pc(
24972 ++ &vx_per_cpu(vxi, sched_pc, cpu), cpu);
24973 ++ vx_info_exit_cvirt_pc(
24974 ++ &vx_per_cpu(vxi, cvirt_pc, cpu), cpu);
24975 ++ }
24976 ++
24977 ++ vxi->vx_state |= VXS_RELEASED;
24978 ++
24979 ++#ifdef CONFIG_SMP
24980 ++ free_percpu(vxi->ptr_pc);
24981 ++#endif
24982 ++ kfree(vxi);
24983 ++ atomic_dec(&vx_global_ctotal);
24984 ++}
24985 ++
24986 ++static void __shutdown_vx_info(struct vx_info *vxi)
24987 ++{
24988 ++ struct nsproxy *nsproxy;
24989 ++ struct fs_struct *fs;
24990 ++
24991 ++ might_sleep();
24992 ++
24993 ++ vxi->vx_state |= VXS_SHUTDOWN;
24994 ++ vs_state_change(vxi, VSC_SHUTDOWN);
24995 ++
24996 ++ nsproxy = xchg(&vxi->vx_nsproxy, NULL);
24997 ++ fs = xchg(&vxi->vx_fs, NULL);
24998 ++
24999 ++ if (nsproxy)
25000 ++ put_nsproxy(nsproxy);
25001 ++ if (fs)
25002 ++ put_fs_struct(fs);
25003 ++}
25004 ++
25005 ++/* exported stuff */
25006 ++
25007 ++void free_vx_info(struct vx_info *vxi)
25008 ++{
25009 ++ unsigned long flags;
25010 ++
25011 ++ /* check for reference counts first */
25012 ++ BUG_ON(atomic_read(&vxi->vx_usecnt));
25013 ++ BUG_ON(atomic_read(&vxi->vx_tasks));
25014 ++
25015 ++ /* context must not be hashed */
25016 ++ BUG_ON(vx_info_state(vxi, VXS_HASHED));
25017 ++
25018 ++ /* context shutdown is mandatory */
25019 ++ BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN));
25020 ++
25021 ++ BUG_ON(vxi->vx_nsproxy);
25022 ++ BUG_ON(vxi->vx_fs);
25023 ++
25024 ++ spin_lock_irqsave(&vx_info_inactive_lock, flags);
25025 ++ hlist_del(&vxi->vx_hlist);
25026 ++ spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
25027 ++
25028 ++ __dealloc_vx_info(vxi);
25029 ++}
25030 ++
25031 ++
25032 ++/* hash table for vx_info hash */
25033 ++
25034 ++#define VX_HASH_SIZE 13
25035 ++
25036 ++static struct hlist_head vx_info_hash[VX_HASH_SIZE] =
25037 ++ { [0 ... VX_HASH_SIZE-1] = HLIST_HEAD_INIT };
25038 ++
25039 ++static spinlock_t vx_info_hash_lock = SPIN_LOCK_UNLOCKED;
25040 ++
25041 ++
25042 ++static inline unsigned int __hashval(xid_t xid)
25043 ++{
25044 ++ return (xid % VX_HASH_SIZE);
25045 ++}
25046 ++
25047 ++
25048 ++
25049 ++/* __hash_vx_info()
25050 ++
25051 ++ * add the vxi to the global hash table
25052 ++ * requires the hash_lock to be held */
25053 ++
25054 ++static inline void __hash_vx_info(struct vx_info *vxi)
25055 ++{
25056 ++ struct hlist_head *head;
25057 ++
25058 ++ vxd_assert_lock(&vx_info_hash_lock);
25059 ++ vxdprintk(VXD_CBIT(xid, 4),
25060 ++ "__hash_vx_info: %p[#%d]", vxi, vxi->vx_id);
25061 ++ vxh_hash_vx_info(vxi);
25062 ++
25063 ++ /* context must not be hashed */
25064 ++ BUG_ON(vx_info_state(vxi, VXS_HASHED));
25065 ++
25066 ++ vxi->vx_state |= VXS_HASHED;
25067 ++ head = &vx_info_hash[__hashval(vxi->vx_id)];
25068 ++ hlist_add_head(&vxi->vx_hlist, head);
25069 ++ atomic_inc(&vx_global_cactive);
25070 ++}
25071 ++
25072 ++/* __unhash_vx_info()
25073 ++
25074 ++ * remove the vxi from the global hash table
25075 ++ * requires the hash_lock to be held */
25076 ++
25077 ++static inline void __unhash_vx_info(struct vx_info *vxi)
25078 ++{
25079 ++ unsigned long flags;
25080 ++
25081 ++ vxd_assert_lock(&vx_info_hash_lock);
25082 ++ vxdprintk(VXD_CBIT(xid, 4),
25083 ++ "__unhash_vx_info: %p[#%d.%d.%d]", vxi, vxi->vx_id,
25084 ++ atomic_read(&vxi->vx_usecnt), atomic_read(&vxi->vx_tasks));
25085 ++ vxh_unhash_vx_info(vxi);
25086 ++
25087 ++ /* context must be hashed */
25088 ++ BUG_ON(!vx_info_state(vxi, VXS_HASHED));
25089 ++ /* but without tasks */
25090 ++ BUG_ON(atomic_read(&vxi->vx_tasks));
25091 ++
25092 ++ vxi->vx_state &= ~VXS_HASHED;
25093 ++ hlist_del_init(&vxi->vx_hlist);
25094 ++ spin_lock_irqsave(&vx_info_inactive_lock, flags);
25095 ++ hlist_add_head(&vxi->vx_hlist, &vx_info_inactive);
25096 ++ spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
25097 ++ atomic_dec(&vx_global_cactive);
25098 ++}
25099 ++
25100 ++
25101 ++/* __lookup_vx_info()
25102 ++
25103 ++ * requires the hash_lock to be held
25104 ++ * doesn't increment the vx_refcnt */
25105 ++
25106 ++static inline struct vx_info *__lookup_vx_info(xid_t xid)
25107 ++{
25108 ++ struct hlist_head *head = &vx_info_hash[__hashval(xid)];
25109 ++ struct hlist_node *pos;
25110 ++ struct vx_info *vxi;
25111 ++
25112 ++ vxd_assert_lock(&vx_info_hash_lock);
25113 ++ hlist_for_each(pos, head) {
25114 ++ vxi = hlist_entry(pos, struct vx_info, vx_hlist);
25115 ++
25116 ++ if (vxi->vx_id == xid)
25117 ++ goto found;
25118 ++ }
25119 ++ vxi = NULL;
25120 ++found:
25121 ++ vxdprintk(VXD_CBIT(xid, 0),
25122 ++ "__lookup_vx_info(#%u): %p[#%u]",
25123 ++ xid, vxi, vxi ? vxi->vx_id : 0);
25124 ++ vxh_lookup_vx_info(vxi, xid);
25125 ++ return vxi;
25126 ++}
25127 ++
25128 ++
25129 ++/* __create_vx_info()
25130 ++
25131 ++ * create the requested context
25132 ++ * get(), claim() and hash it */
25133 ++
25134 ++static struct vx_info *__create_vx_info(int id)
25135 ++{
25136 ++ struct vx_info *new, *vxi = NULL;
25137 ++
25138 ++ vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id);
25139 ++
25140 ++ if (!(new = __alloc_vx_info(id)))
25141 ++ return ERR_PTR(-ENOMEM);
25142 ++
25143 ++ /* required to make dynamic xids unique */
25144 ++ spin_lock(&vx_info_hash_lock);
25145 ++
25146 ++ /* static context requested */
25147 ++ if ((vxi = __lookup_vx_info(id))) {
25148 ++ vxdprintk(VXD_CBIT(xid, 0),
25149 ++ "create_vx_info(%d) = %p (already there)", id, vxi);
25150 ++ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0))
25151 ++ vxi = ERR_PTR(-EBUSY);
25152 ++ else
25153 ++ vxi = ERR_PTR(-EEXIST);
25154 ++ goto out_unlock;
25155 ++ }
25156 ++ /* new context */
25157 ++ vxdprintk(VXD_CBIT(xid, 0),
25158 ++ "create_vx_info(%d) = %p (new)", id, new);
25159 ++ claim_vx_info(new, NULL);
25160 ++ __hash_vx_info(get_vx_info(new));
25161 ++ vxi = new, new = NULL;
25162 ++
25163 ++out_unlock:
25164 ++ spin_unlock(&vx_info_hash_lock);
25165 ++ vxh_create_vx_info(IS_ERR(vxi) ? NULL : vxi, id);
25166 ++ if (new)
25167 ++ __dealloc_vx_info(new);
25168 ++ return vxi;
25169 ++}
25170 ++
25171 ++
25172 ++/* exported stuff */
25173 ++
25174 ++
25175 ++void unhash_vx_info(struct vx_info *vxi)
25176 ++{
25177 ++ __shutdown_vx_info(vxi);
25178 ++ spin_lock(&vx_info_hash_lock);
25179 ++ __unhash_vx_info(vxi);
25180 ++ spin_unlock(&vx_info_hash_lock);
25181 ++ __wakeup_vx_info(vxi);
25182 ++}
25183 ++
25184 ++
25185 ++/* lookup_vx_info()
25186 ++
25187 ++ * search for a vx_info and get() it
25188 ++ * negative id means current */
25189 ++
25190 ++struct vx_info *lookup_vx_info(int id)
25191 ++{
25192 ++ struct vx_info *vxi = NULL;
25193 ++
25194 ++ if (id < 0) {
25195 ++ vxi = get_vx_info(current->vx_info);
25196 ++ } else if (id > 1) {
25197 ++ spin_lock(&vx_info_hash_lock);
25198 ++ vxi = get_vx_info(__lookup_vx_info(id));
25199 ++ spin_unlock(&vx_info_hash_lock);
25200 ++ }
25201 ++ return vxi;
25202 ++}
25203 ++
25204 ++/* xid_is_hashed()
25205 ++
25206 ++ * verify that xid is still hashed */
25207 ++
25208 ++int xid_is_hashed(xid_t xid)
25209 ++{
25210 ++ int hashed;
25211 ++
25212 ++ spin_lock(&vx_info_hash_lock);
25213 ++ hashed = (__lookup_vx_info(xid) != NULL);
25214 ++ spin_unlock(&vx_info_hash_lock);
25215 ++ return hashed;
25216 ++}
25217 ++
25218 ++#ifdef CONFIG_PROC_FS
25219 ++
25220 ++/* get_xid_list()
25221 ++
25222 ++ * get a subset of hashed xids for proc
25223 ++ * assumes size is at least one */
25224 ++
25225 ++int get_xid_list(int index, unsigned int *xids, int size)
25226 ++{
25227 ++ int hindex, nr_xids = 0;
25228 ++
25229 ++ /* only show current and children */
25230 ++ if (!vx_check(0, VS_ADMIN | VS_WATCH)) {
25231 ++ if (index > 0)
25232 ++ return 0;
25233 ++ xids[nr_xids] = vx_current_xid();
25234 ++ return 1;
25235 ++ }
25236 ++
25237 ++ for (hindex = 0; hindex < VX_HASH_SIZE; hindex++) {
25238 ++ struct hlist_head *head = &vx_info_hash[hindex];
25239 ++ struct hlist_node *pos;
25240 ++
25241 ++ spin_lock(&vx_info_hash_lock);
25242 ++ hlist_for_each(pos, head) {
25243 ++ struct vx_info *vxi;
25244 ++
25245 ++ if (--index > 0)
25246 ++ continue;
25247 ++
25248 ++ vxi = hlist_entry(pos, struct vx_info, vx_hlist);
25249 ++ xids[nr_xids] = vxi->vx_id;
25250 ++ if (++nr_xids >= size) {
25251 ++ spin_unlock(&vx_info_hash_lock);
25252 ++ goto out;
25253 ++ }
25254 ++ }
25255 ++ /* keep the lock time short */
25256 ++ spin_unlock(&vx_info_hash_lock);
25257 ++ }
25258 ++out:
25259 ++ return nr_xids;
25260 ++}
25261 ++#endif
25262 ++
25263 ++#ifdef CONFIG_VSERVER_DEBUG
25264 ++
25265 ++void dump_vx_info_inactive(int level)
25266 ++{
25267 ++ struct hlist_node *entry, *next;
25268 ++
25269 ++ hlist_for_each_safe(entry, next, &vx_info_inactive) {
25270 ++ struct vx_info *vxi =
25271 ++ list_entry(entry, struct vx_info, vx_hlist);
25272 ++
25273 ++ dump_vx_info(vxi, level);
25274 ++ }
25275 ++}
25276 ++
25277 ++#endif
25278 ++
25279 ++int vx_migrate_user(struct task_struct *p, struct vx_info *vxi)
25280 ++{
25281 ++ struct user_struct *new_user, *old_user;
25282 ++
25283 ++ if (!p || !vxi)
25284 ++ BUG();
25285 ++
25286 ++ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
25287 ++ return -EACCES;
25288 ++
25289 ++ new_user = alloc_uid(vxi->vx_id, p->uid);
25290 ++ if (!new_user)
25291 ++ return -ENOMEM;
25292 ++
25293 ++ old_user = p->user;
25294 ++ if (new_user != old_user) {
25295 ++ atomic_inc(&new_user->processes);
25296 ++ atomic_dec(&old_user->processes);
25297 ++ p->user = new_user;
25298 ++ }
25299 ++ free_uid(old_user);
25300 ++ return 0;
25301 ++}
25302 ++
25303 ++void vx_mask_cap_bset(struct vx_info *vxi, struct task_struct *p)
25304 ++{
25305 ++ p->cap_effective &= vxi->vx_cap_bset;
25306 ++ p->cap_inheritable &= vxi->vx_cap_bset;
25307 ++ p->cap_permitted &= vxi->vx_cap_bset;
25308 ++}
25309 ++
25310 ++
25311 ++#include <linux/file.h>
25312 ++
25313 ++static int vx_openfd_task(struct task_struct *tsk)
25314 ++{
25315 ++ struct files_struct *files = tsk->files;
25316 ++ struct fdtable *fdt;
25317 ++ const unsigned long *bptr;
25318 ++ int count, total;
25319 ++
25320 ++ /* no rcu_read_lock() because of spin_lock() */
25321 ++ spin_lock(&files->file_lock);
25322 ++ fdt = files_fdtable(files);
25323 ++ bptr = fdt->open_fds->fds_bits;
25324 ++ count = fdt->max_fds / (sizeof(unsigned long) * 8);
25325 ++ for (total = 0; count > 0; count--) {
25326 ++ if (*bptr)
25327 ++ total += hweight_long(*bptr);
25328 ++ bptr++;
25329 ++ }
25330 ++ spin_unlock(&files->file_lock);
25331 ++ return total;
25332 ++}
25333 ++
25334 ++
25335 ++/* for *space compatibility */
25336 ++
25337 ++asmlinkage long sys_unshare(unsigned long);
25338 ++
25339 ++/*
25340 ++ * migrate task to new context
25341 ++ * gets vxi, puts old_vxi on change
25342 ++ * optionally unshares namespaces (hack)
25343 ++ */
25344 ++
25345 ++int vx_migrate_task(struct task_struct *p, struct vx_info *vxi, int unshare)
25346 ++{
25347 ++ struct vx_info *old_vxi;
25348 ++ int ret = 0;
25349 ++
25350 ++ if (!p || !vxi)
25351 ++ BUG();
25352 ++
25353 ++ vxdprintk(VXD_CBIT(xid, 5),
25354 ++ "vx_migrate_task(%p,%p[#%d.%d])", p, vxi,
25355 ++ vxi->vx_id, atomic_read(&vxi->vx_usecnt));
25356 ++
25357 ++ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0) &&
25358 ++ !vx_info_flags(vxi, VXF_STATE_SETUP, 0))
25359 ++ return -EACCES;
25360 ++
25361 ++ if (vx_info_state(vxi, VXS_SHUTDOWN))
25362 ++ return -EFAULT;
25363 ++
25364 ++ old_vxi = task_get_vx_info(p);
25365 ++ if (old_vxi == vxi)
25366 ++ goto out;
25367 ++
25368 ++ if (!(ret = vx_migrate_user(p, vxi))) {
25369 ++ int openfd;
25370 ++
25371 ++ task_lock(p);
25372 ++ openfd = vx_openfd_task(p);
25373 ++
25374 ++ if (old_vxi) {
25375 ++ atomic_dec(&old_vxi->cvirt.nr_threads);
25376 ++ atomic_dec(&old_vxi->cvirt.nr_running);
25377 ++ __rlim_dec(&old_vxi->limit, RLIMIT_NPROC);
25378 ++ /* FIXME: what about the struct files here? */
25379 ++ __rlim_sub(&old_vxi->limit, VLIMIT_OPENFD, openfd);
25380 ++ /* account for the executable */
25381 ++ __rlim_dec(&old_vxi->limit, VLIMIT_DENTRY);
25382 ++ }
25383 ++ atomic_inc(&vxi->cvirt.nr_threads);
25384 ++ atomic_inc(&vxi->cvirt.nr_running);
25385 ++ __rlim_inc(&vxi->limit, RLIMIT_NPROC);
25386 ++ /* FIXME: what about the struct files here? */
25387 ++ __rlim_add(&vxi->limit, VLIMIT_OPENFD, openfd);
25388 ++ /* account for the executable */
25389 ++ __rlim_inc(&vxi->limit, VLIMIT_DENTRY);
25390 ++
25391 ++ if (old_vxi) {
25392 ++ release_vx_info(old_vxi, p);
25393 ++ clr_vx_info(&p->vx_info);
25394 ++ }
25395 ++ claim_vx_info(vxi, p);
25396 ++ set_vx_info(&p->vx_info, vxi);
25397 ++ p->xid = vxi->vx_id;
25398 ++
25399 ++ vxdprintk(VXD_CBIT(xid, 5),
25400 ++ "moved task %p into vxi:%p[#%d]",
25401 ++ p, vxi, vxi->vx_id);
25402 ++
25403 ++ vx_mask_cap_bset(vxi, p);
25404 ++ task_unlock(p);
25405 ++
25406 ++ /* hack for *spaces to provide compatibility */
25407 ++ if (unshare) {
25408 ++ struct nsproxy *old_nsp, *new_nsp;
25409 ++
25410 ++ ret = unshare_nsproxy_namespaces(
25411 ++ CLONE_NEWUTS | CLONE_NEWIPC,
25412 ++ &new_nsp, NULL);
25413 ++ if (ret)
25414 ++ goto out;
25415 ++
25416 ++ old_nsp = xchg(&p->nsproxy, new_nsp);
25417 ++ vx_set_space(vxi, CLONE_NEWUTS | CLONE_NEWIPC);
25418 ++ put_nsproxy(old_nsp);
25419 ++ }
25420 ++ }
25421 ++out:
25422 ++ put_vx_info(old_vxi);
25423 ++ return ret;
25424 ++}
25425 ++
25426 ++int vx_set_reaper(struct vx_info *vxi, struct task_struct *p)
25427 ++{
25428 ++ struct task_struct *old_reaper;
25429 ++
25430 ++ if (!vxi)
25431 ++ return -EINVAL;
25432 ++
25433 ++ vxdprintk(VXD_CBIT(xid, 6),
25434 ++ "vx_set_reaper(%p[#%d],%p[#%d,%d])",
25435 ++ vxi, vxi->vx_id, p, p->xid, p->pid);
25436 ++
25437 ++ old_reaper = vxi->vx_reaper;
25438 ++ if (old_reaper == p)
25439 ++ return 0;
25440 ++
25441 ++ /* set new child reaper */
25442 ++ get_task_struct(p);
25443 ++ vxi->vx_reaper = p;
25444 ++ put_task_struct(old_reaper);
25445 ++ return 0;
25446 ++}
25447 ++
25448 ++int vx_set_init(struct vx_info *vxi, struct task_struct *p)
25449 ++{
25450 ++ if (!vxi)
25451 ++ return -EINVAL;
25452 ++
25453 ++ vxdprintk(VXD_CBIT(xid, 6),
25454 ++ "vx_set_init(%p[#%d],%p[#%d,%d,%d])",
25455 ++ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
25456 ++
25457 ++ vxi->vx_flags &= ~VXF_STATE_INIT;
25458 ++ vxi->vx_initpid = p->tgid;
25459 ++ return 0;
25460 ++}
25461 ++
25462 ++void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code)
25463 ++{
25464 ++ vxdprintk(VXD_CBIT(xid, 6),
25465 ++ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])",
25466 ++ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
25467 ++
25468 ++ vxi->exit_code = code;
25469 ++ vxi->vx_initpid = 0;
25470 ++}
25471 ++
25472 ++
25473 ++void vx_set_persistent(struct vx_info *vxi)
25474 ++{
25475 ++ vxdprintk(VXD_CBIT(xid, 6),
25476 ++ "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id);
25477 ++
25478 ++ get_vx_info(vxi);
25479 ++ claim_vx_info(vxi, NULL);
25480 ++}
25481 ++
25482 ++void vx_clear_persistent(struct vx_info *vxi)
25483 ++{
25484 ++ vxdprintk(VXD_CBIT(xid, 6),
25485 ++ "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id);
25486 ++
25487 ++ release_vx_info(vxi, NULL);
25488 ++ put_vx_info(vxi);
25489 ++}
25490 ++
25491 ++void vx_update_persistent(struct vx_info *vxi)
25492 ++{
25493 ++ if (vx_info_flags(vxi, VXF_PERSISTENT, 0))
25494 ++ vx_set_persistent(vxi);
25495 ++ else
25496 ++ vx_clear_persistent(vxi);
25497 ++}
25498 ++
25499 ++
25500 ++/* task must be current or locked */
25501 ++
25502 ++void exit_vx_info(struct task_struct *p, int code)
25503 ++{
25504 ++ struct vx_info *vxi = p->vx_info;
25505 ++
25506 ++ if (vxi) {
25507 ++ atomic_dec(&vxi->cvirt.nr_threads);
25508 ++ vx_nproc_dec(p);
25509 ++
25510 ++ vxi->exit_code = code;
25511 ++ release_vx_info(vxi, p);
25512 ++ }
25513 ++}
25514 ++
25515 ++void exit_vx_info_early(struct task_struct *p, int code)
25516 ++{
25517 ++ struct vx_info *vxi = p->vx_info;
25518 ++
25519 ++ if (vxi) {
25520 ++ if (vxi->vx_initpid == p->tgid)
25521 ++ vx_exit_init(vxi, p, code);
25522 ++ if (vxi->vx_reaper == p)
25523 ++ vx_set_reaper(vxi, init_pid_ns.child_reaper);
25524 ++ }
25525 ++}
25526 ++
25527 ++
25528 ++/* vserver syscall commands below here */
25529 ++
25530 ++/* taks xid and vx_info functions */
25531 ++
25532 ++#include <asm/uaccess.h>
25533 ++
25534 ++
25535 ++int vc_task_xid(uint32_t id)
25536 ++{
25537 ++ xid_t xid;
25538 ++
25539 ++ if (id) {
25540 ++ struct task_struct *tsk;
25541 ++
25542 ++ read_lock(&tasklist_lock);
25543 ++ tsk = find_task_by_real_pid(id);
25544 ++ xid = (tsk) ? tsk->xid : -ESRCH;
25545 ++ read_unlock(&tasklist_lock);
25546 ++ } else
25547 ++ xid = vx_current_xid();
25548 ++ return xid;
25549 ++}
25550 ++
25551 ++
25552 ++int vc_vx_info(struct vx_info *vxi, void __user *data)
25553 ++{
25554 ++ struct vcmd_vx_info_v0 vc_data;
25555 ++
25556 ++ vc_data.xid = vxi->vx_id;
25557 ++ vc_data.initpid = vxi->vx_initpid;
25558 ++
25559 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
25560 ++ return -EFAULT;
25561 ++ return 0;
25562 ++}
25563 ++
25564 ++
25565 ++int vc_ctx_stat(struct vx_info *vxi, void __user *data)
25566 ++{
25567 ++ struct vcmd_ctx_stat_v0 vc_data;
25568 ++
25569 ++ vc_data.usecnt = atomic_read(&vxi->vx_usecnt);
25570 ++ vc_data.tasks = atomic_read(&vxi->vx_tasks);
25571 ++
25572 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
25573 ++ return -EFAULT;
25574 ++ return 0;
25575 ++}
25576 ++
25577 ++
25578 ++/* context functions */
25579 ++
25580 ++int vc_ctx_create(uint32_t xid, void __user *data)
25581 ++{
25582 ++ struct vcmd_ctx_create vc_data = { .flagword = VXF_INIT_SET };
25583 ++ struct vx_info *new_vxi;
25584 ++ int ret;
25585 ++
25586 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
25587 ++ return -EFAULT;
25588 ++
25589 ++ if ((xid > MAX_S_CONTEXT) || (xid < 2))
25590 ++ return -EINVAL;
25591 ++
25592 ++ new_vxi = __create_vx_info(xid);
25593 ++ if (IS_ERR(new_vxi))
25594 ++ return PTR_ERR(new_vxi);
25595 ++
25596 ++ /* initial flags */
25597 ++ new_vxi->vx_flags = vc_data.flagword;
25598 ++
25599 ++ ret = -ENOEXEC;
25600 ++ if (vs_state_change(new_vxi, VSC_STARTUP))
25601 ++ goto out;
25602 ++
25603 ++ ret = vx_migrate_task(current, new_vxi, (!data));
25604 ++ if (ret)
25605 ++ goto out;
25606 ++
25607 ++ /* return context id on success */
25608 ++ ret = new_vxi->vx_id;
25609 ++
25610 ++ /* get a reference for persistent contexts */
25611 ++ if ((vc_data.flagword & VXF_PERSISTENT))
25612 ++ vx_set_persistent(new_vxi);
25613 ++out:
25614 ++ release_vx_info(new_vxi, NULL);
25615 ++ put_vx_info(new_vxi);
25616 ++ return ret;
25617 ++}
25618 ++
25619 ++
25620 ++int vc_ctx_migrate(struct vx_info *vxi, void __user *data)
25621 ++{
25622 ++ struct vcmd_ctx_migrate vc_data = { .flagword = 0 };
25623 ++ int ret;
25624 ++
25625 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
25626 ++ return -EFAULT;
25627 ++
25628 ++ ret = vx_migrate_task(current, vxi, 0);
25629 ++ if (ret)
25630 ++ return ret;
25631 ++ if (vc_data.flagword & VXM_SET_INIT)
25632 ++ ret = vx_set_init(vxi, current);
25633 ++ if (ret)
25634 ++ return ret;
25635 ++ if (vc_data.flagword & VXM_SET_REAPER)
25636 ++ ret = vx_set_reaper(vxi, current);
25637 ++ return ret;
25638 ++}
25639 ++
25640 ++
25641 ++int vc_get_cflags(struct vx_info *vxi, void __user *data)
25642 ++{
25643 ++ struct vcmd_ctx_flags_v0 vc_data;
25644 ++
25645 ++ vc_data.flagword = vxi->vx_flags;
25646 ++
25647 ++ /* special STATE flag handling */
25648 ++ vc_data.mask = vs_mask_flags(~0ULL, vxi->vx_flags, VXF_ONE_TIME);
25649 ++
25650 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
25651 ++ return -EFAULT;
25652 ++ return 0;
25653 ++}
25654 ++
25655 ++int vc_set_cflags(struct vx_info *vxi, void __user *data)
25656 ++{
25657 ++ struct vcmd_ctx_flags_v0 vc_data;
25658 ++ uint64_t mask, trigger;
25659 ++
25660 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
25661 ++ return -EFAULT;
25662 ++
25663 ++ /* special STATE flag handling */
25664 ++ mask = vs_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME);
25665 ++ trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword);
25666 ++
25667 ++ if (vxi == current->vx_info) {
25668 ++ if (trigger & VXF_STATE_SETUP)
25669 ++ vx_mask_cap_bset(vxi, current);
25670 ++ if (trigger & VXF_STATE_INIT) {
25671 ++ int ret;
25672 ++
25673 ++ ret = vx_set_init(vxi, current);
25674 ++ if (ret)
25675 ++ return ret;
25676 ++ ret = vx_set_reaper(vxi, current);
25677 ++ if (ret)
25678 ++ return ret;
25679 ++ }
25680 ++ }
25681 ++
25682 ++ vxi->vx_flags = vs_mask_flags(vxi->vx_flags,
25683 ++ vc_data.flagword, mask);
25684 ++ if (trigger & VXF_PERSISTENT)
25685 ++ vx_update_persistent(vxi);
25686 ++
25687 ++ return 0;
25688 ++}
25689 ++
25690 ++static int do_get_caps(struct vx_info *vxi, uint64_t *bcaps, uint64_t *ccaps)
25691 ++{
25692 ++ if (bcaps)
25693 ++ *bcaps = vxi->vx_bcaps;
25694 ++ if (ccaps)
25695 ++ *ccaps = vxi->vx_ccaps;
25696 ++
25697 ++ return 0;
25698 ++}
25699 ++
25700 ++int vc_get_ccaps(struct vx_info *vxi, void __user *data)
25701 ++{
25702 ++ struct vcmd_ctx_caps_v1 vc_data;
25703 ++ int ret;
25704 ++
25705 ++ ret = do_get_caps(vxi, NULL, &vc_data.ccaps);
25706 ++ if (ret)
25707 ++ return ret;
25708 ++ vc_data.cmask = ~0ULL;
25709 ++
25710 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
25711 ++ return -EFAULT;
25712 ++ return 0;
25713 ++}
25714 ++
25715 ++static int do_set_caps(struct vx_info *vxi,
25716 ++ uint64_t bcaps, uint64_t bmask, uint64_t ccaps, uint64_t cmask)
25717 ++{
25718 ++ vxi->vx_bcaps = vs_mask_flags(vxi->vx_bcaps, bcaps, bmask);
25719 ++ vxi->vx_ccaps = vs_mask_flags(vxi->vx_ccaps, ccaps, cmask);
25720 ++
25721 ++ return 0;
25722 ++}
25723 ++
25724 ++int vc_set_ccaps(struct vx_info *vxi, void __user *data)
25725 ++{
25726 ++ struct vcmd_ctx_caps_v1 vc_data;
25727 ++
25728 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
25729 ++ return -EFAULT;
25730 ++
25731 ++ return do_set_caps(vxi, 0, 0, vc_data.ccaps, vc_data.cmask);
25732 ++}
25733 ++
25734 ++int vc_get_bcaps(struct vx_info *vxi, void __user *data)
25735 ++{
25736 ++ struct vcmd_bcaps vc_data;
25737 ++ int ret;
25738 ++
25739 ++ ret = do_get_caps(vxi, &vc_data.bcaps, NULL);
25740 ++ if (ret)
25741 ++ return ret;
25742 ++ vc_data.bmask = ~0ULL;
25743 ++
25744 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
25745 ++ return -EFAULT;
25746 ++ return 0;
25747 ++}
25748 ++
25749 ++int vc_set_bcaps(struct vx_info *vxi, void __user *data)
25750 ++{
25751 ++ struct vcmd_bcaps vc_data;
25752 ++
25753 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
25754 ++ return -EFAULT;
25755 ++
25756 ++ return do_set_caps(vxi, vc_data.bcaps, vc_data.bmask, 0, 0);
25757 ++}
25758 ++
25759 ++
25760 ++int vc_get_badness(struct vx_info *vxi, void __user *data)
25761 ++{
25762 ++ struct vcmd_badness_v0 vc_data;
25763 ++
25764 ++ vc_data.bias = vxi->vx_badness_bias;
25765 ++
25766 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
25767 ++ return -EFAULT;
25768 ++ return 0;
25769 ++}
25770 ++
25771 ++int vc_set_badness(struct vx_info *vxi, void __user *data)
25772 ++{
25773 ++ struct vcmd_badness_v0 vc_data;
25774 ++
25775 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
25776 ++ return -EFAULT;
25777 ++
25778 ++ vxi->vx_badness_bias = vc_data.bias;
25779 ++ return 0;
25780 ++}
25781 ++
25782 ++#include <linux/module.h>
25783 ++
25784 ++EXPORT_SYMBOL_GPL(free_vx_info);
25785 ++
25786 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/cvirt.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/cvirt.c
25787 +--- linux-2.6.22.19/kernel/vserver/cvirt.c 1970-01-01 01:00:00 +0100
25788 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/cvirt.c 2007-08-15 22:00:34 +0200
25789 +@@ -0,0 +1,300 @@
25790 ++/*
25791 ++ * linux/kernel/vserver/cvirt.c
25792 ++ *
25793 ++ * Virtual Server: Context Virtualization
25794 ++ *
25795 ++ * Copyright (C) 2004-2007 Herbert Pötzl
25796 ++ *
25797 ++ * V0.01 broken out from limit.c
25798 ++ * V0.02 added utsname stuff
25799 ++ * V0.03 changed vcmds to vxi arg
25800 ++ *
25801 ++ */
25802 ++
25803 ++#include <linux/types.h>
25804 ++#include <linux/vs_cvirt.h>
25805 ++#include <linux/vserver/switch.h>
25806 ++#include <linux/vserver/cvirt_cmd.h>
25807 ++
25808 ++#include <asm/uaccess.h>
25809 ++
25810 ++
25811 ++void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle)
25812 ++{
25813 ++ struct vx_info *vxi = current->vx_info;
25814 ++
25815 ++ set_normalized_timespec(uptime,
25816 ++ uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec,
25817 ++ uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec);
25818 ++ if (!idle)
25819 ++ return;
25820 ++ set_normalized_timespec(idle,
25821 ++ idle->tv_sec - vxi->cvirt.bias_idle.tv_sec,
25822 ++ idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec);
25823 ++ return;
25824 ++}
25825 ++
25826 ++uint64_t vx_idle_jiffies(void)
25827 ++{
25828 ++ return init_task.utime + init_task.stime;
25829 ++}
25830 ++
25831 ++
25832 ++
25833 ++static inline uint32_t __update_loadavg(uint32_t load,
25834 ++ int wsize, int delta, int n)
25835 ++{
25836 ++ unsigned long long calc, prev;
25837 ++
25838 ++ /* just set it to n */
25839 ++ if (unlikely(delta >= wsize))
25840 ++ return (n << FSHIFT);
25841 ++
25842 ++ calc = delta * n;
25843 ++ calc <<= FSHIFT;
25844 ++ prev = (wsize - delta);
25845 ++ prev *= load;
25846 ++ calc += prev;
25847 ++ do_div(calc, wsize);
25848 ++ return calc;
25849 ++}
25850 ++
25851 ++
25852 ++void vx_update_load(struct vx_info *vxi)
25853 ++{
25854 ++ uint32_t now, last, delta;
25855 ++ unsigned int nr_running, nr_uninterruptible;
25856 ++ unsigned int total;
25857 ++ unsigned long flags;
25858 ++
25859 ++ spin_lock_irqsave(&vxi->cvirt.load_lock, flags);
25860 ++
25861 ++ now = jiffies;
25862 ++ last = vxi->cvirt.load_last;
25863 ++ delta = now - last;
25864 ++
25865 ++ if (delta < 5*HZ)
25866 ++ goto out;
25867 ++
25868 ++ nr_running = atomic_read(&vxi->cvirt.nr_running);
25869 ++ nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible);
25870 ++ total = nr_running + nr_uninterruptible;
25871 ++
25872 ++ vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0],
25873 ++ 60*HZ, delta, total);
25874 ++ vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
25875 ++ 5*60*HZ, delta, total);
25876 ++ vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
25877 ++ 15*60*HZ, delta, total);
25878 ++
25879 ++ vxi->cvirt.load_last = now;
25880 ++out:
25881 ++ atomic_inc(&vxi->cvirt.load_updates);
25882 ++ spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags);
25883 ++}
25884 ++
25885 ++
25886 ++/*
25887 ++ * Commands to do_syslog:
25888 ++ *
25889 ++ * 0 -- Close the log. Currently a NOP.
25890 ++ * 1 -- Open the log. Currently a NOP.
25891 ++ * 2 -- Read from the log.
25892 ++ * 3 -- Read all messages remaining in the ring buffer.
25893 ++ * 4 -- Read and clear all messages remaining in the ring buffer
25894 ++ * 5 -- Clear ring buffer.
25895 ++ * 6 -- Disable printk's to console
25896 ++ * 7 -- Enable printk's to console
25897 ++ * 8 -- Set level of messages printed to console
25898 ++ * 9 -- Return number of unread characters in the log buffer
25899 ++ * 10 -- Return size of the log buffer
25900 ++ */
25901 ++int vx_do_syslog(int type, char __user *buf, int len)
25902 ++{
25903 ++ int error = 0;
25904 ++ int do_clear = 0;
25905 ++ struct vx_info *vxi = current->vx_info;
25906 ++ struct _vx_syslog *log;
25907 ++
25908 ++ if (!vxi)
25909 ++ return -EINVAL;
25910 ++ log = &vxi->cvirt.syslog;
25911 ++
25912 ++ switch (type) {
25913 ++ case 0: /* Close log */
25914 ++ case 1: /* Open log */
25915 ++ break;
25916 ++ case 2: /* Read from log */
25917 ++ error = wait_event_interruptible(log->log_wait,
25918 ++ (log->log_start - log->log_end));
25919 ++ if (error)
25920 ++ break;
25921 ++ spin_lock_irq(&log->logbuf_lock);
25922 ++ spin_unlock_irq(&log->logbuf_lock);
25923 ++ break;
25924 ++ case 4: /* Read/clear last kernel messages */
25925 ++ do_clear = 1;
25926 ++ /* fall through */
25927 ++ case 3: /* Read last kernel messages */
25928 ++ return 0;
25929 ++
25930 ++ case 5: /* Clear ring buffer */
25931 ++ return 0;
25932 ++
25933 ++ case 6: /* Disable logging to console */
25934 ++ case 7: /* Enable logging to console */
25935 ++ case 8: /* Set level of messages printed to console */
25936 ++ break;
25937 ++
25938 ++ case 9: /* Number of chars in the log buffer */
25939 ++ return 0;
25940 ++ case 10: /* Size of the log buffer */
25941 ++ return 0;
25942 ++ default:
25943 ++ error = -EINVAL;
25944 ++ break;
25945 ++ }
25946 ++ return error;
25947 ++}
25948 ++
25949 ++
25950 ++/* virtual host info names */
25951 ++
25952 ++static char *vx_vhi_name(struct vx_info *vxi, int id)
25953 ++{
25954 ++ struct nsproxy *nsproxy;
25955 ++ struct uts_namespace *uts;
25956 ++
25957 ++
25958 ++ if (id == VHIN_CONTEXT)
25959 ++ return vxi->vx_name;
25960 ++
25961 ++ nsproxy = vxi->vx_nsproxy;
25962 ++ if (!nsproxy)
25963 ++ return NULL;
25964 ++
25965 ++ uts = nsproxy->uts_ns;
25966 ++ if (!uts)
25967 ++ return NULL;
25968 ++
25969 ++ switch (id) {
25970 ++ case VHIN_SYSNAME:
25971 ++ return uts->name.sysname;
25972 ++ case VHIN_NODENAME:
25973 ++ return uts->name.nodename;
25974 ++ case VHIN_RELEASE:
25975 ++ return uts->name.release;
25976 ++ case VHIN_VERSION:
25977 ++ return uts->name.version;
25978 ++ case VHIN_MACHINE:
25979 ++ return uts->name.machine;
25980 ++ case VHIN_DOMAINNAME:
25981 ++ return uts->name.domainname;
25982 ++ default:
25983 ++ return NULL;
25984 ++ }
25985 ++ return NULL;
25986 ++}
25987 ++
25988 ++int vc_set_vhi_name(struct vx_info *vxi, void __user *data)
25989 ++{
25990 ++ struct vcmd_vhi_name_v0 vc_data;
25991 ++ char *name;
25992 ++
25993 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
25994 ++ return -EFAULT;
25995 ++
25996 ++ name = vx_vhi_name(vxi, vc_data.field);
25997 ++ if (!name)
25998 ++ return -EINVAL;
25999 ++
26000 ++ memcpy(name, vc_data.name, 65);
26001 ++ return 0;
26002 ++}
26003 ++
26004 ++int vc_get_vhi_name(struct vx_info *vxi, void __user *data)
26005 ++{
26006 ++ struct vcmd_vhi_name_v0 vc_data;
26007 ++ char *name;
26008 ++
26009 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26010 ++ return -EFAULT;
26011 ++
26012 ++ name = vx_vhi_name(vxi, vc_data.field);
26013 ++ if (!name)
26014 ++ return -EINVAL;
26015 ++
26016 ++ memcpy(vc_data.name, name, 65);
26017 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
26018 ++ return -EFAULT;
26019 ++ return 0;
26020 ++}
26021 ++
26022 ++
26023 ++int vc_virt_stat(struct vx_info *vxi, void __user *data)
26024 ++{
26025 ++ struct vcmd_virt_stat_v0 vc_data;
26026 ++ struct _vx_cvirt *cvirt = &vxi->cvirt;
26027 ++ struct timespec uptime;
26028 ++
26029 ++ do_posix_clock_monotonic_gettime(&uptime);
26030 ++ set_normalized_timespec(&uptime,
26031 ++ uptime.tv_sec - cvirt->bias_uptime.tv_sec,
26032 ++ uptime.tv_nsec - cvirt->bias_uptime.tv_nsec);
26033 ++
26034 ++ vc_data.offset = timeval_to_ns(&cvirt->bias_tv);
26035 ++ vc_data.uptime = timespec_to_ns(&uptime);
26036 ++ vc_data.nr_threads = atomic_read(&cvirt->nr_threads);
26037 ++ vc_data.nr_running = atomic_read(&cvirt->nr_running);
26038 ++ vc_data.nr_uninterruptible = atomic_read(&cvirt->nr_uninterruptible);
26039 ++ vc_data.nr_onhold = atomic_read(&cvirt->nr_onhold);
26040 ++ vc_data.nr_forks = atomic_read(&cvirt->total_forks);
26041 ++ vc_data.load[0] = cvirt->load[0];
26042 ++ vc_data.load[1] = cvirt->load[1];
26043 ++ vc_data.load[2] = cvirt->load[2];
26044 ++
26045 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
26046 ++ return -EFAULT;
26047 ++ return 0;
26048 ++}
26049 ++
26050 ++
26051 ++#ifdef CONFIG_VSERVER_VTIME
26052 ++
26053 ++/* virtualized time base */
26054 ++
26055 ++void vx_gettimeofday(struct timeval *tv)
26056 ++{
26057 ++ do_gettimeofday(tv);
26058 ++ if (!vx_flags(VXF_VIRT_TIME, 0))
26059 ++ return;
26060 ++
26061 ++ tv->tv_sec += current->vx_info->cvirt.bias_tv.tv_sec;
26062 ++ tv->tv_usec += current->vx_info->cvirt.bias_tv.tv_usec;
26063 ++
26064 ++ if (tv->tv_usec >= USEC_PER_SEC) {
26065 ++ tv->tv_sec++;
26066 ++ tv->tv_usec -= USEC_PER_SEC;
26067 ++ } else if (tv->tv_usec < 0) {
26068 ++ tv->tv_sec--;
26069 ++ tv->tv_usec += USEC_PER_SEC;
26070 ++ }
26071 ++}
26072 ++
26073 ++int vx_settimeofday(struct timespec *ts)
26074 ++{
26075 ++ struct timeval tv;
26076 ++
26077 ++ if (!vx_flags(VXF_VIRT_TIME, 0))
26078 ++ return do_settimeofday(ts);
26079 ++
26080 ++ do_gettimeofday(&tv);
26081 ++ current->vx_info->cvirt.bias_tv.tv_sec =
26082 ++ ts->tv_sec - tv.tv_sec;
26083 ++ current->vx_info->cvirt.bias_tv.tv_usec =
26084 ++ (ts->tv_nsec/NSEC_PER_USEC) - tv.tv_usec;
26085 ++ return 0;
26086 ++}
26087 ++
26088 ++#endif
26089 ++
26090 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/cvirt_init.h linux-2.6.22.19-vs2.3.0.34/kernel/vserver/cvirt_init.h
26091 +--- linux-2.6.22.19/kernel/vserver/cvirt_init.h 1970-01-01 01:00:00 +0100
26092 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/cvirt_init.h 2007-10-25 17:05:55 +0200
26093 +@@ -0,0 +1,69 @@
26094 ++
26095 ++
26096 ++extern uint64_t vx_idle_jiffies(void);
26097 ++
26098 ++static inline void vx_info_init_cvirt(struct _vx_cvirt *cvirt)
26099 ++{
26100 ++ uint64_t idle_jiffies = vx_idle_jiffies();
26101 ++ uint64_t nsuptime;
26102 ++
26103 ++ do_posix_clock_monotonic_gettime(&cvirt->bias_uptime);
26104 ++ nsuptime = (unsigned long long)cvirt->bias_uptime.tv_sec
26105 ++ * NSEC_PER_SEC + cvirt->bias_uptime.tv_nsec;
26106 ++ cvirt->bias_clock = nsec_to_clock_t(nsuptime);
26107 ++ cvirt->bias_tv.tv_sec = 0;
26108 ++ cvirt->bias_tv.tv_usec = 0;
26109 ++
26110 ++ jiffies_to_timespec(idle_jiffies, &cvirt->bias_idle);
26111 ++ atomic_set(&cvirt->nr_threads, 0);
26112 ++ atomic_set(&cvirt->nr_running, 0);
26113 ++ atomic_set(&cvirt->nr_uninterruptible, 0);
26114 ++ atomic_set(&cvirt->nr_onhold, 0);
26115 ++
26116 ++ spin_lock_init(&cvirt->load_lock);
26117 ++ cvirt->load_last = jiffies;
26118 ++ atomic_set(&cvirt->load_updates, 0);
26119 ++ cvirt->load[0] = 0;
26120 ++ cvirt->load[1] = 0;
26121 ++ cvirt->load[2] = 0;
26122 ++ atomic_set(&cvirt->total_forks, 0);
26123 ++
26124 ++ spin_lock_init(&cvirt->syslog.logbuf_lock);
26125 ++ init_waitqueue_head(&cvirt->syslog.log_wait);
26126 ++ cvirt->syslog.log_start = 0;
26127 ++ cvirt->syslog.log_end = 0;
26128 ++ cvirt->syslog.con_start = 0;
26129 ++ cvirt->syslog.logged_chars = 0;
26130 ++}
26131 ++
26132 ++static inline
26133 ++void vx_info_init_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
26134 ++{
26135 ++ // cvirt_pc->cpustat = { 0 };
26136 ++}
26137 ++
26138 ++static inline void vx_info_exit_cvirt(struct _vx_cvirt *cvirt)
26139 ++{
26140 ++ int value;
26141 ++
26142 ++ vxwprintk_xid((value = atomic_read(&cvirt->nr_threads)),
26143 ++ "!!! cvirt: %p[nr_threads] = %d on exit.",
26144 ++ cvirt, value);
26145 ++ vxwprintk_xid((value = atomic_read(&cvirt->nr_running)),
26146 ++ "!!! cvirt: %p[nr_running] = %d on exit.",
26147 ++ cvirt, value);
26148 ++ vxwprintk_xid((value = atomic_read(&cvirt->nr_uninterruptible)),
26149 ++ "!!! cvirt: %p[nr_uninterruptible] = %d on exit.",
26150 ++ cvirt, value);
26151 ++ vxwprintk_xid((value = atomic_read(&cvirt->nr_onhold)),
26152 ++ "!!! cvirt: %p[nr_onhold] = %d on exit.",
26153 ++ cvirt, value);
26154 ++ return;
26155 ++}
26156 ++
26157 ++static inline
26158 ++void vx_info_exit_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
26159 ++{
26160 ++ return;
26161 ++}
26162 ++
26163 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/cvirt_proc.h linux-2.6.22.19-vs2.3.0.34/kernel/vserver/cvirt_proc.h
26164 +--- linux-2.6.22.19/kernel/vserver/cvirt_proc.h 1970-01-01 01:00:00 +0100
26165 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/cvirt_proc.h 2007-08-05 20:53:13 +0200
26166 +@@ -0,0 +1,133 @@
26167 ++#ifndef _VX_CVIRT_PROC_H
26168 ++#define _VX_CVIRT_PROC_H
26169 ++
26170 ++#include <linux/nsproxy.h>
26171 ++#include <linux/mnt_namespace.h>
26172 ++#include <linux/utsname.h>
26173 ++#include <linux/ipc.h>
26174 ++
26175 ++
26176 ++static inline
26177 ++int vx_info_proc_nsproxy(struct nsproxy *nsproxy, char *buffer)
26178 ++{
26179 ++ struct mnt_namespace *ns;
26180 ++ struct uts_namespace *uts;
26181 ++ struct ipc_namespace *ipc;
26182 ++ struct vfsmount *mnt;
26183 ++ char *path, *root;
26184 ++ int length = 0;
26185 ++
26186 ++ if (!nsproxy)
26187 ++ goto out;
26188 ++
26189 ++ length += sprintf(buffer + length,
26190 ++ "NSProxy:\t%p [%p,%p,%p]\n",
26191 ++ nsproxy, nsproxy->mnt_ns,
26192 ++ nsproxy->uts_ns, nsproxy->ipc_ns);
26193 ++
26194 ++ ns = nsproxy->mnt_ns;
26195 ++ if (!ns)
26196 ++ goto skip_ns;
26197 ++
26198 ++ path = kmalloc(PATH_MAX, GFP_KERNEL);
26199 ++ if (!path)
26200 ++ goto skip_ns;
26201 ++
26202 ++ mnt = ns->root;
26203 ++ root = d_path(mnt->mnt_root, mnt->mnt_parent, path, PATH_MAX - 2);
26204 ++ length += sprintf(buffer + length,
26205 ++ "Namespace:\t%p [#%u]\n"
26206 ++ "RootPath:\t%s\n",
26207 ++ ns, atomic_read(&ns->count),
26208 ++ root);
26209 ++ kfree(path);
26210 ++skip_ns:
26211 ++
26212 ++ uts = nsproxy->uts_ns;
26213 ++ if (!uts)
26214 ++ goto skip_uts;
26215 ++
26216 ++ length += sprintf(buffer + length,
26217 ++ "SysName:\t%.*s\n"
26218 ++ "NodeName:\t%.*s\n"
26219 ++ "Release:\t%.*s\n"
26220 ++ "Version:\t%.*s\n"
26221 ++ "Machine:\t%.*s\n"
26222 ++ "DomainName:\t%.*s\n",
26223 ++ __NEW_UTS_LEN, uts->name.sysname,
26224 ++ __NEW_UTS_LEN, uts->name.nodename,
26225 ++ __NEW_UTS_LEN, uts->name.release,
26226 ++ __NEW_UTS_LEN, uts->name.version,
26227 ++ __NEW_UTS_LEN, uts->name.machine,
26228 ++ __NEW_UTS_LEN, uts->name.domainname);
26229 ++skip_uts:
26230 ++
26231 ++ ipc = nsproxy->ipc_ns;
26232 ++ if (!ipc)
26233 ++ goto skip_ipc;
26234 ++
26235 ++ length += sprintf(buffer + length,
26236 ++ "SEMS:\t\t%d %d %d %d %d\n"
26237 ++ "MSG:\t\t%d %d %d\n"
26238 ++ "SHM:\t\t%lu %lu %d %d\n",
26239 ++ ipc->sem_ctls[0], ipc->sem_ctls[1],
26240 ++ ipc->sem_ctls[2], ipc->sem_ctls[3],
26241 ++ ipc->used_sems,
26242 ++ ipc->msg_ctlmax, ipc->msg_ctlmnb, ipc->msg_ctlmni,
26243 ++ (unsigned long)ipc->shm_ctlmax,
26244 ++ (unsigned long)ipc->shm_ctlall,
26245 ++ ipc->shm_ctlmni, ipc->shm_tot);
26246 ++skip_ipc:
26247 ++out:
26248 ++ return length;
26249 ++}
26250 ++
26251 ++
26252 ++#include <linux/sched.h>
26253 ++
26254 ++#define LOAD_INT(x) ((x) >> FSHIFT)
26255 ++#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1 - 1)) * 100)
26256 ++
26257 ++static inline
26258 ++int vx_info_proc_cvirt(struct _vx_cvirt *cvirt, char *buffer)
26259 ++{
26260 ++ int length = 0;
26261 ++ int a, b, c;
26262 ++
26263 ++ length += sprintf(buffer + length,
26264 ++ "BiasUptime:\t%lu.%02lu\n",
26265 ++ (unsigned long)cvirt->bias_uptime.tv_sec,
26266 ++ (cvirt->bias_uptime.tv_nsec / (NSEC_PER_SEC / 100)));
26267 ++
26268 ++ a = cvirt->load[0] + (FIXED_1 / 200);
26269 ++ b = cvirt->load[1] + (FIXED_1 / 200);
26270 ++ c = cvirt->load[2] + (FIXED_1 / 200);
26271 ++ length += sprintf(buffer + length,
26272 ++ "nr_threads:\t%d\n"
26273 ++ "nr_running:\t%d\n"
26274 ++ "nr_unintr:\t%d\n"
26275 ++ "nr_onhold:\t%d\n"
26276 ++ "load_updates:\t%d\n"
26277 ++ "loadavg:\t%d.%02d %d.%02d %d.%02d\n"
26278 ++ "total_forks:\t%d\n",
26279 ++ atomic_read(&cvirt->nr_threads),
26280 ++ atomic_read(&cvirt->nr_running),
26281 ++ atomic_read(&cvirt->nr_uninterruptible),
26282 ++ atomic_read(&cvirt->nr_onhold),
26283 ++ atomic_read(&cvirt->load_updates),
26284 ++ LOAD_INT(a), LOAD_FRAC(a),
26285 ++ LOAD_INT(b), LOAD_FRAC(b),
26286 ++ LOAD_INT(c), LOAD_FRAC(c),
26287 ++ atomic_read(&cvirt->total_forks));
26288 ++ return length;
26289 ++}
26290 ++
26291 ++static inline
26292 ++int vx_info_proc_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc,
26293 ++ char *buffer, int cpu)
26294 ++{
26295 ++ int length = 0;
26296 ++ return length;
26297 ++}
26298 ++
26299 ++#endif /* _VX_CVIRT_PROC_H */
26300 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/debug.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/debug.c
26301 +--- linux-2.6.22.19/kernel/vserver/debug.c 1970-01-01 01:00:00 +0100
26302 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/debug.c 2007-10-01 14:57:41 +0200
26303 +@@ -0,0 +1,32 @@
26304 ++/*
26305 ++ * kernel/vserver/debug.c
26306 ++ *
26307 ++ * Copyright (C) 2005-2007 Herbert Pötzl
26308 ++ *
26309 ++ * V0.01 vx_info dump support
26310 ++ *
26311 ++ */
26312 ++
26313 ++#include <linux/module.h>
26314 ++
26315 ++#include <linux/vserver/context.h>
26316 ++
26317 ++
26318 ++void dump_vx_info(struct vx_info *vxi, int level)
26319 ++{
26320 ++ printk("vx_info %p[#%d, %d.%d, %4x]\n", vxi, vxi->vx_id,
26321 ++ atomic_read(&vxi->vx_usecnt),
26322 ++ atomic_read(&vxi->vx_tasks),
26323 ++ vxi->vx_state);
26324 ++ if (level > 0) {
26325 ++ __dump_vx_limit(&vxi->limit);
26326 ++ __dump_vx_sched(&vxi->sched);
26327 ++ __dump_vx_cvirt(&vxi->cvirt);
26328 ++ __dump_vx_cacct(&vxi->cacct);
26329 ++ }
26330 ++ printk("---\n");
26331 ++}
26332 ++
26333 ++
26334 ++EXPORT_SYMBOL_GPL(dump_vx_info);
26335 ++
26336 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/device.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/device.c
26337 +--- linux-2.6.22.19/kernel/vserver/device.c 1970-01-01 01:00:00 +0100
26338 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/device.c 2008-03-17 00:54:40 +0100
26339 +@@ -0,0 +1,443 @@
26340 ++/*
26341 ++ * linux/kernel/vserver/device.c
26342 ++ *
26343 ++ * Linux-VServer: Device Support
26344 ++ *
26345 ++ * Copyright (C) 2006 Herbert Pötzl
26346 ++ * Copyright (C) 2007 Daniel Hokka Zakrisson
26347 ++ *
26348 ++ * V0.01 device mapping basics
26349 ++ * V0.02 added defaults
26350 ++ *
26351 ++ */
26352 ++
26353 ++#include <linux/slab.h>
26354 ++#include <linux/rcupdate.h>
26355 ++#include <linux/fs.h>
26356 ++#include <linux/namei.h>
26357 ++#include <linux/hash.h>
26358 ++
26359 ++#include <asm/errno.h>
26360 ++#include <asm/uaccess.h>
26361 ++#include <linux/vserver/base.h>
26362 ++#include <linux/vserver/debug.h>
26363 ++#include <linux/vserver/context.h>
26364 ++#include <linux/vserver/device.h>
26365 ++#include <linux/vserver/device_cmd.h>
26366 ++
26367 ++
26368 ++#define DMAP_HASH_BITS 4
26369 ++
26370 ++
26371 ++struct vs_mapping {
26372 ++ union {
26373 ++ struct hlist_node hlist;
26374 ++ struct list_head list;
26375 ++ } u;
26376 ++#define dm_hlist u.hlist
26377 ++#define dm_list u.list
26378 ++ xid_t xid;
26379 ++ dev_t device;
26380 ++ struct vx_dmap_target target;
26381 ++};
26382 ++
26383 ++
26384 ++static struct hlist_head dmap_main_hash[1 << DMAP_HASH_BITS];
26385 ++
26386 ++static spinlock_t dmap_main_hash_lock = SPIN_LOCK_UNLOCKED;
26387 ++
26388 ++static struct vx_dmap_target dmap_defaults[2] = {
26389 ++ { .flags = DATTR_OPEN },
26390 ++ { .flags = DATTR_OPEN },
26391 ++};
26392 ++
26393 ++
26394 ++struct kmem_cache *dmap_cachep __read_mostly;
26395 ++
26396 ++int __init dmap_cache_init(void)
26397 ++{
26398 ++ dmap_cachep = kmem_cache_create("dmap_cache",
26399 ++ sizeof(struct vs_mapping), 0,
26400 ++ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
26401 ++ return 0;
26402 ++}
26403 ++
26404 ++__initcall(dmap_cache_init);
26405 ++
26406 ++
26407 ++static inline unsigned int __hashval(dev_t dev, int bits)
26408 ++{
26409 ++ return hash_long((unsigned long)dev, bits);
26410 ++}
26411 ++
26412 ++
26413 ++/* __hash_mapping()
26414 ++ * add the mapping to the hash table
26415 ++ */
26416 ++static inline void __hash_mapping(struct vx_info *vxi, struct vs_mapping *vdm)
26417 ++{
26418 ++ spinlock_t *hash_lock = &dmap_main_hash_lock;
26419 ++ struct hlist_head *head, *hash = dmap_main_hash;
26420 ++ int device = vdm->device;
26421 ++
26422 ++ spin_lock(hash_lock);
26423 ++ vxdprintk(VXD_CBIT(misc, 8), "__hash_mapping: %p[#%d] %08x:%08x",
26424 ++ vxi, vxi ? vxi->vx_id : 0, device, vdm->target.target);
26425 ++
26426 ++ head = &hash[__hashval(device, DMAP_HASH_BITS)];
26427 ++ hlist_add_head(&vdm->dm_hlist, head);
26428 ++ spin_unlock(hash_lock);
26429 ++}
26430 ++
26431 ++
26432 ++static inline int __mode_to_default(umode_t mode)
26433 ++{
26434 ++ switch (mode) {
26435 ++ case S_IFBLK:
26436 ++ return 0;
26437 ++ case S_IFCHR:
26438 ++ return 1;
26439 ++ default:
26440 ++ BUG();
26441 ++ }
26442 ++}
26443 ++
26444 ++
26445 ++/* __set_default()
26446 ++ * set a default
26447 ++ */
26448 ++static inline void __set_default(struct vx_info *vxi, umode_t mode,
26449 ++ struct vx_dmap_target *vdmt)
26450 ++{
26451 ++ spinlock_t *hash_lock = &dmap_main_hash_lock;
26452 ++ spin_lock(hash_lock);
26453 ++
26454 ++ if (vxi)
26455 ++ vxi->dmap.targets[__mode_to_default(mode)] = *vdmt;
26456 ++ else
26457 ++ dmap_defaults[__mode_to_default(mode)] = *vdmt;
26458 ++
26459 ++
26460 ++ spin_unlock(hash_lock);
26461 ++
26462 ++ vxdprintk(VXD_CBIT(misc, 8), "__set_default: %p[#%u] %08x %04x",
26463 ++ vxi, vxi ? vxi->vx_id : 0, vdmt->target, vdmt->flags);
26464 ++}
26465 ++
26466 ++
26467 ++/* __remove_default()
26468 ++ * remove a default
26469 ++ */
26470 ++static inline int __remove_default(struct vx_info *vxi, umode_t mode)
26471 ++{
26472 ++ spinlock_t *hash_lock = &dmap_main_hash_lock;
26473 ++ spin_lock(hash_lock);
26474 ++
26475 ++ if (vxi)
26476 ++ vxi->dmap.targets[__mode_to_default(mode)].flags = 0;
26477 ++ else /* remove == reset */
26478 ++ dmap_defaults[__mode_to_default(mode)].flags = DATTR_OPEN | mode;
26479 ++
26480 ++ spin_unlock(hash_lock);
26481 ++ return 0;
26482 ++}
26483 ++
26484 ++
26485 ++/* __find_mapping()
26486 ++ * find a mapping in the hash table
26487 ++ *
26488 ++ * caller must hold hash_lock
26489 ++ */
26490 ++static inline int __find_mapping(xid_t xid, dev_t device, umode_t mode,
26491 ++ struct vs_mapping **local, struct vs_mapping **global)
26492 ++{
26493 ++ struct hlist_head *hash = dmap_main_hash;
26494 ++ struct hlist_head *head = &hash[__hashval(device, DMAP_HASH_BITS)];
26495 ++ struct hlist_node *pos;
26496 ++ struct vs_mapping *vdm;
26497 ++
26498 ++ *local = NULL;
26499 ++ if (global)
26500 ++ *global = NULL;
26501 ++
26502 ++ hlist_for_each(pos, head) {
26503 ++ vdm = hlist_entry(pos, struct vs_mapping, dm_hlist);
26504 ++
26505 ++ if ((vdm->device == device) &&
26506 ++ !((vdm->target.flags ^ mode) & S_IFMT)) {
26507 ++ if (vdm->xid == xid) {
26508 ++ *local = vdm;
26509 ++ return 1;
26510 ++ } else if (global && vdm->xid == 0)
26511 ++ *global = vdm;
26512 ++ }
26513 ++ }
26514 ++
26515 ++ if (global && *global)
26516 ++ return 0;
26517 ++ else
26518 ++ return -ENOENT;
26519 ++}
26520 ++
26521 ++
26522 ++/* __lookup_mapping()
26523 ++ * find a mapping and store the result in target and flags
26524 ++ */
26525 ++static inline int __lookup_mapping(struct vx_info *vxi,
26526 ++ dev_t device, dev_t *target, int *flags, umode_t mode)
26527 ++{
26528 ++ spinlock_t *hash_lock = &dmap_main_hash_lock;
26529 ++ struct vs_mapping *vdm, *global;
26530 ++ struct vx_dmap_target *vdmt;
26531 ++ int ret = 0;
26532 ++ xid_t xid = vxi->vx_id;
26533 ++ int index;
26534 ++
26535 ++ spin_lock(hash_lock);
26536 ++ if (__find_mapping(xid, device, mode, &vdm, &global) > 0) {
26537 ++ ret = 1;
26538 ++ vdmt = &vdm->target;
26539 ++ goto found;
26540 ++ }
26541 ++
26542 ++ index = __mode_to_default(mode);
26543 ++ if (vxi && vxi->dmap.targets[index].flags) {
26544 ++ ret = 2;
26545 ++ vdmt = &vxi->dmap.targets[index];
26546 ++ } else if (global) {
26547 ++ ret = 3;
26548 ++ vdmt = &global->target;
26549 ++ goto found;
26550 ++ } else {
26551 ++ ret = 4;
26552 ++ vdmt = &dmap_defaults[index];
26553 ++ }
26554 ++
26555 ++found:
26556 ++ if (target && (vdmt->flags & DATTR_REMAP))
26557 ++ *target = vdmt->target;
26558 ++ else if (target)
26559 ++ *target = device;
26560 ++ if (flags)
26561 ++ *flags = vdmt->flags;
26562 ++
26563 ++ spin_unlock(hash_lock);
26564 ++
26565 ++ return ret;
26566 ++}
26567 ++
26568 ++
26569 ++/* __remove_mapping()
26570 ++ * remove a mapping from the hash table
26571 ++ */
26572 ++static inline int __remove_mapping(struct vx_info *vxi, dev_t device,
26573 ++ umode_t mode)
26574 ++{
26575 ++ spinlock_t *hash_lock = &dmap_main_hash_lock;
26576 ++ struct vs_mapping *vdm = NULL;
26577 ++ int ret = 0;
26578 ++
26579 ++ spin_lock(hash_lock);
26580 ++
26581 ++ ret = __find_mapping((vxi ? vxi->vx_id : 0), device, mode, &vdm,
26582 ++ NULL);
26583 ++ vxdprintk(VXD_CBIT(misc, 8), "__remove_mapping: %p[#%d] %08x %04x",
26584 ++ vxi, vxi ? vxi->vx_id : 0, device, mode);
26585 ++ if (ret < 0)
26586 ++ goto out;
26587 ++ hlist_del(&vdm->dm_hlist);
26588 ++
26589 ++out:
26590 ++ spin_unlock(hash_lock);
26591 ++ if (vdm)
26592 ++ kmem_cache_free(dmap_cachep, vdm);
26593 ++ return ret;
26594 ++}
26595 ++
26596 ++
26597 ++
26598 ++int vs_map_device(struct vx_info *vxi,
26599 ++ dev_t device, dev_t *target, umode_t mode)
26600 ++{
26601 ++ int ret, flags = DATTR_MASK;
26602 ++
26603 ++ if (!vxi) {
26604 ++ if (target)
26605 ++ *target = device;
26606 ++ goto out;
26607 ++ }
26608 ++ ret = __lookup_mapping(vxi, device, target, &flags, mode);
26609 ++ vxdprintk(VXD_CBIT(misc, 8), "vs_map_device: %08x target: %08x flags: %04x mode: %04x mapped=%d",
26610 ++ device, target ? *target : 0, flags, mode, ret);
26611 ++out:
26612 ++ return (flags & DATTR_MASK);
26613 ++}
26614 ++
26615 ++
26616 ++
26617 ++static int do_set_mapping(struct vx_info *vxi,
26618 ++ dev_t device, dev_t target, int flags, umode_t mode)
26619 ++{
26620 ++ if (device) {
26621 ++ struct vs_mapping *new;
26622 ++
26623 ++ new = kmem_cache_alloc(dmap_cachep, GFP_KERNEL);
26624 ++ if (!new)
26625 ++ return -ENOMEM;
26626 ++
26627 ++ INIT_HLIST_NODE(&new->dm_hlist);
26628 ++ new->device = device;
26629 ++ new->target.target = target;
26630 ++ new->target.flags = flags | mode;
26631 ++ new->xid = (vxi ? vxi->vx_id : 0);
26632 ++
26633 ++ vxdprintk(VXD_CBIT(misc, 8), "do_set_mapping: %08x target: %08x flags: %04x", device, target, flags);
26634 ++ __hash_mapping(vxi, new);
26635 ++ } else {
26636 ++ struct vx_dmap_target new = {
26637 ++ .target = target,
26638 ++ .flags = flags | mode,
26639 ++ };
26640 ++ __set_default(vxi, mode, &new);
26641 ++ }
26642 ++ return 0;
26643 ++}
26644 ++
26645 ++
26646 ++static int do_unset_mapping(struct vx_info *vxi,
26647 ++ dev_t device, dev_t target, int flags, umode_t mode)
26648 ++{
26649 ++ int ret = -EINVAL;
26650 ++
26651 ++ if (device) {
26652 ++ ret = __remove_mapping(vxi, device, mode);
26653 ++ if (ret < 0)
26654 ++ goto out;
26655 ++ } else {
26656 ++ ret = __remove_default(vxi, mode);
26657 ++ if (ret < 0)
26658 ++ goto out;
26659 ++ }
26660 ++
26661 ++out:
26662 ++ return ret;
26663 ++}
26664 ++
26665 ++
26666 ++static inline int __user_device(const char __user *name, dev_t *dev,
26667 ++ umode_t *mode)
26668 ++{
26669 ++ struct nameidata nd;
26670 ++ int ret;
26671 ++
26672 ++ if (!name) {
26673 ++ *dev = 0;
26674 ++ return 0;
26675 ++ }
26676 ++ ret = user_path_walk_link(name, &nd);
26677 ++ if (ret)
26678 ++ return ret;
26679 ++ if (nd.dentry->d_inode) {
26680 ++ *dev = nd.dentry->d_inode->i_rdev;
26681 ++ *mode = nd.dentry->d_inode->i_mode;
26682 ++ }
26683 ++ path_release(&nd);
26684 ++ return 0;
26685 ++}
26686 ++
26687 ++static inline int __mapping_mode(dev_t device, dev_t target,
26688 ++ umode_t device_mode, umode_t target_mode, umode_t *mode)
26689 ++{
26690 ++ if (device)
26691 ++ *mode = device_mode & S_IFMT;
26692 ++ else if (target)
26693 ++ *mode = target_mode & S_IFMT;
26694 ++ else
26695 ++ return -EINVAL;
26696 ++
26697 ++ /* if both given, device and target mode have to match */
26698 ++ if (device && target &&
26699 ++ ((device_mode ^ target_mode) & S_IFMT))
26700 ++ return -EINVAL;
26701 ++ return 0;
26702 ++}
26703 ++
26704 ++
26705 ++static inline int do_mapping(struct vx_info *vxi, const char __user *device_path,
26706 ++ const char __user *target_path, int flags, int set)
26707 ++{
26708 ++ dev_t device = ~0, target = ~0;
26709 ++ umode_t device_mode = 0, target_mode = 0, mode;
26710 ++ int ret;
26711 ++
26712 ++ ret = __user_device(device_path, &device, &device_mode);
26713 ++ if (ret)
26714 ++ return ret;
26715 ++ ret = __user_device(target_path, &target, &target_mode);
26716 ++ if (ret)
26717 ++ return ret;
26718 ++
26719 ++ ret = __mapping_mode(device, target,
26720 ++ device_mode, target_mode, &mode);
26721 ++ if (ret)
26722 ++ return ret;
26723 ++
26724 ++ if (set)
26725 ++ return do_set_mapping(vxi, device, target,
26726 ++ flags, mode);
26727 ++ else
26728 ++ return do_unset_mapping(vxi, device, target,
26729 ++ flags, mode);
26730 ++}
26731 ++
26732 ++
26733 ++int vc_set_mapping(struct vx_info *vxi, void __user *data)
26734 ++{
26735 ++ struct vcmd_set_mapping_v0 vc_data;
26736 ++
26737 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26738 ++ return -EFAULT;
26739 ++
26740 ++ return do_mapping(vxi, vc_data.device, vc_data.target,
26741 ++ vc_data.flags, 1);
26742 ++}
26743 ++
26744 ++int vc_unset_mapping(struct vx_info *vxi, void __user *data)
26745 ++{
26746 ++ struct vcmd_set_mapping_v0 vc_data;
26747 ++
26748 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26749 ++ return -EFAULT;
26750 ++
26751 ++ return do_mapping(vxi, vc_data.device, vc_data.target,
26752 ++ vc_data.flags, 0);
26753 ++}
26754 ++
26755 ++
26756 ++#ifdef CONFIG_COMPAT
26757 ++
26758 ++int vc_set_mapping_x32(struct vx_info *vxi, void __user *data)
26759 ++{
26760 ++ struct vcmd_set_mapping_v0_x32 vc_data;
26761 ++
26762 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26763 ++ return -EFAULT;
26764 ++
26765 ++ return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
26766 ++ compat_ptr(vc_data.target_ptr), vc_data.flags, 1);
26767 ++}
26768 ++
26769 ++int vc_unset_mapping_x32(struct vx_info *vxi, void __user *data)
26770 ++{
26771 ++ struct vcmd_set_mapping_v0_x32 vc_data;
26772 ++
26773 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
26774 ++ return -EFAULT;
26775 ++
26776 ++ return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
26777 ++ compat_ptr(vc_data.target_ptr), vc_data.flags, 0);
26778 ++}
26779 ++
26780 ++#endif /* CONFIG_COMPAT */
26781 ++
26782 ++
26783 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/dlimit.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/dlimit.c
26784 +--- linux-2.6.22.19/kernel/vserver/dlimit.c 1970-01-01 01:00:00 +0100
26785 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/dlimit.c 2007-08-15 22:07:58 +0200
26786 +@@ -0,0 +1,520 @@
26787 ++/*
26788 ++ * linux/kernel/vserver/dlimit.c
26789 ++ *
26790 ++ * Virtual Server: Context Disk Limits
26791 ++ *
26792 ++ * Copyright (C) 2004-2007 Herbert Pötzl
26793 ++ *
26794 ++ * V0.01 initial version
26795 ++ * V0.02 compat32 splitup
26796 ++ *
26797 ++ */
26798 ++
26799 ++#include <linux/statfs.h>
26800 ++#include <linux/vs_tag.h>
26801 ++#include <linux/vs_dlimit.h>
26802 ++#include <linux/vserver/dlimit_cmd.h>
26803 ++
26804 ++#include <asm/uaccess.h>
26805 ++
26806 ++/* __alloc_dl_info()
26807 ++
26808 ++ * allocate an initialized dl_info struct
26809 ++ * doesn't make it visible (hash) */
26810 ++
26811 ++static struct dl_info *__alloc_dl_info(struct super_block *sb, tag_t tag)
26812 ++{
26813 ++ struct dl_info *new = NULL;
26814 ++
26815 ++ vxdprintk(VXD_CBIT(dlim, 5),
26816 ++ "alloc_dl_info(%p,%d)*", sb, tag);
26817 ++
26818 ++ /* would this benefit from a slab cache? */
26819 ++ new = kmalloc(sizeof(struct dl_info), GFP_KERNEL);
26820 ++ if (!new)
26821 ++ return 0;
26822 ++
26823 ++ memset(new, 0, sizeof(struct dl_info));
26824 ++ new->dl_tag = tag;
26825 ++ new->dl_sb = sb;
26826 ++ INIT_RCU_HEAD(&new->dl_rcu);
26827 ++ INIT_HLIST_NODE(&new->dl_hlist);
26828 ++ spin_lock_init(&new->dl_lock);
26829 ++ atomic_set(&new->dl_refcnt, 0);
26830 ++ atomic_set(&new->dl_usecnt, 0);
26831 ++
26832 ++ /* rest of init goes here */
26833 ++
26834 ++ vxdprintk(VXD_CBIT(dlim, 4),
26835 ++ "alloc_dl_info(%p,%d) = %p", sb, tag, new);
26836 ++ return new;
26837 ++}
26838 ++
26839 ++/* __dealloc_dl_info()
26840 ++
26841 ++ * final disposal of dl_info */
26842 ++
26843 ++static void __dealloc_dl_info(struct dl_info *dli)
26844 ++{
26845 ++ vxdprintk(VXD_CBIT(dlim, 4),
26846 ++ "dealloc_dl_info(%p)", dli);
26847 ++
26848 ++ dli->dl_hlist.next = LIST_POISON1;
26849 ++ dli->dl_tag = -1;
26850 ++ dli->dl_sb = 0;
26851 ++
26852 ++ BUG_ON(atomic_read(&dli->dl_usecnt));
26853 ++ BUG_ON(atomic_read(&dli->dl_refcnt));
26854 ++
26855 ++ kfree(dli);
26856 ++}
26857 ++
26858 ++
26859 ++/* hash table for dl_info hash */
26860 ++
26861 ++#define DL_HASH_SIZE 13
26862 ++
26863 ++struct hlist_head dl_info_hash[DL_HASH_SIZE];
26864 ++
26865 ++static spinlock_t dl_info_hash_lock = SPIN_LOCK_UNLOCKED;
26866 ++
26867 ++
26868 ++static inline unsigned int __hashval(struct super_block *sb, tag_t tag)
26869 ++{
26870 ++ return ((tag ^ (unsigned long)sb) % DL_HASH_SIZE);
26871 ++}
26872 ++
26873 ++
26874 ++
26875 ++/* __hash_dl_info()
26876 ++
26877 ++ * add the dli to the global hash table
26878 ++ * requires the hash_lock to be held */
26879 ++
26880 ++static inline void __hash_dl_info(struct dl_info *dli)
26881 ++{
26882 ++ struct hlist_head *head;
26883 ++
26884 ++ vxdprintk(VXD_CBIT(dlim, 6),
26885 ++ "__hash_dl_info: %p[#%d]", dli, dli->dl_tag);
26886 ++ get_dl_info(dli);
26887 ++ head = &dl_info_hash[__hashval(dli->dl_sb, dli->dl_tag)];
26888 ++ hlist_add_head_rcu(&dli->dl_hlist, head);
26889 ++}
26890 ++
26891 ++/* __unhash_dl_info()
26892 ++
26893 ++ * remove the dli from the global hash table
26894 ++ * requires the hash_lock to be held */
26895 ++
26896 ++static inline void __unhash_dl_info(struct dl_info *dli)
26897 ++{
26898 ++ vxdprintk(VXD_CBIT(dlim, 6),
26899 ++ "__unhash_dl_info: %p[#%d]", dli, dli->dl_tag);
26900 ++ hlist_del_rcu(&dli->dl_hlist);
26901 ++ put_dl_info(dli);
26902 ++}
26903 ++
26904 ++
26905 ++/* __lookup_dl_info()
26906 ++
26907 ++ * requires the rcu_read_lock()
26908 ++ * doesn't increment the dl_refcnt */
26909 ++
26910 ++static inline struct dl_info *__lookup_dl_info(struct super_block *sb, tag_t tag)
26911 ++{
26912 ++ struct hlist_head *head = &dl_info_hash[__hashval(sb, tag)];
26913 ++ struct hlist_node *pos;
26914 ++ struct dl_info *dli;
26915 ++
26916 ++ hlist_for_each_entry_rcu(dli, pos, head, dl_hlist) {
26917 ++
26918 ++ if (dli->dl_tag == tag && dli->dl_sb == sb) {
26919 ++ return dli;
26920 ++ }
26921 ++ }
26922 ++ return NULL;
26923 ++}
26924 ++
26925 ++
26926 ++struct dl_info *locate_dl_info(struct super_block *sb, tag_t tag)
26927 ++{
26928 ++ struct dl_info *dli;
26929 ++
26930 ++ rcu_read_lock();
26931 ++ dli = get_dl_info(__lookup_dl_info(sb, tag));
26932 ++ vxdprintk(VXD_CBIT(dlim, 7),
26933 ++ "locate_dl_info(%p,#%d) = %p", sb, tag, dli);
26934 ++ rcu_read_unlock();
26935 ++ return dli;
26936 ++}
26937 ++
26938 ++void rcu_free_dl_info(struct rcu_head *head)
26939 ++{
26940 ++ struct dl_info *dli = container_of(head, struct dl_info, dl_rcu);
26941 ++ int usecnt, refcnt;
26942 ++
26943 ++ BUG_ON(!dli || !head);
26944 ++
26945 ++ usecnt = atomic_read(&dli->dl_usecnt);
26946 ++ BUG_ON(usecnt < 0);
26947 ++
26948 ++ refcnt = atomic_read(&dli->dl_refcnt);
26949 ++ BUG_ON(refcnt < 0);
26950 ++
26951 ++ vxdprintk(VXD_CBIT(dlim, 3),
26952 ++ "rcu_free_dl_info(%p)", dli);
26953 ++ if (!usecnt)
26954 ++ __dealloc_dl_info(dli);
26955 ++ else
26956 ++ printk("!!! rcu didn't free\n");
26957 ++}
26958 ++
26959 ++
26960 ++
26961 ++
26962 ++static int do_addrem_dlimit(uint32_t id, const char __user *name,
26963 ++ uint32_t flags, int add)
26964 ++{
26965 ++ struct nameidata nd;
26966 ++ int ret;
26967 ++
26968 ++ ret = user_path_walk_link(name, &nd);
26969 ++ if (!ret) {
26970 ++ struct super_block *sb;
26971 ++ struct dl_info *dli;
26972 ++
26973 ++ ret = -EINVAL;
26974 ++ if (!nd.dentry->d_inode)
26975 ++ goto out_release;
26976 ++ if (!(sb = nd.dentry->d_inode->i_sb))
26977 ++ goto out_release;
26978 ++
26979 ++ if (add) {
26980 ++ dli = __alloc_dl_info(sb, id);
26981 ++ spin_lock(&dl_info_hash_lock);
26982 ++
26983 ++ ret = -EEXIST;
26984 ++ if (__lookup_dl_info(sb, id))
26985 ++ goto out_unlock;
26986 ++ __hash_dl_info(dli);
26987 ++ dli = NULL;
26988 ++ } else {
26989 ++ spin_lock(&dl_info_hash_lock);
26990 ++ dli = __lookup_dl_info(sb, id);
26991 ++
26992 ++ ret = -ESRCH;
26993 ++ if (!dli)
26994 ++ goto out_unlock;
26995 ++ __unhash_dl_info(dli);
26996 ++ }
26997 ++ ret = 0;
26998 ++ out_unlock:
26999 ++ spin_unlock(&dl_info_hash_lock);
27000 ++ if (add && dli)
27001 ++ __dealloc_dl_info(dli);
27002 ++ out_release:
27003 ++ path_release(&nd);
27004 ++ }
27005 ++ return ret;
27006 ++}
27007 ++
27008 ++int vc_add_dlimit(uint32_t id, void __user *data)
27009 ++{
27010 ++ struct vcmd_ctx_dlimit_base_v0 vc_data;
27011 ++
27012 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
27013 ++ return -EFAULT;
27014 ++
27015 ++ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1);
27016 ++}
27017 ++
27018 ++int vc_rem_dlimit(uint32_t id, void __user *data)
27019 ++{
27020 ++ struct vcmd_ctx_dlimit_base_v0 vc_data;
27021 ++
27022 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
27023 ++ return -EFAULT;
27024 ++
27025 ++ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0);
27026 ++}
27027 ++
27028 ++#ifdef CONFIG_COMPAT
27029 ++
27030 ++int vc_add_dlimit_x32(uint32_t id, void __user *data)
27031 ++{
27032 ++ struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
27033 ++
27034 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
27035 ++ return -EFAULT;
27036 ++
27037 ++ return do_addrem_dlimit(id,
27038 ++ compat_ptr(vc_data.name_ptr), vc_data.flags, 1);
27039 ++}
27040 ++
27041 ++int vc_rem_dlimit_x32(uint32_t id, void __user *data)
27042 ++{
27043 ++ struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
27044 ++
27045 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
27046 ++ return -EFAULT;
27047 ++
27048 ++ return do_addrem_dlimit(id,
27049 ++ compat_ptr(vc_data.name_ptr), vc_data.flags, 0);
27050 ++}
27051 ++
27052 ++#endif /* CONFIG_COMPAT */
27053 ++
27054 ++
27055 ++static inline
27056 ++int do_set_dlimit(uint32_t id, const char __user *name,
27057 ++ uint32_t space_used, uint32_t space_total,
27058 ++ uint32_t inodes_used, uint32_t inodes_total,
27059 ++ uint32_t reserved, uint32_t flags)
27060 ++{
27061 ++ struct nameidata nd;
27062 ++ int ret;
27063 ++
27064 ++ ret = user_path_walk_link(name, &nd);
27065 ++ if (!ret) {
27066 ++ struct super_block *sb;
27067 ++ struct dl_info *dli;
27068 ++
27069 ++ ret = -EINVAL;
27070 ++ if (!nd.dentry->d_inode)
27071 ++ goto out_release;
27072 ++ if (!(sb = nd.dentry->d_inode->i_sb))
27073 ++ goto out_release;
27074 ++ if ((reserved != CDLIM_KEEP &&
27075 ++ reserved > 100) ||
27076 ++ (inodes_used != CDLIM_KEEP &&
27077 ++ inodes_used > inodes_total) ||
27078 ++ (space_used != CDLIM_KEEP &&
27079 ++ space_used > space_total))
27080 ++ goto out_release;
27081 ++
27082 ++ ret = -ESRCH;
27083 ++ dli = locate_dl_info(sb, id);
27084 ++ if (!dli)
27085 ++ goto out_release;
27086 ++
27087 ++ spin_lock(&dli->dl_lock);
27088 ++
27089 ++ if (inodes_used != CDLIM_KEEP)
27090 ++ dli->dl_inodes_used = inodes_used;
27091 ++ if (inodes_total != CDLIM_KEEP)
27092 ++ dli->dl_inodes_total = inodes_total;
27093 ++ if (space_used != CDLIM_KEEP) {
27094 ++ dli->dl_space_used = space_used;
27095 ++ dli->dl_space_used <<= 10;
27096 ++ }
27097 ++ if (space_total == CDLIM_INFINITY)
27098 ++ dli->dl_space_total = DLIM_INFINITY;
27099 ++ else if (space_total != CDLIM_KEEP) {
27100 ++ dli->dl_space_total = space_total;
27101 ++ dli->dl_space_total <<= 10;
27102 ++ }
27103 ++ if (reserved != CDLIM_KEEP)
27104 ++ dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100;
27105 ++
27106 ++ spin_unlock(&dli->dl_lock);
27107 ++
27108 ++ put_dl_info(dli);
27109 ++ ret = 0;
27110 ++
27111 ++ out_release:
27112 ++ path_release(&nd);
27113 ++ }
27114 ++ return ret;
27115 ++}
27116 ++
27117 ++int vc_set_dlimit(uint32_t id, void __user *data)
27118 ++{
27119 ++ struct vcmd_ctx_dlimit_v0 vc_data;
27120 ++
27121 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
27122 ++ return -EFAULT;
27123 ++
27124 ++ return do_set_dlimit(id, vc_data.name,
27125 ++ vc_data.space_used, vc_data.space_total,
27126 ++ vc_data.inodes_used, vc_data.inodes_total,
27127 ++ vc_data.reserved, vc_data.flags);
27128 ++}
27129 ++
27130 ++#ifdef CONFIG_COMPAT
27131 ++
27132 ++int vc_set_dlimit_x32(uint32_t id, void __user *data)
27133 ++{
27134 ++ struct vcmd_ctx_dlimit_v0_x32 vc_data;
27135 ++
27136 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
27137 ++ return -EFAULT;
27138 ++
27139 ++ return do_set_dlimit(id, compat_ptr(vc_data.name_ptr),
27140 ++ vc_data.space_used, vc_data.space_total,
27141 ++ vc_data.inodes_used, vc_data.inodes_total,
27142 ++ vc_data.reserved, vc_data.flags);
27143 ++}
27144 ++
27145 ++#endif /* CONFIG_COMPAT */
27146 ++
27147 ++
27148 ++static inline
27149 ++int do_get_dlimit(uint32_t id, const char __user *name,
27150 ++ uint32_t *space_used, uint32_t *space_total,
27151 ++ uint32_t *inodes_used, uint32_t *inodes_total,
27152 ++ uint32_t *reserved, uint32_t *flags)
27153 ++{
27154 ++ struct nameidata nd;
27155 ++ int ret;
27156 ++
27157 ++ ret = user_path_walk_link(name, &nd);
27158 ++ if (!ret) {
27159 ++ struct super_block *sb;
27160 ++ struct dl_info *dli;
27161 ++
27162 ++ ret = -EINVAL;
27163 ++ if (!nd.dentry->d_inode)
27164 ++ goto out_release;
27165 ++ if (!(sb = nd.dentry->d_inode->i_sb))
27166 ++ goto out_release;
27167 ++
27168 ++ ret = -ESRCH;
27169 ++ dli = locate_dl_info(sb, id);
27170 ++ if (!dli)
27171 ++ goto out_release;
27172 ++
27173 ++ spin_lock(&dli->dl_lock);
27174 ++ *inodes_used = dli->dl_inodes_used;
27175 ++ *inodes_total = dli->dl_inodes_total;
27176 ++ *space_used = dli->dl_space_used >> 10;
27177 ++ if (dli->dl_space_total == DLIM_INFINITY)
27178 ++ *space_total = CDLIM_INFINITY;
27179 ++ else
27180 ++ *space_total = dli->dl_space_total >> 10;
27181 ++
27182 ++ *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10);
27183 ++ spin_unlock(&dli->dl_lock);
27184 ++
27185 ++ put_dl_info(dli);
27186 ++ ret = -EFAULT;
27187 ++
27188 ++ ret = 0;
27189 ++ out_release:
27190 ++ path_release(&nd);
27191 ++ }
27192 ++ return ret;
27193 ++}
27194 ++
27195 ++
27196 ++int vc_get_dlimit(uint32_t id, void __user *data)
27197 ++{
27198 ++ struct vcmd_ctx_dlimit_v0 vc_data;
27199 ++ int ret;
27200 ++
27201 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
27202 ++ return -EFAULT;
27203 ++
27204 ++ ret = do_get_dlimit(id, vc_data.name,
27205 ++ &vc_data.space_used, &vc_data.space_total,
27206 ++ &vc_data.inodes_used, &vc_data.inodes_total,
27207 ++ &vc_data.reserved, &vc_data.flags);
27208 ++ if (ret)
27209 ++ return ret;
27210 ++
27211 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
27212 ++ return -EFAULT;
27213 ++ return 0;
27214 ++}
27215 ++
27216 ++#ifdef CONFIG_COMPAT
27217 ++
27218 ++int vc_get_dlimit_x32(uint32_t id, void __user *data)
27219 ++{
27220 ++ struct vcmd_ctx_dlimit_v0_x32 vc_data;
27221 ++ int ret;
27222 ++
27223 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
27224 ++ return -EFAULT;
27225 ++
27226 ++ ret = do_get_dlimit(id, compat_ptr(vc_data.name_ptr),
27227 ++ &vc_data.space_used, &vc_data.space_total,
27228 ++ &vc_data.inodes_used, &vc_data.inodes_total,
27229 ++ &vc_data.reserved, &vc_data.flags);
27230 ++ if (ret)
27231 ++ return ret;
27232 ++
27233 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
27234 ++ return -EFAULT;
27235 ++ return 0;
27236 ++}
27237 ++
27238 ++#endif /* CONFIG_COMPAT */
27239 ++
27240 ++
27241 ++void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf)
27242 ++{
27243 ++ struct dl_info *dli;
27244 ++ __u64 blimit, bfree, bavail;
27245 ++ __u32 ifree;
27246 ++
27247 ++ dli = locate_dl_info(sb, dx_current_tag());
27248 ++ if (!dli)
27249 ++ return;
27250 ++
27251 ++ spin_lock(&dli->dl_lock);
27252 ++ if (dli->dl_inodes_total == (unsigned long)DLIM_INFINITY)
27253 ++ goto no_ilim;
27254 ++
27255 ++ /* reduce max inodes available to limit */
27256 ++ if (buf->f_files > dli->dl_inodes_total)
27257 ++ buf->f_files = dli->dl_inodes_total;
27258 ++
27259 ++ ifree = dli->dl_inodes_total - dli->dl_inodes_used;
27260 ++ /* reduce free inodes to min */
27261 ++ if (ifree < buf->f_ffree)
27262 ++ buf->f_ffree = ifree;
27263 ++
27264 ++no_ilim:
27265 ++ if (dli->dl_space_total == DLIM_INFINITY)
27266 ++ goto no_blim;
27267 ++
27268 ++ blimit = dli->dl_space_total >> sb->s_blocksize_bits;
27269 ++
27270 ++ if (dli->dl_space_total < dli->dl_space_used)
27271 ++ bfree = 0;
27272 ++ else
27273 ++ bfree = (dli->dl_space_total - dli->dl_space_used)
27274 ++ >> sb->s_blocksize_bits;
27275 ++
27276 ++ bavail = ((dli->dl_space_total >> 10) * dli->dl_nrlmult);
27277 ++ if (bavail < dli->dl_space_used)
27278 ++ bavail = 0;
27279 ++ else
27280 ++ bavail = (bavail - dli->dl_space_used)
27281 ++ >> sb->s_blocksize_bits;
27282 ++
27283 ++ /* reduce max space available to limit */
27284 ++ if (buf->f_blocks > blimit)
27285 ++ buf->f_blocks = blimit;
27286 ++
27287 ++ /* reduce free space to min */
27288 ++ if (bfree < buf->f_bfree)
27289 ++ buf->f_bfree = bfree;
27290 ++
27291 ++ /* reduce avail space to min */
27292 ++ if (bavail < buf->f_bavail)
27293 ++ buf->f_bavail = bavail;
27294 ++
27295 ++no_blim:
27296 ++ spin_unlock(&dli->dl_lock);
27297 ++ put_dl_info(dli);
27298 ++
27299 ++ return;
27300 ++}
27301 ++
27302 ++#include <linux/module.h>
27303 ++
27304 ++EXPORT_SYMBOL_GPL(locate_dl_info);
27305 ++EXPORT_SYMBOL_GPL(rcu_free_dl_info);
27306 ++
27307 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/helper.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/helper.c
27308 +--- linux-2.6.22.19/kernel/vserver/helper.c 1970-01-01 01:00:00 +0100
27309 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/helper.c 2007-08-15 22:12:01 +0200
27310 +@@ -0,0 +1,199 @@
27311 ++/*
27312 ++ * linux/kernel/vserver/helper.c
27313 ++ *
27314 ++ * Virtual Context Support
27315 ++ *
27316 ++ * Copyright (C) 2004-2007 Herbert Pötzl
27317 ++ *
27318 ++ * V0.01 basic helper
27319 ++ *
27320 ++ */
27321 ++
27322 ++#include <linux/kmod.h>
27323 ++#include <linux/reboot.h>
27324 ++#include <linux/vs_context.h>
27325 ++#include <linux/vs_network.h>
27326 ++#include <linux/vserver/signal.h>
27327 ++
27328 ++
27329 ++char vshelper_path[255] = "/sbin/vshelper";
27330 ++
27331 ++
27332 ++static int do_vshelper(char *name, char *argv[], char *envp[], int sync)
27333 ++{
27334 ++ int ret;
27335 ++
27336 ++ if ((ret = call_usermodehelper(name, argv, envp, sync))) {
27337 ++ printk( KERN_WARNING
27338 ++ "%s: (%s %s) returned %s with %d\n",
27339 ++ name, argv[1], argv[2],
27340 ++ sync ? "sync" : "async", ret);
27341 ++ }
27342 ++ vxdprintk(VXD_CBIT(switch, 4),
27343 ++ "%s: (%s %s) returned %s with %d",
27344 ++ name, argv[1], argv[2], sync ? "sync" : "async", ret);
27345 ++ return ret;
27346 ++}
27347 ++
27348 ++/*
27349 ++ * vshelper path is set via /proc/sys
27350 ++ * invoked by vserver sys_reboot(), with
27351 ++ * the following arguments
27352 ++ *
27353 ++ * argv [0] = vshelper_path;
27354 ++ * argv [1] = action: "restart", "halt", "poweroff", ...
27355 ++ * argv [2] = context identifier
27356 ++ *
27357 ++ * envp [*] = type-specific parameters
27358 ++ */
27359 ++
27360 ++long vs_reboot_helper(struct vx_info *vxi, int cmd, void __user *arg)
27361 ++{
27362 ++ char id_buf[8], cmd_buf[16];
27363 ++ char uid_buf[16], pid_buf[16];
27364 ++ int ret;
27365 ++
27366 ++ char *argv[] = {vshelper_path, NULL, id_buf, 0};
27367 ++ char *envp[] = {"HOME=/", "TERM=linux",
27368 ++ "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
27369 ++ uid_buf, pid_buf, cmd_buf, 0};
27370 ++
27371 ++ if (vx_info_state(vxi, VXS_HELPER))
27372 ++ return -EAGAIN;
27373 ++ vxi->vx_state |= VXS_HELPER;
27374 ++
27375 ++ snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id);
27376 ++
27377 ++ snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
27378 ++ snprintf(uid_buf, sizeof(uid_buf)-1, "VS_UID=%d", current->uid);
27379 ++ snprintf(pid_buf, sizeof(pid_buf)-1, "VS_PID=%d", current->pid);
27380 ++
27381 ++ switch (cmd) {
27382 ++ case LINUX_REBOOT_CMD_RESTART:
27383 ++ argv[1] = "restart";
27384 ++ break;
27385 ++
27386 ++ case LINUX_REBOOT_CMD_HALT:
27387 ++ argv[1] = "halt";
27388 ++ break;
27389 ++
27390 ++ case LINUX_REBOOT_CMD_POWER_OFF:
27391 ++ argv[1] = "poweroff";
27392 ++ break;
27393 ++
27394 ++ case LINUX_REBOOT_CMD_SW_SUSPEND:
27395 ++ argv[1] = "swsusp";
27396 ++ break;
27397 ++
27398 ++ default:
27399 ++ vxi->vx_state &= ~VXS_HELPER;
27400 ++ return 0;
27401 ++ }
27402 ++
27403 ++ ret = do_vshelper(vshelper_path, argv, envp, 0);
27404 ++ vxi->vx_state &= ~VXS_HELPER;
27405 ++ __wakeup_vx_info(vxi);
27406 ++ return (ret) ? -EPERM : 0;
27407 ++}
27408 ++
27409 ++
27410 ++long vs_reboot(unsigned int cmd, void __user *arg)
27411 ++{
27412 ++ struct vx_info *vxi = current->vx_info;
27413 ++ long ret = 0;
27414 ++
27415 ++ vxdprintk(VXD_CBIT(misc, 5),
27416 ++ "vs_reboot(%p[#%d],%d)",
27417 ++ vxi, vxi ? vxi->vx_id : 0, cmd);
27418 ++
27419 ++ ret = vs_reboot_helper(vxi, cmd, arg);
27420 ++ if (ret)
27421 ++ return ret;
27422 ++
27423 ++ vxi->reboot_cmd = cmd;
27424 ++ if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
27425 ++ switch (cmd) {
27426 ++ case LINUX_REBOOT_CMD_RESTART:
27427 ++ case LINUX_REBOOT_CMD_HALT:
27428 ++ case LINUX_REBOOT_CMD_POWER_OFF:
27429 ++ vx_info_kill(vxi, 0, SIGKILL);
27430 ++ vx_info_kill(vxi, 1, SIGKILL);
27431 ++ default:
27432 ++ break;
27433 ++ }
27434 ++ }
27435 ++ return 0;
27436 ++}
27437 ++
27438 ++
27439 ++/*
27440 ++ * argv [0] = vshelper_path;
27441 ++ * argv [1] = action: "startup", "shutdown"
27442 ++ * argv [2] = context identifier
27443 ++ *
27444 ++ * envp [*] = type-specific parameters
27445 ++ */
27446 ++
27447 ++long vs_state_change(struct vx_info *vxi, unsigned int cmd)
27448 ++{
27449 ++ char id_buf[8], cmd_buf[16];
27450 ++ char *argv[] = {vshelper_path, NULL, id_buf, 0};
27451 ++ char *envp[] = {"HOME=/", "TERM=linux",
27452 ++ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
27453 ++
27454 ++ if (!vx_info_flags(vxi, VXF_SC_HELPER, 0))
27455 ++ return 0;
27456 ++
27457 ++ snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id);
27458 ++ snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
27459 ++
27460 ++ switch (cmd) {
27461 ++ case VSC_STARTUP:
27462 ++ argv[1] = "startup";
27463 ++ break;
27464 ++ case VSC_SHUTDOWN:
27465 ++ argv[1] = "shutdown";
27466 ++ break;
27467 ++ default:
27468 ++ return 0;
27469 ++ }
27470 ++
27471 ++ return do_vshelper(vshelper_path, argv, envp, 1);
27472 ++}
27473 ++
27474 ++
27475 ++/*
27476 ++ * argv [0] = vshelper_path;
27477 ++ * argv [1] = action: "netup", "netdown"
27478 ++ * argv [2] = context identifier
27479 ++ *
27480 ++ * envp [*] = type-specific parameters
27481 ++ */
27482 ++
27483 ++long vs_net_change(struct nx_info *nxi, unsigned int cmd)
27484 ++{
27485 ++ char id_buf[8], cmd_buf[16];
27486 ++ char *argv[] = {vshelper_path, NULL, id_buf, 0};
27487 ++ char *envp[] = {"HOME=/", "TERM=linux",
27488 ++ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
27489 ++
27490 ++ if (!nx_info_flags(nxi, NXF_SC_HELPER, 0))
27491 ++ return 0;
27492 ++
27493 ++ snprintf(id_buf, sizeof(id_buf)-1, "%d", nxi->nx_id);
27494 ++ snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
27495 ++
27496 ++ switch (cmd) {
27497 ++ case VSC_NETUP:
27498 ++ argv[1] = "netup";
27499 ++ break;
27500 ++ case VSC_NETDOWN:
27501 ++ argv[1] = "netdown";
27502 ++ break;
27503 ++ default:
27504 ++ return 0;
27505 ++ }
27506 ++
27507 ++ return do_vshelper(vshelper_path, argv, envp, 1);
27508 ++}
27509 ++
27510 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/history.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/history.c
27511 +--- linux-2.6.22.19/kernel/vserver/history.c 1970-01-01 01:00:00 +0100
27512 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/history.c 2007-08-15 22:13:54 +0200
27513 +@@ -0,0 +1,258 @@
27514 ++/*
27515 ++ * kernel/vserver/history.c
27516 ++ *
27517 ++ * Virtual Context History Backtrace
27518 ++ *
27519 ++ * Copyright (C) 2004-2007 Herbert Pötzl
27520 ++ *
27521 ++ * V0.01 basic structure
27522 ++ * V0.02 hash/unhash and trace
27523 ++ * V0.03 preemption fixes
27524 ++ *
27525 ++ */
27526 ++
27527 ++#include <linux/module.h>
27528 ++#include <asm/uaccess.h>
27529 ++
27530 ++#include <linux/vserver/context.h>
27531 ++#include <linux/vserver/debug.h>
27532 ++#include <linux/vserver/debug_cmd.h>
27533 ++#include <linux/vserver/history.h>
27534 ++
27535 ++
27536 ++#ifdef CONFIG_VSERVER_HISTORY
27537 ++#define VXH_SIZE CONFIG_VSERVER_HISTORY_SIZE
27538 ++#else
27539 ++#define VXH_SIZE 64
27540 ++#endif
27541 ++
27542 ++struct _vx_history {
27543 ++ unsigned int counter;
27544 ++
27545 ++ struct _vx_hist_entry entry[VXH_SIZE + 1];
27546 ++};
27547 ++
27548 ++
27549 ++DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
27550 ++
27551 ++unsigned volatile int vxh_active = 1;
27552 ++
27553 ++static atomic_t sequence = ATOMIC_INIT(0);
27554 ++
27555 ++
27556 ++/* vxh_advance()
27557 ++
27558 ++ * requires disabled preemption */
27559 ++
27560 ++struct _vx_hist_entry *vxh_advance(void *loc)
27561 ++{
27562 ++ unsigned int cpu = smp_processor_id();
27563 ++ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
27564 ++ struct _vx_hist_entry *entry;
27565 ++ unsigned int index;
27566 ++
27567 ++ index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
27568 ++ entry = &hist->entry[index];
27569 ++
27570 ++ entry->seq = atomic_inc_return(&sequence);
27571 ++ entry->loc = loc;
27572 ++ return entry;
27573 ++}
27574 ++
27575 ++EXPORT_SYMBOL_GPL(vxh_advance);
27576 ++
27577 ++
27578 ++#define VXH_LOC_FMTS "(#%04x,*%d):%p"
27579 ++
27580 ++#define VXH_LOC_ARGS(e) (e)->seq, cpu, (e)->loc
27581 ++
27582 ++
27583 ++#define VXH_VXI_FMTS "%p[#%d,%d.%d]"
27584 ++
27585 ++#define VXH_VXI_ARGS(e) (e)->vxi.ptr, \
27586 ++ (e)->vxi.ptr ? (e)->vxi.xid : 0, \
27587 ++ (e)->vxi.ptr ? (e)->vxi.usecnt : 0, \
27588 ++ (e)->vxi.ptr ? (e)->vxi.tasks : 0
27589 ++
27590 ++void vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
27591 ++{
27592 ++ switch (e->type) {
27593 ++ case VXH_THROW_OOPS:
27594 ++ printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
27595 ++ break;
27596 ++
27597 ++ case VXH_GET_VX_INFO:
27598 ++ case VXH_PUT_VX_INFO:
27599 ++ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
27600 ++ VXH_LOC_ARGS(e),
27601 ++ (e->type == VXH_GET_VX_INFO) ? "get" : "put",
27602 ++ VXH_VXI_ARGS(e));
27603 ++ break;
27604 ++
27605 ++ case VXH_INIT_VX_INFO:
27606 ++ case VXH_SET_VX_INFO:
27607 ++ case VXH_CLR_VX_INFO:
27608 ++ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
27609 ++ VXH_LOC_ARGS(e),
27610 ++ (e->type == VXH_INIT_VX_INFO) ? "init" :
27611 ++ ((e->type == VXH_SET_VX_INFO) ? "set" : "clr"),
27612 ++ VXH_VXI_ARGS(e), e->sc.data);
27613 ++ break;
27614 ++
27615 ++ case VXH_CLAIM_VX_INFO:
27616 ++ case VXH_RELEASE_VX_INFO:
27617 ++ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
27618 ++ VXH_LOC_ARGS(e),
27619 ++ (e->type == VXH_CLAIM_VX_INFO) ? "claim" : "release",
27620 ++ VXH_VXI_ARGS(e), e->sc.data);
27621 ++ break;
27622 ++
27623 ++ case VXH_ALLOC_VX_INFO:
27624 ++ case VXH_DEALLOC_VX_INFO:
27625 ++ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
27626 ++ VXH_LOC_ARGS(e),
27627 ++ (e->type == VXH_ALLOC_VX_INFO) ? "alloc" : "dealloc",
27628 ++ VXH_VXI_ARGS(e));
27629 ++ break;
27630 ++
27631 ++ case VXH_HASH_VX_INFO:
27632 ++ case VXH_UNHASH_VX_INFO:
27633 ++ printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
27634 ++ VXH_LOC_ARGS(e),
27635 ++ (e->type == VXH_HASH_VX_INFO) ? "hash" : "unhash",
27636 ++ VXH_VXI_ARGS(e));
27637 ++ break;
27638 ++
27639 ++ case VXH_LOC_VX_INFO:
27640 ++ case VXH_LOOKUP_VX_INFO:
27641 ++ case VXH_CREATE_VX_INFO:
27642 ++ printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
27643 ++ VXH_LOC_ARGS(e),
27644 ++ (e->type == VXH_CREATE_VX_INFO) ? "create" :
27645 ++ ((e->type == VXH_LOC_VX_INFO) ? "loc" : "lookup"),
27646 ++ e->ll.arg, VXH_VXI_ARGS(e));
27647 ++ break;
27648 ++ }
27649 ++}
27650 ++
27651 ++static void __vxh_dump_history(void)
27652 ++{
27653 ++ unsigned int i, cpu;
27654 ++
27655 ++ printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
27656 ++ atomic_read(&sequence), NR_CPUS);
27657 ++
27658 ++ for (i = 0; i < VXH_SIZE; i++) {
27659 ++ for_each_online_cpu(cpu) {
27660 ++ struct _vx_history *hist =
27661 ++ &per_cpu(vx_history_buffer, cpu);
27662 ++ unsigned int index = (hist->counter - i) % VXH_SIZE;
27663 ++ struct _vx_hist_entry *entry = &hist->entry[index];
27664 ++
27665 ++ vxh_dump_entry(entry, cpu);
27666 ++ }
27667 ++ }
27668 ++}
27669 ++
27670 ++void vxh_dump_history(void)
27671 ++{
27672 ++ vxh_active = 0;
27673 ++#ifdef CONFIG_SMP
27674 ++ local_irq_enable();
27675 ++ smp_send_stop();
27676 ++ local_irq_disable();
27677 ++#endif
27678 ++ __vxh_dump_history();
27679 ++}
27680 ++
27681 ++
27682 ++/* vserver syscall commands below here */
27683 ++
27684 ++
27685 ++int vc_dump_history(uint32_t id)
27686 ++{
27687 ++ vxh_active = 0;
27688 ++ __vxh_dump_history();
27689 ++ vxh_active = 1;
27690 ++
27691 ++ return 0;
27692 ++}
27693 ++
27694 ++
27695 ++int do_read_history(struct __user _vx_hist_entry *data,
27696 ++ int cpu, uint32_t *index, uint32_t *count)
27697 ++{
27698 ++ int pos, ret = 0;
27699 ++ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
27700 ++ int end = hist->counter;
27701 ++ int start = end - VXH_SIZE + 2;
27702 ++ int idx = *index;
27703 ++
27704 ++ /* special case: get current pos */
27705 ++ if (!*count) {
27706 ++ *index = end;
27707 ++ return 0;
27708 ++ }
27709 ++
27710 ++ /* have we lost some data? */
27711 ++ if (idx < start)
27712 ++ idx = start;
27713 ++
27714 ++ for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
27715 ++ struct _vx_hist_entry *entry =
27716 ++ &hist->entry[idx % VXH_SIZE];
27717 ++
27718 ++ /* send entry to userspace */
27719 ++ ret = copy_to_user(&data[pos], entry, sizeof(*entry));
27720 ++ if (ret)
27721 ++ break;
27722 ++ }
27723 ++ /* save new index and count */
27724 ++ *index = idx;
27725 ++ *count = pos;
27726 ++ return ret ? ret : (*index < end);
27727 ++}
27728 ++
27729 ++int vc_read_history(uint32_t id, void __user *data)
27730 ++{
27731 ++ struct vcmd_read_history_v0 vc_data;
27732 ++ int ret;
27733 ++
27734 ++ if (id >= NR_CPUS)
27735 ++ return -EINVAL;
27736 ++
27737 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
27738 ++ return -EFAULT;
27739 ++
27740 ++ ret = do_read_history((struct __user _vx_hist_entry *)vc_data.data,
27741 ++ id, &vc_data.index, &vc_data.count);
27742 ++
27743 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
27744 ++ return -EFAULT;
27745 ++ return ret;
27746 ++}
27747 ++
27748 ++#ifdef CONFIG_COMPAT
27749 ++
27750 ++int vc_read_history_x32(uint32_t id, void __user *data)
27751 ++{
27752 ++ struct vcmd_read_history_v0_x32 vc_data;
27753 ++ int ret;
27754 ++
27755 ++ if (id >= NR_CPUS)
27756 ++ return -EINVAL;
27757 ++
27758 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
27759 ++ return -EFAULT;
27760 ++
27761 ++ ret = do_read_history((struct __user _vx_hist_entry *)
27762 ++ compat_ptr(vc_data.data_ptr),
27763 ++ id, &vc_data.index, &vc_data.count);
27764 ++
27765 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
27766 ++ return -EFAULT;
27767 ++ return ret;
27768 ++}
27769 ++
27770 ++#endif /* CONFIG_COMPAT */
27771 ++
27772 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/inet.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/inet.c
27773 +--- linux-2.6.22.19/kernel/vserver/inet.c 1970-01-01 01:00:00 +0100
27774 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/inet.c 2008-02-07 15:34:29 +0100
27775 +@@ -0,0 +1,223 @@
27776 ++
27777 ++#include <linux/in.h>
27778 ++#include <linux/inetdevice.h>
27779 ++#include <linux/vs_inet6.h>
27780 ++#include <linux/vserver/debug.h>
27781 ++#include <net/route.h>
27782 ++#include <net/addrconf.h>
27783 ++
27784 ++
27785 ++int nx_v4_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
27786 ++{
27787 ++ int ret = 0;
27788 ++
27789 ++ if (!nxi1 || !nxi2 || nxi1 == nxi2)
27790 ++ ret = 1;
27791 ++ else {
27792 ++ struct nx_addr_v4 *ptr;
27793 ++
27794 ++ for (ptr = &nxi1->v4; ptr; ptr = ptr->next) {
27795 ++ if (v4_nx_addr_in_nx_info(nxi2, ptr, -1)) {
27796 ++ ret = 1;
27797 ++ break;
27798 ++ }
27799 ++ }
27800 ++ }
27801 ++
27802 ++ vxdprintk(VXD_CBIT(net, 2),
27803 ++ "nx_v4_addr_conflict(%p,%p): %d",
27804 ++ nxi1, nxi2, ret);
27805 ++
27806 ++ return ret;
27807 ++}
27808 ++
27809 ++
27810 ++#ifdef CONFIG_IPV6
27811 ++
27812 ++int nx_v6_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
27813 ++{
27814 ++ int ret = 0;
27815 ++
27816 ++ if (!nxi1 || !nxi2 || nxi1 == nxi2)
27817 ++ ret = 1;
27818 ++ else {
27819 ++ struct nx_addr_v6 *ptr;
27820 ++
27821 ++ for (ptr = &nxi1->v6; ptr; ptr = ptr->next) {
27822 ++ if (v6_nx_addr_in_nx_info(nxi2, ptr, -1)) {
27823 ++ ret = 1;
27824 ++ break;
27825 ++ }
27826 ++ }
27827 ++ }
27828 ++
27829 ++ vxdprintk(VXD_CBIT(net, 2),
27830 ++ "nx_v6_addr_conflict(%p,%p): %d",
27831 ++ nxi1, nxi2, ret);
27832 ++
27833 ++ return ret;
27834 ++}
27835 ++
27836 ++#endif
27837 ++
27838 ++int v4_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
27839 ++{
27840 ++ struct in_device *in_dev;
27841 ++ struct in_ifaddr **ifap;
27842 ++ struct in_ifaddr *ifa;
27843 ++ int ret = 0;
27844 ++
27845 ++ if (!dev)
27846 ++ goto out;
27847 ++ in_dev = in_dev_get(dev);
27848 ++ if (!in_dev)
27849 ++ goto out;
27850 ++
27851 ++ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
27852 ++ ifap = &ifa->ifa_next) {
27853 ++ if (v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW)) {
27854 ++ ret = 1;
27855 ++ break;
27856 ++ }
27857 ++ }
27858 ++ in_dev_put(in_dev);
27859 ++out:
27860 ++ return ret;
27861 ++}
27862 ++
27863 ++
27864 ++#ifdef CONFIG_IPV6
27865 ++
27866 ++int v6_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
27867 ++{
27868 ++ struct inet6_dev *in_dev;
27869 ++ struct inet6_ifaddr **ifap;
27870 ++ struct inet6_ifaddr *ifa;
27871 ++ int ret = 0;
27872 ++
27873 ++ if (!dev)
27874 ++ goto out;
27875 ++ in_dev = in6_dev_get(dev);
27876 ++ if (!in_dev)
27877 ++ goto out;
27878 ++
27879 ++ for (ifap = &in_dev->addr_list; (ifa = *ifap) != NULL;
27880 ++ ifap = &ifa->if_next) {
27881 ++ if (v6_addr_in_nx_info(nxi, &ifa->addr, -1)) {
27882 ++ ret = 1;
27883 ++ break;
27884 ++ }
27885 ++ }
27886 ++ in6_dev_put(in_dev);
27887 ++out:
27888 ++ return ret;
27889 ++}
27890 ++
27891 ++#endif
27892 ++
27893 ++int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
27894 ++{
27895 ++ int ret = 1;
27896 ++
27897 ++ if (!nxi)
27898 ++ goto out;
27899 ++ if (nxi->v4.type && v4_dev_in_nx_info(dev, nxi))
27900 ++ goto out;
27901 ++#ifdef CONFIG_IPV6
27902 ++ ret = 2;
27903 ++ if (nxi->v6.type && v6_dev_in_nx_info(dev, nxi))
27904 ++ goto out;
27905 ++#endif
27906 ++ ret = 0;
27907 ++out:
27908 ++ vxdprintk(VXD_CBIT(net, 3),
27909 ++ "dev_in_nx_info(%p,%p[#%d]) = %d",
27910 ++ dev, nxi, nxi ? nxi->nx_id : 0, ret);
27911 ++ return ret;
27912 ++}
27913 ++
27914 ++int ip_v4_find_src(struct nx_info *nxi, struct rtable **rp, struct flowi *fl)
27915 ++{
27916 ++ if (!nxi)
27917 ++ return 0;
27918 ++
27919 ++ /* FIXME: handle lback only case */
27920 ++ if (!NX_IPV4(nxi))
27921 ++ return -EPERM;
27922 ++
27923 ++ vxdprintk(VXD_CBIT(net, 4),
27924 ++ "ip_v4_find_src(%p[#%u]) " NIPQUAD_FMT " -> " NIPQUAD_FMT,
27925 ++ nxi, nxi ? nxi->nx_id : 0,
27926 ++ NIPQUAD(fl->fl4_src), NIPQUAD(fl->fl4_dst));
27927 ++
27928 ++ /* single IP is unconditional */
27929 ++ if (nx_info_flags(nxi, NXF_SINGLE_IP, 0) &&
27930 ++ (fl->fl4_src == INADDR_ANY))
27931 ++ fl->fl4_src = nxi->v4.ip[0].s_addr;
27932 ++
27933 ++ if (fl->fl4_src == INADDR_ANY) {
27934 ++ struct nx_addr_v4 *ptr;
27935 ++ __be32 found;
27936 ++ int err;
27937 ++
27938 ++ err = __ip_route_output_key(rp, fl);
27939 ++ if (!err) {
27940 ++ found = (*rp)->rt_src;
27941 ++ ip_rt_put(*rp);
27942 ++ vxdprintk(VXD_CBIT(net, 4),
27943 ++ "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
27944 ++ nxi, nxi ? nxi->nx_id : 0, fl->oif, NIPQUAD(found));
27945 ++ if (v4_addr_in_nx_info(nxi, found, NXA_MASK_BIND))
27946 ++ goto found;
27947 ++ }
27948 ++
27949 ++ for (ptr = &nxi->v4; ptr; ptr = ptr->next) {
27950 ++ __be32 primary = ptr->ip[0].s_addr;
27951 ++ __be32 mask = ptr->mask.s_addr;
27952 ++ __be32 net = primary & mask;
27953 ++
27954 ++ vxdprintk(VXD_CBIT(net, 4), "ip_v4_find_src(%p[#%u]) chk: "
27955 ++ NIPQUAD_FMT "/" NIPQUAD_FMT "/" NIPQUAD_FMT,
27956 ++ nxi, nxi ? nxi->nx_id : 0, NIPQUAD(primary),
27957 ++ NIPQUAD(mask), NIPQUAD(net));
27958 ++ if ((found & mask) != net)
27959 ++ continue;
27960 ++
27961 ++ fl->fl4_src = primary;
27962 ++ err = __ip_route_output_key(rp, fl);
27963 ++ vxdprintk(VXD_CBIT(net, 4),
27964 ++ "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
27965 ++ nxi, nxi ? nxi->nx_id : 0, fl->oif, NIPQUAD(primary));
27966 ++ if (!err) {
27967 ++ found = (*rp)->rt_src;
27968 ++ ip_rt_put(*rp);
27969 ++ if (found == primary)
27970 ++ goto found;
27971 ++ }
27972 ++ }
27973 ++ /* still no source ip? */
27974 ++ found = LOOPBACK(fl->fl4_dst)
27975 ++ ? IPI_LOOPBACK : nxi->v4.ip[0].s_addr;
27976 ++ found:
27977 ++ /* assign src ip to flow */
27978 ++ fl->fl4_src = found;
27979 ++
27980 ++ } else {
27981 ++ if (!v4_addr_in_nx_info(nxi, fl->fl4_src, NXA_MASK_BIND))
27982 ++ return -EPERM;
27983 ++ }
27984 ++
27985 ++ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0)) {
27986 ++ if (LOOPBACK(fl->fl4_dst))
27987 ++ fl->fl4_dst = nxi->v4_lback.s_addr;
27988 ++ if (LOOPBACK(fl->fl4_src))
27989 ++ fl->fl4_src = nxi->v4_lback.s_addr;
27990 ++ } else if (LOOPBACK(fl->fl4_dst) &&
27991 ++ !nx_info_flags(nxi, NXF_LBACK_ALLOW, 0))
27992 ++ return -EPERM;
27993 ++
27994 ++ return 0;
27995 ++}
27996 ++
27997 ++EXPORT_SYMBOL_GPL(ip_v4_find_src);
27998 ++
27999 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/init.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/init.c
28000 +--- linux-2.6.22.19/kernel/vserver/init.c 1970-01-01 01:00:00 +0100
28001 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/init.c 2007-08-15 22:15:36 +0200
28002 +@@ -0,0 +1,45 @@
28003 ++/*
28004 ++ * linux/kernel/init.c
28005 ++ *
28006 ++ * Virtual Server Init
28007 ++ *
28008 ++ * Copyright (C) 2004-2007 Herbert Pötzl
28009 ++ *
28010 ++ * V0.01 basic structure
28011 ++ *
28012 ++ */
28013 ++
28014 ++#include <linux/init.h>
28015 ++
28016 ++int vserver_register_sysctl(void);
28017 ++void vserver_unregister_sysctl(void);
28018 ++
28019 ++
28020 ++static int __init init_vserver(void)
28021 ++{
28022 ++ int ret = 0;
28023 ++
28024 ++#ifdef CONFIG_VSERVER_DEBUG
28025 ++ vserver_register_sysctl();
28026 ++#endif
28027 ++ return ret;
28028 ++}
28029 ++
28030 ++
28031 ++static void __exit exit_vserver(void)
28032 ++{
28033 ++
28034 ++#ifdef CONFIG_VSERVER_DEBUG
28035 ++ vserver_unregister_sysctl();
28036 ++#endif
28037 ++ return;
28038 ++}
28039 ++
28040 ++/* FIXME: GFP_ZONETYPES gone
28041 ++long vx_slab[GFP_ZONETYPES]; */
28042 ++long vx_area;
28043 ++
28044 ++
28045 ++module_init(init_vserver);
28046 ++module_exit(exit_vserver);
28047 ++
28048 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/inode.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/inode.c
28049 +--- linux-2.6.22.19/kernel/vserver/inode.c 1970-01-01 01:00:00 +0100
28050 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/inode.c 2007-09-11 17:57:41 +0200
28051 +@@ -0,0 +1,409 @@
28052 ++/*
28053 ++ * linux/kernel/vserver/inode.c
28054 ++ *
28055 ++ * Virtual Server: File System Support
28056 ++ *
28057 ++ * Copyright (C) 2004-2007 Herbert Pötzl
28058 ++ *
28059 ++ * V0.01 separated from vcontext V0.05
28060 ++ * V0.02 moved to tag (instead of xid)
28061 ++ *
28062 ++ */
28063 ++
28064 ++#include <linux/tty.h>
28065 ++#include <linux/proc_fs.h>
28066 ++#include <linux/devpts_fs.h>
28067 ++#include <linux/fs.h>
28068 ++#include <linux/file.h>
28069 ++#include <linux/mount.h>
28070 ++#include <linux/parser.h>
28071 ++#include <linux/vserver/inode.h>
28072 ++#include <linux/vserver/inode_cmd.h>
28073 ++#include <linux/vs_base.h>
28074 ++#include <linux/vs_tag.h>
28075 ++
28076 ++#include <asm/uaccess.h>
28077 ++
28078 ++
28079 ++static int __vc_get_iattr(struct inode *in, uint32_t *tag, uint32_t *flags, uint32_t *mask)
28080 ++{
28081 ++ struct proc_dir_entry *entry;
28082 ++
28083 ++ if (!in || !in->i_sb)
28084 ++ return -ESRCH;
28085 ++
28086 ++ *flags = IATTR_TAG
28087 ++ | (IS_BARRIER(in) ? IATTR_BARRIER : 0)
28088 ++ | (IS_IUNLINK(in) ? IATTR_IUNLINK : 0)
28089 ++ | (IS_IMMUTABLE(in) ? IATTR_IMMUTABLE : 0);
28090 ++ *mask = IATTR_IUNLINK | IATTR_IMMUTABLE;
28091 ++
28092 ++ if (S_ISDIR(in->i_mode))
28093 ++ *mask |= IATTR_BARRIER;
28094 ++
28095 ++ if (IS_TAGGED(in)) {
28096 ++ *tag = in->i_tag;
28097 ++ *mask |= IATTR_TAG;
28098 ++ }
28099 ++
28100 ++ switch (in->i_sb->s_magic) {
28101 ++ case PROC_SUPER_MAGIC:
28102 ++ entry = PROC_I(in)->pde;
28103 ++
28104 ++ /* check for specific inodes? */
28105 ++ if (entry)
28106 ++ *mask |= IATTR_FLAGS;
28107 ++ if (entry)
28108 ++ *flags |= (entry->vx_flags & IATTR_FLAGS);
28109 ++ else
28110 ++ *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS);
28111 ++ break;
28112 ++
28113 ++ case DEVPTS_SUPER_MAGIC:
28114 ++ *tag = in->i_tag;
28115 ++ *mask |= IATTR_TAG;
28116 ++ break;
28117 ++
28118 ++ default:
28119 ++ break;
28120 ++ }
28121 ++ return 0;
28122 ++}
28123 ++
28124 ++int vc_get_iattr(void __user *data)
28125 ++{
28126 ++ struct nameidata nd;
28127 ++ struct vcmd_ctx_iattr_v1 vc_data = { .tag = -1 };
28128 ++ int ret;
28129 ++
28130 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
28131 ++ return -EFAULT;
28132 ++
28133 ++ ret = user_path_walk_link(vc_data.name, &nd);
28134 ++ if (!ret) {
28135 ++ ret = __vc_get_iattr(nd.dentry->d_inode,
28136 ++ &vc_data.tag, &vc_data.flags, &vc_data.mask);
28137 ++ path_release(&nd);
28138 ++ }
28139 ++ if (ret)
28140 ++ return ret;
28141 ++
28142 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
28143 ++ ret = -EFAULT;
28144 ++ return ret;
28145 ++}
28146 ++
28147 ++#ifdef CONFIG_COMPAT
28148 ++
28149 ++int vc_get_iattr_x32(void __user *data)
28150 ++{
28151 ++ struct nameidata nd;
28152 ++ struct vcmd_ctx_iattr_v1_x32 vc_data = { .tag = -1 };
28153 ++ int ret;
28154 ++
28155 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
28156 ++ return -EFAULT;
28157 ++
28158 ++ ret = user_path_walk_link(compat_ptr(vc_data.name_ptr), &nd);
28159 ++ if (!ret) {
28160 ++ ret = __vc_get_iattr(nd.dentry->d_inode,
28161 ++ &vc_data.tag, &vc_data.flags, &vc_data.mask);
28162 ++ path_release(&nd);
28163 ++ }
28164 ++ if (ret)
28165 ++ return ret;
28166 ++
28167 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
28168 ++ ret = -EFAULT;
28169 ++ return ret;
28170 ++}
28171 ++
28172 ++#endif /* CONFIG_COMPAT */
28173 ++
28174 ++
28175 ++int vc_fget_iattr(uint32_t fd, void __user *data)
28176 ++{
28177 ++ struct file *filp;
28178 ++ struct vcmd_ctx_fiattr_v0 vc_data = { .tag = -1 };
28179 ++ int ret;
28180 ++
28181 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
28182 ++ return -EFAULT;
28183 ++
28184 ++ filp = fget(fd);
28185 ++ if (!filp || !filp->f_dentry || !filp->f_dentry->d_inode)
28186 ++ return -EBADF;
28187 ++
28188 ++ ret = __vc_get_iattr(filp->f_dentry->d_inode,
28189 ++ &vc_data.tag, &vc_data.flags, &vc_data.mask);
28190 ++
28191 ++ fput(filp);
28192 ++
28193 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
28194 ++ ret = -EFAULT;
28195 ++ return ret;
28196 ++}
28197 ++
28198 ++
28199 ++static int __vc_set_iattr(struct dentry *de, uint32_t *tag, uint32_t *flags, uint32_t *mask)
28200 ++{
28201 ++ struct inode *in = de->d_inode;
28202 ++ int error = 0, is_proc = 0, has_tag = 0;
28203 ++ struct iattr attr = { 0 };
28204 ++
28205 ++ if (!in || !in->i_sb)
28206 ++ return -ESRCH;
28207 ++
28208 ++ is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC);
28209 ++ if ((*mask & IATTR_FLAGS) && !is_proc)
28210 ++ return -EINVAL;
28211 ++
28212 ++ has_tag = IS_TAGGED(in) ||
28213 ++ (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC);
28214 ++ if ((*mask & IATTR_TAG) && !has_tag)
28215 ++ return -EINVAL;
28216 ++
28217 ++ mutex_lock(&in->i_mutex);
28218 ++ if (*mask & IATTR_TAG) {
28219 ++ attr.ia_tag = *tag;
28220 ++ attr.ia_valid |= ATTR_TAG;
28221 ++ }
28222 ++
28223 ++ if (*mask & IATTR_FLAGS) {
28224 ++ struct proc_dir_entry *entry = PROC_I(in)->pde;
28225 ++ unsigned int iflags = PROC_I(in)->vx_flags;
28226 ++
28227 ++ iflags = (iflags & ~(*mask & IATTR_FLAGS))
28228 ++ | (*flags & IATTR_FLAGS);
28229 ++ PROC_I(in)->vx_flags = iflags;
28230 ++ if (entry)
28231 ++ entry->vx_flags = iflags;
28232 ++ }
28233 ++
28234 ++ if (*mask & (IATTR_BARRIER | IATTR_IUNLINK | IATTR_IMMUTABLE)) {
28235 ++ if (*mask & IATTR_IMMUTABLE) {
28236 ++ if (*flags & IATTR_IMMUTABLE)
28237 ++ in->i_flags |= S_IMMUTABLE;
28238 ++ else
28239 ++ in->i_flags &= ~S_IMMUTABLE;
28240 ++ }
28241 ++ if (*mask & IATTR_IUNLINK) {
28242 ++ if (*flags & IATTR_IUNLINK)
28243 ++ in->i_flags |= S_IUNLINK;
28244 ++ else
28245 ++ in->i_flags &= ~S_IUNLINK;
28246 ++ }
28247 ++ if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) {
28248 ++ if (*flags & IATTR_BARRIER)
28249 ++ in->i_flags |= S_BARRIER;
28250 ++ else
28251 ++ in->i_flags &= ~S_BARRIER;
28252 ++ }
28253 ++ if (in->i_op && in->i_op->sync_flags) {
28254 ++ error = in->i_op->sync_flags(in);
28255 ++ if (error)
28256 ++ goto out;
28257 ++ }
28258 ++ }
28259 ++
28260 ++ if (attr.ia_valid) {
28261 ++ if (in->i_op && in->i_op->setattr)
28262 ++ error = in->i_op->setattr(de, &attr);
28263 ++ else {
28264 ++ error = inode_change_ok(in, &attr);
28265 ++ if (!error)
28266 ++ error = inode_setattr(in, &attr);
28267 ++ }
28268 ++ }
28269 ++
28270 ++out:
28271 ++ mutex_unlock(&in->i_mutex);
28272 ++ return error;
28273 ++}
28274 ++
28275 ++int vc_set_iattr(void __user *data)
28276 ++{
28277 ++ struct nameidata nd;
28278 ++ struct vcmd_ctx_iattr_v1 vc_data;
28279 ++ int ret;
28280 ++
28281 ++ if (!capable(CAP_LINUX_IMMUTABLE))
28282 ++ return -EPERM;
28283 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
28284 ++ return -EFAULT;
28285 ++
28286 ++ ret = user_path_walk_link(vc_data.name, &nd);
28287 ++ if (!ret) {
28288 ++ ret = __vc_set_iattr(nd.dentry,
28289 ++ &vc_data.tag, &vc_data.flags, &vc_data.mask);
28290 ++ path_release(&nd);
28291 ++ }
28292 ++
28293 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
28294 ++ ret = -EFAULT;
28295 ++ return ret;
28296 ++}
28297 ++
28298 ++#ifdef CONFIG_COMPAT
28299 ++
28300 ++int vc_set_iattr_x32(void __user *data)
28301 ++{
28302 ++ struct nameidata nd;
28303 ++ struct vcmd_ctx_iattr_v1_x32 vc_data;
28304 ++ int ret;
28305 ++
28306 ++ if (!capable(CAP_LINUX_IMMUTABLE))
28307 ++ return -EPERM;
28308 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
28309 ++ return -EFAULT;
28310 ++
28311 ++ ret = user_path_walk_link(compat_ptr(vc_data.name_ptr), &nd);
28312 ++ if (!ret) {
28313 ++ ret = __vc_set_iattr(nd.dentry,
28314 ++ &vc_data.tag, &vc_data.flags, &vc_data.mask);
28315 ++ path_release(&nd);
28316 ++ }
28317 ++
28318 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
28319 ++ ret = -EFAULT;
28320 ++ return ret;
28321 ++}
28322 ++
28323 ++#endif /* CONFIG_COMPAT */
28324 ++
28325 ++int vc_fset_iattr(uint32_t fd, void __user *data)
28326 ++{
28327 ++ struct file *filp;
28328 ++ struct vcmd_ctx_fiattr_v0 vc_data;
28329 ++ int ret;
28330 ++
28331 ++ if (!capable(CAP_LINUX_IMMUTABLE))
28332 ++ return -EPERM;
28333 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
28334 ++ return -EFAULT;
28335 ++
28336 ++ filp = fget(fd);
28337 ++ if (!filp || !filp->f_dentry || !filp->f_dentry->d_inode)
28338 ++ return -EBADF;
28339 ++
28340 ++ ret = __vc_set_iattr(filp->f_dentry, &vc_data.tag,
28341 ++ &vc_data.flags, &vc_data.mask);
28342 ++
28343 ++ fput(filp);
28344 ++
28345 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
28346 ++ return -EFAULT;
28347 ++ return ret;
28348 ++}
28349 ++
28350 ++
28351 ++enum { Opt_notagcheck, Opt_tag, Opt_notag, Opt_tagid, Opt_err };
28352 ++
28353 ++static match_table_t tokens = {
28354 ++ {Opt_notagcheck, "notagcheck"},
28355 ++#ifdef CONFIG_PROPAGATE
28356 ++ {Opt_notag, "notag"},
28357 ++ {Opt_tag, "tag"},
28358 ++ {Opt_tagid, "tagid=%u"},
28359 ++#endif
28360 ++ {Opt_err, NULL}
28361 ++};
28362 ++
28363 ++
28364 ++static void __dx_parse_remove(char *string, char *opt)
28365 ++{
28366 ++ char *p = strstr(string, opt);
28367 ++ char *q = p;
28368 ++
28369 ++ if (p) {
28370 ++ while (*q != '\0' && *q != ',')
28371 ++ q++;
28372 ++ while (*q)
28373 ++ *p++ = *q++;
28374 ++ while (*p)
28375 ++ *p++ = '\0';
28376 ++ }
28377 ++}
28378 ++
28379 ++static inline
28380 ++int __dx_parse_tag(char *string, tag_t *tag, int remove)
28381 ++{
28382 ++ substring_t args[MAX_OPT_ARGS];
28383 ++ int token, option = 0;
28384 ++
28385 ++ if (!string)
28386 ++ return 0;
28387 ++
28388 ++ token = match_token(string, tokens, args);
28389 ++
28390 ++ vxdprintk(VXD_CBIT(tag, 7),
28391 ++ "dx_parse_tag(»%s«): %d:#%d",
28392 ++ string, token, option);
28393 ++
28394 ++ switch (token) {
28395 ++ case Opt_tag:
28396 ++ if (tag)
28397 ++ *tag = 0;
28398 ++ if (remove)
28399 ++ __dx_parse_remove(string, "tag");
28400 ++ return MNT_TAGID;
28401 ++ case Opt_notag:
28402 ++ if (remove)
28403 ++ __dx_parse_remove(string, "notag");
28404 ++ return MNT_NOTAG;
28405 ++ case Opt_notagcheck:
28406 ++ if (remove)
28407 ++ __dx_parse_remove(string, "notagcheck");
28408 ++ return MNT_NOTAGCHECK;
28409 ++ case Opt_tagid:
28410 ++ if (tag && !match_int(args, &option))
28411 ++ *tag = option;
28412 ++ if (remove)
28413 ++ __dx_parse_remove(string, "tagid");
28414 ++ return MNT_TAGID;
28415 ++ }
28416 ++ return 0;
28417 ++}
28418 ++
28419 ++int dx_parse_tag(char *string, tag_t *tag, int remove)
28420 ++{
28421 ++ int retval, flags = 0;
28422 ++
28423 ++ while ((retval = __dx_parse_tag(string, tag, remove)))
28424 ++ flags |= retval;
28425 ++ return flags;
28426 ++}
28427 ++
28428 ++#ifdef CONFIG_PROPAGATE
28429 ++
28430 ++void __dx_propagate_tag(struct nameidata *nd, struct inode *inode)
28431 ++{
28432 ++ tag_t new_tag = 0;
28433 ++ struct vfsmount *mnt;
28434 ++ int propagate;
28435 ++
28436 ++ if (!nd)
28437 ++ return;
28438 ++ mnt = nd->mnt;
28439 ++ if (!mnt)
28440 ++ return;
28441 ++
28442 ++ propagate = (mnt->mnt_flags & MNT_TAGID);
28443 ++ if (propagate)
28444 ++ new_tag = mnt->mnt_tag;
28445 ++
28446 ++ vxdprintk(VXD_CBIT(tag, 7),
28447 ++ "dx_propagate_tag(%p[#%lu.%d]): %d,%d",
28448 ++ inode, inode->i_ino, inode->i_tag,
28449 ++ new_tag, (propagate) ? 1 : 0);
28450 ++
28451 ++ if (propagate)
28452 ++ inode->i_tag = new_tag;
28453 ++}
28454 ++
28455 ++#include <linux/module.h>
28456 ++
28457 ++EXPORT_SYMBOL_GPL(__dx_propagate_tag);
28458 ++
28459 ++#endif /* CONFIG_PROPAGATE */
28460 ++
28461 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/limit.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/limit.c
28462 +--- linux-2.6.22.19/kernel/vserver/limit.c 1970-01-01 01:00:00 +0100
28463 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/limit.c 2007-08-19 00:08:19 +0200
28464 +@@ -0,0 +1,318 @@
28465 ++/*
28466 ++ * linux/kernel/vserver/limit.c
28467 ++ *
28468 ++ * Virtual Server: Context Limits
28469 ++ *
28470 ++ * Copyright (C) 2004-2007 Herbert Pötzl
28471 ++ *
28472 ++ * V0.01 broken out from vcontext V0.05
28473 ++ * V0.02 changed vcmds to vxi arg
28474 ++ *
28475 ++ */
28476 ++
28477 ++#include <linux/module.h>
28478 ++#include <linux/vs_limit.h>
28479 ++#include <linux/vserver/limit.h>
28480 ++#include <linux/vserver/limit_cmd.h>
28481 ++
28482 ++#include <asm/uaccess.h>
28483 ++
28484 ++
28485 ++const char *vlimit_name[NUM_LIMITS] = {
28486 ++ [RLIMIT_CPU] = "CPU",
28487 ++ [RLIMIT_RSS] = "RSS",
28488 ++ [RLIMIT_NPROC] = "NPROC",
28489 ++ [RLIMIT_NOFILE] = "NOFILE",
28490 ++ [RLIMIT_MEMLOCK] = "VML",
28491 ++ [RLIMIT_AS] = "VM",
28492 ++ [RLIMIT_LOCKS] = "LOCKS",
28493 ++ [RLIMIT_SIGPENDING] = "SIGP",
28494 ++ [RLIMIT_MSGQUEUE] = "MSGQ",
28495 ++
28496 ++ [VLIMIT_NSOCK] = "NSOCK",
28497 ++ [VLIMIT_OPENFD] = "OPENFD",
28498 ++ [VLIMIT_ANON] = "ANON",
28499 ++ [VLIMIT_SHMEM] = "SHMEM",
28500 ++ [VLIMIT_DENTRY] = "DENTRY",
28501 ++};
28502 ++
28503 ++EXPORT_SYMBOL_GPL(vlimit_name);
28504 ++
28505 ++#define MASK_ENTRY(x) (1 << (x))
28506 ++
28507 ++const struct vcmd_ctx_rlimit_mask_v0 vlimit_mask = {
28508 ++ /* minimum */
28509 ++ 0
28510 ++ , /* softlimit */
28511 ++ MASK_ENTRY( RLIMIT_RSS ) |
28512 ++ MASK_ENTRY( VLIMIT_ANON ) |
28513 ++ 0
28514 ++ , /* maximum */
28515 ++ MASK_ENTRY( RLIMIT_RSS ) |
28516 ++ MASK_ENTRY( RLIMIT_NPROC ) |
28517 ++ MASK_ENTRY( RLIMIT_NOFILE ) |
28518 ++ MASK_ENTRY( RLIMIT_MEMLOCK ) |
28519 ++ MASK_ENTRY( RLIMIT_AS ) |
28520 ++ MASK_ENTRY( RLIMIT_LOCKS ) |
28521 ++ MASK_ENTRY( RLIMIT_MSGQUEUE ) |
28522 ++
28523 ++ MASK_ENTRY( VLIMIT_NSOCK ) |
28524 ++ MASK_ENTRY( VLIMIT_OPENFD ) |
28525 ++ MASK_ENTRY( VLIMIT_ANON ) |
28526 ++ MASK_ENTRY( VLIMIT_SHMEM ) |
28527 ++ MASK_ENTRY( VLIMIT_DENTRY ) |
28528 ++ 0
28529 ++};
28530 ++ /* accounting only */
28531 ++uint32_t account_mask =
28532 ++ MASK_ENTRY( VLIMIT_SEMARY ) |
28533 ++ MASK_ENTRY( VLIMIT_NSEMS ) |
28534 ++ MASK_ENTRY( VLIMIT_MAPPED ) |
28535 ++ 0;
28536 ++
28537 ++
28538 ++static int is_valid_vlimit(int id)
28539 ++{
28540 ++ uint32_t mask = vlimit_mask.minimum |
28541 ++ vlimit_mask.softlimit | vlimit_mask.maximum;
28542 ++ return mask & (1 << id);
28543 ++}
28544 ++
28545 ++static int is_accounted_vlimit(int id)
28546 ++{
28547 ++ if (is_valid_vlimit(id))
28548 ++ return 1;
28549 ++ return account_mask & (1 << id);
28550 ++}
28551 ++
28552 ++
28553 ++static inline uint64_t vc_get_soft(struct vx_info *vxi, int id)
28554 ++{
28555 ++ rlim_t limit = __rlim_soft(&vxi->limit, id);
28556 ++ return VX_VLIM(limit);
28557 ++}
28558 ++
28559 ++static inline uint64_t vc_get_hard(struct vx_info *vxi, int id)
28560 ++{
28561 ++ rlim_t limit = __rlim_hard(&vxi->limit, id);
28562 ++ return VX_VLIM(limit);
28563 ++}
28564 ++
28565 ++static int do_get_rlimit(struct vx_info *vxi, uint32_t id,
28566 ++ uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
28567 ++{
28568 ++ if (!is_valid_vlimit(id))
28569 ++ return -EINVAL;
28570 ++
28571 ++ if (minimum)
28572 ++ *minimum = CRLIM_UNSET;
28573 ++ if (softlimit)
28574 ++ *softlimit = vc_get_soft(vxi, id);
28575 ++ if (maximum)
28576 ++ *maximum = vc_get_hard(vxi, id);
28577 ++ return 0;
28578 ++}
28579 ++
28580 ++int vc_get_rlimit(struct vx_info *vxi, void __user *data)
28581 ++{
28582 ++ struct vcmd_ctx_rlimit_v0 vc_data;
28583 ++ int ret;
28584 ++
28585 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
28586 ++ return -EFAULT;
28587 ++
28588 ++ ret = do_get_rlimit(vxi, vc_data.id,
28589 ++ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
28590 ++ if (ret)
28591 ++ return ret;
28592 ++
28593 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
28594 ++ return -EFAULT;
28595 ++ return 0;
28596 ++}
28597 ++
28598 ++static int do_set_rlimit(struct vx_info *vxi, uint32_t id,
28599 ++ uint64_t minimum, uint64_t softlimit, uint64_t maximum)
28600 ++{
28601 ++ if (!is_valid_vlimit(id))
28602 ++ return -EINVAL;
28603 ++
28604 ++ if (maximum != CRLIM_KEEP)
28605 ++ __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum);
28606 ++ if (softlimit != CRLIM_KEEP)
28607 ++ __rlim_soft(&vxi->limit, id) = VX_RLIM(softlimit);
28608 ++
28609 ++ /* clamp soft limit */
28610 ++ if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id))
28611 ++ __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id);
28612 ++
28613 ++ return 0;
28614 ++}
28615 ++
28616 ++int vc_set_rlimit(struct vx_info *vxi, void __user *data)
28617 ++{
28618 ++ struct vcmd_ctx_rlimit_v0 vc_data;
28619 ++
28620 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
28621 ++ return -EFAULT;
28622 ++
28623 ++ return do_set_rlimit(vxi, vc_data.id,
28624 ++ vc_data.minimum, vc_data.softlimit, vc_data.maximum);
28625 ++}
28626 ++
28627 ++#ifdef CONFIG_IA32_EMULATION
28628 ++
28629 ++int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data)
28630 ++{
28631 ++ struct vcmd_ctx_rlimit_v0_x32 vc_data;
28632 ++
28633 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
28634 ++ return -EFAULT;
28635 ++
28636 ++ return do_set_rlimit(vxi, vc_data.id,
28637 ++ vc_data.minimum, vc_data.softlimit, vc_data.maximum);
28638 ++}
28639 ++
28640 ++int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data)
28641 ++{
28642 ++ struct vcmd_ctx_rlimit_v0_x32 vc_data;
28643 ++ int ret;
28644 ++
28645 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
28646 ++ return -EFAULT;
28647 ++
28648 ++ ret = do_get_rlimit(vxi, vc_data.id,
28649 ++ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
28650 ++ if (ret)
28651 ++ return ret;
28652 ++
28653 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
28654 ++ return -EFAULT;
28655 ++ return 0;
28656 ++}
28657 ++
28658 ++#endif /* CONFIG_IA32_EMULATION */
28659 ++
28660 ++
28661 ++int vc_get_rlimit_mask(uint32_t id, void __user *data)
28662 ++{
28663 ++ if (copy_to_user(data, &vlimit_mask, sizeof(vlimit_mask)))
28664 ++ return -EFAULT;
28665 ++ return 0;
28666 ++}
28667 ++
28668 ++
28669 ++static inline void vx_reset_minmax(struct _vx_limit *limit)
28670 ++{
28671 ++ rlim_t value;
28672 ++ int lim;
28673 ++
28674 ++ for (lim = 0; lim < NUM_LIMITS; lim++) {
28675 ++ value = __rlim_get(limit, lim);
28676 ++ __rlim_rmax(limit, lim) = value;
28677 ++ __rlim_rmin(limit, lim) = value;
28678 ++ }
28679 ++}
28680 ++
28681 ++
28682 ++int vc_reset_minmax(struct vx_info *vxi, void __user *data)
28683 ++{
28684 ++ vx_reset_minmax(&vxi->limit);
28685 ++ return 0;
28686 ++}
28687 ++
28688 ++
28689 ++int vc_rlimit_stat(struct vx_info *vxi, void __user *data)
28690 ++{
28691 ++ struct vcmd_rlimit_stat_v0 vc_data;
28692 ++ struct _vx_limit *limit = &vxi->limit;
28693 ++ int id;
28694 ++
28695 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
28696 ++ return -EFAULT;
28697 ++
28698 ++ id = vc_data.id;
28699 ++ if (!is_accounted_vlimit(id))
28700 ++ return -EINVAL;
28701 ++
28702 ++ vx_limit_fixup(limit, id);
28703 ++ vc_data.hits = atomic_read(&__rlim_lhit(limit, id));
28704 ++ vc_data.value = __rlim_get(limit, id);
28705 ++ vc_data.minimum = __rlim_rmin(limit, id);
28706 ++ vc_data.maximum = __rlim_rmax(limit, id);
28707 ++
28708 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
28709 ++ return -EFAULT;
28710 ++ return 0;
28711 ++}
28712 ++
28713 ++
28714 ++void vx_vsi_meminfo(struct sysinfo *val)
28715 ++{
28716 ++ struct vx_info *vxi = current->vx_info;
28717 ++ unsigned long totalram, freeram;
28718 ++ rlim_t v;
28719 ++
28720 ++ /* we blindly accept the max */
28721 ++ v = __rlim_soft(&vxi->limit, RLIMIT_RSS);
28722 ++ totalram = (v != RLIM_INFINITY) ? v : val->totalram;
28723 ++
28724 ++ /* total minus used equals free */
28725 ++ v = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
28726 ++ freeram = (v < totalram) ? totalram - v : 0;
28727 ++
28728 ++ val->totalram = totalram;
28729 ++ val->freeram = freeram;
28730 ++ val->bufferram = 0;
28731 ++ val->totalhigh = 0;
28732 ++ val->freehigh = 0;
28733 ++ return;
28734 ++}
28735 ++
28736 ++void vx_vsi_swapinfo(struct sysinfo *val)
28737 ++{
28738 ++ struct vx_info *vxi = current->vx_info;
28739 ++ unsigned long totalswap, freeswap;
28740 ++ rlim_t v, w;
28741 ++
28742 ++ v = __rlim_soft(&vxi->limit, RLIMIT_RSS);
28743 ++ if (v == RLIM_INFINITY) {
28744 ++ val->freeswap = val->totalswap;
28745 ++ return;
28746 ++ }
28747 ++
28748 ++ /* we blindly accept the max */
28749 ++ w = __rlim_hard(&vxi->limit, RLIMIT_RSS);
28750 ++ totalswap = (w != RLIM_INFINITY) ? (w - v) : val->totalswap;
28751 ++
28752 ++ /* currently 'used' swap */
28753 ++ w = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
28754 ++ w -= (w > v) ? v : w;
28755 ++
28756 ++ /* total minus used equals free */
28757 ++ freeswap = (w < totalswap) ? totalswap - w : 0;
28758 ++
28759 ++ val->totalswap = totalswap;
28760 ++ val->freeswap = freeswap;
28761 ++ return;
28762 ++}
28763 ++
28764 ++
28765 ++unsigned long vx_badness(struct task_struct *task, struct mm_struct *mm)
28766 ++{
28767 ++ struct vx_info *vxi = mm->mm_vx_info;
28768 ++ unsigned long points;
28769 ++ rlim_t v, w;
28770 ++
28771 ++ if (!vxi)
28772 ++ return 0;
28773 ++
28774 ++ points = vxi->vx_badness_bias;
28775 ++
28776 ++ v = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
28777 ++ w = __rlim_soft(&vxi->limit, RLIMIT_RSS);
28778 ++ points += (v > w) ? (v - w) : 0;
28779 ++
28780 ++ return points;
28781 ++}
28782 ++
28783 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/limit_init.h linux-2.6.22.19-vs2.3.0.34/kernel/vserver/limit_init.h
28784 +--- linux-2.6.22.19/kernel/vserver/limit_init.h 1970-01-01 01:00:00 +0100
28785 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/limit_init.h 2007-10-25 17:05:55 +0200
28786 +@@ -0,0 +1,33 @@
28787 ++
28788 ++
28789 ++static inline void vx_info_init_limit(struct _vx_limit *limit)
28790 ++{
28791 ++ int lim;
28792 ++
28793 ++ for (lim = 0; lim < NUM_LIMITS; lim++) {
28794 ++ __rlim_soft(limit, lim) = RLIM_INFINITY;
28795 ++ __rlim_hard(limit, lim) = RLIM_INFINITY;
28796 ++ __rlim_set(limit, lim, 0);
28797 ++ atomic_set(&__rlim_lhit(limit, lim), 0);
28798 ++ __rlim_rmin(limit, lim) = 0;
28799 ++ __rlim_rmax(limit, lim) = 0;
28800 ++ }
28801 ++}
28802 ++
28803 ++static inline void vx_info_exit_limit(struct _vx_limit *limit)
28804 ++{
28805 ++#ifdef CONFIG_VSERVER_WARN
28806 ++ rlim_t value;
28807 ++ int lim;
28808 ++
28809 ++ for (lim = 0; lim < NUM_LIMITS; lim++) {
28810 ++ if ((1 << lim) & VLIM_NOCHECK)
28811 ++ continue;
28812 ++ value = __rlim_get(limit, lim);
28813 ++ vxwprintk_xid(value,
28814 ++ "!!! limit: %p[%s,%d] = %ld on exit.",
28815 ++ limit, vlimit_name[lim], lim, (long)value);
28816 ++ }
28817 ++#endif
28818 ++}
28819 ++
28820 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/limit_proc.h linux-2.6.22.19-vs2.3.0.34/kernel/vserver/limit_proc.h
28821 +--- linux-2.6.22.19/kernel/vserver/limit_proc.h 1970-01-01 01:00:00 +0100
28822 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/limit_proc.h 2007-08-05 20:53:13 +0200
28823 +@@ -0,0 +1,57 @@
28824 ++#ifndef _VX_LIMIT_PROC_H
28825 ++#define _VX_LIMIT_PROC_H
28826 ++
28827 ++#include <linux/vserver/limit_int.h>
28828 ++
28829 ++
28830 ++#define VX_LIMIT_FMT ":\t%8ld\t%8ld/%8ld\t%8lld/%8lld\t%6d\n"
28831 ++#define VX_LIMIT_TOP \
28832 ++ "Limit\t current\t min/max\t\t soft/hard\t\thits\n"
28833 ++
28834 ++#define VX_LIMIT_ARG(r) \
28835 ++ (unsigned long)__rlim_get(limit, r), \
28836 ++ (unsigned long)__rlim_rmin(limit, r), \
28837 ++ (unsigned long)__rlim_rmax(limit, r), \
28838 ++ VX_VLIM(__rlim_soft(limit, r)), \
28839 ++ VX_VLIM(__rlim_hard(limit, r)), \
28840 ++ atomic_read(&__rlim_lhit(limit, r))
28841 ++
28842 ++static inline int vx_info_proc_limit(struct _vx_limit *limit, char *buffer)
28843 ++{
28844 ++ vx_limit_fixup(limit, -1);
28845 ++ return sprintf(buffer, VX_LIMIT_TOP
28846 ++ "PROC" VX_LIMIT_FMT
28847 ++ "VM" VX_LIMIT_FMT
28848 ++ "VML" VX_LIMIT_FMT
28849 ++ "RSS" VX_LIMIT_FMT
28850 ++ "ANON" VX_LIMIT_FMT
28851 ++ "RMAP" VX_LIMIT_FMT
28852 ++ "FILES" VX_LIMIT_FMT
28853 ++ "OFD" VX_LIMIT_FMT
28854 ++ "LOCKS" VX_LIMIT_FMT
28855 ++ "SOCK" VX_LIMIT_FMT
28856 ++ "MSGQ" VX_LIMIT_FMT
28857 ++ "SHM" VX_LIMIT_FMT
28858 ++ "SEMA" VX_LIMIT_FMT
28859 ++ "SEMS" VX_LIMIT_FMT
28860 ++ "DENT" VX_LIMIT_FMT,
28861 ++ VX_LIMIT_ARG(RLIMIT_NPROC),
28862 ++ VX_LIMIT_ARG(RLIMIT_AS),
28863 ++ VX_LIMIT_ARG(RLIMIT_MEMLOCK),
28864 ++ VX_LIMIT_ARG(RLIMIT_RSS),
28865 ++ VX_LIMIT_ARG(VLIMIT_ANON),
28866 ++ VX_LIMIT_ARG(VLIMIT_MAPPED),
28867 ++ VX_LIMIT_ARG(RLIMIT_NOFILE),
28868 ++ VX_LIMIT_ARG(VLIMIT_OPENFD),
28869 ++ VX_LIMIT_ARG(RLIMIT_LOCKS),
28870 ++ VX_LIMIT_ARG(VLIMIT_NSOCK),
28871 ++ VX_LIMIT_ARG(RLIMIT_MSGQUEUE),
28872 ++ VX_LIMIT_ARG(VLIMIT_SHMEM),
28873 ++ VX_LIMIT_ARG(VLIMIT_SEMARY),
28874 ++ VX_LIMIT_ARG(VLIMIT_NSEMS),
28875 ++ VX_LIMIT_ARG(VLIMIT_DENTRY));
28876 ++}
28877 ++
28878 ++#endif /* _VX_LIMIT_PROC_H */
28879 ++
28880 ++
28881 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/monitor.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/monitor.c
28882 +--- linux-2.6.22.19/kernel/vserver/monitor.c 1970-01-01 01:00:00 +0100
28883 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/monitor.c 2007-08-15 23:18:20 +0200
28884 +@@ -0,0 +1,138 @@
28885 ++/*
28886 ++ * kernel/vserver/monitor.c
28887 ++ *
28888 ++ * Virtual Context Scheduler Monitor
28889 ++ *
28890 ++ * Copyright (C) 2006-2007 Herbert Pötzl
28891 ++ *
28892 ++ * V0.01 basic design
28893 ++ *
28894 ++ */
28895 ++
28896 ++#include <linux/module.h>
28897 ++#include <linux/jiffies.h>
28898 ++#include <asm/uaccess.h>
28899 ++#include <asm/atomic.h>
28900 ++
28901 ++#include <linux/vserver/monitor.h>
28902 ++#include <linux/vserver/debug_cmd.h>
28903 ++
28904 ++
28905 ++#ifdef CONFIG_VSERVER_MONITOR
28906 ++#define VXM_SIZE CONFIG_VSERVER_MONITOR_SIZE
28907 ++#else
28908 ++#define VXM_SIZE 64
28909 ++#endif
28910 ++
28911 ++struct _vx_monitor {
28912 ++ unsigned int counter;
28913 ++
28914 ++ struct _vx_mon_entry entry[VXM_SIZE+1];
28915 ++};
28916 ++
28917 ++
28918 ++DEFINE_PER_CPU(struct _vx_monitor, vx_monitor_buffer);
28919 ++
28920 ++unsigned volatile int vxm_active = 1;
28921 ++
28922 ++static atomic_t sequence = ATOMIC_INIT(0);
28923 ++
28924 ++
28925 ++/* vxm_advance()
28926 ++
28927 ++ * requires disabled preemption */
28928 ++
28929 ++struct _vx_mon_entry *vxm_advance(int cpu)
28930 ++{
28931 ++ struct _vx_monitor *mon = &per_cpu(vx_monitor_buffer, cpu);
28932 ++ struct _vx_mon_entry *entry;
28933 ++ unsigned int index;
28934 ++
28935 ++ index = vxm_active ? (mon->counter++ % VXM_SIZE) : VXM_SIZE;
28936 ++ entry = &mon->entry[index];
28937 ++
28938 ++ entry->ev.seq = atomic_inc_return(&sequence);
28939 ++ entry->ev.jif = jiffies;
28940 ++ return entry;
28941 ++}
28942 ++
28943 ++EXPORT_SYMBOL_GPL(vxm_advance);
28944 ++
28945 ++
28946 ++int do_read_monitor(struct __user _vx_mon_entry *data,
28947 ++ int cpu, uint32_t *index, uint32_t *count)
28948 ++{
28949 ++ int pos, ret = 0;
28950 ++ struct _vx_monitor *mon = &per_cpu(vx_monitor_buffer, cpu);
28951 ++ int end = mon->counter;
28952 ++ int start = end - VXM_SIZE + 2;
28953 ++ int idx = *index;
28954 ++
28955 ++ /* special case: get current pos */
28956 ++ if (!*count) {
28957 ++ *index = end;
28958 ++ return 0;
28959 ++ }
28960 ++
28961 ++ /* have we lost some data? */
28962 ++ if (idx < start)
28963 ++ idx = start;
28964 ++
28965 ++ for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
28966 ++ struct _vx_mon_entry *entry =
28967 ++ &mon->entry[idx % VXM_SIZE];
28968 ++
28969 ++ /* send entry to userspace */
28970 ++ ret = copy_to_user(&data[pos], entry, sizeof(*entry));
28971 ++ if (ret)
28972 ++ break;
28973 ++ }
28974 ++ /* save new index and count */
28975 ++ *index = idx;
28976 ++ *count = pos;
28977 ++ return ret ? ret : (*index < end);
28978 ++}
28979 ++
28980 ++int vc_read_monitor(uint32_t id, void __user *data)
28981 ++{
28982 ++ struct vcmd_read_monitor_v0 vc_data;
28983 ++ int ret;
28984 ++
28985 ++ if (id >= NR_CPUS)
28986 ++ return -EINVAL;
28987 ++
28988 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
28989 ++ return -EFAULT;
28990 ++
28991 ++ ret = do_read_monitor((struct __user _vx_mon_entry *)vc_data.data,
28992 ++ id, &vc_data.index, &vc_data.count);
28993 ++
28994 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
28995 ++ return -EFAULT;
28996 ++ return ret;
28997 ++}
28998 ++
28999 ++#ifdef CONFIG_COMPAT
29000 ++
29001 ++int vc_read_monitor_x32(uint32_t id, void __user *data)
29002 ++{
29003 ++ struct vcmd_read_monitor_v0_x32 vc_data;
29004 ++ int ret;
29005 ++
29006 ++ if (id >= NR_CPUS)
29007 ++ return -EINVAL;
29008 ++
29009 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
29010 ++ return -EFAULT;
29011 ++
29012 ++ ret = do_read_monitor((struct __user _vx_mon_entry *)
29013 ++ compat_ptr(vc_data.data_ptr),
29014 ++ id, &vc_data.index, &vc_data.count);
29015 ++
29016 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
29017 ++ return -EFAULT;
29018 ++ return ret;
29019 ++}
29020 ++
29021 ++#endif /* CONFIG_COMPAT */
29022 ++
29023 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/network.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/network.c
29024 +--- linux-2.6.22.19/kernel/vserver/network.c 1970-01-01 01:00:00 +0100
29025 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/network.c 2007-10-05 14:54:36 +0200
29026 +@@ -0,0 +1,862 @@
29027 ++/*
29028 ++ * linux/kernel/vserver/network.c
29029 ++ *
29030 ++ * Virtual Server: Network Support
29031 ++ *
29032 ++ * Copyright (C) 2003-2007 Herbert Pötzl
29033 ++ *
29034 ++ * V0.01 broken out from vcontext V0.05
29035 ++ * V0.02 cleaned up implementation
29036 ++ * V0.03 added equiv nx commands
29037 ++ * V0.04 switch to RCU based hash
29038 ++ * V0.05 and back to locking again
29039 ++ * V0.06 changed vcmds to nxi arg
29040 ++ * V0.07 have __create claim() the nxi
29041 ++ *
29042 ++ */
29043 ++
29044 ++#include <linux/err.h>
29045 ++#include <linux/slab.h>
29046 ++#include <linux/rcupdate.h>
29047 ++
29048 ++#include <linux/vs_network.h>
29049 ++#include <linux/vserver/network_cmd.h>
29050 ++
29051 ++
29052 ++atomic_t nx_global_ctotal = ATOMIC_INIT(0);
29053 ++atomic_t nx_global_cactive = ATOMIC_INIT(0);
29054 ++
29055 ++static struct kmem_cache *nx_addr_v4_cachep = NULL;
29056 ++static struct kmem_cache *nx_addr_v6_cachep = NULL;
29057 ++
29058 ++
29059 ++static int __init init_network(void)
29060 ++{
29061 ++ nx_addr_v4_cachep = kmem_cache_create("nx_v4_addr_cache",
29062 ++ sizeof(struct nx_addr_v4), 0, SLAB_PANIC, NULL, NULL);
29063 ++ nx_addr_v6_cachep = kmem_cache_create("nx_v6_addr_cache",
29064 ++ sizeof(struct nx_addr_v6), 0, SLAB_PANIC, NULL, NULL);
29065 ++ return 0;
29066 ++}
29067 ++
29068 ++
29069 ++/* __alloc_nx_addr_v4() */
29070 ++
29071 ++static inline struct nx_addr_v4 *__alloc_nx_addr_v4(void)
29072 ++{
29073 ++ struct nx_addr_v4 *nxa = kmem_cache_alloc(
29074 ++ nx_addr_v4_cachep, GFP_KERNEL);
29075 ++
29076 ++ if (!IS_ERR(nxa))
29077 ++ memset(nxa, 0, sizeof(*nxa));
29078 ++ return nxa;
29079 ++}
29080 ++
29081 ++/* __dealloc_nx_addr_v4() */
29082 ++
29083 ++static inline void __dealloc_nx_addr_v4(struct nx_addr_v4 *nxa)
29084 ++{
29085 ++ kmem_cache_free(nx_addr_v4_cachep, nxa);
29086 ++}
29087 ++
29088 ++/* __dealloc_nx_addr_v4_all() */
29089 ++
29090 ++static inline void __dealloc_nx_addr_v4_all(struct nx_addr_v4 *nxa)
29091 ++{
29092 ++ while (nxa) {
29093 ++ struct nx_addr_v4 *next = nxa->next;
29094 ++
29095 ++ __dealloc_nx_addr_v4(nxa);
29096 ++ nxa = next;
29097 ++ }
29098 ++}
29099 ++
29100 ++
29101 ++#ifdef CONFIG_IPV6
29102 ++
29103 ++/* __alloc_nx_addr_v6() */
29104 ++
29105 ++static inline struct nx_addr_v6 *__alloc_nx_addr_v6(void)
29106 ++{
29107 ++ struct nx_addr_v6 *nxa = kmem_cache_alloc(
29108 ++ nx_addr_v6_cachep, GFP_KERNEL);
29109 ++
29110 ++ if (!IS_ERR(nxa))
29111 ++ memset(nxa, 0, sizeof(*nxa));
29112 ++ return nxa;
29113 ++}
29114 ++
29115 ++/* __dealloc_nx_addr_v6() */
29116 ++
29117 ++static inline void __dealloc_nx_addr_v6(struct nx_addr_v6 *nxa)
29118 ++{
29119 ++ kmem_cache_free(nx_addr_v6_cachep, nxa);
29120 ++}
29121 ++
29122 ++/* __dealloc_nx_addr_v6_all() */
29123 ++
29124 ++static inline void __dealloc_nx_addr_v6_all(struct nx_addr_v6 *nxa)
29125 ++{
29126 ++ while (nxa) {
29127 ++ struct nx_addr_v6 *next = nxa->next;
29128 ++
29129 ++ __dealloc_nx_addr_v6(nxa);
29130 ++ nxa = next;
29131 ++ }
29132 ++}
29133 ++
29134 ++#endif /* CONFIG_IPV6 */
29135 ++
29136 ++
29137 ++/* __alloc_nx_info()
29138 ++
29139 ++ * allocate an initialized nx_info struct
29140 ++ * doesn't make it visible (hash) */
29141 ++
29142 ++static struct nx_info *__alloc_nx_info(nid_t nid)
29143 ++{
29144 ++ struct nx_info *new = NULL;
29145 ++
29146 ++ vxdprintk(VXD_CBIT(nid, 1), "alloc_nx_info(%d)*", nid);
29147 ++
29148 ++ /* would this benefit from a slab cache? */
29149 ++ new = kmalloc(sizeof(struct nx_info), GFP_KERNEL);
29150 ++ if (!new)
29151 ++ return 0;
29152 ++
29153 ++ memset(new, 0, sizeof(struct nx_info));
29154 ++ new->nx_id = nid;
29155 ++ INIT_HLIST_NODE(&new->nx_hlist);
29156 ++ atomic_set(&new->nx_usecnt, 0);
29157 ++ atomic_set(&new->nx_tasks, 0);
29158 ++ new->nx_state = 0;
29159 ++
29160 ++ new->nx_flags = NXF_INIT_SET;
29161 ++
29162 ++ /* rest of init goes here */
29163 ++
29164 ++ new->v4_lback.s_addr = htonl(INADDR_LOOPBACK);
29165 ++ new->v4_bcast.s_addr = htonl(INADDR_BROADCAST);
29166 ++
29167 ++ vxdprintk(VXD_CBIT(nid, 0),
29168 ++ "alloc_nx_info(%d) = %p", nid, new);
29169 ++ atomic_inc(&nx_global_ctotal);
29170 ++ return new;
29171 ++}
29172 ++
29173 ++/* __dealloc_nx_info()
29174 ++
29175 ++ * final disposal of nx_info */
29176 ++
29177 ++static void __dealloc_nx_info(struct nx_info *nxi)
29178 ++{
29179 ++ vxdprintk(VXD_CBIT(nid, 0),
29180 ++ "dealloc_nx_info(%p)", nxi);
29181 ++
29182 ++ nxi->nx_hlist.next = LIST_POISON1;
29183 ++ nxi->nx_id = -1;
29184 ++
29185 ++ BUG_ON(atomic_read(&nxi->nx_usecnt));
29186 ++ BUG_ON(atomic_read(&nxi->nx_tasks));
29187 ++
29188 ++ __dealloc_nx_addr_v4_all(nxi->v4.next);
29189 ++
29190 ++ nxi->nx_state |= NXS_RELEASED;
29191 ++ kfree(nxi);
29192 ++ atomic_dec(&nx_global_ctotal);
29193 ++}
29194 ++
29195 ++static void __shutdown_nx_info(struct nx_info *nxi)
29196 ++{
29197 ++ nxi->nx_state |= NXS_SHUTDOWN;
29198 ++ vs_net_change(nxi, VSC_NETDOWN);
29199 ++}
29200 ++
29201 ++/* exported stuff */
29202 ++
29203 ++void free_nx_info(struct nx_info *nxi)
29204 ++{
29205 ++ /* context shutdown is mandatory */
29206 ++ BUG_ON(nxi->nx_state != NXS_SHUTDOWN);
29207 ++
29208 ++ /* context must not be hashed */
29209 ++ BUG_ON(nxi->nx_state & NXS_HASHED);
29210 ++
29211 ++ BUG_ON(atomic_read(&nxi->nx_usecnt));
29212 ++ BUG_ON(atomic_read(&nxi->nx_tasks));
29213 ++
29214 ++ __dealloc_nx_info(nxi);
29215 ++}
29216 ++
29217 ++
29218 ++void __nx_set_lback(struct nx_info *nxi)
29219 ++{
29220 ++ int nid = nxi->nx_id;
29221 ++ __be32 lback = htonl(INADDR_LOOPBACK ^ ((nid & 0xFFFF) << 8));
29222 ++
29223 ++ nxi->v4_lback.s_addr = lback;
29224 ++}
29225 ++
29226 ++extern int __nx_inet_add_lback(__be32 addr);
29227 ++extern int __nx_inet_del_lback(__be32 addr);
29228 ++
29229 ++
29230 ++/* hash table for nx_info hash */
29231 ++
29232 ++#define NX_HASH_SIZE 13
29233 ++
29234 ++struct hlist_head nx_info_hash[NX_HASH_SIZE];
29235 ++
29236 ++static spinlock_t nx_info_hash_lock = SPIN_LOCK_UNLOCKED;
29237 ++
29238 ++
29239 ++static inline unsigned int __hashval(nid_t nid)
29240 ++{
29241 ++ return (nid % NX_HASH_SIZE);
29242 ++}
29243 ++
29244 ++
29245 ++
29246 ++/* __hash_nx_info()
29247 ++
29248 ++ * add the nxi to the global hash table
29249 ++ * requires the hash_lock to be held */
29250 ++
29251 ++static inline void __hash_nx_info(struct nx_info *nxi)
29252 ++{
29253 ++ struct hlist_head *head;
29254 ++
29255 ++ vxd_assert_lock(&nx_info_hash_lock);
29256 ++ vxdprintk(VXD_CBIT(nid, 4),
29257 ++ "__hash_nx_info: %p[#%d]", nxi, nxi->nx_id);
29258 ++
29259 ++ /* context must not be hashed */
29260 ++ BUG_ON(nx_info_state(nxi, NXS_HASHED));
29261 ++
29262 ++ nxi->nx_state |= NXS_HASHED;
29263 ++ head = &nx_info_hash[__hashval(nxi->nx_id)];
29264 ++ hlist_add_head(&nxi->nx_hlist, head);
29265 ++ atomic_inc(&nx_global_cactive);
29266 ++}
29267 ++
29268 ++/* __unhash_nx_info()
29269 ++
29270 ++ * remove the nxi from the global hash table
29271 ++ * requires the hash_lock to be held */
29272 ++
29273 ++static inline void __unhash_nx_info(struct nx_info *nxi)
29274 ++{
29275 ++ vxd_assert_lock(&nx_info_hash_lock);
29276 ++ vxdprintk(VXD_CBIT(nid, 4),
29277 ++ "__unhash_nx_info: %p[#%d.%d.%d]", nxi, nxi->nx_id,
29278 ++ atomic_read(&nxi->nx_usecnt), atomic_read(&nxi->nx_tasks));
29279 ++
29280 ++ /* context must be hashed */
29281 ++ BUG_ON(!nx_info_state(nxi, NXS_HASHED));
29282 ++ /* but without tasks */
29283 ++ BUG_ON(atomic_read(&nxi->nx_tasks));
29284 ++
29285 ++ nxi->nx_state &= ~NXS_HASHED;
29286 ++ hlist_del(&nxi->nx_hlist);
29287 ++ atomic_dec(&nx_global_cactive);
29288 ++}
29289 ++
29290 ++
29291 ++/* __lookup_nx_info()
29292 ++
29293 ++ * requires the hash_lock to be held
29294 ++ * doesn't increment the nx_refcnt */
29295 ++
29296 ++static inline struct nx_info *__lookup_nx_info(nid_t nid)
29297 ++{
29298 ++ struct hlist_head *head = &nx_info_hash[__hashval(nid)];
29299 ++ struct hlist_node *pos;
29300 ++ struct nx_info *nxi;
29301 ++
29302 ++ vxd_assert_lock(&nx_info_hash_lock);
29303 ++ hlist_for_each(pos, head) {
29304 ++ nxi = hlist_entry(pos, struct nx_info, nx_hlist);
29305 ++
29306 ++ if (nxi->nx_id == nid)
29307 ++ goto found;
29308 ++ }
29309 ++ nxi = NULL;
29310 ++found:
29311 ++ vxdprintk(VXD_CBIT(nid, 0),
29312 ++ "__lookup_nx_info(#%u): %p[#%u]",
29313 ++ nid, nxi, nxi ? nxi->nx_id : 0);
29314 ++ return nxi;
29315 ++}
29316 ++
29317 ++
29318 ++/* __create_nx_info()
29319 ++
29320 ++ * create the requested context
29321 ++ * get(), claim() and hash it */
29322 ++
29323 ++static struct nx_info *__create_nx_info(int id)
29324 ++{
29325 ++ struct nx_info *new, *nxi = NULL;
29326 ++
29327 ++ vxdprintk(VXD_CBIT(nid, 1), "create_nx_info(%d)*", id);
29328 ++
29329 ++ if (!(new = __alloc_nx_info(id)))
29330 ++ return ERR_PTR(-ENOMEM);
29331 ++
29332 ++ /* required to make dynamic xids unique */
29333 ++ spin_lock(&nx_info_hash_lock);
29334 ++
29335 ++ /* static context requested */
29336 ++ if ((nxi = __lookup_nx_info(id))) {
29337 ++ vxdprintk(VXD_CBIT(nid, 0),
29338 ++ "create_nx_info(%d) = %p (already there)", id, nxi);
29339 ++ if (nx_info_flags(nxi, NXF_STATE_SETUP, 0))
29340 ++ nxi = ERR_PTR(-EBUSY);
29341 ++ else
29342 ++ nxi = ERR_PTR(-EEXIST);
29343 ++ goto out_unlock;
29344 ++ }
29345 ++ /* new context */
29346 ++ vxdprintk(VXD_CBIT(nid, 0),
29347 ++ "create_nx_info(%d) = %p (new)", id, new);
29348 ++ claim_nx_info(new, NULL);
29349 ++ __nx_set_lback(new);
29350 ++ __hash_nx_info(get_nx_info(new));
29351 ++ nxi = new, new = NULL;
29352 ++
29353 ++out_unlock:
29354 ++ spin_unlock(&nx_info_hash_lock);
29355 ++ if (new)
29356 ++ __dealloc_nx_info(new);
29357 ++ return nxi;
29358 ++}
29359 ++
29360 ++
29361 ++
29362 ++/* exported stuff */
29363 ++
29364 ++
29365 ++void unhash_nx_info(struct nx_info *nxi)
29366 ++{
29367 ++ __shutdown_nx_info(nxi);
29368 ++ spin_lock(&nx_info_hash_lock);
29369 ++ __unhash_nx_info(nxi);
29370 ++ spin_unlock(&nx_info_hash_lock);
29371 ++}
29372 ++
29373 ++/* lookup_nx_info()
29374 ++
29375 ++ * search for a nx_info and get() it
29376 ++ * negative id means current */
29377 ++
29378 ++struct nx_info *lookup_nx_info(int id)
29379 ++{
29380 ++ struct nx_info *nxi = NULL;
29381 ++
29382 ++ if (id < 0) {
29383 ++ nxi = get_nx_info(current->nx_info);
29384 ++ } else if (id > 1) {
29385 ++ spin_lock(&nx_info_hash_lock);
29386 ++ nxi = get_nx_info(__lookup_nx_info(id));
29387 ++ spin_unlock(&nx_info_hash_lock);
29388 ++ }
29389 ++ return nxi;
29390 ++}
29391 ++
29392 ++/* nid_is_hashed()
29393 ++
29394 ++ * verify that nid is still hashed */
29395 ++
29396 ++int nid_is_hashed(nid_t nid)
29397 ++{
29398 ++ int hashed;
29399 ++
29400 ++ spin_lock(&nx_info_hash_lock);
29401 ++ hashed = (__lookup_nx_info(nid) != NULL);
29402 ++ spin_unlock(&nx_info_hash_lock);
29403 ++ return hashed;
29404 ++}
29405 ++
29406 ++
29407 ++#ifdef CONFIG_PROC_FS
29408 ++
29409 ++/* get_nid_list()
29410 ++
29411 ++ * get a subset of hashed nids for proc
29412 ++ * assumes size is at least one */
29413 ++
29414 ++int get_nid_list(int index, unsigned int *nids, int size)
29415 ++{
29416 ++ int hindex, nr_nids = 0;
29417 ++
29418 ++ /* only show current and children */
29419 ++ if (!nx_check(0, VS_ADMIN | VS_WATCH)) {
29420 ++ if (index > 0)
29421 ++ return 0;
29422 ++ nids[nr_nids] = nx_current_nid();
29423 ++ return 1;
29424 ++ }
29425 ++
29426 ++ for (hindex = 0; hindex < NX_HASH_SIZE; hindex++) {
29427 ++ struct hlist_head *head = &nx_info_hash[hindex];
29428 ++ struct hlist_node *pos;
29429 ++
29430 ++ spin_lock(&nx_info_hash_lock);
29431 ++ hlist_for_each(pos, head) {
29432 ++ struct nx_info *nxi;
29433 ++
29434 ++ if (--index > 0)
29435 ++ continue;
29436 ++
29437 ++ nxi = hlist_entry(pos, struct nx_info, nx_hlist);
29438 ++ nids[nr_nids] = nxi->nx_id;
29439 ++ if (++nr_nids >= size) {
29440 ++ spin_unlock(&nx_info_hash_lock);
29441 ++ goto out;
29442 ++ }
29443 ++ }
29444 ++ /* keep the lock time short */
29445 ++ spin_unlock(&nx_info_hash_lock);
29446 ++ }
29447 ++out:
29448 ++ return nr_nids;
29449 ++}
29450 ++#endif
29451 ++
29452 ++
29453 ++/*
29454 ++ * migrate task to new network
29455 ++ * gets nxi, puts old_nxi on change
29456 ++ */
29457 ++
29458 ++int nx_migrate_task(struct task_struct *p, struct nx_info *nxi)
29459 ++{
29460 ++ struct nx_info *old_nxi;
29461 ++ int ret = 0;
29462 ++
29463 ++ if (!p || !nxi)
29464 ++ BUG();
29465 ++
29466 ++ vxdprintk(VXD_CBIT(nid, 5),
29467 ++ "nx_migrate_task(%p,%p[#%d.%d.%d])",
29468 ++ p, nxi, nxi->nx_id,
29469 ++ atomic_read(&nxi->nx_usecnt),
29470 ++ atomic_read(&nxi->nx_tasks));
29471 ++
29472 ++ if (nx_info_flags(nxi, NXF_INFO_PRIVATE, 0) &&
29473 ++ !nx_info_flags(nxi, NXF_STATE_SETUP, 0))
29474 ++ return -EACCES;
29475 ++
29476 ++ if (nx_info_state(nxi, NXS_SHUTDOWN))
29477 ++ return -EFAULT;
29478 ++
29479 ++ /* maybe disallow this completely? */
29480 ++ old_nxi = task_get_nx_info(p);
29481 ++ if (old_nxi == nxi)
29482 ++ goto out;
29483 ++
29484 ++ task_lock(p);
29485 ++ if (old_nxi)
29486 ++ clr_nx_info(&p->nx_info);
29487 ++ claim_nx_info(nxi, p);
29488 ++ set_nx_info(&p->nx_info, nxi);
29489 ++ p->nid = nxi->nx_id;
29490 ++ task_unlock(p);
29491 ++
29492 ++ vxdprintk(VXD_CBIT(nid, 5),
29493 ++ "moved task %p into nxi:%p[#%d]",
29494 ++ p, nxi, nxi->nx_id);
29495 ++
29496 ++ if (old_nxi)
29497 ++ release_nx_info(old_nxi, p);
29498 ++ ret = 0;
29499 ++out:
29500 ++ put_nx_info(old_nxi);
29501 ++ return ret;
29502 ++}
29503 ++
29504 ++
29505 ++void nx_set_persistent(struct nx_info *nxi)
29506 ++{
29507 ++ vxdprintk(VXD_CBIT(nid, 6),
29508 ++ "nx_set_persistent(%p[#%d])", nxi, nxi->nx_id);
29509 ++
29510 ++ get_nx_info(nxi);
29511 ++ claim_nx_info(nxi, NULL);
29512 ++}
29513 ++
29514 ++void nx_clear_persistent(struct nx_info *nxi)
29515 ++{
29516 ++ vxdprintk(VXD_CBIT(nid, 6),
29517 ++ "nx_clear_persistent(%p[#%d])", nxi, nxi->nx_id);
29518 ++
29519 ++ release_nx_info(nxi, NULL);
29520 ++ put_nx_info(nxi);
29521 ++}
29522 ++
29523 ++void nx_update_persistent(struct nx_info *nxi)
29524 ++{
29525 ++ if (nx_info_flags(nxi, NXF_PERSISTENT, 0))
29526 ++ nx_set_persistent(nxi);
29527 ++ else
29528 ++ nx_clear_persistent(nxi);
29529 ++}
29530 ++
29531 ++/* vserver syscall commands below here */
29532 ++
29533 ++/* taks nid and nx_info functions */
29534 ++
29535 ++#include <asm/uaccess.h>
29536 ++
29537 ++
29538 ++int vc_task_nid(uint32_t id)
29539 ++{
29540 ++ nid_t nid;
29541 ++
29542 ++ if (id) {
29543 ++ struct task_struct *tsk;
29544 ++
29545 ++ read_lock(&tasklist_lock);
29546 ++ tsk = find_task_by_real_pid(id);
29547 ++ nid = (tsk) ? tsk->nid : -ESRCH;
29548 ++ read_unlock(&tasklist_lock);
29549 ++ } else
29550 ++ nid = nx_current_nid();
29551 ++ return nid;
29552 ++}
29553 ++
29554 ++
29555 ++int vc_nx_info(struct nx_info *nxi, void __user *data)
29556 ++{
29557 ++ struct vcmd_nx_info_v0 vc_data;
29558 ++
29559 ++ vc_data.nid = nxi->nx_id;
29560 ++
29561 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
29562 ++ return -EFAULT;
29563 ++ return 0;
29564 ++}
29565 ++
29566 ++
29567 ++/* network functions */
29568 ++
29569 ++int vc_net_create(uint32_t nid, void __user *data)
29570 ++{
29571 ++ struct vcmd_net_create vc_data = { .flagword = NXF_INIT_SET };
29572 ++ struct nx_info *new_nxi;
29573 ++ int ret;
29574 ++
29575 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
29576 ++ return -EFAULT;
29577 ++
29578 ++ if ((nid > MAX_S_CONTEXT) || (nid < 2))
29579 ++ return -EINVAL;
29580 ++
29581 ++ new_nxi = __create_nx_info(nid);
29582 ++ if (IS_ERR(new_nxi))
29583 ++ return PTR_ERR(new_nxi);
29584 ++
29585 ++ /* initial flags */
29586 ++ new_nxi->nx_flags = vc_data.flagword;
29587 ++
29588 ++ ret = -ENOEXEC;
29589 ++ if (vs_net_change(new_nxi, VSC_NETUP))
29590 ++ goto out;
29591 ++
29592 ++ ret = nx_migrate_task(current, new_nxi);
29593 ++ if (ret)
29594 ++ goto out;
29595 ++
29596 ++ /* return context id on success */
29597 ++ ret = new_nxi->nx_id;
29598 ++
29599 ++ /* get a reference for persistent contexts */
29600 ++ if ((vc_data.flagword & NXF_PERSISTENT))
29601 ++ nx_set_persistent(new_nxi);
29602 ++out:
29603 ++ release_nx_info(new_nxi, NULL);
29604 ++ put_nx_info(new_nxi);
29605 ++ return ret;
29606 ++}
29607 ++
29608 ++
29609 ++int vc_net_migrate(struct nx_info *nxi, void __user *data)
29610 ++{
29611 ++ return nx_migrate_task(current, nxi);
29612 ++}
29613 ++
29614 ++
29615 ++
29616 ++int do_add_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
29617 ++ uint16_t type, uint16_t flags)
29618 ++{
29619 ++ struct nx_addr_v4 *nxa = &nxi->v4;
29620 ++
29621 ++ if (NX_IPV4(nxi)) {
29622 ++ /* locate last entry */
29623 ++ for (; nxa->next; nxa = nxa->next);
29624 ++ nxa->next = __alloc_nx_addr_v4();
29625 ++ nxa = nxa->next;
29626 ++
29627 ++ if (IS_ERR(nxa))
29628 ++ return PTR_ERR(nxa);
29629 ++ }
29630 ++
29631 ++ if (nxi->v4.next)
29632 ++ /* remove single ip for ip list */
29633 ++ nxi->nx_flags &= ~NXF_SINGLE_IP;
29634 ++
29635 ++ nxa->ip[0].s_addr = ip;
29636 ++ nxa->ip[1].s_addr = ip2;
29637 ++ nxa->mask.s_addr = mask;
29638 ++ nxa->type = type;
29639 ++ nxa->flags = flags;
29640 ++ return 0;
29641 ++}
29642 ++
29643 ++
29644 ++int vc_net_add(struct nx_info *nxi, void __user *data)
29645 ++{
29646 ++ struct vcmd_net_addr_v0 vc_data;
29647 ++ int index, ret = 0;
29648 ++
29649 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
29650 ++ return -EFAULT;
29651 ++
29652 ++ switch (vc_data.type) {
29653 ++ case NXA_TYPE_IPV4:
29654 ++ if ((vc_data.count < 1) || (vc_data.count > 4))
29655 ++ return -EINVAL;
29656 ++
29657 ++ index = 0;
29658 ++ while (index < vc_data.count) {
29659 ++ ret = do_add_v4_addr(nxi, vc_data.ip[index].s_addr, 0,
29660 ++ vc_data.mask[index].s_addr, NXA_TYPE_ADDR, 0);
29661 ++ if (ret)
29662 ++ return ret;
29663 ++ index++;
29664 ++ }
29665 ++ ret = index;
29666 ++ break;
29667 ++
29668 ++ case NXA_TYPE_IPV4|NXA_MOD_BCAST:
29669 ++ nxi->v4_bcast = vc_data.ip[0];
29670 ++ ret = 1;
29671 ++ break;
29672 ++
29673 ++ case NXA_TYPE_IPV4|NXA_MOD_LBACK:
29674 ++ nxi->v4_lback = vc_data.ip[0];
29675 ++ ret = 1;
29676 ++ break;
29677 ++
29678 ++ default:
29679 ++ ret = -EINVAL;
29680 ++ break;
29681 ++ }
29682 ++ return ret;
29683 ++}
29684 ++
29685 ++int vc_net_remove(struct nx_info *nxi, void __user *data)
29686 ++{
29687 ++ struct vcmd_net_addr_v0 vc_data;
29688 ++
29689 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
29690 ++ return -EFAULT;
29691 ++
29692 ++ switch (vc_data.type) {
29693 ++ case NXA_TYPE_ANY:
29694 ++ __dealloc_nx_addr_v4_all(xchg(&nxi->v4.next, NULL));
29695 ++ memset(&nxi->v4, 0, sizeof(nxi->v4));
29696 ++ break;
29697 ++
29698 ++ default:
29699 ++ return -EINVAL;
29700 ++ }
29701 ++ return 0;
29702 ++}
29703 ++
29704 ++
29705 ++int vc_net_add_ipv4(struct nx_info *nxi, void __user *data)
29706 ++{
29707 ++ struct vcmd_net_addr_ipv4_v1 vc_data;
29708 ++
29709 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
29710 ++ return -EFAULT;
29711 ++
29712 ++ switch (vc_data.type) {
29713 ++ case NXA_TYPE_ADDR:
29714 ++ case NXA_TYPE_RANGE:
29715 ++ case NXA_TYPE_MASK:
29716 ++ return do_add_v4_addr(nxi, vc_data.ip.s_addr, 0,
29717 ++ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
29718 ++
29719 ++ case NXA_TYPE_ADDR | NXA_MOD_BCAST:
29720 ++ nxi->v4_bcast = vc_data.ip;
29721 ++ break;
29722 ++
29723 ++ case NXA_TYPE_ADDR | NXA_MOD_LBACK:
29724 ++ nxi->v4_lback = vc_data.ip;
29725 ++ break;
29726 ++
29727 ++ default:
29728 ++ return -EINVAL;
29729 ++ }
29730 ++ return 0;
29731 ++}
29732 ++
29733 ++int vc_net_remove_ipv4(struct nx_info *nxi, void __user *data)
29734 ++{
29735 ++ struct vcmd_net_addr_ipv4_v1 vc_data;
29736 ++
29737 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
29738 ++ return -EFAULT;
29739 ++
29740 ++ switch (vc_data.type) {
29741 ++/* case NXA_TYPE_ADDR:
29742 ++ break; */
29743 ++
29744 ++ case NXA_TYPE_ANY:
29745 ++ __dealloc_nx_addr_v4_all(xchg(&nxi->v4.next, NULL));
29746 ++ memset(&nxi->v4, 0, sizeof(nxi->v4));
29747 ++ break;
29748 ++
29749 ++ default:
29750 ++ return -EINVAL;
29751 ++ }
29752 ++ return 0;
29753 ++}
29754 ++
29755 ++
29756 ++#ifdef CONFIG_IPV6
29757 ++
29758 ++int do_add_v6_addr(struct nx_info *nxi,
29759 ++ struct in6_addr *ip, struct in6_addr *mask,
29760 ++ uint32_t prefix, uint16_t type, uint16_t flags)
29761 ++{
29762 ++ struct nx_addr_v6 *nxa = &nxi->v6;
29763 ++
29764 ++ if (NX_IPV6(nxi)) {
29765 ++ /* locate last entry */
29766 ++ for (; nxa->next; nxa = nxa->next);
29767 ++ nxa->next = __alloc_nx_addr_v6();
29768 ++ nxa = nxa->next;
29769 ++
29770 ++ if (IS_ERR(nxa))
29771 ++ return PTR_ERR(nxa);
29772 ++ }
29773 ++
29774 ++ nxa->ip = *ip;
29775 ++ nxa->mask = *mask;
29776 ++ nxa->prefix = prefix;
29777 ++ nxa->type = type;
29778 ++ nxa->flags = flags;
29779 ++ return 0;
29780 ++}
29781 ++
29782 ++
29783 ++int vc_net_add_ipv6(struct nx_info *nxi, void __user *data)
29784 ++{
29785 ++ struct vcmd_net_addr_ipv6_v1 vc_data;
29786 ++
29787 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
29788 ++ return -EFAULT;
29789 ++
29790 ++ switch (vc_data.type) {
29791 ++ case NXA_TYPE_ADDR:
29792 ++ case NXA_TYPE_MASK:
29793 ++ return do_add_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
29794 ++ vc_data.prefix, vc_data.type, vc_data.flags);
29795 ++ default:
29796 ++ return -EINVAL;
29797 ++ }
29798 ++ return 0;
29799 ++}
29800 ++
29801 ++int vc_net_remove_ipv6(struct nx_info *nxi, void __user *data)
29802 ++{
29803 ++ struct vcmd_net_addr_ipv6_v1 vc_data;
29804 ++
29805 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
29806 ++ return -EFAULT;
29807 ++
29808 ++ switch (vc_data.type) {
29809 ++ case NXA_TYPE_ANY:
29810 ++ __dealloc_nx_addr_v6_all(xchg(&nxi->v6.next, NULL));
29811 ++ memset(&nxi->v6, 0, sizeof(nxi->v6));
29812 ++ break;
29813 ++
29814 ++ default:
29815 ++ return -EINVAL;
29816 ++ }
29817 ++ return 0;
29818 ++}
29819 ++
29820 ++#endif /* CONFIG_IPV6 */
29821 ++
29822 ++
29823 ++int vc_get_nflags(struct nx_info *nxi, void __user *data)
29824 ++{
29825 ++ struct vcmd_net_flags_v0 vc_data;
29826 ++
29827 ++ vc_data.flagword = nxi->nx_flags;
29828 ++
29829 ++ /* special STATE flag handling */
29830 ++ vc_data.mask = vs_mask_flags(~0ULL, nxi->nx_flags, NXF_ONE_TIME);
29831 ++
29832 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
29833 ++ return -EFAULT;
29834 ++ return 0;
29835 ++}
29836 ++
29837 ++int vc_set_nflags(struct nx_info *nxi, void __user *data)
29838 ++{
29839 ++ struct vcmd_net_flags_v0 vc_data;
29840 ++ uint64_t mask, trigger;
29841 ++
29842 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
29843 ++ return -EFAULT;
29844 ++
29845 ++ /* special STATE flag handling */
29846 ++ mask = vs_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME);
29847 ++ trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword);
29848 ++
29849 ++ nxi->nx_flags = vs_mask_flags(nxi->nx_flags,
29850 ++ vc_data.flagword, mask);
29851 ++ if (trigger & NXF_PERSISTENT)
29852 ++ nx_update_persistent(nxi);
29853 ++
29854 ++ return 0;
29855 ++}
29856 ++
29857 ++int vc_get_ncaps(struct nx_info *nxi, void __user *data)
29858 ++{
29859 ++ struct vcmd_net_caps_v0 vc_data;
29860 ++
29861 ++ vc_data.ncaps = nxi->nx_ncaps;
29862 ++ vc_data.cmask = ~0ULL;
29863 ++
29864 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
29865 ++ return -EFAULT;
29866 ++ return 0;
29867 ++}
29868 ++
29869 ++int vc_set_ncaps(struct nx_info *nxi, void __user *data)
29870 ++{
29871 ++ struct vcmd_net_caps_v0 vc_data;
29872 ++
29873 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
29874 ++ return -EFAULT;
29875 ++
29876 ++ nxi->nx_ncaps = vs_mask_flags(nxi->nx_ncaps,
29877 ++ vc_data.ncaps, vc_data.cmask);
29878 ++ return 0;
29879 ++}
29880 ++
29881 ++
29882 ++#include <linux/module.h>
29883 ++
29884 ++module_init(init_network);
29885 ++
29886 ++EXPORT_SYMBOL_GPL(free_nx_info);
29887 ++EXPORT_SYMBOL_GPL(unhash_nx_info);
29888 ++
29889 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/proc.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/proc.c
29890 +--- linux-2.6.22.19/kernel/vserver/proc.c 1970-01-01 01:00:00 +0100
29891 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/proc.c 2007-10-05 14:54:36 +0200
29892 +@@ -0,0 +1,1065 @@
29893 ++/*
29894 ++ * linux/kernel/vserver/proc.c
29895 ++ *
29896 ++ * Virtual Context Support
29897 ++ *
29898 ++ * Copyright (C) 2003-2007 Herbert Pötzl
29899 ++ *
29900 ++ * V0.01 basic structure
29901 ++ * V0.02 adaptation vs1.3.0
29902 ++ * V0.03 proc permissions
29903 ++ * V0.04 locking/generic
29904 ++ * V0.05 next generation procfs
29905 ++ * V0.06 inode validation
29906 ++ * V0.07 generic rewrite vid
29907 ++ * V0.08 remove inode type
29908 ++ *
29909 ++ */
29910 ++
29911 ++#include <linux/proc_fs.h>
29912 ++#include <asm/unistd.h>
29913 ++
29914 ++#include <linux/vs_context.h>
29915 ++#include <linux/vs_network.h>
29916 ++#include <linux/vs_cvirt.h>
29917 ++#include <linux/vs_inet.h>
29918 ++#include <linux/vs_inet6.h>
29919 ++
29920 ++#include <linux/vserver/global.h>
29921 ++
29922 ++#include "cvirt_proc.h"
29923 ++#include "cacct_proc.h"
29924 ++#include "limit_proc.h"
29925 ++#include "sched_proc.h"
29926 ++#include "vci_config.h"
29927 ++
29928 ++static struct proc_dir_entry *proc_virtual;
29929 ++
29930 ++static struct proc_dir_entry *proc_virtnet;
29931 ++
29932 ++
29933 ++/* first the actual feeds */
29934 ++
29935 ++
29936 ++static int proc_vci(char *buffer)
29937 ++{
29938 ++ return sprintf(buffer,
29939 ++ "VCIVersion:\t%04x:%04x\n"
29940 ++ "VCISyscall:\t%d\n"
29941 ++ "VCIKernel:\t%08x\n",
29942 ++ VCI_VERSION >> 16,
29943 ++ VCI_VERSION & 0xFFFF,
29944 ++ __NR_vserver,
29945 ++ vci_kernel_config());
29946 ++}
29947 ++
29948 ++static int proc_virtual_info(char *buffer)
29949 ++{
29950 ++ return proc_vci(buffer);
29951 ++}
29952 ++
29953 ++static int proc_virtual_status(char *buffer)
29954 ++{
29955 ++ return sprintf(buffer,
29956 ++ "#CTotal:\t%d\n"
29957 ++ "#CActive:\t%d\n"
29958 ++ "#NSProxy:\t%d\t%d %d %d %d\n",
29959 ++ atomic_read(&vx_global_ctotal),
29960 ++ atomic_read(&vx_global_cactive),
29961 ++ atomic_read(&vs_global_nsproxy),
29962 ++ atomic_read(&vs_global_fs),
29963 ++ atomic_read(&vs_global_mnt_ns),
29964 ++ atomic_read(&vs_global_uts_ns),
29965 ++ atomic_read(&vs_global_ipc_ns));
29966 ++}
29967 ++
29968 ++
29969 ++int proc_vxi_info(struct vx_info *vxi, char *buffer)
29970 ++{
29971 ++ int length;
29972 ++
29973 ++ length = sprintf(buffer,
29974 ++ "ID:\t%d\n"
29975 ++ "Info:\t%p\n"
29976 ++ "Init:\t%d\n"
29977 ++ "OOM:\t%lld\n",
29978 ++ vxi->vx_id,
29979 ++ vxi,
29980 ++ vxi->vx_initpid,
29981 ++ vxi->vx_badness_bias);
29982 ++ return length;
29983 ++}
29984 ++
29985 ++int proc_vxi_status(struct vx_info *vxi, char *buffer)
29986 ++{
29987 ++ int length;
29988 ++
29989 ++ length = sprintf(buffer,
29990 ++ "UseCnt:\t%d\n"
29991 ++ "Tasks:\t%d\n"
29992 ++ "Flags:\t%016llx\n"
29993 ++ "BCaps:\t%016llx\n"
29994 ++ "CCaps:\t%016llx\n"
29995 ++ "Spaces:\t%08lx\n",
29996 ++ atomic_read(&vxi->vx_usecnt),
29997 ++ atomic_read(&vxi->vx_tasks),
29998 ++ (unsigned long long)vxi->vx_flags,
29999 ++ (unsigned long long)vxi->vx_bcaps,
30000 ++ (unsigned long long)vxi->vx_ccaps,
30001 ++ vxi->vx_nsmask);
30002 ++ return length;
30003 ++}
30004 ++
30005 ++int proc_vxi_limit(struct vx_info *vxi, char *buffer)
30006 ++{
30007 ++ return vx_info_proc_limit(&vxi->limit, buffer);
30008 ++}
30009 ++
30010 ++int proc_vxi_sched(struct vx_info *vxi, char *buffer)
30011 ++{
30012 ++ int cpu, length;
30013 ++
30014 ++ length = vx_info_proc_sched(&vxi->sched, buffer);
30015 ++ for_each_online_cpu(cpu) {
30016 ++ length += vx_info_proc_sched_pc(
30017 ++ &vx_per_cpu(vxi, sched_pc, cpu),
30018 ++ buffer + length, cpu);
30019 ++ }
30020 ++ return length;
30021 ++}
30022 ++
30023 ++int proc_vxi_nsproxy(struct vx_info *vxi, char *buffer)
30024 ++{
30025 ++ return vx_info_proc_nsproxy(vxi->vx_nsproxy, buffer);
30026 ++}
30027 ++
30028 ++int proc_vxi_cvirt(struct vx_info *vxi, char *buffer)
30029 ++{
30030 ++ int cpu, length;
30031 ++
30032 ++ vx_update_load(vxi);
30033 ++ length = vx_info_proc_cvirt(&vxi->cvirt, buffer);
30034 ++ for_each_online_cpu(cpu) {
30035 ++ length += vx_info_proc_cvirt_pc(
30036 ++ &vx_per_cpu(vxi, cvirt_pc, cpu),
30037 ++ buffer + length, cpu);
30038 ++ }
30039 ++ return length;
30040 ++}
30041 ++
30042 ++int proc_vxi_cacct(struct vx_info *vxi, char *buffer)
30043 ++{
30044 ++ return vx_info_proc_cacct(&vxi->cacct, buffer);
30045 ++}
30046 ++
30047 ++
30048 ++static int proc_virtnet_info(char *buffer)
30049 ++{
30050 ++ return proc_vci(buffer);
30051 ++}
30052 ++
30053 ++static int proc_virtnet_status(char *buffer)
30054 ++{
30055 ++ return sprintf(buffer,
30056 ++ "#CTotal:\t%d\n"
30057 ++ "#CActive:\t%d\n",
30058 ++ atomic_read(&nx_global_ctotal),
30059 ++ atomic_read(&nx_global_cactive));
30060 ++}
30061 ++
30062 ++int proc_nxi_info(struct nx_info *nxi, char *buffer)
30063 ++{
30064 ++ struct nx_addr_v4 *v4a;
30065 ++#ifdef CONFIG_IPV6
30066 ++ struct nx_addr_v6 *v6a;
30067 ++#endif
30068 ++ int length, i;
30069 ++
30070 ++ length = sprintf(buffer,
30071 ++ "ID:\t%d\n"
30072 ++ "Info:\t%p\n"
30073 ++ "Bcast:\t" NIPQUAD_FMT "\n"
30074 ++ "Lback:\t" NIPQUAD_FMT "\n",
30075 ++ nxi->nx_id,
30076 ++ nxi,
30077 ++ NIPQUAD(nxi->v4_bcast.s_addr),
30078 ++ NIPQUAD(nxi->v4_lback.s_addr));
30079 ++
30080 ++ if (!NX_IPV4(nxi))
30081 ++ goto skip_v4;
30082 ++ for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
30083 ++ length += sprintf(buffer + length, "%d:\t" NXAV4_FMT "\n",
30084 ++ i, NXAV4(v4a));
30085 ++skip_v4:
30086 ++#ifdef CONFIG_IPV6
30087 ++ if (!NX_IPV6(nxi))
30088 ++ goto skip_v6;
30089 ++ for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
30090 ++ length += sprintf(buffer + length, "%d:\t" NXAV6_FMT "\n",
30091 ++ i, NXAV6(v6a));
30092 ++skip_v6:
30093 ++#endif
30094 ++ return length;
30095 ++}
30096 ++
30097 ++int proc_nxi_status(struct nx_info *nxi, char *buffer)
30098 ++{
30099 ++ int length;
30100 ++
30101 ++ length = sprintf(buffer,
30102 ++ "UseCnt:\t%d\n"
30103 ++ "Tasks:\t%d\n"
30104 ++ "Flags:\t%016llx\n"
30105 ++ "NCaps:\t%016llx\n",
30106 ++ atomic_read(&nxi->nx_usecnt),
30107 ++ atomic_read(&nxi->nx_tasks),
30108 ++ (unsigned long long)nxi->nx_flags,
30109 ++ (unsigned long long)nxi->nx_ncaps);
30110 ++ return length;
30111 ++}
30112 ++
30113 ++
30114 ++
30115 ++/* here the inode helpers */
30116 ++
30117 ++struct vs_entry {
30118 ++ int len;
30119 ++ char *name;
30120 ++ mode_t mode;
30121 ++ struct inode_operations *iop;
30122 ++ struct file_operations *fop;
30123 ++ union proc_op op;
30124 ++};
30125 ++
30126 ++static struct inode *vs_proc_make_inode(struct super_block *sb, struct vs_entry *p)
30127 ++{
30128 ++ struct inode *inode = new_inode(sb);
30129 ++
30130 ++ if (!inode)
30131 ++ goto out;
30132 ++
30133 ++ inode->i_mode = p->mode;
30134 ++ if (p->iop)
30135 ++ inode->i_op = p->iop;
30136 ++ if (p->fop)
30137 ++ inode->i_fop = p->fop;
30138 ++
30139 ++ inode->i_nlink = (p->mode & S_IFDIR) ? 2 : 1;
30140 ++ inode->i_flags |= S_IMMUTABLE;
30141 ++
30142 ++ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
30143 ++
30144 ++ inode->i_uid = 0;
30145 ++ inode->i_gid = 0;
30146 ++ inode->i_tag = 0;
30147 ++out:
30148 ++ return inode;
30149 ++}
30150 ++
30151 ++static struct dentry *vs_proc_instantiate(struct inode *dir,
30152 ++ struct dentry *dentry, int id, void *ptr)
30153 ++{
30154 ++ struct vs_entry *p = ptr;
30155 ++ struct inode *inode = vs_proc_make_inode(dir->i_sb, p);
30156 ++ struct dentry *error = ERR_PTR(-EINVAL);
30157 ++
30158 ++ if (!inode)
30159 ++ goto out;
30160 ++
30161 ++ PROC_I(inode)->op = p->op;
30162 ++ PROC_I(inode)->fd = id;
30163 ++ d_add(dentry, inode);
30164 ++ error = NULL;
30165 ++out:
30166 ++ return error;
30167 ++}
30168 ++
30169 ++/* Lookups */
30170 ++
30171 ++typedef struct dentry *instantiate_t(struct inode *, struct dentry *, int, void *);
30172 ++
30173 ++/*
30174 ++ * Fill a directory entry.
30175 ++ *
30176 ++ * If possible create the dcache entry and derive our inode number and
30177 ++ * file type from dcache entry.
30178 ++ *
30179 ++ * Since all of the proc inode numbers are dynamically generated, the inode
30180 ++ * numbers do not exist until the inode is cache. This means creating the
30181 ++ * the dcache entry in readdir is necessary to keep the inode numbers
30182 ++ * reported by readdir in sync with the inode numbers reported
30183 ++ * by stat.
30184 ++ */
30185 ++static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
30186 ++ char *name, int len, instantiate_t instantiate, int id, void *ptr)
30187 ++{
30188 ++ struct dentry *child, *dir = filp->f_dentry;
30189 ++ struct inode *inode;
30190 ++ struct qstr qname;
30191 ++ ino_t ino = 0;
30192 ++ unsigned type = DT_UNKNOWN;
30193 ++
30194 ++ qname.name = name;
30195 ++ qname.len = len;
30196 ++ qname.hash = full_name_hash(name, len);
30197 ++
30198 ++ child = d_lookup(dir, &qname);
30199 ++ if (!child) {
30200 ++ struct dentry *new;
30201 ++ new = d_alloc(dir, &qname);
30202 ++ if (new) {
30203 ++ child = instantiate(dir->d_inode, new, id, ptr);
30204 ++ if (child)
30205 ++ dput(new);
30206 ++ else
30207 ++ child = new;
30208 ++ }
30209 ++ }
30210 ++ if (!child || IS_ERR(child) || !child->d_inode)
30211 ++ goto end_instantiate;
30212 ++ inode = child->d_inode;
30213 ++ if (inode) {
30214 ++ ino = inode->i_ino;
30215 ++ type = inode->i_mode >> 12;
30216 ++ }
30217 ++ dput(child);
30218 ++end_instantiate:
30219 ++ if (!ino)
30220 ++ ino = find_inode_number(dir, &qname);
30221 ++ if (!ino)
30222 ++ ino = 1;
30223 ++ return filldir(dirent, name, len, filp->f_pos, ino, type);
30224 ++}
30225 ++
30226 ++
30227 ++
30228 ++/* get and revalidate vx_info/xid */
30229 ++
30230 ++static inline
30231 ++struct vx_info *get_proc_vx_info(struct inode *inode)
30232 ++{
30233 ++ return lookup_vx_info(PROC_I(inode)->fd);
30234 ++}
30235 ++
30236 ++static int proc_xid_revalidate(struct dentry *dentry, struct nameidata *nd)
30237 ++{
30238 ++ struct inode *inode = dentry->d_inode;
30239 ++ xid_t xid = PROC_I(inode)->fd;
30240 ++
30241 ++ if (!xid || xid_is_hashed(xid))
30242 ++ return 1;
30243 ++ d_drop(dentry);
30244 ++ return 0;
30245 ++}
30246 ++
30247 ++
30248 ++/* get and revalidate nx_info/nid */
30249 ++
30250 ++static int proc_nid_revalidate(struct dentry *dentry, struct nameidata *nd)
30251 ++{
30252 ++ struct inode *inode = dentry->d_inode;
30253 ++ nid_t nid = PROC_I(inode)->fd;
30254 ++
30255 ++ if (!nid || nid_is_hashed(nid))
30256 ++ return 1;
30257 ++ d_drop(dentry);
30258 ++ return 0;
30259 ++}
30260 ++
30261 ++
30262 ++
30263 ++#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
30264 ++
30265 ++static ssize_t proc_vs_info_read(struct file *file, char __user *buf,
30266 ++ size_t count, loff_t *ppos)
30267 ++{
30268 ++ struct inode *inode = file->f_dentry->d_inode;
30269 ++ unsigned long page;
30270 ++ ssize_t length = 0;
30271 ++
30272 ++ if (count > PROC_BLOCK_SIZE)
30273 ++ count = PROC_BLOCK_SIZE;
30274 ++
30275 ++ /* fade that out as soon as stable */
30276 ++ WARN_ON(PROC_I(inode)->fd);
30277 ++
30278 ++ if (!(page = __get_free_page(GFP_KERNEL)))
30279 ++ return -ENOMEM;
30280 ++
30281 ++ BUG_ON(!PROC_I(inode)->op.proc_vs_read);
30282 ++ length = PROC_I(inode)->op.proc_vs_read((char *)page);
30283 ++
30284 ++ if (length >= 0)
30285 ++ length = simple_read_from_buffer(buf, count, ppos,
30286 ++ (char *)page, length);
30287 ++
30288 ++ free_page(page);
30289 ++ return length;
30290 ++}
30291 ++
30292 ++static ssize_t proc_vx_info_read(struct file *file, char __user *buf,
30293 ++ size_t count, loff_t *ppos)
30294 ++{
30295 ++ struct inode *inode = file->f_dentry->d_inode;
30296 ++ struct vx_info *vxi = NULL;
30297 ++ xid_t xid = PROC_I(inode)->fd;
30298 ++ unsigned long page;
30299 ++ ssize_t length = 0;
30300 ++
30301 ++ if (count > PROC_BLOCK_SIZE)
30302 ++ count = PROC_BLOCK_SIZE;
30303 ++
30304 ++ /* fade that out as soon as stable */
30305 ++ WARN_ON(!xid);
30306 ++ vxi = lookup_vx_info(xid);
30307 ++ if (!vxi)
30308 ++ goto out;
30309 ++
30310 ++ length = -ENOMEM;
30311 ++ if (!(page = __get_free_page(GFP_KERNEL)))
30312 ++ goto out_put;
30313 ++
30314 ++ BUG_ON(!PROC_I(inode)->op.proc_vxi_read);
30315 ++ length = PROC_I(inode)->op.proc_vxi_read(vxi, (char *)page);
30316 ++
30317 ++ if (length >= 0)
30318 ++ length = simple_read_from_buffer(buf, count, ppos,
30319 ++ (char *)page, length);
30320 ++
30321 ++ free_page(page);
30322 ++out_put:
30323 ++ put_vx_info(vxi);
30324 ++out:
30325 ++ return length;
30326 ++}
30327 ++
30328 ++static ssize_t proc_nx_info_read(struct file *file, char __user *buf,
30329 ++ size_t count, loff_t *ppos)
30330 ++{
30331 ++ struct inode *inode = file->f_dentry->d_inode;
30332 ++ struct nx_info *nxi = NULL;
30333 ++ nid_t nid = PROC_I(inode)->fd;
30334 ++ unsigned long page;
30335 ++ ssize_t length = 0;
30336 ++
30337 ++ if (count > PROC_BLOCK_SIZE)
30338 ++ count = PROC_BLOCK_SIZE;
30339 ++
30340 ++ /* fade that out as soon as stable */
30341 ++ WARN_ON(!nid);
30342 ++ nxi = lookup_nx_info(nid);
30343 ++ if (!nxi)
30344 ++ goto out;
30345 ++
30346 ++ length = -ENOMEM;
30347 ++ if (!(page = __get_free_page(GFP_KERNEL)))
30348 ++ goto out_put;
30349 ++
30350 ++ BUG_ON(!PROC_I(inode)->op.proc_nxi_read);
30351 ++ length = PROC_I(inode)->op.proc_nxi_read(nxi, (char *)page);
30352 ++
30353 ++ if (length >= 0)
30354 ++ length = simple_read_from_buffer(buf, count, ppos,
30355 ++ (char *)page, length);
30356 ++
30357 ++ free_page(page);
30358 ++out_put:
30359 ++ put_nx_info(nxi);
30360 ++out:
30361 ++ return length;
30362 ++}
30363 ++
30364 ++
30365 ++
30366 ++/* here comes the lower level */
30367 ++
30368 ++
30369 ++#define NOD(NAME, MODE, IOP, FOP, OP) { \
30370 ++ .len = sizeof(NAME) - 1, \
30371 ++ .name = (NAME), \
30372 ++ .mode = MODE, \
30373 ++ .iop = IOP, \
30374 ++ .fop = FOP, \
30375 ++ .op = OP, \
30376 ++}
30377 ++
30378 ++
30379 ++#define DIR(NAME, MODE, OTYPE) \
30380 ++ NOD(NAME, (S_IFDIR | (MODE)), \
30381 ++ &proc_ ## OTYPE ## _inode_operations, \
30382 ++ &proc_ ## OTYPE ## _file_operations, { } )
30383 ++
30384 ++#define INF(NAME, MODE, OTYPE) \
30385 ++ NOD(NAME, (S_IFREG | (MODE)), NULL, \
30386 ++ &proc_vs_info_file_operations, \
30387 ++ { .proc_vs_read = &proc_##OTYPE } )
30388 ++
30389 ++#define VINF(NAME, MODE, OTYPE) \
30390 ++ NOD(NAME, (S_IFREG | (MODE)), NULL, \
30391 ++ &proc_vx_info_file_operations, \
30392 ++ { .proc_vxi_read = &proc_##OTYPE } )
30393 ++
30394 ++#define NINF(NAME, MODE, OTYPE) \
30395 ++ NOD(NAME, (S_IFREG | (MODE)), NULL, \
30396 ++ &proc_nx_info_file_operations, \
30397 ++ { .proc_nxi_read = &proc_##OTYPE } )
30398 ++
30399 ++
30400 ++static struct file_operations proc_vs_info_file_operations = {
30401 ++ .read = proc_vs_info_read,
30402 ++};
30403 ++
30404 ++static struct file_operations proc_vx_info_file_operations = {
30405 ++ .read = proc_vx_info_read,
30406 ++};
30407 ++
30408 ++static struct dentry_operations proc_xid_dentry_operations = {
30409 ++ .d_revalidate = proc_xid_revalidate,
30410 ++};
30411 ++
30412 ++static struct vs_entry vx_base_stuff[] = {
30413 ++ VINF("info", S_IRUGO, vxi_info),
30414 ++ VINF("status", S_IRUGO, vxi_status),
30415 ++ VINF("limit", S_IRUGO, vxi_limit),
30416 ++ VINF("sched", S_IRUGO, vxi_sched),
30417 ++ VINF("nsproxy", S_IRUGO, vxi_nsproxy),
30418 ++ VINF("cvirt", S_IRUGO, vxi_cvirt),
30419 ++ VINF("cacct", S_IRUGO, vxi_cacct),
30420 ++ {}
30421 ++};
30422 ++
30423 ++
30424 ++
30425 ++
30426 ++static struct dentry *proc_xid_instantiate(struct inode *dir,
30427 ++ struct dentry *dentry, int id, void *ptr)
30428 ++{
30429 ++ dentry->d_op = &proc_xid_dentry_operations;
30430 ++ return vs_proc_instantiate(dir, dentry, id, ptr);
30431 ++}
30432 ++
30433 ++static struct dentry *proc_xid_lookup(struct inode *dir,
30434 ++ struct dentry *dentry, struct nameidata *nd)
30435 ++{
30436 ++ struct vs_entry *p = vx_base_stuff;
30437 ++ struct dentry *error = ERR_PTR(-ENOENT);
30438 ++
30439 ++ for (; p->name; p++) {
30440 ++ if (p->len != dentry->d_name.len)
30441 ++ continue;
30442 ++ if (!memcmp(dentry->d_name.name, p->name, p->len))
30443 ++ break;
30444 ++ }
30445 ++ if (!p->name)
30446 ++ goto out;
30447 ++
30448 ++ error = proc_xid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
30449 ++out:
30450 ++ return error;
30451 ++}
30452 ++
30453 ++static int proc_xid_readdir(struct file *filp,
30454 ++ void *dirent, filldir_t filldir)
30455 ++{
30456 ++ struct dentry *dentry = filp->f_dentry;
30457 ++ struct inode *inode = dentry->d_inode;
30458 ++ struct vs_entry *p = vx_base_stuff;
30459 ++ int size = sizeof(vx_base_stuff) / sizeof(struct vs_entry);
30460 ++ int pos, index;
30461 ++ u64 ino;
30462 ++
30463 ++ pos = filp->f_pos;
30464 ++ switch (pos) {
30465 ++ case 0:
30466 ++ ino = inode->i_ino;
30467 ++ if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
30468 ++ goto out;
30469 ++ pos++;
30470 ++ /* fall through */
30471 ++ case 1:
30472 ++ ino = parent_ino(dentry);
30473 ++ if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
30474 ++ goto out;
30475 ++ pos++;
30476 ++ /* fall through */
30477 ++ default:
30478 ++ index = pos - 2;
30479 ++ if (index >= size)
30480 ++ goto out;
30481 ++ for (p += index; p->name; p++) {
30482 ++ if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
30483 ++ vs_proc_instantiate, PROC_I(inode)->fd, p))
30484 ++ goto out;
30485 ++ pos++;
30486 ++ }
30487 ++ }
30488 ++out:
30489 ++ filp->f_pos = pos;
30490 ++ return 1;
30491 ++}
30492 ++
30493 ++
30494 ++
30495 ++static struct file_operations proc_nx_info_file_operations = {
30496 ++ .read = proc_nx_info_read,
30497 ++};
30498 ++
30499 ++static struct dentry_operations proc_nid_dentry_operations = {
30500 ++ .d_revalidate = proc_nid_revalidate,
30501 ++};
30502 ++
30503 ++static struct vs_entry nx_base_stuff[] = {
30504 ++ NINF("info", S_IRUGO, nxi_info),
30505 ++ NINF("status", S_IRUGO, nxi_status),
30506 ++ {}
30507 ++};
30508 ++
30509 ++
30510 ++static struct dentry *proc_nid_instantiate(struct inode *dir,
30511 ++ struct dentry *dentry, int id, void *ptr)
30512 ++{
30513 ++ dentry->d_op = &proc_nid_dentry_operations;
30514 ++ return vs_proc_instantiate(dir, dentry, id, ptr);
30515 ++}
30516 ++
30517 ++static struct dentry *proc_nid_lookup(struct inode *dir,
30518 ++ struct dentry *dentry, struct nameidata *nd)
30519 ++{
30520 ++ struct vs_entry *p = nx_base_stuff;
30521 ++ struct dentry *error = ERR_PTR(-ENOENT);
30522 ++
30523 ++ for (; p->name; p++) {
30524 ++ if (p->len != dentry->d_name.len)
30525 ++ continue;
30526 ++ if (!memcmp(dentry->d_name.name, p->name, p->len))
30527 ++ break;
30528 ++ }
30529 ++ if (!p->name)
30530 ++ goto out;
30531 ++
30532 ++ error = proc_nid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
30533 ++out:
30534 ++ return error;
30535 ++}
30536 ++
30537 ++static int proc_nid_readdir(struct file *filp,
30538 ++ void *dirent, filldir_t filldir)
30539 ++{
30540 ++ struct dentry *dentry = filp->f_dentry;
30541 ++ struct inode *inode = dentry->d_inode;
30542 ++ struct vs_entry *p = nx_base_stuff;
30543 ++ int size = sizeof(nx_base_stuff) / sizeof(struct vs_entry);
30544 ++ int pos, index;
30545 ++ u64 ino;
30546 ++
30547 ++ pos = filp->f_pos;
30548 ++ switch (pos) {
30549 ++ case 0:
30550 ++ ino = inode->i_ino;
30551 ++ if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
30552 ++ goto out;
30553 ++ pos++;
30554 ++ /* fall through */
30555 ++ case 1:
30556 ++ ino = parent_ino(dentry);
30557 ++ if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
30558 ++ goto out;
30559 ++ pos++;
30560 ++ /* fall through */
30561 ++ default:
30562 ++ index = pos - 2;
30563 ++ if (index >= size)
30564 ++ goto out;
30565 ++ for (p += index; p->name; p++) {
30566 ++ if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
30567 ++ vs_proc_instantiate, PROC_I(inode)->fd, p))
30568 ++ goto out;
30569 ++ pos++;
30570 ++ }
30571 ++ }
30572 ++out:
30573 ++ filp->f_pos = pos;
30574 ++ return 1;
30575 ++}
30576 ++
30577 ++
30578 ++#define MAX_MULBY10 ((~0U - 9) / 10)
30579 ++
30580 ++static inline int atovid(const char *str, int len)
30581 ++{
30582 ++ int vid, c;
30583 ++
30584 ++ vid = 0;
30585 ++ while (len-- > 0) {
30586 ++ c = *str - '0';
30587 ++ str++;
30588 ++ if (c > 9)
30589 ++ return -1;
30590 ++ if (vid >= MAX_MULBY10)
30591 ++ return -1;
30592 ++ vid *= 10;
30593 ++ vid += c;
30594 ++ if (!vid)
30595 ++ return -1;
30596 ++ }
30597 ++ return vid;
30598 ++}
30599 ++
30600 ++/* now the upper level (virtual) */
30601 ++
30602 ++
30603 ++static struct file_operations proc_xid_file_operations = {
30604 ++ .read = generic_read_dir,
30605 ++ .readdir = proc_xid_readdir,
30606 ++};
30607 ++
30608 ++static struct inode_operations proc_xid_inode_operations = {
30609 ++ .lookup = proc_xid_lookup,
30610 ++};
30611 ++
30612 ++static struct vs_entry vx_virtual_stuff[] = {
30613 ++ INF("info", S_IRUGO, virtual_info),
30614 ++ INF("status", S_IRUGO, virtual_status),
30615 ++ DIR(NULL, S_IRUGO | S_IXUGO, xid),
30616 ++};
30617 ++
30618 ++
30619 ++static struct dentry *proc_virtual_lookup(struct inode *dir,
30620 ++ struct dentry *dentry, struct nameidata *nd)
30621 ++{
30622 ++ struct vs_entry *p = vx_virtual_stuff;
30623 ++ struct dentry *error = ERR_PTR(-ENOENT);
30624 ++ int id = 0;
30625 ++
30626 ++ for (; p->name; p++) {
30627 ++ if (p->len != dentry->d_name.len)
30628 ++ continue;
30629 ++ if (!memcmp(dentry->d_name.name, p->name, p->len))
30630 ++ break;
30631 ++ }
30632 ++ if (p->name)
30633 ++ goto instantiate;
30634 ++
30635 ++ id = atovid(dentry->d_name.name, dentry->d_name.len);
30636 ++ if ((id < 0) || !xid_is_hashed(id))
30637 ++ goto out;
30638 ++
30639 ++instantiate:
30640 ++ error = proc_xid_instantiate(dir, dentry, id, p);
30641 ++out:
30642 ++ return error;
30643 ++}
30644 ++
30645 ++static struct file_operations proc_nid_file_operations = {
30646 ++ .read = generic_read_dir,
30647 ++ .readdir = proc_nid_readdir,
30648 ++};
30649 ++
30650 ++static struct inode_operations proc_nid_inode_operations = {
30651 ++ .lookup = proc_nid_lookup,
30652 ++};
30653 ++
30654 ++static struct vs_entry nx_virtnet_stuff[] = {
30655 ++ INF("info", S_IRUGO, virtnet_info),
30656 ++ INF("status", S_IRUGO, virtnet_status),
30657 ++ DIR(NULL, S_IRUGO | S_IXUGO, nid),
30658 ++};
30659 ++
30660 ++
30661 ++static struct dentry *proc_virtnet_lookup(struct inode *dir,
30662 ++ struct dentry *dentry, struct nameidata *nd)
30663 ++{
30664 ++ struct vs_entry *p = nx_virtnet_stuff;
30665 ++ struct dentry *error = ERR_PTR(-ENOENT);
30666 ++ int id = 0;
30667 ++
30668 ++ for (; p->name; p++) {
30669 ++ if (p->len != dentry->d_name.len)
30670 ++ continue;
30671 ++ if (!memcmp(dentry->d_name.name, p->name, p->len))
30672 ++ break;
30673 ++ }
30674 ++ if (p->name)
30675 ++ goto instantiate;
30676 ++
30677 ++ id = atovid(dentry->d_name.name, dentry->d_name.len);
30678 ++ if ((id < 0) || !nid_is_hashed(id))
30679 ++ goto out;
30680 ++
30681 ++instantiate:
30682 ++ error = proc_nid_instantiate(dir, dentry, id, p);
30683 ++out:
30684 ++ return error;
30685 ++}
30686 ++
30687 ++
30688 ++
30689 ++#define PROC_NUMBUF 10
30690 ++#define PROC_MAXVIDS 32
30691 ++
30692 ++int proc_virtual_readdir(struct file *filp,
30693 ++ void *dirent, filldir_t filldir)
30694 ++{
30695 ++ struct dentry *dentry = filp->f_dentry;
30696 ++ struct inode *inode = dentry->d_inode;
30697 ++ struct vs_entry *p = vx_virtual_stuff;
30698 ++ int size = sizeof(vx_virtual_stuff) / sizeof(struct vs_entry);
30699 ++ int pos, index;
30700 ++ unsigned int xid_array[PROC_MAXVIDS];
30701 ++ char buf[PROC_NUMBUF];
30702 ++ unsigned int nr_xids, i;
30703 ++ u64 ino;
30704 ++
30705 ++ pos = filp->f_pos;
30706 ++ switch (pos) {
30707 ++ case 0:
30708 ++ ino = inode->i_ino;
30709 ++ if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
30710 ++ goto out;
30711 ++ pos++;
30712 ++ /* fall through */
30713 ++ case 1:
30714 ++ ino = parent_ino(dentry);
30715 ++ if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
30716 ++ goto out;
30717 ++ pos++;
30718 ++ /* fall through */
30719 ++ default:
30720 ++ index = pos - 2;
30721 ++ if (index >= size)
30722 ++ goto entries;
30723 ++ for (p += index; p->name; p++) {
30724 ++ if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
30725 ++ vs_proc_instantiate, 0, p))
30726 ++ goto out;
30727 ++ pos++;
30728 ++ }
30729 ++ entries:
30730 ++ index = pos - size;
30731 ++ p = &vx_virtual_stuff[size - 1];
30732 ++ nr_xids = get_xid_list(index, xid_array, PROC_MAXVIDS);
30733 ++ for (i = 0; i < nr_xids; i++) {
30734 ++ int n, xid = xid_array[i];
30735 ++ unsigned int j = PROC_NUMBUF;
30736 ++
30737 ++ n = xid;
30738 ++ do
30739 ++ buf[--j] = '0' + (n % 10);
30740 ++ while (n /= 10);
30741 ++
30742 ++ if (proc_fill_cache(filp, dirent, filldir,
30743 ++ buf + j, PROC_NUMBUF - j,
30744 ++ vs_proc_instantiate, xid, p))
30745 ++ goto out;
30746 ++ pos++;
30747 ++ }
30748 ++ }
30749 ++out:
30750 ++ filp->f_pos = pos;
30751 ++ return 0;
30752 ++}
30753 ++
30754 ++static int proc_virtual_getattr(struct vfsmount *mnt,
30755 ++ struct dentry *dentry, struct kstat *stat)
30756 ++{
30757 ++ struct inode *inode = dentry->d_inode;
30758 ++
30759 ++ generic_fillattr(inode, stat);
30760 ++ stat->nlink = 2 + atomic_read(&vx_global_cactive);
30761 ++ return 0;
30762 ++}
30763 ++
30764 ++static struct file_operations proc_virtual_dir_operations = {
30765 ++ .read = generic_read_dir,
30766 ++ .readdir = proc_virtual_readdir,
30767 ++};
30768 ++
30769 ++static struct inode_operations proc_virtual_dir_inode_operations = {
30770 ++ .getattr = proc_virtual_getattr,
30771 ++ .lookup = proc_virtual_lookup,
30772 ++};
30773 ++
30774 ++
30775 ++
30776 ++
30777 ++
30778 ++int proc_virtnet_readdir(struct file *filp,
30779 ++ void *dirent, filldir_t filldir)
30780 ++{
30781 ++ struct dentry *dentry = filp->f_dentry;
30782 ++ struct inode *inode = dentry->d_inode;
30783 ++ struct vs_entry *p = nx_virtnet_stuff;
30784 ++ int size = sizeof(nx_virtnet_stuff) / sizeof(struct vs_entry);
30785 ++ int pos, index;
30786 ++ unsigned int nid_array[PROC_MAXVIDS];
30787 ++ char buf[PROC_NUMBUF];
30788 ++ unsigned int nr_nids, i;
30789 ++ u64 ino;
30790 ++
30791 ++ pos = filp->f_pos;
30792 ++ switch (pos) {
30793 ++ case 0:
30794 ++ ino = inode->i_ino;
30795 ++ if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
30796 ++ goto out;
30797 ++ pos++;
30798 ++ /* fall through */
30799 ++ case 1:
30800 ++ ino = parent_ino(dentry);
30801 ++ if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
30802 ++ goto out;
30803 ++ pos++;
30804 ++ /* fall through */
30805 ++ default:
30806 ++ index = pos - 2;
30807 ++ if (index >= size)
30808 ++ goto entries;
30809 ++ for (p += index; p->name; p++) {
30810 ++ if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
30811 ++ vs_proc_instantiate, 0, p))
30812 ++ goto out;
30813 ++ pos++;
30814 ++ }
30815 ++ entries:
30816 ++ index = pos - size;
30817 ++ p = &nx_virtnet_stuff[size - 1];
30818 ++ nr_nids = get_nid_list(index, nid_array, PROC_MAXVIDS);
30819 ++ for (i = 0; i < nr_nids; i++) {
30820 ++ int n, nid = nid_array[i];
30821 ++ unsigned int j = PROC_NUMBUF;
30822 ++
30823 ++ n = nid;
30824 ++ do
30825 ++ buf[--j] = '0' + (n % 10);
30826 ++ while (n /= 10);
30827 ++
30828 ++ if (proc_fill_cache(filp, dirent, filldir,
30829 ++ buf + j, PROC_NUMBUF - j,
30830 ++ vs_proc_instantiate, nid, p))
30831 ++ goto out;
30832 ++ pos++;
30833 ++ }
30834 ++ }
30835 ++out:
30836 ++ filp->f_pos = pos;
30837 ++ return 0;
30838 ++}
30839 ++
30840 ++static int proc_virtnet_getattr(struct vfsmount *mnt,
30841 ++ struct dentry *dentry, struct kstat *stat)
30842 ++{
30843 ++ struct inode *inode = dentry->d_inode;
30844 ++
30845 ++ generic_fillattr(inode, stat);
30846 ++ stat->nlink = 2 + atomic_read(&nx_global_cactive);
30847 ++ return 0;
30848 ++}
30849 ++
30850 ++static struct file_operations proc_virtnet_dir_operations = {
30851 ++ .read = generic_read_dir,
30852 ++ .readdir = proc_virtnet_readdir,
30853 ++};
30854 ++
30855 ++static struct inode_operations proc_virtnet_dir_inode_operations = {
30856 ++ .getattr = proc_virtnet_getattr,
30857 ++ .lookup = proc_virtnet_lookup,
30858 ++};
30859 ++
30860 ++
30861 ++
30862 ++void proc_vx_init(void)
30863 ++{
30864 ++ struct proc_dir_entry *ent;
30865 ++
30866 ++ ent = proc_mkdir("virtual", 0);
30867 ++ if (ent) {
30868 ++ ent->proc_fops = &proc_virtual_dir_operations;
30869 ++ ent->proc_iops = &proc_virtual_dir_inode_operations;
30870 ++ }
30871 ++ proc_virtual = ent;
30872 ++
30873 ++ ent = proc_mkdir("virtnet", 0);
30874 ++ if (ent) {
30875 ++ ent->proc_fops = &proc_virtnet_dir_operations;
30876 ++ ent->proc_iops = &proc_virtnet_dir_inode_operations;
30877 ++ }
30878 ++ proc_virtnet = ent;
30879 ++}
30880 ++
30881 ++
30882 ++
30883 ++
30884 ++/* per pid info */
30885 ++
30886 ++
30887 ++int proc_pid_vx_info(struct task_struct *p, char *buffer)
30888 ++{
30889 ++ struct vx_info *vxi;
30890 ++ char *orig = buffer;
30891 ++
30892 ++ buffer += sprintf(buffer, "XID:\t%d\n", vx_task_xid(p));
30893 ++
30894 ++ vxi = task_get_vx_info(p);
30895 ++ if (!vxi)
30896 ++ goto out;
30897 ++
30898 ++ buffer += sprintf(buffer, "BCaps:\t%016llx\n",
30899 ++ (unsigned long long)vxi->vx_bcaps);
30900 ++ buffer += sprintf(buffer, "CCaps:\t%016llx\n",
30901 ++ (unsigned long long)vxi->vx_ccaps);
30902 ++ buffer += sprintf(buffer, "CFlags:\t%016llx\n",
30903 ++ (unsigned long long)vxi->vx_flags);
30904 ++ buffer += sprintf(buffer, "CIPid:\t%d\n", vxi->vx_initpid);
30905 ++
30906 ++ put_vx_info(vxi);
30907 ++out:
30908 ++ return buffer - orig;
30909 ++}
30910 ++
30911 ++
30912 ++int proc_pid_nx_info(struct task_struct *p, char *buffer)
30913 ++{
30914 ++ struct nx_info *nxi;
30915 ++ struct nx_addr_v4 *v4a;
30916 ++#ifdef CONFIG_IPV6
30917 ++ struct nx_addr_v6 *v6a;
30918 ++#endif
30919 ++ char *orig = buffer;
30920 ++ int i;
30921 ++
30922 ++ buffer += sprintf(buffer, "NID:\t%d\n", nx_task_nid(p));
30923 ++
30924 ++ nxi = task_get_nx_info(p);
30925 ++ if (!nxi)
30926 ++ goto out;
30927 ++
30928 ++ buffer += sprintf(buffer, "NCaps:\t%016llx\n",
30929 ++ (unsigned long long)nxi->nx_ncaps);
30930 ++ buffer += sprintf(buffer, "NFlags:\t%016llx\n",
30931 ++ (unsigned long long)nxi->nx_flags);
30932 ++
30933 ++ buffer += sprintf(buffer,
30934 ++ "V4Root[bcast]:\t" NIPQUAD_FMT "\n",
30935 ++ NIPQUAD(nxi->v4_bcast.s_addr));
30936 ++ buffer += sprintf (buffer,
30937 ++ "V4Root[lback]:\t" NIPQUAD_FMT "\n",
30938 ++ NIPQUAD(nxi->v4_lback.s_addr));
30939 ++ if (!NX_IPV4(nxi))
30940 ++ goto skip_v4;
30941 ++ for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
30942 ++ buffer += sprintf(buffer, "V4Root[%d]:\t" NXAV4_FMT "\n",
30943 ++ i, NXAV4(v4a));
30944 ++skip_v4:
30945 ++#ifdef CONFIG_IPV6
30946 ++ if (!NX_IPV6(nxi))
30947 ++ goto skip_v6;
30948 ++ for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
30949 ++ buffer += sprintf(buffer, "V6Root[%d]:\t" NXAV6_FMT "\n",
30950 ++ i, NXAV6(v6a));
30951 ++skip_v6:
30952 ++#endif
30953 ++ put_nx_info(nxi);
30954 ++out:
30955 ++ return buffer - orig;
30956 ++}
30957 ++
30958 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/sched.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/sched.c
30959 +--- linux-2.6.22.19/kernel/vserver/sched.c 1970-01-01 01:00:00 +0100
30960 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/sched.c 2007-08-15 23:32:49 +0200
30961 +@@ -0,0 +1,413 @@
30962 ++/*
30963 ++ * linux/kernel/vserver/sched.c
30964 ++ *
30965 ++ * Virtual Server: Scheduler Support
30966 ++ *
30967 ++ * Copyright (C) 2004-2007 Herbert Pötzl
30968 ++ *
30969 ++ * V0.01 adapted Sam Vilains version to 2.6.3
30970 ++ * V0.02 removed legacy interface
30971 ++ * V0.03 changed vcmds to vxi arg
30972 ++ * V0.04 removed older and legacy interfaces
30973 ++ *
30974 ++ */
30975 ++
30976 ++#include <linux/vs_context.h>
30977 ++#include <linux/vs_sched.h>
30978 ++#include <linux/vserver/sched_cmd.h>
30979 ++
30980 ++#include <asm/uaccess.h>
30981 ++
30982 ++
30983 ++#define vxd_check_range(val, min, max) do { \
30984 ++ vxlprintk((val < min) || (val > max), \
30985 ++ "check_range(%ld,%ld,%ld)", \
30986 ++ (long)val, (long)min, (long)max, \
30987 ++ __FILE__, __LINE__); \
30988 ++ } while (0)
30989 ++
30990 ++
30991 ++void vx_update_sched_param(struct _vx_sched *sched,
30992 ++ struct _vx_sched_pc *sched_pc)
30993 ++{
30994 ++ unsigned int set_mask = sched->update_mask;
30995 ++
30996 ++ if (set_mask & VXSM_FILL_RATE)
30997 ++ sched_pc->fill_rate[0] = sched->fill_rate[0];
30998 ++ if (set_mask & VXSM_INTERVAL)
30999 ++ sched_pc->interval[0] = sched->interval[0];
31000 ++ if (set_mask & VXSM_FILL_RATE2)
31001 ++ sched_pc->fill_rate[1] = sched->fill_rate[1];
31002 ++ if (set_mask & VXSM_INTERVAL2)
31003 ++ sched_pc->interval[1] = sched->interval[1];
31004 ++ if (set_mask & VXSM_TOKENS)
31005 ++ sched_pc->tokens = sched->tokens;
31006 ++ if (set_mask & VXSM_TOKENS_MIN)
31007 ++ sched_pc->tokens_min = sched->tokens_min;
31008 ++ if (set_mask & VXSM_TOKENS_MAX)
31009 ++ sched_pc->tokens_max = sched->tokens_max;
31010 ++ if (set_mask & VXSM_PRIO_BIAS)
31011 ++ sched_pc->prio_bias = sched->prio_bias;
31012 ++
31013 ++ if (set_mask & VXSM_IDLE_TIME)
31014 ++ sched_pc->flags |= VXSF_IDLE_TIME;
31015 ++ else
31016 ++ sched_pc->flags &= ~VXSF_IDLE_TIME;
31017 ++
31018 ++ /* reset time */
31019 ++ sched_pc->norm_time = jiffies;
31020 ++}
31021 ++
31022 ++
31023 ++/*
31024 ++ * recalculate the context's scheduling tokens
31025 ++ *
31026 ++ * ret > 0 : number of tokens available
31027 ++ * ret < 0 : on hold, check delta_min[]
31028 ++ * -1 only jiffies
31029 ++ * -2 also idle time
31030 ++ *
31031 ++ */
31032 ++int vx_tokens_recalc(struct _vx_sched_pc *sched_pc,
31033 ++ unsigned long *norm_time, unsigned long *idle_time, int delta_min[2])
31034 ++{
31035 ++ long delta;
31036 ++ long tokens = 0;
31037 ++ int flags = sched_pc->flags;
31038 ++
31039 ++ /* how much time did pass? */
31040 ++ delta = *norm_time - sched_pc->norm_time;
31041 ++ vxd_check_range(delta, 0, INT_MAX);
31042 ++
31043 ++ if (delta >= sched_pc->interval[0]) {
31044 ++ long tokens, integral;
31045 ++
31046 ++ /* calc integral token part */
31047 ++ tokens = delta / sched_pc->interval[0];
31048 ++ integral = tokens * sched_pc->interval[0];
31049 ++ tokens *= sched_pc->fill_rate[0];
31050 ++#ifdef CONFIG_VSERVER_HARDCPU
31051 ++ delta_min[0] = delta - integral;
31052 ++ vxd_check_range(delta_min[0], 0, sched_pc->interval[0]);
31053 ++#endif
31054 ++ /* advance time */
31055 ++ sched_pc->norm_time += delta;
31056 ++
31057 ++ /* add tokens */
31058 ++ sched_pc->tokens += tokens;
31059 ++ sched_pc->token_time += tokens;
31060 ++ } else
31061 ++ delta_min[0] = delta;
31062 ++
31063 ++#ifdef CONFIG_VSERVER_IDLETIME
31064 ++ if (!(flags & VXSF_IDLE_TIME))
31065 ++ goto skip_idle;
31066 ++
31067 ++ /* how much was the idle skip? */
31068 ++ delta = *idle_time - sched_pc->idle_time;
31069 ++ vxd_check_range(delta, 0, INT_MAX);
31070 ++
31071 ++ if (delta >= sched_pc->interval[1]) {
31072 ++ long tokens, integral;
31073 ++
31074 ++ /* calc fair share token part */
31075 ++ tokens = delta / sched_pc->interval[1];
31076 ++ integral = tokens * sched_pc->interval[1];
31077 ++ tokens *= sched_pc->fill_rate[1];
31078 ++ delta_min[1] = delta - integral;
31079 ++ vxd_check_range(delta_min[1], 0, sched_pc->interval[1]);
31080 ++
31081 ++ /* advance idle time */
31082 ++ sched_pc->idle_time += integral;
31083 ++
31084 ++ /* add tokens */
31085 ++ sched_pc->tokens += tokens;
31086 ++ sched_pc->token_time += tokens;
31087 ++ } else
31088 ++ delta_min[1] = delta;
31089 ++skip_idle:
31090 ++#endif
31091 ++
31092 ++ /* clip at maximum */
31093 ++ if (sched_pc->tokens > sched_pc->tokens_max)
31094 ++ sched_pc->tokens = sched_pc->tokens_max;
31095 ++ tokens = sched_pc->tokens;
31096 ++
31097 ++ if ((flags & VXSF_ONHOLD)) {
31098 ++ /* can we unhold? */
31099 ++ if (tokens >= sched_pc->tokens_min) {
31100 ++ flags &= ~VXSF_ONHOLD;
31101 ++ sched_pc->hold_ticks +=
31102 ++ *norm_time - sched_pc->onhold;
31103 ++ } else
31104 ++ goto on_hold;
31105 ++ } else {
31106 ++ /* put on hold? */
31107 ++ if (tokens <= 0) {
31108 ++ flags |= VXSF_ONHOLD;
31109 ++ sched_pc->onhold = *norm_time;
31110 ++ goto on_hold;
31111 ++ }
31112 ++ }
31113 ++ sched_pc->flags = flags;
31114 ++ return tokens;
31115 ++
31116 ++on_hold:
31117 ++ tokens = sched_pc->tokens_min - tokens;
31118 ++ sched_pc->flags = flags;
31119 ++ BUG_ON(tokens < 0);
31120 ++
31121 ++#ifdef CONFIG_VSERVER_HARDCPU
31122 ++ /* next interval? */
31123 ++ if (!sched_pc->fill_rate[0])
31124 ++ delta_min[0] = HZ;
31125 ++ else if (tokens > sched_pc->fill_rate[0])
31126 ++ delta_min[0] += sched_pc->interval[0] *
31127 ++ tokens / sched_pc->fill_rate[0];
31128 ++ else
31129 ++ delta_min[0] = sched_pc->interval[0] - delta_min[0];
31130 ++ vxd_check_range(delta_min[0], 0, INT_MAX);
31131 ++
31132 ++#ifdef CONFIG_VSERVER_IDLETIME
31133 ++ if (!(flags & VXSF_IDLE_TIME))
31134 ++ return -1;
31135 ++
31136 ++ /* next interval? */
31137 ++ if (!sched_pc->fill_rate[1])
31138 ++ delta_min[1] = HZ;
31139 ++ else if (tokens > sched_pc->fill_rate[1])
31140 ++ delta_min[1] += sched_pc->interval[1] *
31141 ++ tokens / sched_pc->fill_rate[1];
31142 ++ else
31143 ++ delta_min[1] = sched_pc->interval[1] - delta_min[1];
31144 ++ vxd_check_range(delta_min[1], 0, INT_MAX);
31145 ++
31146 ++ return -2;
31147 ++#else
31148 ++ return -1;
31149 ++#endif /* CONFIG_VSERVER_IDLETIME */
31150 ++#else
31151 ++ return 0;
31152 ++#endif /* CONFIG_VSERVER_HARDCPU */
31153 ++}
31154 ++
31155 ++static inline unsigned long msec_to_ticks(unsigned long msec)
31156 ++{
31157 ++ return msecs_to_jiffies(msec);
31158 ++}
31159 ++
31160 ++static inline unsigned long ticks_to_msec(unsigned long ticks)
31161 ++{
31162 ++ return jiffies_to_msecs(ticks);
31163 ++}
31164 ++
31165 ++static inline unsigned long ticks_to_usec(unsigned long ticks)
31166 ++{
31167 ++ return jiffies_to_usecs(ticks);
31168 ++}
31169 ++
31170 ++
31171 ++static int do_set_sched(struct vx_info *vxi, struct vcmd_sched_v5 *data)
31172 ++{
31173 ++ unsigned int set_mask = data->mask;
31174 ++ unsigned int update_mask;
31175 ++ int i, cpu;
31176 ++
31177 ++ /* Sanity check data values */
31178 ++ if (data->tokens_max <= 0)
31179 ++ data->tokens_max = HZ;
31180 ++ if (data->tokens_min < 0)
31181 ++ data->tokens_min = HZ / 3;
31182 ++ if (data->tokens_min >= data->tokens_max)
31183 ++ data->tokens_min = data->tokens_max;
31184 ++
31185 ++ if (data->prio_bias > MAX_PRIO_BIAS)
31186 ++ data->prio_bias = MAX_PRIO_BIAS;
31187 ++ if (data->prio_bias < MIN_PRIO_BIAS)
31188 ++ data->prio_bias = MIN_PRIO_BIAS;
31189 ++
31190 ++ spin_lock(&vxi->sched.tokens_lock);
31191 ++
31192 ++ /* sync up on delayed updates */
31193 ++ for_each_cpu_mask(cpu, vxi->sched.update)
31194 ++ vx_update_sched_param(&vxi->sched,
31195 ++ &vx_per_cpu(vxi, sched_pc, cpu));
31196 ++
31197 ++ if (set_mask & VXSM_FILL_RATE)
31198 ++ vxi->sched.fill_rate[0] = data->fill_rate[0];
31199 ++ if (set_mask & VXSM_FILL_RATE2)
31200 ++ vxi->sched.fill_rate[1] = data->fill_rate[1];
31201 ++ if (set_mask & VXSM_INTERVAL)
31202 ++ vxi->sched.interval[0] = (set_mask & VXSM_MSEC) ?
31203 ++ msec_to_ticks(data->interval[0]) : data->interval[0];
31204 ++ if (set_mask & VXSM_INTERVAL2)
31205 ++ vxi->sched.interval[1] = (set_mask & VXSM_MSEC) ?
31206 ++ msec_to_ticks(data->interval[1]) : data->interval[1];
31207 ++ if (set_mask & VXSM_TOKENS)
31208 ++ vxi->sched.tokens = data->tokens;
31209 ++ if (set_mask & VXSM_TOKENS_MIN)
31210 ++ vxi->sched.tokens_min = data->tokens_min;
31211 ++ if (set_mask & VXSM_TOKENS_MAX)
31212 ++ vxi->sched.tokens_max = data->tokens_max;
31213 ++ if (set_mask & VXSM_PRIO_BIAS)
31214 ++ vxi->sched.prio_bias = data->prio_bias;
31215 ++
31216 ++ /* Sanity check rate/interval */
31217 ++ for (i = 0; i < 2; i++) {
31218 ++ if (data->fill_rate[i] < 0)
31219 ++ data->fill_rate[i] = 0;
31220 ++ if (data->interval[i] <= 0)
31221 ++ data->interval[i] = HZ;
31222 ++ }
31223 ++
31224 ++ update_mask = vxi->sched.update_mask & VXSM_SET_MASK;
31225 ++ update_mask |= (set_mask & (VXSM_SET_MASK | VXSM_IDLE_TIME));
31226 ++ vxi->sched.update_mask = update_mask;
31227 ++
31228 ++#ifdef CONFIG_SMP
31229 ++ rmb();
31230 ++ if (set_mask & VXSM_CPU_ID) {
31231 ++ vxi->sched.update = cpumask_of_cpu(data->cpu_id);
31232 ++ cpus_and(vxi->sched.update, cpu_online_map,
31233 ++ vxi->sched.update);
31234 ++ } else
31235 ++ vxi->sched.update = cpu_online_map;
31236 ++
31237 ++ /* forced reload? */
31238 ++ if (set_mask & VXSM_FORCE) {
31239 ++ for_each_cpu_mask(cpu, vxi->sched.update)
31240 ++ vx_update_sched_param(&vxi->sched,
31241 ++ &vx_per_cpu(vxi, sched_pc, cpu));
31242 ++ vxi->sched.update = CPU_MASK_NONE;
31243 ++ }
31244 ++#else
31245 ++ /* on UP we update immediately */
31246 ++ vx_update_sched_param(&vxi->sched,
31247 ++ &vx_per_cpu(vxi, sched_pc, 0));
31248 ++#endif
31249 ++
31250 ++ spin_unlock(&vxi->sched.tokens_lock);
31251 ++ return 0;
31252 ++}
31253 ++
31254 ++
31255 ++#define COPY_IDS(C) C(cpu_id); C(bucket_id)
31256 ++#define COPY_PRI(C) C(prio_bias)
31257 ++#define COPY_TOK(C) C(tokens); C(tokens_min); C(tokens_max)
31258 ++#define COPY_FRI(C) C(fill_rate[0]); C(interval[0]); \
31259 ++ C(fill_rate[1]); C(interval[1]);
31260 ++
31261 ++#define COPY_VALUE(name) vc_data.name = data->name
31262 ++
31263 ++static int do_set_sched_v4(struct vx_info *vxi, struct vcmd_set_sched_v4 *data)
31264 ++{
31265 ++ struct vcmd_sched_v5 vc_data;
31266 ++
31267 ++ vc_data.mask = data->set_mask;
31268 ++ COPY_IDS(COPY_VALUE);
31269 ++ COPY_PRI(COPY_VALUE);
31270 ++ COPY_TOK(COPY_VALUE);
31271 ++ vc_data.fill_rate[0] = vc_data.fill_rate[1] = data->fill_rate;
31272 ++ vc_data.interval[0] = vc_data.interval[1] = data->interval;
31273 ++ return do_set_sched(vxi, &vc_data);
31274 ++}
31275 ++
31276 ++int vc_set_sched_v4(struct vx_info *vxi, void __user *data)
31277 ++{
31278 ++ struct vcmd_set_sched_v4 vc_data;
31279 ++
31280 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
31281 ++ return -EFAULT;
31282 ++
31283 ++ return do_set_sched_v4(vxi, &vc_data);
31284 ++}
31285 ++
31286 ++ /* latest interface is v5 */
31287 ++
31288 ++int vc_set_sched(struct vx_info *vxi, void __user *data)
31289 ++{
31290 ++ struct vcmd_sched_v5 vc_data;
31291 ++
31292 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
31293 ++ return -EFAULT;
31294 ++
31295 ++ return do_set_sched(vxi, &vc_data);
31296 ++}
31297 ++
31298 ++
31299 ++#define COPY_PRI(C) C(prio_bias)
31300 ++#define COPY_TOK(C) C(tokens); C(tokens_min); C(tokens_max)
31301 ++#define COPY_FRI(C) C(fill_rate[0]); C(interval[0]); \
31302 ++ C(fill_rate[1]); C(interval[1]);
31303 ++
31304 ++#define COPY_VALUE(name) vc_data.name = data->name
31305 ++
31306 ++
31307 ++int vc_get_sched(struct vx_info *vxi, void __user *data)
31308 ++{
31309 ++ struct vcmd_sched_v5 vc_data;
31310 ++
31311 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
31312 ++ return -EFAULT;
31313 ++
31314 ++ if (vc_data.mask & VXSM_CPU_ID) {
31315 ++ int cpu = vc_data.cpu_id;
31316 ++ struct _vx_sched_pc *data;
31317 ++
31318 ++ if (!cpu_possible(cpu))
31319 ++ return -EINVAL;
31320 ++
31321 ++ data = &vx_per_cpu(vxi, sched_pc, cpu);
31322 ++ COPY_TOK(COPY_VALUE);
31323 ++ COPY_PRI(COPY_VALUE);
31324 ++ COPY_FRI(COPY_VALUE);
31325 ++
31326 ++ if (data->flags & VXSF_IDLE_TIME)
31327 ++ vc_data.mask |= VXSM_IDLE_TIME;
31328 ++ } else {
31329 ++ struct _vx_sched *data = &vxi->sched;
31330 ++
31331 ++ COPY_TOK(COPY_VALUE);
31332 ++ COPY_PRI(COPY_VALUE);
31333 ++ COPY_FRI(COPY_VALUE);
31334 ++ }
31335 ++
31336 ++ if (vc_data.mask & VXSM_MSEC) {
31337 ++ vc_data.interval[0] = ticks_to_msec(vc_data.interval[0]);
31338 ++ vc_data.interval[1] = ticks_to_msec(vc_data.interval[1]);
31339 ++ }
31340 ++
31341 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
31342 ++ return -EFAULT;
31343 ++ return 0;
31344 ++}
31345 ++
31346 ++
31347 ++int vc_sched_info(struct vx_info *vxi, void __user *data)
31348 ++{
31349 ++ struct vcmd_sched_info vc_data;
31350 ++ int cpu;
31351 ++
31352 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
31353 ++ return -EFAULT;
31354 ++
31355 ++ cpu = vc_data.cpu_id;
31356 ++ if (!cpu_possible(cpu))
31357 ++ return -EINVAL;
31358 ++
31359 ++ if (vxi) {
31360 ++ struct _vx_sched_pc *sched_pc =
31361 ++ &vx_per_cpu(vxi, sched_pc, cpu);
31362 ++
31363 ++ vc_data.user_msec = ticks_to_msec(sched_pc->user_ticks);
31364 ++ vc_data.sys_msec = ticks_to_msec(sched_pc->sys_ticks);
31365 ++ vc_data.hold_msec = ticks_to_msec(sched_pc->hold_ticks);
31366 ++ vc_data.vavavoom = sched_pc->vavavoom;
31367 ++ }
31368 ++ vc_data.token_usec = ticks_to_usec(1);
31369 ++
31370 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
31371 ++ return -EFAULT;
31372 ++ return 0;
31373 ++}
31374 ++
31375 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/sched_init.h linux-2.6.22.19-vs2.3.0.34/kernel/vserver/sched_init.h
31376 +--- linux-2.6.22.19/kernel/vserver/sched_init.h 1970-01-01 01:00:00 +0100
31377 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/sched_init.h 2007-08-05 20:53:13 +0200
31378 +@@ -0,0 +1,50 @@
31379 ++
31380 ++static inline void vx_info_init_sched(struct _vx_sched *sched)
31381 ++{
31382 ++ static struct lock_class_key tokens_lock_key;
31383 ++
31384 ++ /* scheduling; hard code starting values as constants */
31385 ++ sched->fill_rate[0] = 1;
31386 ++ sched->interval[0] = 4;
31387 ++ sched->fill_rate[1] = 1;
31388 ++ sched->interval[1] = 8;
31389 ++ sched->tokens = HZ >> 2;
31390 ++ sched->tokens_min = HZ >> 4;
31391 ++ sched->tokens_max = HZ >> 1;
31392 ++ sched->tokens_lock = SPIN_LOCK_UNLOCKED;
31393 ++ sched->prio_bias = 0;
31394 ++
31395 ++ lockdep_set_class(&sched->tokens_lock, &tokens_lock_key);
31396 ++}
31397 ++
31398 ++static inline
31399 ++void vx_info_init_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
31400 ++{
31401 ++ sched_pc->fill_rate[0] = 1;
31402 ++ sched_pc->interval[0] = 4;
31403 ++ sched_pc->fill_rate[1] = 1;
31404 ++ sched_pc->interval[1] = 8;
31405 ++ sched_pc->tokens = HZ >> 2;
31406 ++ sched_pc->tokens_min = HZ >> 4;
31407 ++ sched_pc->tokens_max = HZ >> 1;
31408 ++ sched_pc->prio_bias = 0;
31409 ++ sched_pc->vavavoom = 0;
31410 ++ sched_pc->token_time = 0;
31411 ++ sched_pc->idle_time = 0;
31412 ++ sched_pc->norm_time = jiffies;
31413 ++
31414 ++ sched_pc->user_ticks = 0;
31415 ++ sched_pc->sys_ticks = 0;
31416 ++ sched_pc->hold_ticks = 0;
31417 ++}
31418 ++
31419 ++static inline void vx_info_exit_sched(struct _vx_sched *sched)
31420 ++{
31421 ++ return;
31422 ++}
31423 ++
31424 ++static inline
31425 ++void vx_info_exit_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
31426 ++{
31427 ++ return;
31428 ++}
31429 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/sched_proc.h linux-2.6.22.19-vs2.3.0.34/kernel/vserver/sched_proc.h
31430 +--- linux-2.6.22.19/kernel/vserver/sched_proc.h 1970-01-01 01:00:00 +0100
31431 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/sched_proc.h 2007-08-05 20:53:13 +0200
31432 +@@ -0,0 +1,57 @@
31433 ++#ifndef _VX_SCHED_PROC_H
31434 ++#define _VX_SCHED_PROC_H
31435 ++
31436 ++
31437 ++static inline
31438 ++int vx_info_proc_sched(struct _vx_sched *sched, char *buffer)
31439 ++{
31440 ++ int length = 0;
31441 ++
31442 ++ length += sprintf(buffer,
31443 ++ "FillRate:\t%8d,%d\n"
31444 ++ "Interval:\t%8d,%d\n"
31445 ++ "TokensMin:\t%8d\n"
31446 ++ "TokensMax:\t%8d\n"
31447 ++ "PrioBias:\t%8d\n",
31448 ++ sched->fill_rate[0],
31449 ++ sched->fill_rate[1],
31450 ++ sched->interval[0],
31451 ++ sched->interval[1],
31452 ++ sched->tokens_min,
31453 ++ sched->tokens_max,
31454 ++ sched->prio_bias);
31455 ++ return length;
31456 ++}
31457 ++
31458 ++static inline
31459 ++int vx_info_proc_sched_pc(struct _vx_sched_pc *sched_pc,
31460 ++ char *buffer, int cpu)
31461 ++{
31462 ++ int length = 0;
31463 ++
31464 ++ length += sprintf(buffer + length,
31465 ++ "cpu %d: %lld %lld %lld %ld %ld", cpu,
31466 ++ (unsigned long long)sched_pc->user_ticks,
31467 ++ (unsigned long long)sched_pc->sys_ticks,
31468 ++ (unsigned long long)sched_pc->hold_ticks,
31469 ++ sched_pc->token_time,
31470 ++ sched_pc->idle_time);
31471 ++ length += sprintf(buffer + length,
31472 ++ " %c%c %d %d %d %d/%d %d/%d",
31473 ++ (sched_pc->flags & VXSF_ONHOLD) ? 'H' : 'R',
31474 ++ (sched_pc->flags & VXSF_IDLE_TIME) ? 'I' : '-',
31475 ++ sched_pc->tokens,
31476 ++ sched_pc->tokens_min,
31477 ++ sched_pc->tokens_max,
31478 ++ sched_pc->fill_rate[0],
31479 ++ sched_pc->interval[0],
31480 ++ sched_pc->fill_rate[1],
31481 ++ sched_pc->interval[1]);
31482 ++ length += sprintf(buffer + length,
31483 ++ " %d %d\n",
31484 ++ sched_pc->prio_bias,
31485 ++ sched_pc->vavavoom);
31486 ++ return length;
31487 ++}
31488 ++
31489 ++#endif /* _VX_SCHED_PROC_H */
31490 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/signal.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/signal.c
31491 +--- linux-2.6.22.19/kernel/vserver/signal.c 1970-01-01 01:00:00 +0100
31492 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/signal.c 2007-08-15 23:34:41 +0200
31493 +@@ -0,0 +1,131 @@
31494 ++/*
31495 ++ * linux/kernel/vserver/signal.c
31496 ++ *
31497 ++ * Virtual Server: Signal Support
31498 ++ *
31499 ++ * Copyright (C) 2003-2007 Herbert Pötzl
31500 ++ *
31501 ++ * V0.01 broken out from vcontext V0.05
31502 ++ * V0.02 changed vcmds to vxi arg
31503 ++ * V0.03 adjusted siginfo for kill
31504 ++ *
31505 ++ */
31506 ++
31507 ++#include <asm/uaccess.h>
31508 ++
31509 ++#include <linux/vs_context.h>
31510 ++#include <linux/vserver/signal_cmd.h>
31511 ++
31512 ++
31513 ++int vx_info_kill(struct vx_info *vxi, int pid, int sig)
31514 ++{
31515 ++ int retval, count = 0;
31516 ++ struct task_struct *p;
31517 ++ struct siginfo *sip = SEND_SIG_PRIV;
31518 ++
31519 ++ retval = -ESRCH;
31520 ++ vxdprintk(VXD_CBIT(misc, 4),
31521 ++ "vx_info_kill(%p[#%d],%d,%d)*",
31522 ++ vxi, vxi->vx_id, pid, sig);
31523 ++ read_lock(&tasklist_lock);
31524 ++ switch (pid) {
31525 ++ case 0:
31526 ++ case -1:
31527 ++ for_each_process(p) {
31528 ++ int err = 0;
31529 ++
31530 ++ if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
31531 ++ (pid && vxi->vx_initpid == p->pid))
31532 ++ continue;
31533 ++
31534 ++ err = group_send_sig_info(sig, sip, p);
31535 ++ ++count;
31536 ++ if (err != -EPERM)
31537 ++ retval = err;
31538 ++ }
31539 ++ break;
31540 ++
31541 ++ case 1:
31542 ++ if (vxi->vx_initpid) {
31543 ++ pid = vxi->vx_initpid;
31544 ++ /* for now, only SIGINT to private init ... */
31545 ++ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
31546 ++ /* ... as long as there are tasks left */
31547 ++ (atomic_read(&vxi->vx_tasks) > 1))
31548 ++ sig = SIGINT;
31549 ++ }
31550 ++ /* fallthrough */
31551 ++ default:
31552 ++ p = find_task_by_real_pid(pid);
31553 ++ if (p) {
31554 ++ if (vx_task_xid(p) == vxi->vx_id)
31555 ++ retval = group_send_sig_info(sig, sip, p);
31556 ++ }
31557 ++ break;
31558 ++ }
31559 ++ read_unlock(&tasklist_lock);
31560 ++ vxdprintk(VXD_CBIT(misc, 4),
31561 ++ "vx_info_kill(%p[#%d],%d,%d,%ld) = %d",
31562 ++ vxi, vxi->vx_id, pid, sig, (long)sip, retval);
31563 ++ return retval;
31564 ++}
31565 ++
31566 ++int vc_ctx_kill(struct vx_info *vxi, void __user *data)
31567 ++{
31568 ++ struct vcmd_ctx_kill_v0 vc_data;
31569 ++
31570 ++ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
31571 ++ return -EFAULT;
31572 ++
31573 ++ /* special check to allow guest shutdown */
31574 ++ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
31575 ++ /* forbid killall pid=0 when init is present */
31576 ++ (((vc_data.pid < 1) && vxi->vx_initpid) ||
31577 ++ (vc_data.pid > 1)))
31578 ++ return -EACCES;
31579 ++
31580 ++ return vx_info_kill(vxi, vc_data.pid, vc_data.sig);
31581 ++}
31582 ++
31583 ++
31584 ++static int __wait_exit(struct vx_info *vxi)
31585 ++{
31586 ++ DECLARE_WAITQUEUE(wait, current);
31587 ++ int ret = 0;
31588 ++
31589 ++ add_wait_queue(&vxi->vx_wait, &wait);
31590 ++ set_current_state(TASK_INTERRUPTIBLE);
31591 ++
31592 ++wait:
31593 ++ if (vx_info_state(vxi,
31594 ++ VXS_SHUTDOWN | VXS_HASHED | VXS_HELPER) == VXS_SHUTDOWN)
31595 ++ goto out;
31596 ++ if (signal_pending(current)) {
31597 ++ ret = -ERESTARTSYS;
31598 ++ goto out;
31599 ++ }
31600 ++ schedule();
31601 ++ goto wait;
31602 ++
31603 ++out:
31604 ++ set_current_state(TASK_RUNNING);
31605 ++ remove_wait_queue(&vxi->vx_wait, &wait);
31606 ++ return ret;
31607 ++}
31608 ++
31609 ++
31610 ++
31611 ++int vc_wait_exit(struct vx_info *vxi, void __user *data)
31612 ++{
31613 ++ struct vcmd_wait_exit_v0 vc_data;
31614 ++ int ret;
31615 ++
31616 ++ ret = __wait_exit(vxi);
31617 ++ vc_data.reboot_cmd = vxi->reboot_cmd;
31618 ++ vc_data.exit_code = vxi->exit_code;
31619 ++
31620 ++ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
31621 ++ ret = -EFAULT;
31622 ++ return ret;
31623 ++}
31624 ++
31625 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/space.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/space.c
31626 +--- linux-2.6.22.19/kernel/vserver/space.c 1970-01-01 01:00:00 +0100
31627 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/space.c 2007-08-15 23:39:13 +0200
31628 +@@ -0,0 +1,277 @@
31629 ++/*
31630 ++ * linux/kernel/vserver/space.c
31631 ++ *
31632 ++ * Virtual Server: Context Space Support
31633 ++ *
31634 ++ * Copyright (C) 2003-2007 Herbert Pötzl
31635 ++ *
31636 ++ * V0.01 broken out from context.c 0.07
31637 ++ * V0.02 added task locking for namespace
31638 ++ * V0.03 broken out vx_enter_namespace
31639 ++ * V0.04 added *space support and commands
31640 ++ *
31641 ++ */
31642 ++
31643 ++#include <linux/utsname.h>
31644 ++#include <linux/nsproxy.h>
31645 ++#include <linux/err.h>
31646 ++#include <asm/uaccess.h>
31647 ++
31648 ++#include <linux/vs_context.h>
31649 ++#include <linux/vserver/space.h>
31650 ++#include <linux/vserver/space_cmd.h>
31651 ++
31652 ++
31653 ++atomic_t vs_global_nsproxy = ATOMIC_INIT(0);
31654 ++atomic_t vs_global_fs = ATOMIC_INIT(0);
31655 ++atomic_t vs_global_mnt_ns = ATOMIC_INIT(0);
31656 ++atomic_t vs_global_uts_ns = ATOMIC_INIT(0);
31657 ++atomic_t vs_global_ipc_ns = ATOMIC_INIT(0);
31658 ++
31659 ++
31660 ++/* namespace functions */
31661 ++
31662 ++#include <linux/mnt_namespace.h>
31663 ++
31664 ++const struct vcmd_space_mask space_mask = {
31665 ++ .mask = CLONE_NEWNS |
31666 ++ CLONE_NEWUTS |
31667 ++ CLONE_NEWIPC |
31668 ++ CLONE_FS
31669 ++};
31670 ++
31671 ++
31672 ++/*
31673 ++ * build a new nsproxy mix
31674 ++ * assumes that both proxies are 'const'
31675 ++ * does not touch nsproxy refcounts
31676 ++ * will hold a reference on the result.
31677 ++ */
31678 ++
31679 ++struct nsproxy *vs_mix_nsproxy(struct nsproxy *old_nsproxy,
31680 ++ struct nsproxy *new_nsproxy, unsigned long mask)
31681 ++{
31682 ++ struct mnt_namespace *old_ns;
31683 ++ struct uts_namespace *old_uts;
31684 ++ struct ipc_namespace *old_ipc;
31685 ++ struct nsproxy *nsproxy;
31686 ++
31687 ++ nsproxy = copy_nsproxy(old_nsproxy);
31688 ++ if (!nsproxy)
31689 ++ goto out;
31690 ++
31691 ++ if (mask & CLONE_NEWNS) {
31692 ++ old_ns = nsproxy->mnt_ns;
31693 ++ nsproxy->mnt_ns = new_nsproxy->mnt_ns;
31694 ++ if (nsproxy->mnt_ns)
31695 ++ get_mnt_ns(nsproxy->mnt_ns);
31696 ++ } else
31697 ++ old_ns = NULL;
31698 ++
31699 ++ if (mask & CLONE_NEWUTS) {
31700 ++ old_uts = nsproxy->uts_ns;
31701 ++ nsproxy->uts_ns = new_nsproxy->uts_ns;
31702 ++ if (nsproxy->uts_ns)
31703 ++ get_uts_ns(nsproxy->uts_ns);
31704 ++ } else
31705 ++ old_uts = NULL;
31706 ++
31707 ++ if (mask & CLONE_NEWIPC) {
31708 ++ old_ipc = nsproxy->ipc_ns;
31709 ++ nsproxy->ipc_ns = new_nsproxy->ipc_ns;
31710 ++ if (nsproxy->ipc_ns)
31711 ++ get_ipc_ns(nsproxy->ipc_ns);
31712 ++ } else
31713 ++ old_ipc = NULL;
31714 ++
31715 ++ if (old_ns)
31716 ++ put_mnt_ns(old_ns);
31717 ++ if (old_uts)
31718 ++ put_uts_ns(old_uts);
31719 ++ if (old_ipc)
31720 ++ put_ipc_ns(old_ipc);
31721 ++out:
31722 ++ return nsproxy;
31723 ++}
31724 ++
31725 ++
31726 ++/*
31727 ++ * merge two nsproxy structs into a new one.
31728 ++ * will hold a reference on the result.
31729 ++ */
31730 ++
31731 ++static inline
31732 ++struct nsproxy *__vs_merge_nsproxy(struct nsproxy *old,
31733 ++ struct nsproxy *proxy, unsigned long mask)
31734 ++{
31735 ++ struct nsproxy null_proxy = { .mnt_ns = NULL };
31736 ++
31737 ++ if (!proxy)
31738 ++ return NULL;
31739 ++
31740 ++ if (mask) {
31741 ++ /* vs_mix_nsproxy returns with reference */
31742 ++ return vs_mix_nsproxy(old ? old : &null_proxy,
31743 ++ proxy, mask);
31744 ++ }
31745 ++ get_nsproxy(proxy);
31746 ++ return proxy;
31747 ++}
31748 ++
31749 ++/*
31750 ++ * merge two fs structs into a new one.
31751 ++ * will take a reference on the result.
31752 ++ */
31753 ++
31754 ++static inline
31755 ++struct fs_struct *__vs_merge_fs(struct fs_struct *old,
31756 ++ struct fs_struct *fs, unsigned long mask)
31757 ++{
31758 ++ if (!(mask & CLONE_FS)) {
31759 ++ if (old)
31760 ++ atomic_inc(&old->count);
31761 ++ return old;
31762 ++ }
31763 ++
31764 ++ if (!fs)
31765 ++ return NULL;
31766 ++
31767 ++ return copy_fs_struct(fs);
31768 ++}
31769 ++
31770 ++
31771 ++int vx_enter_space(struct vx_info *vxi, unsigned long mask)
31772 ++{
31773 ++ struct nsproxy *proxy, *proxy_cur, *proxy_new;
31774 ++ struct fs_struct *fs, *fs_cur, *fs_new;
31775 ++ int ret;
31776 ++
31777 ++ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
31778 ++ return -EACCES;
31779 ++
31780 ++ if (!mask)
31781 ++ mask = vxi->vx_nsmask;
31782 ++
31783 ++ if ((mask & vxi->vx_nsmask) != mask)
31784 ++ return -EINVAL;
31785 ++
31786 ++ proxy = vxi->vx_nsproxy;
31787 ++ fs = vxi->vx_fs;
31788 ++
31789 ++ task_lock(current);
31790 ++ fs_cur = current->fs;
31791 ++ atomic_inc(&fs_cur->count);
31792 ++ proxy_cur = current->nsproxy;
31793 ++ get_nsproxy(proxy_cur);
31794 ++ task_unlock(current);
31795 ++
31796 ++ fs_new = __vs_merge_fs(fs_cur, fs, mask);
31797 ++ if (IS_ERR(fs_new)) {
31798 ++ ret = PTR_ERR(fs_new);
31799 ++ goto out_put;
31800 ++ }
31801 ++
31802 ++ proxy_new = __vs_merge_nsproxy(proxy_cur, proxy, mask);
31803 ++ if (IS_ERR(proxy_new)) {
31804 ++ ret = PTR_ERR(proxy_new);
31805 ++ goto out_put_fs;
31806 ++ }
31807 ++
31808 ++ fs_new = xchg(&current->fs, fs_new);
31809 ++ proxy_new = xchg(&current->nsproxy, proxy_new);
31810 ++ ret = 0;
31811 ++
31812 ++ if (proxy_new)
31813 ++ put_nsproxy(proxy_new);
31814 ++out_put_fs:
31815 ++ if (fs_new)
31816 ++ put_fs_struct(fs_new);
31817 ++out_put:
31818 ++ if (proxy_cur)
31819 ++ put_nsproxy(proxy_cur);
31820 ++ if (fs_cur)
31821 ++ put_fs_struct(fs_cur);
31822 ++ return ret;
31823 ++}
31824 ++
31825 ++
31826 ++int vx_set_space(struct vx_info *vxi, unsigned long mask)
31827 ++{
31828 ++ struct nsproxy *proxy_vxi, *proxy_cur, *proxy_new;
31829 ++ struct fs_struct *fs_vxi, *fs_cur, *fs_new;
31830 ++ int ret;
31831 ++
31832 ++ if (!mask)
31833 ++ mask = space_mask.mask;
31834 ++
31835 ++ if ((mask & space_mask.mask) != mask)
31836 ++ return -EINVAL;
31837 ++
31838 ++ proxy_vxi = vxi->vx_nsproxy;
31839 ++ fs_vxi = vxi->vx_fs;
31840 ++
31841 ++ task_lock(current);
31842 ++ fs_cur = current->fs;
31843 ++ atomic_inc(&fs_cur->count);
31844 ++ proxy_cur = current->nsproxy;
31845 ++ get_nsproxy(proxy_cur);
31846 ++ task_unlock(current);
31847 ++
31848 ++ fs_new = __vs_merge_fs(fs_vxi, fs_cur, mask);
31849 ++ if (IS_ERR(fs_new)) {
31850 ++ ret = PTR_ERR(fs_new);
31851 ++ goto out_put;
31852 ++ }
31853 ++
31854 ++ proxy_new = __vs_merge_nsproxy(proxy_vxi, proxy_cur, mask);
31855 ++ if (IS_ERR(proxy_new)) {
31856 ++ ret = PTR_ERR(proxy_new);
31857 ++ goto out_put_fs;
31858 ++ }
31859 ++
31860 ++ fs_new = xchg(&vxi->vx_fs, fs_new);
31861 ++ proxy_new = xchg(&vxi->vx_nsproxy, proxy_new);
31862 ++ vxi->vx_nsmask |= mask;
31863 ++ ret = 0;
31864 ++
31865 ++ if (proxy_new)
31866 ++ put_nsproxy(proxy_new);
31867 ++out_put_fs:
31868 ++ if (fs_new)
31869 ++ put_fs_struct(fs_new);
31870 ++out_put:
31871 ++ if (proxy_cur)
31872 ++ put_nsproxy(proxy_cur);
31873 ++ if (fs_cur)
31874 ++ put_fs_struct(fs_cur);
31875 ++ return ret;
31876 ++}
31877 ++
31878 ++
31879 ++int vc_enter_space(struct vx_info *vxi, void __user *data)
31880 ++{
31881 ++ struct vcmd_space_mask vc_data = { .mask = 0 };
31882 ++
31883 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
31884 ++ return -EFAULT;
31885 ++
31886 ++ return vx_enter_space(vxi, vc_data.mask);
31887 ++}
31888 ++
31889 ++int vc_set_space(struct vx_info *vxi, void __user *data)
31890 ++{
31891 ++ struct vcmd_space_mask vc_data = { .mask = 0 };
31892 ++
31893 ++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
31894 ++ return -EFAULT;
31895 ++
31896 ++ return vx_set_space(vxi, vc_data.mask);
31897 ++}
31898 ++
31899 ++int vc_get_space_mask(struct vx_info *vxi, void __user *data)
31900 ++{
31901 ++ if (copy_to_user(data, &space_mask, sizeof(space_mask)))
31902 ++ return -EFAULT;
31903 ++ return 0;
31904 ++}
31905 ++
31906 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/switch.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/switch.c
31907 +--- linux-2.6.22.19/kernel/vserver/switch.c 1970-01-01 01:00:00 +0100
31908 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/switch.c 2007-10-25 17:05:55 +0200
31909 +@@ -0,0 +1,529 @@
31910 ++/*
31911 ++ * linux/kernel/vserver/switch.c
31912 ++ *
31913 ++ * Virtual Server: Syscall Switch
31914 ++ *
31915 ++ * Copyright (C) 2003-2007 Herbert Pötzl
31916 ++ *
31917 ++ * V0.01 syscall switch
31918 ++ * V0.02 added signal to context
31919 ++ * V0.03 added rlimit functions
31920 ++ * V0.04 added iattr, task/xid functions
31921 ++ * V0.05 added debug/history stuff
31922 ++ * V0.06 added compat32 layer
31923 ++ * V0.07 vcmd args and perms
31924 ++ * V0.08 added status commands
31925 ++ * V0.09 added tag commands
31926 ++ * V0.10 added oom bias
31927 ++ * V0.11 added device commands
31928 ++ *
31929 ++ */
31930 ++
31931 ++#include <linux/vs_context.h>
31932 ++#include <linux/vs_network.h>
31933 ++#include <linux/vserver/switch.h>
31934 ++
31935 ++#include "vci_config.h"
31936 ++
31937 ++
31938 ++static inline
31939 ++int vc_get_version(uint32_t id)
31940 ++{
31941 ++ return VCI_VERSION;
31942 ++}
31943 ++
31944 ++static inline
31945 ++int vc_get_vci(uint32_t id)
31946 ++{
31947 ++ return vci_kernel_config();
31948 ++}
31949 ++
31950 ++#include <linux/vserver/context_cmd.h>
31951 ++#include <linux/vserver/cvirt_cmd.h>
31952 ++#include <linux/vserver/cacct_cmd.h>
31953 ++#include <linux/vserver/limit_cmd.h>
31954 ++#include <linux/vserver/network_cmd.h>
31955 ++#include <linux/vserver/sched_cmd.h>
31956 ++#include <linux/vserver/debug_cmd.h>
31957 ++#include <linux/vserver/inode_cmd.h>
31958 ++#include <linux/vserver/dlimit_cmd.h>
31959 ++#include <linux/vserver/signal_cmd.h>
31960 ++#include <linux/vserver/space_cmd.h>
31961 ++#include <linux/vserver/tag_cmd.h>
31962 ++#include <linux/vserver/device_cmd.h>
31963 ++
31964 ++#include <linux/vserver/inode.h>
31965 ++#include <linux/vserver/dlimit.h>
31966 ++
31967 ++
31968 ++#ifdef CONFIG_COMPAT
31969 ++#define __COMPAT(name, id, data, compat) \
31970 ++ (compat) ? name ## _x32(id, data) : name(id, data)
31971 ++#define __COMPAT_NO_ID(name, data, compat) \
31972 ++ (compat) ? name ## _x32(data) : name(data)
31973 ++#else
31974 ++#define __COMPAT(name, id, data, compat) \
31975 ++ name(id, data)
31976 ++#define __COMPAT_NO_ID(name, data, compat) \
31977 ++ name(data)
31978 ++#endif
31979 ++
31980 ++
31981 ++static inline
31982 ++long do_vcmd(uint32_t cmd, uint32_t id,
31983 ++ struct vx_info *vxi, struct nx_info *nxi,
31984 ++ void __user *data, int compat)
31985 ++{
31986 ++ switch (cmd) {
31987 ++
31988 ++ case VCMD_get_version:
31989 ++ return vc_get_version(id);
31990 ++ case VCMD_get_vci:
31991 ++ return vc_get_vci(id);
31992 ++
31993 ++ case VCMD_task_xid:
31994 ++ return vc_task_xid(id);
31995 ++ case VCMD_vx_info:
31996 ++ return vc_vx_info(vxi, data);
31997 ++
31998 ++ case VCMD_task_nid:
31999 ++ return vc_task_nid(id);
32000 ++ case VCMD_nx_info:
32001 ++ return vc_nx_info(nxi, data);
32002 ++
32003 ++ case VCMD_task_tag:
32004 ++ return vc_task_tag(id);
32005 ++
32006 ++ /* this is version 1 */
32007 ++ case VCMD_set_space:
32008 ++ return vc_set_space(vxi, data);
32009 ++
32010 ++ case VCMD_get_space_mask:
32011 ++ return vc_get_space_mask(vxi, data);
32012 ++
32013 ++#ifdef CONFIG_IA32_EMULATION
32014 ++ case VCMD_get_rlimit:
32015 ++ return __COMPAT(vc_get_rlimit, vxi, data, compat);
32016 ++ case VCMD_set_rlimit:
32017 ++ return __COMPAT(vc_set_rlimit, vxi, data, compat);
32018 ++#else
32019 ++ case VCMD_get_rlimit:
32020 ++ return vc_get_rlimit(vxi, data);
32021 ++ case VCMD_set_rlimit:
32022 ++ return vc_set_rlimit(vxi, data);
32023 ++#endif
32024 ++ case VCMD_get_rlimit_mask:
32025 ++ return vc_get_rlimit_mask(id, data);
32026 ++ case VCMD_reset_minmax:
32027 ++ return vc_reset_minmax(vxi, data);
32028 ++
32029 ++ case VCMD_get_vhi_name:
32030 ++ return vc_get_vhi_name(vxi, data);
32031 ++ case VCMD_set_vhi_name:
32032 ++ return vc_set_vhi_name(vxi, data);
32033 ++
32034 ++ case VCMD_ctx_stat:
32035 ++ return vc_ctx_stat(vxi, data);
32036 ++ case VCMD_virt_stat:
32037 ++ return vc_virt_stat(vxi, data);
32038 ++ case VCMD_sock_stat:
32039 ++ return vc_sock_stat(vxi, data);
32040 ++ case VCMD_rlimit_stat:
32041 ++ return vc_rlimit_stat(vxi, data);
32042 ++
32043 ++ case VCMD_set_cflags:
32044 ++ return vc_set_cflags(vxi, data);
32045 ++ case VCMD_get_cflags:
32046 ++ return vc_get_cflags(vxi, data);
32047 ++
32048 ++ /* this is version 1 */
32049 ++ case VCMD_set_ccaps:
32050 ++ return vc_set_ccaps(vxi, data);
32051 ++ /* this is version 1 */
32052 ++ case VCMD_get_ccaps:
32053 ++ return vc_get_ccaps(vxi, data);
32054 ++ case VCMD_set_bcaps:
32055 ++ return vc_set_bcaps(vxi, data);
32056 ++ case VCMD_get_bcaps:
32057 ++ return vc_get_bcaps(vxi, data);
32058 ++
32059 ++ case VCMD_set_badness:
32060 ++ return vc_set_badness(vxi, data);
32061 ++ case VCMD_get_badness:
32062 ++ return vc_get_badness(vxi, data);
32063 ++
32064 ++ case VCMD_set_nflags:
32065 ++ return vc_set_nflags(nxi, data);
32066 ++ case VCMD_get_nflags:
32067 ++ return vc_get_nflags(nxi, data);
32068 ++
32069 ++ case VCMD_set_ncaps:
32070 ++ return vc_set_ncaps(nxi, data);
32071 ++ case VCMD_get_ncaps:
32072 ++ return vc_get_ncaps(nxi, data);
32073 ++
32074 ++ case VCMD_set_sched_v4:
32075 ++ return vc_set_sched_v4(vxi, data);
32076 ++ /* this is version 5 */
32077 ++ case VCMD_set_sched:
32078 ++ return vc_set_sched(vxi, data);
32079 ++ case VCMD_get_sched:
32080 ++ return vc_get_sched(vxi, data);
32081 ++ case VCMD_sched_info:
32082 ++ return vc_sched_info(vxi, data);
32083 ++
32084 ++ case VCMD_add_dlimit:
32085 ++ return __COMPAT(vc_add_dlimit, id, data, compat);
32086 ++ case VCMD_rem_dlimit:
32087 ++ return __COMPAT(vc_rem_dlimit, id, data, compat);
32088 ++ case VCMD_set_dlimit:
32089 ++ return __COMPAT(vc_set_dlimit, id, data, compat);
32090 ++ case VCMD_get_dlimit:
32091 ++ return __COMPAT(vc_get_dlimit, id, data, compat);
32092 ++
32093 ++ case VCMD_ctx_kill:
32094 ++ return vc_ctx_kill(vxi, data);
32095 ++
32096 ++ case VCMD_wait_exit:
32097 ++ return vc_wait_exit(vxi, data);
32098 ++
32099 ++ case VCMD_get_iattr:
32100 ++ return __COMPAT_NO_ID(vc_get_iattr, data, compat);
32101 ++ case VCMD_set_iattr:
32102 ++ return __COMPAT_NO_ID(vc_set_iattr, data, compat);
32103 ++
32104 ++ case VCMD_fget_iattr:
32105 ++ return vc_fget_iattr(id, data);
32106 ++ case VCMD_fset_iattr:
32107 ++ return vc_fset_iattr(id, data);
32108 ++
32109 ++ case VCMD_enter_space_v0:
32110 ++ return vc_enter_space(vxi, NULL);
32111 ++ /* this is version 1 */
32112 ++ case VCMD_enter_space:
32113 ++ return vc_enter_space(vxi, data);
32114 ++
32115 ++ case VCMD_ctx_create_v0:
32116 ++ return vc_ctx_create(id, NULL);
32117 ++ case VCMD_ctx_create:
32118 ++ return vc_ctx_create(id, data);
32119 ++ case VCMD_ctx_migrate_v0:
32120 ++ return vc_ctx_migrate(vxi, NULL);
32121 ++ case VCMD_ctx_migrate:
32122 ++ return vc_ctx_migrate(vxi, data);
32123 ++
32124 ++ case VCMD_net_create_v0:
32125 ++ return vc_net_create(id, NULL);
32126 ++ case VCMD_net_create:
32127 ++ return vc_net_create(id, data);
32128 ++ case VCMD_net_migrate:
32129 ++ return vc_net_migrate(nxi, data);
32130 ++
32131 ++ case VCMD_tag_migrate:
32132 ++ return vc_tag_migrate(id);
32133 ++
32134 ++ case VCMD_net_add:
32135 ++ return vc_net_add(nxi, data);
32136 ++ case VCMD_net_remove:
32137 ++ return vc_net_remove(nxi, data);
32138 ++
32139 ++ case VCMD_net_add_ipv4:
32140 ++ return vc_net_add_ipv4(nxi, data);
32141 ++ case VCMD_net_remove_ipv4:
32142 ++ return vc_net_remove_ipv4(nxi, data);
32143 ++#ifdef CONFIG_IPV6
32144 ++ case VCMD_net_add_ipv6:
32145 ++ return vc_net_add_ipv6(nxi, data);
32146 ++ case VCMD_net_remove_ipv6:
32147 ++ return vc_net_remove_ipv6(nxi, data);
32148 ++#endif
32149 ++/* case VCMD_add_match_ipv4:
32150 ++ return vc_add_match_ipv4(nxi, data);
32151 ++ case VCMD_get_match_ipv4:
32152 ++ return vc_get_match_ipv4(nxi, data);
32153 ++#ifdef CONFIG_IPV6
32154 ++ case VCMD_add_match_ipv6:
32155 ++ return vc_add_match_ipv6(nxi, data);
32156 ++ case VCMD_get_match_ipv6:
32157 ++ return vc_get_match_ipv6(nxi, data);
32158 ++#endif */
32159 ++
32160 ++#ifdef CONFIG_VSERVER_DEVICE
32161 ++ case VCMD_set_mapping:
32162 ++ return __COMPAT(vc_set_mapping, vxi, data, compat);
32163 ++ case VCMD_unset_mapping:
32164 ++ return __COMPAT(vc_unset_mapping, vxi, data, compat);
32165 ++#endif
32166 ++#ifdef CONFIG_VSERVER_HISTORY
32167 ++ case VCMD_dump_history:
32168 ++ return vc_dump_history(id);
32169 ++ case VCMD_read_history:
32170 ++ return __COMPAT(vc_read_history, id, data, compat);
32171 ++#endif
32172 ++#ifdef CONFIG_VSERVER_MONITOR
32173 ++ case VCMD_read_monitor:
32174 ++ return __COMPAT(vc_read_monitor, id, data, compat);
32175 ++#endif
32176 ++ default:
32177 ++ vxwprintk_task(1, "unimplemented VCMD_%02d_%d[%d]",
32178 ++ VC_CATEGORY(cmd), VC_COMMAND(cmd), VC_VERSION(cmd));
32179 ++ }
32180 ++ return -ENOSYS;
32181 ++}
32182 ++
32183 ++
32184 ++#define __VCMD(vcmd, _perm, _args, _flags) \
32185 ++ case VCMD_ ## vcmd: perm = _perm; \
32186 ++ args = _args; flags = _flags; break
32187 ++
32188 ++
32189 ++#define VCA_NONE 0x00
32190 ++#define VCA_VXI 0x01
32191 ++#define VCA_NXI 0x02
32192 ++
32193 ++#define VCF_NONE 0x00
32194 ++#define VCF_INFO 0x01
32195 ++#define VCF_ADMIN 0x02
32196 ++#define VCF_ARES 0x06 /* includes admin */
32197 ++#define VCF_SETUP 0x08
32198 ++
32199 ++#define VCF_ZIDOK 0x10 /* zero id okay */
32200 ++
32201 ++
32202 ++static inline
32203 ++long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
32204 ++{
32205 ++ long ret;
32206 ++ int permit = -1, state = 0;
32207 ++ int perm = -1, args = 0, flags = 0;
32208 ++ struct vx_info *vxi = NULL;
32209 ++ struct nx_info *nxi = NULL;
32210 ++
32211 ++ switch (cmd) {
32212 ++ /* unpriviledged commands */
32213 ++ __VCMD(get_version, 0, VCA_NONE, 0);
32214 ++ __VCMD(get_vci, 0, VCA_NONE, 0);
32215 ++ __VCMD(get_rlimit_mask, 0, VCA_NONE, 0);
32216 ++ __VCMD(get_space_mask, 0, VCA_NONE, 0);
32217 ++
32218 ++ /* info commands */
32219 ++ __VCMD(task_xid, 2, VCA_NONE, 0);
32220 ++ __VCMD(reset_minmax, 2, VCA_VXI, 0);
32221 ++ __VCMD(vx_info, 3, VCA_VXI, VCF_INFO);
32222 ++ __VCMD(get_bcaps, 3, VCA_VXI, VCF_INFO);
32223 ++ __VCMD(get_ccaps, 3, VCA_VXI, VCF_INFO);
32224 ++ __VCMD(get_cflags, 3, VCA_VXI, VCF_INFO);
32225 ++ __VCMD(get_badness, 3, VCA_VXI, VCF_INFO);
32226 ++ __VCMD(get_vhi_name, 3, VCA_VXI, VCF_INFO);
32227 ++ __VCMD(get_rlimit, 3, VCA_VXI, VCF_INFO);
32228 ++
32229 ++ __VCMD(ctx_stat, 3, VCA_VXI, VCF_INFO);
32230 ++ __VCMD(virt_stat, 3, VCA_VXI, VCF_INFO);
32231 ++ __VCMD(sock_stat, 3, VCA_VXI, VCF_INFO);
32232 ++ __VCMD(rlimit_stat, 3, VCA_VXI, VCF_INFO);
32233 ++
32234 ++ __VCMD(task_nid, 2, VCA_NONE, 0);
32235 ++ __VCMD(nx_info, 3, VCA_NXI, VCF_INFO);
32236 ++ __VCMD(get_ncaps, 3, VCA_NXI, VCF_INFO);
32237 ++ __VCMD(get_nflags, 3, VCA_NXI, VCF_INFO);
32238 ++
32239 ++ __VCMD(task_tag, 2, VCA_NONE, 0);
32240 ++
32241 ++ __VCMD(get_iattr, 2, VCA_NONE, 0);
32242 ++ __VCMD(fget_iattr, 2, VCA_NONE, 0);
32243 ++ __VCMD(get_dlimit, 3, VCA_NONE, VCF_INFO);
32244 ++ __VCMD(get_sched, 3, VCA_VXI, VCF_INFO);
32245 ++ __VCMD(sched_info, 3, VCA_VXI, VCF_INFO | VCF_ZIDOK);
32246 ++
32247 ++ /* lower admin commands */
32248 ++ __VCMD(wait_exit, 4, VCA_VXI, VCF_INFO);
32249 ++ __VCMD(ctx_create_v0, 5, VCA_NONE, 0);
32250 ++ __VCMD(ctx_create, 5, VCA_NONE, 0);
32251 ++ __VCMD(ctx_migrate_v0, 5, VCA_VXI, VCF_ADMIN);
32252 ++ __VCMD(ctx_migrate, 5, VCA_VXI, VCF_ADMIN);
32253 ++ __VCMD(enter_space_v0, 5, VCA_VXI, VCF_ADMIN);
32254 ++ __VCMD(enter_space, 5, VCA_VXI, VCF_ADMIN);
32255 ++
32256 ++ __VCMD(net_create_v0, 5, VCA_NONE, 0);
32257 ++ __VCMD(net_create, 5, VCA_NONE, 0);
32258 ++ __VCMD(net_migrate, 5, VCA_NXI, VCF_ADMIN);
32259 ++
32260 ++ __VCMD(tag_migrate, 5, VCA_NONE, VCF_ADMIN);
32261 ++
32262 ++ /* higher admin commands */
32263 ++ __VCMD(ctx_kill, 6, VCA_VXI, VCF_ARES);
32264 ++ __VCMD(set_space, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
32265 ++
32266 ++ __VCMD(set_ccaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
32267 ++ __VCMD(set_bcaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
32268 ++ __VCMD(set_cflags, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
32269 ++ __VCMD(set_badness, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
32270 ++
32271 ++ __VCMD(set_vhi_name, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
32272 ++ __VCMD(set_rlimit, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
32273 ++ __VCMD(set_sched, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
32274 ++ __VCMD(set_sched_v4, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
32275 ++
32276 ++ __VCMD(set_ncaps, 7, VCA_NXI, VCF_ARES | VCF_SETUP);
32277 ++ __VCMD(set_nflags, 7, VCA_NXI, VCF_ARES | VCF_SETUP);
32278 ++ __VCMD(net_add, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
32279 ++ __VCMD(net_remove, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
32280 ++ __VCMD(net_add_ipv4, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
32281 ++ __VCMD(net_remove_ipv4, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
32282 ++#ifdef CONFIG_IPV6
32283 ++ __VCMD(net_add_ipv6, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
32284 ++ __VCMD(net_remove_ipv6, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
32285 ++#endif
32286 ++ __VCMD(set_iattr, 7, VCA_NONE, 0);
32287 ++ __VCMD(fset_iattr, 7, VCA_NONE, 0);
32288 ++ __VCMD(set_dlimit, 7, VCA_NONE, VCF_ARES);
32289 ++ __VCMD(add_dlimit, 8, VCA_NONE, VCF_ARES);
32290 ++ __VCMD(rem_dlimit, 8, VCA_NONE, VCF_ARES);
32291 ++
32292 ++#ifdef CONFIG_VSERVER_DEVICE
32293 ++ __VCMD(set_mapping, 8, VCA_VXI, VCF_ARES|VCF_ZIDOK);
32294 ++ __VCMD(unset_mapping, 8, VCA_VXI, VCF_ARES|VCF_ZIDOK);
32295 ++#endif
32296 ++ /* debug level admin commands */
32297 ++#ifdef CONFIG_VSERVER_HISTORY
32298 ++ __VCMD(dump_history, 9, VCA_NONE, 0);
32299 ++ __VCMD(read_history, 9, VCA_NONE, 0);
32300 ++#endif
32301 ++#ifdef CONFIG_VSERVER_MONITOR
32302 ++ __VCMD(read_monitor, 9, VCA_NONE, 0);
32303 ++#endif
32304 ++
32305 ++ default:
32306 ++ perm = -1;
32307 ++ }
32308 ++
32309 ++ vxdprintk(VXD_CBIT(switch, 0),
32310 ++ "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]",
32311 ++ VC_CATEGORY(cmd), VC_COMMAND(cmd),
32312 ++ VC_VERSION(cmd), id, data, compat,
32313 ++ perm, args, flags);
32314 ++
32315 ++ ret = -ENOSYS;
32316 ++ if (perm < 0)
32317 ++ goto out;
32318 ++
32319 ++ state = 1;
32320 ++ if (!capable(CAP_CONTEXT))
32321 ++ goto out;
32322 ++
32323 ++ state = 2;
32324 ++ /* moved here from the individual commands */
32325 ++ ret = -EPERM;
32326 ++ if ((perm > 1) && !capable(CAP_SYS_ADMIN))
32327 ++ goto out;
32328 ++
32329 ++ state = 3;
32330 ++ /* vcmd involves resource management */
32331 ++ ret = -EPERM;
32332 ++ if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE))
32333 ++ goto out;
32334 ++
32335 ++ state = 4;
32336 ++ /* various legacy exceptions */
32337 ++ switch (cmd) {
32338 ++ /* will go away when spectator is a cap */
32339 ++ case VCMD_ctx_migrate_v0:
32340 ++ case VCMD_ctx_migrate:
32341 ++ if (id == 1) {
32342 ++ current->xid = 1;
32343 ++ ret = 1;
32344 ++ goto out;
32345 ++ }
32346 ++ break;
32347 ++
32348 ++ /* will go away when spectator is a cap */
32349 ++ case VCMD_net_migrate:
32350 ++ if (id == 1) {
32351 ++ current->nid = 1;
32352 ++ ret = 1;
32353 ++ goto out;
32354 ++ }
32355 ++ break;
32356 ++ }
32357 ++
32358 ++ /* vcmds are fine by default */
32359 ++ permit = 1;
32360 ++
32361 ++ /* admin type vcmds require admin ... */
32362 ++ if (flags & VCF_ADMIN)
32363 ++ permit = vx_check(0, VS_ADMIN) ? 1 : 0;
32364 ++
32365 ++ /* ... but setup type vcmds override that */
32366 ++ if (!permit && (flags & VCF_SETUP))
32367 ++ permit = vx_flags(VXF_STATE_SETUP, 0) ? 2 : 0;
32368 ++
32369 ++ state = 5;
32370 ++ ret = -EPERM;
32371 ++ if (!permit)
32372 ++ goto out;
32373 ++
32374 ++ state = 6;
32375 ++ if (!id && (flags & VCF_ZIDOK))
32376 ++ goto skip_id;
32377 ++
32378 ++ ret = -ESRCH;
32379 ++ if (args & VCA_VXI) {
32380 ++ vxi = lookup_vx_info(id);
32381 ++ if (!vxi)
32382 ++ goto out;
32383 ++
32384 ++ if ((flags & VCF_ADMIN) &&
32385 ++ /* special case kill for shutdown */
32386 ++ (cmd != VCMD_ctx_kill) &&
32387 ++ /* can context be administrated? */
32388 ++ !vx_info_flags(vxi, VXF_STATE_ADMIN, 0)) {
32389 ++ ret = -EACCES;
32390 ++ goto out_vxi;
32391 ++ }
32392 ++ }
32393 ++ state = 7;
32394 ++ if (args & VCA_NXI) {
32395 ++ nxi = lookup_nx_info(id);
32396 ++ if (!nxi)
32397 ++ goto out_vxi;
32398 ++
32399 ++ if ((flags & VCF_ADMIN) &&
32400 ++ /* can context be administrated? */
32401 ++ !nx_info_flags(nxi, NXF_STATE_ADMIN, 0)) {
32402 ++ ret = -EACCES;
32403 ++ goto out_nxi;
32404 ++ }
32405 ++ }
32406 ++skip_id:
32407 ++ state = 8;
32408 ++ ret = do_vcmd(cmd, id, vxi, nxi, data, compat);
32409 ++
32410 ++out_nxi:
32411 ++ if ((args & VCA_NXI) && nxi)
32412 ++ put_nx_info(nxi);
32413 ++out_vxi:
32414 ++ if ((args & VCA_VXI) && vxi)
32415 ++ put_vx_info(vxi);
32416 ++out:
32417 ++ vxdprintk(VXD_CBIT(switch, 1),
32418 ++ "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]",
32419 ++ VC_CATEGORY(cmd), VC_COMMAND(cmd),
32420 ++ VC_VERSION(cmd), ret, ret, state, permit);
32421 ++ return ret;
32422 ++}
32423 ++
32424 ++asmlinkage long
32425 ++sys_vserver(uint32_t cmd, uint32_t id, void __user *data)
32426 ++{
32427 ++ return do_vserver(cmd, id, data, 0);
32428 ++}
32429 ++
32430 ++#ifdef CONFIG_COMPAT
32431 ++
32432 ++asmlinkage long
32433 ++sys32_vserver(uint32_t cmd, uint32_t id, void __user *data)
32434 ++{
32435 ++ return do_vserver(cmd, id, data, 1);
32436 ++}
32437 ++
32438 ++#endif /* CONFIG_COMPAT */
32439 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/sysctl.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/sysctl.c
32440 +--- linux-2.6.22.19/kernel/vserver/sysctl.c 1970-01-01 01:00:00 +0100
32441 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/sysctl.c 2007-08-15 23:42:57 +0200
32442 +@@ -0,0 +1,243 @@
32443 ++/*
32444 ++ * kernel/vserver/sysctl.c
32445 ++ *
32446 ++ * Virtual Context Support
32447 ++ *
32448 ++ * Copyright (C) 2004-2007 Herbert Pötzl
32449 ++ *
32450 ++ * V0.01 basic structure
32451 ++ *
32452 ++ */
32453 ++
32454 ++#include <linux/module.h>
32455 ++#include <linux/ctype.h>
32456 ++#include <linux/sysctl.h>
32457 ++#include <linux/parser.h>
32458 ++#include <asm/uaccess.h>
32459 ++
32460 ++
32461 ++#define CTL_VSERVER 4242 /* unused? */
32462 ++
32463 ++enum {
32464 ++ CTL_DEBUG_ERROR = 0,
32465 ++ CTL_DEBUG_SWITCH = 1,
32466 ++ CTL_DEBUG_XID,
32467 ++ CTL_DEBUG_NID,
32468 ++ CTL_DEBUG_TAG,
32469 ++ CTL_DEBUG_NET,
32470 ++ CTL_DEBUG_LIMIT,
32471 ++ CTL_DEBUG_CRES,
32472 ++ CTL_DEBUG_DLIM,
32473 ++ CTL_DEBUG_QUOTA,
32474 ++ CTL_DEBUG_CVIRT,
32475 ++ CTL_DEBUG_SPACE,
32476 ++ CTL_DEBUG_MISC,
32477 ++};
32478 ++
32479 ++
32480 ++unsigned int vx_debug_switch = 0;
32481 ++unsigned int vx_debug_xid = 0;
32482 ++unsigned int vx_debug_nid = 0;
32483 ++unsigned int vx_debug_tag = 0;
32484 ++unsigned int vx_debug_net = 0;
32485 ++unsigned int vx_debug_limit = 0;
32486 ++unsigned int vx_debug_cres = 0;
32487 ++unsigned int vx_debug_dlim = 0;
32488 ++unsigned int vx_debug_quota = 0;
32489 ++unsigned int vx_debug_cvirt = 0;
32490 ++unsigned int vx_debug_space = 0;
32491 ++unsigned int vx_debug_misc = 0;
32492 ++
32493 ++
32494 ++static struct ctl_table_header *vserver_table_header;
32495 ++static ctl_table vserver_table[];
32496 ++
32497 ++
32498 ++void vserver_register_sysctl(void)
32499 ++{
32500 ++ if (!vserver_table_header) {
32501 ++ vserver_table_header = register_sysctl_table(vserver_table);
32502 ++ }
32503 ++
32504 ++}
32505 ++
32506 ++void vserver_unregister_sysctl(void)
32507 ++{
32508 ++ if (vserver_table_header) {
32509 ++ unregister_sysctl_table(vserver_table_header);
32510 ++ vserver_table_header = NULL;
32511 ++ }
32512 ++}
32513 ++
32514 ++
32515 ++static int proc_dodebug(ctl_table *table, int write,
32516 ++ struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
32517 ++{
32518 ++ char tmpbuf[20], *p, c;
32519 ++ unsigned int value;
32520 ++ size_t left, len;
32521 ++
32522 ++ if ((*ppos && !write) || !*lenp) {
32523 ++ *lenp = 0;
32524 ++ return 0;
32525 ++ }
32526 ++
32527 ++ left = *lenp;
32528 ++
32529 ++ if (write) {
32530 ++ if (!access_ok(VERIFY_READ, buffer, left))
32531 ++ return -EFAULT;
32532 ++ p = (char *)buffer;
32533 ++ while (left && __get_user(c, p) >= 0 && isspace(c))
32534 ++ left--, p++;
32535 ++ if (!left)
32536 ++ goto done;
32537 ++
32538 ++ if (left > sizeof(tmpbuf) - 1)
32539 ++ return -EINVAL;
32540 ++ if (copy_from_user(tmpbuf, p, left))
32541 ++ return -EFAULT;
32542 ++ tmpbuf[left] = '\0';
32543 ++
32544 ++ for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
32545 ++ value = 10 * value + (*p - '0');
32546 ++ if (*p && !isspace(*p))
32547 ++ return -EINVAL;
32548 ++ while (left && isspace(*p))
32549 ++ left--, p++;
32550 ++ *(unsigned int *)table->data = value;
32551 ++ } else {
32552 ++ if (!access_ok(VERIFY_WRITE, buffer, left))
32553 ++ return -EFAULT;
32554 ++ len = sprintf(tmpbuf, "%d", *(unsigned int *)table->data);
32555 ++ if (len > left)
32556 ++ len = left;
32557 ++ if (__copy_to_user(buffer, tmpbuf, len))
32558 ++ return -EFAULT;
32559 ++ if ((left -= len) > 0) {
32560 ++ if (put_user('\n', (char *)buffer + len))
32561 ++ return -EFAULT;
32562 ++ left--;
32563 ++ }
32564 ++ }
32565 ++
32566 ++done:
32567 ++ *lenp -= left;
32568 ++ *ppos += *lenp;
32569 ++ return 0;
32570 ++}
32571 ++
32572 ++
32573 ++#define CTL_ENTRY(ctl, name) \
32574 ++ { \
32575 ++ .ctl_name = ctl, \
32576 ++ .procname = #name, \
32577 ++ .data = &vx_ ## name, \
32578 ++ .maxlen = sizeof(int), \
32579 ++ .mode = 0644, \
32580 ++ .proc_handler = &proc_dodebug \
32581 ++ }
32582 ++
32583 ++static ctl_table debug_table[] = {
32584 ++ CTL_ENTRY(CTL_DEBUG_SWITCH, debug_switch),
32585 ++ CTL_ENTRY(CTL_DEBUG_XID, debug_xid),
32586 ++ CTL_ENTRY(CTL_DEBUG_NID, debug_nid),
32587 ++ CTL_ENTRY(CTL_DEBUG_TAG, debug_tag),
32588 ++ CTL_ENTRY(CTL_DEBUG_NET, debug_net),
32589 ++ CTL_ENTRY(CTL_DEBUG_LIMIT, debug_limit),
32590 ++ CTL_ENTRY(CTL_DEBUG_CRES, debug_cres),
32591 ++ CTL_ENTRY(CTL_DEBUG_DLIM, debug_dlim),
32592 ++ CTL_ENTRY(CTL_DEBUG_QUOTA, debug_quota),
32593 ++ CTL_ENTRY(CTL_DEBUG_CVIRT, debug_cvirt),
32594 ++ CTL_ENTRY(CTL_DEBUG_SPACE, debug_space),
32595 ++ CTL_ENTRY(CTL_DEBUG_MISC, debug_misc),
32596 ++ { .ctl_name = 0 }
32597 ++};
32598 ++
32599 ++static ctl_table vserver_table[] = {
32600 ++ {
32601 ++ .ctl_name = CTL_VSERVER,
32602 ++ .procname = "vserver",
32603 ++ .mode = 0555,
32604 ++ .child = debug_table
32605 ++ },
32606 ++ { .ctl_name = 0 }
32607 ++};
32608 ++
32609 ++
32610 ++static match_table_t tokens = {
32611 ++ { CTL_DEBUG_SWITCH, "switch=%x" },
32612 ++ { CTL_DEBUG_XID, "xid=%x" },
32613 ++ { CTL_DEBUG_NID, "nid=%x" },
32614 ++ { CTL_DEBUG_TAG, "tag=%x" },
32615 ++ { CTL_DEBUG_NET, "net=%x" },
32616 ++ { CTL_DEBUG_LIMIT, "limit=%x" },
32617 ++ { CTL_DEBUG_CRES, "cres=%x" },
32618 ++ { CTL_DEBUG_DLIM, "dlim=%x" },
32619 ++ { CTL_DEBUG_QUOTA, "quota=%x" },
32620 ++ { CTL_DEBUG_CVIRT, "cvirt=%x" },
32621 ++ { CTL_DEBUG_SPACE, "space=%x" },
32622 ++ { CTL_DEBUG_MISC, "misc=%x" },
32623 ++ { CTL_DEBUG_ERROR, NULL }
32624 ++};
32625 ++
32626 ++#define HANDLE_CASE(id, name, val) \
32627 ++ case CTL_DEBUG_ ## id: \
32628 ++ vx_debug_ ## name = val; \
32629 ++ printk("vs_debug_" #name "=0x%x\n", val); \
32630 ++ break
32631 ++
32632 ++
32633 ++static int __init vs_debug_setup(char *str)
32634 ++{
32635 ++ char *p;
32636 ++ int token;
32637 ++
32638 ++ printk("vs_debug_setup(%s)\n", str);
32639 ++ while ((p = strsep(&str, ",")) != NULL) {
32640 ++ substring_t args[MAX_OPT_ARGS];
32641 ++ unsigned int value;
32642 ++
32643 ++ if (!*p)
32644 ++ continue;
32645 ++
32646 ++ token = match_token(p, tokens, args);
32647 ++ value = (token > 0) ? simple_strtoul(args[0].from, NULL, 0) : 0;
32648 ++
32649 ++ switch (token) {
32650 ++ HANDLE_CASE(SWITCH, switch, value);
32651 ++ HANDLE_CASE(XID, xid, value);
32652 ++ HANDLE_CASE(NID, nid, value);
32653 ++ HANDLE_CASE(TAG, tag, value);
32654 ++ HANDLE_CASE(NET, net, value);
32655 ++ HANDLE_CASE(LIMIT, limit, value);
32656 ++ HANDLE_CASE(CRES, cres, value);
32657 ++ HANDLE_CASE(DLIM, dlim, value);
32658 ++ HANDLE_CASE(QUOTA, quota, value);
32659 ++ HANDLE_CASE(CVIRT, cvirt, value);
32660 ++ HANDLE_CASE(SPACE, space, value);
32661 ++ HANDLE_CASE(MISC, misc, value);
32662 ++ default:
32663 ++ return -EINVAL;
32664 ++ break;
32665 ++ }
32666 ++ }
32667 ++ return 1;
32668 ++}
32669 ++
32670 ++__setup("vsdebug=", vs_debug_setup);
32671 ++
32672 ++
32673 ++
32674 ++EXPORT_SYMBOL_GPL(vx_debug_switch);
32675 ++EXPORT_SYMBOL_GPL(vx_debug_xid);
32676 ++EXPORT_SYMBOL_GPL(vx_debug_nid);
32677 ++EXPORT_SYMBOL_GPL(vx_debug_net);
32678 ++EXPORT_SYMBOL_GPL(vx_debug_limit);
32679 ++EXPORT_SYMBOL_GPL(vx_debug_cres);
32680 ++EXPORT_SYMBOL_GPL(vx_debug_dlim);
32681 ++EXPORT_SYMBOL_GPL(vx_debug_quota);
32682 ++EXPORT_SYMBOL_GPL(vx_debug_cvirt);
32683 ++EXPORT_SYMBOL_GPL(vx_debug_space);
32684 ++EXPORT_SYMBOL_GPL(vx_debug_misc);
32685 ++
32686 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/tag.c linux-2.6.22.19-vs2.3.0.34/kernel/vserver/tag.c
32687 +--- linux-2.6.22.19/kernel/vserver/tag.c 1970-01-01 01:00:00 +0100
32688 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/tag.c 2007-10-05 14:54:36 +0200
32689 +@@ -0,0 +1,62 @@
32690 ++/*
32691 ++ * linux/kernel/vserver/tag.c
32692 ++ *
32693 ++ * Virtual Server: Shallow Tag Space
32694 ++ *
32695 ++ * Copyright (C) 2007 Herbert Pötzl
32696 ++ *
32697 ++ * V0.01 basic implementation
32698 ++ *
32699 ++ */
32700 ++
32701 ++#include <linux/sched.h>
32702 ++#include <linux/vserver/debug.h>
32703 ++#include <linux/vs_tag.h>
32704 ++
32705 ++#include <linux/vserver/tag_cmd.h>
32706 ++
32707 ++
32708 ++int dx_migrate_task(struct task_struct *p, tag_t tag)
32709 ++{
32710 ++ if (!p)
32711 ++ BUG();
32712 ++
32713 ++ vxdprintk(VXD_CBIT(tag, 5),
32714 ++ "dx_migrate_task(%p[#%d],#%d)", p, p->tag, tag);
32715 ++
32716 ++ task_lock(p);
32717 ++ p->tag = tag;
32718 ++ task_unlock(p);
32719 ++
32720 ++ vxdprintk(VXD_CBIT(tag, 5),
32721 ++ "moved task %p into [#%d]", p, tag);
32722 ++ return 0;
32723 ++}
32724 ++
32725 ++/* vserver syscall commands below here */
32726 ++
32727 ++/* taks xid and vx_info functions */
32728 ++
32729 ++
32730 ++int vc_task_tag(uint32_t id)
32731 ++{
32732 ++ tag_t tag;
32733 ++
32734 ++ if (id) {
32735 ++ struct task_struct *tsk;
32736 ++ read_lock(&tasklist_lock);
32737 ++ tsk = find_task_by_real_pid(id);
32738 ++ tag = (tsk) ? tsk->tag : -ESRCH;
32739 ++ read_unlock(&tasklist_lock);
32740 ++ } else
32741 ++ tag = dx_current_tag();
32742 ++ return tag;
32743 ++}
32744 ++
32745 ++
32746 ++int vc_tag_migrate(uint32_t tag)
32747 ++{
32748 ++ return dx_migrate_task(current, tag & 0xFFFF);
32749 ++}
32750 ++
32751 ++
32752 +diff -NurpP --minimal linux-2.6.22.19/kernel/vserver/vci_config.h linux-2.6.22.19-vs2.3.0.34/kernel/vserver/vci_config.h
32753 +--- linux-2.6.22.19/kernel/vserver/vci_config.h 1970-01-01 01:00:00 +0100
32754 ++++ linux-2.6.22.19-vs2.3.0.34/kernel/vserver/vci_config.h 2007-08-16 03:56:22 +0200
32755 +@@ -0,0 +1,81 @@
32756 ++
32757 ++/* interface version */
32758 ++
32759 ++#define VCI_VERSION 0x00020302
32760 ++
32761 ++
32762 ++enum {
32763 ++ VCI_KCBIT_NO_DYNAMIC = 0,
32764 ++
32765 ++ VCI_KCBIT_PROC_SECURE = 4,
32766 ++ VCI_KCBIT_HARDCPU = 5,
32767 ++ VCI_KCBIT_IDLELIMIT = 6,
32768 ++ VCI_KCBIT_IDLETIME = 7,
32769 ++
32770 ++ VCI_KCBIT_COWBL = 8,
32771 ++ VCI_KCBIT_FULLCOWBL = 9,
32772 ++ VCI_KCBIT_SPACES = 10,
32773 ++ VCI_KCBIT_NETV2 = 11,
32774 ++
32775 ++ VCI_KCBIT_DEBUG = 16,
32776 ++ VCI_KCBIT_HISTORY = 20,
32777 ++ VCI_KCBIT_TAGGED = 24,
32778 ++ VCI_KCBIT_PPTAG = 28,
32779 ++
32780 ++ VCI_KCBIT_MORE = 31,
32781 ++};
32782 ++
32783 ++
32784 ++static inline uint32_t vci_kernel_config(void)
32785 ++{
32786 ++ return
32787 ++ (1 << VCI_KCBIT_NO_DYNAMIC) |
32788 ++
32789 ++ /* configured features */
32790 ++#ifdef CONFIG_VSERVER_PROC_SECURE
32791 ++ (1 << VCI_KCBIT_PROC_SECURE) |
32792 ++#endif
32793 ++#ifdef CONFIG_VSERVER_HARDCPU
32794 ++ (1 << VCI_KCBIT_HARDCPU) |
32795 ++#endif
32796 ++#ifdef CONFIG_VSERVER_IDLELIMIT
32797 ++ (1 << VCI_KCBIT_IDLELIMIT) |
32798 ++#endif
32799 ++#ifdef CONFIG_VSERVER_IDLETIME
32800 ++ (1 << VCI_KCBIT_IDLETIME) |
32801 ++#endif
32802 ++#ifdef CONFIG_VSERVER_COWBL
32803 ++ (1 << VCI_KCBIT_COWBL) |
32804 ++ (1 << VCI_KCBIT_FULLCOWBL) |
32805 ++#endif
32806 ++ (1 << VCI_KCBIT_SPACES) |
32807 ++ (1 << VCI_KCBIT_NETV2) |
32808 ++
32809 ++ /* debug options */
32810 ++#ifdef CONFIG_VSERVER_DEBUG
32811 ++ (1 << VCI_KCBIT_DEBUG) |
32812 ++#endif
32813 ++#ifdef CONFIG_VSERVER_HISTORY
32814 ++ (1 << VCI_KCBIT_HISTORY) |
32815 ++#endif
32816 ++
32817 ++ /* inode context tagging */
32818 ++#if defined(CONFIG_TAGGING_NONE)
32819 ++ (0 << VCI_KCBIT_TAGGED) |
32820 ++#elif defined(CONFIG_TAGGING_UID16)
32821 ++ (1 << VCI_KCBIT_TAGGED) |
32822 ++#elif defined(CONFIG_TAGGING_GID16)
32823 ++ (2 << VCI_KCBIT_TAGGED) |
32824 ++#elif defined(CONFIG_TAGGING_ID24)
32825 ++ (3 << VCI_KCBIT_TAGGED) |
32826 ++#elif defined(CONFIG_TAGGING_INTERN)
32827 ++ (4 << VCI_KCBIT_TAGGED) |
32828 ++#elif defined(CONFIG_TAGGING_RUNTIME)
32829 ++ (5 << VCI_KCBIT_TAGGED) |
32830 ++#else
32831 ++ (7 << VCI_KCBIT_TAGGED) |
32832 ++#endif
32833 ++ (1 << VCI_KCBIT_PPTAG) |
32834 ++ 0;
32835 ++}
32836 ++
32837 +diff -NurpP --minimal linux-2.6.22.19/mm/filemap_xip.c linux-2.6.22.19-vs2.3.0.34/mm/filemap_xip.c
32838 +--- linux-2.6.22.19/mm/filemap_xip.c 2007-07-09 13:20:04 +0200
32839 ++++ linux-2.6.22.19-vs2.3.0.34/mm/filemap_xip.c 2007-08-05 20:53:13 +0200
32840 +@@ -14,6 +14,7 @@
32841 + #include <linux/uio.h>
32842 + #include <linux/rmap.h>
32843 + #include <linux/sched.h>
32844 ++#include <linux/vs_memory.h>
32845 + #include <asm/tlbflush.h>
32846 + #include "filemap.h"
32847 +
32848 +diff -NurpP --minimal linux-2.6.22.19/mm/fremap.c linux-2.6.22.19-vs2.3.0.34/mm/fremap.c
32849 +--- linux-2.6.22.19/mm/fremap.c 2007-02-06 03:01:56 +0100
32850 ++++ linux-2.6.22.19-vs2.3.0.34/mm/fremap.c 2007-08-05 20:53:13 +0200
32851 +@@ -15,6 +15,7 @@
32852 + #include <linux/rmap.h>
32853 + #include <linux/module.h>
32854 + #include <linux/syscalls.h>
32855 ++#include <linux/vs_memory.h>
32856 +
32857 + #include <asm/mmu_context.h>
32858 + #include <asm/cacheflush.h>
32859 +@@ -74,6 +75,8 @@ int install_page(struct mm_struct *mm, s
32860 + err = -ENOMEM;
32861 + if (page_mapcount(page) > INT_MAX/2)
32862 + goto unlock;
32863 ++ if (!vx_rss_avail(mm, 1))
32864 ++ goto unlock;
32865 +
32866 + if (pte_none(*pte) || !zap_pte(mm, vma, addr, pte))
32867 + inc_mm_counter(mm, file_rss);
32868 +diff -NurpP --minimal linux-2.6.22.19/mm/hugetlb.c linux-2.6.22.19-vs2.3.0.34/mm/hugetlb.c
32869 +--- linux-2.6.22.19/mm/hugetlb.c 2008-03-14 20:19:04 +0100
32870 ++++ linux-2.6.22.19-vs2.3.0.34/mm/hugetlb.c 2007-08-11 22:41:51 +0200
32871 +@@ -19,6 +19,7 @@
32872 + #include <asm/pgtable.h>
32873 +
32874 + #include <linux/hugetlb.h>
32875 ++#include <linux/vs_memory.h>
32876 + #include "internal.h"
32877 +
32878 + const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
32879 +diff -NurpP --minimal linux-2.6.22.19/mm/memory.c linux-2.6.22.19-vs2.3.0.34/mm/memory.c
32880 +--- linux-2.6.22.19/mm/memory.c 2008-03-14 20:19:04 +0100
32881 ++++ linux-2.6.22.19-vs2.3.0.34/mm/memory.c 2008-03-14 21:11:30 +0100
32882 +@@ -498,6 +498,9 @@ static int copy_pte_range(struct mm_stru
32883 + int progress = 0;
32884 + int rss[2];
32885 +
32886 ++ if (!vx_rss_avail(dst_mm, ((end - addr)/PAGE_SIZE + 1)))
32887 ++ return -ENOMEM;
32888 ++
32889 + again:
32890 + rss[1] = rss[0] = 0;
32891 + dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl);
32892 +@@ -2159,6 +2162,11 @@ static int do_swap_page(struct mm_struct
32893 + count_vm_event(PGMAJFAULT);
32894 + }
32895 +
32896 ++ if (!vx_rss_avail(mm, 1)) {
32897 ++ ret = VM_FAULT_OOM;
32898 ++ goto out;
32899 ++ }
32900 ++
32901 + delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
32902 + mark_page_accessed(page);
32903 + lock_page(page);
32904 +@@ -2231,6 +2239,8 @@ static int do_anonymous_page(struct mm_s
32905 + /* Allocate our own private page. */
32906 + pte_unmap(page_table);
32907 +
32908 ++ if (!vx_rss_avail(mm, 1))
32909 ++ goto oom;
32910 + if (unlikely(anon_vma_prepare(vma)))
32911 + goto oom;
32912 + page = alloc_zeroed_user_highpage(vma, address);
32913 +@@ -2304,6 +2314,9 @@ static int do_no_page(struct mm_struct *
32914 + pte_unmap(page_table);
32915 + BUG_ON(vma->vm_flags & VM_PFNMAP);
32916 +
32917 ++ if (!vx_rss_avail(mm, 1))
32918 ++ return VM_FAULT_OOM;
32919 ++
32920 + if (vma->vm_file) {
32921 + mapping = vma->vm_file->f_mapping;
32922 + sequence = mapping->truncate_count;
32923 +@@ -2529,6 +2542,7 @@ static inline int handle_pte_fault(struc
32924 + {
32925 + pte_t entry;
32926 + spinlock_t *ptl;
32927 ++ int ret, type = VXPT_UNKNOWN;
32928 +
32929 + entry = *pte;
32930 + if (!pte_present(entry)) {
32931 +@@ -2557,9 +2571,12 @@ static inline int handle_pte_fault(struc
32932 + if (unlikely(!pte_same(*pte, entry)))
32933 + goto unlock;
32934 + if (write_access) {
32935 +- if (!pte_write(entry))
32936 +- return do_wp_page(mm, vma, address,
32937 ++ if (!pte_write(entry)) {
32938 ++ ret = do_wp_page(mm, vma, address,
32939 + pte, pmd, ptl, entry);
32940 ++ type = VXPT_WRITE;
32941 ++ goto out;
32942 ++ }
32943 + entry = pte_mkdirty(entry);
32944 + }
32945 + entry = pte_mkyoung(entry);
32946 +@@ -2578,7 +2595,10 @@ static inline int handle_pte_fault(struc
32947 + }
32948 + unlock:
32949 + pte_unmap_unlock(pte, ptl);
32950 +- return VM_FAULT_MINOR;
32951 ++ ret = VM_FAULT_MINOR;
32952 ++out:
32953 ++ vx_page_fault(mm, vma, type, ret);
32954 ++ return ret;
32955 + }
32956 +
32957 + /*
32958 +diff -NurpP --minimal linux-2.6.22.19/mm/mlock.c linux-2.6.22.19-vs2.3.0.34/mm/mlock.c
32959 +--- linux-2.6.22.19/mm/mlock.c 2008-03-14 20:19:04 +0100
32960 ++++ linux-2.6.22.19-vs2.3.0.34/mm/mlock.c 2007-08-11 22:41:51 +0200
32961 +@@ -12,6 +12,7 @@
32962 + #include <linux/syscalls.h>
32963 + #include <linux/sched.h>
32964 + #include <linux/module.h>
32965 ++#include <linux/vs_memory.h>
32966 +
32967 + int can_do_mlock(void)
32968 + {
32969 +@@ -76,7 +77,7 @@ success:
32970 + ret = make_pages_present(start, end);
32971 + }
32972 +
32973 +- mm->locked_vm -= pages;
32974 ++ vx_vmlocked_sub(mm, pages);
32975 + out:
32976 + if (ret == -ENOMEM)
32977 + ret = -EAGAIN;
32978 +@@ -134,7 +135,7 @@ static int do_mlock(unsigned long start,
32979 +
32980 + asmlinkage long sys_mlock(unsigned long start, size_t len)
32981 + {
32982 +- unsigned long locked;
32983 ++ unsigned long locked, grow;
32984 + unsigned long lock_limit;
32985 + int error = -ENOMEM;
32986 +
32987 +@@ -145,8 +146,10 @@ asmlinkage long sys_mlock(unsigned long
32988 + len = PAGE_ALIGN(len + (start & ~PAGE_MASK));
32989 + start &= PAGE_MASK;
32990 +
32991 +- locked = len >> PAGE_SHIFT;
32992 +- locked += current->mm->locked_vm;
32993 ++ grow = len >> PAGE_SHIFT;
32994 ++ if (!vx_vmlocked_avail(current->mm, grow))
32995 ++ goto out;
32996 ++ locked = current->mm->locked_vm + grow;
32997 +
32998 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
32999 + lock_limit >>= PAGE_SHIFT;
33000 +@@ -154,6 +157,7 @@ asmlinkage long sys_mlock(unsigned long
33001 + /* check against resource limits */
33002 + if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
33003 + error = do_mlock(start, len, 1);
33004 ++out:
33005 + up_write(&current->mm->mmap_sem);
33006 + return error;
33007 + }
33008 +@@ -213,6 +217,8 @@ asmlinkage long sys_mlockall(int flags)
33009 + lock_limit >>= PAGE_SHIFT;
33010 +
33011 + ret = -ENOMEM;
33012 ++ if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
33013 ++ goto out;
33014 + if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
33015 + capable(CAP_IPC_LOCK))
33016 + ret = do_mlockall(flags);
33017 +diff -NurpP --minimal linux-2.6.22.19/mm/mmap.c linux-2.6.22.19-vs2.3.0.34/mm/mmap.c
33018 +--- linux-2.6.22.19/mm/mmap.c 2008-03-14 20:19:04 +0100
33019 ++++ linux-2.6.22.19-vs2.3.0.34/mm/mmap.c 2008-03-14 21:11:30 +0100
33020 +@@ -1144,10 +1144,10 @@ munmap_back:
33021 + kmem_cache_free(vm_area_cachep, vma);
33022 + }
33023 + out:
33024 +- mm->total_vm += len >> PAGE_SHIFT;
33025 ++ vx_vmpages_add(mm, len >> PAGE_SHIFT);
33026 + vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
33027 + if (vm_flags & VM_LOCKED) {
33028 +- mm->locked_vm += len >> PAGE_SHIFT;
33029 ++ vx_vmlocked_add(mm, len >> PAGE_SHIFT);
33030 + make_pages_present(addr, addr + len);
33031 + }
33032 + if (flags & MAP_POPULATE) {
33033 +@@ -1502,9 +1502,9 @@ static int acct_stack_growth(struct vm_a
33034 + return -ENOMEM;
33035 +
33036 + /* Ok, everything looks good - let it rip */
33037 +- mm->total_vm += grow;
33038 ++ vx_vmpages_add(mm, grow);
33039 + if (vma->vm_flags & VM_LOCKED)
33040 +- mm->locked_vm += grow;
33041 ++ vx_vmlocked_add(mm, grow);
33042 + vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow);
33043 + return 0;
33044 + }
33045 +@@ -1662,9 +1662,9 @@ static void remove_vma_list(struct mm_st
33046 + do {
33047 + long nrpages = vma_pages(vma);
33048 +
33049 +- mm->total_vm -= nrpages;
33050 ++ vx_vmpages_sub(mm, nrpages);
33051 + if (vma->vm_flags & VM_LOCKED)
33052 +- mm->locked_vm -= nrpages;
33053 ++ vx_vmlocked_sub(mm, nrpages);
33054 + vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
33055 + vma = remove_vma(vma);
33056 + } while (vma);
33057 +@@ -1903,6 +1903,8 @@ unsigned long do_brk(unsigned long addr,
33058 + lock_limit >>= PAGE_SHIFT;
33059 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
33060 + return -EAGAIN;
33061 ++ if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT))
33062 ++ return -ENOMEM;
33063 + }
33064 +
33065 + /*
33066 +@@ -1929,7 +1931,8 @@ unsigned long do_brk(unsigned long addr,
33067 + if (mm->map_count > sysctl_max_map_count)
33068 + return -ENOMEM;
33069 +
33070 +- if (security_vm_enough_memory(len >> PAGE_SHIFT))
33071 ++ if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
33072 ++ !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
33073 + return -ENOMEM;
33074 +
33075 + /* Can we just expand an old private anonymous mapping? */
33076 +@@ -1955,9 +1958,9 @@ unsigned long do_brk(unsigned long addr,
33077 + (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
33078 + vma_link(mm, vma, prev, rb_link, rb_parent);
33079 + out:
33080 +- mm->total_vm += len >> PAGE_SHIFT;
33081 ++ vx_vmpages_add(mm, len >> PAGE_SHIFT);
33082 + if (flags & VM_LOCKED) {
33083 +- mm->locked_vm += len >> PAGE_SHIFT;
33084 ++ vx_vmlocked_add(mm, len >> PAGE_SHIFT);
33085 + make_pages_present(addr, addr + len);
33086 + }
33087 + return addr;
33088 +@@ -1986,6 +1989,11 @@ void exit_mmap(struct mm_struct *mm)
33089 + free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0);
33090 + tlb_finish_mmu(tlb, 0, end);
33091 +
33092 ++ set_mm_counter(mm, file_rss, 0);
33093 ++ set_mm_counter(mm, anon_rss, 0);
33094 ++ vx_vmpages_sub(mm, mm->total_vm);
33095 ++ vx_vmlocked_sub(mm, mm->locked_vm);
33096 ++
33097 + /*
33098 + * Walk the list again, actually closing and freeing it,
33099 + * with preemption enabled, without holding any MM locks.
33100 +@@ -2025,7 +2033,8 @@ int insert_vm_struct(struct mm_struct *
33101 + if (__vma && __vma->vm_start < vma->vm_end)
33102 + return -ENOMEM;
33103 + if ((vma->vm_flags & VM_ACCOUNT) &&
33104 +- security_vm_enough_memory(vma_pages(vma)))
33105 ++ (security_vm_enough_memory(vma_pages(vma)) ||
33106 ++ !vx_vmpages_avail(mm, vma_pages(vma))))
33107 + return -ENOMEM;
33108 + vma_link(mm, vma, prev, rb_link, rb_parent);
33109 + return 0;
33110 +@@ -2098,6 +2107,8 @@ int may_expand_vm(struct mm_struct *mm,
33111 +
33112 + if (cur + npages > lim)
33113 + return 0;
33114 ++ if (!vx_vmpages_avail(mm, npages))
33115 ++ return 0;
33116 + return 1;
33117 + }
33118 +
33119 +@@ -2168,7 +2179,6 @@ int install_special_mapping(struct mm_st
33120 + return -ENOMEM;
33121 + }
33122 +
33123 +- mm->total_vm += len >> PAGE_SHIFT;
33124 +-
33125 ++ vx_vmpages_add(mm, len >> PAGE_SHIFT);
33126 + return 0;
33127 + }
33128 +diff -NurpP --minimal linux-2.6.22.19/mm/mremap.c linux-2.6.22.19-vs2.3.0.34/mm/mremap.c
33129 +--- linux-2.6.22.19/mm/mremap.c 2007-02-06 03:01:56 +0100
33130 ++++ linux-2.6.22.19-vs2.3.0.34/mm/mremap.c 2007-08-05 20:53:13 +0200
33131 +@@ -18,6 +18,7 @@
33132 + #include <linux/highmem.h>
33133 + #include <linux/security.h>
33134 + #include <linux/syscalls.h>
33135 ++#include <linux/vs_memory.h>
33136 +
33137 + #include <asm/uaccess.h>
33138 + #include <asm/cacheflush.h>
33139 +@@ -212,7 +213,7 @@ static unsigned long move_vma(struct vm_
33140 + * If this were a serious issue, we'd add a flag to do_munmap().
33141 + */
33142 + hiwater_vm = mm->hiwater_vm;
33143 +- mm->total_vm += new_len >> PAGE_SHIFT;
33144 ++ vx_vmpages_add(mm, new_len >> PAGE_SHIFT);
33145 + vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
33146 +
33147 + if (do_munmap(mm, old_addr, old_len) < 0) {
33148 +@@ -230,7 +231,7 @@ static unsigned long move_vma(struct vm_
33149 + }
33150 +
33151 + if (vm_flags & VM_LOCKED) {
33152 +- mm->locked_vm += new_len >> PAGE_SHIFT;
33153 ++ vx_vmlocked_add(mm, new_len >> PAGE_SHIFT);
33154 + if (new_len > old_len)
33155 + make_pages_present(new_addr + old_len,
33156 + new_addr + new_len);
33157 +@@ -337,6 +338,9 @@ unsigned long do_mremap(unsigned long ad
33158 + ret = -EAGAIN;
33159 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
33160 + goto out;
33161 ++ if (!vx_vmlocked_avail(current->mm,
33162 ++ (new_len - old_len) >> PAGE_SHIFT))
33163 ++ goto out;
33164 + }
33165 + if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) {
33166 + ret = -ENOMEM;
33167 +@@ -365,10 +369,10 @@ unsigned long do_mremap(unsigned long ad
33168 + vma_adjust(vma, vma->vm_start,
33169 + addr + new_len, vma->vm_pgoff, NULL);
33170 +
33171 +- mm->total_vm += pages;
33172 ++ vx_vmpages_add(mm, pages);
33173 + vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
33174 + if (vma->vm_flags & VM_LOCKED) {
33175 +- mm->locked_vm += pages;
33176 ++ vx_vmlocked_add(mm, pages);
33177 + make_pages_present(addr + old_len,
33178 + addr + new_len);
33179 + }
33180 +diff -NurpP --minimal linux-2.6.22.19/mm/nommu.c linux-2.6.22.19-vs2.3.0.34/mm/nommu.c
33181 +--- linux-2.6.22.19/mm/nommu.c 2007-07-09 13:20:04 +0200
33182 ++++ linux-2.6.22.19-vs2.3.0.34/mm/nommu.c 2007-08-05 20:53:13 +0200
33183 +@@ -936,7 +936,7 @@ unsigned long do_mmap_pgoff(struct file
33184 + realalloc += kobjsize(vma);
33185 + askedalloc += sizeof(*vma);
33186 +
33187 +- current->mm->total_vm += len >> PAGE_SHIFT;
33188 ++ vx_vmpages_add(current->mm, len >> PAGE_SHIFT);
33189 +
33190 + add_nommu_vma(vma);
33191 +
33192 +@@ -1061,7 +1061,7 @@ int do_munmap(struct mm_struct *mm, unsi
33193 + kfree(vml);
33194 +
33195 + update_hiwater_vm(mm);
33196 +- mm->total_vm -= len >> PAGE_SHIFT;
33197 ++ vx_vmpages_sub(mm, len >> PAGE_SHIFT);
33198 +
33199 + #ifdef DEBUG
33200 + show_process_blocks();
33201 +@@ -1093,7 +1093,7 @@ void exit_mmap(struct mm_struct * mm)
33202 + printk("Exit_mmap:\n");
33203 + #endif
33204 +
33205 +- mm->total_vm = 0;
33206 ++ vx_vmpages_sub(mm, mm->total_vm);
33207 +
33208 + while ((tmp = mm->context.vmlist)) {
33209 + mm->context.vmlist = tmp->next;
33210 +diff -NurpP --minimal linux-2.6.22.19/mm/oom_kill.c linux-2.6.22.19-vs2.3.0.34/mm/oom_kill.c
33211 +--- linux-2.6.22.19/mm/oom_kill.c 2007-07-09 13:20:04 +0200
33212 ++++ linux-2.6.22.19-vs2.3.0.34/mm/oom_kill.c 2007-08-05 20:53:13 +0200
33213 +@@ -24,6 +24,7 @@
33214 + #include <linux/cpuset.h>
33215 + #include <linux/module.h>
33216 + #include <linux/notifier.h>
33217 ++#include <linux/vs_memory.h>
33218 +
33219 + int sysctl_panic_on_oom;
33220 + /* #define DEBUG */
33221 +@@ -66,6 +67,12 @@ unsigned long badness(struct task_struct
33222 + points = mm->total_vm;
33223 +
33224 + /*
33225 ++ * add points for context badness
33226 ++ */
33227 ++
33228 ++ points += vx_badness(p, mm);
33229 ++
33230 ++ /*
33231 + * After this unlock we can no longer dereference local variable `mm'
33232 + */
33233 + task_unlock(p);
33234 +@@ -156,8 +163,8 @@ unsigned long badness(struct task_struct
33235 + }
33236 +
33237 + #ifdef DEBUG
33238 +- printk(KERN_DEBUG "OOMkill: task %d (%s) got %d points\n",
33239 +- p->pid, p->comm, points);
33240 ++ printk(KERN_DEBUG "OOMkill: task %d:#%u (%s) got %d points\n",
33241 ++ p->pid, p->xid, p->comm, points);
33242 + #endif
33243 + return points;
33244 + }
33245 +@@ -288,7 +295,8 @@ static void __oom_kill_task(struct task_
33246 + }
33247 +
33248 + if (verbose)
33249 +- printk(KERN_ERR "Killed process %d (%s)\n", p->pid, p->comm);
33250 ++ printk(KERN_ERR "Killed process %d:#%u (%s)\n",
33251 ++ p->pid, p->xid, p->comm);
33252 +
33253 + /*
33254 + * We give our sacrificial lamb high priority and access to
33255 +@@ -358,8 +366,8 @@ static int oom_kill_process(struct task_
33256 + return 0;
33257 + }
33258 +
33259 +- printk(KERN_ERR "%s: kill process %d (%s) score %li or a child\n",
33260 +- message, p->pid, p->comm, points);
33261 ++ printk(KERN_ERR "%s: kill process %d:#%u (%s) score %li or a child\n",
33262 ++ message, p->pid, p->xid, p->comm, points);
33263 +
33264 + /* Try to kill a child first */
33265 + list_for_each(tsk, &p->children) {
33266 +diff -NurpP --minimal linux-2.6.22.19/mm/page_alloc.c linux-2.6.22.19-vs2.3.0.34/mm/page_alloc.c
33267 +--- linux-2.6.22.19/mm/page_alloc.c 2007-07-09 13:20:04 +0200
33268 ++++ linux-2.6.22.19-vs2.3.0.34/mm/page_alloc.c 2007-08-05 20:53:13 +0200
33269 +@@ -41,6 +41,8 @@
33270 + #include <linux/pfn.h>
33271 + #include <linux/backing-dev.h>
33272 + #include <linux/fault-inject.h>
33273 ++#include <linux/vs_base.h>
33274 ++#include <linux/vs_limit.h>
33275 +
33276 + #include <asm/tlbflush.h>
33277 + #include <asm/div64.h>
33278 +@@ -1488,6 +1490,9 @@ void si_meminfo(struct sysinfo *val)
33279 + val->totalhigh = totalhigh_pages;
33280 + val->freehigh = nr_free_highpages();
33281 + val->mem_unit = PAGE_SIZE;
33282 ++
33283 ++ if (vx_flags(VXF_VIRT_MEM, 0))
33284 ++ vx_vsi_meminfo(val);
33285 + }
33286 +
33287 + EXPORT_SYMBOL(si_meminfo);
33288 +@@ -1508,6 +1513,9 @@ void si_meminfo_node(struct sysinfo *val
33289 + val->freehigh = 0;
33290 + #endif
33291 + val->mem_unit = PAGE_SIZE;
33292 ++
33293 ++ if (vx_flags(VXF_VIRT_MEM, 0))
33294 ++ vx_vsi_meminfo(val);
33295 + }
33296 + #endif
33297 +
33298 +diff -NurpP --minimal linux-2.6.22.19/mm/rmap.c linux-2.6.22.19-vs2.3.0.34/mm/rmap.c
33299 +--- linux-2.6.22.19/mm/rmap.c 2007-07-09 13:20:04 +0200
33300 ++++ linux-2.6.22.19-vs2.3.0.34/mm/rmap.c 2007-08-05 20:53:13 +0200
33301 +@@ -48,6 +48,7 @@
33302 + #include <linux/rcupdate.h>
33303 + #include <linux/module.h>
33304 + #include <linux/kallsyms.h>
33305 ++#include <linux/vs_memory.h>
33306 +
33307 + #include <asm/tlbflush.h>
33308 +
33309 +diff -NurpP --minimal linux-2.6.22.19/mm/shmem.c linux-2.6.22.19-vs2.3.0.34/mm/shmem.c
33310 +--- linux-2.6.22.19/mm/shmem.c 2008-03-14 20:19:04 +0100
33311 ++++ linux-2.6.22.19-vs2.3.0.34/mm/shmem.c 2008-01-18 12:36:58 +0100
33312 +@@ -55,7 +55,6 @@
33313 + #include <asm/pgtable.h>
33314 +
33315 + /* This magic number is used in glibc for posix shared memory */
33316 +-#define TMPFS_MAGIC 0x01021994
33317 +
33318 + #define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
33319 + #define ENTRIES_PER_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
33320 +@@ -1750,7 +1749,7 @@ static int shmem_statfs(struct dentry *d
33321 + {
33322 + struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
33323 +
33324 +- buf->f_type = TMPFS_MAGIC;
33325 ++ buf->f_type = TMPFS_SUPER_MAGIC;
33326 + buf->f_bsize = PAGE_CACHE_SIZE;
33327 + buf->f_namelen = NAME_MAX;
33328 + spin_lock(&sbinfo->stat_lock);
33329 +@@ -2324,7 +2323,7 @@ static int shmem_fill_super(struct super
33330 + sb->s_maxbytes = SHMEM_MAX_BYTES;
33331 + sb->s_blocksize = PAGE_CACHE_SIZE;
33332 + sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
33333 +- sb->s_magic = TMPFS_MAGIC;
33334 ++ sb->s_magic = TMPFS_SUPER_MAGIC;
33335 + sb->s_op = &shmem_ops;
33336 + sb->s_time_gran = 1;
33337 + #ifdef CONFIG_TMPFS_POSIX_ACL
33338 +diff -NurpP --minimal linux-2.6.22.19/mm/slab.c linux-2.6.22.19-vs2.3.0.34/mm/slab.c
33339 +--- linux-2.6.22.19/mm/slab.c 2007-07-09 13:20:04 +0200
33340 ++++ linux-2.6.22.19-vs2.3.0.34/mm/slab.c 2007-08-05 20:53:13 +0200
33341 +@@ -510,6 +510,8 @@ struct kmem_cache {
33342 + #define STATS_INC_FREEMISS(x) do { } while (0)
33343 + #endif
33344 +
33345 ++#include "slab_vs.h"
33346 ++
33347 + #if DEBUG
33348 +
33349 + /*
33350 +@@ -3314,6 +3316,7 @@ retry:
33351 +
33352 + obj = slab_get_obj(cachep, slabp, nodeid);
33353 + check_slabp(cachep, slabp);
33354 ++ vx_slab_alloc(cachep, flags);
33355 + l3->free_objects--;
33356 + /* move slabp to correct slabp list: */
33357 + list_del(&slabp->list);
33358 +@@ -3386,6 +3389,7 @@ __cache_alloc_node(struct kmem_cache *ca
33359 + /* ___cache_alloc_node can fall back to other nodes */
33360 + ptr = ____cache_alloc_node(cachep, flags, nodeid);
33361 + out:
33362 ++ vx_slab_alloc(cachep, flags);
33363 + local_irq_restore(save_flags);
33364 + ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller);
33365 +
33366 +@@ -3551,6 +3555,7 @@ static inline void __cache_free(struct k
33367 +
33368 + check_irq_off();
33369 + objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
33370 ++ vx_slab_free(cachep);
33371 +
33372 + if (cache_free_alien(cachep, objp))
33373 + return;
33374 +diff -NurpP --minimal linux-2.6.22.19/mm/slab_vs.h linux-2.6.22.19-vs2.3.0.34/mm/slab_vs.h
33375 +--- linux-2.6.22.19/mm/slab_vs.h 1970-01-01 01:00:00 +0100
33376 ++++ linux-2.6.22.19-vs2.3.0.34/mm/slab_vs.h 2007-08-05 20:53:13 +0200
33377 +@@ -0,0 +1,27 @@
33378 ++
33379 ++#include <linux/vserver/context.h>
33380 ++
33381 ++#include <linux/vs_context.h>
33382 ++
33383 ++static inline
33384 ++void vx_slab_alloc(struct kmem_cache *cachep, gfp_t flags)
33385 ++{
33386 ++ int what = gfp_zone(cachep->gfpflags);
33387 ++
33388 ++ if (!current->vx_info)
33389 ++ return;
33390 ++
33391 ++ atomic_add(cachep->buffer_size, &current->vx_info->cacct.slab[what]);
33392 ++}
33393 ++
33394 ++static inline
33395 ++void vx_slab_free(struct kmem_cache *cachep)
33396 ++{
33397 ++ int what = gfp_zone(cachep->gfpflags);
33398 ++
33399 ++ if (!current->vx_info)
33400 ++ return;
33401 ++
33402 ++ atomic_sub(cachep->buffer_size, &current->vx_info->cacct.slab[what]);
33403 ++}
33404 ++
33405 +diff -NurpP --minimal linux-2.6.22.19/mm/swapfile.c linux-2.6.22.19-vs2.3.0.34/mm/swapfile.c
33406 +--- linux-2.6.22.19/mm/swapfile.c 2007-07-09 13:20:04 +0200
33407 ++++ linux-2.6.22.19-vs2.3.0.34/mm/swapfile.c 2007-08-05 20:53:13 +0200
33408 +@@ -31,6 +31,8 @@
33409 + #include <asm/pgtable.h>
33410 + #include <asm/tlbflush.h>
33411 + #include <linux/swapops.h>
33412 ++#include <linux/vs_base.h>
33413 ++#include <linux/vs_memory.h>
33414 +
33415 + DEFINE_SPINLOCK(swap_lock);
33416 + unsigned int nr_swapfiles;
33417 +@@ -1712,6 +1714,8 @@ void si_swapinfo(struct sysinfo *val)
33418 + val->freeswap = nr_swap_pages + nr_to_be_unused;
33419 + val->totalswap = total_swap_pages + nr_to_be_unused;
33420 + spin_unlock(&swap_lock);
33421 ++ if (vx_flags(VXF_VIRT_MEM, 0))
33422 ++ vx_vsi_swapinfo(val);
33423 + }
33424 +
33425 + /*
33426 +diff -NurpP --minimal linux-2.6.22.19/net/core/dev.c linux-2.6.22.19-vs2.3.0.34/net/core/dev.c
33427 +--- linux-2.6.22.19/net/core/dev.c 2008-03-14 20:19:05 +0100
33428 ++++ linux-2.6.22.19-vs2.3.0.34/net/core/dev.c 2007-09-05 03:06:12 +0200
33429 +@@ -117,6 +117,7 @@
33430 + #include <linux/err.h>
33431 + #include <linux/ctype.h>
33432 + #include <linux/if_arp.h>
33433 ++#include <linux/vs_inet.h>
33434 +
33435 + /*
33436 + * The list of packet types we will receive (as opposed to discard)
33437 +@@ -2120,6 +2121,8 @@ static int dev_ifconf(char __user *arg)
33438 +
33439 + total = 0;
33440 + for_each_netdev(dev) {
33441 ++ if (!nx_dev_visible(current->nx_info, dev))
33442 ++ continue;
33443 + for (i = 0; i < NPROTO; i++) {
33444 + if (gifconf_list[i]) {
33445 + int done;
33446 +@@ -2184,6 +2187,9 @@ static void dev_seq_printf_stats(struct
33447 + {
33448 + struct net_device_stats *stats = dev->get_stats(dev);
33449 +
33450 ++ if (!nx_dev_visible(current->nx_info, dev))
33451 ++ return;
33452 ++
33453 + seq_printf(seq, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu "
33454 + "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n",
33455 + dev->name, stats->rx_bytes, stats->rx_packets,
33456 +diff -NurpP --minimal linux-2.6.22.19/net/core/rtnetlink.c linux-2.6.22.19-vs2.3.0.34/net/core/rtnetlink.c
33457 +--- linux-2.6.22.19/net/core/rtnetlink.c 2007-07-09 13:20:05 +0200
33458 ++++ linux-2.6.22.19-vs2.3.0.34/net/core/rtnetlink.c 2007-08-05 20:53:13 +0200
33459 +@@ -537,6 +537,8 @@ static int rtnl_dump_ifinfo(struct sk_bu
33460 +
33461 + idx = 0;
33462 + for_each_netdev(dev) {
33463 ++ if (!nx_dev_visible(skb->sk->sk_nx_info, dev))
33464 ++ continue;
33465 + if (idx < s_idx)
33466 + goto cont;
33467 + if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
33468 +@@ -797,6 +799,9 @@ void rtmsg_ifinfo(int type, struct net_d
33469 + struct sk_buff *skb;
33470 + int err = -ENOBUFS;
33471 +
33472 ++ if (!nx_dev_visible(current->nx_info, dev))
33473 ++ return;
33474 ++
33475 + skb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL);
33476 + if (skb == NULL)
33477 + goto errout;
33478 +diff -NurpP --minimal linux-2.6.22.19/net/core/sock.c linux-2.6.22.19-vs2.3.0.34/net/core/sock.c
33479 +--- linux-2.6.22.19/net/core/sock.c 2007-07-09 13:20:05 +0200
33480 ++++ linux-2.6.22.19-vs2.3.0.34/net/core/sock.c 2007-10-01 14:57:43 +0200
33481 +@@ -125,6 +125,10 @@
33482 + #include <linux/ipsec.h>
33483 +
33484 + #include <linux/filter.h>
33485 ++#include <linux/vs_socket.h>
33486 ++#include <linux/vs_limit.h>
33487 ++#include <linux/vs_context.h>
33488 ++#include <linux/vs_network.h>
33489 +
33490 + #ifdef CONFIG_INET
33491 + #include <net/tcp.h>
33492 +@@ -812,6 +816,9 @@ int sock_getsockopt(struct socket *sock,
33493 + case SO_PEERSEC:
33494 + return security_socket_getpeersec_stream(sock, optval, optlen, len);
33495 +
33496 ++ case SO_PEERTAG:
33497 ++ return vx_socket_peer_tag(sock, level, optval, optlen, len);
33498 ++
33499 + default:
33500 + return -ENOPROTOOPT;
33501 + }
33502 +@@ -869,6 +876,8 @@ struct sock *sk_alloc(int family, gfp_t
33503 + sk->sk_prot = sk->sk_prot_creator = prot;
33504 + sock_lock_init(sk);
33505 + }
33506 ++ sock_vx_init(sk);
33507 ++ sock_nx_init(sk);
33508 +
33509 + if (security_sk_alloc(sk, family, priority))
33510 + goto out_free;
33511 +@@ -907,6 +916,11 @@ void sk_free(struct sock *sk)
33512 + __FUNCTION__, atomic_read(&sk->sk_omem_alloc));
33513 +
33514 + security_sk_free(sk);
33515 ++ vx_sock_dec(sk);
33516 ++ clr_vx_info(&sk->sk_vx_info);
33517 ++ sk->sk_xid = -1;
33518 ++ clr_nx_info(&sk->sk_nx_info);
33519 ++ sk->sk_nid = -1;
33520 + if (sk->sk_prot_creator->slab != NULL)
33521 + kmem_cache_free(sk->sk_prot_creator->slab, sk);
33522 + else
33523 +@@ -924,6 +938,8 @@ struct sock *sk_clone(const struct sock
33524 + sock_copy(newsk, sk);
33525 +
33526 + /* SANITY */
33527 ++ sock_vx_init(newsk);
33528 ++ sock_nx_init(newsk);
33529 + sk_node_init(&newsk->sk_node);
33530 + sock_lock_init(newsk);
33531 + bh_lock_sock(newsk);
33532 +@@ -969,6 +985,12 @@ struct sock *sk_clone(const struct sock
33533 + newsk->sk_priority = 0;
33534 + atomic_set(&newsk->sk_refcnt, 2);
33535 +
33536 ++ set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info);
33537 ++ newsk->sk_xid = sk->sk_xid;
33538 ++ vx_sock_inc(newsk);
33539 ++ set_nx_info(&newsk->sk_nx_info, sk->sk_nx_info);
33540 ++ newsk->sk_nid = sk->sk_nid;
33541 ++
33542 + /*
33543 + * Increment the counter in the same struct proto as the master
33544 + * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
33545 +@@ -1551,6 +1573,11 @@ void sock_init_data(struct socket *sock,
33546 +
33547 + sk->sk_stamp = ktime_set(-1L, -1L);
33548 +
33549 ++ set_vx_info(&sk->sk_vx_info, current->vx_info);
33550 ++ sk->sk_xid = vx_current_xid();
33551 ++ vx_sock_inc(sk);
33552 ++ set_nx_info(&sk->sk_nx_info, current->nx_info);
33553 ++ sk->sk_nid = nx_current_nid();
33554 + atomic_set(&sk->sk_refcnt, 1);
33555 + }
33556 +
33557 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/af_inet.c linux-2.6.22.19-vs2.3.0.34/net/ipv4/af_inet.c
33558 +--- linux-2.6.22.19/net/ipv4/af_inet.c 2008-03-14 20:19:05 +0100
33559 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv4/af_inet.c 2007-10-05 14:54:36 +0200
33560 +@@ -115,6 +115,7 @@
33561 + #ifdef CONFIG_IP_MROUTE
33562 + #include <linux/mroute.h>
33563 + #endif
33564 ++#include <linux/vs_limit.h>
33565 +
33566 + DEFINE_SNMP_STAT(struct linux_mib, net_statistics) __read_mostly;
33567 +
33568 +@@ -308,9 +309,12 @@ lookup_protocol:
33569 + }
33570 +
33571 + err = -EPERM;
33572 ++ if ((protocol == IPPROTO_ICMP) &&
33573 ++ nx_capable(answer->capability, NXC_RAW_ICMP))
33574 ++ goto override;
33575 + if (answer->capability > 0 && !capable(answer->capability))
33576 + goto out_rcu_unlock;
33577 +-
33578 ++override:
33579 + sock->ops = answer->ops;
33580 + answer_prot = answer->prot;
33581 + answer_no_check = answer->no_check;
33582 +@@ -424,6 +428,7 @@ int inet_bind(struct socket *sock, struc
33583 + struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
33584 + struct sock *sk = sock->sk;
33585 + struct inet_sock *inet = inet_sk(sk);
33586 ++ struct nx_v4_sock_addr nsa;
33587 + unsigned short snum;
33588 + int chk_addr_ret;
33589 + int err;
33590 +@@ -437,7 +442,11 @@ int inet_bind(struct socket *sock, struc
33591 + if (addr_len < sizeof(struct sockaddr_in))
33592 + goto out;
33593 +
33594 +- chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
33595 ++ err = v4_map_sock_addr(inet, addr, &nsa);
33596 ++ if (err)
33597 ++ goto out;
33598 ++
33599 ++ chk_addr_ret = inet_addr_type(nsa.saddr);
33600 +
33601 + /* Not specified by any standard per-se, however it breaks too
33602 + * many applications when removed. It is unfortunate since
33603 +@@ -449,7 +458,7 @@ int inet_bind(struct socket *sock, struc
33604 + err = -EADDRNOTAVAIL;
33605 + if (!sysctl_ip_nonlocal_bind &&
33606 + !inet->freebind &&
33607 +- addr->sin_addr.s_addr != INADDR_ANY &&
33608 ++ nsa.saddr != INADDR_ANY &&
33609 + chk_addr_ret != RTN_LOCAL &&
33610 + chk_addr_ret != RTN_MULTICAST &&
33611 + chk_addr_ret != RTN_BROADCAST)
33612 +@@ -474,7 +483,7 @@ int inet_bind(struct socket *sock, struc
33613 + if (sk->sk_state != TCP_CLOSE || inet->num)
33614 + goto out_release_sock;
33615 +
33616 +- inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr;
33617 ++ v4_set_sock_addr(inet, &nsa);
33618 + if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
33619 + inet->saddr = 0; /* Use device */
33620 +
33621 +@@ -667,11 +676,13 @@ int inet_getname(struct socket *sock, st
33622 + peer == 1))
33623 + return -ENOTCONN;
33624 + sin->sin_port = inet->dport;
33625 +- sin->sin_addr.s_addr = inet->daddr;
33626 ++ sin->sin_addr.s_addr =
33627 ++ nx_map_sock_lback(sk->sk_nx_info, inet->daddr);
33628 + } else {
33629 + __be32 addr = inet->rcv_saddr;
33630 + if (!addr)
33631 + addr = inet->saddr;
33632 ++ addr = nx_map_sock_lback(sk->sk_nx_info, addr);
33633 + sin->sin_port = inet->sport;
33634 + sin->sin_addr.s_addr = addr;
33635 + }
33636 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/devinet.c linux-2.6.22.19-vs2.3.0.34/net/ipv4/devinet.c
33637 +--- linux-2.6.22.19/net/ipv4/devinet.c 2008-03-14 20:19:05 +0100
33638 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv4/devinet.c 2008-03-14 21:11:30 +0100
33639 +@@ -427,6 +427,7 @@ struct in_device *inetdev_by_index(int i
33640 + return in_dev;
33641 + }
33642 +
33643 ++
33644 + /* Called only from RTNL semaphored context. No locks. */
33645 +
33646 + struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
33647 +@@ -676,6 +677,8 @@ int devinet_ioctl(unsigned int cmd, void
33648 + *colon = ':';
33649 +
33650 + if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) {
33651 ++ struct nx_info *nxi = current->nx_info;
33652 ++
33653 + if (tryaddrmatch) {
33654 + /* Matthias Andree */
33655 + /* compare label and address (4.4BSD style) */
33656 +@@ -684,6 +687,8 @@ int devinet_ioctl(unsigned int cmd, void
33657 + This is checked above. */
33658 + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
33659 + ifap = &ifa->ifa_next) {
33660 ++ if (!nx_v4_ifa_visible(nxi, ifa))
33661 ++ continue;
33662 + if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
33663 + sin_orig.sin_addr.s_addr ==
33664 + ifa->ifa_address) {
33665 +@@ -696,9 +701,12 @@ int devinet_ioctl(unsigned int cmd, void
33666 + comparing just the label */
33667 + if (!ifa) {
33668 + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
33669 +- ifap = &ifa->ifa_next)
33670 ++ ifap = &ifa->ifa_next) {
33671 ++ if (!nx_v4_ifa_visible(nxi, ifa))
33672 ++ continue;
33673 + if (!strcmp(ifr.ifr_name, ifa->ifa_label))
33674 + break;
33675 ++ }
33676 + }
33677 + }
33678 +
33679 +@@ -849,6 +857,8 @@ static int inet_gifconf(struct net_devic
33680 + goto out;
33681 +
33682 + for (; ifa; ifa = ifa->ifa_next) {
33683 ++ if (!nx_v4_ifa_visible(current->nx_info, ifa))
33684 ++ continue;
33685 + if (!buf) {
33686 + done += sizeof(ifr);
33687 + continue;
33688 +@@ -1179,6 +1189,7 @@ static int inet_dump_ifaddr(struct sk_bu
33689 + struct net_device *dev;
33690 + struct in_device *in_dev;
33691 + struct in_ifaddr *ifa;
33692 ++ struct sock *sk = skb->sk;
33693 + int s_ip_idx, s_idx = cb->args[0];
33694 +
33695 + s_ip_idx = ip_idx = cb->args[1];
33696 +@@ -1193,6 +1204,8 @@ static int inet_dump_ifaddr(struct sk_bu
33697 +
33698 + for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
33699 + ifa = ifa->ifa_next, ip_idx++) {
33700 ++ if (sk && !nx_v4_ifa_visible(sk->sk_nx_info, ifa))
33701 ++ continue;
33702 + if (ip_idx < s_ip_idx)
33703 + continue;
33704 + if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
33705 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/fib_hash.c linux-2.6.22.19-vs2.3.0.34/net/ipv4/fib_hash.c
33706 +--- linux-2.6.22.19/net/ipv4/fib_hash.c 2007-07-09 13:20:05 +0200
33707 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv4/fib_hash.c 2007-08-05 20:53:13 +0200
33708 +@@ -1012,7 +1012,7 @@ static int fib_seq_show(struct seq_file
33709 + prefix = f->fn_key;
33710 + mask = FZ_MASK(iter->zone);
33711 + flags = fib_flag_trans(fa->fa_type, mask, fi);
33712 +- if (fi)
33713 ++ if (fi && nx_dev_visible(current->nx_info, fi->fib_dev))
33714 + snprintf(bf, sizeof(bf),
33715 + "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
33716 + fi->fib_dev ? fi->fib_dev->name : "*", prefix,
33717 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/inet_connection_sock.c linux-2.6.22.19-vs2.3.0.34/net/ipv4/inet_connection_sock.c
33718 +--- linux-2.6.22.19/net/ipv4/inet_connection_sock.c 2007-07-09 13:20:05 +0200
33719 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv4/inet_connection_sock.c 2007-10-18 01:28:12 +0200
33720 +@@ -34,10 +34,40 @@ EXPORT_SYMBOL(inet_csk_timer_bug_msg);
33721 + */
33722 + int sysctl_local_port_range[2] = { 32768, 61000 };
33723 +
33724 ++int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
33725 ++{
33726 ++ __be32 sk1_rcv_saddr = inet_rcv_saddr(sk1),
33727 ++ sk2_rcv_saddr = inet_rcv_saddr(sk2);
33728 ++
33729 ++ if (inet_v6_ipv6only(sk2))
33730 ++ return 0;
33731 ++
33732 ++ if (sk1_rcv_saddr &&
33733 ++ sk2_rcv_saddr &&
33734 ++ sk1_rcv_saddr == sk2_rcv_saddr)
33735 ++ return 1;
33736 ++
33737 ++ if (sk1_rcv_saddr &&
33738 ++ !sk2_rcv_saddr &&
33739 ++ v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, NXA_MASK_BIND))
33740 ++ return 1;
33741 ++
33742 ++ if (sk2_rcv_saddr &&
33743 ++ !sk1_rcv_saddr &&
33744 ++ v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, NXA_MASK_BIND))
33745 ++ return 1;
33746 ++
33747 ++ if (!sk1_rcv_saddr &&
33748 ++ !sk2_rcv_saddr &&
33749 ++ nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info))
33750 ++ return 1;
33751 ++
33752 ++ return 0;
33753 ++}
33754 ++
33755 + int inet_csk_bind_conflict(const struct sock *sk,
33756 + const struct inet_bind_bucket *tb)
33757 + {
33758 +- const __be32 sk_rcv_saddr = inet_rcv_saddr(sk);
33759 + struct sock *sk2;
33760 + struct hlist_node *node;
33761 + int reuse = sk->sk_reuse;
33762 +@@ -50,9 +80,7 @@ int inet_csk_bind_conflict(const struct
33763 + sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
33764 + if (!reuse || !sk2->sk_reuse ||
33765 + sk2->sk_state == TCP_LISTEN) {
33766 +- const __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
33767 +- if (!sk2_rcv_saddr || !sk_rcv_saddr ||
33768 +- sk2_rcv_saddr == sk_rcv_saddr)
33769 ++ if (ipv4_rcv_saddr_equal(sk, sk2))
33770 + break;
33771 + }
33772 + }
33773 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/inet_diag.c linux-2.6.22.19-vs2.3.0.34/net/ipv4/inet_diag.c
33774 +--- linux-2.6.22.19/net/ipv4/inet_diag.c 2008-03-14 20:19:05 +0100
33775 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv4/inet_diag.c 2007-10-30 02:36:32 +0100
33776 +@@ -98,8 +98,8 @@ static int inet_csk_diag_fill(struct soc
33777 +
33778 + r->id.idiag_sport = inet->sport;
33779 + r->id.idiag_dport = inet->dport;
33780 +- r->id.idiag_src[0] = inet->rcv_saddr;
33781 +- r->id.idiag_dst[0] = inet->daddr;
33782 ++ r->id.idiag_src[0] = nx_map_sock_lback(sk->sk_nx_info, inet->rcv_saddr);
33783 ++ r->id.idiag_dst[0] = nx_map_sock_lback(sk->sk_nx_info, inet->daddr);
33784 +
33785 + #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
33786 + if (r->idiag_family == AF_INET6) {
33787 +@@ -186,8 +186,8 @@ static int inet_twsk_diag_fill(struct in
33788 + r->id.idiag_cookie[1] = (u32)(((unsigned long)tw >> 31) >> 1);
33789 + r->id.idiag_sport = tw->tw_sport;
33790 + r->id.idiag_dport = tw->tw_dport;
33791 +- r->id.idiag_src[0] = tw->tw_rcv_saddr;
33792 +- r->id.idiag_dst[0] = tw->tw_daddr;
33793 ++ r->id.idiag_src[0] = nx_map_sock_lback(tw->tw_nx_info, tw->tw_rcv_saddr);
33794 ++ r->id.idiag_dst[0] = nx_map_sock_lback(tw->tw_nx_info, tw->tw_daddr);
33795 + r->idiag_state = tw->tw_substate;
33796 + r->idiag_timer = 3;
33797 + r->idiag_expires = (tmo * 1000 + HZ - 1) / HZ;
33798 +@@ -239,6 +239,7 @@ static int inet_diag_get_exact(struct sk
33799 + hashinfo = handler->idiag_hashinfo;
33800 +
33801 + if (req->idiag_family == AF_INET) {
33802 ++ /* TODO: lback */
33803 + sk = inet_lookup(hashinfo, req->id.idiag_dst[0],
33804 + req->id.idiag_dport, req->id.idiag_src[0],
33805 + req->id.idiag_sport, req->id.idiag_if);
33806 +@@ -478,6 +479,7 @@ static int inet_csk_diag_dump(struct soc
33807 + } else
33808 + #endif
33809 + {
33810 ++ /* TODO: lback */
33811 + entry.saddr = &inet->rcv_saddr;
33812 + entry.daddr = &inet->daddr;
33813 + }
33814 +@@ -514,6 +516,7 @@ static int inet_twsk_diag_dump(struct in
33815 + } else
33816 + #endif
33817 + {
33818 ++ /* TODO: lback */
33819 + entry.saddr = &tw->tw_rcv_saddr;
33820 + entry.daddr = &tw->tw_daddr;
33821 + }
33822 +@@ -560,8 +563,8 @@ static int inet_diag_fill_req(struct sk_
33823 +
33824 + r->id.idiag_sport = inet->sport;
33825 + r->id.idiag_dport = ireq->rmt_port;
33826 +- r->id.idiag_src[0] = ireq->loc_addr;
33827 +- r->id.idiag_dst[0] = ireq->rmt_addr;
33828 ++ r->id.idiag_src[0] = nx_map_sock_lback(sk->sk_nx_info, ireq->loc_addr);
33829 ++ r->id.idiag_dst[0] = nx_map_sock_lback(sk->sk_nx_info, ireq->rmt_addr);
33830 + r->idiag_expires = jiffies_to_msecs(tmo);
33831 + r->idiag_rqueue = 0;
33832 + r->idiag_wqueue = 0;
33833 +@@ -631,6 +634,7 @@ static int inet_diag_dump_reqs(struct sk
33834 + continue;
33835 +
33836 + if (bc) {
33837 ++ /* TODO: lback */
33838 + entry.saddr =
33839 + #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
33840 + (entry.family == AF_INET6) ?
33841 +@@ -697,6 +701,8 @@ static int inet_diag_dump(struct sk_buff
33842 + sk_for_each(sk, node, &hashinfo->listening_hash[i]) {
33843 + struct inet_sock *inet = inet_sk(sk);
33844 +
33845 ++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
33846 ++ continue;
33847 + if (num < s_num) {
33848 + num++;
33849 + continue;
33850 +@@ -757,6 +763,8 @@ skip_listen_ht:
33851 + sk_for_each(sk, node, &head->chain) {
33852 + struct inet_sock *inet = inet_sk(sk);
33853 +
33854 ++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
33855 ++ continue;
33856 + if (num < s_num)
33857 + goto next_normal;
33858 + if (!(r->idiag_states & (1 << sk->sk_state)))
33859 +@@ -781,6 +789,8 @@ next_normal:
33860 + inet_twsk_for_each(tw, node,
33861 + &head->twchain) {
33862 +
33863 ++ if (!nx_check(tw->tw_nid, VS_WATCH_P | VS_IDENT))
33864 ++ continue;
33865 + if (num < s_num)
33866 + goto next_dying;
33867 + if (r->id.idiag_sport != tw->tw_sport &&
33868 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/inet_hashtables.c linux-2.6.22.19-vs2.3.0.34/net/ipv4/inet_hashtables.c
33869 +--- linux-2.6.22.19/net/ipv4/inet_hashtables.c 2007-05-02 19:25:40 +0200
33870 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv4/inet_hashtables.c 2007-08-05 20:53:13 +0200
33871 +@@ -140,11 +140,10 @@ static struct sock *inet_lookup_listener
33872 + const __be32 rcv_saddr = inet->rcv_saddr;
33873 + int score = sk->sk_family == PF_INET ? 1 : 0;
33874 +
33875 +- if (rcv_saddr) {
33876 +- if (rcv_saddr != daddr)
33877 +- continue;
33878 ++ if (v4_inet_addr_match(sk->sk_nx_info, daddr, rcv_saddr))
33879 + score += 2;
33880 +- }
33881 ++ else
33882 ++ continue;
33883 + if (sk->sk_bound_dev_if) {
33884 + if (sk->sk_bound_dev_if != dif)
33885 + continue;
33886 +@@ -175,7 +174,7 @@ struct sock *__inet_lookup_listener(stru
33887 + const struct inet_sock *inet = inet_sk((sk = __sk_head(head)));
33888 +
33889 + if (inet->num == hnum && !sk->sk_node.next &&
33890 +- (!inet->rcv_saddr || inet->rcv_saddr == daddr) &&
33891 ++ v4_inet_addr_match(sk->sk_nx_info, daddr, inet->rcv_saddr) &&
33892 + (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
33893 + !sk->sk_bound_dev_if)
33894 + goto sherry_cache;
33895 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/raw.c linux-2.6.22.19-vs2.3.0.34/net/ipv4/raw.c
33896 +--- linux-2.6.22.19/net/ipv4/raw.c 2007-07-09 13:20:06 +0200
33897 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv4/raw.c 2007-10-05 12:29:05 +0200
33898 +@@ -112,7 +112,7 @@ struct sock *__raw_v4_lookup(struct sock
33899 +
33900 + if (inet->num == num &&
33901 + !(inet->daddr && inet->daddr != raddr) &&
33902 +- !(inet->rcv_saddr && inet->rcv_saddr != laddr) &&
33903 ++ v4_sock_addr_match(sk->sk_nx_info, inet, laddr) &&
33904 + !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
33905 + goto found; /* gotcha */
33906 + }
33907 +@@ -314,6 +314,12 @@ static int raw_send_hdrinc(struct sock *
33908 + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
33909 + }
33910 +
33911 ++ err = -EPERM;
33912 ++ if (!nx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW) &&
33913 ++ sk->sk_nx_info &&
33914 ++ !v4_addr_in_nx_info(sk->sk_nx_info, iph->saddr, NXA_MASK_BIND))
33915 ++ goto error_free;
33916 ++
33917 + err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
33918 + dst_output);
33919 + if (err > 0)
33920 +@@ -325,6 +331,7 @@ out:
33921 +
33922 + error_fault:
33923 + err = -EFAULT;
33924 ++error_free:
33925 + kfree_skb(skb);
33926 + error:
33927 + IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS);
33928 +@@ -491,6 +498,12 @@ static int raw_sendmsg(struct kiocb *ioc
33929 + }
33930 +
33931 + security_sk_classify_flow(sk, &fl);
33932 ++ if (sk->sk_nx_info) {
33933 ++ err = ip_v4_find_src(sk->sk_nx_info, &rt, &fl);
33934 ++
33935 ++ if (err)
33936 ++ goto done;
33937 ++ }
33938 + err = ip_route_output_flow(&rt, &fl, sk, 1);
33939 + }
33940 + if (err)
33941 +@@ -553,17 +566,19 @@ static int raw_bind(struct sock *sk, str
33942 + {
33943 + struct inet_sock *inet = inet_sk(sk);
33944 + struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
33945 ++ struct nx_v4_sock_addr nsa = { 0 };
33946 + int ret = -EINVAL;
33947 + int chk_addr_ret;
33948 +
33949 + if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
33950 + goto out;
33951 +- chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
33952 ++ v4_map_sock_addr(inet, addr, &nsa);
33953 ++ chk_addr_ret = inet_addr_type(nsa.saddr);
33954 + ret = -EADDRNOTAVAIL;
33955 +- if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
33956 ++ if (nsa.saddr && chk_addr_ret != RTN_LOCAL &&
33957 + chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
33958 + goto out;
33959 +- inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr;
33960 ++ v4_set_sock_addr(inet, &nsa);
33961 + if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
33962 + inet->saddr = 0; /* Use device */
33963 + sk_dst_reset(sk);
33964 +@@ -615,7 +630,8 @@ static int raw_recvmsg(struct kiocb *ioc
33965 + /* Copy the address. */
33966 + if (sin) {
33967 + sin->sin_family = AF_INET;
33968 +- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
33969 ++ sin->sin_addr.s_addr =
33970 ++ nx_map_sock_lback(sk->sk_nx_info, ip_hdr(skb)->saddr);
33971 + sin->sin_port = 0;
33972 + memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
33973 + }
33974 +@@ -795,7 +811,8 @@ static struct sock *raw_get_first(struct
33975 + struct hlist_node *node;
33976 +
33977 + sk_for_each(sk, node, &raw_v4_htable[state->bucket])
33978 +- if (sk->sk_family == PF_INET)
33979 ++ if (sk->sk_family == PF_INET &&
33980 ++ nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
33981 + goto found;
33982 + }
33983 + sk = NULL;
33984 +@@ -811,7 +828,8 @@ static struct sock *raw_get_next(struct
33985 + sk = sk_next(sk);
33986 + try_again:
33987 + ;
33988 +- } while (sk && sk->sk_family != PF_INET);
33989 ++ } while (sk && (sk->sk_family != PF_INET ||
33990 ++ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
33991 +
33992 + if (!sk && ++state->bucket < RAWV4_HTABLE_SIZE) {
33993 + sk = sk_head(&raw_v4_htable[state->bucket]);
33994 +@@ -863,7 +881,10 @@ static __inline__ char *get_raw_sock(str
33995 +
33996 + sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
33997 + " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
33998 +- i, src, srcp, dest, destp, sp->sk_state,
33999 ++ i,
34000 ++ nx_map_sock_lback(current_nx_info(), src), srcp,
34001 ++ nx_map_sock_lback(current_nx_info(), dest), destp,
34002 ++ sp->sk_state,
34003 + atomic_read(&sp->sk_wmem_alloc),
34004 + atomic_read(&sp->sk_rmem_alloc),
34005 + 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
34006 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/tcp.c linux-2.6.22.19-vs2.3.0.34/net/ipv4/tcp.c
34007 +--- linux-2.6.22.19/net/ipv4/tcp.c 2008-03-14 20:19:05 +0100
34008 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv4/tcp.c 2007-09-05 03:06:12 +0200
34009 +@@ -258,6 +258,7 @@
34010 + #include <linux/cache.h>
34011 + #include <linux/err.h>
34012 + #include <linux/crypto.h>
34013 ++#include <linux/in.h>
34014 +
34015 + #include <net/icmp.h>
34016 + #include <net/tcp.h>
34017 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/tcp_ipv4.c linux-2.6.22.19-vs2.3.0.34/net/ipv4/tcp_ipv4.c
34018 +--- linux-2.6.22.19/net/ipv4/tcp_ipv4.c 2008-03-14 20:19:05 +0100
34019 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv4/tcp_ipv4.c 2008-01-18 12:36:58 +0100
34020 +@@ -1974,6 +1974,12 @@ static void *listening_get_next(struct s
34021 + req = req->dl_next;
34022 + while (1) {
34023 + while (req) {
34024 ++ vxdprintk(VXD_CBIT(net, 6),
34025 ++ "sk,req: %p [#%d] (from %d)", req->sk,
34026 ++ (req->sk)?req->sk->sk_nid:0, nx_current_nid());
34027 ++ if (req->sk &&
34028 ++ !nx_check(req->sk->sk_nid, VS_WATCH_P | VS_IDENT))
34029 ++ continue;
34030 + if (req->rsk_ops->family == st->family) {
34031 + cur = req;
34032 + goto out;
34033 +@@ -1998,6 +2004,10 @@ get_req:
34034 + }
34035 + get_sk:
34036 + sk_for_each_from(sk, node) {
34037 ++ vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
34038 ++ sk, sk->sk_nid, nx_current_nid());
34039 ++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
34040 ++ continue;
34041 + if (sk->sk_family == st->family) {
34042 + cur = sk;
34043 + goto out;
34044 +@@ -2049,18 +2059,26 @@ static void *established_get_first(struc
34045 +
34046 + read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
34047 + sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
34048 +- if (sk->sk_family != st->family) {
34049 ++ vxdprintk(VXD_CBIT(net, 6),
34050 ++ "sk,egf: %p [#%d] (from %d)",
34051 ++ sk, sk->sk_nid, nx_current_nid());
34052 ++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
34053 ++ continue;
34054 ++ if (sk->sk_family != st->family)
34055 + continue;
34056 +- }
34057 + rc = sk;
34058 + goto out;
34059 + }
34060 + st->state = TCP_SEQ_STATE_TIME_WAIT;
34061 + inet_twsk_for_each(tw, node,
34062 + &tcp_hashinfo.ehash[st->bucket].twchain) {
34063 +- if (tw->tw_family != st->family) {
34064 ++ vxdprintk(VXD_CBIT(net, 6),
34065 ++ "tw: %p [#%d] (from %d)",
34066 ++ tw, tw->tw_nid, nx_current_nid());
34067 ++ if (!nx_check(tw->tw_nid, VS_WATCH_P | VS_IDENT))
34068 ++ continue;
34069 ++ if (tw->tw_family != st->family)
34070 + continue;
34071 +- }
34072 + rc = tw;
34073 + goto out;
34074 + }
34075 +@@ -2084,7 +2102,8 @@ static void *established_get_next(struct
34076 + tw = cur;
34077 + tw = tw_next(tw);
34078 + get_tw:
34079 +- while (tw && tw->tw_family != st->family) {
34080 ++ while (tw && (tw->tw_family != st->family ||
34081 ++ !nx_check(tw->tw_nid, VS_WATCH_P | VS_IDENT))) {
34082 + tw = tw_next(tw);
34083 + }
34084 + if (tw) {
34085 +@@ -2108,6 +2127,11 @@ get_tw:
34086 + sk = sk_next(sk);
34087 +
34088 + sk_for_each_from(sk, node) {
34089 ++ vxdprintk(VXD_CBIT(net, 6),
34090 ++ "sk,egn: %p [#%d] (from %d)",
34091 ++ sk, sk->sk_nid, nx_current_nid());
34092 ++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
34093 ++ continue;
34094 + if (sk->sk_family == st->family)
34095 + goto found;
34096 + }
34097 +@@ -2283,9 +2307,9 @@ static void get_openreq4(struct sock *sk
34098 + sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
34099 + " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p",
34100 + i,
34101 +- ireq->loc_addr,
34102 ++ nx_map_sock_lback(current_nx_info(), ireq->loc_addr),
34103 + ntohs(inet_sk(sk)->sport),
34104 +- ireq->rmt_addr,
34105 ++ nx_map_sock_lback(current_nx_info(), ireq->rmt_addr),
34106 + ntohs(ireq->rmt_port),
34107 + TCP_SYN_RECV,
34108 + 0, 0, /* could print option size, but that is af dependent. */
34109 +@@ -2327,7 +2351,10 @@ static void get_tcp4_sock(struct sock *s
34110 +
34111 + sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
34112 + "%08X %5d %8d %lu %d %p %u %u %u %u %d",
34113 +- i, src, srcp, dest, destp, sk->sk_state,
34114 ++ i,
34115 ++ nx_map_sock_lback(current_nx_info(), src), srcp,
34116 ++ nx_map_sock_lback(current_nx_info(), dest), destp,
34117 ++ sk->sk_state,
34118 + tp->write_seq - tp->snd_una,
34119 + sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog :
34120 + (tp->rcv_nxt - tp->copied_seq),
34121 +@@ -2362,7 +2389,10 @@ static void get_timewait4_sock(struct in
34122 +
34123 + sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
34124 + " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p",
34125 +- i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
34126 ++ i,
34127 ++ nx_map_sock_lback(current_nx_info(), src), srcp,
34128 ++ nx_map_sock_lback(current_nx_info(), dest), destp,
34129 ++ tw->tw_substate, 0, 0,
34130 + 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0,
34131 + atomic_read(&tw->tw_refcnt), tw);
34132 + }
34133 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/tcp_minisocks.c linux-2.6.22.19-vs2.3.0.34/net/ipv4/tcp_minisocks.c
34134 +--- linux-2.6.22.19/net/ipv4/tcp_minisocks.c 2007-07-09 13:20:06 +0200
34135 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv4/tcp_minisocks.c 2007-08-05 20:53:13 +0200
34136 +@@ -28,6 +28,10 @@
34137 + #include <net/inet_common.h>
34138 + #include <net/xfrm.h>
34139 +
34140 ++#include <linux/vs_limit.h>
34141 ++#include <linux/vs_socket.h>
34142 ++#include <linux/vs_context.h>
34143 ++
34144 + #ifdef CONFIG_SYSCTL
34145 + #define SYNC_INIT 0 /* let the user enable it */
34146 + #else
34147 +@@ -293,6 +297,11 @@ void tcp_time_wait(struct sock *sk, int
34148 + tcptw->tw_ts_recent = tp->rx_opt.ts_recent;
34149 + tcptw->tw_ts_recent_stamp = tp->rx_opt.ts_recent_stamp;
34150 +
34151 ++ tw->tw_xid = sk->sk_xid;
34152 ++ tw->tw_vx_info = NULL;
34153 ++ tw->tw_nid = sk->sk_nid;
34154 ++ tw->tw_nx_info = NULL;
34155 ++
34156 + #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
34157 + if (tw->tw_family == PF_INET6) {
34158 + struct ipv6_pinfo *np = inet6_sk(sk);
34159 +diff -NurpP --minimal linux-2.6.22.19/net/ipv4/udp.c linux-2.6.22.19-vs2.3.0.34/net/ipv4/udp.c
34160 +--- linux-2.6.22.19/net/ipv4/udp.c 2007-07-09 13:20:06 +0200
34161 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv4/udp.c 2007-10-09 14:09:19 +0200
34162 +@@ -219,14 +219,7 @@ int udp_get_port(struct sock *sk, unsign
34163 + return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, scmp);
34164 + }
34165 +
34166 +-int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
34167 +-{
34168 +- struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
34169 +-
34170 +- return ( !ipv6_only_sock(sk2) &&
34171 +- (!inet1->rcv_saddr || !inet2->rcv_saddr ||
34172 +- inet1->rcv_saddr == inet2->rcv_saddr ));
34173 +-}
34174 ++extern int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2);
34175 +
34176 + static inline int udp_v4_get_port(struct sock *sk, unsigned short snum)
34177 + {
34178 +@@ -246,15 +239,22 @@ static struct sock *__udp4_lib_lookup(__
34179 + int badness = -1;
34180 +
34181 + read_lock(&udp_hash_lock);
34182 ++
34183 + sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
34184 + struct inet_sock *inet = inet_sk(sk);
34185 +
34186 + if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) {
34187 + int score = (sk->sk_family == PF_INET ? 1 : 0);
34188 ++
34189 + if (inet->rcv_saddr) {
34190 + if (inet->rcv_saddr != daddr)
34191 + continue;
34192 + score+=2;
34193 ++ } else {
34194 ++ /* block non nx_info ips */
34195 ++ if (!v4_addr_in_nx_info(sk->sk_nx_info,
34196 ++ daddr, NXA_MASK_BIND))
34197 ++ continue;
34198 + }
34199 + if (inet->daddr) {
34200 + if (inet->daddr != saddr)
34201 +@@ -280,6 +280,7 @@ static struct sock *__udp4_lib_lookup(__
34202 + }
34203 + }
34204 + }
34205 ++
34206 + if (result)
34207 + sock_hold(result);
34208 + read_unlock(&udp_hash_lock);
34209 +@@ -301,7 +302,7 @@ static inline struct sock *udp_v4_mcast_
34210 + if (s->sk_hash != hnum ||
34211 + (inet->daddr && inet->daddr != rmt_addr) ||
34212 + (inet->dport != rmt_port && inet->dport) ||
34213 +- (inet->rcv_saddr && inet->rcv_saddr != loc_addr) ||
34214 ++ !v4_sock_addr_match(sk->sk_nx_info, inet, loc_addr) ||
34215 + ipv6_only_sock(s) ||
34216 + (s->sk_bound_dev_if && s->sk_bound_dev_if != dif))
34217 + continue;
34218 +@@ -631,7 +632,14 @@ int udp_sendmsg(struct kiocb *iocb, stru
34219 + .uli_u = { .ports =
34220 + { .sport = inet->sport,
34221 + .dport = dport } } };
34222 ++ struct nx_info *nxi = sk->sk_nx_info;
34223 ++
34224 + security_sk_classify_flow(sk, &fl);
34225 ++
34226 ++ err = ip_v4_find_src(nxi, &rt, &fl);
34227 ++ if (err)
34228 ++ goto out;
34229 ++
34230 + err = ip_route_output_flow(&rt, &fl, sk, 1);
34231 + if (err) {
34232 + if (err == -ENETUNREACH)
34233 +@@ -871,7 +879,8 @@ try_again:
34234 + {
34235 + sin->sin_family = AF_INET;
34236 + sin->sin_port = udp_hdr(skb)->source;
34237 +- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
34238 ++ sin->sin_addr.s_addr = nx_map_sock_lback(
34239 ++ skb->sk->sk_nx_info, ip_hdr(skb)->saddr);
34240 + memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
34241 + }
34242 + if (inet->cmsg_flags)
34243 +@@ -1551,7 +1560,8 @@ static struct sock *udp_get_first(struct
34244 + for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
34245 + struct hlist_node *node;
34246 + sk_for_each(sk, node, state->hashtable + state->bucket) {
34247 +- if (sk->sk_family == state->family)
34248 ++ if (sk->sk_family == state->family &&
34249 ++ nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
34250 + goto found;
34251 + }
34252 + }
34253 +@@ -1568,7 +1578,8 @@ static struct sock *udp_get_next(struct
34254 + sk = sk_next(sk);
34255 + try_again:
34256 + ;
34257 +- } while (sk && sk->sk_family != state->family);
34258 ++ } while (sk && (sk->sk_family != state->family ||
34259 ++ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
34260 +
34261 + if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
34262 + sk = sk_head(state->hashtable + state->bucket);
34263 +@@ -1681,7 +1692,10 @@ static void udp4_format_sock(struct sock
34264 +
34265 + sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
34266 + " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
34267 +- bucket, src, srcp, dest, destp, sp->sk_state,
34268 ++ bucket,
34269 ++ nx_map_sock_lback(current_nx_info(), src), srcp,
34270 ++ nx_map_sock_lback(current_nx_info(), dest), destp,
34271 ++ sp->sk_state,
34272 + atomic_read(&sp->sk_wmem_alloc),
34273 + atomic_read(&sp->sk_rmem_alloc),
34274 + 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
34275 +diff -NurpP --minimal linux-2.6.22.19/net/ipv6/Kconfig linux-2.6.22.19-vs2.3.0.34/net/ipv6/Kconfig
34276 +--- linux-2.6.22.19/net/ipv6/Kconfig 2007-07-09 13:20:06 +0200
34277 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv6/Kconfig 2007-08-05 20:53:13 +0200
34278 +@@ -4,8 +4,8 @@
34279 +
34280 + # IPv6 as module will cause a CRASH if you try to unload it
34281 + config IPV6
34282 +- tristate "The IPv6 protocol"
34283 +- default m
34284 ++ bool "The IPv6 protocol"
34285 ++ default n
34286 + ---help---
34287 + This is complemental support for the IP version 6.
34288 + You will still be able to do traditional IPv4 networking as well.
34289 +diff -NurpP --minimal linux-2.6.22.19/net/ipv6/addrconf.c linux-2.6.22.19-vs2.3.0.34/net/ipv6/addrconf.c
34290 +--- linux-2.6.22.19/net/ipv6/addrconf.c 2008-03-14 20:19:05 +0100
34291 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv6/addrconf.c 2008-01-18 12:36:58 +0100
34292 +@@ -86,6 +86,7 @@
34293 +
34294 + #include <linux/proc_fs.h>
34295 + #include <linux/seq_file.h>
34296 ++#include <linux/vs_inet6.h>
34297 +
34298 + /* Set to 3 to get tracing... */
34299 + #define ACONF_DEBUG 2
34300 +@@ -904,7 +905,8 @@ static inline int ipv6_saddr_label(const
34301 + }
34302 +
34303 + int ipv6_dev_get_saddr(struct net_device *daddr_dev,
34304 +- struct in6_addr *daddr, struct in6_addr *saddr)
34305 ++ struct in6_addr *daddr, struct in6_addr *saddr,
34306 ++ struct nx_info *nxi)
34307 + {
34308 + struct ipv6_saddr_score hiscore;
34309 + struct inet6_ifaddr *ifa_result = NULL;
34310 +@@ -949,6 +951,10 @@ int ipv6_dev_get_saddr(struct net_device
34311 +
34312 + score.addr_type = __ipv6_addr_type(&ifa->addr);
34313 +
34314 ++ /* Use only addresses assigned to the context */
34315 ++ if (!v6_ifa_in_nx_info(ifa, nxi))
34316 ++ continue;
34317 ++
34318 + /* Rule 0:
34319 + * - Tentative Address (RFC2462 section 5.4)
34320 + * - A tentative address is not considered
34321 +@@ -1162,9 +1168,10 @@ record_it:
34322 +
34323 +
34324 + int ipv6_get_saddr(struct dst_entry *dst,
34325 +- struct in6_addr *daddr, struct in6_addr *saddr)
34326 ++ struct in6_addr *daddr, struct in6_addr *saddr,
34327 ++ struct nx_info *nxi)
34328 + {
34329 +- return ipv6_dev_get_saddr(dst ? ip6_dst_idev(dst)->dev : NULL, daddr, saddr);
34330 ++ return ipv6_dev_get_saddr(dst ? ip6_dst_idev(dst)->dev : NULL, daddr, saddr, nxi);
34331 + }
34332 +
34333 + EXPORT_SYMBOL(ipv6_get_saddr);
34334 +@@ -1260,35 +1267,46 @@ struct inet6_ifaddr * ipv6_get_ifaddr(st
34335 + return ifp;
34336 + }
34337 +
34338 ++extern int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2);
34339 ++
34340 + int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
34341 + {
34342 + const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
34343 + const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
34344 +- __be32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr;
34345 + __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
34346 + int sk_ipv6only = ipv6_only_sock(sk);
34347 + int sk2_ipv6only = inet_v6_ipv6only(sk2);
34348 + int addr_type = ipv6_addr_type(sk_rcv_saddr6);
34349 + int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED;
34350 +
34351 +- if (!sk2_rcv_saddr && !sk_ipv6only)
34352 ++ /* FIXME: needs handling for v4 ANY */
34353 ++ if (!sk2_rcv_saddr && !sk_ipv6only && !sk2->sk_nx_info)
34354 + return 1;
34355 +
34356 + if (addr_type2 == IPV6_ADDR_ANY &&
34357 +- !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED))
34358 ++ !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED) &&
34359 ++ v6_addr_in_nx_info(sk2->sk_nx_info, sk_rcv_saddr6, -1))
34360 + return 1;
34361 +
34362 + if (addr_type == IPV6_ADDR_ANY &&
34363 +- !(sk_ipv6only && addr_type2 == IPV6_ADDR_MAPPED))
34364 ++ !(sk_ipv6only && addr_type2 == IPV6_ADDR_MAPPED) &&
34365 ++ (sk2_rcv_saddr6 && v6_addr_in_nx_info(sk->sk_nx_info, sk2_rcv_saddr6, -1)))
34366 ++ return 1;
34367 ++
34368 ++ if (addr_type == IPV6_ADDR_ANY &&
34369 ++ addr_type2 == IPV6_ADDR_ANY &&
34370 ++ nx_v6_addr_conflict(sk->sk_nx_info, sk2->sk_nx_info))
34371 + return 1;
34372 +
34373 + if (sk2_rcv_saddr6 &&
34374 ++ addr_type != IPV6_ADDR_ANY &&
34375 ++ addr_type != IPV6_ADDR_ANY &&
34376 + ipv6_addr_equal(sk_rcv_saddr6, sk2_rcv_saddr6))
34377 + return 1;
34378 +
34379 + if (addr_type == IPV6_ADDR_MAPPED &&
34380 + !sk2_ipv6only &&
34381 +- (!sk2_rcv_saddr || !sk_rcv_saddr || sk_rcv_saddr == sk2_rcv_saddr))
34382 ++ ipv4_rcv_saddr_equal(sk, sk2))
34383 + return 1;
34384 +
34385 + return 0;
34386 +@@ -2788,7 +2806,10 @@ static void if6_seq_stop(struct seq_file
34387 + static int if6_seq_show(struct seq_file *seq, void *v)
34388 + {
34389 + struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
34390 +- seq_printf(seq,
34391 ++
34392 ++ if (nx_check(0, VS_ADMIN|VS_WATCH) ||
34393 ++ v6_addr_in_nx_info(current_nx_info(), &ifp->addr, -1))
34394 ++ seq_printf(seq,
34395 + NIP6_SEQFMT " %02x %02x %02x %02x %8s\n",
34396 + NIP6(ifp->addr),
34397 + ifp->idev->dev->ifindex,
34398 +@@ -3270,6 +3291,11 @@ static int inet6_dump_addr(struct sk_buf
34399 + struct inet6_ifaddr *ifa;
34400 + struct ifmcaddr6 *ifmca;
34401 + struct ifacaddr6 *ifaca;
34402 ++ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
34403 ++
34404 ++ /* disable ipv6 on non v6 guests */
34405 ++ if (nxi && !nx_info_has_v6(nxi))
34406 ++ return skb->len;
34407 +
34408 + s_idx = cb->args[0];
34409 + s_ip_idx = ip_idx = cb->args[1];
34410 +@@ -3291,6 +3317,8 @@ static int inet6_dump_addr(struct sk_buf
34411 + ifa = ifa->if_next, ip_idx++) {
34412 + if (ip_idx < s_ip_idx)
34413 + continue;
34414 ++ if (!v6_addr_in_nx_info(nxi, &ifa->addr, -1))
34415 ++ continue;
34416 + if ((err = inet6_fill_ifaddr(skb, ifa,
34417 + NETLINK_CB(cb->skb).pid,
34418 + cb->nlh->nlmsg_seq, RTM_NEWADDR,
34419 +@@ -3304,6 +3332,8 @@ static int inet6_dump_addr(struct sk_buf
34420 + ifmca = ifmca->next, ip_idx++) {
34421 + if (ip_idx < s_ip_idx)
34422 + continue;
34423 ++ if (!v6_addr_in_nx_info(nxi, &ifmca->mca_addr, -1))
34424 ++ continue;
34425 + if ((err = inet6_fill_ifmcaddr(skb, ifmca,
34426 + NETLINK_CB(cb->skb).pid,
34427 + cb->nlh->nlmsg_seq, RTM_GETMULTICAST,
34428 +@@ -3317,6 +3347,8 @@ static int inet6_dump_addr(struct sk_buf
34429 + ifaca = ifaca->aca_next, ip_idx++) {
34430 + if (ip_idx < s_ip_idx)
34431 + continue;
34432 ++ if (!v6_addr_in_nx_info(nxi, &ifaca->aca_addr, -1))
34433 ++ continue;
34434 + if ((err = inet6_fill_ifacaddr(skb, ifaca,
34435 + NETLINK_CB(cb->skb).pid,
34436 + cb->nlh->nlmsg_seq, RTM_GETANYCAST,
34437 +@@ -3593,12 +3625,19 @@ static int inet6_dump_ifinfo(struct sk_b
34438 + int s_idx = cb->args[0];
34439 + struct net_device *dev;
34440 + struct inet6_dev *idev;
34441 ++ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
34442 ++
34443 ++ /* FIXME: maybe disable ipv6 on non v6 guests?
34444 ++ if (skb->sk && skb->sk->sk_vx_info)
34445 ++ return skb->len; */
34446 +
34447 + read_lock(&dev_base_lock);
34448 + idx = 0;
34449 + for_each_netdev(dev) {
34450 + if (idx < s_idx)
34451 + goto cont;
34452 ++ if (!v6_dev_in_nx_info(dev, nxi))
34453 ++ goto cont;
34454 + if ((idev = in6_dev_get(dev)) == NULL)
34455 + goto cont;
34456 + err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid,
34457 +diff -NurpP --minimal linux-2.6.22.19/net/ipv6/af_inet6.c linux-2.6.22.19-vs2.3.0.34/net/ipv6/af_inet6.c
34458 +--- linux-2.6.22.19/net/ipv6/af_inet6.c 2008-03-14 20:19:05 +0100
34459 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv6/af_inet6.c 2007-10-05 12:29:05 +0200
34460 +@@ -43,6 +43,7 @@
34461 + #include <linux/netdevice.h>
34462 + #include <linux/icmpv6.h>
34463 + #include <linux/netfilter_ipv6.h>
34464 ++#include <linux/vs_inet6.h>
34465 +
34466 + #include <net/ip.h>
34467 + #include <net/ipv6.h>
34468 +@@ -150,9 +151,12 @@ lookup_protocol:
34469 + }
34470 +
34471 + err = -EPERM;
34472 ++ if ((protocol == IPPROTO_ICMPV6) &&
34473 ++ nx_capable(answer->capability, NXC_RAW_ICMP))
34474 ++ goto override;
34475 + if (answer->capability > 0 && !capable(answer->capability))
34476 + goto out_rcu_unlock;
34477 +-
34478 ++override:
34479 + sock->ops = answer->ops;
34480 + answer_prot = answer->prot;
34481 + answer_no_check = answer->no_check;
34482 +@@ -250,6 +254,7 @@ int inet6_bind(struct socket *sock, stru
34483 + struct sock *sk = sock->sk;
34484 + struct inet_sock *inet = inet_sk(sk);
34485 + struct ipv6_pinfo *np = inet6_sk(sk);
34486 ++ struct nx_v6_sock_addr nsa;
34487 + __be32 v4addr = 0;
34488 + unsigned short snum;
34489 + int addr_type = 0;
34490 +@@ -261,6 +266,11 @@ int inet6_bind(struct socket *sock, stru
34491 +
34492 + if (addr_len < SIN6_LEN_RFC2133)
34493 + return -EINVAL;
34494 ++
34495 ++ err = v6_map_sock_addr(inet, addr, &nsa);
34496 ++ if (err)
34497 ++ return err;
34498 ++
34499 + addr_type = ipv6_addr_type(&addr->sin6_addr);
34500 + if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
34501 + return -EINVAL;
34502 +@@ -284,6 +294,10 @@ int inet6_bind(struct socket *sock, stru
34503 + err = -EADDRNOTAVAIL;
34504 + goto out;
34505 + }
34506 ++ if (!v4_addr_in_nx_info(sk->sk_nx_info, v4addr, NXA_MASK_BIND)) {
34507 ++ err = -EADDRNOTAVAIL;
34508 ++ goto out;
34509 ++ }
34510 + } else {
34511 + if (addr_type != IPV6_ADDR_ANY) {
34512 + struct net_device *dev = NULL;
34513 +@@ -309,6 +323,11 @@ int inet6_bind(struct socket *sock, stru
34514 + }
34515 + }
34516 +
34517 ++ if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
34518 ++ err = -EADDRNOTAVAIL;
34519 ++ goto out;
34520 ++ }
34521 ++
34522 + /* ipv4 addr of the socket is invalid. Only the
34523 + * unspecified and mapped address have a v4 equivalent.
34524 + */
34525 +@@ -326,6 +345,8 @@ int inet6_bind(struct socket *sock, stru
34526 + }
34527 + }
34528 +
34529 ++ v6_set_sock_addr(inet, &nsa);
34530 ++
34531 + inet->rcv_saddr = v4addr;
34532 + inet->saddr = v4addr;
34533 +
34534 +@@ -420,9 +441,11 @@ int inet6_getname(struct socket *sock, s
34535 + return -ENOTCONN;
34536 + sin->sin6_port = inet->dport;
34537 + ipv6_addr_copy(&sin->sin6_addr, &np->daddr);
34538 ++ /* FIXME: remap lback? */
34539 + if (np->sndflow)
34540 + sin->sin6_flowinfo = np->flow_label;
34541 + } else {
34542 ++ /* FIXME: remap lback? */
34543 + if (ipv6_addr_any(&np->rcv_saddr))
34544 + ipv6_addr_copy(&sin->sin6_addr, &np->saddr);
34545 + else
34546 +diff -NurpP --minimal linux-2.6.22.19/net/ipv6/fib6_rules.c linux-2.6.22.19-vs2.3.0.34/net/ipv6/fib6_rules.c
34547 +--- linux-2.6.22.19/net/ipv6/fib6_rules.c 2007-07-09 13:20:06 +0200
34548 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv6/fib6_rules.c 2007-08-12 00:22:19 +0200
34549 +@@ -107,7 +107,7 @@ static int fib6_rule_action(struct fib_r
34550 + r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) {
34551 + struct in6_addr saddr;
34552 + if (ipv6_get_saddr(&rt->u.dst, &flp->fl6_dst,
34553 +- &saddr))
34554 ++ &saddr, NULL))
34555 + goto again;
34556 + if (!ipv6_prefix_equal(&saddr, &r->src.addr,
34557 + r->src.plen))
34558 +diff -NurpP --minimal linux-2.6.22.19/net/ipv6/inet6_hashtables.c linux-2.6.22.19-vs2.3.0.34/net/ipv6/inet6_hashtables.c
34559 +--- linux-2.6.22.19/net/ipv6/inet6_hashtables.c 2007-05-02 19:25:45 +0200
34560 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv6/inet6_hashtables.c 2007-08-05 20:53:13 +0200
34561 +@@ -16,6 +16,7 @@
34562 +
34563 + #include <linux/module.h>
34564 + #include <linux/random.h>
34565 ++#include <linux/vs_inet6.h>
34566 +
34567 + #include <net/inet_connection_sock.h>
34568 + #include <net/inet_hashtables.h>
34569 +@@ -121,6 +122,9 @@ struct sock *inet6_lookup_listener(struc
34570 + if (!ipv6_addr_equal(&np->rcv_saddr, daddr))
34571 + continue;
34572 + score++;
34573 ++ } else {
34574 ++ if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
34575 ++ continue;
34576 + }
34577 + if (sk->sk_bound_dev_if) {
34578 + if (sk->sk_bound_dev_if != dif)
34579 +diff -NurpP --minimal linux-2.6.22.19/net/ipv6/ip6_output.c linux-2.6.22.19-vs2.3.0.34/net/ipv6/ip6_output.c
34580 +--- linux-2.6.22.19/net/ipv6/ip6_output.c 2008-03-14 20:19:05 +0100
34581 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv6/ip6_output.c 2007-09-30 14:58:01 +0200
34582 +@@ -884,7 +884,7 @@ static int ip6_dst_lookup_tail(struct so
34583 + goto out_err_release;
34584 +
34585 + if (ipv6_addr_any(&fl->fl6_src)) {
34586 +- err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src);
34587 ++ err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src, sk->sk_nx_info);
34588 + if (err)
34589 + goto out_err_release;
34590 + }
34591 +diff -NurpP --minimal linux-2.6.22.19/net/ipv6/ndisc.c linux-2.6.22.19-vs2.3.0.34/net/ipv6/ndisc.c
34592 +--- linux-2.6.22.19/net/ipv6/ndisc.c 2008-03-14 20:19:05 +0100
34593 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv6/ndisc.c 2008-01-18 12:36:58 +0100
34594 +@@ -531,7 +531,7 @@ static void ndisc_send_na(struct net_dev
34595 + override = 0;
34596 + in6_ifa_put(ifp);
34597 + } else {
34598 +- if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr))
34599 ++ if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr, NULL))
34600 + return;
34601 + src_addr = &tmpaddr;
34602 + }
34603 +diff -NurpP --minimal linux-2.6.22.19/net/ipv6/route.c linux-2.6.22.19-vs2.3.0.34/net/ipv6/route.c
34604 +--- linux-2.6.22.19/net/ipv6/route.c 2007-07-09 13:20:06 +0200
34605 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv6/route.c 2008-01-19 01:55:06 +0100
34606 +@@ -2182,7 +2182,7 @@ static int rt6_fill_node(struct sk_buff
34607 + NLA_PUT_U32(skb, RTA_IIF, iif);
34608 + else if (dst) {
34609 + struct in6_addr saddr_buf;
34610 +- if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf) == 0)
34611 ++ if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf, (skb->sk ? skb->sk->sk_nx_info : NULL)) == 0)
34612 + NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
34613 + }
34614 +
34615 +diff -NurpP --minimal linux-2.6.22.19/net/ipv6/tcp_ipv6.c linux-2.6.22.19-vs2.3.0.34/net/ipv6/tcp_ipv6.c
34616 +--- linux-2.6.22.19/net/ipv6/tcp_ipv6.c 2008-03-14 20:19:05 +0100
34617 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv6/tcp_ipv6.c 2008-01-18 12:36:58 +0100
34618 +@@ -68,6 +68,7 @@
34619 +
34620 + #include <linux/crypto.h>
34621 + #include <linux/scatterlist.h>
34622 ++#include <linux/vs_inet6.h>
34623 +
34624 + /* Socket used for sending RSTs and ACKs */
34625 + static struct socket *tcp6_socket;
34626 +@@ -160,8 +161,15 @@ static int tcp_v6_connect(struct sock *s
34627 + * connect() to INADDR_ANY means loopback (BSD'ism).
34628 + */
34629 +
34630 +- if(ipv6_addr_any(&usin->sin6_addr))
34631 +- usin->sin6_addr.s6_addr[15] = 0x1;
34632 ++ if(ipv6_addr_any(&usin->sin6_addr)) {
34633 ++ struct nx_info *nxi = sk->sk_nx_info;
34634 ++
34635 ++ if (nxi && nx_info_has_v6(nxi))
34636 ++ /* FIXME: remap lback? */
34637 ++ usin->sin6_addr = nxi->v6.ip;
34638 ++ else
34639 ++ usin->sin6_addr.s6_addr[15] = 0x1;
34640 ++ }
34641 +
34642 + addr_type = ipv6_addr_type(&usin->sin6_addr);
34643 +
34644 +diff -NurpP --minimal linux-2.6.22.19/net/ipv6/udp.c linux-2.6.22.19-vs2.3.0.34/net/ipv6/udp.c
34645 +--- linux-2.6.22.19/net/ipv6/udp.c 2007-07-09 13:20:06 +0200
34646 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv6/udp.c 2007-08-12 03:34:32 +0200
34647 +@@ -48,6 +48,7 @@
34648 +
34649 + #include <linux/proc_fs.h>
34650 + #include <linux/seq_file.h>
34651 ++#include <linux/vs_inet6.h>
34652 + #include "udp_impl.h"
34653 +
34654 + DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
34655 +@@ -82,6 +83,10 @@ static struct sock *__udp6_lib_lookup(st
34656 + if (!ipv6_addr_equal(&np->rcv_saddr, daddr))
34657 + continue;
34658 + score++;
34659 ++ } else {
34660 ++ /* block non nx_info ips */
34661 ++ if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
34662 ++ continue;
34663 + }
34664 + if (!ipv6_addr_any(&np->daddr)) {
34665 + if (!ipv6_addr_equal(&np->daddr, saddr))
34666 +diff -NurpP --minimal linux-2.6.22.19/net/ipv6/xfrm6_policy.c linux-2.6.22.19-vs2.3.0.34/net/ipv6/xfrm6_policy.c
34667 +--- linux-2.6.22.19/net/ipv6/xfrm6_policy.c 2007-07-09 13:20:06 +0200
34668 ++++ linux-2.6.22.19-vs2.3.0.34/net/ipv6/xfrm6_policy.c 2007-08-12 00:22:19 +0200
34669 +@@ -49,7 +49,7 @@ static int xfrm6_get_saddr(xfrm_address_
34670 +
34671 + if (!xfrm6_dst_lookup((struct xfrm_dst **)&rt, &fl_tunnel)) {
34672 + ipv6_get_saddr(&rt->u.dst, (struct in6_addr *)&daddr->a6,
34673 +- (struct in6_addr *)&saddr->a6);
34674 ++ (struct in6_addr *)&saddr->a6, NULL);
34675 + dst_release(&rt->u.dst);
34676 + return 0;
34677 + }
34678 +diff -NurpP --minimal linux-2.6.22.19/net/netlink/af_netlink.c linux-2.6.22.19-vs2.3.0.34/net/netlink/af_netlink.c
34679 +--- linux-2.6.22.19/net/netlink/af_netlink.c 2008-03-14 20:19:05 +0100
34680 ++++ linux-2.6.22.19-vs2.3.0.34/net/netlink/af_netlink.c 2008-01-18 12:36:58 +0100
34681 +@@ -56,6 +56,9 @@
34682 + #include <linux/audit.h>
34683 + #include <linux/selinux.h>
34684 + #include <linux/mutex.h>
34685 ++#include <linux/vs_context.h>
34686 ++#include <linux/vs_network.h>
34687 ++#include <linux/vs_limit.h>
34688 +
34689 + #include <net/sock.h>
34690 + #include <net/scm.h>
34691 +@@ -885,6 +888,10 @@ static inline int do_one_broadcast(struc
34692 + !test_bit(p->group - 1, nlk->groups))
34693 + goto out;
34694 +
34695 ++ if (sk->sk_nx_info &&
34696 ++ (p->group == RTNLGRP_IPV4_IFADDR || p->group == RTNLGRP_IPV6_IFADDR))
34697 ++ goto out;
34698 ++
34699 + if (p->failure) {
34700 + netlink_overrun(sk);
34701 + goto out;
34702 +diff -NurpP --minimal linux-2.6.22.19/net/rxrpc/Kconfig linux-2.6.22.19-vs2.3.0.34/net/rxrpc/Kconfig
34703 +--- linux-2.6.22.19/net/rxrpc/Kconfig 2008-03-14 20:19:05 +0100
34704 ++++ linux-2.6.22.19-vs2.3.0.34/net/rxrpc/Kconfig 2008-01-18 12:59:53 +0100
34705 +@@ -4,7 +4,7 @@
34706 +
34707 + config AF_RXRPC
34708 + tristate "RxRPC session sockets"
34709 +- depends on INET && EXPERIMENTAL
34710 ++ depends on INET && EXPERIMENTAL && !VSERVER_SECURITY
34711 + select CRYPTO
34712 + select KEYS
34713 + help
34714 +diff -NurpP --minimal linux-2.6.22.19/net/sctp/ipv6.c linux-2.6.22.19-vs2.3.0.34/net/sctp/ipv6.c
34715 +--- linux-2.6.22.19/net/sctp/ipv6.c 2008-03-14 20:19:05 +0100
34716 ++++ linux-2.6.22.19-vs2.3.0.34/net/sctp/ipv6.c 2007-08-12 00:22:19 +0200
34717 +@@ -303,7 +303,7 @@ static void sctp_v6_get_saddr(struct sct
34718 + __FUNCTION__, asoc, dst, NIP6(daddr->v6.sin6_addr));
34719 +
34720 + if (!asoc) {
34721 +- ipv6_get_saddr(dst, &daddr->v6.sin6_addr,&saddr->v6.sin6_addr);
34722 ++ ipv6_get_saddr(dst, &daddr->v6.sin6_addr,&saddr->v6.sin6_addr, asoc->base.sk->sk_nx_info);
34723 + SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: " NIP6_FMT "\n",
34724 + NIP6(saddr->v6.sin6_addr));
34725 + return;
34726 +diff -NurpP --minimal linux-2.6.22.19/net/socket.c linux-2.6.22.19-vs2.3.0.34/net/socket.c
34727 +--- linux-2.6.22.19/net/socket.c 2008-03-14 20:19:05 +0100
34728 ++++ linux-2.6.22.19-vs2.3.0.34/net/socket.c 2008-01-18 12:36:58 +0100
34729 +@@ -92,6 +92,10 @@
34730 +
34731 + #include <net/sock.h>
34732 + #include <linux/netfilter.h>
34733 ++#include <linux/vs_base.h>
34734 ++#include <linux/vs_socket.h>
34735 ++#include <linux/vs_inet.h>
34736 ++#include <linux/vs_inet6.h>
34737 +
34738 + static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
34739 + static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
34740 +@@ -543,7 +547,7 @@ static inline int __sock_sendmsg(struct
34741 + struct msghdr *msg, size_t size)
34742 + {
34743 + struct sock_iocb *si = kiocb_to_siocb(iocb);
34744 +- int err;
34745 ++ int err, len;
34746 +
34747 + si->sock = sock;
34748 + si->scm = NULL;
34749 +@@ -554,7 +558,22 @@ static inline int __sock_sendmsg(struct
34750 + if (err)
34751 + return err;
34752 +
34753 +- return sock->ops->sendmsg(iocb, sock, msg, size);
34754 ++ len = sock->ops->sendmsg(iocb, sock, msg, size);
34755 ++ if (sock->sk) {
34756 ++ if (len == size)
34757 ++ vx_sock_send(sock->sk, size);
34758 ++ else
34759 ++ vx_sock_fail(sock->sk, size);
34760 ++ }
34761 ++ vxdprintk(VXD_CBIT(net, 7),
34762 ++ "__sock_sendmsg: %p[%p,%p,%p;%d/%d]:%d/%d",
34763 ++ sock, sock->sk,
34764 ++ (sock->sk)?sock->sk->sk_nx_info:0,
34765 ++ (sock->sk)?sock->sk->sk_vx_info:0,
34766 ++ (sock->sk)?sock->sk->sk_xid:0,
34767 ++ (sock->sk)?sock->sk->sk_nid:0,
34768 ++ (unsigned int)size, len);
34769 ++ return len;
34770 + }
34771 +
34772 + int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
34773 +@@ -623,7 +642,7 @@ EXPORT_SYMBOL_GPL(__sock_recv_timestamp)
34774 + static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
34775 + struct msghdr *msg, size_t size, int flags)
34776 + {
34777 +- int err;
34778 ++ int err, len;
34779 + struct sock_iocb *si = kiocb_to_siocb(iocb);
34780 +
34781 + si->sock = sock;
34782 +@@ -636,7 +655,18 @@ static inline int __sock_recvmsg(struct
34783 + if (err)
34784 + return err;
34785 +
34786 +- return sock->ops->recvmsg(iocb, sock, msg, size, flags);
34787 ++ len = sock->ops->recvmsg(iocb, sock, msg, size, flags);
34788 ++ if ((len >= 0) && sock->sk)
34789 ++ vx_sock_recv(sock->sk, len);
34790 ++ vxdprintk(VXD_CBIT(net, 7),
34791 ++ "__sock_recvmsg: %p[%p,%p,%p;%d/%d]:%d/%d",
34792 ++ sock, sock->sk,
34793 ++ (sock->sk)?sock->sk->sk_nx_info:0,
34794 ++ (sock->sk)?sock->sk->sk_vx_info:0,
34795 ++ (sock->sk)?sock->sk->sk_xid:0,
34796 ++ (sock->sk)?sock->sk->sk_nid:0,
34797 ++ (unsigned int)size, len);
34798 ++ return len;
34799 + }
34800 +
34801 + int sock_recvmsg(struct socket *sock, struct msghdr *msg,
34802 +@@ -1087,6 +1117,13 @@ static int __sock_create(int family, int
34803 + if (type < 0 || type >= SOCK_MAX)
34804 + return -EINVAL;
34805 +
34806 ++ if (!nx_check(0, VS_ADMIN)) {
34807 ++ if (family == PF_INET && !current_nx_info_has_v4())
34808 ++ return -EAFNOSUPPORT;
34809 ++ if (family == PF_INET6 && !current_nx_info_has_v6())
34810 ++ return -EAFNOSUPPORT;
34811 ++ }
34812 ++
34813 + /* Compatibility.
34814 +
34815 + This uglymoron is moved from INET layer to here to avoid
34816 +@@ -1204,6 +1241,7 @@ asmlinkage long sys_socket(int family, i
34817 + if (retval < 0)
34818 + goto out;
34819 +
34820 ++ set_bit(SOCK_USER_SOCKET, &sock->flags);
34821 + retval = sock_map_fd(sock);
34822 + if (retval < 0)
34823 + goto out_release;
34824 +@@ -1236,10 +1274,12 @@ asmlinkage long sys_socketpair(int famil
34825 + err = sock_create(family, type, protocol, &sock1);
34826 + if (err < 0)
34827 + goto out;
34828 ++ set_bit(SOCK_USER_SOCKET, &sock1->flags);
34829 +
34830 + err = sock_create(family, type, protocol, &sock2);
34831 + if (err < 0)
34832 + goto out_release_1;
34833 ++ set_bit(SOCK_USER_SOCKET, &sock2->flags);
34834 +
34835 + err = sock1->ops->socketpair(sock1, sock2);
34836 + if (err < 0)
34837 +diff -NurpP --minimal linux-2.6.22.19/net/sunrpc/auth.c linux-2.6.22.19-vs2.3.0.34/net/sunrpc/auth.c
34838 +--- linux-2.6.22.19/net/sunrpc/auth.c 2007-05-02 19:25:48 +0200
34839 ++++ linux-2.6.22.19-vs2.3.0.34/net/sunrpc/auth.c 2007-08-05 20:53:13 +0200
34840 +@@ -13,6 +13,7 @@
34841 + #include <linux/errno.h>
34842 + #include <linux/sunrpc/clnt.h>
34843 + #include <linux/spinlock.h>
34844 ++#include <linux/vs_tag.h>
34845 +
34846 + #ifdef RPC_DEBUG
34847 + # define RPCDBG_FACILITY RPCDBG_AUTH
34848 +@@ -263,6 +264,7 @@ rpcauth_lookupcred(struct rpc_auth *auth
34849 + struct auth_cred acred = {
34850 + .uid = current->fsuid,
34851 + .gid = current->fsgid,
34852 ++ .tag = dx_current_tag(),
34853 + .group_info = current->group_info,
34854 + };
34855 + struct rpc_cred *ret;
34856 +@@ -282,6 +284,7 @@ rpcauth_bindcred(struct rpc_task *task)
34857 + struct auth_cred acred = {
34858 + .uid = current->fsuid,
34859 + .gid = current->fsgid,
34860 ++ .tag = dx_current_tag(),
34861 + .group_info = current->group_info,
34862 + };
34863 + struct rpc_cred *ret;
34864 +diff -NurpP --minimal linux-2.6.22.19/net/sunrpc/auth_unix.c linux-2.6.22.19-vs2.3.0.34/net/sunrpc/auth_unix.c
34865 +--- linux-2.6.22.19/net/sunrpc/auth_unix.c 2007-05-02 19:25:48 +0200
34866 ++++ linux-2.6.22.19-vs2.3.0.34/net/sunrpc/auth_unix.c 2007-08-05 20:53:13 +0200
34867 +@@ -11,12 +11,14 @@
34868 + #include <linux/module.h>
34869 + #include <linux/sunrpc/clnt.h>
34870 + #include <linux/sunrpc/auth.h>
34871 ++#include <linux/vs_tag.h>
34872 +
34873 + #define NFS_NGROUPS 16
34874 +
34875 + struct unx_cred {
34876 + struct rpc_cred uc_base;
34877 + gid_t uc_gid;
34878 ++ tag_t uc_tag;
34879 + gid_t uc_gids[NFS_NGROUPS];
34880 + };
34881 + #define uc_uid uc_base.cr_uid
34882 +@@ -79,6 +81,7 @@ unx_create_cred(struct rpc_auth *auth, s
34883 + if (flags & RPCAUTH_LOOKUP_ROOTCREDS) {
34884 + cred->uc_uid = 0;
34885 + cred->uc_gid = 0;
34886 ++ cred->uc_tag = dx_current_tag();
34887 + cred->uc_gids[0] = NOGROUP;
34888 + } else {
34889 + int groups = acred->group_info->ngroups;
34890 +@@ -87,6 +90,7 @@ unx_create_cred(struct rpc_auth *auth, s
34891 +
34892 + cred->uc_uid = acred->uid;
34893 + cred->uc_gid = acred->gid;
34894 ++ cred->uc_tag = acred->tag;
34895 + for (i = 0; i < groups; i++)
34896 + cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
34897 + if (i < NFS_NGROUPS)
34898 +@@ -118,7 +122,8 @@ unx_match(struct auth_cred *acred, struc
34899 + int groups;
34900 +
34901 + if (cred->uc_uid != acred->uid
34902 +- || cred->uc_gid != acred->gid)
34903 ++ || cred->uc_gid != acred->gid
34904 ++ || cred->uc_tag != acred->tag)
34905 + return 0;
34906 +
34907 + groups = acred->group_info->ngroups;
34908 +@@ -144,7 +149,7 @@ unx_marshal(struct rpc_task *task, __be3
34909 + struct rpc_clnt *clnt = task->tk_client;
34910 + struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred;
34911 + __be32 *base, *hold;
34912 +- int i;
34913 ++ int i, tag;
34914 +
34915 + *p++ = htonl(RPC_AUTH_UNIX);
34916 + base = p++;
34917 +@@ -154,9 +159,12 @@ unx_marshal(struct rpc_task *task, __be3
34918 + * Copy the UTS nodename captured when the client was created.
34919 + */
34920 + p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
34921 ++ tag = task->tk_client->cl_tag;
34922 +
34923 +- *p++ = htonl((u32) cred->uc_uid);
34924 +- *p++ = htonl((u32) cred->uc_gid);
34925 ++ *p++ = htonl((u32) TAGINO_UID(tag,
34926 ++ cred->uc_uid, cred->uc_tag));
34927 ++ *p++ = htonl((u32) TAGINO_GID(tag,
34928 ++ cred->uc_gid, cred->uc_tag));
34929 + hold = p++;
34930 + for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++)
34931 + *p++ = htonl((u32) cred->uc_gids[i]);
34932 +diff -NurpP --minimal linux-2.6.22.19/net/sunrpc/clnt.c linux-2.6.22.19-vs2.3.0.34/net/sunrpc/clnt.c
34933 +--- linux-2.6.22.19/net/sunrpc/clnt.c 2007-07-09 13:20:13 +0200
34934 ++++ linux-2.6.22.19-vs2.3.0.34/net/sunrpc/clnt.c 2007-08-05 20:53:13 +0200
34935 +@@ -30,6 +30,7 @@
34936 + #include <linux/smp_lock.h>
34937 + #include <linux/utsname.h>
34938 + #include <linux/workqueue.h>
34939 ++#include <linux/vs_cvirt.h>
34940 +
34941 + #include <linux/sunrpc/clnt.h>
34942 + #include <linux/sunrpc/rpc_pipe_fs.h>
34943 +@@ -249,7 +250,9 @@ struct rpc_clnt *rpc_create(struct rpc_c
34944 + clnt->cl_oneshot = 1;
34945 + if (args->flags & RPC_CLNT_CREATE_DISCRTRY)
34946 + clnt->cl_discrtry = 1;
34947 +-
34948 ++ /* TODO: handle RPC_CLNT_CREATE_TAGGED
34949 ++ if (args->flags & RPC_CLNT_CREATE_TAGGED)
34950 ++ clnt->cl_tag = 1; */
34951 + return clnt;
34952 + }
34953 + EXPORT_SYMBOL_GPL(rpc_create);
34954 +diff -NurpP --minimal linux-2.6.22.19/net/unix/af_unix.c linux-2.6.22.19-vs2.3.0.34/net/unix/af_unix.c
34955 +--- linux-2.6.22.19/net/unix/af_unix.c 2008-03-14 20:19:05 +0100
34956 ++++ linux-2.6.22.19-vs2.3.0.34/net/unix/af_unix.c 2008-01-18 12:36:58 +0100
34957 +@@ -115,6 +115,8 @@
34958 + #include <linux/mount.h>
34959 + #include <net/checksum.h>
34960 + #include <linux/security.h>
34961 ++#include <linux/vs_context.h>
34962 ++#include <linux/vs_limit.h>
34963 +
34964 + int sysctl_unix_max_dgram_qlen __read_mostly = 10;
34965 +
34966 +@@ -252,6 +254,8 @@ static struct sock *__unix_find_socket_b
34967 + sk_for_each(s, node, &unix_socket_table[hash ^ type]) {
34968 + struct unix_sock *u = unix_sk(s);
34969 +
34970 ++ if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT))
34971 ++ continue;
34972 + if (u->addr->len == len &&
34973 + !memcmp(u->addr->name, sunname, len))
34974 + goto found;
34975 +@@ -807,7 +811,7 @@ static int unix_bind(struct socket *sock
34976 + */
34977 + mode = S_IFSOCK |
34978 + (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
34979 +- err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
34980 ++ err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
34981 + if (err)
34982 + goto out_mknod_dput;
34983 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
34984 +diff -NurpP --minimal linux-2.6.22.19/net/x25/af_x25.c linux-2.6.22.19-vs2.3.0.34/net/x25/af_x25.c
34985 +--- linux-2.6.22.19/net/x25/af_x25.c 2007-07-09 13:20:13 +0200
34986 ++++ linux-2.6.22.19-vs2.3.0.34/net/x25/af_x25.c 2007-08-05 20:53:13 +0200
34987 +@@ -500,7 +500,10 @@ static int x25_create(struct socket *soc
34988 +
34989 + x25 = x25_sk(sk);
34990 +
34991 +- sock_init_data(sock, sk);
34992 ++ sk->sk_socket = sock;
34993 ++ sk->sk_type = sock->type;
34994 ++ sk->sk_sleep = &sock->wait;
34995 ++ sock->sk = sk;
34996 +
34997 + x25_init_timers(sk);
34998 +
34999 +diff -NurpP --minimal linux-2.6.22.19/security/Kconfig linux-2.6.22.19-vs2.3.0.34/security/Kconfig
35000 +--- linux-2.6.22.19/security/Kconfig 2006-11-30 21:19:47 +0100
35001 ++++ linux-2.6.22.19-vs2.3.0.34/security/Kconfig 2007-08-05 20:53:13 +0200
35002 +@@ -6,6 +6,7 @@ menu "Security options"
35003 +
35004 + config KEYS
35005 + bool "Enable access key retention support"
35006 ++ depends on !VSERVER_SECURITY
35007 + help
35008 + This option provides support for retaining authentication tokens and
35009 + access keys in the kernel.
35010 +diff -NurpP --minimal linux-2.6.22.19/security/commoncap.c linux-2.6.22.19-vs2.3.0.34/security/commoncap.c
35011 +--- linux-2.6.22.19/security/commoncap.c 2007-07-09 13:20:14 +0200
35012 ++++ linux-2.6.22.19-vs2.3.0.34/security/commoncap.c 2007-08-05 20:53:13 +0200
35013 +@@ -22,10 +22,11 @@
35014 + #include <linux/ptrace.h>
35015 + #include <linux/xattr.h>
35016 + #include <linux/hugetlb.h>
35017 ++#include <linux/vs_context.h>
35018 +
35019 + int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
35020 + {
35021 +- NETLINK_CB(skb).eff_cap = current->cap_effective;
35022 ++ cap_t(NETLINK_CB(skb).eff_cap) = vx_mbcap(cap_effective);
35023 + return 0;
35024 + }
35025 +
35026 +@@ -43,7 +44,7 @@ EXPORT_SYMBOL(cap_netlink_recv);
35027 + int cap_capable (struct task_struct *tsk, int cap)
35028 + {
35029 + /* Derived from include/linux/sched.h:capable. */
35030 +- if (cap_raised(tsk->cap_effective, cap))
35031 ++ if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
35032 + return 0;
35033 + return -EPERM;
35034 + }
35035 +@@ -141,7 +142,8 @@ void cap_bprm_apply_creds (struct linux_
35036 + /* Derived from fs/exec.c:compute_creds. */
35037 + kernel_cap_t new_permitted, working;
35038 +
35039 +- new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
35040 ++ new_permitted = cap_intersect (bprm->cap_permitted,
35041 ++ vx_current_cap_bset());
35042 + working = cap_intersect (bprm->cap_inheritable,
35043 + current->cap_inheritable);
35044 + new_permitted = cap_combine (new_permitted, working);
35045 +@@ -310,7 +312,8 @@ void cap_task_reparent_to_init (struct t
35046 +
35047 + int cap_syslog (int type)
35048 + {
35049 +- if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
35050 ++ if ((type != 3 && type != 10) &&
35051 ++ !vx_capable(CAP_SYS_ADMIN, VXC_SYSLOG))
35052 + return -EPERM;
35053 + return 0;
35054 + }
35055 +diff -NurpP --minimal linux-2.6.22.19/security/dummy.c linux-2.6.22.19-vs2.3.0.34/security/dummy.c
35056 +--- linux-2.6.22.19/security/dummy.c 2007-05-02 19:25:51 +0200
35057 ++++ linux-2.6.22.19-vs2.3.0.34/security/dummy.c 2007-08-05 20:53:13 +0200
35058 +@@ -28,6 +28,7 @@
35059 + #include <linux/hugetlb.h>
35060 + #include <linux/ptrace.h>
35061 + #include <linux/file.h>
35062 ++#include <linux/vs_context.h>
35063 +
35064 + static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
35065 + {
35066 +@@ -678,7 +679,7 @@ static int dummy_sem_semop (struct sem_a
35067 +
35068 + static int dummy_netlink_send (struct sock *sk, struct sk_buff *skb)
35069 + {
35070 +- NETLINK_CB(skb).eff_cap = current->cap_effective;
35071 ++ cap_t(NETLINK_CB(skb).eff_cap) = vx_mbcap(cap_effective);
35072 + return 0;
35073 + }
35074 +
35075 +diff -NurpP --minimal linux-2.6.22.19/security/selinux/hooks.c linux-2.6.22.19-vs2.3.0.34/security/selinux/hooks.c
35076 +--- linux-2.6.22.19/security/selinux/hooks.c 2008-03-14 20:19:05 +0100
35077 ++++ linux-2.6.22.19-vs2.3.0.34/security/selinux/hooks.c 2007-10-30 01:21:54 +0100
35078 +@@ -60,7 +60,6 @@
35079 + #include <linux/dccp.h>
35080 + #include <linux/quota.h>
35081 + #include <linux/un.h> /* for Unix socket types */
35082 +-#include <net/af_unix.h> /* for Unix socket types */
35083 + #include <linux/parser.h>
35084 + #include <linux/nfs_mount.h>
35085 + #include <net/ipv6.h>
35086
35087 --
35088 gentoo-commits@l.g.o mailing list