Whamcloud - gitweb
EX-8369 ldiskfs: fix dense writes
authorAlex Zhuravlev <bzzz@whamcloud.com>
Mon, 30 Oct 2023 10:16:49 +0000 (13:16 +0300)
committerAndreas Dilger <adilger@whamcloud.com>
Thu, 9 Nov 2023 08:37:56 +0000 (08:37 +0000)
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 <bzzz@whamcloud.com>
Change-Id: I9f6b2c600f2132dcad23726f2fb3848ab02cc117
Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/52888
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
ldiskfs/kernel_patches/patches/rhel8/ext4-mballoc-dense.patch

index b11f015..2956e04 100644 (file)
@@ -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;
        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;
 +              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);
 
        /*
         * 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);