]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/nfsclient/nfs_socket.c
This commit was generated by cvs2svn to compensate for changes in r155429,
[FreeBSD/FreeBSD.git] / sys / nfsclient / nfs_socket.c
1 /*-
2  * Copyright (c) 1989, 1991, 1993, 1995
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Rick Macklem at The University of Guelph.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 4. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  *      @(#)nfs_socket.c        8.5 (Berkeley) 3/30/95
33  */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37
38 /*
39  * Socket operations for use by nfs
40  */
41
42 #include "opt_inet6.h"
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/lock.h>
48 #include <sys/malloc.h>
49 #include <sys/mbuf.h>
50 #include <sys/mount.h>
51 #include <sys/mutex.h>
52 #include <sys/proc.h>
53 #include <sys/protosw.h>
54 #include <sys/signalvar.h>
55 #include <sys/syscallsubr.h>
56 #include <sys/socket.h>
57 #include <sys/socketvar.h>
58 #include <sys/sysctl.h>
59 #include <sys/syslog.h>
60 #include <sys/vnode.h>
61
62 #include <netinet/in.h>
63 #include <netinet/tcp.h>
64
65 #include <rpc/rpcclnt.h>
66
67 #include <nfs/rpcv2.h>
68 #include <nfs/nfsproto.h>
69 #include <nfsclient/nfs.h>
70 #include <nfs/xdr_subs.h>
71 #include <nfsclient/nfsm_subs.h>
72 #include <nfsclient/nfsmount.h>
73 #include <nfsclient/nfsnode.h>
74
75 #include <nfs4client/nfs4.h>
76
77 #define TRUE    1
78 #define FALSE   0
79
80 extern u_int32_t nfs_xid;
81
82 /*
83  * Estimate rto for an nfs rpc sent via. an unreliable datagram.
84  * Use the mean and mean deviation of rtt for the appropriate type of rpc
85  * for the frequent rpcs and a default for the others.
86  * The justification for doing "other" this way is that these rpcs
87  * happen so infrequently that timer est. would probably be stale.
88  * Also, since many of these rpcs are
89  * non-idempotent, a conservative timeout is desired.
90  * getattr, lookup - A+2D
91  * read, write     - A+4D
92  * other           - nm_timeo
93  */
94 #define NFS_RTO(n, t) \
95         ((t) == 0 ? (n)->nm_timeo : \
96          ((t) < 3 ? \
97           (((((n)->nm_srtt[t-1] + 3) >> 2) + (n)->nm_sdrtt[t-1] + 1) >> 1) : \
98           ((((n)->nm_srtt[t-1] + 7) >> 3) + (n)->nm_sdrtt[t-1] + 1)))
99 #define NFS_SRTT(r)     (r)->r_nmp->nm_srtt[proct[(r)->r_procnum] - 1]
100 #define NFS_SDRTT(r)    (r)->r_nmp->nm_sdrtt[proct[(r)->r_procnum] - 1]
101
102 /*
103  * Defines which timer to use for the procnum.
104  * 0 - default
105  * 1 - getattr
106  * 2 - lookup
107  * 3 - read
108  * 4 - write
109  */
110 static int proct[NFS_NPROCS] = {
111         0, 1, 0, 2, 1, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0,
112 };
113
114 static int      nfs_realign_test;
115 static int      nfs_realign_count;
116 static int      nfs_bufpackets = 4;
117 static int      nfs_reconnects;
118
119 SYSCTL_DECL(_vfs_nfs);
120
121 SYSCTL_INT(_vfs_nfs, OID_AUTO, realign_test, CTLFLAG_RW, &nfs_realign_test, 0, "");
122 SYSCTL_INT(_vfs_nfs, OID_AUTO, realign_count, CTLFLAG_RW, &nfs_realign_count, 0, "");
123 SYSCTL_INT(_vfs_nfs, OID_AUTO, bufpackets, CTLFLAG_RW, &nfs_bufpackets, 0, "");
124 SYSCTL_INT(_vfs_nfs, OID_AUTO, reconnects, CTLFLAG_RD, &nfs_reconnects, 0,
125     "number of times the nfs client has had to reconnect");
126
127
128 /*
129  * There is a congestion window for outstanding rpcs maintained per mount
130  * point. The cwnd size is adjusted in roughly the way that:
131  * Van Jacobson, Congestion avoidance and Control, In "Proceedings of
132  * SIGCOMM '88". ACM, August 1988.
133  * describes for TCP. The cwnd size is chopped in half on a retransmit timeout
134  * and incremented by 1/cwnd when each rpc reply is received and a full cwnd
135  * of rpcs is in progress.
136  * (The sent count and cwnd are scaled for integer arith.)
137  * Variants of "slow start" were tried and were found to be too much of a
138  * performance hit (ave. rtt 3 times larger),
139  * I suspect due to the large rtt that nfs rpcs have.
140  */
141 #define NFS_CWNDSCALE   256
142 #define NFS_MAXCWND     (NFS_CWNDSCALE * 32)
143 #define NFS_NBACKOFF    8
144 static int nfs_backoff[NFS_NBACKOFF] = { 2, 4, 8, 16, 32, 64, 128, 256, };
145 struct callout  nfs_callout;
146
147 static int      nfs_msg(struct thread *, const char *, const char *, int);
148 static int      nfs_realign(struct mbuf **pm, int hsiz);
149 static int      nfs_reply(struct nfsreq *);
150 static void     nfs_softterm(struct nfsreq *rep);
151 static int      nfs_reconnect(struct nfsreq *rep);
152 static void nfs_clnt_tcp_soupcall(struct socket *so, void *arg, int waitflag);
153 static void nfs_clnt_udp_soupcall(struct socket *so, void *arg, int waitflag);
154 static void wakeup_nfsreq(struct nfsreq *req);
155
156 extern struct mtx nfs_reqq_mtx;
157 extern struct mtx nfs_reply_mtx;
158
159 /*
160  * Initialize sockets and congestion for a new NFS connection.
161  * We do not free the sockaddr if error.
162  */
163 int
164 nfs_connect(struct nfsmount *nmp, struct nfsreq *rep)
165 {
166         struct socket *so;
167         int error, rcvreserve, sndreserve;
168         int pktscale;
169         struct sockaddr *saddr;
170         struct thread *td = &thread0; /* only used for socreate and sobind */
171
172         NET_ASSERT_GIANT();
173
174         if (nmp->nm_sotype == SOCK_STREAM) {
175                 mtx_lock(&nmp->nm_nfstcpstate.mtx);
176                 nmp->nm_nfstcpstate.flags |= NFS_TCP_EXPECT_RPCMARKER;
177                 nmp->nm_nfstcpstate.rpcresid = 0;
178                 mtx_unlock(&nmp->nm_nfstcpstate.mtx);
179         }       
180         nmp->nm_so = NULL;
181         saddr = nmp->nm_nam;
182         error = socreate(saddr->sa_family, &nmp->nm_so, nmp->nm_sotype,
183                 nmp->nm_soproto, nmp->nm_mountp->mnt_cred, td);
184         if (error)
185                 goto bad;
186         so = nmp->nm_so;
187         nmp->nm_soflags = so->so_proto->pr_flags;
188
189         /*
190          * Some servers require that the client port be a reserved port number.
191          */
192         if (nmp->nm_flag & NFSMNT_RESVPORT) {
193                 struct sockopt sopt;
194                 int ip, ip2, len;
195                 struct sockaddr_in6 ssin;
196                 struct sockaddr *sa;
197
198                 bzero(&sopt, sizeof sopt);
199                 switch(saddr->sa_family) {
200                 case AF_INET:
201                         sopt.sopt_level = IPPROTO_IP;
202                         sopt.sopt_name = IP_PORTRANGE;
203                         ip = IP_PORTRANGE_LOW;
204                         ip2 = IP_PORTRANGE_DEFAULT;
205                         len = sizeof (struct sockaddr_in);
206                         break;
207 #ifdef INET6
208                 case AF_INET6:
209                         sopt.sopt_level = IPPROTO_IPV6;
210                         sopt.sopt_name = IPV6_PORTRANGE;
211                         ip = IPV6_PORTRANGE_LOW;
212                         ip2 = IPV6_PORTRANGE_DEFAULT;
213                         len = sizeof (struct sockaddr_in6);
214                         break;
215 #endif
216                 default:
217                         goto noresvport;
218                 }
219                 sa = (struct sockaddr *)&ssin;
220                 bzero(sa, len);
221                 sa->sa_len = len;
222                 sa->sa_family = saddr->sa_family;
223                 sopt.sopt_dir = SOPT_SET;
224                 sopt.sopt_val = (void *)&ip;
225                 sopt.sopt_valsize = sizeof(ip);
226                 error = sosetopt(so, &sopt);
227                 if (error)
228                         goto bad;
229                 error = sobind(so, sa, td);
230                 if (error)
231                         goto bad;
232                 ip = ip2;
233                 error = sosetopt(so, &sopt);
234                 if (error)
235                         goto bad;
236         noresvport: ;
237         }
238
239         /*
240          * Protocols that do not require connections may be optionally left
241          * unconnected for servers that reply from a port other than NFS_PORT.
242          */
243         if (nmp->nm_flag & NFSMNT_NOCONN) {
244                 if (nmp->nm_soflags & PR_CONNREQUIRED) {
245                         error = ENOTCONN;
246                         goto bad;
247                 }
248         } else {
249                 error = soconnect(so, nmp->nm_nam, td);
250                 if (error)
251                         goto bad;
252
253                 /*
254                  * Wait for the connection to complete. Cribbed from the
255                  * connect system call but with the wait timing out so
256                  * that interruptible mounts don't hang here for a long time.
257                  */
258                 SOCK_LOCK(so);
259                 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
260                         (void) msleep(&so->so_timeo, SOCK_MTX(so),
261                             PSOCK, "nfscon", 2 * hz);
262                         if ((so->so_state & SS_ISCONNECTING) &&
263                             so->so_error == 0 && rep &&
264                             (error = nfs_sigintr(nmp, rep, rep->r_td)) != 0) {
265                                 so->so_state &= ~SS_ISCONNECTING;
266                                 SOCK_UNLOCK(so);
267                                 goto bad;
268                         }
269                 }
270                 if (so->so_error) {
271                         error = so->so_error;
272                         so->so_error = 0;
273                         SOCK_UNLOCK(so);
274                         goto bad;
275                 }
276                 SOCK_UNLOCK(so);
277         }
278         so->so_rcv.sb_timeo = 12 * hz;
279         so->so_snd.sb_timeo = 5 * hz;
280
281         /*
282          * Get buffer reservation size from sysctl, but impose reasonable
283          * limits.
284          */
285         pktscale = nfs_bufpackets;
286         if (pktscale < 2)
287                 pktscale = 2;
288         if (pktscale > 64)
289                 pktscale = 64;
290
291         if (nmp->nm_sotype == SOCK_DGRAM) {
292                 sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR) * pktscale;
293                 rcvreserve = (max(nmp->nm_rsize, nmp->nm_readdirsize) +
294                     NFS_MAXPKTHDR) * pktscale;
295         } else if (nmp->nm_sotype == SOCK_SEQPACKET) {
296                 sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR) * pktscale;
297                 rcvreserve = (max(nmp->nm_rsize, nmp->nm_readdirsize) +
298                     NFS_MAXPKTHDR) * pktscale;
299         } else {
300                 if (nmp->nm_sotype != SOCK_STREAM)
301                         panic("nfscon sotype");
302                 if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
303                         struct sockopt sopt;
304                         int val;
305
306                         bzero(&sopt, sizeof sopt);
307                         sopt.sopt_dir = SOPT_SET;
308                         sopt.sopt_level = SOL_SOCKET;
309                         sopt.sopt_name = SO_KEEPALIVE;
310                         sopt.sopt_val = &val;
311                         sopt.sopt_valsize = sizeof val;
312                         val = 1;
313                         sosetopt(so, &sopt);
314                 }
315                 if (so->so_proto->pr_protocol == IPPROTO_TCP) {
316                         struct sockopt sopt;
317                         int val;
318
319                         bzero(&sopt, sizeof sopt);
320                         sopt.sopt_dir = SOPT_SET;
321                         sopt.sopt_level = IPPROTO_TCP;
322                         sopt.sopt_name = TCP_NODELAY;
323                         sopt.sopt_val = &val;
324                         sopt.sopt_valsize = sizeof val;
325                         val = 1;
326                         sosetopt(so, &sopt);
327                 }
328                 sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR +
329                     sizeof (u_int32_t)) * pktscale;
330                 rcvreserve = (nmp->nm_rsize + NFS_MAXPKTHDR +
331                     sizeof (u_int32_t)) * pktscale;
332         }
333         error = soreserve(so, sndreserve, rcvreserve);
334         if (error)
335                 goto bad;
336         SOCKBUF_LOCK(&so->so_rcv);
337         so->so_rcv.sb_flags |= SB_NOINTR;
338         so->so_upcallarg = (caddr_t)nmp;
339         if (so->so_type == SOCK_STREAM)
340                 so->so_upcall = nfs_clnt_tcp_soupcall;
341         else    
342                 so->so_upcall = nfs_clnt_udp_soupcall;
343         so->so_rcv.sb_flags |= SB_UPCALL;
344         SOCKBUF_UNLOCK(&so->so_rcv);
345         SOCKBUF_LOCK(&so->so_snd);
346         so->so_snd.sb_flags |= SB_NOINTR;
347         SOCKBUF_UNLOCK(&so->so_snd);
348
349         /* Initialize other non-zero congestion variables */
350         nmp->nm_srtt[0] = nmp->nm_srtt[1] = nmp->nm_srtt[2] =
351                 nmp->nm_srtt[3] = (NFS_TIMEO << 3);
352         nmp->nm_sdrtt[0] = nmp->nm_sdrtt[1] = nmp->nm_sdrtt[2] =
353                 nmp->nm_sdrtt[3] = 0;
354         nmp->nm_cwnd = NFS_MAXCWND / 2;     /* Initial send window */
355         nmp->nm_sent = 0;
356         nmp->nm_timeouts = 0;
357         return (0);
358
359 bad:
360         nfs_disconnect(nmp);
361         return (error);
362 }
363
364 /*
365  * Reconnect routine:
366  * Called when a connection is broken on a reliable protocol.
367  * - clean up the old socket
368  * - nfs_connect() again
369  * - set R_MUSTRESEND for all outstanding requests on mount point
370  * If this fails the mount point is DEAD!
371  * nb: Must be called with the nfs_sndlock() set on the mount point.
372  */
373 static int
374 nfs_reconnect(struct nfsreq *rep)
375 {
376         struct nfsreq *rp;
377         struct nfsmount *nmp = rep->r_nmp;
378         int error;
379
380         nfs_reconnects++;
381         nfs_disconnect(nmp);
382         while ((error = nfs_connect(nmp, rep)) != 0) {
383                 if (error == ERESTART)
384                         error = EINTR;
385                 if (error == EIO || error == EINTR)
386                         return (error);
387                 (void) tsleep(&lbolt, PSOCK, "nfscon", 0);
388         }
389
390         /*
391          * Clear the FORCE_RECONNECT flag only after the connect 
392          * succeeds. To prevent races between multiple processes 
393          * waiting on the mountpoint where the connection is being
394          * torn down. The first one to acquire the sndlock will 
395          * retry the connection. The others block on the sndlock
396          * until the connection is established successfully, and 
397          * then re-transmit the request.
398          */
399         mtx_lock(&nmp->nm_nfstcpstate.mtx);
400         nmp->nm_nfstcpstate.flags &= ~NFS_TCP_FORCE_RECONNECT;
401         mtx_unlock(&nmp->nm_nfstcpstate.mtx);   
402
403         /*
404          * Loop through outstanding request list and fix up all requests
405          * on old socket.
406          */
407         mtx_lock(&nfs_reqq_mtx);
408         TAILQ_FOREACH(rp, &nfs_reqq, r_chain) {
409                 if (rp->r_nmp == nmp)
410                         rp->r_flags |= R_MUSTRESEND;
411         }
412         mtx_unlock(&nfs_reqq_mtx);
413         return (0);
414 }
415
416 /*
417  * NFS disconnect. Clean up and unlink.
418  */
419 void
420 nfs_disconnect(struct nfsmount *nmp)
421 {
422         struct socket *so;
423
424         NET_ASSERT_GIANT();
425
426         if (nmp->nm_so) {
427                 so = nmp->nm_so;
428                 nmp->nm_so = NULL;
429                 SOCKBUF_LOCK(&so->so_rcv);
430                 so->so_upcallarg = NULL;
431                 so->so_upcall = NULL;
432                 so->so_rcv.sb_flags &= ~SB_UPCALL;
433                 SOCKBUF_UNLOCK(&so->so_rcv);
434                 soshutdown(so, SHUT_WR);
435                 soclose(so);
436         }
437 }
438
439 void
440 nfs_safedisconnect(struct nfsmount *nmp)
441 {
442         struct nfsreq dummyreq;
443
444         bzero(&dummyreq, sizeof(dummyreq));
445         dummyreq.r_nmp = nmp;
446         nfs_disconnect(nmp);
447 }
448
449 /*
450  * This is the nfs send routine. For connection based socket types, it
451  * must be called with an nfs_sndlock() on the socket.
452  * - return EINTR if the RPC is terminated, 0 otherwise
453  * - set R_MUSTRESEND if the send fails for any reason
454  * - do any cleanup required by recoverable socket errors (?)
455  */
456 int
457 nfs_send(struct socket *so, struct sockaddr *nam, struct mbuf *top,
458     struct nfsreq *rep)
459 {
460         struct sockaddr *sendnam;
461         int error, error2, soflags, flags;
462
463         NET_ASSERT_GIANT();
464
465         KASSERT(rep, ("nfs_send: called with rep == NULL"));
466
467         error = nfs_sigintr(rep->r_nmp, rep, rep->r_td);
468         if (error) {
469                 m_freem(top);
470                 return (error);
471         }
472         if ((so = rep->r_nmp->nm_so) == NULL) {
473                 rep->r_flags |= R_MUSTRESEND;
474                 m_freem(top);
475                 return (0);
476         }
477         rep->r_flags &= ~R_MUSTRESEND;
478         soflags = rep->r_nmp->nm_soflags;
479
480         if ((soflags & PR_CONNREQUIRED) || (so->so_state & SS_ISCONNECTED))
481                 sendnam = NULL;
482         else
483                 sendnam = nam;
484         if (so->so_type == SOCK_SEQPACKET)
485                 flags = MSG_EOR;
486         else
487                 flags = 0;
488
489         error = so->so_proto->pr_usrreqs->pru_sosend(so, sendnam, 0, top, 0,
490                                                      flags, curthread /*XXX*/);
491         if (error == ENOBUFS && so->so_type == SOCK_DGRAM) {
492                 error = 0;
493                 rep->r_flags |= R_MUSTRESEND;
494         }
495
496         if (error) {
497                 /*
498                  * Don't report EPIPE errors on nfs sockets.
499                  * These can be due to idle tcp mounts which will be closed by
500                  * netapp, solaris, etc. if left idle too long.
501                  */
502                 if (error != EPIPE) {
503                         log(LOG_INFO, "nfs send error %d for server %s\n",
504                             error,
505                             rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
506                 }
507                 /*
508                  * Deal with errors for the client side.
509                  */
510                 error2 = NFS_SIGREP(rep);
511                 if (error2)
512                         error = error2;
513                 else
514                         rep->r_flags |= R_MUSTRESEND;
515
516                 /*
517                  * Handle any recoverable (soft) socket errors here. (?)
518                  */
519                 if (error != EINTR && error != ERESTART && error != EIO &&
520                         error != EWOULDBLOCK && error != EPIPE)
521                         error = 0;
522         }
523         return (error);
524 }
525
526 int
527 nfs_reply(struct nfsreq *rep)
528 {
529         register struct socket *so;
530         register struct mbuf *m;
531         int error = 0, sotype, slpflag;
532
533         NET_ASSERT_GIANT();
534
535         sotype = rep->r_nmp->nm_sotype;
536         /*
537          * For reliable protocols, lock against other senders/receivers
538          * in case a reconnect is necessary.
539          */
540         if (sotype != SOCK_DGRAM) {
541                 error = nfs_sndlock(rep);
542                 if (error)
543                         return (error);
544 tryagain:
545                 if (rep->r_mrep) {
546                         nfs_sndunlock(rep);
547                         return (0);
548                 }
549                 if (rep->r_flags & R_SOFTTERM) {
550                         nfs_sndunlock(rep);
551                         return (EINTR);
552                 }
553                 so = rep->r_nmp->nm_so;
554                 mtx_lock(&rep->r_nmp->nm_nfstcpstate.mtx);
555                 if (!so || 
556                     (rep->r_nmp->nm_nfstcpstate.flags & NFS_TCP_FORCE_RECONNECT)) {
557                         mtx_unlock(&rep->r_nmp->nm_nfstcpstate.mtx);
558                         error = nfs_reconnect(rep);
559                         if (error) {
560                                 nfs_sndunlock(rep);
561                                 return (error);
562                         }
563                         goto tryagain;
564                 } else
565                         mtx_unlock(&rep->r_nmp->nm_nfstcpstate.mtx);
566                 while (rep->r_flags & R_MUSTRESEND) {
567                         m = m_copym(rep->r_mreq, 0, M_COPYALL, M_WAIT);
568                         nfsstats.rpcretries++;
569                         error = nfs_send(so, rep->r_nmp->nm_nam, m, rep);
570                         if (error) {
571                                 if (error == EINTR || error == ERESTART ||
572                                     (error = nfs_reconnect(rep)) != 0) {
573                                         nfs_sndunlock(rep);
574                                         return (error);
575                                 }
576                                 goto tryagain;
577                         }
578                 }
579                 nfs_sndunlock(rep);
580         }
581         slpflag = 0;
582         if (rep->r_nmp->nm_flag & NFSMNT_INT)
583                 slpflag = PCATCH;
584         mtx_lock(&nfs_reply_mtx);
585         while ((rep->r_mrep == NULL) && (error == 0) && 
586                ((rep->r_flags & R_SOFTTERM) == 0) &&
587                ((sotype == SOCK_DGRAM) || ((rep->r_flags & R_MUSTRESEND) == 0)))
588                 error = msleep((caddr_t)rep, &nfs_reply_mtx, 
589                                slpflag | (PZERO - 1), "nfsreq", 0);
590         mtx_unlock(&nfs_reply_mtx);
591         if (error == EINTR || error == ERESTART)
592                 /* NFS operations aren't restartable. Map ERESTART to EINTR */
593                 return (EINTR);
594         if (rep->r_flags & R_SOFTTERM)
595                 /* Request was terminated because we exceeded the retries (soft mount) */
596                 return (ETIMEDOUT);
597         if (sotype == SOCK_STREAM) {
598                 mtx_lock(&rep->r_nmp->nm_nfstcpstate.mtx);
599                 if (((rep->r_nmp->nm_nfstcpstate.flags & NFS_TCP_FORCE_RECONNECT) || 
600                      (rep->r_flags & R_MUSTRESEND))) {
601                         mtx_unlock(&rep->r_nmp->nm_nfstcpstate.mtx);    
602                         error = nfs_sndlock(rep);
603                         if (error)
604                                 return (error);
605                         goto tryagain;
606                 } else
607                         mtx_unlock(&rep->r_nmp->nm_nfstcpstate.mtx);
608         }
609         return (error);
610 }
611
612 /*
613  * XXX TO DO
614  * Make nfs_realign() non-blocking. Also make nfsm_dissect() nonblocking.
615  */
616 static void
617 nfs_clnt_match_xid(struct socket *so, 
618                    struct nfsmount *nmp, 
619                    struct mbuf *mrep)
620 {
621         struct mbuf *md;
622         caddr_t dpos;
623         u_int32_t rxid, *tl;
624         struct nfsreq *rep;
625         register int32_t t1;
626         int error;
627         
628         /*
629          * Search for any mbufs that are not a multiple of 4 bytes long
630          * or with m_data not longword aligned.
631          * These could cause pointer alignment problems, so copy them to
632          * well aligned mbufs.
633          */
634         if (nfs_realign(&mrep, 5 * NFSX_UNSIGNED) == ENOMEM) {
635                 m_freem(mrep);
636                 nfsstats.rpcinvalid++;
637                 return;
638         }
639         
640         /*
641          * Get the xid and check that it is an rpc reply
642          */
643         md = mrep;
644         dpos = mtod(md, caddr_t);
645         tl = nfsm_dissect_nonblock(u_int32_t *, 2*NFSX_UNSIGNED);
646         rxid = *tl++;
647         if (*tl != rpc_reply) {
648                 m_freem(mrep);
649 nfsmout:
650                 nfsstats.rpcinvalid++;
651                 return;
652         }
653
654         mtx_lock(&nfs_reqq_mtx);
655         /*
656          * Loop through the request list to match up the reply
657          * Iff no match, just drop the datagram
658          */
659         TAILQ_FOREACH(rep, &nfs_reqq, r_chain) {
660                 if (rep->r_mrep == NULL && rxid == rep->r_xid) {
661                         /* Found it.. */
662                         rep->r_mrep = mrep;
663                         rep->r_md = md;
664                         rep->r_dpos = dpos;
665                         /*
666                          * Update congestion window.
667                          * Do the additive increase of
668                          * one rpc/rtt.
669                          */
670                         if (nmp->nm_cwnd <= nmp->nm_sent) {
671                                 nmp->nm_cwnd +=
672                                         (NFS_CWNDSCALE * NFS_CWNDSCALE +
673                                          (nmp->nm_cwnd >> 1)) / nmp->nm_cwnd;
674                                 if (nmp->nm_cwnd > NFS_MAXCWND)
675                                         nmp->nm_cwnd = NFS_MAXCWND;
676                         }       
677                         if (rep->r_flags & R_SENT) {
678                                 rep->r_flags &= ~R_SENT;
679                                 nmp->nm_sent -= NFS_CWNDSCALE;
680                         }
681                         /*
682                          * Update rtt using a gain of 0.125 on the mean
683                          * and a gain of 0.25 on the deviation.
684                          */
685                         if (rep->r_flags & R_TIMING) {
686                                 /*
687                                  * Since the timer resolution of
688                                  * NFS_HZ is so course, it can often
689                                  * result in r_rtt == 0. Since
690                                  * r_rtt == N means that the actual
691                                  * rtt is between N+dt and N+2-dt ticks,
692                                  * add 1.
693                                  */
694                                 t1 = rep->r_rtt + 1;
695                                 t1 -= (NFS_SRTT(rep) >> 3);
696                                 NFS_SRTT(rep) += t1;
697                                 if (t1 < 0)
698                                         t1 = -t1;
699                                 t1 -= (NFS_SDRTT(rep) >> 2);
700                                 NFS_SDRTT(rep) += t1;
701                         }
702                         nmp->nm_timeouts = 0;
703                         break;
704                 }
705         }
706         /*
707          * If not matched to a request, drop it.
708          * If it's mine, wake up requestor.
709          */
710         if (rep == 0) {
711                 nfsstats.rpcunexpected++;
712                 m_freem(mrep);
713         } else
714                 wakeup_nfsreq(rep);
715         mtx_unlock(&nfs_reqq_mtx);
716 }
717
718 /* 
719  * The wakeup of the requestor should be done under the mutex
720  * to avoid potential missed wakeups.
721  */
722 static void 
723 wakeup_nfsreq(struct nfsreq *req)
724 {
725         mtx_lock(&nfs_reply_mtx);
726         wakeup((caddr_t)req);
727         mtx_unlock(&nfs_reply_mtx);     
728 }
729
730 static void
731 nfs_mark_for_reconnect(struct nfsmount *nmp)
732 {
733         struct nfsreq *rp;
734
735         mtx_lock(&nmp->nm_nfstcpstate.mtx);
736         nmp->nm_nfstcpstate.flags |= NFS_TCP_FORCE_RECONNECT;
737         mtx_unlock(&nmp->nm_nfstcpstate.mtx);
738         /* 
739          * Wakeup all processes that are waiting for replies 
740          * on this mount point. One of them does the reconnect.
741          */
742         mtx_lock(&nfs_reqq_mtx);
743         TAILQ_FOREACH(rp, &nfs_reqq, r_chain) {
744                 if (rp->r_nmp == nmp) {
745                         rp->r_flags |= R_MUSTRESEND;
746                         wakeup_nfsreq(rp);
747                 }
748         }
749         mtx_unlock(&nfs_reqq_mtx);
750 }
751
752 static int
753 nfstcp_readable(struct socket *so, int bytes)
754 {
755         int retval;
756         
757         SOCKBUF_LOCK(&so->so_rcv);
758         retval = (so->so_rcv.sb_cc >= (bytes) ||
759                   (so->so_rcv.sb_state & SBS_CANTRCVMORE) ||
760                   so->so_error);
761         SOCKBUF_UNLOCK(&so->so_rcv);
762         return (retval);
763 }
764
765 #define nfstcp_marker_readable(so)      nfstcp_readable(so, sizeof(u_int32_t))
766
767 static void
768 nfs_clnt_tcp_soupcall(struct socket *so, void *arg, int waitflag)
769 {
770         struct nfsmount *nmp = (struct nfsmount *)arg;
771         struct mbuf *mp = NULL;
772         struct uio auio;
773         int error;
774         u_int32_t len;
775         int rcvflg;
776
777         /*
778          * Don't pick any more data from the socket if we've marked the 
779          * mountpoint for reconnect.
780          */
781         mtx_lock(&nmp->nm_nfstcpstate.mtx);
782         if (nmp->nm_nfstcpstate.flags & NFS_TCP_FORCE_RECONNECT) {
783                 mtx_unlock(&nmp->nm_nfstcpstate.mtx);           
784                 return;
785         } else                  
786                 mtx_unlock(&nmp->nm_nfstcpstate.mtx);
787         auio.uio_td = curthread;
788         auio.uio_segflg = UIO_SYSSPACE;
789         auio.uio_rw = UIO_READ;
790         for ( ; ; ) {
791                 if (nmp->nm_nfstcpstate.flags & NFS_TCP_EXPECT_RPCMARKER) {
792                         if (!nfstcp_marker_readable(so)) {
793                                 /* Marker is not readable */
794                                 return;
795                         }
796                         auio.uio_resid = sizeof(u_int32_t);
797                         auio.uio_iov = NULL;
798                         auio.uio_iovcnt = 0;
799                         mp = NULL;
800                         rcvflg = (MSG_DONTWAIT | MSG_SOCALLBCK);
801                         error =  so->so_proto->pr_usrreqs->pru_soreceive
802                                 (so, (struct sockaddr **)0,
803                                  &auio, &mp, (struct mbuf **)0, &rcvflg);
804                         /*
805                          * We've already tested that the socket is readable. 2 cases 
806                          * here, we either read 0 bytes (client closed connection), 
807                          * or got some other error. In both cases, we tear down the 
808                          * connection.
809                          */
810                         if (error || auio.uio_resid > 0) {
811                                 if (error && error != ECONNRESET) {
812                                         log(LOG_ERR, 
813                                             "nfs/tcp clnt: Error %d reading socket, tearing down TCP connection\n",
814                                             error);
815                                 }
816                                 goto mark_reconnect;
817                         }
818                         if (mp == NULL)
819                                 panic("nfs_clnt_tcp_soupcall: Got empty mbuf chain from sorecv\n");
820                         bcopy(mtod(mp, u_int32_t *), &len, sizeof(len));
821                         len = ntohl(len) & ~0x80000000;
822                         m_freem(mp);
823                         /*
824                          * This is SERIOUS! We are out of sync with the sender
825                          * and forcing a disconnect/reconnect is all I can do.
826                          */
827                         if (len > NFS_MAXPACKET || len == 0) {
828                                 log(LOG_ERR, "%s (%d) from nfs server %s\n",
829                                     "impossible packet length",
830                                     len,
831                                     nmp->nm_mountp->mnt_stat.f_mntfromname);
832                                 goto mark_reconnect;
833                         }
834                         nmp->nm_nfstcpstate.rpcresid = len;
835                         nmp->nm_nfstcpstate.flags &= ~(NFS_TCP_EXPECT_RPCMARKER);
836                 }
837                 /* 
838                  * Processed RPC marker or no RPC marker to process. 
839                  * Pull in and process data.
840                  */
841                 if (nmp->nm_nfstcpstate.rpcresid > 0) {
842                         if (!nfstcp_readable(so, nmp->nm_nfstcpstate.rpcresid)) {
843                                 /* All data not readable */
844                                 return;
845                         }
846                         auio.uio_resid = nmp->nm_nfstcpstate.rpcresid;
847                         auio.uio_iov = NULL;
848                         auio.uio_iovcnt = 0;
849                         mp = NULL;
850                         rcvflg = (MSG_DONTWAIT | MSG_SOCALLBCK);
851                         error =  so->so_proto->pr_usrreqs->pru_soreceive
852                                 (so, (struct sockaddr **)0,
853                                  &auio, &mp, (struct mbuf **)0, &rcvflg);
854                         if (error || auio.uio_resid > 0) {
855                                 if (error && error != ECONNRESET) {
856                                         log(LOG_ERR, 
857                                             "nfs/tcp clnt: Error %d reading socket, tearing down TCP connection\n",
858                                             error);
859                                 }
860                                 goto mark_reconnect;                            
861                         }
862                         if (mp == NULL)
863                                 panic("nfs_clnt_tcp_soupcall: Got empty mbuf chain from sorecv\n");
864                         nmp->nm_nfstcpstate.rpcresid = 0;
865                         nmp->nm_nfstcpstate.flags |= NFS_TCP_EXPECT_RPCMARKER;
866                         /* We got the entire RPC reply. Match XIDs and wake up requestor */
867                         nfs_clnt_match_xid(so, nmp, mp);
868                 }
869         }
870
871 mark_reconnect:
872         nfs_mark_for_reconnect(nmp);
873 }
874
875 static void
876 nfs_clnt_udp_soupcall(struct socket *so, void *arg, int waitflag)
877 {
878         struct nfsmount *nmp = (struct nfsmount *)arg;
879         struct uio auio;
880         struct mbuf *mp = NULL;
881         struct mbuf *control = NULL;
882         int error, rcvflag;
883
884         auio.uio_resid = 1000000;
885         auio.uio_td = curthread;
886         rcvflag = MSG_DONTWAIT;
887         auio.uio_resid = 1000000000;
888         do {
889                 mp = control = NULL;
890                 error = so->so_proto->pr_usrreqs->pru_soreceive(so,
891                                         NULL, &auio, &mp,
892                                         &control, &rcvflag);
893                 if (control)
894                         m_freem(control);
895                 if (mp)
896                         nfs_clnt_match_xid(so, nmp, mp);
897         } while (mp && !error);
898 }
899
900 /*
901  * nfs_request - goes something like this
902  *      - fill in request struct
903  *      - links it into list
904  *      - calls nfs_send() for first transmit
905  *      - calls nfs_receive() to get reply
906  *      - break down rpc header and return with nfs reply pointed to
907  *        by mrep or error
908  * nb: always frees up mreq mbuf list
909  */
910 /* XXX overloaded before */
911 #define NQ_TRYLATERDEL  15      /* Initial try later delay (sec) */
912
913 int
914 nfs_request(struct vnode *vp, struct mbuf *mrest, int procnum,
915     struct thread *td, struct ucred *cred, struct mbuf **mrp,
916     struct mbuf **mdp, caddr_t *dposp)
917 {
918         struct mbuf *mrep, *m2;
919         struct nfsreq *rep;
920         u_int32_t *tl;
921         int i;
922         struct nfsmount *nmp;
923         struct mbuf *m, *md, *mheadend;
924         time_t waituntil;
925         caddr_t dpos;
926         int s, error = 0, mrest_len, auth_len, auth_type;
927         int trylater_delay = NQ_TRYLATERDEL, trylater_cnt = 0;
928         struct timeval now;
929         u_int32_t *xidp;
930
931         /* Reject requests while attempting a forced unmount. */
932         if (vp->v_mount->mnt_kern_flag & MNTK_UNMOUNTF) {
933                 m_freem(mrest);
934                 return (ESTALE);
935         }
936         nmp = VFSTONFS(vp->v_mount);
937         if ((nmp->nm_flag & NFSMNT_NFSV4) != 0)
938                 return nfs4_request(vp, mrest, procnum, td, cred, mrp, mdp, dposp);
939         MALLOC(rep, struct nfsreq *, sizeof(struct nfsreq), M_NFSREQ, M_WAITOK);
940         rep->r_mrep = rep->r_md = NULL;
941         rep->r_nmp = nmp;
942         rep->r_vp = vp;
943         rep->r_td = td;
944         rep->r_procnum = procnum;
945
946         getmicrouptime(&now);
947         rep->r_lastmsg = now.tv_sec -
948             ((nmp->nm_tprintf_delay) - (nmp->nm_tprintf_initial_delay));
949         mrest_len = m_length(mrest, NULL);
950
951         /*
952          * Get the RPC header with authorization.
953          */
954         auth_type = RPCAUTH_UNIX;
955         if (cred->cr_ngroups < 1)
956                 panic("nfsreq nogrps");
957         auth_len = ((((cred->cr_ngroups - 1) > nmp->nm_numgrps) ?
958                 nmp->nm_numgrps : (cred->cr_ngroups - 1)) << 2) +
959                 5 * NFSX_UNSIGNED;
960         m = nfsm_rpchead(cred, nmp->nm_flag, procnum, auth_type, auth_len,
961              mrest, mrest_len, &mheadend, &xidp);
962
963         /*
964          * For stream protocols, insert a Sun RPC Record Mark.
965          */
966         if (nmp->nm_sotype == SOCK_STREAM) {
967                 M_PREPEND(m, NFSX_UNSIGNED, M_TRYWAIT);
968                 *mtod(m, u_int32_t *) = htonl(0x80000000 |
969                          (m->m_pkthdr.len - NFSX_UNSIGNED));
970         }
971         rep->r_mreq = m;
972         rep->r_xid = *xidp;
973 tryagain:
974         if (nmp->nm_flag & NFSMNT_SOFT)
975                 rep->r_retry = nmp->nm_retry;
976         else
977                 rep->r_retry = NFS_MAXREXMIT + 1;       /* past clip limit */
978         rep->r_rtt = rep->r_rexmit = 0;
979         if (proct[procnum] > 0)
980                 rep->r_flags = R_TIMING;
981         else
982                 rep->r_flags = 0;
983         rep->r_mrep = NULL;
984
985         /*
986          * Do the client side RPC.
987          */
988         nfsstats.rpcrequests++;
989         /*
990          * Chain request into list of outstanding requests. Be sure
991          * to put it LAST so timer finds oldest requests first.
992          */
993         s = splsoftclock();
994         mtx_lock(&nfs_reqq_mtx);
995         if (TAILQ_EMPTY(&nfs_reqq))
996                 callout_reset(&nfs_callout, nfs_ticks, nfs_timer, NULL);
997         TAILQ_INSERT_TAIL(&nfs_reqq, rep, r_chain);
998         mtx_unlock(&nfs_reqq_mtx);
999
1000         /*
1001          * If backing off another request or avoiding congestion, don't
1002          * send this one now but let timer do it. If not timing a request,
1003          * do it now.
1004          */
1005         if (nmp->nm_so && (nmp->nm_sotype != SOCK_DGRAM ||
1006                 (nmp->nm_flag & NFSMNT_DUMBTIMR) ||
1007                 nmp->nm_sent < nmp->nm_cwnd)) {
1008                 splx(s);
1009                 error = nfs_sndlock(rep);
1010                 if (!error) {
1011                         m2 = m_copym(m, 0, M_COPYALL, M_TRYWAIT);
1012                         error = nfs_send(nmp->nm_so, nmp->nm_nam, m2, rep);
1013                         nfs_sndunlock(rep);
1014                 }
1015                 mtx_lock(&nfs_reqq_mtx);
1016                 /* 
1017                  * nfs_timer() could've re-transmitted the request if we ended up
1018                  * blocking on nfs_send() too long, so check for R_SENT here.
1019                  */
1020                 if (!error && (rep->r_flags & (R_SENT | R_MUSTRESEND)) == 0) {
1021                         nmp->nm_sent += NFS_CWNDSCALE;
1022                         rep->r_flags |= R_SENT;
1023                 }
1024                 mtx_unlock(&nfs_reqq_mtx);
1025         } else {
1026                 splx(s);
1027                 rep->r_rtt = -1;
1028         }
1029
1030         /*
1031          * Wait for the reply from our send or the timer's.
1032          */
1033         if (!error || error == EPIPE)
1034                 error = nfs_reply(rep);
1035
1036         /*
1037          * RPC done, unlink the request.
1038          */
1039         s = splsoftclock();
1040         mtx_lock(&nfs_reqq_mtx);
1041         /*
1042          * nfs_timer() may be in the process of re-transmitting this request.
1043          * nfs_timer() drops the nfs_reqq_mtx before the pru_send() (to avoid LORs).
1044          * Wait till nfs_timer() completes the re-transmission. When the reply 
1045          * comes back, it will be discarded (since the req struct for it no longer 
1046          * exists).
1047          */
1048         while (rep->r_flags & R_REXMIT_INPROG) {
1049                 msleep((caddr_t)&rep->r_flags, &nfs_reqq_mtx, 
1050                        (PZERO - 1), "nfsrxmt", 0);
1051         }
1052         TAILQ_REMOVE(&nfs_reqq, rep, r_chain);
1053         if (TAILQ_EMPTY(&nfs_reqq))
1054                 callout_stop(&nfs_callout);
1055         /*
1056          * Decrement the outstanding request count.
1057          */
1058         if (rep->r_flags & R_SENT) {
1059                 rep->r_flags &= ~R_SENT;        /* paranoia */
1060                 nmp->nm_sent -= NFS_CWNDSCALE;
1061         }
1062         mtx_unlock(&nfs_reqq_mtx);
1063         splx(s);
1064
1065         /*
1066          * If there was a successful reply and a tprintf msg.
1067          * tprintf a response.
1068          */
1069         if (!error) {
1070                 mtx_lock(&Giant);
1071                 nfs_up(rep, nmp, rep->r_td, "is alive again", NFSSTA_TIMEO);
1072                 mtx_unlock(&Giant);
1073         }
1074         mrep = rep->r_mrep;
1075         md = rep->r_md;
1076         dpos = rep->r_dpos;
1077         if (error) {
1078                 /*
1079                  * If we got interrupted by a signal in nfs_reply(), there's
1080                  * a very small window where the reply could've come in before
1081                  * this process got scheduled in. To handle that case, we need 
1082                  * to free the reply if it was delivered.
1083                  */
1084                 if (rep->r_mrep != NULL)
1085                         m_freem(rep->r_mrep);
1086                 m_freem(rep->r_mreq);
1087                 free((caddr_t)rep, M_NFSREQ);
1088                 return (error);
1089         }
1090
1091         if (rep->r_mrep == NULL)
1092                 panic("nfs_request: rep->r_mrep shouldn't be NULL if no error\n");
1093
1094         /*
1095          * break down the rpc header and check if ok
1096          */
1097         tl = nfsm_dissect(u_int32_t *, 3 * NFSX_UNSIGNED);
1098         if (*tl++ == rpc_msgdenied) {
1099                 if (*tl == rpc_mismatch)
1100                         error = EOPNOTSUPP;
1101                 else
1102                         error = EACCES;
1103                 m_freem(mrep);
1104                 m_freem(rep->r_mreq);
1105                 free((caddr_t)rep, M_NFSREQ);
1106                 return (error);
1107         }
1108
1109         /*
1110          * Just throw away any verifyer (ie: kerberos etc).
1111          */
1112         i = fxdr_unsigned(int, *tl++);          /* verf type */
1113         i = fxdr_unsigned(int32_t, *tl);        /* len */
1114         if (i > 0)
1115                 nfsm_adv(nfsm_rndup(i));
1116         tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
1117         /* 0 == ok */
1118         if (*tl == 0) {
1119                 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
1120                 if (*tl != 0) {
1121                         error = fxdr_unsigned(int, *tl);
1122                         if ((nmp->nm_flag & NFSMNT_NFSV3) &&
1123                                 error == NFSERR_TRYLATER) {
1124                                 m_freem(mrep);
1125                                 error = 0;
1126                                 waituntil = time_second + trylater_delay;
1127                                 while (time_second < waituntil)
1128                                         (void) tsleep(&lbolt,
1129                                                 PSOCK, "nqnfstry", 0);
1130                                 trylater_delay *= nfs_backoff[trylater_cnt];
1131                                 if (trylater_cnt < NFS_NBACKOFF - 1)
1132                                         trylater_cnt++;
1133                                 if (++nfs_xid == 0)
1134                                         nfs_xid++;
1135                                 rep->r_xid = *xidp = txdr_unsigned(nfs_xid);
1136                                 goto tryagain;
1137                         }
1138
1139                         /*
1140                          * If the File Handle was stale, invalidate the
1141                          * lookup cache, just in case.
1142                          */
1143                         if (error == ESTALE)
1144                                 cache_purge(vp);
1145                         if (nmp->nm_flag & NFSMNT_NFSV3) {
1146                                 *mrp = mrep;
1147                                 *mdp = md;
1148                                 *dposp = dpos;
1149                                 error |= NFSERR_RETERR;
1150                         } else
1151                                 m_freem(mrep);
1152                         m_freem(rep->r_mreq);
1153                         free((caddr_t)rep, M_NFSREQ);
1154                         return (error);
1155                 }
1156
1157                 *mrp = mrep;
1158                 *mdp = md;
1159                 *dposp = dpos;
1160                 m_freem(rep->r_mreq);
1161                 FREE((caddr_t)rep, M_NFSREQ);
1162                 return (0);
1163         }
1164         m_freem(mrep);
1165         error = EPROTONOSUPPORT;
1166 nfsmout:
1167         m_freem(rep->r_mreq);
1168         free((caddr_t)rep, M_NFSREQ);
1169         return (error);
1170 }
1171
1172 /*
1173  * Nfs timer routine
1174  * Scan the nfsreq list and retranmit any requests that have timed out
1175  * To avoid retransmission attempts on STREAM sockets (in the future) make
1176  * sure to set the r_retry field to 0 (implies nm_retry == 0).
1177  * 
1178  * The nfs reqq lock cannot be held while we do the pru_send() because of a
1179  * lock ordering violation. The NFS client socket callback acquires 
1180  * inp_lock->nfsreq mutex and pru_send acquires inp_lock. So we drop the 
1181  * reqq mutex (and reacquire it after the pru_send()). The req structure
1182  * (for the rexmit) is prevented from being removed by the R_REXMIT_INPROG flag.
1183  */
1184 void
1185 nfs_timer(void *arg)
1186 {
1187         struct nfsreq *rep;
1188         struct mbuf *m;
1189         struct socket *so;
1190         struct nfsmount *nmp;
1191         int timeo;
1192         int s, error;
1193         struct timeval now;
1194
1195         getmicrouptime(&now);
1196         s = splnet();
1197         mtx_lock(&Giant);       /* nfs_down -> tprintf */
1198         mtx_lock(&nfs_reqq_mtx);
1199         TAILQ_FOREACH(rep, &nfs_reqq, r_chain) {
1200                 nmp = rep->r_nmp;
1201                 if (rep->r_mrep || (rep->r_flags & R_SOFTTERM))
1202                         continue;
1203                 if (nfs_sigintr(nmp, rep, rep->r_td))
1204                         continue;
1205                 if (nmp->nm_tprintf_initial_delay != 0 &&
1206                     (rep->r_rexmit > 2 || (rep->r_flags & R_RESENDERR)) &&
1207                     rep->r_lastmsg + nmp->nm_tprintf_delay < now.tv_sec) {
1208                         rep->r_lastmsg = now.tv_sec;
1209                         nfs_down(rep, nmp, rep->r_td, "not responding",
1210                             0, NFSSTA_TIMEO);
1211 #if 0
1212                         if (!(nmp->nm_state & NFSSTA_MOUNTED)) {
1213                                 /* we're not yet completely mounted and */
1214                                 /* we can't complete an RPC, so we fail */
1215                                 nfsstats.rpctimeouts++;
1216                                 nfs_softterm(rep);
1217                                 continue;
1218                         }
1219 #endif
1220                 }
1221                 if (rep->r_rtt >= 0) {
1222                         rep->r_rtt++;
1223                         if (nmp->nm_flag & NFSMNT_DUMBTIMR)
1224                                 timeo = nmp->nm_timeo;
1225                         else
1226                                 timeo = NFS_RTO(nmp, proct[rep->r_procnum]);
1227                         if (nmp->nm_timeouts > 0)
1228                                 timeo *= nfs_backoff[nmp->nm_timeouts - 1];
1229                         if (rep->r_rtt <= timeo)
1230                                 continue;
1231                         if (nmp->nm_timeouts < NFS_NBACKOFF)
1232                                 nmp->nm_timeouts++;
1233                 }
1234                 if (rep->r_rexmit >= rep->r_retry) {    /* too many */
1235                         nfsstats.rpctimeouts++;
1236                         nfs_softterm(rep);
1237                         continue;
1238                 }
1239                 if (nmp->nm_sotype != SOCK_DGRAM) {
1240                         if (++rep->r_rexmit > NFS_MAXREXMIT)
1241                                 rep->r_rexmit = NFS_MAXREXMIT;
1242                         /*
1243                          * For NFS/TCP, setting R_MUSTRESEND and waking up 
1244                          * the requester will cause the request to be   
1245                          * retransmitted (in nfs_reply()), re-connecting
1246                          * if necessary.
1247                          */
1248                         rep->r_flags |= R_MUSTRESEND;
1249                         wakeup_nfsreq(rep);
1250                         continue;
1251                 }
1252                 if ((so = nmp->nm_so) == NULL)
1253                         continue;
1254                 /*
1255                  * If there is enough space and the window allows..
1256                  *      Resend it
1257                  * Set r_rtt to -1 in case we fail to send it now.
1258                  */
1259                 rep->r_rtt = -1;
1260                 if (sbspace(&so->so_snd) >= rep->r_mreq->m_pkthdr.len &&
1261                    ((nmp->nm_flag & NFSMNT_DUMBTIMR) ||
1262                     (rep->r_flags & R_SENT) ||
1263                     nmp->nm_sent < nmp->nm_cwnd) &&
1264                    (m = m_copym(rep->r_mreq, 0, M_COPYALL, M_DONTWAIT))) {
1265                         /*
1266                          * Mark the request to indicate that a XMIT is in progress
1267                          * to prevent the req structure being removed in nfs_request().
1268                          */
1269                         rep->r_flags |= R_REXMIT_INPROG;
1270                         mtx_unlock(&nfs_reqq_mtx);
1271                         NET_LOCK_GIANT();
1272                         if ((nmp->nm_flag & NFSMNT_NOCONN) == 0)
1273                             error = (*so->so_proto->pr_usrreqs->pru_send)
1274                                     (so, 0, m, NULL, NULL, curthread);
1275                         else
1276                             error = (*so->so_proto->pr_usrreqs->pru_send)
1277                                     (so, 0, m, nmp->nm_nam, NULL, curthread);
1278                         NET_UNLOCK_GIANT();
1279                         mtx_lock(&nfs_reqq_mtx);
1280                         rep->r_flags &= ~R_REXMIT_INPROG;
1281                         wakeup((caddr_t)&rep->r_flags);
1282                         if (error) {
1283                                 if (NFSIGNORE_SOERROR(nmp->nm_soflags, error))
1284                                         so->so_error = 0;
1285                                 rep->r_flags |= R_RESENDERR;
1286                         } else {
1287                                 /*
1288                                  * Iff first send, start timing
1289                                  * else turn timing off, backoff timer
1290                                  * and divide congestion window by 2.
1291                                  */
1292                                 rep->r_flags &= ~R_RESENDERR;
1293                                 if (rep->r_flags & R_SENT) {
1294                                         rep->r_flags &= ~R_TIMING;
1295                                         if (++rep->r_rexmit > NFS_MAXREXMIT)
1296                                                 rep->r_rexmit = NFS_MAXREXMIT;
1297                                         nmp->nm_cwnd >>= 1;
1298                                         if (nmp->nm_cwnd < NFS_CWNDSCALE)
1299                                                 nmp->nm_cwnd = NFS_CWNDSCALE;
1300                                         nfsstats.rpcretries++;
1301                                 } else {
1302                                         rep->r_flags |= R_SENT;
1303                                         nmp->nm_sent += NFS_CWNDSCALE;
1304                                 }
1305                                 rep->r_rtt = 0;
1306                         }
1307                 }
1308         }
1309         mtx_unlock(&nfs_reqq_mtx);
1310         mtx_unlock(&Giant);     /* nfs_down -> tprintf */
1311         splx(s);
1312         callout_reset(&nfs_callout, nfs_ticks, nfs_timer, NULL);
1313 }
1314
1315 /*
1316  * Mark all of an nfs mount's outstanding requests with R_SOFTTERM and
1317  * wait for all requests to complete. This is used by forced unmounts
1318  * to terminate any outstanding RPCs.
1319  */
1320 int
1321 nfs_nmcancelreqs(nmp)
1322         struct nfsmount *nmp;
1323 {
1324         struct nfsreq *req;
1325         int i, s;
1326
1327         s = splnet();
1328         mtx_lock(&nfs_reqq_mtx);
1329         TAILQ_FOREACH(req, &nfs_reqq, r_chain) {
1330                 if (nmp != req->r_nmp || req->r_mrep != NULL ||
1331                     (req->r_flags & R_SOFTTERM))
1332                         continue;
1333                 nfs_softterm(req);
1334         }
1335         mtx_unlock(&nfs_reqq_mtx);
1336         splx(s);
1337
1338         for (i = 0; i < 30; i++) {
1339                 s = splnet();
1340                 mtx_lock(&nfs_reqq_mtx);
1341                 TAILQ_FOREACH(req, &nfs_reqq, r_chain) {
1342                         if (nmp == req->r_nmp)
1343                                 break;
1344                 }
1345                 mtx_unlock(&nfs_reqq_mtx);
1346                 splx(s);
1347                 if (req == NULL)
1348                         return (0);
1349                 tsleep(&lbolt, PSOCK, "nfscancel", 0);
1350         }
1351         return (EBUSY);
1352 }
1353
1354 /*
1355  * Flag a request as being about to terminate (due to NFSMNT_INT/NFSMNT_SOFT).
1356  * The nm_send count is decremented now to avoid deadlocks when the process in
1357  * soreceive() hasn't yet managed to send its own request.
1358  */
1359
1360 static void
1361 nfs_softterm(struct nfsreq *rep)
1362 {
1363
1364         rep->r_flags |= R_SOFTTERM;
1365         if (rep->r_flags & R_SENT) {
1366                 rep->r_nmp->nm_sent -= NFS_CWNDSCALE;
1367                 rep->r_flags &= ~R_SENT;
1368         }
1369         /* 
1370          * Request terminated, wakeup the blocked process, so that we
1371          * can return EINTR back.
1372          */
1373         wakeup_nfsreq(rep);
1374 }
1375
1376 /*
1377  * Any signal that can interrupt an NFS operation in an intr mount
1378  * should be added to this set. SIGSTOP and SIGKILL cannot be masked.
1379  */
1380 int nfs_sig_set[] = {
1381         SIGINT,
1382         SIGTERM,
1383         SIGHUP,
1384         SIGKILL,
1385         SIGSTOP,
1386         SIGQUIT
1387 };
1388
1389 /*
1390  * Check to see if one of the signals in our subset is pending on
1391  * the process (in an intr mount).
1392  */
1393 static int
1394 nfs_sig_pending(sigset_t set)
1395 {
1396         int i;
1397         
1398         for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++)
1399                 if (SIGISMEMBER(set, nfs_sig_set[i]))
1400                         return (1);
1401         return (0);
1402 }
1403  
1404 /*
1405  * The set/restore sigmask functions are used to (temporarily) overwrite
1406  * the process p_sigmask during an RPC call (for example). These are also
1407  * used in other places in the NFS client that might tsleep().
1408  */
1409 void
1410 nfs_set_sigmask(struct thread *td, sigset_t *oldset)
1411 {
1412         sigset_t newset;
1413         int i;
1414         struct proc *p;
1415         
1416         SIGFILLSET(newset);
1417         if (td == NULL)
1418                 td = curthread; /* XXX */
1419         p = td->td_proc;
1420         /* Remove the NFS set of signals from newset */
1421         PROC_LOCK(p);
1422         mtx_lock(&p->p_sigacts->ps_mtx);
1423         for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++) {
1424                 /*
1425                  * But make sure we leave the ones already masked
1426                  * by the process, ie. remove the signal from the
1427                  * temporary signalmask only if it wasn't already
1428                  * in p_sigmask.
1429                  */
1430                 if (!SIGISMEMBER(td->td_sigmask, nfs_sig_set[i]) &&
1431                     !SIGISMEMBER(p->p_sigacts->ps_sigignore, nfs_sig_set[i]))
1432                         SIGDELSET(newset, nfs_sig_set[i]);
1433         }
1434         mtx_unlock(&p->p_sigacts->ps_mtx);
1435         PROC_UNLOCK(p);
1436         kern_sigprocmask(td, SIG_SETMASK, &newset, oldset, 0);
1437 }
1438
1439 void
1440 nfs_restore_sigmask(struct thread *td, sigset_t *set)
1441 {
1442         if (td == NULL)
1443                 td = curthread; /* XXX */
1444         kern_sigprocmask(td, SIG_SETMASK, set, NULL, 0);
1445 }
1446
1447 /*
1448  * NFS wrapper to msleep(), that shoves a new p_sigmask and restores the
1449  * old one after msleep() returns.
1450  */
1451 int
1452 nfs_msleep(struct thread *td, void *ident, struct mtx *mtx, int priority, char *wmesg, int timo)
1453 {
1454         sigset_t oldset;
1455         int error;
1456         struct proc *p;
1457         
1458         if ((priority & PCATCH) == 0)
1459                 return msleep(ident, mtx, priority, wmesg, timo);
1460         if (td == NULL)
1461                 td = curthread; /* XXX */
1462         nfs_set_sigmask(td, &oldset);
1463         error = msleep(ident, mtx, priority, wmesg, timo);
1464         nfs_restore_sigmask(td, &oldset);
1465         p = td->td_proc;
1466         return (error);
1467 }
1468
1469 /*
1470  * NFS wrapper to tsleep(), that shoves a new p_sigmask and restores the
1471  * old one after tsleep() returns.
1472  */
1473 int
1474 nfs_tsleep(struct thread *td, void *ident, int priority, char *wmesg, int timo)
1475 {
1476         sigset_t oldset;
1477         int error;
1478         struct proc *p;
1479         
1480         if ((priority & PCATCH) == 0)
1481                 return tsleep(ident, priority, wmesg, timo);
1482         if (td == NULL)
1483                 td = curthread; /* XXX */
1484         nfs_set_sigmask(td, &oldset);
1485         error = tsleep(ident, priority, wmesg, timo);
1486         nfs_restore_sigmask(td, &oldset);
1487         p = td->td_proc;
1488         return (error);
1489 }
1490
1491 /*
1492  * Test for a termination condition pending on the process.
1493  * This is used for NFSMNT_INT mounts.
1494  */
1495 int
1496 nfs_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td)
1497 {
1498         struct proc *p;
1499         sigset_t tmpset;
1500
1501         if ((nmp->nm_flag & NFSMNT_NFSV4) != 0)
1502                 return nfs4_sigintr(nmp, rep, td);
1503         if (rep && (rep->r_flags & R_SOFTTERM))
1504                 return (EIO);
1505         /* Terminate all requests while attempting a forced unmount. */
1506         if (nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF)
1507                 return (EIO);
1508         if (!(nmp->nm_flag & NFSMNT_INT))
1509                 return (0);
1510         if (td == NULL)
1511                 return (0);
1512
1513         p = td->td_proc;
1514         PROC_LOCK(p);
1515         tmpset = p->p_siglist;
1516         SIGSETNAND(tmpset, td->td_sigmask);
1517         mtx_lock(&p->p_sigacts->ps_mtx);
1518         SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore);
1519         mtx_unlock(&p->p_sigacts->ps_mtx);
1520         if (SIGNOTEMPTY(p->p_siglist) && nfs_sig_pending(tmpset)) {
1521                 PROC_UNLOCK(p);
1522                 return (EINTR);
1523         }
1524         PROC_UNLOCK(p);
1525
1526         return (0);
1527 }
1528
1529 /*
1530  * Lock a socket against others.
1531  * Necessary for STREAM sockets to ensure you get an entire rpc request/reply
1532  * and also to avoid race conditions between the processes with nfs requests
1533  * in progress when a reconnect is necessary.
1534  */
1535 int
1536 nfs_sndlock(struct nfsreq *rep)
1537 {
1538         int *statep = &rep->r_nmp->nm_state;
1539         struct thread *td;
1540         int error, slpflag = 0, slptimeo = 0;
1541
1542         td = rep->r_td;
1543         if (rep->r_nmp->nm_flag & NFSMNT_INT)
1544                 slpflag = PCATCH;
1545         while (*statep & NFSSTA_SNDLOCK) {
1546                 error = nfs_sigintr(rep->r_nmp, rep, td);
1547                 if (error)
1548                         return (error);
1549                 *statep |= NFSSTA_WANTSND;
1550                 (void) tsleep(statep, slpflag | (PZERO - 1),
1551                         "nfsndlck", slptimeo);
1552                 if (slpflag == PCATCH) {
1553                         slpflag = 0;
1554                         slptimeo = 2 * hz;
1555                 }
1556         }
1557         *statep |= NFSSTA_SNDLOCK;
1558         return (0);
1559 }
1560
1561 /*
1562  * Unlock the stream socket for others.
1563  */
1564 void
1565 nfs_sndunlock(struct nfsreq *rep)
1566 {
1567         int *statep = &rep->r_nmp->nm_state;
1568
1569         if ((*statep & NFSSTA_SNDLOCK) == 0)
1570                 panic("nfs sndunlock");
1571         *statep &= ~NFSSTA_SNDLOCK;
1572         if (*statep & NFSSTA_WANTSND) {
1573                 *statep &= ~NFSSTA_WANTSND;
1574                 wakeup(statep);
1575         }
1576 }
1577
1578 /*
1579  *      nfs_realign:
1580  *
1581  *      Check for badly aligned mbuf data and realign by copying the unaligned
1582  *      portion of the data into a new mbuf chain and freeing the portions
1583  *      of the old chain that were replaced.
1584  *
1585  *      We cannot simply realign the data within the existing mbuf chain
1586  *      because the underlying buffers may contain other rpc commands and
1587  *      we cannot afford to overwrite them.
1588  *
1589  *      We would prefer to avoid this situation entirely.  The situation does
1590  *      not occur with NFS/UDP and is supposed to only occassionally occur
1591  *      with TCP.  Use vfs.nfs.realign_count and realign_test to check this.
1592  *
1593  */
1594 static int
1595 nfs_realign(struct mbuf **pm, int hsiz)
1596 {
1597         struct mbuf *m;
1598         struct mbuf *n = NULL;
1599         int off = 0;
1600
1601         ++nfs_realign_test;
1602         while ((m = *pm) != NULL) {
1603                 if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) {
1604                         MGET(n, M_DONTWAIT, MT_DATA);
1605                         if (n == NULL)
1606                                 return (ENOMEM);
1607                         if (m->m_len >= MINCLSIZE) {
1608                                 MCLGET(n, M_DONTWAIT);
1609                                 if (n->m_ext.ext_buf == NULL) {
1610                                         m_freem(n);
1611                                         return (ENOMEM);
1612                                 }
1613                         }
1614                         n->m_len = 0;
1615                         break;
1616                 }
1617                 pm = &m->m_next;
1618         }
1619         /*
1620          * If n is non-NULL, loop on m copying data, then replace the
1621          * portion of the chain that had to be realigned.
1622          */
1623         if (n != NULL) {
1624                 ++nfs_realign_count;
1625                 while (m) {
1626                         m_copyback(n, off, m->m_len, mtod(m, caddr_t));
1627                         off += m->m_len;
1628                         m = m->m_next;
1629                 }
1630                 m_freem(*pm);
1631                 *pm = n;
1632         }
1633         return (0);
1634 }
1635
1636
1637 static int
1638 nfs_msg(struct thread *td, const char *server, const char *msg, int error)
1639 {
1640         struct proc *p;
1641
1642         GIANT_REQUIRED; /* tprintf */
1643
1644         p = td ? td->td_proc : NULL;
1645         if (error) {
1646                 tprintf(p, LOG_INFO, "nfs server %s: %s, error %d\n", server,
1647                     msg, error);
1648         } else {
1649                 tprintf(p, LOG_INFO, "nfs server %s: %s\n", server, msg);
1650         }
1651         return (0);
1652 }
1653
1654 void
1655 nfs_down(rep, nmp, td, msg, error, flags)
1656         struct nfsreq *rep;
1657         struct nfsmount *nmp;
1658         struct thread *td;
1659         const char *msg;
1660         int error, flags;
1661 {
1662
1663         GIANT_REQUIRED; /* nfs_msg */
1664
1665         if (nmp == NULL)
1666                 return;
1667         if ((flags & NFSSTA_TIMEO) && !(nmp->nm_state & NFSSTA_TIMEO)) {
1668                 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid,
1669                     VQ_NOTRESP, 0);
1670                 nmp->nm_state |= NFSSTA_TIMEO;
1671         }
1672 #ifdef NFSSTA_LOCKTIMEO
1673         if ((flags & NFSSTA_LOCKTIMEO) && !(nmp->nm_state & NFSSTA_LOCKTIMEO)) {
1674                 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid,
1675                     VQ_NOTRESPLOCK, 0);
1676                 nmp->nm_state |= NFSSTA_LOCKTIMEO;
1677         }
1678 #endif
1679         if (rep)
1680                 rep->r_flags |= R_TPRINTFMSG;
1681         nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, error);
1682 }
1683
1684 void
1685 nfs_up(rep, nmp, td, msg, flags)
1686         struct nfsreq *rep;
1687         struct nfsmount *nmp;
1688         struct thread *td;
1689         const char *msg;
1690         int flags;
1691 {
1692
1693         GIANT_REQUIRED; /* nfs_msg */
1694
1695         if (nmp == NULL)
1696                 return;
1697         if ((rep == NULL) || (rep->r_flags & R_TPRINTFMSG) != 0)
1698                 nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, 0);
1699         if ((flags & NFSSTA_TIMEO) && (nmp->nm_state & NFSSTA_TIMEO)) {
1700                 nmp->nm_state &= ~NFSSTA_TIMEO;
1701                 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid,
1702                     VQ_NOTRESP, 1);
1703         }
1704 #ifdef NFSSTA_LOCKTIMEO
1705         if ((flags & NFSSTA_LOCKTIMEO) && (nmp->nm_state & NFSSTA_LOCKTIMEO)) {
1706                 nmp->nm_state &= ~NFSSTA_LOCKTIMEO;
1707                 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid,
1708                     VQ_NOTRESPLOCK, 1);
1709         }
1710 #endif
1711 }
1712