PERFORCE change 26510 for review

Robert Watson rwatson at freebsd.org
Fri Mar 7 21:48:43 GMT 2003


http://perforce.freebsd.org/chv.cgi?CH=26510

Change 26510 by rwatson at rwatson_tislabs on 2003/03/07 13:48:12

	Submerge p_textdvp, since we're no longer making use of
	vn_fullpath() from mac_audit, and the slightly improved
	accuracy of fullpath with respects to the original lookup
	is no longer required, reducing the diffs from _base to
	_mac substantially.  The revised handling of vfs_cache.c
	with regards to locks and walking up the tree is in
	the p4 history and can be extracted if needed in the
	future.

Affected files ...

.. //depot/projects/trustedbsd/mac/sys/compat/linprocfs/linprocfs.c#15 integrate
.. //depot/projects/trustedbsd/mac/sys/fs/procfs/procfs.c#14 integrate
.. //depot/projects/trustedbsd/mac/sys/kern/kern_exec.c#56 edit
.. //depot/projects/trustedbsd/mac/sys/kern/kern_exit.c#28 integrate
.. //depot/projects/trustedbsd/mac/sys/kern/kern_fork.c#28 integrate
.. //depot/projects/trustedbsd/mac/sys/kern/vfs_aio.c#28 integrate
.. //depot/projects/trustedbsd/mac/sys/kern/vfs_cache.c#15 integrate
.. //depot/projects/trustedbsd/mac/sys/sys/proc.h#37 integrate
.. //depot/projects/trustedbsd/mac/sys/sys/vnode.h#54 integrate

Differences ...

==== //depot/projects/trustedbsd/mac/sys/compat/linprocfs/linprocfs.c#15 (text+ko) ====

@@ -343,18 +343,12 @@
 	int error;
 
 	/* resolve symlinks etc. in the emulation tree prefix */
-	NDINIT(&nd, LOOKUP, FOLLOW | SAVESTART, UIO_SYSSPACE, linux_emul_path,
-	    td);
+	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, linux_emul_path, td);
 	flep = NULL;
-	if (namei(&nd) == 0) {
-		if (vn_fullpath(td, nd.ni_dvp, nd.ni_vp, &dlep, &flep) == 0)
-			lep = dlep;
-		else
-			lep = linux_emul_path;
-		NDFREE(&nd, 0);
-	} else {
+	if (namei(&nd) != 0 || vn_fullpath(td, nd.ni_vp, &dlep, &flep) == -1)
 		lep = linux_emul_path;
-	}
+	else
+		lep = dlep;
 	lep_len = strlen(lep);
 	
 	mtx_lock(&mountlist_mtx);

==== //depot/projects/trustedbsd/mac/sys/fs/procfs/procfs.c#14 (text+ko) ====

@@ -70,7 +70,7 @@
 	char *fullpath = "unknown";
 	char *freepath = NULL;
 
-	vn_fullpath(td, p->p_textdvp, p->p_textvp, &fullpath, &freepath);
+	vn_fullpath(td, p->p_textvp, &fullpath, &freepath);
 	sbuf_printf(sb, "%s", fullpath);
 	if (freepath)
 		free(freepath, M_TEMP);

==== //depot/projects/trustedbsd/mac/sys/kern/kern_exec.c#56 (text+ko) ====

@@ -179,7 +179,7 @@
 #ifdef KTRACE
 	struct vnode *tracevp = NULL;
 #endif
-	struct vnode *textvp = NULL, *textdvp = NULL;
+	struct vnode *textvp = NULL;
 	int credential_changing;
 	int textset;
 #ifdef MAC
@@ -362,7 +362,6 @@
 		vput(ndp->ni_vp);
 		vm_object_deallocate(imgp->object);
 		imgp->object = NULL;
-		vrele(ndp->ni_dvp);
 		/* set new name to that of the interpreter */
 		NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME | SAVESTART,
 		    UIO_SYSSPACE, imgp->interpreter_name, td);
@@ -416,7 +415,6 @@
 
 	/* Get a reference to the vnode prior to locking the proc */
 	VREF(ndp->ni_vp);
-	VREF(ndp->ni_dvp);
 
 	/*
 	 * For security and other reasons, signal handlers cannot
@@ -573,9 +571,7 @@
 	 * to locking the proc lock.
 	 */
 	textvp = p->p_textvp;
-	textdvp = p->p_textdvp;
 	p->p_textvp = ndp->ni_vp;
-	p->p_textdvp = ndp->ni_dvp;
 
 	/*
 	 * Notify others that we exec'd, and clear the P_INEXEC flag
@@ -630,8 +626,6 @@
 		vrele(textvp);
 	if (ndp->ni_vp && error != 0)
 		vrele(ndp->ni_vp);
-	if (ndp->ni_dvp && error != 0)
-		vrele(ndp->ni_dvp);
 #ifdef KTRACE
 	if (tracevp != NULL)
 		vrele(tracevp);
@@ -652,7 +646,6 @@
 	if (imgp->vp) {
 		NDFREE(ndp, NDF_ONLY_PNBUF);
 		vput(imgp->vp);
-		vrele(ndp->ni_dvp);
 	}
 
 	if (imgp->stringbase != NULL)

==== //depot/projects/trustedbsd/mac/sys/kern/kern_exit.c#28 (text+ko) ====

@@ -373,10 +373,6 @@
 		p->p_textvp = NULL;
 		vrele(vtmp);
 	}
-	if ((vtmp = p->p_textdvp) != NULL) {
-		p->p_textdvp = NULL;
-		vrele(vtmp);
-	}
 
 	/*
 	 * Release our limits structure.

==== //depot/projects/trustedbsd/mac/sys/kern/kern_fork.c#28 (text+ko) ====

@@ -551,11 +551,8 @@
 
 	/* Bump references to the text vnode (for procfs) */
 	p2->p_textvp = p1->p_textvp;
-	p2->p_textdvp = p1->p_textdvp;
 	if (p2->p_textvp)
 		VREF(p2->p_textvp);
-	if (p2->p_textdvp)
-		VREF(p2->p_textdvp);
 	p2->p_fd = fd;
 	PROC_UNLOCK(p1);
 	PROC_UNLOCK(p2);

==== //depot/projects/trustedbsd/mac/sys/kern/vfs_aio.c#28 (text+ko) ====

@@ -772,10 +772,6 @@
 		vrele(mycp->p_textvp);
 		mycp->p_textvp = NULL;
 	}
-	if (mycp->p_textdvp) {
-		vrele(mycp->p_textdvp);
-		mycp->p_textdvp = NULL;
-	}
 
 	/*
 	 * Allocate and ready the aio control info.  There is one aiop structure

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

@@ -50,7 +50,6 @@
 #include <sys/syscallsubr.h>
 #include <sys/sysproto.h>
 #include <sys/proc.h>
-#include <sys/dirent.h>
 #include <sys/filedesc.h>
 #include <sys/fnv_hash.h>
 
@@ -815,203 +814,107 @@
  * Thus begins the fullpath magic.
  */
 
+#undef STATNODE
+#define STATNODE(name)							\
+	static u_int name;						\
+	SYSCTL_UINT(_vfs_cache, OID_AUTO, name, CTLFLAG_RD, &name, 0, "")
+
 static int disablefullpath;
 SYSCTL_INT(_debug, OID_AUTO, disablefullpath, CTLFLAG_RW, &disablefullpath, 0,
 	"Disable the vn_fullpath function");
 
-static int
-vn_fullpath_dirents_searchbyid(struct thread *td, struct vnode *dvp,
-    struct dirent *dp, struct dirent *enddp, const struct vattr *vap,
-    struct dirent **retdp)
+STATNODE(numfullpathcalls);
+STATNODE(numfullpathfail1);
+STATNODE(numfullpathfail2);
+STATNODE(numfullpathfail3);
+STATNODE(numfullpathfail4);
+STATNODE(numfullpathfound);
+
+/*
+ * Retrieve the full filesystem path that correspond to a vnode from the name
+ * cache (if available)
+ */
+int
+vn_fullpath(struct thread *td, struct vnode *vn, char **retbuf, char **freebuf)
 {
-	struct vattr pvattr;
-	struct componentname cnp;
+	char *bp, *buf;
+	int i, slash_prefixed;
+	struct filedesc *fdp;
+	struct namecache *ncp;
 	struct vnode *vp;
-	struct ucred *ucred = td->td_ucred;
-	int error;
 
-	*retdp = NULL;
-	for (; dp != enddp; dp = (struct dirent *)((char *)dp + dp->d_reclen)) {
-		if (dp->d_name[0] == '.' && (dp->d_namlen == 1 ||
-		    (dp->d_namlen == 2 && dp->d_name[1] == '.')))
-			continue;
-		cnp.cn_nameiop = LOOKUP;
-		cnp.cn_flags = LOCKPARENT | ISLASTCN | NOFOLLOW;
-		cnp.cn_thread = td;
-		cnp.cn_cred = ucred;
-		cnp.cn_nameptr = dp->d_name;
-		cnp.cn_namelen = dp->d_namlen;
-		error = VOP_LOOKUP(dvp, &vp, &cnp);
-		if (error)
-			return (error);
-		error = VOP_GETATTR(vp, &pvattr, ucred, td);
-		if (vp != dvp)
-			(void)vput(vp);
-		else
-			vrele(vp);	/* if looking up "." */
-		if (error)
-			return (error);
-		if (pvattr.va_fsid == vap->va_fsid &&
-		    pvattr.va_fileid == vap->va_fileid) {
-			*retdp = dp;
-			break;
-		}
-	}
-	return (0);
-}
-
-int
-vn_fullpath(struct thread *td, struct vnode *startdvp, struct vnode *startvp,
-    char **buf, char **freebuf) {
-	struct vattr cvattr;
-	struct vnode *vp, *dvp, *fd_rdir;
-	char *bp, *allocedmem, *direntmem;
-	const int direntmem_size = (32 << 10) - MAXPATHLEN;
-	int error, i, slash_prefixed;
-
+	numfullpathcalls++;
 	if (disablefullpath)
-		return (EPERM);
-	FILEDESC_LOCK(td->td_proc->p_fd);
-	fd_rdir = td->td_proc->p_fd->fd_rdir;
-	vref(fd_rdir);
-	FILEDESC_UNLOCK(td->td_proc->p_fd);
-	allocedmem = malloc(MAXPATHLEN + direntmem_size, M_TEMP, M_WAITOK);
-	bp = allocedmem;
-	bp += MAXPATHLEN - 1;
+		return (ENODEV);
+	if (vn == NULL)
+		return (EINVAL);
+	buf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
+	bp = buf + MAXPATHLEN - 1;
 	*bp = '\0';
-	direntmem = allocedmem + MAXPATHLEN;
+	fdp = td->td_proc->p_fd;
 	slash_prefixed = 0;
-	vref(startvp);
-	for (vp = startvp;; vrele(vp), vp = dvp) {
-		struct iovec diov = {
-			direntmem,
-			direntmem_size
-		};
-		struct uio duio = {
-			&diov,
-			1,
-			0,
-			direntmem_size,
-			UIO_SYSSPACE,
-			UIO_READ,
-			td
-		};
-		struct dirent *dp;
-		int direof;
-
-		if (vp == rootvnode || vp == fd_rdir)
-			break;
+	FILEDESC_LOCK(fdp);
+	for (vp = vn; vp != fdp->fd_rdir && vp != rootvnode;) {
 		ASSERT_VOP_LOCKED(vp, "vn_fullpath");
 		if (vp->v_vflag & VV_ROOT) {
 			if (vp->v_mount == NULL) {	/* forced unmount */
-				error = EBADF;
-				goto out;
+				FILEDESC_UNLOCK(fdp);
+				free(buf, M_TEMP);
+				return (EBADF);
 			}
-			dvp = vp->v_mount->mnt_vnodecovered;
-			vref(dvp);
+			vp = vp->v_mount->mnt_vnodecovered;
 			continue;
 		}
-		if (startdvp != NULL) {
-			dvp = startdvp;
-			vref(dvp);
-			startdvp = NULL;
-		} else {
-			if (vp->v_ddid == vp->v_dd->v_id) {
-				dvp = vp->v_dd;
-				vref(dvp);
-			} else {
-				struct componentname cnp;
-
-				if (vp->v_type != VDIR) {
-					error = EBADF;
-					goto out;
-				}
-				cnp.cn_nameiop = LOOKUP;
-				cnp.cn_flags = 0;
-				cnp.cn_thread = td;
-				cnp.cn_cred = td->td_ucred;
-				cnp.cn_nameptr = "..";
-				cnp.cn_namelen = 2;
-				vn_lock(vp, LK_EXCLUSIVE, td);
-				error = VOP_LOOKUP(vp, &dvp, &cnp);
-				if (error) { 
-					VOP_UNLOCK(vp, 0, td);
-					goto out;
-				}
-				VOP_UNLOCK(dvp, 0, td);
-			}
+		if (vp != vn && vp->v_dd->v_id != vp->v_ddid) {
+			FILEDESC_UNLOCK(fdp);
+			numfullpathfail1++;
+			free(buf, M_TEMP);
+			return (ENOTDIR);
+		}
+		ncp = TAILQ_FIRST(&vp->v_cache_dst);
+		if (!ncp) {
+			FILEDESC_UNLOCK(fdp);
+			numfullpathfail2++;
+			free(buf, M_TEMP);
+			return (ENOENT);
 		}
-		if (vp == dvp)
-			break;
-		/*
-		 * Utilize POSIX requirement of files having same
-		 * st_dev and st_ino to be the same  file, in our
-		 * case with vattr.va_fsid and vattr.va_fileid.
-		 */
-		vn_lock(vp, LK_EXCLUSIVE, td);
-		error = VOP_GETATTR(vp, &cvattr, curthread->td_ucred,
-		    curthread);
-		VOP_UNLOCK(vp, 0, td);
-		if (error) {
-			vrele(dvp);
-			goto out;
+		if (vp != vn && ncp->nc_dvp != vp->v_dd) {
+			FILEDESC_UNLOCK(fdp);
+			numfullpathfail3++;
+			free(buf, M_TEMP);
+			return (EBADF);
 		}
-		vn_lock(dvp, LK_EXCLUSIVE, td);
-		for (direof = 0; !direof;) {
-			error = VOP_READDIR(dvp, &duio, td->td_ucred, &direof,
-			    NULL, NULL);
-			if (error)
-				break;
-			error = vn_fullpath_dirents_searchbyid(td, dvp,
-			    (struct dirent *)direntmem,
-			    (struct dirent *)(direntmem +
-			    direntmem_size - duio.uio_resid),
-			    &cvattr, &dp);
-			if (error)
-				break;
-			if (dp != NULL) {
-				for (i = dp->d_namlen - 1; i >= 0; i--) {
-					if (bp == allocedmem) {
-						error = ENOMEM;
-						vput(dvp);
-						goto out;
-					}
-					*--bp = dp->d_name[i];
-				}
-				goto nextcomp;
+		for (i = ncp->nc_nlen - 1; i >= 0; i--) {
+			if (bp == buf) {
+				FILEDESC_UNLOCK(fdp);
+				numfullpathfail4++;
+				free(buf, M_TEMP);
+				return (ENOMEM);
 			}
-			diov.iov_base = direntmem;
-			diov.iov_len = direntmem_size;
-			duio.uio_resid = direntmem_size;
+			*--bp = ncp->nc_name[i];
 		}
-		vput(dvp);
-		if (direof)
-			error = ENOENT;
-		goto out;
-nextcomp:
-		if (bp == allocedmem) {
-			error = ENOMEM;
-			vput(dvp);
-			goto out;
+		if (bp == buf) {
+			FILEDESC_UNLOCK(fdp);
+			numfullpathfail4++;
+			free(buf, M_TEMP);
+			return (ENOMEM);
 		}
 		*--bp = '/';
 		slash_prefixed = 1;
-		VOP_UNLOCK(dvp, 0, td);
+		vp = ncp->nc_dvp;
 	}
 	if (!slash_prefixed) {
-		if (bp == allocedmem) {
-			error = ENOMEM;
-			goto out;
+		if (bp == buf) {
+			FILEDESC_UNLOCK(fdp);
+			numfullpathfail4++;
+			free(buf, M_TEMP);
+			return (ENOMEM);
 		}
 		*--bp = '/';
 	}
-	error = 0;
-	*buf = bp;
-	*freebuf = allocedmem;
-out:
-	vrele(vp);
-	vrele(fd_rdir);
-	if (error)
-		free(allocedmem, M_TEMP);
-	return (error);
+	FILEDESC_UNLOCK(fdp);
+	numfullpathfound++;
+	*retbuf = bp; 
+	*freebuf = buf;
+	return (0);
 }

==== //depot/projects/trustedbsd/mac/sys/sys/proc.h#37 (text+ko) ====

@@ -556,7 +556,6 @@
 	struct vnode	*p_tracep;	/* (c + o) Trace to vnode. */
 	sigset_t	p_siglist;	/* (c) Sigs arrived, not delivered. */
 	struct vnode	*p_textvp;	/* (b) Vnode of executable. */
-	struct vnode	*p_textdvp;	/* (b) Dir vnode of executable. */
 	char		p_lock;		/* (c) Proclock (prevent swap) count. */
 	struct klist	p_klist;	/* (c) Knotes attached to this proc. */
 	struct sigiolst	p_sigiolst;	/* (c) List of sigio sources. */

==== //depot/projects/trustedbsd/mac/sys/sys/vnode.h#54 (text+ko) ====

@@ -617,11 +617,10 @@
 int	lease_check(struct vop_lease_args *ap);
 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_textdvp,		\
-	(p)->p_textvp,  rb, rfb)
-int	vn_fullpath(struct thread *td, struct vnode *optional_dvp,
-	    struct vnode *vn, char **retbuf, char **freebuf);
+#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,
+	    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);
 int	vaccess_acl_posix1e(enum vtype type, uid_t file_uid,
To Unsubscribe: send mail to majordomo at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message



More information about the trustedbsd-cvs mailing list