diff options
| author | David Sterba <dsterba@suse.com> | 2015-10-20 12:22:13 -0400 |
|---|---|---|
| committer | Chris Mason <clm@fb.com> | 2015-10-26 22:38:30 -0400 |
| commit | bc3094673f22d00794a8606200788e411b4ec80d (patch) | |
| tree | a90e4834e26e4e69339a100d1489bcc3159e06d8 | |
| parent | dee32d0ac3719ef8d640efaf0884111df444730f (diff) | |
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: David Sterba <dsterba@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
| -rw-r--r-- | fs/btrfs/ctree.h | 14 | ||||
| -rw-r--r-- | fs/btrfs/volumes.c | 41 | ||||
| -rw-r--r-- | fs/btrfs/volumes.h | 1 | ||||
| -rw-r--r-- | include/uapi/linux/btrfs.h | 8 |
4 files changed, 60 insertions, 4 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 8ccbf4317a4a..4001585ec434 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -823,8 +823,18 @@ struct btrfs_disk_balance_args { | |||
| 823 | */ | 823 | */ |
| 824 | __le64 profiles; | 824 | __le64 profiles; |
| 825 | 825 | ||
| 826 | /* usage filter */ | 826 | /* |
| 827 | __le64 usage; | 827 | * usage filter |
| 828 | * BTRFS_BALANCE_ARGS_USAGE with a single value means '0..N' | ||
| 829 | * BTRFS_BALANCE_ARGS_USAGE_RANGE - range syntax, min..max | ||
| 830 | */ | ||
| 831 | union { | ||
| 832 | __le64 usage; | ||
| 833 | struct { | ||
| 834 | __le32 usage_min; | ||
| 835 | __le32 usage_max; | ||
| 836 | }; | ||
| 837 | }; | ||
| 828 | 838 | ||
| 829 | /* devid filter */ | 839 | /* devid filter */ |
| 830 | __le64 devid; | 840 | __le64 devid; |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 9f5d16739880..17ed76d18eb6 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -3059,16 +3059,19 @@ static void update_balance_args(struct btrfs_balance_control *bctl) | |||
| 3059 | * (albeit full) chunks. | 3059 | * (albeit full) chunks. |
| 3060 | */ | 3060 | */ |
| 3061 | if (!(bctl->data.flags & BTRFS_BALANCE_ARGS_USAGE) && | 3061 | if (!(bctl->data.flags & BTRFS_BALANCE_ARGS_USAGE) && |
| 3062 | !(bctl->data.flags & BTRFS_BALANCE_ARGS_USAGE_RANGE) && | ||
| 3062 | !(bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT)) { | 3063 | !(bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT)) { |
| 3063 | bctl->data.flags |= BTRFS_BALANCE_ARGS_USAGE; | 3064 | bctl->data.flags |= BTRFS_BALANCE_ARGS_USAGE; |
| 3064 | bctl->data.usage = 90; | 3065 | bctl->data.usage = 90; |
| 3065 | } | 3066 | } |
| 3066 | if (!(bctl->sys.flags & BTRFS_BALANCE_ARGS_USAGE) && | 3067 | if (!(bctl->sys.flags & BTRFS_BALANCE_ARGS_USAGE) && |
| 3068 | !(bctl->sys.flags & BTRFS_BALANCE_ARGS_USAGE_RANGE) && | ||
| 3067 | !(bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT)) { | 3069 | !(bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT)) { |
| 3068 | bctl->sys.flags |= BTRFS_BALANCE_ARGS_USAGE; | 3070 | bctl->sys.flags |= BTRFS_BALANCE_ARGS_USAGE; |
| 3069 | bctl->sys.usage = 90; | 3071 | bctl->sys.usage = 90; |
| 3070 | } | 3072 | } |
| 3071 | if (!(bctl->meta.flags & BTRFS_BALANCE_ARGS_USAGE) && | 3073 | if (!(bctl->meta.flags & BTRFS_BALANCE_ARGS_USAGE) && |
| 3074 | !(bctl->meta.flags & BTRFS_BALANCE_ARGS_USAGE_RANGE) && | ||
| 3072 | !(bctl->meta.flags & BTRFS_BALANCE_ARGS_CONVERT)) { | 3075 | !(bctl->meta.flags & BTRFS_BALANCE_ARGS_CONVERT)) { |
| 3073 | bctl->meta.flags |= BTRFS_BALANCE_ARGS_USAGE; | 3076 | bctl->meta.flags |= BTRFS_BALANCE_ARGS_USAGE; |
| 3074 | bctl->meta.usage = 90; | 3077 | bctl->meta.usage = 90; |
| @@ -3124,13 +3127,46 @@ static int chunk_usage_filter(struct btrfs_fs_info *fs_info, u64 chunk_offset, | |||
| 3124 | struct btrfs_balance_args *bargs) | 3127 | struct btrfs_balance_args *bargs) |
| 3125 | { | 3128 | { |
| 3126 | struct btrfs_block_group_cache *cache; | 3129 | struct btrfs_block_group_cache *cache; |
| 3130 | u64 chunk_used; | ||
| 3131 | u64 user_thresh_min; | ||
| 3132 | u64 user_thresh_max; | ||
| 3133 | int ret = 1; | ||
| 3134 | |||
| 3135 | cache = btrfs_lookup_block_group(fs_info, chunk_offset); | ||
| 3136 | chunk_used = btrfs_block_group_used(&cache->item); | ||
| 3137 | |||
| 3138 | if (bargs->usage_min == 0) | ||
| 3139 | user_thresh_min = 0; | ||
| 3140 | else | ||
| 3141 | user_thresh_min = div_factor_fine(cache->key.offset, | ||
| 3142 | bargs->usage_min); | ||
| 3143 | |||
| 3144 | if (bargs->usage_max == 0) | ||
| 3145 | user_thresh_max = 1; | ||
| 3146 | else if (bargs->usage_max > 100) | ||
| 3147 | user_thresh_max = cache->key.offset; | ||
| 3148 | else | ||
| 3149 | user_thresh_max = div_factor_fine(cache->key.offset, | ||
| 3150 | bargs->usage_max); | ||
| 3151 | |||
| 3152 | if (user_thresh_min <= chunk_used && chunk_used < user_thresh_max) | ||
| 3153 | ret = 0; | ||
| 3154 | |||
| 3155 | btrfs_put_block_group(cache); | ||
| 3156 | return ret; | ||
| 3157 | } | ||
| 3158 | |||
| 3159 | static int chunk_usage_range_filter(struct btrfs_fs_info *fs_info, | ||
| 3160 | u64 chunk_offset, struct btrfs_balance_args *bargs) | ||
| 3161 | { | ||
| 3162 | struct btrfs_block_group_cache *cache; | ||
| 3127 | u64 chunk_used, user_thresh; | 3163 | u64 chunk_used, user_thresh; |
| 3128 | int ret = 1; | 3164 | int ret = 1; |
| 3129 | 3165 | ||
| 3130 | cache = btrfs_lookup_block_group(fs_info, chunk_offset); | 3166 | cache = btrfs_lookup_block_group(fs_info, chunk_offset); |
| 3131 | chunk_used = btrfs_block_group_used(&cache->item); | 3167 | chunk_used = btrfs_block_group_used(&cache->item); |
| 3132 | 3168 | ||
| 3133 | if (bargs->usage == 0) | 3169 | if (bargs->usage_min == 0) |
| 3134 | user_thresh = 1; | 3170 | user_thresh = 1; |
| 3135 | else if (bargs->usage > 100) | 3171 | else if (bargs->usage > 100) |
| 3136 | user_thresh = cache->key.offset; | 3172 | user_thresh = cache->key.offset; |
| @@ -3279,6 +3315,9 @@ static int should_balance_chunk(struct btrfs_root *root, | |||
| 3279 | if ((bargs->flags & BTRFS_BALANCE_ARGS_USAGE) && | 3315 | if ((bargs->flags & BTRFS_BALANCE_ARGS_USAGE) && |
| 3280 | chunk_usage_filter(bctl->fs_info, chunk_offset, bargs)) { | 3316 | chunk_usage_filter(bctl->fs_info, chunk_offset, bargs)) { |
| 3281 | return 0; | 3317 | return 0; |
| 3318 | } else if ((bargs->flags & BTRFS_BALANCE_ARGS_USAGE_RANGE) && | ||
| 3319 | chunk_usage_range_filter(bctl->fs_info, chunk_offset, bargs)) { | ||
| 3320 | return 0; | ||
| 3282 | } | 3321 | } |
| 3283 | 3322 | ||
| 3284 | /* devid filter */ | 3323 | /* devid filter */ |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index a5bf224d3c65..2a396cbb14a5 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
| @@ -382,6 +382,7 @@ struct map_lookup { | |||
| 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 | #define BTRFS_BALANCE_ARGS_STRIPES_RANGE (1ULL << 7) |
| 385 | #define BTRFS_BALANCE_ARGS_USAGE_RANGE (1ULL << 8) | ||
| 385 | 386 | ||
| 386 | #define BTRFS_BALANCE_ARGS_MASK \ | 387 | #define BTRFS_BALANCE_ARGS_MASK \ |
| 387 | (BTRFS_BALANCE_ARGS_PROFILES | \ | 388 | (BTRFS_BALANCE_ARGS_PROFILES | \ |
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h index 17a94704b183..dea893199257 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h | |||
| @@ -206,7 +206,13 @@ struct btrfs_ioctl_feature_flags { | |||
| 206 | */ | 206 | */ |
| 207 | struct btrfs_balance_args { | 207 | struct btrfs_balance_args { |
| 208 | __u64 profiles; | 208 | __u64 profiles; |
| 209 | __u64 usage; | 209 | union { |
| 210 | __le64 usage; | ||
| 211 | struct { | ||
| 212 | __le32 usage_min; | ||
| 213 | __le32 usage_max; | ||
| 214 | }; | ||
| 215 | }; | ||
| 210 | __u64 devid; | 216 | __u64 devid; |
| 211 | __u64 pstart; | 217 | __u64 pstart; |
| 212 | __u64 pend; | 218 | __u64 pend; |
