Contents of /trunk/kernel-alx-legacy/patches-4.9/0243-4.9.144-all-fixes.patch
Parent Directory | Revision Log
Revision 3608 -
(show annotations)
(download)
Fri Aug 14 07:34:29 2020 UTC (4 years, 1 month ago) by niro
File size: 191186 byte(s)
Fri Aug 14 07:34:29 2020 UTC (4 years, 1 month ago) by niro
File size: 191186 byte(s)
-added kerenl-alx-legacy pkg
1 | diff --git a/Makefile b/Makefile |
2 | index 8ec52cd19526..c62b2b529724 100644 |
3 | --- a/Makefile |
4 | +++ b/Makefile |
5 | @@ -1,6 +1,6 @@ |
6 | VERSION = 4 |
7 | PATCHLEVEL = 9 |
8 | -SUBLEVEL = 143 |
9 | +SUBLEVEL = 144 |
10 | EXTRAVERSION = |
11 | NAME = Roaring Lionus |
12 | |
13 | @@ -802,6 +802,9 @@ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) |
14 | # disable pointer signed / unsigned warnings in gcc 4.0 |
15 | KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign) |
16 | |
17 | +# disable stringop warnings in gcc 8+ |
18 | +KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation) |
19 | + |
20 | # disable invalid "can't wrap" optimizations for signed / pointers |
21 | KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) |
22 | |
23 | diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig |
24 | index b7b78cb09a37..c7a081c583b9 100644 |
25 | --- a/arch/arc/Kconfig |
26 | +++ b/arch/arc/Kconfig |
27 | @@ -105,7 +105,7 @@ endmenu |
28 | |
29 | choice |
30 | prompt "ARC Instruction Set" |
31 | - default ISA_ARCOMPACT |
32 | + default ISA_ARCV2 |
33 | |
34 | config ISA_ARCOMPACT |
35 | bool "ARCompact ISA" |
36 | diff --git a/arch/arc/Makefile b/arch/arc/Makefile |
37 | index a3b456008201..fd79faab7892 100644 |
38 | --- a/arch/arc/Makefile |
39 | +++ b/arch/arc/Makefile |
40 | @@ -8,7 +8,7 @@ |
41 | |
42 | UTS_MACHINE := arc |
43 | |
44 | -KBUILD_DEFCONFIG := nsim_700_defconfig |
45 | +KBUILD_DEFCONFIG := nsim_hs_defconfig |
46 | |
47 | cflags-y += -fno-common -pipe -fno-builtin -mmedium-calls -D__linux__ |
48 | cflags-$(CONFIG_ISA_ARCOMPACT) += -mA7 |
49 | diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig |
50 | index dd623199bb48..cdb00af5aeac 100644 |
51 | --- a/arch/arc/configs/axs101_defconfig |
52 | +++ b/arch/arc/configs/axs101_defconfig |
53 | @@ -15,6 +15,7 @@ CONFIG_PERF_EVENTS=y |
54 | # CONFIG_VM_EVENT_COUNTERS is not set |
55 | # CONFIG_SLUB_DEBUG is not set |
56 | # CONFIG_COMPAT_BRK is not set |
57 | +CONFIG_ISA_ARCOMPACT=y |
58 | CONFIG_MODULES=y |
59 | CONFIG_MODULE_FORCE_LOAD=y |
60 | CONFIG_MODULE_UNLOAD=y |
61 | @@ -96,6 +97,7 @@ CONFIG_VFAT_FS=y |
62 | CONFIG_NTFS_FS=y |
63 | CONFIG_TMPFS=y |
64 | CONFIG_NFS_FS=y |
65 | +CONFIG_NFS_V3_ACL=y |
66 | CONFIG_NLS_CODEPAGE_437=y |
67 | CONFIG_NLS_ISO8859_1=y |
68 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
69 | diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig |
70 | index 2e0d7d74b8ee..02c766d2c1e0 100644 |
71 | --- a/arch/arc/configs/axs103_defconfig |
72 | +++ b/arch/arc/configs/axs103_defconfig |
73 | @@ -97,6 +97,7 @@ CONFIG_VFAT_FS=y |
74 | CONFIG_NTFS_FS=y |
75 | CONFIG_TMPFS=y |
76 | CONFIG_NFS_FS=y |
77 | +CONFIG_NFS_V3_ACL=y |
78 | CONFIG_NLS_CODEPAGE_437=y |
79 | CONFIG_NLS_ISO8859_1=y |
80 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
81 | diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig |
82 | index ec188fca2cc9..8c16093d639f 100644 |
83 | --- a/arch/arc/configs/axs103_smp_defconfig |
84 | +++ b/arch/arc/configs/axs103_smp_defconfig |
85 | @@ -98,6 +98,7 @@ CONFIG_VFAT_FS=y |
86 | CONFIG_NTFS_FS=y |
87 | CONFIG_TMPFS=y |
88 | CONFIG_NFS_FS=y |
89 | +CONFIG_NFS_V3_ACL=y |
90 | CONFIG_NLS_CODEPAGE_437=y |
91 | CONFIG_NLS_ISO8859_1=y |
92 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
93 | diff --git a/arch/arc/configs/nps_defconfig b/arch/arc/configs/nps_defconfig |
94 | index ede625c76216..397742c6c84e 100644 |
95 | --- a/arch/arc/configs/nps_defconfig |
96 | +++ b/arch/arc/configs/nps_defconfig |
97 | @@ -15,6 +15,7 @@ CONFIG_SYSCTL_SYSCALL=y |
98 | CONFIG_EMBEDDED=y |
99 | CONFIG_PERF_EVENTS=y |
100 | # CONFIG_COMPAT_BRK is not set |
101 | +CONFIG_ISA_ARCOMPACT=y |
102 | CONFIG_KPROBES=y |
103 | CONFIG_MODULES=y |
104 | CONFIG_MODULE_FORCE_LOAD=y |
105 | @@ -75,6 +76,7 @@ CONFIG_PROC_KCORE=y |
106 | CONFIG_TMPFS=y |
107 | # CONFIG_MISC_FILESYSTEMS is not set |
108 | CONFIG_NFS_FS=y |
109 | +CONFIG_NFS_V3_ACL=y |
110 | CONFIG_ROOT_NFS=y |
111 | CONFIG_DEBUG_INFO=y |
112 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
113 | diff --git a/arch/arc/configs/nsim_700_defconfig b/arch/arc/configs/nsim_700_defconfig |
114 | index df609fce999b..cbc6d068d1f4 100644 |
115 | --- a/arch/arc/configs/nsim_700_defconfig |
116 | +++ b/arch/arc/configs/nsim_700_defconfig |
117 | @@ -16,6 +16,7 @@ CONFIG_EMBEDDED=y |
118 | CONFIG_PERF_EVENTS=y |
119 | # CONFIG_SLUB_DEBUG is not set |
120 | # CONFIG_COMPAT_BRK is not set |
121 | +CONFIG_ISA_ARCOMPACT=y |
122 | CONFIG_KPROBES=y |
123 | CONFIG_MODULES=y |
124 | # CONFIG_LBDAF is not set |
125 | diff --git a/arch/arc/configs/nsimosci_defconfig b/arch/arc/configs/nsimosci_defconfig |
126 | index 5680daa65471..d34b838a71c1 100644 |
127 | --- a/arch/arc/configs/nsimosci_defconfig |
128 | +++ b/arch/arc/configs/nsimosci_defconfig |
129 | @@ -16,6 +16,7 @@ CONFIG_EMBEDDED=y |
130 | CONFIG_PERF_EVENTS=y |
131 | # CONFIG_SLUB_DEBUG is not set |
132 | # CONFIG_COMPAT_BRK is not set |
133 | +CONFIG_ISA_ARCOMPACT=y |
134 | CONFIG_KPROBES=y |
135 | CONFIG_MODULES=y |
136 | # CONFIG_LBDAF is not set |
137 | @@ -70,5 +71,6 @@ CONFIG_EXT2_FS_XATTR=y |
138 | CONFIG_TMPFS=y |
139 | # CONFIG_MISC_FILESYSTEMS is not set |
140 | CONFIG_NFS_FS=y |
141 | +CONFIG_NFS_V3_ACL=y |
142 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
143 | # CONFIG_ENABLE_MUST_CHECK is not set |
144 | diff --git a/arch/arc/configs/nsimosci_hs_defconfig b/arch/arc/configs/nsimosci_hs_defconfig |
145 | index 87decc491c58..e8c7dd703f13 100644 |
146 | --- a/arch/arc/configs/nsimosci_hs_defconfig |
147 | +++ b/arch/arc/configs/nsimosci_hs_defconfig |
148 | @@ -69,5 +69,6 @@ CONFIG_EXT2_FS_XATTR=y |
149 | CONFIG_TMPFS=y |
150 | # CONFIG_MISC_FILESYSTEMS is not set |
151 | CONFIG_NFS_FS=y |
152 | +CONFIG_NFS_V3_ACL=y |
153 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
154 | # CONFIG_ENABLE_MUST_CHECK is not set |
155 | diff --git a/arch/arc/configs/nsimosci_hs_smp_defconfig b/arch/arc/configs/nsimosci_hs_smp_defconfig |
156 | index 4d14684dc74a..100d7bf0035b 100644 |
157 | --- a/arch/arc/configs/nsimosci_hs_smp_defconfig |
158 | +++ b/arch/arc/configs/nsimosci_hs_smp_defconfig |
159 | @@ -80,6 +80,7 @@ CONFIG_EXT2_FS_XATTR=y |
160 | CONFIG_TMPFS=y |
161 | # CONFIG_MISC_FILESYSTEMS is not set |
162 | CONFIG_NFS_FS=y |
163 | +CONFIG_NFS_V3_ACL=y |
164 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
165 | # CONFIG_ENABLE_MUST_CHECK is not set |
166 | CONFIG_FTRACE=y |
167 | diff --git a/arch/arc/configs/tb10x_defconfig b/arch/arc/configs/tb10x_defconfig |
168 | index 4c5118384eb5..493966c0dcbe 100644 |
169 | --- a/arch/arc/configs/tb10x_defconfig |
170 | +++ b/arch/arc/configs/tb10x_defconfig |
171 | @@ -19,6 +19,7 @@ CONFIG_KALLSYMS_ALL=y |
172 | # CONFIG_AIO is not set |
173 | CONFIG_EMBEDDED=y |
174 | # CONFIG_COMPAT_BRK is not set |
175 | +CONFIG_ISA_ARCOMPACT=y |
176 | CONFIG_SLAB=y |
177 | CONFIG_MODULES=y |
178 | CONFIG_MODULE_FORCE_LOAD=y |
179 | diff --git a/arch/arc/configs/vdk_hs38_defconfig b/arch/arc/configs/vdk_hs38_defconfig |
180 | index c0d6a010751a..b1d38afeba70 100644 |
181 | --- a/arch/arc/configs/vdk_hs38_defconfig |
182 | +++ b/arch/arc/configs/vdk_hs38_defconfig |
183 | @@ -88,6 +88,7 @@ CONFIG_NTFS_FS=y |
184 | CONFIG_TMPFS=y |
185 | CONFIG_JFFS2_FS=y |
186 | CONFIG_NFS_FS=y |
187 | +CONFIG_NFS_V3_ACL=y |
188 | CONFIG_NLS_CODEPAGE_437=y |
189 | CONFIG_NLS_ISO8859_1=y |
190 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
191 | diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig |
192 | index 969b206d6c67..2d103f73a265 100644 |
193 | --- a/arch/arc/configs/vdk_hs38_smp_defconfig |
194 | +++ b/arch/arc/configs/vdk_hs38_smp_defconfig |
195 | @@ -87,6 +87,7 @@ CONFIG_NTFS_FS=y |
196 | CONFIG_TMPFS=y |
197 | CONFIG_JFFS2_FS=y |
198 | CONFIG_NFS_FS=y |
199 | +CONFIG_NFS_V3_ACL=y |
200 | CONFIG_NLS_CODEPAGE_437=y |
201 | CONFIG_NLS_ISO8859_1=y |
202 | # CONFIG_ENABLE_WARN_DEPRECATED is not set |
203 | diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h |
204 | index d87882513ee3..deee3ac8c29f 100644 |
205 | --- a/arch/mips/include/asm/syscall.h |
206 | +++ b/arch/mips/include/asm/syscall.h |
207 | @@ -51,7 +51,7 @@ static inline unsigned long mips_get_syscall_arg(unsigned long *arg, |
208 | #ifdef CONFIG_64BIT |
209 | case 4: case 5: case 6: case 7: |
210 | #ifdef CONFIG_MIPS32_O32 |
211 | - if (test_thread_flag(TIF_32BIT_REGS)) |
212 | + if (test_tsk_thread_flag(task, TIF_32BIT_REGS)) |
213 | return get_user(*arg, (int *)usp + n); |
214 | else |
215 | #endif |
216 | diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c |
217 | index 0696142048d5..9194b04cb689 100644 |
218 | --- a/arch/mips/ralink/mt7620.c |
219 | +++ b/arch/mips/ralink/mt7620.c |
220 | @@ -81,7 +81,7 @@ static struct rt2880_pmx_func pcie_rst_grp[] = { |
221 | }; |
222 | static struct rt2880_pmx_func nd_sd_grp[] = { |
223 | FUNC("nand", MT7620_GPIO_MODE_NAND, 45, 15), |
224 | - FUNC("sd", MT7620_GPIO_MODE_SD, 45, 15) |
225 | + FUNC("sd", MT7620_GPIO_MODE_SD, 47, 13) |
226 | }; |
227 | |
228 | static struct rt2880_pmx_group mt7620a_pinmux_data[] = { |
229 | diff --git a/arch/x86/include/asm/suspend_64.h b/arch/x86/include/asm/suspend_64.h |
230 | index 6136a18152af..2bd96b4df140 100644 |
231 | --- a/arch/x86/include/asm/suspend_64.h |
232 | +++ b/arch/x86/include/asm/suspend_64.h |
233 | @@ -42,8 +42,7 @@ struct saved_context { |
234 | set_debugreg((thread)->debugreg##register, register) |
235 | |
236 | /* routines for saving/restoring kernel state */ |
237 | -extern int acpi_save_state_mem(void); |
238 | -extern char core_restore_code; |
239 | -extern char restore_registers; |
240 | +extern char core_restore_code[]; |
241 | +extern char restore_registers[]; |
242 | |
243 | #endif /* _ASM_X86_SUSPEND_64_H */ |
244 | diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c |
245 | index 4bc35ac28d11..fa1b0e3c8a06 100644 |
246 | --- a/arch/x86/kvm/svm.c |
247 | +++ b/arch/x86/kvm/svm.c |
248 | @@ -1333,20 +1333,23 @@ static u64 *avic_get_physical_id_entry(struct kvm_vcpu *vcpu, int index) |
249 | static int avic_init_access_page(struct kvm_vcpu *vcpu) |
250 | { |
251 | struct kvm *kvm = vcpu->kvm; |
252 | - int ret; |
253 | + int ret = 0; |
254 | |
255 | + mutex_lock(&kvm->slots_lock); |
256 | if (kvm->arch.apic_access_page_done) |
257 | - return 0; |
258 | + goto out; |
259 | |
260 | - ret = x86_set_memory_region(kvm, |
261 | - APIC_ACCESS_PAGE_PRIVATE_MEMSLOT, |
262 | - APIC_DEFAULT_PHYS_BASE, |
263 | - PAGE_SIZE); |
264 | + ret = __x86_set_memory_region(kvm, |
265 | + APIC_ACCESS_PAGE_PRIVATE_MEMSLOT, |
266 | + APIC_DEFAULT_PHYS_BASE, |
267 | + PAGE_SIZE); |
268 | if (ret) |
269 | - return ret; |
270 | + goto out; |
271 | |
272 | kvm->arch.apic_access_page_done = true; |
273 | - return 0; |
274 | +out: |
275 | + mutex_unlock(&kvm->slots_lock); |
276 | + return ret; |
277 | } |
278 | |
279 | static int avic_init_backing_page(struct kvm_vcpu *vcpu) |
280 | diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c |
281 | index 0cb1dd461529..fef485b789ca 100644 |
282 | --- a/arch/x86/power/hibernate_64.c |
283 | +++ b/arch/x86/power/hibernate_64.c |
284 | @@ -126,7 +126,7 @@ static int relocate_restore_code(void) |
285 | if (!relocated_restore_code) |
286 | return -ENOMEM; |
287 | |
288 | - memcpy((void *)relocated_restore_code, &core_restore_code, PAGE_SIZE); |
289 | + memcpy((void *)relocated_restore_code, core_restore_code, PAGE_SIZE); |
290 | |
291 | /* Make the page containing the relocated code executable */ |
292 | pgd = (pgd_t *)__va(read_cr3()) + pgd_index(relocated_restore_code); |
293 | @@ -197,8 +197,8 @@ int arch_hibernation_header_save(void *addr, unsigned int max_size) |
294 | |
295 | if (max_size < sizeof(struct restore_data_record)) |
296 | return -EOVERFLOW; |
297 | - rdr->jump_address = (unsigned long)&restore_registers; |
298 | - rdr->jump_address_phys = __pa_symbol(&restore_registers); |
299 | + rdr->jump_address = (unsigned long)restore_registers; |
300 | + rdr->jump_address_phys = __pa_symbol(restore_registers); |
301 | rdr->cr3 = restore_cr3; |
302 | rdr->magic = RESTORE_MAGIC; |
303 | return 0; |
304 | diff --git a/drivers/android/binder.c b/drivers/android/binder.c |
305 | index 49199bd2ab93..80499f421a29 100644 |
306 | --- a/drivers/android/binder.c |
307 | +++ b/drivers/android/binder.c |
308 | @@ -302,6 +302,7 @@ struct binder_proc { |
309 | struct mm_struct *vma_vm_mm; |
310 | struct task_struct *tsk; |
311 | struct files_struct *files; |
312 | + struct mutex files_lock; |
313 | struct hlist_node deferred_work_node; |
314 | int deferred_work; |
315 | void *buffer; |
316 | @@ -375,20 +376,26 @@ binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer); |
317 | |
318 | static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) |
319 | { |
320 | - struct files_struct *files = proc->files; |
321 | unsigned long rlim_cur; |
322 | unsigned long irqs; |
323 | + int ret; |
324 | |
325 | - if (files == NULL) |
326 | - return -ESRCH; |
327 | - |
328 | - if (!lock_task_sighand(proc->tsk, &irqs)) |
329 | - return -EMFILE; |
330 | - |
331 | + mutex_lock(&proc->files_lock); |
332 | + if (proc->files == NULL) { |
333 | + ret = -ESRCH; |
334 | + goto err; |
335 | + } |
336 | + if (!lock_task_sighand(proc->tsk, &irqs)) { |
337 | + ret = -EMFILE; |
338 | + goto err; |
339 | + } |
340 | rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE); |
341 | unlock_task_sighand(proc->tsk, &irqs); |
342 | |
343 | - return __alloc_fd(files, 0, rlim_cur, flags); |
344 | + ret = __alloc_fd(proc->files, 0, rlim_cur, flags); |
345 | +err: |
346 | + mutex_unlock(&proc->files_lock); |
347 | + return ret; |
348 | } |
349 | |
350 | /* |
351 | @@ -397,8 +404,10 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) |
352 | static void task_fd_install( |
353 | struct binder_proc *proc, unsigned int fd, struct file *file) |
354 | { |
355 | + mutex_lock(&proc->files_lock); |
356 | if (proc->files) |
357 | __fd_install(proc->files, fd, file); |
358 | + mutex_unlock(&proc->files_lock); |
359 | } |
360 | |
361 | /* |
362 | @@ -408,9 +417,11 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd) |
363 | { |
364 | int retval; |
365 | |
366 | - if (proc->files == NULL) |
367 | - return -ESRCH; |
368 | - |
369 | + mutex_lock(&proc->files_lock); |
370 | + if (proc->files == NULL) { |
371 | + retval = -ESRCH; |
372 | + goto err; |
373 | + } |
374 | retval = __close_fd(proc->files, fd); |
375 | /* can't restart close syscall because file table entry was cleared */ |
376 | if (unlikely(retval == -ERESTARTSYS || |
377 | @@ -418,7 +429,8 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd) |
378 | retval == -ERESTARTNOHAND || |
379 | retval == -ERESTART_RESTARTBLOCK)) |
380 | retval = -EINTR; |
381 | - |
382 | +err: |
383 | + mutex_unlock(&proc->files_lock); |
384 | return retval; |
385 | } |
386 | |
387 | @@ -2946,7 +2958,9 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) |
388 | binder_insert_free_buffer(proc, buffer); |
389 | proc->free_async_space = proc->buffer_size / 2; |
390 | barrier(); |
391 | + mutex_lock(&proc->files_lock); |
392 | proc->files = get_files_struct(current); |
393 | + mutex_unlock(&proc->files_lock); |
394 | proc->vma = vma; |
395 | proc->vma_vm_mm = vma->vm_mm; |
396 | |
397 | @@ -2982,6 +2996,7 @@ static int binder_open(struct inode *nodp, struct file *filp) |
398 | return -ENOMEM; |
399 | get_task_struct(current->group_leader); |
400 | proc->tsk = current->group_leader; |
401 | + mutex_init(&proc->files_lock); |
402 | INIT_LIST_HEAD(&proc->todo); |
403 | init_waitqueue_head(&proc->wait); |
404 | proc->default_priority = task_nice(current); |
405 | @@ -3220,9 +3235,11 @@ static void binder_deferred_func(struct work_struct *work) |
406 | |
407 | files = NULL; |
408 | if (defer & BINDER_DEFERRED_PUT_FILES) { |
409 | + mutex_lock(&proc->files_lock); |
410 | files = proc->files; |
411 | if (files) |
412 | proc->files = NULL; |
413 | + mutex_unlock(&proc->files_lock); |
414 | } |
415 | |
416 | if (defer & BINDER_DEFERRED_FLUSH) |
417 | diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c |
418 | index fb9976254224..fabfeeb537ae 100644 |
419 | --- a/drivers/gpu/drm/ast/ast_main.c |
420 | +++ b/drivers/gpu/drm/ast/ast_main.c |
421 | @@ -556,7 +556,8 @@ int ast_driver_unload(struct drm_device *dev) |
422 | drm_mode_config_cleanup(dev); |
423 | |
424 | ast_mm_fini(ast); |
425 | - pci_iounmap(dev->pdev, ast->ioregs); |
426 | + if (ast->ioregs != ast->regs + AST_IO_MM_OFFSET) |
427 | + pci_iounmap(dev->pdev, ast->ioregs); |
428 | pci_iounmap(dev->pdev, ast->regs); |
429 | kfree(ast); |
430 | return 0; |
431 | diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c |
432 | index 6b143514a566..56b2dd9a5b68 100644 |
433 | --- a/drivers/gpu/drm/drm_auth.c |
434 | +++ b/drivers/gpu/drm/drm_auth.c |
435 | @@ -133,6 +133,7 @@ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv) |
436 | |
437 | lockdep_assert_held_once(&dev->master_mutex); |
438 | |
439 | + WARN_ON(fpriv->is_master); |
440 | old_master = fpriv->master; |
441 | fpriv->master = drm_master_create(dev); |
442 | if (!fpriv->master) { |
443 | @@ -161,6 +162,7 @@ out_err: |
444 | /* drop references and restore old master on failure */ |
445 | drm_master_put(&fpriv->master); |
446 | fpriv->master = old_master; |
447 | + fpriv->is_master = 0; |
448 | |
449 | return ret; |
450 | } |
451 | diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c |
452 | index 92e3f93ee682..06d61e654f59 100644 |
453 | --- a/drivers/gpu/drm/gma500/mdfld_intel_display.c |
454 | +++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c |
455 | @@ -99,7 +99,7 @@ void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe) |
456 | /* Wait for for the pipe enable to take effect. */ |
457 | for (count = 0; count < COUNT_MAX; count++) { |
458 | temp = REG_READ(map->conf); |
459 | - if ((temp & PIPEACONF_PIPE_STATE) == 1) |
460 | + if (temp & PIPEACONF_PIPE_STATE) |
461 | break; |
462 | } |
463 | } |
464 | diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c |
465 | index e097780752f6..863d030786e5 100644 |
466 | --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c |
467 | +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c |
468 | @@ -1446,8 +1446,7 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, |
469 | } |
470 | |
471 | /* The CEC module handles HDMI hotplug detection */ |
472 | - cec_np = of_find_compatible_node(np->parent, NULL, |
473 | - "mediatek,mt8173-cec"); |
474 | + cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173-cec"); |
475 | if (!cec_np) { |
476 | dev_err(dev, "Failed to find CEC node\n"); |
477 | return -EINVAL; |
478 | @@ -1457,8 +1456,10 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, |
479 | if (!cec_pdev) { |
480 | dev_err(hdmi->dev, "Waiting for CEC device %s\n", |
481 | cec_np->full_name); |
482 | + of_node_put(cec_np); |
483 | return -EPROBE_DEFER; |
484 | } |
485 | + of_node_put(cec_np); |
486 | hdmi->cec_dev = &cec_pdev->dev; |
487 | |
488 | /* |
489 | diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c |
490 | index d7da1dca765f..b1daf5c16117 100644 |
491 | --- a/drivers/infiniband/hw/mlx5/main.c |
492 | +++ b/drivers/infiniband/hw/mlx5/main.c |
493 | @@ -710,31 +710,26 @@ enum mlx5_ib_width { |
494 | MLX5_IB_WIDTH_12X = 1 << 4 |
495 | }; |
496 | |
497 | -static int translate_active_width(struct ib_device *ibdev, u8 active_width, |
498 | +static void translate_active_width(struct ib_device *ibdev, u8 active_width, |
499 | u8 *ib_width) |
500 | { |
501 | struct mlx5_ib_dev *dev = to_mdev(ibdev); |
502 | - int err = 0; |
503 | |
504 | - if (active_width & MLX5_IB_WIDTH_1X) { |
505 | + if (active_width & MLX5_IB_WIDTH_1X) |
506 | *ib_width = IB_WIDTH_1X; |
507 | - } else if (active_width & MLX5_IB_WIDTH_2X) { |
508 | - mlx5_ib_dbg(dev, "active_width %d is not supported by IB spec\n", |
509 | - (int)active_width); |
510 | - err = -EINVAL; |
511 | - } else if (active_width & MLX5_IB_WIDTH_4X) { |
512 | + else if (active_width & MLX5_IB_WIDTH_4X) |
513 | *ib_width = IB_WIDTH_4X; |
514 | - } else if (active_width & MLX5_IB_WIDTH_8X) { |
515 | + else if (active_width & MLX5_IB_WIDTH_8X) |
516 | *ib_width = IB_WIDTH_8X; |
517 | - } else if (active_width & MLX5_IB_WIDTH_12X) { |
518 | + else if (active_width & MLX5_IB_WIDTH_12X) |
519 | *ib_width = IB_WIDTH_12X; |
520 | - } else { |
521 | - mlx5_ib_dbg(dev, "Invalid active_width %d\n", |
522 | + else { |
523 | + mlx5_ib_dbg(dev, "Invalid active_width %d, setting width to default value: 4x\n", |
524 | (int)active_width); |
525 | - err = -EINVAL; |
526 | + *ib_width = IB_WIDTH_4X; |
527 | } |
528 | |
529 | - return err; |
530 | + return; |
531 | } |
532 | |
533 | static int mlx5_mtu_to_ib_mtu(int mtu) |
534 | @@ -842,10 +837,8 @@ static int mlx5_query_hca_port(struct ib_device *ibdev, u8 port, |
535 | if (err) |
536 | goto out; |
537 | |
538 | - err = translate_active_width(ibdev, ib_link_width_oper, |
539 | - &props->active_width); |
540 | - if (err) |
541 | - goto out; |
542 | + translate_active_width(ibdev, ib_link_width_oper, &props->active_width); |
543 | + |
544 | err = mlx5_query_port_ib_proto_oper(mdev, &props->active_speed, port); |
545 | if (err) |
546 | goto out; |
547 | diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c |
548 | index bc6f5bb6c524..d46424d4b71e 100644 |
549 | --- a/drivers/infiniband/ulp/iser/iser_verbs.c |
550 | +++ b/drivers/infiniband/ulp/iser/iser_verbs.c |
551 | @@ -1110,7 +1110,9 @@ u8 iser_check_task_pi_status(struct iscsi_iser_task *iser_task, |
552 | IB_MR_CHECK_SIG_STATUS, &mr_status); |
553 | if (ret) { |
554 | pr_err("ib_check_mr_status failed, ret %d\n", ret); |
555 | - goto err; |
556 | + /* Not a lot we can do, return ambiguous guard error */ |
557 | + *sector = 0; |
558 | + return 0x1; |
559 | } |
560 | |
561 | if (mr_status.fail_status & IB_MR_CHECK_SIG_STATUS) { |
562 | @@ -1138,9 +1140,6 @@ u8 iser_check_task_pi_status(struct iscsi_iser_task *iser_task, |
563 | } |
564 | |
565 | return 0; |
566 | -err: |
567 | - /* Not alot we can do here, return ambiguous guard error */ |
568 | - return 0x1; |
569 | } |
570 | |
571 | void iser_err_comp(struct ib_wc *wc, const char *type) |
572 | diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c |
573 | index 2e52015634f9..f55dcdf99bc5 100644 |
574 | --- a/drivers/input/joystick/xpad.c |
575 | +++ b/drivers/input/joystick/xpad.c |
576 | @@ -483,18 +483,18 @@ static const u8 xboxone_hori_init[] = { |
577 | }; |
578 | |
579 | /* |
580 | - * This packet is required for some of the PDP pads to start |
581 | + * This packet is required for most (all?) of the PDP pads to start |
582 | * sending input reports. These pads include: (0x0e6f:0x02ab), |
583 | - * (0x0e6f:0x02a4). |
584 | + * (0x0e6f:0x02a4), (0x0e6f:0x02a6). |
585 | */ |
586 | static const u8 xboxone_pdp_init1[] = { |
587 | 0x0a, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14 |
588 | }; |
589 | |
590 | /* |
591 | - * This packet is required for some of the PDP pads to start |
592 | + * This packet is required for most (all?) of the PDP pads to start |
593 | * sending input reports. These pads include: (0x0e6f:0x02ab), |
594 | - * (0x0e6f:0x02a4). |
595 | + * (0x0e6f:0x02a4), (0x0e6f:0x02a6). |
596 | */ |
597 | static const u8 xboxone_pdp_init2[] = { |
598 | 0x06, 0x20, 0x00, 0x02, 0x01, 0x00 |
599 | @@ -530,12 +530,8 @@ static const struct xboxone_init_packet xboxone_init_packets[] = { |
600 | XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init), |
601 | XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init), |
602 | XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init), |
603 | - XBOXONE_INIT_PKT(0x0e6f, 0x02ab, xboxone_pdp_init1), |
604 | - XBOXONE_INIT_PKT(0x0e6f, 0x02ab, xboxone_pdp_init2), |
605 | - XBOXONE_INIT_PKT(0x0e6f, 0x02a4, xboxone_pdp_init1), |
606 | - XBOXONE_INIT_PKT(0x0e6f, 0x02a4, xboxone_pdp_init2), |
607 | - XBOXONE_INIT_PKT(0x0e6f, 0x02a6, xboxone_pdp_init1), |
608 | - XBOXONE_INIT_PKT(0x0e6f, 0x02a6, xboxone_pdp_init2), |
609 | + XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init1), |
610 | + XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init2), |
611 | XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init), |
612 | XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init), |
613 | XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init), |
614 | diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c |
615 | index 795fa353de7c..c64d87442a62 100644 |
616 | --- a/drivers/input/keyboard/matrix_keypad.c |
617 | +++ b/drivers/input/keyboard/matrix_keypad.c |
618 | @@ -405,7 +405,7 @@ matrix_keypad_parse_dt(struct device *dev) |
619 | struct matrix_keypad_platform_data *pdata; |
620 | struct device_node *np = dev->of_node; |
621 | unsigned int *gpios; |
622 | - int i, nrow, ncol; |
623 | + int ret, i, nrow, ncol; |
624 | |
625 | if (!np) { |
626 | dev_err(dev, "device lacks DT data\n"); |
627 | @@ -447,12 +447,19 @@ matrix_keypad_parse_dt(struct device *dev) |
628 | return ERR_PTR(-ENOMEM); |
629 | } |
630 | |
631 | - for (i = 0; i < pdata->num_row_gpios; i++) |
632 | - gpios[i] = of_get_named_gpio(np, "row-gpios", i); |
633 | + for (i = 0; i < nrow; i++) { |
634 | + ret = of_get_named_gpio(np, "row-gpios", i); |
635 | + if (ret < 0) |
636 | + return ERR_PTR(ret); |
637 | + gpios[i] = ret; |
638 | + } |
639 | |
640 | - for (i = 0; i < pdata->num_col_gpios; i++) |
641 | - gpios[pdata->num_row_gpios + i] = |
642 | - of_get_named_gpio(np, "col-gpios", i); |
643 | + for (i = 0; i < ncol; i++) { |
644 | + ret = of_get_named_gpio(np, "col-gpios", i); |
645 | + if (ret < 0) |
646 | + return ERR_PTR(ret); |
647 | + gpios[nrow + i] = ret; |
648 | + } |
649 | |
650 | pdata->row_gpios = gpios; |
651 | pdata->col_gpios = &gpios[pdata->num_row_gpios]; |
652 | @@ -479,10 +486,8 @@ static int matrix_keypad_probe(struct platform_device *pdev) |
653 | pdata = dev_get_platdata(&pdev->dev); |
654 | if (!pdata) { |
655 | pdata = matrix_keypad_parse_dt(&pdev->dev); |
656 | - if (IS_ERR(pdata)) { |
657 | - dev_err(&pdev->dev, "no platform data defined\n"); |
658 | + if (IS_ERR(pdata)) |
659 | return PTR_ERR(pdata); |
660 | - } |
661 | } else if (!pdata->keymap_data) { |
662 | dev_err(&pdev->dev, "no keymap data defined\n"); |
663 | return -EINVAL; |
664 | diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c |
665 | index b3119589a444..471984ec2db0 100644 |
666 | --- a/drivers/input/mouse/elan_i2c_core.c |
667 | +++ b/drivers/input/mouse/elan_i2c_core.c |
668 | @@ -1253,6 +1253,9 @@ static const struct acpi_device_id elan_acpi_id[] = { |
669 | { "ELAN0618", 0 }, |
670 | { "ELAN061C", 0 }, |
671 | { "ELAN061D", 0 }, |
672 | + { "ELAN061E", 0 }, |
673 | + { "ELAN0620", 0 }, |
674 | + { "ELAN0621", 0 }, |
675 | { "ELAN0622", 0 }, |
676 | { "ELAN1000", 0 }, |
677 | { } |
678 | diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.c b/drivers/net/ethernet/qlogic/qed/qed_debug.c |
679 | index 68f19ca57f96..245eb02d0c4e 100644 |
680 | --- a/drivers/net/ethernet/qlogic/qed/qed_debug.c |
681 | +++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c |
682 | @@ -3039,10 +3039,10 @@ static u32 qed_grc_dump_big_ram(struct qed_hwfn *p_hwfn, |
683 | s_big_ram_defs[big_ram_id].num_of_blocks[dev_data->chip_id]; |
684 | ram_size = total_blocks * BIG_RAM_BLOCK_SIZE_DWORDS; |
685 | |
686 | - strncpy(type_name, s_big_ram_defs[big_ram_id].instance_name, |
687 | - strlen(s_big_ram_defs[big_ram_id].instance_name)); |
688 | - strncpy(mem_name, s_big_ram_defs[big_ram_id].instance_name, |
689 | - strlen(s_big_ram_defs[big_ram_id].instance_name)); |
690 | + strscpy(type_name, s_big_ram_defs[big_ram_id].instance_name, |
691 | + sizeof(type_name)); |
692 | + strscpy(mem_name, s_big_ram_defs[big_ram_id].instance_name, |
693 | + sizeof(mem_name)); |
694 | |
695 | /* Dump memory header */ |
696 | offset += qed_grc_dump_mem_hdr(p_hwfn, |
697 | diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c |
698 | index 94a356bbb6b9..61419d1b4543 100644 |
699 | --- a/drivers/net/wireless/ath/wil6210/wmi.c |
700 | +++ b/drivers/net/wireless/ath/wil6210/wmi.c |
701 | @@ -1302,8 +1302,14 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie) |
702 | }; |
703 | int rc; |
704 | u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len; |
705 | - struct wmi_set_appie_cmd *cmd = kzalloc(len, GFP_KERNEL); |
706 | + struct wmi_set_appie_cmd *cmd; |
707 | |
708 | + if (len < ie_len) { |
709 | + rc = -EINVAL; |
710 | + goto out; |
711 | + } |
712 | + |
713 | + cmd = kzalloc(len, GFP_KERNEL); |
714 | if (!cmd) { |
715 | rc = -ENOMEM; |
716 | goto out; |
717 | diff --git a/drivers/reset/core.c b/drivers/reset/core.c |
718 | index b8ae1dbd4c17..188205a55261 100644 |
719 | --- a/drivers/reset/core.c |
720 | +++ b/drivers/reset/core.c |
721 | @@ -135,11 +135,16 @@ EXPORT_SYMBOL_GPL(devm_reset_controller_register); |
722 | * @rstc: reset controller |
723 | * |
724 | * Calling this on a shared reset controller is an error. |
725 | + * |
726 | + * If rstc is NULL it is an optional reset and the function will just |
727 | + * return 0. |
728 | */ |
729 | int reset_control_reset(struct reset_control *rstc) |
730 | { |
731 | - if (WARN_ON(IS_ERR_OR_NULL(rstc)) || |
732 | - WARN_ON(rstc->shared)) |
733 | + if (!rstc) |
734 | + return 0; |
735 | + |
736 | + if (WARN_ON(IS_ERR(rstc))) |
737 | return -EINVAL; |
738 | |
739 | if (rstc->rcdev->ops->reset) |
740 | @@ -159,10 +164,16 @@ EXPORT_SYMBOL_GPL(reset_control_reset); |
741 | * |
742 | * For shared reset controls a driver cannot expect the hw's registers and |
743 | * internal state to be reset, but must be prepared for this to happen. |
744 | + * |
745 | + * If rstc is NULL it is an optional reset and the function will just |
746 | + * return 0. |
747 | */ |
748 | int reset_control_assert(struct reset_control *rstc) |
749 | { |
750 | - if (WARN_ON(IS_ERR_OR_NULL(rstc))) |
751 | + if (!rstc) |
752 | + return 0; |
753 | + |
754 | + if (WARN_ON(IS_ERR(rstc))) |
755 | return -EINVAL; |
756 | |
757 | if (!rstc->rcdev->ops->assert) |
758 | @@ -185,10 +196,16 @@ EXPORT_SYMBOL_GPL(reset_control_assert); |
759 | * @rstc: reset controller |
760 | * |
761 | * After calling this function, the reset is guaranteed to be deasserted. |
762 | + * |
763 | + * If rstc is NULL it is an optional reset and the function will just |
764 | + * return 0. |
765 | */ |
766 | int reset_control_deassert(struct reset_control *rstc) |
767 | { |
768 | - if (WARN_ON(IS_ERR_OR_NULL(rstc))) |
769 | + if (!rstc) |
770 | + return 0; |
771 | + |
772 | + if (WARN_ON(IS_ERR(rstc))) |
773 | return -EINVAL; |
774 | |
775 | if (!rstc->rcdev->ops->deassert) |
776 | @@ -206,12 +223,15 @@ EXPORT_SYMBOL_GPL(reset_control_deassert); |
777 | /** |
778 | * reset_control_status - returns a negative errno if not supported, a |
779 | * positive value if the reset line is asserted, or zero if the reset |
780 | - * line is not asserted. |
781 | + * line is not asserted or if the desc is NULL (optional reset). |
782 | * @rstc: reset controller |
783 | */ |
784 | int reset_control_status(struct reset_control *rstc) |
785 | { |
786 | - if (WARN_ON(IS_ERR_OR_NULL(rstc))) |
787 | + if (!rstc) |
788 | + return 0; |
789 | + |
790 | + if (WARN_ON(IS_ERR(rstc))) |
791 | return -EINVAL; |
792 | |
793 | if (rstc->rcdev->ops->status) |
794 | @@ -221,7 +241,7 @@ int reset_control_status(struct reset_control *rstc) |
795 | } |
796 | EXPORT_SYMBOL_GPL(reset_control_status); |
797 | |
798 | -static struct reset_control *__reset_control_get( |
799 | +static struct reset_control *__reset_control_get_internal( |
800 | struct reset_controller_dev *rcdev, |
801 | unsigned int index, int shared) |
802 | { |
803 | @@ -254,7 +274,7 @@ static struct reset_control *__reset_control_get( |
804 | return rstc; |
805 | } |
806 | |
807 | -static void __reset_control_put(struct reset_control *rstc) |
808 | +static void __reset_control_put_internal(struct reset_control *rstc) |
809 | { |
810 | lockdep_assert_held(&reset_list_mutex); |
811 | |
812 | @@ -268,7 +288,8 @@ static void __reset_control_put(struct reset_control *rstc) |
813 | } |
814 | |
815 | struct reset_control *__of_reset_control_get(struct device_node *node, |
816 | - const char *id, int index, int shared) |
817 | + const char *id, int index, bool shared, |
818 | + bool optional) |
819 | { |
820 | struct reset_control *rstc; |
821 | struct reset_controller_dev *r, *rcdev; |
822 | @@ -282,14 +303,18 @@ struct reset_control *__of_reset_control_get(struct device_node *node, |
823 | if (id) { |
824 | index = of_property_match_string(node, |
825 | "reset-names", id); |
826 | + if (index == -EILSEQ) |
827 | + return ERR_PTR(index); |
828 | if (index < 0) |
829 | - return ERR_PTR(-ENOENT); |
830 | + return optional ? NULL : ERR_PTR(-ENOENT); |
831 | } |
832 | |
833 | ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", |
834 | index, &args); |
835 | - if (ret) |
836 | + if (ret == -EINVAL) |
837 | return ERR_PTR(ret); |
838 | + if (ret) |
839 | + return optional ? NULL : ERR_PTR(ret); |
840 | |
841 | mutex_lock(&reset_list_mutex); |
842 | rcdev = NULL; |
843 | @@ -318,7 +343,7 @@ struct reset_control *__of_reset_control_get(struct device_node *node, |
844 | } |
845 | |
846 | /* reset_list_mutex also protects the rcdev's reset_control list */ |
847 | - rstc = __reset_control_get(rcdev, rstc_id, shared); |
848 | + rstc = __reset_control_get_internal(rcdev, rstc_id, shared); |
849 | |
850 | mutex_unlock(&reset_list_mutex); |
851 | |
852 | @@ -326,6 +351,17 @@ struct reset_control *__of_reset_control_get(struct device_node *node, |
853 | } |
854 | EXPORT_SYMBOL_GPL(__of_reset_control_get); |
855 | |
856 | +struct reset_control *__reset_control_get(struct device *dev, const char *id, |
857 | + int index, bool shared, bool optional) |
858 | +{ |
859 | + if (dev->of_node) |
860 | + return __of_reset_control_get(dev->of_node, id, index, shared, |
861 | + optional); |
862 | + |
863 | + return optional ? NULL : ERR_PTR(-EINVAL); |
864 | +} |
865 | +EXPORT_SYMBOL_GPL(__reset_control_get); |
866 | + |
867 | /** |
868 | * reset_control_put - free the reset controller |
869 | * @rstc: reset controller |
870 | @@ -333,11 +369,11 @@ EXPORT_SYMBOL_GPL(__of_reset_control_get); |
871 | |
872 | void reset_control_put(struct reset_control *rstc) |
873 | { |
874 | - if (IS_ERR(rstc)) |
875 | + if (IS_ERR_OR_NULL(rstc)) |
876 | return; |
877 | |
878 | mutex_lock(&reset_list_mutex); |
879 | - __reset_control_put(rstc); |
880 | + __reset_control_put_internal(rstc); |
881 | mutex_unlock(&reset_list_mutex); |
882 | } |
883 | EXPORT_SYMBOL_GPL(reset_control_put); |
884 | @@ -348,7 +384,8 @@ static void devm_reset_control_release(struct device *dev, void *res) |
885 | } |
886 | |
887 | struct reset_control *__devm_reset_control_get(struct device *dev, |
888 | - const char *id, int index, int shared) |
889 | + const char *id, int index, bool shared, |
890 | + bool optional) |
891 | { |
892 | struct reset_control **ptr, *rstc; |
893 | |
894 | @@ -357,8 +394,7 @@ struct reset_control *__devm_reset_control_get(struct device *dev, |
895 | if (!ptr) |
896 | return ERR_PTR(-ENOMEM); |
897 | |
898 | - rstc = __of_reset_control_get(dev ? dev->of_node : NULL, |
899 | - id, index, shared); |
900 | + rstc = __reset_control_get(dev, id, index, shared, optional); |
901 | if (!IS_ERR(rstc)) { |
902 | *ptr = rstc; |
903 | devres_add(dev, ptr); |
904 | @@ -374,17 +410,18 @@ EXPORT_SYMBOL_GPL(__devm_reset_control_get); |
905 | * device_reset - find reset controller associated with the device |
906 | * and perform reset |
907 | * @dev: device to be reset by the controller |
908 | + * @optional: whether it is optional to reset the device |
909 | * |
910 | - * Convenience wrapper for reset_control_get() and reset_control_reset(). |
911 | + * Convenience wrapper for __reset_control_get() and reset_control_reset(). |
912 | * This is useful for the common case of devices with single, dedicated reset |
913 | * lines. |
914 | */ |
915 | -int device_reset(struct device *dev) |
916 | +int __device_reset(struct device *dev, bool optional) |
917 | { |
918 | struct reset_control *rstc; |
919 | int ret; |
920 | |
921 | - rstc = reset_control_get(dev, NULL); |
922 | + rstc = __reset_control_get(dev, NULL, 0, 0, optional); |
923 | if (IS_ERR(rstc)) |
924 | return PTR_ERR(rstc); |
925 | |
926 | @@ -394,4 +431,4 @@ int device_reset(struct device *dev) |
927 | |
928 | return ret; |
929 | } |
930 | -EXPORT_SYMBOL_GPL(device_reset); |
931 | +EXPORT_SYMBOL_GPL(__device_reset); |
932 | diff --git a/drivers/scsi/bfa/bfa_fcbuild.c b/drivers/scsi/bfa/bfa_fcbuild.c |
933 | index b8dadc9cc993..d3b00a475aeb 100644 |
934 | --- a/drivers/scsi/bfa/bfa_fcbuild.c |
935 | +++ b/drivers/scsi/bfa/bfa_fcbuild.c |
936 | @@ -1250,8 +1250,8 @@ fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, |
937 | memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s)); |
938 | |
939 | rspnid->dap = s_id; |
940 | - rspnid->spn_len = (u8) strlen((char *)name); |
941 | - strncpy((char *)rspnid->spn, (char *)name, rspnid->spn_len); |
942 | + strlcpy(rspnid->spn, name, sizeof(rspnid->spn)); |
943 | + rspnid->spn_len = (u8) strlen(rspnid->spn); |
944 | |
945 | return sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s); |
946 | } |
947 | @@ -1271,8 +1271,8 @@ fc_rsnn_nn_build(struct fchs_s *fchs, void *pyld, u32 s_id, |
948 | memset(rsnn_nn, 0, sizeof(struct fcgs_rsnn_nn_req_s)); |
949 | |
950 | rsnn_nn->node_name = node_name; |
951 | - rsnn_nn->snn_len = (u8) strlen((char *)name); |
952 | - strncpy((char *)rsnn_nn->snn, (char *)name, rsnn_nn->snn_len); |
953 | + strlcpy(rsnn_nn->snn, name, sizeof(rsnn_nn->snn)); |
954 | + rsnn_nn->snn_len = (u8) strlen(rsnn_nn->snn); |
955 | |
956 | return sizeof(struct fcgs_rsnn_nn_req_s) + sizeof(struct ct_hdr_s); |
957 | } |
958 | diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c |
959 | index 1e7e139d71ea..f602de047087 100644 |
960 | --- a/drivers/scsi/bfa/bfa_fcs.c |
961 | +++ b/drivers/scsi/bfa/bfa_fcs.c |
962 | @@ -832,23 +832,23 @@ bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric) |
963 | bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model); |
964 | |
965 | /* Model name/number */ |
966 | - strncpy((char *)&port_cfg->sym_name, model, |
967 | - BFA_FCS_PORT_SYMBNAME_MODEL_SZ); |
968 | - strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, |
969 | - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); |
970 | + strlcpy(port_cfg->sym_name.symname, model, |
971 | + BFA_SYMNAME_MAXLEN); |
972 | + strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR, |
973 | + BFA_SYMNAME_MAXLEN); |
974 | |
975 | /* Driver Version */ |
976 | - strncat((char *)&port_cfg->sym_name, (char *)driver_info->version, |
977 | - BFA_FCS_PORT_SYMBNAME_VERSION_SZ); |
978 | - strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, |
979 | - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); |
980 | + strlcat(port_cfg->sym_name.symname, driver_info->version, |
981 | + BFA_SYMNAME_MAXLEN); |
982 | + strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR, |
983 | + BFA_SYMNAME_MAXLEN); |
984 | |
985 | /* Host machine name */ |
986 | - strncat((char *)&port_cfg->sym_name, |
987 | - (char *)driver_info->host_machine_name, |
988 | - BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ); |
989 | - strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, |
990 | - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); |
991 | + strlcat(port_cfg->sym_name.symname, |
992 | + driver_info->host_machine_name, |
993 | + BFA_SYMNAME_MAXLEN); |
994 | + strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR, |
995 | + BFA_SYMNAME_MAXLEN); |
996 | |
997 | /* |
998 | * Host OS Info : |
999 | @@ -856,24 +856,24 @@ bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric) |
1000 | * OS name string and instead copy the entire OS info string (64 bytes). |
1001 | */ |
1002 | if (driver_info->host_os_patch[0] == '\0') { |
1003 | - strncat((char *)&port_cfg->sym_name, |
1004 | - (char *)driver_info->host_os_name, |
1005 | - BFA_FCS_OS_STR_LEN); |
1006 | - strncat((char *)&port_cfg->sym_name, |
1007 | + strlcat(port_cfg->sym_name.symname, |
1008 | + driver_info->host_os_name, |
1009 | + BFA_SYMNAME_MAXLEN); |
1010 | + strlcat(port_cfg->sym_name.symname, |
1011 | BFA_FCS_PORT_SYMBNAME_SEPARATOR, |
1012 | - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); |
1013 | + BFA_SYMNAME_MAXLEN); |
1014 | } else { |
1015 | - strncat((char *)&port_cfg->sym_name, |
1016 | - (char *)driver_info->host_os_name, |
1017 | - BFA_FCS_PORT_SYMBNAME_OSINFO_SZ); |
1018 | - strncat((char *)&port_cfg->sym_name, |
1019 | + strlcat(port_cfg->sym_name.symname, |
1020 | + driver_info->host_os_name, |
1021 | + BFA_SYMNAME_MAXLEN); |
1022 | + strlcat(port_cfg->sym_name.symname, |
1023 | BFA_FCS_PORT_SYMBNAME_SEPARATOR, |
1024 | - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); |
1025 | + BFA_SYMNAME_MAXLEN); |
1026 | |
1027 | /* Append host OS Patch Info */ |
1028 | - strncat((char *)&port_cfg->sym_name, |
1029 | - (char *)driver_info->host_os_patch, |
1030 | - BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ); |
1031 | + strlcat(port_cfg->sym_name.symname, |
1032 | + driver_info->host_os_patch, |
1033 | + BFA_SYMNAME_MAXLEN); |
1034 | } |
1035 | |
1036 | /* null terminate */ |
1037 | @@ -893,26 +893,26 @@ bfa_fcs_fabric_nsymb_init(struct bfa_fcs_fabric_s *fabric) |
1038 | bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model); |
1039 | |
1040 | /* Model name/number */ |
1041 | - strncpy((char *)&port_cfg->node_sym_name, model, |
1042 | - BFA_FCS_PORT_SYMBNAME_MODEL_SZ); |
1043 | - strncat((char *)&port_cfg->node_sym_name, |
1044 | + strlcpy(port_cfg->node_sym_name.symname, model, |
1045 | + BFA_SYMNAME_MAXLEN); |
1046 | + strlcat(port_cfg->node_sym_name.symname, |
1047 | BFA_FCS_PORT_SYMBNAME_SEPARATOR, |
1048 | - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); |
1049 | + BFA_SYMNAME_MAXLEN); |
1050 | |
1051 | /* Driver Version */ |
1052 | - strncat((char *)&port_cfg->node_sym_name, (char *)driver_info->version, |
1053 | - BFA_FCS_PORT_SYMBNAME_VERSION_SZ); |
1054 | - strncat((char *)&port_cfg->node_sym_name, |
1055 | + strlcat(port_cfg->node_sym_name.symname, (char *)driver_info->version, |
1056 | + BFA_SYMNAME_MAXLEN); |
1057 | + strlcat(port_cfg->node_sym_name.symname, |
1058 | BFA_FCS_PORT_SYMBNAME_SEPARATOR, |
1059 | - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); |
1060 | + BFA_SYMNAME_MAXLEN); |
1061 | |
1062 | /* Host machine name */ |
1063 | - strncat((char *)&port_cfg->node_sym_name, |
1064 | - (char *)driver_info->host_machine_name, |
1065 | - BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ); |
1066 | - strncat((char *)&port_cfg->node_sym_name, |
1067 | + strlcat(port_cfg->node_sym_name.symname, |
1068 | + driver_info->host_machine_name, |
1069 | + BFA_SYMNAME_MAXLEN); |
1070 | + strlcat(port_cfg->node_sym_name.symname, |
1071 | BFA_FCS_PORT_SYMBNAME_SEPARATOR, |
1072 | - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); |
1073 | + BFA_SYMNAME_MAXLEN); |
1074 | |
1075 | /* null terminate */ |
1076 | port_cfg->node_sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0; |
1077 | diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c |
1078 | index 4ddda72f60e6..eb87949b00c1 100644 |
1079 | --- a/drivers/scsi/bfa/bfa_fcs_lport.c |
1080 | +++ b/drivers/scsi/bfa/bfa_fcs_lport.c |
1081 | @@ -2631,10 +2631,10 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, |
1082 | bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, |
1083 | hba_attr->fw_version); |
1084 | |
1085 | - strncpy(hba_attr->driver_version, (char *)driver_info->version, |
1086 | + strlcpy(hba_attr->driver_version, (char *)driver_info->version, |
1087 | sizeof(hba_attr->driver_version)); |
1088 | |
1089 | - strncpy(hba_attr->os_name, driver_info->host_os_name, |
1090 | + strlcpy(hba_attr->os_name, driver_info->host_os_name, |
1091 | sizeof(hba_attr->os_name)); |
1092 | |
1093 | /* |
1094 | @@ -2642,23 +2642,23 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, |
1095 | * to the os name along with a separator |
1096 | */ |
1097 | if (driver_info->host_os_patch[0] != '\0') { |
1098 | - strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, |
1099 | - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); |
1100 | - strncat(hba_attr->os_name, driver_info->host_os_patch, |
1101 | - sizeof(driver_info->host_os_patch)); |
1102 | + strlcat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, |
1103 | + sizeof(hba_attr->os_name)); |
1104 | + strlcat(hba_attr->os_name, driver_info->host_os_patch, |
1105 | + sizeof(hba_attr->os_name)); |
1106 | } |
1107 | |
1108 | /* Retrieve the max frame size from the port attr */ |
1109 | bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); |
1110 | hba_attr->max_ct_pyld = fcs_port_attr.max_frm_size; |
1111 | |
1112 | - strncpy(hba_attr->node_sym_name.symname, |
1113 | + strlcpy(hba_attr->node_sym_name.symname, |
1114 | port->port_cfg.node_sym_name.symname, BFA_SYMNAME_MAXLEN); |
1115 | strcpy(hba_attr->vendor_info, "QLogic"); |
1116 | hba_attr->num_ports = |
1117 | cpu_to_be32(bfa_ioc_get_nports(&port->fcs->bfa->ioc)); |
1118 | hba_attr->fabric_name = port->fabric->lps->pr_nwwn; |
1119 | - strncpy(hba_attr->bios_ver, hba_attr->option_rom_ver, BFA_VERSION_LEN); |
1120 | + strlcpy(hba_attr->bios_ver, hba_attr->option_rom_ver, BFA_VERSION_LEN); |
1121 | |
1122 | } |
1123 | |
1124 | @@ -2725,20 +2725,20 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, |
1125 | /* |
1126 | * OS device Name |
1127 | */ |
1128 | - strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name, |
1129 | + strlcpy(port_attr->os_device_name, driver_info->os_device_name, |
1130 | sizeof(port_attr->os_device_name)); |
1131 | |
1132 | /* |
1133 | * Host name |
1134 | */ |
1135 | - strncpy(port_attr->host_name, (char *)driver_info->host_machine_name, |
1136 | + strlcpy(port_attr->host_name, driver_info->host_machine_name, |
1137 | sizeof(port_attr->host_name)); |
1138 | |
1139 | port_attr->node_name = bfa_fcs_lport_get_nwwn(port); |
1140 | port_attr->port_name = bfa_fcs_lport_get_pwwn(port); |
1141 | |
1142 | - strncpy(port_attr->port_sym_name.symname, |
1143 | - (char *)&bfa_fcs_lport_get_psym_name(port), BFA_SYMNAME_MAXLEN); |
1144 | + strlcpy(port_attr->port_sym_name.symname, |
1145 | + bfa_fcs_lport_get_psym_name(port).symname, BFA_SYMNAME_MAXLEN); |
1146 | bfa_fcs_lport_get_attr(port, &lport_attr); |
1147 | port_attr->port_type = cpu_to_be32(lport_attr.port_type); |
1148 | port_attr->scos = pport_attr.cos_supported; |
1149 | @@ -3218,7 +3218,7 @@ bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp, |
1150 | rsp_str[gmal_entry->len-1] = 0; |
1151 | |
1152 | /* copy IP Address to fabric */ |
1153 | - strncpy(bfa_fcs_lport_get_fabric_ipaddr(port), |
1154 | + strlcpy(bfa_fcs_lport_get_fabric_ipaddr(port), |
1155 | gmal_entry->ip_addr, |
1156 | BFA_FCS_FABRIC_IPADDR_SZ); |
1157 | break; |
1158 | @@ -4656,21 +4656,13 @@ bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) |
1159 | * to that of the base port. |
1160 | */ |
1161 | |
1162 | - strncpy((char *)psymbl, |
1163 | - (char *) & |
1164 | - (bfa_fcs_lport_get_psym_name |
1165 | + strlcpy(symbl, |
1166 | + (char *)&(bfa_fcs_lport_get_psym_name |
1167 | (bfa_fcs_get_base_port(port->fcs))), |
1168 | - strlen((char *) & |
1169 | - bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port |
1170 | - (port->fcs)))); |
1171 | - |
1172 | - /* Ensure we have a null terminating string. */ |
1173 | - ((char *)psymbl)[strlen((char *) & |
1174 | - bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port |
1175 | - (port->fcs)))] = 0; |
1176 | - strncat((char *)psymbl, |
1177 | - (char *) &(bfa_fcs_lport_get_psym_name(port)), |
1178 | - strlen((char *) &bfa_fcs_lport_get_psym_name(port))); |
1179 | + sizeof(symbl)); |
1180 | + |
1181 | + strlcat(symbl, (char *)&(bfa_fcs_lport_get_psym_name(port)), |
1182 | + sizeof(symbl)); |
1183 | } else { |
1184 | psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port)); |
1185 | } |
1186 | @@ -5162,7 +5154,6 @@ bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced) |
1187 | struct fchs_s fchs; |
1188 | struct bfa_fcxp_s *fcxp; |
1189 | u8 symbl[256]; |
1190 | - u8 *psymbl = &symbl[0]; |
1191 | int len; |
1192 | |
1193 | /* Avoid sending RSPN in the following states. */ |
1194 | @@ -5192,22 +5183,17 @@ bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced) |
1195 | * For Vports, we append the vport's port symbolic name |
1196 | * to that of the base port. |
1197 | */ |
1198 | - strncpy((char *)psymbl, (char *)&(bfa_fcs_lport_get_psym_name |
1199 | + strlcpy(symbl, (char *)&(bfa_fcs_lport_get_psym_name |
1200 | (bfa_fcs_get_base_port(port->fcs))), |
1201 | - strlen((char *)&bfa_fcs_lport_get_psym_name( |
1202 | - bfa_fcs_get_base_port(port->fcs)))); |
1203 | - |
1204 | - /* Ensure we have a null terminating string. */ |
1205 | - ((char *)psymbl)[strlen((char *)&bfa_fcs_lport_get_psym_name( |
1206 | - bfa_fcs_get_base_port(port->fcs)))] = 0; |
1207 | + sizeof(symbl)); |
1208 | |
1209 | - strncat((char *)psymbl, |
1210 | + strlcat(symbl, |
1211 | (char *)&(bfa_fcs_lport_get_psym_name(port)), |
1212 | - strlen((char *)&bfa_fcs_lport_get_psym_name(port))); |
1213 | + sizeof(symbl)); |
1214 | } |
1215 | |
1216 | len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), |
1217 | - bfa_fcs_lport_get_fcid(port), 0, psymbl); |
1218 | + bfa_fcs_lport_get_fcid(port), 0, symbl); |
1219 | |
1220 | bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, |
1221 | FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); |
1222 | diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c |
1223 | index a1ada4a31c97..16750416d3c0 100644 |
1224 | --- a/drivers/scsi/bfa/bfa_ioc.c |
1225 | +++ b/drivers/scsi/bfa/bfa_ioc.c |
1226 | @@ -2803,7 +2803,7 @@ void |
1227 | bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer) |
1228 | { |
1229 | memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN); |
1230 | - strncpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); |
1231 | + strlcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); |
1232 | } |
1233 | |
1234 | void |
1235 | diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c |
1236 | index 12de292175ef..225883d2aeef 100644 |
1237 | --- a/drivers/scsi/bfa/bfa_svc.c |
1238 | +++ b/drivers/scsi/bfa/bfa_svc.c |
1239 | @@ -366,8 +366,8 @@ bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid, |
1240 | lp.eid = event; |
1241 | lp.log_type = BFA_PL_LOG_TYPE_STRING; |
1242 | lp.misc = misc; |
1243 | - strncpy(lp.log_entry.string_log, log_str, |
1244 | - BFA_PL_STRING_LOG_SZ - 1); |
1245 | + strlcpy(lp.log_entry.string_log, log_str, |
1246 | + BFA_PL_STRING_LOG_SZ); |
1247 | lp.log_entry.string_log[BFA_PL_STRING_LOG_SZ - 1] = '\0'; |
1248 | bfa_plog_add(plog, &lp); |
1249 | } |
1250 | diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c |
1251 | index e70410beb83a..389f8ef0b095 100644 |
1252 | --- a/drivers/scsi/bfa/bfad.c |
1253 | +++ b/drivers/scsi/bfa/bfad.c |
1254 | @@ -983,20 +983,20 @@ bfad_start_ops(struct bfad_s *bfad) { |
1255 | |
1256 | /* Fill the driver_info info to fcs*/ |
1257 | memset(&driver_info, 0, sizeof(driver_info)); |
1258 | - strncpy(driver_info.version, BFAD_DRIVER_VERSION, |
1259 | - sizeof(driver_info.version) - 1); |
1260 | + strlcpy(driver_info.version, BFAD_DRIVER_VERSION, |
1261 | + sizeof(driver_info.version)); |
1262 | if (host_name) |
1263 | - strncpy(driver_info.host_machine_name, host_name, |
1264 | - sizeof(driver_info.host_machine_name) - 1); |
1265 | + strlcpy(driver_info.host_machine_name, host_name, |
1266 | + sizeof(driver_info.host_machine_name)); |
1267 | if (os_name) |
1268 | - strncpy(driver_info.host_os_name, os_name, |
1269 | - sizeof(driver_info.host_os_name) - 1); |
1270 | + strlcpy(driver_info.host_os_name, os_name, |
1271 | + sizeof(driver_info.host_os_name)); |
1272 | if (os_patch) |
1273 | - strncpy(driver_info.host_os_patch, os_patch, |
1274 | - sizeof(driver_info.host_os_patch) - 1); |
1275 | + strlcpy(driver_info.host_os_patch, os_patch, |
1276 | + sizeof(driver_info.host_os_patch)); |
1277 | |
1278 | - strncpy(driver_info.os_device_name, bfad->pci_name, |
1279 | - sizeof(driver_info.os_device_name) - 1); |
1280 | + strlcpy(driver_info.os_device_name, bfad->pci_name, |
1281 | + sizeof(driver_info.os_device_name)); |
1282 | |
1283 | /* FCS driver info init */ |
1284 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1285 | diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c |
1286 | index 13db3b7bc873..d0a504af5b4f 100644 |
1287 | --- a/drivers/scsi/bfa/bfad_attr.c |
1288 | +++ b/drivers/scsi/bfa/bfad_attr.c |
1289 | @@ -843,7 +843,7 @@ bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr, |
1290 | char symname[BFA_SYMNAME_MAXLEN]; |
1291 | |
1292 | bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr); |
1293 | - strncpy(symname, port_attr.port_cfg.sym_name.symname, |
1294 | + strlcpy(symname, port_attr.port_cfg.sym_name.symname, |
1295 | BFA_SYMNAME_MAXLEN); |
1296 | return snprintf(buf, PAGE_SIZE, "%s\n", symname); |
1297 | } |
1298 | diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c |
1299 | index d1ad0208dfe7..a3bd23685824 100644 |
1300 | --- a/drivers/scsi/bfa/bfad_bsg.c |
1301 | +++ b/drivers/scsi/bfa/bfad_bsg.c |
1302 | @@ -127,7 +127,7 @@ bfad_iocmd_ioc_get_attr(struct bfad_s *bfad, void *cmd) |
1303 | |
1304 | /* fill in driver attr info */ |
1305 | strcpy(iocmd->ioc_attr.driver_attr.driver, BFAD_DRIVER_NAME); |
1306 | - strncpy(iocmd->ioc_attr.driver_attr.driver_ver, |
1307 | + strlcpy(iocmd->ioc_attr.driver_attr.driver_ver, |
1308 | BFAD_DRIVER_VERSION, BFA_VERSION_LEN); |
1309 | strcpy(iocmd->ioc_attr.driver_attr.fw_ver, |
1310 | iocmd->ioc_attr.adapter_attr.fw_ver); |
1311 | @@ -315,9 +315,9 @@ bfad_iocmd_port_get_attr(struct bfad_s *bfad, void *cmd) |
1312 | iocmd->attr.port_type = port_attr.port_type; |
1313 | iocmd->attr.loopback = port_attr.loopback; |
1314 | iocmd->attr.authfail = port_attr.authfail; |
1315 | - strncpy(iocmd->attr.port_symname.symname, |
1316 | + strlcpy(iocmd->attr.port_symname.symname, |
1317 | port_attr.port_cfg.sym_name.symname, |
1318 | - sizeof(port_attr.port_cfg.sym_name.symname)); |
1319 | + sizeof(iocmd->attr.port_symname.symname)); |
1320 | |
1321 | iocmd->status = BFA_STATUS_OK; |
1322 | return 0; |
1323 | diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c |
1324 | index c00b2ff72b55..be5ee2d37815 100644 |
1325 | --- a/drivers/scsi/csiostor/csio_lnode.c |
1326 | +++ b/drivers/scsi/csiostor/csio_lnode.c |
1327 | @@ -238,14 +238,23 @@ csio_osname(uint8_t *buf, size_t buf_len) |
1328 | } |
1329 | |
1330 | static inline void |
1331 | -csio_append_attrib(uint8_t **ptr, uint16_t type, uint8_t *val, uint16_t len) |
1332 | +csio_append_attrib(uint8_t **ptr, uint16_t type, void *val, size_t val_len) |
1333 | { |
1334 | + uint16_t len; |
1335 | struct fc_fdmi_attr_entry *ae = (struct fc_fdmi_attr_entry *)*ptr; |
1336 | + |
1337 | + if (WARN_ON(val_len > U16_MAX)) |
1338 | + return; |
1339 | + |
1340 | + len = val_len; |
1341 | + |
1342 | ae->type = htons(type); |
1343 | len += 4; /* includes attribute type and length */ |
1344 | len = (len + 3) & ~3; /* should be multiple of 4 bytes */ |
1345 | ae->len = htons(len); |
1346 | - memcpy(ae->value, val, len); |
1347 | + memcpy(ae->value, val, val_len); |
1348 | + if (len > val_len) |
1349 | + memset(ae->value + val_len, 0, len - val_len); |
1350 | *ptr += len; |
1351 | } |
1352 | |
1353 | @@ -335,7 +344,7 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req) |
1354 | numattrs++; |
1355 | val = htonl(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT); |
1356 | csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_SUPPORTEDSPEED, |
1357 | - (uint8_t *)&val, |
1358 | + &val, |
1359 | FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN); |
1360 | numattrs++; |
1361 | |
1362 | @@ -346,23 +355,22 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req) |
1363 | else |
1364 | val = htonl(CSIO_HBA_PORTSPEED_UNKNOWN); |
1365 | csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED, |
1366 | - (uint8_t *)&val, |
1367 | - FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN); |
1368 | + &val, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN); |
1369 | numattrs++; |
1370 | |
1371 | mfs = ln->ln_sparm.csp.sp_bb_data; |
1372 | csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_MAXFRAMESIZE, |
1373 | - (uint8_t *)&mfs, FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN); |
1374 | + &mfs, sizeof(mfs)); |
1375 | numattrs++; |
1376 | |
1377 | strcpy(buf, "csiostor"); |
1378 | csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_OSDEVICENAME, buf, |
1379 | - (uint16_t)strlen(buf)); |
1380 | + strlen(buf)); |
1381 | numattrs++; |
1382 | |
1383 | if (!csio_hostname(buf, sizeof(buf))) { |
1384 | csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_HOSTNAME, |
1385 | - buf, (uint16_t)strlen(buf)); |
1386 | + buf, strlen(buf)); |
1387 | numattrs++; |
1388 | } |
1389 | attrib_blk->numattrs = htonl(numattrs); |
1390 | @@ -444,33 +452,32 @@ csio_ln_fdmi_dprt_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req) |
1391 | |
1392 | strcpy(buf, "Chelsio Communications"); |
1393 | csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MANUFACTURER, buf, |
1394 | - (uint16_t)strlen(buf)); |
1395 | + strlen(buf)); |
1396 | numattrs++; |
1397 | csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_SERIALNUMBER, |
1398 | - hw->vpd.sn, (uint16_t)sizeof(hw->vpd.sn)); |
1399 | + hw->vpd.sn, sizeof(hw->vpd.sn)); |
1400 | numattrs++; |
1401 | csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODEL, hw->vpd.id, |
1402 | - (uint16_t)sizeof(hw->vpd.id)); |
1403 | + sizeof(hw->vpd.id)); |
1404 | numattrs++; |
1405 | csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODELDESCRIPTION, |
1406 | - hw->model_desc, (uint16_t)strlen(hw->model_desc)); |
1407 | + hw->model_desc, strlen(hw->model_desc)); |
1408 | numattrs++; |
1409 | csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_HARDWAREVERSION, |
1410 | - hw->hw_ver, (uint16_t)sizeof(hw->hw_ver)); |
1411 | + hw->hw_ver, sizeof(hw->hw_ver)); |
1412 | numattrs++; |
1413 | csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_FIRMWAREVERSION, |
1414 | - hw->fwrev_str, (uint16_t)strlen(hw->fwrev_str)); |
1415 | + hw->fwrev_str, strlen(hw->fwrev_str)); |
1416 | numattrs++; |
1417 | |
1418 | if (!csio_osname(buf, sizeof(buf))) { |
1419 | csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_OSNAMEVERSION, |
1420 | - buf, (uint16_t)strlen(buf)); |
1421 | + buf, strlen(buf)); |
1422 | numattrs++; |
1423 | } |
1424 | |
1425 | csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MAXCTPAYLOAD, |
1426 | - (uint8_t *)&maxpayload, |
1427 | - FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN); |
1428 | + &maxpayload, FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN); |
1429 | len = (uint32_t)(pld - (uint8_t *)cmd); |
1430 | numattrs++; |
1431 | attrib_blk->numattrs = htonl(numattrs); |
1432 | @@ -1794,6 +1801,8 @@ csio_ln_mgmt_submit_req(struct csio_ioreq *io_req, |
1433 | struct csio_mgmtm *mgmtm = csio_hw_to_mgmtm(hw); |
1434 | int rv; |
1435 | |
1436 | + BUG_ON(pld_len > pld->len); |
1437 | + |
1438 | io_req->io_cbfn = io_cbfn; /* Upper layer callback handler */ |
1439 | io_req->fw_handle = (uintptr_t) (io_req); |
1440 | io_req->eq_idx = mgmtm->eq_idx; |
1441 | diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c |
1442 | index 43d4b30cbf65..282ea00d0f87 100644 |
1443 | --- a/drivers/scsi/scsi_devinfo.c |
1444 | +++ b/drivers/scsi/scsi_devinfo.c |
1445 | @@ -33,7 +33,6 @@ struct scsi_dev_info_list_table { |
1446 | }; |
1447 | |
1448 | |
1449 | -static const char spaces[] = " "; /* 16 of them */ |
1450 | static unsigned scsi_default_dev_flags; |
1451 | static LIST_HEAD(scsi_dev_info_list); |
1452 | static char scsi_dev_flags[256]; |
1453 | @@ -298,20 +297,13 @@ static void scsi_strcpy_devinfo(char *name, char *to, size_t to_length, |
1454 | size_t from_length; |
1455 | |
1456 | from_length = strlen(from); |
1457 | - strncpy(to, from, min(to_length, from_length)); |
1458 | - if (from_length < to_length) { |
1459 | - if (compatible) { |
1460 | - /* |
1461 | - * NUL terminate the string if it is short. |
1462 | - */ |
1463 | - to[from_length] = '\0'; |
1464 | - } else { |
1465 | - /* |
1466 | - * space pad the string if it is short. |
1467 | - */ |
1468 | - strncpy(&to[from_length], spaces, |
1469 | - to_length - from_length); |
1470 | - } |
1471 | + /* this zero-pads the destination */ |
1472 | + strncpy(to, from, to_length); |
1473 | + if (from_length < to_length && !compatible) { |
1474 | + /* |
1475 | + * space pad the string if it is short. |
1476 | + */ |
1477 | + memset(&to[from_length], ' ', to_length - from_length); |
1478 | } |
1479 | if (from_length > to_length) |
1480 | printk(KERN_WARNING "%s: %s string '%s' is too long\n", |
1481 | diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c |
1482 | index 9e63bdf2afe7..4e233f3e7215 100644 |
1483 | --- a/drivers/staging/rts5208/sd.c |
1484 | +++ b/drivers/staging/rts5208/sd.c |
1485 | @@ -4110,12 +4110,6 @@ RTY_SEND_CMD: |
1486 | rtsx_trace(chip); |
1487 | return STATUS_FAIL; |
1488 | } |
1489 | - |
1490 | - } else if (rsp_type == SD_RSP_TYPE_R0) { |
1491 | - if ((ptr[3] & 0x1E) != 0x03) { |
1492 | - rtsx_trace(chip); |
1493 | - return STATUS_FAIL; |
1494 | - } |
1495 | } |
1496 | } |
1497 | } |
1498 | diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c |
1499 | index 2db68dfe497d..c448225ef5ca 100644 |
1500 | --- a/drivers/tty/serial/kgdboc.c |
1501 | +++ b/drivers/tty/serial/kgdboc.c |
1502 | @@ -131,24 +131,6 @@ static void kgdboc_unregister_kbd(void) |
1503 | #define kgdboc_restore_input() |
1504 | #endif /* ! CONFIG_KDB_KEYBOARD */ |
1505 | |
1506 | -static int kgdboc_option_setup(char *opt) |
1507 | -{ |
1508 | - if (!opt) { |
1509 | - pr_err("kgdboc: config string not provided\n"); |
1510 | - return -EINVAL; |
1511 | - } |
1512 | - |
1513 | - if (strlen(opt) >= MAX_CONFIG_LEN) { |
1514 | - printk(KERN_ERR "kgdboc: config string too long\n"); |
1515 | - return -ENOSPC; |
1516 | - } |
1517 | - strcpy(config, opt); |
1518 | - |
1519 | - return 0; |
1520 | -} |
1521 | - |
1522 | -__setup("kgdboc=", kgdboc_option_setup); |
1523 | - |
1524 | static void cleanup_kgdboc(void) |
1525 | { |
1526 | if (kgdb_unregister_nmi_console()) |
1527 | @@ -162,15 +144,13 @@ static int configure_kgdboc(void) |
1528 | { |
1529 | struct tty_driver *p; |
1530 | int tty_line = 0; |
1531 | - int err; |
1532 | + int err = -ENODEV; |
1533 | char *cptr = config; |
1534 | struct console *cons; |
1535 | |
1536 | - err = kgdboc_option_setup(config); |
1537 | - if (err || !strlen(config) || isspace(config[0])) |
1538 | + if (!strlen(config) || isspace(config[0])) |
1539 | goto noconfig; |
1540 | |
1541 | - err = -ENODEV; |
1542 | kgdboc_io_ops.is_console = 0; |
1543 | kgdb_tty_driver = NULL; |
1544 | |
1545 | @@ -318,6 +298,25 @@ static struct kgdb_io kgdboc_io_ops = { |
1546 | }; |
1547 | |
1548 | #ifdef CONFIG_KGDB_SERIAL_CONSOLE |
1549 | +static int kgdboc_option_setup(char *opt) |
1550 | +{ |
1551 | + if (!opt) { |
1552 | + pr_err("config string not provided\n"); |
1553 | + return -EINVAL; |
1554 | + } |
1555 | + |
1556 | + if (strlen(opt) >= MAX_CONFIG_LEN) { |
1557 | + pr_err("config string too long\n"); |
1558 | + return -ENOSPC; |
1559 | + } |
1560 | + strcpy(config, opt); |
1561 | + |
1562 | + return 0; |
1563 | +} |
1564 | + |
1565 | +__setup("kgdboc=", kgdboc_option_setup); |
1566 | + |
1567 | + |
1568 | /* This is only available if kgdboc is a built in for early debugging */ |
1569 | static int __init kgdboc_early_init(char *opt) |
1570 | { |
1571 | diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c |
1572 | index ff4d6cac7ac0..ab89fa3b4118 100644 |
1573 | --- a/drivers/usb/gadget/udc/dummy_hcd.c |
1574 | +++ b/drivers/usb/gadget/udc/dummy_hcd.c |
1575 | @@ -379,11 +379,10 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) |
1576 | USB_PORT_STAT_CONNECTION) == 0) |
1577 | dum_hcd->port_status |= |
1578 | (USB_PORT_STAT_C_CONNECTION << 16); |
1579 | - if ((dum_hcd->port_status & |
1580 | - USB_PORT_STAT_ENABLE) == 1 && |
1581 | - (dum_hcd->port_status & |
1582 | - USB_SS_PORT_LS_U0) == 1 && |
1583 | - dum_hcd->rh_state != DUMMY_RH_SUSPENDED) |
1584 | + if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) && |
1585 | + (dum_hcd->port_status & |
1586 | + USB_PORT_STAT_LINK_STATE) == USB_SS_PORT_LS_U0 && |
1587 | + dum_hcd->rh_state != DUMMY_RH_SUSPENDED) |
1588 | dum_hcd->active = 1; |
1589 | } |
1590 | } else { |
1591 | diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile |
1592 | index 128ce17a80b0..076ccfb44c28 100644 |
1593 | --- a/fs/btrfs/Makefile |
1594 | +++ b/fs/btrfs/Makefile |
1595 | @@ -9,7 +9,7 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \ |
1596 | export.o tree-log.o free-space-cache.o zlib.o lzo.o \ |
1597 | compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o \ |
1598 | reada.o backref.o ulist.o qgroup.o send.o dev-replace.o raid56.o \ |
1599 | - uuid-tree.o props.o hash.o free-space-tree.o |
1600 | + uuid-tree.o props.o hash.o free-space-tree.o tree-checker.o |
1601 | |
1602 | btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o |
1603 | btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o |
1604 | diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h |
1605 | index 86245b884fce..a423c36bcd72 100644 |
1606 | --- a/fs/btrfs/ctree.h |
1607 | +++ b/fs/btrfs/ctree.h |
1608 | @@ -1415,7 +1415,7 @@ do { \ |
1609 | #define BTRFS_INODE_ROOT_ITEM_INIT (1 << 31) |
1610 | |
1611 | struct btrfs_map_token { |
1612 | - struct extent_buffer *eb; |
1613 | + const struct extent_buffer *eb; |
1614 | char *kaddr; |
1615 | unsigned long offset; |
1616 | }; |
1617 | @@ -1449,18 +1449,19 @@ static inline void btrfs_init_map_token (struct btrfs_map_token *token) |
1618 | sizeof(((type *)0)->member))) |
1619 | |
1620 | #define DECLARE_BTRFS_SETGET_BITS(bits) \ |
1621 | -u##bits btrfs_get_token_##bits(struct extent_buffer *eb, void *ptr, \ |
1622 | - unsigned long off, \ |
1623 | - struct btrfs_map_token *token); \ |
1624 | -void btrfs_set_token_##bits(struct extent_buffer *eb, void *ptr, \ |
1625 | +u##bits btrfs_get_token_##bits(const struct extent_buffer *eb, \ |
1626 | + const void *ptr, unsigned long off, \ |
1627 | + struct btrfs_map_token *token); \ |
1628 | +void btrfs_set_token_##bits(struct extent_buffer *eb, const void *ptr, \ |
1629 | unsigned long off, u##bits val, \ |
1630 | struct btrfs_map_token *token); \ |
1631 | -static inline u##bits btrfs_get_##bits(struct extent_buffer *eb, void *ptr, \ |
1632 | +static inline u##bits btrfs_get_##bits(const struct extent_buffer *eb, \ |
1633 | + const void *ptr, \ |
1634 | unsigned long off) \ |
1635 | { \ |
1636 | return btrfs_get_token_##bits(eb, ptr, off, NULL); \ |
1637 | } \ |
1638 | -static inline void btrfs_set_##bits(struct extent_buffer *eb, void *ptr, \ |
1639 | +static inline void btrfs_set_##bits(struct extent_buffer *eb, void *ptr,\ |
1640 | unsigned long off, u##bits val) \ |
1641 | { \ |
1642 | btrfs_set_token_##bits(eb, ptr, off, val, NULL); \ |
1643 | @@ -1472,7 +1473,8 @@ DECLARE_BTRFS_SETGET_BITS(32) |
1644 | DECLARE_BTRFS_SETGET_BITS(64) |
1645 | |
1646 | #define BTRFS_SETGET_FUNCS(name, type, member, bits) \ |
1647 | -static inline u##bits btrfs_##name(struct extent_buffer *eb, type *s) \ |
1648 | +static inline u##bits btrfs_##name(const struct extent_buffer *eb, \ |
1649 | + const type *s) \ |
1650 | { \ |
1651 | BUILD_BUG_ON(sizeof(u##bits) != sizeof(((type *)0))->member); \ |
1652 | return btrfs_get_##bits(eb, s, offsetof(type, member)); \ |
1653 | @@ -1483,7 +1485,8 @@ static inline void btrfs_set_##name(struct extent_buffer *eb, type *s, \ |
1654 | BUILD_BUG_ON(sizeof(u##bits) != sizeof(((type *)0))->member); \ |
1655 | btrfs_set_##bits(eb, s, offsetof(type, member), val); \ |
1656 | } \ |
1657 | -static inline u##bits btrfs_token_##name(struct extent_buffer *eb, type *s, \ |
1658 | +static inline u##bits btrfs_token_##name(const struct extent_buffer *eb,\ |
1659 | + const type *s, \ |
1660 | struct btrfs_map_token *token) \ |
1661 | { \ |
1662 | BUILD_BUG_ON(sizeof(u##bits) != sizeof(((type *)0))->member); \ |
1663 | @@ -1498,9 +1501,9 @@ static inline void btrfs_set_token_##name(struct extent_buffer *eb, \ |
1664 | } |
1665 | |
1666 | #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ |
1667 | -static inline u##bits btrfs_##name(struct extent_buffer *eb) \ |
1668 | +static inline u##bits btrfs_##name(const struct extent_buffer *eb) \ |
1669 | { \ |
1670 | - type *p = page_address(eb->pages[0]); \ |
1671 | + const type *p = page_address(eb->pages[0]); \ |
1672 | u##bits res = le##bits##_to_cpu(p->member); \ |
1673 | return res; \ |
1674 | } \ |
1675 | @@ -1512,7 +1515,7 @@ static inline void btrfs_set_##name(struct extent_buffer *eb, \ |
1676 | } |
1677 | |
1678 | #define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \ |
1679 | -static inline u##bits btrfs_##name(type *s) \ |
1680 | +static inline u##bits btrfs_##name(const type *s) \ |
1681 | { \ |
1682 | return le##bits##_to_cpu(s->member); \ |
1683 | } \ |
1684 | @@ -1818,7 +1821,7 @@ static inline unsigned long btrfs_node_key_ptr_offset(int nr) |
1685 | sizeof(struct btrfs_key_ptr) * nr; |
1686 | } |
1687 | |
1688 | -void btrfs_node_key(struct extent_buffer *eb, |
1689 | +void btrfs_node_key(const struct extent_buffer *eb, |
1690 | struct btrfs_disk_key *disk_key, int nr); |
1691 | |
1692 | static inline void btrfs_set_node_key(struct extent_buffer *eb, |
1693 | @@ -1847,28 +1850,28 @@ static inline struct btrfs_item *btrfs_item_nr(int nr) |
1694 | return (struct btrfs_item *)btrfs_item_nr_offset(nr); |
1695 | } |
1696 | |
1697 | -static inline u32 btrfs_item_end(struct extent_buffer *eb, |
1698 | +static inline u32 btrfs_item_end(const struct extent_buffer *eb, |
1699 | struct btrfs_item *item) |
1700 | { |
1701 | return btrfs_item_offset(eb, item) + btrfs_item_size(eb, item); |
1702 | } |
1703 | |
1704 | -static inline u32 btrfs_item_end_nr(struct extent_buffer *eb, int nr) |
1705 | +static inline u32 btrfs_item_end_nr(const struct extent_buffer *eb, int nr) |
1706 | { |
1707 | return btrfs_item_end(eb, btrfs_item_nr(nr)); |
1708 | } |
1709 | |
1710 | -static inline u32 btrfs_item_offset_nr(struct extent_buffer *eb, int nr) |
1711 | +static inline u32 btrfs_item_offset_nr(const struct extent_buffer *eb, int nr) |
1712 | { |
1713 | return btrfs_item_offset(eb, btrfs_item_nr(nr)); |
1714 | } |
1715 | |
1716 | -static inline u32 btrfs_item_size_nr(struct extent_buffer *eb, int nr) |
1717 | +static inline u32 btrfs_item_size_nr(const struct extent_buffer *eb, int nr) |
1718 | { |
1719 | return btrfs_item_size(eb, btrfs_item_nr(nr)); |
1720 | } |
1721 | |
1722 | -static inline void btrfs_item_key(struct extent_buffer *eb, |
1723 | +static inline void btrfs_item_key(const struct extent_buffer *eb, |
1724 | struct btrfs_disk_key *disk_key, int nr) |
1725 | { |
1726 | struct btrfs_item *item = btrfs_item_nr(nr); |
1727 | @@ -1904,8 +1907,8 @@ BTRFS_SETGET_STACK_FUNCS(stack_dir_name_len, struct btrfs_dir_item, |
1728 | BTRFS_SETGET_STACK_FUNCS(stack_dir_transid, struct btrfs_dir_item, |
1729 | transid, 64); |
1730 | |
1731 | -static inline void btrfs_dir_item_key(struct extent_buffer *eb, |
1732 | - struct btrfs_dir_item *item, |
1733 | +static inline void btrfs_dir_item_key(const struct extent_buffer *eb, |
1734 | + const struct btrfs_dir_item *item, |
1735 | struct btrfs_disk_key *key) |
1736 | { |
1737 | read_eb_member(eb, item, struct btrfs_dir_item, location, key); |
1738 | @@ -1913,7 +1916,7 @@ static inline void btrfs_dir_item_key(struct extent_buffer *eb, |
1739 | |
1740 | static inline void btrfs_set_dir_item_key(struct extent_buffer *eb, |
1741 | struct btrfs_dir_item *item, |
1742 | - struct btrfs_disk_key *key) |
1743 | + const struct btrfs_disk_key *key) |
1744 | { |
1745 | write_eb_member(eb, item, struct btrfs_dir_item, location, key); |
1746 | } |
1747 | @@ -1925,8 +1928,8 @@ BTRFS_SETGET_FUNCS(free_space_bitmaps, struct btrfs_free_space_header, |
1748 | BTRFS_SETGET_FUNCS(free_space_generation, struct btrfs_free_space_header, |
1749 | generation, 64); |
1750 | |
1751 | -static inline void btrfs_free_space_key(struct extent_buffer *eb, |
1752 | - struct btrfs_free_space_header *h, |
1753 | +static inline void btrfs_free_space_key(const struct extent_buffer *eb, |
1754 | + const struct btrfs_free_space_header *h, |
1755 | struct btrfs_disk_key *key) |
1756 | { |
1757 | read_eb_member(eb, h, struct btrfs_free_space_header, location, key); |
1758 | @@ -1934,7 +1937,7 @@ static inline void btrfs_free_space_key(struct extent_buffer *eb, |
1759 | |
1760 | static inline void btrfs_set_free_space_key(struct extent_buffer *eb, |
1761 | struct btrfs_free_space_header *h, |
1762 | - struct btrfs_disk_key *key) |
1763 | + const struct btrfs_disk_key *key) |
1764 | { |
1765 | write_eb_member(eb, h, struct btrfs_free_space_header, location, key); |
1766 | } |
1767 | @@ -1961,25 +1964,25 @@ static inline void btrfs_cpu_key_to_disk(struct btrfs_disk_key *disk, |
1768 | disk->objectid = cpu_to_le64(cpu->objectid); |
1769 | } |
1770 | |
1771 | -static inline void btrfs_node_key_to_cpu(struct extent_buffer *eb, |
1772 | - struct btrfs_key *key, int nr) |
1773 | +static inline void btrfs_node_key_to_cpu(const struct extent_buffer *eb, |
1774 | + struct btrfs_key *key, int nr) |
1775 | { |
1776 | struct btrfs_disk_key disk_key; |
1777 | btrfs_node_key(eb, &disk_key, nr); |
1778 | btrfs_disk_key_to_cpu(key, &disk_key); |
1779 | } |
1780 | |
1781 | -static inline void btrfs_item_key_to_cpu(struct extent_buffer *eb, |
1782 | - struct btrfs_key *key, int nr) |
1783 | +static inline void btrfs_item_key_to_cpu(const struct extent_buffer *eb, |
1784 | + struct btrfs_key *key, int nr) |
1785 | { |
1786 | struct btrfs_disk_key disk_key; |
1787 | btrfs_item_key(eb, &disk_key, nr); |
1788 | btrfs_disk_key_to_cpu(key, &disk_key); |
1789 | } |
1790 | |
1791 | -static inline void btrfs_dir_item_key_to_cpu(struct extent_buffer *eb, |
1792 | - struct btrfs_dir_item *item, |
1793 | - struct btrfs_key *key) |
1794 | +static inline void btrfs_dir_item_key_to_cpu(const struct extent_buffer *eb, |
1795 | + const struct btrfs_dir_item *item, |
1796 | + struct btrfs_key *key) |
1797 | { |
1798 | struct btrfs_disk_key disk_key; |
1799 | btrfs_dir_item_key(eb, item, &disk_key); |
1800 | @@ -2012,7 +2015,7 @@ BTRFS_SETGET_STACK_FUNCS(stack_header_nritems, struct btrfs_header, |
1801 | nritems, 32); |
1802 | BTRFS_SETGET_STACK_FUNCS(stack_header_bytenr, struct btrfs_header, bytenr, 64); |
1803 | |
1804 | -static inline int btrfs_header_flag(struct extent_buffer *eb, u64 flag) |
1805 | +static inline int btrfs_header_flag(const struct extent_buffer *eb, u64 flag) |
1806 | { |
1807 | return (btrfs_header_flags(eb) & flag) == flag; |
1808 | } |
1809 | @@ -2031,7 +2034,7 @@ static inline int btrfs_clear_header_flag(struct extent_buffer *eb, u64 flag) |
1810 | return (flags & flag) == flag; |
1811 | } |
1812 | |
1813 | -static inline int btrfs_header_backref_rev(struct extent_buffer *eb) |
1814 | +static inline int btrfs_header_backref_rev(const struct extent_buffer *eb) |
1815 | { |
1816 | u64 flags = btrfs_header_flags(eb); |
1817 | return flags >> BTRFS_BACKREF_REV_SHIFT; |
1818 | @@ -2051,12 +2054,12 @@ static inline unsigned long btrfs_header_fsid(void) |
1819 | return offsetof(struct btrfs_header, fsid); |
1820 | } |
1821 | |
1822 | -static inline unsigned long btrfs_header_chunk_tree_uuid(struct extent_buffer *eb) |
1823 | +static inline unsigned long btrfs_header_chunk_tree_uuid(const struct extent_buffer *eb) |
1824 | { |
1825 | return offsetof(struct btrfs_header, chunk_tree_uuid); |
1826 | } |
1827 | |
1828 | -static inline int btrfs_is_leaf(struct extent_buffer *eb) |
1829 | +static inline int btrfs_is_leaf(const struct extent_buffer *eb) |
1830 | { |
1831 | return btrfs_header_level(eb) == 0; |
1832 | } |
1833 | @@ -2090,12 +2093,12 @@ BTRFS_SETGET_STACK_FUNCS(root_stransid, struct btrfs_root_item, |
1834 | BTRFS_SETGET_STACK_FUNCS(root_rtransid, struct btrfs_root_item, |
1835 | rtransid, 64); |
1836 | |
1837 | -static inline bool btrfs_root_readonly(struct btrfs_root *root) |
1838 | +static inline bool btrfs_root_readonly(const struct btrfs_root *root) |
1839 | { |
1840 | return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_RDONLY)) != 0; |
1841 | } |
1842 | |
1843 | -static inline bool btrfs_root_dead(struct btrfs_root *root) |
1844 | +static inline bool btrfs_root_dead(const struct btrfs_root *root) |
1845 | { |
1846 | return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_DEAD)) != 0; |
1847 | } |
1848 | @@ -2152,51 +2155,51 @@ BTRFS_SETGET_STACK_FUNCS(backup_num_devices, struct btrfs_root_backup, |
1849 | /* struct btrfs_balance_item */ |
1850 | BTRFS_SETGET_FUNCS(balance_flags, struct btrfs_balance_item, flags, 64); |
1851 | |
1852 | -static inline void btrfs_balance_data(struct extent_buffer *eb, |
1853 | - struct btrfs_balance_item *bi, |
1854 | +static inline void btrfs_balance_data(const struct extent_buffer *eb, |
1855 | + const struct btrfs_balance_item *bi, |
1856 | struct btrfs_disk_balance_args *ba) |
1857 | { |
1858 | read_eb_member(eb, bi, struct btrfs_balance_item, data, ba); |
1859 | } |
1860 | |
1861 | static inline void btrfs_set_balance_data(struct extent_buffer *eb, |
1862 | - struct btrfs_balance_item *bi, |
1863 | - struct btrfs_disk_balance_args *ba) |
1864 | + struct btrfs_balance_item *bi, |
1865 | + const struct btrfs_disk_balance_args *ba) |
1866 | { |
1867 | write_eb_member(eb, bi, struct btrfs_balance_item, data, ba); |
1868 | } |
1869 | |
1870 | -static inline void btrfs_balance_meta(struct extent_buffer *eb, |
1871 | - struct btrfs_balance_item *bi, |
1872 | +static inline void btrfs_balance_meta(const struct extent_buffer *eb, |
1873 | + const struct btrfs_balance_item *bi, |
1874 | struct btrfs_disk_balance_args *ba) |
1875 | { |
1876 | read_eb_member(eb, bi, struct btrfs_balance_item, meta, ba); |
1877 | } |
1878 | |
1879 | static inline void btrfs_set_balance_meta(struct extent_buffer *eb, |
1880 | - struct btrfs_balance_item *bi, |
1881 | - struct btrfs_disk_balance_args *ba) |
1882 | + struct btrfs_balance_item *bi, |
1883 | + const struct btrfs_disk_balance_args *ba) |
1884 | { |
1885 | write_eb_member(eb, bi, struct btrfs_balance_item, meta, ba); |
1886 | } |
1887 | |
1888 | -static inline void btrfs_balance_sys(struct extent_buffer *eb, |
1889 | - struct btrfs_balance_item *bi, |
1890 | +static inline void btrfs_balance_sys(const struct extent_buffer *eb, |
1891 | + const struct btrfs_balance_item *bi, |
1892 | struct btrfs_disk_balance_args *ba) |
1893 | { |
1894 | read_eb_member(eb, bi, struct btrfs_balance_item, sys, ba); |
1895 | } |
1896 | |
1897 | static inline void btrfs_set_balance_sys(struct extent_buffer *eb, |
1898 | - struct btrfs_balance_item *bi, |
1899 | - struct btrfs_disk_balance_args *ba) |
1900 | + struct btrfs_balance_item *bi, |
1901 | + const struct btrfs_disk_balance_args *ba) |
1902 | { |
1903 | write_eb_member(eb, bi, struct btrfs_balance_item, sys, ba); |
1904 | } |
1905 | |
1906 | static inline void |
1907 | btrfs_disk_balance_args_to_cpu(struct btrfs_balance_args *cpu, |
1908 | - struct btrfs_disk_balance_args *disk) |
1909 | + const struct btrfs_disk_balance_args *disk) |
1910 | { |
1911 | memset(cpu, 0, sizeof(*cpu)); |
1912 | |
1913 | @@ -2216,7 +2219,7 @@ btrfs_disk_balance_args_to_cpu(struct btrfs_balance_args *cpu, |
1914 | |
1915 | static inline void |
1916 | btrfs_cpu_balance_args_to_disk(struct btrfs_disk_balance_args *disk, |
1917 | - struct btrfs_balance_args *cpu) |
1918 | + const struct btrfs_balance_args *cpu) |
1919 | { |
1920 | memset(disk, 0, sizeof(*disk)); |
1921 | |
1922 | @@ -2284,7 +2287,7 @@ BTRFS_SETGET_STACK_FUNCS(super_magic, struct btrfs_super_block, magic, 64); |
1923 | BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block, |
1924 | uuid_tree_generation, 64); |
1925 | |
1926 | -static inline int btrfs_super_csum_size(struct btrfs_super_block *s) |
1927 | +static inline int btrfs_super_csum_size(const struct btrfs_super_block *s) |
1928 | { |
1929 | u16 t = btrfs_super_csum_type(s); |
1930 | /* |
1931 | @@ -2303,8 +2306,8 @@ static inline unsigned long btrfs_leaf_data(struct extent_buffer *l) |
1932 | * this returns the address of the start of the last item, |
1933 | * which is the stop of the leaf data stack |
1934 | */ |
1935 | -static inline unsigned int leaf_data_end(struct btrfs_root *root, |
1936 | - struct extent_buffer *leaf) |
1937 | +static inline unsigned int leaf_data_end(const struct btrfs_root *root, |
1938 | + const struct extent_buffer *leaf) |
1939 | { |
1940 | u32 nr = btrfs_header_nritems(leaf); |
1941 | |
1942 | @@ -2329,7 +2332,7 @@ BTRFS_SETGET_STACK_FUNCS(stack_file_extent_compression, |
1943 | struct btrfs_file_extent_item, compression, 8); |
1944 | |
1945 | static inline unsigned long |
1946 | -btrfs_file_extent_inline_start(struct btrfs_file_extent_item *e) |
1947 | +btrfs_file_extent_inline_start(const struct btrfs_file_extent_item *e) |
1948 | { |
1949 | return (unsigned long)e + BTRFS_FILE_EXTENT_INLINE_DATA_START; |
1950 | } |
1951 | @@ -2363,8 +2366,9 @@ BTRFS_SETGET_FUNCS(file_extent_other_encoding, struct btrfs_file_extent_item, |
1952 | * size of any extent headers. If a file is compressed on disk, this is |
1953 | * the compressed size |
1954 | */ |
1955 | -static inline u32 btrfs_file_extent_inline_item_len(struct extent_buffer *eb, |
1956 | - struct btrfs_item *e) |
1957 | +static inline u32 btrfs_file_extent_inline_item_len( |
1958 | + const struct extent_buffer *eb, |
1959 | + struct btrfs_item *e) |
1960 | { |
1961 | return btrfs_item_size(eb, e) - BTRFS_FILE_EXTENT_INLINE_DATA_START; |
1962 | } |
1963 | @@ -2372,9 +2376,9 @@ static inline u32 btrfs_file_extent_inline_item_len(struct extent_buffer *eb, |
1964 | /* this returns the number of file bytes represented by the inline item. |
1965 | * If an item is compressed, this is the uncompressed size |
1966 | */ |
1967 | -static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, |
1968 | - int slot, |
1969 | - struct btrfs_file_extent_item *fi) |
1970 | +static inline u32 btrfs_file_extent_inline_len(const struct extent_buffer *eb, |
1971 | + int slot, |
1972 | + const struct btrfs_file_extent_item *fi) |
1973 | { |
1974 | struct btrfs_map_token token; |
1975 | |
1976 | @@ -2396,8 +2400,8 @@ static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, |
1977 | |
1978 | |
1979 | /* btrfs_dev_stats_item */ |
1980 | -static inline u64 btrfs_dev_stats_value(struct extent_buffer *eb, |
1981 | - struct btrfs_dev_stats_item *ptr, |
1982 | +static inline u64 btrfs_dev_stats_value(const struct extent_buffer *eb, |
1983 | + const struct btrfs_dev_stats_item *ptr, |
1984 | int index) |
1985 | { |
1986 | u64 val; |
1987 | diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c |
1988 | index 57d375c68e46..77b32415d9f2 100644 |
1989 | --- a/fs/btrfs/disk-io.c |
1990 | +++ b/fs/btrfs/disk-io.c |
1991 | @@ -50,6 +50,7 @@ |
1992 | #include "sysfs.h" |
1993 | #include "qgroup.h" |
1994 | #include "compression.h" |
1995 | +#include "tree-checker.h" |
1996 | |
1997 | #ifdef CONFIG_X86 |
1998 | #include <asm/cpufeature.h> |
1999 | @@ -452,9 +453,9 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, |
2000 | int mirror_num = 0; |
2001 | int failed_mirror = 0; |
2002 | |
2003 | - clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags); |
2004 | io_tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree; |
2005 | while (1) { |
2006 | + clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags); |
2007 | ret = read_extent_buffer_pages(io_tree, eb, WAIT_COMPLETE, |
2008 | btree_get_extent, mirror_num); |
2009 | if (!ret) { |
2010 | @@ -465,14 +466,6 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, |
2011 | ret = -EIO; |
2012 | } |
2013 | |
2014 | - /* |
2015 | - * This buffer's crc is fine, but its contents are corrupted, so |
2016 | - * there is no reason to read the other copies, they won't be |
2017 | - * any less wrong. |
2018 | - */ |
2019 | - if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags)) |
2020 | - break; |
2021 | - |
2022 | num_copies = btrfs_num_copies(root->fs_info, |
2023 | eb->start, eb->len); |
2024 | if (num_copies == 1) |
2025 | @@ -546,145 +539,6 @@ static int check_tree_block_fsid(struct btrfs_fs_info *fs_info, |
2026 | return ret; |
2027 | } |
2028 | |
2029 | -#define CORRUPT(reason, eb, root, slot) \ |
2030 | - btrfs_crit(root->fs_info, "corrupt %s, %s: block=%llu," \ |
2031 | - " root=%llu, slot=%d", \ |
2032 | - btrfs_header_level(eb) == 0 ? "leaf" : "node",\ |
2033 | - reason, btrfs_header_bytenr(eb), root->objectid, slot) |
2034 | - |
2035 | -static noinline int check_leaf(struct btrfs_root *root, |
2036 | - struct extent_buffer *leaf) |
2037 | -{ |
2038 | - struct btrfs_key key; |
2039 | - struct btrfs_key leaf_key; |
2040 | - u32 nritems = btrfs_header_nritems(leaf); |
2041 | - int slot; |
2042 | - |
2043 | - /* |
2044 | - * Extent buffers from a relocation tree have a owner field that |
2045 | - * corresponds to the subvolume tree they are based on. So just from an |
2046 | - * extent buffer alone we can not find out what is the id of the |
2047 | - * corresponding subvolume tree, so we can not figure out if the extent |
2048 | - * buffer corresponds to the root of the relocation tree or not. So skip |
2049 | - * this check for relocation trees. |
2050 | - */ |
2051 | - if (nritems == 0 && !btrfs_header_flag(leaf, BTRFS_HEADER_FLAG_RELOC)) { |
2052 | - struct btrfs_root *check_root; |
2053 | - |
2054 | - key.objectid = btrfs_header_owner(leaf); |
2055 | - key.type = BTRFS_ROOT_ITEM_KEY; |
2056 | - key.offset = (u64)-1; |
2057 | - |
2058 | - check_root = btrfs_get_fs_root(root->fs_info, &key, false); |
2059 | - /* |
2060 | - * The only reason we also check NULL here is that during |
2061 | - * open_ctree() some roots has not yet been set up. |
2062 | - */ |
2063 | - if (!IS_ERR_OR_NULL(check_root)) { |
2064 | - struct extent_buffer *eb; |
2065 | - |
2066 | - eb = btrfs_root_node(check_root); |
2067 | - /* if leaf is the root, then it's fine */ |
2068 | - if (leaf != eb) { |
2069 | - CORRUPT("non-root leaf's nritems is 0", |
2070 | - leaf, check_root, 0); |
2071 | - free_extent_buffer(eb); |
2072 | - return -EIO; |
2073 | - } |
2074 | - free_extent_buffer(eb); |
2075 | - } |
2076 | - return 0; |
2077 | - } |
2078 | - |
2079 | - if (nritems == 0) |
2080 | - return 0; |
2081 | - |
2082 | - /* Check the 0 item */ |
2083 | - if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) != |
2084 | - BTRFS_LEAF_DATA_SIZE(root)) { |
2085 | - CORRUPT("invalid item offset size pair", leaf, root, 0); |
2086 | - return -EIO; |
2087 | - } |
2088 | - |
2089 | - /* |
2090 | - * Check to make sure each items keys are in the correct order and their |
2091 | - * offsets make sense. We only have to loop through nritems-1 because |
2092 | - * we check the current slot against the next slot, which verifies the |
2093 | - * next slot's offset+size makes sense and that the current's slot |
2094 | - * offset is correct. |
2095 | - */ |
2096 | - for (slot = 0; slot < nritems - 1; slot++) { |
2097 | - btrfs_item_key_to_cpu(leaf, &leaf_key, slot); |
2098 | - btrfs_item_key_to_cpu(leaf, &key, slot + 1); |
2099 | - |
2100 | - /* Make sure the keys are in the right order */ |
2101 | - if (btrfs_comp_cpu_keys(&leaf_key, &key) >= 0) { |
2102 | - CORRUPT("bad key order", leaf, root, slot); |
2103 | - return -EIO; |
2104 | - } |
2105 | - |
2106 | - /* |
2107 | - * Make sure the offset and ends are right, remember that the |
2108 | - * item data starts at the end of the leaf and grows towards the |
2109 | - * front. |
2110 | - */ |
2111 | - if (btrfs_item_offset_nr(leaf, slot) != |
2112 | - btrfs_item_end_nr(leaf, slot + 1)) { |
2113 | - CORRUPT("slot offset bad", leaf, root, slot); |
2114 | - return -EIO; |
2115 | - } |
2116 | - |
2117 | - /* |
2118 | - * Check to make sure that we don't point outside of the leaf, |
2119 | - * just in case all the items are consistent to each other, but |
2120 | - * all point outside of the leaf. |
2121 | - */ |
2122 | - if (btrfs_item_end_nr(leaf, slot) > |
2123 | - BTRFS_LEAF_DATA_SIZE(root)) { |
2124 | - CORRUPT("slot end outside of leaf", leaf, root, slot); |
2125 | - return -EIO; |
2126 | - } |
2127 | - } |
2128 | - |
2129 | - return 0; |
2130 | -} |
2131 | - |
2132 | -static int check_node(struct btrfs_root *root, struct extent_buffer *node) |
2133 | -{ |
2134 | - unsigned long nr = btrfs_header_nritems(node); |
2135 | - struct btrfs_key key, next_key; |
2136 | - int slot; |
2137 | - u64 bytenr; |
2138 | - int ret = 0; |
2139 | - |
2140 | - if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(root)) { |
2141 | - btrfs_crit(root->fs_info, |
2142 | - "corrupt node: block %llu root %llu nritems %lu", |
2143 | - node->start, root->objectid, nr); |
2144 | - return -EIO; |
2145 | - } |
2146 | - |
2147 | - for (slot = 0; slot < nr - 1; slot++) { |
2148 | - bytenr = btrfs_node_blockptr(node, slot); |
2149 | - btrfs_node_key_to_cpu(node, &key, slot); |
2150 | - btrfs_node_key_to_cpu(node, &next_key, slot + 1); |
2151 | - |
2152 | - if (!bytenr) { |
2153 | - CORRUPT("invalid item slot", node, root, slot); |
2154 | - ret = -EIO; |
2155 | - goto out; |
2156 | - } |
2157 | - |
2158 | - if (btrfs_comp_cpu_keys(&key, &next_key) >= 0) { |
2159 | - CORRUPT("bad key order", node, root, slot); |
2160 | - ret = -EIO; |
2161 | - goto out; |
2162 | - } |
2163 | - } |
2164 | -out: |
2165 | - return ret; |
2166 | -} |
2167 | - |
2168 | static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio, |
2169 | u64 phy_offset, struct page *page, |
2170 | u64 start, u64 end, int mirror) |
2171 | @@ -750,12 +604,12 @@ static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio, |
2172 | * that we don't try and read the other copies of this block, just |
2173 | * return -EIO. |
2174 | */ |
2175 | - if (found_level == 0 && check_leaf(root, eb)) { |
2176 | + if (found_level == 0 && btrfs_check_leaf_full(root, eb)) { |
2177 | set_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags); |
2178 | ret = -EIO; |
2179 | } |
2180 | |
2181 | - if (found_level > 0 && check_node(root, eb)) |
2182 | + if (found_level > 0 && btrfs_check_node(root, eb)) |
2183 | ret = -EIO; |
2184 | |
2185 | if (!ret) |
2186 | @@ -4086,7 +3940,13 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) |
2187 | buf->len, |
2188 | root->fs_info->dirty_metadata_batch); |
2189 | #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY |
2190 | - if (btrfs_header_level(buf) == 0 && check_leaf(root, buf)) { |
2191 | + /* |
2192 | + * Since btrfs_mark_buffer_dirty() can be called with item pointer set |
2193 | + * but item data not updated. |
2194 | + * So here we should only check item pointers, not item data. |
2195 | + */ |
2196 | + if (btrfs_header_level(buf) == 0 && |
2197 | + btrfs_check_leaf_relaxed(root, buf)) { |
2198 | btrfs_print_leaf(root, buf); |
2199 | ASSERT(0); |
2200 | } |
2201 | diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c |
2202 | index a775307f3b6b..7938c48c72ff 100644 |
2203 | --- a/fs/btrfs/extent-tree.c |
2204 | +++ b/fs/btrfs/extent-tree.c |
2205 | @@ -9896,6 +9896,8 @@ static int find_first_block_group(struct btrfs_root *root, |
2206 | int ret = 0; |
2207 | struct btrfs_key found_key; |
2208 | struct extent_buffer *leaf; |
2209 | + struct btrfs_block_group_item bg; |
2210 | + u64 flags; |
2211 | int slot; |
2212 | |
2213 | ret = btrfs_search_slot(NULL, root, key, path, 0, 0); |
2214 | @@ -9930,8 +9932,32 @@ static int find_first_block_group(struct btrfs_root *root, |
2215 | "logical %llu len %llu found bg but no related chunk", |
2216 | found_key.objectid, found_key.offset); |
2217 | ret = -ENOENT; |
2218 | + } else if (em->start != found_key.objectid || |
2219 | + em->len != found_key.offset) { |
2220 | + btrfs_err(root->fs_info, |
2221 | + "block group %llu len %llu mismatch with chunk %llu len %llu", |
2222 | + found_key.objectid, found_key.offset, |
2223 | + em->start, em->len); |
2224 | + ret = -EUCLEAN; |
2225 | } else { |
2226 | - ret = 0; |
2227 | + read_extent_buffer(leaf, &bg, |
2228 | + btrfs_item_ptr_offset(leaf, slot), |
2229 | + sizeof(bg)); |
2230 | + flags = btrfs_block_group_flags(&bg) & |
2231 | + BTRFS_BLOCK_GROUP_TYPE_MASK; |
2232 | + |
2233 | + if (flags != (em->map_lookup->type & |
2234 | + BTRFS_BLOCK_GROUP_TYPE_MASK)) { |
2235 | + btrfs_err(root->fs_info, |
2236 | +"block group %llu len %llu type flags 0x%llx mismatch with chunk type flags 0x%llx", |
2237 | + found_key.objectid, |
2238 | + found_key.offset, flags, |
2239 | + (BTRFS_BLOCK_GROUP_TYPE_MASK & |
2240 | + em->map_lookup->type)); |
2241 | + ret = -EUCLEAN; |
2242 | + } else { |
2243 | + ret = 0; |
2244 | + } |
2245 | } |
2246 | free_extent_map(em); |
2247 | goto out; |
2248 | @@ -10159,6 +10185,62 @@ btrfs_create_block_group_cache(struct btrfs_root *root, u64 start, u64 size) |
2249 | return cache; |
2250 | } |
2251 | |
2252 | + |
2253 | +/* |
2254 | + * Iterate all chunks and verify that each of them has the corresponding block |
2255 | + * group |
2256 | + */ |
2257 | +static int check_chunk_block_group_mappings(struct btrfs_fs_info *fs_info) |
2258 | +{ |
2259 | + struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree; |
2260 | + struct extent_map *em; |
2261 | + struct btrfs_block_group_cache *bg; |
2262 | + u64 start = 0; |
2263 | + int ret = 0; |
2264 | + |
2265 | + while (1) { |
2266 | + read_lock(&map_tree->map_tree.lock); |
2267 | + /* |
2268 | + * lookup_extent_mapping will return the first extent map |
2269 | + * intersecting the range, so setting @len to 1 is enough to |
2270 | + * get the first chunk. |
2271 | + */ |
2272 | + em = lookup_extent_mapping(&map_tree->map_tree, start, 1); |
2273 | + read_unlock(&map_tree->map_tree.lock); |
2274 | + if (!em) |
2275 | + break; |
2276 | + |
2277 | + bg = btrfs_lookup_block_group(fs_info, em->start); |
2278 | + if (!bg) { |
2279 | + btrfs_err(fs_info, |
2280 | + "chunk start=%llu len=%llu doesn't have corresponding block group", |
2281 | + em->start, em->len); |
2282 | + ret = -EUCLEAN; |
2283 | + free_extent_map(em); |
2284 | + break; |
2285 | + } |
2286 | + if (bg->key.objectid != em->start || |
2287 | + bg->key.offset != em->len || |
2288 | + (bg->flags & BTRFS_BLOCK_GROUP_TYPE_MASK) != |
2289 | + (em->map_lookup->type & BTRFS_BLOCK_GROUP_TYPE_MASK)) { |
2290 | + btrfs_err(fs_info, |
2291 | +"chunk start=%llu len=%llu flags=0x%llx doesn't match block group start=%llu len=%llu flags=0x%llx", |
2292 | + em->start, em->len, |
2293 | + em->map_lookup->type & BTRFS_BLOCK_GROUP_TYPE_MASK, |
2294 | + bg->key.objectid, bg->key.offset, |
2295 | + bg->flags & BTRFS_BLOCK_GROUP_TYPE_MASK); |
2296 | + ret = -EUCLEAN; |
2297 | + free_extent_map(em); |
2298 | + btrfs_put_block_group(bg); |
2299 | + break; |
2300 | + } |
2301 | + start = em->start + em->len; |
2302 | + free_extent_map(em); |
2303 | + btrfs_put_block_group(bg); |
2304 | + } |
2305 | + return ret; |
2306 | +} |
2307 | + |
2308 | int btrfs_read_block_groups(struct btrfs_root *root) |
2309 | { |
2310 | struct btrfs_path *path; |
2311 | @@ -10343,7 +10425,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) |
2312 | } |
2313 | |
2314 | init_global_block_rsv(info); |
2315 | - ret = 0; |
2316 | + ret = check_chunk_block_group_mappings(info); |
2317 | error: |
2318 | btrfs_free_path(path); |
2319 | return ret; |
2320 | diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c |
2321 | index 5feaef9bcbda..793d4d571d8d 100644 |
2322 | --- a/fs/btrfs/extent_io.c |
2323 | +++ b/fs/btrfs/extent_io.c |
2324 | @@ -5442,9 +5442,8 @@ unlock_exit: |
2325 | return ret; |
2326 | } |
2327 | |
2328 | -void read_extent_buffer(struct extent_buffer *eb, void *dstv, |
2329 | - unsigned long start, |
2330 | - unsigned long len) |
2331 | +void read_extent_buffer(const struct extent_buffer *eb, void *dstv, |
2332 | + unsigned long start, unsigned long len) |
2333 | { |
2334 | size_t cur; |
2335 | size_t offset; |
2336 | @@ -5473,9 +5472,9 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv, |
2337 | } |
2338 | } |
2339 | |
2340 | -int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dstv, |
2341 | - unsigned long start, |
2342 | - unsigned long len) |
2343 | +int read_extent_buffer_to_user(const struct extent_buffer *eb, |
2344 | + void __user *dstv, |
2345 | + unsigned long start, unsigned long len) |
2346 | { |
2347 | size_t cur; |
2348 | size_t offset; |
2349 | @@ -5515,10 +5514,10 @@ int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dstv, |
2350 | * return 1 if the item spans two pages. |
2351 | * return -EINVAL otherwise. |
2352 | */ |
2353 | -int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, |
2354 | - unsigned long min_len, char **map, |
2355 | - unsigned long *map_start, |
2356 | - unsigned long *map_len) |
2357 | +int map_private_extent_buffer(const struct extent_buffer *eb, |
2358 | + unsigned long start, unsigned long min_len, |
2359 | + char **map, unsigned long *map_start, |
2360 | + unsigned long *map_len) |
2361 | { |
2362 | size_t offset = start & (PAGE_SIZE - 1); |
2363 | char *kaddr; |
2364 | @@ -5552,9 +5551,8 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, |
2365 | return 0; |
2366 | } |
2367 | |
2368 | -int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv, |
2369 | - unsigned long start, |
2370 | - unsigned long len) |
2371 | +int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv, |
2372 | + unsigned long start, unsigned long len) |
2373 | { |
2374 | size_t cur; |
2375 | size_t offset; |
2376 | diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h |
2377 | index ab31d145227e..9ecdc9584df7 100644 |
2378 | --- a/fs/btrfs/extent_io.h |
2379 | +++ b/fs/btrfs/extent_io.h |
2380 | @@ -396,14 +396,13 @@ static inline void extent_buffer_get(struct extent_buffer *eb) |
2381 | atomic_inc(&eb->refs); |
2382 | } |
2383 | |
2384 | -int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv, |
2385 | - unsigned long start, |
2386 | - unsigned long len); |
2387 | -void read_extent_buffer(struct extent_buffer *eb, void *dst, |
2388 | +int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv, |
2389 | + unsigned long start, unsigned long len); |
2390 | +void read_extent_buffer(const struct extent_buffer *eb, void *dst, |
2391 | unsigned long start, |
2392 | unsigned long len); |
2393 | -int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dst, |
2394 | - unsigned long start, |
2395 | +int read_extent_buffer_to_user(const struct extent_buffer *eb, |
2396 | + void __user *dst, unsigned long start, |
2397 | unsigned long len); |
2398 | void write_extent_buffer(struct extent_buffer *eb, const void *src, |
2399 | unsigned long start, unsigned long len); |
2400 | @@ -428,10 +427,10 @@ void set_extent_buffer_uptodate(struct extent_buffer *eb); |
2401 | void clear_extent_buffer_uptodate(struct extent_buffer *eb); |
2402 | int extent_buffer_uptodate(struct extent_buffer *eb); |
2403 | int extent_buffer_under_io(struct extent_buffer *eb); |
2404 | -int map_private_extent_buffer(struct extent_buffer *eb, unsigned long offset, |
2405 | - unsigned long min_len, char **map, |
2406 | - unsigned long *map_start, |
2407 | - unsigned long *map_len); |
2408 | +int map_private_extent_buffer(const struct extent_buffer *eb, |
2409 | + unsigned long offset, unsigned long min_len, |
2410 | + char **map, unsigned long *map_start, |
2411 | + unsigned long *map_len); |
2412 | void extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end); |
2413 | void extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end); |
2414 | void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end, |
2415 | diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c |
2416 | index 5ca0dbb9074d..69a3c11af9d4 100644 |
2417 | --- a/fs/btrfs/free-space-cache.c |
2418 | +++ b/fs/btrfs/free-space-cache.c |
2419 | @@ -2464,6 +2464,7 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group, |
2420 | struct rb_node *n; |
2421 | int count = 0; |
2422 | |
2423 | + spin_lock(&ctl->tree_lock); |
2424 | for (n = rb_first(&ctl->free_space_offset); n; n = rb_next(n)) { |
2425 | info = rb_entry(n, struct btrfs_free_space, offset_index); |
2426 | if (info->bytes >= bytes && !block_group->ro) |
2427 | @@ -2473,6 +2474,7 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group, |
2428 | info->offset, info->bytes, |
2429 | (info->bitmap) ? "yes" : "no"); |
2430 | } |
2431 | + spin_unlock(&ctl->tree_lock); |
2432 | btrfs_info(block_group->fs_info, "block group has cluster?: %s", |
2433 | list_empty(&block_group->cluster_list) ? "no" : "yes"); |
2434 | btrfs_info(block_group->fs_info, |
2435 | diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c |
2436 | index 875c757e73e2..5e2b92d83617 100644 |
2437 | --- a/fs/btrfs/struct-funcs.c |
2438 | +++ b/fs/btrfs/struct-funcs.c |
2439 | @@ -50,8 +50,8 @@ static inline void put_unaligned_le8(u8 val, void *p) |
2440 | */ |
2441 | |
2442 | #define DEFINE_BTRFS_SETGET_BITS(bits) \ |
2443 | -u##bits btrfs_get_token_##bits(struct extent_buffer *eb, void *ptr, \ |
2444 | - unsigned long off, \ |
2445 | +u##bits btrfs_get_token_##bits(const struct extent_buffer *eb, \ |
2446 | + const void *ptr, unsigned long off, \ |
2447 | struct btrfs_map_token *token) \ |
2448 | { \ |
2449 | unsigned long part_offset = (unsigned long)ptr; \ |
2450 | @@ -90,7 +90,8 @@ u##bits btrfs_get_token_##bits(struct extent_buffer *eb, void *ptr, \ |
2451 | return res; \ |
2452 | } \ |
2453 | void btrfs_set_token_##bits(struct extent_buffer *eb, \ |
2454 | - void *ptr, unsigned long off, u##bits val, \ |
2455 | + const void *ptr, unsigned long off, \ |
2456 | + u##bits val, \ |
2457 | struct btrfs_map_token *token) \ |
2458 | { \ |
2459 | unsigned long part_offset = (unsigned long)ptr; \ |
2460 | @@ -133,7 +134,7 @@ DEFINE_BTRFS_SETGET_BITS(16) |
2461 | DEFINE_BTRFS_SETGET_BITS(32) |
2462 | DEFINE_BTRFS_SETGET_BITS(64) |
2463 | |
2464 | -void btrfs_node_key(struct extent_buffer *eb, |
2465 | +void btrfs_node_key(const struct extent_buffer *eb, |
2466 | struct btrfs_disk_key *disk_key, int nr) |
2467 | { |
2468 | unsigned long ptr = btrfs_node_key_ptr_offset(nr); |
2469 | diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c |
2470 | new file mode 100644 |
2471 | index 000000000000..7b69ba78e600 |
2472 | --- /dev/null |
2473 | +++ b/fs/btrfs/tree-checker.c |
2474 | @@ -0,0 +1,649 @@ |
2475 | +/* |
2476 | + * Copyright (C) Qu Wenruo 2017. All rights reserved. |
2477 | + * |
2478 | + * This program is free software; you can redistribute it and/or |
2479 | + * modify it under the terms of the GNU General Public |
2480 | + * License v2 as published by the Free Software Foundation. |
2481 | + * |
2482 | + * This program is distributed in the hope that it will be useful, |
2483 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2484 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2485 | + * General Public License for more details. |
2486 | + * |
2487 | + * You should have received a copy of the GNU General Public |
2488 | + * License along with this program. |
2489 | + */ |
2490 | + |
2491 | +/* |
2492 | + * The module is used to catch unexpected/corrupted tree block data. |
2493 | + * Such behavior can be caused either by a fuzzed image or bugs. |
2494 | + * |
2495 | + * The objective is to do leaf/node validation checks when tree block is read |
2496 | + * from disk, and check *every* possible member, so other code won't |
2497 | + * need to checking them again. |
2498 | + * |
2499 | + * Due to the potential and unwanted damage, every checker needs to be |
2500 | + * carefully reviewed otherwise so it does not prevent mount of valid images. |
2501 | + */ |
2502 | + |
2503 | +#include "ctree.h" |
2504 | +#include "tree-checker.h" |
2505 | +#include "disk-io.h" |
2506 | +#include "compression.h" |
2507 | +#include "hash.h" |
2508 | +#include "volumes.h" |
2509 | + |
2510 | +#define CORRUPT(reason, eb, root, slot) \ |
2511 | + btrfs_crit(root->fs_info, \ |
2512 | + "corrupt %s, %s: block=%llu, root=%llu, slot=%d", \ |
2513 | + btrfs_header_level(eb) == 0 ? "leaf" : "node", \ |
2514 | + reason, btrfs_header_bytenr(eb), root->objectid, slot) |
2515 | + |
2516 | +/* |
2517 | + * Error message should follow the following format: |
2518 | + * corrupt <type>: <identifier>, <reason>[, <bad_value>] |
2519 | + * |
2520 | + * @type: leaf or node |
2521 | + * @identifier: the necessary info to locate the leaf/node. |
2522 | + * It's recommened to decode key.objecitd/offset if it's |
2523 | + * meaningful. |
2524 | + * @reason: describe the error |
2525 | + * @bad_value: optional, it's recommened to output bad value and its |
2526 | + * expected value (range). |
2527 | + * |
2528 | + * Since comma is used to separate the components, only space is allowed |
2529 | + * inside each component. |
2530 | + */ |
2531 | + |
2532 | +/* |
2533 | + * Append generic "corrupt leaf/node root=%llu block=%llu slot=%d: " to @fmt. |
2534 | + * Allows callers to customize the output. |
2535 | + */ |
2536 | +__printf(4, 5) |
2537 | +static void generic_err(const struct btrfs_root *root, |
2538 | + const struct extent_buffer *eb, int slot, |
2539 | + const char *fmt, ...) |
2540 | +{ |
2541 | + struct va_format vaf; |
2542 | + va_list args; |
2543 | + |
2544 | + va_start(args, fmt); |
2545 | + |
2546 | + vaf.fmt = fmt; |
2547 | + vaf.va = &args; |
2548 | + |
2549 | + btrfs_crit(root->fs_info, |
2550 | + "corrupt %s: root=%llu block=%llu slot=%d, %pV", |
2551 | + btrfs_header_level(eb) == 0 ? "leaf" : "node", |
2552 | + root->objectid, btrfs_header_bytenr(eb), slot, &vaf); |
2553 | + va_end(args); |
2554 | +} |
2555 | + |
2556 | +static int check_extent_data_item(struct btrfs_root *root, |
2557 | + struct extent_buffer *leaf, |
2558 | + struct btrfs_key *key, int slot) |
2559 | +{ |
2560 | + struct btrfs_file_extent_item *fi; |
2561 | + u32 sectorsize = root->sectorsize; |
2562 | + u32 item_size = btrfs_item_size_nr(leaf, slot); |
2563 | + |
2564 | + if (!IS_ALIGNED(key->offset, sectorsize)) { |
2565 | + CORRUPT("unaligned key offset for file extent", |
2566 | + leaf, root, slot); |
2567 | + return -EUCLEAN; |
2568 | + } |
2569 | + |
2570 | + fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); |
2571 | + |
2572 | + if (btrfs_file_extent_type(leaf, fi) > BTRFS_FILE_EXTENT_TYPES) { |
2573 | + CORRUPT("invalid file extent type", leaf, root, slot); |
2574 | + return -EUCLEAN; |
2575 | + } |
2576 | + |
2577 | + /* |
2578 | + * Support for new compression/encrption must introduce incompat flag, |
2579 | + * and must be caught in open_ctree(). |
2580 | + */ |
2581 | + if (btrfs_file_extent_compression(leaf, fi) > BTRFS_COMPRESS_TYPES) { |
2582 | + CORRUPT("invalid file extent compression", leaf, root, slot); |
2583 | + return -EUCLEAN; |
2584 | + } |
2585 | + if (btrfs_file_extent_encryption(leaf, fi)) { |
2586 | + CORRUPT("invalid file extent encryption", leaf, root, slot); |
2587 | + return -EUCLEAN; |
2588 | + } |
2589 | + if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) { |
2590 | + /* Inline extent must have 0 as key offset */ |
2591 | + if (key->offset) { |
2592 | + CORRUPT("inline extent has non-zero key offset", |
2593 | + leaf, root, slot); |
2594 | + return -EUCLEAN; |
2595 | + } |
2596 | + |
2597 | + /* Compressed inline extent has no on-disk size, skip it */ |
2598 | + if (btrfs_file_extent_compression(leaf, fi) != |
2599 | + BTRFS_COMPRESS_NONE) |
2600 | + return 0; |
2601 | + |
2602 | + /* Uncompressed inline extent size must match item size */ |
2603 | + if (item_size != BTRFS_FILE_EXTENT_INLINE_DATA_START + |
2604 | + btrfs_file_extent_ram_bytes(leaf, fi)) { |
2605 | + CORRUPT("plaintext inline extent has invalid size", |
2606 | + leaf, root, slot); |
2607 | + return -EUCLEAN; |
2608 | + } |
2609 | + return 0; |
2610 | + } |
2611 | + |
2612 | + /* Regular or preallocated extent has fixed item size */ |
2613 | + if (item_size != sizeof(*fi)) { |
2614 | + CORRUPT( |
2615 | + "regluar or preallocated extent data item size is invalid", |
2616 | + leaf, root, slot); |
2617 | + return -EUCLEAN; |
2618 | + } |
2619 | + if (!IS_ALIGNED(btrfs_file_extent_ram_bytes(leaf, fi), sectorsize) || |
2620 | + !IS_ALIGNED(btrfs_file_extent_disk_bytenr(leaf, fi), sectorsize) || |
2621 | + !IS_ALIGNED(btrfs_file_extent_disk_num_bytes(leaf, fi), sectorsize) || |
2622 | + !IS_ALIGNED(btrfs_file_extent_offset(leaf, fi), sectorsize) || |
2623 | + !IS_ALIGNED(btrfs_file_extent_num_bytes(leaf, fi), sectorsize)) { |
2624 | + CORRUPT( |
2625 | + "regular or preallocated extent data item has unaligned value", |
2626 | + leaf, root, slot); |
2627 | + return -EUCLEAN; |
2628 | + } |
2629 | + |
2630 | + return 0; |
2631 | +} |
2632 | + |
2633 | +static int check_csum_item(struct btrfs_root *root, struct extent_buffer *leaf, |
2634 | + struct btrfs_key *key, int slot) |
2635 | +{ |
2636 | + u32 sectorsize = root->sectorsize; |
2637 | + u32 csumsize = btrfs_super_csum_size(root->fs_info->super_copy); |
2638 | + |
2639 | + if (key->objectid != BTRFS_EXTENT_CSUM_OBJECTID) { |
2640 | + CORRUPT("invalid objectid for csum item", leaf, root, slot); |
2641 | + return -EUCLEAN; |
2642 | + } |
2643 | + if (!IS_ALIGNED(key->offset, sectorsize)) { |
2644 | + CORRUPT("unaligned key offset for csum item", leaf, root, slot); |
2645 | + return -EUCLEAN; |
2646 | + } |
2647 | + if (!IS_ALIGNED(btrfs_item_size_nr(leaf, slot), csumsize)) { |
2648 | + CORRUPT("unaligned csum item size", leaf, root, slot); |
2649 | + return -EUCLEAN; |
2650 | + } |
2651 | + return 0; |
2652 | +} |
2653 | + |
2654 | +/* |
2655 | + * Customized reported for dir_item, only important new info is key->objectid, |
2656 | + * which represents inode number |
2657 | + */ |
2658 | +__printf(4, 5) |
2659 | +static void dir_item_err(const struct btrfs_root *root, |
2660 | + const struct extent_buffer *eb, int slot, |
2661 | + const char *fmt, ...) |
2662 | +{ |
2663 | + struct btrfs_key key; |
2664 | + struct va_format vaf; |
2665 | + va_list args; |
2666 | + |
2667 | + btrfs_item_key_to_cpu(eb, &key, slot); |
2668 | + va_start(args, fmt); |
2669 | + |
2670 | + vaf.fmt = fmt; |
2671 | + vaf.va = &args; |
2672 | + |
2673 | + btrfs_crit(root->fs_info, |
2674 | + "corrupt %s: root=%llu block=%llu slot=%d ino=%llu, %pV", |
2675 | + btrfs_header_level(eb) == 0 ? "leaf" : "node", root->objectid, |
2676 | + btrfs_header_bytenr(eb), slot, key.objectid, &vaf); |
2677 | + va_end(args); |
2678 | +} |
2679 | + |
2680 | +static int check_dir_item(struct btrfs_root *root, |
2681 | + struct extent_buffer *leaf, |
2682 | + struct btrfs_key *key, int slot) |
2683 | +{ |
2684 | + struct btrfs_dir_item *di; |
2685 | + u32 item_size = btrfs_item_size_nr(leaf, slot); |
2686 | + u32 cur = 0; |
2687 | + |
2688 | + di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); |
2689 | + while (cur < item_size) { |
2690 | + u32 name_len; |
2691 | + u32 data_len; |
2692 | + u32 max_name_len; |
2693 | + u32 total_size; |
2694 | + u32 name_hash; |
2695 | + u8 dir_type; |
2696 | + |
2697 | + /* header itself should not cross item boundary */ |
2698 | + if (cur + sizeof(*di) > item_size) { |
2699 | + dir_item_err(root, leaf, slot, |
2700 | + "dir item header crosses item boundary, have %zu boundary %u", |
2701 | + cur + sizeof(*di), item_size); |
2702 | + return -EUCLEAN; |
2703 | + } |
2704 | + |
2705 | + /* dir type check */ |
2706 | + dir_type = btrfs_dir_type(leaf, di); |
2707 | + if (dir_type >= BTRFS_FT_MAX) { |
2708 | + dir_item_err(root, leaf, slot, |
2709 | + "invalid dir item type, have %u expect [0, %u)", |
2710 | + dir_type, BTRFS_FT_MAX); |
2711 | + return -EUCLEAN; |
2712 | + } |
2713 | + |
2714 | + if (key->type == BTRFS_XATTR_ITEM_KEY && |
2715 | + dir_type != BTRFS_FT_XATTR) { |
2716 | + dir_item_err(root, leaf, slot, |
2717 | + "invalid dir item type for XATTR key, have %u expect %u", |
2718 | + dir_type, BTRFS_FT_XATTR); |
2719 | + return -EUCLEAN; |
2720 | + } |
2721 | + if (dir_type == BTRFS_FT_XATTR && |
2722 | + key->type != BTRFS_XATTR_ITEM_KEY) { |
2723 | + dir_item_err(root, leaf, slot, |
2724 | + "xattr dir type found for non-XATTR key"); |
2725 | + return -EUCLEAN; |
2726 | + } |
2727 | + if (dir_type == BTRFS_FT_XATTR) |
2728 | + max_name_len = XATTR_NAME_MAX; |
2729 | + else |
2730 | + max_name_len = BTRFS_NAME_LEN; |
2731 | + |
2732 | + /* Name/data length check */ |
2733 | + name_len = btrfs_dir_name_len(leaf, di); |
2734 | + data_len = btrfs_dir_data_len(leaf, di); |
2735 | + if (name_len > max_name_len) { |
2736 | + dir_item_err(root, leaf, slot, |
2737 | + "dir item name len too long, have %u max %u", |
2738 | + name_len, max_name_len); |
2739 | + return -EUCLEAN; |
2740 | + } |
2741 | + if (name_len + data_len > BTRFS_MAX_XATTR_SIZE(root)) { |
2742 | + dir_item_err(root, leaf, slot, |
2743 | + "dir item name and data len too long, have %u max %u", |
2744 | + name_len + data_len, |
2745 | + BTRFS_MAX_XATTR_SIZE(root)); |
2746 | + return -EUCLEAN; |
2747 | + } |
2748 | + |
2749 | + if (data_len && dir_type != BTRFS_FT_XATTR) { |
2750 | + dir_item_err(root, leaf, slot, |
2751 | + "dir item with invalid data len, have %u expect 0", |
2752 | + data_len); |
2753 | + return -EUCLEAN; |
2754 | + } |
2755 | + |
2756 | + total_size = sizeof(*di) + name_len + data_len; |
2757 | + |
2758 | + /* header and name/data should not cross item boundary */ |
2759 | + if (cur + total_size > item_size) { |
2760 | + dir_item_err(root, leaf, slot, |
2761 | + "dir item data crosses item boundary, have %u boundary %u", |
2762 | + cur + total_size, item_size); |
2763 | + return -EUCLEAN; |
2764 | + } |
2765 | + |
2766 | + /* |
2767 | + * Special check for XATTR/DIR_ITEM, as key->offset is name |
2768 | + * hash, should match its name |
2769 | + */ |
2770 | + if (key->type == BTRFS_DIR_ITEM_KEY || |
2771 | + key->type == BTRFS_XATTR_ITEM_KEY) { |
2772 | + char namebuf[max(BTRFS_NAME_LEN, XATTR_NAME_MAX)]; |
2773 | + |
2774 | + read_extent_buffer(leaf, namebuf, |
2775 | + (unsigned long)(di + 1), name_len); |
2776 | + name_hash = btrfs_name_hash(namebuf, name_len); |
2777 | + if (key->offset != name_hash) { |
2778 | + dir_item_err(root, leaf, slot, |
2779 | + "name hash mismatch with key, have 0x%016x expect 0x%016llx", |
2780 | + name_hash, key->offset); |
2781 | + return -EUCLEAN; |
2782 | + } |
2783 | + } |
2784 | + cur += total_size; |
2785 | + di = (struct btrfs_dir_item *)((void *)di + total_size); |
2786 | + } |
2787 | + return 0; |
2788 | +} |
2789 | + |
2790 | +__printf(4, 5) |
2791 | +__cold |
2792 | +static void block_group_err(const struct btrfs_fs_info *fs_info, |
2793 | + const struct extent_buffer *eb, int slot, |
2794 | + const char *fmt, ...) |
2795 | +{ |
2796 | + struct btrfs_key key; |
2797 | + struct va_format vaf; |
2798 | + va_list args; |
2799 | + |
2800 | + btrfs_item_key_to_cpu(eb, &key, slot); |
2801 | + va_start(args, fmt); |
2802 | + |
2803 | + vaf.fmt = fmt; |
2804 | + vaf.va = &args; |
2805 | + |
2806 | + btrfs_crit(fs_info, |
2807 | + "corrupt %s: root=%llu block=%llu slot=%d bg_start=%llu bg_len=%llu, %pV", |
2808 | + btrfs_header_level(eb) == 0 ? "leaf" : "node", |
2809 | + btrfs_header_owner(eb), btrfs_header_bytenr(eb), slot, |
2810 | + key.objectid, key.offset, &vaf); |
2811 | + va_end(args); |
2812 | +} |
2813 | + |
2814 | +static int check_block_group_item(struct btrfs_fs_info *fs_info, |
2815 | + struct extent_buffer *leaf, |
2816 | + struct btrfs_key *key, int slot) |
2817 | +{ |
2818 | + struct btrfs_block_group_item bgi; |
2819 | + u32 item_size = btrfs_item_size_nr(leaf, slot); |
2820 | + u64 flags; |
2821 | + u64 type; |
2822 | + |
2823 | + /* |
2824 | + * Here we don't really care about alignment since extent allocator can |
2825 | + * handle it. We care more about the size, as if one block group is |
2826 | + * larger than maximum size, it's must be some obvious corruption. |
2827 | + */ |
2828 | + if (key->offset > BTRFS_MAX_DATA_CHUNK_SIZE || key->offset == 0) { |
2829 | + block_group_err(fs_info, leaf, slot, |
2830 | + "invalid block group size, have %llu expect (0, %llu]", |
2831 | + key->offset, BTRFS_MAX_DATA_CHUNK_SIZE); |
2832 | + return -EUCLEAN; |
2833 | + } |
2834 | + |
2835 | + if (item_size != sizeof(bgi)) { |
2836 | + block_group_err(fs_info, leaf, slot, |
2837 | + "invalid item size, have %u expect %zu", |
2838 | + item_size, sizeof(bgi)); |
2839 | + return -EUCLEAN; |
2840 | + } |
2841 | + |
2842 | + read_extent_buffer(leaf, &bgi, btrfs_item_ptr_offset(leaf, slot), |
2843 | + sizeof(bgi)); |
2844 | + if (btrfs_block_group_chunk_objectid(&bgi) != |
2845 | + BTRFS_FIRST_CHUNK_TREE_OBJECTID) { |
2846 | + block_group_err(fs_info, leaf, slot, |
2847 | + "invalid block group chunk objectid, have %llu expect %llu", |
2848 | + btrfs_block_group_chunk_objectid(&bgi), |
2849 | + BTRFS_FIRST_CHUNK_TREE_OBJECTID); |
2850 | + return -EUCLEAN; |
2851 | + } |
2852 | + |
2853 | + if (btrfs_block_group_used(&bgi) > key->offset) { |
2854 | + block_group_err(fs_info, leaf, slot, |
2855 | + "invalid block group used, have %llu expect [0, %llu)", |
2856 | + btrfs_block_group_used(&bgi), key->offset); |
2857 | + return -EUCLEAN; |
2858 | + } |
2859 | + |
2860 | + flags = btrfs_block_group_flags(&bgi); |
2861 | + if (hweight64(flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) > 1) { |
2862 | + block_group_err(fs_info, leaf, slot, |
2863 | +"invalid profile flags, have 0x%llx (%lu bits set) expect no more than 1 bit set", |
2864 | + flags & BTRFS_BLOCK_GROUP_PROFILE_MASK, |
2865 | + hweight64(flags & BTRFS_BLOCK_GROUP_PROFILE_MASK)); |
2866 | + return -EUCLEAN; |
2867 | + } |
2868 | + |
2869 | + type = flags & BTRFS_BLOCK_GROUP_TYPE_MASK; |
2870 | + if (type != BTRFS_BLOCK_GROUP_DATA && |
2871 | + type != BTRFS_BLOCK_GROUP_METADATA && |
2872 | + type != BTRFS_BLOCK_GROUP_SYSTEM && |
2873 | + type != (BTRFS_BLOCK_GROUP_METADATA | |
2874 | + BTRFS_BLOCK_GROUP_DATA)) { |
2875 | + block_group_err(fs_info, leaf, slot, |
2876 | +"invalid type, have 0x%llx (%lu bits set) expect either 0x%llx, 0x%llx, 0x%llx or 0x%llx", |
2877 | + type, hweight64(type), |
2878 | + BTRFS_BLOCK_GROUP_DATA, BTRFS_BLOCK_GROUP_METADATA, |
2879 | + BTRFS_BLOCK_GROUP_SYSTEM, |
2880 | + BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA); |
2881 | + return -EUCLEAN; |
2882 | + } |
2883 | + return 0; |
2884 | +} |
2885 | + |
2886 | +/* |
2887 | + * Common point to switch the item-specific validation. |
2888 | + */ |
2889 | +static int check_leaf_item(struct btrfs_root *root, |
2890 | + struct extent_buffer *leaf, |
2891 | + struct btrfs_key *key, int slot) |
2892 | +{ |
2893 | + int ret = 0; |
2894 | + |
2895 | + switch (key->type) { |
2896 | + case BTRFS_EXTENT_DATA_KEY: |
2897 | + ret = check_extent_data_item(root, leaf, key, slot); |
2898 | + break; |
2899 | + case BTRFS_EXTENT_CSUM_KEY: |
2900 | + ret = check_csum_item(root, leaf, key, slot); |
2901 | + break; |
2902 | + case BTRFS_DIR_ITEM_KEY: |
2903 | + case BTRFS_DIR_INDEX_KEY: |
2904 | + case BTRFS_XATTR_ITEM_KEY: |
2905 | + ret = check_dir_item(root, leaf, key, slot); |
2906 | + break; |
2907 | + case BTRFS_BLOCK_GROUP_ITEM_KEY: |
2908 | + ret = check_block_group_item(root->fs_info, leaf, key, slot); |
2909 | + break; |
2910 | + } |
2911 | + return ret; |
2912 | +} |
2913 | + |
2914 | +static int check_leaf(struct btrfs_root *root, struct extent_buffer *leaf, |
2915 | + bool check_item_data) |
2916 | +{ |
2917 | + struct btrfs_fs_info *fs_info = root->fs_info; |
2918 | + /* No valid key type is 0, so all key should be larger than this key */ |
2919 | + struct btrfs_key prev_key = {0, 0, 0}; |
2920 | + struct btrfs_key key; |
2921 | + u32 nritems = btrfs_header_nritems(leaf); |
2922 | + int slot; |
2923 | + |
2924 | + if (btrfs_header_level(leaf) != 0) { |
2925 | + generic_err(root, leaf, 0, |
2926 | + "invalid level for leaf, have %d expect 0", |
2927 | + btrfs_header_level(leaf)); |
2928 | + return -EUCLEAN; |
2929 | + } |
2930 | + |
2931 | + /* |
2932 | + * Extent buffers from a relocation tree have a owner field that |
2933 | + * corresponds to the subvolume tree they are based on. So just from an |
2934 | + * extent buffer alone we can not find out what is the id of the |
2935 | + * corresponding subvolume tree, so we can not figure out if the extent |
2936 | + * buffer corresponds to the root of the relocation tree or not. So |
2937 | + * skip this check for relocation trees. |
2938 | + */ |
2939 | + if (nritems == 0 && !btrfs_header_flag(leaf, BTRFS_HEADER_FLAG_RELOC)) { |
2940 | + u64 owner = btrfs_header_owner(leaf); |
2941 | + struct btrfs_root *check_root; |
2942 | + |
2943 | + /* These trees must never be empty */ |
2944 | + if (owner == BTRFS_ROOT_TREE_OBJECTID || |
2945 | + owner == BTRFS_CHUNK_TREE_OBJECTID || |
2946 | + owner == BTRFS_EXTENT_TREE_OBJECTID || |
2947 | + owner == BTRFS_DEV_TREE_OBJECTID || |
2948 | + owner == BTRFS_FS_TREE_OBJECTID || |
2949 | + owner == BTRFS_DATA_RELOC_TREE_OBJECTID) { |
2950 | + generic_err(root, leaf, 0, |
2951 | + "invalid root, root %llu must never be empty", |
2952 | + owner); |
2953 | + return -EUCLEAN; |
2954 | + } |
2955 | + key.objectid = owner; |
2956 | + key.type = BTRFS_ROOT_ITEM_KEY; |
2957 | + key.offset = (u64)-1; |
2958 | + |
2959 | + check_root = btrfs_get_fs_root(fs_info, &key, false); |
2960 | + /* |
2961 | + * The only reason we also check NULL here is that during |
2962 | + * open_ctree() some roots has not yet been set up. |
2963 | + */ |
2964 | + if (!IS_ERR_OR_NULL(check_root)) { |
2965 | + struct extent_buffer *eb; |
2966 | + |
2967 | + eb = btrfs_root_node(check_root); |
2968 | + /* if leaf is the root, then it's fine */ |
2969 | + if (leaf != eb) { |
2970 | + CORRUPT("non-root leaf's nritems is 0", |
2971 | + leaf, check_root, 0); |
2972 | + free_extent_buffer(eb); |
2973 | + return -EUCLEAN; |
2974 | + } |
2975 | + free_extent_buffer(eb); |
2976 | + } |
2977 | + return 0; |
2978 | + } |
2979 | + |
2980 | + if (nritems == 0) |
2981 | + return 0; |
2982 | + |
2983 | + /* |
2984 | + * Check the following things to make sure this is a good leaf, and |
2985 | + * leaf users won't need to bother with similar sanity checks: |
2986 | + * |
2987 | + * 1) key ordering |
2988 | + * 2) item offset and size |
2989 | + * No overlap, no hole, all inside the leaf. |
2990 | + * 3) item content |
2991 | + * If possible, do comprehensive sanity check. |
2992 | + * NOTE: All checks must only rely on the item data itself. |
2993 | + */ |
2994 | + for (slot = 0; slot < nritems; slot++) { |
2995 | + u32 item_end_expected; |
2996 | + int ret; |
2997 | + |
2998 | + btrfs_item_key_to_cpu(leaf, &key, slot); |
2999 | + |
3000 | + /* Make sure the keys are in the right order */ |
3001 | + if (btrfs_comp_cpu_keys(&prev_key, &key) >= 0) { |
3002 | + CORRUPT("bad key order", leaf, root, slot); |
3003 | + return -EUCLEAN; |
3004 | + } |
3005 | + |
3006 | + /* |
3007 | + * Make sure the offset and ends are right, remember that the |
3008 | + * item data starts at the end of the leaf and grows towards the |
3009 | + * front. |
3010 | + */ |
3011 | + if (slot == 0) |
3012 | + item_end_expected = BTRFS_LEAF_DATA_SIZE(root); |
3013 | + else |
3014 | + item_end_expected = btrfs_item_offset_nr(leaf, |
3015 | + slot - 1); |
3016 | + if (btrfs_item_end_nr(leaf, slot) != item_end_expected) { |
3017 | + CORRUPT("slot offset bad", leaf, root, slot); |
3018 | + return -EUCLEAN; |
3019 | + } |
3020 | + |
3021 | + /* |
3022 | + * Check to make sure that we don't point outside of the leaf, |
3023 | + * just in case all the items are consistent to each other, but |
3024 | + * all point outside of the leaf. |
3025 | + */ |
3026 | + if (btrfs_item_end_nr(leaf, slot) > |
3027 | + BTRFS_LEAF_DATA_SIZE(root)) { |
3028 | + CORRUPT("slot end outside of leaf", leaf, root, slot); |
3029 | + return -EUCLEAN; |
3030 | + } |
3031 | + |
3032 | + /* Also check if the item pointer overlaps with btrfs item. */ |
3033 | + if (btrfs_item_nr_offset(slot) + sizeof(struct btrfs_item) > |
3034 | + btrfs_item_ptr_offset(leaf, slot)) { |
3035 | + CORRUPT("slot overlap with its data", leaf, root, slot); |
3036 | + return -EUCLEAN; |
3037 | + } |
3038 | + |
3039 | + if (check_item_data) { |
3040 | + /* |
3041 | + * Check if the item size and content meet other |
3042 | + * criteria |
3043 | + */ |
3044 | + ret = check_leaf_item(root, leaf, &key, slot); |
3045 | + if (ret < 0) |
3046 | + return ret; |
3047 | + } |
3048 | + |
3049 | + prev_key.objectid = key.objectid; |
3050 | + prev_key.type = key.type; |
3051 | + prev_key.offset = key.offset; |
3052 | + } |
3053 | + |
3054 | + return 0; |
3055 | +} |
3056 | + |
3057 | +int btrfs_check_leaf_full(struct btrfs_root *root, struct extent_buffer *leaf) |
3058 | +{ |
3059 | + return check_leaf(root, leaf, true); |
3060 | +} |
3061 | + |
3062 | +int btrfs_check_leaf_relaxed(struct btrfs_root *root, |
3063 | + struct extent_buffer *leaf) |
3064 | +{ |
3065 | + return check_leaf(root, leaf, false); |
3066 | +} |
3067 | + |
3068 | +int btrfs_check_node(struct btrfs_root *root, struct extent_buffer *node) |
3069 | +{ |
3070 | + unsigned long nr = btrfs_header_nritems(node); |
3071 | + struct btrfs_key key, next_key; |
3072 | + int slot; |
3073 | + int level = btrfs_header_level(node); |
3074 | + u64 bytenr; |
3075 | + int ret = 0; |
3076 | + |
3077 | + if (level <= 0 || level >= BTRFS_MAX_LEVEL) { |
3078 | + generic_err(root, node, 0, |
3079 | + "invalid level for node, have %d expect [1, %d]", |
3080 | + level, BTRFS_MAX_LEVEL - 1); |
3081 | + return -EUCLEAN; |
3082 | + } |
3083 | + if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(root)) { |
3084 | + btrfs_crit(root->fs_info, |
3085 | +"corrupt node: root=%llu block=%llu, nritems too %s, have %lu expect range [1,%u]", |
3086 | + root->objectid, node->start, |
3087 | + nr == 0 ? "small" : "large", nr, |
3088 | + BTRFS_NODEPTRS_PER_BLOCK(root)); |
3089 | + return -EUCLEAN; |
3090 | + } |
3091 | + |
3092 | + for (slot = 0; slot < nr - 1; slot++) { |
3093 | + bytenr = btrfs_node_blockptr(node, slot); |
3094 | + btrfs_node_key_to_cpu(node, &key, slot); |
3095 | + btrfs_node_key_to_cpu(node, &next_key, slot + 1); |
3096 | + |
3097 | + if (!bytenr) { |
3098 | + generic_err(root, node, slot, |
3099 | + "invalid NULL node pointer"); |
3100 | + ret = -EUCLEAN; |
3101 | + goto out; |
3102 | + } |
3103 | + if (!IS_ALIGNED(bytenr, root->sectorsize)) { |
3104 | + generic_err(root, node, slot, |
3105 | + "unaligned pointer, have %llu should be aligned to %u", |
3106 | + bytenr, root->sectorsize); |
3107 | + ret = -EUCLEAN; |
3108 | + goto out; |
3109 | + } |
3110 | + |
3111 | + if (btrfs_comp_cpu_keys(&key, &next_key) >= 0) { |
3112 | + generic_err(root, node, slot, |
3113 | + "bad key order, current (%llu %u %llu) next (%llu %u %llu)", |
3114 | + key.objectid, key.type, key.offset, |
3115 | + next_key.objectid, next_key.type, |
3116 | + next_key.offset); |
3117 | + ret = -EUCLEAN; |
3118 | + goto out; |
3119 | + } |
3120 | + } |
3121 | +out: |
3122 | + return ret; |
3123 | +} |
3124 | diff --git a/fs/btrfs/tree-checker.h b/fs/btrfs/tree-checker.h |
3125 | new file mode 100644 |
3126 | index 000000000000..3d53e8d6fda0 |
3127 | --- /dev/null |
3128 | +++ b/fs/btrfs/tree-checker.h |
3129 | @@ -0,0 +1,38 @@ |
3130 | +/* |
3131 | + * Copyright (C) Qu Wenruo 2017. All rights reserved. |
3132 | + * |
3133 | + * This program is free software; you can redistribute it and/or |
3134 | + * modify it under the terms of the GNU General Public |
3135 | + * License v2 as published by the Free Software Foundation. |
3136 | + * |
3137 | + * This program is distributed in the hope that it will be useful, |
3138 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3139 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3140 | + * General Public License for more details. |
3141 | + * |
3142 | + * You should have received a copy of the GNU General Public |
3143 | + * License along with this program. |
3144 | + */ |
3145 | + |
3146 | +#ifndef __BTRFS_TREE_CHECKER__ |
3147 | +#define __BTRFS_TREE_CHECKER__ |
3148 | + |
3149 | +#include "ctree.h" |
3150 | +#include "extent_io.h" |
3151 | + |
3152 | +/* |
3153 | + * Comprehensive leaf checker. |
3154 | + * Will check not only the item pointers, but also every possible member |
3155 | + * in item data. |
3156 | + */ |
3157 | +int btrfs_check_leaf_full(struct btrfs_root *root, struct extent_buffer *leaf); |
3158 | + |
3159 | +/* |
3160 | + * Less strict leaf checker. |
3161 | + * Will only check item pointers, not reading item data. |
3162 | + */ |
3163 | +int btrfs_check_leaf_relaxed(struct btrfs_root *root, |
3164 | + struct extent_buffer *leaf); |
3165 | +int btrfs_check_node(struct btrfs_root *root, struct extent_buffer *node); |
3166 | + |
3167 | +#endif |
3168 | diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c |
3169 | index 76017e1b3c0f..5aa2749eaf42 100644 |
3170 | --- a/fs/btrfs/volumes.c |
3171 | +++ b/fs/btrfs/volumes.c |
3172 | @@ -4656,7 +4656,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, |
3173 | |
3174 | if (type & BTRFS_BLOCK_GROUP_DATA) { |
3175 | max_stripe_size = SZ_1G; |
3176 | - max_chunk_size = 10 * max_stripe_size; |
3177 | + max_chunk_size = BTRFS_MAX_DATA_CHUNK_SIZE; |
3178 | if (!devs_max) |
3179 | devs_max = BTRFS_MAX_DEVS(info->chunk_root); |
3180 | } else if (type & BTRFS_BLOCK_GROUP_METADATA) { |
3181 | @@ -6370,6 +6370,8 @@ static int btrfs_check_chunk_valid(struct btrfs_root *root, |
3182 | u16 num_stripes; |
3183 | u16 sub_stripes; |
3184 | u64 type; |
3185 | + u64 features; |
3186 | + bool mixed = false; |
3187 | |
3188 | length = btrfs_chunk_length(leaf, chunk); |
3189 | stripe_len = btrfs_chunk_stripe_len(leaf, chunk); |
3190 | @@ -6410,6 +6412,32 @@ static int btrfs_check_chunk_valid(struct btrfs_root *root, |
3191 | btrfs_chunk_type(leaf, chunk)); |
3192 | return -EIO; |
3193 | } |
3194 | + |
3195 | + if ((type & BTRFS_BLOCK_GROUP_TYPE_MASK) == 0) { |
3196 | + btrfs_err(root->fs_info, "missing chunk type flag: 0x%llx", type); |
3197 | + return -EIO; |
3198 | + } |
3199 | + |
3200 | + if ((type & BTRFS_BLOCK_GROUP_SYSTEM) && |
3201 | + (type & (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA))) { |
3202 | + btrfs_err(root->fs_info, |
3203 | + "system chunk with data or metadata type: 0x%llx", type); |
3204 | + return -EIO; |
3205 | + } |
3206 | + |
3207 | + features = btrfs_super_incompat_flags(root->fs_info->super_copy); |
3208 | + if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) |
3209 | + mixed = true; |
3210 | + |
3211 | + if (!mixed) { |
3212 | + if ((type & BTRFS_BLOCK_GROUP_METADATA) && |
3213 | + (type & BTRFS_BLOCK_GROUP_DATA)) { |
3214 | + btrfs_err(root->fs_info, |
3215 | + "mixed chunk type in non-mixed mode: 0x%llx", type); |
3216 | + return -EIO; |
3217 | + } |
3218 | + } |
3219 | + |
3220 | if ((type & BTRFS_BLOCK_GROUP_RAID10 && sub_stripes != 2) || |
3221 | (type & BTRFS_BLOCK_GROUP_RAID1 && num_stripes < 1) || |
3222 | (type & BTRFS_BLOCK_GROUP_RAID5 && num_stripes < 2) || |
3223 | diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h |
3224 | index 09ed29c67848..9c09aa29d6bd 100644 |
3225 | --- a/fs/btrfs/volumes.h |
3226 | +++ b/fs/btrfs/volumes.h |
3227 | @@ -24,6 +24,8 @@ |
3228 | #include <linux/btrfs.h> |
3229 | #include "async-thread.h" |
3230 | |
3231 | +#define BTRFS_MAX_DATA_CHUNK_SIZE (10ULL * SZ_1G) |
3232 | + |
3233 | extern struct mutex uuid_mutex; |
3234 | |
3235 | #define BTRFS_STRIPE_LEN SZ_64K |
3236 | diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c |
3237 | index 3d2639c30018..6cbd0d805c9d 100644 |
3238 | --- a/fs/ceph/mds_client.c |
3239 | +++ b/fs/ceph/mds_client.c |
3240 | @@ -3983,14 +3983,24 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, |
3241 | return auth; |
3242 | } |
3243 | |
3244 | +static int add_authorizer_challenge(struct ceph_connection *con, |
3245 | + void *challenge_buf, int challenge_buf_len) |
3246 | +{ |
3247 | + struct ceph_mds_session *s = con->private; |
3248 | + struct ceph_mds_client *mdsc = s->s_mdsc; |
3249 | + struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth; |
3250 | + |
3251 | + return ceph_auth_add_authorizer_challenge(ac, s->s_auth.authorizer, |
3252 | + challenge_buf, challenge_buf_len); |
3253 | +} |
3254 | |
3255 | -static int verify_authorizer_reply(struct ceph_connection *con, int len) |
3256 | +static int verify_authorizer_reply(struct ceph_connection *con) |
3257 | { |
3258 | struct ceph_mds_session *s = con->private; |
3259 | struct ceph_mds_client *mdsc = s->s_mdsc; |
3260 | struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth; |
3261 | |
3262 | - return ceph_auth_verify_authorizer_reply(ac, s->s_auth.authorizer, len); |
3263 | + return ceph_auth_verify_authorizer_reply(ac, s->s_auth.authorizer); |
3264 | } |
3265 | |
3266 | static int invalidate_authorizer(struct ceph_connection *con) |
3267 | @@ -4046,6 +4056,7 @@ static const struct ceph_connection_operations mds_con_ops = { |
3268 | .put = con_put, |
3269 | .dispatch = dispatch, |
3270 | .get_authorizer = get_authorizer, |
3271 | + .add_authorizer_challenge = add_authorizer_challenge, |
3272 | .verify_authorizer_reply = verify_authorizer_reply, |
3273 | .invalidate_authorizer = invalidate_authorizer, |
3274 | .peer_reset = peer_reset, |
3275 | diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c |
3276 | index aee2a066a446..0b061bbf1639 100644 |
3277 | --- a/fs/f2fs/checkpoint.c |
3278 | +++ b/fs/f2fs/checkpoint.c |
3279 | @@ -69,6 +69,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index, |
3280 | .old_blkaddr = index, |
3281 | .new_blkaddr = index, |
3282 | .encrypted_page = NULL, |
3283 | + .is_meta = is_meta, |
3284 | }; |
3285 | |
3286 | if (unlikely(!is_meta)) |
3287 | @@ -85,8 +86,10 @@ repeat: |
3288 | fio.page = page; |
3289 | |
3290 | if (f2fs_submit_page_bio(&fio)) { |
3291 | - f2fs_put_page(page, 1); |
3292 | - goto repeat; |
3293 | + memset(page_address(page), 0, PAGE_SIZE); |
3294 | + f2fs_stop_checkpoint(sbi, false); |
3295 | + f2fs_bug_on(sbi, 1); |
3296 | + return page; |
3297 | } |
3298 | |
3299 | lock_page(page); |
3300 | @@ -117,7 +120,8 @@ struct page *get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index) |
3301 | return __get_meta_page(sbi, index, false); |
3302 | } |
3303 | |
3304 | -bool is_valid_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr, int type) |
3305 | +bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, |
3306 | + block_t blkaddr, int type) |
3307 | { |
3308 | switch (type) { |
3309 | case META_NAT: |
3310 | @@ -137,8 +141,20 @@ bool is_valid_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr, int type) |
3311 | return false; |
3312 | break; |
3313 | case META_POR: |
3314 | + case DATA_GENERIC: |
3315 | if (unlikely(blkaddr >= MAX_BLKADDR(sbi) || |
3316 | - blkaddr < MAIN_BLKADDR(sbi))) |
3317 | + blkaddr < MAIN_BLKADDR(sbi))) { |
3318 | + if (type == DATA_GENERIC) { |
3319 | + f2fs_msg(sbi->sb, KERN_WARNING, |
3320 | + "access invalid blkaddr:%u", blkaddr); |
3321 | + WARN_ON(1); |
3322 | + } |
3323 | + return false; |
3324 | + } |
3325 | + break; |
3326 | + case META_GENERIC: |
3327 | + if (unlikely(blkaddr < SEG0_BLKADDR(sbi) || |
3328 | + blkaddr >= MAIN_BLKADDR(sbi))) |
3329 | return false; |
3330 | break; |
3331 | default: |
3332 | @@ -162,6 +178,7 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, |
3333 | .op = REQ_OP_READ, |
3334 | .op_flags = sync ? (READ_SYNC | REQ_META | REQ_PRIO) : REQ_RAHEAD, |
3335 | .encrypted_page = NULL, |
3336 | + .is_meta = (type != META_POR), |
3337 | }; |
3338 | struct blk_plug plug; |
3339 | |
3340 | @@ -171,7 +188,7 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, |
3341 | blk_start_plug(&plug); |
3342 | for (; nrpages-- > 0; blkno++) { |
3343 | |
3344 | - if (!is_valid_blkaddr(sbi, blkno, type)) |
3345 | + if (!f2fs_is_valid_blkaddr(sbi, blkno, type)) |
3346 | goto out; |
3347 | |
3348 | switch (type) { |
3349 | @@ -706,6 +723,14 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, |
3350 | &cp_page_1, version); |
3351 | if (err) |
3352 | return NULL; |
3353 | + |
3354 | + if (le32_to_cpu(cp_block->cp_pack_total_block_count) > |
3355 | + sbi->blocks_per_seg) { |
3356 | + f2fs_msg(sbi->sb, KERN_WARNING, |
3357 | + "invalid cp_pack_total_block_count:%u", |
3358 | + le32_to_cpu(cp_block->cp_pack_total_block_count)); |
3359 | + goto invalid_cp; |
3360 | + } |
3361 | pre_version = *version; |
3362 | |
3363 | cp_addr += le32_to_cpu(cp_block->cp_pack_total_block_count) - 1; |
3364 | @@ -769,15 +794,15 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) |
3365 | cp_block = (struct f2fs_checkpoint *)page_address(cur_page); |
3366 | memcpy(sbi->ckpt, cp_block, blk_size); |
3367 | |
3368 | - /* Sanity checking of checkpoint */ |
3369 | - if (sanity_check_ckpt(sbi)) |
3370 | - goto fail_no_cp; |
3371 | - |
3372 | if (cur_page == cp1) |
3373 | sbi->cur_cp_pack = 1; |
3374 | else |
3375 | sbi->cur_cp_pack = 2; |
3376 | |
3377 | + /* Sanity checking of checkpoint */ |
3378 | + if (sanity_check_ckpt(sbi)) |
3379 | + goto free_fail_no_cp; |
3380 | + |
3381 | if (cp_blks <= 1) |
3382 | goto done; |
3383 | |
3384 | @@ -799,6 +824,9 @@ done: |
3385 | f2fs_put_page(cp2, 1); |
3386 | return 0; |
3387 | |
3388 | +free_fail_no_cp: |
3389 | + f2fs_put_page(cp1, 1); |
3390 | + f2fs_put_page(cp2, 1); |
3391 | fail_no_cp: |
3392 | kfree(sbi->ckpt); |
3393 | return -EINVAL; |
3394 | diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c |
3395 | index ae354ac67da1..9041805096e0 100644 |
3396 | --- a/fs/f2fs/data.c |
3397 | +++ b/fs/f2fs/data.c |
3398 | @@ -240,6 +240,10 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio) |
3399 | struct page *page = fio->encrypted_page ? |
3400 | fio->encrypted_page : fio->page; |
3401 | |
3402 | + if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr, |
3403 | + __is_meta_io(fio) ? META_GENERIC : DATA_GENERIC)) |
3404 | + return -EFAULT; |
3405 | + |
3406 | trace_f2fs_submit_page_bio(page, fio); |
3407 | f2fs_trace_ios(fio, 0); |
3408 | |
3409 | @@ -266,9 +270,9 @@ void f2fs_submit_page_mbio(struct f2fs_io_info *fio) |
3410 | |
3411 | io = is_read ? &sbi->read_io : &sbi->write_io[btype]; |
3412 | |
3413 | - if (fio->old_blkaddr != NEW_ADDR) |
3414 | - verify_block_addr(sbi, fio->old_blkaddr); |
3415 | - verify_block_addr(sbi, fio->new_blkaddr); |
3416 | + if (__is_valid_data_blkaddr(fio->old_blkaddr)) |
3417 | + verify_block_addr(fio, fio->old_blkaddr); |
3418 | + verify_block_addr(fio, fio->new_blkaddr); |
3419 | |
3420 | down_write(&io->io_rwsem); |
3421 | |
3422 | @@ -722,7 +726,13 @@ next_dnode: |
3423 | next_block: |
3424 | blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); |
3425 | |
3426 | - if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) { |
3427 | + if (__is_valid_data_blkaddr(blkaddr) && |
3428 | + !f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC)) { |
3429 | + err = -EFAULT; |
3430 | + goto sync_out; |
3431 | + } |
3432 | + |
3433 | + if (!is_valid_data_blkaddr(sbi, blkaddr)) { |
3434 | if (create) { |
3435 | if (unlikely(f2fs_cp_error(sbi))) { |
3436 | err = -EIO; |
3437 | @@ -985,6 +995,9 @@ static struct bio *f2fs_grab_bio(struct inode *inode, block_t blkaddr, |
3438 | struct block_device *bdev = sbi->sb->s_bdev; |
3439 | struct bio *bio; |
3440 | |
3441 | + if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC)) |
3442 | + return ERR_PTR(-EFAULT); |
3443 | + |
3444 | if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) { |
3445 | ctx = fscrypt_get_ctx(inode, GFP_NOFS); |
3446 | if (IS_ERR(ctx)) |
3447 | @@ -1084,6 +1097,10 @@ got_it: |
3448 | SetPageUptodate(page); |
3449 | goto confused; |
3450 | } |
3451 | + |
3452 | + if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), block_nr, |
3453 | + DATA_GENERIC)) |
3454 | + goto set_error_page; |
3455 | } else { |
3456 | zero_user_segment(page, 0, PAGE_SIZE); |
3457 | if (!PageUptodate(page)) |
3458 | @@ -1212,11 +1229,17 @@ retry_encrypt: |
3459 | |
3460 | set_page_writeback(page); |
3461 | |
3462 | + if (__is_valid_data_blkaddr(fio->old_blkaddr) && |
3463 | + !f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr, |
3464 | + DATA_GENERIC)) { |
3465 | + err = -EFAULT; |
3466 | + goto out_writepage; |
3467 | + } |
3468 | /* |
3469 | * If current allocation needs SSR, |
3470 | * it had better in-place writes for updated data. |
3471 | */ |
3472 | - if (unlikely(fio->old_blkaddr != NEW_ADDR && |
3473 | + if (unlikely(is_valid_data_blkaddr(fio->sbi, fio->old_blkaddr) && |
3474 | !is_cold_data(page) && |
3475 | !IS_ATOMIC_WRITTEN_PAGE(page) && |
3476 | need_inplace_update(inode))) { |
3477 | diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h |
3478 | index 88e111ab068b..9c380885b0fc 100644 |
3479 | --- a/fs/f2fs/f2fs.h |
3480 | +++ b/fs/f2fs/f2fs.h |
3481 | @@ -145,7 +145,7 @@ struct cp_control { |
3482 | }; |
3483 | |
3484 | /* |
3485 | - * For CP/NAT/SIT/SSA readahead |
3486 | + * indicate meta/data type |
3487 | */ |
3488 | enum { |
3489 | META_CP, |
3490 | @@ -153,6 +153,8 @@ enum { |
3491 | META_SIT, |
3492 | META_SSA, |
3493 | META_POR, |
3494 | + DATA_GENERIC, |
3495 | + META_GENERIC, |
3496 | }; |
3497 | |
3498 | /* for the list of ino */ |
3499 | @@ -694,6 +696,7 @@ struct f2fs_io_info { |
3500 | block_t old_blkaddr; /* old block address before Cow */ |
3501 | struct page *page; /* page to be written */ |
3502 | struct page *encrypted_page; /* encrypted page */ |
3503 | + bool is_meta; /* indicate borrow meta inode mapping or not */ |
3504 | }; |
3505 | |
3506 | #define is_read_io(rw) (rw == READ) |
3507 | @@ -1929,6 +1932,39 @@ static inline void *f2fs_kvzalloc(size_t size, gfp_t flags) |
3508 | (pgofs - ADDRS_PER_INODE(inode) + ADDRS_PER_BLOCK) / \ |
3509 | ADDRS_PER_BLOCK * ADDRS_PER_BLOCK + ADDRS_PER_INODE(inode)) |
3510 | |
3511 | +#define __is_meta_io(fio) (PAGE_TYPE_OF_BIO(fio->type) == META && \ |
3512 | + (!is_read_io(fio->op) || fio->is_meta)) |
3513 | + |
3514 | +bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, |
3515 | + block_t blkaddr, int type); |
3516 | +void f2fs_msg(struct super_block *sb, const char *level, const char *fmt, ...); |
3517 | +static inline void verify_blkaddr(struct f2fs_sb_info *sbi, |
3518 | + block_t blkaddr, int type) |
3519 | +{ |
3520 | + if (!f2fs_is_valid_blkaddr(sbi, blkaddr, type)) { |
3521 | + f2fs_msg(sbi->sb, KERN_ERR, |
3522 | + "invalid blkaddr: %u, type: %d, run fsck to fix.", |
3523 | + blkaddr, type); |
3524 | + f2fs_bug_on(sbi, 1); |
3525 | + } |
3526 | +} |
3527 | + |
3528 | +static inline bool __is_valid_data_blkaddr(block_t blkaddr) |
3529 | +{ |
3530 | + if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) |
3531 | + return false; |
3532 | + return true; |
3533 | +} |
3534 | + |
3535 | +static inline bool is_valid_data_blkaddr(struct f2fs_sb_info *sbi, |
3536 | + block_t blkaddr) |
3537 | +{ |
3538 | + if (!__is_valid_data_blkaddr(blkaddr)) |
3539 | + return false; |
3540 | + verify_blkaddr(sbi, blkaddr, DATA_GENERIC); |
3541 | + return true; |
3542 | +} |
3543 | + |
3544 | /* |
3545 | * file.c |
3546 | */ |
3547 | @@ -2114,7 +2150,8 @@ void f2fs_stop_checkpoint(struct f2fs_sb_info *, bool); |
3548 | struct page *grab_meta_page(struct f2fs_sb_info *, pgoff_t); |
3549 | struct page *get_meta_page(struct f2fs_sb_info *, pgoff_t); |
3550 | struct page *get_tmp_page(struct f2fs_sb_info *, pgoff_t); |
3551 | -bool is_valid_blkaddr(struct f2fs_sb_info *, block_t, int); |
3552 | +bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, |
3553 | + block_t blkaddr, int type); |
3554 | int ra_meta_pages(struct f2fs_sb_info *, block_t, int, int, bool); |
3555 | void ra_meta_pages_cond(struct f2fs_sb_info *, pgoff_t); |
3556 | long sync_meta_pages(struct f2fs_sb_info *, enum page_type, long); |
3557 | diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c |
3558 | index 594e6e20d6dd..b768f495603e 100644 |
3559 | --- a/fs/f2fs/file.c |
3560 | +++ b/fs/f2fs/file.c |
3561 | @@ -310,13 +310,13 @@ static pgoff_t __get_first_dirty_index(struct address_space *mapping, |
3562 | return pgofs; |
3563 | } |
3564 | |
3565 | -static bool __found_offset(block_t blkaddr, pgoff_t dirty, pgoff_t pgofs, |
3566 | - int whence) |
3567 | +static bool __found_offset(struct f2fs_sb_info *sbi, block_t blkaddr, |
3568 | + pgoff_t dirty, pgoff_t pgofs, int whence) |
3569 | { |
3570 | switch (whence) { |
3571 | case SEEK_DATA: |
3572 | if ((blkaddr == NEW_ADDR && dirty == pgofs) || |
3573 | - (blkaddr != NEW_ADDR && blkaddr != NULL_ADDR)) |
3574 | + is_valid_data_blkaddr(sbi, blkaddr)) |
3575 | return true; |
3576 | break; |
3577 | case SEEK_HOLE: |
3578 | @@ -378,7 +378,15 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence) |
3579 | block_t blkaddr; |
3580 | blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); |
3581 | |
3582 | - if (__found_offset(blkaddr, dirty, pgofs, whence)) { |
3583 | + if (__is_valid_data_blkaddr(blkaddr) && |
3584 | + !f2fs_is_valid_blkaddr(F2FS_I_SB(inode), |
3585 | + blkaddr, DATA_GENERIC)) { |
3586 | + f2fs_put_dnode(&dn); |
3587 | + goto fail; |
3588 | + } |
3589 | + |
3590 | + if (__found_offset(F2FS_I_SB(inode), blkaddr, dirty, |
3591 | + pgofs, whence)) { |
3592 | f2fs_put_dnode(&dn); |
3593 | goto found; |
3594 | } |
3595 | @@ -481,6 +489,11 @@ int truncate_data_blocks_range(struct dnode_of_data *dn, int count) |
3596 | |
3597 | dn->data_blkaddr = NULL_ADDR; |
3598 | set_data_blkaddr(dn); |
3599 | + |
3600 | + if (__is_valid_data_blkaddr(blkaddr) && |
3601 | + !f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC)) |
3602 | + continue; |
3603 | + |
3604 | invalidate_blocks(sbi, blkaddr); |
3605 | if (dn->ofs_in_node == 0 && IS_INODE(dn->node_page)) |
3606 | clear_inode_flag(dn->inode, FI_FIRST_BLOCK_WRITTEN); |
3607 | diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c |
3608 | index d7369895a78a..1de02c31756b 100644 |
3609 | --- a/fs/f2fs/inode.c |
3610 | +++ b/fs/f2fs/inode.c |
3611 | @@ -59,13 +59,16 @@ static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri) |
3612 | } |
3613 | } |
3614 | |
3615 | -static bool __written_first_block(struct f2fs_inode *ri) |
3616 | +static int __written_first_block(struct f2fs_sb_info *sbi, |
3617 | + struct f2fs_inode *ri) |
3618 | { |
3619 | block_t addr = le32_to_cpu(ri->i_addr[0]); |
3620 | |
3621 | - if (addr != NEW_ADDR && addr != NULL_ADDR) |
3622 | - return true; |
3623 | - return false; |
3624 | + if (!__is_valid_data_blkaddr(addr)) |
3625 | + return 1; |
3626 | + if (!f2fs_is_valid_blkaddr(sbi, addr, DATA_GENERIC)) |
3627 | + return -EFAULT; |
3628 | + return 0; |
3629 | } |
3630 | |
3631 | static void __set_inode_rdev(struct inode *inode, struct f2fs_inode *ri) |
3632 | @@ -103,12 +106,57 @@ static void __recover_inline_status(struct inode *inode, struct page *ipage) |
3633 | return; |
3634 | } |
3635 | |
3636 | +static bool sanity_check_inode(struct inode *inode, struct page *node_page) |
3637 | +{ |
3638 | + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
3639 | + unsigned long long iblocks; |
3640 | + |
3641 | + iblocks = le64_to_cpu(F2FS_INODE(node_page)->i_blocks); |
3642 | + if (!iblocks) { |
3643 | + set_sbi_flag(sbi, SBI_NEED_FSCK); |
3644 | + f2fs_msg(sbi->sb, KERN_WARNING, |
3645 | + "%s: corrupted inode i_blocks i_ino=%lx iblocks=%llu, " |
3646 | + "run fsck to fix.", |
3647 | + __func__, inode->i_ino, iblocks); |
3648 | + return false; |
3649 | + } |
3650 | + |
3651 | + if (ino_of_node(node_page) != nid_of_node(node_page)) { |
3652 | + set_sbi_flag(sbi, SBI_NEED_FSCK); |
3653 | + f2fs_msg(sbi->sb, KERN_WARNING, |
3654 | + "%s: corrupted inode footer i_ino=%lx, ino,nid: " |
3655 | + "[%u, %u] run fsck to fix.", |
3656 | + __func__, inode->i_ino, |
3657 | + ino_of_node(node_page), nid_of_node(node_page)); |
3658 | + return false; |
3659 | + } |
3660 | + |
3661 | + if (F2FS_I(inode)->extent_tree) { |
3662 | + struct extent_info *ei = &F2FS_I(inode)->extent_tree->largest; |
3663 | + |
3664 | + if (ei->len && |
3665 | + (!f2fs_is_valid_blkaddr(sbi, ei->blk, DATA_GENERIC) || |
3666 | + !f2fs_is_valid_blkaddr(sbi, ei->blk + ei->len - 1, |
3667 | + DATA_GENERIC))) { |
3668 | + set_sbi_flag(sbi, SBI_NEED_FSCK); |
3669 | + f2fs_msg(sbi->sb, KERN_WARNING, |
3670 | + "%s: inode (ino=%lx) extent info [%u, %u, %u] " |
3671 | + "is incorrect, run fsck to fix", |
3672 | + __func__, inode->i_ino, |
3673 | + ei->blk, ei->fofs, ei->len); |
3674 | + return false; |
3675 | + } |
3676 | + } |
3677 | + return true; |
3678 | +} |
3679 | + |
3680 | static int do_read_inode(struct inode *inode) |
3681 | { |
3682 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
3683 | struct f2fs_inode_info *fi = F2FS_I(inode); |
3684 | struct page *node_page; |
3685 | struct f2fs_inode *ri; |
3686 | + int err; |
3687 | |
3688 | /* Check if ino is within scope */ |
3689 | if (check_nid_range(sbi, inode->i_ino)) { |
3690 | @@ -152,6 +200,11 @@ static int do_read_inode(struct inode *inode) |
3691 | |
3692 | get_inline_info(inode, ri); |
3693 | |
3694 | + if (!sanity_check_inode(inode, node_page)) { |
3695 | + f2fs_put_page(node_page, 1); |
3696 | + return -EINVAL; |
3697 | + } |
3698 | + |
3699 | /* check data exist */ |
3700 | if (f2fs_has_inline_data(inode) && !f2fs_exist_data(inode)) |
3701 | __recover_inline_status(inode, node_page); |
3702 | @@ -159,7 +212,12 @@ static int do_read_inode(struct inode *inode) |
3703 | /* get rdev by using inline_info */ |
3704 | __get_inode_rdev(inode, ri); |
3705 | |
3706 | - if (__written_first_block(ri)) |
3707 | + err = __written_first_block(sbi, ri); |
3708 | + if (err < 0) { |
3709 | + f2fs_put_page(node_page, 1); |
3710 | + return err; |
3711 | + } |
3712 | + if (!err) |
3713 | set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN); |
3714 | |
3715 | if (!need_inode_block_update(sbi, inode->i_ino)) |
3716 | diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c |
3717 | index addff6a3b176..f4fe54047fb7 100644 |
3718 | --- a/fs/f2fs/node.c |
3719 | +++ b/fs/f2fs/node.c |
3720 | @@ -304,8 +304,7 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, |
3721 | new_blkaddr == NULL_ADDR); |
3722 | f2fs_bug_on(sbi, nat_get_blkaddr(e) == NEW_ADDR && |
3723 | new_blkaddr == NEW_ADDR); |
3724 | - f2fs_bug_on(sbi, nat_get_blkaddr(e) != NEW_ADDR && |
3725 | - nat_get_blkaddr(e) != NULL_ADDR && |
3726 | + f2fs_bug_on(sbi, is_valid_data_blkaddr(sbi, nat_get_blkaddr(e)) && |
3727 | new_blkaddr == NEW_ADDR); |
3728 | |
3729 | /* increment version no as node is removed */ |
3730 | @@ -320,7 +319,7 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, |
3731 | |
3732 | /* change address */ |
3733 | nat_set_blkaddr(e, new_blkaddr); |
3734 | - if (new_blkaddr == NEW_ADDR || new_blkaddr == NULL_ADDR) |
3735 | + if (!is_valid_data_blkaddr(sbi, new_blkaddr)) |
3736 | set_nat_flag(e, IS_CHECKPOINTED, false); |
3737 | __set_nat_cache_dirty(nm_i, e); |
3738 | |
3739 | @@ -1606,6 +1605,12 @@ static int f2fs_write_node_page(struct page *page, |
3740 | return 0; |
3741 | } |
3742 | |
3743 | + if (__is_valid_data_blkaddr(ni.blk_addr) && |
3744 | + !f2fs_is_valid_blkaddr(sbi, ni.blk_addr, DATA_GENERIC)) { |
3745 | + up_read(&sbi->node_write); |
3746 | + goto redirty_out; |
3747 | + } |
3748 | + |
3749 | set_page_writeback(page); |
3750 | fio.old_blkaddr = ni.blk_addr; |
3751 | write_node_page(nid, &fio); |
3752 | @@ -1704,8 +1709,9 @@ static void __del_from_free_nid_list(struct f2fs_nm_info *nm_i, |
3753 | static int add_free_nid(struct f2fs_sb_info *sbi, nid_t nid, bool build) |
3754 | { |
3755 | struct f2fs_nm_info *nm_i = NM_I(sbi); |
3756 | - struct free_nid *i; |
3757 | + struct free_nid *i, *e; |
3758 | struct nat_entry *ne; |
3759 | + int err = -EINVAL; |
3760 | |
3761 | if (!available_free_memory(sbi, FREE_NIDS)) |
3762 | return -1; |
3763 | @@ -1714,35 +1720,58 @@ static int add_free_nid(struct f2fs_sb_info *sbi, nid_t nid, bool build) |
3764 | if (unlikely(nid == 0)) |
3765 | return 0; |
3766 | |
3767 | - if (build) { |
3768 | - /* do not add allocated nids */ |
3769 | - ne = __lookup_nat_cache(nm_i, nid); |
3770 | - if (ne && (!get_nat_flag(ne, IS_CHECKPOINTED) || |
3771 | - nat_get_blkaddr(ne) != NULL_ADDR)) |
3772 | - return 0; |
3773 | - } |
3774 | - |
3775 | i = f2fs_kmem_cache_alloc(free_nid_slab, GFP_NOFS); |
3776 | i->nid = nid; |
3777 | i->state = NID_NEW; |
3778 | |
3779 | - if (radix_tree_preload(GFP_NOFS)) { |
3780 | - kmem_cache_free(free_nid_slab, i); |
3781 | - return 0; |
3782 | - } |
3783 | + if (radix_tree_preload(GFP_NOFS)) |
3784 | + goto err; |
3785 | |
3786 | spin_lock(&nm_i->free_nid_list_lock); |
3787 | - if (radix_tree_insert(&nm_i->free_nid_root, i->nid, i)) { |
3788 | - spin_unlock(&nm_i->free_nid_list_lock); |
3789 | - radix_tree_preload_end(); |
3790 | - kmem_cache_free(free_nid_slab, i); |
3791 | - return 0; |
3792 | + |
3793 | + if (build) { |
3794 | + /* |
3795 | + * Thread A Thread B |
3796 | + * - f2fs_create |
3797 | + * - f2fs_new_inode |
3798 | + * - alloc_nid |
3799 | + * - __insert_nid_to_list(ALLOC_NID_LIST) |
3800 | + * - f2fs_balance_fs_bg |
3801 | + * - build_free_nids |
3802 | + * - __build_free_nids |
3803 | + * - scan_nat_page |
3804 | + * - add_free_nid |
3805 | + * - __lookup_nat_cache |
3806 | + * - f2fs_add_link |
3807 | + * - init_inode_metadata |
3808 | + * - new_inode_page |
3809 | + * - new_node_page |
3810 | + * - set_node_addr |
3811 | + * - alloc_nid_done |
3812 | + * - __remove_nid_from_list(ALLOC_NID_LIST) |
3813 | + * - __insert_nid_to_list(FREE_NID_LIST) |
3814 | + */ |
3815 | + ne = __lookup_nat_cache(nm_i, nid); |
3816 | + if (ne && (!get_nat_flag(ne, IS_CHECKPOINTED) || |
3817 | + nat_get_blkaddr(ne) != NULL_ADDR)) |
3818 | + goto err_out; |
3819 | + |
3820 | + e = __lookup_free_nid_list(nm_i, nid); |
3821 | + if (e) |
3822 | + goto err_out; |
3823 | } |
3824 | + if (radix_tree_insert(&nm_i->free_nid_root, i->nid, i)) |
3825 | + goto err_out; |
3826 | + err = 0; |
3827 | list_add_tail(&i->list, &nm_i->free_nid_list); |
3828 | nm_i->fcnt++; |
3829 | +err_out: |
3830 | spin_unlock(&nm_i->free_nid_list_lock); |
3831 | radix_tree_preload_end(); |
3832 | - return 1; |
3833 | +err: |
3834 | + if (err) |
3835 | + kmem_cache_free(free_nid_slab, i); |
3836 | + return !err; |
3837 | } |
3838 | |
3839 | static void remove_free_nid(struct f2fs_nm_info *nm_i, nid_t nid) |
3840 | diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c |
3841 | index 98c1a63a4614..ab4cbb4be423 100644 |
3842 | --- a/fs/f2fs/recovery.c |
3843 | +++ b/fs/f2fs/recovery.c |
3844 | @@ -236,7 +236,7 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) |
3845 | while (1) { |
3846 | struct fsync_inode_entry *entry; |
3847 | |
3848 | - if (!is_valid_blkaddr(sbi, blkaddr, META_POR)) |
3849 | + if (!f2fs_is_valid_blkaddr(sbi, blkaddr, META_POR)) |
3850 | return 0; |
3851 | |
3852 | page = get_tmp_page(sbi, blkaddr); |
3853 | @@ -468,7 +468,7 @@ retry_dn: |
3854 | } |
3855 | |
3856 | /* dest is valid block, try to recover from src to dest */ |
3857 | - if (is_valid_blkaddr(sbi, dest, META_POR)) { |
3858 | + if (f2fs_is_valid_blkaddr(sbi, dest, META_POR)) { |
3859 | |
3860 | if (src == NULL_ADDR) { |
3861 | err = reserve_new_block(&dn); |
3862 | @@ -527,7 +527,7 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list, |
3863 | while (1) { |
3864 | struct fsync_inode_entry *entry; |
3865 | |
3866 | - if (!is_valid_blkaddr(sbi, blkaddr, META_POR)) |
3867 | + if (!f2fs_is_valid_blkaddr(sbi, blkaddr, META_POR)) |
3868 | break; |
3869 | |
3870 | ra_meta_pages_cond(sbi, blkaddr); |
3871 | diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c |
3872 | index 35d48ef0573c..2fb99a081de8 100644 |
3873 | --- a/fs/f2fs/segment.c |
3874 | +++ b/fs/f2fs/segment.c |
3875 | @@ -493,6 +493,9 @@ int create_flush_cmd_control(struct f2fs_sb_info *sbi) |
3876 | init_waitqueue_head(&fcc->flush_wait_queue); |
3877 | init_llist_head(&fcc->issue_list); |
3878 | SM_I(sbi)->cmd_control_info = fcc; |
3879 | + if (!test_opt(sbi, FLUSH_MERGE)) |
3880 | + return err; |
3881 | + |
3882 | fcc->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi, |
3883 | "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev)); |
3884 | if (IS_ERR(fcc->f2fs_issue_flush)) { |
3885 | @@ -941,7 +944,7 @@ bool is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr) |
3886 | struct seg_entry *se; |
3887 | bool is_cp = false; |
3888 | |
3889 | - if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) |
3890 | + if (!is_valid_data_blkaddr(sbi, blkaddr)) |
3891 | return true; |
3892 | |
3893 | mutex_lock(&sit_i->sentry_lock); |
3894 | @@ -1665,7 +1668,7 @@ void f2fs_wait_on_encrypted_page_writeback(struct f2fs_sb_info *sbi, |
3895 | { |
3896 | struct page *cpage; |
3897 | |
3898 | - if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) |
3899 | + if (!is_valid_data_blkaddr(sbi, blkaddr)) |
3900 | return; |
3901 | |
3902 | cpage = find_lock_page(META_MAPPING(sbi), blkaddr); |
3903 | @@ -2319,7 +2322,7 @@ static int build_curseg(struct f2fs_sb_info *sbi) |
3904 | return restore_curseg_summaries(sbi); |
3905 | } |
3906 | |
3907 | -static void build_sit_entries(struct f2fs_sb_info *sbi) |
3908 | +static int build_sit_entries(struct f2fs_sb_info *sbi) |
3909 | { |
3910 | struct sit_info *sit_i = SIT_I(sbi); |
3911 | struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA); |
3912 | @@ -2330,6 +2333,7 @@ static void build_sit_entries(struct f2fs_sb_info *sbi) |
3913 | unsigned int i, start, end; |
3914 | unsigned int readed, start_blk = 0; |
3915 | int nrpages = MAX_BIO_BLOCKS(sbi) * 8; |
3916 | + int err = 0; |
3917 | |
3918 | do { |
3919 | readed = ra_meta_pages(sbi, start_blk, nrpages, META_SIT, true); |
3920 | @@ -2347,7 +2351,9 @@ static void build_sit_entries(struct f2fs_sb_info *sbi) |
3921 | sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)]; |
3922 | f2fs_put_page(page, 1); |
3923 | |
3924 | - check_block_count(sbi, start, &sit); |
3925 | + err = check_block_count(sbi, start, &sit); |
3926 | + if (err) |
3927 | + return err; |
3928 | seg_info_from_raw_sit(se, &sit); |
3929 | |
3930 | /* build discard map only one time */ |
3931 | @@ -2370,12 +2376,23 @@ static void build_sit_entries(struct f2fs_sb_info *sbi) |
3932 | unsigned int old_valid_blocks; |
3933 | |
3934 | start = le32_to_cpu(segno_in_journal(journal, i)); |
3935 | + if (start >= MAIN_SEGS(sbi)) { |
3936 | + f2fs_msg(sbi->sb, KERN_ERR, |
3937 | + "Wrong journal entry on segno %u", |
3938 | + start); |
3939 | + set_sbi_flag(sbi, SBI_NEED_FSCK); |
3940 | + err = -EINVAL; |
3941 | + break; |
3942 | + } |
3943 | + |
3944 | se = &sit_i->sentries[start]; |
3945 | sit = sit_in_journal(journal, i); |
3946 | |
3947 | old_valid_blocks = se->valid_blocks; |
3948 | |
3949 | - check_block_count(sbi, start, &sit); |
3950 | + err = check_block_count(sbi, start, &sit); |
3951 | + if (err) |
3952 | + break; |
3953 | seg_info_from_raw_sit(se, &sit); |
3954 | |
3955 | if (f2fs_discard_en(sbi)) { |
3956 | @@ -2390,6 +2407,7 @@ static void build_sit_entries(struct f2fs_sb_info *sbi) |
3957 | se->valid_blocks - old_valid_blocks; |
3958 | } |
3959 | up_read(&curseg->journal_rwsem); |
3960 | + return err; |
3961 | } |
3962 | |
3963 | static void init_free_segmap(struct f2fs_sb_info *sbi) |
3964 | @@ -2539,7 +2557,7 @@ int build_segment_manager(struct f2fs_sb_info *sbi) |
3965 | |
3966 | INIT_LIST_HEAD(&sm_info->sit_entry_set); |
3967 | |
3968 | - if (test_opt(sbi, FLUSH_MERGE) && !f2fs_readonly(sbi->sb)) { |
3969 | + if (!f2fs_readonly(sbi->sb)) { |
3970 | err = create_flush_cmd_control(sbi); |
3971 | if (err) |
3972 | return err; |
3973 | @@ -2556,7 +2574,9 @@ int build_segment_manager(struct f2fs_sb_info *sbi) |
3974 | return err; |
3975 | |
3976 | /* reinit free segmap based on SIT */ |
3977 | - build_sit_entries(sbi); |
3978 | + err = build_sit_entries(sbi); |
3979 | + if (err) |
3980 | + return err; |
3981 | |
3982 | init_free_segmap(sbi); |
3983 | err = build_dirty_segmap(sbi); |
3984 | diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h |
3985 | index 3d9b9e98c4c2..893723978f5e 100644 |
3986 | --- a/fs/f2fs/segment.h |
3987 | +++ b/fs/f2fs/segment.h |
3988 | @@ -18,6 +18,8 @@ |
3989 | #define DEF_RECLAIM_PREFREE_SEGMENTS 5 /* 5% over total segments */ |
3990 | #define DEF_MAX_RECLAIM_PREFREE_SEGMENTS 4096 /* 8GB in maximum */ |
3991 | |
3992 | +#define F2FS_MIN_SEGMENTS 9 /* SB + 2 (CP + SIT + NAT) + SSA + MAIN */ |
3993 | + |
3994 | /* L: Logical segment # in volume, R: Relative segment # in main area */ |
3995 | #define GET_L2R_SEGNO(free_i, segno) (segno - free_i->start_segno) |
3996 | #define GET_R2L_SEGNO(free_i, segno) (segno + free_i->start_segno) |
3997 | @@ -47,13 +49,19 @@ |
3998 | (secno == CURSEG_I(sbi, CURSEG_COLD_NODE)->segno / \ |
3999 | sbi->segs_per_sec)) \ |
4000 | |
4001 | -#define MAIN_BLKADDR(sbi) (SM_I(sbi)->main_blkaddr) |
4002 | -#define SEG0_BLKADDR(sbi) (SM_I(sbi)->seg0_blkaddr) |
4003 | +#define MAIN_BLKADDR(sbi) \ |
4004 | + (SM_I(sbi) ? SM_I(sbi)->main_blkaddr : \ |
4005 | + le32_to_cpu(F2FS_RAW_SUPER(sbi)->main_blkaddr)) |
4006 | +#define SEG0_BLKADDR(sbi) \ |
4007 | + (SM_I(sbi) ? SM_I(sbi)->seg0_blkaddr : \ |
4008 | + le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment0_blkaddr)) |
4009 | |
4010 | #define MAIN_SEGS(sbi) (SM_I(sbi)->main_segments) |
4011 | #define MAIN_SECS(sbi) (sbi->total_sections) |
4012 | |
4013 | -#define TOTAL_SEGS(sbi) (SM_I(sbi)->segment_count) |
4014 | +#define TOTAL_SEGS(sbi) \ |
4015 | + (SM_I(sbi) ? SM_I(sbi)->segment_count : \ |
4016 | + le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count)) |
4017 | #define TOTAL_BLKS(sbi) (TOTAL_SEGS(sbi) << sbi->log_blocks_per_seg) |
4018 | |
4019 | #define MAX_BLKADDR(sbi) (SEG0_BLKADDR(sbi) + TOTAL_BLKS(sbi)) |
4020 | @@ -73,7 +81,7 @@ |
4021 | (GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & (sbi->blocks_per_seg - 1)) |
4022 | |
4023 | #define GET_SEGNO(sbi, blk_addr) \ |
4024 | - (((blk_addr == NULL_ADDR) || (blk_addr == NEW_ADDR)) ? \ |
4025 | + ((!is_valid_data_blkaddr(sbi, blk_addr)) ? \ |
4026 | NULL_SEGNO : GET_L2R_SEGNO(FREE_I(sbi), \ |
4027 | GET_SEGNO_FROM_SEG0(sbi, blk_addr))) |
4028 | #define GET_SECNO(sbi, segno) \ |
4029 | @@ -589,16 +597,20 @@ static inline void check_seg_range(struct f2fs_sb_info *sbi, unsigned int segno) |
4030 | f2fs_bug_on(sbi, segno > TOTAL_SEGS(sbi) - 1); |
4031 | } |
4032 | |
4033 | -static inline void verify_block_addr(struct f2fs_sb_info *sbi, block_t blk_addr) |
4034 | +static inline void verify_block_addr(struct f2fs_io_info *fio, block_t blk_addr) |
4035 | { |
4036 | - BUG_ON(blk_addr < SEG0_BLKADDR(sbi) |
4037 | - || blk_addr >= MAX_BLKADDR(sbi)); |
4038 | + struct f2fs_sb_info *sbi = fio->sbi; |
4039 | + |
4040 | + if (__is_meta_io(fio)) |
4041 | + verify_blkaddr(sbi, blk_addr, META_GENERIC); |
4042 | + else |
4043 | + verify_blkaddr(sbi, blk_addr, DATA_GENERIC); |
4044 | } |
4045 | |
4046 | /* |
4047 | * Summary block is always treated as an invalid block |
4048 | */ |
4049 | -static inline void check_block_count(struct f2fs_sb_info *sbi, |
4050 | +static inline int check_block_count(struct f2fs_sb_info *sbi, |
4051 | int segno, struct f2fs_sit_entry *raw_sit) |
4052 | { |
4053 | #ifdef CONFIG_F2FS_CHECK_FS |
4054 | @@ -620,11 +632,25 @@ static inline void check_block_count(struct f2fs_sb_info *sbi, |
4055 | cur_pos = next_pos; |
4056 | is_valid = !is_valid; |
4057 | } while (cur_pos < sbi->blocks_per_seg); |
4058 | - BUG_ON(GET_SIT_VBLOCKS(raw_sit) != valid_blocks); |
4059 | + |
4060 | + if (unlikely(GET_SIT_VBLOCKS(raw_sit) != valid_blocks)) { |
4061 | + f2fs_msg(sbi->sb, KERN_ERR, |
4062 | + "Mismatch valid blocks %d vs. %d", |
4063 | + GET_SIT_VBLOCKS(raw_sit), valid_blocks); |
4064 | + set_sbi_flag(sbi, SBI_NEED_FSCK); |
4065 | + return -EINVAL; |
4066 | + } |
4067 | #endif |
4068 | /* check segment usage, and check boundary of a given segment number */ |
4069 | - f2fs_bug_on(sbi, GET_SIT_VBLOCKS(raw_sit) > sbi->blocks_per_seg |
4070 | - || segno > TOTAL_SEGS(sbi) - 1); |
4071 | + if (unlikely(GET_SIT_VBLOCKS(raw_sit) > sbi->blocks_per_seg |
4072 | + || segno > TOTAL_SEGS(sbi) - 1)) { |
4073 | + f2fs_msg(sbi->sb, KERN_ERR, |
4074 | + "Wrong valid blocks %d or segno %u", |
4075 | + GET_SIT_VBLOCKS(raw_sit), segno); |
4076 | + set_sbi_flag(sbi, SBI_NEED_FSCK); |
4077 | + return -EINVAL; |
4078 | + } |
4079 | + return 0; |
4080 | } |
4081 | |
4082 | static inline pgoff_t current_sit_addr(struct f2fs_sb_info *sbi, |
4083 | diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c |
4084 | index 91bf72334722..c8f408d8a582 100644 |
4085 | --- a/fs/f2fs/super.c |
4086 | +++ b/fs/f2fs/super.c |
4087 | @@ -1337,6 +1337,8 @@ static inline bool sanity_check_area_boundary(struct f2fs_sb_info *sbi, |
4088 | static int sanity_check_raw_super(struct f2fs_sb_info *sbi, |
4089 | struct buffer_head *bh) |
4090 | { |
4091 | + block_t segment_count, segs_per_sec, secs_per_zone; |
4092 | + block_t total_sections, blocks_per_seg; |
4093 | struct f2fs_super_block *raw_super = (struct f2fs_super_block *) |
4094 | (bh->b_data + F2FS_SUPER_OFFSET); |
4095 | struct super_block *sb = sbi->sb; |
4096 | @@ -1393,6 +1395,68 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, |
4097 | return 1; |
4098 | } |
4099 | |
4100 | + segment_count = le32_to_cpu(raw_super->segment_count); |
4101 | + segs_per_sec = le32_to_cpu(raw_super->segs_per_sec); |
4102 | + secs_per_zone = le32_to_cpu(raw_super->secs_per_zone); |
4103 | + total_sections = le32_to_cpu(raw_super->section_count); |
4104 | + |
4105 | + /* blocks_per_seg should be 512, given the above check */ |
4106 | + blocks_per_seg = 1 << le32_to_cpu(raw_super->log_blocks_per_seg); |
4107 | + |
4108 | + if (segment_count > F2FS_MAX_SEGMENT || |
4109 | + segment_count < F2FS_MIN_SEGMENTS) { |
4110 | + f2fs_msg(sb, KERN_INFO, |
4111 | + "Invalid segment count (%u)", |
4112 | + segment_count); |
4113 | + return 1; |
4114 | + } |
4115 | + |
4116 | + if (total_sections > segment_count || |
4117 | + total_sections < F2FS_MIN_SEGMENTS || |
4118 | + segs_per_sec > segment_count || !segs_per_sec) { |
4119 | + f2fs_msg(sb, KERN_INFO, |
4120 | + "Invalid segment/section count (%u, %u x %u)", |
4121 | + segment_count, total_sections, segs_per_sec); |
4122 | + return 1; |
4123 | + } |
4124 | + |
4125 | + if ((segment_count / segs_per_sec) < total_sections) { |
4126 | + f2fs_msg(sb, KERN_INFO, |
4127 | + "Small segment_count (%u < %u * %u)", |
4128 | + segment_count, segs_per_sec, total_sections); |
4129 | + return 1; |
4130 | + } |
4131 | + |
4132 | + if (segment_count > (le32_to_cpu(raw_super->block_count) >> 9)) { |
4133 | + f2fs_msg(sb, KERN_INFO, |
4134 | + "Wrong segment_count / block_count (%u > %u)", |
4135 | + segment_count, le32_to_cpu(raw_super->block_count)); |
4136 | + return 1; |
4137 | + } |
4138 | + |
4139 | + if (secs_per_zone > total_sections || !secs_per_zone) { |
4140 | + f2fs_msg(sb, KERN_INFO, |
4141 | + "Wrong secs_per_zone / total_sections (%u, %u)", |
4142 | + secs_per_zone, total_sections); |
4143 | + return 1; |
4144 | + } |
4145 | + if (le32_to_cpu(raw_super->extension_count) > F2FS_MAX_EXTENSION) { |
4146 | + f2fs_msg(sb, KERN_INFO, |
4147 | + "Corrupted extension count (%u > %u)", |
4148 | + le32_to_cpu(raw_super->extension_count), |
4149 | + F2FS_MAX_EXTENSION); |
4150 | + return 1; |
4151 | + } |
4152 | + |
4153 | + if (le32_to_cpu(raw_super->cp_payload) > |
4154 | + (blocks_per_seg - F2FS_CP_PACKS)) { |
4155 | + f2fs_msg(sb, KERN_INFO, |
4156 | + "Insane cp_payload (%u > %u)", |
4157 | + le32_to_cpu(raw_super->cp_payload), |
4158 | + blocks_per_seg - F2FS_CP_PACKS); |
4159 | + return 1; |
4160 | + } |
4161 | + |
4162 | /* check reserved ino info */ |
4163 | if (le32_to_cpu(raw_super->node_ino) != 1 || |
4164 | le32_to_cpu(raw_super->meta_ino) != 2 || |
4165 | @@ -1405,13 +1469,6 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, |
4166 | return 1; |
4167 | } |
4168 | |
4169 | - if (le32_to_cpu(raw_super->segment_count) > F2FS_MAX_SEGMENT) { |
4170 | - f2fs_msg(sb, KERN_INFO, |
4171 | - "Invalid segment count (%u)", |
4172 | - le32_to_cpu(raw_super->segment_count)); |
4173 | - return 1; |
4174 | - } |
4175 | - |
4176 | /* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */ |
4177 | if (sanity_check_area_boundary(sbi, bh)) |
4178 | return 1; |
4179 | @@ -1424,10 +1481,14 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi) |
4180 | unsigned int total, fsmeta; |
4181 | struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi); |
4182 | struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); |
4183 | + unsigned int ovp_segments, reserved_segments; |
4184 | unsigned int main_segs, blocks_per_seg; |
4185 | unsigned int sit_segs, nat_segs; |
4186 | unsigned int sit_bitmap_size, nat_bitmap_size; |
4187 | unsigned int log_blocks_per_seg; |
4188 | + unsigned int segment_count_main; |
4189 | + unsigned int cp_pack_start_sum, cp_payload; |
4190 | + block_t user_block_count; |
4191 | int i; |
4192 | |
4193 | total = le32_to_cpu(raw_super->segment_count); |
4194 | @@ -1442,6 +1503,26 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi) |
4195 | if (unlikely(fsmeta >= total)) |
4196 | return 1; |
4197 | |
4198 | + ovp_segments = le32_to_cpu(ckpt->overprov_segment_count); |
4199 | + reserved_segments = le32_to_cpu(ckpt->rsvd_segment_count); |
4200 | + |
4201 | + if (unlikely(fsmeta < F2FS_MIN_SEGMENTS || |
4202 | + ovp_segments == 0 || reserved_segments == 0)) { |
4203 | + f2fs_msg(sbi->sb, KERN_ERR, |
4204 | + "Wrong layout: check mkfs.f2fs version"); |
4205 | + return 1; |
4206 | + } |
4207 | + |
4208 | + user_block_count = le64_to_cpu(ckpt->user_block_count); |
4209 | + segment_count_main = le32_to_cpu(raw_super->segment_count_main); |
4210 | + log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg); |
4211 | + if (!user_block_count || user_block_count >= |
4212 | + segment_count_main << log_blocks_per_seg) { |
4213 | + f2fs_msg(sbi->sb, KERN_ERR, |
4214 | + "Wrong user_block_count: %u", user_block_count); |
4215 | + return 1; |
4216 | + } |
4217 | + |
4218 | main_segs = le32_to_cpu(raw_super->segment_count_main); |
4219 | blocks_per_seg = sbi->blocks_per_seg; |
4220 | |
4221 | @@ -1458,7 +1539,6 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi) |
4222 | |
4223 | sit_bitmap_size = le32_to_cpu(ckpt->sit_ver_bitmap_bytesize); |
4224 | nat_bitmap_size = le32_to_cpu(ckpt->nat_ver_bitmap_bytesize); |
4225 | - log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg); |
4226 | |
4227 | if (sit_bitmap_size != ((sit_segs / 2) << log_blocks_per_seg) / 8 || |
4228 | nat_bitmap_size != ((nat_segs / 2) << log_blocks_per_seg) / 8) { |
4229 | @@ -1468,6 +1548,17 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi) |
4230 | return 1; |
4231 | } |
4232 | |
4233 | + cp_pack_start_sum = __start_sum_addr(sbi); |
4234 | + cp_payload = __cp_payload(sbi); |
4235 | + if (cp_pack_start_sum < cp_payload + 1 || |
4236 | + cp_pack_start_sum > blocks_per_seg - 1 - |
4237 | + NR_CURSEG_TYPE) { |
4238 | + f2fs_msg(sbi->sb, KERN_ERR, |
4239 | + "Wrong cp_pack_start_sum: %u", |
4240 | + cp_pack_start_sum); |
4241 | + return 1; |
4242 | + } |
4243 | + |
4244 | if (unlikely(f2fs_cp_error(sbi))) { |
4245 | f2fs_msg(sbi->sb, KERN_ERR, "A bug case: need to run fsck"); |
4246 | return 1; |
4247 | diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c |
4248 | index 2c2f182cde03..f53c139c312e 100644 |
4249 | --- a/fs/hugetlbfs/inode.c |
4250 | +++ b/fs/hugetlbfs/inode.c |
4251 | @@ -118,6 +118,16 @@ static void huge_pagevec_release(struct pagevec *pvec) |
4252 | pagevec_reinit(pvec); |
4253 | } |
4254 | |
4255 | +/* |
4256 | + * Mask used when checking the page offset value passed in via system |
4257 | + * calls. This value will be converted to a loff_t which is signed. |
4258 | + * Therefore, we want to check the upper PAGE_SHIFT + 1 bits of the |
4259 | + * value. The extra bit (- 1 in the shift value) is to take the sign |
4260 | + * bit into account. |
4261 | + */ |
4262 | +#define PGOFF_LOFFT_MAX \ |
4263 | + (((1UL << (PAGE_SHIFT + 1)) - 1) << (BITS_PER_LONG - (PAGE_SHIFT + 1))) |
4264 | + |
4265 | static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) |
4266 | { |
4267 | struct inode *inode = file_inode(file); |
4268 | @@ -136,17 +146,31 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) |
4269 | vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND; |
4270 | vma->vm_ops = &hugetlb_vm_ops; |
4271 | |
4272 | + /* |
4273 | + * page based offset in vm_pgoff could be sufficiently large to |
4274 | + * overflow a loff_t when converted to byte offset. This can |
4275 | + * only happen on architectures where sizeof(loff_t) == |
4276 | + * sizeof(unsigned long). So, only check in those instances. |
4277 | + */ |
4278 | + if (sizeof(unsigned long) == sizeof(loff_t)) { |
4279 | + if (vma->vm_pgoff & PGOFF_LOFFT_MAX) |
4280 | + return -EINVAL; |
4281 | + } |
4282 | + |
4283 | + /* must be huge page aligned */ |
4284 | if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT)) |
4285 | return -EINVAL; |
4286 | |
4287 | vma_len = (loff_t)(vma->vm_end - vma->vm_start); |
4288 | + len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); |
4289 | + /* check for overflow */ |
4290 | + if (len < vma_len) |
4291 | + return -EINVAL; |
4292 | |
4293 | inode_lock(inode); |
4294 | file_accessed(file); |
4295 | |
4296 | ret = -ENOMEM; |
4297 | - len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); |
4298 | - |
4299 | if (hugetlb_reserve_pages(inode, |
4300 | vma->vm_pgoff >> huge_page_order(h), |
4301 | len >> huge_page_shift(h), vma, |
4302 | @@ -155,7 +179,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) |
4303 | |
4304 | ret = 0; |
4305 | if (vma->vm_flags & VM_WRITE && inode->i_size < len) |
4306 | - inode->i_size = len; |
4307 | + i_size_write(inode, len); |
4308 | out: |
4309 | inode_unlock(inode); |
4310 | |
4311 | diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c |
4312 | index 9b43ca02b7ab..80317b04c84a 100644 |
4313 | --- a/fs/kernfs/symlink.c |
4314 | +++ b/fs/kernfs/symlink.c |
4315 | @@ -88,7 +88,7 @@ static int kernfs_get_target_path(struct kernfs_node *parent, |
4316 | int slen = strlen(kn->name); |
4317 | |
4318 | len -= slen; |
4319 | - strncpy(s + len, kn->name, slen); |
4320 | + memcpy(s + len, kn->name, slen); |
4321 | if (len) |
4322 | s[--len] = '/'; |
4323 | |
4324 | diff --git a/fs/udf/super.c b/fs/udf/super.c |
4325 | index 12467ad608cd..03369a89600e 100644 |
4326 | --- a/fs/udf/super.c |
4327 | +++ b/fs/udf/super.c |
4328 | @@ -929,16 +929,20 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) |
4329 | } |
4330 | |
4331 | ret = udf_dstrCS0toUTF8(outstr, 31, pvoldesc->volIdent, 32); |
4332 | - if (ret < 0) |
4333 | - goto out_bh; |
4334 | - |
4335 | - strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret); |
4336 | + if (ret < 0) { |
4337 | + strcpy(UDF_SB(sb)->s_volume_ident, "InvalidName"); |
4338 | + pr_warn("incorrect volume identification, setting to " |
4339 | + "'InvalidName'\n"); |
4340 | + } else { |
4341 | + strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret); |
4342 | + } |
4343 | udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident); |
4344 | |
4345 | ret = udf_dstrCS0toUTF8(outstr, 127, pvoldesc->volSetIdent, 128); |
4346 | - if (ret < 0) |
4347 | + if (ret < 0) { |
4348 | + ret = 0; |
4349 | goto out_bh; |
4350 | - |
4351 | + } |
4352 | outstr[ret] = 0; |
4353 | udf_debug("volSetIdent[] = '%s'\n", outstr); |
4354 | |
4355 | diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c |
4356 | index 3a3be23689b3..61a1738895b7 100644 |
4357 | --- a/fs/udf/unicode.c |
4358 | +++ b/fs/udf/unicode.c |
4359 | @@ -341,6 +341,11 @@ try_again: |
4360 | return u_len; |
4361 | } |
4362 | |
4363 | +/* |
4364 | + * Convert CS0 dstring to output charset. Warning: This function may truncate |
4365 | + * input string if it is too long as it is used for informational strings only |
4366 | + * and it is better to truncate the string than to refuse mounting a media. |
4367 | + */ |
4368 | int udf_dstrCS0toUTF8(uint8_t *utf_o, int o_len, |
4369 | const uint8_t *ocu_i, int i_len) |
4370 | { |
4371 | @@ -349,9 +354,12 @@ int udf_dstrCS0toUTF8(uint8_t *utf_o, int o_len, |
4372 | if (i_len > 0) { |
4373 | s_len = ocu_i[i_len - 1]; |
4374 | if (s_len >= i_len) { |
4375 | - pr_err("incorrect dstring lengths (%d/%d)\n", |
4376 | - s_len, i_len); |
4377 | - return -EINVAL; |
4378 | + pr_warn("incorrect dstring lengths (%d/%d)," |
4379 | + " truncating\n", s_len, i_len); |
4380 | + s_len = i_len - 1; |
4381 | + /* 2-byte encoding? Need to round properly... */ |
4382 | + if (ocu_i[0] == 16) |
4383 | + s_len -= (s_len - 1) & 2; |
4384 | } |
4385 | } |
4386 | |
4387 | diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c |
4388 | index 6622d46ddec3..9687208c676f 100644 |
4389 | --- a/fs/xfs/libxfs/xfs_attr.c |
4390 | +++ b/fs/xfs/libxfs/xfs_attr.c |
4391 | @@ -487,7 +487,14 @@ xfs_attr_shortform_addname(xfs_da_args_t *args) |
4392 | if (args->flags & ATTR_CREATE) |
4393 | return retval; |
4394 | retval = xfs_attr_shortform_remove(args); |
4395 | - ASSERT(retval == 0); |
4396 | + if (retval) |
4397 | + return retval; |
4398 | + /* |
4399 | + * Since we have removed the old attr, clear ATTR_REPLACE so |
4400 | + * that the leaf format add routine won't trip over the attr |
4401 | + * not being around. |
4402 | + */ |
4403 | + args->flags &= ~ATTR_REPLACE; |
4404 | } |
4405 | |
4406 | if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX || |
4407 | diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h |
4408 | index 070fc49e39e2..5031defe59c5 100644 |
4409 | --- a/include/linux/bpf_verifier.h |
4410 | +++ b/include/linux/bpf_verifier.h |
4411 | @@ -71,6 +71,7 @@ struct bpf_insn_aux_data { |
4412 | enum bpf_reg_type ptr_type; /* pointer type for load/store insns */ |
4413 | struct bpf_map *map_ptr; /* pointer for call insn into lookup_elem */ |
4414 | }; |
4415 | + int sanitize_stack_off; /* stack slot to be cleared */ |
4416 | bool seen; /* this insn was processed by the verifier */ |
4417 | }; |
4418 | |
4419 | diff --git a/include/linux/ceph/auth.h b/include/linux/ceph/auth.h |
4420 | index 374bb1c4ef52..035f26a04364 100644 |
4421 | --- a/include/linux/ceph/auth.h |
4422 | +++ b/include/linux/ceph/auth.h |
4423 | @@ -63,8 +63,12 @@ struct ceph_auth_client_ops { |
4424 | /* ensure that an existing authorizer is up to date */ |
4425 | int (*update_authorizer)(struct ceph_auth_client *ac, int peer_type, |
4426 | struct ceph_auth_handshake *auth); |
4427 | + int (*add_authorizer_challenge)(struct ceph_auth_client *ac, |
4428 | + struct ceph_authorizer *a, |
4429 | + void *challenge_buf, |
4430 | + int challenge_buf_len); |
4431 | int (*verify_authorizer_reply)(struct ceph_auth_client *ac, |
4432 | - struct ceph_authorizer *a, size_t len); |
4433 | + struct ceph_authorizer *a); |
4434 | void (*invalidate_authorizer)(struct ceph_auth_client *ac, |
4435 | int peer_type); |
4436 | |
4437 | @@ -117,9 +121,12 @@ void ceph_auth_destroy_authorizer(struct ceph_authorizer *a); |
4438 | extern int ceph_auth_update_authorizer(struct ceph_auth_client *ac, |
4439 | int peer_type, |
4440 | struct ceph_auth_handshake *a); |
4441 | +int ceph_auth_add_authorizer_challenge(struct ceph_auth_client *ac, |
4442 | + struct ceph_authorizer *a, |
4443 | + void *challenge_buf, |
4444 | + int challenge_buf_len); |
4445 | extern int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac, |
4446 | - struct ceph_authorizer *a, |
4447 | - size_t len); |
4448 | + struct ceph_authorizer *a); |
4449 | extern void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, |
4450 | int peer_type); |
4451 | |
4452 | diff --git a/include/linux/ceph/ceph_features.h b/include/linux/ceph/ceph_features.h |
4453 | index ae2f66833762..cf765db39c95 100644 |
4454 | --- a/include/linux/ceph/ceph_features.h |
4455 | +++ b/include/linux/ceph/ceph_features.h |
4456 | @@ -76,6 +76,7 @@ |
4457 | // duplicated since it was introduced at the same time as CEPH_FEATURE_CRUSH_TUNABLES5 |
4458 | #define CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING (1ULL<<58) /* New, v7 encoding */ |
4459 | #define CEPH_FEATURE_FS_FILE_LAYOUT_V2 (1ULL<<58) /* file_layout_t */ |
4460 | +#define CEPH_FEATURE_CEPHX_V2 (1ULL<<61) // *do not share this bit* |
4461 | |
4462 | /* |
4463 | * The introduction of CEPH_FEATURE_OSD_SNAPMAPPER caused the feature |
4464 | @@ -124,7 +125,8 @@ static inline u64 ceph_sanitize_features(u64 features) |
4465 | CEPH_FEATURE_MSGR_KEEPALIVE2 | \ |
4466 | CEPH_FEATURE_CRUSH_V4 | \ |
4467 | CEPH_FEATURE_CRUSH_TUNABLES5 | \ |
4468 | - CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING) |
4469 | + CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING | \ |
4470 | + CEPH_FEATURE_CEPHX_V2) |
4471 | |
4472 | #define CEPH_FEATURES_REQUIRED_DEFAULT \ |
4473 | (CEPH_FEATURE_NOSRCADDR | \ |
4474 | diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h |
4475 | index 8dbd7879fdc6..5e1c9c80d536 100644 |
4476 | --- a/include/linux/ceph/messenger.h |
4477 | +++ b/include/linux/ceph/messenger.h |
4478 | @@ -30,7 +30,10 @@ struct ceph_connection_operations { |
4479 | struct ceph_auth_handshake *(*get_authorizer) ( |
4480 | struct ceph_connection *con, |
4481 | int *proto, int force_new); |
4482 | - int (*verify_authorizer_reply) (struct ceph_connection *con, int len); |
4483 | + int (*add_authorizer_challenge)(struct ceph_connection *con, |
4484 | + void *challenge_buf, |
4485 | + int challenge_buf_len); |
4486 | + int (*verify_authorizer_reply) (struct ceph_connection *con); |
4487 | int (*invalidate_authorizer)(struct ceph_connection *con); |
4488 | |
4489 | /* there was some error on the socket (disconnect, whatever) */ |
4490 | @@ -200,9 +203,8 @@ struct ceph_connection { |
4491 | attempt for this connection, client */ |
4492 | u32 peer_global_seq; /* peer's global seq for this connection */ |
4493 | |
4494 | + struct ceph_auth_handshake *auth; |
4495 | int auth_retry; /* true if we need a newer authorizer */ |
4496 | - void *auth_reply_buf; /* where to put the authorizer reply */ |
4497 | - int auth_reply_buf_len; |
4498 | |
4499 | struct mutex mutex; |
4500 | |
4501 | diff --git a/include/linux/ceph/msgr.h b/include/linux/ceph/msgr.h |
4502 | index 0fe2656ac415..063f9d7f1b74 100644 |
4503 | --- a/include/linux/ceph/msgr.h |
4504 | +++ b/include/linux/ceph/msgr.h |
4505 | @@ -90,7 +90,7 @@ struct ceph_entity_inst { |
4506 | #define CEPH_MSGR_TAG_SEQ 13 /* 64-bit int follows with seen seq number */ |
4507 | #define CEPH_MSGR_TAG_KEEPALIVE2 14 /* keepalive2 byte + ceph_timespec */ |
4508 | #define CEPH_MSGR_TAG_KEEPALIVE2_ACK 15 /* keepalive2 reply */ |
4509 | - |
4510 | +#define CEPH_MSGR_TAG_CHALLENGE_AUTHORIZER 16 /* cephx v2 doing server challenge */ |
4511 | |
4512 | /* |
4513 | * connection negotiation |
4514 | diff --git a/include/linux/reset.h b/include/linux/reset.h |
4515 | index 5daff15722d3..7e99690dbc81 100644 |
4516 | --- a/include/linux/reset.h |
4517 | +++ b/include/linux/reset.h |
4518 | @@ -13,76 +13,82 @@ int reset_control_deassert(struct reset_control *rstc); |
4519 | int reset_control_status(struct reset_control *rstc); |
4520 | |
4521 | struct reset_control *__of_reset_control_get(struct device_node *node, |
4522 | - const char *id, int index, int shared); |
4523 | + const char *id, int index, bool shared, |
4524 | + bool optional); |
4525 | +struct reset_control *__reset_control_get(struct device *dev, const char *id, |
4526 | + int index, bool shared, |
4527 | + bool optional); |
4528 | void reset_control_put(struct reset_control *rstc); |
4529 | +int __device_reset(struct device *dev, bool optional); |
4530 | struct reset_control *__devm_reset_control_get(struct device *dev, |
4531 | - const char *id, int index, int shared); |
4532 | - |
4533 | -int __must_check device_reset(struct device *dev); |
4534 | - |
4535 | -static inline int device_reset_optional(struct device *dev) |
4536 | -{ |
4537 | - return device_reset(dev); |
4538 | -} |
4539 | + const char *id, int index, bool shared, |
4540 | + bool optional); |
4541 | |
4542 | #else |
4543 | |
4544 | static inline int reset_control_reset(struct reset_control *rstc) |
4545 | { |
4546 | - WARN_ON(1); |
4547 | return 0; |
4548 | } |
4549 | |
4550 | static inline int reset_control_assert(struct reset_control *rstc) |
4551 | { |
4552 | - WARN_ON(1); |
4553 | return 0; |
4554 | } |
4555 | |
4556 | static inline int reset_control_deassert(struct reset_control *rstc) |
4557 | { |
4558 | - WARN_ON(1); |
4559 | return 0; |
4560 | } |
4561 | |
4562 | static inline int reset_control_status(struct reset_control *rstc) |
4563 | { |
4564 | - WARN_ON(1); |
4565 | return 0; |
4566 | } |
4567 | |
4568 | static inline void reset_control_put(struct reset_control *rstc) |
4569 | { |
4570 | - WARN_ON(1); |
4571 | } |
4572 | |
4573 | -static inline int __must_check device_reset(struct device *dev) |
4574 | +static inline int __device_reset(struct device *dev, bool optional) |
4575 | { |
4576 | - WARN_ON(1); |
4577 | - return -ENOTSUPP; |
4578 | + return optional ? 0 : -ENOTSUPP; |
4579 | } |
4580 | |
4581 | -static inline int device_reset_optional(struct device *dev) |
4582 | +static inline struct reset_control *__of_reset_control_get( |
4583 | + struct device_node *node, |
4584 | + const char *id, int index, bool shared, |
4585 | + bool optional) |
4586 | { |
4587 | - return -ENOTSUPP; |
4588 | + return optional ? NULL : ERR_PTR(-ENOTSUPP); |
4589 | } |
4590 | |
4591 | -static inline struct reset_control *__of_reset_control_get( |
4592 | - struct device_node *node, |
4593 | - const char *id, int index, int shared) |
4594 | +static inline struct reset_control *__reset_control_get( |
4595 | + struct device *dev, const char *id, |
4596 | + int index, bool shared, bool optional) |
4597 | { |
4598 | - return ERR_PTR(-ENOTSUPP); |
4599 | + return optional ? NULL : ERR_PTR(-ENOTSUPP); |
4600 | } |
4601 | |
4602 | static inline struct reset_control *__devm_reset_control_get( |
4603 | - struct device *dev, |
4604 | - const char *id, int index, int shared) |
4605 | + struct device *dev, const char *id, |
4606 | + int index, bool shared, bool optional) |
4607 | { |
4608 | - return ERR_PTR(-ENOTSUPP); |
4609 | + return optional ? NULL : ERR_PTR(-ENOTSUPP); |
4610 | } |
4611 | |
4612 | #endif /* CONFIG_RESET_CONTROLLER */ |
4613 | |
4614 | +static inline int __must_check device_reset(struct device *dev) |
4615 | +{ |
4616 | + return __device_reset(dev, false); |
4617 | +} |
4618 | + |
4619 | +static inline int device_reset_optional(struct device *dev) |
4620 | +{ |
4621 | + return __device_reset(dev, true); |
4622 | +} |
4623 | + |
4624 | /** |
4625 | * reset_control_get_exclusive - Lookup and obtain an exclusive reference |
4626 | * to a reset controller. |
4627 | @@ -101,10 +107,7 @@ static inline struct reset_control *__devm_reset_control_get( |
4628 | static inline struct reset_control * |
4629 | __must_check reset_control_get_exclusive(struct device *dev, const char *id) |
4630 | { |
4631 | -#ifndef CONFIG_RESET_CONTROLLER |
4632 | - WARN_ON(1); |
4633 | -#endif |
4634 | - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 0); |
4635 | + return __reset_control_get(dev, id, 0, false, false); |
4636 | } |
4637 | |
4638 | /** |
4639 | @@ -132,19 +135,19 @@ __must_check reset_control_get_exclusive(struct device *dev, const char *id) |
4640 | static inline struct reset_control *reset_control_get_shared( |
4641 | struct device *dev, const char *id) |
4642 | { |
4643 | - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 1); |
4644 | + return __reset_control_get(dev, id, 0, true, false); |
4645 | } |
4646 | |
4647 | static inline struct reset_control *reset_control_get_optional_exclusive( |
4648 | struct device *dev, const char *id) |
4649 | { |
4650 | - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 0); |
4651 | + return __reset_control_get(dev, id, 0, false, true); |
4652 | } |
4653 | |
4654 | static inline struct reset_control *reset_control_get_optional_shared( |
4655 | struct device *dev, const char *id) |
4656 | { |
4657 | - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 1); |
4658 | + return __reset_control_get(dev, id, 0, true, true); |
4659 | } |
4660 | |
4661 | /** |
4662 | @@ -160,7 +163,7 @@ static inline struct reset_control *reset_control_get_optional_shared( |
4663 | static inline struct reset_control *of_reset_control_get_exclusive( |
4664 | struct device_node *node, const char *id) |
4665 | { |
4666 | - return __of_reset_control_get(node, id, 0, 0); |
4667 | + return __of_reset_control_get(node, id, 0, false, false); |
4668 | } |
4669 | |
4670 | /** |
4671 | @@ -185,7 +188,7 @@ static inline struct reset_control *of_reset_control_get_exclusive( |
4672 | static inline struct reset_control *of_reset_control_get_shared( |
4673 | struct device_node *node, const char *id) |
4674 | { |
4675 | - return __of_reset_control_get(node, id, 0, 1); |
4676 | + return __of_reset_control_get(node, id, 0, true, false); |
4677 | } |
4678 | |
4679 | /** |
4680 | @@ -202,7 +205,7 @@ static inline struct reset_control *of_reset_control_get_shared( |
4681 | static inline struct reset_control *of_reset_control_get_exclusive_by_index( |
4682 | struct device_node *node, int index) |
4683 | { |
4684 | - return __of_reset_control_get(node, NULL, index, 0); |
4685 | + return __of_reset_control_get(node, NULL, index, false, false); |
4686 | } |
4687 | |
4688 | /** |
4689 | @@ -230,7 +233,7 @@ static inline struct reset_control *of_reset_control_get_exclusive_by_index( |
4690 | static inline struct reset_control *of_reset_control_get_shared_by_index( |
4691 | struct device_node *node, int index) |
4692 | { |
4693 | - return __of_reset_control_get(node, NULL, index, 1); |
4694 | + return __of_reset_control_get(node, NULL, index, true, false); |
4695 | } |
4696 | |
4697 | /** |
4698 | @@ -249,10 +252,7 @@ static inline struct reset_control * |
4699 | __must_check devm_reset_control_get_exclusive(struct device *dev, |
4700 | const char *id) |
4701 | { |
4702 | -#ifndef CONFIG_RESET_CONTROLLER |
4703 | - WARN_ON(1); |
4704 | -#endif |
4705 | - return __devm_reset_control_get(dev, id, 0, 0); |
4706 | + return __devm_reset_control_get(dev, id, 0, false, false); |
4707 | } |
4708 | |
4709 | /** |
4710 | @@ -267,19 +267,19 @@ __must_check devm_reset_control_get_exclusive(struct device *dev, |
4711 | static inline struct reset_control *devm_reset_control_get_shared( |
4712 | struct device *dev, const char *id) |
4713 | { |
4714 | - return __devm_reset_control_get(dev, id, 0, 1); |
4715 | + return __devm_reset_control_get(dev, id, 0, true, false); |
4716 | } |
4717 | |
4718 | static inline struct reset_control *devm_reset_control_get_optional_exclusive( |
4719 | struct device *dev, const char *id) |
4720 | { |
4721 | - return __devm_reset_control_get(dev, id, 0, 0); |
4722 | + return __devm_reset_control_get(dev, id, 0, false, true); |
4723 | } |
4724 | |
4725 | static inline struct reset_control *devm_reset_control_get_optional_shared( |
4726 | struct device *dev, const char *id) |
4727 | { |
4728 | - return __devm_reset_control_get(dev, id, 0, 1); |
4729 | + return __devm_reset_control_get(dev, id, 0, true, true); |
4730 | } |
4731 | |
4732 | /** |
4733 | @@ -297,7 +297,7 @@ static inline struct reset_control *devm_reset_control_get_optional_shared( |
4734 | static inline struct reset_control * |
4735 | devm_reset_control_get_exclusive_by_index(struct device *dev, int index) |
4736 | { |
4737 | - return __devm_reset_control_get(dev, NULL, index, 0); |
4738 | + return __devm_reset_control_get(dev, NULL, index, false, false); |
4739 | } |
4740 | |
4741 | /** |
4742 | @@ -313,7 +313,7 @@ devm_reset_control_get_exclusive_by_index(struct device *dev, int index) |
4743 | static inline struct reset_control * |
4744 | devm_reset_control_get_shared_by_index(struct device *dev, int index) |
4745 | { |
4746 | - return __devm_reset_control_get(dev, NULL, index, 1); |
4747 | + return __devm_reset_control_get(dev, NULL, index, true, false); |
4748 | } |
4749 | |
4750 | /* |
4751 | diff --git a/include/uapi/linux/btrfs_tree.h b/include/uapi/linux/btrfs_tree.h |
4752 | index c794c9af6c0f..a1ded2a1bf1d 100644 |
4753 | --- a/include/uapi/linux/btrfs_tree.h |
4754 | +++ b/include/uapi/linux/btrfs_tree.h |
4755 | @@ -730,6 +730,7 @@ struct btrfs_balance_item { |
4756 | #define BTRFS_FILE_EXTENT_INLINE 0 |
4757 | #define BTRFS_FILE_EXTENT_REG 1 |
4758 | #define BTRFS_FILE_EXTENT_PREALLOC 2 |
4759 | +#define BTRFS_FILE_EXTENT_TYPES 2 |
4760 | |
4761 | struct btrfs_file_extent_item { |
4762 | /* |
4763 | diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c |
4764 | index dafa2708ce9e..1438b7396cb4 100644 |
4765 | --- a/kernel/bpf/verifier.c |
4766 | +++ b/kernel/bpf/verifier.c |
4767 | @@ -540,10 +540,11 @@ static bool is_spillable_regtype(enum bpf_reg_type type) |
4768 | /* check_stack_read/write functions track spill/fill of registers, |
4769 | * stack boundary and alignment are checked in check_mem_access() |
4770 | */ |
4771 | -static int check_stack_write(struct bpf_verifier_state *state, int off, |
4772 | - int size, int value_regno) |
4773 | +static int check_stack_write(struct bpf_verifier_env *env, |
4774 | + struct bpf_verifier_state *state, int off, |
4775 | + int size, int value_regno, int insn_idx) |
4776 | { |
4777 | - int i; |
4778 | + int i, spi = (MAX_BPF_STACK + off) / BPF_REG_SIZE; |
4779 | /* caller checked that off % size == 0 and -MAX_BPF_STACK <= off < 0, |
4780 | * so it's aligned access and [off, off + size) are within stack limits |
4781 | */ |
4782 | @@ -558,15 +559,37 @@ static int check_stack_write(struct bpf_verifier_state *state, int off, |
4783 | } |
4784 | |
4785 | /* save register state */ |
4786 | - state->spilled_regs[(MAX_BPF_STACK + off) / BPF_REG_SIZE] = |
4787 | - state->regs[value_regno]; |
4788 | - |
4789 | - for (i = 0; i < BPF_REG_SIZE; i++) |
4790 | + state->spilled_regs[spi] = state->regs[value_regno]; |
4791 | + |
4792 | + for (i = 0; i < BPF_REG_SIZE; i++) { |
4793 | + if (state->stack_slot_type[MAX_BPF_STACK + off + i] == STACK_MISC && |
4794 | + !env->allow_ptr_leaks) { |
4795 | + int *poff = &env->insn_aux_data[insn_idx].sanitize_stack_off; |
4796 | + int soff = (-spi - 1) * BPF_REG_SIZE; |
4797 | + |
4798 | + /* detected reuse of integer stack slot with a pointer |
4799 | + * which means either llvm is reusing stack slot or |
4800 | + * an attacker is trying to exploit CVE-2018-3639 |
4801 | + * (speculative store bypass) |
4802 | + * Have to sanitize that slot with preemptive |
4803 | + * store of zero. |
4804 | + */ |
4805 | + if (*poff && *poff != soff) { |
4806 | + /* disallow programs where single insn stores |
4807 | + * into two different stack slots, since verifier |
4808 | + * cannot sanitize them |
4809 | + */ |
4810 | + verbose("insn %d cannot access two stack slots fp%d and fp%d", |
4811 | + insn_idx, *poff, soff); |
4812 | + return -EINVAL; |
4813 | + } |
4814 | + *poff = soff; |
4815 | + } |
4816 | state->stack_slot_type[MAX_BPF_STACK + off + i] = STACK_SPILL; |
4817 | + } |
4818 | } else { |
4819 | /* regular write of data into stack */ |
4820 | - state->spilled_regs[(MAX_BPF_STACK + off) / BPF_REG_SIZE] = |
4821 | - (struct bpf_reg_state) {}; |
4822 | + state->spilled_regs[spi] = (struct bpf_reg_state) {}; |
4823 | |
4824 | for (i = 0; i < size; i++) |
4825 | state->stack_slot_type[MAX_BPF_STACK + off + i] = STACK_MISC; |
4826 | @@ -747,7 +770,7 @@ static int check_ptr_alignment(struct bpf_verifier_env *env, |
4827 | * if t==write && value_regno==-1, some unknown value is stored into memory |
4828 | * if t==read && value_regno==-1, don't care what we read from memory |
4829 | */ |
4830 | -static int check_mem_access(struct bpf_verifier_env *env, u32 regno, int off, |
4831 | +static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regno, int off, |
4832 | int bpf_size, enum bpf_access_type t, |
4833 | int value_regno) |
4834 | { |
4835 | @@ -843,7 +866,8 @@ static int check_mem_access(struct bpf_verifier_env *env, u32 regno, int off, |
4836 | verbose("attempt to corrupt spilled pointer on stack\n"); |
4837 | return -EACCES; |
4838 | } |
4839 | - err = check_stack_write(state, off, size, value_regno); |
4840 | + err = check_stack_write(env, state, off, size, |
4841 | + value_regno, insn_idx); |
4842 | } else { |
4843 | err = check_stack_read(state, off, size, value_regno); |
4844 | } |
4845 | @@ -877,7 +901,7 @@ static int check_mem_access(struct bpf_verifier_env *env, u32 regno, int off, |
4846 | return err; |
4847 | } |
4848 | |
4849 | -static int check_xadd(struct bpf_verifier_env *env, struct bpf_insn *insn) |
4850 | +static int check_xadd(struct bpf_verifier_env *env, int insn_idx, struct bpf_insn *insn) |
4851 | { |
4852 | struct bpf_reg_state *regs = env->cur_state.regs; |
4853 | int err; |
4854 | @@ -910,13 +934,13 @@ static int check_xadd(struct bpf_verifier_env *env, struct bpf_insn *insn) |
4855 | } |
4856 | |
4857 | /* check whether atomic_add can read the memory */ |
4858 | - err = check_mem_access(env, insn->dst_reg, insn->off, |
4859 | + err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, |
4860 | BPF_SIZE(insn->code), BPF_READ, -1); |
4861 | if (err) |
4862 | return err; |
4863 | |
4864 | /* check whether atomic_add can write into the same memory */ |
4865 | - return check_mem_access(env, insn->dst_reg, insn->off, |
4866 | + return check_mem_access(env, insn_idx, insn->dst_reg, insn->off, |
4867 | BPF_SIZE(insn->code), BPF_WRITE, -1); |
4868 | } |
4869 | |
4870 | @@ -1272,7 +1296,7 @@ static int check_call(struct bpf_verifier_env *env, int func_id, int insn_idx) |
4871 | * is inferred from register state. |
4872 | */ |
4873 | for (i = 0; i < meta.access_size; i++) { |
4874 | - err = check_mem_access(env, meta.regno, i, BPF_B, BPF_WRITE, -1); |
4875 | + err = check_mem_access(env, insn_idx, meta.regno, i, BPF_B, BPF_WRITE, -1); |
4876 | if (err) |
4877 | return err; |
4878 | } |
4879 | @@ -2938,7 +2962,7 @@ static int do_check(struct bpf_verifier_env *env) |
4880 | /* check that memory (src_reg + off) is readable, |
4881 | * the state of dst_reg will be updated by this func |
4882 | */ |
4883 | - err = check_mem_access(env, insn->src_reg, insn->off, |
4884 | + err = check_mem_access(env, insn_idx, insn->src_reg, insn->off, |
4885 | BPF_SIZE(insn->code), BPF_READ, |
4886 | insn->dst_reg); |
4887 | if (err) |
4888 | @@ -2978,7 +3002,7 @@ static int do_check(struct bpf_verifier_env *env) |
4889 | enum bpf_reg_type *prev_dst_type, dst_reg_type; |
4890 | |
4891 | if (BPF_MODE(insn->code) == BPF_XADD) { |
4892 | - err = check_xadd(env, insn); |
4893 | + err = check_xadd(env, insn_idx, insn); |
4894 | if (err) |
4895 | return err; |
4896 | insn_idx++; |
4897 | @@ -2997,7 +3021,7 @@ static int do_check(struct bpf_verifier_env *env) |
4898 | dst_reg_type = regs[insn->dst_reg].type; |
4899 | |
4900 | /* check that memory (dst_reg + off) is writeable */ |
4901 | - err = check_mem_access(env, insn->dst_reg, insn->off, |
4902 | + err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, |
4903 | BPF_SIZE(insn->code), BPF_WRITE, |
4904 | insn->src_reg); |
4905 | if (err) |
4906 | @@ -3032,7 +3056,7 @@ static int do_check(struct bpf_verifier_env *env) |
4907 | } |
4908 | |
4909 | /* check that memory (dst_reg + off) is writeable */ |
4910 | - err = check_mem_access(env, insn->dst_reg, insn->off, |
4911 | + err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, |
4912 | BPF_SIZE(insn->code), BPF_WRITE, |
4913 | -1); |
4914 | if (err) |
4915 | @@ -3369,6 +3393,34 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) |
4916 | else |
4917 | continue; |
4918 | |
4919 | + if (type == BPF_WRITE && |
4920 | + env->insn_aux_data[i + delta].sanitize_stack_off) { |
4921 | + struct bpf_insn patch[] = { |
4922 | + /* Sanitize suspicious stack slot with zero. |
4923 | + * There are no memory dependencies for this store, |
4924 | + * since it's only using frame pointer and immediate |
4925 | + * constant of zero |
4926 | + */ |
4927 | + BPF_ST_MEM(BPF_DW, BPF_REG_FP, |
4928 | + env->insn_aux_data[i + delta].sanitize_stack_off, |
4929 | + 0), |
4930 | + /* the original STX instruction will immediately |
4931 | + * overwrite the same stack slot with appropriate value |
4932 | + */ |
4933 | + *insn, |
4934 | + }; |
4935 | + |
4936 | + cnt = ARRAY_SIZE(patch); |
4937 | + new_prog = bpf_patch_insn_data(env, i + delta, patch, cnt); |
4938 | + if (!new_prog) |
4939 | + return -ENOMEM; |
4940 | + |
4941 | + delta += cnt - 1; |
4942 | + env->prog = new_prog; |
4943 | + insn = new_prog->insnsi + i + delta; |
4944 | + continue; |
4945 | + } |
4946 | + |
4947 | if (env->insn_aux_data[i + delta].ptr_type != PTR_TO_CTX) |
4948 | continue; |
4949 | |
4950 | diff --git a/kernel/debug/kdb/kdb_support.c b/kernel/debug/kdb/kdb_support.c |
4951 | index 2aed4a33521b..61cd704a21c8 100644 |
4952 | --- a/kernel/debug/kdb/kdb_support.c |
4953 | +++ b/kernel/debug/kdb/kdb_support.c |
4954 | @@ -129,13 +129,13 @@ int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab) |
4955 | } |
4956 | if (i >= ARRAY_SIZE(kdb_name_table)) { |
4957 | debug_kfree(kdb_name_table[0]); |
4958 | - memcpy(kdb_name_table, kdb_name_table+1, |
4959 | + memmove(kdb_name_table, kdb_name_table+1, |
4960 | sizeof(kdb_name_table[0]) * |
4961 | (ARRAY_SIZE(kdb_name_table)-1)); |
4962 | } else { |
4963 | debug_kfree(knt1); |
4964 | knt1 = kdb_name_table[i]; |
4965 | - memcpy(kdb_name_table+i, kdb_name_table+i+1, |
4966 | + memmove(kdb_name_table+i, kdb_name_table+i+1, |
4967 | sizeof(kdb_name_table[0]) * |
4968 | (ARRAY_SIZE(kdb_name_table)-i-1)); |
4969 | } |
4970 | diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c |
4971 | index a1de021dccba..fbfab5722254 100644 |
4972 | --- a/kernel/events/uprobes.c |
4973 | +++ b/kernel/events/uprobes.c |
4974 | @@ -608,7 +608,7 @@ static int prepare_uprobe(struct uprobe *uprobe, struct file *file, |
4975 | BUG_ON((uprobe->offset & ~PAGE_MASK) + |
4976 | UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); |
4977 | |
4978 | - smp_wmb(); /* pairs with rmb() in find_active_uprobe() */ |
4979 | + smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */ |
4980 | set_bit(UPROBE_COPY_INSN, &uprobe->flags); |
4981 | |
4982 | out: |
4983 | @@ -1902,10 +1902,18 @@ static void handle_swbp(struct pt_regs *regs) |
4984 | * After we hit the bp, _unregister + _register can install the |
4985 | * new and not-yet-analyzed uprobe at the same address, restart. |
4986 | */ |
4987 | - smp_rmb(); /* pairs with wmb() in install_breakpoint() */ |
4988 | if (unlikely(!test_bit(UPROBE_COPY_INSN, &uprobe->flags))) |
4989 | goto out; |
4990 | |
4991 | + /* |
4992 | + * Pairs with the smp_wmb() in prepare_uprobe(). |
4993 | + * |
4994 | + * Guarantees that if we see the UPROBE_COPY_INSN bit set, then |
4995 | + * we must also see the stores to &uprobe->arch performed by the |
4996 | + * prepare_uprobe() call. |
4997 | + */ |
4998 | + smp_rmb(); |
4999 | + |
5000 | /* Tracing handlers use ->utask to communicate with fetch methods */ |
5001 | if (!get_utask()) |
5002 | goto out; |
5003 | diff --git a/lib/kobject.c b/lib/kobject.c |
5004 | index b733a83e5294..f58c7f2b229c 100644 |
5005 | --- a/lib/kobject.c |
5006 | +++ b/lib/kobject.c |
5007 | @@ -127,7 +127,7 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length) |
5008 | int cur = strlen(kobject_name(parent)); |
5009 | /* back up enough to print this name with '/' */ |
5010 | length -= cur; |
5011 | - strncpy(path + length, kobject_name(parent), cur); |
5012 | + memcpy(path + length, kobject_name(parent), cur); |
5013 | *(path + --length) = '/'; |
5014 | } |
5015 | |
5016 | diff --git a/lib/test_hexdump.c b/lib/test_hexdump.c |
5017 | index 3f415d8101f3..1c3c513add77 100644 |
5018 | --- a/lib/test_hexdump.c |
5019 | +++ b/lib/test_hexdump.c |
5020 | @@ -81,7 +81,7 @@ static void __init test_hexdump_prepare_test(size_t len, int rowsize, |
5021 | const char *q = *result++; |
5022 | size_t amount = strlen(q); |
5023 | |
5024 | - strncpy(p, q, amount); |
5025 | + memcpy(p, q, amount); |
5026 | p += amount; |
5027 | |
5028 | *p++ = ' '; |
5029 | diff --git a/mm/hugetlb.c b/mm/hugetlb.c |
5030 | index 5e3a4db36310..3e50fcfe6ad8 100644 |
5031 | --- a/mm/hugetlb.c |
5032 | +++ b/mm/hugetlb.c |
5033 | @@ -4170,6 +4170,12 @@ int hugetlb_reserve_pages(struct inode *inode, |
5034 | struct resv_map *resv_map; |
5035 | long gbl_reserve; |
5036 | |
5037 | + /* This should never happen */ |
5038 | + if (from > to) { |
5039 | + VM_WARN(1, "%s called with a negative range\n", __func__); |
5040 | + return -EINVAL; |
5041 | + } |
5042 | + |
5043 | /* |
5044 | * Only apply hugepage reservation if asked. At fault time, an |
5045 | * attempt will be made for VM_NORESERVE to allocate a page |
5046 | @@ -4259,7 +4265,9 @@ int hugetlb_reserve_pages(struct inode *inode, |
5047 | return 0; |
5048 | out_err: |
5049 | if (!vma || vma->vm_flags & VM_MAYSHARE) |
5050 | - region_abort(resv_map, from, to); |
5051 | + /* Don't call region_abort if region_chg failed */ |
5052 | + if (chg >= 0) |
5053 | + region_abort(resv_map, from, to); |
5054 | if (vma && is_vma_resv_set(vma, HPAGE_RESV_OWNER)) |
5055 | kref_put(&resv_map->refs, resv_map_release); |
5056 | return ret; |
5057 | diff --git a/mm/truncate.c b/mm/truncate.c |
5058 | index 9c809e7d73c3..befdc6f575d2 100644 |
5059 | --- a/mm/truncate.c |
5060 | +++ b/mm/truncate.c |
5061 | @@ -443,9 +443,13 @@ void truncate_inode_pages_final(struct address_space *mapping) |
5062 | */ |
5063 | spin_lock_irq(&mapping->tree_lock); |
5064 | spin_unlock_irq(&mapping->tree_lock); |
5065 | - |
5066 | - truncate_inode_pages(mapping, 0); |
5067 | } |
5068 | + |
5069 | + /* |
5070 | + * Cleancache needs notification even if there are no pages or shadow |
5071 | + * entries. |
5072 | + */ |
5073 | + truncate_inode_pages(mapping, 0); |
5074 | } |
5075 | EXPORT_SYMBOL(truncate_inode_pages_final); |
5076 | |
5077 | diff --git a/net/ceph/auth.c b/net/ceph/auth.c |
5078 | index c822b3ae1bd3..8e79dca81748 100644 |
5079 | --- a/net/ceph/auth.c |
5080 | +++ b/net/ceph/auth.c |
5081 | @@ -314,14 +314,30 @@ int ceph_auth_update_authorizer(struct ceph_auth_client *ac, |
5082 | } |
5083 | EXPORT_SYMBOL(ceph_auth_update_authorizer); |
5084 | |
5085 | +int ceph_auth_add_authorizer_challenge(struct ceph_auth_client *ac, |
5086 | + struct ceph_authorizer *a, |
5087 | + void *challenge_buf, |
5088 | + int challenge_buf_len) |
5089 | +{ |
5090 | + int ret = 0; |
5091 | + |
5092 | + mutex_lock(&ac->mutex); |
5093 | + if (ac->ops && ac->ops->add_authorizer_challenge) |
5094 | + ret = ac->ops->add_authorizer_challenge(ac, a, challenge_buf, |
5095 | + challenge_buf_len); |
5096 | + mutex_unlock(&ac->mutex); |
5097 | + return ret; |
5098 | +} |
5099 | +EXPORT_SYMBOL(ceph_auth_add_authorizer_challenge); |
5100 | + |
5101 | int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac, |
5102 | - struct ceph_authorizer *a, size_t len) |
5103 | + struct ceph_authorizer *a) |
5104 | { |
5105 | int ret = 0; |
5106 | |
5107 | mutex_lock(&ac->mutex); |
5108 | if (ac->ops && ac->ops->verify_authorizer_reply) |
5109 | - ret = ac->ops->verify_authorizer_reply(ac, a, len); |
5110 | + ret = ac->ops->verify_authorizer_reply(ac, a); |
5111 | mutex_unlock(&ac->mutex); |
5112 | return ret; |
5113 | } |
5114 | diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c |
5115 | index b216131915e7..29e23b5cb2ed 100644 |
5116 | --- a/net/ceph/auth_x.c |
5117 | +++ b/net/ceph/auth_x.c |
5118 | @@ -8,6 +8,7 @@ |
5119 | |
5120 | #include <linux/ceph/decode.h> |
5121 | #include <linux/ceph/auth.h> |
5122 | +#include <linux/ceph/ceph_features.h> |
5123 | #include <linux/ceph/libceph.h> |
5124 | #include <linux/ceph/messenger.h> |
5125 | |
5126 | @@ -69,25 +70,40 @@ static int ceph_x_encrypt(struct ceph_crypto_key *secret, void *buf, |
5127 | return sizeof(u32) + ciphertext_len; |
5128 | } |
5129 | |
5130 | +static int __ceph_x_decrypt(struct ceph_crypto_key *secret, void *p, |
5131 | + int ciphertext_len) |
5132 | +{ |
5133 | + struct ceph_x_encrypt_header *hdr = p; |
5134 | + int plaintext_len; |
5135 | + int ret; |
5136 | + |
5137 | + ret = ceph_crypt(secret, false, p, ciphertext_len, ciphertext_len, |
5138 | + &plaintext_len); |
5139 | + if (ret) |
5140 | + return ret; |
5141 | + |
5142 | + if (le64_to_cpu(hdr->magic) != CEPHX_ENC_MAGIC) { |
5143 | + pr_err("%s bad magic\n", __func__); |
5144 | + return -EINVAL; |
5145 | + } |
5146 | + |
5147 | + return plaintext_len - sizeof(*hdr); |
5148 | +} |
5149 | + |
5150 | static int ceph_x_decrypt(struct ceph_crypto_key *secret, void **p, void *end) |
5151 | { |
5152 | - struct ceph_x_encrypt_header *hdr = *p + sizeof(u32); |
5153 | - int ciphertext_len, plaintext_len; |
5154 | + int ciphertext_len; |
5155 | int ret; |
5156 | |
5157 | ceph_decode_32_safe(p, end, ciphertext_len, e_inval); |
5158 | ceph_decode_need(p, end, ciphertext_len, e_inval); |
5159 | |
5160 | - ret = ceph_crypt(secret, false, *p, end - *p, ciphertext_len, |
5161 | - &plaintext_len); |
5162 | - if (ret) |
5163 | + ret = __ceph_x_decrypt(secret, *p, ciphertext_len); |
5164 | + if (ret < 0) |
5165 | return ret; |
5166 | |
5167 | - if (hdr->struct_v != 1 || le64_to_cpu(hdr->magic) != CEPHX_ENC_MAGIC) |
5168 | - return -EPERM; |
5169 | - |
5170 | *p += ciphertext_len; |
5171 | - return plaintext_len - sizeof(struct ceph_x_encrypt_header); |
5172 | + return ret; |
5173 | |
5174 | e_inval: |
5175 | return -EINVAL; |
5176 | @@ -271,6 +287,51 @@ bad: |
5177 | return -EINVAL; |
5178 | } |
5179 | |
5180 | +/* |
5181 | + * Encode and encrypt the second part (ceph_x_authorize_b) of the |
5182 | + * authorizer. The first part (ceph_x_authorize_a) should already be |
5183 | + * encoded. |
5184 | + */ |
5185 | +static int encrypt_authorizer(struct ceph_x_authorizer *au, |
5186 | + u64 *server_challenge) |
5187 | +{ |
5188 | + struct ceph_x_authorize_a *msg_a; |
5189 | + struct ceph_x_authorize_b *msg_b; |
5190 | + void *p, *end; |
5191 | + int ret; |
5192 | + |
5193 | + msg_a = au->buf->vec.iov_base; |
5194 | + WARN_ON(msg_a->ticket_blob.secret_id != cpu_to_le64(au->secret_id)); |
5195 | + p = (void *)(msg_a + 1) + le32_to_cpu(msg_a->ticket_blob.blob_len); |
5196 | + end = au->buf->vec.iov_base + au->buf->vec.iov_len; |
5197 | + |
5198 | + msg_b = p + ceph_x_encrypt_offset(); |
5199 | + msg_b->struct_v = 2; |
5200 | + msg_b->nonce = cpu_to_le64(au->nonce); |
5201 | + if (server_challenge) { |
5202 | + msg_b->have_challenge = 1; |
5203 | + msg_b->server_challenge_plus_one = |
5204 | + cpu_to_le64(*server_challenge + 1); |
5205 | + } else { |
5206 | + msg_b->have_challenge = 0; |
5207 | + msg_b->server_challenge_plus_one = 0; |
5208 | + } |
5209 | + |
5210 | + ret = ceph_x_encrypt(&au->session_key, p, end - p, sizeof(*msg_b)); |
5211 | + if (ret < 0) |
5212 | + return ret; |
5213 | + |
5214 | + p += ret; |
5215 | + if (server_challenge) { |
5216 | + WARN_ON(p != end); |
5217 | + } else { |
5218 | + WARN_ON(p > end); |
5219 | + au->buf->vec.iov_len = p - au->buf->vec.iov_base; |
5220 | + } |
5221 | + |
5222 | + return 0; |
5223 | +} |
5224 | + |
5225 | static void ceph_x_authorizer_cleanup(struct ceph_x_authorizer *au) |
5226 | { |
5227 | ceph_crypto_key_destroy(&au->session_key); |
5228 | @@ -287,7 +348,6 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac, |
5229 | int maxlen; |
5230 | struct ceph_x_authorize_a *msg_a; |
5231 | struct ceph_x_authorize_b *msg_b; |
5232 | - void *p, *end; |
5233 | int ret; |
5234 | int ticket_blob_len = |
5235 | (th->ticket_blob ? th->ticket_blob->vec.iov_len : 0); |
5236 | @@ -331,21 +391,13 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac, |
5237 | dout(" th %p secret_id %lld %lld\n", th, th->secret_id, |
5238 | le64_to_cpu(msg_a->ticket_blob.secret_id)); |
5239 | |
5240 | - p = msg_a + 1; |
5241 | - p += ticket_blob_len; |
5242 | - end = au->buf->vec.iov_base + au->buf->vec.iov_len; |
5243 | - |
5244 | - msg_b = p + ceph_x_encrypt_offset(); |
5245 | - msg_b->struct_v = 1; |
5246 | get_random_bytes(&au->nonce, sizeof(au->nonce)); |
5247 | - msg_b->nonce = cpu_to_le64(au->nonce); |
5248 | - ret = ceph_x_encrypt(&au->session_key, p, end - p, sizeof(*msg_b)); |
5249 | - if (ret < 0) |
5250 | + ret = encrypt_authorizer(au, NULL); |
5251 | + if (ret) { |
5252 | + pr_err("failed to encrypt authorizer: %d", ret); |
5253 | goto out_au; |
5254 | + } |
5255 | |
5256 | - p += ret; |
5257 | - WARN_ON(p > end); |
5258 | - au->buf->vec.iov_len = p - au->buf->vec.iov_base; |
5259 | dout(" built authorizer nonce %llx len %d\n", au->nonce, |
5260 | (int)au->buf->vec.iov_len); |
5261 | return 0; |
5262 | @@ -622,8 +674,56 @@ static int ceph_x_update_authorizer( |
5263 | return 0; |
5264 | } |
5265 | |
5266 | +static int decrypt_authorize_challenge(struct ceph_x_authorizer *au, |
5267 | + void *challenge_buf, |
5268 | + int challenge_buf_len, |
5269 | + u64 *server_challenge) |
5270 | +{ |
5271 | + struct ceph_x_authorize_challenge *ch = |
5272 | + challenge_buf + sizeof(struct ceph_x_encrypt_header); |
5273 | + int ret; |
5274 | + |
5275 | + /* no leading len */ |
5276 | + ret = __ceph_x_decrypt(&au->session_key, challenge_buf, |
5277 | + challenge_buf_len); |
5278 | + if (ret < 0) |
5279 | + return ret; |
5280 | + if (ret < sizeof(*ch)) { |
5281 | + pr_err("bad size %d for ceph_x_authorize_challenge\n", ret); |
5282 | + return -EINVAL; |
5283 | + } |
5284 | + |
5285 | + *server_challenge = le64_to_cpu(ch->server_challenge); |
5286 | + return 0; |
5287 | +} |
5288 | + |
5289 | +static int ceph_x_add_authorizer_challenge(struct ceph_auth_client *ac, |
5290 | + struct ceph_authorizer *a, |
5291 | + void *challenge_buf, |
5292 | + int challenge_buf_len) |
5293 | +{ |
5294 | + struct ceph_x_authorizer *au = (void *)a; |
5295 | + u64 server_challenge; |
5296 | + int ret; |
5297 | + |
5298 | + ret = decrypt_authorize_challenge(au, challenge_buf, challenge_buf_len, |
5299 | + &server_challenge); |
5300 | + if (ret) { |
5301 | + pr_err("failed to decrypt authorize challenge: %d", ret); |
5302 | + return ret; |
5303 | + } |
5304 | + |
5305 | + ret = encrypt_authorizer(au, &server_challenge); |
5306 | + if (ret) { |
5307 | + pr_err("failed to encrypt authorizer w/ challenge: %d", ret); |
5308 | + return ret; |
5309 | + } |
5310 | + |
5311 | + return 0; |
5312 | +} |
5313 | + |
5314 | static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, |
5315 | - struct ceph_authorizer *a, size_t len) |
5316 | + struct ceph_authorizer *a) |
5317 | { |
5318 | struct ceph_x_authorizer *au = (void *)a; |
5319 | void *p = au->enc_buf; |
5320 | @@ -633,8 +733,10 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, |
5321 | ret = ceph_x_decrypt(&au->session_key, &p, p + CEPHX_AU_ENC_BUF_LEN); |
5322 | if (ret < 0) |
5323 | return ret; |
5324 | - if (ret != sizeof(*reply)) |
5325 | - return -EPERM; |
5326 | + if (ret < sizeof(*reply)) { |
5327 | + pr_err("bad size %d for ceph_x_authorize_reply\n", ret); |
5328 | + return -EINVAL; |
5329 | + } |
5330 | |
5331 | if (au->nonce + 1 != le64_to_cpu(reply->nonce_plus_one)) |
5332 | ret = -EPERM; |
5333 | @@ -700,26 +802,64 @@ static int calc_signature(struct ceph_x_authorizer *au, struct ceph_msg *msg, |
5334 | __le64 *psig) |
5335 | { |
5336 | void *enc_buf = au->enc_buf; |
5337 | - struct { |
5338 | - __le32 len; |
5339 | - __le32 header_crc; |
5340 | - __le32 front_crc; |
5341 | - __le32 middle_crc; |
5342 | - __le32 data_crc; |
5343 | - } __packed *sigblock = enc_buf + ceph_x_encrypt_offset(); |
5344 | int ret; |
5345 | |
5346 | - sigblock->len = cpu_to_le32(4*sizeof(u32)); |
5347 | - sigblock->header_crc = msg->hdr.crc; |
5348 | - sigblock->front_crc = msg->footer.front_crc; |
5349 | - sigblock->middle_crc = msg->footer.middle_crc; |
5350 | - sigblock->data_crc = msg->footer.data_crc; |
5351 | - ret = ceph_x_encrypt(&au->session_key, enc_buf, CEPHX_AU_ENC_BUF_LEN, |
5352 | - sizeof(*sigblock)); |
5353 | - if (ret < 0) |
5354 | - return ret; |
5355 | + if (msg->con->peer_features & CEPH_FEATURE_CEPHX_V2) { |
5356 | + struct { |
5357 | + __le32 len; |
5358 | + __le32 header_crc; |
5359 | + __le32 front_crc; |
5360 | + __le32 middle_crc; |
5361 | + __le32 data_crc; |
5362 | + } __packed *sigblock = enc_buf + ceph_x_encrypt_offset(); |
5363 | + |
5364 | + sigblock->len = cpu_to_le32(4*sizeof(u32)); |
5365 | + sigblock->header_crc = msg->hdr.crc; |
5366 | + sigblock->front_crc = msg->footer.front_crc; |
5367 | + sigblock->middle_crc = msg->footer.middle_crc; |
5368 | + sigblock->data_crc = msg->footer.data_crc; |
5369 | + |
5370 | + ret = ceph_x_encrypt(&au->session_key, enc_buf, |
5371 | + CEPHX_AU_ENC_BUF_LEN, sizeof(*sigblock)); |
5372 | + if (ret < 0) |
5373 | + return ret; |
5374 | + |
5375 | + *psig = *(__le64 *)(enc_buf + sizeof(u32)); |
5376 | + } else { |
5377 | + struct { |
5378 | + __le32 header_crc; |
5379 | + __le32 front_crc; |
5380 | + __le32 front_len; |
5381 | + __le32 middle_crc; |
5382 | + __le32 middle_len; |
5383 | + __le32 data_crc; |
5384 | + __le32 data_len; |
5385 | + __le32 seq_lower_word; |
5386 | + } __packed *sigblock = enc_buf; |
5387 | + struct { |
5388 | + __le64 a, b, c, d; |
5389 | + } __packed *penc = enc_buf; |
5390 | + int ciphertext_len; |
5391 | + |
5392 | + sigblock->header_crc = msg->hdr.crc; |
5393 | + sigblock->front_crc = msg->footer.front_crc; |
5394 | + sigblock->front_len = msg->hdr.front_len; |
5395 | + sigblock->middle_crc = msg->footer.middle_crc; |
5396 | + sigblock->middle_len = msg->hdr.middle_len; |
5397 | + sigblock->data_crc = msg->footer.data_crc; |
5398 | + sigblock->data_len = msg->hdr.data_len; |
5399 | + sigblock->seq_lower_word = *(__le32 *)&msg->hdr.seq; |
5400 | + |
5401 | + /* no leading len, no ceph_x_encrypt_header */ |
5402 | + ret = ceph_crypt(&au->session_key, true, enc_buf, |
5403 | + CEPHX_AU_ENC_BUF_LEN, sizeof(*sigblock), |
5404 | + &ciphertext_len); |
5405 | + if (ret) |
5406 | + return ret; |
5407 | + |
5408 | + *psig = penc->a ^ penc->b ^ penc->c ^ penc->d; |
5409 | + } |
5410 | |
5411 | - *psig = *(__le64 *)(enc_buf + sizeof(u32)); |
5412 | return 0; |
5413 | } |
5414 | |
5415 | @@ -774,6 +914,7 @@ static const struct ceph_auth_client_ops ceph_x_ops = { |
5416 | .handle_reply = ceph_x_handle_reply, |
5417 | .create_authorizer = ceph_x_create_authorizer, |
5418 | .update_authorizer = ceph_x_update_authorizer, |
5419 | + .add_authorizer_challenge = ceph_x_add_authorizer_challenge, |
5420 | .verify_authorizer_reply = ceph_x_verify_authorizer_reply, |
5421 | .invalidate_authorizer = ceph_x_invalidate_authorizer, |
5422 | .reset = ceph_x_reset, |
5423 | diff --git a/net/ceph/auth_x_protocol.h b/net/ceph/auth_x_protocol.h |
5424 | index 671d30576c4f..a7cd203aacc2 100644 |
5425 | --- a/net/ceph/auth_x_protocol.h |
5426 | +++ b/net/ceph/auth_x_protocol.h |
5427 | @@ -69,6 +69,13 @@ struct ceph_x_authorize_a { |
5428 | struct ceph_x_authorize_b { |
5429 | __u8 struct_v; |
5430 | __le64 nonce; |
5431 | + __u8 have_challenge; |
5432 | + __le64 server_challenge_plus_one; |
5433 | +} __attribute__ ((packed)); |
5434 | + |
5435 | +struct ceph_x_authorize_challenge { |
5436 | + __u8 struct_v; |
5437 | + __le64 server_challenge; |
5438 | } __attribute__ ((packed)); |
5439 | |
5440 | struct ceph_x_authorize_reply { |
5441 | diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c |
5442 | index 68acf94fae72..5a8075d9f2e7 100644 |
5443 | --- a/net/ceph/messenger.c |
5444 | +++ b/net/ceph/messenger.c |
5445 | @@ -1394,30 +1394,26 @@ static void prepare_write_keepalive(struct ceph_connection *con) |
5446 | * Connection negotiation. |
5447 | */ |
5448 | |
5449 | -static struct ceph_auth_handshake *get_connect_authorizer(struct ceph_connection *con, |
5450 | - int *auth_proto) |
5451 | +static int get_connect_authorizer(struct ceph_connection *con) |
5452 | { |
5453 | struct ceph_auth_handshake *auth; |
5454 | + int auth_proto; |
5455 | |
5456 | if (!con->ops->get_authorizer) { |
5457 | + con->auth = NULL; |
5458 | con->out_connect.authorizer_protocol = CEPH_AUTH_UNKNOWN; |
5459 | con->out_connect.authorizer_len = 0; |
5460 | - return NULL; |
5461 | + return 0; |
5462 | } |
5463 | |
5464 | - /* Can't hold the mutex while getting authorizer */ |
5465 | - mutex_unlock(&con->mutex); |
5466 | - auth = con->ops->get_authorizer(con, auth_proto, con->auth_retry); |
5467 | - mutex_lock(&con->mutex); |
5468 | - |
5469 | + auth = con->ops->get_authorizer(con, &auth_proto, con->auth_retry); |
5470 | if (IS_ERR(auth)) |
5471 | - return auth; |
5472 | - if (con->state != CON_STATE_NEGOTIATING) |
5473 | - return ERR_PTR(-EAGAIN); |
5474 | + return PTR_ERR(auth); |
5475 | |
5476 | - con->auth_reply_buf = auth->authorizer_reply_buf; |
5477 | - con->auth_reply_buf_len = auth->authorizer_reply_buf_len; |
5478 | - return auth; |
5479 | + con->auth = auth; |
5480 | + con->out_connect.authorizer_protocol = cpu_to_le32(auth_proto); |
5481 | + con->out_connect.authorizer_len = cpu_to_le32(auth->authorizer_buf_len); |
5482 | + return 0; |
5483 | } |
5484 | |
5485 | /* |
5486 | @@ -1433,12 +1429,22 @@ static void prepare_write_banner(struct ceph_connection *con) |
5487 | con_flag_set(con, CON_FLAG_WRITE_PENDING); |
5488 | } |
5489 | |
5490 | +static void __prepare_write_connect(struct ceph_connection *con) |
5491 | +{ |
5492 | + con_out_kvec_add(con, sizeof(con->out_connect), &con->out_connect); |
5493 | + if (con->auth) |
5494 | + con_out_kvec_add(con, con->auth->authorizer_buf_len, |
5495 | + con->auth->authorizer_buf); |
5496 | + |
5497 | + con->out_more = 0; |
5498 | + con_flag_set(con, CON_FLAG_WRITE_PENDING); |
5499 | +} |
5500 | + |
5501 | static int prepare_write_connect(struct ceph_connection *con) |
5502 | { |
5503 | unsigned int global_seq = get_global_seq(con->msgr, 0); |
5504 | int proto; |
5505 | - int auth_proto; |
5506 | - struct ceph_auth_handshake *auth; |
5507 | + int ret; |
5508 | |
5509 | switch (con->peer_name.type) { |
5510 | case CEPH_ENTITY_TYPE_MON: |
5511 | @@ -1465,24 +1471,11 @@ static int prepare_write_connect(struct ceph_connection *con) |
5512 | con->out_connect.protocol_version = cpu_to_le32(proto); |
5513 | con->out_connect.flags = 0; |
5514 | |
5515 | - auth_proto = CEPH_AUTH_UNKNOWN; |
5516 | - auth = get_connect_authorizer(con, &auth_proto); |
5517 | - if (IS_ERR(auth)) |
5518 | - return PTR_ERR(auth); |
5519 | - |
5520 | - con->out_connect.authorizer_protocol = cpu_to_le32(auth_proto); |
5521 | - con->out_connect.authorizer_len = auth ? |
5522 | - cpu_to_le32(auth->authorizer_buf_len) : 0; |
5523 | - |
5524 | - con_out_kvec_add(con, sizeof (con->out_connect), |
5525 | - &con->out_connect); |
5526 | - if (auth && auth->authorizer_buf_len) |
5527 | - con_out_kvec_add(con, auth->authorizer_buf_len, |
5528 | - auth->authorizer_buf); |
5529 | - |
5530 | - con->out_more = 0; |
5531 | - con_flag_set(con, CON_FLAG_WRITE_PENDING); |
5532 | + ret = get_connect_authorizer(con); |
5533 | + if (ret) |
5534 | + return ret; |
5535 | |
5536 | + __prepare_write_connect(con); |
5537 | return 0; |
5538 | } |
5539 | |
5540 | @@ -1743,11 +1736,21 @@ static int read_partial_connect(struct ceph_connection *con) |
5541 | if (ret <= 0) |
5542 | goto out; |
5543 | |
5544 | - size = le32_to_cpu(con->in_reply.authorizer_len); |
5545 | - end += size; |
5546 | - ret = read_partial(con, end, size, con->auth_reply_buf); |
5547 | - if (ret <= 0) |
5548 | - goto out; |
5549 | + if (con->auth) { |
5550 | + size = le32_to_cpu(con->in_reply.authorizer_len); |
5551 | + if (size > con->auth->authorizer_reply_buf_len) { |
5552 | + pr_err("authorizer reply too big: %d > %zu\n", size, |
5553 | + con->auth->authorizer_reply_buf_len); |
5554 | + ret = -EINVAL; |
5555 | + goto out; |
5556 | + } |
5557 | + |
5558 | + end += size; |
5559 | + ret = read_partial(con, end, size, |
5560 | + con->auth->authorizer_reply_buf); |
5561 | + if (ret <= 0) |
5562 | + goto out; |
5563 | + } |
5564 | |
5565 | dout("read_partial_connect %p tag %d, con_seq = %u, g_seq = %u\n", |
5566 | con, (int)con->in_reply.tag, |
5567 | @@ -1755,7 +1758,6 @@ static int read_partial_connect(struct ceph_connection *con) |
5568 | le32_to_cpu(con->in_reply.global_seq)); |
5569 | out: |
5570 | return ret; |
5571 | - |
5572 | } |
5573 | |
5574 | /* |
5575 | @@ -2039,13 +2041,28 @@ static int process_connect(struct ceph_connection *con) |
5576 | |
5577 | dout("process_connect on %p tag %d\n", con, (int)con->in_tag); |
5578 | |
5579 | - if (con->auth_reply_buf) { |
5580 | + if (con->auth) { |
5581 | /* |
5582 | * Any connection that defines ->get_authorizer() |
5583 | - * should also define ->verify_authorizer_reply(). |
5584 | + * should also define ->add_authorizer_challenge() and |
5585 | + * ->verify_authorizer_reply(). |
5586 | + * |
5587 | * See get_connect_authorizer(). |
5588 | */ |
5589 | - ret = con->ops->verify_authorizer_reply(con, 0); |
5590 | + if (con->in_reply.tag == CEPH_MSGR_TAG_CHALLENGE_AUTHORIZER) { |
5591 | + ret = con->ops->add_authorizer_challenge( |
5592 | + con, con->auth->authorizer_reply_buf, |
5593 | + le32_to_cpu(con->in_reply.authorizer_len)); |
5594 | + if (ret < 0) |
5595 | + return ret; |
5596 | + |
5597 | + con_out_kvec_reset(con); |
5598 | + __prepare_write_connect(con); |
5599 | + prepare_read_connect(con); |
5600 | + return 0; |
5601 | + } |
5602 | + |
5603 | + ret = con->ops->verify_authorizer_reply(con); |
5604 | if (ret < 0) { |
5605 | con->error_msg = "bad authorize reply"; |
5606 | return ret; |
5607 | diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c |
5608 | index 0ffeb60cfe67..70ccb0716fc5 100644 |
5609 | --- a/net/ceph/osd_client.c |
5610 | +++ b/net/ceph/osd_client.c |
5611 | @@ -4478,14 +4478,24 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con, |
5612 | return auth; |
5613 | } |
5614 | |
5615 | +static int add_authorizer_challenge(struct ceph_connection *con, |
5616 | + void *challenge_buf, int challenge_buf_len) |
5617 | +{ |
5618 | + struct ceph_osd *o = con->private; |
5619 | + struct ceph_osd_client *osdc = o->o_osdc; |
5620 | + struct ceph_auth_client *ac = osdc->client->monc.auth; |
5621 | + |
5622 | + return ceph_auth_add_authorizer_challenge(ac, o->o_auth.authorizer, |
5623 | + challenge_buf, challenge_buf_len); |
5624 | +} |
5625 | |
5626 | -static int verify_authorizer_reply(struct ceph_connection *con, int len) |
5627 | +static int verify_authorizer_reply(struct ceph_connection *con) |
5628 | { |
5629 | struct ceph_osd *o = con->private; |
5630 | struct ceph_osd_client *osdc = o->o_osdc; |
5631 | struct ceph_auth_client *ac = osdc->client->monc.auth; |
5632 | |
5633 | - return ceph_auth_verify_authorizer_reply(ac, o->o_auth.authorizer, len); |
5634 | + return ceph_auth_verify_authorizer_reply(ac, o->o_auth.authorizer); |
5635 | } |
5636 | |
5637 | static int invalidate_authorizer(struct ceph_connection *con) |
5638 | @@ -4519,6 +4529,7 @@ static const struct ceph_connection_operations osd_con_ops = { |
5639 | .put = put_osd_con, |
5640 | .dispatch = dispatch, |
5641 | .get_authorizer = get_authorizer, |
5642 | + .add_authorizer_challenge = add_authorizer_challenge, |
5643 | .verify_authorizer_reply = verify_authorizer_reply, |
5644 | .invalidate_authorizer = invalidate_authorizer, |
5645 | .alloc_msg = alloc_msg, |
5646 | diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c |
5647 | index d8d99c21a9c1..e6ee6acac80c 100644 |
5648 | --- a/net/ipv4/ip_tunnel.c |
5649 | +++ b/net/ipv4/ip_tunnel.c |
5650 | @@ -261,8 +261,8 @@ static struct net_device *__ip_tunnel_create(struct net *net, |
5651 | } else { |
5652 | if (strlen(ops->kind) > (IFNAMSIZ - 3)) |
5653 | goto failed; |
5654 | - strlcpy(name, ops->kind, IFNAMSIZ); |
5655 | - strncat(name, "%d", 2); |
5656 | + strcpy(name, ops->kind); |
5657 | + strcat(name, "%d"); |
5658 | } |
5659 | |
5660 | ASSERT_RTNL(); |
5661 | diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c |
5662 | index c2646446e157..d62affeb2a38 100644 |
5663 | --- a/net/tipc/subscr.c |
5664 | +++ b/net/tipc/subscr.c |
5665 | @@ -389,7 +389,7 @@ int tipc_topsrv_start(struct net *net) |
5666 | topsrv->tipc_conn_new = tipc_subscrb_connect_cb; |
5667 | topsrv->tipc_conn_release = tipc_subscrb_release_cb; |
5668 | |
5669 | - strncpy(topsrv->name, name, strlen(name) + 1); |
5670 | + strscpy(topsrv->name, name, sizeof(topsrv->name)); |
5671 | tn->topsrv = topsrv; |
5672 | atomic_set(&tn->subscription_count, 0); |
5673 | |
5674 | diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn |
5675 | index fb3522fd8702..d08b6fbdfa85 100644 |
5676 | --- a/scripts/Makefile.extrawarn |
5677 | +++ b/scripts/Makefile.extrawarn |
5678 | @@ -10,6 +10,8 @@ |
5679 | # are not supported by all versions of the compiler |
5680 | # ========================================================================== |
5681 | |
5682 | +KBUILD_CFLAGS += $(call cc-disable-warning, packed-not-aligned) |
5683 | + |
5684 | ifeq ("$(origin W)", "command line") |
5685 | export KBUILD_ENABLE_EXTRA_GCC_CHECKS := $(W) |
5686 | endif |
5687 | @@ -25,6 +27,7 @@ warning-1 += -Wold-style-definition |
5688 | warning-1 += $(call cc-option, -Wmissing-include-dirs) |
5689 | warning-1 += $(call cc-option, -Wunused-but-set-variable) |
5690 | warning-1 += $(call cc-option, -Wunused-const-variable) |
5691 | +warning-1 += $(call cc-option, -Wpacked-not-aligned) |
5692 | warning-1 += $(call cc-disable-warning, missing-field-initializers) |
5693 | warning-1 += $(call cc-disable-warning, sign-compare) |
5694 | |
5695 | diff --git a/scripts/unifdef.c b/scripts/unifdef.c |
5696 | index 7493c0ee51cc..db00e3e30a59 100644 |
5697 | --- a/scripts/unifdef.c |
5698 | +++ b/scripts/unifdef.c |
5699 | @@ -395,7 +395,7 @@ usage(void) |
5700 | * When we have processed a group that starts off with a known-false |
5701 | * #if/#elif sequence (which has therefore been deleted) followed by a |
5702 | * #elif that we don't understand and therefore must keep, we edit the |
5703 | - * latter into a #if to keep the nesting correct. We use strncpy() to |
5704 | + * latter into a #if to keep the nesting correct. We use memcpy() to |
5705 | * overwrite the 4 byte token "elif" with "if " without a '\0' byte. |
5706 | * |
5707 | * When we find a true #elif in a group, the following block will |
5708 | @@ -450,7 +450,7 @@ static void Idrop (void) { Fdrop(); ignoreon(); } |
5709 | static void Itrue (void) { Ftrue(); ignoreon(); } |
5710 | static void Ifalse(void) { Ffalse(); ignoreon(); } |
5711 | /* modify this line */ |
5712 | -static void Mpass (void) { strncpy(keyword, "if ", 4); Pelif(); } |
5713 | +static void Mpass (void) { memcpy(keyword, "if ", 4); Pelif(); } |
5714 | static void Mtrue (void) { keywordedit("else"); state(IS_TRUE_MIDDLE); } |
5715 | static void Melif (void) { keywordedit("endif"); state(IS_FALSE_TRAILER); } |
5716 | static void Melse (void) { keywordedit("endif"); state(IS_FALSE_ELSE); } |
5717 | diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c |
5718 | index cedf13b64803..2f18b1cdc2cd 100644 |
5719 | --- a/sound/pci/trident/trident.c |
5720 | +++ b/sound/pci/trident/trident.c |
5721 | @@ -123,7 +123,7 @@ static int snd_trident_probe(struct pci_dev *pci, |
5722 | } else { |
5723 | strcpy(card->shortname, "Trident "); |
5724 | } |
5725 | - strcat(card->shortname, card->driver); |
5726 | + strcat(card->shortname, str); |
5727 | sprintf(card->longname, "%s PCI Audio at 0x%lx, irq %d", |
5728 | card->shortname, trident->port, trident->irq); |
5729 |