On Sat 29-03-25 09:42:17, Christian Brauner wrote: > Use a common iterator for all callbacks. > > Signed-off-by: Christian Brauner <brauner@xxxxxxxxxx> Very nice! Feel free to add: Reviewed-by: Jan Kara <jack@xxxxxxx> Honza > --- > fs/super.c | 67 +++++++++++------------------------------------------- > include/linux/fs.h | 6 ++++- > 2 files changed, 18 insertions(+), 55 deletions(-) > > diff --git a/fs/super.c b/fs/super.c > index c67ea3cdda41..0dd208804a74 100644 > --- a/fs/super.c > +++ b/fs/super.c > @@ -887,37 +887,7 @@ void drop_super_exclusive(struct super_block *sb) > } > EXPORT_SYMBOL(drop_super_exclusive); > > -static void __iterate_supers(void (*f)(struct super_block *)) > -{ > - struct super_block *sb, *p = NULL; > - > - spin_lock(&sb_lock); > - list_for_each_entry(sb, &super_blocks, s_list) { > - if (super_flags(sb, SB_DYING)) > - continue; > - sb->s_count++; > - spin_unlock(&sb_lock); > - > - f(sb); > - > - spin_lock(&sb_lock); > - if (p) > - __put_super(p); > - p = sb; > - } > - if (p) > - __put_super(p); > - spin_unlock(&sb_lock); > -} > -/** > - * iterate_supers - call function for all active superblocks > - * @f: function to call > - * @arg: argument to pass to it > - * > - * Scans the superblock list and calls given function, passing it > - * locked superblock and given argument. > - */ > -void iterate_supers(void (*f)(struct super_block *, void *), void *arg) > +void __iterate_supers(void (*f)(struct super_block *, void *), void *arg, bool excl) > { > struct super_block *sb, *p = NULL; > > @@ -927,14 +897,13 @@ void iterate_supers(void (*f)(struct super_block *, void *), void *arg) > > if (super_flags(sb, SB_DYING)) > continue; > - > sb->s_count++; > spin_unlock(&sb_lock); > > - locked = super_lock_shared(sb); > + locked = super_lock(sb, excl); > if (locked) { > f(sb, arg); > - super_unlock_shared(sb); > + super_unlock(sb, excl); > } > > spin_lock(&sb_lock); > @@ -1111,11 +1080,9 @@ int reconfigure_super(struct fs_context *fc) > return retval; > } > > -static void do_emergency_remount_callback(struct super_block *sb) > +static void do_emergency_remount_callback(struct super_block *sb, void *unused) > { > - bool locked = super_lock_excl(sb); > - > - if (locked && sb->s_root && sb->s_bdev && !sb_rdonly(sb)) { > + if (sb->s_bdev && !sb_rdonly(sb)) { > struct fs_context *fc; > > fc = fs_context_for_reconfigure(sb->s_root, > @@ -1126,13 +1093,11 @@ static void do_emergency_remount_callback(struct super_block *sb) > put_fs_context(fc); > } > } > - if (locked) > - super_unlock_excl(sb); > } > > static void do_emergency_remount(struct work_struct *work) > { > - __iterate_supers(do_emergency_remount_callback); > + __iterate_supers(do_emergency_remount_callback, NULL, true); > kfree(work); > printk("Emergency Remount complete\n"); > } > @@ -1148,24 +1113,18 @@ void emergency_remount(void) > } > } > > -static void do_thaw_all_callback(struct super_block *sb) > +static void do_thaw_all_callback(struct super_block *sb, void *unused) > { > - bool locked = super_lock_excl(sb); > - > - if (locked && sb->s_root) { > - if (IS_ENABLED(CONFIG_BLOCK)) > - while (sb->s_bdev && !bdev_thaw(sb->s_bdev)) > - pr_warn("Emergency Thaw on %pg\n", sb->s_bdev); > - thaw_super_locked(sb, FREEZE_HOLDER_USERSPACE); > - return; > - } > - if (locked) > - super_unlock_excl(sb); > + if (IS_ENABLED(CONFIG_BLOCK)) > + while (sb->s_bdev && !bdev_thaw(sb->s_bdev)) > + pr_warn("Emergency Thaw on %pg\n", sb->s_bdev); > + thaw_super_locked(sb, FREEZE_HOLDER_USERSPACE); > + return; > } > > static void do_thaw_all(struct work_struct *work) > { > - __iterate_supers(do_thaw_all_callback); > + __iterate_supers(do_thaw_all_callback, NULL, true); > kfree(work); > printk(KERN_WARNING "Emergency Thaw complete\n"); > } > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 016b0fe1536e..0351500b71d2 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -3515,7 +3515,11 @@ extern void put_filesystem(struct file_system_type *fs); > extern struct file_system_type *get_fs_type(const char *name); > extern void drop_super(struct super_block *sb); > extern void drop_super_exclusive(struct super_block *sb); > -extern void iterate_supers(void (*)(struct super_block *, void *), void *); > +void __iterate_supers(void (*f)(struct super_block *, void *), void *arg, bool excl); > +static inline void iterate_supers(void (*f)(struct super_block *, void *), void *arg) > +{ > + __iterate_supers(f, arg, false); > +} > extern void iterate_supers_type(struct file_system_type *, > void (*)(struct super_block *, void *), void *); > > > -- > 2.47.2 > -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR