BSD 4_3_Reno release
[unix-history] / usr / src / sys / nfs / nfs_subs.c
index e246d30..b2344f4 100644 (file)
@@ -5,19 +5,22 @@
  * This code is derived from software contributed to Berkeley by
  * Rick Macklem at The University of Guelph.
  *
  * This code is derived from software contributed to Berkeley by
  * Rick Macklem at The University of Guelph.
  *
- * 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.
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement:  This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software.  Neither the name of the University nor the names of
+ * its contributors may 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.
  *
  *
- *     @(#)nfs_subs.c  7.24 (Berkeley) %G%
+ *     @(#)nfs_subs.c  7.29 (Berkeley) 7/26/90
  */
 
 /*
  */
 
 /*
@@ -61,7 +64,7 @@ static u_long *rpc_uidp = (u_long *)0;
 static u_long nfs_xid = 1;
 static char *rpc_unixauth;
 extern long hostid;
 static u_long nfs_xid = 1;
 static char *rpc_unixauth;
 extern long hostid;
-extern enum vtype v_type[NFLNK+1];
+enum vtype ntov_type[7] = { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON };
 extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON];
 extern struct map nfsmap[NFS_MSIZ];
 extern struct nfsreq nfsreqh;
 extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON];
 extern struct map nfsmap[NFS_MSIZ];
 extern struct nfsreq nfsreqh;
@@ -73,7 +76,7 @@ static char *nfs_unixauth();
  * Maximum number of groups passed through to NFS server.
  * According to RFC1057 it should be 16.
  * For release 3.X systems, the maximum value is 8.
  * Maximum number of groups passed through to NFS server.
  * According to RFC1057 it should be 16.
  * For release 3.X systems, the maximum value is 8.
- * For release 4.X systems, the maximum value is 10.
+ * For some other servers, the maximum value is 10.
  */
 int numgrps = 8;
 
  */
 int numgrps = 8;
 
@@ -102,7 +105,8 @@ struct mbuf *nfsm_reqh(prog, vers, procid, cred, hsiz, bpos, mb, retxid)
        int asiz, siz;
 
        NFSMGETHDR(mreq);
        int asiz, siz;
 
        NFSMGETHDR(mreq);
-       asiz = (((cred->cr_ngroups > numgrps) ? numgrps : cred->cr_ngroups)<<2);
+       asiz = ((((cred->cr_ngroups - 1) > numgrps) ? numgrps :
+                 (cred->cr_ngroups - 1)) << 2);
 #ifdef FILLINHOST
        asiz += nfsm_rndup(hostnamelen)+(9*NFSX_UNSIGNED);
 #else
 #ifdef FILLINHOST
        asiz += nfsm_rndup(hostnamelen)+(9*NFSX_UNSIGNED);
 #else
@@ -166,13 +170,13 @@ struct mbuf *nfsm_reqh(prog, vers, procid, cred, hsiz, bpos, mb, retxid)
  */
 nfsm_mbuftouio(mrep, uiop, siz, dpos)
        struct mbuf **mrep;
  */
 nfsm_mbuftouio(mrep, uiop, siz, dpos)
        struct mbuf **mrep;
-       struct uio *uiop;
+       register struct uio *uiop;
        int siz;
        caddr_t *dpos;
 {
        int siz;
        caddr_t *dpos;
 {
+       register char *mbufcp, *uiocp;
        register int xfer, left, len;
        register struct mbuf *mp;
        register int xfer, left, len;
        register struct mbuf *mp;
-       register char *mbufcp, *uiocp;
        long uiosiz, rem;
        int error = 0;
 
        long uiosiz, rem;
        int error = 0;
 
@@ -244,12 +248,11 @@ nfsm_uiotombuf(uiop, mq, siz, bpos)
        int siz;
        caddr_t *bpos;
 {
        int siz;
        caddr_t *bpos;
 {
-       register struct mbuf *mp;
-       struct mbuf *mp2;
-       long xfer, left, uiosiz;
-       int clflg;
-       int rem, len;
-       char *cp, *uiocp;
+       register char *uiocp;
+       register struct mbuf *mp, *mp2;
+       register int xfer, left, len;
+       int uiosiz, clflg, rem;
+       char *cp;
 
        if (siz > MLEN)         /* or should it >= MCLBYTES ?? */
                clflg = 1;
 
        if (siz > MLEN)         /* or should it >= MCLBYTES ?? */
                clflg = 1;
@@ -504,12 +507,6 @@ nfs_init()
        /* Ensure async daemons disabled */
        for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
                nfs_iodwant[i] = (struct proc *)0;
        /* Ensure async daemons disabled */
        for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
                nfs_iodwant[i] = (struct proc *)0;
-       v_type[0] = VNON;
-       v_type[1] = VREG;
-       v_type[2] = VDIR;
-       v_type[3] = VBLK;
-       v_type[4] = VCHR;
-       v_type[5] = VLNK;
        nfs_xdrneg1 = txdr_unsigned(-1);
        nfs_nhinit();                   /* Init the nfsnode table */
        nfsrv_initcache();              /* Init the server request cache */
        nfs_xdrneg1 = txdr_unsigned(-1);
        nfs_nhinit();                   /* Init the nfsnode table */
        nfsrv_initcache();              /* Init the server request cache */
@@ -535,9 +532,9 @@ static char *nfs_unixauth(cr)
        /* Maybe someday there should be a cache of AUTH_SHORT's */
        if ((p = rpc_uidp) == NULL) {
 #ifdef FILLINHOST
        /* Maybe someday there should be a cache of AUTH_SHORT's */
        if ((p = rpc_uidp) == NULL) {
 #ifdef FILLINHOST
-               i = nfsm_rndup(hostnamelen)+(19*NFSX_UNSIGNED);
+               i = nfsm_rndup(hostnamelen)+(25*NFSX_UNSIGNED);
 #else
 #else
-               i = 19*NFSX_UNSIGNED;
+               i = 25*NFSX_UNSIGNED;
 #endif
                MALLOC(p, u_long *, i, M_TEMP, M_WAITOK);
                bzero((caddr_t)p, i);
 #endif
                MALLOC(p, u_long *, i, M_TEMP, M_WAITOK);
                bzero((caddr_t)p, i);
@@ -557,9 +554,9 @@ static char *nfs_unixauth(cr)
        }
        *p++ = txdr_unsigned(cr->cr_uid);
        *p++ = txdr_unsigned(cr->cr_groups[0]);
        }
        *p++ = txdr_unsigned(cr->cr_uid);
        *p++ = txdr_unsigned(cr->cr_groups[0]);
-       ngr = (cr->cr_ngroups > numgrps) ? numgrps : cr->cr_ngroups;
+       ngr = ((cr->cr_ngroups - 1) > numgrps) ? numgrps : (cr->cr_ngroups - 1);
        *p++ = txdr_unsigned(ngr);
        *p++ = txdr_unsigned(ngr);
-       for (i = 0; i < ngr; i++)
+       for (i = 1; i <= ngr; i++)
                *p++ = txdr_unsigned(cr->cr_groups[i]);
        /* And add the AUTH_NULL */
        *p++ = 0;
                *p++ = txdr_unsigned(cr->cr_groups[i]);
        /* And add the AUTH_NULL */
        *p++ = 0;
@@ -600,7 +597,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
        int error = 0;
        struct mbuf *md;
        enum vtype type;
        int error = 0;
        struct mbuf *md;
        enum vtype type;
-       dev_t rdev;
+       long rdev;
        struct timeval mtime;
        struct vnode *nvp;
 
        struct timeval mtime;
        struct vnode *nvp;
 
@@ -611,7 +608,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
                return (error);
        fp = (struct nfsv2_fattr *)cp2;
        type = nfstov_type(fp->fa_type);
                return (error);
        fp = (struct nfsv2_fattr *)cp2;
        type = nfstov_type(fp->fa_type);
-       rdev = fxdr_unsigned(dev_t, fp->fa_rdev);
+       rdev = fxdr_unsigned(long, fp->fa_rdev);
        fxdr_time(&fp->fa_mtime, &mtime);
        /*
         * If v_type == VNON it is a new node, so fill in the v_type,
        fxdr_time(&fp->fa_mtime, &mtime);
        /*
         * If v_type == VNON it is a new node, so fill in the v_type,
@@ -622,7 +619,10 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
         */
        np = VTONFS(vp);
        if (vp->v_type == VNON) {
         */
        np = VTONFS(vp);
        if (vp->v_type == VNON) {
-               vp->v_type = type;
+               if (type == VCHR && rdev == 0xffffffff)
+                       vp->v_type = type = VFIFO;
+               else
+                       vp->v_type = type;
                if (vp->v_type == VFIFO) {
 #ifdef FIFO
                        extern struct vnodeops fifo_nfsv2nodeops;
                if (vp->v_type == VFIFO) {
 #ifdef FIFO
                        extern struct vnodeops fifo_nfsv2nodeops;
@@ -633,7 +633,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
                }
                if (vp->v_type == VCHR || vp->v_type == VBLK) {
                        vp->v_op = &spec_nfsv2nodeops;
                }
                if (vp->v_type == VCHR || vp->v_type == VBLK) {
                        vp->v_op = &spec_nfsv2nodeops;
-                       if (nvp = checkalias(vp, rdev, vp->v_mount)) {
+                       if (nvp = checkalias(vp, (dev_t)rdev, vp->v_mount)) {
                                /*
                                 * Reinitialize aliased node.
                                 */
                                /*
                                 * Reinitialize aliased node.
                                 */
@@ -666,10 +666,10 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
                np->n_size = vap->va_size;
        vap->va_size_rsv = 0;
        vap->va_blocksize = fxdr_unsigned(long, fp->fa_blocksize);
                np->n_size = vap->va_size;
        vap->va_size_rsv = 0;
        vap->va_blocksize = fxdr_unsigned(long, fp->fa_blocksize);
-       vap->va_rdev = rdev;
-       vap->va_bytes = fxdr_unsigned(long, fp->fa_blocks) * vap->va_blocksize;
+       vap->va_rdev = (dev_t)rdev;
+       vap->va_bytes = fxdr_unsigned(long, fp->fa_blocks) * NFS_FABLKSIZE;
        vap->va_bytes_rsv = 0;
        vap->va_bytes_rsv = 0;
-       vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0] | 0x8000;
+       vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
        vap->va_fileid = fxdr_unsigned(long, fp->fa_fileid);
        vap->va_atime.tv_sec = fxdr_unsigned(long, fp->fa_atime.tv_sec);
        vap->va_atime.tv_usec = 0;
        vap->va_fileid = fxdr_unsigned(long, fp->fa_fileid);
        vap->va_atime.tv_sec = fxdr_unsigned(long, fp->fa_atime.tv_sec);
        vap->va_atime.tv_usec = 0;
@@ -732,46 +732,50 @@ nfs_namei(ndp, fhp, len, mdp, dposp)
        int flag;
        int error;
 
        int flag;
        int error;
 
-       flag = ndp->ni_nameiop & OPFLAG;
-       /*
-        * Copy the name from the mbuf list to the d_name field of ndp
-        * and set the various ndp fields appropriately.
-        */
-       cp = *dposp;
-       md = *mdp;
-       rem = mtod(md, caddr_t)+md->m_len-cp;
-       ndp->ni_hash = 0;
-       for (i = 0; i < len;) {
-               while (rem == 0) {
-                       md = md->m_next;
-                       if (md == NULL)
-                               return (EBADRPC);
-                       cp = mtod(md, caddr_t);
-                       rem = md->m_len;
-               }
-               if (*cp == '\0' || *cp == '/')
-                       return (EINVAL);
-               if (*cp & 0200)
-                       if ((*cp&0377) == ('/'|0200) || flag != DELETE)
+       if ((ndp->ni_nameiop & HASBUF) == 0) {
+               flag = ndp->ni_nameiop & OPFLAG;
+               /*
+                * Copy the name from the mbuf list to the d_name field of ndp
+                * and set the various ndp fields appropriately.
+                */
+               cp = *dposp;
+               md = *mdp;
+               rem = mtod(md, caddr_t)+md->m_len-cp;
+               ndp->ni_hash = 0;
+               for (i = 0; i < len;) {
+                       while (rem == 0) {
+                               md = md->m_next;
+                               if (md == NULL)
+                                       return (EBADRPC);
+                               cp = mtod(md, caddr_t);
+                               rem = md->m_len;
+                       }
+                       if (*cp == '\0' || *cp == '/')
                                return (EINVAL);
                                return (EINVAL);
-               ndp->ni_dent.d_name[i++] = *cp;
-               ndp->ni_hash += (unsigned char)*cp * i;
-               cp++;
-               rem--;
-       }
-       *mdp = md;
-       *dposp = cp;
-       len = nfsm_rndup(len)-len;
-       if (len > 0) {
-               if (rem < len) {
-                       if (error = nfs_adv(mdp, dposp, len, rem))
-                               return (error);
-               } else
-                       *dposp += len;
-       }
+                       if (*cp & 0200)
+                               if ((*cp&0377) == ('/'|0200) || flag != DELETE)
+                                       return (EINVAL);
+                       ndp->ni_dent.d_name[i++] = *cp;
+                       ndp->ni_hash += (unsigned char)*cp * i;
+                       cp++;
+                       rem--;
+               }
+               *mdp = md;
+               *dposp = cp;
+               len = nfsm_rndup(len)-len;
+               if (len > 0) {
+                       if (rem < len) {
+                               if (error = nfs_adv(mdp, dposp, len, rem))
+                                       return (error);
+                       } else
+                               *dposp += len;
+               }
+       } else
+               i = len;
        ndp->ni_namelen = i;
        ndp->ni_dent.d_namlen = i;
        ndp->ni_dent.d_name[i] = '\0';
        ndp->ni_namelen = i;
        ndp->ni_dent.d_namlen = i;
        ndp->ni_dent.d_name[i] = '\0';
+       ndp->ni_segflg = UIO_SYSSPACE;
        ndp->ni_pathlen = 1;
        ndp->ni_pnbuf = ndp->ni_dirp = ndp->ni_ptr = &ndp->ni_dent.d_name[0];
        ndp->ni_next = &ndp->ni_dent.d_name[i];
        ndp->ni_pathlen = 1;
        ndp->ni_pnbuf = ndp->ni_dirp = ndp->ni_ptr = &ndp->ni_dent.d_name[0];
        ndp->ni_next = &ndp->ni_dent.d_name[i];