Commit fe0f726c authored by Tejun Heo's avatar Tejun Heo

kernfs: combine ino/id lookup functions into kernfs_find_and_get_node_by_id()

kernfs_find_and_get_node_by_ino() looks the kernfs_node matching the
specified ino.  On top of that, kernfs_get_node_by_id() and
kernfs_fh_get_inode() implement full ID matching by testing the rest
of ID.

On surface, confusingly, the two are slightly different in that the
latter uses 0 gen as wildcard while the former doesn't - does it mean
that the latter can't uniquely identify inodes w/ 0 gen?  In practice,
this is a distinction without a difference because generation number
starts at 1.  There are no actual IDs with 0 gen, so it can always
safely used as wildcard.

Let's simplify the code by renaming kernfs_find_and_get_node_by_ino()
to kernfs_find_and_get_node_by_id(), moving all lookup logics into it,
and removing now unnecessary kernfs_get_node_by_id().
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 67c0496e
...@@ -696,17 +696,22 @@ struct kernfs_node *kernfs_new_node(struct kernfs_node *parent, ...@@ -696,17 +696,22 @@ struct kernfs_node *kernfs_new_node(struct kernfs_node *parent,
} }
/* /*
* kernfs_find_and_get_node_by_ino - get kernfs_node from inode number * kernfs_find_and_get_node_by_id - get kernfs_node from node id
* @root: the kernfs root * @root: the kernfs root
* @ino: inode number * @id: the target node id
*
* @id's lower 32bits encode ino and upper gen. If the gen portion is
* zero, all generations are matched.
* *
* RETURNS: * RETURNS:
* NULL on failure. Return a kernfs node with reference counter incremented * NULL on failure. Return a kernfs node with reference counter incremented
*/ */
struct kernfs_node *kernfs_find_and_get_node_by_ino(struct kernfs_root *root, struct kernfs_node *kernfs_find_and_get_node_by_id(struct kernfs_root *root,
unsigned int ino) u64 id)
{ {
struct kernfs_node *kn; struct kernfs_node *kn;
ino_t ino = kernfs_id_ino(id);
u32 gen = kernfs_id_gen(id);
spin_lock(&kernfs_idr_lock); spin_lock(&kernfs_idr_lock);
...@@ -714,6 +719,10 @@ struct kernfs_node *kernfs_find_and_get_node_by_ino(struct kernfs_root *root, ...@@ -714,6 +719,10 @@ struct kernfs_node *kernfs_find_and_get_node_by_ino(struct kernfs_root *root,
if (!kn) if (!kn)
goto err_unlock; goto err_unlock;
/* 0 matches all generations */
if (unlikely(gen && kernfs_gen(kn) != gen))
goto err_unlock;
/* /*
* ACTIVATED is protected with kernfs_mutex but it was clear when * ACTIVATED is protected with kernfs_mutex but it was clear when
* @kn was added to idr and we just wanna see it set. No need to * @kn was added to idr and we just wanna see it set. No need to
......
...@@ -109,8 +109,6 @@ struct kernfs_node *kernfs_new_node(struct kernfs_node *parent, ...@@ -109,8 +109,6 @@ struct kernfs_node *kernfs_new_node(struct kernfs_node *parent,
const char *name, umode_t mode, const char *name, umode_t mode,
kuid_t uid, kgid_t gid, kuid_t uid, kgid_t gid,
unsigned flags); unsigned flags);
struct kernfs_node *kernfs_find_and_get_node_by_ino(struct kernfs_root *root,
unsigned int ino);
/* /*
* file.c * file.c
......
...@@ -53,24 +53,6 @@ const struct super_operations kernfs_sops = { ...@@ -53,24 +53,6 @@ const struct super_operations kernfs_sops = {
.show_path = kernfs_sop_show_path, .show_path = kernfs_sop_show_path,
}; };
/*
* Similar to kernfs_fh_get_inode, this one gets kernfs node from inode
* number and generation
*/
struct kernfs_node *kernfs_get_node_by_id(struct kernfs_root *root, u64 id)
{
struct kernfs_node *kn;
kn = kernfs_find_and_get_node_by_ino(root, kernfs_id_ino(id));
if (!kn)
return NULL;
if (kernfs_gen(kn) != kernfs_id_gen(id)) {
kernfs_put(kn);
return NULL;
}
return kn;
}
static struct inode *kernfs_fh_get_inode(struct super_block *sb, static struct inode *kernfs_fh_get_inode(struct super_block *sb,
u64 ino, u32 generation) u64 ino, u32 generation)
{ {
...@@ -81,7 +63,8 @@ static struct inode *kernfs_fh_get_inode(struct super_block *sb, ...@@ -81,7 +63,8 @@ static struct inode *kernfs_fh_get_inode(struct super_block *sb,
if (ino == 0) if (ino == 0)
return ERR_PTR(-ESTALE); return ERR_PTR(-ESTALE);
kn = kernfs_find_and_get_node_by_ino(info->root, ino); kn = kernfs_find_and_get_node_by_id(info->root,
ino | ((u64)generation << 32));
if (!kn) if (!kn)
return ERR_PTR(-ESTALE); return ERR_PTR(-ESTALE);
inode = kernfs_get_inode(sb, kn); inode = kernfs_get_inode(sb, kn);
...@@ -89,11 +72,6 @@ static struct inode *kernfs_fh_get_inode(struct super_block *sb, ...@@ -89,11 +72,6 @@ static struct inode *kernfs_fh_get_inode(struct super_block *sb,
if (!inode) if (!inode)
return ERR_PTR(-ESTALE); return ERR_PTR(-ESTALE);
if (generation && inode->i_generation != generation) {
/* we didn't find the right inode.. */
iput(inode);
return ERR_PTR(-ESTALE);
}
return inode; return inode;
} }
......
...@@ -393,7 +393,8 @@ void kernfs_kill_sb(struct super_block *sb); ...@@ -393,7 +393,8 @@ void kernfs_kill_sb(struct super_block *sb);
void kernfs_init(void); void kernfs_init(void);
struct kernfs_node *kernfs_get_node_by_id(struct kernfs_root *root, u64 id); struct kernfs_node *kernfs_find_and_get_node_by_id(struct kernfs_root *root,
u64 id);
#else /* CONFIG_KERNFS */ #else /* CONFIG_KERNFS */
static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn) static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn)
......
...@@ -5790,7 +5790,7 @@ void cgroup_path_from_kernfs_id(u64 id, char *buf, size_t buflen) ...@@ -5790,7 +5790,7 @@ void cgroup_path_from_kernfs_id(u64 id, char *buf, size_t buflen)
{ {
struct kernfs_node *kn; struct kernfs_node *kn;
kn = kernfs_get_node_by_id(cgrp_dfl_root.kf_root, id); kn = kernfs_find_and_get_node_by_id(cgrp_dfl_root.kf_root, id);
if (!kn) if (!kn)
return; return;
kernfs_path(kn, buf, buflen); kernfs_path(kn, buf, buflen);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment