From owner-p4-projects Fri Mar 7 13:48:59 2003 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D92AD37B401; Fri, 7 Mar 2003 13:48:45 -0800 (PST) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6964737B405 for ; Fri, 7 Mar 2003 13:48:45 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7022943F93 for ; Fri, 7 Mar 2003 13:48:44 -0800 (PST) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h27Lmi0U089065 for ; Fri, 7 Mar 2003 13:48:44 -0800 (PST) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h27LmhDU089062 for perforce@freebsd.org; Fri, 7 Mar 2003 13:48:43 -0800 (PST) Date: Fri, 7 Mar 2003 13:48:43 -0800 (PST) Message-Id: <200303072148.h27LmhDU089062@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson Subject: PERFORCE change 26510 for review To: Perforce Change Reviews Sender: owner-p4-projects@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG http://perforce.freebsd.org/chv.cgi?CH=26510 Change 26510 by rwatson@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 #include #include -#include #include #include @@ -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@FreeBSD.org with "unsubscribe p4-projects" in the body of the message