Re: [PATCH v2] kernfs: allocate inodes and dentry outside kernfs_rwsem

From: Tejun Heo

Date: Fri Oct 16 2026 - 16:33:28 EST


Hello, Shakeel.

On Fri, Oct 16, 2026 at 09:43:45AM -0700, Shakeel Butt wrote:
> Allocate the inode with the lock dropped. kernfs_iget() first looks for
> an existing inode. If there is none, it pins the node, drops the lock,
> allocates, takes the lock again, and adds the inode only if the node is
> still active. So __kernfs_remove() still finds every inode it must
> clear i_nlink on, as commit dc1a0cc95737 ("kernfs: don't lose
> IN_DELETE_SELF when decoding a file handle") needs.

Would it be simpler to allocate the inode before taking kernfs_rwsem and
free it if it ends up unused, as 8b64f32fee95 ("kernfs: allocate the new
name outside kernfs_rwsem") and 5ad03af18434 ("kernfs: allocate the open
node outside the open file mutex") do? Then the lock doesn't have to be
dropped, and there's no need for the pin and the active recheck. The
unused cases (negative lookups, inactive nodes, nodes which already have
an inode) are exceptions, and an inode alloc and free isn't expensive.

The helper would then just run under kernfs_rwsem. Maybe
kernfs_get_inode_locked() would be a better name for it?

kernfs_fill_super() can preallocate the same way, which gets rid of the
last inode allocation under kernfs_rwsem. cgroup_may_write() allocates
the inode under cgroup_mutex and could allocate before grabbing the
mutex too.

> kernfs_get_parent_dentry() also held the lock across d_obtain_alias(),
> which allocates a dentry. Hold it only around kernfs_iget(), as
> __kernfs_fh_to_dentry() already does.

This also adds the active test to ->get_parent. A parent which is being
removed and has no inode now gets -ESTALE instead of a new inode with
i_nlink 1, which closes the window dc1a0cc95737 ("kernfs: don't lose
IN_DELETE_SELF when decoding a file handle") left open. Can you mention
it in the description?

Thanks.

--
tejun