diff options
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
| -rw-r--r-- | net/sunrpc/rpc_pipe.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 23a2b8f6dc49..192453248870 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -113,7 +113,7 @@ out: | |||
| 113 | wake_up(&rpci->waitq); | 113 | wake_up(&rpci->waitq); |
| 114 | return res; | 114 | return res; |
| 115 | } | 115 | } |
| 116 | EXPORT_SYMBOL(rpc_queue_upcall); | 116 | EXPORT_SYMBOL_GPL(rpc_queue_upcall); |
| 117 | 117 | ||
| 118 | static inline void | 118 | static inline void |
| 119 | rpc_inode_setowner(struct inode *inode, void *private) | 119 | rpc_inode_setowner(struct inode *inode, void *private) |
| @@ -126,13 +126,14 @@ rpc_close_pipes(struct inode *inode) | |||
| 126 | { | 126 | { |
| 127 | struct rpc_inode *rpci = RPC_I(inode); | 127 | struct rpc_inode *rpci = RPC_I(inode); |
| 128 | struct rpc_pipe_ops *ops; | 128 | struct rpc_pipe_ops *ops; |
| 129 | int need_release; | ||
| 129 | 130 | ||
| 130 | mutex_lock(&inode->i_mutex); | 131 | mutex_lock(&inode->i_mutex); |
| 131 | ops = rpci->ops; | 132 | ops = rpci->ops; |
| 132 | if (ops != NULL) { | 133 | if (ops != NULL) { |
| 133 | LIST_HEAD(free_list); | 134 | LIST_HEAD(free_list); |
| 134 | |||
| 135 | spin_lock(&inode->i_lock); | 135 | spin_lock(&inode->i_lock); |
| 136 | need_release = rpci->nreaders != 0 || rpci->nwriters != 0; | ||
| 136 | rpci->nreaders = 0; | 137 | rpci->nreaders = 0; |
| 137 | list_splice_init(&rpci->in_upcall, &free_list); | 138 | list_splice_init(&rpci->in_upcall, &free_list); |
| 138 | list_splice_init(&rpci->pipe, &free_list); | 139 | list_splice_init(&rpci->pipe, &free_list); |
| @@ -141,7 +142,7 @@ rpc_close_pipes(struct inode *inode) | |||
| 141 | spin_unlock(&inode->i_lock); | 142 | spin_unlock(&inode->i_lock); |
| 142 | rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE); | 143 | rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE); |
| 143 | rpci->nwriters = 0; | 144 | rpci->nwriters = 0; |
| 144 | if (ops->release_pipe) | 145 | if (need_release && ops->release_pipe) |
| 145 | ops->release_pipe(inode); | 146 | ops->release_pipe(inode); |
| 146 | cancel_delayed_work_sync(&rpci->queue_timeout); | 147 | cancel_delayed_work_sync(&rpci->queue_timeout); |
| 147 | } | 148 | } |
| @@ -169,16 +170,24 @@ static int | |||
| 169 | rpc_pipe_open(struct inode *inode, struct file *filp) | 170 | rpc_pipe_open(struct inode *inode, struct file *filp) |
| 170 | { | 171 | { |
| 171 | struct rpc_inode *rpci = RPC_I(inode); | 172 | struct rpc_inode *rpci = RPC_I(inode); |
| 173 | int first_open; | ||
| 172 | int res = -ENXIO; | 174 | int res = -ENXIO; |
| 173 | 175 | ||
| 174 | mutex_lock(&inode->i_mutex); | 176 | mutex_lock(&inode->i_mutex); |
| 175 | if (rpci->ops != NULL) { | 177 | if (rpci->ops == NULL) |
| 176 | if (filp->f_mode & FMODE_READ) | 178 | goto out; |
| 177 | rpci->nreaders ++; | 179 | first_open = rpci->nreaders == 0 && rpci->nwriters == 0; |
| 178 | if (filp->f_mode & FMODE_WRITE) | 180 | if (first_open && rpci->ops->open_pipe) { |
| 179 | rpci->nwriters ++; | 181 | res = rpci->ops->open_pipe(inode); |
| 180 | res = 0; | 182 | if (res) |
| 183 | goto out; | ||
| 181 | } | 184 | } |
| 185 | if (filp->f_mode & FMODE_READ) | ||
| 186 | rpci->nreaders++; | ||
| 187 | if (filp->f_mode & FMODE_WRITE) | ||
| 188 | rpci->nwriters++; | ||
| 189 | res = 0; | ||
| 190 | out: | ||
| 182 | mutex_unlock(&inode->i_mutex); | 191 | mutex_unlock(&inode->i_mutex); |
| 183 | return res; | 192 | return res; |
| 184 | } | 193 | } |
| @@ -188,6 +197,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp) | |||
| 188 | { | 197 | { |
| 189 | struct rpc_inode *rpci = RPC_I(inode); | 198 | struct rpc_inode *rpci = RPC_I(inode); |
| 190 | struct rpc_pipe_msg *msg; | 199 | struct rpc_pipe_msg *msg; |
| 200 | int last_close; | ||
| 191 | 201 | ||
| 192 | mutex_lock(&inode->i_mutex); | 202 | mutex_lock(&inode->i_mutex); |
| 193 | if (rpci->ops == NULL) | 203 | if (rpci->ops == NULL) |
| @@ -214,7 +224,8 @@ rpc_pipe_release(struct inode *inode, struct file *filp) | |||
| 214 | rpci->ops->destroy_msg, -EAGAIN); | 224 | rpci->ops->destroy_msg, -EAGAIN); |
| 215 | } | 225 | } |
| 216 | } | 226 | } |
| 217 | if (rpci->ops->release_pipe) | 227 | last_close = rpci->nwriters == 0 && rpci->nreaders == 0; |
| 228 | if (last_close && rpci->ops->release_pipe) | ||
| 218 | rpci->ops->release_pipe(inode); | 229 | rpci->ops->release_pipe(inode); |
| 219 | out: | 230 | out: |
| 220 | mutex_unlock(&inode->i_mutex); | 231 | mutex_unlock(&inode->i_mutex); |
| @@ -396,6 +407,7 @@ enum { | |||
| 396 | RPCAUTH_nfs, | 407 | RPCAUTH_nfs, |
| 397 | RPCAUTH_portmap, | 408 | RPCAUTH_portmap, |
| 398 | RPCAUTH_statd, | 409 | RPCAUTH_statd, |
| 410 | RPCAUTH_nfsd4_cb, | ||
| 399 | RPCAUTH_RootEOF | 411 | RPCAUTH_RootEOF |
| 400 | }; | 412 | }; |
| 401 | 413 | ||
| @@ -429,6 +441,10 @@ static struct rpc_filelist files[] = { | |||
| 429 | .name = "statd", | 441 | .name = "statd", |
| 430 | .mode = S_IFDIR | S_IRUGO | S_IXUGO, | 442 | .mode = S_IFDIR | S_IRUGO | S_IXUGO, |
| 431 | }, | 443 | }, |
| 444 | [RPCAUTH_nfsd4_cb] = { | ||
| 445 | .name = "nfsd4_cb", | ||
| 446 | .mode = S_IFDIR | S_IRUGO | S_IXUGO, | ||
| 447 | }, | ||
| 432 | }; | 448 | }; |
| 433 | 449 | ||
| 434 | enum { | 450 | enum { |
| @@ -748,7 +764,7 @@ rpc_rmdir(struct dentry *dentry) | |||
| 748 | * @name: name of pipe | 764 | * @name: name of pipe |
| 749 | * @private: private data to associate with the pipe, for the caller's use | 765 | * @private: private data to associate with the pipe, for the caller's use |
| 750 | * @ops: operations defining the behavior of the pipe: upcall, downcall, | 766 | * @ops: operations defining the behavior of the pipe: upcall, downcall, |
| 751 | * release_pipe, and destroy_msg. | 767 | * release_pipe, open_pipe, and destroy_msg. |
| 752 | * @flags: rpc_inode flags | 768 | * @flags: rpc_inode flags |
| 753 | * | 769 | * |
| 754 | * Data is made available for userspace to read by calls to | 770 | * Data is made available for userspace to read by calls to |
| @@ -808,7 +824,7 @@ err_dput: | |||
| 808 | -ENOMEM); | 824 | -ENOMEM); |
| 809 | goto out; | 825 | goto out; |
| 810 | } | 826 | } |
| 811 | EXPORT_SYMBOL(rpc_mkpipe); | 827 | EXPORT_SYMBOL_GPL(rpc_mkpipe); |
| 812 | 828 | ||
| 813 | /** | 829 | /** |
| 814 | * rpc_unlink - remove a pipe | 830 | * rpc_unlink - remove a pipe |
| @@ -839,7 +855,7 @@ rpc_unlink(struct dentry *dentry) | |||
| 839 | dput(parent); | 855 | dput(parent); |
| 840 | return error; | 856 | return error; |
| 841 | } | 857 | } |
| 842 | EXPORT_SYMBOL(rpc_unlink); | 858 | EXPORT_SYMBOL_GPL(rpc_unlink); |
| 843 | 859 | ||
| 844 | /* | 860 | /* |
| 845 | * populate the filesystem | 861 | * populate the filesystem |
