ext4: get block from bh in ext4_free_blocks for fast commit replay
authorKemeng Shi <shikemeng@huaweicloud.com>
Sat, 3 Jun 2023 15:03:16 +0000 (23:03 +0800)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 26 Jun 2023 22:13:05 +0000 (18:13 -0400)
ext4_free_blocks will retrieve block from bh if block parameter is zero.
Retrieve block before ext4_free_blocks_simple to avoid potentially
passing wrong block to ext4_free_blocks_simple.

Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
Cc: stable@kernel.org
Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Link: https://lore.kernel.org/r/20230603150327.3596033-9-shikemeng@huaweicloud.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/mballoc.c

index bcc9622daa4a36ac49d80fe2ea0774a6486a3a06..dadda9e8cf29634e13c4f6ce709e2443e21914d4 100644 (file)
@@ -6368,12 +6368,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);
@@ -6381,6 +6375,13 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
                        block = bh->b_blocknr;
        }
 
+       if (sbi->s_mount_state & EXT4_FC_REPLAY) {
+               ext4_free_blocks_simple(inode, block, count);
+               return;
+       }
+
+       might_sleep();
+
        if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) &&
            !ext4_inode_block_valid(inode, block, count)) {
                ext4_error(sb, "Freeing blocks not in datazone - "