X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=cmds-device.c;h=a939c56f05b522efd711b5516a6bf7369c6a6f51;hb=dad817d3bad44619c355d11e39512b413da6939c;hp=3f800e6d73eea4be12cebf3a6a7154fa80a76f96;hpb=358807cc33fb3ed50ddf782e5b32f6e3cc2fa329;p=platform%2Fupstream%2Fbtrfs-progs.git diff --git a/cmds-device.c b/cmds-device.c index 3f800e6..a939c56 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -107,8 +107,9 @@ static int cmd_device_add(int argc, char **argv) continue; } - res = btrfs_prepare_device(devfd, argv[i], 1, &dev_block_count, - 0, discard); + res = btrfs_prepare_device(devfd, argv[i], &dev_block_count, 0, + PREP_DEVICE_ZERO_END | PREP_DEVICE_VERBOSE | + (discard ? PREP_DEVICE_DISCARD : 0)); close(devfd); if (res) { ret++; @@ -159,20 +160,46 @@ static int _cmd_device_remove(int argc, char **argv, for(i = optind; i < argc - 1; i++) { struct btrfs_ioctl_vol_args arg; + struct btrfs_ioctl_vol_args_v2 argv2 = {0}; + int is_devid = 0; int res; - if (is_block_device(argv[i]) != 1 && strcmp(argv[i], "missing")) { + if (string_is_numerical(argv[i])) { + argv2.devid = arg_strtou64(argv[i]); + argv2.flags = BTRFS_DEVICE_SPEC_BY_ID; + is_devid = 1; + } else if (is_block_device(argv[i]) == 1 || + strcmp(argv[i], "missing") == 0) { + strncpy_null(argv2.name, argv[i]); + } else { error("not a block device: %s", argv[i]); ret++; continue; } - memset(&arg, 0, sizeof(arg)); - strncpy_null(arg.name, argv[i]); + /* * Positive values are from BTRFS_ERROR_DEV_*, * otherwise it's a generic error, one of errnos */ - res = ioctl(fdmnt, BTRFS_IOC_RM_DEV, &arg); + res = ioctl(fdmnt, BTRFS_IOC_RM_DEV_V2, &argv2); + + /* + * If BTRFS_IOC_RM_DEV_V2 is not supported we get ENOTTY and if + * argv2.flags includes a flag which kernel doesn't understand then + * we shall get EOPNOTSUPP + */ + if (res < 0 && (errno == ENOTTY || errno == EOPNOTSUPP)) { + if (is_devid) { + error("device delete by id failed: %s", + strerror(errno)); + ret++; + continue; + } + memset(&arg, 0, sizeof(arg)); + strncpy_null(arg.name, argv[i]); + res = ioctl(fdmnt, BTRFS_IOC_RM_DEV, &arg); + } + if (res) { const char *msg; @@ -180,8 +207,13 @@ static int _cmd_device_remove(int argc, char **argv, msg = btrfs_err_str(res); else msg = strerror(errno); - error("error removing device '%s': %s", - argv[i], msg); + if (is_devid) { + error("error removing devid %llu: %s", + (unsigned long long)argv2.devid, msg); + } else { + error("error removing device '%s': %s", + argv[i], msg); + } ret++; } } @@ -191,7 +223,7 @@ static int _cmd_device_remove(int argc, char **argv, } static const char * const cmd_device_remove_usage[] = { - "btrfs device remove [...] ", + "btrfs device remove | [|...] ", "Remove a device from a filesystem", NULL }; @@ -202,7 +234,7 @@ static int cmd_device_remove(int argc, char **argv) } static const char * const cmd_device_delete_usage[] = { - "btrfs device delete [...] ", + "btrfs device delete | [|...] ", "Remove a device from a filesystem", NULL }; @@ -222,11 +254,10 @@ static const char * const cmd_device_scan_usage[] = { static int cmd_device_scan(int argc, char **argv) { int i; - int devstart = 1; + int devstart; int all = 0; int ret = 0; - optind = 1; while (1) { int c; static const struct option long_options[] = { @@ -245,16 +276,17 @@ static int cmd_device_scan(int argc, char **argv) usage(cmd_device_scan_usage); } } + devstart = optind; if (all && check_argc_max(argc - optind, 1)) usage(cmd_device_scan_usage); - if (all || argc - optind == 1) { + if (all || argc - optind == 0) { printf("Scanning for Btrfs filesystems\n"); ret = btrfs_scan_lblkid(); error_on(ret, "error %d while scanning", ret); ret = btrfs_register_all_devices(); - error_on(ret, "error %d while registering devices", ret); + error_on(ret, "there are %d errors while registering devices", ret); goto out; } @@ -301,7 +333,7 @@ static int cmd_device_ready(int argc, char **argv) clean_args_no_options(argc, argv, cmd_device_ready_usage); - if (check_argc_min(argc - optind, 1)) + if (check_argc_exact(argc - optind, 1)) usage(cmd_device_ready_usage); fd = open("/dev/btrfs-control", O_RDWR); @@ -360,7 +392,6 @@ static int cmd_device_stats(int argc, char **argv) __u64 flags = 0; DIR *dirstream = NULL; - optind = 1; while ((c = getopt(argc, argv, "z")) != -1) { switch (c) { case 'z': @@ -415,6 +446,17 @@ static int cmd_device_stats(int argc, char **argv) canonical_path = canonicalize_path((char *)path); + /* No path when device is missing. */ + if (!canonical_path) { + canonical_path = malloc(32); + if (!canonical_path) { + error("not enough memory for path buffer"); + goto out; + } + snprintf(canonical_path, 32, + "devid:%llu", args.devid); + } + if (args.nr_items >= BTRFS_DEV_STAT_WRITE_ERRS + 1) printf("[%s].write_io_errs %llu\n", canonical_path,