diff options
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
| -rw-r--r-- | net/sunrpc/rpc_pipe.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index ded6c63f11ec..4f188d0a5d11 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -76,25 +76,35 @@ int | |||
| 76 | rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg) | 76 | rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg) |
| 77 | { | 77 | { |
| 78 | struct rpc_inode *rpci = RPC_I(inode); | 78 | struct rpc_inode *rpci = RPC_I(inode); |
| 79 | int res = 0; | 79 | int res = -EPIPE; |
| 80 | 80 | ||
| 81 | down(&inode->i_sem); | 81 | down(&inode->i_sem); |
| 82 | if (rpci->ops == NULL) | ||
| 83 | goto out; | ||
| 82 | if (rpci->nreaders) { | 84 | if (rpci->nreaders) { |
| 83 | list_add_tail(&msg->list, &rpci->pipe); | 85 | list_add_tail(&msg->list, &rpci->pipe); |
| 84 | rpci->pipelen += msg->len; | 86 | rpci->pipelen += msg->len; |
| 87 | res = 0; | ||
| 85 | } else if (rpci->flags & RPC_PIPE_WAIT_FOR_OPEN) { | 88 | } else if (rpci->flags & RPC_PIPE_WAIT_FOR_OPEN) { |
| 86 | if (list_empty(&rpci->pipe)) | 89 | if (list_empty(&rpci->pipe)) |
| 87 | schedule_delayed_work(&rpci->queue_timeout, | 90 | schedule_delayed_work(&rpci->queue_timeout, |
| 88 | RPC_UPCALL_TIMEOUT); | 91 | RPC_UPCALL_TIMEOUT); |
| 89 | list_add_tail(&msg->list, &rpci->pipe); | 92 | list_add_tail(&msg->list, &rpci->pipe); |
| 90 | rpci->pipelen += msg->len; | 93 | rpci->pipelen += msg->len; |
| 91 | } else | 94 | res = 0; |
| 92 | res = -EPIPE; | 95 | } |
| 96 | out: | ||
| 93 | up(&inode->i_sem); | 97 | up(&inode->i_sem); |
| 94 | wake_up(&rpci->waitq); | 98 | wake_up(&rpci->waitq); |
| 95 | return res; | 99 | return res; |
| 96 | } | 100 | } |
| 97 | 101 | ||
| 102 | static inline void | ||
| 103 | rpc_inode_setowner(struct inode *inode, void *private) | ||
| 104 | { | ||
| 105 | RPC_I(inode)->private = private; | ||
| 106 | } | ||
| 107 | |||
| 98 | static void | 108 | static void |
| 99 | rpc_close_pipes(struct inode *inode) | 109 | rpc_close_pipes(struct inode *inode) |
| 100 | { | 110 | { |
| @@ -111,15 +121,10 @@ rpc_close_pipes(struct inode *inode) | |||
| 111 | rpci->ops->release_pipe(inode); | 121 | rpci->ops->release_pipe(inode); |
| 112 | rpci->ops = NULL; | 122 | rpci->ops = NULL; |
| 113 | } | 123 | } |
| 124 | rpc_inode_setowner(inode, NULL); | ||
| 114 | up(&inode->i_sem); | 125 | up(&inode->i_sem); |
| 115 | } | 126 | } |
| 116 | 127 | ||
| 117 | static inline void | ||
| 118 | rpc_inode_setowner(struct inode *inode, void *private) | ||
| 119 | { | ||
| 120 | RPC_I(inode)->private = private; | ||
| 121 | } | ||
| 122 | |||
| 123 | static struct inode * | 128 | static struct inode * |
| 124 | rpc_alloc_inode(struct super_block *sb) | 129 | rpc_alloc_inode(struct super_block *sb) |
| 125 | { | 130 | { |
| @@ -501,7 +506,6 @@ repeat: | |||
| 501 | dentry = dvec[--n]; | 506 | dentry = dvec[--n]; |
| 502 | if (dentry->d_inode) { | 507 | if (dentry->d_inode) { |
| 503 | rpc_close_pipes(dentry->d_inode); | 508 | rpc_close_pipes(dentry->d_inode); |
| 504 | rpc_inode_setowner(dentry->d_inode, NULL); | ||
| 505 | simple_unlink(dir, dentry); | 509 | simple_unlink(dir, dentry); |
| 506 | } | 510 | } |
| 507 | dput(dentry); | 511 | dput(dentry); |
| @@ -576,10 +580,8 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 576 | int error; | 580 | int error; |
| 577 | 581 | ||
| 578 | shrink_dcache_parent(dentry); | 582 | shrink_dcache_parent(dentry); |
| 579 | if (dentry->d_inode) { | 583 | if (dentry->d_inode) |
| 580 | rpc_close_pipes(dentry->d_inode); | 584 | rpc_close_pipes(dentry->d_inode); |
| 581 | rpc_inode_setowner(dentry->d_inode, NULL); | ||
| 582 | } | ||
| 583 | if ((error = simple_rmdir(dir, dentry)) != 0) | 585 | if ((error = simple_rmdir(dir, dentry)) != 0) |
| 584 | return error; | 586 | return error; |
| 585 | if (!error) { | 587 | if (!error) { |
| @@ -732,7 +734,6 @@ rpc_unlink(char *path) | |||
| 732 | d_drop(dentry); | 734 | d_drop(dentry); |
| 733 | if (dentry->d_inode) { | 735 | if (dentry->d_inode) { |
| 734 | rpc_close_pipes(dentry->d_inode); | 736 | rpc_close_pipes(dentry->d_inode); |
| 735 | rpc_inode_setowner(dentry->d_inode, NULL); | ||
| 736 | error = simple_unlink(dir, dentry); | 737 | error = simple_unlink(dir, dentry); |
| 737 | } | 738 | } |
| 738 | dput(dentry); | 739 | dput(dentry); |
