Commit graph

1,444,094 commits

Author SHA1 Message Date
Christian Brauner
4bbcff264b filelock: fix break_lease() stub signature for CONFIG_FILE_LOCKING=n
The CONFIG_FILE_LOCKING=n stub for break_lease() takes a 'bool wait'
argument, whereas the CONFIG_FILE_LOCKING=y version and every caller pass
an openmode as an 'unsigned int mode'. The mismatch was introduced when
__break_lease() was reworked to use flags: only the stub was switched to
'bool wait', a stray leftover from the neighbouring break_layout()
helper. The real prototype kept 'unsigned int mode'.

This was harmless until O_WRONLY changed from the octal literal 00000001
to (1 << 0). clang's -Wtautological-constant-compare then fires on the
implicit shift-to-bool conversion at the first FILE_LOCKING=n caller:

  fs/open.c:112:29: warning: converting the result of '<<' to a boolean
                    always evaluates to true [-Wtautological-constant-compare]
    112 | error = break_lease(inode, O_WRONLY);

Restore the stub's parameter to 'unsigned int mode' so it matches the
real prototype and every caller. The stub still just returns 0, so there
is no functional change; it removes the type inconsistency and silences
the warning.

Root cause diagnosed by Nathan Chancellor.

Fixes: 4be9f3cc58 ("filelock: rework the __break_lease API to use flags")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202606071029.DKCs8WOs-lkp@intel.com/
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-07 11:40:28 +02:00
Jori Koolstra
0da79c259a
vfs: uapi: retire octal and hex numbers in favor of (1 << n) for O_ flags
A recent build failure[1] exposed the diffculty of working with the
current octal and hex definitions of O_ flags when trying to find a gap
for a new flag. This difficulty is compounded by the fact that O_ flags
may have architectural specific values.

Replace the hex/octal #defines, which are hard to parse when looking for
free bits, with explicit bit shifts like (1 << 11). Also, add comments
that identify which architectures redefine some of the seemingly free
("cursed") bits in uapi/asm-generic/fcntl.h. These should not be used to
define new O_ flags (for now, at least).

The translastion was done with Claude Opus 4.8, and verified with a
(non-AI) gawk script. The accounting of which architectures claim
which bit-gaps in uapi/asm-generic/fcntl.h is also done by hand.

[1]: https://lore.kernel.org/all/agruPPybCx8q2XcJ@sirena.org.uk/

Assisted-by: Claude:Opus 4.8
Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl>
Link: https://patch.msgid.link/20260604222405.5382-1-jkoolstra@xs4all.nl
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-06 15:34:03 +02:00
Christian Brauner
9af8c8a54f
bpf: add bpf_real_inode() kfunc
Add a sleepable BPF kfunc that resolves the real inode backing a dentry
via d_real_inode(). On overlay/union filesystems the inode attached to
the dentry is the overlay inode which does not carry the underlying
device information. d_real_inode() resolves through the overlay and
returns the inode from the lower, real filesystem.

This is used in the RestrictFilesytemAccess bpf program that has been
merged into systemd a little while ago.

Link: https://github.com/systemd/systemd/pull/41340 [1]
Link: https://patch.msgid.link/20260526-work-bpf-verity-v2-1-cd0b1850d31b@kernel.org
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-06 15:25:46 +02:00
Andy Shevchenko
1a571226cb
fs/read_write: Do not export __kernel_write() to the entire world
Since we have EXPORT_SYMBOL_FOR_MODULES(), we may narrow
the __kernel_write() export to the only which really needs it.
With that being done, update the respective comment.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/20260604095233.284067-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-05 14:46:20 +02:00
Christian Brauner
f1f63c8967
Merge patch series "libfs: set SB_I_NOEXEC and SB_I_NODEV in init_pseudo()"
John Hubbard <jhubbard@nvidia.com> says:

This began as a one-line dma-buf fix for a path_noexec() warning added
by commit 1e7ab6f678 ("anon_inode: rework assertions"). Christoph
pointed out that the fix belongs higher up: a pseudo filesystem has no
reason not to set SB_I_NOEXEC by default. This series does that.

  * Patch 1 sets both flags in init_pseudo(), so every pseudo
    filesystem gets them. This is the only patch that changes a flag,
    and the only one with Fixes:/Cc: stable.

  * Patch 2 drops the assignments that are now redundant in the callers
    that set them by hand.

Most callers already set one or both flags. I audited every
init_pseudo() caller. Here is what patch 1 actually changes for each.
The only visible effect is on dma-buf, where SB_I_NOEXEC silences the
warning. SB_I_NODEV is never consulted on these SB_NOUSER mounts, and
none of the callers that gain SB_I_NOEXEC are executed from.

  caller                       had        patch 1 adds
  ---------------------------  --------   --------------
  fs/anon_inodes.c             both       nothing new
  mm/secretmem.c               both       nothing new
  virt/kvm/guest_memfd.c       both       nothing new
  fs/nsfs.c                    both       nothing new
  fs/pidfs.c                   both       nothing new
  fs/aio.c                     NOEXEC     NODEV
  drivers/dma-buf/dma-buf.c    neither    NOEXEC + NODEV
  net/socket.c                 neither    NOEXEC + NODEV
  fs/pipe.c                    neither    NOEXEC + NODEV
  kernel/resource.c            neither    NOEXEC + NODEV
  fs/erofs/super.c             neither    NOEXEC + NODEV
  fs/btrfs/tests/...           neither    NOEXEC + NODEV
  drivers/vfio/vfio_main.c     neither    NOEXEC + NODEV
  drivers/gpu/drm/drm_drv.c    neither    NOEXEC + NODEV
  drivers/dax/super.c          neither    NOEXEC + NODEV
  block/bdev.c                 neither    NOEXEC + NODEV

* patches from https://patch.msgid.link/20260604025315.245910-1-jhubbard@nvidia.com:
  libfs: drop redundant SB_I_NOEXEC/SB_I_NODEV in init_pseudo() callers
  libfs: set SB_I_NOEXEC and SB_I_NODEV by default in init_pseudo()

Link: https://patch.msgid.link/20260604025315.245910-1-jhubbard@nvidia.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-06-04 10:10:58 +02:00
John Hubbard
be5748d2ae
libfs: drop redundant SB_I_NOEXEC/SB_I_NODEV in init_pseudo() callers
init_pseudo() now sets SB_I_NOEXEC and SB_I_NODEV by default, so the
per-caller assignments are redundant. Drop them.

Signed-off-by: John Hubbard <jhubbard@nvidia.com>
Link: https://patch.msgid.link/20260604025315.245910-3-jhubbard@nvidia.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-04 10:10:49 +02:00
John Hubbard
6de2aeffab
libfs: set SB_I_NOEXEC and SB_I_NODEV by default in init_pseudo()
Since commit 1e7ab6f678 ("anon_inode: rework assertions"),
path_noexec() warns when an anonymous-inode file is mmap'd from a
superblock that has not set SB_I_NOEXEC. dma-buf backs its files this
way and never set the flag, so mmap of any exported buffer trips the
warning on a CONFIG_DEBUG_VFS=y kernel:

  WARNING: CPU: 11 PID: 121813 at fs/exec.c:118 path_noexec+0x47/0x50
   do_mmap+0x2b5/0x680
   vm_mmap_pgoff+0x129/0x210
   ksys_mmap_pgoff+0x177/0x240
   __x64_sys_mmap+0x33/0x70

init_pseudo() sets up internal SB_NOUSER mounts that are never
path-reachable. Set both flags here so every pseudo filesystem gets
them by default instead of each caller setting them.

SB_I_NODEV is inert for unreachable mounts. SB_I_NOEXEC has one
visible effect: an executable mapping of a pseudo-fs fd, such as a
dma-buf, now fails with -EPERM, which is the invariant the assertion
enforces. No in-tree caller maps these executable.

Reproduce on CONFIG_DEBUG_VFS=y:

  make -C tools/testing/selftests/dmabuf-heaps
  sudo ./tools/testing/selftests/dmabuf-heaps/dmabuf-heap -t system

Fixes: 1e7ab6f678 ("anon_inode: rework assertions")
Suggested-by: Christoph Hellwig <hch@infradead.org>
Cc: stable@vger.kernel.org
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
Link: https://patch.msgid.link/20260604025315.245910-2-jhubbard@nvidia.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-04 10:10:49 +02:00
Al Viro
6dd3c6884c
mount: honour SB_NOUSER in the new mount API
One should *not* be allowed to mount one of those, new API or not.

Reported-by: Denis Arefev <arefev@swemel.ru>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Link: https://patch.msgid.link/20260602020444.GP2636677@ZenIV
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-02 16:56:27 +02:00
Mingyu Wang
00633c4683
fs/fcntl: fix SOFTIRQ-unsafe lock order in fasync signaling
A SOFTIRQ-safe to SOFTIRQ-unsafe lock order deadlock can occur in
send_sigio() and send_sigurg() when a process group receives a signal.

When FASYNC is configured for a process group (PIDTYPE_PGID), both
functions use read_lock(&tasklist_lock) to traverse the task list.
However, they are frequently called from softirq context:
- send_sigio() via input_inject_event -> kill_fasync
- send_sigurg() via tcp_check_urg -> sk_send_sigurg (NET_RX_SOFTIRQ)

The deadlock is caused by the rwlock writer fairness mechanism:
1. CPU 0 (process context) holds read_lock(&tasklist_lock) in do_wait().
2. CPU 1 (process context) attempts write_lock(&tasklist_lock) in
   fork() or exit() and spins, which blocks all new readers.
3. CPU 0 is interrupted by a softirq (e.g., TCP URG packet reception).
4. The softirq calls send_sigurg() and attempts to acquire
   read_lock(&tasklist_lock), deadlocking because CPU 1 is waiting.

Since PID hashing and do_each_pid_task() traversals are already
RCU-protected, the read_lock on tasklist_lock is no longer strictly
required for safe traversal. Fix this by replacing tasklist_lock with
rcu_read_lock(), aligning the process group signaling path with the
single-PID path. This also mitigates a potential remote denial of
service vector via TCP URG packets.

Lockdep splat:
=====================================================
WARNING: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected
[...]
Chain exists of:
  &dev->event_lock --> &f_owner->lock --> tasklist_lock

Possible interrupt unsafe locking scenario:
       CPU0                    CPU1
       ----                    ----
  lock(tasklist_lock);
                           local_irq_disable();
                           lock(&dev->event_lock);
                           lock(&f_owner->lock);
  <Interrupt>
    lock(&dev->event_lock);

*** DEADLOCK ***

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
Link: https://patch.msgid.link/20260523135210.590928-1-w15303746062@163.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-28 14:40:25 +02:00
Christian Brauner
99f414273b
Merge patch series "fs/pipe: reduce pipe->mutex contention by pre-allocating outside the lock"
Breno Leitao <leitao@debian.org> says:

While profiling Meta's caching code[1], I found pipe->mutex contention
on the hot path. anon_pipe_write() currently calls alloc_page() once
per page while holding pipe->mutex. The allocation can sleep doing
direct reclaim and runs memcg charging, which extends the critical
section and stalls any concurrent reader on the same mutex.

This series pre-allocates pages outside pipe->mutex in
anon_pipe_write(): for writes that span more than one full page, up
to PIPE_PREALLOC_MAX (8) pages are allocated via a per-page
alloc_page() loop before the mutex is taken. anon_pipe_get_page()
then drains the prealloc array first, falls back to the per-pipe
tmp_page[] cache, and only enters the allocator under the mutex for
the leftover pages (writes larger than PIPE_PREALLOC_MAX, single-page
writes that skip prealloc, or shortfalls when the prealloc loop
fails). Leftover prealloc pages are recycled into tmp_page[] before
unlock and any remainder is put_page()'d after unlock, keeping the
allocator out of the critical section on both sides.

alloc_pages_bulk_mempolicy() looked tempting but the bulk allocator
refuses __GFP_ACCOUNT under memcg -- it returns at most one page
when memcg_kmem_online() && (gfp & __GFP_ACCOUNT), see commit
8dcb3060d8 ("memcg: page_alloc: skip bulk allocator for
__GFP_ACCOUNT"). A per-page loop keeps memcg accounting and the
task NUMA mempolicy honoured uniformly without open-coding the
charge.

I also vibe-coded a microbenchmark to validate the change. It sweeps
writers x readers over {1,2,5} x {1,5,10} with 64KB writes against a
1 MB pipe and prints throughput + latency percentiles per config.

Measured on arm64 and also on x86 using virtme-ng (16 vCPUs, 64KB
writes, 1 MB pipe). The numbers below were collected on v1
(alloc_pages_bulk()); v2's per-page loop preserves the dominant
"allocation outside the mutex" win and is expected to land in the same
range.

== No memory pressure (10s per config) ==

  Throughput in MB/s (baseline -> patched, delta):
    writers   readers=1              readers=5               readers=10
          1   1119 -> 1354  (+21%)   1132 -> 1195   (+6%)   1060 -> 1240  (+17%)
          2   1162 -> 1487  (+28%)   1034 -> 1285  (+24%)   1069 -> 1213  (+14%)
          5   1152 -> 1357  (+18%)   1021 -> 1164  (+14%)    997 -> 1239  (+24%)

  Avg write latency in ns (baseline -> patched, delta):
    writers   readers=1                 readers=5                readers=10
          1    55786 ->  46103 (-17%)   55164 ->  52260  (-5%)   58906 ->  50370 (-14%)
          2   107546 ->  84011 (-22%)  120837 ->  97206 (-20%)  116860 -> 103036 (-12%)
          5   271293 -> 230170 (-15%)  306089 -> 268429 (-12%)  313300 -> 252232 (-19%)

Throughput improves +6% to +28% and average write latency drops 5%
to 22% across every configuration.

== Under memory pressure (--memory-pressure, 6s per config) ==

stress-ng --vm 2 --vm-bytes 50% --vm-keep is forked alongside the
sweep so the alloc_page() calls inside anon_pipe_write() routinely
hit direct reclaim -- exactly the regime the patch targets.

  Throughput in MB/s (baseline -> patched, delta):
    writers   readers=1            readers=5            readers=10
          1   1088 -> 1438  (+32%)   996  -> 1477  (+48%)   989  -> 1194  (+21%)
          2   1076 -> 1378  (+28%)   1007 -> 1269  (+26%)   1018 -> 1234  (+21%)
          5   1052 -> 1311  (+25%)   986  -> 1225  (+24%)   972  -> 1249  (+29%)

  Avg write latency in ns (baseline -> patched, delta):
    writers   readers=1              readers=5              readers=10
          1    57397 ->  43406 (-24%)   62690 ->  42272 (-33%)   63136 ->  52272 (-17%)
          2   116121 ->  90700 (-22%)  124098 ->  98481 (-21%)  122754 -> 101217 (-18%)
          5   297122 -> 238322 (-20%)  316836 -> 255095 (-19%)  321496 -> 250189 (-22%)

Throughput improves +21% to +48% and average write latency drops
17% to 33% -- a noticeably bigger win than the no-pressure run.

That tracks: when alloc_page() has to dip into reclaim, the cost
of holding pipe->mutex across it is highest, and pulling the
allocation out of the critical section pays the most.

* patches from https://patch.msgid.link/20260524-fix_pipe-v3-0-bb4a75d23a90@debian.org:
  selftests/pipe: add pipe_bench microbenchmark
  fs/pipe: pre-allocate pages outside pipe->mutex in anon_pipe_write

Link: https://www.usenix.org/system/files/conference/atc13/atc13-bronson.pdf [1]
Link: https://patch.msgid.link/20260524-fix_pipe-v3-0-bb4a75d23a90@debian.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-28 14:33:32 +02:00
Breno Leitao
d29bd8efe1
selftests/pipe: add pipe_bench microbenchmark
Add a small selftest that stresses pipe->mutex contention by spawning N
writer threads that hammer a single pipe with multi-page writes, plus M
reader threads that drain. Each writer records its own write() latency
samples into a log2-bucketed histogram; main aggregates and prints
total writes, throughput, average and percentile (p50/p99) latencies,
and the maximum observed latency.

Pass --memory-pressure to fork stress-ng (--vm 4 --vm-bytes 80%
--vm-method all) for the duration of the run, so alloc_page() in
anon_pipe_write() routinely hits direct reclaim. The flag fails
fast if stress-ng is not on $PATH.

Program print something like the following, for different writes,
readers, msgsizes and memory pressure:

	config: writers=X readers=Y msgsize=Z duration=3 pipe_size=1048576
	memory_pressure=[no|yes]
	writes: total=54451 rate=18150/s
	throughput_MBps: 1134.40
	lat_avg_ns: 275355
	lat_p50_ns_upper: 262143
	lat_p99_ns_upper: 1048575
	lat_max_ns: 2145633

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Breno Leitao <leitao@debian.org>
Link: https://patch.msgid.link/20260524-fix_pipe-v3-2-bb4a75d23a90@debian.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-28 14:33:25 +02:00
Breno Leitao
212ed884a1
fs/pipe: pre-allocate pages outside pipe->mutex in anon_pipe_write
anon_pipe_write() takes pipe->mutex (aka "mutex protecting the whole
thing") and then, from the per-iteration anon_pipe_get_page() helper,
used to call alloc_page(GFP_HIGHUSER | __GFP_ACCOUNT) once per page
while still holding it.

That allocation can sleep doing direct reclaim and/or runs memcg
charging, which extends the critical section and stalls a concurrent
reader on the very same mutex.

Just pre-alloc the required pages before the lock in an array and just pop
them inside the lock.

This can improve the pipe throughput up to 48% and reduce the
latency in 33%, easily seen when there is memory pressure and direct
reclaim.

Reviewed-by: Mateusz Guzik <mjguzik@gmail.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Breno Leitao <leitao@debian.org>
Link: https://patch.msgid.link/20260524-fix_pipe-v3-1-bb4a75d23a90@debian.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-28 14:33:24 +02:00
Mateusz Guzik
d24576fddf
fs: retire stale comment in fget_task_next()
The routine originally showed up in e9a53aeb5e ("file: Implement
task_lookup_next_fd_rcu"), afterwards it got renamed and started
entering RCU on its own in 8fd3395ec9 ("get rid of
...lookup...fdget_rcu() family").

Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Link: https://patch.msgid.link/20260522142152.1515572-1-mjguzik@gmail.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-28 14:27:00 +02:00
Qingshuang Fu
5afe734e76
fs: fix spelling mistakes in comment
Fix three spelling errors in the comment for an internal file structure
allocation function:
- happend  →  happened
- over     →  exceed (grammatical fix)
- int      →  in

Changes since v1:
- Fix comma after e.g.
- Fix incorrect use of "imbalance"

Signed-off-by: Qingshuang Fu <fuqingshuang@kylinos.cn>
Link: https://patch.msgid.link/20260527100025.960339-1-fffsqian@163.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-28 14:05:59 +02:00
Christian Brauner
cfe724c85f Merge patch series "fs: replace __get_free_pages() call with kmalloc()"
Mike Rapoport (Microsoft) <rppt@kernel.org> says:

This is a (small) part of larger work of replacing page allocator calls
with kmalloc.

* patches from https://patch.msgid.link/20260523-b4-fs-v1-0-275e36a83f0e@kernel.org:
  bfs: replace get_zeroed_page() with kzalloc()
  binfmt_misc: replace __get_free_page() with kmalloc()
  configfs: replace __get_free_pages() with kzalloc()
  fs/namespace: use __getname() to allocate mntpath buffer
  fs/select: replace __get_free_page() with kmalloc()
  fuse: replace __get_free_page() with kmalloc()
  isofs: replace __get_free_page() with kmalloc()
  jbd2: replace __get_free_pages() with kmalloc()
  jfs: replace __get_free_page() with kmalloc()
  libfs: simple_transaction_get(): replace get_zeroed_page() with kzalloc()
  NFSD: replace __get_free_page() with kmalloc() in nfsd_buffered_readdir()
  NFS: remove unused page and page2 in nfs4_replace_transport()
  NFS: replace __get_free_page() with kmalloc() in nfs_show_devname()
  nilfs2: replace get_zeroed_page() with kzalloc()
  ocfs2/dlm: replace __get_free_page() with kmalloc()
  proc: replace __get_free_page() with kmalloc()
  quota: allocate dquot_hash with kmalloc()

Link: https://patch.msgid.link/20260523-b4-fs-v1-0-275e36a83f0e@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-28 13:58:14 +02:00
Mike Rapoport (Microsoft)
c1fe8d334f bfs: replace get_zeroed_page() with kzalloc()
bfs_dump_imap() allocates temporary buffer with get_zeroed_page().

kmalloc() is a better API for such use and it also provides better
scalability and more debugging possibilities.

Replace use of get_zeroed_page() with kzalloc().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-17-275e36a83f0e@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-28 13:58:14 +02:00
Mike Rapoport (Microsoft)
6ff17653e9 binfmt_misc: replace __get_free_page() with kmalloc()
bm_entry_read() allocates temporary buffer using __get_free_page().

kmalloc() is a better API for such use and it also provides better
scalability and more debugging possibilities.

Replace use of __get_free_page() with kmalloc().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-16-275e36a83f0e@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-28 13:58:14 +02:00
Mike Rapoport (Microsoft)
1b27d11b17 configfs: replace __get_free_pages() with kzalloc()
configfs allocates staging buffers __get_free_pages().

kmalloc() is a better API for such use and it also provides better
scalability and more debugging possibilities.

Replace use of __get_free_pages() with kzalloc().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-15-275e36a83f0e@kernel.org
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-28 13:58:14 +02:00
Mike Rapoport (Microsoft)
aca4fd395d fs/namespace: use __getname() to allocate mntpath buffer
mnt_warn_timestamp_expiry() allocates memory for a path with
__get_free_page() although there is a dedicated helper for allocation of
file paths: __getname().

Replace __get_free_page() for allocation of a path buffer with __getname().

Christian Brauner <brauner@kernel.org> says:

Pass PATH_MAX (not PAGE_SIZE) to d_path() to match the size that
__getname() actually allocates, and drop the now-unnecessary NULL check
around __putname() since __putname() handles NULL.  Both per Jan Kara's
review feedback, acked by the author.

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-14-275e36a83f0e@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-28 13:57:57 +02:00
Mike Rapoport (Microsoft)
cf080236f3
fs/select: replace __get_free_page() with kmalloc()
poll_get_entry() allocates new memory for poll_table entries using
__get_free_page().

kmalloc() is a better API for such use and it also provides better
scalability and more debugging possibilities.

Replace use of __get_free_page() with kmalloc().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-13-275e36a83f0e@kernel.org
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:12:24 +02:00
Mike Rapoport (Microsoft)
3db329857c
fuse: replace __get_free_page() with kmalloc()
fuse_do_ioctl allocates memory for struct iov array using
__get_free_page().

kmalloc() is a better API for such use and it also provides better
scalability and more debugging possibilities.

Replace use of __get_free_page() with kmalloc().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-12-275e36a83f0e@kernel.org
Acked-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:12:24 +02:00
Mike Rapoport (Microsoft)
263873f40e
isofs: replace __get_free_page() with kmalloc()
isofs_readdir() allocates a temporary buffer with __get_free_page().

kmalloc() is a better API for such use and it also provides better
scalability and more debugging possibilities.

Replace use of __get_free_page() with kmalloc().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-11-275e36a83f0e@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:12:24 +02:00
Mike Rapoport (Microsoft)
2f6702dc6f
jbd2: replace __get_free_pages() with kmalloc()
jbd2_alloc() falls back from kmem_cache_alloc() to __get_free_pages() for
allocations larger than PAGE_SIZE.
But kmalloc() can handle such cases with essentially the same fallback.

Replace use of __get_free_pages() with kmalloc() and simplify
jbd2_free() as both kmem_cache_alloc() and kmalloc() allocations can be
freed with kfree().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-10-275e36a83f0e@kernel.org
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:12:24 +02:00
Mike Rapoport (Microsoft)
de9f4f0b2c
jfs: replace __get_free_page() with kmalloc()
jfs_readdir() allocates dirent_buf with __get_free_page().

kmalloc() is a better API for such use and it also provides better
scalability and more debugging possibilities.

Replace use of __get_free_page() with kmalloc().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-9-275e36a83f0e@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:12:23 +02:00
Mike Rapoport (Microsoft)
02d7d892d2
libfs: simple_transaction_get(): replace get_zeroed_page() with kzalloc()
simple_transaction_get() allocates memory with get_zeroed_page(). That
memory is used as a file local buffer that is accessed using
copy_from_user() and simple_read_from_buffer().

kmalloc() is a better API for such use and it also provides better
scalability and more debugging possibilities.

Replace use of get_zeroed_page() with kzalloc().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-8-275e36a83f0e@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:12:23 +02:00
Mike Rapoport (Microsoft)
06040e7520
NFSD: replace __get_free_page() with kmalloc() in nfsd_buffered_readdir()
nfsd_buffered_readdir() allocates a staging buffer with __get_free_page().

kmalloc() is a better API for such use and it also provides better
scalability and more debugging possibilities.

Replace use of __get_free_page() with kmalloc().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-7-275e36a83f0e@kernel.org
Acked-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:12:23 +02:00
Mike Rapoport (Microsoft)
7c031f1d47
NFS: remove unused page and page2 in nfs4_replace_transport()
Temporary buffers page and page2 allocated by nfs4_replace_transport() and
passed to nfs4_try_replacing_one_location() are never used.

Remove them and the code that allocates and frees memory for these buffers.

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-6-275e36a83f0e@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:12:23 +02:00
Mike Rapoport (Microsoft)
eb28dd9d34
NFS: replace __get_free_page() with kmalloc() in nfs_show_devname()
nfs_show_devname() allocates a tmemporary buffer __get_free_page().

kmalloc() is a better API for such use and it also provides better
scalability and more debugging possibilities.

Replace use of __get_free_page() with kmalloc().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-5-275e36a83f0e@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:12:23 +02:00
Mike Rapoport (Microsoft)
4948580c76
nilfs2: replace get_zeroed_page() with kzalloc()
nilfs_ioctl_wrap_copy() allocates a temporary buffer with
get_zeroed_page().

kzalloc() is a better API for such use and it also provides better
scalability and more debugging possibilities.

Replace use of get_zeroed_page() with kzalloc().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-4-275e36a83f0e@kernel.org
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:12:23 +02:00
Mike Rapoport (Microsoft)
bc24c55579
ocfs2/dlm: replace __get_free_page() with kmalloc()
A few places in ocsfs2 allocate temporary buffers with __get_free_page() or
get_zeroed_page().

kmalloc() is a better API for such use and it also provides better
scalability and more debugging possibilities.

Replace use of __get_free_page() and get_zeroed_page() with kmalloc() and
kzalloc() respectively.

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-3-275e36a83f0e@kernel.org
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:12:23 +02:00
Mike Rapoport (Microsoft)
cb7907e36c
proc: replace __get_free_page() with kmalloc()
A few functions in fs/proc/base.c use __get_free_page() to allocate a
temporary buffer.

kmalloc() is a better API for such use and it also provides better
scalability and more debugging possibilities.

Replace use of __get_free_page() with kmalloc().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-2-275e36a83f0e@kernel.org
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:12:22 +02:00
Mike Rapoport (Microsoft)
6c519166e1
quota: allocate dquot_hash with kmalloc()
dquot_init() allocates a single page for dquot_hash with
__get_free_pages().

kmalloc() is a better API for such use and it also provides better
scalability and more debugging possibilities.

Replace use of __get_free_pages() with kmalloc() and get rid of the order
variable that remained 0 for more than 20 years.

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260523-b4-fs-v1-1-275e36a83f0e@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:12:22 +02:00
Christian Brauner
99489cd82c
Merge patch series "fs: refactor code to use clear_and_wake_up_bit()"
Agatha Isabelle Moreira <code@agatha.dev> says:

Refactor code to use `clear_and_wake_up_bit()` instead of manual calls
to:
       	clear_bit_unlock();
	smp_mb__after_atomic();
	wake_up_bit();

The helper function `clear_and_wake_up_bit()` was introduced in
'commit 8236b0ae31 ("bdi: wake up concurrent wb_shutdown()
callers.")' as a generic way of doing the same sequence of operations,
but several pieces of code still remain.

Replace manual calls to the operations by a single call to
`clear_and_wake_up_bit()` to deduplicate code and standardize pathways.

* patches from https://patch.msgid.link/ag4PEP52c8rxrYPc@guidai:
  fs: jbd2: use clear_and_wake_up_bit() in journal_end_buffer_io_sync()
  fs: buffer: use clear_and_wake_up_bit() in unlock_buffer()

Link: https://patch.msgid.link/ag4PEP52c8rxrYPc@guidai
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:11:02 +02:00
Jia He
ec3f4e0443
init/initramfs_test: wait_for_initramfs() before running
initramfs_test_extract() and friends call unpack_to_rootfs() from a
kunit kthread while do_populate_rootfs() may still be running
asynchronously from rootfs_initcall. unpack_to_rootfs() keeps its
parser state in module-static variables (victim, byte_count, state,
this_header, header_buf, name_buf, ...), so the two writers corrupt
each other.

On arm64 v7.0-rc5+ this oopses early in boot:

  Unable to handle kernel paging request at virtual address ffff80018f9f0ffc
  pc : do_reset+0x3c/0x98
  Call trace:
   do_reset
   initramfs_test_extract
   kunit_try_run_case
  Initramfs unpacking failed: junk within compressed archive

do_reset() faults because 'victim' was overwritten by the boot-time
unpacker; the boot unpacker meanwhile logs the bogus "junk within
compressed archive" on the real initrd because the test wrecked its
state machine.

Add a .suite_init callback that calls wait_for_initramfs() so the async
unpack is quiescent before the first case runs. suite_init runs once per
suite rather than before every individual test case.

Fixes: 83c0b27266 ("initramfs_test: kunit tests for initramfs unpacking")
Signed-off-by: Jia He <justin.he@arm.com>
Link: https://patch.msgid.link/20260519093937.1064628-1-justin.he@arm.com
Reviewed-by: David Disseldorp <ddiss@suse.de>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:11:02 +02:00
Agatha Isabelle Moreira
2fddb8479d
fs: jbd2: use clear_and_wake_up_bit() in journal_end_buffer_io_sync()
Use `clear_and_wake_up_bit()` in `journal_end_buffer_io_sync()`, since
the helper was introduced in 'commit 8236b0ae31 ("bdi: wake up
concurrent wb_shutdown() callers.")' as a generic way of doing the same
sequence of operations:
	clear_bit_unlock();
	smp_mb__after_atomic();
	wake_up_bit();

The helper was first implemented to avoid bugs caused by forgetting to
call `wake_up_bit()` after `clear_bit_unlock()`.

Since `journal_end_buffer_io_sync()` was first introduced by 'commit
470decc613 ("jbd2: initial copy of files from jbd")' and last
modified in this operation by 'commit 4e857c58ef ("arch: Mass
conversion of smp_mb__*()")', years before `clear_and_wake_up_bit()`, it
still uses the open-coded sequence.

Replace the open-coded sequence with the helper to avoid duplicate code
and reduce code paths to maintain.

Suggested-by: shuo chen <1289151713@qq.com>
Link: https://lore.kernel.org/kernelnewbies/agzoqV835-co4kAN@guidai/T/#t
Signed-off-by: Agatha Isabelle Moreira <code@agatha.dev>
Link: https://patch.msgid.link/ag4SrrOl7R2DcLLi@guidai
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:11:02 +02:00
Agatha Isabelle Moreira
0432b89f61
fs: buffer: use clear_and_wake_up_bit() in unlock_buffer()
Use `clear_and_wake_up_bit()` in `unlock_buffer()`, since the helper was
introduced in 'commit 8236b0ae31 ("bdi: wake up concurrent
wb_shutdown() callers.")' as a generic way of doing the same sequence of
operations:
       	clear_bit_unlock();
	smp_mb__after_atomic();
	wake_up_bit();

The helper was implemented to avoid bugs caused by forgetting to call
`wake_up_bit()` after `clear_bit_unlock()`.

Since `unlock_buffer()` predates git and was last modified in
'commit 4e857c58ef ("arch: Mass conversion of smp_mb__*()")', years
before `clear_and_wake_up_bit()`, it still uses the open-coded sequence.

Replace the open-coded sequence with the helper to avoid duplicate code
and reduce code paths to maintain.

Suggested-by: shuo chen <1289151713@qq.com>
Link: https://lore.kernel.org/kernelnewbies/agzoqV835-co4kAN@guidai/T/#t
Signed-off-by: Agatha Isabelle Moreira <code@agatha.dev>
Link: https://patch.msgid.link/ag4SD-mkmn5IbuN7@guidai
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-27 15:11:02 +02:00
Christoph Hellwig
988c918b81
minix: release the sb buffer_head when setting the v3 block size fails
At this point the superblock is already read, so jump to the label that
releases the buffer_head for it.

Fixes: d893fc670546 ("minix: handle set_blocksize failures")
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260518130330.529085-1-hch@lst.de
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-22 12:20:49 +02:00
Mike Rapoport (Microsoft)
3fb2d124b6
init: do_mounts: use kmalloc() for allocations of temporary buffers
Several places in init/do_mounts.c allocate temporary buffers for
filesystem names or options using __get_free_page() or alloc_page().

Usage of alloc_page() APIs is not required there and only creates
unnecessary noise with castings or conversion from struct page to void *.

kmalloc() is a better API for these uses and it also provides better
scalability and more debugging possibilities.

Replace use of __get_free_page() and alloc_page() with kmalloc().

While on it, add a check for -ENOMEM condition in mount_root_generic().

Link: https://lore.kernel.org/all/635405e4-9423-4a25-a6e7-e03c8ea0bcbe@redhat.com
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Link: https://patch.msgid.link/20260520-init-v1-1-aaf2ebac5ad9@kernel.org
Reviewed-by: David Disseldorp <ddiss@suse.de>
Reviewed-by: SeongJae Park <sj@kernel.org>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-22 12:12:20 +02:00
Mateusz Guzik
7dc6acb3d5
fs/pipe: write to ->poll_usage only once
Both GNU and BSD makes share a "token pipe" between their instances, as
a result a -j $BIGNUM invocation results in multicore perf problems in
the poll handler.

Avoiding the store will reduce it a little bit. However, the crux of the
problem is the locked queuing up in poll_wait().

Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Link: https://patch.msgid.link/20260516021852.256932-1-mjguzik@gmail.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 13:39:36 +02:00
Alexey Dobriyan
50d377ef12
sync_file_range: delete dead S_ISLNK code
Symlinks can't appear as opened file.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Link: https://patch.msgid.link/295235c7-7f68-4554-bb6f-85398beca350@p183
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 13:39:36 +02:00
Thorsten Blum
de7680d943
namei: use QSTR() instead of QSTR_INIT() in path_pts
Drop the hard-coded length argument and use the simpler QSTR(). Inline
the code and drop the local variable.

Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Link: https://patch.msgid.link/20260505114242.158883-2-thorsten.blum@linux.dev
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 13:39:36 +02:00
Christian Brauner
d90e60ced4
Merge patch series "fix crashes when mounting legacy file system with sector size > PAGE_SIZE"
Christoph Hellwig <hch@lst.de> says:

Due to an almost comical failure on my part, my work in progress test
case failed to create any file system on a 64k block size loop device,
and then tried to mount it, leading to a probe of file system built
into my kernel.  Roughly the first half of the series are file systems
that actually crashed, but I fixed up all the pattern of missing
error handling that I saw.

* patches from https://patch.msgid.link/20260511071701.2456211-1-hch@lst.de:
  omfs: handle set_blocksize failures
  ntfs3: handle set_blocksize failures
  minix: handle set_blocksize failures
  isofs: handle set_blocksize failures
  affs: handle set_blocksize failures
  befs: handle set_blocksize failures
  jfs: handle set_blocksize failures
  qnx4: handle set_blocksize failures
  hpfs: handle set_blocksize failures
  bfs: handle set_blocksize failures

Link: https://patch.msgid.link/20260511071701.2456211-1-hch@lst.de
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 13:39:36 +02:00
Christoph Hellwig
18c3d6fcb5
omfs: handle set_blocksize failures
omfs uses buffer_heads, which don't handle block size > PAGE_SIZE well.
Without this, mounting we will hit the

        BUG_ON(offset >= folio_size(folio));

in folio_set_bh on the first __bread_gfp call.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260511071701.2456211-11-hch@lst.de
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 13:39:36 +02:00
Christoph Hellwig
24f7d1824b
ntfs3: handle set_blocksize failures
ntfs3 uses buffer_heads, which don't handle block size > PAGE_SIZE well.
Without this, mounting we will hit the

        BUG_ON(offset >= folio_size(folio));

in folio_set_bh on the first __bread_gfp call.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260511071701.2456211-10-hch@lst.de
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 13:39:36 +02:00
Christoph Hellwig
38a03dc2bc
minix: handle set_blocksize failures
minix uses buffer_heads, which don't handle block size > PAGE_SIZE well.
Without this, mounting we will hit the

        BUG_ON(offset >= folio_size(folio));

in folio_set_bh on the first __bread_gfp call.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260511071701.2456211-9-hch@lst.de
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 13:39:36 +02:00
Christoph Hellwig
25ef4c4d9f
isofs: handle set_blocksize failures
isofs uses buffer_heads, which don't handle block size > PAGE_SIZE well.
Without this, mounting we will hit the

        BUG_ON(offset >= folio_size(folio));

in folio_set_bh on the first __bread_gfp call.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260511071701.2456211-8-hch@lst.de
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 13:39:35 +02:00
Christoph Hellwig
0861182af5
affs: handle set_blocksize failures
affs uses buffer_heads, which don't handle block size > PAGE_SIZE well.
Without this, mounting we will hit the

        BUG_ON(offset >= folio_size(folio));

in folio_set_bh on the first __bread_gfp call.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260511071701.2456211-7-hch@lst.de
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 13:39:35 +02:00
Christoph Hellwig
7597d42a25
befs: handle set_blocksize failures
befs uses buffer_heads, which don't handle block size > PAGE_SIZE well.
Without this, mounting we will hit the

        BUG_ON(offset >= folio_size(folio));

in folio_set_bh on the first __bread_gfp call.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260511071701.2456211-6-hch@lst.de
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 13:39:35 +02:00
Christoph Hellwig
05107f5602
jfs: handle set_blocksize failures
jfs uses buffer_heads, which don't handle block size > PAGE_SIZE well.
Without this, mounting we will hit the

        BUG_ON(offset >= folio_size(folio));

in folio_set_bh on the first __bread_gfp call.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260511071701.2456211-5-hch@lst.de
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 13:39:35 +02:00
Christoph Hellwig
c7d911ea1c
qnx4: handle set_blocksize failures
qnx4 uses buffer_heads, which don't handle block size > PAGE_SIZE well.
Without this, mounting will hit the

        BUG_ON(offset >= folio_size(folio));

in folio_set_bh on the first __bread_gfp call.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260511071701.2456211-4-hch@lst.de
Acked-by: Anders Larsen <al@alarsen.net>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-21 13:39:35 +02:00