xfs
[Top] [All Lists]

[PATCH 19/25] xfs: cross-reference bnobt records with cntbt

To: david@xxxxxxxxxxxxx, darrick.wong@xxxxxxxxxx
Subject: [PATCH 19/25] xfs: cross-reference bnobt records with cntbt
From: "Darrick J. Wong" <darrick.wong@xxxxxxxxxx>
Date: Thu, 25 Aug 2016 16:42:15 -0700
Cc: linux-xfs@xxxxxxxxxxxxxxx, xfs@xxxxxxxxxxx
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <147216841262.3108.10746252464845687338.stgit@xxxxxxxxxxxxxxxx>
References: <147216841262.3108.10746252464845687338.stgit@xxxxxxxxxxxxxxxx>
User-agent: StGit/0.17.1-dirty
Scrub should make sure that each bnobt record has a corresponding
cntbt record.

Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
---
 fs/xfs/libxfs/xfs_alloc.c |    2 +-
 fs/xfs/libxfs/xfs_alloc.h |    7 +++++++
 fs/xfs/xfs_scrub.c        |   24 ++++++++++++++++++++++++
 3 files changed, 32 insertions(+), 1 deletion(-)


diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index 0de83f5..a65cd8d 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -170,7 +170,7 @@ xfs_alloc_lookup_ge(
  * Lookup the first record less than or equal to [bno, len]
  * in the btree given by cur.
  */
-static int                             /* error */
+int                                    /* error */
 xfs_alloc_lookup_le(
        struct xfs_btree_cur    *cur,   /* btree cursor */
        xfs_agblock_t           bno,    /* starting block of extent */
diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h
index b740456..2afc024 100644
--- a/fs/xfs/libxfs/xfs_alloc.h
+++ b/fs/xfs/libxfs/xfs_alloc.h
@@ -189,6 +189,13 @@ xfs_free_extent(
        enum xfs_ag_resv_type   type);  /* block reservation type */
 
 int                            /* error */
+xfs_alloc_lookup_le(
+       struct xfs_btree_cur    *cur,   /* btree cursor */
+       xfs_agblock_t           bno,    /* starting block of extent */
+       xfs_extlen_t            len,    /* length of extent */
+       int                     *stat); /* success/failure */
+
+int                            /* error */
 xfs_alloc_lookup_ge(
        struct xfs_btree_cur    *cur,   /* btree cursor */
        xfs_agblock_t           bno,    /* starting block of extent */
diff --git a/fs/xfs/xfs_scrub.c b/fs/xfs/xfs_scrub.c
index 612d3c3..66365e2 100644
--- a/fs/xfs/xfs_scrub.c
+++ b/fs/xfs/xfs_scrub.c
@@ -1096,9 +1096,14 @@ xfs_scrub_allocbt_helper(
 {
        struct xfs_mount                *mp = bs->cur->bc_mp;
        struct xfs_agf                  *agf;
+       struct xfs_btree_cur            *other_cur;
+       xfs_agblock_t                   fbno;
        xfs_agblock_t                   bno;
+       xfs_extlen_t                    flen;
        xfs_extlen_t                    len;
+       int                             has_otherrec;
        int                             error = 0;
+       int                             err2;
 
        bno = be32_to_cpu(rec->alloc.ar_startblock);
        len = be32_to_cpu(rec->alloc.ar_blockcount);
@@ -1112,6 +1117,25 @@ xfs_scrub_allocbt_helper(
        XFS_BTREC_SCRUB_CHECK(bs, (unsigned long long)bno + len <=
                        be32_to_cpu(agf->agf_length));
 
+       /*
+        * Ensure there's a corresponding cntbt/bnobt record matching
+        * this bnobt/cntbt record, respectively.
+        */
+       other_cur = (bs->cnt_cur ? bs->cnt_cur : bs->bno_cur);
+       err2 = xfs_alloc_lookup_le(other_cur, bno, len, &has_otherrec);
+       if (err2)
+               goto skip_freesp_xref;
+       XFS_BTREC_SCRUB_CHECK(bs, has_otherrec);
+       if (!has_otherrec)
+               goto skip_freesp_xref;
+       err2 = xfs_alloc_get_rec(other_cur, &fbno, &flen, &has_otherrec);
+       if (!err2) {
+               XFS_BTREC_SCRUB_CHECK(bs, has_otherrec);
+               XFS_BTREC_SCRUB_CHECK(bs, fbno == bno);
+               XFS_BTREC_SCRUB_CHECK(bs, flen == len);
+       }
+skip_freesp_xref:
+
        return error;
 }
 

<Prev in Thread] Current Thread [Next in Thread>