Skip to content

Commit 905edb4

Browse files
ahrensbehlendorf
authored andcommitted
Illumos 5347 - idle pool may run itself out of space
5347 idle pool may run itself out of space Reviewed by: Alex Reece <alex.reece@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Steven Hartland <killing@multiplay.co.uk> Reviewed by: Richard Elling <richard.elling@richardelling.com> Approved by: Dan McDonald <danmcd@omniti.com> References: illumos/illumos-gate@231aab8 illumos/illumos-gate@4a92375 3642 https://www.illumos.org/issues/5347 89b1cd6 (partial commit & fix) fbeddd6 Illumos 4390 2696dfa Illumos 3642, 3643 Porting notes: This is completing the partial fix from FreeBSD Ported-by: kernelOfTruth kerneloftruth@gmail.com Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #3586
1 parent 93f6d7e commit 905edb4

File tree

4 files changed

+51
-25
lines changed

4 files changed

+51
-25
lines changed

include/sys/uberblock.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2323
* Use is subject to license terms.
2424
*/
25+
/*
26+
* Copyright (c) 2014 by Delphix. All rights reserved.
27+
*/
2528

2629
#ifndef _SYS_UBERBLOCK_H
2730
#define _SYS_UBERBLOCK_H
@@ -36,8 +39,8 @@ extern "C" {
3639

3740
typedef struct uberblock uberblock_t;
3841

39-
extern int uberblock_verify(uberblock_t *ub);
40-
extern int uberblock_update(uberblock_t *ub, vdev_t *rvd, uint64_t txg);
42+
extern int uberblock_verify(uberblock_t *);
43+
extern boolean_t uberblock_update(uberblock_t *, vdev_t *, uint64_t);
4144

4245
#ifdef __cplusplus
4346
}

module/zfs/dsl_scan.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,11 +1528,15 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx)
15281528
dp->dp_bptree_obj, tx));
15291529
dp->dp_bptree_obj = 0;
15301530
scn->scn_async_destroying = B_FALSE;
1531+
scn->scn_async_stalled = B_FALSE;
15311532
} else {
15321533
/*
1533-
* If we didn't make progress, mark the async destroy as
1534-
* stalled, so that we will not initiate a spa_sync() on
1535-
* its behalf.
1534+
* If we didn't make progress, mark the async
1535+
* destroy as stalled, so that we will not initiate
1536+
* a spa_sync() on its behalf. Note that we only
1537+
* check this if we are not finished, because if the
1538+
* bptree had no blocks for us to visit, we can
1539+
* finish without "making progress".
15361540
*/
15371541
scn->scn_async_stalled =
15381542
(scn->scn_visited_this_txg == 0);

module/zfs/spa.c

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6393,21 +6393,6 @@ spa_sync(spa_t *spa, uint64_t txg)
63936393
}
63946394
}
63956395

6396-
/*
6397-
* If anything has changed in this txg, or if someone is waiting
6398-
* for this txg to sync (eg, spa_vdev_remove()), push the
6399-
* deferred frees from the previous txg. If not, leave them
6400-
* alone so that we don't generate work on an otherwise idle
6401-
* system.
6402-
*/
6403-
if (!txg_list_empty(&dp->dp_dirty_datasets, txg) ||
6404-
!txg_list_empty(&dp->dp_dirty_dirs, txg) ||
6405-
!txg_list_empty(&dp->dp_sync_tasks, txg) ||
6406-
((dsl_scan_active(dp->dp_scan) ||
6407-
txg_sync_waiting(dp)) && !spa_shutting_down(spa))) {
6408-
spa_sync_deferred_frees(spa, tx);
6409-
}
6410-
64116396
/*
64126397
* Iterate to convergence.
64136398
*/
@@ -6425,6 +6410,11 @@ spa_sync(spa_t *spa, uint64_t txg)
64256410
if (pass < zfs_sync_pass_deferred_free) {
64266411
spa_sync_frees(spa, free_bpl, tx);
64276412
} else {
6413+
/*
6414+
* We can not defer frees in pass 1, because
6415+
* we sync the deferred frees later in pass 1.
6416+
*/
6417+
ASSERT3U(pass, >, 1);
64286418
bplist_iterate(free_bpl, bpobj_enqueue_cb,
64296419
&spa->spa_deferred_bpobj, tx);
64306420
}
@@ -6435,8 +6425,37 @@ spa_sync(spa_t *spa, uint64_t txg)
64356425
while ((vd = txg_list_remove(&spa->spa_vdev_txg_list, txg)))
64366426
vdev_sync(vd, txg);
64376427

6438-
if (pass == 1)
6428+
if (pass == 1) {
64396429
spa_sync_upgrades(spa, tx);
6430+
ASSERT3U(txg, >=,
6431+
spa->spa_uberblock.ub_rootbp.blk_birth);
6432+
/*
6433+
* Note: We need to check if the MOS is dirty
6434+
* because we could have marked the MOS dirty
6435+
* without updating the uberblock (e.g. if we
6436+
* have sync tasks but no dirty user data). We
6437+
* need to check the uberblock's rootbp because
6438+
* it is updated if we have synced out dirty
6439+
* data (though in this case the MOS will most
6440+
* likely also be dirty due to second order
6441+
* effects, we don't want to rely on that here).
6442+
*/
6443+
if (spa->spa_uberblock.ub_rootbp.blk_birth < txg &&
6444+
!dmu_objset_is_dirty(mos, txg)) {
6445+
/*
6446+
* Nothing changed on the first pass,
6447+
* therefore this TXG is a no-op. Avoid
6448+
* syncing deferred frees, so that we
6449+
* can keep this TXG as a no-op.
6450+
*/
6451+
ASSERT(txg_list_empty(&dp->dp_dirty_datasets,
6452+
txg));
6453+
ASSERT(txg_list_empty(&dp->dp_dirty_dirs, txg));
6454+
ASSERT(txg_list_empty(&dp->dp_sync_tasks, txg));
6455+
break;
6456+
}
6457+
spa_sync_deferred_frees(spa, tx);
6458+
}
64406459

64416460
} while (dmu_objset_is_dirty(mos, txg));
64426461

module/zfs/uberblock.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*/
2121
/*
2222
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23-
* Copyright (c) 2013 by Delphix. All rights reserved.
23+
* Copyright (c) 2013, 2014 by Delphix. All rights reserved.
2424
*/
2525

2626
#include <sys/zfs_context.h>
@@ -40,10 +40,10 @@ uberblock_verify(uberblock_t *ub)
4040
}
4141

4242
/*
43-
* Update the uberblock and return a boolean value indicating whether
44-
* anything changed in this transaction group.
43+
* Update the uberblock and return TRUE if anything changed in this
44+
* transaction group.
4545
*/
46-
int
46+
boolean_t
4747
uberblock_update(uberblock_t *ub, vdev_t *rvd, uint64_t txg)
4848
{
4949
ASSERT(ub->ub_txg < txg);

0 commit comments

Comments
 (0)