[Devel] [PATCH vz10 09/24] kernfs: rcu_read_lock() when walking parents in ve visibility checks

Konstantin Khorenko khorenko at virtuozzo.com
Mon Jul 6 13:59:47 MSK 2026


kernfs_ve_permission() and kernfs_d_visible() walk the parent chain with
kernfs_parent(), which is rcu_dereference_check(kn->__parent, ...) and
requires the kernfs rwsem/rename_lock, a zero refcount, or an RCU
read-side critical section. They are called from the permission/lookup
path holding only kernfs_iattr_rwsem, so on a lockdep kernel this trips:

  WARNING: suspicious RCU usage
  fs/kernfs/kernfs-internal.h:131 suspicious rcu_dereference_check() usage!
  kernfs_ve_permission <- kernfs_iop_permission <- inode_permission

Wrap the parent walks in rcu_read_lock(); kernfs nodes are RCU-freed so
this is both correct (guards against concurrent reparent/free) and
silences the splat.

Fixes: cd9dd4ead86a ("ve/kernfs: implement ve-based permissions")
Feature: sysfs: per-CT entries visibility and permissions configuration
https://virtuozzo.atlassian.net/browse/VSTOR-137234
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
 fs/kernfs/ve.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/fs/kernfs/ve.c b/fs/kernfs/ve.c
index beaa278b014e..e83ee5bec3bf 100644
--- a/fs/kernfs/ve.c
+++ b/fs/kernfs/ve.c
@@ -64,11 +64,15 @@ int kernfs_ve_permission(struct kernfs_node *kn,
 		return 0;
 
 	/* Entries with namespace tag and their sub-entries always visible */
+	rcu_read_lock();
 	while (tmp_kn) {
-		if (tmp_kn->ns)
+		if (tmp_kn->ns) {
+			rcu_read_unlock();
 			return 0;
+		}
 		tmp_kn = kernfs_parent(tmp_kn);
 	}
+	rcu_read_unlock();
 
 	if (kernfs_type(kn) == KERNFS_LINK)
 		kn = kn->symlink.target_kn;
@@ -108,11 +112,15 @@ bool kernfs_d_visible(struct kernfs_node *kn, struct kernfs_super_info *info)
 		return true;
 
 	/* Entries with namespace tag and their sub-entries always visible */
+	rcu_read_lock();
 	while (tmp_kn) {
-		if (tmp_kn->ns)
+		if (tmp_kn->ns) {
+			rcu_read_unlock();
 			return true;
+		}
 		tmp_kn = kernfs_parent(tmp_kn);
 	}
+	rcu_read_unlock();
 
 	/* Symlinks are visible if target kn is visible */
 	if (kernfs_type(kn) == KERNFS_LINK)
-- 
2.47.1



More information about the Devel mailing list