aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs3proc.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/nfs3proc.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/nfs3proc.c')
-rw-r--r--fs/nfs/nfs3proc.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index bb41d88e1567..4e9d941ab548 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -438,6 +438,27 @@ nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir)
438 return 1; 438 return 1;
439} 439}
440 440
441static void
442nfs3_proc_rename_setup(struct rpc_message *msg, struct inode *dir)
443{
444 msg->rpc_proc = &nfs3_procedures[NFS3PROC_RENAME];
445}
446
447static int
448nfs3_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
449 struct inode *new_dir)
450{
451 struct nfs_renameres *res;
452
453 if (nfs3_async_handle_jukebox(task, old_dir))
454 return 0;
455 res = task->tk_msg.rpc_resp;
456
457 nfs_post_op_update_inode(old_dir, res->old_fattr);
458 nfs_post_op_update_inode(new_dir, res->new_fattr);
459 return 1;
460}
461
441static int 462static int
442nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name, 463nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
443 struct inode *new_dir, struct qstr *new_name) 464 struct inode *new_dir, struct qstr *new_name)
@@ -842,6 +863,8 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
842 .unlink_setup = nfs3_proc_unlink_setup, 863 .unlink_setup = nfs3_proc_unlink_setup,
843 .unlink_done = nfs3_proc_unlink_done, 864 .unlink_done = nfs3_proc_unlink_done,
844 .rename = nfs3_proc_rename, 865 .rename = nfs3_proc_rename,
866 .rename_setup = nfs3_proc_rename_setup,
867 .rename_done = nfs3_proc_rename_done,
845 .link = nfs3_proc_link, 868 .link = nfs3_proc_link,
846 .symlink = nfs3_proc_symlink, 869 .symlink = nfs3_proc_symlink,
847 .mkdir = nfs3_proc_mkdir, 870 .mkdir = nfs3_proc_mkdir,