]> granicus.if.org Git - zfs/commitdiff
Fix z_teardown_inactive_lock deadlock
authorBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 9 Sep 2014 01:31:27 +0000 (18:31 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 11 Sep 2014 16:11:45 +0000 (09:11 -0700)
When rolling back a mounted filesystem zfs_suspend() is called
which acquires the z_teardown_inactive_lock.  This lock can not
be dropped until the filesystem has been rolled back and resumed
in zfs_resume_fs().

Therefore, we must not call iput() under this lock because it
may result in the inode->evict() handler being called which also
takes this lock.  Instead use zfs_iput_async() to ensure dropping
the last reference is deferred and runs in a safe context.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #2670

module/zfs/zfs_znode.c

index f2e305f7af2c7190fb25e88812aff82d2036dc21..08faf0838c680b7c88144a4501b66ab178fc4fa8 100644 (file)
@@ -1009,7 +1009,7 @@ zfs_rezget(znode_t *zp)
        }
 
        if (zp->z_xattr_parent) {
-               iput(ZTOI(zp->z_xattr_parent));
+               zfs_iput_async(ZTOI(zp->z_xattr_parent));
                zp->z_xattr_parent = NULL;
        }
        rw_exit(&zp->z_xattr_lock);