From owner-p4-projects@FreeBSD.ORG Sat Jun 9 10:31:59 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id A1B3316A46E; Sat, 9 Jun 2007 10:31:59 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 4BE1516A46C for ; Sat, 9 Jun 2007 10:31:59 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 3BABA13C447 for ; Sat, 9 Jun 2007 10:31:59 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l59AVx3K085173 for ; Sat, 9 Jun 2007 10:31:59 GMT (envelope-from rdivacky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l59AVwnR085161 for perforce@freebsd.org; Sat, 9 Jun 2007 10:31:58 GMT (envelope-from rdivacky@FreeBSD.org) Date: Sat, 9 Jun 2007 10:31:58 GMT Message-Id: <200706091031.l59AVwnR085161@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to rdivacky@FreeBSD.org using -f From: Roman Divacky To: Perforce Change Reviews Cc: Subject: PERFORCE change 121263 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 09 Jun 2007 10:32:00 -0000 http://perforce.freebsd.org/chv.cgi?CH=121263 Change 121263 by rdivacky@rdivacky_witten on 2007/06/09 10:31:25 Change all the non-at syscalls that have *at counterparts to the consistent model of having: kern_foo() { return kern_fooat(...., AT_FDCWD); } and kern_fooat() being the complete syscall thus eliminating the need for kern_common_foo() stuff. Suggested by: "Eric Lemar" Requested by: des Affected files ... .. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_syscalls.c#17 edit Differences ... ==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_syscalls.c#17 (text+ko) ==== @@ -88,27 +88,6 @@ static int kern_get_at(struct thread *td, int dirfd, struct vnode **dir_vn); static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred, struct thread *td); -static int kern_common_open(struct thread *td, int flags, int mode, - struct nameidata *nd); -static int kern_common_access(struct thread *td, int flags, - struct nameidata *nd); -static int kern_common_stat(struct thread *td, struct stat *sbp, - struct nameidata *nd); -static int kern_common_lstat(struct thread *td, struct stat *sbp, - struct nameidata *nd); -static int kern_common_chown(struct thread *td, int uid, int gid, - struct nameidata *nd); -static int kern_common_lchown(struct thread *td, int uid, int gid, - struct nameidata *nd); -static int kern_common_chmod(struct thread *td, int mode, struct nameidata *nd); -static int kern_common_readlink(struct thread *td, char *buf, - enum uio_seg bufseg, int count, struct nameidata *nd); -static int kern_common_link(struct thread *td, struct nameidata *ndp, - struct nameidata *ndl); -static int kern_common_utimes(struct thread *td, char *path, enum uio_seg pathseg, - struct timeval *tptr, enum uio_seg tptrseg, struct nameidata *nd); -static int kern_common_rename(struct thread *td, char *from, char *to, - enum uio_seg pathseg, struct nameidata *fromnd, struct nameidata *tond); /* * The module initialization routine for POSIX asynchronous I/O will @@ -980,13 +959,7 @@ kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags, int mode) { - struct nameidata nd; - - AUDIT_ARG(fflags, flags); - AUDIT_ARG(mode, mode); - NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | MPSAFE, pathseg, path, td); - - return kern_common_open(td, flags, mode, &nd); + return kern_openat(td, path, pathseg, flags, mode, AT_FDCWD); } static int @@ -1013,29 +986,8 @@ kern_openat(struct thread *td, char *path, enum uio_seg pathseg, int flags, int mode, int dirfd) { - int error; struct nameidata nd; struct vnode *dir_vn; - - AUDIT_ARG(fflags, flags); - AUDIT_ARG(mode, mode); - /* XXX: audit dirfd */ - - error = kern_get_at(td, dirfd, &dir_vn); - if (error) - return (error); - - NDINIT_AT(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | MPSAFE, pathseg, path, td, dir_vn); - - error = kern_common_open(td, flags, mode, &nd); - if (dir_vn) - vrele(dir_vn); - return (error); -} - -static int -kern_common_open(struct thread *td, int flags, int mode, struct nameidata *nd) -{ struct proc *p = td->td_proc; struct filedesc *fdp = p->p_fd; struct file *fp; @@ -1048,18 +1000,30 @@ struct flock lf; int vfslocked; - if ((flags & O_ACCMODE) == O_ACCMODE) - return (EINVAL); + AUDIT_ARG(fflags, flags); + AUDIT_ARG(mode, mode); + /* XXX: audit dirfd */ + + error = kern_get_at(td, dirfd, &dir_vn); + if (error) + return (error); + + NDINIT_AT(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | MPSAFE, pathseg, path, td, dir_vn); + + if ((flags & O_ACCMODE) == O_ACCMODE) { + error = EINVAL; + goto out; + } flags = FFLAGS(flags); error = falloc(td, &nfp, &indx); if (error) - return (error); + goto out; /* An extra reference on `nfp' has been held for us by falloc(). */ fp = nfp; cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; td->td_dupfd = -1; /* XXX check for fdopen */ - error = vn_open(nd, &flags, cmode, fp); + error = vn_open(&nd, &flags, cmode, fp); if (error) { /* * If the vn_open replaced the method vector, something @@ -1069,7 +1033,8 @@ if (error == ENXIO && fp->f_ops != &badfileops) { fdrop(fp, td); td->td_retval[0] = indx; - return (0); + error = 0; + goto out; } /* @@ -1083,7 +1048,8 @@ dupfdopen(td, fdp, indx, td->td_dupfd, flags, error)) == 0) { td->td_retval[0] = indx; fdrop(fp, td); - return (0); + error = 0; + goto out; } /* * Clean up the descriptor, but only if another thread hadn't @@ -1094,12 +1060,12 @@ if (error == ERESTART) error = EINTR; - return (error); + goto out; } td->td_dupfd = 0; - vfslocked = NDHASGIANT(nd); - NDFREE(nd, NDF_ONLY_PNBUF); - vp = nd->ni_vp; + vfslocked = NDHASGIANT(&nd); + NDFREE(&nd, NDF_ONLY_PNBUF); + vp = nd.ni_vp; FILE_LOCK(fp); fp->f_vnode = vp; @@ -1154,10 +1120,16 @@ fdrop(fp, td); td->td_retval[0] = indx; return (0); +out: + if (dir_vn) + vrele(dir_vn); + return (error); bad: VFS_UNLOCK_GIANT(vfslocked); fdclose(fdp, fp, indx, td); fdrop(fp, td); + if (dir_vn) + vrele(dir_vn); return (error); } @@ -1505,14 +1477,7 @@ int kern_link(struct thread *td, char *path, char *link, enum uio_seg segflg) { - struct nameidata ndp, ndl; - - bwillwrite(); - NDINIT(&ndp, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, segflg, path, td); - NDINIT(&ndl, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE2, - segflg, link, td); - - return kern_common_link(td, &ndp, &ndl); + return kern_linkat(td, path, link, segflg, AT_FDCWD, AT_FDCWD); } int @@ -1522,6 +1487,10 @@ struct nameidata ndp, ndl; int error; struct vnode *pdir_vn, *ldir_vn; + struct vnode *vp; + struct mount *mp; + int vfslocked; + int lvfslocked; error = kern_get_at(td, olddirfd, &pdir_vn); if (error) @@ -1536,69 +1505,59 @@ NDINIT_AT(&ndl, CREATE, LOCKPARENT | SAVENAME| MPSAFE | AUDITVNODE1, segflg, link, td, ldir_vn); - error = kern_common_link(td, &ndp, &ndl); - if (pdir_vn) - vrele(pdir_vn); - if (ldir_vn) - vrele(ldir_vn); - return (error); -} - -static int -kern_common_link(struct thread *td, struct nameidata *ndp, struct nameidata *ndl) -{ - struct vnode *vp; - struct mount *mp; - int vfslocked; - int lvfslocked; - int error; - bwillwrite(); - if ((error = namei(ndp)) != 0) - return (error); - vfslocked = NDHASGIANT(ndp); - NDFREE(ndp, NDF_ONLY_PNBUF); - vp = ndp->ni_vp; + if ((error = namei(&ndp)) != 0) + goto out; + vfslocked = NDHASGIANT(&ndp); + NDFREE(&ndp, NDF_ONLY_PNBUF); + vp = ndp.ni_vp; if (vp->v_type == VDIR) { vrele(vp); VFS_UNLOCK_GIANT(vfslocked); - return (EPERM); /* POSIX */ + error = EPERM; /* POSIX */ + goto out; } if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { vrele(vp); VFS_UNLOCK_GIANT(vfslocked); - return (error); + goto out; } - if ((error = namei(ndl)) == 0) { - lvfslocked = NDHASGIANT(ndl); - if (ndl->ni_vp != NULL) { - if (ndl->ni_dvp == ndl->ni_vp) - vrele(ndl->ni_dvp); + if ((error = namei(&ndl)) == 0) { + lvfslocked = NDHASGIANT(&ndl); + if (ndl.ni_vp != NULL) { + if (ndl.ni_dvp == ndl.ni_vp) + vrele(ndl.ni_dvp); else - vput(ndl->ni_dvp); - vrele(ndl->ni_vp); + vput(ndl.ni_dvp); + vrele(ndl.ni_vp); error = EEXIST; } else if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td)) == 0) { - VOP_LEASE(ndl->ni_dvp, td, td->td_ucred, LEASE_WRITE); + VOP_LEASE(ndl.ni_dvp, td, td->td_ucred, LEASE_WRITE); VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); error = can_hardlink(vp, td, td->td_ucred); if (error == 0) #ifdef MAC error = mac_check_vnode_link(td->td_ucred, - ndl->ni_dvp, vp, &(ndl->ni_cnd)); + ndl.ni_dvp, vp, &ndl.ni_cnd); if (error == 0) #endif - error = VOP_LINK(ndl->ni_dvp, vp, &(ndl->ni_cnd)); + error = VOP_LINK(ndl.ni_dvp, vp, &ndl.ni_cnd); VOP_UNLOCK(vp, 0, td); - vput(ndl->ni_dvp); + vput(ndl.ni_dvp); } - NDFREE(ndl, NDF_ONLY_PNBUF); + NDFREE(&ndl, NDF_ONLY_PNBUF); VFS_UNLOCK_GIANT(lvfslocked); } vrele(vp); vn_finished_write(mp); VFS_UNLOCK_GIANT(vfslocked); + +out: + if (pdir_vn) + vrele(pdir_vn); + if (ldir_vn) + vrele(ldir_vn); return (error); } @@ -2046,12 +2005,7 @@ int kern_access(struct thread *td, char *path, enum uio_seg pathseg, int flags) { - struct nameidata nd; - - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, - pathseg, path, td); - - return kern_common_access(td, flags, &nd); + return kern_accessat(td, path, pathseg, flags, AT_FDCWD); } int @@ -2060,6 +2014,9 @@ int error; struct nameidata nd; struct vnode *dir_vn; + struct ucred *cred, *tmpcred; + struct vnode *vp; + int vfslocked; error = kern_get_at(td, dirfd, &dir_vn); if (error) @@ -2068,20 +2025,6 @@ NDINIT_AT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, pathseg, path, td, dir_vn); - error = kern_common_access(td, flags, &nd); - if (dir_vn) - vrele(dir_vn); - return (error); -} - -static int -kern_common_access(struct thread *td, int flags, struct nameidata *nd) -{ - struct ucred *cred, *tmpcred; - struct vnode *vp; - int vfslocked; - int error; - /* * Create and modify a temporary credential instead of one that * is potentially shared. This could also mess up socket @@ -2092,18 +2035,20 @@ tmpcred->cr_uid = cred->cr_ruid; tmpcred->cr_groups[0] = cred->cr_rgid; td->td_ucred = tmpcred; - if ((error = namei(nd)) != 0) - goto out1; - vfslocked = NDHASGIANT(nd); - vp = nd->ni_vp; + if ((error = namei(&nd)) != 0) + goto out; + vfslocked = NDHASGIANT(&nd); + vp = nd.ni_vp; error = vn_access(vp, flags, tmpcred, td); - NDFREE(nd, NDF_ONLY_PNBUF); + NDFREE(&nd, NDF_ONLY_PNBUF); vput(vp); VFS_UNLOCK_GIANT(vfslocked); -out1: +out: td->td_ucred = cred; crfree(tmpcred); + if (dir_vn) + vrele(dir_vn); return (error); } @@ -2267,21 +2212,16 @@ int kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp) { - struct nameidata nd; - - NDINIT(&nd, LOOKUP, - FOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE | AUDITVNODE1, - pathseg, path, td); - - return kern_common_stat(td, sbp, &nd); + return kern_statat(td, path, pathseg, sbp, AT_FDCWD); } int kern_statat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp, int dirfd) { - int error; struct nameidata nd; struct vnode *dir_vn; + struct stat sb; + int error, vfslocked; error = kern_get_at(td, dirfd, &dir_vn); if (error) @@ -2290,33 +2230,27 @@ NDINIT_AT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1 | MPSAFE, pathseg, path, td, dir_vn); - error = kern_common_stat(td, sbp, &nd); - if (dir_vn) - vrele(dir_vn); - return (error); -} - -static int -kern_common_stat(struct thread *td, struct stat *sbp, struct nameidata *nd) -{ - struct stat sb; - int error, vfslocked; - - if ((error = namei(nd)) != 0) - return (error); - vfslocked = NDHASGIANT(nd); - error = vn_stat(nd->ni_vp, &sb, td->td_ucred, NOCRED, td); - NDFREE(nd, NDF_ONLY_PNBUF); - vput(nd->ni_vp); + if ((error = namei(&nd)) != 0) + goto out; + vfslocked = NDHASGIANT(&nd); + error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); + NDFREE(&nd, NDF_ONLY_PNBUF); + vput(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); /* dont bother with the path as this is hopefully going away soon */ if (mtx_owned(&Giant)) printf("stat(%d):\n", vfslocked); if (error) - return (error); + goto out; *sbp = sb; - return (0); + + error = 0; +out: + if (dir_vn) + vrele(dir_vn); + return (error); } + /* * Get file status; this version does not follow links. */ @@ -2346,21 +2280,17 @@ int kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp) { - struct nameidata nd; - - NDINIT(&nd, LOOKUP, - NOFOLLOW | LOCKLEAF | LOCKSHARED | MPSAFE | AUDITVNODE1, - pathseg, path, td); - - return kern_common_lstat(td, sbp, &nd); + return kern_lstatat(td, path, pathseg, sbp, AT_FDCWD); } int kern_lstatat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp, int dirfd) { - int error; struct nameidata nd; struct vnode *dir_vn; + struct vnode *vp; + struct stat sb; + int error, vfslocked; error = kern_get_at(td, dirfd, &dir_vn); if (error) @@ -2369,31 +2299,22 @@ NDINIT_AT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKSHARED | AUDITVNODE1 | MPSAFE, pathseg, path, td, dir_vn); - error = kern_common_lstat(td, sbp, &nd); - if (dir_vn) - vrele(dir_vn); - return (error); -} - -static int -kern_common_lstat(struct thread *td, struct stat *sbp, struct nameidata *nd) -{ - struct vnode *vp; - struct stat sb; - int error, vfslocked; - - if ((error = namei(nd)) != 0) - return (error); - vfslocked = NDHASGIANT(nd); - vp = nd->ni_vp; + if ((error = namei(&nd)) != 0) + goto out; + vfslocked = NDHASGIANT(&nd); + vp = nd.ni_vp; error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td); - NDFREE(nd, NDF_ONLY_PNBUF); + NDFREE(&nd, NDF_ONLY_PNBUF); vput(vp); VFS_UNLOCK_GIANT(vfslocked); if (error) - return (error); + goto out; *sbp = sb; - return (0); + error = 0; +out: + if (dir_vn) + vrele(dir_vn); + return (error); } /* @@ -2550,20 +2471,19 @@ kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf, enum uio_seg bufseg, int count) { - struct nameidata nd; - NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, - pathseg, path, td); - - return kern_common_readlink(td, buf, bufseg, count, &nd); + return kern_readlinkat(td, path, pathseg, buf, bufseg, count, AT_FDCWD); } int kern_readlinkat(struct thread *td, char *path, enum uio_seg pathseg, char *buf, enum uio_seg bufseg, int count, int dirfd) { - int error; struct nameidata nd; struct vnode *dir_vn; + struct vnode *vp; + struct iovec aiov; + struct uio auio; + int error, vfslocked; error = kern_get_at(td, dirfd, &dir_vn); if (error) @@ -2572,33 +2492,17 @@ NDINIT_AT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, pathseg, path, td, dir_vn); - error = kern_common_readlink(td, buf, bufseg, count, &nd); - if (dir_vn) - vrele(dir_vn); - return (error); -} - -static int -kern_common_readlink(struct thread *td, char *buf, enum uio_seg bufseg, int count, - struct nameidata *nd) -{ - struct vnode *vp; - struct iovec aiov; - struct uio auio; - int error; - int vfslocked; - - if ((error = namei(nd)) != 0) - return (error); - NDFREE(nd, NDF_ONLY_PNBUF); - vfslocked = NDHASGIANT(nd); - vp = nd->ni_vp; + if ((error = namei(&nd)) != 0) + goto out; + NDFREE(&nd, NDF_ONLY_PNBUF); + vfslocked = NDHASGIANT(&nd); + vp = nd.ni_vp; #ifdef MAC error = mac_check_vnode_readlink(td->td_ucred, vp); if (error) { vput(vp); VFS_UNLOCK_GIANT(vfslocked); - return (error); + goto out; } #endif if (vp->v_type != VLNK) @@ -2618,6 +2522,9 @@ vput(vp); VFS_UNLOCK_GIANT(vfslocked); td->td_retval[0] = count - auio.uio_resid; +out: + if (dir_vn) + vrele(dir_vn); return (error); } @@ -2816,19 +2723,15 @@ int kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode) { - struct nameidata nd; - AUDIT_ARG(mode, mode); - NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); - - return kern_common_chmod(td, mode, &nd); + return kern_chmodat(td, path, pathseg, mode, AT_FDCWD); } int kern_chmodat(struct thread *td, char *path, enum uio_seg pathseg, int mode, int dirfd) { - int error; struct nameidata nd; struct vnode *dir_vn; + int error, vfslocked; error = kern_get_at(td, dirfd, &dir_vn); if (error) @@ -2836,28 +2739,19 @@ NDINIT_AT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td, dir_vn); - error = kern_common_chmod(td, mode, &nd); + if ((error = namei(&nd)) != 0) + goto out; + vfslocked = NDHASGIANT(&nd); + NDFREE(&nd, NDF_ONLY_PNBUF); + error = setfmode(td, nd.ni_vp, mode); + vrele(nd.ni_vp); + VFS_UNLOCK_GIANT(vfslocked); +out: if (dir_vn) vrele(dir_vn); return (error); } -static int -kern_common_chmod(struct thread *td, int mode, struct nameidata *nd) -{ - int error; - int vfslocked; - - if ((error = namei(nd)) != 0) - return (error); - vfslocked = NDHASGIANT(nd); - NDFREE(nd, NDF_ONLY_PNBUF); - error = setfmode(td, nd->ni_vp, mode); - vrele(nd->ni_vp); - VFS_UNLOCK_GIANT(vfslocked); - return (error); -} - /* * Change mode of a file given path name (don't follow links.) */ @@ -2988,21 +2882,16 @@ kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid, int gid) { - struct nameidata nd; - - AUDIT_ARG(owner, uid, gid); - NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); - - return kern_common_chown(td, uid, gid, &nd); + return kern_chownat(td, path, pathseg, uid, gid, AT_FDCWD); } int kern_chownat(struct thread *td, char *path, enum uio_seg pathseg, int uid, int gid, int dirfd) { - int error; struct nameidata nd; struct vnode *dir_vn; + int error, vfslocked; error = kern_get_at(td, dirfd, &dir_vn); if (error) @@ -3010,28 +2899,19 @@ NDINIT_AT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td, dir_vn); - error = kern_common_chown(td, uid, gid, &nd); + if ((error = namei(&nd)) != 0) + goto out; + vfslocked = NDHASGIANT(&nd); + NDFREE(&nd, NDF_ONLY_PNBUF); + error = setfown(td, nd.ni_vp, uid, gid); + vrele(nd.ni_vp); + VFS_UNLOCK_GIANT(vfslocked); +out: if (dir_vn) vrele(dir_vn); return (error); } -static int -kern_common_chown(struct thread *td, int uid, int gid, struct nameidata *nd) -{ - int error; - int vfslocked; - - if ((error = namei(nd)) != 0) - return (error); - vfslocked = NDHASGIANT(nd); - NDFREE(nd, NDF_ONLY_PNBUF); - error = setfown(td, nd->ni_vp, uid, gid); - vrele(nd->ni_vp); - VFS_UNLOCK_GIANT(vfslocked); - return (error); -} - /* * Set ownership given a path name, do not cross symlinks. */ @@ -3059,21 +2939,16 @@ kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid, int gid) { - struct nameidata nd; - - AUDIT_ARG(owner, uid, gid); - NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); - - return kern_common_lchown(td, uid, gid, &nd); + return kern_lchownat(td, path, pathseg, uid, gid, AT_FDCWD); } int kern_lchownat(struct thread *td, char *path, enum uio_seg pathseg, int uid, int gid, int dirfd) { - int error; struct nameidata nd; struct vnode *dir_vn; + int error, vfslocked; error = kern_get_at(td, dirfd, &dir_vn); if (error) @@ -3081,27 +2956,17 @@ NDINIT_AT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td, dir_vn); - error = kern_common_chown(td, uid, gid, &nd); + if ((error = namei(&nd)) != 0) + goto out; + vfslocked = NDHASGIANT(&nd); + NDFREE(&nd, NDF_ONLY_PNBUF); + error = setfown(td, nd.ni_vp, uid, gid); + vrele(nd.ni_vp); + VFS_UNLOCK_GIANT(vfslocked); +out: if (dir_vn) vrele(dir_vn); return (error); - -} - -static int -kern_common_lchown(struct thread *td, int uid, int gid, struct nameidata *nd) -{ - int error; - int vfslocked; - - if ((error = namei(nd)) != 0) - return (error); - vfslocked = NDHASGIANT(nd); - NDFREE(nd, NDF_ONLY_PNBUF); - error = setfown(td, nd->ni_vp, uid, gid); - vrele(nd->ni_vp); - VFS_UNLOCK_GIANT(vfslocked); - return (error); } /* @@ -3247,20 +3112,17 @@ kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg) { - struct nameidata nd; - - NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); - - return kern_common_utimes(td, path, pathseg, tptr, tptrseg, &nd); + return kern_utimesat(td, path, pathseg, tptr, tptrseg, AT_FDCWD); } int kern_utimesat(struct thread *td, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg, int dirfd) { - int error; struct nameidata nd; struct vnode *dir_vn; + struct timespec ts[2]; + int error, vfslocked; error = kern_get_at(td, dirfd, &dir_vn); if (error) @@ -3268,32 +3130,21 @@ NDINIT_AT(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | MPSAFE, pathseg, path, td, dir_vn); - error = kern_common_utimes(td, path, pathseg, tptr, tptrseg, &nd); + if ((error = getutimes(tptr, tptrseg, ts)) != 0) + goto out; + if ((error = namei(&nd)) != 0) + goto out; + vfslocked = NDHASGIANT(&nd); + NDFREE(&nd, NDF_ONLY_PNBUF); + error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); + vrele(nd.ni_vp); + VFS_UNLOCK_GIANT(vfslocked); +out: if (dir_vn) vrele(dir_vn); return (error); } -static int -kern_common_utimes(struct thread *td, char *path, enum uio_seg pathseg, - struct timeval *tptr, enum uio_seg tptrseg, struct nameidata *nd) -{ - struct timespec ts[2]; - int error; - int vfslocked; - - if ((error = getutimes(tptr, tptrseg, ts)) != 0) - return (error); - if ((error = namei(nd)) != 0) - return (error); - vfslocked = NDHASGIANT(nd); - NDFREE(nd, NDF_ONLY_PNBUF); - error = setutimes(td, nd->ni_vp, ts, 2, tptr == NULL); - vrele(nd->ni_vp); - VFS_UNLOCK_GIANT(vfslocked); - return (error); -} - /* * Set the access and modification times of a file. */ @@ -3641,19 +3492,7 @@ int kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) { - struct nameidata fromnd, tond; - -#ifdef MAC - NDINIT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE | - AUDITVNODE1, pathseg, from, td); -#else - NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART | MPSAFE | - AUDITVNODE1, pathseg, from, td); -#endif - NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | - MPSAFE | AUDITVNODE2, pathseg, to, td); - - return kern_common_rename(td, from, to, pathseg, &fromnd, &tond); + return kern_renameat(td, from, to, pathseg, AT_FDCWD, AT_FDCWD); } int @@ -3661,6 +3500,10 @@ { struct nameidata fromnd, tond; struct vnode *fdir_vn, *tdir_vn; + struct mount *mp = NULL; + struct vnode *tvp, *fvp, *tdvp; + int tvfslocked; + int fvfslocked; int error; error = kern_get_at(td, fdirfd, &fdir_vn); @@ -3680,62 +3523,42 @@ NDINIT_AT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | MPSAFE | AUDITVNODE2, pathseg, to, td, tdir_vn); - error = kern_common_rename(td, from, to, pathseg, &fromnd, &tond); - - if (fdir_vn) - vrele(fdir_vn); - if (tdir_vn) - vrele(tdir_vn); - - return (error); -} - -static int -kern_common_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg, - struct nameidata *fromnd, struct nameidata *tond) -{ - struct mount *mp = NULL; - struct vnode *tvp, *fvp, *tdvp; - int tvfslocked; - int fvfslocked; - int error; - bwillwrite(); - if ((error = namei(fromnd)) != 0) - return (error); - fvfslocked = NDHASGIANT(fromnd); + if ((error = namei(&fromnd)) != 0) + goto out2; + fvfslocked = NDHASGIANT(&fromnd); tvfslocked = 0; #ifdef MAC - error = mac_check_vnode_rename_from(td->td_ucred, fromnd->ni_dvp, - fromnd->ni_vp, &(fromnd->ni_cnd)); - VOP_UNLOCK(fromnd->ni_dvp, 0, td); - if (fromnd->ni_dvp != fromnd->ni_vp) - VOP_UNLOCK(fromnd->ni_vp, 0, td); + error = mac_check_vnode_rename_from(td->td_ucred, fromnd.ni_dvp, + fromnd.ni_vp, &fromnd.ni_cnd); + VOP_UNLOCK(fromnd.ni_dvp, 0, td); + if (fromnd.ni_dvp != fromnd.ni_vp) + VOP_UNLOCK(fromnd.ni_vp, 0, td); #endif - fvp = fromnd->ni_vp; + fvp = fromnd.ni_vp; if (error == 0) error = vn_start_write(fvp, &mp, V_WAIT | PCATCH); if (error != 0) { - NDFREE(fromnd, NDF_ONLY_PNBUF); - vrele(fromnd->ni_dvp); + NDFREE(&fromnd, NDF_ONLY_PNBUF); + vrele(fromnd.ni_dvp); vrele(fvp); goto out1; } - if (fromnd->ni_vp->v_type == VDIR) - tond->ni_cnd.cn_flags |= WILLBEDIR; - if ((error = namei(tond)) != 0) { + if (fromnd.ni_vp->v_type == VDIR) + tond.ni_cnd.cn_flags |= WILLBEDIR; + if ((error = namei(&tond)) != 0) { /* Translate error code for rename("dir1", "dir2/."). */ if (error == EISDIR && fvp->v_type == VDIR) error = EINVAL; - NDFREE(fromnd, NDF_ONLY_PNBUF); - vrele(fromnd->ni_dvp); + NDFREE(&fromnd, NDF_ONLY_PNBUF); + vrele(fromnd.ni_dvp); vrele(fvp); vn_finished_write(mp); goto out1; } - tvfslocked = NDHASGIANT(tond); - tdvp = tond->ni_dvp; - tvp = tond->ni_vp; + tvfslocked = NDHASGIANT(&tond); + tdvp = tond.ni_dvp; + tvp = tond.ni_vp; if (tvp != NULL) { if (fvp->v_type == VDIR && tvp->v_type != VDIR) { error = ENOTDIR; @@ -3756,42 +3579,48 @@ #ifdef MAC else error = mac_check_vnode_rename_to(td->td_ucred, tdvp, - tond->ni_vp, fromnd->ni_dvp == tdvp, &(tond->ni_cnd)); + tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); #endif out: if (!error) { VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE); - if (fromnd->ni_dvp != tdvp) { - VOP_LEASE(fromnd->ni_dvp, td, td->td_ucred, LEASE_WRITE); + if (fromnd.ni_dvp != tdvp) { + VOP_LEASE(fromnd.ni_dvp, td, td->td_ucred, LEASE_WRITE); } if (tvp) { VOP_LEASE(tvp, td, td->td_ucred, LEASE_WRITE); } - error = VOP_RENAME(fromnd->ni_dvp, fromnd->ni_vp, &(fromnd->ni_cnd), - tond->ni_dvp, tond->ni_vp, &(tond->ni_cnd)); - NDFREE(fromnd, NDF_ONLY_PNBUF); - NDFREE(tond, NDF_ONLY_PNBUF); + error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, + tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); + NDFREE(&fromnd, NDF_ONLY_PNBUF); + NDFREE(&tond, NDF_ONLY_PNBUF); } else { - NDFREE(fromnd, NDF_ONLY_PNBUF); - NDFREE(tond, NDF_ONLY_PNBUF); + NDFREE(&fromnd, NDF_ONLY_PNBUF); + NDFREE(&tond, NDF_ONLY_PNBUF); if (tvp) vput(tvp); if (tdvp == tvp) vrele(tdvp); else vput(tdvp); - vrele(fromnd->ni_dvp); + vrele(fromnd.ni_dvp); vrele(fvp); } >>> TRUNCATED FOR MAIL (1000 lines) <<<