Contents of /trunk/kernel-alx/patches-3.0-r1/0103-3.0.4-all-fixes.patch
Parent Directory | Revision Log
Revision 1521 -
(show annotations)
(download)
Wed Sep 7 13:28:13 2011 UTC (13 years ago) by niro
File size: 41883 byte(s)
Wed Sep 7 13:28:13 2011 UTC (13 years ago) by niro
File size: 41883 byte(s)
-added kernel 3.0-alx-r1
1 | diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h |
2 | index 64a619d..7ff4669 100644 |
3 | --- a/arch/x86/include/asm/xen/page.h |
4 | +++ b/arch/x86/include/asm/xen/page.h |
5 | @@ -39,7 +39,7 @@ typedef struct xpaddr { |
6 | ((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE)) |
7 | |
8 | extern unsigned long *machine_to_phys_mapping; |
9 | -extern unsigned int machine_to_phys_order; |
10 | +extern unsigned long machine_to_phys_nr; |
11 | |
12 | extern unsigned long get_phys_to_machine(unsigned long pfn); |
13 | extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); |
14 | @@ -87,7 +87,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn) |
15 | if (xen_feature(XENFEAT_auto_translated_physmap)) |
16 | return mfn; |
17 | |
18 | - if (unlikely((mfn >> machine_to_phys_order) != 0)) { |
19 | + if (unlikely(mfn >= machine_to_phys_nr)) { |
20 | pfn = ~0; |
21 | goto try_override; |
22 | } |
23 | diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c |
24 | index adc66c3..34b1859 100644 |
25 | --- a/arch/x86/kernel/apic/x2apic_uv_x.c |
26 | +++ b/arch/x86/kernel/apic/x2apic_uv_x.c |
27 | @@ -207,7 +207,6 @@ static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_ri |
28 | ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | |
29 | APIC_DM_INIT; |
30 | uv_write_global_mmr64(pnode, UVH_IPI_INT, val); |
31 | - mdelay(10); |
32 | |
33 | val = (1UL << UVH_IPI_INT_SEND_SHFT) | |
34 | (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | |
35 | diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c |
36 | index da0d779..ed6086e 100644 |
37 | --- a/arch/x86/kernel/cpu/intel.c |
38 | +++ b/arch/x86/kernel/cpu/intel.c |
39 | @@ -465,11 +465,11 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) |
40 | u64 epb; |
41 | |
42 | rdmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb); |
43 | - if ((epb & 0xF) == 0) { |
44 | - printk_once(KERN_WARNING, "x86: updated energy_perf_bias" |
45 | - " to 'normal' from 'performance'\n" |
46 | - "You can view and update epb via utility," |
47 | - " such as x86_energy_perf_policy(8)\n"); |
48 | + if ((epb & 0xF) == ENERGY_PERF_BIAS_PERFORMANCE) { |
49 | + printk_once(KERN_WARNING "ENERGY_PERF_BIAS:" |
50 | + " Set to 'normal', was 'performance'\n" |
51 | + "ENERGY_PERF_BIAS: View and update with" |
52 | + " x86_energy_perf_policy(8)\n"); |
53 | epb = (epb & ~0xF) | ENERGY_PERF_BIAS_NORMAL; |
54 | wrmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb); |
55 | } |
56 | diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c |
57 | index 929739a..3d17bc7 100644 |
58 | --- a/arch/x86/kernel/cpu/mtrr/main.c |
59 | +++ b/arch/x86/kernel/cpu/mtrr/main.c |
60 | @@ -248,6 +248,25 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ |
61 | unsigned long flags; |
62 | int cpu; |
63 | |
64 | +#ifdef CONFIG_SMP |
65 | + /* |
66 | + * If this cpu is not yet active, we are in the cpu online path. There |
67 | + * can be no stop_machine() in parallel, as stop machine ensures this |
68 | + * by using get_online_cpus(). We can skip taking the stop_cpus_mutex, |
69 | + * as we don't need it and also we can't afford to block while waiting |
70 | + * for the mutex. |
71 | + * |
72 | + * If this cpu is active, we need to prevent stop_machine() happening |
73 | + * in parallel by taking the stop cpus mutex. |
74 | + * |
75 | + * Also, this is called in the context of cpu online path or in the |
76 | + * context where cpu hotplug is prevented. So checking the active status |
77 | + * of the raw_smp_processor_id() is safe. |
78 | + */ |
79 | + if (cpu_active(raw_smp_processor_id())) |
80 | + mutex_lock(&stop_cpus_mutex); |
81 | +#endif |
82 | + |
83 | preempt_disable(); |
84 | |
85 | data.smp_reg = reg; |
86 | @@ -330,6 +349,10 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ |
87 | |
88 | local_irq_restore(flags); |
89 | preempt_enable(); |
90 | +#ifdef CONFIG_SMP |
91 | + if (cpu_active(raw_smp_processor_id())) |
92 | + mutex_unlock(&stop_cpus_mutex); |
93 | +#endif |
94 | } |
95 | |
96 | /** |
97 | diff --git a/arch/x86/platform/olpc/olpc.c b/arch/x86/platform/olpc/olpc.c |
98 | index 0060fd5..02e3934 100644 |
99 | --- a/arch/x86/platform/olpc/olpc.c |
100 | +++ b/arch/x86/platform/olpc/olpc.c |
101 | @@ -157,13 +157,13 @@ restart: |
102 | if (inbuf && inlen) { |
103 | /* write data to EC */ |
104 | for (i = 0; i < inlen; i++) { |
105 | + pr_devel("olpc-ec: sending cmd arg 0x%x\n", inbuf[i]); |
106 | + outb(inbuf[i], 0x68); |
107 | if (wait_on_ibf(0x6c, 0)) { |
108 | printk(KERN_ERR "olpc-ec: timeout waiting for" |
109 | " EC accept data!\n"); |
110 | goto err; |
111 | } |
112 | - pr_devel("olpc-ec: sending cmd arg 0x%x\n", inbuf[i]); |
113 | - outb(inbuf[i], 0x68); |
114 | } |
115 | } |
116 | if (outbuf && outlen) { |
117 | diff --git a/arch/x86/vdso/vdso32/sysenter.S b/arch/x86/vdso/vdso32/sysenter.S |
118 | index e2800af..e354bce 100644 |
119 | --- a/arch/x86/vdso/vdso32/sysenter.S |
120 | +++ b/arch/x86/vdso/vdso32/sysenter.S |
121 | @@ -43,7 +43,7 @@ __kernel_vsyscall: |
122 | .space 7,0x90 |
123 | |
124 | /* 14: System call restart point is here! (SYSENTER_RETURN-2) */ |
125 | - jmp .Lenter_kernel |
126 | + int $0x80 |
127 | /* 16: System call normal return point is here! */ |
128 | VDSO32_SYSENTER_RETURN: /* Symbol used by sysenter.c via vdso32-syms.h */ |
129 | pop %ebp |
130 | diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c |
131 | index 5325742..67d69f1 100644 |
132 | --- a/arch/x86/xen/enlighten.c |
133 | +++ b/arch/x86/xen/enlighten.c |
134 | @@ -77,8 +77,8 @@ EXPORT_SYMBOL_GPL(xen_domain_type); |
135 | |
136 | unsigned long *machine_to_phys_mapping = (void *)MACH2PHYS_VIRT_START; |
137 | EXPORT_SYMBOL(machine_to_phys_mapping); |
138 | -unsigned int machine_to_phys_order; |
139 | -EXPORT_SYMBOL(machine_to_phys_order); |
140 | +unsigned long machine_to_phys_nr; |
141 | +EXPORT_SYMBOL(machine_to_phys_nr); |
142 | |
143 | struct start_info *xen_start_info; |
144 | EXPORT_SYMBOL_GPL(xen_start_info); |
145 | diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c |
146 | index 0ccccb6..5f76c0a 100644 |
147 | --- a/arch/x86/xen/mmu.c |
148 | +++ b/arch/x86/xen/mmu.c |
149 | @@ -1626,15 +1626,19 @@ static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) |
150 | void __init xen_setup_machphys_mapping(void) |
151 | { |
152 | struct xen_machphys_mapping mapping; |
153 | - unsigned long machine_to_phys_nr_ents; |
154 | |
155 | if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) { |
156 | machine_to_phys_mapping = (unsigned long *)mapping.v_start; |
157 | - machine_to_phys_nr_ents = mapping.max_mfn + 1; |
158 | + machine_to_phys_nr = mapping.max_mfn + 1; |
159 | } else { |
160 | - machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES; |
161 | + machine_to_phys_nr = MACH2PHYS_NR_ENTRIES; |
162 | } |
163 | - machine_to_phys_order = fls(machine_to_phys_nr_ents - 1); |
164 | +#ifdef CONFIG_X86_32 |
165 | + if ((machine_to_phys_mapping + machine_to_phys_nr) |
166 | + < machine_to_phys_mapping) |
167 | + machine_to_phys_nr = (unsigned long *)NULL |
168 | + - machine_to_phys_mapping; |
169 | +#endif |
170 | } |
171 | |
172 | #ifdef CONFIG_X86_64 |
173 | diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c |
174 | index b4533a8..e79dbb9 100644 |
175 | --- a/arch/x86/xen/smp.c |
176 | +++ b/arch/x86/xen/smp.c |
177 | @@ -521,8 +521,6 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus) |
178 | native_smp_prepare_cpus(max_cpus); |
179 | WARN_ON(xen_smp_intr_init(0)); |
180 | |
181 | - if (!xen_have_vector_callback) |
182 | - return; |
183 | xen_init_lock_cpu(0); |
184 | xen_init_spinlocks(); |
185 | } |
186 | @@ -546,6 +544,8 @@ static void xen_hvm_cpu_die(unsigned int cpu) |
187 | |
188 | void __init xen_hvm_smp_init(void) |
189 | { |
190 | + if (!xen_have_vector_callback) |
191 | + return; |
192 | smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; |
193 | smp_ops.smp_send_reschedule = xen_smp_send_reschedule; |
194 | smp_ops.cpu_up = xen_hvm_cpu_up; |
195 | diff --git a/drivers/block/loop.c b/drivers/block/loop.c |
196 | index 76c8da7..2ebacf0 100644 |
197 | --- a/drivers/block/loop.c |
198 | +++ b/drivers/block/loop.c |
199 | @@ -750,10 +750,10 @@ static ssize_t loop_attr_backing_file_show(struct loop_device *lo, char *buf) |
200 | ssize_t ret; |
201 | char *p = NULL; |
202 | |
203 | - mutex_lock(&lo->lo_ctl_mutex); |
204 | + spin_lock_irq(&lo->lo_lock); |
205 | if (lo->lo_backing_file) |
206 | p = d_path(&lo->lo_backing_file->f_path, buf, PAGE_SIZE - 1); |
207 | - mutex_unlock(&lo->lo_ctl_mutex); |
208 | + spin_unlock_irq(&lo->lo_lock); |
209 | |
210 | if (IS_ERR_OR_NULL(p)) |
211 | ret = PTR_ERR(p); |
212 | @@ -1007,7 +1007,9 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) |
213 | |
214 | kthread_stop(lo->lo_thread); |
215 | |
216 | + spin_lock_irq(&lo->lo_lock); |
217 | lo->lo_backing_file = NULL; |
218 | + spin_unlock_irq(&lo->lo_lock); |
219 | |
220 | loop_release_xfer(lo); |
221 | lo->transfer = NULL; |
222 | diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c |
223 | index b536a9c..9ea8c25 100644 |
224 | --- a/drivers/block/xen-blkfront.c |
225 | +++ b/drivers/block/xen-blkfront.c |
226 | @@ -123,8 +123,8 @@ static DEFINE_SPINLOCK(minor_lock); |
227 | #define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED)) |
228 | #define EMULATED_HD_DISK_MINOR_OFFSET (0) |
229 | #define EMULATED_HD_DISK_NAME_OFFSET (EMULATED_HD_DISK_MINOR_OFFSET / 256) |
230 | -#define EMULATED_SD_DISK_MINOR_OFFSET (EMULATED_HD_DISK_MINOR_OFFSET + (4 * 16)) |
231 | -#define EMULATED_SD_DISK_NAME_OFFSET (EMULATED_HD_DISK_NAME_OFFSET + 4) |
232 | +#define EMULATED_SD_DISK_MINOR_OFFSET (0) |
233 | +#define EMULATED_SD_DISK_NAME_OFFSET (EMULATED_SD_DISK_MINOR_OFFSET / 256) |
234 | |
235 | #define DEV_NAME "xvd" /* name in /dev */ |
236 | |
237 | @@ -529,7 +529,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, |
238 | minor = BLKIF_MINOR_EXT(info->vdevice); |
239 | nr_parts = PARTS_PER_EXT_DISK; |
240 | offset = minor / nr_parts; |
241 | - if (xen_hvm_domain() && offset <= EMULATED_HD_DISK_NAME_OFFSET + 4) |
242 | + if (xen_hvm_domain() && offset < EMULATED_HD_DISK_NAME_OFFSET + 4) |
243 | printk(KERN_WARNING "blkfront: vdevice 0x%x might conflict with " |
244 | "emulated IDE disks,\n\t choose an xvd device name" |
245 | "from xvde on\n", info->vdevice); |
246 | diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c |
247 | index 04f1e7c..f6cf448 100644 |
248 | --- a/drivers/edac/i7core_edac.c |
249 | +++ b/drivers/edac/i7core_edac.c |
250 | @@ -1670,7 +1670,7 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, |
251 | char *type, *optype, *err, *msg; |
252 | unsigned long error = m->status & 0x1ff0000l; |
253 | u32 optypenum = (m->status >> 4) & 0x07; |
254 | - u32 core_err_cnt = (m->status >> 38) && 0x7fff; |
255 | + u32 core_err_cnt = (m->status >> 38) & 0x7fff; |
256 | u32 dimm = (m->misc >> 16) & 0x3; |
257 | u32 channel = (m->misc >> 18) & 0x3; |
258 | u32 syndrome = m->misc >> 32; |
259 | diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c |
260 | index 6ab6c41..d1b36f8 100644 |
261 | --- a/drivers/gpu/drm/radeon/radeon_connectors.c |
262 | +++ b/drivers/gpu/drm/radeon/radeon_connectors.c |
263 | @@ -466,6 +466,16 @@ static bool radeon_connector_needs_extended_probe(struct radeon_device *dev, |
264 | (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) |
265 | return true; |
266 | } |
267 | + /* TOSHIBA Satellite L300D with ATI Mobility Radeon x1100 |
268 | + * (RS690M) sends data to i2c bus for a HDMI connector that |
269 | + * is not implemented */ |
270 | + if ((dev->pdev->device == 0x791f) && |
271 | + (dev->pdev->subsystem_vendor == 0x1179) && |
272 | + (dev->pdev->subsystem_device == 0xff68)) { |
273 | + if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) && |
274 | + (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) |
275 | + return true; |
276 | + } |
277 | |
278 | /* Default: no EDID header probe required for DDC probing */ |
279 | return false; |
280 | diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c |
281 | index 2e618b5..b7f0726 100644 |
282 | --- a/drivers/gpu/drm/ttm/ttm_bo.c |
283 | +++ b/drivers/gpu/drm/ttm/ttm_bo.c |
284 | @@ -353,8 +353,10 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc) |
285 | |
286 | ret = ttm_tt_set_user(bo->ttm, current, |
287 | bo->buffer_start, bo->num_pages); |
288 | - if (unlikely(ret != 0)) |
289 | + if (unlikely(ret != 0)) { |
290 | ttm_tt_destroy(bo->ttm); |
291 | + bo->ttm = NULL; |
292 | + } |
293 | break; |
294 | default: |
295 | printk(KERN_ERR TTM_PFX "Illegal buffer object type\n"); |
296 | diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c |
297 | index 58d5436..6d3de08 100644 |
298 | --- a/drivers/mmc/host/sdhci.c |
299 | +++ b/drivers/mmc/host/sdhci.c |
300 | @@ -1863,9 +1863,6 @@ static void sdhci_tasklet_finish(unsigned long param) |
301 | |
302 | del_timer(&host->timer); |
303 | |
304 | - if (host->version >= SDHCI_SPEC_300) |
305 | - del_timer(&host->tuning_timer); |
306 | - |
307 | mrq = host->mrq; |
308 | |
309 | /* |
310 | diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c |
311 | index 0f563c8..493e331 100644 |
312 | --- a/drivers/net/igb/e1000_82575.c |
313 | +++ b/drivers/net/igb/e1000_82575.c |
314 | @@ -1735,6 +1735,7 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw) |
315 | ctrl |= E1000_CTRL_RST; |
316 | |
317 | wr32(E1000_CTRL, ctrl); |
318 | + wrfl(); |
319 | |
320 | /* Add delay to insure DEV_RST has time to complete */ |
321 | if (global_device_reset) |
322 | diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c |
323 | index 8f90f62..241a099 100644 |
324 | --- a/drivers/net/wireless/rt2x00/rt2x00usb.c |
325 | +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c |
326 | @@ -262,23 +262,20 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) |
327 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
328 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
329 | |
330 | - if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
331 | + if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
332 | return; |
333 | - |
334 | - if (rt2x00dev->ops->lib->tx_dma_done) |
335 | - rt2x00dev->ops->lib->tx_dma_done(entry); |
336 | - |
337 | - /* |
338 | - * Report the frame as DMA done |
339 | - */ |
340 | - rt2x00lib_dmadone(entry); |
341 | - |
342 | /* |
343 | * Check if the frame was correctly uploaded |
344 | */ |
345 | if (urb->status) |
346 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); |
347 | + /* |
348 | + * Report the frame as DMA done |
349 | + */ |
350 | + rt2x00lib_dmadone(entry); |
351 | |
352 | + if (rt2x00dev->ops->lib->tx_dma_done) |
353 | + rt2x00dev->ops->lib->tx_dma_done(entry); |
354 | /* |
355 | * Schedule the delayed work for reading the TX status |
356 | * from the device. |
357 | diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c |
358 | index 54b8c28..720d885 100644 |
359 | --- a/fs/befs/linuxvfs.c |
360 | +++ b/fs/befs/linuxvfs.c |
361 | @@ -474,17 +474,22 @@ befs_follow_link(struct dentry *dentry, struct nameidata *nd) |
362 | befs_data_stream *data = &befs_ino->i_data.ds; |
363 | befs_off_t len = data->size; |
364 | |
365 | - befs_debug(sb, "Follow long symlink"); |
366 | - |
367 | - link = kmalloc(len, GFP_NOFS); |
368 | - if (!link) { |
369 | - link = ERR_PTR(-ENOMEM); |
370 | - } else if (befs_read_lsymlink(sb, data, link, len) != len) { |
371 | - kfree(link); |
372 | - befs_error(sb, "Failed to read entire long symlink"); |
373 | + if (len == 0) { |
374 | + befs_error(sb, "Long symlink with illegal length"); |
375 | link = ERR_PTR(-EIO); |
376 | } else { |
377 | - link[len - 1] = '\0'; |
378 | + befs_debug(sb, "Follow long symlink"); |
379 | + |
380 | + link = kmalloc(len, GFP_NOFS); |
381 | + if (!link) { |
382 | + link = ERR_PTR(-ENOMEM); |
383 | + } else if (befs_read_lsymlink(sb, data, link, len) != len) { |
384 | + kfree(link); |
385 | + befs_error(sb, "Failed to read entire long symlink"); |
386 | + link = ERR_PTR(-EIO); |
387 | + } else { |
388 | + link[len - 1] = '\0'; |
389 | + } |
390 | } |
391 | } else { |
392 | link = befs_ino->i_data.symlink; |
393 | diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c |
394 | index 71cd456..7e20a65 100644 |
395 | --- a/fs/btrfs/extent-tree.c |
396 | +++ b/fs/btrfs/extent-tree.c |
397 | @@ -1784,6 +1784,9 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, |
398 | |
399 | |
400 | for (i = 0; i < multi->num_stripes; i++, stripe++) { |
401 | + if (!stripe->dev->can_discard) |
402 | + continue; |
403 | + |
404 | ret = btrfs_issue_discard(stripe->dev->bdev, |
405 | stripe->physical, |
406 | stripe->length); |
407 | @@ -1791,11 +1794,16 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, |
408 | discarded_bytes += stripe->length; |
409 | else if (ret != -EOPNOTSUPP) |
410 | break; |
411 | + |
412 | + /* |
413 | + * Just in case we get back EOPNOTSUPP for some reason, |
414 | + * just ignore the return value so we don't screw up |
415 | + * people calling discard_extent. |
416 | + */ |
417 | + ret = 0; |
418 | } |
419 | kfree(multi); |
420 | } |
421 | - if (discarded_bytes && ret == -EOPNOTSUPP) |
422 | - ret = 0; |
423 | |
424 | if (actual_bytes) |
425 | *actual_bytes = discarded_bytes; |
426 | diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c |
427 | index 4ce8a9f..7fa128d 100644 |
428 | --- a/fs/btrfs/tree-log.c |
429 | +++ b/fs/btrfs/tree-log.c |
430 | @@ -799,14 +799,15 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, |
431 | struct extent_buffer *eb, int slot, |
432 | struct btrfs_key *key) |
433 | { |
434 | - struct inode *dir; |
435 | - int ret; |
436 | struct btrfs_inode_ref *ref; |
437 | + struct btrfs_dir_item *di; |
438 | + struct inode *dir; |
439 | struct inode *inode; |
440 | - char *name; |
441 | - int namelen; |
442 | unsigned long ref_ptr; |
443 | unsigned long ref_end; |
444 | + char *name; |
445 | + int namelen; |
446 | + int ret; |
447 | int search_done = 0; |
448 | |
449 | /* |
450 | @@ -909,6 +910,25 @@ again: |
451 | } |
452 | btrfs_release_path(path); |
453 | |
454 | + /* look for a conflicting sequence number */ |
455 | + di = btrfs_lookup_dir_index_item(trans, root, path, btrfs_ino(dir), |
456 | + btrfs_inode_ref_index(eb, ref), |
457 | + name, namelen, 0); |
458 | + if (di && !IS_ERR(di)) { |
459 | + ret = drop_one_dir_item(trans, root, path, dir, di); |
460 | + BUG_ON(ret); |
461 | + } |
462 | + btrfs_release_path(path); |
463 | + |
464 | + /* look for a conflicing name */ |
465 | + di = btrfs_lookup_dir_item(trans, root, path, btrfs_ino(dir), |
466 | + name, namelen, 0); |
467 | + if (di && !IS_ERR(di)) { |
468 | + ret = drop_one_dir_item(trans, root, path, dir, di); |
469 | + BUG_ON(ret); |
470 | + } |
471 | + btrfs_release_path(path); |
472 | + |
473 | insert: |
474 | /* insert our name */ |
475 | ret = btrfs_add_link(trans, dir, inode, name, namelen, 0, |
476 | diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c |
477 | index 19450bc..43baaf0 100644 |
478 | --- a/fs/btrfs/volumes.c |
479 | +++ b/fs/btrfs/volumes.c |
480 | @@ -500,6 +500,9 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) |
481 | fs_devices->rw_devices--; |
482 | } |
483 | |
484 | + if (device->can_discard) |
485 | + fs_devices->num_can_discard--; |
486 | + |
487 | new_device = kmalloc(sizeof(*new_device), GFP_NOFS); |
488 | BUG_ON(!new_device); |
489 | memcpy(new_device, device, sizeof(*new_device)); |
490 | @@ -508,6 +511,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) |
491 | new_device->bdev = NULL; |
492 | new_device->writeable = 0; |
493 | new_device->in_fs_metadata = 0; |
494 | + new_device->can_discard = 0; |
495 | list_replace_rcu(&device->dev_list, &new_device->dev_list); |
496 | |
497 | call_rcu(&device->rcu, free_device); |
498 | @@ -547,6 +551,7 @@ int btrfs_close_devices(struct btrfs_fs_devices *fs_devices) |
499 | static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, |
500 | fmode_t flags, void *holder) |
501 | { |
502 | + struct request_queue *q; |
503 | struct block_device *bdev; |
504 | struct list_head *head = &fs_devices->devices; |
505 | struct btrfs_device *device; |
506 | @@ -603,6 +608,12 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, |
507 | seeding = 0; |
508 | } |
509 | |
510 | + q = bdev_get_queue(bdev); |
511 | + if (blk_queue_discard(q)) { |
512 | + device->can_discard = 1; |
513 | + fs_devices->num_can_discard++; |
514 | + } |
515 | + |
516 | device->bdev = bdev; |
517 | device->in_fs_metadata = 0; |
518 | device->mode = flags; |
519 | @@ -1542,6 +1553,7 @@ error: |
520 | |
521 | int btrfs_init_new_device(struct btrfs_root *root, char *device_path) |
522 | { |
523 | + struct request_queue *q; |
524 | struct btrfs_trans_handle *trans; |
525 | struct btrfs_device *device; |
526 | struct block_device *bdev; |
527 | @@ -1611,6 +1623,9 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) |
528 | |
529 | lock_chunks(root); |
530 | |
531 | + q = bdev_get_queue(bdev); |
532 | + if (blk_queue_discard(q)) |
533 | + device->can_discard = 1; |
534 | device->writeable = 1; |
535 | device->work.func = pending_bios_fn; |
536 | generate_random_uuid(device->uuid); |
537 | @@ -1646,6 +1661,8 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) |
538 | root->fs_info->fs_devices->num_devices++; |
539 | root->fs_info->fs_devices->open_devices++; |
540 | root->fs_info->fs_devices->rw_devices++; |
541 | + if (device->can_discard) |
542 | + root->fs_info->fs_devices->num_can_discard++; |
543 | root->fs_info->fs_devices->total_rw_bytes += device->total_bytes; |
544 | |
545 | if (!blk_queue_nonrot(bdev_get_queue(bdev))) |
546 | diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h |
547 | index 7c12d61..6d866db 100644 |
548 | --- a/fs/btrfs/volumes.h |
549 | +++ b/fs/btrfs/volumes.h |
550 | @@ -48,6 +48,7 @@ struct btrfs_device { |
551 | int writeable; |
552 | int in_fs_metadata; |
553 | int missing; |
554 | + int can_discard; |
555 | |
556 | spinlock_t io_lock; |
557 | |
558 | @@ -104,6 +105,7 @@ struct btrfs_fs_devices { |
559 | u64 rw_devices; |
560 | u64 missing_devices; |
561 | u64 total_rw_bytes; |
562 | + u64 num_can_discard; |
563 | struct block_device *latest_bdev; |
564 | |
565 | /* all of the devices in the FS, protected by a mutex |
566 | diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c |
567 | index ccc1afa..e0ea721 100644 |
568 | --- a/fs/cifs/connect.c |
569 | +++ b/fs/cifs/connect.c |
570 | @@ -2838,7 +2838,8 @@ cleanup_volume_info_contents(struct smb_vol *volume_info) |
571 | kfree(volume_info->username); |
572 | kzfree(volume_info->password); |
573 | kfree(volume_info->UNC); |
574 | - kfree(volume_info->UNCip); |
575 | + if (volume_info->UNCip != volume_info->UNC + 2) |
576 | + kfree(volume_info->UNCip); |
577 | kfree(volume_info->domainname); |
578 | kfree(volume_info->iocharset); |
579 | kfree(volume_info->prepath); |
580 | diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c |
581 | index d8d26f3..16cdd6d 100644 |
582 | --- a/fs/cifs/dir.c |
583 | +++ b/fs/cifs/dir.c |
584 | @@ -110,8 +110,8 @@ cifs_bp_rename_retry: |
585 | } |
586 | rcu_read_unlock(); |
587 | if (namelen != dfsplen || read_seqretry(&rename_lock, seq)) { |
588 | - cERROR(1, "did not end path lookup where expected namelen is %d", |
589 | - namelen); |
590 | + cFYI(1, "did not end path lookup where expected. namelen=%d " |
591 | + "dfsplen=%d", namelen, dfsplen); |
592 | /* presumably this is only possible if racing with a rename |
593 | of one of the parent directories (we can not lock the dentries |
594 | above us to prevent this, but retrying should be harmless) */ |
595 | diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h |
596 | index bb85757..5802fa1 100644 |
597 | --- a/fs/ext4/ext4_jbd2.h |
598 | +++ b/fs/ext4/ext4_jbd2.h |
599 | @@ -289,10 +289,10 @@ static inline int ext4_should_order_data(struct inode *inode) |
600 | |
601 | static inline int ext4_should_writeback_data(struct inode *inode) |
602 | { |
603 | - if (!S_ISREG(inode->i_mode)) |
604 | - return 0; |
605 | if (EXT4_JOURNAL(inode) == NULL) |
606 | return 1; |
607 | + if (!S_ISREG(inode->i_mode)) |
608 | + return 0; |
609 | if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA)) |
610 | return 0; |
611 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) |
612 | diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c |
613 | index e3126c0..b864839 100644 |
614 | --- a/fs/ext4/inode.c |
615 | +++ b/fs/ext4/inode.c |
616 | @@ -189,6 +189,12 @@ void ext4_evict_inode(struct inode *inode) |
617 | int err; |
618 | |
619 | trace_ext4_evict_inode(inode); |
620 | + |
621 | + mutex_lock(&inode->i_mutex); |
622 | + ext4_flush_completed_IO(inode); |
623 | + mutex_unlock(&inode->i_mutex); |
624 | + ext4_ioend_wait(inode); |
625 | + |
626 | if (inode->i_nlink) { |
627 | truncate_inode_pages(&inode->i_data, 0); |
628 | goto no_delete; |
629 | @@ -1849,6 +1855,8 @@ static int ext4_journalled_write_end(struct file *file, |
630 | from = pos & (PAGE_CACHE_SIZE - 1); |
631 | to = from + len; |
632 | |
633 | + BUG_ON(!ext4_handle_valid(handle)); |
634 | + |
635 | if (copied < len) { |
636 | if (!PageUptodate(page)) |
637 | copied = 0; |
638 | @@ -2148,7 +2156,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, |
639 | else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT)) |
640 | err = ext4_bio_write_page(&io_submit, page, |
641 | len, mpd->wbc); |
642 | - else |
643 | + else if (buffer_uninit(page_bufs)) { |
644 | + ext4_set_bh_endio(page_bufs, inode); |
645 | + err = block_write_full_page_endio(page, |
646 | + noalloc_get_block_write, |
647 | + mpd->wbc, ext4_end_io_buffer_write); |
648 | + } else |
649 | err = block_write_full_page(page, |
650 | noalloc_get_block_write, mpd->wbc); |
651 | |
652 | @@ -2564,6 +2577,8 @@ static int __ext4_journalled_writepage(struct page *page, |
653 | goto out; |
654 | } |
655 | |
656 | + BUG_ON(!ext4_handle_valid(handle)); |
657 | + |
658 | ret = walk_page_buffers(handle, page_bufs, 0, len, NULL, |
659 | do_journal_get_write_access); |
660 | |
661 | @@ -3635,8 +3650,15 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate) |
662 | goto out; |
663 | } |
664 | |
665 | - io_end->flag = EXT4_IO_END_UNWRITTEN; |
666 | + /* |
667 | + * It may be over-defensive here to check EXT4_IO_END_UNWRITTEN now, |
668 | + * but being more careful is always safe for the future change. |
669 | + */ |
670 | inode = io_end->inode; |
671 | + if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) { |
672 | + io_end->flag |= EXT4_IO_END_UNWRITTEN; |
673 | + atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten); |
674 | + } |
675 | |
676 | /* Add the io_end to per-inode completed io list*/ |
677 | spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags); |
678 | diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c |
679 | index 7bb8f76..97e5e98 100644 |
680 | --- a/fs/ext4/page-io.c |
681 | +++ b/fs/ext4/page-io.c |
682 | @@ -338,8 +338,10 @@ submit_and_retry: |
683 | if ((io_end->num_io_pages >= MAX_IO_PAGES) && |
684 | (io_end->pages[io_end->num_io_pages-1] != io_page)) |
685 | goto submit_and_retry; |
686 | - if (buffer_uninit(bh)) |
687 | - io->io_end->flag |= EXT4_IO_END_UNWRITTEN; |
688 | + if (buffer_uninit(bh) && !(io_end->flag & EXT4_IO_END_UNWRITTEN)) { |
689 | + io_end->flag |= EXT4_IO_END_UNWRITTEN; |
690 | + atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten); |
691 | + } |
692 | io->io_end->size += bh->b_size; |
693 | io->io_next_block++; |
694 | ret = bio_add_page(io->io_bio, bh->b_page, bh->b_size, bh_offset(bh)); |
695 | diff --git a/fs/ext4/super.c b/fs/ext4/super.c |
696 | index 9ea71aa..111ed9d 100644 |
697 | --- a/fs/ext4/super.c |
698 | +++ b/fs/ext4/super.c |
699 | @@ -892,7 +892,6 @@ static void ext4_i_callback(struct rcu_head *head) |
700 | |
701 | static void ext4_destroy_inode(struct inode *inode) |
702 | { |
703 | - ext4_ioend_wait(inode); |
704 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { |
705 | ext4_msg(inode->i_sb, KERN_ERR, |
706 | "Inode %lu (%p): orphan list check failed!", |
707 | diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c |
708 | index 640fc22..168a80f 100644 |
709 | --- a/fs/fuse/dev.c |
710 | +++ b/fs/fuse/dev.c |
711 | @@ -1358,6 +1358,10 @@ static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size, |
712 | if (outarg.namelen > FUSE_NAME_MAX) |
713 | goto err; |
714 | |
715 | + err = -EINVAL; |
716 | + if (size != sizeof(outarg) + outarg.namelen + 1) |
717 | + goto err; |
718 | + |
719 | name.name = buf; |
720 | name.len = outarg.namelen; |
721 | err = fuse_copy_one(cs, buf, outarg.namelen + 1); |
722 | diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h |
723 | index b257383..07df5f1 100644 |
724 | --- a/fs/nfs/callback.h |
725 | +++ b/fs/nfs/callback.h |
726 | @@ -38,6 +38,7 @@ enum nfs4_callback_opnum { |
727 | struct cb_process_state { |
728 | __be32 drc_status; |
729 | struct nfs_client *clp; |
730 | + int slotid; |
731 | }; |
732 | |
733 | struct cb_compound_hdr_arg { |
734 | @@ -166,7 +167,6 @@ extern unsigned nfs4_callback_layoutrecall( |
735 | void *dummy, struct cb_process_state *cps); |
736 | |
737 | extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses); |
738 | -extern void nfs4_cb_take_slot(struct nfs_client *clp); |
739 | |
740 | struct cb_devicenotifyitem { |
741 | uint32_t cbd_notify_type; |
742 | diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c |
743 | index d4d1954..aaa09e9 100644 |
744 | --- a/fs/nfs/callback_proc.c |
745 | +++ b/fs/nfs/callback_proc.c |
746 | @@ -333,7 +333,7 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args) |
747 | /* Normal */ |
748 | if (likely(args->csa_sequenceid == slot->seq_nr + 1)) { |
749 | slot->seq_nr++; |
750 | - return htonl(NFS4_OK); |
751 | + goto out_ok; |
752 | } |
753 | |
754 | /* Replay */ |
755 | @@ -352,11 +352,14 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args) |
756 | /* Wraparound */ |
757 | if (args->csa_sequenceid == 1 && (slot->seq_nr + 1) == 0) { |
758 | slot->seq_nr = 1; |
759 | - return htonl(NFS4_OK); |
760 | + goto out_ok; |
761 | } |
762 | |
763 | /* Misordered request */ |
764 | return htonl(NFS4ERR_SEQ_MISORDERED); |
765 | +out_ok: |
766 | + tbl->highest_used_slotid = args->csa_slotid; |
767 | + return htonl(NFS4_OK); |
768 | } |
769 | |
770 | /* |
771 | @@ -418,26 +421,37 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, |
772 | struct cb_sequenceres *res, |
773 | struct cb_process_state *cps) |
774 | { |
775 | + struct nfs4_slot_table *tbl; |
776 | struct nfs_client *clp; |
777 | int i; |
778 | __be32 status = htonl(NFS4ERR_BADSESSION); |
779 | |
780 | - cps->clp = NULL; |
781 | - |
782 | clp = nfs4_find_client_sessionid(args->csa_addr, &args->csa_sessionid); |
783 | if (clp == NULL) |
784 | goto out; |
785 | |
786 | + tbl = &clp->cl_session->bc_slot_table; |
787 | + |
788 | + spin_lock(&tbl->slot_tbl_lock); |
789 | /* state manager is resetting the session */ |
790 | if (test_bit(NFS4_SESSION_DRAINING, &clp->cl_session->session_state)) { |
791 | - status = NFS4ERR_DELAY; |
792 | + spin_unlock(&tbl->slot_tbl_lock); |
793 | + status = htonl(NFS4ERR_DELAY); |
794 | + /* Return NFS4ERR_BADSESSION if we're draining the session |
795 | + * in order to reset it. |
796 | + */ |
797 | + if (test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state)) |
798 | + status = htonl(NFS4ERR_BADSESSION); |
799 | goto out; |
800 | } |
801 | |
802 | status = validate_seqid(&clp->cl_session->bc_slot_table, args); |
803 | + spin_unlock(&tbl->slot_tbl_lock); |
804 | if (status) |
805 | goto out; |
806 | |
807 | + cps->slotid = args->csa_slotid; |
808 | + |
809 | /* |
810 | * Check for pending referring calls. If a match is found, a |
811 | * related callback was received before the response to the original |
812 | @@ -454,7 +468,6 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, |
813 | res->csr_slotid = args->csa_slotid; |
814 | res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; |
815 | res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; |
816 | - nfs4_cb_take_slot(clp); |
817 | |
818 | out: |
819 | cps->clp = clp; /* put in nfs4_callback_compound */ |
820 | diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c |
821 | index c6c86a7..918ad64 100644 |
822 | --- a/fs/nfs/callback_xdr.c |
823 | +++ b/fs/nfs/callback_xdr.c |
824 | @@ -754,26 +754,15 @@ static void nfs4_callback_free_slot(struct nfs4_session *session) |
825 | * Let the state manager know callback processing done. |
826 | * A single slot, so highest used slotid is either 0 or -1 |
827 | */ |
828 | - tbl->highest_used_slotid--; |
829 | + tbl->highest_used_slotid = -1; |
830 | nfs4_check_drain_bc_complete(session); |
831 | spin_unlock(&tbl->slot_tbl_lock); |
832 | } |
833 | |
834 | -static void nfs4_cb_free_slot(struct nfs_client *clp) |
835 | +static void nfs4_cb_free_slot(struct cb_process_state *cps) |
836 | { |
837 | - if (clp && clp->cl_session) |
838 | - nfs4_callback_free_slot(clp->cl_session); |
839 | -} |
840 | - |
841 | -/* A single slot, so highest used slotid is either 0 or -1 */ |
842 | -void nfs4_cb_take_slot(struct nfs_client *clp) |
843 | -{ |
844 | - struct nfs4_slot_table *tbl = &clp->cl_session->bc_slot_table; |
845 | - |
846 | - spin_lock(&tbl->slot_tbl_lock); |
847 | - tbl->highest_used_slotid++; |
848 | - BUG_ON(tbl->highest_used_slotid != 0); |
849 | - spin_unlock(&tbl->slot_tbl_lock); |
850 | + if (cps->slotid != -1) |
851 | + nfs4_callback_free_slot(cps->clp->cl_session); |
852 | } |
853 | |
854 | #else /* CONFIG_NFS_V4_1 */ |
855 | @@ -784,7 +773,7 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) |
856 | return htonl(NFS4ERR_MINOR_VERS_MISMATCH); |
857 | } |
858 | |
859 | -static void nfs4_cb_free_slot(struct nfs_client *clp) |
860 | +static void nfs4_cb_free_slot(struct cb_process_state *cps) |
861 | { |
862 | } |
863 | #endif /* CONFIG_NFS_V4_1 */ |
864 | @@ -866,6 +855,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r |
865 | struct cb_process_state cps = { |
866 | .drc_status = 0, |
867 | .clp = NULL, |
868 | + .slotid = -1, |
869 | }; |
870 | unsigned int nops = 0; |
871 | |
872 | @@ -906,7 +896,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r |
873 | |
874 | *hdr_res.status = status; |
875 | *hdr_res.nops = htonl(nops); |
876 | - nfs4_cb_free_slot(cps.clp); |
877 | + nfs4_cb_free_slot(&cps); |
878 | nfs_put_client(cps.clp); |
879 | dprintk("%s: done, status = %u\n", __func__, ntohl(status)); |
880 | return rpc_success; |
881 | diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c |
882 | index 8ff2ea3..1d1dc1e 100644 |
883 | --- a/fs/nfs/objlayout/objio_osd.c |
884 | +++ b/fs/nfs/objlayout/objio_osd.c |
885 | @@ -479,7 +479,6 @@ static int _io_check(struct objio_state *ios, bool is_write) |
886 | for (i = 0; i < ios->numdevs; i++) { |
887 | struct osd_sense_info osi; |
888 | struct osd_request *or = ios->per_dev[i].or; |
889 | - unsigned dev; |
890 | int ret; |
891 | |
892 | if (!or) |
893 | @@ -500,9 +499,8 @@ static int _io_check(struct objio_state *ios, bool is_write) |
894 | |
895 | continue; /* we recovered */ |
896 | } |
897 | - dev = ios->per_dev[i].dev; |
898 | - objlayout_io_set_result(&ios->ol_state, dev, |
899 | - &ios->layout->comps[dev].oc_object_id, |
900 | + objlayout_io_set_result(&ios->ol_state, i, |
901 | + &ios->layout->comps[i].oc_object_id, |
902 | osd_pri_2_pnfs_err(osi.osd_err_pri), |
903 | ios->per_dev[i].offset, |
904 | ios->per_dev[i].length, |
905 | @@ -589,22 +587,19 @@ static void _calc_stripe_info(struct objio_state *ios, u64 file_offset, |
906 | } |
907 | |
908 | static int _add_stripe_unit(struct objio_state *ios, unsigned *cur_pg, |
909 | - unsigned pgbase, struct _objio_per_comp *per_dev, int cur_len, |
910 | + unsigned pgbase, struct _objio_per_comp *per_dev, int len, |
911 | gfp_t gfp_flags) |
912 | { |
913 | unsigned pg = *cur_pg; |
914 | + int cur_len = len; |
915 | struct request_queue *q = |
916 | osd_request_queue(_io_od(ios, per_dev->dev)); |
917 | |
918 | - per_dev->length += cur_len; |
919 | - |
920 | if (per_dev->bio == NULL) { |
921 | - unsigned stripes = ios->layout->num_comps / |
922 | - ios->layout->mirrors_p1; |
923 | - unsigned pages_in_stripe = stripes * |
924 | + unsigned pages_in_stripe = ios->layout->group_width * |
925 | (ios->layout->stripe_unit / PAGE_SIZE); |
926 | unsigned bio_size = (ios->ol_state.nr_pages + pages_in_stripe) / |
927 | - stripes; |
928 | + ios->layout->group_width; |
929 | |
930 | if (BIO_MAX_PAGES_KMALLOC < bio_size) |
931 | bio_size = BIO_MAX_PAGES_KMALLOC; |
932 | @@ -632,6 +627,7 @@ static int _add_stripe_unit(struct objio_state *ios, unsigned *cur_pg, |
933 | } |
934 | BUG_ON(cur_len); |
935 | |
936 | + per_dev->length += len; |
937 | *cur_pg = pg; |
938 | return 0; |
939 | } |
940 | @@ -650,7 +646,7 @@ static int _prepare_one_group(struct objio_state *ios, u64 length, |
941 | int ret = 0; |
942 | |
943 | while (length) { |
944 | - struct _objio_per_comp *per_dev = &ios->per_dev[dev]; |
945 | + struct _objio_per_comp *per_dev = &ios->per_dev[dev - first_dev]; |
946 | unsigned cur_len, page_off = 0; |
947 | |
948 | if (!per_dev->length) { |
949 | @@ -670,8 +666,8 @@ static int _prepare_one_group(struct objio_state *ios, u64 length, |
950 | cur_len = stripe_unit; |
951 | } |
952 | |
953 | - if (max_comp < dev) |
954 | - max_comp = dev; |
955 | + if (max_comp < dev - first_dev) |
956 | + max_comp = dev - first_dev; |
957 | } else { |
958 | cur_len = stripe_unit; |
959 | } |
960 | @@ -806,7 +802,7 @@ static int _read_mirrors(struct objio_state *ios, unsigned cur_comp) |
961 | struct _objio_per_comp *per_dev = &ios->per_dev[cur_comp]; |
962 | unsigned dev = per_dev->dev; |
963 | struct pnfs_osd_object_cred *cred = |
964 | - &ios->layout->comps[dev]; |
965 | + &ios->layout->comps[cur_comp]; |
966 | struct osd_obj_id obj = { |
967 | .partition = cred->oc_object_id.oid_partition_id, |
968 | .id = cred->oc_object_id.oid_object_id, |
969 | @@ -904,7 +900,7 @@ static int _write_mirrors(struct objio_state *ios, unsigned cur_comp) |
970 | for (; cur_comp < last_comp; ++cur_comp, ++dev) { |
971 | struct osd_request *or = NULL; |
972 | struct pnfs_osd_object_cred *cred = |
973 | - &ios->layout->comps[dev]; |
974 | + &ios->layout->comps[cur_comp]; |
975 | struct osd_obj_id obj = { |
976 | .partition = cred->oc_object_id.oid_partition_id, |
977 | .id = cred->oc_object_id.oid_object_id, |
978 | diff --git a/fs/nfs/objlayout/pnfs_osd_xdr_cli.c b/fs/nfs/objlayout/pnfs_osd_xdr_cli.c |
979 | index 16fc758..b3918f7 100644 |
980 | --- a/fs/nfs/objlayout/pnfs_osd_xdr_cli.c |
981 | +++ b/fs/nfs/objlayout/pnfs_osd_xdr_cli.c |
982 | @@ -170,6 +170,9 @@ int pnfs_osd_xdr_decode_layout_map(struct pnfs_osd_layout *layout, |
983 | p = _osd_xdr_decode_data_map(p, &layout->olo_map); |
984 | layout->olo_comps_index = be32_to_cpup(p++); |
985 | layout->olo_num_comps = be32_to_cpup(p++); |
986 | + dprintk("%s: olo_comps_index=%d olo_num_comps=%d\n", __func__, |
987 | + layout->olo_comps_index, layout->olo_num_comps); |
988 | + |
989 | iter->total_comps = layout->olo_num_comps; |
990 | return 0; |
991 | } |
992 | diff --git a/include/linux/personality.h b/include/linux/personality.h |
993 | index eec3bae..8fc7dd1a 100644 |
994 | --- a/include/linux/personality.h |
995 | +++ b/include/linux/personality.h |
996 | @@ -22,6 +22,7 @@ extern int __set_personality(unsigned int); |
997 | * These occupy the top three bytes. |
998 | */ |
999 | enum { |
1000 | + UNAME26 = 0x0020000, |
1001 | ADDR_NO_RANDOMIZE = 0x0040000, /* disable randomization of VA space */ |
1002 | FDPIC_FUNCPTRS = 0x0080000, /* userspace function ptrs point to descriptors |
1003 | * (signal handling) |
1004 | diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h |
1005 | index 092dc9b..14d3524 100644 |
1006 | --- a/include/linux/stop_machine.h |
1007 | +++ b/include/linux/stop_machine.h |
1008 | @@ -27,6 +27,8 @@ struct cpu_stop_work { |
1009 | struct cpu_stop_done *done; |
1010 | }; |
1011 | |
1012 | +extern struct mutex stop_cpus_mutex; |
1013 | + |
1014 | int stop_one_cpu(unsigned int cpu, cpu_stop_fn_t fn, void *arg); |
1015 | void stop_one_cpu_nowait(unsigned int cpu, cpu_stop_fn_t fn, void *arg, |
1016 | struct cpu_stop_work *work_buf); |
1017 | diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c |
1018 | index 3a2cab4..e38544d 100644 |
1019 | --- a/kernel/irq/generic-chip.c |
1020 | +++ b/kernel/irq/generic-chip.c |
1021 | @@ -246,7 +246,7 @@ void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk, |
1022 | gc->mask_cache = irq_reg_readl(gc->reg_base + ct->regs.mask); |
1023 | |
1024 | for (i = gc->irq_base; msk; msk >>= 1, i++) { |
1025 | - if (!msk & 0x01) |
1026 | + if (!(msk & 0x01)) |
1027 | continue; |
1028 | |
1029 | if (flags & IRQ_GC_INIT_NESTED_LOCK) |
1030 | @@ -301,7 +301,7 @@ void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk, |
1031 | raw_spin_unlock(&gc_lock); |
1032 | |
1033 | for (; msk; msk >>= 1, i++) { |
1034 | - if (!msk & 0x01) |
1035 | + if (!(msk & 0x01)) |
1036 | continue; |
1037 | |
1038 | /* Remove handler first. That will mask the irq line */ |
1039 | diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c |
1040 | index e3516b2..0cae1cc 100644 |
1041 | --- a/kernel/stop_machine.c |
1042 | +++ b/kernel/stop_machine.c |
1043 | @@ -132,8 +132,8 @@ void stop_one_cpu_nowait(unsigned int cpu, cpu_stop_fn_t fn, void *arg, |
1044 | cpu_stop_queue_work(&per_cpu(cpu_stopper, cpu), work_buf); |
1045 | } |
1046 | |
1047 | +DEFINE_MUTEX(stop_cpus_mutex); |
1048 | /* static data for stop_cpus */ |
1049 | -static DEFINE_MUTEX(stop_cpus_mutex); |
1050 | static DEFINE_PER_CPU(struct cpu_stop_work, stop_cpus_work); |
1051 | |
1052 | int __stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg) |
1053 | diff --git a/kernel/sys.c b/kernel/sys.c |
1054 | index e4128b2..5c942cf 100644 |
1055 | --- a/kernel/sys.c |
1056 | +++ b/kernel/sys.c |
1057 | @@ -38,6 +38,8 @@ |
1058 | #include <linux/fs_struct.h> |
1059 | #include <linux/gfp.h> |
1060 | #include <linux/syscore_ops.h> |
1061 | +#include <linux/version.h> |
1062 | +#include <linux/ctype.h> |
1063 | |
1064 | #include <linux/compat.h> |
1065 | #include <linux/syscalls.h> |
1066 | @@ -45,6 +47,8 @@ |
1067 | #include <linux/user_namespace.h> |
1068 | |
1069 | #include <linux/kmsg_dump.h> |
1070 | +/* Move somewhere else to avoid recompiling? */ |
1071 | +#include <generated/utsrelease.h> |
1072 | |
1073 | #include <asm/uaccess.h> |
1074 | #include <asm/io.h> |
1075 | @@ -1124,6 +1128,34 @@ DECLARE_RWSEM(uts_sem); |
1076 | #define override_architecture(name) 0 |
1077 | #endif |
1078 | |
1079 | +/* |
1080 | + * Work around broken programs that cannot handle "Linux 3.0". |
1081 | + * Instead we map 3.x to 2.6.40+x, so e.g. 3.0 would be 2.6.40 |
1082 | + */ |
1083 | +static int override_release(char __user *release, int len) |
1084 | +{ |
1085 | + int ret = 0; |
1086 | + char buf[len]; |
1087 | + |
1088 | + if (current->personality & UNAME26) { |
1089 | + char *rest = UTS_RELEASE; |
1090 | + int ndots = 0; |
1091 | + unsigned v; |
1092 | + |
1093 | + while (*rest) { |
1094 | + if (*rest == '.' && ++ndots >= 3) |
1095 | + break; |
1096 | + if (!isdigit(*rest) && *rest != '.') |
1097 | + break; |
1098 | + rest++; |
1099 | + } |
1100 | + v = ((LINUX_VERSION_CODE >> 8) & 0xff) + 40; |
1101 | + snprintf(buf, len, "2.6.%u%s", v, rest); |
1102 | + ret = copy_to_user(release, buf, len); |
1103 | + } |
1104 | + return ret; |
1105 | +} |
1106 | + |
1107 | SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name) |
1108 | { |
1109 | int errno = 0; |
1110 | @@ -1133,6 +1165,8 @@ SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name) |
1111 | errno = -EFAULT; |
1112 | up_read(&uts_sem); |
1113 | |
1114 | + if (!errno && override_release(name->release, sizeof(name->release))) |
1115 | + errno = -EFAULT; |
1116 | if (!errno && override_architecture(name)) |
1117 | errno = -EFAULT; |
1118 | return errno; |
1119 | @@ -1154,6 +1188,8 @@ SYSCALL_DEFINE1(uname, struct old_utsname __user *, name) |
1120 | error = -EFAULT; |
1121 | up_read(&uts_sem); |
1122 | |
1123 | + if (!error && override_release(name->release, sizeof(name->release))) |
1124 | + error = -EFAULT; |
1125 | if (!error && override_architecture(name)) |
1126 | error = -EFAULT; |
1127 | return error; |
1128 | @@ -1188,6 +1224,8 @@ SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name) |
1129 | |
1130 | if (!error && override_architecture(name)) |
1131 | error = -EFAULT; |
1132 | + if (!error && override_release(name->release, sizeof(name->release))) |
1133 | + error = -EFAULT; |
1134 | return error ? -EFAULT : 0; |
1135 | } |
1136 | #endif |
1137 | diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c |
1138 | index 200c9a1..a872d0a 100644 |
1139 | --- a/sound/pci/ac97/ac97_patch.c |
1140 | +++ b/sound/pci/ac97/ac97_patch.c |
1141 | @@ -1909,6 +1909,7 @@ static unsigned int ad1981_jacks_whitelist[] = { |
1142 | 0x103c0944, /* HP nc6220 */ |
1143 | 0x103c0934, /* HP nc8220 */ |
1144 | 0x103c006d, /* HP nx9105 */ |
1145 | + 0x103c300d, /* HP Compaq dc5100 SFF(PT003AW) */ |
1146 | 0x17340088, /* FSC Scenic-W */ |
1147 | 0 /* end */ |
1148 | }; |
1149 | diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c |
1150 | index aa52b3e..2cf87f5 100644 |
1151 | --- a/sound/usb/caiaq/audio.c |
1152 | +++ b/sound/usb/caiaq/audio.c |
1153 | @@ -139,8 +139,12 @@ static void stream_stop(struct snd_usb_caiaqdev *dev) |
1154 | |
1155 | for (i = 0; i < N_URBS; i++) { |
1156 | usb_kill_urb(dev->data_urbs_in[i]); |
1157 | - usb_kill_urb(dev->data_urbs_out[i]); |
1158 | + |
1159 | + if (test_bit(i, &dev->outurb_active_mask)) |
1160 | + usb_kill_urb(dev->data_urbs_out[i]); |
1161 | } |
1162 | + |
1163 | + dev->outurb_active_mask = 0; |
1164 | } |
1165 | |
1166 | static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream) |
1167 | @@ -612,8 +616,8 @@ static void read_completed(struct urb *urb) |
1168 | { |
1169 | struct snd_usb_caiaq_cb_info *info = urb->context; |
1170 | struct snd_usb_caiaqdev *dev; |
1171 | - struct urb *out; |
1172 | - int frame, len, send_it = 0, outframe = 0; |
1173 | + struct urb *out = NULL; |
1174 | + int i, frame, len, send_it = 0, outframe = 0; |
1175 | size_t offset = 0; |
1176 | |
1177 | if (urb->status || !info) |
1178 | @@ -624,7 +628,17 @@ static void read_completed(struct urb *urb) |
1179 | if (!dev->streaming) |
1180 | return; |
1181 | |
1182 | - out = dev->data_urbs_out[info->index]; |
1183 | + /* find an unused output urb that is unused */ |
1184 | + for (i = 0; i < N_URBS; i++) |
1185 | + if (test_and_set_bit(i, &dev->outurb_active_mask) == 0) { |
1186 | + out = dev->data_urbs_out[i]; |
1187 | + break; |
1188 | + } |
1189 | + |
1190 | + if (!out) { |
1191 | + log("Unable to find an output urb to use\n"); |
1192 | + goto requeue; |
1193 | + } |
1194 | |
1195 | /* read the recently received packet and send back one which has |
1196 | * the same layout */ |
1197 | @@ -655,8 +669,12 @@ static void read_completed(struct urb *urb) |
1198 | out->number_of_packets = outframe; |
1199 | out->transfer_flags = URB_ISO_ASAP; |
1200 | usb_submit_urb(out, GFP_ATOMIC); |
1201 | + } else { |
1202 | + struct snd_usb_caiaq_cb_info *oinfo = out->context; |
1203 | + clear_bit(oinfo->index, &dev->outurb_active_mask); |
1204 | } |
1205 | |
1206 | +requeue: |
1207 | /* re-submit inbound urb */ |
1208 | for (frame = 0; frame < FRAMES_PER_URB; frame++) { |
1209 | urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame; |
1210 | @@ -678,6 +696,8 @@ static void write_completed(struct urb *urb) |
1211 | dev->output_running = 1; |
1212 | wake_up(&dev->prepare_wait_queue); |
1213 | } |
1214 | + |
1215 | + clear_bit(info->index, &dev->outurb_active_mask); |
1216 | } |
1217 | |
1218 | static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) |
1219 | @@ -829,6 +849,9 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) |
1220 | if (!dev->data_cb_info) |
1221 | return -ENOMEM; |
1222 | |
1223 | + dev->outurb_active_mask = 0; |
1224 | + BUILD_BUG_ON(N_URBS > (sizeof(dev->outurb_active_mask) * 8)); |
1225 | + |
1226 | for (i = 0; i < N_URBS; i++) { |
1227 | dev->data_cb_info[i].dev = dev; |
1228 | dev->data_cb_info[i].index = i; |
1229 | diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h |
1230 | index b2b3101..3f9c633 100644 |
1231 | --- a/sound/usb/caiaq/device.h |
1232 | +++ b/sound/usb/caiaq/device.h |
1233 | @@ -96,6 +96,7 @@ struct snd_usb_caiaqdev { |
1234 | int input_panic, output_panic, warned; |
1235 | char *audio_in_buf, *audio_out_buf; |
1236 | unsigned int samplerates, bpp; |
1237 | + unsigned long outurb_active_mask; |
1238 | |
1239 | struct snd_pcm_substream *sub_playback[MAX_STREAMS]; |
1240 | struct snd_pcm_substream *sub_capture[MAX_STREAMS]; |
1241 | diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c |
1242 | index c04d7c7..cdd19d7 100644 |
1243 | --- a/sound/usb/mixer.c |
1244 | +++ b/sound/usb/mixer.c |
1245 | @@ -152,6 +152,7 @@ static inline void check_mapped_dB(const struct usbmix_name_map *p, |
1246 | if (p && p->dB) { |
1247 | cval->dBmin = p->dB->min; |
1248 | cval->dBmax = p->dB->max; |
1249 | + cval->initialized = 1; |
1250 | } |
1251 | } |
1252 | |
1253 | @@ -1092,7 +1093,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, |
1254 | " Switch" : " Volume"); |
1255 | if (control == UAC_FU_VOLUME) { |
1256 | check_mapped_dB(map, cval); |
1257 | - if (cval->dBmin < cval->dBmax) { |
1258 | + if (cval->dBmin < cval->dBmax || !cval->initialized) { |
1259 | kctl->tlv.c = mixer_vol_tlv; |
1260 | kctl->vd[0].access |= |
1261 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | |