aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/inode.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2010-08-05 06:38:26 -0400
committerJan Kara <jack@suse.cz>2010-08-05 15:28:28 -0400
commit5f11e6a44059f728dddd8d0dbe5b4368ea93575b (patch)
treec66eed7a13b1de48d9a6539b9a7c7a27bda706c6 /fs/ext3/inode.c
parentaa32a796389bedbcf1c7714385b18714a0743810 (diff)
ext3: 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. Reviewed-by: "Theodore Ts'o" <tytso@mit.edu> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ext3/inode.c')
-rw-r--r--fs/ext3/inode.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 436e5bbccbc..001eb0e2d48 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1149,9 +1149,25 @@ static int walk_page_buffers( handle_t *handle,
1149static int do_journal_get_write_access(handle_t *handle, 1149static int do_journal_get_write_access(handle_t *handle,
1150 struct buffer_head *bh) 1150 struct buffer_head *bh)
1151{ 1151{
1152 int dirty = buffer_dirty(bh);
1153 int ret;
1154
1152 if (!buffer_mapped(bh) || buffer_freed(bh)) 1155 if (!buffer_mapped(bh) || buffer_freed(bh))
1153 return 0; 1156 return 0;
1154 return ext3_journal_get_write_access(handle, bh); 1157 /*
1158 * __block_prepare_write() could have dirtied some buffers. Clean
1159 * the dirty bit as jbd2_journal_get_write_access() could complain
1160 * otherwise about fs integrity issues. Setting of the dirty bit
1161 * by __block_prepare_write() isn't a real problem here as we clear
1162 * the bit before releasing a page lock and thus writeback cannot
1163 * ever write the buffer.
1164 */
1165 if (dirty)
1166 clear_buffer_dirty(bh);
1167 ret = ext3_journal_get_write_access(handle, bh);
1168 if (!ret && dirty)
1169 ret = ext3_journal_dirty_metadata(handle, bh);
1170 return ret;
1155} 1171}
1156 1172
1157/* 1173/*