diff options
author | John Poduska <[email protected]> | 2020-03-12 13:25:56 -0400 |
---|---|---|
committer | GitHub <[email protected]> | 2020-03-12 10:25:56 -0700 |
commit | e6b28efccc4853b4f2715c2d37ab05cead2e1c3e (patch) | |
tree | 106de4649fcdb96798b03a92309b1e9ffa9540ef /include/sys/dmu_impl.h | |
parent | 1e9231ada893d43bdbfa8ef3a11f1e423296981d (diff) |
Prevent race condition in dnode_dest (#10101)
dnode_special_close() waits for the refcount of dn_holds to go to zero
without holding the dn_mtx. dnode_rele_and_unlock() does the final
remove to dn_holds with dn_mtx being held:
refs = zfs_refcount_remove(&dn->dn_holds, tag);
mutex_exit(&dn->dn_mtx);
So, there is a race condition after the remove until dn_mtx is
dropped. During that time, dnode_destroy() can get called, which ends
up in dnode_dest() calling mutex_destroy() and a panic since the lock
is still held.
This change adds a condvar to wait for the final dnode_rele_and_unlock()
to release the dn_mtx before calling dnode_destroy().
Reviewed-by: Paul Dagnelie <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Matthew Ahrens <[email protected]>
Signed-off-by: John Poduska <[email protected]>
Closes #7814
Closes #10101
Diffstat (limited to 'include/sys/dmu_impl.h')
-rw-r--r-- | include/sys/dmu_impl.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/sys/dmu_impl.h b/include/sys/dmu_impl.h index 8d0b96084..0c6273a3a 100644 --- a/include/sys/dmu_impl.h +++ b/include/sys/dmu_impl.h @@ -164,6 +164,7 @@ extern "C" { * dn_dirty_txg * dd_assigned_tx * dn_notxholds + * dn_nodnholds * dn_dirtyctx * dn_dirtyctx_firstset * (dn_phys copy fields?) |