Author: avg
Date: Mon May 16 12:15:19 2016
New Revision: 299940
URL: https://svnweb.freebsd.org/changeset/base/299940

Log:
  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

Modified:
  head/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c

Modified: head/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c
==============================================================================
--- head/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c  Mon May 16 
12:02:06 2016        (r299939)
+++ head/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c  Mon May 16 
12:15:19 2016        (r299940)
@@ -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);
 

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c    Mon May 
16 12:02:06 2016        (r299939)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c    Mon May 
16 12:15:19 2016        (r299940)
@@ -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
                 */
                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);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to