Break out of zfs_zget early if unlinked znode
If zp->z_unlinked is set, we're working with a znode that has been marked for deletion. If that's the case, we can skip the "goto again" loop and return ENOENT, as the znode should not be discovered. Reviewed-by: Richard Yao <ryao@gentoo.org> Reviewed-by: Matt Ahrens <mahrens@delphix.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Heitor Alves de Siqueira <halves@canonical.com> Closes #9583
This commit is contained in:
parent
cc1a1e17d9
commit
41e1aa2a06
|
@ -1094,6 +1094,9 @@ again:
|
||||||
mutex_enter(&zp->z_lock);
|
mutex_enter(&zp->z_lock);
|
||||||
ASSERT3U(zp->z_id, ==, obj_num);
|
ASSERT3U(zp->z_id, ==, obj_num);
|
||||||
/*
|
/*
|
||||||
|
* If zp->z_unlinked is set, the znode is already marked
|
||||||
|
* for deletion and should not be discovered.
|
||||||
|
*
|
||||||
* If igrab() returns NULL the VFS has independently
|
* If igrab() returns NULL the VFS has independently
|
||||||
* determined the inode should be evicted and has
|
* determined the inode should be evicted and has
|
||||||
* called iput_final() to start the eviction process.
|
* called iput_final() to start the eviction process.
|
||||||
|
@ -1107,19 +1110,24 @@ again:
|
||||||
* need to detect the active SA hold thereby informing
|
* need to detect the active SA hold thereby informing
|
||||||
* the VFS that this inode should not be evicted.
|
* the VFS that this inode should not be evicted.
|
||||||
*/
|
*/
|
||||||
if (igrab(ZTOI(zp)) == NULL) {
|
if (zp->z_unlinked) {
|
||||||
mutex_exit(&zp->z_lock);
|
err = SET_ERROR(ENOENT);
|
||||||
sa_buf_rele(db, NULL);
|
} else if (igrab(ZTOI(zp)) == NULL) {
|
||||||
zfs_znode_hold_exit(zfsvfs, zh);
|
err = SET_ERROR(EAGAIN);
|
||||||
|
} else {
|
||||||
|
*zpp = zp;
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_exit(&zp->z_lock);
|
||||||
|
sa_buf_rele(db, NULL);
|
||||||
|
zfs_znode_hold_exit(zfsvfs, zh);
|
||||||
|
|
||||||
|
if (err == EAGAIN) {
|
||||||
/* inode might need this to finish evict */
|
/* inode might need this to finish evict */
|
||||||
cond_resched();
|
cond_resched();
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
*zpp = zp;
|
|
||||||
err = 0;
|
|
||||||
mutex_exit(&zp->z_lock);
|
|
||||||
sa_buf_rele(db, NULL);
|
|
||||||
zfs_znode_hold_exit(zfsvfs, zh);
|
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue