xfs: add repair helpers for the reverse mapping btree
Add a couple of functions to the reverse mapping btree that will be used to repair 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
7f8f1313d9
commit
4d4f86b49f
2 changed files with 85 additions and 0 deletions
|
@ -2032,6 +2032,34 @@ xfs_rmap_map_shared(
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Insert a raw rmap into the rmapbt. */
|
||||||
|
int
|
||||||
|
xfs_rmap_map_raw(
|
||||||
|
struct xfs_btree_cur *cur,
|
||||||
|
struct xfs_rmap_irec *rmap)
|
||||||
|
{
|
||||||
|
struct xfs_owner_info oinfo;
|
||||||
|
|
||||||
|
oinfo.oi_owner = rmap->rm_owner;
|
||||||
|
oinfo.oi_offset = rmap->rm_offset;
|
||||||
|
oinfo.oi_flags = 0;
|
||||||
|
if (rmap->rm_flags & XFS_RMAP_ATTR_FORK)
|
||||||
|
oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
|
||||||
|
if (rmap->rm_flags & XFS_RMAP_BMBT_BLOCK)
|
||||||
|
oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
|
||||||
|
|
||||||
|
if (rmap->rm_flags || XFS_RMAP_NON_INODE_OWNER(rmap->rm_owner))
|
||||||
|
return xfs_rmap_map(cur, rmap->rm_startblock,
|
||||||
|
rmap->rm_blockcount,
|
||||||
|
rmap->rm_flags & XFS_RMAP_UNWRITTEN,
|
||||||
|
&oinfo);
|
||||||
|
|
||||||
|
return xfs_rmap_map_shared(cur, rmap->rm_startblock,
|
||||||
|
rmap->rm_blockcount,
|
||||||
|
rmap->rm_flags & XFS_RMAP_UNWRITTEN,
|
||||||
|
&oinfo);
|
||||||
|
}
|
||||||
|
|
||||||
struct xfs_rmap_query_range_info {
|
struct xfs_rmap_query_range_info {
|
||||||
xfs_rmap_query_range_fn fn;
|
xfs_rmap_query_range_fn fn;
|
||||||
void *priv;
|
void *priv;
|
||||||
|
@ -2455,3 +2483,56 @@ xfs_rmap_record_exists(
|
||||||
irec.rm_startblock + irec.rm_blockcount >= bno + len);
|
irec.rm_startblock + irec.rm_blockcount >= bno + len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct xfs_rmap_key_state {
|
||||||
|
uint64_t owner;
|
||||||
|
uint64_t offset;
|
||||||
|
unsigned int flags;
|
||||||
|
bool has_rmap;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* For each rmap given, figure out if it doesn't match the key we want. */
|
||||||
|
STATIC int
|
||||||
|
xfs_rmap_has_other_keys_helper(
|
||||||
|
struct xfs_btree_cur *cur,
|
||||||
|
struct xfs_rmap_irec *rec,
|
||||||
|
void *priv)
|
||||||
|
{
|
||||||
|
struct xfs_rmap_key_state *rks = priv;
|
||||||
|
|
||||||
|
if (rks->owner == rec->rm_owner && rks->offset == rec->rm_offset &&
|
||||||
|
((rks->flags & rec->rm_flags) & XFS_RMAP_KEY_FLAGS) == rks->flags)
|
||||||
|
return 0;
|
||||||
|
rks->has_rmap = true;
|
||||||
|
return XFS_BTREE_QUERY_RANGE_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given an extent and some owner info, can we find records overlapping
|
||||||
|
* the extent whose owner info does not match the given owner?
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xfs_rmap_has_other_keys(
|
||||||
|
struct xfs_btree_cur *cur,
|
||||||
|
xfs_agblock_t bno,
|
||||||
|
xfs_extlen_t len,
|
||||||
|
struct xfs_owner_info *oinfo,
|
||||||
|
bool *has_rmap)
|
||||||
|
{
|
||||||
|
struct xfs_rmap_irec low = {0};
|
||||||
|
struct xfs_rmap_irec high;
|
||||||
|
struct xfs_rmap_key_state rks;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
xfs_owner_info_unpack(oinfo, &rks.owner, &rks.offset, &rks.flags);
|
||||||
|
rks.has_rmap = false;
|
||||||
|
|
||||||
|
low.rm_startblock = bno;
|
||||||
|
memset(&high, 0xFF, sizeof(high));
|
||||||
|
high.rm_startblock = bno + len - 1;
|
||||||
|
|
||||||
|
error = xfs_rmap_query_range(cur, &low, &high,
|
||||||
|
xfs_rmap_has_other_keys_helper, &rks);
|
||||||
|
*has_rmap = rks.has_rmap;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
|
@ -238,5 +238,9 @@ int xfs_rmap_has_record(struct xfs_btree_cur *cur, xfs_agblock_t bno,
|
||||||
int xfs_rmap_record_exists(struct xfs_btree_cur *cur, xfs_agblock_t bno,
|
int xfs_rmap_record_exists(struct xfs_btree_cur *cur, xfs_agblock_t bno,
|
||||||
xfs_extlen_t len, struct xfs_owner_info *oinfo,
|
xfs_extlen_t len, struct xfs_owner_info *oinfo,
|
||||||
bool *has_rmap);
|
bool *has_rmap);
|
||||||
|
int xfs_rmap_has_other_keys(struct xfs_btree_cur *cur, xfs_agblock_t bno,
|
||||||
|
xfs_extlen_t len, struct xfs_owner_info *oinfo,
|
||||||
|
bool *has_rmap);
|
||||||
|
int xfs_rmap_map_raw(struct xfs_btree_cur *cur, struct xfs_rmap_irec *rmap);
|
||||||
|
|
||||||
#endif /* __XFS_RMAP_H__ */
|
#endif /* __XFS_RMAP_H__ */
|
||||||
|
|
Loading…
Add table
Reference in a new issue