From 7231a4d0d2661ddd81a2296064404529cb87605a Mon Sep 17 00:00:00 2001 From: Artem Blagodarenko Date: Wed, 17 Oct 2018 15:17:47 +0300 Subject: [PATCH] LU-11535 ldiskfs: allocate extra ldiskfs_ext_path for root Patch ext4_s_max_ext_tree_depth changes path array allocation. Maximum extent depth is counted in ext4_ext_init(), but extent's root stored in i_data is not counted. This leads to out of array writting in ldiskfs_ext_remove_space() and following fault during transaction commit: BUG: unable to handle kernel NULL pointer dereference at (null) [] osd_trans_commit_cb+0xcb/0x2b0 [osd_ldiskfs] [] ldiskfs_journal_commit_callback+0x61/0x80 [] jbd2_journal_commit_transaction+0x116f/0x15a0 This patch adds one extra element for root in path array. Cray-bug-id: LUS-6488 Signed-off-by: Artem Blagodarenko Change-Id: I950e223f6ad68c88c1e78fc62448542fd4e78329 Reviewed-on: https://review.whamcloud.com/33388 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Wang Shilong Reviewed-by: Oleg Drokin --- .../kernel_patches/patches/rhel6.6/ext4_s_max_ext_tree_depth.patch | 4 ++-- ldiskfs/kernel_patches/patches/rhel7/ext4_s_max_ext_tree_depth.patch | 4 ++-- .../kernel_patches/patches/sles11sp3/ext4_s_max_ext_tree_depth.patch | 5 +++-- .../kernel_patches/patches/sles12sp2/ext4_s_max_ext_tree_depth.patch | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) 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 index b14d599..c47535d 100644 --- 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 @@ -30,7 +30,7 @@ Index: linux-stage/fs/ext4/extents.c - 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, ++ (EXT4_SB(inode->i_sb)->s_max_ext_tree_depth + 1), + GFP_NOFS); if (!path) return ERR_PTR(-ENOMEM); @@ -55,7 +55,7 @@ Index: linux-stage/fs/ext4/extents.c } else { - path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), + path = kzalloc(sizeof(struct ext4_ext_path) * -+ EXT4_SB(inode->i_sb)->s_max_ext_tree_depth, ++ (EXT4_SB(inode->i_sb)->s_max_ext_tree_depth + 1), GFP_NOFS); if (path == NULL) { ext4_journal_stop(handle); 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 index 0efc834..07de8c5 100644 --- 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 @@ -51,7 +51,7 @@ Index: linux-2.6.32-504.el6.x86_64/fs/ext4/extents.c - 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, ++ (EXT4_SB(inode->i_sb)->s_max_ext_tree_depth + 1), + GFP_NOFS); if (!path) return ERR_PTR(-ENOMEM); @@ -77,7 +77,7 @@ Index: linux-2.6.32-504.el6.x86_64/fs/ext4/extents.c - 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, ++ (EXT4_SB(inode->i_sb)->s_max_ext_tree_depth + 1), + GFP_NOFS); if (path == NULL) { ext4_journal_stop(handle); 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 index bcbf8e6..cb26db2 100644 --- 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 @@ -51,7 +51,7 @@ Index: linux-2.6.32-504.el6.x86_64/fs/ext4/extents.c - 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, ++ (EXT4_SB(inode->i_sb)->s_max_ext_tree_depth + 1), + GFP_NOFS); if (!path) return ERR_PTR(-ENOMEM); @@ -75,7 +75,8 @@ Index: linux-2.6.32-504.el6.x86_64/fs/ext4/extents.c 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); ++ (EXT4_SB(inode->i_sb)->s_max_ext_tree_depth + 1), ++ GFP_NOFS); if (path == NULL) { ext4_journal_stop(handle); return -ENOMEM; diff --git a/ldiskfs/kernel_patches/patches/sles12sp2/ext4_s_max_ext_tree_depth.patch b/ldiskfs/kernel_patches/patches/sles12sp2/ext4_s_max_ext_tree_depth.patch index fcd7d26..76c8fe7 100644 --- a/ldiskfs/kernel_patches/patches/sles12sp2/ext4_s_max_ext_tree_depth.patch +++ b/ldiskfs/kernel_patches/patches/sles12sp2/ext4_s_max_ext_tree_depth.patch @@ -51,7 +51,7 @@ Index: linux-2.6.32-504.el6.x86_64/fs/ext4/extents.c - 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, ++ (EXT4_SB(inode->i_sb)->s_max_ext_tree_depth + 1), + GFP_NOFS); if (unlikely(!path)) return ERR_PTR(-ENOMEM); @@ -63,7 +63,7 @@ Index: linux-2.6.32-504.el6.x86_64/fs/ext4/extents.c - 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, ++ (EXT4_SB(inode->i_sb)->s_max_ext_tree_depth + 1), + GFP_NOFS); if (path == NULL) { ext4_journal_stop(handle); -- 1.8.3.1