Contents of /trunk/kernel26-alx/patches-2.6.27-r3/0146-2.6.27.47-all-fixes.patch
Parent Directory | Revision Log
Revision 1176 -
(show annotations)
(download)
Thu Oct 14 15:11:06 2010 UTC (13 years, 11 months ago) by niro
File size: 49366 byte(s)
Thu Oct 14 15:11:06 2010 UTC (13 years, 11 months ago) by niro
File size: 49366 byte(s)
-2.6.27-alx-r3: new magellan 0.5.2 kernel
1 | diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c |
2 | index 876e918..f459e3e 100644 |
3 | --- a/arch/x86/kernel/process.c |
4 | +++ b/arch/x86/kernel/process.c |
5 | @@ -283,16 +283,12 @@ static void c1e_idle(void) |
6 | if (!cpu_isset(cpu, c1e_mask)) { |
7 | cpu_set(cpu, c1e_mask); |
8 | /* |
9 | - * Force broadcast so ACPI can not interfere. Needs |
10 | - * to run with interrupts enabled as it uses |
11 | - * smp_function_call. |
12 | + * Force broadcast so ACPI can not interfere. |
13 | */ |
14 | - local_irq_enable(); |
15 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, |
16 | &cpu); |
17 | printk(KERN_INFO "Switch to broadcast mode on CPU%d\n", |
18 | cpu); |
19 | - local_irq_disable(); |
20 | } |
21 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); |
22 | |
23 | diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c |
24 | index 5639e27..94483a2 100644 |
25 | --- a/drivers/acpi/processor_idle.c |
26 | +++ b/drivers/acpi/processor_idle.c |
27 | @@ -317,8 +317,9 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr, |
28 | pr->power.timer_broadcast_on_state = state; |
29 | } |
30 | |
31 | -static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) |
32 | +static void __lapic_timer_propagate_broadcast(void *arg) |
33 | { |
34 | + struct acpi_processor *pr = (struct acpi_processor *) arg; |
35 | unsigned long reason; |
36 | |
37 | reason = pr->power.timer_broadcast_on_state < INT_MAX ? |
38 | @@ -327,6 +328,12 @@ static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) |
39 | clockevents_notify(reason, &pr->id); |
40 | } |
41 | |
42 | +static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) |
43 | +{ |
44 | + smp_call_function_single(pr->id, __lapic_timer_propagate_broadcast, |
45 | + (void *)pr, 1); |
46 | +} |
47 | + |
48 | /* Power(C) State timer broadcast control */ |
49 | static void acpi_state_timer_broadcast(struct acpi_processor *pr, |
50 | struct acpi_processor_cx *cx, |
51 | @@ -347,7 +354,7 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr, |
52 | |
53 | static void acpi_timer_check_state(int state, struct acpi_processor *pr, |
54 | struct acpi_processor_cx *cstate) { } |
55 | -static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) { } |
56 | +static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) { } |
57 | static void acpi_state_timer_broadcast(struct acpi_processor *pr, |
58 | struct acpi_processor_cx *cx, |
59 | int broadcast) |
60 | @@ -1177,7 +1184,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) |
61 | working++; |
62 | } |
63 | |
64 | - acpi_propagate_timer_broadcast(pr); |
65 | + lapic_timer_propagate_broadcast(pr); |
66 | |
67 | return (working); |
68 | } |
69 | diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c |
70 | index 22995d7..9358fa6 100644 |
71 | --- a/drivers/ata/libata-eh.c |
72 | +++ b/drivers/ata/libata-eh.c |
73 | @@ -1497,6 +1497,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) |
74 | } |
75 | |
76 | /* okay, this error is ours */ |
77 | + memset(&tf, 0, sizeof(tf)); |
78 | rc = ata_eh_read_log_10h(dev, &tag, &tf); |
79 | if (rc) { |
80 | ata_link_printk(link, KERN_ERR, "failed to read log page 10h " |
81 | @@ -1900,8 +1901,9 @@ static void ata_eh_link_autopsy(struct ata_link *link) |
82 | qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); |
83 | |
84 | /* determine whether the command is worth retrying */ |
85 | - if (!(qc->err_mask & AC_ERR_INVALID) && |
86 | - ((qc->flags & ATA_QCFLAG_IO) || qc->err_mask != AC_ERR_DEV)) |
87 | + if (qc->flags & ATA_QCFLAG_IO || |
88 | + (!(qc->err_mask & AC_ERR_INVALID) && |
89 | + qc->err_mask != AC_ERR_DEV)) |
90 | qc->flags |= ATA_QCFLAG_RETRY; |
91 | |
92 | /* accumulate error info */ |
93 | diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c |
94 | index e6788f4..f325128 100644 |
95 | --- a/drivers/char/tty_io.c |
96 | +++ b/drivers/char/tty_io.c |
97 | @@ -1893,6 +1893,8 @@ static void release_one_tty(struct tty_struct *tty, int idx) |
98 | list_del_init(&tty->tty_files); |
99 | file_list_unlock(); |
100 | |
101 | + put_pid(tty->pgrp); |
102 | + put_pid(tty->session); |
103 | free_tty_struct(tty); |
104 | } |
105 | |
106 | diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c |
107 | index f942ecd..0af9a2c 100644 |
108 | --- a/drivers/hwmon/w83781d.c |
109 | +++ b/drivers/hwmon/w83781d.c |
110 | @@ -1797,17 +1797,17 @@ static int __init |
111 | w83781d_isa_found(unsigned short address) |
112 | { |
113 | int val, save, found = 0; |
114 | - |
115 | - /* We have to request the region in two parts because some |
116 | - boards declare base+4 to base+7 as a PNP device */ |
117 | - if (!request_region(address, 4, "w83781d")) { |
118 | - pr_debug("w83781d: Failed to request low part of region\n"); |
119 | - return 0; |
120 | - } |
121 | - if (!request_region(address + 4, 4, "w83781d")) { |
122 | - pr_debug("w83781d: Failed to request high part of region\n"); |
123 | - release_region(address, 4); |
124 | - return 0; |
125 | + int port; |
126 | + |
127 | + /* Some boards declare base+0 to base+7 as a PNP device, some base+4 |
128 | + * to base+7 and some base+5 to base+6. So we better request each port |
129 | + * individually for the probing phase. */ |
130 | + for (port = address; port < address + W83781D_EXTENT; port++) { |
131 | + if (!request_region(port, 1, "w83781d")) { |
132 | + pr_debug("w83781d: Failed to request port 0x%x\n", |
133 | + port); |
134 | + goto release; |
135 | + } |
136 | } |
137 | |
138 | #define REALLY_SLOW_IO |
139 | @@ -1881,8 +1881,8 @@ w83781d_isa_found(unsigned short address) |
140 | val == 0x30 ? "W83782D" : "W83781D", (int)address); |
141 | |
142 | release: |
143 | - release_region(address + 4, 4); |
144 | - release_region(address, 4); |
145 | + for (port--; port >= address; port--) |
146 | + release_region(port, 1); |
147 | return found; |
148 | } |
149 | |
150 | diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c |
151 | index dc7ea32..177346e 100644 |
152 | --- a/drivers/i2c/busses/i2c-i801.c |
153 | +++ b/drivers/i2c/busses/i2c-i801.c |
154 | @@ -413,9 +413,11 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, |
155 | data->block[0] = 32; /* max for SMBus block reads */ |
156 | } |
157 | |
158 | + /* Experience has shown that the block buffer can only be used for |
159 | + SMBus (not I2C) block transactions, even though the datasheet |
160 | + doesn't mention this limitation. */ |
161 | if ((i801_features & FEATURE_BLOCK_BUFFER) |
162 | - && !(command == I2C_SMBUS_I2C_BLOCK_DATA |
163 | - && read_write == I2C_SMBUS_READ) |
164 | + && command != I2C_SMBUS_I2C_BLOCK_DATA |
165 | && i801_set_block_buffer_mode() == 0) |
166 | result = i801_block_transaction_by_block(data, read_write, |
167 | hwpec); |
168 | diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c |
169 | index b1c050f..e29b6d5 100644 |
170 | --- a/drivers/i2c/busses/i2c-tiny-usb.c |
171 | +++ b/drivers/i2c/busses/i2c-tiny-usb.c |
172 | @@ -13,6 +13,7 @@ |
173 | #include <linux/kernel.h> |
174 | #include <linux/errno.h> |
175 | #include <linux/module.h> |
176 | +#include <linux/types.h> |
177 | |
178 | /* include interfaces to usb layer */ |
179 | #include <linux/usb.h> |
180 | @@ -31,8 +32,8 @@ |
181 | #define CMD_I2C_IO_END (1<<1) |
182 | |
183 | /* i2c bit delay, default is 10us -> 100kHz */ |
184 | -static int delay = 10; |
185 | -module_param(delay, int, 0); |
186 | +static unsigned short delay = 10; |
187 | +module_param(delay, ushort, 0); |
188 | MODULE_PARM_DESC(delay, "bit delay in microseconds, " |
189 | "e.g. 10 for 100kHz (default is 100kHz)"); |
190 | |
191 | @@ -109,7 +110,7 @@ static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) |
192 | |
193 | static u32 usb_func(struct i2c_adapter *adapter) |
194 | { |
195 | - u32 func; |
196 | + __le32 func; |
197 | |
198 | /* get functionality from adapter */ |
199 | if (usb_read(adapter, CMD_GET_FUNC, 0, 0, &func, sizeof(func)) != |
200 | @@ -118,7 +119,7 @@ static u32 usb_func(struct i2c_adapter *adapter) |
201 | return 0; |
202 | } |
203 | |
204 | - return func; |
205 | + return le32_to_cpu(func); |
206 | } |
207 | |
208 | /* This is the actual algorithm we define */ |
209 | @@ -216,8 +217,7 @@ static int i2c_tiny_usb_probe(struct usb_interface *interface, |
210 | "i2c-tiny-usb at bus %03d device %03d", |
211 | dev->usb_dev->bus->busnum, dev->usb_dev->devnum); |
212 | |
213 | - if (usb_write(&dev->adapter, CMD_SET_DELAY, |
214 | - cpu_to_le16(delay), 0, NULL, 0) != 0) { |
215 | + if (usb_write(&dev->adapter, CMD_SET_DELAY, delay, 0, NULL, 0) != 0) { |
216 | dev_err(&dev->adapter.dev, |
217 | "failure setting delay to %dus\n", delay); |
218 | retval = -EIO; |
219 | diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c |
220 | index 3d3fb00..5ba06d9 100644 |
221 | --- a/drivers/i2c/i2c-core.c |
222 | +++ b/drivers/i2c/i2c-core.c |
223 | @@ -1269,14 +1269,24 @@ static int i2c_detect_address(struct i2c_client *temp_client, int kind, |
224 | |
225 | /* Make sure there is something at this address, unless forced */ |
226 | if (kind < 0) { |
227 | - if (i2c_smbus_xfer(adapter, addr, 0, 0, 0, |
228 | - I2C_SMBUS_QUICK, NULL) < 0) |
229 | - return 0; |
230 | + if (addr == 0x73 && (adapter->class & I2C_CLASS_HWMON)) { |
231 | + /* Special probe for FSC hwmon chips */ |
232 | + union i2c_smbus_data dummy; |
233 | |
234 | - /* prevent 24RF08 corruption */ |
235 | - if ((addr & ~0x0f) == 0x50) |
236 | - i2c_smbus_xfer(adapter, addr, 0, 0, 0, |
237 | - I2C_SMBUS_QUICK, NULL); |
238 | + if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_READ, 0, |
239 | + I2C_SMBUS_BYTE_DATA, &dummy) < 0) |
240 | + return 0; |
241 | + } else { |
242 | + if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0, |
243 | + I2C_SMBUS_QUICK, NULL) < 0) |
244 | + return 0; |
245 | + |
246 | + /* Prevent 24RF08 corruption */ |
247 | + if ((addr & ~0x0f) == 0x50) |
248 | + i2c_smbus_xfer(adapter, addr, 0, |
249 | + I2C_SMBUS_WRITE, 0, |
250 | + I2C_SMBUS_QUICK, NULL); |
251 | + } |
252 | } |
253 | |
254 | /* Finally call the custom detection function */ |
255 | diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c |
256 | index 4c3f124..342df4a 100644 |
257 | --- a/drivers/scsi/megaraid/megaraid_sas.c |
258 | +++ b/drivers/scsi/megaraid/megaraid_sas.c |
259 | @@ -3292,6 +3292,7 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg) |
260 | compat_alloc_user_space(sizeof(struct megasas_iocpacket)); |
261 | int i; |
262 | int error = 0; |
263 | + compat_uptr_t ptr; |
264 | |
265 | if (clear_user(ioc, sizeof(*ioc))) |
266 | return -EFAULT; |
267 | @@ -3304,9 +3305,22 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg) |
268 | copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32))) |
269 | return -EFAULT; |
270 | |
271 | - for (i = 0; i < MAX_IOCTL_SGE; i++) { |
272 | - compat_uptr_t ptr; |
273 | + /* |
274 | + * The sense_ptr is used in megasas_mgmt_fw_ioctl only when |
275 | + * sense_len is not null, so prepare the 64bit value under |
276 | + * the same condition. |
277 | + */ |
278 | + if (ioc->sense_len) { |
279 | + void __user **sense_ioc_ptr = |
280 | + (void __user **)(ioc->frame.raw + ioc->sense_off); |
281 | + compat_uptr_t *sense_cioc_ptr = |
282 | + (compat_uptr_t *)(cioc->frame.raw + cioc->sense_off); |
283 | + if (get_user(ptr, sense_cioc_ptr) || |
284 | + put_user(compat_ptr(ptr), sense_ioc_ptr)) |
285 | + return -EFAULT; |
286 | + } |
287 | |
288 | + for (i = 0; i < MAX_IOCTL_SGE; i++) { |
289 | if (get_user(ptr, &cioc->sgl[i].iov_base) || |
290 | put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) || |
291 | copy_in_user(&ioc->sgl[i].iov_len, |
292 | diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c |
293 | index 83887ff..2c3cdbd 100644 |
294 | --- a/drivers/usb/core/inode.c |
295 | +++ b/drivers/usb/core/inode.c |
296 | @@ -510,13 +510,13 @@ static int fs_create_by_name (const char *name, mode_t mode, |
297 | *dentry = NULL; |
298 | mutex_lock(&parent->d_inode->i_mutex); |
299 | *dentry = lookup_one_len(name, parent, strlen(name)); |
300 | - if (!IS_ERR(dentry)) { |
301 | + if (!IS_ERR(*dentry)) { |
302 | if ((mode & S_IFMT) == S_IFDIR) |
303 | error = usbfs_mkdir (parent->d_inode, *dentry, mode); |
304 | else |
305 | error = usbfs_create (parent->d_inode, *dentry, mode); |
306 | } else |
307 | - error = PTR_ERR(dentry); |
308 | + error = PTR_ERR(*dentry); |
309 | mutex_unlock(&parent->d_inode->i_mutex); |
310 | |
311 | return error; |
312 | diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c |
313 | index 8b7c776..532f8cc 100644 |
314 | --- a/fs/ext4/balloc.c |
315 | +++ b/fs/ext4/balloc.c |
316 | @@ -1754,6 +1754,44 @@ out: |
317 | return ret; |
318 | } |
319 | |
320 | +int ext4_claim_free_blocks(struct ext4_sb_info *sbi, |
321 | + ext4_fsblk_t nblocks) |
322 | +{ |
323 | + s64 free_blocks, dirty_blocks; |
324 | + ext4_fsblk_t root_blocks = 0; |
325 | + struct percpu_counter *fbc = &sbi->s_freeblocks_counter; |
326 | + struct percpu_counter *dbc = &sbi->s_dirtyblocks_counter; |
327 | + |
328 | + free_blocks = percpu_counter_read_positive(fbc); |
329 | + dirty_blocks = percpu_counter_read_positive(dbc); |
330 | + |
331 | + if (!capable(CAP_SYS_RESOURCE) && |
332 | + sbi->s_resuid != current->fsuid && |
333 | + (sbi->s_resgid == 0 || !in_group_p(sbi->s_resgid))) |
334 | + root_blocks = ext4_r_blocks_count(sbi->s_es); |
335 | + |
336 | + if (free_blocks - (nblocks + root_blocks + dirty_blocks) < |
337 | + EXT4_FREEBLOCKS_WATERMARK) { |
338 | + free_blocks = percpu_counter_sum(fbc); |
339 | + dirty_blocks = percpu_counter_sum(dbc); |
340 | + if (dirty_blocks < 0) { |
341 | + printk(KERN_CRIT "Dirty block accounting " |
342 | + "went wrong %lld\n", |
343 | + dirty_blocks); |
344 | + } |
345 | + } |
346 | + /* Check whether we have space after |
347 | + * accounting for current dirty blocks |
348 | + */ |
349 | + if (free_blocks < ((s64)(root_blocks + nblocks) + dirty_blocks)) |
350 | + /* we don't have free space */ |
351 | + return -ENOSPC; |
352 | + |
353 | + /* Add the blocks to nblocks */ |
354 | + percpu_counter_add(dbc, nblocks); |
355 | + return 0; |
356 | +} |
357 | + |
358 | /** |
359 | * ext4_has_free_blocks() |
360 | * @sbi: in-core super block structure. |
361 | @@ -1766,27 +1804,31 @@ out: |
362 | ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi, |
363 | ext4_fsblk_t nblocks) |
364 | { |
365 | - ext4_fsblk_t free_blocks; |
366 | + ext4_fsblk_t free_blocks, dirty_blocks; |
367 | ext4_fsblk_t root_blocks = 0; |
368 | + struct percpu_counter *fbc = &sbi->s_freeblocks_counter; |
369 | + struct percpu_counter *dbc = &sbi->s_dirtyblocks_counter; |
370 | |
371 | - free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); |
372 | + free_blocks = percpu_counter_read_positive(fbc); |
373 | + dirty_blocks = percpu_counter_read_positive(dbc); |
374 | |
375 | if (!capable(CAP_SYS_RESOURCE) && |
376 | sbi->s_resuid != current->fsuid && |
377 | (sbi->s_resgid == 0 || !in_group_p(sbi->s_resgid))) |
378 | root_blocks = ext4_r_blocks_count(sbi->s_es); |
379 | -#ifdef CONFIG_SMP |
380 | - if (free_blocks - root_blocks < FBC_BATCH) |
381 | - free_blocks = |
382 | - percpu_counter_sum_and_set(&sbi->s_freeblocks_counter); |
383 | -#endif |
384 | - if (free_blocks <= root_blocks) |
385 | + |
386 | + if (free_blocks - (nblocks + root_blocks + dirty_blocks) < |
387 | + EXT4_FREEBLOCKS_WATERMARK) { |
388 | + free_blocks = percpu_counter_sum_positive(fbc); |
389 | + dirty_blocks = percpu_counter_sum_positive(dbc); |
390 | + } |
391 | + if (free_blocks <= (root_blocks + dirty_blocks)) |
392 | /* we don't have free space */ |
393 | return 0; |
394 | - if (free_blocks - root_blocks < nblocks) |
395 | + if (free_blocks - (root_blocks + dirty_blocks) < nblocks) |
396 | return free_blocks - root_blocks; |
397 | return nblocks; |
398 | - } |
399 | +} |
400 | |
401 | |
402 | /** |
403 | @@ -1865,14 +1907,17 @@ ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode, |
404 | /* |
405 | * With delalloc we already reserved the blocks |
406 | */ |
407 | - *count = ext4_has_free_blocks(sbi, *count); |
408 | - } |
409 | - if (*count == 0) { |
410 | - *errp = -ENOSPC; |
411 | - return 0; /*return with ENOSPC error */ |
412 | + while (*count && ext4_claim_free_blocks(sbi, *count)) { |
413 | + /* let others to free the space */ |
414 | + yield(); |
415 | + *count = *count >> 1; |
416 | + } |
417 | + if (!*count) { |
418 | + *errp = -ENOSPC; |
419 | + return 0; /*return with ENOSPC error */ |
420 | + } |
421 | + num = *count; |
422 | } |
423 | - num = *count; |
424 | - |
425 | /* |
426 | * Check quota for allocation of this block. |
427 | */ |
428 | @@ -2067,9 +2112,14 @@ allocated: |
429 | le16_add_cpu(&gdp->bg_free_blocks_count, -num); |
430 | gdp->bg_checksum = ext4_group_desc_csum(sbi, group_no, gdp); |
431 | spin_unlock(sb_bgl_lock(sbi, group_no)); |
432 | + percpu_counter_sub(&sbi->s_freeblocks_counter, num); |
433 | + /* |
434 | + * Now reduce the dirty block count also. Should not go negative |
435 | + */ |
436 | if (!EXT4_I(inode)->i_delalloc_reserved_flag) |
437 | - percpu_counter_sub(&sbi->s_freeblocks_counter, num); |
438 | - |
439 | + percpu_counter_sub(&sbi->s_dirtyblocks_counter, *count); |
440 | + else |
441 | + percpu_counter_sub(&sbi->s_dirtyblocks_counter, num); |
442 | if (sbi->s_log_groups_per_flex) { |
443 | ext4_group_t flex_group = ext4_flex_group(sbi, group_no); |
444 | spin_lock(sb_bgl_lock(sbi, flex_group)); |
445 | diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h |
446 | index 1985721..7b666b2 100644 |
447 | --- a/fs/ext4/ext4.h |
448 | +++ b/fs/ext4/ext4.h |
449 | @@ -1015,6 +1015,8 @@ extern ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, |
450 | unsigned long *count, int *errp); |
451 | extern ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode, |
452 | ext4_fsblk_t goal, unsigned long *count, int *errp); |
453 | +extern int ext4_claim_free_blocks(struct ext4_sb_info *sbi, |
454 | + ext4_fsblk_t nblocks); |
455 | extern ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi, |
456 | ext4_fsblk_t nblocks); |
457 | extern void ext4_free_blocks (handle_t *handle, struct inode *inode, |
458 | @@ -1245,6 +1247,17 @@ do { \ |
459 | __ext4_std_error((sb), __func__, (errno)); \ |
460 | } while (0) |
461 | |
462 | +#ifdef CONFIG_SMP |
463 | +/* Each CPU can accumulate FBC_BATCH blocks in their local |
464 | + * counters. So we need to make sure we have free blocks more |
465 | + * than FBC_BATCH * nr_cpu_ids. Also add a window of 4 times. |
466 | + */ |
467 | +#define EXT4_FREEBLOCKS_WATERMARK (4 * (FBC_BATCH * nr_cpu_ids)) |
468 | +#else |
469 | +#define EXT4_FREEBLOCKS_WATERMARK 0 |
470 | +#endif |
471 | + |
472 | + |
473 | /* |
474 | * Inodes and files operations |
475 | */ |
476 | diff --git a/fs/ext4/ext4_sb.h b/fs/ext4/ext4_sb.h |
477 | index f20df8a..6d096d5 100644 |
478 | --- a/fs/ext4/ext4_sb.h |
479 | +++ b/fs/ext4/ext4_sb.h |
480 | @@ -60,6 +60,7 @@ struct ext4_sb_info { |
481 | struct percpu_counter s_freeblocks_counter; |
482 | struct percpu_counter s_freeinodes_counter; |
483 | struct percpu_counter s_dirs_counter; |
484 | + struct percpu_counter s_dirtyblocks_counter; |
485 | struct blockgroup_lock s_blockgroup_lock; |
486 | |
487 | /* root of the per fs reservation window tree */ |
488 | diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c |
489 | index aeebfc2..a67f837 100644 |
490 | --- a/fs/ext4/inode.c |
491 | +++ b/fs/ext4/inode.c |
492 | @@ -1032,19 +1032,20 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used) |
493 | BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); |
494 | mdb_free = EXT4_I(inode)->i_reserved_meta_blocks - mdb; |
495 | |
496 | - /* Account for allocated meta_blocks */ |
497 | - mdb_free -= EXT4_I(inode)->i_allocated_meta_blocks; |
498 | - |
499 | - /* update fs free blocks counter for truncate case */ |
500 | - percpu_counter_add(&sbi->s_freeblocks_counter, mdb_free); |
501 | + if (mdb_free) { |
502 | + /* Account for allocated meta_blocks */ |
503 | + mdb_free -= EXT4_I(inode)->i_allocated_meta_blocks; |
504 | + |
505 | + /* update fs dirty blocks counter */ |
506 | + percpu_counter_sub(&sbi->s_dirtyblocks_counter, mdb_free); |
507 | + EXT4_I(inode)->i_allocated_meta_blocks = 0; |
508 | + EXT4_I(inode)->i_reserved_meta_blocks = mdb; |
509 | + } |
510 | |
511 | /* update per-inode reservations */ |
512 | BUG_ON(used > EXT4_I(inode)->i_reserved_data_blocks); |
513 | EXT4_I(inode)->i_reserved_data_blocks -= used; |
514 | |
515 | - BUG_ON(mdb > EXT4_I(inode)->i_reserved_meta_blocks); |
516 | - EXT4_I(inode)->i_reserved_meta_blocks = mdb; |
517 | - EXT4_I(inode)->i_allocated_meta_blocks = 0; |
518 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); |
519 | |
520 | /* |
521 | @@ -1548,6 +1549,7 @@ static int ext4_journalled_write_end(struct file *file, |
522 | |
523 | static int ext4_da_reserve_space(struct inode *inode, int nrblocks) |
524 | { |
525 | + int retries = 0; |
526 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
527 | unsigned long md_needed, mdblocks, total = 0; |
528 | |
529 | @@ -1556,6 +1558,7 @@ static int ext4_da_reserve_space(struct inode *inode, int nrblocks) |
530 | * in order to allocate nrblocks |
531 | * worse case is one extent per block |
532 | */ |
533 | +repeat: |
534 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); |
535 | total = EXT4_I(inode)->i_reserved_data_blocks + nrblocks; |
536 | mdblocks = ext4_calc_metadata_amount(inode, total); |
537 | @@ -1564,13 +1567,14 @@ static int ext4_da_reserve_space(struct inode *inode, int nrblocks) |
538 | md_needed = mdblocks - EXT4_I(inode)->i_reserved_meta_blocks; |
539 | total = md_needed + nrblocks; |
540 | |
541 | - if (ext4_has_free_blocks(sbi, total) < total) { |
542 | + if (ext4_claim_free_blocks(sbi, total)) { |
543 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); |
544 | + if (ext4_should_retry_alloc(inode->i_sb, &retries)) { |
545 | + yield(); |
546 | + goto repeat; |
547 | + } |
548 | return -ENOSPC; |
549 | } |
550 | - /* reduce fs free blocks counter */ |
551 | - percpu_counter_sub(&sbi->s_freeblocks_counter, total); |
552 | - |
553 | EXT4_I(inode)->i_reserved_data_blocks += nrblocks; |
554 | EXT4_I(inode)->i_reserved_meta_blocks = mdblocks; |
555 | |
556 | @@ -1612,8 +1616,8 @@ static void ext4_da_release_space(struct inode *inode, int to_free) |
557 | |
558 | release = to_free + mdb_free; |
559 | |
560 | - /* update fs free blocks counter for truncate case */ |
561 | - percpu_counter_add(&sbi->s_freeblocks_counter, release); |
562 | + /* update fs dirty blocks counter for truncate case */ |
563 | + percpu_counter_sub(&sbi->s_dirtyblocks_counter, release); |
564 | |
565 | /* update per-inode reservations */ |
566 | BUG_ON(to_free > EXT4_I(inode)->i_reserved_data_blocks); |
567 | @@ -1657,6 +1661,7 @@ struct mpage_da_data { |
568 | struct writeback_control *wbc; |
569 | int io_done; |
570 | long pages_written; |
571 | + int retval; |
572 | }; |
573 | |
574 | /* |
575 | @@ -1694,17 +1699,23 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd) |
576 | |
577 | pagevec_init(&pvec, 0); |
578 | while (index <= end) { |
579 | - nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE); |
580 | + /* |
581 | + * We can use PAGECACHE_TAG_DIRTY lookup here because |
582 | + * even though we have cleared the dirty flag on the page |
583 | + * We still keep the page in the radix tree with tag |
584 | + * PAGECACHE_TAG_DIRTY. See clear_page_dirty_for_io. |
585 | + * The PAGECACHE_TAG_DIRTY is cleared in set_page_writeback |
586 | + * which is called via the below writepage callback. |
587 | + */ |
588 | + nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, |
589 | + PAGECACHE_TAG_DIRTY, |
590 | + min(end - index, |
591 | + (pgoff_t)PAGEVEC_SIZE-1) + 1); |
592 | if (nr_pages == 0) |
593 | break; |
594 | for (i = 0; i < nr_pages; i++) { |
595 | struct page *page = pvec.pages[i]; |
596 | |
597 | - index = page->index; |
598 | - if (index > end) |
599 | - break; |
600 | - index++; |
601 | - |
602 | BUG_ON(!PageLocked(page)); |
603 | BUG_ON(PageWriteback(page)); |
604 | |
605 | @@ -1821,6 +1832,57 @@ static inline void __unmap_underlying_blocks(struct inode *inode, |
606 | unmap_underlying_metadata(bdev, bh->b_blocknr + i); |
607 | } |
608 | |
609 | +static void ext4_da_block_invalidatepages(struct mpage_da_data *mpd, |
610 | + sector_t logical, long blk_cnt) |
611 | +{ |
612 | + int nr_pages, i; |
613 | + pgoff_t index, end; |
614 | + struct pagevec pvec; |
615 | + struct inode *inode = mpd->inode; |
616 | + struct address_space *mapping = inode->i_mapping; |
617 | + |
618 | + index = logical >> (PAGE_CACHE_SHIFT - inode->i_blkbits); |
619 | + end = (logical + blk_cnt - 1) >> |
620 | + (PAGE_CACHE_SHIFT - inode->i_blkbits); |
621 | + while (index <= end) { |
622 | + nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE); |
623 | + if (nr_pages == 0) |
624 | + break; |
625 | + for (i = 0; i < nr_pages; i++) { |
626 | + struct page *page = pvec.pages[i]; |
627 | + index = page->index; |
628 | + if (index > end) |
629 | + break; |
630 | + index++; |
631 | + |
632 | + BUG_ON(!PageLocked(page)); |
633 | + BUG_ON(PageWriteback(page)); |
634 | + block_invalidatepage(page, 0); |
635 | + ClearPageUptodate(page); |
636 | + unlock_page(page); |
637 | + } |
638 | + } |
639 | + return; |
640 | +} |
641 | + |
642 | +static void ext4_print_free_blocks(struct inode *inode) |
643 | +{ |
644 | + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
645 | + printk(KERN_EMERG "Total free blocks count %lld\n", |
646 | + ext4_count_free_blocks(inode->i_sb)); |
647 | + printk(KERN_EMERG "Free/Dirty block details\n"); |
648 | + printk(KERN_EMERG "free_blocks=%lld\n", |
649 | + percpu_counter_sum(&sbi->s_freeblocks_counter)); |
650 | + printk(KERN_EMERG "dirty_blocks=%lld\n", |
651 | + percpu_counter_sum(&sbi->s_dirtyblocks_counter)); |
652 | + printk(KERN_EMERG "Block reservation details\n"); |
653 | + printk(KERN_EMERG "i_reserved_data_blocks=%lu\n", |
654 | + EXT4_I(inode)->i_reserved_data_blocks); |
655 | + printk(KERN_EMERG "i_reserved_meta_blocks=%lu\n", |
656 | + EXT4_I(inode)->i_reserved_meta_blocks); |
657 | + return; |
658 | +} |
659 | + |
660 | /* |
661 | * mpage_da_map_blocks - go through given space |
662 | * |
663 | @@ -1830,32 +1892,69 @@ static inline void __unmap_underlying_blocks(struct inode *inode, |
664 | * The function skips space we know is already mapped to disk blocks. |
665 | * |
666 | */ |
667 | -static void mpage_da_map_blocks(struct mpage_da_data *mpd) |
668 | +static int mpage_da_map_blocks(struct mpage_da_data *mpd) |
669 | { |
670 | int err = 0; |
671 | - struct buffer_head *lbh = &mpd->lbh; |
672 | - sector_t next = lbh->b_blocknr; |
673 | struct buffer_head new; |
674 | + struct buffer_head *lbh = &mpd->lbh; |
675 | + sector_t next; |
676 | |
677 | /* |
678 | * We consider only non-mapped and non-allocated blocks |
679 | */ |
680 | if (buffer_mapped(lbh) && !buffer_delay(lbh)) |
681 | - return; |
682 | - |
683 | + return 0; |
684 | new.b_state = lbh->b_state; |
685 | new.b_blocknr = 0; |
686 | new.b_size = lbh->b_size; |
687 | - |
688 | + next = lbh->b_blocknr; |
689 | /* |
690 | * If we didn't accumulate anything |
691 | * to write simply return |
692 | */ |
693 | if (!new.b_size) |
694 | - return; |
695 | + return 0; |
696 | err = mpd->get_block(mpd->inode, next, &new, 1); |
697 | - if (err) |
698 | - return; |
699 | + if (err) { |
700 | + |
701 | + /* If get block returns with error |
702 | + * we simply return. Later writepage |
703 | + * will redirty the page and writepages |
704 | + * will find the dirty page again |
705 | + */ |
706 | + if (err == -EAGAIN) |
707 | + return 0; |
708 | + |
709 | + if (err == -ENOSPC && |
710 | + ext4_count_free_blocks(mpd->inode->i_sb)) { |
711 | + mpd->retval = err; |
712 | + return 0; |
713 | + } |
714 | + |
715 | + /* |
716 | + * get block failure will cause us |
717 | + * to loop in writepages. Because |
718 | + * a_ops->writepage won't be able to |
719 | + * make progress. The page will be redirtied |
720 | + * by writepage and writepages will again |
721 | + * try to write the same. |
722 | + */ |
723 | + printk(KERN_EMERG "%s block allocation failed for inode %lu " |
724 | + "at logical offset %llu with max blocks " |
725 | + "%zd with error %d\n", |
726 | + __func__, mpd->inode->i_ino, |
727 | + (unsigned long long)next, |
728 | + lbh->b_size >> mpd->inode->i_blkbits, err); |
729 | + printk(KERN_EMERG "This should not happen.!! " |
730 | + "Data will be lost\n"); |
731 | + if (err == -ENOSPC) { |
732 | + ext4_print_free_blocks(mpd->inode); |
733 | + } |
734 | + /* invlaidate all the pages */ |
735 | + ext4_da_block_invalidatepages(mpd, next, |
736 | + lbh->b_size >> mpd->inode->i_blkbits); |
737 | + return err; |
738 | + } |
739 | BUG_ON(new.b_size == 0); |
740 | |
741 | if (buffer_new(&new)) |
742 | @@ -1868,7 +1967,7 @@ static void mpage_da_map_blocks(struct mpage_da_data *mpd) |
743 | if (buffer_delay(lbh) || buffer_unwritten(lbh)) |
744 | mpage_put_bnr_to_bhs(mpd, next, &new); |
745 | |
746 | - return; |
747 | + return 0; |
748 | } |
749 | |
750 | #define BH_FLAGS ((1 << BH_Uptodate) | (1 << BH_Mapped) | \ |
751 | @@ -1937,8 +2036,8 @@ flush_it: |
752 | * We couldn't merge the block to our extent, so we |
753 | * need to flush current extent and start new one |
754 | */ |
755 | - mpage_da_map_blocks(mpd); |
756 | - mpage_da_submit_io(mpd); |
757 | + if (mpage_da_map_blocks(mpd) == 0) |
758 | + mpage_da_submit_io(mpd); |
759 | mpd->io_done = 1; |
760 | return; |
761 | } |
762 | @@ -1980,8 +2079,8 @@ static int __mpage_da_writepage(struct page *page, |
763 | * and start IO on them using writepage() |
764 | */ |
765 | if (mpd->next_page != mpd->first_page) { |
766 | - mpage_da_map_blocks(mpd); |
767 | - mpage_da_submit_io(mpd); |
768 | + if (mpage_da_map_blocks(mpd) == 0) |
769 | + mpage_da_submit_io(mpd); |
770 | /* |
771 | * skip rest of the page in the page_vec |
772 | */ |
773 | @@ -2074,39 +2173,36 @@ static int __mpage_da_writepage(struct page *page, |
774 | */ |
775 | static int mpage_da_writepages(struct address_space *mapping, |
776 | struct writeback_control *wbc, |
777 | - get_block_t get_block) |
778 | + struct mpage_da_data *mpd) |
779 | { |
780 | - struct mpage_da_data mpd; |
781 | long to_write; |
782 | int ret; |
783 | |
784 | - if (!get_block) |
785 | + if (!mpd->get_block) |
786 | return generic_writepages(mapping, wbc); |
787 | |
788 | - mpd.wbc = wbc; |
789 | - mpd.inode = mapping->host; |
790 | - mpd.lbh.b_size = 0; |
791 | - mpd.lbh.b_state = 0; |
792 | - mpd.lbh.b_blocknr = 0; |
793 | - mpd.first_page = 0; |
794 | - mpd.next_page = 0; |
795 | - mpd.get_block = get_block; |
796 | - mpd.io_done = 0; |
797 | - mpd.pages_written = 0; |
798 | + mpd->lbh.b_size = 0; |
799 | + mpd->lbh.b_state = 0; |
800 | + mpd->lbh.b_blocknr = 0; |
801 | + mpd->first_page = 0; |
802 | + mpd->next_page = 0; |
803 | + mpd->io_done = 0; |
804 | + mpd->pages_written = 0; |
805 | + mpd->retval = 0; |
806 | |
807 | to_write = wbc->nr_to_write; |
808 | |
809 | - ret = write_cache_pages(mapping, wbc, __mpage_da_writepage, &mpd); |
810 | + ret = write_cache_pages(mapping, wbc, __mpage_da_writepage, mpd); |
811 | |
812 | /* |
813 | * Handle last extent of pages |
814 | */ |
815 | - if (!mpd.io_done && mpd.next_page != mpd.first_page) { |
816 | - mpage_da_map_blocks(&mpd); |
817 | - mpage_da_submit_io(&mpd); |
818 | + if (!mpd->io_done && mpd->next_page != mpd->first_page) { |
819 | + if (mpage_da_map_blocks(mpd) == 0) |
820 | + mpage_da_submit_io(mpd); |
821 | } |
822 | |
823 | - wbc->nr_to_write = to_write - mpd.pages_written; |
824 | + wbc->nr_to_write = to_write - mpd->pages_written; |
825 | return ret; |
826 | } |
827 | |
828 | @@ -2352,7 +2448,7 @@ static int ext4_da_writepages(struct address_space *mapping, |
829 | struct writeback_control *wbc) |
830 | { |
831 | handle_t *handle = NULL; |
832 | - loff_t range_start = 0; |
833 | + struct mpage_da_data mpd; |
834 | struct inode *inode = mapping->host; |
835 | int needed_blocks, ret = 0, nr_to_writebump = 0; |
836 | long to_write, pages_skipped = 0; |
837 | @@ -2390,16 +2486,12 @@ static int ext4_da_writepages(struct address_space *mapping, |
838 | wbc->nr_to_write = sbi->s_mb_stream_request; |
839 | } |
840 | |
841 | - if (!wbc->range_cyclic) |
842 | - /* |
843 | - * If range_cyclic is not set force range_cont |
844 | - * and save the old writeback_index |
845 | - */ |
846 | - wbc->range_cont = 1; |
847 | |
848 | - range_start = wbc->range_start; |
849 | pages_skipped = wbc->pages_skipped; |
850 | |
851 | + mpd.wbc = wbc; |
852 | + mpd.inode = mapping->host; |
853 | + |
854 | restart_loop: |
855 | to_write = wbc->nr_to_write; |
856 | while (!ret && to_write > 0) { |
857 | @@ -2435,11 +2527,17 @@ restart_loop: |
858 | goto out_writepages; |
859 | } |
860 | } |
861 | - |
862 | to_write -= wbc->nr_to_write; |
863 | - ret = mpage_da_writepages(mapping, wbc, |
864 | - ext4_da_get_block_write); |
865 | + |
866 | + mpd.get_block = ext4_da_get_block_write; |
867 | + ret = mpage_da_writepages(mapping, wbc, &mpd); |
868 | + |
869 | ext4_journal_stop(handle); |
870 | + |
871 | + if (mpd.retval == -ENOSPC) |
872 | + jbd2_journal_force_commit_nested(sbi->s_journal); |
873 | + |
874 | + /* reset the retry count */ |
875 | if (ret == MPAGE_DA_EXTENT_TAIL) { |
876 | /* |
877 | * got one extent now try with |
878 | @@ -2459,9 +2557,8 @@ restart_loop: |
879 | wbc->nr_to_write = to_write; |
880 | } |
881 | |
882 | - if (wbc->range_cont && (pages_skipped != wbc->pages_skipped)) { |
883 | + if (!wbc->range_cyclic && (pages_skipped != wbc->pages_skipped)) { |
884 | /* We skipped pages in this loop */ |
885 | - wbc->range_start = range_start; |
886 | wbc->nr_to_write = to_write + |
887 | wbc->pages_skipped - pages_skipped; |
888 | wbc->pages_skipped = pages_skipped; |
889 | @@ -2470,7 +2567,6 @@ restart_loop: |
890 | |
891 | out_writepages: |
892 | wbc->nr_to_write = to_write - nr_to_writebump; |
893 | - wbc->range_start = range_start; |
894 | return ret; |
895 | } |
896 | |
897 | @@ -2488,7 +2584,6 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping, |
898 | index = pos >> PAGE_CACHE_SHIFT; |
899 | from = pos & (PAGE_CACHE_SIZE - 1); |
900 | to = from + len; |
901 | - |
902 | retry: |
903 | /* |
904 | * With delayed allocation, we don't log the i_disksize update |
905 | diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c |
906 | index c7dc115..453589d 100644 |
907 | --- a/fs/ext4/mballoc.c |
908 | +++ b/fs/ext4/mballoc.c |
909 | @@ -3100,7 +3100,7 @@ void exit_ext4_mballoc(void) |
910 | */ |
911 | static noinline_for_stack int |
912 | ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, |
913 | - handle_t *handle) |
914 | + handle_t *handle, unsigned long reserv_blks) |
915 | { |
916 | struct buffer_head *bitmap_bh = NULL; |
917 | struct ext4_super_block *es; |
918 | @@ -3188,15 +3188,16 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, |
919 | le16_add_cpu(&gdp->bg_free_blocks_count, -ac->ac_b_ex.fe_len); |
920 | gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp); |
921 | spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group)); |
922 | - |
923 | + percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len); |
924 | /* |
925 | - * free blocks account has already be reduced/reserved |
926 | - * at write_begin() time for delayed allocation |
927 | - * do not double accounting |
928 | + * Now reduce the dirty block count also. Should not go negative |
929 | */ |
930 | if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED)) |
931 | - percpu_counter_sub(&sbi->s_freeblocks_counter, |
932 | - ac->ac_b_ex.fe_len); |
933 | + /* release all the reserved blocks if non delalloc */ |
934 | + percpu_counter_sub(&sbi->s_dirtyblocks_counter, reserv_blks); |
935 | + else |
936 | + percpu_counter_sub(&sbi->s_dirtyblocks_counter, |
937 | + ac->ac_b_ex.fe_len); |
938 | |
939 | if (sbi->s_log_groups_per_flex) { |
940 | ext4_group_t flex_group = ext4_flex_group(sbi, |
941 | @@ -4630,12 +4631,13 @@ static int ext4_mb_discard_preallocations(struct super_block *sb, int needed) |
942 | ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, |
943 | struct ext4_allocation_request *ar, int *errp) |
944 | { |
945 | + int freed; |
946 | struct ext4_allocation_context *ac = NULL; |
947 | struct ext4_sb_info *sbi; |
948 | struct super_block *sb; |
949 | ext4_fsblk_t block = 0; |
950 | - int freed; |
951 | - int inquota; |
952 | + unsigned long inquota; |
953 | + unsigned long reserv_blks = 0; |
954 | |
955 | sb = ar->inode->i_sb; |
956 | sbi = EXT4_SB(sb); |
957 | @@ -4649,14 +4651,17 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, |
958 | /* |
959 | * With delalloc we already reserved the blocks |
960 | */ |
961 | - ar->len = ext4_has_free_blocks(sbi, ar->len); |
962 | - } |
963 | - |
964 | - if (ar->len == 0) { |
965 | - *errp = -ENOSPC; |
966 | - return 0; |
967 | + while (ar->len && ext4_claim_free_blocks(sbi, ar->len)) { |
968 | + /* let others to free the space */ |
969 | + yield(); |
970 | + ar->len = ar->len >> 1; |
971 | + } |
972 | + if (!ar->len) { |
973 | + *errp = -ENOSPC; |
974 | + return 0; |
975 | + } |
976 | + reserv_blks = ar->len; |
977 | } |
978 | - |
979 | while (ar->len && DQUOT_ALLOC_BLOCK(ar->inode, ar->len)) { |
980 | ar->flags |= EXT4_MB_HINT_NOPREALLOC; |
981 | ar->len--; |
982 | @@ -4701,7 +4706,7 @@ repeat: |
983 | ext4_mb_new_preallocation(ac); |
984 | } |
985 | if (likely(ac->ac_status == AC_STATUS_FOUND)) { |
986 | - *errp = ext4_mb_mark_diskspace_used(ac, handle); |
987 | + *errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_blks); |
988 | if (*errp == -EAGAIN) { |
989 | /* |
990 | * drop the reference that we took |
991 | diff --git a/fs/ext4/super.c b/fs/ext4/super.c |
992 | index baacaf8..2bca22d 100644 |
993 | --- a/fs/ext4/super.c |
994 | +++ b/fs/ext4/super.c |
995 | @@ -521,6 +521,7 @@ static void ext4_put_super(struct super_block *sb) |
996 | percpu_counter_destroy(&sbi->s_freeblocks_counter); |
997 | percpu_counter_destroy(&sbi->s_freeinodes_counter); |
998 | percpu_counter_destroy(&sbi->s_dirs_counter); |
999 | + percpu_counter_destroy(&sbi->s_dirtyblocks_counter); |
1000 | brelse(sbi->s_sbh); |
1001 | #ifdef CONFIG_QUOTA |
1002 | for (i = 0; i < MAXQUOTAS; i++) |
1003 | @@ -2280,6 +2281,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) |
1004 | err = percpu_counter_init(&sbi->s_dirs_counter, |
1005 | ext4_count_dirs(sb)); |
1006 | } |
1007 | + if (!err) { |
1008 | + err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); |
1009 | + } |
1010 | if (err) { |
1011 | printk(KERN_ERR "EXT4-fs: insufficient memory\n"); |
1012 | goto failed_mount3; |
1013 | @@ -2517,6 +2521,7 @@ failed_mount3: |
1014 | percpu_counter_destroy(&sbi->s_freeblocks_counter); |
1015 | percpu_counter_destroy(&sbi->s_freeinodes_counter); |
1016 | percpu_counter_destroy(&sbi->s_dirs_counter); |
1017 | + percpu_counter_destroy(&sbi->s_dirtyblocks_counter); |
1018 | failed_mount2: |
1019 | for (i = 0; i < db_count; i++) |
1020 | brelse(sbi->s_group_desc[i]); |
1021 | @@ -3208,7 +3213,8 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) |
1022 | buf->f_type = EXT4_SUPER_MAGIC; |
1023 | buf->f_bsize = sb->s_blocksize; |
1024 | buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; |
1025 | - buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter); |
1026 | + buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter) - |
1027 | + percpu_counter_sum_positive(&sbi->s_dirtyblocks_counter); |
1028 | ext4_free_blocks_count_set(es, buf->f_bfree); |
1029 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); |
1030 | if (buf->f_bfree < ext4_r_blocks_count(es)) |
1031 | diff --git a/fs/nfs/client.c b/fs/nfs/client.c |
1032 | index 9d6a0e4..710645c 100644 |
1033 | --- a/fs/nfs/client.c |
1034 | +++ b/fs/nfs/client.c |
1035 | @@ -826,6 +826,8 @@ out_error: |
1036 | static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source) |
1037 | { |
1038 | target->flags = source->flags; |
1039 | + target->rsize = source->rsize; |
1040 | + target->wsize = source->wsize; |
1041 | target->acregmin = source->acregmin; |
1042 | target->acregmax = source->acregmax; |
1043 | target->acdirmin = source->acdirmin; |
1044 | diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c |
1045 | index e195f67..ee7ed21 100644 |
1046 | --- a/fs/nfs/dir.c |
1047 | +++ b/fs/nfs/dir.c |
1048 | @@ -826,6 +826,8 @@ out_zap_parent: |
1049 | /* If we have submounts, don't unhash ! */ |
1050 | if (have_submounts(dentry)) |
1051 | goto out_valid; |
1052 | + if (dentry->d_flags & DCACHE_DISCONNECTED) |
1053 | + goto out_valid; |
1054 | shrink_dcache_parent(dentry); |
1055 | } |
1056 | d_drop(dentry); |
1057 | diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c |
1058 | index abffc90..6203c81 100644 |
1059 | --- a/fs/nfsd/nfs4xdr.c |
1060 | +++ b/fs/nfsd/nfs4xdr.c |
1061 | @@ -179,10 +179,10 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes) |
1062 | argp->p = page_address(argp->pagelist[0]); |
1063 | argp->pagelist++; |
1064 | if (argp->pagelen < PAGE_SIZE) { |
1065 | - argp->end = p + (argp->pagelen>>2); |
1066 | + argp->end = argp->p + (argp->pagelen>>2); |
1067 | argp->pagelen = 0; |
1068 | } else { |
1069 | - argp->end = p + (PAGE_SIZE>>2); |
1070 | + argp->end = argp->p + (PAGE_SIZE>>2); |
1071 | argp->pagelen -= PAGE_SIZE; |
1072 | } |
1073 | memcpy(((char*)p)+avail, argp->p, (nbytes - avail)); |
1074 | @@ -1115,10 +1115,10 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) |
1075 | argp->p = page_address(argp->pagelist[0]); |
1076 | argp->pagelist++; |
1077 | if (argp->pagelen < PAGE_SIZE) { |
1078 | - argp->end = p + (argp->pagelen>>2); |
1079 | + argp->end = argp->p + (argp->pagelen>>2); |
1080 | argp->pagelen = 0; |
1081 | } else { |
1082 | - argp->end = p + (PAGE_SIZE>>2); |
1083 | + argp->end = argp->p + (PAGE_SIZE>>2); |
1084 | argp->pagelen -= PAGE_SIZE; |
1085 | } |
1086 | } |
1087 | diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h |
1088 | index 2083888..9007ccd 100644 |
1089 | --- a/include/linux/percpu_counter.h |
1090 | +++ b/include/linux/percpu_counter.h |
1091 | @@ -35,7 +35,7 @@ int percpu_counter_init_irq(struct percpu_counter *fbc, s64 amount); |
1092 | void percpu_counter_destroy(struct percpu_counter *fbc); |
1093 | void percpu_counter_set(struct percpu_counter *fbc, s64 amount); |
1094 | void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch); |
1095 | -s64 __percpu_counter_sum(struct percpu_counter *fbc, int set); |
1096 | +s64 __percpu_counter_sum(struct percpu_counter *fbc); |
1097 | |
1098 | static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) |
1099 | { |
1100 | @@ -44,19 +44,13 @@ static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) |
1101 | |
1102 | static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc) |
1103 | { |
1104 | - s64 ret = __percpu_counter_sum(fbc, 0); |
1105 | + s64 ret = __percpu_counter_sum(fbc); |
1106 | return ret < 0 ? 0 : ret; |
1107 | } |
1108 | |
1109 | -static inline s64 percpu_counter_sum_and_set(struct percpu_counter *fbc) |
1110 | -{ |
1111 | - return __percpu_counter_sum(fbc, 1); |
1112 | -} |
1113 | - |
1114 | - |
1115 | static inline s64 percpu_counter_sum(struct percpu_counter *fbc) |
1116 | { |
1117 | - return __percpu_counter_sum(fbc, 0); |
1118 | + return __percpu_counter_sum(fbc); |
1119 | } |
1120 | |
1121 | static inline s64 percpu_counter_read(struct percpu_counter *fbc) |
1122 | diff --git a/include/linux/security.h b/include/linux/security.h |
1123 | index 1638afd..0601e71 100644 |
1124 | --- a/include/linux/security.h |
1125 | +++ b/include/linux/security.h |
1126 | @@ -1590,6 +1590,7 @@ int security_syslog(int type); |
1127 | int security_settime(struct timespec *ts, struct timezone *tz); |
1128 | int security_vm_enough_memory(long pages); |
1129 | int security_vm_enough_memory_mm(struct mm_struct *mm, long pages); |
1130 | +int security_vm_enough_memory_kern(long pages); |
1131 | int security_bprm_alloc(struct linux_binprm *bprm); |
1132 | void security_bprm_free(struct linux_binprm *bprm); |
1133 | void security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe); |
1134 | @@ -1822,14 +1823,23 @@ static inline int security_settime(struct timespec *ts, struct timezone *tz) |
1135 | |
1136 | static inline int security_vm_enough_memory(long pages) |
1137 | { |
1138 | + WARN_ON(current->mm == NULL); |
1139 | return cap_vm_enough_memory(current->mm, pages); |
1140 | } |
1141 | |
1142 | static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) |
1143 | { |
1144 | + WARN_ON(mm == NULL); |
1145 | return cap_vm_enough_memory(mm, pages); |
1146 | } |
1147 | |
1148 | +static inline int security_vm_enough_memory_kern(long pages) |
1149 | +{ |
1150 | + /* If current->mm is a kernel thread then we will pass NULL, |
1151 | + for this specific case that is fine */ |
1152 | + return cap_vm_enough_memory(current->mm, pages); |
1153 | +} |
1154 | + |
1155 | static inline int security_bprm_alloc(struct linux_binprm *bprm) |
1156 | { |
1157 | return 0; |
1158 | diff --git a/include/linux/writeback.h b/include/linux/writeback.h |
1159 | index c2835bb..cc0e6d9 100644 |
1160 | --- a/include/linux/writeback.h |
1161 | +++ b/include/linux/writeback.h |
1162 | @@ -62,7 +62,6 @@ struct writeback_control { |
1163 | unsigned for_writepages:1; /* This is a writepages() call */ |
1164 | unsigned range_cyclic:1; /* range_start is cyclic */ |
1165 | unsigned more_io:1; /* more io to be dispatched */ |
1166 | - unsigned range_cont:1; |
1167 | }; |
1168 | |
1169 | /* |
1170 | diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c |
1171 | index f8d9680..ae51d5e 100644 |
1172 | --- a/kernel/time/clockevents.c |
1173 | +++ b/kernel/time/clockevents.c |
1174 | @@ -124,11 +124,12 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires, |
1175 | */ |
1176 | int clockevents_register_notifier(struct notifier_block *nb) |
1177 | { |
1178 | + unsigned long flags; |
1179 | int ret; |
1180 | |
1181 | - spin_lock(&clockevents_lock); |
1182 | + spin_lock_irqsave(&clockevents_lock, flags); |
1183 | ret = raw_notifier_chain_register(&clockevents_chain, nb); |
1184 | - spin_unlock(&clockevents_lock); |
1185 | + spin_unlock_irqrestore(&clockevents_lock, flags); |
1186 | |
1187 | return ret; |
1188 | } |
1189 | @@ -165,6 +166,8 @@ static void clockevents_notify_released(void) |
1190 | */ |
1191 | void clockevents_register_device(struct clock_event_device *dev) |
1192 | { |
1193 | + unsigned long flags; |
1194 | + |
1195 | BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED); |
1196 | /* |
1197 | * A nsec2cyc multiplicator of 0 is invalid and we'd crash |
1198 | @@ -175,13 +178,13 @@ void clockevents_register_device(struct clock_event_device *dev) |
1199 | WARN_ON(1); |
1200 | } |
1201 | |
1202 | - spin_lock(&clockevents_lock); |
1203 | + spin_lock_irqsave(&clockevents_lock, flags); |
1204 | |
1205 | list_add(&dev->list, &clockevent_devices); |
1206 | clockevents_do_notify(CLOCK_EVT_NOTIFY_ADD, dev); |
1207 | clockevents_notify_released(); |
1208 | |
1209 | - spin_unlock(&clockevents_lock); |
1210 | + spin_unlock_irqrestore(&clockevents_lock, flags); |
1211 | } |
1212 | |
1213 | /* |
1214 | @@ -228,8 +231,9 @@ void clockevents_exchange_device(struct clock_event_device *old, |
1215 | void clockevents_notify(unsigned long reason, void *arg) |
1216 | { |
1217 | struct list_head *node, *tmp; |
1218 | + unsigned long flags; |
1219 | |
1220 | - spin_lock(&clockevents_lock); |
1221 | + spin_lock_irqsave(&clockevents_lock, flags); |
1222 | clockevents_do_notify(reason, arg); |
1223 | |
1224 | switch (reason) { |
1225 | @@ -244,7 +248,7 @@ void clockevents_notify(unsigned long reason, void *arg) |
1226 | default: |
1227 | break; |
1228 | } |
1229 | - spin_unlock(&clockevents_lock); |
1230 | + spin_unlock_irqrestore(&clockevents_lock, flags); |
1231 | } |
1232 | EXPORT_SYMBOL_GPL(clockevents_notify); |
1233 | #endif |
1234 | diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c |
1235 | index cb01cd8..d1b3216 100644 |
1236 | --- a/kernel/time/tick-broadcast.c |
1237 | +++ b/kernel/time/tick-broadcast.c |
1238 | @@ -205,11 +205,11 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev) |
1239 | * Powerstate information: The system enters/leaves a state, where |
1240 | * affected devices might stop |
1241 | */ |
1242 | -static void tick_do_broadcast_on_off(void *why) |
1243 | +static void tick_do_broadcast_on_off(unsigned long *reason) |
1244 | { |
1245 | struct clock_event_device *bc, *dev; |
1246 | struct tick_device *td; |
1247 | - unsigned long flags, *reason = why; |
1248 | + unsigned long flags; |
1249 | int cpu, bc_stopped; |
1250 | |
1251 | spin_lock_irqsave(&tick_broadcast_lock, flags); |
1252 | @@ -276,8 +276,7 @@ void tick_broadcast_on_off(unsigned long reason, int *oncpu) |
1253 | printk(KERN_ERR "tick-broadcast: ignoring broadcast for " |
1254 | "offline CPU #%d\n", *oncpu); |
1255 | else |
1256 | - smp_call_function_single(*oncpu, tick_do_broadcast_on_off, |
1257 | - &reason, 1); |
1258 | + tick_do_broadcast_on_off(&reason); |
1259 | } |
1260 | |
1261 | /* |
1262 | diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c |
1263 | index 8f3fb3d..dfe3995 100644 |
1264 | --- a/kernel/trace/trace.c |
1265 | +++ b/kernel/trace/trace.c |
1266 | @@ -3018,7 +3018,6 @@ static int trace_free_page(void) |
1267 | ClearPageLRU(page); |
1268 | list_del(&page->lru); |
1269 | tracing_pages_allocated--; |
1270 | - tracing_pages_allocated--; |
1271 | __free_page(page); |
1272 | |
1273 | tracing_reset(data); |
1274 | @@ -3036,6 +3035,7 @@ static int trace_free_page(void) |
1275 | page = list_entry(p, struct page, lru); |
1276 | ClearPageLRU(page); |
1277 | list_del(&page->lru); |
1278 | + tracing_pages_allocated--; |
1279 | __free_page(page); |
1280 | |
1281 | tracing_reset(data); |
1282 | diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c |
1283 | index 4a8ba4b..a866389 100644 |
1284 | --- a/lib/percpu_counter.c |
1285 | +++ b/lib/percpu_counter.c |
1286 | @@ -52,7 +52,7 @@ EXPORT_SYMBOL(__percpu_counter_add); |
1287 | * Add up all the per-cpu counts, return the result. This is a more accurate |
1288 | * but much slower version of percpu_counter_read_positive() |
1289 | */ |
1290 | -s64 __percpu_counter_sum(struct percpu_counter *fbc, int set) |
1291 | +s64 __percpu_counter_sum(struct percpu_counter *fbc) |
1292 | { |
1293 | s64 ret; |
1294 | int cpu; |
1295 | @@ -62,11 +62,9 @@ s64 __percpu_counter_sum(struct percpu_counter *fbc, int set) |
1296 | for_each_online_cpu(cpu) { |
1297 | s32 *pcount = per_cpu_ptr(fbc->counters, cpu); |
1298 | ret += *pcount; |
1299 | - if (set) |
1300 | - *pcount = 0; |
1301 | + *pcount = 0; |
1302 | } |
1303 | - if (set) |
1304 | - fbc->count = ret; |
1305 | + fbc->count = ret; |
1306 | |
1307 | spin_unlock(&fbc->lock); |
1308 | return ret; |
1309 | diff --git a/mm/mmap.c b/mm/mmap.c |
1310 | index 8b5aa8e..f3e5bfe 100644 |
1311 | --- a/mm/mmap.c |
1312 | +++ b/mm/mmap.c |
1313 | @@ -178,7 +178,8 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) |
1314 | |
1315 | /* Don't let a single process grow too big: |
1316 | leave 3% of the size of this process for other processes */ |
1317 | - allowed -= mm->total_vm / 32; |
1318 | + if (mm) |
1319 | + allowed -= mm->total_vm / 32; |
1320 | |
1321 | /* |
1322 | * cast `allowed' as a signed long because vm_committed_space |
1323 | diff --git a/mm/nommu.c b/mm/nommu.c |
1324 | index 4bf7686..7122331 100644 |
1325 | --- a/mm/nommu.c |
1326 | +++ b/mm/nommu.c |
1327 | @@ -1432,7 +1432,8 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) |
1328 | |
1329 | /* Don't let a single process grow too big: |
1330 | leave 3% of the size of this process for other processes */ |
1331 | - allowed -= current->mm->total_vm / 32; |
1332 | + if (mm) |
1333 | + allowed -= mm->total_vm / 32; |
1334 | |
1335 | /* |
1336 | * cast `allowed' as a signed long because vm_committed_space |
1337 | diff --git a/mm/page-writeback.c b/mm/page-writeback.c |
1338 | index 5f7cdc2..e5c4ca2 100644 |
1339 | --- a/mm/page-writeback.c |
1340 | +++ b/mm/page-writeback.c |
1341 | @@ -1027,8 +1027,6 @@ continue_unlock: |
1342 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) |
1343 | mapping->writeback_index = done_index; |
1344 | |
1345 | - if (wbc->range_cont) |
1346 | - wbc->range_start = index << PAGE_CACHE_SHIFT; |
1347 | return ret; |
1348 | } |
1349 | EXPORT_SYMBOL(write_cache_pages); |
1350 | diff --git a/mm/shmem.c b/mm/shmem.c |
1351 | index 04fb4f1..c088da1 100644 |
1352 | --- a/mm/shmem.c |
1353 | +++ b/mm/shmem.c |
1354 | @@ -163,8 +163,8 @@ static inline struct shmem_sb_info *SHMEM_SB(struct super_block *sb) |
1355 | */ |
1356 | static inline int shmem_acct_size(unsigned long flags, loff_t size) |
1357 | { |
1358 | - return (flags & VM_ACCOUNT)? |
1359 | - security_vm_enough_memory(VM_ACCT(size)): 0; |
1360 | + return (flags & VM_ACCOUNT) ? |
1361 | + security_vm_enough_memory_kern(VM_ACCT(size)) : 0; |
1362 | } |
1363 | |
1364 | static inline void shmem_unacct_size(unsigned long flags, loff_t size) |
1365 | @@ -181,8 +181,8 @@ static inline void shmem_unacct_size(unsigned long flags, loff_t size) |
1366 | */ |
1367 | static inline int shmem_acct_block(unsigned long flags) |
1368 | { |
1369 | - return (flags & VM_ACCOUNT)? |
1370 | - 0: security_vm_enough_memory(VM_ACCT(PAGE_CACHE_SIZE)); |
1371 | + return (flags & VM_ACCOUNT) ? |
1372 | + 0 : security_vm_enough_memory_kern(VM_ACCT(PAGE_CACHE_SIZE)); |
1373 | } |
1374 | |
1375 | static inline void shmem_unacct_blocks(unsigned long flags, long pages) |
1376 | diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c |
1377 | index e46c825..4c772de 100644 |
1378 | --- a/net/sunrpc/svc_xprt.c |
1379 | +++ b/net/sunrpc/svc_xprt.c |
1380 | @@ -810,6 +810,11 @@ static void svc_age_temp_xprts(unsigned long closure) |
1381 | void svc_delete_xprt(struct svc_xprt *xprt) |
1382 | { |
1383 | struct svc_serv *serv = xprt->xpt_server; |
1384 | + struct svc_deferred_req *dr; |
1385 | + |
1386 | + /* Only do this once */ |
1387 | + if (test_and_set_bit(XPT_DEAD, &xprt->xpt_flags)) |
1388 | + return; |
1389 | |
1390 | dprintk("svc: svc_delete_xprt(%p)\n", xprt); |
1391 | xprt->xpt_ops->xpo_detach(xprt); |
1392 | @@ -824,12 +829,16 @@ void svc_delete_xprt(struct svc_xprt *xprt) |
1393 | * while still attached to a queue, the queue itself |
1394 | * is about to be destroyed (in svc_destroy). |
1395 | */ |
1396 | - if (!test_and_set_bit(XPT_DEAD, &xprt->xpt_flags)) { |
1397 | - BUG_ON(atomic_read(&xprt->xpt_ref.refcount) < 2); |
1398 | - if (test_bit(XPT_TEMP, &xprt->xpt_flags)) |
1399 | - serv->sv_tmpcnt--; |
1400 | + if (test_bit(XPT_TEMP, &xprt->xpt_flags)) |
1401 | + serv->sv_tmpcnt--; |
1402 | + |
1403 | + for (dr = svc_deferred_dequeue(xprt); dr; |
1404 | + dr = svc_deferred_dequeue(xprt)) { |
1405 | svc_xprt_put(xprt); |
1406 | + kfree(dr); |
1407 | } |
1408 | + |
1409 | + svc_xprt_put(xprt); |
1410 | spin_unlock_bh(&serv->sv_lock); |
1411 | } |
1412 | |
1413 | @@ -875,17 +884,19 @@ static void svc_revisit(struct cache_deferred_req *dreq, int too_many) |
1414 | container_of(dreq, struct svc_deferred_req, handle); |
1415 | struct svc_xprt *xprt = dr->xprt; |
1416 | |
1417 | - if (too_many) { |
1418 | + spin_lock(&xprt->xpt_lock); |
1419 | + set_bit(XPT_DEFERRED, &xprt->xpt_flags); |
1420 | + if (too_many || test_bit(XPT_DEAD, &xprt->xpt_flags)) { |
1421 | + spin_unlock(&xprt->xpt_lock); |
1422 | + dprintk("revisit canceled\n"); |
1423 | svc_xprt_put(xprt); |
1424 | kfree(dr); |
1425 | return; |
1426 | } |
1427 | dprintk("revisit queued\n"); |
1428 | dr->xprt = NULL; |
1429 | - spin_lock(&xprt->xpt_lock); |
1430 | list_add(&dr->handle.recent, &xprt->xpt_deferred); |
1431 | spin_unlock(&xprt->xpt_lock); |
1432 | - set_bit(XPT_DEFERRED, &xprt->xpt_flags); |
1433 | svc_xprt_enqueue(xprt); |
1434 | svc_xprt_put(xprt); |
1435 | } |
1436 | diff --git a/security/security.c b/security/security.c |
1437 | index 27a315d..50b61ae 100644 |
1438 | --- a/security/security.c |
1439 | +++ b/security/security.c |
1440 | @@ -195,14 +195,23 @@ int security_settime(struct timespec *ts, struct timezone *tz) |
1441 | |
1442 | int security_vm_enough_memory(long pages) |
1443 | { |
1444 | + WARN_ON(current->mm == NULL); |
1445 | return security_ops->vm_enough_memory(current->mm, pages); |
1446 | } |
1447 | |
1448 | int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) |
1449 | { |
1450 | + WARN_ON(mm == NULL); |
1451 | return security_ops->vm_enough_memory(mm, pages); |
1452 | } |
1453 | |
1454 | +int security_vm_enough_memory_kern(long pages) |
1455 | +{ |
1456 | + /* If current->mm is a kernel thread then we will pass NULL, |
1457 | + for this specific case that is fine */ |
1458 | + return security_ops->vm_enough_memory(current->mm, pages); |
1459 | +} |
1460 | + |
1461 | int security_bprm_alloc(struct linux_binprm *bprm) |
1462 | { |
1463 | return security_ops->bprm_alloc_security(bprm); |
1464 | diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c |
1465 | index 7e83131..62ebff5 100644 |
1466 | --- a/sound/pci/mixart/mixart.c |
1467 | +++ b/sound/pci/mixart/mixart.c |
1468 | @@ -1160,13 +1160,15 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private |
1469 | unsigned long count, unsigned long pos) |
1470 | { |
1471 | struct mixart_mgr *mgr = entry->private_data; |
1472 | + unsigned long maxsize; |
1473 | |
1474 | - count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ |
1475 | - if(count <= 0) |
1476 | + if (pos >= MIXART_BA0_SIZE) |
1477 | return 0; |
1478 | - if(pos + count > MIXART_BA0_SIZE) |
1479 | - count = (long)(MIXART_BA0_SIZE - pos); |
1480 | - if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count)) |
1481 | + maxsize = MIXART_BA0_SIZE - pos; |
1482 | + if (count > maxsize) |
1483 | + count = maxsize; |
1484 | + count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ |
1485 | + if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count)) |
1486 | return -EFAULT; |
1487 | return count; |
1488 | } |
1489 | @@ -1179,13 +1181,15 @@ static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private |
1490 | unsigned long count, unsigned long pos) |
1491 | { |
1492 | struct mixart_mgr *mgr = entry->private_data; |
1493 | + unsigned long maxsize; |
1494 | |
1495 | - count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ |
1496 | - if(count <= 0) |
1497 | + if (pos > MIXART_BA1_SIZE) |
1498 | return 0; |
1499 | - if(pos + count > MIXART_BA1_SIZE) |
1500 | - count = (long)(MIXART_BA1_SIZE - pos); |
1501 | - if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count)) |
1502 | + maxsize = MIXART_BA1_SIZE - pos; |
1503 | + if (count > maxsize) |
1504 | + count = maxsize; |
1505 | + count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ |
1506 | + if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count)) |
1507 | return -EFAULT; |
1508 | return count; |
1509 | } |