aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-08-12 03:04:07 -0400
committerJ. Bruce Fields <bfields@redhat.com>2010-09-21 16:57:49 -0400
commit1ebede86b8abbcf8833830e18e05391758cf2f28 (patch)
tree872f1218a45f84070eeac162621ef3e56fc6f222 /net/sunrpc
parent06497524589f2a7717da33969d541674e0a27da6 (diff)
sunrpc: close connection when a request is irretrievably lost.
If we drop a request in the sunrpc layer, either due kmalloc failure, or due to a cache miss when we could not queue the request for later replay, then close the connection to encourage the client to retry sooner. Note that if the drop happens in the NFS layer, NFSERR_JUKEBOX (aka NFS4ERR_DELAY) is returned to guide the client concerning replay. Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c12
-rw-r--r--net/sunrpc/svc.c3
-rw-r--r--net/sunrpc/svcauth_unix.c11
3 files changed, 17 insertions, 9 deletions
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index cc385b3a59c2..ed005af3ef5d 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -964,7 +964,7 @@ svcauth_gss_set_client(struct svc_rqst *rqstp)
964 if (rqstp->rq_gssclient == NULL) 964 if (rqstp->rq_gssclient == NULL)
965 return SVC_DENIED; 965 return SVC_DENIED;
966 stat = svcauth_unix_set_client(rqstp); 966 stat = svcauth_unix_set_client(rqstp);
967 if (stat == SVC_DROP) 967 if (stat == SVC_DROP || stat == SVC_CLOSE)
968 return stat; 968 return stat;
969 return SVC_OK; 969 return SVC_OK;
970} 970}
@@ -1018,7 +1018,7 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp,
1018 return SVC_DENIED; 1018 return SVC_DENIED;
1019 memset(&rsikey, 0, sizeof(rsikey)); 1019 memset(&rsikey, 0, sizeof(rsikey));
1020 if (dup_netobj(&rsikey.in_handle, &gc->gc_ctx)) 1020 if (dup_netobj(&rsikey.in_handle, &gc->gc_ctx))
1021 return SVC_DROP; 1021 return SVC_CLOSE;
1022 *authp = rpc_autherr_badverf; 1022 *authp = rpc_autherr_badverf;
1023 if (svc_safe_getnetobj(argv, &tmpobj)) { 1023 if (svc_safe_getnetobj(argv, &tmpobj)) {
1024 kfree(rsikey.in_handle.data); 1024 kfree(rsikey.in_handle.data);
@@ -1026,22 +1026,22 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp,
1026 } 1026 }
1027 if (dup_netobj(&rsikey.in_token, &tmpobj)) { 1027 if (dup_netobj(&rsikey.in_token, &tmpobj)) {
1028 kfree(rsikey.in_handle.data); 1028 kfree(rsikey.in_handle.data);
1029 return SVC_DROP; 1029 return SVC_CLOSE;
1030 } 1030 }
1031 1031
1032 /* Perform upcall, or find upcall result: */ 1032 /* Perform upcall, or find upcall result: */
1033 rsip = rsi_lookup(&rsikey); 1033 rsip = rsi_lookup(&rsikey);
1034 rsi_free(&rsikey); 1034 rsi_free(&rsikey);
1035 if (!rsip) 1035 if (!rsip)
1036 return SVC_DROP; 1036 return SVC_CLOSE;
1037 switch (cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle)) { 1037 switch (cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle)) {
1038 case -EAGAIN: 1038 case -EAGAIN:
1039 case -ETIMEDOUT: 1039 case -ETIMEDOUT:
1040 case -ENOENT: 1040 case -ENOENT:
1041 /* No upcall result: */ 1041 /* No upcall result: */
1042 return SVC_DROP; 1042 return SVC_CLOSE;
1043 case 0: 1043 case 0:
1044 ret = SVC_DROP; 1044 ret = SVC_CLOSE;
1045 /* Got an answer to the upcall; use it: */ 1045 /* Got an answer to the upcall; use it: */
1046 if (gss_write_init_verf(rqstp, rsip)) 1046 if (gss_write_init_verf(rqstp, rsip))
1047 goto out; 1047 goto out;
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index d9017d64597e..6359c42c4941 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1055,6 +1055,9 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
1055 goto err_bad; 1055 goto err_bad;
1056 case SVC_DENIED: 1056 case SVC_DENIED:
1057 goto err_bad_auth; 1057 goto err_bad_auth;
1058 case SVC_CLOSE:
1059 if (test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags))
1060 svc_close_xprt(rqstp->rq_xprt);
1058 case SVC_DROP: 1061 case SVC_DROP:
1059 goto dropit; 1062 goto dropit;
1060 case SVC_COMPLETE: 1063 case SVC_COMPLETE:
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 207311610988..e91b550bc836 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -674,6 +674,8 @@ static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp)
674 switch (ret) { 674 switch (ret) {
675 case -ENOENT: 675 case -ENOENT:
676 return ERR_PTR(-ENOENT); 676 return ERR_PTR(-ENOENT);
677 case -ETIMEDOUT:
678 return ERR_PTR(-ESHUTDOWN);
677 case 0: 679 case 0:
678 gi = get_group_info(ug->gi); 680 gi = get_group_info(ug->gi);
679 cache_put(&ug->h, &unix_gid_cache); 681 cache_put(&ug->h, &unix_gid_cache);
@@ -720,8 +722,9 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
720 switch (cache_check(&ip_map_cache, &ipm->h, &rqstp->rq_chandle)) { 722 switch (cache_check(&ip_map_cache, &ipm->h, &rqstp->rq_chandle)) {
721 default: 723 default:
722 BUG(); 724 BUG();
723 case -EAGAIN:
724 case -ETIMEDOUT: 725 case -ETIMEDOUT:
726 return SVC_CLOSE;
727 case -EAGAIN:
725 return SVC_DROP; 728 return SVC_DROP;
726 case -ENOENT: 729 case -ENOENT:
727 return SVC_DENIED; 730 return SVC_DENIED;
@@ -736,6 +739,8 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
736 switch (PTR_ERR(gi)) { 739 switch (PTR_ERR(gi)) {
737 case -EAGAIN: 740 case -EAGAIN:
738 return SVC_DROP; 741 return SVC_DROP;
742 case -ESHUTDOWN:
743 return SVC_CLOSE;
739 case -ENOENT: 744 case -ENOENT:
740 break; 745 break;
741 default: 746 default:
@@ -776,7 +781,7 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)
776 cred->cr_gid = (gid_t) -1; 781 cred->cr_gid = (gid_t) -1;
777 cred->cr_group_info = groups_alloc(0); 782 cred->cr_group_info = groups_alloc(0);
778 if (cred->cr_group_info == NULL) 783 if (cred->cr_group_info == NULL)
779 return SVC_DROP; /* kmalloc failure - client must retry */ 784 return SVC_CLOSE; /* kmalloc failure - client must retry */
780 785
781 /* Put NULL verifier */ 786 /* Put NULL verifier */
782 svc_putnl(resv, RPC_AUTH_NULL); 787 svc_putnl(resv, RPC_AUTH_NULL);
@@ -840,7 +845,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
840 goto badcred; 845 goto badcred;
841 cred->cr_group_info = groups_alloc(slen); 846 cred->cr_group_info = groups_alloc(slen);
842 if (cred->cr_group_info == NULL) 847 if (cred->cr_group_info == NULL)
843 return SVC_DROP; 848 return SVC_CLOSE;
844 for (i = 0; i < slen; i++) 849 for (i = 0; i < slen; i++)
845 GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv); 850 GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv);
846 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { 851 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {