]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
ext4: correct cluster len and clusters changed accounting in ext4_mb_mark_bb
authorRitesh Harjani <riteshh@linux.ibm.com>
Wed, 16 Feb 2022 07:02:43 +0000 (12:32 +0530)
committerStefan Bader <stefan.bader@canonical.com>
Wed, 27 Apr 2022 09:58:25 +0000 (11:58 +0200)
BugLink: https://bugs.launchpad.net/bugs/1969110
[ Upstream commit a5c0e2fdf7cea535ba03259894dc184e5a4c2800 ]

ext4_mb_mark_bb() currently wrongly calculates cluster len (clen) and
flex_group->free_clusters. This patch fixes that.

Identified based on code review of ext4_mb_mark_bb() function.

Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/a0b035d536bafa88110b74456853774b64c8ac40.1644992609.git.riteshh@linux.ibm.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Sasha Levin <sashal@kernel.org>
(cherry picked from commit 572d14e6cec4738d9e2878bd2cf8c070e3b64708)
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
fs/ext4/mballoc.c

index d2c906d3f63b6987b629d95fa3d8012242ef786f..d88f1364fa5a8c6c8d2cfb66763f1bde4482ae57 100644 (file)
@@ -3899,10 +3899,11 @@ void ext4_mb_mark_bb(struct super_block *sb, ext4_fsblk_t block,
        struct ext4_sb_info *sbi = EXT4_SB(sb);
        ext4_group_t group;
        ext4_grpblk_t blkoff;
-       int i, clen, err;
+       int i, err;
        int already;
+       unsigned int clen, clen_changed;
 
-       clen = EXT4_B2C(sbi, len);
+       clen = EXT4_NUM_B2C(sbi, len);
 
        ext4_get_group_no_and_offset(sb, block, &group, &blkoff);
        bitmap_bh = ext4_read_block_bitmap(sb, group);
@@ -3923,6 +3924,7 @@ void ext4_mb_mark_bb(struct super_block *sb, ext4_fsblk_t block,
                if (!mb_test_bit(blkoff + i, bitmap_bh->b_data) == !state)
                        already++;
 
+       clen_changed = clen - already;
        if (state)
                ext4_set_bits(bitmap_bh->b_data, blkoff, clen);
        else
@@ -3935,9 +3937,9 @@ void ext4_mb_mark_bb(struct super_block *sb, ext4_fsblk_t block,
                                                group, gdp));
        }
        if (state)
-               clen = ext4_free_group_clusters(sb, gdp) - clen + already;
+               clen = ext4_free_group_clusters(sb, gdp) - clen_changed;
        else
-               clen = ext4_free_group_clusters(sb, gdp) + clen - already;
+               clen = ext4_free_group_clusters(sb, gdp) + clen_changed;
 
        ext4_free_group_clusters_set(sb, gdp, clen);
        ext4_block_bitmap_csum_set(sb, group, gdp, bitmap_bh);
@@ -3947,10 +3949,13 @@ void ext4_mb_mark_bb(struct super_block *sb, ext4_fsblk_t block,
 
        if (sbi->s_log_groups_per_flex) {
                ext4_group_t flex_group = ext4_flex_group(sbi, group);
+               struct flex_groups *fg = sbi_array_rcu_deref(sbi,
+                                          s_flex_groups, flex_group);
 
-               atomic64_sub(len,
-                            &sbi_array_rcu_deref(sbi, s_flex_groups,
-                                                 flex_group)->free_clusters);
+               if (state)
+                       atomic64_sub(clen_changed, &fg->free_clusters);
+               else
+                       atomic64_add(clen_changed, &fg->free_clusters);
        }
 
        err = ext4_handle_dirty_metadata(NULL, NULL, bitmap_bh);