From d8dc6a1b53c5007aa38c89d58e530af1195d39dd Mon Sep 17 00:00:00 2001 From: Alex Zhuravlev Date: Mon, 12 Jun 2023 08:20:16 +0300 Subject: [PATCH] LU-16843 ldiskfs: merge extent blocks There are cases (e.g. file written synchronously with discontiguous blocks that are later filled in) when a lot of extents are created initially, then the extents get merged over time, but there is no way to merge the index blocks. This can cause a very deep extent index tree (above 5 levels) and cause problems like: inode has invalid extent depth: 6 Merge leave/index blocks (one at each level at most) to right/left when extents are removed from the index. submitted to ext4@ maillist: https://lore.kernel.org/linux-ext4/7A2B8861-96AA-4815-BB58-180F63F62436@whamcloud.com/ Lustre-change: https://review.whamcloud.com/51096 Lustre-commit: 0f7e6c02a9ea5b85d8d97f724bed318268cea60f Signed-off-by: Alex Zhuravlev Change-Id: I746c0917e746eb442d3c69a23f591d9cdade76fa Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/51272 Reviewed-by: Andreas Dilger Tested-by: jenkins Tested-by: Maloo --- .../patches/rhel7.9/ext4-ext-merge.patch | 219 +++++++++++++++++++++ .../patches/rhel8/ext4-ext-merge.patch | 219 +++++++++++++++++++++ .../series/ldiskfs-3.10-rhel7.6.series | 1 + .../series/ldiskfs-3.10-rhel7.7.series | 1 + .../series/ldiskfs-3.10-rhel7.8.series | 1 + .../series/ldiskfs-3.10-rhel7.9.series | 1 + .../series/ldiskfs-4.12-sles15-22.series | 1 + .../series/ldiskfs-4.12-sles15.series | 1 + .../series/ldiskfs-4.12-sles15sp1-7.series | 1 + .../series/ldiskfs-4.12-sles15sp1.series | 1 + .../series/ldiskfs-4.15.0-20-ubuntu18.series | 1 + .../series/ldiskfs-4.15.0-24-ubuntu18.series | 1 + .../series/ldiskfs-4.18-rhel8.1.series | 1 + .../series/ldiskfs-4.18-rhel8.2.series | 1 + .../series/ldiskfs-4.18-rhel8.3.series | 1 + .../series/ldiskfs-4.18-rhel8.4.series | 1 + .../series/ldiskfs-4.18-rhel8.5.series | 1 + .../series/ldiskfs-4.18-rhel8.6.series | 1 + .../series/ldiskfs-4.18-rhel8.7.series | 1 + .../series/ldiskfs-4.18-rhel8.series | 1 + .../series/ldiskfs-5.0.0-13-ubuntu19.series | 1 + .../series/ldiskfs-5.4.0-42-ubuntu20.series | 1 + .../series/ldiskfs-5.4.0-66-ubuntu20.series | 1 + .../kernel_patches/series/ldiskfs-5.4.0-ml.series | 1 + .../kernel_patches/series/ldiskfs-5.4.21-ml.series | 1 + .../kernel_patches/series/ldiskfs-5.8.0-ml.series | 1 + 26 files changed, 462 insertions(+) create mode 100644 ldiskfs/kernel_patches/patches/rhel7.9/ext4-ext-merge.patch create mode 100644 ldiskfs/kernel_patches/patches/rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/patches/rhel7.9/ext4-ext-merge.patch b/ldiskfs/kernel_patches/patches/rhel7.9/ext4-ext-merge.patch new file mode 100644 index 0000000..b59d2c8 --- /dev/null +++ b/ldiskfs/kernel_patches/patches/rhel7.9/ext4-ext-merge.patch @@ -0,0 +1,219 @@ +Index: linux-4.18.0-80.1.2.el8_0/fs/ext4/extents.c +=================================================================== +--- linux-4.18.0-80.1.2.el8_0.orig/fs/ext4/extents.c ++++ linux-4.18.0-80.1.2.el8_0/fs/ext4/extents.c +@@ -1888,7 +1944,7 @@ static void ext4_ext_try_to_merge_up( + * This function tries to merge the @ex extent to neighbours in the tree, then + * tries to collapse the extent tree into the inode. + */ +-static void ext4_ext_try_to_merge(handle_t *handle, ++static int ext4_ext_try_to_merge(handle_t *handle, + struct inode *inode, + struct ext4_ext_path *path, + struct ext4_extent *ex) +@@ -1905,9 +1961,177 @@ static void ext4_ext_try_to_merge(han + merge_done = ext4_ext_try_to_merge_right(inode, path, ex - 1); + + if (!merge_done) +- (void) ext4_ext_try_to_merge_right(inode, path, ex); ++ merge_done = ext4_ext_try_to_merge_right(inode, path, ex); + + ext4_ext_try_to_merge_up(handle, inode, path); ++ ++ return merge_done; ++} ++ ++/* ++ * This function tries to merge blocks from @path into @npath ++ */ ++static int ext4_ext_merge_blocks(handle_t *handle, ++ struct inode *inode, ++ struct ext4_ext_path *path, ++ struct ext4_ext_path *npath) ++{ ++ unsigned int depth = ext_depth(inode); ++ int used, nused, free, i, k, err; ++ ext4_lblk_t next; ++ ++ if (path[depth].p_hdr == npath[depth].p_hdr) ++ return 0; ++ ++ used = le16_to_cpu(path[depth].p_hdr->eh_entries); ++ free = le16_to_cpu(npath[depth].p_hdr->eh_max) - ++ le16_to_cpu(npath[depth].p_hdr->eh_entries); ++ if (free < used) ++ return 0; ++ ++ err = ext4_ext_get_access(handle, inode, path + depth); ++ if (err) ++ return err; ++ err = ext4_ext_get_access(handle, inode, npath + depth); ++ if (err) ++ return err; ++ ++ /* move entries from the current leave to the next one */ ++ nused = le16_to_cpu(npath[depth].p_hdr->eh_entries); ++ memmove(EXT_FIRST_EXTENT(npath[depth].p_hdr) + used, ++ EXT_FIRST_EXTENT(npath[depth].p_hdr), ++ nused * sizeof(struct ext4_extent)); ++ memcpy(EXT_FIRST_EXTENT(npath[depth].p_hdr), ++ EXT_FIRST_EXTENT(path[depth].p_hdr), ++ used * sizeof(struct ext4_extent)); ++ le16_add_cpu(&npath[depth].p_hdr->eh_entries, used); ++ le16_add_cpu(&path[depth].p_hdr->eh_entries, -used); ++ ext4_ext_try_to_merge_right(inode, npath, ++ EXT_FIRST_EXTENT(npath[depth].p_hdr)); ++ ++ err = ext4_ext_dirty(handle, inode, path + depth); ++ if (err) ++ return err; ++ err = ext4_ext_dirty(handle, inode, npath + depth); ++ if (err) ++ return err; ++ ++ /* otherwise the index won't get corrected */ ++ npath[depth].p_ext = EXT_FIRST_EXTENT(npath[depth].p_hdr); ++ err = ext4_ext_correct_indexes(handle, inode, npath); ++ if (err) ++ return err; ++ ++ for (i = depth - 1; i >= 0; i--) { ++ ++ next = ext4_idx_pblock(path[i].p_idx); ++ ext4_free_blocks(handle, inode, NULL, next, 1, ++ EXT4_FREE_BLOCKS_METADATA | ++ EXT4_FREE_BLOCKS_FORGET); ++ err = ext4_ext_get_access(handle, inode, path + i); ++ if (err) ++ return err; ++ le16_add_cpu(&path[i].p_hdr->eh_entries, -1); ++ if (le16_to_cpu(path[i].p_hdr->eh_entries) == 0) { ++ /* whole index block collapsed, go up */ ++ continue; ++ } ++ /* remove index pointer */ ++ used = EXT_LAST_INDEX(path[i].p_hdr) - path[i].p_idx + 1; ++ memmove(path[i].p_idx, path[i].p_idx + 1, ++ used * sizeof(struct ext4_extent_idx)); ++ ++ err = ext4_ext_dirty(handle, inode, path + i); ++ if (err) ++ return err; ++ ++ if (path[i].p_hdr == npath[i].p_hdr) ++ break; ++ ++ /* try to move index pointers */ ++ used = le16_to_cpu(path[i].p_hdr->eh_entries); ++ free = le16_to_cpu(npath[i].p_hdr->eh_max) - ++ le16_to_cpu(npath[i].p_hdr->eh_entries); ++ if (used > free) ++ break; ++ err = ext4_ext_get_access(handle, inode, npath + i); ++ if (err) ++ return err; ++ memmove(EXT_FIRST_INDEX(npath[i].p_hdr) + used, ++ EXT_FIRST_INDEX(npath[i].p_hdr), ++ npath[i].p_hdr->eh_entries * sizeof(struct ext4_extent_idx)); ++ memcpy(EXT_FIRST_INDEX(npath[i].p_hdr), EXT_FIRST_INDEX(path[i].p_hdr), ++ used * sizeof(struct ext4_extent_idx)); ++ le16_add_cpu(&path[i].p_hdr->eh_entries, -used); ++ le16_add_cpu(&npath[i].p_hdr->eh_entries, used); ++ err = ext4_ext_dirty(handle, inode, path + i); ++ if (err) ++ return err; ++ err = ext4_ext_dirty(handle, inode, npath + i); ++ if (err) ++ return err; ++ ++ /* correct index above */ ++ for (k = i; k > 0; k--) { ++ err = ext4_ext_get_access(handle, inode, npath + k - 1); ++ if (err) ++ return err; ++ npath[k-1].p_idx->ei_block = ++ EXT_FIRST_INDEX(npath[k].p_hdr)->ei_block; ++ err = ext4_ext_dirty(handle, inode, npath + k - 1); ++ if (err) ++ return err; ++ } ++ } ++ ++ /* ++ * TODO: given we've got two paths, it should be possible to ++ * collapse those two blocks into the root one in some cases ++ */ ++ return 1; ++} ++ ++static int ext4_ext_try_to_merge_blocks(handle_t *handle, ++ struct inode *inode, ++ struct ext4_ext_path *path) ++{ ++ struct ext4_ext_path *npath = NULL; ++ unsigned int depth = ext_depth(inode); ++ ext4_lblk_t next; ++ int used, rc = 0; ++ ++ if (depth == 0) ++ return 0; ++ ++ used = le16_to_cpu(path[depth].p_hdr->eh_entries); ++ /* XXX: think of a good value here */ ++ if (used > 100) ++ return 0; ++ ++ /* try to merge to the next block */ ++ next = ext4_ext_next_leaf_block(path); ++ if (next == EXT_MAX_BLOCKS) ++ return 0; ++ npath = ext4_ext_find_extent(inode, next, NULL, 0); ++ if (IS_ERR(npath)) ++ return 0; ++ rc = ext4_ext_merge_blocks(handle, inode, path, npath); ++ ext4_ext_drop_refs(npath); ++ kfree(npath); ++ if (rc) ++ return rc > 0 ? 0 : rc; ++ ++ /* try to merge with the previous block */ ++ if (EXT_FIRST_EXTENT(path[depth].p_hdr)->ee_block == 0) ++ return 0; ++ next = EXT_FIRST_EXTENT(path[depth].p_hdr)->ee_block - 1; ++ npath = ext4_ext_find_extent(inode, next, NULL, 0); ++ if (IS_ERR(npath)) ++ return 0; ++ rc = ext4_ext_merge_blocks(handle, inode, npath, path); ++ ext4_ext_drop_refs(npath); ++ kfree(npath); ++ return rc > 0 ? 0 : rc; + } + + /* +@@ -1979,6 +2205,7 @@ int ext4_ext_insert_extent(handle_t * + int depth, len, err; + ext4_lblk_t next; + int mb_flags = 0, unwritten; ++ int merged = 0; + + if (gb_flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) + mb_flags |= EXT4_MB_DELALLOC_RESERVED; +@@ -2172,8 +2399,7 @@ has_space: + merge: + /* try to merge extents */ + if (!(gb_flags & EXT4_GET_BLOCKS_PRE_IO)) +- ext4_ext_try_to_merge(handle, inode, path, nearex); +- ++ merged = ext4_ext_try_to_merge(handle, inode, path, nearex); + + /* time to correct all indexes above */ + err = ext4_ext_correct_indexes(handle, inode, path); +@@ -2181,6 +2407,8 @@ merge: + goto cleanup; + + err = ext4_ext_dirty(handle, inode, path + path->p_depth); ++ if (!err && merged) ++ err = ext4_ext_try_to_merge_blocks(handle, inode, path); + + cleanup: + ext4_ext_drop_refs(npath); diff --git a/ldiskfs/kernel_patches/patches/rhel8/ext4-ext-merge.patch b/ldiskfs/kernel_patches/patches/rhel8/ext4-ext-merge.patch new file mode 100644 index 0000000..3d70d6b --- /dev/null +++ b/ldiskfs/kernel_patches/patches/rhel8/ext4-ext-merge.patch @@ -0,0 +1,219 @@ +Index: linux-4.18.0-80.1.2.el8_0/fs/ext4/extents.c +=================================================================== +--- linux-4.18.0-80.1.2.el8_0.orig/fs/ext4/extents.c ++++ linux-4.18.0-80.1.2.el8_0/fs/ext4/extents.c +@@ -1888,7 +1944,7 @@ static void ext4_ext_try_to_merge_up( + * This function tries to merge the @ex extent to neighbours in the tree, then + * tries to collapse the extent tree into the inode. + */ +-static void ext4_ext_try_to_merge(handle_t *handle, ++static int ext4_ext_try_to_merge(handle_t *handle, + struct inode *inode, + struct ext4_ext_path *path, + struct ext4_extent *ex) +@@ -1905,9 +1961,177 @@ static void ext4_ext_try_to_merge(han + merge_done = ext4_ext_try_to_merge_right(inode, path, ex - 1); + + if (!merge_done) +- (void) ext4_ext_try_to_merge_right(inode, path, ex); ++ merge_done = ext4_ext_try_to_merge_right(inode, path, ex); + + ext4_ext_try_to_merge_up(handle, inode, path); ++ ++ return merge_done; ++} ++ ++/* ++ * This function tries to merge blocks from @path into @npath ++ */ ++static int ext4_ext_merge_blocks(handle_t *handle, ++ struct inode *inode, ++ struct ext4_ext_path *path, ++ struct ext4_ext_path *npath) ++{ ++ unsigned int depth = ext_depth(inode); ++ int used, nused, free, i, k, err; ++ ext4_lblk_t next; ++ ++ if (path[depth].p_hdr == npath[depth].p_hdr) ++ return 0; ++ ++ used = le16_to_cpu(path[depth].p_hdr->eh_entries); ++ free = le16_to_cpu(npath[depth].p_hdr->eh_max) - ++ le16_to_cpu(npath[depth].p_hdr->eh_entries); ++ if (free < used) ++ return 0; ++ ++ err = ext4_ext_get_access(handle, inode, path + depth); ++ if (err) ++ return err; ++ err = ext4_ext_get_access(handle, inode, npath + depth); ++ if (err) ++ return err; ++ ++ /* move entries from the current leave to the next one */ ++ nused = le16_to_cpu(npath[depth].p_hdr->eh_entries); ++ memmove(EXT_FIRST_EXTENT(npath[depth].p_hdr) + used, ++ EXT_FIRST_EXTENT(npath[depth].p_hdr), ++ nused * sizeof(struct ext4_extent)); ++ memcpy(EXT_FIRST_EXTENT(npath[depth].p_hdr), ++ EXT_FIRST_EXTENT(path[depth].p_hdr), ++ used * sizeof(struct ext4_extent)); ++ le16_add_cpu(&npath[depth].p_hdr->eh_entries, used); ++ le16_add_cpu(&path[depth].p_hdr->eh_entries, -used); ++ ext4_ext_try_to_merge_right(inode, npath, ++ EXT_FIRST_EXTENT(npath[depth].p_hdr)); ++ ++ err = ext4_ext_dirty(handle, inode, path + depth); ++ if (err) ++ return err; ++ err = ext4_ext_dirty(handle, inode, npath + depth); ++ if (err) ++ return err; ++ ++ /* otherwise the index won't get corrected */ ++ npath[depth].p_ext = EXT_FIRST_EXTENT(npath[depth].p_hdr); ++ err = ext4_ext_correct_indexes(handle, inode, npath); ++ if (err) ++ return err; ++ ++ for (i = depth - 1; i >= 0; i--) { ++ ++ next = ext4_idx_pblock(path[i].p_idx); ++ ext4_free_blocks(handle, inode, NULL, next, 1, ++ EXT4_FREE_BLOCKS_METADATA | ++ EXT4_FREE_BLOCKS_FORGET); ++ err = ext4_ext_get_access(handle, inode, path + i); ++ if (err) ++ return err; ++ le16_add_cpu(&path[i].p_hdr->eh_entries, -1); ++ if (le16_to_cpu(path[i].p_hdr->eh_entries) == 0) { ++ /* whole index block collapsed, go up */ ++ continue; ++ } ++ /* remove index pointer */ ++ used = EXT_LAST_INDEX(path[i].p_hdr) - path[i].p_idx + 1; ++ memmove(path[i].p_idx, path[i].p_idx + 1, ++ used * sizeof(struct ext4_extent_idx)); ++ ++ err = ext4_ext_dirty(handle, inode, path + i); ++ if (err) ++ return err; ++ ++ if (path[i].p_hdr == npath[i].p_hdr) ++ break; ++ ++ /* try to move index pointers */ ++ used = le16_to_cpu(path[i].p_hdr->eh_entries); ++ free = le16_to_cpu(npath[i].p_hdr->eh_max) - ++ le16_to_cpu(npath[i].p_hdr->eh_entries); ++ if (used > free) ++ break; ++ err = ext4_ext_get_access(handle, inode, npath + i); ++ if (err) ++ return err; ++ memmove(EXT_FIRST_INDEX(npath[i].p_hdr) + used, ++ EXT_FIRST_INDEX(npath[i].p_hdr), ++ npath[i].p_hdr->eh_entries * sizeof(struct ext4_extent_idx)); ++ memcpy(EXT_FIRST_INDEX(npath[i].p_hdr), EXT_FIRST_INDEX(path[i].p_hdr), ++ used * sizeof(struct ext4_extent_idx)); ++ le16_add_cpu(&path[i].p_hdr->eh_entries, -used); ++ le16_add_cpu(&npath[i].p_hdr->eh_entries, used); ++ err = ext4_ext_dirty(handle, inode, path + i); ++ if (err) ++ return err; ++ err = ext4_ext_dirty(handle, inode, npath + i); ++ if (err) ++ return err; ++ ++ /* correct index above */ ++ for (k = i; k > 0; k--) { ++ err = ext4_ext_get_access(handle, inode, npath + k - 1); ++ if (err) ++ return err; ++ npath[k-1].p_idx->ei_block = ++ EXT_FIRST_INDEX(npath[k].p_hdr)->ei_block; ++ err = ext4_ext_dirty(handle, inode, npath + k - 1); ++ if (err) ++ return err; ++ } ++ } ++ ++ /* ++ * TODO: given we've got two paths, it should be possible to ++ * collapse those two blocks into the root one in some cases ++ */ ++ return 1; ++} ++ ++static int ext4_ext_try_to_merge_blocks(handle_t *handle, ++ struct inode *inode, ++ struct ext4_ext_path *path) ++{ ++ struct ext4_ext_path *npath = NULL; ++ unsigned int depth = ext_depth(inode); ++ ext4_lblk_t next; ++ int used, rc = 0; ++ ++ if (depth == 0) ++ return 0; ++ ++ used = le16_to_cpu(path[depth].p_hdr->eh_entries); ++ /* XXX: think of a good value here */ ++ if (used > 100) ++ return 0; ++ ++ /* try to merge to the next block */ ++ next = ext4_ext_next_leaf_block(path); ++ if (next == EXT_MAX_BLOCKS) ++ return 0; ++ npath = ext4_find_extent(inode, next, NULL, 0); ++ if (IS_ERR(npath)) ++ return 0; ++ rc = ext4_ext_merge_blocks(handle, inode, path, npath); ++ ext4_ext_drop_refs(npath); ++ kfree(npath); ++ if (rc) ++ return rc > 0 ? 0 : rc; ++ ++ /* try to merge with the previous block */ ++ if (EXT_FIRST_EXTENT(path[depth].p_hdr)->ee_block == 0) ++ return 0; ++ next = EXT_FIRST_EXTENT(path[depth].p_hdr)->ee_block - 1; ++ npath = ext4_find_extent(inode, next, NULL, 0); ++ if (IS_ERR(npath)) ++ return 0; ++ rc = ext4_ext_merge_blocks(handle, inode, npath, path); ++ ext4_ext_drop_refs(npath); ++ kfree(npath); ++ return rc > 0 ? 0 : rc; + } + + /* +@@ -1979,6 +2205,7 @@ int ext4_ext_insert_extent(handle_t * + int depth, len, err; + ext4_lblk_t next; + int mb_flags = 0, unwritten; ++ int merged = 0; + + if (gb_flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) + mb_flags |= EXT4_MB_DELALLOC_RESERVED; +@@ -2172,8 +2399,7 @@ has_space: + merge: + /* try to merge extents */ + if (!(gb_flags & EXT4_GET_BLOCKS_PRE_IO)) +- ext4_ext_try_to_merge(handle, inode, path, nearex); +- ++ merged = ext4_ext_try_to_merge(handle, inode, path, nearex); + + /* time to correct all indexes above */ + err = ext4_ext_correct_indexes(handle, inode, path); +@@ -2181,6 +2407,8 @@ merge: + goto cleanup; + + err = ext4_ext_dirty(handle, inode, path + path->p_depth); ++ if (!err && merged) ++ err = ext4_ext_try_to_merge_blocks(handle, inode, path); + + cleanup: + ext4_ext_drop_refs(npath); diff --git a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.6.series b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.6.series index 5347bf1..eb17732 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.6.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.6.series @@ -54,3 +54,4 @@ rhel7.9/ext4-enc-flag.patch rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch rhel7.6/ext4-projid-xattrs.patch rhel7.9/ext4-filename-encode.patch +rhel7.9/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.7.series b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.7.series index e2f62b7..6cdfa29 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.7.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.7.series @@ -54,3 +54,4 @@ rhel7.9/ext4-enc-flag.patch rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch rhel7.6/ext4-projid-xattrs.patch rhel7.9/ext4-filename-encode.patch +rhel7.9/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.8.series b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.8.series index 696fd84..6fa0dc3 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.8.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.8.series @@ -46,3 +46,4 @@ rhel7.9/ext4-enc-flag.patch rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch rhel7.6/ext4-projid-xattrs.patch rhel7.9/ext4-filename-encode.patch +rhel7.9/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.9.series b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.9.series index fcef984..ee89365 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.9.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.9.series @@ -46,3 +46,4 @@ rhel7.9/ext4-enc-flag.patch rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch rhel7.6/ext4-projid-xattrs.patch rhel7.9/ext4-filename-encode.patch +rhel7.9/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15-22.series b/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15-22.series index e8a8420..42d8bcf 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15-22.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15-22.series @@ -28,3 +28,4 @@ suse15/ext4-export-mb-stream-allocator-variables.patch base/ext4-no-max-dir-size-limit-for-iam-objects.patch rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch base/ext4-projid-xattrs.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15.series b/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15.series index c731d36..088df6e 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15.series @@ -28,3 +28,4 @@ suse15/ext4-export-mb-stream-allocator-variables.patch base/ext4-no-max-dir-size-limit-for-iam-objects.patch rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch base/ext4-projid-xattrs.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15sp1-7.series b/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15sp1-7.series index e8a8420..42d8bcf 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15sp1-7.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15sp1-7.series @@ -28,3 +28,4 @@ suse15/ext4-export-mb-stream-allocator-variables.patch base/ext4-no-max-dir-size-limit-for-iam-objects.patch rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch base/ext4-projid-xattrs.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15sp1.series b/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15sp1.series index a51161a..4ccd79d 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15sp1.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.12-sles15sp1.series @@ -28,3 +28,4 @@ suse15/ext4-export-mb-stream-allocator-variables.patch base/ext4-no-max-dir-size-limit-for-iam-objects.patch rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch base/ext4-projid-xattrs.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.15.0-20-ubuntu18.series b/ldiskfs/kernel_patches/series/ldiskfs-4.15.0-20-ubuntu18.series index f345f82..e0ca387 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.15.0-20-ubuntu18.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.15.0-20-ubuntu18.series @@ -25,3 +25,4 @@ ubuntu18/ext4-include-terminating-u32-in-size-of-xattr-entries-when-expanding-in base/ext4-no-max-dir-size-limit-for-iam-objects.patch rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch ubuntu18/ext4-projid-xattrs.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.15.0-24-ubuntu18.series b/ldiskfs/kernel_patches/series/ldiskfs-4.15.0-24-ubuntu18.series index 2350afa..0794695 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.15.0-24-ubuntu18.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.15.0-24-ubuntu18.series @@ -26,3 +26,4 @@ suse15/ext4-export-mb-stream-allocator-variables.patch base/ext4-no-max-dir-size-limit-for-iam-objects.patch rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch ubuntu18/ext4-projid-xattrs.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.1.series b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.1.series index b62a740..79edfad 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.1.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.1.series @@ -31,3 +31,4 @@ rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch base/ext4-projid-xattrs.patch rhel8/ext4-filename-encode.patch base/ext4-delayed-iput.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.2.series b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.2.series index 5e7b1ea..c07c366 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.2.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.2.series @@ -31,3 +31,4 @@ rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch base/ext4-projid-xattrs.patch rhel8/ext4-filename-encode.patch base/ext4-delayed-iput.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.3.series b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.3.series index eac24a6..fe64216 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.3.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.3.series @@ -31,3 +31,4 @@ rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch base/ext4-projid-xattrs.patch rhel8/ext4-filename-encode.patch base/ext4-delayed-iput.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.4.series b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.4.series index 11e3007..ccd43f6 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.4.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.4.series @@ -33,3 +33,4 @@ rhel8.5/ext4-filename-encode.patch rhel8/ext4-old_ea_inodes_handling_fix.patch rhel8.4/ext4-optimize-find_delayed_extent.patch base/ext4-delayed-iput.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.5.series b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.5.series index 5e92fa3..dd9e9bc 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.5.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.5.series @@ -34,3 +34,4 @@ rhel8.5/ext4-filename-encode.patch rhel8/ext4-old_ea_inodes_handling_fix.patch rhel8.4/ext4-optimize-find_delayed_extent.patch base/ext4-delayed-iput.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.6.series b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.6.series index 5e92fa3..dd9e9bc 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.6.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.6.series @@ -34,3 +34,4 @@ rhel8.5/ext4-filename-encode.patch rhel8/ext4-old_ea_inodes_handling_fix.patch rhel8.4/ext4-optimize-find_delayed_extent.patch base/ext4-delayed-iput.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.7.series b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.7.series index 7b71bc6..61d0b9a 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.7.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.7.series @@ -34,3 +34,4 @@ base/ext4-delayed-iput.patch rhel8.7/ext4-filename-encode.patch rhel8/ext4-old_ea_inodes_handling_fix.patch rhel8.4/ext4-optimize-find_delayed_extent.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.series b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.series index d794945..4a21c8d 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.series @@ -33,3 +33,4 @@ rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch ubuntu18/ext4-projid-xattrs.patch rhel8/ext4-filename-encode.patch base/ext4-delayed-iput.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.0.0-13-ubuntu19.series b/ldiskfs/kernel_patches/series/ldiskfs-5.0.0-13-ubuntu19.series index b3e7c73..b13c9e0 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.0.0-13-ubuntu19.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.0.0-13-ubuntu19.series @@ -26,3 +26,4 @@ rhel8/ext4-simple-blockalloc.patch base/ext4-no-max-dir-size-limit-for-iam-objects.patch rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch base/ext4-projid-xattrs.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-42-ubuntu20.series b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-42-ubuntu20.series index f5cb25c..594d266 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-42-ubuntu20.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-42-ubuntu20.series @@ -30,3 +30,4 @@ linux-5.4/ext4-enc-flag.patch rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch base/ext4-projid-xattrs.patch base/ext4-delayed-iput.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-66-ubuntu20.series b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-66-ubuntu20.series index 0d47ecf..0460cf4 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-66-ubuntu20.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-66-ubuntu20.series @@ -30,3 +30,4 @@ linux-5.4/ext4-enc-flag.patch rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch base/ext4-projid-xattrs.patch base/ext4-delayed-iput.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-ml.series b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-ml.series index a370d0d..1d96454 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-ml.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-ml.series @@ -30,3 +30,4 @@ linux-5.4/ext4-enc-flag.patch rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch base/ext4-projid-xattrs.patch base/ext4-delayed-iput.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.4.21-ml.series b/ldiskfs/kernel_patches/series/ldiskfs-5.4.21-ml.series index f5cb25c..594d266 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.4.21-ml.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.4.21-ml.series @@ -30,3 +30,4 @@ linux-5.4/ext4-enc-flag.patch rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch base/ext4-projid-xattrs.patch base/ext4-delayed-iput.patch +rhel8/ext4-ext-merge.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-ml.series b/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-ml.series index 579d789..8f7ef27 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-ml.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-ml.series @@ -28,3 +28,4 @@ linux-5.8/ext4-simple-blockalloc.patch linux-5.8/ext4-enc-flag.patch linux-5.8/ext4-no-max-dir-size-limit-for-iam-objects.patch base/ext4-projid-xattrs.patch +rhel8/ext4-ext-merge.patch -- 1.8.3.1