[pnfs] [PATCH 10/10] pnfs: Enable O_DIRECT write path.
Dean Hildebrand
seattleplus at gmail.com
Tue Jul 8 17:54:06 EDT 2008
Signed-off-by: Dean Hildebrand <dhildeb at us.ibm.com>
---
fs/nfs/direct.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 42 insertions(+), 1 deletions(-)
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index a397a9c..fe291ad 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -515,6 +515,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
.workqueue = nfsiod_workqueue,
.flags = RPC_TASK_ASYNC,
};
+ int result;
dreq->count = 0;
get_dreq(dreq);
@@ -538,6 +539,13 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
* Reuse data->task; data->args should not have changed
* since the original request was sent.
*/
+ result = pnfs_try_to_write_data(data, &nfs_write_direct_ops,
+ NFS_FILE_SYNC);
+#if defined(CONFIG_PNFS)
+ if (result == PNFS_ATTEMPTED && !data->pdata.pnfs_error)
+ continue;
+#endif /* CONFIG_PNFS */
+
nfs_direct_write_execute(data, &task_setup_data, &msg);
}
@@ -617,6 +625,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
.workqueue = nfsiod_workqueue,
.flags = RPC_TASK_ASYNC,
};
+ int result;
data->inode = dreq->inode;
data->cred = msg.rpc_cred;
@@ -629,6 +638,12 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
data->res.fattr = &data->fattr;
data->res.verf = &data->verf;
+ result = pnfs_try_to_commit(data, &nfs_commit_direct_ops,
+ RPC_TASK_ASYNC);
+ dprintk("%s: pnfs commit result %d\n", __func__, result);
+ if (result <= PNFS_ATTEMPTED)
+ return;
+
nfs_direct_commit_execute(dreq, data, &task_setup_data, &msg);
}
@@ -677,6 +692,9 @@ static void nfs_direct_write_result(struct rpc_task *task, void *calldata)
{
struct nfs_write_data *data = calldata;
+ dprintk("%s: verf: %d stable %d\n", __func__,
+ data->res.verf->committed, data->args.stable);
+
if (nfs_writeback_done(task, data) != 0)
return;
}
@@ -794,6 +812,16 @@ static ssize_t nfs_direct_write_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, 1,
+ &wsize, &pnfs_stripe_rem);
+
+ dprintk("%s: pos %llu count %Zu wsize %Zu\n",
+ __func__, pos, count, wsize);
do {
struct nfs_write_data *data;
@@ -802,6 +830,10 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
pgbase = user_addr & ~PAGE_MASK;
bytes = min(wsize,count);
+#if defined(CONFIG_PNFS)
+ bytes = min(bytes, pnfs_stripe_rem);
+ pnfs_stripe_rem = wsize;
+#endif /* CONFIG_PNFS */
result = -ENOMEM;
data = nfs_writedata_alloc(nfs_page_array_len(pgbase, bytes));
if (unlikely(!data))
@@ -844,7 +876,16 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
data->res.count = bytes;
data->res.verf = &data->verf;
- if (nfs_direct_write_execute(data, &task_setup_data, &msg))
+ result = pnfs_try_to_write_data(data, &nfs_write_direct_ops,
+ sync);
+#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_write_execute(data, &task_setup_data, &msg))
break;
started += bytes;
--
1.5.3.3
More information about the pNFS
mailing list