This is so we can force chunk allocation to test various parts of the fs. I used this to test my btrfsck patch for checking for empty block groups, and a weird block group removal issue.
Signed-off-by: Josef Bacik <jo...@toxicpanda.com> --- cmds/filesystem.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ ioctl.h | 1 + 2 files changed, 49 insertions(+) diff --git a/cmds/filesystem.c b/cmds/filesystem.c index 4f22089a..93d51195 100644 --- a/cmds/filesystem.c +++ b/cmds/filesystem.c @@ -1174,6 +1174,53 @@ static int cmd_filesystem_label(const struct cmd_struct *cmd, } static DEFINE_SIMPLE_COMMAND(filesystem_label, "label"); +static const char * const cmd_filesystem_alloc_chunk_usage[] = { + "btrfs filesystem alloc-chunk [data|metadata|system] <path>", + "Force a chunk allocation of the specified type on the given filesystem.", + NULL +}; + +static int cmd_filesystem_alloc_chunk(const struct cmd_struct *cmd, + int argc, char **argv) +{ + char *path; + DIR *dirstream = NULL; + int fd, ret, e; + u64 flags = 0; + + clean_args_no_options(cmd, argc, argv); + + if (check_argc_exact(argc - optind, 2)) + return 1; + + if (!strncmp(argv[optind], "data", strlen("data"))) + flags = BTRFS_BLOCK_GROUP_DATA; + else if (!strncmp(argv[optind], "system", strlen("system"))) + flags = BTRFS_BLOCK_GROUP_SYSTEM; + else if (!strncmp(argv[optind], "metadata", strlen("metadata"))) + flags = BTRFS_BLOCK_GROUP_METADATA; + + if (flags == 0) { + error("Must specify either data, system, or metadata"); + return 1; + } + + path = argv[optind + 1]; + fd = btrfs_open_dir(path, &dirstream, 1); + if (fd < 0) + return 1; + + ret = ioctl(fd, BTRFS_IOC_ALLOC_CHUNK, &flags); + e = errno; + close_file_or_dir(fd, dirstream); + if (ret) { + error("Failed to alloc chunk: %d", e); + return 1; + } + return 0; +} +static DEFINE_SIMPLE_COMMAND(filesystem_alloc_chunk, "alloc-chunk"); + static const char * const cmd_filesystem_balance_usage[] = { "btrfs filesystem balance [args...] (alias of \"btrfs balance\")", "Please see \"btrfs balance --help\" for more information.", @@ -1209,6 +1256,7 @@ static const struct cmd_group filesystem_cmd_group = { &cmd_struct_filesystem_resize, &cmd_struct_filesystem_label, &cmd_struct_filesystem_usage, + &cmd_struct_filesystem_alloc_chunk, NULL } }; diff --git a/ioctl.h b/ioctl.h index 66ee599f..4a5c2891 100644 --- a/ioctl.h +++ b/ioctl.h @@ -929,6 +929,7 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code) struct btrfs_ioctl_get_subvol_rootref_args) #define BTRFS_IOC_INO_LOOKUP_USER _IOWR(BTRFS_IOCTL_MAGIC, 62, \ struct btrfs_ioctl_ino_lookup_user_args) +#define BTRFS_IOC_ALLOC_CHUNK _IOR(BTRFS_IOCTL_MAGIC, 63, __u64) #ifdef __cplusplus } #endif -- 2.21.0