aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/clnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r--net/sunrpc/clnt.c60
1 files changed, 39 insertions, 21 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index ebfcf9b89909..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,33 +99,49 @@ 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_vfsmnt = ERR_PTR(-ENOENT); 110 clnt->cl_path.mnt = ERR_PTR(-ENOENT);
103 clnt->cl_dentry = ERR_PTR(-ENOENT); 111 clnt->cl_path.dentry = ERR_PTR(-ENOENT);
104 if (dir_name == NULL) 112 if (dir_name == NULL)
105 return 0; 113 return 0;
106 114
107 clnt->cl_vfsmnt = rpc_get_mount(); 115 path.mnt = rpc_get_mount();
108 if (IS_ERR(clnt->cl_vfsmnt)) 116 if (IS_ERR(path.mnt))
109 return PTR_ERR(clnt->cl_vfsmnt); 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_dentry = rpc_mkdir(clnt->cl_pathname, clnt); 127 if (!IS_ERR(path.dentry))
117 if (!IS_ERR(clnt->cl_dentry)) 128 break;
118 return 0; 129 error = PTR_ERR(path.dentry);
119 error = PTR_ERR(clnt->cl_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)
@@ -231,8 +249,8 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
231 return clnt; 249 return clnt;
232 250
233out_no_auth: 251out_no_auth:
234 if (!IS_ERR(clnt->cl_dentry)) { 252 if (!IS_ERR(clnt->cl_path.dentry)) {
235 rpc_rmdir(clnt->cl_dentry); 253 rpc_remove_client_dir(clnt->cl_path.dentry);
236 rpc_put_mount(); 254 rpc_put_mount();
237 } 255 }
238out_no_path: 256out_no_path:
@@ -423,8 +441,8 @@ rpc_free_client(struct kref *kref)
423 441
424 dprintk("RPC: destroying %s client for %s\n", 442 dprintk("RPC: destroying %s client for %s\n",
425 clnt->cl_protname, clnt->cl_server); 443 clnt->cl_protname, clnt->cl_server);
426 if (!IS_ERR(clnt->cl_dentry)) { 444 if (!IS_ERR(clnt->cl_path.dentry)) {
427 rpc_rmdir(clnt->cl_dentry); 445 rpc_remove_client_dir(clnt->cl_path.dentry);
428 rpc_put_mount(); 446 rpc_put_mount();
429 } 447 }
430 if (clnt->cl_parent != clnt) { 448 if (clnt->cl_parent != clnt) {