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 <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <clm@fb.com>
master
Anand Jain 2013-10-24 22:42:56 +08:00 committed by Chris Mason
parent f1332a2ebc
commit a156b967ed
1 changed files with 73 additions and 47 deletions

View File

@ -248,6 +248,26 @@ static int cmd_df(int argc, char **argv)
return !!ret; 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) static int uuid_search(struct btrfs_fs_devices *fs_devices, char *search)
{ {
char uuidbuf[37]; char uuidbuf[37];
@ -354,16 +374,18 @@ static int print_one_fs(struct btrfs_ioctl_fs_info_args *fs_info,
return ret; return ret;
uuid_unparse(fs_info->fsid, uuidbuf); uuid_unparse(fs_info->fsid, uuidbuf);
printf("Label: %s uuid: %s\n", if (label && strlen(label))
strlen(label) ? label : "none", uuidbuf); printf("Label: '%s' ", label);
else
printf("Label: none ");
printf("\tTotal devices %llu FS bytes used %s\n", printf(" uuid: %s\n\tTotal devices %llu FS bytes used %s\n", uuidbuf,
fs_info->num_devices, fs_info->num_devices,
pretty_size(calc_used_bytes(space_info))); pretty_size(calc_used_bytes(space_info)));
for (i = 0; i < fs_info->num_devices; i++) { for (i = 0; i < fs_info->num_devices; i++) {
tmp_dev_info = (struct btrfs_ioctl_dev_info_args *)&dev_info[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, tmp_dev_info->devid,
pretty_size(tmp_dev_info->total_bytes), pretty_size(tmp_dev_info->total_bytes),
pretty_size(tmp_dev_info->bytes_used), pretty_size(tmp_dev_info->bytes_used),
@ -387,7 +409,7 @@ static int check_arg_type(char *input)
char path[PATH_MAX]; char path[PATH_MAX];
if (!input) if (!input)
return BTRFS_ARG_UNKNOWN; return -EINVAL;
if (realpath(input, path)) { if (realpath(input, path)) {
if (is_block_device(input) == 1) if (is_block_device(input) == 1)
@ -399,7 +421,7 @@ static int check_arg_type(char *input)
return BTRFS_ARG_UNKNOWN; return BTRFS_ARG_UNKNOWN;
} }
if (!uuid_parse(input, out)) if (strlen(input) == 36 && !uuid_parse(input, out))
return BTRFS_ARG_UUID; return BTRFS_ARG_UUID;
return BTRFS_ARG_UNKNOWN; return BTRFS_ARG_UNKNOWN;
@ -407,23 +429,19 @@ static int check_arg_type(char *input)
static int btrfs_scan_kernel(void *search) static int btrfs_scan_kernel(void *search)
{ {
int ret = 0, fd, type; int ret = 0, fd;
FILE *f; FILE *f;
struct mntent *mnt; struct mntent *mnt;
struct btrfs_ioctl_fs_info_args fs_info_arg; struct btrfs_ioctl_fs_info_args fs_info_arg;
struct btrfs_ioctl_dev_info_args *dev_info_arg = NULL; struct btrfs_ioctl_dev_info_args *dev_info_arg = NULL;
struct btrfs_ioctl_space_args *space_info_arg; struct btrfs_ioctl_space_args *space_info_arg;
char label[BTRFS_LABEL_SIZE]; char label[BTRFS_LABEL_SIZE];
uuid_t uuid;
f = setmntent("/proc/self/mounts", "r"); f = setmntent("/proc/self/mounts", "r");
if (f == NULL) if (f == NULL)
return 1; return 1;
type = check_arg_type(search); memset(label, 0, sizeof(label));
if (type == BTRFS_ARG_BLKDEV)
return 1;
while ((mnt = getmntent(f)) != NULL) { while ((mnt = getmntent(f)) != NULL) {
if (strcmp(mnt->mnt_type, "btrfs")) if (strcmp(mnt->mnt_type, "btrfs"))
continue; continue;
@ -432,38 +450,36 @@ static int btrfs_scan_kernel(void *search)
if (ret) if (ret)
return ret; return ret;
switch (type) { if (get_label_mounted(mnt->mnt_dir, label)) {
case BTRFS_ARG_UUID: kfree(dev_info_arg);
ret = uuid_parse(search, uuid); return 1;
if (ret) }
return 1; if (search && !match_search_item_kernel(fs_info_arg.fsid,
if (uuid_compare(fs_info_arg.fsid, uuid)) mnt->mnt_dir, label, search)) {
continue; kfree(dev_info_arg);
break; continue;
case BTRFS_ARG_MNTPOINT:
if (strcmp(search, mnt->mnt_dir))
continue;
break;
case BTRFS_ARG_UNKNOWN:
break;
} }
fd = open(mnt->mnt_dir, O_RDONLY); fd = open(mnt->mnt_dir, O_RDONLY);
if ((fd != -1) && !get_df(fd, &space_info_arg)) { 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, print_one_fs(&fs_info_arg, dev_info_arg,
space_info_arg, label, mnt->mnt_dir); space_info_arg, label, mnt->mnt_dir);
free(space_info_arg); kfree(space_info_arg);
memset(label, 0, sizeof(label));
} }
if (fd != -1) if (fd != -1)
close(fd); 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[] = { static const char * const cmd_show_usage[] = {
"btrfs filesystem show [options|<path>|<uuid>]", "btrfs filesystem show [options] [<path>|<uuid>|<device>|label]",
"Show the structure of a filesystem", "Show the structure of a filesystem",
"-d|--all-devices show only disks under /dev containing btrfs filesystem", "-d|--all-devices show only disks under /dev containing btrfs filesystem",
"-m|--mounted show only mounted btrfs", "-m|--mounted show only mounted btrfs",
@ -481,6 +497,7 @@ static int cmd_show(int argc, char **argv)
int where = BTRFS_SCAN_LBLKID; int where = BTRFS_SCAN_LBLKID;
int type = 0; int type = 0;
char mp[BTRFS_PATH_NAME_MAX + 1]; char mp[BTRFS_PATH_NAME_MAX + 1];
char path[PATH_MAX];
while (1) { while (1) {
int long_index; 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))
if (check_argc_max(argc, optind + 1)) usage(cmd_show_usage);
usage(cmd_show_usage);
} else {
if (check_argc_max(argc, optind))
usage(cmd_show_usage);
}
if (argc > optind) { if (argc > optind) {
search = argv[optind]; search = argv[optind];
type = check_arg_type(search); if (strlen(search) == 0)
if (type == BTRFS_ARG_UNKNOWN) {
fprintf(stderr, "ERROR: arg type unknown\n");
usage(cmd_show_usage); usage(cmd_show_usage);
} type = check_arg_type(search);
if (type == BTRFS_ARG_BLKDEV) { if (type == BTRFS_ARG_BLKDEV) {
ret = get_btrfs_mount(search, mp, sizeof(mp)); if (where == BTRFS_SCAN_DEV) {
if (ret == 0) /* we need to do this because
search = mp; * 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; goto devs_only;
/* show mounted btrfs */ /* show mounted btrfs */
btrfs_scan_kernel(search); ret = btrfs_scan_kernel(search);
if (search && !ret)
return 0;
/* shows mounted only */ /* shows mounted only */
if (where == BTRFS_SCAN_MOUNTED) if (where == BTRFS_SCAN_MOUNTED)