switch-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
..
acl.c
acl.h
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
group.h
hash.c
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
Kconfig
Makefile
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
xattr.c ext4: Allow ext4 to run without a journal 2009-01-07 00:06:22 -05:00
xattr.h
xattr_security.c
xattr_trusted.c
xattr_user.c