Accepting request 232435 from home:dsterba:branches:filesystems
- update to upstream 3.14.1 - mkfs: - fix TRIM detection - do not zero-out end of device unconditionally - no crash with --features option - fsck: - clear log tree in repair mode - check reloc roots - btrfs - reworked space reporting (bnc#873106) - btrfs fi usage - new command - btrfs dev usage - new command - btrfs fi df - enhanced output with GlobalReserve - Removed patches: * 0001-btrfs-progs-move-arg_strtou64-to-a-separate-file-for.patch - Added patches: * 0001-Btrfs-progs-fix-check-to-test-trim-support.patch * 0002-Btrfs-progs-fsck-fix-double-free-memory-crash.patch * 0003-Btrfs-progs-mkfs-Remove-zero_end-1-since-it-has-been.patch * 0004-btrfs-progs-fix-wrong-max-system-array-size-check-in.patch * 0005-btrfs-progs-move-arg_strtou64-to-a-separate-file-for.patch * 0006-Btrfs-progs-fsck-clear-out-log-tree-in-repair-mode.patch * 0007-Btrfs-progs-fsck-avoid-pinning-same-block-several-ti.patch * 0008-Btrfs-progs-fsck-add-ability-to-check-reloc-roots.patch * 0009-btrfs-progs-prevent-close_root-if-the-root-to-close-.patch * 0010-btrfs-progs-fix-mkfs.btrfs-segfault-with-features-op.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 * 0018-btrfs-progs-read-global-reserve-size-from-space-info.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 * 0023-btrfs-progs-print-B-for-bytes.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-extend-pretty-printers-with-unit-mode.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 OBS-URL: https://build.opensuse.org/request/show/232435 OBS-URL: https://build.opensuse.org/package/show/filesystems/btrfsprogs?expand=0&rev=156
This commit is contained in:
parent
4687704315
commit
6beb01c50d
30
0001-Btrfs-progs-fix-check-to-test-trim-support.patch
Normal file
30
0001-Btrfs-progs-fix-check-to-test-trim-support.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From f7025683c14debd0ca3ee21dc64699a185849b35 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rakesh Pandit <rakesh@tuxera.com>
|
||||||
|
Date: Tue, 22 Apr 2014 16:30:27 +0300
|
||||||
|
Subject: [PATCH 03/42] Btrfs-progs: fix check to test trim support
|
||||||
|
|
||||||
|
It was added in 25d82d22 but broke recently in 4724d7b0 while making
|
||||||
|
discard interruptible.
|
||||||
|
|
||||||
|
Signed-off-by: Rakesh Pandit <rakesh@tuxera.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
utils.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/utils.c b/utils.c
|
||||||
|
index 3e9c527a492c..187ad3b9b12b 100644
|
||||||
|
--- a/utils.c
|
||||||
|
+++ b/utils.c
|
||||||
|
@@ -626,7 +626,7 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
|
||||||
|
* is not necessary for the mkfs functionality but just an
|
||||||
|
* optimization.
|
||||||
|
*/
|
||||||
|
- if (discard_blocks(fd, 0, 0) == 0) {
|
||||||
|
+ if (discard_range(fd, 0, 0) == 0) {
|
||||||
|
fprintf(stderr, "Performing full device TRIM (%s) ...\n",
|
||||||
|
pretty_size(block_count));
|
||||||
|
discard_blocks(fd, 0, block_count);
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
35
0002-Btrfs-progs-fsck-fix-double-free-memory-crash.patch
Normal file
35
0002-Btrfs-progs-fsck-fix-double-free-memory-crash.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From 4c92a4a31b51950d8d0f167a0391586803802f4c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rakesh Pandit <rakesh@tuxera.com>
|
||||||
|
Date: Sun, 20 Apr 2014 16:17:53 +0300
|
||||||
|
Subject: [PATCH 08/42] Btrfs-progs: fsck: fix double free memory crash
|
||||||
|
|
||||||
|
Fix double free of memory if btrfs_open_devices fails:
|
||||||
|
*** Error in `btrfs': double free or corruption (fasttop): 0x000000000066e020 ***
|
||||||
|
|
||||||
|
Crash happened because when open failed on device inside
|
||||||
|
btrfs_open_devices it freed all memory by calling btrfs_close_devices but
|
||||||
|
inside disk-io.c we call btrfs_close_again it again.
|
||||||
|
|
||||||
|
Signed-off-by: Rakesh Pandit <rakesh@tuxera.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
disk-io.c | 3 +--
|
||||||
|
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/disk-io.c b/disk-io.c
|
||||||
|
index 19b95a724f1b..8db0335bc81b 100644
|
||||||
|
--- a/disk-io.c
|
||||||
|
+++ b/disk-io.c
|
||||||
|
@@ -1091,8 +1091,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
|
||||||
|
|
||||||
|
ret = btrfs_open_devices(fs_devices, oflags);
|
||||||
|
if (ret)
|
||||||
|
- goto out_devices;
|
||||||
|
-
|
||||||
|
+ goto out;
|
||||||
|
|
||||||
|
disk_super = fs_info->super_copy;
|
||||||
|
if (!(flags & OPEN_CTREE_RECOVER_SUPER))
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
@ -0,0 +1,44 @@
|
|||||||
|
From e7cd3d7fa55bb26d9b4579fececc863db6555d97 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Li Yang <liyang.fnst@cn.fujitsu.com>
|
||||||
|
Date: Mon, 21 Apr 2014 05:38:08 -0400
|
||||||
|
Subject: [PATCH 09/42] Btrfs-progs: mkfs: Remove 'zero_end =1' since it has
|
||||||
|
been set to a value
|
||||||
|
|
||||||
|
In utils.c, zero_end is used as a parameter, should not force it to 1.
|
||||||
|
In mkfs.c, zero_end is set to 1 or 0(-b) at the beginning, should not
|
||||||
|
force it to 1 unconditionally.
|
||||||
|
|
||||||
|
Signed-off-by: Li Yang <liyang.fnst@cn.fujitsu.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
mkfs.c | 1 -
|
||||||
|
utils.c | 1 -
|
||||||
|
2 files changed, 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/mkfs.c b/mkfs.c
|
||||||
|
index dbd83f5ce168..f2b577922c9e 100644
|
||||||
|
--- a/mkfs.c
|
||||||
|
+++ b/mkfs.c
|
||||||
|
@@ -1543,7 +1543,6 @@ int main(int ac, char **av)
|
||||||
|
|
||||||
|
btrfs_register_one_device(file);
|
||||||
|
|
||||||
|
- zero_end = 1;
|
||||||
|
while (dev_cnt-- > 0) {
|
||||||
|
int old_mixed = mixed;
|
||||||
|
|
||||||
|
diff --git a/utils.c b/utils.c
|
||||||
|
index 44c0e4ab39f2..29953d9dd2a9 100644
|
||||||
|
--- a/utils.c
|
||||||
|
+++ b/utils.c
|
||||||
|
@@ -613,7 +613,6 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
|
||||||
|
}
|
||||||
|
if (max_block_count)
|
||||||
|
block_count = min(block_count, max_block_count);
|
||||||
|
- zero_end = 1;
|
||||||
|
|
||||||
|
if (block_count < 1024 * 1024 * 1024 && !(*mixed)) {
|
||||||
|
printf("SMALL VOLUME: forcing mixed metadata/data groups\n");
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
@ -0,0 +1,34 @@
|
|||||||
|
From b014a6150ebaa97cee780fca184df626c173c30e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gui Hecheng <guihc.fnst@cn.fujitsu.com>
|
||||||
|
Date: Mon, 21 Apr 2014 20:13:31 +0800
|
||||||
|
Subject: [PATCH 10/42] btrfs-progs: fix wrong max system array size check in
|
||||||
|
user space
|
||||||
|
|
||||||
|
For system chunk array,
|
||||||
|
We copy a "disk_key" and an chunk item each time,
|
||||||
|
so there should be enough space to hold both of them,
|
||||||
|
not only the chunk item.
|
||||||
|
|
||||||
|
Signed-off-by: Gui Hecheng <guihc.fnst@cn.fujitsu.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
volumes.c | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/volumes.c b/volumes.c
|
||||||
|
index 77ffd3252c38..b39f374305bc 100644
|
||||||
|
--- a/volumes.c
|
||||||
|
+++ b/volumes.c
|
||||||
|
@@ -630,7 +630,8 @@ int btrfs_add_system_chunk(struct btrfs_trans_handle *trans,
|
||||||
|
u8 *ptr;
|
||||||
|
|
||||||
|
array_size = btrfs_super_sys_array_size(super_copy);
|
||||||
|
- if (array_size + item_size > BTRFS_SYSTEM_CHUNK_ARRAY_SIZE)
|
||||||
|
+ if (array_size + item_size + sizeof(disk_key)
|
||||||
|
+ > BTRFS_SYSTEM_CHUNK_ARRAY_SIZE)
|
||||||
|
return -EFBIG;
|
||||||
|
|
||||||
|
ptr = super_copy->sys_chunk_array + array_size;
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
@ -1,23 +1,25 @@
|
|||||||
From f555e06e2d266f52cdeb12218f8175eba2a17020 Mon Sep 17 00:00:00 2001
|
From b5230eca8a9214c7290ed818ff9792eb5d3e142b Mon Sep 17 00:00:00 2001
|
||||||
From: David Sterba <dsterba@suse.cz>
|
From: David Sterba <dsterba@suse.cz>
|
||||||
Date: Fri, 11 Apr 2014 13:22:50 +0200
|
Date: Fri, 11 Apr 2014 13:22:50 +0200
|
||||||
Subject: [PATCH] btrfs-progs: move arg_strtou64 to a separate file for library
|
Subject: [PATCH 12/42] btrfs-progs: move arg_strtou64 to a separate file for
|
||||||
|
library
|
||||||
|
|
||||||
Linking with libbtrfs fails because arg_strtou64 is not defined and we
|
Linking with libbtrfs fails because arg_strtou64 is not defined and we
|
||||||
cannot just add utils.o to library objects because it's not
|
cannot just add utils.o to library objects because it's not
|
||||||
library-clean.
|
library-clean.
|
||||||
|
|
||||||
Reported-by: Arvin Schnell <aschnell@suse.com>
|
Reported-by: Arvin Schnell <aschnell@suse.com>
|
||||||
|
Reported-by: Anton Farygin <rider@altlinux.org>
|
||||||
Signed-off-by: David Sterba <dsterba@suse.cz>
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
---
|
---
|
||||||
Makefile | 5 +++--
|
Makefile | 5 +++--
|
||||||
libutils.c | 43 +++++++++++++++++++++++++++++++++++++++++++
|
utils-lib.c | 42 ++++++++++++++++++++++++++++++++++++++++++
|
||||||
utils.c | 33 ---------------------------------
|
utils.c | 33 ---------------------------------
|
||||||
3 files changed, 46 insertions(+), 35 deletions(-)
|
3 files changed, 45 insertions(+), 35 deletions(-)
|
||||||
create mode 100644 libutils.c
|
create mode 100644 utils-lib.c
|
||||||
|
|
||||||
diff --git a/Makefile b/Makefile
|
diff --git a/Makefile b/Makefile
|
||||||
index da0519766443..9ae7115d23a3 100644
|
index 51d53fadf5af..76565e8b2307 100644
|
||||||
--- a/Makefile
|
--- a/Makefile
|
||||||
+++ b/Makefile
|
+++ b/Makefile
|
||||||
@@ -9,14 +9,15 @@ CFLAGS = -g -O1 -fno-strict-aliasing
|
@@ -9,14 +9,15 @@ CFLAGS = -g -O1 -fno-strict-aliasing
|
||||||
@ -26,7 +28,7 @@ index da0519766443..9ae7115d23a3 100644
|
|||||||
extent-cache.o extent_io.o volumes.o utils.o repair.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
|
- qgroup.o raid6.o free-space-cache.o list_sort.o props.o
|
||||||
+ qgroup.o raid6.o free-space-cache.o list_sort.o props.o \
|
+ qgroup.o raid6.o free-space-cache.o list_sort.o props.o \
|
||||||
+ libutils.o
|
+ utils-lib.o
|
||||||
cmds_objects = cmds-subvolume.o cmds-filesystem.o cmds-device.o cmds-scrub.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-inspect.o cmds-balance.o cmds-send.o cmds-receive.o \
|
||||||
cmds-quota.o cmds-qgroup.o cmds-replace.o cmds-check.o \
|
cmds-quota.o cmds-qgroup.o cmds-replace.o cmds-check.o \
|
||||||
@ -34,16 +36,16 @@ index da0519766443..9ae7115d23a3 100644
|
|||||||
cmds-property.o
|
cmds-property.o
|
||||||
libbtrfs_objects = send-stream.o send-utils.o rbtree.o btrfs-list.o crc32c.o \
|
libbtrfs_objects = send-stream.o send-utils.o rbtree.o btrfs-list.o crc32c.o \
|
||||||
- uuid-tree.o
|
- uuid-tree.o
|
||||||
+ uuid-tree.o libutils.o
|
+ uuid-tree.o utils-lib.o
|
||||||
libbtrfs_headers = send-stream.h send-utils.h send.h rbtree.h btrfs-list.h \
|
libbtrfs_headers = send-stream.h send-utils.h send.h rbtree.h btrfs-list.h \
|
||||||
crc32c.h list.h kerncompat.h radix-tree.h extent-cache.h \
|
crc32c.h list.h kerncompat.h radix-tree.h extent-cache.h \
|
||||||
extent_io.h ioctl.h ctree.h btrfsck.h
|
extent_io.h ioctl.h ctree.h btrfsck.h
|
||||||
diff --git a/libutils.c b/libutils.c
|
diff --git a/utils-lib.c b/utils-lib.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 000000000000..074f771e0b6e
|
index 000000000000..9d53c6e5c710
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/libutils.c
|
+++ b/utils-lib.c
|
||||||
@@ -0,0 +1,43 @@
|
@@ -0,0 +1,42 @@
|
||||||
+#define _GNU_SOURCE
|
+#define _GNU_SOURCE
|
||||||
+
|
+
|
||||||
+#include "kerncompat.h"
|
+#include "kerncompat.h"
|
||||||
@ -56,8 +58,8 @@ index 000000000000..074f771e0b6e
|
|||||||
+#endif /* BTRFS_FLAT_INCLUDES */
|
+#endif /* BTRFS_FLAT_INCLUDES */
|
||||||
+
|
+
|
||||||
+/*
|
+/*
|
||||||
+ * This function should be only used when parsing
|
+ * This function should be only used when parsing command arg, it won't return
|
||||||
+ * command arg, it won't return error to it's
|
+ * error to its caller and rather exit directly just like usage().
|
||||||
+ */
|
+ */
|
||||||
+u64 arg_strtou64(const char *str)
|
+u64 arg_strtou64(const char *str)
|
||||||
+{
|
+{
|
||||||
@ -70,10 +72,10 @@ index 000000000000..074f771e0b6e
|
|||||||
+ str);
|
+ str);
|
||||||
+ exit(1);
|
+ exit(1);
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
+ /*
|
+ /*
|
||||||
+ * if we pass a negative number to strtoull,
|
+ * if we pass a negative number to strtoull, it will return an
|
||||||
+ * it will return an unexpected number to us,
|
+ * unexpected number to us, so let's do the check ourselves.
|
||||||
+ * so let's do the check ourselves.
|
|
||||||
+ */
|
+ */
|
||||||
+ if (str[0] == '-') {
|
+ if (str[0] == '-') {
|
||||||
+ fprintf(stderr, "ERROR: %s: negative value is invalid.\n",
|
+ fprintf(stderr, "ERROR: %s: negative value is invalid.\n",
|
||||||
@ -86,12 +88,11 @@ index 000000000000..074f771e0b6e
|
|||||||
+ }
|
+ }
|
||||||
+ return value;
|
+ return value;
|
||||||
+}
|
+}
|
||||||
+
|
|
||||||
diff --git a/utils.c b/utils.c
|
diff --git a/utils.c b/utils.c
|
||||||
index 3e9c527a492c..134f43a76fe9 100644
|
index 29953d9dd2a9..e130849c7bb5 100644
|
||||||
--- a/utils.c
|
--- a/utils.c
|
||||||
+++ b/utils.c
|
+++ b/utils.c
|
||||||
@@ -1539,39 +1539,6 @@ scan_again:
|
@@ -1538,39 +1538,6 @@ scan_again:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
|||||||
|
From 3ecff1d8f1eaa5e0d065c439cf72032dd01da751 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
|
||||||
|
Date: Thu, 24 Apr 2014 11:19:16 +0800
|
||||||
|
Subject: [PATCH 13/42] Btrfs-progs: fsck: clear out log tree in repair mode
|
||||||
|
|
||||||
|
Repair mode will commit transaction which will make us
|
||||||
|
fail to load log tree anymore.
|
||||||
|
|
||||||
|
Give a warning to common users, if they really want to
|
||||||
|
coninue, we will clear out log tree.
|
||||||
|
|
||||||
|
Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
cmds-check.c | 33 +++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 33 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/cmds-check.c b/cmds-check.c
|
||||||
|
index 1fe97b3a38c0..7457618fb702 100644
|
||||||
|
--- a/cmds-check.c
|
||||||
|
+++ b/cmds-check.c
|
||||||
|
@@ -6616,6 +6616,22 @@ out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int zero_log_tree(struct btrfs_root *root)
|
||||||
|
+{
|
||||||
|
+ struct btrfs_trans_handle *trans;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ trans = btrfs_start_transaction(root, 1);
|
||||||
|
+ if (IS_ERR(trans)) {
|
||||||
|
+ ret = PTR_ERR(trans);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+ btrfs_set_super_log_root(root->fs_info->super_copy, 0);
|
||||||
|
+ btrfs_set_super_log_root_level(root->fs_info->super_copy, 0);
|
||||||
|
+ ret = btrfs_commit_transaction(trans, root);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{ "super", 1, NULL, 's' },
|
||||||
|
{ "repair", 0, NULL, 0 },
|
||||||
|
@@ -6720,6 +6736,23 @@ int cmd_check(int argc, char **argv)
|
||||||
|
}
|
||||||
|
|
||||||
|
root = info->fs_root;
|
||||||
|
+ /*
|
||||||
|
+ * repair mode will force us to commit transaction which
|
||||||
|
+ * will make us fail to load log tree when mounting.
|
||||||
|
+ */
|
||||||
|
+ if (repair && btrfs_super_log_root(info->super_copy)) {
|
||||||
|
+ ret = ask_user("repair mode will force to clear out log tree, Are you sure?");
|
||||||
|
+ if (!ret) {
|
||||||
|
+ ret = 1;
|
||||||
|
+ goto close_out;
|
||||||
|
+ }
|
||||||
|
+ ret = zero_log_tree(root);
|
||||||
|
+ if (ret) {
|
||||||
|
+ fprintf(stderr, "fail to zero log tree\n");
|
||||||
|
+ goto close_out;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
uuid_unparse(info->super_copy->fsid, uuidbuf);
|
||||||
|
printf("Checking filesystem on %s\nUUID: %s\n", argv[optind], uuidbuf);
|
||||||
|
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
@ -0,0 +1,38 @@
|
|||||||
|
From 20e9fa6f969b3c6a4b3ff9941c351e90320aed61 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
|
||||||
|
Date: Thu, 24 Apr 2014 11:19:17 +0800
|
||||||
|
Subject: [PATCH 14/42] Btrfs-progs: fsck: avoid pinning same block several
|
||||||
|
times
|
||||||
|
|
||||||
|
This can not only give some speedups but also avoid forever loop
|
||||||
|
with a really broken filesystem.
|
||||||
|
|
||||||
|
Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
cmds-check.c | 9 +++++++++
|
||||||
|
1 file changed, 9 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/cmds-check.c b/cmds-check.c
|
||||||
|
index 7457618fb702..57d3f36eea1f 100644
|
||||||
|
--- a/cmds-check.c
|
||||||
|
+++ b/cmds-check.c
|
||||||
|
@@ -6190,6 +6190,15 @@ static int pin_down_tree_blocks(struct btrfs_fs_info *fs_info,
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * If we have pinned this block before, don't pin it again.
|
||||||
|
+ * This can not only avoid forever loop with broken filesystem
|
||||||
|
+ * but also give us some speedups.
|
||||||
|
+ */
|
||||||
|
+ if (test_range_bit(&fs_info->pinned_extents, eb->start,
|
||||||
|
+ eb->start + eb->len - 1, EXTENT_DIRTY, 0))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
btrfs_pin_extent(fs_info, eb->start, eb->len);
|
||||||
|
|
||||||
|
leafsize = btrfs_super_leafsize(fs_info->super_copy);
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
92
0008-Btrfs-progs-fsck-add-ability-to-check-reloc-roots.patch
Normal file
92
0008-Btrfs-progs-fsck-add-ability-to-check-reloc-roots.patch
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
From 26bf4f0a10dd192e4dc5494d2cf9398c666eaab6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
|
||||||
|
Date: Thu, 24 Apr 2014 18:51:10 +0800
|
||||||
|
Subject: [PATCH 15/42] Btrfs-progs: fsck: add ability to check reloc roots
|
||||||
|
|
||||||
|
When encountering system crash or balance enospc errors,
|
||||||
|
there maybe still some reloc roots left.
|
||||||
|
|
||||||
|
The way we store reloc root is different from fs root:
|
||||||
|
|
||||||
|
reloc root's root key(BTRFS_RELOC_TREE_OBJECTID, ROOT_ITEM, objectid)
|
||||||
|
fs root's root key(objectid, ROOT_ITEM, -1)
|
||||||
|
reloc data's root key(BTRFS_DATA_RELOC_TREE_OBJECTID, ROOT_ITEM, 0)
|
||||||
|
|
||||||
|
So this patch use right key to search corresponding root node, and
|
||||||
|
avoid using normal fs root cache for reloc roots.
|
||||||
|
|
||||||
|
Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
cmds-check.c | 33 ++++++++++++++++++++++++++-------
|
||||||
|
1 file changed, 26 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cmds-check.c b/cmds-check.c
|
||||||
|
index 57d3f36eea1f..103efc5718ec 100644
|
||||||
|
--- a/cmds-check.c
|
||||||
|
+++ b/cmds-check.c
|
||||||
|
@@ -299,8 +299,22 @@ static struct inode_record *clone_inode_rec(struct inode_record *orig_rec)
|
||||||
|
return rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void print_inode_error(int errors)
|
||||||
|
+static void print_inode_error(struct btrfs_root *root, struct inode_record *rec)
|
||||||
|
{
|
||||||
|
+ u64 root_objectid = root->root_key.objectid;
|
||||||
|
+ int errors = rec->errors;
|
||||||
|
+
|
||||||
|
+ if (!errors)
|
||||||
|
+ return;
|
||||||
|
+ /* reloc root errors, we print its corresponding fs root objectid*/
|
||||||
|
+ if (root_objectid == BTRFS_TREE_RELOC_OBJECTID) {
|
||||||
|
+ root_objectid = root->root_key.offset;
|
||||||
|
+ fprintf(stderr, "reloc");
|
||||||
|
+ }
|
||||||
|
+ fprintf(stderr, "root %llu inode %llu errors %x",
|
||||||
|
+ (unsigned long long) root_objectid,
|
||||||
|
+ (unsigned long long) rec->ino, rec->errors);
|
||||||
|
+
|
||||||
|
if (errors & I_ERR_NO_INODE_ITEM)
|
||||||
|
fprintf(stderr, ", no inode item");
|
||||||
|
if (errors & I_ERR_NO_ORPHAN_ITEM)
|
||||||
|
@@ -1598,10 +1612,7 @@ static int check_inode_recs(struct btrfs_root *root,
|
||||||
|
rec->errors |= I_ERR_NO_INODE_ITEM;
|
||||||
|
if (rec->found_link != rec->nlink)
|
||||||
|
rec->errors |= I_ERR_LINK_COUNT_WRONG;
|
||||||
|
- fprintf(stderr, "root %llu inode %llu errors %x",
|
||||||
|
- (unsigned long long) root->root_key.objectid,
|
||||||
|
- (unsigned long long) rec->ino, rec->errors);
|
||||||
|
- print_inode_error(rec->errors);
|
||||||
|
+ print_inode_error(root, rec);
|
||||||
|
list_for_each_entry(backref, &rec->backrefs, list) {
|
||||||
|
if (!backref->found_dir_item)
|
||||||
|
backref->errors |= REF_ERR_NO_DIR_ITEM;
|
||||||
|
@@ -2060,8 +2071,14 @@ static int check_fs_roots(struct btrfs_root *root,
|
||||||
|
btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
|
||||||
|
if (key.type == BTRFS_ROOT_ITEM_KEY &&
|
||||||
|
fs_root_objectid(key.objectid)) {
|
||||||
|
- key.offset = (u64)-1;
|
||||||
|
- tmp_root = btrfs_read_fs_root(root->fs_info, &key);
|
||||||
|
+ if (key.objectid == BTRFS_TREE_RELOC_OBJECTID) {
|
||||||
|
+ tmp_root = btrfs_read_fs_root_no_cache(
|
||||||
|
+ root->fs_info, &key);
|
||||||
|
+ } else {
|
||||||
|
+ key.offset = (u64)-1;
|
||||||
|
+ tmp_root = btrfs_read_fs_root(
|
||||||
|
+ root->fs_info, &key);
|
||||||
|
+ }
|
||||||
|
if (IS_ERR(tmp_root)) {
|
||||||
|
err = 1;
|
||||||
|
goto next;
|
||||||
|
@@ -2069,6 +2086,8 @@ static int check_fs_roots(struct btrfs_root *root,
|
||||||
|
ret = check_fs_root(tmp_root, root_cache, &wc);
|
||||||
|
if (ret)
|
||||||
|
err = 1;
|
||||||
|
+ if (key.objectid == BTRFS_TREE_RELOC_OBJECTID)
|
||||||
|
+ btrfs_free_fs_root(tmp_root);
|
||||||
|
} else if (key.type == BTRFS_ROOT_REF_KEY ||
|
||||||
|
key.type == BTRFS_ROOT_BACKREF_KEY) {
|
||||||
|
process_root_ref(leaf, path.slots[0], &key,
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
From 07bb42ca797d78333b0fd47189a6504cd25b28d5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gui Hecheng <guihc.fnst@cn.fujitsu.com>
|
||||||
|
Date: Thu, 24 Apr 2014 11:39:28 +0800
|
||||||
|
Subject: [PATCH 16/42] btrfs-progs: prevent close_root if the root to close is
|
||||||
|
potentially NULL
|
||||||
|
|
||||||
|
Originally only if 'block_only' is specified, the 'fs_root == NULL'
|
||||||
|
will be checked. But if 'block_only' is not specified and close_root
|
||||||
|
will be called blindly without checking 'fs_root == NULL', which is
|
||||||
|
unsafe.
|
||||||
|
|
||||||
|
Signed-off-by: Gui Hecheng <guihc.fnst@cn.fujitsu.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
btrfs-debug-tree.c | 9 +++++----
|
||||||
|
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/btrfs-debug-tree.c b/btrfs-debug-tree.c
|
||||||
|
index 8ae7270dc2fe..cb6c1061b329 100644
|
||||||
|
--- a/btrfs-debug-tree.c
|
||||||
|
+++ b/btrfs-debug-tree.c
|
||||||
|
@@ -177,13 +177,14 @@ int main(int ac, char **av)
|
||||||
|
fprintf(stderr, "unable to open %s\n", av[optind]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
root = info->fs_root;
|
||||||
|
+ if (!root) {
|
||||||
|
+ fprintf(stderr, "unable to open %s\n", av[optind]);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (block_only) {
|
||||||
|
- if (!root) {
|
||||||
|
- fprintf(stderr, "unable to open %s\n", av[optind]);
|
||||||
|
- exit(1);
|
||||||
|
- }
|
||||||
|
leaf = read_tree_block(root,
|
||||||
|
block_only,
|
||||||
|
root->leafsize, 0);
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
@ -0,0 +1,37 @@
|
|||||||
|
From 61e0b6eaf4d98ddea540ebbf6b7ad7202ffc6786 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Holger=20Hoffst=C3=A4tte?=
|
||||||
|
<holger.hoffstaette@googlemail.com>
|
||||||
|
Date: Sat, 26 Apr 2014 09:41:04 +0000
|
||||||
|
Subject: [PATCH 19/42] btrfs-progs: fix mkfs.btrfs segfault with --features
|
||||||
|
option
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The mkfs.btrfs --features long option takes an argument but does not
|
||||||
|
declare it. Consequently getopt does not allocate an argument, which
|
||||||
|
makes an unconditional strdup() crash during options parsing.
|
||||||
|
Fix by declaring the argument in the options alias array.
|
||||||
|
|
||||||
|
Signed-off-by: Holger Hoffstätte <holger.hoffstaette@googlemail.com>
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
mkfs.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/mkfs.c b/mkfs.c
|
||||||
|
index 4f5ee07e5ef9..16e92221a547 100644
|
||||||
|
--- a/mkfs.c
|
||||||
|
+++ b/mkfs.c
|
||||||
|
@@ -350,7 +350,7 @@ static struct option long_options[] = {
|
||||||
|
{ "version", 0, NULL, 'V' },
|
||||||
|
{ "rootdir", 1, NULL, 'r' },
|
||||||
|
{ "nodiscard", 0, NULL, 'K' },
|
||||||
|
- { "features", 0, NULL, 'O' },
|
||||||
|
+ { "features", 1, NULL, 'O' },
|
||||||
|
{ NULL, 0, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
771
0011-btrfs-progs-Enhance-the-command-btrfs-filesystem-df.patch
Normal file
771
0011-btrfs-progs-Enhance-the-command-btrfs-filesystem-df.patch
Normal file
@ -0,0 +1,771 @@
|
|||||||
|
From 04a9855f53cb7e4ad874cec28acfa537f00a28ba Mon Sep 17 00:00:00 2001
|
||||||
|
From: Goffredo Baroncelli <kreijack@libero.it>
|
||||||
|
Date: Thu, 13 Feb 2014 20:19:01 +0100
|
||||||
|
Subject: [PATCH 22/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>
|
||||||
|
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 | 92 +--------
|
||||||
|
ctree.h | 5 +-
|
||||||
|
utils.c | 12 ++
|
||||||
|
utils.h | 1 +
|
||||||
|
7 files changed, 560 insertions(+), 93 deletions(-)
|
||||||
|
create mode 100644 cmds-fi-disk_usage.c
|
||||||
|
create mode 100644 cmds-fi-disk_usage.h
|
||||||
|
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index 76565e8b2307..50fb9b0ff2e3 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -15,7 +15,7 @@ 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 \
|
||||||
|
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
|
||||||
|
libbtrfs_headers = send-stream.h send-utils.h send.h rbtree.h btrfs-list.h \
|
||||||
|
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000000..4012c781f20d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/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));
|
||||||
|
+ 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;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
diff --git a/cmds-fi-disk_usage.h b/cmds-fi-disk_usage.h
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000000..9f68bb342d52
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/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
|
||||||
|
diff --git a/cmds-filesystem.c b/cmds-filesystem.c
|
||||||
|
index 306f715475ac..0edfb50daca2 100644
|
||||||
|
--- a/cmds-filesystem.c
|
||||||
|
+++ b/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"
|
||||||
|
|
||||||
|
@@ -112,50 +113,6 @@ static const char * const filesystem_cmd_group_usage[] = {
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
-static const char * const cmd_df_usage[] = {
|
||||||
|
- "btrfs filesystem df <path>",
|
||||||
|
- "Show space usage information for a mount point",
|
||||||
|
- NULL
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-static char *group_type_str(u64 flag)
|
||||||
|
-{
|
||||||
|
- switch (flag & BTRFS_BLOCK_GROUP_TYPE_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";
|
||||||
|
- 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;
|
||||||
|
@@ -204,51 +161,6 @@ static int get_df(int fd, struct btrfs_ioctl_space_args **sargs_ret)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void print_df(struct btrfs_ioctl_space_args *sargs)
|
||||||
|
-{
|
||||||
|
- u64 i;
|
||||||
|
- struct btrfs_ioctl_space_info *sp = sargs->spaces;
|
||||||
|
-
|
||||||
|
- 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),
|
||||||
|
- pretty_size(sp->total_bytes),
|
||||||
|
- pretty_size(sp->used_bytes));
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int cmd_df(int argc, char **argv)
|
||||||
|
-{
|
||||||
|
- struct btrfs_ioctl_space_args *sargs = NULL;
|
||||||
|
- int ret;
|
||||||
|
- int fd;
|
||||||
|
- char *path;
|
||||||
|
- DIR *dirstream = NULL;
|
||||||
|
-
|
||||||
|
- if (check_argc_exact(argc, 2))
|
||||||
|
- usage(cmd_df_usage);
|
||||||
|
-
|
||||||
|
- path = argv[1];
|
||||||
|
-
|
||||||
|
- fd = open_file_or_dir(path, &dirstream);
|
||||||
|
- if (fd < 0) {
|
||||||
|
- fprintf(stderr, "ERROR: can't access '%s'\n", path);
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
- ret = get_df(fd, &sargs);
|
||||||
|
-
|
||||||
|
- if (!ret && sargs) {
|
||||||
|
- print_df(sargs);
|
||||||
|
- free(sargs);
|
||||||
|
- } else {
|
||||||
|
- fprintf(stderr, "ERROR: get_df failed %s\n", strerror(-ret));
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- close_file_or_dir(fd, dirstream);
|
||||||
|
- return !!ret;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static int match_search_item_kernel(__u8 *fsid, char *mnt, char *label,
|
||||||
|
char *search)
|
||||||
|
{
|
||||||
|
@@ -999,7 +911,7 @@ static int cmd_label(int argc, char **argv)
|
||||||
|
|
||||||
|
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 },
|
||||||
|
diff --git a/ctree.h b/ctree.h
|
||||||
|
index a4d2cd114614..8ac17619b9dc 100644
|
||||||
|
--- a/ctree.h
|
||||||
|
+++ b/ctree.h
|
||||||
|
@@ -843,9 +843,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 | \
|
||||||
|
diff --git a/utils.c b/utils.c
|
||||||
|
index e130849c7bb5..7731b071f353 100644
|
||||||
|
--- a/utils.c
|
||||||
|
+++ b/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"
|
||||||
|
@@ -2206,3 +2208,13 @@ int find_mount_root(const char *path, char **mount_root)
|
||||||
|
free(longest_match);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+u64 disk_size(char *path)
|
||||||
|
+{
|
||||||
|
+ struct statfs sfs;
|
||||||
|
+
|
||||||
|
+ if (statfs(path, &sfs) < 0)
|
||||||
|
+ return 0;
|
||||||
|
+ else
|
||||||
|
+ return sfs.f_bsize * sfs.f_blocks;
|
||||||
|
+}
|
||||||
|
diff --git a/utils.h b/utils.h
|
||||||
|
index db8d63c396d5..581faa9f6972 100644
|
||||||
|
--- a/utils.h
|
||||||
|
+++ b/utils.h
|
||||||
|
@@ -101,5 +101,6 @@ int get_btrfs_mount(const char *dev, char *mp, size_t mp_size);
|
||||||
|
int find_mount_root(const char *path, char **mount_root);
|
||||||
|
int get_device_info(int fd, u64 devid,
|
||||||
|
struct btrfs_ioctl_dev_info_args *di_args);
|
||||||
|
+u64 disk_size(char *path);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
261
0012-btrfs-progs-Add-helpers-functions-to-handle-the-prin.patch
Normal file
261
0012-btrfs-progs-Add-helpers-functions-to-handle-the-prin.patch
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
From a79f61440afaa0b77dc67c896fa3367a171c2306 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Goffredo Baroncelli <kreijack@libero.it>
|
||||||
|
Date: Thu, 13 Feb 2014 20:19:21 +0100
|
||||||
|
Subject: [PATCH 23/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
|
||||||
|
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index 50fb9b0ff2e3..bf6dc1c67d2c 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -10,7 +10,7 @@ objects = ctree.o disk-io.o radix-tree.o extent-tree.o print-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 \
|
||||||
|
- utils-lib.o
|
||||||
|
+ utils-lib.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 \
|
||||||
|
diff --git a/string_table.c b/string_table.c
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000000..016356c50392
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/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);
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
diff --git a/string_table.h b/string_table.h
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000000..83c4425d5f76
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/string_table.h
|
||||||
|
@@ -0,0 +1,36 @@
|
||||||
|
+/*
|
||||||
|
+ * This program is free software; you can redistribute it and/or
|
||||||
|
+ * modify it under the terms of the GNU General Public
|
||||||
|
+ * License v2 as published by the Free Software Foundation.
|
||||||
|
+ *
|
||||||
|
+ * This program is distributed in the hope that it will be useful,
|
||||||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ * General Public License for more details.
|
||||||
|
+ *
|
||||||
|
+ * You should have received a copy of the GNU General Public
|
||||||
|
+ * License along with this program; if not, write to the
|
||||||
|
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
+ * Boston, MA 021110-1307, USA.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef STRING_TABLE_H
|
||||||
|
+#define STRING_TABLE_H
|
||||||
|
+
|
||||||
|
+struct string_table {
|
||||||
|
+
|
||||||
|
+ int ncols, nrows;
|
||||||
|
+ char *cells[];
|
||||||
|
+
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+struct string_table *table_create(int columns, int rows);
|
||||||
|
+char *table_printf(struct string_table *tab, int column, int row,
|
||||||
|
+ char *fmt, ...);
|
||||||
|
+char *table_vprintf(struct string_table *tab, int column, int row,
|
||||||
|
+ char *fmt, va_list ap);
|
||||||
|
+void table_dump(struct string_table *tab);
|
||||||
|
+void table_free(struct string_table *);
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
581
0013-btrfs-progs-Add-command-btrfs-filesystem-disk-usage.patch
Normal file
581
0013-btrfs-progs-Add-command-btrfs-filesystem-disk-usage.patch
Normal file
@ -0,0 +1,581 @@
|
|||||||
|
From bb2b9f64b992f166533cc0d06aeec9518795d24a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Goffredo Baroncelli <kreijack@libero.it>
|
||||||
|
Date: Thu, 13 Feb 2014 20:19:50 +0100
|
||||||
|
Subject: [PATCH 24/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 | 60 ++++++++
|
||||||
|
utils.h | 5 +
|
||||||
|
5 files changed, 499 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||||
|
index 4012c781f20d..16b3ab250956 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 = 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 = 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= group_type_str(flags);
|
||||||
|
+ r_mode = 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 0edfb50daca2..214a0cda518c 100644
|
||||||
|
--- a/cmds-filesystem.c
|
||||||
|
+++ b/cmds-filesystem.c
|
||||||
|
@@ -918,6 +918,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 7731b071f353..f2ab416c28b2 100644
|
||||||
|
--- a/utils.c
|
||||||
|
+++ b/utils.c
|
||||||
|
@@ -2218,3 +2218,63 @@ 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;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Convert a chunk type to a chunk description
|
||||||
|
+ */
|
||||||
|
+const char *group_type_str(u64 flag)
|
||||||
|
+{
|
||||||
|
+ switch (flag & BTRFS_BLOCK_GROUP_TYPE_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";
|
||||||
|
+ default:
|
||||||
|
+ return "unknown";
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Convert a chunk type to a chunk profile description
|
||||||
|
+ */
|
||||||
|
+const 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";
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/utils.h b/utils.h
|
||||||
|
index 581faa9f6972..2d08e0b2a3a4 100644
|
||||||
|
--- a/utils.h
|
||||||
|
+++ b/utils.h
|
||||||
|
@@ -102,5 +102,10 @@ int find_mount_root(const char *path, char **mount_root);
|
||||||
|
int get_device_info(int fd, u64 devid,
|
||||||
|
struct btrfs_ioctl_dev_info_args *di_args);
|
||||||
|
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);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
193
0014-btrfs-progs-Add-btrfs-device-disk-usage-command.patch
Normal file
193
0014-btrfs-progs-Add-btrfs-device-disk-usage-command.patch
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
From b8eb50e005cc92d870faf6bfe285950c4ac66e09 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Goffredo Baroncelli <kreijack@libero.it>
|
||||||
|
Date: Thu, 13 Feb 2014 20:20:12 +0100
|
||||||
|
Subject: [PATCH 25/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 29da661e2a0d..f2e08ba55ba6 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"
|
||||||
|
|
||||||
|
@@ -435,6 +436,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 16b3ab250956..e4eb72be0a88 100644
|
||||||
|
--- a/cmds-fi-disk_usage.c
|
||||||
|
+++ b/cmds-fi-disk_usage.c
|
||||||
|
@@ -942,3 +942,139 @@ int cmd_filesystem_disk_usage(int argc, char **argv)
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static void print_disk_chunks(int fd,
|
||||||
|
+ u64 devid,
|
||||||
|
+ u64 total_size,
|
||||||
|
+ struct chunk_info *chunks_info_ptr,
|
||||||
|
+ int chunks_info_count,
|
||||||
|
+ int mode)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+ u64 allocated = 0;
|
||||||
|
+
|
||||||
|
+ for (i = 0 ; i < chunks_info_count ; i++) {
|
||||||
|
+ const char *description;
|
||||||
|
+ const char *r_mode;
|
||||||
|
+ u64 flags;
|
||||||
|
+ u64 size;
|
||||||
|
+
|
||||||
|
+ if (chunks_info_ptr[i].devid != devid)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ flags = chunks_info_ptr[i].type;
|
||||||
|
+
|
||||||
|
+ description = group_type_str(flags);
|
||||||
|
+ r_mode = group_profile_str(flags);
|
||||||
|
+ size = calc_chunk_size(chunks_info_ptr+i);
|
||||||
|
+ printf(" %s,%s:%*s%10s\n",
|
||||||
|
+ description,
|
||||||
|
+ r_mode,
|
||||||
|
+ (int)(20 - strlen(description) - strlen(r_mode)), "",
|
||||||
|
+ df_pretty_sizes(size, mode));
|
||||||
|
+
|
||||||
|
+ allocated += size;
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+ printf(" Unallocated: %*s%10s\n",
|
||||||
|
+ (int)(20 - strlen("Unallocated")), "",
|
||||||
|
+ df_pretty_sizes(total_size - allocated, mode));
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int _cmd_device_disk_usage(int fd, char *path, int mode)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+ int ret = 0;
|
||||||
|
+ int info_count = 0;
|
||||||
|
+ struct chunk_info *info_ptr = 0;
|
||||||
|
+ struct disk_info *disks_info_ptr = 0;
|
||||||
|
+ int disks_info_count = 0;
|
||||||
|
+
|
||||||
|
+ if (load_chunk_info(fd, &info_ptr, &info_count) ||
|
||||||
|
+ load_disks_info(fd, &disks_info_ptr, &disks_info_count)) {
|
||||||
|
+ ret = -1;
|
||||||
|
+ goto exit;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = 0 ; i < disks_info_count ; i++) {
|
||||||
|
+ printf("%s\t%10s\n", disks_info_ptr[i].path,
|
||||||
|
+ df_pretty_sizes(disks_info_ptr[i].size, mode));
|
||||||
|
+
|
||||||
|
+ print_disk_chunks(fd, disks_info_ptr[i].devid,
|
||||||
|
+ disks_info_ptr[i].size,
|
||||||
|
+ info_ptr, info_count,
|
||||||
|
+ mode);
|
||||||
|
+ printf("\n");
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+exit:
|
||||||
|
+
|
||||||
|
+ if (disks_info_ptr)
|
||||||
|
+ free(disks_info_ptr);
|
||||||
|
+ if (info_ptr)
|
||||||
|
+ free(info_ptr);
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const char * const cmd_device_disk_usage_usage[] = {
|
||||||
|
+ "btrfs device disk-usage [-b] <path> [<path>..]",
|
||||||
|
+ "Show which chunks are in a device.",
|
||||||
|
+ "",
|
||||||
|
+ "-b\tSet byte as unit",
|
||||||
|
+ NULL
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+int cmd_device_disk_usage(int argc, char **argv)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ int flags = DF_HUMAN_UNIT;
|
||||||
|
+ int i, more_than_one = 0;
|
||||||
|
+
|
||||||
|
+ optind = 1;
|
||||||
|
+ while (1) {
|
||||||
|
+ char c = getopt(argc, argv, "b");
|
||||||
|
+
|
||||||
|
+ if (c < 0)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ switch (c) {
|
||||||
|
+ case 'b':
|
||||||
|
+ flags &= ~DF_HUMAN_UNIT;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ usage(cmd_device_disk_usage_usage);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (check_argc_min(argc - optind, 1)) {
|
||||||
|
+ usage(cmd_device_disk_usage_usage);
|
||||||
|
+ return 21;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = optind; i < argc ; i++) {
|
||||||
|
+ int r, fd;
|
||||||
|
+ DIR *dirstream = NULL;
|
||||||
|
+ if (more_than_one)
|
||||||
|
+ printf("\n");
|
||||||
|
+
|
||||||
|
+ fd = open_file_or_dir(argv[i], &dirstream);
|
||||||
|
+ if (fd < 0) {
|
||||||
|
+ fprintf(stderr, "ERROR: can't access to '%s'\n",
|
||||||
|
+ argv[1]);
|
||||||
|
+ return 12;
|
||||||
|
+ }
|
||||||
|
+ r = _cmd_device_disk_usage(fd, argv[i], flags);
|
||||||
|
+ close_file_or_dir(fd, dirstream);
|
||||||
|
+
|
||||||
|
+ if (r)
|
||||||
|
+ return r;
|
||||||
|
+ more_than_one = 1;
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/cmds-fi-disk_usage.h b/cmds-fi-disk_usage.h
|
||||||
|
index 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
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
@ -0,0 +1,57 @@
|
|||||||
|
From a604369c26e4e816579c59d7a595279b1b720cbc 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 26/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 e4eb72be0a88..a3b06bebba72 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;
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
28
0016-btrfs-progs-Fix-memleak-in-get_raid56_used.patch
Normal file
28
0016-btrfs-progs-Fix-memleak-in-get_raid56_used.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
From ef568dad3da6887e656be617a178cbb69b36cdf3 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 27/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 a3b06bebba72..2bd591db0f8a 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;
|
||||||
|
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
38
0017-Btrfs-progs-fi-usage-free-memory-if-realloc-fails.patch
Normal file
38
0017-Btrfs-progs-fi-usage-free-memory-if-realloc-fails.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From b43d0660526d1a3e81f34fd499eb1dd038b00e08 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rakesh Pandit <rakesh@tuxera.com>
|
||||||
|
Date: Sat, 19 Apr 2014 14:12:03 +0300
|
||||||
|
Subject: [PATCH 28/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 2bd591db0f8a..cd71c8da3cf4 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
@ -0,0 +1,60 @@
|
|||||||
|
From 28c2061817b8cb266458249cc7bdd770eb2b407b Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Thu, 16 Jan 2014 14:18:37 +0100
|
||||||
|
Subject: [PATCH 29/42] btrfs-progs: read global reserve size from space infos
|
||||||
|
|
||||||
|
Kernels >= 3.15 export the global block reserve as a space info presented
|
||||||
|
by 'btrfs fi df' but would display 'unknown' instead of some meaningful
|
||||||
|
string.
|
||||||
|
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
ctree.h | 6 ++++++
|
||||||
|
utils.c | 7 ++++++-
|
||||||
|
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/ctree.h b/ctree.h
|
||||||
|
index 8ac17619b9dc..5c43fc5f5f6e 100644
|
||||||
|
--- a/ctree.h
|
||||||
|
+++ b/ctree.h
|
||||||
|
@@ -862,6 +862,12 @@ struct btrfs_csum_item {
|
||||||
|
/* used in struct btrfs_balance_args fields */
|
||||||
|
#define BTRFS_AVAIL_ALLOC_BIT_SINGLE (1ULL << 48)
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * GLOBAL_RSV does not exist as a on-disk block group type and is used
|
||||||
|
+ * internally for exporting info about global block reserve from space infos
|
||||||
|
+ */
|
||||||
|
+#define BTRFS_SPACE_INFO_GLOBAL_RSV (1ULL << 49)
|
||||||
|
+
|
||||||
|
#define BTRFS_QGROUP_STATUS_OFF 0
|
||||||
|
#define BTRFS_QGROUP_STATUS_ON 1
|
||||||
|
#define BTRFS_QGROUP_STATUS_SCANNING 2
|
||||||
|
diff --git a/utils.c b/utils.c
|
||||||
|
index f2ab416c28b2..ca150404ea6f 100644
|
||||||
|
--- a/utils.c
|
||||||
|
+++ b/utils.c
|
||||||
|
@@ -2240,7 +2240,10 @@ u64 get_partition_size(char *dev)
|
||||||
|
*/
|
||||||
|
const char *group_type_str(u64 flag)
|
||||||
|
{
|
||||||
|
- switch (flag & BTRFS_BLOCK_GROUP_TYPE_MASK) {
|
||||||
|
+ 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:
|
||||||
|
@@ -2249,6 +2252,8 @@ const char *group_type_str(u64 flag)
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
289
0019-btrfs-progs-add-original-df-and-rename-disk_usage-to.patch
Normal file
289
0019-btrfs-progs-add-original-df-and-rename-disk_usage-to.patch
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
From 90cbd00127631b5f8964d5518d6b22bfe994a686 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Wed, 23 Apr 2014 18:47:52 +0200
|
||||||
|
Subject: [PATCH 30/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 | 55 ++++++++++++++++++++++++++++++++--
|
||||||
|
3 files changed, 71 insertions(+), 76 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||||
|
index cd71c8da3cf4..efc640d13148 100644
|
||||||
|
--- a/cmds-fi-disk_usage.c
|
||||||
|
+++ b/cmds-fi-disk_usage.c
|
||||||
|
@@ -328,6 +328,8 @@ 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
|
||||||
|
@@ -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_info *ci)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * 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_type,
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * 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_linear(int mode,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
-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(int fd, char *path, int mode, int tabular)
|
||||||
|
}
|
||||||
|
|
||||||
|
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_usage_usage[] = {
|
||||||
|
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, char **argv)
|
||||||
|
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, char **argv)
|
||||||
|
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)
|
||||||
|
diff --git a/cmds-fi-disk_usage.h b/cmds-fi-disk_usage.h
|
||||||
|
index c315004cd806..95cf4aabefb4 100644
|
||||||
|
--- a/cmds-fi-disk_usage.h
|
||||||
|
+++ b/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);
|
||||||
|
diff --git a/cmds-filesystem.c b/cmds-filesystem.c
|
||||||
|
index 214a0cda518c..9340cb61cabe 100644
|
||||||
|
--- a/cmds-filesystem.c
|
||||||
|
+++ b/cmds-filesystem.c
|
||||||
|
@@ -113,6 +113,26 @@ static const char * const filesystem_cmd_group_usage[] = {
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
+static const char * const cmd_filesystem_df_usage[] = {
|
||||||
|
+ "btrfs filesystem df <path>",
|
||||||
|
+ "Show space usage information for a mount point",
|
||||||
|
+ NULL
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static void print_df(struct btrfs_ioctl_space_args *sargs)
|
||||||
|
+{
|
||||||
|
+ u64 i;
|
||||||
|
+ struct btrfs_ioctl_space_info *sp = sargs->spaces;
|
||||||
|
+
|
||||||
|
+ 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),
|
||||||
|
+ pretty_size(sp->total_bytes),
|
||||||
|
+ pretty_size(sp->used_bytes));
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int get_df(int fd, struct btrfs_ioctl_space_args **sargs_ret)
|
||||||
|
{
|
||||||
|
u64 count = 0;
|
||||||
|
@@ -161,6 +181,37 @@ static int get_df(int fd, struct btrfs_ioctl_space_args **sargs_ret)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int cmd_filesystem_df(int argc, char **argv)
|
||||||
|
+{
|
||||||
|
+ struct btrfs_ioctl_space_args *sargs = NULL;
|
||||||
|
+ int ret;
|
||||||
|
+ int fd;
|
||||||
|
+ char *path;
|
||||||
|
+ DIR *dirstream = NULL;
|
||||||
|
+
|
||||||
|
+ if (check_argc_exact(argc, 2))
|
||||||
|
+ usage(cmd_filesystem_df_usage);
|
||||||
|
+
|
||||||
|
+ path = argv[1];
|
||||||
|
+
|
||||||
|
+ fd = open_file_or_dir(path, &dirstream);
|
||||||
|
+ if (fd < 0) {
|
||||||
|
+ fprintf(stderr, "ERROR: can't access '%s'\n", path);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ ret = get_df(fd, &sargs);
|
||||||
|
+
|
||||||
|
+ if (!ret && sargs) {
|
||||||
|
+ print_df(sargs);
|
||||||
|
+ free(sargs);
|
||||||
|
+ } else {
|
||||||
|
+ fprintf(stderr, "ERROR: get_df failed %s\n", strerror(-ret));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ close_file_or_dir(fd, dirstream);
|
||||||
|
+ return !!ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int match_search_item_kernel(__u8 *fsid, char *mnt, char *label,
|
||||||
|
char *search)
|
||||||
|
{
|
||||||
|
@@ -918,8 +969,8 @@ 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 },
|
||||||
|
+ { "usage", cmd_filesystem_usage,
|
||||||
|
+ cmd_filesystem_usage_usage, NULL, 0 },
|
||||||
|
|
||||||
|
NULL_CMD_STRUCT
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
712
0020-btrfs-progs-move-device-usage-to-cmds-device-more-cl.patch
Normal file
712
0020-btrfs-progs-move-device-usage-to-cmds-device-more-cl.patch
Normal file
@ -0,0 +1,712 @@
|
|||||||
|
From 14462c746c40b97dd8efe0bea18cbc6372431a39 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Wed, 23 Apr 2014 19:00:22 +0200
|
||||||
|
Subject: [PATCH 31/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 f2e08ba55ba6..c20b26e9be90 100644
|
||||||
|
--- a/cmds-device.c
|
||||||
|
+++ b/cmds-device.c
|
||||||
|
@@ -429,6 +429,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 },
|
||||||
|
@@ -436,8 +528,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 efc640d13148..023659daac0e 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
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From a6979c52fbff0e0961a0a0546c45bca11f6a0658 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Thu, 24 Apr 2014 15:21:16 +0200
|
||||||
|
Subject: [PATCH 32/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 023659daac0e..3fa2af004dc4 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;
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
@ -0,0 +1,44 @@
|
|||||||
|
From 70b51a393b7d9ee6d20b16be0c925c58ea88f3c5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Thu, 24 Apr 2014 18:37:50 +0200
|
||||||
|
Subject: [PATCH 33/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 3fa2af004dc4..8c0462230510 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)
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
28
0023-btrfs-progs-print-B-for-bytes.patch
Normal file
28
0023-btrfs-progs-print-B-for-bytes.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
From 86b1a432b74285db0096fdd4894626cb26773eeb Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Thu, 24 Apr 2014 18:31:28 +0200
|
||||||
|
Subject: [PATCH 34/42] btrfs-progs: print B for bytes
|
||||||
|
|
||||||
|
This arguably helps parsers.
|
||||||
|
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
utils.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/utils.c b/utils.c
|
||||||
|
index ca150404ea6f..159abf8bd0e4 100644
|
||||||
|
--- a/utils.c
|
||||||
|
+++ b/utils.c
|
||||||
|
@@ -1252,7 +1252,7 @@ out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static char *size_strs[] = { "", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"};
|
||||||
|
+static char *size_strs[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"};
|
||||||
|
int pretty_size_snprintf(u64 size, char *str, size_t str_bytes)
|
||||||
|
{
|
||||||
|
int num_divs = 0;
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
101
0024-btrfs-progs-Print-more-info-about-device-sizes.patch
Normal file
101
0024-btrfs-progs-Print-more-info-about-device-sizes.patch
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
From c856f30b979c71ab5cda62753993e725dae922e6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Thu, 24 Apr 2014 18:32:27 +0200
|
||||||
|
Subject: [PATCH 35/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 occuppied: 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 | 13 ++++++++++++-
|
||||||
|
cmds-fi-disk_usage.h | 6 +++++-
|
||||||
|
3 files changed, 20 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cmds-device.c b/cmds-device.c
|
||||||
|
index c20b26e9be90..154188643c8f 100644
|
||||||
|
--- a/cmds-device.c
|
||||||
|
+++ b/cmds-device.c
|
||||||
|
@@ -453,9 +453,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 8c0462230510..63ed9ba089d5 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_size;
|
||||||
|
++ndevs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -879,5 +880,15 @@ 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 occuppied:%*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
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
@ -0,0 +1,96 @@
|
|||||||
|
From a2b5656ac87bd741153b97ac1e7bcf40ecc4f16c Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Thu, 24 Apr 2014 18:57:12 +0200
|
||||||
|
Subject: [PATCH 36/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 | 9 ++++-----
|
||||||
|
cmds-fi-disk_usage.h | 2 +-
|
||||||
|
3 files changed, 7 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cmds-device.c b/cmds-device.c
|
||||||
|
index 154188643c8f..3e851badc116 100644
|
||||||
|
--- a/cmds-device.c
|
||||||
|
+++ b/cmds-device.c
|
||||||
|
@@ -456,10 +456,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 63ed9ba089d5..0e93dc836f16 100644
|
||||||
|
--- a/cmds-fi-disk_usage.c
|
||||||
|
+++ b/cmds-fi-disk_usage.c
|
||||||
|
@@ -500,7 +500,7 @@ 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].device_size = get_partition_size((char *)dev_info.path);
|
||||||
|
- info[ndevs].size = dev_info.total_size;
|
||||||
|
+ info[ndevs].size = dev_info.total_bytes;
|
||||||
|
++ndevs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
@@ -890,5 +890,4 @@ void print_device_sizes(int fd, struct device_info *devinfo, int mode)
|
||||||
|
printf(" FS occuppied:%*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 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);
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
107
0026-btrfs-progs-add-section-of-overall-filesystem-usage.patch
Normal file
107
0026-btrfs-progs-add-section-of-overall-filesystem-usage.patch
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
From d8ca04ddc42461c462e3b52031e1134f01c71663 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Fri, 25 Apr 2014 17:24:40 +0200
|
||||||
|
Subject: [PATCH 37/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 0e93dc836f16..e17f04e31d35 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);
|
||||||
|
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
372
0027-btrfs-progs-cleanup-filesystem-device-usage-code.patch
Normal file
372
0027-btrfs-progs-cleanup-filesystem-device-usage-code.patch
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
From e81d2614ff21e3e9e723cc645cc73646a42d06e8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Fri, 25 Apr 2014 19:39:11 +0200
|
||||||
|
Subject: [PATCH 38/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 3e851badc116..bf5898f6da68 100644
|
||||||
|
--- a/cmds-device.c
|
||||||
|
+++ b/cmds-device.c
|
||||||
|
@@ -441,31 +441,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;
|
||||||
|
}
|
||||||
|
@@ -507,6 +505,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 e17f04e31d35..9d1c4085b4ea 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,
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
172
0028-btrfs-progs-extend-pretty-printers-with-unit-mode.patch
Normal file
172
0028-btrfs-progs-extend-pretty-printers-with-unit-mode.patch
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
From f54a92b54b57ea8be8d55ea012c9b69c9f0db5ff Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Mon, 28 Apr 2014 18:04:48 +0200
|
||||||
|
Subject: [PATCH 39/42] btrfs-progs: extend pretty printers with unit mode
|
||||||
|
|
||||||
|
The functionality of pretty unit printing was duplicated by
|
||||||
|
df_pretty_sizes, merge it with pretty_size and enhance the interface
|
||||||
|
with more suffix mode. Raw, binary or decimal.
|
||||||
|
|
||||||
|
Signed-off-by: David Sterba <dsterba@suse.cz>
|
||||||
|
---
|
||||||
|
cmds-fi-disk_usage.c | 9 ++-----
|
||||||
|
utils.c | 71 ++++++++++++++++++++++++++++++++++++----------------
|
||||||
|
utils.h | 21 +++++++++++-----
|
||||||
|
3 files changed, 66 insertions(+), 35 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c
|
||||||
|
index 9d1c4085b4ea..1e412c0b0e69 100644
|
||||||
|
--- a/cmds-fi-disk_usage.c
|
||||||
|
+++ b/cmds-fi-disk_usage.c
|
||||||
|
@@ -33,18 +33,13 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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));
|
||||||
|
+ return pretty_size_mode(size, UNITS_HUMAN);
|
||||||
|
else
|
||||||
|
- sprintf(buf, "%llu", size);
|
||||||
|
-
|
||||||
|
- return buf;
|
||||||
|
+ return pretty_size_mode(size, UNITS_RAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/utils.c b/utils.c
|
||||||
|
index 159abf8bd0e4..69112be51cb2 100644
|
||||||
|
--- a/utils.c
|
||||||
|
+++ b/utils.c
|
||||||
|
@@ -1252,35 +1252,62 @@ out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static char *size_strs[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"};
|
||||||
|
-int pretty_size_snprintf(u64 size, char *str, size_t str_bytes)
|
||||||
|
+static const char const *unit_suffix_binary[] =
|
||||||
|
+ { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"};
|
||||||
|
+static const char const *unit_suffix_decimal[] =
|
||||||
|
+ { "B", "KB", "MB", "GB", "TB", "PB", "EB"};
|
||||||
|
+
|
||||||
|
+int pretty_size_snprintf(u64 size, char *str, size_t str_size, int unit_mode)
|
||||||
|
{
|
||||||
|
- int num_divs = 0;
|
||||||
|
+ int num_divs;
|
||||||
|
float fraction;
|
||||||
|
+ int base = 0;
|
||||||
|
+ const char const **suffix = NULL;
|
||||||
|
+ u64 last_size;
|
||||||
|
|
||||||
|
- if (str_bytes == 0)
|
||||||
|
+ if (str_size == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- if( size < 1024 ){
|
||||||
|
- fraction = size;
|
||||||
|
- num_divs = 0;
|
||||||
|
- } else {
|
||||||
|
- u64 last_size = size;
|
||||||
|
- num_divs = 0;
|
||||||
|
- while(size >= 1024){
|
||||||
|
- last_size = size;
|
||||||
|
- size /= 1024;
|
||||||
|
- num_divs ++;
|
||||||
|
- }
|
||||||
|
+ if (unit_mode == UNITS_RAW) {
|
||||||
|
+ snprintf(str, str_size, "%llu", size);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (num_divs >= ARRAY_SIZE(size_strs)) {
|
||||||
|
- str[0] = '\0';
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- fraction = (float)last_size / 1024;
|
||||||
|
+ if (unit_mode == UNITS_BINARY) {
|
||||||
|
+ base = 1024;
|
||||||
|
+ suffix = unit_suffix_binary;
|
||||||
|
+ } else if (unit_mode == UNITS_DECIMAL) {
|
||||||
|
+ base = 1000;
|
||||||
|
+ suffix = unit_suffix_decimal;
|
||||||
|
}
|
||||||
|
- return snprintf(str, str_bytes, "%.2f%s", fraction,
|
||||||
|
- size_strs[num_divs]);
|
||||||
|
+
|
||||||
|
+ /* Unknown mode */
|
||||||
|
+ if (!base) {
|
||||||
|
+ fprintf(stderr, "INTERNAL ERROR: unknown unit base, mode %d",
|
||||||
|
+ unit_mode);
|
||||||
|
+ assert(0);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ num_divs = 0;
|
||||||
|
+ last_size = size;
|
||||||
|
+
|
||||||
|
+ while (size >= base) {
|
||||||
|
+ last_size = size;
|
||||||
|
+ size /= base;
|
||||||
|
+ num_divs++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (num_divs >= ARRAY_SIZE(unit_suffix_binary)) {
|
||||||
|
+ str[0] = '\0';
|
||||||
|
+ printf("INTERNAL ERROR: unsupported unit suffix, index %d\n",
|
||||||
|
+ num_divs);
|
||||||
|
+ assert(0);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ fraction = (float)last_size / base;
|
||||||
|
+
|
||||||
|
+ return snprintf(str, str_size, "%.2f%s", fraction, suffix[num_divs]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/utils.h b/utils.h
|
||||||
|
index 2d08e0b2a3a4..3aea8b47d9e7 100644
|
||||||
|
--- a/utils.h
|
||||||
|
+++ b/utils.h
|
||||||
|
@@ -39,6 +39,14 @@
|
||||||
|
|
||||||
|
#define BTRFS_UUID_UNPARSED_SIZE 37
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Output mode of byte units
|
||||||
|
+ */
|
||||||
|
+#define UNITS_RAW (1)
|
||||||
|
+#define UNITS_BINARY (2)
|
||||||
|
+#define UNITS_DECIMAL (3)
|
||||||
|
+#define UNITS_HUMAN UNITS_BINARY
|
||||||
|
+
|
||||||
|
int make_btrfs(int fd, const char *device, const char *label,
|
||||||
|
u64 blocks[6], u64 num_bytes, u32 nodesize,
|
||||||
|
u32 leafsize, u32 sectorsize, u32 stripesize, u64 features);
|
||||||
|
@@ -59,12 +67,13 @@ int check_mounted_where(int fd, const char *file, char *where, int size,
|
||||||
|
int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
|
||||||
|
int super_offset);
|
||||||
|
|
||||||
|
-int pretty_size_snprintf(u64 size, char *str, size_t str_bytes);
|
||||||
|
-#define pretty_size(size) \
|
||||||
|
- ({ \
|
||||||
|
- static __thread char _str[24]; \
|
||||||
|
- (void)pretty_size_snprintf((size), _str, sizeof(_str)); \
|
||||||
|
- _str; \
|
||||||
|
+int pretty_size_snprintf(u64 size, char *str, size_t str_bytes, int unit_mode);
|
||||||
|
+#define pretty_size(size) pretty_size_mode(size, UNITS_BINARY)
|
||||||
|
+#define pretty_size_mode(size, mode) \
|
||||||
|
+ ({ \
|
||||||
|
+ static __thread char _str[32]; \
|
||||||
|
+ (void)pretty_size_snprintf((size), _str, sizeof(_str), mode); \
|
||||||
|
+ _str; \
|
||||||
|
})
|
||||||
|
|
||||||
|
int get_mountpt(char *dev, char *mntpt, size_t size);
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
263
0029-btrfs-progs-replace-df_pretty_sizes-with-pretty_size.patch
Normal file
263
0029-btrfs-progs-replace-df_pretty_sizes-with-pretty_size.patch
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
From a1764abe279f04a664d2745d6d2ce49db722bce3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Mon, 28 Apr 2014 18:13:16 +0200
|
||||||
|
Subject: [PATCH 40/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 | 63 ++++++++++++++++++++++------------------------------
|
||||||
|
cmds-fi-disk_usage.h | 3 ---
|
||||||
|
3 files changed, 30 insertions(+), 44 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cmds-device.c b/cmds-device.c
|
||||||
|
index bf5898f6da68..eb6b79ca5127 100644
|
||||||
|
--- a/cmds-device.c
|
||||||
|
+++ b/cmds-device.c
|
||||||
|
@@ -471,19 +471,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);
|
||||||
|
@@ -506,7 +506,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 1e412c0b0e69..d1b8bbddc4d5 100644
|
||||||
|
--- a/cmds-fi-disk_usage.c
|
||||||
|
+++ b/cmds-fi-disk_usage.c
|
||||||
|
@@ -32,17 +32,6 @@
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Pretty print the size
|
||||||
|
- */
|
||||||
|
-char *df_pretty_sizes(u64 size, int mode)
|
||||||
|
-{
|
||||||
|
- if (mode & DF_HUMAN_UNIT)
|
||||||
|
- return pretty_size_mode(size, UNITS_HUMAN);
|
||||||
|
- else
|
||||||
|
- return pretty_size_mode(size, UNITS_RAW);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-/*
|
||||||
|
* Add the chunk info to the chunk_info list
|
||||||
|
*/
|
||||||
|
static int add_info_to_list(struct chunk_info **info_ptr,
|
||||||
|
@@ -389,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;
|
||||||
|
@@ -397,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:
|
||||||
|
|
||||||
|
@@ -612,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, ">-");
|
||||||
|
|
||||||
|
@@ -624,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;
|
||||||
|
|
||||||
|
}
|
||||||
|
@@ -636,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);
|
||||||
|
@@ -670,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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -704,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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -732,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");
|
||||||
|
@@ -787,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;
|
||||||
|
|
||||||
|
@@ -800,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;
|
||||||
|
@@ -837,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);
|
||||||
|
@@ -881,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 occuppied:%*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);
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
233
0030-btrfs-progs-clean-up-return-codes-and-paths.patch
Normal file
233
0030-btrfs-progs-clean-up-return-codes-and-paths.patch
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
From 2c574dd5564fbe11a9e6e9c707fa907a7418c687 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Mon, 28 Apr 2014 18:55:05 +0200
|
||||||
|
Subject: [PATCH 41/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 eb6b79ca5127..6dd5b05c7651 100644
|
||||||
|
--- a/cmds-device.c
|
||||||
|
+++ b/cmds-device.c
|
||||||
|
@@ -448,10 +448,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);
|
||||||
|
@@ -461,7 +459,7 @@ static int _cmd_device_usage(int fd, char *path, int mode)
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
-exit:
|
||||||
|
+out:
|
||||||
|
free(devinfo);
|
||||||
|
free(chunkinfo);
|
||||||
|
|
||||||
|
@@ -472,6 +470,7 @@ int cmd_device_usage(int argc, char **argv)
|
||||||
|
{
|
||||||
|
|
||||||
|
int mode = UNITS_HUMAN;
|
||||||
|
+ int ret = 0;
|
||||||
|
int i, more_than_one = 0;
|
||||||
|
|
||||||
|
optind = 1;
|
||||||
|
@@ -494,28 +493,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 d1b8bbddc4d5..7c93247e4f54 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,
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
@ -0,0 +1,96 @@
|
|||||||
|
From 552e2741a3b0ce344c73b3e1d80d385605d49e75 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Sterba <dsterba@suse.cz>
|
||||||
|
Date: Tue, 29 Apr 2014 17:32:22 +0200
|
||||||
|
Subject: [PATCH 42/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 7c93247e4f54..0caba159b974 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 = 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= group_type_str(flags);
|
||||||
|
r_mode = group_profile_str(flags);
|
||||||
|
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
3
btrfs-progs-v3.14.1.tar.bz2
Normal file
3
btrfs-progs-v3.14.1.tar.bz2
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:91b731c9889cdad80d36e6f0345b9dc6fa0e7f98eda5730bfd88947ff4afedb1
|
||||||
|
size 281329
|
@ -1,3 +0,0 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:d5680d1ae0a88f6f07350e1dd8e81a1d6933bf7eccd4233c9d24f5a7b8f482bd
|
|
||||||
size 281254
|
|
@ -1,3 +1,53 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri May 2 13:37:04 UTC 2014 - dsterba@suse.cz
|
||||||
|
|
||||||
|
- update to upstream 3.14.1
|
||||||
|
- mkfs:
|
||||||
|
- fix TRIM detection
|
||||||
|
- do not zero-out end of device unconditionally
|
||||||
|
- no crash with --features option
|
||||||
|
- fsck:
|
||||||
|
- clear log tree in repair mode
|
||||||
|
- check reloc roots
|
||||||
|
- btrfs - reworked space reporting (bnc#873106)
|
||||||
|
- btrfs fi usage - new command
|
||||||
|
- btrfs dev usage - new command
|
||||||
|
- btrfs fi df - enhanced output with GlobalReserve
|
||||||
|
- Removed patches:
|
||||||
|
* 0001-btrfs-progs-move-arg_strtou64-to-a-separate-file-for.patch
|
||||||
|
- Added patches:
|
||||||
|
* 0001-Btrfs-progs-fix-check-to-test-trim-support.patch
|
||||||
|
* 0002-Btrfs-progs-fsck-fix-double-free-memory-crash.patch
|
||||||
|
* 0003-Btrfs-progs-mkfs-Remove-zero_end-1-since-it-has-been.patch
|
||||||
|
* 0004-btrfs-progs-fix-wrong-max-system-array-size-check-in.patch
|
||||||
|
* 0005-btrfs-progs-move-arg_strtou64-to-a-separate-file-for.patch
|
||||||
|
* 0006-Btrfs-progs-fsck-clear-out-log-tree-in-repair-mode.patch
|
||||||
|
* 0007-Btrfs-progs-fsck-avoid-pinning-same-block-several-ti.patch
|
||||||
|
* 0008-Btrfs-progs-fsck-add-ability-to-check-reloc-roots.patch
|
||||||
|
* 0009-btrfs-progs-prevent-close_root-if-the-root-to-close-.patch
|
||||||
|
* 0010-btrfs-progs-fix-mkfs.btrfs-segfault-with-features-op.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
|
||||||
|
* 0018-btrfs-progs-read-global-reserve-size-from-space-info.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
|
||||||
|
* 0023-btrfs-progs-print-B-for-bytes.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-extend-pretty-printers-with-unit-mode.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
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Sat Apr 26 09:45:23 UTC 2014 - coolo@suse.com
|
Sat Apr 26 09:45:23 UTC 2014 - coolo@suse.com
|
||||||
|
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
%define tar_version v3.14
|
%define tar_version v3.14.1
|
||||||
Name: btrfsprogs
|
Name: btrfsprogs
|
||||||
Version: 3.14
|
Version: 3.14.1
|
||||||
Release: 0
|
Release: 0
|
||||||
Summary: Utilities for the Btrfs filesystem
|
Summary: Utilities for the Btrfs filesystem
|
||||||
License: GPL-2.0
|
License: GPL-2.0
|
||||||
@ -31,7 +31,37 @@ Source: btrfs-progs-%{tar_version}.tar.bz2
|
|||||||
Source1: boot-btrfs.sh
|
Source1: boot-btrfs.sh
|
||||||
Source4: setup-btrfs.sh
|
Source4: setup-btrfs.sh
|
||||||
|
|
||||||
Patch1: 0001-btrfs-progs-move-arg_strtou64-to-a-separate-file-for.patch
|
Patch1: 0001-Btrfs-progs-fix-check-to-test-trim-support.patch
|
||||||
|
Patch2: 0002-Btrfs-progs-fsck-fix-double-free-memory-crash.patch
|
||||||
|
Patch3: 0003-Btrfs-progs-mkfs-Remove-zero_end-1-since-it-has-been.patch
|
||||||
|
Patch4: 0004-btrfs-progs-fix-wrong-max-system-array-size-check-in.patch
|
||||||
|
Patch5: 0005-btrfs-progs-move-arg_strtou64-to-a-separate-file-for.patch
|
||||||
|
Patch6: 0006-Btrfs-progs-fsck-clear-out-log-tree-in-repair-mode.patch
|
||||||
|
Patch7: 0007-Btrfs-progs-fsck-avoid-pinning-same-block-several-ti.patch
|
||||||
|
Patch8: 0008-Btrfs-progs-fsck-add-ability-to-check-reloc-roots.patch
|
||||||
|
Patch9: 0009-btrfs-progs-prevent-close_root-if-the-root-to-close-.patch
|
||||||
|
Patch10: 0010-btrfs-progs-fix-mkfs.btrfs-segfault-with-features-op.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
|
||||||
|
Patch18: 0018-btrfs-progs-read-global-reserve-size-from-space-info.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
|
||||||
|
Patch23: 0023-btrfs-progs-print-B-for-bytes.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-extend-pretty-printers-with-unit-mode.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
|
||||||
Patch164: 0164-btrfs-progs-convert-set-label-or-copy-from-origin.patch
|
Patch164: 0164-btrfs-progs-convert-set-label-or-copy-from-origin.patch
|
||||||
@ -77,6 +107,36 @@ build applications to interface with btrfs.
|
|||||||
%prep
|
%prep
|
||||||
%setup -q -n btrfs-progs-%{tar_version}
|
%setup -q -n btrfs-progs-%{tar_version}
|
||||||
%patch1 -p1
|
%patch1 -p1
|
||||||
|
%patch2 -p1
|
||||||
|
%patch3 -p1
|
||||||
|
%patch4 -p1
|
||||||
|
%patch5 -p1
|
||||||
|
%patch6 -p1
|
||||||
|
%patch7 -p1
|
||||||
|
%patch8 -p1
|
||||||
|
%patch9 -p1
|
||||||
|
%patch10 -p1
|
||||||
|
%patch11 -p1
|
||||||
|
%patch12 -p1
|
||||||
|
%patch13 -p1
|
||||||
|
%patch14 -p1
|
||||||
|
%patch15 -p1
|
||||||
|
%patch16 -p1
|
||||||
|
%patch17 -p1
|
||||||
|
%patch18 -p1
|
||||||
|
%patch19 -p1
|
||||||
|
%patch20 -p1
|
||||||
|
%patch21 -p1
|
||||||
|
%patch22 -p1
|
||||||
|
%patch23 -p1
|
||||||
|
%patch24 -p1
|
||||||
|
%patch25 -p1
|
||||||
|
%patch26 -p1
|
||||||
|
%patch27 -p1
|
||||||
|
%patch28 -p1
|
||||||
|
%patch29 -p1
|
||||||
|
%patch30 -p1
|
||||||
|
%patch31 -p1
|
||||||
%patch163 -p1
|
%patch163 -p1
|
||||||
%patch164 -p1
|
%patch164 -p1
|
||||||
%patch167 -p1
|
%patch167 -p1
|
||||||
|
@ -6,8 +6,8 @@ Index: btrfs-progs-v0.19-116-g13eced9/version.sh
|
|||||||
# Copyright 2008, Oracle
|
# Copyright 2008, Oracle
|
||||||
# Released under the GNU GPLv2
|
# Released under the GNU GPLv2
|
||||||
|
|
||||||
-v="v3.14"
|
-v="v3.14.1"
|
||||||
+v="v3.14+20140408"
|
+v="v3.14.1+20140502"
|
||||||
|
|
||||||
which git &> /dev/null
|
which git &> /dev/null
|
||||||
if [ $? == 0 -a -d .git ]; then
|
if [ $? == 0 -a -d .git ]; then
|
||||||
|
Loading…
Reference in New Issue
Block a user