aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sunrpc/rpc_pipe.c100
1 files changed, 59 insertions, 41 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index cf30bf58bfcf..36338515f342 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -624,6 +624,57 @@ static int __rpc_rmpipe(struct inode *dir, struct dentry *dentry)
624 return __rpc_unlink(dir, dentry); 624 return __rpc_unlink(dir, dentry);
625} 625}
626 626
627static struct dentry *__rpc_lookup_create(struct dentry *parent,
628 struct qstr *name)
629{
630 struct dentry *dentry;
631
632 dentry = d_lookup(parent, name);
633 if (!dentry) {
634 dentry = d_alloc(parent, name);
635 if (!dentry) {
636 dentry = ERR_PTR(-ENOMEM);
637 goto out_err;
638 }
639 }
640 if (!dentry->d_inode)
641 dentry->d_op = &rpc_dentry_operations;
642out_err:
643 return dentry;
644}
645
646static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent,
647 struct qstr *name)
648{
649 struct dentry *dentry;
650
651 dentry = __rpc_lookup_create(parent, name);
652 if (dentry->d_inode == NULL)
653 return dentry;
654 dput(dentry);
655 return ERR_PTR(-EEXIST);
656}
657
658static struct dentry *rpc_lookup_negative(const char *path,
659 struct nameidata *nd)
660{
661 struct inode *dir;
662 struct dentry *dentry;
663 int error;
664
665 error = rpc_lookup_parent(path, nd);
666 if (error != 0)
667 return ERR_PTR(error);
668 dir = nd->path.dentry->d_inode;
669 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
670 dentry = __rpc_lookup_create_exclusive(nd->path.dentry, &nd->last);
671 if (IS_ERR(dentry)) {
672 mutex_unlock(&dir->i_mutex);
673 rpc_release_path(nd);
674 }
675 return dentry;
676}
677
627/* 678/*
628 * FIXME: This probably has races. 679 * FIXME: This probably has races.
629 */ 680 */
@@ -723,44 +774,6 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry)
723 return error; 774 return error;
724} 775}
725 776
726static struct dentry *
727rpc_lookup_create(struct dentry *parent, const char *name, int len, int exclusive)
728{
729 struct inode *dir = parent->d_inode;
730 struct dentry *dentry;
731
732 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
733 dentry = lookup_one_len(name, parent, len);
734 if (IS_ERR(dentry))
735 goto out_err;
736 if (!dentry->d_inode)
737 dentry->d_op = &rpc_dentry_operations;
738 else if (exclusive) {
739 dput(dentry);
740 dentry = ERR_PTR(-EEXIST);
741 goto out_err;
742 }
743 return dentry;
744out_err:
745 mutex_unlock(&dir->i_mutex);
746 return dentry;
747}
748
749static struct dentry *
750rpc_lookup_negative(char *path, struct nameidata *nd)
751{
752 struct dentry *dentry;
753 int error;
754
755 if ((error = rpc_lookup_parent(path, nd)) != 0)
756 return ERR_PTR(error);
757 dentry = rpc_lookup_create(nd->path.dentry, nd->last.name, nd->last.len,
758 1);
759 if (IS_ERR(dentry))
760 rpc_release_path(nd);
761 return dentry;
762}
763
764/** 777/**
765 * rpc_mkdir - Create a new directory in rpc_pipefs 778 * rpc_mkdir - Create a new directory in rpc_pipefs
766 * @path: path from the rpc_pipefs root to the new directory 779 * @path: path from the rpc_pipefs root to the new directory
@@ -854,6 +867,7 @@ struct dentry *rpc_mkpipe(struct dentry *parent, const char *name,
854 struct dentry *dentry; 867 struct dentry *dentry;
855 struct inode *dir = parent->d_inode; 868 struct inode *dir = parent->d_inode;
856 umode_t umode = S_IFIFO | S_IRUSR | S_IWUSR; 869 umode_t umode = S_IFIFO | S_IRUSR | S_IWUSR;
870 struct qstr q;
857 int err; 871 int err;
858 872
859 if (ops->upcall == NULL) 873 if (ops->upcall == NULL)
@@ -861,10 +875,14 @@ struct dentry *rpc_mkpipe(struct dentry *parent, const char *name,
861 if (ops->downcall == NULL) 875 if (ops->downcall == NULL)
862 umode &= ~S_IWUGO; 876 umode &= ~S_IWUGO;
863 877
864 dentry = rpc_lookup_create(parent, name, strlen(name), 0); 878 q.name = name;
879 q.len = strlen(name);
880 q.hash = full_name_hash(q.name, q.len),
881
882 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
883 dentry = __rpc_lookup_create(parent, &q);
865 if (IS_ERR(dentry)) 884 if (IS_ERR(dentry))
866 return dentry; 885 goto out;
867 dir = parent->d_inode;
868 if (dentry->d_inode) { 886 if (dentry->d_inode) {
869 struct rpc_inode *rpci = RPC_I(dentry->d_inode); 887 struct rpc_inode *rpci = RPC_I(dentry->d_inode);
870 if (rpci->private != private || 888 if (rpci->private != private ||