Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Oct 2014 02:23:28 +0000 (UTC)
From:      Steven Hartland <smh@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r273158 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201410160223.s9G2NSDu015140@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: smh
Date: Thu Oct 16 02:23:27 2014
New Revision: 273158
URL: https://svnweb.freebsd.org/changeset/base/273158

Log:
  Prevent ZFS leaking pool free space
  
  When processing async destroys ZFS would leak space every txg timeout
  (5 seconds by default), if no writes occurred, until the pool is totally
  full. At this point it would be unfixable without a pool recreation.
  
  In addition if the machine was rebooted with the pool in this situation
  would fail to import on boot, hanging indefinitely, as the import process
  requires the ability to write data to the pool. Any attempts to query the
  pool status during the hung import would not return as the import holds
  the pool lock.
  
  The only way to import such a pool would be to specify -o readonly=on
  to the zpool import.
  
  zdb -bb <pool> can be used to check for "deferred free" size which is where
  this lost space will be counted.
  
  MFC after:	3 days
  Sponsored by:	Multiplay

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c

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	Thu Oct 16 01:48:39 2014	(r273157)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c	Thu Oct 16 02:23:27 2014	(r273158)
@@ -1459,13 +1459,6 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *
 			    "traverse_dataset_destroyed()", err);
 		}
 
-		/*
-		 * If we didn't make progress, mark the async destroy as
-		 * stalled, so that we will not initiate a spa_sync() on
-		 * its behalf.
-		 */
-		scn->scn_async_stalled = (scn->scn_visited_this_txg == 0);
-
 		if (bptree_is_empty(dp->dp_meta_objset, dp->dp_bptree_obj)) {
 			/* finished; deactivate async destroy feature */
 			spa_feature_decr(spa, SPA_FEATURE_ASYNC_DESTROY, tx);
@@ -1478,6 +1471,14 @@ 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;
+		} 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.
+			 */
+			scn->scn_async_stalled =
+			    (scn->scn_visited_this_txg == 0);
 		}
 	}
 	if (scn->scn_visited_this_txg) {



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