diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-02-19 20:04:20 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-02-26 00:40:33 -0500 |
commit | 383ba71938519959be8e0b598ec658f0c211ff45 (patch) | |
tree | 01eb0155676fe69d40f01dc137ea3be952d88997 /fs/nfs/direct.c | |
parent | 4b5621f6b127bce9218998c187bd25bf7f9fc371 (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.c | 5 |
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; |