summaryrefslogtreecommitdiff
path: root/cmd_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'cmd_device.c')
-rw-r--r--cmd_device.c88
1 files changed, 79 insertions, 9 deletions
diff --git a/cmd_device.c b/cmd_device.c
index dfb6ef8..32f4492 100644
--- a/cmd_device.c
+++ b/cmd_device.c
@@ -177,20 +177,90 @@ int cmd_device_show(int argc, char *argv[])
return 0;
}
+static void device_add_usage(void)
+{
+ puts("bcache device_add - add a device to an existing filesystem\n"
+ "Usage: bcache device_add [OPTION]... filesystem device\n"
+ "\n"
+ "Options:\n"
+ " --fs_size=size Size of filesystem on device\n"
+ " --bucket=size Bucket size\n"
+ " --discard Enable discards\n"
+ " -t, --tier=# Higher tier (e.g. 1) indicates slower devices\n"
+ " -f, --force Use device even if it appears to already be formatted\n"
+ " -h, --help Display this help and exit\n"
+ "\n"
+ "Report bugs to <linux-bcache@vger.kernel.org>");
+}
+
+static const struct option device_add_opts[] = {
+ { "fs_size", required_argument, NULL, 'S' },
+ { "bucket", required_argument, NULL, 'B' },
+ { "discard", no_argument, NULL, 'D' },
+ { "tier", required_argument, NULL, 't' },
+ { "force", no_argument, NULL, 'f' },
+ { NULL }
+};
+
int cmd_device_add(int argc, char *argv[])
{
- if (argc < 3)
- die("Please supply a filesystem and at least one device to add");
+ struct format_opts format_opts = format_opts_default();
+ struct dev_opts dev_opts = { 0 };
+ bool force = false;
+ int opt;
- struct bcache_handle fs = bcache_fs_open(argv[1]);
+ while ((opt = getopt_long(argc, argv, "t:fh",
+ device_add_opts, NULL)) != -1)
+ switch (opt) {
+ case 'S':
+ if (bch_strtoull_h(optarg, &dev_opts.size))
+ die("invalid filesystem size");
- for (unsigned i = 2; i < argc; i++) {
- struct bch_ioctl_disk_add ia = {
- .dev = (__u64) argv[i],
- };
+ dev_opts.size >>= 9;
+ break;
+ case 'B':
+ dev_opts.bucket_size =
+ hatoi_validate(optarg, "bucket size");
+ break;
+ case 'D':
+ dev_opts.discard = true;
+ break;
+ case 't':
+ if (kstrtouint(optarg, 10, &dev_opts.tier) ||
+ dev_opts.tier >= BCH_TIER_MAX)
+ die("invalid tier");
+ break;
+ case 'f':
+ force = true;
+ break;
+ case 'h':
+ device_add_usage();
+ exit(EXIT_SUCCESS);
+ }
- xioctl(fs.ioctl_fd, BCH_IOCTL_DISK_ADD, &ia);
- }
+ if (argc - optind != 2)
+ die("Please supply a filesystem and a device to add");
+
+ struct bcache_handle fs = bcache_fs_open(argv[optind]);
+
+ dev_opts.path = argv[optind + 1];
+ dev_opts.fd = open_for_format(dev_opts.path, force);
+
+ format_opts.block_size =
+ read_file_u64(fs.sysfs_fd, "block_size_bytes") >> 9;
+ format_opts.btree_node_size =
+ read_file_u64(fs.sysfs_fd, "btree_node_size_bytes") >> 9;
+
+ struct bch_sb *sb = bcache_format(format_opts, &dev_opts, 1);
+ free(sb);
+ fsync(dev_opts.fd);
+ close(dev_opts.fd);
+
+ struct bch_ioctl_disk_add ia = {
+ .dev = (__u64) dev_opts.path,
+ };
+
+ xioctl(fs.ioctl_fd, BCH_IOCTL_DISK_ADD, &ia);
return 0;
}