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

Commit dee32d0a authored by Gabríel Arthúr Pétursson's avatar Gabríel Arthúr Pétursson Committed by Chris Mason
Browse files

btrfs: add balance filter for stripes



Balance block groups which have the given number of stripes, defined by
a range min..max. This is useful to selectively rebalance only chunks
that do not span enough devices, applies to RAID0/10/5/6.

Signed-off-by: default avatarGabríel Arthúr Pétursson <gabriel@system.is>
[ renamed bargs members, added to the UAPI, wrote the changelog ]
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>

Signed-off-by: default avatarChris Mason <clm@fb.com>
parent 12907fc7
Loading
Loading
Loading
Loading
+8 −1
Original line number Original line Diff line number Diff line
@@ -859,7 +859,14 @@ struct btrfs_disk_balance_args {
		};
		};
	};
	};


	__le64 unused[7];
	/*
	 * Process chunks that cross stripes_min..stripes_max devices,
	 * BTRFS_BALANCE_ARGS_STRIPES_RANGE
	 */
	__le32 stripes_min;
	__le32 stripes_max;

	__le64 unused[6];
} __attribute__ ((__packed__));
} __attribute__ ((__packed__));


/*
/*
+19 −0
Original line number Original line Diff line number Diff line
@@ -3220,6 +3220,19 @@ static int chunk_vrange_filter(struct extent_buffer *leaf,
	return 1;
	return 1;
}
}


static int chunk_stripes_range_filter(struct extent_buffer *leaf,
			       struct btrfs_chunk *chunk,
			       struct btrfs_balance_args *bargs)
{
	int num_stripes = btrfs_chunk_num_stripes(leaf, chunk);

	if (bargs->stripes_min <= num_stripes
			&& num_stripes <= bargs->stripes_max)
		return 0;

	return 1;
}

static int chunk_soft_convert_filter(u64 chunk_type,
static int chunk_soft_convert_filter(u64 chunk_type,
				     struct btrfs_balance_args *bargs)
				     struct btrfs_balance_args *bargs)
{
{
@@ -3286,6 +3299,12 @@ static int should_balance_chunk(struct btrfs_root *root,
		return 0;
		return 0;
	}
	}


	/* stripes filter */
	if ((bargs->flags & BTRFS_BALANCE_ARGS_STRIPES_RANGE) &&
	    chunk_stripes_range_filter(leaf, chunk, bargs)) {
		return 0;
	}

	/* soft profile changing mode */
	/* soft profile changing mode */
	if ((bargs->flags & BTRFS_BALANCE_ARGS_SOFT) &&
	if ((bargs->flags & BTRFS_BALANCE_ARGS_SOFT) &&
	    chunk_soft_convert_filter(chunk_type, bargs)) {
	    chunk_soft_convert_filter(chunk_type, bargs)) {
+1 −0
Original line number Original line Diff line number Diff line
@@ -381,6 +381,7 @@ struct map_lookup {
#define BTRFS_BALANCE_ARGS_VRANGE	(1ULL << 4)
#define BTRFS_BALANCE_ARGS_VRANGE	(1ULL << 4)
#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_MASK			\
#define BTRFS_BALANCE_ARGS_MASK			\
	(BTRFS_BALANCE_ARGS_PROFILES |		\
	(BTRFS_BALANCE_ARGS_PROFILES |		\
+9 −1
Original line number Original line Diff line number Diff line
@@ -229,7 +229,15 @@ struct btrfs_balance_args {
			__u32 limit_max;
			__u32 limit_max;
		};
		};
	};
	};
	__u64 unused[7];

	/*
	 * Process chunks that cross stripes_min..stripes_max devices,
	 * BTRFS_BALANCE_ARGS_STRIPES_RANGE
	 */
	__le32 stripes_min;
	__le32 stripes_max;

	__u64 unused[6];
} __attribute__ ((__packed__));
} __attribute__ ((__packed__));


/* report balance progress to userspace */
/* report balance progress to userspace */