Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4d3062f authored by Heming Zhao via Ocfs2-devel's avatar Heming Zhao via Ocfs2-devel Committed by Greg Kroah-Hartman
Browse files

ocfs2: rewrite error handling of ocfs2_fill_super

[ Upstream commit f1e75d128b46e3b066e7b2e7cfca10491109d44d ]

Current ocfs2_fill_super() uses one goto label "read_super_error" to
handle all error cases.  And with previous serial patches, the error
handling should fork more branches to handle different error cases.  This
patch rewrite the error handling of ocfs2_fill_super.

Link: https://lkml.kernel.org/r/20220424130952.2436-6-heming.zhao@suse.com


Signed-off-by: default avatarHeming Zhao <heming.zhao@suse.com>
Reviewed-by: default avatarJoseph Qi <joseph.qi@linux.alibaba.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Gang He <ghe@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Mark Fasheh <mark@fasheh.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Stable-dep-of: ce2fcf1516d6 ("ocfs2: fix memory leak in ocfs2_mount_volume()")
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 227cc62e
Loading
Loading
Loading
Loading
+32 −35
Original line number Original line Diff line number Diff line
@@ -984,28 +984,27 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)


	if (!ocfs2_parse_options(sb, data, &parsed_options, 0)) {
	if (!ocfs2_parse_options(sb, data, &parsed_options, 0)) {
		status = -EINVAL;
		status = -EINVAL;
		goto read_super_error;
		goto out;
	}
	}


	/* probe for superblock */
	/* probe for superblock */
	status = ocfs2_sb_probe(sb, &bh, &sector_size, &stats);
	status = ocfs2_sb_probe(sb, &bh, &sector_size, &stats);
	if (status < 0) {
	if (status < 0) {
		mlog(ML_ERROR, "superblock probe failed!\n");
		mlog(ML_ERROR, "superblock probe failed!\n");
		goto read_super_error;
		goto out;
	}
	}


	status = ocfs2_initialize_super(sb, bh, sector_size, &stats);
	status = ocfs2_initialize_super(sb, bh, sector_size, &stats);
	osb = OCFS2_SB(sb);
	if (status < 0) {
		mlog_errno(status);
		goto read_super_error;
	}
	brelse(bh);
	brelse(bh);
	bh = NULL;
	bh = NULL;
	if (status < 0)
		goto out;

	osb = OCFS2_SB(sb);


	if (!ocfs2_check_set_options(sb, &parsed_options)) {
	if (!ocfs2_check_set_options(sb, &parsed_options)) {
		status = -EINVAL;
		status = -EINVAL;
		goto read_super_error;
		goto out_super;
	}
	}
	osb->s_mount_opt = parsed_options.mount_opt;
	osb->s_mount_opt = parsed_options.mount_opt;
	osb->s_atime_quantum = parsed_options.atime_quantum;
	osb->s_atime_quantum = parsed_options.atime_quantum;
@@ -1022,7 +1021,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)


	status = ocfs2_verify_userspace_stack(osb, &parsed_options);
	status = ocfs2_verify_userspace_stack(osb, &parsed_options);
	if (status)
	if (status)
		goto read_super_error;
		goto out_super;


	sb->s_magic = OCFS2_SUPER_MAGIC;
	sb->s_magic = OCFS2_SUPER_MAGIC;


@@ -1036,7 +1035,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
			status = -EACCES;
			status = -EACCES;
			mlog(ML_ERROR, "Readonly device detected but readonly "
			mlog(ML_ERROR, "Readonly device detected but readonly "
			     "mount was not specified.\n");
			     "mount was not specified.\n");
			goto read_super_error;
			goto out_super;
		}
		}


		/* You should not be able to start a local heartbeat
		/* You should not be able to start a local heartbeat
@@ -1045,7 +1044,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
			status = -EROFS;
			status = -EROFS;
			mlog(ML_ERROR, "Local heartbeat specified on readonly "
			mlog(ML_ERROR, "Local heartbeat specified on readonly "
			     "device.\n");
			     "device.\n");
			goto read_super_error;
			goto out_super;
		}
		}


		status = ocfs2_check_journals_nolocks(osb);
		status = ocfs2_check_journals_nolocks(osb);
@@ -1054,9 +1053,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
				mlog(ML_ERROR, "Recovery required on readonly "
				mlog(ML_ERROR, "Recovery required on readonly "
				     "file system, but write access is "
				     "file system, but write access is "
				     "unavailable.\n");
				     "unavailable.\n");
			else
			goto out_super;
				mlog_errno(status);
			goto read_super_error;
		}
		}


		ocfs2_set_ro_flag(osb, 1);
		ocfs2_set_ro_flag(osb, 1);
@@ -1072,10 +1069,8 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
	}
	}


	status = ocfs2_verify_heartbeat(osb);
	status = ocfs2_verify_heartbeat(osb);
	if (status < 0) {
	if (status < 0)
		mlog_errno(status);
		goto out_super;
		goto read_super_error;
	}


	osb->osb_debug_root = debugfs_create_dir(osb->uuid_str,
	osb->osb_debug_root = debugfs_create_dir(osb->uuid_str,
						 ocfs2_debugfs_root);
						 ocfs2_debugfs_root);
@@ -1089,15 +1084,14 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)


	status = ocfs2_mount_volume(sb);
	status = ocfs2_mount_volume(sb);
	if (status < 0)
	if (status < 0)
		goto read_super_error;
		goto out_debugfs;


	if (osb->root_inode)
	if (osb->root_inode)
		inode = igrab(osb->root_inode);
		inode = igrab(osb->root_inode);


	if (!inode) {
	if (!inode) {
		status = -EIO;
		status = -EIO;
		mlog_errno(status);
		goto out_dismount;
		goto read_super_error;
	}
	}


	osb->osb_dev_kset = kset_create_and_add(sb->s_id, NULL,
	osb->osb_dev_kset = kset_create_and_add(sb->s_id, NULL,
@@ -1105,7 +1099,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
	if (!osb->osb_dev_kset) {
	if (!osb->osb_dev_kset) {
		status = -ENOMEM;
		status = -ENOMEM;
		mlog(ML_ERROR, "Unable to create device kset %s.\n", sb->s_id);
		mlog(ML_ERROR, "Unable to create device kset %s.\n", sb->s_id);
		goto read_super_error;
		goto out_dismount;
	}
	}


	/* Create filecheck sysfs related directories/files at
	/* Create filecheck sysfs related directories/files at
@@ -1114,14 +1108,13 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
		status = -ENOMEM;
		status = -ENOMEM;
		mlog(ML_ERROR, "Unable to create filecheck sysfs directory at "
		mlog(ML_ERROR, "Unable to create filecheck sysfs directory at "
			"/sys/fs/ocfs2/%s/filecheck.\n", sb->s_id);
			"/sys/fs/ocfs2/%s/filecheck.\n", sb->s_id);
		goto read_super_error;
		goto out_dismount;
	}
	}


	root = d_make_root(inode);
	root = d_make_root(inode);
	if (!root) {
	if (!root) {
		status = -ENOMEM;
		status = -ENOMEM;
		mlog_errno(status);
		goto out_dismount;
		goto read_super_error;
	}
	}


	sb->s_root = root;
	sb->s_root = root;
@@ -1168,17 +1161,21 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)


	return status;
	return status;


read_super_error:
out_dismount:
	brelse(bh);

	if (status)
		mlog_errno(status);

	if (osb) {
	atomic_set(&osb->vol_state, VOLUME_DISABLED);
	atomic_set(&osb->vol_state, VOLUME_DISABLED);
	wake_up(&osb->osb_mount_event);
	wake_up(&osb->osb_mount_event);
	ocfs2_dismount_volume(sb, 1);
	ocfs2_dismount_volume(sb, 1);
	}
	goto out;

out_debugfs:
	debugfs_remove_recursive(osb->osb_debug_root);
out_super:
	ocfs2_release_system_inodes(osb);
	kfree(osb->recovery_map);
	ocfs2_delete_osb(osb);
	kfree(osb);
out:
	mlog_errno(status);


	return status;
	return status;
}
}