projects
/
openwrt
/
staging
/
blogic.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
| inline |
side by side
(parent:
a214238
)
ext4: Fix potential fiemap deadlock (mmap_sem vs. i_data_sem)
author
Theodore Ts'o
<tytso@mit.edu>
Thu, 10 Dec 2009 02:30:02 +0000
(21:30 -0500)
committer
Theodore Ts'o
<tytso@mit.edu>
Thu, 10 Dec 2009 02:30:02 +0000
(21:30 -0500)
Fix the following potential circular locking dependency between
mm->mmap_sem and ei->i_data_sem:
=======================================================
[ INFO: possible circular locking dependency detected ]
2.6.32-04115-gec044c5
#37
-------------------------------------------------------
ureadahead/1855 is trying to acquire lock:
(&mm->mmap_sem){++++++}, at: [<
ffffffff81107224
>] might_fault+0x5c/0xac
but task is already holding lock:
(&ei->i_data_sem){++++..}, at: [<
ffffffff811be1fd
>] ext4_fiemap+0x11b/0x159
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&ei->i_data_sem){++++..}:
[<
ffffffff81099bfa
>] __lock_acquire+0xb67/0xd0f
[<
ffffffff81099e7e
>] lock_acquire+0xdc/0x102
[<
ffffffff81516633
>] down_read+0x51/0x84
[<
ffffffff811a2414
>] ext4_get_blocks+0x50/0x2a5
[<
ffffffff811a3453
>] ext4_get_block+0xab/0xef
[<
ffffffff81154f39
>] do_mpage_readpage+0x198/0x48d
[<
ffffffff81155360
>] mpage_readpages+0xd0/0x114
[<
ffffffff811a104b
>] ext4_readpages+0x1d/0x1f
[<
ffffffff810f8644
>] __do_page_cache_readahead+0x12f/0x1bc
[<
ffffffff810f86f2
>] ra_submit+0x21/0x25
[<
ffffffff810f0cfd
>] filemap_fault+0x19f/0x32c
[<
ffffffff81107b97
>] __do_fault+0x55/0x3a2
[<
ffffffff81109db0
>] handle_mm_fault+0x327/0x734
[<
ffffffff8151aaa9
>] do_page_fault+0x292/0x2aa
[<
ffffffff81518205
>] page_fault+0x25/0x30
[<
ffffffff812a34d8
>] clear_user+0x38/0x3c
[<
ffffffff81167e16
>] padzero+0x20/0x31
[<
ffffffff81168b47
>] load_elf_binary+0x8bc/0x17ed
[<
ffffffff81130e95
>] search_binary_handler+0xc2/0x259
[<
ffffffff81166d64
>] load_script+0x1b8/0x1cc
[<
ffffffff81130e95
>] search_binary_handler+0xc2/0x259
[<
ffffffff8113255f
>] do_execve+0x1ce/0x2cf
[<
ffffffff81027494
>] sys_execve+0x43/0x5a
[<
ffffffff8102918a
>] stub_execve+0x6a/0xc0
-> #0 (&mm->mmap_sem){++++++}:
[<
ffffffff81099aa4
>] __lock_acquire+0xa11/0xd0f
[<
ffffffff81099e7e
>] lock_acquire+0xdc/0x102
[<
ffffffff81107251
>] might_fault+0x89/0xac
[<
ffffffff81139382
>] fiemap_fill_next_extent+0x95/0xda
[<
ffffffff811bcb43
>] ext4_ext_fiemap_cb+0x138/0x157
[<
ffffffff811be069
>] ext4_ext_walk_space+0x178/0x1f1
[<
ffffffff811be21e
>] ext4_fiemap+0x13c/0x159
[<
ffffffff811390e6
>] do_vfs_ioctl+0x348/0x4d6
[<
ffffffff811392ca
>] sys_ioctl+0x56/0x79
[<
ffffffff81028cb2
>] system_call_fastpath+0x16/0x1b
other info that might help us debug this:
1 lock held by ureadahead/1855:
#0: (&ei->i_data_sem){++++..}, at: [<
ffffffff811be1fd
>] ext4_fiemap+0x11b/0x159
stack backtrace:
Pid: 1855, comm: ureadahead Not tainted
2.6.32-04115-gec044c5
#37
Call Trace:
[<
ffffffff81098c70
>] print_circular_bug+0xa8/0xb7
[<
ffffffff81099aa4
>] __lock_acquire+0xa11/0xd0f
[<
ffffffff8102f229
>] ? sched_clock+0x9/0xd
[<
ffffffff81099e7e
>] lock_acquire+0xdc/0x102
[<
ffffffff81107224
>] ? might_fault+0x5c/0xac
[<
ffffffff81107251
>] might_fault+0x89/0xac
[<
ffffffff81107224
>] ? might_fault+0x5c/0xac
[<
ffffffff81124b44
>] ? __kmalloc+0x13b/0x18c
[<
ffffffff81139382
>] fiemap_fill_next_extent+0x95/0xda
[<
ffffffff811bcb43
>] ext4_ext_fiemap_cb+0x138/0x157
[<
ffffffff811bca0b
>] ? ext4_ext_fiemap_cb+0x0/0x157
[<
ffffffff811be069
>] ext4_ext_walk_space+0x178/0x1f1
[<
ffffffff811be21e
>] ext4_fiemap+0x13c/0x159
[<
ffffffff81107224
>] ? might_fault+0x5c/0xac
[<
ffffffff811390e6
>] do_vfs_ioctl+0x348/0x4d6
[<
ffffffff8129f6d0
>] ? __up_read+0x8d/0x95
[<
ffffffff81517fb5
>] ? retint_swapgs+0x13/0x1b
[<
ffffffff811392ca
>] sys_ioctl+0x56/0x79
[<
ffffffff81028cb2
>] system_call_fastpath+0x16/0x1b
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
fs/ext4/extents.c
patch
|
blob
|
history
diff --git
a/fs/ext4/extents.c
b/fs/ext4/extents.c
index 700206e525dabef2cf130dd4ce1137fe7e795523..3a7928f825e45f8fb244587cbe7c8921f6a3269b 100644
(file)
--- a/
fs/ext4/extents.c
+++ b/
fs/ext4/extents.c
@@
-1762,7
+1762,9
@@
int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block,
while (block < last && block != EXT_MAX_BLOCK) {
num = last - block;
/* find extent for this block */
+ down_read(&EXT4_I(inode)->i_data_sem);
path = ext4_ext_find_extent(inode, block, path);
+ up_read(&EXT4_I(inode)->i_data_sem);
if (IS_ERR(path)) {
err = PTR_ERR(path);
path = NULL;
@@
-3724,10
+3726,8
@@
int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
* Walk the extent tree gathering extent information.
* ext4_ext_fiemap_cb will push extents back to user.
*/
- down_read(&EXT4_I(inode)->i_data_sem);
error = ext4_ext_walk_space(inode, start_blk, len_blks,
ext4_ext_fiemap_cb, fieinfo);
- up_read(&EXT4_I(inode)->i_data_sem);
}
return error;