[pnfs] [PATCH 08/10] pnfsd: Update getdeviceinfo for draft-19

Dean Hildebrand seattleplus at gmail.com
Thu Feb 7 21:58:55 EST 2008


Signed-off-by: Dean Hildebrand <dhildeb at us.ibm.com>
---
 fs/nfsd/nfs4xdr.c               |   64 +++++++++++++++++++++++++++++---------
 include/linux/exportfs.h        |    9 +++--
 include/linux/nfsd/nfsd4_pnfs.h |    1 +
 3 files changed, 55 insertions(+), 19 deletions(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 045bd20..6f7e2ff 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1250,16 +1250,25 @@ nfsd4_decode_getdevlist(struct nfsd4_compoundargs *argp,
 	DECODE_TAIL;
 }
 
+/* GETDEVICEINFO: minorversion1-19.txt
+u32             pnfs_deviceid4                  device_id;
+u32             pnfs_layouttype4                layout_type;
+u32             count4                          maxcount;
+u32             bitmap4                         device_notify_types;
+*/
 static int
 nfsd4_decode_getdevinfo(struct nfsd4_compoundargs *argp,
 			struct nfsd4_pnfs_getdevinfo *gdev)
 {
+	int num;
 	DECODE_HEAD;
 
-	READ_BUF(8 + sizeof(deviceid_t));
+	READ_BUF(16 + sizeof(deviceid_t));
 	COPYMEM(&gdev->gd_devid, sizeof(deviceid_t));
 	READ32(gdev->gd_type);
 	READ32(gdev->gd_maxcount);
+	READ32(num);
+	READ32(gdev->gd_notify_types);
 
 	DECODE_TAIL;
 }
@@ -3377,7 +3386,8 @@ nfsd4_encode_getdevinfo(struct nfsd4_compoundres *resp,
 {
 	struct pnfs_devinfo_arg args;
 	struct super_block *sb;
-	int maxcount;
+	int maxcount = 0;
+	u32 *p_in = resp->p;
 
 	ENCODE_HEAD;
 
@@ -3393,25 +3403,29 @@ nfsd4_encode_getdevinfo(struct nfsd4_compoundres *resp,
 	if (gdev->gd_type == LAYOUT_NFSV4_FILES)
 		args.func = filelayout_encode_devinfo;
 
+	/* If maxcount is 0 then just update notifications */
+	if (gdev->gd_maxcount != 0) {
+		maxcount = PAGE_SIZE;
+		if (maxcount > gdev->gd_maxcount)
+			maxcount = gdev->gd_maxcount;
+
+		/* Ensure have room for type and notify field */
+		maxcount -= 12;
+		if (maxcount < 0) {
+			nfserr = -ETOOSMALL;
+			goto toosmall;
+		}
+	}
+
 	RESERVE_SPACE(4);
 	WRITE32(gdev->gd_type);
 	ADJUST_ARGS();
 
-	maxcount = PAGE_SIZE;
-	if (maxcount > gdev->gd_maxcount)
-		maxcount = gdev->gd_maxcount;
-
-	/* Ensure have room for type field */
-	maxcount -= 4;
-	if (maxcount < 0) {
-		printk(KERN_ERR "%s: buffer too small\n", __func__);
-		return  nfserr_toosmall;
-	}
-
 	/* Set layout type and id of device to encode */
 	args.type = gdev->gd_type;
 	args.devid.pnfs_fsid = gdev->gd_devid.pnfs_fsid;
 	args.devid.pnfs_devid = gdev->gd_devid.pnfs_devid;
+	args.notify_types = gdev->gd_notify_types;
 
 	/* Set xdr info so file system can encode device */
 	args.xdr.p   = resp->p;
@@ -3421,8 +3435,13 @@ nfsd4_encode_getdevinfo(struct nfsd4_compoundres *resp,
 	/* Call file system to retrieve and encode device */
 	nfserr = sb->s_export_op->get_device_info(sb, &args);
 	if (nfserr) {
+		/* Rewind to the beginning */
+		p = p_in;
+		ADJUST_ARGS();
+		if (nfserr == -ETOOSMALL)
+			goto toosmall;
 		printk(KERN_ERR "%s: export ERROR %d\n", __func__, nfserr);
-		return nfserrno(nfserr);
+		goto out;
 	}
 
 	/* The file system should never write 0 bytes without
@@ -3435,7 +3454,22 @@ nfsd4_encode_getdevinfo(struct nfsd4_compoundres *resp,
 	 */
 	p += XDR_QUADLEN(args.xdr.bytes_written);
 	ADJUST_ARGS();
-	return nfs_ok;
+
+	/* Encode supported device notifications */
+	RESERVE_SPACE(8);
+	WRITE32(1);
+	WRITE32(args.notify_types);
+	ADJUST_ARGS();
+
+out:
+	return nfserrno(nfserr);
+toosmall:
+	dprintk("%s: maxcount too small\n", __func__);
+	RESERVE_SPACE(4);
+	/* TODO: For now just return the min size as a page */
+	WRITE32(PAGE_SIZE);
+	ADJUST_ARGS();
+	goto out;
 }
 
 /* LAYOUTGET: minorversion1-19.txt
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
index 6048e7b..d7612db 100644
--- a/include/linux/exportfs.h
+++ b/include/linux/exportfs.h
@@ -68,10 +68,11 @@ typedef int (*pnfs_encodedev_t)(struct pnfs_xdr_info *xdr, void *device);
 
 /* Arguments for get_device_info */
 struct pnfs_devinfo_arg {
-	u32 type;
-	deviceid_t devid;
-	struct pnfs_xdr_info xdr;
-	pnfs_encodedev_t func;
+	u32 type;			/* request */
+	deviceid_t devid;		/* request */
+	u32 notify_types;		/* request/response */
+	struct pnfs_xdr_info xdr;	/* request/response */
+	pnfs_encodedev_t func;		/* request */
 };
 
 /* Used by get_device_iter to retrieve all available devices.
diff --git a/include/linux/nfsd/nfsd4_pnfs.h b/include/linux/nfsd/nfsd4_pnfs.h
index c917cb7..9a92fcc 100644
--- a/include/linux/nfsd/nfsd4_pnfs.h
+++ b/include/linux/nfsd/nfsd4_pnfs.h
@@ -58,6 +58,7 @@ struct nfsd4_pnfs_getdevinfo {
 	u32		gd_type;	/* request */
 	deviceid_t	gd_devid;	/* request */
 	u32		gd_maxcount;	/* request */
+	u32		gd_notify_types; /* request */
 	struct svc_fh	*gd_fhp;	/* response */
 };
 
-- 
1.5.3.3



More information about the pNFS mailing list