From patchwork Mon Jul 27 22:04:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 11687717 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D81D8912 for ; Mon, 27 Jul 2020 22:05:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C330021883 for ; Mon, 27 Jul 2020 22:05:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726907AbgG0WFB (ORCPT ); Mon, 27 Jul 2020 18:05:01 -0400 Received: from mx2.suse.de ([195.135.220.15]:58042 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726140AbgG0WFB (ORCPT ); Mon, 27 Jul 2020 18:05:01 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 8E995AB7A; Mon, 27 Jul 2020 22:05:09 +0000 (UTC) From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 1/3] btrfs: enumerate the type of exclusive operation in progress Date: Mon, 27 Jul 2020 17:04:49 -0500 Message-Id: <20200727220451.30680-2-rgoldwyn@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200727220451.30680-1-rgoldwyn@suse.de> References: <20200727220451.30680-1-rgoldwyn@suse.de> MIME-Version: 1.0 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues Instead of using a flag bit for exclusive operation, use an atomic_t variable to store if the exclusive operation is being performed. Introduce an API to start and finish an exclusive operation. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/ctree.h | 24 +++++++++++++++++++----- fs/btrfs/dev-replace.c | 4 ++-- fs/btrfs/inode.c | 4 ++-- fs/btrfs/ioctl.c | 36 +++++++++++++++++++++++------------- fs/btrfs/volumes.c | 8 ++++---- 5 files changed, 50 insertions(+), 26 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index d404cce8ae40..a56f383a7894 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -540,11 +540,6 @@ enum { BTRFS_FS_QUOTA_OVERRIDE, /* Used to record internally whether fs has been frozen */ BTRFS_FS_FROZEN, - /* - * Indicate that a whole-filesystem exclusive operation is running - * (device replace, resize, device add/delete, balance) - */ - BTRFS_FS_EXCL_OP, /* * To info transaction_kthread we need an immediate commit so it * doesn't need to wait for commit_interval @@ -570,6 +565,20 @@ enum { BTRFS_FS_DISCARD_RUNNING, }; +/* + * Exclusive operation values + * (device replace, resize, device add/remove, balance) + */ +enum btrfs_exclusive_operation_t { + BTRFS_EXCLOP_NONE = 0, + BTRFS_EXCLOP_BALANCE, + BTRFS_EXCLOP_DEV_ADD, + BTRFS_EXCLOP_DEV_REPLACE, + BTRFS_EXCLOP_DEV_REMOVE, + BTRFS_EXCLOP_SWAP_ACTIVATE, + BTRFS_EXCLOP_RESIZE, +}; + struct btrfs_fs_info { u8 chunk_tree_uuid[BTRFS_UUID_SIZE]; unsigned long flags; @@ -939,6 +948,9 @@ struct btrfs_fs_info { */ int send_in_progress; + /* Type of exclusive operation running */ + atomic_t exclusive_operation; + #ifdef CONFIG_BTRFS_FS_REF_VERIFY spinlock_t ref_verify_lock; struct rb_root block_tree; @@ -2949,6 +2961,8 @@ void btrfs_get_block_group_info(struct list_head *groups_list, struct btrfs_ioctl_space_info *space); void btrfs_update_ioctl_balance_args(struct btrfs_fs_info *fs_info, struct btrfs_ioctl_balance_args *bargs); +bool btrfs_exclop_start(struct btrfs_fs_info *fs_info, int type); +void btrfs_exclop_finish(struct btrfs_fs_info *fs_info); /* file.c */ int __init btrfs_auto_defrag_init(void); diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index db93909b25e0..b8406f5cc8ff 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c @@ -983,7 +983,7 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info) * should never allow both to start and pause. We don't want to allow * dev-replace to start anyway. */ - if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) { + if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_DEV_REPLACE)) { down_write(&dev_replace->rwsem); dev_replace->replace_state = BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED; @@ -1020,7 +1020,7 @@ static int btrfs_dev_replace_kthread(void *data) ret = btrfs_dev_replace_finishing(fs_info, ret); WARN_ON(ret && ret != -ECANCELED); - clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags); + btrfs_exclop_finish(fs_info); return 0; } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 43c803c16b48..ba4e4b902b13 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -10012,7 +10012,7 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file, * concurrent device add which isn't actually necessary, but it's not * really worth the trouble to allow it. */ - if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) { + if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_SWAP_ACTIVATE)) { btrfs_warn(fs_info, "cannot activate swapfile while exclusive operation is running"); return -EBUSY; @@ -10158,7 +10158,7 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file, if (ret) btrfs_swap_deactivate(file); - clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags); + btrfs_exclop_finish(fs_info); if (ret) return ret; diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index e8f7c5f00894..2f45b88d7eed 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -364,6 +364,17 @@ static int check_xflags(unsigned int flags) return 0; } +bool btrfs_exclop_start(struct btrfs_fs_info *fs_info, int type) +{ + return !atomic_cmpxchg(&fs_info->exclusive_operation, BTRFS_EXCLOP_NONE, + type); +} + +void btrfs_exclop_finish(struct btrfs_fs_info *fs_info) +{ + atomic_set(&fs_info->exclusive_operation, BTRFS_EXCLOP_NONE); +} + /* * Set the xflags from the internal inode flags. The remaining items of fsxattr * are zeroed. @@ -1605,7 +1616,7 @@ static noinline int btrfs_ioctl_resize(struct file *file, if (ret) return ret; - if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) { + if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_RESIZE)) { mnt_drop_write_file(file); return BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; } @@ -1719,7 +1730,7 @@ static noinline int btrfs_ioctl_resize(struct file *file, out_free: kfree(vol_args); out: - clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags); + btrfs_exclop_finish(fs_info); mnt_drop_write_file(file); return ret; } @@ -3079,7 +3090,7 @@ static long btrfs_ioctl_add_dev(struct btrfs_fs_info *fs_info, void __user *arg) if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) + if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_DEV_ADD)) return BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; vol_args = memdup_user(arg, sizeof(*vol_args)); @@ -3096,7 +3107,7 @@ static long btrfs_ioctl_add_dev(struct btrfs_fs_info *fs_info, void __user *arg) kfree(vol_args); out: - clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags); + btrfs_exclop_finish(fs_info); return ret; } @@ -3125,7 +3136,7 @@ static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg) goto out; } - if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) { + if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_DEV_REMOVE)) { ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; goto out; } @@ -3136,7 +3147,7 @@ static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg) vol_args->name[BTRFS_SUBVOL_NAME_MAX] = '\0'; ret = btrfs_rm_device(fs_info, vol_args->name, 0); } - clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags); + btrfs_exclop_finish(fs_info); if (!ret) { if (vol_args->flags & BTRFS_DEVICE_SPEC_BY_ID) @@ -3167,7 +3178,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) if (ret) return ret; - if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) { + if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_DEV_REMOVE)) { ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; goto out_drop_write; } @@ -3185,7 +3196,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) btrfs_info(fs_info, "disk deleted %s", vol_args->name); kfree(vol_args); out: - clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags); + btrfs_exclop_finish(fs_info); out_drop_write: mnt_drop_write_file(file); @@ -3668,11 +3679,11 @@ static long btrfs_ioctl_dev_replace(struct btrfs_fs_info *fs_info, ret = -EROFS; goto out; } - if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) { + if (btrfs_exclop_start(fs_info, BTRFS_EXCLOP_DEV_REPLACE)) { ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; } else { ret = btrfs_dev_replace_by_ioctl(fs_info, p); - clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags); + btrfs_exclop_finish(fs_info); } break; case BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS: @@ -3883,7 +3894,7 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg) return ret; again: - if (!test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) { + if (btrfs_exclop_start(fs_info, BTRFS_EXCLOP_BALANCE)) { mutex_lock(&fs_info->balance_mutex); need_unlock = true; goto locked; @@ -3929,7 +3940,6 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg) } locked: - BUG_ON(!test_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)); if (arg) { bargs = memdup_user(arg, sizeof(*bargs)); @@ -4006,7 +4016,7 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg) out_unlock: mutex_unlock(&fs_info->balance_mutex); if (need_unlock) - clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags); + btrfs_exclop_finish(fs_info); out: mnt_drop_write_file(file); return ret; diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 0d6e785bcb98..8a55ac7a0d3e 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -4150,7 +4150,7 @@ int btrfs_balance(struct btrfs_fs_info *fs_info, if ((ret && ret != -ECANCELED && ret != -ENOSPC) || balance_need_close(fs_info)) { reset_balance_state(fs_info); - clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags); + btrfs_exclop_finish(fs_info); } wake_up(&fs_info->balance_wait_q); @@ -4161,7 +4161,7 @@ int btrfs_balance(struct btrfs_fs_info *fs_info, reset_balance_state(fs_info); else kfree(bctl); - clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags); + btrfs_exclop_finish(fs_info); return ret; } @@ -4263,7 +4263,7 @@ int btrfs_recover_balance(struct btrfs_fs_info *fs_info) * is in a paused state and must have fs_info::balance_ctl properly * set up. */ - if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) + if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_BALANCE)) btrfs_warn(fs_info, "balance: cannot set exclusive op status, resume manually"); @@ -4345,7 +4345,7 @@ int btrfs_cancel_balance(struct btrfs_fs_info *fs_info) if (fs_info->balance_ctl) { reset_balance_state(fs_info); - clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags); + btrfs_exclop_finish(fs_info); btrfs_info(fs_info, "balance: canceled"); } } From patchwork Mon Jul 27 22:04:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 11687719 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C737E13B6 for ; Mon, 27 Jul 2020 22:05:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B85F82083E for ; Mon, 27 Jul 2020 22:05:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726946AbgG0WFF (ORCPT ); Mon, 27 Jul 2020 18:05:05 -0400 Received: from mx2.suse.de ([195.135.220.15]:58082 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726140AbgG0WFD (ORCPT ); Mon, 27 Jul 2020 18:05:03 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 84574AB7A; Mon, 27 Jul 2020 22:05:12 +0000 (UTC) From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 2/3] btrfs: export currently executing exclusive operation via sysfs Date: Mon, 27 Jul 2020 17:04:50 -0500 Message-Id: <20200727220451.30680-3-rgoldwyn@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200727220451.30680-1-rgoldwyn@suse.de> References: <20200727220451.30680-1-rgoldwyn@suse.de> MIME-Version: 1.0 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues /sys/fs//exclusive_operation contains the currently executing exclusive operation. Add a sysfs_notify() when operation end, so userspace can be notified of exclusive operation is finished. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/ioctl.c | 2 ++ fs/btrfs/sysfs.c | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 2f45b88d7eed..a00d6d5c42c1 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -373,6 +373,8 @@ bool btrfs_exclop_start(struct btrfs_fs_info *fs_info, int type) void btrfs_exclop_finish(struct btrfs_fs_info *fs_info) { atomic_set(&fs_info->exclusive_operation, BTRFS_EXCLOP_NONE); + sysfs_notify(&fs_info->fs_devices->fsid_kobj, NULL, + "exclusive_operation"); } /* diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index a39bff64ff24..71950c121588 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -808,6 +808,30 @@ static ssize_t btrfs_checksum_show(struct kobject *kobj, BTRFS_ATTR(, checksum, btrfs_checksum_show); +static ssize_t btrfs_exclusive_operation_show(struct kobject *kobj, + struct kobj_attribute *a, char *buf) +{ + struct btrfs_fs_info *fs_info = to_fs_info(kobj); + switch (atomic_read(&fs_info->exclusive_operation)) { + case BTRFS_EXCLOP_NONE: + return scnprintf(buf, PAGE_SIZE, "none\n"); + case BTRFS_EXCLOP_BALANCE: + return scnprintf(buf, PAGE_SIZE, "balance\n"); + case BTRFS_EXCLOP_DEV_ADD: + return scnprintf(buf, PAGE_SIZE, "device add\n"); + case BTRFS_EXCLOP_DEV_REPLACE: + return scnprintf(buf, PAGE_SIZE, "device replace\n"); + case BTRFS_EXCLOP_DEV_REMOVE: + return scnprintf(buf, PAGE_SIZE, "device remove\n"); + case BTRFS_EXCLOP_SWAP_ACTIVATE: + return scnprintf(buf, PAGE_SIZE, "swap activate\n"); + case BTRFS_EXCLOP_RESIZE: + return scnprintf(buf, PAGE_SIZE, "resize\n"); + } + return 0; +} +BTRFS_ATTR(, exclusive_operation, btrfs_exclusive_operation_show); + static const struct attribute *btrfs_attrs[] = { BTRFS_ATTR_PTR(, label), BTRFS_ATTR_PTR(, nodesize), @@ -816,6 +840,7 @@ static const struct attribute *btrfs_attrs[] = { BTRFS_ATTR_PTR(, quota_override), BTRFS_ATTR_PTR(, metadata_uuid), BTRFS_ATTR_PTR(, checksum), + BTRFS_ATTR_PTR(, exclusive_operation), NULL, }; From patchwork Mon Jul 27 22:04:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 11687721 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D6716138A for ; Mon, 27 Jul 2020 22:05:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BE1222075D for ; Mon, 27 Jul 2020 22:05:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726455AbgG0WFH (ORCPT ); Mon, 27 Jul 2020 18:05:07 -0400 Received: from mx2.suse.de ([195.135.220.15]:58120 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726140AbgG0WFG (ORCPT ); Mon, 27 Jul 2020 18:05:06 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 7C211AB7A; Mon, 27 Jul 2020 22:05:15 +0000 (UTC) From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 3/3] btrfs: add more information for balance Date: Mon, 27 Jul 2020 17:04:51 -0500 Message-Id: <20200727220451.30680-4-rgoldwyn@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200727220451.30680-1-rgoldwyn@suse.de> References: <20200727220451.30680-1-rgoldwyn@suse.de> MIME-Version: 1.0 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues Include information about the state of the balance and expected, considered and completed statistics. Q: I am not sure of the cancelled state, and stopping seemed more appropriate since it was a transient state to cancelling the operation. Would you prefer to call it cancelled? This information is not used by user space as of now. We could use it for "btrfs balance status" or ignore this patch for inclusion at all. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/sysfs.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index 71950c121588..001a7ae375d0 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -808,6 +808,33 @@ static ssize_t btrfs_checksum_show(struct kobject *kobj, BTRFS_ATTR(, checksum, btrfs_checksum_show); +static ssize_t btrfs_balance_show(struct btrfs_fs_info *fs_info, char *buf) +{ + ssize_t ret = 0; + struct btrfs_balance_control *bctl; + + ret += scnprintf(buf, PAGE_SIZE, "balance\n"); + spin_lock(&fs_info->balance_lock); + bctl = fs_info->balance_ctl; + if (!bctl) { + ret += scnprintf(buf + ret, PAGE_SIZE - ret, + "State: stopping\n"); + goto out; + } + if (test_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags)) + ret += scnprintf(buf + ret, PAGE_SIZE - ret, + "State: running\n"); + else + ret += scnprintf(buf + ret, PAGE_SIZE - ret, + "State: paused\n"); + ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%llu %llu %llu\n", + bctl->stat.expected, bctl->stat.considered, + bctl->stat.completed); +out: + spin_unlock(&fs_info->balance_lock); + return ret; +} + static ssize_t btrfs_exclusive_operation_show(struct kobject *kobj, struct kobj_attribute *a, char *buf) { @@ -816,7 +843,7 @@ static ssize_t btrfs_exclusive_operation_show(struct kobject *kobj, case BTRFS_EXCLOP_NONE: return scnprintf(buf, PAGE_SIZE, "none\n"); case BTRFS_EXCLOP_BALANCE: - return scnprintf(buf, PAGE_SIZE, "balance\n"); + return btrfs_balance_show(fs_info, buf); case BTRFS_EXCLOP_DEV_ADD: return scnprintf(buf, PAGE_SIZE, "device add\n"); case BTRFS_EXCLOP_DEV_REPLACE: