| From ad95c5e9bc8b5885f94dce720137cac8fa8da4c9 Mon Sep 17 00:00:00 2001 |
| From: Jan Kara <jack@suse.cz> |
| Date: Mon, 30 May 2011 13:29:20 +0200 |
| Subject: ext3: Fix oops in ext3_try_to_allocate_with_rsv() |
| |
| From: Jan Kara <jack@suse.cz> |
| |
| commit ad95c5e9bc8b5885f94dce720137cac8fa8da4c9 upstream. |
| |
| Block allocation is called from two places: ext3_get_blocks_handle() and |
| ext3_xattr_block_set(). These two callers are not necessarily synchronized |
| because xattr code holds only xattr_sem and i_mutex, and |
| ext3_get_blocks_handle() may hold only truncate_mutex when called from |
| writepage() path. Block reservation code does not expect two concurrent |
| allocations to happen to the same inode and thus assertions can be triggered |
| or reservation structure corruption can occur. |
| |
| Fix the problem by taking truncate_mutex in xattr code to serialize |
| allocations. |
| |
| CC: Sage Weil <sage@newdream.net> |
| Reported-by: Fyodor Ustinov <ufm@ufm.su> |
| Signed-off-by: Jan Kara <jack@suse.cz> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| fs/ext3/xattr.c | 12 ++++++++++-- |
| 1 file changed, 10 insertions(+), 2 deletions(-) |
| |
| --- a/fs/ext3/xattr.c |
| +++ b/fs/ext3/xattr.c |
| @@ -800,8 +800,16 @@ inserted: |
| /* We need to allocate a new block */ |
| ext3_fsblk_t goal = ext3_group_first_block_no(sb, |
| EXT3_I(inode)->i_block_group); |
| - ext3_fsblk_t block = ext3_new_block(handle, inode, |
| - goal, &error); |
| + ext3_fsblk_t block; |
| + |
| + /* |
| + * Protect us agaist concurrent allocations to the |
| + * same inode from ext3_..._writepage(). Reservation |
| + * code does not expect racing allocations. |
| + */ |
| + mutex_lock(&EXT3_I(inode)->truncate_mutex); |
| + block = ext3_new_block(handle, inode, goal, &error); |
| + mutex_unlock(&EXT3_I(inode)->truncate_mutex); |
| if (error) |
| goto cleanup; |
| ea_idebug(inode, "creating block %d", block); |