[pnfs] [PATCH 10/10] pnfs: Enable O_DIRECT write path.
Dean Hildebrand
seattleplus at gmail.com
Thu Jul 10 01:25:49 EDT 2008
Benny b wrote:
> On Jul. 09, 2008, 0:54 +0300, Dean Hildebrand <seattleplus at gmail.com> wrote:
>
>> 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)
>>
>
> I don't like the fact that some pnfs_try_to methods may return
> an (negative) error status and some may not. If the return type
> is enum pnfs_try_status then that should be it. In this case,
> pnfs_try_to_commit should just return PNFS_ATTEMPTED and the
> error status, if needed, can be extracted from data->pdata.pnfs_error;
>
Yes, I totally agree. I guess we all need to agree on how ifdef and the
try_to_xxx functions relate (from earlier email). Maybe we can talk
about this tomorrow.
> Benny
>
>
>> + 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;
>>
>
> I'm not sure if this is the right thing to do since in the non-pnfs
> path the error status is not returned.
>
> Benny
>
>
>> + break;
>> + }
>> +#endif /* CONFIG_PNFS */
>> + if (result == PNFS_NOT_ATTEMPTED &&
>> + nfs_direct_write_execute(data, &task_setup_data, &msg))
>> break;
>>
>> started += bytes;
>>
>
>
More information about the pNFS
mailing list