summaryrefslogtreecommitdiff
path: root/cmds-fi-disk_usage.c
diff options
context:
space:
mode:
authorGoffredo Baroncelli <kreijack@libero.it>2014-02-13 20:20:12 +0100
committerDavid Sterba <dsterba@suse.cz>2014-12-04 16:48:09 +0100
commit330903d4eec6d0d0bf25f7052ee10300d3791d0c (patch)
tree4c737e8cc3dc4fc57223379acf380e768d22ad75 /cmds-fi-disk_usage.c
parent9002666a2b5d826f81dfdfd2051b3472db8d5640 (diff)
btrfs-progs: Add btrfs device disk-usage command
Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it> Signed-off-by: David Sterba <dsterba@suse.cz>
Diffstat (limited to 'cmds-fi-disk_usage.c')
-rw-r--r--cmds-fi-disk_usage.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
index 25cd4ede..5274a732 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 = btrfs_group_type_str(flags);
+ r_mode = btrfs_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;
+}