]> granicus.if.org Git - zfs/commitdiff
Fix fail path in zfs_znode_alloc
authorChunwei Chen <david.chen@osnexus.com>
Fri, 9 Oct 2015 19:27:01 +0000 (12:27 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 13 Oct 2015 22:57:17 +0000 (15:57 -0700)
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 <david.chen@osnexus.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #3899

module/zfs/zfs_znode.c

index 8fd16408b021e4564929ecaf42f239f2c8058a93..bf360f1bc6359343268ab8b8995078b03c2a9e8c 100644 (file)
@@ -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);
 }