commit btrfsprogs for openSUSE:Factory
Hello community, here is the log from the commit of package btrfsprogs for openSUSE:Factory checked in at 2014-05-06 13:39:23 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/btrfsprogs (Old) and /work/SRC/openSUSE:Factory/.btrfsprogs.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "btrfsprogs" Changes: -------- --- /work/SRC/openSUSE:Factory/btrfsprogs/btrfsprogs.changes 2014-04-30 15:00:47.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.btrfsprogs.new/btrfsprogs.changes 2014-05-06 13:39:27.000000000 +0200 @@ -1,0 +2,50 @@ +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 + +------------------------------------------------------------------- Old: ---- 0001-btrfs-progs-move-arg_strtou64-to-a-separate-file-for.patch btrfs-progs-v3.14.tar.bz2 New: ---- 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 btrfs-progs-v3.14.1.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ btrfsprogs.spec ++++++ --- /var/tmp/diff_new_pack.g4pZwt/_old 2014-05-06 13:39:28.000000000 +0200 +++ /var/tmp/diff_new_pack.g4pZwt/_new 2014-05-06 13:39:28.000000000 +0200 @@ -16,9 +16,9 @@ # -%define tar_version v3.14 +%define tar_version v3.14.1 Name: btrfsprogs -Version: 3.14 +Version: 3.14.1 Release: 0 Summary: Utilities for the Btrfs filesystem License: GPL-2.0 @@ -31,7 +31,37 @@ Source1: boot-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 Patch164: 0164-btrfs-progs-convert-set-label-or-copy-from-origin.patch @@ -77,6 +107,36 @@ %prep %setup -q -n btrfs-progs-%{tar_version} %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 %patch164 -p1 %patch167 -p1 ++++++ 0001-Btrfs-progs-fix-check-to-test-trim-support.patch ++++++
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 ++++++ 0002-Btrfs-progs-fsck-fix-double-free-memory-crash.patch ++++++
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 ++++++ 0003-Btrfs-progs-mkfs-Remove-zero_end-1-since-it-has-been.patch ++++++
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 ++++++ 0004-btrfs-progs-fix-wrong-max-system-array-size-check-in.patch ++++++
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 ++++++ 0001-btrfs-progs-move-arg_strtou64-to-a-separate-file-for.patch -> 0005-btrfs-progs-move-arg_strtou64-to-a-separate-file-for.patch ++++++ --- /work/SRC/openSUSE:Factory/btrfsprogs/0001-btrfs-progs-move-arg_strtou64-to-a-separate-file-for.patch 2014-04-14 06:43:25.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.btrfsprogs.new/0005-btrfs-progs-move-arg_strtou64-to-a-separate-file-for.patch 2014-05-06 13:39:26.000000000 +0200 @@ -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> 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 cannot just add utils.o to library objects because it's not library-clean. Reported-by: Arvin Schnell <aschnell@suse.com> +Reported-by: Anton Farygin <rider@altlinux.org> Signed-off-by: David Sterba <dsterba@suse.cz> --- - Makefile | 5 +++-- - libutils.c | 43 +++++++++++++++++++++++++++++++++++++++++++ - utils.c | 33 --------------------------------- - 3 files changed, 46 insertions(+), 35 deletions(-) - create mode 100644 libutils.c + Makefile | 5 +++-- + utils-lib.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + utils.c | 33 --------------------------------- + 3 files changed, 45 insertions(+), 35 deletions(-) + create mode 100644 utils-lib.c diff --git a/Makefile b/Makefile -index da0519766443..9ae7115d23a3 100644 +index 51d53fadf5af..76565e8b2307 100644 --- a/Makefile +++ b/Makefile @@ -9,14 +9,15 @@ CFLAGS = -g -O1 -fno-strict-aliasing @@ -26,7 +28,7 @@ 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 \ -+ libutils.o ++ utils-lib.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 \ @@ -34,16 +36,16 @@ cmds-property.o libbtrfs_objects = send-stream.o send-utils.o rbtree.o btrfs-list.o crc32c.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 \ crc32c.h list.h kerncompat.h radix-tree.h extent-cache.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 -index 000000000000..074f771e0b6e +index 000000000000..9d53c6e5c710 --- /dev/null -+++ b/libutils.c -@@ -0,0 +1,43 @@ ++++ b/utils-lib.c +@@ -0,0 +1,42 @@ +#define _GNU_SOURCE + +#include "kerncompat.h" @@ -56,8 +58,8 @@ +#endif /* BTRFS_FLAT_INCLUDES */ + +/* -+ * This function should be only used when parsing -+ * command arg, it won't return error to it's ++ * This function should be only used when parsing command arg, it won't return ++ * error to its caller and rather exit directly just like usage(). + */ +u64 arg_strtou64(const char *str) +{ @@ -70,10 +72,10 @@ + str); + exit(1); + } ++ + /* -+ * if we pass a negative number to strtoull, -+ * it will return an unexpected number to us, -+ * so let's do the check ourselves. ++ * if we pass a negative number to strtoull, it will return an ++ * unexpected number to us, so let's do the check ourselves. + */ + if (str[0] == '-') { + fprintf(stderr, "ERROR: %s: negative value is invalid.\n", @@ -86,12 +88,11 @@ + } + return value; +} -+ diff --git a/utils.c b/utils.c -index 3e9c527a492c..134f43a76fe9 100644 +index 29953d9dd2a9..e130849c7bb5 100644 --- a/utils.c +++ b/utils.c -@@ -1539,39 +1539,6 @@ scan_again: +@@ -1538,39 +1538,6 @@ scan_again: return 0; } ++++++ 0006-Btrfs-progs-fsck-clear-out-log-tree-in-repair-mode.patch ++++++
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 ++++++ 0007-Btrfs-progs-fsck-avoid-pinning-same-block-several-ti.patch ++++++
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 ++++++ 0008-Btrfs-progs-fsck-add-ability-to-check-reloc-roots.patch ++++++
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
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
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
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
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 ++++++ 0009-btrfs-progs-prevent-close_root-if-the-root-to-close-.patch ++++++ 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 ++++++ 0010-btrfs-progs-fix-mkfs.btrfs-segfault-with-features-op.patch ++++++ 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 ++++++ 0011-btrfs-progs-Enhance-the-command-btrfs-filesystem-df.patch ++++++ ++++ 771 lines (skipped) ++++++ 0012-btrfs-progs-Add-helpers-functions-to-handle-the-prin.patch ++++++ 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 ++++++ 0013-btrfs-progs-Add-command-btrfs-filesystem-disk-usage.patch ++++++
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 ++++++ 0014-btrfs-progs-Add-btrfs-device-disk-usage-command.patch ++++++
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 ++++++ 0015-btrfs-progs-cleanup-dead-return-after-usage-for-fi-d.patch ++++++
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 ++++++ 0016-btrfs-progs-Fix-memleak-in-get_raid56_used.patch ++++++
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 ++++++ 0017-Btrfs-progs-fi-usage-free-memory-if-realloc-fails.patch ++++++
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 ++++++ 0018-btrfs-progs-read-global-reserve-size-from-space-info.patch ++++++
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 ++++++ 0019-btrfs-progs-add-original-df-and-rename-disk_usage-to.patch ++++++
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 ++++++ 0020-btrfs-progs-move-device-usage-to-cmds-device-more-cl.patch ++++++ ++++ 712 lines (skipped) ++++++ 0021-btrfs-progs-check-if-we-can-t-get-info-from-ioctls-d.patch ++++++
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 ++++++ 0022-btrfs-progs-zero-out-structures-before-calling-ioctl.patch ++++++
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 ++++++ 0023-btrfs-progs-print-B-for-bytes.patch ++++++
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 ++++++ 0024-btrfs-progs-Print-more-info-about-device-sizes.patch ++++++
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 ++++++ 0025-btrfs-progs-compare-unallocated-space-against-the-co.patch ++++++
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 ++++++ 0026-btrfs-progs-add-section-of-overall-filesystem-usage.patch ++++++
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 ++++++ 0027-btrfs-progs-cleanup-filesystem-device-usage-code.patch ++++++
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 ++++++ 0028-btrfs-progs-extend-pretty-printers-with-unit-mode.patch ++++++
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
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
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 ++++++ 0029-btrfs-progs-replace-df_pretty_sizes-with-pretty_size.patch ++++++ 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 ++++++ 0030-btrfs-progs-clean-up-return-codes-and-paths.patch ++++++
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 ++++++ 0031-btrfs-progs-move-global-reserve-to-overall-summary.patch ++++++
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 ++++++ btrfs-progs-v3.14.tar.bz2 -> btrfs-progs-v3.14.1.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v3.14/btrfs.c new/btrfs-progs-v3.14.1/btrfs.c --- old/btrfs-progs-v3.14/btrfs.c 2014-04-07 01:33:55.000000000 +0200 +++ new/btrfs-progs-v3.14.1/btrfs.c 2014-04-18 19:46:31.000000000 +0200 @@ -212,31 +212,20 @@ return 0; } -static int handle_options(int *argc, char ***argv) +static void handle_options(int *argc, char ***argv) { - char **orig_argv = *argv; - - while (*argc > 0) { + if (*argc > 0) { const char *arg = (*argv)[0]; - if (arg[0] != '-') - break; - - if (!strcmp(arg, "--help")) { - break; - } else if (!strcmp(arg, "--version")) { - break; - } else { - fprintf(stderr, "Unknown option: %s\n", arg); - fprintf(stderr, "usage: %s\n", - btrfs_cmd_group.usagestr[0]); - exit(129); - } - - (*argv)++; - (*argc)--; + if (arg[0] != '-' || + !strcmp(arg, "--help") || + !strcmp(arg, "--version")) + return; + fprintf(stderr, "Unknown option: %s\n", arg); + fprintf(stderr, "usage: %s\n", + btrfs_cmd_group.usagestr[0]); + exit(129); } - - return (*argv) - orig_argv; + return; } static const struct cmd_group btrfs_cmd_group = { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v3.14/cmds-check.c new/btrfs-progs-v3.14.1/cmds-check.c --- old/btrfs-progs-v3.14/cmds-check.c 2014-04-07 01:33:55.000000000 +0200 +++ new/btrfs-progs-v3.14.1/cmds-check.c 2014-04-18 19:46:31.000000000 +0200 @@ -92,7 +92,6 @@ struct list_head list; struct cache_extent cache; struct btrfs_disk_key parent_key; - unsigned int found_rec; u64 start; u64 max_size; u64 nr; @@ -101,8 +100,9 @@ u64 generation; u64 parent_generation; u64 info_objectid; - u64 num_duplicates; + u32 num_duplicates; u8 info_level; + unsigned int found_rec:1; unsigned int content_checked:1; unsigned int owner_ref_checked:1; unsigned int is_root:1; @@ -1166,7 +1166,7 @@ extent_type = btrfs_file_extent_type(eb, fi); if (extent_type == BTRFS_FILE_EXTENT_INLINE) { - num_bytes = btrfs_file_extent_inline_len(eb, fi); + num_bytes = btrfs_file_extent_inline_len(eb, slot, fi); if (num_bytes == 0) rec->errors |= I_ERR_BAD_FILE_EXTENT; rec->found_size += num_bytes; @@ -2737,7 +2737,7 @@ rec->start = start; rec->max_size = max_size; rec->nr = max(nr, max_size); - rec->found_rec = extent_rec; + rec->found_rec = !!extent_rec; rec->content_checked = 0; rec->owner_ref_checked = 0; rec->num_duplicates = 0; @@ -2920,7 +2920,7 @@ cache = search_cache_extent(reada, 0); if (cache) { bits[0].start = cache->start; - bits[1].size = cache->size; + bits[0].size = cache->size; *reada_bits = 1; return 1; } @@ -3892,12 +3892,6 @@ remove_cache_extent(nodes, cache); free(cache); } - cache = lookup_cache_extent(seen, bytenr, size); - if (cache) { - remove_cache_extent(seen, cache); - free(cache); - } - cache = lookup_cache_extent(extent_cache, bytenr, size); if (cache) { struct extent_record *rec; @@ -5914,6 +5908,10 @@ free_device_cache_tree(&dev_cache); free_block_group_tree(&block_group_cache); free_device_extent_tree(&dev_extent_cache); + free_extent_cache_tree(&seen); + free_extent_cache_tree(&pending); + free_extent_cache_tree(&reada); + free_extent_cache_tree(&nodes); return ret; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v3.14/cmds-device.c new/btrfs-progs-v3.14.1/cmds-device.c --- old/btrfs-progs-v3.14/cmds-device.c 2014-04-07 01:33:55.000000000 +0200 +++ new/btrfs-progs-v3.14.1/cmds-device.c 2014-04-18 19:46:31.000000000 +0200 @@ -187,9 +187,8 @@ } static const char * const cmd_scan_dev_usage[] = { - "btrfs device scan [options] [<device> [<device>...]]", + "btrfs device scan [(-d|--all-devices)|<device> [<device>...]]", "Scan devices for a btrfs filesystem", - "-d|--all-devices scan all devices under /dev", NULL }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v3.14/cmds-property.c new/btrfs-progs-v3.14.1/cmds-property.c --- old/btrfs-progs-v3.14/cmds-property.c 2014-04-07 01:33:55.000000000 +0200 +++ new/btrfs-progs-v3.14.1/cmds-property.c 2014-04-18 19:46:31.000000000 +0200 @@ -392,7 +392,7 @@ char *name = NULL; int types = 0; - if (check_argc_min(argc, 2) || check_argc_max(argc, 4)) + if (check_argc_min(argc, 2) || check_argc_max(argc, 5)) usage(cmd_get_usage); parse_args(argc, argv, cmd_get_usage, &types, &object, &name, NULL); @@ -417,7 +417,7 @@ char *value; int types = 0; - if (check_argc_min(argc, 4) || check_argc_max(argc, 5)) + if (check_argc_min(argc, 4) || check_argc_max(argc, 6)) usage(cmd_set_usage); parse_args(argc, argv, cmd_set_usage, &types, &object, &name, &value); @@ -437,7 +437,7 @@ char *object = NULL; int types = 0; - if (check_argc_min(argc, 2) || check_argc_max(argc, 3)) + if (check_argc_min(argc, 2) || check_argc_max(argc, 4)) usage(cmd_list_usage); parse_args(argc, argv, cmd_list_usage, &types, &object, NULL, NULL); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v3.14/cmds-restore.c new/btrfs-progs-v3.14.1/cmds-restore.c --- old/btrfs-progs-v3.14/cmds-restore.c 2014-04-07 01:33:55.000000000 +0200 +++ new/btrfs-progs-v3.14.1/cmds-restore.c 2014-04-18 19:46:31.000000000 +0200 @@ -229,8 +229,7 @@ fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); ptr = btrfs_file_extent_inline_start(fi); - len = btrfs_file_extent_inline_item_len(leaf, - btrfs_item_nr(path->slots[0])); + len = btrfs_file_extent_inline_len(leaf, path->slots[0], fi); read_extent_buffer(leaf, buf, ptr, len); compress = btrfs_file_extent_compression(leaf, fi); @@ -297,7 +296,7 @@ ram_size = btrfs_file_extent_ram_bytes(leaf, fi); offset = btrfs_file_extent_offset(leaf, fi); num_bytes = btrfs_file_extent_num_bytes(leaf, fi); - size_left = num_bytes; + size_left = disk_size; if (compress == BTRFS_COMPRESS_NONE) bytenr += offset; @@ -376,7 +375,7 @@ goto out; } - ret = decompress(inbuf, outbuf, num_bytes, &ram_size, compress); + ret = decompress(inbuf, outbuf, disk_size, &ram_size, compress); if (ret) { num_copies = btrfs_num_copies(&root->fs_info->mapping_tree, bytenr, length); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v3.14/ctree.h new/btrfs-progs-v3.14.1/ctree.h --- old/btrfs-progs-v3.14/ctree.h 2014-04-07 01:33:55.000000000 +0200 +++ new/btrfs-progs-v3.14.1/ctree.h 2014-04-18 19:46:31.000000000 +0200 @@ -1184,9 +1184,9 @@ sizeof(((type *)0)->member))) #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ -static inline u##bits btrfs_##name(struct extent_buffer *eb) \ +static inline u##bits btrfs_##name(const struct extent_buffer *eb) \ { \ - struct btrfs_header *h = (struct btrfs_header *)eb->data; \ + const struct btrfs_header *h = (struct btrfs_header *)eb->data; \ return le##bits##_to_cpu(h->member); \ } \ static inline void btrfs_set_##name(struct extent_buffer *eb, \ @@ -1197,11 +1197,11 @@ } #define BTRFS_SETGET_FUNCS(name, type, member, bits) \ -static inline u##bits btrfs_##name(struct extent_buffer *eb, \ - type *s) \ +static inline u##bits btrfs_##name(const struct extent_buffer *eb, \ + const type *s) \ { \ unsigned long offset = (unsigned long)s; \ - type *p = (type *) (eb->data + offset); \ + const type *p = (type *) (eb->data + offset); \ return get_unaligned_le##bits(&p->member); \ } \ static inline void btrfs_set_##name(struct extent_buffer *eb, \ @@ -1213,7 +1213,7 @@ } #define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \ -static inline u##bits btrfs_##name(type *s) \ +static inline u##bits btrfs_##name(const type *s) \ { \ return le##bits##_to_cpu(s->member); \ } \ @@ -2094,15 +2094,6 @@ BTRFS_SETGET_STACK_FUNCS(stack_qgroup_limit_rsv_exclusive, struct btrfs_qgroup_limit_item, rsv_exclusive, 64); -/* this returns the number of file bytes represented by the inline item. - * If an item is compressed, this is the uncompressed size - */ -static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, - struct btrfs_file_extent_item *e) -{ - return btrfs_file_extent_ram_bytes(eb, e); -} - /* * this returns the number of bytes used by the item on disk, minus the * size of any extent headers. If a file is compressed on disk, this is @@ -2116,6 +2107,28 @@ return btrfs_item_size(eb, e) - offset; } +/* this returns the number of file bytes represented by the inline item. + * If an item is compressed, this is the uncompressed size + */ +static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, + int slot, + struct btrfs_file_extent_item *fi) +{ + /* + * return the space used on disk if this item isn't + * compressed or encoded + */ + if (btrfs_file_extent_compression(eb, fi) == 0 && + btrfs_file_extent_encryption(eb, fi) == 0 && + btrfs_file_extent_other_encoding(eb, fi) == 0) { + return btrfs_file_extent_inline_item_len(eb, + btrfs_item_nr(slot)); + } + + /* otherwise use the ram bytes field */ + return btrfs_file_extent_ram_bytes(eb, fi); +} + static inline u32 btrfs_level_size(struct btrfs_root *root, int level) { if (level == 0) return root->leafsize; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v3.14/ioctl.h new/btrfs-progs-v3.14.1/ioctl.h --- old/btrfs-progs-v3.14/ioctl.h 2014-04-07 01:33:55.000000000 +0200 +++ new/btrfs-progs-v3.14.1/ioctl.h 2014-04-18 19:46:31.000000000 +0200 @@ -480,9 +480,9 @@ case BTRFS_ERROR_DEV_RAID10_MIN_NOT_MET: return "unable to go below four devices on raid10"; case BTRFS_ERROR_DEV_RAID5_MIN_NOT_MET: - return "unable to go below three devices on raid5"; + return "unable to go below two devices on raid5"; case BTRFS_ERROR_DEV_RAID6_MIN_NOT_MET: - return "unable to go below four devices on raid6"; + return "unable to go below three devices on raid6"; case BTRFS_ERROR_DEV_TGT_REPLACE: return "unable to remove the dev_replace target dev"; case BTRFS_ERROR_DEV_MISSING_NOT_FOUND: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v3.14/print-tree.c new/btrfs-progs-v3.14.1/print-tree.c --- old/btrfs-progs-v3.14/print-tree.c 2014-04-07 01:33:55.000000000 +0200 +++ new/btrfs-progs-v3.14.1/print-tree.c 2014-04-18 19:46:31.000000000 +0200 @@ -209,6 +209,7 @@ static void print_file_extent_item(struct extent_buffer *eb, struct btrfs_item *item, + int slot, struct btrfs_file_extent_item *fi) { int extent_type = btrfs_file_extent_type(eb, fi); @@ -217,7 +218,7 @@ printf("\t\tinline extent data size %u " "ram %u compress %d\n", btrfs_file_extent_inline_item_len(eb, item), - btrfs_file_extent_inline_len(eb, fi), + btrfs_file_extent_inline_len(eb, slot, fi), btrfs_file_extent_compression(eb, fi)); return; } @@ -829,7 +830,7 @@ case BTRFS_EXTENT_DATA_KEY: fi = btrfs_item_ptr(l, i, struct btrfs_file_extent_item); - print_file_extent_item(l, item, fi); + print_file_extent_item(l, item, i, fi); break; case BTRFS_BLOCK_GROUP_ITEM_KEY: bi = btrfs_item_ptr(l, i, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v3.14/version.sh new/btrfs-progs-v3.14.1/version.sh --- old/btrfs-progs-v3.14/version.sh 2014-04-07 01:33:55.000000000 +0200 +++ new/btrfs-progs-v3.14.1/version.sh 2014-04-18 19:46:31.000000000 +0200 @@ -6,7 +6,7 @@ # Copyright 2008, Oracle # Released under the GNU GPLv2 -v="v3.14" +v="v3.14.1" which git &> /dev/null if [ $? == 0 -a -d .git ]; then ++++++ local-version-override.patch ++++++ --- /var/tmp/diff_new_pack.g4pZwt/_old 2014-05-06 13:39:29.000000000 +0200 +++ /var/tmp/diff_new_pack.g4pZwt/_new 2014-05-06 13:39:29.000000000 +0200 @@ -6,8 +6,8 @@ # Copyright 2008, Oracle # Released under the GNU GPLv2 --v="v3.14" -+v="v3.14+20140408" +-v="v3.14.1" ++v="v3.14.1+20140502" which git &> /dev/null if [ $? == 0 -a -d .git ]; then -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org
participants (1)
-
root@hilbert.suse.de