Re: [PATCH 1/3] kernfs: don't repeat or skip an entry when readdir resumes

From: Tejun Heo

Date: Thu Sep 10 2026 - 16:18:24 EST


On Wed, Sep 09, 2026 at 05:36:48PM -0700, Shakeel Butt wrote:
> readdir keeps its place as a name hash in ctx->pos and pins the entry in
> file->private_data. If that entry is gone when the listing comes back,
> kernfs_dir_pos() searches the rbtree for the hash and keeps whatever
> node the descent stopped on. That is the entry before or after the
> missing one, depending on the shape of the tree.
>
> Landing before it repeats an entry the previous getdents(2) call already
> reported. Landing after it, kernfs_dir_next_pos() calls rb_next() and
> steps over an unreported entry.
>
> With children A(10), B(20), C(30):
>
> report A, ctx->pos = 10
> A removed
> kernfs_dir_next_pos(10, A)
> A is gone, the search for 10 stops at B
> rb_next(B) -> C, so B is never reported
>
> Only the repeat happens today, between two getdents(2) calls. The skip
> needs the pinned entry to go away inside one call, which the next patch
> allows when it drops kernfs_rwsem around dir_emit().
>
> Before the commit 4e4d6d860b93 the descent kept a node only on the way
> left, which is a search for the first entry at or after the hash. That
> commit moved the assignment to the top of the loop, where it runs on
> right turns too. Restore that search, and step forward only when the
> pinned entry is still there rather than when the hash matches, since two
> entries in one directory can share a hash.
>
> While here, kernfs_dir_next_pos() called the hash @ino. It is never an
> inode number, so name it @hash.
>
> Fixes: 4e4d6d860b93 ("sysfs: Add s_hash to sysfs_dirent and order directory entries by hash")
> Assisted-by: LLM
> Signed-off-by: Shakeel Butt <shakeel.butt@xxxxxxxxx>

Acked-by: Tejun Heo <tj@xxxxxxxxxx>

Thanks.

--
tejun