aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/fs/xfs/libxfs
AgeCommit message (Collapse)AuthorFilesLines
2026-09-17xfs: fix wild memcpy access when formatting ondisk rtrefcount btree rootsDarrick J. Wong1-2/+2
LOLLM noticed that the inode btree root formatting methods copy too many bytes -- there's only one set of keys in node blocks, not two. This causes memory corruption of whatever's beyond the buffers. Cc: stable@vger.kernel.org # v6.14 Fixes: f0415af60f482a ("xfs: wire up a new metafile type for the realtime refcount") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Assisted-by: LOLLM # finding obvious bugs Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-17xfs: don't let hidden_space go negative in xfs_metafile_resv_initDarrick J. Wong1-4/+4
LOLLM points out that if the amount of fdblocks that we can reserve for a metadata btree file goes below the space already used by that file, then the hidden_space subtraction can underflow, causing xfs_dec_fdblocks to subtract a huge amount of space. We never want the target to be less than the used sapce, so fix the logic that adjusts dblocks_avail downwards. Also fix an error in the adjacent comment. Cc: stable@vger.kernel.org # v6.15 Fixes: 1df8d75030b787 ("xfs: make metabtree reservations global") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Assisted-by: LOLLM # finding obvious bugs Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-15xfs: fix typos and repeated words in commentsHemanth Selam7-8/+8
Correct ten misspellings and eight accidentally doubled words in comments. No code changes. The doubled word in xfs_zone_alloc.c was not a duplicate: "so that is is reused" is "it is" misspelt, so that one reads "so that it is reused" rather than dropping a word. Signed-off-by: Hemanth Selam <hemanth.selam@gmail.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-15xfs: remove duplicate INO1_WRITTEN checkJiangshan Yi1-10/+0
Commit a23eca88448e ("xfs: fix exchange-range reflink flag clearing issue with INO1_WRITTEN") duplicated commit b2d5a81dae38 ("xfs: fix exchange-range reflink flag clearing issue with INO1_WRITTEN"), so xmi_can_exchange_reflink_flags() ended up with two identical XFS_EXCHMAPS_INO1_WRITTEN checks. The second one is dead code, since the first one already returned false. Remove it. Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-11xfs: fix under-reservation of blocks when repairing sf directoriesDarrick J. Wong2-1/+3
Whilst running QA on XFS for-next as of 7.3-rc2 with MKFS_OPTIONS="-n size=8192", I observed the following (trimmed) dmesg splat: XFS: Assertion failed: args->total >= dp->i_nblocks - nblks, file: fs/xfs/libxfs/xfs_da_btree.c, line: 2387 WARNING: fs/xfs/xfs_message.c:104 at assfail+0x46/0x4a [xfs], CPU#0: xfs_scrub/1426511 CPU: 0 UID: 0 PID: 1426511 Comm: xfs_scrub Tainted: G W 7.3.0-rc2-djwx #rc2 PREEMPT(lazy) 6e418570b606a39783b0e7e7b30dc407b965f9e8 Tainted: [W]=WARN RIP: 0010:assfail+0x46/0x4a [xfs] RSP: 0018:ffffc900010d7890 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00000000ffffffd1 RDX: 0000000000000000 RSI: 0000000000000021 RDI: ffffffffa059fd38 RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000 R10: 000000000000000a R11: 000000007fffffff R12: ffffc900010d7940 R13: ffff888368d8f980 R14: ffffc900010d7a48 R15: ffffc900010d78d0 FS: 00007f445c5ce680(0000) GS:ffff8884a97ea000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f443803b9a8 CR3: 0000000107a4b000 CR4: 00000000003506f0 Call Trace: <TASK> xfs_da_grow_inode_int+0x2e0/0x300 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c] xfs_dir2_grow_inode+0x6e/0x150 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c] xfs_dir2_sf_to_block+0x149/0x870 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c] xrep_dir_swap_prep+0xe2/0x110 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c] xrep_dir_swap+0xfb/0x2f0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c] xrep_dir_rebuild_tree+0x99/0x100 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c] xrep_directory+0x83/0x1c0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c] xrep_attempt+0x4f/0x1e0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c] xfs_scrub_metadata+0x393/0x5b0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c] xfs_ioc_scrubv_metadata+0x306/0x570 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c] xfs_file_ioctl+0xa4f/0x1150 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c] __x64_sys_ioctl+0x76/0xc0 do_syscall_64+0x7a/0x3b0 entry_SYSCALL_64_after_hwframe+0x4b/0x53 This is a consequence of commit 0fe77e57588b98, which added the following assertion to xfs_da_grow_inode_int: ASSERT(args->total >= dp->i_nblocks - nblks); Tracing this back to xrep_dir_swap_prep, I noticed that the xfs_da_args object that's passed to xfs_dir2_sf_to_block sets args->total to 1. This is incorrect because mkfs set the directory block size to 8k and the filesystem block size to 4k. In other words, args->total should be 2 here, not 1. Dave Chinner tripped over the same problem with the same branch through a different channel -- his test setup set the fs block size to 1k, in which case the directory block size is still set to 4k. Here, args->total should be 4. Changing the assignment of args->total to sc->mp->m_dir_geo->fsbcount makes the assertion go away, but that isn't a complete fix. In xrep_tempexch_estimate, we also incorrectly assume that a shortform conversion requires 1 fsblock when it should be m_dir_geo->fsbcount. Without that, we can under-reserve space in the transaction and cause a filesystem shutdown. Note that the xfs_dabuf_nfsb helper will compute the correct value for directories and xattr, so we use that instead of open-coding the logic. Also fix xrep_xattr_swap_prep to assign args->total via xfs_dabuf_nfsb to avoid one logic bomb if we ever support multi-fsblock attrs. Cc: stable@vger.kernel.org # v6.10 Cc: floss@jetm.me Reported-by: dgc@kernel.org Fixes: 629fdaf5f5b1b7 ("xfs: use atomic extent swapping to fix user file fork data") Tripped-by: 0fe77e57588b98 ("xfs: assert the reservation covers each da fork growth") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-07xfs: don't leak new_bp if xfs_btree_bload_drop_buf failsDarrick J. Wong1-1/+3
LOLLM observes that in xfs_btree_bload_prep_block, xfs_btree_bload_drop_buf can hit an IO error if writing the delwri buffer list to disk fails. In this case, we fail to release new_bp, which means we lose a locked buffer. Fix that. Cc: stable@vger.kernel.org # v6.8 Fixes: e069d549705e49 ("xfs: constrain dirty buffers while formatting a staged btree") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Assisted-by: LOLLM # finding obvious bugs Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-07xfs: preserve owner on in-memory btree creationDarrick J. Wong1-0/+2
LOLLM points out a minor bug where a higher level function creating an in-memory btree is required to pass in an owner number, but the creation function erases that. In-memory btrees are ephemeral so this really doesn't matter except for debugging. But let's fix this papercut. Cc: stable@vger.kernel.org # v6.9 Fixes: a095686a238352 ("xfs: support in-memory btrees") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Assisted-by: LOLLM # finding obvious bugs Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-07xfs: fix xfs_rtrmapbt_mem_cursor for non-rmap filesystemsDarrick J. Wong1-1/+1
It's possible to construct an in-memory rtrmap btree for filesystems that don't have the rmap feature enabled. The kernel doesn't do this, but xfs_repair will, if asked to reindex a filesystem that has rtreflink enabled but not rtrmap. Therefore, we must create the cursor with enough levels to handle a maximally sized btree possible. Note that the rtrmapbt btree cursor slab creates objects large enough to handle xfs_rtrmap_maxlevels_ondisk() levels, so setting bc_nlevels to the same value isn't costing us any extra memory. Cc: stable@vger.kernel.org # v6.14 Fixes: 4a61f12eb11958 ("xfs: create a shadow rmap btree during realtime rmap repair") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-07xfs: fix the rtrmap and rtrefcount _maxlevels_ondisk functionsDarrick J. Wong2-3/+8
The _maxlevels_ondisk functions are used to compute the size of in-memory btree cursors for each btree type. Unfortunately, LOLLM noticed that the rtrmap and rtrefcount versions of these functions forget to account for the inode root, which means that we could access beyond the end of the cursor given a sufficiently large btree. Fix this. Cc: stable@vger.kernel.org # v6.14 Fixes: 9abe03a0e4f978 ("xfs: introduce realtime refcount btree ondisk definitions") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Assisted-by: LOLLM # finding obvious bugs Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-07xfs: assert the reservation covers each da fork growthJavier Tia1-0/+1
xfs_da_grow_inode_int() subtracts the blocks it just allocated from args->total, the caller's remaining block reservation. The subtraction is unsigned, so a caller that reaches it with too small a total wraps the field instead of failing, and every allocation afterwards runs with a bogus reservation. Assert the remaining reservation still covers the step, so an under-reserved or uninitialised total trips in debug builds instead of silently wrapping. Suggested-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Javier Tia <floss@jetm.me> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-07xfs: initialise args->total for parent pointer updatesJavier Tia1-2/+10
xfs_parent_da_args_init() builds an xfs_da_args from a zeroed xfs_parent_args (kmem_cache_zalloc), leaving args->total == 0. xfs_da_grow_inode_int() treats that field as a running block reservation and subtracts from it; because it is an xfs_extlen_t (uint32_t), the first attr-fork growth wraps it to ~0U. That defeats the free-space check in xfs_alloc_space_available(), and when it coincides with an AG that has exactly zero available blocks the allocation is clamped to maxlen 0 and returns -ENOSPC, which xfs_defer_finish_noroll() escalates to a filesystem shutdown. Set args->total the way the log recovery path does (xfs_attri_recover_work(), xfs_attr_item.c:706), in the add and replace paths that can grow the fork. Removals and lookups never grow it, so they leave the field alone, matching that switch. Fixes: b7c62d90c12c ("xfs: parent pointer attribute creation") Cc: stable@vger.kernel.org # v6.10 Signed-off-by: Javier Tia <floss@jetm.me> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-07xfs: correct the parent pointer space reservation commentJavier Tia1-2/+17
The comment on xfs_parent_calc_space_res() claims parent pointers are "always the first attr in an attr tree". They are not: a parent pointer is recorded per dirent, so by the Nth hardlink the attr fork is already in leaf or node format. The reservation is still correct, because XFS_DAENTER_SPACE_RES() covers a split at every level of a maximum-depth attr dabtree whatever format the fork is in, but anyone auditing a shortfall here is led by the comment to look for a bug that is not there. Rewrite the comment to state what actually bounds the result, and record why the double split allowance and the extent-add term differ from xfs_attr_calc_size(). Signed-off-by: Javier Tia <floss@jetm.me> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-07xfs: report the error that made deferred work shut down the fsJavier Tia1-1/+14
When a deferred operation fails and shuts the filesystem down, xfs_defer_finish_noroll() reports neither the errno nor which operation originated it, so the log cannot tell a transient -ENOSPC from real corruption. Report the operation type, errno and remaining reservation. trace_xfs_defer_finish_error() runs after xfs_force_shutdown(), which BUGs under fs.xfs.panic_mask and so never fires for the first failure; move it ahead of the shutdown and mirror it to xfs_alert() for systems without tracing armed. Capture the op name while the item is live (dfp is freed once its work list drains) and suppress the alert once the fs is already down. Signed-off-by: Javier Tia <floss@jetm.me> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-07xfs: give the deferred barrier op type a nameJavier Tia1-0/+1
xfs_barrier_defer_type is the only xfs_defer_op_type with no .name. Every other one carries a short string used for tracing and reporting: attr, bmap, extent_free, agfl_free, rtextent_free, refcount, rtrefcount, rmap, rtrmap and exchmaps. That has been harmless because nothing dereferences the field, but it leaves a NULL in a table where every other entry is populated, so the first caller to print it gets "(null)" in the kernel and undefined behaviour in the userspace libxfs build of this file, where xfs_alert lands in fprintf. xfs_defer_add() already treats a missing member of this table as worth shutting the filesystem down for, so an unpopulated one is out of step with how the file handles its own ops tables. Signed-off-by: Javier Tia <floss@jetm.me> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-07xfs: initialise error in xfs_defer_finish_one()Javier Tia1-1/+1
xfs_defer_finish_one() declares error without an initialiser and only assigns it inside the loop over dfp->dfp_work. When that list is empty the loop body never runs, control falls through to the "Done with the dfp, free it" path, and the function returns an indeterminate value. An item-less pending item reaches this through xfs_defer_add_barrier(), which xfs_reap_ag_blocks() uses on any CONFIG_XFS_ONLINE_REPAIR kernel. xfs_defer_finish_noroll() treats any non-EAGAIN return as fatal, so a non-zero stack value turns a successful barrier into a SHUTDOWN_CORRUPT_INCORE in the middle of a repair. Zero is the correct result: reaching the free path means the item loop drained without a non-zero error. Fixes: 3f3cec031099 ("xfs: force small EFIs for reaping btree extents") Cc: stable@vger.kernel.org Signed-off-by: Javier Tia <floss@jetm.me> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-07xfs: fix exchange-range reflink flag clearing issue with INO1_WRITTENLin Jiapeng1-0/+10
When exchanging two full-file ranges, xmi_can_exchange_reflink_flags() can move the reflink inode flag from the file that currently has it to the other file, as long as exactly one side is marked. This assumes that the file contents, and therefore all shared extents, are exchanged. That assumption is not true when XFS_EXCHMAPS_INO1_WRITTEN is set. xfs_exchmaps_can_skip_mapping() can skip hole and unwritten mappings from file1, so an exchange can complete without moving every mapping that the earlier flag-swap decision accounted for. In that case the post-operation cleanup can clear the reflink flag from an inode that still owns shared written extents. Later writes then take the non-reflink write path and may update blocks that should still have been protected by CoW, which shows up as data corruption between reflink-related files. Fix this by disabling the reflink flag exchange whenever XFS_EXCHMAPS_INO1_WRITTEN is requested. The contents exchange can still proceed; the conservative outcome is that both inodes keep the reflink flag. The regular reflink flag cleanup path can drop the extra flag later once the inode no longer has shared extents. Reported-by: Lin Jiapeng (TencentOS Red Team) <jiapenglin@tencent.com> Fixes: 966ceafc7a43 ("xfs: create deferred log items for file mapping exchanges") Cc: stable@vger.kernel.org # v6.10 Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Lin Jiapeng <jiapenglin@tencent.com> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-09-04treewide: refresh kmalloc_obj() conversionsKees Cook1-2/+2
This is another run of the Coccinelle script for converting kmalloc() family of allocations to kmalloc_obj() via the existing rules in scripts/coccinelle/api/kmalloc_objs.cocci This catches both the set of kmalloc() uses added since the first kmalloc_obj() conversions in v7.0 and adds a large group missed in the first pass due to Coccinelle not interacting well with the cleanup.h scoped_...() family of macros[1]. I worked around this with spatch's "--macro-file" argument to a file with all the scoped_...() macros mapped to Coccinelle's YACFE_ITERATOR[2] as that was the closest viable control flow indicator I could find. Build tested allmodconfig on x86, arm64, arm, loongarch, mips, powerpc, riscv, and s390 with no new warnings. Link: https://lore.kernel.org/lkml/202609021314.8A9C0B8@keescook/ [1] Link: https://github.com/coccinelle/coccinelle/blob/master/standard.h [2] Signed-off-by: Kees Cook <kees+treewide@kernel.org>
2026-08-21xfs: don't hold buffer locks across sync transaction commit in xfs_sync_sb_bufYun Zhou2-21/+22
xfs_sync_sb_buf() holds sb/rtsb buffer locks across a synchronous xfs_trans_commit(), which flushes the CIL push workqueue internally. If shutdown occurs during the CIL push, xfs_buf_item_unpin() needs to lock these buffers to fail them, causing a deadlock: setlabel: holds buf lock -> flush_workqueue(xfs-cil) CIL push worker: xfs_buf_item_unpin -> xfs_buf_lock(same buf) Remove the xfs_trans_bhold() calls so that commit releases the buffer locks normally. After the sync commit, re-acquire the buffers via mp->m_sb_bp / mp->m_rtsb_bp for the on-disk writeback. Fixes: f7664b31975b ("xfs: implement online get/set fs label") Reported-by: syzbot+837bcd54843dd6262f2f@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=837bcd54843dd6262f2f Cc: stable@vger.kernel.org Signed-off-by: Yun Zhou <yun.zhou@windriver.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-08-17Merge tag 'xfs-merge-7.3' of git://git.kernel.org:/pub/scm/fs/xfs/xfs-linuxLinus Torvalds9-106/+112
Pull xfs updates from Carlos Maiolino: "There are no big standing out features on this window, so this mostly consists on bug fixes and code refactoring. The only user visible change that stands out is the support for FALLOC_FL_WRITE_ZEROES added to this" * tag 'xfs-merge-7.3' of git://git.kernel.org:/pub/scm/fs/xfs/xfs-linux: (23 commits) xfs: validate attr entry pointer before field access xfs: check split_sectors validity before bio_split call xfs: use file target for post-log fsync fallback flush xfs: restore nofs context unconditionally in xfs_trans_roll xfs: add lockless xfs_buf_readahead_map fast path xfs: move buffer locking out of xfs_find_get_buf xfs: merge xfs_buf_reverify into xfs_buf_read_map xfs: use goto based error unwinding in xfs_buf_read_map xfs: don't reverify buffers in xfs_buf_readahead_map xfs: use WRITE_ONCE to update b_flags xfs: hide b_flags manipulation from code outside of xfs_buf.c xfs: remove _XBF_LOGRECOVERY xfs: remove spurious XBF_DONE clearing on readahead validation failure xfs: split out a lower-level xfs_buf_get_map helper from xfs_find_get_buf xfs: consolidate buffer locking in xfs_buf_get_map xfs: don't get a pag reference in xfs_buf_get_map xfs: use kmalloc_objs() instead of kmalloc() in xfs_da_grow_inode_int xfs: mark internal metadir file creation helpers static xfs: create rtgroup metadir inodes using xfs_metadir_create_file xfs: create quota metadir inodes using xfs_metadir_create_file ...
2026-08-10xfs: validate attr entry pointer before field accessHongling Zeng1-0/+14
xfs_attr3_leaf_verify_entry() accesses lentry/rentry fields (namelen, valuelen) before checking if the entry pointer itself is within bounds. If nameidx is crafted to point near the end of the buffer, these field accesses can read out-of-bounds before the bounds check at name_end > buf_end is performed. Add explicit bounds checks for entry pointers before accessing their fields. Use offsetof() to check that the start of the flexible array member (nameval/name) is within bounds, which ensures all preceding fields are safe to access. Fixes: c84760659dcf2 ("xfs: check attribute leaf block structure") Cc: <stable@vger.kernel.org> # v5.5 Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-08-10xfs: hide b_flags manipulation from code outside of xfs_buf.cChristoph Hellwig2-5/+4
Add helpers for the remaining buffer flags manipulation not done in the core buffer cache code. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-08-10xfs: remove spurious XBF_DONE clearing on readahead validation failureChristoph Hellwig2-12/+11
Both callers of ->verify_read already do this, so don't duplicate the flag manipulation. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-08-03xfs: check v5 superblock features earlyChristoph Hellwig1-2/+2
When working on a new features that reuses the existing pad in the superblock, I noticed that mounting such a file system on an old kernel logs a rather confusing warning: XFS (vdc): Metadir superblock padding fields must be zero. This is because we only validate the various feature fields in v5 superblocks after the common superblock validation helper is called. Fix this by calling the feature validation first. Fixes: eca383fcd63b ("xfs: refactor superblock verifiers") Cc: <stable@vger.kernel.org> # v4.19 Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-08-03xfs: fix exchange-range reflink flag clearing issue with INO1_WRITTENLin Jiapeng1-0/+10
When exchanging two full-file ranges, xmi_can_exchange_reflink_flags() can move the reflink inode flag from the file that currently has it to the other file, as long as exactly one side is marked. This assumes that the file contents, and therefore all shared extents, are exchanged. That assumption is not true when XFS_EXCHMAPS_INO1_WRITTEN is set. xfs_exchmaps_can_skip_mapping() can skip hole and unwritten mappings from file1, so an exchange can complete without moving every mapping that the earlier flag-swap decision accounted for. In that case the post-operation cleanup can clear the reflink flag from an inode that still owns shared written extents. Later writes then take the non-reflink write path and may update blocks that should still have been protected by CoW, which shows up as data corruption between reflink-related files. Fix this by disabling the reflink flag exchange whenever XFS_EXCHMAPS_INO1_WRITTEN is requested. The contents exchange can still proceed; the conservative outcome is that both inodes keep the reflink flag. The regular reflink flag cleanup path can drop the extra flag later once the inode no longer has shared extents. Reported-by: Lin Jiapeng (TencentOS Red Team) <jiapenglin@tencent.com> Fixes: 966ceafc7a43 ("xfs: create deferred log items for file mapping exchanges") Cc: stable@vger.kernel.org # v6.10 Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Lin Jiapeng <jiapenglin@tencent.com> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: use kmalloc_objs() instead of kmalloc() in xfs_da_grow_inode_intCihan Karadag1-2/+1
Convert open-coded kmalloc() multiplication to the modern kmalloc_objs() interface to improve type safety and prevent potential integer overflows. No functional changes are intended. Signed-off-by: Cihan Karadag <cihan.cihan@gmail.com> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: mark internal metadir file creation helpers staticJohannes Thumshirn2-7/+3
Now that there is xfs_metadir_create_file() mark xfs_metadir_start_create(), xfs_metadir_create() and xfs_metadir_cancel() as static and remove them from xfs_metadir.h. Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: create rtgroup metadir inodes using xfs_metadir_create_fileJohannes Thumshirn1-32/+26
Now that we have xfs_metadir_create_file() use it in xfs_rtginode_create(). Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: create quota metadir inodes using xfs_metadir_create_fileJohannes Thumshirn1-28/+11
Now that we have xfs_metadir_create_file() use it in xfs_dqinode_metadir_create(). Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: add xfs_metadir_create_file helperJohannes Thumshirn2-21/+43
Factor the metadata inode create/commit/cleanup lifecycle out of xfs_metadir_mkdir into a reusable helper that takes an optional callback to initialize the new inode, and convert xfs_metadir_mkdir to it. Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-22xfs: fix off-by-one in rtrefcount btree root level validationXiang Mei1-2/+2
xfs_rtrefcountbt_compute_maxlevels() sets mp->m_rtrefc_maxlevels = min(d_maxlevels, r_maxlevels) + 1; where the trailing "+ 1" already accounts for the inode-root level, so the deepest valid on-disk root level is m_rtrefc_maxlevels - 1 and a cursor must satisfy bc_nlevels <= bc_maxlevels (= m_rtrefc_maxlevels). The two on-disk validation paths, xfs_rtrefcountbt_verify() and xfs_iformat_rtrefcount(), check the root level with ">" instead of ">=", so a crafted rtreflink (metadir + realtime + reflink) image whose /rtgroups/N.refcount inode has bb_level == m_rtrefc_maxlevels is accepted on mount. xfs_rtrefcountbt_init_cursor() then sets bc_nlevels = bb_level + 1, exceeding bc_maxlevels by one. Since the xfs_rtrefcountbt_cur slab object is sized for exactly bc_maxlevels entries, the first btree op on such a cursor indexes bc_levels[m_rtrefc_maxlevels] past the end of the object. This is reached by the first rtrefcount cursor built after mount, via log/CoW recovery (xfs_reflink_recover_cow() during xfs_mountfs()) or an FS_IOC_GETFSMAP over the realtime device. Reject a root level equal to m_rtrefc_maxlevels, matching the ">=" form already used by the sibling data-device refcount/rmap verifiers and the in-memory rtrmap verifier. BUG: KASAN: slab-out-of-bounds in xfs_btree_lookup (fs/xfs/libxfs/xfs_btree.c:2101) Write of size 2 at addr ffff888018391658 by task exploit/144 xfs_btree_lookup (fs/xfs/libxfs/xfs_btree.c:2101) xfs_btree_query_range (fs/xfs/libxfs/xfs_btree.c:5308) xfs_refcount_recover_cow_leftovers (fs/xfs/libxfs/xfs_refcount.c:2113) xfs_reflink_recover_cow (fs/xfs/xfs_reflink.c:1085) xlog_recover_finish (fs/xfs/xfs_log_recover.c:3551) xfs_mountfs (fs/xfs/xfs_mount.c:1158) xfs_fs_fill_super (fs/xfs/xfs_super.c:1940) get_tree_bdev_flags (fs/super.c:1634) vfs_get_tree (fs/super.c:1694) path_mount (fs/namespace.c:4161) __x64_sys_mount (fs/namespace.c:4367) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121) The buggy address belongs to the cache xfs_rtrefcountbt_cur of size 216 The buggy address is located 8 bytes to the right of allocated 216-byte region [ffff888018391578, ffff888018391650) Kernel panic - not syncing: Fatal exception Cc: stable@vger.kernel.org # v6.14 Fixes: 9abe03a0e4f978 ("xfs: introduce realtime refcount btree ondisk definitions") Reported-by: Weiming Shi <bestswngs@gmail.com> Signed-off-by: Xiang Mei <xmei5@asu.edu> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-12xfs: fix null pointer dereference in tracepointAndrey Albershteyn1-1/+1
If dfp is not NULL we exit early here, when dfp is NULL it's allocated in xfs_defer_alloc() but not assigned. The tracepoint tries to dereference members of dfp struct. Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org> Cc: stable@vger.kernel.org # v6.8 Fixes: 3f3cec031099c3 ("xfs: force small EFIs for reaping btree extents") Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-07-01xfs: fix memory leak in xfs_dqinode_metadir_create()Dawei Feng1-2/+12
If xfs_metadir_create() fails in xfs_dqinode_metadir_create(), the current code returns directly, leaking the allocated update and transaction state. If the subsequent commit fails, the caller-owned inode reference is left behind. Fix this memory leak by routing the create failure path through xfs_metadir_cancel(). For both create and commit failures, finish and release any inode returned to the caller, mirroring the unwind pattern in xfs_metadir_mkdir(). The bug was first flagged by an experimental analysis tool we are developing for kernel memory-management bugs while analyzing v6.13-rc1. The tool is still under development and is not yet publicly available. Manual inspection confirms that the bug is still present in v7.1.1. An x86_64 allyesconfig build showed no new warnings. Runtime validation used kprobe fault injection during `mount -o uquota` on a metadir XFS image. Injecting xfs_metadir_create() reproduced the old active-update path that left mount stuck later in mount setup; after this change, the same injection reported cancel_hits=1 and irele_hits=1. Injecting xfs_metadir_commit() exercised the old inode-reference leak path; after this change, it reported irele_hits=1. Fixes: e80fbe1ad8ef ("xfs: use metadir for quota inodes") Cc: stable@vger.kernel.org # v6.13 Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-16Merge tag 'xfs-merge-7.2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linuxLinus Torvalds30-186/+183
Pull xfs updates from Carlos Maiolino: "The main highlight is the removal of experimental tag of the zone allocator feature. Besides that, this contains a collection of bug fixes and code refactoring but no new features have been added" * tag 'xfs-merge-7.2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (29 commits) xfs: shut down the filesystem on a failed mount xfs: skip inode inactivation on a shut down mount xfs: move XFS_LSN_CMP to xfs_log_format.h xfs: shut down zoned file systems on writeback errors xfs: cleanup xfs_growfs_compute_deltas xfs: pass back updated nb from xfs_growfs_compute_deltas xfs: fix pointer arithmetic error on 32-bit systems xfs: initialize iomap->flags earlier in xfs_bmbt_to_iomap xfs: only log freed extents for the current RTG in zoned growfs xfs: add newly added RTGs to the free pool in growfs xfs: factor out a xfs_zone_mark_free helper xfs: mark struct xfs_imap as __packed xfs: store an agbno in struct xfs_imap xfs: massage xfs_imap_to_bp into xfs_read_icluster xfs: remove im_len field in struct xfs_imap xfs: cleanup xfs_imap xfs: remove the call to xfs_buf_reverify in xfs_trans_read_buf_map xfs: remove the i_ino field in struct xfs_inode xfs: remove xfs_setup_existing_inode xfs: convert xchk_inode_xref_set_corrupt to xchk_ip_xref_set_corrupt ...
2026-06-15Merge tag 'vfs-7.2-rc1.casefold' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfsLinus Torvalds1-0/+2
Pull vfs casefolding updates from Christian Brauner: "This exposes the case folding behavior of local filesystems so that file servers - nfsd, ksmbd, and user space file servers - can report the actual behavior to clients instead of guessing. Filesystems report case-insensitive and case-nonpreserving behavior via new file_kattr flags in their fileattr_get implementations. fat, exfat, ntfs3, hfs, hfsplus, xfs, cifs, nfs, vboxsf, and isofs are wired up. Local filesystems that are not explicitly handled default to the usual POSIX behavior of case-sensitive and case-preserving. nfsd uses this to report case folding via NFSv3 PATHCONF and to implement the NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING attributes - both have been part of the NFS protocols for decades to support clients on non-POSIX systems - and ksmbd reports it via FS_ATTRIBUTE_INFORMATION. Exposing the information through the fileattr uapi covers user space file servers. The immediate motivation is interoperability: Windows NFS clients hard-require servers to report case-insensitivity for Win32 applications to work correctly, and a client that knows the server is case-insensitive can avoid issuing multiple LOOKUP/READDIR requests searching for case variants. The Linux NFS client already grew support for case-insensitive shares years ago in support of the Hammerspace NFS server - negative dentry caching must be disabled (a lookup for "FILE.TXT" failing must not cache a negative entry when "file.txt" exists) and directory change invalidation must drop cached case-folded name variants. Such servers often operate in multi-protocol environments where a single file service instance caters to both NFS and SMB clients, and nfsd needs to report case folding properly to participate as a first-class citizen there. A follow-up series brings fixes for the initial work: the nfsd case-info probe now uses kernel credentials, maps -ESTALE to NFS3ERR_STALE, and has its cost capped across READDIR entries; the nfs client avoids transiently zeroed case capability bits during the probe and skips the pathconf probe when neither field is consumed; the FS_CASEFOLD_FL semantics are clarified in the UAPI header; and the tools UAPI headers are synced" * tag 'vfs-7.2-rc1.casefold' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (22 commits) nfsd: Cap case-folding probe cost across READDIR entries nfsd: Map -ESTALE from case probe to NFS3ERR_STALE nfsd: Use kernel credentials for case-info probe fs: Clarify FS_CASEFOLD_FL semantics in UAPI header nfs: Skip pathconf probe when neither field is consumed nfs: Avoid transient zeroed case capability bits during probe tools headers UAPI: Sync case-sensitivity flags from linux/fs.h ksmbd: Report filesystem case sensitivity via FS_ATTRIBUTE_INFORMATION nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING nfsd: Report export case-folding via NFSv3 PATHCONF isofs: Implement fileattr_get for case sensitivity vboxsf: Implement fileattr_get for case sensitivity nfs: Implement fileattr_get for case sensitivity cifs: Implement fileattr_get for case sensitivity xfs: Report case sensitivity in fileattr_get hfsplus: Report case sensitivity in fileattr_get hfs: Implement fileattr_get for case sensitivity ntfs3: Implement fileattr_get for case sensitivity exfat: Implement fileattr_get for case sensitivity fat: Implement fileattr_get for case sensitivity ...
2026-06-12xfs: move XFS_LSN_CMP to xfs_log_format.hChristoph Hellwig2-1/+13
Because CYCLE_LSN/BLOCK_LSN are defined in xfs_log_format.h, XFS_LSN_CMP forces a xfs_log_format.h dependency in xfs_log.h. Move XFS_LSN_CMP to xfs_log_format.h and drop the macro/inline indirection to clean up our header mess a little bit. This also helps xfsprogs, which doesn't have xfs_log.h, but needs XFS_LSN_CMP. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-10xfs: cleanup xfs_growfs_compute_deltasChristoph Hellwig2-25/+22
xfs_growfs_compute_deltas has an odd calling conventions, and looks very convoluted due to the use of do_div and strangely named and typed variables. Rename it, make it return the agcount and let the caller calculate the delta. The internally use the better div_u64_rem helper and descriptive variable names and types. Also add a comment describing what the function is used for. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-10xfs: pass back updated nb from xfs_growfs_compute_deltasChristoph Hellwig2-6/+6
xfs_growfs_compute_deltas can update nb for corner cases like a number of blocks that would create a less the minimal sized AG, or running past the max AG limit. Pass back the calculated value to the caller, as it relies on to calculate the new number of perag structures. Note that the grown file system size is not affected by this miscalculation as it uses the passed back delta value. Fixes: a49b7ff63f98 ("xfs: Refactoring the nagcount and delta calculation") Cc: stable@vger.kernel.org # v7.0 Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-10xfs: fix pointer arithmetic error on 32-bit systemsDarrick J. Wong1-1/+1
The translation of the old XFS_BMBT_KEY_ADDR macro into a static function is not correct on 32-bit systems because the sizeof() argument went from being a xfs_bmbt_key_t (i.e. a struct) to a (struct xfs_bmbt_key *) (i.e. a pointer to the same struct). On 64-bit systems this turns out ok because they are the same size, but on 32-bit systems this is catastrophic because they are not the same size. So far there have been no complaints, most likely because the xfs developers urge against running it on 32-bit systems. But this needs fixing asap. Cc: stable@vger.kernel.org # v6.12 Fixes: 79124b37400635 ("xfs: replace shouty XFS_BM{BT,DR} macros") Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-09xfs: mark struct xfs_imap as __packedChristoph Hellwig1-1/+1
This returns 2 bytes of padding at the to struct xfs_inode into which this structure is embedded. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-09xfs: store an agbno in struct xfs_imapChristoph Hellwig3-26/+17
The xfs_imap structure is embedded into the xfs_inode, which means the size of it directly affects the inode size. Replacing the xfs_daddr_t with an xfs_agbno_t and taking the AG information from other easily available sources allows us to shrink the structure including the typical padding from 16 bytes to 8 bytes. As a side-effect the debugging check in xfs_imap() naturally now converges to a stricter variant that checks that the cluster is located inside a single AG, and not just inside the entire device. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-09xfs: massage xfs_imap_to_bp into xfs_read_iclusterChristoph Hellwig3-11/+9
xfs_imap_to_bp only uses the im_blkno field from struct xfs_imap, so pass that directly. Rename the function to xfs_read_icluster, which describes the functionality much better and matches other helpers like xfs_read_agf and xfs_read_agi. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-09xfs: remove im_len field in struct xfs_imapChristoph Hellwig3-7/+7
im_len is always set to the same value for a given file system, which makes it redundant. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-09xfs: cleanup xfs_imapChristoph Hellwig1-34/+28
Reshuffle the code a bit so that the imap_lookup and filling out of the xfs_imap structure aren't duplicated. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-09xfs: remove the i_ino field in struct xfs_inodeChristoph Hellwig25-72/+72
Now that the VFS inode has a u64 i_ino field, there is no need to store a copy of the inode number in the xfs_inode structure. Introduce an I_INO() wrapper as a shortcut to the inode number so that we don't have to propagate the VFS inode everywhere. The only non-obvious part is the clearing of i_ino to 0 for RCU freeing the inode. None of this calls into VFS paths, which makes clearing the VFS inode field here just as safe as clearing the old field in the xfs_inode. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-09xfs: add a xfs_rmap_inode_owner helperChristoph Hellwig2-1/+3
Add a small wrapper for initializing the rmap owner to i_ino. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-09xfs: add a xfs_rmap_inode_bmbt_ownerChristoph Hellwig4-6/+8
Add a small wrapper for initializing the bmbt owner to i_ino. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-09xfs: add a XFS_INO_TO_FSB helperChristoph Hellwig3-9/+7
Add a shortcut for the common XFS_INO_TO_FSB(mp, ip->i_ino) pattern. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-09xfs: add a XFS_INODE_TO_AGINO helperChristoph Hellwig2-3/+4
Add a shortcut for the common XFS_INO_TO_AGINO(mp, ip->i_ino) pattern. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-09xfs: add a XFS_INODE_TO_AGNO helperChristoph Hellwig4-4/+6
Add a shortcut for the common XFS_INO_TO_AGNO(mp, ip->i_ino) pattern. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
2026-06-09xfs: fix exchmaps reservation limit checkYingjie Gao1-1/+1
xfs_exchmaps_estimate_overhead() adds the bmbt and rmapbt overhead to a local resblks variable, but the final UINT_MAX check still tests req->resblks. That is the reservation value from before the overhead was added. The computed value is stored back in req->resblks and later passed to xfs_trans_alloc(), whose block reservation argument is unsigned int. Check the computed reservation so the existing limit applies to the value that will be used. Fixes: 966ceafc7a43 ("xfs: create deferred log items for file mapping exchanges") Cc: stable@vger.kernel.org # v6.10 Signed-off-by: Yingjie Gao <gaoyingjie@uniontech.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>