Skip to content

Commit

Permalink
Fix deadlock between zfs umount & snapentry_expire
Browse files Browse the repository at this point in the history
zfs umount -> zfsctl_destroy() takes zfs_snapshot_lock WRITER &
calls zfsctl_snapshot_unmount_cancel() which waits for
snapentry_expire() if present(only when snap is automounted).
This snapentry_expire() itself then waits for zfs_snapshot_lock
READER, resulting in a deadlock.

Fix is to take READER in zfsctl_destroy() & upgrade to WRITER
after call to zfsctl_snapshot_unmount_cancel() before calling
zfsctl_snapshot_remove(). This allows snapentry_expire() to
progress too with the READER.

Signed-off-by: Rohan Puri <rohan.puri15@gmail.com>
  • Loading branch information
rohan-puri committed Jul 28, 2018
1 parent fb7307b commit 26d4de9
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion module/zfs/zfs_ctldir.c
Original file line number Diff line number Diff line change
Expand Up @@ -566,10 +566,14 @@ zfsctl_destroy(zfsvfs_t *zfsvfs)
spa_t *spa = zfsvfs->z_os->os_spa;
uint64_t objsetid = dmu_objset_id(zfsvfs->z_os);

rw_enter(&zfs_snapshot_lock, RW_WRITER);
rw_enter(&zfs_snapshot_lock, RW_READER);
if ((se = zfsctl_snapshot_find_by_objsetid(spa, objsetid))
!= NULL) {
zfsctl_snapshot_unmount_cancel(se);
if (!rw_tryupgrade(&zfs_snapshot_lock)) {
rw_exit(&zfs_snapshot_lock);
rw_enter(&zfs_snapshot_lock, RW_WRITER);
}
zfsctl_snapshot_remove(se);
zfsctl_snapshot_rele(se);
}
Expand Down

0 comments on commit 26d4de9

Please sign in to comment.