]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_db: use iocursor type to guess btree geometry if bad magic
authorDarrick J. Wong <darrick.wong@oracle.com>
Tue, 2 May 2017 16:12:55 +0000 (11:12 -0500)
committerEric Sandeen <sandeen@redhat.com>
Tue, 2 May 2017 16:12:55 +0000 (11:12 -0500)
The function block_to_bt plays an integral role in determining the btree
geometry of a block that we want to manipulate with the debugger.
Normally we use the block magic to find the geometry profile, but if the
magic is bad we'll never find it and return NULL.  The callers of this
function do not check for NULL and crash.

Therefore, if we can't find a geometry profile matching the magic
number, use the iocursor type to guess the profile and scowl about that
to stdout.  This makes it so that even with a corrupt magic we can try
to print the fields instead of crashing the debugger.

[sandeen: comment changes, add magic ASSERT, keep other ASSERTs]

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
db/btblock.c

index 835a5f080d53480d099b7711b2730937082a7f82..9f506df4d9d1a78c2b8756045b331d2e084641bf 100644 (file)
@@ -25,6 +25,8 @@
 #include "print.h"
 #include "bit.h"
 #include "init.h"
+#include "io.h"
+#include "output.h"
 
 /*
  * Definition of the possible btree block layouts.
@@ -113,22 +115,60 @@ struct xfs_db_btree {
 };
 
 /*
- * Find the right block defintion for a given ondisk block.
- *
- * We use the least significant bit of the magic number as index into
- * the array of block defintions.
+ * Find the right block definition for a given ondisk block.
  */
 static struct xfs_db_btree *
 block_to_bt(
        struct xfs_btree_block  *bb)
 {
-       struct xfs_db_btree *btp = &btrees[0];
+       struct xfs_db_btree     *btp;
+       uint32_t                magic;
+       bool                    crc;
 
-       do {
-               if (be32_to_cpu((bb)->bb_magic) == btp->magic)
+       magic = be32_to_cpu((bb)->bb_magic);
+       for (btp = &btrees[0]; btp->magic != 0; btp++) {
+               if (magic == btp->magic)
+                       return btp;
+       }
+
+       /* Magic is invalid/unknown.  Guess based on iocur type */
+       crc = xfs_sb_version_hascrc(&mp->m_sb);
+       switch (iocur_top->typ->typnm) {
+       case TYP_BMAPBTA:
+       case TYP_BMAPBTD:
+               magic = crc ? XFS_BMAP_CRC_MAGIC : XFS_BMAP_MAGIC;
+               break;
+       case TYP_BNOBT:
+               magic = crc ? XFS_ABTB_CRC_MAGIC : XFS_ABTB_MAGIC;
+               break;
+       case TYP_CNTBT:
+               magic = crc ? XFS_ABTC_CRC_MAGIC : XFS_ABTC_MAGIC;
+               break;
+       case TYP_INOBT:
+               magic = crc ? XFS_IBT_CRC_MAGIC : XFS_IBT_MAGIC;
+               break;
+       case TYP_FINOBT:
+               magic = crc ? XFS_FIBT_CRC_MAGIC : XFS_FIBT_MAGIC;
+               break;
+       case TYP_RMAPBT:
+               magic = crc ? XFS_RMAP_CRC_MAGIC : 0;
+               break;
+       case TYP_REFCBT:
+               magic = crc ? XFS_REFC_CRC_MAGIC : 0;
+               break;
+       default:
+               ASSERT(0);
+       }
+
+       ASSERT(magic);
+       dbprintf(_("Bad btree magic 0x%x; coercing to %s.\n"),
+               be32_to_cpu((bb)->bb_magic),
+               iocur_top->typ->name);
+
+       for (btp = &btrees[0]; btp->magic != 0; btp++) {
+               if (magic == btp->magic)
                        return btp;
-               btp++;
-       } while (btp->magic != 0);
+       }
 
        return NULL;
 }