Commit bff049a3 authored by Anna Schumaker's avatar Anna Schumaker
Browse files

NFS: Decode a full READ_PLUS reply



Decode multiple hole and data segments sent by the server, placing
everything directly where they need to go in the xdr pages.

Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent e6ac0acc
Loading
Loading
Loading
Loading
+19 −17
Original line number Diff line number Diff line
@@ -1032,7 +1032,7 @@ static int decode_read_plus_data(struct xdr_stream *xdr, struct nfs_pgio_res *re

	p = xdr_decode_hyper(p, &offset);
	count = be32_to_cpup(p);
	recvd = xdr_read_pages(xdr, count);
	recvd = xdr_align_data(xdr, res->count, count);
	res->count += recvd;

	if (count > recvd) {
@@ -1057,7 +1057,7 @@ static int decode_read_plus_hole(struct xdr_stream *xdr, struct nfs_pgio_res *re

	p = xdr_decode_hyper(p, &offset);
	p = xdr_decode_hyper(p, &length);
	recvd = xdr_expand_hole(xdr, 0, length);
	recvd = xdr_expand_hole(xdr, res->count, length);
	res->count += recvd;

	if (recvd < length) {
@@ -1070,7 +1070,7 @@ static int decode_read_plus_hole(struct xdr_stream *xdr, struct nfs_pgio_res *re
static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
{
	uint32_t eof, segments, type;
	int status;
	int status, i;
	__be32 *p;

	status = decode_op_hdr(xdr, OP_READ_PLUS);
@@ -1086,6 +1086,7 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
	if (segments == 0)
		goto out;

	for (i = 0; i < segments; i++) {
		p = xdr_inline_decode(xdr, 4);
		if (unlikely(!p))
			return -EIO;
@@ -1098,10 +1099,11 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
		else
			return -EINVAL;

	if (status)
		if (status < 0)
			return status;
	if (segments > 1)
		eof = 0;
		if (status > 0)
			break;
	}

out:
	res->eof = eof;