Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'mm-nonmm-stable-2022-05-26' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull misc updates from Andrew Morton:
"The non-MM patch queue for this merge window.

Not a lot of material this cycle. Many singleton patches against
various subsystems. Most notably some maintenance work in ocfs2
and initramfs"

* tag 'mm-nonmm-stable-2022-05-26' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (65 commits)
kcov: update pos before writing pc in trace function
ocfs2: dlmfs: fix error handling of user_dlm_destroy_lock
ocfs2: dlmfs: don't clear USER_LOCK_ATTACHED when destroying lock
fs/ntfs: remove redundant variable idx
fat: remove time truncations in vfat_create/vfat_mkdir
fat: report creation time in statx
fat: ignore ctime updates, and keep ctime identical to mtime in memory
fat: split fat_truncate_time() into separate functions
MAINTAINERS: add Muchun as a memcg reviewer
proc/sysctl: make protected_* world readable
ia64: mca: drop redundant spinlock initialization
tty: fix deadlock caused by calling printk() under tty_port->lock
relay: remove redundant assignment to pointer buf
fs/ntfs3: validate BOOT sectors_per_clusters
lib/string_helpers: fix not adding strarray to device's resource list
kernel/crash_core.c: remove redundant check of ck_cmdline
ELF, uapi: fixup ELF_ST_TYPE definition
ipc/mqueue: use get_tree_nodev() in mqueue_get_tree()
ipc: update semtimedop() to use hrtimer
ipc/sem: remove redundant assignments
...

+1182 -707
+1 -1
MAINTAINERS
··· 5056 5056 M: Michal Hocko <mhocko@kernel.org> 5057 5057 M: Roman Gushchin <roman.gushchin@linux.dev> 5058 5058 M: Shakeel Butt <shakeelb@google.com> 5059 + R: Muchun Song <songmuchun@bytedance.com> 5059 5060 L: cgroups@vger.kernel.org 5060 5061 L: linux-mm@kvack.org 5061 5062 S: Maintained ··· 16097 16096 F: include/asm-generic/syscall.h 16098 16097 F: include/linux/ptrace.h 16099 16098 F: include/linux/regset.h 16100 - F: include/uapi/linux/ptrace.h 16101 16099 F: include/uapi/linux/ptrace.h 16102 16100 F: kernel/ptrace.c 16103 16101
-1
arch/alpha/lib/csum_partial_copy.c
··· 353 353 return 0; 354 354 return __csum_and_copy(src, dst, len); 355 355 } 356 - EXPORT_SYMBOL(csum_and_copy_from_user); 357 356 358 357 __wsum 359 358 csum_partial_copy_nocheck(const void *src, void *dst, int len)
+4 -23
arch/arm/kernel/crash_dump.c
··· 14 14 #include <linux/crash_dump.h> 15 15 #include <linux/uaccess.h> 16 16 #include <linux/io.h> 17 + #include <linux/uio.h> 17 18 18 - /** 19 - * copy_oldmem_page() - copy one page from old kernel memory 20 - * @pfn: page frame number to be copied 21 - * @buf: buffer where the copied page is placed 22 - * @csize: number of bytes to copy 23 - * @offset: offset in bytes into the page 24 - * @userbuf: if set, @buf is int he user address space 25 - * 26 - * This function copies one page from old kernel memory into buffer pointed by 27 - * @buf. If @buf is in userspace, set @userbuf to %1. Returns number of bytes 28 - * copied or negative error in case of failure. 29 - */ 30 - ssize_t copy_oldmem_page(unsigned long pfn, char *buf, 31 - size_t csize, unsigned long offset, 32 - int userbuf) 19 + ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, 20 + size_t csize, unsigned long offset) 33 21 { 34 22 void *vaddr; 35 23 ··· 28 40 if (!vaddr) 29 41 return -ENOMEM; 30 42 31 - if (userbuf) { 32 - if (copy_to_user(buf, vaddr + offset, csize)) { 33 - iounmap(vaddr); 34 - return -EFAULT; 35 - } 36 - } else { 37 - memcpy(buf, vaddr + offset, csize); 38 - } 43 + csize = copy_to_iter(vaddr + offset, csize, iter); 39 44 40 45 iounmap(vaddr); 41 46 return csize;
+4 -25
arch/arm64/kernel/crash_dump.c
··· 9 9 #include <linux/crash_dump.h> 10 10 #include <linux/errno.h> 11 11 #include <linux/io.h> 12 - #include <linux/memblock.h> 13 - #include <linux/uaccess.h> 12 + #include <linux/uio.h> 14 13 #include <asm/memory.h> 15 14 16 - /** 17 - * copy_oldmem_page() - copy one page from old kernel memory 18 - * @pfn: page frame number to be copied 19 - * @buf: buffer where the copied page is placed 20 - * @csize: number of bytes to copy 21 - * @offset: offset in bytes into the page 22 - * @userbuf: if set, @buf is in a user address space 23 - * 24 - * This function copies one page from old kernel memory into buffer pointed by 25 - * @buf. If @buf is in userspace, set @userbuf to %1. Returns number of bytes 26 - * copied or negative error in case of failure. 27 - */ 28 - ssize_t copy_oldmem_page(unsigned long pfn, char *buf, 29 - size_t csize, unsigned long offset, 30 - int userbuf) 15 + ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, 16 + size_t csize, unsigned long offset) 31 17 { 32 18 void *vaddr; 33 19 ··· 24 38 if (!vaddr) 25 39 return -ENOMEM; 26 40 27 - if (userbuf) { 28 - if (copy_to_user((char __user *)buf, vaddr + offset, csize)) { 29 - memunmap(vaddr); 30 - return -EFAULT; 31 - } 32 - } else { 33 - memcpy(buf, vaddr + offset, csize); 34 - } 41 + csize = copy_to_iter(vaddr + offset, csize, iter); 35 42 36 43 memunmap(vaddr); 37 44
+4 -28
arch/ia64/kernel/crash_dump.c
··· 10 10 #include <linux/errno.h> 11 11 #include <linux/types.h> 12 12 #include <linux/crash_dump.h> 13 - 13 + #include <linux/uio.h> 14 14 #include <asm/page.h> 15 - #include <linux/uaccess.h> 16 15 17 - /** 18 - * copy_oldmem_page - copy one page from "oldmem" 19 - * @pfn: page frame number to be copied 20 - * @buf: target memory address for the copy; this can be in kernel address 21 - * space or user address space (see @userbuf) 22 - * @csize: number of bytes to copy 23 - * @offset: offset in bytes into the page (based on pfn) to begin the copy 24 - * @userbuf: if set, @buf is in user address space, use copy_to_user(), 25 - * otherwise @buf is in kernel address space, use memcpy(). 26 - * 27 - * Copy a page from "oldmem". For this page, there is no pte mapped 28 - * in the current kernel. We stitch up a pte, similar to kmap_atomic. 29 - * 30 - * Calling copy_to_user() in atomic context is not desirable. Hence first 31 - * copying the data to a pre-allocated kernel page and then copying to user 32 - * space in non-atomic context. 33 - */ 34 - ssize_t 35 - copy_oldmem_page(unsigned long pfn, char *buf, 36 - size_t csize, unsigned long offset, int userbuf) 16 + ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, 17 + size_t csize, unsigned long offset) 37 18 { 38 19 void *vaddr; 39 20 40 21 if (!csize) 41 22 return 0; 42 23 vaddr = __va(pfn<<PAGE_SHIFT); 43 - if (userbuf) { 44 - if (copy_to_user(buf, (vaddr + offset), csize)) { 45 - return -EFAULT; 46 - } 47 - } else 48 - memcpy(buf, (vaddr + offset), csize); 24 + csize = copy_to_iter(vaddr + offset, csize, iter); 49 25 return csize; 50 26 } 51 27
+32 -32
arch/ia64/kernel/kprobes.c
··· 29 29 30 30 enum instruction_type {A, I, M, F, B, L, X, u}; 31 31 static enum instruction_type bundle_encoding[32][3] = { 32 - { M, I, I }, /* 00 */ 33 - { M, I, I }, /* 01 */ 34 - { M, I, I }, /* 02 */ 35 - { M, I, I }, /* 03 */ 36 - { M, L, X }, /* 04 */ 37 - { M, L, X }, /* 05 */ 38 - { u, u, u }, /* 06 */ 39 - { u, u, u }, /* 07 */ 40 - { M, M, I }, /* 08 */ 41 - { M, M, I }, /* 09 */ 42 - { M, M, I }, /* 0A */ 43 - { M, M, I }, /* 0B */ 44 - { M, F, I }, /* 0C */ 45 - { M, F, I }, /* 0D */ 46 - { M, M, F }, /* 0E */ 47 - { M, M, F }, /* 0F */ 48 - { M, I, B }, /* 10 */ 49 - { M, I, B }, /* 11 */ 50 - { M, B, B }, /* 12 */ 51 - { M, B, B }, /* 13 */ 52 - { u, u, u }, /* 14 */ 53 - { u, u, u }, /* 15 */ 54 - { B, B, B }, /* 16 */ 55 - { B, B, B }, /* 17 */ 56 - { M, M, B }, /* 18 */ 57 - { M, M, B }, /* 19 */ 58 - { u, u, u }, /* 1A */ 59 - { u, u, u }, /* 1B */ 60 - { M, F, B }, /* 1C */ 61 - { M, F, B }, /* 1D */ 62 - { u, u, u }, /* 1E */ 63 - { u, u, u }, /* 1F */ 32 + [0x00] = { M, I, I }, 33 + [0x01] = { M, I, I }, 34 + [0x02] = { M, I, I }, 35 + [0x03] = { M, I, I }, 36 + [0x04] = { M, L, X }, 37 + [0x05] = { M, L, X }, 38 + [0x06] = { u, u, u }, 39 + [0x07] = { u, u, u }, 40 + [0x08] = { M, M, I }, 41 + [0x09] = { M, M, I }, 42 + [0x0A] = { M, M, I }, 43 + [0x0B] = { M, M, I }, 44 + [0x0C] = { M, F, I }, 45 + [0x0D] = { M, F, I }, 46 + [0x0E] = { M, M, F }, 47 + [0x0F] = { M, M, F }, 48 + [0x10] = { M, I, B }, 49 + [0x11] = { M, I, B }, 50 + [0x12] = { M, B, B }, 51 + [0x13] = { M, B, B }, 52 + [0x14] = { u, u, u }, 53 + [0x15] = { u, u, u }, 54 + [0x16] = { B, B, B }, 55 + [0x17] = { B, B, B }, 56 + [0x18] = { M, M, B }, 57 + [0x19] = { M, M, B }, 58 + [0x1A] = { u, u, u }, 59 + [0x1B] = { u, u, u }, 60 + [0x1C] = { M, F, B }, 61 + [0x1D] = { M, F, B }, 62 + [0x1E] = { u, u, u }, 63 + [0x1F] = { u, u, u }, 64 64 }; 65 65 66 66 /* Insert a long branch code */
-1
arch/ia64/kernel/mca.c
··· 290 290 { 291 291 BREAK_LOGLEVEL(console_loglevel); 292 292 293 - spin_lock_init(&mlogbuf_rlock); 294 293 ia64_mlogbuf_dump(); 295 294 printk(KERN_EMERG "mlogbuf_finish: printing switched to urgent mode, " 296 295 "MCA/INIT might be dodgy or fail.\n");
+1 -1
arch/ia64/kernel/palinfo.c
··· 120 120 * Input: 121 121 * - a pointer to a buffer to hold the string 122 122 * - a 64-bit vector 123 - * Ouput: 123 + * Output: 124 124 * - a pointer to the end of the buffer 125 125 * 126 126 */
+1 -1
arch/ia64/kernel/ptrace.c
··· 2025 2025 * - epsinstruction: cfm is set by br.call 2026 2026 * locals don't exist. 2027 2027 * 2028 - * For both cases argguments are reachable in cfm.sof - cfm.sol. 2028 + * For both cases arguments are reachable in cfm.sof - cfm.sol. 2029 2029 * CFM: [ ... | sor: 17..14 | sol : 13..7 | sof : 6..0 ] 2030 2030 */ 2031 2031 cfm = pt->cr_ifs;
+1 -1
arch/ia64/kernel/traps.c
··· 309 309 /* 310 310 * Lower 4 bits are used as a count. Upper bits are a sequence 311 311 * number that is updated when count is reset. The cmpxchg will 312 - * fail is seqno has changed. This minimizes mutiple cpus 312 + * fail is seqno has changed. This minimizes multiple cpus 313 313 * resetting the count. 314 314 */ 315 315 if (current_jiffies > last.time)
+1 -1
arch/ia64/mm/init.c
··· 449 449 memblock_free_all(); 450 450 451 451 /* 452 - * For fsyscall entrpoints with no light-weight handler, use the ordinary 452 + * For fsyscall entrypoints with no light-weight handler, use the ordinary 453 453 * (heavy-weight) handler, but mark it by setting bit 0, so the fsyscall entry 454 454 * code can tell them apart. 455 455 */
+2 -2
arch/ia64/mm/tlb.c
··· 174 174 * override table (in which case we should ignore the value from 175 175 * PAL_VM_SUMMARY). 176 176 * 177 - * Kernel parameter "nptcg=" overrides maximum number of simultanesous ptc.g 177 + * Kernel parameter "nptcg=" overrides maximum number of simultaneous ptc.g 178 178 * purges defined in either PAL_VM_SUMMARY or PAL override table. In this case, 179 179 * we should ignore the value from either PAL_VM_SUMMARY or PAL override table. 180 180 * ··· 516 516 if (i >= per_cpu(ia64_tr_num, cpu)) 517 517 return -EBUSY; 518 518 519 - /*Record tr info for mca hander use!*/ 519 + /*Record tr info for mca handler use!*/ 520 520 if (i > per_cpu(ia64_tr_used, cpu)) 521 521 per_cpu(ia64_tr_used, cpu) = i; 522 522
-2
arch/m68k/lib/checksum.c
··· 265 265 return sum; 266 266 } 267 267 268 - EXPORT_SYMBOL(csum_and_copy_from_user); 269 - 270 268 271 269 /* 272 270 * copy from kernel space while checksumming, otherwise like csum_partial
+4 -23
arch/mips/kernel/crash_dump.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 #include <linux/highmem.h> 3 3 #include <linux/crash_dump.h> 4 + #include <linux/uio.h> 4 5 5 - /** 6 - * copy_oldmem_page - copy one page from "oldmem" 7 - * @pfn: page frame number to be copied 8 - * @buf: target memory address for the copy; this can be in kernel address 9 - * space or user address space (see @userbuf) 10 - * @csize: number of bytes to copy 11 - * @offset: offset in bytes into the page (based on pfn) to begin the copy 12 - * @userbuf: if set, @buf is in user address space, use copy_to_user(), 13 - * otherwise @buf is in kernel address space, use memcpy(). 14 - * 15 - * Copy a page from "oldmem". For this page, there is no pte mapped 16 - * in the current kernel. 17 - */ 18 - ssize_t copy_oldmem_page(unsigned long pfn, char *buf, 19 - size_t csize, unsigned long offset, int userbuf) 6 + ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, 7 + size_t csize, unsigned long offset) 20 8 { 21 9 void *vaddr; 22 10 ··· 12 24 return 0; 13 25 14 26 vaddr = kmap_local_pfn(pfn); 15 - 16 - if (!userbuf) { 17 - memcpy(buf, vaddr + offset, csize); 18 - } else { 19 - if (copy_to_user(buf, vaddr + offset, csize)) 20 - csize = -EFAULT; 21 - } 22 - 27 + csize = copy_to_iter(vaddr + offset, csize, iter); 23 28 kunmap_local(vaddr); 24 29 25 30 return csize;
+5 -30
arch/powerpc/kernel/crash_dump.c
··· 16 16 #include <asm/kdump.h> 17 17 #include <asm/prom.h> 18 18 #include <asm/firmware.h> 19 - #include <linux/uaccess.h> 19 + #include <linux/uio.h> 20 20 #include <asm/rtas.h> 21 21 #include <asm/inst.h> 22 22 ··· 68 68 } 69 69 #endif /* CONFIG_NONSTATIC_KERNEL */ 70 70 71 - static size_t copy_oldmem_vaddr(void *vaddr, char *buf, size_t csize, 72 - unsigned long offset, int userbuf) 73 - { 74 - if (userbuf) { 75 - if (copy_to_user((char __user *)buf, (vaddr + offset), csize)) 76 - return -EFAULT; 77 - } else 78 - memcpy(buf, (vaddr + offset), csize); 79 - 80 - return csize; 81 - } 82 - 83 - /** 84 - * copy_oldmem_page - copy one page from "oldmem" 85 - * @pfn: page frame number to be copied 86 - * @buf: target memory address for the copy; this can be in kernel address 87 - * space or user address space (see @userbuf) 88 - * @csize: number of bytes to copy 89 - * @offset: offset in bytes into the page (based on pfn) to begin the copy 90 - * @userbuf: if set, @buf is in user address space, use copy_to_user(), 91 - * otherwise @buf is in kernel address space, use memcpy(). 92 - * 93 - * Copy a page from "oldmem". For this page, there is no pte mapped 94 - * in the current kernel. We stitch up a pte, similar to kmap_atomic. 95 - */ 96 - ssize_t copy_oldmem_page(unsigned long pfn, char *buf, 97 - size_t csize, unsigned long offset, int userbuf) 71 + ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, 72 + size_t csize, unsigned long offset) 98 73 { 99 74 void *vaddr; 100 75 phys_addr_t paddr; ··· 82 107 83 108 if (memblock_is_region_memory(paddr, csize)) { 84 109 vaddr = __va(paddr); 85 - csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); 110 + csize = copy_to_iter(vaddr + offset, csize, iter); 86 111 } else { 87 112 vaddr = ioremap_cache(paddr, PAGE_SIZE); 88 - csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); 113 + csize = copy_to_iter(vaddr + offset, csize, iter); 89 114 iounmap(vaddr); 90 115 } 91 116
-2
arch/powerpc/lib/checksum_wrappers.c
··· 24 24 user_read_access_end(); 25 25 return csum; 26 26 } 27 - EXPORT_SYMBOL(csum_and_copy_from_user); 28 27 29 28 __wsum csum_and_copy_to_user(const void *src, void __user *dst, int len) 30 29 { ··· 37 38 user_write_access_end(); 38 39 return csum; 39 40 } 40 - EXPORT_SYMBOL(csum_and_copy_to_user);
+4 -22
arch/riscv/kernel/crash_dump.c
··· 7 7 8 8 #include <linux/crash_dump.h> 9 9 #include <linux/io.h> 10 + #include <linux/uio.h> 10 11 11 - /** 12 - * copy_oldmem_page() - copy one page from old kernel memory 13 - * @pfn: page frame number to be copied 14 - * @buf: buffer where the copied page is placed 15 - * @csize: number of bytes to copy 16 - * @offset: offset in bytes into the page 17 - * @userbuf: if set, @buf is in a user address space 18 - * 19 - * This function copies one page from old kernel memory into buffer pointed by 20 - * @buf. If @buf is in userspace, set @userbuf to %1. Returns number of bytes 21 - * copied or negative error in case of failure. 22 - */ 23 - ssize_t copy_oldmem_page(unsigned long pfn, char *buf, 24 - size_t csize, unsigned long offset, 25 - int userbuf) 12 + ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, 13 + size_t csize, unsigned long offset) 26 14 { 27 15 void *vaddr; 28 16 ··· 21 33 if (!vaddr) 22 34 return -ENOMEM; 23 35 24 - if (userbuf) { 25 - if (copy_to_user((char __user *)buf, vaddr + offset, csize)) { 26 - memunmap(vaddr); 27 - return -EFAULT; 28 - } 29 - } else 30 - memcpy(buf, vaddr + offset, csize); 36 + csize = copy_to_iter(vaddr + offset, csize, iter); 31 37 32 38 memunmap(vaddr); 33 39 return csize;
+8 -5
arch/s390/kernel/crash_dump.c
··· 15 15 #include <linux/slab.h> 16 16 #include <linux/memblock.h> 17 17 #include <linux/elf.h> 18 + #include <linux/uio.h> 18 19 #include <asm/asm-offsets.h> 19 20 #include <asm/os_info.h> 20 21 #include <asm/elf.h> ··· 213 212 /* 214 213 * Copy one page from "oldmem" 215 214 */ 216 - ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, 217 - unsigned long offset, int userbuf) 215 + ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, size_t csize, 216 + unsigned long offset) 218 217 { 219 218 unsigned long src; 220 219 int rc; ··· 222 221 if (!csize) 223 222 return 0; 224 223 src = pfn_to_phys(pfn) + offset; 225 - if (userbuf) 226 - rc = copy_oldmem_user((void __force __user *) buf, src, csize); 224 + 225 + /* XXX: pass the iov_iter down to a common function */ 226 + if (iter_is_iovec(iter)) 227 + rc = copy_oldmem_user(iter->iov->iov_base, src, csize); 227 228 else 228 - rc = copy_oldmem_kernel((void *) buf, src, csize); 229 + rc = copy_oldmem_kernel(iter->kvec->iov_base, src, csize); 229 230 return rc; 230 231 } 231 232
+5 -24
arch/sh/kernel/crash_dump.c
··· 8 8 #include <linux/errno.h> 9 9 #include <linux/crash_dump.h> 10 10 #include <linux/io.h> 11 + #include <linux/uio.h> 11 12 #include <linux/uaccess.h> 12 13 13 - /** 14 - * copy_oldmem_page - copy one page from "oldmem" 15 - * @pfn: page frame number to be copied 16 - * @buf: target memory address for the copy; this can be in kernel address 17 - * space or user address space (see @userbuf) 18 - * @csize: number of bytes to copy 19 - * @offset: offset in bytes into the page (based on pfn) to begin the copy 20 - * @userbuf: if set, @buf is in user address space, use copy_to_user(), 21 - * otherwise @buf is in kernel address space, use memcpy(). 22 - * 23 - * Copy a page from "oldmem". For this page, there is no pte mapped 24 - * in the current kernel. We stitch up a pte, similar to kmap_atomic. 25 - */ 26 - ssize_t copy_oldmem_page(unsigned long pfn, char *buf, 27 - size_t csize, unsigned long offset, int userbuf) 14 + ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, 15 + size_t csize, unsigned long offset) 28 16 { 29 17 void __iomem *vaddr; 30 18 ··· 20 32 return 0; 21 33 22 34 vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE); 23 - 24 - if (userbuf) { 25 - if (copy_to_user((void __user *)buf, (vaddr + offset), csize)) { 26 - iounmap(vaddr); 27 - return -EFAULT; 28 - } 29 - } else 30 - memcpy(buf, (vaddr + offset), csize); 31 - 35 + csize = copy_to_iter(vaddr + offset, csize, iter); 32 36 iounmap(vaddr); 37 + 33 38 return csize; 34 39 }
+4 -25
arch/x86/kernel/crash_dump_32.c
··· 10 10 #include <linux/errno.h> 11 11 #include <linux/highmem.h> 12 12 #include <linux/crash_dump.h> 13 - 14 - #include <linux/uaccess.h> 13 + #include <linux/uio.h> 15 14 16 15 static inline bool is_crashed_pfn_valid(unsigned long pfn) 17 16 { ··· 28 29 #endif 29 30 } 30 31 31 - /** 32 - * copy_oldmem_page - copy one page from "oldmem" 33 - * @pfn: page frame number to be copied 34 - * @buf: target memory address for the copy; this can be in kernel address 35 - * space or user address space (see @userbuf) 36 - * @csize: number of bytes to copy 37 - * @offset: offset in bytes into the page (based on pfn) to begin the copy 38 - * @userbuf: if set, @buf is in user address space, use copy_to_user(), 39 - * otherwise @buf is in kernel address space, use memcpy(). 40 - * 41 - * Copy a page from "oldmem". For this page, there might be no pte mapped 42 - * in the current kernel. 43 - */ 44 - ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, 45 - unsigned long offset, int userbuf) 32 + ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, size_t csize, 33 + unsigned long offset) 46 34 { 47 35 void *vaddr; 48 36 ··· 40 54 return -EFAULT; 41 55 42 56 vaddr = kmap_local_pfn(pfn); 43 - 44 - if (!userbuf) { 45 - memcpy(buf, vaddr + offset, csize); 46 - } else { 47 - if (copy_to_user(buf, vaddr + offset, csize)) 48 - csize = -EFAULT; 49 - } 50 - 57 + csize = copy_to_iter(vaddr + offset, csize, iter); 51 58 kunmap_local(vaddr); 52 59 53 60 return csize;
+17 -31
arch/x86/kernel/crash_dump_64.c
··· 8 8 9 9 #include <linux/errno.h> 10 10 #include <linux/crash_dump.h> 11 - #include <linux/uaccess.h> 11 + #include <linux/uio.h> 12 12 #include <linux/io.h> 13 13 #include <linux/cc_platform.h> 14 14 15 - static ssize_t __copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, 16 - unsigned long offset, int userbuf, 15 + static ssize_t __copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, 16 + size_t csize, unsigned long offset, 17 17 bool encrypted) 18 18 { 19 19 void *vaddr; ··· 29 29 if (!vaddr) 30 30 return -ENOMEM; 31 31 32 - if (userbuf) { 33 - if (copy_to_user((void __user *)buf, vaddr + offset, csize)) { 34 - iounmap((void __iomem *)vaddr); 35 - return -EFAULT; 36 - } 37 - } else 38 - memcpy(buf, vaddr + offset, csize); 32 + csize = copy_to_iter(vaddr + offset, csize, iter); 39 33 40 34 iounmap((void __iomem *)vaddr); 41 35 return csize; 42 36 } 43 37 44 - /** 45 - * copy_oldmem_page - copy one page of memory 46 - * @pfn: page frame number to be copied 47 - * @buf: target memory address for the copy; this can be in kernel address 48 - * space or user address space (see @userbuf) 49 - * @csize: number of bytes to copy 50 - * @offset: offset in bytes into the page (based on pfn) to begin the copy 51 - * @userbuf: if set, @buf is in user address space, use copy_to_user(), 52 - * otherwise @buf is in kernel address space, use memcpy(). 53 - * 54 - * Copy a page from the old kernel's memory. For this page, there is no pte 55 - * mapped in the current kernel. We stitch up a pte, similar to kmap_atomic. 56 - */ 57 - ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, 58 - unsigned long offset, int userbuf) 38 + ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, size_t csize, 39 + unsigned long offset) 59 40 { 60 - return __copy_oldmem_page(pfn, buf, csize, offset, userbuf, false); 41 + return __copy_oldmem_page(iter, pfn, csize, offset, false); 61 42 } 62 43 63 - /** 44 + /* 64 45 * copy_oldmem_page_encrypted - same as copy_oldmem_page() above but ioremap the 65 46 * memory with the encryption mask set to accommodate kdump on SME-enabled 66 47 * machines. 67 48 */ 68 - ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize, 69 - unsigned long offset, int userbuf) 49 + ssize_t copy_oldmem_page_encrypted(struct iov_iter *iter, unsigned long pfn, 50 + size_t csize, unsigned long offset) 70 51 { 71 - return __copy_oldmem_page(pfn, buf, csize, offset, userbuf, true); 52 + return __copy_oldmem_page(iter, pfn, csize, offset, true); 72 53 } 73 54 74 55 ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) 75 56 { 76 - return read_from_oldmem(buf, count, ppos, 0, 57 + struct kvec kvec = { .iov_base = buf, .iov_len = count }; 58 + struct iov_iter iter; 59 + 60 + iov_iter_kvec(&iter, READ, &kvec, 1, count); 61 + 62 + return read_from_oldmem(&iter, count, ppos, 77 63 cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)); 78 64 }
-2
arch/x86/lib/csum-wrappers_64.c
··· 32 32 user_access_end(); 33 33 return sum; 34 34 } 35 - EXPORT_SYMBOL(csum_and_copy_from_user); 36 35 37 36 /** 38 37 * csum_and_copy_to_user - Copy and checksum to user space. ··· 56 57 user_access_end(); 57 58 return sum; 58 59 } 59 - EXPORT_SYMBOL(csum_and_copy_to_user); 60 60 61 61 /** 62 62 * csum_partial_copy_nocheck - Copy and checksum.
+2 -2
drivers/rapidio/devices/rio_mport_cdev.c
··· 915 915 goto err_req; 916 916 } 917 917 918 - if (xfer->length + xfer->offset > map->size) { 918 + if (xfer->length + xfer->offset > req->map->size) { 919 919 ret = -EINVAL; 920 920 goto err_req; 921 921 } ··· 927 927 } 928 928 929 929 sg_set_buf(req->sgt.sgl, 930 - map->virt_addr + (baddr - map->phys_addr) + 930 + req->map->virt_addr + (baddr - req->map->phys_addr) + 931 931 xfer->offset, xfer->length); 932 932 } 933 933
+2 -1
drivers/tty/tty_buffer.c
··· 175 175 */ 176 176 if (atomic_read(&port->buf.mem_used) > port->buf.mem_limit) 177 177 return NULL; 178 - p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); 178 + p = kmalloc(sizeof(struct tty_buffer) + 2 * size, 179 + GFP_ATOMIC | __GFP_NOWARN); 179 180 if (p == NULL) 180 181 return NULL; 181 182
+13 -1
fs/fat/fat.h
··· 126 126 struct hlist_node i_fat_hash; /* hash by i_location */ 127 127 struct hlist_node i_dir_hash; /* hash by i_logstart */ 128 128 struct rw_semaphore truncate_lock; /* protect bmap against truncate */ 129 + struct timespec64 i_crtime; /* File creation (birth) time */ 129 130 struct inode vfs_inode; 130 131 }; 131 132 ··· 434 433 __fat_fs_error(sb, 1, fmt , ## args) 435 434 #define fat_fs_error_ratelimit(sb, fmt, args...) \ 436 435 __fat_fs_error(sb, __ratelimit(&MSDOS_SB(sb)->ratelimit), fmt , ## args) 436 + 437 + #define FAT_PRINTK_PREFIX "%sFAT-fs (%s): " 438 + #define fat_msg(sb, level, fmt, args...) \ 439 + do { \ 440 + printk_index_subsys_emit(FAT_PRINTK_PREFIX, level, fmt, ##args);\ 441 + _fat_msg(sb, level, fmt, ##args); \ 442 + } while (0) 437 443 __printf(3, 4) __cold 438 - void fat_msg(struct super_block *sb, const char *level, const char *fmt, ...); 444 + void _fat_msg(struct super_block *sb, const char *level, const char *fmt, ...); 439 445 #define fat_msg_ratelimit(sb, level, fmt, args...) \ 440 446 do { \ 441 447 if (__ratelimit(&MSDOS_SB(sb)->ratelimit)) \ ··· 454 446 __le16 __time, __le16 __date, u8 time_cs); 455 447 extern void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts, 456 448 __le16 *time, __le16 *date, u8 *time_cs); 449 + extern struct timespec64 fat_truncate_atime(const struct msdos_sb_info *sbi, 450 + const struct timespec64 *ts); 451 + extern struct timespec64 fat_truncate_mtime(const struct msdos_sb_info *sbi, 452 + const struct timespec64 *ts); 457 453 extern int fat_truncate_time(struct inode *inode, struct timespec64 *now, 458 454 int flags); 459 455 extern int fat_update_time(struct inode *inode, struct timespec64 *now,
+4 -3
fs/fat/fatent.c
··· 94 94 err_brelse: 95 95 brelse(bhs[0]); 96 96 err: 97 - fat_msg(sb, KERN_ERR, "FAT read failed (blocknr %llu)", (llu)blocknr); 97 + fat_msg_ratelimit(sb, KERN_ERR, "FAT read failed (blocknr %llu)", 98 + (llu)blocknr); 98 99 return -EIO; 99 100 } 100 101 ··· 108 107 fatent->fat_inode = MSDOS_SB(sb)->fat_inode; 109 108 fatent->bhs[0] = sb_bread(sb, blocknr); 110 109 if (!fatent->bhs[0]) { 111 - fat_msg(sb, KERN_ERR, "FAT read failed (blocknr %llu)", 112 - (llu)blocknr); 110 + fat_msg_ratelimit(sb, KERN_ERR, "FAT read failed (blocknr %llu)", 111 + (llu)blocknr); 113 112 return -EIO; 114 113 } 115 114 fatent->nr_bhs = 1;
+12 -4
fs/fat/file.c
··· 398 398 struct kstat *stat, u32 request_mask, unsigned int flags) 399 399 { 400 400 struct inode *inode = d_inode(path->dentry); 401 - generic_fillattr(mnt_userns, inode, stat); 402 - stat->blksize = MSDOS_SB(inode->i_sb)->cluster_size; 401 + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); 403 402 404 - if (MSDOS_SB(inode->i_sb)->options.nfs == FAT_NFS_NOSTALE_RO) { 403 + generic_fillattr(mnt_userns, inode, stat); 404 + stat->blksize = sbi->cluster_size; 405 + 406 + if (sbi->options.nfs == FAT_NFS_NOSTALE_RO) { 405 407 /* Use i_pos for ino. This is used as fileid of nfs. */ 406 - stat->ino = fat_i_pos_read(MSDOS_SB(inode->i_sb), inode); 408 + stat->ino = fat_i_pos_read(sbi, inode); 407 409 } 410 + 411 + if (sbi->options.isvfat && request_mask & STATX_BTIME) { 412 + stat->result_mask |= STATX_BTIME; 413 + stat->btime = MSDOS_I(inode)->i_crtime; 414 + } 415 + 408 416 return 0; 409 417 } 410 418 EXPORT_SYMBOL_GPL(fat_getattr);
+10 -9
fs/fat/inode.c
··· 567 567 & ~((loff_t)sbi->cluster_size - 1)) >> 9; 568 568 569 569 fat_time_fat2unix(sbi, &inode->i_mtime, de->time, de->date, 0); 570 + inode->i_ctime = inode->i_mtime; 570 571 if (sbi->options.isvfat) { 571 - fat_time_fat2unix(sbi, &inode->i_ctime, de->ctime, 572 - de->cdate, de->ctime_cs); 573 572 fat_time_fat2unix(sbi, &inode->i_atime, 0, de->adate, 0); 573 + fat_time_fat2unix(sbi, &MSDOS_I(inode)->i_crtime, de->ctime, 574 + de->cdate, de->ctime_cs); 574 575 } else 575 - fat_truncate_time(inode, &inode->i_mtime, S_ATIME|S_CTIME); 576 + inode->i_atime = fat_truncate_atime(sbi, &inode->i_mtime); 576 577 577 578 return 0; 578 579 } ··· 758 757 ei->i_logstart = 0; 759 758 ei->i_attrs = 0; 760 759 ei->i_pos = 0; 760 + ei->i_crtime.tv_sec = 0; 761 + ei->i_crtime.tv_nsec = 0; 761 762 762 763 return &ei->vfs_inode; 763 764 } ··· 891 888 &raw_entry->date, NULL); 892 889 if (sbi->options.isvfat) { 893 890 __le16 atime; 894 - fat_time_unix2fat(sbi, &inode->i_ctime, &raw_entry->ctime, 895 - &raw_entry->cdate, &raw_entry->ctime_cs); 896 891 fat_time_unix2fat(sbi, &inode->i_atime, &atime, 897 892 &raw_entry->adate, NULL); 893 + fat_time_unix2fat(sbi, &MSDOS_I(inode)->i_crtime, &raw_entry->ctime, 894 + &raw_entry->cdate, &raw_entry->ctime_cs); 898 895 } 899 896 spin_unlock(&sbi->inode_hash_lock); 900 897 mark_buffer_dirty(bh); ··· 1888 1885 fat_msg(sb, KERN_INFO, "Can't find a valid FAT filesystem"); 1889 1886 1890 1887 out_fail: 1891 - if (fsinfo_inode) 1892 - iput(fsinfo_inode); 1893 - if (fat_inode) 1894 - iput(fat_inode); 1888 + iput(fsinfo_inode); 1889 + iput(fat_inode); 1895 1890 unload_nls(sbi->nls_io); 1896 1891 unload_nls(sbi->nls_disk); 1897 1892 fat_reset_iocharset(&sbi->options);
+43 -35
fs/fat/misc.c
··· 42 42 EXPORT_SYMBOL_GPL(__fat_fs_error); 43 43 44 44 /** 45 - * fat_msg() - print preformated FAT specific messages. Every thing what is 46 - * not fat_fs_error() should be fat_msg(). 45 + * _fat_msg() - Print a preformatted FAT message based on a superblock. 46 + * @sb: A pointer to a &struct super_block 47 + * @level: A Kernel printk level constant 48 + * @fmt: The printf-style format string to print. 49 + * 50 + * Everything that is not fat_fs_error() should be fat_msg(). 51 + * 52 + * fat_msg() wraps _fat_msg() for printk indexing. 47 53 */ 48 - void fat_msg(struct super_block *sb, const char *level, const char *fmt, ...) 54 + void _fat_msg(struct super_block *sb, const char *level, const char *fmt, ...) 49 55 { 50 56 struct va_format vaf; 51 57 va_list args; ··· 59 53 va_start(args, fmt); 60 54 vaf.fmt = fmt; 61 55 vaf.va = &args; 62 - printk("%sFAT-fs (%s): %pV\n", level, sb->s_id, &vaf); 56 + _printk(FAT_PRINTK_PREFIX "%pV\n", level, sb->s_id, &vaf); 63 57 va_end(args); 64 58 } 65 59 ··· 193 187 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 194 188 }; 195 189 196 - static inline int fat_tz_offset(struct msdos_sb_info *sbi) 190 + static inline int fat_tz_offset(const struct msdos_sb_info *sbi) 197 191 { 198 192 return (sbi->options.tz_set ? 199 193 -sbi->options.time_offset : ··· 281 275 return (struct timespec64){ ts.tv_sec & ~1ULL, 0 }; 282 276 } 283 277 284 - static inline struct timespec64 fat_timespec64_trunc_10ms(struct timespec64 ts) 278 + /* 279 + * truncate atime to 24 hour granularity (00:00:00 in local timezone) 280 + */ 281 + struct timespec64 fat_truncate_atime(const struct msdos_sb_info *sbi, 282 + const struct timespec64 *ts) 285 283 { 286 - if (ts.tv_nsec) 287 - ts.tv_nsec -= ts.tv_nsec % 10000000UL; 288 - return ts; 284 + /* to localtime */ 285 + time64_t seconds = ts->tv_sec - fat_tz_offset(sbi); 286 + s32 remainder; 287 + 288 + div_s64_rem(seconds, SECS_PER_DAY, &remainder); 289 + /* to day boundary, and back to unix time */ 290 + seconds = seconds + fat_tz_offset(sbi) - remainder; 291 + 292 + return (struct timespec64){ seconds, 0 }; 293 + } 294 + 295 + /* 296 + * truncate mtime to 2 second granularity 297 + */ 298 + struct timespec64 fat_truncate_mtime(const struct msdos_sb_info *sbi, 299 + const struct timespec64 *ts) 300 + { 301 + return fat_timespec64_trunc_2secs(*ts); 289 302 } 290 303 291 304 /* 292 305 * truncate the various times with appropriate granularity: 293 - * root inode: 294 - * all times always 0 295 - * all other inodes: 296 - * mtime - 2 seconds 297 - * ctime 298 - * msdos - 2 seconds 299 - * vfat - 10 milliseconds 300 - * atime - 24 hours (00:00:00 in local timezone) 306 + * all times in root node are always 0 301 307 */ 302 308 int fat_truncate_time(struct inode *inode, struct timespec64 *now, int flags) 303 309 { ··· 324 306 ts = current_time(inode); 325 307 } 326 308 327 - if (flags & S_ATIME) { 328 - /* to localtime */ 329 - time64_t seconds = now->tv_sec - fat_tz_offset(sbi); 330 - s32 remainder; 331 - 332 - div_s64_rem(seconds, SECS_PER_DAY, &remainder); 333 - /* to day boundary, and back to unix time */ 334 - seconds = seconds + fat_tz_offset(sbi) - remainder; 335 - 336 - inode->i_atime = (struct timespec64){ seconds, 0 }; 337 - } 338 - if (flags & S_CTIME) { 339 - if (sbi->options.isvfat) 340 - inode->i_ctime = fat_timespec64_trunc_10ms(*now); 341 - else 342 - inode->i_ctime = fat_timespec64_trunc_2secs(*now); 343 - } 309 + if (flags & S_ATIME) 310 + inode->i_atime = fat_truncate_atime(sbi, now); 311 + /* 312 + * ctime and mtime share the same on-disk field, and should be 313 + * identical in memory. all mtime updates will be applied to ctime, 314 + * but ctime updates are ignored. 315 + */ 344 316 if (flags & S_MTIME) 345 - inode->i_mtime = fat_timespec64_trunc_2secs(*now); 317 + inode->i_mtime = inode->i_ctime = fat_truncate_mtime(sbi, now); 346 318 347 319 return 0; 348 320 }
-4
fs/fat/namei_vfat.c
··· 780 780 goto out; 781 781 } 782 782 inode_inc_iversion(inode); 783 - fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME); 784 - /* timestamp is already written, so mark_inode_dirty() is unneeded. */ 785 783 786 784 d_instantiate(dentry, inode); 787 785 out: ··· 876 878 } 877 879 inode_inc_iversion(inode); 878 880 set_nlink(inode, 2); 879 - fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME); 880 - /* timestamp is already written, so mark_inode_dirty() is unneeded. */ 881 881 882 882 d_instantiate(dentry, inode); 883 883
+4 -4
fs/namei.c
··· 1032 1032 .procname = "protected_symlinks", 1033 1033 .data = &sysctl_protected_symlinks, 1034 1034 .maxlen = sizeof(int), 1035 - .mode = 0600, 1035 + .mode = 0644, 1036 1036 .proc_handler = proc_dointvec_minmax, 1037 1037 .extra1 = SYSCTL_ZERO, 1038 1038 .extra2 = SYSCTL_ONE, ··· 1041 1041 .procname = "protected_hardlinks", 1042 1042 .data = &sysctl_protected_hardlinks, 1043 1043 .maxlen = sizeof(int), 1044 - .mode = 0600, 1044 + .mode = 0644, 1045 1045 .proc_handler = proc_dointvec_minmax, 1046 1046 .extra1 = SYSCTL_ZERO, 1047 1047 .extra2 = SYSCTL_ONE, ··· 1050 1050 .procname = "protected_fifos", 1051 1051 .data = &sysctl_protected_fifos, 1052 1052 .maxlen = sizeof(int), 1053 - .mode = 0600, 1053 + .mode = 0644, 1054 1054 .proc_handler = proc_dointvec_minmax, 1055 1055 .extra1 = SYSCTL_ZERO, 1056 1056 .extra2 = SYSCTL_TWO, ··· 1059 1059 .procname = "protected_regular", 1060 1060 .data = &sysctl_protected_regular, 1061 1061 .maxlen = sizeof(int), 1062 - .mode = 0600, 1062 + .mode = 0644, 1063 1063 .proc_handler = proc_dointvec_minmax, 1064 1064 .extra1 = SYSCTL_ZERO, 1065 1065 .extra2 = SYSCTL_TWO,
+2 -2
fs/ntfs/file.c
··· 1772 1772 last_vcn = -1; 1773 1773 do { 1774 1774 VCN vcn; 1775 - pgoff_t idx, start_idx; 1775 + pgoff_t start_idx; 1776 1776 unsigned ofs, do_pages, u; 1777 1777 size_t copied; 1778 1778 1779 - start_idx = idx = pos >> PAGE_SHIFT; 1779 + start_idx = pos >> PAGE_SHIFT; 1780 1780 ofs = pos & ~PAGE_MASK; 1781 1781 bytes = PAGE_SIZE - ofs; 1782 1782 do_pages = 1;
+7 -3
fs/ntfs3/super.c
··· 668 668 669 669 static u32 true_sectors_per_clst(const struct NTFS_BOOT *boot) 670 670 { 671 - return boot->sectors_per_clusters <= 0x80 672 - ? boot->sectors_per_clusters 673 - : (1u << (0 - boot->sectors_per_clusters)); 671 + if (boot->sectors_per_clusters <= 0x80) 672 + return boot->sectors_per_clusters; 673 + if (boot->sectors_per_clusters >= 0xf4) /* limit shift to 2MB max */ 674 + return 1U << (0 - boot->sectors_per_clusters); 675 + return -EINVAL; 674 676 } 675 677 676 678 /* ··· 715 713 716 714 /* cluster size: 512, 1K, 2K, 4K, ... 2M */ 717 715 sct_per_clst = true_sectors_per_clst(boot); 716 + if ((int)sct_per_clst < 0) 717 + goto out; 718 718 if (!is_power_of_2(sct_per_clst)) 719 719 goto out; 720 720
+6 -6
fs/ocfs2/dlm/dlmdebug.c
··· 541 541 struct debug_lockres *dl = m->private; 542 542 struct dlm_ctxt *dlm = dl->dl_ctxt; 543 543 struct dlm_lock_resource *oldres = dl->dl_res; 544 - struct dlm_lock_resource *res = NULL; 544 + struct dlm_lock_resource *res = NULL, *iter; 545 545 struct list_head *track_list; 546 546 547 547 spin_lock(&dlm->track_lock); ··· 556 556 } 557 557 } 558 558 559 - list_for_each_entry(res, track_list, tracking) { 560 - if (&res->tracking == &dlm->tracking_list) 561 - res = NULL; 562 - else 563 - dlm_lockres_get(res); 559 + list_for_each_entry(iter, track_list, tracking) { 560 + if (&iter->tracking != &dlm->tracking_list) { 561 + dlm_lockres_get(iter); 562 + res = iter; 563 + } 564 564 break; 565 565 } 566 566 spin_unlock(&dlm->track_lock);
+10 -11
fs/ocfs2/dlm/dlmunlock.c
··· 392 392 struct dlm_ctxt *dlm = data; 393 393 struct dlm_unlock_lock *unlock = (struct dlm_unlock_lock *)msg->buf; 394 394 struct dlm_lock_resource *res = NULL; 395 - struct dlm_lock *lock = NULL; 395 + struct dlm_lock *lock = NULL, *iter; 396 396 enum dlm_status status = DLM_NORMAL; 397 - int found = 0, i; 397 + int i; 398 398 struct dlm_lockstatus *lksb = NULL; 399 399 int ignore; 400 400 u32 flags; ··· 437 437 } 438 438 439 439 queue=&res->granted; 440 - found = 0; 441 440 spin_lock(&res->spinlock); 442 441 if (res->state & DLM_LOCK_RES_RECOVERING) { 443 442 spin_unlock(&res->spinlock); ··· 460 461 } 461 462 462 463 for (i=0; i<3; i++) { 463 - list_for_each_entry(lock, queue, list) { 464 - if (lock->ml.cookie == unlock->cookie && 465 - lock->ml.node == unlock->node_idx) { 466 - dlm_lock_get(lock); 467 - found = 1; 464 + list_for_each_entry(iter, queue, list) { 465 + if (iter->ml.cookie == unlock->cookie && 466 + iter->ml.node == unlock->node_idx) { 467 + dlm_lock_get(iter); 468 + lock = iter; 468 469 break; 469 470 } 470 471 } 471 - if (found) 472 + if (lock) 472 473 break; 473 474 /* scan granted -> converting -> blocked queues */ 474 475 queue++; 475 476 } 476 477 spin_unlock(&res->spinlock); 477 - if (!found) { 478 + if (!lock) { 478 479 status = DLM_IVLOCKID; 479 480 goto not_found; 480 481 } ··· 504 505 dlm_kick_thread(dlm, res); 505 506 506 507 not_found: 507 - if (!found) 508 + if (!lock) 508 509 mlog(ML_ERROR, "failed to find lock to unlock! " 509 510 "cookie=%u:%llu\n", 510 511 dlm_get_lock_cookie_node(be64_to_cpu(unlock->cookie)),
+15 -2
fs/ocfs2/dlmfs/userdlm.c
··· 433 433 } 434 434 435 435 spin_lock(&lockres->l_lock); 436 + if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) { 437 + spin_unlock(&lockres->l_lock); 438 + status = -EAGAIN; 439 + goto bail; 440 + } 436 441 437 442 /* We only compare against the currently granted level 438 443 * here. If the lock is blocked waiting on a downconvert, ··· 600 595 spin_lock(&lockres->l_lock); 601 596 if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) { 602 597 spin_unlock(&lockres->l_lock); 603 - return 0; 598 + goto bail; 604 599 } 605 600 606 601 lockres->l_flags |= USER_LOCK_IN_TEARDOWN; ··· 614 609 } 615 610 616 611 if (lockres->l_ro_holders || lockres->l_ex_holders) { 612 + lockres->l_flags &= ~USER_LOCK_IN_TEARDOWN; 617 613 spin_unlock(&lockres->l_lock); 618 614 goto bail; 619 615 } 620 616 621 617 status = 0; 622 618 if (!(lockres->l_flags & USER_LOCK_ATTACHED)) { 619 + /* 620 + * lock is never requested, leave USER_LOCK_IN_TEARDOWN set 621 + * to avoid new lock request coming in. 622 + */ 623 623 spin_unlock(&lockres->l_lock); 624 624 goto bail; 625 625 } 626 626 627 - lockres->l_flags &= ~USER_LOCK_ATTACHED; 628 627 lockres->l_flags |= USER_LOCK_BUSY; 629 628 spin_unlock(&lockres->l_lock); 630 629 631 630 status = ocfs2_dlm_unlock(conn, &lockres->l_lksb, DLM_LKF_VALBLK); 632 631 if (status) { 632 + spin_lock(&lockres->l_lock); 633 + lockres->l_flags &= ~USER_LOCK_IN_TEARDOWN; 634 + lockres->l_flags &= ~USER_LOCK_BUSY; 635 + spin_unlock(&lockres->l_lock); 633 636 user_log_dlm_error("ocfs2_dlm_unlock", status, lockres); 634 637 goto bail; 635 638 }
+2 -2
fs/ocfs2/inode.c
··· 125 125 struct inode *inode = NULL; 126 126 struct super_block *sb = osb->sb; 127 127 struct ocfs2_find_inode_args args; 128 + journal_t *journal = osb->journal->j_journal; 128 129 129 130 trace_ocfs2_iget_begin((unsigned long long)blkno, flags, 130 131 sysfile_type); ··· 172 171 * part of the transaction - the inode could have been reclaimed and 173 172 * now it is reread from disk. 174 173 */ 175 - if (osb->journal) { 174 + if (journal) { 176 175 transaction_t *transaction; 177 176 tid_t tid; 178 177 struct ocfs2_inode_info *oi = OCFS2_I(inode); 179 - journal_t *journal = osb->journal->j_journal; 180 178 181 179 read_lock(&journal->j_state_lock); 182 180 if (journal->j_running_transaction)
+23 -10
fs/ocfs2/journal.c
··· 810 810 write_unlock(&journal->j_state_lock); 811 811 } 812 812 813 - int ocfs2_journal_init(struct ocfs2_super *osb, int *dirty) 813 + /* 814 + * alloc & initialize skeleton for journal structure. 815 + * ocfs2_journal_init() will make fs have journal ability. 816 + */ 817 + int ocfs2_journal_alloc(struct ocfs2_super *osb) 814 818 { 815 - int status = -1; 816 - struct inode *inode = NULL; /* the journal inode */ 817 - journal_t *j_journal = NULL; 818 - struct ocfs2_journal *journal = NULL; 819 - struct ocfs2_dinode *di = NULL; 820 - struct buffer_head *bh = NULL; 821 - int inode_lock = 0; 819 + int status = 0; 820 + struct ocfs2_journal *journal; 822 821 823 - /* initialize our journal structure */ 824 822 journal = kzalloc(sizeof(struct ocfs2_journal), GFP_KERNEL); 825 823 if (!journal) { 826 824 mlog(ML_ERROR, "unable to alloc journal\n"); 827 825 status = -ENOMEM; 828 - goto done; 826 + goto bail; 829 827 } 830 828 osb->journal = journal; 831 829 journal->j_osb = osb; ··· 837 839 INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery); 838 840 journal->j_state = OCFS2_JOURNAL_FREE; 839 841 842 + bail: 843 + return status; 844 + } 845 + 846 + int ocfs2_journal_init(struct ocfs2_super *osb, int *dirty) 847 + { 848 + int status = -1; 849 + struct inode *inode = NULL; /* the journal inode */ 850 + journal_t *j_journal = NULL; 851 + struct ocfs2_journal *journal = osb->journal; 852 + struct ocfs2_dinode *di = NULL; 853 + struct buffer_head *bh = NULL; 854 + int inode_lock = 0; 855 + 856 + BUG_ON(!journal); 840 857 /* already have the inode for our journal */ 841 858 inode = ocfs2_get_system_file_inode(osb, JOURNAL_SYSTEM_INODE, 842 859 osb->slot_num);
+2
fs/ocfs2/journal.h
··· 154 154 * Journal Control: 155 155 * Initialize, Load, Shutdown, Wipe a journal. 156 156 * 157 + * ocfs2_journal_alloc - Initialize skeleton for journal structure. 157 158 * ocfs2_journal_init - Initialize journal structures in the OSB. 158 159 * ocfs2_journal_load - Load the given journal off disk. Replay it if 159 160 * there's transactions still in there. ··· 168 167 * ocfs2_start_checkpoint - Kick the commit thread to do a checkpoint. 169 168 */ 170 169 void ocfs2_set_journal_params(struct ocfs2_super *osb); 170 + int ocfs2_journal_alloc(struct ocfs2_super *osb); 171 171 int ocfs2_journal_init(struct ocfs2_super *osb, int *dirty); 172 172 void ocfs2_journal_shutdown(struct ocfs2_super *osb); 173 173 int ocfs2_journal_wipe(struct ocfs2_journal *journal,
+5 -5
fs/ocfs2/quota_local.c
··· 921 921 { 922 922 struct mem_dqinfo *info = sb_dqinfo(sb, type); 923 923 struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv; 924 - struct ocfs2_quota_chunk *chunk; 924 + struct ocfs2_quota_chunk *chunk = NULL, *iter; 925 925 struct ocfs2_local_disk_chunk *dchunk; 926 926 int found = 0, len; 927 927 928 - list_for_each_entry(chunk, &oinfo->dqi_chunk, qc_chunk) { 928 + list_for_each_entry(iter, &oinfo->dqi_chunk, qc_chunk) { 929 929 dchunk = (struct ocfs2_local_disk_chunk *) 930 - chunk->qc_headerbh->b_data; 930 + iter->qc_headerbh->b_data; 931 931 if (le32_to_cpu(dchunk->dqc_free) > 0) { 932 - found = 1; 932 + chunk = iter; 933 933 break; 934 934 } 935 935 } 936 - if (!found) 936 + if (!chunk) 937 937 return NULL; 938 938 939 939 if (chunk->qc_num < oinfo->dqi_chunks - 1) {
+1 -3
fs/ocfs2/reservations.c
··· 198 198 resv->r_flags |= flags; 199 199 } 200 200 201 - int ocfs2_resmap_init(struct ocfs2_super *osb, 201 + void ocfs2_resmap_init(struct ocfs2_super *osb, 202 202 struct ocfs2_reservation_map *resmap) 203 203 { 204 204 memset(resmap, 0, sizeof(*resmap)); ··· 207 207 resmap->m_reservations = RB_ROOT; 208 208 /* m_bitmap_len is initialized to zero by the above memset. */ 209 209 INIT_LIST_HEAD(&resmap->m_lru); 210 - 211 - return 0; 212 210 } 213 211 214 212 static void ocfs2_resv_mark_lru(struct ocfs2_reservation_map *resmap,
+2 -7
fs/ocfs2/reservations.h
··· 73 73 74 74 /** 75 75 * ocfs2_resmap_init() - Initialize fields of a reservations bitmap 76 + * @osb: struct ocfs2_super to be saved in resmap 76 77 * @resmap: struct ocfs2_reservation_map to initialize 77 - * @obj: unused for now 78 - * @ops: unused for now 79 - * @max_bitmap_bytes: Maximum size of the bitmap (typically blocksize) 80 - * 81 - * Only possible return value other than '0' is -ENOMEM for failure to 82 - * allocation mirror bitmap. 83 78 */ 84 - int ocfs2_resmap_init(struct ocfs2_super *osb, 79 + void ocfs2_resmap_init(struct ocfs2_super *osb, 85 80 struct ocfs2_reservation_map *resmap); 86 81 87 82 /**
+111 -69
fs/ocfs2/super.c
··· 989 989 990 990 if (!ocfs2_parse_options(sb, data, &parsed_options, 0)) { 991 991 status = -EINVAL; 992 - goto read_super_error; 992 + goto out; 993 993 } 994 994 995 995 /* probe for superblock */ 996 996 status = ocfs2_sb_probe(sb, &bh, &sector_size, &stats); 997 997 if (status < 0) { 998 998 mlog(ML_ERROR, "superblock probe failed!\n"); 999 - goto read_super_error; 999 + goto out; 1000 1000 } 1001 1001 1002 1002 status = ocfs2_initialize_super(sb, bh, sector_size, &stats); 1003 - osb = OCFS2_SB(sb); 1004 - if (status < 0) { 1005 - mlog_errno(status); 1006 - goto read_super_error; 1007 - } 1008 1003 brelse(bh); 1009 1004 bh = NULL; 1005 + if (status < 0) 1006 + goto out; 1007 + 1008 + osb = OCFS2_SB(sb); 1010 1009 1011 1010 if (!ocfs2_check_set_options(sb, &parsed_options)) { 1012 1011 status = -EINVAL; 1013 - goto read_super_error; 1012 + goto out_super; 1014 1013 } 1015 1014 osb->s_mount_opt = parsed_options.mount_opt; 1016 1015 osb->s_atime_quantum = parsed_options.atime_quantum; ··· 1026 1027 1027 1028 status = ocfs2_verify_userspace_stack(osb, &parsed_options); 1028 1029 if (status) 1029 - goto read_super_error; 1030 + goto out_super; 1030 1031 1031 1032 sb->s_magic = OCFS2_SUPER_MAGIC; 1032 1033 ··· 1040 1041 status = -EACCES; 1041 1042 mlog(ML_ERROR, "Readonly device detected but readonly " 1042 1043 "mount was not specified.\n"); 1043 - goto read_super_error; 1044 + goto out_super; 1044 1045 } 1045 1046 1046 1047 /* You should not be able to start a local heartbeat ··· 1049 1050 status = -EROFS; 1050 1051 mlog(ML_ERROR, "Local heartbeat specified on readonly " 1051 1052 "device.\n"); 1052 - goto read_super_error; 1053 + goto out_super; 1053 1054 } 1054 1055 1055 1056 status = ocfs2_check_journals_nolocks(osb); ··· 1058 1059 mlog(ML_ERROR, "Recovery required on readonly " 1059 1060 "file system, but write access is " 1060 1061 "unavailable.\n"); 1061 - else 1062 - mlog_errno(status); 1063 - goto read_super_error; 1062 + goto out_super; 1064 1063 } 1065 1064 1066 1065 ocfs2_set_ro_flag(osb, 1); ··· 1074 1077 } 1075 1078 1076 1079 status = ocfs2_verify_heartbeat(osb); 1077 - if (status < 0) { 1078 - mlog_errno(status); 1079 - goto read_super_error; 1080 - } 1080 + if (status < 0) 1081 + goto out_super; 1081 1082 1082 1083 osb->osb_debug_root = debugfs_create_dir(osb->uuid_str, 1083 1084 ocfs2_debugfs_root); ··· 1089 1094 1090 1095 status = ocfs2_mount_volume(sb); 1091 1096 if (status < 0) 1092 - goto read_super_error; 1097 + goto out_debugfs; 1093 1098 1094 1099 if (osb->root_inode) 1095 1100 inode = igrab(osb->root_inode); 1096 1101 1097 1102 if (!inode) { 1098 1103 status = -EIO; 1099 - mlog_errno(status); 1100 - goto read_super_error; 1104 + goto out_dismount; 1101 1105 } 1102 1106 1103 1107 osb->osb_dev_kset = kset_create_and_add(sb->s_id, NULL, ··· 1104 1110 if (!osb->osb_dev_kset) { 1105 1111 status = -ENOMEM; 1106 1112 mlog(ML_ERROR, "Unable to create device kset %s.\n", sb->s_id); 1107 - goto read_super_error; 1113 + goto out_dismount; 1108 1114 } 1109 1115 1110 1116 /* Create filecheck sysfs related directories/files at ··· 1113 1119 status = -ENOMEM; 1114 1120 mlog(ML_ERROR, "Unable to create filecheck sysfs directory at " 1115 1121 "/sys/fs/ocfs2/%s/filecheck.\n", sb->s_id); 1116 - goto read_super_error; 1122 + goto out_dismount; 1117 1123 } 1118 1124 1119 1125 root = d_make_root(inode); 1120 1126 if (!root) { 1121 1127 status = -ENOMEM; 1122 - mlog_errno(status); 1123 - goto read_super_error; 1128 + goto out_dismount; 1124 1129 } 1125 1130 1126 1131 sb->s_root = root; ··· 1171 1178 1172 1179 return status; 1173 1180 1174 - read_super_error: 1175 - brelse(bh); 1181 + out_dismount: 1182 + atomic_set(&osb->vol_state, VOLUME_DISABLED); 1183 + wake_up(&osb->osb_mount_event); 1184 + ocfs2_dismount_volume(sb, 1); 1185 + goto out; 1176 1186 1177 - if (status) 1178 - mlog_errno(status); 1179 - 1180 - if (osb) { 1181 - atomic_set(&osb->vol_state, VOLUME_DISABLED); 1182 - wake_up(&osb->osb_mount_event); 1183 - ocfs2_dismount_volume(sb, 1); 1184 - } 1187 + out_debugfs: 1188 + debugfs_remove_recursive(osb->osb_debug_root); 1189 + out_super: 1190 + ocfs2_release_system_inodes(osb); 1191 + kfree(osb->recovery_map); 1192 + ocfs2_delete_osb(osb); 1193 + kfree(osb); 1194 + out: 1195 + mlog_errno(status); 1185 1196 1186 1197 return status; 1187 1198 } ··· 1800 1803 static int ocfs2_mount_volume(struct super_block *sb) 1801 1804 { 1802 1805 int status = 0; 1803 - int unlock_super = 0; 1804 1806 struct ocfs2_super *osb = OCFS2_SB(sb); 1805 1807 1806 1808 if (ocfs2_is_hard_readonly(osb)) 1807 - goto leave; 1809 + goto out; 1808 1810 1809 1811 mutex_init(&osb->obs_trim_fs_mutex); 1810 1812 ··· 1813 1817 if (status == -EBADR && ocfs2_userspace_stack(osb)) 1814 1818 mlog(ML_ERROR, "couldn't mount because cluster name on" 1815 1819 " disk does not match the running cluster name.\n"); 1816 - goto leave; 1820 + goto out; 1817 1821 } 1818 1822 1819 1823 status = ocfs2_super_lock(osb, 1); 1820 1824 if (status < 0) { 1821 1825 mlog_errno(status); 1822 - goto leave; 1826 + goto out_dlm; 1823 1827 } 1824 - unlock_super = 1; 1825 1828 1826 1829 /* This will load up the node map and add ourselves to it. */ 1827 1830 status = ocfs2_find_slot(osb); 1828 1831 if (status < 0) { 1829 1832 mlog_errno(status); 1830 - goto leave; 1833 + goto out_super_lock; 1831 1834 } 1832 1835 1833 1836 /* load all node-local system inodes */ 1834 1837 status = ocfs2_init_local_system_inodes(osb); 1835 1838 if (status < 0) { 1836 1839 mlog_errno(status); 1837 - goto leave; 1840 + goto out_super_lock; 1838 1841 } 1839 1842 1840 1843 status = ocfs2_check_volume(osb); 1841 1844 if (status < 0) { 1842 1845 mlog_errno(status); 1843 - goto leave; 1846 + goto out_system_inodes; 1844 1847 } 1845 1848 1846 1849 status = ocfs2_truncate_log_init(osb); 1847 - if (status < 0) 1850 + if (status < 0) { 1848 1851 mlog_errno(status); 1852 + goto out_system_inodes; 1853 + } 1849 1854 1850 - leave: 1851 - if (unlock_super) 1852 - ocfs2_super_unlock(osb, 1); 1855 + ocfs2_super_unlock(osb, 1); 1856 + return 0; 1853 1857 1858 + out_system_inodes: 1859 + if (osb->local_alloc_state == OCFS2_LA_ENABLED) 1860 + ocfs2_shutdown_local_alloc(osb); 1861 + ocfs2_release_system_inodes(osb); 1862 + /* before journal shutdown, we should release slot_info */ 1863 + ocfs2_free_slot_info(osb); 1864 + ocfs2_journal_shutdown(osb); 1865 + out_super_lock: 1866 + ocfs2_super_unlock(osb, 1); 1867 + out_dlm: 1868 + ocfs2_dlm_shutdown(osb, 0); 1869 + out: 1854 1870 return status; 1855 1871 } 1856 1872 ··· 2030 2022 if (!osb) { 2031 2023 status = -ENOMEM; 2032 2024 mlog_errno(status); 2033 - goto bail; 2025 + goto out; 2034 2026 } 2035 2027 2036 2028 sb->s_fs_info = osb; ··· 2091 2083 mlog(ML_ERROR, "Invalid number of node slots (%u)\n", 2092 2084 osb->max_slots); 2093 2085 status = -EINVAL; 2094 - goto bail; 2086 + goto out; 2095 2087 } 2096 2088 2097 2089 ocfs2_orphan_scan_init(osb); ··· 2100 2092 if (status) { 2101 2093 mlog(ML_ERROR, "Unable to initialize recovery state\n"); 2102 2094 mlog_errno(status); 2103 - goto bail; 2095 + goto out; 2104 2096 } 2105 2097 2106 2098 init_waitqueue_head(&osb->checkpoint_event); ··· 2118 2110 2119 2111 init_waitqueue_head(&osb->osb_mount_event); 2120 2112 2121 - status = ocfs2_resmap_init(osb, &osb->osb_la_resmap); 2122 - if (status) { 2123 - mlog_errno(status); 2124 - goto bail; 2125 - } 2113 + ocfs2_resmap_init(osb, &osb->osb_la_resmap); 2126 2114 2127 2115 osb->vol_label = kmalloc(OCFS2_MAX_VOL_LABEL_LEN, GFP_KERNEL); 2128 2116 if (!osb->vol_label) { 2129 2117 mlog(ML_ERROR, "unable to alloc vol label\n"); 2130 2118 status = -ENOMEM; 2131 - goto bail; 2119 + goto out_recovery_map; 2132 2120 } 2133 2121 2134 2122 osb->slot_recovery_generations = ··· 2133 2129 if (!osb->slot_recovery_generations) { 2134 2130 status = -ENOMEM; 2135 2131 mlog_errno(status); 2136 - goto bail; 2132 + goto out_vol_label; 2137 2133 } 2138 2134 2139 2135 init_waitqueue_head(&osb->osb_wipe_event); ··· 2143 2139 if (!osb->osb_orphan_wipes) { 2144 2140 status = -ENOMEM; 2145 2141 mlog_errno(status); 2146 - goto bail; 2142 + goto out_slot_recovery_gen; 2147 2143 } 2148 2144 2149 2145 osb->osb_rf_lock_tree = RB_ROOT; ··· 2159 2155 mlog(ML_ERROR, "couldn't mount because of unsupported " 2160 2156 "optional features (%x).\n", i); 2161 2157 status = -EINVAL; 2162 - goto bail; 2158 + goto out_orphan_wipes; 2163 2159 } 2164 2160 if (!sb_rdonly(osb->sb) && (i = OCFS2_HAS_RO_COMPAT_FEATURE(osb->sb, ~OCFS2_FEATURE_RO_COMPAT_SUPP))) { 2165 2161 mlog(ML_ERROR, "couldn't mount RDWR because of " 2166 2162 "unsupported optional features (%x).\n", i); 2167 2163 status = -EINVAL; 2168 - goto bail; 2164 + goto out_orphan_wipes; 2169 2165 } 2170 2166 2171 2167 if (ocfs2_clusterinfo_valid(osb)) { ··· 2186 2182 "cluster stack label (%s) \n", 2187 2183 osb->osb_cluster_stack); 2188 2184 status = -EINVAL; 2189 - goto bail; 2185 + goto out_orphan_wipes; 2190 2186 } 2191 2187 memcpy(osb->osb_cluster_name, 2192 2188 OCFS2_RAW_SB(di)->s_cluster_info.ci_cluster, ··· 2198 2194 } 2199 2195 2200 2196 get_random_bytes(&osb->s_next_generation, sizeof(u32)); 2197 + 2198 + /* 2199 + * FIXME 2200 + * This should be done in ocfs2_journal_init(), but any inode 2201 + * writes back operation will cause the filesystem to crash. 2202 + */ 2203 + status = ocfs2_journal_alloc(osb); 2204 + if (status < 0) 2205 + goto out_orphan_wipes; 2201 2206 2202 2207 INIT_WORK(&osb->dquot_drop_work, ocfs2_drop_dquot_refs); 2203 2208 init_llist_head(&osb->dquot_drop_list); ··· 2221 2208 mlog(ML_ERROR, "Volume has invalid cluster size (%d)\n", 2222 2209 osb->s_clustersize); 2223 2210 status = -EINVAL; 2224 - goto bail; 2211 + goto out_journal; 2225 2212 } 2226 2213 2227 2214 total_blocks = ocfs2_clusters_to_blocks(osb->sb, ··· 2233 2220 mlog(ML_ERROR, "Volume too large " 2234 2221 "to mount safely on this system"); 2235 2222 status = -EFBIG; 2236 - goto bail; 2223 + goto out_journal; 2237 2224 } 2238 2225 2239 2226 if (ocfs2_setup_osb_uuid(osb, di->id2.i_super.s_uuid, 2240 2227 sizeof(di->id2.i_super.s_uuid))) { 2241 2228 mlog(ML_ERROR, "Out of memory trying to setup our uuid.\n"); 2242 2229 status = -ENOMEM; 2243 - goto bail; 2230 + goto out_journal; 2244 2231 } 2245 2232 2246 2233 strlcpy(osb->vol_label, di->id2.i_super.s_label, ··· 2260 2247 if (!osb->osb_dlm_debug) { 2261 2248 status = -ENOMEM; 2262 2249 mlog_errno(status); 2263 - goto bail; 2250 + goto out_uuid_str; 2264 2251 } 2265 2252 2266 2253 atomic_set(&osb->vol_state, VOLUME_INIT); ··· 2269 2256 status = ocfs2_init_global_system_inodes(osb); 2270 2257 if (status < 0) { 2271 2258 mlog_errno(status); 2272 - goto bail; 2259 + goto out_dlm_out; 2273 2260 } 2274 2261 2275 2262 /* ··· 2280 2267 if (!inode) { 2281 2268 status = -EINVAL; 2282 2269 mlog_errno(status); 2283 - goto bail; 2270 + goto out_system_inodes; 2284 2271 } 2285 2272 2286 2273 osb->bitmap_blkno = OCFS2_I(inode)->ip_blkno; ··· 2293 2280 status = ocfs2_init_slot_info(osb); 2294 2281 if (status < 0) { 2295 2282 mlog_errno(status); 2296 - goto bail; 2283 + goto out_system_inodes; 2297 2284 } 2298 2285 2299 2286 osb->ocfs2_wq = alloc_ordered_workqueue("ocfs2_wq", WQ_MEM_RECLAIM); 2300 2287 if (!osb->ocfs2_wq) { 2301 2288 status = -ENOMEM; 2302 2289 mlog_errno(status); 2290 + goto out_slot_info; 2303 2291 } 2304 2292 2305 - bail: 2293 + return status; 2294 + 2295 + out_slot_info: 2296 + ocfs2_free_slot_info(osb); 2297 + out_system_inodes: 2298 + ocfs2_release_system_inodes(osb); 2299 + out_dlm_out: 2300 + ocfs2_put_dlm_debug(osb->osb_dlm_debug); 2301 + out_uuid_str: 2302 + kfree(osb->uuid_str); 2303 + out_journal: 2304 + kfree(osb->journal); 2305 + out_orphan_wipes: 2306 + kfree(osb->osb_orphan_wipes); 2307 + out_slot_recovery_gen: 2308 + kfree(osb->slot_recovery_generations); 2309 + out_vol_label: 2310 + kfree(osb->vol_label); 2311 + out_recovery_map: 2312 + kfree(osb->recovery_map); 2313 + out: 2314 + kfree(osb); 2315 + sb->s_fs_info = NULL; 2306 2316 return status; 2307 2317 } 2308 2318 ··· 2519 2483 2520 2484 kfree(osb->osb_orphan_wipes); 2521 2485 kfree(osb->slot_recovery_generations); 2486 + /* FIXME 2487 + * This belongs in journal shutdown, but because we have to 2488 + * allocate osb->journal at the middle of ocfs2_initialize_super(), 2489 + * we free it here. 2490 + */ 2491 + kfree(osb->journal); 2522 2492 kfree(osb->local_alloc_copy); 2523 2493 kfree(osb->uuid_str); 2524 2494 kfree(osb->vol_label);
+1 -1
fs/pipe.c
··· 653 653 unsigned int head, tail; 654 654 655 655 /* Epoll has some historical nasty semantics, this enables them */ 656 - pipe->poll_usage = 1; 656 + WRITE_ONCE(pipe->poll_usage, true); 657 657 658 658 /* 659 659 * Reading pipe state only -- no need for acquiring the semaphore.
+3
fs/proc/generic.c
··· 448 448 proc_set_user(ent, (*parent)->uid, (*parent)->gid); 449 449 450 450 ent->proc_dops = &proc_misc_dentry_ops; 451 + /* Revalidate everything under /proc/${pid}/net */ 452 + if ((*parent)->proc_dops == &proc_net_dentry_ops) 453 + pde_force_lookup(ent); 451 454 452 455 out: 453 456 return ent;
+9 -5
fs/proc/kcore.c
··· 479 479 * the previous entry, search for a matching entry. 480 480 */ 481 481 if (!m || start < m->addr || start >= m->addr + m->size) { 482 - list_for_each_entry(m, &kclist_head, list) { 483 - if (start >= m->addr && 484 - start < m->addr + m->size) 482 + struct kcore_list *iter; 483 + 484 + m = NULL; 485 + list_for_each_entry(iter, &kclist_head, list) { 486 + if (start >= iter->addr && 487 + start < iter->addr + iter->size) { 488 + m = iter; 485 489 break; 490 + } 486 491 } 487 492 } 488 493 ··· 497 492 page_offline_freeze(); 498 493 } 499 494 500 - if (&m->list == &kclist_head) { 495 + if (!m) { 501 496 if (clear_user(buffer, tsz)) { 502 497 ret = -EFAULT; 503 498 goto out; 504 499 } 505 - m = NULL; /* skip the list anchor */ 506 500 goto skip; 507 501 } 508 502
+3
fs/proc/proc_net.c
··· 376 376 377 377 proc_set_user(netd, uid, gid); 378 378 379 + /* Seed dentry revalidation for /proc/${pid}/net */ 380 + pde_force_lookup(netd); 381 + 379 382 err = -EEXIST; 380 383 net_statd = proc_net_mkdir(net, "stat", netd); 381 384 if (!net_statd)
+56 -74
fs/proc/vmcore.c
··· 26 26 #include <linux/vmalloc.h> 27 27 #include <linux/pagemap.h> 28 28 #include <linux/uaccess.h> 29 + #include <linux/uio.h> 29 30 #include <linux/cc_platform.h> 30 31 #include <asm/io.h> 31 32 #include "internal.h" ··· 129 128 } 130 129 131 130 /* Reads a page from the oldmem device from given offset. */ 132 - ssize_t read_from_oldmem(char *buf, size_t count, 133 - u64 *ppos, int userbuf, 134 - bool encrypted) 131 + ssize_t read_from_oldmem(struct iov_iter *iter, size_t count, 132 + u64 *ppos, bool encrypted) 135 133 { 136 134 unsigned long pfn, offset; 137 135 size_t nr_bytes; ··· 152 152 153 153 /* If pfn is not ram, return zeros for sparse dump files */ 154 154 if (!pfn_is_ram(pfn)) { 155 - tmp = 0; 156 - if (!userbuf) 157 - memset(buf, 0, nr_bytes); 158 - else if (clear_user(buf, nr_bytes)) 159 - tmp = -EFAULT; 155 + tmp = iov_iter_zero(nr_bytes, iter); 160 156 } else { 161 157 if (encrypted) 162 - tmp = copy_oldmem_page_encrypted(pfn, buf, 158 + tmp = copy_oldmem_page_encrypted(iter, pfn, 163 159 nr_bytes, 164 - offset, 165 - userbuf); 160 + offset); 166 161 else 167 - tmp = copy_oldmem_page(pfn, buf, nr_bytes, 168 - offset, userbuf); 162 + tmp = copy_oldmem_page(iter, pfn, nr_bytes, 163 + offset); 169 164 } 170 - if (tmp < 0) { 165 + if (tmp < nr_bytes) { 171 166 srcu_read_unlock(&vmcore_cb_srcu, idx); 172 - return tmp; 167 + return -EFAULT; 173 168 } 174 169 175 170 *ppos += nr_bytes; 176 171 count -= nr_bytes; 177 - buf += nr_bytes; 178 172 read += nr_bytes; 179 173 ++pfn; 180 174 offset = 0; ··· 197 203 */ 198 204 ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos) 199 205 { 200 - return read_from_oldmem(buf, count, ppos, 0, false); 206 + struct kvec kvec = { .iov_base = buf, .iov_len = count }; 207 + struct iov_iter iter; 208 + 209 + iov_iter_kvec(&iter, READ, &kvec, 1, count); 210 + 211 + return read_from_oldmem(&iter, count, ppos, false); 201 212 } 202 213 203 214 /* ··· 210 211 */ 211 212 ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos) 212 213 { 213 - return read_from_oldmem(buf, count, ppos, 0, cc_platform_has(CC_ATTR_MEM_ENCRYPT)); 214 + struct kvec kvec = { .iov_base = buf, .iov_len = count }; 215 + struct iov_iter iter; 216 + 217 + iov_iter_kvec(&iter, READ, &kvec, 1, count); 218 + 219 + return read_from_oldmem(&iter, count, ppos, 220 + cc_platform_has(CC_ATTR_MEM_ENCRYPT)); 214 221 } 215 222 216 223 /* ··· 233 228 /* 234 229 * Architectures which support memory encryption override this. 235 230 */ 236 - ssize_t __weak 237 - copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize, 238 - unsigned long offset, int userbuf) 231 + ssize_t __weak copy_oldmem_page_encrypted(struct iov_iter *iter, 232 + unsigned long pfn, size_t csize, unsigned long offset) 239 233 { 240 - return copy_oldmem_page(pfn, buf, csize, offset, userbuf); 241 - } 242 - 243 - /* 244 - * Copy to either kernel or user space 245 - */ 246 - static int copy_to(void *target, void *src, size_t size, int userbuf) 247 - { 248 - if (userbuf) { 249 - if (copy_to_user((char __user *) target, src, size)) 250 - return -EFAULT; 251 - } else { 252 - memcpy(target, src, size); 253 - } 254 - return 0; 234 + return copy_oldmem_page(iter, pfn, csize, offset); 255 235 } 256 236 257 237 #ifdef CONFIG_PROC_VMCORE_DEVICE_DUMP 258 - static int vmcoredd_copy_dumps(void *dst, u64 start, size_t size, int userbuf) 238 + static int vmcoredd_copy_dumps(struct iov_iter *iter, u64 start, size_t size) 259 239 { 260 240 struct vmcoredd_node *dump; 261 241 u64 offset = 0; ··· 253 263 if (start < offset + dump->size) { 254 264 tsz = min(offset + (u64)dump->size - start, (u64)size); 255 265 buf = dump->buf + start - offset; 256 - if (copy_to(dst, buf, tsz, userbuf)) { 266 + if (copy_to_iter(buf, tsz, iter) < tsz) { 257 267 ret = -EFAULT; 258 268 goto out_unlock; 259 269 } 260 270 261 271 size -= tsz; 262 272 start += tsz; 263 - dst += tsz; 264 273 265 274 /* Leave now if buffer filled already */ 266 275 if (!size) ··· 315 326 /* Read from the ELF header and then the crash dump. On error, negative value is 316 327 * returned otherwise number of bytes read are returned. 317 328 */ 318 - static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos, 319 - int userbuf) 329 + static ssize_t __read_vmcore(struct iov_iter *iter, loff_t *fpos) 320 330 { 321 331 ssize_t acc = 0, tmp; 322 332 size_t tsz; 323 333 u64 start; 324 334 struct vmcore *m = NULL; 325 335 326 - if (buflen == 0 || *fpos >= vmcore_size) 336 + if (!iov_iter_count(iter) || *fpos >= vmcore_size) 327 337 return 0; 328 338 329 - /* trim buflen to not go beyond EOF */ 330 - if (buflen > vmcore_size - *fpos) 331 - buflen = vmcore_size - *fpos; 339 + iov_iter_truncate(iter, vmcore_size - *fpos); 332 340 333 341 /* Read ELF core header */ 334 342 if (*fpos < elfcorebuf_sz) { 335 - tsz = min(elfcorebuf_sz - (size_t)*fpos, buflen); 336 - if (copy_to(buffer, elfcorebuf + *fpos, tsz, userbuf)) 343 + tsz = min(elfcorebuf_sz - (size_t)*fpos, iov_iter_count(iter)); 344 + if (copy_to_iter(elfcorebuf + *fpos, tsz, iter) < tsz) 337 345 return -EFAULT; 338 - buflen -= tsz; 339 346 *fpos += tsz; 340 - buffer += tsz; 341 347 acc += tsz; 342 348 343 349 /* leave now if filled buffer already */ 344 - if (buflen == 0) 350 + if (!iov_iter_count(iter)) 345 351 return acc; 346 352 } 347 353 ··· 357 373 /* Read device dumps */ 358 374 if (*fpos < elfcorebuf_sz + vmcoredd_orig_sz) { 359 375 tsz = min(elfcorebuf_sz + vmcoredd_orig_sz - 360 - (size_t)*fpos, buflen); 376 + (size_t)*fpos, iov_iter_count(iter)); 361 377 start = *fpos - elfcorebuf_sz; 362 - if (vmcoredd_copy_dumps(buffer, start, tsz, userbuf)) 378 + if (vmcoredd_copy_dumps(iter, start, tsz)) 363 379 return -EFAULT; 364 380 365 - buflen -= tsz; 366 381 *fpos += tsz; 367 - buffer += tsz; 368 382 acc += tsz; 369 383 370 384 /* leave now if filled buffer already */ 371 - if (!buflen) 385 + if (!iov_iter_count(iter)) 372 386 return acc; 373 387 } 374 388 #endif /* CONFIG_PROC_VMCORE_DEVICE_DUMP */ 375 389 376 390 /* Read remaining elf notes */ 377 - tsz = min(elfcorebuf_sz + elfnotes_sz - (size_t)*fpos, buflen); 391 + tsz = min(elfcorebuf_sz + elfnotes_sz - (size_t)*fpos, 392 + iov_iter_count(iter)); 378 393 kaddr = elfnotes_buf + *fpos - elfcorebuf_sz - vmcoredd_orig_sz; 379 - if (copy_to(buffer, kaddr, tsz, userbuf)) 394 + if (copy_to_iter(kaddr, tsz, iter) < tsz) 380 395 return -EFAULT; 381 396 382 - buflen -= tsz; 383 397 *fpos += tsz; 384 - buffer += tsz; 385 398 acc += tsz; 386 399 387 400 /* leave now if filled buffer already */ 388 - if (buflen == 0) 401 + if (!iov_iter_count(iter)) 389 402 return acc; 390 403 } 391 404 ··· 390 409 if (*fpos < m->offset + m->size) { 391 410 tsz = (size_t)min_t(unsigned long long, 392 411 m->offset + m->size - *fpos, 393 - buflen); 412 + iov_iter_count(iter)); 394 413 start = m->paddr + *fpos - m->offset; 395 - tmp = read_from_oldmem(buffer, tsz, &start, 396 - userbuf, cc_platform_has(CC_ATTR_MEM_ENCRYPT)); 414 + tmp = read_from_oldmem(iter, tsz, &start, 415 + cc_platform_has(CC_ATTR_MEM_ENCRYPT)); 397 416 if (tmp < 0) 398 417 return tmp; 399 - buflen -= tsz; 400 418 *fpos += tsz; 401 - buffer += tsz; 402 419 acc += tsz; 403 420 404 421 /* leave now if filled buffer already */ 405 - if (buflen == 0) 422 + if (!iov_iter_count(iter)) 406 423 return acc; 407 424 } 408 425 } ··· 408 429 return acc; 409 430 } 410 431 411 - static ssize_t read_vmcore(struct file *file, char __user *buffer, 412 - size_t buflen, loff_t *fpos) 432 + static ssize_t read_vmcore(struct kiocb *iocb, struct iov_iter *iter) 413 433 { 414 - return __read_vmcore((__force char *) buffer, buflen, fpos, 1); 434 + return __read_vmcore(iter, &iocb->ki_pos); 415 435 } 416 436 417 437 /* 418 438 * The vmcore fault handler uses the page cache and fills data using the 419 - * standard __vmcore_read() function. 439 + * standard __read_vmcore() function. 420 440 * 421 441 * On s390 the fault handler is used for memory regions that can't be mapped 422 442 * directly with remap_pfn_range(). ··· 425 447 #ifdef CONFIG_S390 426 448 struct address_space *mapping = vmf->vma->vm_file->f_mapping; 427 449 pgoff_t index = vmf->pgoff; 450 + struct iov_iter iter; 451 + struct kvec kvec; 428 452 struct page *page; 429 453 loff_t offset; 430 - char *buf; 431 454 int rc; 432 455 433 456 page = find_or_create_page(mapping, index, GFP_KERNEL); ··· 436 457 return VM_FAULT_OOM; 437 458 if (!PageUptodate(page)) { 438 459 offset = (loff_t) index << PAGE_SHIFT; 439 - buf = __va((page_to_pfn(page) << PAGE_SHIFT)); 440 - rc = __read_vmcore(buf, PAGE_SIZE, &offset, 0); 460 + kvec.iov_base = page_address(page); 461 + kvec.iov_len = PAGE_SIZE; 462 + iov_iter_kvec(&iter, READ, &kvec, 1, PAGE_SIZE); 463 + 464 + rc = __read_vmcore(&iter, &offset); 441 465 if (rc < 0) { 442 466 unlock_page(page); 443 467 put_page(page); ··· 690 708 691 709 static const struct proc_ops vmcore_proc_ops = { 692 710 .proc_open = open_vmcore, 693 - .proc_read = read_vmcore, 711 + .proc_read_iter = read_vmcore, 694 712 .proc_lseek = default_llseek, 695 713 .proc_mmap = mmap_vmcore, 696 714 };
+3 -1
fs/sysv/super.c
··· 312 312 sbi->s_firstinodezone = 2; 313 313 314 314 flavour_setup[sbi->s_type](sbi, &sb->s_max_links); 315 - 315 + if (sbi->s_firstdatazone < sbi->s_firstinodezone) 316 + return 0; 317 + 316 318 sbi->s_ndatazones = sbi->s_nzones - sbi->s_firstdatazone; 317 319 sbi->s_inodes_per_block = bsize >> 6; 318 320 sbi->s_inodes_per_block_1 = (bsize >> 6)-1;
+8 -11
include/linux/crash_dump.h
··· 24 24 unsigned long from, unsigned long pfn, 25 25 unsigned long size, pgprot_t prot); 26 26 27 - extern ssize_t copy_oldmem_page(unsigned long, char *, size_t, 28 - unsigned long, int); 29 - extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf, 30 - size_t csize, unsigned long offset, 31 - int userbuf); 27 + ssize_t copy_oldmem_page(struct iov_iter *i, unsigned long pfn, size_t csize, 28 + unsigned long offset); 29 + ssize_t copy_oldmem_page_encrypted(struct iov_iter *iter, unsigned long pfn, 30 + size_t csize, unsigned long offset); 32 31 33 32 void vmcore_cleanup(void); 34 33 ··· 134 135 #endif /* CONFIG_PROC_VMCORE_DEVICE_DUMP */ 135 136 136 137 #ifdef CONFIG_PROC_VMCORE 137 - ssize_t read_from_oldmem(char *buf, size_t count, 138 - u64 *ppos, int userbuf, 139 - bool encrypted); 138 + ssize_t read_from_oldmem(struct iov_iter *iter, size_t count, 139 + u64 *ppos, bool encrypted); 140 140 #else 141 - static inline ssize_t read_from_oldmem(char *buf, size_t count, 142 - u64 *ppos, int userbuf, 143 - bool encrypted) 141 + static inline ssize_t read_from_oldmem(struct iov_iter *iter, size_t count, 142 + u64 *ppos, bool encrypted) 144 143 { 145 144 return -EOPNOTSUPP; 146 145 }
+3 -3
include/linux/list.h
··· 35 35 static inline void INIT_LIST_HEAD(struct list_head *list) 36 36 { 37 37 WRITE_ONCE(list->next, list); 38 - list->prev = list; 38 + WRITE_ONCE(list->prev, list); 39 39 } 40 40 41 41 #ifdef CONFIG_DEBUG_LIST ··· 306 306 static inline void list_del_init_careful(struct list_head *entry) 307 307 { 308 308 __list_del_entry(entry); 309 - entry->prev = entry; 309 + WRITE_ONCE(entry->prev, entry); 310 310 smp_store_release(&entry->next, entry); 311 311 } 312 312 ··· 326 326 static inline int list_empty_careful(const struct list_head *head) 327 327 { 328 328 struct list_head *next = smp_load_acquire(&head->next); 329 - return list_is_head(next, head) && (next == head->prev); 329 + return list_is_head(next, head) && (next == READ_ONCE(head->prev)); 330 330 } 331 331 332 332 /**
+1 -1
include/linux/pipe_fs_i.h
··· 71 71 unsigned int files; 72 72 unsigned int r_counter; 73 73 unsigned int w_counter; 74 - unsigned int poll_usage; 74 + bool poll_usage; 75 75 struct page *tmp_page; 76 76 struct fasync_struct *fasync_readers; 77 77 struct fasync_struct *fasync_writers;
+1 -1
include/linux/ptrace.h
··· 30 30 31 31 #define PT_SEIZED 0x00010000 /* SEIZE used, enable new behavior */ 32 32 #define PT_PTRACED 0x00000001 33 - #define PT_DTRACE 0x00000002 /* delayed trace (used on m68k, i386) */ 33 + #define PT_DTRACE 0x00000002 /* delayed trace (used on um) */ 34 34 35 35 #define PT_OPT_FLAG_SHIFT 3 36 36 /* PT_TRACE_* event enable flags */
+2 -1
include/uapi/linux/acct.h
··· 103 103 /* 104 104 * accounting flags 105 105 */ 106 - /* bit set when the process ... */ 106 + /* bit set when the process/task ... */ 107 107 #define AFORK 0x01 /* ... executed fork, but did not exec */ 108 108 #define ASU 0x02 /* ... used super-user privileges */ 109 109 #define ACOMPAT 0x04 /* ... used compatibility mode (VAX only not used) */ 110 110 #define ACORE 0x08 /* ... dumped core */ 111 111 #define AXSIG 0x10 /* ... was killed by a signal */ 112 + #define AGROUP 0x20 /* ... was the last task of the process (task group) */ 112 113 113 114 #if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN) 114 115 #define ACCT_BYTEORDER 0x80 /* accounting file is big endian */
+1 -1
include/uapi/linux/elf.h
··· 134 134 #define STT_TLS 6 135 135 136 136 #define ELF_ST_BIND(x) ((x) >> 4) 137 - #define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf) 137 + #define ELF_ST_TYPE(x) ((x) & 0xf) 138 138 #define ELF32_ST_BIND(x) ELF_ST_BIND(x) 139 139 #define ELF32_ST_TYPE(x) ELF_ST_TYPE(x) 140 140 #define ELF64_ST_BIND(x) ELF_ST_BIND(x)
+21 -3
include/uapi/linux/taskstats.h
··· 34 34 */ 35 35 36 36 37 - #define TASKSTATS_VERSION 11 37 + #define TASKSTATS_VERSION 12 38 38 #define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN 39 39 * in linux/sched.h */ 40 40 ··· 48 48 __u32 ac_exitcode; /* Exit status */ 49 49 50 50 /* The accounting flags of a task as defined in <linux/acct.h> 51 - * Defined values are AFORK, ASU, ACOMPAT, ACORE, and AXSIG. 51 + * Defined values are AFORK, ASU, ACOMPAT, ACORE, AXSIG, and AGROUP. 52 + * (AGROUP since version 12). 52 53 */ 53 54 __u8 ac_flag; /* Record flags */ 54 55 __u8 ac_nice; /* task_nice */ ··· 174 173 /* v10: 64-bit btime to avoid overflow */ 175 174 __u64 ac_btime64; /* 64-bit begin time */ 176 175 177 - /* Delay waiting for memory compact */ 176 + /* v11: Delay waiting for memory compact */ 178 177 __u64 compact_count; 179 178 __u64 compact_delay_total; 179 + 180 + /* v12 begin */ 181 + __u32 ac_tgid; /* thread group ID */ 182 + /* Thread group walltime up to now. This is total process walltime if 183 + * AGROUP flag is set. 184 + */ 185 + __u64 ac_tgetime __attribute__((aligned(8))); 186 + /* Lightweight information to identify process binary files. 187 + * This leaves userspace to match this to a file system path, using 188 + * MAJOR() and MINOR() macros to identify a device and mount point, 189 + * the inode to identify the executable file. This is /proc/self/exe 190 + * at the end, so matching the most recent exec(). Values are zero 191 + * for kernel threads. 192 + */ 193 + __u64 ac_exe_dev; /* program binary device ID */ 194 + __u64 ac_exe_inode; /* program binary inode number */ 195 + /* v12 end */ 180 196 }; 181 197 182 198
+12 -2
init/Kconfig
··· 423 423 See the man page for more details. 424 424 425 425 config USELIB 426 - bool "uselib syscall" 427 - def_bool ALPHA || M68K || SPARC || X86_32 || IA32_EMULATION 426 + bool "uselib syscall (for libc5 and earlier)" 427 + default ALPHA || M68K || SPARC 428 428 help 429 429 This option enables the uselib syscall, a system call used in the 430 430 dynamic linker from libc5 and earlier. glibc does not use this ··· 1345 1345 The boot config file must be attached at the end of initramfs 1346 1346 with checksum, size and magic word. 1347 1347 See <file:Documentation/admin-guide/bootconfig.rst> for details. 1348 + 1349 + If unsure, say Y. 1350 + 1351 + config INITRAMFS_PRESERVE_MTIME 1352 + bool "Preserve cpio archive mtimes in initramfs" 1353 + default y 1354 + help 1355 + Each entry in an initramfs cpio archive carries an mtime value. When 1356 + enabled, extracted cpio items take this mtime, with directory mtime 1357 + setting deferred until after creation of any child entries. 1348 1358 1349 1359 If unsure, say Y. 1350 1360
+50 -26
init/initramfs.c
··· 17 17 #include <linux/init_syscalls.h> 18 18 #include <linux/umh.h> 19 19 20 - static ssize_t __init xwrite(struct file *file, const char *p, size_t count, 21 - loff_t *pos) 20 + static __initdata bool csum_present; 21 + static __initdata u32 io_csum; 22 + 23 + static ssize_t __init xwrite(struct file *file, const unsigned char *p, 24 + size_t count, loff_t *pos) 22 25 { 23 26 ssize_t out = 0; 24 27 ··· 35 32 return out ? out : rv; 36 33 } else if (rv == 0) 37 34 break; 35 + 36 + if (csum_present) { 37 + ssize_t i; 38 + 39 + for (i = 0; i < rv; i++) 40 + io_csum += p[i]; 41 + } 38 42 39 43 p += rv; 40 44 out += rv; ··· 126 116 } 127 117 } 128 118 129 - static long __init do_utime(char *filename, time64_t mtime) 119 + #ifdef CONFIG_INITRAMFS_PRESERVE_MTIME 120 + static void __init do_utime(char *filename, time64_t mtime) 130 121 { 131 - struct timespec64 t[2]; 122 + struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } }; 123 + init_utimes(filename, t); 124 + } 132 125 133 - t[0].tv_sec = mtime; 134 - t[0].tv_nsec = 0; 135 - t[1].tv_sec = mtime; 136 - t[1].tv_nsec = 0; 137 - return init_utimes(filename, t); 126 + static void __init do_utime_path(const struct path *path, time64_t mtime) 127 + { 128 + struct timespec64 t[2] = { { .tv_sec = mtime }, { .tv_sec = mtime } }; 129 + vfs_utimes(path, t); 138 130 } 139 131 140 132 static __initdata LIST_HEAD(dir_list); 141 133 struct dir_entry { 142 134 struct list_head list; 143 - char *name; 144 135 time64_t mtime; 136 + char name[]; 145 137 }; 146 138 147 139 static void __init dir_add(const char *name, time64_t mtime) 148 140 { 149 - struct dir_entry *de = kmalloc(sizeof(struct dir_entry), GFP_KERNEL); 141 + size_t nlen = strlen(name) + 1; 142 + struct dir_entry *de; 143 + 144 + de = kmalloc(sizeof(struct dir_entry) + nlen, GFP_KERNEL); 150 145 if (!de) 151 146 panic_show_mem("can't allocate dir_entry buffer"); 152 147 INIT_LIST_HEAD(&de->list); 153 - de->name = kstrdup(name, GFP_KERNEL); 148 + strscpy(de->name, name, nlen); 154 149 de->mtime = mtime; 155 150 list_add(&de->list, &dir_list); 156 151 } ··· 166 151 list_for_each_entry_safe(de, tmp, &dir_list, list) { 167 152 list_del(&de->list); 168 153 do_utime(de->name, de->mtime); 169 - kfree(de->name); 170 154 kfree(de); 171 155 } 172 156 } 157 + #else 158 + static void __init do_utime(char *filename, time64_t mtime) {} 159 + static void __init do_utime_path(const struct path *path, time64_t mtime) {} 160 + static void __init dir_add(const char *name, time64_t mtime) {} 161 + static void __init dir_utime(void) {} 162 + #endif 173 163 174 164 static __initdata time64_t mtime; 175 165 ··· 186 166 static __initdata uid_t uid; 187 167 static __initdata gid_t gid; 188 168 static __initdata unsigned rdev; 169 + static __initdata u32 hdr_csum; 189 170 190 171 static void __init parse_header(char *s) 191 172 { 192 - unsigned long parsed[12]; 173 + unsigned long parsed[13]; 193 174 char buf[9]; 194 175 int i; 195 176 196 177 buf[8] = '\0'; 197 - for (i = 0, s += 6; i < 12; i++, s += 8) { 178 + for (i = 0, s += 6; i < 13; i++, s += 8) { 198 179 memcpy(buf, s, 8); 199 180 parsed[i] = simple_strtoul(buf, NULL, 16); 200 181 } ··· 210 189 minor = parsed[8]; 211 190 rdev = new_encode_dev(MKDEV(parsed[9], parsed[10])); 212 191 name_len = parsed[11]; 192 + hdr_csum = parsed[12]; 213 193 } 214 194 215 195 /* FSM */ ··· 279 257 280 258 static int __init do_header(void) 281 259 { 282 - if (memcmp(collected, "070707", 6)==0) { 283 - error("incorrect cpio method used: use -H newc option"); 284 - return 1; 285 - } 286 - if (memcmp(collected, "070701", 6)) { 287 - error("no cpio magic"); 260 + if (!memcmp(collected, "070701", 6)) { 261 + csum_present = false; 262 + } else if (!memcmp(collected, "070702", 6)) { 263 + csum_present = true; 264 + } else { 265 + if (memcmp(collected, "070707", 6) == 0) 266 + error("incorrect cpio method used: use -H newc option"); 267 + else 268 + error("no cpio magic"); 288 269 return 1; 289 270 } 290 271 parse_header(collected); ··· 378 353 if (IS_ERR(wfile)) 379 354 return 0; 380 355 wfile_pos = 0; 356 + io_csum = 0; 381 357 382 358 vfs_fchown(wfile, uid, gid); 383 359 vfs_fchmod(wfile, mode); ··· 406 380 static int __init do_copy(void) 407 381 { 408 382 if (byte_count >= body_len) { 409 - struct timespec64 t[2] = { }; 410 383 if (xwrite(wfile, victim, body_len, &wfile_pos) != body_len) 411 384 error("write error"); 412 385 413 - t[0].tv_sec = mtime; 414 - t[1].tv_sec = mtime; 415 - vfs_utimes(&wfile->f_path, t); 416 - 386 + do_utime_path(&wfile->f_path, mtime); 417 387 fput(wfile); 388 + if (csum_present && io_csum != hdr_csum) 389 + error("bad data checksum"); 418 390 eat(body_len); 419 391 state = SkipIt; 420 392 return 0;
+14
ipc/mqueue.c
··· 45 45 46 46 struct mqueue_fs_context { 47 47 struct ipc_namespace *ipc_ns; 48 + bool newns; /* Set if newly created ipc namespace */ 48 49 }; 49 50 50 51 #define MQUEUE_MAGIC 0x19800202 ··· 428 427 { 429 428 struct mqueue_fs_context *ctx = fc->fs_private; 430 429 430 + /* 431 + * With a newly created ipc namespace, we don't need to do a search 432 + * for an ipc namespace match, but we still need to set s_fs_info. 433 + */ 434 + if (ctx->newns) { 435 + fc->s_fs_info = ctx->ipc_ns; 436 + return get_tree_nodev(fc, mqueue_fill_super); 437 + } 431 438 return get_tree_keyed(fc, mqueue_fill_super, ctx->ipc_ns); 432 439 } 433 440 ··· 463 454 return 0; 464 455 } 465 456 457 + /* 458 + * mq_init_ns() is currently the only caller of mq_create_mount(). 459 + * So the ns parameter is always a newly created ipc namespace. 460 + */ 466 461 static struct vfsmount *mq_create_mount(struct ipc_namespace *ns) 467 462 { 468 463 struct mqueue_fs_context *ctx; ··· 478 465 return ERR_CAST(fc); 479 466 480 467 ctx = fc->fs_private; 468 + ctx->newns = true; 481 469 put_ipc_ns(ctx->ipc_ns); 482 470 ctx->ipc_ns = get_ipc_ns(ns); 483 471 put_user_ns(fc->user_ns);
+11 -14
ipc/sem.c
··· 766 766 for (sop = sops; sop < sops + nsops; sop++) { 767 767 curr = &sma->sems[sop->sem_num]; 768 768 sem_op = sop->sem_op; 769 - result = curr->semval; 770 769 771 770 if (sop->sem_flg & SEM_UNDO) { 772 771 int undo = un->semadj[sop->sem_num] - sem_op; ··· 1429 1430 if (err) 1430 1431 goto out_rcu_wakeup; 1431 1432 1432 - err = -EACCES; 1433 1433 switch (cmd) { 1434 1434 case GETALL: 1435 1435 { ··· 1993 1995 int max, locknum; 1994 1996 bool undos = false, alter = false, dupsop = false; 1995 1997 struct sem_queue queue; 1996 - unsigned long dup = 0, jiffies_left = 0; 1998 + unsigned long dup = 0; 1999 + ktime_t expires, *exp = NULL; 2000 + bool timed_out = false; 1997 2001 1998 2002 if (nsops < 1 || semid < 0) 1999 2003 return -EINVAL; ··· 2003 2003 return -E2BIG; 2004 2004 2005 2005 if (timeout) { 2006 - if (timeout->tv_sec < 0 || timeout->tv_nsec < 0 || 2007 - timeout->tv_nsec >= 1000000000L) { 2008 - error = -EINVAL; 2009 - goto out; 2010 - } 2011 - jiffies_left = timespec64_to_jiffies(timeout); 2006 + if (!timespec64_valid(timeout)) 2007 + return -EINVAL; 2008 + expires = ktime_add_safe(ktime_get(), 2009 + timespec64_to_ktime(*timeout)); 2010 + exp = &expires; 2012 2011 } 2013 2012 2014 2013 ··· 2165 2166 sem_unlock(sma, locknum); 2166 2167 rcu_read_unlock(); 2167 2168 2168 - if (timeout) 2169 - jiffies_left = schedule_timeout(jiffies_left); 2170 - else 2171 - schedule(); 2169 + timed_out = !schedule_hrtimeout_range(exp, 2170 + current->timer_slack_ns, HRTIMER_MODE_ABS); 2172 2171 2173 2172 /* 2174 2173 * fastpath: the semop has completed, either successfully or ··· 2207 2210 /* 2208 2211 * If an interrupt occurred we have to clean up the queue. 2209 2212 */ 2210 - if (timeout && jiffies_left == 0) 2213 + if (timed_out) 2211 2214 error = -EAGAIN; 2212 2215 } while (error == -EINTR && !signal_pending(current)); /* spurious */ 2213 2216
-3
kernel/crash_core.c
··· 222 222 p = strstr(p+1, name); 223 223 } 224 224 225 - if (!ck_cmdline) 226 - return NULL; 227 - 228 225 return ck_cmdline; 229 226 } 230 227
+1 -1
kernel/hung_task.c
··· 73 73 * hung task is detected: 74 74 */ 75 75 unsigned int __read_mostly sysctl_hung_task_panic = 76 - CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE; 76 + IS_ENABLED(CONFIG_BOOTPARAM_HUNG_TASK_PANIC); 77 77 78 78 static int 79 79 hung_task_panic(struct notifier_block *this, unsigned long event, void *ptr)
+12 -2
kernel/kcov.c
··· 204 204 /* The first 64-bit word is the number of subsequent PCs. */ 205 205 pos = READ_ONCE(area[0]) + 1; 206 206 if (likely(pos < t->kcov_size)) { 207 - area[pos] = ip; 207 + /* Previously we write pc before updating pos. However, some 208 + * early interrupt code could bypass check_kcov_mode() check 209 + * and invoke __sanitizer_cov_trace_pc(). If such interrupt is 210 + * raised between writing pc and updating pos, the pc could be 211 + * overitten by the recursive __sanitizer_cov_trace_pc(). 212 + * Update pos before writing pc to avoid such interleaving. 213 + */ 208 214 WRITE_ONCE(area[0], pos); 215 + barrier(); 216 + area[pos] = ip; 209 217 } 210 218 } 211 219 EXPORT_SYMBOL(__sanitizer_cov_trace_pc); ··· 244 236 start_index = 1 + count * KCOV_WORDS_PER_CMP; 245 237 end_pos = (start_index + KCOV_WORDS_PER_CMP) * sizeof(u64); 246 238 if (likely(end_pos <= max_pos)) { 239 + /* See comment in __sanitizer_cov_trace_pc(). */ 240 + WRITE_ONCE(area[0], count + 1); 241 + barrier(); 247 242 area[start_index] = type; 248 243 area[start_index + 1] = arg1; 249 244 area[start_index + 2] = arg2; 250 245 area[start_index + 3] = ip; 251 - WRITE_ONCE(area[0], count + 1); 252 246 } 253 247 } 254 248
-2
kernel/kexec_core.c
··· 768 768 kimage_free_pages(old_page); 769 769 continue; 770 770 } 771 - addr = old_addr; 772 771 page = old_page; 773 772 break; 774 773 } ··· 787 788 unsigned char __user *buf = NULL; 788 789 unsigned char *kbuf = NULL; 789 790 790 - result = 0; 791 791 if (image->file_mode) 792 792 kbuf = segment->kbuf; 793 793 else
+1 -1
kernel/pid_namespace.c
··· 52 52 /* Name collision forces to do allocation under mutex. */ 53 53 if (!*pkc) 54 54 *pkc = kmem_cache_create(name, len, 0, 55 - SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT, 0); 55 + SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT, NULL); 56 56 mutex_unlock(&pid_caches_mutex); 57 57 /* current can fail, but someone else can succeed. */ 58 58 return READ_ONCE(*pkc);
-6
kernel/ptrace.c
··· 829 829 } 830 830 #endif 831 831 832 - #ifdef PTRACE_SINGLESTEP 833 832 #define is_singlestep(request) ((request) == PTRACE_SINGLESTEP) 834 - #else 835 - #define is_singlestep(request) 0 836 - #endif 837 833 838 834 #ifdef PTRACE_SINGLEBLOCK 839 835 #define is_singleblock(request) ((request) == PTRACE_SINGLEBLOCK) ··· 1217 1221 } 1218 1222 #endif 1219 1223 1220 - #ifdef PTRACE_SINGLESTEP 1221 1224 case PTRACE_SINGLESTEP: 1222 - #endif 1223 1225 #ifdef PTRACE_SINGLEBLOCK 1224 1226 case PTRACE_SINGLEBLOCK: 1225 1227 #endif
+1 -1
kernel/relay.c
··· 440 440 441 441 mutex_lock(&relay_channels_mutex); 442 442 list_for_each_entry(chan, &relay_channels, list) { 443 - if ((buf = *per_cpu_ptr(chan->buf, cpu))) 443 + if (*per_cpu_ptr(chan->buf, cpu)) 444 444 continue; 445 445 buf = relay_open_buf(chan, cpu); 446 446 if (!buf) {
+24
kernel/taskstats.c
··· 9 9 #include <linux/kernel.h> 10 10 #include <linux/taskstats_kern.h> 11 11 #include <linux/tsacct_kern.h> 12 + #include <linux/acct.h> 12 13 #include <linux/delayacct.h> 13 14 #include <linux/cpumask.h> 14 15 #include <linux/percpu.h> ··· 154 153 up_write(&listeners->sem); 155 154 } 156 155 156 + static void exe_add_tsk(struct taskstats *stats, struct task_struct *tsk) 157 + { 158 + /* No idea if I'm allowed to access that here, now. */ 159 + struct file *exe_file = get_task_exe_file(tsk); 160 + 161 + if (exe_file) { 162 + /* Following cp_new_stat64() in stat.c . */ 163 + stats->ac_exe_dev = 164 + huge_encode_dev(exe_file->f_inode->i_sb->s_dev); 165 + stats->ac_exe_inode = exe_file->f_inode->i_ino; 166 + fput(exe_file); 167 + } else { 168 + stats->ac_exe_dev = 0; 169 + stats->ac_exe_inode = 0; 170 + } 171 + } 172 + 157 173 static void fill_stats(struct user_namespace *user_ns, 158 174 struct pid_namespace *pid_ns, 159 175 struct task_struct *tsk, struct taskstats *stats) ··· 193 175 194 176 /* fill in extended acct fields */ 195 177 xacct_add_tsk(stats, tsk); 178 + 179 + /* add executable info */ 180 + exe_add_tsk(stats, tsk); 196 181 } 197 182 198 183 static int fill_stats_for_pid(pid_t pid, struct taskstats *stats) ··· 641 620 goto err; 642 621 643 622 fill_stats(&init_user_ns, &init_pid_ns, tsk, stats); 623 + if (group_dead) 624 + stats->ac_flag |= AGROUP; 644 625 645 626 /* 646 627 * Doesn't matter if tsk is the leader or the last group member leaving ··· 688 665 .module = THIS_MODULE, 689 666 .ops = taskstats_ops, 690 667 .n_ops = ARRAY_SIZE(taskstats_ops), 668 + .netnsok = true, 691 669 }; 692 670 693 671 /* Needed early in initialization */
+8 -2
kernel/tsacct.c
··· 23 23 { 24 24 const struct cred *tcred; 25 25 u64 utime, stime, utimescaled, stimescaled; 26 - u64 delta; 26 + u64 now_ns, delta; 27 27 time64_t btime; 28 28 29 29 BUILD_BUG_ON(TS_COMM_LEN < TASK_COMM_LEN); 30 30 31 31 /* calculate task elapsed time in nsec */ 32 - delta = ktime_get_ns() - tsk->start_time; 32 + now_ns = ktime_get_ns(); 33 + /* store whole group time first */ 34 + delta = now_ns - tsk->group_leader->start_time; 33 35 /* Convert to micro seconds */ 36 + do_div(delta, NSEC_PER_USEC); 37 + stats->ac_tgetime = delta; 38 + delta = now_ns - tsk->start_time; 34 39 do_div(delta, NSEC_PER_USEC); 35 40 stats->ac_etime = delta; 36 41 /* Convert to seconds for btime (note y2106 limit) */ ··· 56 51 stats->ac_nice = task_nice(tsk); 57 52 stats->ac_sched = tsk->policy; 58 53 stats->ac_pid = task_pid_nr_ns(tsk, pid_ns); 54 + stats->ac_tgid = task_tgid_nr_ns(tsk, pid_ns); 59 55 rcu_read_lock(); 60 56 tcred = __task_cred(tsk); 61 57 stats->ac_uid = from_kuid_munged(user_ns, tcred->uid);
+2 -2
kernel/watchdog.c
··· 57 57 * Should we panic when a soft-lockup or hard-lockup occurs: 58 58 */ 59 59 unsigned int __read_mostly hardlockup_panic = 60 - CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE; 60 + IS_ENABLED(CONFIG_BOOTPARAM_HARDLOCKUP_PANIC); 61 61 /* 62 62 * We may not want to enable hard lockup detection by default in all cases, 63 63 * for example when running the kernel as a guest on a hypervisor. In these ··· 168 168 169 169 /* Global variables, exported for sysctl */ 170 170 unsigned int __read_mostly softlockup_panic = 171 - CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE; 171 + IS_ENABLED(CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC); 172 172 173 173 static bool softlockup_initialized __read_mostly; 174 174 static u64 __read_mostly sample_period;
-21
lib/Kconfig.debug
··· 1073 1073 1074 1074 Say N if unsure. 1075 1075 1076 - config BOOTPARAM_SOFTLOCKUP_PANIC_VALUE 1077 - int 1078 - depends on SOFTLOCKUP_DETECTOR 1079 - range 0 1 1080 - default 0 if !BOOTPARAM_SOFTLOCKUP_PANIC 1081 - default 1 if BOOTPARAM_SOFTLOCKUP_PANIC 1082 - 1083 1076 config HARDLOCKUP_DETECTOR_PERF 1084 1077 bool 1085 1078 select SOFTLOCKUP_DETECTOR ··· 1113 1120 using the watchdog_thresh sysctl). 1114 1121 1115 1122 Say N if unsure. 1116 - 1117 - config BOOTPARAM_HARDLOCKUP_PANIC_VALUE 1118 - int 1119 - depends on HARDLOCKUP_DETECTOR 1120 - range 0 1 1121 - default 0 if !BOOTPARAM_HARDLOCKUP_PANIC 1122 - default 1 if BOOTPARAM_HARDLOCKUP_PANIC 1123 1123 1124 1124 config DETECT_HUNG_TASK 1125 1125 bool "Detect Hung Tasks" ··· 1160 1174 where a hung tasks must be resolved ASAP. 1161 1175 1162 1176 Say N if unsure. 1163 - 1164 - config BOOTPARAM_HUNG_TASK_PANIC_VALUE 1165 - int 1166 - depends on DETECT_HUNG_TASK 1167 - range 0 1 1168 - default 0 if !BOOTPARAM_HUNG_TASK_PANIC 1169 - default 1 if BOOTPARAM_HUNG_TASK_PANIC 1170 1177 1171 1178 config WQ_WATCHDOG 1172 1179 bool "Detect Workqueue Stalls"
+1 -1
lib/glob.c
··· 45 45 * (no exception for /), it can be easily proved that there's 46 46 * never a need to backtrack multiple levels. 47 47 */ 48 - char const *back_pat = NULL, *back_str = back_str; 48 + char const *back_pat = NULL, *back_str; 49 49 50 50 /* 51 51 * Loop over each token (character or class) in pat, matching
+6 -19
lib/string.c
··· 517 517 size_t strspn(const char *s, const char *accept) 518 518 { 519 519 const char *p; 520 - const char *a; 521 - size_t count = 0; 522 520 523 521 for (p = s; *p != '\0'; ++p) { 524 - for (a = accept; *a != '\0'; ++a) { 525 - if (*p == *a) 526 - break; 527 - } 528 - if (*a == '\0') 529 - return count; 530 - ++count; 522 + if (!strchr(accept, *p)) 523 + break; 531 524 } 532 - return count; 525 + return p - s; 533 526 } 534 - 535 527 EXPORT_SYMBOL(strspn); 536 528 #endif 537 529 ··· 536 544 size_t strcspn(const char *s, const char *reject) 537 545 { 538 546 const char *p; 539 - const char *r; 540 - size_t count = 0; 541 547 542 548 for (p = s; *p != '\0'; ++p) { 543 - for (r = reject; *r != '\0'; ++r) { 544 - if (*p == *r) 545 - return count; 546 - } 547 - ++count; 549 + if (strchr(reject, *p)) 550 + break; 548 551 } 549 - return count; 552 + return p - s; 550 553 } 551 554 EXPORT_SYMBOL(strcspn); 552 555 #endif
+3
lib/string_helpers.c
··· 757 757 return ERR_PTR(-ENOMEM); 758 758 } 759 759 760 + ptr->n = n; 761 + devres_add(dev, ptr); 762 + 760 763 return ptr->array; 761 764 } 762 765 EXPORT_SYMBOL_GPL(devm_kasprintf_strarray);
+10 -2
lib/test_meminit.c
··· 279 279 c = kmem_cache_create("test_cache", size, size, SLAB_TYPESAFE_BY_RCU, 280 280 NULL); 281 281 buf = kmem_cache_alloc(c, GFP_KERNEL); 282 + if (!buf) 283 + goto out; 282 284 saved_ptr = buf; 283 285 fill_with_garbage(buf, size); 284 286 buf_contents = kmalloc(size, GFP_KERNEL); 285 - if (!buf_contents) 287 + if (!buf_contents) { 288 + kmem_cache_free(c, buf); 286 289 goto out; 290 + } 287 291 used_objects = kmalloc_array(maxiter, sizeof(void *), GFP_KERNEL); 288 292 if (!used_objects) { 293 + kmem_cache_free(c, buf); 289 294 kfree(buf_contents); 290 295 goto out; 291 296 } ··· 311 306 } 312 307 } 313 308 309 + for (iter = 0; iter < maxiter; iter++) 310 + kmem_cache_free(c, used_objects[iter]); 311 + 314 312 free_out: 315 - kmem_cache_destroy(c); 316 313 kfree(buf_contents); 317 314 kfree(used_objects); 318 315 out: 316 + kmem_cache_destroy(c); 319 317 *total_failures += fail; 320 318 return 1; 321 319 }
+33
lib/test_string.c
··· 179 179 return 0; 180 180 } 181 181 182 + static __init int strspn_selftest(void) 183 + { 184 + static const struct strspn_test { 185 + const char str[16]; 186 + const char accept[16]; 187 + const char reject[16]; 188 + unsigned a; 189 + unsigned r; 190 + } tests[] __initconst = { 191 + { "foobar", "", "", 0, 6 }, 192 + { "abba", "abc", "ABBA", 4, 4 }, 193 + { "abba", "a", "b", 1, 1 }, 194 + { "", "abc", "abc", 0, 0}, 195 + }; 196 + const struct strspn_test *s = tests; 197 + size_t i, res; 198 + 199 + for (i = 0; i < ARRAY_SIZE(tests); ++i, ++s) { 200 + res = strspn(s->str, s->accept); 201 + if (res != s->a) 202 + return 0x100 + 2*i; 203 + res = strcspn(s->str, s->reject); 204 + if (res != s->r) 205 + return 0x100 + 2*i + 1; 206 + } 207 + return 0; 208 + } 209 + 182 210 static __exit void string_selftest_remove(void) 183 211 { 184 212 } ··· 237 209 238 210 test = 5; 239 211 subtest = strnchr_selftest(); 212 + if (subtest) 213 + goto fail; 214 + 215 + test = 6; 216 + subtest = strspn_selftest(); 240 217 if (subtest) 241 218 goto fail; 242 219
+1
scripts/bloat-o-meter
··· 36 36 if name.startswith("__se_compat_sys"): continue 37 37 if name.startswith("__addressable_"): continue 38 38 if name == "linux_banner": continue 39 + if name == "vermagic": continue 39 40 # statics and some other optimizations adds random .NUMBER 40 41 name = re_NUMBER.sub('', name) 41 42 sym[name] = sym.get(name, 0) + int(size, 16)
+19 -8
scripts/decode_stacktrace.sh
··· 45 45 fi 46 46 fi 47 47 48 - declare -A cache 49 - declare -A modcache 48 + declare aarray_support=true 49 + declare -A cache 2>/dev/null 50 + if [[ $? != 0 ]]; then 51 + aarray_support=false 52 + else 53 + declare -A modcache 54 + fi 50 55 51 56 find_module() { 52 57 if [[ -n $debuginfod ]] ; then ··· 102 97 103 98 if [[ $module == "" ]] ; then 104 99 local objfile=$vmlinux 105 - elif [[ "${modcache[$module]+isset}" == "isset" ]]; then 100 + elif [[ $aarray_support == true && "${modcache[$module]+isset}" == "isset" ]]; then 106 101 local objfile=${modcache[$module]} 107 102 else 108 103 local objfile=$(find_module) ··· 110 105 echo "WARNING! Modules path isn't set, but is needed to parse this symbol" >&2 111 106 return 112 107 fi 113 - modcache[$module]=$objfile 108 + if [[ $aarray_support == true ]]; then 109 + modcache[$module]=$objfile 110 + fi 114 111 fi 115 112 116 113 # Remove the englobing parenthesis ··· 132 125 # Use 'nm vmlinux' to figure out the base address of said symbol. 133 126 # It's actually faster to call it every time than to load it 134 127 # all into bash. 135 - if [[ "${cache[$module,$name]+isset}" == "isset" ]]; then 128 + if [[ $aarray_support == true && "${cache[$module,$name]+isset}" == "isset" ]]; then 136 129 local base_addr=${cache[$module,$name]} 137 130 else 138 131 local base_addr=$(nm "$objfile" 2>/dev/null | awk '$3 == "'$name'" && ($2 == "t" || $2 == "T") {print $1; exit}') ··· 140 133 # address not found 141 134 return 142 135 fi 143 - cache[$module,$name]="$base_addr" 136 + if [[ $aarray_support == true ]]; then 137 + cache[$module,$name]="$base_addr" 138 + fi 144 139 fi 145 140 # Let's start doing the math to get the exact address into the 146 141 # symbol. First, strip out the symbol total length. ··· 158 149 159 150 # Pass it to addr2line to get filename and line number 160 151 # Could get more than one result 161 - if [[ "${cache[$module,$address]+isset}" == "isset" ]]; then 152 + if [[ $aarray_support == true && "${cache[$module,$address]+isset}" == "isset" ]]; then 162 153 local code=${cache[$module,$address]} 163 154 else 164 155 local code=$(${CROSS_COMPILE}addr2line -i -e "$objfile" "$address" 2>/dev/null) 165 - cache[$module,$address]=$code 156 + if [[ $aarray_support == true ]]; then 157 + cache[$module,$address]=$code 158 + fi 166 159 fi 167 160 168 161 # addr2line doesn't return a proper error code if it fails, so
+1
scripts/get_maintainer.pl
··· 983 983 } 984 984 985 985 foreach my $email (@file_emails) { 986 + $email = mailmap_email($email); 986 987 my ($name, $address) = parse_email($email); 987 988 988 989 my $tmp_email = format_email($name, $address, $email_usename);
+1
tools/accounting/.gitignore
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 getdelays 3 + procacct
+1 -1
tools/accounting/Makefile
··· 2 2 CC := $(CROSS_COMPILE)gcc 3 3 CFLAGS := -I../../usr/include 4 4 5 - PROGS := getdelays 5 + PROGS := getdelays procacct 6 6 7 7 all: $(PROGS) 8 8
+417
tools/accounting/procacct.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* procacct.c 3 + * 4 + * Demonstrator of fetching resource data on task exit, as a way 5 + * to accumulate accurate program resource usage statistics, without 6 + * prior identification of the programs. For that, the fields for 7 + * device and inode of the program executable binary file are also 8 + * extracted in addition to the command string. 9 + * 10 + * The TGID together with the PID and the AGROUP flag allow 11 + * identification of threads in a process and single-threaded processes. 12 + * The ac_tgetime field gives proper whole-process walltime. 13 + * 14 + * Written (changed) by Thomas Orgis, University of Hamburg in 2022 15 + * 16 + * This is a cheap derivation (inheriting the style) of getdelays.c: 17 + * 18 + * Utility to get per-pid and per-tgid delay accounting statistics 19 + * Also illustrates usage of the taskstats interface 20 + * 21 + * Copyright (C) Shailabh Nagar, IBM Corp. 2005 22 + * Copyright (C) Balbir Singh, IBM Corp. 2006 23 + * Copyright (c) Jay Lan, SGI. 2006 24 + */ 25 + 26 + #include <stdio.h> 27 + #include <stdlib.h> 28 + #include <errno.h> 29 + #include <unistd.h> 30 + #include <poll.h> 31 + #include <string.h> 32 + #include <fcntl.h> 33 + #include <sys/types.h> 34 + #include <sys/stat.h> 35 + #include <sys/socket.h> 36 + #include <sys/wait.h> 37 + #include <signal.h> 38 + 39 + #include <linux/genetlink.h> 40 + #include <linux/acct.h> 41 + #include <linux/taskstats.h> 42 + #include <linux/kdev_t.h> 43 + 44 + /* 45 + * Generic macros for dealing with netlink sockets. Might be duplicated 46 + * elsewhere. It is recommended that commercial grade applications use 47 + * libnl or libnetlink and use the interfaces provided by the library 48 + */ 49 + #define GENLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN)) 50 + #define GENLMSG_PAYLOAD(glh) (NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN) 51 + #define NLA_DATA(na) ((void *)((char *)(na) + NLA_HDRLEN)) 52 + #define NLA_PAYLOAD(len) (len - NLA_HDRLEN) 53 + 54 + #define err(code, fmt, arg...) \ 55 + do { \ 56 + fprintf(stderr, fmt, ##arg); \ 57 + exit(code); \ 58 + } while (0) 59 + 60 + int rcvbufsz; 61 + char name[100]; 62 + int dbg; 63 + int print_delays; 64 + int print_io_accounting; 65 + int print_task_context_switch_counts; 66 + 67 + #define PRINTF(fmt, arg...) { \ 68 + if (dbg) { \ 69 + printf(fmt, ##arg); \ 70 + } \ 71 + } 72 + 73 + /* Maximum size of response requested or message sent */ 74 + #define MAX_MSG_SIZE 1024 75 + /* Maximum number of cpus expected to be specified in a cpumask */ 76 + #define MAX_CPUS 32 77 + 78 + struct msgtemplate { 79 + struct nlmsghdr n; 80 + struct genlmsghdr g; 81 + char buf[MAX_MSG_SIZE]; 82 + }; 83 + 84 + char cpumask[100+6*MAX_CPUS]; 85 + 86 + static void usage(void) 87 + { 88 + fprintf(stderr, "procacct [-v] [-w logfile] [-r bufsize] [-m cpumask]\n"); 89 + fprintf(stderr, " -v: debug on\n"); 90 + } 91 + 92 + /* 93 + * Create a raw netlink socket and bind 94 + */ 95 + static int create_nl_socket(int protocol) 96 + { 97 + int fd; 98 + struct sockaddr_nl local; 99 + 100 + fd = socket(AF_NETLINK, SOCK_RAW, protocol); 101 + if (fd < 0) 102 + return -1; 103 + 104 + if (rcvbufsz) 105 + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, 106 + &rcvbufsz, sizeof(rcvbufsz)) < 0) { 107 + fprintf(stderr, "Unable to set socket rcv buf size to %d\n", 108 + rcvbufsz); 109 + goto error; 110 + } 111 + 112 + memset(&local, 0, sizeof(local)); 113 + local.nl_family = AF_NETLINK; 114 + 115 + if (bind(fd, (struct sockaddr *) &local, sizeof(local)) < 0) 116 + goto error; 117 + 118 + return fd; 119 + error: 120 + close(fd); 121 + return -1; 122 + } 123 + 124 + 125 + static int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid, 126 + __u8 genl_cmd, __u16 nla_type, 127 + void *nla_data, int nla_len) 128 + { 129 + struct nlattr *na; 130 + struct sockaddr_nl nladdr; 131 + int r, buflen; 132 + char *buf; 133 + 134 + struct msgtemplate msg; 135 + 136 + msg.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); 137 + msg.n.nlmsg_type = nlmsg_type; 138 + msg.n.nlmsg_flags = NLM_F_REQUEST; 139 + msg.n.nlmsg_seq = 0; 140 + msg.n.nlmsg_pid = nlmsg_pid; 141 + msg.g.cmd = genl_cmd; 142 + msg.g.version = 0x1; 143 + na = (struct nlattr *) GENLMSG_DATA(&msg); 144 + na->nla_type = nla_type; 145 + na->nla_len = nla_len + 1 + NLA_HDRLEN; 146 + memcpy(NLA_DATA(na), nla_data, nla_len); 147 + msg.n.nlmsg_len += NLMSG_ALIGN(na->nla_len); 148 + 149 + buf = (char *) &msg; 150 + buflen = msg.n.nlmsg_len; 151 + memset(&nladdr, 0, sizeof(nladdr)); 152 + nladdr.nl_family = AF_NETLINK; 153 + while ((r = sendto(sd, buf, buflen, 0, (struct sockaddr *) &nladdr, 154 + sizeof(nladdr))) < buflen) { 155 + if (r > 0) { 156 + buf += r; 157 + buflen -= r; 158 + } else if (errno != EAGAIN) 159 + return -1; 160 + } 161 + return 0; 162 + } 163 + 164 + 165 + /* 166 + * Probe the controller in genetlink to find the family id 167 + * for the TASKSTATS family 168 + */ 169 + static int get_family_id(int sd) 170 + { 171 + struct { 172 + struct nlmsghdr n; 173 + struct genlmsghdr g; 174 + char buf[256]; 175 + } ans; 176 + 177 + int id = 0, rc; 178 + struct nlattr *na; 179 + int rep_len; 180 + 181 + strcpy(name, TASKSTATS_GENL_NAME); 182 + rc = send_cmd(sd, GENL_ID_CTRL, getpid(), CTRL_CMD_GETFAMILY, 183 + CTRL_ATTR_FAMILY_NAME, (void *)name, 184 + strlen(TASKSTATS_GENL_NAME)+1); 185 + if (rc < 0) 186 + return 0; /* sendto() failure? */ 187 + 188 + rep_len = recv(sd, &ans, sizeof(ans), 0); 189 + if (ans.n.nlmsg_type == NLMSG_ERROR || 190 + (rep_len < 0) || !NLMSG_OK((&ans.n), rep_len)) 191 + return 0; 192 + 193 + na = (struct nlattr *) GENLMSG_DATA(&ans); 194 + na = (struct nlattr *) ((char *) na + NLA_ALIGN(na->nla_len)); 195 + if (na->nla_type == CTRL_ATTR_FAMILY_ID) 196 + id = *(__u16 *) NLA_DATA(na); 197 + 198 + return id; 199 + } 200 + 201 + #define average_ms(t, c) (t / 1000000ULL / (c ? c : 1)) 202 + 203 + static void print_procacct(struct taskstats *t) 204 + { 205 + /* First letter: T is a mere thread, G the last in a group, U unknown. */ 206 + printf( 207 + "%c pid=%lu tgid=%lu uid=%lu wall=%llu gwall=%llu cpu=%llu vmpeak=%llu rsspeak=%llu dev=%lu:%lu inode=%llu comm=%s\n" 208 + , t->version >= 12 ? (t->ac_flag & AGROUP ? 'P' : 'T') : '?' 209 + , (unsigned long)t->ac_pid 210 + , (unsigned long)(t->version >= 12 ? t->ac_tgid : 0) 211 + , (unsigned long)t->ac_uid 212 + , (unsigned long long)t->ac_etime 213 + , (unsigned long long)(t->version >= 12 ? t->ac_tgetime : 0) 214 + , (unsigned long long)(t->ac_utime+t->ac_stime) 215 + , (unsigned long long)t->hiwater_vm 216 + , (unsigned long long)t->hiwater_rss 217 + , (unsigned long)(t->version >= 12 ? MAJOR(t->ac_exe_dev) : 0) 218 + , (unsigned long)(t->version >= 12 ? MINOR(t->ac_exe_dev) : 0) 219 + , (unsigned long long)(t->version >= 12 ? t->ac_exe_inode : 0) 220 + , t->ac_comm 221 + ); 222 + } 223 + 224 + void handle_aggr(int mother, struct nlattr *na, int fd) 225 + { 226 + int aggr_len = NLA_PAYLOAD(na->nla_len); 227 + int len2 = 0; 228 + pid_t rtid = 0; 229 + 230 + na = (struct nlattr *) NLA_DATA(na); 231 + while (len2 < aggr_len) { 232 + switch (na->nla_type) { 233 + case TASKSTATS_TYPE_PID: 234 + rtid = *(int *) NLA_DATA(na); 235 + PRINTF("PID\t%d\n", rtid); 236 + break; 237 + case TASKSTATS_TYPE_TGID: 238 + rtid = *(int *) NLA_DATA(na); 239 + PRINTF("TGID\t%d\n", rtid); 240 + break; 241 + case TASKSTATS_TYPE_STATS: 242 + if (mother == TASKSTATS_TYPE_AGGR_PID) 243 + print_procacct((struct taskstats *) NLA_DATA(na)); 244 + if (fd) { 245 + if (write(fd, NLA_DATA(na), na->nla_len) < 0) 246 + err(1, "write error\n"); 247 + } 248 + break; 249 + case TASKSTATS_TYPE_NULL: 250 + break; 251 + default: 252 + fprintf(stderr, "Unknown nested nla_type %d\n", 253 + na->nla_type); 254 + break; 255 + } 256 + len2 += NLA_ALIGN(na->nla_len); 257 + na = (struct nlattr *)((char *)na + 258 + NLA_ALIGN(na->nla_len)); 259 + } 260 + } 261 + 262 + int main(int argc, char *argv[]) 263 + { 264 + int c, rc, rep_len, aggr_len, len2; 265 + int cmd_type = TASKSTATS_CMD_ATTR_UNSPEC; 266 + __u16 id; 267 + __u32 mypid; 268 + 269 + struct nlattr *na; 270 + int nl_sd = -1; 271 + int len = 0; 272 + pid_t tid = 0; 273 + 274 + int fd = 0; 275 + int write_file = 0; 276 + int maskset = 0; 277 + char *logfile = NULL; 278 + int containerset = 0; 279 + char *containerpath = NULL; 280 + int cfd = 0; 281 + int forking = 0; 282 + sigset_t sigset; 283 + 284 + struct msgtemplate msg; 285 + 286 + while (!forking) { 287 + c = getopt(argc, argv, "m:vr:"); 288 + if (c < 0) 289 + break; 290 + 291 + switch (c) { 292 + case 'w': 293 + logfile = strdup(optarg); 294 + printf("write to file %s\n", logfile); 295 + write_file = 1; 296 + break; 297 + case 'r': 298 + rcvbufsz = atoi(optarg); 299 + printf("receive buf size %d\n", rcvbufsz); 300 + if (rcvbufsz < 0) 301 + err(1, "Invalid rcv buf size\n"); 302 + break; 303 + case 'm': 304 + strncpy(cpumask, optarg, sizeof(cpumask)); 305 + cpumask[sizeof(cpumask) - 1] = '\0'; 306 + maskset = 1; 307 + break; 308 + case 'v': 309 + printf("debug on\n"); 310 + dbg = 1; 311 + break; 312 + default: 313 + usage(); 314 + exit(-1); 315 + } 316 + } 317 + if (!maskset) { 318 + maskset = 1; 319 + strncpy(cpumask, "1", sizeof(cpumask)); 320 + cpumask[sizeof(cpumask) - 1] = '\0'; 321 + } 322 + printf("cpumask %s maskset %d\n", cpumask, maskset); 323 + 324 + if (write_file) { 325 + fd = open(logfile, O_WRONLY | O_CREAT | O_TRUNC, 0644); 326 + if (fd == -1) { 327 + perror("Cannot open output file\n"); 328 + exit(1); 329 + } 330 + } 331 + 332 + nl_sd = create_nl_socket(NETLINK_GENERIC); 333 + if (nl_sd < 0) 334 + err(1, "error creating Netlink socket\n"); 335 + 336 + mypid = getpid(); 337 + id = get_family_id(nl_sd); 338 + if (!id) { 339 + fprintf(stderr, "Error getting family id, errno %d\n", errno); 340 + goto err; 341 + } 342 + PRINTF("family id %d\n", id); 343 + 344 + if (maskset) { 345 + rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET, 346 + TASKSTATS_CMD_ATTR_REGISTER_CPUMASK, 347 + &cpumask, strlen(cpumask) + 1); 348 + PRINTF("Sent register cpumask, retval %d\n", rc); 349 + if (rc < 0) { 350 + fprintf(stderr, "error sending register cpumask\n"); 351 + goto err; 352 + } 353 + } 354 + 355 + do { 356 + rep_len = recv(nl_sd, &msg, sizeof(msg), 0); 357 + PRINTF("received %d bytes\n", rep_len); 358 + 359 + if (rep_len < 0) { 360 + fprintf(stderr, "nonfatal reply error: errno %d\n", 361 + errno); 362 + continue; 363 + } 364 + if (msg.n.nlmsg_type == NLMSG_ERROR || 365 + !NLMSG_OK((&msg.n), rep_len)) { 366 + struct nlmsgerr *err = NLMSG_DATA(&msg); 367 + 368 + fprintf(stderr, "fatal reply error, errno %d\n", 369 + err->error); 370 + goto done; 371 + } 372 + 373 + PRINTF("nlmsghdr size=%zu, nlmsg_len=%d, rep_len=%d\n", 374 + sizeof(struct nlmsghdr), msg.n.nlmsg_len, rep_len); 375 + 376 + 377 + rep_len = GENLMSG_PAYLOAD(&msg.n); 378 + 379 + na = (struct nlattr *) GENLMSG_DATA(&msg); 380 + len = 0; 381 + while (len < rep_len) { 382 + len += NLA_ALIGN(na->nla_len); 383 + int mother = na->nla_type; 384 + 385 + PRINTF("mother=%i\n", mother); 386 + switch (na->nla_type) { 387 + case TASKSTATS_TYPE_AGGR_PID: 388 + case TASKSTATS_TYPE_AGGR_TGID: 389 + /* For nested attributes, na follows */ 390 + handle_aggr(mother, na, fd); 391 + break; 392 + default: 393 + fprintf(stderr, "Unexpected nla_type %d\n", 394 + na->nla_type); 395 + case TASKSTATS_TYPE_NULL: 396 + break; 397 + } 398 + na = (struct nlattr *) (GENLMSG_DATA(&msg) + len); 399 + } 400 + } while (1); 401 + done: 402 + if (maskset) { 403 + rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET, 404 + TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK, 405 + &cpumask, strlen(cpumask) + 1); 406 + printf("Sent deregister mask, retval %d\n", rc); 407 + if (rc < 0) 408 + err(rc, "error sending deregister cpumask\n"); 409 + } 410 + err: 411 + close(nl_sd); 412 + if (fd) 413 + close(fd); 414 + if (cfd) 415 + close(cfd); 416 + return 0; 417 + }
+67 -25
usr/gen_init_cpio.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 #include <stdio.h> 3 3 #include <stdlib.h> 4 + #include <stdint.h> 5 + #include <stdbool.h> 4 6 #include <sys/types.h> 5 7 #include <sys/stat.h> 6 8 #include <string.h> ··· 22 20 23 21 #define xstr(s) #s 24 22 #define str(s) xstr(s) 23 + #define MIN(a, b) ((a) < (b) ? (a) : (b)) 25 24 26 25 static unsigned int offset; 27 26 static unsigned int ino = 721; 28 27 static time_t default_mtime; 28 + static bool do_csum = false; 29 29 30 30 struct file_handler { 31 31 const char *type; ··· 81 77 82 78 sprintf(s, "%s%08X%08X%08lX%08lX%08X%08lX" 83 79 "%08X%08X%08X%08X%08X%08X%08X", 84 - "070701", /* magic */ 80 + do_csum ? "070702" : "070701", /* magic */ 85 81 0, /* ino */ 86 82 0, /* mode */ 87 83 (long) 0, /* uid */ ··· 113 109 name++; 114 110 sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" 115 111 "%08X%08X%08X%08X%08X%08X%08X", 116 - "070701", /* magic */ 112 + do_csum ? "070702" : "070701", /* magic */ 117 113 ino++, /* ino */ 118 114 S_IFLNK | mode, /* mode */ 119 115 (long) uid, /* uid */ ··· 162 158 name++; 163 159 sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" 164 160 "%08X%08X%08X%08X%08X%08X%08X", 165 - "070701", /* magic */ 161 + do_csum ? "070702" : "070701", /* magic */ 166 162 ino++, /* ino */ 167 163 mode, /* mode */ 168 164 (long) uid, /* uid */ ··· 256 252 name++; 257 253 sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" 258 254 "%08X%08X%08X%08X%08X%08X%08X", 259 - "070701", /* magic */ 255 + do_csum ? "070702" : "070701", /* magic */ 260 256 ino++, /* ino */ 261 257 mode, /* mode */ 262 258 (long) uid, /* uid */ ··· 296 292 return rc; 297 293 } 298 294 295 + static int cpio_mkfile_csum(int fd, unsigned long size, uint32_t *csum) 296 + { 297 + while (size) { 298 + unsigned char filebuf[65536]; 299 + ssize_t this_read; 300 + size_t i, this_size = MIN(size, sizeof(filebuf)); 301 + 302 + this_read = read(fd, filebuf, this_size); 303 + if (this_read <= 0 || this_read > this_size) 304 + return -1; 305 + 306 + for (i = 0; i < this_read; i++) 307 + *csum += filebuf[i]; 308 + 309 + size -= this_read; 310 + } 311 + /* seek back to the start for data segment I/O */ 312 + if (lseek(fd, 0, SEEK_SET) < 0) 313 + return -1; 314 + 315 + return 0; 316 + } 317 + 299 318 static int cpio_mkfile(const char *name, const char *location, 300 319 unsigned int mode, uid_t uid, gid_t gid, 301 320 unsigned int nlinks) 302 321 { 303 322 char s[256]; 304 - char *filebuf = NULL; 305 323 struct stat buf; 306 - long size; 324 + unsigned long size; 307 325 int file = -1; 308 326 int retval; 309 327 int rc = -1; 310 328 int namesize; 311 329 unsigned int i; 330 + uint32_t csum = 0; 312 331 313 332 mode |= S_IFREG; 314 333 ··· 353 326 buf.st_mtime = 0xffffffff; 354 327 } 355 328 356 - filebuf = malloc(buf.st_size); 357 - if (!filebuf) { 358 - fprintf (stderr, "out of memory\n"); 329 + if (buf.st_size > 0xffffffff) { 330 + fprintf(stderr, "%s: Size exceeds maximum cpio file size\n", 331 + location); 359 332 goto error; 360 333 } 361 334 362 - retval = read (file, filebuf, buf.st_size); 363 - if (retval < 0) { 364 - fprintf (stderr, "Can not read %s file\n", location); 335 + if (do_csum && cpio_mkfile_csum(file, buf.st_size, &csum) < 0) { 336 + fprintf(stderr, "Failed to checksum file %s\n", location); 365 337 goto error; 366 338 } 367 339 368 340 size = 0; 369 341 for (i = 1; i <= nlinks; i++) { 370 342 /* data goes on last link */ 371 - if (i == nlinks) size = buf.st_size; 343 + if (i == nlinks) 344 + size = buf.st_size; 372 345 373 346 if (name[0] == '/') 374 347 name++; 375 348 namesize = strlen(name) + 1; 376 349 sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" 377 350 "%08lX%08X%08X%08X%08X%08X%08X", 378 - "070701", /* magic */ 351 + do_csum ? "070702" : "070701", /* magic */ 379 352 ino, /* ino */ 380 353 mode, /* mode */ 381 354 (long) uid, /* uid */ ··· 388 361 0, /* rmajor */ 389 362 0, /* rminor */ 390 363 namesize, /* namesize */ 391 - 0); /* chksum */ 364 + size ? csum : 0); /* chksum */ 392 365 push_hdr(s); 393 366 push_string(name); 394 367 push_pad(); 395 368 396 - if (size) { 397 - if (fwrite(filebuf, size, 1, stdout) != 1) { 369 + while (size) { 370 + unsigned char filebuf[65536]; 371 + ssize_t this_read; 372 + size_t this_size = MIN(size, sizeof(filebuf)); 373 + 374 + this_read = read(file, filebuf, this_size); 375 + if (this_read <= 0 || this_read > this_size) { 376 + fprintf(stderr, "Can not read %s file\n", location); 377 + goto error; 378 + } 379 + 380 + if (fwrite(filebuf, this_read, 1, stdout) != 1) { 398 381 fprintf(stderr, "writing filebuf failed\n"); 399 382 goto error; 400 383 } 401 - offset += size; 402 - push_pad(); 384 + offset += this_read; 385 + size -= this_read; 403 386 } 387 + push_pad(); 404 388 405 389 name += namesize; 406 390 } 407 391 ino++; 408 392 rc = 0; 409 - 393 + 410 394 error: 411 - if (filebuf) free(filebuf); 412 - if (file >= 0) close(file); 395 + if (file >= 0) 396 + close(file); 413 397 return rc; 414 398 } 415 399 ··· 496 458 static void usage(const char *prog) 497 459 { 498 460 fprintf(stderr, "Usage:\n" 499 - "\t%s [-t <timestamp>] <cpio_list>\n" 461 + "\t%s [-t <timestamp>] [-c] <cpio_list>\n" 500 462 "\n" 501 463 "<cpio_list> is a file containing newline separated entries that\n" 502 464 "describe the files to be included in the initramfs archive:\n" ··· 531 493 "\n" 532 494 "<timestamp> is time in seconds since Epoch that will be used\n" 533 495 "as mtime for symlinks, special files and directories. The default\n" 534 - "is to use the current time for these entries.\n", 496 + "is to use the current time for these entries.\n" 497 + "-c: calculate and store 32-bit checksums for file data.\n", 535 498 prog); 536 499 } 537 500 ··· 574 535 575 536 default_mtime = time(NULL); 576 537 while (1) { 577 - int opt = getopt(argc, argv, "t:h"); 538 + int opt = getopt(argc, argv, "t:ch"); 578 539 char *invalid; 579 540 580 541 if (opt == -1) ··· 588 549 usage(argv[0]); 589 550 exit(1); 590 551 } 552 + break; 553 + case 'c': 554 + do_csum = true; 591 555 break; 592 556 case 'h': 593 557 case '?':