diff options
author | Darrick J. Wong <djwong@kernel.org> | 2021-09-01 10:40:09 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2021-12-15 17:28:46 -0800 |
commit | 185222c1786b60d88a17f13ab114b751b53cbc60 (patch) | |
tree | 831687f64ce48dd1a310ea3627ce7a1e0cb81380 /fs/xfs/libxfs/xfs_refcount.c | |
parent | e2d561ad05eefeb77a1d42966392980ff17fa12b (diff) |
xfs: teach xfs_btree_has_record to return false if there are gaps
The current implementation of xfs_btree_has_record returns true if it
finds /any/ record within the given range. Unfortunately, that's not
what the predicate is supposed to do -- it's supposed to test if the
/entire/ range is covered by records.
Therefore, enhance the routine to check that the first record it
encounters starts earlier or at the same point as the low key, the last
record ends at or after the same point as the high key, and that there
aren't any gaps in the records.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/libxfs/xfs_refcount.c')
-rw-r--r-- | fs/xfs/libxfs/xfs_refcount.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 327ba25e9e17..7466e51f6e5d 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1763,6 +1763,18 @@ out_free: return error; } +static bool +xfs_refcount_has_key_gap( + struct xfs_btree_cur *cur, + const union xfs_btree_key *key1, + const union xfs_btree_key *key2) +{ + xfs_agblock_t next; + + next = be32_to_cpu(key1->refc.rc_startblock) + 1; + return next != be32_to_cpu(key2->refc.rc_startblock); +} + /* Is there a record covering a given extent? */ int xfs_refcount_has_record( @@ -1779,7 +1791,8 @@ xfs_refcount_has_record( memset(&high, 0xFF, sizeof(high)); high.rc.rc_startblock = bno + len - 1; - return xfs_btree_has_record(cur, &low, &high, exists); + return xfs_btree_has_record(cur, &low, &high, xfs_refcount_has_key_gap, + exists); } int __init |