fix a vnode reference leak caused by illumos compat traverse()
This commit partially reverts r273641 which introduced the leak. It did so to accomodate for some consumers of traverse() that expected the starting vnode to stay as-is. But that introduced the leak in the case when a mounted filesystem was found and its root vnode was returned. r299914 removed the troublesome consumers and now there is no reason to keep the starting vnode. So, now the new rules are: - if there is no mounted filesystem, then nothing is changed - otherwise the starting vnode is always released - the root vnode of the mounted filesystem is returned locked and referenced in the case of success MFC after: 5 weeks X-MFC after: r299914
This commit is contained in:
parent
04f04889ae
commit
88211e07b7
@ -89,13 +89,14 @@ traverse(vnode_t **cvpp, int lktype)
|
||||
if (vfsp == NULL)
|
||||
break;
|
||||
error = vfs_busy(vfsp, 0);
|
||||
|
||||
/*
|
||||
* tvp is NULL for *cvpp vnode, which we can't unlock.
|
||||
* At least some callers expect the reference to be
|
||||
* maintained to the original *cvpp
|
||||
*/
|
||||
if (tvp != NULL)
|
||||
vput(cvp);
|
||||
else
|
||||
vrele(cvp);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
|
@ -1018,7 +1018,6 @@ zfsctl_snapdir_lookup(ap)
|
||||
VN_HOLD(*vpp);
|
||||
err = traverse(vpp, LK_EXCLUSIVE | LK_RETRY);
|
||||
if (err != 0) {
|
||||
VN_RELE(*vpp);
|
||||
*vpp = NULL;
|
||||
} else if (*vpp == sep->se_root) {
|
||||
/*
|
||||
@ -1613,16 +1612,15 @@ zfsctl_lookup_objset(vfs_t *vfsp, uint64_t objsetid, zfsvfs_t **zfsvfsp)
|
||||
*/
|
||||
error = traverse(&vp, LK_SHARED | LK_RETRY);
|
||||
if (error == 0) {
|
||||
if (vp == sep->se_root)
|
||||
if (vp == sep->se_root) {
|
||||
VN_RELE(vp); /* release covered vp */
|
||||
error = SET_ERROR(EINVAL);
|
||||
else
|
||||
} else {
|
||||
*zfsvfsp = VTOZ(vp)->z_zfsvfs;
|
||||
VN_URELE(vp); /* put snapshot's root vp */
|
||||
}
|
||||
}
|
||||
mutex_exit(&sdp->sd_lock);
|
||||
if (error == 0)
|
||||
VN_URELE(vp);
|
||||
else
|
||||
VN_RELE(vp);
|
||||
} else {
|
||||
error = SET_ERROR(EINVAL);
|
||||
mutex_exit(&sdp->sd_lock);
|
||||
|
Loading…
x
Reference in New Issue
Block a user