@@ -170,7 +170,7 @@ xfs_alloc_lookup_ge(
* Lookup the first record less than or equal to [bno, len]
* in the btree given by cur.
*/
-static int /* error */
+int /* error */
xfs_alloc_lookup_le(
struct xfs_btree_cur *cur, /* btree cursor */
xfs_agblock_t bno, /* starting block of extent */
@@ -189,6 +189,13 @@ xfs_free_extent(
enum xfs_ag_resv_type type); /* block reservation type */
int /* error */
+xfs_alloc_lookup_le(
+ struct xfs_btree_cur *cur, /* btree cursor */
+ xfs_agblock_t bno, /* starting block of extent */
+ xfs_extlen_t len, /* length of extent */
+ int *stat); /* success/failure */
+
+int /* error */
xfs_alloc_lookup_ge(
struct xfs_btree_cur *cur, /* btree cursor */
xfs_agblock_t bno, /* starting block of extent */
@@ -1096,9 +1096,14 @@ xfs_scrub_allocbt_helper(
{
struct xfs_mount *mp = bs->cur->bc_mp;
struct xfs_agf *agf;
+ struct xfs_btree_cur *other_cur;
+ xfs_agblock_t fbno;
xfs_agblock_t bno;
+ xfs_extlen_t flen;
xfs_extlen_t len;
+ int has_otherrec;
int error = 0;
+ int err2;
bno = be32_to_cpu(rec->alloc.ar_startblock);
len = be32_to_cpu(rec->alloc.ar_blockcount);
@@ -1112,6 +1117,25 @@ xfs_scrub_allocbt_helper(
XFS_BTREC_SCRUB_CHECK(bs, (unsigned long long)bno + len <=
be32_to_cpu(agf->agf_length));
+ /*
+ * Ensure there's a corresponding cntbt/bnobt record matching
+ * this bnobt/cntbt record, respectively.
+ */
+ other_cur = (bs->cnt_cur ? bs->cnt_cur : bs->bno_cur);
+ err2 = xfs_alloc_lookup_le(other_cur, bno, len, &has_otherrec);
+ if (err2)
+ goto skip_freesp_xref;
+ XFS_BTREC_SCRUB_CHECK(bs, has_otherrec);
+ if (!has_otherrec)
+ goto skip_freesp_xref;
+ err2 = xfs_alloc_get_rec(other_cur, &fbno, &flen, &has_otherrec);
+ if (!err2) {
+ XFS_BTREC_SCRUB_CHECK(bs, has_otherrec);
+ XFS_BTREC_SCRUB_CHECK(bs, fbno == bno);
+ XFS_BTREC_SCRUB_CHECK(bs, flen == len);
+ }
+skip_freesp_xref:
+
return error;
}
Scrub should make sure that each bnobt record has a corresponding cntbt record. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/libxfs/xfs_alloc.c | 2 +- fs/xfs/libxfs/xfs_alloc.h | 7 +++++++ fs/xfs/xfs_scrub.c | 24 ++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-)