Skip to content

Commit

Permalink
ext3: Fix oops in ext3_try_to_allocate_with_rsv()
Browse files Browse the repository at this point in the history
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>
CC: stable@kernel.org
Reported-by: Fyodor Ustinov <ufm@ufm.su>
Signed-off-by: Jan Kara <jack@suse.cz>
  • Loading branch information
Jan Kara committed Jun 25, 2011
1 parent bd5c9e1 commit ad95c5e
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions fs/ext3/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -803,8 +803,16 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode,
/* 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);
Expand Down

0 comments on commit ad95c5e

Please sign in to comment.