mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-04-06 17:49:11 +03:00
Check for RW_WRITE_HELD in zfs_inactive
Before read locking z_teardown_inactive_lock, we need to check if we have already had write lock on it. Otherwise, we would deadlock on ourself when doing rollback: zfs_ioc_rollback ->zfs_suspend_fs (z_teardown_inactive_lock, RW_WRITER) ->zfs_resume_fs->zfs_rezget->zfs_iput_async->iput-> ... ->zfs_inactive (z_teardown_inactive_lock, RW_READER) Signed-off-by: Chunwei Chen <tuxoko@gmail.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #2869
This commit is contained in:
parent
97771edaca
commit
cafbd2aca3
@ -4096,10 +4096,16 @@ zfs_inactive(struct inode *ip)
|
|||||||
znode_t *zp = ITOZ(ip);
|
znode_t *zp = ITOZ(ip);
|
||||||
zfs_sb_t *zsb = ITOZSB(ip);
|
zfs_sb_t *zsb = ITOZSB(ip);
|
||||||
int error;
|
int error;
|
||||||
|
int need_unlock = 0;
|
||||||
|
|
||||||
rw_enter(&zsb->z_teardown_inactive_lock, RW_READER);
|
/* Only read lock if we haven't already write locked, e.g. rollback */
|
||||||
|
if (!RW_WRITE_HELD(&zsb->z_teardown_inactive_lock)) {
|
||||||
|
need_unlock = 1;
|
||||||
|
rw_enter(&zsb->z_teardown_inactive_lock, RW_READER);
|
||||||
|
}
|
||||||
if (zp->z_sa_hdl == NULL) {
|
if (zp->z_sa_hdl == NULL) {
|
||||||
rw_exit(&zsb->z_teardown_inactive_lock);
|
if (need_unlock)
|
||||||
|
rw_exit(&zsb->z_teardown_inactive_lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4122,7 +4128,8 @@ zfs_inactive(struct inode *ip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
zfs_zinactive(zp);
|
zfs_zinactive(zp);
|
||||||
rw_exit(&zsb->z_teardown_inactive_lock);
|
if (need_unlock)
|
||||||
|
rw_exit(&zsb->z_teardown_inactive_lock);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(zfs_inactive);
|
EXPORT_SYMBOL(zfs_inactive);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user