[pnfs] [PATCH 02/28] pnfs: fix pnfs_{read|write}pages

Fred Isaman iisaman at citi.umich.edu
Tue Mar 11 15:31:43 EDT 2008


THIS WILL BREAK OTHER LAYOUT DRIVERS that rely on old behavior.

This patch makes it possible to fall back to nfs from the layout driver's
read_pagelist or write_pagelist routines. It alters the call chain, and
expects ld_io_ops->{read|write}_pagelist to return either a 0 or 1,
consistent with its parents, putting any other information that needs to
be returned into the data.res and data.task structures.  The done routine
should be called by the layout driver if and only if it returns 0.

Signed-off-by: Fred Isaman <iisaman at citi.umich.edu>
---
 fs/nfs/pnfs.c             |   22 ++++++++++++----------
 include/linux/nfs4_pnfs.h |   16 ++++++++++++++--
 2 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 8059181..7a7379d 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1422,13 +1422,15 @@ pnfs_writepages(struct nfs_write_data *wdata, int how)
 							how,
 							wdata);
 
-	if (status)
+	if (status) {
 		put_lseg(lseg);
-	if (status > 0) {
-		dprintk("%s: LD write_pagelist returned status %d > 0\n", __FUNCTION__, status);
-		pnfs_update_last_write(nfsi, args->offset, status);
+		wdata->pnfsflags &= ~PNFS_NO_RPC;
+	} else if (wdata->res.count > 0) {
+		/* Succesful synchronous case */
+		dprintk("%s: LD write_pagelist returned count %d > 0\n",
+			__func__, wdata->res.count);
+		pnfs_update_last_write(nfsi, args->offset, wdata->res.count);
 		pnfs_need_layoutcommit(nfsi, wdata->args.context);
-		status = 0;
 	}
 
 out:
@@ -1503,12 +1505,12 @@ pnfs_readpages(struct nfs_read_data *rdata)
 							(loff_t)args->offset,
 							args->count,
 							rdata);
-	if (status)
+	if (status) {
 		put_lseg(lseg);
-	if (status > 0) {
-		dprintk("%s: LD read_pagelist returned status %d > 0\n", __FUNCTION__, status);
-		status = 0;
-	}
+		rdata->pnfsflags &= ~PNFS_NO_RPC;
+	} else if (rdata->res.count > 0)
+		dprintk("%s: LD read_pagelist returned count %d > 0\n",
+			__func__, rdata->res.count);
 
  out:
 	dprintk("%s: End Status %d\n", __FUNCTION__, status);
diff --git a/include/linux/nfs4_pnfs.h b/include/linux/nfs4_pnfs.h
index 381a599..2aaf526 100644
--- a/include/linux/nfs4_pnfs.h
+++ b/include/linux/nfs4_pnfs.h
@@ -116,8 +116,20 @@ struct layoutdriver_io_operations {
 	/* Functions that use the pagecache.
 	 * If use_pagecache == 1, then these functions must be implemented.
 	 */
-	ssize_t (*read_pagelist) (struct pnfs_layout_type *layoutid, struct page **pages, unsigned int pgbase, unsigned nr_pages, loff_t offset, size_t count, struct nfs_read_data *nfs_data);
-	ssize_t (*write_pagelist) (struct pnfs_layout_type *layoutid, struct page **pages, unsigned int pgbase, unsigned nr_pages, loff_t offset, size_t count, int sync, struct nfs_write_data *nfs_data);
+	/* read and write pagelist should return just 0 (to indicate
+	 * the layout code has taken control) or 1 (to indicate the
+	 * layoutcode wishes to fall back to normal nfs.)  If 0 is returned,
+	 * information can be passed back through nfs_data->res and
+	 * nfs_data->task.tk_status.
+	 */
+	int (*read_pagelist) (struct pnfs_layout_type *layoutid,
+			      struct page **pages, unsigned int pgbase,
+			      unsigned nr_pages, loff_t offset, size_t count,
+			      struct nfs_read_data *nfs_data);
+	int (*write_pagelist) (struct pnfs_layout_type *layoutid,
+			       struct page **pages, unsigned int pgbase,
+			       unsigned nr_pages, loff_t offset, size_t count,
+			       int sync, struct nfs_write_data *nfs_data);
 	int (*flush_one) (struct pnfs_layout_segment *, struct list_head *head, unsigned int npages, size_t count, int how);
 	void (*free_request_data) (struct nfs_page *);
 
-- 
1.5.3.3



More information about the pNFS mailing list