From owner-svn-src-all@FreeBSD.ORG Mon Dec 15 05:10:57 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 7AF63CE0; Mon, 15 Dec 2014 05:10:57 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 65D4F1DF; Mon, 15 Dec 2014 05:10:57 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sBF5AvYi038548; Mon, 15 Dec 2014 05:10:57 GMT (envelope-from delphij@FreeBSD.org) Received: (from delphij@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sBF5AuNu038541; Mon, 15 Dec 2014 05:10:56 GMT (envelope-from delphij@FreeBSD.org) Message-Id: <201412150510.sBF5AuNu038541@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: delphij set sender to delphij@FreeBSD.org using -f From: Xin LI Date: Mon, 15 Dec 2014 05:10:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r275781 - in head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Dec 2014 05:10:57 -0000 Author: delphij Date: Mon Dec 15 05:10:55 2014 New Revision: 275781 URL: https://svnweb.freebsd.org/changeset/base/275781 Log: MFV r275550: In addition to r273158, make the code in spa_sync() that checks if the current TXG is a no-op TXG less fragile. Illumos issue: 5347 idle pool may run itself out of space MFC after: 2 weeks Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/uberblock.h head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/uberblock.c Directory Properties: head/sys/cddl/contrib/opensolaris/ (props changed) Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c Mon Dec 15 04:51:36 2014 (r275780) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c Mon Dec 15 05:10:55 2014 (r275781) @@ -1486,11 +1486,15 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t * dp->dp_bptree_obj, tx)); dp->dp_bptree_obj = 0; scn->scn_async_destroying = B_FALSE; + scn->scn_async_stalled = B_FALSE; } else { /* - * If we didn't make progress, mark the async destroy as - * stalled, so that we will not initiate a spa_sync() on - * its behalf. + * If we didn't make progress, mark the async + * destroy as stalled, so that we will not initiate + * a spa_sync() on its behalf. Note that we only + * check this if we are not finished, because if the + * bptree had no blocks for us to visit, we can + * finish without "making progress". */ scn->scn_async_stalled = (scn->scn_visited_this_txg == 0); Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c Mon Dec 15 04:51:36 2014 (r275780) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c Mon Dec 15 05:10:55 2014 (r275781) @@ -6605,21 +6605,6 @@ spa_sync(spa_t *spa, uint64_t txg) } /* - * If anything has changed in this txg, or if someone is waiting - * for this txg to sync (eg, spa_vdev_remove()), push the - * deferred frees from the previous txg. If not, leave them - * alone so that we don't generate work on an otherwise idle - * system. - */ - if (!txg_list_empty(&dp->dp_dirty_datasets, txg) || - !txg_list_empty(&dp->dp_dirty_dirs, txg) || - !txg_list_empty(&dp->dp_sync_tasks, txg) || - ((dsl_scan_active(dp->dp_scan) || - txg_sync_waiting(dp)) && !spa_shutting_down(spa))) { - spa_sync_deferred_frees(spa, tx); - } - - /* * Iterate to convergence. */ do { @@ -6636,6 +6621,11 @@ spa_sync(spa_t *spa, uint64_t txg) if (pass < zfs_sync_pass_deferred_free) { spa_sync_frees(spa, free_bpl, tx); } else { + /* + * We can not defer frees in pass 1, because + * we sync the deferred frees later in pass 1. + */ + ASSERT3U(pass, >, 1); bplist_iterate(free_bpl, bpobj_enqueue_cb, &spa->spa_deferred_bpobj, tx); } @@ -6646,8 +6636,37 @@ spa_sync(spa_t *spa, uint64_t txg) while (vd = txg_list_remove(&spa->spa_vdev_txg_list, txg)) vdev_sync(vd, txg); - if (pass == 1) + if (pass == 1) { spa_sync_upgrades(spa, tx); + ASSERT3U(txg, >=, + spa->spa_uberblock.ub_rootbp.blk_birth); + /* + * Note: We need to check if the MOS is dirty + * because we could have marked the MOS dirty + * without updating the uberblock (e.g. if we + * have sync tasks but no dirty user data). We + * need to check the uberblock's rootbp because + * it is updated if we have synced out dirty + * data (though in this case the MOS will most + * likely also be dirty due to second order + * effects, we don't want to rely on that here). + */ + if (spa->spa_uberblock.ub_rootbp.blk_birth < txg && + !dmu_objset_is_dirty(mos, txg)) { + /* + * Nothing changed on the first pass, + * therefore this TXG is a no-op. Avoid + * syncing deferred frees, so that we + * can keep this TXG as a no-op. + */ + ASSERT(txg_list_empty(&dp->dp_dirty_datasets, + txg)); + ASSERT(txg_list_empty(&dp->dp_dirty_dirs, txg)); + ASSERT(txg_list_empty(&dp->dp_sync_tasks, txg)); + break; + } + spa_sync_deferred_frees(spa, tx); + } } while (dmu_objset_is_dirty(mos, txg)); Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/uberblock.h ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/uberblock.h Mon Dec 15 04:51:36 2014 (r275780) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/uberblock.h Mon Dec 15 05:10:55 2014 (r275781) @@ -22,6 +22,9 @@ * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2014 by Delphix. All rights reserved. + */ #ifndef _SYS_UBERBLOCK_H #define _SYS_UBERBLOCK_H @@ -36,8 +39,8 @@ extern "C" { typedef struct uberblock uberblock_t; -extern int uberblock_verify(uberblock_t *ub); -extern int uberblock_update(uberblock_t *ub, vdev_t *rvd, uint64_t txg); +extern int uberblock_verify(uberblock_t *); +extern boolean_t uberblock_update(uberblock_t *, vdev_t *, uint64_t); #ifdef __cplusplus } Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/uberblock.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/uberblock.c Mon Dec 15 04:51:36 2014 (r275780) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/uberblock.c Mon Dec 15 05:10:55 2014 (r275781) @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013, 2014 by Delphix. All rights reserved. */ #include @@ -40,10 +40,10 @@ uberblock_verify(uberblock_t *ub) } /* - * Update the uberblock and return a boolean value indicating whether - * anything changed in this transaction group. + * Update the uberblock and return TRUE if anything changed in this + * transaction group. */ -int +boolean_t uberblock_update(uberblock_t *ub, vdev_t *rvd, uint64_t txg) { ASSERT(ub->ub_txg < txg);