[PATCH 26/51] xfs_repair: mask off length appropriately

Darrick J. Wong
2015-10-07T05:08:06Z

Ensure that we remove the flag bits from blockcount before using the
length field.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
repair/scan.c | 32 ++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/repair/scan.c b/repair/scan.c
index c1ab6df..1ade344 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -792,6 +792,8 @@ scan_rmapbt(
int numrecs;
int state;
xfs_agblock_t lastblock = 0;
+ int64_t lastowner = 0;
+ int64_t lastoffset = 0;

if (magic != XFS_RMAP_CRC_MAGIC) {
name = "(unknown)";
@@ -859,11 +861,12 @@ _("%s rmap btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
for (i = 0; i < numrecs; i++) {
xfs_agblock_t b, end;
xfs_extlen_t len, blen;
- int64_t owner;
+ int64_t owner, offset;

b = be32_to_cpu(rp[i].rm_startblock);
- len = be32_to_cpu(rp[i].rm_blockcount);
+ len = XFS_RMAP_LEN(be32_to_cpu(rp[i].rm_blockcount));
owner = be64_to_cpu(rp[i].rm_owner);
+ offset = be64_to_cpu(rp[i].rm_offset);
end = b + len;

if (!verify_agbno(mp, agno, b)) {
@@ -879,14 +882,27 @@ _("%s rmap btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
continue;
}

- /* XXX: range check owner */
+ if (!(owner > 0 || (owner > XFS_RMAP_OWN_MIN &&
+ owner <= XFS_RMAP_OWN_FS)))
+ do_warn(
+ _("invalid owner in rmap btree record %d (%"PRId64" %u) block %u/%u\n"),
+ i, owner, len, agno, bno);

- if (b && b <= lastblock) {
- do_warn(_(
- "out-of-order rmap btree record %d (%u %u) block %u/%u\n"),
- i, b, len, agno, bno);
- } else {
+ if (i == 0) {
+advance:
lastblock = b;
+ lastowner = owner;
+ lastoffset = offset;
+ } else {
+ bool bad;
+
+ bad = b <= lastblock;
+ if (bad)
+ do_warn(
+ _("out-of-order rmap btree record %d (%u %"PRId64" %"PRIx64" %u) block %u/%u\n"),
+ i, b, owner, offset, len, agno, bno);
+ else
+ goto advance;
}

for ( ; b < end; b += blen) {