From 536464e609c46a3950d7742bc3860b87d6bfc726 Mon Sep 17 00:00:00 2001 From: Bruno Faccini Date: Thu, 10 Jan 2013 15:27:25 +0100 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 Signed-off-by: Bruno Faccini Change-Id: I0ca3ff1e7ae8daa0260cd070c5ac52c843248a1b Reviewed-on: http://review.whamcloud.com/4683 Tested-by: Hudson Reviewed-by: Andreas Dilger Reviewed-by: Johann Lombardi Tested-by: Maloo --- .../patches/ext4-prealloc-rhel6.patch | 44 +++++++++++++++++++--- .../patches/ext4-vmalloc-rhel6.patch | 35 +---------------- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/ldiskfs/kernel_patches/patches/ext4-prealloc-rhel6.patch b/ldiskfs/kernel_patches/patches/ext4-prealloc-rhel6.patch index bd94246..5ec3320 100644 --- a/ldiskfs/kernel_patches/patches/ext4-prealloc-rhel6.patch +++ b/ldiskfs/kernel_patches/patches/ext4-prealloc-rhel6.patch @@ -143,6 +143,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; +@@ -2397,14 +2497,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); + @@ -2411,12 +2505,56 @@ sbi->s_mb_max_to_scan = MB_DEFAULT_MAX_TO_SCAN; sbi->s_mb_min_to_scan = MB_DEFAULT_MIN_TO_SCAN; @@ -202,10 +217,19 @@ Index: linux-stage/fs/ext4/mballoc.c kfree(sbi->s_mb_offsets); kfree(sbi->s_mb_maxs); return -ENOMEM; -@@ -2430,9 +2568,18 @@ +@@ -2430,9 +2568,27 @@ 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) + if (sbi->s_proc) { + struct proc_dir_entry *p; @@ -222,7 +246,15 @@ Index: linux-stage/fs/ext4/mballoc.c if (sbi->s_journal) sbi->s_journal->j_commit_callback = release_blocks_on_commit; -@@ -2512,8 +2659,10 @@ +@@ -2483,6 +2639,7 @@ + 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) +@@ -2512,8 +2668,10 @@ } free_percpu(sbi->s_locality_groups); @@ -234,7 +266,7 @@ Index: linux-stage/fs/ext4/mballoc.c return 0; } -@@ -2807,11 +2956,12 @@ +@@ -2807,11 +2965,12 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, struct ext4_allocation_request *ar) { @@ -249,7 +281,7 @@ Index: linux-stage/fs/ext4/mballoc.c struct ext4_prealloc_space *pa; /* do normalize only data requests, metadata requests -@@ -2841,49 +2991,35 @@ +@@ -2841,49 +3000,35 @@ size = size << bsbits; if (size < i_size_read(ac->ac_inode)) size = i_size_read(ac->ac_inode); @@ -324,7 +356,7 @@ Index: linux-stage/fs/ext4/mballoc.c /* don't cover already allocated blocks in selected range */ if (ar->pleft && start <= ar->lleft) { -@@ -2955,7 +3091,6 @@ +@@ -2955,7 +3100,6 @@ } BUG_ON(start + size <= ac->ac_o_ex.fe_logical && start > ac->ac_o_ex.fe_logical); @@ -332,7 +364,7 @@ Index: linux-stage/fs/ext4/mballoc.c /* now prepare goal request */ -@@ -3939,11 +4074,19 @@ +@@ -3939,11 +4083,19 @@ /* 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 686121d..359bee0 100644 --- a/ldiskfs/kernel_patches/patches/ext4-vmalloc-rhel6.patch +++ b/ldiskfs/kernel_patches/patches/ext4-vmalloc-rhel6.patch @@ -173,38 +173,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 * +@@ -2639,7 +2647,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]); @@ -214,5 +183,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