linux/fs/ext4
Aneesh Kumar K.V 393418676a ext4: Fix the race between read_inode_bitmap() and ext4_new_inode()
We need to make sure we update the inode bitmap and clear
EXT4_BG_INODE_UNINIT flag with sb_bgl_lock held, since
ext4_read_inode_bitmap() looks at EXT4_BG_INODE_UNINIT to decide
whether to initialize the inode bitmap each time it is called.
(introduced by commit c806e68f.)

ext4_read_inode_bitmap does:

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

and ext4_new_inode does
if (!ext4_set_bit_atomic(sb_bgl_lock(sbi, group),
                   ino, inode_bitmap_bh->b_data))
		   ......
		   ...
spin_lock(sb_bgl_lock(sbi, group));

gdp->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
i.e., on allocation we update the bitmap then we take the sb_bgl_lock
and clear the EXT4_BG_INODE_UNINIT flag. What can happen is a
parallel ext4_read_inode_bitmap can zero out the bitmap in between
the above ext4_set_bit_atomic and spin_lock(sb_bg_lock..)

The race results in below user visible errors
EXT4-fs error (device sdb1): ext4_free_inode: bit already cleared for inode 168449
EXT4-fs warning (device sdb1): ext4_unlink: Deleting nonexistent file ...
EXT4-fs warning (device sdb1): ext4_rmdir: empty directory has too many links ...
# ls -al /mnt/tmp/f/p369/d3/d6/d39/db2/dee/d10f/d3f/l71
ls: /mnt/tmp/f/p369/d3/d6/d39/db2/dee/d10f/d3f/l71: Stale NFS file handle

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:14 -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 high 16 bits of the block group descriptor's free counts fields 2009-01-05 22:20:24 -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: Use high 16 bits of the block group descriptor's free counts fields 2009-01-05 22:20:24 -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: Fix the race between read_inode_bitmap() and ext4_new_inode() 2009-01-05 21:38:14 -05:00
inode.c ext4: Use high 16 bits of the block group descriptor's free counts fields 2009-01-05 22:20:24 -05:00
ioctl.c ext4: Allow ext4 to run without a journal 2009-01-07 00:06:22 -05:00
mballoc.c ext4: Use high 16 bits of the block group descriptor's free counts fields 2009-01-05 22:20:24 -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
resize.c ext4: Use high 16 bits of the block group descriptor's free counts fields 2009-01-05 22:20:24 -05:00
super.c ext4: Use high 16 bits of the block group descriptor's free counts fields 2009-01-05 22:20:24 -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