Commit 26cb5a32 authored by Al Viro's avatar Al Viro
Browse files

exofs_mount(): fix leaks on failure exits



... and don't abuse mount_nodev(), while we are at it.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Reviewed-by: default avatarDavid Howells <dhowells@redhat.com>
parent 65102238
Loading
Loading
Loading
Loading
+29 −8
Original line number Diff line number Diff line
@@ -705,21 +705,18 @@ out:
/*
 * Read the superblock from the OSD and fill in the fields
 */
static int exofs_fill_super(struct super_block *sb, void *data, int silent)
static int exofs_fill_super(struct super_block *sb,
				struct exofs_mountopt *opts,
				struct exofs_sb_info *sbi,
				int silent)
{
	struct inode *root;
	struct exofs_mountopt *opts = data;
	struct exofs_sb_info *sbi;	/*extended info                  */
	struct osd_dev *od;		/* Master device                 */
	struct exofs_fscb fscb;		/*on-disk superblock info        */
	struct ore_comp comp;
	unsigned table_count;
	int ret;

	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
	if (!sbi)
		return -ENOMEM;

	/* use mount options to fill superblock */
	if (opts->is_osdname) {
		struct osd_dev_info odi = {.systemid_len = 0};
@@ -863,7 +860,9 @@ static struct dentry *exofs_mount(struct file_system_type *type,
			  int flags, const char *dev_name,
			  void *data)
{
	struct super_block *s;
	struct exofs_mountopt opts;
	struct exofs_sb_info *sbi;
	int ret;

	ret = parse_options(data, &opts);
@@ -872,9 +871,31 @@ static struct dentry *exofs_mount(struct file_system_type *type,
		return ERR_PTR(ret);
	}

	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
	if (!sbi) {
		kfree(opts.dev_name);
		return ERR_PTR(-ENOMEM);
	}

	s = sget(type, NULL, set_anon_super, flags, NULL);

	if (IS_ERR(s)) {
		kfree(opts.dev_name);
		kfree(sbi);
		return ERR_CAST(s);
	}

	if (!opts.dev_name)
		opts.dev_name = dev_name;
	return mount_nodev(type, flags, &opts, exofs_fill_super);


	ret = exofs_fill_super(s, &opts, sbi, flags & SB_SILENT ? 1 : 0);
	if (ret) {
		deactivate_locked_super(s);
		return ERR_PTR(ret);
	}
	s->s_flags |= SB_ACTIVE;
	return dget(s->s_root);
}

/*