summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2016-07-13 10:10:05 +0000
committeravg <avg@FreeBSD.org>2016-07-13 10:10:05 +0000
commit3e58df09596aea413cde6ad3fbfd7b9a90280711 (patch)
treeadd0afacf18ab10cd953fa047bd0ba3e29444eb4
parent1774c04e22d7748b699bdb3c75f864096b0f5cc7 (diff)
downloadFreeBSD-src-3e58df09596aea413cde6ad3fbfd7b9a90280711.zip
FreeBSD-src-3e58df09596aea413cde6ad3fbfd7b9a90280711.tar.gz
MFC r299940: fix a vnode reference leak caused by illumos compat traverse()
-rw-r--r--sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c5
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c12
2 files changed, 8 insertions, 9 deletions
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c b/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c
index 848007e..4214ca8 100644
--- a/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c
+++ b/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c
@@ -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);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
index 729d36d..fa350a1 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
@@ -1044,7 +1044,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) {
/*
@@ -1675,16 +1674,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);
OpenPOWER on IntegriCloud