nfs: nfs4xdr: get rid of READ_BUF
authorBenny Halevy <bhalevy@panasas.com>
Fri, 14 Aug 2009 14:20:14 +0000 (17:20 +0300)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Fri, 14 Aug 2009 18:02:23 +0000 (14:02 -0400)
Use xdr_inline_decode instead.
Open code debug printout and error return.

Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/nfs4xdr.c

index 3f49da0960e3d3e6c68a56087ee5404bb8091cdc..b0d690c3a24c664222993223224a96a365ee5353 100644 (file)
@@ -2423,24 +2423,6 @@ static int nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, uint32_t *p,
 }
 #endif /* CONFIG_NFS_V4_1 */
 
-/*
- * START OF "GENERIC" DECODE ROUTINES.
- *   These may look a little ugly since they are imported from a "generic"
- * set of XDR encode/decode routines which are intended to be shared by
- * all of our NFSv4 implementations (OpenBSD, MacOS X...).
- *
- * If the pain of reading these is too great, it should be a straightforward
- * task to translate them into Linux-specific versions which are more
- * consistent with the style used in NFSv2/v3...
- */
-#define READ_BUF(nbytes)  do { \
-       p = xdr_inline_decode(xdr, nbytes); \
-       if (unlikely(!p)) { \
-               print_overflow_msg(__func__, xdr); \
-               return -EIO; \
-       } \
-} while (0)
-
 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
 {
        dprintk("nfs: %s: prematurely hit end of receive buffer. "
@@ -2452,28 +2434,42 @@ static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char
 {
        __be32 *p;
 
-       READ_BUF(4);
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               goto out_overflow;
        *len = be32_to_cpup(p++);
-       READ_BUF(*len);
+       p = xdr_inline_decode(xdr, *len);
+       if (unlikely(!p))
+               goto out_overflow;
        *string = (char *)p;
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
 {
        __be32 *p;
 
-       READ_BUF(8);
+       p = xdr_inline_decode(xdr, 8);
+       if (unlikely(!p))
+               goto out_overflow;
        hdr->status = be32_to_cpup(p++);
        hdr->taglen = be32_to_cpup(p++);
 
-       READ_BUF(hdr->taglen + 4);
+       p = xdr_inline_decode(xdr, hdr->taglen + 4);
+       if (unlikely(!p))
+               goto out_overflow;
        hdr->tag = (char *)p;
        p += XDR_QUADLEN(hdr->taglen);
        hdr->nops = be32_to_cpup(p++);
        if (unlikely(hdr->nops < 1))
                return nfs4_stat_to_errno(hdr->status);
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
@@ -2482,7 +2478,9 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
        uint32_t opnum;
        int32_t nfserr;
 
-       READ_BUF(8);
+       p = xdr_inline_decode(xdr, 8);
+       if (unlikely(!p))
+               goto out_overflow;
        opnum = be32_to_cpup(p++);
        if (opnum != expected) {
                dprintk("nfs: Server returned operation"
@@ -2494,6 +2492,9 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
        if (nfserr != NFS_OK)
                return nfs4_stat_to_errno(nfserr);
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 /* Dummy routine */
@@ -2503,8 +2504,11 @@ static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp)
        unsigned int strlen;
        char *str;
 
-       READ_BUF(12);
-       return decode_opaque_inline(xdr, &strlen, &str);
+       p = xdr_inline_decode(xdr, 12);
+       if (likely(p))
+               return decode_opaque_inline(xdr, &strlen, &str);
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
@@ -2512,27 +2516,39 @@ static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
        uint32_t bmlen;
        __be32 *p;
 
-       READ_BUF(4);
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               goto out_overflow;
        bmlen = be32_to_cpup(p++);
 
        bitmap[0] = bitmap[1] = 0;
-       READ_BUF((bmlen << 2));
+       p = xdr_inline_decode(xdr, (bmlen << 2));
+       if (unlikely(!p))
+               goto out_overflow;
        if (bmlen > 0) {
                bitmap[0] = be32_to_cpup(p++);
                if (bmlen > 1)
                        bitmap[1] = be32_to_cpup(p++);
        }
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static inline int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, __be32 **savep)
 {
        __be32 *p;
 
-       READ_BUF(4);
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               goto out_overflow;
        *attrlen = be32_to_cpup(p++);
        *savep = xdr->p;
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask)
@@ -2555,7 +2571,9 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *
        if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) {
-               READ_BUF(4);
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       goto out_overflow;
                *type = be32_to_cpup(p++);
                if (*type < NF4REG || *type > NF4NAMEDATTR) {
                        dprintk("%s: bad type %d\n", __func__, *type);
@@ -2566,6 +2584,9 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *
        }
        dprintk("%s: type=0%o\n", __func__, nfs_type2fmt[*type]);
        return ret;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change)
@@ -2577,7 +2598,9 @@ static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t
        if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) {
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, change);
                bitmap[0] &= ~FATTR4_WORD0_CHANGE;
                ret = NFS_ATTR_FATTR_CHANGE;
@@ -2585,6 +2608,9 @@ static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t
        dprintk("%s: change attribute=%Lu\n", __func__,
                        (unsigned long long)*change);
        return ret;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size)
@@ -2596,13 +2622,18 @@ static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *
        if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) {
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, size);
                bitmap[0] &= ~FATTR4_WORD0_SIZE;
                ret = NFS_ATTR_FATTR_SIZE;
        }
        dprintk("%s: file size=%Lu\n", __func__, (unsigned long long)*size);
        return ret;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
@@ -2613,12 +2644,17 @@ static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, ui
        if (unlikely(bitmap[0] & (FATTR4_WORD0_LINK_SUPPORT - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) {
-               READ_BUF(4);
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       goto out_overflow;
                *res = be32_to_cpup(p++);
                bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT;
        }
        dprintk("%s: link support=%s\n", __func__, *res == 0 ? "false" : "true");
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
@@ -2629,12 +2665,17 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap,
        if (unlikely(bitmap[0] & (FATTR4_WORD0_SYMLINK_SUPPORT - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) {
-               READ_BUF(4);
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       goto out_overflow;
                *res = be32_to_cpup(p++);
                bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT;
        }
        dprintk("%s: symlink support=%s\n", __func__, *res == 0 ? "false" : "true");
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid)
@@ -2647,7 +2688,9 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs
        if (unlikely(bitmap[0] & (FATTR4_WORD0_FSID - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_FSID)) {
-               READ_BUF(16);
+               p = xdr_inline_decode(xdr, 16);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, &fsid->major);
                p = xdr_decode_hyper(p, &fsid->minor);
                bitmap[0] &= ~FATTR4_WORD0_FSID;
@@ -2657,6 +2700,9 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs
                        (unsigned long long)fsid->major,
                        (unsigned long long)fsid->minor);
        return ret;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
@@ -2667,12 +2713,17 @@ static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint
        if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) {
-               READ_BUF(4);
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       goto out_overflow;
                *res = be32_to_cpup(p++);
                bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME;
        }
        dprintk("%s: file size=%u\n", __func__, (unsigned int)*res);
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
@@ -2683,12 +2734,17 @@ static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint
        if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) {
-               READ_BUF(4);
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       goto out_overflow;
                *res = be32_to_cpup(p++);
                bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT;
        }
        dprintk("%s: ACLs supported=%u\n", __func__, (unsigned int)*res);
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
@@ -2700,13 +2756,18 @@ static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t
        if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) {
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, fileid);
                bitmap[0] &= ~FATTR4_WORD0_FILEID;
                ret = NFS_ATTR_FATTR_FILEID;
        }
        dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid);
        return ret;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
@@ -2718,13 +2779,18 @@ static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitma
        if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U)))
                return -EIO;
        if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) {
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, fileid);
                bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
                ret = NFS_ATTR_FATTR_FILEID;
        }
        dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid);
        return ret;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
@@ -2736,12 +2802,17 @@ static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin
        if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_AVAIL - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) {
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, res);
                bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL;
        }
        dprintk("%s: files avail=%Lu\n", __func__, (unsigned long long)*res);
        return status;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
@@ -2753,12 +2824,17 @@ static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint
        if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_FREE - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_FILES_FREE)) {
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, res);
                bitmap[0] &= ~FATTR4_WORD0_FILES_FREE;
        }
        dprintk("%s: files free=%Lu\n", __func__, (unsigned long long)*res);
        return status;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
@@ -2770,12 +2846,17 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin
        if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_TOTAL - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_FILES_TOTAL)) {
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, res);
                bitmap[0] &= ~FATTR4_WORD0_FILES_TOTAL;
        }
        dprintk("%s: files total=%Lu\n", __func__, (unsigned long long)*res);
        return status;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path)
@@ -2784,7 +2865,9 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path)
        __be32 *p;
        int status = 0;
 
-       READ_BUF(4);
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               goto out_overflow;
        n = be32_to_cpup(p++);
        if (n == 0)
                goto root_path;
@@ -2819,6 +2902,9 @@ out_eio:
        dprintk(" status %d", status);
        status = -EIO;
        goto out;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res)
@@ -2836,7 +2922,9 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
        status = decode_pathname(xdr, &res->fs_path);
        if (unlikely(status != 0))
                goto out;
-       READ_BUF(4);
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               goto out_overflow;
        n = be32_to_cpup(p++);
        if (n <= 0)
                goto out_eio;
@@ -2845,7 +2933,9 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
                u32 m;
                struct nfs4_fs_location *loc = &res->locations[res->nlocations];
 
-               READ_BUF(4);
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       goto out_overflow;
                m = be32_to_cpup(p++);
 
                loc->nservers = 0;
@@ -2885,6 +2975,8 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
 out:
        dprintk("%s: fs_locations done, error = %d\n", __func__, status);
        return status;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
 out_eio:
        status = -EIO;
        goto out;
@@ -2899,12 +2991,17 @@ static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uin
        if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXFILESIZE - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) {
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, res);
                bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE;
        }
        dprintk("%s: maxfilesize=%Lu\n", __func__, (unsigned long long)*res);
        return status;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink)
@@ -2916,12 +3013,17 @@ static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_
        if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXLINK - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) {
-               READ_BUF(4);
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       goto out_overflow;
                *maxlink = be32_to_cpup(p++);
                bitmap[0] &= ~FATTR4_WORD0_MAXLINK;
        }
        dprintk("%s: maxlink=%u\n", __func__, *maxlink);
        return status;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname)
@@ -2933,12 +3035,17 @@ static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_
        if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXNAME - 1U)))
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) {
-               READ_BUF(4);
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       goto out_overflow;
                *maxname = be32_to_cpup(p++);
                bitmap[0] &= ~FATTR4_WORD0_MAXNAME;
        }
        dprintk("%s: maxname=%u\n", __func__, *maxname);
        return status;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
@@ -2951,7 +3058,9 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_MAXREAD)) {
                uint64_t maxread;
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, &maxread);
                if (maxread > 0x7FFFFFFF)
                        maxread = 0x7FFFFFFF;
@@ -2960,6 +3069,9 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_
        }
        dprintk("%s: maxread=%lu\n", __func__, (unsigned long)*res);
        return status;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
@@ -2972,7 +3084,9 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_MAXWRITE)) {
                uint64_t maxwrite;
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, &maxwrite);
                if (maxwrite > 0x7FFFFFFF)
                        maxwrite = 0x7FFFFFFF;
@@ -2981,6 +3095,9 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32
        }
        dprintk("%s: maxwrite=%lu\n", __func__, (unsigned long)*res);
        return status;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *mode)
@@ -2993,7 +3110,9 @@ static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *m
        if (unlikely(bitmap[1] & (FATTR4_WORD1_MODE - 1U)))
                return -EIO;
        if (likely(bitmap[1] & FATTR4_WORD1_MODE)) {
-               READ_BUF(4);
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       goto out_overflow;
                tmp = be32_to_cpup(p++);
                *mode = tmp & ~S_IFMT;
                bitmap[1] &= ~FATTR4_WORD1_MODE;
@@ -3001,6 +3120,9 @@ static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *m
        }
        dprintk("%s: file mode=0%o\n", __func__, (unsigned int)*mode);
        return ret;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink)
@@ -3012,13 +3134,18 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t
        if (unlikely(bitmap[1] & (FATTR4_WORD1_NUMLINKS - 1U)))
                return -EIO;
        if (likely(bitmap[1] & FATTR4_WORD1_NUMLINKS)) {
-               READ_BUF(4);
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       goto out_overflow;
                *nlink = be32_to_cpup(p++);
                bitmap[1] &= ~FATTR4_WORD1_NUMLINKS;
                ret = NFS_ATTR_FATTR_NLINK;
        }
        dprintk("%s: nlink=%u\n", __func__, (unsigned int)*nlink);
        return ret;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *uid)
@@ -3031,9 +3158,13 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf
        if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U)))
                return -EIO;
        if (likely(bitmap[1] & FATTR4_WORD1_OWNER)) {
-               READ_BUF(4);
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       goto out_overflow;
                len = be32_to_cpup(p++);
-               READ_BUF(len);
+               p = xdr_inline_decode(xdr, len);
+               if (unlikely(!p))
+                       goto out_overflow;
                if (len < XDR_MAX_NETOBJ) {
                        if (nfs_map_name_to_uid(clp, (char *)p, len, uid) == 0)
                                ret = NFS_ATTR_FATTR_OWNER;
@@ -3047,6 +3178,9 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf
        }
        dprintk("%s: uid=%d\n", __func__, (int)*uid);
        return ret;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *gid)
@@ -3059,9 +3193,13 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf
        if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U)))
                return -EIO;
        if (likely(bitmap[1] & FATTR4_WORD1_OWNER_GROUP)) {
-               READ_BUF(4);
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       goto out_overflow;
                len = be32_to_cpup(p++);
-               READ_BUF(len);
+               p = xdr_inline_decode(xdr, len);
+               if (unlikely(!p))
+                       goto out_overflow;
                if (len < XDR_MAX_NETOBJ) {
                        if (nfs_map_group_to_gid(clp, (char *)p, len, gid) == 0)
                                ret = NFS_ATTR_FATTR_GROUP;
@@ -3075,6 +3213,9 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf
        }
        dprintk("%s: gid=%d\n", __func__, (int)*gid);
        return ret;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev)
@@ -3089,7 +3230,9 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde
        if (likely(bitmap[1] & FATTR4_WORD1_RAWDEV)) {
                dev_t tmp;
 
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                major = be32_to_cpup(p++);
                minor = be32_to_cpup(p++);
                tmp = MKDEV(major, minor);
@@ -3100,6 +3243,9 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde
        }
        dprintk("%s: rdev=(0x%x:0x%x)\n", __func__, major, minor);
        return ret;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
@@ -3111,12 +3257,17 @@ static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin
        if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_AVAIL - 1U)))
                return -EIO;
        if (likely(bitmap[1] & FATTR4_WORD1_SPACE_AVAIL)) {
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, res);
                bitmap[1] &= ~FATTR4_WORD1_SPACE_AVAIL;
        }
        dprintk("%s: space avail=%Lu\n", __func__, (unsigned long long)*res);
        return status;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
@@ -3128,12 +3279,17 @@ static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint
        if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_FREE - 1U)))
                return -EIO;
        if (likely(bitmap[1] & FATTR4_WORD1_SPACE_FREE)) {
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, res);
                bitmap[1] &= ~FATTR4_WORD1_SPACE_FREE;
        }
        dprintk("%s: space free=%Lu\n", __func__, (unsigned long long)*res);
        return status;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
@@ -3145,12 +3301,17 @@ static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uin
        if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_TOTAL - 1U)))
                return -EIO;
        if (likely(bitmap[1] & FATTR4_WORD1_SPACE_TOTAL)) {
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, res);
                bitmap[1] &= ~FATTR4_WORD1_SPACE_TOTAL;
        }
        dprintk("%s: space total=%Lu\n", __func__, (unsigned long long)*res);
        return status;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used)
@@ -3162,7 +3323,9 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint
        if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_USED - 1U)))
                return -EIO;
        if (likely(bitmap[1] & FATTR4_WORD1_SPACE_USED)) {
-               READ_BUF(8);
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, used);
                bitmap[1] &= ~FATTR4_WORD1_SPACE_USED;
                ret = NFS_ATTR_FATTR_SPACE_USED;
@@ -3170,6 +3333,9 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint
        dprintk("%s: space used=%Lu\n", __func__,
                        (unsigned long long)*used);
        return ret;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time)
@@ -3178,12 +3344,17 @@ static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time)
        uint64_t sec;
        uint32_t nsec;
 
-       READ_BUF(12);
+       p = xdr_inline_decode(xdr, 12);
+       if (unlikely(!p))
+               goto out_overflow;
        p = xdr_decode_hyper(p, &sec);
        nsec = be32_to_cpup(p++);
        time->tv_sec = (time_t)sec;
        time->tv_nsec = (long)nsec;
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
@@ -3261,11 +3432,16 @@ static int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *c
 {
        __be32 *p;
 
-       READ_BUF(20);
+       p = xdr_inline_decode(xdr, 20);
+       if (unlikely(!p))
+               goto out_overflow;
        cinfo->atomic = be32_to_cpup(p++);
        p = xdr_decode_hyper(p, &cinfo->before);
        p = xdr_decode_hyper(p, &cinfo->after);
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access)
@@ -3277,12 +3453,17 @@ static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access)
        status = decode_op_hdr(xdr, OP_ACCESS);
        if (status)
                return status;
-       READ_BUF(8);
+       p = xdr_inline_decode(xdr, 8);
+       if (unlikely(!p))
+               goto out_overflow;
        supp = be32_to_cpup(p++);
        acc = be32_to_cpup(p++);
        access->supported = supp;
        access->access = acc;
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_opaque_fixed(struct xdr_stream *xdr, void *buf, size_t len)
@@ -3341,10 +3522,16 @@ static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
                return status;
        if ((status = decode_change_info(xdr, cinfo)))
                return status;
-       READ_BUF(4);
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               goto out_overflow;
        bmlen = be32_to_cpup(p++);
-       READ_BUF(bmlen << 2);
-       return 0;
+       p = xdr_inline_decode(xdr, bmlen << 2);
+       if (likely(p))
+               return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res)
@@ -3596,14 +3783,21 @@ static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh)
        if (status)
                return status;
 
-       READ_BUF(4);
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               goto out_overflow;
        len = be32_to_cpup(p++);
        if (len > NFS4_FHSIZE)
                return -EIO;
        fh->size = len;
-       READ_BUF(len);
+       p = xdr_inline_decode(xdr, len);
+       if (unlikely(!p))
+               goto out_overflow;
        memcpy(fh->data, p, len);
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
@@ -3625,7 +3819,9 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl)
        __be32 *p;
        uint32_t namelen, type;
 
-       READ_BUF(32);
+       p = xdr_inline_decode(xdr, 32);
+       if (unlikely(!p))
+               goto out_overflow;
        p = xdr_decode_hyper(p, &offset);
        p = xdr_decode_hyper(p, &length);
        type = be32_to_cpup(p++);
@@ -3641,8 +3837,12 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl)
        }
        p = xdr_decode_hyper(p, &clientid);
        namelen = be32_to_cpup(p++);
-       READ_BUF(namelen);
-       return -NFS4ERR_DENIED;
+       p = xdr_inline_decode(xdr, namelen);
+       if (likely(p))
+               return -NFS4ERR_DENIED;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res)
@@ -3697,7 +3897,9 @@ static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize)
        __be32 *p;
        uint32_t limit_type, nblocks, blocksize;
 
-       READ_BUF(12);
+       p = xdr_inline_decode(xdr, 12);
+       if (unlikely(!p))
+               goto out_overflow;
        limit_type = be32_to_cpup(p++);
        switch (limit_type) {
        case 1:
@@ -3709,6 +3911,9 @@ static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize)
                *maxsize = (uint64_t)nblocks * (uint64_t)blocksize;
        }
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
@@ -3717,7 +3922,9 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
        uint32_t delegation_type;
        int status;
 
-       READ_BUF(4);
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               goto out_overflow;
        delegation_type = be32_to_cpup(p++);
        if (delegation_type == NFS4_OPEN_DELEGATE_NONE) {
                res->delegation_type = 0;
@@ -3726,7 +3933,9 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
        status = decode_stateid(xdr, &res->delegation);
        if (unlikely(status))
                return status;
-       READ_BUF(4);
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               goto out_overflow;
        res->do_recall = be32_to_cpup(p++);
 
        switch (delegation_type) {
@@ -3739,6 +3948,9 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
                                return -EIO;
        }
        return decode_ace(xdr, NULL, res->server->nfs_client);
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
@@ -3757,13 +3969,17 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
 
        decode_change_info(xdr, &res->cinfo);
 
-       READ_BUF(8);
+       p = xdr_inline_decode(xdr, 8);
+       if (unlikely(!p))
+               goto out_overflow;
        res->rflags = be32_to_cpup(p++);
        bmlen = be32_to_cpup(p++);
        if (bmlen > 10)
                goto xdr_error;
 
-       READ_BUF(bmlen << 2);
+       p = xdr_inline_decode(xdr, bmlen << 2);
+       if (unlikely(!p))
+               goto out_overflow;
        savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE);
        for (i = 0; i < savewords; ++i)
                res->attrset[i] = be32_to_cpup(p++);
@@ -3774,6 +3990,9 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
 xdr_error:
        dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen);
        return -EIO;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res)
@@ -3820,7 +4039,9 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_
        status = decode_op_hdr(xdr, OP_READ);
        if (status)
                return status;
-       READ_BUF(8);
+       p = xdr_inline_decode(xdr, 8);
+       if (unlikely(!p))
+               goto out_overflow;
        eof = be32_to_cpup(p++);
        count = be32_to_cpup(p++);
        hdrlen = (u8 *) p - (u8 *) iov->iov_base;
@@ -3835,6 +4056,9 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_
        res->eof = eof;
        res->count = count;
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir)
@@ -3947,7 +4171,9 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
                return status;
 
        /* Convert length of symlink */
-       READ_BUF(4);
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               goto out_overflow;
        len = be32_to_cpup(p++);
        if (len >= rcvbuf->page_len || len <= 0) {
                dprintk("nfs: server returned giant symlink!\n");
@@ -3972,6 +4198,9 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
        kaddr[len+rcvbuf->page_base] = '\0';
        kunmap_atomic(kaddr, KM_USER0);
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
@@ -4069,10 +4298,16 @@ static int decode_setattr(struct xdr_stream *xdr)
        status = decode_op_hdr(xdr, OP_SETATTR);
        if (status)
                return status;
-       READ_BUF(4);
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               goto out_overflow;
        bmlen = be32_to_cpup(p++);
-       READ_BUF(bmlen << 2);
-       return 0;
+       p = xdr_inline_decode(xdr, bmlen << 2);
+       if (likely(p))
+               return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
@@ -4081,7 +4316,9 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
        uint32_t opnum;
        int32_t nfserr;
 
-       READ_BUF(8);
+       p = xdr_inline_decode(xdr, 8);
+       if (unlikely(!p))
+               goto out_overflow;
        opnum = be32_to_cpup(p++);
        if (opnum != OP_SETCLIENTID) {
                dprintk("nfs: decode_setclientid: Server returned operation"
@@ -4090,26 +4327,39 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
        }
        nfserr = be32_to_cpup(p++);
        if (nfserr == NFS_OK) {
-               READ_BUF(8 + NFS4_VERIFIER_SIZE);
+               p = xdr_inline_decode(xdr, 8 + NFS4_VERIFIER_SIZE);
+               if (unlikely(!p))
+                       goto out_overflow;
                p = xdr_decode_hyper(p, &clp->cl_clientid);
                memcpy(clp->cl_confirm.data, p, NFS4_VERIFIER_SIZE);
        } else if (nfserr == NFSERR_CLID_INUSE) {
                uint32_t len;
 
                /* skip netid string */
-               READ_BUF(4);
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       goto out_overflow;
                len = be32_to_cpup(p++);
-               READ_BUF(len);
+               p = xdr_inline_decode(xdr, len);
+               if (unlikely(!p))
+                       goto out_overflow;
 
                /* skip uaddr string */
-               READ_BUF(4);
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       goto out_overflow;
                len = be32_to_cpup(p++);
-               READ_BUF(len);
+               p = xdr_inline_decode(xdr, len);
+               if (unlikely(!p))
+                       goto out_overflow;
                return -NFSERR_CLID_INUSE;
        } else
                return nfs4_stat_to_errno(nfserr);
 
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_setclientid_confirm(struct xdr_stream *xdr)
@@ -4126,11 +4376,16 @@ static int decode_write(struct xdr_stream *xdr, struct nfs_writeres *res)
        if (status)
                return status;
 
-       READ_BUF(16);
+       p = xdr_inline_decode(xdr, 16);
+       if (unlikely(!p))
+               goto out_overflow;
        res->count = be32_to_cpup(p++);
        res->verf->committed = be32_to_cpup(p++);
        memcpy(res->verf->verifier, p, 8);
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_delegreturn(struct xdr_stream *xdr)
@@ -4152,9 +4407,13 @@ static int decode_exchange_id(struct xdr_stream *xdr,
        if (status)
                return status;
 
-       READ_BUF(8);
+       p = xdr_inline_decode(xdr, 8);
+       if (unlikely(!p))
+               goto out_overflow;
        p = xdr_decode_hyper(p, &clp->cl_ex_clid);
-       READ_BUF(12);
+       p = xdr_inline_decode(xdr, 12);
+       if (unlikely(!p))
+               goto out_overflow;
        clp->cl_seqid = be32_to_cpup(p++);
        clp->cl_exchange_flags = be32_to_cpup(p++);
 
@@ -4164,7 +4423,9 @@ static int decode_exchange_id(struct xdr_stream *xdr,
                return -EIO;
 
        /* Throw away minor_id */
-       READ_BUF(8);
+       p = xdr_inline_decode(xdr, 8);
+       if (unlikely(!p))
+               goto out_overflow;
 
        /* Throw away Major id */
        status = decode_opaque_inline(xdr, &dummy, &dummy_str);
@@ -4182,6 +4443,9 @@ static int decode_exchange_id(struct xdr_stream *xdr,
                return status;
 
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_chan_attrs(struct xdr_stream *xdr,
@@ -4190,7 +4454,9 @@ static int decode_chan_attrs(struct xdr_stream *xdr,
        __be32 *p;
        u32 nr_attrs;
 
-       READ_BUF(28);
+       p = xdr_inline_decode(xdr, 28);
+       if (unlikely(!p))
+               goto out_overflow;
        attrs->headerpadsz = be32_to_cpup(p++);
        attrs->max_rqst_sz = be32_to_cpup(p++);
        attrs->max_resp_sz = be32_to_cpup(p++);
@@ -4203,9 +4469,15 @@ static int decode_chan_attrs(struct xdr_stream *xdr,
                        __func__, nr_attrs);
                return -EINVAL;
        }
-       if (nr_attrs == 1)
-               READ_BUF(4); /* skip rdma_attrs */
+       if (nr_attrs == 1) {
+               p = xdr_inline_decode(xdr, 4); /* skip rdma_attrs */
+               if (unlikely(!p))
+                       goto out_overflow;
+       }
        return 0;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_sessionid(struct xdr_stream *xdr, struct nfs4_sessionid *sid)
@@ -4228,7 +4500,9 @@ static int decode_create_session(struct xdr_stream *xdr,
                return status;
 
        /* seqid, flags */
-       READ_BUF(8);
+       p = xdr_inline_decode(xdr, 8);
+       if (unlikely(!p))
+               goto out_overflow;
        clp->cl_seqid = be32_to_cpup(p++);
        session->flags = be32_to_cpup(p++);
 
@@ -4237,6 +4511,9 @@ static int decode_create_session(struct xdr_stream *xdr,
        if (!status)
                status = decode_chan_attrs(xdr, &session->bc_attrs);
        return status;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       return -EIO;
 }
 
 static int decode_destroy_session(struct xdr_stream *xdr, void *dummy)
@@ -4277,7 +4554,9 @@ static int decode_sequence(struct xdr_stream *xdr,
                goto out_err;
        }
 
-       READ_BUF(20);
+       p = xdr_inline_decode(xdr, 20);
+       if (unlikely(!p))
+               goto out_overflow;
 
        /* seqid */
        slot = &res->sr_session->fc_slot_table.slots[res->sr_slotid];
@@ -4302,6 +4581,10 @@ static int decode_sequence(struct xdr_stream *xdr,
 out_err:
        res->sr_status = status;
        return status;
+out_overflow:
+       print_overflow_msg(__func__, xdr);
+       status = -EIO;
+       goto out_err;
 #else  /* CONFIG_NFS_V4_1 */
        return 0;
 #endif /* CONFIG_NFS_V4_1 */