Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx> --- fs/nfs/nfs4xdr.c | 30 +++++++++++++++++++++++------- include/linux/sunrpc/xdr.h | 1 + 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index b916297..2cf724d 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -2214,8 +2214,10 @@ static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) { __be32 *p; + xdr->status = -EIO; READ_BUF(8); READ32(hdr->status); + xdr->status = hdr->status; READ32(hdr->taglen); READ_BUF(hdr->taglen + 4); @@ -2225,24 +2227,38 @@ static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) return 0; } -static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) +static int +decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) { __be32 *p; uint32_t opnum; int32_t nfserr; - READ_BUF(8); + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) { + dprintk("nfs: %s: prematurely hit end of receive" + " buffer\n", __func__); + dprintk("nfs: %s: xdr->p=%p, bytes=%u, xdr->end=%p\n", + __func__, xdr->p, 8, xdr->end); + goto err; + } READ32(opnum); - if (opnum != expected) { + if (unlikely(opnum != expected)) { dprintk("nfs: Server returned operation" " %d but we issued a request for %d\n", opnum, expected); - return -EIO; + goto err; } READ32(nfserr); - if (nfserr != NFS_OK) - return nfs4_stat_to_errno(nfserr); - return 0; + if (likely(nfserr == NFS_OK)) + return 0; + xdr->status = nfserr; +err: + if (xdr->status != NFS_OK) + return nfs4_stat_to_errno(xdr->status); + dprintk("nfs: %s: xdr status %d, returning %d\n", + __func__, xdr->status, -EIO); + return -EIO; } /* Dummy routine */ diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index e4057d7..0c09ae5 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -208,6 +208,7 @@ struct xdr_stream { __be32 *end; /* end of available buffer space */ struct kvec *iov; /* pointer to the current kvec */ + int status; }; extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); -- 1.5.6.GIT -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html