Skip to contentSkip to conversation

NFSv4.1 Fix gdia_maxcount calculation to fit in ca_maxresponsesize

PATCH New [email protected] 1 participant 4 messages Jun 25, 2013

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover NFSv4.1 Fix gdia_maxcount calculation to fit in ca_maxresponsesize

From: Andy Adamson <[email protected]>

Quoted 5 lines

From Trond:
The problem is that pdev->pglen is used both as the total buffer length, as a function argument and as the reply message length (through the call to xdr_init_decode_pages). We really should split out those 3 different roles...

AFAICS there are two roles: the reply or total message length used for xdr_init_decode_pages (where it is also a function argument) and the gdia_maxcount.

Put the block and object layout change in separate patches for ease of backporting.

-->Andy

Andy Adamson (3):
NFSv4.1 Fix gdia_maxcount calculation to fit in ca_maxresponsesize NFSv4.1 use pnfs_device maxcount for the blocklayout gdia_maxcount NFSv4.1 use pnfs_device maxcount for the objectlayout gdia_maxcount

 fs/nfs/blocklayout/blocklayout.c | 1 +
 fs/nfs/internal.h                | 1 +
 fs/nfs/nfs4filelayoutdev.c       | 1 +
 fs/nfs/nfs4xdr.c                 | 8 +++++++-
 fs/nfs/objlayout/objlayout.c     | 1 +
 fs/nfs/pnfs.h                    | 3 ++-
 6 files changed, 13 insertions(+), 2 deletions(-)
Signature · 1 line
1.7.11.7
#1 lore raw

PATCH 1/3 NFSv4.1 Fix gdia_maxcount calculation to fit in ca_maxresponsesize

From: Andy Adamson <[email protected]>

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.

---
 fs/nfs/internal.h          | 1 +
 fs/nfs/nfs4filelayoutdev.c | 1 +
 fs/nfs/nfs4xdr.c           | 8 +++++++-
 fs/nfs/pnfs.h              | 3 ++-
 4 files changed, 11 insertions(+), 2 deletions(-)
fs/nfs/internal.h +1 -0
index 97ec2ef..3c8373f 100644
@@ -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 */
fs/nfs/nfs4filelayoutdev.c +1 -0
index 0493dbd..95604f6 100644
@@ -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);
fs/nfs/nfs4xdr.c +7 -1
index 2a3f77e1..0abfb846 100644
@@ -867,6 +867,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[] = {
@@ -1924,7 +1930,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 */
 }
 
fs/nfs/pnfs.h +2 -1
index 1441dff..a4f4181 100644
@@ -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
Signature · 1 line
1.7.11.7
#2 lore raw

PATCH 2/3 NFSv4.1 use pnfs_device maxcount for the blocklayout gdia_maxcount

In reply to [email protected]

From: Andy Adamson <[email protected]>

---
 fs/nfs/blocklayout/blocklayout.c | 1 +
 1 file changed, 1 insertion(+)
fs/nfs/blocklayout/blocklayout.c +1 -0
index 1e5fdd3..e242bbf 100644
@@ -1089,6 +1089,7 @@ nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh,
 	dev->pgbase = 0;
 	dev->pglen = PAGE_SIZE * max_pages;
 	dev->mincount = 0;
+	dev->maxcount = max_resp_sz - nfs41_maxgetdevinfo_overhead;
 
 	dprintk("%s: dev_id: %s\n", __func__, dev->dev_id.data);
 	rc = nfs4_proc_getdeviceinfo(server, dev, NULL);
Signature · 1 line
1.7.11.7
#3 lore raw

PATCH 3/3 NFSv4.1 use pnfs_device maxcount for the objectlayout gdia_maxcount

In reply to [email protected]

From: Andy Adamson <[email protected]>

---
 fs/nfs/objlayout/objlayout.c | 1 +
 1 file changed, 1 insertion(+)
fs/nfs/objlayout/objlayout.c +1 -0
index 1989908..e4f9cbf 100644
@@ -613,6 +613,7 @@ int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay,
 	pd.pgbase = 0;
 	pd.pglen = PAGE_SIZE;
 	pd.mincount = 0;
+	pd.maxcount = PAGE_SIZE;
 
 	err = nfs4_proc_getdeviceinfo(NFS_SERVER(pnfslay->plh_inode), &pd,
 			pnfslay->plh_lc_cred);
Signature · 1 line
1.7.11.7