Commit 7e3d3620 authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker
Browse files

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: 06b5fc3a ("Merge tag 'nfs-rdma-for-5.1-1'...")
Cc: stable@vger.kernel.org # 5.1+
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 19d55046
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -950,6 +950,8 @@ static int xs_local_send_request(struct rpc_rqst *req)
	struct sock_xprt *transport =
				container_of(xprt, struct sock_xprt, xprt);
	struct xdr_buf *xdr = &req->rq_snd_buf;
	rpc_fraghdr rm = xs_stream_record_marker(xdr);
	unsigned int msglen = rm ? req->rq_slen + sizeof(rm) : req->rq_slen;
	int status;
	int sent = 0;

@@ -964,9 +966,7 @@ static int xs_local_send_request(struct rpc_rqst *req)

	req->rq_xtime = ktime_get();
	status = xs_sendpages(transport->sock, NULL, 0, xdr,
			      transport->xmit.offset,
			      xs_stream_record_marker(xdr),
			      &sent);
			      transport->xmit.offset, rm, &sent);
	dprintk("RPC:       %s(%u) = %d\n",
			__func__, xdr->len - transport->xmit.offset, status);

@@ -976,7 +976,7 @@ static int xs_local_send_request(struct rpc_rqst *req)
	if (likely(sent > 0) || status == 0) {
		transport->xmit.offset += sent;
		req->rq_bytes_sent = transport->xmit.offset;
		if (likely(req->rq_bytes_sent >= req->rq_slen)) {
		if (likely(req->rq_bytes_sent >= msglen)) {
			req->rq_xmit_bytes_sent += transport->xmit.offset;
			transport->xmit.offset = 0;
			return 0;
@@ -1097,6 +1097,8 @@ static int xs_tcp_send_request(struct rpc_rqst *req)
	struct rpc_xprt *xprt = req->rq_xprt;
	struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
	struct xdr_buf *xdr = &req->rq_snd_buf;
	rpc_fraghdr rm = xs_stream_record_marker(xdr);
	unsigned int msglen = rm ? req->rq_slen + sizeof(rm) : req->rq_slen;
	bool vm_wait = false;
	int status;
	int sent;
@@ -1122,9 +1124,7 @@ static int xs_tcp_send_request(struct rpc_rqst *req)
	while (1) {
		sent = 0;
		status = xs_sendpages(transport->sock, NULL, 0, xdr,
				      transport->xmit.offset,
				      xs_stream_record_marker(xdr),
				      &sent);
				      transport->xmit.offset, rm, &sent);

		dprintk("RPC:       xs_tcp_send_request(%u) = %d\n",
				xdr->len - transport->xmit.offset, status);
@@ -1133,7 +1133,7 @@ static int xs_tcp_send_request(struct rpc_rqst *req)
		 * reset the count of bytes sent. */
		transport->xmit.offset += sent;
		req->rq_bytes_sent = transport->xmit.offset;
		if (likely(req->rq_bytes_sent >= req->rq_slen)) {
		if (likely(req->rq_bytes_sent >= msglen)) {
			req->rq_xmit_bytes_sent += transport->xmit.offset;
			transport->xmit.offset = 0;
			return 0;