mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
xfs: fix rtgroup repair estimations
When I added online fsck for realtime reflink, I forgot to update
xrep_calc_rtgroup_resblks to factor in the size of the refcount btree
when it guesses how much space we need to start a repair. This hasn't
been a huge problem in practice because there are few filesystems with
(a) realtime, (b) rtgroups, (c) reflink, and (d) no rmap. But let's fix
this before someone stumbles upon it, especially since LOLLM flagged
this for me.
Cc: stable@vger.kernel.org # v6.14
Fixes: 83ccffc489 ("xfs: online repair of the realtime refcount 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>
This commit is contained in:
parent
065f3ce593
commit
41c4c41cf6
|
|
@ -399,6 +399,7 @@ xrep_calc_rtgroup_resblks(
|
|||
struct xfs_mount *mp = sc->mp;
|
||||
struct xfs_scrub_metadata *sm = sc->sm;
|
||||
uint64_t usedlen;
|
||||
xfs_extlen_t refcbt_sz = 0;
|
||||
xfs_extlen_t rmapbt_sz = 0;
|
||||
|
||||
if (!(sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR))
|
||||
|
|
@ -411,13 +412,27 @@ xrep_calc_rtgroup_resblks(
|
|||
usedlen = xfs_rtbxlen_to_blen(mp, xfs_rtgroup_extents(mp, sm->sm_agno));
|
||||
ASSERT(usedlen <= XFS_MAX_RGBLOCKS);
|
||||
|
||||
if (xfs_has_reflink(mp))
|
||||
refcbt_sz = xfs_rtrefcountbt_calc_size(mp, usedlen);
|
||||
|
||||
if (xfs_has_rmapbt(mp))
|
||||
rmapbt_sz = xfs_rtrmapbt_calc_size(mp, usedlen);
|
||||
|
||||
trace_xrep_calc_rtgroup_resblks_btsize(mp, sm->sm_agno, usedlen,
|
||||
rmapbt_sz);
|
||||
/*
|
||||
* Guess how many blocks we need to rebuild the rmapbt. For
|
||||
* non-reflink filesystems we can't have more records than used blocks.
|
||||
* However, with reflink it's possible to have more than one rmap
|
||||
* record per rtgroup block. We don't know how many rmaps there could
|
||||
* be in the rtgroup, so we start off with what we hope is an generous
|
||||
* over-estimation.
|
||||
*/
|
||||
if (refcbt_sz > 0 && rmapbt_sz > 0)
|
||||
rmapbt_sz *= 2;
|
||||
|
||||
return rmapbt_sz;
|
||||
trace_xrep_calc_rtgroup_resblks_btsize(mp, sm->sm_agno, usedlen,
|
||||
rmapbt_sz, refcbt_sz);
|
||||
|
||||
return max(rmapbt_sz, refcbt_sz);
|
||||
}
|
||||
#endif /* CONFIG_XFS_RT */
|
||||
|
||||
|
|
|
|||
|
|
@ -2376,25 +2376,29 @@ TRACE_EVENT(xrep_calc_ag_resblks_btsize,
|
|||
#ifdef CONFIG_XFS_RT
|
||||
TRACE_EVENT(xrep_calc_rtgroup_resblks_btsize,
|
||||
TP_PROTO(struct xfs_mount *mp, xfs_rgnumber_t rgno,
|
||||
xfs_rgblock_t usedlen, xfs_rgblock_t rmapbt_sz),
|
||||
TP_ARGS(mp, rgno, usedlen, rmapbt_sz),
|
||||
xfs_rgblock_t usedlen, xfs_rgblock_t rmapbt_sz,
|
||||
xfs_rgblock_t refcbt_sz),
|
||||
TP_ARGS(mp, rgno, usedlen, rmapbt_sz, refcbt_sz),
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
__field(xfs_rgnumber_t, rgno)
|
||||
__field(xfs_rgblock_t, usedlen)
|
||||
__field(xfs_rgblock_t, rmapbt_sz)
|
||||
__field(xfs_rgblock_t, refcbt_sz)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->dev = mp->m_super->s_dev;
|
||||
__entry->rgno = rgno;
|
||||
__entry->usedlen = usedlen;
|
||||
__entry->rmapbt_sz = rmapbt_sz;
|
||||
__entry->refcbt_sz = refcbt_sz;
|
||||
),
|
||||
TP_printk("dev %d:%d rgno 0x%x usedlen %u rmapbt %u",
|
||||
TP_printk("dev %d:%d rgno 0x%x usedlen %u rmapbt %u refcountbt %u",
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev),
|
||||
__entry->rgno,
|
||||
__entry->usedlen,
|
||||
__entry->rmapbt_sz)
|
||||
__entry->rmapbt_sz,
|
||||
__entry->refcbt_sz)
|
||||
);
|
||||
#endif /* CONFIG_XFS_RT */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user