]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
super: use a common iterator (Part 1)
authorChristian Brauner <brauner@kernel.org>
Sat, 29 Mar 2025 08:42:17 +0000 (09:42 +0100)
committerChristian Brauner <brauner@kernel.org>
Mon, 7 Apr 2025 07:37:17 +0000 (09:37 +0200)
Use a common iterator for all callbacks.

Link: https://lore.kernel.org/r/20250329-work-freeze-v2-4-a47af37ecc3d@kernel.org
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/super.c
include/linux/fs.h

index c67ea3cdda41237e4399117ed3bb6d6c9cb81e78..0dd208804a74d9794cce927ece51b56a4653b71c 100644 (file)
@@ -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 @@ cancel_readonly:
        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");
 }
index 35b81f4979048a3bcb70f52c2a2dfaaf2a75891a..5e007bffd00e3b5e4a4f1be20ecbaa173072a5ba 100644 (file)
@@ -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 *);