[pnfs] [PATCH 09/10] pnfs: Enable O_DIRECT read path.

Dean Hildebrand seattleplus at gmail.com
Tue Jul 8 17:54:05 EDT 2008


Signed-off-by: Dean Hildebrand <dhildeb at us.ibm.com>
---
 fs/nfs/direct.c |   37 +++++++++++++++++++++++++++++++++++--
 1 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 854ed47..a397a9c 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -55,6 +55,7 @@
 
 #include "internal.h"
 #include "iostat.h"
+#include "pnfs.h"
 
 #define NFSDBG_FACILITY		NFSDBG_VFS
 
@@ -189,12 +190,22 @@ static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq)
 {
 	ssize_t result = -EIOCBQUEUED;
 
+	if (!pnfs_use_rpc(NFS_SERVER(dreq->inode))) {
+		/* FIXME: Right now non-rpc layout types must perform
+		 * syncronous direct i/o.
+		 * New pNFS callback to wait on outstanding requests?
+		 */
+		result = 0;
+		goto set_result;
+	}
+
 	/* Async requests don't wait here */
 	if (dreq->iocb)
 		goto out;
 
 	result = wait_for_completion_killable(&dreq->completion);
 
+set_result:
 	if (!result)
 		result = dreq->error;
 	if (!result)
@@ -329,6 +340,16 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
 	unsigned int pgbase;
 	int result;
 	ssize_t started = 0;
+	size_t pnfs_stripe_rem = count;
+
+	/* pnfs_stripe_rem will be set to the remaining bytes in
+	 * the first stripe_unit (which for standard nfs is count)
+	 */
+	pnfs_direct_init_io(inode, ctx, count, pos, 0, &rsize,
+			    &pnfs_stripe_rem);
+
+	dprintk("%s: pos %llu count %Zu wsize %Zu\n",
+		__func__, pos, count, rsize);
 
 	do {
 		struct nfs_read_data *data;
@@ -336,6 +357,10 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
 
 		pgbase = user_addr & ~PAGE_MASK;
 		bytes = min(rsize,count);
+#if defined(CONFIG_PNFS)
+		bytes = min(bytes, pnfs_stripe_rem);
+		pnfs_stripe_rem = rsize;
+#endif /* CONFIG_PNFS */
 
 		result = -ENOMEM;
 		data = nfs_readdata_alloc(nfs_page_array_len(pgbase, bytes));
@@ -377,8 +402,16 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
 		data->res.eof = 0;
 		data->res.count = bytes;
 
-		if (nfs_direct_read_execute(data, &task_setup_data, &msg))
-		    break;
+		result = pnfs_try_to_read_data(data, &nfs_read_direct_ops);
+#if defined(CONFIG_PNFS)
+		if (result == PNFS_ATTEMPTED && data->pdata.pnfs_error) {
+			result = data->pdata.pnfs_error;
+			break;
+		}
+#endif /* CONFIG_PNFS */
+		if (result == PNFS_NOT_ATTEMPTED &&
+		    nfs_direct_read_execute(data, &task_setup_data, &msg))
+			break;
 
 		started += bytes;
 		user_addr += bytes;
-- 
1.5.3.3



More information about the pNFS mailing list