nilfs2: get rid of sget use for acquiring nilfs object

This will change the way to obtain nilfs object in nilfs_get_sb()
function.

Previously, a preliminary sget() call was performed, and the nilfs
object was acquired from a super block instance found by the sget()
call.

This patch, instead, instroduces a new dedicated function
find_or_create_nilfs(); as the name implies, the function finds an
existent nilfs object from a global list or creates a new one if no
object is found on the device.

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>
This commit is contained in:
Ryusuke Konishi
2009-06-08 01:39:29 +09:00
committed by Al Viro
parent 81fc20bd0e
commit 33c8e57c86
3 changed files with 76 additions and 65 deletions

View File

@@ -1059,13 +1059,6 @@ 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;
return s->s_bdev == sd->bdev;
}
static int nilfs_test_bdev_super2(struct super_block *s, void *data)
{
struct nilfs_super_data *sd = data;
int ret;
@@ -1096,8 +1089,8 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data, struct vfsmount *mnt)
{
struct nilfs_super_data sd;
struct super_block *s, *s2;
struct the_nilfs *nilfs = NULL;
struct super_block *s;
struct the_nilfs *nilfs;
int err, need_to_close = 1;
sd.bdev = open_bdev_exclusive(dev_name, flags, fs_type);
@@ -1118,11 +1111,12 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
goto failed;
}
/*
* once the super is inserted into the list by sget, s_umount
* will protect the lockfs code from trying to start a snapshot
* while we are mounting
*/
nilfs = find_or_create_nilfs(sd.bdev);
if (!nilfs) {
err = -ENOMEM;
goto failed;
}
down(&sd.bdev->bd_mount_sem);
if (!sd.cno &&
(err = test_exclusive_mount(fs_type, sd.bdev, flags ^ MS_RDONLY))) {
@@ -1131,51 +1125,22 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
}
/*
* Phase-1: search any existent instance and get the_nilfs
* Search specified snapshot or R/W mode super_block
*/
if (!sd.cno)
/* trying to get the latest checkpoint. */
sd.cno = nilfs_last_cno(nilfs);
s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, &sd);
if (IS_ERR(s))
goto error_s;
if (!s->s_root) {
err = -ENOMEM;
nilfs = alloc_nilfs(sd.bdev);
if (!nilfs)
goto cancel_new;
} else {
struct nilfs_sb_info *sbi = NILFS_SB(s);
/*
* s_umount protects super_block from unmount process;
* It covers pointers of nilfs_sb_info and the_nilfs.
*/
nilfs = sbi->s_nilfs;
get_nilfs(nilfs);
up_write(&s->s_umount);
/*
* Phase-2: search specified snapshot or R/W mode super_block
*/
if (!sd.cno)
/* trying to get the latest checkpoint. */
sd.cno = nilfs_last_cno(nilfs);
s2 = sget(fs_type, nilfs_test_bdev_super2,
nilfs_set_bdev_super, &sd);
deactivate_super(s);
/*
* Although deactivate_super() invokes close_bdev_exclusive() at
* kill_block_super(). Here, s is an existent mount; we need
* one more close_bdev_exclusive() call.
*/
s = s2;
if (IS_ERR(s))
goto error_s;
if (IS_ERR(s)) {
err = PTR_ERR(s);
goto failed_unlock;
}
if (!s->s_root) {
char b[BDEVNAME_SIZE];
/* New superblock instance created */
s->s_flags = flags;
strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id));
sb_set_blocksize(s, block_size(sd.bdev));
@@ -1195,15 +1160,9 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
simple_set_mnt(mnt, s);
return 0;
error_s:
up(&sd.bdev->bd_mount_sem);
if (nilfs)
put_nilfs(nilfs);
close_bdev_exclusive(sd.bdev, flags);
return PTR_ERR(s);
failed_unlock:
up(&sd.bdev->bd_mount_sem);
put_nilfs(nilfs);
failed:
close_bdev_exclusive(sd.bdev, flags);
@@ -1212,8 +1171,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
cancel_new:
/* Abandoning the newly allocated superblock */
up(&sd.bdev->bd_mount_sem);
if (nilfs)
put_nilfs(nilfs);
put_nilfs(nilfs);
up_write(&s->s_umount);
deactivate_super(s);
/*