Contents of /trunk/kernel-magellan/patches-3.9/0106-3.9.7-all-fixes.patch
Parent Directory | Revision Log
Revision 2221 -
(show annotations)
(download)
Mon Jul 1 09:43:31 2013 UTC (11 years, 2 months ago) by niro
File size: 94478 byte(s)
Mon Jul 1 09:43:31 2013 UTC (11 years, 2 months ago) by niro
File size: 94478 byte(s)
-linux-3.9.7
1 | diff --git a/arch/arm/mach-kirkwood/mpp.c b/arch/arm/mach-kirkwood/mpp.c |
2 | index 827cde4..e96fd71 100644 |
3 | --- a/arch/arm/mach-kirkwood/mpp.c |
4 | +++ b/arch/arm/mach-kirkwood/mpp.c |
5 | @@ -22,9 +22,10 @@ static unsigned int __init kirkwood_variant(void) |
6 | |
7 | kirkwood_pcie_id(&dev, &rev); |
8 | |
9 | - if ((dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0) || |
10 | - (dev == MV88F6282_DEV_ID)) |
11 | + if (dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0) |
12 | return MPP_F6281_MASK; |
13 | + if (dev == MV88F6282_DEV_ID) |
14 | + return MPP_F6282_MASK; |
15 | if (dev == MV88F6192_DEV_ID && rev >= MV88F6192_REV_A0) |
16 | return MPP_F6192_MASK; |
17 | if (dev == MV88F6180_DEV_ID) |
18 | diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h |
19 | index 05e6d2e..0f271e3 100644 |
20 | --- a/arch/powerpc/include/asm/exception-64s.h |
21 | +++ b/arch/powerpc/include/asm/exception-64s.h |
22 | @@ -513,7 +513,7 @@ label##_common: \ |
23 | */ |
24 | #define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \ |
25 | EXCEPTION_COMMON(trap, label, hdlr, ret_from_except_lite, \ |
26 | - FINISH_NAP;RUNLATCH_ON;DISABLE_INTS) |
27 | + FINISH_NAP;DISABLE_INTS;RUNLATCH_ON) |
28 | |
29 | /* |
30 | * When the idle code in power4_idle puts the CPU into NAP mode, |
31 | diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S |
32 | index 3bbe7ed..644378e 100644 |
33 | --- a/arch/powerpc/kernel/exceptions-64s.S |
34 | +++ b/arch/powerpc/kernel/exceptions-64s.S |
35 | @@ -707,7 +707,7 @@ machine_check_common: |
36 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) |
37 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) |
38 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) |
39 | - STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception) |
40 | + STD_EXCEPTION_COMMON(0xe40, emulation_assist, .emulation_assist_interrupt) |
41 | STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception) |
42 | #ifdef CONFIG_PPC_DOORBELL |
43 | STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .doorbell_exception) |
44 | diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c |
45 | index 4f97fe3..523d1e2 100644 |
46 | --- a/arch/powerpc/kernel/irq.c |
47 | +++ b/arch/powerpc/kernel/irq.c |
48 | @@ -162,7 +162,7 @@ notrace unsigned int __check_irq_replay(void) |
49 | * in case we also had a rollover while hard disabled |
50 | */ |
51 | local_paca->irq_happened &= ~PACA_IRQ_DEC; |
52 | - if (decrementer_check_overflow()) |
53 | + if ((happened & PACA_IRQ_DEC) || decrementer_check_overflow()) |
54 | return 0x900; |
55 | |
56 | /* Finally check if an external interrupt happened */ |
57 | diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c |
58 | index 9600c36..0d86c8a 100644 |
59 | --- a/arch/powerpc/kernel/process.c |
60 | +++ b/arch/powerpc/kernel/process.c |
61 | @@ -1371,7 +1371,7 @@ EXPORT_SYMBOL(dump_stack); |
62 | |
63 | #ifdef CONFIG_PPC64 |
64 | /* Called with hard IRQs off */ |
65 | -void __ppc64_runlatch_on(void) |
66 | +void notrace __ppc64_runlatch_on(void) |
67 | { |
68 | struct thread_info *ti = current_thread_info(); |
69 | unsigned long ctrl; |
70 | @@ -1384,7 +1384,7 @@ void __ppc64_runlatch_on(void) |
71 | } |
72 | |
73 | /* Called with hard IRQs off */ |
74 | -void __ppc64_runlatch_off(void) |
75 | +void notrace __ppc64_runlatch_off(void) |
76 | { |
77 | struct thread_info *ti = current_thread_info(); |
78 | unsigned long ctrl; |
79 | diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c |
80 | index 29857c6..bf33ace 100644 |
81 | --- a/arch/powerpc/kernel/traps.c |
82 | +++ b/arch/powerpc/kernel/traps.c |
83 | @@ -1142,6 +1142,16 @@ void __kprobes program_check_exception(struct pt_regs *regs) |
84 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); |
85 | } |
86 | |
87 | +/* |
88 | + * This occurs when running in hypervisor mode on POWER6 or later |
89 | + * and an illegal instruction is encountered. |
90 | + */ |
91 | +void __kprobes emulation_assist_interrupt(struct pt_regs *regs) |
92 | +{ |
93 | + regs->msr |= REASON_ILLEGAL; |
94 | + program_check_exception(regs); |
95 | +} |
96 | + |
97 | void alignment_exception(struct pt_regs *regs) |
98 | { |
99 | int sig, code, fixed = 0; |
100 | diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c |
101 | index 35ee62f..c205035 100644 |
102 | --- a/arch/x86/boot/compressed/eboot.c |
103 | +++ b/arch/x86/boot/compressed/eboot.c |
104 | @@ -251,51 +251,6 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size) |
105 | *size = len; |
106 | } |
107 | |
108 | -static efi_status_t setup_efi_vars(struct boot_params *params) |
109 | -{ |
110 | - struct setup_data *data; |
111 | - struct efi_var_bootdata *efidata; |
112 | - u64 store_size, remaining_size, var_size; |
113 | - efi_status_t status; |
114 | - |
115 | - if (sys_table->runtime->hdr.revision < EFI_2_00_SYSTEM_TABLE_REVISION) |
116 | - return EFI_UNSUPPORTED; |
117 | - |
118 | - data = (struct setup_data *)(unsigned long)params->hdr.setup_data; |
119 | - |
120 | - while (data && data->next) |
121 | - data = (struct setup_data *)(unsigned long)data->next; |
122 | - |
123 | - status = efi_call_phys4((void *)sys_table->runtime->query_variable_info, |
124 | - EFI_VARIABLE_NON_VOLATILE | |
125 | - EFI_VARIABLE_BOOTSERVICE_ACCESS | |
126 | - EFI_VARIABLE_RUNTIME_ACCESS, &store_size, |
127 | - &remaining_size, &var_size); |
128 | - |
129 | - if (status != EFI_SUCCESS) |
130 | - return status; |
131 | - |
132 | - status = efi_call_phys3(sys_table->boottime->allocate_pool, |
133 | - EFI_LOADER_DATA, sizeof(*efidata), &efidata); |
134 | - |
135 | - if (status != EFI_SUCCESS) |
136 | - return status; |
137 | - |
138 | - efidata->data.type = SETUP_EFI_VARS; |
139 | - efidata->data.len = sizeof(struct efi_var_bootdata) - |
140 | - sizeof(struct setup_data); |
141 | - efidata->data.next = 0; |
142 | - efidata->store_size = store_size; |
143 | - efidata->remaining_size = remaining_size; |
144 | - efidata->max_var_size = var_size; |
145 | - |
146 | - if (data) |
147 | - data->next = (unsigned long)efidata; |
148 | - else |
149 | - params->hdr.setup_data = (unsigned long)efidata; |
150 | - |
151 | -} |
152 | - |
153 | static efi_status_t setup_efi_pci(struct boot_params *params) |
154 | { |
155 | efi_pci_io_protocol *pci; |
156 | @@ -1202,8 +1157,6 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, |
157 | |
158 | setup_graphics(boot_params); |
159 | |
160 | - setup_efi_vars(boot_params); |
161 | - |
162 | setup_efi_pci(boot_params); |
163 | |
164 | status = efi_call_phys3(sys_table->boottime->allocate_pool, |
165 | diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h |
166 | index 2fb5d58..60c89f3 100644 |
167 | --- a/arch/x86/include/asm/efi.h |
168 | +++ b/arch/x86/include/asm/efi.h |
169 | @@ -102,13 +102,6 @@ extern void efi_call_phys_epilog(void); |
170 | extern void efi_unmap_memmap(void); |
171 | extern void efi_memory_uc(u64 addr, unsigned long size); |
172 | |
173 | -struct efi_var_bootdata { |
174 | - struct setup_data data; |
175 | - u64 store_size; |
176 | - u64 remaining_size; |
177 | - u64 max_var_size; |
178 | -}; |
179 | - |
180 | #ifdef CONFIG_EFI |
181 | |
182 | static inline bool efi_is_native(void) |
183 | diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h |
184 | index 0874424..c15ddaf 100644 |
185 | --- a/arch/x86/include/uapi/asm/bootparam.h |
186 | +++ b/arch/x86/include/uapi/asm/bootparam.h |
187 | @@ -6,7 +6,6 @@ |
188 | #define SETUP_E820_EXT 1 |
189 | #define SETUP_DTB 2 |
190 | #define SETUP_PCI 3 |
191 | -#define SETUP_EFI_VARS 4 |
192 | |
193 | /* ram_size flags */ |
194 | #define RAMDISK_IMAGE_START_MASK 0x07FF |
195 | diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S |
196 | index 7a6f3b3..f2bb9c9 100644 |
197 | --- a/arch/x86/kernel/relocate_kernel_64.S |
198 | +++ b/arch/x86/kernel/relocate_kernel_64.S |
199 | @@ -160,7 +160,7 @@ identity_mapped: |
200 | xorq %rbp, %rbp |
201 | xorq %r8, %r8 |
202 | xorq %r9, %r9 |
203 | - xorq %r10, %r9 |
204 | + xorq %r10, %r10 |
205 | xorq %r11, %r11 |
206 | xorq %r12, %r12 |
207 | xorq %r13, %r13 |
208 | diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c |
209 | index 59b7fc4..0c13708 100644 |
210 | --- a/arch/x86/mm/init.c |
211 | +++ b/arch/x86/mm/init.c |
212 | @@ -277,6 +277,9 @@ static int __meminit split_mem_range(struct map_range *mr, int nr_range, |
213 | end_pfn = limit_pfn; |
214 | nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); |
215 | |
216 | + if (!after_bootmem) |
217 | + adjust_range_page_size_mask(mr, nr_range); |
218 | + |
219 | /* try to merge same page size and continuous */ |
220 | for (i = 0; nr_range > 1 && i < nr_range - 1; i++) { |
221 | unsigned long old_start; |
222 | @@ -291,9 +294,6 @@ static int __meminit split_mem_range(struct map_range *mr, int nr_range, |
223 | nr_range--; |
224 | } |
225 | |
226 | - if (!after_bootmem) |
227 | - adjust_range_page_size_mask(mr, nr_range); |
228 | - |
229 | for (i = 0; i < nr_range; i++) |
230 | printk(KERN_DEBUG " [mem %#010lx-%#010lx] page %s\n", |
231 | mr[i].start, mr[i].end - 1, |
232 | diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c |
233 | index e4a86a6..90f3a52 100644 |
234 | --- a/arch/x86/platform/efi/efi.c |
235 | +++ b/arch/x86/platform/efi/efi.c |
236 | @@ -41,7 +41,6 @@ |
237 | #include <linux/io.h> |
238 | #include <linux/reboot.h> |
239 | #include <linux/bcd.h> |
240 | -#include <linux/ucs2_string.h> |
241 | |
242 | #include <asm/setup.h> |
243 | #include <asm/efi.h> |
244 | @@ -52,12 +51,12 @@ |
245 | |
246 | #define EFI_DEBUG 1 |
247 | |
248 | -/* |
249 | - * There's some additional metadata associated with each |
250 | - * variable. Intel's reference implementation is 60 bytes - bump that |
251 | - * to account for potential alignment constraints |
252 | - */ |
253 | -#define VAR_METADATA_SIZE 64 |
254 | +#define EFI_MIN_RESERVE 5120 |
255 | + |
256 | +#define EFI_DUMMY_GUID \ |
257 | + EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9) |
258 | + |
259 | +static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; |
260 | |
261 | struct efi __read_mostly efi = { |
262 | .mps = EFI_INVALID_TABLE_ADDR, |
263 | @@ -77,13 +76,6 @@ struct efi_memory_map memmap; |
264 | static struct efi efi_phys __initdata; |
265 | static efi_system_table_t efi_systab __initdata; |
266 | |
267 | -static u64 efi_var_store_size; |
268 | -static u64 efi_var_remaining_size; |
269 | -static u64 efi_var_max_var_size; |
270 | -static u64 boot_used_size; |
271 | -static u64 boot_var_size; |
272 | -static u64 active_size; |
273 | - |
274 | unsigned long x86_efi_facility; |
275 | |
276 | /* |
277 | @@ -186,53 +178,8 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size, |
278 | efi_char16_t *name, |
279 | efi_guid_t *vendor) |
280 | { |
281 | - efi_status_t status; |
282 | - static bool finished = false; |
283 | - static u64 var_size; |
284 | - |
285 | - status = efi_call_virt3(get_next_variable, |
286 | - name_size, name, vendor); |
287 | - |
288 | - if (status == EFI_NOT_FOUND) { |
289 | - finished = true; |
290 | - if (var_size < boot_used_size) { |
291 | - boot_var_size = boot_used_size - var_size; |
292 | - active_size += boot_var_size; |
293 | - } else { |
294 | - printk(KERN_WARNING FW_BUG "efi: Inconsistent initial sizes\n"); |
295 | - } |
296 | - } |
297 | - |
298 | - if (boot_used_size && !finished) { |
299 | - unsigned long size; |
300 | - u32 attr; |
301 | - efi_status_t s; |
302 | - void *tmp; |
303 | - |
304 | - s = virt_efi_get_variable(name, vendor, &attr, &size, NULL); |
305 | - |
306 | - if (s != EFI_BUFFER_TOO_SMALL || !size) |
307 | - return status; |
308 | - |
309 | - tmp = kmalloc(size, GFP_ATOMIC); |
310 | - |
311 | - if (!tmp) |
312 | - return status; |
313 | - |
314 | - s = virt_efi_get_variable(name, vendor, &attr, &size, tmp); |
315 | - |
316 | - if (s == EFI_SUCCESS && (attr & EFI_VARIABLE_NON_VOLATILE)) { |
317 | - var_size += size; |
318 | - var_size += ucs2_strsize(name, 1024); |
319 | - active_size += size; |
320 | - active_size += VAR_METADATA_SIZE; |
321 | - active_size += ucs2_strsize(name, 1024); |
322 | - } |
323 | - |
324 | - kfree(tmp); |
325 | - } |
326 | - |
327 | - return status; |
328 | + return efi_call_virt3(get_next_variable, |
329 | + name_size, name, vendor); |
330 | } |
331 | |
332 | static efi_status_t virt_efi_set_variable(efi_char16_t *name, |
333 | @@ -241,34 +188,9 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name, |
334 | unsigned long data_size, |
335 | void *data) |
336 | { |
337 | - efi_status_t status; |
338 | - u32 orig_attr = 0; |
339 | - unsigned long orig_size = 0; |
340 | - |
341 | - status = virt_efi_get_variable(name, vendor, &orig_attr, &orig_size, |
342 | - NULL); |
343 | - |
344 | - if (status != EFI_BUFFER_TOO_SMALL) |
345 | - orig_size = 0; |
346 | - |
347 | - status = efi_call_virt5(set_variable, |
348 | - name, vendor, attr, |
349 | - data_size, data); |
350 | - |
351 | - if (status == EFI_SUCCESS) { |
352 | - if (orig_size) { |
353 | - active_size -= orig_size; |
354 | - active_size -= ucs2_strsize(name, 1024); |
355 | - active_size -= VAR_METADATA_SIZE; |
356 | - } |
357 | - if (data_size) { |
358 | - active_size += data_size; |
359 | - active_size += ucs2_strsize(name, 1024); |
360 | - active_size += VAR_METADATA_SIZE; |
361 | - } |
362 | - } |
363 | - |
364 | - return status; |
365 | + return efi_call_virt5(set_variable, |
366 | + name, vendor, attr, |
367 | + data_size, data); |
368 | } |
369 | |
370 | static efi_status_t virt_efi_query_variable_info(u32 attr, |
371 | @@ -776,9 +698,6 @@ void __init efi_init(void) |
372 | char vendor[100] = "unknown"; |
373 | int i = 0; |
374 | void *tmp; |
375 | - struct setup_data *data; |
376 | - struct efi_var_bootdata *efi_var_data; |
377 | - u64 pa_data; |
378 | |
379 | #ifdef CONFIG_X86_32 |
380 | if (boot_params.efi_info.efi_systab_hi || |
381 | @@ -796,22 +715,6 @@ void __init efi_init(void) |
382 | if (efi_systab_init(efi_phys.systab)) |
383 | return; |
384 | |
385 | - pa_data = boot_params.hdr.setup_data; |
386 | - while (pa_data) { |
387 | - data = early_ioremap(pa_data, sizeof(*efi_var_data)); |
388 | - if (data->type == SETUP_EFI_VARS) { |
389 | - efi_var_data = (struct efi_var_bootdata *)data; |
390 | - |
391 | - efi_var_store_size = efi_var_data->store_size; |
392 | - efi_var_remaining_size = efi_var_data->remaining_size; |
393 | - efi_var_max_var_size = efi_var_data->max_var_size; |
394 | - } |
395 | - pa_data = data->next; |
396 | - early_iounmap(data, sizeof(*efi_var_data)); |
397 | - } |
398 | - |
399 | - boot_used_size = efi_var_store_size - efi_var_remaining_size; |
400 | - |
401 | set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); |
402 | |
403 | /* |
404 | @@ -1075,6 +978,13 @@ void __init efi_enter_virtual_mode(void) |
405 | runtime_code_page_mkexec(); |
406 | |
407 | kfree(new_memmap); |
408 | + |
409 | + /* clean DUMMY object */ |
410 | + efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, |
411 | + EFI_VARIABLE_NON_VOLATILE | |
412 | + EFI_VARIABLE_BOOTSERVICE_ACCESS | |
413 | + EFI_VARIABLE_RUNTIME_ACCESS, |
414 | + 0, NULL); |
415 | } |
416 | |
417 | /* |
418 | @@ -1126,33 +1036,65 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) |
419 | efi_status_t status; |
420 | u64 storage_size, remaining_size, max_size; |
421 | |
422 | + if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) |
423 | + return 0; |
424 | + |
425 | status = efi.query_variable_info(attributes, &storage_size, |
426 | &remaining_size, &max_size); |
427 | if (status != EFI_SUCCESS) |
428 | return status; |
429 | |
430 | - if (!max_size && remaining_size > size) |
431 | - printk_once(KERN_ERR FW_BUG "Broken EFI implementation" |
432 | - " is returning MaxVariableSize=0\n"); |
433 | /* |
434 | * Some firmware implementations refuse to boot if there's insufficient |
435 | * space in the variable store. We account for that by refusing the |
436 | * write if permitting it would reduce the available space to under |
437 | - * 50%. However, some firmware won't reclaim variable space until |
438 | - * after the used (not merely the actively used) space drops below |
439 | - * a threshold. We can approximate that case with the value calculated |
440 | - * above. If both the firmware and our calculations indicate that the |
441 | - * available space would drop below 50%, refuse the write. |
442 | + * 5KB. This figure was provided by Samsung, so should be safe. |
443 | */ |
444 | + if ((remaining_size - size < EFI_MIN_RESERVE) && |
445 | + !efi_no_storage_paranoia) { |
446 | + |
447 | + /* |
448 | + * Triggering garbage collection may require that the firmware |
449 | + * generate a real EFI_OUT_OF_RESOURCES error. We can force |
450 | + * that by attempting to use more space than is available. |
451 | + */ |
452 | + unsigned long dummy_size = remaining_size + 1024; |
453 | + void *dummy = kmalloc(dummy_size, GFP_ATOMIC); |
454 | + |
455 | + status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, |
456 | + EFI_VARIABLE_NON_VOLATILE | |
457 | + EFI_VARIABLE_BOOTSERVICE_ACCESS | |
458 | + EFI_VARIABLE_RUNTIME_ACCESS, |
459 | + dummy_size, dummy); |
460 | + |
461 | + if (status == EFI_SUCCESS) { |
462 | + /* |
463 | + * This should have failed, so if it didn't make sure |
464 | + * that we delete it... |
465 | + */ |
466 | + efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, |
467 | + EFI_VARIABLE_NON_VOLATILE | |
468 | + EFI_VARIABLE_BOOTSERVICE_ACCESS | |
469 | + EFI_VARIABLE_RUNTIME_ACCESS, |
470 | + 0, dummy); |
471 | + } |
472 | |
473 | - if (!storage_size || size > remaining_size || |
474 | - (max_size && size > max_size)) |
475 | - return EFI_OUT_OF_RESOURCES; |
476 | + /* |
477 | + * The runtime code may now have triggered a garbage collection |
478 | + * run, so check the variable info again |
479 | + */ |
480 | + status = efi.query_variable_info(attributes, &storage_size, |
481 | + &remaining_size, &max_size); |
482 | |
483 | - if (!efi_no_storage_paranoia && |
484 | - ((active_size + size + VAR_METADATA_SIZE > storage_size / 2) && |
485 | - (remaining_size - size < storage_size / 2))) |
486 | - return EFI_OUT_OF_RESOURCES; |
487 | + if (status != EFI_SUCCESS) |
488 | + return status; |
489 | + |
490 | + /* |
491 | + * There still isn't enough room, so return an error |
492 | + */ |
493 | + if (remaining_size - size < EFI_MIN_RESERVE) |
494 | + return EFI_OUT_OF_RESOURCES; |
495 | + } |
496 | |
497 | return EFI_SUCCESS; |
498 | } |
499 | diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c |
500 | index 5e7e991..b32fc76 100644 |
501 | --- a/drivers/acpi/scan.c |
502 | +++ b/drivers/acpi/scan.c |
503 | @@ -830,11 +830,8 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) |
504 | return -ENOSYS; |
505 | |
506 | result = driver->ops.add(device); |
507 | - if (result) { |
508 | - device->driver = NULL; |
509 | - device->driver_data = NULL; |
510 | + if (result) |
511 | return result; |
512 | - } |
513 | |
514 | device->driver = driver; |
515 | |
516 | diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c |
517 | index 81a9335..c397f3f 100644 |
518 | --- a/drivers/acpi/video.c |
519 | +++ b/drivers/acpi/video.c |
520 | @@ -1646,6 +1646,9 @@ static int acpi_video_bus_add(struct acpi_device *device) |
521 | int error; |
522 | acpi_status status; |
523 | |
524 | + if (device->handler) |
525 | + return -EINVAL; |
526 | + |
527 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, |
528 | device->parent->handle, 1, |
529 | acpi_video_bus_match, NULL, |
530 | diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c |
531 | index 1c1b8e5..dadea48 100644 |
532 | --- a/drivers/block/cciss.c |
533 | +++ b/drivers/block/cciss.c |
534 | @@ -162,8 +162,6 @@ static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id); |
535 | static int cciss_open(struct block_device *bdev, fmode_t mode); |
536 | static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode); |
537 | static int cciss_release(struct gendisk *disk, fmode_t mode); |
538 | -static int do_ioctl(struct block_device *bdev, fmode_t mode, |
539 | - unsigned int cmd, unsigned long arg); |
540 | static int cciss_ioctl(struct block_device *bdev, fmode_t mode, |
541 | unsigned int cmd, unsigned long arg); |
542 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); |
543 | @@ -229,7 +227,7 @@ static const struct block_device_operations cciss_fops = { |
544 | .owner = THIS_MODULE, |
545 | .open = cciss_unlocked_open, |
546 | .release = cciss_release, |
547 | - .ioctl = do_ioctl, |
548 | + .ioctl = cciss_ioctl, |
549 | .getgeo = cciss_getgeo, |
550 | #ifdef CONFIG_COMPAT |
551 | .compat_ioctl = cciss_compat_ioctl, |
552 | @@ -1138,16 +1136,6 @@ static int cciss_release(struct gendisk *disk, fmode_t mode) |
553 | return 0; |
554 | } |
555 | |
556 | -static int do_ioctl(struct block_device *bdev, fmode_t mode, |
557 | - unsigned cmd, unsigned long arg) |
558 | -{ |
559 | - int ret; |
560 | - mutex_lock(&cciss_mutex); |
561 | - ret = cciss_ioctl(bdev, mode, cmd, arg); |
562 | - mutex_unlock(&cciss_mutex); |
563 | - return ret; |
564 | -} |
565 | - |
566 | #ifdef CONFIG_COMPAT |
567 | |
568 | static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, |
569 | @@ -1174,7 +1162,7 @@ static int cciss_compat_ioctl(struct block_device *bdev, fmode_t mode, |
570 | case CCISS_REGNEWD: |
571 | case CCISS_RESCANDISK: |
572 | case CCISS_GETLUNINFO: |
573 | - return do_ioctl(bdev, mode, cmd, arg); |
574 | + return cciss_ioctl(bdev, mode, cmd, arg); |
575 | |
576 | case CCISS_PASSTHRU32: |
577 | return cciss_ioctl32_passthru(bdev, mode, cmd, arg); |
578 | @@ -1214,7 +1202,7 @@ static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, |
579 | if (err) |
580 | return -EFAULT; |
581 | |
582 | - err = do_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p); |
583 | + err = cciss_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p); |
584 | if (err) |
585 | return err; |
586 | err |= |
587 | @@ -1256,7 +1244,7 @@ static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode, |
588 | if (err) |
589 | return -EFAULT; |
590 | |
591 | - err = do_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p); |
592 | + err = cciss_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p); |
593 | if (err) |
594 | return err; |
595 | err |= |
596 | @@ -1306,11 +1294,14 @@ static int cciss_getpciinfo(ctlr_info_t *h, void __user *argp) |
597 | static int cciss_getintinfo(ctlr_info_t *h, void __user *argp) |
598 | { |
599 | cciss_coalint_struct intinfo; |
600 | + unsigned long flags; |
601 | |
602 | if (!argp) |
603 | return -EINVAL; |
604 | + spin_lock_irqsave(&h->lock, flags); |
605 | intinfo.delay = readl(&h->cfgtable->HostWrite.CoalIntDelay); |
606 | intinfo.count = readl(&h->cfgtable->HostWrite.CoalIntCount); |
607 | + spin_unlock_irqrestore(&h->lock, flags); |
608 | if (copy_to_user |
609 | (argp, &intinfo, sizeof(cciss_coalint_struct))) |
610 | return -EFAULT; |
611 | @@ -1351,12 +1342,15 @@ static int cciss_setintinfo(ctlr_info_t *h, void __user *argp) |
612 | static int cciss_getnodename(ctlr_info_t *h, void __user *argp) |
613 | { |
614 | NodeName_type NodeName; |
615 | + unsigned long flags; |
616 | int i; |
617 | |
618 | if (!argp) |
619 | return -EINVAL; |
620 | + spin_lock_irqsave(&h->lock, flags); |
621 | for (i = 0; i < 16; i++) |
622 | NodeName[i] = readb(&h->cfgtable->ServerName[i]); |
623 | + spin_unlock_irqrestore(&h->lock, flags); |
624 | if (copy_to_user(argp, NodeName, sizeof(NodeName_type))) |
625 | return -EFAULT; |
626 | return 0; |
627 | @@ -1393,10 +1387,13 @@ static int cciss_setnodename(ctlr_info_t *h, void __user *argp) |
628 | static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp) |
629 | { |
630 | Heartbeat_type heartbeat; |
631 | + unsigned long flags; |
632 | |
633 | if (!argp) |
634 | return -EINVAL; |
635 | + spin_lock_irqsave(&h->lock, flags); |
636 | heartbeat = readl(&h->cfgtable->HeartBeat); |
637 | + spin_unlock_irqrestore(&h->lock, flags); |
638 | if (copy_to_user(argp, &heartbeat, sizeof(Heartbeat_type))) |
639 | return -EFAULT; |
640 | return 0; |
641 | @@ -1405,10 +1402,13 @@ static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp) |
642 | static int cciss_getbustypes(ctlr_info_t *h, void __user *argp) |
643 | { |
644 | BusTypes_type BusTypes; |
645 | + unsigned long flags; |
646 | |
647 | if (!argp) |
648 | return -EINVAL; |
649 | + spin_lock_irqsave(&h->lock, flags); |
650 | BusTypes = readl(&h->cfgtable->BusTypes); |
651 | + spin_unlock_irqrestore(&h->lock, flags); |
652 | if (copy_to_user(argp, &BusTypes, sizeof(BusTypes_type))) |
653 | return -EFAULT; |
654 | return 0; |
655 | diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c |
656 | index b7b7a88..fe333e4 100644 |
657 | --- a/drivers/block/rbd.c |
658 | +++ b/drivers/block/rbd.c |
659 | @@ -435,8 +435,8 @@ static const struct block_device_operations rbd_bd_ops = { |
660 | }; |
661 | |
662 | /* |
663 | - * Initialize an rbd client instance. |
664 | - * We own *ceph_opts. |
665 | + * Initialize an rbd client instance. Success or not, this function |
666 | + * consumes ceph_opts. |
667 | */ |
668 | static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts) |
669 | { |
670 | @@ -583,7 +583,8 @@ static int parse_rbd_opts_token(char *c, void *private) |
671 | |
672 | /* |
673 | * Get a ceph client with specific addr and configuration, if one does |
674 | - * not exist create it. |
675 | + * not exist create it. Either way, ceph_opts is consumed by this |
676 | + * function. |
677 | */ |
678 | static struct rbd_client *rbd_get_client(struct ceph_options *ceph_opts) |
679 | { |
680 | @@ -4104,7 +4105,6 @@ static ssize_t rbd_add(struct bus_type *bus, |
681 | rc = PTR_ERR(rbdc); |
682 | goto err_out_args; |
683 | } |
684 | - ceph_opts = NULL; /* rbd_dev client now owns this */ |
685 | |
686 | /* pick the pool */ |
687 | osdc = &rbdc->client->osdc; |
688 | @@ -4140,8 +4140,6 @@ err_out_rbd_dev: |
689 | err_out_client: |
690 | rbd_put_client(rbdc); |
691 | err_out_args: |
692 | - if (ceph_opts) |
693 | - ceph_destroy_options(ceph_opts); |
694 | kfree(rbd_opts); |
695 | rbd_spec_put(spec); |
696 | err_out_module: |
697 | diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c |
698 | index 3cfd093..d6742dc 100644 |
699 | --- a/drivers/gpu/drm/gma500/cdv_intel_display.c |
700 | +++ b/drivers/gpu/drm/gma500/cdv_intel_display.c |
701 | @@ -1750,6 +1750,19 @@ static void cdv_intel_crtc_destroy(struct drm_crtc *crtc) |
702 | kfree(psb_intel_crtc); |
703 | } |
704 | |
705 | +static void cdv_intel_crtc_disable(struct drm_crtc *crtc) |
706 | +{ |
707 | + struct gtt_range *gt; |
708 | + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; |
709 | + |
710 | + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); |
711 | + |
712 | + if (crtc->fb) { |
713 | + gt = to_psb_fb(crtc->fb)->gtt; |
714 | + psb_gtt_unpin(gt); |
715 | + } |
716 | +} |
717 | + |
718 | const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = { |
719 | .dpms = cdv_intel_crtc_dpms, |
720 | .mode_fixup = cdv_intel_crtc_mode_fixup, |
721 | @@ -1757,6 +1770,7 @@ const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = { |
722 | .mode_set_base = cdv_intel_pipe_set_base, |
723 | .prepare = cdv_intel_crtc_prepare, |
724 | .commit = cdv_intel_crtc_commit, |
725 | + .disable = cdv_intel_crtc_disable, |
726 | }; |
727 | |
728 | const struct drm_crtc_funcs cdv_intel_crtc_funcs = { |
729 | diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c |
730 | index 9edb190..1c01b9a 100644 |
731 | --- a/drivers/gpu/drm/gma500/psb_intel_display.c |
732 | +++ b/drivers/gpu/drm/gma500/psb_intel_display.c |
733 | @@ -1246,6 +1246,19 @@ void psb_intel_crtc_destroy(struct drm_crtc *crtc) |
734 | kfree(psb_intel_crtc); |
735 | } |
736 | |
737 | +static void psb_intel_crtc_disable(struct drm_crtc *crtc) |
738 | +{ |
739 | + struct gtt_range *gt; |
740 | + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; |
741 | + |
742 | + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); |
743 | + |
744 | + if (crtc->fb) { |
745 | + gt = to_psb_fb(crtc->fb)->gtt; |
746 | + psb_gtt_unpin(gt); |
747 | + } |
748 | +} |
749 | + |
750 | const struct drm_crtc_helper_funcs psb_intel_helper_funcs = { |
751 | .dpms = psb_intel_crtc_dpms, |
752 | .mode_fixup = psb_intel_crtc_mode_fixup, |
753 | @@ -1253,6 +1266,7 @@ const struct drm_crtc_helper_funcs psb_intel_helper_funcs = { |
754 | .mode_set_base = psb_intel_pipe_set_base, |
755 | .prepare = psb_intel_crtc_prepare, |
756 | .commit = psb_intel_crtc_commit, |
757 | + .disable = psb_intel_crtc_disable, |
758 | }; |
759 | |
760 | const struct drm_crtc_funcs psb_intel_crtc_funcs = { |
761 | diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c |
762 | index cdd78ca..859d468 100644 |
763 | --- a/drivers/gpu/drm/i915/intel_sdvo.c |
764 | +++ b/drivers/gpu/drm/i915/intel_sdvo.c |
765 | @@ -1771,10 +1771,13 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
766 | * arranged in priority order. |
767 | */ |
768 | intel_ddc_get_modes(connector, &intel_sdvo->ddc); |
769 | - if (list_empty(&connector->probed_modes) == false) |
770 | - goto end; |
771 | |
772 | - /* Fetch modes from VBT */ |
773 | + /* |
774 | + * Fetch modes from VBT. For SDVO prefer the VBT mode since some |
775 | + * SDVO->LVDS transcoders can't cope with the EDID mode. Since |
776 | + * drm_mode_probed_add adds the mode at the head of the list we add it |
777 | + * last. |
778 | + */ |
779 | if (dev_priv->sdvo_lvds_vbt_mode != NULL) { |
780 | newmode = drm_mode_duplicate(connector->dev, |
781 | dev_priv->sdvo_lvds_vbt_mode); |
782 | @@ -1786,7 +1789,6 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
783 | } |
784 | } |
785 | |
786 | -end: |
787 | list_for_each_entry(newmode, &connector->probed_modes, head) { |
788 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { |
789 | intel_sdvo->sdvo_lvds_fixed_mode = |
790 | diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c |
791 | index d0817d9..a60a5ac 100644 |
792 | --- a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c |
793 | +++ b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c |
794 | @@ -50,11 +50,15 @@ nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval) |
795 | { |
796 | const u32 doff = (or * 0x800); |
797 | int load = -EINVAL; |
798 | + nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000); |
799 | + nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); |
800 | nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval); |
801 | udelay(9500); |
802 | nv_wr32(priv, 0x61a00c + doff, 0x80000000); |
803 | load = (nv_rd32(priv, 0x61a00c + doff) & 0x38000000) >> 27; |
804 | nv_wr32(priv, 0x61a00c + doff, 0x00000000); |
805 | + nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80550000); |
806 | + nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); |
807 | return load; |
808 | } |
809 | |
810 | diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h |
811 | index 92d3ab1..dd74ced 100644 |
812 | --- a/drivers/gpu/drm/nouveau/core/include/core/class.h |
813 | +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h |
814 | @@ -216,7 +216,7 @@ struct nv04_display_class { |
815 | #define NV50_DISP_DAC_PWR_STATE 0x00000040 |
816 | #define NV50_DISP_DAC_PWR_STATE_ON 0x00000000 |
817 | #define NV50_DISP_DAC_PWR_STATE_OFF 0x00000040 |
818 | -#define NV50_DISP_DAC_LOAD 0x0002000c |
819 | +#define NV50_DISP_DAC_LOAD 0x00020100 |
820 | #define NV50_DISP_DAC_LOAD_VALUE 0x00000007 |
821 | |
822 | #define NV50_DISP_PIOR_MTHD 0x00030000 |
823 | diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c |
824 | index 1ddc03e..dfbb42b 100644 |
825 | --- a/drivers/gpu/drm/nouveau/nv50_display.c |
826 | +++ b/drivers/gpu/drm/nouveau/nv50_display.c |
827 | @@ -1554,7 +1554,9 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) |
828 | { |
829 | struct nv50_disp *disp = nv50_disp(encoder->dev); |
830 | int ret, or = nouveau_encoder(encoder)->or; |
831 | - u32 load = 0; |
832 | + u32 load = nouveau_drm(encoder->dev)->vbios.dactestval; |
833 | + if (load == 0) |
834 | + load = 340; |
835 | |
836 | ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); |
837 | if (ret || load != 7) |
838 | diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c |
839 | index 6af167f..7116798 100644 |
840 | --- a/drivers/md/raid1.c |
841 | +++ b/drivers/md/raid1.c |
842 | @@ -427,7 +427,17 @@ static void raid1_end_write_request(struct bio *bio, int error) |
843 | |
844 | r1_bio->bios[mirror] = NULL; |
845 | to_put = bio; |
846 | - set_bit(R1BIO_Uptodate, &r1_bio->state); |
847 | + /* |
848 | + * Do not set R1BIO_Uptodate if the current device is |
849 | + * rebuilding or Faulty. This is because we cannot use |
850 | + * such device for properly reading the data back (we could |
851 | + * potentially use it, if the current write would have felt |
852 | + * before rdev->recovery_offset, but for simplicity we don't |
853 | + * check this here. |
854 | + */ |
855 | + if (test_bit(In_sync, &conf->mirrors[mirror].rdev->flags) && |
856 | + !test_bit(Faulty, &conf->mirrors[mirror].rdev->flags)) |
857 | + set_bit(R1BIO_Uptodate, &r1_bio->state); |
858 | |
859 | /* Maybe we can clear some bad blocks. */ |
860 | if (is_badblock(conf->mirrors[mirror].rdev, |
861 | @@ -880,17 +890,17 @@ static void allow_barrier(struct r1conf *conf) |
862 | wake_up(&conf->wait_barrier); |
863 | } |
864 | |
865 | -static void freeze_array(struct r1conf *conf) |
866 | +static void freeze_array(struct r1conf *conf, int extra) |
867 | { |
868 | /* stop syncio and normal IO and wait for everything to |
869 | * go quite. |
870 | * We increment barrier and nr_waiting, and then |
871 | - * wait until nr_pending match nr_queued+1 |
872 | + * wait until nr_pending match nr_queued+extra |
873 | * This is called in the context of one normal IO request |
874 | * that has failed. Thus any sync request that might be pending |
875 | * will be blocked by nr_pending, and we need to wait for |
876 | * pending IO requests to complete or be queued for re-try. |
877 | - * Thus the number queued (nr_queued) plus this request (1) |
878 | + * Thus the number queued (nr_queued) plus this request (extra) |
879 | * must match the number of pending IOs (nr_pending) before |
880 | * we continue. |
881 | */ |
882 | @@ -898,7 +908,7 @@ static void freeze_array(struct r1conf *conf) |
883 | conf->barrier++; |
884 | conf->nr_waiting++; |
885 | wait_event_lock_irq_cmd(conf->wait_barrier, |
886 | - conf->nr_pending == conf->nr_queued+1, |
887 | + conf->nr_pending == conf->nr_queued+extra, |
888 | conf->resync_lock, |
889 | flush_pending_writes(conf)); |
890 | spin_unlock_irq(&conf->resync_lock); |
891 | @@ -1558,8 +1568,8 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev) |
892 | * we wait for all outstanding requests to complete. |
893 | */ |
894 | synchronize_sched(); |
895 | - raise_barrier(conf); |
896 | - lower_barrier(conf); |
897 | + freeze_array(conf, 0); |
898 | + unfreeze_array(conf); |
899 | clear_bit(Unmerged, &rdev->flags); |
900 | } |
901 | md_integrity_add_rdev(rdev, mddev); |
902 | @@ -1609,11 +1619,11 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev) |
903 | */ |
904 | struct md_rdev *repl = |
905 | conf->mirrors[conf->raid_disks + number].rdev; |
906 | - raise_barrier(conf); |
907 | + freeze_array(conf, 0); |
908 | clear_bit(Replacement, &repl->flags); |
909 | p->rdev = repl; |
910 | conf->mirrors[conf->raid_disks + number].rdev = NULL; |
911 | - lower_barrier(conf); |
912 | + unfreeze_array(conf); |
913 | clear_bit(WantReplacement, &rdev->flags); |
914 | } else |
915 | clear_bit(WantReplacement, &rdev->flags); |
916 | @@ -2230,7 +2240,7 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio) |
917 | * frozen |
918 | */ |
919 | if (mddev->ro == 0) { |
920 | - freeze_array(conf); |
921 | + freeze_array(conf, 1); |
922 | fix_read_error(conf, r1_bio->read_disk, |
923 | r1_bio->sector, r1_bio->sectors); |
924 | unfreeze_array(conf); |
925 | @@ -2827,8 +2837,8 @@ static int run(struct mddev *mddev) |
926 | return PTR_ERR(conf); |
927 | |
928 | if (mddev->queue) |
929 | - blk_queue_max_write_same_sectors(mddev->queue, |
930 | - mddev->chunk_sectors); |
931 | + blk_queue_max_write_same_sectors(mddev->queue, 0); |
932 | + |
933 | rdev_for_each(rdev, mddev) { |
934 | if (!mddev->gendisk) |
935 | continue; |
936 | @@ -3009,7 +3019,7 @@ static int raid1_reshape(struct mddev *mddev) |
937 | return -ENOMEM; |
938 | } |
939 | |
940 | - raise_barrier(conf); |
941 | + freeze_array(conf, 0); |
942 | |
943 | /* ok, everything is stopped */ |
944 | oldpool = conf->r1bio_pool; |
945 | @@ -3040,7 +3050,7 @@ static int raid1_reshape(struct mddev *mddev) |
946 | conf->raid_disks = mddev->raid_disks = raid_disks; |
947 | mddev->delta_disks = 0; |
948 | |
949 | - lower_barrier(conf); |
950 | + unfreeze_array(conf); |
951 | |
952 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
953 | md_wakeup_thread(mddev->thread); |
954 | diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c |
955 | index 46c14e5..e4ea992 100644 |
956 | --- a/drivers/md/raid10.c |
957 | +++ b/drivers/md/raid10.c |
958 | @@ -490,7 +490,17 @@ static void raid10_end_write_request(struct bio *bio, int error) |
959 | sector_t first_bad; |
960 | int bad_sectors; |
961 | |
962 | - set_bit(R10BIO_Uptodate, &r10_bio->state); |
963 | + /* |
964 | + * Do not set R10BIO_Uptodate if the current device is |
965 | + * rebuilding or Faulty. This is because we cannot use |
966 | + * such device for properly reading the data back (we could |
967 | + * potentially use it, if the current write would have felt |
968 | + * before rdev->recovery_offset, but for simplicity we don't |
969 | + * check this here. |
970 | + */ |
971 | + if (test_bit(In_sync, &rdev->flags) && |
972 | + !test_bit(Faulty, &rdev->flags)) |
973 | + set_bit(R10BIO_Uptodate, &r10_bio->state); |
974 | |
975 | /* Maybe we can clear some bad blocks. */ |
976 | if (is_badblock(rdev, |
977 | @@ -1055,17 +1065,17 @@ static void allow_barrier(struct r10conf *conf) |
978 | wake_up(&conf->wait_barrier); |
979 | } |
980 | |
981 | -static void freeze_array(struct r10conf *conf) |
982 | +static void freeze_array(struct r10conf *conf, int extra) |
983 | { |
984 | /* stop syncio and normal IO and wait for everything to |
985 | * go quiet. |
986 | * We increment barrier and nr_waiting, and then |
987 | - * wait until nr_pending match nr_queued+1 |
988 | + * wait until nr_pending match nr_queued+extra |
989 | * This is called in the context of one normal IO request |
990 | * that has failed. Thus any sync request that might be pending |
991 | * will be blocked by nr_pending, and we need to wait for |
992 | * pending IO requests to complete or be queued for re-try. |
993 | - * Thus the number queued (nr_queued) plus this request (1) |
994 | + * Thus the number queued (nr_queued) plus this request (extra) |
995 | * must match the number of pending IOs (nr_pending) before |
996 | * we continue. |
997 | */ |
998 | @@ -1073,7 +1083,7 @@ static void freeze_array(struct r10conf *conf) |
999 | conf->barrier++; |
1000 | conf->nr_waiting++; |
1001 | wait_event_lock_irq_cmd(conf->wait_barrier, |
1002 | - conf->nr_pending == conf->nr_queued+1, |
1003 | + conf->nr_pending == conf->nr_queued+extra, |
1004 | conf->resync_lock, |
1005 | flush_pending_writes(conf)); |
1006 | |
1007 | @@ -1839,8 +1849,8 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev) |
1008 | * we wait for all outstanding requests to complete. |
1009 | */ |
1010 | synchronize_sched(); |
1011 | - raise_barrier(conf, 0); |
1012 | - lower_barrier(conf); |
1013 | + freeze_array(conf, 0); |
1014 | + unfreeze_array(conf); |
1015 | clear_bit(Unmerged, &rdev->flags); |
1016 | } |
1017 | md_integrity_add_rdev(rdev, mddev); |
1018 | @@ -2636,7 +2646,7 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio) |
1019 | r10_bio->devs[slot].bio = NULL; |
1020 | |
1021 | if (mddev->ro == 0) { |
1022 | - freeze_array(conf); |
1023 | + freeze_array(conf, 1); |
1024 | fix_read_error(conf, mddev, r10_bio); |
1025 | unfreeze_array(conf); |
1026 | } else |
1027 | @@ -3625,8 +3635,7 @@ static int run(struct mddev *mddev) |
1028 | if (mddev->queue) { |
1029 | blk_queue_max_discard_sectors(mddev->queue, |
1030 | mddev->chunk_sectors); |
1031 | - blk_queue_max_write_same_sectors(mddev->queue, |
1032 | - mddev->chunk_sectors); |
1033 | + blk_queue_max_write_same_sectors(mddev->queue, 0); |
1034 | blk_queue_io_min(mddev->queue, chunk_size); |
1035 | if (conf->geo.raid_disks % conf->geo.near_copies) |
1036 | blk_queue_io_opt(mddev->queue, chunk_size * conf->geo.raid_disks); |
1037 | diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c |
1038 | index f4e87bf..251ab64 100644 |
1039 | --- a/drivers/md/raid5.c |
1040 | +++ b/drivers/md/raid5.c |
1041 | @@ -5457,7 +5457,7 @@ static int run(struct mddev *mddev) |
1042 | if (mddev->major_version == 0 && |
1043 | mddev->minor_version > 90) |
1044 | rdev->recovery_offset = reshape_offset; |
1045 | - |
1046 | + |
1047 | if (rdev->recovery_offset < reshape_offset) { |
1048 | /* We need to check old and new layout */ |
1049 | if (!only_parity(rdev->raid_disk, |
1050 | @@ -5580,6 +5580,8 @@ static int run(struct mddev *mddev) |
1051 | */ |
1052 | mddev->queue->limits.discard_zeroes_data = 0; |
1053 | |
1054 | + blk_queue_max_write_same_sectors(mddev->queue, 0); |
1055 | + |
1056 | rdev_for_each(rdev, mddev) { |
1057 | disk_stack_limits(mddev->gendisk, rdev->bdev, |
1058 | rdev->data_offset << 9); |
1059 | diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c |
1060 | index 6f42e57..e313c71 100644 |
1061 | --- a/drivers/net/ethernet/broadcom/tg3.c |
1062 | +++ b/drivers/net/ethernet/broadcom/tg3.c |
1063 | @@ -1799,6 +1799,9 @@ static int tg3_poll_fw(struct tg3 *tp) |
1064 | int i; |
1065 | u32 val; |
1066 | |
1067 | + if (tg3_flag(tp, NO_FWARE_REPORTED)) |
1068 | + return 0; |
1069 | + |
1070 | if (tg3_flag(tp, IS_SSB_CORE)) { |
1071 | /* We don't use firmware. */ |
1072 | return 0; |
1073 | @@ -10016,6 +10019,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) |
1074 | */ |
1075 | static int tg3_init_hw(struct tg3 *tp, int reset_phy) |
1076 | { |
1077 | + /* Chip may have been just powered on. If so, the boot code may still |
1078 | + * be running initialization. Wait for it to finish to avoid races in |
1079 | + * accessing the hardware. |
1080 | + */ |
1081 | + tg3_enable_register_access(tp); |
1082 | + tg3_poll_fw(tp); |
1083 | + |
1084 | tg3_switch_clocks(tp); |
1085 | |
1086 | tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); |
1087 | diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig |
1088 | index 17507dc..cc1fd78 100644 |
1089 | --- a/drivers/net/wireless/ath/ath9k/Kconfig |
1090 | +++ b/drivers/net/wireless/ath/ath9k/Kconfig |
1091 | @@ -92,13 +92,17 @@ config ATH9K_MAC_DEBUG |
1092 | This option enables collection of statistics for Rx/Tx status |
1093 | data and some other MAC related statistics |
1094 | |
1095 | -config ATH9K_RATE_CONTROL |
1096 | +config ATH9K_LEGACY_RATE_CONTROL |
1097 | bool "Atheros ath9k rate control" |
1098 | depends on ATH9K |
1099 | - default y |
1100 | + default n |
1101 | ---help--- |
1102 | Say Y, if you want to use the ath9k specific rate control |
1103 | - module instead of minstrel_ht. |
1104 | + module instead of minstrel_ht. Be warned that there are various |
1105 | + issues with the ath9k RC and minstrel is a more robust algorithm. |
1106 | + Note that even if this option is selected, "ath9k_rate_control" |
1107 | + has to be passed to mac80211 using the module parameter, |
1108 | + ieee80211_default_rc_algo. |
1109 | |
1110 | config ATH9K_HTC |
1111 | tristate "Atheros HTC based wireless cards support" |
1112 | diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile |
1113 | index 2ad8f94..75ee9e7 100644 |
1114 | --- a/drivers/net/wireless/ath/ath9k/Makefile |
1115 | +++ b/drivers/net/wireless/ath/ath9k/Makefile |
1116 | @@ -8,7 +8,7 @@ ath9k-y += beacon.o \ |
1117 | antenna.o |
1118 | |
1119 | ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o |
1120 | -ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o |
1121 | +ath9k-$(CONFIG_ATH9K_LEGACY_RATE_CONTROL) += rc.o |
1122 | ath9k-$(CONFIG_ATH9K_PCI) += pci.o |
1123 | ath9k-$(CONFIG_ATH9K_AHB) += ahb.o |
1124 | ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o |
1125 | diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h |
1126 | index db5ffad..7546b9a 100644 |
1127 | --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h |
1128 | +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h |
1129 | @@ -958,11 +958,11 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = { |
1130 | {0x0000a074, 0x00000000}, |
1131 | {0x0000a078, 0x00000000}, |
1132 | {0x0000a07c, 0x00000000}, |
1133 | - {0x0000a080, 0x1a1a1a1a}, |
1134 | - {0x0000a084, 0x1a1a1a1a}, |
1135 | - {0x0000a088, 0x1a1a1a1a}, |
1136 | - {0x0000a08c, 0x1a1a1a1a}, |
1137 | - {0x0000a090, 0x171a1a1a}, |
1138 | + {0x0000a080, 0x22222229}, |
1139 | + {0x0000a084, 0x1d1d1d1d}, |
1140 | + {0x0000a088, 0x1d1d1d1d}, |
1141 | + {0x0000a08c, 0x1d1d1d1d}, |
1142 | + {0x0000a090, 0x171d1d1d}, |
1143 | {0x0000a094, 0x11111717}, |
1144 | {0x0000a098, 0x00030311}, |
1145 | {0x0000a09c, 0x00000000}, |
1146 | diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c |
1147 | index 26db547..4157126 100644 |
1148 | --- a/drivers/net/wireless/ath/ath9k/init.c |
1149 | +++ b/drivers/net/wireless/ath/ath9k/init.c |
1150 | @@ -766,8 +766,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) |
1151 | hw->wiphy->iface_combinations = &if_comb; |
1152 | hw->wiphy->n_iface_combinations = 1; |
1153 | |
1154 | - if (AR_SREV_5416(sc->sc_ah)) |
1155 | - hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
1156 | + hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
1157 | |
1158 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; |
1159 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; |
1160 | @@ -809,10 +808,6 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) |
1161 | sc->ant_rx = hw->wiphy->available_antennas_rx; |
1162 | sc->ant_tx = hw->wiphy->available_antennas_tx; |
1163 | |
1164 | -#ifdef CONFIG_ATH9K_RATE_CONTROL |
1165 | - hw->rate_control_algorithm = "ath9k_rate_control"; |
1166 | -#endif |
1167 | - |
1168 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) |
1169 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
1170 | &sc->sbands[IEEE80211_BAND_2GHZ]; |
1171 | diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h |
1172 | index 267dbfc..b9a8738 100644 |
1173 | --- a/drivers/net/wireless/ath/ath9k/rc.h |
1174 | +++ b/drivers/net/wireless/ath/ath9k/rc.h |
1175 | @@ -231,7 +231,7 @@ static inline void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, |
1176 | } |
1177 | #endif |
1178 | |
1179 | -#ifdef CONFIG_ATH9K_RATE_CONTROL |
1180 | +#ifdef CONFIG_ATH9K_LEGACY_RATE_CONTROL |
1181 | int ath_rate_control_register(void); |
1182 | void ath_rate_control_unregister(void); |
1183 | #else |
1184 | diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c |
1185 | index 64b637a..911c4c0 100644 |
1186 | --- a/drivers/net/wireless/b43/main.c |
1187 | +++ b/drivers/net/wireless/b43/main.c |
1188 | @@ -2451,7 +2451,7 @@ static void b43_request_firmware(struct work_struct *work) |
1189 | for (i = 0; i < B43_NR_FWTYPES; i++) { |
1190 | errmsg = ctx->errors[i]; |
1191 | if (strlen(errmsg)) |
1192 | - b43err(dev->wl, errmsg); |
1193 | + b43err(dev->wl, "%s", errmsg); |
1194 | } |
1195 | b43_print_fw_helptext(dev->wl, 1); |
1196 | goto out; |
1197 | diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h |
1198 | index d455285..66b3eee 100644 |
1199 | --- a/drivers/net/wireless/ti/wl12xx/wl12xx.h |
1200 | +++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h |
1201 | @@ -41,7 +41,7 @@ |
1202 | #define WL127X_IFTYPE_MR_VER 5 |
1203 | #define WL127X_MAJOR_MR_VER 7 |
1204 | #define WL127X_SUBTYPE_MR_VER WLCORE_FW_VER_IGNORE |
1205 | -#define WL127X_MINOR_MR_VER 115 |
1206 | +#define WL127X_MINOR_MR_VER 42 |
1207 | |
1208 | /* FW chip version for wl128x */ |
1209 | #define WL128X_CHIP_VER 7 |
1210 | diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c |
1211 | index 8bc6c80..c48ee4d 100644 |
1212 | --- a/drivers/rtc/rtc-twl.c |
1213 | +++ b/drivers/rtc/rtc-twl.c |
1214 | @@ -524,6 +524,7 @@ static int twl_rtc_probe(struct platform_device *pdev) |
1215 | } |
1216 | |
1217 | platform_set_drvdata(pdev, rtc); |
1218 | + device_init_wakeup(&pdev->dev, 1); |
1219 | return 0; |
1220 | |
1221 | out2: |
1222 | diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c |
1223 | index 57cae1f..246c191 100644 |
1224 | --- a/drivers/usb/chipidea/core.c |
1225 | +++ b/drivers/usb/chipidea/core.c |
1226 | @@ -279,8 +279,9 @@ static void ci_role_work(struct work_struct *work) |
1227 | |
1228 | ci_role_stop(ci); |
1229 | ci_role_start(ci, role); |
1230 | - enable_irq(ci->irq); |
1231 | } |
1232 | + |
1233 | + enable_irq(ci->irq); |
1234 | } |
1235 | |
1236 | static ssize_t show_role(struct device *dev, struct device_attribute *attr, |
1237 | diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c |
1238 | index a172ad5..0c65a81 100644 |
1239 | --- a/drivers/usb/serial/f81232.c |
1240 | +++ b/drivers/usb/serial/f81232.c |
1241 | @@ -165,11 +165,12 @@ static void f81232_set_termios(struct tty_struct *tty, |
1242 | /* FIXME - Stubbed out for now */ |
1243 | |
1244 | /* Don't change anything if nothing has changed */ |
1245 | - if (!tty_termios_hw_change(&tty->termios, old_termios)) |
1246 | + if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios)) |
1247 | return; |
1248 | |
1249 | /* Do the real work here... */ |
1250 | - tty_termios_copy_hw(&tty->termios, old_termios); |
1251 | + if (old_termios) |
1252 | + tty_termios_copy_hw(&tty->termios, old_termios); |
1253 | } |
1254 | |
1255 | static int f81232_tiocmget(struct tty_struct *tty) |
1256 | @@ -187,12 +188,11 @@ static int f81232_tiocmset(struct tty_struct *tty, |
1257 | |
1258 | static int f81232_open(struct tty_struct *tty, struct usb_serial_port *port) |
1259 | { |
1260 | - struct ktermios tmp_termios; |
1261 | int result; |
1262 | |
1263 | /* Setup termios */ |
1264 | if (tty) |
1265 | - f81232_set_termios(tty, port, &tmp_termios); |
1266 | + f81232_set_termios(tty, port, NULL); |
1267 | |
1268 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
1269 | if (result) { |
1270 | diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c |
1271 | index 3b10018..3b5ba4f 100644 |
1272 | --- a/drivers/usb/serial/pl2303.c |
1273 | +++ b/drivers/usb/serial/pl2303.c |
1274 | @@ -283,7 +283,7 @@ static void pl2303_set_termios(struct tty_struct *tty, |
1275 | serial settings even to the same values as before. Thus |
1276 | we actually need to filter in this specific case */ |
1277 | |
1278 | - if (!tty_termios_hw_change(&tty->termios, old_termios)) |
1279 | + if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios)) |
1280 | return; |
1281 | |
1282 | cflag = tty->termios.c_cflag; |
1283 | @@ -292,7 +292,8 @@ static void pl2303_set_termios(struct tty_struct *tty, |
1284 | if (!buf) { |
1285 | dev_err(&port->dev, "%s - out of memory.\n", __func__); |
1286 | /* Report back no change occurred */ |
1287 | - tty->termios = *old_termios; |
1288 | + if (old_termios) |
1289 | + tty->termios = *old_termios; |
1290 | return; |
1291 | } |
1292 | |
1293 | @@ -432,7 +433,7 @@ static void pl2303_set_termios(struct tty_struct *tty, |
1294 | control = priv->line_control; |
1295 | if ((cflag & CBAUD) == B0) |
1296 | priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); |
1297 | - else if ((old_termios->c_cflag & CBAUD) == B0) |
1298 | + else if (old_termios && (old_termios->c_cflag & CBAUD) == B0) |
1299 | priv->line_control |= (CONTROL_DTR | CONTROL_RTS); |
1300 | if (control != priv->line_control) { |
1301 | control = priv->line_control; |
1302 | @@ -491,7 +492,6 @@ static void pl2303_close(struct usb_serial_port *port) |
1303 | |
1304 | static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) |
1305 | { |
1306 | - struct ktermios tmp_termios; |
1307 | struct usb_serial *serial = port->serial; |
1308 | struct pl2303_serial_private *spriv = usb_get_serial_data(serial); |
1309 | int result; |
1310 | @@ -507,7 +507,7 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) |
1311 | |
1312 | /* Setup termios */ |
1313 | if (tty) |
1314 | - pl2303_set_termios(tty, port, &tmp_termios); |
1315 | + pl2303_set_termios(tty, port, NULL); |
1316 | |
1317 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
1318 | if (result) { |
1319 | diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c |
1320 | index 549ef68..6607379 100644 |
1321 | --- a/drivers/usb/serial/spcp8x5.c |
1322 | +++ b/drivers/usb/serial/spcp8x5.c |
1323 | @@ -314,7 +314,6 @@ static void spcp8x5_set_termios(struct tty_struct *tty, |
1324 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); |
1325 | unsigned long flags; |
1326 | unsigned int cflag = tty->termios.c_cflag; |
1327 | - unsigned int old_cflag = old_termios->c_cflag; |
1328 | unsigned short uartdata; |
1329 | unsigned char buf[2] = {0, 0}; |
1330 | int baud; |
1331 | @@ -323,15 +322,15 @@ static void spcp8x5_set_termios(struct tty_struct *tty, |
1332 | |
1333 | |
1334 | /* check that they really want us to change something */ |
1335 | - if (!tty_termios_hw_change(&tty->termios, old_termios)) |
1336 | + if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios)) |
1337 | return; |
1338 | |
1339 | /* set DTR/RTS active */ |
1340 | spin_lock_irqsave(&priv->lock, flags); |
1341 | control = priv->line_control; |
1342 | - if ((old_cflag & CBAUD) == B0) { |
1343 | + if (old_termios && (old_termios->c_cflag & CBAUD) == B0) { |
1344 | priv->line_control |= MCR_DTR; |
1345 | - if (!(old_cflag & CRTSCTS)) |
1346 | + if (!(old_termios->c_cflag & CRTSCTS)) |
1347 | priv->line_control |= MCR_RTS; |
1348 | } |
1349 | if (control != priv->line_control) { |
1350 | @@ -421,7 +420,6 @@ static void spcp8x5_set_termios(struct tty_struct *tty, |
1351 | * status of the device. */ |
1352 | static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port) |
1353 | { |
1354 | - struct ktermios tmp_termios; |
1355 | struct usb_serial *serial = port->serial; |
1356 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); |
1357 | int ret; |
1358 | @@ -442,7 +440,7 @@ static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port) |
1359 | |
1360 | /* Setup termios */ |
1361 | if (tty) |
1362 | - spcp8x5_set_termios(tty, port, &tmp_termios); |
1363 | + spcp8x5_set_termios(tty, port, NULL); |
1364 | |
1365 | spcp8x5_get_msr(serial->dev, &status, priv->type); |
1366 | |
1367 | diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c |
1368 | index 202dd3d..ebbf680 100644 |
1369 | --- a/fs/ceph/locks.c |
1370 | +++ b/fs/ceph/locks.c |
1371 | @@ -191,27 +191,23 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count) |
1372 | } |
1373 | |
1374 | /** |
1375 | - * Encode the flock and fcntl locks for the given inode into the pagelist. |
1376 | - * Format is: #fcntl locks, sequential fcntl locks, #flock locks, |
1377 | - * sequential flock locks. |
1378 | - * Must be called with lock_flocks() already held. |
1379 | - * If we encounter more of a specific lock type than expected, |
1380 | - * we return the value 1. |
1381 | + * Encode the flock and fcntl locks for the given inode into the ceph_filelock |
1382 | + * array. Must be called with lock_flocks() already held. |
1383 | + * If we encounter more of a specific lock type than expected, return -ENOSPC. |
1384 | */ |
1385 | -int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, |
1386 | - int num_fcntl_locks, int num_flock_locks) |
1387 | +int ceph_encode_locks_to_buffer(struct inode *inode, |
1388 | + struct ceph_filelock *flocks, |
1389 | + int num_fcntl_locks, int num_flock_locks) |
1390 | { |
1391 | struct file_lock *lock; |
1392 | - struct ceph_filelock cephlock; |
1393 | int err = 0; |
1394 | int seen_fcntl = 0; |
1395 | int seen_flock = 0; |
1396 | + int l = 0; |
1397 | |
1398 | dout("encoding %d flock and %d fcntl locks", num_flock_locks, |
1399 | num_fcntl_locks); |
1400 | - err = ceph_pagelist_append(pagelist, &num_fcntl_locks, sizeof(u32)); |
1401 | - if (err) |
1402 | - goto fail; |
1403 | + |
1404 | for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) { |
1405 | if (lock->fl_flags & FL_POSIX) { |
1406 | ++seen_fcntl; |
1407 | @@ -219,19 +215,12 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, |
1408 | err = -ENOSPC; |
1409 | goto fail; |
1410 | } |
1411 | - err = lock_to_ceph_filelock(lock, &cephlock); |
1412 | + err = lock_to_ceph_filelock(lock, &flocks[l]); |
1413 | if (err) |
1414 | goto fail; |
1415 | - err = ceph_pagelist_append(pagelist, &cephlock, |
1416 | - sizeof(struct ceph_filelock)); |
1417 | + ++l; |
1418 | } |
1419 | - if (err) |
1420 | - goto fail; |
1421 | } |
1422 | - |
1423 | - err = ceph_pagelist_append(pagelist, &num_flock_locks, sizeof(u32)); |
1424 | - if (err) |
1425 | - goto fail; |
1426 | for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) { |
1427 | if (lock->fl_flags & FL_FLOCK) { |
1428 | ++seen_flock; |
1429 | @@ -239,19 +228,51 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, |
1430 | err = -ENOSPC; |
1431 | goto fail; |
1432 | } |
1433 | - err = lock_to_ceph_filelock(lock, &cephlock); |
1434 | + err = lock_to_ceph_filelock(lock, &flocks[l]); |
1435 | if (err) |
1436 | goto fail; |
1437 | - err = ceph_pagelist_append(pagelist, &cephlock, |
1438 | - sizeof(struct ceph_filelock)); |
1439 | + ++l; |
1440 | } |
1441 | - if (err) |
1442 | - goto fail; |
1443 | } |
1444 | fail: |
1445 | return err; |
1446 | } |
1447 | |
1448 | +/** |
1449 | + * Copy the encoded flock and fcntl locks into the pagelist. |
1450 | + * Format is: #fcntl locks, sequential fcntl locks, #flock locks, |
1451 | + * sequential flock locks. |
1452 | + * Returns zero on success. |
1453 | + */ |
1454 | +int ceph_locks_to_pagelist(struct ceph_filelock *flocks, |
1455 | + struct ceph_pagelist *pagelist, |
1456 | + int num_fcntl_locks, int num_flock_locks) |
1457 | +{ |
1458 | + int err = 0; |
1459 | + __le32 nlocks; |
1460 | + |
1461 | + nlocks = cpu_to_le32(num_fcntl_locks); |
1462 | + err = ceph_pagelist_append(pagelist, &nlocks, sizeof(nlocks)); |
1463 | + if (err) |
1464 | + goto out_fail; |
1465 | + |
1466 | + err = ceph_pagelist_append(pagelist, flocks, |
1467 | + num_fcntl_locks * sizeof(*flocks)); |
1468 | + if (err) |
1469 | + goto out_fail; |
1470 | + |
1471 | + nlocks = cpu_to_le32(num_flock_locks); |
1472 | + err = ceph_pagelist_append(pagelist, &nlocks, sizeof(nlocks)); |
1473 | + if (err) |
1474 | + goto out_fail; |
1475 | + |
1476 | + err = ceph_pagelist_append(pagelist, |
1477 | + &flocks[num_fcntl_locks], |
1478 | + num_flock_locks * sizeof(*flocks)); |
1479 | +out_fail: |
1480 | + return err; |
1481 | +} |
1482 | + |
1483 | /* |
1484 | * Given a pointer to a lock, convert it to a ceph filelock |
1485 | */ |
1486 | diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c |
1487 | index 442880d..90903a7 100644 |
1488 | --- a/fs/ceph/mds_client.c |
1489 | +++ b/fs/ceph/mds_client.c |
1490 | @@ -364,9 +364,9 @@ void ceph_put_mds_session(struct ceph_mds_session *s) |
1491 | atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1); |
1492 | if (atomic_dec_and_test(&s->s_ref)) { |
1493 | if (s->s_auth.authorizer) |
1494 | - s->s_mdsc->fsc->client->monc.auth->ops->destroy_authorizer( |
1495 | - s->s_mdsc->fsc->client->monc.auth, |
1496 | - s->s_auth.authorizer); |
1497 | + ceph_auth_destroy_authorizer( |
1498 | + s->s_mdsc->fsc->client->monc.auth, |
1499 | + s->s_auth.authorizer); |
1500 | kfree(s); |
1501 | } |
1502 | } |
1503 | @@ -2474,39 +2474,44 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, |
1504 | |
1505 | if (recon_state->flock) { |
1506 | int num_fcntl_locks, num_flock_locks; |
1507 | - struct ceph_pagelist_cursor trunc_point; |
1508 | - |
1509 | - ceph_pagelist_set_cursor(pagelist, &trunc_point); |
1510 | - do { |
1511 | - lock_flocks(); |
1512 | - ceph_count_locks(inode, &num_fcntl_locks, |
1513 | - &num_flock_locks); |
1514 | - rec.v2.flock_len = (2*sizeof(u32) + |
1515 | - (num_fcntl_locks+num_flock_locks) * |
1516 | - sizeof(struct ceph_filelock)); |
1517 | - unlock_flocks(); |
1518 | - |
1519 | - /* pre-alloc pagelist */ |
1520 | - ceph_pagelist_truncate(pagelist, &trunc_point); |
1521 | - err = ceph_pagelist_append(pagelist, &rec, reclen); |
1522 | - if (!err) |
1523 | - err = ceph_pagelist_reserve(pagelist, |
1524 | - rec.v2.flock_len); |
1525 | - |
1526 | - /* encode locks */ |
1527 | - if (!err) { |
1528 | - lock_flocks(); |
1529 | - err = ceph_encode_locks(inode, |
1530 | - pagelist, |
1531 | - num_fcntl_locks, |
1532 | - num_flock_locks); |
1533 | - unlock_flocks(); |
1534 | - } |
1535 | - } while (err == -ENOSPC); |
1536 | + struct ceph_filelock *flocks; |
1537 | + |
1538 | +encode_again: |
1539 | + lock_flocks(); |
1540 | + ceph_count_locks(inode, &num_fcntl_locks, &num_flock_locks); |
1541 | + unlock_flocks(); |
1542 | + flocks = kmalloc((num_fcntl_locks+num_flock_locks) * |
1543 | + sizeof(struct ceph_filelock), GFP_NOFS); |
1544 | + if (!flocks) { |
1545 | + err = -ENOMEM; |
1546 | + goto out_free; |
1547 | + } |
1548 | + lock_flocks(); |
1549 | + err = ceph_encode_locks_to_buffer(inode, flocks, |
1550 | + num_fcntl_locks, |
1551 | + num_flock_locks); |
1552 | + unlock_flocks(); |
1553 | + if (err) { |
1554 | + kfree(flocks); |
1555 | + if (err == -ENOSPC) |
1556 | + goto encode_again; |
1557 | + goto out_free; |
1558 | + } |
1559 | + /* |
1560 | + * number of encoded locks is stable, so copy to pagelist |
1561 | + */ |
1562 | + rec.v2.flock_len = cpu_to_le32(2*sizeof(u32) + |
1563 | + (num_fcntl_locks+num_flock_locks) * |
1564 | + sizeof(struct ceph_filelock)); |
1565 | + err = ceph_pagelist_append(pagelist, &rec, reclen); |
1566 | + if (!err) |
1567 | + err = ceph_locks_to_pagelist(flocks, pagelist, |
1568 | + num_fcntl_locks, |
1569 | + num_flock_locks); |
1570 | + kfree(flocks); |
1571 | } else { |
1572 | err = ceph_pagelist_append(pagelist, &rec, reclen); |
1573 | } |
1574 | - |
1575 | out_free: |
1576 | kfree(path); |
1577 | out_dput: |
1578 | @@ -3433,13 +3438,17 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, |
1579 | struct ceph_auth_handshake *auth = &s->s_auth; |
1580 | |
1581 | if (force_new && auth->authorizer) { |
1582 | - if (ac->ops && ac->ops->destroy_authorizer) |
1583 | - ac->ops->destroy_authorizer(ac, auth->authorizer); |
1584 | + ceph_auth_destroy_authorizer(ac, auth->authorizer); |
1585 | auth->authorizer = NULL; |
1586 | } |
1587 | - if (!auth->authorizer && ac->ops && ac->ops->create_authorizer) { |
1588 | - int ret = ac->ops->create_authorizer(ac, CEPH_ENTITY_TYPE_MDS, |
1589 | - auth); |
1590 | + if (!auth->authorizer) { |
1591 | + int ret = ceph_auth_create_authorizer(ac, CEPH_ENTITY_TYPE_MDS, |
1592 | + auth); |
1593 | + if (ret) |
1594 | + return ERR_PTR(ret); |
1595 | + } else { |
1596 | + int ret = ceph_auth_update_authorizer(ac, CEPH_ENTITY_TYPE_MDS, |
1597 | + auth); |
1598 | if (ret) |
1599 | return ERR_PTR(ret); |
1600 | } |
1601 | @@ -3455,7 +3464,7 @@ static int verify_authorizer_reply(struct ceph_connection *con, int len) |
1602 | struct ceph_mds_client *mdsc = s->s_mdsc; |
1603 | struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth; |
1604 | |
1605 | - return ac->ops->verify_authorizer_reply(ac, s->s_auth.authorizer, len); |
1606 | + return ceph_auth_verify_authorizer_reply(ac, s->s_auth.authorizer, len); |
1607 | } |
1608 | |
1609 | static int invalidate_authorizer(struct ceph_connection *con) |
1610 | @@ -3464,8 +3473,7 @@ static int invalidate_authorizer(struct ceph_connection *con) |
1611 | struct ceph_mds_client *mdsc = s->s_mdsc; |
1612 | struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth; |
1613 | |
1614 | - if (ac->ops->invalidate_authorizer) |
1615 | - ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_MDS); |
1616 | + ceph_auth_invalidate_authorizer(ac, CEPH_ENTITY_TYPE_MDS); |
1617 | |
1618 | return ceph_monc_validate_auth(&mdsc->fsc->client->monc); |
1619 | } |
1620 | diff --git a/fs/ceph/super.h b/fs/ceph/super.h |
1621 | index c7b3097..907f214 100644 |
1622 | --- a/fs/ceph/super.h |
1623 | +++ b/fs/ceph/super.h |
1624 | @@ -841,8 +841,13 @@ extern const struct export_operations ceph_export_ops; |
1625 | extern int ceph_lock(struct file *file, int cmd, struct file_lock *fl); |
1626 | extern int ceph_flock(struct file *file, int cmd, struct file_lock *fl); |
1627 | extern void ceph_count_locks(struct inode *inode, int *p_num, int *f_num); |
1628 | -extern int ceph_encode_locks(struct inode *i, struct ceph_pagelist *p, |
1629 | - int p_locks, int f_locks); |
1630 | +extern int ceph_encode_locks_to_buffer(struct inode *inode, |
1631 | + struct ceph_filelock *flocks, |
1632 | + int num_fcntl_locks, |
1633 | + int num_flock_locks); |
1634 | +extern int ceph_locks_to_pagelist(struct ceph_filelock *flocks, |
1635 | + struct ceph_pagelist *pagelist, |
1636 | + int num_fcntl_locks, int num_flock_locks); |
1637 | extern int lock_to_ceph_filelock(struct file_lock *fl, struct ceph_filelock *c); |
1638 | |
1639 | /* debugfs.c */ |
1640 | diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c |
1641 | index bd4b5a7..bdfabda 100644 |
1642 | --- a/fs/proc/kmsg.c |
1643 | +++ b/fs/proc/kmsg.c |
1644 | @@ -21,12 +21,12 @@ extern wait_queue_head_t log_wait; |
1645 | |
1646 | static int kmsg_open(struct inode * inode, struct file * file) |
1647 | { |
1648 | - return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_FILE); |
1649 | + return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_PROC); |
1650 | } |
1651 | |
1652 | static int kmsg_release(struct inode * inode, struct file * file) |
1653 | { |
1654 | - (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, SYSLOG_FROM_FILE); |
1655 | + (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, SYSLOG_FROM_PROC); |
1656 | return 0; |
1657 | } |
1658 | |
1659 | @@ -34,15 +34,15 @@ static ssize_t kmsg_read(struct file *file, char __user *buf, |
1660 | size_t count, loff_t *ppos) |
1661 | { |
1662 | if ((file->f_flags & O_NONBLOCK) && |
1663 | - !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE)) |
1664 | + !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_PROC)) |
1665 | return -EAGAIN; |
1666 | - return do_syslog(SYSLOG_ACTION_READ, buf, count, SYSLOG_FROM_FILE); |
1667 | + return do_syslog(SYSLOG_ACTION_READ, buf, count, SYSLOG_FROM_PROC); |
1668 | } |
1669 | |
1670 | static unsigned int kmsg_poll(struct file *file, poll_table *wait) |
1671 | { |
1672 | poll_wait(file, &log_wait, wait); |
1673 | - if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE)) |
1674 | + if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_PROC)) |
1675 | return POLLIN | POLLRDNORM; |
1676 | return 0; |
1677 | } |
1678 | diff --git a/include/linux/ceph/auth.h b/include/linux/ceph/auth.h |
1679 | index d4080f3..5f33868 100644 |
1680 | --- a/include/linux/ceph/auth.h |
1681 | +++ b/include/linux/ceph/auth.h |
1682 | @@ -52,6 +52,9 @@ struct ceph_auth_client_ops { |
1683 | */ |
1684 | int (*create_authorizer)(struct ceph_auth_client *ac, int peer_type, |
1685 | struct ceph_auth_handshake *auth); |
1686 | + /* ensure that an existing authorizer is up to date */ |
1687 | + int (*update_authorizer)(struct ceph_auth_client *ac, int peer_type, |
1688 | + struct ceph_auth_handshake *auth); |
1689 | int (*verify_authorizer_reply)(struct ceph_auth_client *ac, |
1690 | struct ceph_authorizer *a, size_t len); |
1691 | void (*destroy_authorizer)(struct ceph_auth_client *ac, |
1692 | @@ -75,6 +78,8 @@ struct ceph_auth_client { |
1693 | u64 global_id; /* our unique id in system */ |
1694 | const struct ceph_crypto_key *key; /* our secret key */ |
1695 | unsigned want_keys; /* which services we want */ |
1696 | + |
1697 | + struct mutex mutex; |
1698 | }; |
1699 | |
1700 | extern struct ceph_auth_client *ceph_auth_init(const char *name, |
1701 | @@ -94,5 +99,18 @@ extern int ceph_build_auth(struct ceph_auth_client *ac, |
1702 | void *msg_buf, size_t msg_len); |
1703 | |
1704 | extern int ceph_auth_is_authenticated(struct ceph_auth_client *ac); |
1705 | +extern int ceph_auth_create_authorizer(struct ceph_auth_client *ac, |
1706 | + int peer_type, |
1707 | + struct ceph_auth_handshake *auth); |
1708 | +extern void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac, |
1709 | + struct ceph_authorizer *a); |
1710 | +extern int ceph_auth_update_authorizer(struct ceph_auth_client *ac, |
1711 | + int peer_type, |
1712 | + struct ceph_auth_handshake *a); |
1713 | +extern int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac, |
1714 | + struct ceph_authorizer *a, |
1715 | + size_t len); |
1716 | +extern void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, |
1717 | + int peer_type); |
1718 | |
1719 | #endif |
1720 | diff --git a/include/linux/cpu.h b/include/linux/cpu.h |
1721 | index ce7a074..714e792 100644 |
1722 | --- a/include/linux/cpu.h |
1723 | +++ b/include/linux/cpu.h |
1724 | @@ -175,6 +175,8 @@ extern struct bus_type cpu_subsys; |
1725 | |
1726 | extern void get_online_cpus(void); |
1727 | extern void put_online_cpus(void); |
1728 | +extern void cpu_hotplug_disable(void); |
1729 | +extern void cpu_hotplug_enable(void); |
1730 | #define hotcpu_notifier(fn, pri) cpu_notifier(fn, pri) |
1731 | #define register_hotcpu_notifier(nb) register_cpu_notifier(nb) |
1732 | #define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb) |
1733 | @@ -198,6 +200,8 @@ static inline void cpu_hotplug_driver_unlock(void) |
1734 | |
1735 | #define get_online_cpus() do { } while (0) |
1736 | #define put_online_cpus() do { } while (0) |
1737 | +#define cpu_hotplug_disable() do { } while (0) |
1738 | +#define cpu_hotplug_enable() do { } while (0) |
1739 | #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) |
1740 | /* These aren't inline functions due to a GCC bug. */ |
1741 | #define register_hotcpu_notifier(nb) ({ (void)(nb); 0; }) |
1742 | diff --git a/include/linux/swapops.h b/include/linux/swapops.h |
1743 | index 47ead51..c5fd30d 100644 |
1744 | --- a/include/linux/swapops.h |
1745 | +++ b/include/linux/swapops.h |
1746 | @@ -137,6 +137,7 @@ static inline void make_migration_entry_read(swp_entry_t *entry) |
1747 | |
1748 | extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, |
1749 | unsigned long address); |
1750 | +extern void migration_entry_wait_huge(struct mm_struct *mm, pte_t *pte); |
1751 | #else |
1752 | |
1753 | #define make_migration_entry(page, write) swp_entry(0, 0) |
1754 | @@ -148,6 +149,8 @@ static inline int is_migration_entry(swp_entry_t swp) |
1755 | static inline void make_migration_entry_read(swp_entry_t *entryp) { } |
1756 | static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, |
1757 | unsigned long address) { } |
1758 | +static inline void migration_entry_wait_huge(struct mm_struct *mm, |
1759 | + pte_t *pte) { } |
1760 | static inline int is_write_migration_entry(swp_entry_t entry) |
1761 | { |
1762 | return 0; |
1763 | diff --git a/include/linux/syslog.h b/include/linux/syslog.h |
1764 | index 3891139..98a3153 100644 |
1765 | --- a/include/linux/syslog.h |
1766 | +++ b/include/linux/syslog.h |
1767 | @@ -44,8 +44,8 @@ |
1768 | /* Return size of the log buffer */ |
1769 | #define SYSLOG_ACTION_SIZE_BUFFER 10 |
1770 | |
1771 | -#define SYSLOG_FROM_CALL 0 |
1772 | -#define SYSLOG_FROM_FILE 1 |
1773 | +#define SYSLOG_FROM_READER 0 |
1774 | +#define SYSLOG_FROM_PROC 1 |
1775 | |
1776 | int do_syslog(int type, char __user *buf, int count, bool from_file); |
1777 | |
1778 | diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h |
1779 | index 90cf75a..05bf874 100644 |
1780 | --- a/include/net/bluetooth/hci_core.h |
1781 | +++ b/include/net/bluetooth/hci_core.h |
1782 | @@ -1065,6 +1065,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event); |
1783 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); |
1784 | int mgmt_index_added(struct hci_dev *hdev); |
1785 | int mgmt_index_removed(struct hci_dev *hdev); |
1786 | +int mgmt_set_powered_failed(struct hci_dev *hdev, int err); |
1787 | int mgmt_powered(struct hci_dev *hdev, u8 powered); |
1788 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); |
1789 | int mgmt_connectable(struct hci_dev *hdev, u8 connectable); |
1790 | diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h |
1791 | index 22980a7..9944c3e 100644 |
1792 | --- a/include/net/bluetooth/mgmt.h |
1793 | +++ b/include/net/bluetooth/mgmt.h |
1794 | @@ -42,6 +42,7 @@ |
1795 | #define MGMT_STATUS_NOT_POWERED 0x0f |
1796 | #define MGMT_STATUS_CANCELLED 0x10 |
1797 | #define MGMT_STATUS_INVALID_INDEX 0x11 |
1798 | +#define MGMT_STATUS_RFKILLED 0x12 |
1799 | |
1800 | struct mgmt_hdr { |
1801 | __le16 opcode; |
1802 | diff --git a/kernel/audit.c b/kernel/audit.c |
1803 | index d596e53..8a667f10 100644 |
1804 | --- a/kernel/audit.c |
1805 | +++ b/kernel/audit.c |
1806 | @@ -1107,7 +1107,7 @@ static inline void audit_get_stamp(struct audit_context *ctx, |
1807 | static void wait_for_auditd(unsigned long sleep_time) |
1808 | { |
1809 | DECLARE_WAITQUEUE(wait, current); |
1810 | - set_current_state(TASK_INTERRUPTIBLE); |
1811 | + set_current_state(TASK_UNINTERRUPTIBLE); |
1812 | add_wait_queue(&audit_backlog_wait, &wait); |
1813 | |
1814 | if (audit_backlog_limit && |
1815 | diff --git a/kernel/cpu.c b/kernel/cpu.c |
1816 | index b5e4ab2..198a388 100644 |
1817 | --- a/kernel/cpu.c |
1818 | +++ b/kernel/cpu.c |
1819 | @@ -133,6 +133,27 @@ static void cpu_hotplug_done(void) |
1820 | mutex_unlock(&cpu_hotplug.lock); |
1821 | } |
1822 | |
1823 | +/* |
1824 | + * Wait for currently running CPU hotplug operations to complete (if any) and |
1825 | + * disable future CPU hotplug (from sysfs). The 'cpu_add_remove_lock' protects |
1826 | + * the 'cpu_hotplug_disabled' flag. The same lock is also acquired by the |
1827 | + * hotplug path before performing hotplug operations. So acquiring that lock |
1828 | + * guarantees mutual exclusion from any currently running hotplug operations. |
1829 | + */ |
1830 | +void cpu_hotplug_disable(void) |
1831 | +{ |
1832 | + cpu_maps_update_begin(); |
1833 | + cpu_hotplug_disabled = 1; |
1834 | + cpu_maps_update_done(); |
1835 | +} |
1836 | + |
1837 | +void cpu_hotplug_enable(void) |
1838 | +{ |
1839 | + cpu_maps_update_begin(); |
1840 | + cpu_hotplug_disabled = 0; |
1841 | + cpu_maps_update_done(); |
1842 | +} |
1843 | + |
1844 | #else /* #if CONFIG_HOTPLUG_CPU */ |
1845 | static void cpu_hotplug_begin(void) {} |
1846 | static void cpu_hotplug_done(void) {} |
1847 | @@ -541,36 +562,6 @@ static int __init alloc_frozen_cpus(void) |
1848 | core_initcall(alloc_frozen_cpus); |
1849 | |
1850 | /* |
1851 | - * Prevent regular CPU hotplug from racing with the freezer, by disabling CPU |
1852 | - * hotplug when tasks are about to be frozen. Also, don't allow the freezer |
1853 | - * to continue until any currently running CPU hotplug operation gets |
1854 | - * completed. |
1855 | - * To modify the 'cpu_hotplug_disabled' flag, we need to acquire the |
1856 | - * 'cpu_add_remove_lock'. And this same lock is also taken by the regular |
1857 | - * CPU hotplug path and released only after it is complete. Thus, we |
1858 | - * (and hence the freezer) will block here until any currently running CPU |
1859 | - * hotplug operation gets completed. |
1860 | - */ |
1861 | -void cpu_hotplug_disable_before_freeze(void) |
1862 | -{ |
1863 | - cpu_maps_update_begin(); |
1864 | - cpu_hotplug_disabled = 1; |
1865 | - cpu_maps_update_done(); |
1866 | -} |
1867 | - |
1868 | - |
1869 | -/* |
1870 | - * When tasks have been thawed, re-enable regular CPU hotplug (which had been |
1871 | - * disabled while beginning to freeze tasks). |
1872 | - */ |
1873 | -void cpu_hotplug_enable_after_thaw(void) |
1874 | -{ |
1875 | - cpu_maps_update_begin(); |
1876 | - cpu_hotplug_disabled = 0; |
1877 | - cpu_maps_update_done(); |
1878 | -} |
1879 | - |
1880 | -/* |
1881 | * When callbacks for CPU hotplug notifications are being executed, we must |
1882 | * ensure that the state of the system with respect to the tasks being frozen |
1883 | * or not, as reported by the notification, remains unchanged *throughout the |
1884 | @@ -589,12 +580,12 @@ cpu_hotplug_pm_callback(struct notifier_block *nb, |
1885 | |
1886 | case PM_SUSPEND_PREPARE: |
1887 | case PM_HIBERNATION_PREPARE: |
1888 | - cpu_hotplug_disable_before_freeze(); |
1889 | + cpu_hotplug_disable(); |
1890 | break; |
1891 | |
1892 | case PM_POST_SUSPEND: |
1893 | case PM_POST_HIBERNATION: |
1894 | - cpu_hotplug_enable_after_thaw(); |
1895 | + cpu_hotplug_enable(); |
1896 | break; |
1897 | |
1898 | default: |
1899 | diff --git a/kernel/printk.c b/kernel/printk.c |
1900 | index abbdd9e..0e4eba6a 100644 |
1901 | --- a/kernel/printk.c |
1902 | +++ b/kernel/printk.c |
1903 | @@ -368,6 +368,53 @@ static void log_store(int facility, int level, |
1904 | log_next_seq++; |
1905 | } |
1906 | |
1907 | +#ifdef CONFIG_SECURITY_DMESG_RESTRICT |
1908 | +int dmesg_restrict = 1; |
1909 | +#else |
1910 | +int dmesg_restrict; |
1911 | +#endif |
1912 | + |
1913 | +static int syslog_action_restricted(int type) |
1914 | +{ |
1915 | + if (dmesg_restrict) |
1916 | + return 1; |
1917 | + /* |
1918 | + * Unless restricted, we allow "read all" and "get buffer size" |
1919 | + * for everybody. |
1920 | + */ |
1921 | + return type != SYSLOG_ACTION_READ_ALL && |
1922 | + type != SYSLOG_ACTION_SIZE_BUFFER; |
1923 | +} |
1924 | + |
1925 | +static int check_syslog_permissions(int type, bool from_file) |
1926 | +{ |
1927 | + /* |
1928 | + * If this is from /proc/kmsg and we've already opened it, then we've |
1929 | + * already done the capabilities checks at open time. |
1930 | + */ |
1931 | + if (from_file && type != SYSLOG_ACTION_OPEN) |
1932 | + return 0; |
1933 | + |
1934 | + if (syslog_action_restricted(type)) { |
1935 | + if (capable(CAP_SYSLOG)) |
1936 | + return 0; |
1937 | + /* |
1938 | + * For historical reasons, accept CAP_SYS_ADMIN too, with |
1939 | + * a warning. |
1940 | + */ |
1941 | + if (capable(CAP_SYS_ADMIN)) { |
1942 | + pr_warn_once("%s (%d): Attempt to access syslog with " |
1943 | + "CAP_SYS_ADMIN but no CAP_SYSLOG " |
1944 | + "(deprecated).\n", |
1945 | + current->comm, task_pid_nr(current)); |
1946 | + return 0; |
1947 | + } |
1948 | + return -EPERM; |
1949 | + } |
1950 | + return security_syslog(type); |
1951 | +} |
1952 | + |
1953 | + |
1954 | /* /dev/kmsg - userspace message inject/listen interface */ |
1955 | struct devkmsg_user { |
1956 | u64 seq; |
1957 | @@ -624,7 +671,8 @@ static int devkmsg_open(struct inode *inode, struct file *file) |
1958 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) |
1959 | return 0; |
1960 | |
1961 | - err = security_syslog(SYSLOG_ACTION_READ_ALL); |
1962 | + err = check_syslog_permissions(SYSLOG_ACTION_READ_ALL, |
1963 | + SYSLOG_FROM_READER); |
1964 | if (err) |
1965 | return err; |
1966 | |
1967 | @@ -817,45 +865,6 @@ static inline void boot_delay_msec(int level) |
1968 | } |
1969 | #endif |
1970 | |
1971 | -#ifdef CONFIG_SECURITY_DMESG_RESTRICT |
1972 | -int dmesg_restrict = 1; |
1973 | -#else |
1974 | -int dmesg_restrict; |
1975 | -#endif |
1976 | - |
1977 | -static int syslog_action_restricted(int type) |
1978 | -{ |
1979 | - if (dmesg_restrict) |
1980 | - return 1; |
1981 | - /* Unless restricted, we allow "read all" and "get buffer size" for everybody */ |
1982 | - return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER; |
1983 | -} |
1984 | - |
1985 | -static int check_syslog_permissions(int type, bool from_file) |
1986 | -{ |
1987 | - /* |
1988 | - * If this is from /proc/kmsg and we've already opened it, then we've |
1989 | - * already done the capabilities checks at open time. |
1990 | - */ |
1991 | - if (from_file && type != SYSLOG_ACTION_OPEN) |
1992 | - return 0; |
1993 | - |
1994 | - if (syslog_action_restricted(type)) { |
1995 | - if (capable(CAP_SYSLOG)) |
1996 | - return 0; |
1997 | - /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */ |
1998 | - if (capable(CAP_SYS_ADMIN)) { |
1999 | - printk_once(KERN_WARNING "%s (%d): " |
2000 | - "Attempt to access syslog with CAP_SYS_ADMIN " |
2001 | - "but no CAP_SYSLOG (deprecated).\n", |
2002 | - current->comm, task_pid_nr(current)); |
2003 | - return 0; |
2004 | - } |
2005 | - return -EPERM; |
2006 | - } |
2007 | - return 0; |
2008 | -} |
2009 | - |
2010 | #if defined(CONFIG_PRINTK_TIME) |
2011 | static bool printk_time = 1; |
2012 | #else |
2013 | @@ -1253,7 +1262,7 @@ out: |
2014 | |
2015 | SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) |
2016 | { |
2017 | - return do_syslog(type, buf, len, SYSLOG_FROM_CALL); |
2018 | + return do_syslog(type, buf, len, SYSLOG_FROM_READER); |
2019 | } |
2020 | |
2021 | /* |
2022 | diff --git a/kernel/sys.c b/kernel/sys.c |
2023 | index 0da73cf..e5f0aca 100644 |
2024 | --- a/kernel/sys.c |
2025 | +++ b/kernel/sys.c |
2026 | @@ -357,6 +357,29 @@ int unregister_reboot_notifier(struct notifier_block *nb) |
2027 | } |
2028 | EXPORT_SYMBOL(unregister_reboot_notifier); |
2029 | |
2030 | +/* Add backwards compatibility for stable trees. */ |
2031 | +#ifndef PF_NO_SETAFFINITY |
2032 | +#define PF_NO_SETAFFINITY PF_THREAD_BOUND |
2033 | +#endif |
2034 | + |
2035 | +static void migrate_to_reboot_cpu(void) |
2036 | +{ |
2037 | + /* The boot cpu is always logical cpu 0 */ |
2038 | + int cpu = 0; |
2039 | + |
2040 | + cpu_hotplug_disable(); |
2041 | + |
2042 | + /* Make certain the cpu I'm about to reboot on is online */ |
2043 | + if (!cpu_online(cpu)) |
2044 | + cpu = cpumask_first(cpu_online_mask); |
2045 | + |
2046 | + /* Prevent races with other tasks migrating this task */ |
2047 | + current->flags |= PF_NO_SETAFFINITY; |
2048 | + |
2049 | + /* Make certain I only run on the appropriate processor */ |
2050 | + set_cpus_allowed_ptr(current, cpumask_of(cpu)); |
2051 | +} |
2052 | + |
2053 | /** |
2054 | * kernel_restart - reboot the system |
2055 | * @cmd: pointer to buffer containing command to execute for restart |
2056 | @@ -368,7 +391,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier); |
2057 | void kernel_restart(char *cmd) |
2058 | { |
2059 | kernel_restart_prepare(cmd); |
2060 | - disable_nonboot_cpus(); |
2061 | + migrate_to_reboot_cpu(); |
2062 | syscore_shutdown(); |
2063 | if (!cmd) |
2064 | printk(KERN_EMERG "Restarting system.\n"); |
2065 | @@ -395,7 +418,7 @@ static void kernel_shutdown_prepare(enum system_states state) |
2066 | void kernel_halt(void) |
2067 | { |
2068 | kernel_shutdown_prepare(SYSTEM_HALT); |
2069 | - disable_nonboot_cpus(); |
2070 | + migrate_to_reboot_cpu(); |
2071 | syscore_shutdown(); |
2072 | printk(KERN_EMERG "System halted.\n"); |
2073 | kmsg_dump(KMSG_DUMP_HALT); |
2074 | @@ -414,7 +437,7 @@ void kernel_power_off(void) |
2075 | kernel_shutdown_prepare(SYSTEM_POWER_OFF); |
2076 | if (pm_power_off_prepare) |
2077 | pm_power_off_prepare(); |
2078 | - disable_nonboot_cpus(); |
2079 | + migrate_to_reboot_cpu(); |
2080 | syscore_shutdown(); |
2081 | printk(KERN_EMERG "Power down.\n"); |
2082 | kmsg_dump(KMSG_DUMP_POWEROFF); |
2083 | diff --git a/mm/hugetlb.c b/mm/hugetlb.c |
2084 | index 1a12f5b..ce4cb19 100644 |
2085 | --- a/mm/hugetlb.c |
2086 | +++ b/mm/hugetlb.c |
2087 | @@ -2823,7 +2823,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, |
2088 | if (ptep) { |
2089 | entry = huge_ptep_get(ptep); |
2090 | if (unlikely(is_hugetlb_entry_migration(entry))) { |
2091 | - migration_entry_wait(mm, (pmd_t *)ptep, address); |
2092 | + migration_entry_wait_huge(mm, ptep); |
2093 | return 0; |
2094 | } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) |
2095 | return VM_FAULT_HWPOISON_LARGE | |
2096 | diff --git a/mm/memcontrol.c b/mm/memcontrol.c |
2097 | index 9630d58..f10c112 100644 |
2098 | --- a/mm/memcontrol.c |
2099 | +++ b/mm/memcontrol.c |
2100 | @@ -3033,8 +3033,6 @@ int memcg_update_cache_size(struct kmem_cache *s, int num_groups) |
2101 | return -ENOMEM; |
2102 | } |
2103 | |
2104 | - INIT_WORK(&s->memcg_params->destroy, |
2105 | - kmem_cache_destroy_work_func); |
2106 | s->memcg_params->is_root_cache = true; |
2107 | |
2108 | /* |
2109 | diff --git a/mm/migrate.c b/mm/migrate.c |
2110 | index 22ed5c1..c04d9af 100644 |
2111 | --- a/mm/migrate.c |
2112 | +++ b/mm/migrate.c |
2113 | @@ -200,15 +200,14 @@ static void remove_migration_ptes(struct page *old, struct page *new) |
2114 | * get to the page and wait until migration is finished. |
2115 | * When we return from this function the fault will be retried. |
2116 | */ |
2117 | -void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, |
2118 | - unsigned long address) |
2119 | +static void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep, |
2120 | + spinlock_t *ptl) |
2121 | { |
2122 | - pte_t *ptep, pte; |
2123 | - spinlock_t *ptl; |
2124 | + pte_t pte; |
2125 | swp_entry_t entry; |
2126 | struct page *page; |
2127 | |
2128 | - ptep = pte_offset_map_lock(mm, pmd, address, &ptl); |
2129 | + spin_lock(ptl); |
2130 | pte = *ptep; |
2131 | if (!is_swap_pte(pte)) |
2132 | goto out; |
2133 | @@ -236,6 +235,20 @@ out: |
2134 | pte_unmap_unlock(ptep, ptl); |
2135 | } |
2136 | |
2137 | +void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, |
2138 | + unsigned long address) |
2139 | +{ |
2140 | + spinlock_t *ptl = pte_lockptr(mm, pmd); |
2141 | + pte_t *ptep = pte_offset_map(pmd, address); |
2142 | + __migration_entry_wait(mm, ptep, ptl); |
2143 | +} |
2144 | + |
2145 | +void migration_entry_wait_huge(struct mm_struct *mm, pte_t *pte) |
2146 | +{ |
2147 | + spinlock_t *ptl = &(mm)->page_table_lock; |
2148 | + __migration_entry_wait(mm, pte, ptl); |
2149 | +} |
2150 | + |
2151 | #ifdef CONFIG_BLOCK |
2152 | /* Returns true if all buffers are successfully locked */ |
2153 | static bool buffer_migrate_lock_buffers(struct buffer_head *head, |
2154 | diff --git a/mm/page_alloc.c b/mm/page_alloc.c |
2155 | index 8fcced7..0d4fef2 100644 |
2156 | --- a/mm/page_alloc.c |
2157 | +++ b/mm/page_alloc.c |
2158 | @@ -1626,6 +1626,7 @@ static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark, |
2159 | long min = mark; |
2160 | long lowmem_reserve = z->lowmem_reserve[classzone_idx]; |
2161 | int o; |
2162 | + long free_cma = 0; |
2163 | |
2164 | free_pages -= (1 << order) - 1; |
2165 | if (alloc_flags & ALLOC_HIGH) |
2166 | @@ -1635,9 +1636,10 @@ static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark, |
2167 | #ifdef CONFIG_CMA |
2168 | /* If allocation can't use CMA areas don't use free CMA pages */ |
2169 | if (!(alloc_flags & ALLOC_CMA)) |
2170 | - free_pages -= zone_page_state(z, NR_FREE_CMA_PAGES); |
2171 | + free_cma = zone_page_state(z, NR_FREE_CMA_PAGES); |
2172 | #endif |
2173 | - if (free_pages <= min + lowmem_reserve) |
2174 | + |
2175 | + if (free_pages - free_cma <= min + lowmem_reserve) |
2176 | return false; |
2177 | for (o = 0; o < order; o++) { |
2178 | /* At the next order, this order's pages become unavailable */ |
2179 | diff --git a/mm/swap_state.c b/mm/swap_state.c |
2180 | index 7efcf15..44574ce 100644 |
2181 | --- a/mm/swap_state.c |
2182 | +++ b/mm/swap_state.c |
2183 | @@ -336,8 +336,24 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask, |
2184 | * Swap entry may have been freed since our caller observed it. |
2185 | */ |
2186 | err = swapcache_prepare(entry); |
2187 | - if (err == -EEXIST) { /* seems racy */ |
2188 | + if (err == -EEXIST) { |
2189 | radix_tree_preload_end(); |
2190 | + /* |
2191 | + * We might race against get_swap_page() and stumble |
2192 | + * across a SWAP_HAS_CACHE swap_map entry whose page |
2193 | + * has not been brought into the swapcache yet, while |
2194 | + * the other end is scheduled away waiting on discard |
2195 | + * I/O completion at scan_swap_map(). |
2196 | + * |
2197 | + * In order to avoid turning this transitory state |
2198 | + * into a permanent loop around this -EEXIST case |
2199 | + * if !CONFIG_PREEMPT and the I/O completion happens |
2200 | + * to be waiting on the CPU waitqueue where we are now |
2201 | + * busy looping, we just conditionally invoke the |
2202 | + * scheduler here, if there are some more important |
2203 | + * tasks to run. |
2204 | + */ |
2205 | + cond_resched(); |
2206 | continue; |
2207 | } |
2208 | if (err) { /* swp entry is obsolete ? */ |
2209 | diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c |
2210 | index 60793e7..b88605f 100644 |
2211 | --- a/net/bluetooth/hci_core.c |
2212 | +++ b/net/bluetooth/hci_core.c |
2213 | @@ -1139,11 +1139,15 @@ static const struct rfkill_ops hci_rfkill_ops = { |
2214 | static void hci_power_on(struct work_struct *work) |
2215 | { |
2216 | struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); |
2217 | + int err; |
2218 | |
2219 | BT_DBG("%s", hdev->name); |
2220 | |
2221 | - if (hci_dev_open(hdev->id) < 0) |
2222 | + err = hci_dev_open(hdev->id); |
2223 | + if (err < 0) { |
2224 | + mgmt_set_powered_failed(hdev, err); |
2225 | return; |
2226 | + } |
2227 | |
2228 | if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) |
2229 | queue_delayed_work(hdev->req_workqueue, &hdev->power_off, |
2230 | diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c |
2231 | index 7c7e932..c5f9cd6 100644 |
2232 | --- a/net/bluetooth/l2cap_core.c |
2233 | +++ b/net/bluetooth/l2cap_core.c |
2234 | @@ -3568,10 +3568,14 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) |
2235 | } |
2236 | |
2237 | static inline int l2cap_command_rej(struct l2cap_conn *conn, |
2238 | - struct l2cap_cmd_hdr *cmd, u8 *data) |
2239 | + struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
2240 | + u8 *data) |
2241 | { |
2242 | struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data; |
2243 | |
2244 | + if (cmd_len < sizeof(*rej)) |
2245 | + return -EPROTO; |
2246 | + |
2247 | if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD) |
2248 | return 0; |
2249 | |
2250 | @@ -3720,11 +3724,14 @@ sendresp: |
2251 | } |
2252 | |
2253 | static int l2cap_connect_req(struct l2cap_conn *conn, |
2254 | - struct l2cap_cmd_hdr *cmd, u8 *data) |
2255 | + struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) |
2256 | { |
2257 | struct hci_dev *hdev = conn->hcon->hdev; |
2258 | struct hci_conn *hcon = conn->hcon; |
2259 | |
2260 | + if (cmd_len < sizeof(struct l2cap_conn_req)) |
2261 | + return -EPROTO; |
2262 | + |
2263 | hci_dev_lock(hdev); |
2264 | if (test_bit(HCI_MGMT, &hdev->dev_flags) && |
2265 | !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags)) |
2266 | @@ -3738,7 +3745,8 @@ static int l2cap_connect_req(struct l2cap_conn *conn, |
2267 | } |
2268 | |
2269 | static int l2cap_connect_create_rsp(struct l2cap_conn *conn, |
2270 | - struct l2cap_cmd_hdr *cmd, u8 *data) |
2271 | + struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
2272 | + u8 *data) |
2273 | { |
2274 | struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; |
2275 | u16 scid, dcid, result, status; |
2276 | @@ -3746,6 +3754,9 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, |
2277 | u8 req[128]; |
2278 | int err; |
2279 | |
2280 | + if (cmd_len < sizeof(*rsp)) |
2281 | + return -EPROTO; |
2282 | + |
2283 | scid = __le16_to_cpu(rsp->scid); |
2284 | dcid = __le16_to_cpu(rsp->dcid); |
2285 | result = __le16_to_cpu(rsp->result); |
2286 | @@ -3843,6 +3854,9 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, |
2287 | struct l2cap_chan *chan; |
2288 | int len, err = 0; |
2289 | |
2290 | + if (cmd_len < sizeof(*req)) |
2291 | + return -EPROTO; |
2292 | + |
2293 | dcid = __le16_to_cpu(req->dcid); |
2294 | flags = __le16_to_cpu(req->flags); |
2295 | |
2296 | @@ -3866,7 +3880,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, |
2297 | |
2298 | /* Reject if config buffer is too small. */ |
2299 | len = cmd_len - sizeof(*req); |
2300 | - if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) { |
2301 | + if (chan->conf_len + len > sizeof(chan->conf_req)) { |
2302 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, |
2303 | l2cap_build_conf_rsp(chan, rsp, |
2304 | L2CAP_CONF_REJECT, flags), rsp); |
2305 | @@ -3944,14 +3958,18 @@ unlock: |
2306 | } |
2307 | |
2308 | static inline int l2cap_config_rsp(struct l2cap_conn *conn, |
2309 | - struct l2cap_cmd_hdr *cmd, u8 *data) |
2310 | + struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
2311 | + u8 *data) |
2312 | { |
2313 | struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data; |
2314 | u16 scid, flags, result; |
2315 | struct l2cap_chan *chan; |
2316 | - int len = le16_to_cpu(cmd->len) - sizeof(*rsp); |
2317 | + int len = cmd_len - sizeof(*rsp); |
2318 | int err = 0; |
2319 | |
2320 | + if (cmd_len < sizeof(*rsp)) |
2321 | + return -EPROTO; |
2322 | + |
2323 | scid = __le16_to_cpu(rsp->scid); |
2324 | flags = __le16_to_cpu(rsp->flags); |
2325 | result = __le16_to_cpu(rsp->result); |
2326 | @@ -4052,7 +4070,8 @@ done: |
2327 | } |
2328 | |
2329 | static inline int l2cap_disconnect_req(struct l2cap_conn *conn, |
2330 | - struct l2cap_cmd_hdr *cmd, u8 *data) |
2331 | + struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
2332 | + u8 *data) |
2333 | { |
2334 | struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data; |
2335 | struct l2cap_disconn_rsp rsp; |
2336 | @@ -4060,6 +4079,9 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, |
2337 | struct l2cap_chan *chan; |
2338 | struct sock *sk; |
2339 | |
2340 | + if (cmd_len != sizeof(*req)) |
2341 | + return -EPROTO; |
2342 | + |
2343 | scid = __le16_to_cpu(req->scid); |
2344 | dcid = __le16_to_cpu(req->dcid); |
2345 | |
2346 | @@ -4099,12 +4121,16 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, |
2347 | } |
2348 | |
2349 | static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, |
2350 | - struct l2cap_cmd_hdr *cmd, u8 *data) |
2351 | + struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
2352 | + u8 *data) |
2353 | { |
2354 | struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data; |
2355 | u16 dcid, scid; |
2356 | struct l2cap_chan *chan; |
2357 | |
2358 | + if (cmd_len != sizeof(*rsp)) |
2359 | + return -EPROTO; |
2360 | + |
2361 | scid = __le16_to_cpu(rsp->scid); |
2362 | dcid = __le16_to_cpu(rsp->dcid); |
2363 | |
2364 | @@ -4134,11 +4160,15 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, |
2365 | } |
2366 | |
2367 | static inline int l2cap_information_req(struct l2cap_conn *conn, |
2368 | - struct l2cap_cmd_hdr *cmd, u8 *data) |
2369 | + struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
2370 | + u8 *data) |
2371 | { |
2372 | struct l2cap_info_req *req = (struct l2cap_info_req *) data; |
2373 | u16 type; |
2374 | |
2375 | + if (cmd_len != sizeof(*req)) |
2376 | + return -EPROTO; |
2377 | + |
2378 | type = __le16_to_cpu(req->type); |
2379 | |
2380 | BT_DBG("type 0x%4.4x", type); |
2381 | @@ -4185,11 +4215,15 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, |
2382 | } |
2383 | |
2384 | static inline int l2cap_information_rsp(struct l2cap_conn *conn, |
2385 | - struct l2cap_cmd_hdr *cmd, u8 *data) |
2386 | + struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
2387 | + u8 *data) |
2388 | { |
2389 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; |
2390 | u16 type, result; |
2391 | |
2392 | + if (cmd_len != sizeof(*rsp)) |
2393 | + return -EPROTO; |
2394 | + |
2395 | type = __le16_to_cpu(rsp->type); |
2396 | result = __le16_to_cpu(rsp->result); |
2397 | |
2398 | @@ -5055,16 +5089,16 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, |
2399 | |
2400 | switch (cmd->code) { |
2401 | case L2CAP_COMMAND_REJ: |
2402 | - l2cap_command_rej(conn, cmd, data); |
2403 | + l2cap_command_rej(conn, cmd, cmd_len, data); |
2404 | break; |
2405 | |
2406 | case L2CAP_CONN_REQ: |
2407 | - err = l2cap_connect_req(conn, cmd, data); |
2408 | + err = l2cap_connect_req(conn, cmd, cmd_len, data); |
2409 | break; |
2410 | |
2411 | case L2CAP_CONN_RSP: |
2412 | case L2CAP_CREATE_CHAN_RSP: |
2413 | - err = l2cap_connect_create_rsp(conn, cmd, data); |
2414 | + err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data); |
2415 | break; |
2416 | |
2417 | case L2CAP_CONF_REQ: |
2418 | @@ -5072,15 +5106,15 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, |
2419 | break; |
2420 | |
2421 | case L2CAP_CONF_RSP: |
2422 | - err = l2cap_config_rsp(conn, cmd, data); |
2423 | + err = l2cap_config_rsp(conn, cmd, cmd_len, data); |
2424 | break; |
2425 | |
2426 | case L2CAP_DISCONN_REQ: |
2427 | - err = l2cap_disconnect_req(conn, cmd, data); |
2428 | + err = l2cap_disconnect_req(conn, cmd, cmd_len, data); |
2429 | break; |
2430 | |
2431 | case L2CAP_DISCONN_RSP: |
2432 | - err = l2cap_disconnect_rsp(conn, cmd, data); |
2433 | + err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data); |
2434 | break; |
2435 | |
2436 | case L2CAP_ECHO_REQ: |
2437 | @@ -5091,11 +5125,11 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, |
2438 | break; |
2439 | |
2440 | case L2CAP_INFO_REQ: |
2441 | - err = l2cap_information_req(conn, cmd, data); |
2442 | + err = l2cap_information_req(conn, cmd, cmd_len, data); |
2443 | break; |
2444 | |
2445 | case L2CAP_INFO_RSP: |
2446 | - err = l2cap_information_rsp(conn, cmd, data); |
2447 | + err = l2cap_information_rsp(conn, cmd, cmd_len, data); |
2448 | break; |
2449 | |
2450 | case L2CAP_CREATE_CHAN_REQ: |
2451 | diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c |
2452 | index 39395c7..8b649d9 100644 |
2453 | --- a/net/bluetooth/mgmt.c |
2454 | +++ b/net/bluetooth/mgmt.c |
2455 | @@ -3124,6 +3124,27 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered) |
2456 | return err; |
2457 | } |
2458 | |
2459 | +int mgmt_set_powered_failed(struct hci_dev *hdev, int err) |
2460 | +{ |
2461 | + struct pending_cmd *cmd; |
2462 | + u8 status; |
2463 | + |
2464 | + cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); |
2465 | + if (!cmd) |
2466 | + return -ENOENT; |
2467 | + |
2468 | + if (err == -ERFKILL) |
2469 | + status = MGMT_STATUS_RFKILLED; |
2470 | + else |
2471 | + status = MGMT_STATUS_FAILED; |
2472 | + |
2473 | + err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status); |
2474 | + |
2475 | + mgmt_pending_remove(cmd); |
2476 | + |
2477 | + return err; |
2478 | +} |
2479 | + |
2480 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) |
2481 | { |
2482 | struct cmd_lookup match = { NULL, hdev }; |
2483 | diff --git a/net/ceph/auth.c b/net/ceph/auth.c |
2484 | index b4bf4ac..6b923bc 100644 |
2485 | --- a/net/ceph/auth.c |
2486 | +++ b/net/ceph/auth.c |
2487 | @@ -47,6 +47,7 @@ struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_cryp |
2488 | if (!ac) |
2489 | goto out; |
2490 | |
2491 | + mutex_init(&ac->mutex); |
2492 | ac->negotiating = true; |
2493 | if (name) |
2494 | ac->name = name; |
2495 | @@ -73,10 +74,12 @@ void ceph_auth_destroy(struct ceph_auth_client *ac) |
2496 | */ |
2497 | void ceph_auth_reset(struct ceph_auth_client *ac) |
2498 | { |
2499 | + mutex_lock(&ac->mutex); |
2500 | dout("auth_reset %p\n", ac); |
2501 | if (ac->ops && !ac->negotiating) |
2502 | ac->ops->reset(ac); |
2503 | ac->negotiating = true; |
2504 | + mutex_unlock(&ac->mutex); |
2505 | } |
2506 | |
2507 | int ceph_entity_name_encode(const char *name, void **p, void *end) |
2508 | @@ -102,6 +105,7 @@ int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len) |
2509 | int i, num; |
2510 | int ret; |
2511 | |
2512 | + mutex_lock(&ac->mutex); |
2513 | dout("auth_build_hello\n"); |
2514 | monhdr->have_version = 0; |
2515 | monhdr->session_mon = cpu_to_le16(-1); |
2516 | @@ -122,15 +126,19 @@ int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len) |
2517 | |
2518 | ret = ceph_entity_name_encode(ac->name, &p, end); |
2519 | if (ret < 0) |
2520 | - return ret; |
2521 | + goto out; |
2522 | ceph_decode_need(&p, end, sizeof(u64), bad); |
2523 | ceph_encode_64(&p, ac->global_id); |
2524 | |
2525 | ceph_encode_32(&lenp, p - lenp - sizeof(u32)); |
2526 | - return p - buf; |
2527 | + ret = p - buf; |
2528 | +out: |
2529 | + mutex_unlock(&ac->mutex); |
2530 | + return ret; |
2531 | |
2532 | bad: |
2533 | - return -ERANGE; |
2534 | + ret = -ERANGE; |
2535 | + goto out; |
2536 | } |
2537 | |
2538 | static int ceph_build_auth_request(struct ceph_auth_client *ac, |
2539 | @@ -151,11 +159,13 @@ static int ceph_build_auth_request(struct ceph_auth_client *ac, |
2540 | if (ret < 0) { |
2541 | pr_err("error %d building auth method %s request\n", ret, |
2542 | ac->ops->name); |
2543 | - return ret; |
2544 | + goto out; |
2545 | } |
2546 | dout(" built request %d bytes\n", ret); |
2547 | ceph_encode_32(&p, ret); |
2548 | - return p + ret - msg_buf; |
2549 | + ret = p + ret - msg_buf; |
2550 | +out: |
2551 | + return ret; |
2552 | } |
2553 | |
2554 | /* |
2555 | @@ -176,6 +186,7 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac, |
2556 | int result_msg_len; |
2557 | int ret = -EINVAL; |
2558 | |
2559 | + mutex_lock(&ac->mutex); |
2560 | dout("handle_auth_reply %p %p\n", p, end); |
2561 | ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad); |
2562 | protocol = ceph_decode_32(&p); |
2563 | @@ -227,33 +238,103 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac, |
2564 | |
2565 | ret = ac->ops->handle_reply(ac, result, payload, payload_end); |
2566 | if (ret == -EAGAIN) { |
2567 | - return ceph_build_auth_request(ac, reply_buf, reply_len); |
2568 | + ret = ceph_build_auth_request(ac, reply_buf, reply_len); |
2569 | } else if (ret) { |
2570 | pr_err("auth method '%s' error %d\n", ac->ops->name, ret); |
2571 | - return ret; |
2572 | } |
2573 | - return 0; |
2574 | |
2575 | -bad: |
2576 | - pr_err("failed to decode auth msg\n"); |
2577 | out: |
2578 | + mutex_unlock(&ac->mutex); |
2579 | return ret; |
2580 | + |
2581 | +bad: |
2582 | + pr_err("failed to decode auth msg\n"); |
2583 | + ret = -EINVAL; |
2584 | + goto out; |
2585 | } |
2586 | |
2587 | int ceph_build_auth(struct ceph_auth_client *ac, |
2588 | void *msg_buf, size_t msg_len) |
2589 | { |
2590 | + int ret = 0; |
2591 | + |
2592 | + mutex_lock(&ac->mutex); |
2593 | if (!ac->protocol) |
2594 | - return ceph_auth_build_hello(ac, msg_buf, msg_len); |
2595 | - BUG_ON(!ac->ops); |
2596 | - if (ac->ops->should_authenticate(ac)) |
2597 | - return ceph_build_auth_request(ac, msg_buf, msg_len); |
2598 | - return 0; |
2599 | + ret = ceph_auth_build_hello(ac, msg_buf, msg_len); |
2600 | + else if (ac->ops->should_authenticate(ac)) |
2601 | + ret = ceph_build_auth_request(ac, msg_buf, msg_len); |
2602 | + mutex_unlock(&ac->mutex); |
2603 | + return ret; |
2604 | } |
2605 | |
2606 | int ceph_auth_is_authenticated(struct ceph_auth_client *ac) |
2607 | { |
2608 | - if (!ac->ops) |
2609 | - return 0; |
2610 | - return ac->ops->is_authenticated(ac); |
2611 | + int ret = 0; |
2612 | + |
2613 | + mutex_lock(&ac->mutex); |
2614 | + if (ac->ops) |
2615 | + ret = ac->ops->is_authenticated(ac); |
2616 | + mutex_unlock(&ac->mutex); |
2617 | + return ret; |
2618 | +} |
2619 | +EXPORT_SYMBOL(ceph_auth_is_authenticated); |
2620 | + |
2621 | +int ceph_auth_create_authorizer(struct ceph_auth_client *ac, |
2622 | + int peer_type, |
2623 | + struct ceph_auth_handshake *auth) |
2624 | +{ |
2625 | + int ret = 0; |
2626 | + |
2627 | + mutex_lock(&ac->mutex); |
2628 | + if (ac->ops && ac->ops->create_authorizer) |
2629 | + ret = ac->ops->create_authorizer(ac, peer_type, auth); |
2630 | + mutex_unlock(&ac->mutex); |
2631 | + return ret; |
2632 | +} |
2633 | +EXPORT_SYMBOL(ceph_auth_create_authorizer); |
2634 | + |
2635 | +void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac, |
2636 | + struct ceph_authorizer *a) |
2637 | +{ |
2638 | + mutex_lock(&ac->mutex); |
2639 | + if (ac->ops && ac->ops->destroy_authorizer) |
2640 | + ac->ops->destroy_authorizer(ac, a); |
2641 | + mutex_unlock(&ac->mutex); |
2642 | +} |
2643 | +EXPORT_SYMBOL(ceph_auth_destroy_authorizer); |
2644 | + |
2645 | +int ceph_auth_update_authorizer(struct ceph_auth_client *ac, |
2646 | + int peer_type, |
2647 | + struct ceph_auth_handshake *a) |
2648 | +{ |
2649 | + int ret = 0; |
2650 | + |
2651 | + mutex_lock(&ac->mutex); |
2652 | + if (ac->ops && ac->ops->update_authorizer) |
2653 | + ret = ac->ops->update_authorizer(ac, peer_type, a); |
2654 | + mutex_unlock(&ac->mutex); |
2655 | + return ret; |
2656 | +} |
2657 | +EXPORT_SYMBOL(ceph_auth_update_authorizer); |
2658 | + |
2659 | +int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac, |
2660 | + struct ceph_authorizer *a, size_t len) |
2661 | +{ |
2662 | + int ret = 0; |
2663 | + |
2664 | + mutex_lock(&ac->mutex); |
2665 | + if (ac->ops && ac->ops->verify_authorizer_reply) |
2666 | + ret = ac->ops->verify_authorizer_reply(ac, a, len); |
2667 | + mutex_unlock(&ac->mutex); |
2668 | + return ret; |
2669 | +} |
2670 | +EXPORT_SYMBOL(ceph_auth_verify_authorizer_reply); |
2671 | + |
2672 | +void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type) |
2673 | +{ |
2674 | + mutex_lock(&ac->mutex); |
2675 | + if (ac->ops && ac->ops->invalidate_authorizer) |
2676 | + ac->ops->invalidate_authorizer(ac, peer_type); |
2677 | + mutex_unlock(&ac->mutex); |
2678 | } |
2679 | +EXPORT_SYMBOL(ceph_auth_invalidate_authorizer); |
2680 | diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c |
2681 | index a16bf14..96238ba 100644 |
2682 | --- a/net/ceph/auth_x.c |
2683 | +++ b/net/ceph/auth_x.c |
2684 | @@ -298,6 +298,7 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac, |
2685 | return -ENOMEM; |
2686 | } |
2687 | au->service = th->service; |
2688 | + au->secret_id = th->secret_id; |
2689 | |
2690 | msg_a = au->buf->vec.iov_base; |
2691 | msg_a->struct_v = 1; |
2692 | @@ -555,6 +556,26 @@ static int ceph_x_create_authorizer( |
2693 | return 0; |
2694 | } |
2695 | |
2696 | +static int ceph_x_update_authorizer( |
2697 | + struct ceph_auth_client *ac, int peer_type, |
2698 | + struct ceph_auth_handshake *auth) |
2699 | +{ |
2700 | + struct ceph_x_authorizer *au; |
2701 | + struct ceph_x_ticket_handler *th; |
2702 | + |
2703 | + th = get_ticket_handler(ac, peer_type); |
2704 | + if (IS_ERR(th)) |
2705 | + return PTR_ERR(th); |
2706 | + |
2707 | + au = (struct ceph_x_authorizer *)auth->authorizer; |
2708 | + if (au->secret_id < th->secret_id) { |
2709 | + dout("ceph_x_update_authorizer service %u secret %llu < %llu\n", |
2710 | + au->service, au->secret_id, th->secret_id); |
2711 | + return ceph_x_build_authorizer(ac, th, au); |
2712 | + } |
2713 | + return 0; |
2714 | +} |
2715 | + |
2716 | static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, |
2717 | struct ceph_authorizer *a, size_t len) |
2718 | { |
2719 | @@ -630,7 +651,7 @@ static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac, |
2720 | |
2721 | th = get_ticket_handler(ac, peer_type); |
2722 | if (!IS_ERR(th)) |
2723 | - remove_ticket_handler(ac, th); |
2724 | + memset(&th->validity, 0, sizeof(th->validity)); |
2725 | } |
2726 | |
2727 | |
2728 | @@ -641,6 +662,7 @@ static const struct ceph_auth_client_ops ceph_x_ops = { |
2729 | .build_request = ceph_x_build_request, |
2730 | .handle_reply = ceph_x_handle_reply, |
2731 | .create_authorizer = ceph_x_create_authorizer, |
2732 | + .update_authorizer = ceph_x_update_authorizer, |
2733 | .verify_authorizer_reply = ceph_x_verify_authorizer_reply, |
2734 | .destroy_authorizer = ceph_x_destroy_authorizer, |
2735 | .invalidate_authorizer = ceph_x_invalidate_authorizer, |
2736 | diff --git a/net/ceph/auth_x.h b/net/ceph/auth_x.h |
2737 | index f459e93..c5a058d 100644 |
2738 | --- a/net/ceph/auth_x.h |
2739 | +++ b/net/ceph/auth_x.h |
2740 | @@ -29,6 +29,7 @@ struct ceph_x_authorizer { |
2741 | struct ceph_buffer *buf; |
2742 | unsigned int service; |
2743 | u64 nonce; |
2744 | + u64 secret_id; |
2745 | char reply_buf[128]; /* big enough for encrypted blob */ |
2746 | }; |
2747 | |
2748 | diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c |
2749 | index 2c0669f..096e09f 100644 |
2750 | --- a/net/ceph/messenger.c |
2751 | +++ b/net/ceph/messenger.c |
2752 | @@ -1597,7 +1597,6 @@ static int process_connect(struct ceph_connection *con) |
2753 | con->error_msg = "connect authorization failure"; |
2754 | return -1; |
2755 | } |
2756 | - con->auth_retry = 1; |
2757 | con_out_kvec_reset(con); |
2758 | ret = prepare_write_connect(con); |
2759 | if (ret < 0) |
2760 | @@ -1682,7 +1681,7 @@ static int process_connect(struct ceph_connection *con) |
2761 | |
2762 | WARN_ON(con->state != CON_STATE_NEGOTIATING); |
2763 | con->state = CON_STATE_OPEN; |
2764 | - |
2765 | + con->auth_retry = 0; /* we authenticated; clear flag */ |
2766 | con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq); |
2767 | con->connect_seq++; |
2768 | con->peer_features = server_feat; |
2769 | diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c |
2770 | index aef5b10..1fe25cd 100644 |
2771 | --- a/net/ceph/mon_client.c |
2772 | +++ b/net/ceph/mon_client.c |
2773 | @@ -737,7 +737,7 @@ static void delayed_work(struct work_struct *work) |
2774 | |
2775 | __validate_auth(monc); |
2776 | |
2777 | - if (monc->auth->ops->is_authenticated(monc->auth)) |
2778 | + if (ceph_auth_is_authenticated(monc->auth)) |
2779 | __send_subscribe(monc); |
2780 | } |
2781 | __schedule_delayed(monc); |
2782 | @@ -892,8 +892,7 @@ static void handle_auth_reply(struct ceph_mon_client *monc, |
2783 | |
2784 | mutex_lock(&monc->mutex); |
2785 | had_debugfs_info = have_debugfs_info(monc); |
2786 | - if (monc->auth->ops) |
2787 | - was_auth = monc->auth->ops->is_authenticated(monc->auth); |
2788 | + was_auth = ceph_auth_is_authenticated(monc->auth); |
2789 | monc->pending_auth = 0; |
2790 | ret = ceph_handle_auth_reply(monc->auth, msg->front.iov_base, |
2791 | msg->front.iov_len, |
2792 | @@ -904,7 +903,7 @@ static void handle_auth_reply(struct ceph_mon_client *monc, |
2793 | wake_up_all(&monc->client->auth_wq); |
2794 | } else if (ret > 0) { |
2795 | __send_prepared_auth_request(monc, ret); |
2796 | - } else if (!was_auth && monc->auth->ops->is_authenticated(monc->auth)) { |
2797 | + } else if (!was_auth && ceph_auth_is_authenticated(monc->auth)) { |
2798 | dout("authenticated, starting session\n"); |
2799 | |
2800 | monc->client->msgr.inst.name.type = CEPH_ENTITY_TYPE_CLIENT; |
2801 | diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c |
2802 | index d730dd4..366e70e 100644 |
2803 | --- a/net/ceph/osd_client.c |
2804 | +++ b/net/ceph/osd_client.c |
2805 | @@ -654,8 +654,7 @@ static void put_osd(struct ceph_osd *osd) |
2806 | if (atomic_dec_and_test(&osd->o_ref) && osd->o_auth.authorizer) { |
2807 | struct ceph_auth_client *ac = osd->o_osdc->client->monc.auth; |
2808 | |
2809 | - if (ac->ops && ac->ops->destroy_authorizer) |
2810 | - ac->ops->destroy_authorizer(ac, osd->o_auth.authorizer); |
2811 | + ceph_auth_destroy_authorizer(ac, osd->o_auth.authorizer); |
2812 | kfree(osd); |
2813 | } |
2814 | } |
2815 | @@ -1399,13 +1398,13 @@ static void kick_requests(struct ceph_osd_client *osdc, int force_resend) |
2816 | __register_request(osdc, req); |
2817 | __unregister_linger_request(osdc, req); |
2818 | } |
2819 | + reset_changed_osds(osdc); |
2820 | mutex_unlock(&osdc->request_mutex); |
2821 | |
2822 | if (needmap) { |
2823 | dout("%d requests for down osds, need new map\n", needmap); |
2824 | ceph_monc_request_next_osdmap(&osdc->client->monc); |
2825 | } |
2826 | - reset_changed_osds(osdc); |
2827 | } |
2828 | |
2829 | |
2830 | @@ -2168,13 +2167,17 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, |
2831 | struct ceph_auth_handshake *auth = &o->o_auth; |
2832 | |
2833 | if (force_new && auth->authorizer) { |
2834 | - if (ac->ops && ac->ops->destroy_authorizer) |
2835 | - ac->ops->destroy_authorizer(ac, auth->authorizer); |
2836 | + ceph_auth_destroy_authorizer(ac, auth->authorizer); |
2837 | auth->authorizer = NULL; |
2838 | } |
2839 | - if (!auth->authorizer && ac->ops && ac->ops->create_authorizer) { |
2840 | - int ret = ac->ops->create_authorizer(ac, CEPH_ENTITY_TYPE_OSD, |
2841 | - auth); |
2842 | + if (!auth->authorizer) { |
2843 | + int ret = ceph_auth_create_authorizer(ac, CEPH_ENTITY_TYPE_OSD, |
2844 | + auth); |
2845 | + if (ret) |
2846 | + return ERR_PTR(ret); |
2847 | + } else { |
2848 | + int ret = ceph_auth_update_authorizer(ac, CEPH_ENTITY_TYPE_OSD, |
2849 | + auth); |
2850 | if (ret) |
2851 | return ERR_PTR(ret); |
2852 | } |
2853 | @@ -2190,11 +2193,7 @@ static int verify_authorizer_reply(struct ceph_connection *con, int len) |
2854 | struct ceph_osd_client *osdc = o->o_osdc; |
2855 | struct ceph_auth_client *ac = osdc->client->monc.auth; |
2856 | |
2857 | - /* |
2858 | - * XXX If ac->ops or ac->ops->verify_authorizer_reply is null, |
2859 | - * XXX which do we do: succeed or fail? |
2860 | - */ |
2861 | - return ac->ops->verify_authorizer_reply(ac, o->o_auth.authorizer, len); |
2862 | + return ceph_auth_verify_authorizer_reply(ac, o->o_auth.authorizer, len); |
2863 | } |
2864 | |
2865 | static int invalidate_authorizer(struct ceph_connection *con) |
2866 | @@ -2203,9 +2202,7 @@ static int invalidate_authorizer(struct ceph_connection *con) |
2867 | struct ceph_osd_client *osdc = o->o_osdc; |
2868 | struct ceph_auth_client *ac = osdc->client->monc.auth; |
2869 | |
2870 | - if (ac->ops && ac->ops->invalidate_authorizer) |
2871 | - ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_OSD); |
2872 | - |
2873 | + ceph_auth_invalidate_authorizer(ac, CEPH_ENTITY_TYPE_OSD); |
2874 | return ceph_monc_validate_auth(&osdc->client->monc); |
2875 | } |
2876 |