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 | } __attribute__ ((__packed__)); | 870 | } __attribute__ ((__packed__)); |
| 864 | 871 | ||
| 865 | /* | 872 | /* |
| @@ -3220,6 +3220,19 @@ static int chunk_vrange_filter(struct extent_buffer *leaf, · 3219 unmodified lines | |||
| 3220 | return 1; | 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 | static int chunk_soft_convert_filter(u64 chunk_type, | 3236 | static int chunk_soft_convert_filter(u64 chunk_type, |
| 3224 | struct btrfs_balance_args *bargs) | 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 | return 0; | 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 | /* soft profile changing mode */ | 3308 | /* soft profile changing mode */ |
| 3290 | if ((bargs->flags & BTRFS_BALANCE_ARGS_SOFT) && | 3309 | if ((bargs->flags & BTRFS_BALANCE_ARGS_SOFT) && |
| 3291 | chunk_soft_convert_filter(chunk_type, bargs)) { | 3310 | chunk_soft_convert_filter(chunk_type, bargs)) { |
| @@ -381,6 +381,7 @@ struct map_lookup { · 380 unmodified lines | |||
| 381 | #define BTRFS_BALANCE_ARGS_VRANGE (1ULL << 4) | 381 | #define BTRFS_BALANCE_ARGS_VRANGE (1ULL << 4) |
| 382 | #define BTRFS_BALANCE_ARGS_LIMIT (1ULL << 5) | 382 | #define BTRFS_BALANCE_ARGS_LIMIT (1ULL << 5) |
| 383 | #define BTRFS_BALANCE_ARGS_LIMIT_RANGE (1ULL << 6) | 383 | #define BTRFS_BALANCE_ARGS_LIMIT_RANGE (1ULL << 6) |
| 384 | #define BTRFS_BALANCE_ARGS_STRIPES_RANGE (1ULL << 7) | ||
| 384 | 385 | ||
| 385 | #define BTRFS_BALANCE_ARGS_MASK \ | 386 | #define BTRFS_BALANCE_ARGS_MASK \ |
| 386 | (BTRFS_BALANCE_ARGS_PROFILES | \ | 387 | (BTRFS_BALANCE_ARGS_PROFILES | \ |
| @@ -229,7 +229,15 @@ struct btrfs_balance_args { · 228 unmodified lines | |||
| 229 | __u32 limit_max; | 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 | } __attribute__ ((__packed__)); | 241 | } __attribute__ ((__packed__)); |
| 234 | 242 | ||
| 235 | /* report balance progress to userspace */ | 243 | /* report balance progress to userspace */ |