Skip to content

Commit 89b1cd6

Browse files
smhbehlendorf
authored andcommitted
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. References: freebsd/freebsd-src@48431b7 http://svnweb.freebsd.org/base?view=revision&revision=273158 https://reviews.csiden.org/r/132/ Porting notes: This issue was filed as illumos 5347 and a more comprehensive fix is under review. Once that change is finalized it will be integrated, in the meanwhile the FreeBSD fix has been merged to prevent the issue. Ported by: Tim Chase <tim@chase2k.com> Signed-off-by: Matthew Ahrens mahrens@delphix.com Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #2896
1 parent 4254acb commit 89b1cd6

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

module/zfs/dsl_scan.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,13 +1493,6 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx)
14931493
"traverse_dataset_destroyed()", err);
14941494
}
14951495

1496-
/*
1497-
* If we didn't make progress, mark the async destroy as
1498-
* stalled, so that we will not initiate a spa_sync() on
1499-
* its behalf.
1500-
*/
1501-
scn->scn_async_stalled = (scn->scn_visited_this_txg == 0);
1502-
15031496
if (bptree_is_empty(dp->dp_meta_objset, dp->dp_bptree_obj)) {
15041497
/* finished; deactivate async destroy feature */
15051498
spa_feature_decr(spa, SPA_FEATURE_ASYNC_DESTROY, tx);
@@ -1512,6 +1505,14 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx)
15121505
dp->dp_bptree_obj, tx));
15131506
dp->dp_bptree_obj = 0;
15141507
scn->scn_async_destroying = B_FALSE;
1508+
} else {
1509+
/*
1510+
* If we didn't make progress, mark the async destroy as
1511+
* stalled, so that we will not initiate a spa_sync() on
1512+
* its behalf.
1513+
*/
1514+
scn->scn_async_stalled =
1515+
(scn->scn_visited_this_txg == 0);
15151516
}
15161517
}
15171518
if (scn->scn_visited_this_txg) {

0 commit comments

Comments
 (0)