Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
btrfs: allow buffered write to skip full page if it's sector aligned
[BUG] Since the support of sector size < page size for btrfs, test case generic/563 fails with 4K sector size and 64K page size: --- tests/generic/563.out 2024-04-25 18:13:45.178550333 +0930 +++ /home/adam/xfstests-dev/results//generic/563.out.bad 2024-09-30 09:09:16.155312379 +0930 @@ -3,7 +3,8 @@ read is in range write is in range write -> read/write -read is in range +read has value of 8388608 +read is NOT in range -33792 .. 33792 write is in range ... [CAUSE] The test case creates a 8MiB file, then buffered write into the 8MiB using 4K block size, to overwrite the whole file. On 4K page sized systems, since the write range covers the full sector and page, btrfs will no bother reading the page, just like what XFS and EXT4 do. But 64K page sized systems, although the write is sector aligned, it's not page aligned, thus btrfs still goes the full page alignment check, and read the full page out. This causes extra data read, and fail the test case. [FIX] To skip the full page read, we need to do the following modification: - Do not trigger full page read as long as the buffered write is sector aligned This is pretty simple by modifying the check inside prepare_uptodate_page(). - Skip already uptodate sectors during full page read Or we can lead to the following data corruption: 0 32K 64K |///////| | Where the file range [0, 32K) is dirtied by buffered write, the remaining range [32K, 64K) is not. When reading the full page, since [0,32K) is only dirtied but not written back, there is no data extent map for it, but a hole covering [0, 64k). If we continue reading the full page range [0, 64K), the dirtied range will be filled with 0 (since there is only a hole covering the whole range). This causes the dirtied range to get lost. Signed-off-by: Qu Wenruo <[email protected]> Signed-off-by: David Sterba <[email protected]>
- Loading branch information