Skip to content

Commit d84c9eb

Browse files
jankaratytso
authored andcommitted
ext4: Mark pages with journalled data dirty
Currently pages with journalled data written by write(2) or modified by block zeroing during truncate(2) are not marked as dirty. They are dirtied only once the transaction commits. This however makes writeback code think inode has no pages to write and so ext4_writepages() is not called to make pages with journalled data persistent. Mark pages with journalled data dirty (similarly as it happens for writes through mmap) so that writeback code knows about them and ext4_writepages() can do what it needs to to the inode. Signed-off-by: Jan Kara <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent bd15939 commit d84c9eb

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

fs/ext4/inode.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,18 @@ int ext4_walk_page_buffers(handle_t *handle, struct inode *inode,
10031003
return ret;
10041004
}
10051005

1006+
/*
1007+
* Helper for handling dirtying of journalled data. We also mark the folio as
1008+
* dirty so that writeback code knows about this page (and inode) contains
1009+
* dirty data. ext4_writepages() then commits appropriate transaction to
1010+
* make data stable.
1011+
*/
1012+
static int ext4_dirty_journalled_data(handle_t *handle, struct buffer_head *bh)
1013+
{
1014+
folio_mark_dirty(bh->b_folio);
1015+
return ext4_handle_dirty_metadata(handle, NULL, bh);
1016+
}
1017+
10061018
int do_journal_get_write_access(handle_t *handle, struct inode *inode,
10071019
struct buffer_head *bh)
10081020
{
@@ -1025,7 +1037,7 @@ int do_journal_get_write_access(handle_t *handle, struct inode *inode,
10251037
ret = ext4_journal_get_write_access(handle, inode->i_sb, bh,
10261038
EXT4_JTR_NONE);
10271039
if (!ret && dirty)
1028-
ret = ext4_handle_dirty_metadata(handle, NULL, bh);
1040+
ret = ext4_dirty_journalled_data(handle, bh);
10291041
return ret;
10301042
}
10311043

@@ -1272,7 +1284,7 @@ static int write_end_fn(handle_t *handle, struct inode *inode,
12721284
if (!buffer_mapped(bh) || buffer_freed(bh))
12731285
return 0;
12741286
set_buffer_uptodate(bh);
1275-
ret = ext4_handle_dirty_metadata(handle, NULL, bh);
1287+
ret = ext4_dirty_journalled_data(handle, bh);
12761288
clear_buffer_meta(bh);
12771289
clear_buffer_prio(bh);
12781290
return ret;
@@ -1356,7 +1368,7 @@ static int ext4_write_end(struct file *file,
13561368
/*
13571369
* This is a private version of page_zero_new_buffers() which doesn't
13581370
* set the buffer to be dirty, since in data=journalled mode we need
1359-
* to call ext4_handle_dirty_metadata() instead.
1371+
* to call ext4_dirty_journalled_data() instead.
13601372
*/
13611373
static void ext4_journalled_zero_new_buffers(handle_t *handle,
13621374
struct inode *inode,
@@ -3740,7 +3752,7 @@ static int __ext4_block_zero_page_range(handle_t *handle,
37403752
BUFFER_TRACE(bh, "zeroed end of block");
37413753

37423754
if (ext4_should_journal_data(inode)) {
3743-
err = ext4_handle_dirty_metadata(handle, inode, bh);
3755+
err = ext4_dirty_journalled_data(handle, bh);
37443756
} else {
37453757
err = 0;
37463758
mark_buffer_dirty(bh);

0 commit comments

Comments
 (0)