mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	btrfs: zoned: factor out per-zone logic from btrfs_load_block_group_zone_info
Split out a helper for the body of the per-zone loop in btrfs_load_block_group_zone_info to make the function easier to read and modify. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
		
							parent
							
								
									15c12fcc50
								
							
						
					
					
						commit
						09a46725cc
					
				
					 1 changed files with 92 additions and 92 deletions
				
			
		
							
								
								
									
										184
									
								
								fs/btrfs/zoned.c
									
									
									
									
									
								
							
							
						
						
									
										184
									
								
								fs/btrfs/zoned.c
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1288,19 +1288,103 @@ struct zone_info {
 | 
			
		|||
	u64 alloc_offset;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int btrfs_load_zone_info(struct btrfs_fs_info *fs_info, int zone_idx,
 | 
			
		||||
				struct zone_info *info, unsigned long *active,
 | 
			
		||||
				struct map_lookup *map)
 | 
			
		||||
{
 | 
			
		||||
	struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
 | 
			
		||||
	struct btrfs_device *device = map->stripes[zone_idx].dev;
 | 
			
		||||
	int dev_replace_is_ongoing = 0;
 | 
			
		||||
	unsigned int nofs_flag;
 | 
			
		||||
	struct blk_zone zone;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	info->physical = map->stripes[zone_idx].physical;
 | 
			
		||||
 | 
			
		||||
	if (!device->bdev) {
 | 
			
		||||
		info->alloc_offset = WP_MISSING_DEV;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Consider a zone as active if we can allow any number of active zones. */
 | 
			
		||||
	if (!device->zone_info->max_active_zones)
 | 
			
		||||
		__set_bit(zone_idx, active);
 | 
			
		||||
 | 
			
		||||
	if (!btrfs_dev_is_sequential(device, info->physical)) {
 | 
			
		||||
		info->alloc_offset = WP_CONVENTIONAL;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* This zone will be used for allocation, so mark this zone non-empty. */
 | 
			
		||||
	btrfs_dev_clear_zone_empty(device, info->physical);
 | 
			
		||||
 | 
			
		||||
	down_read(&dev_replace->rwsem);
 | 
			
		||||
	dev_replace_is_ongoing = btrfs_dev_replace_is_ongoing(dev_replace);
 | 
			
		||||
	if (dev_replace_is_ongoing && dev_replace->tgtdev != NULL)
 | 
			
		||||
		btrfs_dev_clear_zone_empty(dev_replace->tgtdev, info->physical);
 | 
			
		||||
	up_read(&dev_replace->rwsem);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * The group is mapped to a sequential zone. Get the zone write pointer
 | 
			
		||||
	 * to determine the allocation offset within the zone.
 | 
			
		||||
	 */
 | 
			
		||||
	WARN_ON(!IS_ALIGNED(info->physical, fs_info->zone_size));
 | 
			
		||||
	nofs_flag = memalloc_nofs_save();
 | 
			
		||||
	ret = btrfs_get_dev_zone(device, info->physical, &zone);
 | 
			
		||||
	memalloc_nofs_restore(nofs_flag);
 | 
			
		||||
	if (ret) {
 | 
			
		||||
		if (ret != -EIO && ret != -EOPNOTSUPP)
 | 
			
		||||
			return ret;
 | 
			
		||||
		info->alloc_offset = WP_MISSING_DEV;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (zone.type == BLK_ZONE_TYPE_CONVENTIONAL) {
 | 
			
		||||
		btrfs_err_in_rcu(fs_info,
 | 
			
		||||
		"zoned: unexpected conventional zone %llu on device %s (devid %llu)",
 | 
			
		||||
			zone.start << SECTOR_SHIFT, rcu_str_deref(device->name),
 | 
			
		||||
			device->devid);
 | 
			
		||||
		return -EIO;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	info->capacity = (zone.capacity << SECTOR_SHIFT);
 | 
			
		||||
 | 
			
		||||
	switch (zone.cond) {
 | 
			
		||||
	case BLK_ZONE_COND_OFFLINE:
 | 
			
		||||
	case BLK_ZONE_COND_READONLY:
 | 
			
		||||
		btrfs_err(fs_info,
 | 
			
		||||
		"zoned: offline/readonly zone %llu on device %s (devid %llu)",
 | 
			
		||||
			  (info->physical >> device->zone_info->zone_size_shift),
 | 
			
		||||
			  rcu_str_deref(device->name), device->devid);
 | 
			
		||||
		info->alloc_offset = WP_MISSING_DEV;
 | 
			
		||||
		break;
 | 
			
		||||
	case BLK_ZONE_COND_EMPTY:
 | 
			
		||||
		info->alloc_offset = 0;
 | 
			
		||||
		break;
 | 
			
		||||
	case BLK_ZONE_COND_FULL:
 | 
			
		||||
		info->alloc_offset = info->capacity;
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		/* Partially used zone. */
 | 
			
		||||
		info->alloc_offset = ((zone.wp - zone.start) << SECTOR_SHIFT);
 | 
			
		||||
		__set_bit(zone_idx, active);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
 | 
			
		||||
{
 | 
			
		||||
	struct btrfs_fs_info *fs_info = cache->fs_info;
 | 
			
		||||
	struct extent_map_tree *em_tree = &fs_info->mapping_tree;
 | 
			
		||||
	struct extent_map *em;
 | 
			
		||||
	struct map_lookup *map;
 | 
			
		||||
	struct btrfs_device *device;
 | 
			
		||||
	u64 logical = cache->start;
 | 
			
		||||
	u64 length = cache->length;
 | 
			
		||||
	struct zone_info *zone_info = NULL;
 | 
			
		||||
	int ret;
 | 
			
		||||
	int i;
 | 
			
		||||
	unsigned int nofs_flag;
 | 
			
		||||
	unsigned long *active = NULL;
 | 
			
		||||
	u64 last_alloc = 0;
 | 
			
		||||
	u32 num_sequential = 0, num_conventional = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1345,98 +1429,14 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < map->num_stripes; i++) {
 | 
			
		||||
		struct zone_info *info = &zone_info[i];
 | 
			
		||||
		bool is_sequential;
 | 
			
		||||
		struct blk_zone zone;
 | 
			
		||||
		struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
 | 
			
		||||
		int dev_replace_is_ongoing = 0;
 | 
			
		||||
		ret = btrfs_load_zone_info(fs_info, i, &zone_info[i], active, map);
 | 
			
		||||
		if (ret)
 | 
			
		||||
			goto out;
 | 
			
		||||
 | 
			
		||||
		device = map->stripes[i].dev;
 | 
			
		||||
		info->physical = map->stripes[i].physical;
 | 
			
		||||
 | 
			
		||||
		if (device->bdev == NULL) {
 | 
			
		||||
			info->alloc_offset = WP_MISSING_DEV;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		is_sequential = btrfs_dev_is_sequential(device, info->physical);
 | 
			
		||||
		if (is_sequential)
 | 
			
		||||
			num_sequential++;
 | 
			
		||||
		else
 | 
			
		||||
		if (zone_info[i].alloc_offset == WP_CONVENTIONAL)
 | 
			
		||||
			num_conventional++;
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Consider a zone as active if we can allow any number of
 | 
			
		||||
		 * active zones.
 | 
			
		||||
		 */
 | 
			
		||||
		if (!device->zone_info->max_active_zones)
 | 
			
		||||
			__set_bit(i, active);
 | 
			
		||||
 | 
			
		||||
		if (!is_sequential) {
 | 
			
		||||
			info->alloc_offset = WP_CONVENTIONAL;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * This zone will be used for allocation, so mark this zone
 | 
			
		||||
		 * non-empty.
 | 
			
		||||
		 */
 | 
			
		||||
		btrfs_dev_clear_zone_empty(device, info->physical);
 | 
			
		||||
 | 
			
		||||
		down_read(&dev_replace->rwsem);
 | 
			
		||||
		dev_replace_is_ongoing = btrfs_dev_replace_is_ongoing(dev_replace);
 | 
			
		||||
		if (dev_replace_is_ongoing && dev_replace->tgtdev != NULL)
 | 
			
		||||
			btrfs_dev_clear_zone_empty(dev_replace->tgtdev, info->physical);
 | 
			
		||||
		up_read(&dev_replace->rwsem);
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * The group is mapped to a sequential zone. Get the zone write
 | 
			
		||||
		 * pointer to determine the allocation offset within the zone.
 | 
			
		||||
		 */
 | 
			
		||||
		WARN_ON(!IS_ALIGNED(info->physical, fs_info->zone_size));
 | 
			
		||||
		nofs_flag = memalloc_nofs_save();
 | 
			
		||||
		ret = btrfs_get_dev_zone(device, info->physical, &zone);
 | 
			
		||||
		memalloc_nofs_restore(nofs_flag);
 | 
			
		||||
		if (ret == -EIO || ret == -EOPNOTSUPP) {
 | 
			
		||||
			ret = 0;
 | 
			
		||||
			info->alloc_offset = WP_MISSING_DEV;
 | 
			
		||||
			continue;
 | 
			
		||||
		} else if (ret) {
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (zone.type == BLK_ZONE_TYPE_CONVENTIONAL) {
 | 
			
		||||
			btrfs_err_in_rcu(fs_info,
 | 
			
		||||
	"zoned: unexpected conventional zone %llu on device %s (devid %llu)",
 | 
			
		||||
				zone.start << SECTOR_SHIFT,
 | 
			
		||||
				rcu_str_deref(device->name), device->devid);
 | 
			
		||||
			ret = -EIO;
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		info->capacity = (zone.capacity << SECTOR_SHIFT);
 | 
			
		||||
 | 
			
		||||
		switch (zone.cond) {
 | 
			
		||||
		case BLK_ZONE_COND_OFFLINE:
 | 
			
		||||
		case BLK_ZONE_COND_READONLY:
 | 
			
		||||
			btrfs_err(fs_info,
 | 
			
		||||
		"zoned: offline/readonly zone %llu on device %s (devid %llu)",
 | 
			
		||||
				  info->physical >> device->zone_info->zone_size_shift,
 | 
			
		||||
				  rcu_str_deref(device->name), device->devid);
 | 
			
		||||
			info->alloc_offset = WP_MISSING_DEV;
 | 
			
		||||
			break;
 | 
			
		||||
		case BLK_ZONE_COND_EMPTY:
 | 
			
		||||
			info->alloc_offset = 0;
 | 
			
		||||
			break;
 | 
			
		||||
		case BLK_ZONE_COND_FULL:
 | 
			
		||||
			info->alloc_offset = info->capacity;
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			/* Partially used zone */
 | 
			
		||||
			info->alloc_offset = ((zone.wp - zone.start) << SECTOR_SHIFT);
 | 
			
		||||
			__set_bit(i, active);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			num_sequential++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (num_sequential > 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue