diff options
author | Trond Myklebust <trondmy@gmail.com> | 2019-06-24 19:15:44 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2019-06-28 11:17:47 -0400 |
commit | 7e3d3620974b743b91b1f9d0660061b1de20174c (patch) | |
tree | 5aeb08a887ba0c77314a67f6d5f65e713d6f485c | |
parent | 19d55046cd824baab53534ba7e7f99945c6fdcb1 (diff) |
SUNRPC: Fix up calculation of client message length
In the case where a record marker was used, xs_sendpages() needs
to return the length of the payload + record marker so that we
operate correctly in the case of a partial transmission.
When the callers check return value, they therefore need to
take into account the record marker length.
Fixes: 06b5fc3ad94e ("Merge tag 'nfs-rdma-for-5.1-1'...")
Cc: stable@vger.kernel.org # 5.1+
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r-- | net/sunrpc/xprtsock.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index c69951ed2ebc..36652352a38c 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -950,6 +950,8 @@ static int xs_local_send_request(struct rpc_rqst *req) | |||
950 | struct sock_xprt *transport = | 950 | struct sock_xprt *transport = |
951 | container_of(xprt, struct sock_xprt, xprt); | 951 | container_of(xprt, struct sock_xprt, xprt); |
952 | struct xdr_buf *xdr = &req->rq_snd_buf; | 952 | struct xdr_buf *xdr = &req->rq_snd_buf; |
953 | rpc_fraghdr rm = xs_stream_record_marker(xdr); | ||
954 | unsigned int msglen = rm ? req->rq_slen + sizeof(rm) : req->rq_slen; | ||
953 | int status; | 955 | int status; |
954 | int sent = 0; | 956 | int sent = 0; |
955 | 957 | ||
@@ -964,9 +966,7 @@ static int xs_local_send_request(struct rpc_rqst *req) | |||
964 | 966 | ||
965 | req->rq_xtime = ktime_get(); | 967 | req->rq_xtime = ktime_get(); |
966 | status = xs_sendpages(transport->sock, NULL, 0, xdr, | 968 | status = xs_sendpages(transport->sock, NULL, 0, xdr, |
967 | transport->xmit.offset, | 969 | transport->xmit.offset, rm, &sent); |
968 | xs_stream_record_marker(xdr), | ||
969 | &sent); | ||
970 | dprintk("RPC: %s(%u) = %d\n", | 970 | dprintk("RPC: %s(%u) = %d\n", |
971 | __func__, xdr->len - transport->xmit.offset, status); | 971 | __func__, xdr->len - transport->xmit.offset, status); |
972 | 972 | ||
@@ -976,7 +976,7 @@ static int xs_local_send_request(struct rpc_rqst *req) | |||
976 | if (likely(sent > 0) || status == 0) { | 976 | if (likely(sent > 0) || status == 0) { |
977 | transport->xmit.offset += sent; | 977 | transport->xmit.offset += sent; |
978 | req->rq_bytes_sent = transport->xmit.offset; | 978 | req->rq_bytes_sent = transport->xmit.offset; |
979 | if (likely(req->rq_bytes_sent >= req->rq_slen)) { | 979 | if (likely(req->rq_bytes_sent >= msglen)) { |
980 | req->rq_xmit_bytes_sent += transport->xmit.offset; | 980 | req->rq_xmit_bytes_sent += transport->xmit.offset; |
981 | transport->xmit.offset = 0; | 981 | transport->xmit.offset = 0; |
982 | return 0; | 982 | return 0; |
@@ -1097,6 +1097,8 @@ static int xs_tcp_send_request(struct rpc_rqst *req) | |||
1097 | struct rpc_xprt *xprt = req->rq_xprt; | 1097 | struct rpc_xprt *xprt = req->rq_xprt; |
1098 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 1098 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
1099 | struct xdr_buf *xdr = &req->rq_snd_buf; | 1099 | struct xdr_buf *xdr = &req->rq_snd_buf; |
1100 | rpc_fraghdr rm = xs_stream_record_marker(xdr); | ||
1101 | unsigned int msglen = rm ? req->rq_slen + sizeof(rm) : req->rq_slen; | ||
1100 | bool vm_wait = false; | 1102 | bool vm_wait = false; |
1101 | int status; | 1103 | int status; |
1102 | int sent; | 1104 | int sent; |
@@ -1122,9 +1124,7 @@ static int xs_tcp_send_request(struct rpc_rqst *req) | |||
1122 | while (1) { | 1124 | while (1) { |
1123 | sent = 0; | 1125 | sent = 0; |
1124 | status = xs_sendpages(transport->sock, NULL, 0, xdr, | 1126 | status = xs_sendpages(transport->sock, NULL, 0, xdr, |
1125 | transport->xmit.offset, | 1127 | transport->xmit.offset, rm, &sent); |
1126 | xs_stream_record_marker(xdr), | ||
1127 | &sent); | ||
1128 | 1128 | ||
1129 | dprintk("RPC: xs_tcp_send_request(%u) = %d\n", | 1129 | dprintk("RPC: xs_tcp_send_request(%u) = %d\n", |
1130 | xdr->len - transport->xmit.offset, status); | 1130 | xdr->len - transport->xmit.offset, status); |
@@ -1133,7 +1133,7 @@ static int xs_tcp_send_request(struct rpc_rqst *req) | |||
1133 | * reset the count of bytes sent. */ | 1133 | * reset the count of bytes sent. */ |
1134 | transport->xmit.offset += sent; | 1134 | transport->xmit.offset += sent; |
1135 | req->rq_bytes_sent = transport->xmit.offset; | 1135 | req->rq_bytes_sent = transport->xmit.offset; |
1136 | if (likely(req->rq_bytes_sent >= req->rq_slen)) { | 1136 | if (likely(req->rq_bytes_sent >= msglen)) { |
1137 | req->rq_xmit_bytes_sent += transport->xmit.offset; | 1137 | req->rq_xmit_bytes_sent += transport->xmit.offset; |
1138 | transport->xmit.offset = 0; | 1138 | transport->xmit.offset = 0; |
1139 | return 0; | 1139 | return 0; |