Skip to content

Commit b47e42d

Browse files
committed
super: use common iterator (Part 2)
Use a common iterator for all callbacks. We could go for something even more elaborate (advance step-by-step similar to iov_iter) but I really don't think this is warranted. Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Jan Kara <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent 2992476 commit b47e42d

File tree

2 files changed

+40
-14
lines changed

2 files changed

+40
-14
lines changed

fs/super.c

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -887,21 +887,46 @@ void drop_super_exclusive(struct super_block *sb)
887887
}
888888
EXPORT_SYMBOL(drop_super_exclusive);
889889

890-
void __iterate_supers(void (*f)(struct super_block *, void *), void *arg, bool excl)
890+
enum super_iter_flags_t {
891+
SUPER_ITER_EXCL = (1U << 0),
892+
SUPER_ITER_UNLOCKED = (1U << 1),
893+
SUPER_ITER_REVERSE = (1U << 2),
894+
};
895+
896+
static inline struct super_block *first_super(enum super_iter_flags_t flags)
897+
{
898+
if (flags & SUPER_ITER_REVERSE)
899+
return list_last_entry(&super_blocks, struct super_block, s_list);
900+
return list_first_entry(&super_blocks, struct super_block, s_list);
901+
}
902+
903+
static inline struct super_block *next_super(struct super_block *sb,
904+
enum super_iter_flags_t flags)
905+
{
906+
if (flags & SUPER_ITER_REVERSE)
907+
return list_prev_entry(sb, s_list);
908+
return list_next_entry(sb, s_list);
909+
}
910+
911+
static void __iterate_supers(void (*f)(struct super_block *, void *), void *arg,
912+
enum super_iter_flags_t flags)
891913
{
892914
struct super_block *sb, *p = NULL;
915+
bool excl = flags & SUPER_ITER_EXCL;
893916

894-
spin_lock(&sb_lock);
895-
list_for_each_entry(sb, &super_blocks, s_list) {
896-
bool locked;
917+
guard(spinlock)(&sb_lock);
897918

919+
for (sb = first_super(flags);
920+
!list_entry_is_head(sb, &super_blocks, s_list);
921+
sb = next_super(sb, flags)) {
898922
if (super_flags(sb, SB_DYING))
899923
continue;
900924
sb->s_count++;
901925
spin_unlock(&sb_lock);
902926

903-
locked = super_lock(sb, excl);
904-
if (locked) {
927+
if (flags & SUPER_ITER_UNLOCKED) {
928+
f(sb, arg);
929+
} else if (super_lock(sb, excl)) {
905930
f(sb, arg);
906931
super_unlock(sb, excl);
907932
}
@@ -913,7 +938,11 @@ void __iterate_supers(void (*f)(struct super_block *, void *), void *arg, bool e
913938
}
914939
if (p)
915940
__put_super(p);
916-
spin_unlock(&sb_lock);
941+
}
942+
943+
void iterate_supers(void (*f)(struct super_block *, void *), void *arg)
944+
{
945+
__iterate_supers(f, arg, 0);
917946
}
918947

919948
/**
@@ -1097,7 +1126,8 @@ static void do_emergency_remount_callback(struct super_block *sb, void *unused)
10971126

10981127
static void do_emergency_remount(struct work_struct *work)
10991128
{
1100-
__iterate_supers(do_emergency_remount_callback, NULL, true);
1129+
__iterate_supers(do_emergency_remount_callback, NULL,
1130+
SUPER_ITER_EXCL | SUPER_ITER_REVERSE);
11011131
kfree(work);
11021132
printk("Emergency Remount complete\n");
11031133
}
@@ -1124,7 +1154,7 @@ static void do_thaw_all_callback(struct super_block *sb, void *unused)
11241154

11251155
static void do_thaw_all(struct work_struct *work)
11261156
{
1127-
__iterate_supers(do_thaw_all_callback, NULL, true);
1157+
__iterate_supers(do_thaw_all_callback, NULL, SUPER_ITER_EXCL);
11281158
kfree(work);
11291159
printk(KERN_WARNING "Emergency Thaw complete\n");
11301160
}

include/linux/fs.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3515,11 +3515,7 @@ extern void put_filesystem(struct file_system_type *fs);
35153515
extern struct file_system_type *get_fs_type(const char *name);
35163516
extern void drop_super(struct super_block *sb);
35173517
extern void drop_super_exclusive(struct super_block *sb);
3518-
void __iterate_supers(void (*f)(struct super_block *, void *), void *arg, bool excl);
3519-
static inline void iterate_supers(void (*f)(struct super_block *, void *), void *arg)
3520-
{
3521-
__iterate_supers(f, arg, false);
3522-
}
3518+
extern void iterate_supers(void (*f)(struct super_block *, void *), void *arg);
35233519
extern void iterate_supers_type(struct file_system_type *,
35243520
void (*)(struct super_block *, void *), void *);
35253521

0 commit comments

Comments
 (0)