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 |