[pnfs] [PATCH] update pNFS ops to draft 13

Marc Eshel eshel at almaden.ibm.com
Tue Sep 4 12:23:04 EDT 2007


From: Marc Eshel <eshel at almaden.ibm.com>


---

 fs/nfs/nfs4filelayout.c            |   25 ++++++----
 fs/nfs/nfs4filelayout.h            |    1 
 fs/nfs/nfs4filelayoutdev.c         |   23 +++++----
 fs/nfs/nfs4xdr.c                   |   90 ++++++++++++++++++++----------------
 fs/nfsd/nfs4filelayoutxdr.c        |   28 +++++++----
 fs/nfsd/nfs4xdr.c                  |   16 ++++--
 include/linux/nfs4.h               |   18 +++++++
 include/linux/nfs4_pnfs.h          |    7 ---
 include/linux/nfsd/nfs4layoutxdr.h |    2 -
 9 files changed, 126 insertions(+), 84 deletions(-)

diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 043583f..9a63870 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -445,6 +445,7 @@ filelayout_set_layout(struct pnfs_layout
 	struct nfs4_filelayout* fl = NULL;
 	int i;
 	uint32_t *p = (uint32_t*)layout;
+	uint32_t nfl_util;
 
 	dprintk("%s set_layout_map Begin\n", __FUNCTION__);
 
@@ -454,30 +455,34 @@ filelayout_set_layout(struct pnfs_layout
 	if (!fl)
 		goto nfserr;
 
-	READ32(fl->stripe_type);
-	READ32(fl->commit_through_mds);
-	READ64(fl->stripe_unit);
-	READ64(fl->file_size);
-	READ32(fl->index_len);
 	if (fl->index_len > 0) { //??? if>0 must build index list
 		printk("filelayout_set_layout: XXX add loop for index list\n");
 	}
 	READ32(fl->num_devs);
 
-	dprintk("DEBUG: %s: type %d stripe_unit %lld file_size %lld devs %d\n",
-				__func__, fl->stripe_type, fl->stripe_unit,
-				fl->file_size, fl->num_devs);
+	dprintk("DEBUG: %s: devs %d\n", __FUNCTION__, fl->num_devs);
 
 	for (i = 0; i < fl->num_devs; i++) {
 		READ32(fl->devs[i].dev_id);
+		READ32(nfl_util);
 		READ32(fl->devs[i].dev_index);
+		READ32(fl->index_len);
 
+		if (nfl_util & NFL4_UFLG_COMMIT_THRU_MDS)
+			fl->commit_through_mds = 1;
+		if (nfl_util & NFL4_UFLG_DENSE)
+			fl->stripe_type = STRIPE_DENSE;
+		else
+			fl->stripe_type = STRIPE_SPARSE;
+		fl->stripe_unit = nfl_util & ~NFL4_UFLG_MASK;
+
+	
 		/* fh */
 		memset(&fl->devs[i].fh, 0, sizeof(struct nfs_fh));
 		READ32(fl->devs[i].fh.size);
 		COPYMEM(fl->devs[i].fh.data, fl->devs[i].fh.size);
-		dprintk("DEBUG: %s: dev %d len %d\n", __func__,
-		fl->devs[i].dev_id,fl->devs[i].fh.size);
+		dprintk("DEBUG: %s: dev %d len %d nfl_util 0x%X\n", __func__,
+			fl->devs[i].dev_id,fl->devs[i].fh.size, nfl_util);
 	}
 
 	return layoutid;
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h
index 357a915..1383a36 100644
--- a/fs/nfs/nfs4filelayout.h
+++ b/fs/nfs/nfs4filelayout.h
@@ -73,7 +73,6 @@ struct nfs4_filelayout {
 	u64 offset;
 	u64 length;
 	u32 iomode;
-	u64 file_size;
 	u32 stripe_type;
 	u32 commit_through_mds;
 	u64 stripe_unit;
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index fe1e067..4296007 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -265,7 +265,7 @@ nfs4_pnfs_device_add(struct filelayout_m
 static struct nfs4_pnfs_dev_item*
 decode_device(struct pnfs_device* dev)
 {
-	int len;
+	int index, i, j, len;
 	int tmp[6];
 	uint32_t *p = (uint32_t*)dev->dev_addr_buf;
 	struct nfs4_pnfs_dev_item* file_dev;
@@ -275,7 +275,6 @@ decode_device(struct pnfs_device* dev)
 	{
 		return NULL;
 	}
-
 	/* Initialize dev */
 	INIT_HLIST_NODE(&file_dev->hash_node);
 	atomic_set(&file_dev->count, 0);
@@ -283,19 +282,20 @@ decode_device(struct pnfs_device* dev)
 	/* Device id */
 	file_dev->dev_id = dev->dev_id;
 
-	/* Get the device type */
-	READ32(dev->dev_type);
-
-	if (dev->dev_type != FILE_SIMPLE) {
-		printk(KERN_NOTICE "Device type %d not supported!\n", dev->dev_type);
-		return NULL;
+	READ32(index);
+	for (i = 0; i < index; i++) {  /* skip indices list */
+		READ32(j);
 	}
 
+	READ32(len);
+	BUG_ON(len != 1);    /* 1 DS per device id */
+
 	/* Get the device count */
 	READ32(dev->dev_count);
 
 	if (dev->dev_count > 1)
-		printk(KERN_NOTICE "%s: Add loop for dev_count\n", __FUNCTION__);
+		printk(KERN_NOTICE "%s: Add loop for multipath dev_count %d dev_id %d\n",
+			__FUNCTION__, dev->dev_count, dev->dev_id);
 
 	/* Decode contents of device*/
 
@@ -303,8 +303,11 @@ decode_device(struct pnfs_device* dev)
 
 	/* check and skip r_netid */
 	READ32(len);
-	if (len != 3) /* "tcp" */
+	if (len != 3) { /* "tcp" */
+		printk("%s: ERROR: Device index %d dev_count %d len %d\n",
+			__FUNCTION__, index, dev->dev_count, len);
 		return NULL;
+	}
 	/* Read the bytes into a temporary buffer */
 	/* TODO: should probably sanity check them */
 	READ32(tmp[0]);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 2e5a8a7..cfb391d 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4914,54 +4914,62 @@ #ifdef CONFIG_PNFS
  */
 static int decode_getdevicelist(struct xdr_stream *xdr, struct pnfs_devicelist *res)
 {
-        uint32_t *p;
-        int status, i, cnt;
-        uint32_t len = 0, total_len = 0;
-        struct nfs_writeverf verftemp;
+	uint32_t *p;
+	int status, i, cnt;
+	uint32_t len = 0, total_len = 0;
+	struct nfs_writeverf verftemp;
 
-        status = decode_op_hdr(xdr, OP_GETDEVICELIST);
-        if (status)
-                return status;
+	status = decode_op_hdr(xdr, OP_GETDEVICELIST);
+	if (status)
+		return status;
 
-        /* TODO: Skip cookie for now */
-        READ_BUF(8);
-        (*p) += 2;
+	/* TODO: Skip cookie for now */
+	READ_BUF(8);
+	(*p) += 2;
 
-        /* Read verifier */
-        READ_BUF(8);
-        COPYMEM(verftemp.verifier, 8);
+	/* Read verifier */
+	READ_BUF(8);
+	COPYMEM(verftemp.verifier, 8);
 
-        READ_BUF(4);
-        READ32(res->num_devs);
+	READ_BUF(4);
+	READ32(res->num_devs);
 
-        for (i = 0,cnt=0; i < res->num_devs && cnt < NFS4_PNFS_DEV_MAXCOUNT; i++)
-        {
-                READ_BUF(4);
-                READ32(res->devs[cnt].dev_id);	/* device id */
-                READ_BUF(4);			/* skip layout type */
-                READ_BUF(4);
-                READ32(len);
-                dprintk("%s: num_dev %d i %d cnt %d id %d len %d\n",
-                        __FUNCTION__, res->num_devs, i, cnt,
-                        res->devs[cnt].dev_id, len);
-
-                READ_BUF(len);
-
-                /* DH-TODO: Can I decode this inline?  Is the xdr_stream
-                 * memory valid after the completion of this function?
-                 */
-/*              decode_opaque_inline(xdr, &len, &r_addr); */
-                COPYMEM(&res->devs[cnt].dev_addr_buf, len);
-                res->devs[cnt].dev_addr_len = len;
+	for (i = 0,cnt=0; i < res->num_devs && cnt < NFS4_PNFS_DEV_MAXCOUNT; i++)
+	{
+		READ_BUF(4);
+		READ32(res->devs[cnt].dev_id);	/* device id */
 
-                total_len += len;
-                cnt++;
-        }
-        READ_BUF(4);
-        READ32(res->eof);
+		READ_BUF(4);
+		READ32(len); /* 1 in list of device_addr */
+		if (len > 1)
+			printk(KERN_EMERG "%s: list of %d device addr\n",
+				__FUNCTION__, len);
+		READ_BUF(4);
+		READ32(res->layout_type);
 
-        res->devs_len = total_len;
-        return 0;
+		READ_BUF(4);
+		READ32(len);
+		dprintk("%s: num_dev %d i %d cnt %d id %d len %d\n",
+			__FUNCTION__, res->num_devs, i, cnt,
+			res->devs[cnt].dev_id, len);
+
+		READ_BUF(len);
+
+		/* DH-TODO: Can I decode this inline?  Is the xdr_stream
+		 * memory valid after the completion of this function?
+		 */
+		/* decode_opaque_inline(xdr, &len, &r_addr); */
+		COPYMEM(&res->devs[cnt].dev_addr_buf, len);
+		res->devs[cnt].dev_addr_len = len;
+
+		total_len += len;
+		cnt++;
+	}
+	READ_BUF(4);
+	READ32(res->eof);
+
+	res->devs_len = total_len;
+	return 0;
 }
 
 /* DH: decode device info arguments
diff --git a/fs/nfsd/nfs4filelayoutxdr.c b/fs/nfsd/nfs4filelayoutxdr.c
index 28badc6..a3d697f 100644
--- a/fs/nfsd/nfs4filelayoutxdr.c
+++ b/fs/nfsd/nfs4filelayoutxdr.c
@@ -52,13 +52,17 @@ filelayout_encode_devaddr(u32 *p, u32 *e
 	u32 *p_in = p;
 
 	fdev = (struct pnfs_filelayout_devaddr *)dev_addr;
-        len = 4+XDR_QUADLEN(fdev->r_netid.len)+XDR_QUADLEN(fdev->r_addr.len);
+        len = 6+XDR_QUADLEN(fdev->r_netid.len)+XDR_QUADLEN(fdev->r_addr.len);
         len = len << 2;
 	if (p + XDR_QUADLEN(len) > end)
 		return -ENOMEM;
 	WRITE32(len);
-	WRITE32(fdev->r_dev_type);
-	WRITE32(1);
+
+	WRITE32(1);  /* 1 in indices list */
+	WRITE32(0);  /* index 0 */
+	WRITE32(1);  /* 1 DS per device id */
+	WRITE32(1);  /* 1 in list of multipath */
+
 	WRITE32(fdev->r_netid.len);
 	WRITEMEM(fdev->r_netid.data,fdev->r_netid.len);
 	WRITE32(fdev->r_addr.len);
@@ -89,11 +93,13 @@ filelayout_encode_layoutlist_item(u32 *p
 	int len;
 	unsigned int fhlen = item->dev_fh.fh_size;
 
-	len = 12 + fhlen;
+	len = 20 + fhlen;
 	if (p + XDR_QUADLEN(len) > end)
 		return -ENOMEM;
 	WRITE32(item->dev_id);
+	WRITE32(item->dev_util); /* nfl_util4 */
 	WRITE32(item->dev_index);
+	WRITE32(1); /* One for now can be an array of FHs */
 	WRITE32(fhlen);
 	WRITEMEM(&item->dev_fh.fh_base, fhlen);
 	return len;
@@ -107,19 +113,20 @@ filelayout_encode_layout(u32 *p, u32 *en
 	struct nfsd4_pnfs_layoutlist *item;
 	int i, full_len, len;
 	u32 *totlen;
+	u32 nfl_util;
 
 	flp = (struct nfsd4_pnfs_filelayout *)layout;
-	len = 32;
+	len = 4;
 	if (p + XDR_QUADLEN(len + 4) > end)
 		return -ENOMEM;
 	full_len = len + 4;
 	totlen = p; 	/* fill-in opaque layout length later*/
 	p++;
-	WRITE32(flp->lg_stripe_type);
-	WRITE32(flp->lg_commit_through_mds);
-	WRITE64(flp->lg_stripe_unit);
-	WRITE64(flp->lg_file_size);
-	WRITE32(flp->lg_indexlen);
+	nfl_util = flp->lg_stripe_unit;
+	if (flp->lg_commit_through_mds)
+		nfl_util |= NFL4_UFLG_COMMIT_THRU_MDS;
+	if (flp->lg_stripe_type)
+		nfl_util |= NFL4_UFLG_DENSE;
 
 	if (flp->lg_indexlen > 0) {   //??? if>0 must build index list
 		printk("filelayout_encode_layout: XXX add loop for index list\n");
@@ -127,6 +134,7 @@ filelayout_encode_layout(u32 *p, u32 *en
 	WRITE32(flp->lg_llistlen);
 	for (i=0; i < flp->lg_llistlen; i++) {
 		item = &flp->lg_llist[i];
+		item->dev_util = nfl_util;
 		len = filelayout_encode_layoutlist_item(p, end, item);
 		if (len > 0) {
 			p += XDR_QUADLEN(len);
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index b9e0400..d3ce4a7 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2888,10 +2888,14 @@ nfsd4_encode_devlist_item(struct nfsd4_c
 	int len;
 	ENCODE_HEAD;
 
-	RESERVE_SPACE(8);
+	RESERVE_SPACE(28);
 	WRITE32(dlist->dev_id);
-	WRITE32(lotype);
+
+	WRITE32(1); /* 1 in list of device_addr */
+	WRITE32(lotype); /* layout type */
+	
 	ADJUST_ARGS();
+	dprintk("%s: device id %d\n",__FUNCTION__, dlist->dev_id);
 
 	if (ex_ops->devaddr_encode == NULL && lotype == LAYOUT_NFSV4_FILES)
 	{
@@ -2941,7 +2945,7 @@ nfsd4_encode_getdevlist(struct nfsd4_com
 		item = gdevl->gd_devlist;
 		for (i = 0; i < gdevl->gd_devlist_len; i++) {
 			dprintk("%s: i %d item %p\n",__FUNCTION__, i, item);
-			len = nfsd4_encode_devlist_item (resp, item,
+			len = nfsd4_encode_devlist_item(resp, item,
 						gdevl->gd_ops, gdevl->gd_type);
 			item++;
 			if (len <= 0) {
@@ -2969,12 +2973,14 @@ nfsd4_encode_getdevinfo(struct nfsd4_com
 
 	printk("%s: err %d\n",__FUNCTION__, nfserr);
 	if (!nfserr) {
-		RESERVE_SPACE(8);
+		RESERVE_SPACE(28);
 		WRITE32(gdev->gd_type);
+		ADJUST_ARGS();
+
 		if (gdev->gd_ops->devaddr_encode == NULL &&
 					gdev->gd_type == LAYOUT_NFSV4_FILES)
 		{
-			len = filelayout_encode_devaddr(p, resp->end,gdev->gd_devaddr);
+			len = filelayout_encode_devaddr(p, resp->end, gdev->gd_devaddr);
 			filelayout_free_devaddr(gdev->gd_devaddr);
 		}
 		else {
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 4912cea..bdc55ed 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -294,6 +294,11 @@ enum nfsstat4 {
 	NFS4ERR_CONN_BINDING_NOT_ENFORCED = 10073,
 	NFS4ERR_CLIENTID_BUSY = 10074,
 	NFS4ERR_PNFS_IO_HOLE = 10075,
+	NFS4ERR_SEQ_FALSE_RETRY	= 10076,
+	NFS4ERR_BAD_HIGH_SLOT = 10077,
+	NFS4ERR_DEADSESSION = 10078,
+	NFS4ERR_ENCR_ALG_UNSUPP = 10079,
+	NFS4ERR_PNFS_NO_LAYOUT = 10080
 };
 
 /*
@@ -496,6 +501,19 @@ enum pnfs_iomode {
 	IOMODE_ANY = 3,
 };
 
+#define NFL4_UFLG_MASK			0x0000003F
+#define NFL4_UFLG_DENSE			0x00000001
+#define NFL4_UFLG_COMMIT_THRU_MDS	0x00000002
+#define NFL4_UFLG_STRIPE_UNIT_SIZE_MASK	0xFFFFFFC0
+
+/* Encoded in the loh_body field of type layouthint4 */
+enum filelayout_hint_care4 {
+	NFLH4_CARE_DENSE		= NFL4_UFLG_DENSE,
+	NFLH4_CARE_COMMIT_THRU_MDS	= NFL4_UFLG_COMMIT_THRU_MDS,
+	NFLH4_CARE_STRIPE_UNIT_SIZE	= 0x00000040,
+	NFLH4_CARE_STRIPE_COUNT		= 0x00000080
+};
+
 #endif /* CONFIG_PNFS */
 
 /* Create Session Flags */
diff --git a/include/linux/nfs4_pnfs.h b/include/linux/nfs4_pnfs.h
index 74d25fd..48c33fa 100644
--- a/include/linux/nfs4_pnfs.h
+++ b/include/linux/nfs4_pnfs.h
@@ -122,13 +122,13 @@ struct pnfs_layoutdriver_type {
 struct pnfs_device
 {
 	int           dev_id;
-	int           dev_type;
 	unsigned int  dev_count;
 	unsigned int  dev_addr_len;
 	char          dev_addr_buf[NFS4_PNFS_DEV_MAXSIZE];
 };
 
 struct pnfs_devicelist {
+	int                 layout_type;
 	unsigned int        num_devs;
 	unsigned int        eof;
 	unsigned int        devs_len;
@@ -170,9 +170,4 @@ void pnfs_unregister_layoutdriver(struct
 #define NFS4_PNFS_MAX_LAYOUTS 4
 #define NFS4_PNFS_PRIVATE_LAYOUT 0x80000000
 
-enum file_layout_device_type {
-	FILE_SIMPLE  = 1,
-	FILE_COMPLEX = 2
-};
-
 #endif /* LINUX_NFS4_PNFS_H */
diff --git a/include/linux/nfsd/nfs4layoutxdr.h b/include/linux/nfsd/nfs4layoutxdr.h
index 25cde5f..2d0159a 100644
--- a/include/linux/nfsd/nfs4layoutxdr.h
+++ b/include/linux/nfsd/nfs4layoutxdr.h
@@ -58,7 +58,6 @@ #define ADJUST_ARGS()           resp->p 
 
 /* the nfsd4_pnfs_devlist dev_addr for the file layout type */
 struct pnfs_filelayout_devaddr {
-	u32			r_dev_type;
 	struct xdr_netobj	r_netid;
 	struct xdr_netobj	r_addr;
 };
@@ -66,6 +65,7 @@ struct pnfs_filelayout_devaddr {
 struct nfsd4_pnfs_layoutlist {
 	u32				dev_id;
 	u32                             dev_index;
+	u32                             dev_util;
 	struct knfsd_fh                 dev_fh;
 };
 


More information about the pNFS mailing list