Commit afba2bc0 authored by Naohiro Aota's avatar Naohiro Aota Committed by David Sterba
Browse files

btrfs: zoned: implement active zone tracking



Add zone_is_active flag to btrfs_block_group. This flag indicates the
underlying zones are all active. Such zone active block groups are tracked
by fs_info->active_bg_list.

btrfs_dev_{set,clear}_active_zone() take responsibility for the underlying
device part. They set/clear the bitmap to indicate zone activeness and
count the number of zones we can activate left.

btrfs_zone_{activate,finish}() take responsibility for the logical part and
the list management. In addition, btrfs_zone_finish() wait for any writes
on it and send REQ_OP_ZONE_FINISH to the zone.

Signed-off-by: default avatarNaohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent dafc340d
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -1896,6 +1896,7 @@ static struct btrfs_block_group *btrfs_create_block_group_cache(
	INIT_LIST_HEAD(&cache->discard_list);
	INIT_LIST_HEAD(&cache->discard_list);
	INIT_LIST_HEAD(&cache->dirty_list);
	INIT_LIST_HEAD(&cache->dirty_list);
	INIT_LIST_HEAD(&cache->io_list);
	INIT_LIST_HEAD(&cache->io_list);
	INIT_LIST_HEAD(&cache->active_bg_list);
	btrfs_init_free_space_ctl(cache, cache->free_space_ctl);
	btrfs_init_free_space_ctl(cache, cache->free_space_ctl);
	atomic_set(&cache->frozen, 0);
	atomic_set(&cache->frozen, 0);
	mutex_init(&cache->free_space_lock);
	mutex_init(&cache->free_space_lock);
@@ -3842,6 +3843,16 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
	}
	}
	spin_unlock(&info->unused_bgs_lock);
	spin_unlock(&info->unused_bgs_lock);


	spin_lock(&info->zone_active_bgs_lock);
	while (!list_empty(&info->zone_active_bgs)) {
		block_group = list_first_entry(&info->zone_active_bgs,
					       struct btrfs_block_group,
					       active_bg_list);
		list_del_init(&block_group->active_bg_list);
		btrfs_put_block_group(block_group);
	}
	spin_unlock(&info->zone_active_bgs_lock);

	spin_lock(&info->block_group_cache_lock);
	spin_lock(&info->block_group_cache_lock);
	while ((n = rb_last(&info->block_group_cache_tree)) != NULL) {
	while ((n = rb_last(&info->block_group_cache_tree)) != NULL) {
		block_group = rb_entry(n, struct btrfs_block_group,
		block_group = rb_entry(n, struct btrfs_block_group,
+2 −0
Original line number Original line Diff line number Diff line
@@ -98,6 +98,7 @@ struct btrfs_block_group {
	unsigned int to_copy:1;
	unsigned int to_copy:1;
	unsigned int relocating_repair:1;
	unsigned int relocating_repair:1;
	unsigned int chunk_item_inserted:1;
	unsigned int chunk_item_inserted:1;
	unsigned int zone_is_active:1;


	int disk_cache_state;
	int disk_cache_state;


@@ -205,6 +206,7 @@ struct btrfs_block_group {
	u64 zone_capacity;
	u64 zone_capacity;
	u64 meta_write_pointer;
	u64 meta_write_pointer;
	struct map_lookup *physical_map;
	struct map_lookup *physical_map;
	struct list_head active_bg_list;
};
};


static inline u64 btrfs_block_group_end(struct btrfs_block_group *block_group)
static inline u64 btrfs_block_group_end(struct btrfs_block_group *block_group)
+3 −0
Original line number Original line Diff line number Diff line
@@ -1018,6 +1018,9 @@ struct btrfs_fs_info {
	spinlock_t treelog_bg_lock;
	spinlock_t treelog_bg_lock;
	u64 treelog_bg;
	u64 treelog_bg;


	spinlock_t zone_active_bgs_lock;
	struct list_head zone_active_bgs;

#ifdef CONFIG_BTRFS_FS_REF_VERIFY
#ifdef CONFIG_BTRFS_FS_REF_VERIFY
	spinlock_t ref_verify_lock;
	spinlock_t ref_verify_lock;
	struct rb_root block_tree;
	struct rb_root block_tree;
+2 −0
Original line number Original line Diff line number Diff line
@@ -2884,6 +2884,7 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
	spin_lock_init(&fs_info->buffer_lock);
	spin_lock_init(&fs_info->buffer_lock);
	spin_lock_init(&fs_info->unused_bgs_lock);
	spin_lock_init(&fs_info->unused_bgs_lock);
	spin_lock_init(&fs_info->treelog_bg_lock);
	spin_lock_init(&fs_info->treelog_bg_lock);
	spin_lock_init(&fs_info->zone_active_bgs_lock);
	rwlock_init(&fs_info->tree_mod_log_lock);
	rwlock_init(&fs_info->tree_mod_log_lock);
	mutex_init(&fs_info->unused_bg_unpin_mutex);
	mutex_init(&fs_info->unused_bg_unpin_mutex);
	mutex_init(&fs_info->reclaim_bgs_lock);
	mutex_init(&fs_info->reclaim_bgs_lock);
@@ -2897,6 +2898,7 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
	INIT_LIST_HEAD(&fs_info->tree_mod_seq_list);
	INIT_LIST_HEAD(&fs_info->tree_mod_seq_list);
	INIT_LIST_HEAD(&fs_info->unused_bgs);
	INIT_LIST_HEAD(&fs_info->unused_bgs);
	INIT_LIST_HEAD(&fs_info->reclaim_bgs);
	INIT_LIST_HEAD(&fs_info->reclaim_bgs);
	INIT_LIST_HEAD(&fs_info->zone_active_bgs);
#ifdef CONFIG_BTRFS_DEBUG
#ifdef CONFIG_BTRFS_DEBUG
	INIT_LIST_HEAD(&fs_info->allocated_roots);
	INIT_LIST_HEAD(&fs_info->allocated_roots);
	INIT_LIST_HEAD(&fs_info->allocated_ebs);
	INIT_LIST_HEAD(&fs_info->allocated_ebs);
+3 −2
Original line number Original line Diff line number Diff line
@@ -2763,8 +2763,9 @@ void btrfs_dump_free_space(struct btrfs_block_group *block_group,
	 * out the free space after the allocation offset.
	 * out the free space after the allocation offset.
	 */
	 */
	if (btrfs_is_zoned(fs_info)) {
	if (btrfs_is_zoned(fs_info)) {
		btrfs_info(fs_info, "free space %llu",
		btrfs_info(fs_info, "free space %llu active %d",
			   block_group->zone_capacity - block_group->alloc_offset);
			   block_group->zone_capacity - block_group->alloc_offset,
			   block_group->zone_is_active);
		return;
		return;
	}
	}


Loading