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 <agruenba@redhat.com>
This commit is contained in:
parent
4b972a01a7
commit
2a27b755ed
@ -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)
|
|||||||
|
|
||||||
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)
|
|||||||
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
|
|||||||
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 @@ fail_lm:
|
|||||||
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)
|
|||||||
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,
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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 @@ fail_lock_module:
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user