Commit 2a27b755 authored by Andreas Gruenbacher's avatar Andreas Gruenbacher

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: default avatarAndreas Gruenbacher <agruenba@redhat.com>
parent 4b972a01
...@@ -61,6 +61,13 @@ static void gfs2_tune_init(struct gfs2_tune *gt) ...@@ -61,6 +61,13 @@ static void gfs2_tune_init(struct gfs2_tune *gt)
gt->gt_complain_secs = 10; 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) static struct gfs2_sbd *init_sbd(struct super_block *sb)
{ {
struct gfs2_sbd *sdp; struct gfs2_sbd *sdp;
...@@ -72,10 +79,8 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) ...@@ -72,10 +79,8 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
sdp->sd_vfs = sb; sdp->sd_vfs = sb;
sdp->sd_lkstats = alloc_percpu(struct gfs2_pcpu_lkstats); sdp->sd_lkstats = alloc_percpu(struct gfs2_pcpu_lkstats);
if (!sdp->sd_lkstats) { if (!sdp->sd_lkstats)
kfree(sdp); goto fail;
return NULL;
}
sb->s_fs_info = sdp; sb->s_fs_info = sdp;
set_bit(SDF_NOJOURNALID, &sdp->sd_flags); set_bit(SDF_NOJOURNALID, &sdp->sd_flags);
...@@ -134,8 +139,11 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) ...@@ -134,8 +139,11 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
mutex_init(&sdp->sd_freeze_mutex); mutex_init(&sdp->sd_freeze_mutex);
return sdp; return sdp;
}
fail:
free_sbd(sdp);
return NULL;
}
/** /**
* gfs2_check_sb - Check superblock * gfs2_check_sb - Check superblock
...@@ -1086,8 +1094,7 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent ...@@ -1086,8 +1094,7 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent
if (error) { if (error) {
/* In this case, we haven't initialized sysfs, so we have to /* In this case, we haven't initialized sysfs, so we have to
manually free the sdp. */ manually free the sdp. */
free_percpu(sdp->sd_lkstats); free_sbd(sdp);
kfree(sdp);
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
return error; return error;
} }
...@@ -1190,7 +1197,6 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent ...@@ -1190,7 +1197,6 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent
gfs2_lm_unmount(sdp); gfs2_lm_unmount(sdp);
fail_debug: fail_debug:
gfs2_delete_debugfs_file(sdp); gfs2_delete_debugfs_file(sdp);
free_percpu(sdp->sd_lkstats);
/* gfs2_sys_fs_del must be the last thing we do, since it causes /* gfs2_sys_fs_del must be the last thing we do, since it causes
* sysfs to call function gfs2_sbd_release, which frees sdp. */ * sysfs to call function gfs2_sbd_release, which frees sdp. */
gfs2_sys_fs_del(sdp); gfs2_sys_fs_del(sdp);
...@@ -1370,7 +1376,6 @@ static void gfs2_kill_sb(struct super_block *sb) ...@@ -1370,7 +1376,6 @@ static void gfs2_kill_sb(struct super_block *sb)
sdp->sd_root_dir = NULL; sdp->sd_root_dir = NULL;
sdp->sd_master_dir = NULL; sdp->sd_master_dir = NULL;
shrink_dcache_sb(sb); shrink_dcache_sb(sb);
free_percpu(sdp->sd_lkstats);
kill_block_super(sb); kill_block_super(sb);
} }
......
...@@ -44,6 +44,8 @@ extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, ...@@ -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 int gfs2_statfs_sync(struct super_block *sb, int type);
extern void gfs2_freeze_func(struct work_struct *work); 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 gfs2_fs_type;
extern struct file_system_type gfs2meta_fs_type; extern struct file_system_type gfs2meta_fs_type;
extern const struct export_operations gfs2_export_ops; extern const struct export_operations gfs2_export_ops;
......
...@@ -301,7 +301,7 @@ static void gfs2_sbd_release(struct kobject *kobj) ...@@ -301,7 +301,7 @@ static void gfs2_sbd_release(struct kobject *kobj)
{ {
struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
kfree(sdp); free_sbd(sdp);
} }
static struct kobj_type gfs2_ktype = { static struct kobj_type gfs2_ktype = {
...@@ -679,7 +679,6 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp) ...@@ -679,7 +679,6 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp)
fail_tune: fail_tune:
sysfs_remove_group(&sdp->sd_kobj, &tune_group); sysfs_remove_group(&sdp->sd_kobj, &tune_group);
fail_reg: fail_reg:
free_percpu(sdp->sd_lkstats);
fs_err(sdp, "error %d adding sysfs files\n", error); fs_err(sdp, "error %d adding sysfs files\n", error);
kobject_put(&sdp->sd_kobj); kobject_put(&sdp->sd_kobj);
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment