]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: check new rtbitmap records against rt refcount btree
authorDarrick J. Wong <djwong@kernel.org>
Fri, 9 Aug 2024 13:31:07 +0000 (15:31 +0200)
committerChristoph Hellwig <hch@lst.de>
Mon, 12 Aug 2024 11:53:11 +0000 (13:53 +0200)
When we're rebuilding the realtime bitmap, check the proposed free
extents against the rt refcount btree to make sure we don't commit any
grievous errors.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/scrub/repair.c
fs/xfs/scrub/rtbitmap_repair.c

index 5a68d2d72c1e9ff9e0b361230cbfe10e6cc868a5..3b09451b30cfecb6637914e7f91bc695d1a4b37e 100644 (file)
@@ -42,6 +42,7 @@
 #include "xfs_rtgroup.h"
 #include "xfs_rtalloc.h"
 #include "xfs_metafile.h"
+#include "xfs_rtrefcount_btree.h"
 #include "scrub/scrub.h"
 #include "scrub/common.h"
 #include "scrub/trace.h"
@@ -1009,6 +1010,13 @@ xrep_rtgroup_btcur_init(
            xfs_has_rtrmapbt(mp))
                sr->rmap_cur = xfs_rtrmapbt_init_cursor(mp, sc->tp, sr->rtg,
                                        sr->rtg->rtg_inodes[XFS_RTG_RMAP]);
+
+       if (sc->sm->sm_type != XFS_SCRUB_TYPE_RTREFCBT &&
+           (sr->rtlock_flags & XFS_RTGLOCK_REFCOUNT) &&
+           xfs_has_rtreflink(mp))
+               sr->refc_cur = xfs_rtrefcountbt_init_cursor(mp, sc->tp,
+                                       sr->rtg,
+                                       sr->rtg->rtg_inodes[XFS_RTG_REFCOUNT]);
 }
 
 /*
index d7054964c370438fadef0a3772d71b6d1a08daa4..e2887a914fb76db352ab04b64f31c8c7a22735dd 100644 (file)
@@ -22,6 +22,7 @@
 #include "xfs_exchmaps.h"
 #include "xfs_rtbitmap.h"
 #include "xfs_rtgroup.h"
+#include "xfs_refcount.h"
 #include "scrub/scrub.h"
 #include "scrub/common.h"
 #include "scrub/trace.h"
@@ -190,7 +191,8 @@ xrep_rtbitmap_mark_free(
        xfs_rgblock_t           rgbno)
 {
        struct xfs_mount        *mp = rtb->sc->mp;
-       struct xfs_rtgroup      *rtg = rtb->sc->sr.rtg;
+       struct xchk_rt          *sr = &rtb->sc->sr;
+       struct xfs_rtgroup      *rtg = sr->rtg;
        xfs_rtxnum_t            startrtx;
        xfs_rtxnum_t            nextrtx;
        xrep_wordoff_t          wordoff, nextwordoff;
@@ -198,6 +200,7 @@ xrep_rtbitmap_mark_free(
        unsigned int            bufwsize;
        xfs_extlen_t            mod;
        xfs_rtword_t            mask;
+       enum xbtree_recpacking  outcome;
        int                     error;
 
        if (!xfs_verify_rgbext(rtg, rtb->next_rgbno, rgbno - rtb->next_rgbno))
@@ -217,6 +220,25 @@ xrep_rtbitmap_mark_free(
        if (mod != mp->m_sb.sb_rextsize - 1)
                return -EFSCORRUPTED;
 
+       /* Must not be shared or CoW staging. */
+       if (sr->refc_cur) {
+               error = xfs_refcount_has_records(sr->refc_cur,
+                               XFS_REFC_DOMAIN_SHARED, rtb->next_rgbno,
+                               rgbno - rtb->next_rgbno, &outcome);
+               if (error)
+                       return error;
+               if (outcome != XBTREE_RECPACKING_EMPTY)
+                       return -EFSCORRUPTED;
+
+               error = xfs_refcount_has_records(sr->refc_cur,
+                               XFS_REFC_DOMAIN_COW, rtb->next_rgbno,
+                               rgbno - rtb->next_rgbno, &outcome);
+               if (error)
+                       return error;
+               if (outcome != XBTREE_RECPACKING_EMPTY)
+                       return -EFSCORRUPTED;
+       }
+
        trace_xrep_rtbitmap_record_free(mp, startrtx, nextrtx - 1);
 
        /* Set bits as needed to round startrtx up to the nearest word. */