summaryrefslogtreecommitdiff
path: root/cmds-filesystem.c
diff options
context:
space:
mode:
authorAnand Jain <anand.jain@oracle.com>2013-10-24 22:42:56 +0800
committerChris Mason <clm@fb.com>2014-01-31 08:21:58 -0800
commita156b967ed9bd606afa8dc402451abcf07226c17 (patch)
tree9c9ba9e8c9dc6c3b8125cac05b8a0f5567196f07 /cmds-filesystem.c
parentf1332a2ebc2ab0ce5efc1e785041aa4e6afb8fbf (diff)
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>
Diffstat (limited to 'cmds-filesystem.c')
-rw-r--r--cmds-filesystem.c120
1 files changed, 73 insertions, 47 deletions
diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index 1c1926bd..ef426d30 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|<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)