--- /dev/null
+Fix ext4_ext_find_extent() to already pre-allocate ext4_ext_path[]
+array of the max depth instead of current depth.
+This will avoid racy cases of concurrent ext_depth() growth in
+current and unsafe implementation with ext4_ext_path[] array
+re-[sizing,allocation], even with more recent and related patches
+that will be integrated in more recent Kernels.
+
+Index: linux-2.6.32-504.el6.x86_64/fs/ext4/ext4.h
+===================================================================
+--- linux-2.6.32-504.el6.x86_64.orig/fs/ext4/ext4.h
++++ linux-2.6.32-504.el6.x86_64/fs/ext4/ext4.h
+@@ -1147,6 +1147,9 @@
+ unsigned long s_ext_extents;
+ #endif
+
++ /* maximum possible extents tree depth, to be computed at mount time */
++ unsigned int s_max_ext_tree_depth;
++
+ /* for buddy allocator */
+ struct ext4_group_info ***s_group_info;
+ struct inode *s_buddy_cache;
+Index: linux-2.6.32-504.el6.x86_64/fs/ext4/super.c
+===================================================================
+--- linux-2.6.32-504.el6.x86_64.orig/fs/ext4/super.c
++++ linux-2.6.32-504.el6.x86_64/fs/ext4/super.c
+@@ -3529,6 +3529,8 @@
+ if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block)))
+ goto failed_mount3;
+
++ ext4_ext_init(sb); /* needed before using extent-mapped journal */
++
+ /*
+ * The first inode we look at is the journal inode. Don't try
+ * root first: it may be modified in the journal!
+@@ -3722,7 +3724,6 @@
+ goto failed_mount4a;
+ }
+
+- ext4_ext_init(sb);
+ err = ext4_mb_init(sb, needs_recovery);
+ if (err) {
+ ext4_msg(sb, KERN_ERR, "failed to initalize mballoc (%d)",
+Index: linux-2.6.32-504.el6.x86_64/fs/ext4/extents.c
+===================================================================
+--- linux-2.6.32-504.el6.x86_64.orig/fs/ext4/extents.c
++++ linux-2.6.32-504.el6.x86_64/fs/ext4/extents.c
+@@ -699,8 +699,9 @@
+
+ /* account possible depth increase */
+ if (!path) {
+- path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 2),
+- GFP_NOFS);
++ path = kzalloc(sizeof(struct ext4_ext_path) *
++ EXT4_SB(inode->i_sb)->s_max_ext_tree_depth,
++ GFP_NOFS);
+ if (!path)
+ return ERR_PTR(-ENOMEM);
+ alloc = 1;
+@@ -1915,11 +1916,8 @@
+ /* find extent for this block */
+ down_read(&EXT4_I(inode)->i_data_sem);
+
+- if (path && ext_depth(inode) != depth) {
+- /* depth was changed. we have to realloc path */
+- kfree(path);
+- path = NULL;
+- }
++ /* path of max possible depth will be allocated during
++ * first pass, so its space can be re-used for each loop */
+
+ path = ext4_ext_find_extent(inode, block, path);
+ if (IS_ERR(path)) {
+@@ -2664,8 +2662,9 @@
+ path[k].p_block =
+ le16_to_cpu(path[k].p_hdr->eh_entries)+1;
+ } else {
+- path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1),
+- GFP_NOFS);
++ path = kzalloc(sizeof(struct ext4_ext_path) *
++ EXT4_SB(inode->i_sb)->s_max_ext_tree_depth,
++ GFP_NOFS);
+ if (path == NULL) {
+ ext4_journal_stop(handle);
+ return -ENOMEM;
+@@ -2790,13 +2789,15 @@
+ */
+ void ext4_ext_init(struct super_block *sb)
+ {
++ ext4_fsblk_t maxblocks;
++
+ /*
+ * possible initialization would be here
+ */
+
+ if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
+-#if defined(AGGRESSIVE_TEST) || defined(CHECK_BINSEARCH) || defined(EXTENTS_STATS)
+- printk(KERN_INFO "EXT4-fs: file extents enabled");
++ printk(KERN_INFO "EXT4-fs (%s): file extents enabled",
++ sb->s_id);
+ #ifdef AGGRESSIVE_TEST
+ printk(", aggressive tests");
+ #endif
+@@ -2805,14 +2806,35 @@
+ #endif
+ #ifdef EXTENTS_STATS
+ printk(", stats");
+-#endif
+- printk("\n");
+-#endif
+-#ifdef EXTENTS_STATS
+ spin_lock_init(&EXT4_SB(sb)->s_ext_stats_lock);
+ EXT4_SB(sb)->s_ext_min = 1 << 30;
+ EXT4_SB(sb)->s_ext_max = 0;
+ #endif
++ EXT4_SB(sb)->s_max_ext_tree_depth = 1;
++
++ maxblocks = sb->s_maxbytes / sb->s_blocksize;
++
++ /* 1st/root level/node of extents tree stands in i_data and
++ * entries stored in tree nodes can be of type ext4_extent
++ * (leaf node) or ext4_extent_idx (internal node) */
++ maxblocks /= (sizeof(((struct ext4_inode_info *)0x0)->i_data) -
++ sizeof(struct ext4_extent_header)) /
++ max(sizeof(struct ext4_extent),
++ sizeof(struct ext4_extent_idx));
++
++ /* compute maximum extents tree depth for a fully populated
++ * file of max size made of only minimal/1-block extents */
++ while (maxblocks > 0) {
++ maxblocks /= (sb->s_blocksize -
++ sizeof(struct ext4_extent_header)) /
++ max(sizeof(struct ext4_extent),
++ sizeof(struct ext4_extent_idx));
++ EXT4_SB(sb)->s_max_ext_tree_depth++;
++ }
++
++ printk(", maximum tree depth=%u",
++ EXT4_SB(sb)->s_max_ext_tree_depth);
++ printk("\n");
+ }
+ }
+
+@@ -4614,11 +4636,8 @@
+ break;
+ }
+
+- if (ext_depth(inode) != depth) {
+- /* depth was changed. we have to realloc path */
+- kfree(path);
+- path = NULL;
+- }
++ /* path of max possible depth will be allocated during
++ * first pass, so its space can be re-used for each loop */
+
+ block = cbex.ec_block + cbex.ec_len;
+ }
--- /dev/null
+Fix ext4_ext_find_extent() to already pre-allocate ext4_ext_path[]
+array of the max depth instead of current depth.
+This will avoid racy cases of concurrent ext_depth() growth in
+current and unsafe implementation with ext4_ext_path[] array
+re-[sizing,allocation], even with more recent and related patches
+that will be integrated in more recent Kernels.
+
+Index: linux-2.6.32-504.el6.x86_64/fs/ext4/ext4.h
+===================================================================
+--- linux-2.6.32-504.el6.x86_64.orig/fs/ext4/ext4.h
++++ linux-2.6.32-504.el6.x86_64/fs/ext4/ext4.h
+@@ -1147,6 +1147,9 @@
+ unsigned long s_ext_extents;
+ #endif
+
++ /* maximum possible extents tree depth, to be computed at mount time */
++ unsigned int s_max_ext_tree_depth;
++
+ /* for buddy allocator */
+ struct ext4_group_info ***s_group_info;
+ struct inode *s_buddy_cache;
+Index: linux-2.6.32-504.el6.x86_64/fs/ext4/super.c
+===================================================================
+--- linux-2.6.32-504.el6.x86_64.orig/fs/ext4/super.c
++++ linux-2.6.32-504.el6.x86_64/fs/ext4/super.c
+@@ -4038,6 +4038,8 @@
+ if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block)))
+ goto failed_mount3;
+
++ ext4_ext_init(sb); /* needed before using extent-mapped journal */
++
+ /*
+ * The first inode we look at is the journal inode. Don't try
+ * root first: it may be modified in the journal!
+@@ -4200,7 +4202,6 @@
+ goto failed_mount4a;
+ }
+
+- ext4_ext_init(sb);
+ err = ext4_mb_init(sb);
+ if (err) {
+ ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
+Index: linux-2.6.32-504.el6.x86_64/fs/ext4/extents.c
+===================================================================
+--- linux-2.6.32-504.el6.x86_64.orig/fs/ext4/extents.c
++++ linux-2.6.32-504.el6.x86_64/fs/ext4/extents.c
+@@ -699,8 +699,9 @@
+
+ /* account possible depth increase */
+ if (!path) {
+- path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 2),
+- GFP_NOFS);
++ path = kzalloc(sizeof(struct ext4_ext_path) *
++ EXT4_SB(inode->i_sb)->s_max_ext_tree_depth,
++ GFP_NOFS);
+ if (!path)
+ return ERR_PTR(-ENOMEM);
+ alloc = 1;
+@@ -1915,11 +1916,8 @@
+ /* find extent for this block */
+ down_read(&EXT4_I(inode)->i_data_sem);
+
+- if (path && ext_depth(inode) != depth) {
+- /* depth was changed. we have to realloc path */
+- kfree(path);
+- path = NULL;
+- }
++ /* path of max possible depth will be allocated during
++ * first pass, so its space can be re-used for each loop */
+
+ path = ext4_ext_find_extent(inode, block, path);
+ if (IS_ERR(path)) {
+@@ -2664,8 +2662,9 @@
+ path[k].p_block =
+ le16_to_cpu(path[k].p_hdr->eh_entries)+1;
+ } else {
+- path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1),
+- GFP_NOFS);
++ path = kzalloc(sizeof(struct ext4_ext_path) *
++ EXT4_SB(inode->i_sb)->s_max_ext_tree_depth,
++ GFP_NOFS);
+ if (path == NULL) {
+ ext4_journal_stop(handle);
+ return -ENOMEM;
+@@ -3048,13 +3034,14 @@
+ */
+ void ext4_ext_init(struct super_block *sb)
+ {
++ ext4_fsblk_t maxblocks;
++
+ /*
+ * possible initialization would be here
+ */
+
+ if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
+-#if defined(AGGRESSIVE_TEST) || defined(CHECK_BINSEARCH) || defined(EXTENTS_STATS)
+- printk(KERN_INFO "EXT4-fs: file extents enabled"
++ printk(KERN_INFO "EXT4-fs (%s): file extents enabled"
+ #ifdef AGGRESSIVE_TEST
+ ", aggressive tests"
+ #endif
+@@ -3064,8 +3051,31 @@
+ #ifdef EXTENTS_STATS
+ ", stats"
+ #endif
+- "\n");
+-#endif
++ , sb->s_id);
++ EXT4_SB(sb)->s_max_ext_tree_depth = 1;
++
++ maxblocks = sb->s_maxbytes / sb->s_blocksize;
++
++ /* 1st/root level/node of extents tree stands in i_data and
++ * entries stored in tree nodes can be of type ext4_extent
++ * (leaf node) or ext4_extent_idx (internal node) */
++ maxblocks /= (sizeof(((struct ext4_inode_info *)0x0)->i_data) -
++ sizeof(struct ext4_extent_header)) /
++ max(sizeof(struct ext4_extent),
++ sizeof(struct ext4_extent_idx));
++
++ /* compute maximum extents tree depth for a fully populated
++ * file of max size made of only minimal/1-block extents */
++ while (maxblocks > 0) {
++ maxblocks /= (sb->s_blocksize -
++ sizeof(struct ext4_extent_header)) /
++ max(sizeof(struct ext4_extent),
++ sizeof(struct ext4_extent_idx));
++ EXT4_SB(sb)->s_max_ext_tree_depth++;
++ }
++
++ printk(", maximum tree depth=%u\n",
++ EXT4_SB(sb)->s_max_ext_tree_depth);
+ #ifdef EXTENTS_STATS
+ spin_lock_init(&EXT4_SB(sb)->s_ext_stats_lock);
+ EXT4_SB(sb)->s_ext_min = 1 << 30;
--- /dev/null
+Fix ext4_ext_find_extent() to already pre-allocate ext4_ext_path[]
+array of the max depth instead of current depth.
+This will avoid racy cases of concurrent ext_depth() growth in
+current and unsafe implementation with ext4_ext_path[] array
+re-[sizing,allocation], even with more recent and related patches
+that will be integrated in more recent Kernels.
+
+Index: linux-2.6.32-504.el6.x86_64/fs/ext4/ext4.h
+===================================================================
+--- linux-2.6.32-504.el6.x86_64.orig/fs/ext4/ext4.h
++++ linux-2.6.32-504.el6.x86_64/fs/ext4/ext4.h
+@@ -1147,6 +1147,9 @@
+ unsigned long s_ext_extents;
+ #endif
+
++ /* maximum possible extents tree depth, to be computed at mount time */
++ unsigned int s_max_ext_tree_depth;
++
+ /* for buddy allocator */
+ struct ext4_group_info ***s_group_info;
+ struct inode *s_buddy_cache;
+Index: linux-2.6.32-504.el6.x86_64/fs/ext4/super.c
+===================================================================
+--- linux-2.6.32-504.el6.x86_64.orig/fs/ext4/super.c
++++ linux-2.6.32-504.el6.x86_64/fs/ext4/super.c
+@@ -3529,6 +3529,8 @@
+ if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block)))
+ goto failed_mount3;
+
++ ext4_ext_init(sb); /* needed before using extent-mapped journal */
++
+ /*
+ * The first inode we look at is the journal inode. Don't try
+ * root first: it may be modified in the journal!
+@@ -3722,7 +3724,6 @@
+ goto failed_mount4a;
+ }
+
+- ext4_ext_init(sb);
+ err = ext4_mb_init(sb, needs_recovery);
+ if (err) {
+ ext4_msg(sb, KERN_ERR, "failed to initalize mballoc (%d)",
+Index: linux-2.6.32-504.el6.x86_64/fs/ext4/extents.c
+===================================================================
+--- linux-2.6.32-504.el6.x86_64.orig/fs/ext4/extents.c
++++ linux-2.6.32-504.el6.x86_64/fs/ext4/extents.c
+@@ -687,8 +687,9 @@
+
+ /* account possible depth increase */
+ if (!path) {
+- path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 2),
+- GFP_NOFS);
++ path = kzalloc(sizeof(struct ext4_ext_path) *
++ EXT4_SB(inode->i_sb)->s_max_ext_tree_depth,
++ GFP_NOFS);
+ if (!path)
+ return ERR_PTR(-ENOMEM);
+ alloc = 1;
+@@ -1985,12 +1986,6 @@
+ break;
+ }
+
+- if (ext_depth(inode) != depth) {
+- /* depth was changed. we have to realloc path */
+- kfree(path);
+- path = NULL;
+- }
+-
+ block = cbex.ec_block + cbex.ec_len;
+ }
+
+@@ -2636,7 +2631,8 @@
+ * after i_size and walking into the tree depth-wise.
+ */
+ depth = ext_depth(inode);
+- path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_NOFS);
++ path = kzalloc(sizeof(struct ext4_ext_path) *
++ EXT4_SB(inode->i_sb)->s_max_ext_tree_depth, GFP_NOFS);
+ if (path == NULL) {
+ ext4_journal_stop(handle);
+ return -ENOMEM;
+@@ -2755,13 +2751,15 @@
+ */
+ void ext4_ext_init(struct super_block *sb)
+ {
++ ext4_fsblk_t maxblocks;
++
+ /*
+ * possible initialization would be here
+ */
+
+ if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
+-#if defined(AGGRESSIVE_TEST) || defined(CHECK_BINSEARCH) || defined(EXTENTS_STATS)
+- printk(KERN_INFO "EXT4-fs: file extents enabled");
++ printk(KERN_INFO "EXT4-fs (%s): file extents enabled",
++ sb->s_id);
+ #ifdef AGGRESSIVE_TEST
+ printk(", aggressive tests");
+ #endif
+@@ -2770,14 +2768,35 @@
+ #endif
+ #ifdef EXTENTS_STATS
+ printk(", stats");
+-#endif
+- printk("\n");
+-#endif
+-#ifdef EXTENTS_STATS
+ spin_lock_init(&EXT4_SB(sb)->s_ext_stats_lock);
+ EXT4_SB(sb)->s_ext_min = 1 << 30;
+ EXT4_SB(sb)->s_ext_max = 0;
+ #endif
++ EXT4_SB(sb)->s_max_ext_tree_depth = 1;
++
++ maxblocks = sb->s_maxbytes / sb->s_blocksize;
++
++ /* 1st/root level/node of extents tree stands in i_data and
++ * entries stored in tree nodes can be of type ext4_extent
++ * (leaf node) or ext4_extent_idx (internal node) */
++ maxblocks /= (sizeof(((struct ext4_inode_info *)0x0)->i_data) -
++ sizeof(struct ext4_extent_header)) /
++ max(sizeof(struct ext4_extent),
++ sizeof(struct ext4_extent_idx));
++
++ /* compute maximum extents tree depth for a fully populated
++ * file of max size made of only minimal/1-block extents */
++ while (maxblocks > 0) {
++ maxblocks /= (sb->s_blocksize -
++ sizeof(struct ext4_extent_header)) /
++ max(sizeof(struct ext4_extent),
++ sizeof(struct ext4_extent_idx));
++ EXT4_SB(sb)->s_max_ext_tree_depth++;
++ }
++
++ printk(", maximum tree depth=%u",
++ EXT4_SB(sb)->s_max_ext_tree_depth);
++ printk("\n");
+ }
+ }
+
+@@ -3592,15 +3611,10 @@
+ * the start of the hole
+ */
+ ext4_ext_drop_refs(path);
+- kfree(path);
+
++ /* keep/reuse path */
+ path = ext4_ext_find_extent(inode,
+- map->m_lblk, NULL);
+- if (IS_ERR(path)) {
+- err = PTR_ERR(path);
+- path = NULL;
+- goto out2;
+- }
++ map->m_lblk, path);
+
+ depth = ext_depth(inode);
+ ex = path[depth].p_ext;
rhel6.6/ext4-corrupted-inode-block-bitmaps-handling-patches.patch
rhel6.3/ext4-notalloc_under_idatasem.patch
rhel6.5/ext4-give-warning-with-dir-htree-growing.patch
+rhel6.6/ext4_s_max_ext_tree_depth.patch
rhel6.6/ext4-corrupted-inode-block-bitmaps-handling-patches.patch
rhel6.3/ext4-notalloc_under_idatasem.patch
rhel6.5/ext4-give-warning-with-dir-htree-growing.patch
+rhel6.6/ext4_s_max_ext_tree_depth.patch
rhel6.3/ext4-not-discard-preallocation-umount.patch
rhel6.3/ext4-journal-path-opt.patch
rhel6.3/ext4-notalloc_under_idatasem.patch
+sles11sp3/ext4_s_max_ext_tree_depth.patch
rhel6.3/ext4-notalloc_under_idatasem.patch
rhel6.5/ext4-give-warning-with-dir-htree-growing.patch
sles11sp3/ext4-mmp-brelse.patch
+sles11sp3/ext4_s_max_ext_tree_depth.patch
rhel7/ext4-give-warning-with-dir-htree-growing.patch
rhel7/ext4-mmp-brelse.patch
rhel7/ext4-jcb-optimization.patch
+rhel7/ext4_s_max_ext_tree_depth.patch
rhel7/ext4-give-warning-with-dir-htree-growing.patch
rhel7/ext4-mmp-brelse.patch
rhel7/ext4-jcb-optimization.patch
+rhel7/ext4_s_max_ext_tree_depth.patch