Skip to content

Commit

Permalink
Issue openzfs#4116.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ab-oe committed Feb 26, 2016
1 parent d2f3e29 commit 39a41a7
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions module/zfs/zvol.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

This comment has been minimized.

Copy link
@behlendorf

behlendorf Feb 27, 2016

This should be called after dmu_tx_assign(). Prior to this the tx isn't part of any txg.

dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL);
dmu_tx_mark_netfree(tx);
error = dmu_tx_assign(tx, TXG_WAIT);
Expand All @@ -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);
Expand Down

0 comments on commit 39a41a7

Please sign in to comment.