From 2a27b755ed244527df845f07f4dd83988a90f2e4 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Thu, 16 May 2019 22:46:30 +0100 Subject: [PATCH] gfs2: Clean up freeing struct gfs2_sbd Add a free_sbd function for freeing a struct gfs2_sbd. Use that for freeing a super-block descriptor, either directly or via kobject_put. Free sd_lkstats inside the kobject release function: that way, gfs2_put_super will no longer leak sd_lkstats. Signed-off-by: Andreas Gruenbacher --- fs/gfs2/ops_fstype.c | 23 ++++++++++++++--------- fs/gfs2/super.h | 2 ++ fs/gfs2/sys.c | 3 +-- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 08823bb..8d614f5 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -61,6 +61,13 @@ static void gfs2_tune_init(struct gfs2_tune *gt) gt->gt_complain_secs = 10; } +void free_sbd(struct gfs2_sbd *sdp) +{ + if (sdp->sd_lkstats) + free_percpu(sdp->sd_lkstats); + kfree(sdp); +} + static struct gfs2_sbd *init_sbd(struct super_block *sb) { struct gfs2_sbd *sdp; @@ -72,10 +79,8 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) sdp->sd_vfs = sb; sdp->sd_lkstats = alloc_percpu(struct gfs2_pcpu_lkstats); - if (!sdp->sd_lkstats) { - kfree(sdp); - return NULL; - } + if (!sdp->sd_lkstats) + goto fail; sb->s_fs_info = sdp; set_bit(SDF_NOJOURNALID, &sdp->sd_flags); @@ -134,8 +139,11 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) mutex_init(&sdp->sd_freeze_mutex); return sdp; -} +fail: + free_sbd(sdp); + return NULL; +} /** * gfs2_check_sb - Check superblock @@ -1086,8 +1094,7 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent if (error) { /* In this case, we haven't initialized sysfs, so we have to manually free the sdp. */ - free_percpu(sdp->sd_lkstats); - kfree(sdp); + free_sbd(sdp); sb->s_fs_info = NULL; return error; } @@ -1190,7 +1197,6 @@ fail_lm: gfs2_lm_unmount(sdp); fail_debug: gfs2_delete_debugfs_file(sdp); - free_percpu(sdp->sd_lkstats); /* gfs2_sys_fs_del must be the last thing we do, since it causes * sysfs to call function gfs2_sbd_release, which frees sdp. */ gfs2_sys_fs_del(sdp); @@ -1370,7 +1376,6 @@ static void gfs2_kill_sb(struct super_block *sb) sdp->sd_root_dir = NULL; sdp->sd_master_dir = NULL; shrink_dcache_sb(sb); - free_percpu(sdp->sd_lkstats); kill_block_super(sb); } diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index c5f42f0..9d49eaa 100644 --- a/fs/gfs2/super.h +++ b/fs/gfs2/super.h @@ -44,6 +44,8 @@ extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, extern int gfs2_statfs_sync(struct super_block *sb, int type); extern void gfs2_freeze_func(struct work_struct *work); +extern void free_sbd(struct gfs2_sbd *sdp); + extern struct file_system_type gfs2_fs_type; extern struct file_system_type gfs2meta_fs_type; extern const struct export_operations gfs2_export_ops; diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 159aedf..325612c 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -301,7 +301,7 @@ static void gfs2_sbd_release(struct kobject *kobj) { struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); - kfree(sdp); + free_sbd(sdp); } static struct kobj_type gfs2_ktype = { @@ -679,7 +679,6 @@ fail_lock_module: fail_tune: sysfs_remove_group(&sdp->sd_kobj, &tune_group); fail_reg: - free_percpu(sdp->sd_lkstats); fs_err(sdp, "error %d adding sysfs files\n", error); kobject_put(&sdp->sd_kobj); sb->s_fs_info = NULL; -- 2.7.4