diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h index a68c8bd3..3cca6032 100644 --- a/kernel-shared/ctree.h +++ b/kernel-shared/ctree.h @@ -1140,6 +1140,7 @@ struct btrfs_block_group { * allocation. This is used only with ZONED mode enabled. */ u64 alloc_offset; + u64 write_offset; }; struct btrfs_device; diff --git a/kernel-shared/transaction.c b/kernel-shared/transaction.c index a2e53fb8..5b991651 100644 --- a/kernel-shared/transaction.c +++ b/kernel-shared/transaction.c @@ -18,6 +18,7 @@ #include "kernel-shared/disk-io.h" #include "kernel-shared/transaction.h" #include "kernel-shared/delayed-ref.h" +#include "kernel-shared/zoned.h" #include "common/messages.h" struct btrfs_trans_handle* btrfs_start_transaction(struct btrfs_root *root, @@ -138,10 +139,15 @@ int __commit_transaction(struct btrfs_trans_handle *trans, int ret; while(1) { +again: ret = find_first_extent_bit(tree, 0, &start, &end, EXTENT_DIRTY); if (ret) break; + + if (btrfs_redirty_extent_buffer_for_zoned(fs_info, start, end)) + goto again; + while(start <= end) { eb = find_first_extent_buffer(tree, start); BUG_ON(!eb || eb->start != start); diff --git a/kernel-shared/zoned.c b/kernel-shared/zoned.c index 28423118..1ec40960 100644 --- a/kernel-shared/zoned.c +++ b/kernel-shared/zoned.c @@ -847,10 +847,40 @@ out: ret = -EIO; } + if (!ret) + cache->write_offset = cache->alloc_offset; + free(alloc_offsets); return ret; } +bool btrfs_redirty_extent_buffer_for_zoned(struct btrfs_fs_info *fs_info, + u64 start, u64 end) +{ + u64 next; + struct btrfs_block_group *cache; + struct extent_buffer *eb; + + if (!btrfs_is_zoned(fs_info)) + return false; + + cache = btrfs_lookup_first_block_group(fs_info, start); + BUG_ON(!cache); + + if (cache->start + cache->write_offset < start) { + next = cache->start + cache->write_offset; + BUG_ON(next + fs_info->nodesize > start); + eb = btrfs_find_create_tree_block(fs_info, next); + btrfs_mark_buffer_dirty(eb); + free_extent_buffer(eb); + return true; + } + + cache->write_offset += (end + 1 - start); + + return false; +} + #endif int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info) diff --git a/kernel-shared/zoned.h b/kernel-shared/zoned.h index f9e30e16..bcbdeda2 100644 --- a/kernel-shared/zoned.h +++ b/kernel-shared/zoned.h @@ -90,6 +90,8 @@ u64 btrfs_find_allocatable_zones(struct btrfs_device *device, u64 hole_start, u64 hole_end, u64 num_bytes); int btrfs_load_block_group_zone_info(struct btrfs_fs_info *fs_info, struct btrfs_block_group *cache); +bool btrfs_redirty_extent_buffer_for_zoned(struct btrfs_fs_info *fs_info, + u64 start, u64 end); #else @@ -127,6 +129,12 @@ static inline int btrfs_load_block_group_zone_info( return 0; } +static inline bool btrfs_redirty_extent_buffer_for_zoned( + struct btrfs_fs_info *fs_info, u64 start, u64 end) +{ + return false; +} + #endif /* BTRFS_ZONED */ static inline bool btrfs_dev_is_sequential(struct btrfs_device *device, u64 pos)