From d816bc5ec76b050ab5319112320e1676d538161c Mon Sep 17 00:00:00 2001 From: George Amanakis Date: Fri, 24 Feb 2023 02:14:52 +0100 Subject: [PATCH] Move dmu_buf_rele() after dsl_dataset_sync_done() Otherwise the dataset may be freed after the last dmu_buf_rele() leading to a panic. Reviewed-by: Mark Maybee Reviewed-by: Matthew Ahrens Signed-off-by: George Amanakis Closes #14522 Closes #14523 --- module/zfs/dmu_objset.c | 1 + module/zfs/dsl_crypt.c | 3 --- module/zfs/dsl_dataset.c | 9 ++------- module/zfs/dsl_pool.c | 1 + 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c index 5083b17634..6cc90dcac3 100644 --- a/module/zfs/dmu_objset.c +++ b/module/zfs/dmu_objset.c @@ -1301,6 +1301,7 @@ dmu_objset_create_sync(void *arg, dmu_tx_t *tx) ASSERT3P(ds->ds_key_mapping, !=, NULL); key_mapping_rele(spa, ds->ds_key_mapping, ds); dsl_dataset_sync_done(ds, tx); + dmu_buf_rele(ds->ds_dbuf, ds); } mutex_enter(&ds->ds_lock); diff --git a/module/zfs/dsl_crypt.c b/module/zfs/dsl_crypt.c index 382de208b0..408d038b4d 100644 --- a/module/zfs/dsl_crypt.c +++ b/module/zfs/dsl_crypt.c @@ -2119,9 +2119,6 @@ dsl_crypto_recv_raw_objset_sync(dsl_dataset_t *ds, dmu_objset_type_t ostype, zio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED); dsl_dataset_sync(ds, zio, tx); VERIFY0(zio_wait(zio)); - - /* dsl_dataset_sync_done will drop this reference. */ - dmu_buf_add_ref(ds->ds_dbuf, ds); dsl_dataset_sync_done(ds, tx); } } diff --git a/module/zfs/dsl_dataset.c b/module/zfs/dsl_dataset.c index 02eef6cda9..3cc7d68ebc 100644 --- a/module/zfs/dsl_dataset.c +++ b/module/zfs/dsl_dataset.c @@ -1272,9 +1272,6 @@ dsl_dataset_zero_zil(dsl_dataset_t *ds, dmu_tx_t *tx) zio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED); dsl_dataset_sync(ds, zio, tx); VERIFY0(zio_wait(zio)); - - /* dsl_dataset_sync_done will drop this reference. */ - dmu_buf_add_ref(ds->ds_dbuf, ds); dsl_dataset_sync_done(ds, tx); } } @@ -2271,10 +2268,6 @@ dsl_dataset_sync_done(dsl_dataset_t *ds, dmu_tx_t *tx) else ASSERT0(os->os_next_write_raw[tx->tx_txg & TXG_MASK]); - ASSERT(!dmu_objset_is_dirty(os, dmu_tx_get_txg(tx))); - - dmu_buf_rele(ds->ds_dbuf, ds); - for (spa_feature_t f = 0; f < SPA_FEATURES; f++) { if (zfeature_active(f, ds->ds_feature_activation[f])) { @@ -2285,6 +2278,8 @@ dsl_dataset_sync_done(dsl_dataset_t *ds, dmu_tx_t *tx) ds->ds_feature[f] = ds->ds_feature_activation[f]; } } + + ASSERT(!dmu_objset_is_dirty(os, dmu_tx_get_txg(tx))); } int diff --git a/module/zfs/dsl_pool.c b/module/zfs/dsl_pool.c index 5ca918a87e..9120fef93c 100644 --- a/module/zfs/dsl_pool.c +++ b/module/zfs/dsl_pool.c @@ -788,6 +788,7 @@ dsl_pool_sync(dsl_pool_t *dp, uint64_t txg) } dsl_dataset_sync_done(ds, tx); + dmu_buf_rele(ds->ds_dbuf, ds); } while ((dd = txg_list_remove(&dp->dp_dirty_dirs, txg)) != NULL) {