aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/dsl_dataset.c
diff options
context:
space:
mode:
authorTom Caputi <[email protected]>2018-08-20 16:42:17 -0400
committerBrian Behlendorf <[email protected]>2018-08-27 10:16:28 -0700
commit47ab01a18f55f89be7b3f340b6ec9101bf9e231c (patch)
treed76615b0403fdd1ba8439b1d57c2e76a0ff8639b /module/zfs/dsl_dataset.c
parent8c4fb36a24d4fd88382e454b13751a5adfea0806 (diff)
Always wait for txg sync when umounting dataset
Currently, when unmounting a filesystem, ZFS will only wait for a txg sync if the dataset is dirty and not readonly. However, this can be problematic in cases where a dataset is remounted readonly immediately before being unmounted, which often happens when the system is being shut down. Since encrypted datasets require that all I/O is completed before the dataset is disowned, this issue causes problems when write I/Os leak into the txgs after the dataset is disowned, which can happen when sync=disabled. While looking into fixes for this issue, it was discovered that dsl_dataset_is_dirty() does not return B_TRUE when the dataset has been removed from the txg dirty datasets list, but has not actually been processed yet. Furthermore, the implementation is comletely different from dmu_objset_is_dirty(), adding to the confusion. Rather than relying on this function, this patch forces the umount code path (and the remount readonly code path) to always perform a txg sync on read-write datasets and removes the function altogether. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Tom Caputi <[email protected]> Closes #7753 Closes #7795
Diffstat (limited to 'module/zfs/dsl_dataset.c')
-rw-r--r--module/zfs/dsl_dataset.c20
1 files changed, 0 insertions, 20 deletions
diff --git a/module/zfs/dsl_dataset.c b/module/zfs/dsl_dataset.c
index bb9b4a1c7..b6e3b9a5c 100644
--- a/module/zfs/dsl_dataset.c
+++ b/module/zfs/dsl_dataset.c
@@ -794,15 +794,6 @@ dsl_dataset_rele_flags(dsl_dataset_t *ds, ds_hold_flags_t flags, void *tag)
(flags & DS_HOLD_FLAG_DECRYPT)) {
(void) spa_keystore_remove_mapping(ds->ds_dir->dd_pool->dp_spa,
ds->ds_object, ds);
-
- /*
- * Encrypted datasets require that users only release their
- * decrypting reference after the dirty data has actually
- * been written out. This ensures that the mapping exists
- * when it is needed to write out dirty data.
- */
- ASSERT(dmu_buf_user_refcount(ds->ds_dbuf) != 0 ||
- !dsl_dataset_is_dirty(ds));
}
dmu_buf_rele(ds->ds_dbuf, tag);
@@ -1168,17 +1159,6 @@ dsl_dataset_dirty(dsl_dataset_t *ds, dmu_tx_t *tx)
}
}
-boolean_t
-dsl_dataset_is_dirty(dsl_dataset_t *ds)
-{
- for (int t = 0; t < TXG_SIZE; t++) {
- if (txg_list_member(&ds->ds_dir->dd_pool->dp_dirty_datasets,
- ds, t))
- return (B_TRUE);
- }
- return (B_FALSE);
-}
-
static int
dsl_dataset_snapshot_reserve_space(dsl_dataset_t *ds, dmu_tx_t *tx)
{