changeset 10859:ea699e57196e

6761101 zdb/mdb crashes when printing bp with bad checksum, compress or type
author Victor Latushkin <Victor.Latushkin@Sun.COM>
date Sun, 25 Oct 2009 05:02:46 +0300
parents 9efff268b959
children f850bd358163
files usr/src/cmd/mdb/common/modules/zfs/zfs.c usr/src/cmd/zdb/zdb.c usr/src/uts/common/fs/zfs/spa_misc.c
diffstat 3 files changed, 42 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/mdb/common/modules/zfs/zfs.c	Sun Oct 25 05:02:46 2009 +0300
+++ b/usr/src/cmd/mdb/common/modules/zfs/zfs.c	Sun Oct 25 05:02:46 2009 +0300
@@ -463,12 +463,15 @@
 	    BP_GET_LSIZE(&bp), BP_GET_PSIZE(&bp));
 	mdb_printf("ENDIAN: %6s\t\t\t\t\tTYPE:  %s\n",
 	    BP_GET_BYTEORDER(&bp) ? "LITTLE" : "BIG",
-	    doti[BP_GET_TYPE(&bp)].ot_name);
+	    BP_GET_TYPE(&bp) < DMU_OT_NUMTYPES ?
+	    doti[BP_GET_TYPE(&bp)].ot_name : "UNKNOWN");
 	mdb_printf("BIRTH:  %-16llx   LEVEL: %-2d\tFILL:  %llx\n",
 	    bp.blk_birth, (int)BP_GET_LEVEL(&bp), bp.blk_fill);
 	mdb_printf("CKFUNC: %-16s\t\tCOMP:  %s\n",
-	    zci[BP_GET_CHECKSUM(&bp)].ci_name,
-	    zct[BP_GET_COMPRESS(&bp)].ci_name);
+	    BP_GET_CHECKSUM(&bp) < ZIO_CHECKSUM_FUNCTIONS ?
+	    zci[BP_GET_CHECKSUM(&bp)].ci_name : "UNKNOWN",
+	    BP_GET_COMPRESS(&bp) < ZIO_COMPRESS_FUNCTIONS ?
+	    zct[BP_GET_COMPRESS(&bp)].ci_name : "UNKNOWN");
 	mdb_printf("CKSUM:  %llx:%llx:%llx:%llx\n",
 	    bp.blk_cksum.zc_word[0],
 	    bp.blk_cksum.zc_word[1],
--- a/usr/src/cmd/zdb/zdb.c	Sun Oct 25 05:02:46 2009 +0300
+++ b/usr/src/cmd/zdb/zdb.c	Sun Oct 25 05:02:46 2009 +0300
@@ -55,6 +55,14 @@
 #undef verify
 #include <libzfs.h>
 
+#define	ZDB_COMPRESS_NAME(idx) ((idx) < ZIO_COMPRESS_FUNCTIONS ? \
+    zio_compress_table[(idx)].ci_name : "UNKNOWN")
+#define	ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ? \
+    zio_checksum_table[(idx)].ci_name : "UNKNOWN")
+#define	ZDB_OT_NAME(idx) ((idx) < DMU_OT_NUMTYPES ? \
+    dmu_ot[(idx)].ot_name : "UNKNOWN")
+#define	ZDB_OT_TYPE(idx) ((idx) < DMU_OT_NUMTYPES ? (idx) : DMU_OT_NUMTYPES)
+
 const char cmdname[] = "zdb";
 uint8_t dump_opt[256];
 
@@ -272,6 +280,13 @@
 }
 
 /*ARGSUSED*/
+static void
+dump_unknown(objset_t *os, uint64_t object, void *data, size_t size)
+{
+	(void) printf("\tUNKNOWN OBJECT TYPE\n");
+}
+
+/*ARGSUSED*/
 void
 dump_uint8(objset_t *os, uint64_t object, void *data, size_t size)
 {
@@ -1018,7 +1033,7 @@
 {
 }
 
-static object_viewer_t *object_viewer[DMU_OT_NUMTYPES] = {
+static object_viewer_t *object_viewer[DMU_OT_NUMTYPES + 1] = {
 	dump_none,		/* unallocated			*/
 	dump_zap,		/* object directory		*/
 	dump_uint64,		/* object array			*/
@@ -1061,6 +1076,7 @@
 	dump_zap,		/* ZFS user/group used		*/
 	dump_zap,		/* ZFS user/group quota		*/
 	dump_zap,		/* snapshot refcount tags	*/
+	dump_unknown		/* Unknown type, must be last	*/
 };
 
 static void
@@ -1105,22 +1121,22 @@
 
 	if (doi.doi_checksum != ZIO_CHECKSUM_INHERIT || verbosity >= 6) {
 		(void) snprintf(aux + strlen(aux), sizeof (aux), " (K=%s)",
-		    zio_checksum_table[doi.doi_checksum].ci_name);
+		    ZDB_CHECKSUM_NAME(doi.doi_checksum));
 	}
 
 	if (doi.doi_compress != ZIO_COMPRESS_INHERIT || verbosity >= 6) {
 		(void) snprintf(aux + strlen(aux), sizeof (aux), " (Z=%s)",
-		    zio_compress_table[doi.doi_compress].ci_name);
+		    ZDB_COMPRESS_NAME(doi.doi_compress));
 	}
 
 	(void) printf("%10lld  %3u  %5s  %5s  %5s  %5s  %s%s\n",
 	    (u_longlong_t)object, doi.doi_indirection, iblk, dblk, lsize,
-	    asize, dmu_ot[doi.doi_type].ot_name, aux);
+	    asize, ZDB_OT_NAME(doi.doi_type), aux);
 
 	if (doi.doi_bonus_type != DMU_OT_NONE && verbosity > 3) {
 		(void) printf("%10s  %3s  %5s  %5s  %5s  %5s  %s\n",
 		    "", "", "", "", bonus_size, "bonus",
-		    dmu_ot[doi.doi_bonus_type].ot_name);
+		    ZDB_OT_NAME(doi.doi_bonus_type));
 	}
 
 	if (verbosity >= 4) {
@@ -1132,8 +1148,9 @@
 		(void) printf("\tdnode maxblkid: %llu\n",
 		    (longlong_t)dn->dn_phys->dn_maxblkid);
 
-		object_viewer[doi.doi_bonus_type](os, object, bonus, bsize);
-		object_viewer[doi.doi_type](os, object, NULL, 0);
+		object_viewer[ZDB_OT_TYPE(doi.doi_bonus_type)](os, object,
+		    bonus, bsize);
+		object_viewer[ZDB_OT_TYPE(doi.doi_type)](os, object, NULL, 0);
 		*print_header = 1;
 	}
 
@@ -1540,9 +1557,9 @@
 			    (u_longlong_t)BP_GET_LEVEL(bp),
 			    (longlong_t)BP_GET_PSIZE(bp),
 			    (longlong_t)BP_GET_NDVAS(bp),
-			    dmu_ot[BP_GET_TYPE(bp)].ot_name,
-			    zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name,
-			    zio_compress_table[BP_GET_COMPRESS(bp)].ci_name,
+			    ZDB_OT_NAME(BP_GET_TYPE(bp)),
+			    ZDB_CHECKSUM_NAME(BP_GET_CHECKSUM(bp)),
+			    ZDB_COMPRESS_NAME(BP_GET_COMPRESS(bp)),
 			    (u_longlong_t)bp->blk_cksum.zc_word[0],
 			    (u_longlong_t)bp->blk_cksum.zc_word[1],
 			    (u_longlong_t)bp->blk_cksum.zc_word[2],
@@ -1916,13 +1933,13 @@
 	    (longlong_t)BP_GET_LSIZE(bp), (longlong_t)BP_GET_PSIZE(bp));
 	(void) printf("\tENDIAN: %6s\t\t\t\t\tTYPE:  %s\n",
 	    BP_GET_BYTEORDER(bp) ? "LITTLE" : "BIG",
-	    dmu_ot[BP_GET_TYPE(bp)].ot_name);
+	    ZDB_OT_NAME(BP_GET_TYPE(bp)));
 	(void) printf("\tBIRTH:  %-16llx   LEVEL: %-2llu\tFILL:  %llx\n",
 	    (u_longlong_t)bp->blk_birth, (u_longlong_t)BP_GET_LEVEL(bp),
 	    (u_longlong_t)bp->blk_fill);
 	(void) printf("\tCKFUNC: %-16s\t\tCOMP:  %s\n",
-	    zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name,
-	    zio_compress_table[BP_GET_COMPRESS(bp)].ci_name);
+	    ZDB_CHECKSUM_NAME(BP_GET_CHECKSUM(bp)),
+	    ZDB_COMPRESS_NAME(BP_GET_COMPRESS(bp)));
 	(void) printf("\tCKSUM:  %llx:%llx:%llx:%llx\n",
 	    (u_longlong_t)bp->blk_cksum.zc_word[0],
 	    (u_longlong_t)bp->blk_cksum.zc_word[1],
--- a/usr/src/uts/common/fs/zfs/spa_misc.c	Sun Oct 25 05:02:46 2009 +0300
+++ b/usr/src/uts/common/fs/zfs/spa_misc.c	Sun Oct 25 05:02:46 2009 +0300
@@ -1117,7 +1117,8 @@
 
 	(void) snprintf(buf, len, "[L%llu %s] %llxL/%llxP ",
 	    (u_longlong_t)BP_GET_LEVEL(bp),
-	    dmu_ot[BP_GET_TYPE(bp)].ot_name,
+	    BP_GET_TYPE(bp) < DMU_OT_NUMTYPES ?
+	    dmu_ot[BP_GET_TYPE(bp)].ot_name : "UNKNOWN",
 	    (u_longlong_t)BP_GET_LSIZE(bp),
 	    (u_longlong_t)BP_GET_PSIZE(bp));
 
@@ -1132,8 +1133,10 @@
 
 	(void) snprintf(buf + strlen(buf), len - strlen(buf),
 	    "%s %s %s %s birth=%llu fill=%llu cksum=%llx:%llx:%llx:%llx",
-	    zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name,
-	    zio_compress_table[BP_GET_COMPRESS(bp)].ci_name,
+	    BP_GET_CHECKSUM(bp) < ZIO_CHECKSUM_FUNCTIONS ?
+	    zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name : "UNKNOWN",
+	    BP_GET_COMPRESS(bp) < ZIO_COMPRESS_FUNCTIONS ?
+	    zio_compress_table[BP_GET_COMPRESS(bp)].ci_name : "UNKNOWN",
 	    BP_GET_BYTEORDER(bp) == 0 ? "BE" : "LE",
 	    BP_IS_GANG(bp) ? "gang" : "contiguous",
 	    (u_longlong_t)bp->blk_birth,