use vn_close rather than vrele after vn_open
[unix-history] / usr / src / sys / kern / vfs_syscalls.c
index 04d89bd..61920f5 100644 (file)
@@ -2,24 +2,15 @@
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * %sccs.include.redist.c%
  *
  *
- *     @(#)vfs_syscalls.c      7.53 (Berkeley) %G%
+ *     @(#)vfs_syscalls.c      7.74 (Berkeley) %G%
  */
 
 #include "param.h"
 #include "systm.h"
  */
 
 #include "param.h"
 #include "systm.h"
-#include "syscontext.h"
+#include "namei.h"
+#include "filedesc.h"
 #include "kernel.h"
 #include "file.h"
 #include "stat.h"
 #include "kernel.h"
 #include "file.h"
 #include "stat.h"
 #include "uio.h"
 #include "malloc.h"
 
 #include "uio.h"
 #include "malloc.h"
 
-#define        p_devtmp        p_logname[11]
-
-#undef RETURN
-#define RETURN(val)    { u.u_error = (val); if (u.u_spare[0] != 0) panic("lock count"); return (u.u_error); }
-
 /*
  * Virtual File System System Calls
  */
 
 /*
 /*
  * Virtual File System System Calls
  */
 
 /*
- * mount system call
+ * Mount system call.
  */
 /* ARGSUSED */
 mount(p, uap, retval)
  */
 /* ARGSUSED */
 mount(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                int     type;
                char    *dir;
        register struct args {
                int     type;
                char    *dir;
@@ -52,29 +38,31 @@ mount(p, uap, retval)
        } *uap;
        int *retval;
 {
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        register struct vnode *vp;
        register struct mount *mp;
        int error, flag;
        register struct vnode *vp;
        register struct mount *mp;
        int error, flag;
+       struct nameidata nd;
 
        /*
         * Must be super user
         */
 
        /*
         * Must be super user
         */
-       if (error = suser(ndp->ni_cred, &u.u_acflag))
-               RETURN (error);
+       if (error = suser(p->p_ucred, &p->p_acflag))
+               return (error);
        /*
         * Get vnode to be covered
         */
        /*
         * Get vnode to be covered
         */
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->dir;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->dir;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        vp = ndp->ni_vp;
        if (uap->flags & MNT_UPDATE) {
                if ((vp->v_flag & VROOT) == 0) {
                        vput(vp);
        vp = ndp->ni_vp;
        if (uap->flags & MNT_UPDATE) {
                if ((vp->v_flag & VROOT) == 0) {
                        vput(vp);
-                       RETURN (EINVAL);
+                       return (EINVAL);
                }
                mp = vp->v_mount;
                /*
                }
                mp = vp->v_mount;
                /*
@@ -84,7 +72,7 @@ mount(p, uap, retval)
                if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
                    (uap->flags & MNT_RDONLY) != 0) {
                        vput(vp);
                if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
                    (uap->flags & MNT_RDONLY) != 0) {
                        vput(vp);
-                       RETURN (EOPNOTSUPP);    /* Needs translation */
+                       return (EOPNOTSUPP);    /* Needs translation */
                }
                flag = mp->mnt_flag;
                mp->mnt_flag |= MNT_UPDATE;
                }
                flag = mp->mnt_flag;
                mp->mnt_flag |= MNT_UPDATE;
@@ -94,16 +82,16 @@ mount(p, uap, retval)
        vinvalbuf(vp, 1);
        if (vp->v_usecount != 1) {
                vput(vp);
        vinvalbuf(vp, 1);
        if (vp->v_usecount != 1) {
                vput(vp);
-               RETURN (EBUSY);
+               return (EBUSY);
        }
        if (vp->v_type != VDIR) {
                vput(vp);
        }
        if (vp->v_type != VDIR) {
                vput(vp);
-               RETURN (ENOTDIR);
+               return (ENOTDIR);
        }
        if ((unsigned long)uap->type > MOUNT_MAXTYPE ||
            vfssw[uap->type] == (struct vfsops *)0) {
                vput(vp);
        }
        if ((unsigned long)uap->type > MOUNT_MAXTYPE ||
            vfssw[uap->type] == (struct vfsops *)0) {
                vput(vp);
-               RETURN (ENODEV);
+               return (ENODEV);
        }
 
        /*
        }
 
        /*
@@ -118,13 +106,13 @@ mount(p, uap, retval)
        if (error = vfs_lock(mp)) {
                free((caddr_t)mp, M_MOUNT);
                vput(vp);
        if (error = vfs_lock(mp)) {
                free((caddr_t)mp, M_MOUNT);
                vput(vp);
-               RETURN (error);
+               return (error);
        }
        if (vp->v_mountedhere != (struct mount *)0) {
                vfs_unlock(mp);
                free((caddr_t)mp, M_MOUNT);
                vput(vp);
        }
        if (vp->v_mountedhere != (struct mount *)0) {
                vfs_unlock(mp);
                free((caddr_t)mp, M_MOUNT);
                vput(vp);
-               RETURN (EBUSY);
+               return (EBUSY);
        }
        vp->v_mountedhere = mp;
        mp->mnt_vnodecovered = vp;
        }
        vp->v_mountedhere = mp;
        mp->mnt_vnodecovered = vp;
@@ -155,13 +143,13 @@ update:
        /*
         * Mount the filesystem.
         */
        /*
         * Mount the filesystem.
         */
-       error = VFS_MOUNT(mp, uap->dir, uap->data, ndp);
+       error = VFS_MOUNT(mp, uap->dir, uap->data, ndp, p);
        if (mp->mnt_flag & MNT_UPDATE) {
                mp->mnt_flag &= ~MNT_UPDATE;
                vrele(vp);
                if (error)
                        mp->mnt_flag = flag;
        if (mp->mnt_flag & MNT_UPDATE) {
                mp->mnt_flag &= ~MNT_UPDATE;
                vrele(vp);
                if (error)
                        mp->mnt_flag = flag;
-               RETURN (error);
+               return (error);
        }
        /*
         * Put the new filesystem on the mount list after root.
        }
        /*
         * Put the new filesystem on the mount list after root.
@@ -174,13 +162,13 @@ update:
        if (!error) {
                VOP_UNLOCK(vp);
                vfs_unlock(mp);
        if (!error) {
                VOP_UNLOCK(vp);
                vfs_unlock(mp);
-               error = VFS_START(mp, 0);
+               error = VFS_START(mp, 0, p);
        } else {
                vfs_remove(mp);
                free((caddr_t)mp, M_MOUNT);
                vput(vp);
        }
        } else {
                vfs_remove(mp);
                free((caddr_t)mp, M_MOUNT);
                vput(vp);
        }
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -191,7 +179,7 @@ update:
  */
 /* ARGSUSED */
 unmount(p, uap, retval)
  */
 /* ARGSUSED */
 unmount(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *pathp;
                int     flags;
        register struct args {
                char    *pathp;
                int     flags;
@@ -199,40 +187,43 @@ unmount(p, uap, retval)
        int *retval;
 {
        register struct vnode *vp;
        int *retval;
 {
        register struct vnode *vp;
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        struct mount *mp;
        int error;
        struct mount *mp;
        int error;
+       struct nameidata nd;
 
        /*
         * Must be super user
         */
 
        /*
         * Must be super user
         */
-       if (error = suser(ndp->ni_cred, &u.u_acflag))
-               RETURN (error);
+       if (error = suser(p->p_ucred, &p->p_acflag))
+               return (error);
 
 
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->pathp;
        ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->pathp;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        vp = ndp->ni_vp;
        /*
         * Must be the root of the filesystem
         */
        if ((vp->v_flag & VROOT) == 0) {
                vput(vp);
        vp = ndp->ni_vp;
        /*
         * Must be the root of the filesystem
         */
        if ((vp->v_flag & VROOT) == 0) {
                vput(vp);
-               RETURN (EINVAL);
+               return (EINVAL);
        }
        mp = vp->v_mount;
        vput(vp);
        }
        mp = vp->v_mount;
        vput(vp);
-       RETURN (dounmount(mp, uap->flags));
+       return (dounmount(mp, uap->flags, p));
 }
 
 /*
  * Do an unmount.
  */
 }
 
 /*
  * Do an unmount.
  */
-dounmount(mp, flags)
+dounmount(mp, flags, p)
        register struct mount *mp;
        int flags;
        register struct mount *mp;
        int flags;
+       struct proc *p;
 {
        struct vnode *coveredvp;
        int error;
 {
        struct vnode *coveredvp;
        int error;
@@ -244,10 +235,10 @@ dounmount(mp, flags)
        if (error = vfs_lock(mp))
                return (error);
 
        if (error = vfs_lock(mp))
                return (error);
 
-       xumount(mp);            /* remove unused sticky files from text table */
+       vnode_pager_umount(mp); /* release cached vnodes */
        cache_purgevfs(mp);     /* remove cache entries for this file sys */
        if ((error = VFS_SYNC(mp, MNT_WAIT)) == 0 || (flags & MNT_FORCE))
        cache_purgevfs(mp);     /* remove cache entries for this file sys */
        if ((error = VFS_SYNC(mp, MNT_WAIT)) == 0 || (flags & MNT_FORCE))
-               error = VFS_UNMOUNT(mp, flags);
+               error = VFS_UNMOUNT(mp, flags, p);
        mp->mnt_flag &= ~MNT_UNMOUNT;
        vfs_unbusy(mp);
        if (error) {
        mp->mnt_flag &= ~MNT_UNMOUNT;
        vfs_unbusy(mp);
        if (error) {
@@ -266,8 +257,8 @@ dounmount(mp, flags)
  */
 /* ARGSUSED */
 sync(p, uap, retval)
  */
 /* ARGSUSED */
 sync(p, uap, retval)
-       register struct proc *p;
-       struct args *uap;
+       struct proc *p;
+       void *uap;
        int *retval;
 {
        register struct mount *mp;
        int *retval;
 {
        register struct mount *mp;
@@ -288,14 +279,15 @@ sync(p, uap, retval)
                } else
                        mp = mp->mnt_next;
        } while (mp != rootfs);
                } else
                        mp = mp->mnt_next;
        } while (mp != rootfs);
+       return (0);
 }
 
 /*
 }
 
 /*
- * operate on filesystem quotas
+ * Operate on filesystem quotas.
  */
 /* ARGSUSED */
 quotactl(p, uap, retval)
  */
 /* ARGSUSED */
 quotactl(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char *path;
                int cmd;
        register struct args {
                char *path;
                int cmd;
@@ -305,25 +297,27 @@ quotactl(p, uap, retval)
        int *retval;
 {
        register struct mount *mp;
        int *retval;
 {
        register struct mount *mp;
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        int error;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | FOLLOW;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->path;
        ndp->ni_nameiop = LOOKUP | FOLLOW;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->path;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        mp = ndp->ni_vp->v_mount;
        vrele(ndp->ni_vp);
        mp = ndp->ni_vp->v_mount;
        vrele(ndp->ni_vp);
-       RETURN (VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg));
+       return (VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg, p));
 }
 
 /*
 }
 
 /*
- * get filesystem statistics
+ * Get filesystem statistics.
  */
 /* ARGSUSED */
 statfs(p, uap, retval)
  */
 /* ARGSUSED */
 statfs(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char *path;
                struct statfs *buf;
        register struct args {
                char *path;
                struct statfs *buf;
@@ -331,30 +325,32 @@ statfs(p, uap, retval)
        int *retval;
 {
        register struct mount *mp;
        int *retval;
 {
        register struct mount *mp;
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        register struct statfs *sp;
        int error;
        register struct statfs *sp;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | FOLLOW;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->path;
        ndp->ni_nameiop = LOOKUP | FOLLOW;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->path;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        mp = ndp->ni_vp->v_mount;
        sp = &mp->mnt_stat;
        vrele(ndp->ni_vp);
        mp = ndp->ni_vp->v_mount;
        sp = &mp->mnt_stat;
        vrele(ndp->ni_vp);
-       if (error = VFS_STATFS(mp, sp))
-               RETURN (error);
+       if (error = VFS_STATFS(mp, sp, p))
+               return (error);
        sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
        sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
-       RETURN (copyout((caddr_t)sp, (caddr_t)uap->buf, sizeof(*sp)));
+       return (copyout((caddr_t)sp, (caddr_t)uap->buf, sizeof(*sp)));
 }
 
 /*
 }
 
 /*
- * get filesystem statistics
+ * Get filesystem statistics.
  */
 /* ARGSUSED */
 fstatfs(p, uap, retval)
  */
 /* ARGSUSED */
 fstatfs(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                int fd;
                struct statfs *buf;
        register struct args {
                int fd;
                struct statfs *buf;
@@ -366,21 +362,21 @@ fstatfs(p, uap, retval)
        register struct statfs *sp;
        int error;
 
        register struct statfs *sp;
        int error;
 
-       if (error = getvnode(u.u_ofile, uap->fd, &fp))
-               RETURN (error);
+       if (error = getvnode(p->p_fd, uap->fd, &fp))
+               return (error);
        mp = ((struct vnode *)fp->f_data)->v_mount;
        sp = &mp->mnt_stat;
        mp = ((struct vnode *)fp->f_data)->v_mount;
        sp = &mp->mnt_stat;
-       if (error = VFS_STATFS(mp, sp))
-               RETURN (error);
+       if (error = VFS_STATFS(mp, sp, p))
+               return (error);
        sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
        sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
-       RETURN (copyout((caddr_t)sp, (caddr_t)uap->buf, sizeof(*sp)));
+       return (copyout((caddr_t)sp, (caddr_t)uap->buf, sizeof(*sp)));
 }
 
 /*
 }
 
 /*
- * get statistics on all filesystems
+ * Get statistics on all filesystems.
  */
 getfsstat(p, uap, retval)
  */
 getfsstat(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                struct statfs *buf;
                long bufsize;
        register struct args {
                struct statfs *buf;
                long bufsize;
@@ -407,13 +403,13 @@ getfsstat(p, uap, retval)
                         */
                        if (((uap->flags & MNT_NOWAIT) == 0 ||
                            (uap->flags & MNT_WAIT)) &&
                         */
                        if (((uap->flags & MNT_NOWAIT) == 0 ||
                            (uap->flags & MNT_WAIT)) &&
-                           (error = VFS_STATFS(mp, sp))) {
+                           (error = VFS_STATFS(mp, sp, p))) {
                                mp = mp->mnt_prev;
                                continue;
                        }
                        sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
                        if (error = copyout((caddr_t)sp, sfsp, sizeof(*sp)))
                                mp = mp->mnt_prev;
                                continue;
                        }
                        sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
                        if (error = copyout((caddr_t)sp, sfsp, sizeof(*sp)))
-                               RETURN (error);
+                               return (error);
                        sfsp += sizeof(*sp);
                }
                count++;
                        sfsp += sizeof(*sp);
                }
                count++;
@@ -423,7 +419,7 @@ getfsstat(p, uap, retval)
                *retval = maxcount;
        else
                *retval = count;
                *retval = maxcount;
        else
                *retval = count;
-       RETURN (0);
+       return (0);
 }
 
 /*
 }
 
 /*
@@ -431,32 +427,32 @@ getfsstat(p, uap, retval)
  */
 /* ARGSUSED */
 fchdir(p, uap, retval)
  */
 /* ARGSUSED */
 fchdir(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        struct args {
                int     fd;
        } *uap;
        int *retval;
 {
        struct args {
                int     fd;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct filedesc *fdp = p->p_fd;
        register struct vnode *vp;
        struct file *fp;
        int error;
 
        register struct vnode *vp;
        struct file *fp;
        int error;
 
-       if (error = getvnode(u.u_ofile, uap->fd, &fp))
-               RETURN (error);
+       if (error = getvnode(fdp, uap->fd, &fp))
+               return (error);
        vp = (struct vnode *)fp->f_data;
        VOP_LOCK(vp);
        if (vp->v_type != VDIR)
                error = ENOTDIR;
        else
        vp = (struct vnode *)fp->f_data;
        VOP_LOCK(vp);
        if (vp->v_type != VDIR)
                error = ENOTDIR;
        else
-               error = VOP_ACCESS(vp, VEXEC, ndp->ni_cred);
+               error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
        VOP_UNLOCK(vp);
        if (error)
        VOP_UNLOCK(vp);
        if (error)
-               RETURN (error);
+               return (error);
        VREF(vp);
        VREF(vp);
-       vrele(ndp->ni_cdir);
-       ndp->ni_cdir = vp;
-       RETURN (0);
+       vrele(fdp->fd_cdir);
+       fdp->fd_cdir = vp;
+       return (0);
 }
 
 /*
 }
 
 /*
@@ -464,23 +460,26 @@ fchdir(p, uap, retval)
  */
 /* ARGSUSED */
 chdir(p, uap, retval)
  */
 /* ARGSUSED */
 chdir(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        struct args {
                char    *fname;
        } *uap;
        int *retval;
 {
        struct args {
                char    *fname;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
+       register struct filedesc *fdp = p->p_fd;
        int error;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       if (error = chdirec(ndp))
-               RETURN (error);
-       vrele(ndp->ni_cdir);
-       ndp->ni_cdir = ndp->ni_vp;
-       RETURN (0);
+       if (error = chdirec(ndp, p))
+               return (error);
+       vrele(fdp->fd_cdir);
+       fdp->fd_cdir = ndp->ni_vp;
+       return (0);
 }
 
 /*
 }
 
 /*
@@ -488,44 +487,48 @@ chdir(p, uap, retval)
  */
 /* ARGSUSED */
 chroot(p, uap, retval)
  */
 /* ARGSUSED */
 chroot(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        struct args {
                char    *fname;
        } *uap;
        int *retval;
 {
        struct args {
                char    *fname;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
+       register struct filedesc *fdp = p->p_fd;
        int error;
        int error;
+       struct nameidata nd;
 
 
-       if (error = suser(ndp->ni_cred, &u.u_acflag))
-               RETURN (error);
+       if (error = suser(p->p_ucred, &p->p_acflag))
+               return (error);
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       if (error = chdirec(ndp))
-               RETURN (error);
-       if (ndp->ni_rdir != NULL)
-               vrele(ndp->ni_rdir);
-       ndp->ni_rdir = ndp->ni_vp;
-       RETURN (0);
+       if (error = chdirec(ndp, p))
+               return (error);
+       if (fdp->fd_rdir != NULL)
+               vrele(fdp->fd_rdir);
+       fdp->fd_rdir = ndp->ni_vp;
+       return (0);
 }
 
 /*
  * Common routine for chroot and chdir.
  */
 }
 
 /*
  * Common routine for chroot and chdir.
  */
-chdirec(ndp)
-       register struct nameidata *ndp;
+chdirec(ndp, p)
+       struct nameidata *ndp;
+       struct proc *p;
 {
        struct vnode *vp;
        int error;
 
 {
        struct vnode *vp;
        int error;
 
-       if (error = namei(ndp))
+       if (error = namei(ndp, p))
                return (error);
        vp = ndp->ni_vp;
        if (vp->v_type != VDIR)
                error = ENOTDIR;
        else
                return (error);
        vp = ndp->ni_vp;
        if (vp->v_type != VDIR)
                error = ENOTDIR;
        else
-               error = VOP_ACCESS(vp, VEXEC, ndp->ni_cred);
+               error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
        VOP_UNLOCK(vp);
        if (error)
                vrele(vp);
        VOP_UNLOCK(vp);
        if (error)
                vrele(vp);
@@ -538,7 +541,7 @@ chdirec(ndp)
  * and call the device open routine if any.
  */
 open(p, uap, retval)
  * and call the device open routine if any.
  */
 open(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *fname;
                int     mode;
        register struct args {
                char    *fname;
                int     mode;
@@ -546,41 +549,67 @@ open(p, uap, retval)
        } *uap;
        int *retval;
 {
        } *uap;
        int *retval;
 {
-       struct nameidata *ndp = &u.u_nd;
+       struct nameidata *ndp;
+       register struct filedesc *fdp = p->p_fd;
        register struct file *fp;
        register struct file *fp;
+       register struct vnode *vp;
        int fmode, cmode;
        struct file *nfp;
        int fmode, cmode;
        struct file *nfp;
-       int indx, error;
+       int type, indx, error;
+       struct flock lf;
+       struct nameidata nd;
        extern struct fileops vnops;
 
        extern struct fileops vnops;
 
-       if (error = falloc(&nfp, &indx))
-               RETURN (error);
+       if (error = falloc(p, &nfp, &indx))
+               return (error);
        fp = nfp;
        fp = nfp;
-       fmode = uap->mode - FOPEN;
-       cmode = ((uap->crtmode &~ u.u_cmask) & 07777) &~ S_ISVTX;
+       fmode = FFLAGS(uap->mode);
+       cmode = ((uap->crtmode &~ fdp->fd_cmask) & 07777) &~ S_ISVTX;
+       ndp = &nd;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       p->p_devtmp = -1;                       /* XXX check for fdopen */
-       if (error = vn_open(ndp, fmode, cmode)) {
-               crfree(fp->f_cred);
-               fp->f_count--;
+       p->p_dupfd = -indx - 1;                 /* XXX check for fdopen */
+       if (error = vn_open(ndp, p, fmode, cmode)) {
+               ffree(fp);
                if (error == ENODEV &&          /* XXX from fdopen */
                if (error == ENODEV &&          /* XXX from fdopen */
-                   p->p_devtmp >= 0 &&
-                   (error = dupfdopen(indx, p->p_devtmp, fmode)) == 0) {
+                   p->p_dupfd >= 0 &&
+                   (error = dupfdopen(fdp, indx, p->p_dupfd, fmode)) == 0) {
                        *retval = indx;
                        *retval = indx;
-                       RETURN (0);
+                       return (0);
                }
                if (error == ERESTART)
                        error = EINTR;
                }
                if (error == ERESTART)
                        error = EINTR;
-               u.u_ofile[indx] = NULL;
-               RETURN (error);
+               fdp->fd_ofiles[indx] = NULL;
+               return (error);
        }
        }
+       vp = ndp->ni_vp;
        fp->f_flag = fmode & FMASK;
        fp->f_flag = fmode & FMASK;
+       if (fmode & (O_EXLOCK | O_SHLOCK)) {
+               lf.l_whence = SEEK_SET;
+               lf.l_start = 0;
+               lf.l_len = 0;
+               if (fmode & O_EXLOCK)
+                       lf.l_type = F_WRLCK;
+               else
+                       lf.l_type = F_RDLCK;
+               type = F_FLOCK;
+               if ((fmode & FNONBLOCK) == 0)
+                       type |= F_WAIT;
+               if (error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) {
+                       VOP_UNLOCK(vp);
+                       (void) vn_close(vp, fp->f_flag, fp->f_cred, p);
+                       ffree(fp);
+                       fdp->fd_ofiles[indx] = NULL;
+                       return (error);
+               }
+               fp->f_flag |= FHASLOCK;
+       }
+       VOP_UNLOCK(vp);
        fp->f_type = DTYPE_VNODE;
        fp->f_ops = &vnops;
        fp->f_type = DTYPE_VNODE;
        fp->f_ops = &vnops;
-       fp->f_data = (caddr_t)ndp->ni_vp;
+       fp->f_data = (caddr_t)vp;
        *retval = indx;
        *retval = indx;
-       RETURN (0);
+       return (0);
 }
 
 #ifdef COMPAT_43
 }
 
 #ifdef COMPAT_43
@@ -604,16 +633,16 @@ ocreat(p, uap, retval)
        openuap.fname = uap->fname;
        openuap.crtmode = uap->fmode;
        openuap.mode = O_WRONLY | O_CREAT | O_TRUNC;
        openuap.fname = uap->fname;
        openuap.crtmode = uap->fmode;
        openuap.mode = O_WRONLY | O_CREAT | O_TRUNC;
-       RETURN (open(p, &openuap, retval));
+       return (open(p, &openuap, retval));
 }
 #endif /* COMPAT_43 */
 
 /*
 }
 #endif /* COMPAT_43 */
 
 /*
- * Mknod system call
+ * Mknod system call.
  */
 /* ARGSUSED */
 mknod(p, uap, retval)
  */
 /* ARGSUSED */
 mknod(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *fname;
                int     fmode;
        register struct args {
                char    *fname;
                int     fmode;
@@ -621,18 +650,20 @@ mknod(p, uap, retval)
        } *uap;
        int *retval;
 {
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        register struct vnode *vp;
        struct vattr vattr;
        int error;
        register struct vnode *vp;
        struct vattr vattr;
        int error;
+       struct nameidata nd;
 
 
-       if (error = suser(ndp->ni_cred, &u.u_acflag))
-               RETURN (error);
+       if (error = suser(p->p_ucred, &p->p_acflag))
+               return (error);
+       ndp = &nd;
        ndp->ni_nameiop = CREATE | LOCKPARENT;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_nameiop = CREATE | LOCKPARENT;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        vp = ndp->ni_vp;
        if (vp != NULL) {
                error = EEXIST;
        vp = ndp->ni_vp;
        if (vp != NULL) {
                error = EEXIST;
@@ -654,11 +685,11 @@ mknod(p, uap, retval)
                error = EINVAL;
                goto out;
        }
                error = EINVAL;
                goto out;
        }
-       vattr.va_mode = (uap->fmode & 07777) &~ u.u_cmask;
+       vattr.va_mode = (uap->fmode & 07777) &~ p->p_fd->fd_cmask;
        vattr.va_rdev = uap->dev;
 out:
        if (!error) {
        vattr.va_rdev = uap->dev;
 out:
        if (!error) {
-               error = VOP_MKNOD(ndp, &vattr, ndp->ni_cred);
+               error = VOP_MKNOD(ndp, &vattr, p->p_ucred, p);
        } else {
                VOP_ABORTOP(ndp);
                if (ndp->ni_dvp == vp)
        } else {
                VOP_ABORTOP(ndp);
                if (ndp->ni_dvp == vp)
@@ -668,33 +699,35 @@ out:
                if (vp)
                        vrele(vp);
        }
                if (vp)
                        vrele(vp);
        }
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
- * Mkfifo system call
+ * Mkfifo system call.
  */
 /* ARGSUSED */
 mkfifo(p, uap, retval)
  */
 /* ARGSUSED */
 mkfifo(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *fname;
                int     fmode;
        } *uap;
        int *retval;
 {
        register struct args {
                char    *fname;
                int     fmode;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        struct vattr vattr;
        int error;
        struct vattr vattr;
        int error;
+       struct nameidata nd;
 
 #ifndef FIFO
 
 #ifndef FIFO
-       RETURN (EOPNOTSUPP);
+       return (EOPNOTSUPP);
 #else
 #else
+       ndp = &nd;
        ndp->ni_nameiop = CREATE | LOCKPARENT;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_nameiop = CREATE | LOCKPARENT;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        if (ndp->ni_vp != NULL) {
                VOP_ABORTOP(ndp);
                if (ndp->ni_dvp == ndp->ni_vp)
        if (ndp->ni_vp != NULL) {
                VOP_ABORTOP(ndp);
                if (ndp->ni_dvp == ndp->ni_vp)
@@ -702,44 +735,45 @@ mkfifo(p, uap, retval)
                else
                        vput(ndp->ni_dvp);
                vrele(ndp->ni_vp);
                else
                        vput(ndp->ni_dvp);
                vrele(ndp->ni_vp);
-               RETURN (EEXIST);
-       } else {
-               VATTR_NULL(&vattr);
-               vattr.va_type = VFIFO;
-               vattr.va_mode = (uap->fmode & 07777) &~ u.u_cmask;
+               return (EEXIST);
        }
        }
-       RETURN (VOP_MKNOD(ndp, &vattr, ndp->ni_cred));
+       VATTR_NULL(&vattr);
+       vattr.va_type = VFIFO;
+       vattr.va_mode = (uap->fmode & 07777) &~ p->p_fd->fd_cmask;
+       return (VOP_MKNOD(ndp, &vattr, p->p_ucred, p));
 #endif /* FIFO */
 }
 
 /*
 #endif /* FIFO */
 }
 
 /*
- * link system call
+ * Link system call.
  */
 /* ARGSUSED */
 link(p, uap, retval)
  */
 /* ARGSUSED */
 link(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *target;
                char    *linkname;
        } *uap;
        int *retval;
 {
        register struct args {
                char    *target;
                char    *linkname;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        register struct vnode *vp, *xp;
        int error;
        register struct vnode *vp, *xp;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | FOLLOW;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->target;
        ndp->ni_nameiop = LOOKUP | FOLLOW;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->target;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        vp = ndp->ni_vp;
        if (vp->v_type == VDIR &&
        vp = ndp->ni_vp;
        if (vp->v_type == VDIR &&
-           (error = suser(ndp->ni_cred, &u.u_acflag)))
+           (error = suser(p->p_ucred, &p->p_acflag)))
                goto out1;
        ndp->ni_nameiop = CREATE | LOCKPARENT;
        ndp->ni_dirp = (caddr_t)uap->linkname;
                goto out1;
        ndp->ni_nameiop = CREATE | LOCKPARENT;
        ndp->ni_dirp = (caddr_t)uap->linkname;
-       if (error = namei(ndp))
+       if (error = namei(ndp, p))
                goto out1;
        xp = ndp->ni_vp;
        if (xp != NULL) {
                goto out1;
        xp = ndp->ni_vp;
        if (xp != NULL) {
@@ -751,7 +785,7 @@ link(p, uap, retval)
                error = EXDEV;
 out:
        if (!error) {
                error = EXDEV;
 out:
        if (!error) {
-               error = VOP_LINK(vp, ndp);
+               error = VOP_LINK(vp, ndp, p);
        } else {
                VOP_ABORTOP(ndp);
                if (ndp->ni_dvp == ndp->ni_vp)
        } else {
                VOP_ABORTOP(ndp);
                if (ndp->ni_dvp == ndp->ni_vp)
@@ -763,33 +797,35 @@ out:
        }
 out1:
        vrele(vp);
        }
 out1:
        vrele(vp);
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
- * symlink -- make a symbolic link
+ * Make a symbolic link.
  */
 /* ARGSUSED */
 symlink(p, uap, retval)
  */
 /* ARGSUSED */
 symlink(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *target;
                char    *linkname;
        } *uap;
        int *retval;
 {
        register struct args {
                char    *target;
                char    *linkname;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        struct vattr vattr;
        char *target;
        int error;
        struct vattr vattr;
        char *target;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->linkname;
        MALLOC(target, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
        if (error = copyinstr(uap->target, target, MAXPATHLEN, (u_int *)0))
                goto out;
        ndp->ni_nameiop = CREATE | LOCKPARENT;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->linkname;
        MALLOC(target, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
        if (error = copyinstr(uap->target, target, MAXPATHLEN, (u_int *)0))
                goto out;
        ndp->ni_nameiop = CREATE | LOCKPARENT;
-       if (error = namei(ndp))
+       if (error = namei(ndp, p))
                goto out;
        if (ndp->ni_vp) {
                VOP_ABORTOP(ndp);
                goto out;
        if (ndp->ni_vp) {
                VOP_ABORTOP(ndp);
@@ -802,51 +838,50 @@ symlink(p, uap, retval)
                goto out;
        }
        VATTR_NULL(&vattr);
                goto out;
        }
        VATTR_NULL(&vattr);
-       vattr.va_mode = 0777 &~ u.u_cmask;
-       error = VOP_SYMLINK(ndp, &vattr, target);
+       vattr.va_mode = 0777 &~ p->p_fd->fd_cmask;
+       error = VOP_SYMLINK(ndp, &vattr, target, p);
 out:
        FREE(target, M_NAMEI);
 out:
        FREE(target, M_NAMEI);
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
- * Unlink system call.
- * Hard to avoid races here, especially
- * in unlinking directories.
+ * Delete a name from the filesystem.
  */
 /* ARGSUSED */
 unlink(p, uap, retval)
  */
 /* ARGSUSED */
 unlink(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        struct args {
                char    *fname;
        } *uap;
        int *retval;
 {
        struct args {
                char    *fname;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        register struct vnode *vp;
        int error;
        register struct vnode *vp;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = DELETE | LOCKPARENT | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_nameiop = DELETE | LOCKPARENT | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        vp = ndp->ni_vp;
        if (vp->v_type == VDIR &&
        vp = ndp->ni_vp;
        if (vp->v_type == VDIR &&
-           (error = suser(ndp->ni_cred, &u.u_acflag)))
+           (error = suser(p->p_ucred, &p->p_acflag)))
                goto out;
        /*
                goto out;
        /*
-        * Don't unlink a mounted file.
+        * The root of a mounted filesystem cannot be deleted.
         */
        if (vp->v_flag & VROOT) {
                error = EBUSY;
                goto out;
        }
         */
        if (vp->v_flag & VROOT) {
                error = EBUSY;
                goto out;
        }
-       if (vp->v_flag & VTEXT)
-               xrele(vp);      /* try once to free text */
+       (void) vnode_pager_uncache(vp);
 out:
        if (!error) {
 out:
        if (!error) {
-               error = VOP_REMOVE(ndp);
+               error = VOP_REMOVE(ndp, p);
        } else {
                VOP_ABORTOP(ndp);
                if (ndp->ni_dvp == vp)
        } else {
                VOP_ABORTOP(ndp);
                if (ndp->ni_dvp == vp)
@@ -855,14 +890,14 @@ out:
                        vput(ndp->ni_dvp);
                vput(vp);
        }
                        vput(ndp->ni_dvp);
                vput(vp);
        }
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
- * Seek system call
+ * Seek system call.
  */
 lseek(p, uap, retval)
  */
 lseek(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                int     fdes;
                off_t   off;
        register struct args {
                int     fdes;
                off_t   off;
@@ -870,16 +905,17 @@ lseek(p, uap, retval)
        } *uap;
        off_t *retval;
 {
        } *uap;
        off_t *retval;
 {
-       struct ucred *cred = u.u_nd.ni_cred;
+       struct ucred *cred = p->p_ucred;
+       register struct filedesc *fdp = p->p_fd;
        register struct file *fp;
        struct vattr vattr;
        int error;
 
        register struct file *fp;
        struct vattr vattr;
        int error;
 
-       if ((unsigned)uap->fdes >= NOFILE ||
-           (fp = u.u_ofile[uap->fdes]) == NULL)
-               RETURN (EBADF);
+       if ((unsigned)uap->fdes >= fdp->fd_nfiles ||
+           (fp = fdp->fd_ofiles[uap->fdes]) == NULL)
+               return (EBADF);
        if (fp->f_type != DTYPE_VNODE)
        if (fp->f_type != DTYPE_VNODE)
-               RETURN (ESPIPE);
+               return (ESPIPE);
        switch (uap->sbase) {
 
        case L_INCR:
        switch (uap->sbase) {
 
        case L_INCR:
@@ -888,8 +924,8 @@ lseek(p, uap, retval)
 
        case L_XTND:
                if (error = VOP_GETATTR((struct vnode *)fp->f_data,
 
        case L_XTND:
                if (error = VOP_GETATTR((struct vnode *)fp->f_data,
-                   &vattr, cred))
-                       RETURN (error);
+                   &vattr, cred, p))
+                       return (error);
                fp->f_offset = uap->off + vattr.va_size;
                break;
 
                fp->f_offset = uap->off + vattr.va_size;
                break;
 
@@ -898,37 +934,39 @@ lseek(p, uap, retval)
                break;
 
        default:
                break;
 
        default:
-               RETURN (EINVAL);
+               return (EINVAL);
        }
        *retval = fp->f_offset;
        }
        *retval = fp->f_offset;
-       RETURN (0);
+       return (0);
 }
 
 /*
 }
 
 /*
- * Access system call
+ * Check access permissions.
  */
 /* ARGSUSED */
 saccess(p, uap, retval)
  */
 /* ARGSUSED */
 saccess(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *fname;
                int     fmode;
        } *uap;
        int *retval;
 {
        register struct args {
                char    *fname;
                int     fmode;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
-       register struct ucred *cred = ndp->ni_cred;
+       register struct nameidata *ndp;
+       register struct ucred *cred = p->p_ucred;
        register struct vnode *vp;
        int error, mode, svuid, svgid;
        register struct vnode *vp;
        int error, mode, svuid, svgid;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        svuid = cred->cr_uid;
        svgid = cred->cr_groups[0];
        svuid = cred->cr_uid;
        svgid = cred->cr_groups[0];
-       cred->cr_uid = p->p_ruid;
-       cred->cr_groups[0] = p->p_rgid;
+       cred->cr_uid = p->p_cred->p_ruid;
+       cred->cr_groups[0] = p->p_cred->p_rgid;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       if (error = namei(ndp))
+       if (error = namei(ndp, p))
                goto out1;
        vp = ndp->ni_vp;
        /*
                goto out1;
        vp = ndp->ni_vp;
        /*
@@ -943,79 +981,85 @@ saccess(p, uap, retval)
                if (uap->fmode & X_OK)
                        mode |= VEXEC;
                if ((mode & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
                if (uap->fmode & X_OK)
                        mode |= VEXEC;
                if ((mode & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
-                       error = VOP_ACCESS(vp, mode, ndp->ni_cred);
+                       error = VOP_ACCESS(vp, mode, cred, p);
        }
        vput(vp);
 out1:
        cred->cr_uid = svuid;
        cred->cr_groups[0] = svgid;
        }
        vput(vp);
 out1:
        cred->cr_uid = svuid;
        cred->cr_groups[0] = svgid;
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
- * Stat system call.  This version follows links.
+ * Stat system call.
+ * This version follows links.
  */
 /* ARGSUSED */
 stat(p, uap, retval)
  */
 /* ARGSUSED */
 stat(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *fname;
                struct stat *ub;
        } *uap;
        int *retval;
 {
        register struct args {
                char    *fname;
                struct stat *ub;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        struct stat sb;
        int error;
        struct stat sb;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       if (error = namei(ndp))
-               RETURN (error);
-       error = vn_stat(ndp->ni_vp, &sb);
+       if (error = namei(ndp, p))
+               return (error);
+       error = vn_stat(ndp->ni_vp, &sb, p);
        vput(ndp->ni_vp);
        if (error)
        vput(ndp->ni_vp);
        if (error)
-               RETURN (error);
+               return (error);
        error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
        error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
- * Lstat system call.  This version does not follow links.
+ * Lstat system call.
+ * This version does not follow links.
  */
 /* ARGSUSED */
 lstat(p, uap, retval)
  */
 /* ARGSUSED */
 lstat(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *fname;
                struct stat *ub;
        } *uap;
        int *retval;
 {
        register struct args {
                char    *fname;
                struct stat *ub;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        struct stat sb;
        int error;
        struct stat sb;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | LOCKLEAF | NOFOLLOW;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_nameiop = LOOKUP | LOCKLEAF | NOFOLLOW;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       if (error = namei(ndp))
-               RETURN (error);
-       error = vn_stat(ndp->ni_vp, &sb);
+       if (error = namei(ndp, p))
+               return (error);
+       error = vn_stat(ndp->ni_vp, &sb, p);
        vput(ndp->ni_vp);
        if (error)
        vput(ndp->ni_vp);
        if (error)
-               RETURN (error);
+               return (error);
        error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
        error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
- * Return target name of a symbolic link
+ * Return target name of a symbolic link.
  */
 /* ARGSUSED */
 readlink(p, uap, retval)
  */
 /* ARGSUSED */
 readlink(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *name;
                char    *buf;
        register struct args {
                char    *name;
                char    *buf;
@@ -1023,17 +1067,19 @@ readlink(p, uap, retval)
        } *uap;
        int *retval;
 {
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        register struct vnode *vp;
        struct iovec aiov;
        struct uio auio;
        int error;
        register struct vnode *vp;
        struct iovec aiov;
        struct uio auio;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->name;
        ndp->ni_nameiop = LOOKUP | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->name;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        vp = ndp->ni_vp;
        if (vp->v_type != VLNK) {
                error = EINVAL;
        vp = ndp->ni_vp;
        if (vp->v_type != VLNK) {
                error = EINVAL;
@@ -1046,12 +1092,13 @@ readlink(p, uap, retval)
        auio.uio_offset = 0;
        auio.uio_rw = UIO_READ;
        auio.uio_segflg = UIO_USERSPACE;
        auio.uio_offset = 0;
        auio.uio_rw = UIO_READ;
        auio.uio_segflg = UIO_USERSPACE;
+       auio.uio_procp = p;
        auio.uio_resid = uap->count;
        auio.uio_resid = uap->count;
-       error = VOP_READLINK(vp, &auio, ndp->ni_cred);
+       error = VOP_READLINK(vp, &auio, p->p_ucred);
 out:
        vput(vp);
        *retval = uap->count - auio.uio_resid;
 out:
        vput(vp);
        *retval = uap->count - auio.uio_resid;
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -1059,34 +1106,36 @@ out:
  */
 /* ARGSUSED */
 chflags(p, uap, retval)
  */
 /* ARGSUSED */
 chflags(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *fname;
                int     flags;
        } *uap;
        int *retval;
 {
        register struct args {
                char    *fname;
                int     flags;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        register struct vnode *vp;
        struct vattr vattr;
        int error;
        register struct vnode *vp;
        struct vattr vattr;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       VATTR_NULL(&vattr);
-       vattr.va_flags = uap->flags;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        vp = ndp->ni_vp;
        if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                error = EROFS;
                goto out;
        }
        vp = ndp->ni_vp;
        if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                error = EROFS;
                goto out;
        }
-       error = VOP_SETATTR(vp, &vattr, ndp->ni_cred);
+       VATTR_NULL(&vattr);
+       vattr.va_flags = uap->flags;
+       error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
 out:
        vput(vp);
 out:
        vput(vp);
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -1094,7 +1143,7 @@ out:
  */
 /* ARGSUSED */
 fchflags(p, uap, retval)
  */
 /* ARGSUSED */
 fchflags(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                int     fd;
                int     flags;
        register struct args {
                int     fd;
                int     flags;
@@ -1106,20 +1155,20 @@ fchflags(p, uap, retval)
        struct file *fp;
        int error;
 
        struct file *fp;
        int error;
 
-       if (error = getvnode(u.u_ofile, uap->fd, &fp))
-               RETURN (error);
-       VATTR_NULL(&vattr);
-       vattr.va_flags = uap->flags;
+       if (error = getvnode(p->p_fd, uap->fd, &fp))
+               return (error);
        vp = (struct vnode *)fp->f_data;
        VOP_LOCK(vp);
        if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                error = EROFS;
                goto out;
        }
        vp = (struct vnode *)fp->f_data;
        VOP_LOCK(vp);
        if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                error = EROFS;
                goto out;
        }
-       error = VOP_SETATTR(vp, &vattr, fp->f_cred);
+       VATTR_NULL(&vattr);
+       vattr.va_flags = uap->flags;
+       error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
 out:
        VOP_UNLOCK(vp);
 out:
        VOP_UNLOCK(vp);
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -1127,34 +1176,36 @@ out:
  */
 /* ARGSUSED */
 chmod(p, uap, retval)
  */
 /* ARGSUSED */
 chmod(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *fname;
                int     fmode;
        } *uap;
        int *retval;
 {
        register struct args {
                char    *fname;
                int     fmode;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        register struct vnode *vp;
        struct vattr vattr;
        int error;
        register struct vnode *vp;
        struct vattr vattr;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       VATTR_NULL(&vattr);
-       vattr.va_mode = uap->fmode & 07777;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        vp = ndp->ni_vp;
        if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                error = EROFS;
                goto out;
        }
        vp = ndp->ni_vp;
        if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                error = EROFS;
                goto out;
        }
-       error = VOP_SETATTR(vp, &vattr, ndp->ni_cred);
+       VATTR_NULL(&vattr);
+       vattr.va_mode = uap->fmode & 07777;
+       error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
 out:
        vput(vp);
 out:
        vput(vp);
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -1162,7 +1213,7 @@ out:
  */
 /* ARGSUSED */
 fchmod(p, uap, retval)
  */
 /* ARGSUSED */
 fchmod(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                int     fd;
                int     fmode;
        register struct args {
                int     fd;
                int     fmode;
@@ -1174,20 +1225,20 @@ fchmod(p, uap, retval)
        struct file *fp;
        int error;
 
        struct file *fp;
        int error;
 
-       if (error = getvnode(u.u_ofile, uap->fd, &fp))
-               RETURN (error);
-       VATTR_NULL(&vattr);
-       vattr.va_mode = uap->fmode & 07777;
+       if (error = getvnode(p->p_fd, uap->fd, &fp))
+               return (error);
        vp = (struct vnode *)fp->f_data;
        VOP_LOCK(vp);
        if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                error = EROFS;
                goto out;
        }
        vp = (struct vnode *)fp->f_data;
        VOP_LOCK(vp);
        if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                error = EROFS;
                goto out;
        }
-       error = VOP_SETATTR(vp, &vattr, fp->f_cred);
+       VATTR_NULL(&vattr);
+       vattr.va_mode = uap->fmode & 07777;
+       error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
 out:
        VOP_UNLOCK(vp);
 out:
        VOP_UNLOCK(vp);
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -1195,7 +1246,7 @@ out:
  */
 /* ARGSUSED */
 chown(p, uap, retval)
  */
 /* ARGSUSED */
 chown(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *fname;
                int     uid;
        register struct args {
                char    *fname;
                int     uid;
@@ -1203,28 +1254,30 @@ chown(p, uap, retval)
        } *uap;
        int *retval;
 {
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        register struct vnode *vp;
        struct vattr vattr;
        int error;
        register struct vnode *vp;
        struct vattr vattr;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | NOFOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_nameiop = LOOKUP | NOFOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       VATTR_NULL(&vattr);
-       vattr.va_uid = uap->uid;
-       vattr.va_gid = uap->gid;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        vp = ndp->ni_vp;
        if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                error = EROFS;
                goto out;
        }
        vp = ndp->ni_vp;
        if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                error = EROFS;
                goto out;
        }
-       error = VOP_SETATTR(vp, &vattr, ndp->ni_cred);
+       VATTR_NULL(&vattr);
+       vattr.va_uid = uap->uid;
+       vattr.va_gid = uap->gid;
+       error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
 out:
        vput(vp);
 out:
        vput(vp);
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -1232,7 +1285,7 @@ out:
  */
 /* ARGSUSED */
 fchown(p, uap, retval)
  */
 /* ARGSUSED */
 fchown(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                int     fd;
                int     uid;
        register struct args {
                int     fd;
                int     uid;
@@ -1245,21 +1298,21 @@ fchown(p, uap, retval)
        struct file *fp;
        int error;
 
        struct file *fp;
        int error;
 
-       if (error = getvnode(u.u_ofile, uap->fd, &fp))
-               RETURN (error);
-       VATTR_NULL(&vattr);
-       vattr.va_uid = uap->uid;
-       vattr.va_gid = uap->gid;
+       if (error = getvnode(p->p_fd, uap->fd, &fp))
+               return (error);
        vp = (struct vnode *)fp->f_data;
        VOP_LOCK(vp);
        if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                error = EROFS;
                goto out;
        }
        vp = (struct vnode *)fp->f_data;
        VOP_LOCK(vp);
        if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                error = EROFS;
                goto out;
        }
-       error = VOP_SETATTR(vp, &vattr, fp->f_cred);
+       VATTR_NULL(&vattr);
+       vattr.va_uid = uap->uid;
+       vattr.va_gid = uap->gid;
+       error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
 out:
        VOP_UNLOCK(vp);
 out:
        VOP_UNLOCK(vp);
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -1267,38 +1320,40 @@ out:
  */
 /* ARGSUSED */
 utimes(p, uap, retval)
  */
 /* ARGSUSED */
 utimes(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *fname;
                struct  timeval *tptr;
        } *uap;
        int *retval;
 {
        register struct args {
                char    *fname;
                struct  timeval *tptr;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        register struct vnode *vp;
        struct timeval tv[2];
        struct vattr vattr;
        int error;
        register struct vnode *vp;
        struct timeval tv[2];
        struct vattr vattr;
        int error;
+       struct nameidata nd;
 
        if (error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)))
 
        if (error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)))
-               RETURN (error);
+               return (error);
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       VATTR_NULL(&vattr);
-       vattr.va_atime = tv[0];
-       vattr.va_mtime = tv[1];
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        vp = ndp->ni_vp;
        if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                error = EROFS;
                goto out;
        }
        vp = ndp->ni_vp;
        if (vp->v_mount->mnt_flag & MNT_RDONLY) {
                error = EROFS;
                goto out;
        }
-       error = VOP_SETATTR(vp, &vattr, ndp->ni_cred);
+       VATTR_NULL(&vattr);
+       vattr.va_atime = tv[0];
+       vattr.va_mtime = tv[1];
+       error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
 out:
        vput(vp);
 out:
        vput(vp);
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -1306,37 +1361,39 @@ out:
  */
 /* ARGSUSED */
 truncate(p, uap, retval)
  */
 /* ARGSUSED */
 truncate(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *fname;
                off_t   length;
        } *uap;
        int *retval;
 {
        register struct args {
                char    *fname;
                off_t   length;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        register struct vnode *vp;
        struct vattr vattr;
        int error;
        register struct vnode *vp;
        struct vattr vattr;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       VATTR_NULL(&vattr);
-       vattr.va_size = uap->length;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        vp = ndp->ni_vp;
        if (vp->v_type == VDIR) {
                error = EISDIR;
                goto out;
        }
        if ((error = vn_writechk(vp)) ||
        vp = ndp->ni_vp;
        if (vp->v_type == VDIR) {
                error = EISDIR;
                goto out;
        }
        if ((error = vn_writechk(vp)) ||
-           (error = VOP_ACCESS(vp, VWRITE, ndp->ni_cred)))
+           (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p)))
                goto out;
                goto out;
-       error = VOP_SETATTR(vp, &vattr, ndp->ni_cred);
+       VATTR_NULL(&vattr);
+       vattr.va_size = uap->length;
+       error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
 out:
        vput(vp);
 out:
        vput(vp);
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -1344,7 +1401,7 @@ out:
  */
 /* ARGSUSED */
 ftruncate(p, uap, retval)
  */
 /* ARGSUSED */
 ftruncate(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                int     fd;
                off_t   length;
        register struct args {
                int     fd;
                off_t   length;
@@ -1356,12 +1413,10 @@ ftruncate(p, uap, retval)
        struct file *fp;
        int error;
 
        struct file *fp;
        int error;
 
-       if (error = getvnode(u.u_ofile, uap->fd, &fp))
-               RETURN (error);
+       if (error = getvnode(p->p_fd, uap->fd, &fp))
+               return (error);
        if ((fp->f_flag & FWRITE) == 0)
        if ((fp->f_flag & FWRITE) == 0)
-               RETURN (EINVAL);
-       VATTR_NULL(&vattr);
-       vattr.va_size = uap->length;
+               return (EINVAL);
        vp = (struct vnode *)fp->f_data;
        VOP_LOCK(vp);
        if (vp->v_type == VDIR) {
        vp = (struct vnode *)fp->f_data;
        VOP_LOCK(vp);
        if (vp->v_type == VDIR) {
@@ -1370,10 +1425,12 @@ ftruncate(p, uap, retval)
        }
        if (error = vn_writechk(vp))
                goto out;
        }
        if (error = vn_writechk(vp))
                goto out;
-       error = VOP_SETATTR(vp, &vattr, fp->f_cred);
+       VATTR_NULL(&vattr);
+       vattr.va_size = uap->length;
+       error = VOP_SETATTR(vp, &vattr, fp->f_cred, p);
 out:
        VOP_UNLOCK(vp);
 out:
        VOP_UNLOCK(vp);
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -1381,7 +1438,7 @@ out:
  */
 /* ARGSUSED */
 fsync(p, uap, retval)
  */
 /* ARGSUSED */
 fsync(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        struct args {
                int     fd;
        } *uap;
        struct args {
                int     fd;
        } *uap;
@@ -1391,13 +1448,13 @@ fsync(p, uap, retval)
        struct file *fp;
        int error;
 
        struct file *fp;
        int error;
 
-       if (error = getvnode(u.u_ofile, uap->fd, &fp))
-               RETURN (error);
+       if (error = getvnode(p->p_fd, uap->fd, &fp))
+               return (error);
        vp = (struct vnode *)fp->f_data;
        VOP_LOCK(vp);
        vp = (struct vnode *)fp->f_data;
        VOP_LOCK(vp);
-       error = VOP_FSYNC(vp, fp->f_flag, fp->f_cred, MNT_WAIT);
+       error = VOP_FSYNC(vp, fp->f_flag, fp->f_cred, MNT_WAIT, p);
        VOP_UNLOCK(vp);
        VOP_UNLOCK(vp);
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -1408,7 +1465,7 @@ fsync(p, uap, retval)
  */
 /* ARGSUSED */
 rename(p, uap, retval)
  */
 /* ARGSUSED */
 rename(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *from;
                char    *to;
        register struct args {
                char    *from;
                char    *to;
@@ -1416,23 +1473,21 @@ rename(p, uap, retval)
        int *retval;
 {
        register struct vnode *tvp, *fvp, *tdvp;
        int *retval;
 {
        register struct vnode *tvp, *fvp, *tdvp;
-       register struct nameidata *ndp = &u.u_nd;
-       struct nameidata tond;
+       struct nameidata fromnd, tond;
        int error;
 
        int error;
 
-       ndp->ni_nameiop = DELETE | WANTPARENT;
-       ndp->ni_segflg = UIO_USERSPACE;
-       ndp->ni_dirp = uap->from;
-       if (error = namei(ndp))
-               RETURN (error);
-       fvp = ndp->ni_vp;
-       nddup(ndp, &tond);
-       tond.ni_nameiop = RENAME | LOCKPARENT | LOCKLEAF | NOCACHE;
+       fromnd.ni_nameiop = DELETE | WANTPARENT | SAVESTART;
+       fromnd.ni_segflg = UIO_USERSPACE;
+       fromnd.ni_dirp = uap->from;
+       if (error = namei(&fromnd, p))
+               return (error);
+       fvp = fromnd.ni_vp;
+       tond.ni_nameiop = RENAME | LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART;
        tond.ni_segflg = UIO_USERSPACE;
        tond.ni_dirp = uap->to;
        tond.ni_segflg = UIO_USERSPACE;
        tond.ni_dirp = uap->to;
-       if (error = namei(&tond)) {
-               VOP_ABORTOP(ndp);
-               vrele(ndp->ni_dvp);
+       if (error = namei(&tond, p)) {
+               VOP_ABORTOP(&fromnd);
+               vrele(fromnd.ni_dvp);
                vrele(fvp);
                goto out1;
        }
                vrele(fvp);
                goto out1;
        }
@@ -1446,6 +1501,10 @@ rename(p, uap, retval)
                        error = EISDIR;
                        goto out;
                }
                        error = EISDIR;
                        goto out;
                }
+               if (fvp->v_mount != tvp->v_mount) {
+                       error = EXDEV;
+                       goto out;
+               }
        }
        if (fvp->v_mount != tdvp->v_mount) {
                error = EXDEV;
        }
        if (fvp->v_mount != tdvp->v_mount) {
                error = EXDEV;
@@ -1454,14 +1513,17 @@ rename(p, uap, retval)
        if (fvp == tdvp)
                error = EINVAL;
        /*
        if (fvp == tdvp)
                error = EINVAL;
        /*
-        * If source is the same as the destination,
+        * If source is the same as the destination (that is the
+        * same inode number with the same name in the same directory),
         * then there is nothing to do.
         */
         * then there is nothing to do.
         */
-       if (fvp == tvp)
+       if (fvp == tvp && fromnd.ni_dvp == tdvp &&
+           fromnd.ni_namelen == tond.ni_namelen &&
+           !bcmp(fromnd.ni_ptr, tond.ni_ptr, fromnd.ni_namelen))
                error = -1;
 out:
        if (!error) {
                error = -1;
 out:
        if (!error) {
-               error = VOP_RENAME(ndp, &tond);
+               error = VOP_RENAME(&fromnd, &tond, p);
        } else {
                VOP_ABORTOP(&tond);
                if (tdvp == tvp)
        } else {
                VOP_ABORTOP(&tond);
                if (tdvp == tvp)
@@ -1470,39 +1532,46 @@ out:
                        vput(tdvp);
                if (tvp)
                        vput(tvp);
                        vput(tdvp);
                if (tvp)
                        vput(tvp);
-               VOP_ABORTOP(ndp);
-               vrele(ndp->ni_dvp);
+               VOP_ABORTOP(&fromnd);
+               vrele(fromnd.ni_dvp);
                vrele(fvp);
        }
                vrele(fvp);
        }
+       p->p_spare[1]--;
+       vrele(tond.ni_startdir);
+       FREE(tond.ni_pnbuf, M_NAMEI);
 out1:
 out1:
-       ndrele(&tond);
+       p->p_spare[1]--;
+       vrele(fromnd.ni_startdir);
+       FREE(fromnd.ni_pnbuf, M_NAMEI);
        if (error == -1)
        if (error == -1)
-               RETURN (0);
-       RETURN (error);
+               return (0);
+       return (error);
 }
 
 /*
 }
 
 /*
- * Mkdir system call
+ * Mkdir system call.
  */
 /* ARGSUSED */
 mkdir(p, uap, retval)
  */
 /* ARGSUSED */
 mkdir(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *name;
                int     dmode;
        } *uap;
        int *retval;
 {
        register struct args {
                char    *name;
                int     dmode;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        register struct vnode *vp;
        struct vattr vattr;
        int error;
        register struct vnode *vp;
        struct vattr vattr;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = CREATE | LOCKPARENT;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->name;
        ndp->ni_nameiop = CREATE | LOCKPARENT;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->name;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        vp = ndp->ni_vp;
        if (vp != NULL) {
                VOP_ABORTOP(ndp);
        vp = ndp->ni_vp;
        if (vp != NULL) {
                VOP_ABORTOP(ndp);
@@ -1511,15 +1580,15 @@ mkdir(p, uap, retval)
                else
                        vput(ndp->ni_dvp);
                vrele(vp);
                else
                        vput(ndp->ni_dvp);
                vrele(vp);
-               RETURN (EEXIST);
+               return (EEXIST);
        }
        VATTR_NULL(&vattr);
        vattr.va_type = VDIR;
        }
        VATTR_NULL(&vattr);
        vattr.va_type = VDIR;
-       vattr.va_mode = (uap->dmode & 0777) &~ u.u_cmask;
-       error = VOP_MKDIR(ndp, &vattr);
+       vattr.va_mode = (uap->dmode & 0777) &~ p->p_fd->fd_cmask;
+       error = VOP_MKDIR(ndp, &vattr, p);
        if (!error)
                vput(ndp->ni_vp);
        if (!error)
                vput(ndp->ni_vp);
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -1527,21 +1596,23 @@ mkdir(p, uap, retval)
  */
 /* ARGSUSED */
 rmdir(p, uap, retval)
  */
 /* ARGSUSED */
 rmdir(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        struct args {
                char    *name;
        } *uap;
        int *retval;
 {
        struct args {
                char    *name;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        register struct vnode *vp;
        int error;
        register struct vnode *vp;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = DELETE | LOCKPARENT | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->name;
        ndp->ni_nameiop = DELETE | LOCKPARENT | LOCKLEAF;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->name;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        vp = ndp->ni_vp;
        if (vp->v_type != VDIR) {
                error = ENOTDIR;
        vp = ndp->ni_vp;
        if (vp->v_type != VDIR) {
                error = ENOTDIR;
@@ -1555,13 +1626,13 @@ rmdir(p, uap, retval)
                goto out;
        }
        /*
                goto out;
        }
        /*
-        * Don't unlink a mounted file.
+        * The root of a mounted filesystem cannot be deleted.
         */
        if (vp->v_flag & VROOT)
                error = EBUSY;
 out:
        if (!error) {
         */
        if (vp->v_flag & VROOT)
                error = EBUSY;
 out:
        if (!error) {
-               error = VOP_RMDIR(ndp);
+               error = VOP_RMDIR(ndp, p);
        } else {
                VOP_ABORTOP(ndp);
                if (ndp->ni_dvp == vp)
        } else {
                VOP_ABORTOP(ndp);
                if (ndp->ni_dvp == vp)
@@ -1570,14 +1641,14 @@ out:
                        vput(ndp->ni_dvp);
                vput(vp);
        }
                        vput(ndp->ni_dvp);
                vput(vp);
        }
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
- * Read a block of directory entries in a file system independent format
+ * Read a block of directory entries in a file system independent format.
  */
 getdirentries(p, uap, retval)
  */
 getdirentries(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                int     fd;
                char    *buf;
        register struct args {
                int     fd;
                char    *buf;
@@ -1593,19 +1664,20 @@ getdirentries(p, uap, retval)
        off_t off;
        int error, eofflag;
 
        off_t off;
        int error, eofflag;
 
-       if (error = getvnode(u.u_ofile, uap->fd, &fp))
-               RETURN (error);
+       if (error = getvnode(p->p_fd, uap->fd, &fp))
+               return (error);
        if ((fp->f_flag & FREAD) == 0)
        if ((fp->f_flag & FREAD) == 0)
-               RETURN (EBADF);
+               return (EBADF);
        vp = (struct vnode *)fp->f_data;
        if (vp->v_type != VDIR)
        vp = (struct vnode *)fp->f_data;
        if (vp->v_type != VDIR)
-               RETURN (EINVAL);
+               return (EINVAL);
        aiov.iov_base = uap->buf;
        aiov.iov_len = uap->count;
        auio.uio_iov = &aiov;
        auio.uio_iovcnt = 1;
        auio.uio_rw = UIO_READ;
        auio.uio_segflg = UIO_USERSPACE;
        aiov.iov_base = uap->buf;
        aiov.iov_len = uap->count;
        auio.uio_iov = &aiov;
        auio.uio_iovcnt = 1;
        auio.uio_rw = UIO_READ;
        auio.uio_segflg = UIO_USERSPACE;
+       auio.uio_procp = p;
        auio.uio_resid = uap->count;
        VOP_LOCK(vp);
        auio.uio_offset = off = fp->f_offset;
        auio.uio_resid = uap->count;
        VOP_LOCK(vp);
        auio.uio_offset = off = fp->f_offset;
@@ -1613,27 +1685,28 @@ getdirentries(p, uap, retval)
        fp->f_offset = auio.uio_offset;
        VOP_UNLOCK(vp);
        if (error)
        fp->f_offset = auio.uio_offset;
        VOP_UNLOCK(vp);
        if (error)
-               RETURN (error);
+               return (error);
        error = copyout((caddr_t)&off, (caddr_t)uap->basep, sizeof(long));
        *retval = uap->count - auio.uio_resid;
        error = copyout((caddr_t)&off, (caddr_t)uap->basep, sizeof(long));
        *retval = uap->count - auio.uio_resid;
-       RETURN (error);
+       return (error);
 }
 
 /*
 }
 
 /*
- * mode mask for creation of files
+ * Set the mode mask for creation of filesystem nodes.
  */
 mode_t
 umask(p, uap, retval)
  */
 mode_t
 umask(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        struct args {
                int     mask;
        } *uap;
        int *retval;
 {
        struct args {
                int     mask;
        } *uap;
        int *retval;
 {
+       register struct filedesc *fdp = p->p_fd;
 
 
-       *retval = u.u_cmask;
-       u.u_cmask = uap->mask & 07777;
-       RETURN (0);
+       *retval = fdp->fd_cmask;
+       fdp->fd_cmask = uap->mask & 07777;
+       return (0);
 }
 
 /*
 }
 
 /*
@@ -1642,47 +1715,53 @@ umask(p, uap, retval)
  */
 /* ARGSUSED */
 revoke(p, uap, retval)
  */
 /* ARGSUSED */
 revoke(p, uap, retval)
-       register struct proc *p;
+       struct proc *p;
        register struct args {
                char    *fname;
        } *uap;
        int *retval;
 {
        register struct args {
                char    *fname;
        } *uap;
        int *retval;
 {
-       register struct nameidata *ndp = &u.u_nd;
+       register struct nameidata *ndp;
        register struct vnode *vp;
        struct vattr vattr;
        int error;
        register struct vnode *vp;
        struct vattr vattr;
        int error;
+       struct nameidata nd;
 
 
+       ndp = &nd;
        ndp->ni_nameiop = LOOKUP | FOLLOW;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
        ndp->ni_nameiop = LOOKUP | FOLLOW;
        ndp->ni_segflg = UIO_USERSPACE;
        ndp->ni_dirp = uap->fname;
-       if (error = namei(ndp))
-               RETURN (error);
+       if (error = namei(ndp, p))
+               return (error);
        vp = ndp->ni_vp;
        if (vp->v_type != VCHR && vp->v_type != VBLK) {
                error = EINVAL;
                goto out;
        }
        vp = ndp->ni_vp;
        if (vp->v_type != VCHR && vp->v_type != VBLK) {
                error = EINVAL;
                goto out;
        }
-       if (error = VOP_GETATTR(vp, &vattr, ndp->ni_cred))
+       if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p))
                goto out;
                goto out;
-       if (ndp->ni_cred->cr_uid != vattr.va_uid &&
-           (error = suser(ndp->ni_cred, &u.u_acflag)))
+       if (p->p_ucred->cr_uid != vattr.va_uid &&
+           (error = suser(p->p_ucred, &p->p_acflag)))
                goto out;
        if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
                vgoneall(vp);
 out:
        vrele(vp);
                goto out;
        if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
                vgoneall(vp);
 out:
        vrele(vp);
-       RETURN (error);
+       return (error);
 }
 
 }
 
-getvnode(ofile, fdes, fpp)
-       struct file *ofile[];
+/*
+ * Convert a user file descriptor to a kernel file entry.
+ */
+getvnode(fdp, fdes, fpp)
+       struct filedesc *fdp;
        struct file **fpp;
        int fdes;
 {
        struct file *fp;
 
        struct file **fpp;
        int fdes;
 {
        struct file *fp;
 
-       if ((unsigned)fdes >= NOFILE || (fp = ofile[fdes]) == NULL)
+       if ((unsigned)fdes >= fdp->fd_nfiles ||
+           (fp = fdp->fd_ofiles[fdes]) == NULL)
                return (EBADF);
        if (fp->f_type != DTYPE_VNODE)
                return (EINVAL);
                return (EBADF);
        if (fp->f_type != DTYPE_VNODE)
                return (EINVAL);