diff mbox

[1/4] btrfs-progs: make filesystem show by label work

Message ID 1383536745-4635-1-git-send-email-anand.jain@oracle.com (mailing list archive)
State Accepted, archived
Headers show

Commit Message

Anand Jain Nov. 4, 2013, 3:45 a.m. UTC
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>
---
 cmds-filesystem.c |  120 ++++++++++++++++++++++++++++++++---------------------
 1 files changed, 73 insertions(+), 47 deletions(-)
diff mbox

Patch

diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index d08007e..d2cad81 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -179,6 +179,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];
@@ -275,16 +295,18 @@  static int print_one_fs(struct btrfs_ioctl_fs_info_args *fs_info,
 	struct btrfs_ioctl_dev_info_args *tmp_dev_info;
 
 	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),
@@ -308,7 +330,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)
@@ -320,7 +342,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;
@@ -328,23 +350,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;
@@ -353,38 +371,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 > 0 && !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 > 0)
 			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>|<device>]",
+	"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",
@@ -402,6 +418,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;
@@ -426,24 +443,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;
+			}
 		}
 	}
 
@@ -451,7 +475,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)