diff options
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 501 |
1 files changed, 307 insertions, 194 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 7d6dd6efbdbe..c84c0e0c41cb 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -16,9 +16,9 @@ | |||
16 | #include <linux/namei.h> | 16 | #include <linux/namei.h> |
17 | #include <linux/fsnotify.h> | 17 | #include <linux/fsnotify.h> |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/rcupdate.h> | ||
19 | 20 | ||
20 | #include <asm/ioctls.h> | 21 | #include <asm/ioctls.h> |
21 | #include <linux/fs.h> | ||
22 | #include <linux/poll.h> | 22 | #include <linux/poll.h> |
23 | #include <linux/wait.h> | 23 | #include <linux/wait.h> |
24 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
@@ -27,9 +27,15 @@ | |||
27 | #include <linux/workqueue.h> | 27 | #include <linux/workqueue.h> |
28 | #include <linux/sunrpc/rpc_pipe_fs.h> | 28 | #include <linux/sunrpc/rpc_pipe_fs.h> |
29 | #include <linux/sunrpc/cache.h> | 29 | #include <linux/sunrpc/cache.h> |
30 | #include <linux/nsproxy.h> | ||
31 | #include <linux/notifier.h> | ||
30 | 32 | ||
31 | static struct vfsmount *rpc_mnt __read_mostly; | 33 | #include "netns.h" |
32 | static int rpc_mount_count; | 34 | #include "sunrpc.h" |
35 | |||
36 | #define RPCDBG_FACILITY RPCDBG_DEBUG | ||
37 | |||
38 | #define NET_NAME(net) ((net == &init_net) ? " (init_net)" : "") | ||
33 | 39 | ||
34 | static struct file_system_type rpc_pipe_fs_type; | 40 | static struct file_system_type rpc_pipe_fs_type; |
35 | 41 | ||
@@ -38,7 +44,21 @@ static struct kmem_cache *rpc_inode_cachep __read_mostly; | |||
38 | 44 | ||
39 | #define RPC_UPCALL_TIMEOUT (30*HZ) | 45 | #define RPC_UPCALL_TIMEOUT (30*HZ) |
40 | 46 | ||
41 | static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, | 47 | static BLOCKING_NOTIFIER_HEAD(rpc_pipefs_notifier_list); |
48 | |||
49 | int rpc_pipefs_notifier_register(struct notifier_block *nb) | ||
50 | { | ||
51 | return blocking_notifier_chain_cond_register(&rpc_pipefs_notifier_list, nb); | ||
52 | } | ||
53 | EXPORT_SYMBOL_GPL(rpc_pipefs_notifier_register); | ||
54 | |||
55 | void rpc_pipefs_notifier_unregister(struct notifier_block *nb) | ||
56 | { | ||
57 | blocking_notifier_chain_unregister(&rpc_pipefs_notifier_list, nb); | ||
58 | } | ||
59 | EXPORT_SYMBOL_GPL(rpc_pipefs_notifier_unregister); | ||
60 | |||
61 | static void rpc_purge_list(wait_queue_head_t *waitq, struct list_head *head, | ||
42 | void (*destroy_msg)(struct rpc_pipe_msg *), int err) | 62 | void (*destroy_msg)(struct rpc_pipe_msg *), int err) |
43 | { | 63 | { |
44 | struct rpc_pipe_msg *msg; | 64 | struct rpc_pipe_msg *msg; |
@@ -51,30 +71,31 @@ static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, | |||
51 | msg->errno = err; | 71 | msg->errno = err; |
52 | destroy_msg(msg); | 72 | destroy_msg(msg); |
53 | } while (!list_empty(head)); | 73 | } while (!list_empty(head)); |
54 | wake_up(&rpci->waitq); | 74 | wake_up(waitq); |
55 | } | 75 | } |
56 | 76 | ||
57 | static void | 77 | static void |
58 | rpc_timeout_upcall_queue(struct work_struct *work) | 78 | rpc_timeout_upcall_queue(struct work_struct *work) |
59 | { | 79 | { |
60 | LIST_HEAD(free_list); | 80 | LIST_HEAD(free_list); |
61 | struct rpc_inode *rpci = | 81 | struct rpc_pipe *pipe = |
62 | container_of(work, struct rpc_inode, queue_timeout.work); | 82 | container_of(work, struct rpc_pipe, queue_timeout.work); |
63 | struct inode *inode = &rpci->vfs_inode; | ||
64 | void (*destroy_msg)(struct rpc_pipe_msg *); | 83 | void (*destroy_msg)(struct rpc_pipe_msg *); |
84 | struct dentry *dentry; | ||
65 | 85 | ||
66 | spin_lock(&inode->i_lock); | 86 | spin_lock(&pipe->lock); |
67 | if (rpci->ops == NULL) { | 87 | destroy_msg = pipe->ops->destroy_msg; |
68 | spin_unlock(&inode->i_lock); | 88 | if (pipe->nreaders == 0) { |
69 | return; | 89 | list_splice_init(&pipe->pipe, &free_list); |
90 | pipe->pipelen = 0; | ||
70 | } | 91 | } |
71 | destroy_msg = rpci->ops->destroy_msg; | 92 | dentry = dget(pipe->dentry); |
72 | if (rpci->nreaders == 0) { | 93 | spin_unlock(&pipe->lock); |
73 | list_splice_init(&rpci->pipe, &free_list); | 94 | if (dentry) { |
74 | rpci->pipelen = 0; | 95 | rpc_purge_list(&RPC_I(dentry->d_inode)->waitq, |
96 | &free_list, destroy_msg, -ETIMEDOUT); | ||
97 | dput(dentry); | ||
75 | } | 98 | } |
76 | spin_unlock(&inode->i_lock); | ||
77 | rpc_purge_list(rpci, &free_list, destroy_msg, -ETIMEDOUT); | ||
78 | } | 99 | } |
79 | 100 | ||
80 | ssize_t rpc_pipe_generic_upcall(struct file *filp, struct rpc_pipe_msg *msg, | 101 | ssize_t rpc_pipe_generic_upcall(struct file *filp, struct rpc_pipe_msg *msg, |
@@ -108,30 +129,31 @@ EXPORT_SYMBOL_GPL(rpc_pipe_generic_upcall); | |||
108 | * initialize the fields of @msg (other than @msg->list) appropriately. | 129 | * initialize the fields of @msg (other than @msg->list) appropriately. |
109 | */ | 130 | */ |
110 | int | 131 | int |
111 | rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg) | 132 | rpc_queue_upcall(struct rpc_pipe *pipe, struct rpc_pipe_msg *msg) |
112 | { | 133 | { |
113 | struct rpc_inode *rpci = RPC_I(inode); | ||
114 | int res = -EPIPE; | 134 | int res = -EPIPE; |
135 | struct dentry *dentry; | ||
115 | 136 | ||
116 | spin_lock(&inode->i_lock); | 137 | spin_lock(&pipe->lock); |
117 | if (rpci->ops == NULL) | 138 | if (pipe->nreaders) { |
118 | goto out; | 139 | list_add_tail(&msg->list, &pipe->pipe); |
119 | if (rpci->nreaders) { | 140 | pipe->pipelen += msg->len; |
120 | list_add_tail(&msg->list, &rpci->pipe); | ||
121 | rpci->pipelen += msg->len; | ||
122 | res = 0; | 141 | res = 0; |
123 | } else if (rpci->flags & RPC_PIPE_WAIT_FOR_OPEN) { | 142 | } else if (pipe->flags & RPC_PIPE_WAIT_FOR_OPEN) { |
124 | if (list_empty(&rpci->pipe)) | 143 | if (list_empty(&pipe->pipe)) |
125 | queue_delayed_work(rpciod_workqueue, | 144 | queue_delayed_work(rpciod_workqueue, |
126 | &rpci->queue_timeout, | 145 | &pipe->queue_timeout, |
127 | RPC_UPCALL_TIMEOUT); | 146 | RPC_UPCALL_TIMEOUT); |
128 | list_add_tail(&msg->list, &rpci->pipe); | 147 | list_add_tail(&msg->list, &pipe->pipe); |
129 | rpci->pipelen += msg->len; | 148 | pipe->pipelen += msg->len; |
130 | res = 0; | 149 | res = 0; |
131 | } | 150 | } |
132 | out: | 151 | dentry = dget(pipe->dentry); |
133 | spin_unlock(&inode->i_lock); | 152 | spin_unlock(&pipe->lock); |
134 | wake_up(&rpci->waitq); | 153 | if (dentry) { |
154 | wake_up(&RPC_I(dentry->d_inode)->waitq); | ||
155 | dput(dentry); | ||
156 | } | ||
135 | return res; | 157 | return res; |
136 | } | 158 | } |
137 | EXPORT_SYMBOL_GPL(rpc_queue_upcall); | 159 | EXPORT_SYMBOL_GPL(rpc_queue_upcall); |
@@ -145,29 +167,26 @@ rpc_inode_setowner(struct inode *inode, void *private) | |||
145 | static void | 167 | static void |
146 | rpc_close_pipes(struct inode *inode) | 168 | rpc_close_pipes(struct inode *inode) |
147 | { | 169 | { |
148 | struct rpc_inode *rpci = RPC_I(inode); | 170 | struct rpc_pipe *pipe = RPC_I(inode)->pipe; |
149 | const struct rpc_pipe_ops *ops; | ||
150 | int need_release; | 171 | int need_release; |
172 | LIST_HEAD(free_list); | ||
151 | 173 | ||
152 | mutex_lock(&inode->i_mutex); | 174 | mutex_lock(&inode->i_mutex); |
153 | ops = rpci->ops; | 175 | spin_lock(&pipe->lock); |
154 | if (ops != NULL) { | 176 | need_release = pipe->nreaders != 0 || pipe->nwriters != 0; |
155 | LIST_HEAD(free_list); | 177 | pipe->nreaders = 0; |
156 | spin_lock(&inode->i_lock); | 178 | list_splice_init(&pipe->in_upcall, &free_list); |
157 | need_release = rpci->nreaders != 0 || rpci->nwriters != 0; | 179 | list_splice_init(&pipe->pipe, &free_list); |
158 | rpci->nreaders = 0; | 180 | pipe->pipelen = 0; |
159 | list_splice_init(&rpci->in_upcall, &free_list); | 181 | pipe->dentry = NULL; |
160 | list_splice_init(&rpci->pipe, &free_list); | 182 | spin_unlock(&pipe->lock); |
161 | rpci->pipelen = 0; | 183 | rpc_purge_list(&RPC_I(inode)->waitq, &free_list, pipe->ops->destroy_msg, -EPIPE); |
162 | rpci->ops = NULL; | 184 | pipe->nwriters = 0; |
163 | spin_unlock(&inode->i_lock); | 185 | if (need_release && pipe->ops->release_pipe) |
164 | rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE); | 186 | pipe->ops->release_pipe(inode); |
165 | rpci->nwriters = 0; | 187 | cancel_delayed_work_sync(&pipe->queue_timeout); |
166 | if (need_release && ops->release_pipe) | ||
167 | ops->release_pipe(inode); | ||
168 | cancel_delayed_work_sync(&rpci->queue_timeout); | ||
169 | } | ||
170 | rpc_inode_setowner(inode, NULL); | 188 | rpc_inode_setowner(inode, NULL); |
189 | RPC_I(inode)->pipe = NULL; | ||
171 | mutex_unlock(&inode->i_mutex); | 190 | mutex_unlock(&inode->i_mutex); |
172 | } | 191 | } |
173 | 192 | ||
@@ -197,23 +216,24 @@ rpc_destroy_inode(struct inode *inode) | |||
197 | static int | 216 | static int |
198 | rpc_pipe_open(struct inode *inode, struct file *filp) | 217 | rpc_pipe_open(struct inode *inode, struct file *filp) |
199 | { | 218 | { |
200 | struct rpc_inode *rpci = RPC_I(inode); | 219 | struct rpc_pipe *pipe; |
201 | int first_open; | 220 | int first_open; |
202 | int res = -ENXIO; | 221 | int res = -ENXIO; |
203 | 222 | ||
204 | mutex_lock(&inode->i_mutex); | 223 | mutex_lock(&inode->i_mutex); |
205 | if (rpci->ops == NULL) | 224 | pipe = RPC_I(inode)->pipe; |
225 | if (pipe == NULL) | ||
206 | goto out; | 226 | goto out; |
207 | first_open = rpci->nreaders == 0 && rpci->nwriters == 0; | 227 | first_open = pipe->nreaders == 0 && pipe->nwriters == 0; |
208 | if (first_open && rpci->ops->open_pipe) { | 228 | if (first_open && pipe->ops->open_pipe) { |
209 | res = rpci->ops->open_pipe(inode); | 229 | res = pipe->ops->open_pipe(inode); |
210 | if (res) | 230 | if (res) |
211 | goto out; | 231 | goto out; |
212 | } | 232 | } |
213 | if (filp->f_mode & FMODE_READ) | 233 | if (filp->f_mode & FMODE_READ) |
214 | rpci->nreaders++; | 234 | pipe->nreaders++; |
215 | if (filp->f_mode & FMODE_WRITE) | 235 | if (filp->f_mode & FMODE_WRITE) |
216 | rpci->nwriters++; | 236 | pipe->nwriters++; |
217 | res = 0; | 237 | res = 0; |
218 | out: | 238 | out: |
219 | mutex_unlock(&inode->i_mutex); | 239 | mutex_unlock(&inode->i_mutex); |
@@ -223,38 +243,39 @@ out: | |||
223 | static int | 243 | static int |
224 | rpc_pipe_release(struct inode *inode, struct file *filp) | 244 | rpc_pipe_release(struct inode *inode, struct file *filp) |
225 | { | 245 | { |
226 | struct rpc_inode *rpci = RPC_I(inode); | 246 | struct rpc_pipe *pipe; |
227 | struct rpc_pipe_msg *msg; | 247 | struct rpc_pipe_msg *msg; |
228 | int last_close; | 248 | int last_close; |
229 | 249 | ||
230 | mutex_lock(&inode->i_mutex); | 250 | mutex_lock(&inode->i_mutex); |
231 | if (rpci->ops == NULL) | 251 | pipe = RPC_I(inode)->pipe; |
252 | if (pipe == NULL) | ||
232 | goto out; | 253 | goto out; |
233 | msg = filp->private_data; | 254 | msg = filp->private_data; |
234 | if (msg != NULL) { | 255 | if (msg != NULL) { |
235 | spin_lock(&inode->i_lock); | 256 | spin_lock(&pipe->lock); |
236 | msg->errno = -EAGAIN; | 257 | msg->errno = -EAGAIN; |
237 | list_del_init(&msg->list); | 258 | list_del_init(&msg->list); |
238 | spin_unlock(&inode->i_lock); | 259 | spin_unlock(&pipe->lock); |
239 | rpci->ops->destroy_msg(msg); | 260 | pipe->ops->destroy_msg(msg); |
240 | } | 261 | } |
241 | if (filp->f_mode & FMODE_WRITE) | 262 | if (filp->f_mode & FMODE_WRITE) |
242 | rpci->nwriters --; | 263 | pipe->nwriters --; |
243 | if (filp->f_mode & FMODE_READ) { | 264 | if (filp->f_mode & FMODE_READ) { |
244 | rpci->nreaders --; | 265 | pipe->nreaders --; |
245 | if (rpci->nreaders == 0) { | 266 | if (pipe->nreaders == 0) { |
246 | LIST_HEAD(free_list); | 267 | LIST_HEAD(free_list); |
247 | spin_lock(&inode->i_lock); | 268 | spin_lock(&pipe->lock); |
248 | list_splice_init(&rpci->pipe, &free_list); | 269 | list_splice_init(&pipe->pipe, &free_list); |
249 | rpci->pipelen = 0; | 270 | pipe->pipelen = 0; |
250 | spin_unlock(&inode->i_lock); | 271 | spin_unlock(&pipe->lock); |
251 | rpc_purge_list(rpci, &free_list, | 272 | rpc_purge_list(&RPC_I(inode)->waitq, &free_list, |
252 | rpci->ops->destroy_msg, -EAGAIN); | 273 | pipe->ops->destroy_msg, -EAGAIN); |
253 | } | 274 | } |
254 | } | 275 | } |
255 | last_close = rpci->nwriters == 0 && rpci->nreaders == 0; | 276 | last_close = pipe->nwriters == 0 && pipe->nreaders == 0; |
256 | if (last_close && rpci->ops->release_pipe) | 277 | if (last_close && pipe->ops->release_pipe) |
257 | rpci->ops->release_pipe(inode); | 278 | pipe->ops->release_pipe(inode); |
258 | out: | 279 | out: |
259 | mutex_unlock(&inode->i_mutex); | 280 | mutex_unlock(&inode->i_mutex); |
260 | return 0; | 281 | return 0; |
@@ -264,39 +285,40 @@ static ssize_t | |||
264 | rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) | 285 | rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) |
265 | { | 286 | { |
266 | struct inode *inode = filp->f_path.dentry->d_inode; | 287 | struct inode *inode = filp->f_path.dentry->d_inode; |
267 | struct rpc_inode *rpci = RPC_I(inode); | 288 | struct rpc_pipe *pipe; |
268 | struct rpc_pipe_msg *msg; | 289 | struct rpc_pipe_msg *msg; |
269 | int res = 0; | 290 | int res = 0; |
270 | 291 | ||
271 | mutex_lock(&inode->i_mutex); | 292 | mutex_lock(&inode->i_mutex); |
272 | if (rpci->ops == NULL) { | 293 | pipe = RPC_I(inode)->pipe; |
294 | if (pipe == NULL) { | ||
273 | res = -EPIPE; | 295 | res = -EPIPE; |
274 | goto out_unlock; | 296 | goto out_unlock; |
275 | } | 297 | } |
276 | msg = filp->private_data; | 298 | msg = filp->private_data; |
277 | if (msg == NULL) { | 299 | if (msg == NULL) { |
278 | spin_lock(&inode->i_lock); | 300 | spin_lock(&pipe->lock); |
279 | if (!list_empty(&rpci->pipe)) { | 301 | if (!list_empty(&pipe->pipe)) { |
280 | msg = list_entry(rpci->pipe.next, | 302 | msg = list_entry(pipe->pipe.next, |
281 | struct rpc_pipe_msg, | 303 | struct rpc_pipe_msg, |
282 | list); | 304 | list); |
283 | list_move(&msg->list, &rpci->in_upcall); | 305 | list_move(&msg->list, &pipe->in_upcall); |
284 | rpci->pipelen -= msg->len; | 306 | pipe->pipelen -= msg->len; |
285 | filp->private_data = msg; | 307 | filp->private_data = msg; |
286 | msg->copied = 0; | 308 | msg->copied = 0; |
287 | } | 309 | } |
288 | spin_unlock(&inode->i_lock); | 310 | spin_unlock(&pipe->lock); |
289 | if (msg == NULL) | 311 | if (msg == NULL) |
290 | goto out_unlock; | 312 | goto out_unlock; |
291 | } | 313 | } |
292 | /* NOTE: it is up to the callback to update msg->copied */ | 314 | /* NOTE: it is up to the callback to update msg->copied */ |
293 | res = rpci->ops->upcall(filp, msg, buf, len); | 315 | res = pipe->ops->upcall(filp, msg, buf, len); |
294 | if (res < 0 || msg->len == msg->copied) { | 316 | if (res < 0 || msg->len == msg->copied) { |
295 | filp->private_data = NULL; | 317 | filp->private_data = NULL; |
296 | spin_lock(&inode->i_lock); | 318 | spin_lock(&pipe->lock); |
297 | list_del_init(&msg->list); | 319 | list_del_init(&msg->list); |
298 | spin_unlock(&inode->i_lock); | 320 | spin_unlock(&pipe->lock); |
299 | rpci->ops->destroy_msg(msg); | 321 | pipe->ops->destroy_msg(msg); |
300 | } | 322 | } |
301 | out_unlock: | 323 | out_unlock: |
302 | mutex_unlock(&inode->i_mutex); | 324 | mutex_unlock(&inode->i_mutex); |
@@ -307,13 +329,12 @@ static ssize_t | |||
307 | rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *offset) | 329 | rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *offset) |
308 | { | 330 | { |
309 | struct inode *inode = filp->f_path.dentry->d_inode; | 331 | struct inode *inode = filp->f_path.dentry->d_inode; |
310 | struct rpc_inode *rpci = RPC_I(inode); | ||
311 | int res; | 332 | int res; |
312 | 333 | ||
313 | mutex_lock(&inode->i_mutex); | 334 | mutex_lock(&inode->i_mutex); |
314 | res = -EPIPE; | 335 | res = -EPIPE; |
315 | if (rpci->ops != NULL) | 336 | if (RPC_I(inode)->pipe != NULL) |
316 | res = rpci->ops->downcall(filp, buf, len); | 337 | res = RPC_I(inode)->pipe->ops->downcall(filp, buf, len); |
317 | mutex_unlock(&inode->i_mutex); | 338 | mutex_unlock(&inode->i_mutex); |
318 | return res; | 339 | return res; |
319 | } | 340 | } |
@@ -321,17 +342,18 @@ rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *of | |||
321 | static unsigned int | 342 | static unsigned int |
322 | rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait) | 343 | rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait) |
323 | { | 344 | { |
324 | struct rpc_inode *rpci; | 345 | struct inode *inode = filp->f_path.dentry->d_inode; |
325 | unsigned int mask = 0; | 346 | struct rpc_inode *rpci = RPC_I(inode); |
347 | unsigned int mask = POLLOUT | POLLWRNORM; | ||
326 | 348 | ||
327 | rpci = RPC_I(filp->f_path.dentry->d_inode); | ||
328 | poll_wait(filp, &rpci->waitq, wait); | 349 | poll_wait(filp, &rpci->waitq, wait); |
329 | 350 | ||
330 | mask = POLLOUT | POLLWRNORM; | 351 | mutex_lock(&inode->i_mutex); |
331 | if (rpci->ops == NULL) | 352 | if (rpci->pipe == NULL) |
332 | mask |= POLLERR | POLLHUP; | 353 | mask |= POLLERR | POLLHUP; |
333 | if (filp->private_data || !list_empty(&rpci->pipe)) | 354 | else if (filp->private_data || !list_empty(&rpci->pipe->pipe)) |
334 | mask |= POLLIN | POLLRDNORM; | 355 | mask |= POLLIN | POLLRDNORM; |
356 | mutex_unlock(&inode->i_mutex); | ||
335 | return mask; | 357 | return mask; |
336 | } | 358 | } |
337 | 359 | ||
@@ -339,23 +361,26 @@ static long | |||
339 | rpc_pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 361 | rpc_pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
340 | { | 362 | { |
341 | struct inode *inode = filp->f_path.dentry->d_inode; | 363 | struct inode *inode = filp->f_path.dentry->d_inode; |
342 | struct rpc_inode *rpci = RPC_I(inode); | 364 | struct rpc_pipe *pipe; |
343 | int len; | 365 | int len; |
344 | 366 | ||
345 | switch (cmd) { | 367 | switch (cmd) { |
346 | case FIONREAD: | 368 | case FIONREAD: |
347 | spin_lock(&inode->i_lock); | 369 | mutex_lock(&inode->i_mutex); |
348 | if (rpci->ops == NULL) { | 370 | pipe = RPC_I(inode)->pipe; |
349 | spin_unlock(&inode->i_lock); | 371 | if (pipe == NULL) { |
372 | mutex_unlock(&inode->i_mutex); | ||
350 | return -EPIPE; | 373 | return -EPIPE; |
351 | } | 374 | } |
352 | len = rpci->pipelen; | 375 | spin_lock(&pipe->lock); |
376 | len = pipe->pipelen; | ||
353 | if (filp->private_data) { | 377 | if (filp->private_data) { |
354 | struct rpc_pipe_msg *msg; | 378 | struct rpc_pipe_msg *msg; |
355 | msg = filp->private_data; | 379 | msg = filp->private_data; |
356 | len += msg->len - msg->copied; | 380 | len += msg->len - msg->copied; |
357 | } | 381 | } |
358 | spin_unlock(&inode->i_lock); | 382 | spin_unlock(&pipe->lock); |
383 | mutex_unlock(&inode->i_mutex); | ||
359 | return put_user(len, (int __user *)arg); | 384 | return put_user(len, (int __user *)arg); |
360 | default: | 385 | default: |
361 | return -EINVAL; | 386 | return -EINVAL; |
@@ -378,12 +403,15 @@ rpc_show_info(struct seq_file *m, void *v) | |||
378 | { | 403 | { |
379 | struct rpc_clnt *clnt = m->private; | 404 | struct rpc_clnt *clnt = m->private; |
380 | 405 | ||
381 | seq_printf(m, "RPC server: %s\n", clnt->cl_server); | 406 | rcu_read_lock(); |
407 | seq_printf(m, "RPC server: %s\n", | ||
408 | rcu_dereference(clnt->cl_xprt)->servername); | ||
382 | seq_printf(m, "service: %s (%d) version %d\n", clnt->cl_protname, | 409 | seq_printf(m, "service: %s (%d) version %d\n", clnt->cl_protname, |
383 | clnt->cl_prog, clnt->cl_vers); | 410 | clnt->cl_prog, clnt->cl_vers); |
384 | seq_printf(m, "address: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR)); | 411 | seq_printf(m, "address: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR)); |
385 | seq_printf(m, "protocol: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_PROTO)); | 412 | seq_printf(m, "protocol: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_PROTO)); |
386 | seq_printf(m, "port: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_PORT)); | 413 | seq_printf(m, "port: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_PORT)); |
414 | rcu_read_unlock(); | ||
387 | return 0; | 415 | return 0; |
388 | } | 416 | } |
389 | 417 | ||
@@ -440,23 +468,6 @@ struct rpc_filelist { | |||
440 | umode_t mode; | 468 | umode_t mode; |
441 | }; | 469 | }; |
442 | 470 | ||
443 | struct vfsmount *rpc_get_mount(void) | ||
444 | { | ||
445 | int err; | ||
446 | |||
447 | err = simple_pin_fs(&rpc_pipe_fs_type, &rpc_mnt, &rpc_mount_count); | ||
448 | if (err != 0) | ||
449 | return ERR_PTR(err); | ||
450 | return rpc_mnt; | ||
451 | } | ||
452 | EXPORT_SYMBOL_GPL(rpc_get_mount); | ||
453 | |||
454 | void rpc_put_mount(void) | ||
455 | { | ||
456 | simple_release_fs(&rpc_mnt, &rpc_mount_count); | ||
457 | } | ||
458 | EXPORT_SYMBOL_GPL(rpc_put_mount); | ||
459 | |||
460 | static int rpc_delete_dentry(const struct dentry *dentry) | 471 | static int rpc_delete_dentry(const struct dentry *dentry) |
461 | { | 472 | { |
462 | return 1; | 473 | return 1; |
@@ -540,12 +551,47 @@ static int __rpc_mkdir(struct inode *dir, struct dentry *dentry, | |||
540 | return 0; | 551 | return 0; |
541 | } | 552 | } |
542 | 553 | ||
543 | static int __rpc_mkpipe(struct inode *dir, struct dentry *dentry, | 554 | static void |
544 | umode_t mode, | 555 | init_pipe(struct rpc_pipe *pipe) |
545 | const struct file_operations *i_fop, | 556 | { |
546 | void *private, | 557 | pipe->nreaders = 0; |
547 | const struct rpc_pipe_ops *ops, | 558 | pipe->nwriters = 0; |
548 | int flags) | 559 | INIT_LIST_HEAD(&pipe->in_upcall); |
560 | INIT_LIST_HEAD(&pipe->in_downcall); | ||
561 | INIT_LIST_HEAD(&pipe->pipe); | ||
562 | pipe->pipelen = 0; | ||
563 | INIT_DELAYED_WORK(&pipe->queue_timeout, | ||
564 | rpc_timeout_upcall_queue); | ||
565 | pipe->ops = NULL; | ||
566 | spin_lock_init(&pipe->lock); | ||
567 | pipe->dentry = NULL; | ||
568 | } | ||
569 | |||
570 | void rpc_destroy_pipe_data(struct rpc_pipe *pipe) | ||
571 | { | ||
572 | kfree(pipe); | ||
573 | } | ||
574 | EXPORT_SYMBOL_GPL(rpc_destroy_pipe_data); | ||
575 | |||
576 | struct rpc_pipe *rpc_mkpipe_data(const struct rpc_pipe_ops *ops, int flags) | ||
577 | { | ||
578 | struct rpc_pipe *pipe; | ||
579 | |||
580 | pipe = kzalloc(sizeof(struct rpc_pipe), GFP_KERNEL); | ||
581 | if (!pipe) | ||
582 | return ERR_PTR(-ENOMEM); | ||
583 | init_pipe(pipe); | ||
584 | pipe->ops = ops; | ||
585 | pipe->flags = flags; | ||
586 | return pipe; | ||
587 | } | ||
588 | EXPORT_SYMBOL_GPL(rpc_mkpipe_data); | ||
589 | |||
590 | static int __rpc_mkpipe_dentry(struct inode *dir, struct dentry *dentry, | ||
591 | umode_t mode, | ||
592 | const struct file_operations *i_fop, | ||
593 | void *private, | ||
594 | struct rpc_pipe *pipe) | ||
549 | { | 595 | { |
550 | struct rpc_inode *rpci; | 596 | struct rpc_inode *rpci; |
551 | int err; | 597 | int err; |
@@ -554,10 +600,8 @@ static int __rpc_mkpipe(struct inode *dir, struct dentry *dentry, | |||
554 | if (err) | 600 | if (err) |
555 | return err; | 601 | return err; |
556 | rpci = RPC_I(dentry->d_inode); | 602 | rpci = RPC_I(dentry->d_inode); |
557 | rpci->nkern_readwriters = 1; | ||
558 | rpci->private = private; | 603 | rpci->private = private; |
559 | rpci->flags = flags; | 604 | rpci->pipe = pipe; |
560 | rpci->ops = ops; | ||
561 | fsnotify_create(dir, dentry); | 605 | fsnotify_create(dir, dentry); |
562 | return 0; | 606 | return 0; |
563 | } | 607 | } |
@@ -573,6 +617,22 @@ static int __rpc_rmdir(struct inode *dir, struct dentry *dentry) | |||
573 | return ret; | 617 | return ret; |
574 | } | 618 | } |
575 | 619 | ||
620 | int rpc_rmdir(struct dentry *dentry) | ||
621 | { | ||
622 | struct dentry *parent; | ||
623 | struct inode *dir; | ||
624 | int error; | ||
625 | |||
626 | parent = dget_parent(dentry); | ||
627 | dir = parent->d_inode; | ||
628 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); | ||
629 | error = __rpc_rmdir(dir, dentry); | ||
630 | mutex_unlock(&dir->i_mutex); | ||
631 | dput(parent); | ||
632 | return error; | ||
633 | } | ||
634 | EXPORT_SYMBOL_GPL(rpc_rmdir); | ||
635 | |||
576 | static int __rpc_unlink(struct inode *dir, struct dentry *dentry) | 636 | static int __rpc_unlink(struct inode *dir, struct dentry *dentry) |
577 | { | 637 | { |
578 | int ret; | 638 | int ret; |
@@ -587,16 +647,12 @@ static int __rpc_unlink(struct inode *dir, struct dentry *dentry) | |||
587 | static int __rpc_rmpipe(struct inode *dir, struct dentry *dentry) | 647 | static int __rpc_rmpipe(struct inode *dir, struct dentry *dentry) |
588 | { | 648 | { |
589 | struct inode *inode = dentry->d_inode; | 649 | struct inode *inode = dentry->d_inode; |
590 | struct rpc_inode *rpci = RPC_I(inode); | ||
591 | 650 | ||
592 | rpci->nkern_readwriters--; | ||
593 | if (rpci->nkern_readwriters != 0) | ||
594 | return 0; | ||
595 | rpc_close_pipes(inode); | 651 | rpc_close_pipes(inode); |
596 | return __rpc_unlink(dir, dentry); | 652 | return __rpc_unlink(dir, dentry); |
597 | } | 653 | } |
598 | 654 | ||
599 | static struct dentry *__rpc_lookup_create(struct dentry *parent, | 655 | static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent, |
600 | struct qstr *name) | 656 | struct qstr *name) |
601 | { | 657 | { |
602 | struct dentry *dentry; | 658 | struct dentry *dentry; |
@@ -604,27 +660,13 @@ static struct dentry *__rpc_lookup_create(struct dentry *parent, | |||
604 | dentry = d_lookup(parent, name); | 660 | dentry = d_lookup(parent, name); |
605 | if (!dentry) { | 661 | if (!dentry) { |
606 | dentry = d_alloc(parent, name); | 662 | dentry = d_alloc(parent, name); |
607 | if (!dentry) { | 663 | if (!dentry) |
608 | dentry = ERR_PTR(-ENOMEM); | 664 | return ERR_PTR(-ENOMEM); |
609 | goto out_err; | ||
610 | } | ||
611 | } | 665 | } |
612 | if (!dentry->d_inode) | 666 | if (dentry->d_inode == NULL) { |
613 | d_set_d_op(dentry, &rpc_dentry_operations); | 667 | d_set_d_op(dentry, &rpc_dentry_operations); |
614 | out_err: | ||
615 | return dentry; | ||
616 | } | ||
617 | |||
618 | static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent, | ||
619 | struct qstr *name) | ||
620 | { | ||
621 | struct dentry *dentry; | ||
622 | |||
623 | dentry = __rpc_lookup_create(parent, name); | ||
624 | if (IS_ERR(dentry)) | ||
625 | return dentry; | ||
626 | if (dentry->d_inode == NULL) | ||
627 | return dentry; | 668 | return dentry; |
669 | } | ||
628 | dput(dentry); | 670 | dput(dentry); |
629 | return ERR_PTR(-EEXIST); | 671 | return ERR_PTR(-EEXIST); |
630 | } | 672 | } |
@@ -779,7 +821,7 @@ static int rpc_rmdir_depopulate(struct dentry *dentry, | |||
779 | * @private: private data to associate with the pipe, for the caller's use | 821 | * @private: private data to associate with the pipe, for the caller's use |
780 | * @ops: operations defining the behavior of the pipe: upcall, downcall, | 822 | * @ops: operations defining the behavior of the pipe: upcall, downcall, |
781 | * release_pipe, open_pipe, and destroy_msg. | 823 | * release_pipe, open_pipe, and destroy_msg. |
782 | * @flags: rpc_inode flags | 824 | * @flags: rpc_pipe flags |
783 | * | 825 | * |
784 | * Data is made available for userspace to read by calls to | 826 | * Data is made available for userspace to read by calls to |
785 | * rpc_queue_upcall(). The actual reads will result in calls to | 827 | * rpc_queue_upcall(). The actual reads will result in calls to |
@@ -792,9 +834,8 @@ static int rpc_rmdir_depopulate(struct dentry *dentry, | |||
792 | * The @private argument passed here will be available to all these methods | 834 | * The @private argument passed here will be available to all these methods |
793 | * from the file pointer, via RPC_I(file->f_dentry->d_inode)->private. | 835 | * from the file pointer, via RPC_I(file->f_dentry->d_inode)->private. |
794 | */ | 836 | */ |
795 | struct dentry *rpc_mkpipe(struct dentry *parent, const char *name, | 837 | struct dentry *rpc_mkpipe_dentry(struct dentry *parent, const char *name, |
796 | void *private, const struct rpc_pipe_ops *ops, | 838 | void *private, struct rpc_pipe *pipe) |
797 | int flags) | ||
798 | { | 839 | { |
799 | struct dentry *dentry; | 840 | struct dentry *dentry; |
800 | struct inode *dir = parent->d_inode; | 841 | struct inode *dir = parent->d_inode; |
@@ -802,9 +843,9 @@ struct dentry *rpc_mkpipe(struct dentry *parent, const char *name, | |||
802 | struct qstr q; | 843 | struct qstr q; |
803 | int err; | 844 | int err; |
804 | 845 | ||
805 | if (ops->upcall == NULL) | 846 | if (pipe->ops->upcall == NULL) |
806 | umode &= ~S_IRUGO; | 847 | umode &= ~S_IRUGO; |
807 | if (ops->downcall == NULL) | 848 | if (pipe->ops->downcall == NULL) |
808 | umode &= ~S_IWUGO; | 849 | umode &= ~S_IWUGO; |
809 | 850 | ||
810 | q.name = name; | 851 | q.name = name; |
@@ -812,24 +853,11 @@ struct dentry *rpc_mkpipe(struct dentry *parent, const char *name, | |||
812 | q.hash = full_name_hash(q.name, q.len), | 853 | q.hash = full_name_hash(q.name, q.len), |
813 | 854 | ||
814 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); | 855 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); |
815 | dentry = __rpc_lookup_create(parent, &q); | 856 | dentry = __rpc_lookup_create_exclusive(parent, &q); |
816 | if (IS_ERR(dentry)) | 857 | if (IS_ERR(dentry)) |
817 | goto out; | 858 | goto out; |
818 | if (dentry->d_inode) { | 859 | err = __rpc_mkpipe_dentry(dir, dentry, umode, &rpc_pipe_fops, |
819 | struct rpc_inode *rpci = RPC_I(dentry->d_inode); | 860 | private, pipe); |
820 | if (rpci->private != private || | ||
821 | rpci->ops != ops || | ||
822 | rpci->flags != flags) { | ||
823 | dput (dentry); | ||
824 | err = -EBUSY; | ||
825 | goto out_err; | ||
826 | } | ||
827 | rpci->nkern_readwriters++; | ||
828 | goto out; | ||
829 | } | ||
830 | |||
831 | err = __rpc_mkpipe(dir, dentry, umode, &rpc_pipe_fops, | ||
832 | private, ops, flags); | ||
833 | if (err) | 861 | if (err) |
834 | goto out_err; | 862 | goto out_err; |
835 | out: | 863 | out: |
@@ -842,7 +870,7 @@ out_err: | |||
842 | err); | 870 | err); |
843 | goto out; | 871 | goto out; |
844 | } | 872 | } |
845 | EXPORT_SYMBOL_GPL(rpc_mkpipe); | 873 | EXPORT_SYMBOL_GPL(rpc_mkpipe_dentry); |
846 | 874 | ||
847 | /** | 875 | /** |
848 | * rpc_unlink - remove a pipe | 876 | * rpc_unlink - remove a pipe |
@@ -915,7 +943,7 @@ struct dentry *rpc_create_client_dir(struct dentry *dentry, | |||
915 | 943 | ||
916 | /** | 944 | /** |
917 | * rpc_remove_client_dir - Remove a directory created with rpc_create_client_dir() | 945 | * rpc_remove_client_dir - Remove a directory created with rpc_create_client_dir() |
918 | * @dentry: directory to remove | 946 | * @clnt: rpc client |
919 | */ | 947 | */ |
920 | int rpc_remove_client_dir(struct dentry *dentry) | 948 | int rpc_remove_client_dir(struct dentry *dentry) |
921 | { | 949 | { |
@@ -1020,11 +1048,64 @@ static const struct rpc_filelist files[] = { | |||
1020 | }, | 1048 | }, |
1021 | }; | 1049 | }; |
1022 | 1050 | ||
1051 | /* | ||
1052 | * This call can be used only in RPC pipefs mount notification hooks. | ||
1053 | */ | ||
1054 | struct dentry *rpc_d_lookup_sb(const struct super_block *sb, | ||
1055 | const unsigned char *dir_name) | ||
1056 | { | ||
1057 | struct qstr dir = { | ||
1058 | .name = dir_name, | ||
1059 | .len = strlen(dir_name), | ||
1060 | .hash = full_name_hash(dir_name, strlen(dir_name)), | ||
1061 | }; | ||
1062 | |||
1063 | return d_lookup(sb->s_root, &dir); | ||
1064 | } | ||
1065 | EXPORT_SYMBOL_GPL(rpc_d_lookup_sb); | ||
1066 | |||
1067 | void rpc_pipefs_init_net(struct net *net) | ||
1068 | { | ||
1069 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1070 | |||
1071 | mutex_init(&sn->pipefs_sb_lock); | ||
1072 | } | ||
1073 | |||
1074 | /* | ||
1075 | * This call will be used for per network namespace operations calls. | ||
1076 | * Note: Function will be returned with pipefs_sb_lock taken if superblock was | ||
1077 | * found. This lock have to be released by rpc_put_sb_net() when all operations | ||
1078 | * will be completed. | ||
1079 | */ | ||
1080 | struct super_block *rpc_get_sb_net(const struct net *net) | ||
1081 | { | ||
1082 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1083 | |||
1084 | mutex_lock(&sn->pipefs_sb_lock); | ||
1085 | if (sn->pipefs_sb) | ||
1086 | return sn->pipefs_sb; | ||
1087 | mutex_unlock(&sn->pipefs_sb_lock); | ||
1088 | return NULL; | ||
1089 | } | ||
1090 | EXPORT_SYMBOL_GPL(rpc_get_sb_net); | ||
1091 | |||
1092 | void rpc_put_sb_net(const struct net *net) | ||
1093 | { | ||
1094 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1095 | |||
1096 | BUG_ON(sn->pipefs_sb == NULL); | ||
1097 | mutex_unlock(&sn->pipefs_sb_lock); | ||
1098 | } | ||
1099 | EXPORT_SYMBOL_GPL(rpc_put_sb_net); | ||
1100 | |||
1023 | static int | 1101 | static int |
1024 | rpc_fill_super(struct super_block *sb, void *data, int silent) | 1102 | rpc_fill_super(struct super_block *sb, void *data, int silent) |
1025 | { | 1103 | { |
1026 | struct inode *inode; | 1104 | struct inode *inode; |
1027 | struct dentry *root; | 1105 | struct dentry *root; |
1106 | struct net *net = data; | ||
1107 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1108 | int err; | ||
1028 | 1109 | ||
1029 | sb->s_blocksize = PAGE_CACHE_SIZE; | 1110 | sb->s_blocksize = PAGE_CACHE_SIZE; |
1030 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 1111 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; |
@@ -1038,21 +1119,54 @@ rpc_fill_super(struct super_block *sb, void *data, int silent) | |||
1038 | return -ENOMEM; | 1119 | return -ENOMEM; |
1039 | if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL)) | 1120 | if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL)) |
1040 | return -ENOMEM; | 1121 | return -ENOMEM; |
1122 | dprintk("RPC: sending pipefs MOUNT notification for net %p%s\n", net, | ||
1123 | NET_NAME(net)); | ||
1124 | err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list, | ||
1125 | RPC_PIPEFS_MOUNT, | ||
1126 | sb); | ||
1127 | if (err) | ||
1128 | goto err_depopulate; | ||
1129 | sb->s_fs_info = get_net(net); | ||
1130 | sn->pipefs_sb = sb; | ||
1041 | return 0; | 1131 | return 0; |
1132 | |||
1133 | err_depopulate: | ||
1134 | blocking_notifier_call_chain(&rpc_pipefs_notifier_list, | ||
1135 | RPC_PIPEFS_UMOUNT, | ||
1136 | sb); | ||
1137 | __rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF); | ||
1138 | return err; | ||
1042 | } | 1139 | } |
1043 | 1140 | ||
1044 | static struct dentry * | 1141 | static struct dentry * |
1045 | rpc_mount(struct file_system_type *fs_type, | 1142 | rpc_mount(struct file_system_type *fs_type, |
1046 | int flags, const char *dev_name, void *data) | 1143 | int flags, const char *dev_name, void *data) |
1047 | { | 1144 | { |
1048 | return mount_single(fs_type, flags, data, rpc_fill_super); | 1145 | return mount_ns(fs_type, flags, current->nsproxy->net_ns, rpc_fill_super); |
1146 | } | ||
1147 | |||
1148 | static void rpc_kill_sb(struct super_block *sb) | ||
1149 | { | ||
1150 | struct net *net = sb->s_fs_info; | ||
1151 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1152 | |||
1153 | mutex_lock(&sn->pipefs_sb_lock); | ||
1154 | sn->pipefs_sb = NULL; | ||
1155 | mutex_unlock(&sn->pipefs_sb_lock); | ||
1156 | put_net(net); | ||
1157 | dprintk("RPC: sending pipefs UMOUNT notification for net %p%s\n", net, | ||
1158 | NET_NAME(net)); | ||
1159 | blocking_notifier_call_chain(&rpc_pipefs_notifier_list, | ||
1160 | RPC_PIPEFS_UMOUNT, | ||
1161 | sb); | ||
1162 | kill_litter_super(sb); | ||
1049 | } | 1163 | } |
1050 | 1164 | ||
1051 | static struct file_system_type rpc_pipe_fs_type = { | 1165 | static struct file_system_type rpc_pipe_fs_type = { |
1052 | .owner = THIS_MODULE, | 1166 | .owner = THIS_MODULE, |
1053 | .name = "rpc_pipefs", | 1167 | .name = "rpc_pipefs", |
1054 | .mount = rpc_mount, | 1168 | .mount = rpc_mount, |
1055 | .kill_sb = kill_litter_super, | 1169 | .kill_sb = rpc_kill_sb, |
1056 | }; | 1170 | }; |
1057 | 1171 | ||
1058 | static void | 1172 | static void |
@@ -1062,16 +1176,8 @@ init_once(void *foo) | |||
1062 | 1176 | ||
1063 | inode_init_once(&rpci->vfs_inode); | 1177 | inode_init_once(&rpci->vfs_inode); |
1064 | rpci->private = NULL; | 1178 | rpci->private = NULL; |
1065 | rpci->nreaders = 0; | 1179 | rpci->pipe = NULL; |
1066 | rpci->nwriters = 0; | ||
1067 | INIT_LIST_HEAD(&rpci->in_upcall); | ||
1068 | INIT_LIST_HEAD(&rpci->in_downcall); | ||
1069 | INIT_LIST_HEAD(&rpci->pipe); | ||
1070 | rpci->pipelen = 0; | ||
1071 | init_waitqueue_head(&rpci->waitq); | 1180 | init_waitqueue_head(&rpci->waitq); |
1072 | INIT_DELAYED_WORK(&rpci->queue_timeout, | ||
1073 | rpc_timeout_upcall_queue); | ||
1074 | rpci->ops = NULL; | ||
1075 | } | 1181 | } |
1076 | 1182 | ||
1077 | int register_rpc_pipefs(void) | 1183 | int register_rpc_pipefs(void) |
@@ -1085,17 +1191,24 @@ int register_rpc_pipefs(void) | |||
1085 | init_once); | 1191 | init_once); |
1086 | if (!rpc_inode_cachep) | 1192 | if (!rpc_inode_cachep) |
1087 | return -ENOMEM; | 1193 | return -ENOMEM; |
1194 | err = rpc_clients_notifier_register(); | ||
1195 | if (err) | ||
1196 | goto err_notifier; | ||
1088 | err = register_filesystem(&rpc_pipe_fs_type); | 1197 | err = register_filesystem(&rpc_pipe_fs_type); |
1089 | if (err) { | 1198 | if (err) |
1090 | kmem_cache_destroy(rpc_inode_cachep); | 1199 | goto err_register; |
1091 | return err; | ||
1092 | } | ||
1093 | |||
1094 | return 0; | 1200 | return 0; |
1201 | |||
1202 | err_register: | ||
1203 | rpc_clients_notifier_unregister(); | ||
1204 | err_notifier: | ||
1205 | kmem_cache_destroy(rpc_inode_cachep); | ||
1206 | return err; | ||
1095 | } | 1207 | } |
1096 | 1208 | ||
1097 | void unregister_rpc_pipefs(void) | 1209 | void unregister_rpc_pipefs(void) |
1098 | { | 1210 | { |
1211 | rpc_clients_notifier_unregister(); | ||
1099 | kmem_cache_destroy(rpc_inode_cachep); | 1212 | kmem_cache_destroy(rpc_inode_cachep); |
1100 | unregister_filesystem(&rpc_pipe_fs_type); | 1213 | unregister_filesystem(&rpc_pipe_fs_type); |
1101 | } | 1214 | } |