[PATCH 1/3] kernfs: activate nodes while linking them

From: Pavol Sakac

Date: Fri Sep 11 2026 - 13:24:24 EST


kernfs_add_one() links a new node, releases kernfs_rwsem, and takes it
again through kernfs_activate(). A new node has no descendants, so the
second hold only activates that node.

Activate ordinary nodes before releasing the linking hold, removing a
second write-side acquisition and the linked-but-inactive interval.
KERNFS_ROOT_CREATE_DEACTIVATED roots retain explicit subtree activation.

Removing the unlock-to-lock pair also removes its publication ordering.
The in-tree lockless ID lookups use CREATE_DEACTIVATED roots and retain
kernfs_activate(); unsynchronized callers cannot rely on observing a
node.

Assisted-by: LLM
Signed-off-by: Pavol Sakac <sakacpav@xxxxxxxxx>
---
fs/kernfs/dir.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 82bbaeb326aa..d68bce0b0b41 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -41,6 +41,8 @@ static bool kernfs_active(struct kernfs_node *kn)
return __kernfs_active(kn);
}

+static void kernfs_activate_one(struct kernfs_node *kn);
+
static bool kernfs_lockdep(struct kernfs_node *kn)
{
#ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -855,17 +857,16 @@ int kernfs_add_one(struct kernfs_node *kn)
}

up_write(&root->kernfs_iattr_rwsem);
- up_write(&root->kernfs_rwsem);

/*
- * Activate the new node unless CREATE_DEACTIVATED is requested.
- * If not activated here, the kernfs user is responsible for
- * activating the node with kernfs_activate(). A node which hasn't
- * been activated is not visible to userland and its removal won't
- * trigger deactivation.
+ * A freshly linked node has no descendants, so activating just @kn
+ * under the linking hold is equivalent to the kernfs_activate()
+ * walk; CREATE_DEACTIVATED roots keep deferred activation.
*/
- if (!(kernfs_root(kn)->flags & KERNFS_ROOT_CREATE_DEACTIVATED))
- kernfs_activate(kn);
+ if (!(root->flags & KERNFS_ROOT_CREATE_DEACTIVATED))
+ kernfs_activate_one(kn);
+
+ up_write(&root->kernfs_rwsem);
return 0;

out_unlock:
--
2.47.3