summaryrefslogtreecommitdiffstats
path: root/module/zfs/dsl_pool.c
diff options
context:
space:
mode:
authorGeorge Wilson <[email protected]>2016-11-05 20:43:56 -0700
committerBrian Behlendorf <[email protected]>2017-03-23 18:20:58 -0700
commit55922e73b4294fc6c3014be27b61201b7962088c (patch)
treedc5d76284e608ca16d81b5b1adb0b4aeb668c8de /module/zfs/dsl_pool.c
parent56a6054d553fd7f1cf7d7c86bf4b33951e1d009f (diff)
OpenZFS 3821 - Race in rollback, zil close, and zil flush
Authored by: George Wilson <[email protected]> Reviewed by: Matthew Ahrens <[email protected]> Reviewed by: Dan Kimmel <[email protected]> Reviewed by: Pavel Zakharov <[email protected]> Reviewed by: Andriy Gapon <[email protected]> Approved by: Richard Lowe <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Ported-by: George Melikov <[email protected]> OpenZFS-issue: https://www.illumos.org/issues/3821 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/43297f9 Closes #5905
Diffstat (limited to 'module/zfs/dsl_pool.c')
-rw-r--r--module/zfs/dsl_pool.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/module/zfs/dsl_pool.c b/module/zfs/dsl_pool.c
index 2386484c8..1bc73ebc7 100644
--- a/module/zfs/dsl_pool.c
+++ b/module/zfs/dsl_pool.c
@@ -615,9 +615,16 @@ dsl_pool_sync_done(dsl_pool_t *dp, uint64_t txg)
{
zilog_t *zilog;
- while ((zilog = txg_list_remove(&dp->dp_dirty_zilogs, txg))) {
+ while ((zilog = txg_list_head(&dp->dp_dirty_zilogs, txg))) {
dsl_dataset_t *ds = dmu_objset_ds(zilog->zl_os);
+ /*
+ * We don't remove the zilog from the dp_dirty_zilogs
+ * list until after we've cleaned it. This ensures that
+ * callers of zilog_is_dirty() receive an accurate
+ * answer when they are racing with the spa sync thread.
+ */
zil_clean(zilog, txg);
+ (void) txg_list_remove_this(&dp->dp_dirty_zilogs, zilog, txg);
ASSERT(!dmu_objset_is_dirty(zilog->zl_os, txg));
dmu_buf_rele(ds->ds_dbuf, zilog);
}