From 39a41a75a1d8dfaa771b264dd0d48b65c1eddf44 Mon Sep 17 00:00:00 2001 From: ab-oe Date: Fri, 26 Feb 2016 08:33:44 +0100 Subject: [PATCH] Issue #4116. Make zvol update volsize operation synchronous. There is a race condition when new transaction group is added to dp->dp_dirty_datasets list by the zap_update in the zvol_update_volsize. Meanwhile, before these dirty data are synchronized, the receive process can cause that dmu_recv_end_sync is executed. Then finally dirty data are going to be synchronized but the synchronization ends with the NULL pointer dereference error. --- module/zfs/zvol.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index c90e4ec6b979..10ec8ac73508 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -276,10 +276,12 @@ zvol_update_volsize(uint64_t volsize, objset_t *os) { dmu_tx_t *tx; int error; + uint64_t txg; ASSERT(MUTEX_HELD(&zvol_state_lock)); tx = dmu_tx_create(os); + txg = dmu_tx_get_txg(tx); dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL); dmu_tx_mark_netfree(tx); error = dmu_tx_assign(tx, TXG_WAIT); @@ -292,6 +294,8 @@ zvol_update_volsize(uint64_t volsize, objset_t *os) &volsize, tx); dmu_tx_commit(tx); + txg_wait_synced(dmu_objset_pool(os), txg); + if (error == 0) error = dmu_free_long_range(os, ZVOL_OBJ, volsize, DMU_OBJECT_END);