linux/fs/ext4
Eric Sandeen d33a1976fb ext4: fix bb_prealloc_list corruption due to wrong group locking
This is for Red Hat bug 490026: EXT4 panic, list corruption in
ext4_mb_new_inode_pa

ext4_lock_group(sb, group) is supposed to protect this list for
each group, and a common code flow to remove an album is like
this:

    ext4_get_group_no_and_offset(sb, pa->pa_pstart, &grp, NULL);
    ext4_lock_group(sb, grp);
    list_del(&pa->pa_group_list);
    ext4_unlock_group(sb, grp);

so it's critical that we get the right group number back for
this prealloc context, to lock the right group (the one 
associated with this pa) and prevent concurrent list manipulation.

however, ext4_mb_put_pa() passes in (pa->pa_pstart - 1) with a 
comment, "-1 is to protect from crossing allocation group".

This makes sense for the group_pa, where pa_pstart is advanced
by the length which has been used (in ext4_mb_release_context()),
and when the entire length has been used, pa_pstart has been
advanced to the first block of the next group.

However, for inode_pa, pa_pstart is never advanced; it's just
set once to the first block in the group and not moved after
that.  So in this case, if we subtract one in ext4_mb_put_pa(),
we are actually locking the *previous* group, and opening the
race with the other threads which do not subtract off the extra
block.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
2009-03-16 23:25:40 -04:00
..
Kconfig
Makefile
acl.c
acl.h
balloc.c ext4: don't call jbd2_journal_force_commit_nested without journal 2009-02-26 00:57:35 -05:00
bitmap.c
dir.c ext4: Make printk's consistently prefixed with "EXT4-fs: " 2009-01-06 00:20:32 -05:00
ext4.h ext4: Fix to read empty directory blocks correctly in 64k 2009-02-10 09:53:42 -05:00
ext4_extents.h
ext4_i.h
ext4_jbd2.c
ext4_jbd2.h ext4: Remove "extents" mount option 2009-01-06 14:53:16 -05:00
ext4_sb.h fs: introduce bgl_lock_ptr() 2009-01-04 13:33:20 -08:00
extents.c ext4: fix header check in ext4_ext_search_right() for deep extent trees. 2009-03-10 18:18:47 -04:00
file.c
fsync.c
group.h
hash.c
ialloc.c ext4: Print the find_group_flex() warning only once 2009-03-12 12:20:01 -04:00
inode.c ext4: don't call jbd2_journal_force_commit_nested without journal 2009-02-26 00:57:35 -05:00
ioctl.c
mballoc.c ext4: fix bb_prealloc_list corruption due to wrong group locking 2009-03-16 23:25:40 -04:00
mballoc.h ext4: Don't allow new groups to be added during block allocation 2009-01-05 21:46:55 -05:00
migrate.c ext4: Fix NULL dereference in ext4_ext_migrate()'s error handling 2009-02-15 20:02:19 -05:00
namei.c ext4: Add sanity check to make_indexed_dir 2009-01-16 11:13:40 -05:00
namei.h
resize.c ext4: Initialize the new group descriptor when resizing the filesystem 2009-01-26 19:06:41 -05:00
super.c ext4: Remove duplicate call to ext4_commit_super() in ext4_freeze() 2009-02-28 00:08:53 -05:00
symlink.c
xattr.c
xattr.h
xattr_security.c
xattr_trusted.c
xattr_user.c