From a3200e46e8ce5a967d9de422456e952574fea0f9527f017ede4f80cbe6c7ff3e Mon Sep 17 00:00:00 2001 From: Stephan Kulow Date: Mon, 8 Sep 2014 19:28:13 +0000 Subject: [PATCH] Accepting request 247710 from filesystems 1 OBS-URL: https://build.opensuse.org/request/show/247710 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/btrfsprogs?expand=0&rev=45 --- ...doc-fix-symlink-target-for-btrfsck.8.patch | 29 - ...ck-clear-out-log-tree-in-repair-mode.patch | 19 +- ...ance-the-command-btrfs-filesystem-df.patch | 86 +- ...helpers-functions-to-handle-the-prin.patch | 31 +- ...-command-btrfs-filesystem-disk-usage.patch | 58 +- ...xtend-pretty-printers-with-unit-mode.patch | 74 +- ...onvert-set-label-or-copy-from-origin.patch | 21 +- ...-progs-print-qgroup-excl-as-unsigned.patch | 65 - 0201-btrfs-progs-import-ulist.patch | 374 ----- ...fs-progs-add-quota-group-verify-code.patch | 1385 ----------------- ...gs-show-extent-state-for-a-subvolume.patch | 235 --- ...s-ignore-orphaned-qgroups-by-default.patch | 68 - ...canonicalize-pathnames-for-device-commands | 292 ---- btrfs-progs-v3.14.2.tar.bz2 | 3 - btrfs-progs-v3.16.tar.gz | 3 + btrfsprogs.changes | 55 + btrfsprogs.spec | 35 +- library-version-defines.patch | 90 ++ local-version-override.patch | 4 +- 19 files changed, 295 insertions(+), 2632 deletions(-) delete mode 100644 0001-btrfs-progs-doc-fix-symlink-target-for-btrfsck.8.patch delete mode 100644 0200-btrfs-progs-print-qgroup-excl-as-unsigned.patch delete mode 100644 0201-btrfs-progs-import-ulist.patch delete mode 100644 0202-btrfs-progs-add-quota-group-verify-code.patch delete mode 100644 0203-btrfs-progs-show-extent-state-for-a-subvolume.patch delete mode 100644 0204-btrfs-progs-ignore-orphaned-qgroups-by-default.patch delete mode 100644 btrfs-progs-canonicalize-pathnames-for-device-commands delete mode 100644 btrfs-progs-v3.14.2.tar.bz2 create mode 100644 btrfs-progs-v3.16.tar.gz create mode 100644 library-version-defines.patch diff --git a/0001-btrfs-progs-doc-fix-symlink-target-for-btrfsck.8.patch b/0001-btrfs-progs-doc-fix-symlink-target-for-btrfsck.8.patch deleted file mode 100644 index 100feb8..0000000 --- a/0001-btrfs-progs-doc-fix-symlink-target-for-btrfsck.8.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 1982864ee7028c36be8636d1fb2e4e679ee66bed Mon Sep 17 00:00:00 2001 -From: David Sterba -Date: Mon, 5 May 2014 16:54:00 +0200 -Subject: [PATCH] btrfs-progs: doc: fix symlink target for btrfsck.8 - -The manpage of btrfsck.8 is supposed to link to btrfs-check.8 . - -Reported-by: WorMzy Tykashi -Signed-off-by: David Sterba ---- - Documentation/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Documentation/Makefile b/Documentation/Makefile -index 45299bb29f9b..2df6af001cbc 100644 ---- a/Documentation/Makefile -+++ b/Documentation/Makefile -@@ -74,7 +74,7 @@ install: install-man - install-man: man - $(INSTALL) -d -m 755 $(DESTDIR)$(man8dir) - $(INSTALL) -m 644 $(GZ_MAN8) $(DESTDIR)$(man8dir) -- $(LNS) btrfs-check.8.gz $(DESTDIR)$(man8dir) -+ $(LNS) btrfs-check.8.gz $(DESTDIR)$(man8dir)/btrfsck.8.gz - - clean: - $(RM) *.xml *.xml+ *.8 *.8.gz --- -1.9.0 - diff --git a/0006-Btrfs-progs-fsck-clear-out-log-tree-in-repair-mode.patch b/0006-Btrfs-progs-fsck-clear-out-log-tree-in-repair-mode.patch index bfc20cb..ee02cd8 100644 --- a/0006-Btrfs-progs-fsck-clear-out-log-tree-in-repair-mode.patch +++ b/0006-Btrfs-progs-fsck-clear-out-log-tree-in-repair-mode.patch @@ -15,11 +15,11 @@ Signed-off-by: David Sterba 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: +Index: btrfs-progs-v3.16/cmds-check.c +=================================================================== +--- btrfs-progs-v3.16.orig/cmds-check.c ++++ btrfs-progs-v3.16/cmds-check.c +@@ -6538,6 +6538,22 @@ out: return ret; } @@ -42,7 +42,7 @@ index 1fe97b3a38c0..7457618fb702 100644 static struct option long_options[] = { { "super", 1, NULL, 's' }, { "repair", 0, NULL, 0 }, -@@ -6720,6 +6736,23 @@ int cmd_check(int argc, char **argv) +@@ -6657,6 +6673,23 @@ int cmd_check(int argc, char **argv) } root = info->fs_root; @@ -64,8 +64,5 @@ index 1fe97b3a38c0..7457618fb702 100644 + } + uuid_unparse(info->super_copy->fsid, uuidbuf); - printf("Checking filesystem on %s\nUUID: %s\n", argv[optind], uuidbuf); - --- -1.9.0 - + if (qgroup_report) { + printf("Print quota groups for %s\nUUID: %s\n", argv[optind], diff --git a/0011-btrfs-progs-Enhance-the-command-btrfs-filesystem-df.patch b/0011-btrfs-progs-Enhance-the-command-btrfs-filesystem-df.patch index e324301..ab4eedf 100644 --- a/0011-btrfs-progs-Enhance-the-command-btrfs-filesystem-df.patch +++ b/0011-btrfs-progs-Enhance-the-command-btrfs-filesystem-df.patch @@ -21,11 +21,11 @@ Signed-off-by: David Sterba create mode 100644 cmds-fi-disk_usage.c create mode 100644 cmds-fi-disk_usage.h -diff --git a/Makefile b/Makefile -index 76565e8b2307..50fb9b0ff2e3 100644 ---- a/Makefile -+++ b/Makefile -@@ -15,7 +15,7 @@ cmds_objects = cmds-subvolume.o cmds-filesystem.o cmds-device.o cmds-scrub.o \ +Index: btrfs-progs-v3.16/Makefile +=================================================================== +--- btrfs-progs-v3.16.orig/Makefile ++++ btrfs-progs-v3.16/Makefile +@@ -15,7 +15,7 @@ cmds_objects = cmds-subvolume.o cmds-fil cmds-inspect.o cmds-balance.o cmds-send.o cmds-receive.o \ cmds-quota.o cmds-qgroup.o cmds-replace.o cmds-check.o \ cmds-restore.o cmds-rescue.o chunk-recover.o super-recover.o \ @@ -34,11 +34,10 @@ index 76565e8b2307..50fb9b0ff2e3 100644 libbtrfs_objects = send-stream.o send-utils.o rbtree.o btrfs-list.o crc32c.o \ uuid-tree.o utils-lib.o libbtrfs_headers = send-stream.h send-utils.h send.h rbtree.h btrfs-list.h \ -diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c -new file mode 100644 -index 000000000000..4012c781f20d +Index: btrfs-progs-v3.16/cmds-fi-disk_usage.c +=================================================================== --- /dev/null -+++ b/cmds-fi-disk_usage.c ++++ btrfs-progs-v3.16/cmds-fi-disk_usage.c @@ -0,0 +1,516 @@ +/* + * This program is free software; you can redistribute it and/or @@ -556,11 +555,10 @@ index 000000000000..4012c781f20d + return 0; +} + -diff --git a/cmds-fi-disk_usage.h b/cmds-fi-disk_usage.h -new file mode 100644 -index 000000000000..9f68bb342d52 +Index: btrfs-progs-v3.16/cmds-fi-disk_usage.h +=================================================================== --- /dev/null -+++ b/cmds-fi-disk_usage.h ++++ btrfs-progs-v3.16/cmds-fi-disk_usage.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2007 Oracle. All rights reserved. @@ -587,10 +585,10 @@ index 000000000000..9f68bb342d52 +int cmd_filesystem_df(int argc, char **argv); + +#endif -diff --git a/cmds-filesystem.c b/cmds-filesystem.c -index 306f715475ac..0edfb50daca2 100644 ---- a/cmds-filesystem.c -+++ b/cmds-filesystem.c +Index: btrfs-progs-v3.16/cmds-filesystem.c +=================================================================== +--- btrfs-progs-v3.16.orig/cmds-filesystem.c ++++ btrfs-progs-v3.16/cmds-filesystem.c @@ -36,6 +36,7 @@ #include "volumes.h" #include "version.h" @@ -599,7 +597,7 @@ index 306f715475ac..0edfb50daca2 100644 #include "list_sort.h" #include "disk-io.h" -@@ -112,50 +113,6 @@ static const char * const filesystem_cmd_group_usage[] = { +@@ -112,50 +113,6 @@ static const char * const filesystem_cmd NULL }; @@ -650,7 +648,7 @@ index 306f715475ac..0edfb50daca2 100644 static int get_df(int fd, struct btrfs_ioctl_space_args **sargs_ret) { u64 count = 0; -@@ -204,51 +161,6 @@ static int get_df(int fd, struct btrfs_ioctl_space_args **sargs_ret) +@@ -204,51 +161,6 @@ static int get_df(int fd, struct btrfs_i return 0; } @@ -688,7 +686,7 @@ index 306f715475ac..0edfb50daca2 100644 - } - ret = get_df(fd, &sargs); - -- if (!ret && sargs) { +- if (ret == 0) { - print_df(sargs); - free(sargs); - } else { @@ -702,7 +700,7 @@ index 306f715475ac..0edfb50daca2 100644 static int match_search_item_kernel(__u8 *fsid, char *mnt, char *label, char *search) { -@@ -999,7 +911,7 @@ static int cmd_label(int argc, char **argv) +@@ -999,7 +911,7 @@ static int cmd_label(int argc, char **ar const struct cmd_group filesystem_cmd_group = { filesystem_cmd_group_usage, NULL, { @@ -711,11 +709,11 @@ index 306f715475ac..0edfb50daca2 100644 { "show", cmd_show, cmd_show_usage, NULL, 0 }, { "sync", cmd_sync, cmd_sync_usage, NULL, 0 }, { "defragment", cmd_defrag, cmd_defrag_usage, NULL, 0 }, -diff --git a/ctree.h b/ctree.h -index a4d2cd114614..8ac17619b9dc 100644 ---- a/ctree.h -+++ b/ctree.h -@@ -843,9 +843,10 @@ struct btrfs_csum_item { +Index: btrfs-progs-v3.16/ctree.h +=================================================================== +--- btrfs-progs-v3.16.orig/ctree.h ++++ btrfs-progs-v3.16/ctree.h +@@ -845,9 +845,10 @@ struct btrfs_csum_item { #define BTRFS_BLOCK_GROUP_RAID1 (1ULL << 4) #define BTRFS_BLOCK_GROUP_DUP (1ULL << 5) #define BTRFS_BLOCK_GROUP_RAID10 (1ULL << 6) @@ -728,10 +726,10 @@ index a4d2cd114614..8ac17619b9dc 100644 #define BTRFS_BLOCK_GROUP_TYPE_MASK (BTRFS_BLOCK_GROUP_DATA | \ BTRFS_BLOCK_GROUP_SYSTEM | \ -diff --git a/utils.c b/utils.c -index e130849c7bb5..7731b071f353 100644 ---- a/utils.c -+++ b/utils.c +Index: btrfs-progs-v3.16/utils.c +=================================================================== +--- btrfs-progs-v3.16.orig/utils.c ++++ btrfs-progs-v3.16/utils.c @@ -38,6 +38,8 @@ #include #include @@ -741,9 +739,9 @@ index e130849c7bb5..7731b071f353 100644 #include "kerncompat.h" #include "radix-tree.h" #include "ctree.h" -@@ -2206,3 +2208,13 @@ int find_mount_root(const char *path, char **mount_root) - free(longest_match); - return ret; +@@ -2436,3 +2438,13 @@ int test_isdir(const char *path) + + return S_ISDIR(st.st_mode); } + +u64 disk_size(char *path) @@ -755,17 +753,15 @@ index e130849c7bb5..7731b071f353 100644 + else + return sfs.f_bsize * sfs.f_blocks; +} -diff --git a/utils.h b/utils.h -index db8d63c396d5..581faa9f6972 100644 ---- a/utils.h -+++ b/utils.h -@@ -101,5 +101,6 @@ int get_btrfs_mount(const char *dev, char *mp, size_t mp_size); - int find_mount_root(const char *path, char **mount_root); - int get_device_info(int fd, u64 devid, - struct btrfs_ioctl_dev_info_args *di_args); +Index: btrfs-progs-v3.16/utils.h +=================================================================== +--- btrfs-progs-v3.16.orig/utils.h ++++ btrfs-progs-v3.16/utils.h +@@ -118,6 +118,7 @@ int test_uuid_unique(char *fs_uuid); + int test_minimum_size(const char *file, u32 leafsize); + int test_issubvolname(const char *name); + int test_isdir(const char *path); +u64 disk_size(char *path); - #endif --- -1.9.0 - + /* + * Btrfs minimum size calculation is complicated, it should include at least: diff --git a/0012-btrfs-progs-Add-helpers-functions-to-handle-the-prin.patch b/0012-btrfs-progs-Add-helpers-functions-to-handle-the-prin.patch index a617bf4..09129d1 100644 --- a/0012-btrfs-progs-Add-helpers-functions-to-handle-the-prin.patch +++ b/0012-btrfs-progs-Add-helpers-functions-to-handle-the-prin.patch @@ -39,24 +39,23 @@ Signed-off-by: David Sterba 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 \ +Index: btrfs-progs-v3.16/Makefile +=================================================================== +--- btrfs-progs-v3.16.orig/Makefile ++++ btrfs-progs-v3.16/Makefile +@@ -10,7 +10,7 @@ objects = ctree.o disk-io.o radix-tree.o root-tree.o dir-item.o file-item.o inode-item.o inode-map.o \ extent-cache.o extent_io.o volumes.o utils.o repair.o \ qgroup.o raid6.o free-space-cache.o list_sort.o props.o \ -- utils-lib.o -+ utils-lib.o string_table.o +- ulist.o qgroup-verify.o ++ ulist.o qgroup-verify.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 +Index: btrfs-progs-v3.16/string_table.c +=================================================================== --- /dev/null -+++ b/string_table.c ++++ btrfs-progs-v3.16/string_table.c @@ -0,0 +1,156 @@ +/* + * This program is free software; you can redistribute it and/or @@ -214,11 +213,10 @@ index 000000000000..016356c50392 + free(tab); + +} -diff --git a/string_table.h b/string_table.h -new file mode 100644 -index 000000000000..83c4425d5f76 +Index: btrfs-progs-v3.16/string_table.h +=================================================================== --- /dev/null -+++ b/string_table.h ++++ btrfs-progs-v3.16/string_table.h @@ -0,0 +1,36 @@ +/* + * This program is free software; you can redistribute it and/or @@ -256,6 +254,3 @@ index 000000000000..83c4425d5f76 +void table_free(struct string_table *); + +#endif --- -1.9.0 - diff --git a/0013-btrfs-progs-Add-command-btrfs-filesystem-disk-usage.patch b/0013-btrfs-progs-Add-command-btrfs-filesystem-disk-usage.patch index 30bbdd2..4ab8fce 100644 --- a/0013-btrfs-progs-Add-command-btrfs-filesystem-disk-usage.patch +++ b/0013-btrfs-progs-Add-command-btrfs-filesystem-disk-usage.patch @@ -13,10 +13,10 @@ Signed-off-by: David Sterba 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 +Index: btrfs-progs-v3.16/cmds-fi-disk_usage.c +=================================================================== +--- btrfs-progs-v3.16.orig/cmds-fi-disk_usage.c ++++ btrfs-progs-v3.16/cmds-fi-disk_usage.c @@ -20,10 +20,12 @@ #include #include @@ -44,7 +44,7 @@ index 4012c781f20d..16b3ab250956 100644 /* * Pretty print the size * PAY ATTENTION: it return a statically buffer -@@ -514,3 +523,422 @@ int cmd_filesystem_df(int argc, char **argv) +@@ -514,3 +523,422 @@ int cmd_filesystem_df(int argc, char **a return 0; } @@ -467,10 +467,10 @@ index 4012c781f20d..16b3ab250956 100644 + + 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 +Index: btrfs-progs-v3.16/cmds-fi-disk_usage.h +=================================================================== +--- btrfs-progs-v3.16.orig/cmds-fi-disk_usage.h ++++ btrfs-progs-v3.16/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); @@ -479,11 +479,11 @@ index 9f68bb342d52..c7459b1521e4 100644 +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 = { +Index: btrfs-progs-v3.16/cmds-filesystem.c +=================================================================== +--- btrfs-progs-v3.16.orig/cmds-filesystem.c ++++ btrfs-progs-v3.16/cmds-filesystem.c +@@ -918,6 +918,9 @@ const struct cmd_group filesystem_cmd_gr { "balance", cmd_balance, NULL, &balance_cmd_group, 1 }, { "resize", cmd_resize, cmd_resize_usage, NULL, 0 }, { "label", cmd_label, cmd_label_usage, NULL, 0 }, @@ -493,11 +493,11 @@ index 0edfb50daca2..214a0cda518c 100644 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) +Index: btrfs-progs-v3.16/utils.c +=================================================================== +--- btrfs-progs-v3.16.orig/utils.c ++++ btrfs-progs-v3.16/utils.c +@@ -2448,3 +2448,63 @@ u64 disk_size(char *path) else return sfs.f_bsize * sfs.f_blocks; } @@ -561,13 +561,13 @@ index 7731b071f353..f2ab416c28b2 100644 + 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); +Index: btrfs-progs-v3.16/utils.h +=================================================================== +--- btrfs-progs-v3.16.orig/utils.h ++++ btrfs-progs-v3.16/utils.h +@@ -119,6 +119,11 @@ int test_minimum_size(const char *file, + int test_issubvolname(const char *name); + int test_isdir(const char *path); u64 disk_size(char *path); +int get_device_info(int fd, u64 devid, + struct btrfs_ioctl_dev_info_args *di_args); @@ -575,7 +575,5 @@ index 581faa9f6972..2d08e0b2a3a4 100644 +const char* group_type_str(u64 flags); +const char* group_profile_str(u64 flags); - #endif --- -1.9.0 - + /* + * Btrfs minimum size calculation is complicated, it should include at least: diff --git a/0028-btrfs-progs-extend-pretty-printers-with-unit-mode.patch b/0028-btrfs-progs-extend-pretty-printers-with-unit-mode.patch index dd1bf53..cac7996 100644 --- a/0028-btrfs-progs-extend-pretty-printers-with-unit-mode.patch +++ b/0028-btrfs-progs-extend-pretty-printers-with-unit-mode.patch @@ -14,10 +14,10 @@ Signed-off-by: David Sterba 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 +Index: btrfs-progs-v3.16/cmds-fi-disk_usage.c +=================================================================== +--- btrfs-progs-v3.16.orig/cmds-fi-disk_usage.c ++++ btrfs-progs-v3.16/cmds-fi-disk_usage.c @@ -33,18 +33,13 @@ /* @@ -39,11 +39,11 @@ index 9d1c4085b4ea..1e412c0b0e69 100644 } /* -diff --git a/utils.c b/utils.c -index 159abf8bd0e4..69112be51cb2 100644 ---- a/utils.c -+++ b/utils.c -@@ -1252,35 +1252,62 @@ out: +Index: btrfs-progs-v3.16/utils.c +=================================================================== +--- btrfs-progs-v3.16.orig/utils.c ++++ btrfs-progs-v3.16/utils.c +@@ -1378,35 +1378,62 @@ out: return ret; } @@ -62,10 +62,23 @@ index 159abf8bd0e4..69112be51cb2 100644 + int base = 0; + const char const **suffix = NULL; + u64 last_size; ++ ++ if (str_size == 0) ++ return 0; - if (str_bytes == 0) -+ if (str_size == 0) ++ if (unit_mode == UNITS_RAW) { ++ snprintf(str, str_size, "%llu", size); return 0; ++ } ++ ++ if (unit_mode == UNITS_BINARY) { ++ base = 1024; ++ suffix = unit_suffix_binary; ++ } else if (unit_mode == UNITS_DECIMAL) { ++ base = 1000; ++ suffix = unit_suffix_decimal; ++ } - if( size < 1024 ){ - fraction = size; @@ -78,33 +91,21 @@ index 159abf8bd0e4..69112be51cb2 100644 - 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; -+ } + } +- return snprintf(str, str_bytes, "%.2f%s", fraction, +- size_strs[num_divs]); + + num_divs = 0; + last_size = size; @@ -128,13 +129,13 @@ index 159abf8bd0e4..69112be51cb2 100644 } /* -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 +Index: btrfs-progs-v3.16/utils.h +=================================================================== +--- btrfs-progs-v3.16.orig/utils.h ++++ btrfs-progs-v3.16/utils.h +@@ -49,6 +49,14 @@ int check_argc_max(int nargs, int expect + void fixup_argv0(char **argv, const char *token); + void set_argv0(char **argv); +/* + * Output mode of byte units @@ -145,9 +146,9 @@ index 2d08e0b2a3a4..3aea8b47d9e7 100644 +#define UNITS_HUMAN UNITS_BINARY + int make_btrfs(int fd, const char *device, const char *label, - u64 blocks[6], u64 num_bytes, u32 nodesize, + char *fs_uuid, 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, +@@ -71,12 +79,13 @@ int check_mounted_where(int fd, const ch int btrfs_device_already_in_root(struct btrfs_root *root, int fd, int super_offset); @@ -167,6 +168,3 @@ index 2d08e0b2a3a4..3aea8b47d9e7 100644 }) int get_mountpt(char *dev, char *mntpt, size_t size); --- -1.9.0 - diff --git a/0164-btrfs-progs-convert-set-label-or-copy-from-origin.patch b/0164-btrfs-progs-convert-set-label-or-copy-from-origin.patch index bf68f66..d5cffa2 100644 --- a/0164-btrfs-progs-convert-set-label-or-copy-from-origin.patch +++ b/0164-btrfs-progs-convert-set-label-or-copy-from-origin.patch @@ -8,11 +8,11 @@ Signed-off-by: David Sterba btrfs-convert.c | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) -Index: btrfs-progs-v0.20-rc1-598-g8116550e1662/btrfs-convert.c +Index: btrfs-progs-v3.16/btrfs-convert.c =================================================================== ---- btrfs-progs-v0.20-rc1-598-g8116550e1662.orig/btrfs-convert.c -+++ btrfs-progs-v0.20-rc1-598-g8116550e1662/btrfs-convert.c -@@ -2199,8 +2199,8 @@ err: +--- btrfs-progs-v3.16.orig/btrfs-convert.c ++++ btrfs-progs-v3.16/btrfs-convert.c +@@ -2196,8 +2196,8 @@ err: return ret; } @@ -23,7 +23,7 @@ Index: btrfs-progs-v0.20-rc1-598-g8116550e1662/btrfs-convert.c { int i, ret; int fd = -1; -@@ -2294,6 +2294,17 @@ static int do_convert(const char *devnam +@@ -2291,6 +2291,17 @@ static int do_convert(const char *devnam fprintf(stderr, "error during create_ext2_image %d\n", ret); goto fail; } @@ -41,7 +41,7 @@ Index: btrfs-progs-v0.20-rc1-598-g8116550e1662/btrfs-convert.c printf("cleaning up system chunk.\n"); ret = cleanup_sys_chunk(root, ext2_root); if (ret) { -@@ -2688,11 +2699,13 @@ fail: +@@ -2685,11 +2696,13 @@ fail: static void print_usage(void) { @@ -60,11 +60,12 @@ Index: btrfs-progs-v0.20-rc1-598-g8116550e1662/btrfs-convert.c } int main(int argc, char *argv[]) -@@ -2702,9 +2715,12 @@ int main(int argc, char *argv[]) +@@ -2699,10 +2712,13 @@ int main(int argc, char *argv[]) int noxattr = 0; int datacsum = 1; int rollback = 0; + int copylabel = 0; + int usage_error = 0; char *file; + char *fslabel = NULL; + @@ -74,7 +75,7 @@ Index: btrfs-progs-v0.20-rc1-598-g8116550e1662/btrfs-convert.c if (c < 0) break; switch(c) { -@@ -2720,6 +2736,19 @@ int main(int argc, char *argv[]) +@@ -2718,6 +2734,19 @@ int main(int argc, char *argv[]) case 'r': rollback = 1; break; @@ -94,9 +95,9 @@ Index: btrfs-progs-v0.20-rc1-598-g8116550e1662/btrfs-convert.c default: print_usage(); return 1; -@@ -2740,7 +2769,7 @@ int main(int argc, char *argv[]) +@@ -2755,7 +2784,7 @@ int main(int argc, char *argv[]) if (rollback) { - ret = do_rollback(file, 0); + ret = do_rollback(file); } else { - ret = do_convert(file, datacsum, packing, noxattr); + ret = do_convert(file, datacsum, packing, noxattr, copylabel, fslabel); diff --git a/0200-btrfs-progs-print-qgroup-excl-as-unsigned.patch b/0200-btrfs-progs-print-qgroup-excl-as-unsigned.patch deleted file mode 100644 index d59768d..0000000 --- a/0200-btrfs-progs-print-qgroup-excl-as-unsigned.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 8b40b00f23806115c9f03344227b6590cb187a96 Mon Sep 17 00:00:00 2001 -From: Mark Fasheh -Date: Thu, 1 May 2014 22:35:15 -0700 -Subject: [PATCH 1/3] btrfs-progs: print qgroup excl as unsigned -References: bnc#886493 bnc#865621 -Upstream: submitted - -It's unsigned in the structure definition. - -Signed-off-by: Mark Fasheh ---- - print-tree.c | 12 ++++++------ - qgroup.c | 4 ++-- - 2 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/print-tree.c b/print-tree.c -index 7263b09..adef94a 100644 ---- a/print-tree.c -+++ b/print-tree.c -@@ -884,18 +884,18 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) - qg_info = btrfs_item_ptr(l, i, - struct btrfs_qgroup_info_item); - printf("\t\tgeneration %llu\n" -- "\t\treferenced %lld referenced compressed %lld\n" -- "\t\texclusive %lld exclusive compressed %lld\n", -+ "\t\treferenced %llu referenced compressed %llu\n" -+ "\t\texclusive %llu exclusive compressed %llu\n", - (unsigned long long) - btrfs_qgroup_info_generation(l, qg_info), -- (long long) -+ (unsigned long long) - btrfs_qgroup_info_referenced(l, qg_info), -- (long long) -+ (unsigned long long) - btrfs_qgroup_info_referenced_compressed(l, - qg_info), -- (long long) -+ (unsigned long long) - btrfs_qgroup_info_exclusive(l, qg_info), -- (long long) -+ (unsigned long long) - btrfs_qgroup_info_exclusive_compressed(l, - qg_info)); - break; -diff --git a/qgroup.c b/qgroup.c -index 94d1feb..368b262 100644 ---- a/qgroup.c -+++ b/qgroup.c -@@ -203,11 +203,11 @@ static void print_qgroup_column(struct btrfs_qgroup *qgroup, - print_qgroup_column_add_blank(BTRFS_QGROUP_QGROUPID, len); - break; - case BTRFS_QGROUP_RFER: -- len = printf("%lld", qgroup->rfer); -+ len = printf("%llu", qgroup->rfer); - print_qgroup_column_add_blank(BTRFS_QGROUP_RFER, len); - break; - case BTRFS_QGROUP_EXCL: -- len = printf("%lld", qgroup->excl); -+ len = printf("%llu", qgroup->excl); - print_qgroup_column_add_blank(BTRFS_QGROUP_EXCL, len); - break; - case BTRFS_QGROUP_PARENT: --- -1.8.4 - diff --git a/0201-btrfs-progs-import-ulist.patch b/0201-btrfs-progs-import-ulist.patch deleted file mode 100644 index 29f96f0..0000000 --- a/0201-btrfs-progs-import-ulist.patch +++ /dev/null @@ -1,374 +0,0 @@ -From e1857c491c61040cd845b5e08f1d996d3e3557a8 Mon Sep 17 00:00:00 2001 -From: Mark Fasheh -Date: Thu, 1 May 2014 14:34:30 -0700 -Subject: [PATCH 2/3] btrfs-progs: import ulist -References: bnc#886493 bnc#865621 -Upstream: submitted - -qgroup-verify.c wants this for walking root refs. - -Signed-off-by: Mark Fasheh ---- - Makefile | 3 +- - kerncompat.h | 2 +- - ulist.c | 253 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - ulist.h | 66 ++++++++++++++++ - 4 files changed, 322 insertions(+), 2 deletions(-) - create mode 100644 ulist.c - create mode 100644 ulist.h - -Index: btrfs-progs-v3.14.1/Makefile -=================================================================== ---- btrfs-progs-v3.14.1.orig/Makefile -+++ btrfs-progs-v3.14.1/Makefile -@@ -10,7 +10,7 @@ objects = ctree.o disk-io.o radix-tree.o - root-tree.o dir-item.o file-item.o inode-item.o inode-map.o \ - extent-cache.o extent_io.o volumes.o utils.o repair.o \ - qgroup.o raid6.o free-space-cache.o list_sort.o props.o \ -- utils-lib.o string_table.o -+ utils-lib.o string_table.o ulist.o - cmds_objects = cmds-subvolume.o cmds-filesystem.o cmds-device.o cmds-scrub.o \ - cmds-inspect.o cmds-balance.o cmds-send.o cmds-receive.o \ - cmds-quota.o cmds-qgroup.o cmds-replace.o cmds-check.o \ -Index: btrfs-progs-v3.14.1/kerncompat.h -=================================================================== ---- btrfs-progs-v3.14.1.orig/kerncompat.h -+++ btrfs-progs-v3.14.1/kerncompat.h -@@ -235,7 +235,7 @@ static inline long IS_ERR(const void *pt - - #define BUG_ON(c) assert(!(c)) - #define WARN_ON(c) assert(!(c)) -- -+#define ASSERT(c) assert(c) - - #define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ -Index: btrfs-progs-v3.14.1/ulist.c -=================================================================== ---- /dev/null -+++ btrfs-progs-v3.14.1/ulist.c -@@ -0,0 +1,253 @@ -+/* -+ * Copyright (C) 2011 STRATO AG -+ * written by Arne Jansen -+ * Distributed under the GNU GPL license version 2. -+ */ -+ -+//#include -+#include -+#include "kerncompat.h" -+#include "ulist.h" -+#include "ctree.h" -+ -+/* -+ * ulist is a generic data structure to hold a collection of unique u64 -+ * values. The only operations it supports is adding to the list and -+ * enumerating it. -+ * It is possible to store an auxiliary value along with the key. -+ * -+ * A sample usage for ulists is the enumeration of directed graphs without -+ * visiting a node twice. The pseudo-code could look like this: -+ * -+ * ulist = ulist_alloc(); -+ * ulist_add(ulist, root); -+ * ULIST_ITER_INIT(&uiter); -+ * -+ * while ((elem = ulist_next(ulist, &uiter)) { -+ * for (all child nodes n in elem) -+ * ulist_add(ulist, n); -+ * do something useful with the node; -+ * } -+ * ulist_free(ulist); -+ * -+ * This assumes the graph nodes are adressable by u64. This stems from the -+ * usage for tree enumeration in btrfs, where the logical addresses are -+ * 64 bit. -+ * -+ * It is also useful for tree enumeration which could be done elegantly -+ * recursively, but is not possible due to kernel stack limitations. The -+ * loop would be similar to the above. -+ */ -+ -+/** -+ * ulist_init - freshly initialize a ulist -+ * @ulist: the ulist to initialize -+ * -+ * Note: don't use this function to init an already used ulist, use -+ * ulist_reinit instead. -+ */ -+void ulist_init(struct ulist *ulist) -+{ -+ INIT_LIST_HEAD(&ulist->nodes); -+ ulist->root = RB_ROOT; -+ ulist->nnodes = 0; -+} -+ -+/** -+ * ulist_fini - free up additionally allocated memory for the ulist -+ * @ulist: the ulist from which to free the additional memory -+ * -+ * This is useful in cases where the base 'struct ulist' has been statically -+ * allocated. -+ */ -+static void ulist_fini(struct ulist *ulist) -+{ -+ struct ulist_node *node; -+ struct ulist_node *next; -+ -+ list_for_each_entry_safe(node, next, &ulist->nodes, list) { -+ kfree(node); -+ } -+ ulist->root = RB_ROOT; -+ INIT_LIST_HEAD(&ulist->nodes); -+} -+ -+/** -+ * ulist_reinit - prepare a ulist for reuse -+ * @ulist: ulist to be reused -+ * -+ * Free up all additional memory allocated for the list elements and reinit -+ * the ulist. -+ */ -+void ulist_reinit(struct ulist *ulist) -+{ -+ ulist_fini(ulist); -+ ulist_init(ulist); -+} -+ -+/** -+ * ulist_alloc - dynamically allocate a ulist -+ * @gfp_mask: allocation flags to for base allocation -+ * -+ * The allocated ulist will be returned in an initialized state. -+ */ -+struct ulist *ulist_alloc(gfp_t gfp_mask) -+{ -+ struct ulist *ulist = kmalloc(sizeof(*ulist), gfp_mask); -+ -+ if (!ulist) -+ return NULL; -+ -+ ulist_init(ulist); -+ -+ return ulist; -+} -+ -+/** -+ * ulist_free - free dynamically allocated ulist -+ * @ulist: ulist to free -+ * -+ * It is not necessary to call ulist_fini before. -+ */ -+void ulist_free(struct ulist *ulist) -+{ -+ if (!ulist) -+ return; -+ ulist_fini(ulist); -+ kfree(ulist); -+} -+ -+static struct ulist_node *ulist_rbtree_search(struct ulist *ulist, u64 val) -+{ -+ struct rb_node *n = ulist->root.rb_node; -+ struct ulist_node *u = NULL; -+ -+ while (n) { -+ u = rb_entry(n, struct ulist_node, rb_node); -+ if (u->val < val) -+ n = n->rb_right; -+ else if (u->val > val) -+ n = n->rb_left; -+ else -+ return u; -+ } -+ return NULL; -+} -+ -+static int ulist_rbtree_insert(struct ulist *ulist, struct ulist_node *ins) -+{ -+ struct rb_node **p = &ulist->root.rb_node; -+ struct rb_node *parent = NULL; -+ struct ulist_node *cur = NULL; -+ -+ while (*p) { -+ parent = *p; -+ cur = rb_entry(parent, struct ulist_node, rb_node); -+ -+ if (cur->val < ins->val) -+ p = &(*p)->rb_right; -+ else if (cur->val > ins->val) -+ p = &(*p)->rb_left; -+ else -+ return -EEXIST; -+ } -+ rb_link_node(&ins->rb_node, parent, p); -+ rb_insert_color(&ins->rb_node, &ulist->root); -+ return 0; -+} -+ -+/** -+ * ulist_add - add an element to the ulist -+ * @ulist: ulist to add the element to -+ * @val: value to add to ulist -+ * @aux: auxiliary value to store along with val -+ * @gfp_mask: flags to use for allocation -+ * -+ * Note: locking must be provided by the caller. In case of rwlocks write -+ * locking is needed -+ * -+ * Add an element to a ulist. The @val will only be added if it doesn't -+ * already exist. If it is added, the auxiliary value @aux is stored along with -+ * it. In case @val already exists in the ulist, @aux is ignored, even if -+ * it differs from the already stored value. -+ * -+ * ulist_add returns 0 if @val already exists in ulist and 1 if @val has been -+ * inserted. -+ * In case of allocation failure -ENOMEM is returned and the ulist stays -+ * unaltered. -+ */ -+int ulist_add(struct ulist *ulist, u64 val, u64 aux, gfp_t gfp_mask) -+{ -+ return ulist_add_merge(ulist, val, aux, NULL, gfp_mask); -+} -+ -+int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux, -+ u64 *old_aux, gfp_t gfp_mask) -+{ -+ int ret; -+ struct ulist_node *node; -+ -+ node = ulist_rbtree_search(ulist, val); -+ if (node) { -+ if (old_aux) -+ *old_aux = node->aux; -+ return 0; -+ } -+ node = kmalloc(sizeof(*node), gfp_mask); -+ if (!node) -+ return -ENOMEM; -+ -+ node->val = val; -+ node->aux = aux; -+#ifdef CONFIG_BTRFS_DEBUG -+ node->seqnum = ulist->nnodes; -+#endif -+ -+ ret = ulist_rbtree_insert(ulist, node); -+ ASSERT(!ret); -+ list_add_tail(&node->list, &ulist->nodes); -+ ulist->nnodes++; -+ -+ return 1; -+} -+ -+/** -+ * ulist_next - iterate ulist -+ * @ulist: ulist to iterate -+ * @uiter: iterator variable, initialized with ULIST_ITER_INIT(&iterator) -+ * -+ * Note: locking must be provided by the caller. In case of rwlocks only read -+ * locking is needed -+ * -+ * This function is used to iterate an ulist. -+ * It returns the next element from the ulist or %NULL when the -+ * end is reached. No guarantee is made with respect to the order in which -+ * the elements are returned. They might neither be returned in order of -+ * addition nor in ascending order. -+ * It is allowed to call ulist_add during an enumeration. Newly added items -+ * are guaranteed to show up in the running enumeration. -+ */ -+struct ulist_node *ulist_next(struct ulist *ulist, struct ulist_iterator *uiter) -+{ -+ struct ulist_node *node; -+ -+ if (list_empty(&ulist->nodes)) -+ return NULL; -+ if (uiter->cur_list && uiter->cur_list->next == &ulist->nodes) -+ return NULL; -+ if (uiter->cur_list) { -+ uiter->cur_list = uiter->cur_list->next; -+ } else { -+ uiter->cur_list = ulist->nodes.next; -+#ifdef CONFIG_BTRFS_DEBUG -+ uiter->i = 0; -+#endif -+ } -+ node = list_entry(uiter->cur_list, struct ulist_node, list); -+#ifdef CONFIG_BTRFS_DEBUG -+ ASSERT(node->seqnum == uiter->i); -+ ASSERT(uiter->i >= 0 && uiter->i < ulist->nnodes); -+ uiter->i++; -+#endif -+ return node; -+} -Index: btrfs-progs-v3.14.1/ulist.h -=================================================================== ---- /dev/null -+++ btrfs-progs-v3.14.1/ulist.h -@@ -0,0 +1,66 @@ -+/* -+ * Copyright (C) 2011 STRATO AG -+ * written by Arne Jansen -+ * Distributed under the GNU GPL license version 2. -+ * -+ */ -+ -+#ifndef __ULIST__ -+#define __ULIST__ -+ -+#include "kerncompat.h" -+#include "list.h" -+#include "rbtree.h" -+ -+/* -+ * ulist is a generic data structure to hold a collection of unique u64 -+ * values. The only operations it supports is adding to the list and -+ * enumerating it. -+ * It is possible to store an auxiliary value along with the key. -+ * -+ */ -+struct ulist_iterator { -+#ifdef CONFIG_BTRFS_DEBUG -+ int i; -+#endif -+ struct list_head *cur_list; /* hint to start search */ -+}; -+ -+/* -+ * element of the list -+ */ -+struct ulist_node { -+ u64 val; /* value to store */ -+ u64 aux; /* auxiliary value saved along with the val */ -+ -+#ifdef CONFIG_BTRFS_DEBUG -+ int seqnum; /* sequence number this node is added */ -+#endif -+ -+ struct list_head list; /* used to link node */ -+ struct rb_node rb_node; /* used to speed up search */ -+}; -+ -+struct ulist { -+ /* -+ * number of elements stored in list -+ */ -+ unsigned long nnodes; -+ -+ struct list_head nodes; -+ struct rb_root root; -+}; -+ -+void ulist_init(struct ulist *ulist); -+void ulist_reinit(struct ulist *ulist); -+struct ulist *ulist_alloc(gfp_t gfp_mask); -+void ulist_free(struct ulist *ulist); -+int ulist_add(struct ulist *ulist, u64 val, u64 aux, gfp_t gfp_mask); -+int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux, -+ u64 *old_aux, gfp_t gfp_mask); -+struct ulist_node *ulist_next(struct ulist *ulist, -+ struct ulist_iterator *uiter); -+ -+#define ULIST_ITER_INIT(uiter) ((uiter)->cur_list = NULL) -+ -+#endif diff --git a/0202-btrfs-progs-add-quota-group-verify-code.patch b/0202-btrfs-progs-add-quota-group-verify-code.patch deleted file mode 100644 index da37b58..0000000 --- a/0202-btrfs-progs-add-quota-group-verify-code.patch +++ /dev/null @@ -1,1385 +0,0 @@ -From c8c1814a8b10fab0fae7a32ef239ec8847a0ca81 Mon Sep 17 00:00:00 2001 -From: Mark Fasheh -Date: Thu, 1 May 2014 22:44:24 -0700 -Subject: [PATCH 3/3] btrfs-progs: add quota group verify code -References: bnc#886493 bnc#865621 -Upstream: submitted - -This patch adds functionality (in qgroup-verify.c) to compute bytecounts in -subvolume quota groups. The original groups are read in and stored in memory -so that after we compute our own bytecounts, we can compare them with those -on disk. A print function is provided to do this comparison and show the -results on the console. - -A 'qgroup check' pass is added to btrfsck. If any subvolume quota groups -differ from what we compute, the differences for them are printed. We also -provide an option '--qgroup-report' which will run only the quota check code -and print a report on all quota groups. Other than making it possible to -verify that our qgroup changes work correctly, this mode can also be used in -xfstests for automated checking after qgroup tests. - -This patch does not address the following: -- compressed counts are identical to non compressed, because kernel doesn't - make the distinction yet. Adding the code to verify compressed counts - shouldn't be hard at all though once kernel can do this. -- It is only concerned with subvolume quota groups (like most of - btrfs-progs). - -Signed-off-by: Mark Fasheh ---- - Makefile | 2 +- - cmds-check.c | 24 ++ - ctree.h | 10 + - disk-io.c | 16 +- - print-tree.c | 2 +- - print-tree.h | 1 + - qgroup-verify.c | 1085 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ - qgroup-verify.h | 25 ++ - 8 files changed, 1161 insertions(+), 4 deletions(-) - create mode 100644 qgroup-verify.c - create mode 100644 qgroup-verify.h - -Index: btrfs-progs-v3.14.1/Makefile -=================================================================== ---- btrfs-progs-v3.14.1.orig/Makefile -+++ btrfs-progs-v3.14.1/Makefile -@@ -10,7 +10,7 @@ objects = ctree.o disk-io.o radix-tree.o - root-tree.o dir-item.o file-item.o inode-item.o inode-map.o \ - extent-cache.o extent_io.o volumes.o utils.o repair.o \ - qgroup.o raid6.o free-space-cache.o list_sort.o props.o \ -- utils-lib.o string_table.o ulist.o -+ utils-lib.o string_table.o ulist.o qgroup-verify.o - cmds_objects = cmds-subvolume.o cmds-filesystem.o cmds-device.o cmds-scrub.o \ - cmds-inspect.o cmds-balance.o cmds-send.o cmds-receive.o \ - cmds-quota.o cmds-qgroup.o cmds-replace.o cmds-check.o \ -Index: btrfs-progs-v3.14.1/cmds-check.c -=================================================================== ---- btrfs-progs-v3.14.1.orig/cmds-check.c -+++ btrfs-progs-v3.14.1/cmds-check.c -@@ -38,6 +38,7 @@ - #include "commands.h" - #include "free-space-cache.h" - #include "btrfsck.h" -+#include "qgroup-verify.h" - - static u64 bytes_used = 0; - static u64 total_csum_bytes = 0; -@@ -6472,6 +6473,7 @@ static struct option long_options[] = { - { "init-csum-tree", 0, NULL, 0 }, - { "init-extent-tree", 0, NULL, 0 }, - { "backup", 0, NULL, 0 }, -+ { "qgroup-report", 0, NULL, 'Q' }, - { NULL, 0, NULL, 0} - }; - -@@ -6484,6 +6486,7 @@ const char * const cmd_check_usage[] = { - "--repair try to repair the filesystem", - "--init-csum-tree create a new CRC tree", - "--init-extent-tree create a new extent tree", -+ "--qgroup-report print a report on qgroup consistency", - NULL - }; - -@@ -6498,6 +6501,7 @@ int cmd_check(int argc, char **argv) - u64 num; - int option_index = 0; - int init_csum_tree = 0; -+ int qgroup_report = 0; - enum btrfs_open_ctree_flags ctree_flags = - OPEN_CTREE_PARTIAL | OPEN_CTREE_EXCLUSIVE; - -@@ -6524,6 +6528,9 @@ int cmd_check(int argc, char **argv) - printf("using SB copy %llu, bytenr %llu\n", num, - (unsigned long long)bytenr); - break; -+ case 'Q': -+ qgroup_report = 1; -+ break; - case '?': - case 'h': - usage(cmd_check_usage); -@@ -6588,6 +6595,14 @@ int cmd_check(int argc, char **argv) - } - - uuid_unparse(info->super_copy->fsid, uuidbuf); -+ if (qgroup_report) { -+ printf("Print quota groups for %s\nUUID: %s\n", argv[optind], -+ uuidbuf); -+ ret = qgroup_verify_all(info); -+ if (ret == 0) -+ print_qgroup_report(1); -+ goto close_out; -+ } - printf("Checking filesystem on %s\nUUID: %s\n", argv[optind], uuidbuf); - - if (!extent_buffer_uptodate(info->tree_root->node) || -@@ -6691,11 +6706,20 @@ int cmd_check(int argc, char **argv) - free(bad); - } - -+ if (info->quota_enabled) { -+ int err; -+ fprintf(stderr, "checking quota groups\n"); -+ err = qgroup_verify_all(info); -+ if (err) -+ goto out; -+ } -+ - if (!list_empty(&root->fs_info->recow_ebs)) { - fprintf(stderr, "Transid errors in file system\n"); - ret = 1; - } - out: -+ print_qgroup_report(0); - if (found_old_backref) { /* - * there was a disk format change when mixed - * backref was in testing tree. The old format -Index: btrfs-progs-v3.14.1/ctree.h -=================================================================== ---- btrfs-progs-v3.14.1.orig/ctree.h -+++ btrfs-progs-v3.14.1/ctree.h -@@ -950,6 +950,7 @@ struct btrfs_fs_info { - struct btrfs_root *chunk_root; - struct btrfs_root *dev_root; - struct btrfs_root *csum_root; -+ struct btrfs_root *quota_root; - - struct rb_root fs_root_tree; - -@@ -995,6 +996,7 @@ struct btrfs_fs_info { - unsigned int readonly:1; - unsigned int on_restoring:1; - unsigned int is_chunk_recover:1; -+ unsigned int quota_enabled:1; - - int (*free_extent_hook)(struct btrfs_trans_handle *trans, - struct btrfs_root *root, -@@ -2389,4 +2391,12 @@ int btrfs_csum_truncate(struct btrfs_tra - int btrfs_lookup_uuid_subvol_item(int fd, const u8 *uuid, u64 *subvol_id); - int btrfs_lookup_uuid_received_subvol_item(int fd, const u8 *uuid, - u64 *subvol_id); -+ -+static inline int is_fstree(u64 rootid) -+{ -+ if (rootid == BTRFS_FS_TREE_OBJECTID || -+ (signed long long)rootid >= (signed long long)BTRFS_FIRST_FREE_OBJECTID) -+ return 1; -+ return 0; -+} - #endif -Index: btrfs-progs-v3.14.1/disk-io.c -=================================================================== ---- btrfs-progs-v3.14.1.orig/disk-io.c -+++ btrfs-progs-v3.14.1/disk-io.c -@@ -571,7 +571,6 @@ static int find_and_setup_log_root(struc - return 0; - } - -- - int btrfs_free_fs_root(struct btrfs_root *root) - { - if (root->node) -@@ -697,6 +696,8 @@ struct btrfs_root *btrfs_read_fs_root(st - return fs_info->dev_root; - if (location->objectid == BTRFS_CSUM_TREE_OBJECTID) - return fs_info->csum_root; -+ if (location->objectid == BTRFS_QUOTA_TREE_OBJECTID) -+ return fs_info->csum_root; - - BUG_ON(location->objectid == BTRFS_TREE_RELOC_OBJECTID || - location->offset != (u64)-1); -@@ -723,6 +724,7 @@ void btrfs_free_fs_info(struct btrfs_fs_ - free(fs_info->chunk_root); - free(fs_info->dev_root); - free(fs_info->csum_root); -+ free(fs_info->quota_root); - free(fs_info->super_copy); - free(fs_info->log_root_tree); - free(fs_info); -@@ -743,11 +745,13 @@ struct btrfs_fs_info *btrfs_new_fs_info( - fs_info->chunk_root = malloc(sizeof(struct btrfs_root)); - fs_info->dev_root = malloc(sizeof(struct btrfs_root)); - fs_info->csum_root = malloc(sizeof(struct btrfs_root)); -+ fs_info->quota_root = malloc(sizeof(struct btrfs_root)); - fs_info->super_copy = malloc(BTRFS_SUPER_INFO_SIZE); - - if (!fs_info->tree_root || !fs_info->extent_root || - !fs_info->chunk_root || !fs_info->dev_root || -- !fs_info->csum_root || !fs_info->super_copy) -+ !fs_info->csum_root || !fs_info->quota_root || -+ !fs_info->super_copy) - goto free_all; - - memset(fs_info->super_copy, 0, BTRFS_SUPER_INFO_SIZE); -@@ -756,6 +760,7 @@ struct btrfs_fs_info *btrfs_new_fs_info( - memset(fs_info->chunk_root, 0, sizeof(struct btrfs_root)); - memset(fs_info->dev_root, 0, sizeof(struct btrfs_root)); - memset(fs_info->csum_root, 0, sizeof(struct btrfs_root)); -+ memset(fs_info->quota_root, 0, sizeof(struct btrfs_root)); - - extent_io_tree_init(&fs_info->extent_cache); - extent_io_tree_init(&fs_info->free_space_cache); -@@ -914,6 +919,11 @@ int btrfs_setup_all_roots(struct btrfs_f - } - fs_info->csum_root->track_dirty = 1; - -+ ret = find_and_setup_root(root, fs_info, BTRFS_QUOTA_TREE_OBJECTID, -+ fs_info->quota_root); -+ if (ret == 0) -+ fs_info->quota_enabled = 1; -+ - ret = find_and_setup_log_root(root, fs_info, sb); - if (ret) { - printk("Couldn't setup log root tree\n"); -@@ -938,6 +948,8 @@ int btrfs_setup_all_roots(struct btrfs_f - - void btrfs_release_all_roots(struct btrfs_fs_info *fs_info) - { -+ if (fs_info->quota_root) -+ free_extent_buffer(fs_info->quota_root->node); - if (fs_info->csum_root) - free_extent_buffer(fs_info->csum_root->node); - if (fs_info->dev_root) -Index: btrfs-progs-v3.14.1/print-tree.c -=================================================================== ---- btrfs-progs-v3.14.1.orig/print-tree.c -+++ btrfs-progs-v3.14.1/print-tree.c -@@ -242,7 +242,7 @@ static void print_file_extent_item(struc - btrfs_file_extent_compression(eb, fi)); - } - --static void print_extent_item(struct extent_buffer *eb, int slot, int metadata) -+void print_extent_item(struct extent_buffer *eb, int slot, int metadata) - { - struct btrfs_extent_item *ei; - struct btrfs_extent_inline_ref *iref; -Index: btrfs-progs-v3.14.1/print-tree.h -=================================================================== ---- btrfs-progs-v3.14.1.orig/print-tree.h -+++ btrfs-progs-v3.14.1/print-tree.h -@@ -21,4 +21,5 @@ - void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l); - void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *t, int follow); - void btrfs_print_key(struct btrfs_disk_key *disk_key); -+void print_extent_item(struct extent_buffer *eb, int slot, int metadata); - #endif -Index: btrfs-progs-v3.14.1/qgroup-verify.c -=================================================================== ---- /dev/null -+++ btrfs-progs-v3.14.1/qgroup-verify.c -@@ -0,0 +1,1085 @@ -+/* -+ * Copyright (C) 2014 SUSE. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public -+ * License v2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this program; if not, write to the -+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, -+ * Boston, MA 021110-1307, USA. -+ * -+ * Authors: Mark Fasheh -+ */ -+ -+#include -+#include -+#include -+#include "kerncompat.h" -+#include "radix-tree.h" -+#include "ctree.h" -+#include "disk-io.h" -+#include "print-tree.h" -+#include "utils.h" -+#include "ulist.h" -+ -+#include "qgroup-verify.h" -+ -+/*#define QGROUP_VERIFY_DEBUG*/ -+static unsigned long tot_extents_scanned = 0; -+ -+static void add_bytes(u64 root_objectid, u64 num_bytes, int exclusive); -+ -+struct qgroup_count { -+ u64 qgroupid; -+ -+ struct btrfs_disk_key key; -+ struct btrfs_qgroup_info_item diskinfo; -+ -+ struct btrfs_qgroup_info_item info; -+ -+ struct rb_node rb_node; -+}; -+ -+struct counts_tree { -+ struct rb_root root; -+ unsigned int num_groups; -+} counts = { .root = RB_ROOT }; -+ -+struct rb_root by_bytenr = RB_ROOT; -+ -+/* -+ * List of interior tree blocks. We walk this list after loading the -+ * extent tree to resolve implied refs. For each interior node we'll -+ * place a shared ref in the ref tree against each child object. This -+ * allows the shared ref resolving code to do the actual work later of -+ * finding roots to account against. -+ * -+ * An implied ref is when a tree block has refs on it that may not -+ * exist in any of it's child nodes. Even though the refs might not -+ * exist further down the tree, the fact that our interior node has a -+ * ref means we need to account anything below it to all it's roots. -+ */ -+struct ulist *tree_blocks = NULL; /* unode->val = bytenr, ->aux -+ * = tree_block pointer */ -+struct tree_block { -+ int level; -+ u64 num_bytes; -+}; -+ -+struct ref { -+ u64 bytenr; -+ u64 num_bytes; -+ u64 parent; -+ u64 root; -+ -+ struct rb_node bytenr_node; -+}; -+ -+#ifdef QGROUP_VERIFY_DEBUG -+static void print_ref(struct ref *ref) -+{ -+ printf("bytenr: %llu\t\tnum_bytes: %llu\t\t parent: %llu\t\t" -+ "root: %llu\n", ref->bytenr, ref->num_bytes, -+ ref->parent, ref->root); -+} -+ -+static void print_all_refs(void) -+{ -+ unsigned long count = 0; -+ struct ref *ref; -+ struct rb_node *node; -+ -+ node = rb_first(&by_bytenr); -+ while (node) { -+ ref = rb_entry(node, struct ref, bytenr_node); -+ -+ print_ref(ref); -+ -+ count++; -+ node = rb_next(node); -+ } -+ -+ printf("%lu extents scanned with %lu refs in total.\n", -+ tot_extents_scanned, count); -+} -+#endif -+ -+/* -+ * Store by bytenr in rbtree -+ * -+ * The tree is sorted in ascending order by bytenr, then parent, then -+ * root. Since full refs have a parent == 0, those will come before -+ * shared refs. -+ */ -+static int compare_ref(struct ref *orig, u64 bytenr, u64 root, u64 parent) -+{ -+ if (bytenr < orig->bytenr) -+ return -1; -+ if (bytenr > orig->bytenr) -+ return 1; -+ -+ if (parent < orig->parent) -+ return -1; -+ if (parent > orig->parent) -+ return 1; -+ -+ if (root < orig->root) -+ return -1; -+ if (root > orig->root) -+ return 1; -+ -+ return 0; -+} -+ -+/* -+ * insert a new ref into the tree. returns the existing ref entry -+ * if one is already there. -+ */ -+static struct ref *insert_ref(struct ref *ref) -+{ -+ int ret; -+ struct rb_node **p = &by_bytenr.rb_node; -+ struct rb_node *parent = NULL; -+ struct ref *curr; -+ -+ while (*p) { -+ parent = *p; -+ curr = rb_entry(parent, struct ref, bytenr_node); -+ -+ ret = compare_ref(curr, ref->bytenr, ref->root, ref->parent); -+ if (ret < 0) -+ p = &(*p)->rb_left; -+ else if (ret > 0) -+ p = &(*p)->rb_right; -+ else -+ return curr; -+ } -+ -+ rb_link_node(&ref->bytenr_node, parent, p); -+ rb_insert_color(&ref->bytenr_node, &by_bytenr); -+ return ref; -+} -+ -+/* -+ * Partial search, returns the first ref with matching bytenr. Caller -+ * can walk forward from there. -+ * -+ * Leftmost refs will be full refs - this is used to our advantage -+ * when resolving roots. -+ */ -+static struct ref *find_ref_bytenr(u64 bytenr) -+{ -+ struct rb_node *n = by_bytenr.rb_node; -+ struct ref *ref; -+ -+ while (n) { -+ ref = rb_entry(n, struct ref, bytenr_node); -+ -+ if (bytenr < ref->bytenr) -+ n = n->rb_left; -+ else if (bytenr > ref->bytenr) -+ n = n->rb_right; -+ else { -+ /* Walk to the left to find the first item */ -+ struct rb_node *node_left = rb_prev(&ref->bytenr_node); -+ struct ref *ref_left; -+ -+ while (node_left) { -+ ref_left = rb_entry(node_left, struct ref, -+ bytenr_node); -+ if (ref_left->bytenr != ref->bytenr) -+ break; -+ ref = ref_left; -+ node_left = rb_prev(node_left); -+ } -+ return ref; -+ } -+ } -+ return NULL; -+} -+ -+static struct ref *find_ref(u64 bytenr, u64 root, u64 parent) -+{ -+ struct rb_node *n = by_bytenr.rb_node; -+ struct ref *ref; -+ int ret; -+ -+ while (n) { -+ ref = rb_entry(n, struct ref, bytenr_node); -+ -+ ret = compare_ref(ref, bytenr, root, parent); -+ if (ret < 0) -+ n = n->rb_left; -+ else if (ret > 0) -+ n = n->rb_right; -+ else -+ return ref; -+ } -+ return NULL; -+} -+ -+static struct ref *alloc_ref(u64 bytenr, u64 root, u64 parent, u64 num_bytes) -+{ -+ struct ref *ref = find_ref(bytenr, root, parent); -+ -+ BUG_ON(parent && root); -+ -+ if (ref == NULL) { -+ ref = calloc(1, sizeof(*ref)); -+ if (ref) { -+ ref->bytenr = bytenr; -+ ref->root = root; -+ ref->parent = parent; -+ ref->num_bytes = num_bytes; -+ -+ insert_ref(ref); -+ } -+ } -+ return ref; -+} -+ -+static void free_ref_node(struct rb_node *node) -+{ -+ struct ref *ref = rb_entry(node, struct ref, bytenr_node); -+ free(ref); -+} -+ -+FREE_RB_BASED_TREE(ref, free_ref_node); -+ -+/* -+ * Resolves all the possible roots for the ref at parent. -+ */ -+static void find_parent_roots(struct ulist *roots, u64 parent) -+{ -+ struct ref *ref; -+ struct rb_node *node; -+ -+ /* -+ * Search the rbtree for the first ref with bytenr == parent. -+ * Walk forward so long as bytenr == parent, adding resolved root ids. -+ * For each unresolved root, we recurse -+ */ -+ ref = find_ref_bytenr(parent); -+ node = &ref->bytenr_node; -+ BUG_ON(ref == NULL); -+ BUG_ON(ref->bytenr != parent); -+ -+ { -+ /* -+ * Random sanity check, are we actually getting the -+ * leftmost node? -+ */ -+ struct rb_node *prev_node = rb_prev(&ref->bytenr_node); -+ struct ref *prev; -+ if (prev_node) { -+ prev = rb_entry(prev_node, struct ref, bytenr_node); -+ BUG_ON(prev->bytenr == parent); -+ } -+ } -+ -+ do { -+ if (ref->root) -+ ulist_add(roots, ref->root, 0, 0); -+ else -+ find_parent_roots(roots, ref->parent); -+ -+ node = rb_next(node); -+ if (node) -+ ref = rb_entry(node, struct ref, bytenr_node); -+ } while (node && ref->bytenr == parent); -+} -+ -+/* -+ * Account each ref. Walk the refs, for each set of refs in a -+ * given bytenr: -+ * -+ * - add the roots for direct refs to the ref roots ulist -+ * -+ * - resolve all possible roots for shared refs, insert each -+ * of those into ref_roots ulist (this is a recursive process) -+ * -+ * - Walk ref_roots ulist, adding extent bytes to each qgroup count that -+ * cooresponds to a found root. -+ */ -+static void account_all_refs(void) -+{ -+ int exclusive; -+ struct ref *ref; -+ struct rb_node *node; -+ u64 bytenr, num_bytes; -+ struct ulist *roots = ulist_alloc(0); -+ struct ulist_iterator uiter; -+ struct ulist_node *unode; -+ -+ node = rb_first(&by_bytenr); -+ while (node) { -+ ulist_reinit(roots); -+ -+ ref = rb_entry(node, struct ref, bytenr_node); -+ /* -+ * Walk forward through the list of refs for this -+ * bytenr, adding roots to our ulist. If it's a full -+ * ref, then we have the easy case. Otherwise we need -+ * to search for roots. -+ */ -+ bytenr = ref->bytenr; -+ num_bytes = ref->num_bytes; -+ do { -+ BUG_ON(ref->bytenr != bytenr); -+ BUG_ON(ref->num_bytes != num_bytes); -+ if (ref->root) -+ ulist_add(roots, ref->root, 0, 0); -+ else -+ find_parent_roots(roots, ref->parent); -+ -+ /* -+ * When we leave this inner loop, node is set -+ * to next in our tree and will be turned into -+ * a ref object up top -+ */ -+ node = rb_next(node); -+ if (node) -+ ref = rb_entry(node, struct ref, bytenr_node); -+ } while (node && ref->bytenr == bytenr); -+ -+ /* -+ * Now that we have all roots, we can properly account -+ * this extent against the corresponding qgroups. -+ */ -+ if (roots->nnodes == 1) -+ exclusive = 1; -+ else -+ exclusive = 0; -+ -+ ULIST_ITER_INIT(&uiter); -+ while ((unode = ulist_next(roots, &uiter))) { -+ BUG_ON(unode->val == 0ULL); -+ /* We only want to account fs trees */ -+ if (is_fstree(unode->val)) -+ add_bytes(unode->val, num_bytes, exclusive); -+ } -+ } -+ -+ ulist_free(roots); -+} -+ -+static u64 resolve_one_root(u64 bytenr) -+{ -+ struct ref *ref = find_ref_bytenr(bytenr); -+ -+ BUG_ON(ref == NULL); -+ -+ if (ref->root) -+ return ref->root; -+ return resolve_one_root(ref->parent); -+} -+ -+static inline struct tree_block *unode_tree_block(struct ulist_node *unode) -+{ -+ return (struct tree_block *)unode->aux; -+} -+static inline u64 unode_bytenr(struct ulist_node *unode) -+{ -+ return unode->val; -+} -+ -+static int alloc_tree_block(u64 bytenr, u64 num_bytes, int level) -+{ -+ struct tree_block *block = calloc(1, sizeof(*block)); -+ -+ if (block) { -+ block->num_bytes = num_bytes; -+ block->level = level; -+ if (ulist_add(tree_blocks, bytenr, (unsigned long long)block, 0) >= 0) -+ return 0; -+ free(block); -+ } -+ return -ENOMEM; -+} -+ -+static void free_tree_blocks(void) -+{ -+ struct ulist_iterator uiter; -+ struct ulist_node *unode; -+ -+ if (!tree_blocks) -+ return; -+ -+ ULIST_ITER_INIT(&uiter); -+ while ((unode = ulist_next(tree_blocks, &uiter))) -+ free(unode_tree_block(unode)); -+ ulist_free(tree_blocks); -+ tree_blocks = NULL; -+} -+ -+#ifdef QGROUP_VERIFY_DEBUG -+static void print_tree_block(u64 bytenr, struct tree_block *block) -+{ -+ struct ref *ref; -+ struct rb_node *node; -+ -+ printf("tree block: %llu\t\tlevel: %d\n", (unsigned long long)bytenr, -+ block->level); -+ -+ ref = find_ref_bytenr(bytenr); -+ node = &ref->bytenr_node; -+ do { -+ print_ref(ref); -+ node = rb_next(node); -+ if (node) -+ ref = rb_entry(node, struct ref, bytenr_node); -+ } while (node && ref->bytenr == bytenr); -+ -+ printf("\n"); -+} -+ -+static void print_all_tree_blocks(void) -+{ -+ struct ulist_iterator uiter; -+ struct ulist_node *unode; -+ -+ if (!tree_blocks) -+ return; -+ -+ printf("Listing all found interior tree nodes:\n"); -+ -+ ULIST_ITER_INIT(&uiter); -+ while ((unode = ulist_next(tree_blocks, &uiter))) -+ print_tree_block(unode_bytenr(unode), unode_tree_block(unode)); -+} -+#endif -+ -+static int add_refs_for_leaf_items(struct extent_buffer *eb, u64 ref_parent) -+{ -+ int nr, i; -+ int extent_type; -+ u64 bytenr, num_bytes; -+ struct btrfs_key key; -+ struct btrfs_disk_key disk_key; -+ struct btrfs_file_extent_item *fi; -+ -+ nr = btrfs_header_nritems(eb); -+ for (i = 0; i < nr; i++) { -+ btrfs_item_key(eb, &disk_key, i); -+ btrfs_disk_key_to_cpu(&key, &disk_key); -+ -+ if (key.type != BTRFS_EXTENT_DATA_KEY) -+ continue; -+ -+ fi = btrfs_item_ptr(eb, i, struct btrfs_file_extent_item); -+ /* filter out: inline, disk_bytenr == 0, compressed? -+ * not if we can avoid it */ -+ extent_type = btrfs_file_extent_type(eb, fi); -+ -+ if (extent_type == BTRFS_FILE_EXTENT_INLINE) -+ continue; -+ -+ bytenr = btrfs_file_extent_disk_bytenr(eb, fi); -+ if (!bytenr) -+ continue; -+ -+ num_bytes = btrfs_file_extent_disk_num_bytes(eb, fi); -+ if (alloc_ref(bytenr, 0, ref_parent, num_bytes) == NULL) -+ return ENOMEM; -+ } -+ -+ return 0; -+} -+ -+static int travel_tree(struct btrfs_fs_info *info, struct btrfs_root *root, -+ u64 bytenr, u64 num_bytes, u64 ref_parent) -+{ -+ int ret, nr, i; -+ struct extent_buffer *eb; -+ u64 new_bytenr; -+ u64 new_num_bytes; -+ -+// printf("travel_tree: bytenr: %llu\tnum_bytes: %llu\tref_parent: %llu\n", -+// bytenr, num_bytes, ref_parent); -+ -+ eb = read_tree_block(root, bytenr, num_bytes, 0); -+ if (!eb) -+ return -EIO; -+ -+ ret = 0; -+ /* Don't add a ref for our starting tree block to itself */ -+ if (bytenr != ref_parent) { -+ if (alloc_ref(bytenr, 0, ref_parent, num_bytes) == NULL) -+ return ENOMEM; -+ } -+ -+ if (btrfs_is_leaf(eb)) { -+ ret = add_refs_for_leaf_items(eb, ref_parent); -+ goto out; -+ } -+ -+ /* -+ * Interior nodes are tuples of (key, bytenr) where key is the -+ * leftmost key in the tree block pointed to by bytenr. We -+ * don't have to care about key here, just follow the bytenr -+ * pointer. -+ */ -+ nr = btrfs_header_nritems(eb); -+ for (i = 0; i < nr; i++) { -+ new_bytenr = btrfs_node_blockptr(eb, i); -+ new_num_bytes = btrfs_level_size(root, -+ btrfs_header_level(eb) - 1); -+ -+ ret = travel_tree(info, root, new_bytenr, new_num_bytes, -+ ref_parent); -+ } -+ -+out: -+ free_extent_buffer(eb); -+ return ret; -+} -+ -+static int add_refs_for_implied(struct btrfs_fs_info *info, u64 bytenr, -+ struct tree_block *block) -+{ -+ int ret; -+ u64 root_bytenr = resolve_one_root(bytenr); -+ struct btrfs_root *root; -+ struct btrfs_key key; -+ -+ key.objectid = root_bytenr; -+ key.type = BTRFS_ROOT_ITEM_KEY; -+ key.offset = (u64)-1; -+ -+ /* -+ * XXX: Don't free the root object as we don't know whether it -+ * came off our fs_info struct or not. -+ */ -+ root = btrfs_read_fs_root(info, &key); -+ if (!root || IS_ERR(root)) -+ return ENOENT; -+ -+ ret = travel_tree(info, root, bytenr, block->num_bytes, bytenr); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+/* -+ * Place shared refs in the ref tree for each child of an interior tree node. -+ */ -+static int map_implied_refs(struct btrfs_fs_info *info) -+{ -+ int ret = 0; -+ struct ulist_iterator uiter; -+ struct ulist_node *unode; -+ -+ ULIST_ITER_INIT(&uiter); -+ while ((unode = ulist_next(tree_blocks, &uiter))) { -+ ret = add_refs_for_implied(info, unode_bytenr(unode), -+ unode_tree_block(unode)); -+ if (ret) -+ goto out; -+ } -+out: -+ return ret; -+} -+ -+/* -+ * insert a new root into the tree. returns the existing root entry -+ * if one is already there. qgroupid is used -+ * as the key -+ */ -+static int insert_count(struct qgroup_count *qc) -+{ -+ struct rb_node **p = &counts.root.rb_node; -+ struct rb_node *parent = NULL; -+ struct qgroup_count *curr; -+ -+ while (*p) { -+ parent = *p; -+ curr = rb_entry(parent, struct qgroup_count, rb_node); -+ -+ if (qc->qgroupid < curr->qgroupid) -+ p = &(*p)->rb_left; -+ else if (qc->qgroupid > curr->qgroupid) -+ p = &(*p)->rb_right; -+ else -+ return EEXIST; -+ } -+ counts.num_groups++; -+ rb_link_node(&qc->rb_node, parent, p); -+ rb_insert_color(&qc->rb_node, &counts.root); -+ return 0; -+} -+ -+static struct qgroup_count *find_count(u64 qgroupid) -+{ -+ struct rb_node *n = counts.root.rb_node; -+ struct qgroup_count *count; -+ -+ while (n) { -+ count = rb_entry(n, struct qgroup_count, rb_node); -+ -+ if (qgroupid < count->qgroupid) -+ n = n->rb_left; -+ else if (qgroupid > count->qgroupid) -+ n = n->rb_right; -+ else -+ return count; -+ } -+ return NULL; -+} -+ -+static struct qgroup_count *alloc_count(struct btrfs_disk_key *key, -+ struct extent_buffer *leaf, -+ struct btrfs_qgroup_info_item *disk) -+{ -+ struct qgroup_count *c = calloc(1, sizeof(*c)); -+ struct btrfs_qgroup_info_item *item; -+ -+ if (c) { -+ c->qgroupid = btrfs_disk_key_offset(key); -+ c->key = *key; -+ -+ item = &c->diskinfo; -+ item->generation = btrfs_qgroup_info_generation(leaf, disk); -+ item->referenced = btrfs_qgroup_info_referenced(leaf, disk); -+ item->referenced_compressed = -+ btrfs_qgroup_info_referenced_compressed(leaf, disk); -+ item->exclusive = btrfs_qgroup_info_exclusive(leaf, disk); -+ item->exclusive_compressed = -+ btrfs_qgroup_info_exclusive_compressed(leaf, disk); -+ -+ if (insert_count(c)) { -+ free(c); -+ c = NULL; -+ } -+ } -+ return c; -+} -+ -+static void add_bytes(u64 root_objectid, u64 num_bytes, int exclusive) -+{ -+ struct qgroup_count *count = find_count(root_objectid); -+ struct btrfs_qgroup_info_item *qg; -+ -+ BUG_ON(num_bytes < 4096); /* Random sanity check. */ -+ -+ if (!count) -+ return; -+ -+ qg = &count->info; -+ -+ qg->referenced += num_bytes; -+ /* -+ * count of compressed bytes is unimplemented, so we do the -+ * same as kernel. -+ */ -+ qg->referenced_compressed += num_bytes; -+ -+ if (exclusive) { -+ qg->exclusive += num_bytes; -+ qg->exclusive_compressed += num_bytes; -+ } -+} -+ -+static int load_quota_info(struct btrfs_fs_info *info) -+{ -+ int ret; -+ struct btrfs_root *root = info->quota_root; -+ struct btrfs_path path; -+ struct btrfs_key key; -+ struct btrfs_disk_key disk_key; -+ struct extent_buffer *leaf; -+ struct btrfs_qgroup_info_item *item; -+ struct qgroup_count *count; -+ int i, nr; -+ -+ btrfs_init_path(&path); -+ -+ key.offset = 0; -+ key.objectid = 0; -+ key.type = 0; -+ -+ ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); -+ if (ret < 0) { -+ fprintf(stderr, "ERROR: Couldn't search slot: %d\n", ret); -+ goto out; -+ } -+ -+ while (1) { -+ leaf = path.nodes[0]; -+ -+ nr = btrfs_header_nritems(leaf); -+ for(i = 0; i < nr; i++) { -+ btrfs_item_key(leaf, &disk_key, i); -+ btrfs_disk_key_to_cpu(&key, &disk_key); -+ -+ if (key.type == BTRFS_QGROUP_RELATION_KEY) -+ printf("Ignoring qgroup relation key %llu\n", -+ key.objectid); -+ -+ /* -+ * Ignore: BTRFS_QGROUP_STATUS_KEY, -+ * BTRFS_QGROUP_LIMIT_KEY, BTRFS_QGROUP_RELATION_KEY -+ */ -+ if (key.type != BTRFS_QGROUP_INFO_KEY) -+ continue; -+ -+ item = btrfs_item_ptr(leaf, i, -+ struct btrfs_qgroup_info_item); -+ -+ count = alloc_count(&disk_key, leaf, item); -+ if (!count) { -+ ret = ENOMEM; -+ fprintf(stderr, "ERROR: out of memory\n"); -+ goto out; -+ } -+ } -+ -+ ret = btrfs_next_leaf(root, &path); -+ if (ret != 0) -+ break; -+ } -+ -+ ret = 0; -+ btrfs_release_path(&path); -+out: -+ return ret; -+} -+ -+static int add_inline_refs(struct btrfs_fs_info *info, -+ struct extent_buffer *ei_leaf, int slot, -+ u64 bytenr, u64 num_bytes, int meta_item) -+{ -+ struct btrfs_extent_item *ei; -+ struct btrfs_extent_inline_ref *iref; -+ struct btrfs_extent_data_ref *dref; -+ u64 flags, root_obj, offset, parent; -+ u32 item_size = btrfs_item_size_nr(ei_leaf, slot); -+ int type; -+ unsigned long end; -+ unsigned long ptr; -+ -+ ei = btrfs_item_ptr(ei_leaf, slot, struct btrfs_extent_item); -+ flags = btrfs_extent_flags(ei_leaf, ei); -+ -+ if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK && !meta_item) { -+ struct btrfs_tree_block_info *tbinfo; -+ tbinfo = (struct btrfs_tree_block_info *)(ei + 1); -+ iref = (struct btrfs_extent_inline_ref *)(tbinfo + 1); -+ } else { -+ iref = (struct btrfs_extent_inline_ref *)(ei + 1); -+ } -+ -+ ptr = (unsigned long)iref; -+ end = (unsigned long)ei + item_size; -+ while (ptr < end) { -+ iref = (struct btrfs_extent_inline_ref *)ptr; -+ -+ parent = root_obj = 0; -+ offset = btrfs_extent_inline_ref_offset(ei_leaf, iref); -+ type = btrfs_extent_inline_ref_type(ei_leaf, iref); -+ switch (type) { -+ case BTRFS_TREE_BLOCK_REF_KEY: -+ root_obj = offset; -+ break; -+ case BTRFS_EXTENT_DATA_REF_KEY: -+ dref = (struct btrfs_extent_data_ref *)(&iref->offset); -+ root_obj = btrfs_extent_data_ref_root(ei_leaf, dref); -+ break; -+ case BTRFS_SHARED_DATA_REF_KEY: -+ case BTRFS_SHARED_BLOCK_REF_KEY: -+ parent = offset; -+ break; -+ default: -+ return 1; -+ } -+ -+ if (alloc_ref(bytenr, root_obj, parent, num_bytes) == NULL) -+ return ENOMEM; -+ -+ ptr += btrfs_extent_inline_ref_size(type); -+ } -+ -+ return 0; -+} -+ -+static int add_keyed_ref(struct btrfs_fs_info *info, -+ struct btrfs_key *key, -+ struct extent_buffer *leaf, int slot, -+ u64 bytenr, u64 num_bytes) -+{ -+ u64 root_obj = 0, parent = 0; -+ struct btrfs_extent_data_ref *dref; -+ -+ switch(key->type) { -+ case BTRFS_TREE_BLOCK_REF_KEY: -+ root_obj = key->offset; -+ break; -+ case BTRFS_EXTENT_DATA_REF_KEY: -+ dref = btrfs_item_ptr(leaf, slot, struct btrfs_extent_data_ref); -+ root_obj = btrfs_extent_data_ref_root(leaf, dref); -+ break; -+ case BTRFS_SHARED_DATA_REF_KEY: -+ case BTRFS_SHARED_BLOCK_REF_KEY: -+ parent = key->offset; -+ break; -+ default: -+ return 1; -+ } -+ -+ if (alloc_ref(bytenr, root_obj, parent, num_bytes) == NULL) -+ return ENOMEM; -+ -+ return 0; -+} -+ -+/* -+ * return value of 0 indicates leaf or not meta data. The code that -+ * calls this does not need to make a distinction between the two as -+ * it is only concerned with intermediate blocks which will always -+ * have level > 0. -+ */ -+static int get_tree_block_level(struct btrfs_key *key, -+ struct extent_buffer *ei_leaf, -+ int slot) -+{ -+ int level = 0; -+ int meta_key = key->type == BTRFS_METADATA_ITEM_KEY; -+ u64 flags; -+ struct btrfs_extent_item *ei; -+ -+ ei = btrfs_item_ptr(ei_leaf, slot, struct btrfs_extent_item); -+ flags = btrfs_extent_flags(ei_leaf, ei); -+ -+ if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK && !meta_key) { -+ struct btrfs_tree_block_info *tbinfo; -+ tbinfo = (struct btrfs_tree_block_info *)(ei + 1); -+ level = btrfs_tree_block_level(ei_leaf, tbinfo); -+ } else if (meta_key) { -+ /* skinny metadata */ -+ level = (int)key->offset; -+ } -+ return level; -+} -+ -+/* -+ * Walk the extent tree, allocating a ref item for every ref and -+ * storing it in the bytenr tree. -+ */ -+static int scan_extents(struct btrfs_fs_info *info, -+ u64 start, u64 end) -+{ -+ int ret, i, nr, level; -+ struct btrfs_root *root = info->extent_root; -+ struct btrfs_key key; -+ struct btrfs_path path; -+ struct btrfs_disk_key disk_key; -+ struct extent_buffer *leaf; -+ u64 bytenr = 0, num_bytes = 0; -+ -+ btrfs_init_path(&path); -+ -+ key.objectid = start; -+ key.type = 0; -+ key.offset = 0; -+ -+ ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); -+ if (ret < 0) { -+ fprintf(stderr, "ERROR: Couldn't search slot: %d\n", ret); -+ goto out; -+ } -+ path.reada = 1; -+ -+ while (1) { -+ leaf = path.nodes[0]; -+ -+ nr = btrfs_header_nritems(leaf); -+ for(i = 0; i < nr; i++) { -+ btrfs_item_key(leaf, &disk_key, i); -+ btrfs_disk_key_to_cpu(&key, &disk_key); -+ -+ if (key.objectid < start) -+ continue; -+ -+ if (key.objectid > end) -+ goto done; -+ -+ if (key.type == BTRFS_EXTENT_ITEM_KEY || -+ key.type == BTRFS_METADATA_ITEM_KEY) { -+ int meta = 0; -+ -+ tot_extents_scanned++; -+ -+ bytenr = key.objectid; -+ num_bytes = key.offset; -+ if (key.type == BTRFS_METADATA_ITEM_KEY) { -+ num_bytes = info->extent_root->leafsize; -+ meta = 1; -+ } -+ -+ ret = add_inline_refs(info, leaf, i, bytenr, -+ num_bytes, meta); -+ if (ret) -+ goto out; -+ -+ level = get_tree_block_level(&key, leaf, i); -+ if (level) { -+ if (alloc_tree_block(bytenr, num_bytes, -+ level)) -+ return ENOMEM; -+ } -+ -+ continue; -+ } -+ -+ if (key.type > BTRFS_SHARED_DATA_REF_KEY) -+ continue; -+ if (key.type < BTRFS_TREE_BLOCK_REF_KEY) -+ continue; -+ -+ /* -+ * Keyed refs should come after their extent -+ * item in the tree. As a result, the value of -+ * bytenr and num_bytes should be unchanged -+ * from the above block that catches the -+ * original extent item. -+ */ -+ BUG_ON(key.objectid != bytenr); -+ -+ ret = add_keyed_ref(info, &key, leaf, i, bytenr, -+ num_bytes); -+ if (ret) -+ goto out; -+ } -+ -+ ret = btrfs_next_leaf(root, &path); -+ if (ret != 0) { -+ if (ret < 0) { -+ fprintf(stderr, -+ "ERROR: Next leaf failed: %d\n", ret); -+ goto out; -+ } -+ break; -+ } -+ } -+done: -+ ret = 0; -+out: -+ btrfs_release_path(&path); -+ -+ return ret; -+} -+ -+static void print_fields(u64 bytes, u64 bytes_compressed, char *prefix, -+ char *type) -+{ -+ printf("%s\t\t%s %llu %s compressed %llu\n", -+ prefix, type, (unsigned long long)bytes, type, -+ (unsigned long long)bytes_compressed); -+} -+ -+static void print_fields_signed(long long bytes, -+ long long bytes_compressed, -+ char *prefix, char *type) -+{ -+ printf("%s\t\t%s %lld %s compressed %lld\n", -+ prefix, type, bytes, type, bytes_compressed); -+} -+ -+static void print_qgroup_difference(struct qgroup_count *count, int verbose) -+{ -+ int is_different; -+ struct btrfs_qgroup_info_item *info = &count->info; -+ struct btrfs_qgroup_info_item *disk = &count->diskinfo; -+ long long excl_diff = info->exclusive - disk->exclusive; -+ long long ref_diff = info->referenced - disk->referenced; -+ -+ is_different = excl_diff || ref_diff; -+ -+ if (verbose || is_different) { -+ printf("Counts for qgroup id: %llu %s\n", -+ (unsigned long long)count->qgroupid, -+ is_different ? "are different" : ""); -+ -+ print_fields(info->referenced, info->referenced_compressed, -+ "our:", "referenced"); -+ print_fields(disk->referenced, disk->referenced_compressed, -+ "disk:", "referenced"); -+ if (ref_diff) -+ print_fields_signed(ref_diff, ref_diff, -+ "diff:", "referenced"); -+ print_fields(info->exclusive, info->exclusive_compressed, -+ "our:", "exclusive"); -+ print_fields(disk->exclusive, disk->exclusive_compressed, -+ "disk:", "exclusive"); -+ if (excl_diff) -+ print_fields_signed(excl_diff, excl_diff, -+ "diff:", "exclusive"); -+ } -+} -+ -+void print_qgroup_report(int all) -+{ -+ struct rb_node *node; -+ struct qgroup_count *c; -+ -+ node = rb_first(&counts.root); -+ while (node) { -+ c = rb_entry(node, struct qgroup_count, rb_node); -+ print_qgroup_difference(c, all); -+ node = rb_next(node); -+ } -+} -+ -+int qgroup_verify_all(struct btrfs_fs_info *info) -+{ -+ int ret; -+ -+ if (!info->quota_enabled) -+ return 0; -+ -+ tree_blocks = ulist_alloc(0); -+ if (!tree_blocks) { -+ fprintf(stderr, -+ "ERROR: Out of memory while allocating ulist.\n"); -+ return ENOMEM; -+ } -+ -+ ret = load_quota_info(info); -+ if (ret) { -+ fprintf(stderr, "ERROR: Loading qgroups from disk: %d\n", ret); -+ goto out; -+ } -+ -+ /* -+ * Put all extent refs into our rbtree -+ */ -+ ret = scan_extents(info, 0, ~0ULL); -+ if (ret) { -+ fprintf(stderr, "ERROR: while scanning extent tree: %d\n", ret); -+ goto out; -+ } -+ -+ ret = map_implied_refs(info); -+ if (ret) { -+ fprintf(stderr, "ERROR: while mapping refs: %d\n", ret); -+ goto out; -+ } -+ -+ account_all_refs(); -+ -+out: -+ /* -+ * Don't free the qgroup count records as they will be walked -+ * later via the print function. -+ */ -+ free_tree_blocks(); -+ free_ref_tree(&by_bytenr); -+ return ret; -+} -Index: btrfs-progs-v3.14.1/qgroup-verify.h -=================================================================== ---- /dev/null -+++ btrfs-progs-v3.14.1/qgroup-verify.h -@@ -0,0 +1,25 @@ -+/* -+ * Copyright (C) 2014 SUSE. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public -+ * License v2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this program; if not, write to the -+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, -+ * Boston, MA 021110-1307, USA. -+ */ -+ -+#ifndef _BTRFS_QGROUP_VERIFY_H -+#define _BTRFS_QGROUP_VERIFY_H -+ -+int qgroup_verify_all(struct btrfs_fs_info *info); -+void print_qgroup_report(int all); -+ -+#endif /* _BTRFS_QGROUP_VERIFY_H */ diff --git a/0203-btrfs-progs-show-extent-state-for-a-subvolume.patch b/0203-btrfs-progs-show-extent-state-for-a-subvolume.patch deleted file mode 100644 index 6071ebe..0000000 --- a/0203-btrfs-progs-show-extent-state-for-a-subvolume.patch +++ /dev/null @@ -1,235 +0,0 @@ -From 23356b0034431d5e809b370ee02375b25cd9ced8 Mon Sep 17 00:00:00 2001 -From: Mark Fasheh -Date: Sat, 31 May 2014 22:05:36 -0700 -Subject: [PATCH] btrfs-progs: show extent state for a subvolume -References: bnc#886493 bnc#865621 -Upstream: submitted - -The qgroup verification code can trivially be extended to provide -extended information on the extents which a subvolume root -references. Along with qgroup-verify, I have found this tool to be -invaluable when tracking down extent references. - -The patch adds a switch to the check subcommand '--subvol-extents' -which takes as args a single subvolume id. When run with the switch, -we'll print out each extent that the subvolume references. The extent -printout gives standard extent info you would expect along with -information on which other roots reference it. - -Sample output follows - this is a few lines from a run on a subvolume -I've been testing qgroup changes on: - -Print extent state for subvolume 281 on /dev/vdb2 -UUID: 8203ca66-9858-4e3f-b447-5bbaacf79c02 -Offset Len Root Refs Roots -12582912 20480 12 257 279 280 281 282 283 284 285 286 287 288 289 -12603392 8192 12 257 279 280 281 282 283 284 285 286 287 288 289 -12611584 12288 12 257 279 280 281 282 283 284 285 286 287 288 289 - -124583936 16384 4 281 282 283 280 -125075456 16384 4 280 281 282 283 -126255104 16384 11 257 280 281 282 283 284 285 286 287 288 289 -4763508736 4096 3 279 280 281 - -In case it wasn't clear, this applies on top of my qgroup verify patch: -"btrfs-progs: add quota group verify code" - -A branch with all this can be found on github: - -https://github.com/markfasheh/btrfs-progs-patches/tree/qgroup-verify - -Please apply, - -Signed-off-by: Mark Fasheh ---- - cmds-check.c | 12 +++++++++ - qgroup-verify.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- - qgroup-verify.h | 2 ++ - 3 files changed, 92 insertions(+), 3 deletions(-) - -diff --git a/cmds-check.c b/cmds-check.c -index 5401ad9..18d4341 100644 ---- a/cmds-check.c -+++ b/cmds-check.c -@@ -6428,6 +6428,7 @@ static struct option long_options[] = { - { "init-csum-tree", 0, NULL, 0 }, - { "init-extent-tree", 0, NULL, 0 }, - { "backup", 0, NULL, 0 }, -+ { "subvol-extents", 1, NULL, 'E' }, - { "qgroup-report", 0, NULL, 'Q' }, - { NULL, 0, NULL, 0} - }; -@@ -6442,6 +6443,7 @@ const char * const cmd_check_usage[] = { - "--init-csum-tree create a new CRC tree", - "--init-extent-tree create a new extent tree", - "--qgroup-report print a report on qgroup consistency", -+ "--subvol-extents print subvolume extents and sharing state", - NULL - }; - -@@ -6451,6 +6453,7 @@ int cmd_check(int argc, char **argv) - struct btrfs_root *root; - struct btrfs_fs_info *info; - u64 bytenr = 0; -+ u64 subvolid = 0; - char uuidbuf[BTRFS_UUID_UNPARSED_SIZE]; - int ret; - u64 num; -@@ -6486,6 +6489,9 @@ int cmd_check(int argc, char **argv) - case 'Q': - qgroup_report = 1; - break; -+ case 'E': -+ subvolid = arg_strtou64(optarg); -+ break; - case '?': - case 'h': - usage(cmd_check_usage); -@@ -6541,6 +6547,12 @@ int cmd_check(int argc, char **argv) - print_qgroup_report(1); - goto close_out; - } -+ if (subvolid) { -+ printf("Print extent state for subvolume %llu on %s\nUUID: %s\n", -+ subvolid, argv[optind], uuidbuf); -+ ret = print_extent_state(info, subvolid); -+ goto close_out; -+ } - printf("Checking filesystem on %s\nUUID: %s\n", argv[optind], uuidbuf); - - if (!extent_buffer_uptodate(info->tree_root->node) || -diff --git a/qgroup-verify.c b/qgroup-verify.c -index f7692f9..81a1651 100644 ---- a/qgroup-verify.c -+++ b/qgroup-verify.c -@@ -296,6 +296,8 @@ static void find_parent_roots(struct ulist *roots, u64 parent) - } while (node && ref->bytenr == parent); - } - -+static void print_subvol_info(u64 subvolid, u64 bytenr, u64 num_bytes, -+ struct ulist *roots); - /* - * Account each ref. Walk the refs, for each set of refs in a - * given bytenr: -@@ -308,7 +310,7 @@ static void find_parent_roots(struct ulist *roots, u64 parent) - * - Walk ref_roots ulist, adding extent bytes to each qgroup count that - * cooresponds to a found root. - */ --static void account_all_refs(void) -+static void account_all_refs(int do_qgroups, u64 search_subvol) - { - int exclusive; - struct ref *ref; -@@ -358,11 +360,15 @@ static void account_all_refs(void) - else - exclusive = 0; - -+ if (search_subvol) -+ print_subvol_info(search_subvol, bytenr, num_bytes, -+ roots); -+ - ULIST_ITER_INIT(&uiter); - while ((unode = ulist_next(roots, &uiter))) { - BUG_ON(unode->val == 0ULL); - /* We only want to account fs trees */ -- if (is_fstree(unode->val)) -+ if (is_fstree(unode->val) && do_qgroups) - add_bytes(unode->val, num_bytes, exclusive); - } - } -@@ -1072,7 +1078,7 @@ int qgroup_verify_all(struct btrfs_fs_info *info) - goto out; - } - -- account_all_refs(); -+ account_all_refs(1, 0); - - out: - /* -@@ -1083,3 +1089,72 @@ out: - free_ref_tree(&by_bytenr); - return ret; - } -+ -+static void __print_subvol_info(u64 bytenr, u64 num_bytes, struct ulist *roots) -+{ -+ int n = roots->nnodes; -+ struct ulist_iterator uiter; -+ struct ulist_node *unode; -+ -+ printf("%llu\t%llu\t%d\t", bytenr, num_bytes, n); -+ -+ ULIST_ITER_INIT(&uiter); -+ while ((unode = ulist_next(roots, &uiter))) { -+ printf("%llu ", unode->val); -+ } -+ printf("\n"); -+} -+ -+static void print_subvol_info(u64 subvolid, u64 bytenr, u64 num_bytes, -+ struct ulist *roots) -+{ -+ struct ulist_iterator uiter; -+ struct ulist_node *unode; -+ -+ ULIST_ITER_INIT(&uiter); -+ while ((unode = ulist_next(roots, &uiter))) { -+ BUG_ON(unode->val == 0ULL); -+ if (unode->val == subvolid) { -+ __print_subvol_info(bytenr, num_bytes, roots); -+ return; -+ } -+ } -+ -+ -+} -+ -+int print_extent_state(struct btrfs_fs_info *info, u64 subvol) -+{ -+ int ret; -+ -+ tree_blocks = ulist_alloc(0); -+ if (!tree_blocks) { -+ fprintf(stderr, -+ "ERROR: Out of memory while allocating ulist.\n"); -+ return ENOMEM; -+ } -+ -+ /* -+ * Put all extent refs into our rbtree -+ */ -+ ret = scan_extents(info, 0, ~0ULL); -+ if (ret) { -+ fprintf(stderr, "ERROR: while scanning extent tree: %d\n", ret); -+ goto out; -+ } -+ -+ ret = map_implied_refs(info); -+ if (ret) { -+ fprintf(stderr, "ERROR: while mapping refs: %d\n", ret); -+ goto out; -+ } -+ -+ printf("Offset\t\tLen\tRoot Refs\tRoots\n"); -+ account_all_refs(0, subvol); -+ -+out: -+ free_tree_blocks(); -+ free_ref_tree(&by_bytenr); -+ return ret; -+} -+ -diff --git a/qgroup-verify.h b/qgroup-verify.h -index a222c17..9201407 100644 ---- a/qgroup-verify.h -+++ b/qgroup-verify.h -@@ -22,4 +22,6 @@ - int qgroup_verify_all(struct btrfs_fs_info *info); - void print_qgroup_report(int all); - -+int print_extent_state(struct btrfs_fs_info *info, u64 subvol); -+ - #endif /* _BTRFS_QGROUP_VERIFY_H */ --- -1.8.4.5 - diff --git a/0204-btrfs-progs-ignore-orphaned-qgroups-by-default.patch b/0204-btrfs-progs-ignore-orphaned-qgroups-by-default.patch deleted file mode 100644 index bc94959..0000000 --- a/0204-btrfs-progs-ignore-orphaned-qgroups-by-default.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 049554016bb8007c39cebc9d855fea5e600a11a0 Mon Sep 17 00:00:00 2001 -From: Mark Fasheh -Date: Tue, 8 Jul 2014 13:34:18 -0700 -Subject: btrfs-progs: ignore orphaned qgroups by default -References: bnc#886493 bnc#865621 -Upstream: submitted - -qgroup items are not deleted by btrfs when the underlying subvolume goes -away. As a result, btrfsck will print those as inconsistent. This can -clutter up the printout so we ignore them by default. They are still printed -if a full report (via --qgroup-report) is requested. - -Signed-off-by: Mark Fasheh ---- - qgroup-verify.c | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/qgroup-verify.c b/qgroup-verify.c -index 81a1651..2e1716d 100644 ---- a/qgroup-verify.c -+++ b/qgroup-verify.c -@@ -38,6 +38,7 @@ static void add_bytes(u64 root_objectid, u64 num_bytes, int exclusive); - - struct qgroup_count { - u64 qgroupid; -+ int subvol_exists; - - struct btrfs_disk_key key; - struct btrfs_qgroup_info_item diskinfo; -@@ -697,8 +698,10 @@ static int load_quota_info(struct btrfs_fs_info *info) - { - int ret; - struct btrfs_root *root = info->quota_root; -+ struct btrfs_root *tmproot; - struct btrfs_path path; - struct btrfs_key key; -+ struct btrfs_key root_key; - struct btrfs_disk_key disk_key; - struct extent_buffer *leaf; - struct btrfs_qgroup_info_item *item; -@@ -745,6 +748,15 @@ static int load_quota_info(struct btrfs_fs_info *info) - fprintf(stderr, "ERROR: out of memory\n"); - goto out; - } -+ -+ root_key.objectid = key.offset; -+ root_key.type = BTRFS_ROOT_ITEM_KEY; -+ root_key.offset = (u64)-1; -+ tmproot = btrfs_read_fs_root_no_cache(info, &root_key); -+ if (tmproot && !IS_ERR(tmproot)) { -+ count->subvol_exists = 1; -+ free(tmproot); -+ } - } - - ret = btrfs_next_leaf(root, &path); -@@ -1008,7 +1020,7 @@ static void print_qgroup_difference(struct qgroup_count *count, int verbose) - - is_different = excl_diff || ref_diff; - -- if (verbose || is_different) { -+ if (verbose || (is_different && count->subvol_exists)) { - printf("Counts for qgroup id: %llu %s\n", - (unsigned long long)count->qgroupid, - is_different ? "are different" : ""); --- -1.8.4.5 - diff --git a/btrfs-progs-canonicalize-pathnames-for-device-commands b/btrfs-progs-canonicalize-pathnames-for-device-commands deleted file mode 100644 index 36884da..0000000 --- a/btrfs-progs-canonicalize-pathnames-for-device-commands +++ /dev/null @@ -1,292 +0,0 @@ -From: Jeff Mahoney -Subject: btrfs-progs: canonicalize pathnames for device commands -References: bnc#880486 -Patch-mainline: Submitted to linux-btrfs, 4 Jun 2014 - -mount(8) will canonicalize pathnames before passing them to the kernel. -Links to e.g. /dev/sda will be resolved to /dev/sda. Links to /dev/dm-# -will be resolved using the name of the device mapper table to -/dev/mapper/. - -Btrfs will use whatever name the user passes to it, regardless of whether -it is canonical or not. That means that if a 'btrfs device ready' is -issued on any device node pointing to the original device, it will adopt -the new name instead of the name that was used during mount. - -Mounting using /dev/sdb2 will result in df: -/dev/sdb2 209715200 39328 207577088 1% /mnt - -# ls -la /dev/whatever-i-like -lrwxrwxrwx 1 root root 4 Jun 4 13:36 /dev/whatever-i-like -> sdb2 -# btrfs dev ready /dev/whatever-i-like -# df /mnt -/dev/whatever-i-like 209715200 39328 207577088 1% /mnt - -Likewise, mounting with /dev/mapper/whatever and using /dev/dm-0 with a -btrfs device command results in df showing /dev/dm-0. This can happen with -multipath devices with friendly names enabled and doing something like -'partprobe' which (at least with our version) ends up issuing a 'change' -uevent on the sysfs node. That *always* uses the dm-# name, and we get -confused users. - -This patch does the same canonicalization of the paths that mount does -so that we don't end up having inconsistent names reported by ->show_devices -later. - -Signed-off-by: Jeff Mahoney ---- - cmds-device.c | 60 ++++++++++++++++++++++++++++++++++++++++++++------------- - cmds-replace.c | 13 ++++++++++-- - utils.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - utils.h | 2 + - 4 files changed, 117 insertions(+), 15 deletions(-) - ---- a/cmds-device.c -+++ b/cmds-device.c -@@ -95,6 +95,7 @@ static int cmd_add_dev(int argc, char ** - int devfd, res; - u64 dev_block_count = 0; - int mixed = 0; -+ char *path; - - res = test_dev_for_mkfs(argv[i], force, estr); - if (res) { -@@ -118,15 +119,24 @@ static int cmd_add_dev(int argc, char ** - goto error_out; - } - -- strncpy_null(ioctl_args.name, argv[i]); -+ path = canonicalize_path(argv[i]); -+ if (!path) { -+ fprintf(stderr, -+ "ERROR: Could not canonicalize pathname '%s': %s\n", -+ argv[i], strerror(errno)); -+ ret++; -+ goto error_out; -+ } -+ -+ strncpy_null(ioctl_args.name, path); - res = ioctl(fdmnt, BTRFS_IOC_ADD_DEV, &ioctl_args); - e = errno; -- if(res<0){ -+ if (res < 0) { - fprintf(stderr, "ERROR: error adding the device '%s' - %s\n", -- argv[i], strerror(e)); -+ path, strerror(e)); - ret++; - } -- -+ free(path); - } - - error_out: -@@ -242,6 +252,7 @@ static int cmd_scan_dev(int argc, char * - - for( i = devstart ; i < argc ; i++ ){ - struct btrfs_ioctl_vol_args args; -+ char *path; - - if (!is_block_device(argv[i])) { - fprintf(stderr, -@@ -249,9 +260,17 @@ static int cmd_scan_dev(int argc, char * - ret = 1; - goto close_out; - } -- printf("Scanning for Btrfs filesystems in '%s'\n", argv[i]); -+ path = canonicalize_path(argv[i]); -+ if (!path) { -+ fprintf(stderr, -+ "ERROR: Could not canonicalize path '%s': %s\n", -+ argv[i], strerror(errno)); -+ ret = 1; -+ goto close_out; -+ } -+ printf("Scanning for Btrfs filesystems in '%s'\n", path); - -- strncpy_null(args.name, argv[i]); -+ strncpy_null(args.name, path); - /* - * FIXME: which are the error code returned by this ioctl ? - * it seems that is impossible to understand if there no is -@@ -262,9 +281,11 @@ static int cmd_scan_dev(int argc, char * - - if( ret < 0 ){ - fprintf(stderr, "ERROR: unable to scan the device '%s' - %s\n", -- argv[i], strerror(e)); -+ path, strerror(e)); -+ free(path); - goto close_out; - } -+ free(path); - } - - close_out: -@@ -284,6 +305,7 @@ static int cmd_ready_dev(int argc, char - struct btrfs_ioctl_vol_args args; - int fd; - int ret; -+ char *path; - - if (check_argc_min(argc, 2)) - usage(cmd_ready_dev_usage); -@@ -293,22 +315,34 @@ static int cmd_ready_dev(int argc, char - perror("failed to open /dev/btrfs-control"); - return 1; - } -- if (!is_block_device(argv[1])) { -+ -+ path = canonicalize_path(argv[argc - 1]); -+ if (!path) { - fprintf(stderr, -- "ERROR: %s is not a block device\n", argv[1]); -- close(fd); -- return 1; -+ "ERROR: Could not canonicalize pathname '%s': %s\n", -+ argv[argc - 1], strerror(errno)); -+ ret = 1; -+ goto out; - } - -- strncpy(args.name, argv[argc - 1], BTRFS_PATH_NAME_MAX); -+ if (!is_block_device(path)) { -+ fprintf(stderr, -+ "ERROR: %s is not a block device\n", path); -+ ret = 1; -+ goto out; -+ } -+ -+ strncpy(args.name, path, BTRFS_PATH_NAME_MAX); - ret = ioctl(fd, BTRFS_IOC_DEVICES_READY, &args); - if (ret < 0) { - fprintf(stderr, "ERROR: unable to determine if the device '%s'" -- " is ready for mounting - %s\n", argv[argc - 1], -+ " is ready for mounting - %s\n", path, - strerror(errno)); - ret = 1; - } - -+out: -+ free(path); - close(fd); - return ret; - } ---- a/cmds-replace.c -+++ b/cmds-replace.c -@@ -134,7 +134,7 @@ static int cmd_start_replace(int argc, c - int fddstdev = -1; - char *path; - char *srcdev; -- char *dstdev; -+ char *dstdev = NULL; - int avoid_reading_from_srcdev = 0; - int force_using_targetdev = 0; - struct stat st; -@@ -204,7 +204,12 @@ static int cmd_start_replace(int argc, c - } - - srcdev = argv[optind]; -- dstdev = argv[optind + 1]; -+ dstdev = canonicalize_path(argv[optind + 1]); -+ if (!dstdev) { -+ fprintf(stderr, -+ "ERROR: Could not canonicalize path '%s': %s\n", -+ argv[optind + 1], strerror(errno)); -+ } - - if (is_numerical(srcdev)) { - struct btrfs_ioctl_fs_info_args fi_args; -@@ -278,6 +283,8 @@ static int cmd_start_replace(int argc, c - - close(fddstdev); - fddstdev = -1; -+ free(dstdev); -+ dstdev = NULL; - - dev_replace_handle_sigint(fdmnt); - if (!do_not_background) { -@@ -312,6 +319,8 @@ static int cmd_start_replace(int argc, c - return 0; - - leave_with_error: -+ if (dstdev) -+ free(dstdev); - if (fdmnt != -1) - close(fdmnt); - if (fdsrcdev != -1) ---- a/utils.c -+++ b/utils.c -@@ -987,6 +987,63 @@ static int blk_file_in_dev_list(struct b - } - - /* -+ * Resolve a pathname to a device mapper node to /dev/mapper/ -+ * Returns NULL on invalid input or malloc failure; Other failures -+ * will be handled by the caller using the input pathame. -+ */ -+char *canonicalize_dm_name(const char *ptname) -+{ -+ FILE *f; -+ size_t sz; -+ char path[256], name[256], *res = NULL; -+ -+ if (!ptname || !*ptname) -+ return NULL; -+ -+ snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname); -+ if (!(f = fopen(path, "r"))) -+ return NULL; -+ -+ /* read \n from sysfs */ -+ if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) { -+ name[sz - 1] = '\0'; -+ snprintf(path, sizeof(path), "/dev/mapper/%s", name); -+ -+ if (access(path, F_OK) == 0) -+ res = strdup(path); -+ } -+ fclose(f); -+ return res; -+} -+ -+/* -+ * Resolve a pathname to a canonical device node, e.g. /dev/sda1 or -+ * to a device mapper pathname. -+ * Returns NULL on invalid input or malloc failure; Other failures -+ * will be handled by the caller using the input pathame. -+ */ -+char *canonicalize_path(const char *path) -+{ -+ char *canonical, *p; -+ -+ if (!path || !*path) -+ return NULL; -+ -+ canonical = realpath(path, NULL); -+ if (!canonical) -+ return strdup(path); -+ p = strrchr(canonical, '/'); -+ if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) { -+ char *dm = canonicalize_dm_name(p + 1); -+ if (dm) { -+ free(canonical); -+ return dm; -+ } -+ } -+ return canonical; -+} -+ -+/* - * returns 1 if the device was mounted, < 0 on error or 0 if everything - * is safe to continue. - */ ---- a/utils.h -+++ b/utils.h -@@ -61,6 +61,8 @@ int btrfs_add_to_fsid(struct btrfs_trans - int btrfs_scan_for_fsid(int run_ioctls); - void btrfs_register_one_device(char *fname); - int btrfs_scan_one_dir(char *dirname, int run_ioctl); -+char *canonicalize_dm_name(const char *ptname); -+char *canonicalize_path(const char *path); - int check_mounted(const char *devicename); - int check_mounted_where(int fd, const char *file, char *where, int size, - struct btrfs_fs_devices **fs_devices_mnt); diff --git a/btrfs-progs-v3.14.2.tar.bz2 b/btrfs-progs-v3.14.2.tar.bz2 deleted file mode 100644 index f6ed8b8..0000000 --- a/btrfs-progs-v3.14.2.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ed0530d52ca779c3453ac46fbeb64c59b5500ad909eef0837205aa1796fe880a -size 284230 diff --git a/btrfs-progs-v3.16.tar.gz b/btrfs-progs-v3.16.tar.gz new file mode 100644 index 0000000..43f6683 --- /dev/null +++ b/btrfs-progs-v3.16.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd4f31715ef3767f5061655ed1c7c5a4ca808f9aa331627874dad666017eae57 +size 387600 diff --git a/btrfsprogs.changes b/btrfsprogs.changes index 6d36e69..ef63bee 100644 --- a/btrfsprogs.changes +++ b/btrfsprogs.changes @@ -1,3 +1,58 @@ +------------------------------------------------------------------- +Fri Sep 5 15:02:39 CEST 2014 - dsterba@suse.cz + +- send-stream API users updatd, drop the workaround +- Removed patch: send-stream-api-wokaround.patch + +------------------------------------------------------------------- +Mon Sep 1 14:07:53 CEST 2014 - dsterba@suse.cz + +- workaround for send api breakage +- Added patch: send-stream-api-wokaround.patch + +------------------------------------------------------------------- +Wed Aug 27 17:23:48 CEST 2014 - dsterba@suse.cz + +- add api versioning and package version.h (now 0.1.1) +- Added patches: + * library-version-defines.patch + +------------------------------------------------------------------- +Tue Aug 26 20:13:21 CEST 2014 - dsterba@suse.cz + +- version 3.16 + - show-super: skip unrecognized sb, add option to force + - debug-tree: print tree by id + - mkfs: new option to specify UUID + - receive: new option to limit number of errors + - check: new option to verify quotas + - check: reduced memory requirements + - check: new option to print extent sharing + - restore: check length before decompression + - restore: more error handling + - balance: new filter 'limit' + - recover: allow to read all sb copies + - restore: option to loop during restoring + - mkfs: drop experimental notice + - btrfstune: new option to force dangerous changes + - documentation updates + +- Deleted patches (upstream): + * 0001-btrfs-progs-doc-fix-symlink-target-for-btrfsck.8.patch + * 0200-btrfs-progs-print-qgroup-excl-as-unsigned.patch + * 0201-btrfs-progs-import-ulist.patch + * 0202-btrfs-progs-add-quota-group-verify-code.patch + * 0203-btrfs-progs-show-extent-state-for-a-subvolume.patch + * 0204-btrfs-progs-ignore-orphaned-qgroups-by-default.patch + * btrfs-progs-canonicalize-pathnames-for-device-commands +- Refreshed patches: + * 0006-Btrfs-progs-fsck-clear-out-log-tree-in-repair-mode.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 + * 0028-btrfs-progs-extend-pretty-printers-with-unit-mode.patch + * 0164-btrfs-progs-convert-set-label-or-copy-from-origin.patch + ------------------------------------------------------------------- Wed Jul 9 18:08:37 UTC 2014 - mfasheh@suse.com diff --git a/btrfsprogs.spec b/btrfsprogs.spec index 5ee9ab4..f92589b 100644 --- a/btrfsprogs.spec +++ b/btrfsprogs.spec @@ -16,9 +16,9 @@ # -%define tar_version v3.14.2 +%define tar_version v3.16 Name: btrfsprogs -Version: 3.14.2 +Version: 3.16 Release: 0 Summary: Utilities for the Btrfs filesystem License: GPL-2.0 @@ -26,12 +26,10 @@ Group: System/Filesystems Url: http://btrfs.wiki.kernel.org/index.php/Main_Page #Git-Web: http://git.kernel.org/cgit/linux/kernel/git/mason/btrfs-progs.git #Git-Clone: git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-progs -# git archive --format=tar --prefix=btrfs-progs-`git describe --tags --match "v*"`/ HEAD > %D/btrfs-progs-`git describe --tags --match "v*"`.tar -Source: btrfs-progs-%{tar_version}.tar.bz2 +Source: https://www.kernel.org/pub/linux/kernel/people/mason/btrfs-progs/btrfs-progs-%{tar_version}.tar.gz Source1: boot-btrfs.sh Source4: setup-btrfs.sh -Patch1: 0001-btrfs-progs-doc-fix-symlink-target-for-btrfsck.8.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 @@ -63,15 +61,10 @@ Patch167: 0167-Btrfs-progs-make-find_and_setup_root-return-an-error.patch Patch168: 0168-Btrfs-progs-don-t-bug-out-if-we-can-t-find-the-last-.patch Patch169: 0169-btrfs-progs-Check-metadata-mirrors-in-find-root.patch Patch171: 0171-btrfs-progs-make-free-space-checker-work-on-non-4k-s.patch -Patch172: btrfs-progs-canonicalize-pathnames-for-device-commands - -Patch200: 0200-btrfs-progs-print-qgroup-excl-as-unsigned.patch -Patch201: 0201-btrfs-progs-import-ulist.patch -Patch202: 0202-btrfs-progs-add-quota-group-verify-code.patch -Patch203: 0203-btrfs-progs-show-extent-state-for-a-subvolume.patch -Patch204: 0204-btrfs-progs-ignore-orphaned-qgroups-by-default.patch Patch1000: local-version-override.patch +Patch1001: library-version-defines.patch + BuildRequires: asciidoc BuildRequires: libacl-devel BuildRequires: libattr-devel @@ -108,7 +101,6 @@ build applications to interface with btrfs. %prep %setup -q -n btrfs-progs-%{tar_version} -%patch1 -p1 %patch6 -p1 %patch7 -p1 %patch8 -p1 @@ -139,13 +131,8 @@ build applications to interface with btrfs. %patch168 -p1 %patch169 -p1 %patch171 -p1 -%patch172 -p1 -%patch200 -p1 -%patch201 -p1 -%patch202 -p1 -%patch203 -p1 -%patch204 -p1 %patch1000 -p1 +%patch1001 -p1 %build make %{?_smp_mflags} CFLAGS="%{optflags}" all btrfs-convert \ @@ -157,13 +144,12 @@ install -m 0755 -d %{buildroot}/%{_sbindir} install -m 0755 -d %{buildroot}/%{_bindir} # move some utilities out of /usr/sbin mv %{buildroot}/%{_sbindir}/btrfs-map-logical %{buildroot}/%{_bindir} -# mkinitrd rescue utilities +# initrd rescue utilities install -m 0755 btrfs-zero-log %{buildroot}/%{_sbindir} install -m 0755 btrfs-select-super %{buildroot}/%{_sbindir} install -m 0755 btrfs-image %{buildroot}/%{_sbindir} install -m 0755 btrfstune %{buildroot}/%{_sbindir} install -m 0755 btrfs-find-root %{buildroot}/%{_sbindir} -#UsrMerge install -m 0755 -d %{buildroot}/sbin ln -s %{_sbindir}/btrfs %{buildroot}/sbin ln -s %{_sbindir}/btrfs-zero-log %{buildroot}/sbin @@ -177,9 +163,6 @@ ln -s %{_sbindir}/btrfs-debug-tree %{buildroot}/sbin ln -s %{_sbindir}/btrfs-show-super %{buildroot}/sbin ln -s %{_sbindir}/mkfs.btrfs %{buildroot}/sbin ln -s %{_sbindir}/fsck.btrfs %{buildroot}/sbin -#EndUsrMerge -#UsrMerge -#EndUsrMerge install -d -m0755 %{buildroot}/lib/mkinitrd/scripts/ install -m 0755 %{SOURCE1} %{buildroot}/lib/mkinitrd/scripts/ install -m 0755 %{SOURCE4} %{buildroot}/lib/mkinitrd/scripts/ @@ -206,7 +189,6 @@ done %defattr(-, root, root) /sbin/fsck.btrfs # mkinitrd utils -#UsrMerge /sbin/btrfs /sbin/btrfs-zero-log /sbin/btrfs-convert @@ -216,7 +198,6 @@ done /sbin/mkfs.btrfs /sbin/btrfs-debug-tree /sbin/btrfs-show-super -#EndUsrMerge %{_sbindir}/btrfs %{_sbindir}/btrfs-zero-log %{_sbindir}/btrfs-convert @@ -231,13 +212,13 @@ done %dir /lib/mkinitrd/scripts /lib/mkinitrd/scripts/boot-btrfs.sh /lib/mkinitrd/scripts/setup-btrfs.sh -# other %{_bindir}/btrfs-map-logical %{_mandir}/man8/btrfs-image.8.gz %{_mandir}/man8/btrfsck.8.gz %{_mandir}/man8/fsck.btrfs.8.gz %{_mandir}/man8/mkfs.btrfs.8.gz %{_mandir}/man8/btrfs.8.gz +%{_mandir}/man5/btrfs.5.gz %{_mandir}/man8/btrfs-convert.8.gz %{_mandir}/man8/btrfs-debug-tree.8.gz %{_mandir}/man8/btrfs-map-logical.8.gz diff --git a/library-version-defines.patch b/library-version-defines.patch new file mode 100644 index 0000000..b892158 --- /dev/null +++ b/library-version-defines.patch @@ -0,0 +1,90 @@ +From f412157fd429eab3d309602de214639a8c8c584e Mon Sep 17 00:00:00 2001 +From: Arvin Schnell +Date: Mon, 3 Jun 2013 14:31:41 +0200 +Subject: [PATCH] btrfs-progs: library version defines + +commit 46de1a6ec3dbb0db203baa6c46cb64ba9b000ea2 changed the +parameters of btrfs_read_and_process_send_stream(). This breaks +snapper compilation. We can include version defines usable for the C +preprocessor. + +Version 0.1.0: API up to and including 46de1a6ec3dbb0db2 (3.14.x) + +Version 0.1.1: 909131939f750faffb9fab (changed in 3.16) + +Signed-off-by: Arvin Schnell +Signed-off-by: David Sterba +--- + Makefile | 2 +- + send-stream.h | 5 +++++ + version.sh | 17 ++++++++++++++++- + 3 files changed, 22 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index e721e99c8319..73ef386896bf 100644 +--- a/Makefile ++++ b/Makefile +@@ -20,7 +20,7 @@ libbtrfs_objects = send-stream.o send-utils.o rbtree.o btrfs-list.o crc32c.o \ + uuid-tree.o utils-lib.o + libbtrfs_headers = send-stream.h send-utils.h send.h rbtree.h btrfs-list.h \ + crc32c.h list.h kerncompat.h radix-tree.h extent-cache.h \ +- extent_io.h ioctl.h ctree.h btrfsck.h ++ extent_io.h ioctl.h ctree.h btrfsck.h version.h + TESTS = fsck-tests.sh convert-tests.sh + + INSTALL = install +diff --git a/send-stream.h b/send-stream.h +index 293bf6af3659..bedff4d0422c 100644 +--- a/send-stream.h ++++ b/send-stream.h +@@ -18,6 +18,11 @@ + #ifndef SEND_STREAM_H_ + #define SEND_STREAM_H_ + ++/* ++ * NOTE: this file is public API, any incompatible change has to update ++ * library version ++ */ ++ + #ifdef __cplusplus + extern "C" { + #endif +diff --git a/version.sh b/version.sh +index 90000019fe1d..2e4a8d9e1303 100644 +--- a/version.sh ++++ b/version.sh +@@ -8,6 +8,10 @@ + + v="v3.16" + ++lib_major=0 ++lib_minor=1 ++lib_patchlevel=1 ++ + which git &> /dev/null + if [ $? == 0 -a -d .git ]; then + if head=`git rev-parse --verify HEAD 2>/dev/null`; then +@@ -24,8 +28,19 @@ if [ $? == 0 -a -d .git ]; then + fi + fi + +-echo "#ifndef __BUILD_VERSION" > .build-version.h ++echo "/* NOTE: this file is autogenerated by version.sh, do not edit */" > .build-version.h ++echo "#ifndef __BUILD_VERSION" >> .build-version.h ++echo >> .build-version.h + echo "#define __BUILD_VERSION" >> .build-version.h ++echo >> .build-version.h ++echo "#define BTRFS_LIB_MAJOR $lib_major" >> .build-version.h ++echo "#define BTRFS_LIB_MINOR $lib_minor" >> .build-version.h ++echo "#define BTRFS_LIB_PATCHLEVEL $lib_patchlevel" >> .build-version.h ++echo >> .build-version.h ++echo "#define BTRFS_LIB_VERSION ( BTRFS_LIB_MAJOR * 10000 + \\" >> .build-version.h ++echo " BTRFS_LIB_MINOR * 100 + \\" >> .build-version.h ++echo " BTRFS_LIB_PATCHLEVEL )" >> .build-version.h ++echo >> .build-version.h + echo "#define BTRFS_BUILD_VERSION \"Btrfs $v\"" >> .build-version.h + echo "#endif" >> .build-version.h + +-- +1.9.0 + diff --git a/local-version-override.patch b/local-version-override.patch index b569cb6..40ee0ca 100644 --- a/local-version-override.patch +++ b/local-version-override.patch @@ -6,8 +6,8 @@ Index: btrfs-progs-v0.19-116-g13eced9/version.sh # Copyright 2008, Oracle # Released under the GNU GPLv2 --v="v3.14.2" -+v="v3.14.2+20140530" +-v="v3.16" ++v="v3.16" which git &> /dev/null if [ $? == 0 -a -d .git ]; then