diff options
author | Tao Ma <boyu.mt@taobao.com> | 2011-10-06 10:22:28 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2011-10-06 10:22:28 -0400 |
commit | 7aa0baeaba4afc4fbed7aad2812a1116e6b0adcd (patch) | |
tree | a7237b599107d0adf137c465734d4b67ad83d6dd /fs/ext4/mballoc.c | |
parent | 5356f2615cd558c57a1f7d7528d1ad4de3640d96 (diff) |
ext4: Free resources in ext4_mb_init()'s error paths
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>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/mballoc.c')
-rw-r--r-- | fs/ext4/mballoc.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 1c83161090f8..8c005c028203 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -2504,7 +2504,7 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) | |||
2504 | sbi->s_locality_groups = alloc_percpu(struct ext4_locality_group); | 2504 | sbi->s_locality_groups = alloc_percpu(struct ext4_locality_group); |
2505 | if (sbi->s_locality_groups == NULL) { | 2505 | if (sbi->s_locality_groups == NULL) { |
2506 | ret = -ENOMEM; | 2506 | ret = -ENOMEM; |
2507 | goto out; | 2507 | goto out_free_groupinfo_slab; |
2508 | } | 2508 | } |
2509 | for_each_possible_cpu(i) { | 2509 | for_each_possible_cpu(i) { |
2510 | struct ext4_locality_group *lg; | 2510 | struct ext4_locality_group *lg; |
@@ -2517,9 +2517,8 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) | |||
2517 | 2517 | ||
2518 | /* init file for buddy data */ | 2518 | /* init file for buddy data */ |
2519 | ret = ext4_mb_init_backend(sb); | 2519 | ret = ext4_mb_init_backend(sb); |
2520 | if (ret != 0) { | 2520 | if (ret != 0) |
2521 | goto out; | 2521 | goto out_free_locality_groups; |
2522 | } | ||
2523 | 2522 | ||
2524 | if (sbi->s_proc) | 2523 | if (sbi->s_proc) |
2525 | proc_create_data("mb_groups", S_IRUGO, sbi->s_proc, | 2524 | proc_create_data("mb_groups", S_IRUGO, sbi->s_proc, |
@@ -2527,11 +2526,19 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) | |||
2527 | 2526 | ||
2528 | if (sbi->s_journal) | 2527 | if (sbi->s_journal) |
2529 | sbi->s_journal->j_commit_callback = release_blocks_on_commit; | 2528 | sbi->s_journal->j_commit_callback = release_blocks_on_commit; |
2529 | |||
2530 | return 0; | ||
2531 | |||
2532 | out_free_locality_groups: | ||
2533 | free_percpu(sbi->s_locality_groups); | ||
2534 | sbi->s_locality_groups = NULL; | ||
2535 | out_free_groupinfo_slab: | ||
2536 | ext4_groupinfo_destroy_slabs(); | ||
2530 | out: | 2537 | out: |
2531 | if (ret) { | 2538 | kfree(sbi->s_mb_offsets); |
2532 | kfree(sbi->s_mb_offsets); | 2539 | sbi->s_mb_offsets = NULL; |
2533 | kfree(sbi->s_mb_maxs); | 2540 | kfree(sbi->s_mb_maxs); |
2534 | } | 2541 | sbi->s_mb_maxs = NULL; |
2535 | return ret; | 2542 | return ret; |
2536 | } | 2543 | } |
2537 | 2544 | ||