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/read.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/read.c')
-rw-r--r-- | fs/nfs/read.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 3d7d9631e125..fab0d3720a03 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -73,7 +73,10 @@ static void nfs_readdata_free(struct nfs_read_data *rdata) | |||
73 | 73 | ||
74 | void nfs_readdata_release(void *data) | 74 | void nfs_readdata_release(void *data) |
75 | { | 75 | { |
76 | nfs_readdata_free(data); | 76 | struct nfs_read_data *rdata = data; |
77 | |||
78 | put_nfs_open_context(rdata->args.context); | ||
79 | nfs_readdata_free(rdata); | ||
77 | } | 80 | } |
78 | 81 | ||
79 | static | 82 | static |
@@ -186,7 +189,7 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, | |||
186 | data->args.pgbase = req->wb_pgbase + offset; | 189 | data->args.pgbase = req->wb_pgbase + offset; |
187 | data->args.pages = data->pagevec; | 190 | data->args.pages = data->pagevec; |
188 | data->args.count = count; | 191 | data->args.count = count; |
189 | data->args.context = req->wb_context; | 192 | data->args.context = get_nfs_open_context(req->wb_context); |
190 | 193 | ||
191 | data->res.fattr = &data->fattr; | 194 | data->res.fattr = &data->fattr; |
192 | data->res.count = count; | 195 | data->res.count = count; |