From owner-svn-src-stable@FreeBSD.ORG Sat Feb 9 00:29:38 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 4F762BA2; Sat, 9 Feb 2013 00:29:38 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 23811C11; Sat, 9 Feb 2013 00:29:38 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r190Tc3x002550; Sat, 9 Feb 2013 00:29:38 GMT (envelope-from delphij@svn.freebsd.org) Received: (from delphij@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r190TbeQ002546; Sat, 9 Feb 2013 00:29:37 GMT (envelope-from delphij@svn.freebsd.org) Message-Id: <201302090029.r190TbeQ002546@svn.freebsd.org> From: Xin LI Date: Sat, 9 Feb 2013 00:29:37 +0000 (UTC) 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 X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 09 Feb 2013 00:29:38 -0000 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,