From 21eae342c815c56a843b0b2f5b0cbeee919d0a7c Mon Sep 17 00:00:00 2001 From: Anand Jain Date: Nov 27 2013 15:59:37 +0000 Subject: btrfs-progs: make filesystem show by label work with design revamp around filesystem show the fsid filter by label wasn't planned. but apparently that seemed to be necessary. this patch will fix it. Signed-off-by: Anand Jain Signed-off-by: David Sterba --- diff --git a/cmds-filesystem.c b/cmds-filesystem.c index 1c1926b..ef426d3 100644 --- a/cmds-filesystem.c +++ b/cmds-filesystem.c @@ -248,6 +248,26 @@ static int cmd_df(int argc, char **argv) return !!ret; } +static int match_search_item_kernel(__u8 *fsid, char *mnt, char *label, + char *search) +{ + char uuidbuf[37]; + int search_len = strlen(search); + + search_len = min(search_len, 37); + uuid_unparse(fsid, uuidbuf); + if (!strncmp(uuidbuf, search, search_len)) + return 1; + + if (strlen(label) && strcmp(label, search) == 0) + return 1; + + if (strcmp(mnt, search) == 0) + return 1; + + return 0; +} + static int uuid_search(struct btrfs_fs_devices *fs_devices, char *search) { char uuidbuf[37]; @@ -354,16 +374,18 @@ static int print_one_fs(struct btrfs_ioctl_fs_info_args *fs_info, return ret; uuid_unparse(fs_info->fsid, uuidbuf); - printf("Label: %s uuid: %s\n", - strlen(label) ? label : "none", uuidbuf); + if (label && strlen(label)) + printf("Label: '%s' ", label); + else + printf("Label: none "); - printf("\tTotal devices %llu FS bytes used %s\n", - fs_info->num_devices, + printf(" uuid: %s\n\tTotal devices %llu FS bytes used %s\n", uuidbuf, + fs_info->num_devices, pretty_size(calc_used_bytes(space_info))); for (i = 0; i < fs_info->num_devices; i++) { tmp_dev_info = (struct btrfs_ioctl_dev_info_args *)&dev_info[i]; - printf("\tdevid %llu size %s used %s path %s\n", + printf("\tdevid %4llu size %s used %s path %s\n", tmp_dev_info->devid, pretty_size(tmp_dev_info->total_bytes), pretty_size(tmp_dev_info->bytes_used), @@ -387,7 +409,7 @@ static int check_arg_type(char *input) char path[PATH_MAX]; if (!input) - return BTRFS_ARG_UNKNOWN; + return -EINVAL; if (realpath(input, path)) { if (is_block_device(input) == 1) @@ -399,7 +421,7 @@ static int check_arg_type(char *input) return BTRFS_ARG_UNKNOWN; } - if (!uuid_parse(input, out)) + if (strlen(input) == 36 && !uuid_parse(input, out)) return BTRFS_ARG_UUID; return BTRFS_ARG_UNKNOWN; @@ -407,23 +429,19 @@ static int check_arg_type(char *input) static int btrfs_scan_kernel(void *search) { - int ret = 0, fd, type; + int ret = 0, fd; FILE *f; struct mntent *mnt; struct btrfs_ioctl_fs_info_args fs_info_arg; struct btrfs_ioctl_dev_info_args *dev_info_arg = NULL; struct btrfs_ioctl_space_args *space_info_arg; char label[BTRFS_LABEL_SIZE]; - uuid_t uuid; f = setmntent("/proc/self/mounts", "r"); if (f == NULL) return 1; - type = check_arg_type(search); - if (type == BTRFS_ARG_BLKDEV) - return 1; - + memset(label, 0, sizeof(label)); while ((mnt = getmntent(f)) != NULL) { if (strcmp(mnt->mnt_type, "btrfs")) continue; @@ -432,38 +450,36 @@ static int btrfs_scan_kernel(void *search) if (ret) return ret; - switch (type) { - case BTRFS_ARG_UUID: - ret = uuid_parse(search, uuid); - if (ret) - return 1; - if (uuid_compare(fs_info_arg.fsid, uuid)) - continue; - break; - case BTRFS_ARG_MNTPOINT: - if (strcmp(search, mnt->mnt_dir)) - continue; - break; - case BTRFS_ARG_UNKNOWN: - break; + if (get_label_mounted(mnt->mnt_dir, label)) { + kfree(dev_info_arg); + return 1; + } + if (search && !match_search_item_kernel(fs_info_arg.fsid, + mnt->mnt_dir, label, search)) { + kfree(dev_info_arg); + continue; } fd = open(mnt->mnt_dir, O_RDONLY); if ((fd != -1) && !get_df(fd, &space_info_arg)) { - get_label_mounted(mnt->mnt_dir, label); print_one_fs(&fs_info_arg, dev_info_arg, space_info_arg, label, mnt->mnt_dir); - free(space_info_arg); + kfree(space_info_arg); + memset(label, 0, sizeof(label)); } if (fd != -1) close(fd); - free(dev_info_arg); + kfree(dev_info_arg); + if (search) + return 0; } - return ret; + if (search) + return 1; + return 0; } static const char * const cmd_show_usage[] = { - "btrfs filesystem show [options||]", + "btrfs filesystem show [options] [|||label]", "Show the structure of a filesystem", "-d|--all-devices show only disks under /dev containing btrfs filesystem", "-m|--mounted show only mounted btrfs", @@ -481,6 +497,7 @@ static int cmd_show(int argc, char **argv) int where = BTRFS_SCAN_LBLKID; int type = 0; char mp[BTRFS_PATH_NAME_MAX + 1]; + char path[PATH_MAX]; while (1) { int long_index; @@ -505,24 +522,31 @@ static int cmd_show(int argc, char **argv) } } - if (where == BTRFS_SCAN_LBLKID) { - if (check_argc_max(argc, optind + 1)) - usage(cmd_show_usage); - } else { - if (check_argc_max(argc, optind)) - usage(cmd_show_usage); - } + if (check_argc_max(argc, optind + 1)) + usage(cmd_show_usage); + if (argc > optind) { search = argv[optind]; - type = check_arg_type(search); - if (type == BTRFS_ARG_UNKNOWN) { - fprintf(stderr, "ERROR: arg type unknown\n"); + if (strlen(search) == 0) usage(cmd_show_usage); - } + type = check_arg_type(search); if (type == BTRFS_ARG_BLKDEV) { - ret = get_btrfs_mount(search, mp, sizeof(mp)); - if (ret == 0) - search = mp; + if (where == BTRFS_SCAN_DEV) { + /* we need to do this because + * legacy BTRFS_SCAN_DEV + * provides /dev/dm-x paths + */ + if (realpath(search, path)) + search = path; + } else { + ret = get_btrfs_mount(search, + mp, sizeof(mp)); + if (!ret) + /* given block dev is mounted*/ + search = mp; + else + goto devs_only; + } } } @@ -530,7 +554,9 @@ static int cmd_show(int argc, char **argv) goto devs_only; /* show mounted btrfs */ - btrfs_scan_kernel(search); + ret = btrfs_scan_kernel(search); + if (search && !ret) + return 0; /* shows mounted only */ if (where == BTRFS_SCAN_MOUNTED)