aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--module/os/freebsd/zfs/zvol_os.c9
-rw-r--r--module/os/linux/zfs/zvol_os.c9
-rw-r--r--module/zfs/zvol.c15
3 files changed, 30 insertions, 3 deletions
diff --git a/module/os/freebsd/zfs/zvol_os.c b/module/os/freebsd/zfs/zvol_os.c
index 9c61b45ea..a84ac35a3 100644
--- a/module/os/freebsd/zfs/zvol_os.c
+++ b/module/os/freebsd/zfs/zvol_os.c
@@ -1163,6 +1163,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);
}
@@ -1387,12 +1390,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 9a5913a38..7756d819f 100644
--- a/module/os/linux/zfs/zvol_os.c
+++ b/module/os/linux/zfs/zvol_os.c
@@ -399,6 +399,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);
}
@@ -982,12 +985,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 7c6dae865..44f9832ce 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);
}