aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2010-08-05 14:41:42 -0400
committerTheodore Ts'o <tytso@mit.edu>2010-08-05 14:41:42 -0400
commit56d35a4cd13e7bc5eca5b2dba5a41794afb17e11 (patch)
tree8173b2de9f0f2b596812a725ac1897efa0ba38fc
parent0cfc9255a1efb0467de2162950197750570ecec0 (diff)
ext4: Fix dirtying of journalled buffers in data=journal mode
In data=journal mode, we still use block_write_begin() to prepare page for writing. This function can occasionally mark buffer dirty which violates journalling assumptions - when a buffer is part of a transaction, it should be dirty and a buffer can be already part of a forget list of some transaction when block_write_begin() gets called. This violation of journalling assumptions then results in "JBD: Spotted dirty metadata buffer..." warnings. In fact, temporary dirtying the buffer while the page is still locked does not really cause problems to the journalling because we won't write the buffer until the page gets unlocked. So we just have to make sure to clear dirty bits before unlocking the page. Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/ext4/inode.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index ab2247d642c6..a0ab3754d0d6 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1527,9 +1527,25 @@ static int walk_page_buffers(handle_t *handle,
1527static int do_journal_get_write_access(handle_t *handle, 1527static int do_journal_get_write_access(handle_t *handle,
1528 struct buffer_head *bh) 1528 struct buffer_head *bh)
1529{ 1529{
1530 int dirty = buffer_dirty(bh);
1531 int ret;
1532
1530 if (!buffer_mapped(bh) || buffer_freed(bh)) 1533 if (!buffer_mapped(bh) || buffer_freed(bh))
1531 return 0; 1534 return 0;
1532 return ext4_journal_get_write_access(handle, bh); 1535 /*
1536 * __block_prepare_write() could have dirtied some buffers. Clean
1537 * the dirty bit as jbd2_journal_get_write_access() could complain
1538 * otherwise about fs integrity issues. Setting of the dirty bit
1539 * by __block_prepare_write() isn't a real problem here as we clear
1540 * the bit before releasing a page lock and thus writeback cannot
1541 * ever write the buffer.
1542 */
1543 if (dirty)
1544 clear_buffer_dirty(bh);
1545 ret = ext4_journal_get_write_access(handle, bh);
1546 if (!ret && dirty)
1547 ret = ext4_handle_dirty_metadata(handle, NULL, bh);
1548 return ret;
1533} 1549}
1534 1550
1535/* 1551/*