diff options
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
| -rw-r--r-- | net/sunrpc/rpc_pipe.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 95ccbcf45d3e..8c8eef2b8f26 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -48,7 +48,7 @@ static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, | |||
| 48 | return; | 48 | return; |
| 49 | do { | 49 | do { |
| 50 | msg = list_entry(head->next, struct rpc_pipe_msg, list); | 50 | msg = list_entry(head->next, struct rpc_pipe_msg, list); |
| 51 | list_del(&msg->list); | 51 | list_del_init(&msg->list); |
| 52 | msg->errno = err; | 52 | msg->errno = err; |
| 53 | destroy_msg(msg); | 53 | destroy_msg(msg); |
| 54 | } while (!list_empty(head)); | 54 | } while (!list_empty(head)); |
| @@ -208,7 +208,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp) | |||
| 208 | if (msg != NULL) { | 208 | if (msg != NULL) { |
| 209 | spin_lock(&inode->i_lock); | 209 | spin_lock(&inode->i_lock); |
| 210 | msg->errno = -EAGAIN; | 210 | msg->errno = -EAGAIN; |
| 211 | list_del(&msg->list); | 211 | list_del_init(&msg->list); |
| 212 | spin_unlock(&inode->i_lock); | 212 | spin_unlock(&inode->i_lock); |
| 213 | rpci->ops->destroy_msg(msg); | 213 | rpci->ops->destroy_msg(msg); |
| 214 | } | 214 | } |
| @@ -268,7 +268,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) | |||
| 268 | if (res < 0 || msg->len == msg->copied) { | 268 | if (res < 0 || msg->len == msg->copied) { |
| 269 | filp->private_data = NULL; | 269 | filp->private_data = NULL; |
| 270 | spin_lock(&inode->i_lock); | 270 | spin_lock(&inode->i_lock); |
| 271 | list_del(&msg->list); | 271 | list_del_init(&msg->list); |
| 272 | spin_unlock(&inode->i_lock); | 272 | spin_unlock(&inode->i_lock); |
| 273 | rpci->ops->destroy_msg(msg); | 273 | rpci->ops->destroy_msg(msg); |
| 274 | } | 274 | } |
| @@ -371,21 +371,23 @@ rpc_show_info(struct seq_file *m, void *v) | |||
| 371 | static int | 371 | static int |
| 372 | rpc_info_open(struct inode *inode, struct file *file) | 372 | rpc_info_open(struct inode *inode, struct file *file) |
| 373 | { | 373 | { |
| 374 | struct rpc_clnt *clnt; | 374 | struct rpc_clnt *clnt = NULL; |
| 375 | int ret = single_open(file, rpc_show_info, NULL); | 375 | int ret = single_open(file, rpc_show_info, NULL); |
| 376 | 376 | ||
| 377 | if (!ret) { | 377 | if (!ret) { |
| 378 | struct seq_file *m = file->private_data; | 378 | struct seq_file *m = file->private_data; |
| 379 | mutex_lock(&inode->i_mutex); | 379 | |
| 380 | clnt = RPC_I(inode)->private; | 380 | spin_lock(&file->f_path.dentry->d_lock); |
| 381 | if (clnt) { | 381 | if (!d_unhashed(file->f_path.dentry)) |
| 382 | kref_get(&clnt->cl_kref); | 382 | clnt = RPC_I(inode)->private; |
| 383 | if (clnt != NULL && atomic_inc_not_zero(&clnt->cl_count)) { | ||
| 384 | spin_unlock(&file->f_path.dentry->d_lock); | ||
| 383 | m->private = clnt; | 385 | m->private = clnt; |
| 384 | } else { | 386 | } else { |
| 387 | spin_unlock(&file->f_path.dentry->d_lock); | ||
| 385 | single_release(inode, file); | 388 | single_release(inode, file); |
| 386 | ret = -EINVAL; | 389 | ret = -EINVAL; |
| 387 | } | 390 | } |
| 388 | mutex_unlock(&inode->i_mutex); | ||
| 389 | } | 391 | } |
| 390 | return ret; | 392 | return ret; |
| 391 | } | 393 | } |
