From: Greg Kroah-Hartman Date: Fri, 17 Jul 2026 09:34:38 +0000 (+0200) Subject: 7.1-stable patches X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=216340669f820fc70908cad2aad0c5221c96d29a;p=thirdparty%2Fkernel%2Fstable-queue.git 7.1-stable patches added patches: xfs-clamp-timestamp-nanoseconds-correctly.patch xfs-don-t-wrap-around-quota-ids-in-dqiterate.patch xfs-don-t-zap-bmbt-forks-if-they-are-maxlevels-tall.patch xfs-fail-recovery-on-a-committed-log-item-with-no-regions.patch xfs-fix-null-pointer-dereference-in-tracepoint.patch xfs-fix-off-by-one-error-when-calling-xchk_xref_has_rt_owner.patch xfs-fully-check-the-parent-handle-when-it-points-to-the-rootdir.patch xfs-grab-rtrmap-btree-when-checking-rgsuper.patch xfs-handle-non-inode-owners-for-rtrmap-record-checking.patch xfs-resample-the-data-fork-mapping-after-cycling-ilock.patch xfs-set-xfarray-killable-sort-correctly.patch xfs-use-rtrefcount-btree-cursor-in-xchk_xref_is_rt_cow_staging.patch xfs-use-the-rt-version-of-the-cow-staging-checker.patch xfs-write-the-rg-superblock-when-fixing-it.patch --- diff --git a/queue-7.1/series b/queue-7.1/series index 5e8214a0f7..0aebad26c4 100644 --- a/queue-7.1/series +++ b/queue-7.1/series @@ -517,3 +517,17 @@ alsa-doc-usb-audio-add-doc-for-quirk_flag_ifb_silence_on_empty.patch timekeeping-register-default-clocksource-before-taking-tk_core.lock.patch bluetooth-6lowpan-fix-using-chan-conn-as-indication-to-no-remote-netdev.patch smb-client-reject-overlapping-data-areas-in-smb2-responses.patch +xfs-fix-null-pointer-dereference-in-tracepoint.patch +xfs-fail-recovery-on-a-committed-log-item-with-no-regions.patch +xfs-resample-the-data-fork-mapping-after-cycling-ilock.patch +xfs-don-t-wrap-around-quota-ids-in-dqiterate.patch +xfs-grab-rtrmap-btree-when-checking-rgsuper.patch +xfs-use-the-rt-version-of-the-cow-staging-checker.patch +xfs-set-xfarray-killable-sort-correctly.patch +xfs-handle-non-inode-owners-for-rtrmap-record-checking.patch +xfs-clamp-timestamp-nanoseconds-correctly.patch +xfs-fully-check-the-parent-handle-when-it-points-to-the-rootdir.patch +xfs-don-t-zap-bmbt-forks-if-they-are-maxlevels-tall.patch +xfs-fix-off-by-one-error-when-calling-xchk_xref_has_rt_owner.patch +xfs-write-the-rg-superblock-when-fixing-it.patch +xfs-use-rtrefcount-btree-cursor-in-xchk_xref_is_rt_cow_staging.patch diff --git a/queue-7.1/xfs-clamp-timestamp-nanoseconds-correctly.patch b/queue-7.1/xfs-clamp-timestamp-nanoseconds-correctly.patch new file mode 100644 index 0000000000..19d0229ae8 --- /dev/null +++ b/queue-7.1/xfs-clamp-timestamp-nanoseconds-correctly.patch @@ -0,0 +1,34 @@ +From 15e38a9366b31d3d61081ead115f1dff59379e24 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 13 Jul 2026 23:07:15 -0700 +Subject: xfs: clamp timestamp nanoseconds correctly + +From: Darrick J. Wong + +commit 15e38a9366b31d3d61081ead115f1dff59379e24 upstream. + +LOLLM noticed an off-by-one error in the nsec clamping; fix that so that +we never have tv_nsec == 1e9. + +Cc: stable@vger.kernel.org # v6.8 +Fixes: 2d295fe65776d1 ("xfs: repair inode records") +Signed-off-by: "Darrick J. Wong" +Assisted-by: LOLLM # finding obvious bugs +Reviewed-by: Christoph Hellwig +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/scrub/inode_repair.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/scrub/inode_repair.c ++++ b/fs/xfs/scrub/inode_repair.c +@@ -1753,7 +1753,7 @@ xrep_clamp_timestamp( + struct xfs_inode *ip, + struct timespec64 *ts) + { +- ts->tv_nsec = clamp_t(long, ts->tv_nsec, 0, NSEC_PER_SEC); ++ ts->tv_nsec = clamp_t(long, ts->tv_nsec, 0, NSEC_PER_SEC - 1); + *ts = timestamp_truncate(*ts, VFS_I(ip)); + } + diff --git a/queue-7.1/xfs-don-t-wrap-around-quota-ids-in-dqiterate.patch b/queue-7.1/xfs-don-t-wrap-around-quota-ids-in-dqiterate.patch new file mode 100644 index 0000000000..38c1e19a6d --- /dev/null +++ b/queue-7.1/xfs-don-t-wrap-around-quota-ids-in-dqiterate.patch @@ -0,0 +1,36 @@ +From d766e4e5e85d829629c3ba503802fe1303d7b591 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 13 Jul 2026 23:04:55 -0700 +Subject: xfs: don't wrap around quota ids in dqiterate + +From: Darrick J. Wong + +commit d766e4e5e85d829629c3ba503802fe1303d7b591 upstream. + +LOLLM noticed that q_id is an unsigned 32-bit variable. If it happens +to be set to XFS_DQ_ID_MAX due to a filesystem that actually has a dquot +for ID_MAX, then this addition will truncate to zero and the iteration +starts over. Fix this by casting to u64. + +Cc: stable@vger.kernel.org # v6.8 +Fixes: 21d7500929c8a0 ("xfs: improve dquot iteration for scrub") +Signed-off-by: "Darrick J. Wong" +Assisted-by: LOLLM # finding obvious bugs +Reviewed-by: Christoph Hellwig +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/scrub/dqiterate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/scrub/dqiterate.c ++++ b/fs/xfs/scrub/dqiterate.c +@@ -205,7 +205,7 @@ xchk_dquot_iter( + if (error) + return error; + +- cursor->id = dq->q_id + 1; ++ cursor->id = (uint64_t)dq->q_id + 1; + *dqpp = dq; + return 1; + } diff --git a/queue-7.1/xfs-don-t-zap-bmbt-forks-if-they-are-maxlevels-tall.patch b/queue-7.1/xfs-don-t-zap-bmbt-forks-if-they-are-maxlevels-tall.patch new file mode 100644 index 0000000000..9cbb47a3e2 --- /dev/null +++ b/queue-7.1/xfs-don-t-zap-bmbt-forks-if-they-are-maxlevels-tall.patch @@ -0,0 +1,35 @@ +From 59c462b0f5cfa107794228051724b34ae9334168 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 13 Jul 2026 23:07:30 -0700 +Subject: xfs: don't zap bmbt forks if they are MAXLEVELS tall + +From: Darrick J. Wong + +commit 59c462b0f5cfa107794228051724b34ae9334168 upstream. + +LOLLM noticed a discrepancy between the bmbt level checks in the libxfs +bmbt code vs. the inode repair code. We do actually allow a bmbt root +that proclaims to have a height of XFS_BM_MAXLEVELS. + +Cc: stable@vger.kernel.org # v6.8 +Fixes: e744cef2060559 ("xfs: zap broken inode forks") +Signed-off-by: "Darrick J. Wong" +Assisted-by: LOLLM # finding obvious bugs +Reviewed-by: Christoph Hellwig +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/scrub/inode_repair.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/scrub/inode_repair.c ++++ b/fs/xfs/scrub/inode_repair.c +@@ -921,7 +921,7 @@ xrep_dinode_bad_bmbt_fork( + + if (nrecs == 0 || xfs_bmdr_space_calc(nrecs) > dfork_size) + return true; +- if (level == 0 || level >= XFS_BM_MAXLEVELS(sc->mp, whichfork)) ++ if (level == 0 || level > XFS_BM_MAXLEVELS(sc->mp, whichfork)) + return true; + + dmxr = xfs_bmdr_maxrecs(dfork_size, 0); diff --git a/queue-7.1/xfs-fail-recovery-on-a-committed-log-item-with-no-regions.patch b/queue-7.1/xfs-fail-recovery-on-a-committed-log-item-with-no-regions.patch new file mode 100644 index 0000000000..f12cc28c66 --- /dev/null +++ b/queue-7.1/xfs-fail-recovery-on-a-committed-log-item-with-no-regions.patch @@ -0,0 +1,69 @@ +From 2094dab19d45c487285617b7b68913d0cc0c1211 Mon Sep 17 00:00:00 2001 +From: Weiming Shi +Date: Thu, 2 Jul 2026 09:20:00 -0700 +Subject: xfs: fail recovery on a committed log item with no regions + +From: Weiming Shi + +commit 2094dab19d45c487285617b7b68913d0cc0c1211 upstream. + +If the first op of a transaction is a bare transaction header +(len == sizeof(struct xfs_trans_header)), xlog_recover_add_to_trans() +adds an item but no region, leaving it on r_itemq with ri_cnt == 0 and +ri_buf == NULL. + +The header can be split across op records, so later ops may still add +regions; the item is only invalid if the transaction commits with none. +The runtime commit path never emits such a transaction, so this only +happens on a crafted log. It came from an AI-assisted code audit of the +recovery parser. + +xlog_recover_reorder_trans() calls ITEM_TYPE() on the item, which reads +*(unsigned short *)item->ri_buf[0].iov_base and faults on the NULL +ri_buf. Reject it there, before the commit handlers that also read +ri_buf[0]. + + KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] + RIP: 0010:xlog_recover_reorder_trans (fs/xfs/xfs_log_recover.c:1836) + xlog_recover_commit_trans (fs/xfs/xfs_log_recover.c:2043) + xlog_recover_process_data (fs/xfs/xfs_log_recover.c:2501) + xlog_do_recovery_pass (fs/xfs/xfs_log_recover.c:3244) + xlog_recover (fs/xfs/xfs_log_recover.c:3493) + xfs_log_mount (fs/xfs/xfs_log.c:618) + xfs_mountfs (fs/xfs/xfs_mount.c:1034) + xfs_fs_fill_super (fs/xfs/xfs_super.c:1938) + vfs_get_tree (fs/super.c:1695) + path_mount (fs/namespace.c:4161) + __x64_sys_mount (fs/namespace.c:4367) + +Fixes: 89cebc847729 ("xfs: validate transaction header length on log recovery") +Cc: stable@vger.kernel.org # v4.3 +Reported-by: Xiang Mei +Assisted-by: Claude:claude-opus-4-8 +Signed-off-by: Weiming Shi +Reviewed-by: Christoph Hellwig +Reviewed-by: "Darrick J. Wong" +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_log_recover.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/fs/xfs/xfs_log_recover.c ++++ b/fs/xfs/xfs_log_recover.c +@@ -1907,6 +1907,15 @@ xlog_recover_reorder_trans( + list_for_each_entry_safe(item, n, &sort_list, ri_list) { + enum xlog_recover_reorder fate = XLOG_REORDER_ITEM_LIST; + ++ /* a committed item with no regions has a NULL ri_buf[0] */ ++ if (!item->ri_cnt || !item->ri_buf) { ++ xfs_warn(log->l_mp, ++ "%s: committed log item has no regions", ++ __func__); ++ error = -EFSCORRUPTED; ++ break; ++ } ++ + item->ri_ops = xlog_find_item_ops(item); + if (!item->ri_ops) { + xfs_warn(log->l_mp, diff --git a/queue-7.1/xfs-fix-null-pointer-dereference-in-tracepoint.patch b/queue-7.1/xfs-fix-null-pointer-dereference-in-tracepoint.patch new file mode 100644 index 0000000000..04fe4b9aa3 --- /dev/null +++ b/queue-7.1/xfs-fix-null-pointer-dereference-in-tracepoint.patch @@ -0,0 +1,34 @@ +From 9202ee546b0cd71004eed7598546efe4660097da Mon Sep 17 00:00:00 2001 +From: Andrey Albershteyn +Date: Thu, 9 Jul 2026 17:24:07 +0200 +Subject: xfs: fix null pointer dereference in tracepoint + +From: Andrey Albershteyn + +commit 9202ee546b0cd71004eed7598546efe4660097da upstream. + +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 +Cc: stable@vger.kernel.org # v6.8 +Fixes: 3f3cec031099c3 ("xfs: force small EFIs for reaping btree extents") +Reviewed-by: "Darrick J. Wong" +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/libxfs/xfs_defer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/libxfs/xfs_defer.c ++++ b/fs/xfs/libxfs/xfs_defer.c +@@ -878,7 +878,7 @@ xfs_defer_add_barrier( + if (dfp) + return; + +- xfs_defer_alloc(&tp->t_dfops, &xfs_barrier_defer_type); ++ dfp = xfs_defer_alloc(&tp->t_dfops, &xfs_barrier_defer_type); + + trace_xfs_defer_add_item(tp->t_mountp, dfp, NULL); + } diff --git a/queue-7.1/xfs-fix-off-by-one-error-when-calling-xchk_xref_has_rt_owner.patch b/queue-7.1/xfs-fix-off-by-one-error-when-calling-xchk_xref_has_rt_owner.patch new file mode 100644 index 0000000000..d7facde6e1 --- /dev/null +++ b/queue-7.1/xfs-fix-off-by-one-error-when-calling-xchk_xref_has_rt_owner.patch @@ -0,0 +1,34 @@ +From 5d72a68f2007ba2a968d6bf47dba3f4620bd182e Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 13 Jul 2026 23:06:28 -0700 +Subject: xfs: fix off-by-one error when calling xchk_xref_has_rt_owner + +From: Darrick J. Wong + +commit 5d72a68f2007ba2a968d6bf47dba3f4620bd182e upstream. + +LOLLM noticed an off-by-one error when computing the length of the +rtrmap to cross-check. + +Cc: stable@vger.kernel.org # v6.14 +Fixes: 037a44d8277adf ("xfs: cross-reference the realtime rmapbt") +Signed-off-by: "Darrick J. Wong" +Assisted-by: LOLLM # finding obvious bugs +Reviewed-by: Christoph Hellwig +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/scrub/rtbitmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/scrub/rtbitmap.c ++++ b/fs/xfs/scrub/rtbitmap.c +@@ -258,7 +258,7 @@ xchk_rtbitmap( + * the last free extent we saw and the last possible extent in the rt + * group. + */ +- last_rgbno = rtg->rtg_extents * mp->m_sb.sb_rextsize - 1; ++ last_rgbno = rtg->rtg_extents * mp->m_sb.sb_rextsize; + if (rtb->next_free_rgbno < last_rgbno) + xchk_xref_has_rt_owner(sc, rtb->next_free_rgbno, + last_rgbno - rtb->next_free_rgbno); diff --git a/queue-7.1/xfs-fully-check-the-parent-handle-when-it-points-to-the-rootdir.patch b/queue-7.1/xfs-fully-check-the-parent-handle-when-it-points-to-the-rootdir.patch new file mode 100644 index 0000000000..440f5fbddc --- /dev/null +++ b/queue-7.1/xfs-fully-check-the-parent-handle-when-it-points-to-the-rootdir.patch @@ -0,0 +1,57 @@ +From ba150ce63453ccd74bae1404c1dfedbd01ecfd55 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 13 Jul 2026 23:06:59 -0700 +Subject: xfs: fully check the parent handle when it points to the rootdir + +From: Darrick J. Wong + +commit ba150ce63453ccd74bae1404c1dfedbd01ecfd55 upstream. + +LOLLM noticed that the directory tree path checking declares the path to +be ok if the inumber in the parent pointer reaches the root directory. +Unfortunately, it neglects to check that the generation is correct. Fix +that by moving the generation check up. + +Cc: stable@vger.kernel.org # v6.10 +Fixes: 928b721a11789a ("xfs: teach online scrub to find directory tree structure problems") +Signed-off-by: "Darrick J. Wong" +Assisted-by: LOLLM # finding obvious bugs +Reviewed-by: Christoph Hellwig +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/scrub/dirtree.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/fs/xfs/scrub/dirtree.c ++++ b/fs/xfs/scrub/dirtree.c +@@ -383,6 +383,14 @@ xchk_dirpath_step_up( + goto out_scanlock; + } + ++ /* The handle encoded in the parent pointer must match. */ ++ if (VFS_I(dp)->i_generation != be32_to_cpu(dl->pptr_rec.p_gen)) { ++ trace_xchk_dirpath_badgen(dl->sc, dp, path->path_nr, ++ path->nr_steps, &dl->xname, &dl->pptr_rec); ++ error = -EFSCORRUPTED; ++ goto out_scanlock; ++ } ++ + /* We've reached the root directory; the path is ok. */ + if (parent_ino == dl->root_ino) { + xchk_dirpath_set_outcome(dl, path, XCHK_DIRPATH_OK); +@@ -411,14 +419,6 @@ xchk_dirpath_step_up( + goto out_scanlock; + } + +- /* The handle encoded in the parent pointer must match. */ +- if (VFS_I(dp)->i_generation != be32_to_cpu(dl->pptr_rec.p_gen)) { +- trace_xchk_dirpath_badgen(dl->sc, dp, path->path_nr, +- path->nr_steps, &dl->xname, &dl->pptr_rec); +- error = -EFSCORRUPTED; +- goto out_scanlock; +- } +- + /* Parent pointer must point up to a directory. */ + if (!S_ISDIR(VFS_I(dp)->i_mode)) { + trace_xchk_dirpath_nondir_parent(dl->sc, dp, path->path_nr, diff --git a/queue-7.1/xfs-grab-rtrmap-btree-when-checking-rgsuper.patch b/queue-7.1/xfs-grab-rtrmap-btree-when-checking-rgsuper.patch new file mode 100644 index 0000000000..846081d7c1 --- /dev/null +++ b/queue-7.1/xfs-grab-rtrmap-btree-when-checking-rgsuper.patch @@ -0,0 +1,57 @@ +From ea6e2d9de25d2095845e0cdf2274e581fd40d636 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 13 Jul 2026 23:05:57 -0700 +Subject: xfs: grab rtrmap btree when checking rgsuper + +From: Darrick J. Wong + +commit ea6e2d9de25d2095845e0cdf2274e581fd40d636 upstream. + +LOLLM noticed that we aren't grabbing the rtrmap btree when we check the +realtime group superblock. As a result, none of the cross-referencing +checks have ever run. Fix this. + +Cc: stable@vger.kernel.org # v6.14 +Fixes: 428e4884656db9 ("xfs: allow queued realtime intents to drain before scrubbing") +Signed-off-by: "Darrick J. Wong" +Assisted-by: LOLLM # finding obvious bugs +Reviewed-by: Christoph Hellwig +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/scrub/rgsuper.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/fs/xfs/scrub/rgsuper.c ++++ b/fs/xfs/scrub/rgsuper.c +@@ -23,6 +23,8 @@ int + xchk_setup_rgsuperblock( + struct xfs_scrub *sc) + { ++ if (xchk_need_intent_drain(sc)) ++ xchk_fsgates_enable(sc, XCHK_FSGATES_DRAIN); + return xchk_trans_alloc(sc, 0); + } + +@@ -43,6 +45,7 @@ xchk_rgsuperblock( + struct xfs_scrub *sc) + { + xfs_rgnumber_t rgno = sc->sm->sm_agno; ++ unsigned int flags; + int error; + + /* +@@ -63,7 +66,12 @@ xchk_rgsuperblock( + if (!xchk_xref_process_error(sc, 0, 0, &error)) + return error; + +- error = xchk_rtgroup_lock(sc, &sc->sr, XFS_RTGLOCK_BITMAP_SHARED); ++ if (xfs_has_rtrmapbt(sc->mp)) ++ flags = XFS_RTGLOCK_BITMAP | XFS_RTGLOCK_RMAP; ++ else ++ flags = XFS_RTGLOCK_BITMAP_SHARED; ++ ++ error = xchk_rtgroup_lock(sc, &sc->sr, flags); + if (error) + return error; + diff --git a/queue-7.1/xfs-handle-non-inode-owners-for-rtrmap-record-checking.patch b/queue-7.1/xfs-handle-non-inode-owners-for-rtrmap-record-checking.patch new file mode 100644 index 0000000000..c16b97826e --- /dev/null +++ b/queue-7.1/xfs-handle-non-inode-owners-for-rtrmap-record-checking.patch @@ -0,0 +1,47 @@ +From 353a5900bc85234e7df05caac37698042dc26348 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 13 Jul 2026 23:06:43 -0700 +Subject: xfs: handle non-inode owners for rtrmap record checking + +From: Darrick J. Wong + +commit 353a5900bc85234e7df05caac37698042dc26348 upstream. + +LOLLM noticed that two helper functions in the rtrmapbt scrub code don't +actually handle non-inode owners correctly -- CoW staging extents and +rgsuperblock extents are not shareable, but they are mergeable. Fix +these two helpers. + +Cc: stable@vger.kernel.org # v6.14 +Fixes: 2d9a3e98053e8c ("xfs: allow overlapping rtrmapbt records for shared data extents") +Signed-off-by: "Darrick J. Wong" +Assisted-by: LOLLM # finding obvious bugs +Reviewed-by: Christoph Hellwig +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/scrub/rtrmap.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/fs/xfs/scrub/rtrmap.c ++++ b/fs/xfs/scrub/rtrmap.c +@@ -87,6 +87,9 @@ xchk_rtrmapbt_is_shareable( + return false; + if (irec->rm_flags & XFS_RMAP_UNWRITTEN) + return false; ++ if (irec->rm_owner == XFS_RMAP_OWN_COW || ++ irec->rm_owner == XFS_RMAP_OWN_FS) ++ return false; + return true; + } + +@@ -146,6 +149,9 @@ xchk_rtrmap_mergeable( + return false; + if (r1->rm_flags != r2->rm_flags) + return false; ++ if (r1->rm_owner == XFS_RMAP_OWN_COW || ++ r1->rm_owner == XFS_RMAP_OWN_FS) ++ return true; + return r1->rm_offset + r1->rm_blockcount == r2->rm_offset; + } + diff --git a/queue-7.1/xfs-resample-the-data-fork-mapping-after-cycling-ilock.patch b/queue-7.1/xfs-resample-the-data-fork-mapping-after-cycling-ilock.patch new file mode 100644 index 0000000000..86358b3b7c --- /dev/null +++ b/queue-7.1/xfs-resample-the-data-fork-mapping-after-cycling-ilock.patch @@ -0,0 +1,100 @@ +From 2f4acd0fcd862e22eab45690ec2c08c80b6ef2e7 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 13 Jul 2026 23:03:44 -0700 +Subject: xfs: resample the data fork mapping after cycling ILOCK + +From: Darrick J. Wong + +commit 2f4acd0fcd862e22eab45690ec2c08c80b6ef2e7 upstream. + +xfs_reflink_fill_{cow_hole,delalloc} are both presented with an inode, +a data fork mapping, and a cow fork mapping. Unfortunately, these two +helpers cycle the ILOCK to grab a transaction, which means that the +mappings are stale as soon as we reacquire the ILOCK. Currently we +refresh the cow fork mapping by re-calling xfs_find_trim_cow_extent, but +we don't refresh the data fork mapping beforehand, which means that the +xfs_bmap_trim_cow in that function queries the refcount btree about the +wrong physical blocks and returns an inaccurate value in *shared. + +If *shared is now false, the directio write proceeds with a stale data +fork mapping. Fix this by querying the data fork mapping if the +sequence counter changes across the ILOCK cycle. + +Cc: hch@lst.de +Cc: stable@vger.kernel.org # v4.11 +Fixes: 3c68d44a2b49a0 ("xfs: allocate direct I/O COW blocks in iomap_begin") +Signed-off-by: "Darrick J. Wong" +Reviewed-by: Christoph Hellwig +Reviewed-by: Carlos Maiolino +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_reflink.c | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +--- a/fs/xfs/xfs_reflink.c ++++ b/fs/xfs/xfs_reflink.c +@@ -440,6 +440,7 @@ xfs_reflink_fill_cow_hole( + struct xfs_mount *mp = ip->i_mount; + struct xfs_trans *tp; + xfs_filblks_t resaligned; ++ unsigned int seq_before = READ_ONCE(ip->i_df.if_seq); + unsigned int dblocks = 0, rblocks = 0; + int nimaps; + int error; +@@ -465,6 +466,22 @@ xfs_reflink_fill_cow_hole( + + *lockmode = XFS_ILOCK_EXCL; + ++ /* ++ * The data fork mapping may have changed while we dropped the ILOCK ++ * (a racing O_DIRECT writer under IOLOCK_SHARED can complete a full ++ * CoW cycle including xfs_reflink_end_cow(), which remaps this offset ++ * and drops the refcount of the old shared block). Re-read it so the ++ * shared-status recheck below and the caller's in-place iomap both ++ * operate on the current mapping rather than a stale physical block. ++ */ ++ if (seq_before != READ_ONCE(ip->i_df.if_seq)) { ++ nimaps = 1; ++ error = xfs_bmapi_read(ip, imap->br_startoff, ++ imap->br_blockcount, imap, &nimaps, 0); ++ if (error) ++ goto out_trans_cancel; ++ } ++ + error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found); + if (error || !*shared) + goto out_trans_cancel; +@@ -511,6 +528,8 @@ xfs_reflink_fill_delalloc( + bool found; + + do { ++ unsigned int seq_before = READ_ONCE(ip->i_df.if_seq); ++ + xfs_iunlock(ip, *lockmode); + *lockmode = 0; + +@@ -521,6 +540,23 @@ xfs_reflink_fill_delalloc( + + *lockmode = XFS_ILOCK_EXCL; + ++ /* ++ * The data fork mapping may have changed while we dropped the ++ * ILOCK (a racing O_DIRECT writer under IOLOCK_SHARED can ++ * complete a full CoW cycle including xfs_reflink_end_cow(), ++ * which remaps this offset and drops the refcount of the old ++ * shared block). Re-read it so the shared-status recheck ++ * below and the caller's in-place iomap both operate on the ++ * current mapping rather than a stale physical block. ++ */ ++ if (seq_before != READ_ONCE(ip->i_df.if_seq)) { ++ nimaps = 1; ++ error = xfs_bmapi_read(ip, imap->br_startoff, ++ imap->br_blockcount, imap, &nimaps, 0); ++ if (error) ++ goto out_trans_cancel; ++ } ++ + error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, + &found); + if (error || !*shared) diff --git a/queue-7.1/xfs-set-xfarray-killable-sort-correctly.patch b/queue-7.1/xfs-set-xfarray-killable-sort-correctly.patch new file mode 100644 index 0000000000..379bb3bd64 --- /dev/null +++ b/queue-7.1/xfs-set-xfarray-killable-sort-correctly.patch @@ -0,0 +1,66 @@ +From 540ddc626245f12f56326ee0c1601f71ebb41d64 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 13 Jul 2026 23:06:12 -0700 +Subject: xfs: set xfarray killable sort correctly + +From: Darrick J. Wong + +commit 540ddc626245f12f56326ee0c1601f71ebb41d64 upstream. + +LOLLM noticed that we *disable* interruptible sorts when the KILLABLE +flag is set. This is backwards. Fix the incorrect logic, and rename +the variable to make the connection more obvious. + +Cc: stable@vger.kernel.org # v6.10 +Fixes: 271557de7cbfde ("xfs: reduce the rate of cond_resched calls inside scrub") +Signed-off-by: "Darrick J. Wong" +Assisted-by: LOLLM # finding obvious bugs +Reviewed-by: Christoph Hellwig +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/scrub/scrub.h | 6 +++--- + fs/xfs/scrub/xfarray.c | 3 +-- + 2 files changed, 4 insertions(+), 5 deletions(-) + +--- a/fs/xfs/scrub/scrub.h ++++ b/fs/xfs/scrub/scrub.h +@@ -11,7 +11,7 @@ struct xfs_scrub; + struct xchk_relax { + unsigned long next_resched; + unsigned int resched_nr; +- bool interruptible; ++ bool killable; + }; + + /* Yield to the scheduler at most 10x per second. */ +@@ -21,7 +21,7 @@ struct xchk_relax { + (struct xchk_relax){ \ + .next_resched = XCHK_RELAX_NEXT, \ + .resched_nr = 0, \ +- .interruptible = true, \ ++ .killable = true, \ + } + + /* +@@ -45,7 +45,7 @@ static inline int xchk_maybe_relax(struc + widget->next_resched = XCHK_RELAX_NEXT; + } + +- if (widget->interruptible && fatal_signal_pending(current)) ++ if (widget->killable && fatal_signal_pending(current)) + return -EINTR; + + return 0; +--- a/fs/xfs/scrub/xfarray.c ++++ b/fs/xfs/scrub/xfarray.c +@@ -487,8 +487,7 @@ xfarray_sortinfo_alloc( + xfarray_sortinfo_lo(si)[0] = 0; + xfarray_sortinfo_hi(si)[0] = array->nr - 1; + si->relax = INIT_XCHK_RELAX; +- if (flags & XFARRAY_SORT_KILLABLE) +- si->relax.interruptible = false; ++ si->relax.killable = !!(flags & XFARRAY_SORT_KILLABLE); + + trace_xfarray_sort(si, nr_bytes); + *infop = si; diff --git a/queue-7.1/xfs-use-rtrefcount-btree-cursor-in-xchk_xref_is_rt_cow_staging.patch b/queue-7.1/xfs-use-rtrefcount-btree-cursor-in-xchk_xref_is_rt_cow_staging.patch new file mode 100644 index 0000000000..921b55af37 --- /dev/null +++ b/queue-7.1/xfs-use-rtrefcount-btree-cursor-in-xchk_xref_is_rt_cow_staging.patch @@ -0,0 +1,35 @@ +From ee248157da501f0c02688fb64e5359f2832b0b01 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 13 Jul 2026 23:05:10 -0700 +Subject: xfs: use rtrefcount btree cursor in xchk_xref_is_rt_cow_staging + +From: Darrick J. Wong + +commit ee248157da501f0c02688fb64e5359f2832b0b01 upstream. + +LOLLM points out that we pass the wrong btree cursor here. We want the +rtrefcount btree cursor, not the non-rt one. This is fairly benign +since it only affects tracing data. + +Cc: stable@vger.kernel.org # v6.14 +Fixes: 91683bb3f264c0 ("xfs: cross-reference checks with the rt refcount btree") +Signed-off-by: "Darrick J. Wong" +Assisted-by: LOLLM # finding obvious bugs +Reviewed-by: Christoph Hellwig +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/scrub/rtrefcount.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/scrub/rtrefcount.c ++++ b/fs/xfs/scrub/rtrefcount.c +@@ -607,7 +607,7 @@ xchk_xref_is_rt_cow_staging( + + /* CoW lookup returned a shared extent record? */ + if (rc.rc_domain != XFS_REFC_DOMAIN_COW) +- xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0); ++ xchk_btree_xref_set_corrupt(sc, sc->sr.refc_cur, 0); + + /* Must be at least as long as what was passed in */ + if (rc.rc_blockcount < len) diff --git a/queue-7.1/xfs-use-the-rt-version-of-the-cow-staging-checker.patch b/queue-7.1/xfs-use-the-rt-version-of-the-cow-staging-checker.patch new file mode 100644 index 0000000000..0a8004406c --- /dev/null +++ b/queue-7.1/xfs-use-the-rt-version-of-the-cow-staging-checker.patch @@ -0,0 +1,35 @@ +From 881f2eb0fcdea2f46a50fa6a892fe9e3ccf19e01 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 13 Jul 2026 23:05:26 -0700 +Subject: xfs: use the rt version of the cow staging checker + +From: Darrick J. Wong + +commit 881f2eb0fcdea2f46a50fa6a892fe9e3ccf19e01 upstream. + +LOLLM also noticed that xchk_rtrmapbt_xref ought to be using the rtdev +version of the "is this a cow extent?" helper function, not the datadev +one. + +Cc: stable@vger.kernel.org # v6.14 +Fixes: 91683bb3f264c0 ("xfs: cross-reference checks with the rt refcount btree") +Signed-off-by: "Darrick J. Wong" +Assisted-by: LOLLM # finding obvious bugs +Reviewed-by: Christoph Hellwig +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/scrub/rtrmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/scrub/rtrmap.c ++++ b/fs/xfs/scrub/rtrmap.c +@@ -209,7 +209,7 @@ xchk_rtrmapbt_xref( + xfs_rgbno_to_rtb(sc->sr.rtg, irec->rm_startblock), + irec->rm_blockcount); + if (irec->rm_owner == XFS_RMAP_OWN_COW) +- xchk_xref_is_cow_staging(sc, irec->rm_startblock, ++ xchk_xref_is_rt_cow_staging(sc, irec->rm_startblock, + irec->rm_blockcount); + else + xchk_rtrmapbt_xref_rtrefc(sc, irec); diff --git a/queue-7.1/xfs-write-the-rg-superblock-when-fixing-it.patch b/queue-7.1/xfs-write-the-rg-superblock-when-fixing-it.patch new file mode 100644 index 0000000000..11da33b068 --- /dev/null +++ b/queue-7.1/xfs-write-the-rg-superblock-when-fixing-it.patch @@ -0,0 +1,39 @@ +From 9af789fa274bc14b907f811f79fa988a6fc6d4e7 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 13 Jul 2026 23:05:41 -0700 +Subject: xfs: write the rg superblock when fixing it + +From: Darrick J. Wong + +commit 9af789fa274bc14b907f811f79fa988a6fc6d4e7 upstream. + +The rtgroup superblock fixer should write the rtgroup superblock. +LOLLM noticed this, oops. :/ + +Cc: stable@vger.kernel.org # v6.13 +Fixes: 1433f8f9cead37 ("xfs: repair realtime group superblock") +Signed-off-by: "Darrick J. Wong" +Assisted-by: LOLLM # finding obvious bugs +Reviewed-by: Christoph Hellwig +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/scrub/rgsuper.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/fs/xfs/scrub/rgsuper.c ++++ b/fs/xfs/scrub/rgsuper.c +@@ -88,9 +88,13 @@ int + xrep_rgsuperblock( + struct xfs_scrub *sc) + { ++ struct xfs_buf *sb_bp; ++ + ASSERT(rtg_rgno(sc->sr.rtg) == 0); + ++ sb_bp = xfs_trans_getsb(sc->tp); + xfs_log_sb(sc->tp); ++ xfs_log_rtsb(sc->tp, sb_bp); + return 0; + } + #endif /* CONFIG_XFS_ONLINE_REPAIR */