]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ext4: use jbd2 jinode dirty range accessor
authorLi Chen <me@linux.beauty>
Fri, 6 Mar 2026 08:56:40 +0000 (16:56 +0800)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 9 Apr 2026 14:51:05 +0000 (10:51 -0400)
ext4 journal commit callbacks access jbd2_inode dirty range fields without
holding journal->j_list_lock.
Use jbd2_jinode_get_dirty_range() to get the range in bytes, and read
i_transaction with READ_ONCE() in the redirty check.

Suggested-by: Jan Kara <jack@suse.cz>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Li Chen <me@linux.beauty>
Link: https://patch.msgid.link/20260306085643.465275-3-me@linux.beauty
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/inode.c
fs/ext4/super.c

index 025ea8f0c41bdfae8703529a09f4da60b0b89d2c..13cd564f89e1fb2377826447a40992b6ee5019ef 100644 (file)
@@ -3055,17 +3055,23 @@ static int ext4_writepages(struct address_space *mapping,
 
 int ext4_normal_submit_inode_data_buffers(struct jbd2_inode *jinode)
 {
+       loff_t range_start, range_end;
        struct writeback_control wbc = {
                .sync_mode = WB_SYNC_ALL,
                .nr_to_write = LONG_MAX,
-               .range_start = jinode->i_dirty_start,
-               .range_end = jinode->i_dirty_end,
        };
        struct mpage_da_data mpd = {
                .inode = jinode->i_vfs_inode,
                .wbc = &wbc,
                .can_map = 0,
        };
+
+       if (!jbd2_jinode_get_dirty_range(jinode, &range_start, &range_end))
+               return 0;
+
+       wbc.range_start = range_start;
+       wbc.range_end = range_end;
+
        return ext4_do_writepages(&mpd);
 }
 
index a34efb44e73d70d034aa2ed1b4011a6851235f22..638d859f4fca49b2969bc3dc3f2c8ae957ab474c 100644 (file)
@@ -521,6 +521,7 @@ static bool ext4_journalled_writepage_needs_redirty(struct jbd2_inode *jinode,
 {
        struct buffer_head *bh, *head;
        struct journal_head *jh;
+       transaction_t *trans = READ_ONCE(jinode->i_transaction);
 
        bh = head = folio_buffers(folio);
        do {
@@ -539,7 +540,7 @@ static bool ext4_journalled_writepage_needs_redirty(struct jbd2_inode *jinode,
                 */
                jh = bh2jh(bh);
                if (buffer_dirty(bh) ||
-                   (jh && (jh->b_transaction != jinode->i_transaction ||
+                   (jh && (jh->b_transaction != trans ||
                            jh->b_next_transaction)))
                        return true;
        } while ((bh = bh->b_this_page) != head);
@@ -550,15 +551,20 @@ static bool ext4_journalled_writepage_needs_redirty(struct jbd2_inode *jinode,
 static int ext4_journalled_submit_inode_data_buffers(struct jbd2_inode *jinode)
 {
        struct address_space *mapping = jinode->i_vfs_inode->i_mapping;
+       loff_t range_start, range_end;
        struct writeback_control wbc = {
-               .sync_mode =  WB_SYNC_ALL,
+               .sync_mode = WB_SYNC_ALL,
                .nr_to_write = LONG_MAX,
-               .range_start = jinode->i_dirty_start,
-               .range_end = jinode->i_dirty_end,
-        };
+       };
        struct folio *folio = NULL;
        int error;
 
+       if (!jbd2_jinode_get_dirty_range(jinode, &range_start, &range_end))
+               return 0;
+
+       wbc.range_start = range_start;
+       wbc.range_end = range_end;
+
        /*
         * writeback_iter() already checks for dirty pages and calls
         * folio_clear_dirty_for_io(), which we want to write protect the