BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / nfs / nfs_socket.c
index d853222..ff092d4 100644 (file)
@@ -1,46 +1,62 @@
 /*
 /*
- * Copyright (c) 1989 The Regents of the University of California.
+ * Copyright (c) 1989, 1991 The Regents of the University of California.
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Rick Macklem at The University of Guelph.
  *
  * All rights reserved.
  *
  * 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 and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. 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.
  *
  *
- *     @(#)nfs_socket.c        7.16 (Berkeley) %G%
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)nfs_socket.c        7.23 (Berkeley) 4/20/91
  */
 
 /*
  * Socket operations for use by nfs
  */
 
  */
 
 /*
  * Socket operations for use by nfs
  */
 
-#include "types.h"
 #include "param.h"
 #include "param.h"
-#include "uio.h"
-#include "user.h"
 #include "proc.h"
 #include "proc.h"
-#include "signal.h"
 #include "mount.h"
 #include "kernel.h"
 #include "malloc.h"
 #include "mbuf.h"
 #include "mount.h"
 #include "kernel.h"
 #include "malloc.h"
 #include "mbuf.h"
+#include "namei.h"
 #include "vnode.h"
 #include "domain.h"
 #include "protosw.h"
 #include "socket.h"
 #include "socketvar.h"
 #include "vnode.h"
 #include "domain.h"
 #include "protosw.h"
 #include "socket.h"
 #include "socketvar.h"
+#include "syslog.h"
+#include "tprintf.h"
 #include "../netinet/in.h"
 #include "../netinet/tcp.h"
 #include "../netinet/in.h"
 #include "../netinet/tcp.h"
+
 #include "rpcv2.h"
 #include "nfsv2.h"
 #include "nfs.h"
 #include "rpcv2.h"
 #include "nfsv2.h"
 #include "nfs.h"
@@ -48,9 +64,8 @@
 #include "nfsm_subs.h"
 #include "nfsmount.h"
 
 #include "nfsm_subs.h"
 #include "nfsmount.h"
 
-#include "syslog.h"
-
 #define        TRUE    1
 #define        TRUE    1
+#define        FALSE   0
 
 /*
  * External data, mostly RPC constants in XDR form
 
 /*
  * External data, mostly RPC constants in XDR form
 extern u_long rpc_reply, rpc_msgdenied, rpc_mismatch, rpc_vers, rpc_auth_unix,
        rpc_msgaccepted, rpc_call;
 extern u_long nfs_prog, nfs_vers;
 extern u_long rpc_reply, rpc_msgdenied, rpc_mismatch, rpc_vers, rpc_auth_unix,
        rpc_msgaccepted, rpc_call;
 extern u_long nfs_prog, nfs_vers;
+/* Maybe these should be bits in a u_long ?? */
 extern int nonidempotent[NFS_NPROCS];
 extern int nonidempotent[NFS_NPROCS];
+static int compressrequest[NFS_NPROCS] = {
+       FALSE,
+       TRUE,
+       TRUE,
+       FALSE,
+       TRUE,
+       TRUE,
+       TRUE,
+       FALSE,
+       FALSE,
+       TRUE,
+       TRUE,
+       TRUE,
+       TRUE,
+       TRUE,
+       TRUE,
+       TRUE,
+       TRUE,
+       TRUE,
+};
 int    nfs_sbwait();
 void   nfs_disconnect();
 int    nfs_sbwait();
 void   nfs_disconnect();
+struct mbuf *nfs_compress(), *nfs_uncompress();
 
 int    nfsrv_null(),
        nfsrv_getattr(),
 
 int    nfsrv_null(),
        nfsrv_getattr(),
@@ -113,7 +150,7 @@ nfs_connect(nmp)
        register struct nfsmount *nmp;
 {
        register struct socket *so;
        register struct nfsmount *nmp;
 {
        register struct socket *so;
-       int s, error;
+       int s, error, bufsize;
        struct mbuf *m;
 
        nmp->nm_so = (struct socket *)0;
        struct mbuf *m;
 
        nmp->nm_so = (struct socket *)0;
@@ -123,6 +160,15 @@ nfs_connect(nmp)
        so = nmp->nm_so;
        nmp->nm_soflags = so->so_proto->pr_flags;
 
        so = nmp->nm_so;
        nmp->nm_soflags = so->so_proto->pr_flags;
 
+       if (nmp->nm_sotype == SOCK_DGRAM)
+               bufsize = min(4 * (nmp->nm_wsize + NFS_MAXPKTHDR),
+                   NFS_MAXPACKET);
+       else
+               bufsize = min(4 * (nmp->nm_wsize + NFS_MAXPKTHDR + sizeof(u_long)),
+                   NFS_MAXPACKET + sizeof(u_long));
+       if (error = soreserve(so, bufsize, bufsize))
+               goto bad;
+
        /*
         * Protocols that do not require connections may be optionally left
         * unconnected for servers that reply from a port other than NFS_PORT.
        /*
         * Protocols that do not require connections may be optionally left
         * unconnected for servers that reply from a port other than NFS_PORT.
@@ -142,7 +188,7 @@ nfs_connect(nmp)
                 */
                s = splnet();
                while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)
                 */
                s = splnet();
                while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)
-                       sleep((caddr_t)&so->so_timeo, PZERO-2);
+                       (void) tsleep((caddr_t)&so->so_timeo, PSOCK, "nfscon", 0);
                splx(s);
                if (so->so_error) {
                        error = so->so_error;
                splx(s);
                if (so->so_error) {
                        error = so->so_error;
@@ -150,18 +196,16 @@ nfs_connect(nmp)
                }
        }
        if (nmp->nm_sotype == SOCK_DGRAM) {
                }
        }
        if (nmp->nm_sotype == SOCK_DGRAM) {
-               if (nmp->nm_flag & (NFSMNT_SOFT | NFSMNT_INT)) {
+               if (nmp->nm_flag & (NFSMNT_SOFT | NFSMNT_SPONGY | NFSMNT_INT)) {
                        so->so_rcv.sb_timeo = (5 * hz);
                        so->so_snd.sb_timeo = (5 * hz);
                } else {
                        so->so_rcv.sb_timeo = 0;
                        so->so_snd.sb_timeo = 0;
                }
                        so->so_rcv.sb_timeo = (5 * hz);
                        so->so_snd.sb_timeo = (5 * hz);
                } else {
                        so->so_rcv.sb_timeo = 0;
                        so->so_snd.sb_timeo = 0;
                }
-               if (error = soreserve(so, nmp->nm_wsize + NFS_MAXPKTHDR,
-                   (nmp->nm_rsize + NFS_MAXPKTHDR) * 4))
-                       goto bad;
+               nmp->nm_rto = NFS_TIMEO;
        } else {
        } else {
-               if (nmp->nm_flag & NFSMNT_INT) {
+               if (nmp->nm_flag & (NFSMNT_SOFT | NFSMNT_SPONGY | NFSMNT_INT)) {
                        so->so_rcv.sb_timeo = (5 * hz);
                        so->so_snd.sb_timeo = (5 * hz);
                } else {
                        so->so_rcv.sb_timeo = (5 * hz);
                        so->so_snd.sb_timeo = (5 * hz);
                } else {
@@ -182,18 +226,14 @@ nfs_connect(nmp)
                        m->m_len = sizeof(int);
                        sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m);
                }
                        m->m_len = sizeof(int);
                        sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m);
                }
-               if (error = soreserve(so,
-                   (nmp->nm_wsize + NFS_MAXPKTHDR + sizeof(u_long)) * 2,
-                   nmp->nm_rsize + NFS_MAXPKTHDR + sizeof(u_long)))
-                       goto bad;
+               nmp->nm_rto = 10 * NFS_TIMEO;           /* XXX */
        }
        so->so_rcv.sb_flags |= SB_NOINTR;
        so->so_snd.sb_flags |= SB_NOINTR;
 
        /* Initialize other non-zero congestion variables */
        }
        so->so_rcv.sb_flags |= SB_NOINTR;
        so->so_snd.sb_flags |= SB_NOINTR;
 
        /* Initialize other non-zero congestion variables */
-       nmp->nm_rto = NFS_TIMEO;
-       nmp->nm_window = 2;                 /* Initial send window */
-       nmp->nm_ssthresh = NFS_MAXWINDOW; /* Slowstart threshold */
+       nmp->nm_window = 2;                     /* Initial send window */
+       nmp->nm_ssthresh = NFS_MAXWINDOW;       /* Slowstart threshold */
        nmp->nm_rttvar = nmp->nm_rto << 1;
        nmp->nm_sent = 0;
        nmp->nm_currexmit = 0;
        nmp->nm_rttvar = nmp->nm_rto << 1;
        nmp->nm_sent = 0;
        nmp->nm_currexmit = 0;
@@ -220,28 +260,18 @@ nfs_reconnect(rep, nmp)
        register struct nfsreq *rp;
        int error;
 
        register struct nfsreq *rp;
        int error;
 
-       if (rep->r_procp)
-               tprintf(rep->r_procp->p_session,
-                       "Nfs server %s, trying reconnect\n",
-                       nmp->nm_mountp->mnt_stat.f_mntfromname);
-       else
-               tprintf(NULL, "Nfs server %s, trying a reconnect\n",
-                       nmp->nm_mountp->mnt_stat.f_mntfromname);
+       nfs_msg(rep->r_procp, nmp->nm_mountp->mnt_stat.f_mntfromname,
+           "trying reconnect");
        while (error = nfs_connect(nmp)) {
 #ifdef lint
                error = error;
 #endif /* lint */
                if ((nmp->nm_flag & NFSMNT_INT) && nfs_sigintr(rep->r_procp))
                        return (EINTR);
        while (error = nfs_connect(nmp)) {
 #ifdef lint
                error = error;
 #endif /* lint */
                if ((nmp->nm_flag & NFSMNT_INT) && nfs_sigintr(rep->r_procp))
                        return (EINTR);
-               tsleep((caddr_t)&lbolt, PSOCK, "nfscon", 0);
+               (void) tsleep((caddr_t)&lbolt, PSOCK, "nfscon", 0);
        }
        }
-       if (rep->r_procp)
-               tprintf(rep->r_procp->p_session,
-                       "Nfs server %s, reconnected\n",
-                       nmp->nm_mountp->mnt_stat.f_mntfromname);
-       else
-               tprintf(NULL, "Nfs server %s, reconnected\n",
-                       nmp->nm_mountp->mnt_stat.f_mntfromname);
+       nfs_msg(rep->r_procp, nmp->nm_mountp->mnt_stat.f_mntfromname,
+           "reconnected");
 
        /*
         * Loop through outstanding request list and fix up all requests
 
        /*
         * Loop through outstanding request list and fix up all requests
@@ -341,11 +371,11 @@ nfs_receive(so, aname, mp, rep)
        struct uio auio;
        struct iovec aio;
        register struct mbuf *m;
        struct uio auio;
        struct iovec aio;
        register struct mbuf *m;
-       struct mbuf *m2, *m3, *mnew, **mbp;
+       struct mbuf *m2, *mnew, **mbp;
        caddr_t fcp, tcp;
        u_long len;
        struct mbuf **getnam;
        caddr_t fcp, tcp;
        u_long len;
        struct mbuf **getnam;
-       int error, siz, mlen, soflags, rcvflg = MSG_WAITALL;
+       int error, siz, mlen, soflags, rcvflg;
 
        /*
         * Set up arguments for soreceive()
 
        /*
         * Set up arguments for soreceive()
@@ -395,20 +425,29 @@ tryagain:
                        auio.uio_iovcnt = 1;
                        auio.uio_segflg = UIO_SYSSPACE;
                        auio.uio_rw = UIO_READ;
                        auio.uio_iovcnt = 1;
                        auio.uio_segflg = UIO_SYSSPACE;
                        auio.uio_rw = UIO_READ;
+                       auio.uio_procp = (struct proc *)0;
                        auio.uio_offset = 0;
                        auio.uio_resid = sizeof(u_long);
                        do {
                        auio.uio_offset = 0;
                        auio.uio_resid = sizeof(u_long);
                        do {
-                          error = soreceive(so, (struct mbuf **)0, &auio,
+                           rcvflg = MSG_WAITALL;
+                           error = soreceive(so, (struct mbuf **)0, &auio,
                                (struct mbuf **)0, (struct mbuf **)0, &rcvflg);
                                (struct mbuf **)0, (struct mbuf **)0, &rcvflg);
-                          if (error == EWOULDBLOCK && rep) {
+                           if (error == EWOULDBLOCK && rep) {
                                if (rep->r_flags & R_SOFTTERM)
                                        return (EINTR);
                                if (rep->r_flags & R_MUSTRESEND)
                                        goto tryagain;
                                if (rep->r_flags & R_SOFTTERM)
                                        return (EINTR);
                                if (rep->r_flags & R_MUSTRESEND)
                                        goto tryagain;
-                          }
+                           }
                        } while (error == EWOULDBLOCK);
                        } while (error == EWOULDBLOCK);
-                       if (!error && auio.uio_resid > 0)
-                               error = EPIPE;
+                       if (!error && auio.uio_resid > 0) {
+                           if (rep)
+                               log(LOG_INFO,
+                                  "short receive (%d/%d) from nfs server %s\n",
+                                  sizeof(u_long) - auio.uio_resid,
+                                  sizeof(u_long),
+                                rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
+                           error = EPIPE;
+                       }
                        if (error)
                                goto errout;
                        len = ntohl(len) & ~0x80000000;
                        if (error)
                                goto errout;
                        len = ntohl(len) & ~0x80000000;
@@ -417,20 +456,33 @@ tryagain:
                         * and forcing a disconnect/reconnect is all I can do.
                         */
                        if (len > NFS_MAXPACKET) {
                         * and forcing a disconnect/reconnect is all I can do.
                         */
                        if (len > NFS_MAXPACKET) {
-                               error = EFBIG;
-                               goto errout;
+                           if (rep)
+                               log(LOG_ERR, "%s (%d) from nfs server %s\n",
+                                   "impossible packet length",
+                                   len,
+                                rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
+                           error = EFBIG;
+                           goto errout;
                        }
                        auio.uio_resid = len;
                        do {
                        }
                        auio.uio_resid = len;
                        do {
+                           rcvflg = MSG_WAITALL;
                            error =  soreceive(so, (struct mbuf **)0,
                                &auio, mp, (struct mbuf **)0, &rcvflg);
                        } while (error == EWOULDBLOCK || error == EINTR ||
                                 error == ERESTART);
                            error =  soreceive(so, (struct mbuf **)0,
                                &auio, mp, (struct mbuf **)0, &rcvflg);
                        } while (error == EWOULDBLOCK || error == EINTR ||
                                 error == ERESTART);
-                       if (!error && auio.uio_resid > 0)
-                               error = EPIPE;
+                       if (!error && auio.uio_resid > 0) {
+                           if (rep)
+                               log(LOG_INFO,
+                                  "short receive (%d/%d) from nfs server %s\n",
+                                  len - auio.uio_resid, len,
+                                rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
+                           error = EPIPE;
+                       }
                } else {
                        auio.uio_resid = len = 1000000; /* Anything Big */
                        do {
                } else {
                        auio.uio_resid = len = 1000000; /* Anything Big */
                        do {
+                           rcvflg = 0;
                            error =  soreceive(so, (struct mbuf **)0,
                                &auio, mp, (struct mbuf **)0, &rcvflg);
                            if (error == EWOULDBLOCK && rep) {
                            error =  soreceive(so, (struct mbuf **)0,
                                &auio, mp, (struct mbuf **)0, &rcvflg);
                            if (error == EWOULDBLOCK && rep) {
@@ -448,6 +500,11 @@ errout:
                if (error && rep && error != EINTR && error != ERESTART) {
                        m_freem(*mp);
                        *mp = (struct mbuf *)0;
                if (error && rep && error != EINTR && error != ERESTART) {
                        m_freem(*mp);
                        *mp = (struct mbuf *)0;
+                       if (error != EPIPE && rep)
+                               log(LOG_INFO,
+                                   "receive error %d from nfs server %s\n",
+                                   error,
+                                rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
                        nfs_disconnect(rep->r_nmp);
                        error = nfs_reconnect(rep, rep->r_nmp);
                        if (!error)
                        nfs_disconnect(rep->r_nmp);
                        error = nfs_reconnect(rep, rep->r_nmp);
                        if (!error)
@@ -460,6 +517,7 @@ errout:
                        getnam = aname;
                auio.uio_resid = len = 1000000;
                do {
                        getnam = aname;
                auio.uio_resid = len = 1000000;
                do {
+                       rcvflg = 0;
                        error =  soreceive(so, getnam, &auio, mp,
                                (struct mbuf **)0, &rcvflg);
                        if (error == EWOULDBLOCK && rep &&
                        error =  soreceive(so, getnam, &auio, mp,
                                (struct mbuf **)0, &rcvflg);
                        if (error == EWOULDBLOCK && rep &&
@@ -483,47 +541,34 @@ errout:
                /*
                 * All this for something that may never happen.
                 */
                /*
                 * All this for something that may never happen.
                 */
-               if (m->m_len & 0x3) {
+               if (m->m_next && (m->m_len & 0x3)) {
                        printf("nfs_rcv odd length!\n");
                        printf("nfs_rcv odd length!\n");
-                       fcp = mtod(m, caddr_t);
-                       mnew = m2 = (struct mbuf *)0;
-#ifdef lint
-                       m3 = (struct mbuf *)0;
                        mlen = 0;
                        mlen = 0;
-#endif /* lint */
                        while (m) {
                        while (m) {
-                               if (m2 == NULL || mlen == 0) {
-                                       MGET(m2, M_WAIT, MT_DATA);
-                                       if (len > MINCLSIZE)
-                                               MCLGET(m2, M_WAIT);
-                                       m2->m_len = 0;
-                                       mlen = M_TRAILINGSPACE(m2);
-                                       tcp = mtod(m2, caddr_t);
-                                       if (mnew) {
-                                               m3->m_next = m2;
-                                               m3 = m2;
-                                       } else
-                                               mnew = m3 = m2;
-                               }
-                               siz = (mlen > m->m_len) ? m->m_len : mlen;
-                               bcopy(fcp, tcp, siz);
-                               m2->m_len += siz;
-                               mlen -= siz;
-                               len -= siz;
-                               tcp += siz;
-                               m->m_len -= siz;
-                               fcp += siz;
-                               if (m->m_len == 0) {
-                                       do {
-                                               m = m->m_next;
-                                       } while (m && m->m_len == 0);
-                                       if (m)
-                                               fcp = mtod(m, caddr_t);
+                               fcp = mtod(m, caddr_t);
+                               while (m->m_len > 0) {
+                                       if (mlen == 0) {
+                                               MGET(m2, M_WAIT, MT_DATA);
+                                               if (len >= MINCLSIZE)
+                                                       MCLGET(m2, M_WAIT);
+                                               m2->m_len = 0;
+                                               mlen = M_TRAILINGSPACE(m2);
+                                               tcp = mtod(m2, caddr_t);
+                                               *mbp = m2;
+                                               mbp = &m2->m_next;
+                                       }
+                                       siz = MIN(mlen, m->m_len);
+                                       bcopy(fcp, tcp, siz);
+                                       m2->m_len += siz;
+                                       mlen -= siz;
+                                       len -= siz;
+                                       tcp += siz;
+                                       m->m_len -= siz;
+                                       fcp += siz;
                                }
                                }
+                               MFREE(m, mnew);
+                               m = mnew;
                        }
                        }
-                       m = *mbp;
-                       *mbp = mnew;
-                       m_freem(m);
                        break;
                }
                len -= m->m_len;
                        break;
                }
                len -= m->m_len;
@@ -533,11 +578,6 @@ errout:
        return (error);
 }
 
        return (error);
 }
 
-struct rpc_replyhead {
-       u_long  r_xid;
-       u_long  r_rep;
-};
-
 /*
  * Implement receipt of reply on a socket.
  * We must search through the list of received datagrams matching them
 /*
  * Implement receipt of reply on a socket.
  * We must search through the list of received datagrams matching them
@@ -551,7 +591,7 @@ nfs_reply(nmp, myrep)
        register struct mbuf *m;
        register struct nfsreq *rep;
        register int error = 0;
        register struct mbuf *m;
        register struct nfsreq *rep;
        register int error = 0;
-       struct rpc_replyhead replyh;
+       u_long rxid;
        struct mbuf *mp, *nam;
        char *cp;
        int cnt, xfer;
        struct mbuf *mp, *nam;
        char *cp;
        int cnt, xfer;
@@ -566,7 +606,7 @@ nfs_reply(nmp, myrep)
                 * Also necessary for connection based protocols to avoid
                 * race conditions during a reconnect.
                 */
                 * Also necessary for connection based protocols to avoid
                 * race conditions during a reconnect.
                 */
-               nfs_solock(&nmp->nm_flag, 1);
+               nfs_solock(&nmp->nm_flag);
                /* Already received, bye bye */
                if (myrep->r_mrep != NULL) {
                        nfs_sounlock(&nmp->nm_flag);
                /* Already received, bye bye */
                if (myrep->r_mrep != NULL) {
                        nfs_sounlock(&nmp->nm_flag);
@@ -604,30 +644,15 @@ nfs_reply(nmp, myrep)
                 * Get the xid and check that it is an rpc reply
                 */
                m = mp;
                 * Get the xid and check that it is an rpc reply
                 */
                m = mp;
-               if (m->m_len >= 2*NFSX_UNSIGNED)
-                       bcopy(mtod(m, caddr_t), (caddr_t)&replyh,
-                               2*NFSX_UNSIGNED);
-               else {
-                       cnt = 2*NFSX_UNSIGNED;
-                       cp = (caddr_t)&replyh;
-                       while (m && cnt > 0) {
-                               if (m->m_len > 0) {
-                                       xfer = (m->m_len >= cnt) ? cnt :
-                                               m->m_len;
-                                       bcopy(mtod(m, caddr_t), cp, xfer);
-                                       cnt -= xfer;
-                                       cp += xfer;
-                               }
-                               if (cnt > 0)
-                                       m = m->m_next;
-                       }
-               }
-               if (replyh.r_rep != rpc_reply || m == NULL) {
+               while (m && m->m_len == 0)
+                       m = m->m_next;
+               if (m == NULL) {
                        nfsstats.rpcinvalid++;
                        m_freem(mp);
                        nfs_sounlock(&nmp->nm_flag);
                        continue;
                }
                        nfsstats.rpcinvalid++;
                        m_freem(mp);
                        nfs_sounlock(&nmp->nm_flag);
                        continue;
                }
+               bcopy(mtod(m, caddr_t), (caddr_t)&rxid, NFSX_UNSIGNED);
                /*
                 * Loop through the request list to match up the reply
                 * Iff no match, just drop the datagram
                /*
                 * Loop through the request list to match up the reply
                 * Iff no match, just drop the datagram
@@ -635,7 +660,7 @@ nfs_reply(nmp, myrep)
                m = mp;
                rep = nfsreqh.r_next;
                while (rep != &nfsreqh) {
                m = mp;
                rep = nfsreqh.r_next;
                while (rep != &nfsreqh) {
-                       if (rep->r_mrep == NULL && replyh.r_xid == rep->r_xid) {
+                       if (rep->r_mrep == NULL && rxid == rep->r_xid) {
                                /* Found it.. */
                                rep->r_mrep = m;
                                /*
                                /* Found it.. */
                                rep->r_mrep = m;
                                /*
@@ -679,12 +704,13 @@ nfs_reply(nmp, myrep)
  *       by mrep or error
  * nb: always frees up mreq mbuf list
  */
  *       by mrep or error
  * nb: always frees up mreq mbuf list
  */
-nfs_request(vp, mreq, xid, procnum, procp, mp, mrp, mdp, dposp)
+nfs_request(vp, mreq, xid, procnum, procp, tryhard, mp, mrp, mdp, dposp)
        struct vnode *vp;
        struct mbuf *mreq;
        u_long xid;
        int procnum;
        struct proc *procp;
        struct vnode *vp;
        struct mbuf *mreq;
        u_long xid;
        int procnum;
        struct proc *procp;
+       int tryhard;
        struct mount *mp;
        struct mbuf **mrp;
        struct mbuf **mdp;
        struct mount *mp;
        struct mbuf **mrp;
        struct mbuf **mdp;
@@ -692,7 +718,7 @@ nfs_request(vp, mreq, xid, procnum, procp, mp, mrp, mdp, dposp)
 {
        register struct mbuf *m, *mrep;
        register struct nfsreq *rep;
 {
        register struct mbuf *m, *mrep;
        register struct nfsreq *rep;
-       register u_long *p;
+       register u_long *tl;
        register int len;
        struct nfsmount *nmp;
        struct mbuf *md;
        register int len;
        struct nfsmount *nmp;
        struct mbuf *md;
@@ -700,7 +726,7 @@ nfs_request(vp, mreq, xid, procnum, procp, mp, mrp, mdp, dposp)
        caddr_t dpos;
        char *cp2;
        int t1;
        caddr_t dpos;
        char *cp2;
        int t1;
-       int s;
+       int s, compressed;
        int error = 0;
 
        nmp = VFSTONFS(mp);
        int error = 0;
 
        nmp = VFSTONFS(mp);
@@ -710,7 +736,8 @@ nfs_request(vp, mreq, xid, procnum, procp, mp, mrp, mdp, dposp)
        rep->r_nmp = nmp;
        rep->r_vp = vp;
        rep->r_procp = procp;
        rep->r_nmp = nmp;
        rep->r_vp = vp;
        rep->r_procp = procp;
-       if (nmp->nm_flag & NFSMNT_SOFT)
+       if ((nmp->nm_flag & NFSMNT_SOFT) ||
+           ((nmp->nm_flag & NFSMNT_SPONGY) && !tryhard))
                rep->r_retry = nmp->nm_retry;
        else
                rep->r_retry = NFS_MAXREXMIT + 1;       /* past clip limit */
                rep->r_retry = nmp->nm_retry;
        else
                rep->r_retry = NFS_MAXREXMIT + 1;       /* past clip limit */
@@ -721,7 +748,7 @@ nfs_request(vp, mreq, xid, procnum, procp, mp, mrp, mdp, dposp)
         * - idempotent requests on SOCK_DGRAM use 0
         * - Reliable transports, NFS_RELIABLETIMEO
         *   Timeouts are still done on reliable transports to ensure detection
         * - idempotent requests on SOCK_DGRAM use 0
         * - Reliable transports, NFS_RELIABLETIMEO
         *   Timeouts are still done on reliable transports to ensure detection
-        *   of connection loss.
+        *   of excessive connection delay.
         */
        if (nmp->nm_sotype != SOCK_DGRAM)
                rep->r_timerinit = -NFS_RELIABLETIMEO;
         */
        if (nmp->nm_sotype != SOCK_DGRAM)
                rep->r_timerinit = -NFS_RELIABLETIMEO;
@@ -738,6 +765,15 @@ nfs_request(vp, mreq, xid, procnum, procp, mp, mrp, mdp, dposp)
        }
        mreq->m_pkthdr.len = len;
        mreq->m_pkthdr.rcvif = (struct ifnet *)0;
        }
        mreq->m_pkthdr.len = len;
        mreq->m_pkthdr.rcvif = (struct ifnet *)0;
+       compressed = 0;
+       m = mreq;
+       if ((nmp->nm_flag & NFSMNT_COMPRESS) && compressrequest[procnum]) {
+               mreq = nfs_compress(mreq);
+               if (mreq != m) {
+                       len = mreq->m_pkthdr.len;
+                       compressed++;
+               }
+       }
        /*
         * For non-atomic protocols, insert a Sun RPC Record Mark.
         */
        /*
         * For non-atomic protocols, insert a Sun RPC Record Mark.
         */
@@ -777,7 +813,7 @@ nfs_request(vp, mreq, xid, procnum, procp, mp, mrp, mdp, dposp)
                splx(s);
                m = m_copym(mreq, 0, M_COPYALL, M_WAIT);
                if (nmp->nm_soflags & PR_CONNREQUIRED)
                splx(s);
                m = m_copym(mreq, 0, M_COPYALL, M_WAIT);
                if (nmp->nm_soflags & PR_CONNREQUIRED)
-                       nfs_solock(&nmp->nm_flag, 1);
+                       nfs_solock(&nmp->nm_flag);
                error = nfs_send(nmp->nm_so, nmp->nm_nam, m, rep);
                if (nmp->nm_soflags & PR_CONNREQUIRED)
                        nfs_sounlock(&nmp->nm_flag);
                error = nfs_send(nmp->nm_so, nmp->nm_nam, m, rep);
                if (nmp->nm_soflags & PR_CONNREQUIRED)
                        nfs_sounlock(&nmp->nm_flag);
@@ -804,29 +840,26 @@ nfs_request(vp, mreq, xid, procnum, procp, mp, mrp, mdp, dposp)
         * If there was a successful reply and a tprintf msg.
         * tprintf a response.
         */
         * If there was a successful reply and a tprintf msg.
         * tprintf a response.
         */
-       if (!error && (rep->r_flags & R_TPRINTFMSG)) {
-               if (rep->r_procp)
-                       tprintf(rep->r_procp->p_session,
-                               "Nfs server %s, is alive again\n",
-                               rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
-               else
-                       tprintf(NULL, "Nfs server %s, is alive again\n",
-                               rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
-       }
+       if (!error && (rep->r_flags & R_TPRINTFMSG))
+               nfs_msg(rep->r_procp, nmp->nm_mountp->mnt_stat.f_mntfromname,
+                   "is alive again");
        m_freem(rep->r_mreq);
        m_freem(rep->r_mreq);
-       mrep = md = rep->r_mrep;
+       mrep = rep->r_mrep;
        FREE((caddr_t)rep, M_NFSREQ);
        if (error)
                return (error);
 
        FREE((caddr_t)rep, M_NFSREQ);
        if (error)
                return (error);
 
+       if (compressed)
+               mrep = nfs_uncompress(mrep);
+       md = mrep;
        /*
         * break down the rpc header and check if ok
         */
        dpos = mtod(md, caddr_t);
        /*
         * break down the rpc header and check if ok
         */
        dpos = mtod(md, caddr_t);
-       nfsm_disect(p, u_long *, 5*NFSX_UNSIGNED);
-       p += 2;
-       if (*p++ == rpc_msgdenied) {
-               if (*p == rpc_mismatch)
+       nfsm_disect(tl, u_long *, 5*NFSX_UNSIGNED);
+       tl += 2;
+       if (*tl++ == rpc_msgdenied) {
+               if (*tl == rpc_mismatch)
                        error = EOPNOTSUPP;
                else
                        error = EACCES;
                        error = EOPNOTSUPP;
                else
                        error = EACCES;
@@ -837,16 +870,16 @@ nfs_request(vp, mreq, xid, procnum, procp, mp, mrp, mdp, dposp)
         * skip over the auth_verf, someday we may want to cache auth_short's
         * for nfs_reqhead(), but for now just dump it
         */
         * skip over the auth_verf, someday we may want to cache auth_short's
         * for nfs_reqhead(), but for now just dump it
         */
-       if (*++p != 0) {
-               len = nfsm_rndup(fxdr_unsigned(long, *p));
+       if (*++tl != 0) {
+               len = nfsm_rndup(fxdr_unsigned(long, *tl));
                nfsm_adv(len);
        }
                nfsm_adv(len);
        }
-       nfsm_disect(p, u_long *, NFSX_UNSIGNED);
+       nfsm_disect(tl, u_long *, NFSX_UNSIGNED);
        /* 0 == ok */
        /* 0 == ok */
-       if (*p == 0) {
-               nfsm_disect(p, u_long *, NFSX_UNSIGNED);
-               if (*p != 0) {
-                       error = fxdr_unsigned(int, *p);
+       if (*tl == 0) {
+               nfsm_disect(tl, u_long *, NFSX_UNSIGNED);
+               if (*tl != 0) {
+                       error = fxdr_unsigned(int, *tl);
                        m_freem(mrep);
                        return (error);
                }
                        m_freem(mrep);
                        return (error);
                }
@@ -868,7 +901,7 @@ nfsmout:
  * - fill in the cred struct.
  */
 nfs_getreq(so, prog, vers, maxproc, nam, mrp, mdp, dposp, retxid, procnum, cr,
  * - fill in the cred struct.
  */
 nfs_getreq(so, prog, vers, maxproc, nam, mrp, mdp, dposp, retxid, procnum, cr,
-       lockp, msk, mtch)
+       msk, mtch, wascomp)
        struct socket *so;
        u_long prog;
        u_long vers;
        struct socket *so;
        u_long prog;
        u_long vers;
@@ -880,11 +913,11 @@ nfs_getreq(so, prog, vers, maxproc, nam, mrp, mdp, dposp, retxid, procnum, cr,
        u_long *retxid;
        u_long *procnum;
        register struct ucred *cr;
        u_long *retxid;
        u_long *procnum;
        register struct ucred *cr;
-       int *lockp;
        struct mbuf *msk, *mtch;
        struct mbuf *msk, *mtch;
+       int *wascomp;
 {
        register int i;
 {
        register int i;
-       register u_long *p;
+       register u_long *tl;
        register long t1;
        caddr_t dpos, cp2;
        int error = 0;
        register long t1;
        caddr_t dpos, cp2;
        int error = 0;
@@ -892,9 +925,7 @@ nfs_getreq(so, prog, vers, maxproc, nam, mrp, mdp, dposp, retxid, procnum, cr,
        int len;
 
        if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
        int len;
 
        if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
-               nfs_solock(lockp, 0);
                error = nfs_receive(so, nam, &mrep, (struct nfsreq *)0);
                error = nfs_receive(so, nam, &mrep, (struct nfsreq *)0);
-               nfs_sounlock(lockp);
        } else {
                mrep = (struct mbuf *)0;
                do {
        } else {
                mrep = (struct mbuf *)0;
                do {
@@ -908,59 +939,65 @@ nfs_getreq(so, prog, vers, maxproc, nam, mrp, mdp, dposp, retxid, procnum, cr,
        if (error)
                return (error);
        md = mrep;
        if (error)
                return (error);
        md = mrep;
+       mrep = nfs_uncompress(mrep);
+       if (mrep != md) {
+               *wascomp = 1;
+               md = mrep;
+       } else
+               *wascomp = 0;
        dpos = mtod(mrep, caddr_t);
        dpos = mtod(mrep, caddr_t);
-       nfsm_disect(p, u_long *, 10*NFSX_UNSIGNED);
-       *retxid = *p++;
-       if (*p++ != rpc_call) {
+       nfsm_disect(tl, u_long *, 10*NFSX_UNSIGNED);
+       *retxid = *tl++;
+       if (*tl++ != rpc_call) {
                m_freem(mrep);
                return (ERPCMISMATCH);
        }
                m_freem(mrep);
                return (ERPCMISMATCH);
        }
-       if (*p++ != rpc_vers) {
+       if (*tl++ != rpc_vers) {
                m_freem(mrep);
                return (ERPCMISMATCH);
        }
                m_freem(mrep);
                return (ERPCMISMATCH);
        }
-       if (*p++ != prog) {
+       if (*tl++ != prog) {
                m_freem(mrep);
                return (EPROGUNAVAIL);
        }
                m_freem(mrep);
                return (EPROGUNAVAIL);
        }
-       if (*p++ != vers) {
+       if (*tl++ != vers) {
                m_freem(mrep);
                return (EPROGMISMATCH);
        }
                m_freem(mrep);
                return (EPROGMISMATCH);
        }
-       *procnum = fxdr_unsigned(u_long, *p++);
+       *procnum = fxdr_unsigned(u_long, *tl++);
        if (*procnum == NFSPROC_NULL) {
                *mrp = mrep;
                return (0);
        }
        if (*procnum == NFSPROC_NULL) {
                *mrp = mrep;
                return (0);
        }
-       if (*procnum > maxproc || *p++ != rpc_auth_unix) {
+       if (*procnum > maxproc || *tl++ != rpc_auth_unix) {
                m_freem(mrep);
                return (EPROCUNAVAIL);
        }
                m_freem(mrep);
                return (EPROCUNAVAIL);
        }
-       len = fxdr_unsigned(int, *p++);
+       len = fxdr_unsigned(int, *tl++);
        if (len < 0 || len > RPCAUTH_MAXSIZ) {
                m_freem(mrep);
                return (EBADRPC);
        }
        if (len < 0 || len > RPCAUTH_MAXSIZ) {
                m_freem(mrep);
                return (EBADRPC);
        }
-       len = fxdr_unsigned(int, *++p);
+       len = fxdr_unsigned(int, *++tl);
        if (len < 0 || len > NFS_MAXNAMLEN) {
                m_freem(mrep);
                return (EBADRPC);
        }
        nfsm_adv(nfsm_rndup(len));
        if (len < 0 || len > NFS_MAXNAMLEN) {
                m_freem(mrep);
                return (EBADRPC);
        }
        nfsm_adv(nfsm_rndup(len));
-       nfsm_disect(p, u_long *, 3*NFSX_UNSIGNED);
-       cr->cr_uid = fxdr_unsigned(uid_t, *p++);
-       cr->cr_gid = fxdr_unsigned(gid_t, *p++);
-       len = fxdr_unsigned(int, *p);
+       nfsm_disect(tl, u_long *, 3*NFSX_UNSIGNED);
+       cr->cr_uid = fxdr_unsigned(uid_t, *tl++);
+       cr->cr_gid = fxdr_unsigned(gid_t, *tl++);
+       len = fxdr_unsigned(int, *tl);
        if (len < 0 || len > RPCAUTH_UNIXGIDS) {
                m_freem(mrep);
                return (EBADRPC);
        }
        if (len < 0 || len > RPCAUTH_UNIXGIDS) {
                m_freem(mrep);
                return (EBADRPC);
        }
-       nfsm_disect(p, u_long *, (len + 2)*NFSX_UNSIGNED);
+       nfsm_disect(tl, u_long *, (len + 2)*NFSX_UNSIGNED);
        for (i = 1; i <= len; i++)
                if (i < NGROUPS)
        for (i = 1; i <= len; i++)
                if (i < NGROUPS)
-                       cr->cr_groups[i] = fxdr_unsigned(gid_t, *p++);
+                       cr->cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
                else
                else
-                       p++;
+                       tl++;
        cr->cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1);
        /*
         * Do we have any use for the verifier.
        cr->cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1);
        /*
         * Do we have any use for the verifier.
@@ -968,7 +1005,7 @@ nfs_getreq(so, prog, vers, maxproc, nam, mrp, mdp, dposp, retxid, procnum, cr,
         * should be AUTH_NULL, but some clients make it AUTH_UNIX?
         * For now, just skip over it
         */
         * should be AUTH_NULL, but some clients make it AUTH_UNIX?
         * For now, just skip over it
         */
-       len = fxdr_unsigned(int, *++p);
+       len = fxdr_unsigned(int, *++tl);
        if (len < 0 || len > RPCAUTH_MAXSIZ) {
                m_freem(mrep);
                return (EBADRPC);
        if (len < 0 || len > RPCAUTH_MAXSIZ) {
                m_freem(mrep);
                return (EBADRPC);
@@ -995,7 +1032,7 @@ nfs_rephead(siz, retxid, err, mrq, mbp, bposp)
        struct mbuf **mbp;
        caddr_t *bposp;
 {
        struct mbuf **mbp;
        caddr_t *bposp;
 {
-       register u_long *p;
+       register u_long *tl;
        register long t1;
        caddr_t bpos;
        struct mbuf *mreq, *mb, *mb2;
        register long t1;
        caddr_t bpos;
        struct mbuf *mreq, *mb, *mb2;
@@ -1004,38 +1041,38 @@ nfs_rephead(siz, retxid, err, mrq, mbp, bposp)
        mb = mreq;
        if ((siz+RPC_REPLYSIZ) > MHLEN)
                MCLGET(mreq, M_WAIT);
        mb = mreq;
        if ((siz+RPC_REPLYSIZ) > MHLEN)
                MCLGET(mreq, M_WAIT);
-       p = mtod(mreq, u_long *);
+       tl = mtod(mreq, u_long *);
        mreq->m_len = 6*NFSX_UNSIGNED;
        mreq->m_len = 6*NFSX_UNSIGNED;
-       bpos = ((caddr_t)p)+mreq->m_len;
-       *p++ = retxid;
-       *p++ = rpc_reply;
+       bpos = ((caddr_t)tl)+mreq->m_len;
+       *tl++ = retxid;
+       *tl++ = rpc_reply;
        if (err == ERPCMISMATCH) {
        if (err == ERPCMISMATCH) {
-               *p++ = rpc_msgdenied;
-               *p++ = rpc_mismatch;
-               *p++ = txdr_unsigned(2);
-               *p = txdr_unsigned(2);
+               *tl++ = rpc_msgdenied;
+               *tl++ = rpc_mismatch;
+               *tl++ = txdr_unsigned(2);
+               *tl = txdr_unsigned(2);
        } else {
        } else {
-               *p++ = rpc_msgaccepted;
-               *p++ = 0;
-               *p++ = 0;
+               *tl++ = rpc_msgaccepted;
+               *tl++ = 0;
+               *tl++ = 0;
                switch (err) {
                case EPROGUNAVAIL:
                switch (err) {
                case EPROGUNAVAIL:
-                       *p = txdr_unsigned(RPC_PROGUNAVAIL);
+                       *tl = txdr_unsigned(RPC_PROGUNAVAIL);
                        break;
                case EPROGMISMATCH:
                        break;
                case EPROGMISMATCH:
-                       *p = txdr_unsigned(RPC_PROGMISMATCH);
-                       nfsm_build(p, u_long *, 2*NFSX_UNSIGNED);
-                       *p++ = txdr_unsigned(2);
-                       *p = txdr_unsigned(2);  /* someday 3 */
+                       *tl = txdr_unsigned(RPC_PROGMISMATCH);
+                       nfsm_build(tl, u_long *, 2*NFSX_UNSIGNED);
+                       *tl++ = txdr_unsigned(2);
+                       *tl = txdr_unsigned(2); /* someday 3 */
                        break;
                case EPROCUNAVAIL:
                        break;
                case EPROCUNAVAIL:
-                       *p = txdr_unsigned(RPC_PROCUNAVAIL);
+                       *tl = txdr_unsigned(RPC_PROCUNAVAIL);
                        break;
                default:
                        break;
                default:
-                       *p = 0;
+                       *tl = 0;
                        if (err != VNOVAL) {
                        if (err != VNOVAL) {
-                               nfsm_build(p, u_long *, NFSX_UNSIGNED);
-                               *p = txdr_unsigned(err);
+                               nfsm_build(tl, u_long *, NFSX_UNSIGNED);
+                               *tl = txdr_unsigned(err);
                        }
                        break;
                };
                        }
                        break;
                };
@@ -1074,18 +1111,9 @@ nfs_timer()
                }
                if (rep->r_flags & R_TIMING)    /* update rtt in mount */
                        nmp->nm_rtt++;
                }
                if (rep->r_flags & R_TIMING)    /* update rtt in mount */
                        nmp->nm_rtt++;
-               if (nmp->nm_sotype != SOCK_DGRAM)
-                       continue;
                /* If not timed out */
                if (++rep->r_timer < nmp->nm_rto)
                        continue;
                /* If not timed out */
                if (++rep->r_timer < nmp->nm_rto)
                        continue;
-#ifdef notdef
-               if (nmp->nm_sotype != SOCK_DGRAM) {
-                       rep->r_flags |= R_MUSTRESEND;
-                       rep->r_timer = rep->r_timerinit;
-                       continue;
-               }
-#endif
                /* Do backoff and save new timeout in mount */
                if (rep->r_flags & R_TIMING) {
                        nfs_backofftimer(nmp);
                /* Do backoff and save new timeout in mount */
                if (rep->r_flags & R_TIMING) {
                        nfs_backofftimer(nmp);
@@ -1108,22 +1136,19 @@ nfs_timer()
                 * Check for server not responding
                 */
                if ((rep->r_flags & R_TPRINTFMSG) == 0 &&
                 * Check for server not responding
                 */
                if ((rep->r_flags & R_TPRINTFMSG) == 0 &&
-                    rep->r_rexmit > 8) {
-                       if (rep->r_procp && rep->r_procp->p_session)
-                               tprintf(rep->r_procp->p_session,
-                                       "Nfs server %s, not responding\n",
-                                       nmp->nm_mountp->mnt_stat.f_mntfromname);
-                       else
-                               tprintf(NULL,
-                                       "Nfs server %s, not responding\n",
-                                       nmp->nm_mountp->mnt_stat.f_mntfromname);
+                    rep->r_rexmit > NFS_FISHY) {
+                       nfs_msg(rep->r_procp,
+                           nmp->nm_mountp->mnt_stat.f_mntfromname,
+                           "not responding");
                        rep->r_flags |= R_TPRINTFMSG;
                }
                        rep->r_flags |= R_TPRINTFMSG;
                }
-               if (rep->r_rexmit > rep->r_retry) {     /* too many */
+               if (rep->r_rexmit >= rep->r_retry) {    /* too many */
                        nfsstats.rpctimeouts++;
                        rep->r_flags |= R_SOFTTERM;
                        continue;
                }
                        nfsstats.rpctimeouts++;
                        rep->r_flags |= R_SOFTTERM;
                        continue;
                }
+               if (nmp->nm_sotype != SOCK_DGRAM)
+                       continue;
 
                /*
                 * If there is enough space and the window allows..
 
                /*
                 * If there is enough space and the window allows..
@@ -1288,23 +1313,33 @@ nfs_sigintr(p)
                return (0);
 }
 
                return (0);
 }
 
+nfs_msg(p, server, msg)
+       struct proc *p;
+       char *server, *msg;
+{
+       tpr_t tpr;
+
+       if (p)
+               tpr = tprintf_open(p);
+       else
+               tpr = NULL;
+       tprintf(tpr, "nfs server %s: %s\n", server, msg);
+       tprintf_close(tpr);
+}
+
 /*
  * Lock a socket against others.
  * Necessary for STREAM sockets to ensure you get an entire rpc request/reply
  * and also to avoid race conditions between the processes with nfs requests
  * in progress when a reconnect is necessary.
  */
 /*
  * Lock a socket against others.
  * Necessary for STREAM sockets to ensure you get an entire rpc request/reply
  * and also to avoid race conditions between the processes with nfs requests
  * in progress when a reconnect is necessary.
  */
-nfs_solock(flagp, cant_intr)
-       int *flagp;
-       int cant_intr;
+nfs_solock(flagp)
+       register int *flagp;
 {
 
        while (*flagp & NFSMNT_SCKLOCK) {
                *flagp |= NFSMNT_WANTSCK;
 {
 
        while (*flagp & NFSMNT_SCKLOCK) {
                *flagp |= NFSMNT_WANTSCK;
-               if (cant_intr)
-                       (void) sleep((caddr_t)flagp, PZERO-7);
-               else
-                       (void) tsleep((caddr_t)flagp, PZERO+1, "nfssolck", 0);
+               (void) tsleep((caddr_t)flagp, PZERO-1, "nfsolck", 0);
        }
        *flagp |= NFSMNT_SCKLOCK;
 }
        }
        *flagp |= NFSMNT_SCKLOCK;
 }
@@ -1313,7 +1348,7 @@ nfs_solock(flagp, cant_intr)
  * Unlock the stream socket for others.
  */
 nfs_sounlock(flagp)
  * Unlock the stream socket for others.
  */
 nfs_sounlock(flagp)
-       int *flagp;
+       register int *flagp;
 {
 
        if ((*flagp & NFSMNT_SCKLOCK) == 0)
 {
 
        if ((*flagp & NFSMNT_SCKLOCK) == 0)