On 10/30/20 9:51 AM, Naohiro Aota wrote:
Tree manipulating operations like merging nodes often release
once-allocated tree nodes. Btrfs cleans such nodes so that pages in the
node are not uselessly written out. On ZONED volumes, however, such
optimization blocks the following IOs as the cancellation of the write out
of the freed blocks breaks the sequential write sequence expected by the
device.
This patch introduces a list of clean and unwritten extent buffers that
have been released in a transaction. Btrfs redirty the buffer so that
btree_write_cache_pages() can send proper bios to the devices.
Besides it clears the entire content of the extent buffer not to confuse
raw block scanners e.g. btrfsck. By clearing the content,
csum_dirty_buffer() complains about bytenr mismatch, so avoid the checking
and checksum using newly introduced buffer flag EXTENT_BUFFER_NO_CHECK.
Signed-off-by: Naohiro Aota <naohiro.aota@xxxxxxx>
This is a lot of work when you could just add
if (btrfs_is_zoned(fs_info))
return;
to btrfs_clean_tree_block(). The dirty secret is we don't actually unset the
bits in the transaction io tree because it would require memory allocation
sometimes, so you don't even need to mess with ->dirty_pages in the first place.
The only thing you need is to keep from clearing the EB dirty. In fact you
could just do
if (btrfs_is_zoned(fs_info)) {
memzero_extent_buffer(eb, 0, eb->len);
set_bit(EXTENT_BUFFER_NO_CHECK, &eb->bflags);
}
to btrfs_clean_tree_block() and then in btrfs_free_tree_block() make sure we
always pin the extent if we're zoned. Thanks,
Josef