xfs
[Top] [All Lists]

[PATCH 24/25] xfs: scrub should cross-reference the realtime bitmap

To: david@xxxxxxxxxxxxx, darrick.wong@xxxxxxxxxx
Subject: [PATCH 24/25] xfs: scrub should cross-reference the realtime bitmap
From: "Darrick J. Wong" <darrick.wong@xxxxxxxxxx>
Date: Thu, 25 Aug 2016 16:42:52 -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
While we're scrubbing various btrees, cross-reference the records
with the other metadata.

Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
---
 fs/xfs/libxfs/xfs_rtbitmap.c |   29 +++++++++++++++++++++++++++++
 fs/xfs/xfs_rtalloc.h         |    3 +++
 fs/xfs/xfs_scrub.c           |    9 +++++++++
 3 files changed, 41 insertions(+)


diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c
index f4b68c0..0f95c19 100644
--- a/fs/xfs/libxfs/xfs_rtbitmap.c
+++ b/fs/xfs/libxfs/xfs_rtbitmap.c
@@ -1016,3 +1016,32 @@ xfs_rtfree_extent(
        }
        return 0;
 }
+
+/* Is the given extent all free? */
+int
+xfs_rtbitmap_extent_is_free(
+       struct xfs_mount                *mp,
+       xfs_rtblock_t                   start,
+       xfs_rtblock_t                   len,
+       bool                            *is_free)
+{
+       xfs_rtblock_t                   end;
+       xfs_extlen_t                    clen;
+       int                             matches;
+       int                             error;
+
+       *is_free = false;
+       while (len) {
+               clen = len > ~0U ? ~0U : len;
+               error = xfs_rtcheck_range(mp, NULL, start, clen, 1, &end,
+                               &matches);
+               if (error || !matches || end < start + clen)
+                       return error;
+
+               len -= end - start;
+               start = end + 1;
+       }
+
+       *is_free = true;
+       return error;
+}
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h
index 91e48f9..14fd2c3 100644
--- a/fs/xfs/xfs_rtalloc.h
+++ b/fs/xfs/xfs_rtalloc.h
@@ -121,6 +121,8 @@ int xfs_rtmodify_summary(struct xfs_mount *mp, struct 
xfs_trans *tp, int log,
 int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp,
                     xfs_rtblock_t start, xfs_extlen_t len,
                     struct xfs_buf **rbpp, xfs_fsblock_t *rsb);
+int xfs_rtbitmap_extent_is_free(struct xfs_mount *mp,
+               xfs_rtblock_t start, xfs_rtblock_t len, bool *is_free);
 
 
 #else
@@ -129,6 +131,7 @@ int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans 
*tp,
 # define xfs_rtpick_extent(m,t,l,rb)                    (ENOSYS)
 # define xfs_growfs_rt(mp,in)                           (ENOSYS)
 # define xfs_rtbuf_get(m,t,b,i,p)                       (ENOSYS)
+# define xfs_rtbitmap_extent_is_free(m,s,l,i)           (ENOSYS)
 static inline int              /* error */
 xfs_rtmount_init(
        xfs_mount_t     *mp)    /* file system mount structure */
diff --git a/fs/xfs/xfs_scrub.c b/fs/xfs/xfs_scrub.c
index ff55d8c..e4e3210 100644
--- a/fs/xfs/xfs_scrub.c
+++ b/fs/xfs/xfs_scrub.c
@@ -2304,6 +2304,7 @@ xfs_scrub_bmap_extent(
        xfs_extlen_t                    flen;
        bool                            is_freesp;
        bool                            has_inodes;
+       bool                            is_free;
        unsigned int                    rflags;
        int                             has_rmap;
        int                             has_refcount;
@@ -2390,6 +2391,14 @@ xfs_scrub_bmap_extent(
                        xfs_btree_del_cursor(xcur, err2 ? XFS_BTREE_ERROR :
                                                          XFS_BTREE_NOERROR);
                }
+       } else {
+               /* Cross-reference with rtbitmap. */
+               xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
+               err2 = xfs_rtbitmap_extent_is_free(mp, irec->br_startblock,
+                               irec->br_blockcount, &is_free);
+               if (!err2)
+                       XFS_BTREC_SCRUB_CHECK(&info->bs, !is_free);
+               xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
        }
 
        /* Cross-reference with rmapbt. */

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