Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 Dec 2008 21:49:39 +0000 (UTC)
From:      Joe Marcus Clarke <marcus@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r186617 - head/sys/fs/pseudofs
Message-ID:  <200812302149.mBULnd6N005838@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marcus (doc,ports committer)
Date: Tue Dec 30 21:49:39 2008
New Revision: 186617
URL: http://svn.freebsd.org/changeset/base/186617

Log:
  Add a VOP_VPTOCNP implementation for pseudofs which covers file systems
  such as procfs and linprocfs.
  
  This implementation's locking was enhanced by kib.
  
  Reviewed by:	kib
  		des
  Approved by:	des
  		kib
  Tested by:	pho

Modified:
  head/sys/fs/pseudofs/pseudofs_vnops.c

Modified: head/sys/fs/pseudofs/pseudofs_vnops.c
==============================================================================
--- head/sys/fs/pseudofs/pseudofs_vnops.c	Tue Dec 30 20:51:07 2008	(r186616)
+++ head/sys/fs/pseudofs/pseudofs_vnops.c	Tue Dec 30 21:49:39 2008	(r186617)
@@ -310,6 +310,84 @@ pfs_getextattr(struct vop_getextattr_arg
 }
 
 /*
+ * Convert a vnode to its component name
+ */
+static int
+pfs_vptocnp(struct vop_vptocnp_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	struct vnode **dvp = ap->a_vpp;
+	struct pfs_vdata *pvd = vp->v_data;
+	struct pfs_node *pd = pvd->pvd_pn;
+	struct pfs_node *pn;
+	struct mount *mp;
+	char *buf = ap->a_buf;
+	int *buflen = ap->a_buflen;
+	char pidbuf[PFS_NAMELEN];
+	pid_t pid = pvd->pvd_pid;
+	int len, i, error, locked;
+
+	i = *buflen;
+	error = 0;
+
+	pfs_lock(pd);
+
+	if (vp->v_type == VDIR && pd->pn_type == pfstype_root) {
+		*dvp = vp;
+		vhold(*dvp);
+		pfs_unlock(pd);
+		PFS_RETURN (0);
+	} else if (vp->v_type == VDIR && pd->pn_type == pfstype_procdir) {
+		len = snprintf(pidbuf, sizeof(pidbuf), "%d", pid);
+		i -= len;
+		if (i < 0) {
+			error = ENOMEM;
+			goto failed;
+		}
+		bcopy(pidbuf, buf + i, len);
+	} else {
+		i -= strlen(pd->pn_name);
+		if (i < 0) {
+			error = ENOMEM;
+			goto failed;
+		}
+		bcopy(pd->pn_name, buf + i, strlen(pd->pn_name));
+	}
+
+	pn = pd->pn_parent;
+	pfs_unlock(pd);
+
+	mp = vp->v_mount;
+	error = vfs_busy(mp, 0);
+	if (error)
+		return (error);
+
+	/*
+	 * vp is held by caller.
+	 */
+	locked = VOP_ISLOCKED(vp);
+	VOP_UNLOCK(vp, 0);
+
+	error = pfs_vncache_alloc(mp, dvp, pn, pid);
+	if (error) {
+		vn_lock(vp, locked | LK_RETRY);
+		vfs_unbusy(mp);
+		PFS_RETURN(error);
+	}
+
+	*buflen = i;
+	vhold(*dvp);
+	vput(*dvp);
+	vn_lock(vp, locked | LK_RETRY);
+	vfs_unbusy(mp);
+
+	PFS_RETURN (0);
+failed:
+	pfs_unlock(pd);
+	PFS_RETURN(error);
+}
+
+/*
  * Look up a file or directory
  */
 static int
@@ -890,6 +968,7 @@ struct vop_vector pfs_vnodeops = {
 	.vop_rmdir =		VOP_EOPNOTSUPP,
 	.vop_setattr =		pfs_setattr,
 	.vop_symlink =		VOP_EOPNOTSUPP,
+	.vop_vptocnp =		pfs_vptocnp,
 	.vop_write =		pfs_write,
 	/* XXX I've probably forgotten a few that need VOP_EOPNOTSUPP */
 };



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