diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2019-05-16 17:46:30 -0400 |
---|---|---|
committer | Andreas Gruenbacher <agruenba@redhat.com> | 2019-06-27 14:53:45 -0400 |
commit | 2a27b755ed244527df845f07f4dd83988a90f2e4 (patch) | |
tree | 514a0b34f5509029336314c82f6be5ad07f7ee35 | |
parent | 4b972a01a7da614b4796475f933094751a295a2f (diff) |
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>
-rw-r--r-- | fs/gfs2/ops_fstype.c | 23 | ||||
-rw-r--r-- | fs/gfs2/super.h | 2 | ||||
-rw-r--r-- | 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 08823bb3b2d0..8d614f599065 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) | |||
61 | gt->gt_complain_secs = 10; | 61 | gt->gt_complain_secs = 10; |
62 | } | 62 | } |
63 | 63 | ||
64 | void free_sbd(struct gfs2_sbd *sdp) | ||
65 | { | ||
66 | if (sdp->sd_lkstats) | ||
67 | free_percpu(sdp->sd_lkstats); | ||
68 | kfree(sdp); | ||
69 | } | ||
70 | |||
64 | static struct gfs2_sbd *init_sbd(struct super_block *sb) | 71 | static struct gfs2_sbd *init_sbd(struct super_block *sb) |
65 | { | 72 | { |
66 | struct gfs2_sbd *sdp; | 73 | struct gfs2_sbd *sdp; |
@@ -72,10 +79,8 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
72 | 79 | ||
73 | sdp->sd_vfs = sb; | 80 | sdp->sd_vfs = sb; |
74 | sdp->sd_lkstats = alloc_percpu(struct gfs2_pcpu_lkstats); | 81 | sdp->sd_lkstats = alloc_percpu(struct gfs2_pcpu_lkstats); |
75 | if (!sdp->sd_lkstats) { | 82 | if (!sdp->sd_lkstats) |
76 | kfree(sdp); | 83 | goto fail; |
77 | return NULL; | ||
78 | } | ||
79 | sb->s_fs_info = sdp; | 84 | sb->s_fs_info = sdp; |
80 | 85 | ||
81 | set_bit(SDF_NOJOURNALID, &sdp->sd_flags); | 86 | set_bit(SDF_NOJOURNALID, &sdp->sd_flags); |
@@ -134,8 +139,11 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
134 | mutex_init(&sdp->sd_freeze_mutex); | 139 | mutex_init(&sdp->sd_freeze_mutex); |
135 | 140 | ||
136 | return sdp; | 141 | return sdp; |
137 | } | ||
138 | 142 | ||
143 | fail: | ||
144 | free_sbd(sdp); | ||
145 | return NULL; | ||
146 | } | ||
139 | 147 | ||
140 | /** | 148 | /** |
141 | * gfs2_check_sb - Check superblock | 149 | * gfs2_check_sb - Check superblock |
@@ -1086,8 +1094,7 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent | |||
1086 | if (error) { | 1094 | if (error) { |
1087 | /* In this case, we haven't initialized sysfs, so we have to | 1095 | /* In this case, we haven't initialized sysfs, so we have to |
1088 | manually free the sdp. */ | 1096 | manually free the sdp. */ |
1089 | free_percpu(sdp->sd_lkstats); | 1097 | free_sbd(sdp); |
1090 | kfree(sdp); | ||
1091 | sb->s_fs_info = NULL; | 1098 | sb->s_fs_info = NULL; |
1092 | return error; | 1099 | return error; |
1093 | } | 1100 | } |
@@ -1190,7 +1197,6 @@ fail_lm: | |||
1190 | gfs2_lm_unmount(sdp); | 1197 | gfs2_lm_unmount(sdp); |
1191 | fail_debug: | 1198 | fail_debug: |
1192 | gfs2_delete_debugfs_file(sdp); | 1199 | gfs2_delete_debugfs_file(sdp); |
1193 | free_percpu(sdp->sd_lkstats); | ||
1194 | /* gfs2_sys_fs_del must be the last thing we do, since it causes | 1200 | /* gfs2_sys_fs_del must be the last thing we do, since it causes |
1195 | * sysfs to call function gfs2_sbd_release, which frees sdp. */ | 1201 | * sysfs to call function gfs2_sbd_release, which frees sdp. */ |
1196 | gfs2_sys_fs_del(sdp); | 1202 | gfs2_sys_fs_del(sdp); |
@@ -1370,7 +1376,6 @@ static void gfs2_kill_sb(struct super_block *sb) | |||
1370 | sdp->sd_root_dir = NULL; | 1376 | sdp->sd_root_dir = NULL; |
1371 | sdp->sd_master_dir = NULL; | 1377 | sdp->sd_master_dir = NULL; |
1372 | shrink_dcache_sb(sb); | 1378 | shrink_dcache_sb(sb); |
1373 | free_percpu(sdp->sd_lkstats); | ||
1374 | kill_block_super(sb); | 1379 | kill_block_super(sb); |
1375 | } | 1380 | } |
1376 | 1381 | ||
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index c5f42f0c503b..9d49eaadb9d9 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, | |||
44 | extern int gfs2_statfs_sync(struct super_block *sb, int type); | 44 | extern int gfs2_statfs_sync(struct super_block *sb, int type); |
45 | extern void gfs2_freeze_func(struct work_struct *work); | 45 | extern void gfs2_freeze_func(struct work_struct *work); |
46 | 46 | ||
47 | extern void free_sbd(struct gfs2_sbd *sdp); | ||
48 | |||
47 | extern struct file_system_type gfs2_fs_type; | 49 | extern struct file_system_type gfs2_fs_type; |
48 | extern struct file_system_type gfs2meta_fs_type; | 50 | extern struct file_system_type gfs2meta_fs_type; |
49 | extern const struct export_operations gfs2_export_ops; | 51 | extern const struct export_operations gfs2_export_ops; |
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 159aedf63c2a..325612ce1c6b 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -301,7 +301,7 @@ static void gfs2_sbd_release(struct kobject *kobj) | |||
301 | { | 301 | { |
302 | struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); | 302 | struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); |
303 | 303 | ||
304 | kfree(sdp); | 304 | free_sbd(sdp); |
305 | } | 305 | } |
306 | 306 | ||
307 | static struct kobj_type gfs2_ktype = { | 307 | static struct kobj_type gfs2_ktype = { |
@@ -679,7 +679,6 @@ fail_lock_module: | |||
679 | fail_tune: | 679 | fail_tune: |
680 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); | 680 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); |
681 | fail_reg: | 681 | fail_reg: |
682 | free_percpu(sdp->sd_lkstats); | ||
683 | fs_err(sdp, "error %d adding sysfs files\n", error); | 682 | fs_err(sdp, "error %d adding sysfs files\n", error); |
684 | kobject_put(&sdp->sd_kobj); | 683 | kobject_put(&sdp->sd_kobj); |
685 | sb->s_fs_info = NULL; | 684 | sb->s_fs_info = NULL; |