Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 31 May 2009 14:58:43 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r193175 - head/sys/fs/nullfs
Message-ID:  <200905311458.n4VEwhvH046981@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sun May 31 14:58:43 2009
New Revision: 193175
URL: http://svn.freebsd.org/changeset/base/193175

Log:
  Implement the bypass routine for VOP_VPTOCNP in nullfs.
  Among other things, this makes procfs <pid>/file working for executables
  started from nullfs mount.
  
  Tested by:	pho
  PR:	94269, 104938

Modified:
  head/sys/fs/nullfs/null_vnops.c

Modified: head/sys/fs/nullfs/null_vnops.c
==============================================================================
--- head/sys/fs/nullfs/null_vnops.c	Sun May 31 14:57:43 2009	(r193174)
+++ head/sys/fs/nullfs/null_vnops.c	Sun May 31 14:58:43 2009	(r193175)
@@ -741,6 +741,55 @@ null_vptofh(struct vop_vptofh_args *ap)
 	return VOP_VPTOFH(lvp, ap->a_fhp);
 }
 
+static int
+null_vptocnp(struct vop_vptocnp_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	struct vnode **dvp = ap->a_vpp;
+	struct vnode *lvp, *ldvp;
+	int error, locked;
+
+	if (vp->v_type == VDIR)
+		return (vop_stdvptocnp(ap));
+
+	locked = VOP_ISLOCKED(vp);
+	lvp = NULLVPTOLOWERVP(vp);
+	vhold(lvp);
+	VOP_UNLOCK(vp, 0); /* vp is held by vn_vptocnp_locked that called us */
+	ldvp = lvp;
+	error = vn_vptocnp(&ldvp, ap->a_buf, ap->a_buflen);
+	vdrop(lvp);
+	if (error != 0) {
+		vn_lock(vp, locked | LK_RETRY);
+		return (ENOENT);
+	}
+
+	/*
+	 * Exclusive lock is required by insmntque1 call in
+	 * null_nodeget()
+	 */
+	error = vn_lock(ldvp, LK_EXCLUSIVE);
+	if (error != 0) {
+		vn_lock(vp, locked | LK_RETRY);
+		vdrop(ldvp);
+		return (ENOENT);
+	}
+	vref(ldvp);
+	vdrop(ldvp);
+	error = null_nodeget(vp->v_mount, ldvp, dvp);
+	if (error == 0) {
+#ifdef DIAGNOSTIC
+		NULLVPTOLOWERVP(*dvp);
+#endif
+		vhold(*dvp);
+		vput(*dvp);
+	} else
+		vput(ldvp);
+
+	vn_lock(vp, locked | LK_RETRY);
+	return (error);
+}
+
 /*
  * Global vfs data structures
  */
@@ -762,6 +811,6 @@ struct vop_vector null_vnodeops = {
 	.vop_setattr =		null_setattr,
 	.vop_strategy =		VOP_EOPNOTSUPP,
 	.vop_unlock =		null_unlock,
-	.vop_vptocnp =		vop_stdvptocnp,
+	.vop_vptocnp =		null_vptocnp,
 	.vop_vptofh =		null_vptofh,
 };



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905311458.n4VEwhvH046981>