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:
@@ -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. */
|
||||
|
Reference in New Issue
Block a user