summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2009-03-05 02:35:15 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-03-16 17:32:43 -0700
commit9d9cc48d44908a2e476167fb1345d250225a8e69 (patch)
tree49f497724f208dd5608e5a44de15bf8561c24b05
parentf08d9c62257c72baacd3050b45f3073a815b5297 (diff)
downloadlinux-stable-9d9cc48d44908a2e476167fb1345d250225a8e69.tar.gz
ext4: Fix deadlock in ext4_write_begin() and ext4_da_write_begin()
(cherry picked from commit ebd3610b110bbb18ea6f9f2aeed1e1068c537227) Functions ext4_write_begin() and ext4_da_write_begin() call grab_cache_page_write_begin() without AOP_FLAG_NOFS. Thus it can happen that page reclaim is triggered in that function and it recurses back into the filesystem (or some other filesystem). But this can lead to various problems as a transaction is already started at that point. Add the necessary flag. http://bugzilla.kernel.org/show_bug.cgi?id=11688 Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--fs/ext4/inode.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c794e61127cf..b7f20b0bb0ee 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1347,6 +1347,10 @@ retry:
goto out;
}
+ /* We cannot recurse into the filesystem as the transaction is already
+ * started */
+ flags |= AOP_FLAG_NOFS;
+
page = grab_cache_page_write_begin(mapping, index, flags);
if (!page) {
ext4_journal_stop(handle);
@@ -1356,7 +1360,7 @@ retry:
*pagep = page;
ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- ext4_get_block);
+ ext4_get_block);
if (!ret && ext4_should_journal_data(inode)) {
ret = walk_page_buffers(handle, page_buffers(page),
@@ -2603,6 +2607,9 @@ retry:
ret = PTR_ERR(handle);
goto out;
}
+ /* We cannot recurse into the filesystem as the transaction is already
+ * started */
+ flags |= AOP_FLAG_NOFS;
page = grab_cache_page_write_begin(mapping, index, flags);
if (!page) {