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: Gabríel Arthúr Pétursson <gabriel@system.is> [ renamed bargs members, added to the UAPI, wrote the changelog ] Signed-off-by: David Sterba <dsterba@suse.com>
Unified · Split
| @@ -859,7 +859,14 @@ struct btrfs_disk_balance_args { · 858 unmodified lines | ||
| 859 | 859 | }; |
| 860 | 860 | }; |
| 861 | 861 | |
| 862 | − __le64 unused[7]; | |
| 862 | + /* | |
| 863 | + * Process chunks that cross stripes_min..stripes_max devices, | |
| 864 | + * BTRFS_BALANCE_ARGS_STRIPES_RANGE | |
| 865 | + */ | |
| 866 | + __le32 stripes_min; | |
| 867 | + __le32 stripes_max; | |
| 868 | + | |
| 869 | + __le64 unused[6]; | |
| 863 | 870 | } __attribute__ ((__packed__)); |
| 864 | 871 | |
| 865 | 872 | /* |
| @@ -3220,6 +3220,19 @@ static int chunk_vrange_filter(struct extent_buffer *leaf, · 3219 unmodified lines | ||
| 3220 | 3220 | return 1; |
| 3221 | 3221 | } |
| 3222 | 3222 | |
| 3223 | +static int chunk_stripes_range_filter(struct extent_buffer *leaf, | |
| 3224 | + struct btrfs_chunk *chunk, | |
| 3225 | + struct btrfs_balance_args *bargs) | |
| 3226 | +{ | |
| 3227 | + int num_stripes = btrfs_chunk_num_stripes(leaf, chunk); | |
| 3228 | + | |
| 3229 | + if (bargs->stripes_min <= num_stripes | |
| 3230 | + && num_stripes <= bargs->stripes_max) | |
| 3231 | + return 0; | |
| 3232 | + | |
| 3233 | + return 1; | |
| 3234 | +} | |
| 3235 | + | |
| 3223 | 3236 | static int chunk_soft_convert_filter(u64 chunk_type, |
| 3224 | 3237 | struct btrfs_balance_args *bargs) |
| 3225 | 3238 | { |
| @@ -3286,6 +3299,12 @@ static int should_balance_chunk(struct btrfs_root *root, · 60 unmodified lines | ||
| 3286 | 3299 | return 0; |
| 3287 | 3300 | } |
| 3288 | 3301 | |
| 3302 | + /* stripes filter */ | |
| 3303 | + if ((bargs->flags & BTRFS_BALANCE_ARGS_STRIPES_RANGE) && | |
| 3304 | + chunk_stripes_range_filter(leaf, chunk, bargs)) { | |
| 3305 | + return 0; | |
| 3306 | + } | |
| 3307 | + | |
| 3289 | 3308 | /* soft profile changing mode */ |
| 3290 | 3309 | if ((bargs->flags & BTRFS_BALANCE_ARGS_SOFT) && |
| 3291 | 3310 | chunk_soft_convert_filter(chunk_type, bargs)) { |
| @@ -381,6 +381,7 @@ struct map_lookup { · 380 unmodified lines | ||
| 381 | 381 | #define BTRFS_BALANCE_ARGS_VRANGE (1ULL << 4) |
| 382 | 382 | #define BTRFS_BALANCE_ARGS_LIMIT (1ULL << 5) |
| 383 | 383 | #define BTRFS_BALANCE_ARGS_LIMIT_RANGE (1ULL << 6) |
| 384 | +#define BTRFS_BALANCE_ARGS_STRIPES_RANGE (1ULL << 7) | |
| 384 | 385 | |
| 385 | 386 | #define BTRFS_BALANCE_ARGS_MASK \ |
| 386 | 387 | (BTRFS_BALANCE_ARGS_PROFILES | \ |
| @@ -229,7 +229,15 @@ struct btrfs_balance_args { · 228 unmodified lines | ||
| 229 | 229 | __u32 limit_max; |
| 230 | 230 | }; |
| 231 | 231 | }; |
| 232 | − __u64 unused[7]; | |
| 232 | + | |
| 233 | + /* | |
| 234 | + * Process chunks that cross stripes_min..stripes_max devices, | |
| 235 | + * BTRFS_BALANCE_ARGS_STRIPES_RANGE | |
| 236 | + */ | |
| 237 | + __le32 stripes_min; | |
| 238 | + __le32 stripes_max; | |
| 239 | + | |
| 240 | + __u64 unused[6]; | |
| 233 | 241 | } __attribute__ ((__packed__)); |
| 234 | 242 | |
| 235 | 243 | /* report balance progress to userspace */ |