From 8f4461e504ec809e2218203e0a02b323430d766e Mon Sep 17 00:00:00 2001 From: Emoly Liu Date: Tue, 19 Feb 2013 02:15:28 +0800 Subject: [PATCH] LU-2072 ldiskfs: Leak of s_mb_prealloc_table in ldiskfs ext4-prealloc-rhel[5,6] patches adds kmalloc'ed sbi->s_mb_prealloc_table field which is never freed in [ldiskfs,ext4]_mb_release()/ext4-vmalloc-rhel[5,6].patch port of master patch 536464e609c46a3950d7742bc3860b87d6bfc726 Signed-off-by: Bruno Faccini Signed-off-by: Liu Ying Change-Id: I0acd9f62d6ffc516540d707830b40c0bd211a43b Reviewed-on: http://review.whamcloud.com/5474 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Oleg Drokin --- .../patches/ext4-prealloc-rhel6.patch | 45 ++++++++++++++++++---- .../patches/ext4-vmalloc-rhel6.patch | 39 ++----------------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/ldiskfs/kernel_patches/patches/ext4-prealloc-rhel6.patch b/ldiskfs/kernel_patches/patches/ext4-prealloc-rhel6.patch index 6074545..dcb67a7 100644 --- a/ldiskfs/kernel_patches/patches/ext4-prealloc-rhel6.patch +++ b/ldiskfs/kernel_patches/patches/ext4-prealloc-rhel6.patch @@ -129,7 +129,21 @@ Index: linux-stage/fs/ext4/mballoc.c static int ext4_mb_seq_groups_open(struct inode *inode, struct file *file) { struct super_block *sb = PDE(inode)->data; -@@ -2394,12 +2487,56 @@ int ext4_mb_init(struct super_block *sb, +@@ -2380,26 +2473,62 @@ int ext4_mb_init(struct super_block *sb, + i++; + } while (i <= sb->s_blocksize_bits + 1); + +- /* init file for buddy data */ +- ret = ext4_mb_init_backend(sb); +- if (ret != 0) { +- kfree(sbi->s_mb_offsets); +- kfree(sbi->s_mb_maxs); +- return ret; +- } +- + spin_lock_init(&sbi->s_md_lock); + spin_lock_init(&sbi->s_bal_lock); + sbi->s_mb_max_to_scan = MB_DEFAULT_MAX_TO_SCAN; sbi->s_mb_min_to_scan = MB_DEFAULT_MIN_TO_SCAN; sbi->s_mb_stats = MB_DEFAULT_STATS; @@ -188,11 +202,20 @@ Index: linux-stage/fs/ext4/mballoc.c kfree(sbi->s_mb_offsets); kfree(sbi->s_mb_maxs); return -ENOMEM; -@@ -2413,9 +2550,18 @@ int ext4_mb_init(struct super_block *sb, +@@ -2413,9 +2542,27 @@ int ext4_mb_init(struct super_block *sb, spin_lock_init(&lg->lg_prealloc_lock); } - if (sbi->s_proc) ++ /* init file for buddy data */ ++ ret = ext4_mb_init_backend(sb); ++ if (ret != 0) { ++ kfree(sbi->s_mb_prealloc_table); ++ kfree(sbi->s_mb_offsets); ++ kfree(sbi->s_mb_maxs); ++ return ret; ++ } ++ + if (sbi->s_proc) { + struct proc_dir_entry *p; proc_create_data("mb_groups", S_IRUGO, sbi->s_proc, @@ -208,7 +231,15 @@ Index: linux-stage/fs/ext4/mballoc.c if (sbi->s_journal) sbi->s_journal->j_commit_callback = release_blocks_on_commit; -@@ -2495,8 +2641,10 @@ int ext4_mb_release(struct super_block * +@@ -2466,6 +2613,7 @@ int ext4_mb_release(struct super_block * + kfree(sbi->s_group_info[i]); + kfree(sbi->s_group_info); + } ++ kfree(sbi->s_mb_prealloc_table); + kfree(sbi->s_mb_offsets); + kfree(sbi->s_mb_maxs); + if (sbi->s_buddy_cache) +@@ -2495,8 +2643,10 @@ int ext4_mb_release(struct super_block * } free_percpu(sbi->s_locality_groups); @@ -220,7 +251,7 @@ Index: linux-stage/fs/ext4/mballoc.c return 0; } -@@ -2795,11 +2943,12 @@ static noinline_for_stack void +@@ -2797,11 +2947,12 @@ static noinline_for_stack void ext4_mb_normalize_request(struct ext4_allocation_context *ac, struct ext4_allocation_request *ar) { @@ -235,7 +266,7 @@ Index: linux-stage/fs/ext4/mballoc.c struct ext4_prealloc_space *pa; /* do normalize only data requests, metadata requests -@@ -2829,49 +2978,35 @@ ext4_mb_normalize_request(struct ext4_al +@@ -2831,49 +2982,35 @@ ext4_mb_normalize_request(struct ext4_al size = size << bsbits; if (size < i_size_read(ac->ac_inode)) size = i_size_read(ac->ac_inode); @@ -310,7 +341,7 @@ Index: linux-stage/fs/ext4/mballoc.c /* don't cover already allocated blocks in selected range */ if (ar->pleft && start <= ar->lleft) { -@@ -2943,7 +3078,6 @@ ext4_mb_normalize_request(struct ext4_al +@@ -2945,7 +3082,6 @@ ext4_mb_normalize_request(struct ext4_al } BUG_ON(start + size <= ac->ac_o_ex.fe_logical && start > ac->ac_o_ex.fe_logical); @@ -318,7 +349,7 @@ Index: linux-stage/fs/ext4/mballoc.c /* now prepare goal request */ -@@ -3927,11 +4061,19 @@ static void ext4_mb_group_or_file(struct +@@ -3929,11 +4065,19 @@ static void ext4_mb_group_or_file(struct /* don't use group allocation for large files */ size = max(size, isize); diff --git a/ldiskfs/kernel_patches/patches/ext4-vmalloc-rhel6.patch b/ldiskfs/kernel_patches/patches/ext4-vmalloc-rhel6.patch index 6691dbe..392bd28 100644 --- a/ldiskfs/kernel_patches/patches/ext4-vmalloc-rhel6.patch +++ b/ldiskfs/kernel_patches/patches/ext4-vmalloc-rhel6.patch @@ -107,7 +107,7 @@ Index: linux-stage/fs/ext4/mballoc.c =================================================================== --- linux-stage.orig/fs/ext4/mballoc.c +++ linux-stage/fs/ext4/mballoc.c -@@ -2426,24 +2426,37 @@ static int ext4_mb_init_backend(struct s +@@ -2408,24 +2408,37 @@ static int ext4_mb_init_backend(struct s while (array_size < sizeof(*sbi->s_group_info) * num_meta_group_infos_max) array_size = array_size << 1; @@ -153,7 +153,7 @@ Index: linux-stage/fs/ext4/mballoc.c "EXT4-fs: can't read descriptor %u\n", i); goto err_freebuddy; } -@@ -2461,7 +2474,10 @@ err_freebuddy: +@@ -2443,7 +2456,10 @@ err_freebuddy: kfree(sbi->s_group_info[i]); iput(sbi->s_buddy_cache); err_freesgi: @@ -165,38 +165,7 @@ Index: linux-stage/fs/ext4/mballoc.c return -ENOMEM; } -@@ -2502,14 +2518,6 @@ int ext4_mb_init(struct super_block *sb, - i++; - } while (i <= sb->s_blocksize_bits + 1); - -- /* init file for buddy data */ -- ret = ext4_mb_init_backend(sb); -- if (ret != 0) { -- kfree(sbi->s_mb_offsets); -- kfree(sbi->s_mb_maxs); -- return ret; -- } -- - spin_lock_init(&sbi->s_md_lock); - spin_lock_init(&sbi->s_bal_lock); - -@@ -2579,6 +2587,15 @@ int ext4_mb_init(struct super_block *sb, - spin_lock_init(&lg->lg_prealloc_lock); - } - -+ /* init file for buddy data */ -+ ret = ext4_mb_init_backend(sb); -+ if (ret != 0) { -+ kfree(sbi->s_mb_prealloc_table); -+ kfree(sbi->s_mb_offsets); -+ kfree(sbi->s_mb_maxs); -+ return ret; -+ } -+ - if (sbi->s_proc) { - struct proc_dir_entry *p; - proc_create_data("mb_groups", S_IRUGO, sbi->s_proc, -@@ -2639,7 +2656,10 @@ int ext4_mb_release(struct super_block * +@@ -2622,7 +2638,10 @@ int ext4_mb_release(struct super_block * EXT4_DESC_PER_BLOCK_BITS(sb); for (i = 0; i < num_meta_group_infos; i++) kfree(sbi->s_group_info[i]); @@ -206,5 +175,5 @@ Index: linux-stage/fs/ext4/mballoc.c + else + kfree(sbi->s_group_info); } + kfree(sbi->s_mb_prealloc_table); kfree(sbi->s_mb_offsets); - kfree(sbi->s_mb_maxs); -- 1.8.3.1