xfs: add scrub cross-referencing helpers for the rmap btrees
Add a couple of functions to the rmap btrees that will be used to cross-reference metadata against the rmapbt. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
parent
2e001266b6
commit
ed7c52d4bf
@ -2387,3 +2387,70 @@ xfs_rmap_compare(
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Is there a record covering a given extent? */
|
||||
int
|
||||
xfs_rmap_has_record(
|
||||
struct xfs_btree_cur *cur,
|
||||
xfs_agblock_t bno,
|
||||
xfs_extlen_t len,
|
||||
bool *exists)
|
||||
{
|
||||
union xfs_btree_irec low;
|
||||
union xfs_btree_irec high;
|
||||
|
||||
memset(&low, 0, sizeof(low));
|
||||
low.r.rm_startblock = bno;
|
||||
memset(&high, 0xFF, sizeof(high));
|
||||
high.r.rm_startblock = bno + len - 1;
|
||||
|
||||
return xfs_btree_has_record(cur, &low, &high, exists);
|
||||
}
|
||||
|
||||
/*
|
||||
* Is there a record for this owner completely covering a given physical
|
||||
* extent? If so, *has_rmap will be set to true. If there is no record
|
||||
* or the record only covers part of the range, we set *has_rmap to false.
|
||||
* This function doesn't perform range lookups or offset checks, so it is
|
||||
* not suitable for checking data fork blocks.
|
||||
*/
|
||||
int
|
||||
xfs_rmap_record_exists(
|
||||
struct xfs_btree_cur *cur,
|
||||
xfs_agblock_t bno,
|
||||
xfs_extlen_t len,
|
||||
struct xfs_owner_info *oinfo,
|
||||
bool *has_rmap)
|
||||
{
|
||||
uint64_t owner;
|
||||
uint64_t offset;
|
||||
unsigned int flags;
|
||||
int has_record;
|
||||
struct xfs_rmap_irec irec;
|
||||
int error;
|
||||
|
||||
xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
|
||||
ASSERT(XFS_RMAP_NON_INODE_OWNER(owner) ||
|
||||
(flags & XFS_RMAP_BMBT_BLOCK));
|
||||
|
||||
error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags,
|
||||
&has_record);
|
||||
if (error)
|
||||
return error;
|
||||
if (!has_record) {
|
||||
*has_rmap = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
error = xfs_rmap_get_rec(cur, &irec, &has_record);
|
||||
if (error)
|
||||
return error;
|
||||
if (!has_record) {
|
||||
*has_rmap = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*has_rmap = (irec.rm_owner == owner && irec.rm_startblock <= bno &&
|
||||
irec.rm_startblock + irec.rm_blockcount >= bno + len);
|
||||
return 0;
|
||||
}
|
||||
|
@ -233,5 +233,10 @@ int xfs_rmap_compare(const struct xfs_rmap_irec *a,
|
||||
union xfs_btree_rec;
|
||||
int xfs_rmap_btrec_to_irec(union xfs_btree_rec *rec,
|
||||
struct xfs_rmap_irec *irec);
|
||||
int xfs_rmap_has_record(struct xfs_btree_cur *cur, xfs_agblock_t bno,
|
||||
xfs_extlen_t len, bool *exists);
|
||||
int xfs_rmap_record_exists(struct xfs_btree_cur *cur, xfs_agblock_t bno,
|
||||
xfs_extlen_t len, struct xfs_owner_info *oinfo,
|
||||
bool *has_rmap);
|
||||
|
||||
#endif /* __XFS_RMAP_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user