nilfs2: simplify life cycle management of nilfs object

This stops pre-allocating nilfs object in nilfs_get_sb routine, and
stops managing its life cycle by reference counting.

nilfs_find_or_create_nilfs() function, nilfs->ns_mount_mutex,
nilfs_objects list, and the reference counter will be removed through
the simplification.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 2e58e7c..5893cb2 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -356,7 +356,7 @@
 		up_write(&nilfs->ns_sem);
 	}
 
-	put_nilfs(sbi->s_nilfs);
+	destroy_nilfs(nilfs);
 	sbi->s_super = NULL;
 	sb->s_fs_info = NULL;
 	kfree(sbi);
@@ -836,15 +836,14 @@
  * @sb: super_block
  * @data: mount options
  * @silent: silent mode flag
- * @nilfs: the_nilfs struct
  *
  * This function is called exclusively by nilfs->ns_mount_mutex.
  * So, the recovery process is protected from other simultaneous mounts.
  */
 static int
-nilfs_fill_super(struct super_block *sb, void *data, int silent,
-		 struct the_nilfs *nilfs)
+nilfs_fill_super(struct super_block *sb, void *data, int silent)
 {
+	struct the_nilfs *nilfs;
 	struct nilfs_sb_info *sbi;
 	struct nilfs_root *fsroot;
 	__u64 cno;
@@ -855,14 +854,18 @@
 		return -ENOMEM;
 
 	sb->s_fs_info = sbi;
-
-	get_nilfs(nilfs);
-	sbi->s_nilfs = nilfs;
 	sbi->s_super = sb;
 
+	nilfs = alloc_nilfs(sb->s_bdev);
+	if (!nilfs) {
+		err = -ENOMEM;
+		goto failed_sbi;
+	}
+	sbi->s_nilfs = nilfs;
+
 	err = init_nilfs(nilfs, sbi, (char *)data);
 	if (err)
-		goto failed_sbi;
+		goto failed_nilfs;
 
 	spin_lock_init(&sbi->s_inode_lock);
 	INIT_LIST_HEAD(&sbi->s_dirty_files);
@@ -885,14 +888,14 @@
 
 	err = load_nilfs(nilfs, sbi);
 	if (err)
-		goto failed_sbi;
+		goto failed_nilfs;
 
 	cno = nilfs_last_cno(nilfs);
 	err = nilfs_attach_checkpoint(sbi, cno, true, &fsroot);
 	if (err) {
 		printk(KERN_ERR "NILFS: error loading last checkpoint "
 		       "(checkpoint number=%llu).\n", (unsigned long long)cno);
-		goto failed_sbi;
+		goto failed_nilfs;
 	}
 
 	if (!(sb->s_flags & MS_RDONLY)) {
@@ -921,8 +924,10 @@
  failed_checkpoint:
 	nilfs_put_root(fsroot);
 
+ failed_nilfs:
+	destroy_nilfs(nilfs);
+
  failed_sbi:
-	put_nilfs(nilfs);
 	sb->s_fs_info = NULL;
 	kfree(sbi);
 	return err;
@@ -1077,7 +1082,6 @@
 	struct nilfs_super_data sd;
 	struct super_block *s;
 	fmode_t mode = FMODE_READ;
-	struct the_nilfs *nilfs;
 	struct dentry *root_dentry;
 	int err, s_new = false;
 
@@ -1095,18 +1099,10 @@
 		goto failed;
 	}
 
-	nilfs = find_or_create_nilfs(sd.bdev);
-	if (!nilfs) {
-		err = -ENOMEM;
-		goto failed;
-	}
-
-	mutex_lock(&nilfs->ns_mount_mutex);
-
 	s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, sd.bdev);
 	if (IS_ERR(s)) {
 		err = PTR_ERR(s);
-		goto failed_unlock;
+		goto failed;
 	}
 
 	if (!s->s_root) {
@@ -1120,10 +1116,9 @@
 		strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id));
 		sb_set_blocksize(s, block_size(sd.bdev));
 
-		err = nilfs_fill_super(s, data, flags & MS_SILENT ? 1 : 0,
-				       nilfs);
+		err = nilfs_fill_super(s, data, flags & MS_SILENT ? 1 : 0);
 		if (err)
-			goto cancel_new;
+			goto failed_super;
 
 		s->s_flags |= MS_ACTIVE;
 	} else if (!sd.cno) {
@@ -1153,17 +1148,12 @@
 
 	if (sd.cno) {
 		err = nilfs_attach_snapshot(s, sd.cno, &root_dentry);
-		if (err) {
-			if (s_new)
-				goto cancel_new;
+		if (err)
 			goto failed_super;
-		}
 	} else {
 		root_dentry = dget(s->s_root);
 	}
 
-	mutex_unlock(&nilfs->ns_mount_mutex);
-	put_nilfs(nilfs);
 	if (!s_new)
 		close_bdev_exclusive(sd.bdev, mode);
 
@@ -1173,23 +1163,10 @@
 
  failed_super:
 	deactivate_locked_super(s);
- failed_unlock:
-	mutex_unlock(&nilfs->ns_mount_mutex);
-	put_nilfs(nilfs);
- failed:
-	close_bdev_exclusive(sd.bdev, mode);
-	return err;
 
- cancel_new:
-	/* Abandoning the newly allocated superblock */
-	mutex_unlock(&nilfs->ns_mount_mutex);
-	put_nilfs(nilfs);
-	deactivate_locked_super(s);
-	/*
-	 * This deactivate_locked_super() invokes close_bdev_exclusive().
-	 * We must finish all post-cleaning before this call;
-	 * put_nilfs() needs the block device.
-	 */
+ failed:
+	if (!s_new)
+		close_bdev_exclusive(sd.bdev, mode);
 	return err;
 }