diff --git a/0062-ldiskfs-fix-build-for-oe2203sp3.patch b/0062-ldiskfs-fix-build-for-oe2203sp3.patch new file mode 100644 index 0000000000000000000000000000000000000000..88f2b3ac3249f6138a8ecd31694598886d2450b0 --- /dev/null +++ b/0062-ldiskfs-fix-build-for-oe2203sp3.patch @@ -0,0 +1,1151 @@ +From 3e677b9e42a412b2445ed738113860a580497290 Mon Sep 17 00:00:00 2001 +From: Xinliang Liu +Date: Tue, 28 Nov 2023 07:53:08 +0000 +Subject: [PATCH] ldiskfs: fix build for oe2203sp3 + +Update ldiskfs patch for oe2203sp3 for new kernel +5.10.0-171.0.0.84.oe2203sp3. + +Signed-off-by: Xinliang Liu +--- + .../oe2203sp3/ext4-mballoc-extra-checks.patch | 320 ++++++++++++++ + .../patches/oe2203sp3/ext4-prealloc.patch | 404 ++++++++++++++++++ + .../oe2203sp3/ext4-simple-blockalloc.patch | 361 ++++++++++++++++ + .../series/ldiskfs-5.10.0-oe2203sp1.series | 6 +- + 4 files changed, 1088 insertions(+), 3 deletions(-) + create mode 100644 ldiskfs/kernel_patches/patches/oe2203sp3/ext4-mballoc-extra-checks.patch + create mode 100644 ldiskfs/kernel_patches/patches/oe2203sp3/ext4-prealloc.patch + create mode 100644 ldiskfs/kernel_patches/patches/oe2203sp3/ext4-simple-blockalloc.patch + +diff --git a/ldiskfs/kernel_patches/patches/oe2203sp3/ext4-mballoc-extra-checks.patch b/ldiskfs/kernel_patches/patches/oe2203sp3/ext4-mballoc-extra-checks.patch +new file mode 100644 +index 0000000000..09f2a49586 +--- /dev/null ++++ b/ldiskfs/kernel_patches/patches/oe2203sp3/ext4-mballoc-extra-checks.patch +@@ -0,0 +1,320 @@ ++From 3b61206118f2a731016a3a113b7c2333843dd436 Mon Sep 17 00:00:00 2001 ++From: Xinliang Liu ++Date: Mon, 27 Nov 2023 08:23:12 +0000 ++Subject: [PATCH] ext4: mballoc extra checks ++ ++Signed-off-by: Xinliang Liu ++--- ++ fs/ext4/ext4.h | 1 + ++ fs/ext4/mballoc.c | 105 ++++++++++++++++++++++++++++++++++++++++------ ++ fs/ext4/mballoc.h | 2 +- ++ 3 files changed, 94 insertions(+), 14 deletions(-) ++ ++diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h ++index 26180ca..fd8d3a3 100644 ++--- a/fs/ext4/ext4.h +++++ b/fs/ext4/ext4.h ++@@ -3343,6 +3343,7 @@ struct ext4_group_info { ++ ext4_grpblk_t bb_fragments; /* nr of freespace fragments */ ++ ext4_grpblk_t bb_largest_free_order;/* order of largest frag in BG */ ++ struct list_head bb_prealloc_list; +++ unsigned long bb_prealloc_nr; ++ #ifdef DOUBLE_CHECK ++ void *bb_bitmap; ++ #endif ++diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c ++index a7b5eb7..4f40602 100644 ++--- a/fs/ext4/mballoc.c +++++ b/fs/ext4/mballoc.c ++@@ -345,7 +345,7 @@ static const char * const ext4_groupinfo_slab_names[NR_GRPINFO_CACHES] = { ++ "ext4_groupinfo_64k", "ext4_groupinfo_128k" ++ }; ++ ++-static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, +++static int ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, ++ ext4_group_t group); ++ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, ++ ext4_group_t group); ++@@ -768,7 +768,7 @@ mb_set_largest_free_order(struct super_block *sb, struct ext4_group_info *grp) ++ } ++ ++ static noinline_for_stack ++-void ext4_mb_generate_buddy(struct super_block *sb, +++int ext4_mb_generate_buddy(struct super_block *sb, ++ void *buddy, void *bitmap, ext4_group_t group, ++ struct ext4_group_info *grp) ++ { ++@@ -812,6 +812,7 @@ void ext4_mb_generate_buddy(struct super_block *sb, ++ grp->bb_free = free; ++ ext4_mark_group_bitmap_corrupted(sb, group, ++ EXT4_GROUP_INFO_BBITMAP_CORRUPT); +++ return -EIO; ++ } ++ mb_set_largest_free_order(sb, grp); ++ ++@@ -820,6 +821,8 @@ void ext4_mb_generate_buddy(struct super_block *sb, ++ period = get_cycles() - period; ++ atomic_inc(&sbi->s_mb_buddies_generated); ++ atomic64_add(period, &sbi->s_mb_generation_time); +++ +++ return 0; ++ } ++ ++ /* The buddy information is attached the buddy cache inode ++@@ -924,7 +927,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore, gfp_t gfp) ++ } ++ ++ first_block = page->index * blocks_per_page; ++- for (i = 0; i < blocks_per_page; i++) { +++ for (i = 0; i < blocks_per_page && err == 0; i++) { ++ group = (first_block + i) >> 1; ++ if (group >= ngroups) ++ break; ++@@ -972,7 +975,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore, gfp_t gfp) ++ ext4_lock_group(sb, group); ++ /* init the buddy */ ++ memset(data, 0xff, blocksize); ++- ext4_mb_generate_buddy(sb, data, incore, group, grinfo); +++ err = ext4_mb_generate_buddy(sb, data, incore, group, grinfo); ++ ext4_unlock_group(sb, group); ++ incore = NULL; ++ } else { ++@@ -987,7 +990,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore, gfp_t gfp) ++ memcpy(data, bitmap, blocksize); ++ ++ /* mark all preallocated blks used in in-core bitmap */ ++- ext4_mb_generate_from_pa(sb, data, group); +++ err = ext4_mb_generate_from_pa(sb, data, group); ++ ext4_mb_generate_from_freelist(sb, data, group); ++ ext4_unlock_group(sb, group); ++ ++@@ -997,7 +1000,8 @@ static int ext4_mb_init_cache(struct page *page, char *incore, gfp_t gfp) ++ incore = data; ++ } ++ } ++- SetPageUptodate(page); +++ if (likely(err == 0)) +++ SetPageUptodate(page); ++ ++ out: ++ if (bh) { ++@@ -2519,9 +2523,11 @@ static void *ext4_mb_seq_groups_next(struct seq_file *seq, void *v, loff_t *pos) ++ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v) ++ { ++ struct super_block *sb = PDE_DATA(file_inode(seq->file)); +++ struct ext4_group_desc *gdp; ++ ext4_group_t group = (ext4_group_t) ((unsigned long) v); ++ int i; ++ int err, buddy_loaded = 0; +++ int free = 0; ++ struct ext4_buddy e4b; ++ struct ext4_group_info *grinfo; ++ unsigned char blocksize_bits = min_t(unsigned char, ++@@ -2534,7 +2540,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v) ++ ++ group--; ++ if (group == 0) ++- seq_puts(seq, "#group: free frags first [" +++ seq_puts(seq, "#group: bfree gfree frags first pa [" ++ " 2^0 2^1 2^2 2^3 2^4 2^5 2^6 " ++ " 2^7 2^8 2^9 2^10 2^11 2^12 2^13 ]\n"); ++ ++@@ -2554,13 +2560,19 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v) ++ buddy_loaded = 1; ++ } ++ +++ gdp = ext4_get_group_desc(sb, group, NULL); +++ if (gdp != NULL) +++ free = ext4_free_group_clusters(sb, gdp); +++ ++ memcpy(&sg, grinfo, i); ++ ++ if (buddy_loaded) ++ ext4_mb_unload_buddy(&e4b); ++ ++- seq_printf(seq, "#%-5u: %-5u %-5u %-5u [", group, sg.info.bb_free, ++- sg.info.bb_fragments, sg.info.bb_first_free); +++ seq_printf(seq, "#%-5lu: %-5u %-5u %-5u %-5u %-5lu [", +++ (long unsigned int)group, sg.info.bb_free, free, +++ sg.info.bb_fragments, sg.info.bb_first_free, +++ sg.info.bb_prealloc_nr); ++ for (i = 0; i <= 13; i++) ++ seq_printf(seq, " %-5u", i <= blocksize_bits + 1 ? ++ sg.info.bb_counters[i] : 0); ++@@ -4097,25 +4109,74 @@ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, ++ return; ++ } ++ +++/* +++ * check free blocks in bitmap match free block in group descriptor +++ * do this before taking preallocated blocks into account to be able +++ * to detect on-disk corruptions. The group lock should be hold by the +++ * caller. +++ */ +++int ext4_mb_check_ondisk_bitmap(struct super_block *sb, void *bitmap, +++ struct ext4_group_desc *gdp, int group) +++{ +++ unsigned short max = EXT4_CLUSTERS_PER_GROUP(sb); +++ unsigned short i, first, free = 0; +++ unsigned short free_in_gdp = ext4_free_group_clusters(sb, gdp); +++ +++ if (free_in_gdp == 0 && gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) +++ return 0; +++ +++ i = mb_find_next_zero_bit(bitmap, max, 0); +++ +++ while (i < max) { +++ first = i; +++ i = mb_find_next_bit(bitmap, max, i); +++ if (i > max) +++ i = max; +++ free += i - first; +++ if (i < max) +++ i = mb_find_next_zero_bit(bitmap, max, i); +++ } +++ +++ if (free != free_in_gdp) { +++ ext4_error(sb, "on-disk bitmap for group %d" +++ "corrupted: %u blocks free in bitmap, %u - in gd\n", +++ group, free, free_in_gdp); +++ return -EIO; +++ } +++ return 0; +++} +++ ++ /* ++ * the function goes through all preallocation in this group and marks them ++ * used in in-core bitmap. buddy must be generated from this bitmap ++ * Need to be called with ext4 group lock held ++ */ ++ static noinline_for_stack ++-void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, +++int ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, ++ ext4_group_t group) ++ { ++ struct ext4_group_info *grp = ext4_get_group_info(sb, group); ++ struct ext4_prealloc_space *pa; +++ struct ext4_group_desc *gdp; ++ struct list_head *cur; ++ ext4_group_t groupnr; ++ ext4_grpblk_t start; ++ int preallocated = 0; +++ int skip = 0, count = 0; +++ int err; ++ int len; ++ ++ if (!grp) ++- return; +++ return -EIO; +++ +++ gdp = ext4_get_group_desc(sb, group, NULL); +++ if (gdp == NULL) +++ return -EIO; +++ +++ /* before applying preallocations, check bitmap consistency */ +++ err = ext4_mb_check_ondisk_bitmap(sb, bitmap, gdp, group); +++ if (err) +++ return err; ++ ++ /* all form of preallocation discards first load group, ++ * so the only competing code is preallocation use. ++@@ -4132,13 +4193,23 @@ void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, ++ &groupnr, &start); ++ len = pa->pa_len; ++ spin_unlock(&pa->pa_lock); ++- if (unlikely(len == 0)) +++ if (unlikely(len == 0)) { +++ skip++; ++ continue; +++ } ++ BUG_ON(groupnr != group); ++ ext4_set_bits(bitmap, start, len); ++ preallocated += len; +++ count++; +++ } +++ if (count + skip != grp->bb_prealloc_nr) { +++ ext4_error(sb, "lost preallocations: " +++ "count %d, bb_prealloc_nr %lu, skip %d\n", +++ count, grp->bb_prealloc_nr, skip); +++ return -EIO; ++ } ++ mb_debug(sb, "preallocated %d for group %u\n", preallocated, group); +++ return 0; ++ } ++ ++ static void ext4_mb_mark_pa_deleted(struct super_block *sb, ++@@ -4222,6 +4293,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, ++ */ ++ ext4_lock_group(sb, grp); ++ list_del(&pa->pa_group_list); +++ ext4_get_group_info(sb, grp)->bb_prealloc_nr--; ++ ext4_unlock_group(sb, grp); ++ ++ spin_lock(pa->pa_obj_lock); ++@@ -4327,6 +4399,7 @@ adjust_bex: ++ pa->pa_inode = ac->ac_inode; ++ ++ list_add(&pa->pa_group_list, &grp->bb_prealloc_list); +++ grp->bb_prealloc_nr++; ++ ++ spin_lock(pa->pa_obj_lock); ++ list_add_rcu(&pa->pa_inode_list, &ei->i_prealloc_list); ++@@ -4384,6 +4457,7 @@ ext4_mb_new_group_pa(struct ext4_allocation_context *ac) ++ pa->pa_inode = NULL; ++ ++ list_add(&pa->pa_group_list, &grp->bb_prealloc_list); +++ grp->bb_prealloc_nr++; ++ ++ /* ++ * We will later add the new pa to the right bucket ++@@ -4554,6 +4628,8 @@ ext4_mb_discard_group_preallocations(struct super_block *sb, ++ ++ spin_unlock(&pa->pa_lock); ++ +++ BUG_ON(grp->bb_prealloc_nr == 0); +++ grp->bb_prealloc_nr--; ++ list_del(&pa->pa_group_list); ++ list_add(&pa->u.pa_tmp_list, &list); ++ } ++@@ -4681,7 +4757,7 @@ repeat: ++ if (err) { ++ ext4_error_err(sb, -err, "Error %d loading buddy information for %u", ++ err, group); ++- continue; +++ return; ++ } ++ ++ bitmap_bh = ext4_read_block_bitmap(sb, group); ++@@ -4694,6 +4770,8 @@ repeat: ++ } ++ ++ ext4_lock_group(sb, group); +++ BUG_ON(e4b.bd_info->bb_prealloc_nr == 0); +++ e4b.bd_info->bb_prealloc_nr--; ++ list_del(&pa->pa_group_list); ++ ext4_mb_release_inode_pa(&e4b, bitmap_bh, pa); ++ ext4_unlock_group(sb, group); ++@@ -4991,6 +5069,7 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb, ++ } ++ ext4_lock_group(sb, group); ++ list_del(&pa->pa_group_list); +++ ext4_get_group_info(sb, group)->bb_prealloc_nr--; ++ ext4_mb_release_group_pa(&e4b, pa); ++ ext4_unlock_group(sb, group); ++ ++diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h ++index 7be6288..448b2e8 100644 ++--- a/fs/ext4/mballoc.h +++++ b/fs/ext4/mballoc.h ++@@ -66,7 +66,7 @@ ++ /* ++ * for which requests use 2^N search using buddies ++ */ ++-#define MB_DEFAULT_ORDER2_REQS 2 +++#define MB_DEFAULT_ORDER2_REQS 8 ++ ++ /* ++ * default group prealloc size 512 blocks ++-- ++2.33.0 ++ +diff --git a/ldiskfs/kernel_patches/patches/oe2203sp3/ext4-prealloc.patch b/ldiskfs/kernel_patches/patches/oe2203sp3/ext4-prealloc.patch +new file mode 100644 +index 0000000000..bc64fdb084 +--- /dev/null ++++ b/ldiskfs/kernel_patches/patches/oe2203sp3/ext4-prealloc.patch +@@ -0,0 +1,404 @@ ++From e64e4f631ac4aaa7fbaa97bcae213d32cb8fd6e3 Mon Sep 17 00:00:00 2001 ++From: Xinliang Liu ++Date: Mon, 27 Nov 2023 03:23:32 +0000 ++Subject: [PATCH] ext4: prealloc ++ ++Signed-off-by: Xinliang Liu ++--- ++ fs/ext4/ext4.h | 7 +- ++ fs/ext4/inode.c | 3 + ++ fs/ext4/mballoc.c | 219 +++++++++++++++++++++++++++++++++++----------- ++ fs/ext4/sysfs.c | 8 +- ++ 4 files changed, 182 insertions(+), 55 deletions(-) ++ ++diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h ++index 9e7dfc4..8a7df09 100644 ++--- a/fs/ext4/ext4.h +++++ b/fs/ext4/ext4.h ++@@ -1299,6 +1299,8 @@ extern void ext4_set_bits(void *bm, int cur, int len); ++ /* Metadata checksum algorithm codes */ ++ #define EXT4_CRC32C_CHKSUM 1 ++ +++#define EXT4_MAX_PREALLOC_TABLE 64 +++ ++ /* ++ * Structure of the super block ++ */ ++@@ -1534,11 +1536,13 @@ struct ext4_sb_info { ++ ++ /* tunables */ ++ unsigned long s_stripe; ++- unsigned int s_mb_stream_request; +++ unsigned long s_mb_small_req; +++ unsigned long s_mb_large_req; ++ unsigned int s_mb_max_to_scan; ++ unsigned int s_mb_min_to_scan; ++ unsigned int s_mb_stats; ++ unsigned int s_mb_order2_reqs; +++ unsigned long *s_mb_prealloc_table; ++ unsigned int s_mb_group_prealloc; ++ unsigned int s_mb_max_inode_prealloc; ++ unsigned int s_max_dir_size_kb; ++@@ -2827,6 +2831,7 @@ int ext4_fc_record_regions(struct super_block *sb, int ino, ++ int len, int replay); ++ ++ /* mballoc.c */ +++extern const struct proc_ops ext4_seq_prealloc_table_fops; ++ extern const struct seq_operations ext4_mb_seq_groups_ops; ++ extern long ext4_mb_stats; ++ extern long ext4_mb_max_to_scan; ++diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c ++index b2aa0ed..bda409e 100644 ++--- a/fs/ext4/inode.c +++++ b/fs/ext4/inode.c ++@@ -2773,6 +2773,9 @@ static int ext4_writepages(struct address_space *mapping, ++ PAGE_SIZE >> inode->i_blkbits); ++ } ++ +++ if (wbc->nr_to_write < sbi->s_mb_small_req) +++ wbc->nr_to_write = sbi->s_mb_small_req; +++ ++ if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) ++ range_whole = 1; ++ ++diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c ++index 929fc42..a7b5eb7 100644 ++--- a/fs/ext4/mballoc.c +++++ b/fs/ext4/mballoc.c ++@@ -2641,6 +2641,99 @@ int ext4_seq_mb_stats_show(struct seq_file *seq, void *offset) ++ return 0; ++ } ++ +++static int ext4_mb_check_and_update_prealloc(struct ext4_sb_info *sbi, +++ char *str, size_t cnt, +++ int update) +++{ +++ unsigned long value; +++ unsigned long prev = 0; +++ char *cur; +++ char *next; +++ char *end; +++ int num = 0; +++ +++ cur = str; +++ end = str + cnt; +++ while (cur < end) { +++ while ((cur < end) && (*cur == ' ')) cur++; +++ value = simple_strtol(cur, &next, 0); +++ if (value == 0) +++ break; +++ if (cur == next) +++ return -EINVAL; +++ +++ cur = next; +++ +++ if (value > (sbi->s_blocks_per_group - 1 - 1 - sbi->s_itb_per_group)) +++ return -EINVAL; +++ +++ /* they should add values in order */ +++ if (value <= prev) +++ return -EINVAL; +++ +++ if (update) +++ sbi->s_mb_prealloc_table[num] = value; +++ +++ prev = value; +++ num++; +++ } +++ +++ if (num > EXT4_MAX_PREALLOC_TABLE - 1) +++ return -EOVERFLOW; +++ +++ if (update) +++ sbi->s_mb_prealloc_table[num] = 0; +++ +++ return 0; +++} +++ +++static ssize_t ext4_mb_prealloc_table_proc_write(struct file *file, +++ const char __user *buf, +++ size_t cnt, loff_t *pos) +++{ +++ struct ext4_sb_info *sbi = EXT4_SB(PDE_DATA(file_inode(file))); +++ char str[128]; +++ int rc; +++ +++ if (cnt >= sizeof(str)) +++ return -EINVAL; +++ if (copy_from_user(str, buf, cnt)) +++ return -EFAULT; +++ +++ rc = ext4_mb_check_and_update_prealloc(sbi, str, cnt, 0); +++ if (rc) +++ return rc; +++ +++ rc = ext4_mb_check_and_update_prealloc(sbi, str, cnt, 1); +++ return rc ? rc : cnt; +++} +++ +++static int mb_prealloc_table_seq_show(struct seq_file *m, void *v) +++{ +++ struct ext4_sb_info *sbi = EXT4_SB(m->private); +++ int i; +++ +++ for (i = 0; i < EXT4_MAX_PREALLOC_TABLE && +++ sbi->s_mb_prealloc_table[i] != 0; i++) +++ seq_printf(m, "%ld ", sbi->s_mb_prealloc_table[i]); +++ seq_printf(m, "\n"); +++ +++ return 0; +++} +++ +++static int mb_prealloc_table_seq_open(struct inode *inode, struct file *file) +++{ +++ return single_open(file, mb_prealloc_table_seq_show, PDE_DATA(inode)); +++} +++ +++const struct proc_ops ext4_seq_prealloc_table_fops = { +++ .proc_open = mb_prealloc_table_seq_open, +++ .proc_read = seq_read, +++ .proc_lseek = seq_lseek, +++ .proc_release = single_release, +++ .proc_write = ext4_mb_prealloc_table_proc_write, +++}; +++ ++ static struct kmem_cache *get_groupinfo_cache(int blocksize_bits) ++ { ++ int cache_index = blocksize_bits - EXT4_MIN_BLOCK_LOG_SIZE; ++@@ -2903,7 +2996,7 @@ static int ext4_groupinfo_create_slab(size_t size) ++ int ext4_mb_init(struct super_block *sb) ++ { ++ struct ext4_sb_info *sbi = EXT4_SB(sb); ++- unsigned i, j; +++ unsigned i, j, k, l; ++ unsigned offset, offset_incr; ++ unsigned max; ++ int ret; ++@@ -2951,7 +3044,6 @@ int ext4_mb_init(struct super_block *sb) ++ sbi->s_mb_max_to_scan = MB_DEFAULT_MAX_TO_SCAN; ++ sbi->s_mb_min_to_scan = MB_DEFAULT_MIN_TO_SCAN; ++ sbi->s_mb_stats = MB_DEFAULT_STATS; ++- sbi->s_mb_stream_request = MB_DEFAULT_STREAM_THRESHOLD; ++ sbi->s_mb_order2_reqs = MB_DEFAULT_ORDER2_REQS; ++ sbi->s_mb_max_inode_prealloc = MB_DEFAULT_MAX_INODE_PREALLOC; ++ /* ++@@ -2976,9 +3068,29 @@ int ext4_mb_init(struct super_block *sb) ++ * RAID stripe size so that preallocations don't fragment ++ * the stripes. ++ */ ++- if (sbi->s_stripe > 1) { ++- sbi->s_mb_group_prealloc = roundup( ++- sbi->s_mb_group_prealloc, sbi->s_stripe); +++ +++ /* Allocate table once */ +++ sbi->s_mb_prealloc_table = kzalloc( +++ EXT4_MAX_PREALLOC_TABLE * sizeof(unsigned long), GFP_NOFS); +++ if (sbi->s_mb_prealloc_table == NULL) { +++ ret = -ENOMEM; +++ goto out; +++ } +++ +++ if (sbi->s_stripe == 0) { +++ for (k = 0, l = 4; k <= 9; ++k, l *= 2) +++ sbi->s_mb_prealloc_table[k] = l; +++ +++ sbi->s_mb_small_req = 256; +++ sbi->s_mb_large_req = 1024; +++ sbi->s_mb_group_prealloc = 512; +++ } else { +++ for (k = 0, l = sbi->s_stripe; k <= 2; ++k, l *= 2) +++ sbi->s_mb_prealloc_table[k] = l; +++ +++ sbi->s_mb_small_req = sbi->s_stripe; +++ sbi->s_mb_large_req = sbi->s_stripe * 8; +++ sbi->s_mb_group_prealloc = sbi->s_stripe * 4; ++ } ++ ++ sbi->s_locality_groups = alloc_percpu(struct ext4_locality_group); ++@@ -3006,6 +3118,7 @@ out_free_locality_groups: ++ free_percpu(sbi->s_locality_groups); ++ sbi->s_locality_groups = NULL; ++ out: +++ kfree(sbi->s_mb_prealloc_table); ++ kfree(sbi->s_mb_offsets); ++ sbi->s_mb_offsets = NULL; ++ kfree(sbi->s_mb_maxs); ++@@ -3278,7 +3391,6 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, ++ int err, len; ++ ++ BUG_ON(ac->ac_status != AC_STATUS_FOUND); ++- BUG_ON(ac->ac_b_ex.fe_len <= 0); ++ ++ sb = ac->ac_sb; ++ sbi = EXT4_SB(sb); ++@@ -3513,13 +3625,14 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, ++ { ++ struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb); ++ struct ext4_super_block *es = sbi->s_es; ++- int bsbits, max; +++ int bsbits, i, wind; ++ ext4_lblk_t end; ++- loff_t size, start_off; +++ loff_t size; ++ loff_t orig_size __maybe_unused; ++ ext4_lblk_t start; ++ struct ext4_inode_info *ei = EXT4_I(ac->ac_inode); ++ struct ext4_prealloc_space *pa; +++ unsigned long value, last_non_zero; ++ ++ /* do normalize only data requests, metadata requests ++ do not need preallocation */ ++@@ -3548,51 +3661,46 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, ++ size = size << bsbits; ++ if (size < i_size_read(ac->ac_inode)) ++ size = i_size_read(ac->ac_inode); ++- orig_size = size; +++ size = (size + ac->ac_sb->s_blocksize - 1) >> bsbits; +++ +++ start = wind = 0; +++ value = last_non_zero = 0; ++ ++- /* max size of free chunks */ ++- max = 2 << bsbits; ++- ++-#define NRL_CHECK_SIZE(req, size, max, chunk_size) \ ++- (req <= (size) || max <= (chunk_size)) ++- ++- /* first, try to predict filesize */ ++- /* XXX: should this table be tunable? */ ++- start_off = 0; ++- if (size <= 16 * 1024) { ++- size = 16 * 1024; ++- } else if (size <= 32 * 1024) { ++- size = 32 * 1024; ++- } else if (size <= 64 * 1024) { ++- size = 64 * 1024; ++- } else if (size <= 128 * 1024) { ++- size = 128 * 1024; ++- } else if (size <= 256 * 1024) { ++- size = 256 * 1024; ++- } else if (size <= 512 * 1024) { ++- size = 512 * 1024; ++- } else if (size <= 1024 * 1024) { ++- size = 1024 * 1024; ++- } else if (NRL_CHECK_SIZE(size, 4 * 1024 * 1024, max, 2 * 1024)) { ++- start_off = ((loff_t)ac->ac_o_ex.fe_logical >> ++- (21 - bsbits)) << 21; ++- size = 2 * 1024 * 1024; ++- } else if (NRL_CHECK_SIZE(size, 8 * 1024 * 1024, max, 4 * 1024)) { ++- start_off = ((loff_t)ac->ac_o_ex.fe_logical >> ++- (22 - bsbits)) << 22; ++- size = 4 * 1024 * 1024; ++- } else if (NRL_CHECK_SIZE(ac->ac_o_ex.fe_len, ++- (8<<20)>>bsbits, max, 8 * 1024)) { ++- start_off = ((loff_t)ac->ac_o_ex.fe_logical >> ++- (23 - bsbits)) << 23; ++- size = 8 * 1024 * 1024; +++ /* let's choose preallocation window depending on file size */ +++ for (i = 0; i < EXT4_MAX_PREALLOC_TABLE; i++) { +++ value = sbi->s_mb_prealloc_table[i]; +++ if (value == 0) +++ break; +++ else +++ last_non_zero = value; +++ +++ if (size <= value) { +++ wind = value; +++ break; +++ } +++ } +++ +++ if (wind == 0) { +++ if (last_non_zero != 0) { +++ __u64 tstart, tend; +++ /* file is quite large, we now preallocate with +++ * the biggest configured window with regart to +++ * logical offset */ +++ wind = last_non_zero; +++ tstart = ac->ac_o_ex.fe_logical; +++ do_div(tstart, wind); +++ start = tstart * wind; +++ tend = ac->ac_o_ex.fe_logical + ac->ac_o_ex.fe_len - 1; +++ do_div(tend, wind); +++ tend = tend * wind + wind; +++ size = tend - start; +++ } ++ } else { ++- start_off = (loff_t) ac->ac_o_ex.fe_logical << bsbits; ++- size = (loff_t) EXT4_C2B(EXT4_SB(ac->ac_sb), ++- ac->ac_o_ex.fe_len) << bsbits; +++ size = wind; ++ } ++- size = size >> bsbits; ++- start = start_off >> bsbits; +++ +++ +++ orig_size = size; ++ ++ /* ++ * For tiny groups (smaller than 8MB) the chosen allocation ++@@ -3698,7 +3806,6 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, ++ (unsigned long) ac->ac_o_ex.fe_logical); ++ BUG(); ++ } ++- BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); ++ ++ /* now prepare goal request */ ++ ++@@ -4735,11 +4842,19 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac) ++ ++ /* don't use group allocation for large files */ ++ size = max(size, isize); ++- if (size > sbi->s_mb_stream_request) { +++ if ((ac->ac_o_ex.fe_len >= sbi->s_mb_small_req) || +++ (size >= sbi->s_mb_large_req)) { ++ ac->ac_flags |= EXT4_MB_STREAM_ALLOC; ++ return; ++ } ++ +++ /* +++ * request is so large that we don't care about +++ * streaming - it overweights any possible seek +++ */ +++ if (ac->ac_o_ex.fe_len >= sbi->s_mb_large_req) +++ return; +++ ++ BUG_ON(ac->ac_lg != NULL); ++ /* ++ * locality group prealloc space are per cpu. The reason for having ++diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c ++index b0bb4a9..74ec068 100644 ++--- a/fs/ext4/sysfs.c +++++ b/fs/ext4/sysfs.c ++@@ -218,7 +218,8 @@ EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats); ++ EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan); ++ EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan); ++ EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs); ++-EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request); +++EXT4_RW_ATTR_SBI_UI(mb_small_req, s_mb_small_req); +++EXT4_RW_ATTR_SBI_UI(mb_large_req, s_mb_large_req); ++ EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc); ++ EXT4_RW_ATTR_SBI_UI(mb_max_inode_prealloc, s_mb_max_inode_prealloc); ++ EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb); ++@@ -266,7 +267,8 @@ static struct attribute *ext4_attrs[] = { ++ ATTR_LIST(mb_max_to_scan), ++ ATTR_LIST(mb_min_to_scan), ++ ATTR_LIST(mb_order2_req), ++- ATTR_LIST(mb_stream_req), +++ ATTR_LIST(mb_small_req), +++ ATTR_LIST(mb_large_req), ++ ATTR_LIST(mb_group_prealloc), ++ ATTR_LIST(mb_max_inode_prealloc), ++ ATTR_LIST(max_writeback_mb_bump), ++@@ -541,6 +543,8 @@ int ext4_register_sysfs(struct super_block *sb) ++ &ext4_mb_seq_groups_ops, sb); ++ proc_create_single_data("mb_stats", 0444, sbi->s_proc, ++ ext4_seq_mb_stats_show, sb); +++ proc_create_data("prealloc_table", S_IRUGO, sbi->s_proc, +++ &ext4_seq_prealloc_table_fops, sb); ++ } ++ return 0; ++ } ++-- ++2.33.0 ++ +diff --git a/ldiskfs/kernel_patches/patches/oe2203sp3/ext4-simple-blockalloc.patch b/ldiskfs/kernel_patches/patches/oe2203sp3/ext4-simple-blockalloc.patch +new file mode 100644 +index 0000000000..a9a79c4c2e +--- /dev/null ++++ b/ldiskfs/kernel_patches/patches/oe2203sp3/ext4-simple-blockalloc.patch +@@ -0,0 +1,361 @@ ++From 20d4652a1de56f5354552f704947097bcc4f8eb2 Mon Sep 17 00:00:00 2001 ++From: Xinliang Liu ++Date: Mon, 27 Nov 2023 09:24:43 +0000 ++Subject: [PATCH] ext4: simple blockalloc ++ ++Signed-off-by: Xinliang Liu ++--- ++ fs/ext4/ext4.h | 5 ++ ++ fs/ext4/mballoc.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++ ++ fs/ext4/mballoc.h | 3 + ++ fs/ext4/sysfs.c | 52 ++++++++++++++++++ ++ 4 files changed, 196 insertions(+) ++ ++diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h ++index fe8fe65..0c4f853 100644 ++--- a/fs/ext4/ext4.h +++++ b/fs/ext4/ext4.h ++@@ -1561,6 +1561,9 @@ struct ext4_sb_info { ++ unsigned int s_mb_min_to_scan; ++ unsigned int s_mb_stats; ++ unsigned int s_mb_order2_reqs; +++ ext4_fsblk_t s_mb_c1_blocks; +++ ext4_fsblk_t s_mb_c2_blocks; +++ ext4_fsblk_t s_mb_c3_blocks; ++ unsigned long *s_mb_prealloc_table; ++ unsigned int s_mb_group_prealloc; ++ unsigned int s_mb_max_inode_prealloc; ++@@ -1584,6 +1587,7 @@ struct ext4_sb_info { ++ atomic64_t s_bal_cX_groups_considered[4]; ++ atomic64_t s_bal_cX_hits[4]; ++ atomic64_t s_bal_cX_failed[4]; /* cX loop didn't find blocks */ +++ atomic64_t s_bal_cX_skipped[4]; ++ atomic_t s_mb_buddies_generated; /* number of buddies generated */ ++ atomic64_t s_mb_generation_time; ++ atomic_t s_mb_lost_chunks; ++@@ -3003,6 +3007,7 @@ int ext4_fc_record_regions(struct super_block *sb, int ino, ++ /* mballoc.c */ ++ extern const struct proc_ops ext4_seq_prealloc_table_fops; ++ extern const struct seq_operations ext4_mb_seq_groups_ops; +++extern const struct proc_ops ext4_mb_seq_alloc_fops; ++ extern const struct proc_ops ext4_seq_mb_last_group_fops; ++ extern int ext4_mb_seq_last_start_seq_show(struct seq_file *m, void *v); ++ extern long ext4_mb_stats; ++diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c ++index bd3938c..967a902 100644 ++--- a/fs/ext4/mballoc.c +++++ b/fs/ext4/mballoc.c ++@@ -2303,6 +2303,20 @@ void ext4_mb_prefetch_fini(struct super_block *sb, ext4_group_t group, ++ } ++ } ++ +++static u64 available_blocks_count(struct ext4_sb_info *sbi) +++{ +++ ext4_fsblk_t resv_blocks; +++ u64 bfree; +++ struct ext4_super_block *es = sbi->s_es; +++ +++ resv_blocks = EXT4_C2B(sbi, atomic64_read(&sbi->s_resv_clusters)); +++ bfree = percpu_counter_sum_positive(&sbi->s_freeclusters_counter) - +++ percpu_counter_sum_positive(&sbi->s_dirtyclusters_counter); +++ +++ bfree = EXT4_C2B(sbi, max_t(s64, bfree, 0)); +++ return bfree - (ext4_r_blocks_count(es) + resv_blocks); +++} +++ ++ static noinline_for_stack int ++ ext4_mb_regular_allocator(struct ext4_allocation_context *ac) ++ { ++@@ -2313,6 +2327,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac) ++ struct ext4_sb_info *sbi; ++ struct super_block *sb; ++ struct ext4_buddy e4b; +++ ext4_fsblk_t avail_blocks; ++ int lost; ++ ++ sb = ac->ac_sb; ++@@ -2366,6 +2381,21 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac) ++ ++ /* Let's just scan groups to find more-less suitable blocks */ ++ cr = ac->ac_2order ? 0 : 1; +++ +++ /* Choose what loop to pass based on disk fullness */ +++ avail_blocks = available_blocks_count(sbi) ; +++ +++ if (avail_blocks < sbi->s_mb_c3_blocks) { +++ cr = 3; +++ atomic64_inc(&sbi->s_bal_cX_skipped[2]); +++ } else if(avail_blocks < sbi->s_mb_c2_blocks) { +++ cr = 2; +++ atomic64_inc(&sbi->s_bal_cX_skipped[1]); +++ } else if(avail_blocks < sbi->s_mb_c1_blocks) { +++ cr = 1; +++ atomic64_inc(&sbi->s_bal_cX_skipped[0]); +++ } +++ ++ /* ++ * cr == 0 try to get exact allocation, ++ * cr == 3 try to get anything ++@@ -2484,6 +2514,9 @@ repeat: ++ cr = 3; ++ goto repeat; ++ } +++ /* Processed all groups and haven't found blocks */ +++ if (i == ngroups) +++ atomic64_inc(&sbi->s_bal_cX_failed[cr]); ++ } ++ ++ if (sbi->s_mb_stats && ac->ac_status == AC_STATUS_FOUND) ++@@ -2810,6 +2843,95 @@ const struct proc_ops ext4_seq_mb_last_group_fops = { ++ .proc_write = ext4_mb_last_group_write, ++ }; ++ +++static int mb_seq_alloc_show(struct seq_file *seq, void *v) +++{ +++ struct super_block *sb = seq->private; +++ struct ext4_sb_info *sbi = EXT4_SB(sb); +++ +++ seq_printf(seq, "mballoc:\n"); +++ seq_printf(seq, "\tblocks: %u\n", atomic_read(&sbi->s_bal_allocated)); +++ seq_printf(seq, "\treqs: %u\n", atomic_read(&sbi->s_bal_reqs)); +++ seq_printf(seq, "\tsuccess: %u\n", atomic_read(&sbi->s_bal_success)); +++ +++ seq_printf(seq, "\textents_scanned: %u\n", +++ atomic_read(&sbi->s_bal_ex_scanned)); +++ seq_printf(seq, "\t\tgoal_hits: %u\n", atomic_read(&sbi->s_bal_goals)); +++ seq_printf(seq, "\t\t2^n_hits: %u\n", atomic_read(&sbi->s_bal_2orders)); +++ seq_printf(seq, "\t\tbreaks: %u\n", atomic_read(&sbi->s_bal_breaks)); +++ seq_printf(seq, "\t\tlost: %u\n", atomic_read(&sbi->s_mb_lost_chunks)); +++ +++ seq_printf(seq, "\tuseless_c1_loops: %llu\n", +++ atomic64_read(&sbi->s_bal_cX_failed[0])); +++ seq_printf(seq, "\tuseless_c2_loops: %llu\n", +++ atomic64_read(&sbi->s_bal_cX_failed[1])); +++ seq_printf(seq, "\tuseless_c3_loops: %llu\n", +++ atomic64_read(&sbi->s_bal_cX_failed[2])); +++ seq_printf(seq, "\tskipped_c1_loops: %llu\n", +++ atomic64_read(&sbi->s_bal_cX_skipped[0])); +++ seq_printf(seq, "\tskipped_c2_loops: %llu\n", +++ atomic64_read(&sbi->s_bal_cX_skipped[1])); +++ seq_printf(seq, "\tskipped_c3_loops: %llu\n", +++ atomic64_read(&sbi->s_bal_cX_skipped[2])); +++ seq_printf(seq, "\tbuddies_generated: %u\n", +++ atomic_read(&sbi->s_mb_buddies_generated)); +++ seq_printf(seq, "\tbuddies_time_used: %llu\n", +++ atomic64_read(&sbi->s_mb_generation_time)); +++ seq_printf(seq, "\tpreallocated: %u\n", +++ atomic_read(&sbi->s_mb_preallocated)); +++ seq_printf(seq, "\tdiscarded: %u\n", +++ atomic_read(&sbi->s_mb_discarded)); +++ return 0; +++} +++ +++static ssize_t mb_seq_alloc_write(struct file *file, +++ const char __user *buf, +++ size_t cnt, loff_t *pos) +++{ +++ struct ext4_sb_info *sbi = EXT4_SB(PDE_DATA(file_inode(file))); +++ +++ atomic_set(&sbi->s_bal_allocated, 0), +++ atomic_set(&sbi->s_bal_reqs, 0), +++ atomic_set(&sbi->s_bal_success, 0); +++ +++ atomic_set(&sbi->s_bal_ex_scanned, 0), +++ atomic_set(&sbi->s_bal_goals, 0), +++ atomic_set(&sbi->s_bal_2orders, 0), +++ atomic_set(&sbi->s_bal_breaks, 0), +++ atomic_set(&sbi->s_mb_lost_chunks, 0); +++ +++ atomic64_set(&sbi->s_bal_cX_failed[0], 0), +++ atomic64_set(&sbi->s_bal_cX_failed[1], 0), +++ atomic64_set(&sbi->s_bal_cX_failed[2], 0); +++ atomic64_set(&sbi->s_bal_cX_failed[3], 0); +++ +++ atomic64_set(&sbi->s_bal_cX_skipped[0], 0), +++ atomic64_set(&sbi->s_bal_cX_skipped[1], 0), +++ atomic64_set(&sbi->s_bal_cX_skipped[2], 0); +++ atomic64_set(&sbi->s_bal_cX_skipped[3], 0); +++ +++ +++ atomic_set(&sbi->s_mb_buddies_generated, 0); +++ atomic64_set(&sbi->s_mb_generation_time, 0); +++ +++ atomic_set(&sbi->s_mb_preallocated, 0), +++ atomic_set(&sbi->s_mb_discarded, 0); +++ +++ return cnt; +++} +++ +++static int mb_seq_alloc_open(struct inode *inode, struct file *file) +++{ +++ return single_open(file, mb_seq_alloc_show, PDE_DATA(inode)); +++} +++ +++const struct proc_ops ext4_mb_seq_alloc_fops = { +++ .proc_open = mb_seq_alloc_open, +++ .proc_read = seq_read, +++ .proc_lseek = seq_lseek, +++ .proc_release = single_release, +++ .proc_write = mb_seq_alloc_write, +++}; +++ ++ int ext4_mb_seq_last_start_seq_show(struct seq_file *m, void *v) ++ { ++ struct ext4_sb_info *sbi = EXT4_SB(m->private); ++@@ -3068,6 +3190,7 @@ static int ext4_groupinfo_create_slab(size_t size) ++ return 0; ++ } ++ +++#define THRESHOLD_BLOCKS(ts) (ext4_blocks_count(sbi->s_es) / 100 * ts) ++ int ext4_mb_init(struct super_block *sb) ++ { ++ struct ext4_sb_info *sbi = EXT4_SB(sb); ++@@ -3121,6 +3244,9 @@ int ext4_mb_init(struct super_block *sb) ++ sbi->s_mb_stats = MB_DEFAULT_STATS; ++ sbi->s_mb_order2_reqs = MB_DEFAULT_ORDER2_REQS; ++ sbi->s_mb_max_inode_prealloc = MB_DEFAULT_MAX_INODE_PREALLOC; +++ sbi->s_mb_c1_blocks = THRESHOLD_BLOCKS(MB_DEFAULT_C1_THRESHOLD); +++ sbi->s_mb_c2_blocks = THRESHOLD_BLOCKS(MB_DEFAULT_C2_THRESHOLD); +++ sbi->s_mb_c3_blocks = THRESHOLD_BLOCKS(MB_DEFAULT_C3_THRESHOLD); ++ /* ++ * The default group preallocation is 512, which for 4k block ++ * sizes translates to 2 megabytes. However for bigalloc file ++@@ -3261,6 +3387,16 @@ int ext4_mb_release(struct super_block *sb) ++ atomic_read(&sbi->s_bal_allocated), ++ atomic_read(&sbi->s_bal_reqs), ++ atomic_read(&sbi->s_bal_success)); +++ ext4_msg(sb, KERN_INFO, +++ "mballoc: (%llu, %llu, %llu) useless c(0,1,2) loops", +++ atomic64_read(&sbi->s_bal_cX_failed[0]), +++ atomic64_read(&sbi->s_bal_cX_failed[1]), +++ atomic64_read(&sbi->s_bal_cX_failed[2])); +++ ext4_msg(sb, KERN_INFO, +++ "mballoc: (%llu, %llu, %llu) skipped c(0,1,2) loops", +++ atomic64_read(&sbi->s_bal_cX_skipped[0]), +++ atomic64_read(&sbi->s_bal_cX_skipped[1]), +++ atomic64_read(&sbi->s_bal_cX_skipped[2])); ++ ext4_msg(sb, KERN_INFO, ++ "mballoc: %u extents scanned, %u groups scanned, %u goal hits, " ++ "%u 2^N hits, %u breaks, %u lost", ++diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h ++index 90d6772..ea9a956 100644 ++--- a/fs/ext4/mballoc.h +++++ b/fs/ext4/mballoc.h ++@@ -68,6 +68,9 @@ ++ * for which requests use 2^N search using buddies ++ */ ++ #define MB_DEFAULT_ORDER2_REQS 8 +++#define MB_DEFAULT_C1_THRESHOLD 25 +++#define MB_DEFAULT_C2_THRESHOLD 15 +++#define MB_DEFAULT_C3_THRESHOLD 5 ++ ++ /* ++ * default group prealloc size 512 blocks ++diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c ++index 93d3ff5..91be249 100644 ++--- a/fs/ext4/sysfs.c +++++ b/fs/ext4/sysfs.c ++@@ -21,6 +21,9 @@ ++ typedef enum { ++ attr_noop, ++ attr_delayed_allocation_blocks, +++ attr_mb_c1_threshold, +++ attr_mb_c2_threshold, +++ attr_mb_c3_threshold, ++ attr_session_write_kbytes, ++ attr_lifetime_write_kbytes, ++ attr_reserved_clusters, ++@@ -141,6 +144,32 @@ static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf) ++ task_pid_vnr(sbi->s_journal->j_task)); ++ } ++ +++#define THRESHOLD_PERCENT(ts) (ts * 100 / ext4_blocks_count(sbi->s_es)) +++ +++static int save_threshold_percent(struct ext4_sb_info *sbi, const char *buf, +++ ext4_fsblk_t *blocks) +++{ +++ unsigned long long val; +++ +++ int ret; +++ +++ ret = kstrtoull(skip_spaces(buf), 0, &val); +++ if (ret || val > 100) +++ return -EINVAL; +++ +++ *blocks = val * ext4_blocks_count(sbi->s_es) / 100; +++ return 0; +++} +++ +++static ssize_t mb_threshold_store(struct ext4_sb_info *sbi, +++ const char *buf, size_t count, +++ ext4_fsblk_t *blocks) +++{ +++ int ret = save_threshold_percent(sbi, buf, blocks); +++ +++ return ret ?: count; +++} +++ ++ #define EXT4_ATTR(_name,_mode,_id) \ ++ static struct ext4_attr ext4_attr_##_name = { \ ++ .attr = {.name = __stringify(_name), .mode = _mode }, \ ++@@ -210,6 +239,9 @@ EXT4_ATTR_FUNC(session_write_kbytes, 0444); ++ EXT4_ATTR_FUNC(lifetime_write_kbytes, 0444); ++ EXT4_ATTR_FUNC(reserved_clusters, 0644); ++ EXT4_ATTR_FUNC(sra_exceeded_retry_limit, 0444); +++EXT4_ATTR_FUNC(mb_c1_threshold, 0644); +++EXT4_ATTR_FUNC(mb_c2_threshold, 0644); +++EXT4_ATTR_FUNC(mb_c3_threshold, 0644); ++ ++ EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, inode_readahead, ++ ext4_sb_info, s_inode_readahead_blks); ++@@ -264,6 +296,9 @@ static struct attribute *ext4_attrs[] = { ++ ATTR_LIST(lifetime_write_kbytes), ++ ATTR_LIST(reserved_clusters), ++ ATTR_LIST(sra_exceeded_retry_limit), +++ ATTR_LIST(mb_c1_threshold), +++ ATTR_LIST(mb_c2_threshold), +++ ATTR_LIST(mb_c3_threshold), ++ ATTR_LIST(inode_readahead_blks), ++ ATTR_LIST(inode_goal), ++ ATTR_LIST(max_dir_size), ++@@ -383,6 +418,15 @@ static ssize_t ext4_attr_show(struct kobject *kobj, ++ return snprintf(buf, PAGE_SIZE, "%llu\n", ++ (s64) EXT4_C2B(sbi, ++ percpu_counter_sum(&sbi->s_dirtyclusters_counter))); +++ case attr_mb_c1_threshold: +++ return scnprintf(buf, PAGE_SIZE, "%llu\n", +++ THRESHOLD_PERCENT(sbi->s_mb_c1_blocks)); +++ case attr_mb_c2_threshold: +++ return scnprintf(buf, PAGE_SIZE, "%llu\n", +++ THRESHOLD_PERCENT(sbi->s_mb_c2_blocks)); +++ case attr_mb_c3_threshold: +++ return scnprintf(buf, PAGE_SIZE, "%llu\n", +++ THRESHOLD_PERCENT(sbi->s_mb_c3_blocks)); ++ case attr_session_write_kbytes: ++ return session_write_kbytes_show(sbi, buf); ++ case attr_lifetime_write_kbytes: ++@@ -488,6 +532,12 @@ static ssize_t ext4_attr_store(struct kobject *kobj, ++ return inode_readahead_blks_store(sbi, buf, len); ++ case attr_trigger_test_error: ++ return trigger_test_error(sbi, buf, len); +++ case attr_mb_c1_threshold: +++ return mb_threshold_store(sbi, buf, len, &sbi->s_mb_c1_blocks); +++ case attr_mb_c2_threshold: +++ return mb_threshold_store(sbi, buf, len, &sbi->s_mb_c2_blocks); +++ case attr_mb_c3_threshold: +++ return mb_threshold_store(sbi, buf, len, &sbi->s_mb_c3_blocks); ++ } ++ return 0; ++ } ++@@ -559,6 +609,8 @@ int ext4_register_sysfs(struct super_block *sb) ++ &ext4_seq_mb_last_group_fops, sb); ++ proc_create_single_data("mb_last_start", S_IRUGO, sbi->s_proc, ++ ext4_mb_seq_last_start_seq_show, sb); +++ proc_create_data("mb_alloc_stats", S_IFREG | S_IRUGO | S_IWUSR, +++ sbi->s_proc, &ext4_mb_seq_alloc_fops, sb); ++ } ++ return 0; ++ } ++-- ++2.33.0 ++ +diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.10.0-oe2203sp1.series b/ldiskfs/kernel_patches/series/ldiskfs-5.10.0-oe2203sp1.series +index 82711ec7a5..68f1048c83 100644 +--- a/ldiskfs/kernel_patches/series/ldiskfs-5.10.0-oe2203sp1.series ++++ b/ldiskfs/kernel_patches/series/ldiskfs-5.10.0-oe2203sp1.series +@@ -1,10 +1,10 @@ + oe2203/ext4-inode-version.patch + linux-5.4/ext4-lookup-dotdot.patch + suse15/ext4-print-inum-in-htree-warning.patch +-linux-5.8/ext4-prealloc.patch ++oe2203sp3/ext4-prealloc.patch + ubuntu18/ext4-osd-iop-common.patch + oe2203/ext4-misc.patch +-linux-5.8/ext4-mballoc-extra-checks.patch ++oe2203sp3/ext4-mballoc-extra-checks.patch + linux-5.4/ext4-hash-indexed-dir-dotdot-update.patch + linux-5.8/ext4-kill-dx-root.patch + linux-5.8/ext4-mballoc-pa-free-mismatch.patch +@@ -23,7 +23,7 @@ rhel7.6/ext4-export-orphan-add.patch + linux-5.8/ext4-export-mb-stream-allocator-variables.patch + ubuntu19/ext4-iget-with-flags.patch + linux-5.4/export-ext4fs-dirhash-helper.patch +-oe2203/ext4-simple-blockalloc.patch ++oe2203sp3/ext4-simple-blockalloc.patch + oe2203/ext4-xattr-disable-credits-check.patch + linux-5.8/ext4-no-max-dir-size-limit-for-iam-objects.patch + rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch +-- +2.33.0 + diff --git a/lustre.spec b/lustre.spec index 3757c249a48d37f1fb725370f4e1bb8c3f071aef..2564f230fe96daaf8f7b3e6dc15794f2a04ec4b2 100644 --- a/lustre.spec +++ b/lustre.spec @@ -185,7 +185,7 @@ Summary: Lustre File System Name: %{lustre_name} Version: 2.15.3 -Release: 1 +Release: 2 License: GPL-2.0-only AND LGPL-2.1-or-later Group: System Environment/Kernel Source: https://github.com/lustre/lustre-release/archive/refs/tags/%{version}.tar.gz @@ -264,6 +264,7 @@ Patch58: 0058-LU-14073-ldiskfs-don-t-test-LDISKFS_IOC_FSSETXATTR.patch Patch59: 0059-LU-16019-llite-fully-disable-readahead-in-kernel-I-O.patch Patch60: 0060-Update-openEuler-22.03-kernels.patch Patch61: 0061-Update-kernel-for-openEuler-20.03-LTS.patch +Patch62: 0062-ldiskfs-fix-build-for-oe2203sp3.patch %if %{with lustre_modules} Requires: %{requires_kmod_name} = %{requires_kmod_version} @@ -937,6 +938,9 @@ rm -rf $RPM_BUILD_ROOT rm -rf %{_tmppath}/kmp %changelog +* Tue Nov 28 2023 Xinliang Liu - 2.15.3-2 +- Fix build for oe2203sp3 new kernel 5.10.0-171.0.0.84.oe2203sp3. + * Fri Nov 10 2023 Xinliang Liu - 2.15.3-1 - Update to 2.15.3 with openEuler bugfixes patches.