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

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
...@@ -859,7 +859,14 @@ struct btrfs_disk_balance_args { ...@@ -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__));
/* /*
......
...@@ -3220,6 +3220,19 @@ static int chunk_vrange_filter(struct extent_buffer *leaf, ...@@ -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, ...@@ -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)) {
......
...@@ -381,6 +381,7 @@ struct map_lookup { ...@@ -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 | \
......
...@@ -229,7 +229,15 @@ struct btrfs_balance_args { ...@@ -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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment