mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	btrfs: zoned: make zone activation multi stripe capable
Currently activation of a zone only works if the block group isn't spanning more than one zone. This limitation is purely artificial and can be easily expanded to block groups being places across multiple zones. This is a preparation for allowing DUP and later more complex block-group profiles on zoned btrfs. Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
		
							parent
							
								
									f7238e5094
								
							
						
					
					
						commit
						f9a912a3c4
					
				
					 1 changed files with 33 additions and 28 deletions
				
			
		| 
						 | 
					@ -1781,50 +1781,55 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group)
 | 
				
			||||||
	struct btrfs_device *device;
 | 
						struct btrfs_device *device;
 | 
				
			||||||
	u64 physical;
 | 
						u64 physical;
 | 
				
			||||||
	bool ret;
 | 
						bool ret;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!btrfs_is_zoned(block_group->fs_info))
 | 
						if (!btrfs_is_zoned(block_group->fs_info))
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	map = block_group->physical_map;
 | 
						map = block_group->physical_map;
 | 
				
			||||||
	/* Currently support SINGLE profile only */
 | 
					 | 
				
			||||||
	ASSERT(map->num_stripes == 1);
 | 
					 | 
				
			||||||
	device = map->stripes[0].dev;
 | 
					 | 
				
			||||||
	physical = map->stripes[0].physical;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (device->zone_info->max_active_zones == 0)
 | 
					 | 
				
			||||||
		return true;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock(&block_group->lock);
 | 
						spin_lock(&block_group->lock);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (block_group->zone_is_active) {
 | 
						if (block_group->zone_is_active) {
 | 
				
			||||||
		ret = true;
 | 
							ret = true;
 | 
				
			||||||
		goto out_unlock;
 | 
							goto out_unlock;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* No space left */
 | 
						for (i = 0; i < map->num_stripes; i++) {
 | 
				
			||||||
	if (block_group->alloc_offset == block_group->zone_capacity) {
 | 
							device = map->stripes[i].dev;
 | 
				
			||||||
		ret = false;
 | 
							physical = map->stripes[i].physical;
 | 
				
			||||||
		goto out_unlock;
 | 
					
 | 
				
			||||||
 | 
							if (device->zone_info->max_active_zones == 0)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* No space left */
 | 
				
			||||||
 | 
							if (block_group->alloc_offset == block_group->zone_capacity) {
 | 
				
			||||||
 | 
								ret = false;
 | 
				
			||||||
 | 
								goto out_unlock;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!btrfs_dev_set_active_zone(device, physical)) {
 | 
				
			||||||
 | 
								/* Cannot activate the zone */
 | 
				
			||||||
 | 
								ret = false;
 | 
				
			||||||
 | 
								goto out_unlock;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Successfully activated all the zones */
 | 
				
			||||||
 | 
							if (i == map->num_stripes - 1)
 | 
				
			||||||
 | 
								block_group->zone_is_active = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!btrfs_dev_set_active_zone(device, physical)) {
 | 
					 | 
				
			||||||
		/* Cannot activate the zone */
 | 
					 | 
				
			||||||
		ret = false;
 | 
					 | 
				
			||||||
		goto out_unlock;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Successfully activated all the zones */
 | 
					 | 
				
			||||||
	block_group->zone_is_active = 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	spin_unlock(&block_group->lock);
 | 
						spin_unlock(&block_group->lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* For the active block group list */
 | 
						if (block_group->zone_is_active) {
 | 
				
			||||||
	btrfs_get_block_group(block_group);
 | 
							/* For the active block group list */
 | 
				
			||||||
 | 
							btrfs_get_block_group(block_group);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock(&fs_info->zone_active_bgs_lock);
 | 
							spin_lock(&fs_info->zone_active_bgs_lock);
 | 
				
			||||||
	ASSERT(list_empty(&block_group->active_bg_list));
 | 
							list_add_tail(&block_group->active_bg_list,
 | 
				
			||||||
	list_add_tail(&block_group->active_bg_list, &fs_info->zone_active_bgs);
 | 
								      &fs_info->zone_active_bgs);
 | 
				
			||||||
	spin_unlock(&fs_info->zone_active_bgs_lock);
 | 
							spin_unlock(&fs_info->zone_active_bgs_lock);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue