nfs_krpc.c (195203) | nfs_krpc.c (203731) |
---|---|
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 --- 19 unchanged lines hidden (view full) --- 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95 33 */ 34 35#include <sys/cdefs.h> | 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 --- 19 unchanged lines hidden (view full) --- 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95 33 */ 34 35#include <sys/cdefs.h> |
36__FBSDID("$FreeBSD: head/sys/nfsclient/nfs_krpc.c 195203 2009-06-30 19:10:17Z dfr $"); | 36__FBSDID("$FreeBSD: head/sys/nfsclient/nfs_krpc.c 203731 2010-02-09 23:40:07Z marius $"); |
37 38/* 39 * Socket operations for use by nfs 40 */ 41 42#include "opt_inet6.h" 43#include "opt_kdtrace.h" 44#include "opt_kgssapi.h" --- 55 unchanged lines hidden (view full) --- 100SYSCTL_INT(_vfs_nfs, OID_AUTO, realign_test, CTLFLAG_RW, &nfs_realign_test, 0, 101 "Number of realign tests done"); 102SYSCTL_INT(_vfs_nfs, OID_AUTO, realign_count, CTLFLAG_RW, &nfs_realign_count, 0, 103 "Number of mbuf realignments done"); 104SYSCTL_INT(_vfs_nfs, OID_AUTO, bufpackets, CTLFLAG_RW, &nfs_bufpackets, 0, 105 "Buffer reservation size 2 < x < 64"); 106SYSCTL_INT(_vfs_nfs, OID_AUTO, reconnects, CTLFLAG_RD, &nfs_reconnects, 0, 107 "Number of times the nfs client has had to reconnect"); | 37 38/* 39 * Socket operations for use by nfs 40 */ 41 42#include "opt_inet6.h" 43#include "opt_kdtrace.h" 44#include "opt_kgssapi.h" --- 55 unchanged lines hidden (view full) --- 100SYSCTL_INT(_vfs_nfs, OID_AUTO, realign_test, CTLFLAG_RW, &nfs_realign_test, 0, 101 "Number of realign tests done"); 102SYSCTL_INT(_vfs_nfs, OID_AUTO, realign_count, CTLFLAG_RW, &nfs_realign_count, 0, 103 "Number of mbuf realignments done"); 104SYSCTL_INT(_vfs_nfs, OID_AUTO, bufpackets, CTLFLAG_RW, &nfs_bufpackets, 0, 105 "Buffer reservation size 2 < x < 64"); 106SYSCTL_INT(_vfs_nfs, OID_AUTO, reconnects, CTLFLAG_RD, &nfs_reconnects, 0, 107 "Number of times the nfs client has had to reconnect"); |
108SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs3_jukebox_delay, CTLFLAG_RW, &nfs3_jukebox_delay, 0, | 108SYSCTL_INT(_vfs_nfs, OID_AUTO, nfs3_jukebox_delay, CTLFLAG_RW, 109 &nfs3_jukebox_delay, 0, |
109 "Number of seconds to delay a retry after receiving EJUKEBOX"); | 110 "Number of seconds to delay a retry after receiving EJUKEBOX"); |
110SYSCTL_INT(_vfs_nfs, OID_AUTO, skip_wcc_data_onerr, CTLFLAG_RW, &nfs_skip_wcc_data_onerr, 0, | 111SYSCTL_INT(_vfs_nfs, OID_AUTO, skip_wcc_data_onerr, CTLFLAG_RW, 112 &nfs_skip_wcc_data_onerr, 0, |
111 "Disable weak cache consistency checking when server returns an error"); 112 113static void nfs_down(struct nfsmount *, struct thread *, const char *, 114 int, int); 115static void nfs_up(struct nfsmount *, struct thread *, const char *, 116 int, int); 117static int nfs_msg(struct thread *, const char *, const char *, int); 118 --- 36 unchanged lines hidden (view full) --- 155}; 156 157/* 158 * Choose the correct RTT timer for this NFS procedure. 159 */ 160static inline enum nfs_rto_timer_t 161nfs_rto_timer(u_int32_t procnum) 162{ | 113 "Disable weak cache consistency checking when server returns an error"); 114 115static void nfs_down(struct nfsmount *, struct thread *, const char *, 116 int, int); 117static void nfs_up(struct nfsmount *, struct thread *, const char *, 118 int, int); 119static int nfs_msg(struct thread *, const char *, const char *, int); 120 --- 36 unchanged lines hidden (view full) --- 157}; 158 159/* 160 * Choose the correct RTT timer for this NFS procedure. 161 */ 162static inline enum nfs_rto_timer_t 163nfs_rto_timer(u_int32_t procnum) 164{ |
163 return nfs_proct[procnum]; | 165 166 return (nfs_proct[procnum]); |
164} 165 166/* 167 * Initialize the RTT estimator state for a new mount point. 168 */ 169static void 170nfs_init_rtt(struct nfsmount *nmp) 171{ --- 48 unchanged lines hidden (view full) --- 220 nconf = getnetconfigent("udp"); 221 else 222 nconf = getnetconfigent("tcp"); 223 else 224 if (nmp->nm_sotype == SOCK_DGRAM) 225 nconf = getnetconfigent("udp6"); 226 else 227 nconf = getnetconfigent("tcp6"); | 167} 168 169/* 170 * Initialize the RTT estimator state for a new mount point. 171 */ 172static void 173nfs_init_rtt(struct nfsmount *nmp) 174{ --- 48 unchanged lines hidden (view full) --- 223 nconf = getnetconfigent("udp"); 224 else 225 nconf = getnetconfigent("tcp"); 226 else 227 if (nmp->nm_sotype == SOCK_DGRAM) 228 nconf = getnetconfigent("udp6"); 229 else 230 nconf = getnetconfigent("tcp6"); |
228 | 231 |
229 /* 230 * Get buffer reservation size from sysctl, but impose reasonable 231 * limits. 232 */ 233 pktscale = nfs_bufpackets; 234 if (pktscale < 2) 235 pktscale = 2; 236 if (pktscale > 64) --- 31 unchanged lines hidden (view full) --- 268 CLNT_CONTROL(client, CLSET_RETRIES, &retries); 269 270 mtx_lock(&nmp->nm_mtx); 271 if (nmp->nm_client) { 272 /* 273 * Someone else already connected. 274 */ 275 CLNT_RELEASE(client); | 232 /* 233 * Get buffer reservation size from sysctl, but impose reasonable 234 * limits. 235 */ 236 pktscale = nfs_bufpackets; 237 if (pktscale < 2) 238 pktscale = 2; 239 if (pktscale > 64) --- 31 unchanged lines hidden (view full) --- 271 CLNT_CONTROL(client, CLSET_RETRIES, &retries); 272 273 mtx_lock(&nmp->nm_mtx); 274 if (nmp->nm_client) { 275 /* 276 * Someone else already connected. 277 */ 278 CLNT_RELEASE(client); |
276 } else { | 279 } else |
277 nmp->nm_client = client; | 280 nmp->nm_client = client; |
278 } | |
279 280 /* 281 * Protocols that do not require connections may be optionally left 282 * unconnected for servers that reply from a port other than NFS_PORT. 283 */ 284 if (!(nmp->nm_flag & NFSMNT_NOCONN)) { 285 mtx_unlock(&nmp->nm_mtx); 286 CLNT_CONTROL(client, CLSET_CONNECT, &one); | 281 282 /* 283 * Protocols that do not require connections may be optionally left 284 * unconnected for servers that reply from a port other than NFS_PORT. 285 */ 286 if (!(nmp->nm_flag & NFSMNT_NOCONN)) { 287 mtx_unlock(&nmp->nm_mtx); 288 CLNT_CONTROL(client, CLSET_CONNECT, &one); |
287 } else { | 289 } else |
288 mtx_unlock(&nmp->nm_mtx); | 290 mtx_unlock(&nmp->nm_mtx); |
289 } | |
290 291 /* Restore current thread's credentials. */ 292 td->td_ucred = origcred; 293 294 mtx_lock(&nmp->nm_mtx); | 291 292 /* Restore current thread's credentials. */ 293 td->td_ucred = origcred; 294 295 mtx_lock(&nmp->nm_mtx); |
295 /* Initialize other non-zero congestion variables */ | 296 /* Initialize other non-zero congestion variables. */ |
296 nfs_init_rtt(nmp); 297 mtx_unlock(&nmp->nm_mtx); 298 return (0); 299} 300 301/* | 297 nfs_init_rtt(nmp); 298 mtx_unlock(&nmp->nm_mtx); 299 return (0); 300} 301 302/* |
302 * NFS disconnect. Clean up and unlink. | 303 * NFS disconnect. Clean up and unlink. |
303 */ 304void 305nfs_disconnect(struct nfsmount *nmp) 306{ 307 CLIENT *client; 308 309 mtx_lock(&nmp->nm_mtx); 310 if (nmp->nm_client) { 311 client = nmp->nm_client; 312 nmp->nm_client = NULL; 313 mtx_unlock(&nmp->nm_mtx); 314#ifdef KGSSAPI 315 rpc_gss_secpurge(client); 316#endif 317 CLNT_CLOSE(client); 318 CLNT_RELEASE(client); | 304 */ 305void 306nfs_disconnect(struct nfsmount *nmp) 307{ 308 CLIENT *client; 309 310 mtx_lock(&nmp->nm_mtx); 311 if (nmp->nm_client) { 312 client = nmp->nm_client; 313 nmp->nm_client = NULL; 314 mtx_unlock(&nmp->nm_mtx); 315#ifdef KGSSAPI 316 rpc_gss_secpurge(client); 317#endif 318 CLNT_CLOSE(client); 319 CLNT_RELEASE(client); |
319 } else { | 320 } else |
320 mtx_unlock(&nmp->nm_mtx); | 321 mtx_unlock(&nmp->nm_mtx); |
321 } | |
322} 323 324void 325nfs_safedisconnect(struct nfsmount *nmp) 326{ 327 328 nfs_disconnect(nmp); 329} --- 6 unchanged lines hidden (view full) --- 336 AUTH *auth; 337#endif 338 339 switch (nmp->nm_secflavor) { 340#ifdef KGSSAPI 341 case RPCSEC_GSS_KRB5: 342 case RPCSEC_GSS_KRB5I: 343 case RPCSEC_GSS_KRB5P: | 322} 323 324void 325nfs_safedisconnect(struct nfsmount *nmp) 326{ 327 328 nfs_disconnect(nmp); 329} --- 6 unchanged lines hidden (view full) --- 336 AUTH *auth; 337#endif 338 339 switch (nmp->nm_secflavor) { 340#ifdef KGSSAPI 341 case RPCSEC_GSS_KRB5: 342 case RPCSEC_GSS_KRB5I: 343 case RPCSEC_GSS_KRB5P: |
344 if (!nmp->nm_mech_oid) { | 344 if (!nmp->nm_mech_oid) |
345 if (!rpc_gss_mech_to_oid("kerberosv5", | 345 if (!rpc_gss_mech_to_oid("kerberosv5", |
346 &nmp->nm_mech_oid)) | 346 &nmp->nm_mech_oid)) |
347 return (NULL); | 347 return (NULL); |
348 } | |
349 if (nmp->nm_secflavor == RPCSEC_GSS_KRB5) 350 svc = rpc_gss_svc_none; 351 else if (nmp->nm_secflavor == RPCSEC_GSS_KRB5I) 352 svc = rpc_gss_svc_integrity; 353 else 354 svc = rpc_gss_svc_privacy; 355 auth = rpc_gss_secfind(nmp->nm_client, cred, 356 nmp->nm_principal, nmp->nm_mech_oid, svc); --- 141 unchanged lines hidden (view full) --- 498 return (ESTALE); 499 } 500 nmp = VFSTONFS(vp->v_mount); 501 bzero(&nf, sizeof(struct nfs_feedback_arg)); 502 nf.nf_mount = nmp; 503 nf.nf_td = td; 504 getmicrouptime(&now); 505 nf.nf_lastmsg = now.tv_sec - | 348 if (nmp->nm_secflavor == RPCSEC_GSS_KRB5) 349 svc = rpc_gss_svc_none; 350 else if (nmp->nm_secflavor == RPCSEC_GSS_KRB5I) 351 svc = rpc_gss_svc_integrity; 352 else 353 svc = rpc_gss_svc_privacy; 354 auth = rpc_gss_secfind(nmp->nm_client, cred, 355 nmp->nm_principal, nmp->nm_mech_oid, svc); --- 141 unchanged lines hidden (view full) --- 497 return (ESTALE); 498 } 499 nmp = VFSTONFS(vp->v_mount); 500 bzero(&nf, sizeof(struct nfs_feedback_arg)); 501 nf.nf_mount = nmp; 502 nf.nf_td = td; 503 getmicrouptime(&now); 504 nf.nf_lastmsg = now.tv_sec - |
506 ((nmp->nm_tprintf_delay) - (nmp->nm_tprintf_initial_delay)); | 505 ((nmp->nm_tprintf_delay) - (nmp->nm_tprintf_initial_delay)); |
507 508 /* | 506 507 /* |
509 * XXX if not already connected call nfs_connect now. Longer | 508 * XXX if not already connected call nfs_connect now. Longer |
510 * term, change nfs_mount to call nfs_connect unconditionally 511 * and let clnt_reconnect_create handle reconnects. 512 */ 513 if (!nmp->nm_client) 514 nfs_connect(nmp); 515 516 auth = nfs_getauth(nmp, cred); 517 if (!auth) { 518 m_freem(mreq); 519 return (EACCES); 520 } 521 bzero(&ext, sizeof(ext)); 522 ext.rc_auth = auth; 523 524 ext.rc_feedback = nfs_feedback; 525 ext.rc_feedback_arg = &nf; 526 527 /* 528 * Use a conservative timeout for RPCs other than getattr, | 509 * term, change nfs_mount to call nfs_connect unconditionally 510 * and let clnt_reconnect_create handle reconnects. 511 */ 512 if (!nmp->nm_client) 513 nfs_connect(nmp); 514 515 auth = nfs_getauth(nmp, cred); 516 if (!auth) { 517 m_freem(mreq); 518 return (EACCES); 519 } 520 bzero(&ext, sizeof(ext)); 521 ext.rc_auth = auth; 522 523 ext.rc_feedback = nfs_feedback; 524 ext.rc_feedback_arg = &nf; 525 526 /* 527 * Use a conservative timeout for RPCs other than getattr, |
529 * lookup, read or write. The justification for doing "other" | 528 * lookup, read or write. The justification for doing "other" |
530 * this way is that these RPCs happen so infrequently that 531 * timer est. would probably be stale. Also, since many of 532 * these RPCs are non-idempotent, a conservative timeout is 533 * desired. 534 */ 535 timer = nfs_rto_timer(procnum); | 529 * this way is that these RPCs happen so infrequently that 530 * timer est. would probably be stale. Also, since many of 531 * these RPCs are non-idempotent, a conservative timeout is 532 * desired. 533 */ 534 timer = nfs_rto_timer(procnum); |
536 if (timer != NFS_DEFAULT_TIMER) { | 535 if (timer != NFS_DEFAULT_TIMER) |
537 ext.rc_timers = &nmp->nm_timers[timer - 1]; | 536 ext.rc_timers = &nmp->nm_timers[timer - 1]; |
538 } else { | 537 else |
539 ext.rc_timers = NULL; | 538 ext.rc_timers = NULL; |
540 } | |
541 542#ifdef KDTRACE_HOOKS 543 if (dtrace_nfsclient_nfs23_start_probe != NULL) { 544 uint32_t probe_id; 545 int probe_procnum; 546 547 if (nmp->nm_flag & NFSMNT_NFSV3) { 548 probe_id = nfsclient_nfs3_start_probes[procnum]; --- 16 unchanged lines hidden (view full) --- 565 stat = CLNT_CALL_MBUF(nmp->nm_client, &ext, 566 (nmp->nm_flag & NFSMNT_NFSV3) ? procnum : nfsv2_procid[procnum], 567 mreq, &mrep, timo); 568 569 /* 570 * If there was a successful reply and a tprintf msg. 571 * tprintf a response. 572 */ | 539 540#ifdef KDTRACE_HOOKS 541 if (dtrace_nfsclient_nfs23_start_probe != NULL) { 542 uint32_t probe_id; 543 int probe_procnum; 544 545 if (nmp->nm_flag & NFSMNT_NFSV3) { 546 probe_id = nfsclient_nfs3_start_probes[procnum]; --- 16 unchanged lines hidden (view full) --- 563 stat = CLNT_CALL_MBUF(nmp->nm_client, &ext, 564 (nmp->nm_flag & NFSMNT_NFSV3) ? procnum : nfsv2_procid[procnum], 565 mreq, &mrep, timo); 566 567 /* 568 * If there was a successful reply and a tprintf msg. 569 * tprintf a response. 570 */ |
573 if (stat == RPC_SUCCESS) { | 571 if (stat == RPC_SUCCESS) |
574 error = 0; | 572 error = 0; |
575 } else if (stat == RPC_TIMEDOUT) { | 573 else if (stat == RPC_TIMEDOUT) |
576 error = ETIMEDOUT; | 574 error = ETIMEDOUT; |
577 } else if (stat == RPC_VERSMISMATCH) { | 575 else if (stat == RPC_VERSMISMATCH) |
578 error = EOPNOTSUPP; | 576 error = EOPNOTSUPP; |
579 } else if (stat == RPC_PROGVERSMISMATCH) { | 577 else if (stat == RPC_PROGVERSMISMATCH) |
580 error = EPROTONOSUPPORT; | 578 error = EPROTONOSUPPORT; |
581 } else { | 579 else |
582 error = EACCES; | 580 error = EACCES; |
583 } | |
584 if (error) 585 goto nfsmout; 586 587 KASSERT(mrep != NULL, ("mrep shouldn't be NULL if no error\n")); 588 589 /* 590 * Search for any mbufs that are not a multiple of 4 bytes long 591 * or with m_data not longword aligned. --- 12 unchanged lines hidden (view full) --- 604 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); 605 if (*tl != 0) { 606 error = fxdr_unsigned(int, *tl); 607 if ((nmp->nm_flag & NFSMNT_NFSV3) && 608 error == NFSERR_TRYLATER) { 609 m_freem(mrep); 610 error = 0; 611 waituntil = time_second + nfs3_jukebox_delay; | 581 if (error) 582 goto nfsmout; 583 584 KASSERT(mrep != NULL, ("mrep shouldn't be NULL if no error\n")); 585 586 /* 587 * Search for any mbufs that are not a multiple of 4 bytes long 588 * or with m_data not longword aligned. --- 12 unchanged lines hidden (view full) --- 601 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); 602 if (*tl != 0) { 603 error = fxdr_unsigned(int, *tl); 604 if ((nmp->nm_flag & NFSMNT_NFSV3) && 605 error == NFSERR_TRYLATER) { 606 m_freem(mrep); 607 error = 0; 608 waituntil = time_second + nfs3_jukebox_delay; |
612 while (time_second < waituntil) { 613 (void) tsleep(&fake_wchan, PSOCK, "nqnfstry", hz); 614 } | 609 while (time_second < waituntil) 610 (void)tsleep(&fake_wchan, PSOCK, "nqnfstry", 611 hz); |
615 goto tryagain; 616 } 617 618 /* 619 * If the File Handle was stale, invalidate the lookup 620 * cache, just in case. 621 */ 622 if (error == ESTALE) 623 nfs_purgecache(vp); 624 /* | 612 goto tryagain; 613 } 614 615 /* 616 * If the File Handle was stale, invalidate the lookup 617 * cache, just in case. 618 */ 619 if (error == ESTALE) 620 nfs_purgecache(vp); 621 /* |
625 * Skip wcc data on NFS errors for now. NetApp filers | 622 * Skip wcc data on NFS errors for now. NetApp filers |
626 * return corrupt postop attrs in the wcc data for NFS | 623 * return corrupt postop attrs in the wcc data for NFS |
627 * err EROFS. Not sure if they could return corrupt | 624 * err EROFS. Not sure if they could return corrupt |
628 * postop attrs for others errors. 629 */ | 625 * postop attrs for others errors. 626 */ |
630 if ((nmp->nm_flag & NFSMNT_NFSV3) && !nfs_skip_wcc_data_onerr) { | 627 if ((nmp->nm_flag & NFSMNT_NFSV3) && 628 !nfs_skip_wcc_data_onerr) { |
631 *mrp = mrep; 632 *mdp = md; 633 *dposp = dpos; 634 error |= NFSERR_RETERR; 635 } else 636 m_freem(mrep); 637 goto nfsmout; 638 } --- 45 unchanged lines hidden (view full) --- 684 m_freem(mreq); 685 if (auth) 686 AUTH_DESTROY(auth); 687 return (error); 688} 689 690/* 691 * Mark all of an nfs mount's outstanding requests with R_SOFTTERM and | 629 *mrp = mrep; 630 *mdp = md; 631 *dposp = dpos; 632 error |= NFSERR_RETERR; 633 } else 634 m_freem(mrep); 635 goto nfsmout; 636 } --- 45 unchanged lines hidden (view full) --- 682 m_freem(mreq); 683 if (auth) 684 AUTH_DESTROY(auth); 685 return (error); 686} 687 688/* 689 * Mark all of an nfs mount's outstanding requests with R_SOFTTERM and |
692 * wait for all requests to complete. This is used by forced unmounts | 690 * wait for all requests to complete. This is used by forced unmounts |
693 * to terminate any outstanding RPCs. 694 */ 695int 696nfs_nmcancelreqs(struct nfsmount *nmp) 697{ 698 699 if (nmp->nm_client) 700 CLNT_CLOSE(nmp->nm_client); 701 return (0); 702} 703 704/* 705 * Any signal that can interrupt an NFS operation in an intr mount | 691 * to terminate any outstanding RPCs. 692 */ 693int 694nfs_nmcancelreqs(struct nfsmount *nmp) 695{ 696 697 if (nmp->nm_client) 698 CLNT_CLOSE(nmp->nm_client); 699 return (0); 700} 701 702/* 703 * Any signal that can interrupt an NFS operation in an intr mount |
706 * should be added to this set. SIGSTOP and SIGKILL cannot be masked. | 704 * should be added to this set. SIGSTOP and SIGKILL cannot be masked. |
707 */ 708int nfs_sig_set[] = { 709 SIGINT, 710 SIGTERM, 711 SIGHUP, 712 SIGKILL, 713 SIGSTOP, 714 SIGQUIT 715}; 716 717/* 718 * Check to see if one of the signals in our subset is pending on 719 * the process (in an intr mount). 720 */ 721static int 722nfs_sig_pending(sigset_t set) 723{ 724 int i; | 705 */ 706int nfs_sig_set[] = { 707 SIGINT, 708 SIGTERM, 709 SIGHUP, 710 SIGKILL, 711 SIGSTOP, 712 SIGQUIT 713}; 714 715/* 716 * Check to see if one of the signals in our subset is pending on 717 * the process (in an intr mount). 718 */ 719static int 720nfs_sig_pending(sigset_t set) 721{ 722 int i; |
725 | 723 |
726 for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++) 727 if (SIGISMEMBER(set, nfs_sig_set[i])) 728 return (1); 729 return (0); 730} | 724 for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++) 725 if (SIGISMEMBER(set, nfs_sig_set[i])) 726 return (1); 727 return (0); 728} |
731 | 729 |
732/* 733 * The set/restore sigmask functions are used to (temporarily) overwrite | 730/* 731 * The set/restore sigmask functions are used to (temporarily) overwrite |
734 * the process p_sigmask during an RPC call (for example). These are also | 732 * the process p_sigmask during an RPC call (for example). These are also |
735 * used in other places in the NFS client that might tsleep(). 736 */ 737void 738nfs_set_sigmask(struct thread *td, sigset_t *oldset) 739{ 740 sigset_t newset; 741 int i; 742 struct proc *p; | 733 * used in other places in the NFS client that might tsleep(). 734 */ 735void 736nfs_set_sigmask(struct thread *td, sigset_t *oldset) 737{ 738 sigset_t newset; 739 int i; 740 struct proc *p; |
743 | 741 |
744 SIGFILLSET(newset); 745 if (td == NULL) 746 td = curthread; /* XXX */ 747 p = td->td_proc; | 742 SIGFILLSET(newset); 743 if (td == NULL) 744 td = curthread; /* XXX */ 745 p = td->td_proc; |
748 /* Remove the NFS set of signals from newset */ | 746 /* Remove the NFS set of signals from newset. */ |
749 PROC_LOCK(p); 750 mtx_lock(&p->p_sigacts->ps_mtx); 751 for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++) { 752 /* 753 * But make sure we leave the ones already masked | 747 PROC_LOCK(p); 748 mtx_lock(&p->p_sigacts->ps_mtx); 749 for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++) { 750 /* 751 * But make sure we leave the ones already masked |
754 * by the process, ie. remove the signal from the | 752 * by the process, i.e. remove the signal from the |
755 * temporary signalmask only if it wasn't already 756 * in p_sigmask. 757 */ 758 if (!SIGISMEMBER(td->td_sigmask, nfs_sig_set[i]) && 759 !SIGISMEMBER(p->p_sigacts->ps_sigignore, nfs_sig_set[i])) 760 SIGDELSET(newset, nfs_sig_set[i]); 761 } 762 mtx_unlock(&p->p_sigacts->ps_mtx); --- 9 unchanged lines hidden (view full) --- 772 kern_sigprocmask(td, SIG_SETMASK, set, NULL, 0); 773} 774 775/* 776 * NFS wrapper to msleep(), that shoves a new p_sigmask and restores the 777 * old one after msleep() returns. 778 */ 779int | 753 * temporary signalmask only if it wasn't already 754 * in p_sigmask. 755 */ 756 if (!SIGISMEMBER(td->td_sigmask, nfs_sig_set[i]) && 757 !SIGISMEMBER(p->p_sigacts->ps_sigignore, nfs_sig_set[i])) 758 SIGDELSET(newset, nfs_sig_set[i]); 759 } 760 mtx_unlock(&p->p_sigacts->ps_mtx); --- 9 unchanged lines hidden (view full) --- 770 kern_sigprocmask(td, SIG_SETMASK, set, NULL, 0); 771} 772 773/* 774 * NFS wrapper to msleep(), that shoves a new p_sigmask and restores the 775 * old one after msleep() returns. 776 */ 777int |
780nfs_msleep(struct thread *td, void *ident, struct mtx *mtx, int priority, char *wmesg, int timo) | 778nfs_msleep(struct thread *td, void *ident, struct mtx *mtx, int priority, 779 char *wmesg, int timo) |
781{ 782 sigset_t oldset; 783 int error; 784 struct proc *p; | 780{ 781 sigset_t oldset; 782 int error; 783 struct proc *p; |
785 | 784 |
786 if ((priority & PCATCH) == 0) 787 return msleep(ident, mtx, priority, wmesg, timo); 788 if (td == NULL) 789 td = curthread; /* XXX */ 790 nfs_set_sigmask(td, &oldset); 791 error = msleep(ident, mtx, priority, wmesg, timo); 792 nfs_restore_sigmask(td, &oldset); 793 p = td->td_proc; --- 4 unchanged lines hidden (view full) --- 798 * Test for a termination condition pending on the process. 799 * This is used for NFSMNT_INT mounts. 800 */ 801int 802nfs_sigintr(struct nfsmount *nmp, struct thread *td) 803{ 804 struct proc *p; 805 sigset_t tmpset; | 785 if ((priority & PCATCH) == 0) 786 return msleep(ident, mtx, priority, wmesg, timo); 787 if (td == NULL) 788 td = curthread; /* XXX */ 789 nfs_set_sigmask(td, &oldset); 790 error = msleep(ident, mtx, priority, wmesg, timo); 791 nfs_restore_sigmask(td, &oldset); 792 p = td->td_proc; --- 4 unchanged lines hidden (view full) --- 797 * Test for a termination condition pending on the process. 798 * This is used for NFSMNT_INT mounts. 799 */ 800int 801nfs_sigintr(struct nfsmount *nmp, struct thread *td) 802{ 803 struct proc *p; 804 sigset_t tmpset; |
806 | 805 |
807 /* Terminate all requests while attempting a forced unmount. */ 808 if (nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF) 809 return (EIO); 810 if (!(nmp->nm_flag & NFSMNT_INT)) 811 return (0); 812 if (td == NULL) 813 return (0); 814 p = td->td_proc; --- 14 unchanged lines hidden (view full) --- 829} 830 831static int 832nfs_msg(struct thread *td, const char *server, const char *msg, int error) 833{ 834 struct proc *p; 835 836 p = td ? td->td_proc : NULL; | 806 /* Terminate all requests while attempting a forced unmount. */ 807 if (nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF) 808 return (EIO); 809 if (!(nmp->nm_flag & NFSMNT_INT)) 810 return (0); 811 if (td == NULL) 812 return (0); 813 p = td->td_proc; --- 14 unchanged lines hidden (view full) --- 828} 829 830static int 831nfs_msg(struct thread *td, const char *server, const char *msg, int error) 832{ 833 struct proc *p; 834 835 p = td ? td->td_proc : NULL; |
837 if (error) { | 836 if (error) |
838 tprintf(p, LOG_INFO, "nfs server %s: %s, error %d\n", server, 839 msg, error); | 837 tprintf(p, LOG_INFO, "nfs server %s: %s, error %d\n", server, 838 msg, error); |
840 } else { | 839 else |
841 tprintf(p, LOG_INFO, "nfs server %s: %s\n", server, msg); | 840 tprintf(p, LOG_INFO, "nfs server %s: %s\n", server, msg); |
842 } | |
843 return (0); 844} 845 846static void 847nfs_down(struct nfsmount *nmp, struct thread *td, const char *msg, 848 int error, int flags) 849{ 850 if (nmp == NULL) 851 return; 852 mtx_lock(&nmp->nm_mtx); 853 if ((flags & NFSSTA_TIMEO) && !(nmp->nm_state & NFSSTA_TIMEO)) { 854 nmp->nm_state |= NFSSTA_TIMEO; 855 mtx_unlock(&nmp->nm_mtx); 856 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, 857 VQ_NOTRESP, 0); 858 } else 859 mtx_unlock(&nmp->nm_mtx); 860 mtx_lock(&nmp->nm_mtx); | 841 return (0); 842} 843 844static void 845nfs_down(struct nfsmount *nmp, struct thread *td, const char *msg, 846 int error, int flags) 847{ 848 if (nmp == NULL) 849 return; 850 mtx_lock(&nmp->nm_mtx); 851 if ((flags & NFSSTA_TIMEO) && !(nmp->nm_state & NFSSTA_TIMEO)) { 852 nmp->nm_state |= NFSSTA_TIMEO; 853 mtx_unlock(&nmp->nm_mtx); 854 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, 855 VQ_NOTRESP, 0); 856 } else 857 mtx_unlock(&nmp->nm_mtx); 858 mtx_lock(&nmp->nm_mtx); |
861 if ((flags & NFSSTA_LOCKTIMEO) && !(nmp->nm_state & NFSSTA_LOCKTIMEO)) { | 859 if ((flags & NFSSTA_LOCKTIMEO) && 860 !(nmp->nm_state & NFSSTA_LOCKTIMEO)) { |
862 nmp->nm_state |= NFSSTA_LOCKTIMEO; 863 mtx_unlock(&nmp->nm_mtx); 864 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, 865 VQ_NOTRESPLOCK, 0); 866 } else 867 mtx_unlock(&nmp->nm_mtx); 868 nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, error); 869} 870 871static void 872nfs_up(struct nfsmount *nmp, struct thread *td, const char *msg, 873 int flags, int tprintfmsg) 874{ 875 if (nmp == NULL) 876 return; | 861 nmp->nm_state |= NFSSTA_LOCKTIMEO; 862 mtx_unlock(&nmp->nm_mtx); 863 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, 864 VQ_NOTRESPLOCK, 0); 865 } else 866 mtx_unlock(&nmp->nm_mtx); 867 nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, error); 868} 869 870static void 871nfs_up(struct nfsmount *nmp, struct thread *td, const char *msg, 872 int flags, int tprintfmsg) 873{ 874 if (nmp == NULL) 875 return; |
877 if (tprintfmsg) { | 876 if (tprintfmsg) |
878 nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, 0); | 877 nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, 0); |
879 } | |
880 881 mtx_lock(&nmp->nm_mtx); 882 if ((flags & NFSSTA_TIMEO) && (nmp->nm_state & NFSSTA_TIMEO)) { 883 nmp->nm_state &= ~NFSSTA_TIMEO; 884 mtx_unlock(&nmp->nm_mtx); 885 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, 886 VQ_NOTRESP, 1); 887 } else 888 mtx_unlock(&nmp->nm_mtx); | 878 879 mtx_lock(&nmp->nm_mtx); 880 if ((flags & NFSSTA_TIMEO) && (nmp->nm_state & NFSSTA_TIMEO)) { 881 nmp->nm_state &= ~NFSSTA_TIMEO; 882 mtx_unlock(&nmp->nm_mtx); 883 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, 884 VQ_NOTRESP, 1); 885 } else 886 mtx_unlock(&nmp->nm_mtx); |
889 | 887 |
890 mtx_lock(&nmp->nm_mtx); | 888 mtx_lock(&nmp->nm_mtx); |
891 if ((flags & NFSSTA_LOCKTIMEO) && (nmp->nm_state & NFSSTA_LOCKTIMEO)) { | 889 if ((flags & NFSSTA_LOCKTIMEO) && 890 (nmp->nm_state & NFSSTA_LOCKTIMEO)) { |
892 nmp->nm_state &= ~NFSSTA_LOCKTIMEO; 893 mtx_unlock(&nmp->nm_mtx); 894 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, 895 VQ_NOTRESPLOCK, 1); 896 } else 897 mtx_unlock(&nmp->nm_mtx); 898} | 891 nmp->nm_state &= ~NFSSTA_LOCKTIMEO; 892 mtx_unlock(&nmp->nm_mtx); 893 vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, 894 VQ_NOTRESPLOCK, 1); 895 } else 896 mtx_unlock(&nmp->nm_mtx); 897} |