aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/zfs_vfsops.c
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2013-07-11 14:11:32 -0700
committerBrian Behlendorf <[email protected]>2013-07-12 10:06:53 -0700
commit76351672c222f28ea1b681097a9eff58a6791555 (patch)
treec7654dba10dcca9e875fe19a7df7bce569d5e9ab /module/zfs/zfs_vfsops.c
parente34f17a8dfc0ef7650ba489f9772c2c20dc8bec4 (diff)
Fix zfsctl_expire_snapshot() deadlock
It is possible for an automounted snapshot which is expiring to deadlock with a manual unmount of the snapshot. This can occur because taskq_cancel_id() will block if the task is currently executing until it completes. But it will never complete because zfsctl_unmount_snapshot() is holding the zsb->z_ctldir_lock which zfsctl_expire_snapshot() must acquire. ---------------------- z_unmount/0:2153 --------------------- mutex_lock <blocking on zsb->z_ctldir_lock> zfsctl_unmount_snapshot zfsctl_expire_snapshot taskq_thread ------------------------- zfs:10690 ------------------------- taskq_wait_id <waiting for z_unmount to exit> taskq_cancel_id __zfsctl_unmount_snapshot zfsctl_unmount_snapshot <takes zsb->z_ctldir_lock> zfs_unmount_snap zfs_ioc_destroy_snaps_nvl zfsdev_ioctl do_vfs_ioctl We resolve the deadlock by dropping the zsb->z_ctldir_lock before calling __zfsctl_unmount_snapshot(). The lock is only there to prevent concurrent modification to the zsb->z_ctldir_snaps AVL tree. Moreover, we're careful to remove the zfs_snapentry_t from the AVL tree before dropping the lock which ensures no other tasks can find it. On failure it's added back to the tree. Signed-off-by: Brian Behlendorf <[email protected]> Signed-off-by: Chris Dunlap <[email protected]> Closes #1527
Diffstat (limited to 'module/zfs/zfs_vfsops.c')
0 files changed, 0 insertions, 0 deletions