diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2018-11-09 22:26:42 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-12-05 09:20:32 +0100 |
commit | bd5acf3e81ec539c10d0bf116b43297de6a43338 (patch) | |
tree | 9e922df07094d86dac4a023b4b6a99bf34271df5 | |
parent | d1dbff485dc86b1e0e87c96ee032de98a2bbf2b5 (diff) | |
download | linux-stable-bd5acf3e81ec539c10d0bf116b43297de6a43338.tar.gz linux-stable-bd5acf3e81ec539c10d0bf116b43297de6a43338.tar.bz2 linux-stable-bd5acf3e81ec539c10d0bf116b43297de6a43338.zip |
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>
-rw-r--r-- | fs/exofs/super.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 7d61e3fa378c..8fb98bb94237 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c @@ -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); } /* |