xfs: cross-reference the realtime bitmap
authorDarrick J. Wong <darrick.wong@oracle.com>
Wed, 17 Jan 2018 02:53:10 +0000 (18:53 -0800)
committerDarrick J. Wong <darrick.wong@oracle.com>
Thu, 18 Jan 2018 05:00:46 +0000 (21:00 -0800)
While we're scrubbing various btrees, cross-reference the records
with the other metadata.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
fs/xfs/libxfs/xfs_rtbitmap.c
fs/xfs/scrub/bmap.c
fs/xfs/scrub/rtbitmap.c
fs/xfs/scrub/scrub.h
fs/xfs/xfs_rtalloc.h

index 3fb29a5ea915001276abc6938925175d76c44a2b..106be2d0bb88cb44fda2ab4979b15c39c2fd64c7 100644 (file)
@@ -1097,3 +1097,24 @@ xfs_verify_rtbno(
 {
        return rtbno < mp->m_sb.sb_rblocks;
 }
+
+/* Is the given extent all free? */
+int
+xfs_rtalloc_extent_is_free(
+       struct xfs_mount                *mp,
+       struct xfs_trans                *tp,
+       xfs_rtblock_t                   start,
+       xfs_extlen_t                    len,
+       bool                            *is_free)
+{
+       xfs_rtblock_t                   end;
+       int                             matches;
+       int                             error;
+
+       error = xfs_rtcheck_range(mp, tp, start, len, 1, &end, &matches);
+       if (error)
+               return error;
+
+       *is_free = matches;
+       return 0;
+}
index 7b2cf8fd1ce0fd5f04098eca4c423269ef0512b4..2bb3e0c4b4efc675266ccd6830b6fb94278c2451 100644 (file)
@@ -243,6 +243,9 @@ xfs_scrub_bmap_rt_extent_xref(
 {
        if (info->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
                return;
+
+       xfs_scrub_xref_is_used_rt_space(info->sc, irec->br_startblock,
+                       irec->br_blockcount);
 }
 
 /* Cross-reference a single datadev extent record. */
index 6860d5d925157077ba3a223374a9642f721cacda..26390991369ad7427aa33466c28614aa1dc1b7c5 100644 (file)
@@ -98,3 +98,26 @@ xfs_scrub_rtsummary(
        /* XXX: implement this some day */
        return -ENOENT;
 }
+
+
+/* xref check that the extent is not free in the rtbitmap */
+void
+xfs_scrub_xref_is_used_rt_space(
+       struct xfs_scrub_context        *sc,
+       xfs_rtblock_t                   fsbno,
+       xfs_extlen_t                    len)
+{
+       bool                            is_free;
+       int                             error;
+
+       xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
+       error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, fsbno, len,
+                       &is_free);
+       if (!xfs_scrub_should_check_xref(sc, &error, NULL))
+               goto out_unlock;
+       if (is_free)
+               xfs_scrub_ino_xref_set_corrupt(sc, sc->mp->m_rbmip->i_ino,
+                               NULL);
+out_unlock:
+       xfs_iunlock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
+}
index c8f8b42cbdb3164a2b078a508808d7a3e3fbe5cb..0d92af86f67ae6a0343ac001f5ed160dcf6f24f2 100644 (file)
@@ -142,5 +142,11 @@ void xfs_scrub_xref_is_cow_staging(struct xfs_scrub_context *sc,
                xfs_agblock_t bno, xfs_extlen_t len);
 void xfs_scrub_xref_is_not_shared(struct xfs_scrub_context *sc,
                xfs_agblock_t bno, xfs_extlen_t len);
+#ifdef CONFIG_XFS_RT
+void xfs_scrub_xref_is_used_rt_space(struct xfs_scrub_context *sc,
+               xfs_rtblock_t rtbno, xfs_extlen_t len);
+#else
+# define xfs_scrub_xref_is_used_rt_space(sc, rtbno, len) do { } while (0)
+#endif
 
 #endif /* __XFS_SCRUB_SCRUB_H__ */
index 3f30f846d7f29fee442c02738d124159249d1959..dfee3c9911552547adb6d981e36a57b5d06a847b 100644 (file)
@@ -139,6 +139,9 @@ int xfs_rtalloc_query_all(struct xfs_trans *tp,
                          xfs_rtalloc_query_range_fn fn,
                          void *priv);
 bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno);
+int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp,
+                              xfs_rtblock_t start, xfs_extlen_t len,
+                              bool *is_free);
 #else
 # define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb)    (ENOSYS)
 # define xfs_rtfree_extent(t,b,l)                       (ENOSYS)
@@ -148,6 +151,7 @@ bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno);
 # define xfs_rtalloc_query_all(t,f,p)                   (ENOSYS)
 # define xfs_rtbuf_get(m,t,b,i,p)                       (ENOSYS)
 # define xfs_verify_rtbno(m, r)                        (false)
+# define xfs_rtalloc_extent_is_free(m,t,s,l,i)          (ENOSYS)
 static inline int              /* error */
 xfs_rtmount_init(
        xfs_mount_t     *mp)    /* file system mount structure */