diff options
-rw-r--r-- | fs/nfs/nfs4xdr.c | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 5be2868c02f1..8c21d69a9dc1 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -3097,7 +3097,8 @@ out_overflow: | |||
3097 | return -EIO; | 3097 | return -EIO; |
3098 | } | 3098 | } |
3099 | 3099 | ||
3100 | static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) | 3100 | static bool __decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected, |
3101 | int *nfs_retval) | ||
3101 | { | 3102 | { |
3102 | __be32 *p; | 3103 | __be32 *p; |
3103 | uint32_t opnum; | 3104 | uint32_t opnum; |
@@ -3107,19 +3108,32 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) | |||
3107 | if (unlikely(!p)) | 3108 | if (unlikely(!p)) |
3108 | goto out_overflow; | 3109 | goto out_overflow; |
3109 | opnum = be32_to_cpup(p++); | 3110 | opnum = be32_to_cpup(p++); |
3110 | if (opnum != expected) { | 3111 | if (unlikely(opnum != expected)) |
3111 | dprintk("nfs: Server returned operation" | 3112 | goto out_bad_operation; |
3112 | " %d but we issued a request for %d\n", | ||
3113 | opnum, expected); | ||
3114 | return -EIO; | ||
3115 | } | ||
3116 | nfserr = be32_to_cpup(p); | 3113 | nfserr = be32_to_cpup(p); |
3117 | if (nfserr != NFS_OK) | 3114 | if (nfserr == NFS_OK) |
3118 | return nfs4_stat_to_errno(nfserr); | 3115 | *nfs_retval = 0; |
3119 | return 0; | 3116 | else |
3117 | *nfs_retval = nfs4_stat_to_errno(nfserr); | ||
3118 | return true; | ||
3119 | out_bad_operation: | ||
3120 | dprintk("nfs: Server returned operation" | ||
3121 | " %d but we issued a request for %d\n", | ||
3122 | opnum, expected); | ||
3123 | *nfs_retval = -EREMOTEIO; | ||
3124 | return false; | ||
3120 | out_overflow: | 3125 | out_overflow: |
3121 | print_overflow_msg(__func__, xdr); | 3126 | print_overflow_msg(__func__, xdr); |
3122 | return -EIO; | 3127 | *nfs_retval = -EIO; |
3128 | return false; | ||
3129 | } | ||
3130 | |||
3131 | static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) | ||
3132 | { | ||
3133 | int retval; | ||
3134 | |||
3135 | __decode_op_hdr(xdr, expected, &retval); | ||
3136 | return retval; | ||
3123 | } | 3137 | } |
3124 | 3138 | ||
3125 | /* Dummy routine */ | 3139 | /* Dummy routine */ |
@@ -5001,11 +5015,12 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) | |||
5001 | uint32_t savewords, bmlen, i; | 5015 | uint32_t savewords, bmlen, i; |
5002 | int status; | 5016 | int status; |
5003 | 5017 | ||
5004 | status = decode_op_hdr(xdr, OP_OPEN); | 5018 | if (!__decode_op_hdr(xdr, OP_OPEN, &status)) |
5005 | if (status != -EIO) | 5019 | return status; |
5006 | nfs_increment_open_seqid(status, res->seqid); | 5020 | nfs_increment_open_seqid(status, res->seqid); |
5007 | if (!status) | 5021 | if (status) |
5008 | status = decode_stateid(xdr, &res->stateid); | 5022 | return status; |
5023 | status = decode_stateid(xdr, &res->stateid); | ||
5009 | if (unlikely(status)) | 5024 | if (unlikely(status)) |
5010 | return status; | 5025 | return status; |
5011 | 5026 | ||