+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;
+ }