[pnfs] [PATCH 07/10] pnfs: Move getdeviceinfo to draft-19 on client

Marc Eshel eshel at almaden.ibm.com
Sat Feb 9 03:26:23 EST 2008


From: Dean Hildebrand <dhildeb at us.ibm.com>

When the layout driver calls get_device_info, it needs
to make sure it sets the id and type in the device
argument.
---

 fs/nfs/nfs4filelayoutdev.c |    3 +++
 fs/nfs/nfs4proc.c          |    1 +
 fs/nfs/nfs4xdr.c           |   45 +++++++++++++++++++++++++++++++-------------
 include/linux/nfs4.h       |    6 ++++++
 include/linux/nfs4_pnfs.h  |    2 ++
 5 files changed, 44 insertions(+), 13 deletions(-)

diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index e407459..c18c766 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -656,6 +656,9 @@ get_device_info(struct filelayout_mount_type *mt,
 		return NULL;
 
 	memcpy(&pdev->dev_id, dev_id, NFS4_PNFS_DEVICEID4_SIZE);
+	pdev->layout_type = LAYOUT_NFSV4_FILES;
+	/* TODO: Update types when CB_NOTIFY_DEVICEID is available */
+	pdev->dev_notify_types = 0;
 
 	rc = pnfs_callback_ops->nfs_getdeviceinfo(mt->fl_sb, fh, pdev);
 	dprintk("%s getdevice info returns %d\n", __func__, rc);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 4e11c33..92f91da 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5365,6 +5365,7 @@ int nfs4_pnfs_getdeviceinfo(struct super_block *sb,
 		.fh = fh,
 		.dev_id = &dev->dev_id,
 		.layoutclass = server->pnfs_curr_ld->id,
+		.dev_notify_types = dev->dev_notify_types,
 	};
 	struct nfs4_pnfs_getdeviceinfo_res res = {
 		.dev = dev,
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index ea6d3e8..b932d0e 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -276,10 +276,10 @@ static int nr_sequence_quads;
 				    NFS4_PNFS_DEV_MAXNUM *		\
 				    (NFS4_PNFS_DEVICEID4_SIZE + 2 +	\
 				     NFS4_PNFS_DEV_MAXSIZE))
-#define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + 2 + \
-				    NFS4_PNFS_DEVICEID4_SIZE)
-#define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + 2 + \
-				   NFS4_PNFS_DEV_MAXSIZE)
+#define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + 4 + \
+				    XDR_QUADLEN(NFS4_PNFS_DEVICEID4_SIZE))
+#define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + 4 + \
+				    XDR_QUADLEN(NFS4_PNFS_DEV_MAXSIZE))
 #define encode_pnfs_layoutget_sz (op_encode_hdr_maxsz + 10 + encode_stateid_maxsz)
 #define decode_pnfs_layoutget_maxsz	(op_decode_hdr_maxsz + 8 + \
 					 decode_stateid_maxsz + \
@@ -1825,14 +1825,14 @@ static int encode_getdevicelist(struct xdr_stream *xdr, const struct nfs4_pnfs_g
 static int encode_getdeviceinfo(struct xdr_stream *xdr,
 				const struct nfs4_pnfs_getdeviceinfo_arg *args)
 {
-	uint32_t *p;
-
-	RESERVE_SPACE(12 + NFS4_PNFS_DEVICEID4_SIZE);
-
+	__be32 *p;
+	RESERVE_SPACE(20 + NFS4_PNFS_DEVICEID4_SIZE);
 	WRITE32(OP_GETDEVICEINFO);
 	WRITEMEM(args->dev_id->data, NFS4_PNFS_DEVICEID4_SIZE);
 	WRITE32(args->layoutclass);
 	WRITE32(NFS4_PNFS_DEV_MAXSIZE);
+	WRITE32(1); 				/* single bitmap */
+	WRITE32(args->dev_notify_types);
 	return 0;
 }
 
@@ -3386,6 +3386,9 @@ static int nfs41_xdr_enc_pnfs_getdeviceinfo(struct rpc_rqst *req,
 	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
 	encode_compound_hdr(&xdr, &hdr, 1);
 	encode_sequence(&xdr, &args->seq_args);
+	/* TODO: Need to get rid of putfh, not in draft-19
+	 * Need way to map devid to fsid, but fsid could be 128 bits (uuid)
+	 */
 	status = encode_putfh(&xdr, args->fh);
 	if (status != 0)
 		goto out;
@@ -5520,23 +5523,39 @@ static int decode_getdevicelist(struct xdr_stream *xdr, struct pnfs_devicelist *
 static int decode_getdeviceinfo(struct xdr_stream *xdr,
 				struct pnfs_device *res)
 {
-	uint32_t *p;
-	uint32_t len, type;
+	__be32 *p;
+	uint32_t len, type, tlen, mincount;
 	int status;
 
 	status = decode_op_hdr(xdr, OP_GETDEVICEINFO);
-	if (status)
+	if (status) {
+		/* TODO: Do we want to resend getdeviceinfo with mincount? */
+		if (status == -NFS4ERR_TOOSMALL) {
+			READ_BUF(4);
+			READ32(mincount);
+			dprintk("%s: Min count too small. mincnt = %u\n",
+			       __func__, mincount);
+		}
 		return status;
+	}
 
-	READ_BUF(4);	/* TODO: confirm layout type */
+	READ_BUF(8);
 	READ32(type);
-	READ_BUF(4);
+	if (type != res->layout_type) {
+		dprintk("%s: layout mismatch req: %u res: %u\n",
+			__func__, res->layout_type, type);
+		return -EINVAL;
+	}
 	READ32(len);
 	READ_BUF(len);
 
 	COPYMEM(&res->dev_addr_buf, len);
 	res->dev_addr_len = len;
 
+	/* Always 1 bitmap */
+	READ_BUF(8);
+	READ32(tlen);
+	READ32(res->dev_notify_types);
 	return 0;
 }
 
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 49be268..0278cf2 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -534,6 +534,12 @@ enum filelayout_hint_care4 {
 	NFLH4_CARE_STRIPE_UNIT_SIZE	= 0x00000040,
 	NFLH4_CARE_STRIPE_COUNT		= 0x00000080
 };
+
+enum pnfs_notify_deviceid_type4 {
+	NOTIFY_DEVICEID4_CHANGE = 1,
+	NOTIFY_DEVICEID4_DELETE = 2,
+};
+
 #endif /* defined(CONFIG_PNFS) || defined(CONFIG_PNFSD) */
 
 #endif
diff --git a/include/linux/nfs4_pnfs.h b/include/linux/nfs4_pnfs.h
index fea7a05..ed230f4 100644
--- a/include/linux/nfs4_pnfs.h
+++ b/include/linux/nfs4_pnfs.h
@@ -183,9 +183,11 @@ struct layoutdriver_policy_operations {
 
 struct pnfs_device {
 	pnfs_deviceid dev_id;
+	unsigned int  layout_type;
 	unsigned int  dev_count;
 	unsigned int  dev_addr_len;
 	char          dev_addr_buf[NFS4_PNFS_DEV_MAXSIZE];
+	unsigned int  dev_notify_types;
 };
 
 struct pnfs_devicelist {


More information about the pNFS mailing list