aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2010-09-17 17:31:57 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-09-17 17:31:57 -0400
commitd3d4152a5d59af9e13a73efa9e9c24383fbe307f (patch)
tree552ea5586bb64f8fef93825c72e88b9248d02b79 /fs/nfs/nfs4proc.c
parent779c51795bfb35c2403c924b9de90ca9356bc693 (diff)
nfs: make sillyrename an async operation
A synchronous rename can be interrupted by a SIGKILL. If that happens during a sillyrename operation, it's possible for the rename call to be sent to the server, but the task exits before processing the reply. If this happens, the sillyrenamed file won't get cleaned up during nfs_dentry_iput and the server is left with a dangling .nfs* file hanging around. Fix this problem by turning sillyrename into an asynchronous operation and have the task doing the sillyrename just wait on the reply. If the task is killed before the sillyrename completes, it'll still proceed to completion. Signed-off-by: Jeff Layton <jlayton@redhat.com> Reviewed-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index a3c21cc4677b..c46e45e9b33f 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2566,6 +2566,34 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
2566 return 1; 2566 return 1;
2567} 2567}
2568 2568
2569static void nfs4_proc_rename_setup(struct rpc_message *msg, struct inode *dir)
2570{
2571 struct nfs_server *server = NFS_SERVER(dir);
2572 struct nfs_renameargs *arg = msg->rpc_argp;
2573 struct nfs_renameres *res = msg->rpc_resp;
2574
2575 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME];
2576 arg->bitmask = server->attr_bitmask;
2577 res->server = server;
2578}
2579
2580static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
2581 struct inode *new_dir)
2582{
2583 struct nfs_renameres *res = task->tk_msg.rpc_resp;
2584
2585 if (!nfs4_sequence_done(task, &res->seq_res))
2586 return 0;
2587 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
2588 return 0;
2589
2590 update_changeattr(old_dir, &res->old_cinfo);
2591 nfs_post_op_update_inode(old_dir, res->old_fattr);
2592 update_changeattr(new_dir, &res->new_cinfo);
2593 nfs_post_op_update_inode(new_dir, res->new_fattr);
2594 return 1;
2595}
2596
2569static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name, 2597static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
2570 struct inode *new_dir, struct qstr *new_name) 2598 struct inode *new_dir, struct qstr *new_name)
2571{ 2599{
@@ -5338,6 +5366,8 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
5338 .unlink_setup = nfs4_proc_unlink_setup, 5366 .unlink_setup = nfs4_proc_unlink_setup,
5339 .unlink_done = nfs4_proc_unlink_done, 5367 .unlink_done = nfs4_proc_unlink_done,
5340 .rename = nfs4_proc_rename, 5368 .rename = nfs4_proc_rename,
5369 .rename_setup = nfs4_proc_rename_setup,
5370 .rename_done = nfs4_proc_rename_done,
5341 .link = nfs4_proc_link, 5371 .link = nfs4_proc_link,
5342 .symlink = nfs4_proc_symlink, 5372 .symlink = nfs4_proc_symlink,
5343 .mkdir = nfs4_proc_mkdir, 5373 .mkdir = nfs4_proc_mkdir,