1 /*- 2 * Copyright (c) 1989, 1991, 1993, 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rick Macklem at The University of Guelph. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 4. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 */ 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 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 62 #include <kgssapi/krb5/kcrypto.h> 63 64 #include <fs/nfs/nfsport.h> 65 66 #ifdef KDTRACE_HOOKS 67 #include <sys/dtrace_bsd.h> 68 69 dtrace_nfsclient_nfs23_start_probe_func_t 70 dtrace_nfscl_nfs234_start_probe; 71 72 dtrace_nfsclient_nfs23_done_probe_func_t 73 dtrace_nfscl_nfs234_done_probe; 74 75 /* 76 * Registered probes by RPC type. 77 */ 78 uint32_t nfscl_nfs2_start_probes[NFSV41_NPROCS + 1]; 79 uint32_t nfscl_nfs2_done_probes[NFSV41_NPROCS + 1]; 80 81 uint32_t nfscl_nfs3_start_probes[NFSV41_NPROCS + 1]; 82 uint32_t nfscl_nfs3_done_probes[NFSV41_NPROCS + 1]; 83 84 uint32_t nfscl_nfs4_start_probes[NFSV41_NPROCS + 1]; 85 uint32_t nfscl_nfs4_done_probes[NFSV41_NPROCS + 1]; 86 #endif 87 88 NFSSTATESPINLOCK; 89 NFSREQSPINLOCK; 90 NFSDLOCKMUTEX; 91 extern struct nfsstats newnfsstats; 92 extern struct nfsreqhead nfsd_reqq; 93 extern int nfscl_ticks; 94 extern void (*ncl_call_invalcaches)(struct vnode *); 95 extern int nfs_numnfscbd; 96 extern int nfscl_debuglevel; 97 98 SVCPOOL *nfscbd_pool; 99 static int nfsrv_gsscallbackson = 0; 100 static int nfs_bufpackets = 4; 101 static int nfs_reconnects; 102 static int nfs3_jukebox_delay = 10; 103 static int nfs_skip_wcc_data_onerr = 1; 104 105 SYSCTL_DECL(_vfs_nfs); 106 107 SYSCTL_INT(_vfs_nfs, OID_AUTO, bufpackets, CTLFLAG_RW, &nfs_bufpackets, 0, 108 "Buffer reservation size 2 < x < 64"); 109 SYSCTL_INT(_vfs_nfs, OID_AUTO, reconnects, CTLFLAG_RD, &nfs_reconnects, 0, 110 "Number of times the nfs client has had to reconnect"); 111 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs3_jukebox_delay, CTLFLAG_RW, &nfs3_jukebox_delay, 0, 112 "Number of seconds to delay a retry after receiving EJUKEBOX"); 113 SYSCTL_INT(_vfs_nfs, OID_AUTO, skip_wcc_data_onerr, CTLFLAG_RW, &nfs_skip_wcc_data_onerr, 0, 114 "Disable weak cache consistency checking when server returns an error"); 115 116 static void nfs_down(struct nfsmount *, struct thread *, const char *, 117 int, int); 118 static void nfs_up(struct nfsmount *, struct thread *, const char *, 119 int, int); 120 static int nfs_msg(struct thread *, const char *, const char *, int); 121 122 struct nfs_cached_auth { 123 int ca_refs; /* refcount, including 1 from the cache */ 124 uid_t ca_uid; /* uid that corresponds to this auth */ 125 AUTH *ca_auth; /* RPC auth handle */ 126 }; 127 128 static int nfsv2_procid[NFS_V3NPROCS] = { 129 NFSV2PROC_NULL, 130 NFSV2PROC_GETATTR, 131 NFSV2PROC_SETATTR, 132 NFSV2PROC_LOOKUP, 133 NFSV2PROC_NOOP, 134 NFSV2PROC_READLINK, 135 NFSV2PROC_READ, 136 NFSV2PROC_WRITE, 137 NFSV2PROC_CREATE, 138 NFSV2PROC_MKDIR, 139 NFSV2PROC_SYMLINK, 140 NFSV2PROC_CREATE, 141 NFSV2PROC_REMOVE, 142 NFSV2PROC_RMDIR, 143 NFSV2PROC_RENAME, 144 NFSV2PROC_LINK, 145 NFSV2PROC_READDIR, 146 NFSV2PROC_NOOP, 147 NFSV2PROC_STATFS, 148 NFSV2PROC_NOOP, 149 NFSV2PROC_NOOP, 150 NFSV2PROC_NOOP, 151 }; 152 153 /* 154 * Initialize sockets and congestion for a new NFS connection. 155 * We do not free the sockaddr if error. 156 */ 157 int 158 newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp, 159 struct ucred *cred, NFSPROC_T *p, int callback_retry_mult) 160 { 161 int rcvreserve, sndreserve; 162 int pktscale; 163 struct sockaddr *saddr; 164 struct ucred *origcred; 165 CLIENT *client; 166 struct netconfig *nconf; 167 struct socket *so; 168 int one = 1, retries, error = 0; 169 struct thread *td = curthread; 170 SVCXPRT *xprt; 171 struct timeval timo; 172 173 /* 174 * We need to establish the socket using the credentials of 175 * the mountpoint. Some parts of this process (such as 176 * sobind() and soconnect()) will use the curent thread's 177 * credential instead of the socket credential. To work 178 * around this, temporarily change the current thread's 179 * credential to that of the mountpoint. 180 * 181 * XXX: It would be better to explicitly pass the correct 182 * credential to sobind() and soconnect(). 183 */ 184 origcred = td->td_ucred; 185 186 /* 187 * Use the credential in nr_cred, if not NULL. 188 */ 189 if (nrp->nr_cred != NULL) 190 td->td_ucred = nrp->nr_cred; 191 else 192 td->td_ucred = cred; 193 saddr = nrp->nr_nam; 194 195 if (saddr->sa_family == AF_INET) 196 if (nrp->nr_sotype == SOCK_DGRAM) 197 nconf = getnetconfigent("udp"); 198 else 199 nconf = getnetconfigent("tcp"); 200 else 201 if (nrp->nr_sotype == SOCK_DGRAM) 202 nconf = getnetconfigent("udp6"); 203 else 204 nconf = getnetconfigent("tcp6"); 205 206 pktscale = nfs_bufpackets; 207 if (pktscale < 2) 208 pktscale = 2; 209 if (pktscale > 64) 210 pktscale = 64; 211 /* 212 * soreserve() can fail if sb_max is too small, so shrink pktscale 213 * and try again if there is an error. 214 * Print a log message suggesting increasing sb_max. 215 * Creating a socket and doing this is necessary since, if the 216 * reservation sizes are too large and will make soreserve() fail, 217 * the connection will work until a large send is attempted and 218 * then it will loop in the krpc code. 219 */ 220 so = NULL; 221 saddr = NFSSOCKADDR(nrp->nr_nam, struct sockaddr *); 222 error = socreate(saddr->sa_family, &so, nrp->nr_sotype, 223 nrp->nr_soproto, td->td_ucred, td); 224 if (error) { 225 td->td_ucred = origcred; 226 goto out; 227 } 228 do { 229 if (error != 0 && pktscale > 2) 230 pktscale--; 231 if (nrp->nr_sotype == SOCK_DGRAM) { 232 if (nmp != NULL) { 233 sndreserve = (NFS_MAXDGRAMDATA + NFS_MAXPKTHDR) * 234 pktscale; 235 rcvreserve = (NFS_MAXDGRAMDATA + NFS_MAXPKTHDR) * 236 pktscale; 237 } else { 238 sndreserve = rcvreserve = 1024 * pktscale; 239 } 240 } else { 241 if (nrp->nr_sotype != SOCK_STREAM) 242 panic("nfscon sotype"); 243 if (nmp != NULL) { 244 sndreserve = (NFS_MAXBSIZE + NFS_MAXPKTHDR + 245 sizeof (u_int32_t)) * pktscale; 246 rcvreserve = (NFS_MAXBSIZE + NFS_MAXPKTHDR + 247 sizeof (u_int32_t)) * pktscale; 248 } else { 249 sndreserve = rcvreserve = 1024 * pktscale; 250 } 251 } 252 error = soreserve(so, sndreserve, rcvreserve); 253 } while (error != 0 && pktscale > 2); 254 soclose(so); 255 if (error) { 256 td->td_ucred = origcred; 257 goto out; 258 } 259 260 client = clnt_reconnect_create(nconf, saddr, nrp->nr_prog, 261 nrp->nr_vers, sndreserve, rcvreserve); 262 CLNT_CONTROL(client, CLSET_WAITCHAN, "newnfsreq"); 263 if (nmp != NULL) { 264 if ((nmp->nm_flag & NFSMNT_INT)) 265 CLNT_CONTROL(client, CLSET_INTERRUPTIBLE, &one); 266 if ((nmp->nm_flag & NFSMNT_RESVPORT)) 267 CLNT_CONTROL(client, CLSET_PRIVPORT, &one); 268 if (NFSHASSOFT(nmp)) { 269 if (nmp->nm_sotype == SOCK_DGRAM) 270 /* 271 * For UDP, the large timeout for a reconnect 272 * will be set to "nm_retry * nm_timeo / 2", so 273 * we only want to do 2 reconnect timeout 274 * retries. 275 */ 276 retries = 2; 277 else 278 retries = nmp->nm_retry; 279 } else 280 retries = INT_MAX; 281 if (NFSHASNFSV4N(nmp)) { 282 /* 283 * Make sure the nfscbd_pool doesn't get destroyed 284 * while doing this. 285 */ 286 NFSD_LOCK(); 287 if (nfs_numnfscbd > 0) { 288 nfs_numnfscbd++; 289 NFSD_UNLOCK(); 290 xprt = svc_vc_create_backchannel(nfscbd_pool); 291 CLNT_CONTROL(client, CLSET_BACKCHANNEL, xprt); 292 NFSD_LOCK(); 293 nfs_numnfscbd--; 294 if (nfs_numnfscbd == 0) 295 wakeup(&nfs_numnfscbd); 296 } 297 NFSD_UNLOCK(); 298 } 299 } else { 300 /* 301 * Three cases: 302 * - Null RPC callback to client 303 * - Non-Null RPC callback to client, wait a little longer 304 * - upcalls to nfsuserd and gssd (clp == NULL) 305 */ 306 if (callback_retry_mult == 0) { 307 retries = NFSV4_UPCALLRETRY; 308 CLNT_CONTROL(client, CLSET_PRIVPORT, &one); 309 } else { 310 retries = NFSV4_CALLBACKRETRY * callback_retry_mult; 311 } 312 } 313 CLNT_CONTROL(client, CLSET_RETRIES, &retries); 314 315 if (nmp != NULL) { 316 /* 317 * For UDP, there are 2 timeouts: 318 * - CLSET_RETRY_TIMEOUT sets the initial timeout for the timer 319 * that does a retransmit of an RPC request using the same 320 * socket and xid. This is what you normally want to do, 321 * since NFS servers depend on "same xid" for their 322 * Duplicate Request Cache. 323 * - timeout specified in CLNT_CALL_MBUF(), which specifies when 324 * retransmits on the same socket should fail and a fresh 325 * socket created. Each of these timeouts counts as one 326 * CLSET_RETRIES as set above. 327 * Set the initial retransmit timeout for UDP. This timeout 328 * doesn't exist for TCP and the following call just fails, 329 * which is ok. 330 */ 331 timo.tv_sec = nmp->nm_timeo / NFS_HZ; 332 timo.tv_usec = (nmp->nm_timeo % NFS_HZ) * 1000000 / NFS_HZ; 333 CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, &timo); 334 } 335 336 mtx_lock(&nrp->nr_mtx); 337 if (nrp->nr_client != NULL) { 338 mtx_unlock(&nrp->nr_mtx); 339 /* 340 * Someone else already connected. 341 */ 342 CLNT_RELEASE(client); 343 } else { 344 nrp->nr_client = client; 345 /* 346 * Protocols that do not require connections may be optionally 347 * left unconnected for servers that reply from a port other 348 * than NFS_PORT. 349 */ 350 if (nmp == NULL || (nmp->nm_flag & NFSMNT_NOCONN) == 0) { 351 mtx_unlock(&nrp->nr_mtx); 352 CLNT_CONTROL(client, CLSET_CONNECT, &one); 353 } else 354 mtx_unlock(&nrp->nr_mtx); 355 } 356 357 358 /* Restore current thread's credentials. */ 359 td->td_ucred = origcred; 360 361 out: 362 NFSEXITCODE(error); 363 return (error); 364 } 365 366 /* 367 * NFS disconnect. Clean up and unlink. 368 */ 369 void 370 newnfs_disconnect(struct nfssockreq *nrp) 371 { 372 CLIENT *client; 373 374 mtx_lock(&nrp->nr_mtx); 375 if (nrp->nr_client != NULL) { 376 client = nrp->nr_client; 377 nrp->nr_client = NULL; 378 mtx_unlock(&nrp->nr_mtx); 379 rpc_gss_secpurge_call(client); 380 CLNT_CLOSE(client); 381 CLNT_RELEASE(client); 382 } else { 383 mtx_unlock(&nrp->nr_mtx); 384 } 385 } 386 387 static AUTH * 388 nfs_getauth(struct nfssockreq *nrp, int secflavour, char *clnt_principal, 389 char *srv_principal, gss_OID mech_oid, struct ucred *cred) 390 { 391 rpc_gss_service_t svc; 392 AUTH *auth; 393 394 switch (secflavour) { 395 case RPCSEC_GSS_KRB5: 396 case RPCSEC_GSS_KRB5I: 397 case RPCSEC_GSS_KRB5P: 398 if (!mech_oid) { 399 if (!rpc_gss_mech_to_oid_call("kerberosv5", &mech_oid)) 400 return (NULL); 401 } 402 if (secflavour == RPCSEC_GSS_KRB5) 403 svc = rpc_gss_svc_none; 404 else if (secflavour == RPCSEC_GSS_KRB5I) 405 svc = rpc_gss_svc_integrity; 406 else 407 svc = rpc_gss_svc_privacy; 408 409 if (clnt_principal == NULL) 410 auth = rpc_gss_secfind_call(nrp->nr_client, cred, 411 srv_principal, mech_oid, svc); 412 else { 413 auth = rpc_gss_seccreate_call(nrp->nr_client, cred, 414 clnt_principal, srv_principal, "kerberosv5", 415 svc, NULL, NULL, NULL); 416 return (auth); 417 } 418 if (auth != NULL) 419 return (auth); 420 /* fallthrough */ 421 case AUTH_SYS: 422 default: 423 return (authunix_create(cred)); 424 425 } 426 } 427 428 /* 429 * Callback from the RPC code to generate up/down notifications. 430 */ 431 432 struct nfs_feedback_arg { 433 struct nfsmount *nf_mount; 434 int nf_lastmsg; /* last tprintf */ 435 int nf_tprintfmsg; 436 struct thread *nf_td; 437 }; 438 439 static void 440 nfs_feedback(int type, int proc, void *arg) 441 { 442 struct nfs_feedback_arg *nf = (struct nfs_feedback_arg *) arg; 443 struct nfsmount *nmp = nf->nf_mount; 444 time_t now; 445 446 switch (type) { 447 case FEEDBACK_REXMIT2: 448 case FEEDBACK_RECONNECT: 449 now = NFSD_MONOSEC; 450 if (nf->nf_lastmsg + nmp->nm_tprintf_delay < now) { 451 nfs_down(nmp, nf->nf_td, 452 "not responding", 0, NFSSTA_TIMEO); 453 nf->nf_tprintfmsg = TRUE; 454 nf->nf_lastmsg = now; 455 } 456 break; 457 458 case FEEDBACK_OK: 459 nfs_up(nf->nf_mount, nf->nf_td, 460 "is alive again", NFSSTA_TIMEO, nf->nf_tprintfmsg); 461 break; 462 } 463 } 464 465 /* 466 * newnfs_request - goes something like this 467 * - does the rpc by calling the krpc layer 468 * - break down rpc header and return with nfs reply 469 * nb: always frees up nd_mreq mbuf list 470 */ 471 int 472 newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, 473 struct nfsclient *clp, struct nfssockreq *nrp, vnode_t vp, 474 struct thread *td, struct ucred *cred, u_int32_t prog, u_int32_t vers, 475 u_char *retsum, int toplevel, u_int64_t *xidp, struct nfsclsession *sep) 476 { 477 u_int32_t retseq, retval, *tl; 478 time_t waituntil; 479 int i = 0, j = 0, opcnt, set_sigset = 0, slot; 480 int trycnt, error = 0, usegssname = 0, secflavour = AUTH_SYS; 481 int freeslot, timeo; 482 u_int16_t procnum; 483 u_int trylater_delay = 1; 484 struct nfs_feedback_arg nf; 485 struct timeval timo; 486 AUTH *auth; 487 struct rpc_callextra ext; 488 enum clnt_stat stat; 489 struct nfsreq *rep = NULL; 490 char *srv_principal = NULL, *clnt_principal = NULL; 491 sigset_t oldset; 492 struct ucred *authcred; 493 494 if (xidp != NULL) 495 *xidp = 0; 496 /* Reject requests while attempting a forced unmount. */ 497 if (nmp != NULL && (nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF)) { 498 m_freem(nd->nd_mreq); 499 return (ESTALE); 500 } 501 502 /* 503 * Set authcred, which is used to acquire RPC credentials to 504 * the cred argument, by default. The crhold() should not be 505 * necessary, but will ensure that some future code change 506 * doesn't result in the credential being free'd prematurely. 507 */ 508 authcred = crhold(cred); 509 510 /* For client side interruptible mounts, mask off the signals. */ 511 if (nmp != NULL && td != NULL && NFSHASINT(nmp)) { 512 newnfs_set_sigmask(td, &oldset); 513 set_sigset = 1; 514 } 515 516 /* 517 * XXX if not already connected call nfs_connect now. Longer 518 * term, change nfs_mount to call nfs_connect unconditionally 519 * and let clnt_reconnect_create handle reconnects. 520 */ 521 if (nrp->nr_client == NULL) 522 newnfs_connect(nmp, nrp, cred, td, 0); 523 524 /* 525 * For a client side mount, nmp is != NULL and clp == NULL. For 526 * server calls (callbacks or upcalls), nmp == NULL. 527 */ 528 if (clp != NULL) { 529 NFSLOCKSTATE(); 530 if ((clp->lc_flags & LCL_GSS) && nfsrv_gsscallbackson) { 531 secflavour = RPCSEC_GSS_KRB5; 532 if (nd->nd_procnum != NFSPROC_NULL) { 533 if (clp->lc_flags & LCL_GSSINTEGRITY) 534 secflavour = RPCSEC_GSS_KRB5I; 535 else if (clp->lc_flags & LCL_GSSPRIVACY) 536 secflavour = RPCSEC_GSS_KRB5P; 537 } 538 } 539 NFSUNLOCKSTATE(); 540 } else if (nmp != NULL && NFSHASKERB(nmp) && 541 nd->nd_procnum != NFSPROC_NULL) { 542 if (NFSHASALLGSSNAME(nmp) && nmp->nm_krbnamelen > 0) 543 nd->nd_flag |= ND_USEGSSNAME; 544 if ((nd->nd_flag & ND_USEGSSNAME) != 0) { 545 /* 546 * If there is a client side host based credential, 547 * use that, otherwise use the system uid, if set. 548 * The system uid is in the nmp->nm_sockreq.nr_cred 549 * credentials. 550 */ 551 if (nmp->nm_krbnamelen > 0) { 552 usegssname = 1; 553 clnt_principal = nmp->nm_krbname; 554 } else if (nmp->nm_uid != (uid_t)-1) { 555 KASSERT(nmp->nm_sockreq.nr_cred != NULL, 556 ("newnfs_request: NULL nr_cred")); 557 crfree(authcred); 558 authcred = crhold(nmp->nm_sockreq.nr_cred); 559 } 560 } else if (nmp->nm_krbnamelen == 0 && 561 nmp->nm_uid != (uid_t)-1 && cred->cr_uid == (uid_t)0) { 562 /* 563 * If there is no host based principal name and 564 * the system uid is set and this is root, use the 565 * system uid, since root won't have user 566 * credentials in a credentials cache file. 567 * The system uid is in the nmp->nm_sockreq.nr_cred 568 * credentials. 569 */ 570 KASSERT(nmp->nm_sockreq.nr_cred != NULL, 571 ("newnfs_request: NULL nr_cred")); 572 crfree(authcred); 573 authcred = crhold(nmp->nm_sockreq.nr_cred); 574 } 575 if (NFSHASINTEGRITY(nmp)) 576 secflavour = RPCSEC_GSS_KRB5I; 577 else if (NFSHASPRIVACY(nmp)) 578 secflavour = RPCSEC_GSS_KRB5P; 579 else 580 secflavour = RPCSEC_GSS_KRB5; 581 srv_principal = NFSMNT_SRVKRBNAME(nmp); 582 } else if (nmp != NULL && !NFSHASKERB(nmp) && 583 nd->nd_procnum != NFSPROC_NULL && 584 (nd->nd_flag & ND_USEGSSNAME) != 0) { 585 /* 586 * Use the uid that did the mount when the RPC is doing 587 * NFSv4 system operations, as indicated by the 588 * ND_USEGSSNAME flag, for the AUTH_SYS case. 589 * The credentials in nm_sockreq.nr_cred were used for the 590 * mount. 591 */ 592 KASSERT(nmp->nm_sockreq.nr_cred != NULL, 593 ("newnfs_request: NULL nr_cred")); 594 crfree(authcred); 595 authcred = crhold(nmp->nm_sockreq.nr_cred); 596 } 597 598 if (nmp != NULL) { 599 bzero(&nf, sizeof(struct nfs_feedback_arg)); 600 nf.nf_mount = nmp; 601 nf.nf_td = td; 602 nf.nf_lastmsg = NFSD_MONOSEC - 603 ((nmp->nm_tprintf_delay)-(nmp->nm_tprintf_initial_delay)); 604 } 605 606 if (nd->nd_procnum == NFSPROC_NULL) 607 auth = authnone_create(); 608 else if (usegssname) { 609 /* 610 * For this case, the authenticator is held in the 611 * nfssockreq structure, so don't release the reference count 612 * held on it. --> Don't AUTH_DESTROY() it in this function. 613 */ 614 if (nrp->nr_auth == NULL) 615 nrp->nr_auth = nfs_getauth(nrp, secflavour, 616 clnt_principal, srv_principal, NULL, authcred); 617 else 618 rpc_gss_refresh_auth_call(nrp->nr_auth); 619 auth = nrp->nr_auth; 620 } else 621 auth = nfs_getauth(nrp, secflavour, NULL, 622 srv_principal, NULL, authcred); 623 crfree(authcred); 624 if (auth == NULL) { 625 m_freem(nd->nd_mreq); 626 if (set_sigset) 627 newnfs_restore_sigmask(td, &oldset); 628 return (EACCES); 629 } 630 bzero(&ext, sizeof(ext)); 631 ext.rc_auth = auth; 632 if (nmp != NULL) { 633 ext.rc_feedback = nfs_feedback; 634 ext.rc_feedback_arg = &nf; 635 } 636 637 procnum = nd->nd_procnum; 638 if ((nd->nd_flag & ND_NFSV4) && 639 nd->nd_procnum != NFSPROC_NULL && 640 nd->nd_procnum != NFSV4PROC_CBCOMPOUND) 641 procnum = NFSV4PROC_COMPOUND; 642 643 if (nmp != NULL) { 644 NFSINCRGLOBAL(newnfsstats.rpcrequests); 645 646 /* Map the procnum to the old NFSv2 one, as required. */ 647 if ((nd->nd_flag & ND_NFSV2) != 0) { 648 if (nd->nd_procnum < NFS_V3NPROCS) 649 procnum = nfsv2_procid[nd->nd_procnum]; 650 else 651 procnum = NFSV2PROC_NOOP; 652 } 653 654 /* 655 * Now only used for the R_DONTRECOVER case, but until that is 656 * supported within the krpc code, I need to keep a queue of 657 * outstanding RPCs for nfsv4 client requests. 658 */ 659 if ((nd->nd_flag & ND_NFSV4) && procnum == NFSV4PROC_COMPOUND) 660 MALLOC(rep, struct nfsreq *, sizeof(struct nfsreq), 661 M_NFSDREQ, M_WAITOK); 662 #ifdef KDTRACE_HOOKS 663 if (dtrace_nfscl_nfs234_start_probe != NULL) { 664 uint32_t probe_id; 665 int probe_procnum; 666 667 if (nd->nd_flag & ND_NFSV4) { 668 probe_id = 669 nfscl_nfs4_start_probes[nd->nd_procnum]; 670 probe_procnum = nd->nd_procnum; 671 } else if (nd->nd_flag & ND_NFSV3) { 672 probe_id = nfscl_nfs3_start_probes[procnum]; 673 probe_procnum = procnum; 674 } else { 675 probe_id = 676 nfscl_nfs2_start_probes[nd->nd_procnum]; 677 probe_procnum = procnum; 678 } 679 if (probe_id != 0) 680 (dtrace_nfscl_nfs234_start_probe) 681 (probe_id, vp, nd->nd_mreq, cred, 682 probe_procnum); 683 } 684 #endif 685 } 686 trycnt = 0; 687 freeslot = -1; /* Set to slot that needs to be free'd */ 688 tryagain: 689 slot = -1; /* Slot that needs a sequence# increment. */ 690 /* 691 * This timeout specifies when a new socket should be created, 692 * along with new xid values. For UDP, this should be done 693 * infrequently, since retransmits of RPC requests should normally 694 * use the same xid. 695 */ 696 if (nmp == NULL) { 697 timo.tv_usec = 0; 698 if (clp == NULL) 699 timo.tv_sec = NFSV4_UPCALLTIMEO; 700 else 701 timo.tv_sec = NFSV4_CALLBACKTIMEO; 702 } else { 703 if (nrp->nr_sotype != SOCK_DGRAM) { 704 timo.tv_usec = 0; 705 if ((nmp->nm_flag & NFSMNT_NFSV4)) 706 timo.tv_sec = INT_MAX; 707 else 708 timo.tv_sec = NFS_TCPTIMEO; 709 } else { 710 if (NFSHASSOFT(nmp)) { 711 /* 712 * CLSET_RETRIES is set to 2, so this should be 713 * half of the total timeout required. 714 */ 715 timeo = nmp->nm_retry * nmp->nm_timeo / 2; 716 if (timeo < 1) 717 timeo = 1; 718 timo.tv_sec = timeo / NFS_HZ; 719 timo.tv_usec = (timeo % NFS_HZ) * 1000000 / 720 NFS_HZ; 721 } else { 722 /* For UDP hard mounts, use a large value. */ 723 timo.tv_sec = NFS_MAXTIMEO / NFS_HZ; 724 timo.tv_usec = 0; 725 } 726 } 727 728 if (rep != NULL) { 729 rep->r_flags = 0; 730 rep->r_nmp = nmp; 731 /* 732 * Chain request into list of outstanding requests. 733 */ 734 NFSLOCKREQ(); 735 TAILQ_INSERT_TAIL(&nfsd_reqq, rep, r_chain); 736 NFSUNLOCKREQ(); 737 } 738 } 739 740 nd->nd_mrep = NULL; 741 stat = CLNT_CALL_MBUF(nrp->nr_client, &ext, procnum, nd->nd_mreq, 742 &nd->nd_mrep, timo); 743 744 if (rep != NULL) { 745 /* 746 * RPC done, unlink the request. 747 */ 748 NFSLOCKREQ(); 749 TAILQ_REMOVE(&nfsd_reqq, rep, r_chain); 750 NFSUNLOCKREQ(); 751 } 752 753 /* 754 * If there was a successful reply and a tprintf msg. 755 * tprintf a response. 756 */ 757 if (stat == RPC_SUCCESS) { 758 error = 0; 759 } else if (stat == RPC_TIMEDOUT) { 760 NFSINCRGLOBAL(newnfsstats.rpctimeouts); 761 error = ETIMEDOUT; 762 } else if (stat == RPC_VERSMISMATCH) { 763 NFSINCRGLOBAL(newnfsstats.rpcinvalid); 764 error = EOPNOTSUPP; 765 } else if (stat == RPC_PROGVERSMISMATCH) { 766 NFSINCRGLOBAL(newnfsstats.rpcinvalid); 767 error = EPROTONOSUPPORT; 768 } else if (stat == RPC_INTR) { 769 error = EINTR; 770 } else { 771 NFSINCRGLOBAL(newnfsstats.rpcinvalid); 772 error = EACCES; 773 } 774 if (error) { 775 m_freem(nd->nd_mreq); 776 if (usegssname == 0) 777 AUTH_DESTROY(auth); 778 if (rep != NULL) 779 FREE((caddr_t)rep, M_NFSDREQ); 780 if (set_sigset) 781 newnfs_restore_sigmask(td, &oldset); 782 return (error); 783 } 784 785 KASSERT(nd->nd_mrep != NULL, ("mrep shouldn't be NULL if no error\n")); 786 787 /* 788 * Search for any mbufs that are not a multiple of 4 bytes long 789 * or with m_data not longword aligned. 790 * These could cause pointer alignment problems, so copy them to 791 * well aligned mbufs. 792 */ 793 newnfs_realign(&nd->nd_mrep, M_WAITOK); 794 nd->nd_md = nd->nd_mrep; 795 nd->nd_dpos = NFSMTOD(nd->nd_md, caddr_t); 796 nd->nd_repstat = 0; 797 if (nd->nd_procnum != NFSPROC_NULL) { 798 /* If sep == NULL, set it to the default in nmp. */ 799 if (sep == NULL && nmp != NULL) 800 sep = NFSMNT_MDSSESSION(nmp); 801 /* 802 * and now the actual NFS xdr. 803 */ 804 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); 805 nd->nd_repstat = fxdr_unsigned(u_int32_t, *tl); 806 if (nd->nd_repstat >= 10000) 807 NFSCL_DEBUG(1, "proc=%d reps=%d\n", (int)nd->nd_procnum, 808 (int)nd->nd_repstat); 809 810 /* 811 * Get rid of the tag, return count and SEQUENCE result for 812 * NFSv4. 813 */ 814 if ((nd->nd_flag & ND_NFSV4) != 0) { 815 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); 816 i = fxdr_unsigned(int, *tl); 817 error = nfsm_advance(nd, NFSM_RNDUP(i), -1); 818 if (error) 819 goto nfsmout; 820 NFSM_DISSECT(tl, u_int32_t *, 3 * NFSX_UNSIGNED); 821 opcnt = fxdr_unsigned(int, *tl++); 822 i = fxdr_unsigned(int, *tl++); 823 j = fxdr_unsigned(int, *tl); 824 if (j >= 10000) 825 NFSCL_DEBUG(1, "fop=%d fst=%d\n", i, j); 826 /* 827 * If the first op is Sequence, free up the slot. 828 */ 829 if (nmp != NULL && i == NFSV4OP_SEQUENCE && j != 0) 830 NFSCL_DEBUG(1, "failed seq=%d\n", j); 831 if (nmp != NULL && i == NFSV4OP_SEQUENCE && j == 0) { 832 NFSM_DISSECT(tl, uint32_t *, NFSX_V4SESSIONID + 833 5 * NFSX_UNSIGNED); 834 mtx_lock(&sep->nfsess_mtx); 835 tl += NFSX_V4SESSIONID / NFSX_UNSIGNED; 836 retseq = fxdr_unsigned(uint32_t, *tl++); 837 slot = fxdr_unsigned(int, *tl++); 838 freeslot = slot; 839 if (retseq != sep->nfsess_slotseq[slot]) 840 printf("retseq diff 0x%x\n", retseq); 841 retval = fxdr_unsigned(uint32_t, *++tl); 842 if ((retval + 1) < sep->nfsess_foreslots) 843 sep->nfsess_foreslots = (retval + 1); 844 else if ((retval + 1) > sep->nfsess_foreslots) 845 sep->nfsess_foreslots = (retval < 64) ? 846 (retval + 1) : 64; 847 mtx_unlock(&sep->nfsess_mtx); 848 849 /* Grab the op and status for the next one. */ 850 if (opcnt > 1) { 851 NFSM_DISSECT(tl, uint32_t *, 852 2 * NFSX_UNSIGNED); 853 i = fxdr_unsigned(int, *tl++); 854 j = fxdr_unsigned(int, *tl); 855 } 856 } 857 } 858 if (nd->nd_repstat != 0) { 859 if (((nd->nd_repstat == NFSERR_DELAY || 860 nd->nd_repstat == NFSERR_GRACE) && 861 (nd->nd_flag & ND_NFSV4) && 862 nd->nd_procnum != NFSPROC_DELEGRETURN && 863 nd->nd_procnum != NFSPROC_SETATTR && 864 nd->nd_procnum != NFSPROC_READ && 865 nd->nd_procnum != NFSPROC_READDS && 866 nd->nd_procnum != NFSPROC_WRITE && 867 nd->nd_procnum != NFSPROC_WRITEDS && 868 nd->nd_procnum != NFSPROC_OPEN && 869 nd->nd_procnum != NFSPROC_CREATE && 870 nd->nd_procnum != NFSPROC_OPENCONFIRM && 871 nd->nd_procnum != NFSPROC_OPENDOWNGRADE && 872 nd->nd_procnum != NFSPROC_CLOSE && 873 nd->nd_procnum != NFSPROC_LOCK && 874 nd->nd_procnum != NFSPROC_LOCKU) || 875 (nd->nd_repstat == NFSERR_DELAY && 876 (nd->nd_flag & ND_NFSV4) == 0) || 877 nd->nd_repstat == NFSERR_RESOURCE) { 878 if (trylater_delay > NFS_TRYLATERDEL) 879 trylater_delay = NFS_TRYLATERDEL; 880 waituntil = NFSD_MONOSEC + trylater_delay; 881 while (NFSD_MONOSEC < waituntil) 882 (void) nfs_catnap(PZERO, 0, "nfstry"); 883 trylater_delay *= 2; 884 if (slot != -1) { 885 mtx_lock(&sep->nfsess_mtx); 886 sep->nfsess_slotseq[slot]++; 887 *nd->nd_slotseq = txdr_unsigned( 888 sep->nfsess_slotseq[slot]); 889 mtx_unlock(&sep->nfsess_mtx); 890 } 891 m_freem(nd->nd_mrep); 892 nd->nd_mrep = NULL; 893 goto tryagain; 894 } 895 896 /* 897 * If the File Handle was stale, invalidate the 898 * lookup cache, just in case. 899 * (vp != NULL implies a client side call) 900 */ 901 if (nd->nd_repstat == ESTALE && vp != NULL) { 902 cache_purge(vp); 903 if (ncl_call_invalcaches != NULL) 904 (*ncl_call_invalcaches)(vp); 905 } 906 } 907 if ((nd->nd_flag & ND_NFSV4) != 0) { 908 /* Free the slot, as required. */ 909 if (freeslot != -1) 910 nfsv4_freeslot(sep, freeslot); 911 /* 912 * If this op is Putfh, throw its results away. 913 */ 914 if (j >= 10000) 915 NFSCL_DEBUG(1, "nop=%d nst=%d\n", i, j); 916 if (nmp != NULL && i == NFSV4OP_PUTFH && j == 0) { 917 NFSM_DISSECT(tl,u_int32_t *,2 * NFSX_UNSIGNED); 918 i = fxdr_unsigned(int, *tl++); 919 j = fxdr_unsigned(int, *tl); 920 if (j >= 10000) 921 NFSCL_DEBUG(1, "n2op=%d n2st=%d\n", i, 922 j); 923 /* 924 * All Compounds that do an Op that must 925 * be in sequence consist of NFSV4OP_PUTFH 926 * followed by one of these. As such, we 927 * can determine if the seqid# should be 928 * incremented, here. 929 */ 930 if ((i == NFSV4OP_OPEN || 931 i == NFSV4OP_OPENCONFIRM || 932 i == NFSV4OP_OPENDOWNGRADE || 933 i == NFSV4OP_CLOSE || 934 i == NFSV4OP_LOCK || 935 i == NFSV4OP_LOCKU) && 936 (j == 0 || 937 (j != NFSERR_STALECLIENTID && 938 j != NFSERR_STALESTATEID && 939 j != NFSERR_BADSTATEID && 940 j != NFSERR_BADSEQID && 941 j != NFSERR_BADXDR && 942 j != NFSERR_RESOURCE && 943 j != NFSERR_NOFILEHANDLE))) 944 nd->nd_flag |= ND_INCRSEQID; 945 } 946 /* 947 * If this op's status is non-zero, mark 948 * that there is no more data to process. 949 */ 950 if (j) 951 nd->nd_flag |= ND_NOMOREDATA; 952 953 /* 954 * If R_DONTRECOVER is set, replace the stale error 955 * reply, so that recovery isn't initiated. 956 */ 957 if ((nd->nd_repstat == NFSERR_STALECLIENTID || 958 nd->nd_repstat == NFSERR_BADSESSION || 959 nd->nd_repstat == NFSERR_STALESTATEID) && 960 rep != NULL && (rep->r_flags & R_DONTRECOVER)) 961 nd->nd_repstat = NFSERR_STALEDONTRECOVER; 962 } 963 } 964 965 #ifdef KDTRACE_HOOKS 966 if (nmp != NULL && dtrace_nfscl_nfs234_done_probe != NULL) { 967 uint32_t probe_id; 968 int probe_procnum; 969 970 if (nd->nd_flag & ND_NFSV4) { 971 probe_id = nfscl_nfs4_done_probes[nd->nd_procnum]; 972 probe_procnum = nd->nd_procnum; 973 } else if (nd->nd_flag & ND_NFSV3) { 974 probe_id = nfscl_nfs3_done_probes[procnum]; 975 probe_procnum = procnum; 976 } else { 977 probe_id = nfscl_nfs2_done_probes[nd->nd_procnum]; 978 probe_procnum = procnum; 979 } 980 if (probe_id != 0) 981 (dtrace_nfscl_nfs234_done_probe)(probe_id, vp, 982 nd->nd_mreq, cred, probe_procnum, 0); 983 } 984 #endif 985 986 m_freem(nd->nd_mreq); 987 if (usegssname == 0) 988 AUTH_DESTROY(auth); 989 if (rep != NULL) 990 FREE((caddr_t)rep, M_NFSDREQ); 991 if (set_sigset) 992 newnfs_restore_sigmask(td, &oldset); 993 return (0); 994 nfsmout: 995 mbuf_freem(nd->nd_mrep); 996 mbuf_freem(nd->nd_mreq); 997 if (usegssname == 0) 998 AUTH_DESTROY(auth); 999 if (rep != NULL) 1000 FREE((caddr_t)rep, M_NFSDREQ); 1001 if (set_sigset) 1002 newnfs_restore_sigmask(td, &oldset); 1003 return (error); 1004 } 1005 1006 /* 1007 * Mark all of an nfs mount's outstanding requests with R_SOFTTERM and 1008 * wait for all requests to complete. This is used by forced unmounts 1009 * to terminate any outstanding RPCs. 1010 */ 1011 int 1012 newnfs_nmcancelreqs(struct nfsmount *nmp) 1013 { 1014 1015 if (nmp->nm_sockreq.nr_client != NULL) 1016 CLNT_CLOSE(nmp->nm_sockreq.nr_client); 1017 return (0); 1018 } 1019 1020 /* 1021 * Any signal that can interrupt an NFS operation in an intr mount 1022 * should be added to this set. SIGSTOP and SIGKILL cannot be masked. 1023 */ 1024 int newnfs_sig_set[] = { 1025 SIGINT, 1026 SIGTERM, 1027 SIGHUP, 1028 SIGKILL, 1029 SIGQUIT 1030 }; 1031 1032 /* 1033 * Check to see if one of the signals in our subset is pending on 1034 * the process (in an intr mount). 1035 */ 1036 static int 1037 nfs_sig_pending(sigset_t set) 1038 { 1039 int i; 1040 1041 for (i = 0 ; i < sizeof(newnfs_sig_set)/sizeof(int) ; i++) 1042 if (SIGISMEMBER(set, newnfs_sig_set[i])) 1043 return (1); 1044 return (0); 1045 } 1046 1047 /* 1048 * The set/restore sigmask functions are used to (temporarily) overwrite 1049 * the thread td_sigmask during an RPC call (for example). These are also 1050 * used in other places in the NFS client that might tsleep(). 1051 */ 1052 void 1053 newnfs_set_sigmask(struct thread *td, sigset_t *oldset) 1054 { 1055 sigset_t newset; 1056 int i; 1057 struct proc *p; 1058 1059 SIGFILLSET(newset); 1060 if (td == NULL) 1061 td = curthread; /* XXX */ 1062 p = td->td_proc; 1063 /* Remove the NFS set of signals from newset */ 1064 PROC_LOCK(p); 1065 mtx_lock(&p->p_sigacts->ps_mtx); 1066 for (i = 0 ; i < sizeof(newnfs_sig_set)/sizeof(int) ; i++) { 1067 /* 1068 * But make sure we leave the ones already masked 1069 * by the process, ie. remove the signal from the 1070 * temporary signalmask only if it wasn't already 1071 * in p_sigmask. 1072 */ 1073 if (!SIGISMEMBER(td->td_sigmask, newnfs_sig_set[i]) && 1074 !SIGISMEMBER(p->p_sigacts->ps_sigignore, newnfs_sig_set[i])) 1075 SIGDELSET(newset, newnfs_sig_set[i]); 1076 } 1077 mtx_unlock(&p->p_sigacts->ps_mtx); 1078 kern_sigprocmask(td, SIG_SETMASK, &newset, oldset, 1079 SIGPROCMASK_PROC_LOCKED); 1080 PROC_UNLOCK(p); 1081 } 1082 1083 void 1084 newnfs_restore_sigmask(struct thread *td, sigset_t *set) 1085 { 1086 if (td == NULL) 1087 td = curthread; /* XXX */ 1088 kern_sigprocmask(td, SIG_SETMASK, set, NULL, 0); 1089 } 1090 1091 /* 1092 * NFS wrapper to msleep(), that shoves a new p_sigmask and restores the 1093 * old one after msleep() returns. 1094 */ 1095 int 1096 newnfs_msleep(struct thread *td, void *ident, struct mtx *mtx, int priority, char *wmesg, int timo) 1097 { 1098 sigset_t oldset; 1099 int error; 1100 struct proc *p; 1101 1102 if ((priority & PCATCH) == 0) 1103 return msleep(ident, mtx, priority, wmesg, timo); 1104 if (td == NULL) 1105 td = curthread; /* XXX */ 1106 newnfs_set_sigmask(td, &oldset); 1107 error = msleep(ident, mtx, priority, wmesg, timo); 1108 newnfs_restore_sigmask(td, &oldset); 1109 p = td->td_proc; 1110 return (error); 1111 } 1112 1113 /* 1114 * Test for a termination condition pending on the process. 1115 * This is used for NFSMNT_INT mounts. 1116 */ 1117 int 1118 newnfs_sigintr(struct nfsmount *nmp, struct thread *td) 1119 { 1120 struct proc *p; 1121 sigset_t tmpset; 1122 1123 /* Terminate all requests while attempting a forced unmount. */ 1124 if (nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF) 1125 return (EIO); 1126 if (!(nmp->nm_flag & NFSMNT_INT)) 1127 return (0); 1128 if (td == NULL) 1129 return (0); 1130 p = td->td_proc; 1131 PROC_LOCK(p); 1132 tmpset = p->p_siglist; 1133 SIGSETOR(tmpset, td->td_siglist); 1134 SIGSETNAND(tmpset, td->td_sigmask); 1135 mtx_lock(&p->p_sigacts->ps_mtx); 1136 SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore); 1137 mtx_unlock(&p->p_sigacts->ps_mtx); 1138 if ((SIGNOTEMPTY(p->p_siglist) || SIGNOTEMPTY(td->td_siglist)) 1139 && nfs_sig_pending(tmpset)) { 1140 PROC_UNLOCK(p); 1141 return (EINTR); 1142 } 1143 PROC_UNLOCK(p); 1144 return (0); 1145 } 1146 1147 static int 1148 nfs_msg(struct thread *td, const char *server, const char *msg, int error) 1149 { 1150 struct proc *p; 1151 1152 p = td ? td->td_proc : NULL; 1153 if (error) { 1154 tprintf(p, LOG_INFO, "newnfs server %s: %s, error %d\n", 1155 server, msg, error); 1156 } else { 1157 tprintf(p, LOG_INFO, "newnfs server %s: %s\n", server, msg); 1158 } 1159 return (0); 1160 } 1161 1162 static void 1163 nfs_down(struct nfsmount *nmp, struct thread *td, const char *msg, 1164 int error, int flags) 1165 { 1166 if (nmp == NULL) 1167 return; 1168 mtx_lock(&nmp->nm_mtx); 1169 if ((flags & NFSSTA_TIMEO) && !(nmp->nm_state & NFSSTA_TIMEO)) { 1170 nmp->nm_state |= NFSSTA_TIMEO; 1171 mtx_unlock(&nmp->nm_mtx); 1172 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, 1173 VQ_NOTRESP, 0); 1174 } else 1175 mtx_unlock(&nmp->nm_mtx); 1176 mtx_lock(&nmp->nm_mtx); 1177 if ((flags & NFSSTA_LOCKTIMEO) && !(nmp->nm_state & NFSSTA_LOCKTIMEO)) { 1178 nmp->nm_state |= NFSSTA_LOCKTIMEO; 1179 mtx_unlock(&nmp->nm_mtx); 1180 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, 1181 VQ_NOTRESPLOCK, 0); 1182 } else 1183 mtx_unlock(&nmp->nm_mtx); 1184 nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, error); 1185 } 1186 1187 static void 1188 nfs_up(struct nfsmount *nmp, struct thread *td, const char *msg, 1189 int flags, int tprintfmsg) 1190 { 1191 if (nmp == NULL) 1192 return; 1193 if (tprintfmsg) { 1194 nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, 0); 1195 } 1196 1197 mtx_lock(&nmp->nm_mtx); 1198 if ((flags & NFSSTA_TIMEO) && (nmp->nm_state & NFSSTA_TIMEO)) { 1199 nmp->nm_state &= ~NFSSTA_TIMEO; 1200 mtx_unlock(&nmp->nm_mtx); 1201 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, 1202 VQ_NOTRESP, 1); 1203 } else 1204 mtx_unlock(&nmp->nm_mtx); 1205 1206 mtx_lock(&nmp->nm_mtx); 1207 if ((flags & NFSSTA_LOCKTIMEO) && (nmp->nm_state & NFSSTA_LOCKTIMEO)) { 1208 nmp->nm_state &= ~NFSSTA_LOCKTIMEO; 1209 mtx_unlock(&nmp->nm_mtx); 1210 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, 1211 VQ_NOTRESPLOCK, 1); 1212 } else 1213 mtx_unlock(&nmp->nm_mtx); 1214 } 1215 1216