mirror of https://gitee.com/openkylin/linux.git
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: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
e6ac0accb2
commit
bff049a3b5
|
@ -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,22 +1086,24 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
|
|||
if (segments == 0)
|
||||
goto out;
|
||||
|
||||
p = xdr_inline_decode(xdr, 4);
|
||||
if (unlikely(!p))
|
||||
return -EIO;
|
||||
for (i = 0; i < segments; i++) {
|
||||
p = xdr_inline_decode(xdr, 4);
|
||||
if (unlikely(!p))
|
||||
return -EIO;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
if (segments > 1)
|
||||
eof = 0;
|
||||
if (status < 0)
|
||||
return status;
|
||||
if (status > 0)
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
res->eof = eof;
|
||||
|
|
Loading…
Reference in New Issue