Commit 9af0b3d12577 "ext4: fix race when setting the bitmap corrupted
flag" want to fix race between setting inode/block bitmap corrupted
flag and reducing free group inodes/clusters counter to prevent
multiple frees. But ext4_test_and_set_bit() will invoke
__test_and_set_bit() which is non-atomic, so the race is still there.
Fix this by invoke test_and_set_bit() instead.
Fixes: 9af0b3d12577 ("ext4: fix race when setting the bitmap corrupted flag")
Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
---
fs/ext4/ext4.h | 6 ++++++
fs/ext4/super.c | 6 ++----
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 3f89d0a..755ba14 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2888,6 +2888,12 @@ struct ext4_group_info {
(test_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &((grp)->bb_state)))
#define EXT4_MB_GRP_IBITMAP_CORRUPT(grp) \
(test_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &((grp)->bb_state)))
+#define EXT4_MB_GRP_TEST_AND_SET_BBITMAP_CORRUPT(grp) \
+ (test_and_set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, \
+ &((grp)->bb_state)))
+#define EXT4_MB_GRP_TEST_AND_SET_IBITMAP_CORRUPT(grp) \
+ (test_and_set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, \
+ &((grp)->bb_state)))