[pnfs] [PATCH 03/10] pnfs: file layout commit use wb_private
andros at umich.edu
andros at umich.edu
Wed Jan 16 17:52:54 EST 2008
From: Andy Adamson <andros at umich.edu>
Remove struct nfs_page wb_devip and wb_devport fields. Refactor
filelayout_commit to use the struct nfs4_pnfs_dserver in the nfs_page
wb_private field.
Signed-off-by: Andy Adamson<andros at umich.edu>
---
fs/nfs/nfs4filelayout.c | 133 +++++++++++++++++++++++++---------------------
include/linux/nfs_page.h | 2 -
2 files changed, 73 insertions(+), 62 deletions(-)
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index c8e3be3..a642751 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -460,8 +460,6 @@ skip_get:
count -= reqcount;
dstotal += reqcount;
- req->wb_devip = ds->ds_ip_addr;
- req->wb_devport = ds->ds_port;
req->wb_ops = &filelayout_io_operations;
req->wb_private = dserver;
@@ -559,8 +557,8 @@ ssize_t filelayout_write_pagelist(
data->ds_nfs_client = ds->ds_clp;
data->args.fh = dserver->fh;
- dprintk("%s set wb_devip: wb_devport %x:%hu\n", __FUNCTION__,
- htonl(ds->ds_ip_addr), ntohs(ds->ds_port));
+ dprintk("%s using DS %x:%hu\n", __FUNCTION__,
+ htonl(ds->ds_ip_addr), ntohs(ds->ds_port));
/* Get the file offset on the dserver. Set the write offset to
* this offset and save the original offset.
@@ -665,26 +663,62 @@ filelayout_free_lseg(struct pnfs_layout_type *layoutid,
memset(fls, 0, sizeof(*fls));
}
-/* TODO: Technically we would need to execute a COMMIT op to each
- * data server on which a page in 'pages' exists.
- * Once we fix this, we will need to invoke the pnfs_commit_complete callback.
+/*
+ * Do two nfs_pnfs_dserver pointers point to the same structure?
+ * Just compare the first multipath servers.
+ */
+static int
+filelayout_same_ds(struct nfs4_pnfs_dserver *one, struct nfs4_pnfs_dserver *two)
+{
+ struct nfs4_pnfs_dev *d_one = one->dev, *d_two = two->dev;
+ struct nfs4_pnfs_ds *ds_one, *ds_two;
+
+ ds_one = d_one->ds_list[0];
+ ds_two = d_two->ds_list[0];
+ return (d_one->stripe_index == d_two->stripe_index &&
+ d_one->num_ds == d_two->num_ds &&
+ ds_one->ds_ip_addr == ds_two->ds_ip_addr &&
+ ds_one->ds_port == ds_two->ds_port);
+}
+
+/*
+ * Allocate a new nfs_write_data struct and initialize
+ */
+static void
+filelayout_clone_write_data(struct nfs_write_data *old,
+ struct nfs_write_data *new)
+{
+ new = nfs_commit_alloc();
+ if (!new)
+ return;
+ new->inode = old->inode;
+ new->cred = old->cred;
+ new->args.offset = 0;
+ new->args.count = 0;
+ new->res.count = 0;
+ new->res.fattr = old->res.fattr;
+ new->res.verf = old->res.verf;
+ new->args.context = old->args.context;
+ new->call_ops = old->call_ops;
+ new->how = old->how;
+}
+
+/*
+ * Execute a COMMIT op to the MDS or to each data server on which a page
+ * in 'pages' exists.
+ * Invoke the pnfs_commit_complete callback.
*/
int
filelayout_commit(struct pnfs_layout_type *layoutid, int sync,
struct nfs_write_data *data)
{
- struct inode *ino = PNFS_INODE(layoutid);
- struct nfs_write_data *dsdata = NULL;
struct nfs4_filelayout *flo;
struct nfs4_filelayout_segment *nfslay;
- struct nfs4_pnfs_dev_item *dev;
- struct nfs4_pnfs_dev *fdev;
- struct nfs4_pnfs_dserver dserver;
+ struct nfs_write_data *dsdata = NULL;
+ struct nfs4_pnfs_dserver *dserver = NULL;
struct nfs4_pnfs_ds *ds;
- struct nfs_page *first;
struct nfs_page *req;
- struct list_head *pos, *tmp;
- int i;
+ struct list_head *pos, *tmp, *head = &data->pages;
flo = PNFS_LD_DATA(layoutid);
nfslay = LSEG_LD_DATA(&flo->pnfs_lseg);
@@ -697,70 +731,49 @@ filelayout_commit(struct pnfs_layout_type *layoutid, int sync,
return 1;
}
- dev = nfs4_pnfs_device_item_get(ino, nfslay->dev_id);
- fdev = &dev->stripe_devs[0];
+ /* COMMIT to each Data Server */
+ while (!list_empty(head)) {
- /* Gather pages per DS - Isn't this already done in nfs_pageio_init?*/
- for (i = 0; i < nfslay->num_fh; i++) {
- /* just try the first data server for the index..*/
- ds = fdev->ds_list[0];
+ /* dserver and dsdata must be NULL */
+ req = nfs_list_entry(head->next);
- if (!dsdata) {
- unsigned int pgcnt = 0;
+ dserver = (struct nfs4_pnfs_dserver *)req->wb_private;
+ /* XXX BUG_ON(!dserver) ?*/
+ if (!dserver)
+ goto out_bad;
- list_for_each_safe(pos, tmp, &data->pages) {
- req = nfs_list_entry(pos);
- if (req->wb_devip == ds->ds_ip_addr &&
- req->wb_devport == ds->ds_port)
- pgcnt++;
- }
- dsdata = nfs_commit_alloc();
- }
+ filelayout_clone_write_data(data, dsdata);
if (!dsdata)
goto out_bad;
- list_for_each_safe(pos, tmp, &data->pages) {
+
+ /* Just try the first multipath data server */
+ ds = dserver->dev->ds_list[0];
+ dsdata->pnfs_client = ds->ds_clp->cl_rpcclient;
+ dsdata->ds_nfs_client = ds->ds_clp;
+ dsdata->args.fh = dserver->fh;
+
+ /* Gather all pages going to the data server */
+ list_for_each_safe(pos, tmp, head) {
req = nfs_list_entry(pos);
- if (req->wb_devip == ds->ds_ip_addr &&
- req->wb_devport == ds->ds_port) {
+ if (filelayout_same_ds(dserver, req->wb_private)) {
nfs_list_remove_request(req);
- nfs_list_add_request(req, &dsdata->pages);
+ nfs_list_add_request(req, head);
}
}
- if (list_empty(&dsdata->pages)) {
- if (list_empty(&data->pages)) {
- dprintk("%s exit i %d devid %d\n",
- __FUNCTION__, i, nfslay->dev_id);
- nfs_commit_free(dsdata);
- return 0;
- } else
- continue;
- }
- first = nfs_list_entry(dsdata->pages.next);
-
- dprintk("%s call nfs_initiate_commit i %d devid %d\n",
- __FUNCTION__, i, nfslay->dev_id);
-
- dsdata->pnfs_client = ds->ds_clp->cl_rpcclient;
- dsdata->ds_nfs_client = ds->ds_clp;
- dserver.dev = fdev;
-
- /* TODO: Is the FH different from NFS_FH(data->inode)?
- * (set in nfs_commit_rpcsetup)
- */
- dserver.fh = &nfslay->fh_array[i];
- dsdata->args.fh = dserver.fh;
+ /* Send COMMIT to data server */
nfs_initiate_commit(dsdata, dsdata->pnfs_client, sync);
+ /* reset for next data server */
dsdata = NULL;
- fdev++;
+ dserver = NULL;
}
-
/* Release original commit data since it is not used */
nfs_commit_free(data);
return 0;
out_bad:
+ /* XXX should we send COMMIT to MDS e.g. not free data and return 1 ? */
nfs_commit_free(data);
return -ENOMEM;
}
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 098b788..8da70b2 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -45,8 +45,6 @@ struct nfs_page {
unsigned long wb_flags;
struct nfs_writeverf wb_verf; /* Commit cookie */
#ifdef CONFIG_PNFS
- unsigned int wb_devip; /* pNFS data server IP addr */
- unsigned int wb_devport; /* pNFS data server port */
void *wb_ops; /* pNFS io operations */
void *wb_private;
#endif
--
1.5.0.2
More information about the pNFS
mailing list