Skip to content

Commit 4d4f86b

Browse files
committed
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 <[email protected]> Reviewed-by: Dave Chinner <[email protected]>
1 parent 7f8f131 commit 4d4f86b

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

fs/xfs/libxfs/xfs_rmap.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,6 +2032,34 @@ xfs_rmap_map_shared(
20322032
return error;
20332033
}
20342034

2035+
/* Insert a raw rmap into the rmapbt. */
2036+
int
2037+
xfs_rmap_map_raw(
2038+
struct xfs_btree_cur *cur,
2039+
struct xfs_rmap_irec *rmap)
2040+
{
2041+
struct xfs_owner_info oinfo;
2042+
2043+
oinfo.oi_owner = rmap->rm_owner;
2044+
oinfo.oi_offset = rmap->rm_offset;
2045+
oinfo.oi_flags = 0;
2046+
if (rmap->rm_flags & XFS_RMAP_ATTR_FORK)
2047+
oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
2048+
if (rmap->rm_flags & XFS_RMAP_BMBT_BLOCK)
2049+
oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
2050+
2051+
if (rmap->rm_flags || XFS_RMAP_NON_INODE_OWNER(rmap->rm_owner))
2052+
return xfs_rmap_map(cur, rmap->rm_startblock,
2053+
rmap->rm_blockcount,
2054+
rmap->rm_flags & XFS_RMAP_UNWRITTEN,
2055+
&oinfo);
2056+
2057+
return xfs_rmap_map_shared(cur, rmap->rm_startblock,
2058+
rmap->rm_blockcount,
2059+
rmap->rm_flags & XFS_RMAP_UNWRITTEN,
2060+
&oinfo);
2061+
}
2062+
20352063
struct xfs_rmap_query_range_info {
20362064
xfs_rmap_query_range_fn fn;
20372065
void *priv;
@@ -2455,3 +2483,56 @@ xfs_rmap_record_exists(
24552483
irec.rm_startblock + irec.rm_blockcount >= bno + len);
24562484
return 0;
24572485
}
2486+
2487+
struct xfs_rmap_key_state {
2488+
uint64_t owner;
2489+
uint64_t offset;
2490+
unsigned int flags;
2491+
bool has_rmap;
2492+
};
2493+
2494+
/* For each rmap given, figure out if it doesn't match the key we want. */
2495+
STATIC int
2496+
xfs_rmap_has_other_keys_helper(
2497+
struct xfs_btree_cur *cur,
2498+
struct xfs_rmap_irec *rec,
2499+
void *priv)
2500+
{
2501+
struct xfs_rmap_key_state *rks = priv;
2502+
2503+
if (rks->owner == rec->rm_owner && rks->offset == rec->rm_offset &&
2504+
((rks->flags & rec->rm_flags) & XFS_RMAP_KEY_FLAGS) == rks->flags)
2505+
return 0;
2506+
rks->has_rmap = true;
2507+
return XFS_BTREE_QUERY_RANGE_ABORT;
2508+
}
2509+
2510+
/*
2511+
* Given an extent and some owner info, can we find records overlapping
2512+
* the extent whose owner info does not match the given owner?
2513+
*/
2514+
int
2515+
xfs_rmap_has_other_keys(
2516+
struct xfs_btree_cur *cur,
2517+
xfs_agblock_t bno,
2518+
xfs_extlen_t len,
2519+
struct xfs_owner_info *oinfo,
2520+
bool *has_rmap)
2521+
{
2522+
struct xfs_rmap_irec low = {0};
2523+
struct xfs_rmap_irec high;
2524+
struct xfs_rmap_key_state rks;
2525+
int error;
2526+
2527+
xfs_owner_info_unpack(oinfo, &rks.owner, &rks.offset, &rks.flags);
2528+
rks.has_rmap = false;
2529+
2530+
low.rm_startblock = bno;
2531+
memset(&high, 0xFF, sizeof(high));
2532+
high.rm_startblock = bno + len - 1;
2533+
2534+
error = xfs_rmap_query_range(cur, &low, &high,
2535+
xfs_rmap_has_other_keys_helper, &rks);
2536+
*has_rmap = rks.has_rmap;
2537+
return error;
2538+
}

fs/xfs/libxfs/xfs_rmap.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,5 +238,9 @@ int xfs_rmap_has_record(struct xfs_btree_cur *cur, xfs_agblock_t bno,
238238
int xfs_rmap_record_exists(struct xfs_btree_cur *cur, xfs_agblock_t bno,
239239
xfs_extlen_t len, struct xfs_owner_info *oinfo,
240240
bool *has_rmap);
241+
int xfs_rmap_has_other_keys(struct xfs_btree_cur *cur, xfs_agblock_t bno,
242+
xfs_extlen_t len, struct xfs_owner_info *oinfo,
243+
bool *has_rmap);
244+
int xfs_rmap_map_raw(struct xfs_btree_cur *cur, struct xfs_rmap_irec *rmap);
241245

242246
#endif /* __XFS_RMAP_H__ */

0 commit comments

Comments
 (0)