diff --git a/module/os/freebsd/zfs/zvol_os.c b/module/os/freebsd/zfs/zvol_os.c index 348c24631b..695253ac67 100644 --- a/module/os/freebsd/zfs/zvol_os.c +++ b/module/os/freebsd/zfs/zvol_os.c @@ -1157,6 +1157,9 @@ zvol_ensure_zilog(zvol_state_t *zv) zv->zv_zilog = zil_open(zv->zv_objset, zvol_get_data); zv->zv_flags |= ZVOL_WRITTEN_TO; + /* replay / destroy done in zvol_create_minor_impl() */ + VERIFY0((zv->zv_zilog->zl_header->zh_flags & + ZIL_REPLAY_NEEDED)); } rw_downgrade(&zv->zv_suspend_lock); } @@ -1381,12 +1384,16 @@ zvol_create_minor_impl(const char *name) zv->zv_volsize = volsize; zv->zv_objset = os; + ASSERT3P(zv->zv_zilog, ==, NULL); + zv->zv_zilog = zil_open(os, zvol_get_data); if (spa_writeable(dmu_objset_spa(os))) { if (zil_replay_disable) - zil_destroy(dmu_objset_zil(os), B_FALSE); + zil_destroy(zv->zv_zilog, B_FALSE); else zil_replay(os, zv, zvol_replay_vector); } + zil_close(zv->zv_zilog); + zv->zv_zilog = NULL; ASSERT3P(zv->zv_kstat.dk_kstats, ==, NULL); dataset_kstats_create(&zv->zv_kstat, zv->zv_objset); diff --git a/module/os/linux/zfs/zvol_os.c b/module/os/linux/zfs/zvol_os.c index 6158d58ddc..836af9199c 100644 --- a/module/os/linux/zfs/zvol_os.c +++ b/module/os/linux/zfs/zvol_os.c @@ -357,6 +357,9 @@ zvol_request(struct request_queue *q, struct bio *bio) zv->zv_zilog = zil_open(zv->zv_objset, zvol_get_data); zv->zv_flags |= ZVOL_WRITTEN_TO; + /* replay / destroy done in zvol_create_minor */ + VERIFY0((zv->zv_zilog->zl_header->zh_flags & + ZIL_REPLAY_NEEDED)); } rw_downgrade(&zv->zv_suspend_lock); } @@ -947,12 +950,16 @@ zvol_os_create_minor(const char *name) blk_queue_flag_set(QUEUE_FLAG_SCSI_PASSTHROUGH, zv->zv_zso->zvo_queue); #endif + ASSERT3P(zv->zv_zilog, ==, NULL); + zv->zv_zilog = zil_open(os, zvol_get_data); if (spa_writeable(dmu_objset_spa(os))) { if (zil_replay_disable) - zil_destroy(dmu_objset_zil(os), B_FALSE); + zil_destroy(zv->zv_zilog, B_FALSE); else zil_replay(os, zv, zvol_replay_vector); } + zil_close(zv->zv_zilog); + zv->zv_zilog = NULL; ASSERT3P(zv->zv_kstat.dk_kstats, ==, NULL); dataset_kstats_create(&zv->zv_kstat, zv->zv_objset); diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index 7c6dae8650..44f9832ce8 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -473,7 +473,19 @@ zvol_replay_truncate(void *arg1, void *arg2, boolean_t byteswap) offset = lr->lr_offset; length = lr->lr_length; - return (dmu_free_long_range(zv->zv_objset, ZVOL_OBJ, offset, length)); + dmu_tx_t *tx = dmu_tx_create(zv->zv_objset); + dmu_tx_mark_netfree(tx); + int error = dmu_tx_assign(tx, TXG_WAIT); + if (error != 0) { + dmu_tx_abort(tx); + } else { + zil_replaying(zv->zv_zilog, tx); + dmu_tx_commit(tx); + error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ, offset, + length); + } + + return (error); } /* @@ -513,6 +525,7 @@ zvol_replay_write(void *arg1, void *arg2, boolean_t byteswap) dmu_tx_abort(tx); } else { dmu_write(os, ZVOL_OBJ, offset, length, data, tx); + zil_replaying(zv->zv_zilog, tx); dmu_tx_commit(tx); }