[2/5] btrfs: zoned: don't clear dirty flag of extent buffer
Commit Message
One a zoned filesystem, never clear the dirty flag of an extent buffer,
but instead mark it as cancelled.
On writeout, when encountering cancelled extent_buffers, zero them out.
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
fs/btrfs/disk-io.c | 2 +-
fs/btrfs/extent_io.c | 7 +++++--
fs/btrfs/zoned.c | 3 ++-
3 files changed, 8 insertions(+), 4 deletions(-)
Comments
> if (test_bit(EXTENT_BUFFER_CANCELLED, &eb->bflags)) {
> - WARN_ON_ONCE(found_start != 0);
> + memzero_extent_buffer(eb, 0, eb->len);
> return BLK_STS_OK;
> + if (btrfs_is_zoned(fs_info)) {
> + set_bit(EXTENT_BUFFER_CANCELLED, &eb->bflags);
> + return;
> + }
Maybe these two places would benefit from comments on why the buffer
is just marked as cancelled and zeroed out (that is to keep the
write order because block numbers are already assigned)?
Otherwise this looks great:
Reviewed-by: Christoph Hellwig <hch@lst.de>
@@ -255,7 +255,7 @@ blk_status_t btree_csum_one_bio(struct btrfs_bio *bbio)
return BLK_STS_IOERR;
if (test_bit(EXTENT_BUFFER_CANCELLED, &eb->bflags)) {
- WARN_ON_ONCE(found_start != 0);
+ memzero_extent_buffer(eb, 0, eb->len);
return BLK_STS_OK;
}
@@ -3748,6 +3748,11 @@ void btrfs_clear_buffer_dirty(struct btrfs_trans_handle *trans,
if (trans && btrfs_header_generation(eb) != trans->transid)
return;
+ if (btrfs_is_zoned(fs_info)) {
+ set_bit(EXTENT_BUFFER_CANCELLED, &eb->bflags);
+ return;
+ }
+
if (!test_and_clear_bit(EXTENT_BUFFER_DIRTY, &eb->bflags))
return;
@@ -4139,8 +4144,6 @@ static void __write_extent_buffer(const struct extent_buffer *eb,
/* For unmapped (dummy) ebs, no need to check their uptodate status. */
const bool check_uptodate = !test_bit(EXTENT_BUFFER_UNMAPPED, &eb->bflags);
- WARN_ON(test_bit(EXTENT_BUFFER_CANCELLED, &eb->bflags));
-
if (check_eb_range(eb, start, len))
return;
@@ -1722,7 +1722,8 @@ void btrfs_redirty_list_add(struct btrfs_transaction *trans,
btrfs_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN))
return;
- ASSERT(!test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags));
+ ASSERT(test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags));
+ ASSERT(test_bit(EXTENT_BUFFER_CANCELLED, &eb->bflags));
memzero_extent_buffer(eb, 0, eb->len);
set_bit(EXTENT_BUFFER_CANCELLED, &eb->bflags);