From: Bruno Faccini Date: Wed, 6 Apr 2016 14:38:05 +0000 (+0200) Subject: LU-7980 ldiskfs: always pre-allocate max depth for path X-Git-Tag: 2.8.53~32 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=655255b651d80d115fbde6729bd58e22afce6483 LU-7980 ldiskfs: always pre-allocate max depth for path Upon very specific meta-data and I/O pattern a situation can be encountered where ext_depth() will concurrently (due to i_data_sem release) grow outside of currently used ext4_ext_path[] array boundary. This can lead to potential Slab overrun if current ext_depth() is used to index previously sized+allocated ext4_ext_path[] array. This patch fixes this by already pre-allocating _ext_path[] array of the max possible depth. This is an alternate way to avoid racy cases, that can lead to slab overrun, with current and unsafe implementation that causes ext4_ext_path[] array re-[sizing,allocation] based on current depth. Now unnecessay free an realloc upon depth change detection prior to reuse already allocated path space have also been removed. Signed-off-by: Bruno Faccini Change-Id: I0ae955c5eccf032cb02ef55c6381964a5eaf82c2 Reviewed-on: http://review.whamcloud.com/19349 Tested-by: Jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Alex Zhuravlev --- diff --git a/ldiskfs/kernel_patches/patches/rhel6.6/ext4_s_max_ext_tree_depth.patch b/ldiskfs/kernel_patches/patches/rhel6.6/ext4_s_max_ext_tree_depth.patch new file mode 100644 index 0000000..96c9b89 --- /dev/null +++ b/ldiskfs/kernel_patches/patches/rhel6.6/ext4_s_max_ext_tree_depth.patch @@ -0,0 +1,156 @@ +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; + } diff --git a/ldiskfs/kernel_patches/patches/rhel7/ext4_s_max_ext_tree_depth.patch b/ldiskfs/kernel_patches/patches/rhel7/ext4_s_max_ext_tree_depth.patch new file mode 100644 index 0000000..0efc834 --- /dev/null +++ b/ldiskfs/kernel_patches/patches/rhel7/ext4_s_max_ext_tree_depth.patch @@ -0,0 +1,135 @@ +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; diff --git a/ldiskfs/kernel_patches/patches/sles11sp3/ext4_s_max_ext_tree_depth.patch b/ldiskfs/kernel_patches/patches/sles11sp3/ext4_s_max_ext_tree_depth.patch new file mode 100644 index 0000000..bcbf8e6 --- /dev/null +++ b/ldiskfs/kernel_patches/patches/sles11sp3/ext4_s_max_ext_tree_depth.patch @@ -0,0 +1,157 @@ +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; diff --git a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.6.series b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.6.series index e3df418..9405d7e 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.6.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.6.series @@ -47,3 +47,4 @@ rhel6.6/ext4-remove-truncate-warning.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.7.series b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.7.series index e3fd3fd..bea14bc 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.7.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.7.series @@ -46,3 +46,4 @@ rhel6.6/ext4-remove-truncate-warning.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-3.0-sles11.series b/ldiskfs/kernel_patches/series/ldiskfs-3.0-sles11.series index 4728457..f8405dd 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-3.0-sles11.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-3.0-sles11.series @@ -38,3 +38,4 @@ sles11sp2/ext4-max-dir-size-options.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-3.0-sles11sp3.series b/ldiskfs/kernel_patches/series/ldiskfs-3.0-sles11sp3.series index 9cb4ecd..72124a1 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-3.0-sles11sp3.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-3.0-sles11sp3.series @@ -40,3 +40,4 @@ sles11sp2/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 sles11sp3/ext4-mmp-brelse.patch +sles11sp3/ext4_s_max_ext_tree_depth.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.2.series b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.2.series index db32551..c4ea562 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.2.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.2.series @@ -20,3 +20,4 @@ rhel7/ext4-corrupted-inode-block-bitmaps-handling-patches.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.series b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.series index 69906c5..926f63a 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.series @@ -20,3 +20,4 @@ rhel7/ext4-corrupted-inode-block-bitmaps-handling-patches.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