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: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
@@ -53,7 +53,7 @@
|
|||||||
#define decode_read_plus_maxsz (op_decode_hdr_maxsz + \
|
#define decode_read_plus_maxsz (op_decode_hdr_maxsz + \
|
||||||
1 /* rpr_eof */ + \
|
1 /* rpr_eof */ + \
|
||||||
1 /* rpr_contents count */ + \
|
1 /* rpr_contents count */ + \
|
||||||
NFS42_READ_PLUS_SEGMENT_SIZE)
|
2 * NFS42_READ_PLUS_SEGMENT_SIZE)
|
||||||
#define encode_seek_maxsz (op_encode_hdr_maxsz + \
|
#define encode_seek_maxsz (op_encode_hdr_maxsz + \
|
||||||
encode_stateid_maxsz + \
|
encode_stateid_maxsz + \
|
||||||
2 /* offset */ + \
|
2 /* offset */ + \
|
||||||
@@ -1045,6 +1045,28 @@ static int decode_read_plus_data(struct xdr_stream *xdr, struct nfs_pgio_res *re
|
|||||||
return 0;
|
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)
|
static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
|
||||||
{
|
{
|
||||||
uint32_t eof, segments, type;
|
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++);
|
type = be32_to_cpup(p++);
|
||||||
if (type == NFS4_CONTENT_DATA)
|
if (type == NFS4_CONTENT_DATA)
|
||||||
status = decode_read_plus_data(xdr, res, &eof);
|
status = decode_read_plus_data(xdr, res, &eof);
|
||||||
|
else if (type == NFS4_CONTENT_HOLE)
|
||||||
|
status = decode_read_plus_hole(xdr, res, &eof);
|
||||||
else
|
else
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user