]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
xfs: skip scrub xref if corruption already noted
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 14 May 2018 13:34:31 +0000 (06:34 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 16 May 2018 00:57:05 +0000 (17:57 -0700)
Don't bother looking for cross-referencing problems if the metadata is
already corrupt or we've already found a cross-referencing problem.
Since we added a helper function for flags testing, convert existing
users to use it.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
fs/xfs/scrub/alloc.c
fs/xfs/scrub/bmap.c
fs/xfs/scrub/common.c
fs/xfs/scrub/common.h
fs/xfs/scrub/ialloc.c
fs/xfs/scrub/inode.c
fs/xfs/scrub/refcount.c
fs/xfs/scrub/rmap.c
fs/xfs/scrub/rtbitmap.c
fs/xfs/scrub/scrub.c

index 517c079d3f68db704a803469bbcdc742c2a42851..941a0a55224e84bedd893e5e67f1d89b0cf6236d 100644 (file)
@@ -70,7 +70,7 @@ xfs_scrub_allocbt_xref_other(
                pcur = &sc->sa.cnt_cur;
        else
                pcur = &sc->sa.bno_cur;
-       if (!*pcur)
+       if (!*pcur || xfs_scrub_skip_xref(sc->sm))
                return;
 
        error = xfs_alloc_lookup_le(*pcur, agbno, len, &has_otherrec);
@@ -172,7 +172,7 @@ xfs_scrub_xref_is_used_space(
        bool                            is_freesp;
        int                             error;
 
-       if (!sc->sa.bno_cur)
+       if (!sc->sa.bno_cur || xfs_scrub_skip_xref(sc->sm))
                return;
 
        error = xfs_alloc_has_record(sc->sa.bno_cur, agbno, len, &is_freesp);
index 3f8fd10160f0661752a6b974a983a65ce0eaa8d5..e5a4611abf86ce8f7b4dd9a3332670c22e7a5249 100644 (file)
@@ -174,7 +174,7 @@ xfs_scrub_bmap_xref_rmap(
        unsigned long long              rmap_end;
        uint64_t                        owner;
 
-       if (!info->sc->sa.rmap_cur)
+       if (!info->sc->sa.rmap_cur || xfs_scrub_skip_xref(info->sc->sm))
                return;
 
        if (info->whichfork == XFS_COW_FORK)
index 95625aa90c240d7c29cb92e713b01deea26a5621..2ac8576c4670bb0ba989a8f4dedcd23cff0dc9fd 100644 (file)
@@ -737,6 +737,10 @@ xfs_scrub_should_check_xref(
        int                             *error,
        struct xfs_btree_cur            **curpp)
 {
+       /* No point in xref if we already know we're corrupt. */
+       if (xfs_scrub_skip_xref(sc->sm))
+               return false;
+
        if (*error == 0)
                return true;
 
index c95c30c986b76c7440b040b05b934712857adc4e..a23ad7fa2b6cc51ed6fa5932b2e8b5017d1ee5ab 100644 (file)
@@ -145,4 +145,14 @@ int xfs_scrub_setup_inode_contents(struct xfs_scrub_context *sc,
                                   struct xfs_inode *ip, unsigned int resblks);
 void xfs_scrub_buffer_recheck(struct xfs_scrub_context *sc, struct xfs_buf *bp);
 
+/*
+ * Don't bother cross-referencing if we already found corruption or cross
+ * referencing discrepancies.
+ */
+static inline bool xfs_scrub_skip_xref(struct xfs_scrub_metadata *sm)
+{
+       return sm->sm_flags & (XFS_SCRUB_OFLAG_CORRUPT |
+                              XFS_SCRUB_OFLAG_XCORRUPT);
+}
+
 #endif /* __XFS_SCRUB_COMMON_H__ */
index 106ca4bd753f1536ac7bb96c3fb76fcd969a7999..00a834d3b56d60da02f219e61838230e652127cc 100644 (file)
@@ -387,7 +387,8 @@ xfs_scrub_iallocbt_xref_rmap_btreeblks(
        int                             error;
 
        if (!sc->sa.ino_cur || !sc->sa.rmap_cur ||
-           (xfs_sb_version_hasfinobt(&sc->mp->m_sb) && !sc->sa.fino_cur))
+           (xfs_sb_version_hasfinobt(&sc->mp->m_sb) && !sc->sa.fino_cur) ||
+           xfs_scrub_skip_xref(sc->sm))
                return;
 
        /* Check that we saw as many inobt blocks as the rmap says. */
@@ -424,7 +425,7 @@ xfs_scrub_iallocbt_xref_rmap_inodes(
        xfs_filblks_t                   blocks;
        int                             error;
 
-       if (!sc->sa.rmap_cur)
+       if (!sc->sa.rmap_cur || xfs_scrub_skip_xref(sc->sm))
                return;
 
        /* Check that we saw as many inode blocks as the rmap knows about. */
@@ -496,7 +497,7 @@ xfs_scrub_xref_inode_check(
        bool                            has_inodes;
        int                             error;
 
-       if (!(*icur))
+       if (!(*icur) || xfs_scrub_skip_xref(sc->sm))
                return;
 
        error = xfs_ialloc_has_inodes_at_extent(*icur, agbno, len, &has_inodes);
index e15b1bc5053f7cec3953aa3cc161b6e3a247208d..550c0cf70a921df72160dfdc6bf67db5c148b946 100644 (file)
@@ -448,7 +448,7 @@ xfs_scrub_inode_xref_finobt(
        int                             has_record;
        int                             error;
 
-       if (!sc->sa.fino_cur)
+       if (!sc->sa.fino_cur || xfs_scrub_skip_xref(sc->sm))
                return;
 
        agino = XFS_INO_TO_AGINO(sc->mp, ino);
@@ -491,6 +491,9 @@ xfs_scrub_inode_xref_bmap(
        xfs_filblks_t                   acount;
        int                             error;
 
+       if (xfs_scrub_skip_xref(sc->sm))
+               return;
+
        /* Walk all the extents to check nextents/naextents/nblocks. */
        error = xfs_bmap_count_blocks(sc->tp, sc->ip, XFS_DATA_FORK,
                        &nextents, &count);
index d86526d2932c1a237ca3a6304e8d91d7a598865f..324a5f159145ce4c8c3e659bac1076125f0af21a 100644 (file)
@@ -310,7 +310,7 @@ xfs_scrub_refcountbt_xref_rmap(
        struct xfs_scrub_refcnt_frag    *n;
        int                             error;
 
-       if (!sc->sa.rmap_cur)
+       if (!sc->sa.rmap_cur || xfs_scrub_skip_xref(sc->sm))
                return;
 
        /* Cross-reference with the rmapbt to confirm the refcount. */
@@ -404,7 +404,7 @@ xfs_scrub_refcount_xref_rmap(
        xfs_filblks_t                   blocks;
        int                             error;
 
-       if (!sc->sa.rmap_cur)
+       if (!sc->sa.rmap_cur || xfs_scrub_skip_xref(sc->sm))
                return;
 
        /* Check that we saw as many refcbt blocks as the rmap knows about. */
@@ -460,7 +460,7 @@ xfs_scrub_xref_is_cow_staging(
        int                             has_refcount;
        int                             error;
 
-       if (!sc->sa.refc_cur)
+       if (!sc->sa.refc_cur || xfs_scrub_skip_xref(sc->sm))
                return;
 
        /* Find the CoW staging extent. */
@@ -504,7 +504,7 @@ xfs_scrub_xref_is_not_shared(
        bool                            shared;
        int                             error;
 
-       if (!sc->sa.refc_cur)
+       if (!sc->sa.refc_cur || xfs_scrub_skip_xref(sc->sm))
                return;
 
        error = xfs_refcount_has_record(sc->sa.refc_cur, agbno, len, &shared);
index 8f2a7c3ff455181b01aac1d6620b623af3c6e865..b376a9a77c0471a0d06eeda872e1ea1d3d06f8c6 100644 (file)
@@ -66,7 +66,7 @@ xfs_scrub_rmapbt_xref_refc(
        bool                            is_unwritten;
        int                             error;
 
-       if (!sc->sa.refc_cur)
+       if (!sc->sa.refc_cur || xfs_scrub_skip_xref(sc->sm))
                return;
 
        non_inode = XFS_RMAP_NON_INODE_OWNER(irec->rm_owner);
@@ -207,7 +207,7 @@ xfs_scrub_xref_check_owner(
        bool                            has_rmap;
        int                             error;
 
-       if (!sc->sa.rmap_cur)
+       if (!sc->sa.rmap_cur || xfs_scrub_skip_xref(sc->sm))
                return;
 
        error = xfs_rmap_record_exists(sc->sa.rmap_cur, bno, len, oinfo,
@@ -250,7 +250,7 @@ xfs_scrub_xref_has_no_owner(
        bool                            has_rmap;
        int                             error;
 
-       if (!sc->sa.rmap_cur)
+       if (!sc->sa.rmap_cur || xfs_scrub_skip_xref(sc->sm))
                return;
 
        error = xfs_rmap_has_record(sc->sa.rmap_cur, bno, len, &has_rmap);
index 39c41dfe08ee538e16d0143be75ce26a76ec4d9a..8b048f107af2e4f6b9200e08b3d10c1b2512a2be 100644 (file)
@@ -110,6 +110,9 @@ xfs_scrub_xref_is_used_rt_space(
        bool                            is_free;
        int                             error;
 
+       if (xfs_scrub_skip_xref(sc->sm))
+               return;
+
        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);
index 67509d8b8b8e4c77e9bda3692dcf2c1cb456f1ae..ad6eda4fa12321a6f41b6d8ebfb133a29688c92f 100644 (file)
@@ -450,8 +450,8 @@ xfs_scrub_metadata(
        } else if (error)
                goto out_teardown;
 
-       if (sc.sm->sm_flags & (XFS_SCRUB_OFLAG_CORRUPT |
-                              XFS_SCRUB_OFLAG_XCORRUPT))
+       if (sm->sm_flags & (XFS_SCRUB_OFLAG_CORRUPT |
+                           XFS_SCRUB_OFLAG_XCORRUPT))
                xfs_alert_ratelimited(mp, "Corruption detected during scrub.");
 
 out_teardown: