summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChunwei Chen <[email protected]>2015-10-09 12:27:01 -0700
committerBrian Behlendorf <[email protected]>2015-10-13 15:57:17 -0700
commit07d63f0cb953b7a0e5a88820e7cc2341d6e1d79e (patch)
tree0c3d7ef4e7755ed62b4d44513c512683e16d5703
parentaa159afb568fff01bb9f427c16b406c5d29664c7 (diff)
Fix fail path in zfs_znode_alloc
When sa_bulk_lookup() fails, unlock_new_inode() will spit out a WARNING. It will also recursive deadlock on ZFS_OBJ_HOLD_ENTER in zfs_zinactive(). Since we never call insert_inode_locked in fail path, I_NEW is never set, the inode is never hashed. So unlock_new_inode() can be safely remove it. We set z_sa_hdl to NULL in fail path so that iput path will stop at zfs_inactive() without entering zfs_zinactive(). This way we can avoid the deadlock and prevent double sa_handle_destroy(). Signed-off-by: Chunwei Chen <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Issue #3899
-rw-r--r--module/zfs/zfs_znode.c3
1 files changed, 1 insertions, 2 deletions
diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c
index 8fd16408b..bf360f1bc 100644
--- a/module/zfs/zfs_znode.c
+++ b/module/zfs/zfs_znode.c
@@ -410,7 +410,7 @@ zfs_znode_alloc(zfs_sb_t *zsb, dmu_buf_t *db, int blksz,
if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count) != 0 || zp->z_gen == 0) {
if (hdl == NULL)
sa_handle_destroy(zp->z_sa_hdl);
-
+ zp->z_sa_hdl = NULL;
goto error;
}
@@ -448,7 +448,6 @@ zfs_znode_alloc(zfs_sb_t *zsb, dmu_buf_t *db, int blksz,
return (zp);
error:
- unlock_new_inode(ip);
iput(ip);
return (NULL);
}