mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	btrfs: extend balance filter usage to take minimum and maximum
Similar to the 'limit' filter, we can enhance the 'usage' filter to accept a range. The change is backward compatible, the range is applied only in connection with the BTRFS_BALANCE_ARGS_USAGE_RANGE flag. We don't have a usecase yet, the current syntax has been sufficient. The enhancement should provide parity with other range-like filters. Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
		
							parent
							
								
									dee32d0ac3
								
							
						
					
					
						commit
						bc3094673f
					
				
					 4 changed files with 60 additions and 4 deletions
				
			
		| 
						 | 
					@ -823,8 +823,18 @@ struct btrfs_disk_balance_args {
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	__le64 profiles;
 | 
						__le64 profiles;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* usage filter */
 | 
						/*
 | 
				
			||||||
 | 
						 * usage filter
 | 
				
			||||||
 | 
						 * BTRFS_BALANCE_ARGS_USAGE with a single value means '0..N'
 | 
				
			||||||
 | 
						 * BTRFS_BALANCE_ARGS_USAGE_RANGE - range syntax, min..max
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
		__le64 usage;
 | 
							__le64 usage;
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								__le32 usage_min;
 | 
				
			||||||
 | 
								__le32 usage_max;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* devid filter */
 | 
						/* devid filter */
 | 
				
			||||||
	__le64 devid;
 | 
						__le64 devid;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3059,16 +3059,19 @@ static void update_balance_args(struct btrfs_balance_control *bctl)
 | 
				
			||||||
	 * (albeit full) chunks.
 | 
						 * (albeit full) chunks.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (!(bctl->data.flags & BTRFS_BALANCE_ARGS_USAGE) &&
 | 
						if (!(bctl->data.flags & BTRFS_BALANCE_ARGS_USAGE) &&
 | 
				
			||||||
 | 
						    !(bctl->data.flags & BTRFS_BALANCE_ARGS_USAGE_RANGE) &&
 | 
				
			||||||
	    !(bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT)) {
 | 
						    !(bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT)) {
 | 
				
			||||||
		bctl->data.flags |= BTRFS_BALANCE_ARGS_USAGE;
 | 
							bctl->data.flags |= BTRFS_BALANCE_ARGS_USAGE;
 | 
				
			||||||
		bctl->data.usage = 90;
 | 
							bctl->data.usage = 90;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!(bctl->sys.flags & BTRFS_BALANCE_ARGS_USAGE) &&
 | 
						if (!(bctl->sys.flags & BTRFS_BALANCE_ARGS_USAGE) &&
 | 
				
			||||||
 | 
						    !(bctl->sys.flags & BTRFS_BALANCE_ARGS_USAGE_RANGE) &&
 | 
				
			||||||
	    !(bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT)) {
 | 
						    !(bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT)) {
 | 
				
			||||||
		bctl->sys.flags |= BTRFS_BALANCE_ARGS_USAGE;
 | 
							bctl->sys.flags |= BTRFS_BALANCE_ARGS_USAGE;
 | 
				
			||||||
		bctl->sys.usage = 90;
 | 
							bctl->sys.usage = 90;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!(bctl->meta.flags & BTRFS_BALANCE_ARGS_USAGE) &&
 | 
						if (!(bctl->meta.flags & BTRFS_BALANCE_ARGS_USAGE) &&
 | 
				
			||||||
 | 
						    !(bctl->meta.flags & BTRFS_BALANCE_ARGS_USAGE_RANGE) &&
 | 
				
			||||||
	    !(bctl->meta.flags & BTRFS_BALANCE_ARGS_CONVERT)) {
 | 
						    !(bctl->meta.flags & BTRFS_BALANCE_ARGS_CONVERT)) {
 | 
				
			||||||
		bctl->meta.flags |= BTRFS_BALANCE_ARGS_USAGE;
 | 
							bctl->meta.flags |= BTRFS_BALANCE_ARGS_USAGE;
 | 
				
			||||||
		bctl->meta.usage = 90;
 | 
							bctl->meta.usage = 90;
 | 
				
			||||||
| 
						 | 
					@ -3122,6 +3125,39 @@ static int chunk_profiles_filter(u64 chunk_type,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int chunk_usage_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset,
 | 
					static int chunk_usage_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset,
 | 
				
			||||||
			      struct btrfs_balance_args *bargs)
 | 
								      struct btrfs_balance_args *bargs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct btrfs_block_group_cache *cache;
 | 
				
			||||||
 | 
						u64 chunk_used;
 | 
				
			||||||
 | 
						u64 user_thresh_min;
 | 
				
			||||||
 | 
						u64 user_thresh_max;
 | 
				
			||||||
 | 
						int ret = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cache = btrfs_lookup_block_group(fs_info, chunk_offset);
 | 
				
			||||||
 | 
						chunk_used = btrfs_block_group_used(&cache->item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (bargs->usage_min == 0)
 | 
				
			||||||
 | 
							user_thresh_min = 0;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							user_thresh_min = div_factor_fine(cache->key.offset,
 | 
				
			||||||
 | 
										bargs->usage_min);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (bargs->usage_max == 0)
 | 
				
			||||||
 | 
							user_thresh_max = 1;
 | 
				
			||||||
 | 
						else if (bargs->usage_max > 100)
 | 
				
			||||||
 | 
							user_thresh_max = cache->key.offset;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							user_thresh_max = div_factor_fine(cache->key.offset,
 | 
				
			||||||
 | 
										bargs->usage_max);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (user_thresh_min <= chunk_used && chunk_used < user_thresh_max)
 | 
				
			||||||
 | 
							ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						btrfs_put_block_group(cache);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int chunk_usage_range_filter(struct btrfs_fs_info *fs_info,
 | 
				
			||||||
 | 
							u64 chunk_offset, struct btrfs_balance_args *bargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct btrfs_block_group_cache *cache;
 | 
						struct btrfs_block_group_cache *cache;
 | 
				
			||||||
	u64 chunk_used, user_thresh;
 | 
						u64 chunk_used, user_thresh;
 | 
				
			||||||
| 
						 | 
					@ -3130,7 +3166,7 @@ static int chunk_usage_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset,
 | 
				
			||||||
	cache = btrfs_lookup_block_group(fs_info, chunk_offset);
 | 
						cache = btrfs_lookup_block_group(fs_info, chunk_offset);
 | 
				
			||||||
	chunk_used = btrfs_block_group_used(&cache->item);
 | 
						chunk_used = btrfs_block_group_used(&cache->item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (bargs->usage == 0)
 | 
						if (bargs->usage_min == 0)
 | 
				
			||||||
		user_thresh = 1;
 | 
							user_thresh = 1;
 | 
				
			||||||
	else if (bargs->usage > 100)
 | 
						else if (bargs->usage > 100)
 | 
				
			||||||
		user_thresh = cache->key.offset;
 | 
							user_thresh = cache->key.offset;
 | 
				
			||||||
| 
						 | 
					@ -3279,6 +3315,9 @@ static int should_balance_chunk(struct btrfs_root *root,
 | 
				
			||||||
	if ((bargs->flags & BTRFS_BALANCE_ARGS_USAGE) &&
 | 
						if ((bargs->flags & BTRFS_BALANCE_ARGS_USAGE) &&
 | 
				
			||||||
	    chunk_usage_filter(bctl->fs_info, chunk_offset, bargs)) {
 | 
						    chunk_usage_filter(bctl->fs_info, chunk_offset, bargs)) {
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
						} else if ((bargs->flags & BTRFS_BALANCE_ARGS_USAGE_RANGE) &&
 | 
				
			||||||
 | 
						    chunk_usage_range_filter(bctl->fs_info, chunk_offset, bargs)) {
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* devid filter */
 | 
						/* devid filter */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -382,6 +382,7 @@ struct map_lookup {
 | 
				
			||||||
#define BTRFS_BALANCE_ARGS_LIMIT	(1ULL << 5)
 | 
					#define BTRFS_BALANCE_ARGS_LIMIT	(1ULL << 5)
 | 
				
			||||||
#define BTRFS_BALANCE_ARGS_LIMIT_RANGE	(1ULL << 6)
 | 
					#define BTRFS_BALANCE_ARGS_LIMIT_RANGE	(1ULL << 6)
 | 
				
			||||||
#define BTRFS_BALANCE_ARGS_STRIPES_RANGE (1ULL << 7)
 | 
					#define BTRFS_BALANCE_ARGS_STRIPES_RANGE (1ULL << 7)
 | 
				
			||||||
 | 
					#define BTRFS_BALANCE_ARGS_USAGE_RANGE	(1ULL << 8)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BTRFS_BALANCE_ARGS_MASK			\
 | 
					#define BTRFS_BALANCE_ARGS_MASK			\
 | 
				
			||||||
	(BTRFS_BALANCE_ARGS_PROFILES |		\
 | 
						(BTRFS_BALANCE_ARGS_PROFILES |		\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -206,7 +206,13 @@ struct btrfs_ioctl_feature_flags {
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct btrfs_balance_args {
 | 
					struct btrfs_balance_args {
 | 
				
			||||||
	__u64 profiles;
 | 
						__u64 profiles;
 | 
				
			||||||
	__u64 usage;
 | 
						union {
 | 
				
			||||||
 | 
							__le64 usage;
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								__le32 usage_min;
 | 
				
			||||||
 | 
								__le32 usage_max;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
	__u64 devid;
 | 
						__u64 devid;
 | 
				
			||||||
	__u64 pstart;
 | 
						__u64 pstart;
 | 
				
			||||||
	__u64 pend;
 | 
						__u64 pend;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue