aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/rpc_pipe.c
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-01-10 07:12:38 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-01-31 18:20:26 -0500
commitad6b134008f4e765dd19976552b929273ae523bd (patch)
tree5f5fbafe5739155cfce6bb0b1e07a9418a72666f /net/sunrpc/rpc_pipe.c
parent39cb67b9a04300df41e201d9e6392691cdad080f (diff)
SUNRPC: fix pipe->ops cleanup on pipe dentry unlink
This patch looks late due to GSS AUTH patches sent already. But it fixes a flaw in RPC PipeFS pipes handling. I've added this patch in the series, because this series related to pipes. But it should be a part of previous series named "SUNPRC: cleanup PipeFS for network-namespace-aware users". Pipe dentry can be created and destroyed many times during pipe life cycle. This actually means, that we can't set pipe->ops to NULL in rpc_close_pipes() and use this variable as a flag, indicating, that pipe's dentry is unlinking. To follow this restriction, this patch replaces "pipe->ops = NULL" assignment and checks for NULL with "pipe->dentry = NULL" assignment and checks for NULL respectively. This patch also removes check for non-NULL pipe->ops (or pipe->dentry) in rpc_close_pipes() because it always non-NULL now. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
-rw-r--r--net/sunrpc/rpc_pipe.c51
1 files changed, 20 insertions, 31 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 910de4169a8d..6b417fcabdbf 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -86,10 +86,6 @@ rpc_timeout_upcall_queue(struct work_struct *work)
86 void (*destroy_msg)(struct rpc_pipe_msg *); 86 void (*destroy_msg)(struct rpc_pipe_msg *);
87 87
88 spin_lock(&pipe->lock); 88 spin_lock(&pipe->lock);
89 if (pipe->ops == NULL) {
90 spin_unlock(&pipe->lock);
91 return;
92 }
93 destroy_msg = pipe->ops->destroy_msg; 89 destroy_msg = pipe->ops->destroy_msg;
94 if (pipe->nreaders == 0) { 90 if (pipe->nreaders == 0) {
95 list_splice_init(&pipe->pipe, &free_list); 91 list_splice_init(&pipe->pipe, &free_list);
@@ -135,8 +131,6 @@ rpc_queue_upcall(struct rpc_pipe *pipe, struct rpc_pipe_msg *msg)
135 int res = -EPIPE; 131 int res = -EPIPE;
136 132
137 spin_lock(&pipe->lock); 133 spin_lock(&pipe->lock);
138 if (pipe->ops == NULL)
139 goto out;
140 if (pipe->nreaders) { 134 if (pipe->nreaders) {
141 list_add_tail(&msg->list, &pipe->pipe); 135 list_add_tail(&msg->list, &pipe->pipe);
142 pipe->pipelen += msg->len; 136 pipe->pipelen += msg->len;
@@ -150,7 +144,6 @@ rpc_queue_upcall(struct rpc_pipe *pipe, struct rpc_pipe_msg *msg)
150 pipe->pipelen += msg->len; 144 pipe->pipelen += msg->len;
151 res = 0; 145 res = 0;
152 } 146 }
153out:
154 spin_unlock(&pipe->lock); 147 spin_unlock(&pipe->lock);
155 wake_up(&pipe->waitq); 148 wake_up(&pipe->waitq);
156 return res; 149 return res;
@@ -167,27 +160,23 @@ static void
167rpc_close_pipes(struct inode *inode) 160rpc_close_pipes(struct inode *inode)
168{ 161{
169 struct rpc_pipe *pipe = RPC_I(inode)->pipe; 162 struct rpc_pipe *pipe = RPC_I(inode)->pipe;
170 const struct rpc_pipe_ops *ops;
171 int need_release; 163 int need_release;
164 LIST_HEAD(free_list);
172 165
173 mutex_lock(&inode->i_mutex); 166 mutex_lock(&inode->i_mutex);
174 ops = pipe->ops; 167 spin_lock(&pipe->lock);
175 if (ops != NULL) { 168 need_release = pipe->nreaders != 0 || pipe->nwriters != 0;
176 LIST_HEAD(free_list); 169 pipe->nreaders = 0;
177 spin_lock(&pipe->lock); 170 list_splice_init(&pipe->in_upcall, &free_list);
178 need_release = pipe->nreaders != 0 || pipe->nwriters != 0; 171 list_splice_init(&pipe->pipe, &free_list);
179 pipe->nreaders = 0; 172 pipe->pipelen = 0;
180 list_splice_init(&pipe->in_upcall, &free_list); 173 pipe->dentry = NULL;
181 list_splice_init(&pipe->pipe, &free_list); 174 spin_unlock(&pipe->lock);
182 pipe->pipelen = 0; 175 rpc_purge_list(pipe, &free_list, pipe->ops->destroy_msg, -EPIPE);
183 pipe->ops = NULL; 176 pipe->nwriters = 0;
184 spin_unlock(&pipe->lock); 177 if (need_release && pipe->ops->release_pipe)
185 rpc_purge_list(pipe, &free_list, ops->destroy_msg, -EPIPE); 178 pipe->ops->release_pipe(inode);
186 pipe->nwriters = 0; 179 cancel_delayed_work_sync(&pipe->queue_timeout);
187 if (need_release && ops->release_pipe)
188 ops->release_pipe(inode);
189 cancel_delayed_work_sync(&pipe->queue_timeout);
190 }
191 rpc_inode_setowner(inode, NULL); 180 rpc_inode_setowner(inode, NULL);
192 mutex_unlock(&inode->i_mutex); 181 mutex_unlock(&inode->i_mutex);
193} 182}
@@ -223,7 +212,7 @@ rpc_pipe_open(struct inode *inode, struct file *filp)
223 int res = -ENXIO; 212 int res = -ENXIO;
224 213
225 mutex_lock(&inode->i_mutex); 214 mutex_lock(&inode->i_mutex);
226 if (pipe->ops == NULL) 215 if (pipe->dentry == NULL)
227 goto out; 216 goto out;
228 first_open = pipe->nreaders == 0 && pipe->nwriters == 0; 217 first_open = pipe->nreaders == 0 && pipe->nwriters == 0;
229 if (first_open && pipe->ops->open_pipe) { 218 if (first_open && pipe->ops->open_pipe) {
@@ -249,7 +238,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
249 int last_close; 238 int last_close;
250 239
251 mutex_lock(&inode->i_mutex); 240 mutex_lock(&inode->i_mutex);
252 if (pipe->ops == NULL) 241 if (pipe->dentry == NULL)
253 goto out; 242 goto out;
254 msg = filp->private_data; 243 msg = filp->private_data;
255 if (msg != NULL) { 244 if (msg != NULL) {
@@ -290,7 +279,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
290 int res = 0; 279 int res = 0;
291 280
292 mutex_lock(&inode->i_mutex); 281 mutex_lock(&inode->i_mutex);
293 if (pipe->ops == NULL) { 282 if (pipe->dentry == NULL) {
294 res = -EPIPE; 283 res = -EPIPE;
295 goto out_unlock; 284 goto out_unlock;
296 } 285 }
@@ -333,7 +322,7 @@ rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *of
333 322
334 mutex_lock(&inode->i_mutex); 323 mutex_lock(&inode->i_mutex);
335 res = -EPIPE; 324 res = -EPIPE;
336 if (pipe->ops != NULL) 325 if (pipe->dentry != NULL)
337 res = pipe->ops->downcall(filp, buf, len); 326 res = pipe->ops->downcall(filp, buf, len);
338 mutex_unlock(&inode->i_mutex); 327 mutex_unlock(&inode->i_mutex);
339 return res; 328 return res;
@@ -348,7 +337,7 @@ rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait)
348 poll_wait(filp, &pipe->waitq, wait); 337 poll_wait(filp, &pipe->waitq, wait);
349 338
350 mask = POLLOUT | POLLWRNORM; 339 mask = POLLOUT | POLLWRNORM;
351 if (pipe->ops == NULL) 340 if (pipe->dentry == NULL)
352 mask |= POLLERR | POLLHUP; 341 mask |= POLLERR | POLLHUP;
353 if (filp->private_data || !list_empty(&pipe->pipe)) 342 if (filp->private_data || !list_empty(&pipe->pipe))
354 mask |= POLLIN | POLLRDNORM; 343 mask |= POLLIN | POLLRDNORM;
@@ -365,7 +354,7 @@ rpc_pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
365 switch (cmd) { 354 switch (cmd) {
366 case FIONREAD: 355 case FIONREAD:
367 spin_lock(&pipe->lock); 356 spin_lock(&pipe->lock);
368 if (pipe->ops == NULL) { 357 if (pipe->dentry == NULL) {
369 spin_unlock(&pipe->lock); 358 spin_unlock(&pipe->lock);
370 return -EPIPE; 359 return -EPIPE;
371 } 360 }