aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/volumes.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 28addea5b0f2..bcc0acda8691 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2650,6 +2650,7 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
2650{ 2650{
2651 struct btrfs_fs_info *fs_info = bctl->fs_info; 2651 struct btrfs_fs_info *fs_info = bctl->fs_info;
2652 u64 allowed; 2652 u64 allowed;
2653 int mixed = 0;
2653 int ret; 2654 int ret;
2654 2655
2655 if (btrfs_fs_closing(fs_info) || 2656 if (btrfs_fs_closing(fs_info) ||
@@ -2659,13 +2660,16 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
2659 goto out; 2660 goto out;
2660 } 2661 }
2661 2662
2663 allowed = btrfs_super_incompat_flags(fs_info->super_copy);
2664 if (allowed & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS)
2665 mixed = 1;
2666
2662 /* 2667 /*
2663 * In case of mixed groups both data and meta should be picked, 2668 * In case of mixed groups both data and meta should be picked,
2664 * and identical options should be given for both of them. 2669 * and identical options should be given for both of them.
2665 */ 2670 */
2666 allowed = btrfs_super_incompat_flags(fs_info->super_copy); 2671 allowed = BTRFS_BALANCE_DATA | BTRFS_BALANCE_METADATA;
2667 if ((allowed & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) && 2672 if (mixed && (bctl->flags & allowed)) {
2668 (bctl->flags & (BTRFS_BALANCE_DATA | BTRFS_BALANCE_METADATA))) {
2669 if (!(bctl->flags & BTRFS_BALANCE_DATA) || 2673 if (!(bctl->flags & BTRFS_BALANCE_DATA) ||
2670 !(bctl->flags & BTRFS_BALANCE_METADATA) || 2674 !(bctl->flags & BTRFS_BALANCE_METADATA) ||
2671 memcmp(&bctl->data, &bctl->meta, sizeof(bctl->data))) { 2675 memcmp(&bctl->data, &bctl->meta, sizeof(bctl->data))) {
@@ -2713,7 +2717,8 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
2713 goto out; 2717 goto out;
2714 } 2718 }
2715 2719
2716 if ((bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) && 2720 /* allow dup'ed data chunks only in mixed mode */
2721 if (!mixed && (bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) &&
2717 (bctl->data.target & BTRFS_BLOCK_GROUP_DUP)) { 2722 (bctl->data.target & BTRFS_BLOCK_GROUP_DUP)) {
2718 printk(KERN_ERR "btrfs: dup for data is not allowed\n"); 2723 printk(KERN_ERR "btrfs: dup for data is not allowed\n");
2719 ret = -EINVAL; 2724 ret = -EINVAL;