Commit f16fe773 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[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().
parent 09162fbb
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data); 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); int do_remount_sb(struct super_block *sb, int flags, void * data);
void kill_super(struct super_block *sb);
int __init init_rootfs(void); int __init init_rootfs(void);
static struct list_head *mount_hashtable; static struct list_head *mount_hashtable;
...@@ -152,7 +151,7 @@ void __mntput(struct vfsmount *mnt) ...@@ -152,7 +151,7 @@ void __mntput(struct vfsmount *mnt)
struct super_block *sb = mnt->mnt_sb; struct super_block *sb = mnt->mnt_sb;
dput(mnt->mnt_root); dput(mnt->mnt_root);
free_vfsmnt(mnt); free_vfsmnt(mnt);
kill_super(sb); deactivate_super(sb);
} }
/* iterator */ /* iterator */
......
...@@ -296,22 +296,6 @@ static inline void destroy_super(struct super_block *s) ...@@ -296,22 +296,6 @@ static inline void destroy_super(struct super_block *s)
/* Superblock refcounting */ /* 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 * put_super - drop a temporary reference to superblock
* @s: superblock in question * @s: superblock in question
...@@ -327,6 +311,28 @@ static inline void put_super(struct super_block *s) ...@@ -327,6 +311,28 @@ static inline void put_super(struct super_block *s)
spin_unlock(&sb_lock); 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 * grab_super - acquire an active reference
* @s - reference we are trying to make active * @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) ...@@ -380,13 +386,12 @@ static void insert_super(struct super_block *s, struct file_system_type *type)
* remove_super - makes superblock unreachable * remove_super - makes superblock unreachable
* @s: superblock in question * @s: superblock in question
* *
* Removes superblock from the lists, unlocks it and drop the reference * Removes superblock from the lists, and unlocks it. @s should have
* @s should have no active references by that time and after * no active references by that time and after remove_super() it's
* remove_super() it's essentially in rundown mode - all remaining * essentially in rundown mode - all remaining references are temporary,
* references are temporary, no new reference of any sort are going * no new references of any sort are going to appear and all holders
* to appear and all holders of temporary ones will eventually drop them. * of temporary ones will eventually drop them. At that point superblock
* At that point superblock itself will be destroyed; all its contents * itself will be destroyed; all its contents is already gone.
* is already gone.
*/ */
static void remove_super(struct super_block *s) static void remove_super(struct super_block *s)
{ {
...@@ -395,7 +400,6 @@ 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); list_del(&s->s_instances);
spin_unlock(&sb_lock); spin_unlock(&sb_lock);
up_write(&s->s_umount); up_write(&s->s_umount);
put_super(s);
} }
static void generic_shutdown_super(struct super_block *sb) static void generic_shutdown_super(struct super_block *sb)
...@@ -432,18 +436,6 @@ 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); 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, struct super_block *sget(struct file_system_type *type,
int (*test)(struct super_block *,void *), int (*test)(struct super_block *,void *),
int (*set)(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, ...@@ -732,7 +724,7 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
if (s->s_root) { if (s->s_root) {
if ((flags ^ s->s_flags) & MS_RDONLY) { if ((flags ^ s->s_flags) & MS_RDONLY) {
up_write(&s->s_umount); up_write(&s->s_umount);
kill_super(s); deactivate_super(s);
s = ERR_PTR(-EBUSY); s = ERR_PTR(-EBUSY);
} }
bd_release(bdev); bd_release(bdev);
...@@ -743,7 +735,7 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type, ...@@ -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); error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
if (error) { if (error) {
up_write(&s->s_umount); up_write(&s->s_umount);
kill_super(s); deactivate_super(s);
s = ERR_PTR(error); s = ERR_PTR(error);
} else } else
s->s_flags |= MS_ACTIVE; s->s_flags |= MS_ACTIVE;
...@@ -781,7 +773,7 @@ struct super_block *get_sb_nodev(struct file_system_type *fs_type, ...@@ -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); error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
if (error) { if (error) {
up_write(&s->s_umount); up_write(&s->s_umount);
kill_super(s); deactivate_super(s);
return ERR_PTR(error); return ERR_PTR(error);
} }
s->s_flags |= MS_ACTIVE; s->s_flags |= MS_ACTIVE;
...@@ -807,7 +799,7 @@ struct super_block *get_sb_single(struct file_system_type *fs_type, ...@@ -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); error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
if (error) { if (error) {
up_write(&s->s_umount); up_write(&s->s_umount);
kill_super(s); deactivate_super(s);
return ERR_PTR(error); return ERR_PTR(error);
} }
s->s_flags |= MS_ACTIVE; s->s_flags |= MS_ACTIVE;
......
...@@ -959,6 +959,7 @@ struct super_block *get_sb_nodev(struct file_system_type *fs_type, ...@@ -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_block_super(struct super_block *sb);
void kill_anon_super(struct super_block *sb); void kill_anon_super(struct super_block *sb);
void kill_litter_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 */ /* Alas, no aliases. Too much hassle with bringing module.h everywhere */
#define fops_get(fops) \ #define fops_get(fops) \
......
...@@ -291,6 +291,7 @@ EXPORT_SYMBOL(get_sb_nodev); ...@@ -291,6 +291,7 @@ EXPORT_SYMBOL(get_sb_nodev);
EXPORT_SYMBOL(get_sb_single); EXPORT_SYMBOL(get_sb_single);
EXPORT_SYMBOL(kill_anon_super); EXPORT_SYMBOL(kill_anon_super);
EXPORT_SYMBOL(kill_litter_super); EXPORT_SYMBOL(kill_litter_super);
EXPORT_SYMBOL(deactivate_super);
/* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
EXPORT_SYMBOL(default_llseek); EXPORT_SYMBOL(default_llseek);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment