aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-20 17:04:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-20 17:04:11 -0500
commit982197277c85018cc6eb77f1d3bef17933b0c5fd (patch)
tree805fcef9ec7c1e83867b89332fd37f751594fae3 /net/sunrpc
parent40889e8d9fc6355980cf2bc94ef4356c10dec4ec (diff)
parent24ffb93872f7363a01ad639e3c8a9889b46c3f0a (diff)
Merge branch 'for-3.8' of git://linux-nfs.org/~bfields/linux
Pull nfsd update from Bruce Fields: "Included this time: - more nfsd containerization work from Stanislav Kinsbursky: we're not quite there yet, but should be by 3.9. - NFSv4.1 progress: implementation of basic backchannel security negotiation and the mandatory BACKCHANNEL_CTL operation. See http://wiki.linux-nfs.org/wiki/index.php/Server_4.0_and_4.1_issues for remaining TODO's - Fixes for some bugs that could be triggered by unusual compounds. Our xdr code wasn't designed with v4 compounds in mind, and it shows. A more thorough rewrite is still a todo. - If you've ever seen "RPC: multiple fragments per record not supported" logged while using some sort of odd userland NFS client, that should now be fixed. - Further work from Jeff Layton on our mechanism for storing information about NFSv4 clients across reboots. - Further work from Bryan Schumaker on his fault-injection mechanism (which allows us to discard selective NFSv4 state, to excercise rarely-taken recovery code paths in the client.) - The usual mix of miscellaneous bugs and cleanup. Thanks to everyone who tested or contributed this cycle." * 'for-3.8' of git://linux-nfs.org/~bfields/linux: (111 commits) nfsd4: don't leave freed stateid hashed nfsd4: free_stateid can use the current stateid nfsd4: cleanup: replace rq_resused count by rq_next_page pointer nfsd: warn on odd reply state in nfsd_vfs_read nfsd4: fix oops on unusual readlike compound nfsd4: disable zero-copy on non-final read ops svcrpc: fix some printks NFSD: Correct the size calculation in fault_inject_write NFSD: Pass correct buffer size to rpc_ntop nfsd: pass proper net to nfsd_destroy() from NFSd kthreads nfsd: simplify service shutdown nfsd: replace boolean nfsd_up flag by users counter nfsd: simplify NFSv4 state init and shutdown nfsd: introduce helpers for generic resources init and shutdown nfsd: make NFSd service structure allocated per net nfsd: make NFSd service boot time per-net nfsd: per-net NFSd up flag introduced nfsd: move per-net startup code to separated function nfsd: pass net to __write_ports() and down nfsd: pass net to nfsd_set_nrthreads() ...
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/rpcb_clnt.c1
-rw-r--r--net/sunrpc/svc.c8
-rw-r--r--net/sunrpc/svcsock.c98
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_recvfrom.c10
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_sendto.c4
5 files changed, 61 insertions, 60 deletions
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 411f332de0b3..795a0f4e920b 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -23,7 +23,6 @@
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/mutex.h> 24#include <linux/mutex.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/nsproxy.h>
27#include <net/ipv6.h> 26#include <net/ipv6.h>
28 27
29#include <linux/sunrpc/clnt.h> 28#include <linux/sunrpc/clnt.h>
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index dfa4ba69ff45..dbf12ac5ecb7 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -20,7 +20,6 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/kthread.h> 21#include <linux/kthread.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/nsproxy.h>
24 23
25#include <linux/sunrpc/types.h> 24#include <linux/sunrpc/types.h>
26#include <linux/sunrpc/xdr.h> 25#include <linux/sunrpc/xdr.h>
@@ -1041,7 +1040,7 @@ static void svc_unregister(const struct svc_serv *serv, struct net *net)
1041} 1040}
1042 1041
1043/* 1042/*
1044 * Printk the given error with the address of the client that caused it. 1043 * dprintk the given error with the address of the client that caused it.
1045 */ 1044 */
1046static __printf(2, 3) 1045static __printf(2, 3)
1047void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) 1046void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
@@ -1055,8 +1054,7 @@ void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
1055 vaf.fmt = fmt; 1054 vaf.fmt = fmt;
1056 vaf.va = &args; 1055 vaf.va = &args;
1057 1056
1058 net_warn_ratelimited("svc: %s: %pV", 1057 dprintk("svc: %s: %pV", svc_print_addr(rqstp, buf, sizeof(buf)), &vaf);
1059 svc_print_addr(rqstp, buf, sizeof(buf)), &vaf);
1060 1058
1061 va_end(args); 1059 va_end(args);
1062} 1060}
@@ -1305,7 +1303,7 @@ svc_process(struct svc_rqst *rqstp)
1305 * Setup response xdr_buf. 1303 * Setup response xdr_buf.
1306 * Initially it has just one page 1304 * Initially it has just one page
1307 */ 1305 */
1308 rqstp->rq_resused = 1; 1306 rqstp->rq_next_page = &rqstp->rq_respages[1];
1309 resv->iov_base = page_address(rqstp->rq_respages[0]); 1307 resv->iov_base = page_address(rqstp->rq_respages[0]);
1310 resv->iov_len = 0; 1308 resv->iov_len = 0;
1311 rqstp->rq_res.pages = rqstp->rq_respages + 1; 1309 rqstp->rq_res.pages = rqstp->rq_respages + 1;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index cc3020d16789..0a148c9d2a5c 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -605,6 +605,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
605 rqstp->rq_respages = rqstp->rq_pages + 1 + 605 rqstp->rq_respages = rqstp->rq_pages + 1 +
606 DIV_ROUND_UP(rqstp->rq_arg.page_len, PAGE_SIZE); 606 DIV_ROUND_UP(rqstp->rq_arg.page_len, PAGE_SIZE);
607 } 607 }
608 rqstp->rq_next_page = rqstp->rq_respages+1;
608 609
609 if (serv->sv_stats) 610 if (serv->sv_stats)
610 serv->sv_stats->netudpcnt++; 611 serv->sv_stats->netudpcnt++;
@@ -878,9 +879,9 @@ static unsigned int svc_tcp_restore_pages(struct svc_sock *svsk, struct svc_rqst
878{ 879{
879 unsigned int i, len, npages; 880 unsigned int i, len, npages;
880 881
881 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) 882 if (svsk->sk_datalen == 0)
882 return 0; 883 return 0;
883 len = svsk->sk_tcplen - sizeof(rpc_fraghdr); 884 len = svsk->sk_datalen;
884 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 885 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
885 for (i = 0; i < npages; i++) { 886 for (i = 0; i < npages; i++) {
886 if (rqstp->rq_pages[i] != NULL) 887 if (rqstp->rq_pages[i] != NULL)
@@ -897,9 +898,9 @@ static void svc_tcp_save_pages(struct svc_sock *svsk, struct svc_rqst *rqstp)
897{ 898{
898 unsigned int i, len, npages; 899 unsigned int i, len, npages;
899 900
900 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) 901 if (svsk->sk_datalen == 0)
901 return; 902 return;
902 len = svsk->sk_tcplen - sizeof(rpc_fraghdr); 903 len = svsk->sk_datalen;
903 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 904 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
904 for (i = 0; i < npages; i++) { 905 for (i = 0; i < npages; i++) {
905 svsk->sk_pages[i] = rqstp->rq_pages[i]; 906 svsk->sk_pages[i] = rqstp->rq_pages[i];
@@ -911,9 +912,9 @@ static void svc_tcp_clear_pages(struct svc_sock *svsk)
911{ 912{
912 unsigned int i, len, npages; 913 unsigned int i, len, npages;
913 914
914 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) 915 if (svsk->sk_datalen == 0)
915 goto out; 916 goto out;
916 len = svsk->sk_tcplen - sizeof(rpc_fraghdr); 917 len = svsk->sk_datalen;
917 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 918 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
918 for (i = 0; i < npages; i++) { 919 for (i = 0; i < npages; i++) {
919 BUG_ON(svsk->sk_pages[i] == NULL); 920 BUG_ON(svsk->sk_pages[i] == NULL);
@@ -922,13 +923,12 @@ static void svc_tcp_clear_pages(struct svc_sock *svsk)
922 } 923 }
923out: 924out:
924 svsk->sk_tcplen = 0; 925 svsk->sk_tcplen = 0;
926 svsk->sk_datalen = 0;
925} 927}
926 928
927/* 929/*
928 * Receive data. 930 * Receive fragment record header.
929 * If we haven't gotten the record length yet, get the next four bytes. 931 * If we haven't gotten the record length yet, get the next four bytes.
930 * Otherwise try to gobble up as much as possible up to the complete
931 * record length.
932 */ 932 */
933static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) 933static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
934{ 934{
@@ -954,32 +954,16 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
954 return -EAGAIN; 954 return -EAGAIN;
955 } 955 }
956 956
957 svsk->sk_reclen = ntohl(svsk->sk_reclen); 957 dprintk("svc: TCP record, %d bytes\n", svc_sock_reclen(svsk));
958 if (!(svsk->sk_reclen & RPC_LAST_STREAM_FRAGMENT)) { 958 if (svc_sock_reclen(svsk) + svsk->sk_datalen >
959 /* FIXME: technically, a record can be fragmented, 959 serv->sv_max_mesg) {
960 * and non-terminal fragments will not have the top 960 net_notice_ratelimited("RPC: fragment too large: %d\n",
961 * bit set in the fragment length header. 961 svc_sock_reclen(svsk));
962 * But apparently no known nfs clients send fragmented
963 * records. */
964 net_notice_ratelimited("RPC: multiple fragments per record not supported\n");
965 goto err_delete;
966 }
967
968 svsk->sk_reclen &= RPC_FRAGMENT_SIZE_MASK;
969 dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen);
970 if (svsk->sk_reclen > serv->sv_max_mesg) {
971 net_notice_ratelimited("RPC: fragment too large: 0x%08lx\n",
972 (unsigned long)svsk->sk_reclen);
973 goto err_delete; 962 goto err_delete;
974 } 963 }
975 } 964 }
976 965
977 if (svsk->sk_reclen < 8) 966 return svc_sock_reclen(svsk);
978 goto err_delete; /* client is nuts. */
979
980 len = svsk->sk_reclen;
981
982 return len;
983error: 967error:
984 dprintk("RPC: TCP recv_record got %d\n", len); 968 dprintk("RPC: TCP recv_record got %d\n", len);
985 return len; 969 return len;
@@ -1023,7 +1007,7 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp)
1023 if (dst->iov_len < src->iov_len) 1007 if (dst->iov_len < src->iov_len)
1024 return -EAGAIN; /* whatever; just giving up. */ 1008 return -EAGAIN; /* whatever; just giving up. */
1025 memcpy(dst->iov_base, src->iov_base, src->iov_len); 1009 memcpy(dst->iov_base, src->iov_base, src->iov_len);
1026 xprt_complete_rqst(req->rq_task, svsk->sk_reclen); 1010 xprt_complete_rqst(req->rq_task, rqstp->rq_arg.len);
1027 rqstp->rq_arg.len = 0; 1011 rqstp->rq_arg.len = 0;
1028 return 0; 1012 return 0;
1029} 1013}
@@ -1042,6 +1026,17 @@ static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len)
1042 return i; 1026 return i;
1043} 1027}
1044 1028
1029static void svc_tcp_fragment_received(struct svc_sock *svsk)
1030{
1031 /* If we have more data, signal svc_xprt_enqueue() to try again */
1032 if (svc_recv_available(svsk) > sizeof(rpc_fraghdr))
1033 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
1034 dprintk("svc: TCP %s record (%d bytes)\n",
1035 svc_sock_final_rec(svsk) ? "final" : "nonfinal",
1036 svc_sock_reclen(svsk));
1037 svsk->sk_tcplen = 0;
1038 svsk->sk_reclen = 0;
1039}
1045 1040
1046/* 1041/*
1047 * Receive data from a TCP socket. 1042 * Receive data from a TCP socket.
@@ -1068,29 +1063,39 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1068 goto error; 1063 goto error;
1069 1064
1070 base = svc_tcp_restore_pages(svsk, rqstp); 1065 base = svc_tcp_restore_pages(svsk, rqstp);
1071 want = svsk->sk_reclen - base; 1066 want = svc_sock_reclen(svsk) - (svsk->sk_tcplen - sizeof(rpc_fraghdr));
1072 1067
1073 vec = rqstp->rq_vec; 1068 vec = rqstp->rq_vec;
1074 1069
1075 pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0], 1070 pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0],
1076 svsk->sk_reclen); 1071 svsk->sk_datalen + want);
1077 1072
1078 rqstp->rq_respages = &rqstp->rq_pages[pnum]; 1073 rqstp->rq_respages = &rqstp->rq_pages[pnum];
1074 rqstp->rq_next_page = rqstp->rq_respages + 1;
1079 1075
1080 /* Now receive data */ 1076 /* Now receive data */
1081 len = svc_partial_recvfrom(rqstp, vec, pnum, want, base); 1077 len = svc_partial_recvfrom(rqstp, vec, pnum, want, base);
1082 if (len >= 0) 1078 if (len >= 0) {
1083 svsk->sk_tcplen += len; 1079 svsk->sk_tcplen += len;
1084 if (len != want) { 1080 svsk->sk_datalen += len;
1081 }
1082 if (len != want || !svc_sock_final_rec(svsk)) {
1085 svc_tcp_save_pages(svsk, rqstp); 1083 svc_tcp_save_pages(svsk, rqstp);
1086 if (len < 0 && len != -EAGAIN) 1084 if (len < 0 && len != -EAGAIN)
1087 goto err_other; 1085 goto err_delete;
1088 dprintk("svc: incomplete TCP record (%d of %d)\n", 1086 if (len == want)
1089 svsk->sk_tcplen, svsk->sk_reclen); 1087 svc_tcp_fragment_received(svsk);
1088 else
1089 dprintk("svc: incomplete TCP record (%d of %d)\n",
1090 (int)(svsk->sk_tcplen - sizeof(rpc_fraghdr)),
1091 svc_sock_reclen(svsk));
1090 goto err_noclose; 1092 goto err_noclose;
1091 } 1093 }
1092 1094
1093 rqstp->rq_arg.len = svsk->sk_reclen; 1095 if (svc_sock_reclen(svsk) < 8)
1096 goto err_delete; /* client is nuts. */
1097
1098 rqstp->rq_arg.len = svsk->sk_datalen;
1094 rqstp->rq_arg.page_base = 0; 1099 rqstp->rq_arg.page_base = 0;
1095 if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) { 1100 if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) {
1096 rqstp->rq_arg.head[0].iov_len = rqstp->rq_arg.len; 1101 rqstp->rq_arg.head[0].iov_len = rqstp->rq_arg.len;
@@ -1107,11 +1112,8 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1107 len = receive_cb_reply(svsk, rqstp); 1112 len = receive_cb_reply(svsk, rqstp);
1108 1113
1109 /* Reset TCP read info */ 1114 /* Reset TCP read info */
1110 svsk->sk_reclen = 0; 1115 svsk->sk_datalen = 0;
1111 svsk->sk_tcplen = 0; 1116 svc_tcp_fragment_received(svsk);
1112 /* If we have more data, signal svc_xprt_enqueue() to try again */
1113 if (svc_recv_available(svsk) > sizeof(rpc_fraghdr))
1114 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
1115 1117
1116 if (len < 0) 1118 if (len < 0)
1117 goto error; 1119 goto error;
@@ -1120,15 +1122,14 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1120 if (serv->sv_stats) 1122 if (serv->sv_stats)
1121 serv->sv_stats->nettcpcnt++; 1123 serv->sv_stats->nettcpcnt++;
1122 1124
1123 dprintk("svc: TCP complete record (%d bytes)\n", rqstp->rq_arg.len);
1124 return rqstp->rq_arg.len; 1125 return rqstp->rq_arg.len;
1125 1126
1126error: 1127error:
1127 if (len != -EAGAIN) 1128 if (len != -EAGAIN)
1128 goto err_other; 1129 goto err_delete;
1129 dprintk("RPC: TCP recvfrom got EAGAIN\n"); 1130 dprintk("RPC: TCP recvfrom got EAGAIN\n");
1130 return 0; 1131 return 0;
1131err_other: 1132err_delete:
1132 printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", 1133 printk(KERN_NOTICE "%s: recvfrom returned errno %d\n",
1133 svsk->sk_xprt.xpt_server->sv_name, -len); 1134 svsk->sk_xprt.xpt_server->sv_name, -len);
1134 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); 1135 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
@@ -1305,6 +1306,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
1305 1306
1306 svsk->sk_reclen = 0; 1307 svsk->sk_reclen = 0;
1307 svsk->sk_tcplen = 0; 1308 svsk->sk_tcplen = 0;
1309 svsk->sk_datalen = 0;
1308 memset(&svsk->sk_pages[0], 0, sizeof(svsk->sk_pages)); 1310 memset(&svsk->sk_pages[0], 0, sizeof(svsk->sk_pages));
1309 1311
1310 tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; 1312 tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index 41cb63b623df..0ce75524ed21 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -521,11 +521,11 @@ next_sge:
521 rqstp->rq_pages[ch_no] = NULL; 521 rqstp->rq_pages[ch_no] = NULL;
522 522
523 /* 523 /*
524 * Detach res pages. svc_release must see a resused count of 524 * Detach res pages. If svc_release sees any it will attempt to
525 * zero or it will attempt to put them. 525 * put them.
526 */ 526 */
527 while (rqstp->rq_resused) 527 while (rqstp->rq_next_page != rqstp->rq_respages)
528 rqstp->rq_respages[--rqstp->rq_resused] = NULL; 528 *(--rqstp->rq_next_page) = NULL;
529 529
530 return err; 530 return err;
531} 531}
@@ -550,7 +550,7 @@ static int rdma_read_complete(struct svc_rqst *rqstp,
550 550
551 /* rq_respages starts after the last arg page */ 551 /* rq_respages starts after the last arg page */
552 rqstp->rq_respages = &rqstp->rq_arg.pages[page_no]; 552 rqstp->rq_respages = &rqstp->rq_arg.pages[page_no];
553 rqstp->rq_resused = 0; 553 rqstp->rq_next_page = &rqstp->rq_arg.pages[page_no];
554 554
555 /* Rebuild rq_arg head and tail. */ 555 /* Rebuild rq_arg head and tail. */
556 rqstp->rq_arg.head[0] = head->arg.head[0]; 556 rqstp->rq_arg.head[0] = head->arg.head[0];
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index 42eb7ba0b903..c1d124dc772b 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -548,6 +548,7 @@ static int send_reply(struct svcxprt_rdma *rdma,
548 int sge_no; 548 int sge_no;
549 int sge_bytes; 549 int sge_bytes;
550 int page_no; 550 int page_no;
551 int pages;
551 int ret; 552 int ret;
552 553
553 /* Post a recv buffer to handle another request. */ 554 /* Post a recv buffer to handle another request. */
@@ -611,7 +612,8 @@ static int send_reply(struct svcxprt_rdma *rdma,
611 * respages array. They are our pages until the I/O 612 * respages array. They are our pages until the I/O
612 * completes. 613 * completes.
613 */ 614 */
614 for (page_no = 0; page_no < rqstp->rq_resused; page_no++) { 615 pages = rqstp->rq_next_page - rqstp->rq_respages;
616 for (page_no = 0; page_no < pages; page_no++) {
615 ctxt->pages[page_no+1] = rqstp->rq_respages[page_no]; 617 ctxt->pages[page_no+1] = rqstp->rq_respages[page_no];
616 ctxt->count++; 618 ctxt->count++;
617 rqstp->rq_respages[page_no] = NULL; 619 rqstp->rq_respages[page_no] = NULL;