2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
24 * Copyright (c) 1989, 1991, 1993, 1995
25 * The Regents of the University of California. All rights reserved.
27 * This code is derived from software contributed to Berkeley by
28 * Rick Macklem at The University of Guelph.
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by the University of
41 * California, Berkeley and its contributors.
42 * 4. Neither the name of the University nor the names of its contributors
43 * may be used to endorse or promote products derived from this software
44 * without specific prior written permission.
46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
59 * FreeBSD-Id: nfs_socket.c,v 1.30 1997/10/28 15:59:07 bde Exp $
63 * Socket operations for use by nfs
66 #include <sys/param.h>
67 #include <sys/systm.h>
69 #include <sys/mount.h>
70 #include <sys/kernel.h>
72 #include <sys/malloc.h>
73 #include <sys/vnode.h>
74 #include <sys/domain.h>
75 #include <sys/protosw.h>
76 #include <sys/socket.h>
77 #include <sys/socketvar.h>
78 #include <sys/syslog.h>
79 #include <sys/tprintf.h>
80 #include <machine/spl.h>
83 #include <kern/clock.h>
84 #include <kern/task.h>
85 #include <kern/thread.h>
88 #include <netinet/in.h>
89 #include <netinet/tcp.h>
91 #include <nfs/rpcv2.h>
92 #include <nfs/nfsproto.h>
94 #include <nfs/xdr_subs.h>
95 #include <nfs/nfsm_subs.h>
96 #include <nfs/nfsmount.h>
97 #include <nfs/nfsnode.h>
98 #include <nfs/nfsrtt.h>
99 #include <nfs/nqnfs.h>
101 #include <sys/kdebug.h>
103 #define FSDBG(A, B, C, D, E) \
104 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, (A))) | DBG_FUNC_NONE, \
105 (int)(B), (int)(C), (int)(D), (int)(E), 0)
106 #define FSDBG_TOP(A, B, C, D, E) \
107 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, (A))) | DBG_FUNC_START, \
108 (int)(B), (int)(C), (int)(D), (int)(E), 0)
109 #define FSDBG_BOT(A, B, C, D, E) \
110 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, (A))) | DBG_FUNC_END, \
111 (int)(B), (int)(C), (int)(D), (int)(E), 0)
117 * Estimate rto for an nfs rpc sent via. an unreliable datagram.
118 * Use the mean and mean deviation of rtt for the appropriate type of rpc
119 * for the frequent rpcs and a default for the others.
120 * The justification for doing "other" this way is that these rpcs
121 * happen so infrequently that timer est. would probably be stale.
122 * Also, since many of these rpcs are
123 * non-idempotent, a conservative timeout is desired.
124 * getattr, lookup - A+2D
128 #define NFS_RTO(n, t) \
129 ((t) == 0 ? (n)->nm_timeo : \
131 (((((n)->nm_srtt[t-1] + 3) >> 2) + (n)->nm_sdrtt[t-1] + 1) >> 1) : \
132 ((((n)->nm_srtt[t-1] + 7) >> 3) + (n)->nm_sdrtt[t-1] + 1)))
133 #define NFS_SRTT(r) (r)->r_nmp->nm_srtt[proct[(r)->r_procnum] - 1]
134 #define NFS_SDRTT(r) (r)->r_nmp->nm_sdrtt[proct[(r)->r_procnum] - 1]
136 * External data, mostly RPC constants in XDR form
138 extern u_long rpc_reply
, rpc_msgdenied
, rpc_mismatch
, rpc_vers
, rpc_auth_unix
,
139 rpc_msgaccepted
, rpc_call
, rpc_autherr
,
141 extern u_long nfs_prog
, nqnfs_prog
;
142 extern time_t nqnfsstarttime
;
143 extern struct nfsstats nfsstats
;
144 extern int nfsv3_procid
[NFS_NPROCS
];
145 extern int nfs_ticks
;
146 extern u_long nfs_xidwrap
;
149 * Defines which timer to use for the procnum.
156 static int proct
[NFS_NPROCS
] = {
157 0, 1, 0, 2, 1, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0,
162 * There is a congestion window for outstanding rpcs maintained per mount
163 * point. The cwnd size is adjusted in roughly the way that:
164 * Van Jacobson, Congestion avoidance and Control, In "Proceedings of
165 * SIGCOMM '88". ACM, August 1988.
166 * describes for TCP. The cwnd size is chopped in half on a retransmit timeout
167 * and incremented by 1/cwnd when each rpc reply is received and a full cwnd
168 * of rpcs is in progress.
169 * (The sent count and cwnd are scaled for integer arith.)
170 * Variants of "slow start" were tried and were found to be too much of a
171 * performance hit (ave. rtt 3 times larger),
172 * I suspect due to the large rtt that nfs rpcs have.
174 #define NFS_CWNDSCALE 256
175 #define NFS_MAXCWND (NFS_CWNDSCALE * 32)
176 static int nfs_backoff
[8] = { 2, 4, 8, 16, 32, 64, 128, 256, };
178 struct nfsrtt nfsrtt
;
180 static int nfs_msg
__P((struct proc
*, const char *, const char *, int));
181 static int nfs_rcvlock
__P((struct nfsreq
*));
182 static void nfs_rcvunlock
__P((struct nfsreq
*));
183 static int nfs_receive
__P((struct nfsreq
*rep
, struct mbuf
**aname
,
185 static int nfs_reconnect
__P((struct nfsreq
*rep
));
186 static void nfs_repbusy(struct nfsreq
*rep
);
187 static struct nfsreq
* nfs_repnext(struct nfsreq
*rep
);
188 static void nfs_repdequeue(struct nfsreq
*rep
);
191 boolean_t
current_thread_aborted(void);
192 kern_return_t
thread_terminate(thread_act_t
);
195 static int nfsrv_getstream
__P((struct nfssvc_sock
*,int));
197 int (*nfsrv3_procs
[NFS_NPROCS
]) __P((struct nfsrv_descript
*nd
,
198 struct nfssvc_sock
*slp
,
200 struct mbuf
**mreqp
)) = {
228 #endif /* NFS_NOSERVER */
231 * NFSTRACE points were changed to FSDBG (KERNEL_DEBUG)
232 * But some of this code may prove useful someday...
236 int nfstraceindx
= 0;
237 struct nfstracerec nfstracebuf
[NFSTBUFSIZ
] = {{0,0,0,0}};
239 #define NFSTRACESUSPENDERS
240 #ifdef NFSTRACESUSPENDERS
241 uint nfstracemask
= 0xfff00200;
242 int nfstracexid
= -1;
243 uint onfstracemask
= 0;
244 int nfstracesuspend
= -1;
245 #define NFSTRACE_SUSPEND \
247 if (nfstracemask) { \
248 onfstracemask = nfstracemask; \
252 #define NFSTRACE_RESUME \
254 nfstracesuspend = -1; \
256 nfstracemask = onfstracemask; \
258 #define NFSTRACE_STARTSUSPENDCOUNTDOWN \
260 nfstracesuspend = (nfstraceindx+100) % NFSTBUFSIZ; \
262 #define NFSTRACE_SUSPENDING (nfstracesuspend != -1)
263 #define NFSTRACE_SUSPENSEOVER \
264 (nfstracesuspend > 100 ? \
265 (nfstraceindx >= nfstracesuspend || \
266 nfstraceindx < nfstracesuspend - 100) : \
267 (nfstraceindx >= nfstracesuspend && \
268 nfstraceindx < nfstracesuspend + 8192 - 100))
270 uint nfstracemask
= 0;
271 #endif /* NFSTRACESUSPENDERS */
276 int nfsoprocnum
, nfsolen
;
277 int nfsbt
[32], nfsbtlen
;
281 backtrace(int *where
, int size
)
283 int register sp
, *fp
, numsaved
;
285 __asm__
volatile("mr %0,r1" : "=r" (sp
));
287 fp
= (int *)*((int *)sp
);
289 for (numsaved
= 0; numsaved
< size
; numsaved
++) {
297 #elif defined(__i386__)
301 return (0); /* Till someone implements a real routine */
304 #error architecture not implemented.
308 nfsdup(struct nfsreq
*rep
)
310 int *ip
, i
, first
= 1, end
;
314 if ((nfs_debug
& NFS_DEBUG_DUP
) == 0)
316 /* last mbuf in chain will be nfs content */
317 for (mb
= rep
->r_mreq
; mb
->m_next
; mb
= mb
->m_next
)
319 if (rep
->r_procnum
== nfsoprocnum
&& mb
->m_len
== nfsolen
&&
320 !bcmp((caddr_t
)nfsodata
, mb
->m_data
, nfsolen
)) {
321 s
= b
+ sprintf(b
, "nfsdup x=%x p=%d h=", rep
->r_xid
,
323 end
= (int)(VTONFS(rep
->r_vp
)->n_fhp
);
324 ip
= (int *)(end
& ~3);
325 end
+= VTONFS(rep
->r_vp
)->n_fhsize
;
326 while ((int)ip
< end
) {
328 if (first
) { /* avoid leading zeroes */
332 s
+= sprintf(s
, "%x", i
);
334 s
+= sprintf(s
, "%08x", i
);
338 else /* eliminate trailing zeroes */
342 * set a breakpoint here and you can view the
343 * current backtrace and the one saved in nfsbt
347 nfsoprocnum
= rep
->r_procnum
;
349 bcopy(mb
->m_data
, (caddr_t
)nfsodata
, mb
->m_len
);
350 nfsbtlen
= backtrace(&nfsbt
, sizeof(nfsbt
));
356 * attempt to bind a socket to a reserved port
359 nfs_bind_resv(struct nfsmount
*nmp
)
361 struct socket
*so
= nmp
->nm_so
;
362 struct sockaddr_in sin
;
369 sin
.sin_len
= sizeof (struct sockaddr_in
);
370 sin
.sin_family
= AF_INET
;
371 sin
.sin_addr
.s_addr
= INADDR_ANY
;
372 tport
= IPPORT_RESERVED
- 1;
373 sin
.sin_port
= htons(tport
);
375 while (((error
= sobind(so
, (struct sockaddr
*) &sin
)) == EADDRINUSE
) &&
376 (--tport
> IPPORT_RESERVED
/ 2))
377 sin
.sin_port
= htons(tport
);
382 * variables for managing the nfs_bind_resv_thread
384 int nfs_resv_mounts
= 0;
385 static int nfs_bind_resv_thread_state
= 0;
386 #define NFS_BIND_RESV_THREAD_STATE_INITTED 1
387 #define NFS_BIND_RESV_THREAD_STATE_RUNNING 2
388 static struct slock nfs_bind_resv_slock
;
389 struct nfs_bind_resv_request
{
390 TAILQ_ENTRY(nfs_bind_resv_request
) brr_chain
;
391 struct nfsmount
*brr_nmp
;
394 static TAILQ_HEAD(, nfs_bind_resv_request
) nfs_bind_resv_request_queue
;
397 * thread to handle any reserved port bind requests
400 nfs_bind_resv_thread(void)
402 struct nfs_bind_resv_request
*brreq
;
403 boolean_t funnel_state
;
405 funnel_state
= thread_funnel_set(network_flock
, TRUE
);
406 nfs_bind_resv_thread_state
= NFS_BIND_RESV_THREAD_STATE_RUNNING
;
408 while (nfs_resv_mounts
> 0) {
409 simple_lock(&nfs_bind_resv_slock
);
410 while ((brreq
= TAILQ_FIRST(&nfs_bind_resv_request_queue
))) {
411 TAILQ_REMOVE(&nfs_bind_resv_request_queue
, brreq
, brr_chain
);
412 simple_unlock(&nfs_bind_resv_slock
);
413 brreq
->brr_error
= nfs_bind_resv(brreq
->brr_nmp
);
415 simple_lock(&nfs_bind_resv_slock
);
417 simple_unlock(&nfs_bind_resv_slock
);
418 (void)tsleep((caddr_t
)&nfs_bind_resv_request_queue
, PSOCK
,
419 "nfs_bind_resv_request_queue", 0);
422 nfs_bind_resv_thread_state
= NFS_BIND_RESV_THREAD_STATE_INITTED
;
423 (void) thread_funnel_set(network_flock
, funnel_state
);
424 (void) thread_terminate(current_act());
428 nfs_bind_resv_thread_wake(void)
430 if (nfs_bind_resv_thread_state
< NFS_BIND_RESV_THREAD_STATE_RUNNING
)
432 wakeup(&nfs_bind_resv_request_queue
);
437 * underprivileged procs call this to request nfs_bind_resv_thread
438 * to perform the reserved port binding for them.
441 nfs_bind_resv_nopriv(struct nfsmount
*nmp
)
443 struct nfs_bind_resv_request brreq
;
446 if (nfs_bind_resv_thread_state
< NFS_BIND_RESV_THREAD_STATE_RUNNING
) {
447 if (nfs_bind_resv_thread_state
< NFS_BIND_RESV_THREAD_STATE_INITTED
) {
448 simple_lock_init(&nfs_bind_resv_slock
);
449 TAILQ_INIT(&nfs_bind_resv_request_queue
);
450 nfs_bind_resv_thread_state
= NFS_BIND_RESV_THREAD_STATE_INITTED
;
452 kernel_thread(kernel_task
, nfs_bind_resv_thread
);
453 nfs_bind_resv_thread_state
= NFS_BIND_RESV_THREAD_STATE_RUNNING
;
459 simple_lock(&nfs_bind_resv_slock
);
460 TAILQ_INSERT_TAIL(&nfs_bind_resv_request_queue
, &brreq
, brr_chain
);
461 simple_unlock(&nfs_bind_resv_slock
);
463 error
= nfs_bind_resv_thread_wake();
465 TAILQ_REMOVE(&nfs_bind_resv_request_queue
, &brreq
, brr_chain
);
466 /* Note: we might be able to simply restart the thread */
470 (void) tsleep((caddr_t
)&brreq
, PSOCK
, "nfsbindresv", 0);
472 return (brreq
.brr_error
);
476 * Initialize sockets and congestion for a new NFS connection.
477 * We do not free the sockaddr if error.
480 nfs_connect(nmp
, rep
)
481 struct nfsmount
*nmp
;
485 int s
, error
, rcvreserve
, sndreserve
;
486 struct sockaddr
*saddr
;
488 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
489 nmp
->nm_so
= (struct socket
*)0;
490 saddr
= mtod(nmp
->nm_nam
, struct sockaddr
*);
491 error
= socreate(saddr
->sa_family
, &nmp
->nm_so
, nmp
->nm_sotype
,
497 nmp
->nm_soflags
= so
->so_proto
->pr_flags
;
500 * Some servers require that the client port be a reserved port number.
502 if (saddr
->sa_family
== AF_INET
&& (nmp
->nm_flag
& NFSMNT_RESVPORT
)) {
505 * sobind() requires current_proc() to have superuser privs.
506 * If this bind is part of a reconnect, and the current proc
507 * doesn't have superuser privs, we hand the sobind() off to
508 * a kernel thread to process.
510 if ((nmp
->nm_state
& NFSSTA_MOUNTED
) &&
511 (p
= current_proc()) && suser(p
->p_ucred
, &p
->p_acflag
)) {
512 /* request nfs_bind_resv_thread() to do bind */
513 error
= nfs_bind_resv_nopriv(nmp
);
515 error
= nfs_bind_resv(nmp
);
522 * Protocols that do not require connections may be optionally left
523 * unconnected for servers that reply from a port other than NFS_PORT.
525 if (nmp
->nm_flag
& NFSMNT_NOCONN
) {
526 if (nmp
->nm_soflags
& PR_CONNREQUIRED
) {
531 error
= soconnect(so
, mtod(nmp
->nm_nam
, struct sockaddr
*));
537 * Wait for the connection to complete. Cribbed from the
538 * connect system call but with the wait timing out so
539 * that interruptible mounts don't hang here for a long time.
542 while ((so
->so_state
& SS_ISCONNECTING
) && so
->so_error
== 0) {
543 (void) tsleep((caddr_t
)&so
->so_timeo
, PSOCK
,
545 if ((so
->so_state
& SS_ISCONNECTING
) &&
546 so
->so_error
== 0 && rep
&&
547 (error
= nfs_sigintr(nmp
, rep
, rep
->r_procp
))) {
548 so
->so_state
&= ~SS_ISCONNECTING
;
554 error
= so
->so_error
;
562 * Always time out on recieve, this allows us to reconnect the
563 * socket to deal with network changes.
565 so
->so_rcv
.sb_timeo
= (2 * hz
);
566 if (nmp
->nm_flag
& (NFSMNT_SOFT
| NFSMNT_INT
)) {
567 so
->so_snd
.sb_timeo
= (5 * hz
);
569 so
->so_snd
.sb_timeo
= 0;
571 if (nmp
->nm_sotype
== SOCK_DGRAM
) {
572 sndreserve
= (nmp
->nm_wsize
+ NFS_MAXPKTHDR
) * 3;
573 rcvreserve
= (nmp
->nm_rsize
+ NFS_MAXPKTHDR
) *
574 (nmp
->nm_readahead
> 0 ? nmp
->nm_readahead
+ 1 : 2);
575 } else if (nmp
->nm_sotype
== SOCK_SEQPACKET
) {
576 sndreserve
= (nmp
->nm_wsize
+ NFS_MAXPKTHDR
) * 3;
577 rcvreserve
= (nmp
->nm_rsize
+ NFS_MAXPKTHDR
) *
578 (nmp
->nm_readahead
> 0 ? nmp
->nm_readahead
+ 1 : 2);
580 if (nmp
->nm_sotype
!= SOCK_STREAM
)
581 panic("nfscon sotype");
583 if (so
->so_proto
->pr_flags
& PR_CONNREQUIRED
) {
587 bzero(&sopt
, sizeof sopt
);
588 sopt
.sopt_dir
= SOPT_SET
;
589 sopt
.sopt_level
= SOL_SOCKET
;
590 sopt
.sopt_name
= SO_KEEPALIVE
;
591 sopt
.sopt_val
= &val
;
592 sopt
.sopt_valsize
= sizeof val
;
596 if (so
->so_proto
->pr_protocol
== IPPROTO_TCP
) {
600 bzero(&sopt
, sizeof sopt
);
601 sopt
.sopt_dir
= SOPT_SET
;
602 sopt
.sopt_level
= IPPROTO_TCP
;
603 sopt
.sopt_name
= TCP_NODELAY
;
604 sopt
.sopt_val
= &val
;
605 sopt
.sopt_valsize
= sizeof val
;
610 sndreserve
= (nmp
->nm_wsize
+ NFS_MAXPKTHDR
+ sizeof (u_long
)) * 3;
611 rcvreserve
= (nmp
->nm_rsize
+ NFS_MAXPKTHDR
+ sizeof (u_long
)) *
612 (nmp
->nm_readahead
> 0 ? nmp
->nm_readahead
+ 1 : 2);
615 if (sndreserve
> NFS_MAXSOCKBUF
)
616 sndreserve
= NFS_MAXSOCKBUF
;
617 if (rcvreserve
> NFS_MAXSOCKBUF
)
618 rcvreserve
= NFS_MAXSOCKBUF
;
619 error
= soreserve(so
, sndreserve
, rcvreserve
);
623 so
->so_rcv
.sb_flags
|= SB_NOINTR
;
624 so
->so_snd
.sb_flags
|= SB_NOINTR
;
626 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);
628 /* Initialize other non-zero congestion variables */
629 nmp
->nm_srtt
[0] = nmp
->nm_srtt
[1] = nmp
->nm_srtt
[2] =
630 nmp
->nm_srtt
[3] = (NFS_TIMEO
<< 3);
631 nmp
->nm_sdrtt
[0] = nmp
->nm_sdrtt
[1] = nmp
->nm_sdrtt
[2] =
632 nmp
->nm_sdrtt
[3] = 0;
633 nmp
->nm_cwnd
= NFS_MAXCWND
/ 2; /* Initial send window */
635 FSDBG(529, nmp
, nmp
->nm_state
, nmp
->nm_soflags
, nmp
->nm_cwnd
);
636 nmp
->nm_timeouts
= 0;
640 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);
647 * Called when a connection is broken on a reliable protocol.
648 * - clean up the old socket
649 * - nfs_connect() again
650 * - set R_MUSTRESEND for all outstanding requests on mount point
651 * If this fails the mount point is DEAD!
652 * nb: Must be called with the nfs_sndlock() set on the mount point.
656 register struct nfsreq
*rep
;
658 register struct nfsreq
*rp
;
659 register struct nfsmount
*nmp
= rep
->r_nmp
;
663 while ((error
= nfs_connect(nmp
, rep
))) {
664 if (error
== EINTR
|| error
== ERESTART
)
668 nfs_down(rep
, rep
->r_nmp
, rep
->r_procp
, "can not connect",
669 error
, NFSSTA_TIMEO
);
670 if (!(nmp
->nm_state
& NFSSTA_MOUNTED
)) {
671 /* we're not yet completely mounted and */
672 /* we can't reconnect, so we fail */
675 if ((error
= nfs_sigintr(rep
->r_nmp
, rep
, rep
->r_procp
)))
677 (void) tsleep((caddr_t
)&lbolt
, PSOCK
, "nfscon", 0);
680 NFS_DPF(DUP
, ("nfs_reconnect RESEND\n"));
682 * Loop through outstanding request list and fix up all requests
685 TAILQ_FOREACH(rp
, &nfs_reqq
, r_chain
) {
686 if (rp
->r_nmp
== nmp
)
687 rp
->r_flags
|= R_MUSTRESEND
;
693 * NFS disconnect. Clean up and unlink.
697 register struct nfsmount
*nmp
;
699 register struct socket
*so
;
701 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
704 nmp
->nm_so
= (struct socket
*)0;
708 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);
712 * This is the nfs send routine. For connection based socket types, it
713 * must be called with an nfs_sndlock() on the socket.
714 * "rep == NULL" indicates that it has been called from a server.
715 * For the client side:
716 * - return EINTR if the RPC is terminated, 0 otherwise
717 * - set R_MUSTRESEND if the send fails for any reason
718 * - do any cleanup required by recoverable socket errors (???)
719 * For the server side:
720 * - return EINTR or ERESTART if interrupted by a signal
721 * - return EPIPE if a connection is lost for connection based sockets (TCP...)
722 * - do any cleanup required by recoverable socket errors (???)
725 nfs_send(so
, nam
, top
, rep
)
726 register struct socket
*so
;
728 register struct mbuf
*top
;
731 struct sockaddr
*sendnam
;
732 int error
, error2
, soflags
, flags
;
735 char savenametolog
[MNAMELEN
];
738 error
= nfs_sigintr(rep
->r_nmp
, rep
, rep
->r_procp
);
743 if ((so
= rep
->r_nmp
->nm_so
) == NULL
) {
744 rep
->r_flags
|= R_MUSTRESEND
;
748 rep
->r_flags
&= ~R_MUSTRESEND
;
749 soflags
= rep
->r_nmp
->nm_soflags
;
750 TAILQ_FOREACH(rp
, &nfs_reqq
, r_chain
)
754 xidqueued
= rp
->r_xid
;
756 soflags
= so
->so_proto
->pr_flags
;
757 if ((soflags
& PR_CONNREQUIRED
) || (so
->so_state
& SS_ISCONNECTED
) ||
759 sendnam
= (struct sockaddr
*)0;
761 sendnam
= mtod(nam
, struct sockaddr
*);
763 if (so
->so_type
== SOCK_SEQPACKET
)
773 * Save the name here in case mount point goes away when we switch
774 * funnels. The name is using local stack and is large, but don't
775 * want to block if we malloc.
778 strncpy(savenametolog
,
779 rep
->r_nmp
->nm_mountp
->mnt_stat
.f_mntfromname
,
781 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
782 error
= sosend(so
, sendnam
, (struct uio
*)0, top
,
783 (struct mbuf
*)0, flags
);
784 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);
789 TAILQ_FOREACH(rp
, &nfs_reqq
, r_chain
)
790 if (rp
== rep
&& rp
->r_xid
== xidqueued
)
793 panic("nfs_send: error %d xid %x gone",
796 log(LOG_INFO
, "nfs send error %d for server %s\n",
797 error
, savenametolog
);
799 * Deal with errors for the client side.
801 error2
= nfs_sigintr(rep
->r_nmp
, rep
, rep
->r_procp
);
805 rep
->r_flags
|= R_MUSTRESEND
;
807 ("nfs_send RESEND error=%d\n", error
));
810 log(LOG_INFO
, "nfsd send error %d\n", error
);
813 * Handle any recoverable (soft) socket errors here. (???)
815 if (error
!= EINTR
&& error
!= ERESTART
&& error
!= EIO
&&
816 error
!= EWOULDBLOCK
&& error
!= EPIPE
) {
824 * Receive a Sun RPC Request/Reply. For SOCK_DGRAM, the work is all
825 * done by soreceive(), but for SOCK_STREAM we must deal with the Record
826 * Mark and consolidate the data into a new mbuf list.
827 * nb: Sometimes TCP passes the data up to soreceive() in long lists of
829 * For SOCK_STREAM we must be very careful to read an entire record once
830 * we have read any of it, even if the system call has been interrupted.
833 nfs_receive(rep
, aname
, mp
)
834 register struct nfsreq
*rep
;
838 register struct socket
*so
;
841 register struct mbuf
*m
;
842 struct mbuf
*control
;
844 struct sockaddr
**getnam
;
845 struct sockaddr
*tmp_nam
;
847 struct sockaddr_in
*sin
;
848 int error
, error2
, sotype
, rcvflg
;
849 struct proc
*p
= current_proc(); /* XXX */
852 * Set up arguments for soreceive()
854 *mp
= (struct mbuf
*)0;
855 *aname
= (struct mbuf
*)0;
856 sotype
= rep
->r_nmp
->nm_sotype
;
859 * For reliable protocols, lock against other senders/receivers
860 * in case a reconnect is necessary.
861 * For SOCK_STREAM, first get the Record Mark to find out how much
862 * more there is to get.
863 * We must lock the socket against other receivers
864 * until we have an entire rpc request/reply.
866 if (sotype
!= SOCK_DGRAM
) {
867 error
= nfs_sndlock(rep
);
872 * Check for fatal errors and resending request.
875 * Ugh: If a reconnect attempt just happened, nm_so
876 * would have changed. NULL indicates a failed
877 * attempt that has essentially shut down this
880 if ((error
= nfs_sigintr(rep
->r_nmp
, rep
, p
)) || rep
->r_mrep
) {
886 so
= rep
->r_nmp
->nm_so
;
888 error
= nfs_reconnect(rep
);
895 while (rep
->r_flags
& R_MUSTRESEND
) {
896 m
= m_copym(rep
->r_mreq
, 0, M_COPYALL
, M_WAIT
);
897 nfsstats
.rpcretries
++;
899 ("nfs_receive RESEND %s\n",
900 rep
->r_nmp
->nm_mountp
->mnt_stat
.f_mntfromname
));
901 error
= nfs_send(so
, rep
->r_nmp
->nm_nam
, m
, rep
);
903 * we also hold rcv lock so rep is still
907 if (error
== EINTR
|| error
== ERESTART
||
908 (error
= nfs_reconnect(rep
))) {
916 if (sotype
== SOCK_STREAM
) {
917 aio
.iov_base
= (caddr_t
) &len
;
918 aio
.iov_len
= sizeof(u_long
);
921 auio
.uio_segflg
= UIO_SYSSPACE
;
922 auio
.uio_rw
= UIO_READ
;
924 auio
.uio_resid
= sizeof(u_long
);
927 rcvflg
= MSG_WAITALL
;
928 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
929 error
= soreceive(so
, (struct sockaddr
**)0, &auio
,
930 (struct mbuf
**)0, (struct mbuf
**)0, &rcvflg
);
931 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);
932 if (!rep
->r_nmp
) /* if unmounted then bailout */
934 if (error
== EWOULDBLOCK
&& rep
) {
935 error2
= nfs_sigintr(rep
->r_nmp
, rep
, p
);
939 } while (error
== EWOULDBLOCK
);
940 if (!error
&& auio
.uio_resid
> 0) {
942 "short receive (%d/%d) from nfs server %s\n",
943 sizeof(u_long
) - auio
.uio_resid
,
945 rep
->r_nmp
->nm_mountp
->mnt_stat
.f_mntfromname
);
950 len
= ntohl(len
) & ~0x80000000;
952 * This is SERIOUS! We are out of sync with the sender
953 * and forcing a disconnect/reconnect is all I can do.
955 if (len
> NFS_MAXPACKET
) {
956 log(LOG_ERR
, "%s (%d) from nfs server %s\n",
957 "impossible packet length",
959 rep
->r_nmp
->nm_mountp
->mnt_stat
.f_mntfromname
);
963 auio
.uio_resid
= len
;
965 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
967 rcvflg
= MSG_WAITALL
;
968 error
= soreceive(so
, (struct sockaddr
**)0,
969 &auio
, mp
, (struct mbuf
**)0, &rcvflg
);
970 if (!rep
->r_nmp
) /* if unmounted then bailout */ {
971 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);
974 } while (error
== EWOULDBLOCK
|| error
== EINTR
||
977 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);
979 if (!error
&& auio
.uio_resid
> 0) {
981 "short receive (%d/%d) from nfs server %s\n",
982 len
- auio
.uio_resid
, len
,
983 rep
->r_nmp
->nm_mountp
->mnt_stat
.f_mntfromname
);
988 * NB: Since uio_resid is big, MSG_WAITALL is ignored
989 * and soreceive() will return when it has either a
990 * control msg or a data msg.
991 * We have no use for control msg., but must grab them
992 * and then throw them away so we know what is going
995 auio
.uio_resid
= len
= 100000000; /* Anything Big */
998 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
1002 error
= soreceive(so
, (struct sockaddr
**)0,
1003 &auio
, mp
, &control
, &rcvflg
);
1006 if (!rep
->r_nmp
) /* if unmounted then bailout */ {
1007 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);
1010 if (error
== EWOULDBLOCK
&& rep
) {
1011 error2
= nfs_sigintr(rep
->r_nmp
, rep
, p
);
1013 thread_funnel_switch(NETWORK_FUNNEL
,
1018 } while (error
== EWOULDBLOCK
||
1019 (!error
&& *mp
== NULL
&& control
));
1021 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);
1023 if ((rcvflg
& MSG_EOR
) == 0)
1025 if (!error
&& *mp
== NULL
)
1027 len
-= auio
.uio_resid
;
1030 if (error
&& error
!= EINTR
&& error
!= ERESTART
) {
1032 *mp
= (struct mbuf
*)0;
1035 "receive error %d from nfs server %s\n",
1037 rep
->r_nmp
->nm_mountp
->mnt_stat
.f_mntfromname
);
1038 error
= nfs_sndlock(rep
);
1040 error
= nfs_reconnect(rep
);
1048 * We could have failed while rebinding the datagram socket
1049 * so we need to attempt to rebind here.
1051 if ((so
= rep
->r_nmp
->nm_so
) == NULL
) {
1052 error
= nfs_sndlock(rep
);
1054 error
= nfs_reconnect(rep
);
1059 if (!rep
->r_nmp
) /* if unmounted then bailout */
1061 so
= rep
->r_nmp
->nm_so
;
1063 if (so
->so_state
& SS_ISCONNECTED
)
1064 getnam
= (struct sockaddr
**)0;
1067 auio
.uio_resid
= len
= 1000000;
1070 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
1073 error
= soreceive(so
, getnam
, &auio
, mp
,
1074 (struct mbuf
**)0, &rcvflg
);
1076 if ((getnam
) && (*getnam
)) {
1077 MGET(mhck
, M_WAIT
, MT_SONAME
);
1078 mhck
->m_len
= (*getnam
)->sa_len
;
1079 sin
= mtod(mhck
, struct sockaddr_in
*);
1080 bcopy(*getnam
, sin
, sizeof(struct sockaddr_in
));
1081 mhck
->m_hdr
.mh_len
= sizeof(struct sockaddr_in
);
1082 FREE(*getnam
, M_SONAME
);
1085 if (!rep
->r_nmp
) /* if unmounted then bailout */
1088 error2
= nfs_sigintr(rep
->r_nmp
, rep
, p
);
1094 /* Reconnect for all errors. We may be receiving
1095 * soft/hard/blocking errors because of a network
1097 * XXX: we should rate limit or delay this
1098 * to once every N attempts or something.
1099 * although TCP doesn't seem to.
1102 thread_funnel_switch(NETWORK_FUNNEL
,
1104 error2
= nfs_sndlock(rep
);
1106 error2
= nfs_reconnect(rep
);
1109 else if (!rep
->r_nmp
) /* if unmounted then bailout */
1112 so
= rep
->r_nmp
->nm_so
;
1117 thread_funnel_switch(KERNEL_FUNNEL
,
1120 } while (error
== EWOULDBLOCK
);
1123 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);
1124 len
-= auio
.uio_resid
;
1129 *mp
= (struct mbuf
*)0;
1135 * Implement receipt of reply on a socket.
1136 * We must search through the list of received datagrams matching them
1137 * with outstanding requests using the xid, until ours is found.
1142 struct nfsreq
*myrep
;
1144 register struct nfsreq
*rep
;
1145 register struct nfsmount
*nmp
= myrep
->r_nmp
;
1147 struct mbuf
*mrep
, *md
;
1154 * Loop around until we get our own reply
1158 * Lock against other receivers so that I don't get stuck in
1159 * sbwait() after someone else has received my reply for me.
1160 * Also necessary for connection based protocols to avoid
1161 * race conditions during a reconnect.
1162 * If nfs_rcvlock() returns EALREADY, that means that
1163 * the reply has already been recieved by another
1164 * process and we can return immediately. In this
1165 * case, the lock is not taken to avoid races with
1168 error
= nfs_rcvlock(myrep
);
1169 if (error
== EALREADY
)
1175 * If we slept after putting bits otw, then reply may have
1176 * arrived. In which case returning is required, or we
1177 * would hang trying to nfs_receive an already received reply.
1179 if (myrep
->r_mrep
!= NULL
) {
1180 nfs_rcvunlock(myrep
);
1181 FSDBG(530, myrep
->r_xid
, myrep
, myrep
->r_nmp
, -1);
1185 * Get the next Rpc reply off the socket. Assume myrep->r_nmp
1186 * is still intact by checks done in nfs_rcvlock.
1188 /* XXX why do we ask for nam here? we don't use it! */
1189 error
= nfs_receive(myrep
, &nam
, &mrep
);
1193 * Bailout asap if nfsmount struct gone (unmounted).
1195 if (!myrep
->r_nmp
) {
1196 FSDBG(530, myrep
->r_xid
, myrep
, nmp
, -2);
1200 FSDBG(530, myrep
->r_xid
, myrep
, nmp
, error
);
1201 nfs_rcvunlock(myrep
);
1203 /* Bailout asap if nfsmount struct gone (unmounted). */
1208 * Ignore routing errors on connectionless protocols??
1210 if (NFSIGNORE_SOERROR(nmp
->nm_soflags
, error
)) {
1212 nmp
->nm_so
->so_error
= 0;
1213 if (myrep
->r_flags
& R_GETONEREP
)
1221 * We assume all is fine, but if we did not have an error
1222 * and mrep is 0, better not dereference it. nfs_receieve
1223 * calls soreceive which carefully sets error=0 when it got
1224 * errors on sbwait (tsleep). In most cases, I assume that's
1225 * so we could go back again. In tcp case, EPIPE is returned.
1226 * In udp, case nfs_receive gets back here with no error and no
1227 * mrep. Is the right fix to have soreceive check for process
1228 * aborted after sbwait and return something non-zero? Should
1229 * nfs_receive give an EPIPE? Too risky to play with those
1230 * two this late in game for a shutdown problem. Instead,
1231 * just check here and get out. (ekn)
1234 nfs_rcvunlock(myrep
);
1235 FSDBG(530, myrep
->r_xid
, myrep
, nmp
, -3);
1236 return (ENXIO
); /* sounds good */
1240 * Get the xid and check that it is an rpc reply
1243 dpos
= mtod(md
, caddr_t
);
1244 nfsm_dissect(tl
, u_long
*, 2*NFSX_UNSIGNED
);
1246 if (*tl
!= rpc_reply
) {
1247 #ifndef NFS_NOSERVER
1248 if (nmp
->nm_flag
& NFSMNT_NQNFS
) {
1249 if (nqnfs_callback(nmp
, mrep
, md
, dpos
))
1250 nfsstats
.rpcinvalid
++;
1252 nfsstats
.rpcinvalid
++;
1256 nfsstats
.rpcinvalid
++;
1260 if (nmp
->nm_state
& NFSSTA_RCVLOCK
)
1261 nfs_rcvunlock(myrep
);
1262 if (myrep
->r_flags
& R_GETONEREP
)
1263 return (0); /* this path used by NQNFS */
1268 * Loop through the request list to match up the reply
1269 * Iff no match, just drop the datagram
1271 TAILQ_FOREACH(rep
, &nfs_reqq
, r_chain
) {
1272 if (rep
->r_mrep
== NULL
&& rxid
== rep
->r_xid
) {
1278 * If we're tracking the round trip time
1279 * then we update the circular log here
1280 * with the stats from our current request.
1285 rt
= &nfsrtt
.rttl
[nfsrtt
.pos
];
1286 rt
->proc
= rep
->r_procnum
;
1287 rt
->rto
= NFS_RTO(nmp
, proct
[rep
->r_procnum
]);
1288 rt
->sent
= nmp
->nm_sent
;
1289 rt
->cwnd
= nmp
->nm_cwnd
;
1290 if (proct
[rep
->r_procnum
] == 0)
1291 panic("nfs_reply: proct[%d] is zero", rep
->r_procnum
);
1292 rt
->srtt
= nmp
->nm_srtt
[proct
[rep
->r_procnum
] - 1];
1293 rt
->sdrtt
= nmp
->nm_sdrtt
[proct
[rep
->r_procnum
] - 1];
1294 rt
->fsid
= nmp
->nm_mountp
->mnt_stat
.f_fsid
;
1295 microtime(&rt
->tstamp
); // XXX unused
1296 if (rep
->r_flags
& R_TIMING
)
1297 rt
->rtt
= rep
->r_rtt
;
1300 nfsrtt
.pos
= (nfsrtt
.pos
+ 1) % NFSRTTLOGSIZ
;
1303 * Update congestion window.
1304 * Do the additive increase of
1307 FSDBG(530, rep
->r_xid
, rep
, nmp
->nm_sent
,
1309 if (nmp
->nm_cwnd
<= nmp
->nm_sent
) {
1311 (NFS_CWNDSCALE
* NFS_CWNDSCALE
+
1312 (nmp
->nm_cwnd
>> 1)) / nmp
->nm_cwnd
;
1313 if (nmp
->nm_cwnd
> NFS_MAXCWND
)
1314 nmp
->nm_cwnd
= NFS_MAXCWND
;
1316 if (rep
->r_flags
& R_SENT
) {
1317 rep
->r_flags
&= ~R_SENT
;
1318 nmp
->nm_sent
-= NFS_CWNDSCALE
;
1321 * Update rtt using a gain of 0.125 on the mean
1322 * and a gain of 0.25 on the deviation.
1324 if (rep
->r_flags
& R_TIMING
) {
1326 * Since the timer resolution of
1327 * NFS_HZ is so course, it can often
1328 * result in r_rtt == 0. Since
1329 * r_rtt == N means that the actual
1330 * rtt is between N+dt and N+2-dt ticks,
1333 if (proct
[rep
->r_procnum
] == 0)
1334 panic("nfs_reply: proct[%d] is zero", rep
->r_procnum
);
1335 t1
= rep
->r_rtt
+ 1;
1336 t1
-= (NFS_SRTT(rep
) >> 3);
1337 NFS_SRTT(rep
) += t1
;
1340 t1
-= (NFS_SDRTT(rep
) >> 2);
1341 NFS_SDRTT(rep
) += t1
;
1343 nmp
->nm_timeouts
= 0;
1347 nfs_rcvunlock(myrep
);
1349 * If not matched to a request, drop it.
1350 * If it's mine, get out.
1353 nfsstats
.rpcunexpected
++;
1355 } else if (rep
== myrep
) {
1356 if (rep
->r_mrep
== NULL
)
1357 panic("nfs_reply: nil r_mrep");
1360 FSDBG(530, myrep
->r_xid
, myrep
, rep
,
1361 rep
? rep
->r_xid
: myrep
->r_flags
);
1362 if (myrep
->r_flags
& R_GETONEREP
)
1363 return (0); /* this path used by NQNFS */
1368 * nfs_request - goes something like this
1369 * - fill in request struct
1370 * - links it into list
1371 * - calls nfs_send() for first transmit
1372 * - calls nfs_receive() to get reply
1373 * - break down rpc header and return with nfs reply pointed to
1375 * nb: always frees up mreq mbuf list
1378 nfs_request(vp
, mrest
, procnum
, procp
, cred
, mrp
, mdp
, dposp
, xidp
)
1389 register struct mbuf
*m
, *mrep
, *m2
;
1390 register struct nfsreq
*rep
, *rp
;
1391 register u_long
*tl
;
1393 struct nfsmount
*nmp
;
1394 struct mbuf
*md
, *mheadend
;
1396 char nickv
[RPCX_NICKVERF
];
1397 time_t reqtime
, waituntil
;
1399 int t1
, nqlflag
, cachable
, s
, error
= 0, mrest_len
, auth_len
, auth_type
;
1400 int trylater_delay
= NQ_TRYLATERDEL
, trylater_cnt
= 0, failed_auth
= 0;
1401 int verf_len
, verf_type
;
1404 char *auth_str
, *verf_str
;
1405 NFSKERBKEY_T key
; /* save session key */
1414 MALLOC_ZONE(rep
, struct nfsreq
*,
1415 sizeof(struct nfsreq
), M_NFSREQ
, M_WAITOK
);
1417 nmp
= VFSTONFS(vp
->v_mount
);
1419 (nmp
->nm_state
& (NFSSTA_FORCE
|NFSSTA_TIMEO
)) ==
1420 (NFSSTA_FORCE
|NFSSTA_TIMEO
)) {
1421 FREE_ZONE((caddr_t
)rep
, sizeof (struct nfsreq
), M_NFSREQ
);
1424 nmsotype
= nmp
->nm_sotype
;
1426 FSDBG_TOP(531, vp
, procnum
, nmp
, rep
);
1430 rep
->r_procp
= procp
;
1431 rep
->r_procnum
= procnum
;
1433 rep
->r_lastmsg
= now
.tv_sec
-
1434 ((nmp
->nm_tprintf_delay
) - (nmp
->nm_tprintf_initial_delay
));
1444 * Get the RPC header with authorization.
1447 nmp
= VFSTONFS(vp
->v_mount
);
1449 FSDBG_BOT(531, error
, rep
->r_xid
, nmp
, rep
);
1450 FREE_ZONE((caddr_t
)rep
, sizeof (struct nfsreq
), M_NFSREQ
);
1453 verf_str
= auth_str
= (char *)0;
1454 if (nmp
->nm_flag
& NFSMNT_KERB
) {
1456 verf_len
= sizeof (nickv
);
1457 auth_type
= RPCAUTH_KERB4
;
1458 bzero((caddr_t
)key
, sizeof (key
));
1459 if (failed_auth
|| nfs_getnickauth(nmp
, cred
, &auth_str
,
1460 &auth_len
, verf_str
, verf_len
)) {
1461 nmp
= VFSTONFS(vp
->v_mount
);
1463 FSDBG_BOT(531, 2, vp
, error
, rep
);
1464 FREE_ZONE((caddr_t
)rep
,
1465 sizeof (struct nfsreq
), M_NFSREQ
);
1469 error
= nfs_getauth(nmp
, rep
, cred
, &auth_str
,
1470 &auth_len
, verf_str
, &verf_len
, key
);
1471 nmp
= VFSTONFS(vp
->v_mount
);
1475 FSDBG_BOT(531, 2, vp
, error
, rep
);
1476 FREE_ZONE((caddr_t
)rep
,
1477 sizeof (struct nfsreq
), M_NFSREQ
);
1483 auth_type
= RPCAUTH_UNIX
;
1484 if (cred
->cr_ngroups
< 1)
1485 panic("nfsreq nogrps");
1486 auth_len
= ((((cred
->cr_ngroups
- 1) > nmp
->nm_numgrps
) ?
1487 nmp
->nm_numgrps
: (cred
->cr_ngroups
- 1)) << 2) +
1490 m
= nfsm_rpchead(cred
, nmp
->nm_flag
, procnum
, auth_type
, auth_len
,
1491 auth_str
, verf_len
, verf_str
, mrest
, mrest_len
, &mheadend
, &xid
);
1493 *xidp
= ntohl(xid
) + ((u_int64_t
)nfs_xidwrap
<< 32);
1495 _FREE(auth_str
, M_TEMP
);
1498 * For stream protocols, insert a Sun RPC Record Mark.
1500 if (nmsotype
== SOCK_STREAM
) {
1501 M_PREPEND(m
, NFSX_UNSIGNED
, M_WAIT
);
1502 *mtod(m
, u_long
*) = htonl(0x80000000 |
1503 (m
->m_pkthdr
.len
- NFSX_UNSIGNED
));
1508 nmp
= VFSTONFS(vp
->v_mount
);
1509 if (nmp
&& (nmp
->nm_flag
& NFSMNT_SOFT
))
1510 rep
->r_retry
= nmp
->nm_retry
;
1512 rep
->r_retry
= NFS_MAXREXMIT
+ 1; /* past clip limit */
1513 rep
->r_rtt
= rep
->r_rexmit
= 0;
1514 if (proct
[procnum
] > 0)
1515 rep
->r_flags
= R_TIMING
;
1521 * Do the client side RPC.
1523 nfsstats
.rpcrequests
++;
1525 * Chain request into list of outstanding requests. Be sure
1526 * to put it LAST so timer finds oldest requests first.
1529 TAILQ_INSERT_TAIL(&nfs_reqq
, rep
, r_chain
);
1531 /* Get send time for nqnfs */
1533 reqtime
= now
.tv_sec
;
1536 * If backing off another request or avoiding congestion, don't
1537 * send this one now but let timer do it. If not timing a request,
1540 if (nmp
&& nmp
->nm_so
&& (nmp
->nm_sotype
!= SOCK_DGRAM
||
1541 (nmp
->nm_flag
& NFSMNT_DUMBTIMR
) ||
1542 nmp
->nm_sent
< nmp
->nm_cwnd
)) {
1543 int connrequired
= (nmp
->nm_soflags
& PR_CONNREQUIRED
);
1547 error
= nfs_sndlock(rep
);
1550 * Set the R_SENT before doing the send in case another thread
1551 * processes the reply before the nfs_send returns here
1554 if ((rep
->r_flags
& R_MUSTRESEND
) == 0) {
1555 FSDBG(531, rep
->r_xid
, rep
, nmp
->nm_sent
,
1557 nmp
->nm_sent
+= NFS_CWNDSCALE
;
1558 rep
->r_flags
|= R_SENT
;
1561 m2
= m_copym(m
, 0, M_COPYALL
, M_WAIT
);
1562 error
= nfs_send(nmp
->nm_so
, nmp
->nm_nam
, m2
, rep
);
1566 nmp
= VFSTONFS(vp
->v_mount
);
1569 nmp
->nm_sent
-= NFS_CWNDSCALE
;
1570 rep
->r_flags
&= ~R_SENT
;
1578 * Wait for the reply from our send or the timer's.
1580 if (!error
|| error
== EPIPE
)
1581 error
= nfs_reply(rep
);
1584 * RPC done, unlink the request.
1586 nfs_repdequeue(rep
);
1588 nmp
= VFSTONFS(vp
->v_mount
);
1591 * Decrement the outstanding request count.
1593 if (rep
->r_flags
& R_SENT
) {
1594 rep
->r_flags
&= ~R_SENT
; /* paranoia */
1596 FSDBG(531, rep
->r_xid
, rep
, nmp
->nm_sent
, nmp
->nm_cwnd
);
1597 nmp
->nm_sent
-= NFS_CWNDSCALE
;
1602 * If there was a successful reply and a tprintf msg.
1603 * tprintf a response.
1606 nfs_up(rep
, nmp
, procp
, "is alive again", NFSSTA_TIMEO
);
1613 m_freem(rep
->r_mreq
);
1614 FSDBG_BOT(531, error
, rep
->r_xid
, nmp
, rep
);
1615 FREE_ZONE((caddr_t
)rep
, sizeof (struct nfsreq
), M_NFSREQ
);
1620 * break down the rpc header and check if ok
1622 nfsm_dissect(tl
, u_long
*, 3 * NFSX_UNSIGNED
);
1623 if (*tl
++ == rpc_msgdenied
) {
1624 if (*tl
== rpc_mismatch
)
1626 else if ((nmp
->nm_flag
& NFSMNT_KERB
) && *tl
++ == rpc_autherr
) {
1629 mheadend
->m_next
= (struct mbuf
*)0;
1631 m_freem(rep
->r_mreq
);
1638 m_freem(rep
->r_mreq
);
1639 FSDBG_BOT(531, error
, rep
->r_xid
, nmp
, rep
);
1640 FREE_ZONE((caddr_t
)rep
, sizeof (struct nfsreq
), M_NFSREQ
);
1645 * Grab any Kerberos verifier, otherwise just throw it away.
1647 verf_type
= fxdr_unsigned(int, *tl
++);
1648 i
= fxdr_unsigned(int, *tl
);
1649 if ((nmp
->nm_flag
& NFSMNT_KERB
) && verf_type
== RPCAUTH_KERB4
) {
1650 error
= nfs_savenickauth(nmp
, cred
, i
, key
, &md
, &dpos
, mrep
);
1654 nfsm_adv(nfsm_rndup(i
));
1655 nfsm_dissect(tl
, u_long
*, NFSX_UNSIGNED
);
1658 nfsm_dissect(tl
, u_long
*, NFSX_UNSIGNED
);
1660 error
= fxdr_unsigned(int, *tl
);
1661 if ((nmp
->nm_flag
& NFSMNT_NFSV3
) &&
1662 error
== NFSERR_TRYLATER
) {
1666 waituntil
= now
.tv_sec
+ trylater_delay
;
1668 ("nfs_request %s flag=%x trylater_cnt=%x waituntil=%lx trylater_delay=%x\n",
1669 nmp
->nm_mountp
->mnt_stat
.f_mntfromname
,
1670 nmp
->nm_flag
, trylater_cnt
, waituntil
,
1672 while (now
.tv_sec
< waituntil
) {
1673 (void)tsleep((caddr_t
)&lbolt
,
1674 PSOCK
, "nqnfstry", 0);
1677 trylater_delay
*= 2;
1678 if (trylater_delay
> 60)
1679 trylater_delay
= 60;
1680 if (trylater_cnt
< 7)
1686 * If the File Handle was stale, invalidate the
1687 * lookup cache, just in case.
1689 if (error
== ESTALE
)
1691 if (nmp
->nm_flag
& NFSMNT_NFSV3
) {
1695 error
|= NFSERR_RETERR
;
1698 error
&= ~NFSERR_RETERR
;
1700 m_freem(rep
->r_mreq
);
1701 FSDBG_BOT(531, error
, rep
->r_xid
, nmp
, rep
);
1702 FREE_ZONE((caddr_t
)rep
,
1703 sizeof (struct nfsreq
), M_NFSREQ
);
1708 * For nqnfs, get any lease in reply
1710 if (nmp
->nm_flag
& NFSMNT_NQNFS
) {
1711 nfsm_dissect(tl
, u_long
*, NFSX_UNSIGNED
);
1714 nqlflag
= fxdr_unsigned(int, *tl
);
1715 nfsm_dissect(tl
, u_long
*, 4*NFSX_UNSIGNED
);
1716 cachable
= fxdr_unsigned(int, *tl
++);
1717 reqtime
+= fxdr_unsigned(int, *tl
++);
1719 if (reqtime
> now
.tv_sec
) {
1720 fxdr_hyper(tl
, &frev
);
1721 nqnfs_clientlease(nmp
, np
, nqlflag
,
1722 cachable
, reqtime
, frev
);
1729 m_freem(rep
->r_mreq
);
1730 FSDBG_BOT(531, 0xf0f0f0f0, rep
->r_xid
, nmp
, rep
);
1731 FREE_ZONE((caddr_t
)rep
, sizeof (struct nfsreq
), M_NFSREQ
);
1735 error
= EPROTONOSUPPORT
;
1737 m_freem(rep
->r_mreq
);
1738 FSDBG_BOT(531, error
, rep
->r_xid
, nmp
, rep
);
1739 FREE_ZONE((caddr_t
)rep
, sizeof (struct nfsreq
), M_NFSREQ
);
1743 #ifndef NFS_NOSERVER
1745 * Generate the rpc reply header
1746 * siz arg. is used to decide if adding a cluster is worthwhile
1749 nfs_rephead(siz
, nd
, slp
, err
, cache
, frev
, mrq
, mbp
, bposp
)
1751 struct nfsrv_descript
*nd
;
1752 struct nfssvc_sock
*slp
;
1760 register u_long
*tl
;
1761 register struct mbuf
*mreq
;
1763 struct mbuf
*mb
, *mb2
;
1765 MGETHDR(mreq
, M_WAIT
, MT_DATA
);
1768 * If this is a big reply, use a cluster else
1769 * try and leave leading space for the lower level headers.
1771 siz
+= RPC_REPLYSIZ
;
1772 if (siz
>= MINCLSIZE
) {
1773 MCLGET(mreq
, M_WAIT
);
1775 mreq
->m_data
+= max_hdr
;
1776 tl
= mtod(mreq
, u_long
*);
1777 mreq
->m_len
= 6 * NFSX_UNSIGNED
;
1778 bpos
= ((caddr_t
)tl
) + mreq
->m_len
;
1779 *tl
++ = txdr_unsigned(nd
->nd_retxid
);
1781 if (err
== ERPCMISMATCH
|| (err
& NFSERR_AUTHERR
)) {
1782 *tl
++ = rpc_msgdenied
;
1783 if (err
& NFSERR_AUTHERR
) {
1784 *tl
++ = rpc_autherr
;
1785 *tl
= txdr_unsigned(err
& ~NFSERR_AUTHERR
);
1786 mreq
->m_len
-= NFSX_UNSIGNED
;
1787 bpos
-= NFSX_UNSIGNED
;
1789 *tl
++ = rpc_mismatch
;
1790 *tl
++ = txdr_unsigned(RPC_VER2
);
1791 *tl
= txdr_unsigned(RPC_VER2
);
1794 *tl
++ = rpc_msgaccepted
;
1797 * For Kerberos authentication, we must send the nickname
1798 * verifier back, otherwise just RPCAUTH_NULL.
1800 if (nd
->nd_flag
& ND_KERBFULL
) {
1801 register struct nfsuid
*nuidp
;
1802 struct timeval ktvin
, ktvout
;
1804 for (nuidp
= NUIDHASH(slp
, nd
->nd_cr
.cr_uid
)->lh_first
;
1805 nuidp
!= 0; nuidp
= nuidp
->nu_hash
.le_next
) {
1806 if (nuidp
->nu_cr
.cr_uid
== nd
->nd_cr
.cr_uid
&&
1807 (!nd
->nd_nam2
|| netaddr_match(NU_NETFAM(nuidp
),
1808 &nuidp
->nu_haddr
, nd
->nd_nam2
)))
1813 txdr_unsigned(nuidp
->nu_timestamp
.tv_sec
- 1);
1815 txdr_unsigned(nuidp
->nu_timestamp
.tv_usec
);
1818 * Encrypt the timestamp in ecb mode using the
1825 *tl
++ = rpc_auth_kerb
;
1826 *tl
++ = txdr_unsigned(3 * NFSX_UNSIGNED
);
1827 *tl
= ktvout
.tv_sec
;
1828 nfsm_build(tl
, u_long
*, 3 * NFSX_UNSIGNED
);
1829 *tl
++ = ktvout
.tv_usec
;
1830 *tl
++ = txdr_unsigned(nuidp
->nu_cr
.cr_uid
);
1841 *tl
= txdr_unsigned(RPC_PROGUNAVAIL
);
1844 *tl
= txdr_unsigned(RPC_PROGMISMATCH
);
1845 nfsm_build(tl
, u_long
*, 2 * NFSX_UNSIGNED
);
1846 if (nd
->nd_flag
& ND_NQNFS
) {
1847 *tl
++ = txdr_unsigned(3);
1848 *tl
= txdr_unsigned(3);
1850 *tl
++ = txdr_unsigned(2);
1851 *tl
= txdr_unsigned(3);
1855 *tl
= txdr_unsigned(RPC_PROCUNAVAIL
);
1858 *tl
= txdr_unsigned(RPC_GARBAGE
);
1862 if (err
!= NFSERR_RETVOID
) {
1863 nfsm_build(tl
, u_long
*, NFSX_UNSIGNED
);
1865 *tl
= txdr_unsigned(nfsrv_errmap(nd
, err
));
1874 * For nqnfs, piggyback lease as requested.
1876 if ((nd
->nd_flag
& ND_NQNFS
) && err
== 0) {
1877 if (nd
->nd_flag
& ND_LEASE
) {
1878 nfsm_build(tl
, u_long
*, 5 * NFSX_UNSIGNED
);
1879 *tl
++ = txdr_unsigned(nd
->nd_flag
& ND_LEASE
);
1880 *tl
++ = txdr_unsigned(cache
);
1881 *tl
++ = txdr_unsigned(nd
->nd_duration
);
1882 txdr_hyper(frev
, tl
);
1884 nfsm_build(tl
, u_long
*, NFSX_UNSIGNED
);
1892 if (err
!= 0 && err
!= NFSERR_RETVOID
)
1893 nfsstats
.srvrpc_errs
++;
1898 #endif /* NFS_NOSERVER */
1902 * From FreeBSD 1.58, a Matt Dillon fix...
1903 * Flag a request as being about to terminate.
1904 * The nm_sent count is decremented now to avoid deadlocks when the process
1905 * in soreceive() hasn't yet managed to send its own request.
1908 nfs_softterm(struct nfsreq
*rep
)
1911 rep
->r_flags
|= R_SOFTTERM
;
1912 if (rep
->r_flags
& R_SENT
) {
1913 FSDBG(532, rep
->r_xid
, rep
, rep
->r_nmp
->nm_sent
,
1914 rep
->r_nmp
->nm_cwnd
);
1915 rep
->r_nmp
->nm_sent
-= NFS_CWNDSCALE
;
1916 rep
->r_flags
&= ~R_SENT
;
1921 nfs_timer_funnel(arg
)
1924 (void) thread_funnel_set(kernel_flock
, TRUE
);
1926 (void) thread_funnel_set(kernel_flock
, FALSE
);
1931 * Ensure rep isn't in use by the timer, then dequeue it.
1934 nfs_repdequeue(struct nfsreq
*rep
)
1938 while ((rep
->r_flags
& R_BUSY
)) {
1939 rep
->r_flags
|= R_WAITING
;
1940 tsleep(rep
, PSOCK
, "repdeq", 0);
1943 TAILQ_REMOVE(&nfs_reqq
, rep
, r_chain
);
1948 * Busy (lock) a nfsreq, used by the nfs timer to make sure it's not
1949 * free()'d out from under it.
1952 nfs_repbusy(struct nfsreq
*rep
)
1955 if ((rep
->r_flags
& R_BUSY
))
1956 panic("rep locked");
1957 rep
->r_flags
|= R_BUSY
;
1961 * Unbusy the nfsreq passed in, return the next nfsreq in the chain busied.
1964 nfs_repnext(struct nfsreq
*rep
)
1966 struct nfsreq
* nextrep
;
1971 * We need to get and busy the next req before signalling the
1972 * current one, otherwise wakeup() may block us and we'll race to
1973 * grab the next req.
1975 nextrep
= TAILQ_NEXT(rep
, r_chain
);
1976 if (nextrep
!= NULL
)
1977 nfs_repbusy(nextrep
);
1978 /* unbusy and signal. */
1979 rep
->r_flags
&= ~R_BUSY
;
1980 if ((rep
->r_flags
& R_WAITING
)) {
1981 rep
->r_flags
&= ~R_WAITING
;
1989 * Scan the nfsreq list and retranmit any requests that have timed out
1990 * To avoid retransmission attempts on STREAM sockets (in the future) make
1991 * sure to set the r_retry field to 0 (implies nm_retry == 0).
1995 void *arg
; /* never used */
1997 register struct nfsreq
*rep
;
1998 register struct mbuf
*m
;
1999 register struct socket
*so
;
2000 register struct nfsmount
*nmp
;
2003 #ifndef NFS_NOSERVER
2004 static long lasttime
= 0;
2005 register struct nfssvc_sock
*slp
;
2007 #endif /* NFS_NOSERVER */
2011 int flags
, rexmit
, cwnd
, sent
;
2017 * XXX If preemptable threads are implemented the spls used for the
2018 * outstanding request queue must be replaced with mutexes.
2020 #ifdef NFSTRACESUSPENDERS
2021 if (NFSTRACE_SUSPENDING
) {
2022 TAILQ_FOREACH(rep
, &nfs_reqq
, r_chain
)
2023 if (rep
->r_xid
== nfstracexid
)
2027 } else if (NFSTRACE_SUSPENSEOVER
) {
2032 rep
= TAILQ_FIRST(&nfs_reqq
);
2036 for ( ; rep
!= NULL
; rep
= nfs_repnext(rep
)) {
2037 #ifdef NFSTRACESUSPENDERS
2038 if (rep
->r_mrep
&& !NFSTRACE_SUSPENDING
) {
2039 nfstracexid
= rep
->r_xid
;
2040 NFSTRACE_STARTSUSPENDCOUNTDOWN
;
2044 if (!nmp
) /* unmounted */
2046 if (rep
->r_mrep
|| (rep
->r_flags
& R_SOFTTERM
))
2048 if (nfs_sigintr(nmp
, rep
, rep
->r_procp
))
2050 if (nmp
->nm_tprintf_initial_delay
!= 0 &&
2051 (rep
->r_rexmit
> 2 || (rep
->r_flags
& R_RESENDERR
)) &&
2052 rep
->r_lastmsg
+ nmp
->nm_tprintf_delay
< now
.tv_sec
) {
2053 rep
->r_lastmsg
= now
.tv_sec
;
2054 nfs_down(rep
, rep
->r_nmp
, rep
->r_procp
, "not responding",
2056 if (!(nmp
->nm_state
& NFSSTA_MOUNTED
)) {
2057 /* we're not yet completely mounted and */
2058 /* we can't complete an RPC, so we fail */
2059 nfsstats
.rpctimeouts
++;
2064 if (rep
->r_rtt
>= 0) {
2066 if (nmp
->nm_flag
& NFSMNT_DUMBTIMR
)
2067 timeo
= nmp
->nm_timeo
;
2069 timeo
= NFS_RTO(nmp
, proct
[rep
->r_procnum
]);
2070 /* ensure 62.5 ms floor */
2071 while (16 * timeo
< hz
)
2073 if (nmp
->nm_timeouts
> 0)
2074 timeo
*= nfs_backoff
[nmp
->nm_timeouts
- 1];
2075 if (rep
->r_rtt
<= timeo
)
2077 if (nmp
->nm_timeouts
< 8)
2081 * Check for too many retransmits. This is never true for
2082 * 'hard' mounts because we set r_retry to NFS_MAXREXMIT + 1
2083 * and never allow r_rexmit to be more than NFS_MAXREXMIT.
2085 if (rep
->r_rexmit
>= rep
->r_retry
) { /* too many */
2086 nfsstats
.rpctimeouts
++;
2090 if (nmp
->nm_sotype
!= SOCK_DGRAM
) {
2091 if (++rep
->r_rexmit
> NFS_MAXREXMIT
)
2092 rep
->r_rexmit
= NFS_MAXREXMIT
;
2095 if ((so
= nmp
->nm_so
) == NULL
)
2099 * If there is enough space and the window allows..
2101 * Set r_rtt to -1 in case we fail to send it now.
2104 rttdiag
= rep
->r_rtt
;
2107 if (sbspace(&so
->so_snd
) >= rep
->r_mreq
->m_pkthdr
.len
&&
2108 ((nmp
->nm_flag
& NFSMNT_DUMBTIMR
) ||
2109 (rep
->r_flags
& R_SENT
) ||
2110 nmp
->nm_sent
< nmp
->nm_cwnd
) &&
2111 (m
= m_copym(rep
->r_mreq
, 0, M_COPYALL
, M_DONTWAIT
))){
2113 struct proc
*p
= current_proc();
2116 if (rep
->r_flags
& R_SENT
&& nfsprnttimo
&&
2117 nmp
->nm_timeouts
>= nfsprnttimo
) {
2118 int t
= proct
[rep
->r_procnum
];
2120 NFS_DPF(DUP
, ("nfs_timer %s nmtm=%d tms=%d rtt=%d tm=%d p=%d A=%d D=%d\n", nmp
->nm_mountp
->mnt_stat
.f_mntfromname
, nmp
->nm_timeo
, nmp
->nm_timeouts
, rttdiag
, timeo
, rep
->r_procnum
, nmp
->nm_srtt
[t
-1], nmp
->nm_sdrtt
[t
-1]));
2122 NFS_DPF(DUP
, ("nfs_timer %s nmtm=%d tms=%d rtt=%d tm=%d p=%d\n", nmp
->nm_mountp
->mnt_stat
.f_mntfromname
, nmp
->nm_timeo
, nmp
->nm_timeouts
, rttdiag
, timeo
, rep
->r_procnum
));
2125 #endif /* NFSDIAG */
2127 * Iff first send, start timing
2128 * else turn timing off, backoff timer
2129 * and divide congestion window by 2.
2130 * We update these *before* the send to avoid
2131 * racing against receiving the reply.
2132 * We save them so we can restore them on send error.
2134 flags
= rep
->r_flags
;
2135 rexmit
= rep
->r_rexmit
;
2136 cwnd
= nmp
->nm_cwnd
;
2137 sent
= nmp
->nm_sent
;
2139 if (rep
->r_flags
& R_SENT
) {
2140 rep
->r_flags
&= ~R_TIMING
;
2141 if (++rep
->r_rexmit
> NFS_MAXREXMIT
)
2142 rep
->r_rexmit
= NFS_MAXREXMIT
;
2144 if (nmp
->nm_cwnd
< NFS_CWNDSCALE
)
2145 nmp
->nm_cwnd
= NFS_CWNDSCALE
;
2146 nfsstats
.rpcretries
++;
2148 rep
->r_flags
|= R_SENT
;
2149 nmp
->nm_sent
+= NFS_CWNDSCALE
;
2151 FSDBG(535, xid
, rep
, nmp
->nm_sent
, nmp
->nm_cwnd
);
2153 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
2155 if ((nmp
->nm_flag
& NFSMNT_NOCONN
) == 0)
2156 error
= (*so
->so_proto
->pr_usrreqs
->pru_send
)
2157 (so
, 0, m
, 0, 0, p
);
2159 error
= (*so
->so_proto
->pr_usrreqs
->pru_send
)
2160 (so
, 0, m
, mtod(nmp
->nm_nam
, struct sockaddr
*), 0, p
);
2162 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);
2164 FSDBG(535, xid
, error
, sent
, cwnd
);
2167 if (NFSIGNORE_SOERROR(nmp
->nm_soflags
, error
))
2169 rep
->r_flags
= flags
| R_RESENDERR
;
2170 rep
->r_rexmit
= rexmit
;
2171 nmp
->nm_cwnd
= cwnd
;
2172 nmp
->nm_sent
= sent
;
2174 nfsstats
.rpcretries
--;
2180 #ifndef NFS_NOSERVER
2182 * Call the nqnfs server timer once a second to handle leases.
2184 if (lasttime
!= now
.tv_sec
) {
2185 lasttime
= now
.tv_sec
;
2190 * Scan the write gathering queues for writes that need to be
2193 cur_usec
= (u_quad_t
)now
.tv_sec
* 1000000 + (u_quad_t
)now
.tv_usec
;
2194 TAILQ_FOREACH(slp
, &nfssvc_sockhead
, ns_chain
) {
2195 if (LIST_FIRST(&slp
->ns_tq
) &&
2196 LIST_FIRST(&slp
->ns_tq
)->nd_time
<= cur_usec
)
2197 nfsrv_wakenfsd(slp
);
2199 #endif /* NFS_NOSERVER */
2202 if (nfsbuffreeuptimestamp
+ 30 <= now
.tv_sec
) {
2204 * We haven't called nfs_buf_freeup() in a little while.
2205 * So, see if we can free up any stale/unused bufs now.
2210 timeout(nfs_timer_funnel
, (void *)0, nfs_ticks
);
2216 * Test for a termination condition pending on the process.
2217 * This is used to determine if we need to bail on a mount.
2218 * EIO is returned if there has been a soft timeout.
2219 * EINTR is returned if there is a signal pending that is not being ignored
2220 * and the mount is interruptable, or if we are a thread that is in the process
2221 * of cancellation (also SIGKILL posted).
2224 nfs_sigintr(nmp
, rep
, p
)
2225 struct nfsmount
*nmp
;
2229 struct uthread
*curr_td
;
2230 sigset_t pending_sigs
;
2231 int context_good
= 0;
2232 struct nfsmount
*repnmp
;
2237 repnmp
= rep
->r_nmp
;
2238 /* we've had a forced unmount. */
2241 /* request has timed out on a 'soft' mount. */
2242 if (rep
->r_flags
& R_SOFTTERM
)
2245 * We're in the progress of a force unmount and there's
2246 * been a timeout we're dead and fail IO.
2248 if ((repnmp
->nm_state
& (NFSSTA_FORCE
|NFSSTA_TIMEO
)) ==
2249 (NFSSTA_FORCE
|NFSSTA_TIMEO
))
2251 /* Someone is unmounting us, go soft and mark it. */
2252 if ((repnmp
->nm_mountp
->mnt_kern_flag
& MNTK_FRCUNMOUNT
)) {
2253 repnmp
->nm_flag
|= NFSMNT_SOFT
;
2254 nmp
->nm_state
|= NFSSTA_FORCE
;
2257 * If the mount is hung and we've requested not to hang
2258 * on remote filesystems, then bail now.
2260 if (p
!= NULL
&& (p
->p_flag
& P_NOREMOTEHANG
) != 0 &&
2261 (repnmp
->nm_state
& NFSSTA_TIMEO
) != 0)
2264 /* XXX: is this valid? this probably should be an assertion. */
2269 * XXX: Since nfs doesn't have a good shot at getting the current
2270 * thread we take a guess. (only struct proc * are passed to VOPs)
2271 * What we do is look at the current thread, if it belongs to the
2272 * passed in proc pointer then we have a "good/accurate" context
2273 * and can make an accurate guess as to what to do.
2274 * However if we have a bad context we have to make due with what
2275 * is in the proc struct which may not be as up to date as we'd
2277 * This is ok because the process will call us with the correct
2278 * context after a short timeout while waiting for a response.
2280 curr_td
= (struct uthread
*)get_bsdthread_info(current_act());
2281 if (curr_td
->uu_proc
== p
)
2283 if (context_good
&& current_thread_aborted())
2285 /* mask off thread and process blocked signals. */
2287 pending_sigs
= curr_td
->uu_siglist
& ~curr_td
->uu_sigmask
;
2289 pending_sigs
= p
->p_siglist
;
2290 /* mask off process level and NFS ignored signals. */
2291 pending_sigs
&= ~p
->p_sigignore
& NFSINT_SIGMASK
;
2292 if (pending_sigs
&& (nmp
->nm_flag
& NFSMNT_INT
) != 0)
2298 * Lock a socket against others.
2299 * Necessary for STREAM sockets to ensure you get an entire rpc request/reply
2300 * and also to avoid race conditions between the processes with nfs requests
2301 * in progress when a reconnect is necessary.
2307 register int *statep
;
2309 int error
, slpflag
= 0, slptimeo
= 0;
2311 if (rep
->r_nmp
== NULL
)
2313 statep
= &rep
->r_nmp
->nm_state
;
2316 if (rep
->r_nmp
->nm_flag
& NFSMNT_INT
)
2318 while (*statep
& NFSSTA_SNDLOCK
) {
2319 error
= nfs_sigintr(rep
->r_nmp
, rep
, p
);
2322 *statep
|= NFSSTA_WANTSND
;
2323 if (p
!= NULL
&& (p
->p_flag
& P_NOREMOTEHANG
) != 0)
2325 (void) tsleep((caddr_t
)statep
, slpflag
| (PZERO
- 1),
2326 "nfsndlck", slptimeo
);
2327 if (slpflag
== PCATCH
) {
2332 * Make sure while we slept that the mountpoint didn't go away.
2333 * nfs_sigintr and callers expect it in tact.
2336 return (ENXIO
); /* don't have lock until out of loop */
2338 *statep
|= NFSSTA_SNDLOCK
;
2343 * Unlock the stream socket for others.
2349 register int *statep
;
2351 if (rep
->r_nmp
== NULL
)
2353 statep
= &rep
->r_nmp
->nm_state
;
2354 if ((*statep
& NFSSTA_SNDLOCK
) == 0)
2355 panic("nfs sndunlock");
2356 *statep
&= ~NFSSTA_SNDLOCK
;
2357 if (*statep
& NFSSTA_WANTSND
) {
2358 *statep
&= ~NFSSTA_WANTSND
;
2359 wakeup((caddr_t
)statep
);
2365 register struct nfsreq
*rep
;
2367 register int *statep
;
2368 int error
, slpflag
, slptimeo
= 0;
2370 /* make sure we still have our mountpoint */
2372 if (rep
->r_mrep
!= NULL
)
2377 statep
= &rep
->r_nmp
->nm_state
;
2378 FSDBG_TOP(534, rep
->r_xid
, rep
, rep
->r_nmp
, *statep
);
2379 if (rep
->r_nmp
->nm_flag
& NFSMNT_INT
)
2383 while (*statep
& NFSSTA_RCVLOCK
) {
2384 if ((error
= nfs_sigintr(rep
->r_nmp
, rep
, rep
->r_procp
))) {
2385 FSDBG_BOT(534, rep
->r_xid
, rep
, rep
->r_nmp
, 0x100);
2387 } else if (rep
->r_mrep
!= NULL
) {
2389 * Don't bother sleeping if reply already arrived
2391 FSDBG_BOT(534, rep
->r_xid
, rep
, rep
->r_nmp
, 0x101);
2394 FSDBG(534, rep
->r_xid
, rep
, rep
->r_nmp
, 0x102);
2395 *statep
|= NFSSTA_WANTRCV
;
2397 * We need to poll if we're P_NOREMOTEHANG so that we
2398 * call nfs_sigintr periodically above.
2400 if (rep
->r_procp
!= NULL
&&
2401 (rep
->r_procp
->p_flag
& P_NOREMOTEHANG
) != 0)
2403 (void) tsleep((caddr_t
)statep
, slpflag
| (PZERO
- 1),
2404 "nfsrcvlk", slptimeo
);
2405 if (slpflag
== PCATCH
) {
2410 * Make sure while we slept that the mountpoint didn't go away.
2411 * nfs_sigintr and caller nfs_reply expect it intact.
2414 FSDBG_BOT(534, rep
->r_xid
, rep
, rep
->r_nmp
, 0x103);
2415 return (ENXIO
); /* don't have lock until out of loop */
2419 * nfs_reply will handle it if reply already arrived.
2420 * (We may have slept or been preempted while on network funnel).
2422 FSDBG_BOT(534, rep
->r_xid
, rep
, rep
->r_nmp
, *statep
);
2423 *statep
|= NFSSTA_RCVLOCK
;
2428 * Unlock the stream socket for others.
2432 register struct nfsreq
*rep
;
2434 register int *statep
;
2436 if (rep
->r_nmp
== NULL
)
2438 statep
= &rep
->r_nmp
->nm_state
;
2440 FSDBG(533, statep
, *statep
, 0, 0);
2441 if ((*statep
& NFSSTA_RCVLOCK
) == 0)
2442 panic("nfs rcvunlock");
2443 *statep
&= ~NFSSTA_RCVLOCK
;
2444 if (*statep
& NFSSTA_WANTRCV
) {
2445 *statep
&= ~NFSSTA_WANTRCV
;
2446 wakeup((caddr_t
)statep
);
2451 #ifndef NFS_NOSERVER
2453 * Socket upcall routine for the nfsd sockets.
2454 * The caddr_t arg is a pointer to the "struct nfssvc_sock".
2455 * Essentially do as much as possible non-blocking, else punt and it will
2456 * be called with M_WAIT from an nfsd.
2459 * Needs to run under network funnel
2462 nfsrv_rcv(so
, arg
, waitflag
)
2467 register struct nfssvc_sock
*slp
= (struct nfssvc_sock
*)arg
;
2468 register struct mbuf
*m
;
2469 struct mbuf
*mp
, *mhck
;
2470 struct sockaddr
*nam
;
2472 int flags
, ns_nflag
=0, error
;
2473 struct sockaddr_in
*sin
;
2475 if ((slp
->ns_flag
& SLP_VALID
) == 0)
2479 * Define this to test for nfsds handling this under heavy load.
2481 if (waitflag
== M_DONTWAIT
) {
2482 ns_nflag
= SLPN_NEEDQ
;
2486 auio
.uio_procp
= NULL
;
2487 if (so
->so_type
== SOCK_STREAM
) {
2489 * If there are already records on the queue, defer soreceive()
2490 * to an nfsd so that there is feedback to the TCP layer that
2491 * the nfs servers are heavily loaded.
2493 if (slp
->ns_rec
&& waitflag
== M_DONTWAIT
) {
2494 ns_nflag
= SLPN_NEEDQ
;
2501 auio
.uio_resid
= 1000000000;
2502 flags
= MSG_DONTWAIT
;
2503 error
= soreceive(so
, (struct sockaddr
**) 0, &auio
, &mp
, (struct mbuf
**)0, &flags
);
2504 if (error
|| mp
== (struct mbuf
*)0) {
2505 if (error
== EWOULDBLOCK
)
2506 ns_nflag
= SLPN_NEEDQ
;
2508 ns_nflag
= SLPN_DISCONN
;
2512 if (slp
->ns_rawend
) {
2513 slp
->ns_rawend
->m_next
= m
;
2514 slp
->ns_cc
+= 1000000000 - auio
.uio_resid
;
2517 slp
->ns_cc
= 1000000000 - auio
.uio_resid
;
2524 * Now try and parse record(s) out of the raw stream data.
2526 error
= nfsrv_getstream(slp
, waitflag
);
2529 ns_nflag
= SLPN_DISCONN
;
2531 ns_nflag
= SLPN_NEEDQ
;
2535 auio
.uio_resid
= 1000000000;
2536 flags
= MSG_DONTWAIT
| MSG_NEEDSA
;
2539 error
= soreceive(so
, &nam
, &auio
, &mp
,
2540 (struct mbuf
**)0, &flags
);
2544 MGET(mhck
, M_WAIT
, MT_SONAME
);
2545 mhck
->m_len
= nam
->sa_len
;
2546 sin
= mtod(mhck
, struct sockaddr_in
*);
2547 bcopy(nam
, sin
, sizeof(struct sockaddr_in
));
2548 mhck
->m_hdr
.mh_len
= sizeof(struct sockaddr_in
);
2555 slp
->ns_recend
->m_nextpkt
= m
;
2559 m
->m_nextpkt
= (struct mbuf
*)0;
2562 FREE(nam
, M_SONAME
);
2565 if ((so
->so_proto
->pr_flags
& PR_CONNREQUIRED
)
2566 && error
!= EWOULDBLOCK
) {
2567 ns_nflag
= SLPN_DISCONN
;
2575 * Now try and process the request records, non-blocking.
2579 slp
->ns_nflag
|= ns_nflag
;
2580 if (waitflag
== M_DONTWAIT
&&
2581 (slp
->ns_rec
|| (slp
->ns_nflag
& (SLPN_NEEDQ
| SLPN_DISCONN
)))) {
2582 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);
2583 nfsrv_wakenfsd(slp
);
2584 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
2589 * Try and extract an RPC request from the mbuf data list received on a
2590 * stream socket. The "waitflag" argument indicates whether or not it
2594 nfsrv_getstream(slp
, waitflag
)
2595 register struct nfssvc_sock
*slp
;
2598 register struct mbuf
*m
, **mpp
;
2599 register char *cp1
, *cp2
;
2601 struct mbuf
*om
, *m2
, *recm
;
2604 if (slp
->ns_nflag
& SLPN_GETSTREAM
)
2605 panic("nfs getstream");
2606 slp
->ns_nflag
|= SLPN_GETSTREAM
;
2608 if (slp
->ns_reclen
== 0) {
2609 if (slp
->ns_cc
< NFSX_UNSIGNED
) {
2610 slp
->ns_nflag
&= ~SLPN_GETSTREAM
;
2614 if (m
->m_len
>= NFSX_UNSIGNED
) {
2615 bcopy(mtod(m
, caddr_t
), (caddr_t
)&recmark
, NFSX_UNSIGNED
);
2616 m
->m_data
+= NFSX_UNSIGNED
;
2617 m
->m_len
-= NFSX_UNSIGNED
;
2619 cp1
= (caddr_t
)&recmark
;
2620 cp2
= mtod(m
, caddr_t
);
2621 while (cp1
< ((caddr_t
)&recmark
) + NFSX_UNSIGNED
) {
2622 while (m
->m_len
== 0) {
2624 cp2
= mtod(m
, caddr_t
);
2631 slp
->ns_cc
-= NFSX_UNSIGNED
;
2632 recmark
= ntohl(recmark
);
2633 slp
->ns_reclen
= recmark
& ~0x80000000;
2634 if (recmark
& 0x80000000)
2635 slp
->ns_nflag
|= SLPN_LASTFRAG
;
2637 slp
->ns_nflag
&= ~SLPN_LASTFRAG
;
2638 if (slp
->ns_reclen
< NFS_MINPACKET
|| slp
->ns_reclen
> NFS_MAXPACKET
) {
2639 slp
->ns_nflag
&= ~SLPN_GETSTREAM
;
2645 * Now get the record part.
2647 * Note that slp->ns_reclen may be 0. Linux sometimes
2648 * generates 0-length RPCs
2651 if (slp
->ns_cc
== slp
->ns_reclen
) {
2653 slp
->ns_raw
= slp
->ns_rawend
= (struct mbuf
*)0;
2654 slp
->ns_cc
= slp
->ns_reclen
= 0;
2655 } else if (slp
->ns_cc
> slp
->ns_reclen
) {
2658 om
= (struct mbuf
*)0;
2659 while (len
< slp
->ns_reclen
) {
2660 if ((len
+ m
->m_len
) > slp
->ns_reclen
) {
2661 m2
= m_copym(m
, 0, slp
->ns_reclen
- len
,
2669 m
->m_data
+= slp
->ns_reclen
- len
;
2670 m
->m_len
-= slp
->ns_reclen
- len
;
2671 len
= slp
->ns_reclen
;
2673 slp
->ns_nflag
&= ~SLPN_GETSTREAM
;
2674 return (EWOULDBLOCK
);
2676 } else if ((len
+ m
->m_len
) == slp
->ns_reclen
) {
2681 om
->m_next
= (struct mbuf
*)0;
2692 slp
->ns_nflag
&= ~SLPN_GETSTREAM
;
2697 * Accumulate the fragments into a record.
2699 mpp
= &slp
->ns_frag
;
2701 mpp
= &((*mpp
)->m_next
);
2703 if (slp
->ns_nflag
& SLPN_LASTFRAG
) {
2705 slp
->ns_recend
->m_nextpkt
= slp
->ns_frag
;
2707 slp
->ns_rec
= slp
->ns_frag
;
2708 slp
->ns_recend
= slp
->ns_frag
;
2709 slp
->ns_frag
= (struct mbuf
*)0;
2715 * Parse an RPC header.
2718 nfsrv_dorec(slp
, nfsd
, ndp
)
2719 register struct nfssvc_sock
*slp
;
2721 struct nfsrv_descript
**ndp
;
2723 register struct mbuf
*m
;
2724 register struct mbuf
*nam
;
2725 register struct nfsrv_descript
*nd
;
2729 if ((slp
->ns_flag
& SLP_VALID
) == 0 ||
2730 (m
= slp
->ns_rec
) == (struct mbuf
*)0)
2732 slp
->ns_rec
= m
->m_nextpkt
;
2734 m
->m_nextpkt
= (struct mbuf
*)0;
2736 slp
->ns_recend
= (struct mbuf
*)0;
2737 if (m
->m_type
== MT_SONAME
) {
2743 MALLOC_ZONE(nd
, struct nfsrv_descript
*,
2744 sizeof (struct nfsrv_descript
), M_NFSRVDESC
, M_WAITOK
);
2745 nd
->nd_md
= nd
->nd_mrep
= m
;
2747 nd
->nd_dpos
= mtod(m
, caddr_t
);
2748 error
= nfs_getreq(nd
, nfsd
, TRUE
);
2752 FREE_ZONE((caddr_t
)nd
, sizeof *nd
, M_NFSRVDESC
);
2761 * Parse an RPC request
2763 * - fill in the cred struct.
2766 nfs_getreq(nd
, nfsd
, has_header
)
2767 register struct nfsrv_descript
*nd
;
2771 register int len
, i
;
2772 register u_long
*tl
;
2776 caddr_t dpos
, cp2
, cp
;
2777 u_long nfsvers
, auth_type
;
2779 int error
= 0, nqnfs
= 0, ticklen
;
2780 struct mbuf
*mrep
, *md
;
2781 register struct nfsuid
*nuidp
;
2782 struct timeval tvin
, tvout
, now
;
2783 #if 0 /* until encrypted keys are implemented */
2784 NFSKERBKEYSCHED_T keys
; /* stores key schedule */
2791 nfsm_dissect(tl
, u_long
*, 10 * NFSX_UNSIGNED
);
2792 nd
->nd_retxid
= fxdr_unsigned(u_long
, *tl
++);
2793 if (*tl
++ != rpc_call
) {
2798 nfsm_dissect(tl
, u_long
*, 8 * NFSX_UNSIGNED
);
2801 if (*tl
++ != rpc_vers
) {
2802 nd
->nd_repstat
= ERPCMISMATCH
;
2803 nd
->nd_procnum
= NFSPROC_NOOP
;
2806 if (*tl
!= nfs_prog
) {
2807 if (*tl
== nqnfs_prog
)
2810 nd
->nd_repstat
= EPROGUNAVAIL
;
2811 nd
->nd_procnum
= NFSPROC_NOOP
;
2816 nfsvers
= fxdr_unsigned(u_long
, *tl
++);
2817 if (((nfsvers
< NFS_VER2
|| nfsvers
> NFS_VER3
) && !nqnfs
) ||
2818 (nfsvers
!= NQNFS_VER3
&& nqnfs
)) {
2819 nd
->nd_repstat
= EPROGMISMATCH
;
2820 nd
->nd_procnum
= NFSPROC_NOOP
;
2824 nd
->nd_flag
= (ND_NFSV3
| ND_NQNFS
);
2825 else if (nfsvers
== NFS_VER3
)
2826 nd
->nd_flag
= ND_NFSV3
;
2827 nd
->nd_procnum
= fxdr_unsigned(u_long
, *tl
++);
2828 if (nd
->nd_procnum
== NFSPROC_NULL
)
2830 if (nd
->nd_procnum
>= NFS_NPROCS
||
2831 (!nqnfs
&& nd
->nd_procnum
>= NQNFSPROC_GETLEASE
) ||
2832 (!nd
->nd_flag
&& nd
->nd_procnum
> NFSV2PROC_STATFS
)) {
2833 nd
->nd_repstat
= EPROCUNAVAIL
;
2834 nd
->nd_procnum
= NFSPROC_NOOP
;
2837 if ((nd
->nd_flag
& ND_NFSV3
) == 0)
2838 nd
->nd_procnum
= nfsv3_procid
[nd
->nd_procnum
];
2840 len
= fxdr_unsigned(int, *tl
++);
2841 if (len
< 0 || len
> RPCAUTH_MAXSIZ
) {
2846 nd
->nd_flag
&= ~ND_KERBAUTH
;
2848 * Handle auth_unix or auth_kerb.
2850 if (auth_type
== rpc_auth_unix
) {
2851 len
= fxdr_unsigned(int, *++tl
);
2852 if (len
< 0 || len
> NFS_MAXNAMLEN
) {
2856 nfsm_adv(nfsm_rndup(len
));
2857 nfsm_dissect(tl
, u_long
*, 3 * NFSX_UNSIGNED
);
2858 bzero((caddr_t
)&nd
->nd_cr
, sizeof (struct ucred
));
2859 nd
->nd_cr
.cr_ref
= 1;
2860 nd
->nd_cr
.cr_uid
= fxdr_unsigned(uid_t
, *tl
++);
2861 nd
->nd_cr
.cr_gid
= fxdr_unsigned(gid_t
, *tl
++);
2862 len
= fxdr_unsigned(int, *tl
);
2863 if (len
< 0 || len
> RPCAUTH_UNIXGIDS
) {
2867 nfsm_dissect(tl
, u_long
*, (len
+ 2) * NFSX_UNSIGNED
);
2868 for (i
= 1; i
<= len
; i
++)
2870 nd
->nd_cr
.cr_groups
[i
] = fxdr_unsigned(gid_t
, *tl
++);
2873 nd
->nd_cr
.cr_ngroups
= (len
>= NGROUPS
) ? NGROUPS
: (len
+ 1);
2874 if (nd
->nd_cr
.cr_ngroups
> 1)
2875 nfsrvw_sort(nd
->nd_cr
.cr_groups
, nd
->nd_cr
.cr_ngroups
);
2876 len
= fxdr_unsigned(int, *++tl
);
2877 if (len
< 0 || len
> RPCAUTH_MAXSIZ
) {
2882 nfsm_adv(nfsm_rndup(len
));
2883 } else if (auth_type
== rpc_auth_kerb
) {
2884 switch (fxdr_unsigned(int, *tl
++)) {
2885 case RPCAKN_FULLNAME
:
2886 ticklen
= fxdr_unsigned(int, *tl
);
2887 *((u_long
*)nfsd
->nfsd_authstr
) = *tl
;
2888 uio
.uio_resid
= nfsm_rndup(ticklen
) + NFSX_UNSIGNED
;
2889 nfsd
->nfsd_authlen
= uio
.uio_resid
+ NFSX_UNSIGNED
;
2890 if (uio
.uio_resid
> (len
- 2 * NFSX_UNSIGNED
)) {
2897 uio
.uio_segflg
= UIO_SYSSPACE
;
2898 iov
.iov_base
= (caddr_t
)&nfsd
->nfsd_authstr
[4];
2899 iov
.iov_len
= RPCAUTH_MAXSIZ
- 4;
2900 nfsm_mtouio(&uio
, uio
.uio_resid
);
2901 nfsm_dissect(tl
, u_long
*, 2 * NFSX_UNSIGNED
);
2902 if (*tl
++ != rpc_auth_kerb
||
2903 fxdr_unsigned(int, *tl
) != 4 * NFSX_UNSIGNED
) {
2904 printf("Bad kerb verifier\n");
2905 nd
->nd_repstat
= (NFSERR_AUTHERR
|AUTH_BADVERF
);
2906 nd
->nd_procnum
= NFSPROC_NOOP
;
2909 nfsm_dissect(cp
, caddr_t
, 4 * NFSX_UNSIGNED
);
2911 if (fxdr_unsigned(int, *tl
) != RPCAKN_FULLNAME
) {
2912 printf("Not fullname kerb verifier\n");
2913 nd
->nd_repstat
= (NFSERR_AUTHERR
|AUTH_BADVERF
);
2914 nd
->nd_procnum
= NFSPROC_NOOP
;
2917 cp
+= NFSX_UNSIGNED
;
2918 bcopy(cp
, nfsd
->nfsd_verfstr
, 3 * NFSX_UNSIGNED
);
2919 nfsd
->nfsd_verflen
= 3 * NFSX_UNSIGNED
;
2920 nd
->nd_flag
|= ND_KERBFULL
;
2921 nfsd
->nfsd_flag
|= NFSD_NEEDAUTH
;
2923 case RPCAKN_NICKNAME
:
2924 if (len
!= 2 * NFSX_UNSIGNED
) {
2925 printf("Kerb nickname short\n");
2926 nd
->nd_repstat
= (NFSERR_AUTHERR
|AUTH_BADCRED
);
2927 nd
->nd_procnum
= NFSPROC_NOOP
;
2930 nickuid
= fxdr_unsigned(uid_t
, *tl
);
2931 nfsm_dissect(tl
, u_long
*, 2 * NFSX_UNSIGNED
);
2932 if (*tl
++ != rpc_auth_kerb
||
2933 fxdr_unsigned(int, *tl
) != 3 * NFSX_UNSIGNED
) {
2934 printf("Kerb nick verifier bad\n");
2935 nd
->nd_repstat
= (NFSERR_AUTHERR
|AUTH_BADVERF
);
2936 nd
->nd_procnum
= NFSPROC_NOOP
;
2939 nfsm_dissect(tl
, u_long
*, 3 * NFSX_UNSIGNED
);
2940 tvin
.tv_sec
= *tl
++;
2943 for (nuidp
= NUIDHASH(nfsd
->nfsd_slp
,nickuid
)->lh_first
;
2944 nuidp
!= 0; nuidp
= nuidp
->nu_hash
.le_next
) {
2945 if (nuidp
->nu_cr
.cr_uid
== nickuid
&&
2947 netaddr_match(NU_NETFAM(nuidp
),
2948 &nuidp
->nu_haddr
, nd
->nd_nam2
)))
2953 (NFSERR_AUTHERR
|AUTH_REJECTCRED
);
2954 nd
->nd_procnum
= NFSPROC_NOOP
;
2959 * Now, decrypt the timestamp using the session key
2966 tvout
.tv_sec
= fxdr_unsigned(long, tvout
.tv_sec
);
2967 tvout
.tv_usec
= fxdr_unsigned(long, tvout
.tv_usec
);
2969 if (nuidp
->nu_expire
< now
.tv_sec
||
2970 nuidp
->nu_timestamp
.tv_sec
> tvout
.tv_sec
||
2971 (nuidp
->nu_timestamp
.tv_sec
== tvout
.tv_sec
&&
2972 nuidp
->nu_timestamp
.tv_usec
> tvout
.tv_usec
)) {
2973 nuidp
->nu_expire
= 0;
2975 (NFSERR_AUTHERR
|AUTH_REJECTVERF
);
2976 nd
->nd_procnum
= NFSPROC_NOOP
;
2979 nfsrv_setcred(&nuidp
->nu_cr
, &nd
->nd_cr
);
2980 nd
->nd_flag
|= ND_KERBNICK
;
2983 nd
->nd_repstat
= (NFSERR_AUTHERR
| AUTH_REJECTCRED
);
2984 nd
->nd_procnum
= NFSPROC_NOOP
;
2989 * For nqnfs, get piggybacked lease request.
2991 if (nqnfs
&& nd
->nd_procnum
!= NQNFSPROC_EVICTED
) {
2992 nfsm_dissect(tl
, u_long
*, NFSX_UNSIGNED
);
2993 nd
->nd_flag
|= fxdr_unsigned(int, *tl
);
2994 if (nd
->nd_flag
& ND_LEASE
) {
2995 nfsm_dissect(tl
, u_long
*, NFSX_UNSIGNED
);
2996 nd
->nd_duration
= fxdr_unsigned(int, *tl
);
2998 nd
->nd_duration
= NQ_MINLEASE
;
3000 nd
->nd_duration
= NQ_MINLEASE
;
3009 * Search for a sleeping nfsd and wake it up.
3010 * SIDE EFFECT: If none found, set NFSD_CHECKSLP flag, so that one of the
3011 * running nfsds will go look for the work in the nfssvc_sock list.
3015 struct nfssvc_sock
*slp
;
3017 register struct nfsd
*nd
;
3019 if ((slp
->ns_flag
& SLP_VALID
) == 0)
3021 TAILQ_FOREACH(nd
, &nfsd_head
, nfsd_chain
) {
3022 if (nd
->nfsd_flag
& NFSD_WAITING
) {
3023 nd
->nfsd_flag
&= ~NFSD_WAITING
;
3025 panic("nfsd wakeup");
3028 wakeup((caddr_t
)nd
);
3032 slp
->ns_flag
|= SLP_DOREC
;
3033 nfsd_head_flag
|= NFSD_CHECKSLP
;
3035 #endif /* NFS_NOSERVER */
3038 nfs_msg(p
, server
, msg
, error
)
3040 const char *server
, *msg
;
3046 tpr
= tprintf_open(p
);
3050 tprintf(tpr
, "nfs server %s: %s, error %d\n", server
, msg
,
3053 tprintf(tpr
, "nfs server %s: %s\n", server
, msg
);
3059 nfs_down(rep
, nmp
, proc
, msg
, error
, flags
)
3061 struct nfsmount
*nmp
;
3068 if ((flags
& NFSSTA_TIMEO
) && !(nmp
->nm_state
& NFSSTA_TIMEO
)) {
3069 vfs_event_signal(&nmp
->nm_mountp
->mnt_stat
.f_fsid
,
3071 nmp
->nm_state
|= NFSSTA_TIMEO
;
3073 if ((flags
& NFSSTA_LOCKTIMEO
) && !(nmp
->nm_state
& NFSSTA_LOCKTIMEO
)) {
3074 vfs_event_signal(&nmp
->nm_mountp
->mnt_stat
.f_fsid
,
3076 nmp
->nm_state
|= NFSSTA_LOCKTIMEO
;
3079 rep
->r_flags
|= R_TPRINTFMSG
;
3080 nfs_msg(proc
, nmp
->nm_mountp
->mnt_stat
.f_mntfromname
, msg
, error
);
3084 nfs_up(rep
, nmp
, proc
, msg
, flags
)
3086 struct nfsmount
*nmp
;
3093 if ((rep
== NULL
) || (rep
->r_flags
& R_TPRINTFMSG
) != 0)
3094 nfs_msg(proc
, nmp
->nm_mountp
->mnt_stat
.f_mntfromname
, msg
, 0);
3095 if ((flags
& NFSSTA_TIMEO
) && (nmp
->nm_state
& NFSSTA_TIMEO
)) {
3096 nmp
->nm_state
&= ~NFSSTA_TIMEO
;
3097 vfs_event_signal(&nmp
->nm_mountp
->mnt_stat
.f_fsid
,
3100 if ((flags
& NFSSTA_LOCKTIMEO
) && (nmp
->nm_state
& NFSSTA_LOCKTIMEO
)) {
3101 nmp
->nm_state
&= ~NFSSTA_LOCKTIMEO
;
3102 vfs_event_signal(&nmp
->nm_mountp
->mnt_stat
.f_fsid
,