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
..
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: don't call jbd2_journal_force_commit_nested without journal 2009-02-26 00:57:35 -05:00
bitmap.c ext4: Change unsigned long to unsigned int 2008-11-05 00:14:04 -05:00
dir.c ext4: Make printk's consistently prefixed with "EXT4-fs: " 2009-01-06 00:20:32 -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: 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
ext4.h ext4: Fix to read empty directory blocks correctly in 64k 2009-02-10 09:53:42 -05: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 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
hash.c ext4: Add support for non-native signed/unsigned htree hash algorithms 2008-10-28 13:21:44 -04:00
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 ext4: Allow ext4 to run without a journal 2009-01-07 00:06:22 -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
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 ext4: Rename ext4dev to ext4 2008-10-10 20:02:48 -04:00
xattr_security.c
xattr_trusted.c
xattr_user.c
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