}
 
 /*
- * 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
- * @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:
  * 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,
-                                                   unsigned int ino)
+struct kernfs_node *kernfs_find_and_get_node_by_id(struct kernfs_root *root,
+                                                  u64 id)
 {
        struct kernfs_node *kn;
+       ino_t ino = kernfs_id_ino(id);
+       u32 gen = kernfs_id_gen(id);
 
        spin_lock(&kernfs_idr_lock);
 
        if (!kn)
                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
         * @kn was added to idr and we just wanna see it set.  No need to
 
                                    const char *name, umode_t mode,
                                    kuid_t uid, kgid_t gid,
                                    unsigned flags);
-struct kernfs_node *kernfs_find_and_get_node_by_ino(struct kernfs_root *root,
-                                                   unsigned int ino);
 
 /*
  * file.c
 
        .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,
                u64 ino, u32 generation)
 {
        if (ino == 0)
                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)
                return ERR_PTR(-ESTALE);
        inode = kernfs_get_inode(sb, kn);
        if (!inode)
                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;
 }
 
 
 
 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 */
 
 static inline enum kernfs_node_type kernfs_type(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)
                return;
        kernfs_path(kn, buf, buflen);