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

Merge tag 'mm-nonmm-stable-2022-08-06-2' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull misc updates from Andrew Morton:
"Updates to various subsystems which I help look after. lib, ocfs2,
fatfs, autofs, squashfs, procfs, etc. A relatively small amount of
material this time"

* tag 'mm-nonmm-stable-2022-08-06-2' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (72 commits)
scripts/gdb: ensure the absolute path is generated on initial source
MAINTAINERS: kunit: add David Gow as a maintainer of KUnit
mailmap: add linux.dev alias for Brendan Higgins
mailmap: update Kirill's email
profile: setup_profiling_timer() is moslty not implemented
ocfs2: fix a typo in a comment
ocfs2: use the bitmap API to simplify code
ocfs2: remove some useless functions
lib/mpi: fix typo 'the the' in comment
proc: add some (hopefully) insightful comments
bdi: remove enum wb_congested_state
kernel/hung_task: fix address space of proc_dohung_task_timeout_secs
lib/lzo/lzo1x_compress.c: replace ternary operator with min() and min_t()
squashfs: support reading fragments in readahead call
squashfs: implement readahead
squashfs: always build "file direct" version of page actor
Revert "squashfs: provide backing_dev_info in order to disable read-ahead"
fs/ocfs2: Fix spelling typo in comment
ia64: old_rr4 added under CONFIG_HUGETLB_PAGE
proc: fix test for "vsyscall=xonly" boot option
...

+1313 -724
+2 -1
.mailmap
··· 78 78 Boris Brezillon <bbrezillon@kernel.org> <b.brezillon@overkiz.com> 79 79 Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@bootlin.com> 80 80 Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@free-electrons.com> 81 + Brendan Higgins <brendan.higgins@linux.dev> <brendanhiggins@google.com> 81 82 Brian Avery <b.avery@hp.com> 82 83 Brian King <brking@us.ibm.com> 83 84 Brian Silverman <bsilver16384@gmail.com> <brian.silverman@bluerivertech.com> ··· 231 230 Keith Busch <kbusch@kernel.org> <keith.busch@intel.com> 232 231 Keith Busch <kbusch@kernel.org> <keith.busch@linux.intel.com> 233 232 Kenneth W Chen <kenneth.w.chen@intel.com> 234 - Kirill Tkhai <kirill.tkhai@openvz.org> <ktkhai@virtuozzo.com> 233 + Kirill Tkhai <tkhai@ya.ru> <ktkhai@virtuozzo.com> 235 234 Konstantin Khlebnikov <koct9i@gmail.com> <khlebnikov@yandex-team.ru> 236 235 Konstantin Khlebnikov <koct9i@gmail.com> <k.khlebnikov@samsung.com> 237 236 Koushik <raghavendra.koushik@neterion.com>
+13
Documentation/admin-guide/kernel-parameters.txt
··· 1673 1673 1674 1674 hlt [BUGS=ARM,SH] 1675 1675 1676 + hostname= [KNL] Set the hostname (aka UTS nodename). 1677 + Format: <string> 1678 + This allows setting the system's hostname during early 1679 + startup. This sets the name returned by gethostname. 1680 + Using this parameter to set the hostname makes it 1681 + possible to ensure the hostname is correctly set before 1682 + any userspace processes run, avoiding the possibility 1683 + that a process may call gethostname before the hostname 1684 + has been explicitly set, resulting in the calling 1685 + process getting an incorrect result. The string must 1686 + not exceed the maximum allowed hostname length (usually 1687 + 64 characters) and will be truncated otherwise. 1688 + 1676 1689 hpet= [X86-32,HPET] option to control HPET usage 1677 1690 Format: { enable (default) | disable | force | 1678 1691 verbose }
+2
MAINTAINERS
··· 11065 11065 11066 11066 KERNEL UNIT TESTING FRAMEWORK (KUnit) 11067 11067 M: Brendan Higgins <brendanhiggins@google.com> 11068 + M: David Gow <davidgow@google.com> 11068 11069 L: linux-kselftest@vger.kernel.org 11069 11070 L: kunit-dev@googlegroups.com 11070 11071 S: Maintained ··· 21278 21277 S: Maintained 21279 21278 F: Documentation/filesystems/vfat.rst 21280 21279 F: fs/fat/ 21280 + F: tools/testing/selftests/filesystems/fat/ 21281 21281 21282 21282 VFIO DRIVER 21283 21283 M: Alex Williamson <alex.williamson@redhat.com>
-6
arch/alpha/kernel/smp.c
··· 497 497 ((bogosum + 2500) / (5000/HZ)) % 100); 498 498 } 499 499 500 - int 501 - setup_profiling_timer(unsigned int multiplier) 502 - { 503 - return -EINVAL; 504 - } 505 - 506 500 static void 507 501 send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation) 508 502 {
-8
arch/arc/kernel/smp.c
··· 232 232 return 0; 233 233 } 234 234 235 - /* 236 - * not supported here 237 - */ 238 - int setup_profiling_timer(unsigned int multiplier) 239 - { 240 - return -EINVAL; 241 - } 242 - 243 235 /*****************************************************************************/ 244 236 /* Inter Processor Interrupt Handling */ 245 237 /*****************************************************************************/
-8
arch/arm/kernel/smp.c
··· 787 787 cpu_relax(); 788 788 } 789 789 790 - /* 791 - * not supported here 792 - */ 793 - int setup_profiling_timer(unsigned int multiplier) 794 - { 795 - return -EINVAL; 796 - } 797 - 798 790 #ifdef CONFIG_CPU_FREQ 799 791 800 792 static DEFINE_PER_CPU(unsigned long, l_p_j_ref);
-8
arch/arm64/kernel/smp.c
··· 1078 1078 } 1079 1079 #endif 1080 1080 1081 - /* 1082 - * not supported here 1083 - */ 1084 - int setup_profiling_timer(unsigned int multiplier) 1085 - { 1086 - return -EINVAL; 1087 - } 1088 - 1089 1081 static bool have_cpu_die(void) 1090 1082 { 1091 1083 #ifdef CONFIG_HOTPLUG_CPU
-5
arch/csky/kernel/smp.c
··· 243 243 { 244 244 } 245 245 246 - int setup_profiling_timer(unsigned int multiplier) 247 - { 248 - return -EINVAL; 249 - } 250 - 251 246 void csky_start_secondary(void) 252 247 { 253 248 struct mm_struct *mm = &init_mm;
-5
arch/hexagon/kernel/smp.c
··· 240 240 send_ipi(mask, IPI_CALL_FUNC); 241 241 } 242 242 243 - int setup_profiling_timer(unsigned int multiplier) 244 - { 245 - return -EINVAL; 246 - } 247 - 248 243 void smp_start_cpus(void) 249 244 { 250 245 int i;
+4 -1
arch/ia64/include/asm/mmu_context.h
··· 124 124 { 125 125 unsigned long rid; 126 126 unsigned long rid_incr = 0; 127 - unsigned long rr0, rr1, rr2, rr3, rr4, old_rr4; 127 + unsigned long rr0, rr1, rr2, rr3, rr4; 128 128 129 + #ifdef CONFIG_HUGETLB_PAGE 130 + unsigned long old_rr4; 129 131 old_rr4 = ia64_get_rr(RGN_BASE(RGN_HPAGE)); 132 + #endif 130 133 rid = context << 3; /* make space for encoding the region number */ 131 134 rid_incr = 1 << 8; 132 135
+14 -14
arch/ia64/include/uapi/asm/cmpxchg.h
··· 33 33 \ 34 34 switch (size) { \ 35 35 case 1: \ 36 - __xchg_result = ia64_xchg1((__u8 *)ptr, x); \ 36 + __xchg_result = ia64_xchg1((__u8 __force *)ptr, x); \ 37 37 break; \ 38 38 \ 39 39 case 2: \ 40 - __xchg_result = ia64_xchg2((__u16 *)ptr, x); \ 40 + __xchg_result = ia64_xchg2((__u16 __force *)ptr, x); \ 41 41 break; \ 42 42 \ 43 43 case 4: \ 44 - __xchg_result = ia64_xchg4((__u32 *)ptr, x); \ 44 + __xchg_result = ia64_xchg4((__u32 __force *)ptr, x); \ 45 45 break; \ 46 46 \ 47 47 case 8: \ 48 - __xchg_result = ia64_xchg8((__u64 *)ptr, x); \ 48 + __xchg_result = ia64_xchg8((__u64 __force *)ptr, x); \ 49 49 break; \ 50 50 default: \ 51 51 ia64_xchg_called_with_bad_pointer(); \ 52 52 } \ 53 - __xchg_result; \ 53 + (__typeof__ (*(ptr)) __force) __xchg_result; \ 54 54 }) 55 55 56 56 #ifndef __KERNEL__ ··· 76 76 \ 77 77 switch (size) { \ 78 78 case 1: \ 79 - _o_ = (__u8) (long) (old); \ 79 + _o_ = (__u8) (long __force) (old); \ 80 80 break; \ 81 81 case 2: \ 82 - _o_ = (__u16) (long) (old); \ 82 + _o_ = (__u16) (long __force) (old); \ 83 83 break; \ 84 84 case 4: \ 85 - _o_ = (__u32) (long) (old); \ 85 + _o_ = (__u32) (long __force) (old); \ 86 86 break; \ 87 87 case 8: \ 88 - _o_ = (__u64) (long) (old); \ 88 + _o_ = (__u64) (long __force) (old); \ 89 89 break; \ 90 90 default: \ 91 91 break; \ 92 92 } \ 93 93 switch (size) { \ 94 94 case 1: \ 95 - _r_ = ia64_cmpxchg1_##sem((__u8 *) ptr, new, _o_); \ 95 + _r_ = ia64_cmpxchg1_##sem((__u8 __force *) ptr, new, _o_); \ 96 96 break; \ 97 97 \ 98 98 case 2: \ 99 - _r_ = ia64_cmpxchg2_##sem((__u16 *) ptr, new, _o_); \ 99 + _r_ = ia64_cmpxchg2_##sem((__u16 __force *) ptr, new, _o_); \ 100 100 break; \ 101 101 \ 102 102 case 4: \ 103 - _r_ = ia64_cmpxchg4_##sem((__u32 *) ptr, new, _o_); \ 103 + _r_ = ia64_cmpxchg4_##sem((__u32 __force *) ptr, new, _o_); \ 104 104 break; \ 105 105 \ 106 106 case 8: \ 107 - _r_ = ia64_cmpxchg8_##sem((__u64 *) ptr, new, _o_); \ 107 + _r_ = ia64_cmpxchg8_##sem((__u64 __force *) ptr, new, _o_); \ 108 108 break; \ 109 109 \ 110 110 default: \ 111 111 _r_ = ia64_cmpxchg_called_with_bad_pointer(); \ 112 112 break; \ 113 113 } \ 114 - (__typeof__(old)) _r_; \ 114 + (__typeof__(old) __force) _r_; \ 115 115 }) 116 116 117 117 #define cmpxchg_acq(ptr, o, n) \
-6
arch/ia64/kernel/smp.c
··· 333 333 { 334 334 send_IPI_allbutself(IPI_CPU_STOP); 335 335 } 336 - 337 - int 338 - setup_profiling_timer (unsigned int multiplier) 339 - { 340 - return -EINVAL; 341 - }
-6
arch/openrisc/kernel/smp.c
··· 197 197 smp_call_function(stop_this_cpu, NULL, 0); 198 198 } 199 199 200 - /* not supported, yet */ 201 - int setup_profiling_timer(unsigned int multiplier) 202 - { 203 - return -EINVAL; 204 - } 205 - 206 200 void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) 207 201 { 208 202 smp_cross_call = fn;
-7
arch/parisc/kernel/smp.c
··· 513 513 514 514 pdc_cpu_rendezvous_unlock(); 515 515 } 516 - 517 - #ifdef CONFIG_PROC_FS 518 - int setup_profiling_timer(unsigned int multiplier) 519 - { 520 - return -EINVAL; 521 - } 522 - #endif
-7
arch/powerpc/kernel/smp.c
··· 1663 1663 BUG(); 1664 1664 } 1665 1665 1666 - #ifdef CONFIG_PROFILING 1667 - int setup_profiling_timer(unsigned int multiplier) 1668 - { 1669 - return 0; 1670 - } 1671 - #endif 1672 - 1673 1666 static void __init fixup_topology(void) 1674 1667 { 1675 1668 int i;
-6
arch/riscv/kernel/smp.c
··· 64 64 return phys_id == cpuid_to_hartid_map(cpu); 65 65 } 66 66 67 - /* Unsupported */ 68 - int setup_profiling_timer(unsigned int multiplier) 69 - { 70 - return -EINVAL; 71 - } 72 - 73 67 static void ipi_stop(void) 74 68 { 75 69 set_cpu_online(smp_processor_id(), false);
-5
arch/sparc/kernel/smp_32.c
··· 174 174 irq_exit(); 175 175 } 176 176 177 - int setup_profiling_timer(unsigned int multiplier) 178 - { 179 - return -EINVAL; 180 - } 181 - 182 177 void __init smp_prepare_cpus(unsigned int max_cpus) 183 178 { 184 179 int i, cpuid, extra;
-6
arch/sparc/kernel/smp_64.c
··· 1186 1186 preempt_enable(); 1187 1187 } 1188 1188 1189 - /* /proc/profile writes can call this, don't __init it please. */ 1190 - int setup_profiling_timer(unsigned int multiplier) 1191 - { 1192 - return -EINVAL; 1193 - } 1194 - 1195 1189 void __init smp_prepare_cpus(unsigned int max_cpus) 1196 1190 { 1197 1191 }
-2
arch/x86/include/asm/apic.h
··· 98 98 #include <asm/paravirt.h> 99 99 #endif 100 100 101 - extern int setup_profiling_timer(unsigned int); 102 - 103 101 static inline void native_apic_mem_write(u32 reg, u32 v) 104 102 { 105 103 volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
-5
arch/x86/kernel/apic/apic.c
··· 1115 1115 set_irq_regs(old_regs); 1116 1116 } 1117 1117 1118 - int setup_profiling_timer(unsigned int multiplier) 1119 - { 1120 - return -EINVAL; 1121 - } 1122 - 1123 1118 /* 1124 1119 * Local APIC start and shutdown 1125 1120 */
+6
arch/x86/kernel/cpu/cacheinfo.c
··· 29 29 #define LVL_3 4 30 30 #define LVL_TRACE 5 31 31 32 + /* Shared last level cache maps */ 33 + DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map); 34 + 35 + /* Shared L2 cache maps */ 36 + DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_l2c_shared_map); 37 + 32 38 struct _cache_table { 33 39 unsigned char descriptor; 34 40 char cache_type;
-4
arch/x86/kernel/smpboot.c
··· 95 95 DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_die_map); 96 96 EXPORT_PER_CPU_SYMBOL(cpu_die_map); 97 97 98 - DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map); 99 - 100 - DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_l2c_shared_map); 101 - 102 98 /* Per CPU bogomips and other parameters */ 103 99 DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info); 104 100 EXPORT_PER_CPU_SYMBOL(cpu_info);
+5 -2
fs/autofs/autofs_i.h
··· 51 51 */ 52 52 struct autofs_info { 53 53 struct dentry *dentry; 54 - struct inode *inode; 55 - 56 54 int flags; 57 55 58 56 struct completion expire_complete; ··· 144 146 { 145 147 return ((sbi->flags & AUTOFS_SBI_CATATONIC) || 146 148 task_pgrp(current) == sbi->oz_pgrp); 149 + } 150 + 151 + static inline bool autofs_empty(struct autofs_info *ino) 152 + { 153 + return ino->count < 2; 147 154 } 148 155 149 156 struct inode *autofs_get_inode(struct super_block *, umode_t);
+1 -1
fs/autofs/expire.c
··· 371 371 return NULL; 372 372 } 373 373 374 - if (simple_empty(dentry)) 374 + if (autofs_empty(ino)) 375 375 return NULL; 376 376 377 377 /* Case 2: tree mount, expire iff entire tree is not busy */
+1
fs/autofs/inode.c
··· 20 20 INIT_LIST_HEAD(&ino->expiring); 21 21 ino->last_used = jiffies; 22 22 ino->sbi = sbi; 23 + ino->count = 1; 23 24 } 24 25 return ino; 25 26 }
+50 -58
fs/autofs/root.c
··· 10 10 11 11 #include "autofs_i.h" 12 12 13 + static int autofs_dir_permission(struct user_namespace *, struct inode *, int); 13 14 static int autofs_dir_symlink(struct user_namespace *, struct inode *, 14 15 struct dentry *, const char *); 15 16 static int autofs_dir_unlink(struct inode *, struct dentry *); ··· 51 50 52 51 const struct inode_operations autofs_dir_inode_operations = { 53 52 .lookup = autofs_lookup, 53 + .permission = autofs_dir_permission, 54 54 .unlink = autofs_dir_unlink, 55 55 .symlink = autofs_dir_symlink, 56 56 .mkdir = autofs_dir_mkdir, ··· 79 77 { 80 78 struct dentry *dentry = file->f_path.dentry; 81 79 struct autofs_sb_info *sbi = autofs_sbi(dentry->d_sb); 80 + struct autofs_info *ino = autofs_dentry_ino(dentry); 82 81 83 82 pr_debug("file=%p dentry=%p %pd\n", file, dentry, dentry); 84 83 ··· 96 93 * it. 97 94 */ 98 95 spin_lock(&sbi->lookup_lock); 99 - if (!path_is_mountpoint(&file->f_path) && simple_empty(dentry)) { 96 + if (!path_is_mountpoint(&file->f_path) && autofs_empty(ino)) { 100 97 spin_unlock(&sbi->lookup_lock); 101 98 return -ENOENT; 102 99 } ··· 291 288 struct dentry *dentry = path->dentry; 292 289 struct autofs_sb_info *sbi = autofs_sbi(dentry->d_sb); 293 290 294 - /* 295 - * If this is an indirect mount the dentry could have gone away 296 - * as a result of an expire and a new one created. 291 + /* If this is an indirect mount the dentry could have gone away 292 + * and a new one created. 293 + * 294 + * This is unusual and I can't remember the case for which it 295 + * was originally added now. But an example of how this can 296 + * happen is an autofs indirect mount that has the "browse" 297 + * option set and also has the "symlink" option in the autofs 298 + * map entry. In this case the daemon will remove the browse 299 + * directory and create a symlink as the mount leaving the 300 + * struct path stale. 301 + * 302 + * Another not so obvious case is when a mount in an autofs 303 + * indirect mount that uses the "nobrowse" option is being 304 + * expired at the same time as a path walk. If the mount has 305 + * been umounted but the mount point directory seen before 306 + * becoming unhashed (during a lockless path walk) when a stat 307 + * family system call is made the mount won't be re-mounted as 308 + * it should. In this case the mount point that's been removed 309 + * (by the daemon) will be stale and the a new mount point 310 + * dentry created. 297 311 */ 298 312 if (autofs_type_indirect(sbi->type) && d_unhashed(dentry)) { 299 313 struct dentry *parent = dentry->d_parent; ··· 382 362 * the mount never trigger mounts themselves (they have an 383 363 * autofs trigger mount mounted on them). But v4 pseudo direct 384 364 * mounts do need the leaves to trigger mounts. In this case 385 - * we have no choice but to use the list_empty() check and 365 + * we have no choice but to use the autofs_empty() check and 386 366 * require user space behave. 387 367 */ 388 368 if (sbi->version > 4) { ··· 391 371 goto done; 392 372 } 393 373 } else { 394 - if (!simple_empty(dentry)) { 374 + if (!autofs_empty(ino)) { 395 375 spin_unlock(&sbi->fs_lock); 396 376 goto done; 397 377 } ··· 446 426 447 427 if (rcu_walk) { 448 428 /* We don't need fs_lock in rcu_walk mode, 449 - * just testing 'AUTOFS_INFO_NO_RCU' is enough. 450 - * simple_empty() takes a spinlock, so leave it 451 - * to last. 429 + * just testing 'AUTOFS_INF_WANT_EXPIRE' is enough. 430 + * 452 431 * We only return -EISDIR when certain this isn't 453 432 * a mount-trap. 454 433 */ ··· 460 441 inode = d_inode_rcu(dentry); 461 442 if (inode && S_ISLNK(inode->i_mode)) 462 443 return -EISDIR; 463 - if (list_empty(&dentry->d_subdirs)) 464 - return 0; 465 - if (!simple_empty(dentry)) 444 + if (!autofs_empty(ino)) 466 445 return -EISDIR; 467 446 return 0; 468 447 } ··· 480 463 * we can avoid needless calls ->d_automount() and avoid 481 464 * an incorrect ELOOP error return. 482 465 */ 483 - if ((!path_is_mountpoint(path) && !simple_empty(dentry)) || 466 + if ((!path_is_mountpoint(path) && !autofs_empty(ino)) || 484 467 (d_really_is_positive(dentry) && d_is_symlink(dentry))) 485 468 status = -EISDIR; 486 469 } ··· 543 526 return NULL; 544 527 } 545 528 529 + static int autofs_dir_permission(struct user_namespace *mnt_userns, 530 + struct inode *inode, int mask) 531 + { 532 + if (mask & MAY_WRITE) { 533 + struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb); 534 + 535 + if (!autofs_oz_mode(sbi)) 536 + return -EACCES; 537 + 538 + /* autofs_oz_mode() needs to allow path walks when the 539 + * autofs mount is catatonic but the state of an autofs 540 + * file system needs to be preserved over restarts. 541 + */ 542 + if (sbi->flags & AUTOFS_SBI_CATATONIC) 543 + return -EACCES; 544 + } 545 + 546 + return generic_permission(mnt_userns, inode, mask); 547 + } 548 + 546 549 static int autofs_dir_symlink(struct user_namespace *mnt_userns, 547 550 struct inode *dir, struct dentry *dentry, 548 551 const char *symname) 549 552 { 550 - struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb); 551 553 struct autofs_info *ino = autofs_dentry_ino(dentry); 552 554 struct autofs_info *p_ino; 553 555 struct inode *inode; ··· 574 538 char *cp; 575 539 576 540 pr_debug("%s <- %pd\n", symname, dentry); 577 - 578 - if (!autofs_oz_mode(sbi)) 579 - return -EACCES; 580 - 581 - /* autofs_oz_mode() needs to allow path walks when the 582 - * autofs mount is catatonic but the state of an autofs 583 - * file system needs to be preserved over restarts. 584 - */ 585 - if (sbi->flags & AUTOFS_SBI_CATATONIC) 586 - return -EACCES; 587 541 588 542 BUG_ON(!ino); 589 543 ··· 597 571 d_add(dentry, inode); 598 572 599 573 dget(dentry); 600 - ino->count++; 601 574 p_ino = autofs_dentry_ino(dentry->d_parent); 602 575 p_ino->count++; 603 576 ··· 626 601 struct autofs_info *ino = autofs_dentry_ino(dentry); 627 602 struct autofs_info *p_ino; 628 603 629 - if (!autofs_oz_mode(sbi)) 630 - return -EACCES; 631 - 632 - /* autofs_oz_mode() needs to allow path walks when the 633 - * autofs mount is catatonic but the state of an autofs 634 - * file system needs to be preserved over restarts. 635 - */ 636 - if (sbi->flags & AUTOFS_SBI_CATATONIC) 637 - return -EACCES; 638 - 639 - ino->count--; 640 604 p_ino = autofs_dentry_ino(dentry->d_parent); 641 605 p_ino->count--; 642 606 dput(ino->dentry); ··· 697 683 698 684 pr_debug("dentry %p, removing %pd\n", dentry, dentry); 699 685 700 - if (!autofs_oz_mode(sbi)) 701 - return -EACCES; 702 - 703 - /* autofs_oz_mode() needs to allow path walks when the 704 - * autofs mount is catatonic but the state of an autofs 705 - * file system needs to be preserved over restarts. 706 - */ 707 - if (sbi->flags & AUTOFS_SBI_CATATONIC) 708 - return -EACCES; 709 - 710 686 if (ino->count != 1) 711 687 return -ENOTEMPTY; 712 688 ··· 708 704 if (sbi->version < 5) 709 705 autofs_clear_leaf_automount_flags(dentry); 710 706 711 - ino->count--; 712 707 p_ino = autofs_dentry_ino(dentry->d_parent); 713 708 p_ino->count--; 714 709 dput(ino->dentry); ··· 729 726 struct autofs_info *p_ino; 730 727 struct inode *inode; 731 728 732 - if (!autofs_oz_mode(sbi)) 733 - return -EACCES; 734 - 735 - /* autofs_oz_mode() needs to allow path walks when the 736 - * autofs mount is catatonic but the state of an autofs 737 - * file system needs to be preserved over restarts. 738 - */ 739 - if (sbi->flags & AUTOFS_SBI_CATATONIC) 740 - return -EACCES; 741 - 742 729 pr_debug("dentry %p, creating %pd\n", dentry, dentry); 743 730 744 731 BUG_ON(!ino); ··· 746 753 autofs_set_leaf_automount_flags(dentry); 747 754 748 755 dget(dentry); 749 - ino->count++; 750 756 p_ino = autofs_dentry_ino(dentry->d_parent); 751 757 p_ino->count++; 752 758 inc_nlink(dir);
+22
fs/eventpoll.c
··· 1747 1747 return to; 1748 1748 } 1749 1749 1750 + /* 1751 + * autoremove_wake_function, but remove even on failure to wake up, because we 1752 + * know that default_wake_function/ttwu will only fail if the thread is already 1753 + * woken, and in that case the ep_poll loop will remove the entry anyways, not 1754 + * try to reuse it. 1755 + */ 1756 + static int ep_autoremove_wake_function(struct wait_queue_entry *wq_entry, 1757 + unsigned int mode, int sync, void *key) 1758 + { 1759 + int ret = default_wake_function(wq_entry, mode, sync, key); 1760 + 1761 + list_del_init(&wq_entry->entry); 1762 + return ret; 1763 + } 1764 + 1750 1765 /** 1751 1766 * ep_poll - Retrieves ready events, and delivers them to the caller-supplied 1752 1767 * event buffer. ··· 1843 1828 * normal wakeup path no need to call __remove_wait_queue() 1844 1829 * explicitly, thus ep->lock is not taken, which halts the 1845 1830 * event delivery. 1831 + * 1832 + * In fact, we now use an even more aggressive function that 1833 + * unconditionally removes, because we don't reuse the wait 1834 + * entry between loop iterations. This lets us also avoid the 1835 + * performance issue if a process is killed, causing all of its 1836 + * threads to wake up without being removed normally. 1846 1837 */ 1847 1838 init_wait(&wait); 1839 + wait.func = ep_autoremove_wake_function; 1848 1840 1849 1841 write_lock_irq(&ep->lock); 1850 1842 /*
+192 -39
fs/fat/namei_vfat.c
··· 889 889 return err; 890 890 } 891 891 892 - static int vfat_rename(struct user_namespace *mnt_userns, struct inode *old_dir, 893 - struct dentry *old_dentry, struct inode *new_dir, 894 - struct dentry *new_dentry, unsigned int flags) 892 + static int vfat_get_dotdot_de(struct inode *inode, struct buffer_head **bh, 893 + struct msdos_dir_entry **de) 894 + { 895 + if (S_ISDIR(inode->i_mode)) { 896 + if (fat_get_dotdot_entry(inode, bh, de)) 897 + return -EIO; 898 + } 899 + return 0; 900 + } 901 + 902 + static int vfat_sync_ipos(struct inode *dir, struct inode *inode) 903 + { 904 + if (IS_DIRSYNC(dir)) 905 + return fat_sync_inode(inode); 906 + mark_inode_dirty(inode); 907 + return 0; 908 + } 909 + 910 + static int vfat_update_dotdot_de(struct inode *dir, struct inode *inode, 911 + struct buffer_head *dotdot_bh, 912 + struct msdos_dir_entry *dotdot_de) 913 + { 914 + fat_set_start(dotdot_de, MSDOS_I(dir)->i_logstart); 915 + mark_buffer_dirty_inode(dotdot_bh, inode); 916 + if (IS_DIRSYNC(dir)) 917 + return sync_dirty_buffer(dotdot_bh); 918 + return 0; 919 + } 920 + 921 + static void vfat_update_dir_metadata(struct inode *dir, struct timespec64 *ts) 922 + { 923 + inode_inc_iversion(dir); 924 + fat_truncate_time(dir, ts, S_CTIME | S_MTIME); 925 + if (IS_DIRSYNC(dir)) 926 + (void)fat_sync_inode(dir); 927 + else 928 + mark_inode_dirty(dir); 929 + } 930 + 931 + static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, 932 + struct inode *new_dir, struct dentry *new_dentry) 895 933 { 896 934 struct buffer_head *dotdot_bh; 897 - struct msdos_dir_entry *dotdot_de; 935 + struct msdos_dir_entry *dotdot_de = NULL; 898 936 struct inode *old_inode, *new_inode; 899 937 struct fat_slot_info old_sinfo, sinfo; 900 938 struct timespec64 ts; 901 939 loff_t new_i_pos; 902 - int err, is_dir, update_dotdot, corrupt = 0; 940 + int err, is_dir, corrupt = 0; 903 941 struct super_block *sb = old_dir->i_sb; 904 - 905 - if (flags & ~RENAME_NOREPLACE) 906 - return -EINVAL; 907 942 908 943 old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; 909 944 old_inode = d_inode(old_dentry); ··· 948 913 if (err) 949 914 goto out; 950 915 951 - is_dir = S_ISDIR(old_inode->i_mode); 952 - update_dotdot = (is_dir && old_dir != new_dir); 953 - if (update_dotdot) { 954 - if (fat_get_dotdot_entry(old_inode, &dotdot_bh, &dotdot_de)) { 955 - err = -EIO; 916 + if (old_dir != new_dir) { 917 + err = vfat_get_dotdot_de(old_inode, &dotdot_bh, &dotdot_de); 918 + if (err) 956 919 goto out; 957 - } 958 920 } 959 921 922 + is_dir = S_ISDIR(old_inode->i_mode); 960 923 ts = current_time(old_dir); 961 924 if (new_inode) { 962 925 if (is_dir) { ··· 975 942 976 943 fat_detach(old_inode); 977 944 fat_attach(old_inode, new_i_pos); 978 - if (IS_DIRSYNC(new_dir)) { 979 - err = fat_sync_inode(old_inode); 980 - if (err) 981 - goto error_inode; 982 - } else 983 - mark_inode_dirty(old_inode); 945 + err = vfat_sync_ipos(new_dir, old_inode); 946 + if (err) 947 + goto error_inode; 984 948 985 - if (update_dotdot) { 986 - fat_set_start(dotdot_de, MSDOS_I(new_dir)->i_logstart); 987 - mark_buffer_dirty_inode(dotdot_bh, old_inode); 988 - if (IS_DIRSYNC(new_dir)) { 989 - err = sync_dirty_buffer(dotdot_bh); 990 - if (err) 991 - goto error_dotdot; 992 - } 949 + if (dotdot_de) { 950 + err = vfat_update_dotdot_de(new_dir, old_inode, dotdot_bh, 951 + dotdot_de); 952 + if (err) 953 + goto error_dotdot; 993 954 drop_nlink(old_dir); 994 955 if (!new_inode) 995 956 inc_nlink(new_dir); ··· 993 966 old_sinfo.bh = NULL; 994 967 if (err) 995 968 goto error_dotdot; 996 - inode_inc_iversion(old_dir); 997 - fat_truncate_time(old_dir, &ts, S_CTIME|S_MTIME); 998 - if (IS_DIRSYNC(old_dir)) 999 - (void)fat_sync_inode(old_dir); 1000 - else 1001 - mark_inode_dirty(old_dir); 969 + vfat_update_dir_metadata(old_dir, &ts); 1002 970 1003 971 if (new_inode) { 1004 972 drop_nlink(new_inode); ··· 1013 991 /* data cluster is shared, serious corruption */ 1014 992 corrupt = 1; 1015 993 1016 - if (update_dotdot) { 1017 - fat_set_start(dotdot_de, MSDOS_I(old_dir)->i_logstart); 1018 - mark_buffer_dirty_inode(dotdot_bh, old_inode); 1019 - corrupt |= sync_dirty_buffer(dotdot_bh); 994 + if (dotdot_de) { 995 + corrupt |= vfat_update_dotdot_de(old_dir, old_inode, dotdot_bh, 996 + dotdot_de); 1020 997 } 1021 998 error_inode: 1022 999 fat_detach(old_inode); ··· 1042 1021 goto out; 1043 1022 } 1044 1023 1024 + static void vfat_exchange_ipos(struct inode *old_inode, struct inode *new_inode, 1025 + loff_t old_i_pos, loff_t new_i_pos) 1026 + { 1027 + fat_detach(old_inode); 1028 + fat_detach(new_inode); 1029 + fat_attach(old_inode, new_i_pos); 1030 + fat_attach(new_inode, old_i_pos); 1031 + } 1032 + 1033 + static void vfat_move_nlink(struct inode *src, struct inode *dst) 1034 + { 1035 + drop_nlink(src); 1036 + inc_nlink(dst); 1037 + } 1038 + 1039 + static int vfat_rename_exchange(struct inode *old_dir, struct dentry *old_dentry, 1040 + struct inode *new_dir, struct dentry *new_dentry) 1041 + { 1042 + struct buffer_head *old_dotdot_bh = NULL, *new_dotdot_bh = NULL; 1043 + struct msdos_dir_entry *old_dotdot_de = NULL, *new_dotdot_de = NULL; 1044 + struct inode *old_inode, *new_inode; 1045 + struct timespec64 ts = current_time(old_dir); 1046 + loff_t old_i_pos, new_i_pos; 1047 + int err, corrupt = 0; 1048 + struct super_block *sb = old_dir->i_sb; 1049 + 1050 + old_inode = d_inode(old_dentry); 1051 + new_inode = d_inode(new_dentry); 1052 + 1053 + /* Acquire super block lock for the operation to be atomic */ 1054 + mutex_lock(&MSDOS_SB(sb)->s_lock); 1055 + 1056 + /* if directories are not the same, get ".." info to update */ 1057 + if (old_dir != new_dir) { 1058 + err = vfat_get_dotdot_de(old_inode, &old_dotdot_bh, 1059 + &old_dotdot_de); 1060 + if (err) 1061 + goto out; 1062 + 1063 + err = vfat_get_dotdot_de(new_inode, &new_dotdot_bh, 1064 + &new_dotdot_de); 1065 + if (err) 1066 + goto out; 1067 + } 1068 + 1069 + old_i_pos = MSDOS_I(old_inode)->i_pos; 1070 + new_i_pos = MSDOS_I(new_inode)->i_pos; 1071 + 1072 + vfat_exchange_ipos(old_inode, new_inode, old_i_pos, new_i_pos); 1073 + 1074 + err = vfat_sync_ipos(old_dir, new_inode); 1075 + if (err) 1076 + goto error_exchange; 1077 + err = vfat_sync_ipos(new_dir, old_inode); 1078 + if (err) 1079 + goto error_exchange; 1080 + 1081 + /* update ".." directory entry info */ 1082 + if (old_dotdot_de) { 1083 + err = vfat_update_dotdot_de(new_dir, old_inode, old_dotdot_bh, 1084 + old_dotdot_de); 1085 + if (err) 1086 + goto error_old_dotdot; 1087 + } 1088 + if (new_dotdot_de) { 1089 + err = vfat_update_dotdot_de(old_dir, new_inode, new_dotdot_bh, 1090 + new_dotdot_de); 1091 + if (err) 1092 + goto error_new_dotdot; 1093 + } 1094 + 1095 + /* if cross directory and only one is a directory, adjust nlink */ 1096 + if (!old_dotdot_de != !new_dotdot_de) { 1097 + if (old_dotdot_de) 1098 + vfat_move_nlink(old_dir, new_dir); 1099 + else 1100 + vfat_move_nlink(new_dir, old_dir); 1101 + } 1102 + 1103 + vfat_update_dir_metadata(old_dir, &ts); 1104 + /* if directories are not the same, update new_dir as well */ 1105 + if (old_dir != new_dir) 1106 + vfat_update_dir_metadata(new_dir, &ts); 1107 + 1108 + out: 1109 + brelse(old_dotdot_bh); 1110 + brelse(new_dotdot_bh); 1111 + mutex_unlock(&MSDOS_SB(sb)->s_lock); 1112 + 1113 + return err; 1114 + 1115 + error_new_dotdot: 1116 + if (new_dotdot_de) { 1117 + corrupt |= vfat_update_dotdot_de(new_dir, new_inode, 1118 + new_dotdot_bh, new_dotdot_de); 1119 + } 1120 + 1121 + error_old_dotdot: 1122 + if (old_dotdot_de) { 1123 + corrupt |= vfat_update_dotdot_de(old_dir, old_inode, 1124 + old_dotdot_bh, old_dotdot_de); 1125 + } 1126 + 1127 + error_exchange: 1128 + vfat_exchange_ipos(old_inode, new_inode, new_i_pos, old_i_pos); 1129 + corrupt |= vfat_sync_ipos(new_dir, new_inode); 1130 + corrupt |= vfat_sync_ipos(old_dir, old_inode); 1131 + 1132 + if (corrupt < 0) { 1133 + fat_fs_error(new_dir->i_sb, 1134 + "%s: Filesystem corrupted (i_pos %lld, %lld)", 1135 + __func__, old_i_pos, new_i_pos); 1136 + } 1137 + goto out; 1138 + } 1139 + 1140 + static int vfat_rename2(struct user_namespace *mnt_userns, struct inode *old_dir, 1141 + struct dentry *old_dentry, struct inode *new_dir, 1142 + struct dentry *new_dentry, unsigned int flags) 1143 + { 1144 + if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE)) 1145 + return -EINVAL; 1146 + 1147 + if (flags & RENAME_EXCHANGE) { 1148 + return vfat_rename_exchange(old_dir, old_dentry, 1149 + new_dir, new_dentry); 1150 + } 1151 + 1152 + /* VFS already handled RENAME_NOREPLACE, handle it as a normal rename */ 1153 + return vfat_rename(old_dir, old_dentry, new_dir, new_dentry); 1154 + } 1155 + 1045 1156 static const struct inode_operations vfat_dir_inode_operations = { 1046 1157 .create = vfat_create, 1047 1158 .lookup = vfat_lookup, 1048 1159 .unlink = vfat_unlink, 1049 1160 .mkdir = vfat_mkdir, 1050 1161 .rmdir = vfat_rmdir, 1051 - .rename = vfat_rename, 1162 + .rename = vfat_rename2, 1052 1163 .setattr = fat_setattr, 1053 1164 .getattr = fat_getattr, 1054 1165 .update_time = fat_update_time,
+19 -19
fs/kernel_read_file.c
··· 29 29 * change between calls to kernel_read_file(). 30 30 * 31 31 * Returns number of bytes read (no single read will be bigger 32 - * than INT_MAX), or negative on error. 32 + * than SSIZE_MAX), or negative on error. 33 33 * 34 34 */ 35 - int kernel_read_file(struct file *file, loff_t offset, void **buf, 36 - size_t buf_size, size_t *file_size, 37 - enum kernel_read_file_id id) 35 + ssize_t kernel_read_file(struct file *file, loff_t offset, void **buf, 36 + size_t buf_size, size_t *file_size, 37 + enum kernel_read_file_id id) 38 38 { 39 39 loff_t i_size, pos; 40 - size_t copied; 40 + ssize_t copied; 41 41 void *allocated = NULL; 42 42 bool whole_file; 43 43 int ret; ··· 58 58 goto out; 59 59 } 60 60 /* The file is too big for sane activities. */ 61 - if (i_size > INT_MAX) { 61 + if (i_size > SSIZE_MAX) { 62 62 ret = -EFBIG; 63 63 goto out; 64 64 } ··· 124 124 } 125 125 EXPORT_SYMBOL_GPL(kernel_read_file); 126 126 127 - int kernel_read_file_from_path(const char *path, loff_t offset, void **buf, 128 - size_t buf_size, size_t *file_size, 129 - enum kernel_read_file_id id) 127 + ssize_t kernel_read_file_from_path(const char *path, loff_t offset, void **buf, 128 + size_t buf_size, size_t *file_size, 129 + enum kernel_read_file_id id) 130 130 { 131 131 struct file *file; 132 - int ret; 132 + ssize_t ret; 133 133 134 134 if (!path || !*path) 135 135 return -EINVAL; ··· 144 144 } 145 145 EXPORT_SYMBOL_GPL(kernel_read_file_from_path); 146 146 147 - int kernel_read_file_from_path_initns(const char *path, loff_t offset, 148 - void **buf, size_t buf_size, 149 - size_t *file_size, 150 - enum kernel_read_file_id id) 147 + ssize_t kernel_read_file_from_path_initns(const char *path, loff_t offset, 148 + void **buf, size_t buf_size, 149 + size_t *file_size, 150 + enum kernel_read_file_id id) 151 151 { 152 152 struct file *file; 153 153 struct path root; 154 - int ret; 154 + ssize_t ret; 155 155 156 156 if (!path || !*path) 157 157 return -EINVAL; ··· 171 171 } 172 172 EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns); 173 173 174 - int kernel_read_file_from_fd(int fd, loff_t offset, void **buf, 175 - size_t buf_size, size_t *file_size, 176 - enum kernel_read_file_id id) 174 + ssize_t kernel_read_file_from_fd(int fd, loff_t offset, void **buf, 175 + size_t buf_size, size_t *file_size, 176 + enum kernel_read_file_id id) 177 177 { 178 178 struct fd f = fdget(fd); 179 - int ret = -EBADF; 179 + ssize_t ret = -EBADF; 180 180 181 181 if (!f.file || !(f.file->f_mode & FMODE_READ)) 182 182 goto out;
+11 -3
fs/ocfs2/dlmfs/dlmfs.c
··· 296 296 { 297 297 int status; 298 298 struct dlmfs_inode_private *ip; 299 + struct user_lock_res *lockres; 300 + int teardown; 299 301 300 302 clear_inode(inode); 301 303 302 304 mlog(0, "inode %lu\n", inode->i_ino); 303 305 304 306 ip = DLMFS_I(inode); 307 + lockres = &ip->ip_lockres; 305 308 306 309 if (S_ISREG(inode->i_mode)) { 307 - status = user_dlm_destroy_lock(&ip->ip_lockres); 308 - if (status < 0) 309 - mlog_errno(status); 310 + spin_lock(&lockres->l_lock); 311 + teardown = !!(lockres->l_flags & USER_LOCK_IN_TEARDOWN); 312 + spin_unlock(&lockres->l_lock); 313 + if (!teardown) { 314 + status = user_dlm_destroy_lock(lockres); 315 + if (status < 0) 316 + mlog_errno(status); 317 + } 310 318 iput(ip->ip_parent); 311 319 goto clear_fields; 312 320 }
+5 -22
fs/ocfs2/heartbeat.c
··· 2 2 /* 3 3 * heartbeat.c 4 4 * 5 - * Register ourselves with the heartbaet service, keep our node maps 5 + * Register ourselves with the heartbeat service, keep our node maps 6 6 * up to date, and fire off recovery when needed. 7 7 * 8 8 * Copyright (C) 2002, 2004 Oracle. All rights reserved. 9 9 */ 10 10 11 + #include <linux/bitmap.h> 11 12 #include <linux/fs.h> 12 13 #include <linux/types.h> 13 14 #include <linux/highmem.h> ··· 25 24 26 25 #include "buffer_head_io.h" 27 26 28 - static inline void __ocfs2_node_map_set_bit(struct ocfs2_node_map *map, 29 - int bit); 30 - static inline void __ocfs2_node_map_clear_bit(struct ocfs2_node_map *map, 31 - int bit); 32 - 33 27 /* special case -1 for now 34 28 * TODO: should *really* make sure the calling func never passes -1!! */ 35 29 static void ocfs2_node_map_init(struct ocfs2_node_map *map) 36 30 { 37 31 map->num_nodes = OCFS2_NODE_MAP_MAX_NODES; 38 - memset(map->map, 0, BITS_TO_LONGS(OCFS2_NODE_MAP_MAX_NODES) * 39 - sizeof(unsigned long)); 32 + bitmap_zero(map->map, OCFS2_NODE_MAP_MAX_NODES); 40 33 } 41 34 42 35 void ocfs2_init_node_maps(struct ocfs2_super *osb) ··· 60 65 ocfs2_recovery_thread(osb, node_num); 61 66 } 62 67 63 - static inline void __ocfs2_node_map_set_bit(struct ocfs2_node_map *map, 64 - int bit) 65 - { 66 - set_bit(bit, map->map); 67 - } 68 - 69 68 void ocfs2_node_map_set_bit(struct ocfs2_super *osb, 70 69 struct ocfs2_node_map *map, 71 70 int bit) ··· 68 79 return; 69 80 BUG_ON(bit >= map->num_nodes); 70 81 spin_lock(&osb->node_map_lock); 71 - __ocfs2_node_map_set_bit(map, bit); 82 + set_bit(bit, map->map); 72 83 spin_unlock(&osb->node_map_lock); 73 - } 74 - 75 - static inline void __ocfs2_node_map_clear_bit(struct ocfs2_node_map *map, 76 - int bit) 77 - { 78 - clear_bit(bit, map->map); 79 84 } 80 85 81 86 void ocfs2_node_map_clear_bit(struct ocfs2_super *osb, ··· 80 97 return; 81 98 BUG_ON(bit >= map->num_nodes); 82 99 spin_lock(&osb->node_map_lock); 83 - __ocfs2_node_map_clear_bit(map, bit); 100 + clear_bit(bit, map->map); 84 101 spin_unlock(&osb->node_map_lock); 85 102 } 86 103
+1 -1
fs/ocfs2/quota_global.c
··· 412 412 goto out_err; 413 413 } 414 414 415 - /* Write information to global quota file. Expects exlusive lock on quota 415 + /* Write information to global quota file. Expects exclusive lock on quota 416 416 * file inode and quota info */ 417 417 static int __ocfs2_global_write_info(struct super_block *sb, int type) 418 418 {
+4 -1
fs/proc/array.c
··· 69 69 #include <linux/sched/cputime.h> 70 70 #include <linux/proc_fs.h> 71 71 #include <linux/ioport.h> 72 - #include <linux/uaccess.h> 73 72 #include <linux/io.h> 74 73 #include <linux/mm.h> 75 74 #include <linux/hugetlb.h> ··· 99 100 { 100 101 char tcomm[64]; 101 102 103 + /* 104 + * Test before PF_KTHREAD because all workqueue worker threads are 105 + * kernel threads. 106 + */ 102 107 if (p->flags & PF_WQ_WORKER) 103 108 wq_worker_comm(tcomm, sizeof(tcomm), p); 104 109 else if (p->flags & PF_KTHREAD)
+38 -8
fs/proc/base.c
··· 1885 1885 put_pid(pid); 1886 1886 } 1887 1887 1888 - struct inode *proc_pid_make_inode(struct super_block * sb, 1888 + struct inode *proc_pid_make_inode(struct super_block *sb, 1889 1889 struct task_struct *task, umode_t mode) 1890 1890 { 1891 1891 struct inode * inode; ··· 1914 1914 1915 1915 /* Let the pid remember us for quick removal */ 1916 1916 ei->pid = pid; 1917 - if (S_ISDIR(mode)) { 1918 - spin_lock(&pid->lock); 1919 - hlist_add_head_rcu(&ei->sibling_inodes, &pid->inodes); 1920 - spin_unlock(&pid->lock); 1921 - } 1922 1917 1923 1918 task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid); 1924 1919 security_task_to_inode(task, inode); ··· 1924 1929 out_unlock: 1925 1930 iput(inode); 1926 1931 return NULL; 1932 + } 1933 + 1934 + /* 1935 + * Generating an inode and adding it into @pid->inodes, so that task will 1936 + * invalidate inode's dentry before being released. 1937 + * 1938 + * This helper is used for creating dir-type entries under '/proc' and 1939 + * '/proc/<tgid>/task'. Other entries(eg. fd, stat) under '/proc/<tgid>' 1940 + * can be released by invalidating '/proc/<tgid>' dentry. 1941 + * In theory, dentries under '/proc/<tgid>/task' can also be released by 1942 + * invalidating '/proc/<tgid>' dentry, we reserve it to handle single 1943 + * thread exiting situation: Any one of threads should invalidate its 1944 + * '/proc/<tgid>/task/<pid>' dentry before released. 1945 + */ 1946 + static struct inode *proc_pid_make_base_inode(struct super_block *sb, 1947 + struct task_struct *task, umode_t mode) 1948 + { 1949 + struct inode *inode; 1950 + struct proc_inode *ei; 1951 + struct pid *pid; 1952 + 1953 + inode = proc_pid_make_inode(sb, task, mode); 1954 + if (!inode) 1955 + return NULL; 1956 + 1957 + /* Let proc_flush_pid find this directory inode */ 1958 + ei = PROC_I(inode); 1959 + pid = ei->pid; 1960 + spin_lock(&pid->lock); 1961 + hlist_add_head_rcu(&ei->sibling_inodes, &pid->inodes); 1962 + spin_unlock(&pid->lock); 1963 + 1964 + return inode; 1927 1965 } 1928 1966 1929 1967 int pid_getattr(struct user_namespace *mnt_userns, const struct path *path, ··· 3397 3369 { 3398 3370 struct inode *inode; 3399 3371 3400 - inode = proc_pid_make_inode(dentry->d_sb, task, S_IFDIR | S_IRUGO | S_IXUGO); 3372 + inode = proc_pid_make_base_inode(dentry->d_sb, task, 3373 + S_IFDIR | S_IRUGO | S_IXUGO); 3401 3374 if (!inode) 3402 3375 return ERR_PTR(-ENOENT); 3403 3376 ··· 3700 3671 struct task_struct *task, const void *ptr) 3701 3672 { 3702 3673 struct inode *inode; 3703 - inode = proc_pid_make_inode(dentry->d_sb, task, S_IFDIR | S_IRUGO | S_IXUGO); 3674 + inode = proc_pid_make_base_inode(dentry->d_sb, task, 3675 + S_IFDIR | S_IRUGO | S_IXUGO); 3704 3676 if (!inode) 3705 3677 return ERR_PTR(-ENOENT); 3706 3678
+12 -7
fs/proc/inode.c
··· 26 26 #include <linux/mount.h> 27 27 #include <linux/bug.h> 28 28 29 - #include <linux/uaccess.h> 30 - 31 29 #include "internal.h" 32 30 33 31 static void proc_evict_inode(struct inode *inode) ··· 212 214 complete(pde->pde_unload_completion); 213 215 } 214 216 215 - /* pde is locked on entry, unlocked on exit */ 217 + /* 218 + * At most 2 contexts can enter this function: the one doing the last 219 + * close on the descriptor and whoever is deleting PDE itself. 220 + * 221 + * First to enter calls ->proc_release hook and signals its completion 222 + * to the second one which waits and then does nothing. 223 + * 224 + * PDE is locked on entry, unlocked on exit. 225 + */ 216 226 static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo) 217 227 __releases(&pde->pde_unload_lock) 218 228 { ··· 230 224 * 231 225 * rmmod (remove_proc_entry() et al) can't delete an entry and proceed: 232 226 * "struct file" needs to be available at the right moment. 233 - * 234 - * Therefore, first process to enter this function does ->release() and 235 - * signals its completion to the other process which does nothing. 236 227 */ 237 228 if (pdeo->closing) { 238 229 /* somebody else is doing that, just wait */ ··· 243 240 244 241 pdeo->closing = true; 245 242 spin_unlock(&pde->pde_unload_lock); 243 + 246 244 file = pdeo->file; 247 245 pde->proc_ops->proc_release(file_inode(file), file); 246 + 248 247 spin_lock(&pde->pde_unload_lock); 249 - /* After ->release. */ 248 + /* Strictly after ->proc_release, see above. */ 250 249 list_del(&pdeo->lh); 251 250 c = pdeo->c; 252 251 spin_unlock(&pde->pde_unload_lock);
-1
fs/proc/kmsg.c
··· 15 15 #include <linux/fs.h> 16 16 #include <linux/syslog.h> 17 17 18 - #include <linux/uaccess.h> 19 18 #include <asm/io.h> 20 19 21 20 extern wait_queue_head_t log_wait;
-1
fs/proc/nommu.c
··· 21 21 #include <linux/seq_file.h> 22 22 #include <linux/hugetlb.h> 23 23 #include <linux/vmalloc.h> 24 - #include <linux/uaccess.h> 25 24 #include <asm/tlb.h> 26 25 #include <asm/div64.h> 27 26 #include "internal.h"
+6 -3
fs/proc/proc_net.c
··· 8 8 * 9 9 * proc net directory handling functions 10 10 */ 11 - 12 - #include <linux/uaccess.h> 13 - 14 11 #include <linux/errno.h> 15 12 #include <linux/time.h> 16 13 #include <linux/proc_fs.h> ··· 350 353 kgid_t gid; 351 354 int err; 352 355 356 + /* 357 + * This PDE acts only as an anchor for /proc/${pid}/net hierarchy. 358 + * Corresponding inode (PDE(inode) == net->proc_net) is never 359 + * instantiated therefore blanket zeroing is fine. 360 + * net->proc_net_stat inode is instantiated normally. 361 + */ 353 362 err = -ENOMEM; 354 363 netd = kmem_cache_zalloc(proc_dir_entry_cache, GFP_KERNEL); 355 364 if (!netd)
-2
fs/proc/proc_tty.c
··· 4 4 * 5 5 * Copyright 1997, Theodore Ts'o 6 6 */ 7 - 8 - #include <linux/uaccess.h> 9 7 #include <linux/module.h> 10 8 #include <linux/init.h> 11 9 #include <linux/errno.h>
+5 -3
fs/proc/root.c
··· 6 6 * 7 7 * proc root directory handling functions 8 8 */ 9 - 10 - #include <linux/uaccess.h> 11 - 12 9 #include <linux/errno.h> 13 10 #include <linux/time.h> 14 11 #include <linux/proc_fs.h> ··· 302 305 proc_mkdir("bus", NULL); 303 306 proc_sys_init(); 304 307 308 + /* 309 + * Last things last. It is not like userspace processes eager 310 + * to open /proc files exist at this point but register last 311 + * anyway. 312 + */ 305 313 register_filesystem(&proc_fs_type); 306 314 } 307 315
-1
fs/proc/vmcore.c
··· 25 25 #include <linux/mutex.h> 26 26 #include <linux/vmalloc.h> 27 27 #include <linux/pagemap.h> 28 - #include <linux/uaccess.h> 29 28 #include <linux/uio.h> 30 29 #include <linux/cc_platform.h> 31 30 #include <asm/io.h>
+2 -2
fs/squashfs/Makefile
··· 5 5 6 6 obj-$(CONFIG_SQUASHFS) += squashfs.o 7 7 squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o 8 - squashfs-y += namei.o super.o symlink.o decompressor.o 8 + squashfs-y += namei.o super.o symlink.o decompressor.o page_actor.o 9 9 squashfs-$(CONFIG_SQUASHFS_FILE_CACHE) += file_cache.o 10 - squashfs-$(CONFIG_SQUASHFS_FILE_DIRECT) += file_direct.o page_actor.o 10 + squashfs-$(CONFIG_SQUASHFS_FILE_DIRECT) += file_direct.o 11 11 squashfs-$(CONFIG_SQUASHFS_DECOMP_SINGLE) += decompressor_single.o 12 12 squashfs-$(CONFIG_SQUASHFS_DECOMP_MULTI) += decompressor_multi.o 13 13 squashfs-$(CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU) += decompressor_multi_percpu.o
+7 -3
fs/squashfs/block.c
··· 34 34 struct squashfs_page_actor *actor, 35 35 int offset, int req_length) 36 36 { 37 - void *actor_addr = squashfs_first_page(actor); 37 + void *actor_addr; 38 38 struct bvec_iter_all iter_all = {}; 39 39 struct bio_vec *bvec = bvec_init_iter_all(&iter_all); 40 40 int copied_bytes = 0; 41 41 int actor_offset = 0; 42 + 43 + squashfs_actor_nobuff(actor); 44 + actor_addr = squashfs_first_page(actor); 42 45 43 46 if (WARN_ON_ONCE(!bio_next_segment(bio, &iter_all))) 44 47 return 0; ··· 52 49 53 50 bytes_to_copy = min_t(int, bytes_to_copy, 54 51 req_length - copied_bytes); 55 - memcpy(actor_addr + actor_offset, bvec_virt(bvec) + offset, 56 - bytes_to_copy); 52 + if (!IS_ERR(actor_addr)) 53 + memcpy(actor_addr + actor_offset, bvec_virt(bvec) + 54 + offset, bytes_to_copy); 57 55 58 56 actor_offset += bytes_to_copy; 59 57 copied_bytes += bytes_to_copy;
+1
fs/squashfs/decompressor.h
··· 20 20 struct bio *, int, int, struct squashfs_page_actor *); 21 21 int id; 22 22 char *name; 23 + int alloc_buffer; 23 24 int supported; 24 25 }; 25 26
+132 -1
fs/squashfs/file.c
··· 39 39 #include "squashfs_fs_sb.h" 40 40 #include "squashfs_fs_i.h" 41 41 #include "squashfs.h" 42 + #include "page_actor.h" 42 43 43 44 /* 44 45 * Locate cache slot in range [offset, index] for specified inode. If ··· 497 496 return res; 498 497 } 499 498 499 + static int squashfs_readahead_fragment(struct page **page, 500 + unsigned int pages, unsigned int expected) 501 + { 502 + struct inode *inode = page[0]->mapping->host; 503 + struct squashfs_cache_entry *buffer = squashfs_get_fragment(inode->i_sb, 504 + squashfs_i(inode)->fragment_block, 505 + squashfs_i(inode)->fragment_size); 506 + struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; 507 + unsigned int n, mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1; 508 + 509 + if (buffer->error) 510 + goto out; 511 + 512 + expected += squashfs_i(inode)->fragment_offset; 513 + 514 + for (n = 0; n < pages; n++) { 515 + unsigned int base = (page[n]->index & mask) << PAGE_SHIFT; 516 + unsigned int offset = base + squashfs_i(inode)->fragment_offset; 517 + 518 + if (expected > offset) { 519 + unsigned int avail = min_t(unsigned int, expected - 520 + offset, PAGE_SIZE); 521 + 522 + squashfs_fill_page(page[n], buffer, offset, avail); 523 + } 524 + 525 + unlock_page(page[n]); 526 + put_page(page[n]); 527 + } 528 + 529 + out: 530 + squashfs_cache_put(buffer); 531 + return buffer->error; 532 + } 533 + 534 + static void squashfs_readahead(struct readahead_control *ractl) 535 + { 536 + struct inode *inode = ractl->mapping->host; 537 + struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; 538 + size_t mask = (1UL << msblk->block_log) - 1; 539 + unsigned short shift = msblk->block_log - PAGE_SHIFT; 540 + loff_t start = readahead_pos(ractl) & ~mask; 541 + size_t len = readahead_length(ractl) + readahead_pos(ractl) - start; 542 + struct squashfs_page_actor *actor; 543 + unsigned int nr_pages = 0; 544 + struct page **pages; 545 + int i, file_end = i_size_read(inode) >> msblk->block_log; 546 + unsigned int max_pages = 1UL << shift; 547 + 548 + readahead_expand(ractl, start, (len | mask) + 1); 549 + 550 + pages = kmalloc_array(max_pages, sizeof(void *), GFP_KERNEL); 551 + if (!pages) 552 + return; 553 + 554 + for (;;) { 555 + pgoff_t index; 556 + int res, bsize; 557 + u64 block = 0; 558 + unsigned int expected; 559 + 560 + nr_pages = __readahead_batch(ractl, pages, max_pages); 561 + if (!nr_pages) 562 + break; 563 + 564 + if (readahead_pos(ractl) >= i_size_read(inode)) 565 + goto skip_pages; 566 + 567 + index = pages[0]->index >> shift; 568 + if ((pages[nr_pages - 1]->index >> shift) != index) 569 + goto skip_pages; 570 + 571 + expected = index == file_end ? 572 + (i_size_read(inode) & (msblk->block_size - 1)) : 573 + msblk->block_size; 574 + 575 + if (index == file_end && squashfs_i(inode)->fragment_block != 576 + SQUASHFS_INVALID_BLK) { 577 + res = squashfs_readahead_fragment(pages, nr_pages, 578 + expected); 579 + if (res) 580 + goto skip_pages; 581 + continue; 582 + } 583 + 584 + bsize = read_blocklist(inode, index, &block); 585 + if (bsize == 0) 586 + goto skip_pages; 587 + 588 + actor = squashfs_page_actor_init_special(msblk, pages, nr_pages, 589 + expected); 590 + if (!actor) 591 + goto skip_pages; 592 + 593 + res = squashfs_read_data(inode->i_sb, block, bsize, NULL, actor); 594 + 595 + kfree(actor); 596 + 597 + if (res == expected) { 598 + int bytes; 599 + 600 + /* Last page (if present) may have trailing bytes not filled */ 601 + bytes = res % PAGE_SIZE; 602 + if (pages[nr_pages - 1]->index == file_end && bytes) 603 + memzero_page(pages[nr_pages - 1], bytes, 604 + PAGE_SIZE - bytes); 605 + 606 + for (i = 0; i < nr_pages; i++) { 607 + flush_dcache_page(pages[i]); 608 + SetPageUptodate(pages[i]); 609 + } 610 + } 611 + 612 + for (i = 0; i < nr_pages; i++) { 613 + unlock_page(pages[i]); 614 + put_page(pages[i]); 615 + } 616 + } 617 + 618 + kfree(pages); 619 + return; 620 + 621 + skip_pages: 622 + for (i = 0; i < nr_pages; i++) { 623 + unlock_page(pages[i]); 624 + put_page(pages[i]); 625 + } 626 + kfree(pages); 627 + } 500 628 501 629 const struct address_space_operations squashfs_aops = { 502 - .read_folio = squashfs_read_folio 630 + .read_folio = squashfs_read_folio, 631 + .readahead = squashfs_readahead 503 632 };
+20 -70
fs/squashfs/file_direct.c
··· 18 18 #include "squashfs.h" 19 19 #include "page_actor.h" 20 20 21 - static int squashfs_read_cache(struct page *target_page, u64 block, int bsize, 22 - int pages, struct page **page, int bytes); 23 - 24 21 /* Read separately compressed datablock directly into page cache */ 25 22 int squashfs_readpage_block(struct page *target_page, u64 block, int bsize, 26 23 int expected) ··· 30 33 int mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1; 31 34 int start_index = target_page->index & ~mask; 32 35 int end_index = start_index | mask; 33 - int i, n, pages, missing_pages, bytes, res = -ENOMEM; 36 + int i, n, pages, bytes, res = -ENOMEM; 34 37 struct page **page; 35 38 struct squashfs_page_actor *actor; 36 39 void *pageaddr; ··· 44 47 if (page == NULL) 45 48 return res; 46 49 47 - /* 48 - * Create a "page actor" which will kmap and kunmap the 49 - * page cache pages appropriately within the decompressor 50 - */ 51 - actor = squashfs_page_actor_init_special(page, pages, 0); 52 - if (actor == NULL) 53 - goto out; 54 - 55 50 /* Try to grab all the pages covered by the Squashfs block */ 56 - for (missing_pages = 0, i = 0, n = start_index; i < pages; i++, n++) { 51 + for (i = 0, n = start_index; n <= end_index; n++) { 57 52 page[i] = (n == target_page->index) ? target_page : 58 53 grab_cache_page_nowait(target_page->mapping, n); 59 54 60 - if (page[i] == NULL) { 61 - missing_pages++; 55 + if (page[i] == NULL) 62 56 continue; 63 - } 64 57 65 58 if (PageUptodate(page[i])) { 66 59 unlock_page(page[i]); 67 60 put_page(page[i]); 68 - page[i] = NULL; 69 - missing_pages++; 61 + continue; 70 62 } 63 + 64 + i++; 71 65 } 72 66 73 - if (missing_pages) { 74 - /* 75 - * Couldn't get one or more pages, this page has either 76 - * been VM reclaimed, but others are still in the page cache 77 - * and uptodate, or we're racing with another thread in 78 - * squashfs_readpage also trying to grab them. Fall back to 79 - * using an intermediate buffer. 80 - */ 81 - res = squashfs_read_cache(target_page, block, bsize, pages, 82 - page, expected); 83 - if (res < 0) 84 - goto mark_errored; 67 + pages = i; 85 68 69 + /* 70 + * Create a "page actor" which will kmap and kunmap the 71 + * page cache pages appropriately within the decompressor 72 + */ 73 + actor = squashfs_page_actor_init_special(msblk, page, pages, expected); 74 + if (actor == NULL) 86 75 goto out; 87 - } 88 76 89 77 /* Decompress directly into the page cache buffers */ 90 78 res = squashfs_read_data(inode->i_sb, block, bsize, NULL, actor); 79 + 80 + kfree(actor); 81 + 91 82 if (res < 0) 92 83 goto mark_errored; 93 84 ··· 84 99 goto mark_errored; 85 100 } 86 101 87 - /* Last page may have trailing bytes not filled */ 102 + /* Last page (if present) may have trailing bytes not filled */ 88 103 bytes = res % PAGE_SIZE; 89 - if (bytes) { 90 - pageaddr = kmap_atomic(page[pages - 1]); 104 + if (page[pages - 1]->index == end_index && bytes) { 105 + pageaddr = kmap_local_page(page[pages - 1]); 91 106 memset(pageaddr + bytes, 0, PAGE_SIZE - bytes); 92 - kunmap_atomic(pageaddr); 107 + kunmap_local(pageaddr); 93 108 } 94 109 95 110 /* Mark pages as uptodate, unlock and release */ ··· 101 116 put_page(page[i]); 102 117 } 103 118 104 - kfree(actor); 105 119 kfree(page); 106 120 107 121 return 0; ··· 119 135 } 120 136 121 137 out: 122 - kfree(actor); 123 138 kfree(page); 124 - return res; 125 - } 126 - 127 - 128 - static int squashfs_read_cache(struct page *target_page, u64 block, int bsize, 129 - int pages, struct page **page, int bytes) 130 - { 131 - struct inode *i = target_page->mapping->host; 132 - struct squashfs_cache_entry *buffer = squashfs_get_datablock(i->i_sb, 133 - block, bsize); 134 - int res = buffer->error, n, offset = 0; 135 - 136 - if (res) { 137 - ERROR("Unable to read page, block %llx, size %x\n", block, 138 - bsize); 139 - goto out; 140 - } 141 - 142 - for (n = 0; n < pages && bytes > 0; n++, 143 - bytes -= PAGE_SIZE, offset += PAGE_SIZE) { 144 - int avail = min_t(int, bytes, PAGE_SIZE); 145 - 146 - if (page[n] == NULL) 147 - continue; 148 - 149 - squashfs_fill_page(page[n], buffer, offset, avail); 150 - unlock_page(page[n]); 151 - if (page[n] != target_page) 152 - put_page(page[n]); 153 - } 154 - 155 - out: 156 - squashfs_cache_put(buffer); 157 139 return res; 158 140 }
+5 -2
fs/squashfs/lz4_wrapper.c
··· 119 119 buff = stream->output; 120 120 while (data) { 121 121 if (bytes <= PAGE_SIZE) { 122 - memcpy(data, buff, bytes); 122 + if (!IS_ERR(data)) 123 + memcpy(data, buff, bytes); 123 124 break; 124 125 } 125 - memcpy(data, buff, PAGE_SIZE); 126 + if (!IS_ERR(data)) 127 + memcpy(data, buff, PAGE_SIZE); 126 128 buff += PAGE_SIZE; 127 129 bytes -= PAGE_SIZE; 128 130 data = squashfs_next_page(output); ··· 141 139 .decompress = lz4_uncompress, 142 140 .id = LZ4_COMPRESSION, 143 141 .name = "lz4", 142 + .alloc_buffer = 0, 144 143 .supported = 1 145 144 };
+5 -2
fs/squashfs/lzo_wrapper.c
··· 93 93 buff = stream->output; 94 94 while (data) { 95 95 if (bytes <= PAGE_SIZE) { 96 - memcpy(data, buff, bytes); 96 + if (!IS_ERR(data)) 97 + memcpy(data, buff, bytes); 97 98 break; 98 99 } else { 99 - memcpy(data, buff, PAGE_SIZE); 100 + if (!IS_ERR(data)) 101 + memcpy(data, buff, PAGE_SIZE); 100 102 buff += PAGE_SIZE; 101 103 bytes -= PAGE_SIZE; 102 104 data = squashfs_next_page(output); ··· 118 116 .decompress = lzo_uncompress, 119 117 .id = LZO_COMPRESSION, 120 118 .name = "lzo", 119 + .alloc_buffer = 0, 121 120 .supported = 1 122 121 };
+47 -8
fs/squashfs/page_actor.c
··· 7 7 #include <linux/kernel.h> 8 8 #include <linux/slab.h> 9 9 #include <linux/pagemap.h> 10 + #include "squashfs_fs_sb.h" 11 + #include "decompressor.h" 10 12 #include "page_actor.h" 11 13 12 14 /* ··· 59 57 } 60 58 61 59 /* Implementation of page_actor for decompressing directly into page cache. */ 60 + static void *handle_next_page(struct squashfs_page_actor *actor) 61 + { 62 + int max_pages = (actor->length + PAGE_SIZE - 1) >> PAGE_SHIFT; 63 + 64 + if (actor->returned_pages == max_pages) 65 + return NULL; 66 + 67 + if ((actor->next_page == actor->pages) || 68 + (actor->next_index != actor->page[actor->next_page]->index)) { 69 + if (actor->alloc_buffer) { 70 + void *tmp_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); 71 + 72 + if (tmp_buffer) { 73 + actor->tmp_buffer = tmp_buffer; 74 + actor->next_index++; 75 + actor->returned_pages++; 76 + return tmp_buffer; 77 + } 78 + } 79 + 80 + actor->next_index++; 81 + actor->returned_pages++; 82 + return ERR_PTR(-ENOMEM); 83 + } 84 + 85 + actor->next_index++; 86 + actor->returned_pages++; 87 + return actor->pageaddr = kmap_local_page(actor->page[actor->next_page++]); 88 + } 89 + 62 90 static void *direct_first_page(struct squashfs_page_actor *actor) 63 91 { 64 - actor->next_page = 1; 65 - return actor->pageaddr = kmap_atomic(actor->page[0]); 92 + return handle_next_page(actor); 66 93 } 67 94 68 95 static void *direct_next_page(struct squashfs_page_actor *actor) 69 96 { 70 97 if (actor->pageaddr) 71 - kunmap_atomic(actor->pageaddr); 98 + kunmap_local(actor->pageaddr); 72 99 73 - return actor->pageaddr = actor->next_page == actor->pages ? NULL : 74 - kmap_atomic(actor->page[actor->next_page++]); 100 + kfree(actor->tmp_buffer); 101 + actor->pageaddr = actor->tmp_buffer = NULL; 102 + 103 + return handle_next_page(actor); 75 104 } 76 105 77 106 static void direct_finish_page(struct squashfs_page_actor *actor) 78 107 { 79 108 if (actor->pageaddr) 80 - kunmap_atomic(actor->pageaddr); 109 + kunmap_local(actor->pageaddr); 110 + 111 + kfree(actor->tmp_buffer); 81 112 } 82 113 83 - struct squashfs_page_actor *squashfs_page_actor_init_special(struct page **page, 84 - int pages, int length) 114 + struct squashfs_page_actor *squashfs_page_actor_init_special(struct squashfs_sb_info *msblk, 115 + struct page **page, int pages, int length) 85 116 { 86 117 struct squashfs_page_actor *actor = kmalloc(sizeof(*actor), GFP_KERNEL); 87 118 ··· 125 90 actor->page = page; 126 91 actor->pages = pages; 127 92 actor->next_page = 0; 93 + actor->returned_pages = 0; 94 + actor->next_index = page[0]->index & ~((1 << (msblk->block_log - PAGE_SHIFT)) - 1); 128 95 actor->pageaddr = NULL; 96 + actor->tmp_buffer = NULL; 97 + actor->alloc_buffer = msblk->decompressor->alloc_buffer; 129 98 actor->squashfs_first_page = direct_first_page; 130 99 actor->squashfs_next_page = direct_next_page; 131 100 actor->squashfs_finish_page = direct_finish_page;
+13 -44
fs/squashfs/page_actor.h
··· 6 6 * Phillip Lougher <phillip@squashfs.org.uk> 7 7 */ 8 8 9 - #ifndef CONFIG_SQUASHFS_FILE_DIRECT 10 - struct squashfs_page_actor { 11 - void **page; 12 - int pages; 13 - int length; 14 - int next_page; 15 - }; 16 - 17 - static inline struct squashfs_page_actor *squashfs_page_actor_init(void **page, 18 - int pages, int length) 19 - { 20 - struct squashfs_page_actor *actor = kmalloc(sizeof(*actor), GFP_KERNEL); 21 - 22 - if (actor == NULL) 23 - return NULL; 24 - 25 - actor->length = length ? : pages * PAGE_SIZE; 26 - actor->page = page; 27 - actor->pages = pages; 28 - actor->next_page = 0; 29 - return actor; 30 - } 31 - 32 - static inline void *squashfs_first_page(struct squashfs_page_actor *actor) 33 - { 34 - actor->next_page = 1; 35 - return actor->page[0]; 36 - } 37 - 38 - static inline void *squashfs_next_page(struct squashfs_page_actor *actor) 39 - { 40 - return actor->next_page == actor->pages ? NULL : 41 - actor->page[actor->next_page++]; 42 - } 43 - 44 - static inline void squashfs_finish_page(struct squashfs_page_actor *actor) 45 - { 46 - /* empty */ 47 - } 48 - #else 49 9 struct squashfs_page_actor { 50 10 union { 51 11 void **buffer; 52 12 struct page **page; 53 13 }; 54 14 void *pageaddr; 15 + void *tmp_buffer; 55 16 void *(*squashfs_first_page)(struct squashfs_page_actor *); 56 17 void *(*squashfs_next_page)(struct squashfs_page_actor *); 57 18 void (*squashfs_finish_page)(struct squashfs_page_actor *); 58 19 int pages; 59 20 int length; 60 21 int next_page; 22 + int alloc_buffer; 23 + int returned_pages; 24 + pgoff_t next_index; 61 25 }; 62 26 63 - extern struct squashfs_page_actor *squashfs_page_actor_init(void **, int, int); 64 - extern struct squashfs_page_actor *squashfs_page_actor_init_special(struct page 65 - **, int, int); 27 + extern struct squashfs_page_actor *squashfs_page_actor_init(void **buffer, 28 + int pages, int length); 29 + extern struct squashfs_page_actor *squashfs_page_actor_init_special( 30 + struct squashfs_sb_info *msblk, 31 + struct page **page, int pages, int length); 66 32 static inline void *squashfs_first_page(struct squashfs_page_actor *actor) 67 33 { 68 34 return actor->squashfs_first_page(actor); ··· 41 75 { 42 76 actor->squashfs_finish_page(actor); 43 77 } 44 - #endif 78 + static inline void squashfs_actor_nobuff(struct squashfs_page_actor *actor) 79 + { 80 + actor->alloc_buffer = 0; 81 + } 45 82 #endif
-33
fs/squashfs/super.c
··· 29 29 #include <linux/module.h> 30 30 #include <linux/magic.h> 31 31 #include <linux/xattr.h> 32 - #include <linux/backing-dev.h> 33 32 34 33 #include "squashfs_fs.h" 35 34 #include "squashfs_fs_sb.h" ··· 112 113 return decompressor; 113 114 } 114 115 115 - static int squashfs_bdi_init(struct super_block *sb) 116 - { 117 - int err; 118 - unsigned int major = MAJOR(sb->s_dev); 119 - unsigned int minor = MINOR(sb->s_dev); 120 - 121 - bdi_put(sb->s_bdi); 122 - sb->s_bdi = &noop_backing_dev_info; 123 - 124 - err = super_setup_bdi_name(sb, "squashfs_%u_%u", major, minor); 125 - if (err) 126 - return err; 127 - 128 - sb->s_bdi->ra_pages = 0; 129 - sb->s_bdi->io_pages = 0; 130 - 131 - return 0; 132 - } 133 116 134 117 static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc) 135 118 { ··· 126 145 int err; 127 146 128 147 TRACE("Entered squashfs_fill_superblock\n"); 129 - 130 - /* 131 - * squashfs provides 'backing_dev_info' in order to disable read-ahead. For 132 - * squashfs, I/O is not deferred, it is done immediately in read_folio, 133 - * which means the user would always have to wait their own I/O. So the effect 134 - * of readahead is very weak for squashfs. squashfs_bdi_init will set 135 - * sb->s_bdi->ra_pages and sb->s_bdi->io_pages to 0 and close readahead for 136 - * squashfs. 137 - */ 138 - err = squashfs_bdi_init(sb); 139 - if (err) { 140 - errorf(fc, "squashfs init bdi failed"); 141 - return err; 142 - } 143 148 144 149 sb->s_fs_info = kzalloc(sizeof(*msblk), GFP_KERNEL); 145 150 if (sb->s_fs_info == NULL) {
+10 -1
fs/squashfs/xz_wrapper.c
··· 131 131 stream->buf.out_pos = 0; 132 132 stream->buf.out_size = PAGE_SIZE; 133 133 stream->buf.out = squashfs_first_page(output); 134 + if (IS_ERR(stream->buf.out)) { 135 + error = PTR_ERR(stream->buf.out); 136 + goto finish; 137 + } 134 138 135 139 for (;;) { 136 140 enum xz_ret xz_err; ··· 160 156 161 157 if (stream->buf.out_pos == stream->buf.out_size) { 162 158 stream->buf.out = squashfs_next_page(output); 163 - if (stream->buf.out != NULL) { 159 + if (IS_ERR(stream->buf.out)) { 160 + error = PTR_ERR(stream->buf.out); 161 + break; 162 + } else if (stream->buf.out != NULL) { 164 163 stream->buf.out_pos = 0; 165 164 total += PAGE_SIZE; 166 165 } ··· 178 171 } 179 172 } 180 173 174 + finish: 181 175 squashfs_finish_page(output); 182 176 183 177 return error ? error : total + stream->buf.out_pos; ··· 191 183 .decompress = squashfs_xz_uncompress, 192 184 .id = XZ_COMPRESSION, 193 185 .name = "xz", 186 + .alloc_buffer = 1, 194 187 .supported = 1 195 188 };
+11 -1
fs/squashfs/zlib_wrapper.c
··· 62 62 stream->next_out = squashfs_first_page(output); 63 63 stream->avail_in = 0; 64 64 65 + if (IS_ERR(stream->next_out)) { 66 + error = PTR_ERR(stream->next_out); 67 + goto finish; 68 + } 69 + 65 70 for (;;) { 66 71 int zlib_err; 67 72 ··· 90 85 91 86 if (stream->avail_out == 0) { 92 87 stream->next_out = squashfs_next_page(output); 93 - if (stream->next_out != NULL) 88 + if (IS_ERR(stream->next_out)) { 89 + error = PTR_ERR(stream->next_out); 90 + break; 91 + } else if (stream->next_out != NULL) 94 92 stream->avail_out = PAGE_SIZE; 95 93 } 96 94 ··· 115 107 } 116 108 } 117 109 110 + finish: 118 111 squashfs_finish_page(output); 119 112 120 113 if (!error) ··· 131 122 .decompress = zlib_uncompress, 132 123 .id = ZLIB_COMPRESSION, 133 124 .name = "zlib", 125 + .alloc_buffer = 1, 134 126 .supported = 1 135 127 }; 136 128
+11 -1
fs/squashfs/zstd_wrapper.c
··· 80 80 81 81 out_buf.size = PAGE_SIZE; 82 82 out_buf.dst = squashfs_first_page(output); 83 + if (IS_ERR(out_buf.dst)) { 84 + error = PTR_ERR(out_buf.dst); 85 + goto finish; 86 + } 83 87 84 88 for (;;) { 85 89 size_t zstd_err; ··· 108 104 109 105 if (out_buf.pos == out_buf.size) { 110 106 out_buf.dst = squashfs_next_page(output); 111 - if (out_buf.dst == NULL) { 107 + if (IS_ERR(out_buf.dst)) { 108 + error = PTR_ERR(out_buf.dst); 109 + break; 110 + } else if (out_buf.dst == NULL) { 112 111 /* Shouldn't run out of pages 113 112 * before stream is done. 114 113 */ ··· 136 129 } 137 130 } 138 131 132 + finish: 133 + 139 134 squashfs_finish_page(output); 140 135 141 136 return error ? error : total_out; ··· 149 140 .decompress = zstd_uncompress, 150 141 .id = ZSTD_COMPRESSION, 151 142 .name = "zstd", 143 + .alloc_buffer = 1, 152 144 .supported = 1 153 145 };
-7
include/linux/backing-dev-defs.h
··· 28 28 WB_start_all, /* nr_pages == 0 (all) work pending */ 29 29 }; 30 30 31 - enum wb_congested_state { 32 - WB_async_congested, /* The async (write) queue is getting full */ 33 - WB_sync_congested, /* The sync queue is getting full */ 34 - }; 35 - 36 31 enum wb_stat_item { 37 32 WB_RECLAIMABLE, 38 33 WB_WRITEBACK, ··· 116 121 117 122 atomic_t writeback_inodes; /* number of inodes under writeback */ 118 123 struct percpu_counter stat[NR_WB_STAT_ITEMS]; 119 - 120 - unsigned long congested; /* WB_[a]sync_congested flags */ 121 124 122 125 unsigned long bw_time_stamp; /* last time write bw is updated */ 123 126 unsigned long dirtied_stamp;
-11
include/linux/compiler-gcc.h
··· 66 66 __builtin_unreachable(); \ 67 67 } while (0) 68 68 69 - /* 70 - * GCC 'asm goto' miscompiles certain code sequences: 71 - * 72 - * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 73 - * 74 - * Work it around via a compiler barrier quirk suggested by Jakub Jelinek. 75 - * 76 - * (asm goto is automatically volatile - the naming reflects this.) 77 - */ 78 - #define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) 79 - 80 69 #if defined(CONFIG_ARCH_USE_BUILTIN_BSWAP) 81 70 #define __HAVE_BUILTIN_BSWAP32__ 82 71 #define __HAVE_BUILTIN_BSWAP64__
+27 -81
include/linux/cpumask.h
··· 116 116 return cpu; 117 117 } 118 118 119 - #if NR_CPUS == 1 120 - /* Uniprocessor. Assume all masks are "1". */ 121 - static inline unsigned int cpumask_first(const struct cpumask *srcp) 122 - { 123 - return 0; 124 - } 125 - 126 - static inline unsigned int cpumask_first_zero(const struct cpumask *srcp) 127 - { 128 - return 0; 129 - } 130 - 131 - static inline unsigned int cpumask_first_and(const struct cpumask *srcp1, 132 - const struct cpumask *srcp2) 133 - { 134 - return 0; 135 - } 136 - 137 - static inline unsigned int cpumask_last(const struct cpumask *srcp) 138 - { 139 - return 0; 140 - } 141 - 142 - /* Valid inputs for n are -1 and 0. */ 143 - static inline unsigned int cpumask_next(int n, const struct cpumask *srcp) 144 - { 145 - return n+1; 146 - } 147 - 148 - static inline unsigned int cpumask_next_zero(int n, const struct cpumask *srcp) 149 - { 150 - return n+1; 151 - } 152 - 153 - static inline unsigned int cpumask_next_and(int n, 154 - const struct cpumask *srcp, 155 - const struct cpumask *andp) 156 - { 157 - return n+1; 158 - } 159 - 160 - static inline unsigned int cpumask_next_wrap(int n, const struct cpumask *mask, 161 - int start, bool wrap) 162 - { 163 - /* cpu0 unless stop condition, wrap and at cpu0, then nr_cpumask_bits */ 164 - return (wrap && n == 0); 165 - } 166 - 167 - /* cpu must be a valid cpu, ie 0, so there's no other choice. */ 168 - static inline unsigned int cpumask_any_but(const struct cpumask *mask, 169 - unsigned int cpu) 170 - { 171 - return 1; 172 - } 173 - 174 - static inline unsigned int cpumask_local_spread(unsigned int i, int node) 175 - { 176 - return 0; 177 - } 178 - 179 - static inline int cpumask_any_and_distribute(const struct cpumask *src1p, 180 - const struct cpumask *src2p) { 181 - return cpumask_first_and(src1p, src2p); 182 - } 183 - 184 - static inline int cpumask_any_distribute(const struct cpumask *srcp) 185 - { 186 - return cpumask_first(srcp); 187 - } 188 - 189 - #define for_each_cpu(cpu, mask) \ 190 - for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) 191 - #define for_each_cpu_not(cpu, mask) \ 192 - for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) 193 - #define for_each_cpu_wrap(cpu, mask, start) \ 194 - for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask, (void)(start)) 195 - #define for_each_cpu_and(cpu, mask1, mask2) \ 196 - for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask1, (void)mask2) 197 - #else 198 119 /** 199 120 * cpumask_first - get the first cpu in a cpumask 200 121 * @srcp: the cpumask pointer ··· 181 260 182 261 int __pure cpumask_next_and(int n, const struct cpumask *, const struct cpumask *); 183 262 int __pure cpumask_any_but(const struct cpumask *mask, unsigned int cpu); 263 + 264 + #if NR_CPUS == 1 265 + /* Uniprocessor: there is only one valid CPU */ 266 + static inline unsigned int cpumask_local_spread(unsigned int i, int node) 267 + { 268 + return 0; 269 + } 270 + 271 + static inline int cpumask_any_and_distribute(const struct cpumask *src1p, 272 + const struct cpumask *src2p) { 273 + return cpumask_first_and(src1p, src2p); 274 + } 275 + 276 + static inline int cpumask_any_distribute(const struct cpumask *srcp) 277 + { 278 + return cpumask_first(srcp); 279 + } 280 + #else 184 281 unsigned int cpumask_local_spread(unsigned int i, int node); 185 282 int cpumask_any_and_distribute(const struct cpumask *src1p, 186 283 const struct cpumask *src2p); 187 284 int cpumask_any_distribute(const struct cpumask *srcp); 285 + #endif /* NR_CPUS */ 188 286 189 287 /** 190 288 * for_each_cpu - iterate over every cpu in a mask ··· 229 289 (cpu) = cpumask_next_zero((cpu), (mask)), \ 230 290 (cpu) < nr_cpu_ids;) 231 291 232 - extern int cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool wrap); 292 + int __pure cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool wrap); 233 293 234 294 /** 235 295 * for_each_cpu_wrap - iterate over every cpu in a mask, starting at a specified location ··· 264 324 for ((cpu) = -1; \ 265 325 (cpu) = cpumask_next_and((cpu), (mask1), (mask2)), \ 266 326 (cpu) < nr_cpu_ids;) 267 - #endif /* SMP */ 268 327 269 328 #define CPU_BITS_NONE \ 270 329 { \ ··· 750 811 /* First bits of cpu_bit_bitmap are in fact unset. */ 751 812 #define cpu_none_mask to_cpumask(cpu_bit_bitmap[0]) 752 813 814 + #if NR_CPUS == 1 815 + /* Uniprocessor: the possible/online/present masks are always "1" */ 816 + #define for_each_possible_cpu(cpu) for ((cpu) = 0; (cpu) < 1; (cpu)++) 817 + #define for_each_online_cpu(cpu) for ((cpu) = 0; (cpu) < 1; (cpu)++) 818 + #define for_each_present_cpu(cpu) for ((cpu) = 0; (cpu) < 1; (cpu)++) 819 + #else 753 820 #define for_each_possible_cpu(cpu) for_each_cpu((cpu), cpu_possible_mask) 754 821 #define for_each_online_cpu(cpu) for_each_cpu((cpu), cpu_online_mask) 755 822 #define for_each_present_cpu(cpu) for_each_cpu((cpu), cpu_present_mask) 823 + #endif 756 824 757 825 /* Wrappers for arch boot code to manipulate normally-constant masks */ 758 826 void init_cpu_present(const struct cpumask *src);
+16 -16
include/linux/kernel_read_file.h
··· 35 35 return kernel_read_file_str[id]; 36 36 } 37 37 38 - int kernel_read_file(struct file *file, loff_t offset, 39 - void **buf, size_t buf_size, 40 - size_t *file_size, 41 - enum kernel_read_file_id id); 42 - int kernel_read_file_from_path(const char *path, loff_t offset, 43 - void **buf, size_t buf_size, 44 - size_t *file_size, 45 - enum kernel_read_file_id id); 46 - int kernel_read_file_from_path_initns(const char *path, loff_t offset, 47 - void **buf, size_t buf_size, 48 - size_t *file_size, 49 - enum kernel_read_file_id id); 50 - int kernel_read_file_from_fd(int fd, loff_t offset, 51 - void **buf, size_t buf_size, 52 - size_t *file_size, 53 - enum kernel_read_file_id id); 38 + ssize_t kernel_read_file(struct file *file, loff_t offset, 39 + void **buf, size_t buf_size, 40 + size_t *file_size, 41 + enum kernel_read_file_id id); 42 + ssize_t kernel_read_file_from_path(const char *path, loff_t offset, 43 + void **buf, size_t buf_size, 44 + size_t *file_size, 45 + enum kernel_read_file_id id); 46 + ssize_t kernel_read_file_from_path_initns(const char *path, loff_t offset, 47 + void **buf, size_t buf_size, 48 + size_t *file_size, 49 + enum kernel_read_file_id id); 50 + ssize_t kernel_read_file_from_fd(int fd, loff_t offset, 51 + void **buf, size_t buf_size, 52 + size_t *file_size, 53 + enum kernel_read_file_id id); 54 54 55 55 #endif /* _LINUX_KERNEL_READ_FILE_H */
+1 -1
include/linux/kfifo.h
··· 688 688 * writer, you don't need extra locking to use these macro. 689 689 */ 690 690 #define kfifo_to_user(fifo, to, len, copied) \ 691 - __kfifo_uint_must_check_helper( \ 691 + __kfifo_int_must_check_helper( \ 692 692 ({ \ 693 693 typeof((fifo) + 1) __tmp = (fifo); \ 694 694 void __user *__to = (to); \
+1
include/linux/limits.h
··· 7 7 #include <vdso/limits.h> 8 8 9 9 #define SIZE_MAX (~(size_t)0) 10 + #define SSIZE_MAX ((ssize_t)(SIZE_MAX >> 1)) 10 11 #define PHYS_ADDR_MAX (~(phys_addr_t)0) 11 12 12 13 #define U8_MAX ((u8)~0U)
-2
include/linux/net.h
··· 307 307 308 308 #define net_get_random_once(buf, nbytes) \ 309 309 get_random_once((buf), (nbytes)) 310 - #define net_get_random_once_wait(buf, nbytes) \ 311 - get_random_once_wait((buf), (nbytes)) 312 310 313 311 /* 314 312 * E.g. XFS meta- & log-data is in slab pages, or bcache meta
-2
include/linux/once.h
··· 54 54 55 55 #define get_random_once(buf, nbytes) \ 56 56 DO_ONCE(get_random_bytes, (buf), (nbytes)) 57 - #define get_random_once_wait(buf, nbytes) \ 58 - DO_ONCE(get_random_bytes_wait, (buf), (nbytes)) \ 59 57 60 58 #endif /* _LINUX_ONCE_H */
+1 -1
include/linux/rbtree.h
··· 17 17 #ifndef _LINUX_RBTREE_H 18 18 #define _LINUX_RBTREE_H 19 19 20 + #include <linux/container_of.h> 20 21 #include <linux/rbtree_types.h> 21 22 22 - #include <linux/kernel.h> 23 23 #include <linux/stddef.h> 24 24 #include <linux/rcupdate.h> 25 25
+3 -3
include/uapi/linux/swab.h
··· 102 102 #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x)) 103 103 #else 104 104 #define __swab16(x) \ 105 - (__builtin_constant_p((__u16)(x)) ? \ 105 + (__u16)(__builtin_constant_p(x) ? \ 106 106 ___constant_swab16(x) : \ 107 107 __fswab16(x)) 108 108 #endif ··· 115 115 #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x)) 116 116 #else 117 117 #define __swab32(x) \ 118 - (__builtin_constant_p((__u32)(x)) ? \ 118 + (__u32)(__builtin_constant_p(x) ? \ 119 119 ___constant_swab32(x) : \ 120 120 __fswab32(x)) 121 121 #endif ··· 128 128 #define __swab64(x) (__u64)__builtin_bswap64((__u64)(x)) 129 129 #else 130 130 #define __swab64(x) \ 131 - (__builtin_constant_p((__u64)(x)) ? \ 131 + (__u64)(__builtin_constant_p(x) ? \ 132 132 ___constant_swab64(x) : \ 133 133 __fswab64(x)) 134 134 #endif
+17
init/version.c
··· 11 11 #include <linux/build-salt.h> 12 12 #include <linux/elfnote-lto.h> 13 13 #include <linux/export.h> 14 + #include <linux/init.h> 15 + #include <linux/printk.h> 14 16 #include <linux/uts.h> 15 17 #include <linux/utsname.h> 16 18 #include <generated/utsrelease.h> ··· 36 34 #endif 37 35 }; 38 36 EXPORT_SYMBOL_GPL(init_uts_ns); 37 + 38 + static int __init early_hostname(char *arg) 39 + { 40 + size_t bufsize = sizeof(init_uts_ns.name.nodename); 41 + size_t maxlen = bufsize - 1; 42 + size_t arglen; 43 + 44 + arglen = strlcpy(init_uts_ns.name.nodename, arg, bufsize); 45 + if (arglen > maxlen) { 46 + pr_warn("hostname parameter exceeds %zd characters and will be truncated", 47 + maxlen); 48 + } 49 + return 0; 50 + } 51 + early_param("hostname", early_hostname); 39 52 40 53 /* FIXED STRINGS! Don't touch! */ 41 54 const char linux_banner[] =
+1 -1
ipc/mqueue.c
··· 489 489 490 490 static void init_once(void *foo) 491 491 { 492 - struct mqueue_inode_info *p = (struct mqueue_inode_info *) foo; 492 + struct mqueue_inode_info *p = foo; 493 493 494 494 inode_init_once(&p->vfs_inode); 495 495 }
+26 -2
kernel/crash_core.c
··· 9 9 #include <linux/init.h> 10 10 #include <linux/utsname.h> 11 11 #include <linux/vmalloc.h> 12 + #include <linux/sizes.h> 12 13 13 14 #include <asm/page.h> 14 15 #include <asm/sections.h> 15 16 16 17 #include <crypto/sha1.h> 18 + 19 + #include "kallsyms_internal.h" 17 20 18 21 /* vmcoreinfo stuff */ 19 22 unsigned char *vmcoreinfo_data; ··· 46 43 unsigned long long *crash_base) 47 44 { 48 45 char *cur = cmdline, *tmp; 46 + unsigned long long total_mem = system_ram; 47 + 48 + /* 49 + * Firmware sometimes reserves some memory regions for its own use, 50 + * so the system memory size is less than the actual physical memory 51 + * size. Work around this by rounding up the total size to 128M, 52 + * which is enough for most test cases. 53 + */ 54 + total_mem = roundup(total_mem, SZ_128M); 49 55 50 56 /* for each entry of the comma-separated list */ 51 57 do { ··· 99 87 return -EINVAL; 100 88 } 101 89 cur = tmp; 102 - if (size >= system_ram) { 90 + if (size >= total_mem) { 103 91 pr_warn("crashkernel: invalid size\n"); 104 92 return -EINVAL; 105 93 } 106 94 107 95 /* match ? */ 108 - if (system_ram >= start && system_ram < end) { 96 + if (total_mem >= start && total_mem < end) { 109 97 *crash_size = size; 110 98 break; 111 99 } ··· 491 479 #define PAGE_OFFLINE_MAPCOUNT_VALUE (~PG_offline) 492 480 VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE); 493 481 #endif 482 + 483 + #ifdef CONFIG_KALLSYMS 484 + VMCOREINFO_SYMBOL(kallsyms_names); 485 + VMCOREINFO_SYMBOL(kallsyms_token_table); 486 + VMCOREINFO_SYMBOL(kallsyms_token_index); 487 + #ifdef CONFIG_KALLSYMS_BASE_RELATIVE 488 + VMCOREINFO_SYMBOL(kallsyms_offsets); 489 + VMCOREINFO_SYMBOL(kallsyms_relative_base); 490 + #else 491 + VMCOREINFO_SYMBOL(kallsyms_addresses); 492 + #endif /* CONFIG_KALLSYMS_BASE_RELATIVE */ 493 + #endif /* CONFIG_KALLSYMS */ 494 494 495 495 arch_crash_save_vmcoreinfo(); 496 496 update_vmcoreinfo_note();
+1 -1
kernel/hung_task.c
··· 229 229 * Process updating of timeout sysctl 230 230 */ 231 231 static int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, 232 - void __user *buffer, 232 + void *buffer, 233 233 size_t *lenp, loff_t *ppos) 234 234 { 235 235 int ret;
+1 -22
kernel/kallsyms.c
··· 32 32 #include <linux/bsearch.h> 33 33 #include <linux/btf_ids.h> 34 34 35 - /* 36 - * These will be re-linked against their real values 37 - * during the second link stage. 38 - */ 39 - extern const unsigned long kallsyms_addresses[] __weak; 40 - extern const int kallsyms_offsets[] __weak; 41 - extern const u8 kallsyms_names[] __weak; 42 - 43 - /* 44 - * Tell the compiler that the count isn't in the small data section if the arch 45 - * has one (eg: FRV). 46 - */ 47 - extern const unsigned int kallsyms_num_syms 48 - __section(".rodata") __attribute__((weak)); 49 - 50 - extern const unsigned long kallsyms_relative_base 51 - __section(".rodata") __attribute__((weak)); 52 - 53 - extern const char kallsyms_token_table[] __weak; 54 - extern const u16 kallsyms_token_index[] __weak; 55 - 56 - extern const unsigned int kallsyms_markers[] __weak; 35 + #include "kallsyms_internal.h" 57 36 58 37 /* 59 38 * Expand a compressed symbol data into the resulting uncompressed string,
+30
kernel/kallsyms_internal.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + #ifndef LINUX_KALLSYMS_INTERNAL_H_ 3 + #define LINUX_KALLSYMS_INTERNAL_H_ 4 + 5 + #include <linux/types.h> 6 + 7 + /* 8 + * These will be re-linked against their real values 9 + * during the second link stage. 10 + */ 11 + extern const unsigned long kallsyms_addresses[] __weak; 12 + extern const int kallsyms_offsets[] __weak; 13 + extern const u8 kallsyms_names[] __weak; 14 + 15 + /* 16 + * Tell the compiler that the count isn't in the small data section if the arch 17 + * has one (eg: FRV). 18 + */ 19 + extern const unsigned int kallsyms_num_syms 20 + __section(".rodata") __attribute__((weak)); 21 + 22 + extern const unsigned long kallsyms_relative_base 23 + __section(".rodata") __attribute__((weak)); 24 + 25 + extern const char kallsyms_token_table[] __weak; 26 + extern const u16 kallsyms_token_index[] __weak; 27 + 28 + extern const unsigned int kallsyms_markers[] __weak; 29 + 30 + #endif // LINUX_KALLSYMS_INTERNAL_H_
+7 -3
kernel/kexec_file.c
··· 40 40 41 41 static int kexec_calculate_store_digests(struct kimage *image); 42 42 43 + /* Maximum size in bytes for kernel/initrd files. */ 44 + #define KEXEC_FILE_SIZE_MAX min_t(s64, 4LL << 30, SSIZE_MAX) 45 + 43 46 /* 44 47 * Currently this is the only default function that is exported as some 45 48 * architectures need it to do additional handlings. ··· 193 190 const char __user *cmdline_ptr, 194 191 unsigned long cmdline_len, unsigned flags) 195 192 { 196 - int ret; 193 + ssize_t ret; 197 194 void *ldata; 198 195 199 196 ret = kernel_read_file_from_fd(kernel_fd, 0, &image->kernel_buf, 200 - INT_MAX, NULL, READING_KEXEC_IMAGE); 197 + KEXEC_FILE_SIZE_MAX, NULL, 198 + READING_KEXEC_IMAGE); 201 199 if (ret < 0) 202 200 return ret; 203 201 image->kernel_buf_len = ret; ··· 218 214 /* It is possible that there no initramfs is being loaded */ 219 215 if (!(flags & KEXEC_FILE_NO_INITRAMFS)) { 220 216 ret = kernel_read_file_from_fd(initrd_fd, 0, &image->initrd_buf, 221 - INT_MAX, NULL, 217 + KEXEC_FILE_SIZE_MAX, NULL, 222 218 READING_KEXEC_INITRAMFS); 223 219 if (ret < 0) 224 220 goto out;
+13 -2
kernel/profile.c
··· 109 109 110 110 /* only text is profiled */ 111 111 prof_len = (_etext - _stext) >> prof_shift; 112 + 113 + if (!prof_len) { 114 + pr_warn("profiling shift: %u too large\n", prof_shift); 115 + prof_on = 0; 116 + return -EINVAL; 117 + } 118 + 112 119 buffer_bytes = prof_len*sizeof(atomic_t); 113 120 114 121 if (!alloc_cpumask_var(&prof_cpu_mask, GFP_KERNEL)) ··· 425 418 return read; 426 419 } 427 420 421 + /* default is to not implement this call */ 422 + int __weak setup_profiling_timer(unsigned mult) 423 + { 424 + return -EINVAL; 425 + } 426 + 428 427 /* 429 428 * Writing to /proc/profile resets the counters 430 429 * ··· 441 428 size_t count, loff_t *ppos) 442 429 { 443 430 #ifdef CONFIG_SMP 444 - extern int setup_profiling_timer(unsigned int multiplier); 445 - 446 431 if (count == sizeof(int)) { 447 432 unsigned int multiplier; 448 433
-9
lib/Kconfig
··· 692 692 bool 693 693 select STACKDEPOT 694 694 695 - config STACK_HASH_ORDER 696 - int "stack depot hash size (12 => 4KB, 20 => 1024KB)" 697 - range 12 20 698 - default 20 699 - depends on STACKDEPOT 700 - help 701 - Select the hash size as a power of 2 for the stackdepot hash table. 702 - Choose a lower value to reduce the memory impact. 703 - 704 695 config REF_TRACKER 705 696 bool 706 697 depends on STACKTRACE_SUPPORT
+9
lib/Kconfig.debug
··· 2029 2029 Documentation on how to use the module can be found in 2030 2030 Documentation/fault-injection/provoke-crashes.rst 2031 2031 2032 + config TEST_CPUMASK 2033 + tristate "cpumask tests" if !KUNIT_ALL_TESTS 2034 + depends on KUNIT 2035 + default KUNIT_ALL_TESTS 2036 + help 2037 + Enable to turn on cpumask tests, running at boot or module load time. 2038 + 2039 + If unsure, say N. 2040 + 2032 2041 config TEST_LIST_SORT 2033 2042 tristate "Linked list sorting test" if !KUNIT_ALL_TESTS 2034 2043 depends on KUNIT
+2 -2
lib/Makefile
··· 34 34 is_single_threaded.o plist.o decompress.o kobject_uevent.o \ 35 35 earlycpio.o seq_buf.o siphash.o dec_and_lock.o \ 36 36 nmi_backtrace.o nodemask.o win_minmax.o memcat_p.o \ 37 - buildid.o 37 + buildid.o cpumask.o 38 38 39 39 lib-$(CONFIG_PRINTK) += dump_stack.o 40 - lib-$(CONFIG_SMP) += cpumask.o 41 40 42 41 lib-y += kobject.o klist.o 43 42 obj-y += lockref.o ··· 99 100 obj-$(CONFIG_TEST_FREE_PAGES) += test_free_pages.o 100 101 obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o 101 102 obj-$(CONFIG_TEST_REF_TRACKER) += test_ref_tracker.o 103 + obj-$(CONFIG_TEST_CPUMASK) += test_cpumask.o 102 104 CFLAGS_test_fprobe.o += $(CC_FLAGS_FTRACE) 103 105 obj-$(CONFIG_FPROBE_SANITY_TEST) += test_fprobe.o 104 106 #
+13 -17
lib/btree.c
··· 238 238 return 1; 239 239 } 240 240 241 - void *btree_lookup(struct btree_head *head, struct btree_geo *geo, 241 + static void *btree_lookup_node(struct btree_head *head, struct btree_geo *geo, 242 242 unsigned long *key) 243 243 { 244 244 int i, height = head->height; ··· 257 257 if (!node) 258 258 return NULL; 259 259 } 260 + return node; 261 + } 260 262 263 + void *btree_lookup(struct btree_head *head, struct btree_geo *geo, 264 + unsigned long *key) 265 + { 266 + int i; 267 + unsigned long *node; 268 + 269 + node = btree_lookup_node(head, geo, key); 261 270 if (!node) 262 271 return NULL; 263 272 ··· 280 271 int btree_update(struct btree_head *head, struct btree_geo *geo, 281 272 unsigned long *key, void *val) 282 273 { 283 - int i, height = head->height; 284 - unsigned long *node = head->node; 274 + int i; 275 + unsigned long *node; 285 276 286 - if (height == 0) 287 - return -ENOENT; 288 - 289 - for ( ; height > 1; height--) { 290 - for (i = 0; i < geo->no_pairs; i++) 291 - if (keycmp(geo, node, i, key) <= 0) 292 - break; 293 - if (i == geo->no_pairs) 294 - return -ENOENT; 295 - node = bval(geo, node, i); 296 - if (!node) 297 - return -ENOENT; 298 - } 299 - 277 + node = btree_lookup_node(head, geo, key); 300 278 if (!node) 301 279 return -ENOENT; 302 280
+2
lib/cpumask.c
··· 192 192 } 193 193 #endif 194 194 195 + #if NR_CPUS > 1 195 196 /** 196 197 * cpumask_local_spread - select the i'th cpu with local numa cpu's first 197 198 * @i: index number ··· 280 279 return next; 281 280 } 282 281 EXPORT_SYMBOL(cpumask_any_distribute); 282 + #endif /* NR_CPUS */
+10 -5
lib/devres.c
··· 29 29 { 30 30 void __iomem **ptr, *addr = NULL; 31 31 32 - ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); 32 + ptr = devres_alloc_node(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL, 33 + dev_to_node(dev)); 33 34 if (!ptr) 34 35 return NULL; 35 36 ··· 293 292 { 294 293 void __iomem **ptr, *addr; 295 294 296 - ptr = devres_alloc(devm_ioport_map_release, sizeof(*ptr), GFP_KERNEL); 295 + ptr = devres_alloc_node(devm_ioport_map_release, sizeof(*ptr), GFP_KERNEL, 296 + dev_to_node(dev)); 297 297 if (!ptr) 298 298 return NULL; 299 299 ··· 368 366 if (dr) 369 367 return dr->table; 370 368 371 - new_dr = devres_alloc(pcim_iomap_release, sizeof(*new_dr), GFP_KERNEL); 369 + new_dr = devres_alloc_node(pcim_iomap_release, sizeof(*new_dr), GFP_KERNEL, 370 + dev_to_node(&pdev->dev)); 372 371 if (!new_dr) 373 372 return NULL; 374 373 dr = devres_get(&pdev->dev, new_dr, NULL, NULL); ··· 551 548 int *mtrr; 552 549 int ret; 553 550 554 - mtrr = devres_alloc(devm_arch_phys_ac_add_release, sizeof(*mtrr), GFP_KERNEL); 551 + mtrr = devres_alloc_node(devm_arch_phys_ac_add_release, sizeof(*mtrr), GFP_KERNEL, 552 + dev_to_node(dev)); 555 553 if (!mtrr) 556 554 return -ENOMEM; 557 555 ··· 597 593 struct arch_io_reserve_memtype_wc_devres *dr; 598 594 int ret; 599 595 600 - dr = devres_alloc(devm_arch_io_free_memtype_wc_release, sizeof(*dr), GFP_KERNEL); 596 + dr = devres_alloc_node(devm_arch_io_free_memtype_wc_release, sizeof(*dr), GFP_KERNEL, 597 + dev_to_node(dev)); 601 598 if (!dr) 602 599 return -ENOMEM; 603 600
+12 -16
lib/error-inject.c
··· 40 40 int get_injectable_error_type(unsigned long addr) 41 41 { 42 42 struct ei_entry *ent; 43 + int ei_type = EI_ETYPE_NONE; 43 44 45 + mutex_lock(&ei_mutex); 44 46 list_for_each_entry(ent, &error_injection_list, list) { 45 - if (addr >= ent->start_addr && addr < ent->end_addr) 46 - return ent->etype; 47 + if (addr >= ent->start_addr && addr < ent->end_addr) { 48 + ei_type = ent->etype; 49 + break; 50 + } 47 51 } 48 - return EI_ETYPE_NONE; 52 + mutex_unlock(&ei_mutex); 53 + 54 + return ei_type; 49 55 } 50 56 51 57 /* ··· 203 197 return 0; 204 198 } 205 199 206 - static const struct seq_operations ei_seq_ops = { 200 + static const struct seq_operations ei_sops = { 207 201 .start = ei_seq_start, 208 202 .next = ei_seq_next, 209 203 .stop = ei_seq_stop, 210 204 .show = ei_seq_show, 211 205 }; 212 206 213 - static int ei_open(struct inode *inode, struct file *filp) 214 - { 215 - return seq_open(filp, &ei_seq_ops); 216 - } 217 - 218 - static const struct file_operations debugfs_ei_ops = { 219 - .open = ei_open, 220 - .read = seq_read, 221 - .llseek = seq_lseek, 222 - .release = seq_release, 223 - }; 207 + DEFINE_SEQ_ATTRIBUTE(ei); 224 208 225 209 static int __init ei_debugfs_init(void) 226 210 { ··· 220 224 if (!dir) 221 225 return -ENOMEM; 222 226 223 - file = debugfs_create_file("list", 0444, dir, NULL, &debugfs_ei_ops); 227 + file = debugfs_create_file("list", 0444, dir, NULL, &ei_fops); 224 228 if (!file) { 225 229 debugfs_remove(dir); 226 230 return -ENOMEM;
+2 -8
lib/flex_proportions.c
··· 63 63 */ 64 64 bool fprop_new_period(struct fprop_global *p, int periods) 65 65 { 66 - s64 events; 67 - unsigned long flags; 66 + s64 events = percpu_counter_sum(&p->events); 68 67 69 - local_irq_save(flags); 70 - events = percpu_counter_sum(&p->events); 71 68 /* 72 69 * Don't do anything if there are no events. 73 70 */ 74 - if (events <= 1) { 75 - local_irq_restore(flags); 71 + if (events <= 1) 76 72 return false; 77 - } 78 73 write_seqcount_begin(&p->sequence); 79 74 if (periods < 64) 80 75 events -= events >> periods; ··· 77 82 percpu_counter_add(&p->events, -events); 78 83 p->period += periods; 79 84 write_seqcount_end(&p->sequence); 80 - local_irq_restore(flags); 81 85 82 86 return true; 83 87 }
+10 -2
lib/list_debug.c
··· 20 20 bool __list_add_valid(struct list_head *new, struct list_head *prev, 21 21 struct list_head *next) 22 22 { 23 - if (CHECK_DATA_CORRUPTION(next->prev != prev, 23 + if (CHECK_DATA_CORRUPTION(prev == NULL, 24 + "list_add corruption. prev is NULL.\n") || 25 + CHECK_DATA_CORRUPTION(next == NULL, 26 + "list_add corruption. next is NULL.\n") || 27 + CHECK_DATA_CORRUPTION(next->prev != prev, 24 28 "list_add corruption. next->prev should be prev (%px), but was %px. (next=%px).\n", 25 29 prev, next->prev, next) || 26 30 CHECK_DATA_CORRUPTION(prev->next != next, ··· 46 42 prev = entry->prev; 47 43 next = entry->next; 48 44 49 - if (CHECK_DATA_CORRUPTION(next == LIST_POISON1, 45 + if (CHECK_DATA_CORRUPTION(next == NULL, 46 + "list_del corruption, %px->next is NULL\n", entry) || 47 + CHECK_DATA_CORRUPTION(prev == NULL, 48 + "list_del corruption, %px->prev is NULL\n", entry) || 49 + CHECK_DATA_CORRUPTION(next == LIST_POISON1, 50 50 "list_del corruption, %px->next is LIST_POISON1 (%px)\n", 51 51 entry, LIST_POISON1) || 52 52 CHECK_DATA_CORRUPTION(prev == LIST_POISON2,
+2 -2
lib/lru_cache.c
··· 147 147 return lc; 148 148 149 149 /* else: could not allocate all elements, give up */ 150 - for (i--; i; i--) { 151 - void *p = element[i]; 150 + while (i) { 151 + void *p = element[--i]; 152 152 kmem_cache_free(cache, p - e_off); 153 153 } 154 154 kfree(lc);
+3 -3
lib/lz4/lz4_decompress.c
··· 507 507 (BYTE *)dest - prefixSize, NULL, 0); 508 508 } 509 509 510 - int LZ4_decompress_safe_forceExtDict(const char *source, char *dest, 511 - int compressedSize, int maxOutputSize, 512 - const void *dictStart, size_t dictSize) 510 + static int LZ4_decompress_safe_forceExtDict(const char *source, char *dest, 511 + int compressedSize, int maxOutputSize, 512 + const void *dictStart, size_t dictSize) 513 513 { 514 514 return LZ4_decompress_generic(source, dest, 515 515 compressedSize, maxOutputSize,
+2 -4
lib/lzo/lzo1x_compress.c
··· 50 50 51 51 if (dv == 0 && bitstream_version) { 52 52 const unsigned char *ir = ip + 4; 53 - const unsigned char *limit = ip_end 54 - < (ip + MAX_ZERO_RUN_LENGTH + 1) 55 - ? ip_end : ip + MAX_ZERO_RUN_LENGTH + 1; 53 + const unsigned char *limit = min(ip_end, ip + MAX_ZERO_RUN_LENGTH + 1); 56 54 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && \ 57 55 defined(LZO_FAST_64BIT_MEMORY_ACCESS) 58 56 u64 dv64; ··· 324 326 data_start = op; 325 327 326 328 while (l > 20) { 327 - size_t ll = l <= (m4_max_offset + 1) ? l : (m4_max_offset + 1); 329 + size_t ll = min_t(size_t, l, m4_max_offset + 1); 328 330 uintptr_t ll_end = (uintptr_t) ip + ll; 329 331 if ((ll_end + ((t + ll) >> 5)) <= ll_end) 330 332 break;
+1 -1
lib/mpi/mpiutil.c
··· 272 272 if (!w) 273 273 w = mpi_alloc(1); 274 274 /* FIXME: If U is 0 we have no need to resize and thus possible 275 - * allocating the the limbs. 275 + * allocating the limbs. 276 276 */ 277 277 RESIZE_IF_NEEDED(w, 1); 278 278 w->d[0] = u;
+2 -2
lib/radix-tree.c
··· 677 677 } 678 678 679 679 static inline int insert_entries(struct radix_tree_node *node, 680 - void __rcu **slot, void *item, bool replace) 680 + void __rcu **slot, void *item) 681 681 { 682 682 if (*slot) 683 683 return -EEXIST; ··· 711 711 if (error) 712 712 return error; 713 713 714 - error = insert_entries(node, slot, item, false); 714 + error = insert_entries(node, slot, item); 715 715 if (error < 0) 716 716 return error; 717 717
+2 -2
lib/scatterlist.c
··· 240 240 **/ 241 241 void sg_free_append_table(struct sg_append_table *table) 242 242 { 243 - __sg_free_table(&table->sgt, SG_MAX_SINGLE_ALLOC, false, sg_kfree, 243 + __sg_free_table(&table->sgt, SG_MAX_SINGLE_ALLOC, 0, sg_kfree, 244 244 table->total_nents); 245 245 } 246 246 EXPORT_SYMBOL(sg_free_append_table); ··· 253 253 **/ 254 254 void sg_free_table(struct sg_table *table) 255 255 { 256 - __sg_free_table(table, SG_MAX_SINGLE_ALLOC, false, sg_kfree, 256 + __sg_free_table(table, SG_MAX_SINGLE_ALLOC, 0, sg_kfree, 257 257 table->orig_nents); 258 258 } 259 259 EXPORT_SYMBOL(sg_free_table);
+1 -1
lib/smp_processor_id.c
··· 47 47 48 48 printk("caller is %pS\n", __builtin_return_address(0)); 49 49 dump_stack(); 50 - instrumentation_end(); 51 50 52 51 out_enable: 52 + instrumentation_end(); 53 53 preempt_enable_no_resched_notrace(); 54 54 out: 55 55 return this_cpu;
+49 -10
lib/stackdepot.c
··· 32 32 #include <linux/string.h> 33 33 #include <linux/types.h> 34 34 #include <linux/memblock.h> 35 + #include <linux/kasan-enabled.h> 35 36 36 37 #define DEPOT_STACK_BITS (sizeof(depot_stack_handle_t) * 8) 37 38 ··· 146 145 return stack; 147 146 } 148 147 149 - #define STACK_HASH_SIZE (1L << CONFIG_STACK_HASH_ORDER) 150 - #define STACK_HASH_MASK (STACK_HASH_SIZE - 1) 148 + /* one hash table bucket entry per 16kB of memory */ 149 + #define STACK_HASH_SCALE 14 150 + /* limited between 4k and 1M buckets */ 151 + #define STACK_HASH_ORDER_MIN 12 152 + #define STACK_HASH_ORDER_MAX 20 151 153 #define STACK_HASH_SEED 0x9747b28c 154 + 155 + static unsigned int stack_hash_order; 156 + static unsigned int stack_hash_mask; 152 157 153 158 static bool stack_depot_disable; 154 159 static struct stack_record **stack_table; ··· 182 175 183 176 int __init stack_depot_early_init(void) 184 177 { 185 - size_t size; 178 + unsigned long entries = 0; 186 179 187 180 /* This is supposed to be called only once, from mm_init() */ 188 181 if (WARN_ON(__stack_depot_early_init_passed)) ··· 190 183 191 184 __stack_depot_early_init_passed = true; 192 185 186 + if (kasan_enabled() && !stack_hash_order) 187 + stack_hash_order = STACK_HASH_ORDER_MAX; 188 + 193 189 if (!__stack_depot_want_early_init || stack_depot_disable) 194 190 return 0; 195 191 196 - size = (STACK_HASH_SIZE * sizeof(struct stack_record *)); 197 - pr_info("Stack Depot early init allocating hash table with memblock_alloc, %zu bytes\n", 198 - size); 199 - stack_table = memblock_alloc(size, SMP_CACHE_BYTES); 192 + if (stack_hash_order) 193 + entries = 1UL << stack_hash_order; 194 + stack_table = alloc_large_system_hash("stackdepot", 195 + sizeof(struct stack_record *), 196 + entries, 197 + STACK_HASH_SCALE, 198 + HASH_EARLY | HASH_ZERO, 199 + NULL, 200 + &stack_hash_mask, 201 + 1UL << STACK_HASH_ORDER_MIN, 202 + 1UL << STACK_HASH_ORDER_MAX); 200 203 201 204 if (!stack_table) { 202 205 pr_err("Stack Depot hash table allocation failed, disabling\n"); ··· 224 207 225 208 mutex_lock(&stack_depot_init_mutex); 226 209 if (!stack_depot_disable && !stack_table) { 227 - pr_info("Stack Depot allocating hash table with kvcalloc\n"); 228 - stack_table = kvcalloc(STACK_HASH_SIZE, sizeof(struct stack_record *), GFP_KERNEL); 210 + unsigned long entries; 211 + int scale = STACK_HASH_SCALE; 212 + 213 + if (stack_hash_order) { 214 + entries = 1UL << stack_hash_order; 215 + } else { 216 + entries = nr_free_buffer_pages(); 217 + entries = roundup_pow_of_two(entries); 218 + 219 + if (scale > PAGE_SHIFT) 220 + entries >>= (scale - PAGE_SHIFT); 221 + else 222 + entries <<= (PAGE_SHIFT - scale); 223 + } 224 + 225 + if (entries < 1UL << STACK_HASH_ORDER_MIN) 226 + entries = 1UL << STACK_HASH_ORDER_MIN; 227 + if (entries > 1UL << STACK_HASH_ORDER_MAX) 228 + entries = 1UL << STACK_HASH_ORDER_MAX; 229 + 230 + pr_info("Stack Depot allocating hash table of %lu entries with kvcalloc\n", 231 + entries); 232 + stack_table = kvcalloc(entries, sizeof(struct stack_record *), GFP_KERNEL); 229 233 if (!stack_table) { 230 234 pr_err("Stack Depot hash table allocation failed, disabling\n"); 231 235 stack_depot_disable = true; 232 236 ret = -ENOMEM; 233 237 } 238 + stack_hash_mask = entries - 1; 234 239 } 235 240 mutex_unlock(&stack_depot_init_mutex); 236 241 return ret; ··· 425 386 goto fast_exit; 426 387 427 388 hash = hash_stack(entries, nr_entries); 428 - bucket = &stack_table[hash & STACK_HASH_MASK]; 389 + bucket = &stack_table[hash & stack_hash_mask]; 429 390 430 391 /* 431 392 * Fast path: look the stack trace up without locking.
+138
lib/test_cpumask.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * KUnit tests for cpumask. 4 + * 5 + * Author: Sander Vanheule <sander@svanheule.net> 6 + */ 7 + 8 + #include <kunit/test.h> 9 + #include <linux/cpu.h> 10 + #include <linux/cpumask.h> 11 + 12 + #define EXPECT_FOR_EACH_CPU_EQ(test, mask) \ 13 + do { \ 14 + const cpumask_t *m = (mask); \ 15 + int mask_weight = cpumask_weight(m); \ 16 + int cpu, iter = 0; \ 17 + for_each_cpu(cpu, m) \ 18 + iter++; \ 19 + KUNIT_EXPECT_EQ((test), mask_weight, iter); \ 20 + } while (0) 21 + 22 + #define EXPECT_FOR_EACH_CPU_NOT_EQ(test, mask) \ 23 + do { \ 24 + const cpumask_t *m = (mask); \ 25 + int mask_weight = cpumask_weight(m); \ 26 + int cpu, iter = 0; \ 27 + for_each_cpu_not(cpu, m) \ 28 + iter++; \ 29 + KUNIT_EXPECT_EQ((test), nr_cpu_ids - mask_weight, iter); \ 30 + } while (0) 31 + 32 + #define EXPECT_FOR_EACH_CPU_WRAP_EQ(test, mask) \ 33 + do { \ 34 + const cpumask_t *m = (mask); \ 35 + int mask_weight = cpumask_weight(m); \ 36 + int cpu, iter = 0; \ 37 + for_each_cpu_wrap(cpu, m, nr_cpu_ids / 2) \ 38 + iter++; \ 39 + KUNIT_EXPECT_EQ((test), mask_weight, iter); \ 40 + } while (0) 41 + 42 + #define EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, name) \ 43 + do { \ 44 + int mask_weight = num_##name##_cpus(); \ 45 + int cpu, iter = 0; \ 46 + for_each_##name##_cpu(cpu) \ 47 + iter++; \ 48 + KUNIT_EXPECT_EQ((test), mask_weight, iter); \ 49 + } while (0) 50 + 51 + static cpumask_t mask_empty; 52 + static cpumask_t mask_all; 53 + 54 + static void test_cpumask_weight(struct kunit *test) 55 + { 56 + KUNIT_EXPECT_TRUE(test, cpumask_empty(&mask_empty)); 57 + KUNIT_EXPECT_TRUE(test, cpumask_full(cpu_possible_mask)); 58 + KUNIT_EXPECT_TRUE(test, cpumask_full(&mask_all)); 59 + 60 + KUNIT_EXPECT_EQ(test, 0, cpumask_weight(&mask_empty)); 61 + KUNIT_EXPECT_EQ(test, nr_cpu_ids, cpumask_weight(cpu_possible_mask)); 62 + KUNIT_EXPECT_EQ(test, nr_cpumask_bits, cpumask_weight(&mask_all)); 63 + } 64 + 65 + static void test_cpumask_first(struct kunit *test) 66 + { 67 + KUNIT_EXPECT_LE(test, nr_cpu_ids, cpumask_first(&mask_empty)); 68 + KUNIT_EXPECT_EQ(test, 0, cpumask_first(cpu_possible_mask)); 69 + 70 + KUNIT_EXPECT_EQ(test, 0, cpumask_first_zero(&mask_empty)); 71 + KUNIT_EXPECT_LE(test, nr_cpu_ids, cpumask_first_zero(cpu_possible_mask)); 72 + } 73 + 74 + static void test_cpumask_last(struct kunit *test) 75 + { 76 + KUNIT_EXPECT_LE(test, nr_cpumask_bits, cpumask_last(&mask_empty)); 77 + KUNIT_EXPECT_EQ(test, nr_cpumask_bits - 1, cpumask_last(cpu_possible_mask)); 78 + } 79 + 80 + static void test_cpumask_next(struct kunit *test) 81 + { 82 + KUNIT_EXPECT_EQ(test, 0, cpumask_next_zero(-1, &mask_empty)); 83 + KUNIT_EXPECT_LE(test, nr_cpu_ids, cpumask_next_zero(-1, cpu_possible_mask)); 84 + 85 + KUNIT_EXPECT_LE(test, nr_cpu_ids, cpumask_next(-1, &mask_empty)); 86 + KUNIT_EXPECT_EQ(test, 0, cpumask_next(-1, cpu_possible_mask)); 87 + } 88 + 89 + static void test_cpumask_iterators(struct kunit *test) 90 + { 91 + EXPECT_FOR_EACH_CPU_EQ(test, &mask_empty); 92 + EXPECT_FOR_EACH_CPU_NOT_EQ(test, &mask_empty); 93 + EXPECT_FOR_EACH_CPU_WRAP_EQ(test, &mask_empty); 94 + 95 + EXPECT_FOR_EACH_CPU_EQ(test, cpu_possible_mask); 96 + EXPECT_FOR_EACH_CPU_NOT_EQ(test, cpu_possible_mask); 97 + EXPECT_FOR_EACH_CPU_WRAP_EQ(test, cpu_possible_mask); 98 + } 99 + 100 + static void test_cpumask_iterators_builtin(struct kunit *test) 101 + { 102 + EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, possible); 103 + 104 + /* Ensure the dynamic masks are stable while running the tests */ 105 + cpu_hotplug_disable(); 106 + 107 + EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, online); 108 + EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, present); 109 + 110 + cpu_hotplug_enable(); 111 + } 112 + 113 + static int test_cpumask_init(struct kunit *test) 114 + { 115 + cpumask_clear(&mask_empty); 116 + cpumask_setall(&mask_all); 117 + 118 + return 0; 119 + } 120 + 121 + static struct kunit_case test_cpumask_cases[] = { 122 + KUNIT_CASE(test_cpumask_weight), 123 + KUNIT_CASE(test_cpumask_first), 124 + KUNIT_CASE(test_cpumask_last), 125 + KUNIT_CASE(test_cpumask_next), 126 + KUNIT_CASE(test_cpumask_iterators), 127 + KUNIT_CASE(test_cpumask_iterators_builtin), 128 + {} 129 + }; 130 + 131 + static struct kunit_suite test_cpumask_suite = { 132 + .name = "cpumask", 133 + .init = test_cpumask_init, 134 + .test_cases = test_cpumask_cases, 135 + }; 136 + kunit_test_suite(test_cpumask_suite); 137 + 138 + MODULE_LICENSE("GPL");
+1 -1
lib/ts_bm.c
··· 80 80 81 81 /* London calling... */ 82 82 DEBUGP("found!\n"); 83 - return consumed += (shift-(bm->patlen-1)); 83 + return consumed + (shift-(bm->patlen-1)); 84 84 85 85 next: bs = bm->bad_shift[text[shift-i]]; 86 86
+27 -20
scripts/bloat-o-meter
··· 7 7 # This software may be used and distributed according to the terms 8 8 # of the GNU General Public License, incorporated herein by reference. 9 9 10 - import sys, os, re 10 + import sys, os, re, argparse 11 11 from signal import signal, SIGPIPE, SIG_DFL 12 12 13 13 signal(SIGPIPE, SIG_DFL) 14 14 15 - if len(sys.argv) < 3: 16 - sys.stderr.write("usage: %s [option] file1 file2\n" % sys.argv[0]) 17 - sys.stderr.write("The options are:\n") 18 - sys.stderr.write("-c categorize output based on symbol type\n") 19 - sys.stderr.write("-d Show delta of Data Section\n") 20 - sys.stderr.write("-t Show delta of text Section\n") 21 - sys.exit(-1) 15 + parser = argparse.ArgumentParser(description="Simple script used to compare the symbol sizes of 2 object files") 16 + group = parser.add_mutually_exclusive_group() 17 + group.add_argument('-c', help='categorize output based on symbol type', action='store_true') 18 + group.add_argument('-d', help='Show delta of Data Section', action='store_true') 19 + group.add_argument('-t', help='Show delta of text Section', action='store_true') 20 + parser.add_argument('-p', dest='prefix', help='Arch prefix for the tool being used. Useful in cross build scenarios') 21 + parser.add_argument('file1', help='First file to compare') 22 + parser.add_argument('file2', help='Second file to compare') 23 + 24 + args = parser.parse_args() 22 25 23 26 re_NUMBER = re.compile(r'\.[0-9]+') 24 27 25 28 def getsizes(file, format): 26 29 sym = {} 27 - with os.popen("nm --size-sort " + file) as f: 30 + nm = "nm" 31 + if args.prefix: 32 + nm = "{}nm".format(args.prefix) 33 + 34 + with os.popen("{} --size-sort {}".format(nm, file)) as f: 28 35 for line in f: 29 36 if line.startswith("\n") or ":" in line: 30 37 continue ··· 84 77 delta.reverse() 85 78 return grow, shrink, add, remove, up, down, delta, old, new, otot, ntot 86 79 87 - def print_result(symboltype, symbolformat, argc): 80 + def print_result(symboltype, symbolformat): 88 81 grow, shrink, add, remove, up, down, delta, old, new, otot, ntot = \ 89 - calc(sys.argv[argc - 1], sys.argv[argc], symbolformat) 82 + calc(args.file1, args.file2, symbolformat) 90 83 91 84 print("add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \ 92 85 (add, remove, grow, shrink, up, -down, up-down)) ··· 100 93 percent = 0 101 94 print("Total: Before=%d, After=%d, chg %+.2f%%" % (otot, ntot, percent)) 102 95 103 - if sys.argv[1] == "-c": 104 - print_result("Function", "tT", 3) 105 - print_result("Data", "dDbB", 3) 106 - print_result("RO Data", "rR", 3) 107 - elif sys.argv[1] == "-d": 108 - print_result("Data", "dDbBrR", 3) 109 - elif sys.argv[1] == "-t": 110 - print_result("Function", "tT", 3) 96 + if args.c: 97 + print_result("Function", "tT") 98 + print_result("Data", "dDbB") 99 + print_result("RO Data", "rR") 100 + elif args.d: 101 + print_result("Data", "dDbBrR") 102 + elif args.t: 103 + print_result("Function", "tT") 111 104 else: 112 - print_result("Function", "tTdDbBrR", 2) 105 + print_result("Function", "tTdDbBrR")
+3 -2
scripts/checkpatch.pl
··· 1042 1042 our $declaration_macros = qr{(?x: 1043 1043 (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| 1044 1044 (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| 1045 - (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( 1045 + (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(| 1046 + (?:$Storage\s+)?(?:XA_STATE|XA_STATE_ORDER)\s*\( 1046 1047 )}; 1047 1048 1048 1049 our %allow_repeated_words = ( ··· 5721 5720 $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ && 5722 5721 #Ignore some three character SI units explicitly, like MiB and KHz 5723 5722 $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 5724 - while ($var =~ m{($Ident)}g) { 5723 + while ($var =~ m{\b($Ident)}g) { 5725 5724 my $word = $1; 5726 5725 next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 5727 5726 if ($check) {
+1 -1
scripts/gdb/vmlinux-gdb.py
··· 13 13 14 14 import os 15 15 16 - sys.path.insert(0, os.path.dirname(__file__) + "/scripts/gdb") 16 + sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + "/scripts/gdb") 17 17 18 18 try: 19 19 gdb.parse_and_eval("0")
-4
tools/accounting/getdelays.c
··· 45 45 exit(code); \ 46 46 } while (0) 47 47 48 - int done; 49 48 int rcvbufsz; 50 49 char name[100]; 51 50 int dbg; ··· 284 285 pid_t rtid = 0; 285 286 286 287 int fd = 0; 287 - int count = 0; 288 288 int write_file = 0; 289 289 int maskset = 0; 290 290 char *logfile = NULL; ··· 493 495 len2 = 0; 494 496 /* For nested attributes, na follows */ 495 497 na = (struct nlattr *) NLA_DATA(na); 496 - done = 0; 497 498 while (len2 < aggr_len) { 498 499 switch (na->nla_type) { 499 500 case TASKSTATS_TYPE_PID: ··· 506 509 printf("TGID\t%d\n", rtid); 507 510 break; 508 511 case TASKSTATS_TYPE_STATS: 509 - count++; 510 512 if (print_delays) 511 513 print_delayacct((struct taskstats *) NLA_DATA(na)); 512 514 if (print_io_accounting)
+1
tools/testing/selftests/Makefile
··· 17 17 TARGETS += filesystems 18 18 TARGETS += filesystems/binderfs 19 19 TARGETS += filesystems/epoll 20 + TARGETS += filesystems/fat 20 21 TARGETS += firmware 21 22 TARGETS += fpu 22 23 TARGETS += ftrace
+2
tools/testing/selftests/filesystems/fat/.gitignore
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + rename_exchange
+7
tools/testing/selftests/filesystems/fat/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + TEST_PROGS := run_fat_tests.sh 4 + TEST_GEN_PROGS_EXTENDED := rename_exchange 5 + CFLAGS += -O2 -g -Wall $(KHDR_INCLUDES) 6 + 7 + include ../../lib.mk
+2
tools/testing/selftests/filesystems/fat/config
··· 1 + CONFIG_BLK_DEV_LOOP=y 2 + CONFIG_VFAT_FS=y
+37
tools/testing/selftests/filesystems/fat/rename_exchange.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Program that atomically exchanges two paths using 4 + * the renameat2() system call RENAME_EXCHANGE flag. 5 + * 6 + * Copyright 2022 Red Hat Inc. 7 + * Author: Javier Martinez Canillas <javierm@redhat.com> 8 + */ 9 + 10 + #define _GNU_SOURCE 11 + #include <fcntl.h> 12 + #include <stdio.h> 13 + #include <stdlib.h> 14 + 15 + void print_usage(const char *program) 16 + { 17 + printf("Usage: %s [oldpath] [newpath]\n", program); 18 + printf("Atomically exchange oldpath and newpath\n"); 19 + } 20 + 21 + int main(int argc, char *argv[]) 22 + { 23 + int ret; 24 + 25 + if (argc != 3) { 26 + print_usage(argv[0]); 27 + exit(EXIT_FAILURE); 28 + } 29 + 30 + ret = renameat2(AT_FDCWD, argv[1], AT_FDCWD, argv[2], RENAME_EXCHANGE); 31 + if (ret) { 32 + perror("rename exchange failed"); 33 + exit(EXIT_FAILURE); 34 + } 35 + 36 + exit(EXIT_SUCCESS); 37 + }
+82
tools/testing/selftests/filesystems/fat/run_fat_tests.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + # 4 + # Run filesystem operations tests on an 1 MiB disk image that is formatted with 5 + # a vfat filesystem and mounted in a temporary directory using a loop device. 6 + # 7 + # Copyright 2022 Red Hat Inc. 8 + # Author: Javier Martinez Canillas <javierm@redhat.com> 9 + 10 + set -e 11 + set -u 12 + set -o pipefail 13 + 14 + BASE_DIR="$(dirname $0)" 15 + TMP_DIR="$(mktemp -d /tmp/fat_tests_tmp.XXXX)" 16 + IMG_PATH="${TMP_DIR}/fat.img" 17 + MNT_PATH="${TMP_DIR}/mnt" 18 + 19 + cleanup() 20 + { 21 + mountpoint -q "${MNT_PATH}" && unmount_image 22 + rm -rf "${TMP_DIR}" 23 + } 24 + trap cleanup SIGINT SIGTERM EXIT 25 + 26 + create_loopback() 27 + { 28 + touch "${IMG_PATH}" 29 + chattr +C "${IMG_PATH}" >/dev/null 2>&1 || true 30 + 31 + truncate -s 1M "${IMG_PATH}" 32 + mkfs.vfat "${IMG_PATH}" >/dev/null 2>&1 33 + } 34 + 35 + mount_image() 36 + { 37 + mkdir -p "${MNT_PATH}" 38 + sudo mount -o loop "${IMG_PATH}" "${MNT_PATH}" 39 + } 40 + 41 + rename_exchange_test() 42 + { 43 + local rename_exchange="${BASE_DIR}/rename_exchange" 44 + local old_path="${MNT_PATH}/old_file" 45 + local new_path="${MNT_PATH}/new_file" 46 + 47 + echo old | sudo tee "${old_path}" >/dev/null 2>&1 48 + echo new | sudo tee "${new_path}" >/dev/null 2>&1 49 + sudo "${rename_exchange}" "${old_path}" "${new_path}" >/dev/null 2>&1 50 + sudo sync -f "${MNT_PATH}" 51 + grep new "${old_path}" >/dev/null 2>&1 52 + grep old "${new_path}" >/dev/null 2>&1 53 + } 54 + 55 + rename_exchange_subdir_test() 56 + { 57 + local rename_exchange="${BASE_DIR}/rename_exchange" 58 + local dir_path="${MNT_PATH}/subdir" 59 + local old_path="${MNT_PATH}/old_file" 60 + local new_path="${dir_path}/new_file" 61 + 62 + sudo mkdir -p "${dir_path}" 63 + echo old | sudo tee "${old_path}" >/dev/null 2>&1 64 + echo new | sudo tee "${new_path}" >/dev/null 2>&1 65 + sudo "${rename_exchange}" "${old_path}" "${new_path}" >/dev/null 2>&1 66 + sudo sync -f "${MNT_PATH}" 67 + grep new "${old_path}" >/dev/null 2>&1 68 + grep old "${new_path}" >/dev/null 2>&1 69 + } 70 + 71 + unmount_image() 72 + { 73 + sudo umount "${MNT_PATH}" &> /dev/null 74 + } 75 + 76 + create_loopback 77 + mount_image 78 + rename_exchange_test 79 + rename_exchange_subdir_test 80 + unmount_image 81 + 82 + exit 0
+68 -7
tools/testing/selftests/proc/proc-pid-vm.c
··· 211 211 } 212 212 #endif 213 213 214 - static bool g_vsyscall = false; 214 + /* 215 + * 0: vsyscall VMA doesn't exist vsyscall=none 216 + * 1: vsyscall VMA is r-xp vsyscall=emulate 217 + * 2: vsyscall VMA is --xp vsyscall=xonly 218 + */ 219 + static int g_vsyscall; 220 + static const char *str_vsyscall; 215 221 216 - static const char str_vsyscall[] = 222 + static const char str_vsyscall_0[] = ""; 223 + static const char str_vsyscall_1[] = 217 224 "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n"; 225 + static const char str_vsyscall_2[] = 226 + "ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]\n"; 218 227 219 228 #ifdef __x86_64__ 220 229 static void sigaction_SIGSEGV(int _, siginfo_t *__, void *___) ··· 232 223 } 233 224 234 225 /* 235 - * vsyscall page can't be unmapped, probe it with memory load. 226 + * vsyscall page can't be unmapped, probe it directly. 236 227 */ 237 228 static void vsyscall(void) 238 229 { ··· 255 246 act.sa_sigaction = sigaction_SIGSEGV; 256 247 (void)sigaction(SIGSEGV, &act, NULL); 257 248 249 + /* gettimeofday(NULL, NULL); */ 250 + asm volatile ( 251 + "call %P0" 252 + : 253 + : "i" (0xffffffffff600000), "D" (NULL), "S" (NULL) 254 + : "rax", "rcx", "r11" 255 + ); 256 + exit(0); 257 + } 258 + waitpid(pid, &wstatus, 0); 259 + if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0) { 260 + /* vsyscall page exists and is executable. */ 261 + } else { 262 + /* vsyscall page doesn't exist. */ 263 + g_vsyscall = 0; 264 + return; 265 + } 266 + 267 + pid = fork(); 268 + if (pid < 0) { 269 + fprintf(stderr, "fork, errno %d\n", errno); 270 + exit(1); 271 + } 272 + if (pid == 0) { 273 + struct rlimit rlim = {0, 0}; 274 + (void)setrlimit(RLIMIT_CORE, &rlim); 275 + 276 + /* Hide "segfault at ffffffffff600000" messages. */ 277 + struct sigaction act; 278 + memset(&act, 0, sizeof(struct sigaction)); 279 + act.sa_flags = SA_SIGINFO; 280 + act.sa_sigaction = sigaction_SIGSEGV; 281 + (void)sigaction(SIGSEGV, &act, NULL); 282 + 258 283 *(volatile int *)0xffffffffff600000UL; 259 284 exit(0); 260 285 } 261 286 waitpid(pid, &wstatus, 0); 262 287 if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0) { 263 - g_vsyscall = true; 288 + /* vsyscall page is readable and executable. */ 289 + g_vsyscall = 1; 290 + return; 264 291 } 292 + 293 + /* vsyscall page is executable but unreadable. */ 294 + g_vsyscall = 2; 265 295 } 266 296 267 297 int main(void) ··· 309 261 int exec_fd; 310 262 311 263 vsyscall(); 264 + switch (g_vsyscall) { 265 + case 0: 266 + str_vsyscall = str_vsyscall_0; 267 + break; 268 + case 1: 269 + str_vsyscall = str_vsyscall_1; 270 + break; 271 + case 2: 272 + str_vsyscall = str_vsyscall_2; 273 + break; 274 + default: 275 + abort(); 276 + } 312 277 313 278 atexit(ate); 314 279 ··· 375 314 376 315 /* Test /proc/$PID/maps */ 377 316 { 378 - const size_t len = strlen(buf0) + (g_vsyscall ? strlen(str_vsyscall) : 0); 317 + const size_t len = strlen(buf0) + strlen(str_vsyscall); 379 318 char buf[256]; 380 319 ssize_t rv; 381 320 int fd; ··· 388 327 rv = read(fd, buf, sizeof(buf)); 389 328 assert(rv == len); 390 329 assert(memcmp(buf, buf0, strlen(buf0)) == 0); 391 - if (g_vsyscall) { 330 + if (g_vsyscall > 0) { 392 331 assert(memcmp(buf + strlen(buf0), str_vsyscall, strlen(str_vsyscall)) == 0); 393 332 } 394 333 } ··· 435 374 assert(memmem(buf, rv, S[i], strlen(S[i]))); 436 375 } 437 376 438 - if (g_vsyscall) { 377 + if (g_vsyscall > 0) { 439 378 assert(memmem(buf, rv, str_vsyscall, strlen(str_vsyscall))); 440 379 } 441 380 }