From 320cc3b263542e692c4978fb327efa591892ab37 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 10 Jul 2020 15:35:45 -0400 Subject: [PATCH] xfs_repair: complain about bad interior btree pointers Actually complain about garbage btree node pointers, don't just silently ignore them. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Eric Sandeen --- libxfs/libxfs_api_defs.h | 1 + repair/scan.c | 55 +++++++++++++++++++++++++++++----------- 2 files changed, 41 insertions(+), 15 deletions(-) Index: xfsprogs-5.0.0/libxfs/libxfs_api_defs.h =================================================================== --- xfsprogs-5.0.0.orig/libxfs/libxfs_api_defs.h +++ xfsprogs-5.0.0/libxfs/libxfs_api_defs.h @@ -118,6 +118,7 @@ #define xfs_symlink_blocks libxfs_symlink_blocks #define xfs_symlink_hdr_ok libxfs_symlink_hdr_ok +#define xfs_verify_agbno libxfs_verify_agbno #define xfs_verify_cksum libxfs_verify_cksum #define xfs_dinode_verify libxfs_dinode_verify Index: xfsprogs-5.0.0/repair/scan.c =================================================================== --- xfsprogs-5.0.0.orig/repair/scan.c +++ xfsprogs-5.0.0/repair/scan.c @@ -743,6 +743,14 @@ _("%s freespace btree block claimed (sta for (i = 0; i < numrecs; i++) { xfs_agblock_t agbno = be32_to_cpu(pp[i]); + if (!libxfs_verify_agbno(mp, agno, agbno)) { + do_warn( + _("bad btree pointer (%u) in %sbt block %u/%u\n"), + agbno, name, agno, bno); + suspect++; + return; + } + /* * XXX - put sibling detection right here. * we know our sibling chain is good. So as we go, @@ -752,10 +760,8 @@ _("%s freespace btree block claimed (sta * pointer mismatch, try and extract as much data * as possible. */ - if (agbno != 0 && verify_agbno(mp, agno, agbno)) { - scan_sbtree(agbno, level, agno, suspect, scan_allocbt, - 0, magic, priv, ops); - } + scan_sbtree(agbno, level, agno, suspect, scan_allocbt, 0, + magic, priv, ops); } } @@ -1196,10 +1202,16 @@ advance: continue; } - if (agbno != 0 && verify_agbno(mp, agno, agbno)) { - scan_sbtree(agbno, level, agno, suspect, scan_rmapbt, 0, - magic, priv, ops); + if (!libxfs_verify_agbno(mp, agno, agbno)) { + do_warn( + _("bad btree pointer (%u) in %sbt block %u/%u\n"), + agbno, name, agno, bno); + suspect++; + return; } + + scan_sbtree(agbno, level, agno, suspect, scan_rmapbt, 0, magic, + priv, ops); } out: @@ -1416,10 +1428,16 @@ _("extent (%u/%u) len %u claimed, state for (i = 0; i < numrecs; i++) { xfs_agblock_t agbno = be32_to_cpu(pp[i]); - if (agbno != 0 && verify_agbno(mp, agno, agbno)) { - scan_sbtree(agbno, level, agno, suspect, scan_refcbt, 0, - magic, priv, ops); + if (!libxfs_verify_agbno(mp, agno, agbno)) { + do_warn( + _("bad btree pointer (%u) in %sbt block %u/%u\n"), + agbno, name, agno, bno); + suspect++; + return; } + + scan_sbtree(agbno, level, agno, suspect, scan_refcbt, 0, magic, + priv, ops); } out: if (suspect) @@ -2083,11 +2101,18 @@ _("inode btree block claimed (state %d), } for (i = 0; i < numrecs; i++) { - if (be32_to_cpu(pp[i]) != 0 && verify_agbno(mp, agno, - be32_to_cpu(pp[i]))) - scan_sbtree(be32_to_cpu(pp[i]), level, agno, - suspect, scan_inobt, 0, magic, priv, - ops); + xfs_agblock_t agbno = be32_to_cpu(pp[i]); + + if (!libxfs_verify_agbno(mp, agno, agbno)) { + do_warn( + _("bad btree pointer (%u) in %sbt block %u/%u\n"), + agbno, name, agno, bno); + suspect++; + return; + } + + scan_sbtree(be32_to_cpu(pp[i]), level, agno, suspect, + scan_inobt, 0, magic, priv, ops); } }