diff options
-rw-r--r-- | fs/nfs/nfs4proc.c | 21 | ||||
-rw-r--r-- | fs/nfs/unlink.c | 13 | ||||
-rw-r--r-- | include/linux/sunrpc/sched.h | 1 | ||||
-rw-r--r-- | net/sunrpc/sched.c | 10 |
4 files changed, 27 insertions, 18 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 3d5d3c0..368b75b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -195,14 +195,13 @@ static void update_changeattr(struct inode *inode, struct nfs4_change_info *cinf } /* Helper for asynchronous RPC calls */ -static int nfs4_call_async(struct rpc_clnt *clnt, rpc_action tk_begin, +static int nfs4_call_async(struct rpc_clnt *clnt, const struct rpc_call_ops *tk_ops, void *calldata) { struct rpc_task *task; if (!(task = rpc_new_task(clnt, RPC_TASK_ASYNC, tk_ops, calldata))) return -ENOMEM; - task->tk_action = tk_begin; rpc_execute(task); return 0; } @@ -882,6 +881,8 @@ static void nfs4_close_done(struct rpc_task *task, void *data) struct nfs4_state *state = calldata->state; struct nfs_server *server = NFS_SERVER(calldata->inode); + if (RPC_ASSASSINATED(task)) + return; /* hmm. we are done with the inode, and in the process of freeing * the state_owner. we keep this around to process errors */ @@ -904,9 +905,9 @@ static void nfs4_close_done(struct rpc_task *task, void *data) nfs_refresh_inode(calldata->inode, calldata->res.fattr); } -static void nfs4_close_begin(struct rpc_task *task) +static void nfs4_close_prepare(struct rpc_task *task, void *data) { - struct nfs4_closedata *calldata = (struct nfs4_closedata *)task->tk_calldata; + struct nfs4_closedata *calldata = data; struct nfs4_state *state = calldata->state; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE], @@ -944,6 +945,7 @@ static void nfs4_close_begin(struct rpc_task *task) } static const struct rpc_call_ops nfs4_close_ops = { + .rpc_call_prepare = nfs4_close_prepare, .rpc_call_done = nfs4_close_done, .rpc_release = nfs4_free_closedata, }; @@ -980,8 +982,7 @@ int nfs4_do_close(struct inode *inode, struct nfs4_state *state) calldata->res.fattr = &calldata->fattr; calldata->res.server = server; - status = nfs4_call_async(server->client, nfs4_close_begin, - &nfs4_close_ops, calldata); + status = nfs4_call_async(server->client, &nfs4_close_ops, calldata); if (status == 0) goto out; @@ -2909,9 +2910,9 @@ static void nfs4_locku_done(struct rpc_task *task, void *data) } } -static void nfs4_locku_begin(struct rpc_task *task) +static void nfs4_locku_prepare(struct rpc_task *task, void *data) { - struct nfs4_unlockdata *calldata = (struct nfs4_unlockdata *)task->tk_calldata; + struct nfs4_unlockdata *calldata = data; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKU], .rpc_argp = &calldata->arg, @@ -2932,6 +2933,7 @@ static void nfs4_locku_begin(struct rpc_task *task) } static const struct rpc_call_ops nfs4_locku_ops = { + .rpc_call_prepare = nfs4_locku_prepare, .rpc_call_done = nfs4_locku_done, .rpc_release = nfs4_locku_complete, }; @@ -2979,8 +2981,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock * atomic_set(&calldata->refcount, 2); init_completion(&calldata->completion); - status = nfs4_call_async(NFS_SERVER(inode)->client, nfs4_locku_begin, - &nfs4_locku_ops, calldata); + status = nfs4_call_async(NFS_SERVER(inode)->client, &nfs4_locku_ops, calldata); if (status == 0) wait_for_completion_interruptible(&calldata->completion); do_vfs_lock(request->fl_file, request); diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index 1494484..a65c7b5 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c @@ -87,10 +87,9 @@ nfs_copy_dname(struct dentry *dentry, struct nfs_unlinkdata *data) * We delay initializing RPC info until after the call to dentry_iput() * in order to minimize races against rename(). */ -static void -nfs_async_unlink_init(struct rpc_task *task) +static void nfs_async_unlink_init(struct rpc_task *task, void *calldata) { - struct nfs_unlinkdata *data = (struct nfs_unlinkdata *)task->tk_calldata; + struct nfs_unlinkdata *data = calldata; struct dentry *dir = data->dir; struct rpc_message msg = { .rpc_cred = data->cred, @@ -147,6 +146,7 @@ static void nfs_async_unlink_release(void *calldata) } static const struct rpc_call_ops nfs_unlink_ops = { + .rpc_call_prepare = nfs_async_unlink_init, .rpc_call_done = nfs_async_unlink_done, .rpc_release = nfs_async_unlink_release, }; @@ -160,7 +160,6 @@ nfs_async_unlink(struct dentry *dentry) { struct dentry *dir = dentry->d_parent; struct nfs_unlinkdata *data; - struct rpc_task *task; struct rpc_clnt *clnt = NFS_CLIENT(dir->d_inode); int status = -ENOMEM; @@ -181,15 +180,13 @@ nfs_async_unlink(struct dentry *dentry) nfs_deletes = data; data->count = 1; - task = &data->task; - rpc_init_task(task, clnt, RPC_TASK_ASYNC, &nfs_unlink_ops, data); - task->tk_action = nfs_async_unlink_init; + rpc_init_task(&data->task, clnt, RPC_TASK_ASYNC, &nfs_unlink_ops, data); spin_lock(&dentry->d_lock); dentry->d_flags |= DCACHE_NFSFS_RENAMED; spin_unlock(&dentry->d_lock); - rpc_sleep_on(&nfs_delete_queue, task, NULL, NULL); + rpc_sleep_on(&nfs_delete_queue, &data->task, NULL, NULL); status = 0; out: return status; diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index 581d8cd..ac1326f 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -112,6 +112,7 @@ struct rpc_task { typedef void (*rpc_action)(struct rpc_task *); struct rpc_call_ops { + void (*rpc_call_prepare)(struct rpc_task *, void *); void (*rpc_call_done)(struct rpc_task *, void *); void (*rpc_release)(void *); }; diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 8d6233d..2d74a16 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -555,6 +555,14 @@ __rpc_atrun(struct rpc_task *task) } /* + * Helper to call task->tk_ops->rpc_call_prepare + */ +static void rpc_prepare_task(struct rpc_task *task) +{ + task->tk_ops->rpc_call_prepare(task, task->tk_calldata); +} + +/* * Helper that calls task->tk_ops->rpc_call_done if it exists */ void rpc_exit_task(struct rpc_task *task) @@ -756,6 +764,8 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, cons task->tk_client = clnt; task->tk_flags = flags; task->tk_ops = tk_ops; + if (tk_ops->rpc_call_prepare != NULL) + task->tk_action = rpc_prepare_task; task->tk_calldata = calldata; /* Initialize retry counters */ |