From: Greg Kroah-Hartman Date: Fri, 11 Dec 2009 04:10:05 +0000 (-0800) Subject: another .31 patch X-Git-Tag: v2.6.31.8~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ac3488771961292ead37862aaf707af4b6391960;p=thirdparty%2Fkernel%2Fstable-queue.git another .31 patch --- diff --git a/queue-2.6.31/ext4-fix-potential-fiemap-deadlock-mmap_sem-vs.-i_data_sem.patch b/queue-2.6.31/ext4-fix-potential-fiemap-deadlock-mmap_sem-vs.-i_data_sem.patch new file mode 100644 index 00000000000..323663d85a3 --- /dev/null +++ b/queue-2.6.31/ext4-fix-potential-fiemap-deadlock-mmap_sem-vs.-i_data_sem.patch @@ -0,0 +1,122 @@ +From stable-bounces@linux.kernel.org Thu Dec 10 15:52:55 2009 +From: "Theodore Ts'o" +Date: Thu, 10 Dec 2009 18:51:31 -0500 +Subject: ext4: Fix potential fiemap deadlock (mmap_sem vs. i_data_sem) +To: stable@kernel.org +Cc: "Theodore Ts'o" +Message-ID: <1260489091-29892-1-git-send-email-tytso@mit.edu> + +(cherry picked from commit fab3a549e204172236779f502eccb4f9bf0dc87d) + +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: [] might_fault+0x5c/0xac + + but task is already holding lock: + (&ei->i_data_sem){++++..}, at: [] 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){++++..}: + [] __lock_acquire+0xb67/0xd0f + [] lock_acquire+0xdc/0x102 + [] down_read+0x51/0x84 + [] ext4_get_blocks+0x50/0x2a5 + [] ext4_get_block+0xab/0xef + [] do_mpage_readpage+0x198/0x48d + [] mpage_readpages+0xd0/0x114 + [] ext4_readpages+0x1d/0x1f + [] __do_page_cache_readahead+0x12f/0x1bc + [] ra_submit+0x21/0x25 + [] filemap_fault+0x19f/0x32c + [] __do_fault+0x55/0x3a2 + [] handle_mm_fault+0x327/0x734 + [] do_page_fault+0x292/0x2aa + [] page_fault+0x25/0x30 + [] clear_user+0x38/0x3c + [] padzero+0x20/0x31 + [] load_elf_binary+0x8bc/0x17ed + [] search_binary_handler+0xc2/0x259 + [] load_script+0x1b8/0x1cc + [] search_binary_handler+0xc2/0x259 + [] do_execve+0x1ce/0x2cf + [] sys_execve+0x43/0x5a + [] stub_execve+0x6a/0xc0 + + -> #0 (&mm->mmap_sem){++++++}: + [] __lock_acquire+0xa11/0xd0f + [] lock_acquire+0xdc/0x102 + [] might_fault+0x89/0xac + [] fiemap_fill_next_extent+0x95/0xda + [] ext4_ext_fiemap_cb+0x138/0x157 + [] ext4_ext_walk_space+0x178/0x1f1 + [] ext4_fiemap+0x13c/0x159 + [] do_vfs_ioctl+0x348/0x4d6 + [] sys_ioctl+0x56/0x79 + [] 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: [] ext4_fiemap+0x11b/0x159 + + stack backtrace: + Pid: 1855, comm: ureadahead Not tainted 2.6.32-04115-gec044c5 #37 + Call Trace: + [] print_circular_bug+0xa8/0xb7 + [] __lock_acquire+0xa11/0xd0f + [] ? sched_clock+0x9/0xd + [] lock_acquire+0xdc/0x102 + [] ? might_fault+0x5c/0xac + [] might_fault+0x89/0xac + [] ? might_fault+0x5c/0xac + [] ? __kmalloc+0x13b/0x18c + [] fiemap_fill_next_extent+0x95/0xda + [] ext4_ext_fiemap_cb+0x138/0x157 + [] ? ext4_ext_fiemap_cb+0x0/0x157 + [] ext4_ext_walk_space+0x178/0x1f1 + [] ext4_fiemap+0x13c/0x159 + [] ? might_fault+0x5c/0xac + [] do_vfs_ioctl+0x348/0x4d6 + [] ? __up_read+0x8d/0x95 + [] ? retint_swapgs+0x13/0x1b + [] sys_ioctl+0x56/0x79 + [] system_call_fastpath+0x16/0x1b + +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/extents.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -1742,7 +1742,9 @@ int ext4_ext_walk_space(struct inode *in + 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; +@@ -3707,10 +3709,8 @@ int ext4_fiemap(struct inode *inode, str + * 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; diff --git a/queue-2.6.31/series b/queue-2.6.31/series index 19216e40afb..f9e4c5b173f 100644 --- a/queue-2.6.31/series +++ b/queue-2.6.31/series @@ -87,3 +87,4 @@ scsi-megaraid_sas-fix-64-bit-sense-pointer-truncation.patch scsi-osd_protocol.h-add-missing-include.patch scsi-scsi_lib_dma-fix-bug-with-dma-maps-on-nested-scsi-objects.patch signal-fix-alternate-signal-stack-check.patch +ext4-fix-potential-fiemap-deadlock-mmap_sem-vs.-i_data_sem.patch