Permalink
Browse files

Use opts.h for format options

  • Loading branch information...
koverstreet committed Dec 19, 2018
1 parent 99ccaf7 commit 0e9822571cc8e27852dcf2b0008b50acd1263a81
Showing with 315 additions and 223 deletions.
  1. +13 −5 cmd_device.c
  2. +55 −136 cmd_format.c
  3. +20 −12 cmd_migrate.c
  4. +202 −39 libbcachefs.c
  5. +23 −29 libbcachefs.h
  6. +1 −1 tools-util.c
  7. +1 −1 tools-util.h
@@ -95,12 +95,20 @@ int cmd_device_add(int argc, char *argv[])
dev_opts.path = dev_path;
dev_opts.fd = open_for_format(dev_opts.path, force);

format_opts.block_size =
read_file_u64(fs.sysfs_fd, "block_size") >> 9;
format_opts.btree_node_size =
read_file_u64(fs.sysfs_fd, "btree_node_size") >> 9;
struct bch_opt_strs fs_opt_strs;
memset(&fs_opt_strs, 0, sizeof(fs_opt_strs));

struct bch_sb *sb = bch2_format(format_opts, &dev_opts, 1);
struct bch_opts fs_opts = bch2_parse_opts(fs_opt_strs);

opt_set(fs_opts, block_size,
read_file_u64(fs.sysfs_fd, "block_size") >> 9);
opt_set(fs_opts, btree_node_size,
read_file_u64(fs.sysfs_fd, "btree_node_size") >> 9);

struct bch_sb *sb = bch2_format(fs_opt_strs,
fs_opts,
format_opts,
&dev_opts, 1);
free(sb);
fsync(dev_opts.fd);
close(dev_opts.fd);
@@ -5,6 +5,7 @@
*
* GPLv2
*/
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
@@ -28,109 +29,72 @@
#include "libbcachefs/super-io.h"
#include "libbcachefs/util.h"

#define OPTS \
t("bcachefs format - create a new bcachefs filesystem on one or more devices") \
t("Usage: bcachefs format [OPTION]... <devices>") \
t("") \
x('b', block_size, "size", NULL) \
x(0, btree_node_size, "size", "Default 256k") \
x(0, metadata_checksum_type, "(none|crc32c|crc64)", NULL) \
x(0, data_checksum_type, "(none|crc32c|crc64)", NULL) \
x(0, compression_type, "(none|lz4|gzip)", NULL) \
x(0, background_compression_type, "(none|lz4|gzip)", NULL) \
x(0, replicas, "#", NULL) \
x(0, data_replicas, "#", NULL) \
x(0, metadata_replicas, "#", NULL) \
x(0, foreground_target, "target", NULL) \
x(0, background_target, "target", NULL) \
x(0, promote_target, "target", NULL) \
x(0, encrypted, NULL, "Enable whole filesystem encryption (chacha20/poly1305)")\
x(0, no_passphrase, NULL, "Don't encrypt master encryption key")\
x('e', error_action, "(continue|remount-ro|panic)", NULL) \
x('L', label, "label", NULL) \
x('U', uuid, "uuid", NULL) \
x('f', force, NULL, NULL) \
t("") \
t("Device specific options:") \
x(0, fs_size, "size", "Size of filesystem on device")\
x(0, bucket_size, "size", "Bucket size") \
x('g', group, "label", "Disk group")\
x(0, discard, NULL, NULL) \
x(0, data_allowed, "journal,btree,data", "Allowed types of data on this device")\
x(0, durability, "#", "Number of times data written to this device will have been considered replicated")\
t("Device specific options must come before corresponding devices, e.g.") \
t(" bcachefs format --group cache /dev/sdb --tier 1 /dev/sdc") \
t("") \
x('q', quiet, NULL, "Only print errors") \
x('h', help, NULL, "Display this help and exit")
#define OPTS \
x(0, replicas, required_argument) \
x(0, encrypted, no_argument) \
x(0, no_passphrase, no_argument) \
x('L', label, required_argument) \
x('U', uuid, required_argument) \
x(0, fs_size, required_argument) \
x(0, bucket_size, required_argument) \
x('g', group, required_argument) \
x(0, discard, no_argument) \
x(0, data_allowed, required_argument) \
x(0, durability, required_argument) \
x('f', force, no_argument) \
x('q', quiet, no_argument) \
x('h', help, no_argument)

static void usage(void)
{
#define t(text) puts(text "\n")
#define x(shortopt, longopt, arg, help) do { \
OPTS
#undef x
#undef t

puts("bcachefs format - create a new bcachefs filesystem on one or more devices\n"
"Usage: bcachefs format [OPTION]... <devices>\n"
"\n"
"Options:\n"
" -b, --block=size\n"
" --btree_node=size Btree node size, default 256k\n"
" --metadata_checksum_type=(none|crc32c|crc64)\n"
" --data_checksum_type=(none|crc32c|crc64)\n"
" --compression_type=(none|lz4|gzip|zstd)\n"
" --background_compression_type=(none|lz4|gzip|zstd)\n"
" --data_replicas=# Number of data replicas\n"
" --metadata_replicas=# Number of metadata replicas\n"
"Options:");

bch2_opts_usage(OPT_FORMAT);

puts(
" --replicas=# Sets both data and metadata replicas\n"
" --encrypted Enable whole filesystem encryption (chacha20/poly1305)\n"
" --no_passphrase Don't encrypt master encryption key\n"
" -e, --error_action=(continue|remount-ro|panic)\n"
" Action to take on filesystem error\n"
" -L, --label=label\n"
" -U, --uuid=uuid\n"
" -f, --force\n"
"\n"
"Device specific options:\n"
" --fs_size=size Size of filesystem on device\n"
" --bucket=size Bucket size\n"
" --discard Enable discards\n"
" --durability=# Device durability (0-4)\n"
" -g, --group=label Disk group\n"
"Device specific options:");

bch2_opts_usage(OPT_DEVICE);

puts(" -g, --group=label Disk group\n"
"\n"
" -f, --force\n"
" -q, --quiet Only print errors\n"
" -h, --help Display this help and exit\n"
"\n"
"Device specific options must come before corresponding devices, e.g.\n"
" bcachefs format --group cache /dev/sdb --tier 1 /dev/sdc\n"
" bcachefs format --group cache /dev/sdb /dev/sdc\n"
"\n"
"Report bugs to <linux-bcache@vger.kernel.org>");
}

enum {
O_no_opt = 1,
#define t(text)
#define x(shortopt, longopt, arg, help) O_##longopt,
#define x(shortopt, longopt, arg) O_##longopt,
OPTS
#undef x
#undef t
};

static const struct option format_opts[] = {
#define t(text)
#define x(shortopt, longopt, arg, help) { \
.name = #longopt, \
.has_arg = arg ? required_argument : no_argument, \
.flag = NULL, \
.val = O_##longopt, \
#define x(shortopt, longopt, arg) { \
.name = #longopt, \
.has_arg = arg, \
.flag = NULL, \
.val = O_##longopt, \
},
static const struct option format_opts[] = {
OPTS
#undef x
#undef t
{ NULL }
};
#undef x

u64 read_flag_list_or_die(char *opt, const char * const list[],
const char *msg)
@@ -148,86 +112,35 @@ int cmd_format(int argc, char *argv[])
struct format_opts opts = format_opts_default();
struct dev_opts dev_opts = dev_opts_default(), *dev;
bool force = false, no_passphrase = false, quiet = false;
unsigned v;
int opt;

darray_init(devices);

struct bch_opt_strs fs_opt_strs =
bch2_cmdline_opts_get(&argc, argv, OPT_FORMAT);
struct bch_opts fs_opts = bch2_parse_opts(fs_opt_strs);

while ((opt = getopt_long(argc, argv,
"-b:e:g:L:U:fqh",
"-L:U:fh",
format_opts,
NULL)) != -1)
switch (opt) {
case O_block_size:
case 'b':
opts.block_size =
hatoi_validate(optarg, "block size");
break;
case O_btree_node_size:
opts.btree_node_size =
hatoi_validate(optarg, "btree node size");
break;
case O_metadata_checksum_type:
opts.meta_csum_type =
read_string_list_or_die(optarg,
bch2_csum_types, "checksum type");
break;
case O_data_checksum_type:
opts.data_csum_type =
read_string_list_or_die(optarg,
bch2_csum_types, "checksum type");
break;
case O_compression_type:
opts.compression_type =
read_string_list_or_die(optarg,
bch2_compression_types,
"compression type");
break;
case O_background_compression_type:
opts.background_compression_type =
read_string_list_or_die(optarg,
bch2_compression_types,
"compression type");
break;
case O_data_replicas:
if (kstrtouint(optarg, 10, &opts.data_replicas) ||
!opts.data_replicas ||
opts.data_replicas > BCH_REPLICAS_MAX)
die("invalid replicas");
break;
case O_metadata_replicas:
if (kstrtouint(optarg, 10, &opts.meta_replicas) ||
!opts.meta_replicas ||
opts.meta_replicas > BCH_REPLICAS_MAX)
die("invalid replicas");
break;
case O_replicas:
if (kstrtouint(optarg, 10, &opts.data_replicas) ||
!opts.data_replicas ||
opts.data_replicas > BCH_REPLICAS_MAX)
if (kstrtouint(optarg, 10, &v) ||
!v ||
v > BCH_REPLICAS_MAX)
die("invalid replicas");
opts.meta_replicas = opts.data_replicas;
break;
case O_foreground_target:
opts.foreground_target = optarg;
break;
case O_background_target:
opts.background_target = optarg;
break;
case O_promote_target:
opts.promote_target = optarg;

opt_set(fs_opts, metadata_replicas, v);
opt_set(fs_opts, data_replicas, v);
break;
case O_encrypted:
opts.encrypted = true;
break;
case O_no_passphrase:
no_passphrase = true;
break;
case O_error_action:
case 'e':
opts.on_error_action =
read_string_list_or_die(optarg,
bch2_error_actions, "error action");
break;
case O_label:
case 'L':
opts.label = optarg;
@@ -282,6 +195,9 @@ int cmd_format(int argc, char *argv[])
usage();
exit(EXIT_SUCCESS);
break;
case '?':
die("unrecognized option %s", optarg);
break;
}

if (darray_empty(devices))
@@ -294,7 +210,10 @@ int cmd_format(int argc, char *argv[])
dev->fd = open_for_format(dev->path, force);

struct bch_sb *sb =
bch2_format(opts, devices.item, darray_size(devices));
bch2_format(fs_opt_strs,
fs_opts,
opts,
devices.item, darray_size(devices));

if (!quiet)
bch2_sb_print(sb, false, 1 << BCH_SB_FIELD_members, HUMAN_READABLE);
@@ -185,13 +185,13 @@ static struct bch_inode_unpacked create_file(struct bch_fs *c,
(handler) != NULL; \
(handler) = *(handlers)++)

static const struct xattr_handler *xattr_resolve_name(const char **name)
static const struct xattr_handler *xattr_resolve_name(char **name)
{
const struct xattr_handler **handlers = bch2_xattr_handlers;
const struct xattr_handler *handler;

for_each_xattr_handler(handlers, handler) {
const char *n;
char *n;

n = strcmp_prefix(*name, xattr_prefix(handler));
if (n) {
@@ -225,7 +225,7 @@ static void copy_xattrs(struct bch_fs *c, struct bch_inode_unpacked *dst,
if (attrs_size < 0)
die("listxattr error: %m");

const char *next, *attr;
char *next, *attr;
for (attr = attrs;
attr < attrs + attrs_size;
attr = next) {
@@ -657,8 +657,10 @@ static const struct option migrate_opts[] = {
{ NULL }
};

static int migrate_fs(const char *fs_path,
struct format_opts format_opts,
static int migrate_fs(const char *fs_path,
struct bch_opt_strs fs_opt_strs,
struct bch_opts fs_opts,
struct format_opts format_opts,
bool force)
{
if (!path_is_fs_root(fs_path))
@@ -675,25 +677,24 @@ static int migrate_fs(const char *fs_path,
dev.path = dev_t_to_path(stat.st_dev);
dev.fd = xopen(dev.path, O_RDWR);

unsigned block_size = get_blocksize(dev.path, dev.fd) << 9;
BUG_ON(!is_power_of_2(block_size) || block_size < 512);
format_opts.block_size = block_size >> 9;
opt_set(fs_opts, block_size, get_blocksize(dev.path, dev.fd));

char *file_path = mprintf("%s/bcachefs", fs_path);
printf("Creating new filesystem on %s in space reserved at %s\n",
dev.path, file_path);

bch2_pick_bucket_size(format_opts, &dev);
bch2_pick_bucket_size(fs_opts, &dev);

u64 bcachefs_inum;
ranges extents = reserve_new_fs_space(file_path,
format_opts.block_size << 9,
fs_opts.block_size << 9,
get_size(dev.path, dev.fd) / 5,
&bcachefs_inum, stat.st_dev, force);

find_superblock_space(extents, &dev);

struct bch_sb *sb = bch2_format(format_opts, &dev, 1);
struct bch_sb *sb = bch2_format(fs_opt_strs,
fs_opts,format_opts, &dev, 1);
u64 sb_offset = le64_to_cpu(sb->layout.sb_offset[0]);

if (format_opts.passphrase)
@@ -757,6 +758,10 @@ int cmd_migrate(int argc, char *argv[])
bool no_passphrase = false, force = false;
int opt;

struct bch_opt_strs fs_opt_strs =
bch2_cmdline_opts_get(&argc, argv, OPT_FORMAT);
struct bch_opts fs_opts = bch2_parse_opts(fs_opt_strs);

while ((opt = getopt_long(argc, argv, "f:Fh",
migrate_opts, NULL)) != -1)
switch (opt) {
@@ -783,7 +788,10 @@ int cmd_migrate(int argc, char *argv[])
if (format_opts.encrypted && !no_passphrase)
format_opts.passphrase = read_passphrase_twice("Enter passphrase: ");

return migrate_fs(fs_path, format_opts, force);
return migrate_fs(fs_path,
fs_opt_strs,
fs_opts,
format_opts, force);
}

static void migrate_superblock_usage(void)
Oops, something went wrong.

0 comments on commit 0e98225

Please sign in to comment.