Drain iput taskq outside z_teardown_lock
It's unsafe to drain the iput taskq while holding the z_teardown_lock as a writer. This is because when the last reference on an inode is dropped it may still have pages which need to be written to disk. This will be done through zpl_writepages which will acquire the z_teardown_lock as a reader in ZFS_ENTER. Therefore, if we're holding the lock as a writer in zfs_sb_teardown the unmount will deadlock. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Chris Dunlop <chris@onthe.net.au> Closes #1988
This commit is contained in:
parent
4fcc43790c
commit
fd23720ae1
|
@ -1091,6 +1091,14 @@ zfs_sb_teardown(zfs_sb_t *zsb, boolean_t unmounting)
|
|||
{
|
||||
znode_t *zp;
|
||||
|
||||
/*
|
||||
* If someone has not already unmounted this file system,
|
||||
* drain the iput_taskq to ensure all active references to the
|
||||
* zfs_sb_t have been handled only then can it be safely destroyed.
|
||||
*/
|
||||
if (zsb->z_os)
|
||||
taskq_wait(dsl_pool_iput_taskq(dmu_objset_pool(zsb->z_os)));
|
||||
|
||||
rrw_enter(&zsb->z_teardown_lock, RW_WRITER, FTAG);
|
||||
|
||||
if (!unmounting) {
|
||||
|
@ -1104,14 +1112,6 @@ zfs_sb_teardown(zfs_sb_t *zsb, boolean_t unmounting)
|
|||
shrink_dcache_sb(zsb->z_parent->z_sb);
|
||||
}
|
||||
|
||||
/*
|
||||
* If someone has not already unmounted this file system,
|
||||
* drain the iput_taskq to ensure all active references to the
|
||||
* zfs_sb_t have been handled only then can it be safely destroyed.
|
||||
*/
|
||||
if (zsb->z_os)
|
||||
taskq_wait(dsl_pool_iput_taskq(dmu_objset_pool(zsb->z_os)));
|
||||
|
||||
/*
|
||||
* Close the zil. NB: Can't close the zil while zfs_inactive
|
||||
* threads are blocked as zil_close can call zfs_inactive.
|
||||
|
|
Loading…
Reference in New Issue