[pnfs] [PATCH 3/6] 2.6-latest-pnfs-client-draft-13-layoutget

andros at umich.edu andros at umich.edu
Fri Oct 19 14:13:19 EDT 2007


From: Andy Adamson <andros at umich.edu>

Update the decoding of LAYOUTGET to draft-13, using the new device data
structures.

Signed-off by: Andy Adamson<andros at umich.edu>
---
 fs/nfs/nfs4filelayout.c    |  101 +++++++++++++++++++++++---------------------
 fs/nfs/nfs4filelayout.h    |   18 ++++----
 fs/nfs/nfs4filelayoutdev.c |   58 ++++++++++++++-----------
 include/linux/nfs_page.h   |    3 +-
 4 files changed, 96 insertions(+), 84 deletions(-)

diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 563ede4..e79e8b1 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -191,7 +191,7 @@ filelayout_get_dserver_offset(loff_t offset, struct nfs4_filelayout * layout)
 			loff_t tmp;
 			u32 stripe_unit_idx;
 
-			stripe_size = layout->stripe_unit * layout->num_devs;
+			stripe_size = layout->stripe_unit * layout->num_fh;
 			/* XXX I do this because do_div seems to take a 32 bit dividend */
 			stripe_unit = layout->stripe_unit;
 			tmp = off = offset;
@@ -352,6 +352,7 @@ ssize_t filelayout_write_pagelist(
 {
 	struct nfs4_filelayout* nfslay = (struct nfs4_filelayout*)layoutid->layoutid;
 	struct nfs4_pnfs_dserver dserver;
+	struct nfs4_pnfs_ds *ds;
 	struct nfs_page* req;
 	struct list_head *h;
 	int status;
@@ -362,19 +363,24 @@ ssize_t filelayout_write_pagelist(
 					offset,
 					count,
 					&dserver);
-	/* ANDROS: XXX should fail if no data server */
-	if(!status) {
-		struct nfs4_pnfs_ds *ds = dserver.dev->ds_list[0];
-
+	if(status) {
+		dprintk("NFS_FILELAYOUT: %s failed to get dataserver\n",
+						__FUNCTION__);
+		return -EIO;
+	} else {
 		/* just try the first data server for the index.. */
+		ds = dserver.dev->ds_list[0];
 		data->pnfs_client = ds->ds_clp->cl_rpcclient;
 		data->session = ds->ds_clp->cl_ds_session;
 		data->args.fh = dserver.fh;
 	}
-	dprintk("%s set wb_devid %d\n", __FUNCTION__, dserver.dev_id);
+	dprintk("%s set wb_devip: wb_devport %x:%hu\n", __FUNCTION__,
+			htonl(ds->ds_ip_addr),ntohs(ds->ds_port));
+
 	list_for_each(h, &data->pages) {
 		req = list_entry(h, struct nfs_page, wb_list);
-		req->wb_devid = dserver.dev_id;
+		req->wb_devip = ds->ds_ip_addr;
+		req->wb_devport = ds->ds_port;
 	}
 
         /* Now get the file offset on the dserver
@@ -459,34 +465,29 @@ filelayout_set_layout(struct pnfs_layout_type* layoutid, struct inode* inode,
 	if (!fl)
 		goto nfserr;
 
-	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: 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;
-
+	READ32(fl->dev_id);
+	READ32(nfl_util);
+	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;
+
+	READ32(fl->first_stripe_index);
+	READ32(fl->num_fh);
+
+	dprintk("DEBUG: %s: dev_id %u nfl_util 0x%X num_fh %u\n", __func__,
+				fl->dev_id, nfl_util, fl->num_fh);
 	
-		/* 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 nfl_util 0x%X\n", __func__,
-			fl->devs[i].dev_id,fl->devs[i].fh.size, nfl_util);
+	for (i = 0; i < fl->num_fh; i++) {
+		/* fh */ 
+		memset(&fl->fh_array[i], 0, sizeof(struct nfs_fh));
+		READ32(fl->fh_array[i].size);
+		COPYMEM(fl->fh_array[i].data, fl->fh_array[i].size);
+		dprintk("DEBUG: %s: fh len %d\n", __func__,
+					fl->fh_array[i].size);
 	}
 
 	return layoutid;
@@ -516,12 +517,13 @@ filelayout_commit(struct pnfs_layout_type * layoutid, struct inode* ino, struct
 	struct nfs_write_data   *dsdata = NULL;
 	struct pnfs_layout_type* laytype;
 	struct nfs4_filelayout* nfslay;
+	struct nfs4_pnfs_dev_item *dev;
+	struct nfs4_pnfs_dev *fdev;
 	struct nfs4_pnfs_dserver dserver;
 	struct nfs4_pnfs_ds *ds;
 	struct nfs_page* first;
 	struct nfs_page* req;
 	struct list_head *pos, *tmp;
-	u32 dev_id;
 	int i;
 
 	laytype = NFS_I(ino)->current_layout;
@@ -536,27 +538,30 @@ filelayout_commit(struct pnfs_layout_type * layoutid, struct inode* ino, struct
 		nfs_execute_write(data);
 		return 0;
 	}
-	for (i = 0; i < nfslay->num_devs; i++) {
-		dev_id = nfslay->devs[i].dev_id;
+	dev = nfs4_pnfs_device_item_get(layoutid, nfslay->dev_id);
+	fdev = &dev->stripe_devs[0];
+
+	for (i = 0; i < nfslay->num_fh; i++) {
+		/* just try the first data server for the index..*/
+		ds = fdev->ds_list[0];
+
 		if (!dsdata) {
 			unsigned int pgcnt = 0;
 
 			list_for_each_safe(pos, tmp, &data->pages) {
 				req = nfs_list_entry(pos);
-				if (req->wb_devid == dev_id)
+				if (req->wb_devip == ds->ds_ip_addr &&
+				    req->wb_devport == ds->ds_port)
 					pgcnt++;
 			}
 			dsdata = nfs_commit_alloc();
 		}
 		if (!dsdata)
 			goto out_bad;
-		dserver.dev = nfs4_pnfs_device_get(ino, dev_id);
-		if (dserver.dev == NULL) {
-			return 1;
-		}
 		list_for_each_safe(pos, tmp, &data->pages) {
 			req = nfs_list_entry(pos);
-			if (req->wb_devid == dev_id) {
+			if (req->wb_devip == ds->ds_ip_addr &&
+			    req->wb_devport == ds->ds_port) {
 				nfs_list_remove_request(req);
 				nfs_list_add_request(req, &dsdata->pages);
 			}
@@ -564,7 +569,7 @@ filelayout_commit(struct pnfs_layout_type * layoutid, struct inode* ino, struct
 		if (list_empty(&dsdata->pages)) {
 			if (list_empty(&data->pages)) {
 				dprintk("%s exit i %d devid %d\n",
-						__FUNCTION__, i,dev_id);
+						__FUNCTION__, i,nfslay->dev_id);
 				nfs_commit_free(dsdata);
 				return 0;
 			} else
@@ -573,23 +578,23 @@ filelayout_commit(struct pnfs_layout_type * layoutid, struct inode* ino, struct
 		first = nfs_list_entry(dsdata->pages.next);
 
 		dprintk("%s call nfs_commit_rpcsetup i %d devid %d\n",
-						__FUNCTION__, i, dev_id);
+						__FUNCTION__, i, nfslay->dev_id);
 
-		/* just try the first data server for the index.. */
-		ds = dserver.dev->ds_list[0];
 		dsdata->pnfs_client = ds->ds_clp->cl_rpcclient;
 		dsdata->session =  ds->ds_clp->cl_ds_session;
+		dserver.dev = fdev;
 
 		nfs_commit_rpcsetup(dsdata, sync);
 
 		/* TODO: Is the FH different from NFS_FH(data->inode)?
 		 * (set in nfs_commit_rpcsetup)
 		 */
-		dserver.fh = &nfslay->devs[i].fh;
+		dserver.fh = &nfslay->fh_array[i];
 		dsdata->args.fh = dserver.fh;
 
 		nfs_execute_write(dsdata);
 		dsdata = NULL;
+		fdev++;
 	}
 
 	/* Release original commit data since it is not used */
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h
index ab7f716..d181473 100644
--- a/fs/nfs/nfs4filelayout.h
+++ b/fs/nfs/nfs4filelayout.h
@@ -74,12 +74,6 @@ struct nfs4_pnfs_dserver {
 	u32 dev_id;
 };
 
-struct nfs4_filelayout_devs {
-	u32 dev_id;
-	u32 dev_index;
-	struct nfs_fh fh;
-};
-
 struct nfs4_filelayout {
 	int uncommitted_write;
 	loff_t last_commit_size;
@@ -90,9 +84,10 @@ struct nfs4_filelayout {
 	u32 stripe_type;
 	u32 commit_through_mds;
 	u64 stripe_unit;
-	unsigned int index_len;
-	unsigned int num_devs;
-	struct nfs4_filelayout_devs devs[NFS4_PNFS_MAX_STRIPE_CNT];
+	u32 first_stripe_index;
+	u32 dev_id;
+	unsigned int num_fh;
+	struct nfs_fh fh_array[NFS4_PNFS_MAX_STRIPE_CNT];
 };
 
 struct filelayout_mount_type {
@@ -110,8 +105,11 @@ int nfs4_pnfs_dserver_get(struct inode *inode,
 			  struct nfs4_pnfs_dserver *dserver);
 int decode_and_add_devicelist(struct filelayout_mount_type *mt, struct pnfs_devicelist* devlist);
 
+struct nfs4_pnfs_dev *
+nfs4_pnfs_device_get(struct inode *inode, u32 dev_id, u32 stripe_index);
 struct nfs4_pnfs_dev_item *
-nfs4_pnfs_device_get(struct inode *inode, u32 dev_id);
+nfs4_pnfs_device_item_get(struct pnfs_layout_type *ltype, u32 dev_id);
+
 
 #define READ32(x)         (x) = ntohl(*p++)
 #define READ64(x)         do {			\
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index da462e4..569361f 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -570,28 +570,41 @@ get_device_info(struct filelayout_mount_type *mt, u32 dev_id)
 	return decode_and_add_device(mt, pdev);
 }
 
-/* Lookup and return the device dev_id
- */
 struct nfs4_pnfs_dev_item *
-nfs4_pnfs_device_get(struct inode *inode, u32 dev_id)
+nfs4_pnfs_device_item_get(struct pnfs_layout_type *ltype, u32 dev_id)
+{
+	struct filelayout_mount_type *mt;
+	struct nfs4_pnfs_dev_item *dev;
+
+	mt = (struct filelayout_mount_type *)ltype->mountid->mountid;
+
+	read_lock(&mt->hlist->dev_lock);
+	dev = _device_lookup(mt->hlist, dev_id);
+	read_unlock(&mt->hlist->dev_lock);
+
+	if (dev == NULL)
+		dev = get_device_info(mt, dev_id);
+	return dev;
+}
+
+/* Lookup and return the data server struct
+ */
+struct nfs4_pnfs_dev *
+nfs4_pnfs_device_get(struct inode *inode, u32 dev_id, u32 stripe_idx)
 {
 	struct nfs4_pnfs_dev_item *dev;
 	struct nfs_server* server = NFS_SERVER(inode);
-	struct filelayout_mount_type *mt = (struct filelayout_mount_type*)server->pnfs_mountid->mountid;
-	struct nfs4_pnfs_dev_hlist *hlist = mt->hlist;
+	struct filelayout_mount_type *mt;
 
-	read_lock(&hlist->dev_lock);
-	dev = _device_lookup(hlist, dev_id);
-/*
-	if (dev) {
-		atomic_inc(&dev->count);
-	}
-*/
-	read_unlock(&hlist->dev_lock);
+	mt = (struct filelayout_mount_type*)server->pnfs_mountid->mountid;
+
+	read_lock(&mt->hlist->dev_lock);
+	dev = _device_lookup(mt->hlist, dev_id);
+	read_unlock(&mt->hlist->dev_lock);
 	if (dev == NULL)
 		dev = get_device_info(mt, dev_id);
 
-	return dev;
+	return &dev->stripe_devs[stripe_idx];
 }
 
 /* Retrieve the rpc client for a specified byte range
@@ -604,7 +617,6 @@ nfs4_pnfs_dserver_get(struct inode *inode,
 		      u32 count,
 		      struct nfs4_pnfs_dserver *dserver)
 {
-	u32 dev_id;
 	u64 tmp;
 	u32 stripe_idx, dbg_stripe_idx;
 
@@ -614,32 +626,28 @@ nfs4_pnfs_dserver_get(struct inode *inode,
 	tmp = offset;
 	/* Want ((offset / layout->stripe_unit) % layout->num_devs) */
 	do_div(tmp, layout->stripe_unit);
-	stripe_idx = do_div(tmp, layout->num_devs);
+	stripe_idx = do_div(tmp, layout->num_fh) + layout->first_stripe_index;
 
 	/* For debugging */
 	tmp = offset + count - 1;
 	do_div(tmp, layout->stripe_unit);
-	dbg_stripe_idx = do_div(tmp, layout->num_devs);
+	dbg_stripe_idx = do_div(tmp, layout->num_fh) + layout->first_stripe_index;
 
 	dprintk("%s: offset=%Lu, count=%u, si=%u, dsi=%u, "
 		   "num_devs=%u, stripe_unit=%Lu\n",
                    __FUNCTION__,
-		   offset, count, stripe_idx, dbg_stripe_idx, layout->num_devs,
+		   offset, count, stripe_idx, dbg_stripe_idx, layout->num_fh,
 		   layout->stripe_unit);
 
 	BUG_ON(dbg_stripe_idx != stripe_idx);
 
-	dev_id = layout->devs[stripe_idx].dev_id;
-
-	/* NOTE: resolved in following patch.
-	 *dserver->dev = nfs4_pnfs_device_get(inode, dev_id); */
-
+	dserver->dev = nfs4_pnfs_device_get(inode, layout->dev_id, stripe_idx);
 	if (dserver->dev == NULL)
 		return 1;
-	dserver->fh = &layout->devs[stripe_idx].fh;
+	dserver->fh = &layout->fh_array[stripe_idx];
 
 	dprintk("%s: dev_id=%u, idx=%u, offset=%Lu, count=%u\n",
-                    __FUNCTION__, dev_id, stripe_idx, offset, count);
+		     __FUNCTION__, layout->dev_id, stripe_idx, offset, count);
 
 	return 0;
 }
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 90f1fab..ea8d73a 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -46,7 +46,8 @@ struct nfs_page {
 	unsigned long		wb_flags;
 	struct nfs_writeverf	wb_verf;	/* Commit cookie */
 #ifdef CONFIG_PNFS
-	unsigned int		wb_devid;	/* pNFS data server id */
+	unsigned int		wb_devip;	/* pNFS data server IP addr */
+	unsigned int		wb_devport;	/* pNFS data server port */
 #endif
 };
 
-- 
1.5.0.2



More information about the pNFS mailing list