From: Greg Kroah-Hartman Date: Wed, 15 Mar 2023 08:07:32 +0000 (+0100) Subject: 5.15-stable patches X-Git-Tag: v4.14.310~46 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=95bb4af05cfb19ad3fd7a87572e5ce4f32fd05a7;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: ext4-add-ext4_sb_block_valid-refactored-out-of-ext4_inode_block_valid.patch ext4-refactor-ext4_free_blocks-to-pull-out-ext4_mb_clear_bb.patch --- diff --git a/queue-5.15/ext4-add-ext4_sb_block_valid-refactored-out-of-ext4_inode_block_valid.patch b/queue-5.15/ext4-add-ext4_sb_block_valid-refactored-out-of-ext4_inode_block_valid.patch new file mode 100644 index 00000000000..86d154b3fe8 --- /dev/null +++ b/queue-5.15/ext4-add-ext4_sb_block_valid-refactored-out-of-ext4_inode_block_valid.patch @@ -0,0 +1,85 @@ +From 6bc6c2bdf1baca6522b8d9ba976257d722423085 Mon Sep 17 00:00:00 2001 +From: Ritesh Harjani +Date: Wed, 16 Feb 2022 12:32:49 +0530 +Subject: ext4: add ext4_sb_block_valid() refactored out of ext4_inode_block_valid() + +From: Ritesh Harjani + +commit 6bc6c2bdf1baca6522b8d9ba976257d722423085 upstream. + +This API will be needed at places where we don't have an inode +for e.g. while freeing blocks in ext4_group_add_blocks() + +Suggested-by: Jan Kara +Signed-off-by: Ritesh Harjani +Link: https://lore.kernel.org/r/dd34a236543ad5ae7123eeebe0cb69e6bdd44f34.1644992610.git.riteshh@linux.ibm.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Tudor Ambarus +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/block_validity.c | 26 +++++++++++++++++--------- + fs/ext4/ext4.h | 3 +++ + 2 files changed, 20 insertions(+), 9 deletions(-) + +--- a/fs/ext4/block_validity.c ++++ b/fs/ext4/block_validity.c +@@ -292,15 +292,10 @@ void ext4_release_system_zone(struct sup + call_rcu(&system_blks->rcu, ext4_destroy_system_zone); + } + +-/* +- * Returns 1 if the passed-in block region (start_blk, +- * start_blk+count) is valid; 0 if some part of the block region +- * overlaps with some other filesystem metadata blocks. +- */ +-int ext4_inode_block_valid(struct inode *inode, ext4_fsblk_t start_blk, +- unsigned int count) ++int ext4_sb_block_valid(struct super_block *sb, struct inode *inode, ++ ext4_fsblk_t start_blk, unsigned int count) + { +- struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); ++ struct ext4_sb_info *sbi = EXT4_SB(sb); + struct ext4_system_blocks *system_blks; + struct ext4_system_zone *entry; + struct rb_node *n; +@@ -329,7 +324,9 @@ int ext4_inode_block_valid(struct inode + else if (start_blk >= (entry->start_blk + entry->count)) + n = n->rb_right; + else { +- ret = (entry->ino == inode->i_ino); ++ ret = 0; ++ if (inode) ++ ret = (entry->ino == inode->i_ino); + break; + } + } +@@ -338,6 +335,17 @@ out_rcu: + return ret; + } + ++/* ++ * Returns 1 if the passed-in block region (start_blk, ++ * start_blk+count) is valid; 0 if some part of the block region ++ * overlaps with some other filesystem metadata blocks. ++ */ ++int ext4_inode_block_valid(struct inode *inode, ext4_fsblk_t start_blk, ++ unsigned int count) ++{ ++ return ext4_sb_block_valid(inode->i_sb, inode, start_blk, count); ++} ++ + int ext4_check_blockref(const char *function, unsigned int line, + struct inode *inode, __le32 *p, unsigned int max) + { +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -3698,6 +3698,9 @@ extern int ext4_inode_block_valid(struct + unsigned int count); + extern int ext4_check_blockref(const char *, unsigned int, + struct inode *, __le32 *, unsigned int); ++extern int ext4_sb_block_valid(struct super_block *sb, struct inode *inode, ++ ext4_fsblk_t start_blk, unsigned int count); ++ + + /* extents.c */ + struct ext4_ext_path; diff --git a/queue-5.15/ext4-refactor-ext4_free_blocks-to-pull-out-ext4_mb_clear_bb.patch b/queue-5.15/ext4-refactor-ext4_free_blocks-to-pull-out-ext4_mb_clear_bb.patch new file mode 100644 index 00000000000..b12f0b322fc --- /dev/null +++ b/queue-5.15/ext4-refactor-ext4_free_blocks-to-pull-out-ext4_mb_clear_bb.patch @@ -0,0 +1,235 @@ +From 8ac3939db99f99667b8eb670cf4baf292896e72d Mon Sep 17 00:00:00 2001 +From: Ritesh Harjani +Date: Wed, 16 Feb 2022 12:32:45 +0530 +Subject: ext4: refactor ext4_free_blocks() to pull out ext4_mb_clear_bb() + +From: Ritesh Harjani + +commit 8ac3939db99f99667b8eb670cf4baf292896e72d upstream. + +ext4_free_blocks() function became too long and confusing, this patch +just pulls out the ext4_mb_clear_bb() function logic from it +which clears the block bitmap and frees it. + +No functionality change in this patch + +Signed-off-by: Ritesh Harjani +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/22c30fbb26ba409cf8aa5f0c7912970272c459e8.1644992610.git.riteshh@linux.ibm.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Tudor Ambarus +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/mballoc.c | 180 ++++++++++++++++++++++++++++++------------------------ + 1 file changed, 102 insertions(+), 78 deletions(-) + +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -5888,7 +5888,8 @@ static void ext4_free_blocks_simple(stru + } + + /** +- * ext4_free_blocks() -- Free given blocks and update quota ++ * ext4_mb_clear_bb() -- helper function for freeing blocks. ++ * Used by ext4_free_blocks() + * @handle: handle for this transaction + * @inode: inode + * @bh: optional buffer of the block to be freed +@@ -5896,9 +5897,9 @@ static void ext4_free_blocks_simple(stru + * @count: number of blocks to be freed + * @flags: flags used by ext4_free_blocks + */ +-void ext4_free_blocks(handle_t *handle, struct inode *inode, +- struct buffer_head *bh, ext4_fsblk_t block, +- unsigned long count, int flags) ++static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode, ++ ext4_fsblk_t block, unsigned long count, ++ int flags) + { + struct buffer_head *bitmap_bh = NULL; + struct super_block *sb = inode->i_sb; +@@ -5915,80 +5916,6 @@ void ext4_free_blocks(handle_t *handle, + + sbi = EXT4_SB(sb); + +- if (sbi->s_mount_state & EXT4_FC_REPLAY) { +- ext4_free_blocks_simple(inode, block, count); +- return; +- } +- +- might_sleep(); +- if (bh) { +- if (block) +- BUG_ON(block != bh->b_blocknr); +- else +- block = bh->b_blocknr; +- } +- +- if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) && +- !ext4_inode_block_valid(inode, block, count)) { +- ext4_error(sb, "Freeing blocks not in datazone - " +- "block = %llu, count = %lu", block, count); +- goto error_return; +- } +- +- ext4_debug("freeing block %llu\n", block); +- trace_ext4_free_blocks(inode, block, count, flags); +- +- if (bh && (flags & EXT4_FREE_BLOCKS_FORGET)) { +- BUG_ON(count > 1); +- +- ext4_forget(handle, flags & EXT4_FREE_BLOCKS_METADATA, +- inode, bh, block); +- } +- +- /* +- * If the extent to be freed does not begin on a cluster +- * boundary, we need to deal with partial clusters at the +- * beginning and end of the extent. Normally we will free +- * blocks at the beginning or the end unless we are explicitly +- * requested to avoid doing so. +- */ +- overflow = EXT4_PBLK_COFF(sbi, block); +- if (overflow) { +- if (flags & EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER) { +- overflow = sbi->s_cluster_ratio - overflow; +- block += overflow; +- if (count > overflow) +- count -= overflow; +- else +- return; +- } else { +- block -= overflow; +- count += overflow; +- } +- } +- overflow = EXT4_LBLK_COFF(sbi, count); +- if (overflow) { +- if (flags & EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER) { +- if (count > overflow) +- count -= overflow; +- else +- return; +- } else +- count += sbi->s_cluster_ratio - overflow; +- } +- +- if (!bh && (flags & EXT4_FREE_BLOCKS_FORGET)) { +- int i; +- int is_metadata = flags & EXT4_FREE_BLOCKS_METADATA; +- +- for (i = 0; i < count; i++) { +- cond_resched(); +- if (is_metadata) +- bh = sb_find_get_block(inode->i_sb, block + i); +- ext4_forget(handle, is_metadata, inode, bh, block + i); +- } +- } +- + do_more: + overflow = 0; + ext4_get_group_no_and_offset(sb, block, &block_group, &bit); +@@ -6156,6 +6083,103 @@ error_return: + return; + } + ++/** ++ * ext4_free_blocks() -- Free given blocks and update quota ++ * @handle: handle for this transaction ++ * @inode: inode ++ * @bh: optional buffer of the block to be freed ++ * @block: starting physical block to be freed ++ * @count: number of blocks to be freed ++ * @flags: flags used by ext4_free_blocks ++ */ ++void ext4_free_blocks(handle_t *handle, struct inode *inode, ++ struct buffer_head *bh, ext4_fsblk_t block, ++ unsigned long count, int flags) ++{ ++ struct super_block *sb = inode->i_sb; ++ unsigned int overflow; ++ struct ext4_sb_info *sbi; ++ ++ sbi = EXT4_SB(sb); ++ ++ if (sbi->s_mount_state & EXT4_FC_REPLAY) { ++ ext4_free_blocks_simple(inode, block, count); ++ return; ++ } ++ ++ might_sleep(); ++ if (bh) { ++ if (block) ++ BUG_ON(block != bh->b_blocknr); ++ else ++ block = bh->b_blocknr; ++ } ++ ++ if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) && ++ !ext4_inode_block_valid(inode, block, count)) { ++ ext4_error(sb, "Freeing blocks not in datazone - " ++ "block = %llu, count = %lu", block, count); ++ return; ++ } ++ ++ ext4_debug("freeing block %llu\n", block); ++ trace_ext4_free_blocks(inode, block, count, flags); ++ ++ if (bh && (flags & EXT4_FREE_BLOCKS_FORGET)) { ++ BUG_ON(count > 1); ++ ++ ext4_forget(handle, flags & EXT4_FREE_BLOCKS_METADATA, ++ inode, bh, block); ++ } ++ ++ /* ++ * If the extent to be freed does not begin on a cluster ++ * boundary, we need to deal with partial clusters at the ++ * beginning and end of the extent. Normally we will free ++ * blocks at the beginning or the end unless we are explicitly ++ * requested to avoid doing so. ++ */ ++ overflow = EXT4_PBLK_COFF(sbi, block); ++ if (overflow) { ++ if (flags & EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER) { ++ overflow = sbi->s_cluster_ratio - overflow; ++ block += overflow; ++ if (count > overflow) ++ count -= overflow; ++ else ++ return; ++ } else { ++ block -= overflow; ++ count += overflow; ++ } ++ } ++ overflow = EXT4_LBLK_COFF(sbi, count); ++ if (overflow) { ++ if (flags & EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER) { ++ if (count > overflow) ++ count -= overflow; ++ else ++ return; ++ } else ++ count += sbi->s_cluster_ratio - overflow; ++ } ++ ++ if (!bh && (flags & EXT4_FREE_BLOCKS_FORGET)) { ++ int i; ++ int is_metadata = flags & EXT4_FREE_BLOCKS_METADATA; ++ ++ for (i = 0; i < count; i++) { ++ cond_resched(); ++ if (is_metadata) ++ bh = sb_find_get_block(inode->i_sb, block + i); ++ ext4_forget(handle, is_metadata, inode, bh, block + i); ++ } ++ } ++ ++ ext4_mb_clear_bb(handle, inode, block, count, flags); ++ return; ++} ++ + /** + * ext4_group_add_blocks() -- Add given blocks to an existing group + * @handle: handle to this transaction diff --git a/queue-5.15/series b/queue-5.15/series index b5c353aff50..6bc7903f8a6 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -122,3 +122,5 @@ sched-fair-detect-capacity-inversion.patch sched-fair-consider-capacity-inversion-in-util_fits_cpu.patch sched-uclamp-fix-a-uninitialized-variable-warnings.patch sched-fair-fixes-for-capacity-inversion-detection.patch +ext4-refactor-ext4_free_blocks-to-pull-out-ext4_mb_clear_bb.patch +ext4-add-ext4_sb_block_valid-refactored-out-of-ext4_inode_block_valid.patch