PERFORCE change 121263 for review
Roman Divacky
rdivacky at FreeBSD.org
Sat Jun 9 10:32:00 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=121263
Change 121263 by rdivacky at 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" <eric.lemar at isilon.com>
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) <<<
More information about the p4-projects
mailing list