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