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 = ¤t_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 = ¤t->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, ®s, 0, NULL, NULL); |
5132 |
++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, |
5133 |
++ 0, ®s, 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, ®s, 0, NULL, NULL); |
5199 |
++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, |
5200 |
++ 0, ®s, 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, ®s, 0, NULL, NULL); |
5239 |
++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, |
5240 |
++ 0, ®s, 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, ®s, 0, NULL, NULL); |
5252 |
++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, |
5253 |
++ 0, ®s, 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, ®s, 0, NULL, NULL); |
5335 |
++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, |
5336 |
++ 0, ®s, 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) (®s->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, ®s.pt, 0, NULL, NULL); |
5530 |
++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, |
5531 |
++ 0, ®s.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, ®s, 0, NULL, |
5602 |
+- NULL); |
5603 |
++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, |
5604 |
++ 0, ®s, 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, ®s, 0, NULL, NULL); |
5753 |
++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, |
5754 |
++ 0, ®s, 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, ®s, 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 |
+ ®s, 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 |
+- ®s, 0, NULL, NULL); |
6334 |
++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD, |
6335 |
++ 0, ®s, 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(¤t->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(¤t->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(¤t->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(¤t->vx_info, NULL); |
17030 |
++ vxis->xid = xchg(¤t->xid, (xid_t)0); |
17031 |
++} |
17032 |
++ |
17033 |
++static inline void __leave_vx_admin(struct vx_info_save *vxis) |
17034 |
++{ |
17035 |
++ (void)xchg(¤t->xid, vxis->xid); |
17036 |
++ (void)xchg(¤t->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(¤t->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, ¤t->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(¤t->fs, fs_new); |
31809 |
++ proxy_new = xchg(¤t->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(¤t->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, ¤t->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, ¤t->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 |