struct kernfs_node *parent;
        struct kernfs_root *root;
 
+       /*
+        * kernfs_node is freed with ->count 0, kernfs_find_and_get_node_by_ino
+        * depends on this to filter reused stale node
+        */
        if (!kn || !atomic_dec_and_test(&kn->count))
                return;
        root = kernfs_root(kn);
        kn->ino = ret;
        kn->generation = gen;
 
+       /*
+        * set ino first. This barrier is paired with atomic_inc_not_zero in
+        * kernfs_find_and_get_node_by_ino
+        */
+       smp_mb__before_atomic();
        atomic_set(&kn->count, 1);
        atomic_set(&kn->active, KN_DEACTIVATED_BIAS);
        RB_CLEAR_NODE(&kn->rb);
        return kn;
 }
 
+/*
+ * kernfs_find_and_get_node_by_ino - get kernfs_node from inode number
+ * @root: the kernfs root
+ * @ino: inode number
+ *
+ * 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 *kn;
+
+       rcu_read_lock();
+       kn = idr_find(&root->ino_idr, ino);
+       if (!kn)
+               goto out;
+
+       /*
+        * Since kernfs_node is freed in RCU, it's possible an old node for ino
+        * is freed, but reused before RCU grace period. But a freed node (see
+        * kernfs_put) or an incompletedly initialized node (see
+        * __kernfs_new_node) should have 'count' 0. We can use this fact to
+        * filter out such node.
+        */
+       if (!atomic_inc_not_zero(&kn->count)) {
+               kn = NULL;
+               goto out;
+       }
+
+       /*
+        * The node could be a new node or a reused node. If it's a new node,
+        * we are ok. If it's reused because of RCU (because of
+        * SLAB_TYPESAFE_BY_RCU), the __kernfs_new_node always sets its 'ino'
+        * before 'count'. So if 'count' is uptodate, 'ino' should be uptodate,
+        * hence we can use 'ino' to filter stale node.
+        */
+       if (kn->ino != ino)
+               goto out;
+       rcu_read_unlock();
+
+       return kn;
+out:
+       rcu_read_unlock();
+       kernfs_put(kn);
+       return NULL;
+}
+
 /**
  *     kernfs_add_one - add kernfs_node to parent without warning
  *     @kn: kernfs_node to be added
 
 
 void __init kernfs_init(void)
 {
+
+       /*
+        * the slab is freed in RCU context, so kernfs_find_and_get_node_by_ino
+        * can access the slab lock free. This could introduce stale nodes,
+        * please see how kernfs_find_and_get_node_by_ino filters out stale
+        * nodes.
+        */
        kernfs_node_cache = kmem_cache_create("kernfs_node_cache",
                                              sizeof(struct kernfs_node),
-                                             0, SLAB_PANIC, NULL);
+                                             0,
+                                             SLAB_PANIC | SLAB_TYPESAFE_BY_RCU,
+                                             NULL);
 }