]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ext4: refactor ext4_free_blocks() to pull out ext4_mb_clear_bb()
authorRitesh Harjani <riteshh@linux.ibm.com>
Wed, 16 Feb 2022 07:02:45 +0000 (12:32 +0530)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 26 Feb 2022 02:34:56 +0000 (21:34 -0500)
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 <riteshh@linux.ibm.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/22c30fbb26ba409cf8aa5f0c7912970272c459e8.1644992610.git.riteshh@linux.ibm.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/mballoc.c

index 816322eddd2bd3fe2c73359b8999233498f32722..7b80c5dd9f40f6c8574dc5875d932925ff6e39d7 100644 (file)
@@ -5872,7 +5872,8 @@ static void ext4_free_blocks_simple(struct inode *inode, ext4_fsblk_t block,
 }
 
 /**
- * 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
@@ -5880,9 +5881,9 @@ static void ext4_free_blocks_simple(struct inode *inode, ext4_fsblk_t block,
  * @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;
@@ -5899,80 +5900,6 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
 
        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);
@@ -6140,6 +6067,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