summaryrefslogtreecommitdiff
path: root/fs/xfs/libxfs/xfs_alloc.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-09-01 10:40:09 -0700
committerDarrick J. Wong <djwong@kernel.org>2021-10-22 16:40:31 -0700
commit404154ba3319fcf41dea7804092518067fa07f4c (patch)
treef33541b6d0b3c59ce5ddc3b69f6e2918a5ec86d8 /fs/xfs/libxfs/xfs_alloc.c
parent006f04ec02fec3a700454bee52de064ffba93d12 (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_alloc.c')
-rw-r--r--fs/xfs/libxfs/xfs_alloc.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index 95157f5a5a6c..4a17a5a167eb 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -3440,6 +3440,18 @@ xfs_alloc_query_all(
return xfs_btree_query_all(cur, xfs_alloc_query_range_helper, &query);
}
+static bool
+xfs_alloc_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->alloc.ar_startblock) + 1;
+ return next != be32_to_cpu(key2->alloc.ar_startblock);
+}
+
/* Is there a record covering a given extent? */
int
xfs_alloc_has_record(
@@ -3456,7 +3468,8 @@ xfs_alloc_has_record(
memset(&high, 0xFF, sizeof(high));
high.a.ar_startblock = bno + len - 1;
- return xfs_btree_has_record(cur, &low, &high, exists);
+ return xfs_btree_has_record(cur, &low, &high, xfs_alloc_has_key_gap,
+ exists);
}
/*