Add extra argument to VOP_BMAP.
[unix-history] / usr / src / sys / ufs / ffs / ufs_vnops.c
index aa6e310..a1818b5 100644 (file)
@@ -4,7 +4,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)ufs_vnops.c 7.94 (Berkeley) %G%
+ *     @(#)ufs_vnops.c 7.109 (Berkeley) %G%
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
 #include <sys/conf.h>
 #include <sys/mount.h>
 #include <sys/vnode.h>
 #include <sys/conf.h>
 #include <sys/mount.h>
 #include <sys/vnode.h>
-#include <sys/specdev.h>
-#include <sys/fifo.h>
 #include <sys/malloc.h>
 #include <sys/malloc.h>
+#include <sys/dirent.h>
 
 #include <vm/vm.h>
 
 
 #include <vm/vm.h>
 
+#include <miscfs/specfs/specdev.h>
+
 #include <ufs/ufs/lockf.h>
 #include <ufs/ufs/quota.h>
 #include <ufs/ufs/inode.h>
 #include <ufs/ufs/lockf.h>
 #include <ufs/ufs/quota.h>
 #include <ufs/ufs/inode.h>
 #include <ufs/ufs/ufsmount.h>
 #include <ufs/ufs/ufs_extern.h>
 
 #include <ufs/ufs/ufsmount.h>
 #include <ufs/ufs/ufs_extern.h>
 
-int ufs_chmod __P((struct vnode *, int, struct ucred *, struct proc *));
-int ufs_chown
+static int ufs_chmod __P((struct vnode *, int, struct ucred *, struct proc *));
+static int ufs_chown
        __P((struct vnode *, uid_t, gid_t, struct ucred *, struct proc *));
 
        __P((struct vnode *, uid_t, gid_t, struct ucred *, struct proc *));
 
-#ifdef _NOQUAD
-#define        SETHIGH(q, h)   (q).val[_QUAD_HIGHWORD] = (h)
-#define        SETLOW(q, l)    (q).val[_QUAD_LOWWORD] = (l)
-#else /* QUAD */
 union _qcvt {
        quad_t qcvt;
        long val[2];
 union _qcvt {
        quad_t qcvt;
        long val[2];
@@ -56,14 +53,18 @@ union _qcvt {
        tmp.val[_QUAD_LOWWORD] = (l); \
        (q) = tmp.qcvt; \
 }
        tmp.val[_QUAD_LOWWORD] = (l); \
        (q) = tmp.qcvt; \
 }
-#endif /* QUAD */
 
 /*
  * Create a regular file
  */
 int
 ufs_create(ap)
 
 /*
  * Create a regular file
  */
 int
 ufs_create(ap)
-       struct vop_create_args *ap;
+       struct vop_create_args /* {
+               struct vnode *a_dvp;
+               struct vnode **a_vpp;
+               struct componentname *a_cnp;
+               struct vattr *a_vap;
+       } */ *ap;
 {
        int error;
 
 {
        int error;
 
@@ -80,7 +81,12 @@ ufs_create(ap)
 /* ARGSUSED */
 int
 ufs_mknod(ap)
 /* ARGSUSED */
 int
 ufs_mknod(ap)
-       struct vop_mknod_args *ap;
+       struct vop_mknod_args /* {
+               struct vnode *a_dvp;
+               struct vnode **a_vpp;
+               struct componentname *a_cnp;
+               struct vattr *a_vap;
+       } */ *ap;
 {
        register struct vattr *vap = ap->a_vap;
        register struct vnode **vpp = ap->a_vpp;
 {
        register struct vattr *vap = ap->a_vap;
        register struct vnode **vpp = ap->a_vpp;
@@ -120,7 +126,12 @@ ufs_mknod(ap)
 /* ARGSUSED */
 int
 ufs_open(ap)
 /* ARGSUSED */
 int
 ufs_open(ap)
-       struct vop_open_args *ap;
+       struct vop_open_args /* {
+               struct vnode *a_vp;
+               int  a_mode;
+               struct ucred *a_cred;
+               struct proc *a_p;
+       } */ *ap;
 {
 
        return (0);
 {
 
        return (0);
@@ -134,7 +145,12 @@ ufs_open(ap)
 /* ARGSUSED */
 int
 ufs_close(ap)
 /* ARGSUSED */
 int
 ufs_close(ap)
-       struct vop_close_args *ap;
+       struct vop_close_args /* {
+               struct vnode *a_vp;
+               int  a_fflag;
+               struct ucred *a_cred;
+               struct proc *a_p;
+       } */ *ap;
 {
        register struct vnode *vp = ap->a_vp;
        register struct inode *ip = VTOI(vp);
 {
        register struct vnode *vp = ap->a_vp;
        register struct inode *ip = VTOI(vp);
@@ -151,9 +167,13 @@ ufs_close(ap)
  */
 int
 ufs_access(ap)
  */
 int
 ufs_access(ap)
-       struct vop_access_args *ap;
+       struct vop_access_args /* {
+               struct vnode *a_vp;
+               int  a_mode;
+               struct ucred *a_cred;
+               struct proc *a_p;
+       } */ *ap;
 {
 {
-       USES_VOP_ISLOCKED;
        register struct vnode *vp = ap->a_vp;
        register struct inode *ip = VTOI(vp);
        register struct ucred *cred = ap->a_cred;
        register struct vnode *vp = ap->a_vp;
        register struct inode *ip = VTOI(vp);
        register struct ucred *cred = ap->a_cred;
@@ -204,7 +224,12 @@ found:
 /* ARGSUSED */
 int
 ufs_getattr(ap)
 /* ARGSUSED */
 int
 ufs_getattr(ap)
-       struct vop_getattr_args *ap;
+       struct vop_getattr_args /* {
+               struct vnode *a_vp;
+               struct vattr *a_vap;
+               struct ucred *a_cred;
+               struct proc *a_p;
+       } */ *ap;
 {
        register struct vnode *vp = ap->a_vp;
        register struct inode *ip = VTOI(vp);
 {
        register struct vnode *vp = ap->a_vp;
        register struct inode *ip = VTOI(vp);
@@ -221,12 +246,7 @@ ufs_getattr(ap)
        vap->va_uid = ip->i_uid;
        vap->va_gid = ip->i_gid;
        vap->va_rdev = (dev_t)ip->i_rdev;
        vap->va_uid = ip->i_uid;
        vap->va_gid = ip->i_gid;
        vap->va_rdev = (dev_t)ip->i_rdev;
-#ifdef tahoe
-       vap->va_size = ip->i_size;
-       vap->va_size_rsv = 0;
-#else
-       vap->va_qsize = ip->i_din.di_qsize;
-#endif
+       vap->va_size = ip->i_din.di_size;
        vap->va_atime = ip->i_atime;
        vap->va_mtime = ip->i_mtime;
        vap->va_ctime = ip->i_ctime;
        vap->va_atime = ip->i_atime;
        vap->va_mtime = ip->i_mtime;
        vap->va_ctime = ip->i_ctime;
@@ -240,9 +260,6 @@ ufs_getattr(ap)
        else
                vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
        vap->va_bytes = dbtob(ip->i_blocks);
        else
                vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
        vap->va_bytes = dbtob(ip->i_blocks);
-#ifdef _NOQUAD
-       vap->va_bytes_rsv = 0;
-#endif
        vap->va_type = vp->v_type;
        vap->va_filerev = ip->i_modrev;
        return (0);
        vap->va_type = vp->v_type;
        vap->va_filerev = ip->i_modrev;
        return (0);
@@ -253,15 +270,19 @@ ufs_getattr(ap)
  */
 int
 ufs_setattr(ap)
  */
 int
 ufs_setattr(ap)
-       struct vop_setattr_args *ap;
+       struct vop_setattr_args /* {
+               struct vnode *a_vp;
+               struct vattr *a_vap;
+               struct ucred *a_cred;
+               struct proc *a_p;
+       } */ *ap;
 {
 {
-       USES_VOP_TRUNCATE;
-       USES_VOP_UPDATE;
        register struct vattr *vap = ap->a_vap;
        register struct vnode *vp = ap->a_vp;
        register struct inode *ip = VTOI(vp);
        register struct ucred *cred = ap->a_cred;
        register struct proc *p = ap->a_p;
        register struct vattr *vap = ap->a_vap;
        register struct vnode *vp = ap->a_vp;
        register struct inode *ip = VTOI(vp);
        register struct ucred *cred = ap->a_cred;
        register struct proc *p = ap->a_p;
+       struct timeval atimeval, mtimeval;
        int error;
 
        /*
        int error;
 
        /*
@@ -282,20 +303,23 @@ ufs_setattr(ap)
        if (vap->va_size != VNOVAL) {
                if (vp->v_type == VDIR)
                        return (EISDIR);
        if (vap->va_size != VNOVAL) {
                if (vp->v_type == VDIR)
                        return (EISDIR);
-               if (error = VOP_TRUNCATE(vp, vap->va_size, 0, cred))
+               if (error = VOP_TRUNCATE(vp, vap->va_size, 0, cred, p))
                        return (error);
        }
        ip = VTOI(vp);
                        return (error);
        }
        ip = VTOI(vp);
-       if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
+       if (vap->va_atime.ts_sec != VNOVAL || vap->va_mtime.ts_sec != VNOVAL) {
                if (cred->cr_uid != ip->i_uid &&
                    (error = suser(cred, &p->p_acflag)))
                        return (error);
                if (cred->cr_uid != ip->i_uid &&
                    (error = suser(cred, &p->p_acflag)))
                        return (error);
-               if (vap->va_atime.tv_sec != VNOVAL)
+               if (vap->va_atime.ts_sec != VNOVAL)
                        ip->i_flag |= IACC;
                        ip->i_flag |= IACC;
-               if (vap->va_mtime.tv_sec != VNOVAL)
-                       ip->i_flag |= IUPD;
-               ip->i_flag |= ICHG;
-               if (error = VOP_UPDATE(vp, &vap->va_atime, &vap->va_mtime, 1))
+               if (vap->va_mtime.ts_sec != VNOVAL)
+                       ip->i_flag |= IUPD | ICHG;
+               atimeval.tv_sec = vap->va_atime.ts_sec;
+               atimeval.tv_usec = vap->va_atime.ts_nsec / 1000;
+               mtimeval.tv_sec = vap->va_mtime.ts_sec;
+               mtimeval.tv_usec = vap->va_mtime.ts_nsec / 1000;
+               if (error = VOP_UPDATE(vp, &atimeval, &mtimeval, 1))
                        return (error);
        }
        error = 0;
                        return (error);
        }
        error = 0;
@@ -457,7 +481,14 @@ good:
 /* ARGSUSED */
 int
 ufs_ioctl(ap)
 /* ARGSUSED */
 int
 ufs_ioctl(ap)
-       struct vop_ioctl_args *ap;
+       struct vop_ioctl_args /* {
+               struct vnode *a_vp;
+               int  a_command;
+               caddr_t  a_data;
+               int  a_fflag;
+               struct ucred *a_cred;
+               struct proc *a_p;
+       } */ *ap;
 {
 
        return (ENOTTY);
 {
 
        return (ENOTTY);
@@ -466,7 +497,13 @@ ufs_ioctl(ap)
 /* ARGSUSED */
 int
 ufs_select(ap)
 /* ARGSUSED */
 int
 ufs_select(ap)
-       struct vop_select_args *ap;
+       struct vop_select_args /* {
+               struct vnode *a_vp;
+               int  a_which;
+               int  a_fflags;
+               struct ucred *a_cred;
+               struct proc *a_p;
+       } */ *ap;
 {
 
        /*
 {
 
        /*
@@ -483,7 +520,12 @@ ufs_select(ap)
 /* ARGSUSED */
 int
 ufs_mmap(ap)
 /* ARGSUSED */
 int
 ufs_mmap(ap)
-       struct vop_mmap_args *ap;
+       struct vop_mmap_args /* {
+               struct vnode *a_vp;
+               int  a_fflags;
+               struct ucred *a_cred;
+               struct proc *a_p;
+       } */ *ap;
 {
 
        return (EINVAL);
 {
 
        return (EINVAL);
@@ -497,7 +539,12 @@ ufs_mmap(ap)
 /* ARGSUSED */
 int
 ufs_seek(ap)
 /* ARGSUSED */
 int
 ufs_seek(ap)
-       struct vop_seek_args *ap;
+       struct vop_seek_args /* {
+               struct vnode *a_vp;
+               off_t  a_oldoff;
+               off_t  a_newoff;
+               struct ucred *a_cred;
+       } */ *ap;
 {
 
        return (0);
 {
 
        return (0);
@@ -510,7 +557,11 @@ ufs_seek(ap)
  */
 int
 ufs_remove(ap)
  */
 int
 ufs_remove(ap)
-       struct vop_remove_args *ap;
+       struct vop_remove_args /* {
+               struct vnode *a_dvp;
+               struct vnode *a_vp;
+               struct componentname *a_cnp;
+       } */ *ap;
 {
        register struct inode *ip, *dp;
        int error;
 {
        register struct inode *ip, *dp;
        int error;
@@ -535,14 +586,17 @@ ufs_remove(ap)
  */
 int
 ufs_link(ap)
  */
 int
 ufs_link(ap)
-       struct vop_link_args *ap;
+       struct vop_link_args /* {
+               struct vnode *a_vp;
+               struct vnode *a_tdvp;
+               struct componentname *a_cnp;
+       } */ *ap;
 {
 {
-       USES_VOP_UPDATE;
-       USES_VOP_ABORTOP;
        register struct vnode *vp = ap->a_vp;
        register struct vnode *tdvp = ap->a_tdvp;
        register struct componentname *cnp = ap->a_cnp;
        register struct inode *ip;
        register struct vnode *vp = ap->a_vp;
        register struct vnode *tdvp = ap->a_tdvp;
        register struct componentname *cnp = ap->a_cnp;
        register struct inode *ip;
+       struct timeval tv;
        int error;
 
        if (vp->v_mount != tdvp->v_mount) {
        int error;
 
        if (vp->v_mount != tdvp->v_mount) {
@@ -567,7 +621,8 @@ ufs_link(ap)
                ILOCK(ip);
        ip->i_nlink++;
        ip->i_flag |= ICHG;
                ILOCK(ip);
        ip->i_nlink++;
        ip->i_flag |= ICHG;
-       error = VOP_UPDATE(tdvp, &time, &time, 1);
+       tv = time;
+       error = VOP_UPDATE(tdvp, &tv, &tv, 1);
        if (!error)
                error = ufs_direnter(ip, vp, cnp);
        if (vp != tdvp)
        if (!error)
                error = ufs_direnter(ip, vp, cnp);
        if (vp != tdvp)
@@ -592,9 +647,6 @@ relookup(dvp, vpp, cnp)
        struct vnode *dvp, **vpp;
        struct componentname *cnp;
 {
        struct vnode *dvp, **vpp;
        struct componentname *cnp;
 {
-       USES_VOP_LOCK;
-       USES_VOP_LOOKUP;
-       USES_VOP_UNLOCK;
        register struct vnode *dp = 0;  /* the directory we are searching */
        struct vnode *tdp;              /* saved dp */
        struct mount *mp;               /* mount table entry */
        register struct vnode *dp = 0;  /* the directory we are searching */
        struct vnode *tdp;              /* saved dp */
        struct mount *mp;               /* mount table entry */
@@ -766,14 +818,15 @@ bad:
  */
 int
 ufs_rename(ap)
  */
 int
 ufs_rename(ap)
-       struct vop_rename_args *ap;
+       struct vop_rename_args  /* {
+               struct vnode *a_fdvp;
+               struct vnode *a_fvp;
+               struct componentname *a_fcnp;
+               struct vnode *a_tdvp;
+               struct vnode *a_tvp;
+               struct componentname *a_tcnp;
+       } */ *ap;
 {
 {
-       USES_VOP_ABORTOP;
-       USES_VOP_ACCESS;
-       USES_VOP_LOCK;
-       USES_VOP_TRUNCATE;
-       USES_VOP_UNLOCK;
-       USES_VOP_UPDATE;
        struct vnode *tvp = ap->a_tvp;
        register struct vnode *tdvp = ap->a_tdvp;
        struct vnode *fvp = ap->a_fvp;
        struct vnode *tvp = ap->a_tvp;
        register struct vnode *tdvp = ap->a_tdvp;
        struct vnode *fvp = ap->a_fvp;
@@ -782,9 +835,11 @@ ufs_rename(ap)
        register struct componentname *fcnp = ap->a_fcnp;
        register struct inode *ip, *xp, *dp;
        struct dirtemplate dirbuf;
        register struct componentname *fcnp = ap->a_fcnp;
        register struct inode *ip, *xp, *dp;
        struct dirtemplate dirbuf;
+       struct timeval tv;
        int doingdirectory = 0, oldparent = 0, newparent = 0;
        int error = 0;
        int fdvpneedsrele = 1, tdvpneedsrele = 1;
        int doingdirectory = 0, oldparent = 0, newparent = 0;
        int error = 0;
        int fdvpneedsrele = 1, tdvpneedsrele = 1;
+       u_char namlen;
 
        /* Check for cross-device rename */
        if ((fvp->v_mount != tdvp->v_mount) ||
 
        /* Check for cross-device rename */
        if ((fvp->v_mount != tdvp->v_mount) ||
@@ -856,7 +911,8 @@ ufs_rename(ap)
         */
        ip->i_nlink++;
        ip->i_flag |= ICHG;
         */
        ip->i_nlink++;
        ip->i_flag |= ICHG;
-       error = VOP_UPDATE(fvp, &time, &time, 1);
+       tv = time;
+       error = VOP_UPDATE(fvp, &tv, &tv, 1);
        IUNLOCK(ip);
 
        /*
        IUNLOCK(ip);
 
        /*
@@ -921,14 +977,14 @@ ufs_rename(ap)
                        }
                        dp->i_nlink++;
                        dp->i_flag |= ICHG;
                        }
                        dp->i_nlink++;
                        dp->i_flag |= ICHG;
-                       if (error = VOP_UPDATE(ITOV(dp), &time, &time, 1))
+                       if (error = VOP_UPDATE(ITOV(dp), &tv, &tv, 1))
                                goto bad;
                }
                if (error = ufs_direnter(ip, tdvp, tcnp)) {
                        if (doingdirectory && newparent) {
                                dp->i_nlink--;
                                dp->i_flag |= ICHG;
                                goto bad;
                }
                if (error = ufs_direnter(ip, tdvp, tcnp)) {
                        if (doingdirectory && newparent) {
                                dp->i_nlink--;
                                dp->i_flag |= ICHG;
-                               (void)VOP_UPDATE(ITOV(dp), &time, &time, 1);
+                               (void)VOP_UPDATE(ITOV(dp), &tv, &tv, 1);
                        }
                        goto bad;
                }
                        }
                        goto bad;
                }
@@ -1001,7 +1057,7 @@ ufs_rename(ap)
                        if (--xp->i_nlink != 0)
                                panic("rename: linked directory");
                        error = VOP_TRUNCATE(ITOV(xp), (off_t)0, IO_SYNC,
                        if (--xp->i_nlink != 0)
                                panic("rename: linked directory");
                        error = VOP_TRUNCATE(ITOV(xp), (off_t)0, IO_SYNC,
-                           tcnp->cn_cred);
+                           tcnp->cn_cred, tcnp->cn_proc);
                }
                xp->i_flag |= ICHG;
                ufs_iput(xp);
                }
                xp->i_flag |= ICHG;
                ufs_iput(xp);
@@ -1058,7 +1114,15 @@ unlinkit:
                                UIO_SYSSPACE, IO_NODELOCKED, 
                                tcnp->cn_cred, (int *)0, (struct proc *)0);
                        if (error == 0) {
                                UIO_SYSSPACE, IO_NODELOCKED, 
                                tcnp->cn_cred, (int *)0, (struct proc *)0);
                        if (error == 0) {
-                               if (dirbuf.dotdot_namlen != 2 ||
+#                              if (BYTE_ORDER == LITTLE_ENDIAN)
+                                       if (fvp->v_mount->mnt_maxsymlinklen <= 0)
+                                               namlen = dirbuf.dotdot_type;
+                                       else
+                                               namlen = dirbuf.dotdot_namlen;
+#                              else
+                                       namlen = dirbuf.dotdot_namlen;
+#                              endif
+                               if (namlen != 2 ||
                                    dirbuf.dotdot_name[0] != '.' ||
                                    dirbuf.dotdot_name[1] != '.') {
                                        ufs_dirbad(xp, (doff_t)12,
                                    dirbuf.dotdot_name[0] != '.' ||
                                    dirbuf.dotdot_name[1] != '.') {
                                        ufs_dirbad(xp, (doff_t)12,
@@ -1105,6 +1169,10 @@ out:
  * A virgin directory (no blushing please).
  */
 static struct dirtemplate mastertemplate = {
  * A virgin directory (no blushing please).
  */
 static struct dirtemplate mastertemplate = {
+       0, 12, DT_DIR, 1, ".",
+       0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
+};
+static struct odirtemplate omastertemplate = {
        0, 12, 1, ".",
        0, DIRBLKSIZ - 12, 2, ".."
 };
        0, 12, 1, ".",
        0, DIRBLKSIZ - 12, 2, ".."
 };
@@ -1114,20 +1182,21 @@ static struct dirtemplate mastertemplate = {
  */
 int
 ufs_mkdir(ap)
  */
 int
 ufs_mkdir(ap)
-       struct vop_mkdir_args *ap;
+       struct vop_mkdir_args /* {
+               struct vnode *a_dvp;
+               struct vnode **a_vpp;
+               struct componentname *a_cnp;
+               struct vattr *a_vap;
+       } */ *ap;
 {
 {
-       USES_VOP_TRUNCATE;
-       USES_VOP_UPDATE;
-       USES_VOP_VALLOC;
-       USES_VOP_VFREE;
        register struct vnode *dvp = ap->a_dvp;
        register struct vattr *vap = ap->a_vap;
        register struct componentname *cnp = ap->a_cnp;
        register struct inode *ip, *dp;
        struct vnode *tvp;
        register struct vnode *dvp = ap->a_dvp;
        register struct vattr *vap = ap->a_vap;
        register struct componentname *cnp = ap->a_cnp;
        register struct inode *ip, *dp;
        struct vnode *tvp;
-       struct dirtemplate dirtemplate;
-       int error;
-       int dmode;
+       struct dirtemplate dirtemplate, *dtp;
+       struct timeval tv;
+       int error, dmode;
 
 #ifdef DIAGNOSTIC
        if ((cnp->cn_flags & HASBUF) == 0)
 
 #ifdef DIAGNOSTIC
        if ((cnp->cn_flags & HASBUF) == 0)
@@ -1168,7 +1237,8 @@ ufs_mkdir(ap)
        ip->i_mode = dmode;
        ITOV(ip)->v_type = VDIR;        /* Rest init'd in iget() */
        ip->i_nlink = 2;
        ip->i_mode = dmode;
        ITOV(ip)->v_type = VDIR;        /* Rest init'd in iget() */
        ip->i_nlink = 2;
-       error = VOP_UPDATE(ITOV(ip), &time, &time, 1);
+       tv = time;
+       error = VOP_UPDATE(ITOV(ip), &tv, &tv, 1);
 
        /*
         * Bump link count in parent directory
 
        /*
         * Bump link count in parent directory
@@ -1178,11 +1248,15 @@ ufs_mkdir(ap)
         */
        dp->i_nlink++;
        dp->i_flag |= ICHG;
         */
        dp->i_nlink++;
        dp->i_flag |= ICHG;
-       if (error = VOP_UPDATE(ITOV(dp), &time, &time, 1))
+       if (error = VOP_UPDATE(ITOV(dp), &tv, &tv, 1))
                goto bad;
 
        /* Initialize directory with "." and ".." from static template. */
                goto bad;
 
        /* Initialize directory with "." and ".." from static template. */
-       dirtemplate = mastertemplate;
+       if (dvp->v_mount->mnt_maxsymlinklen > 0)
+               dtp = &mastertemplate;
+       else
+               dtp = (struct dirtemplate *)&omastertemplate;
+       dirtemplate = *dtp;
        dirtemplate.dot_ino = ip->i_number;
        dirtemplate.dotdot_ino = dp->i_number;
        error = vn_rdwr(UIO_WRITE, ITOV(ip), (caddr_t)&dirtemplate,
        dirtemplate.dot_ino = ip->i_number;
        dirtemplate.dotdot_ino = dp->i_number;
        error = vn_rdwr(UIO_WRITE, ITOV(ip), (caddr_t)&dirtemplate,
@@ -1226,9 +1300,12 @@ bad:
  */
 int
 ufs_rmdir(ap)
  */
 int
 ufs_rmdir(ap)
-       struct vop_rmdir_args *ap;
+       struct vop_rmdir_args /* {
+               struct vnode *a_dvp;
+               struct vnode *a_vp;
+               struct componentname *a_cnp;
+       } */ *ap;
 {
 {
-       USES_VOP_TRUNCATE;
        register struct vnode *dvp = ap->a_dvp;
        register struct componentname *cnp = ap->a_cnp;
        register struct inode *ip, *dp;
        register struct vnode *dvp = ap->a_dvp;
        register struct componentname *cnp = ap->a_cnp;
        register struct inode *ip, *dp;
@@ -1281,7 +1358,8 @@ ufs_rmdir(ap)
         * worry about them later.
         */
        ip->i_nlink -= 2;
         * worry about them later.
         */
        ip->i_nlink -= 2;
-       error = VOP_TRUNCATE(ap->a_vp, (off_t)0, IO_SYNC, cnp->cn_cred);
+       error = VOP_TRUNCATE(ap->a_vp, (off_t)0, IO_SYNC, cnp->cn_cred,
+           cnp->cn_proc);
        cache_purge(ITOV(ip));
 out:
        if (dvp)
        cache_purge(ITOV(ip));
 out:
        if (dvp)
@@ -1295,18 +1373,33 @@ out:
  */
 int
 ufs_symlink(ap)
  */
 int
 ufs_symlink(ap)
-       struct vop_symlink_args *ap;
+       struct vop_symlink_args /* {
+               struct vnode *a_dvp;
+               struct vnode **a_vpp;
+               struct componentname *a_cnp;
+               struct vattr *a_vap;
+               char *a_target;
+       } */ *ap;
 {
 {
-       register struct vnode **vpp = ap->a_vpp;
-       int error;
+       register struct vnode *vp, **vpp = ap->a_vpp;
+       register struct inode *ip;
+       int len, error;
 
        if (error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
            vpp, ap->a_cnp))
                return (error);
 
        if (error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
            vpp, ap->a_cnp))
                return (error);
-       error = vn_rdwr(UIO_WRITE, *vpp, ap->a_target, strlen(ap->a_target),
-           (off_t)0, UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred,
-           (int *)0, (struct proc *)0);
-       vput(*vpp);
+       vp = *vpp;
+       len = strlen(ap->a_target);
+       if (len < vp->v_mount->mnt_maxsymlinklen) {
+               ip = VTOI(vp);
+               bcopy(ap->a_target, (char *)ip->i_shortlink, len);
+               ip->i_size = len;
+               ip->i_flag |= IUPD|ICHG;
+       } else
+               error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
+                   UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred, (int *)0,
+                   (struct proc *)0);
+       vput(vp);
        return (error);
 }
 
        return (error);
 }
 
@@ -1321,9 +1414,12 @@ ufs_symlink(ap)
  */
 int
 ufs_readdir(ap)
  */
 int
 ufs_readdir(ap)
-       struct vop_readdir_args *ap;
+       struct vop_readdir_args /* {
+               struct vnode *a_vp;
+               struct uio *a_uio;
+               struct ucred *a_cred;
+       } */ *ap;
 {
 {
-       USES_VOP_READ;
        register struct uio *uio = ap->a_uio;
        int count, lost, error;
 
        register struct uio *uio = ap->a_uio;
        int count, lost, error;
 
@@ -1334,12 +1430,49 @@ ufs_readdir(ap)
                return (EINVAL);
        uio->uio_resid = count;
        uio->uio_iov->iov_len = count;
                return (EINVAL);
        uio->uio_resid = count;
        uio->uio_iov->iov_len = count;
-       error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
+#      if (BYTE_ORDER == LITTLE_ENDIAN)
+               if (ap->a_vp->v_mount->mnt_maxsymlinklen > 0) {
+                       error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
+               } else {
+                       struct dirent *dp, *edp;
+                       struct uio auio;
+                       struct iovec aiov;
+                       caddr_t dirbuf;
+                       int readcnt;
+                       u_char tmp;
+
+                       auio = *uio;
+                       auio.uio_iov = &aiov;
+                       auio.uio_iovcnt = 1;
+                       auio.uio_segflg = UIO_SYSSPACE;
+                       aiov.iov_len = count;
+                       MALLOC(dirbuf, caddr_t, count, M_TEMP, M_WAITOK);
+                       aiov.iov_base = dirbuf;
+                       error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred);
+                       if (error == 0) {
+                               readcnt = count - auio.uio_resid;
+                               edp = (struct dirent *)&dirbuf[readcnt];
+                               for (dp = (struct dirent *)dirbuf; dp < edp; ) {
+                                       tmp = dp->d_namlen;
+                                       dp->d_namlen = dp->d_type;
+                                       dp->d_type = tmp;
+                                       if (dp->d_reclen > 0) {
+                                               dp = (struct dirent *)
+                                                   ((char *)dp + dp->d_reclen);
+                                       } else {
+                                               error = EIO;
+                                               break;
+                                       }
+                               }
+                               if (dp >= edp)
+                                       error = uiomove(dirbuf, readcnt, uio);
+                       }
+                       FREE(dirbuf, M_TEMP);
+               }
+#      else
+               error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
+#      endif
        uio->uio_resid += lost;
        uio->uio_resid += lost;
-       if ((VTOI(ap->a_vp)->i_size - uio->uio_offset) <= 0)
-               *ap->a_eofflagp = 1;
-       else
-               *ap->a_eofflagp = 0;
        return (error);
 }
 
        return (error);
 }
 
@@ -1348,11 +1481,22 @@ ufs_readdir(ap)
  */
 int
 ufs_readlink(ap)
  */
 int
 ufs_readlink(ap)
-       struct vop_readlink_args *ap;
+       struct vop_readlink_args /* {
+               struct vnode *a_vp;
+               struct uio *a_uio;
+               struct ucred *a_cred;
+       } */ *ap;
 {
 {
-       USES_VOP_READ;
+       register struct vnode *vp = ap->a_vp;
+       register struct inode *ip = VTOI(vp);
+       int isize;
 
 
-       return (VOP_READ(ap->a_vp, ap->a_uio, 0, ap->a_cred));
+       isize = ip->i_size;
+       if (isize < vp->v_mount->mnt_maxsymlinklen) {
+               uiomove((char *)ip->i_shortlink, isize, ap->a_uio);
+               return (0);
+       }
+       return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred));
 }
 
 /*
 }
 
 /*
@@ -1362,7 +1506,10 @@ ufs_readlink(ap)
 /* ARGSUSED */
 int
 ufs_abortop(ap)
 /* ARGSUSED */
 int
 ufs_abortop(ap)
-       struct vop_abortop_args *ap;
+       struct vop_abortop_args /* {
+               struct vnode *a_dvp;
+               struct componentname *a_cnp;
+       } */ *ap;
 {
        if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
                FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
 {
        if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
                FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
@@ -1374,7 +1521,9 @@ ufs_abortop(ap)
  */
 int
 ufs_lock(ap)
  */
 int
 ufs_lock(ap)
-       struct vop_lock_args *ap;
+       struct vop_lock_args /* {
+               struct vnode *a_vp;
+       } */ *ap;
 {
        register struct inode *ip = VTOI(ap->a_vp);
 
 {
        register struct inode *ip = VTOI(ap->a_vp);
 
@@ -1387,7 +1536,9 @@ ufs_lock(ap)
  */
 int
 ufs_unlock(ap)
  */
 int
 ufs_unlock(ap)
-       struct vop_unlock_args *ap;
+       struct vop_unlock_args /* {
+               struct vnode *a_vp;
+       } */ *ap;
 {
        register struct inode *ip = VTOI(ap->a_vp);
 
 {
        register struct inode *ip = VTOI(ap->a_vp);
 
@@ -1402,7 +1553,9 @@ ufs_unlock(ap)
  */
 int
 ufs_islocked(ap)
  */
 int
 ufs_islocked(ap)
-       struct vop_islocked_args *ap;
+       struct vop_islocked_args /* {
+               struct vnode *a_vp;
+       } */ *ap;
 {
 
        if (VTOI(ap->a_vp)->i_flag & ILOCKED)
 {
 
        if (VTOI(ap->a_vp)->i_flag & ILOCKED)
@@ -1416,9 +1569,10 @@ ufs_islocked(ap)
  */
 int
 ufs_strategy(ap)
  */
 int
 ufs_strategy(ap)
-       struct vop_strategy_args *ap;
+       struct vop_strategy_args /* {
+               struct buf *a_bp;
+       } */ *ap;
 {
 {
-       USES_VOP_BMAP;
        register struct buf *bp = ap->a_bp;
        register struct vnode *vp = bp->b_vp;
        register struct inode *ip;
        register struct buf *bp = ap->a_bp;
        register struct vnode *vp = bp->b_vp;
        register struct inode *ip;
@@ -1429,7 +1583,7 @@ ufs_strategy(ap)
                panic("ufs_strategy: spec");
        if (bp->b_blkno == bp->b_lblkno) {
                if (error =
                panic("ufs_strategy: spec");
        if (bp->b_blkno == bp->b_lblkno) {
                if (error =
-                   VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno)) {
+                   VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL)) {
                        bp->b_error = error;
                        bp->b_flags |= B_ERROR;
                        biodone(bp);
                        bp->b_error = error;
                        bp->b_flags |= B_ERROR;
                        biodone(bp);
@@ -1453,7 +1607,9 @@ ufs_strategy(ap)
  */
 int
 ufs_print(ap)
  */
 int
 ufs_print(ap)
-       struct vop_print_args *ap;
+       struct vop_print_args /* {
+               struct vnode *a_vp;
+       } */ *ap;
 {
        register struct vnode *vp = ap->a_vp;
        register struct inode *ip = VTOI(vp);
 {
        register struct vnode *vp = ap->a_vp;
        register struct inode *ip = VTOI(vp);
@@ -1479,9 +1635,13 @@ ufs_print(ap)
  */
 int
 ufsspec_read(ap)
  */
 int
 ufsspec_read(ap)
-       struct vop_read_args *ap;
+       struct vop_read_args /* {
+               struct vnode *a_vp;
+               struct uio *a_uio;
+               int  a_ioflag;
+               struct ucred *a_cred;
+       } */ *ap;
 {
 {
-       extern int (**spec_vnodeop_p)();
 
        /*
         * Set access flag.
 
        /*
         * Set access flag.
@@ -1495,9 +1655,13 @@ ufsspec_read(ap)
  */
 int
 ufsspec_write(ap)
  */
 int
 ufsspec_write(ap)
-       struct vop_write_args *ap;
+       struct vop_write_args /* {
+               struct vnode *a_vp;
+               struct uio *a_uio;
+               int  a_ioflag;
+               struct ucred *a_cred;
+       } */ *ap;
 {
 {
-       extern int (**spec_vnodeop_p)();
 
        /*
         * Set update and change flags.
 
        /*
         * Set update and change flags.
@@ -1513,9 +1677,13 @@ ufsspec_write(ap)
  */
 int
 ufsspec_close(ap)
  */
 int
 ufsspec_close(ap)
-       struct vop_close_args *ap;
+       struct vop_close_args /* {
+               struct vnode *a_vp;
+               int  a_fflag;
+               struct ucred *a_cred;
+               struct proc *a_p;
+       } */ *ap;
 {
 {
-       extern int (**spec_vnodeop_p)();
        register struct inode *ip = VTOI(ap->a_vp);
 
        if (ap->a_vp->v_usecount > 1 && !(ip->i_flag & ILOCKED))
        register struct inode *ip = VTOI(ap->a_vp);
 
        if (ap->a_vp->v_usecount > 1 && !(ip->i_flag & ILOCKED))
@@ -1529,7 +1697,12 @@ ufsspec_close(ap)
  */
 int
 ufsfifo_read(ap)
  */
 int
 ufsfifo_read(ap)
-       struct vop_read_args *ap;
+       struct vop_read_args /* {
+               struct vnode *a_vp;
+               struct uio *a_uio;
+               int  a_ioflag;
+               struct ucred *a_cred;
+       } */ *ap;
 {
        extern int (**fifo_vnodeop_p)();
 
 {
        extern int (**fifo_vnodeop_p)();
 
@@ -1545,7 +1718,12 @@ ufsfifo_read(ap)
  */
 int
 ufsfifo_write(ap)
  */
 int
 ufsfifo_write(ap)
-       struct vop_write_args *ap;
+       struct vop_write_args /* {
+               struct vnode *a_vp;
+               struct uio *a_uio;
+               int  a_ioflag;
+               struct ucred *a_cred;
+       } */ *ap;
 {
        extern int (**fifo_vnodeop_p)();
 
 {
        extern int (**fifo_vnodeop_p)();
 
@@ -1562,7 +1740,12 @@ ufsfifo_write(ap)
  * Update the times on the inode then do device close.
  */
 ufsfifo_close(ap)
  * Update the times on the inode then do device close.
  */
 ufsfifo_close(ap)
-       struct vop_close_args *ap;
+       struct vop_close_args /* {
+               struct vnode *a_vp;
+               int  a_fflag;
+               struct ucred *a_cred;
+               struct proc *a_p;
+       } */ *ap;
 {
        extern int (**fifo_vnodeop_p)();
        register struct inode *ip = VTOI(ap->a_vp);
 {
        extern int (**fifo_vnodeop_p)();
        register struct inode *ip = VTOI(ap->a_vp);
@@ -1578,7 +1761,13 @@ ufsfifo_close(ap)
  */
 int
 ufs_advlock(ap)
  */
 int
 ufs_advlock(ap)
-       struct vop_advlock_args *ap;
+       struct vop_advlock_args /* {
+               struct vnode *a_vp;
+               caddr_t  a_id;
+               int  a_op;
+               struct flock *a_fl;
+               int  a_flags;
+       } */ *ap;
 {
        register struct inode *ip = VTOI(ap->a_vp);
        register struct flock *fl = ap->a_fl;
 {
        register struct inode *ip = VTOI(ap->a_vp);
        register struct flock *fl = ap->a_fl;
@@ -1669,9 +1858,8 @@ ufs_vinit(mntp, specops, fifoops, vpp)
        int (**fifoops)();
        struct vnode **vpp;
 {
        int (**fifoops)();
        struct vnode **vpp;
 {
-       struct inode *ip, *nip;
+       struct inode *ip;
        struct vnode *vp, *nvp;
        struct vnode *vp, *nvp;
-       extern int (**spec_vnodeop_p)();
 
        vp = *vpp;
        ip = VTOI(vp);
 
        vp = *vpp;
        ip = VTOI(vp);
@@ -1683,7 +1871,7 @@ ufs_vinit(mntp, specops, fifoops, vpp)
                        /*
                         * Discard unneeded vnode, but save its inode.
                         */
                        /*
                         * Discard unneeded vnode, but save its inode.
                         */
-                       remque(ip);
+                       ufs_ihashrem(ip);
                        IUNLOCK(ip);
                        nvp->v_data = vp->v_data;
                        vp->v_data = NULL;
                        IUNLOCK(ip);
                        nvp->v_data = vp->v_data;
                        vp->v_data = NULL;
@@ -1727,10 +1915,8 @@ ufs_makeinode(mode, dvp, vpp, cnp)
        struct vnode **vpp;
        struct componentname *cnp;
 {
        struct vnode **vpp;
        struct componentname *cnp;
 {
-       USES_VOP_UPDATE;
-       USES_VOP_VALLOC;
-       USES_VOP_VFREE;
        register struct inode *ip, *pdir;
        register struct inode *ip, *pdir;
+       struct timeval tv;
        struct vnode *tvp;
        int error;
 
        struct vnode *tvp;
        int error;
 
@@ -1772,7 +1958,8 @@ ufs_makeinode(mode, dvp, vpp, cnp)
        /*
         * Make sure inode goes to disk before directory entry.
         */
        /*
         * Make sure inode goes to disk before directory entry.
         */
-       if (error = VOP_UPDATE(tvp, &time, &time, 1))
+       tv = time;
+       if (error = VOP_UPDATE(tvp, &tv, &tv, 1))
                goto bad;
        if (error = ufs_direnter(ip, dvp, cnp))
                goto bad;
                goto bad;
        if (error = ufs_direnter(ip, dvp, cnp))
                goto bad;