提交 23ac6581 编写于 作者: T Trond Myklebust

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: NTrond Myklebust <Trond.Myklebust@netapp.com>
上级 7d217cac
...@@ -51,7 +51,6 @@ struct rpc_clnt { ...@@ -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) ...@@ -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 @@ ...@@ -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 ...@@ -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) ...@@ -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 = { ...@@ -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); ...@@ -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;
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册