From f7b5f2f6145738b33a9fddc08c2b25c34e2f6be5 Mon Sep 17 00:00:00 2001 From: Alex Zhuravlev Date: Mon, 30 Oct 2023 13:16:49 +0300 Subject: [PATCH] EX-8369 ldiskfs: fix dense writes don't mix "dense" and regular writes as regular are bound to logical offsets. Fixes: f36eda6a1e ("LU-10026 osd-ldiskfs: use preallocation for dense writes") Signed-off-by: Alex Zhuravlev Change-Id: I9f6b2c600f2132dcad23726f2fb3848ab02cc117 Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/52888 Tested-by: jenkins Tested-by: Andreas Dilger Reviewed-by: Andreas Dilger --- .../patches/rhel8/ext4-mballoc-dense.patch | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/ldiskfs/kernel_patches/patches/rhel8/ext4-mballoc-dense.patch b/ldiskfs/kernel_patches/patches/rhel8/ext4-mballoc-dense.patch index b11f015..2956e04 100644 --- a/ldiskfs/kernel_patches/patches/rhel8/ext4-mballoc-dense.patch +++ b/ldiskfs/kernel_patches/patches/rhel8/ext4-mballoc-dense.patch @@ -1,10 +1,11 @@ --- linux-4.18.0-80.1.2.el8_0.orig/fs/ext4/mballoc.h +++ linux-4.18.0-80.1.2.el8_0/fs/ext4/mballoc.h -@@ -131,6 +131,7 @@ enum SHIFT_DIRECTION { +@@ -131,6 +131,8 @@ enum SHIFT_DIRECTION { ext4_lblk_t pa_lstart; /* log. block */ ext4_grpblk_t pa_len; /* len of preallocated chunk */ ext4_grpblk_t pa_free; /* how many blocks are free */ + ext4_grpblk_t pa_group; ++ unsigned short pa_regular; unsigned short pa_type; /* pa type. inode or group */ unsigned short pa_error; spinlock_t *pa_obj_lock; @@ -39,17 +40,20 @@ if (flags & EXT4_GET_BLOCKS_METADATA_NOFAIL) --- linux-4.18.0-80.1.2.el8_0.orig/fs/ext4/mballoc.c +++ linux-4.18.0-80.1.2.el8_0/fs/ext4/mballoc.c -@@ -4267,6 +4291,21 @@ ext4_mb_use_inode_pa(struct ext4 +@@ -4267,6 +4291,25 @@ ext4_mb_use_inode_pa(struct ext4 ext4_fsblk_t end; int len; -+ if (ac->ac_flags & EXT4_MB_VERY_DENSE) { ++ if (ac->ac_flags & EXT4_MB_VERY_DENSE && !pa->pa_regular) { + unsigned int len = ac->ac_o_ex.fe_len; ++ if (len > pa->pa_free) ++ len = pa->pa_free; + ext4_get_group_no_and_offset(ac->ac_sb, + pa->pa_pstart, + &ac->ac_b_ex.fe_group, + &ac->ac_b_ex.fe_start); + ac->ac_b_ex.fe_len = len; ++ pa->pa_lstart += len; + pa->pa_pstart += len; + pa->pa_free -= len; + pa->pa_len -= len; @@ -58,19 +62,19 @@ + return; + } + ++ pa->pa_regular = 1; /* found preallocated blocks, use them */ start = pa->pa_pstart + (ac->ac_o_ex.fe_logical - pa->pa_lstart); end = min(pa->pa_pstart + EXT4_C2B(sbi, pa->pa_len), -@@ -4367,6 +4380,24 @@ ext4_mb_use_preallocated(struct ext4 +@@ -4367,6 +4380,23 @@ ext4_mb_use_preallocated(struct ext4 if (!(ac->ac_flags & EXT4_MB_HINT_DATA)) return false; + if (ac->ac_flags & EXT4_MB_VERY_DENSE) { -+ unsigned int len = ac->ac_o_ex.fe_len; + rcu_read_lock(); + list_for_each_entry_rcu(pa, &ei->i_prealloc_list, pa_inode_list) { + spin_lock(&pa->pa_lock); -+ if (pa->pa_deleted == 0 && len <= pa->pa_free) { ++ if (!pa->pa_deleted && pa->pa_free && !pa->pa_regular) { + atomic_inc(&pa->pa_count); + ext4_mb_use_inode_pa(ac, pa); + spin_unlock(&pa->pa_lock); @@ -95,11 +99,12 @@ /* * possible race: -@@ -4894,6 +4894,7 @@ ext4_mb_new_inode_pa(struct ext4 +@@ -4894,6 +4894,8 @@ ext4_mb_new_inode_pa(struct ext4 pa->pa_pstart = ext4_grp_offs_to_block(sb, &ac->ac_b_ex); pa->pa_len = ac->ac_b_ex.fe_len; pa->pa_free = pa->pa_len; + pa->pa_group = ac->ac_b_ex.fe_group; ++ pa->pa_regular = 0; spin_lock_init(&pa->pa_lock); INIT_LIST_HEAD(&pa->pa_inode_list); INIT_LIST_HEAD(&pa->pa_group_list); -- 1.8.3.1