*/
 enum btrfs_exclusive_operation {
        BTRFS_EXCLOP_NONE,
+       BTRFS_EXCLOP_BALANCE_PAUSED,
        BTRFS_EXCLOP_BALANCE,
        BTRFS_EXCLOP_DEV_ADD,
        BTRFS_EXCLOP_DEV_REMOVE,
                                 enum btrfs_exclusive_operation type);
 void btrfs_exclop_start_unlock(struct btrfs_fs_info *fs_info);
 void btrfs_exclop_finish(struct btrfs_fs_info *fs_info);
+void btrfs_exclop_balance(struct btrfs_fs_info *fs_info,
+                         enum btrfs_exclusive_operation op);
+
 
 /* file.c */
 int __init btrfs_auto_defrag_init(void);
 
        sysfs_notify(&fs_info->fs_devices->fsid_kobj, NULL, "exclusive_operation");
 }
 
+void btrfs_exclop_balance(struct btrfs_fs_info *fs_info,
+                         enum btrfs_exclusive_operation op)
+{
+       switch (op) {
+       case BTRFS_EXCLOP_BALANCE_PAUSED:
+               spin_lock(&fs_info->super_lock);
+               ASSERT(fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE ||
+                      fs_info->exclusive_operation == BTRFS_EXCLOP_DEV_ADD);
+               fs_info->exclusive_operation = BTRFS_EXCLOP_BALANCE_PAUSED;
+               spin_unlock(&fs_info->super_lock);
+               break;
+       case BTRFS_EXCLOP_BALANCE:
+               spin_lock(&fs_info->super_lock);
+               ASSERT(fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE_PAUSED);
+               fs_info->exclusive_operation = BTRFS_EXCLOP_BALANCE;
+               spin_unlock(&fs_info->super_lock);
+               break;
+       default:
+               btrfs_warn(fs_info,
+                       "invalid exclop balance operation %d requested", op);
+       }
+}
+
 static int btrfs_ioctl_getversion(struct file *file, int __user *arg)
 {
        struct inode *inode = file_inode(file);
                        spin_lock(&fs_info->balance_lock);
                        bctl->flags |= BTRFS_BALANCE_RESUME;
                        spin_unlock(&fs_info->balance_lock);
+                       btrfs_exclop_balance(fs_info, BTRFS_EXCLOP_BALANCE);
 
                        goto do_balance;
                }
 
        ret = __btrfs_balance(fs_info);
 
        mutex_lock(&fs_info->balance_mutex);
-       if (ret == -ECANCELED && atomic_read(&fs_info->balance_pause_req))
+       if (ret == -ECANCELED && atomic_read(&fs_info->balance_pause_req)) {
                btrfs_info(fs_info, "balance: paused");
+               btrfs_exclop_balance(fs_info, BTRFS_EXCLOP_BALANCE_PAUSED);
+       }
        /*
         * Balance can be canceled by:
         *
                return 0;
        }
 
+       spin_lock(&fs_info->super_lock);
+       ASSERT(fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE_PAUSED);
+       fs_info->exclusive_operation = BTRFS_EXCLOP_BALANCE;
+       spin_unlock(&fs_info->super_lock);
        /*
         * A ro->rw remount sequence should continue with the paused balance
         * regardless of who pauses it, system or the user as of now, so set
         * is in a paused state and must have fs_info::balance_ctl properly
         * set up.
         */
-       if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_BALANCE))
+       if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_BALANCE_PAUSED))
                btrfs_warn(fs_info,
        "balance: cannot set exclusive op status, resume manually");