diff mbox

[7/8] Add btrfs device disk-usage command

Message ID 52FD1AEC.1020700@libero.it (mailing list archive)
State New, archived
Headers show

Commit Message

Goffredo Baroncelli Feb. 13, 2014, 7:20 p.m. UTC
Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
---
 cmds-device.c        |   3 ++
 cmds-fi-disk_usage.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++
 cmds-fi-disk_usage.h |   3 ++
 3 files changed, 142 insertions(+)

Comments

Roman Mamedov Feb. 13, 2014, 7:23 p.m. UTC | #1
On Thu, 13 Feb 2014 20:20:12 +0100
Goffredo Baroncelli <kreijack@libero.it> wrote:

> 
> Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
> ---
>  cmds-device.c        |   3 ++
>  cmds-fi-disk_usage.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  cmds-fi-disk_usage.h |   3 ++
>  3 files changed, 142 insertions(+)
> 
> diff --git a/cmds-device.c b/cmds-device.c
> index bc4a8dc..f25dbfa 100644
> --- a/cmds-device.c
> +++ b/cmds-device.c
> @@ -28,6 +28,7 @@
>  #include "ctree.h"
>  #include "ioctl.h"
>  #include "utils.h"
> +#include "cmds-fi-disk_usage.h"
>  
>  #include "commands.h"
>  
> @@ -401,6 +402,8 @@ const struct cmd_group device_cmd_group = {
>  		{ "scan", cmd_scan_dev, cmd_scan_dev_usage, NULL, 0 },
>  		{ "ready", cmd_ready_dev, cmd_ready_dev_usage, NULL, 0 },
>  		{ "stats", cmd_dev_stats, cmd_dev_stats_usage, NULL, 0 },
> +		{ "disk-usage", cmd_device_disk_usage,
> +			cmd_device_disk_usage_usage, NULL, 0 },
>  		NULL_CMD_STRUCT

Why not just name it "du"? Think about the current handy feature of shortening
commands by only specifying parts of the keywords. "btrfs dev du" would seem
more intuitive than calling it as "btrfs dev disk" or "btrfs dev disk-u".

Or simply "usage", because "...device disk..." is redundant, device is already
a disk, so it can easily be "btrfs device usage".
Goffredo Baroncelli Feb. 13, 2014, 7:44 p.m. UTC | #2
Hi Roman,
On 02/13/2014 08:23 PM, Roman Mamedov wrote:
> On Thu, 13 Feb 2014 20:20:12 +0100
> Goffredo Baroncelli <kreijack@libero.it> wrote:
> 
>>
>> Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
>> ---
[...]

> 
> Why not just name it "du"? Think about the current handy feature of shortening
> commands by only specifying parts of the keywords. "btrfs dev du" would seem
> more intuitive than calling it as "btrfs dev disk" or "btrfs dev disk-u".
> 
> Or simply "usage", because "...device disk..." is redundant, device is already
> a disk, so it can easily be "btrfs device usage".

Yes, I agree about "usage"
GB
diff mbox

Patch

diff --git a/cmds-device.c b/cmds-device.c
index bc4a8dc..f25dbfa 100644
--- a/cmds-device.c
+++ b/cmds-device.c
@@ -28,6 +28,7 @@ 
 #include "ctree.h"
 #include "ioctl.h"
 #include "utils.h"
+#include "cmds-fi-disk_usage.h"
 
 #include "commands.h"
 
@@ -401,6 +402,8 @@  const struct cmd_group device_cmd_group = {
 		{ "scan", cmd_scan_dev, cmd_scan_dev_usage, NULL, 0 },
 		{ "ready", cmd_ready_dev, cmd_ready_dev_usage, NULL, 0 },
 		{ "stats", cmd_dev_stats, cmd_dev_stats_usage, NULL, 0 },
+		{ "disk-usage", cmd_device_disk_usage,
+			cmd_device_disk_usage_usage, NULL, 0 },
 		NULL_CMD_STRUCT
 	}
 };
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
index 16b3ab2..e4eb72b 100644
--- a/cmds-fi-disk_usage.c
+++ b/cmds-fi-disk_usage.c
@@ -942,3 +942,139 @@  int cmd_filesystem_disk_usage(int argc, char **argv)
 
 	return 0;
 }
+
+static void print_disk_chunks(int fd,
+				u64 devid,
+				u64 total_size,
+				struct chunk_info *chunks_info_ptr,
+				int chunks_info_count,
+				int mode)
+{
+	int i;
+	u64 allocated = 0;
+
+	for (i = 0 ; i < chunks_info_count ; i++) {
+		const char *description;
+		const char *r_mode;
+		u64 flags;
+		u64 size;
+
+		if (chunks_info_ptr[i].devid != devid)
+			continue;
+
+		flags = chunks_info_ptr[i].type;
+
+		description = group_type_str(flags);
+		r_mode = group_profile_str(flags);
+		size = calc_chunk_size(chunks_info_ptr+i);
+		printf("   %s,%s:%*s%10s\n",
+			description,
+			r_mode,
+			(int)(20 - strlen(description) - strlen(r_mode)), "",
+			df_pretty_sizes(size, mode));
+
+		allocated += size;
+
+	}
+	printf("   Unallocated: %*s%10s\n",
+		(int)(20 - strlen("Unallocated")), "",
+		df_pretty_sizes(total_size - allocated, mode));
+
+}
+
+static int _cmd_device_disk_usage(int fd, char *path, int mode)
+{
+	int i;
+	int ret = 0;
+	int info_count = 0;
+	struct chunk_info *info_ptr = 0;
+	struct disk_info *disks_info_ptr = 0;
+	int disks_info_count = 0;
+
+	if (load_chunk_info(fd, &info_ptr, &info_count) ||
+	    load_disks_info(fd, &disks_info_ptr, &disks_info_count)) {
+		ret = -1;
+		goto exit;
+	}
+
+	for (i = 0 ; i < disks_info_count ; i++) {
+		printf("%s\t%10s\n", disks_info_ptr[i].path,
+			df_pretty_sizes(disks_info_ptr[i].size, mode));
+
+		print_disk_chunks(fd, disks_info_ptr[i].devid,
+				disks_info_ptr[i].size,
+				info_ptr, info_count,
+				mode);
+		printf("\n");
+
+	}
+
+
+exit:
+
+	if (disks_info_ptr)
+		free(disks_info_ptr);
+	if (info_ptr)
+		free(info_ptr);
+
+	return ret;
+}
+
+const char * const cmd_device_disk_usage_usage[] = {
+	"btrfs device disk-usage [-b] <path> [<path>..]",
+	"Show which chunks are in a device.",
+	"",
+	"-b\tSet byte as unit",
+	NULL
+};
+
+int cmd_device_disk_usage(int argc, char **argv)
+{
+
+	int	flags = DF_HUMAN_UNIT;
+	int	i, more_than_one = 0;
+
+	optind = 1;
+	while (1) {
+		char	c = getopt(argc, argv, "b");
+
+		if (c < 0)
+			break;
+
+		switch (c) {
+		case 'b':
+			flags &= ~DF_HUMAN_UNIT;
+			break;
+		default:
+			usage(cmd_device_disk_usage_usage);
+		}
+	}
+
+	if (check_argc_min(argc - optind, 1)) {
+		usage(cmd_device_disk_usage_usage);
+		return 21;
+	}
+
+	for (i = optind; i < argc ; i++) {
+		int r, fd;
+		DIR	*dirstream = NULL;
+		if (more_than_one)
+			printf("\n");
+
+		fd = open_file_or_dir(argv[i], &dirstream);
+		if (fd < 0) {
+			fprintf(stderr, "ERROR: can't access to '%s'\n",
+				argv[1]);
+			return 12;
+		}
+		r = _cmd_device_disk_usage(fd, argv[i], flags);
+		close_file_or_dir(fd, dirstream);
+
+		if (r)
+			return r;
+		more_than_one = 1;
+
+	}
+
+	return 0;
+}
diff --git a/cmds-fi-disk_usage.h b/cmds-fi-disk_usage.h
index c7459b1..c315004 100644
--- a/cmds-fi-disk_usage.h
+++ b/cmds-fi-disk_usage.h
@@ -25,4 +25,7 @@  int cmd_filesystem_df(int argc, char **argv);
 extern const char * const cmd_filesystem_disk_usage_usage[];
 int cmd_filesystem_disk_usage(int argc, char **argv);
 
+extern const char * const cmd_device_disk_usage_usage[];
+int cmd_device_disk_usage(int argc, char **argv);
+
 #endif