btrfs: balance: print args during start and resume

The information about balance arguments is important for system audit,
this patch prints the textual representation when balance starts or is
resumed.

Example command:

 $ btrfs balance start -f -mprofiles=raid1,convert=single,soft -dlimit=10..20,usage=50 /btrfs

Example kernel log output:

 BTRFS info (device sdb): balance: start -f -dusage=50,limit=10..20 -mconvert=single,soft,profiles=raid1 -sconvert=single,soft,profiles=raid1

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
[ update changelog, simplify code ]
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Anand Jain 2018-11-20 16:12:56 +08:00 committed by David Sterba
parent f89e09cf45
commit 56fc37d936

View File

@ -3979,6 +3979,162 @@ static inline int validate_convert_profile(struct btrfs_balance_args *bctl_arg,
(bctl_arg->target & ~allowed)));
}
/*
* Fill @buf with textual description of balance filter flags @bargs, up to
* @size_buf including the terminating null. The output may be trimmed if it
* does not fit into the provided buffer.
*/
static void describe_balance_args(struct btrfs_balance_args *bargs, char *buf,
u32 size_buf)
{
int ret;
u32 size_bp = size_buf;
char *bp = buf;
u64 flags = bargs->flags;
char tmp_buf[128] = {'\0'};
if (!flags)
return;
#define CHECK_APPEND_NOARG(a) \
do { \
ret = snprintf(bp, size_bp, (a)); \
if (ret < 0 || ret >= size_bp) \
goto out_overflow; \
size_bp -= ret; \
bp += ret; \
} while (0)
#define CHECK_APPEND_1ARG(a, v1) \
do { \
ret = snprintf(bp, size_bp, (a), (v1)); \
if (ret < 0 || ret >= size_bp) \
goto out_overflow; \
size_bp -= ret; \
bp += ret; \
} while (0)
#define CHECK_APPEND_2ARG(a, v1, v2) \
do { \
ret = snprintf(bp, size_bp, (a), (v1), (v2)); \
if (ret < 0 || ret >= size_bp) \
goto out_overflow; \
size_bp -= ret; \
bp += ret; \
} while (0)
if (flags & BTRFS_BALANCE_ARGS_CONVERT) {
int index = btrfs_bg_flags_to_raid_index(bargs->target);
CHECK_APPEND_1ARG("convert=%s,", get_raid_name(index));
}
if (flags & BTRFS_BALANCE_ARGS_SOFT)
CHECK_APPEND_NOARG("soft,");
if (flags & BTRFS_BALANCE_ARGS_PROFILES) {
btrfs_describe_block_groups(bargs->profiles, tmp_buf,
sizeof(tmp_buf));
CHECK_APPEND_1ARG("profiles=%s,", tmp_buf);
}
if (flags & BTRFS_BALANCE_ARGS_USAGE)
CHECK_APPEND_1ARG("usage=%llu,", bargs->usage);
if (flags & BTRFS_BALANCE_ARGS_USAGE_RANGE)
CHECK_APPEND_2ARG("usage=%u..%u,",
bargs->usage_min, bargs->usage_max);
if (flags & BTRFS_BALANCE_ARGS_DEVID)
CHECK_APPEND_1ARG("devid=%llu,", bargs->devid);
if (flags & BTRFS_BALANCE_ARGS_DRANGE)
CHECK_APPEND_2ARG("drange=%llu..%llu,",
bargs->pstart, bargs->pend);
if (flags & BTRFS_BALANCE_ARGS_VRANGE)
CHECK_APPEND_2ARG("vrange=%llu..%llu,",
bargs->vstart, bargs->vend);
if (flags & BTRFS_BALANCE_ARGS_LIMIT)
CHECK_APPEND_1ARG("limit=%llu,", bargs->limit);
if (flags & BTRFS_BALANCE_ARGS_LIMIT_RANGE)
CHECK_APPEND_2ARG("limit=%u..%u,",
bargs->limit_min, bargs->limit_max);
if (flags & BTRFS_BALANCE_ARGS_STRIPES_RANGE)
CHECK_APPEND_2ARG("stripes=%u..%u,",
bargs->stripes_min, bargs->stripes_max);
#undef CHECK_APPEND_2ARG
#undef CHECK_APPEND_1ARG
#undef CHECK_APPEND_NOARG
out_overflow:
if (size_bp < size_buf)
buf[size_buf - size_bp - 1] = '\0'; /* remove last , */
else
buf[0] = '\0';
}
static void describe_balance_start_or_resume(struct btrfs_fs_info *fs_info)
{
u32 size_buf = 1024;
char tmp_buf[192] = {'\0'};
char *buf;
char *bp;
u32 size_bp = size_buf;
int ret;
struct btrfs_balance_control *bctl = fs_info->balance_ctl;
buf = kzalloc(size_buf, GFP_KERNEL);
if (!buf)
return;
bp = buf;
#define CHECK_APPEND_1ARG(a, v1) \
do { \
ret = snprintf(bp, size_bp, (a), (v1)); \
if (ret < 0 || ret >= size_bp) \
goto out_overflow; \
size_bp -= ret; \
bp += ret; \
} while (0)
if (bctl->flags & BTRFS_BALANCE_FORCE)
CHECK_APPEND_1ARG("%s", "-f ");
if (bctl->flags & BTRFS_BALANCE_DATA) {
describe_balance_args(&bctl->data, tmp_buf, sizeof(tmp_buf));
CHECK_APPEND_1ARG("-d%s ", tmp_buf);
}
if (bctl->flags & BTRFS_BALANCE_METADATA) {
describe_balance_args(&bctl->meta, tmp_buf, sizeof(tmp_buf));
CHECK_APPEND_1ARG("-m%s ", tmp_buf);
}
if (bctl->flags & BTRFS_BALANCE_SYSTEM) {
describe_balance_args(&bctl->sys, tmp_buf, sizeof(tmp_buf));
CHECK_APPEND_1ARG("-s%s ", tmp_buf);
}
#undef CHECK_APPEND_1ARG
out_overflow:
if (size_bp < size_buf)
buf[size_buf - size_bp - 1] = '\0'; /* remove last " " */
btrfs_info(fs_info, "balance: %s %s",
(bctl->flags & BTRFS_BALANCE_RESUME) ?
"resume" : "start", buf);
kfree(buf);
}
/*
* Should be called with balance mutexe held
*/
@ -4125,6 +4281,7 @@ int btrfs_balance(struct btrfs_fs_info *fs_info,
ASSERT(!test_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags));
set_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags);
describe_balance_start_or_resume(fs_info);
mutex_unlock(&fs_info->balance_mutex);
ret = __btrfs_balance(fs_info);
@ -4162,10 +4319,8 @@ static int balance_kthread(void *data)
int ret = 0;
mutex_lock(&fs_info->balance_mutex);
if (fs_info->balance_ctl) {
btrfs_info(fs_info, "balance: resuming");
if (fs_info->balance_ctl)
ret = btrfs_balance(fs_info, fs_info->balance_ctl, NULL);
}
mutex_unlock(&fs_info->balance_mutex);
return ret;