exofs_mount(): fix leaks on failure exits
[ Upstream commit 26cb5a328c6b2bda9e859307ce4cfc60df3a2c28 ] ... and don't abuse mount_nodev(), while we are at it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Reviewed-by: David Howells <dhowells@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
d1dbff485d
commit
bd5acf3e81
1 changed files with 29 additions and 8 deletions
|
@ -705,21 +705,18 @@ out:
|
||||||
/*
|
/*
|
||||||
* Read the superblock from the OSD and fill in the fields
|
* 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 inode *root;
|
||||||
struct exofs_mountopt *opts = data;
|
|
||||||
struct exofs_sb_info *sbi; /*extended info */
|
|
||||||
struct osd_dev *od; /* Master device */
|
struct osd_dev *od; /* Master device */
|
||||||
struct exofs_fscb fscb; /*on-disk superblock info */
|
struct exofs_fscb fscb; /*on-disk superblock info */
|
||||||
struct ore_comp comp;
|
struct ore_comp comp;
|
||||||
unsigned table_count;
|
unsigned table_count;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
|
|
||||||
if (!sbi)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
/* use mount options to fill superblock */
|
/* use mount options to fill superblock */
|
||||||
if (opts->is_osdname) {
|
if (opts->is_osdname) {
|
||||||
struct osd_dev_info odi = {.systemid_len = 0};
|
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,
|
int flags, const char *dev_name,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
|
struct super_block *s;
|
||||||
struct exofs_mountopt opts;
|
struct exofs_mountopt opts;
|
||||||
|
struct exofs_sb_info *sbi;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = parse_options(data, &opts);
|
ret = parse_options(data, &opts);
|
||||||
|
@ -872,9 +871,31 @@ static struct dentry *exofs_mount(struct file_system_type *type,
|
||||||
return ERR_PTR(ret);
|
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)
|
if (!opts.dev_name)
|
||||||
opts.dev_name = 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue