Move iput() after zfs_inode_update()

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
This commit is contained in:
Brian Behlendorf 2012-09-12 11:16:08 -07:00
parent cda4db408c
commit 5915791096

View File

@ -1900,13 +1900,13 @@ zfs_rmdir(struct inode *dip, char *name, struct inode *cwd, cred_t *cr,
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);
}