summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2009-05-31 14:58:43 +0000
committerkib <kib@FreeBSD.org>2009-05-31 14:58:43 +0000
commit99131254df449aa0d20af219f3f71fcaac626b99 (patch)
tree2a51ddb3797bed0180c9e57c8f7aade0464ba7e4 /sys/fs
parent443228ae3b3ba01eab22a02b6017cb6d8af64c34 (diff)
downloadFreeBSD-src-99131254df449aa0d20af219f3f71fcaac626b99.zip
FreeBSD-src-99131254df449aa0d20af219f3f71fcaac626b99.tar.gz
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
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/nullfs/null_vnops.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c
index e04b4d1..36eee63 100644
--- a/sys/fs/nullfs/null_vnops.c
+++ b/sys/fs/nullfs/null_vnops.c
@@ -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,
};
OpenPOWER on IntegriCloud