summaryrefslogtreecommitdiffstats
path: root/module/zfs/zfs_vfsops.c
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2013-01-17 10:05:42 -0800
committerBrian Behlendorf <[email protected]>2013-01-17 11:24:20 -0800
commit7973e464de4f93b6e669f7f04a316e013767224e (patch)
treef1c1911ebd701749d2b3dc3dfaeebe9cc3edf386 /module/zfs/zfs_vfsops.c
parent7b3e34ba5a7ee8d0fda44d214f6f11eb16cdb26f (diff)
Revert "Revert "Fix unlink/xattr deadlock""
This reverts commit 53c7411919a64d6f0889aa0d6974610f6cd35744 effectively reinstating the asynchronous xattr cleanup code. These Linux changes were reverted because after testing and careful contemplation I was convinced that due to the 89260a1c8851ce05ea04b23606ba438b271d890 commit they were no longer required. Unfortunately, the deadlock described in #1176 was a case which wasn't considered. At mount zfs_unlinked_drain() can occur which will unlink a list of znodes in effectively a random order which isn't safe. The only reason it was safe to originally revert this change was the we could guarantee that the VFS would always prune the xattr leaves before the parents. Therefore, until we can cleanly resolve this deadlock for all cases we need to keep this change in spite of the xattr unlink performance penalty associated with it. Signed-off-by: Brian Behlendorf <[email protected]> Closes #1176 Issue #457
Diffstat (limited to 'module/zfs/zfs_vfsops.c')
-rw-r--r--module/zfs/zfs_vfsops.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c
index ac5c317ce..f44524238 100644
--- a/module/zfs/zfs_vfsops.c
+++ b/module/zfs/zfs_vfsops.c
@@ -1056,6 +1056,12 @@ zfs_sb_teardown(zfs_sb_t *zsb, boolean_t unmounting)
}
/*
+ * Drain the iput_taskq to ensure all active references to the
+ * zfs_sb_t have been handled only then can it be safely destroyed.
+ */
+ 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.
*/