Annotation of /trunk/kernel-mcore/patches-3.0-r1/0103-3.0.4-all-fixes.patch
Parent Directory | Revision Log
Revision 1542 -
(hide annotations)
(download)
Thu Sep 29 11:51:27 2011 UTC (13 years ago) by niro
File size: 41883 byte(s)
Thu Sep 29 11:51:27 2011 UTC (13 years ago) by niro
File size: 41883 byte(s)
3.0-mcore-r1
1 | niro | 1542 | 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 | |