* [PATCH 01/12] xfs: compute the correct fdblocks/frextents for repair when they're negative
2026-09-23 5:57 [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Darrick J. Wong
@ 2026-09-23 6:01 ` Darrick J. Wong
2026-09-23 6:29 ` Christoph Hellwig
2026-09-23 6:01 ` [PATCH 02/12] xfs: mark cow extents bad if there's no rmap mapping for them Darrick J. Wong
` (11 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Darrick J. Wong @ 2026-09-23 6:01 UTC (permalink / raw)
To: cem, djwong; +Cc: stable, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
LOLLM observed that if either fdblocks or frextents are negative, we'll
set the CORRUPT flag and exit immediately. This doesn't work for a
repair because we still have to walk the filesystem metadata to compute
the correct summary counters so that we can install the new values.
Currently we just write zeroes into the summary counters, which isn't
right.
Cc: <stable@vger.kernel.org> # v6.9
Fixes: 4ed080cd7cb077 ("xfs: repair summary counters")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
---
fs/xfs/scrub/fscounters.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c
index 916699f3da7b1f..cd96393a9e6fcf 100644
--- a/fs/xfs/scrub/fscounters.c
+++ b/fs/xfs/scrub/fscounters.c
@@ -541,7 +541,10 @@ xchk_fscounters(
return -EDEADLOCK;
xchk_set_corrupt(sc);
- return 0;
+
+ /* Need to compute all the fields in fsc for a repair */
+ if (!xchk_could_repair(sc))
+ return 0;
}
/* See if icount is obviously wrong. */
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 02/12] xfs: mark cow extents bad if there's no rmap mapping for them
2026-09-23 5:57 [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Darrick J. Wong
2026-09-23 6:01 ` [PATCH 01/12] xfs: compute the correct fdblocks/frextents for repair when they're negative Darrick J. Wong
@ 2026-09-23 6:01 ` Darrick J. Wong
2026-09-24 5:49 ` Christoph Hellwig
2026-09-23 6:01 ` [PATCH 03/12] xfs: clear the symlink zapped flag if inline symlink is ok Darrick J. Wong
` (10 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Darrick J. Wong @ 2026-09-23 6:01 UTC (permalink / raw)
To: cem, djwong; +Cc: stable, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
LOLLM noticed that we fail to mark cow staging extents as bad if there's
a cow staging extent but no rmap record for the cow staging event.
Close this gap.
Cc: <stable@vger.kernel.org> # v6.8
Fixes: dbbdbd0086320a ("xfs: repair problems in CoW forks")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
---
fs/xfs/scrub/cow_repair.c | 84 +++++++++++++++++++++++++++++----------------
1 file changed, 55 insertions(+), 29 deletions(-)
diff --git a/fs/xfs/scrub/cow_repair.c b/fs/xfs/scrub/cow_repair.c
index 8dd9c0266e2169..e49d9396edc527 100644
--- a/fs/xfs/scrub/cow_repair.c
+++ b/fs/xfs/scrub/cow_repair.c
@@ -200,29 +200,35 @@ xrep_cow_mark_missing_staging_rmap(
void *priv)
{
struct xrep_cow *xc = priv;
- xfs_agblock_t rec_bno;
- xfs_extlen_t rec_len;
- unsigned int adj;
+ const xfs_agblock_t rec_end =
+ rec->rm_startblock + rec->rm_blockcount;
+ int error = 0;
- if (rec->rm_owner == XFS_RMAP_OWN_COW)
- return 0;
-
- rec_bno = rec->rm_startblock;
- rec_len = rec->rm_blockcount;
- if (rec_bno < xc->irec_startbno) {
- adj = xc->irec_startbno - rec_bno;
- rec_len -= adj;
- rec_bno += adj;
+ /* Was there a gap since the last rmap? */
+ if (xc->next_bno < rec->rm_startblock) {
+ error = xrep_cow_mark_file_range(xc,
+ xfs_gbno_to_fsb(cur->bc_group, xc->next_bno),
+ rec->rm_startblock - xc->next_bno);
+ if (error)
+ return error;
}
- if (rec_bno + rec_len > xc->irec_startbno + xc->irec.br_blockcount) {
- adj = (rec_bno + rec_len) -
- (xc->irec_startbno + xc->irec.br_blockcount);
- rec_len -= adj;
+ if (rec->rm_owner != XFS_RMAP_OWN_COW) {
+ const xfs_agblock_t bad_bno =
+ max(xc->irec_startbno, rec->rm_startblock);
+ const xfs_agblock_t irec_end =
+ xc->irec_startbno + xc->irec.br_blockcount;
+ const xfs_extlen_t bad_end = min(irec_end, rec_end);
+
+ error = xrep_cow_mark_file_range(xc,
+ xfs_gbno_to_fsb(cur->bc_group, bad_bno),
+ bad_end - bad_bno);
+ if (error)
+ return error;
}
- return xrep_cow_mark_file_range(xc,
- xfs_gbno_to_fsb(cur->bc_group, rec_bno), rec_len);
+ xc->next_bno = max(xc->next_bno, rec_end);
+ return error;
}
/*
@@ -263,10 +269,12 @@ xrep_cow_find_bad(
struct xfs_perag *pag;
struct xfs_scrub *sc = xc->sc;
xfs_agnumber_t agno;
+ xfs_agblock_t irec_end;
int error;
agno = XFS_FSB_TO_AGNO(sc->mp, xc->irec.br_startblock);
xc->irec_startbno = XFS_FSB_TO_AGBNO(sc->mp, xc->irec.br_startblock);
+ irec_end = xc->irec_startbno + xc->irec.br_blockcount;
pag = xfs_perag_get(sc->mp, agno);
if (!pag)
@@ -278,7 +286,7 @@ xrep_cow_find_bad(
/* Mark any CoW fork extents that are shared. */
rc_low.rc_startblock = xc->irec_startbno;
- rc_high.rc_startblock = xc->irec_startbno + xc->irec.br_blockcount - 1;
+ rc_high.rc_startblock = irec_end - 1;
rc_low.rc_domain = rc_high.rc_domain = XFS_REFC_DOMAIN_SHARED;
error = xfs_refcount_query_range(sc->sa.refc_cur, &rc_low, &rc_high,
xrep_cow_mark_shared_staging, xc);
@@ -287,7 +295,7 @@ xrep_cow_find_bad(
/* Make sure there are CoW staging extents for the whole mapping. */
rc_low.rc_startblock = xc->irec_startbno;
- rc_high.rc_startblock = xc->irec_startbno + xc->irec.br_blockcount - 1;
+ rc_high.rc_startblock = irec_end - 1;
rc_low.rc_domain = rc_high.rc_domain = XFS_REFC_DOMAIN_COW;
xc->next_bno = xc->irec_startbno;
error = xfs_refcount_query_range(sc->sa.refc_cur, &rc_low, &rc_high,
@@ -295,11 +303,10 @@ xrep_cow_find_bad(
if (error)
goto out_sa;
- if (xc->next_bno < xc->irec_startbno + xc->irec.br_blockcount) {
+ if (xc->next_bno < irec_end) {
error = xrep_cow_mark_file_range(xc,
xfs_agbno_to_fsb(pag, xc->next_bno),
- xc->irec_startbno + xc->irec.br_blockcount -
- xc->next_bno);
+ irec_end - xc->next_bno);
if (error)
goto out_sa;
}
@@ -308,11 +315,20 @@ xrep_cow_find_bad(
rm_low.rm_startblock = xc->irec_startbno;
memset(&rm_high, 0xFF, sizeof(rm_high));
rm_high.rm_startblock = xc->irec_startbno + xc->irec.br_blockcount - 1;
+ xc->next_bno = xc->irec_startbno;
error = xfs_rmap_query_range(sc->sa.rmap_cur, &rm_low, &rm_high,
xrep_cow_mark_missing_staging_rmap, xc);
if (error)
goto out_sa;
+ if (xc->next_bno < irec_end) {
+ error = xrep_cow_mark_file_range(xc,
+ xfs_agbno_to_fsb(pag, xc->next_bno),
+ irec_end - xc->next_bno);
+ if (error)
+ goto out_sa;
+ }
+
/*
* If userspace is forcing us to rebuild the CoW fork or someone turned
* on the debugging knob, replace everything in the CoW fork.
@@ -344,9 +360,11 @@ xrep_cow_find_bad_rt(
struct xfs_rmap_irec rm_high = { 0 };
struct xfs_scrub *sc = xc->sc;
struct xfs_rtgroup *rtg;
+ xfs_agblock_t irec_end;
int error = 0;
xc->irec_startbno = xfs_rtb_to_rgbno(sc->mp, xc->irec.br_startblock);
+ irec_end = xc->irec_startbno + xc->irec.br_blockcount;
rtg = xfs_rtgroup_get(sc->mp,
xfs_rtb_to_rgno(sc->mp, xc->irec.br_startblock));
@@ -360,7 +378,7 @@ xrep_cow_find_bad_rt(
/* Mark any CoW fork extents that are shared. */
rc_low.rc_startblock = xc->irec_startbno;
- rc_high.rc_startblock = xc->irec_startbno + xc->irec.br_blockcount - 1;
+ rc_high.rc_startblock = irec_end - 1;
rc_low.rc_domain = rc_high.rc_domain = XFS_REFC_DOMAIN_SHARED;
error = xfs_refcount_query_range(sc->sr.refc_cur, &rc_low, &rc_high,
xrep_cow_mark_shared_staging, xc);
@@ -369,7 +387,7 @@ xrep_cow_find_bad_rt(
/* Make sure there are CoW staging extents for the whole mapping. */
rc_low.rc_startblock = xc->irec_startbno;
- rc_high.rc_startblock = xc->irec_startbno + xc->irec.br_blockcount - 1;
+ rc_high.rc_startblock = irec_end - 1;
rc_low.rc_domain = rc_high.rc_domain = XFS_REFC_DOMAIN_COW;
xc->next_bno = xc->irec_startbno;
error = xfs_refcount_query_range(sc->sr.refc_cur, &rc_low, &rc_high,
@@ -377,11 +395,10 @@ xrep_cow_find_bad_rt(
if (error)
goto out_sr;
- if (xc->next_bno < xc->irec_startbno + xc->irec.br_blockcount) {
+ if (xc->next_bno < irec_end) {
error = xrep_cow_mark_file_range(xc,
xfs_rgbno_to_rtb(rtg, xc->next_bno),
- xc->irec_startbno + xc->irec.br_blockcount -
- xc->next_bno);
+ irec_end - xc->next_bno);
if (error)
goto out_sr;
}
@@ -389,12 +406,21 @@ xrep_cow_find_bad_rt(
/* Mark any area has an rmap that isn't a COW staging extent. */
rm_low.rm_startblock = xc->irec_startbno;
memset(&rm_high, 0xFF, sizeof(rm_high));
- rm_high.rm_startblock = xc->irec_startbno + xc->irec.br_blockcount - 1;
+ rm_high.rm_startblock = irec_end - 1;
+ xc->next_bno = xc->irec_startbno;
error = xfs_rmap_query_range(sc->sr.rmap_cur, &rm_low, &rm_high,
xrep_cow_mark_missing_staging_rmap, xc);
if (error)
goto out_sr;
+ if (xc->next_bno < irec_end) {
+ error = xrep_cow_mark_file_range(xc,
+ xfs_rgbno_to_rtb(rtg, xc->next_bno),
+ irec_end - xc->next_bno);
+ if (error)
+ goto out_sr;
+ }
+
/*
* If userspace is forcing us to rebuild the CoW fork or someone
* turned on the debugging knob, replace everything in the
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 03/12] xfs: clear the symlink zapped flag if inline symlink is ok
2026-09-23 5:57 [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Darrick J. Wong
2026-09-23 6:01 ` [PATCH 01/12] xfs: compute the correct fdblocks/frextents for repair when they're negative Darrick J. Wong
2026-09-23 6:01 ` [PATCH 02/12] xfs: mark cow extents bad if there's no rmap mapping for them Darrick J. Wong
@ 2026-09-23 6:01 ` Darrick J. Wong
2026-09-24 5:49 ` Christoph Hellwig
2026-09-23 6:01 ` [PATCH 04/12] xfs: reinitialize dquot block if non-first dquot can't load Darrick J. Wong
` (9 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Darrick J. Wong @ 2026-09-23 6:01 UTC (permalink / raw)
To: cem, djwong; +Cc: stable, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
LOLLM noticed that we fail to clear the SYMLINK_ZAPPED flag if an inline
symlink checks out ok, even after a repair. Fix that.
Cc: <stable@vger.kernel.org> # v6.8
Fixes: d9041681dd2f53 ("xfs: set inode sick state flags when we zap either ondisk fork")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
---
fs/xfs/scrub/symlink.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/fs/xfs/scrub/symlink.c b/fs/xfs/scrub/symlink.c
index 91d40b9fb5c6d2..ed9ca7f737c3cc 100644
--- a/fs/xfs/scrub/symlink.c
+++ b/fs/xfs/scrub/symlink.c
@@ -70,21 +70,20 @@ xchk_symlink(
return 0;
}
- /* Inline symlink? */
if (ifp->if_format == XFS_DINODE_FMT_LOCAL) {
+ /* Inline symlink? */
if (len > xfs_inode_data_fork_size(ip) ||
len > strnlen(ifp->if_data, xfs_inode_data_fork_size(ip)))
xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
- return 0;
+ } else {
+ /* Remote symlink; must read the contents. */
+ error = xfs_symlink_remote_read(sc->ip, sc->buf);
+ if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
+ return error;
+ if (strnlen(sc->buf, XFS_SYMLINK_MAXLEN) < len)
+ xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
}
- /* Remote symlink; must read the contents. */
- error = xfs_symlink_remote_read(sc->ip, sc->buf);
- if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
- return error;
- if (strnlen(sc->buf, XFS_SYMLINK_MAXLEN) < len)
- xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
-
/* If a remote symlink is clean, it is clearly not zapped. */
xchk_mark_healthy_if_clean(sc, XFS_SICK_INO_SYMLINK_ZAPPED);
return 0;
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 04/12] xfs: reinitialize dquot block if non-first dquot can't load
2026-09-23 5:57 [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Darrick J. Wong
` (2 preceding siblings ...)
2026-09-23 6:01 ` [PATCH 03/12] xfs: clear the symlink zapped flag if inline symlink is ok Darrick J. Wong
@ 2026-09-23 6:01 ` Darrick J. Wong
2026-09-24 5:49 ` Christoph Hellwig
2026-09-23 6:02 ` [PATCH 05/12] xfs: fix inode btree repair when a cluster is larger than a chunk Darrick J. Wong
` (8 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Darrick J. Wong @ 2026-09-23 6:01 UTC (permalink / raw)
To: cem, djwong; +Cc: linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
LOLLM noticed that the early exit logic in xrep_quota_block is defective
because it only looks in the first ondisk dquot for corruption that
would prevent dquots from loading. We need to scan all the dquots in
the block, not just the first one.
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
---
fs/xfs/scrub/quota_repair.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/fs/xfs/scrub/quota_repair.c b/fs/xfs/scrub/quota_repair.c
index 89f7ea4f92ef4a..dbbeb858c13c4c 100644
--- a/fs/xfs/scrub/quota_repair.c
+++ b/fs/xfs/scrub/quota_repair.c
@@ -294,7 +294,6 @@ xrep_quota_block(
xfs_dqid_t id)
{
struct xfs_dqblk *dqblk;
- struct xfs_disk_dquot *ddq;
struct xfs_quotainfo *qi = sc->mp->m_quotainfo;
struct xfs_def_quota *defq = xfs_get_defquota(qi, dqtype);
struct xfs_buf *bp = NULL;
@@ -316,14 +315,21 @@ xrep_quota_block(
break;
case 0:
dqblk = bp->b_addr;
- ddq = &dqblk[0].dd_diskdq;
+ error = 0;
/*
* If there's nothing that would impede a dqiterate, we're
* done.
*/
- if ((ddq->d_type & XFS_DQTYPE_REC_MASK) == dqtype &&
- id == be32_to_cpu(ddq->d_id)) {
+ for (i = 0; i < qi->qi_dqperchunk; i++, dqblk++) {
+ struct xfs_disk_dquot *ddq = &dqblk->dd_diskdq;
+
+ if ((ddq->d_type & XFS_DQTYPE_REC_MASK) != dqtype ||
+ id + i != be32_to_cpu(ddq->d_id))
+ error++;
+ }
+
+ if (!error) {
xfs_trans_brelse(sc->tp, bp);
return 0;
}
@@ -336,7 +342,7 @@ xrep_quota_block(
dqblk = bp->b_addr;
bp->b_ops = &xfs_dquot_buf_ops;
for (i = 0; i < qi->qi_dqperchunk; i++, dqblk++) {
- ddq = &dqblk->dd_diskdq;
+ struct xfs_disk_dquot *ddq = &dqblk->dd_diskdq;
trace_xrep_disk_dquot(sc->mp, dqtype, id + i);
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 05/12] xfs: fix inode btree repair when a cluster is larger than a chunk
2026-09-23 5:57 [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Darrick J. Wong
` (3 preceding siblings ...)
2026-09-23 6:01 ` [PATCH 04/12] xfs: reinitialize dquot block if non-first dquot can't load Darrick J. Wong
@ 2026-09-23 6:02 ` Darrick J. Wong
2026-09-24 5:50 ` Christoph Hellwig
2026-09-23 6:02 ` [PATCH 06/12] xfs: fix integer overflow problem when setting large free areas Darrick J. Wong
` (7 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Darrick J. Wong @ 2026-09-23 6:02 UTC (permalink / raw)
To: cem, djwong; +Cc: stable, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
LOLLM noticed that on filesystems where an inode cluster buffer is
larger than an inode chunk, we can run through the loop body in
xrep_ibt_process_cluster more than once, and the number of inodes that
we pass to xrep_ibt_cluster_record is incorrectly large. In this case
we can run right off the end of the buffer. Fix this by moving the
nr_inodes computation inside the loop.
Note that this is only likely to happen on filesystems with (say) 512b
inodes and 64k fsblocks.
Cc: <stable@vger.kernel.org> # v6.8
Fixes: dbfbf3bdf639a2 ("xfs: repair inode btrees")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
---
fs/xfs/scrub/ialloc_repair.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/xfs/scrub/ialloc_repair.c b/fs/xfs/scrub/ialloc_repair.c
index 46b1c8ac5543fb..43846b3bbf4ed4 100644
--- a/fs/xfs/scrub/ialloc_repair.c
+++ b/fs/xfs/scrub/ialloc_repair.c
@@ -293,12 +293,8 @@ xrep_ibt_process_cluster(
struct xfs_ino_geometry *igeo = M_IGEO(mp);
xfs_agino_t cluster_ag_base;
xfs_agino_t irec_index;
- unsigned int nr_inodes;
int error;
- nr_inodes = min_t(unsigned int, igeo->inodes_per_cluster,
- XFS_INODES_PER_CHUNK);
-
/*
* Grab the inode cluster buffer. This is safe to do with a broken
* inobt because imap_to_bp directly maps the buffer without touching
@@ -317,6 +313,10 @@ xrep_ibt_process_cluster(
for (irec_index = 0;
irec_index < igeo->inodes_per_cluster;
irec_index += XFS_INODES_PER_CHUNK) {
+ unsigned int nr_inodes =
+ min_t(unsigned int, XFS_INODES_PER_CHUNK,
+ igeo->inodes_per_cluster - irec_index);
+
error = xrep_ibt_cluster_record(ri,
cluster_ag_base + irec_index, cluster_bp,
nr_inodes);
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 06/12] xfs: fix integer overflow problem when setting large free areas
2026-09-23 5:57 [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Darrick J. Wong
` (4 preceding siblings ...)
2026-09-23 6:02 ` [PATCH 05/12] xfs: fix inode btree repair when a cluster is larger than a chunk Darrick J. Wong
@ 2026-09-23 6:02 ` Darrick J. Wong
2026-09-24 5:51 ` Christoph Hellwig
2026-09-23 6:02 ` [PATCH 07/12] xfs: fix buffer overflow in corrupt inline attr structure Darrick J. Wong
` (6 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Darrick J. Wong @ 2026-09-23 6:02 UTC (permalink / raw)
To: cem, djwong; +Cc: stable, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
LOLLM points out that the min_t comparison in xrep_rtbitmap_mark_free
operates on a 64-bit bitmap word offset quantity and a 32-bit
words-per-block ratio. Unfortunately, I should have done the comparison
with the (64-bit) xrep_wordoff_t type, but used the 32-bit word count
type. Oops.
Cc: <stable@vger.kernel.org> # v6.14
Fixes: 8defee8dff2b20 ("xfs: online repair of realtime bitmaps for a realtime group")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
---
fs/xfs/scrub/rtbitmap_repair.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/xfs/scrub/rtbitmap_repair.c b/fs/xfs/scrub/rtbitmap_repair.c
index 442a17bf972029..f63aaaff783d50 100644
--- a/fs/xfs/scrub/rtbitmap_repair.c
+++ b/fs/xfs/scrub/rtbitmap_repair.c
@@ -276,7 +276,7 @@ xrep_rtbitmap_mark_free(
xrep_wordoff_t rem;
xrep_wordcnt_t wordcnt;
- wordcnt = min_t(xrep_wordcnt_t, nextwordoff - wordoff,
+ wordcnt = min_t(xrep_wordoff_t, nextwordoff - wordoff,
bufwsize);
/*
^ permalink raw reply related [flat|nested] 30+ messages in thread* Re: [PATCH 06/12] xfs: fix integer overflow problem when setting large free areas
2026-09-23 6:02 ` [PATCH 06/12] xfs: fix integer overflow problem when setting large free areas Darrick J. Wong
@ 2026-09-24 5:51 ` Christoph Hellwig
2026-09-24 19:04 ` Darrick J. Wong
0 siblings, 1 reply; 30+ messages in thread
From: Christoph Hellwig @ 2026-09-24 5:51 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: cem, stable, linux-xfs
On Tue, Sep 22, 2026 at 11:02:18PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> LOLLM points out that the min_t comparison in xrep_rtbitmap_mark_free
> operates on a 64-bit bitmap word offset quantity and a 32-bit
> words-per-block ratio. Unfortunately, I should have done the comparison
> with the (64-bit) xrep_wordoff_t type, but used the 32-bit word count
> type. Oops.
I don't think we'll see rtbitmaps beyond 32-bits in our lifetimes, but
the fix still looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 06/12] xfs: fix integer overflow problem when setting large free areas
2026-09-24 5:51 ` Christoph Hellwig
@ 2026-09-24 19:04 ` Darrick J. Wong
0 siblings, 0 replies; 30+ messages in thread
From: Darrick J. Wong @ 2026-09-24 19:04 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: cem, stable, linux-xfs
On Wed, Sep 23, 2026 at 10:51:15PM -0700, Christoph Hellwig wrote:
> On Tue, Sep 22, 2026 at 11:02:18PM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> >
> > LOLLM points out that the min_t comparison in xrep_rtbitmap_mark_free
> > operates on a 64-bit bitmap word offset quantity and a 32-bit
> > words-per-block ratio. Unfortunately, I should have done the comparison
> > with the (64-bit) xrep_wordoff_t type, but used the 32-bit word count
> > type. Oops.
>
> I don't think we'll see rtbitmaps beyond 32-bits in our lifetimes, but
> the fix still looks good:
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
I really hope not. You can't create them at all with rtgroups, and that
usecase was horribly broken (and still unfixed) on old kernels. Thanks
for the review!
--D
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 07/12] xfs: fix buffer overflow in corrupt inline attr structure
2026-09-23 5:57 [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Darrick J. Wong
` (5 preceding siblings ...)
2026-09-23 6:02 ` [PATCH 06/12] xfs: fix integer overflow problem when setting large free areas Darrick J. Wong
@ 2026-09-23 6:02 ` Darrick J. Wong
2026-09-24 5:51 ` Christoph Hellwig
2026-09-23 6:02 ` [PATCH 08/12] xfs: actually report corrupt xattrs as XFAIL during cross-referencing Darrick J. Wong
` (5 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Darrick J. Wong @ 2026-09-23 6:02 UTC (permalink / raw)
To: cem, djwong; +Cc: stable, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
LOLLM noticed a buffer overrun if the xattr scrubber encounters a file
with a shortform attr fork with sf->count > 0 but if_bytes ==
sizeof(struct xfs_attr_sf_hdr). Basically, we have enough data to have
a header with a nonzero count, but no space for any of those shortform
entries. In this case, the xfs_attr_sf_nextentry() call will run off
the end of if_data and blow up.
Cc: <stable@vger.kernel.org> # v6.4
Fixes: ae0506eba78fd1 ("xfs: check used space of shortform xattr structures")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
---
fs/xfs/scrub/attr.c | 11 +++++++++--
fs/xfs/scrub/attr_repair.c | 3 +++
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
index d5226939c81072..7600c711362583 100644
--- a/fs/xfs/scrub/attr.c
+++ b/fs/xfs/scrub/attr.c
@@ -590,12 +590,17 @@ xchk_xattr_check_sf(
}
for (i = 0; i < sf->count; i++) {
- unsigned char *name = sfe->nameval;
- unsigned char *value = &sfe->nameval[sfe->namelen];
+ unsigned char *name;
+ unsigned char *value;
if (xchk_should_terminate(sc, &error))
return error;
+ if ((unsigned char *)(sfe + 1) >= end) {
+ xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0);
+ break;
+ }
+
next = xfs_attr_sf_nextentry(sfe);
if ((unsigned char *)next > end) {
xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0);
@@ -618,6 +623,7 @@ xchk_xattr_check_sf(
break;
}
+ name = sfe->nameval;
if (!xchk_xattr_set_map(sc, ab->usedmap,
(char *)name - (char *)sf,
sfe->namelen)) {
@@ -625,6 +631,7 @@ xchk_xattr_check_sf(
break;
}
+ value = &sfe->nameval[sfe->namelen];
if (!xchk_xattr_set_map(sc, ab->usedmap,
(char *)value - (char *)sf,
sfe->valuelen)) {
diff --git a/fs/xfs/scrub/attr_repair.c b/fs/xfs/scrub/attr_repair.c
index 28f92e9ba72b24..ac433a5467516d 100644
--- a/fs/xfs/scrub/attr_repair.c
+++ b/fs/xfs/scrub/attr_repair.c
@@ -477,6 +477,9 @@ xrep_xattr_recover_sf(
if (xchk_should_terminate(sc, &error))
return error;
+ if ((unsigned char *)(sfe + 1) >= end)
+ break;
+
next = xfs_attr_sf_nextentry(sfe);
if ((unsigned char *)next > end)
break;
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 08/12] xfs: actually report corrupt xattrs as XFAIL during cross-referencing
2026-09-23 5:57 [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Darrick J. Wong
` (6 preceding siblings ...)
2026-09-23 6:02 ` [PATCH 07/12] xfs: fix buffer overflow in corrupt inline attr structure Darrick J. Wong
@ 2026-09-23 6:02 ` Darrick J. Wong
2026-09-24 5:51 ` Christoph Hellwig
2026-09-23 6:03 ` [PATCH 09/12] xfs: improve dir block reporting when cross-referencing dirents to pptrs Darrick J. Wong
` (4 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Darrick J. Wong @ 2026-09-23 6:02 UTC (permalink / raw)
To: cem, djwong; +Cc: stable, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Some LLM reports that xchk_dir_parent_pointer really ought to report
xattr corruption errors as XFAIL (cross-referencing failed) when a
directory scrub tries to find the parent pointer for a dirent name.
Let's do that.
Cc: <stable@vger.kernel.org> # v6.10
Fixes: 61b3f0df5c2358 ("xfs: check dirents have parent pointers")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
fs/xfs/scrub/dir.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index 19d974c7e2b7a9..4ab7e646924828 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -155,6 +155,8 @@ xchk_dir_parent_pointer(
&sd->pptr_args);
if (error == -ENOATTR)
xchk_fblock_xref_set_corrupt(sc, XFS_DATA_FORK, 0);
+ else
+ xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error);
return 0;
}
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 09/12] xfs: improve dir block reporting when cross-referencing dirents to pptrs
2026-09-23 5:57 [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Darrick J. Wong
` (7 preceding siblings ...)
2026-09-23 6:02 ` [PATCH 08/12] xfs: actually report corrupt xattrs as XFAIL during cross-referencing Darrick J. Wong
@ 2026-09-23 6:03 ` Darrick J. Wong
2026-09-24 5:52 ` Christoph Hellwig
2026-09-23 6:03 ` [PATCH 10/12] xfs: fix unnecessary dapos truncation in xchk_dir_walk Darrick J. Wong
` (3 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Darrick J. Wong @ 2026-09-23 6:03 UTC (permalink / raw)
To: cem, djwong; +Cc: linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
When we're scrubbing a directory, we could pass the file block number of
the dirent that we're scanning to the parent pointer cross-referencing
functions. This improves the accuracy of the scrub tracing data if
something goes wrong. In practice this matters very little, but the
next patch fixes a truncation bug that affects the same tracing, so I
decided to clean everything up all at once.
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
fs/xfs/scrub/dir.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index 4ab7e646924828..a63eebf39fd496 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -144,6 +144,7 @@ xchk_dir_lock_child(
STATIC int
xchk_dir_parent_pointer(
struct xchk_dir *sd,
+ xfs_dablk_t offset,
const struct xfs_name *name,
struct xfs_inode *ip)
{
@@ -154,9 +155,10 @@ xchk_dir_parent_pointer(
error = xfs_parent_lookup(sc->tp, ip, name, &sd->pptr_rec,
&sd->pptr_args);
if (error == -ENOATTR)
- xchk_fblock_xref_set_corrupt(sc, XFS_DATA_FORK, 0);
+ xchk_fblock_xref_set_corrupt(sc, XFS_DATA_FORK, offset);
else
- xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error);
+ xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, offset,
+ &error);
return 0;
}
@@ -165,7 +167,7 @@ xchk_dir_parent_pointer(
STATIC int
xchk_dir_check_pptr_fast(
struct xchk_dir *sd,
- xfs_dir2_dataptr_t dapos,
+ xfs_dablk_t offset,
const struct xfs_name *name,
struct xfs_inode *ip)
{
@@ -180,7 +182,7 @@ xchk_dir_check_pptr_fast(
/* No self-referential non-dot or dotdot dirents. */
if (ip == sc->ip) {
- xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
+ xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
return -ECANCELED;
}
@@ -197,19 +199,19 @@ xchk_dir_check_pptr_fast(
error = xfblob_storename(sd->dir_names, &save_de.name_cookie,
name);
- if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0,
+ if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, offset,
&error))
return error;
error = xfarray_append(sd->dir_entries, &save_de);
- if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0,
+ if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, offset,
&error))
return error;
return 0;
}
- error = xchk_dir_parent_pointer(sd, name, ip);
+ error = xchk_dir_parent_pointer(sd, offset, name, ip);
xfs_iunlock(ip, lockmode);
return error;
}
@@ -300,7 +302,7 @@ xchk_dir_actor(
xchk_dir_check_ftype(sc, offset, ip, name->type);
if (xfs_has_parent(mp)) {
- error = xchk_dir_check_pptr_fast(sd, dapos, name, ip);
+ error = xchk_dir_check_pptr_fast(sd, offset, name, ip);
if (error)
goto out_rele;
}
@@ -1025,7 +1027,7 @@ xchk_dir_slow_dirent(
goto out_unlock;
check_pptr:
- error = xchk_dir_parent_pointer(sd, xname, ip);
+ error = xchk_dir_parent_pointer(sd, 0, xname, ip);
out_unlock:
xfs_iunlock(ip, lockmode);
out_rele:
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 10/12] xfs: fix unnecessary dapos truncation in xchk_dir_walk
2026-09-23 5:57 [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Darrick J. Wong
` (8 preceding siblings ...)
2026-09-23 6:03 ` [PATCH 09/12] xfs: improve dir block reporting when cross-referencing dirents to pptrs Darrick J. Wong
@ 2026-09-23 6:03 ` Darrick J. Wong
2026-09-24 5:54 ` Christoph Hellwig
2026-09-23 6:03 ` [PATCH 11/12] xfs: actually lock the metafile reservation when adjusting after repair Darrick J. Wong
` (2 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Darrick J. Wong @ 2026-09-23 6:03 UTC (permalink / raw)
To: cem, djwong; +Cc: stable, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
LOLLM points out that the all the implementations of xchk_dirent_fn can
handle a signed @dapos parameter, so the truncation here breaks the
information captured in scrub tracepoints if the directory is very
large. I don't think it ever made sense to do the truncation for the
VFS readdir code for programs that can handle 64-bit offsets, but commit
15440319767942 has been around for 17 years without complaints so I'll
leave that alone.
Stumbled-over: 15440319767942 ("[XFS] truncate readdir offsets to signed 32 bit values")
Cc: <stable@vger.kernel.org> # v6.4
Fixes: 4c233b5c4f29df ("xfs: streamline the directory iteration code for scrub")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
---
fs/xfs/scrub/readdir.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/xfs/scrub/readdir.c b/fs/xfs/scrub/readdir.c
index d68bf20b4a148d..970d43030704e1 100644
--- a/fs/xfs/scrub/readdir.c
+++ b/fs/xfs/scrub/readdir.c
@@ -238,7 +238,7 @@ xchk_dir_walk_leaf(
dep = bp->b_addr + offset;
length = xfs_dir2_data_entsize(mp, dep->namelen);
- dapos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;
+ dapos = xfs_dir2_byte_to_dataptr(curoff);
ino = be64_to_cpu(dep->inumber);
name.name = dep->name;
name.len = dep->namelen;
^ permalink raw reply related [flat|nested] 30+ messages in thread* Re: [PATCH 10/12] xfs: fix unnecessary dapos truncation in xchk_dir_walk
2026-09-23 6:03 ` [PATCH 10/12] xfs: fix unnecessary dapos truncation in xchk_dir_walk Darrick J. Wong
@ 2026-09-24 5:54 ` Christoph Hellwig
0 siblings, 0 replies; 30+ messages in thread
From: Christoph Hellwig @ 2026-09-24 5:54 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: cem, stable, linux-xfs
On Tue, Sep 22, 2026 at 11:03:20PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> LOLLM points out that the all the implementations of xchk_dirent_fn can
> handle a signed @dapos parameter, so the truncation here breaks the
> information captured in scrub tracepoints if the directory is very
> large. I don't think it ever made sense to do the truncation for the
> VFS readdir code for programs that can handle 64-bit offsets, but commit
> 15440319767942 has been around for 17 years without complaints so I'll
> leave that alone.
That code doesn't make sense for various other reasons..
But the Posix definition of seekdir/telldir, to which the offset is tied,
have a hardcoded signed long, not a off_t of some kind, so we can't
really go beyond that. But silently truncating in readdir for this
almost impossible to hit case doesn't make thing better.
Enough ranting, the fix itself looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 11/12] xfs: actually lock the metafile reservation when adjusting after repair
2026-09-23 5:57 [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Darrick J. Wong
` (9 preceding siblings ...)
2026-09-23 6:03 ` [PATCH 10/12] xfs: fix unnecessary dapos truncation in xchk_dir_walk Darrick J. Wong
@ 2026-09-23 6:03 ` Darrick J. Wong
2026-09-24 5:55 ` Christoph Hellwig
2026-09-23 6:03 ` [PATCH 12/12] xfs: avoid cross-rtgroup reaping after a repair Darrick J. Wong
2026-10-05 18:06 ` [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Carlos Maiolino
12 siblings, 1 reply; 30+ messages in thread
From: Darrick J. Wong @ 2026-09-23 6:03 UTC (permalink / raw)
To: cem, djwong; +Cc: hch, stable, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
LOLLM reported that xrep_reset_metafile_resv performs unlocked loads
and stores to the metadata file space reservation counters and thus can
race with other threads. Fix this by taking the lock.
Cc: <hch@lst.de>
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
---
fs/xfs/scrub/repair.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c
index c2a437416227a8..956aa75218aa24 100644
--- a/fs/xfs/scrub/repair.c
+++ b/fs/xfs/scrub/repair.c
@@ -1377,12 +1377,14 @@ xrep_reset_metafile_resv(
{
struct xfs_mount *mp = sc->mp;
int64_t delta;
- int error;
+ int error = 0;
+
+ mutex_lock(&mp->m_metafile_resv_lock);
delta = mp->m_metafile_resv_used + mp->m_metafile_resv_avail -
mp->m_metafile_resv_target;
if (delta == 0)
- return 0;
+ goto out_resv_lock;
/*
* Too many blocks have been reserved, transfer some from the incore
@@ -1398,7 +1400,7 @@ xrep_reset_metafile_resv(
mp->m_metafile_resv_avail -= give_back;
}
- return 0;
+ goto out_resv_lock;
}
/*
@@ -1412,14 +1414,18 @@ xrep_reset_metafile_resv(
if (delta == 0) {
xfs_warn(sc->mp,
"Insufficient free space to reset metabtree reservation after repair.");
- return 0;
+ error = 0;
+ goto out_resv_lock;
}
error = xfs_dec_fdblocks(mp, delta, true);
}
if (error)
- return error;
+ goto out_resv_lock;
xfs_mod_sb_delalloc(mp, delta);
mp->m_metafile_resv_avail += delta;
- return 0;
+
+out_resv_lock:
+ mutex_unlock(&mp->m_metafile_resv_lock);
+ return error;
}
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 12/12] xfs: avoid cross-rtgroup reaping after a repair
2026-09-23 5:57 [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Darrick J. Wong
` (10 preceding siblings ...)
2026-09-23 6:03 ` [PATCH 11/12] xfs: actually lock the metafile reservation when adjusting after repair Darrick J. Wong
@ 2026-09-23 6:03 ` Darrick J. Wong
2026-09-24 5:57 ` Christoph Hellwig
2026-10-05 18:06 ` [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Carlos Maiolino
12 siblings, 1 reply; 30+ messages in thread
From: Darrick J. Wong @ 2026-09-23 6:03 UTC (permalink / raw)
To: cem, djwong; +Cc: stable, linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
LOLLM notices that the extents stored in a xrtb_bitmap (aka xfs_rtblock
bitmap) can span multiple rtgroups due to two circumstances. The first
is that the size of an rtgroup is an exact power of two, which means
that rtgroups are adjacent in the segmented xfs_rtblock_t address space.
This is fairly common to reduce the amount of multiplication and
division needed to handle space on the rt volume.
The second is that (unlike in the original rtgroups design), rtgroups do
not have fixed-location metadata like AGs do, which means that there's
nothing to force a break between rtgroups.
Therefore, we must loop through the rtgroups in xreap_rtmeta_extent to
avoid running off the end of an rtgroup while reaping.
Cc: <stable@vger.kernel.org> # v6.14
Fixes: fd97fe1112088c ("xfs: fix CoW forks for realtime files")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
---
fs/xfs/scrub/reap.c | 59 +++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 48 insertions(+), 11 deletions(-)
diff --git a/fs/xfs/scrub/reap.c b/fs/xfs/scrub/reap.c
index f698b9be3dd1df..bf04a85bc81689 100644
--- a/fs/xfs/scrub/reap.c
+++ b/fs/xfs/scrub/reap.c
@@ -1080,26 +1080,23 @@ xreap_configure_rgcow_limits(
XFS_RTGLOCK_RMAP | \
XFS_RTGLOCK_REFCOUNT)
-/*
- * Break a rt file metadata extent into sub-extents by fate (crosslinked, not
- * crosslinked), and dispose of each sub-extent separately. The extent must
- * be aligned to a realtime extent.
- */
-STATIC int
-xreap_rtmeta_extent(
- uint64_t rtbno,
+static int
+xreap_rtgroup_extent(
+ struct xreap_state *rs,
+ xfs_rtblock_t rtbno,
uint64_t len,
- void *priv)
+ xfs_rgblock_t *done)
{
- struct xreap_state *rs = priv;
struct xfs_scrub *sc = rs->sc;
xfs_rgblock_t rgbno = xfs_rtb_to_rgbno(sc->mp, rtbno);
- xfs_rgblock_t rgbno_next = rgbno + len;
+ xfs_rgblock_t rgbno_next;
int error = 0;
ASSERT(sc->ip != NULL);
ASSERT(!sc->sr.rtg);
+ *done = 0;
+
/*
* We're reaping blocks after repairing file metadata, which means that
* we have to init the xchk_ag structure ourselves.
@@ -1110,6 +1107,7 @@ xreap_rtmeta_extent(
xfs_rtgroup_lock(sc->sr.rtg, XREAP_RTGLOCK_ALL);
+ rgbno_next = rgbno + min(len, (uint64_t)rtg_blocks(sc->sr.rtg) - rgbno);
while (rgbno < rgbno_next) {
xfs_extlen_t rglen;
bool crosslinked;
@@ -1136,6 +1134,7 @@ xreap_rtmeta_extent(
}
rgbno += rglen;
+ *done += rglen;
}
out_unlock:
@@ -1145,6 +1144,44 @@ xreap_rtmeta_extent(
return error;
}
+/*
+ * Break a rt file metadata extent into sub-extents by fate (crosslinked, not
+ * crosslinked), and dispose of each sub-extent separately. The extent must
+ * be aligned to a realtime extent.
+ */
+STATIC int
+xreap_rtmeta_extent(
+ uint64_t rtbno,
+ uint64_t len,
+ void *priv)
+{
+ struct xreap_state *rs = priv;
+ int error;
+
+ /*
+ * Space from adjacent rtgroups can be stored as a single bitmap extent
+ * because rtgroups do not have fixed-location metadata such as a
+ * per-group superblock that cannot be reaped. Handle these overlaps
+ * by only reaping within a single rtgroup at a time.
+ *
+ * In the somewhat unlikely event that an rtgroup size is not a power
+ * of two, the segmented nature of xfs_rtblock_t prevents space in
+ * adjacent rtgroups from merging in the bitmap.
+ */
+ while (len > 0) {
+ xfs_rgblock_t done = 0;
+
+ error = xreap_rtgroup_extent(rs, rtbno, len, &done);
+ if (error)
+ return error;
+
+ rtbno += done;
+ len -= done;
+ }
+
+ return 0;
+}
+
/*
* Dispose of every block of every rt metadata extent in the bitmap.
* Do not use this to dispose of the mappings in an ondisk inode fork.
^ permalink raw reply related [flat|nested] 30+ messages in thread* Re: [PATCH 12/12] xfs: avoid cross-rtgroup reaping after a repair
2026-09-23 6:03 ` [PATCH 12/12] xfs: avoid cross-rtgroup reaping after a repair Darrick J. Wong
@ 2026-09-24 5:57 ` Christoph Hellwig
2026-09-24 19:34 ` Darrick J. Wong
0 siblings, 1 reply; 30+ messages in thread
From: Christoph Hellwig @ 2026-09-24 5:57 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: cem, stable, linux-xfs
On Tue, Sep 22, 2026 at 11:03:52PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> LOLLM notices that the extents stored in a xrtb_bitmap (aka xfs_rtblock
> bitmap) can span multiple rtgroups due to two circumstances. The first
> is that the size of an rtgroup is an exact power of two, which means
> that rtgroups are adjacent in the segmented xfs_rtblock_t address space.
> This is fairly common to reduce the amount of multiplication and
> division needed to handle space on the rt volume.
>
> The second is that (unlike in the original rtgroups design), rtgroups do
> not have fixed-location metadata like AGs do, which means that there's
> nothing to force a break between rtgroups.
>
> Therefore, we must loop through the rtgroups in xreap_rtmeta_extent to
> avoid running off the end of an rtgroup while reaping.
This fix looks good.
Sashiko complains this could use some additional input sanitization,
though.
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 12/12] xfs: avoid cross-rtgroup reaping after a repair
2026-09-24 5:57 ` Christoph Hellwig
@ 2026-09-24 19:34 ` Darrick J. Wong
2026-10-05 10:05 ` Carlos Maiolino
0 siblings, 1 reply; 30+ messages in thread
From: Darrick J. Wong @ 2026-09-24 19:34 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: cem, stable, linux-xfs
On Wed, Sep 23, 2026 at 10:57:09PM -0700, Christoph Hellwig wrote:
> On Tue, Sep 22, 2026 at 11:03:52PM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> >
> > LOLLM notices that the extents stored in a xrtb_bitmap (aka xfs_rtblock
> > bitmap) can span multiple rtgroups due to two circumstances. The first
> > is that the size of an rtgroup is an exact power of two, which means
> > that rtgroups are adjacent in the segmented xfs_rtblock_t address space.
> > This is fairly common to reduce the amount of multiplication and
> > division needed to handle space on the rt volume.
> >
> > The second is that (unlike in the original rtgroups design), rtgroups do
> > not have fixed-location metadata like AGs do, which means that there's
> > nothing to force a break between rtgroups.
> >
> > Therefore, we must loop through the rtgroups in xreap_rtmeta_extent to
> > avoid running off the end of an rtgroup while reaping.
>
> This fix looks good.
>
> Sashiko complains this could use some additional input sanitization,
> though.
Oh yeah. If rgbno points into the gap between rtgroups, we should
advance *done to the start of the next rtgroup.
--D
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 12/12] xfs: avoid cross-rtgroup reaping after a repair
2026-09-24 19:34 ` Darrick J. Wong
@ 2026-10-05 10:05 ` Carlos Maiolino
2026-10-05 14:40 ` Darrick J. Wong
0 siblings, 1 reply; 30+ messages in thread
From: Carlos Maiolino @ 2026-10-05 10:05 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: Christoph Hellwig, stable, linux-xfs
On Thu, Sep 24, 2026 at 12:34:31PM -0700, Darrick J. Wong wrote:
> On Wed, Sep 23, 2026 at 10:57:09PM -0700, Christoph Hellwig wrote:
> > On Tue, Sep 22, 2026 at 11:03:52PM -0700, Darrick J. Wong wrote:
> > > From: Darrick J. Wong <djwong@kernel.org>
> > >
> > > LOLLM notices that the extents stored in a xrtb_bitmap (aka xfs_rtblock
> > > bitmap) can span multiple rtgroups due to two circumstances. The first
> > > is that the size of an rtgroup is an exact power of two, which means
> > > that rtgroups are adjacent in the segmented xfs_rtblock_t address space.
> > > This is fairly common to reduce the amount of multiplication and
> > > division needed to handle space on the rt volume.
> > >
> > > The second is that (unlike in the original rtgroups design), rtgroups do
> > > not have fixed-location metadata like AGs do, which means that there's
> > > nothing to force a break between rtgroups.
> > >
> > > Therefore, we must loop through the rtgroups in xreap_rtmeta_extent to
> > > avoid running off the end of an rtgroup while reaping.
> >
> > This fix looks good.
> >
> > Sashiko complains this could use some additional input sanitization,
> > though.
>
> Oh yeah. If rgbno points into the gap between rtgroups, we should
> advance *done to the start of the next rtgroup.
I think we can go with this series now and add that later, no need to
re-send the series just for this case IMHO.
>
> --D
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 12/12] xfs: avoid cross-rtgroup reaping after a repair
2026-10-05 10:05 ` Carlos Maiolino
@ 2026-10-05 14:40 ` Darrick J. Wong
0 siblings, 0 replies; 30+ messages in thread
From: Darrick J. Wong @ 2026-10-05 14:40 UTC (permalink / raw)
To: Carlos Maiolino; +Cc: Christoph Hellwig, stable, linux-xfs
On Mon, Oct 05, 2026 at 12:05:16PM +0200, Carlos Maiolino wrote:
> On Thu, Sep 24, 2026 at 12:34:31PM -0700, Darrick J. Wong wrote:
> > On Wed, Sep 23, 2026 at 10:57:09PM -0700, Christoph Hellwig wrote:
> > > On Tue, Sep 22, 2026 at 11:03:52PM -0700, Darrick J. Wong wrote:
> > > > From: Darrick J. Wong <djwong@kernel.org>
> > > >
> > > > LOLLM notices that the extents stored in a xrtb_bitmap (aka xfs_rtblock
> > > > bitmap) can span multiple rtgroups due to two circumstances. The first
> > > > is that the size of an rtgroup is an exact power of two, which means
> > > > that rtgroups are adjacent in the segmented xfs_rtblock_t address space.
> > > > This is fairly common to reduce the amount of multiplication and
> > > > division needed to handle space on the rt volume.
> > > >
> > > > The second is that (unlike in the original rtgroups design), rtgroups do
> > > > not have fixed-location metadata like AGs do, which means that there's
> > > > nothing to force a break between rtgroups.
> > > >
> > > > Therefore, we must loop through the rtgroups in xreap_rtmeta_extent to
> > > > avoid running off the end of an rtgroup while reaping.
> > >
> > > This fix looks good.
> > >
> > > Sashiko complains this could use some additional input sanitization,
> > > though.
> >
> > Oh yeah. If rgbno points into the gap between rtgroups, we should
> > advance *done to the start of the next rtgroup.
>
> I think we can go with this series now and add that later, no need to
> re-send the series just for this case IMHO.
Sounds good to me. All the patches that don't make it into first 24
batches can just slide into the last one. ;)
--D
> >
> > --D
> >
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17
2026-09-23 5:57 [PATCHSET 2/2] xfs: LLM-inspired bug fixes, part 17 Darrick J. Wong
` (11 preceding siblings ...)
2026-09-23 6:03 ` [PATCH 12/12] xfs: avoid cross-rtgroup reaping after a repair Darrick J. Wong
@ 2026-10-05 18:06 ` Carlos Maiolino
12 siblings, 0 replies; 30+ messages in thread
From: Carlos Maiolino @ 2026-10-05 18:06 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: hch, stable, linux-xfs
On Tue, 22 Sep 2026 22:57:31 -0700, Darrick J. Wong wrote:
> Here's a seventeenth batch of xfs fixes resulting from a LLaMma. Mwa mwa
> mwa...
>
> If you're going to start using this code, I strongly recommend pulling
> from my git trees, which are linked below.
>
> With a bit of luck, this should all go splendidly.
> Comments and questions are, as always, welcome.
>
> [...]
Applied to for-next, thanks!
[01/12] xfs: compute the correct fdblocks/frextents for repair when they're negative
commit: f98d007017acf0eaec2e116ff9c0ece735f61bb3
[02/12] xfs: mark cow extents bad if there's no rmap mapping for them
commit: 2ffc0619c9c2881443c5fffb10db8f2bc0aa2ce8
[03/12] xfs: clear the symlink zapped flag if inline symlink is ok
commit: f8d0d90f2e24b1f4a14796ae63cebfd820cadfcd
[04/12] xfs: reinitialize dquot block if non-first dquot can't load
commit: faa9aa9e846332aaad78096a2cebfeafe68a7776
[05/12] xfs: fix inode btree repair when a cluster is larger than a chunk
commit: 65b89ac3e8c2f041384f715a71b9d113edfa32e5
[06/12] xfs: fix integer overflow problem when setting large free areas
commit: 7e55f84434f3a63d59feb8f89076d280ea9aa8e5
[07/12] xfs: fix buffer overflow in corrupt inline attr structure
commit: 017dd7a84ff4cd2275eb62f4ee6d63c705bac107
[08/12] xfs: actually report corrupt xattrs as XFAIL during cross-referencing
commit: b339cc253019518c61b8b150fb7ea727fdae59f4
[09/12] xfs: improve dir block reporting when cross-referencing dirents to pptrs
commit: 559c9d4259aa4f0a3fc251c4c9ef6aa0c2d08116
[10/12] xfs: fix unnecessary dapos truncation in xchk_dir_walk
commit: f60a2ef8d8a7ac6dedf4d0c3325cc3fc2fe0d948
[11/12] xfs: actually lock the metafile reservation when adjusting after repair
commit: e53c620b3670fc0c162b5f768a10a3a17d0c04f6
[12/12] xfs: avoid cross-rtgroup reaping after a repair
commit: d7c204d4ea7ef0cf0dac908388984c2936f1f94e
Best regards,
--
Carlos Maiolino <cem@kernel.org>
^ permalink raw reply [flat|nested] 30+ messages in thread