diff options
| -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 | */ |
