btrfs-progs: alias btrfs device delete to btrfs device remove
[platform/upstream/btrfs-progs.git] / cmds-device.c
index 197f9d5..0e60500 100644 (file)
@@ -28,7 +28,7 @@
 #include "ctree.h"
 #include "ioctl.h"
 #include "utils.h"
-#include "cmds-fi-disk_usage.h"
+#include "cmds-fi-usage.h"
 
 #include "commands.h"
 
@@ -52,17 +52,16 @@ static int cmd_add_dev(int argc, char **argv)
        DIR     *dirstream = NULL;
        int discard = 1;
        int force = 0;
-       char estr[100];
 
        while (1) {
-               int long_index;
-               static struct option long_options[] = {
+               int c;
+               static const struct option long_options[] = {
                        { "nodiscard", optional_argument, NULL, 'K'},
                        { "force", no_argument, NULL, 'f'},
-                       { 0, 0, 0, 0 }
+                       { NULL, 0, NULL, 0}
                };
-               int c = getopt_long(argc, argv, "Kf", long_options,
-                                       &long_index);
+
+               c = getopt_long(argc, argv, "Kf", long_options, NULL);
                if (c < 0)
                        break;
                switch (c) {
@@ -97,9 +96,8 @@ static int cmd_add_dev(int argc, char **argv)
                int mixed = 0;
                char *path;
 
-               res = test_dev_for_mkfs(argv[i], force, estr);
+               res = test_dev_for_mkfs(argv[i], force);
                if (res) {
-                       fprintf(stderr, "%s", estr);
                        ret++;
                        continue;
                }
@@ -128,6 +126,7 @@ static int cmd_add_dev(int argc, char **argv)
                        goto error_out;
                }
 
+               memset(&ioctl_args, 0, sizeof(ioctl_args));
                strncpy_null(ioctl_args.name, path);
                res = ioctl(fdmnt, BTRFS_IOC_ADD_DEV, &ioctl_args);
                e = errno;
@@ -144,20 +143,14 @@ error_out:
        return !!ret;
 }
 
-static const char * const cmd_rm_dev_usage[] = {
-       "btrfs device delete <device> [<device>...] <path>",
-       "Remove a device from a filesystem",
-       NULL
-};
-
-static int cmd_rm_dev(int argc, char **argv)
+static int _cmd_rm_dev(int argc, char **argv, const char * const *usagestr)
 {
        char    *mntpnt;
        int     i, fdmnt, ret=0, e;
        DIR     *dirstream = NULL;
 
        if (check_argc_min(argc, 3))
-               usage(cmd_rm_dev_usage);
+               usage(usagestr);
 
        mntpnt = argv[argc - 1];
 
@@ -177,18 +170,20 @@ static int cmd_rm_dev(int argc, char **argv)
                        ret++;
                        continue;
                }
+               memset(&arg, 0, sizeof(arg));
                strncpy_null(arg.name, argv[i]);
                res = ioctl(fdmnt, BTRFS_IOC_RM_DEV, &arg);
                e = errno;
-               if (res > 0) {
-                       fprintf(stderr,
-                               "ERROR: error removing the device '%s' - %s\n",
-                               argv[i], btrfs_err_str(res));
-                       ret++;
-               } else if (res < 0) {
+               if (res) {
+                       const char *msg;
+
+                       if (res > 0)
+                               msg = btrfs_err_str(res);
+                       else
+                               msg = strerror(e);
                        fprintf(stderr,
                                "ERROR: error removing the device '%s' - %s\n",
-                               argv[i], strerror(e));
+                               argv[i], msg);
                        ret++;
                }
        }
@@ -197,6 +192,28 @@ static int cmd_rm_dev(int argc, char **argv)
        return !!ret;
 }
 
+static const char * const cmd_rm_dev_usage[] = {
+       "btrfs device remove <device> [<device>...] <path>",
+       "Remove a device from a filesystem",
+       NULL
+};
+
+static int cmd_rm_dev(int argc, char **argv)
+{
+       return _cmd_rm_dev(argc, argv, cmd_rm_dev_usage);
+}
+
+static const char * const cmd_del_dev_usage[] = {
+       "btrfs device delete <device> [<device>...] <path>",
+       "Remove a device from a filesystem",
+       NULL
+};
+
+static int cmd_del_dev(int argc, char **argv)
+{
+       return _cmd_rm_dev(argc, argv, cmd_del_dev_usage);
+}
+
 static const char * const cmd_scan_dev_usage[] = {
        "btrfs device scan [(-d|--all-devices)|<device> [<device>...]]",
        "Scan devices for a btrfs filesystem",
@@ -213,13 +230,13 @@ static int cmd_scan_dev(int argc, char **argv)
 
        optind = 1;
        while (1) {
-               int long_index;
-               static struct option long_options[] = {
+               int c;
+               static const struct option long_options[] = {
                        { "all-devices", no_argument, NULL, 'd'},
-                       { 0, 0, 0, 0 },
+                       { NULL, 0, NULL, 0}
                };
-               int c = getopt_long(argc, argv, "d", long_options,
-                                   &long_index);
+
+               c = getopt_long(argc, argv, "d", long_options, NULL);
                if (c < 0)
                        break;
                switch (c) {
@@ -313,7 +330,8 @@ static int cmd_ready_dev(int argc, char **argv)
                goto out;
        }
 
-       strncpy(args.name, path, BTRFS_PATH_NAME_MAX);
+       memset(&args, 0, sizeof(args));
+       strncpy_null(args.name, path);
        ret = ioctl(fd, BTRFS_IOC_DEVICES_READY, &args);
        if (ret < 0) {
                fprintf(stderr, "ERROR: unable to determine if the device '%s'"
@@ -451,62 +469,103 @@ out:
 }
 
 const char * const cmd_device_usage_usage[] = {
-       "btrfs device usage [-b] <path> [<path>..]",
-       "Show which chunks are in a device.",
-       "",
-       "-b\tSet byte as unit",
+       "btrfs device usage [options] <path> [<path>..]",
+       "Show detailed information about internal allocations in devices.",
+       "-b|--raw           raw numbers in bytes",
+       "-h|--human-readable",
+       "                   human friendly numbers, base 1024 (default)",
+       "-H                 human friendly numbers, base 1000",
+       "--iec              use 1024 as a base (KiB, MiB, GiB, TiB)",
+       "--si               use 1000 as a base (kB, MB, GB, TB)",
+       "-k|--kbytes        show sizes in KiB, or kB with --si",
+       "-m|--mbytes        show sizes in MiB, or MB with --si",
+       "-g|--gbytes        show sizes in GiB, or GB with --si",
+       "-t|--tbytes        show sizes in TiB, or TB with --si",
        NULL
 };
 
-static int _cmd_device_usage(int fd, char *path, int mode)
+static int _cmd_device_usage(int fd, char *path, unsigned unit_mode)
 {
        int i;
        int ret = 0;
-       int info_count = 0;
-       struct chunk_info *info_ptr = 0;
-       struct device_info *device_info_ptr = 0;
-       int device_info_count = 0;
-
-       if (load_chunk_info(fd, &info_ptr, &info_count) ||
-           load_device_info(fd, &device_info_ptr, &device_info_count)) {
-               ret = -1;
-               goto exit;
-       }
+       struct chunk_info *chunkinfo = NULL;
+       struct device_info *devinfo = NULL;
+       int chunkcount = 0;
+       int devcount = 0;
+
+       ret = load_chunk_and_device_info(fd, &chunkinfo, &chunkcount, &devinfo,
+                       &devcount);
+       if (ret)
+               goto out;
 
-       for (i = 0; i < device_info_count; i++) {
-               printf("%s, ID: %llu\n", device_info_ptr[i].path,
-                               device_info_ptr[i].devid);
-               print_device_sizes(fd, &device_info_ptr[i], mode);
-               print_device_chunks(fd, &device_info_ptr[i],
-                               info_ptr, info_count, mode);
+       for (i = 0; i < devcount; i++) {
+               printf("%s, ID: %llu\n", devinfo[i].path, devinfo[i].devid);
+               print_device_sizes(fd, &devinfo[i], unit_mode);
+               print_device_chunks(fd, &devinfo[i], chunkinfo, chunkcount,
+                               unit_mode);
                printf("\n");
        }
 
-exit:
-       if (device_info_ptr)
-               free(device_info_ptr);
-       if (info_ptr)
-               free(info_ptr);
+out:
+       free(devinfo);
+       free(chunkinfo);
 
        return ret;
 }
 
 int cmd_device_usage(int argc, char **argv)
 {
-
-       int     flags = DF_HUMAN_UNIT;
+       unsigned unit_mode = UNITS_DEFAULT;
+       int ret = 0;
        int     i, more_than_one = 0;
 
        optind = 1;
        while (1) {
-               char    c = getopt(argc, argv, "b");
+               int c;
+               static const struct option long_options[] = {
+                       { "raw", no_argument, NULL, 'b'},
+                       { "kbytes", no_argument, NULL, 'k'},
+                       { "mbytes", no_argument, NULL, 'm'},
+                       { "gbytes", no_argument, NULL, 'g'},
+                       { "tbytes", no_argument, NULL, 't'},
+                       { "si", no_argument, NULL, GETOPT_VAL_SI},
+                       { "iec", no_argument, NULL, GETOPT_VAL_IEC},
+                       { "human-readable", no_argument, NULL,
+                               GETOPT_VAL_HUMAN_READABLE},
+                       { NULL, 0, NULL, 0 }
+               };
 
+               c = getopt_long(argc, argv, "bhHkmgt", long_options, NULL);
                if (c < 0)
                        break;
-
                switch (c) {
                case 'b':
-                       flags &= ~DF_HUMAN_UNIT;
+                       unit_mode = UNITS_RAW;
+                       break;
+               case 'k':
+                       units_set_base(&unit_mode, UNITS_KBYTES);
+                       break;
+               case 'm':
+                       units_set_base(&unit_mode, UNITS_MBYTES);
+                       break;
+               case 'g':
+                       units_set_base(&unit_mode, UNITS_GBYTES);
+                       break;
+               case 't':
+                       units_set_base(&unit_mode, UNITS_TBYTES);
+                       break;
+               case GETOPT_VAL_HUMAN_READABLE:
+               case 'h':
+                       unit_mode = UNITS_HUMAN_BINARY;
+                       break;
+               case 'H':
+                       unit_mode = UNITS_HUMAN_DECIMAL;
+                       break;
+               case GETOPT_VAL_SI:
+                       units_set_mode(&unit_mode, UNITS_DECIMAL);
+                       break;
+               case GETOPT_VAL_IEC:
+                       units_set_mode(&unit_mode, UNITS_BINARY);
                        break;
                default:
                        usage(cmd_device_usage_usage);
@@ -517,33 +576,38 @@ int cmd_device_usage(int argc, char **argv)
                usage(cmd_device_usage_usage);
 
        for (i = optind; i < argc ; i++) {
-               int r, fd;
+               int fd;
                DIR     *dirstream = NULL;
                if (more_than_one)
                        printf("\n");
 
                fd = open_file_or_dir(argv[i], &dirstream);
                if (fd < 0) {
-                       fprintf(stderr, "ERROR: can't access to '%s'\n",
+                       fprintf(stderr, "ERROR: can't access '%s'\n",
                                argv[1]);
-                       return 12;
+                       ret = 1;
+                       goto out;
                }
-               r = _cmd_device_usage(fd, argv[i], flags);
+
+               ret = _cmd_device_usage(fd, argv[i], unit_mode);
                close_file_or_dir(fd, dirstream);
 
-               if (r)
-                       return r;
+               if (ret)
+                       goto out;
                more_than_one = 1;
-
        }
-
-       return 0;
+out:
+       return !!ret;
 }
 
+static const char device_cmd_group_info[] =
+"manage and query devices in the filesystem";
+
 const struct cmd_group device_cmd_group = {
-       device_cmd_group_usage, NULL, {
+       device_cmd_group_usage, device_cmd_group_info, {
                { "add", cmd_add_dev, cmd_add_dev_usage, NULL, 0 },
-               { "delete", cmd_rm_dev, cmd_rm_dev_usage, NULL, 0 },
+               { "delete", cmd_del_dev, cmd_del_dev_usage, NULL, CMD_ALIAS },
+               { "remove", cmd_rm_dev, cmd_rm_dev_usage, NULL, 0 },
                { "scan", cmd_scan_dev, cmd_scan_dev_usage, NULL, 0 },
                { "ready", cmd_ready_dev, cmd_ready_dev_usage, NULL, 0 },
                { "stats", cmd_dev_stats, cmd_dev_stats_usage, NULL, 0 },