aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2013-01-28 21:06:42 -0500
committerTheodore Ts'o <tytso@mit.edu>2013-01-28 21:06:42 -0500
commitfe386132f6731d02a45c380be0a3d339e6446cb5 (patch)
treeb28efc5faa2cad4823eaec0ef847a9446ef75a5b /fs/ext4
parent8a850c3fb8d0f204eabc1a32b502f47d3c16eac4 (diff)
ext4: fix ext4_writepage() to achieve data=ordered guarantees
So far ext4_writepage() skipped writing pages that had any delayed or unwritten buffers attached. When blocksize < pagesize this breaks data=ordered mode guarantees as we can have a page with one freshly allocated buffer whose allocation is part of the committing transaction and another buffer in the page which is delayed or unwritten. So fix this problem by calling ext4_bio_writepage() anyway. It will submit mapped buffers and leave others alone. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/inode.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 6824cb1bd1bb..86bf43d6dfcd 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1976,21 +1976,27 @@ static int ext4_writepage(struct page *page,
1976 len = PAGE_CACHE_SIZE; 1976 len = PAGE_CACHE_SIZE;
1977 1977
1978 page_bufs = page_buffers(page); 1978 page_bufs = page_buffers(page);
1979 /*
1980 * We cannot do block allocation or other extent handling in this
1981 * function. If there are buffers needing that, we have to redirty
1982 * the page. But we may reach here when we do a journal commit via
1983 * journal_submit_inode_data_buffers() and in that case we must write
1984 * allocated buffers to achieve data=ordered mode guarantees.
1985 */
1979 if (ext4_walk_page_buffers(NULL, page_bufs, 0, len, NULL, 1986 if (ext4_walk_page_buffers(NULL, page_bufs, 0, len, NULL,
1980 ext4_bh_delay_or_unwritten)) { 1987 ext4_bh_delay_or_unwritten)) {
1981 /*
1982 * We don't want to do block allocation, so redirty
1983 * the page and return. We may reach here when we do
1984 * a journal commit via journal_submit_inode_data_buffers.
1985 * We can also reach here via shrink_page_list but it
1986 * should never be for direct reclaim so warn if that
1987 * happens
1988 */
1989 WARN_ON_ONCE((current->flags & (PF_MEMALLOC|PF_KSWAPD)) ==
1990 PF_MEMALLOC);
1991 redirty_page_for_writepage(wbc, page); 1988 redirty_page_for_writepage(wbc, page);
1992 unlock_page(page); 1989 if (current->flags & PF_MEMALLOC) {
1993 return 0; 1990 /*
1991 * For memory cleaning there's no point in writing only
1992 * some buffers. So just bail out. Warn if we came here
1993 * from direct reclaim.
1994 */
1995 WARN_ON_ONCE((current->flags & (PF_MEMALLOC|PF_KSWAPD))
1996 == PF_MEMALLOC);
1997 unlock_page(page);
1998 return 0;
1999 }
1994 } 2000 }
1995 2001
1996 if (PageChecked(page) && ext4_should_journal_data(inode)) 2002 if (PageChecked(page) && ext4_should_journal_data(inode))