@@ -570,6 +570,23 @@ nfsd4_decode_stateid4(struct nfsd4_compoundargs *argp, stateid_t *sid)
return nfserr_bad_xdr;
}
+#ifdef CONFIG_NFSD_PNFS
+static __be32
+nfsd4_decode_deviceid4(struct nfsd4_compoundargs *argp,
+ struct nfsd4_deviceid *devid)
+{
+ __be32 *p;
+
+ p = xdr_inline_decode(argp->xdr, NFS4_DEVICEID4_SIZE);
+ if (!p)
+ goto xdr_error;
+ memcpy(devid, p, sizeof(*devid));
+ return nfs_ok;
+xdr_error:
+ return nfserr_bad_xdr;
+}
+#endif /* CONFIG_NFSD_PNFS */
+
static __be32 nfsd4_decode_sessionid(struct nfsd4_compoundargs *argp,
struct nfs4_sessionid *sessionid)
{
@@ -1769,27 +1786,24 @@ static __be32
nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
struct nfsd4_getdeviceinfo *gdev)
{
- DECODE_HEAD;
- u32 num, i;
-
- READ_BUF(sizeof(struct nfsd4_deviceid) + 3 * 4);
- COPYMEM(&gdev->gd_devid, sizeof(struct nfsd4_deviceid));
- gdev->gd_layout_type = be32_to_cpup(p++);
- gdev->gd_maxcount = be32_to_cpup(p++);
- num = be32_to_cpup(p++);
- if (num) {
- if (num > 1000)
- goto xdr_error;
- READ_BUF(4 * num);
- gdev->gd_notify_types = be32_to_cpup(p++);
- for (i = 1; i < num; i++) {
- if (be32_to_cpup(p++)) {
- status = nfserr_inval;
- goto out;
- }
- }
- }
- DECODE_TAIL;
+ __be32 status;
+
+ status = nfsd4_decode_deviceid4(argp, &gdev->gd_devid);
+ if (status)
+ goto out;
+ if (xdr_stream_decode_u32(argp->xdr, &gdev->gd_layout_type) < 0)
+ goto xdr_error;
+ if (xdr_stream_decode_u32(argp->xdr, &gdev->gd_maxcount) < 0)
+ goto xdr_error;
+ status = nfsd4_decode_bitmap4(argp, &gdev->gd_notify_types, 1);
+ if (status)
+ goto out;
+
+ status = nfs_ok;
+out:
+ return status;
+xdr_error:
+ return nfserr_bad_xdr;
}
static __be32
Signed-off-by: Chuck Lever <chuck.lever@oracle.com> --- fs/nfsd/nfs4xdr.c | 56 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 21 deletions(-)