]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.0.1/ext3-fix-oops-in-ext3_try_to_allocate_with_rsv.patch
fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 3.0.1 / ext3-fix-oops-in-ext3_try_to_allocate_with_rsv.patch
1 From ad95c5e9bc8b5885f94dce720137cac8fa8da4c9 Mon Sep 17 00:00:00 2001
2 From: Jan Kara <jack@suse.cz>
3 Date: Mon, 30 May 2011 13:29:20 +0200
4 Subject: ext3: Fix oops in ext3_try_to_allocate_with_rsv()
5
6 From: Jan Kara <jack@suse.cz>
7
8 commit ad95c5e9bc8b5885f94dce720137cac8fa8da4c9 upstream.
9
10 Block allocation is called from two places: ext3_get_blocks_handle() and
11 ext3_xattr_block_set(). These two callers are not necessarily synchronized
12 because xattr code holds only xattr_sem and i_mutex, and
13 ext3_get_blocks_handle() may hold only truncate_mutex when called from
14 writepage() path. Block reservation code does not expect two concurrent
15 allocations to happen to the same inode and thus assertions can be triggered
16 or reservation structure corruption can occur.
17
18 Fix the problem by taking truncate_mutex in xattr code to serialize
19 allocations.
20
21 CC: Sage Weil <sage@newdream.net>
22 Reported-by: Fyodor Ustinov <ufm@ufm.su>
23 Signed-off-by: Jan Kara <jack@suse.cz>
24 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
25
26 ---
27 fs/ext3/xattr.c | 12 ++++++++++--
28 1 file changed, 10 insertions(+), 2 deletions(-)
29
30 --- a/fs/ext3/xattr.c
31 +++ b/fs/ext3/xattr.c
32 @@ -803,8 +803,16 @@ inserted:
33 /* We need to allocate a new block */
34 ext3_fsblk_t goal = ext3_group_first_block_no(sb,
35 EXT3_I(inode)->i_block_group);
36 - ext3_fsblk_t block = ext3_new_block(handle, inode,
37 - goal, &error);
38 + ext3_fsblk_t block;
39 +
40 + /*
41 + * Protect us agaist concurrent allocations to the
42 + * same inode from ext3_..._writepage(). Reservation
43 + * code does not expect racing allocations.
44 + */
45 + mutex_lock(&EXT3_I(inode)->truncate_mutex);
46 + block = ext3_new_block(handle, inode, goal, &error);
47 + mutex_unlock(&EXT3_I(inode)->truncate_mutex);
48 if (error)
49 goto cleanup;
50 ea_idebug(inode, "creating block %d", block);