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

NFS: Add READ_PLUS hole segment decoding



We keep things simple for now by only decoding a single hole or data
segment returned by the server, even if they returned more to us.

Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 84ce182a
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@
#define decode_read_plus_maxsz		(op_decode_hdr_maxsz + \
					 1 /* rpr_eof */ + \
					 1 /* rpr_contents count */ + \
					 NFS42_READ_PLUS_SEGMENT_SIZE)
					 2 * NFS42_READ_PLUS_SEGMENT_SIZE)
#define encode_seek_maxsz		(op_encode_hdr_maxsz + \
					 encode_stateid_maxsz + \
					 2 /* offset */ + \
@@ -1045,6 +1045,28 @@ static int decode_read_plus_data(struct xdr_stream *xdr, struct nfs_pgio_res *re
	return 0;
}

static int decode_read_plus_hole(struct xdr_stream *xdr, struct nfs_pgio_res *res,
				 uint32_t *eof)
{
	uint64_t offset, length, recvd;
	__be32 *p;

	p = xdr_inline_decode(xdr, 8 + 8);
	if (unlikely(!p))
		return -EIO;

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

	if (recvd < length) {
		*eof = 0;
		return 1;
	}
	return 0;
}

static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
{
	uint32_t eof, segments, type;
@@ -1071,6 +1093,8 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
	type = be32_to_cpup(p++);
	if (type == NFS4_CONTENT_DATA)
		status = decode_read_plus_data(xdr, res, &eof);
	else if (type == NFS4_CONTENT_HOLE)
		status = decode_read_plus_hole(xdr, res, &eof);
	else
		return -EINVAL;