From 84115e1cd4a3614c4e566d4cce31381dce3dbef9 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 14 Jul 2007 15:39:59 -0400 Subject: SUNRPC: Cleanup of rpc_task initialisation Signed-off-by: Trond Myklebust --- fs/nfs/direct.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'fs/nfs/direct.c') diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 3c9d16b4f80c..f9f5fc13dc7d 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -272,6 +272,11 @@ 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_setup task_setup_data = { + .rpc_client = NFS_CLIENT(inode), + .callback_ops = &nfs_read_direct_ops, + .flags = RPC_TASK_ASYNC, + }; unsigned int pgbase; int result; ssize_t started = 0; @@ -322,8 +327,8 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, data->res.eof = 0; data->res.count = bytes; - rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC, - &nfs_read_direct_ops, data); + task_setup_data.callback_data = data; + rpc_init_task(&data->task, &task_setup_data); NFS_PROTO(inode)->read_setup(data); data->task.tk_cookie = (unsigned long) inode; @@ -431,6 +436,11 @@ 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_setup task_setup_data = { + .rpc_client = NFS_CLIENT(inode), + .callback_ops = &nfs_write_direct_ops, + .flags = RPC_TASK_ASYNC, + }; dreq->count = 0; get_dreq(dreq); @@ -451,8 +461,8 @@ 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. */ - rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC, - &nfs_write_direct_ops, data); + task_setup_data.callback_data = data; + rpc_init_task(&data->task, &task_setup_data); NFS_PROTO(inode)->write_setup(data, FLUSH_STABLE); data->task.tk_priority = RPC_PRIORITY_NORMAL; @@ -504,6 +514,12 @@ static const struct rpc_call_ops nfs_commit_direct_ops = { static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) { struct nfs_write_data *data = dreq->commit_data; + struct rpc_task_setup task_setup_data = { + .rpc_client = NFS_CLIENT(dreq->inode), + .callback_ops = &nfs_commit_direct_ops, + .callback_data = data, + .flags = RPC_TASK_ASYNC, + }; data->inode = dreq->inode; data->cred = dreq->ctx->cred; @@ -515,8 +531,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) data->res.fattr = &data->fattr; data->res.verf = &data->verf; - rpc_init_task(&data->task, NFS_CLIENT(dreq->inode), RPC_TASK_ASYNC, - &nfs_commit_direct_ops, data); + rpc_init_task(&data->task, &task_setup_data); NFS_PROTO(data->inode)->commit_setup(data, 0); data->task.tk_priority = RPC_PRIORITY_NORMAL; @@ -641,6 +656,11 @@ 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_setup task_setup_data = { + .rpc_client = NFS_CLIENT(inode), + .callback_ops = &nfs_write_direct_ops, + .flags = RPC_TASK_ASYNC, + }; size_t wsize = NFS_SERVER(inode)->wsize; unsigned int pgbase; int result; @@ -694,8 +714,8 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, data->res.count = bytes; data->res.verf = &data->verf; - rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC, - &nfs_write_direct_ops, data); + task_setup_data.callback_data = data; + rpc_init_task(&data->task, &task_setup_data); NFS_PROTO(inode)->write_setup(data, sync); data->task.tk_priority = RPC_PRIORITY_NORMAL; -- cgit v1.2.3 From 3ff7576ddac06c3d07089e241b40826d24bbf1ac Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 14 Jul 2007 15:40:00 -0400 Subject: SUNRPC: Clean up the initialisation of priority queue scheduling info. We want the default scheduling priority (priority == 0) to remain RPC_PRIORITY_NORMAL. Also ensure that the priority wait queue scheduling is per process id instead of sometimes being per thread, and sometimes being per inode. Signed-off-by: Trond Myklebust --- fs/nfs/direct.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'fs/nfs/direct.c') diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index f9f5fc13dc7d..5bcc764e501a 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -331,8 +331,6 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, rpc_init_task(&data->task, &task_setup_data); NFS_PROTO(inode)->read_setup(data); - data->task.tk_cookie = (unsigned long) inode; - rpc_execute(&data->task); dprintk("NFS: %5u initiated direct read call " @@ -465,9 +463,6 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) rpc_init_task(&data->task, &task_setup_data); NFS_PROTO(inode)->write_setup(data, FLUSH_STABLE); - data->task.tk_priority = RPC_PRIORITY_NORMAL; - data->task.tk_cookie = (unsigned long) inode; - /* * We're called via an RPC callback, so BKL is already held. */ @@ -534,8 +529,6 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) rpc_init_task(&data->task, &task_setup_data); NFS_PROTO(data->inode)->commit_setup(data, 0); - data->task.tk_priority = RPC_PRIORITY_NORMAL; - data->task.tk_cookie = (unsigned long)data->inode; /* Note: task.tk_ops->rpc_release will free dreq->commit_data */ dreq->commit_data = NULL; @@ -718,9 +711,6 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, rpc_init_task(&data->task, &task_setup_data); NFS_PROTO(inode)->write_setup(data, sync); - data->task.tk_priority = RPC_PRIORITY_NORMAL; - data->task.tk_cookie = (unsigned long) inode; - rpc_execute(&data->task); dprintk("NFS: %5u initiated direct write call " -- cgit v1.2.3 From bdc7f021f3a1fade77adf3c2d7f65690566fddfe Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 14 Jul 2007 15:40:00 -0400 Subject: NFS: Clean up the (commit|read|write)_setup() callback routines Move the common code for setting up the nfs_write_data and nfs_read_data structures into fs/nfs/read.c, fs/nfs/write.c and fs/nfs/direct.c. Signed-off-by: Trond Myklebust --- fs/nfs/direct.c | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) (limited to 'fs/nfs/direct.c') diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 5bcc764e501a..244d1bd7002c 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -272,8 +272,12 @@ 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_message msg = { + .rpc_cred = ctx->cred, + }; struct rpc_task_setup task_setup_data = { .rpc_client = NFS_CLIENT(inode), + .rpc_message = &msg, .callback_ops = &nfs_read_direct_ops, .flags = RPC_TASK_ASYNC, }; @@ -316,7 +320,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, data->req = (struct nfs_page *) dreq; data->inode = inode; - data->cred = ctx->cred; + data->cred = msg.rpc_cred; data->args.fh = NFS_FH(inode); data->args.context = ctx; data->args.offset = pos; @@ -326,10 +330,12 @@ 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.callback_data = data; + NFS_PROTO(inode)->read_setup(data, &msg); rpc_init_task(&data->task, &task_setup_data); - NFS_PROTO(inode)->read_setup(data); rpc_execute(&data->task); @@ -434,6 +440,9 @@ 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_message msg = { + .rpc_cred = dreq->ctx->cred, + }; struct rpc_task_setup task_setup_data = { .rpc_client = NFS_CLIENT(inode), .callback_ops = &nfs_write_direct_ops, @@ -448,6 +457,9 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) get_dreq(dreq); + /* Use stable writes */ + data->args.stable = NFS_FILE_SYNC; + /* * Reset data->res. */ @@ -460,8 +472,10 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) * since the original request was sent. */ task_setup_data.callback_data = data; + msg.rpc_argp = &data->args; + msg.rpc_resp = &data->res; + NFS_PROTO(inode)->write_setup(data, &msg); rpc_init_task(&data->task, &task_setup_data); - NFS_PROTO(inode)->write_setup(data, FLUSH_STABLE); /* * We're called via an RPC callback, so BKL is already held. @@ -509,15 +523,21 @@ static const struct rpc_call_ops nfs_commit_direct_ops = { static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) { struct nfs_write_data *data = dreq->commit_data; + struct rpc_message msg = { + .rpc_argp = &data->args, + .rpc_resp = &data->res, + .rpc_cred = dreq->ctx->cred, + }; struct rpc_task_setup task_setup_data = { .rpc_client = NFS_CLIENT(dreq->inode), + .rpc_message = &msg, .callback_ops = &nfs_commit_direct_ops, .callback_data = data, .flags = RPC_TASK_ASYNC, }; data->inode = dreq->inode; - data->cred = dreq->ctx->cred; + data->cred = msg.rpc_cred; data->args.fh = NFS_FH(data->inode); data->args.offset = 0; @@ -526,8 +546,8 @@ 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); rpc_init_task(&data->task, &task_setup_data); - NFS_PROTO(data->inode)->commit_setup(data, 0); /* Note: task.tk_ops->rpc_release will free dreq->commit_data */ dreq->commit_data = NULL; @@ -649,8 +669,12 @@ 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_message msg = { + .rpc_cred = ctx->cred, + }; struct rpc_task_setup task_setup_data = { .rpc_client = NFS_CLIENT(inode), + .rpc_message = &msg, .callback_ops = &nfs_write_direct_ops, .flags = RPC_TASK_ASYNC, }; @@ -696,20 +720,23 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, data->req = (struct nfs_page *) dreq; data->inode = inode; - data->cred = ctx->cred; + data->cred = msg.rpc_cred; data->args.fh = NFS_FH(inode); data->args.context = ctx; data->args.offset = pos; data->args.pgbase = pgbase; data->args.pages = data->pagevec; data->args.count = bytes; + data->args.stable = sync; data->res.fattr = &data->fattr; data->res.count = bytes; data->res.verf = &data->verf; task_setup_data.callback_data = data; + msg.rpc_argp = &data->args; + msg.rpc_resp = &data->res; + NFS_PROTO(inode)->write_setup(data, &msg); rpc_init_task(&data->task, &task_setup_data); - NFS_PROTO(inode)->write_setup(data, sync); rpc_execute(&data->task); @@ -782,7 +809,7 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov, struct rpc_clnt *clnt = NFS_CLIENT(inode); struct nfs_direct_req *dreq; size_t wsize = NFS_SERVER(inode)->wsize; - int sync = 0; + int sync = NFS_UNSTABLE; dreq = nfs_direct_req_alloc(); if (!dreq) @@ -790,7 +817,7 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov, nfs_alloc_commit_data(dreq); if (dreq->commit_data == NULL || count < wsize) - sync = FLUSH_STABLE; + sync = NFS_FILE_SYNC; dreq->inode = inode; dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); -- cgit v1.2.3 From 0773769191d943358a8392fa86abd756d004c4b6 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 25 Oct 2007 18:42:54 -0400 Subject: NFS/SUNRPC: Convert users of rpc_init_task+rpc_execute to rpc_run_task() Signed-off-by: Trond Myklebust --- fs/nfs/direct.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'fs/nfs/direct.c') diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 244d1bd7002c..eadd87f7159f 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -272,6 +272,7 @@ 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, }; @@ -333,11 +334,13 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, 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); - rpc_init_task(&data->task, &task_setup_data); - rpc_execute(&data->task); + 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", @@ -440,6 +443,7 @@ 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,16 +475,18 @@ 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. */ + 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); - rpc_init_task(&data->task, &task_setup_data); /* * We're called via an RPC callback, so BKL is already held. */ - rpc_execute(&data->task); + 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, @@ -523,12 +529,14 @@ static const struct rpc_call_ops nfs_commit_direct_ops = { 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, .rpc_cred = dreq->ctx->cred, }; struct rpc_task_setup task_setup_data = { + .task = &data->task, .rpc_client = NFS_CLIENT(dreq->inode), .rpc_message = &msg, .callback_ops = &nfs_commit_direct_ops, @@ -547,14 +555,15 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) data->res.verf = &data->verf; NFS_PROTO(data->inode)->commit_setup(data, &msg); - rpc_init_task(&data->task, &task_setup_data); /* 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); - rpc_execute(&data->task); + task = rpc_run_task(&task_setup_data); + if (!IS_ERR(task)) + rpc_put_task(task); } static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode) @@ -669,6 +678,7 @@ 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, }; @@ -732,13 +742,15 @@ 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); - rpc_init_task(&data->task, &task_setup_data); - rpc_execute(&data->task); + 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", -- cgit v1.2.3 From f3c391e89c92651105364c6645244118ec9b3952 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 15 Jan 2008 14:17:12 -0500 Subject: NFS: Optimise away the sigmask code in aio/dio reads and writes There are no interruptible waits for asynchronous RPC tasks, so we don't need to wrap calls to rpc_run_task() with an rpc_clnt_sigmask/rpc_clnt_unsigmask pair. Instead we can wrap the wait_for_completion_interruptible() in nfs_direct_wait(). This means that we completely optimise away sigmask setting for the case of non-blocking aio/dio. Signed-off-by: Trond Myklebust --- fs/nfs/direct.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'fs/nfs/direct.c') diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index eadd87f7159f..f8e165c7d5a6 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -188,12 +188,17 @@ static void nfs_direct_req_release(struct nfs_direct_req *dreq) static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq) { ssize_t result = -EIOCBQUEUED; + struct rpc_clnt *clnt; + sigset_t oldset; /* Async requests don't wait here */ if (dreq->iocb) goto out; + clnt = NFS_CLIENT(dreq->inode); + rpc_clnt_sigmask(clnt, &oldset); result = wait_for_completion_interruptible(&dreq->completion); + rpc_clnt_sigunmask(clnt, &oldset); if (!result) result = dreq->error; @@ -403,9 +408,7 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { ssize_t result = 0; - sigset_t oldset; struct inode *inode = iocb->ki_filp->f_mapping->host; - struct rpc_clnt *clnt = NFS_CLIENT(inode); struct nfs_direct_req *dreq; dreq = nfs_direct_req_alloc(); @@ -417,11 +420,9 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov, if (!is_sync_kiocb(iocb)) dreq->iocb = iocb; - rpc_clnt_sigmask(clnt, &oldset); result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos); if (!result) result = nfs_direct_wait(dreq); - rpc_clnt_sigunmask(clnt, &oldset); nfs_direct_req_release(dreq); return result; @@ -816,9 +817,7 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov, size_t count) { ssize_t result = 0; - sigset_t oldset; struct inode *inode = iocb->ki_filp->f_mapping->host; - struct rpc_clnt *clnt = NFS_CLIENT(inode); struct nfs_direct_req *dreq; size_t wsize = NFS_SERVER(inode)->wsize; int sync = NFS_UNSTABLE; @@ -836,11 +835,9 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov, if (!is_sync_kiocb(iocb)) dreq->iocb = iocb; - rpc_clnt_sigmask(clnt, &oldset); result = nfs_direct_write_schedule_iovec(dreq, iov, nr_segs, pos, sync); if (!result) result = nfs_direct_wait(dreq); - rpc_clnt_sigunmask(clnt, &oldset); nfs_direct_req_release(dreq); return result; -- cgit v1.2.3