Skip to content

Commit 4e0bc3f

Browse files
taoma-tmgregkh
authored andcommitted
ext4: protect group inode free counting with group lock
commit 6f2e9f0 upstream. Now when we set the group inode free count, we don't have a proper group lock so that multiple threads may decrease the inode free count at the same time. And e2fsck will complain something like: Free inodes count wrong for group #1 (1, counted=0). Fix? no Free inodes count wrong for group #2 (3, counted=0). Fix? no Directories count wrong for group #2 (780, counted=779). Fix? no Free inodes count wrong for group #3 (2272, counted=2273). Fix? no So this patch try to protect it with the ext4_lock_group. btw, it is found by xfstests test case 269 and the volume is mkfsed with the parameter "-O ^resize_inode,^uninit_bg,extent,meta_bg,flex_bg,ext_attr" and I have run it 100 times and the error in e2fsck doesn't show up again. Signed-off-by: Tao Ma <boyu.mt@taobao.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Signed-off-by: Benjamin LaHaise <bcrl@kvack.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 5e23efd commit 4e0bc3f

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

fs/ext4/ialloc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,8 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, umode_t mode,
778778
ext4_itable_unused_set(sb, gdp,
779779
(EXT4_INODES_PER_GROUP(sb) - ino));
780780
up_read(&grp->alloc_sem);
781+
} else {
782+
ext4_lock_group(sb, group);
781783
}
782784
ext4_free_inodes_set(sb, gdp, ext4_free_inodes_count(sb, gdp) - 1);
783785
if (S_ISDIR(mode)) {
@@ -790,8 +792,8 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, umode_t mode,
790792
}
791793
if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
792794
gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
793-
ext4_unlock_group(sb, group);
794795
}
796+
ext4_unlock_group(sb, group);
795797

796798
BUFFER_TRACE(group_desc_bh, "call ext4_handle_dirty_metadata");
797799
err = ext4_handle_dirty_metadata(handle, NULL, group_desc_bh);

0 commit comments

Comments
 (0)