On Tue, 18 Mar 2025 at 20:45, James Bottomley <James.Bottomley@xxxxxxxxxxxxxxxxxxxxx> wrote: > > The current iterate_dir() infrastructure is somewhat cumbersome to use > from within the kernel. Introduce a lighter weight > simple_iterate_dir() function that directly iterates the directory and > executes a callback for each positive dentry. > > Signed-off-by: James Bottomley <James.Bottomley@xxxxxxxxxxxxxxxxxxxxx> > --- > fs/libfs.c | 33 +++++++++++++++++++++++++++++++++ > include/linux/fs.h | 2 ++ > 2 files changed, 35 insertions(+) > > diff --git a/fs/libfs.c b/fs/libfs.c > index 816bfe6c0430..37da5fe25242 100644 > --- a/fs/libfs.c > +++ b/fs/libfs.c > @@ -214,6 +214,39 @@ static void internal_readdir(struct dentry *dentry, struct dentry *cursor, > dput(next); > } > > +/** > + * generic_iterate_call - iterate all entries executing @callback This name doesn't match the name below. > + * > + * @dir: directory to iterate over > + * @data: data passed to callback > + * @callback: callback to call > + * > + * Iterates over all positive dentries that are direct children of > + * @dir (so doesn't include . and ..) and executes the callback for > + * each of them. Note that because there's no struct *mnt, the caller > + * is responsible for pinning the filesystem. > + * > + * If the @callback returns true, the iteration will continue and if > + * it returns @false, it will stop (note that since the cursor is > + * destroyed the next invocation will go back to the beginning again). > + * > + */ > +int simple_iterate_call(struct dentry *dir, void *data, > + bool (*callback)(void *, struct dentry *)) > +{ > + struct dentry *cursor = d_alloc_cursor(dir); > + > + if (!cursor) > + return -ENOMEM; > + > + internal_readdir(dir, cursor, data, true, callback); > + > + dput(cursor); > + > + return 0; > +} > +EXPORT_SYMBOL(simple_iterate_call); > + > static bool dcache_readdir_callback(void *data, struct dentry *entry) > { > struct dir_context *ctx = data; > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 2788df98080f..a84896f0b2d1 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -3531,6 +3531,8 @@ extern int simple_rename(struct mnt_idmap *, struct inode *, > unsigned int); > extern void simple_recursive_removal(struct dentry *, > void (*callback)(struct dentry *)); > +extern int simple_iterate_call(struct dentry *dir, void *data, > + bool (*callback)(void *, struct dentry *)); > extern int noop_fsync(struct file *, loff_t, loff_t, int); > extern ssize_t noop_direct_IO(struct kiocb *iocb, struct iov_iter *iter); > extern int simple_empty(struct dentry *); > -- > 2.43.0 >