Move iput() after zfs_inode_update()
authorBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 12 Sep 2012 18:16:08 +0000 (11:16 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 12 Sep 2012 21:22:52 +0000 (14:22 -0700)
When replaying an unlink/remove operation via zfs_rmdir() the object
being removed will be instantiated by a call to zfs_dirent_lock().
This means that there is a single reference protecting the object.
Right before the call to zfs_inode_update() this reference is dropped
which may cause the object to be destroyed.  This will result in a
NULL dereference as shown by the stack trace is issue #782.

This likely isn't an issue during normal operation because there is
always an additional reference held on the object by the VFS.

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

module/zfs/zfs_vnops.c

index 7561434..3003302 100644 (file)
@@ -1900,13 +1900,13 @@ top:
 out:
        zfs_dirent_unlock(dl);
 
+       zfs_inode_update(dzp);
+       zfs_inode_update(zp);
        iput(ip);
 
        if (zsb->z_os->os_sync == ZFS_SYNC_ALWAYS)
                zil_commit(zilog, 0);
 
-       zfs_inode_update(dzp);
-       zfs_inode_update(zp);
        ZFS_EXIT(zsb);
        return (error);
 }