From 486b405d34e4f7273f0919caa07d2987887de3b6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 2 Apr 2013 13:25:06 -0700 Subject: [PATCH] 3.4-stable patches added patches: ext4-convert-number-of-blocks-to-clusters-properly.patch ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch --- ...umber-of-blocks-to-clusters-properly.patch | 99 +++++++++++++ ...r-the-per-flexbg-free_clusters-count.patch | 132 ++++++++++++++++++ queue-3.4/series | 2 + 3 files changed, 233 insertions(+) create mode 100644 queue-3.4/ext4-convert-number-of-blocks-to-clusters-properly.patch create mode 100644 queue-3.4/ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch diff --git a/queue-3.4/ext4-convert-number-of-blocks-to-clusters-properly.patch b/queue-3.4/ext4-convert-number-of-blocks-to-clusters-properly.patch new file mode 100644 index 00000000000..fbe724d94a7 --- /dev/null +++ b/queue-3.4/ext4-convert-number-of-blocks-to-clusters-properly.patch @@ -0,0 +1,99 @@ +From 810da240f221d64bf90020f25941b05b378186fe Mon Sep 17 00:00:00 2001 +From: Lukas Czerner +Date: Sat, 2 Mar 2013 17:18:58 -0500 +Subject: ext4: convert number of blocks to clusters properly + +From: Lukas Czerner + +commit 810da240f221d64bf90020f25941b05b378186fe upstream. + +We're using macro EXT4_B2C() to convert number of blocks to number of +clusters for bigalloc file systems. However, we should be using +EXT4_NUM_B2C(). + +Signed-off-by: Lukas Czerner +Signed-off-by: "Theodore Ts'o" +Signed-off-by: CAI Qian +Signed-off-by: Lingzhu Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/balloc.c | 2 +- + fs/ext4/mballoc.c | 8 ++++---- + fs/ext4/resize.c | 6 +++--- + 3 files changed, 8 insertions(+), 8 deletions(-) + +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -600,7 +600,7 @@ ext4_fsblk_t ext4_count_free_clusters(st + brelse(bitmap_bh); + printk(KERN_DEBUG "ext4_count_free_clusters: stored = %llu" + ", computed = %llu, %llu\n", +- EXT4_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)), ++ EXT4_NUM_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)), + desc_count, bitmap_count); + return bitmap_count; + #else +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -3433,7 +3433,7 @@ ext4_mb_new_inode_pa(struct ext4_allocat + win = offs; + + ac->ac_b_ex.fe_logical = ac->ac_o_ex.fe_logical - +- EXT4_B2C(sbi, win); ++ EXT4_NUM_B2C(sbi, win); + BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical); + BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len); + } +@@ -4577,7 +4577,7 @@ do_more: + EXT4_BLOCKS_PER_GROUP(sb); + count -= overflow; + } +- count_clusters = EXT4_B2C(sbi, count); ++ count_clusters = EXT4_NUM_B2C(sbi, count); + bitmap_bh = ext4_read_block_bitmap(sb, block_group); + if (!bitmap_bh) { + err = -EIO; +@@ -4808,11 +4808,11 @@ int ext4_group_add_blocks(handle_t *hand + desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); + ext4_unlock_group(sb, block_group); + percpu_counter_add(&sbi->s_freeclusters_counter, +- EXT4_B2C(sbi, blocks_freed)); ++ EXT4_NUM_B2C(sbi, blocks_freed)); + + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, block_group); +- atomic_add(EXT4_B2C(sbi, blocks_freed), ++ atomic_add(EXT4_NUM_B2C(sbi, blocks_freed), + &sbi->s_flex_groups[flex_group].free_clusters); + } + +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -1112,7 +1112,7 @@ static int ext4_setup_new_descs(handle_t + ext4_inode_bitmap_set(sb, gdp, group_data->inode_bitmap); + ext4_inode_table_set(sb, gdp, group_data->inode_table); + ext4_free_group_clusters_set(sb, gdp, +- EXT4_B2C(sbi, group_data->free_blocks_count)); ++ EXT4_NUM_B2C(sbi, group_data->free_blocks_count)); + ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb)); + gdp->bg_flags = cpu_to_le16(*bg_flags); + gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); +@@ -1210,7 +1210,7 @@ static void ext4_update_super(struct sup + + /* Update the free space counts */ + percpu_counter_add(&sbi->s_freeclusters_counter, +- EXT4_B2C(sbi, free_blocks)); ++ EXT4_NUM_B2C(sbi, free_blocks)); + percpu_counter_add(&sbi->s_freeinodes_counter, + EXT4_INODES_PER_GROUP(sb) * flex_gd->count); + +@@ -1219,7 +1219,7 @@ static void ext4_update_super(struct sup + sbi->s_log_groups_per_flex) { + ext4_group_t flex_group; + flex_group = ext4_flex_group(sbi, group_data[0].group); +- atomic_add(EXT4_B2C(sbi, free_blocks), ++ atomic_add(EXT4_NUM_B2C(sbi, free_blocks), + &sbi->s_flex_groups[flex_group].free_clusters); + atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count, + &sbi->s_flex_groups[flex_group].free_inodes); diff --git a/queue-3.4/ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch b/queue-3.4/ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch new file mode 100644 index 00000000000..2bf00741ec2 --- /dev/null +++ b/queue-3.4/ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch @@ -0,0 +1,132 @@ +From 90ba983f6889e65a3b506b30dc606aa9d1d46cd2 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Mon, 11 Mar 2013 23:39:59 -0400 +Subject: ext4: use atomic64_t for the per-flexbg free_clusters count + +From: Theodore Ts'o + +commit 90ba983f6889e65a3b506b30dc606aa9d1d46cd2 upstream. + +A user who was using a 8TB+ file system and with a very large flexbg +size (> 65536) could cause the atomic_t used in the struct flex_groups +to overflow. This was detected by PaX security patchset: + +http://forums.grsecurity.net/viewtopic.php?f=3&t=3289&p=12551#p12551 + +This bug was introduced in commit 9f24e4208f7e, so it's been around +since 2.6.30. :-( + +Fix this by using an atomic64_t for struct orlav_stats's +free_clusters. + +Signed-off-by: "Theodore Ts'o" +Reviewed-by: Lukas Czerner +Signed-off-by: Lingzhu Xiang +Reviewed-by: CAI Qian +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ext4.h | 6 +++--- + fs/ext4/ialloc.c | 4 ++-- + fs/ext4/mballoc.c | 12 ++++++------ + fs/ext4/resize.c | 4 ++-- + fs/ext4/super.c | 4 ++-- + 5 files changed, 15 insertions(+), 15 deletions(-) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -316,9 +316,9 @@ struct ext4_group_desc + */ + + struct flex_groups { +- atomic_t free_inodes; +- atomic_t free_clusters; +- atomic_t used_dirs; ++ atomic64_t free_clusters; ++ atomic_t free_inodes; ++ atomic_t used_dirs; + }; + + #define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */ +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -305,8 +305,8 @@ error_return: + } + + struct orlov_stats { ++ __u64 free_clusters; + __u32 free_inodes; +- __u32 free_clusters; + __u32 used_dirs; + }; + +@@ -323,7 +323,7 @@ static void get_orlov_stats(struct super + + if (flex_size > 1) { + stats->free_inodes = atomic_read(&flex_group[g].free_inodes); +- stats->free_clusters = atomic_read(&flex_group[g].free_clusters); ++ stats->free_clusters = atomic64_read(&flex_group[g].free_clusters); + stats->used_dirs = atomic_read(&flex_group[g].used_dirs); + return; + } +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -2813,8 +2813,8 @@ ext4_mb_mark_diskspace_used(struct ext4_ + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, + ac->ac_b_ex.fe_group); +- atomic_sub(ac->ac_b_ex.fe_len, +- &sbi->s_flex_groups[flex_group].free_clusters); ++ atomic64_sub(ac->ac_b_ex.fe_len, ++ &sbi->s_flex_groups[flex_group].free_clusters); + } + + err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); +@@ -4667,8 +4667,8 @@ do_more: + + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, block_group); +- atomic_add(count_clusters, +- &sbi->s_flex_groups[flex_group].free_clusters); ++ atomic64_add(count_clusters, ++ &sbi->s_flex_groups[flex_group].free_clusters); + } + + ext4_mb_unload_buddy(&e4b); +@@ -4812,8 +4812,8 @@ int ext4_group_add_blocks(handle_t *hand + + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, block_group); +- atomic_add(EXT4_NUM_B2C(sbi, blocks_freed), +- &sbi->s_flex_groups[flex_group].free_clusters); ++ atomic64_add(EXT4_NUM_B2C(sbi, blocks_freed), ++ &sbi->s_flex_groups[flex_group].free_clusters); + } + + ext4_mb_unload_buddy(&e4b); +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -1219,8 +1219,8 @@ static void ext4_update_super(struct sup + sbi->s_log_groups_per_flex) { + ext4_group_t flex_group; + flex_group = ext4_flex_group(sbi, group_data[0].group); +- atomic_add(EXT4_NUM_B2C(sbi, free_blocks), +- &sbi->s_flex_groups[flex_group].free_clusters); ++ atomic64_add(EXT4_NUM_B2C(sbi, free_blocks), ++ &sbi->s_flex_groups[flex_group].free_clusters); + atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count, + &sbi->s_flex_groups[flex_group].free_inodes); + } +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -1907,8 +1907,8 @@ static int ext4_fill_flex_info(struct su + flex_group = ext4_flex_group(sbi, i); + atomic_add(ext4_free_inodes_count(sb, gdp), + &sbi->s_flex_groups[flex_group].free_inodes); +- atomic_add(ext4_free_group_clusters(sb, gdp), +- &sbi->s_flex_groups[flex_group].free_clusters); ++ atomic64_add(ext4_free_group_clusters(sb, gdp), ++ &sbi->s_flex_groups[flex_group].free_clusters); + atomic_add(ext4_used_dirs_count(sb, gdp), + &sbi->s_flex_groups[flex_group].used_dirs); + } diff --git a/queue-3.4/series b/queue-3.4/series index d4164f8a447..b2d7de63ebf 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -37,3 +37,5 @@ drm-i915-don-t-clobber-crtc-fb-when-queue_flip-fails.patch btrfs-fix-space-leak-when-we-fail-to-reserve-metadata-space.patch efivars-explicitly-calculate-length-of-variablename.patch efivars-handle-duplicate-names-from-get_next_variable.patch +ext4-convert-number-of-blocks-to-clusters-properly.patch +ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch -- 2.47.3