[pnfs] [PATCH 2/6] pnfs: Isolate odirect rpc read/write/commit execution.
Benny Halevy
bhalevy at panasas.com
Thu May 29 02:41:16 EDT 2008
On May. 29, 2008, 4:27 +0300, Dean Hildebrand <seattleplus at gmail.com> wrote:
> This patch helps prepare for pNFS, which may not use rpc.
>
> Signed-off-by: Dean Hildebrand <dhildeb at us.ibm.com>
> ---
> fs/nfs/direct.c | 154 +++++++++++++++++++++++++++++-------------------------
> 1 files changed, 83 insertions(+), 71 deletions(-)
>
> diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
> index be2d47e..b0a0a34 100644
> --- a/fs/nfs/direct.c
> +++ b/fs/nfs/direct.c
> @@ -259,6 +259,34 @@ static const struct rpc_call_ops nfs_read_direct_ops = {
> .rpc_release = nfs_readdata_release,
> };
>
> +static void nfs_direct_read_execute(struct nfs_read_data *data,
> + struct rpc_task_setup *task_setup_data,
> + struct rpc_message *msg)
> +{
> + struct inode *inode = data->inode;
> + struct rpc_task *task;
> +
> + msg->rpc_argp = &data->args;
> + msg->rpc_resp = &data->res;
> +
> + task_setup_data->task = &data->task;
> + task_setup_data->callback_data = data;
> + NFS_PROTO(inode)->read_setup(data, msg);
> +
> + task = rpc_run_task(task_setup_data);
> + if (!IS_ERR(task))
> + rpc_put_task(task);
Head up for 2.6.26 (and note to self :)
Trond added error handling around here in
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=dbae4c73f08b8a7980cc912954ade3d4c1fb6147
So the function, when ported to 2.6.26 will return int
and propagate rpc_run_task's error, if any.
Other than that, the patch applies to upstream, therefore
I'll rename it to "nfs: ...".
If Trond agrees, we can send the 2.6.26 version of this patch
upstream early on (for 2.6.27) as I see no risk in refactoring
the code as you did.
Benny
> +
> + dprintk("NFS: %5u initiated direct read call "
> + "(req %s/%Ld, %u bytes @ offset %Lu)\n",
> + data->task.tk_pid,
> + inode->i_sb->s_id,
> + (long long)NFS_FILEID(inode),
> + data->args.count,
> + (unsigned long long)data->args.offset);
> +
> +}
> +
> /*
> * For each rsize'd chunk of the user's buffer, dispatch an NFS READ
> * operation. If nfs_readdata_alloc() or get_user_pages() fails,
> @@ -275,7 +303,6 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
> unsigned long user_addr = (unsigned long)iov->iov_base;
> size_t count = iov->iov_len;
> size_t rsize = NFS_SERVER(inode)->rsize;
> - struct rpc_task *task;
> struct rpc_message msg = {
> .rpc_cred = ctx->cred,
> };
> @@ -335,24 +362,8 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
> data->res.fattr = &data->fattr;
> data->res.eof = 0;
> data->res.count = bytes;
> - msg.rpc_argp = &data->args;
> - msg.rpc_resp = &data->res;
> -
> - task_setup_data.task = &data->task;
> - task_setup_data.callback_data = data;
> - NFS_PROTO(inode)->read_setup(data, &msg);
> -
> - task = rpc_run_task(&task_setup_data);
> - if (!IS_ERR(task))
> - rpc_put_task(task);
>
> - dprintk("NFS: %5u initiated direct read call "
> - "(req %s/%Ld, %zu bytes @ offset %Lu)\n",
> - data->task.tk_pid,
> - inode->i_sb->s_id,
> - (long long)NFS_FILEID(inode),
> - bytes,
> - (unsigned long long)data->args.offset);
> + nfs_direct_read_execute(data, &task_setup_data, &msg);
>
> started += bytes;
> user_addr += bytes;
> @@ -438,12 +449,15 @@ static void nfs_direct_free_writedata(struct nfs_direct_req *dreq)
> }
>
> #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
> +static void nfs_direct_write_execute(struct nfs_write_data *data,
> + struct rpc_task_setup *task_setup_data,
> + struct rpc_message *msg);
> +
> static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
> {
> struct inode *inode = dreq->inode;
> struct list_head *p;
> struct nfs_write_data *data;
> - struct rpc_task *task;
> struct rpc_message msg = {
> .rpc_cred = dreq->ctx->cred,
> };
> @@ -471,29 +485,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
> data->res.count = data->args.count;
> memset(&data->verf, 0, sizeof(data->verf));
>
> - /*
> - * Reuse data->task; data->args should not have changed
> - * since the original request was sent.
> - */
> - task_setup_data.task = &data->task;
> - task_setup_data.callback_data = data;
> - msg.rpc_argp = &data->args;
> - msg.rpc_resp = &data->res;
> - NFS_PROTO(inode)->write_setup(data, &msg);
> -
> - /*
> - * We're called via an RPC callback, so BKL is already held.
> - */
> - task = rpc_run_task(&task_setup_data);
> - if (!IS_ERR(task))
> - rpc_put_task(task);
> -
> - dprintk("NFS: %5u rescheduled direct write call (req %s/%Ld, %u bytes @ offset %Lu)\n",
> - data->task.tk_pid,
> - inode->i_sb->s_id,
> - (long long)NFS_FILEID(inode),
> - data->args.count,
> - (unsigned long long)data->args.offset);
> + nfs_direct_write_execute(data, &task_setup_data, &msg);
> }
>
> if (put_dreq(dreq))
> @@ -529,10 +521,28 @@ static const struct rpc_call_ops nfs_commit_direct_ops = {
> .rpc_release = nfs_commit_release,
> };
>
> +static void nfs_direct_commit_execute(struct nfs_direct_req *dreq,
> + struct nfs_write_data *data,
> + struct rpc_task_setup *task_setup_data,
> + struct rpc_message *msg)
> +{
> + struct rpc_task *task;
> +
> + NFS_PROTO(data->inode)->commit_setup(data, msg);
> +
> + /* Note: task.tk_ops->rpc_release will free dreq->commit_data */
> + dreq->commit_data = NULL;
> +
> + dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid);
> +
> + task = rpc_run_task(task_setup_data);
> + if (!IS_ERR(task))
> + rpc_put_task(task);
> +}
> +
> static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
> {
> struct nfs_write_data *data = dreq->commit_data;
> - struct rpc_task *task;
> struct rpc_message msg = {
> .rpc_argp = &data->args,
> .rpc_resp = &data->res,
> @@ -557,16 +567,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
> data->res.fattr = &data->fattr;
> data->res.verf = &data->verf;
>
> - NFS_PROTO(data->inode)->commit_setup(data, &msg);
> -
> - /* Note: task.tk_ops->rpc_release will free dreq->commit_data */
> - dreq->commit_data = NULL;
> -
> - dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid);
> -
> - task = rpc_run_task(&task_setup_data);
> - if (!IS_ERR(task))
> - rpc_put_task(task);
> + nfs_direct_commit_execute(dreq, data, &task_setup_data, &msg);
> }
>
> static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode)
> @@ -669,6 +670,34 @@ static const struct rpc_call_ops nfs_write_direct_ops = {
> .rpc_release = nfs_direct_write_release,
> };
>
> +static void nfs_direct_write_execute(struct nfs_write_data *data,
> + struct rpc_task_setup *task_setup_data,
> + struct rpc_message *msg)
> +{
> + struct inode *inode = data->inode;
> + struct rpc_task *task;
> +
> + msg->rpc_argp = &data->args;
> + msg->rpc_resp = &data->res;
> +
> + task_setup_data->task = &data->task;
> + task_setup_data->callback_data = data;
> + NFS_PROTO(inode)->write_setup(data, msg);
> +
> + task = rpc_run_task(task_setup_data);
> + if (!IS_ERR(task))
> + rpc_put_task(task);
> +
> + dprintk("NFS: %5u initiated direct write call "
> + "(req %s/%Ld, %u bytes @ offset %Lu)\n",
> + data->task.tk_pid,
> + inode->i_sb->s_id,
> + (long long)NFS_FILEID(inode),
> + data->args.count,
> + (unsigned long long)data->args.offset);
> +
> +}
> +
> /*
> * For each wsize'd chunk of the user's buffer, dispatch an NFS WRITE
> * operation. If nfs_writedata_alloc() or get_user_pages() fails,
> @@ -684,7 +713,6 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
> struct inode *inode = ctx->path.dentry->d_inode;
> unsigned long user_addr = (unsigned long)iov->iov_base;
> size_t count = iov->iov_len;
> - struct rpc_task *task;
> struct rpc_message msg = {
> .rpc_cred = ctx->cred,
> };
> @@ -748,23 +776,7 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
> data->res.count = bytes;
> data->res.verf = &data->verf;
>
> - task_setup_data.task = &data->task;
> - task_setup_data.callback_data = data;
> - msg.rpc_argp = &data->args;
> - msg.rpc_resp = &data->res;
> - NFS_PROTO(inode)->write_setup(data, &msg);
> -
> - task = rpc_run_task(&task_setup_data);
> - if (!IS_ERR(task))
> - rpc_put_task(task);
> -
> - dprintk("NFS: %5u initiated direct write call "
> - "(req %s/%Ld, %zu bytes @ offset %Lu)\n",
> - data->task.tk_pid,
> - inode->i_sb->s_id,
> - (long long)NFS_FILEID(inode),
> - bytes,
> - (unsigned long long)data->args.offset);
> + nfs_direct_write_execute(data, &task_setup_data, &msg);
>
> started += bytes;
> user_addr += bytes;
--
Benny Halevy
Software Architect
Tel/Fax: +972-3-647-8340
Mobile: +972-54-802-8340
US: +1-412-203-3187
bhalevy at panasas.com
Panasas, Inc.
The Leader in Parallel Storage
www.panasas.com
More information about the pNFS
mailing list