diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-01-03 03:55:36 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-01-06 14:58:51 -0500 |
commit | 969b7f2522c90dfed5d0d2553a91522bda2c3bf3 (patch) | |
tree | 762dddd9aa1bce49c85ea2ec5db3440938242e6e /net/sunrpc/rpc_pipe.c | |
parent | 566dd6064e89b15ff2dec666a421bebf0f98f26c (diff) |
SUNRPC: Fix a potential race in rpc_pipefs.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 16a2458f38f7..24cc23af9b95 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -70,8 +70,11 @@ rpc_timeout_upcall_queue(void *data) | |||
70 | struct inode *inode = &rpci->vfs_inode; | 70 | struct inode *inode = &rpci->vfs_inode; |
71 | 71 | ||
72 | down(&inode->i_sem); | 72 | down(&inode->i_sem); |
73 | if (rpci->ops == NULL) | ||
74 | goto out; | ||
73 | if (rpci->nreaders == 0 && !list_empty(&rpci->pipe)) | 75 | if (rpci->nreaders == 0 && !list_empty(&rpci->pipe)) |
74 | __rpc_purge_upcall(inode, -ETIMEDOUT); | 76 | __rpc_purge_upcall(inode, -ETIMEDOUT); |
77 | out: | ||
75 | up(&inode->i_sem); | 78 | up(&inode->i_sem); |
76 | } | 79 | } |
77 | 80 | ||
@@ -113,8 +116,6 @@ rpc_close_pipes(struct inode *inode) | |||
113 | { | 116 | { |
114 | struct rpc_inode *rpci = RPC_I(inode); | 117 | struct rpc_inode *rpci = RPC_I(inode); |
115 | 118 | ||
116 | cancel_delayed_work(&rpci->queue_timeout); | ||
117 | flush_scheduled_work(); | ||
118 | down(&inode->i_sem); | 119 | down(&inode->i_sem); |
119 | if (rpci->ops != NULL) { | 120 | if (rpci->ops != NULL) { |
120 | rpci->nreaders = 0; | 121 | rpci->nreaders = 0; |
@@ -127,6 +128,8 @@ rpc_close_pipes(struct inode *inode) | |||
127 | } | 128 | } |
128 | rpc_inode_setowner(inode, NULL); | 129 | rpc_inode_setowner(inode, NULL); |
129 | up(&inode->i_sem); | 130 | up(&inode->i_sem); |
131 | cancel_delayed_work(&rpci->queue_timeout); | ||
132 | flush_scheduled_work(); | ||
130 | } | 133 | } |
131 | 134 | ||
132 | static struct inode * | 135 | static struct inode * |
@@ -166,7 +169,7 @@ rpc_pipe_open(struct inode *inode, struct file *filp) | |||
166 | static int | 169 | static int |
167 | rpc_pipe_release(struct inode *inode, struct file *filp) | 170 | rpc_pipe_release(struct inode *inode, struct file *filp) |
168 | { | 171 | { |
169 | struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode); | 172 | struct rpc_inode *rpci = RPC_I(inode); |
170 | struct rpc_pipe_msg *msg; | 173 | struct rpc_pipe_msg *msg; |
171 | 174 | ||
172 | down(&inode->i_sem); | 175 | down(&inode->i_sem); |