aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2009-08-09 15:14:25 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-08-09 15:14:25 -0400
commit23ac6581702ac6d029643328a7e6ea3baf834c5e (patch)
treee960a371127a240f17971596e0c456ccc8f01b7e
parent7d217caca5d704e48aa5e59aba0b3ad4c7af4fd2 (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.h1
-rw-r--r--include/linux/sunrpc/rpc_pipe_fs.h2
-rw-r--r--net/sunrpc/clnt.c48
-rw-r--r--net/sunrpc/rpc_pipe.c58
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)
45extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *); 45extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
46 46
47struct rpc_clnt; 47struct rpc_clnt;
48extern struct dentry *rpc_create_client_dir(const char *, struct rpc_clnt *); 48extern struct dentry *rpc_create_client_dir(struct dentry *, struct qstr *, struct rpc_clnt *);
49extern int rpc_remove_client_dir(struct dentry *); 49extern int rpc_remove_client_dir(struct dentry *);
50extern struct dentry *rpc_mkpipe(struct dentry *, const char *, void *, 50extern 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
97rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) 99rpc_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;
140err_path_put:
141 path_put(&nd.path);
142err:
143 rpc_put_mount();
144 return error;
127} 145}
128 146
129static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) 147static 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
446static 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
470static int rpc_lookup_parent(const char *pathname, struct nameidata *nd)
471{
472 return __rpc_lookup_path(pathname, LOOKUP_PARENT, nd);
473}
474
475static void
476rpc_release_path(struct nameidata *nd)
477{
478 path_put(&nd->path);
479 rpc_put_mount();
480}
481
482static struct inode * 446static struct inode *
483rpc_get_inode(struct super_block *sb, umode_t mode) 447rpc_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 */
892struct dentry *rpc_create_client_dir(const char *path, 856struct 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;
909out_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/*