1 ext4: warn when page is dirtied without buffers
3 From: Jan Kara <jack@suse.cz>
5 Warn when a page is dirtied without buffers (as that will likely lead to
6 a crash in ext4_writepages()) or when it gets newly dirtied without the
7 page being locked (as there is nothing that prevents buffers to get
8 stripped just before calling set_page_dirty() under memory pressure).
10 Signed-off-by: Jan Kara <jack@suse.cz>
11 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
13 fs/ext4/inode.c | 9 +++++++++
14 1 file changed, 9 insertions(+)
16 Ted, how about merging this debug patch? It should catch situations like what
17 Nikolai reported early. I've run xfstests and neither warning triggers in my
18 test setup but maybe it will for somebody.
20 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
21 index 9c064727ed62..db0f11f49a37 100644
24 @@ -3615,6 +3615,13 @@ static int ext4_journalled_set_page_dirty(struct page *page)
25 return __set_page_dirty_nobuffers(page);
28 +static int ext4_set_page_dirty(struct page *page)
30 + WARN_ON_ONCE(!PageLocked(page) && !PageDirty(page));
31 + WARN_ON_ONCE(!page_has_buffers(page));
32 + return __set_page_dirty_buffers(page);
35 static const struct address_space_operations ext4_aops = {
36 .readpage = ext4_readpage,
37 .readpages = ext4_readpages,
38 @@ -3622,6 +3629,7 @@ static const struct address_space_operations ext4_aops = {
39 .writepages = ext4_writepages,
40 .write_begin = ext4_write_begin,
41 .write_end = ext4_write_end,
42 + .set_page_dirty = ext4_set_page_dirty,
44 .invalidatepage = ext4_invalidatepage,
45 .releasepage = ext4_releasepage,
46 @@ -3654,6 +3662,7 @@ static const struct address_space_operations ext4_da_aops = {
47 .writepages = ext4_writepages,
48 .write_begin = ext4_da_write_begin,
49 .write_end = ext4_da_write_end,
50 + .set_page_dirty = ext4_set_page_dirty,
52 .invalidatepage = ext4_da_invalidatepage,
53 .releasepage = ext4_releasepage,