1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1989, 1991, 1993, 1995
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Rick Macklem at The University of Guelph.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 */
35
36 #include <sys/cdefs.h>
37 /*
38 * Socket operations for use by nfs
39 */
40
41 #include "opt_kgssapi.h"
42 #include "opt_nfs.h"
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/limits.h>
48 #include <sys/lock.h>
49 #include <sys/malloc.h>
50 #include <sys/mbuf.h>
51 #include <sys/mount.h>
52 #include <sys/mutex.h>
53 #include <sys/proc.h>
54 #include <sys/signalvar.h>
55 #include <sys/syscallsubr.h>
56 #include <sys/sysctl.h>
57 #include <sys/syslog.h>
58 #include <sys/vnode.h>
59
60 #include <rpc/rpc.h>
61 #include <rpc/krpc.h>
62
63 #include <kgssapi/krb5/kcrypto.h>
64
65 #include <fs/nfs/nfsport.h>
66
67 #ifdef KDTRACE_HOOKS
68 #include <sys/dtrace_bsd.h>
69
70 dtrace_nfsclient_nfs23_start_probe_func_t
71 dtrace_nfscl_nfs234_start_probe;
72
73 dtrace_nfsclient_nfs23_done_probe_func_t
74 dtrace_nfscl_nfs234_done_probe;
75
76 /*
77 * Registered probes by RPC type.
78 */
79 uint32_t nfscl_nfs2_start_probes[NFSV41_NPROCS + 1];
80 uint32_t nfscl_nfs2_done_probes[NFSV41_NPROCS + 1];
81
82 uint32_t nfscl_nfs3_start_probes[NFSV41_NPROCS + 1];
83 uint32_t nfscl_nfs3_done_probes[NFSV41_NPROCS + 1];
84
85 uint32_t nfscl_nfs4_start_probes[NFSV41_NPROCS + 1];
86 uint32_t nfscl_nfs4_done_probes[NFSV41_NPROCS + 1];
87 #endif
88
89 NFSSTATESPINLOCK;
90 NFSREQSPINLOCK;
91 NFSDLOCKMUTEX;
92 NFSCLSTATEMUTEX;
93 extern struct nfsstatsv1 nfsstatsv1;
94 extern struct nfsreqhead nfsd_reqq;
95 extern int nfscl_ticks;
96 extern void (*ncl_call_invalcaches)(struct vnode *);
97 extern int nfs_numnfscbd;
98 extern int nfscl_debuglevel;
99 extern int nfsrv_lease;
100
101 SVCPOOL *nfscbd_pool;
102 int nfs_bufpackets = 4;
103 static int nfsrv_gsscallbackson = 0;
104 static int nfs_reconnects;
105 static int nfs3_jukebox_delay = 10;
106 static int nfs_skip_wcc_data_onerr = 1;
107 static int nfs_dsretries = 2;
108 static struct timespec nfs_trylater_max = {
109 .tv_sec = NFS_TRYLATERDEL,
110 .tv_nsec = 0,
111 };
112
113 SYSCTL_DECL(_vfs_nfs);
114
115 SYSCTL_INT(_vfs_nfs, OID_AUTO, bufpackets, CTLFLAG_RW, &nfs_bufpackets, 0,
116 "Buffer reservation size 2 < x < 64");
117 SYSCTL_INT(_vfs_nfs, OID_AUTO, reconnects, CTLFLAG_RD, &nfs_reconnects, 0,
118 "Number of times the nfs client has had to reconnect");
119 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs3_jukebox_delay, CTLFLAG_RW, &nfs3_jukebox_delay, 0,
120 "Number of seconds to delay a retry after receiving EJUKEBOX");
121 SYSCTL_INT(_vfs_nfs, OID_AUTO, skip_wcc_data_onerr, CTLFLAG_RW, &nfs_skip_wcc_data_onerr, 0,
122 "Disable weak cache consistency checking when server returns an error");
123 SYSCTL_INT(_vfs_nfs, OID_AUTO, dsretries, CTLFLAG_RW, &nfs_dsretries, 0,
124 "Number of retries for a DS RPC before failure");
125
126 static void nfs_down(struct nfsmount *, struct thread *, const char *,
127 int, int);
128 static void nfs_up(struct nfsmount *, struct thread *, const char *,
129 int, int);
130 static int nfs_msg(struct thread *, const char *, const char *, int);
131
132 struct nfs_cached_auth {
133 int ca_refs; /* refcount, including 1 from the cache */
134 uid_t ca_uid; /* uid that corresponds to this auth */
135 AUTH *ca_auth; /* RPC auth handle */
136 };
137
138 static int nfsv2_procid[NFS_V3NPROCS] = {
139 NFSV2PROC_NULL,
140 NFSV2PROC_GETATTR,
141 NFSV2PROC_SETATTR,
142 NFSV2PROC_LOOKUP,
143 NFSV2PROC_NOOP,
144 NFSV2PROC_READLINK,
145 NFSV2PROC_READ,
146 NFSV2PROC_WRITE,
147 NFSV2PROC_CREATE,
148 NFSV2PROC_MKDIR,
149 NFSV2PROC_SYMLINK,
150 NFSV2PROC_CREATE,
151 NFSV2PROC_REMOVE,
152 NFSV2PROC_RMDIR,
153 NFSV2PROC_RENAME,
154 NFSV2PROC_LINK,
155 NFSV2PROC_READDIR,
156 NFSV2PROC_NOOP,
157 NFSV2PROC_STATFS,
158 NFSV2PROC_NOOP,
159 NFSV2PROC_NOOP,
160 NFSV2PROC_NOOP,
161 };
162
163 /*
164 * This static array indicates that a NFSv4 RPC should use
165 * RPCSEC_GSS, if the mount indicates that via sec=krb5[ip].
166 * System RPCs that do not use file handles will be false
167 * in this array so that they will use AUTH_SYS when the
168 * "syskrb5" mount option is specified, along with
169 * "sec=krb5[ip]".
170 */
171 static bool nfscl_use_gss[NFSV42_NPROCS] = {
172 true,
173 true,
174 true,
175 true,
176 true,
177 true,
178 true,
179 true,
180 true,
181 true,
182 true,
183 true,
184 true,
185 true,
186 true,
187 true,
188 true,
189 true,
190 true,
191 true,
192 true,
193 true,
194 true,
195 false, /* SetClientID */
196 false, /* SetClientIDConfirm */
197 true,
198 true,
199 true,
200 true,
201 true,
202 true,
203 true,
204 false, /* Renew */
205 true,
206 false, /* ReleaseLockOwn */
207 true,
208 true,
209 true,
210 true,
211 true,
212 true,
213 false, /* ExchangeID */
214 false, /* CreateSession */
215 false, /* DestroySession */
216 false, /* DestroyClientID */
217 false, /* FreeStateID */
218 true,
219 true,
220 true,
221 true,
222 false, /* ReclaimComplete */
223 true,
224 true,
225 true,
226 true,
227 true,
228 true,
229 true,
230 true,
231 true,
232 true,
233 true,
234 true,
235 true,
236 true,
237 false, /* BindConnectionToSession */
238 true,
239 true,
240 true,
241 true,
242 true,
243 };
244
245 /*
246 * Initialize sockets and congestion for a new NFS connection.
247 * We do not free the sockaddr if error.
248 * Which arguments are set to NULL indicate what kind of call it is.
249 * cred == NULL --> a call to connect to a pNFS DS
250 * nmp == NULL --> indicates an upcall to userland or a NFSv4.0 callback
251 */
252 int
newnfs_connect(struct nfsmount * nmp,struct nfssockreq * nrp,struct ucred * cred,NFSPROC_T * p,int callback_retry_mult,bool dotls,struct __rpc_client ** clipp)253 newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp,
254 struct ucred *cred, NFSPROC_T *p, int callback_retry_mult, bool dotls,
255 struct __rpc_client **clipp)
256 {
257 int rcvreserve, sndreserve;
258 int pktscale, pktscalesav;
259 struct sockaddr *saddr;
260 struct ucred *origcred;
261 CLIENT *client;
262 struct netconfig *nconf;
263 struct socket *so;
264 int one = 1, retries, error = 0;
265 struct thread *td = curthread;
266 SVCXPRT *xprt;
267 struct timeval timo;
268 uint64_t tval;
269
270 /*
271 * We need to establish the socket using the credentials of
272 * the mountpoint. Some parts of this process (such as
273 * sobind() and soconnect()) will use the curent thread's
274 * credential instead of the socket credential. To work
275 * around this, temporarily change the current thread's
276 * credential to that of the mountpoint.
277 *
278 * XXX: It would be better to explicitly pass the correct
279 * credential to sobind() and soconnect().
280 */
281 origcred = td->td_ucred;
282
283 /*
284 * Use the credential in nr_cred, if not NULL.
285 */
286 if (nrp->nr_cred != NULL)
287 td->td_ucred = nrp->nr_cred;
288 else
289 td->td_ucred = cred;
290 saddr = nrp->nr_nam;
291
292 if (saddr->sa_family == AF_INET)
293 if (nrp->nr_sotype == SOCK_DGRAM)
294 nconf = getnetconfigent("udp");
295 else
296 nconf = getnetconfigent("tcp");
297 else
298 if (nrp->nr_sotype == SOCK_DGRAM)
299 nconf = getnetconfigent("udp6");
300 else
301 nconf = getnetconfigent("tcp6");
302
303 pktscale = nfs_bufpackets;
304 if (pktscale < 2)
305 pktscale = 2;
306 if (pktscale > 64)
307 pktscale = 64;
308 pktscalesav = pktscale;
309 /*
310 * soreserve() can fail if sb_max is too small, so shrink pktscale
311 * and try again if there is an error.
312 * Print a log message suggesting increasing sb_max.
313 * Creating a socket and doing this is necessary since, if the
314 * reservation sizes are too large and will make soreserve() fail,
315 * the connection will work until a large send is attempted and
316 * then it will loop in the krpc code.
317 */
318 so = NULL;
319 saddr = NFSSOCKADDR(nrp->nr_nam, struct sockaddr *);
320 error = socreate(saddr->sa_family, &so, nrp->nr_sotype,
321 nrp->nr_soproto, td->td_ucred, td);
322 if (error != 0)
323 goto out;
324 do {
325 if (error != 0 && pktscale > 2) {
326 if (nmp != NULL && nrp->nr_sotype == SOCK_STREAM &&
327 pktscale == pktscalesav) {
328 /*
329 * Suggest vfs.nfs.bufpackets * maximum RPC message,
330 * adjusted for the sb_max->sb_max_adj conversion of
331 * MCLBYTES / (MSIZE + MCLBYTES) as the minimum setting
332 * for kern.ipc.maxsockbuf.
333 */
334 tval = (NFS_MAXBSIZE + NFS_MAXXDR) * nfs_bufpackets;
335 tval *= MSIZE + MCLBYTES;
336 tval += MCLBYTES - 1; /* Round up divide by MCLBYTES. */
337 tval /= MCLBYTES;
338 printf("Consider increasing kern.ipc.maxsockbuf to a "
339 "minimum of %ju to support %ubyte NFS I/O\n",
340 (uintmax_t)tval, NFS_MAXBSIZE);
341 }
342 pktscale--;
343 }
344 if (nrp->nr_sotype == SOCK_DGRAM) {
345 if (nmp != NULL) {
346 sndreserve = (NFS_MAXDGRAMDATA + NFS_MAXPKTHDR) *
347 pktscale;
348 rcvreserve = (NFS_MAXDGRAMDATA + NFS_MAXPKTHDR) *
349 pktscale;
350 } else {
351 sndreserve = rcvreserve = 1024 * pktscale;
352 }
353 } else {
354 if (nrp->nr_sotype != SOCK_STREAM)
355 panic("nfscon sotype");
356 if (nmp != NULL) {
357 sndreserve = (NFS_MAXBSIZE + NFS_MAXXDR) *
358 pktscale;
359 rcvreserve = (NFS_MAXBSIZE + NFS_MAXXDR) *
360 pktscale;
361 } else {
362 sndreserve = rcvreserve = 1024 * pktscale;
363 }
364 }
365 error = soreserve(so, sndreserve, rcvreserve);
366 if (error != 0 && nmp != NULL && nrp->nr_sotype == SOCK_STREAM &&
367 pktscale <= 2)
368 printf("Must increase kern.ipc.maxsockbuf or reduce"
369 " rsize, wsize\n");
370 } while (error != 0 && pktscale > 2);
371 soclose(so);
372 if (error != 0)
373 goto out;
374
375 client = clnt_reconnect_create(nconf, saddr, nrp->nr_prog,
376 nrp->nr_vers, sndreserve, rcvreserve);
377 CLNT_CONTROL(client, CLSET_WAITCHAN, "nfsreq");
378 if (nmp != NULL) {
379 if ((nmp->nm_flag & NFSMNT_INT))
380 CLNT_CONTROL(client, CLSET_INTERRUPTIBLE, &one);
381 if ((nmp->nm_flag & NFSMNT_RESVPORT))
382 CLNT_CONTROL(client, CLSET_PRIVPORT, &one);
383 if (NFSHASTLS(nmp)) {
384 CLNT_CONTROL(client, CLSET_TLS, &one);
385 if (nmp->nm_tlscertname != NULL)
386 CLNT_CONTROL(client, CLSET_TLSCERTNAME,
387 nmp->nm_tlscertname);
388 }
389 if (NFSHASSOFT(nmp)) {
390 if (nmp->nm_sotype == SOCK_DGRAM)
391 /*
392 * For UDP, the large timeout for a reconnect
393 * will be set to "nm_retry * nm_timeo / 2", so
394 * we only want to do 2 reconnect timeout
395 * retries.
396 */
397 retries = 2;
398 else
399 retries = nmp->nm_retry;
400 } else
401 retries = INT_MAX;
402 if (NFSHASNFSV4N(nmp)) {
403 if (cred != NULL) {
404 if (NFSHASSOFT(nmp)) {
405 /*
406 * This should be a DS mount.
407 * Use CLSET_TIMEOUT to set the timeout
408 * for connections to DSs instead of
409 * specifying a timeout on each RPC.
410 * This is done so that SO_SNDTIMEO
411 * is set on the TCP socket as well
412 * as specifying a time limit when
413 * waiting for an RPC reply. Useful
414 * if the send queue for the TCP
415 * connection has become constipated,
416 * due to a failed DS.
417 * The choice of lease_duration / 4 is
418 * fairly arbitrary, but seems to work
419 * ok, with a lower bound of 10sec.
420 */
421 timo.tv_sec = nfsrv_lease / 4;
422 if (timo.tv_sec < 10)
423 timo.tv_sec = 10;
424 timo.tv_usec = 0;
425 CLNT_CONTROL(client, CLSET_TIMEOUT,
426 &timo);
427 }
428 /*
429 * Make sure the nfscbd_pool doesn't get
430 * destroyed while doing this.
431 */
432 NFSD_LOCK();
433 if (nfs_numnfscbd > 0) {
434 nfs_numnfscbd++;
435 NFSD_UNLOCK();
436 xprt = svc_vc_create_backchannel(
437 nfscbd_pool);
438 CLNT_CONTROL(client, CLSET_BACKCHANNEL,
439 xprt);
440 NFSD_LOCK();
441 nfs_numnfscbd--;
442 if (nfs_numnfscbd == 0)
443 wakeup(&nfs_numnfscbd);
444 }
445 NFSD_UNLOCK();
446 } else {
447 /*
448 * cred == NULL for a DS connect.
449 * For connects to a DS, set a retry limit
450 * so that failed DSs will be detected.
451 * This is ok for NFSv4.1, since a DS does
452 * not maintain open/lock state and is the
453 * only case where using a "soft" mount is
454 * recommended for NFSv4.
455 * For mounts from the MDS to DS, this is done
456 * via mount options, but that is not the case
457 * here. The retry limit here can be adjusted
458 * via the sysctl vfs.nfs.dsretries.
459 * See the comment above w.r.t. timeout.
460 */
461 timo.tv_sec = nfsrv_lease / 4;
462 if (timo.tv_sec < 10)
463 timo.tv_sec = 10;
464 timo.tv_usec = 0;
465 CLNT_CONTROL(client, CLSET_TIMEOUT, &timo);
466 retries = nfs_dsretries;
467 }
468 }
469 } else {
470 /*
471 * Three cases:
472 * - Null RPC callback to client
473 * - Non-Null RPC callback to client, wait a little longer
474 * - upcalls to nfsuserd and gssd (clp == NULL)
475 */
476 if (callback_retry_mult == 0) {
477 retries = NFSV4_UPCALLRETRY;
478 CLNT_CONTROL(client, CLSET_PRIVPORT, &one);
479 } else {
480 retries = NFSV4_CALLBACKRETRY * callback_retry_mult;
481 }
482 if (dotls)
483 CLNT_CONTROL(client, CLSET_TLS, &one);
484 }
485 CLNT_CONTROL(client, CLSET_RETRIES, &retries);
486
487 if (nmp != NULL) {
488 /*
489 * For UDP, there are 2 timeouts:
490 * - CLSET_RETRY_TIMEOUT sets the initial timeout for the timer
491 * that does a retransmit of an RPC request using the same
492 * socket and xid. This is what you normally want to do,
493 * since NFS servers depend on "same xid" for their
494 * Duplicate Request Cache.
495 * - timeout specified in CLNT_CALL_MBUF(), which specifies when
496 * retransmits on the same socket should fail and a fresh
497 * socket created. Each of these timeouts counts as one
498 * CLSET_RETRIES as set above.
499 * Set the initial retransmit timeout for UDP. This timeout
500 * doesn't exist for TCP and the following call just fails,
501 * which is ok.
502 */
503 timo.tv_sec = nmp->nm_timeo / NFS_HZ;
504 timo.tv_usec = (nmp->nm_timeo % NFS_HZ) * 1000000 / NFS_HZ;
505 CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, &timo);
506 }
507
508 /*
509 * *clipp is &nrp->nr_client or &nm_aconn[nmp->nm_nextaconn].
510 * The latter case is for additional connections specified by the
511 * "nconnect" mount option. nr_mtx etc is used for these additional
512 * connections, as well as nr_client in the nfssockreq
513 * structure for the mount.
514 */
515 mtx_lock(&nrp->nr_mtx);
516 if (*clipp != NULL) {
517 mtx_unlock(&nrp->nr_mtx);
518 /*
519 * Someone else already connected.
520 */
521 CLNT_RELEASE(client);
522 } else {
523 *clipp = client;
524 /*
525 * Protocols that do not require connections may be optionally
526 * left unconnected for servers that reply from a port other
527 * than NFS_PORT.
528 */
529 if (nmp == NULL || (nmp->nm_flag & NFSMNT_NOCONN) == 0) {
530 mtx_unlock(&nrp->nr_mtx);
531 CLNT_CONTROL(client, CLSET_CONNECT, &one);
532 } else
533 mtx_unlock(&nrp->nr_mtx);
534 }
535
536 out:
537 /* Restore current thread's credentials. */
538 td->td_ucred = origcred;
539
540 NFSEXITCODE(error);
541 return (error);
542 }
543
544 /*
545 * NFS disconnect. Clean up and unlink.
546 */
547 void
newnfs_disconnect(struct nfsmount * nmp,struct nfssockreq * nrp)548 newnfs_disconnect(struct nfsmount *nmp, struct nfssockreq *nrp)
549 {
550 CLIENT *client, *aconn[NFS_MAXNCONN - 1];
551 int i;
552
553 mtx_lock(&nrp->nr_mtx);
554 if (nrp->nr_client != NULL) {
555 client = nrp->nr_client;
556 nrp->nr_client = NULL;
557 if (nmp != NULL && nmp->nm_aconnect > 0) {
558 for (i = 0; i < nmp->nm_aconnect; i++) {
559 aconn[i] = nmp->nm_aconn[i];
560 nmp->nm_aconn[i] = NULL;
561 }
562 }
563 mtx_unlock(&nrp->nr_mtx);
564 CURVNET_SET_QUIET(CRED_TO_VNET(nrp->nr_cred));
565 rpc_gss_secpurge_call(client);
566 CURVNET_RESTORE();
567 CLNT_CLOSE(client);
568 CLNT_RELEASE(client);
569 if (nmp != NULL && nmp->nm_aconnect > 0) {
570 for (i = 0; i < nmp->nm_aconnect; i++) {
571 if (aconn[i] != NULL) {
572 rpc_gss_secpurge_call(aconn[i]);
573 CLNT_CLOSE(aconn[i]);
574 CLNT_RELEASE(aconn[i]);
575 }
576 }
577 }
578 } else {
579 mtx_unlock(&nrp->nr_mtx);
580 }
581 }
582
583 static AUTH *
nfs_getauth(struct nfssockreq * nrp,int secflavour,char * clnt_principal,char * srv_principal,gss_OID mech_oid,struct ucred * cred)584 nfs_getauth(struct nfssockreq *nrp, int secflavour, char *clnt_principal,
585 char *srv_principal, gss_OID mech_oid, struct ucred *cred)
586 {
587 rpc_gss_service_t svc;
588 AUTH *auth;
589
590 switch (secflavour) {
591 case RPCSEC_GSS_KRB5:
592 case RPCSEC_GSS_KRB5I:
593 case RPCSEC_GSS_KRB5P:
594 if (!mech_oid) {
595 if (!rpc_gss_mech_to_oid_call("kerberosv5", &mech_oid))
596 return (NULL);
597 }
598 if (secflavour == RPCSEC_GSS_KRB5)
599 svc = rpc_gss_svc_none;
600 else if (secflavour == RPCSEC_GSS_KRB5I)
601 svc = rpc_gss_svc_integrity;
602 else
603 svc = rpc_gss_svc_privacy;
604
605 if (clnt_principal == NULL) {
606 NFSCL_DEBUG(1, "nfs_getauth: clnt princ=NULL, "
607 "srv princ=%s\n", srv_principal);
608 auth = rpc_gss_secfind_call(nrp->nr_client, cred,
609 srv_principal, mech_oid, svc);
610 } else {
611 NFSCL_DEBUG(1, "nfs_getauth: clnt princ=%s "
612 "srv princ=%s\n", clnt_principal, srv_principal);
613 auth = rpc_gss_seccreate_call(nrp->nr_client, cred,
614 clnt_principal, srv_principal, "kerberosv5",
615 svc, NULL, NULL, NULL);
616 return (auth);
617 }
618 if (auth != NULL)
619 return (auth);
620 /* fallthrough */
621 case AUTH_SYS:
622 default:
623 return (authunix_create(cred));
624 }
625 }
626
627 /*
628 * Callback from the RPC code to generate up/down notifications.
629 */
630
631 struct nfs_feedback_arg {
632 struct nfsmount *nf_mount;
633 int nf_lastmsg; /* last tprintf */
634 int nf_tprintfmsg;
635 struct thread *nf_td;
636 };
637
638 static void
nfs_feedback(int type,int proc,void * arg)639 nfs_feedback(int type, int proc, void *arg)
640 {
641 struct nfs_feedback_arg *nf = (struct nfs_feedback_arg *) arg;
642 struct nfsmount *nmp = nf->nf_mount;
643 time_t now;
644
645 switch (type) {
646 case FEEDBACK_REXMIT2:
647 case FEEDBACK_RECONNECT:
648 now = NFSD_MONOSEC;
649 if (nf->nf_lastmsg + nmp->nm_tprintf_delay < now) {
650 nfs_down(nmp, nf->nf_td,
651 "not responding", 0, NFSSTA_TIMEO);
652 nf->nf_tprintfmsg = TRUE;
653 nf->nf_lastmsg = now;
654 }
655 break;
656
657 case FEEDBACK_OK:
658 nfs_up(nf->nf_mount, nf->nf_td,
659 "is alive again", NFSSTA_TIMEO, nf->nf_tprintfmsg);
660 break;
661 }
662 }
663
664 /*
665 * newnfs_request - goes something like this
666 * - does the rpc by calling the krpc layer
667 * - break down rpc header and return with nfs reply
668 * nb: always frees up nd_mreq mbuf list
669 */
670 int
newnfs_request(struct nfsrv_descript * nd,struct nfsmount * nmp,struct nfsclient * clp,struct nfssockreq * nrp,vnode_t vp,struct thread * td,struct ucred * cred,u_int32_t prog,u_int32_t vers,u_char * retsum,int toplevel,u_int64_t * xidp,struct nfsclsession * dssep)671 newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp,
672 struct nfsclient *clp, struct nfssockreq *nrp, vnode_t vp,
673 struct thread *td, struct ucred *cred, u_int32_t prog, u_int32_t vers,
674 u_char *retsum, int toplevel, u_int64_t *xidp, struct nfsclsession *dssep)
675 {
676 uint32_t retseq, retval, retval0, slotseq, *tl;
677 int i = 0, j = 0, opcnt, set_sigset = 0, slot;
678 int error = 0, usegssname = 0, secflavour = AUTH_SYS;
679 int freeslot, maxslot, reterr, slotpos, timeo;
680 u_int16_t procnum;
681 u_int nextconn;
682 struct nfs_feedback_arg nf;
683 struct timeval timo;
684 AUTH *auth;
685 struct rpc_callextra ext;
686 enum clnt_stat stat;
687 struct nfsreq *rep = NULL;
688 char *srv_principal = NULL, *clnt_principal = NULL;
689 sigset_t oldset;
690 struct ucred *authcred, *savcred;
691 struct nfsclsession *sep;
692 uint8_t sessionid[NFSX_V4SESSIONID];
693 bool nextconn_set;
694 struct timespec trylater_delay, ts, waituntil;
695
696 /* Initially 1msec. */
697 trylater_delay.tv_sec = 0;
698 trylater_delay.tv_nsec = 1000000;
699 sep = dssep;
700 if (xidp != NULL)
701 *xidp = 0;
702 /* Reject requests while attempting a forced unmount. */
703 if (nmp != NULL && NFSCL_FORCEDISM(nmp->nm_mountp)) {
704 m_freem(nd->nd_mreq);
705 return (ESTALE);
706 }
707
708 /*
709 * Set authcred, which is used to acquire RPC credentials to
710 * the cred argument, by default. The crhold() should not be
711 * necessary, but will ensure that some future code change
712 * doesn't result in the credential being free'd prematurely.
713 */
714 authcred = crhold(cred);
715
716 /* For client side interruptible mounts, mask off the signals. */
717 if (nmp != NULL && td != NULL && NFSHASINT(nmp)) {
718 newnfs_set_sigmask(td, &oldset);
719 set_sigset = 1;
720 }
721
722 /*
723 * If not already connected call newnfs_connect now.
724 */
725 if (nrp->nr_client == NULL)
726 newnfs_connect(nmp, nrp, cred, td, 0, false, &nrp->nr_client);
727
728 /*
729 * If the "nconnect" mount option was specified and this RPC is
730 * one that can have a large RPC message and is being done through
731 * the NFS/MDS server, use an additional connection. (When the RPC is
732 * being done through the server/MDS, nrp == &nmp->nm_sockreq.)
733 * The "nconnect" mount option normally has minimal effect when the
734 * "pnfs" mount option is specified, since only Readdir RPCs are
735 * normally done through the NFS/MDS server.
736 */
737 nextconn_set = false;
738 if (nmp != NULL && nmp->nm_aconnect > 0 && nrp == &nmp->nm_sockreq &&
739 (nd->nd_procnum == NFSPROC_READ ||
740 nd->nd_procnum == NFSPROC_READDIR ||
741 nd->nd_procnum == NFSPROC_READDIRPLUS ||
742 nd->nd_procnum == NFSPROC_WRITE)) {
743 nextconn = atomic_fetchadd_int(&nmp->nm_nextaconn, 1);
744 nextconn %= nmp->nm_aconnect;
745 nextconn_set = true;
746 if (nmp->nm_aconn[nextconn] == NULL)
747 newnfs_connect(nmp, nrp, cred, td, 0, false,
748 &nmp->nm_aconn[nextconn]);
749 }
750
751 /*
752 * For a client side mount, nmp is != NULL and clp == NULL. For
753 * server calls (callbacks or upcalls), nmp == NULL.
754 */
755 if (clp != NULL) {
756 NFSLOCKSTATE();
757 if ((clp->lc_flags & LCL_GSS) && nfsrv_gsscallbackson) {
758 secflavour = RPCSEC_GSS_KRB5;
759 if (nd->nd_procnum != NFSPROC_NULL) {
760 if (clp->lc_flags & LCL_GSSINTEGRITY)
761 secflavour = RPCSEC_GSS_KRB5I;
762 else if (clp->lc_flags & LCL_GSSPRIVACY)
763 secflavour = RPCSEC_GSS_KRB5P;
764 }
765 }
766 NFSUNLOCKSTATE();
767 } else if (nmp != NULL && NFSHASKERB(nmp) &&
768 nd->nd_procnum != NFSPROC_NULL && (!NFSHASSYSKRB5(nmp) ||
769 nfscl_use_gss[nd->nd_procnum])) {
770 if (NFSHASALLGSSNAME(nmp) && nmp->nm_krbnamelen > 0)
771 nd->nd_flag |= ND_USEGSSNAME;
772 if ((nd->nd_flag & ND_USEGSSNAME) != 0) {
773 /*
774 * If there is a client side host based credential,
775 * use that, otherwise use the system uid, if set.
776 * The system uid is in the nmp->nm_sockreq.nr_cred
777 * credentials.
778 */
779 if (nmp->nm_krbnamelen > 0) {
780 usegssname = 1;
781 clnt_principal = nmp->nm_krbname;
782 } else if (nmp->nm_uid != (uid_t)-1) {
783 KASSERT(nmp->nm_sockreq.nr_cred != NULL,
784 ("newnfs_request: NULL nr_cred"));
785 crfree(authcred);
786 authcred = crhold(nmp->nm_sockreq.nr_cred);
787 }
788 } else if (nmp->nm_krbnamelen == 0 &&
789 nmp->nm_uid != (uid_t)-1 && cred->cr_uid == (uid_t)0) {
790 /*
791 * If there is no host based principal name and
792 * the system uid is set and this is root, use the
793 * system uid, since root won't have user
794 * credentials in a credentials cache file.
795 * The system uid is in the nmp->nm_sockreq.nr_cred
796 * credentials.
797 */
798 KASSERT(nmp->nm_sockreq.nr_cred != NULL,
799 ("newnfs_request: NULL nr_cred"));
800 crfree(authcred);
801 authcred = crhold(nmp->nm_sockreq.nr_cred);
802 }
803 if (NFSHASINTEGRITY(nmp))
804 secflavour = RPCSEC_GSS_KRB5I;
805 else if (NFSHASPRIVACY(nmp))
806 secflavour = RPCSEC_GSS_KRB5P;
807 else
808 secflavour = RPCSEC_GSS_KRB5;
809 if (nrp->nr_srvprinc[0] == '\0')
810 srv_principal = NFSMNT_SRVKRBNAME(nmp);
811 else
812 srv_principal = nrp->nr_srvprinc;
813 } else if (nmp != NULL && (!NFSHASKERB(nmp) || NFSHASSYSKRB5(nmp)) &&
814 nd->nd_procnum != NFSPROC_NULL &&
815 (nd->nd_flag & ND_USEGSSNAME) != 0) {
816 /*
817 * Use the uid that did the mount when the RPC is doing
818 * NFSv4 system operations, as indicated by the
819 * ND_USEGSSNAME flag, for the AUTH_SYS case.
820 * The credentials in nm_sockreq.nr_cred were used for the
821 * mount.
822 */
823 KASSERT(nmp->nm_sockreq.nr_cred != NULL,
824 ("newnfs_request: NULL nr_cred"));
825 crfree(authcred);
826 authcred = crhold(nmp->nm_sockreq.nr_cred);
827 }
828
829 if (nmp != NULL) {
830 bzero(&nf, sizeof(struct nfs_feedback_arg));
831 nf.nf_mount = nmp;
832 nf.nf_td = td;
833 nf.nf_lastmsg = NFSD_MONOSEC -
834 ((nmp->nm_tprintf_delay)-(nmp->nm_tprintf_initial_delay));
835 }
836
837 /*
838 * For Kerberos, the upcall needs to be done to the gssd daemon
839 * running in the correct vnet.
840 */
841 CURVNET_SET_QUIET(CRED_TO_VNET(authcred));
842 if (nd->nd_procnum == NFSPROC_NULL)
843 auth = authnone_create();
844 else if (usegssname) {
845 /*
846 * For this case, the authenticator is held in the
847 * nfssockreq structure, so don't release the reference count
848 * held on it. --> Don't AUTH_DESTROY() it in this function.
849 */
850 if (nrp->nr_auth == NULL)
851 nrp->nr_auth = nfs_getauth(nrp, secflavour,
852 clnt_principal, srv_principal, NULL, authcred);
853 else
854 rpc_gss_refresh_auth_call(nrp->nr_auth);
855 auth = nrp->nr_auth;
856 } else
857 auth = nfs_getauth(nrp, secflavour, NULL,
858 srv_principal, NULL, authcred);
859 CURVNET_RESTORE();
860 if (auth == NULL) {
861 crfree(authcred);
862 m_freem(nd->nd_mreq);
863 if (set_sigset)
864 newnfs_restore_sigmask(td, &oldset);
865 return (EACCES);
866 }
867 bzero(&ext, sizeof(ext));
868 ext.rc_auth = auth;
869 if (nmp != NULL) {
870 ext.rc_feedback = nfs_feedback;
871 ext.rc_feedback_arg = &nf;
872 }
873
874 procnum = nd->nd_procnum;
875 if ((nd->nd_flag & ND_NFSV4) &&
876 nd->nd_procnum != NFSPROC_NULL &&
877 nd->nd_procnum != NFSV4PROC_CBCOMPOUND)
878 procnum = NFSV4PROC_COMPOUND;
879
880 if (nmp != NULL) {
881 NFSINCRGLOBAL(nfsstatsv1.rpcrequests);
882
883 /* Map the procnum to the old NFSv2 one, as required. */
884 if ((nd->nd_flag & ND_NFSV2) != 0) {
885 if (nd->nd_procnum < NFS_V3NPROCS)
886 procnum = nfsv2_procid[nd->nd_procnum];
887 else
888 procnum = NFSV2PROC_NOOP;
889 }
890
891 /*
892 * Now only used for the R_DONTRECOVER case, but until that is
893 * supported within the krpc code, I need to keep a queue of
894 * outstanding RPCs for nfsv4 client requests.
895 */
896 if ((nd->nd_flag & ND_NFSV4) && procnum == NFSV4PROC_COMPOUND)
897 rep = malloc(sizeof(struct nfsreq),
898 M_NFSDREQ, M_WAITOK);
899 #ifdef KDTRACE_HOOKS
900 if (dtrace_nfscl_nfs234_start_probe != NULL) {
901 uint32_t probe_id;
902 int probe_procnum;
903
904 if (nd->nd_flag & ND_NFSV4) {
905 probe_id =
906 nfscl_nfs4_start_probes[nd->nd_procnum];
907 probe_procnum = nd->nd_procnum;
908 } else if (nd->nd_flag & ND_NFSV3) {
909 probe_id = nfscl_nfs3_start_probes[procnum];
910 probe_procnum = procnum;
911 } else {
912 probe_id =
913 nfscl_nfs2_start_probes[nd->nd_procnum];
914 probe_procnum = procnum;
915 }
916 if (probe_id != 0)
917 (dtrace_nfscl_nfs234_start_probe)
918 (probe_id, vp, nd->nd_mreq, cred,
919 probe_procnum);
920 }
921 #endif
922 }
923 freeslot = -1; /* Set to slot that needs to be free'd */
924 tryagain:
925 slot = -1; /* Slot that needs a sequence# increment. */
926 /*
927 * This timeout specifies when a new socket should be created,
928 * along with new xid values. For UDP, this should be done
929 * infrequently, since retransmits of RPC requests should normally
930 * use the same xid.
931 */
932 if (nmp == NULL) {
933 if (clp == NULL) {
934 timo.tv_sec = NFSV4_UPCALLTIMEO;
935 timo.tv_usec = 0;
936 } else {
937 timo.tv_sec = NFSV4_CALLBACKTIMEO / 1000;
938 timo.tv_usec = NFSV4_CALLBACKTIMEO * 1000;
939 }
940 } else {
941 if (nrp->nr_sotype != SOCK_DGRAM) {
942 timo.tv_usec = 0;
943 if ((nmp->nm_flag & NFSMNT_NFSV4))
944 timo.tv_sec = INT_MAX;
945 else
946 timo.tv_sec = NFS_TCPTIMEO;
947 } else {
948 if (NFSHASSOFT(nmp)) {
949 /*
950 * CLSET_RETRIES is set to 2, so this should be
951 * half of the total timeout required.
952 */
953 timeo = nmp->nm_retry * nmp->nm_timeo / 2;
954 if (timeo < 1)
955 timeo = 1;
956 timo.tv_sec = timeo / NFS_HZ;
957 timo.tv_usec = (timeo % NFS_HZ) * 1000000 /
958 NFS_HZ;
959 } else {
960 /* For UDP hard mounts, use a large value. */
961 timo.tv_sec = NFS_MAXTIMEO / NFS_HZ;
962 timo.tv_usec = 0;
963 }
964 }
965
966 if (rep != NULL) {
967 rep->r_flags = 0;
968 rep->r_nmp = nmp;
969 /*
970 * Chain request into list of outstanding requests.
971 */
972 NFSLOCKREQ();
973 TAILQ_INSERT_TAIL(&nfsd_reqq, rep, r_chain);
974 NFSUNLOCKREQ();
975 }
976 }
977
978 /*
979 * In case CLNT_CALL_MBUF()/clnt_bck_call() does an AUTH_REFRESH(),
980 * the thread's credentials need to be set to authcred, so that the
981 * correct vnet will be set.
982 */
983 savcred = curthread->td_ucred;
984 curthread->td_ucred = authcred;
985 nd->nd_mrep = NULL;
986 if (clp != NULL && sep != NULL)
987 stat = clnt_bck_call(nrp->nr_client, &ext, procnum,
988 nd->nd_mreq, &nd->nd_mrep, timo, sep->nfsess_xprt);
989 else if (nextconn_set)
990 /*
991 * When there are multiple TCP connections, send the
992 * RPCs with large messages on the alternate TCP
993 * connection(s) in a round robin fashion.
994 * The small RPC messages are sent on the default
995 * TCP connection because they do not require much
996 * network bandwidth and separating them from the
997 * large RPC messages avoids them getting "log jammed"
998 * behind several large RPC messages.
999 */
1000 stat = CLNT_CALL_MBUF(nmp->nm_aconn[nextconn],
1001 &ext, procnum, nd->nd_mreq, &nd->nd_mrep, timo);
1002 else
1003 stat = CLNT_CALL_MBUF(nrp->nr_client, &ext, procnum,
1004 nd->nd_mreq, &nd->nd_mrep, timo);
1005 NFSCL_DEBUG(2, "clnt call=%d\n", stat);
1006 curthread->td_ucred = savcred;
1007
1008 if (rep != NULL) {
1009 /*
1010 * RPC done, unlink the request.
1011 */
1012 NFSLOCKREQ();
1013 TAILQ_REMOVE(&nfsd_reqq, rep, r_chain);
1014 NFSUNLOCKREQ();
1015 }
1016
1017 /*
1018 * If there was a successful reply and a tprintf msg.
1019 * tprintf a response.
1020 */
1021 if (stat == RPC_SUCCESS) {
1022 error = 0;
1023 } else if (stat == RPC_TIMEDOUT) {
1024 NFSINCRGLOBAL(nfsstatsv1.rpctimeouts);
1025 error = ETIMEDOUT;
1026 } else if (stat == RPC_VERSMISMATCH) {
1027 NFSINCRGLOBAL(nfsstatsv1.rpcinvalid);
1028 error = EOPNOTSUPP;
1029 } else if (stat == RPC_PROGVERSMISMATCH) {
1030 NFSINCRGLOBAL(nfsstatsv1.rpcinvalid);
1031 error = EPROTONOSUPPORT;
1032 } else if (stat == RPC_CANTSEND || stat == RPC_CANTRECV ||
1033 stat == RPC_SYSTEMERROR || stat == RPC_INTR) {
1034 /* Check for a session slot that needs to be free'd. */
1035 if ((nd->nd_flag & (ND_NFSV41 | ND_HASSLOTID)) ==
1036 (ND_NFSV41 | ND_HASSLOTID) && nmp != NULL &&
1037 nd->nd_procnum != NFSPROC_NULL) {
1038 /*
1039 * This should only occur when either the MDS or
1040 * a client has an RPC against a DS fail.
1041 * This happens because these cases use "soft"
1042 * connections that can time out and fail.
1043 * The slot used for this RPC is now in a
1044 * non-deterministic state, but if the slot isn't
1045 * free'd, threads can get stuck waiting for a slot.
1046 */
1047 if (sep == NULL)
1048 sep = nfsmnt_mdssession(nmp);
1049 /*
1050 * Bump the sequence# out of range, so that reuse of
1051 * this slot will result in an NFSERR_SEQMISORDERED
1052 * error and not a bogus cached RPC reply.
1053 */
1054 mtx_lock(&sep->nfsess_mtx);
1055 sep->nfsess_slotseq[nd->nd_slotid] += 10;
1056 sep->nfsess_badslots |= (0x1ULL << nd->nd_slotid);
1057 mtx_unlock(&sep->nfsess_mtx);
1058 /* And free the slot. */
1059 nfsv4_freeslot(sep, nd->nd_slotid, true);
1060 }
1061 if (stat == RPC_INTR)
1062 error = EINTR;
1063 else {
1064 NFSINCRGLOBAL(nfsstatsv1.rpcinvalid);
1065 error = ENXIO;
1066 }
1067 } else if (stat == RPC_AUTHERROR) {
1068 /* Check for a session slot that needs to be free'd. */
1069 if ((nd->nd_flag & (ND_NFSV41 | ND_HASSLOTID)) ==
1070 (ND_NFSV41 | ND_HASSLOTID) && nmp != NULL &&
1071 nd->nd_procnum != NFSPROC_NULL) {
1072 /*
1073 * This can occur when a Kerberos/RPCSEC_GSS session
1074 * expires, due to TGT expiration.
1075 * Free the slot, resetting the slot's sequence#.
1076 */
1077 if (sep == NULL)
1078 sep = nfsmnt_mdssession(nmp);
1079 nfsv4_freeslot(sep, nd->nd_slotid, true);
1080 }
1081 NFSINCRGLOBAL(nfsstatsv1.rpcinvalid);
1082 error = EACCES;
1083 } else {
1084 NFSINCRGLOBAL(nfsstatsv1.rpcinvalid);
1085 error = EACCES;
1086 }
1087 if (error) {
1088 crfree(authcred);
1089 m_freem(nd->nd_mreq);
1090 if (usegssname == 0)
1091 AUTH_DESTROY(auth);
1092 if (rep != NULL)
1093 free(rep, M_NFSDREQ);
1094 if (set_sigset)
1095 newnfs_restore_sigmask(td, &oldset);
1096 return (error);
1097 }
1098
1099 KASSERT(nd->nd_mrep != NULL, ("mrep shouldn't be NULL if no error\n"));
1100
1101 /*
1102 * Search for any mbufs that are not a multiple of 4 bytes long
1103 * or with m_data not longword aligned.
1104 * These could cause pointer alignment problems, so copy them to
1105 * well aligned mbufs.
1106 */
1107 newnfs_realign(&nd->nd_mrep, M_WAITOK);
1108 nd->nd_md = nd->nd_mrep;
1109 nd->nd_dpos = mtod(nd->nd_md, caddr_t);
1110 nd->nd_repstat = 0;
1111 if (nd->nd_procnum != NFSPROC_NULL &&
1112 nd->nd_procnum != NFSV4PROC_CBNULL) {
1113 /* If sep == NULL, set it to the default in nmp. */
1114 if (sep == NULL && nmp != NULL)
1115 sep = nfsmnt_mdssession(nmp);
1116 /*
1117 * and now the actual NFS xdr.
1118 */
1119 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
1120 nd->nd_repstat = fxdr_unsigned(u_int32_t, *tl);
1121 if (nd->nd_repstat >= 10000)
1122 NFSCL_DEBUG(1, "proc=%d reps=%d\n", (int)nd->nd_procnum,
1123 (int)nd->nd_repstat);
1124
1125 /*
1126 * Get rid of the tag, return count and SEQUENCE result for
1127 * NFSv4.
1128 */
1129 if ((nd->nd_flag & ND_NFSV4) != 0 && nd->nd_repstat !=
1130 NFSERR_MINORVERMISMATCH) {
1131 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
1132 i = fxdr_unsigned(int, *tl);
1133 error = nfsm_advance(nd, NFSM_RNDUP(i), -1);
1134 if (error)
1135 goto nfsmout;
1136 NFSM_DISSECT(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
1137 opcnt = fxdr_unsigned(int, *tl++);
1138 i = fxdr_unsigned(int, *tl++);
1139 j = fxdr_unsigned(int, *tl);
1140 if (j >= 10000)
1141 NFSCL_DEBUG(1, "fop=%d fst=%d\n", i, j);
1142 /*
1143 * If the first op is Sequence, free up the slot.
1144 */
1145 if ((nmp != NULL && i == NFSV4OP_SEQUENCE && j != 0) ||
1146 (clp != NULL && i == NFSV4OP_CBSEQUENCE && j != 0)) {
1147 NFSCL_DEBUG(1, "failed seq=%d\n", j);
1148 KASSERT(slot == -1, ("newnfs_request: slot not"
1149 " -1"));
1150 /*
1151 * RFC8881 (unlike RFC5661) specifies that a
1152 * NFSERR_DELAY reply to SEQUENCE is handled
1153 * by a retry with same slot/sequence#.
1154 * (Although not explicit, I will assume this
1155 * applies to CB_SEQUENCE as well.)
1156 */
1157 if (j == NFSERR_DELAY) {
1158 nd->nd_repstat =
1159 NFSERR_RETRYUNCACHEDREP;
1160 } else if (sep != NULL &&
1161 i == NFSV4OP_SEQUENCE &&
1162 j == NFSERR_SEQMISORDERED) {
1163 mtx_lock(&sep->nfsess_mtx);
1164 sep->nfsess_badslots |=
1165 (0x1ULL << nd->nd_slotid);
1166 mtx_unlock(&sep->nfsess_mtx);
1167 }
1168 }
1169 if (((nmp != NULL && i == NFSV4OP_SEQUENCE && j == 0) ||
1170 (clp != NULL && i == NFSV4OP_CBSEQUENCE &&
1171 j == 0)) && sep != NULL) {
1172 if (i == NFSV4OP_SEQUENCE)
1173 NFSM_DISSECT(tl, uint32_t *,
1174 NFSX_V4SESSIONID +
1175 5 * NFSX_UNSIGNED);
1176 else
1177 NFSM_DISSECT(tl, uint32_t *,
1178 NFSX_V4SESSIONID +
1179 4 * NFSX_UNSIGNED);
1180 mtx_lock(&sep->nfsess_mtx);
1181 if (bcmp(tl, sep->nfsess_sessionid,
1182 NFSX_V4SESSIONID) == 0) {
1183 tl += NFSX_V4SESSIONID / NFSX_UNSIGNED;
1184 retseq = fxdr_unsigned(uint32_t, *tl++);
1185 slot = fxdr_unsigned(int, *tl++);
1186 if ((nd->nd_flag & ND_HASSLOTID) != 0) {
1187 if (slot >= NFSV4_SLOTS ||
1188 (i == NFSV4OP_CBSEQUENCE &&
1189 slot >= NFSV4_CBSLOTS)) {
1190 printf("newnfs_request:"
1191 " Bogus slot\n");
1192 slot = nd->nd_slotid;
1193 } else if (slot !=
1194 nd->nd_slotid) {
1195 printf("newnfs_request:"
1196 " Wrong session "
1197 "srvslot=%d "
1198 "slot=%d\n", slot,
1199 nd->nd_slotid);
1200 if (i == NFSV4OP_SEQUENCE) {
1201 /*
1202 * Mark both slots as
1203 * bad, because we do
1204 * not know if the
1205 * server has advanced
1206 * the sequence# for
1207 * either of them.
1208 */
1209 sep->nfsess_badslots |=
1210 (0x1ULL << slot);
1211 sep->nfsess_badslots |=
1212 (0x1ULL <<
1213 nd->nd_slotid);
1214 }
1215 slot = nd->nd_slotid;
1216 }
1217 freeslot = slot;
1218 } else if (slot != 0) {
1219 printf("newnfs_request: Bad "
1220 "session slot=%d\n", slot);
1221 slot = 0;
1222 }
1223 if (retseq != sep->nfsess_slotseq[slot])
1224 printf("retseq diff 0x%x\n",
1225 retseq);
1226 retval0 = fxdr_unsigned(uint32_t,*tl++);
1227 retval = fxdr_unsigned(uint32_t, *tl);
1228 if ((retval + 1) < sep->nfsess_foreslots
1229 ) {
1230 sep->nfsess_foreslots = (retval
1231 + 1);
1232 nfs_resetslots(sep);
1233 } else if ((retval + 1) >
1234 sep->nfsess_foreslots) {
1235 if (retval0 > retval)
1236 printf("Sess:highest > "
1237 "target_highest\n");
1238 sep->nfsess_foreslots =
1239 (retval < NFSV4_SLOTS) ?
1240 (retval + 1) : NFSV4_SLOTS;
1241 }
1242 }
1243 mtx_unlock(&sep->nfsess_mtx);
1244
1245 /* Grab the op and status for the next one. */
1246 if (opcnt > 1) {
1247 NFSM_DISSECT(tl, uint32_t *,
1248 2 * NFSX_UNSIGNED);
1249 i = fxdr_unsigned(int, *tl++);
1250 j = fxdr_unsigned(int, *tl);
1251 }
1252 }
1253 }
1254 if (nd->nd_repstat != 0) {
1255 if (nd->nd_repstat == NFSERR_BADSESSION &&
1256 nmp != NULL && dssep == NULL &&
1257 (nd->nd_flag & ND_NFSV41) != 0) {
1258 /*
1259 * If this is a client side MDS RPC, mark
1260 * the MDS session defunct and initiate
1261 * recovery, as required.
1262 * The nfsess_defunct field is protected by
1263 * the NFSLOCKMNT()/nm_mtx lock and not the
1264 * nfsess_mtx lock to simplify its handling,
1265 * for the MDS session. This lock is also
1266 * sufficient for nfsess_sessionid, since it
1267 * never changes in the structure.
1268 */
1269 NFSCL_DEBUG(1, "Got badsession\n");
1270 NFSLOCKCLSTATE();
1271 NFSLOCKMNT(nmp);
1272 if (TAILQ_EMPTY(&nmp->nm_sess)) {
1273 NFSUNLOCKMNT(nmp);
1274 NFSUNLOCKCLSTATE();
1275 printf("If server has not rebooted, "
1276 "check NFS clients for unique "
1277 "/etc/hostid's\n");
1278 goto out;
1279 }
1280 sep = NFSMNT_MDSSESSION(nmp);
1281 if (bcmp(sep->nfsess_sessionid,
1282 nd->nd_sessionid, NFSX_V4SESSIONID) == 0) {
1283 /*
1284 * Initiate recovery. Even if
1285 * nfsess_defunct is already set,
1286 * another recovery may be needed.
1287 * NFSCLFLAGS_RECVRINPRG |
1288 * NFSCLFLAGS_RECOVER should avoid
1289 * recovery storms.
1290 */
1291 sep->nfsess_defunct = 1;
1292 NFSCL_DEBUG(1, "Marked defunct\n");
1293 if (nmp->nm_clp != NULL &&
1294 (nmp->nm_clp->nfsc_flags &
1295 (NFSCLFLAGS_RECVRINPROG |
1296 NFSCLFLAGS_RECOVER)) == 0) {
1297 nmp->nm_clp->nfsc_flags |=
1298 NFSCLFLAGS_RECOVER;
1299 wakeup(nmp->nm_clp);
1300 printf("Initiate recovery. If "
1301 "server has not rebooted, "
1302 "check NFS clients for "
1303 "unique /etc/hostid's\n");
1304 }
1305 }
1306 NFSUNLOCKCLSTATE();
1307 /*
1308 * Sleep for up to 1sec waiting for a new
1309 * session.
1310 */
1311 mtx_sleep(&nmp->nm_sess, &nmp->nm_mtx, PZERO,
1312 "nfsbadsess", hz);
1313 /*
1314 * Get the session again, in case a new one
1315 * has been created during the sleep.
1316 */
1317 sep = NFSMNT_MDSSESSION(nmp);
1318 NFSUNLOCKMNT(nmp);
1319 if ((nd->nd_flag & ND_LOOPBADSESS) != 0) {
1320 reterr = nfsv4_sequencelookup(nmp, sep,
1321 &slotpos, &maxslot, &slotseq,
1322 sessionid, true);
1323 if (reterr == 0) {
1324 /* Fill in new session info. */
1325 NFSCL_DEBUG(1,
1326 "Filling in new sequence\n");
1327 tl = nd->nd_sequence;
1328 bcopy(sessionid, tl,
1329 NFSX_V4SESSIONID);
1330 tl += NFSX_V4SESSIONID /
1331 NFSX_UNSIGNED;
1332 *tl++ = txdr_unsigned(slotseq);
1333 *tl++ = txdr_unsigned(slotpos);
1334 *tl = txdr_unsigned(maxslot);
1335 nd->nd_slotid = slotpos;
1336 nd->nd_flag |= ND_HASSLOTID;
1337 }
1338 if (reterr == NFSERR_BADSESSION ||
1339 reterr == 0) {
1340 NFSCL_DEBUG(1,
1341 "Badsession looping\n");
1342 m_freem(nd->nd_mrep);
1343 nd->nd_mrep = NULL;
1344 goto tryagain;
1345 }
1346 nd->nd_repstat = reterr;
1347 NFSCL_DEBUG(1, "Got err=%d\n", reterr);
1348 }
1349 }
1350 /*
1351 * When clp != NULL, it is a callback and all
1352 * callback operations can be retried for NFSERR_DELAY.
1353 */
1354 if (((nd->nd_repstat == NFSERR_DELAY ||
1355 nd->nd_repstat == NFSERR_GRACE) &&
1356 (nd->nd_flag & ND_NFSV4) && (clp != NULL ||
1357 (nd->nd_procnum != NFSPROC_DELEGRETURN &&
1358 nd->nd_procnum != NFSPROC_SETATTR &&
1359 nd->nd_procnum != NFSPROC_READ &&
1360 nd->nd_procnum != NFSPROC_READDS &&
1361 nd->nd_procnum != NFSPROC_WRITE &&
1362 nd->nd_procnum != NFSPROC_WRITEDS &&
1363 nd->nd_procnum != NFSPROC_OPEN &&
1364 nd->nd_procnum != NFSPROC_OPENLAYGET &&
1365 nd->nd_procnum != NFSPROC_CREATE &&
1366 nd->nd_procnum != NFSPROC_CREATELAYGET &&
1367 nd->nd_procnum != NFSPROC_OPENCONFIRM &&
1368 nd->nd_procnum != NFSPROC_OPENDOWNGRADE &&
1369 nd->nd_procnum != NFSPROC_CLOSE &&
1370 nd->nd_procnum != NFSPROC_LOCK &&
1371 nd->nd_procnum != NFSPROC_LOCKU))) ||
1372 (nd->nd_repstat == NFSERR_DELAY &&
1373 (nd->nd_flag & ND_NFSV4) == 0) ||
1374 nd->nd_repstat == NFSERR_RESOURCE ||
1375 nd->nd_repstat == NFSERR_RETRYUNCACHEDREP) {
1376 /* Clip at NFS_TRYLATERDEL. */
1377 if (timespeccmp(&trylater_delay,
1378 &nfs_trylater_max, >))
1379 trylater_delay = nfs_trylater_max;
1380 getnanouptime(&waituntil);
1381 timespecadd(&waituntil, &trylater_delay,
1382 &waituntil);
1383 do {
1384 nfs_catnap(PZERO, 0, "nfstry");
1385 getnanouptime(&ts);
1386 } while (timespeccmp(&ts, &waituntil, <));
1387 timespecadd(&trylater_delay, &trylater_delay,
1388 &trylater_delay); /* Double each time. */
1389 if (slot != -1) {
1390 mtx_lock(&sep->nfsess_mtx);
1391 sep->nfsess_slotseq[slot]++;
1392 *nd->nd_slotseq = txdr_unsigned(
1393 sep->nfsess_slotseq[slot]);
1394 mtx_unlock(&sep->nfsess_mtx);
1395 }
1396 m_freem(nd->nd_mrep);
1397 nd->nd_mrep = NULL;
1398 goto tryagain;
1399 }
1400
1401 /*
1402 * If the File Handle was stale, invalidate the
1403 * lookup cache, just in case.
1404 * (vp != NULL implies a client side call)
1405 */
1406 if (nd->nd_repstat == ESTALE && vp != NULL) {
1407 cache_purge(vp);
1408 if (ncl_call_invalcaches != NULL)
1409 (*ncl_call_invalcaches)(vp);
1410 }
1411 }
1412 if ((nd->nd_flag & ND_NFSV4) != 0) {
1413 /* Free the slot, as required. */
1414 if (freeslot != -1)
1415 nfsv4_freeslot(sep, freeslot, false);
1416 /*
1417 * If this op is Putfh, throw its results away.
1418 */
1419 if (j >= 10000)
1420 NFSCL_DEBUG(1, "nop=%d nst=%d\n", i, j);
1421 if (nmp != NULL && i == NFSV4OP_PUTFH && j == 0) {
1422 NFSM_DISSECT(tl,u_int32_t *,2 * NFSX_UNSIGNED);
1423 i = fxdr_unsigned(int, *tl++);
1424 j = fxdr_unsigned(int, *tl);
1425 if (j >= 10000)
1426 NFSCL_DEBUG(1, "n2op=%d n2st=%d\n", i,
1427 j);
1428 /*
1429 * All Compounds that do an Op that must
1430 * be in sequence consist of NFSV4OP_PUTFH
1431 * followed by one of these. As such, we
1432 * can determine if the seqid# should be
1433 * incremented, here.
1434 */
1435 if ((i == NFSV4OP_OPEN ||
1436 i == NFSV4OP_OPENCONFIRM ||
1437 i == NFSV4OP_OPENDOWNGRADE ||
1438 i == NFSV4OP_CLOSE ||
1439 i == NFSV4OP_LOCK ||
1440 i == NFSV4OP_LOCKU) &&
1441 (j == 0 ||
1442 (j != NFSERR_STALECLIENTID &&
1443 j != NFSERR_STALESTATEID &&
1444 j != NFSERR_BADSTATEID &&
1445 j != NFSERR_BADSEQID &&
1446 j != NFSERR_BADXDR &&
1447 j != NFSERR_RESOURCE &&
1448 j != NFSERR_NOFILEHANDLE)))
1449 nd->nd_flag |= ND_INCRSEQID;
1450 }
1451 /*
1452 * If this op's status is non-zero, mark
1453 * that there is no more data to process.
1454 * The exception is Setattr, which always has xdr
1455 * when it has failed.
1456 */
1457 if (j != 0 && i != NFSV4OP_SETATTR)
1458 nd->nd_flag |= ND_NOMOREDATA;
1459
1460 /*
1461 * If R_DONTRECOVER is set, replace the stale error
1462 * reply, so that recovery isn't initiated.
1463 */
1464 if ((nd->nd_repstat == NFSERR_STALECLIENTID ||
1465 nd->nd_repstat == NFSERR_BADSESSION ||
1466 nd->nd_repstat == NFSERR_STALESTATEID) &&
1467 rep != NULL && (rep->r_flags & R_DONTRECOVER))
1468 nd->nd_repstat = NFSERR_STALEDONTRECOVER;
1469 }
1470 }
1471 out:
1472 crfree(authcred);
1473
1474 #ifdef KDTRACE_HOOKS
1475 if (nmp != NULL && dtrace_nfscl_nfs234_done_probe != NULL) {
1476 uint32_t probe_id;
1477 int probe_procnum;
1478
1479 if (nd->nd_flag & ND_NFSV4) {
1480 probe_id = nfscl_nfs4_done_probes[nd->nd_procnum];
1481 probe_procnum = nd->nd_procnum;
1482 } else if (nd->nd_flag & ND_NFSV3) {
1483 probe_id = nfscl_nfs3_done_probes[procnum];
1484 probe_procnum = procnum;
1485 } else {
1486 probe_id = nfscl_nfs2_done_probes[nd->nd_procnum];
1487 probe_procnum = procnum;
1488 }
1489 if (probe_id != 0)
1490 (dtrace_nfscl_nfs234_done_probe)(probe_id, vp,
1491 nd->nd_mreq, cred, probe_procnum, 0);
1492 }
1493 #endif
1494
1495 m_freem(nd->nd_mreq);
1496 if (usegssname == 0)
1497 AUTH_DESTROY(auth);
1498 if (rep != NULL)
1499 free(rep, M_NFSDREQ);
1500 if (set_sigset)
1501 newnfs_restore_sigmask(td, &oldset);
1502 return (0);
1503 nfsmout:
1504 crfree(authcred);
1505 m_freem(nd->nd_mrep);
1506 m_freem(nd->nd_mreq);
1507 if (usegssname == 0)
1508 AUTH_DESTROY(auth);
1509 if (rep != NULL)
1510 free(rep, M_NFSDREQ);
1511 if (set_sigset)
1512 newnfs_restore_sigmask(td, &oldset);
1513 return (error);
1514 }
1515
1516 /*
1517 * Reset slots above nfsess_foreslots that are not busy.
1518 */
1519 void
nfs_resetslots(struct nfsclsession * sep)1520 nfs_resetslots(struct nfsclsession *sep)
1521 {
1522 int i;
1523 uint64_t bitval;
1524
1525 mtx_assert(&sep->nfsess_mtx, MA_OWNED);
1526 bitval = (1 << sep->nfsess_foreslots);
1527 for (i = sep->nfsess_foreslots; i < NFSV4_SLOTS; i++) {
1528 if ((sep->nfsess_slots & bitval) == 0 &&
1529 (sep->nfsess_badslots & bitval) == 0)
1530 sep->nfsess_slotseq[i] = 0;
1531 bitval <<= 1;
1532 }
1533 }
1534
1535 /*
1536 * Mark all of an nfs mount's outstanding requests with R_SOFTTERM and
1537 * wait for all requests to complete. This is used by forced unmounts
1538 * to terminate any outstanding RPCs.
1539 */
1540 int
newnfs_nmcancelreqs(struct nfsmount * nmp)1541 newnfs_nmcancelreqs(struct nfsmount *nmp)
1542 {
1543 struct nfsclds *dsp;
1544 struct __rpc_client *cl;
1545 int i;
1546
1547 if (nmp->nm_sockreq.nr_client != NULL)
1548 CLNT_CLOSE(nmp->nm_sockreq.nr_client);
1549 for (i = 0; i < nmp->nm_aconnect; i++)
1550 if (nmp->nm_aconn[i] != NULL)
1551 CLNT_CLOSE(nmp->nm_aconn[i]);
1552 lookformore:
1553 NFSLOCKMNT(nmp);
1554 TAILQ_FOREACH(dsp, &nmp->nm_sess, nfsclds_list) {
1555 NFSLOCKDS(dsp);
1556 if (dsp != TAILQ_FIRST(&nmp->nm_sess) &&
1557 (dsp->nfsclds_flags & NFSCLDS_CLOSED) == 0 &&
1558 dsp->nfsclds_sockp != NULL &&
1559 dsp->nfsclds_sockp->nr_client != NULL) {
1560 dsp->nfsclds_flags |= NFSCLDS_CLOSED;
1561 cl = dsp->nfsclds_sockp->nr_client;
1562 NFSUNLOCKDS(dsp);
1563 NFSUNLOCKMNT(nmp);
1564 CLNT_CLOSE(cl);
1565 goto lookformore;
1566 }
1567 NFSUNLOCKDS(dsp);
1568 }
1569 NFSUNLOCKMNT(nmp);
1570 return (0);
1571 }
1572
1573 /*
1574 * Any signal that can interrupt an NFS operation in an intr mount
1575 * should be added to this set. SIGSTOP and SIGKILL cannot be masked.
1576 */
1577 int newnfs_sig_set[] = {
1578 SIGINT,
1579 SIGTERM,
1580 SIGHUP,
1581 SIGKILL,
1582 SIGQUIT
1583 };
1584
1585 /*
1586 * Check to see if one of the signals in our subset is pending on
1587 * the process (in an intr mount).
1588 */
1589 static int
nfs_sig_pending(sigset_t set)1590 nfs_sig_pending(sigset_t set)
1591 {
1592 int i;
1593
1594 for (i = 0 ; i < nitems(newnfs_sig_set); i++)
1595 if (SIGISMEMBER(set, newnfs_sig_set[i]))
1596 return (1);
1597 return (0);
1598 }
1599
1600 /*
1601 * The set/restore sigmask functions are used to (temporarily) overwrite
1602 * the thread td_sigmask during an RPC call (for example). These are also
1603 * used in other places in the NFS client that might tsleep().
1604 */
1605 void
newnfs_set_sigmask(struct thread * td,sigset_t * oldset)1606 newnfs_set_sigmask(struct thread *td, sigset_t *oldset)
1607 {
1608 sigset_t newset;
1609 int i;
1610 struct proc *p;
1611
1612 SIGFILLSET(newset);
1613 if (td == NULL)
1614 td = curthread; /* XXX */
1615 p = td->td_proc;
1616 /* Remove the NFS set of signals from newset */
1617 PROC_LOCK(p);
1618 mtx_lock(&p->p_sigacts->ps_mtx);
1619 for (i = 0 ; i < nitems(newnfs_sig_set); i++) {
1620 /*
1621 * But make sure we leave the ones already masked
1622 * by the process, ie. remove the signal from the
1623 * temporary signalmask only if it wasn't already
1624 * in p_sigmask.
1625 */
1626 if (!SIGISMEMBER(td->td_sigmask, newnfs_sig_set[i]) &&
1627 !SIGISMEMBER(p->p_sigacts->ps_sigignore, newnfs_sig_set[i]))
1628 SIGDELSET(newset, newnfs_sig_set[i]);
1629 }
1630 mtx_unlock(&p->p_sigacts->ps_mtx);
1631 kern_sigprocmask(td, SIG_SETMASK, &newset, oldset,
1632 SIGPROCMASK_PROC_LOCKED);
1633 PROC_UNLOCK(p);
1634 }
1635
1636 void
newnfs_restore_sigmask(struct thread * td,sigset_t * set)1637 newnfs_restore_sigmask(struct thread *td, sigset_t *set)
1638 {
1639 if (td == NULL)
1640 td = curthread; /* XXX */
1641 kern_sigprocmask(td, SIG_SETMASK, set, NULL, 0);
1642 }
1643
1644 /*
1645 * NFS wrapper to msleep(), that shoves a new p_sigmask and restores the
1646 * old one after msleep() returns.
1647 */
1648 int
newnfs_msleep(struct thread * td,void * ident,struct mtx * mtx,int priority,char * wmesg,int timo)1649 newnfs_msleep(struct thread *td, void *ident, struct mtx *mtx, int priority, char *wmesg, int timo)
1650 {
1651 sigset_t oldset;
1652 int error;
1653
1654 if ((priority & PCATCH) == 0)
1655 return msleep(ident, mtx, priority, wmesg, timo);
1656 if (td == NULL)
1657 td = curthread; /* XXX */
1658 newnfs_set_sigmask(td, &oldset);
1659 error = msleep(ident, mtx, priority, wmesg, timo);
1660 newnfs_restore_sigmask(td, &oldset);
1661 return (error);
1662 }
1663
1664 /*
1665 * Test for a termination condition pending on the process.
1666 * This is used for NFSMNT_INT mounts.
1667 */
1668 int
newnfs_sigintr(struct nfsmount * nmp,struct thread * td)1669 newnfs_sigintr(struct nfsmount *nmp, struct thread *td)
1670 {
1671 struct proc *p;
1672 sigset_t tmpset;
1673
1674 /* Terminate all requests while attempting a forced unmount. */
1675 if (NFSCL_FORCEDISM(nmp->nm_mountp))
1676 return (EIO);
1677 if (!(nmp->nm_flag & NFSMNT_INT))
1678 return (0);
1679 if (td == NULL)
1680 return (0);
1681 p = td->td_proc;
1682 PROC_LOCK(p);
1683 tmpset = p->p_siglist;
1684 SIGSETOR(tmpset, td->td_siglist);
1685 SIGSETNAND(tmpset, td->td_sigmask);
1686 mtx_lock(&p->p_sigacts->ps_mtx);
1687 SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore);
1688 mtx_unlock(&p->p_sigacts->ps_mtx);
1689 if ((SIGNOTEMPTY(p->p_siglist) || SIGNOTEMPTY(td->td_siglist))
1690 && nfs_sig_pending(tmpset)) {
1691 PROC_UNLOCK(p);
1692 return (EINTR);
1693 }
1694 PROC_UNLOCK(p);
1695 return (0);
1696 }
1697
1698 static int
nfs_msg(struct thread * td,const char * server,const char * msg,int error)1699 nfs_msg(struct thread *td, const char *server, const char *msg, int error)
1700 {
1701 struct proc *p;
1702
1703 p = td ? td->td_proc : NULL;
1704 if (error) {
1705 tprintf(p, LOG_INFO, "nfs server %s: %s, error %d\n",
1706 server, msg, error);
1707 } else {
1708 tprintf(p, LOG_INFO, "nfs server %s: %s\n", server, msg);
1709 }
1710 return (0);
1711 }
1712
1713 static void
nfs_down(struct nfsmount * nmp,struct thread * td,const char * msg,int error,int flags)1714 nfs_down(struct nfsmount *nmp, struct thread *td, const char *msg,
1715 int error, int flags)
1716 {
1717 if (nmp == NULL)
1718 return;
1719 mtx_lock(&nmp->nm_mtx);
1720 if ((flags & NFSSTA_TIMEO) && !(nmp->nm_state & NFSSTA_TIMEO)) {
1721 nmp->nm_state |= NFSSTA_TIMEO;
1722 mtx_unlock(&nmp->nm_mtx);
1723 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid,
1724 VQ_NOTRESP, 0);
1725 } else
1726 mtx_unlock(&nmp->nm_mtx);
1727 mtx_lock(&nmp->nm_mtx);
1728 if ((flags & NFSSTA_LOCKTIMEO) && !(nmp->nm_state & NFSSTA_LOCKTIMEO)) {
1729 nmp->nm_state |= NFSSTA_LOCKTIMEO;
1730 mtx_unlock(&nmp->nm_mtx);
1731 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid,
1732 VQ_NOTRESPLOCK, 0);
1733 } else
1734 mtx_unlock(&nmp->nm_mtx);
1735 nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, error);
1736 }
1737
1738 static void
nfs_up(struct nfsmount * nmp,struct thread * td,const char * msg,int flags,int tprintfmsg)1739 nfs_up(struct nfsmount *nmp, struct thread *td, const char *msg,
1740 int flags, int tprintfmsg)
1741 {
1742 if (nmp == NULL)
1743 return;
1744 if (tprintfmsg) {
1745 nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, 0);
1746 }
1747
1748 mtx_lock(&nmp->nm_mtx);
1749 if ((flags & NFSSTA_TIMEO) && (nmp->nm_state & NFSSTA_TIMEO)) {
1750 nmp->nm_state &= ~NFSSTA_TIMEO;
1751 mtx_unlock(&nmp->nm_mtx);
1752 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid,
1753 VQ_NOTRESP, 1);
1754 } else
1755 mtx_unlock(&nmp->nm_mtx);
1756
1757 mtx_lock(&nmp->nm_mtx);
1758 if ((flags & NFSSTA_LOCKTIMEO) && (nmp->nm_state & NFSSTA_LOCKTIMEO)) {
1759 nmp->nm_state &= ~NFSSTA_LOCKTIMEO;
1760 mtx_unlock(&nmp->nm_mtx);
1761 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid,
1762 VQ_NOTRESPLOCK, 1);
1763 } else
1764 mtx_unlock(&nmp->nm_mtx);
1765 }
1766