xfs: cross-reference refcount btree during scrub

During metadata btree scrub, we should cross-reference with the
reference counts.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
Darrick J. Wong
2018-01-16 18:53:09 -08:00
parent dbde19da96
commit f6d5fc21fd
8 changed files with 186 additions and 14 deletions

View File

@@ -32,6 +32,7 @@
#include "xfs_alloc.h"
#include "xfs_ialloc.h"
#include "xfs_rmap.h"
#include "xfs_refcount.h"
#include "scrub/xfs_scrub.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
@@ -51,6 +52,37 @@ xfs_scrub_setup_ag_rmapbt(
/* Reverse-mapping scrubber. */
/* Cross-reference a rmap against the refcount btree. */
STATIC void
xfs_scrub_rmapbt_xref_refc(
struct xfs_scrub_context *sc,
struct xfs_rmap_irec *irec)
{
xfs_agblock_t fbno;
xfs_extlen_t flen;
bool non_inode;
bool is_bmbt;
bool is_attr;
bool is_unwritten;
int error;
if (!sc->sa.refc_cur)
return;
non_inode = XFS_RMAP_NON_INODE_OWNER(irec->rm_owner);
is_bmbt = irec->rm_flags & XFS_RMAP_BMBT_BLOCK;
is_attr = irec->rm_flags & XFS_RMAP_ATTR_FORK;
is_unwritten = irec->rm_flags & XFS_RMAP_UNWRITTEN;
/* If this is shared, must be a data fork extent. */
error = xfs_refcount_find_shared(sc->sa.refc_cur, irec->rm_startblock,
irec->rm_blockcount, &fbno, &flen, false);
if (!xfs_scrub_should_check_xref(sc, &error, &sc->sa.refc_cur))
return;
if (flen != 0 && (non_inode || is_attr || is_bmbt || is_unwritten))
xfs_scrub_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0);
}
/* Cross-reference with the other btrees. */
STATIC void
xfs_scrub_rmapbt_xref(
@@ -68,6 +100,11 @@ xfs_scrub_rmapbt_xref(
xfs_scrub_xref_is_inode_chunk(sc, agbno, len);
else
xfs_scrub_xref_is_not_inode_chunk(sc, agbno, len);
if (irec->rm_owner == XFS_RMAP_OWN_COW)
xfs_scrub_xref_is_cow_staging(sc, irec->rm_startblock,
irec->rm_blockcount);
else
xfs_scrub_rmapbt_xref_refc(sc, irec);
}
/* Scrub an rmapbt record. */