Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Jan 2004 13:28:20 -0800 (PST)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 45170 for review
Message-ID:  <200401112128.i0BLSKw2003872@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=45170

Change 45170 by rwatson@rwatson_paprika on 2004/01/11 13:28:06

	Split vn_fullpath() into two functions:
	- vn_fullpath(): interogates the name cache to build a file
	  path back to either the rootvnode, or to optional_root.
	- vn_fullpath_thread(): does the same as vn_fullpath(), only
	  in the context of a process with a file descriptor array
	  and defined root directory, which is used as as the
	  optional_root argument to vn_fullpath().

Affected files ...

.. //depot/projects/trustedbsd/audit2/sys/kern/vfs_cache.c#2 edit
.. //depot/projects/trustedbsd/audit2/sys/sys/vnode.h#2 edit

Differences ...

==== //depot/projects/trustedbsd/audit2/sys/kern/vfs_cache.c#2 (text+ko) ====

@@ -927,13 +927,14 @@
  * cache (if available)
  */
 int
-vn_fullpath(struct thread *td, struct vnode *vn, char **retbuf, char **freebuf)
+vn_fullpath(struct vnode *optional_root, struct vnode *vn, char **retbuf,
+    char **freebuf)
 {
 	char *bp, *buf;
 	int i, slash_prefixed;
-	struct filedesc *fdp;
 	struct namecache *ncp;
 	struct vnode *vp;
+	int error;
 
 	numfullpathcalls++;
 	if (disablefullpath)
@@ -943,58 +944,47 @@
 	buf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
 	bp = buf + MAXPATHLEN - 1;
 	*bp = '\0';
-	fdp = td->td_proc->p_fd;
 	slash_prefixed = 0;
+	error = 0;
 	ASSERT_VOP_LOCKED(vn, "vn_fullpath");
-	FILEDESC_LOCK(fdp);
-	for (vp = vn; vp != fdp->fd_rdir && vp != rootvnode;) {
+	for (vp = vn; vp != optional_root && vp != rootvnode;) {
 		if (vp->v_vflag & VV_ROOT) {
 			if (vp->v_mount == NULL) {	/* forced unmount */
-				FILEDESC_UNLOCK(fdp);
-				free(buf, M_TEMP);
-				return (EBADF);
+				error = EBADF;
+				goto out1;
 			}
 			vp = vp->v_mount->mnt_vnodecovered;
 			continue;
 		}
 		if (vp != vn && vp->v_dd->v_id != vp->v_ddid) {
-			FILEDESC_UNLOCK(fdp);
-			free(buf, M_TEMP);
 			numfullpathfail1++;
-			return (ENOTDIR);
+			error = ENOTDIR;
+			goto out1;
 		}
 		CACHE_LOCK();
 		ncp = TAILQ_FIRST(&vp->v_cache_dst);
 		if (!ncp) {
 			numfullpathfail2++;
-			CACHE_UNLOCK();
-			FILEDESC_UNLOCK(fdp);
-			free(buf, M_TEMP);
-			return (ENOENT);
+			error = ENOENT;
+			goto out2;
 		}
 		if (vp != vn && ncp->nc_dvp != vp->v_dd) {
 			numfullpathfail3++;
-			CACHE_UNLOCK();
-			FILEDESC_UNLOCK(fdp);
-			free(buf, M_TEMP);
-			return (EBADF);
+			error = EBADF;
+			goto out2;
 		}
 		for (i = ncp->nc_nlen - 1; i >= 0; i--) {
 			if (bp == buf) {
 				numfullpathfail4++;
-				CACHE_UNLOCK();
-				FILEDESC_UNLOCK(fdp);
-				free(buf, M_TEMP);
-				return (ENOMEM);
+				error = ENOMEM;
+				goto out2;
 			}
 			*--bp = ncp->nc_name[i];
 		}
 		if (bp == buf) {
 			numfullpathfail4++;
-			CACHE_UNLOCK();
-			FILEDESC_UNLOCK(fdp);
-			free(buf, M_TEMP);
-			return (ENOMEM);
+			error = ENOMEM;
+			goto out2;
 		}
 		*--bp = '/';
 		slash_prefixed = 1;
@@ -1004,15 +994,44 @@
 	if (!slash_prefixed) {
 		if (bp == buf) {
 			numfullpathfail4++;
-			FILEDESC_UNLOCK(fdp);
-			free(buf, M_TEMP);
-			return (ENOMEM);
+			error = ENOMEM;
+			goto out1;
 		}
 		*--bp = '/';
 	}
-	FILEDESC_UNLOCK(fdp);
 	numfullpathfound++;
 	*retbuf = bp;
 	*freebuf = buf;
+out2:
+	CACHE_UNLOCK();
+out1:
+	if (error)
+		free(buf, M_TEMP);
 	return (0);
 }
+
+/*
+ * Perform a vn_fullpath() operation relative to a specific process's
+ * root.  The process is specified using a thread, which for locking
+ * reasons, should be curthread.  A better API might pass in a reference
+ * to struct filedesc * to specify what root to use.
+ */
+int
+vn_fullpath_thread(struct thread *td, struct vnode *vn, char **retbuf,
+    char **freebuf)
+{
+	struct filedesc *fdp;
+	int error;
+
+	/*
+	 * XXXVFS: This was the way it was done before, but perhaps
+	 * we should just vref() the fdp root directory, rather than
+	 * holding the file descriptor lock across the entire
+	 * operation?
+	 */
+	fdp = td->td_proc->p_fd;
+	FILEDESC_LOCK(fdp);
+	error = vn_fullpath(fdp->fd_rdir, vn, retbuf, freebuf);
+	FILEDESC_UNLOCK(fdp);
+	return (error);
+}

==== //depot/projects/trustedbsd/audit2/sys/sys/vnode.h#2 (text+ko) ====

@@ -610,8 +610,10 @@
 int	spec_vnoperate(struct vop_generic_args *);
 int	speedup_syncer(void);
 #define textvp_fullpath(p, rb, rfb) \
-	vn_fullpath(FIRST_THREAD_IN_PROC(p), (p)->p_textvp, rb, rfb)
-int	vn_fullpath(struct thread *td, struct vnode *vn,
+	vn_fullpath_thread(FIRST_THREAD_IN_PROC(p), (p)->p_textvp, rb, rfb)
+int	vn_fullpath(struct vnode *optional_root, struct vnode *vn,
+	    char **retbuf, char **freebuf);
+int	vn_fullpath_thread(struct thread *td, struct vnode *vn,
 	    char **retbuf, char **freebuf);
 int	vaccess(enum vtype type, mode_t file_mode, uid_t uid, gid_t gid,
 	    mode_t acc_mode, struct ucred *cred, int *privused);



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