Accepting request 266875 from filesystems
1 OBS-URL: https://build.opensuse.org/request/show/266875 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/btrfsprogs?expand=0&rev=51
This commit is contained in:
commit
5a7b47fd82
@ -1,147 +0,0 @@
|
||||
From 86afea330be6179ac88e0fcaf14924e03257b445 Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Thu, 23 Oct 2014 19:05:31 +0200
|
||||
Subject: [PATCH 01/42] btrfs-progs: move group type and profile pretty
|
||||
printers to utils
|
||||
|
||||
Move and add the btrfs_ prefix.
|
||||
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-filesystem.c | 47 ++---------------------------------------------
|
||||
utils.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
utils.h | 2 ++
|
||||
3 files changed, 48 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/cmds-filesystem.c b/cmds-filesystem.c
|
||||
index bb5881edef2d..ffa939c5b89a 100644
|
||||
--- a/cmds-filesystem.c
|
||||
+++ b/cmds-filesystem.c
|
||||
@@ -127,49 +127,6 @@ static const char * const cmd_df_usage[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
-static char *group_type_str(u64 flag)
|
||||
-{
|
||||
- u64 mask = BTRFS_BLOCK_GROUP_TYPE_MASK |
|
||||
- BTRFS_SPACE_INFO_GLOBAL_RSV;
|
||||
-
|
||||
- switch (flag & mask) {
|
||||
- case BTRFS_BLOCK_GROUP_DATA:
|
||||
- return "Data";
|
||||
- case BTRFS_BLOCK_GROUP_SYSTEM:
|
||||
- return "System";
|
||||
- case BTRFS_BLOCK_GROUP_METADATA:
|
||||
- return "Metadata";
|
||||
- case BTRFS_BLOCK_GROUP_DATA|BTRFS_BLOCK_GROUP_METADATA:
|
||||
- return "Data+Metadata";
|
||||
- case BTRFS_SPACE_INFO_GLOBAL_RSV:
|
||||
- return "GlobalReserve";
|
||||
- default:
|
||||
- return "unknown";
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static char *group_profile_str(u64 flag)
|
||||
-{
|
||||
- switch (flag & BTRFS_BLOCK_GROUP_PROFILE_MASK) {
|
||||
- case 0:
|
||||
- return "single";
|
||||
- case BTRFS_BLOCK_GROUP_RAID0:
|
||||
- return "RAID0";
|
||||
- case BTRFS_BLOCK_GROUP_RAID1:
|
||||
- return "RAID1";
|
||||
- case BTRFS_BLOCK_GROUP_RAID5:
|
||||
- return "RAID5";
|
||||
- case BTRFS_BLOCK_GROUP_RAID6:
|
||||
- return "RAID6";
|
||||
- case BTRFS_BLOCK_GROUP_DUP:
|
||||
- return "DUP";
|
||||
- case BTRFS_BLOCK_GROUP_RAID10:
|
||||
- return "RAID10";
|
||||
- default:
|
||||
- return "unknown";
|
||||
- }
|
||||
-}
|
||||
-
|
||||
static int get_df(int fd, struct btrfs_ioctl_space_args **sargs_ret)
|
||||
{
|
||||
u64 count = 0;
|
||||
@@ -225,8 +182,8 @@ static void print_df(struct btrfs_ioctl_space_args *sargs, unsigned unit_mode)
|
||||
|
||||
for (i = 0; i < sargs->total_spaces; i++, sp++) {
|
||||
printf("%s, %s: total=%s, used=%s\n",
|
||||
- group_type_str(sp->flags),
|
||||
- group_profile_str(sp->flags),
|
||||
+ btrfs_group_type_str(sp->flags),
|
||||
+ btrfs_group_profile_str(sp->flags),
|
||||
pretty_size_mode(sp->total_bytes, unit_mode),
|
||||
pretty_size_mode(sp->used_bytes, unit_mode));
|
||||
}
|
||||
diff --git a/utils.c b/utils.c
|
||||
index f10c178bf36e..43b693c94039 100644
|
||||
--- a/utils.c
|
||||
+++ b/utils.c
|
||||
@@ -2431,3 +2431,47 @@ int find_next_key(struct btrfs_path *path, struct btrfs_key *key)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
+
|
||||
+char* btrfs_group_type_str(u64 flag)
|
||||
+{
|
||||
+ u64 mask = BTRFS_BLOCK_GROUP_TYPE_MASK |
|
||||
+ BTRFS_SPACE_INFO_GLOBAL_RSV;
|
||||
+
|
||||
+ switch (flag & mask) {
|
||||
+ case BTRFS_BLOCK_GROUP_DATA:
|
||||
+ return "Data";
|
||||
+ case BTRFS_BLOCK_GROUP_SYSTEM:
|
||||
+ return "System";
|
||||
+ case BTRFS_BLOCK_GROUP_METADATA:
|
||||
+ return "Metadata";
|
||||
+ case BTRFS_BLOCK_GROUP_DATA|BTRFS_BLOCK_GROUP_METADATA:
|
||||
+ return "Data+Metadata";
|
||||
+ case BTRFS_SPACE_INFO_GLOBAL_RSV:
|
||||
+ return "GlobalReserve";
|
||||
+ default:
|
||||
+ return "unknown";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+char* btrfs_group_profile_str(u64 flag)
|
||||
+{
|
||||
+ switch (flag & BTRFS_BLOCK_GROUP_PROFILE_MASK) {
|
||||
+ case 0:
|
||||
+ return "single";
|
||||
+ case BTRFS_BLOCK_GROUP_RAID0:
|
||||
+ return "RAID0";
|
||||
+ case BTRFS_BLOCK_GROUP_RAID1:
|
||||
+ return "RAID1";
|
||||
+ case BTRFS_BLOCK_GROUP_RAID5:
|
||||
+ return "RAID5";
|
||||
+ case BTRFS_BLOCK_GROUP_RAID6:
|
||||
+ return "RAID6";
|
||||
+ case BTRFS_BLOCK_GROUP_DUP:
|
||||
+ return "DUP";
|
||||
+ case BTRFS_BLOCK_GROUP_RAID10:
|
||||
+ return "RAID10";
|
||||
+ default:
|
||||
+ return "unknown";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
diff --git a/utils.h b/utils.h
|
||||
index 7accbd20382c..0d202f6344c4 100644
|
||||
--- a/utils.h
|
||||
+++ b/utils.h
|
||||
@@ -159,5 +159,7 @@ static inline u64 btrfs_min_dev_size(u32 leafsize)
|
||||
}
|
||||
|
||||
int find_next_key(struct btrfs_path *path, struct btrfs_key *key);
|
||||
+char* btrfs_group_type_str(u64 flag);
|
||||
+char* btrfs_group_profile_str(u64 flag);
|
||||
|
||||
#endif
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,696 +0,0 @@
|
||||
From 8296d5dae853ada256834975148678125e51af6e Mon Sep 17 00:00:00 2001
|
||||
From: Goffredo Baroncelli <kreijack@libero.it>
|
||||
Date: Thu, 13 Feb 2014 20:19:01 +0100
|
||||
Subject: [PATCH 02/42] btrfs-progs: Enhance the command btrfs filesystem df
|
||||
|
||||
Enhance the command "btrfs filesystem df" to show space usage information
|
||||
for a mount point(s). It shows also an estimation of the space available,
|
||||
on the basis of the current one used.
|
||||
|
||||
Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
|
||||
[code moved under #if 0 instead of deletion]
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
Makefile | 2 +-
|
||||
cmds-fi-disk_usage.c | 516 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
cmds-fi-disk_usage.h | 25 +++
|
||||
cmds-filesystem.c | 7 +-
|
||||
ctree.h | 5 +-
|
||||
utils.c | 11 ++
|
||||
utils.h | 1 +
|
||||
7 files changed, 563 insertions(+), 4 deletions(-)
|
||||
create mode 100644 cmds-fi-disk_usage.c
|
||||
create mode 100644 cmds-fi-disk_usage.h
|
||||
|
||||
Index: btrfs-progs-v3.17.1/Makefile
|
||||
===================================================================
|
||||
--- btrfs-progs-v3.17.1.orig/Makefile
|
||||
+++ btrfs-progs-v3.17.1/Makefile
|
||||
@@ -15,7 +15,7 @@ cmds_objects = cmds-subvolume.o cmds-fil
|
||||
cmds-inspect.o cmds-balance.o cmds-send.o cmds-receive.o \
|
||||
cmds-quota.o cmds-qgroup.o cmds-replace.o cmds-check.o \
|
||||
cmds-restore.o cmds-rescue.o chunk-recover.o super-recover.o \
|
||||
- cmds-property.o
|
||||
+ cmds-property.o cmds-fi-disk_usage.o
|
||||
libbtrfs_objects = send-stream.o send-utils.o rbtree.o btrfs-list.o crc32c.o \
|
||||
uuid-tree.o utils-lib.o rbtree-utils.o
|
||||
libbtrfs_headers = send-stream.h send-utils.h send.h rbtree.h btrfs-list.h \
|
||||
Index: btrfs-progs-v3.17.1/cmds-fi-disk_usage.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ btrfs-progs-v3.17.1/cmds-fi-disk_usage.c
|
||||
@@ -0,0 +1,516 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public
|
||||
+ * License v2 as published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public
|
||||
+ * License along with this program; if not, write to the
|
||||
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
+ * Boston, MA 021110-1307, USA.
|
||||
+ */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <unistd.h>
|
||||
+#include <sys/ioctl.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#include "utils.h"
|
||||
+#include "kerncompat.h"
|
||||
+#include "ctree.h"
|
||||
+
|
||||
+#include "commands.h"
|
||||
+
|
||||
+#include "version.h"
|
||||
+
|
||||
+#define DF_HUMAN_UNIT (1<<0)
|
||||
+
|
||||
+/*
|
||||
+ * To store the size information about the chunks:
|
||||
+ * the chunks info are grouped by the tuple (type, devid, num_stripes),
|
||||
+ * i.e. if two chunks are of the same type (RAID1, DUP...), are on the
|
||||
+ * same disk, have the same stripes then their sizes are grouped
|
||||
+ */
|
||||
+struct chunk_info {
|
||||
+ u64 type;
|
||||
+ u64 size;
|
||||
+ u64 devid;
|
||||
+ u64 num_stripes;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Pretty print the size
|
||||
+ * PAY ATTENTION: it return a statically buffer
|
||||
+ */
|
||||
+static char *df_pretty_sizes(u64 size, int mode)
|
||||
+{
|
||||
+ static char buf[30];
|
||||
+
|
||||
+ if (mode & DF_HUMAN_UNIT)
|
||||
+ (void)pretty_size_snprintf(size, buf, sizeof(buf), UNITS_DEFAULT);
|
||||
+ else
|
||||
+ sprintf(buf, "%llu", size);
|
||||
+
|
||||
+ return buf;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Add the chunk info to the chunk_info list
|
||||
+ */
|
||||
+static int add_info_to_list(struct chunk_info **info_ptr,
|
||||
+ int *info_count,
|
||||
+ struct btrfs_chunk *chunk)
|
||||
+{
|
||||
+
|
||||
+ u64 type = btrfs_stack_chunk_type(chunk);
|
||||
+ u64 size = btrfs_stack_chunk_length(chunk);
|
||||
+ int num_stripes = btrfs_stack_chunk_num_stripes(chunk);
|
||||
+ int j;
|
||||
+
|
||||
+ for (j = 0 ; j < num_stripes ; j++) {
|
||||
+ int i;
|
||||
+ struct chunk_info *p = 0;
|
||||
+ struct btrfs_stripe *stripe;
|
||||
+ u64 devid;
|
||||
+
|
||||
+ stripe = btrfs_stripe_nr(chunk, j);
|
||||
+ devid = btrfs_stack_stripe_devid(stripe);
|
||||
+
|
||||
+ for (i = 0 ; i < *info_count ; i++)
|
||||
+ if ((*info_ptr)[i].type == type &&
|
||||
+ (*info_ptr)[i].devid == devid &&
|
||||
+ (*info_ptr)[i].num_stripes == num_stripes ) {
|
||||
+ p = (*info_ptr) + i;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!p) {
|
||||
+ int size = sizeof(struct btrfs_chunk) * (*info_count+1);
|
||||
+ struct chunk_info *res = realloc(*info_ptr, size);
|
||||
+
|
||||
+ if (!res) {
|
||||
+ fprintf(stderr, "ERROR: not enough memory\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ *info_ptr = res;
|
||||
+ p = res + *info_count;
|
||||
+ (*info_count)++;
|
||||
+
|
||||
+ p->devid = devid;
|
||||
+ p->type = type;
|
||||
+ p->size = 0;
|
||||
+ p->num_stripes = num_stripes;
|
||||
+ }
|
||||
+
|
||||
+ p->size += size;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Helper to sort the chunk type
|
||||
+ */
|
||||
+static int cmp_chunk_block_group(u64 f1, u64 f2)
|
||||
+{
|
||||
+
|
||||
+ u64 mask;
|
||||
+
|
||||
+ if ((f1 & BTRFS_BLOCK_GROUP_TYPE_MASK) ==
|
||||
+ (f2 & BTRFS_BLOCK_GROUP_TYPE_MASK))
|
||||
+ mask = BTRFS_BLOCK_GROUP_PROFILE_MASK;
|
||||
+ else if (f2 & BTRFS_BLOCK_GROUP_SYSTEM)
|
||||
+ return -1;
|
||||
+ else if (f1 & BTRFS_BLOCK_GROUP_SYSTEM)
|
||||
+ return +1;
|
||||
+ else
|
||||
+ mask = BTRFS_BLOCK_GROUP_TYPE_MASK;
|
||||
+
|
||||
+ if ((f1 & mask) > (f2 & mask))
|
||||
+ return +1;
|
||||
+ else if ((f1 & mask) < (f2 & mask))
|
||||
+ return -1;
|
||||
+ else
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Helper to sort the chunk
|
||||
+ */
|
||||
+static int cmp_chunk_info(const void *a, const void *b)
|
||||
+{
|
||||
+ return cmp_chunk_block_group(
|
||||
+ ((struct chunk_info *)a)->type,
|
||||
+ ((struct chunk_info *)b)->type);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function load all the chunk info from the 'fd' filesystem
|
||||
+ */
|
||||
+static int load_chunk_info(int fd,
|
||||
+ struct chunk_info **info_ptr,
|
||||
+ int *info_count)
|
||||
+{
|
||||
+
|
||||
+ int ret;
|
||||
+ struct btrfs_ioctl_search_args args;
|
||||
+ struct btrfs_ioctl_search_key *sk = &args.key;
|
||||
+ struct btrfs_ioctl_search_header *sh;
|
||||
+ unsigned long off = 0;
|
||||
+ int i, e;
|
||||
+
|
||||
+
|
||||
+ memset(&args, 0, sizeof(args));
|
||||
+
|
||||
+ /*
|
||||
+ * there may be more than one ROOT_ITEM key if there are
|
||||
+ * snapshots pending deletion, we have to loop through
|
||||
+ * them.
|
||||
+ */
|
||||
+
|
||||
+
|
||||
+ sk->tree_id = BTRFS_CHUNK_TREE_OBJECTID;
|
||||
+
|
||||
+ sk->min_objectid = 0;
|
||||
+ sk->max_objectid = (u64)-1;
|
||||
+ sk->max_type = 0;
|
||||
+ sk->min_type = (u8)-1;
|
||||
+ sk->min_offset = 0;
|
||||
+ sk->max_offset = (u64)-1;
|
||||
+ sk->min_transid = 0;
|
||||
+ sk->max_transid = (u64)-1;
|
||||
+ sk->nr_items = 4096;
|
||||
+
|
||||
+ while (1) {
|
||||
+ ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
|
||||
+ e = errno;
|
||||
+ if (ret < 0) {
|
||||
+ fprintf(stderr,
|
||||
+ "ERROR: can't perform the search - %s\n",
|
||||
+ strerror(e));
|
||||
+ return -99;
|
||||
+ }
|
||||
+ /* the ioctl returns the number of item it found in nr_items */
|
||||
+
|
||||
+ if (sk->nr_items == 0)
|
||||
+ break;
|
||||
+
|
||||
+ off = 0;
|
||||
+ for (i = 0; i < sk->nr_items; i++) {
|
||||
+ struct btrfs_chunk *item;
|
||||
+ sh = (struct btrfs_ioctl_search_header *)(args.buf +
|
||||
+ off);
|
||||
+
|
||||
+ off += sizeof(*sh);
|
||||
+ item = (struct btrfs_chunk *)(args.buf + off);
|
||||
+
|
||||
+ if (add_info_to_list(info_ptr, info_count, item)) {
|
||||
+ *info_ptr = 0;
|
||||
+ free(*info_ptr);
|
||||
+ return -100;
|
||||
+ }
|
||||
+
|
||||
+ off += sh->len;
|
||||
+
|
||||
+ sk->min_objectid = sh->objectid;
|
||||
+ sk->min_type = sh->type;
|
||||
+ sk->min_offset = sh->offset+1;
|
||||
+
|
||||
+ }
|
||||
+ if (!sk->min_offset) /* overflow */
|
||||
+ sk->min_type++;
|
||||
+ else
|
||||
+ continue;
|
||||
+
|
||||
+ if (!sk->min_type)
|
||||
+ sk->min_objectid++;
|
||||
+ else
|
||||
+ continue;
|
||||
+
|
||||
+ if (!sk->min_objectid)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ qsort(*info_ptr, *info_count, sizeof(struct chunk_info),
|
||||
+ cmp_chunk_info);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Helper to sort the struct btrfs_ioctl_space_info
|
||||
+ */
|
||||
+static int cmp_btrfs_ioctl_space_info(const void *a, const void *b)
|
||||
+{
|
||||
+ return cmp_chunk_block_group(
|
||||
+ ((struct btrfs_ioctl_space_info *)a)->flags,
|
||||
+ ((struct btrfs_ioctl_space_info *)b)->flags);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function load all the information about the space usage
|
||||
+ */
|
||||
+static struct btrfs_ioctl_space_args *load_space_info(int fd, char *path)
|
||||
+{
|
||||
+ struct btrfs_ioctl_space_args *sargs = 0, *sargs_orig = 0;
|
||||
+ int e, ret, count;
|
||||
+
|
||||
+ sargs_orig = sargs = malloc(sizeof(struct btrfs_ioctl_space_args));
|
||||
+ if (!sargs) {
|
||||
+ fprintf(stderr, "ERROR: not enough memory\n");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ sargs->space_slots = 0;
|
||||
+ sargs->total_spaces = 0;
|
||||
+
|
||||
+ ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, sargs);
|
||||
+ e = errno;
|
||||
+ if (ret) {
|
||||
+ fprintf(stderr,
|
||||
+ "ERROR: couldn't get space info on '%s' - %s\n",
|
||||
+ path, strerror(e));
|
||||
+ free(sargs);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if (!sargs->total_spaces) {
|
||||
+ free(sargs);
|
||||
+ printf("No chunks found\n");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ count = sargs->total_spaces;
|
||||
+
|
||||
+ sargs = realloc(sargs, sizeof(struct btrfs_ioctl_space_args) +
|
||||
+ (count * sizeof(struct btrfs_ioctl_space_info)));
|
||||
+ if (!sargs) {
|
||||
+ free(sargs_orig);
|
||||
+ fprintf(stderr, "ERROR: not enough memory\n");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ sargs->space_slots = count;
|
||||
+ sargs->total_spaces = 0;
|
||||
+
|
||||
+ ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, sargs);
|
||||
+ e = errno;
|
||||
+
|
||||
+ if (ret) {
|
||||
+ fprintf(stderr,
|
||||
+ "ERROR: couldn't get space info on '%s' - %s\n",
|
||||
+ path, strerror(e));
|
||||
+ free(sargs);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ qsort(&(sargs->spaces), count, sizeof(struct btrfs_ioctl_space_info),
|
||||
+ cmp_btrfs_ioctl_space_info);
|
||||
+
|
||||
+ return sargs;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function computes the space occuped by a *single* RAID5/RAID6 chunk.
|
||||
+ * The computation is performed on the basis of the number of stripes
|
||||
+ * which compose the chunk, which could be different from the number of disks
|
||||
+ * if a disk is added later.
|
||||
+ */
|
||||
+static int get_raid56_used(int fd, u64 *raid5_used, u64 *raid6_used)
|
||||
+{
|
||||
+ struct chunk_info *info_ptr=0, *p;
|
||||
+ int info_count=0;
|
||||
+ int ret;
|
||||
+
|
||||
+ *raid5_used = *raid6_used =0;
|
||||
+
|
||||
+ ret = load_chunk_info(fd, &info_ptr, &info_count);
|
||||
+ if( ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ for ( p = info_ptr; info_count ; info_count--, p++ ) {
|
||||
+ if (p->type & BTRFS_BLOCK_GROUP_RAID5)
|
||||
+ (*raid5_used) += p->size / (p->num_stripes -1);
|
||||
+ if (p->type & BTRFS_BLOCK_GROUP_RAID6)
|
||||
+ (*raid6_used) += p->size / (p->num_stripes -2);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static int _cmd_disk_free(int fd, char *path, int mode)
|
||||
+{
|
||||
+ struct btrfs_ioctl_space_args *sargs = 0;
|
||||
+ int i;
|
||||
+ int ret = 0;
|
||||
+ int e, width;
|
||||
+ u64 total_disk; /* filesystem size == sum of
|
||||
+ disks sizes */
|
||||
+ u64 total_chunks; /* sum of chunks sizes on disk(s) */
|
||||
+ u64 total_used; /* logical space used */
|
||||
+ u64 total_free; /* logical space un-used */
|
||||
+ double K;
|
||||
+ u64 raid5_used, raid6_used;
|
||||
+
|
||||
+ if ((sargs = load_space_info(fd, path)) == NULL) {
|
||||
+ ret = -1;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ total_disk = disk_size(path);
|
||||
+ e = errno;
|
||||
+ if (total_disk == 0) {
|
||||
+ fprintf(stderr,
|
||||
+ "ERROR: couldn't get space info on '%s' - %s\n",
|
||||
+ path, strerror(e));
|
||||
+
|
||||
+ ret = 19;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ if (get_raid56_used(fd, &raid5_used, &raid6_used) < 0) {
|
||||
+ fprintf(stderr,
|
||||
+ "ERROR: couldn't get space info on '%s'\n",
|
||||
+ path );
|
||||
+ ret = 20;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ total_chunks = total_used = total_free = 0;
|
||||
+
|
||||
+ for (i = 0; i < sargs->total_spaces; i++) {
|
||||
+ float ratio = 1;
|
||||
+ u64 allocated;
|
||||
+ u64 flags = sargs->spaces[i].flags;
|
||||
+
|
||||
+ /*
|
||||
+ * The raid5/raid6 ratio depends by the stripes number
|
||||
+ * used by every chunk. It is computed separately
|
||||
+ */
|
||||
+ if (flags & BTRFS_BLOCK_GROUP_RAID0)
|
||||
+ ratio = 1;
|
||||
+ else if (flags & BTRFS_BLOCK_GROUP_RAID1)
|
||||
+ ratio = 2;
|
||||
+ else if (flags & BTRFS_BLOCK_GROUP_RAID5)
|
||||
+ ratio = 0;
|
||||
+ else if (flags & BTRFS_BLOCK_GROUP_RAID6)
|
||||
+ ratio = 0;
|
||||
+ else if (flags & BTRFS_BLOCK_GROUP_DUP)
|
||||
+ ratio = 2;
|
||||
+ else if (flags & BTRFS_BLOCK_GROUP_RAID10)
|
||||
+ ratio = 2;
|
||||
+ else
|
||||
+ ratio = 1;
|
||||
+
|
||||
+ allocated = sargs->spaces[i].total_bytes * ratio;
|
||||
+
|
||||
+ total_chunks += allocated;
|
||||
+ total_used += sargs->spaces[i].used_bytes;
|
||||
+ total_free += (sargs->spaces[i].total_bytes -
|
||||
+ sargs->spaces[i].used_bytes);
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ /* add the raid5/6 allocated space */
|
||||
+ total_chunks += raid5_used + raid6_used;
|
||||
+
|
||||
+ K = ((double)total_used + (double)total_free) / (double)total_chunks;
|
||||
+
|
||||
+ if (mode & DF_HUMAN_UNIT)
|
||||
+ width = 10;
|
||||
+ else
|
||||
+ width = 18;
|
||||
+
|
||||
+ printf("Disk size:\t\t%*s\n", width,
|
||||
+ df_pretty_sizes(total_disk, mode));
|
||||
+ printf("Disk allocated:\t\t%*s\n", width,
|
||||
+ df_pretty_sizes(total_chunks, mode));
|
||||
+ printf("Disk unallocated:\t%*s\n", width,
|
||||
+ df_pretty_sizes(total_disk-total_chunks, mode));
|
||||
+ printf("Used:\t\t\t%*s\n", width,
|
||||
+ df_pretty_sizes(total_used, mode));
|
||||
+ printf("Free (Estimated):\t%*s\t(",
|
||||
+ width,
|
||||
+ df_pretty_sizes((u64)(K*total_disk-total_used), mode));
|
||||
+ printf("Max: %s, ",
|
||||
+ df_pretty_sizes(total_disk-total_chunks+total_free, mode));
|
||||
+ printf("min: %s)\n",
|
||||
+ df_pretty_sizes((total_disk-total_chunks)/2+total_free, mode));
|
||||
+ printf("Data to disk ratio:\t%*.0f %%\n",
|
||||
+ width-2, K*100);
|
||||
+
|
||||
+exit:
|
||||
+
|
||||
+ if (sargs)
|
||||
+ free(sargs);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+const char * const cmd_filesystem_df_usage[] = {
|
||||
+ "btrfs filesystem df [-b] <path> [<path>..]",
|
||||
+ "Show space usage information for a mount point(s).",
|
||||
+ "",
|
||||
+ "-b\tSet byte as unit",
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+int cmd_filesystem_df(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_filesystem_df_usage);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (check_argc_min(argc - optind, 1)) {
|
||||
+ usage(cmd_filesystem_df_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_disk_free(fd, argv[i], flags);
|
||||
+ close_file_or_dir(fd, dirstream);
|
||||
+
|
||||
+ if (r)
|
||||
+ return r;
|
||||
+ more_than_one = 1;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
Index: btrfs-progs-v3.17.1/cmds-fi-disk_usage.h
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ btrfs-progs-v3.17.1/cmds-fi-disk_usage.h
|
||||
@@ -0,0 +1,25 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2007 Oracle. All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public
|
||||
+ * License v2 as published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public
|
||||
+ * License along with this program; if not, write to the
|
||||
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
+ * Boston, MA 021110-1307, USA.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __CMDS_FI_DISK_USAGE__
|
||||
+#define __CMDS_FI_DISK_USAGE__
|
||||
+
|
||||
+extern const char * const cmd_filesystem_df_usage[];
|
||||
+int cmd_filesystem_df(int argc, char **argv);
|
||||
+
|
||||
+#endif
|
||||
Index: btrfs-progs-v3.17.1/cmds-filesystem.c
|
||||
===================================================================
|
||||
--- btrfs-progs-v3.17.1.orig/cmds-filesystem.c
|
||||
+++ btrfs-progs-v3.17.1/cmds-filesystem.c
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "volumes.h"
|
||||
#include "version.h"
|
||||
#include "commands.h"
|
||||
+#include "cmds-fi-disk_usage.h"
|
||||
#include "list_sort.h"
|
||||
#include "disk-io.h"
|
||||
|
||||
@@ -121,6 +122,7 @@ static const char * const filesystem_cmd
|
||||
NULL
|
||||
};
|
||||
|
||||
+#if 0
|
||||
static const char * const cmd_df_usage[] = {
|
||||
"btrfs filesystem df [options] <path>",
|
||||
"Show space usage information for a mount point",
|
||||
@@ -135,6 +137,7 @@ static const char * const cmd_df_usage[]
|
||||
"-t|--tbytes show sizes in TiB, or TB with --si",
|
||||
NULL
|
||||
};
|
||||
+#endif
|
||||
|
||||
static int get_df(int fd, struct btrfs_ioctl_space_args **sargs_ret)
|
||||
{
|
||||
@@ -184,6 +187,7 @@ static int get_df(int fd, struct btrfs_i
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#if 0
|
||||
static void print_df(struct btrfs_ioctl_space_args *sargs, unsigned unit_mode)
|
||||
{
|
||||
u64 i;
|
||||
@@ -277,6 +281,7 @@ static int cmd_df(int argc, char **argv)
|
||||
close_file_or_dir(fd, dirstream);
|
||||
return !!ret;
|
||||
}
|
||||
+#endif
|
||||
|
||||
static int match_search_item_kernel(__u8 *fsid, char *mnt, char *label,
|
||||
char *search)
|
||||
@@ -1275,7 +1280,7 @@ static int cmd_label(int argc, char **ar
|
||||
|
||||
const struct cmd_group filesystem_cmd_group = {
|
||||
filesystem_cmd_group_usage, NULL, {
|
||||
- { "df", cmd_df, cmd_df_usage, NULL, 0 },
|
||||
+ { "df", cmd_filesystem_df, cmd_filesystem_df_usage, NULL, 0 },
|
||||
{ "show", cmd_show, cmd_show_usage, NULL, 0 },
|
||||
{ "sync", cmd_sync, cmd_sync_usage, NULL, 0 },
|
||||
{ "defragment", cmd_defrag, cmd_defrag_usage, NULL, 0 },
|
||||
Index: btrfs-progs-v3.17.1/ctree.h
|
||||
===================================================================
|
||||
--- btrfs-progs-v3.17.1.orig/ctree.h
|
||||
+++ btrfs-progs-v3.17.1/ctree.h
|
||||
@@ -842,9 +842,10 @@ struct btrfs_csum_item {
|
||||
#define BTRFS_BLOCK_GROUP_RAID1 (1ULL << 4)
|
||||
#define BTRFS_BLOCK_GROUP_DUP (1ULL << 5)
|
||||
#define BTRFS_BLOCK_GROUP_RAID10 (1ULL << 6)
|
||||
-#define BTRFS_BLOCK_GROUP_RAID5 (1ULL << 7)
|
||||
-#define BTRFS_BLOCK_GROUP_RAID6 (1ULL << 8)
|
||||
+#define BTRFS_BLOCK_GROUP_RAID5 (1ULL << 7)
|
||||
+#define BTRFS_BLOCK_GROUP_RAID6 (1ULL << 8)
|
||||
#define BTRFS_BLOCK_GROUP_RESERVED BTRFS_AVAIL_ALLOC_BIT_SINGLE
|
||||
+#define BTRFS_NR_RAID_TYPES 7
|
||||
|
||||
#define BTRFS_BLOCK_GROUP_TYPE_MASK (BTRFS_BLOCK_GROUP_DATA | \
|
||||
BTRFS_BLOCK_GROUP_SYSTEM | \
|
||||
Index: btrfs-progs-v3.17.1/utils.c
|
||||
===================================================================
|
||||
--- btrfs-progs-v3.17.1.orig/utils.c
|
||||
+++ btrfs-progs-v3.17.1/utils.c
|
||||
@@ -38,6 +38,8 @@
|
||||
#include <linux/kdev_t.h>
|
||||
#include <limits.h>
|
||||
#include <blkid/blkid.h>
|
||||
+#include <sys/vfs.h>
|
||||
+
|
||||
#include "kerncompat.h"
|
||||
#include "radix-tree.h"
|
||||
#include "ctree.h"
|
||||
@@ -2493,3 +2495,12 @@ char* btrfs_group_profile_str(u64 flag)
|
||||
}
|
||||
}
|
||||
|
||||
+u64 disk_size(char *path)
|
||||
+{
|
||||
+ struct statfs sfs;
|
||||
+
|
||||
+ if (statfs(path, &sfs) < 0)
|
||||
+ return 0;
|
||||
+ else
|
||||
+ return sfs.f_bsize * sfs.f_blocks;
|
||||
+}
|
||||
Index: btrfs-progs-v3.17.1/utils.h
|
||||
===================================================================
|
||||
--- btrfs-progs-v3.17.1.orig/utils.h
|
||||
+++ btrfs-progs-v3.17.1/utils.h
|
||||
@@ -134,6 +134,7 @@ int find_mount_root(const char *path, ch
|
||||
int get_device_info(int fd, u64 devid,
|
||||
struct btrfs_ioctl_dev_info_args *di_args);
|
||||
int test_uuid_unique(char *fs_uuid);
|
||||
+u64 disk_size(char *path);
|
||||
|
||||
int test_minimum_size(const char *file, u32 leafsize);
|
||||
int test_issubvolname(const char *name);
|
@ -1,256 +0,0 @@
|
||||
From a1faabe2147d3ba59b16ac16dc0862166e2dee15 Mon Sep 17 00:00:00 2001
|
||||
From: Goffredo Baroncelli <kreijack@libero.it>
|
||||
Date: Thu, 13 Feb 2014 20:19:21 +0100
|
||||
Subject: [PATCH 03/42] btrfs-progs: Add helpers functions to handle the
|
||||
printing of data in tabular format
|
||||
|
||||
This patch adds some functions to manage the printing of the data in
|
||||
tabular format.
|
||||
|
||||
The function
|
||||
struct string_table *table_create(int columns, int rows)
|
||||
creates an (empty) table.
|
||||
|
||||
The functions
|
||||
char *table_printf(struct string_table *tab, int column,
|
||||
int row, char *fmt, ...)
|
||||
char *table_vprintf(struct string_table *tab, int column,
|
||||
int row, char *fmt, va_list ap)
|
||||
populate the table with text. To align the text to the left, the text
|
||||
shall be prefixed with '<', otherwise the text shall be prefixed by a
|
||||
'>'. If the first character is a '=', the the text is replace by a
|
||||
sequence of '=' to fill the column width.
|
||||
|
||||
The function
|
||||
void table_free(struct string_table *)
|
||||
frees all the data associated to the table.
|
||||
|
||||
The function
|
||||
void table_dump(struct string_table *tab)
|
||||
prints the table on stdout.
|
||||
|
||||
Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
Makefile | 2 +-
|
||||
string-table.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
string-table.h | 36 +++++++++++++
|
||||
3 files changed, 193 insertions(+), 1 deletion(-)
|
||||
create mode 100644 string-table.c
|
||||
create mode 100644 string-table.h
|
||||
|
||||
Index: btrfs-progs-v3.17.1/Makefile
|
||||
===================================================================
|
||||
--- btrfs-progs-v3.17.1.orig/Makefile
|
||||
+++ btrfs-progs-v3.17.1/Makefile
|
||||
@@ -10,7 +10,7 @@ objects = ctree.o disk-io.o radix-tree.o
|
||||
root-tree.o dir-item.o file-item.o inode-item.o inode-map.o \
|
||||
extent-cache.o extent_io.o volumes.o utils.o repair.o \
|
||||
qgroup.o raid6.o free-space-cache.o list_sort.o props.o \
|
||||
- ulist.o qgroup-verify.o backref.o
|
||||
+ ulist.o qgroup-verify.o backref.o string-table.o
|
||||
cmds_objects = cmds-subvolume.o cmds-filesystem.o cmds-device.o cmds-scrub.o \
|
||||
cmds-inspect.o cmds-balance.o cmds-send.o cmds-receive.o \
|
||||
cmds-quota.o cmds-qgroup.o cmds-replace.o cmds-check.o \
|
||||
Index: btrfs-progs-v3.17.1/string-table.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ btrfs-progs-v3.17.1/string-table.c
|
||||
@@ -0,0 +1,156 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public
|
||||
+ * License v2 as published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public
|
||||
+ * License along with this program; if not, write to the
|
||||
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
+ * Boston, MA 021110-1307, USA.
|
||||
+ */
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdarg.h>
|
||||
+
|
||||
+#include "string-table.h"
|
||||
+
|
||||
+/*
|
||||
+ * This function create an array of char * which will represent a table
|
||||
+ */
|
||||
+struct string_table *table_create(int columns, int rows)
|
||||
+{
|
||||
+ struct string_table *p;
|
||||
+ int size;
|
||||
+
|
||||
+ size = sizeof( struct string_table ) +
|
||||
+ rows * columns* sizeof(char *);
|
||||
+ p = calloc(1, size);
|
||||
+
|
||||
+ if (!p) return NULL;
|
||||
+
|
||||
+ p->ncols = columns;
|
||||
+ p->nrows = rows;
|
||||
+
|
||||
+ return p;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function is like a vprintf, but store the results in a cell of
|
||||
+ * the table.
|
||||
+ * If fmt starts with '<', the text is left aligned; if fmt starts with
|
||||
+ * '>' the text is right aligned. If fmt is equal to '=' the text will
|
||||
+ * be replaced by a '=====' dimensioned on the basis of the column width
|
||||
+ */
|
||||
+char *table_vprintf(struct string_table *tab, int column, int row,
|
||||
+ char *fmt, va_list ap)
|
||||
+{
|
||||
+ int idx = tab->ncols*row+column;
|
||||
+ char *msg = calloc(100, sizeof(char));
|
||||
+
|
||||
+ if (!msg)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (tab->cells[idx])
|
||||
+ free(tab->cells[idx]);
|
||||
+ tab->cells[idx] = msg;
|
||||
+ vsnprintf(msg, 99, fmt, ap);
|
||||
+
|
||||
+ return msg;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * This function is like a printf, but store the results in a cell of
|
||||
+ * the table.
|
||||
+ */
|
||||
+char *table_printf(struct string_table *tab, int column, int row,
|
||||
+ char *fmt, ...)
|
||||
+{
|
||||
+ va_list ap;
|
||||
+ char *ret;
|
||||
+
|
||||
+ va_start(ap, fmt);
|
||||
+ ret = table_vprintf(tab, column, row, fmt, ap);
|
||||
+ va_end(ap);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function dumps the table. Every "=" string will be replaced by
|
||||
+ * a "=======" length as the column
|
||||
+ */
|
||||
+void table_dump(struct string_table *tab)
|
||||
+{
|
||||
+ int sizes[tab->ncols];
|
||||
+ int i, j;
|
||||
+
|
||||
+ for (i = 0 ; i < tab->ncols ; i++) {
|
||||
+ sizes[i] = 0;
|
||||
+ for (j = 0 ; j < tab->nrows ; j++) {
|
||||
+ int idx = i + j*tab->ncols;
|
||||
+ int s;
|
||||
+
|
||||
+ if (!tab->cells[idx])
|
||||
+ continue;
|
||||
+
|
||||
+ s = strlen(tab->cells[idx]) - 1;
|
||||
+ if (s < 1 || tab->cells[idx][0] == '=')
|
||||
+ continue;
|
||||
+
|
||||
+ if (s > sizes[i])
|
||||
+ sizes[i] = s;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ for (j = 0 ; j < tab->nrows ; j++) {
|
||||
+ for (i = 0 ; i < tab->ncols ; i++) {
|
||||
+
|
||||
+ int idx = i + j*tab->ncols;
|
||||
+ char *s = tab->cells[idx];
|
||||
+
|
||||
+ if (!s|| !strlen(s)) {
|
||||
+ printf("%*s", sizes[i], "");
|
||||
+ } else if (s && s[0] == '=') {
|
||||
+ int k = sizes[i];
|
||||
+ while(k--)
|
||||
+ putchar('=');
|
||||
+ } else {
|
||||
+ printf("%*s",
|
||||
+ s[0] == '<' ? -sizes[i] : sizes[i],
|
||||
+ s+1);
|
||||
+ }
|
||||
+ if (i != (tab->ncols - 1))
|
||||
+ putchar(' ');
|
||||
+ }
|
||||
+ putchar('\n');
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Deallocate a tabular and all its content
|
||||
+ */
|
||||
+
|
||||
+void table_free(struct string_table *tab)
|
||||
+{
|
||||
+
|
||||
+ int i, count;
|
||||
+
|
||||
+ count = tab->ncols * tab->nrows;
|
||||
+
|
||||
+ for (i=0 ; i < count ; i++)
|
||||
+ if (tab->cells[i])
|
||||
+ free(tab->cells[i]);
|
||||
+
|
||||
+ free(tab);
|
||||
+
|
||||
+}
|
||||
Index: btrfs-progs-v3.17.1/string-table.h
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ btrfs-progs-v3.17.1/string-table.h
|
||||
@@ -0,0 +1,36 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public
|
||||
+ * License v2 as published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public
|
||||
+ * License along with this program; if not, write to the
|
||||
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
+ * Boston, MA 021110-1307, USA.
|
||||
+ */
|
||||
+
|
||||
+#ifndef STRING_TABLE_H
|
||||
+#define STRING_TABLE_H
|
||||
+
|
||||
+struct string_table {
|
||||
+
|
||||
+ int ncols, nrows;
|
||||
+ char *cells[];
|
||||
+
|
||||
+};
|
||||
+
|
||||
+
|
||||
+struct string_table *table_create(int columns, int rows);
|
||||
+char *table_printf(struct string_table *tab, int column, int row,
|
||||
+ char *fmt, ...);
|
||||
+char *table_vprintf(struct string_table *tab, int column, int row,
|
||||
+ char *fmt, va_list ap);
|
||||
+void table_dump(struct string_table *tab);
|
||||
+void table_free(struct string_table *);
|
||||
+
|
||||
+#endif
|
@ -1,538 +0,0 @@
|
||||
From fa083296aa7ff515a46ca05e6dbddb38e8c0745f Mon Sep 17 00:00:00 2001
|
||||
From: Goffredo Baroncelli <kreijack@libero.it>
|
||||
Date: Thu, 13 Feb 2014 20:19:50 +0100
|
||||
Subject: [PATCH 04/42] btrfs-progs: Add command btrfs filesystem disk-usage
|
||||
|
||||
Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-fi-disk_usage.c | 428 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
cmds-fi-disk_usage.h | 3 +
|
||||
cmds-filesystem.c | 3 +
|
||||
utils.c | 16 ++
|
||||
utils.h | 5 +
|
||||
5 files changed, 455 insertions(+)
|
||||
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index 7f4415666bd8..25cd4ede97ab 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -20,10 +20,12 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
+#include <stdarg.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "kerncompat.h"
|
||||
#include "ctree.h"
|
||||
+#include "string-table.h"
|
||||
|
||||
#include "commands.h"
|
||||
|
||||
@@ -44,6 +46,13 @@ struct chunk_info {
|
||||
u64 num_stripes;
|
||||
};
|
||||
|
||||
+/* to store information about the disks */
|
||||
+struct disk_info {
|
||||
+ u64 devid;
|
||||
+ char path[BTRFS_DEVICE_PATH_NAME_MAX];
|
||||
+ u64 size;
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Pretty print the size
|
||||
* PAY ATTENTION: it return a statically buffer
|
||||
@@ -514,3 +523,422 @@ int cmd_filesystem_df(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Helper to sort the disk_info structure
|
||||
+ */
|
||||
+static int cmp_disk_info(const void *a, const void *b)
|
||||
+{
|
||||
+ return strcmp(((struct disk_info *)a)->path,
|
||||
+ ((struct disk_info *)b)->path);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function load the disk_info structure and put them in an array
|
||||
+ */
|
||||
+static int load_disks_info(int fd,
|
||||
+ struct disk_info **disks_info_ptr,
|
||||
+ int *disks_info_count)
|
||||
+{
|
||||
+
|
||||
+ int ret, i, ndevs;
|
||||
+ struct btrfs_ioctl_fs_info_args fi_args;
|
||||
+ struct btrfs_ioctl_dev_info_args dev_info;
|
||||
+ struct disk_info *info;
|
||||
+
|
||||
+ *disks_info_count = 0;
|
||||
+ *disks_info_ptr = 0;
|
||||
+
|
||||
+ ret = ioctl(fd, BTRFS_IOC_FS_INFO, &fi_args);
|
||||
+ if (ret < 0) {
|
||||
+ fprintf(stderr, "ERROR: cannot get filesystem info\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ info = malloc(sizeof(struct disk_info) * fi_args.num_devices);
|
||||
+ if (!info) {
|
||||
+ fprintf(stderr, "ERROR: not enough memory\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0, ndevs = 0 ; i <= fi_args.max_id ; i++) {
|
||||
+
|
||||
+ BUG_ON(ndevs >= fi_args.num_devices);
|
||||
+ ret = get_device_info(fd, i, &dev_info);
|
||||
+
|
||||
+ if (ret == -ENODEV)
|
||||
+ continue;
|
||||
+ if (ret) {
|
||||
+ fprintf(stderr,
|
||||
+ "ERROR: cannot get info about device devid=%d\n",
|
||||
+ i);
|
||||
+ free(info);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ info[ndevs].devid = dev_info.devid;
|
||||
+ strcpy(info[ndevs].path, (char *)dev_info.path);
|
||||
+ info[ndevs].size = get_partition_size((char *)dev_info.path);
|
||||
+ ++ndevs;
|
||||
+ }
|
||||
+
|
||||
+ BUG_ON(ndevs != fi_args.num_devices);
|
||||
+ qsort(info, fi_args.num_devices,
|
||||
+ sizeof(struct disk_info), cmp_disk_info);
|
||||
+
|
||||
+ *disks_info_count = fi_args.num_devices;
|
||||
+ *disks_info_ptr = info;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function computes the size of a chunk in a disk
|
||||
+ */
|
||||
+static u64 calc_chunk_size(struct chunk_info *ci)
|
||||
+{
|
||||
+ if (ci->type & BTRFS_BLOCK_GROUP_RAID0)
|
||||
+ return ci->size / ci->num_stripes;
|
||||
+ else if (ci->type & BTRFS_BLOCK_GROUP_RAID1)
|
||||
+ return ci->size ;
|
||||
+ else if (ci->type & BTRFS_BLOCK_GROUP_DUP)
|
||||
+ return ci->size ;
|
||||
+ else if (ci->type & BTRFS_BLOCK_GROUP_RAID5)
|
||||
+ return ci->size / (ci->num_stripes -1);
|
||||
+ else if (ci->type & BTRFS_BLOCK_GROUP_RAID6)
|
||||
+ return ci->size / (ci->num_stripes -2);
|
||||
+ else if (ci->type & BTRFS_BLOCK_GROUP_RAID10)
|
||||
+ return ci->size / ci->num_stripes;
|
||||
+ return ci->size;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function print the results of the command btrfs fi disk-usage
|
||||
+ * in tabular format
|
||||
+ */
|
||||
+static void _cmd_filesystem_disk_usage_tabular(int mode,
|
||||
+ struct btrfs_ioctl_space_args *sargs,
|
||||
+ struct chunk_info *chunks_info_ptr,
|
||||
+ int chunks_info_count,
|
||||
+ struct disk_info *disks_info_ptr,
|
||||
+ int disks_info_count)
|
||||
+{
|
||||
+ int i;
|
||||
+ u64 total_unused = 0;
|
||||
+ struct string_table *matrix = 0;
|
||||
+ int ncols, nrows;
|
||||
+
|
||||
+ ncols = sargs->total_spaces + 2;
|
||||
+ nrows = 2 + 1 + disks_info_count + 1 + 2;
|
||||
+
|
||||
+ matrix = table_create(ncols, nrows);
|
||||
+ if (!matrix) {
|
||||
+ fprintf(stderr, "ERROR: not enough memory\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* header */
|
||||
+ for (i = 0; i < sargs->total_spaces; i++) {
|
||||
+ const char *description;
|
||||
+
|
||||
+ u64 flags = sargs->spaces[i].flags;
|
||||
+ description = btrfs_group_type_str(flags);
|
||||
+
|
||||
+ table_printf(matrix, 1+i, 0, "<%s", description);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < sargs->total_spaces; i++) {
|
||||
+ const char *r_mode;
|
||||
+
|
||||
+ u64 flags = sargs->spaces[i].flags;
|
||||
+ r_mode = btrfs_group_profile_str(flags);
|
||||
+
|
||||
+ table_printf(matrix, 1+i, 1, "<%s", r_mode);
|
||||
+ }
|
||||
+
|
||||
+ table_printf(matrix, 1+sargs->total_spaces, 1, "<Unallocated");
|
||||
+
|
||||
+ /* body */
|
||||
+ for (i = 0 ; i < disks_info_count ; i++) {
|
||||
+ int k, col;
|
||||
+ char *p;
|
||||
+
|
||||
+ u64 total_allocated = 0, unused;
|
||||
+
|
||||
+ p = strrchr(disks_info_ptr[i].path, '/');
|
||||
+ if (!p)
|
||||
+ p = disks_info_ptr[i].path;
|
||||
+ else
|
||||
+ p++;
|
||||
+
|
||||
+ table_printf(matrix, 0, i+3, "<%s",
|
||||
+ disks_info_ptr[i].path);
|
||||
+
|
||||
+ for (col = 1, k = 0 ; k < sargs->total_spaces ; k++) {
|
||||
+ u64 flags = sargs->spaces[k].flags;
|
||||
+ u64 devid = disks_info_ptr[i].devid;
|
||||
+ int j;
|
||||
+ u64 size = 0;
|
||||
+
|
||||
+ for (j = 0 ; j < chunks_info_count ; j++) {
|
||||
+ if (chunks_info_ptr[j].type != flags )
|
||||
+ continue;
|
||||
+ if (chunks_info_ptr[j].devid != devid)
|
||||
+ continue;
|
||||
+
|
||||
+ size += calc_chunk_size(chunks_info_ptr+j);
|
||||
+ }
|
||||
+
|
||||
+ if (size)
|
||||
+ table_printf(matrix, col, i+3,
|
||||
+ ">%s", df_pretty_sizes(size, mode));
|
||||
+ else
|
||||
+ table_printf(matrix, col, i+3, ">-");
|
||||
+
|
||||
+ total_allocated += size;
|
||||
+ col++;
|
||||
+ }
|
||||
+
|
||||
+ unused = get_partition_size(disks_info_ptr[i].path) -
|
||||
+ total_allocated;
|
||||
+
|
||||
+ table_printf(matrix, sargs->total_spaces + 1, i + 3,
|
||||
+ ">%s", df_pretty_sizes(unused, mode));
|
||||
+ total_unused += unused;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i <= sargs->total_spaces; i++)
|
||||
+ table_printf(matrix, i + 1, disks_info_count + 3, "=");
|
||||
+
|
||||
+
|
||||
+ /* footer */
|
||||
+ table_printf(matrix, 0, disks_info_count + 4, "<Total");
|
||||
+ for (i = 0; i < sargs->total_spaces; i++)
|
||||
+ table_printf(matrix, 1 + i, disks_info_count + 4,
|
||||
+ ">%s",
|
||||
+ df_pretty_sizes(sargs->spaces[i].total_bytes, mode));
|
||||
+
|
||||
+ table_printf(matrix, sargs->total_spaces+1, disks_info_count+4,
|
||||
+ ">%s", df_pretty_sizes(total_unused, mode));
|
||||
+
|
||||
+ table_printf(matrix, 0, disks_info_count+5, "<Used");
|
||||
+ for (i = 0; i < sargs->total_spaces; i++)
|
||||
+ table_printf(matrix, 1+i, disks_info_count+5, ">%s",
|
||||
+ df_pretty_sizes(sargs->spaces[i].used_bytes, mode));
|
||||
+
|
||||
+
|
||||
+ table_dump(matrix);
|
||||
+ table_free(matrix);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function prints the unused space per every disk
|
||||
+ */
|
||||
+static void print_unused(struct chunk_info *info_ptr,
|
||||
+ int info_count,
|
||||
+ struct disk_info *disks_info_ptr,
|
||||
+ int disks_info_count,
|
||||
+ int mode)
|
||||
+{
|
||||
+ int i;
|
||||
+ for (i = 0 ; i < disks_info_count ; i++) {
|
||||
+
|
||||
+ int j;
|
||||
+ u64 total = 0;
|
||||
+
|
||||
+ for (j = 0 ; j < info_count ; j++)
|
||||
+ if (info_ptr[j].devid == disks_info_ptr[i].devid)
|
||||
+ total += calc_chunk_size(info_ptr+j);
|
||||
+
|
||||
+ printf(" %s\t%10s\n",
|
||||
+ disks_info_ptr[i].path,
|
||||
+ df_pretty_sizes(disks_info_ptr[i].size - total, mode));
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function prints the allocated chunk per every disk
|
||||
+ */
|
||||
+static void print_chunk_disks(u64 chunk_type,
|
||||
+ struct chunk_info *chunks_info_ptr,
|
||||
+ int chunks_info_count,
|
||||
+ struct disk_info *disks_info_ptr,
|
||||
+ int disks_info_count,
|
||||
+ int mode)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0 ; i < disks_info_count ; i++) {
|
||||
+
|
||||
+ int j;
|
||||
+ u64 total = 0;
|
||||
+
|
||||
+ for (j = 0 ; j < chunks_info_count ; j++) {
|
||||
+
|
||||
+ if (chunks_info_ptr[j].type != chunk_type)
|
||||
+ continue;
|
||||
+ if (chunks_info_ptr[j].devid != disks_info_ptr[i].devid)
|
||||
+ continue;
|
||||
+
|
||||
+ total += calc_chunk_size(&(chunks_info_ptr[j]));
|
||||
+ //total += chunks_info_ptr[j].size;
|
||||
+ }
|
||||
+
|
||||
+ if (total > 0)
|
||||
+ printf(" %s\t%10s\n",
|
||||
+ disks_info_ptr[i].path,
|
||||
+ df_pretty_sizes(total, mode));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function print the results of the command btrfs fi disk-usage
|
||||
+ * in linear format
|
||||
+ */
|
||||
+static void _cmd_filesystem_disk_usage_linear(int mode,
|
||||
+ struct btrfs_ioctl_space_args *sargs,
|
||||
+ struct chunk_info *info_ptr,
|
||||
+ int info_count,
|
||||
+ struct disk_info *disks_info_ptr,
|
||||
+ int disks_info_count)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < sargs->total_spaces; i++) {
|
||||
+ const char *description;
|
||||
+ const char *r_mode;
|
||||
+
|
||||
+ u64 flags = sargs->spaces[i].flags;
|
||||
+ description = btrfs_group_type_str(flags);
|
||||
+ r_mode = btrfs_group_profile_str(flags);
|
||||
+
|
||||
+ printf("%s,%s: Size:%s, ",
|
||||
+ description,
|
||||
+ r_mode,
|
||||
+ df_pretty_sizes(sargs->spaces[i].total_bytes ,
|
||||
+ mode));
|
||||
+ printf("Used:%s\n",
|
||||
+ df_pretty_sizes(sargs->spaces[i].used_bytes,
|
||||
+ mode));
|
||||
+ print_chunk_disks(flags, info_ptr, info_count,
|
||||
+ disks_info_ptr, disks_info_count,
|
||||
+ mode);
|
||||
+ printf("\n");
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ printf("Unallocated:\n");
|
||||
+ print_unused(info_ptr, info_count,
|
||||
+ disks_info_ptr, disks_info_count,
|
||||
+ mode);
|
||||
+
|
||||
+
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static int _cmd_filesystem_disk_usage(int fd, char *path, int mode, int tabular)
|
||||
+{
|
||||
+ struct btrfs_ioctl_space_args *sargs = 0;
|
||||
+ int info_count = 0;
|
||||
+ struct chunk_info *info_ptr = 0;
|
||||
+ struct disk_info *disks_info_ptr = 0;
|
||||
+ int disks_info_count = 0;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (load_chunk_info(fd, &info_ptr, &info_count) ||
|
||||
+ load_disks_info(fd, &disks_info_ptr, &disks_info_count)) {
|
||||
+ ret = -1;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ if ((sargs = load_space_info(fd, path)) == NULL) {
|
||||
+ ret = -1;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ if (tabular)
|
||||
+ _cmd_filesystem_disk_usage_tabular(mode, sargs,
|
||||
+ info_ptr, info_count,
|
||||
+ disks_info_ptr, disks_info_count);
|
||||
+ else
|
||||
+ _cmd_filesystem_disk_usage_linear(mode, sargs,
|
||||
+ info_ptr, info_count,
|
||||
+ disks_info_ptr, disks_info_count);
|
||||
+
|
||||
+exit:
|
||||
+
|
||||
+ if (sargs)
|
||||
+ free(sargs);
|
||||
+ if (disks_info_ptr)
|
||||
+ free(disks_info_ptr);
|
||||
+ if (info_ptr)
|
||||
+ free(info_ptr);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+const char * const cmd_filesystem_disk_usage_usage[] = {
|
||||
+ "btrfs filesystem disk-usage [-b][-t] <path> [<path>..]",
|
||||
+ "Show in which disk the chunks are allocated.",
|
||||
+ "",
|
||||
+ "-b\tSet byte as unit",
|
||||
+ "-t\tShow data in tabular format",
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+int cmd_filesystem_disk_usage(int argc, char **argv)
|
||||
+{
|
||||
+
|
||||
+ int flags = DF_HUMAN_UNIT;
|
||||
+ int i, more_than_one = 0;
|
||||
+ int tabular = 0;
|
||||
+
|
||||
+ optind = 1;
|
||||
+ while (1) {
|
||||
+ char c = getopt(argc, argv, "bt");
|
||||
+ if (c < 0)
|
||||
+ break;
|
||||
+ switch (c) {
|
||||
+ case 'b':
|
||||
+ flags &= ~DF_HUMAN_UNIT;
|
||||
+ break;
|
||||
+ case 't':
|
||||
+ tabular = 1;
|
||||
+ break;
|
||||
+ default:
|
||||
+ usage(cmd_filesystem_disk_usage_usage);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (check_argc_min(argc - optind, 1)) {
|
||||
+ usage(cmd_filesystem_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_filesystem_disk_usage(fd, argv[i], flags, tabular);
|
||||
+ 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 9f68bb342d52..c7459b1521e4 100644
|
||||
--- a/cmds-fi-disk_usage.h
|
||||
+++ b/cmds-fi-disk_usage.h
|
||||
@@ -22,4 +22,7 @@
|
||||
extern const char * const cmd_filesystem_df_usage[];
|
||||
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);
|
||||
+
|
||||
#endif
|
||||
diff --git a/cmds-filesystem.c b/cmds-filesystem.c
|
||||
index 91e4e2e5a881..43d5c31dcbb0 100644
|
||||
--- a/cmds-filesystem.c
|
||||
+++ b/cmds-filesystem.c
|
||||
@@ -1275,6 +1275,9 @@ const struct cmd_group filesystem_cmd_group = {
|
||||
{ "balance", cmd_balance, NULL, &balance_cmd_group, 1 },
|
||||
{ "resize", cmd_resize, cmd_resize_usage, NULL, 0 },
|
||||
{ "label", cmd_label, cmd_label_usage, NULL, 0 },
|
||||
+ { "disk-usage", cmd_filesystem_disk_usage,
|
||||
+ cmd_filesystem_disk_usage_usage, NULL, 0 },
|
||||
+
|
||||
NULL_CMD_STRUCT
|
||||
}
|
||||
};
|
||||
diff --git a/utils.c b/utils.c
|
||||
index cf0559d9c9dd..643f000a5bd0 100644
|
||||
--- a/utils.c
|
||||
+++ b/utils.c
|
||||
@@ -2486,3 +2486,19 @@ u64 disk_size(char *path)
|
||||
else
|
||||
return sfs.f_bsize * sfs.f_blocks;
|
||||
}
|
||||
+
|
||||
+u64 get_partition_size(char *dev)
|
||||
+{
|
||||
+ u64 result;
|
||||
+ int fd = open(dev, O_RDONLY);
|
||||
+
|
||||
+ if (fd < 0)
|
||||
+ return 0;
|
||||
+ if (ioctl(fd, BLKGETSIZE64, &result) < 0) {
|
||||
+ close(fd);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ close(fd);
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
diff --git a/utils.h b/utils.h
|
||||
index 2976e11d7a93..77455ef4d20e 100644
|
||||
--- a/utils.h
|
||||
+++ b/utils.h
|
||||
@@ -134,6 +134,11 @@ int get_device_info(int fd, u64 devid,
|
||||
struct btrfs_ioctl_dev_info_args *di_args);
|
||||
int test_uuid_unique(char *fs_uuid);
|
||||
u64 disk_size(char *path);
|
||||
+int get_device_info(int fd, u64 devid,
|
||||
+ struct btrfs_ioctl_dev_info_args *di_args);
|
||||
+u64 get_partition_size(char *dev);
|
||||
+const char* group_type_str(u64 flags);
|
||||
+const char* group_profile_str(u64 flags);
|
||||
|
||||
int test_minimum_size(const char *file, u32 leafsize);
|
||||
int test_issubvolname(const char *name);
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,193 +0,0 @@
|
||||
From 89a6910a4505829a88bca362541fa75e3ab829e3 Mon Sep 17 00:00:00 2001
|
||||
From: Goffredo Baroncelli <kreijack@libero.it>
|
||||
Date: Thu, 13 Feb 2014 20:20:12 +0100
|
||||
Subject: [PATCH 05/42] btrfs-progs: Add btrfs device disk-usage command
|
||||
|
||||
Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
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 62f0b85b4d0c..037332d87498 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"
|
||||
|
||||
@@ -468,6 +469,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 25cd4ede97ab..5274a73240cf 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;
|
||||
+}
|
||||
diff --git a/cmds-fi-disk_usage.h b/cmds-fi-disk_usage.h
|
||||
index c7459b1521e4..c315004cd806 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
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,57 +0,0 @@
|
||||
From 00f8e6d5c8262a3f3738784e21cf1aca08224efb Mon Sep 17 00:00:00 2001
|
||||
From: Gui Hecheng <guihc.fnst@cn.fujitsu.com>
|
||||
Date: Thu, 6 Mar 2014 11:36:46 +0800
|
||||
Subject: [PATCH 06/42] btrfs-progs: cleanup dead return after usage() for
|
||||
fi-disk_usage
|
||||
|
||||
The usage() calls exit() internally, so remove the return after it.
|
||||
|
||||
Signed-off-by: Gui Hecheng <guihc.fnst@cn.fujitsu.com>
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-fi-disk_usage.c | 12 +++---------
|
||||
1 file changed, 3 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index 5274a73240cf..edada5bbcf6b 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -494,10 +494,8 @@ int cmd_filesystem_df(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
- if (check_argc_min(argc - optind, 1)) {
|
||||
+ if (check_argc_min(argc - optind, 1))
|
||||
usage(cmd_filesystem_df_usage);
|
||||
- return 21;
|
||||
- }
|
||||
|
||||
for (i = optind; i < argc ; i++) {
|
||||
int r, fd;
|
||||
@@ -914,10 +912,8 @@ int cmd_filesystem_disk_usage(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
- if (check_argc_min(argc - optind, 1)) {
|
||||
+ if (check_argc_min(argc - optind, 1))
|
||||
usage(cmd_filesystem_disk_usage_usage);
|
||||
- return 21;
|
||||
- }
|
||||
|
||||
for (i = optind; i < argc ; i++) {
|
||||
int r, fd;
|
||||
@@ -1050,10 +1046,8 @@ int cmd_device_disk_usage(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
- if (check_argc_min(argc - optind, 1)) {
|
||||
+ if (check_argc_min(argc - optind, 1))
|
||||
usage(cmd_device_disk_usage_usage);
|
||||
- return 21;
|
||||
- }
|
||||
|
||||
for (i = optind; i < argc ; i++) {
|
||||
int r, fd;
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,28 +0,0 @@
|
||||
From bf9a3acde396575b141d9ac549aaf83466c0ab91 Mon Sep 17 00:00:00 2001
|
||||
From: Qu Wenruo <quwenruo@cn.fujitsu.com>
|
||||
Date: Wed, 19 Mar 2014 06:10:02 +0000
|
||||
Subject: [PATCH 07/42] btrfs-progs: Fix memleak in get_raid56_used()
|
||||
|
||||
Fix memleak in get_raid56_used().
|
||||
|
||||
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-fi-disk_usage.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index edada5bbcf6b..736294eea3da 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -352,6 +352,7 @@ static int get_raid56_used(int fd, u64 *raid5_used, u64 *raid6_used)
|
||||
if (p->type & BTRFS_BLOCK_GROUP_RAID6)
|
||||
(*raid6_used) += p->size / (p->num_stripes -2);
|
||||
}
|
||||
+ free(info_ptr);
|
||||
|
||||
return 0;
|
||||
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,38 +0,0 @@
|
||||
From 9102adcbc8521dfee5da2fd86b6f8333ee89f3d8 Mon Sep 17 00:00:00 2001
|
||||
From: Rakesh Pandit <rakesh@tuxera.com>
|
||||
Date: Sat, 19 Apr 2014 14:12:03 +0300
|
||||
Subject: [PATCH 08/42] Btrfs-progs: fi usage: free memory if realloc fails
|
||||
|
||||
Lets not assign *info_ptr to 0 before calling free on it and lose
|
||||
track of already allocated memory if realloc fails in
|
||||
add_info_to_list. Lets call free first.
|
||||
|
||||
Signed-off-by: Rakesh Pandit <rakesh@tuxera.com>
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-fi-disk_usage.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index 736294eea3da..9fd59bc1b5ae 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -104,6 +104,7 @@ static int add_info_to_list(struct chunk_info **info_ptr,
|
||||
struct chunk_info *res = realloc(*info_ptr, size);
|
||||
|
||||
if (!res) {
|
||||
+ free(*info_ptr);
|
||||
fprintf(stderr, "ERROR: not enough memory\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -224,7 +225,6 @@ static int load_chunk_info(int fd,
|
||||
|
||||
if (add_info_to_list(info_ptr, info_count, item)) {
|
||||
*info_ptr = 0;
|
||||
- free(*info_ptr);
|
||||
return -100;
|
||||
}
|
||||
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,279 +0,0 @@
|
||||
From 9a0ccdc7cc51262e98fa9345393aa45fd9bba9cb Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Wed, 23 Apr 2014 18:47:52 +0200
|
||||
Subject: [PATCH 09/42] btrfs-progs: add original 'df' and rename 'disk_usage'
|
||||
to 'usage'
|
||||
|
||||
Add back the original output of the 'btrfs fi df' command for backward
|
||||
compatibility. The rich output is moved from 'disk_usage' to 'usage'.
|
||||
|
||||
Agreed in http://www.spinics.net/lists/linux-btrfs/msg31698.html
|
||||
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-fi-disk_usage.c | 85 ++++++++++------------------------------------------
|
||||
cmds-fi-disk_usage.h | 7 ++---
|
||||
cmds-filesystem.c | 16 ++++------
|
||||
3 files changed, 24 insertions(+), 84 deletions(-)
|
||||
|
||||
Index: btrfs-progs-v3.17.1/cmds-fi-disk_usage.c
|
||||
===================================================================
|
||||
--- btrfs-progs-v3.17.1.orig/cmds-fi-disk_usage.c
|
||||
+++ btrfs-progs-v3.17.1/cmds-fi-disk_usage.c
|
||||
@@ -328,6 +328,8 @@ static struct btrfs_ioctl_space_args *lo
|
||||
return sargs;
|
||||
}
|
||||
|
||||
+/* Not used, keep for later */
|
||||
+#if 0
|
||||
/*
|
||||
* This function computes the space occuped by a *single* RAID5/RAID6 chunk.
|
||||
* The computation is performed on the basis of the number of stripes
|
||||
@@ -465,62 +467,7 @@ exit:
|
||||
|
||||
return ret;
|
||||
}
|
||||
-
|
||||
-const char * const cmd_filesystem_df_usage[] = {
|
||||
- "btrfs filesystem df [-b] <path> [<path>..]",
|
||||
- "Show space usage information for a mount point(s).",
|
||||
- "",
|
||||
- "-b\tSet byte as unit",
|
||||
- NULL
|
||||
-};
|
||||
-
|
||||
-int cmd_filesystem_df(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_filesystem_df_usage);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (check_argc_min(argc - optind, 1))
|
||||
- usage(cmd_filesystem_df_usage);
|
||||
-
|
||||
- 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_disk_free(fd, argv[i], flags);
|
||||
- close_file_or_dir(fd, dirstream);
|
||||
-
|
||||
- if (r)
|
||||
- return r;
|
||||
- more_than_one = 1;
|
||||
-
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Helper to sort the disk_info structure
|
||||
@@ -612,10 +559,10 @@ static u64 calc_chunk_size(struct chunk_
|
||||
}
|
||||
|
||||
/*
|
||||
- * This function print the results of the command btrfs fi disk-usage
|
||||
+ * This function print the results of the command "btrfs fi usage"
|
||||
* in tabular format
|
||||
*/
|
||||
-static void _cmd_filesystem_disk_usage_tabular(int mode,
|
||||
+static void _cmd_filesystem_usage_tabular(int mode,
|
||||
struct btrfs_ioctl_space_args *sargs,
|
||||
struct chunk_info *chunks_info_ptr,
|
||||
int chunks_info_count,
|
||||
@@ -795,10 +742,10 @@ static void print_chunk_disks(u64 chunk_
|
||||
}
|
||||
|
||||
/*
|
||||
- * This function print the results of the command btrfs fi disk-usage
|
||||
+ * This function print the results of the command "btrfs fi usage"
|
||||
* in linear format
|
||||
*/
|
||||
-static void _cmd_filesystem_disk_usage_linear(int mode,
|
||||
+static void _cmd_filesystem_usage_linear(int mode,
|
||||
struct btrfs_ioctl_space_args *sargs,
|
||||
struct chunk_info *info_ptr,
|
||||
int info_count,
|
||||
@@ -839,7 +786,7 @@ static void _cmd_filesystem_disk_usage_l
|
||||
|
||||
}
|
||||
|
||||
-static int _cmd_filesystem_disk_usage(int fd, char *path, int mode, int tabular)
|
||||
+static int _cmd_filesystem_usage(int fd, char *path, int mode, int tabular)
|
||||
{
|
||||
struct btrfs_ioctl_space_args *sargs = 0;
|
||||
int info_count = 0;
|
||||
@@ -860,11 +807,11 @@ static int _cmd_filesystem_disk_usage(in
|
||||
}
|
||||
|
||||
if (tabular)
|
||||
- _cmd_filesystem_disk_usage_tabular(mode, sargs,
|
||||
+ _cmd_filesystem_usage_tabular(mode, sargs,
|
||||
info_ptr, info_count,
|
||||
disks_info_ptr, disks_info_count);
|
||||
else
|
||||
- _cmd_filesystem_disk_usage_linear(mode, sargs,
|
||||
+ _cmd_filesystem_usage_linear(mode, sargs,
|
||||
info_ptr, info_count,
|
||||
disks_info_ptr, disks_info_count);
|
||||
|
||||
@@ -880,8 +827,8 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-const char * const cmd_filesystem_disk_usage_usage[] = {
|
||||
- "btrfs filesystem disk-usage [-b][-t] <path> [<path>..]",
|
||||
+const char * const cmd_filesystem_usage_usage[] = {
|
||||
+ "btrfs filesystem usage [-b][-t] <path> [<path>..]",
|
||||
"Show in which disk the chunks are allocated.",
|
||||
"",
|
||||
"-b\tSet byte as unit",
|
||||
@@ -889,7 +836,7 @@ const char * const cmd_filesystem_disk_u
|
||||
NULL
|
||||
};
|
||||
|
||||
-int cmd_filesystem_disk_usage(int argc, char **argv)
|
||||
+int cmd_filesystem_usage(int argc, char **argv)
|
||||
{
|
||||
|
||||
int flags = DF_HUMAN_UNIT;
|
||||
@@ -909,12 +856,12 @@ int cmd_filesystem_disk_usage(int argc,
|
||||
tabular = 1;
|
||||
break;
|
||||
default:
|
||||
- usage(cmd_filesystem_disk_usage_usage);
|
||||
+ usage(cmd_filesystem_usage_usage);
|
||||
}
|
||||
}
|
||||
|
||||
if (check_argc_min(argc - optind, 1))
|
||||
- usage(cmd_filesystem_disk_usage_usage);
|
||||
+ usage(cmd_filesystem_usage_usage);
|
||||
|
||||
for (i = optind; i < argc ; i++) {
|
||||
int r, fd;
|
||||
@@ -928,7 +875,7 @@ int cmd_filesystem_disk_usage(int argc,
|
||||
argv[1]);
|
||||
return 12;
|
||||
}
|
||||
- r = _cmd_filesystem_disk_usage(fd, argv[i], flags, tabular);
|
||||
+ r = _cmd_filesystem_usage(fd, argv[i], flags, tabular);
|
||||
close_file_or_dir(fd, dirstream);
|
||||
|
||||
if (r)
|
||||
Index: btrfs-progs-v3.17.1/cmds-fi-disk_usage.h
|
||||
===================================================================
|
||||
--- btrfs-progs-v3.17.1.orig/cmds-fi-disk_usage.h
|
||||
+++ btrfs-progs-v3.17.1/cmds-fi-disk_usage.h
|
||||
@@ -19,11 +19,8 @@
|
||||
#ifndef __CMDS_FI_DISK_USAGE__
|
||||
#define __CMDS_FI_DISK_USAGE__
|
||||
|
||||
-extern const char * const cmd_filesystem_df_usage[];
|
||||
-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_filesystem_usage_usage[];
|
||||
+int cmd_filesystem_usage(int argc, char **argv);
|
||||
|
||||
extern const char * const cmd_device_disk_usage_usage[];
|
||||
int cmd_device_disk_usage(int argc, char **argv);
|
||||
Index: btrfs-progs-v3.17.1/cmds-filesystem.c
|
||||
===================================================================
|
||||
--- btrfs-progs-v3.17.1.orig/cmds-filesystem.c
|
||||
+++ btrfs-progs-v3.17.1/cmds-filesystem.c
|
||||
@@ -122,8 +122,7 @@ static const char * const filesystem_cmd
|
||||
NULL
|
||||
};
|
||||
|
||||
-#if 0
|
||||
-static const char * const cmd_df_usage[] = {
|
||||
+static const char * const cmd_filesystem_df_usage[] = {
|
||||
"btrfs filesystem df [options] <path>",
|
||||
"Show space usage information for a mount point",
|
||||
"-b|--raw raw numbers in bytes",
|
||||
@@ -137,7 +136,6 @@ static const char * const cmd_df_usage[]
|
||||
"-t|--tbytes show sizes in TiB, or TB with --si",
|
||||
NULL
|
||||
};
|
||||
-#endif
|
||||
|
||||
static int get_df(int fd, struct btrfs_ioctl_space_args **sargs_ret)
|
||||
{
|
||||
@@ -187,7 +185,6 @@ static int get_df(int fd, struct btrfs_i
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#if 0
|
||||
static void print_df(struct btrfs_ioctl_space_args *sargs, unsigned unit_mode)
|
||||
{
|
||||
u64 i;
|
||||
@@ -202,7 +199,7 @@ static void print_df(struct btrfs_ioctl_
|
||||
}
|
||||
}
|
||||
|
||||
-static int cmd_df(int argc, char **argv)
|
||||
+static int cmd_filesystem_df(int argc, char **argv)
|
||||
{
|
||||
struct btrfs_ioctl_space_args *sargs = NULL;
|
||||
int ret;
|
||||
@@ -255,12 +252,12 @@ static int cmd_df(int argc, char **argv)
|
||||
units_set_mode(&unit_mode, UNITS_BINARY);
|
||||
break;
|
||||
default:
|
||||
- usage(cmd_df_usage);
|
||||
+ usage(cmd_filesystem_df_usage);
|
||||
}
|
||||
}
|
||||
|
||||
if (check_argc_exact(argc, optind + 1))
|
||||
- usage(cmd_df_usage);
|
||||
+ usage(cmd_filesystem_df_usage);
|
||||
|
||||
path = argv[optind];
|
||||
|
||||
@@ -281,7 +278,6 @@ static int cmd_df(int argc, char **argv)
|
||||
close_file_or_dir(fd, dirstream);
|
||||
return !!ret;
|
||||
}
|
||||
-#endif
|
||||
|
||||
static int match_search_item_kernel(__u8 *fsid, char *mnt, char *label,
|
||||
char *search)
|
||||
@@ -1287,8 +1283,8 @@ const struct cmd_group filesystem_cmd_gr
|
||||
{ "balance", cmd_balance, NULL, &balance_cmd_group, 1 },
|
||||
{ "resize", cmd_resize, cmd_resize_usage, NULL, 0 },
|
||||
{ "label", cmd_label, cmd_label_usage, NULL, 0 },
|
||||
- { "disk-usage", cmd_filesystem_disk_usage,
|
||||
- cmd_filesystem_disk_usage_usage, NULL, 0 },
|
||||
+ { "usage", cmd_filesystem_usage,
|
||||
+ cmd_filesystem_usage_usage, NULL, 0 },
|
||||
|
||||
NULL_CMD_STRUCT
|
||||
}
|
@ -1,712 +0,0 @@
|
||||
From b90d57cf167b689fd1e191b80649bfcba42865b7 Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Wed, 23 Apr 2014 19:00:22 +0200
|
||||
Subject: [PATCH 10/42] btrfs-progs: move device usage to cmds-device, more
|
||||
cleanups
|
||||
|
||||
Move the command definitions where they belong, keep common 'usage'
|
||||
functions in cmds-fi-disk_usage.c and add exports.
|
||||
|
||||
Rename structures containing 'disk' to 'device'.
|
||||
|
||||
Fix whitespace in the modified code.
|
||||
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-device.c | 96 +++++++++++++++++-
|
||||
cmds-fi-disk_usage.c | 281 ++++++++++++---------------------------------------
|
||||
cmds-fi-disk_usage.h | 30 +++++-
|
||||
3 files changed, 188 insertions(+), 219 deletions(-)
|
||||
|
||||
diff --git a/cmds-device.c b/cmds-device.c
|
||||
index 037332d87498..96e6309c0185 100644
|
||||
--- a/cmds-device.c
|
||||
+++ b/cmds-device.c
|
||||
@@ -462,6 +462,98 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
+const char * const cmd_device_usage_usage[] = {
|
||||
+ "btrfs device usage [-b] <path> [<path>..]",
|
||||
+ "Show which chunks are in a device.",
|
||||
+ "",
|
||||
+ "-b\tSet byte as unit",
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static int _cmd_device_usage(int fd, char *path, int mode)
|
||||
+{
|
||||
+ int i;
|
||||
+ int ret = 0;
|
||||
+ int info_count = 0;
|
||||
+ struct chunk_info *info_ptr = 0;
|
||||
+ struct device_info *device_info_ptr = 0;
|
||||
+ int device_info_count = 0;
|
||||
+
|
||||
+ if (load_chunk_info(fd, &info_ptr, &info_count) ||
|
||||
+ load_device_info(fd, &device_info_ptr, &device_info_count)) {
|
||||
+ ret = -1;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < device_info_count; i++) {
|
||||
+ printf("%s\t%10s\n", device_info_ptr[i].path,
|
||||
+ df_pretty_sizes(device_info_ptr[i].size, mode));
|
||||
+
|
||||
+ print_device_chunks(fd, device_info_ptr[i].devid,
|
||||
+ device_info_ptr[i].size,
|
||||
+ info_ptr, info_count,
|
||||
+ mode);
|
||||
+ printf("\n");
|
||||
+ }
|
||||
+
|
||||
+exit:
|
||||
+ if (device_info_ptr)
|
||||
+ free(device_info_ptr);
|
||||
+ if (info_ptr)
|
||||
+ free(info_ptr);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int cmd_device_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_usage_usage);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (check_argc_min(argc - optind, 1))
|
||||
+ usage(cmd_device_usage_usage);
|
||||
+
|
||||
+ 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_usage(fd, argv[i], flags);
|
||||
+ close_file_or_dir(fd, dirstream);
|
||||
+
|
||||
+ if (r)
|
||||
+ return r;
|
||||
+ more_than_one = 1;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
const struct cmd_group device_cmd_group = {
|
||||
device_cmd_group_usage, NULL, {
|
||||
{ "add", cmd_add_dev, cmd_add_dev_usage, NULL, 0 },
|
||||
@@ -469,8 +561,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 },
|
||||
+ { "usage", cmd_device_usage,
|
||||
+ cmd_device_usage_usage, NULL, 0 },
|
||||
NULL_CMD_STRUCT
|
||||
}
|
||||
};
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index 683d6fb36de4..f432fa57fb91 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -26,38 +26,16 @@
|
||||
#include "kerncompat.h"
|
||||
#include "ctree.h"
|
||||
#include "string-table.h"
|
||||
-
|
||||
+#include "cmds-fi-disk_usage.h"
|
||||
#include "commands.h"
|
||||
|
||||
#include "version.h"
|
||||
|
||||
-#define DF_HUMAN_UNIT (1<<0)
|
||||
-
|
||||
-/*
|
||||
- * To store the size information about the chunks:
|
||||
- * the chunks info are grouped by the tuple (type, devid, num_stripes),
|
||||
- * i.e. if two chunks are of the same type (RAID1, DUP...), are on the
|
||||
- * same disk, have the same stripes then their sizes are grouped
|
||||
- */
|
||||
-struct chunk_info {
|
||||
- u64 type;
|
||||
- u64 size;
|
||||
- u64 devid;
|
||||
- u64 num_stripes;
|
||||
-};
|
||||
-
|
||||
-/* to store information about the disks */
|
||||
-struct disk_info {
|
||||
- u64 devid;
|
||||
- char path[BTRFS_DEVICE_PATH_NAME_MAX];
|
||||
- u64 size;
|
||||
-};
|
||||
-
|
||||
/*
|
||||
* Pretty print the size
|
||||
* PAY ATTENTION: it return a statically buffer
|
||||
*/
|
||||
-static char *df_pretty_sizes(u64 size, int mode)
|
||||
+char *df_pretty_sizes(u64 size, int mode)
|
||||
{
|
||||
static char buf[30];
|
||||
|
||||
@@ -163,14 +141,8 @@ static int cmp_chunk_info(const void *a, const void *b)
|
||||
((struct chunk_info *)b)->type);
|
||||
}
|
||||
|
||||
-/*
|
||||
- * This function load all the chunk info from the 'fd' filesystem
|
||||
- */
|
||||
-static int load_chunk_info(int fd,
|
||||
- struct chunk_info **info_ptr,
|
||||
- int *info_count)
|
||||
+int load_chunk_info(int fd, struct chunk_info **info_ptr, int *info_count)
|
||||
{
|
||||
-
|
||||
int ret;
|
||||
struct btrfs_ioctl_search_args args;
|
||||
struct btrfs_ioctl_search_key *sk = &args.key;
|
||||
@@ -178,7 +150,6 @@ static int load_chunk_info(int fd,
|
||||
unsigned long off = 0;
|
||||
int i, e;
|
||||
|
||||
-
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
/*
|
||||
@@ -186,8 +157,6 @@ static int load_chunk_info(int fd,
|
||||
* snapshots pending deletion, we have to loop through
|
||||
* them.
|
||||
*/
|
||||
-
|
||||
-
|
||||
sk->tree_id = BTRFS_CHUNK_TREE_OBJECTID;
|
||||
|
||||
sk->min_objectid = 0;
|
||||
@@ -253,7 +222,6 @@ static int load_chunk_info(int fd,
|
||||
cmp_chunk_info);
|
||||
|
||||
return 0;
|
||||
-
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -333,7 +301,7 @@ static struct btrfs_ioctl_space_args *load_space_info(int fd, char *path)
|
||||
/*
|
||||
* This function computes the space occuped by a *single* RAID5/RAID6 chunk.
|
||||
* The computation is performed on the basis of the number of stripes
|
||||
- * which compose the chunk, which could be different from the number of disks
|
||||
+ * which compose the chunk, which could be different from the number of devices
|
||||
* if a disk is added later.
|
||||
*/
|
||||
static int get_raid56_used(int fd, u64 *raid5_used, u64 *raid6_used)
|
||||
@@ -367,7 +335,7 @@ static int _cmd_disk_free(int fd, char *path, int mode)
|
||||
int ret = 0;
|
||||
int e, width;
|
||||
u64 total_disk; /* filesystem size == sum of
|
||||
- disks sizes */
|
||||
+ device sizes */
|
||||
u64 total_chunks; /* sum of chunks sizes on disk(s) */
|
||||
u64 total_used; /* logical space used */
|
||||
u64 total_free; /* logical space un-used */
|
||||
@@ -470,29 +438,27 @@ exit:
|
||||
#endif
|
||||
|
||||
/*
|
||||
- * Helper to sort the disk_info structure
|
||||
+ * Helper to sort the device_info structure
|
||||
*/
|
||||
-static int cmp_disk_info(const void *a, const void *b)
|
||||
+static int cmp_device_info(const void *a, const void *b)
|
||||
{
|
||||
- return strcmp(((struct disk_info *)a)->path,
|
||||
- ((struct disk_info *)b)->path);
|
||||
+ return strcmp(((struct device_info *)a)->path,
|
||||
+ ((struct device_info *)b)->path);
|
||||
}
|
||||
|
||||
/*
|
||||
- * This function load the disk_info structure and put them in an array
|
||||
+ * This function loads the device_info structure and put them in an array
|
||||
*/
|
||||
-static int load_disks_info(int fd,
|
||||
- struct disk_info **disks_info_ptr,
|
||||
- int *disks_info_count)
|
||||
+int load_device_info(int fd, struct device_info **device_info_ptr,
|
||||
+ int *device_info_count)
|
||||
{
|
||||
-
|
||||
int ret, i, ndevs;
|
||||
struct btrfs_ioctl_fs_info_args fi_args;
|
||||
struct btrfs_ioctl_dev_info_args dev_info;
|
||||
- struct disk_info *info;
|
||||
+ struct device_info *info;
|
||||
|
||||
- *disks_info_count = 0;
|
||||
- *disks_info_ptr = 0;
|
||||
+ *device_info_count = 0;
|
||||
+ *device_info_ptr = 0;
|
||||
|
||||
ret = ioctl(fd, BTRFS_IOC_FS_INFO, &fi_args);
|
||||
if (ret < 0) {
|
||||
@@ -500,7 +466,7 @@ static int load_disks_info(int fd,
|
||||
return -1;
|
||||
}
|
||||
|
||||
- info = malloc(sizeof(struct disk_info) * fi_args.num_devices);
|
||||
+ info = malloc(sizeof(struct device_info) * fi_args.num_devices);
|
||||
if (!info) {
|
||||
fprintf(stderr, "ERROR: not enough memory\n");
|
||||
return -1;
|
||||
@@ -529,13 +495,12 @@ static int load_disks_info(int fd,
|
||||
|
||||
BUG_ON(ndevs != fi_args.num_devices);
|
||||
qsort(info, fi_args.num_devices,
|
||||
- sizeof(struct disk_info), cmp_disk_info);
|
||||
+ sizeof(struct device_info), cmp_device_info);
|
||||
|
||||
- *disks_info_count = fi_args.num_devices;
|
||||
- *disks_info_ptr = info;
|
||||
+ *device_info_count = fi_args.num_devices;
|
||||
+ *device_info_ptr = info;
|
||||
|
||||
return 0;
|
||||
-
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -566,8 +531,8 @@ static void _cmd_filesystem_usage_tabular(int mode,
|
||||
struct btrfs_ioctl_space_args *sargs,
|
||||
struct chunk_info *chunks_info_ptr,
|
||||
int chunks_info_count,
|
||||
- struct disk_info *disks_info_ptr,
|
||||
- int disks_info_count)
|
||||
+ struct device_info *device_info_ptr,
|
||||
+ int device_info_count)
|
||||
{
|
||||
int i;
|
||||
u64 total_unused = 0;
|
||||
@@ -575,7 +540,7 @@ static void _cmd_filesystem_usage_tabular(int mode,
|
||||
int ncols, nrows;
|
||||
|
||||
ncols = sargs->total_spaces + 2;
|
||||
- nrows = 2 + 1 + disks_info_count + 1 + 2;
|
||||
+ nrows = 2 + 1 + device_info_count + 1 + 2;
|
||||
|
||||
matrix = table_create(ncols, nrows);
|
||||
if (!matrix) {
|
||||
@@ -605,24 +570,23 @@ static void _cmd_filesystem_usage_tabular(int mode,
|
||||
table_printf(matrix, 1+sargs->total_spaces, 1, "<Unallocated");
|
||||
|
||||
/* body */
|
||||
- for (i = 0 ; i < disks_info_count ; i++) {
|
||||
+ for (i = 0; i < device_info_count; i++) {
|
||||
int k, col;
|
||||
char *p;
|
||||
|
||||
u64 total_allocated = 0, unused;
|
||||
|
||||
- p = strrchr(disks_info_ptr[i].path, '/');
|
||||
+ p = strrchr(device_info_ptr[i].path, '/');
|
||||
if (!p)
|
||||
- p = disks_info_ptr[i].path;
|
||||
+ p = device_info_ptr[i].path;
|
||||
else
|
||||
p++;
|
||||
|
||||
- table_printf(matrix, 0, i+3, "<%s",
|
||||
- disks_info_ptr[i].path);
|
||||
+ table_printf(matrix, 0, i + 3, "<%s", device_info_ptr[i].path);
|
||||
|
||||
for (col = 1, k = 0 ; k < sargs->total_spaces ; k++) {
|
||||
u64 flags = sargs->spaces[k].flags;
|
||||
- u64 devid = disks_info_ptr[i].devid;
|
||||
+ u64 devid = device_info_ptr[i].devid;
|
||||
int j;
|
||||
u64 size = 0;
|
||||
|
||||
@@ -645,8 +609,8 @@ static void _cmd_filesystem_usage_tabular(int mode,
|
||||
col++;
|
||||
}
|
||||
|
||||
- unused = get_partition_size(disks_info_ptr[i].path) -
|
||||
- total_allocated;
|
||||
+ unused = get_partition_size(device_info_ptr[i].path)
|
||||
+ - total_allocated;
|
||||
|
||||
table_printf(matrix, sargs->total_spaces + 1, i + 3,
|
||||
">%s", df_pretty_sizes(unused, mode));
|
||||
@@ -655,28 +619,24 @@ static void _cmd_filesystem_usage_tabular(int mode,
|
||||
}
|
||||
|
||||
for (i = 0; i <= sargs->total_spaces; i++)
|
||||
- table_printf(matrix, i + 1, disks_info_count + 3, "=");
|
||||
-
|
||||
+ table_printf(matrix, i + 1, device_info_count + 3, "=");
|
||||
|
||||
/* footer */
|
||||
- table_printf(matrix, 0, disks_info_count + 4, "<Total");
|
||||
+ table_printf(matrix, 0, device_info_count + 4, "<Total");
|
||||
for (i = 0; i < sargs->total_spaces; i++)
|
||||
- table_printf(matrix, 1 + i, disks_info_count + 4,
|
||||
- ">%s",
|
||||
+ table_printf(matrix, 1 + i, device_info_count + 4, ">%s",
|
||||
df_pretty_sizes(sargs->spaces[i].total_bytes, mode));
|
||||
|
||||
- table_printf(matrix, sargs->total_spaces+1, disks_info_count+4,
|
||||
- ">%s", df_pretty_sizes(total_unused, mode));
|
||||
+ table_printf(matrix, sargs->total_spaces + 1, device_info_count + 4,
|
||||
+ ">%s", df_pretty_sizes(total_unused, mode));
|
||||
|
||||
- table_printf(matrix, 0, disks_info_count+5, "<Used");
|
||||
+ table_printf(matrix, 0, device_info_count + 5, "<Used");
|
||||
for (i = 0; i < sargs->total_spaces; i++)
|
||||
- table_printf(matrix, 1+i, disks_info_count+5, ">%s",
|
||||
+ table_printf(matrix, 1 + i, device_info_count+5, ">%s",
|
||||
df_pretty_sizes(sargs->spaces[i].used_bytes, mode));
|
||||
|
||||
-
|
||||
table_dump(matrix);
|
||||
table_free(matrix);
|
||||
-
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -684,50 +644,46 @@ static void _cmd_filesystem_usage_tabular(int mode,
|
||||
*/
|
||||
static void print_unused(struct chunk_info *info_ptr,
|
||||
int info_count,
|
||||
- struct disk_info *disks_info_ptr,
|
||||
- int disks_info_count,
|
||||
+ struct device_info *device_info_ptr,
|
||||
+ int device_info_count,
|
||||
int mode)
|
||||
{
|
||||
int i;
|
||||
- for (i = 0 ; i < disks_info_count ; i++) {
|
||||
-
|
||||
+ for (i = 0; i < device_info_count; i++) {
|
||||
int j;
|
||||
u64 total = 0;
|
||||
|
||||
- for (j = 0 ; j < info_count ; j++)
|
||||
- if (info_ptr[j].devid == disks_info_ptr[i].devid)
|
||||
+ for (j = 0; j < info_count; j++)
|
||||
+ if (info_ptr[j].devid == device_info_ptr[i].devid)
|
||||
total += calc_chunk_size(info_ptr+j);
|
||||
|
||||
printf(" %s\t%10s\n",
|
||||
- disks_info_ptr[i].path,
|
||||
- df_pretty_sizes(disks_info_ptr[i].size - total, mode));
|
||||
-
|
||||
+ device_info_ptr[i].path,
|
||||
+ df_pretty_sizes(device_info_ptr[i].size - total, mode));
|
||||
}
|
||||
-
|
||||
}
|
||||
|
||||
/*
|
||||
* This function prints the allocated chunk per every disk
|
||||
*/
|
||||
-static void print_chunk_disks(u64 chunk_type,
|
||||
+static void print_chunk_device(u64 chunk_type,
|
||||
struct chunk_info *chunks_info_ptr,
|
||||
int chunks_info_count,
|
||||
- struct disk_info *disks_info_ptr,
|
||||
- int disks_info_count,
|
||||
+ struct device_info *device_info_ptr,
|
||||
+ int device_info_count,
|
||||
int mode)
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0 ; i < disks_info_count ; i++) {
|
||||
-
|
||||
+ for (i = 0; i < device_info_count; i++) {
|
||||
int j;
|
||||
u64 total = 0;
|
||||
|
||||
- for (j = 0 ; j < chunks_info_count ; j++) {
|
||||
+ for (j = 0; j < chunks_info_count; j++) {
|
||||
|
||||
if (chunks_info_ptr[j].type != chunk_type)
|
||||
continue;
|
||||
- if (chunks_info_ptr[j].devid != disks_info_ptr[i].devid)
|
||||
+ if (chunks_info_ptr[j].devid != device_info_ptr[i].devid)
|
||||
continue;
|
||||
|
||||
total += calc_chunk_size(&(chunks_info_ptr[j]));
|
||||
@@ -736,7 +692,7 @@ static void print_chunk_disks(u64 chunk_type,
|
||||
|
||||
if (total > 0)
|
||||
printf(" %s\t%10s\n",
|
||||
- disks_info_ptr[i].path,
|
||||
+ device_info_ptr[i].path,
|
||||
df_pretty_sizes(total, mode));
|
||||
}
|
||||
}
|
||||
@@ -749,8 +705,8 @@ static void _cmd_filesystem_usage_linear(int mode,
|
||||
struct btrfs_ioctl_space_args *sargs,
|
||||
struct chunk_info *info_ptr,
|
||||
int info_count,
|
||||
- struct disk_info *disks_info_ptr,
|
||||
- int disks_info_count)
|
||||
+ struct device_info *device_info_ptr,
|
||||
+ int device_info_count)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -768,22 +724,15 @@ static void _cmd_filesystem_usage_linear(int mode,
|
||||
df_pretty_sizes(sargs->spaces[i].total_bytes ,
|
||||
mode));
|
||||
printf("Used:%s\n",
|
||||
- df_pretty_sizes(sargs->spaces[i].used_bytes,
|
||||
- mode));
|
||||
- print_chunk_disks(flags, info_ptr, info_count,
|
||||
- disks_info_ptr, disks_info_count,
|
||||
- mode);
|
||||
+ df_pretty_sizes(sargs->spaces[i].used_bytes, mode));
|
||||
+ print_chunk_device(flags, info_ptr, info_count,
|
||||
+ device_info_ptr, device_info_count, mode);
|
||||
printf("\n");
|
||||
-
|
||||
}
|
||||
|
||||
printf("Unallocated:\n");
|
||||
- print_unused(info_ptr, info_count,
|
||||
- disks_info_ptr, disks_info_count,
|
||||
+ print_unused(info_ptr, info_count, device_info_ptr, device_info_count,
|
||||
mode);
|
||||
-
|
||||
-
|
||||
-
|
||||
}
|
||||
|
||||
static int _cmd_filesystem_usage(int fd, char *path, int mode, int tabular)
|
||||
@@ -791,12 +740,12 @@ static int _cmd_filesystem_usage(int fd, char *path, int mode, int tabular)
|
||||
struct btrfs_ioctl_space_args *sargs = 0;
|
||||
int info_count = 0;
|
||||
struct chunk_info *info_ptr = 0;
|
||||
- struct disk_info *disks_info_ptr = 0;
|
||||
- int disks_info_count = 0;
|
||||
+ struct device_info *device_info_ptr = 0;
|
||||
+ int device_info_count = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (load_chunk_info(fd, &info_ptr, &info_count) ||
|
||||
- load_disks_info(fd, &disks_info_ptr, &disks_info_count)) {
|
||||
+ load_device_info(fd, &device_info_ptr, &device_info_count)) {
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
@@ -809,18 +758,18 @@ static int _cmd_filesystem_usage(int fd, char *path, int mode, int tabular)
|
||||
if (tabular)
|
||||
_cmd_filesystem_usage_tabular(mode, sargs,
|
||||
info_ptr, info_count,
|
||||
- disks_info_ptr, disks_info_count);
|
||||
+ device_info_ptr, device_info_count);
|
||||
else
|
||||
_cmd_filesystem_usage_linear(mode, sargs,
|
||||
info_ptr, info_count,
|
||||
- disks_info_ptr, disks_info_count);
|
||||
+ device_info_ptr, device_info_count);
|
||||
|
||||
exit:
|
||||
|
||||
if (sargs)
|
||||
free(sargs);
|
||||
- if (disks_info_ptr)
|
||||
- free(disks_info_ptr);
|
||||
+ if (device_info_ptr)
|
||||
+ free(device_info_ptr);
|
||||
if (info_ptr)
|
||||
free(info_ptr);
|
||||
|
||||
@@ -887,12 +836,9 @@ int cmd_filesystem_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)
|
||||
+void print_device_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;
|
||||
@@ -925,98 +871,3 @@ static void print_disk_chunks(int fd,
|
||||
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);
|
||||
-
|
||||
- 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 95cf4aabefb4..787b4eb56acf 100644
|
||||
--- a/cmds-fi-disk_usage.h
|
||||
+++ b/cmds-fi-disk_usage.h
|
||||
@@ -19,10 +19,36 @@
|
||||
#ifndef __CMDS_FI_DISK_USAGE__
|
||||
#define __CMDS_FI_DISK_USAGE__
|
||||
|
||||
+#define DF_HUMAN_UNIT (1<<0)
|
||||
+
|
||||
extern const char * const cmd_filesystem_usage_usage[];
|
||||
int cmd_filesystem_usage(int argc, char **argv);
|
||||
|
||||
-extern const char * const cmd_device_disk_usage_usage[];
|
||||
-int cmd_device_disk_usage(int argc, char **argv);
|
||||
+struct device_info {
|
||||
+ u64 devid;
|
||||
+ char path[BTRFS_DEVICE_PATH_NAME_MAX];
|
||||
+ u64 size;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * To store the size information about the chunks:
|
||||
+ * the chunks info are grouped by the tuple (type, devid, num_stripes),
|
||||
+ * i.e. if two chunks are of the same type (RAID1, DUP...), are on the
|
||||
+ * same disk, have the same stripes then their sizes are grouped
|
||||
+ */
|
||||
+struct chunk_info {
|
||||
+ u64 type;
|
||||
+ u64 size;
|
||||
+ u64 devid;
|
||||
+ u64 num_stripes;
|
||||
+};
|
||||
+
|
||||
+int load_device_info(int fd, struct device_info **device_info_ptr,
|
||||
+ int *device_info_count);
|
||||
+int load_chunk_info(int fd, struct chunk_info **info_ptr, int *info_count);
|
||||
+char *df_pretty_sizes(u64 size, int mode);
|
||||
+void print_device_chunks(int fd, u64 devid, u64 total_size,
|
||||
+ struct chunk_info *chunks_info_ptr,
|
||||
+ int chunks_info_count, int mode);
|
||||
|
||||
#endif
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,45 +0,0 @@
|
||||
From 10fd49e8ced9a8fe34a409ab76c69488b9aef704 Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Thu, 24 Apr 2014 15:21:16 +0200
|
||||
Subject: [PATCH 11/42] btrfs-progs: check if we can't get info from ioctls due
|
||||
to permissions
|
||||
|
||||
The TREE_SEARCH ioctl is root-only, FS_INFO will be available for
|
||||
non-root users with an updated kernel, let the user know.
|
||||
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-fi-disk_usage.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index f432fa57fb91..8bc4f58fee0b 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -172,6 +172,12 @@ int load_chunk_info(int fd, struct chunk_info **info_ptr, int *info_count)
|
||||
while (1) {
|
||||
ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
|
||||
e = errno;
|
||||
+ if (ret == -EPERM) {
|
||||
+ fprintf(stderr,
|
||||
+ "ERROR: can't read detailed chunk info from ioctl(TREE_SEARCH), run as root\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
if (ret < 0) {
|
||||
fprintf(stderr,
|
||||
"ERROR: can't perform the search - %s\n",
|
||||
@@ -461,6 +467,10 @@ int load_device_info(int fd, struct device_info **device_info_ptr,
|
||||
*device_info_ptr = 0;
|
||||
|
||||
ret = ioctl(fd, BTRFS_IOC_FS_INFO, &fi_args);
|
||||
+ if (ret == -EPERM) {
|
||||
+ fprintf(stderr, "ERROR: can't get filesystem info from ioctl(FS_INFO), run as root\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "ERROR: cannot get filesystem info\n");
|
||||
return -1;
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,44 +0,0 @@
|
||||
From 5a44a4939129de6edb249c03133e5db347739643 Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Thu, 24 Apr 2014 18:37:50 +0200
|
||||
Subject: [PATCH 12/42] btrfs-progs: zero out structures before calling ioctl
|
||||
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-fi-disk_usage.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index 8bc4f58fee0b..f984be838e3b 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -248,7 +248,7 @@ static struct btrfs_ioctl_space_args *load_space_info(int fd, char *path)
|
||||
struct btrfs_ioctl_space_args *sargs = 0, *sargs_orig = 0;
|
||||
int e, ret, count;
|
||||
|
||||
- sargs_orig = sargs = malloc(sizeof(struct btrfs_ioctl_space_args));
|
||||
+ sargs_orig = sargs = calloc(1, sizeof(struct btrfs_ioctl_space_args));
|
||||
if (!sargs) {
|
||||
fprintf(stderr, "ERROR: not enough memory\n");
|
||||
return NULL;
|
||||
@@ -476,15 +476,15 @@ int load_device_info(int fd, struct device_info **device_info_ptr,
|
||||
return -1;
|
||||
}
|
||||
|
||||
- info = malloc(sizeof(struct device_info) * fi_args.num_devices);
|
||||
+ info = calloc(fi_args.num_devices, sizeof(struct device_info));
|
||||
if (!info) {
|
||||
fprintf(stderr, "ERROR: not enough memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0, ndevs = 0 ; i <= fi_args.max_id ; i++) {
|
||||
-
|
||||
BUG_ON(ndevs >= fi_args.num_devices);
|
||||
+ memset(&dev_info, 0, sizeof(dev_info));
|
||||
ret = get_device_info(fd, i, &dev_info);
|
||||
|
||||
if (ret == -ENODEV)
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,100 +0,0 @@
|
||||
From 685cfb2cb0a7b402c9074e08d2803e275c6f78eb Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Thu, 24 Apr 2014 18:32:27 +0200
|
||||
Subject: [PATCH 13/42] btrfs-progs: Print more info about device sizes
|
||||
|
||||
The entire device size may not be available to the filesystem, eg. if
|
||||
it's modified via resize. Print this information if it can be obtained
|
||||
from the DEV_INFO ioctl.
|
||||
|
||||
Print the device ID on the same line as the device name and move size to
|
||||
the next line.
|
||||
|
||||
Sample:
|
||||
/dev/sda7, ID: 3
|
||||
Device size: 10.00GiB
|
||||
FS occupied: 5.00GiB
|
||||
Data,RAID10: 512.00MiB
|
||||
Metadata,RAID10: 512.00MiB
|
||||
System,RAID10: 4.00MiB
|
||||
Unallocated: 9.00GiB
|
||||
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-device.c | 6 +++---
|
||||
cmds-fi-disk_usage.c | 12 +++++++++++-
|
||||
cmds-fi-disk_usage.h | 6 +++++-
|
||||
3 files changed, 19 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/cmds-device.c b/cmds-device.c
|
||||
index 96e6309c0185..f9a23ac644c0 100644
|
||||
--- a/cmds-device.c
|
||||
+++ b/cmds-device.c
|
||||
@@ -486,9 +486,9 @@ static int _cmd_device_usage(int fd, char *path, int mode)
|
||||
}
|
||||
|
||||
for (i = 0; i < device_info_count; i++) {
|
||||
- printf("%s\t%10s\n", device_info_ptr[i].path,
|
||||
- df_pretty_sizes(device_info_ptr[i].size, mode));
|
||||
-
|
||||
+ printf("%s, ID: %llu\n", device_info_ptr[i].path,
|
||||
+ device_info_ptr[i].devid);
|
||||
+ print_device_sizes(fd, &device_info_ptr[i], mode);
|
||||
print_device_chunks(fd, device_info_ptr[i].devid,
|
||||
device_info_ptr[i].size,
|
||||
info_ptr, info_count,
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index f984be838e3b..83a3c6d52cc5 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -499,7 +499,8 @@ int load_device_info(int fd, struct device_info **device_info_ptr,
|
||||
|
||||
info[ndevs].devid = dev_info.devid;
|
||||
strcpy(info[ndevs].path, (char *)dev_info.path);
|
||||
- info[ndevs].size = get_partition_size((char *)dev_info.path);
|
||||
+ info[ndevs].device_size = get_partition_size((char *)dev_info.path);
|
||||
+ info[ndevs].size = dev_info.total_bytes;
|
||||
++ndevs;
|
||||
}
|
||||
|
||||
@@ -879,5 +880,14 @@ void print_device_chunks(int fd, u64 devid, u64 total_size,
|
||||
printf(" Unallocated: %*s%10s\n",
|
||||
(int)(20 - strlen("Unallocated")), "",
|
||||
df_pretty_sizes(total_size - allocated, mode));
|
||||
+}
|
||||
|
||||
+void print_device_sizes(int fd, struct device_info *devinfo, int mode)
|
||||
+{
|
||||
+ printf(" Device size: %*s%10s\n",
|
||||
+ (int)(20 - strlen("Device size")), "",
|
||||
+ df_pretty_sizes(devinfo->device_size, mode));
|
||||
+ printf(" FS occupied: %*s%10s\n",
|
||||
+ (int)(20 - strlen("FS occupied")), "",
|
||||
+ df_pretty_sizes(devinfo->size, mode));
|
||||
}
|
||||
diff --git a/cmds-fi-disk_usage.h b/cmds-fi-disk_usage.h
|
||||
index 787b4eb56acf..79cc2a115bc5 100644
|
||||
--- a/cmds-fi-disk_usage.h
|
||||
+++ b/cmds-fi-disk_usage.h
|
||||
@@ -27,7 +27,10 @@ int cmd_filesystem_usage(int argc, char **argv);
|
||||
struct device_info {
|
||||
u64 devid;
|
||||
char path[BTRFS_DEVICE_PATH_NAME_MAX];
|
||||
- u64 size;
|
||||
+ /* Size of the block device */
|
||||
+ u64 device_size;
|
||||
+ /* Size that's occupied by the filesystem, can be changed via resize */
|
||||
+ u64 size;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -50,5 +53,6 @@ char *df_pretty_sizes(u64 size, int mode);
|
||||
void print_device_chunks(int fd, u64 devid, u64 total_size,
|
||||
struct chunk_info *chunks_info_ptr,
|
||||
int chunks_info_count, int mode);
|
||||
+void print_device_sizes(int fd, struct device_info *devinfo, int mode);
|
||||
|
||||
#endif
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,81 +0,0 @@
|
||||
From f775e02b0210e5128f980a19a5490c58d80bfc27 Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Thu, 24 Apr 2014 18:57:12 +0200
|
||||
Subject: [PATCH 14/42] btrfs-progs: compare unallocated space against the
|
||||
correct value
|
||||
|
||||
The device may not be fully occupied by the filesystem, the value of
|
||||
Unallocated should not be calculated against the device size but the
|
||||
size provided by DEV_INFO.
|
||||
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-device.c | 6 ++----
|
||||
cmds-fi-disk_usage.c | 6 +++---
|
||||
cmds-fi-disk_usage.h | 2 +-
|
||||
3 files changed, 6 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/cmds-device.c b/cmds-device.c
|
||||
index f9a23ac644c0..1de7f007ed43 100644
|
||||
--- a/cmds-device.c
|
||||
+++ b/cmds-device.c
|
||||
@@ -489,10 +489,8 @@ static int _cmd_device_usage(int fd, char *path, int mode)
|
||||
printf("%s, ID: %llu\n", device_info_ptr[i].path,
|
||||
device_info_ptr[i].devid);
|
||||
print_device_sizes(fd, &device_info_ptr[i], mode);
|
||||
- print_device_chunks(fd, device_info_ptr[i].devid,
|
||||
- device_info_ptr[i].size,
|
||||
- info_ptr, info_count,
|
||||
- mode);
|
||||
+ print_device_chunks(fd, &device_info_ptr[i],
|
||||
+ info_ptr, info_count, mode);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index 83a3c6d52cc5..0ee6e6bb5dc4 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -847,7 +847,7 @@ int cmd_filesystem_usage(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-void print_device_chunks(int fd, u64 devid, u64 total_size,
|
||||
+void print_device_chunks(int fd, struct device_info *devinfo,
|
||||
struct chunk_info *chunks_info_ptr,
|
||||
int chunks_info_count, int mode)
|
||||
{
|
||||
@@ -860,7 +860,7 @@ void print_device_chunks(int fd, u64 devid, u64 total_size,
|
||||
u64 flags;
|
||||
u64 size;
|
||||
|
||||
- if (chunks_info_ptr[i].devid != devid)
|
||||
+ if (chunks_info_ptr[i].devid != devinfo->devid)
|
||||
continue;
|
||||
|
||||
flags = chunks_info_ptr[i].type;
|
||||
@@ -879,7 +879,7 @@ void print_device_chunks(int fd, u64 devid, u64 total_size,
|
||||
}
|
||||
printf(" Unallocated: %*s%10s\n",
|
||||
(int)(20 - strlen("Unallocated")), "",
|
||||
- df_pretty_sizes(total_size - allocated, mode));
|
||||
+ df_pretty_sizes(devinfo->size - allocated, mode));
|
||||
}
|
||||
|
||||
void print_device_sizes(int fd, struct device_info *devinfo, int mode)
|
||||
diff --git a/cmds-fi-disk_usage.h b/cmds-fi-disk_usage.h
|
||||
index 79cc2a115bc5..dbc2a10f31eb 100644
|
||||
--- a/cmds-fi-disk_usage.h
|
||||
+++ b/cmds-fi-disk_usage.h
|
||||
@@ -50,7 +50,7 @@ int load_device_info(int fd, struct device_info **device_info_ptr,
|
||||
int *device_info_count);
|
||||
int load_chunk_info(int fd, struct chunk_info **info_ptr, int *info_count);
|
||||
char *df_pretty_sizes(u64 size, int mode);
|
||||
-void print_device_chunks(int fd, u64 devid, u64 total_size,
|
||||
+void print_device_chunks(int fd, struct device_info *devinfo,
|
||||
struct chunk_info *chunks_info_ptr,
|
||||
int chunks_info_count, int mode);
|
||||
void print_device_sizes(int fd, struct device_info *devinfo, int mode);
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,107 +0,0 @@
|
||||
From d8f3097050e2b7545aed2119e39e9763f21923a3 Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Fri, 25 Apr 2014 17:24:40 +0200
|
||||
Subject: [PATCH 15/42] btrfs-progs: add section of overall filesystem usage
|
||||
|
||||
The 'fi usage' lacks an overall report, this used to be in the enhanced
|
||||
df command. Add it back.
|
||||
|
||||
Sample:
|
||||
Overall:
|
||||
Device size: 35.00GiB
|
||||
Device allocated: 8.07GiB
|
||||
Device unallocated: 26.93GiB
|
||||
Used: 1.12MiB
|
||||
Free (Estimated): 17.57GiB (Max: 30.98GiB, min: 17.52GiB)
|
||||
Data to device ratio: 50 %
|
||||
...
|
||||
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-fi-disk_usage.c | 25 +++++++++++++------------
|
||||
1 file changed, 13 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index 0ee6e6bb5dc4..92402bea314c 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -302,8 +302,6 @@ static struct btrfs_ioctl_space_args *load_space_info(int fd, char *path)
|
||||
return sargs;
|
||||
}
|
||||
|
||||
-/* Not used, keep for later */
|
||||
-#if 0
|
||||
/*
|
||||
* This function computes the space occuped by a *single* RAID5/RAID6 chunk.
|
||||
* The computation is performed on the basis of the number of stripes
|
||||
@@ -331,7 +329,6 @@ static int get_raid56_used(int fd, u64 *raid5_used, u64 *raid6_used)
|
||||
free(info_ptr);
|
||||
|
||||
return 0;
|
||||
-
|
||||
}
|
||||
|
||||
static int _cmd_disk_free(int fd, char *path, int mode)
|
||||
@@ -416,22 +413,24 @@ static int _cmd_disk_free(int fd, char *path, int mode)
|
||||
else
|
||||
width = 18;
|
||||
|
||||
- printf("Disk size:\t\t%*s\n", width,
|
||||
+ printf("Overall:\n");
|
||||
+
|
||||
+ printf(" Device size:\t\t%*s\n", width,
|
||||
df_pretty_sizes(total_disk, mode));
|
||||
- printf("Disk allocated:\t\t%*s\n", width,
|
||||
+ printf(" Device allocated:\t\t%*s\n", width,
|
||||
df_pretty_sizes(total_chunks, mode));
|
||||
- printf("Disk unallocated:\t%*s\n", width,
|
||||
+ printf(" Device unallocated:\t\t%*s\n", width,
|
||||
df_pretty_sizes(total_disk-total_chunks, mode));
|
||||
- printf("Used:\t\t\t%*s\n", width,
|
||||
+ printf(" Used:\t\t\t%*s\n", width,
|
||||
df_pretty_sizes(total_used, mode));
|
||||
- printf("Free (Estimated):\t%*s\t(",
|
||||
+ printf(" Free (Estimated):\t\t%*s\t(",
|
||||
width,
|
||||
df_pretty_sizes((u64)(K*total_disk-total_used), mode));
|
||||
printf("Max: %s, ",
|
||||
df_pretty_sizes(total_disk-total_chunks+total_free, mode));
|
||||
printf("min: %s)\n",
|
||||
df_pretty_sizes((total_disk-total_chunks)/2+total_free, mode));
|
||||
- printf("Data to disk ratio:\t%*.0f %%\n",
|
||||
+ printf(" Data to device ratio:\t%*.0f %%\n",
|
||||
width-2, K*100);
|
||||
|
||||
exit:
|
||||
@@ -441,7 +440,6 @@ exit:
|
||||
|
||||
return ret;
|
||||
}
|
||||
-#endif
|
||||
|
||||
/*
|
||||
* Helper to sort the device_info structure
|
||||
@@ -826,8 +824,6 @@ int cmd_filesystem_usage(int argc, char **argv)
|
||||
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) {
|
||||
@@ -835,6 +831,11 @@ int cmd_filesystem_usage(int argc, char **argv)
|
||||
argv[1]);
|
||||
return 12;
|
||||
}
|
||||
+ if (more_than_one)
|
||||
+ printf("\n");
|
||||
+
|
||||
+ r = _cmd_disk_free(fd, argv[i], flags);
|
||||
+ printf("\n");
|
||||
r = _cmd_filesystem_usage(fd, argv[i], flags, tabular);
|
||||
close_file_or_dir(fd, dirstream);
|
||||
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,372 +0,0 @@
|
||||
From 5f40eaf09d3c21a6422bc03639a46f4a4087f867 Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Fri, 25 Apr 2014 19:39:11 +0200
|
||||
Subject: [PATCH 16/42] btrfs-progs: cleanup filesystem/device usage code
|
||||
|
||||
The main point of this is to load the device and chunk infos at one
|
||||
place and pass down to the printers. The EPERM is handled separately, in
|
||||
case kernel does not give us all the information about chunks or
|
||||
devices, but we want to warn and print at least something.
|
||||
|
||||
For non-root users, 'filesystem usage' prints only the overall stats and
|
||||
warns about RAID5/6.
|
||||
|
||||
The sole cleanup changes affect mostly the modified code and the related
|
||||
functions, should be reasonably small.
|
||||
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-device.c | 31 +++++-----
|
||||
cmds-fi-disk_usage.c | 163 +++++++++++++++++++++++++++------------------------
|
||||
cmds-fi-disk_usage.h | 5 +-
|
||||
3 files changed, 105 insertions(+), 94 deletions(-)
|
||||
|
||||
diff --git a/cmds-device.c b/cmds-device.c
|
||||
index 1de7f007ed43..9ab60bcafedc 100644
|
||||
--- a/cmds-device.c
|
||||
+++ b/cmds-device.c
|
||||
@@ -474,31 +474,29 @@ static int _cmd_device_usage(int fd, char *path, int mode)
|
||||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
- int info_count = 0;
|
||||
- struct chunk_info *info_ptr = 0;
|
||||
- struct device_info *device_info_ptr = 0;
|
||||
- int device_info_count = 0;
|
||||
+ struct chunk_info *chunkinfo = NULL;
|
||||
+ struct device_info *devinfo = NULL;
|
||||
+ int chunkcount = 0;
|
||||
+ int devcount = 0;
|
||||
|
||||
- if (load_chunk_info(fd, &info_ptr, &info_count) ||
|
||||
- load_device_info(fd, &device_info_ptr, &device_info_count)) {
|
||||
+ ret = load_chunk_and_device_info(fd, &chunkinfo, &chunkcount, &devinfo,
|
||||
+ &devcount);
|
||||
+ if (ret) {
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- for (i = 0; i < device_info_count; i++) {
|
||||
- printf("%s, ID: %llu\n", device_info_ptr[i].path,
|
||||
- device_info_ptr[i].devid);
|
||||
- print_device_sizes(fd, &device_info_ptr[i], mode);
|
||||
- print_device_chunks(fd, &device_info_ptr[i],
|
||||
- info_ptr, info_count, mode);
|
||||
+ for (i = 0; i < devcount; i++) {
|
||||
+ printf("%s, ID: %llu\n", devinfo[i].path, devinfo[i].devid);
|
||||
+ print_device_sizes(fd, &devinfo[i], mode);
|
||||
+ print_device_chunks(fd, &devinfo[i], chunkinfo, chunkcount,
|
||||
+ mode);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
exit:
|
||||
- if (device_info_ptr)
|
||||
- free(device_info_ptr);
|
||||
- if (info_ptr)
|
||||
- free(info_ptr);
|
||||
+ free(devinfo);
|
||||
+ free(chunkinfo);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -540,6 +538,7 @@ int cmd_device_usage(int argc, char **argv)
|
||||
argv[1]);
|
||||
return 12;
|
||||
}
|
||||
+
|
||||
r = _cmd_device_usage(fd, argv[i], flags);
|
||||
close_file_or_dir(fd, dirstream);
|
||||
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index 92402bea314c..3be0e6173eec 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -141,7 +141,7 @@ static int cmp_chunk_info(const void *a, const void *b)
|
||||
((struct chunk_info *)b)->type);
|
||||
}
|
||||
|
||||
-int load_chunk_info(int fd, struct chunk_info **info_ptr, int *info_count)
|
||||
+static int load_chunk_info(int fd, struct chunk_info **info_ptr, int *info_count)
|
||||
{
|
||||
int ret;
|
||||
struct btrfs_ioctl_search_args args;
|
||||
@@ -172,11 +172,8 @@ int load_chunk_info(int fd, struct chunk_info **info_ptr, int *info_count)
|
||||
while (1) {
|
||||
ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
|
||||
e = errno;
|
||||
- if (ret == -EPERM) {
|
||||
- fprintf(stderr,
|
||||
- "ERROR: can't read detailed chunk info from ioctl(TREE_SEARCH), run as root\n");
|
||||
- return 0;
|
||||
- }
|
||||
+ if (ret == -EPERM)
|
||||
+ return ret;
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr,
|
||||
@@ -308,30 +305,23 @@ static struct btrfs_ioctl_space_args *load_space_info(int fd, char *path)
|
||||
* which compose the chunk, which could be different from the number of devices
|
||||
* if a disk is added later.
|
||||
*/
|
||||
-static int get_raid56_used(int fd, u64 *raid5_used, u64 *raid6_used)
|
||||
+static void get_raid56_used(int fd, struct chunk_info *chunks, int chunkcount,
|
||||
+ u64 *raid5_used, u64 *raid6_used)
|
||||
{
|
||||
- struct chunk_info *info_ptr=0, *p;
|
||||
- int info_count=0;
|
||||
- int ret;
|
||||
-
|
||||
- *raid5_used = *raid6_used =0;
|
||||
-
|
||||
- ret = load_chunk_info(fd, &info_ptr, &info_count);
|
||||
- if( ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- for ( p = info_ptr; info_count ; info_count--, p++ ) {
|
||||
- if (p->type & BTRFS_BLOCK_GROUP_RAID5)
|
||||
- (*raid5_used) += p->size / (p->num_stripes -1);
|
||||
- if (p->type & BTRFS_BLOCK_GROUP_RAID6)
|
||||
- (*raid6_used) += p->size / (p->num_stripes -2);
|
||||
+ *raid5_used = 0;
|
||||
+ *raid6_used = 0;
|
||||
+
|
||||
+ while (chunkcount-- > 0) {
|
||||
+ if (chunks->type & BTRFS_BLOCK_GROUP_RAID5)
|
||||
+ (*raid5_used) += chunks->size / (chunks->num_stripes - 1);
|
||||
+ if (chunks->type & BTRFS_BLOCK_GROUP_RAID6)
|
||||
+ (*raid6_used) += chunks->size / (chunks->num_stripes - 2);
|
||||
}
|
||||
- free(info_ptr);
|
||||
-
|
||||
- return 0;
|
||||
}
|
||||
|
||||
-static int _cmd_disk_free(int fd, char *path, int mode)
|
||||
+static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
|
||||
+ int chunkcount, struct device_info *devinfo, int devcount,
|
||||
+ char *path, int mode)
|
||||
{
|
||||
struct btrfs_ioctl_space_args *sargs = 0;
|
||||
int i;
|
||||
@@ -360,15 +350,11 @@ static int _cmd_disk_free(int fd, char *path, int mode)
|
||||
ret = 19;
|
||||
goto exit;
|
||||
}
|
||||
- if (get_raid56_used(fd, &raid5_used, &raid6_used) < 0) {
|
||||
- fprintf(stderr,
|
||||
- "ERROR: couldn't get space info on '%s'\n",
|
||||
- path );
|
||||
- ret = 20;
|
||||
- goto exit;
|
||||
- }
|
||||
+ get_raid56_used(fd, chunkinfo, chunkcount, &raid5_used, &raid6_used);
|
||||
|
||||
- total_chunks = total_used = total_free = 0;
|
||||
+ total_chunks = 0;
|
||||
+ total_used = 0;
|
||||
+ total_free = 0;
|
||||
|
||||
for (i = 0; i < sargs->total_spaces; i++) {
|
||||
float ratio = 1;
|
||||
@@ -453,7 +439,7 @@ static int cmp_device_info(const void *a, const void *b)
|
||||
/*
|
||||
* This function loads the device_info structure and put them in an array
|
||||
*/
|
||||
-int load_device_info(int fd, struct device_info **device_info_ptr,
|
||||
+static int load_device_info(int fd, struct device_info **device_info_ptr,
|
||||
int *device_info_count)
|
||||
{
|
||||
int ret, i, ndevs;
|
||||
@@ -465,10 +451,8 @@ int load_device_info(int fd, struct device_info **device_info_ptr,
|
||||
*device_info_ptr = 0;
|
||||
|
||||
ret = ioctl(fd, BTRFS_IOC_FS_INFO, &fi_args);
|
||||
- if (ret == -EPERM) {
|
||||
- fprintf(stderr, "ERROR: can't get filesystem info from ioctl(FS_INFO), run as root\n");
|
||||
- return -1;
|
||||
- }
|
||||
+ if (ret == -EPERM)
|
||||
+ return ret;
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "ERROR: cannot get filesystem info\n");
|
||||
return -1;
|
||||
@@ -512,6 +496,29 @@ int load_device_info(int fd, struct device_info **device_info_ptr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int load_chunk_and_device_info(int fd, struct chunk_info **chunkinfo,
|
||||
+ int *chunkcount, struct device_info **devinfo, int *devcount)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = load_chunk_info(fd, chunkinfo, chunkcount);
|
||||
+ if (ret == -EPERM) {
|
||||
+ fprintf(stderr,
|
||||
+ "WARNING: can't read detailed chunk info, RAID5/6 numbers will be incorrect, run as root\n");
|
||||
+ } else if (ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = load_device_info(fd, devinfo, devcount);
|
||||
+ if (ret == -EPERM) {
|
||||
+ fprintf(stderr,
|
||||
+ "WARNING: can't get filesystem info from ioctl(FS_INFO), run as root\n");
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* This function computes the size of a chunk in a disk
|
||||
*/
|
||||
@@ -744,43 +751,32 @@ static void _cmd_filesystem_usage_linear(int mode,
|
||||
mode);
|
||||
}
|
||||
|
||||
-static int _cmd_filesystem_usage(int fd, char *path, int mode, int tabular)
|
||||
+static int print_filesystem_usage_by_chunk(int fd,
|
||||
+ struct chunk_info *chunkinfo, int chunkcount,
|
||||
+ struct device_info *devinfo, int devcount,
|
||||
+ char *path, int mode, int tabular)
|
||||
{
|
||||
- struct btrfs_ioctl_space_args *sargs = 0;
|
||||
- int info_count = 0;
|
||||
- struct chunk_info *info_ptr = 0;
|
||||
- struct device_info *device_info_ptr = 0;
|
||||
- int device_info_count = 0;
|
||||
+ struct btrfs_ioctl_space_args *sargs;
|
||||
int ret = 0;
|
||||
|
||||
- if (load_chunk_info(fd, &info_ptr, &info_count) ||
|
||||
- load_device_info(fd, &device_info_ptr, &device_info_count)) {
|
||||
- ret = -1;
|
||||
- goto exit;
|
||||
- }
|
||||
+ if (!chunkinfo)
|
||||
+ return 0;
|
||||
|
||||
- if ((sargs = load_space_info(fd, path)) == NULL) {
|
||||
- ret = -1;
|
||||
+ sargs = load_space_info(fd, path);
|
||||
+ if (!sargs) {
|
||||
+ ret = 1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (tabular)
|
||||
- _cmd_filesystem_usage_tabular(mode, sargs,
|
||||
- info_ptr, info_count,
|
||||
- device_info_ptr, device_info_count);
|
||||
+ _cmd_filesystem_usage_tabular(mode, sargs, chunkinfo,
|
||||
+ chunkcount, devinfo, devcount);
|
||||
else
|
||||
- _cmd_filesystem_usage_linear(mode, sargs,
|
||||
- info_ptr, info_count,
|
||||
- device_info_ptr, device_info_count);
|
||||
+ _cmd_filesystem_usage_linear(mode, sargs, chunkinfo,
|
||||
+ chunkcount, devinfo, devcount);
|
||||
|
||||
exit:
|
||||
-
|
||||
- if (sargs)
|
||||
- free(sargs);
|
||||
- if (device_info_ptr)
|
||||
- free(device_info_ptr);
|
||||
- if (info_ptr)
|
||||
- free(info_ptr);
|
||||
+ free(sargs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -796,16 +792,17 @@ const char * const cmd_filesystem_usage_usage[] = {
|
||||
|
||||
int cmd_filesystem_usage(int argc, char **argv)
|
||||
{
|
||||
-
|
||||
int flags = DF_HUMAN_UNIT;
|
||||
int i, more_than_one = 0;
|
||||
int tabular = 0;
|
||||
|
||||
optind = 1;
|
||||
while (1) {
|
||||
- char c = getopt(argc, argv, "bt");
|
||||
+ int c = getopt(argc, argv, "bt");
|
||||
+
|
||||
if (c < 0)
|
||||
break;
|
||||
+
|
||||
switch (c) {
|
||||
case 'b':
|
||||
flags &= ~DF_HUMAN_UNIT;
|
||||
@@ -821,9 +818,14 @@ int cmd_filesystem_usage(int argc, char **argv)
|
||||
if (check_argc_min(argc - optind, 1))
|
||||
usage(cmd_filesystem_usage_usage);
|
||||
|
||||
- for (i = optind; i < argc ; i++) {
|
||||
- int r, fd;
|
||||
- DIR *dirstream = NULL;
|
||||
+ for (i = optind; i < argc; i++) {
|
||||
+ int ret;
|
||||
+ int fd;
|
||||
+ DIR *dirstream = NULL;
|
||||
+ struct chunk_info *chunkinfo = NULL;
|
||||
+ struct device_info *devinfo = NULL;
|
||||
+ int chunkcount = 0;
|
||||
+ int devcount = 0;
|
||||
|
||||
fd = open_file_or_dir(argv[i], &dirstream);
|
||||
if (fd < 0) {
|
||||
@@ -834,15 +836,26 @@ int cmd_filesystem_usage(int argc, char **argv)
|
||||
if (more_than_one)
|
||||
printf("\n");
|
||||
|
||||
- r = _cmd_disk_free(fd, argv[i], flags);
|
||||
+ ret = load_chunk_and_device_info(fd, &chunkinfo, &chunkcount,
|
||||
+ &devinfo, &devcount);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ ret = print_filesystem_usage_overall(fd, chunkinfo, chunkcount,
|
||||
+ devinfo, devcount, argv[i], flags);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
printf("\n");
|
||||
- r = _cmd_filesystem_usage(fd, argv[i], flags, tabular);
|
||||
+ ret = print_filesystem_usage_by_chunk(fd, chunkinfo, chunkcount,
|
||||
+ devinfo, devcount, argv[i], flags, tabular);
|
||||
+cleanup:
|
||||
close_file_or_dir(fd, dirstream);
|
||||
+ free(chunkinfo);
|
||||
+ free(devinfo);
|
||||
|
||||
- if (r)
|
||||
- return r;
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
more_than_one = 1;
|
||||
-
|
||||
}
|
||||
|
||||
return 0;
|
||||
diff --git a/cmds-fi-disk_usage.h b/cmds-fi-disk_usage.h
|
||||
index dbc2a10f31eb..0779defc71db 100644
|
||||
--- a/cmds-fi-disk_usage.h
|
||||
+++ b/cmds-fi-disk_usage.h
|
||||
@@ -46,9 +46,8 @@ struct chunk_info {
|
||||
u64 num_stripes;
|
||||
};
|
||||
|
||||
-int load_device_info(int fd, struct device_info **device_info_ptr,
|
||||
- int *device_info_count);
|
||||
-int load_chunk_info(int fd, struct chunk_info **info_ptr, int *info_count);
|
||||
+int load_chunk_and_device_info(int fd, struct chunk_info **chunkinfo,
|
||||
+ int *chunkcount, struct device_info **devinfo, int *devcount);
|
||||
char *df_pretty_sizes(u64 size, int mode);
|
||||
void print_device_chunks(int fd, struct device_info *devinfo,
|
||||
struct chunk_info *chunks_info_ptr,
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,296 +0,0 @@
|
||||
From 5a16b93f94cfdb7b2028bc9498dd33131254e164 Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Thu, 26 Jun 2014 15:42:24 +0200
|
||||
Subject: [PATCH 25/42] btrfs-progs: rework calculations of fi usage
|
||||
|
||||
This patch reworks the basic calculations of 'fi usage'. It does not address
|
||||
all problems but should make the code more prepared to do so.
|
||||
|
||||
The original code tries to estimate the free space that could lead to negative
|
||||
numbers for some raid profiles:
|
||||
|
||||
Data, RAID1: total=147.00GiB, used=141.92GiB
|
||||
System, RAID1: total=32.00MiB, used=36.00KiB
|
||||
Metadata, RAID1: total=2.00GiB, used=1.17GiB
|
||||
GlobalReserve, single: total=404.00MiB, used=0.00B
|
||||
|
||||
Overall:
|
||||
Device size: 279.46GiB
|
||||
Device allocated: 298.06GiB
|
||||
Device unallocated: 16.00EiB
|
||||
Used: 286.18GiB
|
||||
Free (estimated): 8.00EiB (min: 8.00EiB)
|
||||
Data ratio: 2.00
|
||||
Metadata ratio: 2.00
|
||||
Global reserve: 404.00MiB (used: 0.00B)
|
||||
|
||||
Eg. "Device size" - "Device allocated" = negative number or a very large
|
||||
positive, hence the EiB values.
|
||||
|
||||
There are logical and raw numbers multiplied by ratios mixed together,
|
||||
so the new code makes it explicit which kind is being used. The data and
|
||||
metadata ratios are calculated separately.
|
||||
|
||||
Output after this patch will look like:
|
||||
|
||||
Overall:
|
||||
Device size: 558.92GiB
|
||||
Device allocated: 298.06GiB
|
||||
Device unallocated: 260.86GiB
|
||||
Used: 286.18GiB
|
||||
Free (estimated): 135.51GiB (min: 135.51GiB)
|
||||
Data ratio: 2.00
|
||||
Metadata ratio: 2.00
|
||||
Global reserve: 404.00MiB (used: 0.00B)
|
||||
|
||||
Data,RAID1: Size:147.00GiB, Used:141.92GiB
|
||||
/dev/sdc 147.00GiB
|
||||
/dev/sdd 147.00GiB
|
||||
|
||||
Metadata,RAID1: Size:2.00GiB, Used:1.17GiB
|
||||
/dev/sdc 2.00GiB
|
||||
/dev/sdd 2.00GiB
|
||||
|
||||
System,RAID1: Size:32.00MiB, Used:36.00KiB
|
||||
/dev/sdc 32.00MiB
|
||||
/dev/sdd 32.00MiB
|
||||
|
||||
Unallocated:
|
||||
/dev/sdc 130.43GiB
|
||||
/dev/sdd 130.43GiB
|
||||
|
||||
Changes:
|
||||
* Device size is now the raw size, same for the following three
|
||||
* Free is the logical size
|
||||
* Max/min were reduced to just min
|
||||
|
||||
Filesystem Size Used Avail Use% Mounted on
|
||||
/dev/sdc 280G 144G 141G 51% /mnt/sdc
|
||||
|
||||
The difference between Avail and Free is there because userspace tool does a
|
||||
different guesswork than kernel.
|
||||
|
||||
Issues not addressed by this patch:
|
||||
* RAID56 profiles are not handled
|
||||
* mixed profiles are not handled
|
||||
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-fi-disk_usage.c | 151 +++++++++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 103 insertions(+), 48 deletions(-)
|
||||
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index d95024faf061..6a33b5d1da51 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -306,6 +306,7 @@ static void get_raid56_used(int fd, struct chunk_info *chunks, int chunkcount,
|
||||
}
|
||||
}
|
||||
|
||||
+#define MIN_UNALOCATED_THRESH (16 * 1024 * 1024)
|
||||
static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
|
||||
int chunkcount, struct device_info *devinfo, int devcount,
|
||||
char *path, int mode)
|
||||
@@ -313,16 +314,33 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
|
||||
struct btrfs_ioctl_space_args *sargs = 0;
|
||||
int i;
|
||||
int ret = 0;
|
||||
- int e, width;
|
||||
- u64 total_disk; /* filesystem size == sum of
|
||||
- device sizes */
|
||||
- u64 total_chunks; /* sum of chunks sizes on disk(s) */
|
||||
- u64 total_used; /* logical space used */
|
||||
- u64 total_free; /* logical space un-used */
|
||||
- double K;
|
||||
- u64 raid5_used, raid6_used;
|
||||
- u64 global_reserve;
|
||||
- u64 global_reserve_used;
|
||||
+ int width = 10; /* default 10 for human units */
|
||||
+ /*
|
||||
+ * r_* prefix is for raw data
|
||||
+ * l_* is for logical
|
||||
+ */
|
||||
+ u64 r_total_size = 0; /* filesystem size, sum of device sizes */
|
||||
+ u64 r_total_chunks = 0; /* sum of chunks sizes on disk(s) */
|
||||
+ u64 r_total_used = 0;
|
||||
+ u64 r_total_unused = 0;
|
||||
+ u64 r_data_used = 0;
|
||||
+ u64 r_data_chunks = 0;
|
||||
+ u64 l_data_chunks = 0;
|
||||
+ u64 r_metadata_used = 0;
|
||||
+ u64 r_metadata_chunks = 0;
|
||||
+ u64 l_metadata_chunks = 0;
|
||||
+ u64 r_system_used = 0;
|
||||
+ u64 r_system_chunks = 0;
|
||||
+ double data_ratio;
|
||||
+ double metadata_ratio;
|
||||
+ /* logical */
|
||||
+ u64 raid5_used = 0;
|
||||
+ u64 raid6_used = 0;
|
||||
+ u64 l_global_reserve = 0;
|
||||
+ u64 l_global_reserve_used = 0;
|
||||
+ u64 free_estimated = 0;
|
||||
+ u64 free_min = 0;
|
||||
+ int max_data_ratio = 1;
|
||||
|
||||
sargs = load_space_info(fd, path);
|
||||
if (!sargs) {
|
||||
@@ -330,27 +348,22 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- total_disk = disk_size(path);
|
||||
- e = errno;
|
||||
- if (total_disk == 0) {
|
||||
+ r_total_size = 0;
|
||||
+ for (i = 0; i < devcount; i++)
|
||||
+ r_total_size += devinfo[i].device_size;
|
||||
+
|
||||
+ if (r_total_size == 0) {
|
||||
fprintf(stderr,
|
||||
"ERROR: couldn't get space info on '%s' - %s\n",
|
||||
- path, strerror(e));
|
||||
+ path, strerror(errno));
|
||||
|
||||
ret = 1;
|
||||
goto exit;
|
||||
}
|
||||
get_raid56_used(fd, chunkinfo, chunkcount, &raid5_used, &raid6_used);
|
||||
|
||||
- total_chunks = 0;
|
||||
- total_used = 0;
|
||||
- total_free = 0;
|
||||
- global_reserve = 0;
|
||||
- global_reserve_used = 0;
|
||||
-
|
||||
for (i = 0; i < sargs->total_spaces; i++) {
|
||||
- float ratio = 1;
|
||||
- u64 allocated;
|
||||
+ int ratio;
|
||||
u64 flags = sargs->spaces[i].flags;
|
||||
|
||||
/*
|
||||
@@ -372,52 +385,94 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
|
||||
else
|
||||
ratio = 1;
|
||||
|
||||
+ if (!ratio)
|
||||
+ fprintf(stderr, "WARNING: RAID56 detected, not implemented\n");
|
||||
+
|
||||
+ if (ratio > max_data_ratio)
|
||||
+ max_data_ratio = ratio;
|
||||
+
|
||||
if (flags & BTRFS_SPACE_INFO_GLOBAL_RSV) {
|
||||
- global_reserve = sargs->spaces[i].total_bytes;
|
||||
- global_reserve_used = sargs->spaces[i].used_bytes;
|
||||
+ l_global_reserve = sargs->spaces[i].total_bytes;
|
||||
+ l_global_reserve_used = sargs->spaces[i].used_bytes;
|
||||
+ }
|
||||
+ if ((flags & (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA))
|
||||
+ == (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA)) {
|
||||
+ fprintf(stderr, "WARNING: MIXED blockgroups not handled\n");
|
||||
}
|
||||
|
||||
- allocated = sargs->spaces[i].total_bytes * ratio;
|
||||
+ if (flags & BTRFS_BLOCK_GROUP_DATA) {
|
||||
+ r_data_used += sargs->spaces[i].used_bytes * ratio;
|
||||
+ r_data_chunks += sargs->spaces[i].total_bytes * ratio;
|
||||
+ l_data_chunks += sargs->spaces[i].total_bytes;
|
||||
+ }
|
||||
+ if (flags & BTRFS_BLOCK_GROUP_METADATA) {
|
||||
+ r_metadata_used += sargs->spaces[i].used_bytes * ratio;
|
||||
+ r_metadata_chunks += sargs->spaces[i].total_bytes * ratio;
|
||||
+ l_metadata_chunks += sargs->spaces[i].total_bytes;
|
||||
+ }
|
||||
+ if (flags & BTRFS_BLOCK_GROUP_SYSTEM) {
|
||||
+ r_system_used += sargs->spaces[i].used_bytes * ratio;
|
||||
+ r_system_chunks += sargs->spaces[i].total_bytes * ratio;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- total_chunks += allocated;
|
||||
- total_used += sargs->spaces[i].used_bytes;
|
||||
- total_free += (sargs->spaces[i].total_bytes -
|
||||
- sargs->spaces[i].used_bytes);
|
||||
+ r_total_chunks = r_data_chunks + r_metadata_chunks + r_system_chunks;
|
||||
+ r_total_used = r_data_used + r_metadata_used + r_system_used;
|
||||
+ r_total_unused = r_total_size - r_total_chunks;
|
||||
|
||||
- }
|
||||
+ /* Raw / Logical = raid factor, >= 1 */
|
||||
+ data_ratio = (double)r_data_chunks / l_data_chunks;
|
||||
+ metadata_ratio = (double)r_metadata_chunks / l_metadata_chunks;
|
||||
|
||||
+#if 0
|
||||
/* add the raid5/6 allocated space */
|
||||
total_chunks += raid5_used + raid6_used;
|
||||
+#endif
|
||||
|
||||
- K = ((double)total_used + (double)total_free) / (double)total_chunks;
|
||||
+ /*
|
||||
+ * We're able to fill at least DATA for the unused space
|
||||
+ *
|
||||
+ * With mixed raid levels, this gives a rough estimate but more
|
||||
+ * accurate than just counting the logical free space
|
||||
+ * (l_data_chunks - l_data_used)
|
||||
+ *
|
||||
+ * In non-mixed case there's no difference.
|
||||
+ */
|
||||
+ free_estimated = (r_data_chunks - r_data_used) / data_ratio;
|
||||
+ free_min = free_estimated;
|
||||
+
|
||||
+ /* Chop unallocatable space */
|
||||
+ /* FIXME: must be applied per device */
|
||||
+ if (r_total_unused >= MIN_UNALOCATED_THRESH) {
|
||||
+ free_estimated += r_total_unused / data_ratio;
|
||||
+ /* Match the calculation of 'df', use the highest raid ratio */
|
||||
+ free_min += r_total_unused / max_data_ratio;
|
||||
+ }
|
||||
|
||||
- if (mode == UNITS_HUMAN)
|
||||
- width = 10;
|
||||
- else
|
||||
+ if (mode != UNITS_HUMAN)
|
||||
width = 18;
|
||||
|
||||
printf("Overall:\n");
|
||||
|
||||
printf(" Device size:\t\t%*s\n", width,
|
||||
- pretty_size_mode(total_disk, mode));
|
||||
+ pretty_size_mode(r_total_size, mode));
|
||||
printf(" Device allocated:\t\t%*s\n", width,
|
||||
- pretty_size_mode(total_chunks, mode));
|
||||
+ pretty_size_mode(r_total_chunks, mode));
|
||||
printf(" Device unallocated:\t\t%*s\n", width,
|
||||
- pretty_size_mode(total_disk - total_chunks, mode));
|
||||
+ pretty_size_mode(r_total_unused, mode));
|
||||
printf(" Used:\t\t\t%*s\n", width,
|
||||
- pretty_size_mode(total_used, mode));
|
||||
- printf(" Free (Estimated):\t\t%*s\t(",
|
||||
+ pretty_size_mode(r_total_used, mode));
|
||||
+ printf(" Free (estimated):\t\t%*s\t(",
|
||||
width,
|
||||
- pretty_size_mode((u64)(K * total_disk - total_used), mode));
|
||||
- printf("Max: %s, ",
|
||||
- pretty_size_mode(total_disk - total_chunks + total_free, mode));
|
||||
- printf("min: %s)\n",
|
||||
- pretty_size_mode((total_disk-total_chunks) / 2 + total_free, mode));
|
||||
- printf(" Data to device ratio:\t%*.0f %%\n",
|
||||
- width - 2, K * 100);
|
||||
+ pretty_size_mode(free_estimated, mode));
|
||||
+ printf("min: %s)\n", pretty_size_mode(free_min, mode));
|
||||
+ printf(" Data ratio:\t\t\t%*.2f\n",
|
||||
+ width, data_ratio);
|
||||
+ printf(" Metadata ratio:\t\t%*.2f\n",
|
||||
+ width, metadata_ratio);
|
||||
printf(" Global reserve:\t\t%*s\t(used: %s)\n", width,
|
||||
- pretty_size_mode(global_reserve, mode),
|
||||
- pretty_size_mode(global_reserve_used, mode));
|
||||
+ pretty_size_mode(l_global_reserve, mode),
|
||||
+ pretty_size_mode(l_global_reserve_used, mode));
|
||||
|
||||
exit:
|
||||
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,268 +0,0 @@
|
||||
From b6789cae1b21f0a8ceec5e60142bfac8a80c1278 Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Mon, 28 Apr 2014 18:13:16 +0200
|
||||
Subject: [PATCH 17/42] btrfs-progs: replace df_pretty_sizes with
|
||||
pretty_size_mode
|
||||
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-device.c | 8 +++----
|
||||
cmds-fi-disk_usage.c | 68 ++++++++++++++++++++--------------------------------
|
||||
cmds-fi-disk_usage.h | 3 ---
|
||||
3 files changed, 30 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/cmds-device.c b/cmds-device.c
|
||||
index 9ab60bcafedc..e14eaf61296b 100644
|
||||
--- a/cmds-device.c
|
||||
+++ b/cmds-device.c
|
||||
@@ -504,19 +504,19 @@ exit:
|
||||
int cmd_device_usage(int argc, char **argv)
|
||||
{
|
||||
|
||||
- int flags = DF_HUMAN_UNIT;
|
||||
+ int mode = UNITS_HUMAN;
|
||||
int i, more_than_one = 0;
|
||||
|
||||
optind = 1;
|
||||
while (1) {
|
||||
- char c = getopt(argc, argv, "b");
|
||||
+ int c = getopt(argc, argv, "b");
|
||||
|
||||
if (c < 0)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'b':
|
||||
- flags &= ~DF_HUMAN_UNIT;
|
||||
+ mode = UNITS_RAW;
|
||||
break;
|
||||
default:
|
||||
usage(cmd_device_usage_usage);
|
||||
@@ -539,7 +539,7 @@ int cmd_device_usage(int argc, char **argv)
|
||||
return 12;
|
||||
}
|
||||
|
||||
- r = _cmd_device_usage(fd, argv[i], flags);
|
||||
+ r = _cmd_device_usage(fd, argv[i], mode);
|
||||
close_file_or_dir(fd, dirstream);
|
||||
|
||||
if (r)
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index 3be0e6173eec..579230a79d85 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -32,22 +32,6 @@
|
||||
#include "version.h"
|
||||
|
||||
/*
|
||||
- * Pretty print the size
|
||||
- * PAY ATTENTION: it return a statically buffer
|
||||
- */
|
||||
-char *df_pretty_sizes(u64 size, int mode)
|
||||
-{
|
||||
- static char buf[30];
|
||||
-
|
||||
- if (mode & DF_HUMAN_UNIT)
|
||||
- (void)pretty_size_snprintf(size, buf, sizeof(buf), UNITS_DEFAULT);
|
||||
- else
|
||||
- sprintf(buf, "%llu", size);
|
||||
-
|
||||
- return buf;
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
* Add the chunk info to the chunk_info list
|
||||
*/
|
||||
static int add_info_to_list(struct chunk_info **info_ptr,
|
||||
@@ -394,7 +378,7 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
|
||||
|
||||
K = ((double)total_used + (double)total_free) / (double)total_chunks;
|
||||
|
||||
- if (mode & DF_HUMAN_UNIT)
|
||||
+ if (mode == UNITS_HUMAN)
|
||||
width = 10;
|
||||
else
|
||||
width = 18;
|
||||
@@ -402,22 +386,22 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
|
||||
printf("Overall:\n");
|
||||
|
||||
printf(" Device size:\t\t%*s\n", width,
|
||||
- df_pretty_sizes(total_disk, mode));
|
||||
+ pretty_size_mode(total_disk, mode));
|
||||
printf(" Device allocated:\t\t%*s\n", width,
|
||||
- df_pretty_sizes(total_chunks, mode));
|
||||
+ pretty_size_mode(total_chunks, mode));
|
||||
printf(" Device unallocated:\t\t%*s\n", width,
|
||||
- df_pretty_sizes(total_disk-total_chunks, mode));
|
||||
+ pretty_size_mode(total_disk - total_chunks, mode));
|
||||
printf(" Used:\t\t\t%*s\n", width,
|
||||
- df_pretty_sizes(total_used, mode));
|
||||
+ pretty_size_mode(total_used, mode));
|
||||
printf(" Free (Estimated):\t\t%*s\t(",
|
||||
width,
|
||||
- df_pretty_sizes((u64)(K*total_disk-total_used), mode));
|
||||
+ pretty_size_mode((u64)(K * total_disk - total_used), mode));
|
||||
printf("Max: %s, ",
|
||||
- df_pretty_sizes(total_disk-total_chunks+total_free, mode));
|
||||
+ pretty_size_mode(total_disk - total_chunks + total_free, mode));
|
||||
printf("min: %s)\n",
|
||||
- df_pretty_sizes((total_disk-total_chunks)/2+total_free, mode));
|
||||
+ pretty_size_mode((total_disk-total_chunks) / 2 + total_free, mode));
|
||||
printf(" Data to device ratio:\t%*.0f %%\n",
|
||||
- width-2, K*100);
|
||||
+ width - 2, K * 100);
|
||||
|
||||
exit:
|
||||
|
||||
@@ -617,7 +601,7 @@ static void _cmd_filesystem_usage_tabular(int mode,
|
||||
|
||||
if (size)
|
||||
table_printf(matrix, col, i+3,
|
||||
- ">%s", df_pretty_sizes(size, mode));
|
||||
+ ">%s", pretty_size_mode(size, mode));
|
||||
else
|
||||
table_printf(matrix, col, i+3, ">-");
|
||||
|
||||
@@ -629,7 +613,7 @@ static void _cmd_filesystem_usage_tabular(int mode,
|
||||
- total_allocated;
|
||||
|
||||
table_printf(matrix, sargs->total_spaces + 1, i + 3,
|
||||
- ">%s", df_pretty_sizes(unused, mode));
|
||||
+ ">%s", pretty_size_mode(unused, mode));
|
||||
total_unused += unused;
|
||||
|
||||
}
|
||||
@@ -641,15 +625,15 @@ static void _cmd_filesystem_usage_tabular(int mode,
|
||||
table_printf(matrix, 0, device_info_count + 4, "<Total");
|
||||
for (i = 0; i < sargs->total_spaces; i++)
|
||||
table_printf(matrix, 1 + i, device_info_count + 4, ">%s",
|
||||
- df_pretty_sizes(sargs->spaces[i].total_bytes, mode));
|
||||
+ pretty_size_mode(sargs->spaces[i].total_bytes, mode));
|
||||
|
||||
table_printf(matrix, sargs->total_spaces + 1, device_info_count + 4,
|
||||
- ">%s", df_pretty_sizes(total_unused, mode));
|
||||
+ ">%s", pretty_size_mode(total_unused, mode));
|
||||
|
||||
table_printf(matrix, 0, device_info_count + 5, "<Used");
|
||||
for (i = 0; i < sargs->total_spaces; i++)
|
||||
table_printf(matrix, 1 + i, device_info_count+5, ">%s",
|
||||
- df_pretty_sizes(sargs->spaces[i].used_bytes, mode));
|
||||
+ pretty_size_mode(sargs->spaces[i].used_bytes, mode));
|
||||
|
||||
table_dump(matrix);
|
||||
table_free(matrix);
|
||||
@@ -675,7 +659,7 @@ static void print_unused(struct chunk_info *info_ptr,
|
||||
|
||||
printf(" %s\t%10s\n",
|
||||
device_info_ptr[i].path,
|
||||
- df_pretty_sizes(device_info_ptr[i].size - total, mode));
|
||||
+ pretty_size_mode(device_info_ptr[i].size - total, mode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -709,7 +693,7 @@ static void print_chunk_device(u64 chunk_type,
|
||||
if (total > 0)
|
||||
printf(" %s\t%10s\n",
|
||||
device_info_ptr[i].path,
|
||||
- df_pretty_sizes(total, mode));
|
||||
+ pretty_size_mode(total, mode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,10 +721,10 @@ static void _cmd_filesystem_usage_linear(int mode,
|
||||
printf("%s,%s: Size:%s, ",
|
||||
description,
|
||||
r_mode,
|
||||
- df_pretty_sizes(sargs->spaces[i].total_bytes ,
|
||||
+ pretty_size_mode(sargs->spaces[i].total_bytes,
|
||||
mode));
|
||||
printf("Used:%s\n",
|
||||
- df_pretty_sizes(sargs->spaces[i].used_bytes, mode));
|
||||
+ pretty_size_mode(sargs->spaces[i].used_bytes, mode));
|
||||
print_chunk_device(flags, info_ptr, info_count,
|
||||
device_info_ptr, device_info_count, mode);
|
||||
printf("\n");
|
||||
@@ -792,7 +776,7 @@ const char * const cmd_filesystem_usage_usage[] = {
|
||||
|
||||
int cmd_filesystem_usage(int argc, char **argv)
|
||||
{
|
||||
- int flags = DF_HUMAN_UNIT;
|
||||
+ int mode = UNITS_HUMAN;
|
||||
int i, more_than_one = 0;
|
||||
int tabular = 0;
|
||||
|
||||
@@ -805,7 +789,7 @@ int cmd_filesystem_usage(int argc, char **argv)
|
||||
|
||||
switch (c) {
|
||||
case 'b':
|
||||
- flags &= ~DF_HUMAN_UNIT;
|
||||
+ mode = UNITS_RAW;
|
||||
break;
|
||||
case 't':
|
||||
tabular = 1;
|
||||
@@ -842,12 +826,12 @@ int cmd_filesystem_usage(int argc, char **argv)
|
||||
goto cleanup;
|
||||
|
||||
ret = print_filesystem_usage_overall(fd, chunkinfo, chunkcount,
|
||||
- devinfo, devcount, argv[i], flags);
|
||||
+ devinfo, devcount, argv[i], mode);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
printf("\n");
|
||||
ret = print_filesystem_usage_by_chunk(fd, chunkinfo, chunkcount,
|
||||
- devinfo, devcount, argv[i], flags, tabular);
|
||||
+ devinfo, devcount, argv[i], mode, tabular);
|
||||
cleanup:
|
||||
close_file_or_dir(fd, dirstream);
|
||||
free(chunkinfo);
|
||||
@@ -886,22 +870,22 @@ void print_device_chunks(int fd, struct device_info *devinfo,
|
||||
description,
|
||||
r_mode,
|
||||
(int)(20 - strlen(description) - strlen(r_mode)), "",
|
||||
- df_pretty_sizes(size, mode));
|
||||
+ pretty_size_mode(size, mode));
|
||||
|
||||
allocated += size;
|
||||
|
||||
}
|
||||
printf(" Unallocated: %*s%10s\n",
|
||||
(int)(20 - strlen("Unallocated")), "",
|
||||
- df_pretty_sizes(devinfo->size - allocated, mode));
|
||||
+ pretty_size_mode(devinfo->size - allocated, mode));
|
||||
}
|
||||
|
||||
void print_device_sizes(int fd, struct device_info *devinfo, int mode)
|
||||
{
|
||||
printf(" Device size: %*s%10s\n",
|
||||
(int)(20 - strlen("Device size")), "",
|
||||
- df_pretty_sizes(devinfo->device_size, mode));
|
||||
+ pretty_size_mode(devinfo->device_size, mode));
|
||||
printf(" FS occupied: %*s%10s\n",
|
||||
(int)(20 - strlen("FS occupied")), "",
|
||||
- df_pretty_sizes(devinfo->size, mode));
|
||||
+ pretty_size_mode(devinfo->size, mode));
|
||||
}
|
||||
diff --git a/cmds-fi-disk_usage.h b/cmds-fi-disk_usage.h
|
||||
index 0779defc71db..8a0c60f011e4 100644
|
||||
--- a/cmds-fi-disk_usage.h
|
||||
+++ b/cmds-fi-disk_usage.h
|
||||
@@ -19,8 +19,6 @@
|
||||
#ifndef __CMDS_FI_DISK_USAGE__
|
||||
#define __CMDS_FI_DISK_USAGE__
|
||||
|
||||
-#define DF_HUMAN_UNIT (1<<0)
|
||||
-
|
||||
extern const char * const cmd_filesystem_usage_usage[];
|
||||
int cmd_filesystem_usage(int argc, char **argv);
|
||||
|
||||
@@ -48,7 +46,6 @@ struct chunk_info {
|
||||
|
||||
int load_chunk_and_device_info(int fd, struct chunk_info **chunkinfo,
|
||||
int *chunkcount, struct device_info **devinfo, int *devcount);
|
||||
-char *df_pretty_sizes(u64 size, int mode);
|
||||
void print_device_chunks(int fd, struct device_info *devinfo,
|
||||
struct chunk_info *chunks_info_ptr,
|
||||
int chunks_info_count, int mode);
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,233 +0,0 @@
|
||||
From 3844fa84722d395a584ed8b331e89dc55361dd90 Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Mon, 28 Apr 2014 18:55:05 +0200
|
||||
Subject: [PATCH 18/42] btrfs-progs: clean up return codes and paths
|
||||
|
||||
Use the common patterns with one return statement at the end, pass down error
|
||||
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-device.c | 27 +++++++++++++--------------
|
||||
cmds-fi-disk_usage.c | 39 +++++++++++++++++++++------------------
|
||||
2 files changed, 34 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/cmds-device.c b/cmds-device.c
|
||||
index e14eaf61296b..a728f2102f5c 100644
|
||||
--- a/cmds-device.c
|
||||
+++ b/cmds-device.c
|
||||
@@ -481,10 +481,8 @@ static int _cmd_device_usage(int fd, char *path, int mode)
|
||||
|
||||
ret = load_chunk_and_device_info(fd, &chunkinfo, &chunkcount, &devinfo,
|
||||
&devcount);
|
||||
- if (ret) {
|
||||
- ret = -1;
|
||||
- goto exit;
|
||||
- }
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
|
||||
for (i = 0; i < devcount; i++) {
|
||||
printf("%s, ID: %llu\n", devinfo[i].path, devinfo[i].devid);
|
||||
@@ -494,7 +492,7 @@ static int _cmd_device_usage(int fd, char *path, int mode)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
-exit:
|
||||
+out:
|
||||
free(devinfo);
|
||||
free(chunkinfo);
|
||||
|
||||
@@ -505,6 +503,7 @@ int cmd_device_usage(int argc, char **argv)
|
||||
{
|
||||
|
||||
int mode = UNITS_HUMAN;
|
||||
+ int ret = 0;
|
||||
int i, more_than_one = 0;
|
||||
|
||||
optind = 1;
|
||||
@@ -527,28 +526,28 @@ int cmd_device_usage(int argc, char **argv)
|
||||
usage(cmd_device_usage_usage);
|
||||
|
||||
for (i = optind; i < argc ; i++) {
|
||||
- int r, fd;
|
||||
+ int 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",
|
||||
+ fprintf(stderr, "ERROR: can't access '%s'\n",
|
||||
argv[1]);
|
||||
- return 12;
|
||||
+ ret = 1;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
- r = _cmd_device_usage(fd, argv[i], mode);
|
||||
+ ret = _cmd_device_usage(fd, argv[i], mode);
|
||||
close_file_or_dir(fd, dirstream);
|
||||
|
||||
- if (r)
|
||||
- return r;
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
more_than_one = 1;
|
||||
-
|
||||
}
|
||||
-
|
||||
- return 0;
|
||||
+out:
|
||||
+ return !!ret;
|
||||
}
|
||||
|
||||
const struct cmd_group device_cmd_group = {
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index 579230a79d85..e088956f9409 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -68,7 +68,7 @@ static int add_info_to_list(struct chunk_info **info_ptr,
|
||||
if (!res) {
|
||||
free(*info_ptr);
|
||||
fprintf(stderr, "ERROR: not enough memory\n");
|
||||
- return -1;
|
||||
+ return -ENOMEM;
|
||||
}
|
||||
|
||||
*info_ptr = res;
|
||||
@@ -163,7 +163,7 @@ static int load_chunk_info(int fd, struct chunk_info **info_ptr, int *info_count
|
||||
fprintf(stderr,
|
||||
"ERROR: can't perform the search - %s\n",
|
||||
strerror(e));
|
||||
- return -99;
|
||||
+ return ret;
|
||||
}
|
||||
/* the ioctl returns the number of item it found in nr_items */
|
||||
|
||||
@@ -179,9 +179,10 @@ static int load_chunk_info(int fd, struct chunk_info **info_ptr, int *info_count
|
||||
off += sizeof(*sh);
|
||||
item = (struct btrfs_chunk *)(args.buf + off);
|
||||
|
||||
- if (add_info_to_list(info_ptr, info_count, item)) {
|
||||
+ ret = add_info_to_list(info_ptr, info_count, item);
|
||||
+ if (ret) {
|
||||
*info_ptr = 0;
|
||||
- return -100;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
off += sh->len;
|
||||
@@ -319,8 +320,9 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
|
||||
double K;
|
||||
u64 raid5_used, raid6_used;
|
||||
|
||||
- if ((sargs = load_space_info(fd, path)) == NULL) {
|
||||
- ret = -1;
|
||||
+ sargs = load_space_info(fd, path);
|
||||
+ if (!sargs) {
|
||||
+ ret = 1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@@ -331,7 +333,7 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
|
||||
"ERROR: couldn't get space info on '%s' - %s\n",
|
||||
path, strerror(e));
|
||||
|
||||
- ret = 19;
|
||||
+ ret = 1;
|
||||
goto exit;
|
||||
}
|
||||
get_raid56_used(fd, chunkinfo, chunkcount, &raid5_used, &raid6_used);
|
||||
@@ -439,13 +441,13 @@ static int load_device_info(int fd, struct device_info **device_info_ptr,
|
||||
return ret;
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "ERROR: cannot get filesystem info\n");
|
||||
- return -1;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
info = calloc(fi_args.num_devices, sizeof(struct device_info));
|
||||
if (!info) {
|
||||
fprintf(stderr, "ERROR: not enough memory\n");
|
||||
- return -1;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
for (i = 0, ndevs = 0 ; i <= fi_args.max_id ; i++) {
|
||||
@@ -460,7 +462,7 @@ static int load_device_info(int fd, struct device_info **device_info_ptr,
|
||||
"ERROR: cannot get info about device devid=%d\n",
|
||||
i);
|
||||
free(info);
|
||||
- return -1;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
info[ndevs].devid = dev_info.devid;
|
||||
@@ -749,7 +751,7 @@ static int print_filesystem_usage_by_chunk(int fd,
|
||||
sargs = load_space_info(fd, path);
|
||||
if (!sargs) {
|
||||
ret = 1;
|
||||
- goto exit;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
if (tabular)
|
||||
@@ -759,9 +761,8 @@ static int print_filesystem_usage_by_chunk(int fd,
|
||||
_cmd_filesystem_usage_linear(mode, sargs, chunkinfo,
|
||||
chunkcount, devinfo, devcount);
|
||||
|
||||
-exit:
|
||||
free(sargs);
|
||||
-
|
||||
+out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -777,6 +778,7 @@ const char * const cmd_filesystem_usage_usage[] = {
|
||||
int cmd_filesystem_usage(int argc, char **argv)
|
||||
{
|
||||
int mode = UNITS_HUMAN;
|
||||
+ int ret = 0;
|
||||
int i, more_than_one = 0;
|
||||
int tabular = 0;
|
||||
|
||||
@@ -803,7 +805,6 @@ int cmd_filesystem_usage(int argc, char **argv)
|
||||
usage(cmd_filesystem_usage_usage);
|
||||
|
||||
for (i = optind; i < argc; i++) {
|
||||
- int ret;
|
||||
int fd;
|
||||
DIR *dirstream = NULL;
|
||||
struct chunk_info *chunkinfo = NULL;
|
||||
@@ -813,9 +814,10 @@ int cmd_filesystem_usage(int argc, char **argv)
|
||||
|
||||
fd = open_file_or_dir(argv[i], &dirstream);
|
||||
if (fd < 0) {
|
||||
- fprintf(stderr, "ERROR: can't access to '%s'\n",
|
||||
+ fprintf(stderr, "ERROR: can't access '%s'\n",
|
||||
argv[1]);
|
||||
- return 12;
|
||||
+ ret = 1;
|
||||
+ goto out;
|
||||
}
|
||||
if (more_than_one)
|
||||
printf("\n");
|
||||
@@ -838,11 +840,12 @@ cleanup:
|
||||
free(devinfo);
|
||||
|
||||
if (ret)
|
||||
- return ret;
|
||||
+ goto out;
|
||||
more_than_one = 1;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+out:
|
||||
+ return !!ret;
|
||||
}
|
||||
|
||||
void print_device_chunks(int fd, struct device_info *devinfo,
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,96 +0,0 @@
|
||||
From c440e750f10ec3a57e7fe204c5a9809c59590126 Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Tue, 29 Apr 2014 17:32:22 +0200
|
||||
Subject: [PATCH 19/42] btrfs-progs: move global reserve to overall summary
|
||||
|
||||
It looks confusing among the chunks, it is not in fact a chunk type.
|
||||
|
||||
Sample:
|
||||
Overall:
|
||||
Device size: 35.00GiB
|
||||
Device allocated: 8.07GiB
|
||||
Device unallocated: 26.93GiB
|
||||
Used: 1.12MiB
|
||||
Free (Estimated): 17.57GiB (Max: 30.98GiB, min: 17.52GiB)
|
||||
Data to device ratio: 50 %
|
||||
Global reserve: 16.00MiB (used: 0.00B)
|
||||
...
|
||||
|
||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||
---
|
||||
cmds-fi-disk_usage.c | 22 ++++++++++++++++++++--
|
||||
1 file changed, 20 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||
index e088956f9409..2c3c0a3ed51e 100644
|
||||
--- a/cmds-fi-disk_usage.c
|
||||
+++ b/cmds-fi-disk_usage.c
|
||||
@@ -319,6 +319,8 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
|
||||
u64 total_free; /* logical space un-used */
|
||||
double K;
|
||||
u64 raid5_used, raid6_used;
|
||||
+ u64 global_reserve;
|
||||
+ u64 global_reserve_used;
|
||||
|
||||
sargs = load_space_info(fd, path);
|
||||
if (!sargs) {
|
||||
@@ -341,6 +343,8 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
|
||||
total_chunks = 0;
|
||||
total_used = 0;
|
||||
total_free = 0;
|
||||
+ global_reserve = 0;
|
||||
+ global_reserve_used = 0;
|
||||
|
||||
for (i = 0; i < sargs->total_spaces; i++) {
|
||||
float ratio = 1;
|
||||
@@ -366,6 +370,11 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
|
||||
else
|
||||
ratio = 1;
|
||||
|
||||
+ if (flags & BTRFS_SPACE_INFO_GLOBAL_RSV) {
|
||||
+ global_reserve = sargs->spaces[i].total_bytes;
|
||||
+ global_reserve_used = sargs->spaces[i].used_bytes;
|
||||
+ }
|
||||
+
|
||||
allocated = sargs->spaces[i].total_bytes * ratio;
|
||||
|
||||
total_chunks += allocated;
|
||||
@@ -404,6 +413,9 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo,
|
||||
pretty_size_mode((total_disk-total_chunks) / 2 + total_free, mode));
|
||||
printf(" Data to device ratio:\t%*.0f %%\n",
|
||||
width - 2, K * 100);
|
||||
+ printf(" Global reserve:\t\t%*s\t(used: %s)\n", width,
|
||||
+ pretty_size_mode(global_reserve, mode),
|
||||
+ pretty_size_mode(global_reserve_used, mode));
|
||||
|
||||
exit:
|
||||
|
||||
@@ -553,8 +565,11 @@ static void _cmd_filesystem_usage_tabular(int mode,
|
||||
/* header */
|
||||
for (i = 0; i < sargs->total_spaces; i++) {
|
||||
const char *description;
|
||||
-
|
||||
u64 flags = sargs->spaces[i].flags;
|
||||
+
|
||||
+ if (flags & BTRFS_SPACE_INFO_GLOBAL_RSV)
|
||||
+ continue;
|
||||
+
|
||||
description = btrfs_group_type_str(flags);
|
||||
|
||||
table_printf(matrix, 1+i, 0, "<%s", description);
|
||||
@@ -715,8 +730,11 @@ static void _cmd_filesystem_usage_linear(int mode,
|
||||
for (i = 0; i < sargs->total_spaces; i++) {
|
||||
const char *description;
|
||||
const char *r_mode;
|
||||
-
|
||||
u64 flags = sargs->spaces[i].flags;
|
||||
+
|
||||
+ if (flags & BTRFS_SPACE_INFO_GLOBAL_RSV)
|
||||
+ continue;
|
||||
+
|
||||
description = btrfs_group_type_str(flags);
|
||||
r_mode = btrfs_group_profile_str(flags);
|
||||
|
||||
--
|
||||
2.1.1
|
||||
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:06c0a3b0988fc7e9555cb722a47d10da39b5a8e24911083ef99cbc80d7f16291
|
||||
size 792593
|
3
btrfs-progs-v3.18.tar.gz
Normal file
3
btrfs-progs-v3.18.tar.gz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3fe7a5b8062c49bb3f7861feaaf99b8224c50174e4fa4058d1461474ed6ecc89
|
||||
size 1238132
|
@ -1,3 +1,42 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue Dec 30 00:00:00 CET 2014 - dsterba@suse.cz
|
||||
|
||||
- version 3.18
|
||||
- mkfs - skinny-metadata feature is now on by default, first introduced in
|
||||
kernel 3.10
|
||||
- filesystem usage - give an overview of fs usage in a way that's more
|
||||
comprehensible than existing 'fi df'
|
||||
- device usage - more detailed information about per-device allocations
|
||||
- check:
|
||||
- option to set a different tree root byte number
|
||||
- ability to link lost files to lost+found, caused by a recent kernel bug
|
||||
- repair of severely corrupted fs (use with care)
|
||||
- convert - option to show progress
|
||||
- subvol create - print the commit mode inline, print the global mode only if --verbose
|
||||
- other updates: musl-libc support, coverity bugfixes, new test images,
|
||||
documentation
|
||||
- Removed patches (upstreamed):
|
||||
* 0010-btrfs-progs-move-group-type-and-profile-pretty-print.patch
|
||||
* 0011-btrfs-progs-Enhance-the-command-btrfs-filesystem-df.patch
|
||||
* 0012-btrfs-progs-Add-helpers-functions-to-handle-the-prin.patch
|
||||
* 0013-btrfs-progs-Add-command-btrfs-filesystem-disk-usage.patch
|
||||
* 0014-btrfs-progs-Add-btrfs-device-disk-usage-command.patch
|
||||
* 0015-btrfs-progs-cleanup-dead-return-after-usage-for-fi-d.patch
|
||||
* 0016-btrfs-progs-Fix-memleak-in-get_raid56_used.patch
|
||||
* 0017-Btrfs-progs-fi-usage-free-memory-if-realloc-fails.patch
|
||||
* 0019-btrfs-progs-add-original-df-and-rename-disk_usage-to.patch
|
||||
* 0020-btrfs-progs-move-device-usage-to-cmds-device-more-cl.patch
|
||||
* 0021-btrfs-progs-check-if-we-can-t-get-info-from-ioctls-d.patch
|
||||
* 0022-btrfs-progs-zero-out-structures-before-calling-ioctl.patch
|
||||
* 0024-btrfs-progs-Print-more-info-about-device-sizes.patch
|
||||
* 0025-btrfs-progs-compare-unallocated-space-against-the-co.patch
|
||||
* 0026-btrfs-progs-add-section-of-overall-filesystem-usage.patch
|
||||
* 0027-btrfs-progs-cleanup-filesystem-device-usage-code.patch
|
||||
* 0028-btrfs-progs-rework-calculations-of-fi-usage.patch
|
||||
* 0029-btrfs-progs-replace-df_pretty_sizes-with-pretty_size.patch
|
||||
* 0030-btrfs-progs-clean-up-return-codes-and-paths.patch
|
||||
* 0031-btrfs-progs-move-global-reserve-to-overall-summary.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Dec 4 00:00:00 CET 2014 - dsterba@suse.cz
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
Name: btrfsprogs
|
||||
Version: 3.17.3
|
||||
Version: 3.18
|
||||
Release: 0
|
||||
Summary: Utilities for the Btrfs filesystem
|
||||
License: GPL-2.0
|
||||
@ -30,27 +30,6 @@ Source: https://www.kernel.org/pub/linux/kernel/people/kdave/btrfs-progs
|
||||
Source1: boot-btrfs.sh
|
||||
Source4: setup-btrfs.sh
|
||||
|
||||
Patch10: 0010-btrfs-progs-move-group-type-and-profile-pretty-print.patch
|
||||
Patch11: 0011-btrfs-progs-Enhance-the-command-btrfs-filesystem-df.patch
|
||||
Patch12: 0012-btrfs-progs-Add-helpers-functions-to-handle-the-prin.patch
|
||||
Patch13: 0013-btrfs-progs-Add-command-btrfs-filesystem-disk-usage.patch
|
||||
Patch14: 0014-btrfs-progs-Add-btrfs-device-disk-usage-command.patch
|
||||
Patch15: 0015-btrfs-progs-cleanup-dead-return-after-usage-for-fi-d.patch
|
||||
Patch16: 0016-btrfs-progs-Fix-memleak-in-get_raid56_used.patch
|
||||
Patch17: 0017-Btrfs-progs-fi-usage-free-memory-if-realloc-fails.patch
|
||||
Patch19: 0019-btrfs-progs-add-original-df-and-rename-disk_usage-to.patch
|
||||
Patch20: 0020-btrfs-progs-move-device-usage-to-cmds-device-more-cl.patch
|
||||
Patch21: 0021-btrfs-progs-check-if-we-can-t-get-info-from-ioctls-d.patch
|
||||
Patch22: 0022-btrfs-progs-zero-out-structures-before-calling-ioctl.patch
|
||||
Patch24: 0024-btrfs-progs-Print-more-info-about-device-sizes.patch
|
||||
Patch25: 0025-btrfs-progs-compare-unallocated-space-against-the-co.patch
|
||||
Patch26: 0026-btrfs-progs-add-section-of-overall-filesystem-usage.patch
|
||||
Patch27: 0027-btrfs-progs-cleanup-filesystem-device-usage-code.patch
|
||||
Patch28: 0028-btrfs-progs-rework-calculations-of-fi-usage.patch
|
||||
Patch29: 0029-btrfs-progs-replace-df_pretty_sizes-with-pretty_size.patch
|
||||
Patch30: 0030-btrfs-progs-clean-up-return-codes-and-paths.patch
|
||||
Patch31: 0031-btrfs-progs-move-global-reserve-to-overall-summary.patch
|
||||
|
||||
Patch163: 0163-btrfs-progs-fsck-fix-segfault.patch
|
||||
Patch167: 0167-Btrfs-progs-make-find_and_setup_root-return-an-error.patch
|
||||
Patch168: 0168-Btrfs-progs-don-t-bug-out-if-we-can-t-find-the-last-.patch
|
||||
@ -98,26 +77,6 @@ build applications to interface with btrfs.
|
||||
|
||||
%prep
|
||||
%setup -q -n btrfs-progs-v%{version}
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
%patch13 -p1
|
||||
%patch14 -p1
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch17 -p1
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
%patch24 -p1
|
||||
%patch25 -p1
|
||||
%patch26 -p1
|
||||
%patch27 -p1
|
||||
%patch29 -p1
|
||||
%patch30 -p1
|
||||
%patch31 -p1
|
||||
%patch28 -p1
|
||||
%patch163 -p1
|
||||
%patch167 -p1
|
||||
%patch168 -p1
|
||||
|
@ -6,8 +6,8 @@ Index: btrfs-progs-v3.16.1/version.sh
|
||||
# Copyright 2008, Oracle
|
||||
# Released under the GNU GPLv2
|
||||
|
||||
-v="v3.17.3"
|
||||
+v="v3.17.3+20141204"
|
||||
-v="v3.18"
|
||||
+v="v3.18+20141230"
|
||||
|
||||
lib_major=0
|
||||
lib_minor=1
|
||||
|
Loading…
Reference in New Issue
Block a user