diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-04-23 04:02:05 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-04-23 04:02:05 -0300 |
commit | 394569928e2f17dff4ae367ac700048138e318c7 (patch) | |
tree | c789d2a2d107284e78f6c6558267b6984f518581 /fs/super.c | |
parent | bdcfd44fb5b5fb8fd660e7f93f1095c507481024 (diff) |
Linux-libre 4.5.2-gnupck-4.5.2-gnu
Diffstat (limited to 'fs/super.c')
-rw-r--r-- | fs/super.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/fs/super.c b/fs/super.c index ad57841f7..3446dc4fb 100644 --- a/fs/super.c +++ b/fs/super.c @@ -1372,3 +1372,50 @@ out: return 0; } EXPORT_SYMBOL(thaw_super); + +/** + * lock_supers -- Stop other processes from modifying the list of super blocks. + */ +void take_super_lock() { + spin_lock(&sb_lock); +} + +/** + * unlock_supers -- Allow other processes to again modify the list of super blocks. + */ +void release_super_lock() { + spin_unlock(&sb_lock); +} + +/** + * iterate_supers_no_sb_lock - call function for all active superblocks without using sb_lock + * + * Note that the callback must work with sb_lock taken and not unlock it. + * + * @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_no_sb_lock(void (*f)(struct super_block *, void *), void *arg) +{ + struct super_block *sb, *p = NULL; + + list_for_each_entry(sb, &super_blocks, s_list) { + if (hlist_unhashed(&sb->s_instances)) + continue; + sb->s_count++; + + down_read(&sb->s_umount); + if (sb->s_root && (sb->s_flags & MS_BORN)) + f(sb, arg); + up_read(&sb->s_umount); + + if (p) + __put_super(p); + p = sb; + } + if (p) + __put_super(p); +} |