Message ID | 20250318194111.19419-3-James.Bottomley@HansenPartnership.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | create simple libfs directory iterator and make efivarfs use it | expand |
On Tue, 18 Mar 2025 at 20:45, James Bottomley <James.Bottomley@hansenpartnership.com> 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@HansenPartnership.com> > --- > 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 >
On Tue, 2025-03-18 at 22:33 +0100, Ard Biesheuvel wrote: > On Tue, 18 Mar 2025 at 20:45, James Bottomley > <James.Bottomley@hansenpartnership.com> 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@HansenPartnership.com> > > --- > > 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. Right, I started out thinking the generic_ prefix was the preferred one, but then simple_ looked better and I forgot to update the docbook. Regards, James
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 + * + * @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 *);
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@HansenPartnership.com> --- fs/libfs.c | 33 +++++++++++++++++++++++++++++++++ include/linux/fs.h | 2 ++ 2 files changed, 35 insertions(+)