Magellan Linux

Annotation of /trunk/kernel-mcore/patches-3.0-r2/0107-3.0.8-all-fixes.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1560 - (hide annotations) (download)
Thu Nov 10 14:21:33 2011 UTC (12 years, 7 months ago) by niro
File size: 44427 byte(s)
3.0-mcore-r2, updated to linux-3.0.8
1 niro 1560 diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
2     index 4960686..4372763 100644
3     --- a/arch/arm/kernel/perf_event_v7.c
4     +++ b/arch/arm/kernel/perf_event_v7.c
5     @@ -264,8 +264,8 @@ static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
6     [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
7     [PERF_COUNT_HW_INSTRUCTIONS] =
8     ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE,
9     - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_COHERENT_LINE_HIT,
10     - [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_COHERENT_LINE_MISS,
11     + [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_DCACHE_ACCESS,
12     + [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_DCACHE_REFILL,
13     [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
14     [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
15     [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
16     diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
17     index c19571c..4a4eba5 100644
18     --- a/arch/arm/mm/init.c
19     +++ b/arch/arm/mm/init.c
20     @@ -473,6 +473,13 @@ static void __init free_unused_memmap(struct meminfo *mi)
21     */
22     bank_start = min(bank_start,
23     ALIGN(prev_bank_end, PAGES_PER_SECTION));
24     +#else
25     + /*
26     + * Align down here since the VM subsystem insists that the
27     + * memmap entries are valid from the bank start aligned to
28     + * MAX_ORDER_NR_PAGES.
29     + */
30     + bank_start = round_down(bank_start, MAX_ORDER_NR_PAGES);
31     #endif
32     /*
33     * If we had a previous bank, and there is a space
34     diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
35     index 3032644..87488b9 100644
36     --- a/arch/x86/mm/init.c
37     +++ b/arch/x86/mm/init.c
38     @@ -63,9 +63,8 @@ static void __init find_early_table_space(unsigned long end, int use_pse,
39     #ifdef CONFIG_X86_32
40     /* for fixmap */
41     tables += roundup(__end_of_fixed_addresses * sizeof(pte_t), PAGE_SIZE);
42     -
43     - good_end = max_pfn_mapped << PAGE_SHIFT;
44     #endif
45     + good_end = max_pfn_mapped << PAGE_SHIFT;
46    
47     base = memblock_find_in_range(start, good_end, tables, PAGE_SIZE);
48     if (base == MEMBLOCK_ERROR)
49     diff --git a/crypto/ghash-generic.c b/crypto/ghash-generic.c
50     index be44256..7835b8f 100644
51     --- a/crypto/ghash-generic.c
52     +++ b/crypto/ghash-generic.c
53     @@ -67,6 +67,9 @@ static int ghash_update(struct shash_desc *desc,
54     struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
55     u8 *dst = dctx->buffer;
56    
57     + if (!ctx->gf128)
58     + return -ENOKEY;
59     +
60     if (dctx->bytes) {
61     int n = min(srclen, dctx->bytes);
62     u8 *pos = dst + (GHASH_BLOCK_SIZE - dctx->bytes);
63     @@ -119,6 +122,9 @@ static int ghash_final(struct shash_desc *desc, u8 *dst)
64     struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
65     u8 *buf = dctx->buffer;
66    
67     + if (!ctx->gf128)
68     + return -ENOKEY;
69     +
70     ghash_flush(ctx, dctx);
71     memcpy(dst, buf, GHASH_BLOCK_SIZE);
72    
73     diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
74     index 41841a3..17cef86 100644
75     --- a/drivers/firewire/sbp2.c
76     +++ b/drivers/firewire/sbp2.c
77     @@ -1198,6 +1198,10 @@ static int sbp2_remove(struct device *dev)
78     {
79     struct fw_unit *unit = fw_unit(dev);
80     struct sbp2_target *tgt = dev_get_drvdata(&unit->device);
81     + struct sbp2_logical_unit *lu;
82     +
83     + list_for_each_entry(lu, &tgt->lu_list, link)
84     + cancel_delayed_work_sync(&lu->work);
85    
86     sbp2_target_put(tgt);
87     return 0;
88     diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
89     index ebdb0fd..9a0aee2 100644
90     --- a/drivers/gpu/drm/radeon/atom.c
91     +++ b/drivers/gpu/drm/radeon/atom.c
92     @@ -277,7 +277,12 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
93     case ATOM_ARG_FB:
94     idx = U8(*ptr);
95     (*ptr)++;
96     - val = gctx->scratch[((gctx->fb_base + idx) / 4)];
97     + if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) {
98     + DRM_ERROR("ATOM: fb read beyond scratch region: %d vs. %d\n",
99     + gctx->fb_base + (idx * 4), gctx->scratch_size_bytes);
100     + val = 0;
101     + } else
102     + val = gctx->scratch[(gctx->fb_base / 4) + idx];
103     if (print)
104     DEBUG("FB[0x%02X]", idx);
105     break;
106     @@ -531,7 +536,11 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr,
107     case ATOM_ARG_FB:
108     idx = U8(*ptr);
109     (*ptr)++;
110     - gctx->scratch[((gctx->fb_base + idx) / 4)] = val;
111     + if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) {
112     + DRM_ERROR("ATOM: fb write beyond scratch region: %d vs. %d\n",
113     + gctx->fb_base + (idx * 4), gctx->scratch_size_bytes);
114     + } else
115     + gctx->scratch[(gctx->fb_base / 4) + idx] = val;
116     DEBUG("FB[0x%02X]", idx);
117     break;
118     case ATOM_ARG_PLL:
119     @@ -1367,11 +1376,13 @@ int atom_allocate_fb_scratch(struct atom_context *ctx)
120    
121     usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
122     }
123     + ctx->scratch_size_bytes = 0;
124     if (usage_bytes == 0)
125     usage_bytes = 20 * 1024;
126     /* allocate some scratch memory */
127     ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
128     if (!ctx->scratch)
129     return -ENOMEM;
130     + ctx->scratch_size_bytes = usage_bytes;
131     return 0;
132     }
133     diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h
134     index a589a55..93cfe20 100644
135     --- a/drivers/gpu/drm/radeon/atom.h
136     +++ b/drivers/gpu/drm/radeon/atom.h
137     @@ -137,6 +137,7 @@ struct atom_context {
138     int cs_equal, cs_above;
139     int io_mode;
140     uint32_t *scratch;
141     + int scratch_size_bytes;
142     };
143    
144     extern int atom_debug;
145     diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
146     index b7f0726..e2b2d78 100644
147     --- a/drivers/gpu/drm/ttm/ttm_bo.c
148     +++ b/drivers/gpu/drm/ttm/ttm_bo.c
149     @@ -392,10 +392,12 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
150     * Create and bind a ttm if required.
151     */
152    
153     - if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED) && (bo->ttm == NULL)) {
154     - ret = ttm_bo_add_ttm(bo, false);
155     - if (ret)
156     - goto out_err;
157     + if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) {
158     + if (bo->ttm == NULL) {
159     + ret = ttm_bo_add_ttm(bo, false);
160     + if (ret)
161     + goto out_err;
162     + }
163    
164     ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement);
165     if (ret)
166     diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
167     index 77dbf40..ae3c6f5 100644
168     --- a/drivers/gpu/drm/ttm/ttm_bo_util.c
169     +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
170     @@ -635,13 +635,13 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
171     if (ret)
172     return ret;
173    
174     - ttm_bo_free_old_node(bo);
175     if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
176     (bo->ttm != NULL)) {
177     ttm_tt_unbind(bo->ttm);
178     ttm_tt_destroy(bo->ttm);
179     bo->ttm = NULL;
180     }
181     + ttm_bo_free_old_node(bo);
182     } else {
183     /**
184     * This should help pipeline ordinary buffer moves.
185     diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
186     index a756ee6..c946d90 100644
187     --- a/drivers/hid/hid-ids.h
188     +++ b/drivers/hid/hid-ids.h
189     @@ -568,6 +568,9 @@
190     #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
191     #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600
192    
193     +#define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f
194     +#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002
195     +
196     #define USB_VENDOR_ID_SKYCABLE 0x1223
197     #define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07
198    
199     diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
200     index 0ec91c1..56d0539 100644
201     --- a/drivers/hid/hid-magicmouse.c
202     +++ b/drivers/hid/hid-magicmouse.c
203     @@ -501,9 +501,17 @@ static int magicmouse_probe(struct hid_device *hdev,
204     }
205     report->size = 6;
206    
207     + /*
208     + * Some devices repond with 'invalid report id' when feature
209     + * report switching it into multitouch mode is sent to it.
210     + *
211     + * This results in -EIO from the _raw low-level transport callback,
212     + * but there seems to be no other way of switching the mode.
213     + * Thus the super-ugly hacky success check below.
214     + */
215     ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature),
216     HID_FEATURE_REPORT);
217     - if (ret != sizeof(feature)) {
218     + if (ret != -EIO && ret != sizeof(feature)) {
219     hid_err(hdev, "unable to request touch data (%d)\n", ret);
220     goto err_stop_hw;
221     }
222     diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
223     index 621959d..4bdb5d4 100644
224     --- a/drivers/hid/usbhid/hid-quirks.c
225     +++ b/drivers/hid/usbhid/hid-quirks.c
226     @@ -89,6 +89,7 @@ static const struct hid_blacklist {
227    
228     { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT },
229     { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },
230     + { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },
231     { 0, 0 }
232     };
233    
234     diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
235     index f2b377c..36d7f27 100644
236     --- a/drivers/hwmon/w83627ehf.c
237     +++ b/drivers/hwmon/w83627ehf.c
238     @@ -390,7 +390,7 @@ temp_from_reg(u16 reg, s16 regval)
239     {
240     if (is_word_sized(reg))
241     return LM75_TEMP_FROM_REG(regval);
242     - return regval * 1000;
243     + return ((s8)regval) * 1000;
244     }
245    
246     static inline u16
247     @@ -398,7 +398,8 @@ temp_to_reg(u16 reg, long temp)
248     {
249     if (is_word_sized(reg))
250     return LM75_TEMP_TO_REG(temp);
251     - return DIV_ROUND_CLOSEST(SENSORS_LIMIT(temp, -127000, 128000), 1000);
252     + return (s8)DIV_ROUND_CLOSEST(SENSORS_LIMIT(temp, -127000, 128000),
253     + 1000);
254     }
255    
256     /* Some of analog inputs have internal scaling (2x), 8mV is ADC LSB */
257     @@ -1715,7 +1716,8 @@ static void w83627ehf_device_remove_files(struct device *dev)
258     }
259    
260     /* Get the monitoring functions started */
261     -static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data)
262     +static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data,
263     + enum kinds kind)
264     {
265     int i;
266     u8 tmp, diode;
267     @@ -1746,10 +1748,16 @@ static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data)
268     w83627ehf_write_value(data, W83627EHF_REG_VBAT, tmp | 0x01);
269    
270     /* Get thermal sensor types */
271     - diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE);
272     + switch (kind) {
273     + case w83627ehf:
274     + diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE);
275     + break;
276     + default:
277     + diode = 0x70;
278     + }
279     for (i = 0; i < 3; i++) {
280     if ((tmp & (0x02 << i)))
281     - data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 2;
282     + data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 3;
283     else
284     data->temp_type[i] = 4; /* thermistor */
285     }
286     @@ -2016,7 +2024,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
287     }
288    
289     /* Initialize the chip */
290     - w83627ehf_init_device(data);
291     + w83627ehf_init_device(data, sio_data->kind);
292    
293     data->vrm = vid_which_vrm();
294     superio_enter(sio_data->sioreg);
295     diff --git a/drivers/media/video/uvc/uvc_entity.c b/drivers/media/video/uvc/uvc_entity.c
296     index 48fea37..29e2399 100644
297     --- a/drivers/media/video/uvc/uvc_entity.c
298     +++ b/drivers/media/video/uvc/uvc_entity.c
299     @@ -49,7 +49,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
300     if (remote == NULL)
301     return -EINVAL;
302    
303     - source = (UVC_ENTITY_TYPE(remote) != UVC_TT_STREAMING)
304     + source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING)
305     ? (remote->vdev ? &remote->vdev->entity : NULL)
306     : &remote->subdev.entity;
307     if (source == NULL)
308     diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c
309     index d347116..1658575 100644
310     --- a/drivers/platform/x86/samsung-laptop.c
311     +++ b/drivers/platform/x86/samsung-laptop.c
312     @@ -601,6 +601,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
313     .callback = dmi_check_cb,
314     },
315     {
316     + .ident = "N150/N210/N220",
317     + .matches = {
318     + DMI_MATCH(DMI_SYS_VENDOR,
319     + "SAMSUNG ELECTRONICS CO., LTD."),
320     + DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"),
321     + DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"),
322     + },
323     + .callback = dmi_check_cb,
324     + },
325     + {
326     .ident = "N150/N210/N220/N230",
327     .matches = {
328     DMI_MATCH(DMI_SYS_VENDOR,
329     diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
330     index fc7e57b..53e7d72 100644
331     --- a/fs/cifs/cifsfs.c
332     +++ b/fs/cifs/cifsfs.c
333     @@ -566,6 +566,12 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
334     struct inode *dir = dentry->d_inode;
335     struct dentry *child;
336    
337     + if (!dir) {
338     + dput(dentry);
339     + dentry = ERR_PTR(-ENOENT);
340     + break;
341     + }
342     +
343     /* skip separators */
344     while (*s == sep)
345     s++;
346     @@ -581,10 +587,6 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
347     mutex_unlock(&dir->i_mutex);
348     dput(dentry);
349     dentry = child;
350     - if (!dentry->d_inode) {
351     - dput(dentry);
352     - dentry = ERR_PTR(-ENOENT);
353     - }
354     } while (!IS_ERR(dentry));
355     _FreeXid(xid);
356     kfree(full_path);
357     diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
358     index 168a80f..5cb8614 100644
359     --- a/fs/fuse/dev.c
360     +++ b/fs/fuse/dev.c
361     @@ -258,10 +258,14 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
362     forget->forget_one.nlookup = nlookup;
363    
364     spin_lock(&fc->lock);
365     - fc->forget_list_tail->next = forget;
366     - fc->forget_list_tail = forget;
367     - wake_up(&fc->waitq);
368     - kill_fasync(&fc->fasync, SIGIO, POLL_IN);
369     + if (fc->connected) {
370     + fc->forget_list_tail->next = forget;
371     + fc->forget_list_tail = forget;
372     + wake_up(&fc->waitq);
373     + kill_fasync(&fc->fasync, SIGIO, POLL_IN);
374     + } else {
375     + kfree(forget);
376     + }
377     spin_unlock(&fc->lock);
378     }
379    
380     diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
381     index d685752..4e7f64b 100644
382     --- a/fs/hfsplus/hfsplus_fs.h
383     +++ b/fs/hfsplus/hfsplus_fs.h
384     @@ -13,6 +13,7 @@
385     #include <linux/fs.h>
386     #include <linux/mutex.h>
387     #include <linux/buffer_head.h>
388     +#include <linux/blkdev.h>
389     #include "hfsplus_raw.h"
390    
391     #define DBG_BNODE_REFS 0x00000001
392     @@ -110,7 +111,9 @@ struct hfsplus_vh;
393     struct hfs_btree;
394    
395     struct hfsplus_sb_info {
396     + void *s_vhdr_buf;
397     struct hfsplus_vh *s_vhdr;
398     + void *s_backup_vhdr_buf;
399     struct hfsplus_vh *s_backup_vhdr;
400     struct hfs_btree *ext_tree;
401     struct hfs_btree *cat_tree;
402     @@ -258,6 +261,15 @@ struct hfsplus_readdir_data {
403     struct hfsplus_cat_key key;
404     };
405    
406     +/*
407     + * Find minimum acceptible I/O size for an hfsplus sb.
408     + */
409     +static inline unsigned short hfsplus_min_io_size(struct super_block *sb)
410     +{
411     + return max_t(unsigned short, bdev_logical_block_size(sb->s_bdev),
412     + HFSPLUS_SECTOR_SIZE);
413     +}
414     +
415     #define hfs_btree_open hfsplus_btree_open
416     #define hfs_btree_close hfsplus_btree_close
417     #define hfs_btree_write hfsplus_btree_write
418     @@ -436,8 +448,8 @@ int hfsplus_compare_dentry(const struct dentry *parent,
419     /* wrapper.c */
420     int hfsplus_read_wrapper(struct super_block *);
421     int hfs_part_find(struct super_block *, sector_t *, sector_t *);
422     -int hfsplus_submit_bio(struct block_device *bdev, sector_t sector,
423     - void *data, int rw);
424     +int hfsplus_submit_bio(struct super_block *sb, sector_t sector,
425     + void *buf, void **data, int rw);
426    
427     /* time macros */
428     #define __hfsp_mt2ut(t) (be32_to_cpu(t) - 2082844800U)
429     diff --git a/fs/hfsplus/part_tbl.c b/fs/hfsplus/part_tbl.c
430     index 40ad88c..eb355d8 100644
431     --- a/fs/hfsplus/part_tbl.c
432     +++ b/fs/hfsplus/part_tbl.c
433     @@ -88,11 +88,12 @@ static int hfs_parse_old_pmap(struct super_block *sb, struct old_pmap *pm,
434     return -ENOENT;
435     }
436    
437     -static int hfs_parse_new_pmap(struct super_block *sb, struct new_pmap *pm,
438     - sector_t *part_start, sector_t *part_size)
439     +static int hfs_parse_new_pmap(struct super_block *sb, void *buf,
440     + struct new_pmap *pm, sector_t *part_start, sector_t *part_size)
441     {
442     struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
443     int size = be32_to_cpu(pm->pmMapBlkCnt);
444     + int buf_size = hfsplus_min_io_size(sb);
445     int res;
446     int i = 0;
447    
448     @@ -107,11 +108,14 @@ static int hfs_parse_new_pmap(struct super_block *sb, struct new_pmap *pm,
449     if (++i >= size)
450     return -ENOENT;
451    
452     - res = hfsplus_submit_bio(sb->s_bdev,
453     - *part_start + HFS_PMAP_BLK + i,
454     - pm, READ);
455     - if (res)
456     - return res;
457     + pm = (struct new_pmap *)((u8 *)pm + HFSPLUS_SECTOR_SIZE);
458     + if ((u8 *)pm - (u8 *)buf >= buf_size) {
459     + res = hfsplus_submit_bio(sb,
460     + *part_start + HFS_PMAP_BLK + i,
461     + buf, (void **)&pm, READ);
462     + if (res)
463     + return res;
464     + }
465     } while (pm->pmSig == cpu_to_be16(HFS_NEW_PMAP_MAGIC));
466    
467     return -ENOENT;
468     @@ -124,15 +128,15 @@ static int hfs_parse_new_pmap(struct super_block *sb, struct new_pmap *pm,
469     int hfs_part_find(struct super_block *sb,
470     sector_t *part_start, sector_t *part_size)
471     {
472     - void *data;
473     + void *buf, *data;
474     int res;
475    
476     - data = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL);
477     - if (!data)
478     + buf = kmalloc(hfsplus_min_io_size(sb), GFP_KERNEL);
479     + if (!buf)
480     return -ENOMEM;
481    
482     - res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK,
483     - data, READ);
484     + res = hfsplus_submit_bio(sb, *part_start + HFS_PMAP_BLK,
485     + buf, &data, READ);
486     if (res)
487     goto out;
488    
489     @@ -141,13 +145,13 @@ int hfs_part_find(struct super_block *sb,
490     res = hfs_parse_old_pmap(sb, data, part_start, part_size);
491     break;
492     case HFS_NEW_PMAP_MAGIC:
493     - res = hfs_parse_new_pmap(sb, data, part_start, part_size);
494     + res = hfs_parse_new_pmap(sb, buf, data, part_start, part_size);
495     break;
496     default:
497     res = -ENOENT;
498     break;
499     }
500     out:
501     - kfree(data);
502     + kfree(buf);
503     return res;
504     }
505     diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
506     index 84a47b7..c3a76fd 100644
507     --- a/fs/hfsplus/super.c
508     +++ b/fs/hfsplus/super.c
509     @@ -197,17 +197,17 @@ int hfsplus_sync_fs(struct super_block *sb, int wait)
510     write_backup = 1;
511     }
512    
513     - error2 = hfsplus_submit_bio(sb->s_bdev,
514     + error2 = hfsplus_submit_bio(sb,
515     sbi->part_start + HFSPLUS_VOLHEAD_SECTOR,
516     - sbi->s_vhdr, WRITE_SYNC);
517     + sbi->s_vhdr_buf, NULL, WRITE_SYNC);
518     if (!error)
519     error = error2;
520     if (!write_backup)
521     goto out;
522    
523     - error2 = hfsplus_submit_bio(sb->s_bdev,
524     + error2 = hfsplus_submit_bio(sb,
525     sbi->part_start + sbi->sect_count - 2,
526     - sbi->s_backup_vhdr, WRITE_SYNC);
527     + sbi->s_backup_vhdr_buf, NULL, WRITE_SYNC);
528     if (!error)
529     error2 = error;
530     out:
531     @@ -251,8 +251,8 @@ static void hfsplus_put_super(struct super_block *sb)
532     hfs_btree_close(sbi->ext_tree);
533     iput(sbi->alloc_file);
534     iput(sbi->hidden_dir);
535     - kfree(sbi->s_vhdr);
536     - kfree(sbi->s_backup_vhdr);
537     + kfree(sbi->s_vhdr_buf);
538     + kfree(sbi->s_backup_vhdr_buf);
539     unload_nls(sbi->nls);
540     kfree(sb->s_fs_info);
541     sb->s_fs_info = NULL;
542     @@ -508,8 +508,8 @@ out_close_cat_tree:
543     out_close_ext_tree:
544     hfs_btree_close(sbi->ext_tree);
545     out_free_vhdr:
546     - kfree(sbi->s_vhdr);
547     - kfree(sbi->s_backup_vhdr);
548     + kfree(sbi->s_vhdr_buf);
549     + kfree(sbi->s_backup_vhdr_buf);
550     out_unload_nls:
551     unload_nls(sbi->nls);
552     unload_nls(nls);
553     diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c
554     index 4ac88ff..7b8112d 100644
555     --- a/fs/hfsplus/wrapper.c
556     +++ b/fs/hfsplus/wrapper.c
557     @@ -31,25 +31,67 @@ static void hfsplus_end_io_sync(struct bio *bio, int err)
558     complete(bio->bi_private);
559     }
560    
561     -int hfsplus_submit_bio(struct block_device *bdev, sector_t sector,
562     - void *data, int rw)
563     +/*
564     + * hfsplus_submit_bio - Perfrom block I/O
565     + * @sb: super block of volume for I/O
566     + * @sector: block to read or write, for blocks of HFSPLUS_SECTOR_SIZE bytes
567     + * @buf: buffer for I/O
568     + * @data: output pointer for location of requested data
569     + * @rw: direction of I/O
570     + *
571     + * The unit of I/O is hfsplus_min_io_size(sb), which may be bigger than
572     + * HFSPLUS_SECTOR_SIZE, and @buf must be sized accordingly. On reads
573     + * @data will return a pointer to the start of the requested sector,
574     + * which may not be the same location as @buf.
575     + *
576     + * If @sector is not aligned to the bdev logical block size it will
577     + * be rounded down. For writes this means that @buf should contain data
578     + * that starts at the rounded-down address. As long as the data was
579     + * read using hfsplus_submit_bio() and the same buffer is used things
580     + * will work correctly.
581     + */
582     +int hfsplus_submit_bio(struct super_block *sb, sector_t sector,
583     + void *buf, void **data, int rw)
584     {
585     DECLARE_COMPLETION_ONSTACK(wait);
586     struct bio *bio;
587     int ret = 0;
588     + unsigned int io_size;
589     + loff_t start;
590     + int offset;
591     +
592     + /*
593     + * Align sector to hardware sector size and find offset. We
594     + * assume that io_size is a power of two, which _should_
595     + * be true.
596     + */
597     + io_size = hfsplus_min_io_size(sb);
598     + start = (loff_t)sector << HFSPLUS_SECTOR_SHIFT;
599     + offset = start & (io_size - 1);
600     + sector &= ~((io_size >> HFSPLUS_SECTOR_SHIFT) - 1);
601    
602     bio = bio_alloc(GFP_NOIO, 1);
603     bio->bi_sector = sector;
604     - bio->bi_bdev = bdev;
605     + bio->bi_bdev = sb->s_bdev;
606     bio->bi_end_io = hfsplus_end_io_sync;
607     bio->bi_private = &wait;
608    
609     - /*
610     - * We always submit one sector at a time, so bio_add_page must not fail.
611     - */
612     - if (bio_add_page(bio, virt_to_page(data), HFSPLUS_SECTOR_SIZE,
613     - offset_in_page(data)) != HFSPLUS_SECTOR_SIZE)
614     - BUG();
615     + if (!(rw & WRITE) && data)
616     + *data = (u8 *)buf + offset;
617     +
618     + while (io_size > 0) {
619     + unsigned int page_offset = offset_in_page(buf);
620     + unsigned int len = min_t(unsigned int, PAGE_SIZE - page_offset,
621     + io_size);
622     +
623     + ret = bio_add_page(bio, virt_to_page(buf), len, page_offset);
624     + if (ret != len) {
625     + ret = -EIO;
626     + goto out;
627     + }
628     + io_size -= len;
629     + buf = (u8 *)buf + len;
630     + }
631    
632     submit_bio(rw, bio);
633     wait_for_completion(&wait);
634     @@ -57,8 +99,9 @@ int hfsplus_submit_bio(struct block_device *bdev, sector_t sector,
635     if (!bio_flagged(bio, BIO_UPTODATE))
636     ret = -EIO;
637    
638     +out:
639     bio_put(bio);
640     - return ret;
641     + return ret < 0 ? ret : 0;
642     }
643    
644     static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd)
645     @@ -147,17 +190,17 @@ int hfsplus_read_wrapper(struct super_block *sb)
646     }
647    
648     error = -ENOMEM;
649     - sbi->s_vhdr = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL);
650     - if (!sbi->s_vhdr)
651     + sbi->s_vhdr_buf = kmalloc(hfsplus_min_io_size(sb), GFP_KERNEL);
652     + if (!sbi->s_vhdr_buf)
653     goto out;
654     - sbi->s_backup_vhdr = kmalloc(HFSPLUS_SECTOR_SIZE, GFP_KERNEL);
655     - if (!sbi->s_backup_vhdr)
656     + sbi->s_backup_vhdr_buf = kmalloc(hfsplus_min_io_size(sb), GFP_KERNEL);
657     + if (!sbi->s_backup_vhdr_buf)
658     goto out_free_vhdr;
659    
660     reread:
661     - error = hfsplus_submit_bio(sb->s_bdev,
662     - part_start + HFSPLUS_VOLHEAD_SECTOR,
663     - sbi->s_vhdr, READ);
664     + error = hfsplus_submit_bio(sb, part_start + HFSPLUS_VOLHEAD_SECTOR,
665     + sbi->s_vhdr_buf, (void **)&sbi->s_vhdr,
666     + READ);
667     if (error)
668     goto out_free_backup_vhdr;
669    
670     @@ -186,9 +229,9 @@ reread:
671     goto reread;
672     }
673    
674     - error = hfsplus_submit_bio(sb->s_bdev,
675     - part_start + part_size - 2,
676     - sbi->s_backup_vhdr, READ);
677     + error = hfsplus_submit_bio(sb, part_start + part_size - 2,
678     + sbi->s_backup_vhdr_buf,
679     + (void **)&sbi->s_backup_vhdr, READ);
680     if (error)
681     goto out_free_backup_vhdr;
682    
683     @@ -232,9 +275,9 @@ reread:
684     return 0;
685    
686     out_free_backup_vhdr:
687     - kfree(sbi->s_backup_vhdr);
688     + kfree(sbi->s_backup_vhdr_buf);
689     out_free_vhdr:
690     - kfree(sbi->s_vhdr);
691     + kfree(sbi->s_vhdr_buf);
692     out:
693     return error;
694     }
695     diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
696     index 8633521..8731516 100644
697     --- a/fs/xfs/linux-2.6/xfs_linux.h
698     +++ b/fs/xfs/linux-2.6/xfs_linux.h
699     @@ -70,6 +70,8 @@
700     #include <linux/ctype.h>
701     #include <linux/writeback.h>
702     #include <linux/capability.h>
703     +#include <linux/kthread.h>
704     +#include <linux/freezer.h>
705     #include <linux/list_sort.h>
706    
707     #include <asm/page.h>
708     diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
709     index a1a881e..347cae9 100644
710     --- a/fs/xfs/linux-2.6/xfs_super.c
711     +++ b/fs/xfs/linux-2.6/xfs_super.c
712     @@ -1412,37 +1412,35 @@ xfs_fs_fill_super(
713     sb->s_time_gran = 1;
714     set_posix_acl_flag(sb);
715    
716     - error = xfs_syncd_init(mp);
717     - if (error)
718     - goto out_filestream_unmount;
719     -
720     xfs_inode_shrinker_register(mp);
721    
722     error = xfs_mountfs(mp);
723     if (error)
724     - goto out_syncd_stop;
725     + goto out_filestream_unmount;
726     +
727     + error = xfs_syncd_init(mp);
728     + if (error)
729     + goto out_unmount;
730    
731     root = igrab(VFS_I(mp->m_rootip));
732     if (!root) {
733     error = ENOENT;
734     - goto fail_unmount;
735     + goto out_syncd_stop;
736     }
737     if (is_bad_inode(root)) {
738     error = EINVAL;
739     - goto fail_vnrele;
740     + goto out_syncd_stop;
741     }
742     sb->s_root = d_alloc_root(root);
743     if (!sb->s_root) {
744     error = ENOMEM;
745     - goto fail_vnrele;
746     + goto out_iput;
747     }
748    
749     return 0;
750    
751     - out_syncd_stop:
752     - xfs_inode_shrinker_unregister(mp);
753     - xfs_syncd_stop(mp);
754     out_filestream_unmount:
755     + xfs_inode_shrinker_unregister(mp);
756     xfs_filestream_unmount(mp);
757     out_free_sb:
758     xfs_freesb(mp);
759     @@ -1456,17 +1454,12 @@ xfs_fs_fill_super(
760     out:
761     return -error;
762    
763     - fail_vnrele:
764     - if (sb->s_root) {
765     - dput(sb->s_root);
766     - sb->s_root = NULL;
767     - } else {
768     - iput(root);
769     - }
770     -
771     - fail_unmount:
772     - xfs_inode_shrinker_unregister(mp);
773     + out_iput:
774     + iput(root);
775     + out_syncd_stop:
776     xfs_syncd_stop(mp);
777     + out_unmount:
778     + xfs_inode_shrinker_unregister(mp);
779    
780     /*
781     * Blow away any referenced inode in the filestreams cache.
782     @@ -1667,24 +1660,13 @@ xfs_init_workqueues(void)
783     */
784     xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_CPU_INTENSIVE, 8);
785     if (!xfs_syncd_wq)
786     - goto out;
787     -
788     - xfs_ail_wq = alloc_workqueue("xfsail", WQ_CPU_INTENSIVE, 8);
789     - if (!xfs_ail_wq)
790     - goto out_destroy_syncd;
791     -
792     + return -ENOMEM;
793     return 0;
794     -
795     -out_destroy_syncd:
796     - destroy_workqueue(xfs_syncd_wq);
797     -out:
798     - return -ENOMEM;
799     }
800    
801     STATIC void
802     xfs_destroy_workqueues(void)
803     {
804     - destroy_workqueue(xfs_ail_wq);
805     destroy_workqueue(xfs_syncd_wq);
806     }
807    
808     diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c
809     index 9e0e2fa..8126fc2 100644
810     --- a/fs/xfs/quota/xfs_dquot_item.c
811     +++ b/fs/xfs/quota/xfs_dquot_item.c
812     @@ -183,13 +183,14 @@ xfs_qm_dqunpin_wait(
813     * search the buffer cache can be a time consuming thing, and AIL lock is a
814     * spinlock.
815     */
816     -STATIC void
817     +STATIC bool
818     xfs_qm_dquot_logitem_pushbuf(
819     struct xfs_log_item *lip)
820     {
821     struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip);
822     struct xfs_dquot *dqp = qlip->qli_dquot;
823     struct xfs_buf *bp;
824     + bool ret = true;
825    
826     ASSERT(XFS_DQ_IS_LOCKED(dqp));
827    
828     @@ -201,17 +202,20 @@ xfs_qm_dquot_logitem_pushbuf(
829     if (completion_done(&dqp->q_flush) ||
830     !(lip->li_flags & XFS_LI_IN_AIL)) {
831     xfs_dqunlock(dqp);
832     - return;
833     + return true;
834     }
835    
836     bp = xfs_incore(dqp->q_mount->m_ddev_targp, qlip->qli_format.qlf_blkno,
837     dqp->q_mount->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK);
838     xfs_dqunlock(dqp);
839     if (!bp)
840     - return;
841     + return true;
842     if (XFS_BUF_ISDELAYWRITE(bp))
843     xfs_buf_delwri_promote(bp);
844     + if (XFS_BUF_ISPINNED(bp))
845     + ret = false;
846     xfs_buf_relse(bp);
847     + return ret;
848     }
849    
850     /*
851     diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
852     index 7b7e005..a7342e8 100644
853     --- a/fs/xfs/xfs_buf_item.c
854     +++ b/fs/xfs/xfs_buf_item.c
855     @@ -632,7 +632,7 @@ xfs_buf_item_push(
856     * the xfsbufd to get this buffer written. We have to unlock the buffer
857     * to allow the xfsbufd to write it, too.
858     */
859     -STATIC void
860     +STATIC bool
861     xfs_buf_item_pushbuf(
862     struct xfs_log_item *lip)
863     {
864     @@ -646,6 +646,7 @@ xfs_buf_item_pushbuf(
865    
866     xfs_buf_delwri_promote(bp);
867     xfs_buf_relse(bp);
868     + return true;
869     }
870    
871     STATIC void
872     diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
873     index b1e88d5..391044c 100644
874     --- a/fs/xfs/xfs_inode_item.c
875     +++ b/fs/xfs/xfs_inode_item.c
876     @@ -713,13 +713,14 @@ xfs_inode_item_committed(
877     * marked delayed write. If that's the case, we'll promote it and that will
878     * allow the caller to write the buffer by triggering the xfsbufd to run.
879     */
880     -STATIC void
881     +STATIC bool
882     xfs_inode_item_pushbuf(
883     struct xfs_log_item *lip)
884     {
885     struct xfs_inode_log_item *iip = INODE_ITEM(lip);
886     struct xfs_inode *ip = iip->ili_inode;
887     struct xfs_buf *bp;
888     + bool ret = true;
889    
890     ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED));
891    
892     @@ -730,7 +731,7 @@ xfs_inode_item_pushbuf(
893     if (completion_done(&ip->i_flush) ||
894     !(lip->li_flags & XFS_LI_IN_AIL)) {
895     xfs_iunlock(ip, XFS_ILOCK_SHARED);
896     - return;
897     + return true;
898     }
899    
900     bp = xfs_incore(ip->i_mount->m_ddev_targp, iip->ili_format.ilf_blkno,
901     @@ -738,10 +739,13 @@ xfs_inode_item_pushbuf(
902    
903     xfs_iunlock(ip, XFS_ILOCK_SHARED);
904     if (!bp)
905     - return;
906     + return true;
907     if (XFS_BUF_ISDELAYWRITE(bp))
908     xfs_buf_delwri_promote(bp);
909     + if (XFS_BUF_ISPINNED(bp))
910     + ret = false;
911     xfs_buf_relse(bp);
912     + return ret;
913     }
914    
915     /*
916     diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
917     index c83f63b..efc147f 100644
918     --- a/fs/xfs/xfs_trans.c
919     +++ b/fs/xfs/xfs_trans.c
920     @@ -1426,6 +1426,7 @@ xfs_trans_committed(
921     static inline void
922     xfs_log_item_batch_insert(
923     struct xfs_ail *ailp,
924     + struct xfs_ail_cursor *cur,
925     struct xfs_log_item **log_items,
926     int nr_items,
927     xfs_lsn_t commit_lsn)
928     @@ -1434,7 +1435,7 @@ xfs_log_item_batch_insert(
929    
930     spin_lock(&ailp->xa_lock);
931     /* xfs_trans_ail_update_bulk drops ailp->xa_lock */
932     - xfs_trans_ail_update_bulk(ailp, log_items, nr_items, commit_lsn);
933     + xfs_trans_ail_update_bulk(ailp, cur, log_items, nr_items, commit_lsn);
934    
935     for (i = 0; i < nr_items; i++)
936     IOP_UNPIN(log_items[i], 0);
937     @@ -1452,6 +1453,13 @@ xfs_log_item_batch_insert(
938     * as an iclog write error even though we haven't started any IO yet. Hence in
939     * this case all we need to do is IOP_COMMITTED processing, followed by an
940     * IOP_UNPIN(aborted) call.
941     + *
942     + * The AIL cursor is used to optimise the insert process. If commit_lsn is not
943     + * at the end of the AIL, the insert cursor avoids the need to walk
944     + * the AIL to find the insertion point on every xfs_log_item_batch_insert()
945     + * call. This saves a lot of needless list walking and is a net win, even
946     + * though it slightly increases that amount of AIL lock traffic to set it up
947     + * and tear it down.
948     */
949     void
950     xfs_trans_committed_bulk(
951     @@ -1463,8 +1471,13 @@ xfs_trans_committed_bulk(
952     #define LOG_ITEM_BATCH_SIZE 32
953     struct xfs_log_item *log_items[LOG_ITEM_BATCH_SIZE];
954     struct xfs_log_vec *lv;
955     + struct xfs_ail_cursor cur;
956     int i = 0;
957    
958     + spin_lock(&ailp->xa_lock);
959     + xfs_trans_ail_cursor_last(ailp, &cur, commit_lsn);
960     + spin_unlock(&ailp->xa_lock);
961     +
962     /* unpin all the log items */
963     for (lv = log_vector; lv; lv = lv->lv_next ) {
964     struct xfs_log_item *lip = lv->lv_item;
965     @@ -1493,7 +1506,9 @@ xfs_trans_committed_bulk(
966     /*
967     * Not a bulk update option due to unusual item_lsn.
968     * Push into AIL immediately, rechecking the lsn once
969     - * we have the ail lock. Then unpin the item.
970     + * we have the ail lock. Then unpin the item. This does
971     + * not affect the AIL cursor the bulk insert path is
972     + * using.
973     */
974     spin_lock(&ailp->xa_lock);
975     if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0)
976     @@ -1507,7 +1522,7 @@ xfs_trans_committed_bulk(
977     /* Item is a candidate for bulk AIL insert. */
978     log_items[i++] = lv->lv_item;
979     if (i >= LOG_ITEM_BATCH_SIZE) {
980     - xfs_log_item_batch_insert(ailp, log_items,
981     + xfs_log_item_batch_insert(ailp, &cur, log_items,
982     LOG_ITEM_BATCH_SIZE, commit_lsn);
983     i = 0;
984     }
985     @@ -1515,7 +1530,11 @@ xfs_trans_committed_bulk(
986    
987     /* make sure we insert the remainder! */
988     if (i)
989     - xfs_log_item_batch_insert(ailp, log_items, i, commit_lsn);
990     + xfs_log_item_batch_insert(ailp, &cur, log_items, i, commit_lsn);
991     +
992     + spin_lock(&ailp->xa_lock);
993     + xfs_trans_ail_cursor_done(ailp, &cur);
994     + spin_unlock(&ailp->xa_lock);
995     }
996    
997     /*
998     diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
999     index 06a9759..53597f4 100644
1000     --- a/fs/xfs/xfs_trans.h
1001     +++ b/fs/xfs/xfs_trans.h
1002     @@ -350,7 +350,7 @@ typedef struct xfs_item_ops {
1003     void (*iop_unlock)(xfs_log_item_t *);
1004     xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t);
1005     void (*iop_push)(xfs_log_item_t *);
1006     - void (*iop_pushbuf)(xfs_log_item_t *);
1007     + bool (*iop_pushbuf)(xfs_log_item_t *);
1008     void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t);
1009     } xfs_item_ops_t;
1010    
1011     diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
1012     index 5fc2380..a4c281b 100644
1013     --- a/fs/xfs/xfs_trans_ail.c
1014     +++ b/fs/xfs/xfs_trans_ail.c
1015     @@ -28,8 +28,6 @@
1016     #include "xfs_trans_priv.h"
1017     #include "xfs_error.h"
1018    
1019     -struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */
1020     -
1021     #ifdef DEBUG
1022     /*
1023     * Check that the list is sorted as it should be.
1024     @@ -272,9 +270,9 @@ xfs_trans_ail_cursor_clear(
1025     }
1026    
1027     /*
1028     - * Return the item in the AIL with the current lsn.
1029     - * Return the current tree generation number for use
1030     - * in calls to xfs_trans_next_ail().
1031     + * Initialise the cursor to the first item in the AIL with the given @lsn.
1032     + * This searches the list from lowest LSN to highest. Pass a @lsn of zero
1033     + * to initialise the cursor to the first item in the AIL.
1034     */
1035     xfs_log_item_t *
1036     xfs_trans_ail_cursor_first(
1037     @@ -300,31 +298,97 @@ out:
1038     }
1039    
1040     /*
1041     - * splice the log item list into the AIL at the given LSN.
1042     + * Initialise the cursor to the last item in the AIL with the given @lsn.
1043     + * This searches the list from highest LSN to lowest. If there is no item with
1044     + * the value of @lsn, then it sets the cursor to the last item with an LSN lower
1045     + * than @lsn.
1046     + */
1047     +static struct xfs_log_item *
1048     +__xfs_trans_ail_cursor_last(
1049     + struct xfs_ail *ailp,
1050     + xfs_lsn_t lsn)
1051     +{
1052     + xfs_log_item_t *lip;
1053     +
1054     + list_for_each_entry_reverse(lip, &ailp->xa_ail, li_ail) {
1055     + if (XFS_LSN_CMP(lip->li_lsn, lsn) <= 0)
1056     + return lip;
1057     + }
1058     + return NULL;
1059     +}
1060     +
1061     +/*
1062     + * Initialise the cursor to the last item in the AIL with the given @lsn.
1063     + * This searches the list from highest LSN to lowest.
1064     + */
1065     +struct xfs_log_item *
1066     +xfs_trans_ail_cursor_last(
1067     + struct xfs_ail *ailp,
1068     + struct xfs_ail_cursor *cur,
1069     + xfs_lsn_t lsn)
1070     +{
1071     + xfs_trans_ail_cursor_init(ailp, cur);
1072     + cur->item = __xfs_trans_ail_cursor_last(ailp, lsn);
1073     + return cur->item;
1074     +}
1075     +
1076     +/*
1077     + * splice the log item list into the AIL at the given LSN. We splice to the
1078     + * tail of the given LSN to maintain insert order for push traversals. The
1079     + * cursor is optional, allowing repeated updates to the same LSN to avoid
1080     + * repeated traversals.
1081     */
1082     static void
1083     xfs_ail_splice(
1084     - struct xfs_ail *ailp,
1085     - struct list_head *list,
1086     - xfs_lsn_t lsn)
1087     + struct xfs_ail *ailp,
1088     + struct xfs_ail_cursor *cur,
1089     + struct list_head *list,
1090     + xfs_lsn_t lsn)
1091     {
1092     - xfs_log_item_t *next_lip;
1093     + struct xfs_log_item *lip = cur ? cur->item : NULL;
1094     + struct xfs_log_item *next_lip;
1095    
1096     - /* If the list is empty, just insert the item. */
1097     - if (list_empty(&ailp->xa_ail)) {
1098     - list_splice(list, &ailp->xa_ail);
1099     - return;
1100     - }
1101     + /*
1102     + * Get a new cursor if we don't have a placeholder or the existing one
1103     + * has been invalidated.
1104     + */
1105     + if (!lip || (__psint_t)lip & 1) {
1106     + lip = __xfs_trans_ail_cursor_last(ailp, lsn);
1107    
1108     - list_for_each_entry_reverse(next_lip, &ailp->xa_ail, li_ail) {
1109     - if (XFS_LSN_CMP(next_lip->li_lsn, lsn) <= 0)
1110     - break;
1111     + if (!lip) {
1112     + /* The list is empty, so just splice and return. */
1113     + if (cur)
1114     + cur->item = NULL;
1115     + list_splice(list, &ailp->xa_ail);
1116     + return;
1117     + }
1118     }
1119    
1120     - ASSERT(&next_lip->li_ail == &ailp->xa_ail ||
1121     - XFS_LSN_CMP(next_lip->li_lsn, lsn) <= 0);
1122     -
1123     - list_splice_init(list, &next_lip->li_ail);
1124     + /*
1125     + * Our cursor points to the item we want to insert _after_, so we have
1126     + * to update the cursor to point to the end of the list we are splicing
1127     + * in so that it points to the correct location for the next splice.
1128     + * i.e. before the splice
1129     + *
1130     + * lsn -> lsn -> lsn + x -> lsn + x ...
1131     + * ^
1132     + * | cursor points here
1133     + *
1134     + * After the splice we have:
1135     + *
1136     + * lsn -> lsn -> lsn -> lsn -> .... -> lsn -> lsn + x -> lsn + x ...
1137     + * ^ ^
1138     + * | cursor points here | needs to move here
1139     + *
1140     + * So we set the cursor to the last item in the list to be spliced
1141     + * before we execute the splice, resulting in the cursor pointing to
1142     + * the correct item after the splice occurs.
1143     + */
1144     + if (cur) {
1145     + next_lip = list_entry(list->prev, struct xfs_log_item, li_ail);
1146     + cur->item = next_lip;
1147     + }
1148     + list_splice(list, &lip->li_ail);
1149     }
1150    
1151     /*
1152     @@ -340,16 +404,10 @@ xfs_ail_delete(
1153     xfs_trans_ail_cursor_clear(ailp, lip);
1154     }
1155    
1156     -/*
1157     - * xfs_ail_worker does the work of pushing on the AIL. It will requeue itself
1158     - * to run at a later time if there is more work to do to complete the push.
1159     - */
1160     -STATIC void
1161     -xfs_ail_worker(
1162     - struct work_struct *work)
1163     +static long
1164     +xfsaild_push(
1165     + struct xfs_ail *ailp)
1166     {
1167     - struct xfs_ail *ailp = container_of(to_delayed_work(work),
1168     - struct xfs_ail, xa_work);
1169     xfs_mount_t *mp = ailp->xa_mount;
1170     struct xfs_ail_cursor *cur = &ailp->xa_cursors;
1171     xfs_log_item_t *lip;
1172     @@ -412,8 +470,13 @@ xfs_ail_worker(
1173    
1174     case XFS_ITEM_PUSHBUF:
1175     XFS_STATS_INC(xs_push_ail_pushbuf);
1176     - IOP_PUSHBUF(lip);
1177     - ailp->xa_last_pushed_lsn = lsn;
1178     +
1179     + if (!IOP_PUSHBUF(lip)) {
1180     + stuck++;
1181     + flush_log = 1;
1182     + } else {
1183     + ailp->xa_last_pushed_lsn = lsn;
1184     + }
1185     push_xfsbufd = 1;
1186     break;
1187    
1188     @@ -425,7 +488,6 @@ xfs_ail_worker(
1189    
1190     case XFS_ITEM_LOCKED:
1191     XFS_STATS_INC(xs_push_ail_locked);
1192     - ailp->xa_last_pushed_lsn = lsn;
1193     stuck++;
1194     break;
1195    
1196     @@ -486,20 +548,6 @@ out_done:
1197     /* We're past our target or empty, so idle */
1198     ailp->xa_last_pushed_lsn = 0;
1199    
1200     - /*
1201     - * We clear the XFS_AIL_PUSHING_BIT first before checking
1202     - * whether the target has changed. If the target has changed,
1203     - * this pushes the requeue race directly onto the result of the
1204     - * atomic test/set bit, so we are guaranteed that either the
1205     - * the pusher that changed the target or ourselves will requeue
1206     - * the work (but not both).
1207     - */
1208     - clear_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags);
1209     - smp_rmb();
1210     - if (XFS_LSN_CMP(ailp->xa_target, target) == 0 ||
1211     - test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags))
1212     - return;
1213     -
1214     tout = 50;
1215     } else if (XFS_LSN_CMP(lsn, target) >= 0) {
1216     /*
1217     @@ -522,9 +570,30 @@ out_done:
1218     tout = 20;
1219     }
1220    
1221     - /* There is more to do, requeue us. */
1222     - queue_delayed_work(xfs_syncd_wq, &ailp->xa_work,
1223     - msecs_to_jiffies(tout));
1224     + return tout;
1225     +}
1226     +
1227     +static int
1228     +xfsaild(
1229     + void *data)
1230     +{
1231     + struct xfs_ail *ailp = data;
1232     + long tout = 0; /* milliseconds */
1233     +
1234     + while (!kthread_should_stop()) {
1235     + if (tout && tout <= 20)
1236     + __set_current_state(TASK_KILLABLE);
1237     + else
1238     + __set_current_state(TASK_INTERRUPTIBLE);
1239     + schedule_timeout(tout ?
1240     + msecs_to_jiffies(tout) : MAX_SCHEDULE_TIMEOUT);
1241     +
1242     + try_to_freeze();
1243     +
1244     + tout = xfsaild_push(ailp);
1245     + }
1246     +
1247     + return 0;
1248     }
1249    
1250     /*
1251     @@ -559,8 +628,9 @@ xfs_ail_push(
1252     */
1253     smp_wmb();
1254     xfs_trans_ail_copy_lsn(ailp, &ailp->xa_target, &threshold_lsn);
1255     - if (!test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags))
1256     - queue_delayed_work(xfs_syncd_wq, &ailp->xa_work, 0);
1257     + smp_wmb();
1258     +
1259     + wake_up_process(ailp->xa_task);
1260     }
1261    
1262     /*
1263     @@ -645,6 +715,7 @@ xfs_trans_unlocked_item(
1264     void
1265     xfs_trans_ail_update_bulk(
1266     struct xfs_ail *ailp,
1267     + struct xfs_ail_cursor *cur,
1268     struct xfs_log_item **log_items,
1269     int nr_items,
1270     xfs_lsn_t lsn) __releases(ailp->xa_lock)
1271     @@ -674,7 +745,7 @@ xfs_trans_ail_update_bulk(
1272     list_add(&lip->li_ail, &tmp);
1273     }
1274    
1275     - xfs_ail_splice(ailp, &tmp, lsn);
1276     + xfs_ail_splice(ailp, cur, &tmp, lsn);
1277    
1278     if (!mlip_changed) {
1279     spin_unlock(&ailp->xa_lock);
1280     @@ -794,9 +865,18 @@ xfs_trans_ail_init(
1281     ailp->xa_mount = mp;
1282     INIT_LIST_HEAD(&ailp->xa_ail);
1283     spin_lock_init(&ailp->xa_lock);
1284     - INIT_DELAYED_WORK(&ailp->xa_work, xfs_ail_worker);
1285     +
1286     + ailp->xa_task = kthread_run(xfsaild, ailp, "xfsaild/%s",
1287     + ailp->xa_mount->m_fsname);
1288     + if (IS_ERR(ailp->xa_task))
1289     + goto out_free_ailp;
1290     +
1291     mp->m_ail = ailp;
1292     return 0;
1293     +
1294     +out_free_ailp:
1295     + kmem_free(ailp);
1296     + return ENOMEM;
1297     }
1298    
1299     void
1300     @@ -805,6 +885,6 @@ xfs_trans_ail_destroy(
1301     {
1302     struct xfs_ail *ailp = mp->m_ail;
1303    
1304     - cancel_delayed_work_sync(&ailp->xa_work);
1305     + kthread_stop(ailp->xa_task);
1306     kmem_free(ailp);
1307     }
1308     diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h
1309     index 6b164e9..fe2e3cb 100644
1310     --- a/fs/xfs/xfs_trans_priv.h
1311     +++ b/fs/xfs/xfs_trans_priv.h
1312     @@ -64,24 +64,19 @@ struct xfs_ail_cursor {
1313     */
1314     struct xfs_ail {
1315     struct xfs_mount *xa_mount;
1316     + struct task_struct *xa_task;
1317     struct list_head xa_ail;
1318     xfs_lsn_t xa_target;
1319     struct xfs_ail_cursor xa_cursors;
1320     spinlock_t xa_lock;
1321     - struct delayed_work xa_work;
1322     xfs_lsn_t xa_last_pushed_lsn;
1323     - unsigned long xa_flags;
1324     };
1325    
1326     -#define XFS_AIL_PUSHING_BIT 0
1327     -
1328     /*
1329     * From xfs_trans_ail.c
1330     */
1331     -
1332     -extern struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */
1333     -
1334     void xfs_trans_ail_update_bulk(struct xfs_ail *ailp,
1335     + struct xfs_ail_cursor *cur,
1336     struct xfs_log_item **log_items, int nr_items,
1337     xfs_lsn_t lsn) __releases(ailp->xa_lock);
1338     static inline void
1339     @@ -90,7 +85,7 @@ xfs_trans_ail_update(
1340     struct xfs_log_item *lip,
1341     xfs_lsn_t lsn) __releases(ailp->xa_lock)
1342     {
1343     - xfs_trans_ail_update_bulk(ailp, &lip, 1, lsn);
1344     + xfs_trans_ail_update_bulk(ailp, NULL, &lip, 1, lsn);
1345     }
1346    
1347     void xfs_trans_ail_delete_bulk(struct xfs_ail *ailp,
1348     @@ -111,10 +106,13 @@ xfs_lsn_t xfs_ail_min_lsn(struct xfs_ail *ailp);
1349     void xfs_trans_unlocked_item(struct xfs_ail *,
1350     xfs_log_item_t *);
1351    
1352     -struct xfs_log_item *xfs_trans_ail_cursor_first(struct xfs_ail *ailp,
1353     +struct xfs_log_item * xfs_trans_ail_cursor_first(struct xfs_ail *ailp,
1354     + struct xfs_ail_cursor *cur,
1355     + xfs_lsn_t lsn);
1356     +struct xfs_log_item * xfs_trans_ail_cursor_last(struct xfs_ail *ailp,
1357     struct xfs_ail_cursor *cur,
1358     xfs_lsn_t lsn);
1359     -struct xfs_log_item *xfs_trans_ail_cursor_next(struct xfs_ail *ailp,
1360     +struct xfs_log_item * xfs_trans_ail_cursor_next(struct xfs_ail *ailp,
1361     struct xfs_ail_cursor *cur);
1362     void xfs_trans_ail_cursor_done(struct xfs_ail *ailp,
1363     struct xfs_ail_cursor *cur);
1364     diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
1365     index c8008dd..640ded8 100644
1366     --- a/kernel/posix-cpu-timers.c
1367     +++ b/kernel/posix-cpu-timers.c
1368     @@ -274,9 +274,7 @@ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times)
1369     struct task_cputime sum;
1370     unsigned long flags;
1371    
1372     - spin_lock_irqsave(&cputimer->lock, flags);
1373     if (!cputimer->running) {
1374     - cputimer->running = 1;
1375     /*
1376     * The POSIX timer interface allows for absolute time expiry
1377     * values through the TIMER_ABSTIME flag, therefore we have
1378     @@ -284,8 +282,11 @@ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times)
1379     * it.
1380     */
1381     thread_group_cputime(tsk, &sum);
1382     + spin_lock_irqsave(&cputimer->lock, flags);
1383     + cputimer->running = 1;
1384     update_gt_cputime(&cputimer->cputime, &sum);
1385     - }
1386     + } else
1387     + spin_lock_irqsave(&cputimer->lock, flags);
1388     *times = cputimer->cputime;
1389     spin_unlock_irqrestore(&cputimer->lock, flags);
1390     }
1391     diff --git a/kernel/sys.c b/kernel/sys.c
1392     index 5c942cf..f88dadc 100644
1393     --- a/kernel/sys.c
1394     +++ b/kernel/sys.c
1395     @@ -1135,7 +1135,7 @@ DECLARE_RWSEM(uts_sem);
1396     static int override_release(char __user *release, int len)
1397     {
1398     int ret = 0;
1399     - char buf[len];
1400     + char buf[65];
1401    
1402     if (current->personality & UNAME26) {
1403     char *rest = UTS_RELEASE;
1404     diff --git a/mm/migrate.c b/mm/migrate.c
1405     index 666e4e6..14d0a6a 100644
1406     --- a/mm/migrate.c
1407     +++ b/mm/migrate.c
1408     @@ -120,10 +120,10 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,
1409    
1410     ptep = pte_offset_map(pmd, addr);
1411    
1412     - if (!is_swap_pte(*ptep)) {
1413     - pte_unmap(ptep);
1414     - goto out;
1415     - }
1416     + /*
1417     + * Peek to check is_swap_pte() before taking ptlock? No, we
1418     + * can race mremap's move_ptes(), which skips anon_vma lock.
1419     + */
1420    
1421     ptl = pte_lockptr(mm, pmd);
1422     }
1423     diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
1424     index 4680b1e..373e14f 100644
1425     --- a/net/x25/af_x25.c
1426     +++ b/net/x25/af_x25.c
1427     @@ -295,7 +295,8 @@ static struct sock *x25_find_listener(struct x25_address *addr,
1428     * Found a listening socket, now check the incoming
1429     * call user data vs this sockets call user data
1430     */
1431     - if(skb->len > 0 && x25_sk(s)->cudmatchlength > 0) {
1432     + if (x25_sk(s)->cudmatchlength > 0 &&
1433     + skb->len >= x25_sk(s)->cudmatchlength) {
1434     if((memcmp(x25_sk(s)->calluserdata.cuddata,
1435     skb->data,
1436     x25_sk(s)->cudmatchlength)) == 0) {
1437     diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
1438     index 486f6de..981b6fd 100644
1439     --- a/sound/pci/hda/hda_intel.c
1440     +++ b/sound/pci/hda/hda_intel.c
1441     @@ -2352,6 +2352,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
1442     SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
1443     SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
1444     SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
1445     + SND_PCI_QUIRK(0x1028, 0x02c6, "Dell Inspiron 1010", POS_FIX_LPIB),
1446     SND_PCI_QUIRK(0x1028, 0x0470, "Dell Inspiron 1120", POS_FIX_LPIB),
1447     SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
1448     SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
1449     diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
1450     index 7bbc5f2..cf1fa36 100644
1451     --- a/sound/pci/hda/patch_conexant.c
1452     +++ b/sound/pci/hda/patch_conexant.c
1453     @@ -3097,6 +3097,7 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
1454     SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
1455     SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
1456     SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
1457     + SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO),
1458     SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
1459     SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
1460     SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),