Message ID | 1313767689-2786-1-git-send-email-tm@tao.ma |
---|---|
State | Accepted, archived |
Headers | show |
On Fri, Aug 19, 2011 at 11:28:08PM +0800, Tao Ma wrote: > From: Tao Ma <boyu.mt@taobao.com> > > In commit 79a77c5ac, we move ext4_mb_init_backend after the allocation > of s_locality_group to avoid memory leak in error path, but there are > still some other error paths in ext4_mb_init that need to do the same > work. So this patch adds all the error patch for ext4_mb_init. And all > the pointers are reset to NULL in case the caller may double free them. > > Signed-off-by: Tao Ma <boyu.mt@taobao.com> but I had to reorder the cleanup code for "out_free_groupinfo_slab" and "out_free_locality_groups" in the following patch hunk.... > @@ -2513,11 +2512,19 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) > > if (sbi->s_journal) > sbi->s_journal->j_commit_callback = release_blocks_on_commit; > + > + return 0; > + > +out_free_groupinfo_slab: > + ext4_groupinfo_destroy_slabs(); > +out_free_locality_groups: > + free_percpu(sbi->s_locality_groups); > + sbi->s_locality_groups = NULL; Since we first allocate the groupinfo slabs, and then the locality groups, so the cleanup paths need to do things in the opposite order. - Ted -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 17a5a57..e7d64d8 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2490,7 +2490,7 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) sbi->s_locality_groups = alloc_percpu(struct ext4_locality_group); if (sbi->s_locality_groups == NULL) { ret = -ENOMEM; - goto out; + goto out_free_groupinfo_slab; } for_each_possible_cpu(i) { struct ext4_locality_group *lg; @@ -2503,9 +2503,8 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) /* init file for buddy data */ ret = ext4_mb_init_backend(sb); - if (ret != 0) { - goto out; - } + if (ret != 0) + goto out_free_locality_groups; if (sbi->s_proc) proc_create_data("mb_groups", S_IRUGO, sbi->s_proc, @@ -2513,11 +2512,19 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) if (sbi->s_journal) sbi->s_journal->j_commit_callback = release_blocks_on_commit; + + return 0; + +out_free_groupinfo_slab: + ext4_groupinfo_destroy_slabs(); +out_free_locality_groups: + free_percpu(sbi->s_locality_groups); + sbi->s_locality_groups = NULL; out: - if (ret) { - kfree(sbi->s_mb_offsets); - kfree(sbi->s_mb_maxs); - } + kfree(sbi->s_mb_offsets); + sbi->s_mb_offsets = NULL; + kfree(sbi->s_mb_maxs); + sbi->s_mb_maxs = NULL; return ret; }