ext4: Clear dirty bit from pages without data to write
authorJan Kara <jack@suse.cz>
Wed, 29 Mar 2023 15:49:35 +0000 (17:49 +0200)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 14 Apr 2023 23:55:44 +0000 (19:55 -0400)
With journalled data it can happen that checkpointing code will write
out page contents without clearing the page dirty bit. The logic in
ext4_page_nomap_can_writeout() then results in us never calling
mpage_submit_page() and thus clearing the dirty bit. Drop the
optimization with ext4_page_nomap_can_writeout() and just always call to
mpage_submit_page(). ext4_bio_write_page() knows when to redirty the
page and the additional clearing & setting of page dirty bit for ordered
mode writeout is not that expensive to jump through the hoops for it.

Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20230329154950.19720-4-jack@suse.cz
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/inode.c

index 473226783d003a436630dd320a1c4e918b462c8d..bca86f8f1594f8572f8d24825e22f1c366649dad 100644 (file)
@@ -2348,19 +2348,6 @@ static int ext4_da_writepages_trans_blocks(struct inode *inode)
                                MAX_WRITEPAGES_EXTENT_LEN + bpp - 1, bpp);
 }
 
-/* Return true if the folio needs to be written as part of transaction commit */
-static bool ext4_folio_nomap_can_writeout(struct folio *folio)
-{
-       struct buffer_head *bh, *head;
-
-       bh = head = folio_buffers(folio);
-       do {
-               if (buffer_dirty(bh) && buffer_mapped(bh) && !buffer_delay(bh))
-                       return true;
-       } while ((bh = bh->b_this_page) != head);
-       return false;
-}
-
 static int ext4_journal_page_buffers(handle_t *handle, struct page *page,
                                     int len)
 {
@@ -2545,13 +2532,11 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)
                         * range operations before discarding the page cache.
                         */
                        if (!mpd->can_map) {
-                               if (ext4_folio_nomap_can_writeout(folio)) {
-                                       WARN_ON_ONCE(sb->s_writers.frozen ==
-                                                    SB_FREEZE_COMPLETE);
-                                       err = mpage_submit_folio(mpd, folio);
-                                       if (err < 0)
-                                               goto out;
-                               }
+                               WARN_ON_ONCE(sb->s_writers.frozen ==
+                                            SB_FREEZE_COMPLETE);
+                               err = mpage_submit_folio(mpd, folio);
+                               if (err < 0)
+                                       goto out;
                                /* Pending dirtying of journalled data? */
                                if (folio_test_checked(folio)) {
                                        WARN_ON_ONCE(sb->s_writers.frozen >=