summaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/super.c
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-06-08 01:39:31 +0900
committerAl Viro <viro@zeniv.linux.org.uk>2009-06-11 21:36:18 -0400
commit6dd4740662405a68bb229ac2b9e0aeaaf2188bf2 (patch)
tree36e6ae2a095613be1c36e8828ee9471e60c09de6 /fs/nilfs2/super.c
parent3f82ff55168e92859119bf348e9e0bd6714d2fea (diff)
downloadlinux-6dd4740662405a68bb229ac2b9e0aeaaf2188bf2.tar.gz
linux-6dd4740662405a68bb229ac2b9e0aeaaf2188bf2.tar.bz2
linux-6dd4740662405a68bb229ac2b9e0aeaaf2188bf2.zip
nilfs2: simplify remaining sget() use
This simplifies the test function passed on the remaining sget() callsite in nilfs. Instead of checking mount type (i.e. ro-mount/rw-mount/snapshot mount) in the test function passed to sget(), this patch first looks up the nilfs_sb_info struct which the given mount type matches, and then acquires the super block instance holding the nilfs_sb_info. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/nilfs2/super.c')
-rw-r--r--fs/nilfs2/super.c42
1 files changed, 17 insertions, 25 deletions
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 5a8c5e4731b3..1d1b6e125159 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -336,7 +336,7 @@ static void nilfs_put_super(struct super_block *sb)
put_nilfs(sbi->s_nilfs);
sbi->s_super = NULL;
sb->s_fs_info = NULL;
- kfree(sbi);
+ nilfs_put_sbinfo(sbi);
unlock_kernel();
}
@@ -785,6 +785,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
get_nilfs(nilfs);
sbi->s_nilfs = nilfs;
sbi->s_super = sb;
+ atomic_set(&sbi->s_count, 1);
err = init_nilfs(nilfs, sbi, (char *)data);
if (err)
@@ -902,7 +903,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
failed_sbi:
put_nilfs(nilfs);
sb->s_fs_info = NULL;
- kfree(sbi);
+ nilfs_put_sbinfo(sbi);
return err;
}
@@ -1014,6 +1015,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
struct nilfs_super_data {
struct block_device *bdev;
+ struct nilfs_sb_info *sbi;
__u64 cno;
int flags;
};
@@ -1071,27 +1073,8 @@ static int nilfs_set_bdev_super(struct super_block *s, void *data)
static int nilfs_test_bdev_super(struct super_block *s, void *data)
{
struct nilfs_super_data *sd = data;
- int ret;
-
- if (s->s_bdev != sd->bdev)
- return 0;
-
- if (!((s->s_flags | sd->flags) & MS_RDONLY))
- return 1; /* Reuse an old R/W-mode super_block */
-
- if (s->s_flags & sd->flags & MS_RDONLY) {
- if (down_read_trylock(&s->s_umount)) {
- ret = s->s_root &&
- (sd->cno == NILFS_SB(s)->s_snapshot_cno);
- up_read(&s->s_umount);
- /*
- * This path is locked with sb_lock by sget().
- * So, drop_super() causes deadlock.
- */
- return ret;
- }
- }
- return 0;
+
+ return sd->sbi && s->s_fs_info == (void *)sd->sbi;
}
static int
@@ -1112,7 +1095,6 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
* much more information than normal filesystems to identify mount
* instance. For snapshot mounts, not only a mount type (ro-mount
* or rw-mount) but also a checkpoint number is required.
- * The results are passed in sget() using nilfs_super_data.
*/
sd.cno = 0;
sd.flags = flags;
@@ -1148,13 +1130,23 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
}
/*
- * Search specified snapshot or R/W mode super_block
+ * Find existing nilfs_sb_info struct
*/
+ sd.sbi = nilfs_find_sbinfo(nilfs, !(flags & MS_RDONLY), sd.cno);
+
if (!sd.cno)
/* trying to get the latest checkpoint. */
sd.cno = nilfs_last_cno(nilfs);
+ /*
+ * Get super block instance holding the nilfs_sb_info struct.
+ * A new instance is allocated if no existing mount is present or
+ * existing instance has been unmounted.
+ */
s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, &sd);
+ if (sd.sbi)
+ nilfs_put_sbinfo(sd.sbi);
+
if (IS_ERR(s)) {
err = PTR_ERR(s);
goto failed_unlock;