Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc309467 authored by David Sterba's avatar David Sterba Committed by Chris Mason
Browse files

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: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent dee32d0a
Loading
Loading
Loading
Loading
+12 −2
Original line number Original line Diff line number Diff line
@@ -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;
+40 −1
Original line number Original line Diff line number Diff line
@@ -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 */
+1 −0
Original line number Original line Diff line number Diff line
@@ -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 |		\
+7 −1
Original line number Original line Diff line number Diff line
@@ -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;