Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Feb 2013 00:29:37 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r246574 - in stable/9: cddl/contrib/opensolaris/cmd/zdb sys/cddl/contrib/opensolaris/uts/common/fs/zfs sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys
Message-ID:  <201302090029.r190TbeQ002546@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Sat Feb  9 00:29:36 2013
New Revision: 246574
URL: http://svnweb.freebsd.org/changeset/base/246574

Log:
  MFC r245264:
  
  The current ZFS code expects ddt_zap_count to always succeed by asserting
  the underlying zap_count() to return no errors.  However, it is possible
  that the pool reaches to such a state where zap_count would return error,
  leading to panics when a pool is imported.
  
  This commit changes the ddt_zap_count to return error returned from
  zap_count and handle the error appropriately.  With this change, it's now
  possible to let zpool rollback damaged transaction groups and import the
  pool.
  
  Obtained from:	ZFS on Linux github (e8fd45a0f975c6b8ae8cd644714fc21f14fac2bf)

Modified:
  stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt_zap.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/ddt.h
Directory Properties:
  stable/9/cddl/   (props changed)
  stable/9/cddl/contrib/opensolaris/   (props changed)
  stable/9/sys/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)

Modified: stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb.c
==============================================================================
--- stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb.c	Fri Feb  8 23:59:21 2013	(r246573)
+++ stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb.c	Sat Feb  9 00:29:36 2013	(r246574)
@@ -704,7 +704,9 @@ dump_ddt(ddt_t *ddt, enum ddt_type type,
 		return;
 	ASSERT(error == 0);
 
-	if ((count = ddt_object_count(ddt, type, class)) == 0)
+	error = ddt_object_count(ddt, type, class, &count);
+	ASSERT(error == 0);
+	if (count == 0)
 		return;
 
 	dspace = doi.doi_physical_blocks_512 << 9;

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c	Fri Feb  8 23:59:21 2013	(r246573)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c	Sat Feb  9 00:29:36 2013	(r246574)
@@ -89,12 +89,13 @@ ddt_object_destroy(ddt_t *ddt, enum ddt_
 	spa_t *spa = ddt->ddt_spa;
 	objset_t *os = ddt->ddt_os;
 	uint64_t *objectp = &ddt->ddt_object[type][class];
+	uint64_t count;
 	char name[DDT_NAMELEN];
 
 	ddt_object_name(ddt, type, class, name);
 
 	ASSERT(*objectp != 0);
-	ASSERT(ddt_object_count(ddt, type, class) == 0);
+	VERIFY(ddt_object_count(ddt, type, class, &count) == 0 && count == 0);
 	ASSERT(ddt_histogram_empty(&ddt->ddt_histogram[type][class]));
 	VERIFY(zap_remove(os, DMU_POOL_DIRECTORY_OBJECT, name, tx) == 0);
 	VERIFY(zap_remove(os, spa->spa_ddt_stat_object, name, tx) == 0);
@@ -109,6 +110,7 @@ ddt_object_load(ddt_t *ddt, enum ddt_typ
 {
 	ddt_object_t *ddo = &ddt->ddt_object_stats[type][class];
 	dmu_object_info_t doi;
+	uint64_t count;
 	char name[DDT_NAMELEN];
 	int error;
 
@@ -129,7 +131,11 @@ ddt_object_load(ddt_t *ddt, enum ddt_typ
 	 */
 	VERIFY(ddt_object_info(ddt, type, class, &doi) == 0);
 
-	ddo->ddo_count = ddt_object_count(ddt, type, class);
+	error = ddt_object_count(ddt, type, class, &count);
+	if (error)
+		return error;
+
+	ddo->ddo_count = count;
 	ddo->ddo_dspace = doi.doi_physical_blocks_512 << 9;
 	ddo->ddo_mspace = doi.doi_fill_count * doi.doi_data_block_size;
 
@@ -143,6 +149,7 @@ ddt_object_sync(ddt_t *ddt, enum ddt_typ
 {
 	ddt_object_t *ddo = &ddt->ddt_object_stats[type][class];
 	dmu_object_info_t doi;
+	uint64_t count;
 	char name[DDT_NAMELEN];
 
 	ddt_object_name(ddt, type, class, name);
@@ -155,8 +162,9 @@ ddt_object_sync(ddt_t *ddt, enum ddt_typ
 	 * Cache DDT statistics; this is the only time they'll change.
 	 */
 	VERIFY(ddt_object_info(ddt, type, class, &doi) == 0);
+	VERIFY(ddt_object_count(ddt, type, class, &count) == 0);
 
-	ddo->ddo_count = ddt_object_count(ddt, type, class);
+	ddo->ddo_count = count;
 	ddo->ddo_dspace = doi.doi_physical_blocks_512 << 9;
 	ddo->ddo_mspace = doi.doi_fill_count * doi.doi_data_block_size;
 }
@@ -213,13 +221,13 @@ ddt_object_walk(ddt_t *ddt, enum ddt_typ
 	    ddt->ddt_object[type][class], dde, walk));
 }
 
-uint64_t
-ddt_object_count(ddt_t *ddt, enum ddt_type type, enum ddt_class class)
+int
+ddt_object_count(ddt_t *ddt, enum ddt_type type, enum ddt_class class, uint64_t *count)
 {
 	ASSERT(ddt_object_exists(ddt, type, class));
 
 	return (ddt_ops[type]->ddt_op_count(ddt->ddt_os,
-	    ddt->ddt_object[type][class]));
+	    ddt->ddt_object[type][class], count));
 }
 
 int
@@ -1079,11 +1087,13 @@ ddt_sync_table(ddt_t *ddt, dmu_tx_t *tx,
 	}
 
 	for (enum ddt_type type = 0; type < DDT_TYPES; type++) {
-		uint64_t count = 0;
+		uint64_t add, count = 0;
 		for (enum ddt_class class = 0; class < DDT_CLASSES; class++) {
 			if (ddt_object_exists(ddt, type, class)) {
 				ddt_object_sync(ddt, type, class, tx);
-				count += ddt_object_count(ddt, type, class);
+				VERIFY(ddt_object_count(ddt, type, class,
+				    &add) == 0);
+				count += add;
 			}
 		}
 		for (enum ddt_class class = 0; class < DDT_CLASSES; class++) {

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt_zap.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt_zap.c	Fri Feb  8 23:59:21 2013	(r246573)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt_zap.c	Sat Feb  9 00:29:36 2013	(r246574)
@@ -133,14 +133,11 @@ ddt_zap_walk(objset_t *os, uint64_t obje
 	return (error);
 }
 
-static uint64_t
-ddt_zap_count(objset_t *os, uint64_t object)
+static int
+ddt_zap_count(objset_t *os, uint64_t object, uint64_t *count)
 {
-	uint64_t count = 0;
 
-	VERIFY(zap_count(os, object, &count) == 0);
-
-	return (count);
+	return (zap_count(os, object, count));
 }
 
 const ddt_ops_t ddt_zap_ops = {

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/ddt.h
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/ddt.h	Fri Feb  8 23:59:21 2013	(r246573)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/ddt.h	Sat Feb  9 00:29:36 2013	(r246574)
@@ -163,7 +163,7 @@ typedef struct ddt_ops {
 	    dmu_tx_t *tx);
 	int (*ddt_op_walk)(objset_t *os, uint64_t object, ddt_entry_t *dde,
 	    uint64_t *walk);
-	uint64_t (*ddt_op_count)(objset_t *os, uint64_t object);
+	int (*ddt_op_count)(objset_t *os, uint64_t object, uint64_t *count);
 } ddt_ops_t;
 
 #define	DDT_NAMELEN	80
@@ -172,8 +172,8 @@ extern void ddt_object_name(ddt_t *ddt, 
     enum ddt_class cls, char *name);
 extern int ddt_object_walk(ddt_t *ddt, enum ddt_type type,
     enum ddt_class cls, uint64_t *walk, ddt_entry_t *dde);
-extern uint64_t ddt_object_count(ddt_t *ddt, enum ddt_type type,
-    enum ddt_class cls);
+extern int ddt_object_count(ddt_t *ddt, enum ddt_type type,
+    enum ddt_class class, uint64_t *count);
 extern int ddt_object_info(ddt_t *ddt, enum ddt_type type,
     enum ddt_class cls, dmu_object_info_t *);
 extern boolean_t ddt_object_exists(ddt_t *ddt, enum ddt_type type,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302090029.r190TbeQ002546>