+++ /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 @@
-
- if (!path) {
- /* account possible depth increase */
-- 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 + 1),
-+ GFP_NOFS);
- if (unlikely(!path))
- return ERR_PTR(-ENOMEM);
- alloc = 1;
-@@ -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 + 1),
-+ 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_feature_extents(sb)) {
--#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;