diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 83 |
1 files changed, 41 insertions, 42 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 08580bedc25f..6d152f69587e 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -639,26 +639,6 @@ static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent, | |||
639 | return ERR_PTR(-EEXIST); | 639 | return ERR_PTR(-EEXIST); |
640 | } | 640 | } |
641 | 641 | ||
642 | static struct dentry *rpc_lookup_negative(const char *path, | ||
643 | struct nameidata *nd) | ||
644 | { | ||
645 | struct inode *dir; | ||
646 | struct dentry *dentry; | ||
647 | int error; | ||
648 | |||
649 | error = rpc_lookup_parent(path, nd); | ||
650 | if (error != 0) | ||
651 | return ERR_PTR(error); | ||
652 | dir = nd->path.dentry->d_inode; | ||
653 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); | ||
654 | dentry = __rpc_lookup_create_exclusive(nd->path.dentry, &nd->last); | ||
655 | if (IS_ERR(dentry)) { | ||
656 | mutex_unlock(&dir->i_mutex); | ||
657 | rpc_release_path(nd); | ||
658 | } | ||
659 | return dentry; | ||
660 | } | ||
661 | |||
662 | /* | 642 | /* |
663 | * FIXME: This probably has races. | 643 | * FIXME: This probably has races. |
664 | */ | 644 | */ |
@@ -754,44 +734,30 @@ out_bad: | |||
754 | return err; | 734 | return err; |
755 | } | 735 | } |
756 | 736 | ||
757 | /** | 737 | struct dentry *rpc_mkdir_populate(struct dentry *parent, |
758 | * rpc_create_client_dir - Create a new rpc_client directory in rpc_pipefs | 738 | struct qstr *name, umode_t mode, void *private) |
759 | * @path: path from the rpc_pipefs root to the new directory | ||
760 | * @rpc_client: rpc client to associate with this directory | ||
761 | * | ||
762 | * This creates a directory at the given @path associated with | ||
763 | * @rpc_clnt, which will contain a file named "info" with some basic | ||
764 | * information about the client, together with any "pipes" that may | ||
765 | * later be created using rpc_mkpipe(). | ||
766 | */ | ||
767 | struct dentry *rpc_create_client_dir(const char *path, | ||
768 | struct rpc_clnt *rpc_client) | ||
769 | { | 739 | { |
770 | struct nameidata nd; | ||
771 | struct dentry *dentry; | 740 | struct dentry *dentry; |
772 | struct inode *dir; | 741 | struct inode *dir = parent->d_inode; |
773 | int error; | 742 | int error; |
774 | 743 | ||
775 | dentry = rpc_lookup_negative(path, &nd); | 744 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); |
745 | dentry = __rpc_lookup_create_exclusive(parent, name); | ||
776 | if (IS_ERR(dentry)) | 746 | if (IS_ERR(dentry)) |
777 | return dentry; | 747 | goto out; |
778 | dir = nd.path.dentry->d_inode; | 748 | error = __rpc_mkdir(dir, dentry, mode, NULL, private); |
779 | error = __rpc_mkdir(dir, dentry, S_IRUGO | S_IXUGO, NULL, rpc_client); | ||
780 | if (error != 0) | 749 | if (error != 0) |
781 | goto out_err; | 750 | goto out_err; |
782 | error = rpc_populate(dentry, authfiles, | 751 | error = rpc_populate(dentry, authfiles, |
783 | RPCAUTH_info, RPCAUTH_EOF, rpc_client); | 752 | RPCAUTH_info, RPCAUTH_EOF, private); |
784 | if (error) | 753 | if (error) |
785 | goto err_rmdir; | 754 | goto err_rmdir; |
786 | out: | 755 | out: |
787 | mutex_unlock(&dir->i_mutex); | 756 | mutex_unlock(&dir->i_mutex); |
788 | rpc_release_path(&nd); | ||
789 | return dentry; | 757 | return dentry; |
790 | err_rmdir: | 758 | err_rmdir: |
791 | __rpc_rmdir(dir, dentry); | 759 | __rpc_rmdir(dir, dentry); |
792 | out_err: | 760 | out_err: |
793 | printk(KERN_WARNING "%s: %s() failed to create directory %s (errno = %d)\n", | ||
794 | __FILE__, __func__, path, error); | ||
795 | dentry = ERR_PTR(error); | 761 | dentry = ERR_PTR(error); |
796 | goto out; | 762 | goto out; |
797 | } | 763 | } |
@@ -913,6 +879,39 @@ rpc_unlink(struct dentry *dentry) | |||
913 | } | 879 | } |
914 | EXPORT_SYMBOL_GPL(rpc_unlink); | 880 | EXPORT_SYMBOL_GPL(rpc_unlink); |
915 | 881 | ||
882 | /** | ||
883 | * rpc_create_client_dir - Create a new rpc_client directory in rpc_pipefs | ||
884 | * @path: path from the rpc_pipefs root to the new directory | ||
885 | * @rpc_client: rpc client to associate with this directory | ||
886 | * | ||
887 | * This creates a directory at the given @path associated with | ||
888 | * @rpc_clnt, which will contain a file named "info" with some basic | ||
889 | * information about the client, together with any "pipes" that may | ||
890 | * later be created using rpc_mkpipe(). | ||
891 | */ | ||
892 | struct dentry *rpc_create_client_dir(const char *path, | ||
893 | struct rpc_clnt *rpc_client) | ||
894 | { | ||
895 | struct nameidata nd; | ||
896 | struct dentry *ret; | ||
897 | struct inode *dir; | ||
898 | |||
899 | ret = ERR_PTR(rpc_lookup_parent(path, &nd)); | ||
900 | if (IS_ERR(ret)) | ||
901 | goto out_err; | ||
902 | dir = nd.path.dentry->d_inode; | ||
903 | |||
904 | ret = rpc_mkdir_populate(nd.path.dentry, &nd.last, | ||
905 | S_IRUGO | S_IXUGO, rpc_client); | ||
906 | rpc_release_path(&nd); | ||
907 | if (!IS_ERR(ret)) | ||
908 | return ret; | ||
909 | out_err: | ||
910 | printk(KERN_WARNING "%s: %s() failed to create directory %s (errno = %ld)\n", | ||
911 | __FILE__, __func__, path, PTR_ERR(ret)); | ||
912 | return ret; | ||
913 | } | ||
914 | |||
916 | /* | 915 | /* |
917 | * populate the filesystem | 916 | * populate the filesystem |
918 | */ | 917 | */ |