summaryrefslogtreecommitdiff
path: root/fs
AgeCommit message (Collapse)AuthorFilesLines
2026-07-31iomap: Remove FGP_NOFS from iomap_get_folio()Matthew Wilcox (Oracle)1-1/+1
FGP_NOFS is legacy; filesystems should be using memalloc_nofs_save/restore instead. We have it here in iomap because it was buried in grab_cache_page_write_begin() and we didn't want to change this behaviour as part of the folio transition. I have tested this with XFS and see no issues. Other filesystems (cc'd) may need to make adjustments. Please test with lockdep enabled. Cc: Darrick J. Wong <djwong@kernel.org> Cc: Jens Axboe <axboe@kernel.dk> Cc: Namjae Jeon <linkinjeon@kernel.org> Cc: Sungjong Seo <sj1557.seo@samsung.com> Cc: Yuezhang Mo <yuezhang.mo@sony.com> Cc: Miklos Szeredi <miklos@szeredi.hu> Cc: Andreas Gruenbacher <agruenba@redhat.com> Cc: Hyunchul Lee <hyc.lee@gmail.com> Cc: Konstantin Komarov <almaz.alexandrovich@paragon-software.com> Cc: Carlos Maiolino <cem@kernel.org> Cc: Damien Le Moal <dlemoal@kernel.org> Cc: Naohiro Aota <naohiro.aota@wdc.com> Cc: Johannes Thumshirn <jth@kernel.org> Cc: linux-xfs@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org Cc: linux-block@vger.kernel.org Cc: fuse-devel@lists.linux.dev Cc: gfs2@lists.linux.dev Cc: ntfs3@lists.linux.dev Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Link: https://patch.msgid.link/20260624174228.2015893-1-willy@infradead.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31iomap: add a separate bio_set for iomap_split_ioendChristoph Hellwig1-2/+19
iomap_split_ioend can split bios that already come from iomap_ioend_bioset and thus deadlock when the bioset is exhausted. Add a separate bio_set to avoid this deadlock. Christian Brauner <brauner@kernel.org> says: Mark iomap_ioend_split_bioset static as it is only used in ioend.c, fixing the sparse warning reported by the kernel test robot. Fixes: 5fcbd555d483 ("iomap: split bios to zone append limits in the submission handlers") Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://patch.msgid.link/20260629125229.3400726-1-hch@lst.de Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31dcache: keep shrink_dcache_for_umount() making progress on busy rootsKarl Mehltretter1-1/+6
Commit e9895609cb7f ("wind ->s_roots via ->d_sib instead of ->d_hash") moved secondary roots from ->d_hash to ->d_sib. Secondary roots are now d_unhashed(), so __d_drop() returns without removing them from ->s_roots. Consequently, d_drop() in do_one_tree() no longer guarantees progress through the list. If a secondary root is still busy once do_one_tree() is done with it, its final dput() cannot evict it. The root remains ->s_roots.first and the loop selects it forever, holding ->s_umount for write and repeatedly reporting the same dentry. The root does not need a leaked reference of its own for that. Every child pins its parent (d_alloc() takes a reference on it) and umount_check() deliberately reports a busy descendant instead of complaining about its ancestors, so a single leaked dentry reference anywhere below a secondary root is enough. For filesystems that build ->s_root with d_obtain_root() - nfs, ceph, nilfs2 snapshot mounts - that is the entire tree. Before e9895609cb7f, ___d_drop() special-cased IS_ROOT dentries and removed them from ->s_roots regardless of their refcount, so the d_drop() in do_one_tree() detached the root from the superblock no matter what. Commit 9c8c10e262e0 ("more graceful recovery in umount_collect()") deliberately made busy dentries nonfatal: report them and finish the unmount rather than BUG() while holding ->s_umount. Restore that by detaching the root in do_one_tree() itself, next to the d_drop() that used to do it. That covers both callers - the ->s_roots loop and ->s_root, which for the filesystems above is a secondary root as well. In the normal case dentry_unlist() finds ->d_sib already unhashed when eviction occurs. A permanently leaked reference remains leaked after unmount, as it did before e9895609cb7f; if the extra reference is merely delayed, its final dput() may run after teardown has advanced. Leaving the root on ->s_roots is not an alternative: the superblock would then be freed with a live dentry still linked into it, and that dentry's dentry_unlist() would take ->s_roots_lock on freed memory. Christian Brauner <brauner@kernel.org> says: Moved the ->s_roots removal from the shrink_dcache_for_umount() loop into do_one_tree(), so a busy ->s_root obtained from d_obtain_root() is detached on the first pass instead of being reported a second time when the loop picks it off ->s_roots. Extended the commit message with the pinned-ancestor case. Fixes: e9895609cb7f ("wind ->s_roots via ->d_sib instead of ->d_hash") Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> Link: https://patch.msgid.link/20260729005933.15858-1-kmehltretter@gmail.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31fs/namei.c: fix coding style in atomic_open() and lookup_open()Christian Brauner1-3/+8
Commit 4886c80eef20 ("vfs: call audit_inode_child() in lookup_open() on failure") indented a continuation line with spaces, left three declarations without a following blank line and used a trailing */ on the last line of a block comment. Clean all of that up, no functional change. Link: https://patch.msgid.link/20260731-work-lookup-fixes-v1-3-2412b85cf65c@kernel.org Fixes: 4886c80eef20 ("vfs: call audit_inode_child() in lookup_open() on failure") Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31fs/namei.c: fix kerneldoc of atomic_open() and vfs_lookup_open()Christian Brauner1-5/+7
Commit ba0e87026613 ("fs/namei.c: update kerneldoc of atomic_open()") turned the comment above atomic_open() into kerneldoc, but wrote the return description as running text. kernel-doc only recognises a return section introduced by "Return:" or "Returns:", so this added a warning under W=1: fs/namei.c:4362 No description found for return value of 'atomic_open' Give it the missing colon. The summary line also has to stand on its own line, so move the "from a negative dentry" part into the body, where it can say that the caller has to hand over a negative dentry. Also add the "to" missing from vfs_lookup_open()'s description. Link: https://patch.msgid.link/20260731-work-lookup-fixes-v1-2-2412b85cf65c@kernel.org Fixes: ba0e87026613 ("fs/namei.c: update kerneldoc of atomic_open()") Fixes: 536227b814bd ("VFS: add vfs_lookup_open() for nfsd") Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31fs/namei.c: update stale comments in lookup_open()Christian Brauner1-11/+9
Commit ddb6e6c72a0a ("VFS: move mnt_want_write() and locking into lookup_open()") moved the parent inode locking into lookup_open(), but left the comment claiming the caller has to take it. A caller following that comment now deadlocks, and the series added a second caller. Describe what the function actually does. While at it drop the claim that it returns 0 on success and updates @path, wrong ever since lookup_open() started returning a dentry in v5.7, and fix the reference to lookup_open() in a comment that now sits inside lookup_open() itself. Link: https://patch.msgid.link/20260731-work-lookup-fixes-v1-1-2412b85cf65c@kernel.org Fixes: ddb6e6c72a0a ("VFS: move mnt_want_write() and locking into lookup_open()") Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31Remove excl arg to ->create inode_operationNeilBrown47-63/+54
The only time that 'false' is passed as the 'excl' arg to the ->create inode_operation is in lookup_open() when ->atomic_open is not provided by the parent directory. *all* directory inode_operations which do not have ->atomic_open completely ignore the 'excl' arg. Therefore we don't need the 'excl' arg. Those few ->create operations which pay attention to the arg are only ever called with a value of 'true'. We remove that arg and change all ->create operations to behave as those thhe arg were 'true'. Signed-off-by: NeilBrown <neil@brown.name> Link: https://patch.msgid.link/178290671516.27465.15984496764174914338@noble.neil.brown.name Reviewed-by: Jori Koolstra <jkoolstra@xs4all.nl> Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31seq_file: rename mangle_path to seq_mangle_pathJohannes Berg1-6/+5
The symbol mangle_path conflicts with a gcov symbol which can break the build of ARCH=um with gcov, and it's also not very specific and descriptive. Rename mangle_path() to seq_mangle_path(), and also remove the export since it's not needed or used by any modules. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Alex Hung <alex.hung@amd.com> Link: https://patch.msgid.link/20260727195730.2306887-1-alex.hung@amd.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31dcache: use lockref routines for dead count checksMateusz Guzik1-8/+8
Signed-off-by: Mateusz Guzik <mjguzik@gmail.com> Link: https://patch.msgid.link/20260724171422.429284-3-mjguzik@gmail.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31lockref: tidy up dead count handlingMateusz Guzik7-15/+15
1. put the dead val into a macro so that it can be used in other places 2. __lockref_is_dead(): - drop the __ suffix, this is not an internal routine - drop the spurious cast, the value is already a signed int - use READ_ONCE to prevent any compile shenanigans 3. provide lockref_is_dead_or_zero() Signed-off-by: Mateusz Guzik <mjguzik@gmail.com> Link: https://patch.msgid.link/20260724171422.429284-2-mjguzik@gmail.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31fs/pipe: unify the page pools into a single per-pipe poolBreno Leitao1-97/+74
Pipes keep two separate page caches: a) The per-pipe, lock-protected tmp_page[2] b) An on-stack anon_pipe_prealloc burst pool of up to eight pages filled before the lock Converge them into a single per-pipe pool (struct anon_pipe_prealloc embedded in pipe_inode_info) with the same budget as before: up to PIPE_PREALLOC_MAX (8) pages, trimmed back to PIPE_PREALLOC_KEEP (2) after each operation. tmp_page[2] is removed. Pages are still allocated and freed outside pipe->mutex; only the assignment into the pool is done under it. The pool count is also read locklessly in the prefill path, so it is annotated __data_racy. anon_pipe_prefill_and_lock() tops the pool up to the write's page count -- and returns with pipe->mutex held, so a write acquires the lock only once. anon_pipe_trim_and_unlock() trims the pool under that same lock before dropping it, then frees the excess. Signed-off-by: Breno Leitao <leitao@debian.org> Link: https://patch.msgid.link/20260720-b4-pipe-unification-v5-1-9002a3fe5e6d@debian.org Reviewed-by: Mateusz Guzik <mjguzik@gmail.com> Reviewed-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31fs: annotate inode timestamp accessorsYu Peng2-10/+10
syzbot reported a KCSAN race between fill_mg_cmtime() and inode_set_ctime_to_ts() on inode->i_ctime_{sec,nsec}. stat/getattr can sample inode timestamps while update paths store new values concurrently, so KCSAN can report benign races on these fields. Annotate the timestamp accessors with READ_ONCE()/WRITE_ONCE(), and use the ctime accessor for the remaining ctime loads. This avoids the KCSAN reports without changing timestamp semantics. Fixes: 4e40eff0b573 ("fs: add infrastructure for multigrain timestamps") Reported-by: syzbot+8b3bd9f8a06658479d4a@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=8b3bd9f8a06658479d4a Signed-off-by: Yu Peng <pengyu@kylinos.cn> Link: https://patch.msgid.link/20260708080232.2564807-1-pengyu@kylinos.cn Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31eventpoll: compute timer slack lazily in ep_poll()Usama Arif1-2/+4
ep_poll() computes the timer slack via select_estimate_accuracy() up front, before checking whether events are already available. select_estimate_accuracy() reads the clock (ktime_get_ts64()), and the resulting slack is only consumed by the schedule_hrtimeout_range() call on the blocking path. A busy poller such as an L7 proxy event loop calls epoll_wait() at a very high rate and often finds events already pending, returning via ep_try_send_events() without ever blocking. In that case the up-front slack estimation - including its clock read - is pure overhead. read_tsc() attributable to select_estimate_accuracy() sometimes shows up in perf profiles of such a workload via the epoll_wait() path. Move the slack estimation to the point where the thread is actually about to sleep. The timeout passed to ep_poll() is already an absolute deadline (ep_timeout_to_timespec()), so deferring the estimate does not change the wakeup time; taken closer to the sleep it is, if anything, marginally more accurate. On the common non-blocking path the clock read is skipped entirely. Measured on a host running a Meta production workload with the following bpftrace script: #!/usr/bin/bpftrace fentry:__x64_sys_epoll_wait, fentry:__x64_sys_epoll_pwait { @in[tid] = 1; } fexit:__x64_sys_epoll_wait, fexit:__x64_sys_epoll_pwait { delete(@in, tid); } fentry:select_estimate_accuracy /@in[tid]/ { @sea++; } fentry:schedule_hrtimeout_range /@in[tid]/ { @shr++; } interval:s:30 { printf("sea=%lld shr=%lld wasted=%lld (%d%%)\n", @sea, @shr, @sea - @shr, (@sea - @shr) * 100 / @sea); exit(); } Over a 30s window: sea=3,587,704 shr=3,003,920 wasted=583,784 (16%) So ~16% of ep_poll invocations of select_estimate_accuracy have no consumer. Signed-off-by: Usama Arif <usama.arif@linux.dev> Link: https://patch.msgid.link/20260707190238.3478608-1-usama.arif@linux.dev Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31put_mnt_ns(): leave mounts connectedNoah Orlando1-1/+1
When a mount namespace is destroyed, put_mnt_ns() disconnects its mounts from their mount points. A file descriptor still open on the parent of a mount point can then be used to look under the mount point. Locked mounts are kept connected to prevent this. However, a mount is only locked when its tree is copied across a user namespace boundary. A mount namespace set up by a privileged component has no locked mounts, so its mounts are disconnected. Pass UMOUNT_CONNECTED so every mount is kept connected, as locked mounts already are. Signed-off-by: Noah Orlando <Noah.Orlando@deshaw.com> Link: https://patch.msgid.link/20260706182559.2496448-2-Noah.Orlando@deshaw.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31affs: Move long delayed work on system_dfl_long_wqMarco Crivellari1-1/+1
Currently the code enqueue work items using {queue|mod}_delayed_work(), using system_long_wq. This workqueue should be used when long works are expected and it is a per-cpu workqueue. The function(s) end up calling __queue_delayed_work(), which set a global timer that could fire anywhere, enqueuing the work where the timer fired. Unbound works could benefit from scheduler task placement, to optimize performance and power consumption. Long work shouldn't stick to a single CPU. Recently, a new unbound workqueue specific for long running work has been added:     c116737e972e ("workqueue: Add system_dfl_long_wq for long unbound works") Since the workqueue work doesn't rely on per-cpu variables, there is no obvious reason that justify the use of a per-cpu workqueue. So change system_long_wq with system_dfl_long_wq so that the work may benefit from scheduler task placement. Cc: David Sterba <dsterba@suse.com> Cc: linux-fsdevel@vger.kernel.org Signed-off-by: Marco Crivellari <marco.crivellari@suse.com> Link: https://patch.msgid.link/20260706105443.173697-6-marco.crivellari@suse.com Acked-by: David Sterba <dsterba@suse.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31hfs: Move long delayed work on system_dfl_long_wqMarco Crivellari1-1/+1
Currently the code enqueue work items using {queue|mod}_delayed_work(), using system_long_wq. This workqueue should be used when long works are expected and it is a per-cpu workqueue. The function(s) end up calling __queue_delayed_work(), which set a global timer that could fire anywhere, enqueuing the work where the timer fired. Unbound works could benefit from scheduler task placement, to optimize performance and power consumption. Long work shouldn't stick to a single CPU. Recently, a new unbound workqueue specific for long running work has been added:     c116737e972e ("workqueue: Add system_dfl_long_wq for long unbound works") Since the workqueue work doesn't rely on per-cpu variables, there is no obvious reason that justify the use of a per-cpu workqueue. So change system_long_wq with system_dfl_long_wq so that the work may benefit from scheduler task placement. Cc: Viacheslav Dubeyko <slava@dubeyko.com> Cc: John Paul Adrian Glaubitz Cc: Yangtao Li <frank.li@vivo.com> Cc: linux-fsdevel@vger.kernel.org Signed-off-by: Marco Crivellari <marco.crivellari@suse.com> Link: https://patch.msgid.link/20260706105443.173697-5-marco.crivellari@suse.com Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31hfsplus: Move long delayed work on system_dfl_long_wqMarco Crivellari1-1/+1
Currently the code enqueue work items using {queue|mod}_delayed_work(), using system_long_wq. This workqueue should be used when long works are expected and it is a per-cpu workqueue. The function(s) end up calling __queue_delayed_work(), which set a global timer that could fire anywhere, enqueuing the work where the timer fired. Unbound works could benefit from scheduler task placement, to optimize performance and power consumption. Long work shouldn't stick to a single CPU. Recently, a new unbound workqueue specific for long running work has been added:     c116737e972e ("workqueue: Add system_dfl_long_wq for long unbound works") Since the workqueue work doesn't rely on per-cpu variables, there is no obvious reason that justify the use of a per-cpu workqueue. So change system_long_wq with system_dfl_long_wq so that the work may benefit from scheduler task placement. Cc: Viacheslav Dubeyko <slava@dubeyko.com> Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> Cc: Yangtao Li <frank.li@vivo.com> Cc: linux-fsdevel@vger.kernel.org Signed-off-by: Marco Crivellari <marco.crivellari@suse.com> Link: https://patch.msgid.link/20260706105443.173697-4-marco.crivellari@suse.com Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31fs/jffs2: Move long delayed work on system_dfl_long_wqMarco Crivellari1-1/+1
Currently the code enqueue work items using {queue|mod}_delayed_work(), using system_long_wq. This workqueue should be used when long works are expected and it is a per-cpu workqueue. The function(s) end up calling __queue_delayed_work(), which set a global timer that could fire anywhere, enqueuing the work where the timer fired. Unbound works could benefit from scheduler task placement, to optimize performance and power consumption. Long work shouldn't stick to a single CPU. Recently, a new unbound workqueue specific for long running work has been added:     c116737e972e ("workqueue: Add system_dfl_long_wq for long unbound works") Since the workqueue work doesn't rely on per-cpu variables, there is no obvious reason that justify the use of a per-cpu workqueue. So change system_long_wq with system_dfl_long_wq so that the work may benefit from scheduler task placement. Cc: David Woodhouse <dwmw2@infradead.org> Cc: Richard Weinberger <richard@nod.at> Cc: linux-mtd@lists.infradead.org Signed-off-by: Marco Crivellari <marco.crivellari@suse.com> Link: https://patch.msgid.link/20260706105443.173697-3-marco.crivellari@suse.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31ufs: Move long delayed work on system_dfl_long_wqMarco Crivellari1-1/+1
Currently the code enqueue work items using {queue|mod}_delayed_work(), using system_long_wq. This workqueue should be used when long works are expected and it is a per-cpu workqueue. The function(s) end up calling __queue_delayed_work(), which set a global timer that could fire anywhere, enqueuing the work where the timer fired. Unbound works could benefit from scheduler task placement, to optimize performance and power consumption. Long work shouldn't stick to a single CPU. Recently, a new unbound workqueue specific for long running work has been added:     c116737e972e ("workqueue: Add system_dfl_long_wq for long unbound works") Since the workqueue work doesn't rely on per-cpu variables, there is no obvious reason that justify the use of a per-cpu workqueue. So change system_long_wq with system_dfl_long_wq so that the work may benefit from scheduler task placement. Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Kees Cook <kees@kernel.org> Cc: Eric Sandeen <sandeen@redhat.com> Signed-off-by: Marco Crivellari <marco.crivellari@suse.com> Link: https://patch.msgid.link/20260706105443.173697-2-marco.crivellari@suse.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-31romfs: detect hard link cycles이상호1-0/+8
romfs_iget() follows on-disk hard link entries until it reaches a non-hard link inode: pos = be32_to_cpu(ri.spec) & ROMFH_MASK; The target position is image-controlled, and the loop does not detect cycles. A crafted romfs image can make the root inode a hard link. The hard link can point back to itself and leave mount(2) spinning in the kernel. Reject excessive hard link indirection with -ELOOP. Normal romfs images do not need long hard link chains. This bounds corrupted-image traversal. Propagate romfs_iget() errors from lookup because hard link traversal can now fail with -ELOOP. Signed-off-by: 이상호 <kudo3228@gmail.com> Link: https://patch.msgid.link/20260701220729.822112-1-kudo3228@gmail.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-30fs/proc: use softleaf_has_pfn() in pagemap PMD walkerUsama Arif1-1/+2
pagemap_pmd_range_thp() assumes that every non-present PMD is a migration entry and unconditionally calls softleaf_to_page(). This will crash on any non-present PMD type that does not encode a PFN, such as the upcoming PMD-level swap entries. Guard the page lookup with softleaf_has_pfn(), matching how pte_to_pagemap_entry() already handles non-present PTEs. Link: https://lore.kernel.org/20260706114320.1643046-4-usama.arif@linux.dev Signed-off-by: Usama Arif <usama.arif@linux.dev> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Zi Yan <ziy@nvidia.com> Cc: Alexandre Ghiti <alex@ghiti.fr> Cc: Baolin Wang <baolin.wang@linux.alibaba.com> Cc: Baoquan He <baoquan.he@linux.dev> Cc: Barry Song <baohua@kernel.org> Cc: Chris Li <chrisl@kernel.org> Cc: Dev Jain <dev.jain@arm.com> Cc: "Huang, Ying" <ying.huang@linux.alibaba.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Kairui Song <kasong@tencent.com> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: Kiryl Shutsemau <kas@kernel.org> Cc: Lance Yang <lance.yang@linux.dev> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Nhat Pham <nphamcs@gmail.com> Cc: Nico Pache <npache@redhat.com> Cc: Rik van Riel <riel@surriel.com> Cc: Ryan Roberts <ryan.roberts@arm.com> Cc: Shakeel Butt <shakeel.butt@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2026-07-30Merge tag 'v7.2-rc5-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6Linus Torvalds9-87/+63
Pull smb client fixes from Steve French: - fix SMB1 read and write potential buffer leaks - netfs error handling fix - fix check for last write time in truncate and setattr and cleanup use of smb_store_release() - fscache fix and cleanup - validate idmap key payload length - minor SMB1 error mapping cleanup - witness protocol memory allocation fix * tag 'v7.2-rc5-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: cifs: add fscache_resize_cookie() to cifs_setsize() cifs: fix time_last_write stamp placement in setattr/truncate paths cifs: consolidate time_last_write stamp into _cifsFileInfo_put() smb: client: simplify cifs_fscache_get_super_cookie() smb: client: free partially allocated transform folio queue cifs: validate idmap key payload length smb: client: remove conditional return with no effect smb: client: fix buffer leaks in SMB1 read and write smb: client: use GFP_KERNEL for registry allocation
2026-07-30ksmbd: use memcmp() to compare ClientGUIDsNamjae Jeon1-2/+2
ClientGUID is a fixed-size binary value and can contain embedded NUL bytes. strncmp() stops comparing at the first NUL byte, so different ClientGUID values can incorrectly be treated as equal. Use memcmp() in SMB3 multichannel session binding and FSCTL_VALIDATE_NEGOTIATE_INFO to compare all SMB2_CLIENT_GUID_SIZE bytes. Fixes: f5a544e3bab7 ("ksmbd: add support for SMB3 multichannel") Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Reported-by: Samu <nomomentomori@gmail.com> Suggested-by: Samu <nomomentomori@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-30ksmbd: reject repeated SMB2 NEGOTIATE requestsNamjae Jeon3-15/+37
Unauthenticated client can send multiple successful SMB2 NEGOTIATE requests on one connection before SESSION_SETUP. While the connection is in KSMBD_SESS_NEED_SETUP, smb2_handle_negotiate() accepts another SMB3.1.1 NEGOTIATE and overwrites conn->preauth_info with a new allocation. Only the final allocation is freed when the connection is released, leaking one object for every additional successful request. A repeated SMB2 NEGOTIATE after a dialect has been selected is a protocol violation. MS-SMB2 section 3.3.5.4 requires the server to disconnect without replying in this case. Set the connection exiting when rejecting the request, in addition to suppressing the response. Reject SMB2 NEGOTIATE unless the connection is new or is waiting for the SMB2 NEGOTIATE that follows an SMB1 multi-protocol negotiate. Serialize both SMB1 and SMB2 negotiation paths under conn->srv_mutex, since they update connection-wide dialect and negotiation state. Move the locking contract to ksmbd_smb_negotiate_common(), where the state and dialect are selected, and add ksmbd_conn_new() for consistent state access. Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Cc: stable@vger.kernel.org Reported-by: Runa Takemoto <takemotoruna223@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-30ksmbd: fix use-after-free in __close_file_table_ids()Namjae Jeon1-0/+2
A ksmbd_file can remain alive after logical close while another session holds a temporary reference obtained through ksmbd_lookup_fd_inode(). ksmbd_close_fd() currently marks the file closed and drops the idr-owned reference, but leaves the pointer published in the closing session's idr until the final reference is dropped. If the foreign holder performs the final ksmbd_fd_put(), __put_fd_final() supplies the foreign session's file table to __ksmbd_close_fd(). The object is then freed without being removed from its owner's idr, and the owner session later dereferences the stale pointer during file-table teardown. Remove the volatile id from the owner's idr while ksmbd_close_fd() still holds that table's lock, and clear volatile_id before dropping the idr-owned reference. A later foreign final put then only performs physical destruction and cannot remove the object from the wrong table. Fixes: 8510a043d334 ("ksmbd: increment reference count of parent fp") Reported-by: Yunseong Kim <yunseong.kim@est.tech> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
2026-07-30btrfs: trigger cow fixup via dirty_folio()Boris Burkov7-12/+578
The problem scenario: If we have a folio mmapped shared and then somebody does a dio read with that folio as the read destination, then it is possible that the dio will see a dirty destination page when it starts (and thus skip dirtying and just GUP pin it) but then while it is doing the read, btrfs finishes writing it back and by the endio, the folio is clean. In that case, the dio read must re-dirty the folio with aops->dirty_folio(): btrfs_check_read_bio() |- __iomap_dio_bio_end_io() from btrfs_bio_end_io() |- bio_check_pages_dirty() |- bio_dirty_fn() |- bio_release_pages(bio, true) |- __bio_release_pages(bio, mark_dirty == true) |- folio_lock() |- folio_mark_dirty() |- aops->dirty_folio() |- folio_unlock() A data block normally moves through writeback as follows: TASK folio_lock write clean -> dirty bit + delalloc folio_unlock WRITEBACK for-each-dirty-folio: folio_lock run_delalloc delalloc consumed -> dirty bit + OE submission dirty bit consumed -> writeback bit + OE folio_unlock ENDIO endio OE bytes accounted OE finish writeback -> clean; destroy OE Three critical invariants that this path maintains are: I1. Any dirty block is covered by delalloc xor an ordered extent I2. Any dirty block covered by an OE will be submitted into that OE I3. Any dirty block already submitted into an OE will not be submitted again into the same OE. These ensure that the block will be written exactly once. It is clear that not reserving delalloc for the re-dirty case violates I1. This situation, even without bs < folio_size, has long required btrfs to fixup such dirty pages during writeback with an asynchronous worker that is allowed to do this expensive work and writeback does not proceed for a folio while it is doing this work. Commit 247e743cbe6e ("Btrfs: Use async helpers to deal with pages that have been improperly dirtied") introduced the COW fixup to catch exactly this class at writeback, way back in 2008. Since then, there have been many advances to prevent most of the causes of such re-dirtying and we thought we could get away with removing the annoying cow-fixup in the hope of simplifying writeback for large folio support. Commit b2a9f217ad3f ("btrfs: remove the COW fixup mechanism") Commit 4927b141877c ("btrfs: remove folio ordered flag and subpage bitmap") Since it turns out this assumption was incorrect, as evidenced by the report and attendant reproducers, we must reintroduce the fixup concept. This is of course critically further complicated by bs < folio_size. In that case, rather than just a folio dirty bit, we have a bitmap for the dirty blocks in the folio. And the (also broken) invariant is: I4. folio dirty IFF at least one block bitmap dirty. The original report of a stall on a misinterpreted empty bitmap is exactly evidence of a violation of I4. It is exactly because of bs < folio_size we don't want to simply revert the removal patches. The original fixup was not properly bs < folio_size aware, which motivated removal in the first place. So we wish to build a bs < folio_size aware fixup. One other important detail from the old design, any normal write that happens after a re-dirty but before a fixup is racing with the cow fixup to do the delalloc reservation, therefore it must cancel the fixup state. If it arrives after the reservation exists, it will be a normal dirty overwrite. This critically informs the design in a pretty clear way. fixup requiring re-dirty has folio granularity, while cancellation has delalloc (block) granularity so while we only ever produce fixup in chunks of folios, we must be able to clear it in blocks. Therefore we must track the blocks needing fixup at block granularity. The obvious way to do this is with a new bitmap in btrfs_folio_state, but it is desirable to avoid that if possible. Unfortunately, I don't think it is possible and the reason is subtle and leans on a sort of extreme reproducer, but I think can be explained relatively succinctly. Consider a folio whose two halves will land in different ordered extents (can be accomplished with tricks using nodatasum) and a dio read is running with it as the shared mmap destination. 1. The front half: a. folio comes clean on a normal write b. dio read completes into the folio marking it fixup. c. a write comes for the previous folio for a range extending into this folio, this is a cancellation of the fixup which reserves space. d. writeback runs on the range *not* overlapping the folio. This half remains dirty but is now covered by an OE and is awaiting writeback running on its range to be submitted and finish the OE. 2. The back half: a. the folio is part of an OE that gets far enough along to clear writeback. b. dio read completes into the folio marking it fixup. After this, the folio's front half is dirty in the "normal" sense, it needs to be submitted to the OE waiting for it. It's a cancelled fixup. Meanwhile, the second half is a true fresh fixup. So at this point if we run writeback on this folio, we genuinely can't know what to do without block level information. If we submit it, we submit unreserved dirty from the back half. If we don't, we will never finish the OE waiting for it. So it's either a corruption or a deadlock. Thus, the full high level design picture: - btrfs_data_dirty_folio(): For out of band non-reserving dirties, mark still-clean blocks inside EOF dirty and set their fixup bits (the event carries no range, so every clean block is suspect). Already-dirty blocks are covered or pending and are left alone. - Writeback: skip fixup blocks and enqueue work for them - writepage_fixup(): for each fixup block do the fixup reservation in a worker, after which the blocks can be written back normally. - Typical reserving write paths cancel fixup state for the ranges they cover with btrfs_folio_cancel_fixup() Link: https://lore.kernel.org/linux-btrfs/20260721191152.101118-1-borntraeger@linux.ibm.com/ Assisted-by: LLM Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Boris Burkov <boris@bur.io> Signed-off-by: David Sterba <dsterba@suse.com>
2026-07-30ext4: protect WRITE_ZEROES written extents with orphan listZhang Yi1-7/+69
In ext4_alloc_file_blocks(), the WRITE_ZEROES path converts unwritten extents to written in one transaction, while i_disksize is updated to cover them only in a later transaction. A crash in between leaves written extents beyond i_disksize on disk, which fsck will complain about. To fix this, add the inode to the orphan list in the same handle that does the conversion, and remove it once i_disksize has caught up. Also add a sanity check to ensure conversion does not extend beyond EOF. Since ext4_alloc_file_blocks() is called from the fallocate() path, partial allocation is safe. On partial conversion failure, advance i_disksize only up to the boundary of successfully converted blocks, so that orphan cleanup sees a consistent state. Document this behavior in the function comment. Reported-by: Jan Kara <jack@suse.cz> Closes: https://lore.kernel.org/linux-ext4/3f6ao5amv7glbgigndtegcucgo3n34ij3lau6l3da3hgdxgn3v@ev66wv3r5umt/ Fixes: f4265b8d32c4 ("ext4: add FALLOC_FL_WRITE_ZEROES support") Cc: stable@vger.kernel.org Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20260729085918.3336221-3-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-30ext4: export converted block count from ext4_convert_unwritten_extents()Zhang Yi3-21/+38
ext4_convert_unwritten_extents() currently returns only a success or a failure indication. A zero return means all requested blocks were converted, and a negative value means the conversion failed. However, some blocks may have already been converted when the function fails partway through, and callers have no way to learn how many were done. The WRITE_ZEROES caller in ext4_alloc_file_blocks() needs this information to decide whether to add the inode to the orphan list before updating i_disksize to cover the already-converted written extents, so that a crash before i_disksize catches up can be recovered via orphan truncation. Switch the function to pass out the number of converted blocks through the new output parameter @converted, which will be used by later patches. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20260729085918.3336221-2-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-30ext4: fix incorrect function call when initializing s_resgidJiazi Liu1-1/+1
In __ext4_fill_super(), s_resgid is initialized by calling ext4_get_resuid() instead of ext4_get_resgid(), resulting in the reserved GID being set to the same value as the reserved UID rather than the value stored in the superblock. Fixes: 12c84dd4d308 ("ext4: add support for 32-bit default reserved uid and gid values") Cc: stable@vger.kernel.org Signed-off-by: Jiazi Liu <liujiazi@amazon.com> Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com> Link: https://patch.msgid.link/20260727104103.28916-1-liujiazi@amazon.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-30ext4: validate EA inode i_nlink in ext4_xattr_inode_igetYun Zhou1-0/+15
Validate EA inode state in ext4_xattr_inode_iget() to reject corrupted EA inodes early, before they trigger WARN_ONCE in ext4_xattr_inode_update_ref(). When a corrupted ext4 image has an EA inode with inconsistent i_nlink and ref_count values (e.g. i_nlink=65535), the code currently allows it through and later hits WARN_ONCE when ref_count transitions cross the 0/1 boundary. This is better handled as an early sanity check that returns -EFSCORRUPTED, consistent with how ext4 treats other on-disk corruption. Since ext4_xattr_inode_iget() resolves references from active xattr entries, the target EA inode must be in active state (i_nlink=1, ref_count>0). Reject any inode that does not satisfy this. Reported-by: syzbot+76916a45d2294b551fd9@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=76916a45d2294b551fd9 Fixes: dec214d00e0d ("ext4: xattr inode deduplication") Signed-off-by: Yun Zhou <yun.zhou@windriver.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20260724100255.144768-1-yun.zhou@windriver.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2026-07-30udf: Fix data loss when converting inline inodes to out of lineJan Kara1-2/+13
When udf_expand_file_adinicb() converts file from inline format to out of line, we use filemap_fdatawrite() to writeout the data to the new blocks. However since 36580ed08776 ("udf: Do not allocate blocks on page writeback") the writeback actually doesn't allocate the new block and the folio dirty bit is just silently cleared. Thus unless the file is written to after the conversion (as it can easily happen in case of truncate up), the data is just lost. Fix the problem by explicitely allocating the block underlying the data before starting writeback. Fixes: 36580ed08776 ("udf: Do not allocate blocks on page writeback") CC: stable@vger.kernel.org Link: https://patch.msgid.link/20260730104232.4086759-4-jack@suse.cz Signed-off-by: Jan Kara <jack@suse.cz>
2026-07-30udf: Move udf_map_block() upJan Kara1-59/+59
Move udf_map_block() in the file to avoid forward declarations. Link: https://patch.msgid.link/20260730104232.4086759-3-jack@suse.cz Signed-off-by: Jan Kara <jack@suse.cz>
2026-07-30fs/namei.c: update kerneldoc of atomic_open()Jori Koolstra1-9/+17
The comments above atomic_open() contain several errors: - atomic_open() does not return 0 if successful - @path is not updated Fix those and be more explicit about when FMODE_OPENED and FMODE_CREATED are set. Change to a full kerneldoc. Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl> Link: https://patch.msgid.link/20260710164233.827744-4-jkoolstra@xs4all.nl Reviewed-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-30vfs: call audit_inode_child() in lookup_open() on failureJori Koolstra1-36/+56
audit_inode_child() is called in may_create_dentry() so that failed filesystem operations still register an audit entry. On success, the entry is overwritten when, for instance, fsnotify_create() is called. This is the calling convention in vfs_create() and vfs_mkdir(). In lookup_open(), however, when atomic_open() should have created a file but didn't, no call to audit_inode_child() is made. The same is true for the regular ->create() path. Fix the calling of audit_inode_child() in lookup_open() to match the vfs_create() path. For the ->atomic_open() filesystems this logic has been pushed into atomic_open(). This function is also reordered a bit to make the case distinction of the possible returns from ->atomic_open() more explicit (i.e. finish_open() or finish_no_open()). When retrying delegation breaking, audit_inode_child() could be called more than once, but this is OK because those entries are reused. Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl> Link: https://patch.msgid.link/20260710164233.827744-3-jkoolstra@xs4all.nl Acked-by: Paul Moore (audit) <paul@paul-moore.com> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-30vfs: move create error && negative dentry case in lookup_open() upJori Koolstra1-4/+5
O_CREAT is stripped when create_error is set in lookup_open(), so when lookup does not return an inode, the case if (!dentry->d_inode && (open_flag & O_CREAT)) is always skipped. We can get rid of this cognitive step by handling the error case first. Reviewed-by: NeilBrown <neil@brown.name> Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl> Link: https://patch.msgid.link/20260710164233.827744-2-jkoolstra@xs4all.nl Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-07-30fanotify: stop permission watchdog when timeout is zeroYichong Chen1-1/+6
The fanotify permission watchdog can be disabled by writing zero to fs/fanotify/watchdog_timeout. fanotify_perm_watchdog_group_add() already checks for a zero timeout before scheduling the watchdog. However, once the watchdog work has been scheduled, perm_group_watchdog() unconditionally schedules itself again with the current timeout. If the sysctl is changed to zero while the work is active, secs_to_jiffies(0) causes the work to be rescheduled immediately, resulting in a kworker busy loop. Read the timeout once in perm_group_watchdog_schedule() and do not schedule the work when it is zero. This lets a running watchdog stop after the next execution when the sysctl is set to zero. Fixes: b8cf8fda522d ("fanotify: add watchdog for permission events") Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Link: https://patch.msgid.link/20260730070648.549458-1-chenyichong@uniontech.com Signed-off-by: Jan Kara <jack@suse.cz>
2026-07-30fs/ntfs3: Add basic support for alternative data streamsKonstantin Komarov11-184/+684
An ADS (alternative data stream) is a named $DATA (0x80) attribute. Until now ntfs3 ignored named data attributes entirely, so the only stream reachable from userspace was the unnamed one. Introduce a colon-delimited name syntax so streams can be reached through the regular VFS interfaces. ntfs_nls_to_utf16() now splits a lookup name at ':' and stores the stream part in cpu_str::ads_len (the previously unused padding byte). ntfs_iget5_flags() first instantiates the base inode, then allocates a second inode whose ->base points at it and whose ->file.ads holds the stream name. ntfs_test_inode() compares the stream name as well as the MFT reference, so base and streams get distinct inodes for the same record. Because the MFT record belongs to the base inode, the many helpers in frecord.c and attrlist.c that operate on the record redirect to ni->base, and ni_lock() and friends take the base inode's mutex. The attrib.c paths that used to hardcode an unnamed $DATA lookup now pass ni->file.ads.{name,len}. ni_write_inode() and ni_write_parents() are no-ops for stream inodes, and ntfs_setattr() drops ATTR_SIZE for them. Usage, for a file with streams 'ads1' and 'ads2': cat file:query_streams - list stream names, one per line cat file:ads1 - read a stream touch file:ads3 - create a stream on an existing file rm file:ads1 - remove a stream The pseudo-stream 'query_streams' is handled in ntfs_file_read_iter() via ni_query_ads(), which enumerates named $DATA attributes and returns their names separated by '\n'. The feature is controlled by the new 'ads' mount option, enabled by default; mount with 'ads=0' to restore the previous behaviour. Not implemented yet: - creating a file and a stream in a single call - renaming (moving) a stream Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
2026-07-30fs/ntfs3: Rename 'err' to 'ret' in read pathsKonstantin Komarov1-20/+21
ntfs_file_read_iter() and ntfs_file_splice_read() store both error codes and the number of bytes transferred in a variable named 'err', which is misleading on the success path. Rename it to 'ret'. While here, rename the 'in' parameter of ntfs_file_splice_read() to 'file' for consistency with the rest of the file, and add a local 'ni' instead of calling ntfs_i() inline. Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
2026-07-30fs/ntfs3: Fix memory leak in indx_find_sort()Konstantin Komarov1-0/+1
When popping a level from the index lookup stack, indx_find_sort() frees the struct indx_node but not the index buffer it owns. Every call that descends and then pops a level leaks that allocation. Free n->index before freeing the node itself. Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
2026-07-29ext2: Simplify error handling of IO error when adding xattrJan Kara1-9/+5
When we fail to write out inode when adding new xattr block, we backed out some changes (like quota modifications) but left others (like block allocation or inode xattr block modification). Just leave the inode intact in this case because we can hardly reach a consistent state and defer fixing to e2fsck. Also remove outdated comment and special data handling since sync_inode_metadata() does not write out any data. Link: https://patch.msgid.link/20260728154724.3934977-2-jack@suse.cz Signed-off-by: Jan Kara <jack@suse.cz>
2026-07-29fs/ntfs3: bound page_lcns[] index by the log recordKonstantin Komarov1-0/+15
The copy_lcns loop and the redo shorten loop index page_lcns[] at j + i, where i runs up to the log record's lcns_follow. That count is checked only against the record's own length, not the target entry, so check_dp_table() (which validates the entry's lcns_follow) does not cover it: the copy_lcns entry may even be freshly allocated after that check, and find_dp() bounds j but not i. A crafted record thus overflows page_lcns[] of an otherwise valid entry. Add dp_range_ok() and reject, before each loop, any record whose run does not fit the entry. These are the only two page_lcns[] accesses indexed by the record rather than the entry, so together with the entry validation every access is now bounded. Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal") Cc: stable@vger.kernel.org Reported-by: Weiming Shi <bestswngs@gmail.com> Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Xiang Mei <xmei5@asu.edu> [almaz.alexandrovich@paragon-software.com: original patch contained changes to the problem already handled, applied partly] Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
2026-07-29fs/ntfs3: validate dirty page table on log replayXiang Mei1-0/+19
Each DIR_PAGE_ENTRY ends in a page_lcns[] array whose length is the on-disk lcns_follow field. check_rstbl() validates the table bookkeeping but never checks that this array fits in the entry, so a crafted lcns_follow lets the v0->v1 conversion memmove and later replay passes run off the entry. Add check_dp_table() to reject, right after check_rstbl(), any entry larger than its size claims via struct_size() (the same expression used to allocate these entries, so the check is overflow-safe by construction). All consumers can then trust lcns_follow as the real capacity. This covers every page_lcns[] access whose index is bounded by the entry itself (the conversion memmove, the HotFix store via find_dp(), and the self-bounded scan loops). Accesses whose index comes from the log record need a separate bound and are handled in a follow-up patch. Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal") Cc: stable@vger.kernel.org Reported-by: Weiming Shi <bestswngs@gmail.com> Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Xiang Mei <xmei5@asu.edu> Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
2026-07-29isofs: Drop support of directory entries straddling blocksJan Kara2-52/+11
Based on isofs standard (ECMA-119) directory entries are not allowed to straddle sector boundaries. Isofs images I have available seem to follow this. Now that we have code verifying validity of directory entries (and so we'd properly refuse such entries), let's just drop the code merging directory entries straddling sector boundaries. Acked-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Jan Kara <jack@suse.cz>
2026-07-29exfat: clean up new entry on add entry failureYichong Chen1-1/+16
exfat_add_entry() initializes a new directory entry set before writing it with exfat_put_dentry_set(). If the write fails, mkdir/create returns an error but a partially written entry may be left behind. For non-zero-size directories, the failure also happens after a cluster has been allocated for the new directory. Clean up the new entry best-effort, and free the newly allocated directory cluster only when the cleanup writeback succeeds. This avoids freeing a cluster that may still be referenced by an on-disk entry if the cleanup fails. Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
2026-07-28fs,fsverity: remove check for fsverity being enabled in setattr_prepare()Andrey Albershteyn1-1/+1
The check that fs-verity is available in the kernel is not necessary here. Filesystems could have fsverity files even without fs-verity enabled. In that case, truncate on fsverity file will succeed, what this check is trying to prevent. Fixes: e9734653c523 ("fs,fsverity: reject size changes on fsverity files in setattr_prepare") Cc: stable@vger.kernel.org Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Link: https://patch.msgid.link/20260727094352.1734826-1-aalbersh@kernel.org Signed-off-by: Eric Biggers <ebiggers@kernel.org>
2026-07-28fscrypt: use the mount idmap for the owner check in fscrypt_ioctl_set_policy()Zhan Xusheng1-1/+1
fscrypt_ioctl_set_policy() calls inode_owner_or_capable() with &nop_mnt_idmap before allowing an encryption policy to be set, instead of the idmap of the mount the ioctl was issued on. fscrypt is used by filesystems that support idmapped mounts (e.g. ext4, f2fs), so on such a mount this compares the caller's fsuid against the unmapped on-disk owner rather than the mapped owner: the actual owner can be wrongly denied with -EACCES and an unrelated caller wrongly allowed. Use file_mnt_idmap(filp) instead. Fixes: 14f3db5542e6 ("ext4: support idmapped mounts") Cc: stable@vger.kernel.org Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com> Link: https://patch.msgid.link/20260725080004.929328-1-zhanxusheng1024@gmail.com Signed-off-by: Eric Biggers <ebiggers@kernel.org>
2026-07-28nilfs2: fix BUG in nilfs_copy_dirty_pages() on dirty state mismatchRyusuke Konishi1-2/+15
Syzbot reported a kernel BUG triggered within nilfs_copy_dirty_pages(), which copies dirty DAT file folios/pages to its shadow page cache. The BUG occurs when a retrieved dirty folio/page unexpectedly loses its 'dirty' status. This issue arises because, since the commit referenced below, the 'dirty' flag of a folio/page can be cleared asynchronously after the filesystem detects metadata corruption and transitions to read-only mode. Resolve the issue by returning an -EROFS error if the filesystem has transitioned to read-only mode. Also change the behavior to issue a kernel warning only once instead of triggering a kernel BUG when this unexpected 'dirty' state is detected while the filesystem is not in read-only mode. Reported-by: syzbot+8baf9a79a3ffc6271cb6@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=8baf9a79a3ffc6271cb6 Fixes: 8c26c4e2694a ("nilfs2: fix issue with flush kernel thread after remount in RO mode because of driver's internal error or metadata corruption") Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com> Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
2026-07-28nilfs2: prevent out-of-bounds read in super root block parsingDavid Lee1-0/+6
super-root inode metadata size is trusted before nilfs_read_inode_common(). Reject super-root inode sizes whose computed on-disk footprint exceeds the filesystem block size. This prevents malformed filesystem images from making nilfs_read_inode_common() read past the end of the super-root block. [ryusuke: clarify the commit title] Fixes: 8a9d2191e9f4 ("nilfs2: operations for the_nilfs core object") Signed-off-by: David Lee <david.lee@trailofbits.com> Assisted-by: Codex:gpt-5.5 Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com> Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
2026-07-28nilfs2: fix infinite loop in nilfs_clean_segments()Joshua Crofts1-0/+4
syzbot reported a hung task in nilfs_transaction_begin(). This occurs because the cleaner ioctl falls into an infinite loop if nilfs_segctor_construct() repeatedly returns -EROFS (e.g. the device is remounted as read-only after an I/O error). Currently in nilfs_clean_segments(), if err is non-zero, it logs the error and sleeps but doesn't abort when it encounters a terminal error like -EROFS. This causes the thread to loop forever. Fix this by breaking out of the loop if nilfs_segctor_construct() returns -EROFS. This matches the behaviour in nilfs_segctor_write_out(), which also handles -EROFS. Reported-by: syzbot+cae54346a70bbceeff2c@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=cae54346a70bbceeff2c Fixes: 9ff05123e3bf ("nilfs2: segment constructor") Assisted-by: gemini:gemini-3.1-pro Signed-off-by: Joshua Crofts <joshua.crofts1@gmail.com> Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com> Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
2026-07-28nilfs2: fix slab-out-of-bounds in nilfs_direct_propagate after truncationRyusuke Konishi4-11/+36
Shuangpeng Bai reported that KASAN detected a slab-out-of-bounds error in nilfs_direct_propagate() during testing. Analysis revealed that after truncating a file, a node block immediately below the B-tree root was not deleted. Instead, it remained in the B-tree node cache in a dirty state. The log writer subsequently detected this block and incorrectly invoked nilfs_direct_propagate() on it, which is designed to handle only data blocks in direct mapping. B-tree nodes in the cache are managed by virtual block numbers, and their logical keys typically exceed the range expected by direct mapping. Consequently, processing such a node as a direct mapping entry triggers a slab-out-of-bounds access. The root cause is that when a B-tree mapping collapses into a direct mapping during truncation, an intermediate node block pointed to by the root node is left behind as garbage instead of being explicitly deleted. This resolves the issue by adding a nilfs_btree_discard() operation to delete the remaining intermediate node block during the conversion. A 'deform' flag is added to the bop_delete interface to explicitly signal that the deletion is part of a mapping transformation. This allows the B-tree mapping implementation to perform the necessary cleanup and discarding of the residual node structure that would be otherwise be left orphaned after the transition. Reported-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com> Closes: https://lore.kernel.org/r/08A3603A-ADB6-484C-9015-9AC1340E6FB8@gmail.com Fixes: 36a580eb489f ("nilfs2: direct block mapping") Cc: stable@vger.kernel.org Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com> Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>