From owner-p4-projects@FreeBSD.ORG Sun Jan 11 13:28:23 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 02C0C16A4D1; Sun, 11 Jan 2004 13:28:23 -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 D1E4516A4CE for ; Sun, 11 Jan 2004 13:28:22 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2370343D41 for ; Sun, 11 Jan 2004 13:28:21 -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.10/8.12.10) with ESMTP id i0BLSK0B003875 for ; Sun, 11 Jan 2004 13:28:20 -0800 (PST) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.10/8.12.10/Submit) id i0BLSKw2003872 for perforce@freebsd.org; Sun, 11 Jan 2004 13:28:20 -0800 (PST) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Sun, 11 Jan 2004 13:28:20 -0800 (PST) Message-Id: <200401112128.i0BLSKw2003872@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 To: Perforce Change Reviews Subject: PERFORCE change 45170 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Jan 2004 21:28:23 -0000 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);