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:
Dominique Leuenberger 2015-01-03 21:02:14 +00:00 committed by Git OBS Bridge
commit 5a7b47fd82
25 changed files with 45 additions and 4633 deletions

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3fe7a5b8062c49bb3f7861feaaf99b8224c50174e4fa4058d1461474ed6ecc89
size 1238132

View File

@ -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 Thu Dec 4 00:00:00 CET 2014 - dsterba@suse.cz

View File

@ -17,7 +17,7 @@
Name: btrfsprogs Name: btrfsprogs
Version: 3.17.3 Version: 3.18
Release: 0 Release: 0
Summary: Utilities for the Btrfs filesystem Summary: Utilities for the Btrfs filesystem
License: GPL-2.0 License: GPL-2.0
@ -30,27 +30,6 @@ Source: https://www.kernel.org/pub/linux/kernel/people/kdave/btrfs-progs
Source1: boot-btrfs.sh Source1: boot-btrfs.sh
Source4: setup-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 Patch163: 0163-btrfs-progs-fsck-fix-segfault.patch
Patch167: 0167-Btrfs-progs-make-find_and_setup_root-return-an-error.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 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 %prep
%setup -q -n btrfs-progs-v%{version} %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 %patch163 -p1
%patch167 -p1 %patch167 -p1
%patch168 -p1 %patch168 -p1

View File

@ -6,8 +6,8 @@ Index: btrfs-progs-v3.16.1/version.sh
# Copyright 2008, Oracle # Copyright 2008, Oracle
# Released under the GNU GPLv2 # Released under the GNU GPLv2
-v="v3.17.3" -v="v3.18"
+v="v3.17.3+20141204" +v="v3.18+20141230"
lib_major=0 lib_major=0
lib_minor=1 lib_minor=1