diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-08-09 15:14:25 -0400 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-08-09 15:14:25 -0400 |
| commit | 23ac6581702ac6d029643328a7e6ea3baf834c5e (patch) | |
| tree | e960a371127a240f17971596e0c456ccc8f01b7e | |
| parent | 7d217caca5d704e48aa5e59aba0b3ad4c7af4fd2 (diff) | |
SUNRPC: clean up rpc_setup_pipedir()
There is still a little wart or two there: Since we've already got a
vfsmount, we might as well pass that in to rpc_create_client_dir.
Another point is that if we open code __rpc_lookup_path() here, then we can
avoid looking up the entire parent directory path over and over again: it
doesn't change.
Also get rid of rpc_clnt->cl_pathname, since it has no users...
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
| -rw-r--r-- | include/linux/sunrpc/clnt.h | 1 | ||||
| -rw-r--r-- | include/linux/sunrpc/rpc_pipe_fs.h | 2 | ||||
| -rw-r--r-- | net/sunrpc/clnt.c | 48 | ||||
| -rw-r--r-- | net/sunrpc/rpc_pipe.c | 58 |
4 files changed, 37 insertions, 72 deletions
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 38ad162330a2..1848d44922ef 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h | |||
| @@ -51,7 +51,6 @@ struct rpc_clnt { | |||
| 51 | 51 | ||
| 52 | int cl_nodelen; /* nodename length */ | 52 | int cl_nodelen; /* nodename length */ |
| 53 | char cl_nodename[UNX_MAXNODENAME]; | 53 | char cl_nodename[UNX_MAXNODENAME]; |
| 54 | char cl_pathname[30];/* Path in rpc_pipe_fs */ | ||
| 55 | struct path cl_path; | 54 | struct path cl_path; |
| 56 | struct rpc_clnt * cl_parent; /* Points to parent of clones */ | 55 | struct rpc_clnt * cl_parent; /* Points to parent of clones */ |
| 57 | struct rpc_rtt cl_rtt_default; | 56 | struct rpc_rtt cl_rtt_default; |
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h index 8de0ac276499..88332ef1e959 100644 --- a/include/linux/sunrpc/rpc_pipe_fs.h +++ b/include/linux/sunrpc/rpc_pipe_fs.h | |||
| @@ -45,7 +45,7 @@ RPC_I(struct inode *inode) | |||
| 45 | extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *); | 45 | extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *); |
| 46 | 46 | ||
| 47 | struct rpc_clnt; | 47 | struct rpc_clnt; |
| 48 | extern struct dentry *rpc_create_client_dir(const char *, struct rpc_clnt *); | 48 | extern struct dentry *rpc_create_client_dir(struct dentry *, struct qstr *, struct rpc_clnt *); |
| 49 | extern int rpc_remove_client_dir(struct dentry *); | 49 | extern int rpc_remove_client_dir(struct dentry *); |
| 50 | extern struct dentry *rpc_mkpipe(struct dentry *, const char *, void *, | 50 | extern struct dentry *rpc_mkpipe(struct dentry *, const char *, void *, |
| 51 | const struct rpc_pipe_ops *, int flags); | 51 | const struct rpc_pipe_ops *, int flags); |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index b3f863346300..c1e467e1b07d 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
| @@ -27,6 +27,8 @@ | |||
| 27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
| 28 | #include <linux/kallsyms.h> | 28 | #include <linux/kallsyms.h> |
| 29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
| 30 | #include <linux/namei.h> | ||
| 31 | #include <linux/mount.h> | ||
| 30 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 31 | #include <linux/utsname.h> | 33 | #include <linux/utsname.h> |
| 32 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
| @@ -97,6 +99,12 @@ static int | |||
| 97 | rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) | 99 | rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) |
| 98 | { | 100 | { |
| 99 | static uint32_t clntid; | 101 | static uint32_t clntid; |
| 102 | struct nameidata nd; | ||
| 103 | struct path path; | ||
| 104 | char name[15]; | ||
| 105 | struct qstr q = { | ||
| 106 | .name = name, | ||
| 107 | }; | ||
| 100 | int error; | 108 | int error; |
| 101 | 109 | ||
| 102 | clnt->cl_path.mnt = ERR_PTR(-ENOENT); | 110 | clnt->cl_path.mnt = ERR_PTR(-ENOENT); |
| @@ -104,26 +112,36 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) | |||
| 104 | if (dir_name == NULL) | 112 | if (dir_name == NULL) |
| 105 | return 0; | 113 | return 0; |
| 106 | 114 | ||
| 107 | clnt->cl_path.mnt = rpc_get_mount(); | 115 | path.mnt = rpc_get_mount(); |
| 108 | if (IS_ERR(clnt->cl_path.mnt)) | 116 | if (IS_ERR(path.mnt)) |
| 109 | return PTR_ERR(clnt->cl_path.mnt); | 117 | return PTR_ERR(path.mnt); |
| 118 | error = vfs_path_lookup(path.mnt->mnt_root, path.mnt, dir_name, 0, &nd); | ||
| 119 | if (error) | ||
| 120 | goto err; | ||
| 110 | 121 | ||
| 111 | for (;;) { | 122 | for (;;) { |
| 112 | snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname), | 123 | q.len = snprintf(name, sizeof(name), "clnt%x", (unsigned int)clntid++); |
| 113 | "%s/clnt%x", dir_name, | 124 | name[sizeof(name) - 1] = '\0'; |
| 114 | (unsigned int)clntid++); | 125 | q.hash = full_name_hash(q.name, q.len); |
| 115 | clnt->cl_pathname[sizeof(clnt->cl_pathname) - 1] = '\0'; | 126 | path.dentry = rpc_create_client_dir(nd.path.dentry, &q, clnt); |
| 116 | clnt->cl_path.dentry = rpc_create_client_dir(clnt->cl_pathname, clnt); | 127 | if (!IS_ERR(path.dentry)) |
| 117 | if (!IS_ERR(clnt->cl_path.dentry)) | 128 | break; |
| 118 | return 0; | 129 | error = PTR_ERR(path.dentry); |
| 119 | error = PTR_ERR(clnt->cl_path.dentry); | ||
| 120 | if (error != -EEXIST) { | 130 | if (error != -EEXIST) { |
| 121 | printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n", | 131 | printk(KERN_INFO "RPC: Couldn't create pipefs entry" |
| 122 | clnt->cl_pathname, error); | 132 | " %s/%s, error %d\n", |
| 123 | rpc_put_mount(); | 133 | dir_name, name, error); |
| 124 | return error; | 134 | goto err_path_put; |
| 125 | } | 135 | } |
| 126 | } | 136 | } |
| 137 | path_put(&nd.path); | ||
| 138 | clnt->cl_path = path; | ||
| 139 | return 0; | ||
| 140 | err_path_put: | ||
| 141 | path_put(&nd.path); | ||
| 142 | err: | ||
| 143 | rpc_put_mount(); | ||
| 144 | return error; | ||
| 127 | } | 145 | } |
| 128 | 146 | ||
| 129 | static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) | 147 | static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 6d152f69587e..1613d858ba38 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -443,42 +443,6 @@ static const struct dentry_operations rpc_dentry_operations = { | |||
| 443 | .d_delete = rpc_delete_dentry, | 443 | .d_delete = rpc_delete_dentry, |
| 444 | }; | 444 | }; |
| 445 | 445 | ||
| 446 | static int __rpc_lookup_path(const char *pathname, unsigned flags, | ||
| 447 | struct nameidata *nd) | ||
| 448 | { | ||
| 449 | struct vfsmount *mnt; | ||
| 450 | |||
| 451 | if (pathname[0] == '\0') | ||
| 452 | return -ENOENT; | ||
| 453 | |||
| 454 | mnt = rpc_get_mount(); | ||
| 455 | if (IS_ERR(mnt)) { | ||
| 456 | printk(KERN_WARNING "%s: %s failed to mount " | ||
| 457 | "pseudofilesystem \n", __FILE__, __func__); | ||
| 458 | return PTR_ERR(mnt); | ||
| 459 | } | ||
| 460 | |||
| 461 | if (vfs_path_lookup(mnt->mnt_root, mnt, pathname, flags, nd)) { | ||
| 462 | printk(KERN_WARNING "%s: %s failed to find path %s\n", | ||
| 463 | __FILE__, __func__, pathname); | ||
| 464 | rpc_put_mount(); | ||
| 465 | return -ENOENT; | ||
| 466 | } | ||
| 467 | return 0; | ||
| 468 | } | ||
| 469 | |||
| 470 | static int rpc_lookup_parent(const char *pathname, struct nameidata *nd) | ||
| 471 | { | ||
| 472 | return __rpc_lookup_path(pathname, LOOKUP_PARENT, nd); | ||
| 473 | } | ||
| 474 | |||
| 475 | static void | ||
| 476 | rpc_release_path(struct nameidata *nd) | ||
| 477 | { | ||
| 478 | path_put(&nd->path); | ||
| 479 | rpc_put_mount(); | ||
| 480 | } | ||
| 481 | |||
| 482 | static struct inode * | 446 | static struct inode * |
| 483 | rpc_get_inode(struct super_block *sb, umode_t mode) | 447 | rpc_get_inode(struct super_block *sb, umode_t mode) |
| 484 | { | 448 | { |
| @@ -889,27 +853,11 @@ EXPORT_SYMBOL_GPL(rpc_unlink); | |||
| 889 | * information about the client, together with any "pipes" that may | 853 | * information about the client, together with any "pipes" that may |
| 890 | * later be created using rpc_mkpipe(). | 854 | * later be created using rpc_mkpipe(). |
| 891 | */ | 855 | */ |
| 892 | struct dentry *rpc_create_client_dir(const char *path, | 856 | struct dentry *rpc_create_client_dir(struct dentry *dentry, |
| 857 | struct qstr *name, | ||
| 893 | struct rpc_clnt *rpc_client) | 858 | struct rpc_clnt *rpc_client) |
| 894 | { | 859 | { |
| 895 | struct nameidata nd; | 860 | return rpc_mkdir_populate(dentry, name, S_IRUGO | S_IXUGO, rpc_client); |
| 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 | } | 861 | } |
| 914 | 862 | ||
| 915 | /* | 863 | /* |
