[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