linux/fs/ext4
Aneesh Kumar K.V e8134b27e3 ext4: Fix race between read_block_bitmap() and mark_diskspace_used()
We need to make sure we update the block bitmap and clear
EXT4_BG_BLOCK_UNINIT flag with sb_bgl_lock held, since
ext4_read_block_bitmap() looks at EXT4_BG_BLOCK_UNINIT to decide
whether to initialize the block bitmap each time it is called
(introduced by commit c806e68f), and this can race with block
allocations in ext4_mb_mark_diskspace_used().

ext4_read_block_bitmap does:

spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group));
if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
	ext4_init_block_bitmap(sb, bh, block_group, desc);

Now on the block allocation side we do

mb_set_bits(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group), bitmap_bh->b_data,
			ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len);
....
spin_lock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
	gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);

ie on allocation we update the bitmap then we take the sb_bgl_lock
and clear the EXT4_BG_BLOCK_UNINIT flag. What can happen is a
parallel ext4_read_block_bitmap can zero out the bitmap in between
the above mb_set_bits and spin_lock(sb_bg_lock..)

The race results in below user visible errors
EXT4-fs error (device sdb1): ext4_mb_release_inode_pa: free 100, pa_free 105
EXT4-fs error (device sdb1): mb_free_blocks: double-free of inode 0's block ..

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: stable@kernel.org
2009-01-05 21:38:26 -05:00
..
Kconfig fs/Kconfig: move ext2, ext3, ext4, JBD, JBD2 out 2008-10-20 11:43:59 -07:00
Makefile ext4: Rename ext4dev to ext4 2008-10-10 20:02:48 -04:00
acl.c [PATCH] sanitize ->permission() prototype 2008-07-26 20:53:14 -04:00
acl.h ext4: Rename ext4dev to ext4 2008-10-10 20:02:48 -04:00
balloc.c ext4: Use EXT4_GROUP_INFO_NEED_INIT_BIT during resize 2009-01-05 21:36:19 -05:00
bitmap.c ext4: Change unsigned long to unsigned int 2008-11-05 00:14:04 -05:00
dir.c ext4: Change unsigned long to unsigned int 2008-11-05 00:14:04 -05:00
ext4.h ext4: fix BUG when calling ext4_error with locked block group 2009-01-05 22:19:52 -05:00
ext4_extents.h ext4: Remove i_ext_generation from ext4_inode_info structure 2008-11-04 18:46:03 -05:00
ext4_i.h ext4: Make ext4_group_t be an unsigned int 2009-01-05 22:18:16 -05:00
ext4_jbd2.c ext4: Allow ext4 to run without a journal 2009-01-07 00:06:22 -05:00
ext4_jbd2.h ext4: Allow ext4 to run without a journal 2009-01-07 00:06:22 -05:00
ext4_sb.h ext4: add fsync batch tuning knobs 2009-01-03 20:27:38 -05:00
extents.c ext4: sparse fixes 2008-11-22 15:04:59 -05:00
file.c ext4: sparse fixes 2008-11-22 15:04:59 -05:00
fsync.c ext4: Add debugging markers that can be used by systemtap 2008-10-05 20:50:06 -04:00
group.h ext4: Rename read_block_bitmap() to ext4_read_block_bitmap() 2008-07-11 19:27:31 -04:00
hash.c ext4: Add support for non-native signed/unsigned htree hash algorithms 2008-10-28 13:21:44 -04:00
ialloc.c ext4: Make ext4_group_t be an unsigned int 2009-01-05 22:18:16 -05:00
inode.c ext4: sparse fixes 2008-11-22 15:04:59 -05:00
ioctl.c ext4: Allow ext4 to run without a journal 2009-01-07 00:06:22 -05:00
mballoc.c ext4: Fix race between read_block_bitmap() and mark_diskspace_used() 2009-01-05 21:38:26 -05:00
mballoc.h ext4: fix BUG when calling ext4_error with locked block group 2009-01-05 22:19:52 -05:00
migrate.c ext4: Allow ext4 to run without a journal 2009-01-07 00:06:22 -05:00
namei.c ext4: Allow ext4 to run without a journal 2009-01-07 00:06:22 -05:00
namei.h [PATCH] ext4: rename ext4 symbols to avoid duplication of ext3 symbols 2006-10-11 11:14:15 -07:00
resize.c ext4: Use EXT4_GROUP_INFO_NEED_INIT_BIT during resize 2009-01-05 21:36:19 -05:00
super.c ext4: fix BUG when calling ext4_error with locked block group 2009-01-05 22:19:52 -05:00
symlink.c ext4: Rename ext4dev to ext4 2008-10-10 20:02:48 -04:00
xattr.c ext4: Allow ext4 to run without a journal 2009-01-07 00:06:22 -05:00
xattr.h ext4: Rename ext4dev to ext4 2008-10-10 20:02:48 -04:00
xattr_security.c ext4: move headers out of include/linux 2008-04-29 18:13:32 -04:00
xattr_trusted.c ext4: remove double definitions of xattr macros 2008-07-11 19:27:31 -04:00
xattr_user.c ext4: remove double definitions of xattr macros 2008-07-11 19:27:31 -04:00