[pnfs] [PATCH 19/23] 2.6-latest pnfs client no rpc nfs page cache cleanup

andros at umich.edu andros at umich.edu
Thu Dec 13 15:51:45 EST 2007


From: Andy Adamson <andros at umich.edu>

Cleanup the nfs page cache after a non rpc pNFS I/O

The 2.6.18.3 client called pnfs_readpage_result_norpc() from pnfs_read_done
to clean up after a pNFS I/O that used the page cache, but not NFS RPC.
pnfs_readpage_result_norpc() contained code copied from
the rpc_call_done routines nfs_readpage_result_full, and
nfs_readpage_result_partial. It ran all the code that did not have to do
with an rpc call, namely the NFS_PROTO(inode)->read_done and rpc_restart_call
called in nfs_readpage_result. The PNFS_USE_FULL_CB was used to switch
between the nfs_readpage_result_full and nfs_readpage_result_partial
pieces of pnfs_readpage_result_norpc.

This patch provides a cleaner way of providing the same functionlality.
The pNFS layout driver that uses the nfs page cache, but does not use
RPC sets the new flag PNFS_NO_RPC in nfs_read_data->pnfsflags.
This flag is checked in pnfs4_read_done, and in nfs_readpage_retry(), the
two rpc specific portions of nfs_readpage_result_full and
nfs_readpage_result_partial.

This allows the non rpc pNFS I/O path to use the same cleanup routines
that NFS uses.

The PNFS_USE_FULL_CB is no longer needed.

Signed-off by: Andy Adamson<andros at umich.edu>
---
 fs/nfs/nfs4proc.c       |    4 ++++
 fs/nfs/pnfs.c           |   13 ++++++++++---
 fs/nfs/read.c           |    4 ++++
 include/linux/nfs_xdr.h |    2 +-
 4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index e3b0f4a..84f1bc7 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2944,6 +2944,10 @@ static int pnfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
 	int status;
 
 	dprintk("--> %s\n", __func__);
+
+	if (data->pnfsflags & PNFS_NO_RPC)
+		return 0;
+
 	status = task->tk_status >= 0 ? 0 : task->tk_status;
 
 	/* Is this a DS session */
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index b072ec0..a7d47bc 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -916,6 +916,8 @@ out:
 
 /* Post-read completion function.  Invoked by non RPC layout drivers
  * to clean up read pages.
+ *
+ * NOTE: called must set data->pnfsflags PNFS_NO_RPC
  */
 static void
 pnfs_read_done(struct nfs_read_data* data, ssize_t status, int eof)
@@ -927,12 +929,17 @@ pnfs_read_done(struct nfs_read_data* data, ssize_t status, int eof)
 	    pnfs_use_nfsv4_rproto(data->inode, data->args.count))
 		return;
 
-	/* Status is the number of bytes written or an error code */
+	/* Status is the number of bytes written or an error code
+	 * the rpc_task is uninitialized, and tk_status is all that
+	 * is used in the call done routines.
+	*/
 	data->task.tk_status = status;
 	data->res.eof = eof;
 	data->res.count = status;
-	pnfs_readpage_result_norpc(&data->task, data);
-	nfs_readdata_release(data);
+
+	/* call the NFS cleanup routines. */
+	data->call_ops->rpc_call_done(&data->task, data);
+	data->call_ops->rpc_release(data);
 }
 
 /*
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 4cf47c5..1852434 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -381,6 +381,10 @@ static int nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *data)
 	struct nfs_readargs *argp = &data->args;
 	struct nfs_readres *resp = &data->res;
 
+#ifdef CONFIG_PNFS
+	if (data->pnfsflags & PNFS_NO_RPC)
+		return 0;
+#endif /* CONFIG_PNFS */
 	if (resp->eof || resp->count == argp->count)
 		return 0;
 
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index a6f429b..f747637 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1069,7 +1069,7 @@ struct nfs_read_data {
 #ifdef CONFIG_PNFS
 /* pnfsflag values */
 #define PNFS_ISSYNC		0x0001   /* sync I/O request */
-#define PNFS_USE_FULL_CB	0x0002   /* non rpc result callback switch */
+#define PNFS_NO_RPC		0x0002   /* non rpc result callback switch */
 #endif /* CONFIG_PNFS */
 
 struct nfs_write_data {
-- 
1.5.0.2



More information about the pNFS mailing list