aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/direct.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-02-19 20:04:20 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-02-26 00:40:33 -0500
commit383ba71938519959be8e0b598ec658f0c211ff45 (patch)
tree01eb0155676fe69d40f01dc137ea3be952d88997 /fs/nfs/direct.c
parent4b5621f6b127bce9218998c187bd25bf7f9fc371 (diff)
NFS: Fix a deadlock with lazy umount
We can't allow rpc callback functions like task->tk_ops->rpc_call_prepare() and task->tk_ops->rpc_call_done() to call mntput() in any way, since that will cause a deadlock when the call to rpc_shutdown_client() attempts to wait on 'task' to complete. We can avoid the above deadlock by moving calls to mntput to task->tk_ops->rpc_release() callback, since at that time the task will be marked as completed, and so rpc_shutdown_client won't attempt to wait on it. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/direct.c')
-rw-r--r--fs/nfs/direct.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 16844f98f50e..e0170407a885 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -323,7 +323,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
323 data->inode = inode; 323 data->inode = inode;
324 data->cred = msg.rpc_cred; 324 data->cred = msg.rpc_cred;
325 data->args.fh = NFS_FH(inode); 325 data->args.fh = NFS_FH(inode);
326 data->args.context = ctx; 326 data->args.context = get_nfs_open_context(ctx);
327 data->args.offset = pos; 327 data->args.offset = pos;
328 data->args.pgbase = pgbase; 328 data->args.pgbase = pgbase;
329 data->args.pages = data->pagevec; 329 data->args.pages = data->pagevec;
@@ -546,6 +546,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
546 data->args.fh = NFS_FH(data->inode); 546 data->args.fh = NFS_FH(data->inode);
547 data->args.offset = 0; 547 data->args.offset = 0;
548 data->args.count = 0; 548 data->args.count = 0;
549 data->args.context = get_nfs_open_context(dreq->ctx);
549 data->res.count = 0; 550 data->res.count = 0;
550 data->res.fattr = &data->fattr; 551 data->res.fattr = &data->fattr;
551 data->res.verf = &data->verf; 552 data->res.verf = &data->verf;
@@ -728,7 +729,7 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
728 data->inode = inode; 729 data->inode = inode;
729 data->cred = msg.rpc_cred; 730 data->cred = msg.rpc_cred;
730 data->args.fh = NFS_FH(inode); 731 data->args.fh = NFS_FH(inode);
731 data->args.context = ctx; 732 data->args.context = get_nfs_open_context(ctx);
732 data->args.offset = pos; 733 data->args.offset = pos;
733 data->args.pgbase = pgbase; 734 data->args.pgbase = pgbase;
734 data->args.pages = data->pagevec; 735 data->args.pages = data->pagevec;