Skip to content

Commit 4e30444

Browse files
committed
btrfs: use dirty flag to check if an ordered extent needs to be truncated
Currently there are only two folio ordered flag users: - extent_writepage_io() To ensure the folio range has an ordered extent covering it. This is from the legacy COW fixup mechanism, which is already removed and only a simple check is left. - btrfs_invalidate_folio() This is to avoid race with end_bbio_data_write(), where btrfs_finish_ordered_extent() will be called to handle the OE finishing. But for btrfs_invalidate_folio() we have already waited for the folio writeback to finish, and locked the folio. This means we can use the dirty flag to check if a range is already submitted or not. If the OE range is not dirty, it means the range has been submitted and its dirty flag was cleared. And since we have already waited for writeback, the endio function will handle the OE finishing. Thus if the range is not dirty, we must skip the range. If the OE range is dirty, it means we have allocated an ordered extent but have not yet submitted the range. And that's exactly the case where we need to truncate the ordered extent. Signed-off-by: Qu Wenruo <wqu@suse.com>
1 parent 04479f1 commit 4e30444

1 file changed

Lines changed: 13 additions & 8 deletions

File tree

fs/btrfs/inode.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7593,15 +7593,20 @@ static void btrfs_invalidate_folio(struct folio *folio, size_t offset,
75937593
page_end);
75947594
ASSERT(range_end + 1 - cur < U32_MAX);
75957595
range_len = range_end + 1 - cur;
7596-
if (!btrfs_folio_test_ordered(fs_info, folio, cur, range_len)) {
7597-
/*
7598-
* If Ordered is cleared, it means endio has
7599-
* already been executed for the range.
7600-
* We can't delete the extent states as
7601-
* btrfs_finish_ordered_io() may still use some of them.
7602-
*/
7596+
/*
7597+
* If the range is not dirty, the range has been submitted and
7598+
* since we have waited for the writeback, endio has been
7599+
* executed, thus we must skip the range to avoid double
7600+
* accounting for the ordered extent.
7601+
*/
7602+
if (!btrfs_folio_test_dirty(fs_info, folio, cur, range_len))
76037603
goto next;
7604-
}
7604+
7605+
/*
7606+
* The range is dirty meaning it has not been submitted.
7607+
* Here we need to truncate the OE range as the range will never
7608+
* be submitted.
7609+
*/
76057610
btrfs_folio_clear_ordered(fs_info, folio, cur, range_len);
76067611

76077612
/*

0 commit comments

Comments
 (0)