aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2015-10-20 12:22:13 -0400
committerChris Mason <clm@fb.com>2015-10-26 22:38:30 -0400
commitbc3094673f22d00794a8606200788e411b4ec80d (patch)
treea90e4834e26e4e69339a100d1489bcc3159e06d8
parentdee32d0ac3719ef8d640efaf0884111df444730f (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.h14
-rw-r--r--fs/btrfs/volumes.c41
-rw-r--r--fs/btrfs/volumes.h1
-rw-r--r--include/uapi/linux/btrfs.h8
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
3159static 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 */
207struct btrfs_balance_args { 207struct 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;