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>
This commit is contained in:
parent
7d217caca5
commit
23ac658170
|
@ -51,7 +51,6 @@ struct rpc_clnt {
|
||||||
|
|
||||||
int cl_nodelen; /* nodename length */
|
int cl_nodelen; /* nodename length */
|
||||||
char cl_nodename[UNX_MAXNODENAME];
|
char cl_nodename[UNX_MAXNODENAME];
|
||||||
char cl_pathname[30];/* Path in rpc_pipe_fs */
|
|
||||||
struct path cl_path;
|
struct path cl_path;
|
||||||
struct rpc_clnt * cl_parent; /* Points to parent of clones */
|
struct rpc_clnt * cl_parent; /* Points to parent of clones */
|
||||||
struct rpc_rtt cl_rtt_default;
|
struct rpc_rtt cl_rtt_default;
|
||||||
|
|
|
@ -45,7 +45,7 @@ RPC_I(struct inode *inode)
|
||||||
extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
|
extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
|
||||||
|
|
||||||
struct rpc_clnt;
|
struct rpc_clnt;
|
||||||
extern struct dentry *rpc_create_client_dir(const char *, struct rpc_clnt *);
|
extern struct dentry *rpc_create_client_dir(struct dentry *, struct qstr *, struct rpc_clnt *);
|
||||||
extern int rpc_remove_client_dir(struct dentry *);
|
extern int rpc_remove_client_dir(struct dentry *);
|
||||||
extern struct dentry *rpc_mkpipe(struct dentry *, const char *, void *,
|
extern struct dentry *rpc_mkpipe(struct dentry *, const char *, void *,
|
||||||
const struct rpc_pipe_ops *, int flags);
|
const struct rpc_pipe_ops *, int flags);
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/kallsyms.h>
|
#include <linux/kallsyms.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
#include <linux/namei.h>
|
||||||
|
#include <linux/mount.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/utsname.h>
|
#include <linux/utsname.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
@ -97,6 +99,12 @@ static int
|
||||||
rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
|
rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
|
||||||
{
|
{
|
||||||
static uint32_t clntid;
|
static uint32_t clntid;
|
||||||
|
struct nameidata nd;
|
||||||
|
struct path path;
|
||||||
|
char name[15];
|
||||||
|
struct qstr q = {
|
||||||
|
.name = name,
|
||||||
|
};
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
clnt->cl_path.mnt = ERR_PTR(-ENOENT);
|
clnt->cl_path.mnt = ERR_PTR(-ENOENT);
|
||||||
|
@ -104,26 +112,36 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
|
||||||
if (dir_name == NULL)
|
if (dir_name == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
clnt->cl_path.mnt = rpc_get_mount();
|
path.mnt = rpc_get_mount();
|
||||||
if (IS_ERR(clnt->cl_path.mnt))
|
if (IS_ERR(path.mnt))
|
||||||
return PTR_ERR(clnt->cl_path.mnt);
|
return PTR_ERR(path.mnt);
|
||||||
|
error = vfs_path_lookup(path.mnt->mnt_root, path.mnt, dir_name, 0, &nd);
|
||||||
|
if (error)
|
||||||
|
goto err;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname),
|
q.len = snprintf(name, sizeof(name), "clnt%x", (unsigned int)clntid++);
|
||||||
"%s/clnt%x", dir_name,
|
name[sizeof(name) - 1] = '\0';
|
||||||
(unsigned int)clntid++);
|
q.hash = full_name_hash(q.name, q.len);
|
||||||
clnt->cl_pathname[sizeof(clnt->cl_pathname) - 1] = '\0';
|
path.dentry = rpc_create_client_dir(nd.path.dentry, &q, clnt);
|
||||||
clnt->cl_path.dentry = rpc_create_client_dir(clnt->cl_pathname, clnt);
|
if (!IS_ERR(path.dentry))
|
||||||
if (!IS_ERR(clnt->cl_path.dentry))
|
break;
|
||||||
return 0;
|
error = PTR_ERR(path.dentry);
|
||||||
error = PTR_ERR(clnt->cl_path.dentry);
|
|
||||||
if (error != -EEXIST) {
|
if (error != -EEXIST) {
|
||||||
printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n",
|
printk(KERN_INFO "RPC: Couldn't create pipefs entry"
|
||||||
clnt->cl_pathname, error);
|
" %s/%s, error %d\n",
|
||||||
rpc_put_mount();
|
dir_name, name, error);
|
||||||
return error;
|
goto err_path_put;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
path_put(&nd.path);
|
||||||
|
clnt->cl_path = path;
|
||||||
|
return 0;
|
||||||
|
err_path_put:
|
||||||
|
path_put(&nd.path);
|
||||||
|
err:
|
||||||
|
rpc_put_mount();
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
|
static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
|
||||||
|
|
|
@ -443,42 +443,6 @@ static const struct dentry_operations rpc_dentry_operations = {
|
||||||
.d_delete = rpc_delete_dentry,
|
.d_delete = rpc_delete_dentry,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __rpc_lookup_path(const char *pathname, unsigned flags,
|
|
||||||
struct nameidata *nd)
|
|
||||||
{
|
|
||||||
struct vfsmount *mnt;
|
|
||||||
|
|
||||||
if (pathname[0] == '\0')
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
mnt = rpc_get_mount();
|
|
||||||
if (IS_ERR(mnt)) {
|
|
||||||
printk(KERN_WARNING "%s: %s failed to mount "
|
|
||||||
"pseudofilesystem \n", __FILE__, __func__);
|
|
||||||
return PTR_ERR(mnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vfs_path_lookup(mnt->mnt_root, mnt, pathname, flags, nd)) {
|
|
||||||
printk(KERN_WARNING "%s: %s failed to find path %s\n",
|
|
||||||
__FILE__, __func__, pathname);
|
|
||||||
rpc_put_mount();
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rpc_lookup_parent(const char *pathname, struct nameidata *nd)
|
|
||||||
{
|
|
||||||
return __rpc_lookup_path(pathname, LOOKUP_PARENT, nd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
rpc_release_path(struct nameidata *nd)
|
|
||||||
{
|
|
||||||
path_put(&nd->path);
|
|
||||||
rpc_put_mount();
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct inode *
|
static struct inode *
|
||||||
rpc_get_inode(struct super_block *sb, umode_t mode)
|
rpc_get_inode(struct super_block *sb, umode_t mode)
|
||||||
{
|
{
|
||||||
|
@ -889,27 +853,11 @@ EXPORT_SYMBOL_GPL(rpc_unlink);
|
||||||
* information about the client, together with any "pipes" that may
|
* information about the client, together with any "pipes" that may
|
||||||
* later be created using rpc_mkpipe().
|
* later be created using rpc_mkpipe().
|
||||||
*/
|
*/
|
||||||
struct dentry *rpc_create_client_dir(const char *path,
|
struct dentry *rpc_create_client_dir(struct dentry *dentry,
|
||||||
|
struct qstr *name,
|
||||||
struct rpc_clnt *rpc_client)
|
struct rpc_clnt *rpc_client)
|
||||||
{
|
{
|
||||||
struct nameidata nd;
|
return rpc_mkdir_populate(dentry, name, S_IRUGO | S_IXUGO, rpc_client);
|
||||||
struct dentry *ret;
|
|
||||||
struct inode *dir;
|
|
||||||
|
|
||||||
ret = ERR_PTR(rpc_lookup_parent(path, &nd));
|
|
||||||
if (IS_ERR(ret))
|
|
||||||
goto out_err;
|
|
||||||
dir = nd.path.dentry->d_inode;
|
|
||||||
|
|
||||||
ret = rpc_mkdir_populate(nd.path.dentry, &nd.last,
|
|
||||||
S_IRUGO | S_IXUGO, rpc_client);
|
|
||||||
rpc_release_path(&nd);
|
|
||||||
if (!IS_ERR(ret))
|
|
||||||
return ret;
|
|
||||||
out_err:
|
|
||||||
printk(KERN_WARNING "%s: %s() failed to create directory %s (errno = %ld)\n",
|
|
||||||
__FILE__, __func__, path, PTR_ERR(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue