@@ -445,6 +445,7 @@ xfs_scrub_agf_xref(
struct xfs_btree_cur **pcur;
xfs_agblock_t bno;
xfs_extlen_t blocks;
+ int have;
int error;
bno = XFS_AGF_BLOCK(mp);
@@ -466,6 +467,31 @@ xfs_scrub_agf_xref(
xfs_scrub_block_xref_set_corrupt(sc, sc->sa.agf_bp);
}
+ /* Cross-reference with the cntbt. */
+ pcur = &sc->sa.cnt_cur;
+ while (*pcur) {
+ xfs_agblock_t agbno;
+
+ /* Any freespace at all? */
+ error = xfs_alloc_lookup_le(*pcur, 0, -1U, &have);
+ if (!xfs_scrub_should_xref(sc, &error, pcur))
+ break;
+ if (!have) {
+ if (agf->agf_freeblks != be32_to_cpu(0))
+ xfs_scrub_block_xref_set_corrupt(sc,
+ sc->sa.agf_bp);
+ break;
+ }
+
+ /* Check agf_longest */
+ error = xfs_alloc_get_rec(*pcur, &agbno, &blocks, &have);
+ if (!xfs_scrub_should_xref(sc, &error, pcur))
+ break;
+ if (!have || blocks != be32_to_cpu(agf->agf_longest))
+ xfs_scrub_block_xref_set_corrupt(sc, sc->sa.agf_bp);
+ break;
+ }
+
/* scrub teardown will take care of sc->sa for us */
}
@@ -31,6 +31,7 @@
#include "xfs_sb.h"
#include "xfs_alloc.h"
#include "xfs_rmap.h"
+#include "xfs_alloc.h"
#include "scrub/xfs_scrub.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
@@ -57,6 +58,42 @@ xfs_scrub_allocbt_xref(
xfs_agblock_t bno,
xfs_extlen_t len)
{
+ struct xfs_btree_cur **pcur;
+ struct xfs_scrub_ag *psa = &sc->sa;
+ xfs_agblock_t fbno;
+ xfs_extlen_t flen;
+ int has_otherrec;
+ int error;
+
+ /*
+ * Ensure there's a corresponding cntbt/bnobt record matching
+ * this bnobt/cntbt record, respectively.
+ */
+ if (sc->sm->sm_type == XFS_SCRUB_TYPE_BNOBT)
+ pcur = &psa->cnt_cur;
+ else
+ pcur = &psa->bno_cur;
+ while (*pcur) {
+ error = xfs_alloc_lookup_le(*pcur, bno, len, &has_otherrec);
+ if (!xfs_scrub_should_xref(sc, &error, pcur))
+ break;
+ if (!has_otherrec) {
+ xfs_scrub_btree_xref_set_corrupt(sc, *pcur, 0);
+ break;
+ }
+
+ error = xfs_alloc_get_rec(*pcur, &fbno, &flen, &has_otherrec);
+ if (!xfs_scrub_should_xref(sc, &error, pcur))
+ break;
+ if (!has_otherrec) {
+ xfs_scrub_btree_xref_set_corrupt(sc, *pcur, 0);
+ break;
+ }
+
+ if (fbno != bno || flen != len)
+ xfs_scrub_btree_xref_set_corrupt(sc, *pcur, 0);
+ break;
+ }
}
/* Scrub a bnobt/cntbt record. */