aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/rpc_pipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
-rw-r--r--net/sunrpc/rpc_pipe.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 49278f830367..8c8eef2b8f26 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -27,6 +27,7 @@
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/smp_lock.h>
30 31
31static struct vfsmount *rpc_mount __read_mostly; 32static struct vfsmount *rpc_mount __read_mostly;
32static int rpc_mount_count; 33static int rpc_mount_count;
@@ -47,7 +48,7 @@ static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head,
47 return; 48 return;
48 do { 49 do {
49 msg = list_entry(head->next, struct rpc_pipe_msg, list); 50 msg = list_entry(head->next, struct rpc_pipe_msg, list);
50 list_del(&msg->list); 51 list_del_init(&msg->list);
51 msg->errno = err; 52 msg->errno = err;
52 destroy_msg(msg); 53 destroy_msg(msg);
53 } while (!list_empty(head)); 54 } while (!list_empty(head));
@@ -78,7 +79,7 @@ rpc_timeout_upcall_queue(struct work_struct *work)
78} 79}
79 80
80/** 81/**
81 * rpc_queue_upcall 82 * rpc_queue_upcall - queue an upcall message to userspace
82 * @inode: inode of upcall pipe on which to queue given message 83 * @inode: inode of upcall pipe on which to queue given message
83 * @msg: message to queue 84 * @msg: message to queue
84 * 85 *
@@ -207,7 +208,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
207 if (msg != NULL) { 208 if (msg != NULL) {
208 spin_lock(&inode->i_lock); 209 spin_lock(&inode->i_lock);
209 msg->errno = -EAGAIN; 210 msg->errno = -EAGAIN;
210 list_del(&msg->list); 211 list_del_init(&msg->list);
211 spin_unlock(&inode->i_lock); 212 spin_unlock(&inode->i_lock);
212 rpci->ops->destroy_msg(msg); 213 rpci->ops->destroy_msg(msg);
213 } 214 }
@@ -267,7 +268,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
267 if (res < 0 || msg->len == msg->copied) { 268 if (res < 0 || msg->len == msg->copied) {
268 filp->private_data = NULL; 269 filp->private_data = NULL;
269 spin_lock(&inode->i_lock); 270 spin_lock(&inode->i_lock);
270 list_del(&msg->list); 271 list_del_init(&msg->list);
271 spin_unlock(&inode->i_lock); 272 spin_unlock(&inode->i_lock);
272 rpci->ops->destroy_msg(msg); 273 rpci->ops->destroy_msg(msg);
273 } 274 }
@@ -309,8 +310,7 @@ rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait)
309} 310}
310 311
311static int 312static int
312rpc_pipe_ioctl(struct inode *ino, struct file *filp, 313rpc_pipe_ioctl_unlocked(struct file *filp, unsigned int cmd, unsigned long arg)
313 unsigned int cmd, unsigned long arg)
314{ 314{
315 struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode); 315 struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
316 int len; 316 int len;
@@ -331,13 +331,25 @@ rpc_pipe_ioctl(struct inode *ino, struct file *filp,
331 } 331 }
332} 332}
333 333
334static long
335rpc_pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
336{
337 long ret;
338
339 lock_kernel();
340 ret = rpc_pipe_ioctl_unlocked(filp, cmd, arg);
341 unlock_kernel();
342
343 return ret;
344}
345
334static const struct file_operations rpc_pipe_fops = { 346static const struct file_operations rpc_pipe_fops = {
335 .owner = THIS_MODULE, 347 .owner = THIS_MODULE,
336 .llseek = no_llseek, 348 .llseek = no_llseek,
337 .read = rpc_pipe_read, 349 .read = rpc_pipe_read,
338 .write = rpc_pipe_write, 350 .write = rpc_pipe_write,
339 .poll = rpc_pipe_poll, 351 .poll = rpc_pipe_poll,
340 .ioctl = rpc_pipe_ioctl, 352 .unlocked_ioctl = rpc_pipe_ioctl,
341 .open = rpc_pipe_open, 353 .open = rpc_pipe_open,
342 .release = rpc_pipe_release, 354 .release = rpc_pipe_release,
343}; 355};
@@ -359,21 +371,23 @@ rpc_show_info(struct seq_file *m, void *v)
359static int 371static int
360rpc_info_open(struct inode *inode, struct file *file) 372rpc_info_open(struct inode *inode, struct file *file)
361{ 373{
362 struct rpc_clnt *clnt; 374 struct rpc_clnt *clnt = NULL;
363 int ret = single_open(file, rpc_show_info, NULL); 375 int ret = single_open(file, rpc_show_info, NULL);
364 376
365 if (!ret) { 377 if (!ret) {
366 struct seq_file *m = file->private_data; 378 struct seq_file *m = file->private_data;
367 mutex_lock(&inode->i_mutex); 379
368 clnt = RPC_I(inode)->private; 380 spin_lock(&file->f_path.dentry->d_lock);
369 if (clnt) { 381 if (!d_unhashed(file->f_path.dentry))
370 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);
371 m->private = clnt; 385 m->private = clnt;
372 } else { 386 } else {
387 spin_unlock(&file->f_path.dentry->d_lock);
373 single_release(inode, file); 388 single_release(inode, file);
374 ret = -EINVAL; 389 ret = -EINVAL;
375 } 390 }
376 mutex_unlock(&inode->i_mutex);
377 } 391 }
378 return ret; 392 return ret;
379} 393}
@@ -587,6 +601,8 @@ static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent,
587 struct dentry *dentry; 601 struct dentry *dentry;
588 602
589 dentry = __rpc_lookup_create(parent, name); 603 dentry = __rpc_lookup_create(parent, name);
604 if (IS_ERR(dentry))
605 return dentry;
590 if (dentry->d_inode == NULL) 606 if (dentry->d_inode == NULL)
591 return dentry; 607 return dentry;
592 dput(dentry); 608 dput(dentry);
@@ -999,19 +1015,14 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
999 inode = rpc_get_inode(sb, S_IFDIR | 0755); 1015 inode = rpc_get_inode(sb, S_IFDIR | 0755);
1000 if (!inode) 1016 if (!inode)
1001 return -ENOMEM; 1017 return -ENOMEM;
1002 root = d_alloc_root(inode); 1018 sb->s_root = root = d_alloc_root(inode);
1003 if (!root) { 1019 if (!root) {
1004 iput(inode); 1020 iput(inode);
1005 return -ENOMEM; 1021 return -ENOMEM;
1006 } 1022 }
1007 if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL)) 1023 if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL))
1008 goto out; 1024 return -ENOMEM;
1009 sb->s_root = root;
1010 return 0; 1025 return 0;
1011out:
1012 d_genocide(root);
1013 dput(root);
1014 return -ENOMEM;
1015} 1026}
1016 1027
1017static int 1028static int