NFSv4.1 Fix gdia_maxcount calculation to fit in ca_maxresponsesize
authorAndy Adamson <andros@netapp.com>
Tue, 25 Jun 2013 23:02:53 +0000 (19:02 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Fri, 28 Jun 2013 19:34:43 +0000 (15:34 -0400)
The GETDEVICEINFO gdia_maxcount represents all of the data being returned
within the GETDEVICEINFO4resok structure and includes the XDR overhead.

The CREATE_SESSION ca_maxresponsesize is the maximum reply and includes the RPC
headers (including security flavor credentials and verifiers).

Split out the struct pnfs_device field maxcount which is the gdia_maxcount
from the pglen field which is the reply (the total) buffer length.

Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/internal.h
fs/nfs/nfs4filelayoutdev.c
fs/nfs/nfs4xdr.c
fs/nfs/pnfs.h

index 91e59a39fc08dcfd3b6b788cd9a3610e5d4b8984..4bd53f4e0fd2a758c6c2613030b663c7efd8eab1 100644 (file)
@@ -255,6 +255,7 @@ extern int nfs4_decode_dirent(struct xdr_stream *,
 #ifdef CONFIG_NFS_V4_1
 extern const u32 nfs41_maxread_overhead;
 extern const u32 nfs41_maxwrite_overhead;
+extern const u32 nfs41_maxgetdevinfo_overhead;
 #endif
 
 /* nfs4proc.c */
index 0493dbd129c51986f3788bedfb8c7870954e5d5b..95604f64cab86632d7a166ce588ea9ffd5d87e95 100644 (file)
@@ -711,6 +711,7 @@ filelayout_get_device_info(struct inode *inode,
        pdev->pgbase = 0;
        pdev->pglen = max_resp_sz;
        pdev->mincount = 0;
+       pdev->maxcount = max_resp_sz - nfs41_maxgetdevinfo_overhead;
 
        rc = nfs4_proc_getdeviceinfo(server, pdev, cred);
        dprintk("%s getdevice info returns %d\n", __func__, rc);
index 4be8d135ed61b19bc14f511b0013382211a64c0c..27cc76d88f9a430ebf403822aad98370c105528a 100644 (file)
@@ -853,6 +853,12 @@ const u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
                                     decode_sequence_maxsz +
                                     decode_putfh_maxsz) *
                                    XDR_UNIT);
+
+const u32 nfs41_maxgetdevinfo_overhead = ((RPC_MAX_REPHEADER_WITH_AUTH +
+                                          compound_decode_hdr_maxsz +
+                                          decode_sequence_maxsz) *
+                                         XDR_UNIT);
+EXPORT_SYMBOL_GPL(nfs41_maxgetdevinfo_overhead);
 #endif /* CONFIG_NFS_V4_1 */
 
 static const umode_t nfs_type2fmt[] = {
@@ -1889,7 +1895,7 @@ encode_getdeviceinfo(struct xdr_stream *xdr,
        p = xdr_encode_opaque_fixed(p, args->pdev->dev_id.data,
                                    NFS4_DEVICEID4_SIZE);
        *p++ = cpu_to_be32(args->pdev->layout_type);
-       *p++ = cpu_to_be32(args->pdev->pglen);          /* gdia_maxcount */
+       *p++ = cpu_to_be32(args->pdev->maxcount);       /* gdia_maxcount */
        *p++ = cpu_to_be32(0);                          /* bitmap length 0 */
 }
 
index 1441dff9b0e78c3811a9471b965ca88f7b510d4c..a4f41810a7f497fbe5b34d497d8c1a5078a44524 100644 (file)
@@ -149,9 +149,10 @@ struct pnfs_device {
        struct nfs4_deviceid dev_id;
        unsigned int  layout_type;
        unsigned int  mincount;
+       unsigned int  maxcount; /* gdia_maxcount */
        struct page **pages;
        unsigned int  pgbase;
-       unsigned int  pglen;
+       unsigned int  pglen;    /* reply buffer length */
 };
 
 #define NFS4_PNFS_GETDEVLIST_MAXNUM 16