From f16fe77386e1dfeb0c9461fb0f67626f1ee718d8 Mon Sep 17 00:00:00 2001 From: Alexander Viro Date: Mon, 11 Mar 2002 20:54:20 -0800 Subject: [PATCH] [PATCH] (2/2) fs/super.c cleanups kill_super() and deactivate_super() merged. Next step will be to export these suckers - after that we will be finally done with infrastructure for filesystems with nontrivial ->get_sb(). --- fs/namespace.c | 3 +- fs/super.c | 72 +++++++++++++++++++++------------------------- include/linux/fs.h | 1 + kernel/ksyms.c | 1 + 4 files changed, 35 insertions(+), 42 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index aa6cb6b8f358..1225bac1bafa 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -23,7 +23,6 @@ struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data); int do_remount_sb(struct super_block *sb, int flags, void * data); -void kill_super(struct super_block *sb); int __init init_rootfs(void); static struct list_head *mount_hashtable; @@ -152,7 +151,7 @@ void __mntput(struct vfsmount *mnt) struct super_block *sb = mnt->mnt_sb; dput(mnt->mnt_root); free_vfsmnt(mnt); - kill_super(sb); + deactivate_super(sb); } /* iterator */ diff --git a/fs/super.c b/fs/super.c index dc1ced9f665b..66a6274d1b71 100644 --- a/fs/super.c +++ b/fs/super.c @@ -296,22 +296,6 @@ static inline void destroy_super(struct super_block *s) /* Superblock refcounting */ -/** - * deactivate_super - turn an active reference into temporary - * @s: superblock to deactivate - * - * Turns an active reference into temporary one. Returns 0 if there are - * other active references, 1 if we had deactivated the last one. - */ -static inline int deactivate_super(struct super_block *s) -{ - if (!atomic_dec_and_lock(&s->s_active, &sb_lock)) - return 0; - s->s_count -= S_BIAS-1; - spin_unlock(&sb_lock); - return 1; -} - /** * put_super - drop a temporary reference to superblock * @s: superblock in question @@ -327,6 +311,28 @@ static inline void put_super(struct super_block *s) spin_unlock(&sb_lock); } +/** + * deactivate_super - drop an active reference to superblock + * @s: superblock to deactivate + * + * Drops an active reference to superblock, acquiring a temprory one if + * there is no active references left. In that case we lock superblock, + * tell fs driver to shut it down and drop the temporary reference we + * had just acquired. + */ +void deactivate_super(struct super_block *s) +{ + struct file_system_type *fs = s->s_type; + if (atomic_dec_and_lock(&s->s_active, &sb_lock)) { + s->s_count -= S_BIAS-1; + spin_unlock(&sb_lock); + down_write(&s->s_umount); + fs->kill_sb(s); + put_filesystem(fs); + put_super(s); + } +} + /** * grab_super - acquire an active reference * @s - reference we are trying to make active @@ -380,13 +386,12 @@ static void insert_super(struct super_block *s, struct file_system_type *type) * remove_super - makes superblock unreachable * @s: superblock in question * - * Removes superblock from the lists, unlocks it and drop the reference - * @s should have no active references by that time and after - * remove_super() it's essentially in rundown mode - all remaining - * references are temporary, no new reference of any sort are going - * to appear and all holders of temporary ones will eventually drop them. - * At that point superblock itself will be destroyed; all its contents - * is already gone. + * Removes superblock from the lists, and unlocks it. @s should have + * no active references by that time and after remove_super() it's + * essentially in rundown mode - all remaining references are temporary, + * no new references of any sort are going to appear and all holders + * of temporary ones will eventually drop them. At that point superblock + * itself will be destroyed; all its contents is already gone. */ static void remove_super(struct super_block *s) { @@ -395,7 +400,6 @@ static void remove_super(struct super_block *s) list_del(&s->s_instances); spin_unlock(&sb_lock); up_write(&s->s_umount); - put_super(s); } static void generic_shutdown_super(struct super_block *sb) @@ -432,18 +436,6 @@ static void generic_shutdown_super(struct super_block *sb) remove_super(sb); } -void kill_super(struct super_block *sb) -{ - struct file_system_type *fs = sb->s_type; - - if (!deactivate_super(sb)) - return; - - down_write(&sb->s_umount); - fs->kill_sb(sb); - put_filesystem(fs); -} - struct super_block *sget(struct file_system_type *type, int (*test)(struct super_block *,void *), int (*set)(struct super_block *,void *), @@ -732,7 +724,7 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type, if (s->s_root) { if ((flags ^ s->s_flags) & MS_RDONLY) { up_write(&s->s_umount); - kill_super(s); + deactivate_super(s); s = ERR_PTR(-EBUSY); } bd_release(bdev); @@ -743,7 +735,7 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type, error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); if (error) { up_write(&s->s_umount); - kill_super(s); + deactivate_super(s); s = ERR_PTR(error); } else s->s_flags |= MS_ACTIVE; @@ -781,7 +773,7 @@ struct super_block *get_sb_nodev(struct file_system_type *fs_type, error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); if (error) { up_write(&s->s_umount); - kill_super(s); + deactivate_super(s); return ERR_PTR(error); } s->s_flags |= MS_ACTIVE; @@ -807,7 +799,7 @@ struct super_block *get_sb_single(struct file_system_type *fs_type, error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); if (error) { up_write(&s->s_umount); - kill_super(s); + deactivate_super(s); return ERR_PTR(error); } s->s_flags |= MS_ACTIVE; diff --git a/include/linux/fs.h b/include/linux/fs.h index 6ff5a4b41490..d4041b23a55c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -959,6 +959,7 @@ struct super_block *get_sb_nodev(struct file_system_type *fs_type, void kill_block_super(struct super_block *sb); void kill_anon_super(struct super_block *sb); void kill_litter_super(struct super_block *sb); +void deactivate_super(struct super_block *sb); /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ #define fops_get(fops) \ diff --git a/kernel/ksyms.c b/kernel/ksyms.c index fef69bf4e32d..2b6993b9c66c 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -291,6 +291,7 @@ EXPORT_SYMBOL(get_sb_nodev); EXPORT_SYMBOL(get_sb_single); EXPORT_SYMBOL(kill_anon_super); EXPORT_SYMBOL(kill_litter_super); +EXPORT_SYMBOL(deactivate_super); /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ EXPORT_SYMBOL(default_llseek); -- 2.39.5