diff options
author | Christoph Hellwig <hch@infradead.org> | 2005-07-24 18:53:01 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-09-23 12:38:57 -0400 |
commit | 278c995c8a153bb2a9bc427e931cfb9c8034c9d7 (patch) | |
tree | fe1b62d1686c78659133d751393ab2d5acf38665 /net/sunrpc/clnt.c | |
parent | 470056c288334eb0b37be26c9ff8aee37ed1cc7a (diff) |
[PATCH] RPC,NFS: new rpc_pipefs patch
Currently rpc_mkdir/rpc_rmdir and rpc_mkpipe/mk_unlink have an API that's
a little unfortunate. They take a path relative to the rpc_pipefs root and
thus need to perform a full lookup. If you look at debugfs or usbfs they
always store the dentry for directories they created and thus can pass in
a dentry + single pathname component pair into their equivalents of the
above functions.
And in fact rpc_pipefs actually stores a dentry for all but one component so
this change not only simplifies the core rpc_pipe code but also the callers.
Unfortuntately this code path is only used by the NFS4 idmapper and
AUTH_GSSAPI for which I don't have a test enviroment. Could someone give
it a spin? It's the last bit needed before we can rework the
lookup_hash API
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r-- | net/sunrpc/clnt.c | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 5a8f01d726e9..63bf591310e0 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -67,26 +67,42 @@ static u32 * call_verify(struct rpc_task *task); | |||
67 | static int | 67 | static int |
68 | rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) | 68 | rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) |
69 | { | 69 | { |
70 | static uint32_t clntid; | 70 | static unsigned int clntid; |
71 | char name[128]; | ||
71 | int error; | 72 | int error; |
72 | 73 | ||
73 | if (dir_name == NULL) | 74 | if (dir_name == NULL) |
74 | return 0; | 75 | return 0; |
75 | for (;;) { | 76 | |
76 | snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname), | 77 | retry_parent: |
77 | "%s/clnt%x", dir_name, | 78 | clnt->__cl_parent_dentry = rpc_mkdir(NULL, dir_name, NULL); |
78 | (unsigned int)clntid++); | 79 | if (IS_ERR(clnt->__cl_parent_dentry)) { |
79 | clnt->cl_pathname[sizeof(clnt->cl_pathname) - 1] = '\0'; | 80 | error = PTR_ERR(clnt->__cl_parent_dentry); |
80 | clnt->cl_dentry = rpc_mkdir(clnt->cl_pathname, clnt); | 81 | if (error == -EEXIST) |
81 | if (!IS_ERR(clnt->cl_dentry)) | 82 | goto retry_parent; /* XXX(hch): WTF? */ |
82 | return 0; | 83 | |
84 | printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n", | ||
85 | dir_name, error); | ||
86 | return error; | ||
87 | } | ||
88 | |||
89 | |||
90 | retry_child: | ||
91 | snprintf(name, sizeof(name), "clnt%x", clntid++); | ||
92 | name[sizeof(name) - 1] = '\0'; | ||
93 | |||
94 | clnt->cl_dentry = rpc_mkdir(clnt->__cl_parent_dentry, name, clnt); | ||
95 | if (IS_ERR(clnt->cl_dentry)) { | ||
83 | error = PTR_ERR(clnt->cl_dentry); | 96 | error = PTR_ERR(clnt->cl_dentry); |
84 | if (error != -EEXIST) { | 97 | if (error == -EEXIST) |
85 | printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n", | 98 | goto retry_child; |
86 | clnt->cl_pathname, error); | 99 | printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n", |
87 | return error; | 100 | name, error); |
88 | } | 101 | rpc_rmdir(clnt->__cl_parent_dentry); |
102 | return error; | ||
89 | } | 103 | } |
104 | |||
105 | return 0; | ||
90 | } | 106 | } |
91 | 107 | ||
92 | /* | 108 | /* |
@@ -174,7 +190,8 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname, | |||
174 | return clnt; | 190 | return clnt; |
175 | 191 | ||
176 | out_no_auth: | 192 | out_no_auth: |
177 | rpc_rmdir(clnt->cl_pathname); | 193 | rpc_rmdir(clnt->cl_dentry); |
194 | rpc_rmdir(clnt->__cl_parent_dentry); | ||
178 | out_no_path: | 195 | out_no_path: |
179 | if (clnt->cl_server != clnt->cl_inline_name) | 196 | if (clnt->cl_server != clnt->cl_inline_name) |
180 | kfree(clnt->cl_server); | 197 | kfree(clnt->cl_server); |
@@ -302,8 +319,10 @@ rpc_destroy_client(struct rpc_clnt *clnt) | |||
302 | rpc_destroy_client(clnt->cl_parent); | 319 | rpc_destroy_client(clnt->cl_parent); |
303 | goto out_free; | 320 | goto out_free; |
304 | } | 321 | } |
305 | if (clnt->cl_pathname[0]) | 322 | if (clnt->cl_dentry) |
306 | rpc_rmdir(clnt->cl_pathname); | 323 | rpc_rmdir(clnt->cl_dentry); |
324 | if (clnt->__cl_parent_dentry) | ||
325 | rpc_rmdir(clnt->__cl_parent_dentry); | ||
307 | if (clnt->cl_xprt) { | 326 | if (clnt->cl_xprt) { |
308 | xprt_destroy(clnt->cl_xprt); | 327 | xprt_destroy(clnt->cl_xprt); |
309 | clnt->cl_xprt = NULL; | 328 | clnt->cl_xprt = NULL; |