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;
}
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|<path>|<uuid>]",
"btrfs filesystem show [options] [<path>|<uuid>|<device>|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)