Hello community,
here is the log from the commit of package btrfsprogs for openSUSE:12.1:Update:Test checked in at 2011-12-19 17:26:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:12.1:Update:Test/btrfsprogs (Old)
and /work/SRC/openSUSE:12.1:Update:Test/.btrfsprogs.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "btrfsprogs", Maintainer is "MFasheh@suse.com"
Changes:
--------
--- /work/SRC/openSUSE:12.1:Update:Test/btrfsprogs/btrfsprogs.changes 2011-12-04 18:20:00.000000000 +0100
+++ /work/SRC/openSUSE:12.1:Update:Test/.btrfsprogs.new/btrfsprogs.changes 2011-12-19 17:26:49.000000000 +0100
@@ -1,0 +2,32 @@
+Mon Dec 12 15:44:48 CET 2011 - dkukawka@suse.de
+
+- btrfs-progs-fix-open_ctree_usage_segfaults.patch: fix
+ segfaults from bnc#710486 due to unchecked usage of return
+ value of open_ctree()
+ [fixed compilation warnings]
+
+-------------------------------------------------------------------
+Mon Dec 12 14:50:07 CET 2011 - dsterba@suse.cz
+
+- pull upstream, replace existing patches, spec update
+- update 'restore' utility
+ - lzo support
+ - tools may now take earlies superblock when opening the fs
+ - other fixes
+- pull integration-20111030 branch
+ - mkfs: force mkfs if desired
+ - other fixes
+- add btrfs-dump-super to mkinitrd
+- other fixes
+ - skip non-existent devices or without media
+ - documentation updates
+ - scrubbing single device
+ - graceful error handling when opening fs fails
+
+-------------------------------------------------------------------
+Fri Dec 9 00:43:08 CET 2011 - dsterba@suse.cz
+
+- updated mkinitrd script to scan devices before mount (bnc#727383)
+
+-------------------------------------------------------------------
+
Old:
----
0001-Plug-Memory-leak-in-find_and_setup_log_root.patch
btrfs-progs-pass-correct-build-option-for-pthreads.patch
btrfs-progs-v0.19-116-g13eced9.tar.bz2
btrfsck-ignore-option-a.diff
build-extra-progs.diff
ignore-deleted-loopmounts.diff
New:
----
0100-btrfs-progs-ignore-a-option-in-mkfs.patch
0102-Add-the-force-option.patch
0103-mkfs.btrfs-man-page-document-the-force-option.patch
0104-Ignore-the-error-ENXIO-and-ENOMEDIUM-during-a-devs-s.patch
0105-Regression-tests.patch
0106-Fix-sub-snap-parameter-handling.patch
0107-Add-info-for-the-commands.patch
0108-Add-the-header-footer-introduction-of-the-man-page.patch
0109-helpextract-tool-to-extract-the-info-for-the-help-fr.patch
0110-Update-the-makefile-for-generating-the-man-page.patch
0111-Show-the-help-messages-from-the-info-in-the-comment.patch
0112-Update-the-makefile-for-generating-the-help-messages.patch
0113-Btrfs-progs-add-restriper-commands.patch
0114-btrfs-progs-add-qgroup-commands.patch
0115-btrfs-progs-fixup-is_mounted-checks.patch
0116-Btrfs-progs-add-an-option-for-specifying-the-root-to.patch
0117-Btrfs-progs-try-other-mirrors-if-decomression-fails.patch
0118-Btrfs-progs-try-other-mirrors-on-read-failure.patch
0119-btrfs-progs-Fix-error-handling-for-failed-reads-in-r.patch
0120-btrfs-progs-Check-metadata-mirrors-in-find-root.patch
0121-restore-Split-output-directory-and-btrfs-local-path-.patch
0122-restore-Add-regex-matching-of-paths-and-files-to-be-.patch
0123-btrfs-progs-In-find-root-dump-bytenr-for-every-slot.patch
0124-btrfs-progs-Add-utility-to-dump-all-superblocks-foun.patch
0125-btrfs-progs-Add-the-ability-to-use-the-earliest-supe.patch
0126-btrfs-progs-Use-oldest-super-for-btrfs-select-super..patch
0127-btrfs-progs-add-lzo-compression-support-to-restore.patch
0128-btrfs-progs-fix-regexec-to-only-work-if-we-actually-.patch
0129-btrfs-progs-Fix-compilation-errors-with-btrfs-select.patch
0130-Btrfs-progs-fix-restore-to-fall-back-to-the-broken-o.patch
0131-Btrfs-progs-don-t-bug-out-if-we-can-t-find-the-last-.patch
0132-Btrfs-progs-make-find_and_setup_root-return-an-error.patch
0133-Btrfs-progs-check-return-value-properly.patch
0134-Btrfs-progs-give-restore-a-list-roots-option.patch
0135-Btrfs-progs-fix-compiler-warning-of-extent-tree.c.patch
0136-Btrfs-progs-change-the-way-mkfs-picks-raid-profiles.patch
0137-Btrfs-progs-fail-gracefully-on-error-from-open_ctree.patch
0138-Btrfs-progs-bugfix-for-scrubbing-single-devices.patch
0900-Revert-btrfs-progs-add-qgroup-commands.patch
0901-Revert-Btrfs-progs-add-restriper-commands.patch
Plug-Memory-leak-in-find_and_setup_log_root.patch
btrfs-progs-fix-open_ctree_usage_segfaults.patch
btrfs-progs-v0.19-118-gfdb6c04.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ btrfsprogs.spec ++++++
--- /var/tmp/diff_new_pack.gc4Frh/_old 2011-12-19 17:26:50.000000000 +0100
+++ /var/tmp/diff_new_pack.gc4Frh/_new 2011-12-19 17:26:50.000000000 +0100
@@ -21,24 +21,69 @@
Url: http://btrfs.wiki.kernel.org/index.php/Main_Page
Version: 0.19
Release: 50
-%define tar_version v0.19-116-g13eced9
+%define tar_version v0.19-118-gfdb6c04
Summary: Utilities for the Btrfs filesystem
License: GPL v2 only
Group: System/Filesystems
Supplements: filesystem(btrfs)
+# git archive --format=tar --prefix=btrfs-progs-`git describe`/ HEAD > %D/btrfs-progs-`git describe`.tar
Source: btrfs-progs-%{tar_version}.tar.bz2
Source1: boot-btrfs.sh
Patch0: memleak-fix.diff
-Patch1: 0001-Plug-Memory-leak-in-find_and_setup_log_root.patch
+Patch1: Plug-Memory-leak-in-find_and_setup_log_root.patch
Patch1000: local-version-override.patch
-Patch57: ignore-deleted-loopmounts.diff
-Patch58: btrfsck-ignore-option-a.diff
-Patch59: build-extra-progs.diff
-Patch60: btrfs-progs-pass-correct-build-option-for-pthreads.patch
+# patches above upstream master:
+# + hugo's integration
+Patch100: 0100-btrfs-progs-ignore-a-option-in-mkfs.patch
+Patch102: 0102-Add-the-force-option.patch
+Patch103: 0103-mkfs.btrfs-man-page-document-the-force-option.patch
+Patch104: 0104-Ignore-the-error-ENXIO-and-ENOMEDIUM-during-a-devs-s.patch
+Patch105: 0105-Regression-tests.patch
+Patch106: 0106-Fix-sub-snap-parameter-handling.patch
+Patch107: 0107-Add-info-for-the-commands.patch
+Patch108: 0108-Add-the-header-footer-introduction-of-the-man-page.patch
+Patch109: 0109-helpextract-tool-to-extract-the-info-for-the-help-fr.patch
+Patch110: 0110-Update-the-makefile-for-generating-the-man-page.patch
+Patch111: 0111-Show-the-help-messages-from-the-info-in-the-comment.patch
+Patch112: 0112-Update-the-makefile-for-generating-the-help-messages.patch
+Patch113: 0113-Btrfs-progs-add-restriper-commands.patch
+Patch114: 0114-btrfs-progs-add-qgroup-commands.patch
+Patch115: 0115-btrfs-progs-fixup-is_mounted-checks.patch
+# + josef's restore utility fixes
+Patch116: 0116-Btrfs-progs-add-an-option-for-specifying-the-root-to.patch
+Patch117: 0117-Btrfs-progs-try-other-mirrors-if-decomression-fails.patch
+Patch118: 0118-Btrfs-progs-try-other-mirrors-on-read-failure.patch
+Patch119: 0119-btrfs-progs-Fix-error-handling-for-failed-reads-in-r.patch
+Patch120: 0120-btrfs-progs-Check-metadata-mirrors-in-find-root.patch
+Patch121: 0121-restore-Split-output-directory-and-btrfs-local-path-.patch
+Patch122: 0122-restore-Add-regex-matching-of-paths-and-files-to-be-.patch
+Patch123: 0123-btrfs-progs-In-find-root-dump-bytenr-for-every-slot.patch
+Patch124: 0124-btrfs-progs-Add-utility-to-dump-all-superblocks-foun.patch
+Patch125: 0125-btrfs-progs-Add-the-ability-to-use-the-earliest-supe.patch
+Patch126: 0126-btrfs-progs-Use-oldest-super-for-btrfs-select-super..patch
+Patch127: 0127-btrfs-progs-add-lzo-compression-support-to-restore.patch
+Patch128: 0128-btrfs-progs-fix-regexec-to-only-work-if-we-actually-.patch
+Patch129: 0129-btrfs-progs-Fix-compilation-errors-with-btrfs-select.patch
+Patch130: 0130-Btrfs-progs-fix-restore-to-fall-back-to-the-broken-o.patch
+Patch131: 0131-Btrfs-progs-don-t-bug-out-if-we-can-t-find-the-last-.patch
+Patch132: 0132-Btrfs-progs-make-find_and_setup_root-return-an-error.patch
+Patch133: 0133-Btrfs-progs-check-return-value-properly.patch
+Patch134: 0134-Btrfs-progs-give-restore-a-list-roots-option.patch
+Patch135: 0135-Btrfs-progs-fix-compiler-warning-of-extent-tree.c.patch
+Patch136: 0136-Btrfs-progs-change-the-way-mkfs-picks-raid-profiles.patch
+Patch137: 0137-Btrfs-progs-fail-gracefully-on-error-from-open_ctree.patch
+Patch138: 0138-Btrfs-progs-bugfix-for-scrubbing-single-devices.patch
+
+#
+Patch150: btrfs-progs-fix-open_ctree_usage_segfaults.patch
+
+# - missing kernel features: qgroups
+Patch900: 0900-Revert-btrfs-progs-add-qgroup-commands.patch
+Patch901: 0901-Revert-Btrfs-progs-add-restriper-commands.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
-BuildRequires: libacl-devel libext2fs-devel libuuid-devel zlib-devel
+BuildRequires: libacl-devel libext2fs-devel libuuid-devel lzo-devel zlib-devel
# for /bin/true
Requires: coreutils
@@ -50,28 +95,72 @@
%patch0
%patch1 -p1
%patch1000 -p1
-%patch57 -p1
-%patch58 -p1
-%patch59 -p0
-%patch60 -p1
+%patch100 -p1
+%patch102 -p1
+%patch103 -p1
+%patch104 -p1
+%patch105 -p1
+%patch106 -p1
+%patch107 -p1
+%patch108 -p1
+%patch109 -p1
+%patch110 -p1
+%patch111 -p1
+%patch112 -p1
+%patch113 -p1
+%patch114 -p1
+%patch115 -p1
+%patch116 -p1
+%patch117 -p1
+%patch118 -p1
+%patch119 -p1
+%patch120 -p1
+%patch121 -p1
+%patch122 -p1
+%patch123 -p1
+%patch124 -p1
+%patch125 -p1
+%patch126 -p1
+%patch127 -p1
+%patch128 -p1
+%patch129 -p1
+%patch130 -p1
+%patch131 -p1
+%patch132 -p1
+%patch133 -p1
+%patch134 -p1
+%patch135 -p1
+%patch136 -p1
+%patch137 -p1
+%patch138 -p1
+%patch150 -p1
+%patch900 -p1
+%patch901 -p1
%build
make %{?_smp_mflags} CFLAGS="%{optflags}" all convert \
btrfs-zero-log btrfs-select-super btrfs-image btrfstune \
- restore find-root
-mv restore btrfs-restore
-mv find-root btrfs-find-root
+ restore find-root btrfs-dump-super
%install
make install DESTDIR=${RPM_BUILD_ROOT} prefix=%{_prefix} bindir=/sbin mandir=%{_mandir}
install -m 0755 -d ${RPM_BUILD_ROOT}/sbin
install -m 0755 -d ${RPM_BUILD_ROOT}/%{_bindir}
+# remove dangerous and unwanted tools
+rm ${RPM_BUILD_ROOT}/sbin/btrfs-corrupt-block
+rm ${RPM_BUILD_ROOT}/sbin/calc-size
+# add btrfs- prefix to generic names
+mv ${RPM_BUILD_ROOT}/sbin/restore ${RPM_BUILD_ROOT}/sbin/btrfs-restore
+mv ${RPM_BUILD_ROOT}/sbin/find-root ${RPM_BUILD_ROOT}/sbin/btrfs-find-root
# move some utilities out of /sbin
mv ${RPM_BUILD_ROOT}/sbin/{btrfs-show,btrfs-vol,btrfsctl} ${RPM_BUILD_ROOT}/%{_bindir}
mv ${RPM_BUILD_ROOT}/sbin/{btrfs-map-logical,btrfs-debug-tree} ${RPM_BUILD_ROOT}/%{_bindir}
# mkinitrd rescue utilities
-install -m 0755 btrfs-zero-log btrfs-select-super btrfs-image btrfstune ${RPM_BUILD_ROOT}/sbin
-install -m 0755 btrfs-restore btrfs-find-root ${RPM_BUILD_ROOT}/sbin
+install -m 0755 btrfs-zero-log ${RPM_BUILD_ROOT}/sbin
+install -m 0755 btrfs-select-super ${RPM_BUILD_ROOT}/sbin
+install -m 0755 btrfs-image ${RPM_BUILD_ROOT}/sbin
+install -m 0755 btrfstune ${RPM_BUILD_ROOT}/sbin
+install -m 0755 btrfs-dump-super ${RPM_BUILD_ROOT}/sbin
# command line options are not compatible (bnc#599224)
# copy needed if /bin is different fs from /sbin
cp /bin/true ${RPM_BUILD_ROOT}/sbin/fsck.btrfs
@@ -91,6 +180,7 @@
/sbin/btrfsck
/sbin/btrfs-restore
/sbin/btrfs-find-root
+/sbin/btrfs-dump-super
/sbin/mkfs.btrfs
/lib/mkinitrd/scripts/boot-btrfs.sh
# other
++++++ 0100-btrfs-progs-ignore-a-option-in-mkfs.patch ++++++
From a6aa706ee793b406761baeaa7cde78d1250f2d2b Mon Sep 17 00:00:00 2001
From: David Sterba
Date: Wed, 12 Oct 2011 13:36:13 +0200
Subject: [PATCH 01/35] btrfs-progs: ignore -a option in mkfs
Let mkfs accept '-a' option and not complain. When a partition has non-zero
value in the fs_passno filed in /etc/fstab, the fsck is run but fails and boot
stops. As fsck does not break things currently, it's safe to ignore the option
and let the boot proceed.
Reference: https://bugzilla.novell.com/show_bug.cgi?id=655906
Signed-off-by: David Sterba
---
btrfsck.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/btrfsck.c b/btrfsck.c
index 3a23e66..509ab72 100644
--- a/btrfsck.c
+++ b/btrfsck.c
@@ -2815,10 +2815,11 @@ int main(int ac, char **av)
while(1) {
int c;
- c = getopt(ac, av, "s:");
+ c = getopt(ac, av, "as:");
if (c < 0)
break;
switch(c) {
+ case 'a': /* ignored */ break;
case 's':
num = atol(optarg);
bytenr = btrfs_sb_offset(num);
--
1.7.6.233.gd79bc
++++++ 0102-Add-the-force-option.patch ++++++
From 8456dc84b0c7548ca4f83c4e58e8e9dd443b7686 Mon Sep 17 00:00:00 2001
From: Goffredo Baroncelli
Date: Mon, 3 Jan 2011 19:51:46 +0100
Subject: [PATCH 03/35] Add the --force option.
Add the --force option to not check if a device is already mounted.
---
mkfs.c | 46 ++++++++++++++++++++++++++++------------------
1 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/mkfs.c b/mkfs.c
index e3ced19..be236d0 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -303,6 +303,7 @@ static void print_usage(void)
fprintf(stderr, "\t -A --alloc-start the offset to start the FS\n");
fprintf(stderr, "\t -b --byte-count total number of bytes in the FS\n");
fprintf(stderr, "\t -d --data data profile, raid0, raid1, raid10 or single\n");
+ fprintf(stderr, "\t -f --force don't check if a device is already mounted\n");
fprintf(stderr, "\t -l --leafsize size of btree leaves\n");
fprintf(stderr, "\t -L --label set a label\n");
fprintf(stderr, "\t -m --metadata metadata profile, values like data profile\n");
@@ -368,6 +369,7 @@ static struct option long_options[] = {
{ "data", 1, NULL, 'd' },
{ "version", 0, NULL, 'V' },
{ "rootdir", 1, NULL, 'r' },
+ { "force", 0, NULL, 'f' },
{ 0, 0, 0, 0}
};
@@ -1191,10 +1193,11 @@ int main(int ac, char **av)
u64 size_of_data = 0;
u64 source_dir_size = 0;
char *pretty_buf;
+ int force=0;
while(1) {
int c;
- c = getopt_long(ac, av, "A:b:l:n:s:m:d:L:r:VM", long_options,
+ c = getopt_long(ac, av, "A:b:l:n:s:m:d:L:r:VMf", long_options,
&option_index);
if (c < 0)
break;
@@ -1240,6 +1243,8 @@ int main(int ac, char **av)
case 'r':
source_dir = optarg;
source_dir_set = 1;
+ case 'f':
+ force=1;
break;
default:
print_usage();
@@ -1263,14 +1268,17 @@ int main(int ac, char **av)
if (source_dir == 0) {
file = av[optind++];
- ret = check_mounted(file);
- if (ret < 0) {
- fprintf(stderr, "error checking %s mount status\n", file);
- exit(1);
- }
- if (ret == 1) {
- fprintf(stderr, "%s is mounted\n", file);
- exit(1);
+ if(!force){
+ ret = check_mounted(file);
+ if (ret < 0) {
+ fprintf(stderr,
+ "error checking %s mount status\n", file);
+ exit(1);
+ }
+ if (ret == 1) {
+ fprintf(stderr, "%s is mounted\n", file);
+ exit(1);
+ }
}
ac--;
fd = open(file, O_RDWR);
@@ -1353,15 +1361,17 @@ int main(int ac, char **av)
int old_mixed = mixed;
file = av[optind++];
- ret = check_mounted(file);
- if (ret < 0) {
- fprintf(stderr, "error checking %s mount status\n",
- file);
- exit(1);
- }
- if (ret == 1) {
- fprintf(stderr, "%s is mounted\n", file);
- exit(1);
+ if(!force){
+ ret = check_mounted(file);
+ if (ret < 0) {
+ fprintf(stderr, "error checking %s"
+ " mount status\n",file);
+ exit(1);
+ }
+ if (ret == 1) {
+ fprintf(stderr, "%s is mounted\n", file);
+ exit(1);
+ }
}
fd = open(file, O_RDWR);
if (fd < 0) {
--
1.7.6.233.gd79bc
++++++ 0103-mkfs.btrfs-man-page-document-the-force-option.patch ++++++
From fdd55a58d661cede927b741e57abc4f564bb7bd6 Mon Sep 17 00:00:00 2001
From: Goffredo Baroncelli
Date: Mon, 3 Jan 2011 19:53:05 +0100
Subject: [PATCH 04/35] mkfs.btrfs man page: document the --force option.
Add the --force option to not check if a device is already mounted.
---
man/mkfs.btrfs.8.in | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/man/mkfs.btrfs.8.in b/man/mkfs.btrfs.8.in
index 432db1b..2610e9d 100644
--- a/man/mkfs.btrfs.8.in
+++ b/man/mkfs.btrfs.8.in
@@ -6,6 +6,7 @@ mkfs.btrfs \- create an btrfs filesystem
[ \fB\-A\fP\fI alloc-start\fP ]
[ \fB\-b\fP\fI byte-count\fP ]
[ \fB \-d\fP\fI data-profile\fP ]
+[ \fB \-f\fP ]
[ \fB \-l\fP\fI leafsize\fP ]
[ \fB \-L\fP\fI label\fP ]
[ \fB \-m\fP\fI metadata profile\fP ]
@@ -35,6 +36,9 @@ mkfs.btrfs uses all the available storage for the filesystem.
Specify how the data must be spanned across the devices specified. Valid
values are raid0, raid1, raid10 or single.
.TP
+\fB\-f\fR, \fB\-\-force \fR
+Don't check if the device is already mounted.
+.TP
\fB\-l\fR, \fB\-\-leafsize \fIsize\fR
Specify the leaf size, the least data item in which btrfs stores data. The
default value is the page size.
--
1.7.6.233.gd79bc
++++++ 0104-Ignore-the-error-ENXIO-and-ENOMEDIUM-during-a-devs-s.patch ++++++
From da911929cf232b81a4e2dcffbb26dc3cc6f222af Mon Sep 17 00:00:00 2001
From: Goffredo Baroncelli
Date: Fri, 21 Oct 2011 19:00:28 +0200
Subject: [PATCH 05/35] Ignore the error ENXIO and ENOMEDIUM during a devs
scan
Ignore the error ENXIO (device don't exists) and ENOMEDIUM (
No medium found -> like a cd tray empty) in the function
btrfs_scan_one_dir.
This avoids spurios errors due to an empty CD or a block device node
without a device (which is frequent in a static /dev).
Signed-off-by: Goffredo Baroncelli
---
utils.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/utils.c b/utils.c
index 178d1b9..1c27e14 100644
--- a/utils.c
+++ b/utils.c
@@ -1003,8 +1003,14 @@ again:
}
fd = open(fullpath, O_RDONLY);
if (fd < 0) {
- fprintf(stderr, "failed to read %s: %s\n", fullpath,
- strerror(errno));
+ /* ignore the following errors:
+ ENXIO (device don't exists)
+ ENOMEDIUM (No medium found ->
+ like a cd tray empty)
+ */
+ if(errno != ENXIO && errno != ENOMEDIUM)
+ fprintf(stderr, "failed to read %s: %s\n",
+ fullpath, strerror(errno));
continue;
}
ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices,
--
1.7.6.233.gd79bc
++++++ 0105-Regression-tests.patch ++++++
From 8ed24be618165f2f76851e007347408ab9013d30 Mon Sep 17 00:00:00 2001
From: Hugo Mills
Date: Thu, 27 Oct 2011 22:14:26 +0100
Subject: [PATCH 06/35] Regression tests
Add a shell-script based test harness for performing regression tests
on btrfs tools. This is not intended as a test system for kernel
issues, but instead to put the userspace tools through their paces.
Currently implemented tests are compilation of all tools, and checking
argument counting on "btrfs sub snap". Other tests will follow.
Signed-off-by: Hugo Mills
---
Makefile | 8 +++
test/001u.sh | 23 ++++++++++
test/002s.sh | 42 +++++++++++++++++
test/functions.sh | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++
test/run-tests | 13 +++++
5 files changed, 214 insertions(+), 0 deletions(-)
create mode 100755 test/001u.sh
create mode 100755 test/002s.sh
create mode 100644 test/functions.sh
create mode 100755 test/run-tests
diff --git a/Makefile b/Makefile
index 7a5e2c1..5f25d66 100644
--- a/Makefile
+++ b/Makefile
@@ -113,4 +113,12 @@ install: $(progs) install-man
$(INSTALL) $(progs) $(DESTDIR)$(bindir)
if [ -e btrfs-convert ]; then $(INSTALL) btrfs-convert $(DESTDIR)$(bindir); fi
+test: test-userspace test-root
+
+test-userspace:
+ ./test/run-tests
+
+test-root:
+ sudo ./test/run-tests
+
-include .*.d
diff --git a/test/001u.sh b/test/001u.sh
new file mode 100755
index 0000000..d2cadff
--- /dev/null
+++ b/test/001u.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+. test/functions.sh
+
+unset BTRFS_TESTS_VOLUMES
+
+announce compilation
+
+export CC=gcc-4.6
+catchclean
+make clean >/dev/null 2>&1
+
+catch make || fail Plain make failed
+#catch make dir-test || fail Failed to make dir-test
+catch make btrfs-zero-log || fail Failed to make btrfs-zero-log
+catch make btrfs-select-super || fail Failed to make btrfs-select-super
+catch make btrfstune || fail Failed to make btrfstune
+catch make btrfs-image || fail Failed to make btrfsimage
+catch make quick-test || fail Failed to make quick-test
+catch make convert || fail Failed to make btrfs-convert
+catch make ioctl-test || fail Failed to make ioctl-test
+
+summarise
diff --git a/test/002s.sh b/test/002s.sh
new file mode 100755
index 0000000..2c715b7
--- /dev/null
+++ b/test/002s.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+. test/functions.sh
+
+MNT=./test-mountpoint
+
+function setup() {
+ setup_mkfs btrfs-tests $MNT
+
+ ./btrfs subvolume create $MNT/source >/dev/null || return 1
+ dd if=/dev/urandom of=$MNT/source/file1 \
+ bs=1M count=1 >/dev/null 2>&1 || return 1
+}
+
+function teardown() {
+ teardown_rmfs $MNT
+}
+
+announce snapshot
+catchclean
+
+function test_ro() {
+ ./btrfs subvolume snapshot -r $MNT/source $MNT/destination
+ echo foo >$MNT/destination/foo.txt
+}
+
+# Success modes
+catch ./btrfs subvolume snapshot $MNT/source $MNT/destination \
+ || fail Failed to create rw snapshot
+catch ./btrfs subvolume snapshot -r $MNT/source $MNT/destination \
+ || fail Failed to create ro snapshot
+catch test_ro && fail Failed to use read-only flag
+
+# Failure modes
+catch ./btrfs subvolume snapshot \
+ && fail Accepted incorrect parameters \(0 params\)
+catch ./btrfs subvolume snapshot $MNT/source \
+ && fail Accepted incorrect parameters \(1 param\)
+catch ./btrfs subvolume snapshot -r $MNT/source \
+ && fail Accepted incorrect parameters \(1 param, ro\)
+
+summarise
diff --git a/test/functions.sh b/test/functions.sh
new file mode 100644
index 0000000..ca89c67
--- /dev/null
+++ b/test/functions.sh
@@ -0,0 +1,128 @@
+BTRFS_TESTS_VOLUMES="test1.img test2.img test3.img test4.img"
+TESTS_RUN=0
+TESTS_SUCCEEDED=0
+
+if [ -f .tests.conf ]; then
+ . .tests.conf
+fi
+
+function announce()
+{
+ echo --- $(basename $0) --- Testing "$@"
+}
+
+function summarise()
+{
+ echo === ${TESTS_RUN} tests run
+ echo === ${TESTS_SUCCEEDED} successes
+ echo === $((${TESTS_RUN}-${TESTS_SUCCEEDED})) failures
+}
+
+function catchclean()
+{
+ export SUITE=$(basename "$0" .sh)
+ rm -f ${SUITE}.out ${SUITE}.err
+ touch ${SUITE}.out ${SUITE}.err
+}
+
+# Internal function: set up/check the test volumes as requested
+function local_setup()
+{
+ # Set up for this test
+ VOLUMES=
+ for vol in $BTRFS_TESTS_VOLUMES; do
+ if [ ! -e $vol ]; then
+ dd if=/dev/zero of=$vol count=0 seek=4G bs=1 >/dev/null 2>&1 || return 1
+ fi
+ if [ -f $vol ]; then
+ vol=$(losetup -f --show $vol) || return 1
+ VOLUMES="$VOLUMES $vol"
+ elif [ -b $vol ]; then
+ VOLUMES="$VOLUMES $vol"
+ else
+ echo Don\'t know what to do with $vol
+ fi
+ done
+}
+
+# Internal function: destroy test volumes if we created them
+function local_teardown()
+{
+ for vol in $VOLUMES; do
+ if [ -b $vol ]; then
+ if losetup $vol >/dev/null 2>&1; then
+ file=$(losetup $vol | sed -e 's/^.* (\(.*\)).*$/\1/')
+ losetup -d $vol
+ rm $file
+ fi
+ fi
+ done
+ return 0
+}
+
+trap local_teardown EXIT
+
+function catch()
+{
+ TESTS_RUN=$((${TESTS_RUN}+1))
+
+ local_setup
+ if ! setup; then
+ teardown
+ local_teardown
+ return 1
+ fi
+
+ # Preemptively increase the success count: if we call fail, we'll
+ # decrease it again
+ TESTS_SUCCEEDED=$((${TESTS_SUCCEEDED}+1))
+
+ "$@" >>${SUITE}.out 2>>${SUITE}.err
+ rv=$?
+
+ # Undo any setup we did earlier
+ teardown
+ local_teardown
+
+ return ${rv}
+}
+
+function fail()
+{
+ echo "$@"
+ TESTS_SUCCEEDED=$((${TESTS_SUCCEEDED}-1))
+ summarise
+ exit 1
+}
+
+function setup()
+{
+ echo -n
+}
+
+function teardown()
+{
+ echo -n
+}
+
+function setup_mkfs()
+{
+ LABEL=$1
+ MNT=$2
+
+ mkdir -p $MNT
+ ./mkfs.btrfs -L $LABEL $VOLUMES >/dev/null || return 1
+ mount LABEL=$LABEL $MNT || return 1
+}
+
+function teardown_rmfs()
+{
+ MNT=$1
+
+ sleeptime=1
+ while ! umount $MNT 2>/dev/null; do
+ sleep ${sleeptime}
+ sleeptime=$((${sleeptime}+2))
+ done
+ rmdir $MNT
+}
diff --git a/test/run-tests b/test/run-tests
new file mode 100755
index 0000000..981fc22
--- /dev/null
+++ b/test/run-tests
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+testdir=$(dirname $0)
+
+if [ $UID -eq 0 ]; then
+ type=s
+else
+ type=u
+fi
+
+for test in ${testdir}/[0-9][0-9][0-9]${type}.sh; do
+ ${test}
+done
--
1.7.6.233.gd79bc
++++++ 0106-Fix-sub-snap-parameter-handling.patch ++++++
From 33be6f1695e8bd450be2e22fbf88b826488186a1 Mon Sep 17 00:00:00 2001
From: Hugo Mills
Date: Sun, 30 Oct 2011 20:17:07 +0000
Subject: [PATCH 07/35] Fix sub snap parameter handling
btrfs sub snap uses a local copy of optind, which causes the number of
parameters to be miscounted, preventing it from working properly. This
patch, originally from Arne Jansen , fixes it.
Signed-off-by: Hugo Mills
---
btrfs_cmds.c | 23 ++++++++++++-----------
1 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/btrfs_cmds.c b/btrfs_cmds.c
index b59e9cb..9252ffa 100644
--- a/btrfs_cmds.c
+++ b/btrfs_cmds.c
@@ -304,7 +304,8 @@ int do_subvol_list(int argc, char **argv)
int ret;
int print_parent = 0;
char *subvol;
- int optind = 1;
+
+ optind = 1;
while(1) {
int c = getopt(argc, argv, "p");
@@ -312,7 +313,6 @@ int do_subvol_list(int argc, char **argv)
switch(c) {
case 'p':
print_parent = 1;
- optind++;
break;
}
}
@@ -347,11 +347,13 @@ int do_subvol_list(int argc, char **argv)
int do_clone(int argc, char **argv)
{
- char *subvol, *dst;
- int res, fd, fddst, len, e, optind = 0, readonly = 0;
- char *newname;
- char *dstdir;
- struct btrfs_ioctl_vol_args_v2 args;
+ char *subvol, *dst;
+ int res, fd, fddst, len, e, readonly = 0;
+ char *newname;
+ char *dstdir;
+ struct btrfs_ioctl_vol_args_v2 args;
+
+ optind = 1;
memset(&args, 0, sizeof(args));
@@ -362,7 +364,6 @@ int do_clone(int argc, char **argv)
break;
switch (c) {
case 'r':
- optind++;
readonly = 1;
break;
default:
@@ -372,14 +373,14 @@ int do_clone(int argc, char **argv)
return 1;
}
}
- if (argc - optind != 3) {
+ if (argc - optind != 2) {
fprintf(stderr, "Invalid arguments for subvolume snapshot\n");
free(argv);
return 1;
}
- subvol = argv[optind+1];
- dst = argv[optind+2];
+ subvol = argv[optind];
+ dst = argv[optind+1];
res = test_issubvolume(subvol);
if(res<0){
--
1.7.6.233.gd79bc
++++++ 0107-Add-info-for-the-commands.patch ++++++
From 18254b66cf6ff7c9eff605ac7de9b4947d39a96f Mon Sep 17 00:00:00 2001
From: Goffredo Baroncelli
Date: Sat, 16 Jul 2011 11:35:39 +0200
Subject: [PATCH 08/35] Add info for the commands.
Add info for every btrfs sub-commands in the sources.
---
btrfs_cmds.c | 237 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
scrub.c | 79 +++++++++++++++++++
2 files changed, 316 insertions(+), 0 deletions(-)
diff --git a/btrfs_cmds.c b/btrfs_cmds.c
index 9252ffa..1bfc669 100644
--- a/btrfs_cmds.c
+++ b/btrfs_cmds.c
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#undef ULONG_MAX
@@ -155,6 +156,42 @@ static int parse_compress_type(char *s)
};
}
+
+/**** man: btrfs filesystem defragment
+ *
+ * \Bbtrfs\b \Bfilesystem defragment\b -c[zlib|lzo] [-l \Ilen\i] [-s \Istart\i] [-t \Isize\i] -[vf] <\Ifile\i>|<\Idir\i> [<\Ifile\i>|<\Idir\i>...]
+ *
+ * Defragment a file or a directory.
+ *
+ * Defragment file data and/or directory metadata. To defragment all files in a
+ * directory you have to specify each one on its own or use your shell
+ * wildcards.
+ *
+ * The start position and the number of bytes to deframention can be specified
+ * by \Istart\i and \Ilen\i. Any extent bigger than \Ithresh\i will be
+ * considered already defragged. Use 0 to take the kernel default, and use 1
+ * to say eveery single extent must be rewritten. You can also turn on
+ * compression in defragment operations.
+ *
+ * \B-v\b be verbose
+ *
+ * \B-c\b compress file contents while defragmenting
+ *
+ * \B-f\b flush filesystem after defragmenting
+ *
+ * \B-s start\b defragment only from byte \Istart\i onward
+ *
+ * \B-l len\b defragment only up to \Ilen\i bytes
+ *
+ * \B-t size\b defragment only files at least \Isize\i bytes big
+ *
+ * NOTE: defragmenting with kernels up to 2.6.37 will unlink COW-ed copies of
+ * data, don't use it if you use snapshots, have de-duplicated your data or
+ * made copies with
+ *
+ * \Bcp --reflink\b.
+ ****/
+
int do_defrag(int ac, char **av)
{
int fd;
@@ -267,6 +304,16 @@ int do_defrag(int ac, char **av)
return errors + 20;
}
+
+/**** man: btrfs subvolume find-new
+ *
+ * \Bbtrfs\b \Bsubvolume find-new\b\I <subvolume> \i
+ *
+ * List the recently modified files in a filesystem.
+ *
+ * List the recently modified files in a subvolume, after \I\i ID.
+ ****/
+
int do_find_newer(int argc, char **argv)
{
int fd;
@@ -298,6 +345,25 @@ int do_find_newer(int argc, char **argv)
return 0;
}
+
+/**** man: btrfs subvolume list
+ *
+ * \Bbtrfs\b \Bsubvolume list\b\I [-p] <path>\i
+ *
+ * List the snapshot/subvolume of a filesystem.
+ *
+ * List the subvolumes present in the filesystem \I<path>\i. For every
+ * subvolume the following information is shown by default.
+ * ID <ID> top level <ID> path <path>
+ * where path is the relative path of the subvolume to the \Itop level\i
+ * subvolume.
+ * The subvolume's ID may be used by the \Bsubvolume set-default\b command, or
+ * at mount time via the \Isubvol=\i option.
+ * If \I-p\i is given, then \Iparent <ID>\i is added to the output between ID
+ * and top level. The parent's ID may be used at mount time via the
+ * \Isubvolrootid=\i option.
+ ****/
+
int do_subvol_list(int argc, char **argv)
{
int fd;
@@ -345,6 +411,20 @@ int do_subvol_list(int argc, char **argv)
return 0;
}
+
+/**** man: btrfs subvolume snapshot
+ *
+ * \Bbtrfs\b \Bsubvolume snapshot\b\I [-r] <source> [<dest>/]<name>\i
+ *
+ * Create a writable/readonly snapshot of the subvolume <source> with
+ * the name <name> in the <dest> directory.
+ *
+ * Create a writable/readonly snapshot of the subvolume \I<source>\i with the
+ * name \I<name>\i in the \I<dest>\i directory. If \I<source>\i is not a
+ * subvolume, \Bbtrfs\b returns an error. If \I-r\i is given, the snapshot
+ * will be readonly.
+ ****/
+
int do_clone(int argc, char **argv)
{
char *subvol, *dst;
@@ -463,6 +543,17 @@ int do_clone(int argc, char **argv)
}
+
+/**** man: btrfs subvolume delete
+ *
+ * \Bbtrfs\b \Bsubvolume delete\b\I <subvolume>\i
+ *
+ * Delete the subvolume <subvolume>.
+ *
+ * Delete the subvolume \I<subvolume>\i. If \I<subvolume>\i is not a
+ * subvolume, \Bbtrfs\b returns an error.
+ ****/
+
int do_delete_subvolume(int argc, char **argv)
{
int res, fd, len, e;
@@ -525,6 +616,18 @@ int do_delete_subvolume(int argc, char **argv)
}
+
+/**** man: btrfs subvolume create
+ *
+ * \Bbtrfs\b \Bsubvolume create\b\I [<dest>/]<name>\i
+ *
+ * Create a subvolume in <dest> (or the current directory if
+ * not passed).
+ *
+ * Create a subvolume in \I<dest>\i (or in the current directory if
+ * \I<dest>\i is omitted).
+ ****/
+
int do_create_subvol(int argc, char **argv)
{
int res, fddst, len, e;
@@ -581,6 +684,16 @@ int do_create_subvol(int argc, char **argv)
}
+
+/**** man: btrfs filesystem sync
+ *
+ * \Bbtrfs\b \Bfilesystem sync\b\I <path> \i
+ *
+ * Force a sync on the filesystem <path>.
+ *
+ * Force a sync for the filesystem identified by \I<path>\i.
+ ****/
+
int do_fssync(int argc, char **argv)
{
int fd, res, e;
@@ -605,6 +718,21 @@ int do_fssync(int argc, char **argv)
return 0;
}
+
+/**** man: btrfs device scan
+ *
+ * \Bbtrfs\b \Bdevice scan\b \I[--all-devices|<device> [<device>...]\i
+ *
+ * Scan all device for or the passed device for a btrfs
+ * filesystem.
+ *
+ * If one or more devices are passed, these are scanned for a btrfs filesystem.
+ * If no devices are passed, \Bbtrfs\b scans all the block devices listed
+ * in the /proc/partitions file.
+ * Finally, if \B--all-devices\b is passed, all the devices under /dev are
+ * scanned.
+ ****/
+
int do_scan(int argc, char **argv)
{
int i, fd, e;
@@ -672,6 +800,32 @@ int do_scan(int argc, char **argv)
}
+
+/**** man: btrfs filesystem resize
+ *
+ * \Bbtrfs\b \Bfilesystem resize\b\I [+/\-]<size>[gkm]|max <path>\i
+ *
+ * Resize the file system. If 'max' is passed, the filesystem
+ * will occupe all available space on the device.
+ *
+ * Resize a filesystem identified by \I<path>\i.
+ * The \I<size>\i parameter specifies the new size of the filesystem.
+ * If the prefix \I+\i or \I\-\i is present the size is increased or decreased
+ * by the quantity \I<size>\i.
+ * If no units are specified, the unit of the \I<size>\i parameter defaults to
+ * bytes. Optionally, the size parameter may be suffixed by one of the following
+ * the units designators: 'K', 'M', or 'G', kilobytes, megabytes, or gigabytes,
+ * respectively.
+ *
+ * If 'max' is passed, the filesystem will occupy all available space on the
+ * volume(s).
+ *
+ * The \Bresize\b command \Bdoes not\b manipulate the size of underlying
+ * partition. If you wish to enlarge/reduce a filesystem, you must make sure
+ * you can expand the partition before enlarging the filesystem and shrink the
+ * partition after reducing the size of the filesystem.
+ ****/
+
int do_resize(int argc, char **argv)
{
@@ -762,6 +916,20 @@ static void print_one_uuid(struct btrfs_fs_devices *fs_devices)
printf("\n");
}
+
+/**** man: btrfs filesystem show
+ *
+ * \Bbtrfs\b \Bfilesystem show\b [--all-devices|<uuid>|<label>]\b
+ *
+ * Show the info of a btrfs filesystem. If no argument
+ * is passed, info of all the btrfs filesystem are shown.
+ *
+ * Show the btrfs filesystem with some additional info. If no \IUUID\i or
+ * \Ilabel\i is passed, \Bbtrfs\b show info of all the btrfs filesystem.
+ * If \B--all-devices\b is passed, all the devices under /dev are scanned;
+ * otherwise the devices list is extracted from the /proc/partitions file.
+ ****/
+
int do_show_filesystem(int argc, char **argv)
{
struct list_head *all_uuids;
@@ -807,6 +975,16 @@ int do_show_filesystem(int argc, char **argv)
return 0;
}
+
+/**** man: btrfs device add
+ *
+ * \Bbtrfs\b \Bdevice add\b\I <dev> [<dev>..] <path>\i
+ *
+ * Add a device to a filesystem.
+ *
+ * Add device(s) to the filesystem identified by \I<path>\i.
+ ****/
+
int do_add_volume(int nargs, char **args)
{
@@ -889,6 +1067,15 @@ int do_add_volume(int nargs, char **args)
}
+/**** man: btrfs filesystem balance
+ *
+ * \Bbtrfs\b \Bfilesystem balance\b \I<path>\i
+ *
+ * Balance chunks across the devices.
+ *
+ * Balance chunks across the devices.
+ ****/
+
int do_balance(int argc, char **argv)
{
@@ -914,6 +1101,18 @@ int do_balance(int argc, char **argv)
}
return 0;
}
+
+
+
+/**** man: btrfs device delete
+ *
+ * \Bbtrfs\b \Bdevice delete\b\I <dev> [<dev>..] <path>\i
+ *
+ * Remove a device from a filesystem.
+ *
+ * Remove device(s) from a filesystem identified by \I<path>\i.
+ ****/
+
int do_remove_volume(int nargs, char **args)
{
@@ -947,6 +1146,19 @@ int do_remove_volume(int nargs, char **args)
return 0;
}
+
+/**** man: btrfs subvolume set-default
+ *
+ * \Bbtrfs\b \Bsubvolume set-default\b\I <id> <path>\i
+ *
+ * Set the subvolume of the filesystem <path> which will be mounted
+ * as default.
+ *
+ * Set the subvolume of the filesystem \I<path>\i which is mounted as
+ * \Idefault\i. The subvolume is identified by \I<id>\i, which
+ * is returned by the \Bsubvolume list\b command.
+ ****/
+
int do_set_default_subvol(int nargs, char **argv)
{
int ret=0, fd, e;
@@ -976,6 +1188,31 @@ int do_set_default_subvol(int nargs, char **argv)
return 0;
}
+
+/**** man: btrfs filesystem label
+ *
+ * \Bbtrfs\b \Bfilesystem label\b\I <dev> [newlabel]\i
+ *
+ * With one argument, get the label of filesystem on <device>.
+ * If <newlabel> is passed, set the filesystem label to <newlabel>.
+ * The filesystem must be unmounted.
+ *
+ * Show or update the label of a filesystem. \I<dev>\i is used to identify the
+ * filesystem.
+ * If a \Inewlabel\i optional argument is passed, the label is changed. The
+ * following costraints exist for a label:
+ * \t
+ * - the maximum allowable lenght shall be less or equal than 256 chars
+ * \t
+ * - the label shall not contain the '/' or '\\' characters.
+ *
+ * NOTE: Currently there are the following limitations:
+ * \t
+ * - the filesystem has to be unmounted
+ * \t
+ * - the filesystem should not have more than one device.
+ ****/
+
int do_change_label(int nargs, char **argv)
{
/* check the number of argument */
diff --git a/scrub.c b/scrub.c
index 9dca5f6..66761c5 100644
--- a/scrub.c
+++ b/scrub.c
@@ -1473,16 +1473,76 @@ out:
return 0;
}
+
+/**** man: btrfs scrub start
+ *
+ * \Bbtrfs\b \Bscrub start\b [-Bdqru] {\I<path>\i|\I<device>\i}
+ *
+ * Start a new scrub.
+ *
+ * Start a scrub on all devices of the filesystem identified by \I<path>\i or on
+ * a single \I<device>\i. Without options, scrub is started as a background
+ * process. Progress can be obtained with the \Bscrub status\b command.
+ * Scrubbing involves reading all data from all disks and verifying checksums.
+ * Errors are corrected along the way if possible.
+ * \w
+ *
+ * \IOptions\i
+ * \t -B 5
+ * Do not background and print scrub statistics when finished.
+ * \t -d 5
+ * Print separate statistics for each device of the filesystem (-B only).
+ * \t -q 5
+ * Quiet. Omit error messages and statistics.
+ * \t -r 5
+ * Read only mode. Do not attempt to correct anything.
+ * \t -u 5
+ * Scrub unused space as well. (NOT IMPLEMENTED)
+ * \q
+ ****/
+
int do_scrub_start(int argc, char **argv)
{
return scrub_start(argc, argv, 0);
}
+
+/**** man: btrfs scrub resume
+ *
+ * \Bbtrfs\b \Bscrub resume\b [-Bdqru] {\I<path>\i|\I<device>\i}
+ *
+ * Resume previously canceled or interrupted scrub.
+ *
+ * Resume a canceled or interrupted scrub cycle on the filesystem identified by
+ * \I<path>\i or on a given \I<device>\i. Does not start a new scrub if the
+ * last scrub finished successfully.
+ * \w
+ *
+ * \IOptions\i
+ * \p
+ * see \Bscrub start\b.
+ * \q
+ ****/
+
int do_scrub_resume(int argc, char **argv)
{
return scrub_start(argc, argv, 1);
}
+
+/**** man: btrfs scrub cancel
+ *
+ * \Bbtrfs\b \Bscrub cancel\b {\I<path>\i|\I<device>\i}
+ *
+ * Cancel a running scrub.
+ *
+ * If a scrub is running on the filesystem identified by \I<path>\i, cancel it.
+ * Progress is saved in the scrub progress file and scrubbing can be resumed later
+ * using the \Bscrub resume\b command.
+ * If a \I<device>\i is given, the corresponding filesystem is found and
+ * \Bscrub cancel\b behaves as if it was called on that filesystem.
+ ****/
+
int do_scrub_cancel(int argc, char **argv)
{
char *path = argv[1];
@@ -1528,6 +1588,25 @@ again:
return 0;
}
+
+/**** man: btrfs scrub status
+ *
+ * \Bbtrfs\b \Bscrub status\b [-d] {\I<path>\i|\I<device>\i}
+ *
+ * Show status of running or finished scrub.
+ *
+ * Show status of a running scrub for the filesystem identified by \I<path>\i or
+ * for the specified \I<device>\i.
+ * If no scrub is running, show statistics of the last finished or canceled scrub
+ * for that filesystem or device.
+ * \w
+ *
+ * \IOptions\i
+ * \t -d 5
+ * Print separate statistics for each device of the filesystem.
+ * \q
+ ****/
+
int do_scrub_status(int argc, char **argv)
{
--
1.7.6.233.gd79bc
++++++ 0108-Add-the-header-footer-introduction-of-the-man-page.patch ++++++
From aa8bba1e2c99eb895c7e43f5092e4bf56d68d9c5 Mon Sep 17 00:00:00 2001
From: Goffredo Baroncelli
Date: Sat, 16 Jul 2011 11:11:08 +0200
Subject: [PATCH 09/35] Add the header/footer/introduction of the man page.
Add the header/footer/introduction of the man page. There is also an
introduction to the syntax recognized by the tool helpextract to format
the information.
---
btrfs.c | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 176 insertions(+), 0 deletions(-)
diff --git a/btrfs.c b/btrfs.c
index 1def354..d2f6d4d 100644
--- a/btrfs.c
+++ b/btrfs.c
@@ -26,6 +26,182 @@
#define BASIC_HELP 0
#define ADVANCED_HELP 1
+/**
+ ** The comments below are used to make the man page
+ **
+ ** There are:
+ ** - Header,
+ ** - The synopsis title section (the content are extracted from other
+ ** comments)
+ ** - The synopsis format, which is a template: the '%s' is replaced by
+ ** the command line "syntax"
+ ** - The btrfs introduction section
+ ** - The btfrs command title section (the content are extracted from other
+ ** comments)
+ ** - The command format, which is a template: the first '%s' is replaced by
+ ** the command line "syntax"; the ssecond '%s' is replaced by the
+ ** detailed descritpion
+ ** - The "notes" section
+ ** - The footer (currentli empty)
+ **
+ ** The comments are the following sytax [replace '{slash}' with '/']
+ **
+ ** If the comment starts with '{slash}**** text: ', then all the text below
+ ** are used until ' ***'. The text after 'text: ' are the key used to
+ ** index teh content.
+ **
+ ** If the comment starts with '{slash}**** man: ', then below the comment are
+ ** divided in three section:
+ ** 1) (one line) command line syntax
+ ** 2) (multiple line) short description (showed in the command "btrfs help")
+ ** 3) (multiple line) detailled description (showed in the man page and
+ ** command "btrfs <subcommand> --help")
+ ** The text after 'man: ' are the key used to index the content. This must
+ ** be equal to the subcommand which the info is referred.
+ **
+ ** Below the escape sequence which may be used in the text
+ **
+ ** escape troff
+ ** sequence command
+ **
+ ** \B \fB bold
+ ** \b \fP end bold
+ ** \I \fI italic
+ ** \i \fP end italic
+ ** \c .\" comment
+ ** \P .PP start paragraph
+ ** \p .TP indented paragraph
+ ** \h .SH header
+ ** \d .BR bold regular
+ ** \e .B bold
+ ** \t .IP indented paragraph
+ ** \w .RS move the left margin
+ ** \q .RE move the left margin back
+ ** \- \- minus (it *must* escaped )
+ **
+ **
+ **/
+
+
+/**** text: man btrfs header
+ * .TH BTRFS 8 "" "btrfs" "btrfs"
+ * .\"
+ * .\" Man page for the "btrfs" tool
+ * .\"
+ * .SH NAME
+ * btrfs \- control a btrfs filesystem
+ ****/
+
+/**** text: man btrfs synopsis
+ * .SH SYNOPSIS
+ ****/
+
+/**** text: man btrfs synopsis format
+ * \fB%s\fP
+ * .PP
+ ****/
+
+/**** text: btrfs introduction
+ * \h DESCRIPTION
+ * \Bbtrfs\b is used to control the filesystem and the files and directories
+ * stored. It is the tool to create or destroy a snapshot or a subvolume for
+ * the filesystem, to defrag a file or a directory, flush the data to the disk,
+ * to resize the filesystem, to scan the device.
+ *
+ * It is possible to abbreviate the commands unless the commands are ambiguous.
+ * For example: it is possible to run
+ * \Ibtrfs sub snaps\i instead of \Ibtrfs subvolume snapshot\i. But \Ibtrfs
+ * file s\i is not allowed, because \Ifile s\i may be interpreted both as
+ * \Ifilesystem show\i and as \Ifilesystem sync\i.
+ *
+ * If a command is terminated by \I--help\i, the detailed help is showed.
+ * If the passed command matches more commands, detailed help of all the
+ * matched commands is showed. For example \Ibtrfs dev --help\i shows the
+ * help of all \Idevice*\i commands.
+ ****/
+
+/**** text: man btrfs command format
+ *
+ * .TP
+ * %s%s
+ ****/
+
+/**** text: man btrfs commands
+ * .SH COMMANDS
+ * .TP
+ */
+
+/**** text: btrfs notes
+ * \h BALANCE FILTERS
+ *
+ * With balance filters, it is possible to perform a balance operation on
+ * only a subset of the available chunks. Filters are specified with the
+ * \B--filter\b option of \Bbtrfs filesystem balance\b or \Bbtrfs
+ * balance start\b. Multiple filters may be given, either with multiple
+ * \B--filter\b options, or in a colon-separated list. When multiple
+ * filters are given, only the chunks meeting all of the selection
+ * critera are balanced. Help on the avaialble filters can be obtained
+ * with \B--filter=help\b.
+ *
+ *
+ * \Btype\b=[\B~\b]\I<flagname>\i[\B,\b...]
+ *
+ * Select only the chunks with the given type flag(s). Requiring a flag
+ * to be off can be specified with a \B~\b preceding the flag
+ * name. Flag names are:
+ *
+ * \Bmeta\b, \Bdata\b, \Bsys\b for metadata, file data and system
+ * chunk types.
+ *
+ * \Braid0\b, \Braid1\b, \Braid10\b, \Bdup\b for chunks of the
+ * given replication levels.
+ *
+ *
+ * \Bdevid\b=\I<n>\i
+ *
+ * Select chunks which have data on device ID \I<n>\i. This can be
+ * used, for example, to reduplicate data in a mirrored configuration
+ * where one drive has been lost due to hardware failure.
+ *
+ *
+ * \Bvrange\b=\I<start>\i,\I<end>\i
+ *
+ * Select chunks which have btrfs-internal virtual addresses within the
+ * range \I<start>\i (inclusive) to \I<end>\i (exclusive). Given the
+ * address of the last chunk moved, this filter can be used to restart a
+ * cancelled or interrupted balance operation, by supplying a range of
+ * \I0,\i.
+ *
+ * \Bdrange\b=\I<start>\i,\I<end>\i
+ *
+ * Select chunks which contain data in the address range \I<start>\i
+ * (inclusive) to \I<end>\i (exclusive) on \Iany\i block device in
+ * the filesystem. Can be mixed with the \Bdevid\b filter to select
+ * chunks in a given address range on a specific device.
+ *
+ * \h EXIT STATUS
+ * \Bbtrfs\b returns a zero exist status if it succeeds. Non zero is returned in
+ * case of failure.
+ *
+ * \h AVAILABILITY
+ * \Bbtrfs\b is part of btrfs-progs. Btrfs filesystem is currently under
+ * heavy development, and not suitable for any uses other than benchmarking and
+ * review.
+ *
+ * Please refer to the btrfs wiki http://btrfs.wiki.kernel.org for
+ * further details.
+ *
+ * \h SEE ALSO
+ * \Bmkfs.btrfs (8)\b
+ ****/
+
+/**** text: man btrfs footer
+ ****/
+
+
+
+
+
typedef int (*CommandFunction)(int argc, char **argv);
struct Command {
--
1.7.6.233.gd79bc
++++++ 0109-helpextract-tool-to-extract-the-info-for-the-help-fr.patch ++++++
From e1825e850af190793dadf5ca78f36f394bae9e86 Mon Sep 17 00:00:00 2001
From: Goffredo Baroncelli
Date: Sat, 16 Jul 2011 10:55:30 +0200
Subject: [PATCH 10/35] helpextract: tool to extract the info for the help
from the source.
It is created the file helpextract.c, which is the source for the tool
"helpextract". This program extract the info showed in the man page and
the help command from the sources comments.
---
helpextract.c | 435 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 435 insertions(+), 0 deletions(-)
create mode 100644 helpextract.c
diff --git a/helpextract.c b/helpextract.c
new file mode 100644
index 0000000..9489ea0
--- /dev/null
+++ b/helpextract.c
@@ -0,0 +1,435 @@
+#include
+#include
+#include
+#include
+#include
+
+#define PREFIX_MAN "/**** man: "
+#define PREFIX_TEXT "/**** text: "
+#define PREFIX_END " ****"
+#define PREFIX_SKIP " * "
+
+#define LINEBUF 1024
+
+char **msgs=0;
+int nmsg=0;
+
+static char *xstrdup(char *str){
+ char *new = strdup(str);
+ if(!new){
+ fprintf(stderr,"*** Memory allocation fail ! (xstrdup)\n");
+ exit(101);
+ }
+ return new;
+}
+
+static void *xrealloc(void *ptr, int newsize){
+ void *new = realloc(ptr, newsize);
+ if(!new){
+ fprintf(stderr,"*** Memory allocation fail ! (xrealloc)\n");
+ exit(101);
+ }
+ return new;
+
+
+}
+
+static char *xstrip(char *s){
+
+ char *last=NULL;
+ char *first;
+
+ while(*s && isspace(*s) ) s++;
+
+ first=s;
+
+ while(*s){
+ if(isspace(*s)) last=s;
+ s++;
+ }
+
+ if(last) *last=0;
+ return first;
+
+
+}
+
+static void addtuple(char *key, char *cmdline, char *short_help,
+ char *long_help){
+
+ msgs = (char**)xrealloc(msgs, sizeof(char *)*(nmsg+1)*4);
+
+ key = xstrip(key);
+
+ if( !long_help || !strcmp(long_help,"\n"))
+ long_help = short_help;
+ else if(!short_help || !strcmp(short_help, "\n"))
+ short_help = long_help;
+
+ msgs[nmsg*4] = key;
+ msgs[nmsg*4+1] = cmdline;
+ msgs[nmsg*4+2] = short_help;
+ msgs[nmsg*4+3] = long_help;
+ nmsg++;
+}
+
+
+static int search_in_file(char *nf){
+ char buf[LINEBUF+1];
+ FILE *fp;
+ int status;
+ char *key=NULL;
+ char *cmdline=NULL;
+ char *short_help=NULL;
+ char *long_help=NULL;
+
+ fp = fopen(nf,"r");
+ if(!fp){
+ int e=errno;
+ fprintf(stderr, "*** Cannot open '%s'; error = %d - '%s'\n",
+ nf, e, strerror(e));
+ return -1;
+ }
+
+ status = 0;
+ while(fgets(buf,LINEBUF,fp)){
+ // printf("status = %d, buf=%s",status, buf);
+
+ if(status == 0){
+ if(!strncmp(buf,PREFIX_MAN, strlen(PREFIX_MAN)) ){
+ key = xstrdup(buf+strlen(PREFIX_MAN));
+ status++;
+ }else if(!strncmp(buf,PREFIX_TEXT,
+ strlen(PREFIX_TEXT))){
+ key = xstrdup(buf+strlen(PREFIX_TEXT));
+ status=5;
+ }
+ continue;
+
+ }
+
+ if( !strncmp(buf,PREFIX_END, strlen(PREFIX_END)) ||
+ strncmp(buf, PREFIX_SKIP,2)){
+
+ addtuple(key, cmdline, short_help, long_help);
+ key = cmdline = short_help = long_help = 0;
+ status = 0;
+
+ continue;
+ }
+ if( status == 2){
+ if(strlen(buf)>strlen(PREFIX_SKIP))
+ cmdline = xstrdup(buf+strlen(PREFIX_SKIP));
+ status++;
+ continue;
+ }
+ if( status == 4){
+ int len;
+ int len2;
+ char *p;
+
+ if(strlen(buf)<=strlen(PREFIX_SKIP)){
+ status++;
+ continue;
+ }
+ p=buf+3;
+ while(isspace(*p) && *p ) p++;
+ if(!*p){
+ status++;
+ continue;
+ }
+
+ len2 = strlen(buf)-strlen(PREFIX_SKIP);
+
+ if(short_help)
+ len = strlen(short_help);
+ else
+ len = 0;
+ short_help = (char*)xrealloc(short_help, len+len2+1);
+ strcpy(short_help+len,buf+strlen(PREFIX_SKIP));
+ continue;
+ }
+ if( status == 5){
+ int len;
+ int len2 = strlen(buf)-strlen(PREFIX_SKIP);
+
+ if(long_help)
+ len = strlen(long_help);
+ else
+ len = 0;
+ long_help = (char*)xrealloc(long_help, len+len2+1);
+ strcpy(long_help+len,buf+strlen(PREFIX_SKIP));
+ continue;
+ }
+ if( status == 1 || status == 3 ){
+ status++;
+ continue;
+ }
+
+ fprintf(stderr,"*** Internal error: status = %d\n",status);
+ exit(100);
+
+ }
+
+ if( status != 0 ){
+ fprintf(stderr,"*** Parse error: file = '%s', "
+ "status = %d at the end of file\n",
+ nf, status);
+ exit(100);
+
+ }
+
+ fclose(fp);
+
+ return 0;
+}
+
+/* remove all the escape sequence excepet \\ */
+static char * my_escape(char *src, char *filters[] ){
+
+ static char buffer[LINEBUF*5];
+
+ int i=0;
+ while(*src){
+ int j;
+ int next_char = *(src+1);
+ if(*src != '\\'){
+ buffer[i++]=*src++;
+ continue;
+ }
+ if(!next_char){
+ buffer[i++]=*src++;
+ continue;
+ }
+ if( !filters ){
+ src +=2;
+ continue;
+ }
+
+ j=0;
+ while(filters[j]){
+ if(filters[j][0] == next_char ){
+ strcpy(buffer+i, filters[j]+2);
+ i+=strlen(filters[j]+2);
+ break;
+ }
+ j++;
+ }
+ if(!filters[j]){
+ char *p=src;
+ int l=40;
+ fprintf(stderr,
+ "Unknow escape sequence '\%c' in [\"",
+ next_char);
+ while(*p && l--) fputc(*p++, stderr);
+ fprintf(stderr, "\"...]\n");
+ }
+ src += 2;
+
+ }
+
+ buffer[i]=0;
+ return buffer;
+
+}
+
+static char * escape_c_array(char *src ){
+ static char *filters[]={
+
+ /* remove the all know esc-sequence */
+
+ "B ", /* bold */
+ "b ", /* end bold */
+ "I ", /* italic */
+ "i ", /* end italic */
+ "c ", /* comment */
+ "P ", /* start paragraph */
+ "p ", /* indented paragraph */
+ "h ", /* header */
+ "d ", /* bold regular */
+ "e ", /* bold */
+ "t ", /* indented paragraph */
+ "w ", /* move the left margin */
+ "q ", /* move the left margin back */
+
+ "\\ \\\\",
+ "- -",
+
+ 0
+ };
+
+ return my_escape(src, filters);
+}
+
+static char *escape_man_page(char *src){
+ /* from Gnu troff manual */
+ static char *filters[]={
+ "B \\fB", /* bold */
+ "b \\fP", /* end bold */
+ "I \\fI", /* italic */
+ "i \\fP", /* end italic */
+ "c .\\\"", /* comment */
+ "P .PP", /* start paragraph */
+ "p .TP", /* indented paragraph */
+ "h .SH", /* header */
+ "d .BR", /* bold regular */
+ "e .B", /* bold */
+ "t .IP", /* indented paragraph */
+ "w .RS", /* move the left margin */
+ "q .RE", /* move the left margin back */
+
+ "- \\-", /* escape the minus sign */
+ "\\ \\",
+
+ 0
+ };
+
+ return my_escape(src, filters);
+}
+
+
+static void dump_c_array(){
+
+ int i;
+
+ printf("{");
+ for(i=0; i < nmsg*4 ; i++){
+ char *c = msgs[i];
+ int begin;
+
+ if(!(i%4) && strncmp(c,"btrfs ",5)){
+ i+=3;
+ continue;
+ }
+
+ if(i>0){
+ putchar(',');
+ if(!(i%4)) putchar('\n');
+ }
+
+ if(!c){
+ printf("\n NULL");
+ continue;
+ }
+
+ c = escape_c_array(c);
+
+ begin = 1;
+ while( *c ){
+ if(begin)
+ printf("\n \"");
+ begin = 0;
+ if( *c == '\n' ){
+ printf("\\n\"");
+ begin = 1;
+ }else if( *c == '"' ){
+ printf("\\\"");
+ }else{
+ putchar(*c);
+ }
+
+ c++;
+ }
+ if(!begin) putchar('"');
+ }
+ printf(",\n\n ");
+ for(i=0; i < 4; i++){
+ if(i>0) putchar(',');
+ printf("NULL");
+ }
+ printf("\n}\n");
+
+}
+
+static int my_sort_cmp(const void *p1, const void *p2){
+ return strcmp(*(char**)p1, *(char **)p2);
+}
+
+static void my_sort(){
+ qsort(msgs, nmsg, sizeof(char*)*4, my_sort_cmp);
+}
+
+static int find_section(char *key){
+ int i;
+ for(i = 0 ; i < nmsg ; i++ )
+ if(!strcmp( msgs[i*4],key) ) return i;
+
+ return -1;
+}
+
+static void dump_man_page(){
+
+ int i, fmt;
+
+ i = find_section("man btrfs header");
+ if( i>= 0 ) printf(msgs[i*4+3]);
+
+ i = find_section("man btrfs synopsis");
+ if( i>= 0 ) printf(msgs[i*4+3]);
+
+ fmt = find_section("man btrfs synopsis format");
+ for(i = 0; i < nmsg && fmt>=0; i++ ){
+ if( strncmp("btrfs ",msgs[i*4], 6) ||
+ !strcmp("btrfs introduction", msgs[i*4] ) ||
+ !strcmp("btrfs notes", msgs[i*4] ) )
+ continue;
+
+ printf(msgs[fmt*4+3], escape_man_page(msgs[i*4+1]));
+ }
+
+ i = find_section("btrfs introduction");
+ if( i>= 0 ) printf(escape_man_page(msgs[i*4+3]));
+
+ i = find_section("man btrfs commands");
+ if( i>= 0 ) printf(msgs[i*4+3]);
+
+ fmt = find_section("man btrfs command format");
+ for(i = 0; i < nmsg && fmt>=0; i++ ){
+
+ char big2[LINEBUF*5];
+ if( strncmp("btrfs ",msgs[i*4], 6) ||
+ !strcmp("btrfs introduction", msgs[i*4] ) ||
+ !strcmp("btrfs notes", msgs[i*4] ) )
+ continue;
+
+ strcpy(big2, escape_man_page(msgs[i*4+3]));
+ printf(msgs[fmt*4+3], escape_man_page(msgs[i*4+1]), big2);
+
+ }
+
+ i = find_section("man btrfs notes");
+ if( i>= 0 ) printf(msgs[i*4+3]);
+
+ i = find_section("btrfs notes");
+ if( i>= 0 ) printf(escape_man_page(msgs[i*4+3]));
+
+ i = find_section("man btrfs footer");
+ if( i>= 0 ) printf(msgs[i*4+3]);
+}
+
+static void usage(char *np){
+ printf("usage: %s --man-page|--c-array <file> [<file> [...]]\n", np);
+}
+
+int main(int argc, char **argv ){
+
+ int i;
+ if( argc < 3 || ( strcmp(argv[1],"--man-page") &&
+ strcmp(argv[1],"--c-array") )){
+ usage(argv[0]);
+ return 0;
+ }
+
+ for(i=2; i < argc ; i++)
+ search_in_file(argv[i]);
+
+ my_sort();
+
+ if(!strcmp(argv[1], "--man-page"))
+ dump_man_page();
+ else if (!strcmp(argv[1], "--c-array"))
+ dump_c_array();
+
+ return 0;
+
+}
--
1.7.6.233.gd79bc
++++++ 0110-Update-the-makefile-for-generating-the-man-page.patch ++++++
++++ 710 lines (skipped)
++++++ 0111-Show-the-help-messages-from-the-info-in-the-comment.patch ++++++
From 72aba9c58e83186db249f31198c03ebd0c34d7af Mon Sep 17 00:00:00 2001
From: Goffredo Baroncelli
Date: Sat, 16 Jul 2011 12:11:06 +0200
Subject: [PATCH 12/35] Show the help messages from the info in the comment.
The makefile is update in order to use the tool "helpextract" to extract
the info from the sources comments and to generate the file "helpmsg.c"
which contains an array of string with all the information.
Then the function "print_help" prints these information.
---
btrfs.c | 34 +++++++++++++++++++++++++++++-----
1 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/btrfs.c b/btrfs.c
index d2f6d4d..66b0d80 100644
--- a/btrfs.c
+++ b/btrfs.c
@@ -358,6 +358,8 @@ static struct Command commands[] = {
{ 0, 0, 0, 0 }
};
+extern char * help_messages[];
+
static char *get_prgname(char *programname)
{
char *np;
@@ -373,21 +375,43 @@ static char *get_prgname(char *programname)
static void print_help(char *programname, struct Command *cmd, int helptype)
{
char *pc;
+ int i;
+ char *adv_help;
+ char *std_help;
+
+ /* printf("\t%s %s ", programname, cmd->verb ); */
+
+ adv_help = cmd->adv_help;
+ std_help = cmd->help;
+
+ for(i = 0; help_messages[i]; i+= 4 ){
+ if(!strncmp(help_messages[i],"btrfs ",6) &&
+ !strcmp(help_messages[i]+6,cmd->verb) ){
+ if(help_messages[i+2])
+ std_help = help_messages[i+2];
+ if(help_messages[i+3])
+ adv_help = help_messages[i+3];
+ printf("\t%s\t\t",help_messages[i+1]);
+ break;
+ }
+ }
- printf("\t%s %s ", programname, cmd->verb );
+ if( !help_messages[i])
+ printf("\t%s %s ", programname, cmd->verb );
- if (helptype == ADVANCED_HELP && cmd->adv_help)
- for(pc = cmd->adv_help; *pc; pc++){
+ if (helptype == ADVANCED_HELP && adv_help){
+ for(pc = adv_help; *pc; pc++){
putchar(*pc);
if(*pc == '\n')
printf("\t\t");
}
- else
- for(pc = cmd->help; *pc; pc++){
+ }else{
+ for(pc = std_help; *pc; pc++){
putchar(*pc);
if(*pc == '\n')
printf("\t\t");
}
+ }
putchar('\n');
}
--
1.7.6.233.gd79bc
++++++ 0112-Update-the-makefile-for-generating-the-help-messages.patch ++++++
From e2d4509137cb8713b02a030e6116b041ae82588d Mon Sep 17 00:00:00 2001
From: Goffredo Baroncelli
Date: Sat, 16 Jul 2011 12:11:52 +0200
Subject: [PATCH 13/35] Update the makefile for generating the help messages.
Update the makefile for generating the help messages.
---
Makefile | 17 ++++++++++++++++-
1 files changed, 16 insertions(+), 1 deletions(-)
Index: btrfs-progs-v0.19-118-gfdb6c04/Makefile
===================================================================
--- btrfs-progs-v0.19-118-gfdb6c04.orig/Makefile
+++ btrfs-progs-v0.19-118-gfdb6c04/Makefile
@@ -38,8 +38,9 @@ all: version $(progs) manpages
version:
bash version.sh
-btrfs: $(objects) btrfs.o btrfs_cmds.o scrub.o
+btrfs: $(objects) btrfs.o btrfs_cmds.o scrub.o helpmsg.o
$(CC) $(CFLAGS) -o btrfs btrfs.o btrfs_cmds.o scrub.o \
+ helpmsg.o \
$(objects) $(LDFLAGS) $(LIBS) -lpthread
calc-size: $(objects) calc-size.o
@@ -108,6 +109,19 @@ man/btrfs.8.in: helpextract $(btrfs_man_
manpages: man/btrfs.8.in
cd man; make
+helpmsg.c: helpextract $(btrfs_man_page_source)
+ echo >$@ "/*"
+ echo >>$@ " * this file contains the help messages. It is "
+ echo >>$@ " * automatically generated. do not edit ! "
+ echo >>$@ " */"
+ echo >>$@
+ echo >>$@ "#define NULL 0"
+ echo >>$@
+
+ echo -n "char * help_messages[] = " >>$@
+ ./helpextract --c-array $(btrfs_man_page_source) >>$@
+ echo >>$@ ";"
+
install-man:
cd man; make install
@@ -115,6 +129,7 @@ clean :
rm -f man/btrfs.8.in
rm -f $(progs) cscope.out *.o .*.d btrfs-convert btrfs-image btrfs-select-super \
btrfs-zero-log btrfstune dir-test ioctl-test quick-test version.h
+ rm -f helpmsg.c
cd man; make clean
install: $(progs) install-man
++++++ 0113-Btrfs-progs-add-restriper-commands.patch ++++++
++++ 750 lines (skipped)
++++++ 0114-btrfs-progs-add-qgroup-commands.patch ++++++
++++ 1225 lines (skipped)
++++++ 0115-btrfs-progs-fixup-is_mounted-checks.patch ++++++
From 6ca37050db7e94257559da2b8e8009c2347ed798 Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Thu, 27 Oct 2011 16:23:14 -0400
Subject: [PATCH 16/35] btrfs-progs: fixup is_mounted checks
/proc/mounts contains device names that don't exist,
we end up erroring out because we're not able to stat
the device (that doesn't exist).
Fix this by allowing the mkfs when the target device doesn't exist.
Signed-off-by: Chris Mason
---
utils.c | 34 +++++++++++++++++++---------------
1 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/utils.c b/utils.c
index 1c27e14..6c96548 100644
--- a/utils.c
+++ b/utils.c
@@ -674,11 +674,11 @@ int is_same_blk_file(const char* a, const char* b)
char real_a[PATH_MAX];
char real_b[PATH_MAX];
- if(!realpath(a, real_a) ||
- !realpath(b, real_b))
- {
- return -errno;
- }
+ if(!realpath(a, real_a))
+ strcpy(real_a, a);
+
+ if (!realpath(b, real_b))
+ strcpy(real_b, b);
/* Identical path? */
if(strcmp(real_a, real_b) == 0)
@@ -719,8 +719,8 @@ int is_same_loop_file(const char* a, const char* b)
{
char res_a[PATH_MAX];
char res_b[PATH_MAX];
- const char* final_a;
- const char* final_b;
+ const char* final_a = NULL;
+ const char* final_b = NULL;
int ret;
/* Resolve a if it is a loop device */
@@ -729,10 +729,12 @@ int is_same_loop_file(const char* a, const char* b)
return 0;
return ret;
} else if (ret) {
- if ((ret = resolve_loop_device(a, res_a, sizeof(res_a))) < 0)
- return ret;
-
- final_a = res_a;
+ if ((ret = resolve_loop_device(a, res_a, sizeof(res_a))) < 0) {
+ if (errno != EPERM)
+ return ret;
+ }
+ else
+ final_a = res_a;
} else {
final_a = a;
}
@@ -743,10 +745,12 @@ int is_same_loop_file(const char* a, const char* b)
return 0;
return ret;
} else if (ret) {
- if((ret = resolve_loop_device(b, res_b, sizeof(res_b))) < 0)
- return ret;
-
- final_b = res_b;
+ if ((ret = resolve_loop_device(b, res_b, sizeof(res_b))) < 0) {
+ if (errno != EPERM)
+ return ret;
+ }
+ else
+ final_b = res_b;
} else {
final_b = b;
}
--
1.7.6.233.gd79bc
++++++ 0116-Btrfs-progs-add-an-option-for-specifying-the-root-to.patch ++++++
From 0e6aead68455a1043aed04e0557dc14af2cd6f60 Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Tue, 1 Nov 2011 14:26:20 -0400
Subject: [PATCH 17/35] Btrfs-progs: add an option for specifying the root to
restore
If the normal fs tree is hosed and the user has multiple subvolumes it's handy
to be able to specify just one of the subvolumes to restore. It's also handy if
a user only wants to restore say /home instead of his entire disk. Thanks,
Signed-off-by: Josef Bacik
---
restore.c | 32 ++++++++++++++++++++++++++++----
1 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/restore.c b/restore.c
index 250c9d3..38c4ded 100644
--- a/restore.c
+++ b/restore.c
@@ -760,13 +760,14 @@ int main(int argc, char **argv)
char dir_name[128];
u64 tree_location = 0;
u64 fs_location = 0;
+ u64 root_objectid = 0;
int len;
int ret;
int opt;
int super_mirror = 0;
int find_dir = 0;
- while ((opt = getopt(argc, argv, "sviot:u:df:")) != -1) {
+ while ((opt = getopt(argc, argv, "sviot:u:df:r:")) != -1) {
switch (opt) {
case 's':
get_snaps = 1;
@@ -809,6 +810,14 @@ int main(int argc, char **argv)
case 'd':
find_dir = 1;
break;
+ case 'r':
+ errno = 0;
+ root_objectid = (u64)strtoll(optarg, NULL, 10);
+ if (errno != 0) {
+ fprintf(stderr, "Root objectid not valid\n");
+ exit(1);
+ }
+ break;
default:
usage();
exit(1);
@@ -842,8 +851,6 @@ int main(int argc, char **argv)
}
}
- printf("Root objectid is %Lu\n", root->objectid);
-
memset(path_name, 0, 4096);
strncpy(dir_name, argv[optind + 1], 128);
@@ -856,6 +863,23 @@ int main(int argc, char **argv)
dir_name[len - 1] = '\0';
}
+ if (root_objectid != 0) {
+ struct btrfs_root *orig_root = root;
+
+ key.objectid = root_objectid;
+ key.type = BTRFS_ROOT_ITEM_KEY;
+ key.offset = (u64)-1;
+ root = btrfs_read_fs_root(orig_root->fs_info, &key);
+ if (IS_ERR(root)) {
+ fprintf(stderr, "Error reading root\n");
+ root = orig_root;
+ ret = 1;
+ goto out;
+ }
+ key.type = 0;
+ key.offset = 0;
+ }
+
if (find_dir) {
ret = find_first_dir(root, &key.objectid);
if (ret)
@@ -864,7 +888,7 @@ int main(int argc, char **argv)
key.objectid = BTRFS_FIRST_FREE_OBJECTID;
}
- ret = search_dir(root->fs_info->fs_root, &key, dir_name);
+ ret = search_dir(root, &key, dir_name);
out:
close_ctree(root);
--
1.7.6.233.gd79bc
++++++ 0117-Btrfs-progs-try-other-mirrors-if-decomression-fails.patch ++++++
From 9dee07a6365d2facddea9a501737dce92333c582 Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Fri, 4 Nov 2011 09:10:49 -0400
Subject: [PATCH 18/35] Btrfs-progs: try other mirrors if decomression fails
This will make the restore program fall back on other mirrors if it fails to
decompress an extent for whatever reason. Thanks,
Signed-off-by: Josef Bacik
---
restore.c | 47 +++++++++++++++++++++++++----------------------
1 files changed, 25 insertions(+), 22 deletions(-)
diff --git a/restore.c b/restore.c
index 38c4ded..f062a2b 100644
--- a/restore.c
+++ b/restore.c
@@ -61,7 +61,7 @@ static int decompress(char *inbuf, char *outbuf, u64 compress_len,
ret = inflate(&strm, Z_NO_FLUSH);
if (ret != Z_STREAM_END) {
(void)inflateEnd(&strm);
- fprintf(stderr, "ret is %d\n", ret);
+ fprintf(stderr, "failed to inflate: %d\n", ret);
return -1;
}
@@ -197,6 +197,8 @@ static int copy_one_extent(struct btrfs_root *root, int fd,
int compress;
int ret;
int dev_fd;
+ int mirror_num = 0;
+ int num_copies;
compress = btrfs_file_extent_compression(leaf, fi);
bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
@@ -225,12 +227,10 @@ static int copy_one_extent(struct btrfs_root *root, int fd,
again:
length = size_left;
ret = btrfs_map_block(&root->fs_info->mapping_tree, READ,
- bytenr, &length, &multi, 0);
+ bytenr, &length, &multi, mirror_num);
if (ret) {
- free(inbuf);
- free(outbuf);
fprintf(stderr, "Error mapping block %d\n", ret);
- return ret;
+ goto out;
}
device = multi->stripes[0].dev;
dev_fd = device->fd;
@@ -244,10 +244,9 @@ again:
done = pread(dev_fd, inbuf+count, length, dev_bytenr);
if (done < length) {
- free(inbuf);
- free(outbuf);
+ ret = -1;
fprintf(stderr, "Short read %d\n", errno);
- return -1;
+ goto out;
}
count += length;
@@ -255,41 +254,46 @@ again:
if (size_left)
goto again;
-
if (compress == BTRFS_COMPRESS_NONE) {
while (total < ram_size) {
done = pwrite(fd, inbuf+total, ram_size-total,
pos+total);
if (done < 0) {
- free(inbuf);
+ ret = -1;
fprintf(stderr, "Error writing: %d %s\n", errno, strerror(errno));
- return -1;
+ goto out;
}
total += done;
}
- free(inbuf);
- return 0;
+ ret = 0;
+ goto out;
}
ret = decompress(inbuf, outbuf, disk_size, ram_size);
- free(inbuf);
if (ret) {
- free(outbuf);
- return ret;
+ num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
+ bytenr, length);
+ mirror_num++;
+ if (mirror_num >= num_copies) {
+ ret = -1;
+ goto out;
+ }
+ fprintf(stderr, "Trying another mirror\n");
+ goto again;
}
while (total < ram_size) {
done = pwrite(fd, outbuf+total, ram_size-total, pos+total);
if (done < 0) {
- free(outbuf);
- fprintf(stderr, "Error writing: %d %s\n", errno, strerror(errno));
- return -1;
+ ret = -1;
+ goto out;
}
total += done;
}
+out:
+ free(inbuf);
free(outbuf);
-
- return 0;
+ return ret;
}
static int ask_to_continue(const char *file)
@@ -385,7 +389,6 @@ static int copy_file(struct btrfs_root *root, int fd, struct btrfs_key *key,
/* No more leaves to search */
btrfs_free_path(path);
goto set_size;
- return 0;
}
leaf = path->nodes[0];
} while (!leaf);
--
1.7.6.233.gd79bc
++++++ 0118-Btrfs-progs-try-other-mirrors-on-read-failure.patch ++++++
From ff0e1b17030a9b1e027c8b77f67ab44136e172ac Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Mon, 7 Nov 2011 16:41:01 -0500
Subject: [PATCH 19/35] Btrfs-progs: try other mirrors on read failure
If we hit a bad disk and the read doesn't work, try other mirrors in case we
have other disks with good copies. Thanks,
Signed-off-by: Josef Bacik
---
restore.c | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/restore.c b/restore.c
index f062a2b..4dabae2 100644
--- a/restore.c
+++ b/restore.c
@@ -244,9 +244,16 @@ again:
done = pread(dev_fd, inbuf+count, length, dev_bytenr);
if (done < length) {
- ret = -1;
- fprintf(stderr, "Short read %d\n", errno);
- goto out;
+ num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
+ bytenr, length);
+ mirror_num++;
+ if (mirror_num >= num_copies) {
+ ret = -1;
+ fprintf(stderr, "Exhausted mirrors trying to read\n");
+ goto out;
+ }
+ fprintf(stderr, "Trying another mirror\n");
+ goto again;
}
count += length;
--
1.7.6.233.gd79bc
++++++ 0119-btrfs-progs-Fix-error-handling-for-failed-reads-in-r.patch ++++++
From 16073605bb947e6acfa3b13b6280a90fed9b717a Mon Sep 17 00:00:00 2001
From: David Marcin
Date: Wed, 9 Nov 2011 13:23:28 -0800
Subject: [PATCH 20/35] btrfs-progs: Fix error handling for failed reads in
restore tool when mirrors exist
---
restore.c | 11 +++++++----
1 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/restore.c b/restore.c
index 4dabae2..389b107 100644
--- a/restore.c
+++ b/restore.c
@@ -197,7 +197,7 @@ static int copy_one_extent(struct btrfs_root *root, int fd,
int compress;
int ret;
int dev_fd;
- int mirror_num = 0;
+ int mirror_num = 1;
int num_copies;
compress = btrfs_file_extent_compression(leaf, fi);
@@ -240,14 +240,15 @@ again:
if (size_left < length)
length = size_left;
- size_left -= length;
done = pread(dev_fd, inbuf+count, length, dev_bytenr);
- if (done < length) {
+ /* Need both checks, or we miss negative values due to u64 conversion */
+ if (done < 0 || done < length) {
num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
bytenr, length);
mirror_num++;
- if (mirror_num >= num_copies) {
+ /* mirror_num is 1-indexed, so num_copies is a valid mirror. */
+ if (mirror_num > num_copies) {
ret = -1;
fprintf(stderr, "Exhausted mirrors trying to read\n");
goto out;
@@ -256,6 +257,8 @@ again:
goto again;
}
+ mirror_num = 1;
+ size_left -= length;
count += length;
bytenr += length;
if (size_left)
--
1.7.6.233.gd79bc
++++++ 0120-btrfs-progs-Check-metadata-mirrors-in-find-root.patch ++++++
From a1ebf7b951c6796039748601404aa01fd283ddef Mon Sep 17 00:00:00 2001
From: David Marcin
Date: Wed, 16 Nov 2011 12:18:08 -0800
Subject: [PATCH 21/35] btrfs-progs: Check metadata mirrors in find-root.
Signed-off-by: David Marcin
---
find-root.c | 13 ++++++++++++-
1 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/find-root.c b/find-root.c
index c0f38b8..2899632 100644
--- a/find-root.c
+++ b/find-root.c
@@ -361,6 +361,8 @@ static int find_root(struct btrfs_root *root)
while (1) {
u64 map_length = 4096;
u64 type;
+ int mirror_num;
+ int num_copies;
if (offset >
btrfs_super_total_bytes(&root->fs_info->super_copy)) {
@@ -377,8 +379,10 @@ static int find_root(struct btrfs_root *root)
}
offset = metadata_offset;
}
+ mirror_num = 1;
+ again:
err = __btrfs_map_block(&root->fs_info->mapping_tree, READ,
- offset, &map_length, &type, &multi, 0);
+ offset, &map_length, &type, &multi, mirror_num);
if (err) {
offset += map_length;
continue;
@@ -396,9 +400,16 @@ static int find_root(struct btrfs_root *root)
err = read_physical(root, fd, offset, bytenr, map_length);
if (!err) {
+ /* Found the root. */
ret = 0;
break;
} else if (err < 0) {
+ num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
+ offset, map_length);
+ mirror_num++;
+ if (mirror_num <= num_copies)
+ goto again;
+ /* Unrecoverable error in read. */
ret = err;
break;
}
--
1.7.6.233.gd79bc
++++++ 0121-restore-Split-output-directory-and-btrfs-local-path-.patch ++++++
From 266f413a32d774c68f41f488bb79fac6ad63e930 Mon Sep 17 00:00:00 2001
From: Peter Stuge
Date: Fri, 25 Nov 2011 01:03:57 +0100
Subject: [PATCH 22/35] restore: Split output directory and btrfs-local path
search_dir() parameters
search_dir() recurses down the btrfs tree, and used to take the output
path for every item (i.e. in the running system, output root directory
concatenated with btrfs-local pathname) passed as the only path
parameter. Moving the output root directory to a separate parameter
and passing the btrfs-local pathname for each file and directory
separately allows easy filtering based on the btrfs-local pathname.
Signed-off-by: Peter Stuge
Signed-off-by: Josef Bacik
---
restore.c | 15 ++++++++++-----
1 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/restore.c b/restore.c
index 389b107..0b92ed5 100644
--- a/restore.c
+++ b/restore.c
@@ -35,6 +35,7 @@
#include "volumes.h"
#include "utils.h"
+static char fs_name[4096];
static char path_name[4096];
static int get_snaps = 0;
static int verbose = 0;
@@ -450,7 +451,7 @@ set_size:
}
static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
- const char *dir)
+ const char *output_rootdir, const char *dir)
{
struct btrfs_path *path;
struct extent_buffer *leaf;
@@ -554,8 +555,11 @@ static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
type = btrfs_dir_type(leaf, dir_item);
btrfs_dir_item_key_to_cpu(leaf, dir_item, &location);
- snprintf(path_name, 4096, "%s/%s", dir, filename);
+ /* full path from root of btrfs being restored */
+ snprintf(fs_name, 4096, "%s/%s", dir, filename);
+ /* full path from system root */
+ snprintf(path_name, 4096, "%s%s", output_rootdir, fs_name);
/*
* At this point we're only going to restore directories and
@@ -603,7 +607,7 @@ static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
}
} else if (type == BTRFS_FT_DIR) {
struct btrfs_root *search_root = root;
- char *dir = strdup(path_name);
+ char *dir = strdup(fs_name);
if (!dir) {
fprintf(stderr, "Ran out of memory\n");
@@ -664,7 +668,8 @@ static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
return -1;
}
loops = 0;
- ret = search_dir(search_root, &location, dir);
+ ret = search_dir(search_root, &location,
+ output_rootdir, dir);
free(dir);
if (ret) {
if (ignore_errors)
@@ -901,7 +906,7 @@ int main(int argc, char **argv)
key.objectid = BTRFS_FIRST_FREE_OBJECTID;
}
- ret = search_dir(root, &key, dir_name);
+ ret = search_dir(root, &key, dir_name, "");
out:
close_ctree(root);
--
1.7.6.233.gd79bc
++++++ 0122-restore-Add-regex-matching-of-paths-and-files-to-be-.patch ++++++
From 2f0c2a29ab13b17ae1cc21effcf532f2447b7c8c Mon Sep 17 00:00:00 2001
From: Peter Stuge
Date: Fri, 25 Nov 2011 01:03:58 +0100
Subject: [PATCH 23/35] restore: Add regex matching of paths and files to be
restored
The option -m is used to specify the regex string. -c is used to
specify case insensitive matching. -i was already taken.
In order to restore only a single folder somewhere in the btrfs
tree, it is unfortunately neccessary to construct a slightly
nontrivial regex, e.g.:
restore -m '^/(|home(|/username(|/Desktop(|/.*))))$' /dev/sdb2 /output
This is needed in order to match each directory along the way to the
Desktop directory, as well as all contents below the Desktop directory.
Signed-off-by: Peter Stuge
Signed-off-by: Josef Bacik
---
restore.c | 40 ++++++++++++++++++++++++++++++++++------
1 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/restore.c b/restore.c
index 0b92ed5..e65746a 100644
--- a/restore.c
+++ b/restore.c
@@ -25,6 +25,8 @@
#include
#include
#include
+#include
+#include
#include "kerncompat.h"
#include "ctree.h"
#include "disk-io.h"
@@ -451,7 +453,8 @@ set_size:
}
static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
- const char *output_rootdir, const char *dir)
+ const char *output_rootdir, const char *dir,
+ const regex_t *mreg)
{
struct btrfs_path *path;
struct extent_buffer *leaf;
@@ -558,6 +561,9 @@ static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
/* full path from root of btrfs being restored */
snprintf(fs_name, 4096, "%s/%s", dir, filename);
+ if (REG_NOMATCH == regexec(mreg, fs_name, 0, NULL, 0))
+ goto next;
+
/* full path from system root */
snprintf(path_name, 4096, "%s%s", output_rootdir, fs_name);
@@ -669,7 +675,7 @@ static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
}
loops = 0;
ret = search_dir(search_root, &location,
- output_rootdir, dir);
+ output_rootdir, dir, mreg);
free(dir);
if (ret) {
if (ignore_errors)
@@ -690,8 +696,8 @@ next:
static void usage()
{
- fprintf(stderr, "Usage: restore [-svio] [-t disk offset] <device> "
- "<directory>\n");
+ fprintf(stderr, "Usage: restore [-svioc] [-t disk offset] "
+ "[-m regex] <device> <directory>\n");
}
static struct btrfs_root *open_fs(const char *dev, u64 root_location, int super_mirror)
@@ -784,8 +790,12 @@ int main(int argc, char **argv)
int opt;
int super_mirror = 0;
int find_dir = 0;
+ const char *match_regstr = NULL;
+ int match_cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
+ regex_t match_reg, *mreg = NULL;
+ char reg_err[256];
- while ((opt = getopt(argc, argv, "sviot:u:df:r:")) != -1) {
+ while ((opt = getopt(argc, argv, "sviot:u:df:r:cm:")) != -1) {
switch (opt) {
case 's':
get_snaps = 1;
@@ -836,6 +846,12 @@ int main(int argc, char **argv)
exit(1);
}
break;
+ case 'c':
+ match_cflags |= REG_ICASE;
+ break;
+ case 'm':
+ match_regstr = optarg;
+ break;
default:
usage();
exit(1);
@@ -906,9 +922,21 @@ int main(int argc, char **argv)
key.objectid = BTRFS_FIRST_FREE_OBJECTID;
}
- ret = search_dir(root, &key, dir_name, "");
+ if (match_regstr) {
+ ret = regcomp(&match_reg, match_regstr, match_cflags);
+ if (ret) {
+ regerror(ret, &match_reg, reg_err, sizeof(reg_err));
+ fprintf(stderr, "Regex compile failed: %s\n", reg_err);
+ goto out;
+ }
+ mreg = &match_reg;
+ }
+
+ ret = search_dir(root, &key, dir_name, "", mreg);
out:
+ if (mreg)
+ regfree(mreg);
close_ctree(root);
return ret;
}
--
1.7.6.233.gd79bc
++++++ 0123-btrfs-progs-In-find-root-dump-bytenr-for-every-slot.patch ++++++
From e8919ef79253ace49de01ba228290e4e0cafbfb7 Mon Sep 17 00:00:00 2001
From: David Marcin
Date: Mon, 21 Nov 2011 20:51:15 -0600
Subject: [PATCH 24/35] btrfs-progs: In find-root, dump bytenr for every slot.
Signed-off-by: David Marcin
---
find-root.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 59 insertions(+), 1 deletions(-)
diff --git a/find-root.c b/find-root.c
index 2899632..bd44e1f 100644
--- a/find-root.c
+++ b/find-root.c
@@ -258,8 +258,63 @@ out:
return NULL;
}
+static int dump_root_bytenr(struct btrfs_root *root, u64 bytenr, u64 gen)
+{
+ struct btrfs_root *tmp = malloc(sizeof(struct btrfs_root));
+ struct btrfs_path *path;
+ struct btrfs_key key;
+ struct btrfs_root_item ri;
+ struct extent_buffer *leaf;
+ struct btrfs_disk_key disk_key;
+ struct btrfs_key found_key;
+ int slot;
+ int ret;
+
+ if (!tmp)
+ return -ENOMEM;
+
+ __setup_root(4096, 4096, 4096, 4096, tmp,
+ root->fs_info, BTRFS_ROOT_TREE_OBJECTID);
+
+ tmp->node = read_tree_block(root, bytenr, 4096, gen);
+
+ key.objectid = 0;
+ key.type = BTRFS_ROOT_ITEM_KEY;
+ key.offset = -1;
+
+ path = btrfs_alloc_path();
+
+ /* Walk the slots of this root looking for BTRFS_ROOT_ITEM_KEYs. */
+ ret = btrfs_search_slot(NULL, tmp, &key, path, 0, 0);
+ BUG_ON(ret < 0);
+ while (1) {
+ leaf = path->nodes[0];
+ slot = path->slots[0];
+ if (slot >= btrfs_header_nritems(leaf)) {
+ ret = btrfs_next_leaf(tmp, path);
+ if (ret != 0)
+ break;
+ leaf = path->nodes[0];
+ slot = path->slots[0];
+ }
+ btrfs_item_key(leaf, &disk_key, path->slots[0]);
+ btrfs_disk_key_to_cpu(&found_key, &disk_key);
+ if (btrfs_key_type(&found_key) == BTRFS_ROOT_ITEM_KEY) {
+ unsigned long offset;
+
+ offset = btrfs_item_ptr_offset(leaf, slot);
+ read_extent_buffer(leaf, &ri, offset, sizeof(ri));
+ printf("Generation: %Lu Root bytenr: %Lu\n", gen, btrfs_root_bytenr(&ri));
+ }
+ path->slots[0]++;
+ }
+ btrfs_free_path(path);
+ free_extent_buffer(leaf);
+ return 0;
+}
+
static int search_iobuf(struct btrfs_root *root, void *iobuf,
- size_t iobuf_size, off_t offset)
+ size_t iobuf_size, off_t offset)
{
u64 gen = btrfs_super_generation(&root->fs_info->super_copy);
u64 objectid = search_objectid;
@@ -290,6 +345,9 @@ static int search_iobuf(struct btrfs_root *root, void *iobuf,
h_byte);
goto next;
}
+ /* Found some kind of root and it's fairly valid. */
+ if (dump_root_bytenr(root, h_byte, h_gen))
+ break;
if (h_gen != gen) {
fprintf(stderr, "Well block %Lu seems great, "
"but generation doesn't match, "
--
1.7.6.233.gd79bc
++++++ 0124-btrfs-progs-Add-utility-to-dump-all-superblocks-foun.patch ++++++
From db874f1e8924e86bbdee6600b0e5b3e6d11f9238 Mon Sep 17 00:00:00 2001
From: David Marcin
Date: Tue, 22 Nov 2011 10:08:00 -0800
Subject: [PATCH 25/35] btrfs-progs: Add utility to dump all superblocks found
on a device.
Signed-off-by: David Marcin
---
.gitignore | 4 ++
Makefile | 9 ++++-
btrfs-dump-super.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 98 insertions(+), 2 deletions(-)
create mode 100644 btrfs-dump-super.c
Index: btrfs-progs-v0.19-117-g6da41f2/.gitignore
===================================================================
--- btrfs-progs-v0.19-117-g6da41f2.orig/.gitignore
+++ btrfs-progs-v0.19-117-g6da41f2/.gitignore
@@ -3,12 +3,16 @@
version.h
man/*.gz
btrfs
+btrfs-corrupt-block
btrfs-debug-tree
+btrfs-dump-super
btrfs-map-logical
+btrfs-select-super
btrfs-show
btrfs-vol
btrfsck
btrfsctl
+calc-size
find-root
mkfs.btrfs
repair
Index: btrfs-progs-v0.19-117-g6da41f2/Makefile
===================================================================
--- btrfs-progs-v0.19-117-g6da41f2.orig/Makefile
+++ btrfs-progs-v0.19-117-g6da41f2/Makefile
@@ -17,7 +17,8 @@ LIBS=-luuid
RESTORE_LIBS=-lz
progs = btrfsctl mkfs.btrfs btrfs-debug-tree btrfs-show btrfs-vol btrfsck \
- btrfs btrfs-map-logical restore find-root calc-size btrfs-corrupt-block
+ btrfs btrfs-map-logical restore find-root calc-size btrfs-corrupt-block \
+ btrfs-dump-super
btrfs_man_page_source = btrfs.c btrfs_cmds.c scrub.c
@@ -76,6 +77,9 @@ btrfs-zero-log: $(objects) btrfs-zero-lo
btrfs-select-super: $(objects) btrfs-select-super.o
$(CC) $(CFLAGS) -o btrfs-select-super $(objects) btrfs-select-super.o $(LDFLAGS) $(LIBS)
+btrfs-dump-super: $(objects) btrfs-dump-super.o
+ $(CC) $(CFLAGS) -o btrfs-dump-super $(objects) btrfs-dump-super.o $(LDFLAGS) $(LIBS)
+
btrfstune: $(objects) btrfstune.o
$(CC) $(CFLAGS) -o btrfstune $(objects) btrfstune.o $(LDFLAGS) $(LIBS)
@@ -128,7 +132,8 @@ install-man:
clean :
rm -f man/btrfs.8.in
rm -f $(progs) cscope.out *.o .*.d btrfs-convert btrfs-image btrfs-select-super \
- btrfs-zero-log btrfstune dir-test ioctl-test quick-test version.h
+ btrfs-dump-super btrfs-zero-log btrfstune dir-test ioctl-test quick-test \
+ version.h
rm -f helpmsg.c
cd man; make clean
Index: btrfs-progs-v0.19-117-g6da41f2/btrfs-dump-super.c
===================================================================
--- /dev/null
+++ btrfs-progs-v0.19-117-g6da41f2/btrfs-dump-super.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2011 Google. 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.
+ */
+
+#define _XOPEN_SOURCE 500
+#define _GNU_SOURCE 1
+#include
+#include
+#include
+#include
+#include
+#include "kerncompat.h"
+#include "ctree.h"
+#include "disk-io.h"
+#include "version.h"
+
+static void print_usage(void)
+{
+ fprintf(stderr, "usage: btrfs-dump-super dev\n");
+ fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION);
+ exit(1);
+}
+
+static int read_block(const char* filename, u64 bytenr, struct btrfs_super_block* sb) {
+ int fd = open(filename, O_RDONLY, 0600);
+ int block_size = sizeof(struct btrfs_super_block);
+ int bytes_read = 0;
+
+ if (fd < 0) {
+ fprintf(stderr, "Could not open %s\n", filename);
+ return -1;
+ }
+
+ bytes_read = pread(fd, sb, block_size, bytenr);
+ if (bytes_read < block_size) {
+ fprintf(stderr, "Only read %d bytes of %d.\n", bytes_read, block_size);
+ }
+
+ close(fd);
+ return bytes_read;
+}
+
+int main(int ac, char **av)
+{
+ int i;
+
+ if (ac != 2)
+ print_usage();
+
+ for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
+ u64 bytenr = btrfs_sb_offset(i);
+ int fd;
+ struct btrfs_super_block sb;
+ int block_size = sizeof(struct btrfs_super_block);
+ char filename[1024];
+ int bytes_read = read_block(av[optind], bytenr, &sb);
+ if (bytes_read < block_size)
+ continue;
+
+ sprintf(filename, "/tmp/block.%s.%llu",
+ strrchr(av[optind], '/') + 1, bytenr);
+ fd = open(filename, O_CREAT|O_WRONLY, 0644);
+ if (block_size != pwrite(fd, &sb, block_size, 0)) {
+ fprintf(stderr, "Failed to dump superblock %d", i);
+ continue;
+ }
+ fprintf(stderr, "Dumped superblock %s:%d, gen %llu to %s.\n",
+ av[optind], i, sb.generation, filename);
+ close(fd);
+ }
+
+ return 0;
+}
++++++ 0125-btrfs-progs-Add-the-ability-to-use-the-earliest-supe.patch ++++++
From 6330d8d3b70c0ad35ce8048ccf69b3e96718ed53 Mon Sep 17 00:00:00 2001
From: David Marcin
Date: Mon, 21 Nov 2011 20:31:01 -0600
Subject: [PATCH 26/35] btrfs-progs: Add the ability to use the earliest super
found when opening the ctree.
Signed-off-by: David Marcin
---
convert.c | 6 +++---
disk-io.c | 21 ++++++++++++++-------
disk-io.h | 2 +-
volumes.c | 9 ++++++++-
volumes.h | 6 +++++-
5 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/convert.c b/convert.c
index 291dc27..c036f46 100644
--- a/convert.c
+++ b/convert.c
@@ -2386,7 +2386,7 @@ int do_convert(const char *devname, int datacsum, int packing, int noxattr)
fprintf(stderr, "unable to update system chunk\n");
goto fail;
}
- root = open_ctree_fd(fd, devname, super_bytenr, O_RDWR);
+ root = open_ctree_fd(fd, devname, super_bytenr, O_RDWR, 0);
if (!root) {
fprintf(stderr, "unable to open ctree\n");
goto fail;
@@ -2447,7 +2447,7 @@ int do_convert(const char *devname, int datacsum, int packing, int noxattr)
goto fail;
}
- root = open_ctree_fd(fd, devname, 0, O_RDWR);
+ root = open_ctree_fd(fd, devname, 0, O_RDWR, 0);
if (!root) {
fprintf(stderr, "unable to open ctree\n");
goto fail;
@@ -2546,7 +2546,7 @@ int do_rollback(const char *devname, int force)
fprintf(stderr, "unable to open %s\n", devname);
goto fail;
}
- root = open_ctree_fd(fd, devname, 0, O_RDWR);
+ root = open_ctree_fd(fd, devname, 0, O_RDWR, 0);
if (!root) {
fprintf(stderr, "unable to open ctree\n");
goto fail;
diff --git a/disk-io.c b/disk-io.c
index 408b2d5..a161f15 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -580,7 +580,7 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
return fs_info->dev_root;
if (location->objectid == BTRFS_CSUM_TREE_OBJECTID)
return fs_info->csum_root;
-
+
BUG_ON(location->objectid == BTRFS_TREE_RELOC_OBJECTID ||
location->offset != (u64)-1);
@@ -602,7 +602,8 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
}
struct btrfs_root *__open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
- u64 root_tree_bytenr, int writes)
+ u64 root_tree_bytenr, int writes,
+ int use_earliest_bdev)
{
u32 sectorsize;
u32 nodesize;
@@ -677,8 +678,14 @@ struct btrfs_root *__open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
fs_info->super_bytenr = sb_bytenr;
disk_super = &fs_info->super_copy;
- ret = btrfs_read_dev_super(fs_devices->latest_bdev,
- disk_super, sb_bytenr);
+ if (use_earliest_bdev) {
+ ret = btrfs_read_dev_super(fs_devices->earliest_bdev,
+ disk_super, sb_bytenr);
+ } else {
+ ret = btrfs_read_dev_super(fs_devices->latest_bdev,
+ disk_super, sb_bytenr);
+ }
+
if (ret) {
printk("No valid btrfs found\n");
goto out_devices;
@@ -847,7 +854,7 @@ struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, int writes)
fprintf (stderr, "Could not open %s\n", filename);
return NULL;
}
- root = __open_ctree_fd(fp, filename, sb_bytenr, 0, writes);
+ root = __open_ctree_fd(fp, filename, sb_bytenr, 0, writes, 0);
close(fp);
return root;
@@ -871,9 +878,9 @@ struct btrfs_root *open_ctree_recovery(const char *filename, u64 sb_bytenr,
}
struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
- int writes)
+ int writes, int use_earliest_bdev)
{
- return __open_ctree_fd(fp, path, sb_bytenr, 0, writes);
+ return __open_ctree_fd(fp, path, sb_bytenr, 0, writes, use_earliest_bdev);
}
int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr)
diff --git a/disk-io.h b/disk-io.h
index 2048fcf..8fdcd91 100644
--- a/disk-io.h
+++ b/disk-io.h
@@ -45,7 +45,7 @@ int clean_tree_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct extent_buffer *buf);
struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, int writes);
struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
- int writes);
+ int writes, int use_earliest_bdev);
struct btrfs_root *open_ctree_recovery(const char *filename, u64 sb_bytenr,
u64 root_tree_bytenr);
int close_ctree(struct btrfs_root *root);
diff --git a/volumes.c b/volumes.c
index 03bfb8c..cde20ad 100644
--- a/volumes.c
+++ b/volumes.c
@@ -99,6 +99,8 @@ static int device_list_add(const char *path,
memcpy(fs_devices->fsid, disk_super->fsid, BTRFS_FSID_SIZE);
fs_devices->latest_devid = devid;
fs_devices->latest_trans = found_transid;
+ fs_devices->earliest_devid = devid;
+ fs_devices->earliest_trans = found_transid;
fs_devices->lowest_devid = (u64)-1;
device = NULL;
} else {
@@ -133,8 +135,11 @@ static int device_list_add(const char *path,
if (found_transid > fs_devices->latest_trans) {
fs_devices->latest_devid = devid;
fs_devices->latest_trans = found_transid;
+ } else if (found_transid < fs_devices->earliest_trans) {
+ fs_devices->earliest_devid = devid;
+ fs_devices->earliest_trans = found_transid;
}
- if (fs_devices->lowest_devid > devid) {
+ if (devid < fs_devices->lowest_devid) {
fs_devices->lowest_devid = devid;
}
*fs_devices_ret = fs_devices;
@@ -183,6 +188,8 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices, int flags)
if (device->devid == fs_devices->latest_devid)
fs_devices->latest_bdev = fd;
+ if (device->devid == fs_devices->earliest_devid)
+ fs_devices->earliest_bdev = fd;
if (device->devid == fs_devices->lowest_devid)
fs_devices->lowest_bdev = fd;
device->fd = fd;
diff --git a/volumes.h b/volumes.h
index 7104d36..08c53e4 100644
--- a/volumes.h
+++ b/volumes.h
@@ -64,11 +64,15 @@ struct btrfs_device {
struct btrfs_fs_devices {
u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
- /* the device with this id has the most recent coyp of the super */
+ /* the device with this id has the most recent copy of the super */
u64 latest_devid;
u64 latest_trans;
+ /* the device with this id has the least recent copy of the super */
+ u64 earliest_devid;
+ u64 earliest_trans;
u64 lowest_devid;
int latest_bdev;
+ int earliest_bdev;
int lowest_bdev;
struct list_head devices;
struct list_head list;
--
1.7.6.233.gd79bc
++++++ 0126-btrfs-progs-Use-oldest-super-for-btrfs-select-super..patch ++++++
From a780325614c0d89c9c0ea6779ada5af512b6e319 Mon Sep 17 00:00:00 2001
From: David Marcin
Date: Tue, 22 Nov 2011 10:09:35 -0800
Subject: [PATCH 27/35] btrfs-progs: Use oldest super for btrfs-select-super.
Add required confirmation to btrfs-select-super.
Signed-off-by: David Marcin
---
btrfs-select-super.c | 38 ++++++++++++++++++++++++++++++--------
disk-io.c | 2 +-
2 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/btrfs-select-super.c b/btrfs-select-super.c
index 51eb9c9..4d27f1b 100644
--- a/btrfs-select-super.c
+++ b/btrfs-select-super.c
@@ -34,7 +34,9 @@
static void print_usage(void)
{
- fprintf(stderr, "usage: btrfs-select-super -s number dev\n");
+ fprintf(stderr, "usage: btrfs-select-super [-c] [-e] -s number dev\n");
+ fprintf(stderr, " -c Commit changes to disk [IRREVERSIBLE]\n");
+ fprintf(stderr, " -e Use the earliest super found, may help recover transid verify problems\n");
fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION);
exit(1);
}
@@ -45,10 +47,13 @@ int main(int ac, char **av)
int ret;
int num;
u64 bytenr = 0;
+ int commit = 0;
+ int use_lowest_bdev = 0;
+ int fp;
while(1) {
int c;
- c = getopt(ac, av, "s:");
+ c = getopt(ac, av, "s:ce");
if (c < 0)
break;
switch(c) {
@@ -58,6 +63,12 @@ int main(int ac, char **av)
printf("using SB copy %d, bytenr %llu\n", num,
(unsigned long long)bytenr);
break;
+ case 'c':
+ commit = 1;
+ break;
+ case 'e':
+ use_earliest_bdev = 1;
+ break;
default:
print_usage();
}
@@ -74,22 +85,33 @@ int main(int ac, char **av)
radix_tree_init();
- if((ret = check_mounted(av[optind])) < 0) {
+ if ((ret = check_mounted(av[optind])) < 0) {
fprintf(stderr, "Could not check mount status: %s\n", strerror(-ret));
return ret;
- } else if(ret) {
+ } else if (ret) {
fprintf(stderr, "%s is currently mounted. Aborting.\n", av[optind]);
return -EBUSY;
}
- root = open_ctree(av[optind], bytenr, 1);
+ fp = open(av[optind], O_CREAT|O_RDRW, 0600);
+ if (fp < 0) {
+ fprintf(stderr, "Could not open %s\n", av[optind]);
+ return 1;
+ }
+ root = open_ctree_fd(fp, av[optind], bytenr, 1, use_earliest_bdev);
if (root == NULL)
return 1;
- /* make the super writing code think we've read the first super */
- root->fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET;
- ret = write_all_supers(root);
+ fprintf(stderr, "Found superblock with generation %llu.\n", root->fs_info->super_copy.generation);
+
+ if (commit) {
+ fprintf(stderr, "Committing...\n");
+
+ /* make the super writing code think we've read the first super */
+ root->fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET;
+ ret = write_all_supers(root);
+ }
/* we don't close the ctree or anything, because we don't want a real
* transaction commit. We just want the super copy we pulled off the
diff --git a/disk-io.c b/disk-io.c
index a161f15..9585057 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -871,7 +871,7 @@ struct btrfs_root *open_ctree_recovery(const char *filename, u64 sb_bytenr,
fprintf (stderr, "Could not open %s\n", filename);
return NULL;
}
- root = __open_ctree_fd(fp, filename, sb_bytenr, root_tree_bytenr, 0);
+ root = __open_ctree_fd(fp, filename, sb_bytenr, root_tree_bytenr, 0, 0);
close(fp);
return root;
--
1.7.6.233.gd79bc
++++++ 0127-btrfs-progs-add-lzo-compression-support-to-restore.patch ++++++
From 2fe46117d3cde3737a1600195883e63ab4c59a8d Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Fri, 2 Dec 2011 10:07:43 -0500
Subject: [PATCH 28/35] btrfs-progs: add lzo compression support to restore
This patch simply adds support to decompress lzo compressed extents in restore.
Signed-off-by: Josef Bacik
---
Makefile | 2 +-
restore.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 84 insertions(+), 7 deletions(-)
diff --git a/Makefile b/Makefile
index 548f88c..64de4e6 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ INSTALL = install
prefix ?= /usr/local
bindir = $(prefix)/bin
LIBS=-luuid
-RESTORE_LIBS=-lz
+RESTORE_LIBS=-lz -llzo2
progs = btrfsctl mkfs.btrfs btrfs-debug-tree btrfs-show btrfs-vol btrfsck \
btrfs btrfs-map-logical restore find-root calc-size btrfs-corrupt-block \
diff --git a/restore.c b/restore.c
index e65746a..6433378 100644
--- a/restore.c
+++ b/restore.c
@@ -27,6 +27,8 @@
#include
#include
#include
+#include
+#include
#include "kerncompat.h"
#include "ctree.h"
#include "disk-io.h"
@@ -44,8 +46,12 @@ static int verbose = 0;
static int ignore_errors = 0;
static int overwrite = 0;
-static int decompress(char *inbuf, char *outbuf, u64 compress_len,
- u64 decompress_len)
+#define LZO_LEN 4
+#define PAGE_CACHE_SIZE 4096
+#define lzo1x_worst_compress(x) ((x) + ((x) / 16) + 64 + 3)
+
+static int decompress_zlib(char *inbuf, char *outbuf, u64 compress_len,
+ u64 decompress_len)
{
z_stream strm;
int ret;
@@ -71,6 +77,73 @@ static int decompress(char *inbuf, char *outbuf, u64 compress_len,
(void)inflateEnd(&strm);
return 0;
}
+static inline size_t read_compress_length(unsigned char *buf)
+{
+ __le32 dlen;
+ memcpy(&dlen, buf, LZO_LEN);
+ return le32_to_cpu(dlen);
+}
+
+static int decompress_lzo(unsigned char *inbuf, char *outbuf, u64 compress_len,
+ u64 *decompress_len)
+{
+ size_t new_len;
+ size_t in_len;
+ size_t out_len = 0;
+ size_t tot_len;
+ size_t tot_in;
+ int ret;
+
+ ret = lzo_init();
+ if (ret != LZO_E_OK) {
+ fprintf(stderr, "lzo init returned %d\n", ret);
+ return -1;
+ }
+
+ tot_len = read_compress_length(inbuf);
+ inbuf += LZO_LEN;
+ tot_in = LZO_LEN;
+
+ while (tot_in < tot_len) {
+ in_len = read_compress_length(inbuf);
+ inbuf += LZO_LEN;
+ tot_in += LZO_LEN;
+
+ new_len = lzo1x_worst_compress(PAGE_CACHE_SIZE);
+ ret = lzo1x_decompress_safe((const unsigned char *)inbuf, in_len,
+ (unsigned char *)outbuf, &new_len, NULL);
+ if (ret != LZO_E_OK) {
+ fprintf(stderr, "failed to inflate: %d\n", ret);
+ return -1;
+ }
+ out_len += new_len;
+ outbuf += new_len;
+ inbuf += in_len;
+ tot_in += in_len;
+ }
+
+ *decompress_len = out_len;
+
+ return 0;
+}
+
+static int decompress(char *inbuf, char *outbuf, u64 compress_len,
+ u64 *decompress_len, int compress)
+{
+ switch (compress) {
+ case BTRFS_COMPRESS_ZLIB:
+ return decompress_zlib(inbuf, outbuf, compress_len,
+ *decompress_len);
+ case BTRFS_COMPRESS_LZO:
+ return decompress_lzo((unsigned char *)inbuf, outbuf, compress_len,
+ decompress_len);
+ default:
+ break;
+ }
+
+ fprintf(stderr, "invalid compression type: %d\n", compress);
+ return -1;
+}
int next_leaf(struct btrfs_root *root, struct btrfs_path *path)
{
@@ -133,11 +206,11 @@ static int copy_one_inline(int fd, struct btrfs_path *path, u64 pos)
struct btrfs_file_extent_item *fi;
char buf[4096];
char *outbuf;
+ u64 ram_size;
ssize_t done;
unsigned long ptr;
int ret;
int len;
- int ram_size;
int compress;
fi = btrfs_item_ptr(leaf, path->slots[0],
@@ -165,7 +238,7 @@ static int copy_one_inline(int fd, struct btrfs_path *path, u64 pos)
return -1;
}
- ret = decompress(buf, outbuf, len, ram_size);
+ ret = decompress(buf, outbuf, len, &ram_size, compress);
if (ret) {
free(outbuf);
return ret;
@@ -174,7 +247,7 @@ static int copy_one_inline(int fd, struct btrfs_path *path, u64 pos)
done = pwrite(fd, outbuf, ram_size, pos);
free(outbuf);
if (done < len) {
- fprintf(stderr, "Short compressed inline write, wanted %d, "
+ fprintf(stderr, "Short compressed inline write, wanted %Lu, "
"did %zd: %d\n", ram_size, done, errno);
return -1;
}
@@ -196,6 +269,7 @@ static int copy_one_extent(struct btrfs_root *root, int fd,
u64 length;
u64 size_left;
u64 dev_bytenr;
+ u64 offset;
u64 count = 0;
int compress;
int ret;
@@ -207,8 +281,11 @@ static int copy_one_extent(struct btrfs_root *root, int fd,
bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
disk_size = btrfs_file_extent_disk_num_bytes(leaf, fi);
ram_size = btrfs_file_extent_ram_bytes(leaf, fi);
+ offset = btrfs_file_extent_offset(leaf, fi);
size_left = disk_size;
+ if (offset)
+ printf("offset is %Lu\n", offset);
/* we found a hole */
if (disk_size == 0)
return 0;
@@ -282,7 +359,7 @@ again:
goto out;
}
- ret = decompress(inbuf, outbuf, disk_size, ram_size);
+ ret = decompress(inbuf, outbuf, disk_size, &ram_size, compress);
if (ret) {
num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
bytenr, length);
--
1.7.6.233.gd79bc
++++++ 0128-btrfs-progs-fix-regexec-to-only-work-if-we-actually-.patch ++++++
From 1b8b3c3579ee127b174a850213df7ad81edd5710 Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Fri, 2 Dec 2011 12:52:15 -0500
Subject: [PATCH 29/35] btrfs-progs: fix regexec to only work if we actually
have a regexec
We were unconditionally executing our regular expression, even though we may not
have one, so check to make sure mreg is not null before calling regexec.
Thanks,
Signed-off-by: Josef Bacik
---
restore.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/restore.c b/restore.c
index 6433378..a4ccb18 100644
--- a/restore.c
+++ b/restore.c
@@ -638,7 +638,7 @@ static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
/* full path from root of btrfs being restored */
snprintf(fs_name, 4096, "%s/%s", dir, filename);
- if (REG_NOMATCH == regexec(mreg, fs_name, 0, NULL, 0))
+ if (mreg && REG_NOMATCH == regexec(mreg, fs_name, 0, NULL, 0))
goto next;
/* full path from system root */
--
1.7.6.233.gd79bc
++++++ 0129-btrfs-progs-Fix-compilation-errors-with-btrfs-select.patch ++++++
From 3ceceda914e19a3f7982c5050e6ffb23522071f2 Mon Sep 17 00:00:00 2001
From: David Marcin
Date: Tue, 6 Dec 2011 12:14:54 -0800
Subject: [PATCH 30/35] btrfs-progs: Fix compilation errors with
btrfs-select-super.c introduced by refactoring.
Signed-off-by: David Marcin
---
btrfs-select-super.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/btrfs-select-super.c b/btrfs-select-super.c
index 4d27f1b..079986a 100644
--- a/btrfs-select-super.c
+++ b/btrfs-select-super.c
@@ -48,7 +48,7 @@ int main(int ac, char **av)
int num;
u64 bytenr = 0;
int commit = 0;
- int use_lowest_bdev = 0;
+ int use_earliest_bdev = 0;
int fp;
while(1) {
@@ -93,7 +93,7 @@ int main(int ac, char **av)
return -EBUSY;
}
- fp = open(av[optind], O_CREAT|O_RDRW, 0600);
+ fp = open(av[optind], O_CREAT|O_RDWR, 0600);
if (fp < 0) {
fprintf(stderr, "Could not open %s\n", av[optind]);
return 1;
--
1.7.6.233.gd79bc
++++++ 0130-Btrfs-progs-fix-restore-to-fall-back-to-the-broken-o.patch ++++++
From fb0cfed5d3500e76ce30c6a9803ee1720bf1b4a5 Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Wed, 7 Dec 2011 14:13:35 -0500
Subject: [PATCH 31/35] Btrfs-progs: fix restore to fall back to the broken
open_ctree
We don't need most of the roots when doing restore, like the extent tree. So if
the recovery open_ctree fails because it's trying to open one of these useless
roots just fall back to open_ctree_broken. This will just open the chunk root
which is the bare minimum of what we need to operate. Then from there we can
setup the tree_root and the fs_root, and if either of those are gone we can't
restore anyway. Thanks,
Signed-off-by: Josef Bacik
---
disk-io.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++
disk-io.h | 1 +
find-root.c | 166 -----------------------------------------------------------
restore.c | 48 +++++++++++++++++-
4 files changed, 198 insertions(+), 167 deletions(-)
diff --git a/disk-io.c b/disk-io.c
index 9585057..8a8071c 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -883,6 +883,156 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
return __open_ctree_fd(fp, path, sb_bytenr, 0, writes, use_earliest_bdev);
}
+struct btrfs_root *open_ctree_broken(int fd, const char *device)
+{
+ u32 sectorsize;
+ u32 nodesize;
+ u32 leafsize;
+ u32 blocksize;
+ u32 stripesize;
+ u64 generation;
+ struct btrfs_root *tree_root = malloc(sizeof(struct btrfs_root));
+ struct btrfs_root *extent_root = malloc(sizeof(struct btrfs_root));
+ struct btrfs_root *chunk_root = malloc(sizeof(struct btrfs_root));
+ struct btrfs_root *dev_root = malloc(sizeof(struct btrfs_root));
+ struct btrfs_root *csum_root = malloc(sizeof(struct btrfs_root));
+ struct btrfs_fs_info *fs_info = malloc(sizeof(*fs_info));
+ int ret;
+ struct btrfs_super_block *disk_super;
+ struct btrfs_fs_devices *fs_devices = NULL;
+ u64 total_devs;
+ u64 features;
+
+ ret = btrfs_scan_one_device(fd, device, &fs_devices,
+ &total_devs, BTRFS_SUPER_INFO_OFFSET);
+
+ if (ret) {
+ fprintf(stderr, "No valid Btrfs found on %s\n", device);
+ goto out;
+ }
+
+ if (total_devs != 1) {
+ ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1);
+ if (ret)
+ goto out;
+ }
+
+ memset(fs_info, 0, sizeof(*fs_info));
+ fs_info->tree_root = tree_root;
+ fs_info->extent_root = extent_root;
+ fs_info->chunk_root = chunk_root;
+ fs_info->dev_root = dev_root;
+ fs_info->csum_root = csum_root;
+
+ fs_info->readonly = 1;
+
+ extent_io_tree_init(&fs_info->extent_cache);
+ extent_io_tree_init(&fs_info->free_space_cache);
+ extent_io_tree_init(&fs_info->block_group_cache);
+ extent_io_tree_init(&fs_info->pinned_extents);
+ extent_io_tree_init(&fs_info->pending_del);
+ extent_io_tree_init(&fs_info->extent_ins);
+ cache_tree_init(&fs_info->fs_root_cache);
+
+ cache_tree_init(&fs_info->mapping_tree.cache_tree);
+
+ mutex_init(&fs_info->fs_mutex);
+ fs_info->fs_devices = fs_devices;
+ INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
+ INIT_LIST_HEAD(&fs_info->space_info);
+
+ __setup_root(4096, 4096, 4096, 4096, tree_root,
+ fs_info, BTRFS_ROOT_TREE_OBJECTID);
+
+ ret = btrfs_open_devices(fs_devices, O_RDONLY);
+ if (ret)
+ goto out_cleanup;
+
+ fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET;
+ disk_super = &fs_info->super_copy;
+ ret = btrfs_read_dev_super(fs_devices->latest_bdev,
+ disk_super, BTRFS_SUPER_INFO_OFFSET);
+ if (ret) {
+ printk("No valid btrfs found\n");
+ goto out_devices;
+ }
+
+ memcpy(fs_info->fsid, &disk_super->fsid, BTRFS_FSID_SIZE);
+
+
+ features = btrfs_super_incompat_flags(disk_super) &
+ ~BTRFS_FEATURE_INCOMPAT_SUPP;
+ if (features) {
+ printk("couldn't open because of unsupported "
+ "option features (%Lx).\n", features);
+ goto out_devices;
+ }
+
+ features = btrfs_super_incompat_flags(disk_super);
+ if (!(features & BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF)) {
+ features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF;
+ btrfs_set_super_incompat_flags(disk_super, features);
+ }
+
+ nodesize = btrfs_super_nodesize(disk_super);
+ leafsize = btrfs_super_leafsize(disk_super);
+ sectorsize = btrfs_super_sectorsize(disk_super);
+ stripesize = btrfs_super_stripesize(disk_super);
+ tree_root->nodesize = nodesize;
+ tree_root->leafsize = leafsize;
+ tree_root->sectorsize = sectorsize;
+ tree_root->stripesize = stripesize;
+
+ ret = btrfs_read_sys_array(tree_root);
+ if (ret)
+ goto out_devices;
+ blocksize = btrfs_level_size(tree_root,
+ btrfs_super_chunk_root_level(disk_super));
+ generation = btrfs_super_chunk_root_generation(disk_super);
+
+ __setup_root(nodesize, leafsize, sectorsize, stripesize,
+ chunk_root, fs_info, BTRFS_CHUNK_TREE_OBJECTID);
+
+ chunk_root->node = read_tree_block(chunk_root,
+ btrfs_super_chunk_root(disk_super),
+ blocksize, generation);
+ if (!chunk_root->node) {
+ printk("Couldn't read chunk root\n");
+ goto out_devices;
+ }
+
+ read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid,
+ (unsigned long)btrfs_header_chunk_tree_uuid(chunk_root->node),
+ BTRFS_UUID_SIZE);
+
+ if (!(btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_METADUMP)) {
+ ret = btrfs_read_chunk_tree(chunk_root);
+ if (ret)
+ goto out_chunk;
+ }
+
+ return fs_info->chunk_root;
+out_chunk:
+ free_extent_buffer(fs_info->chunk_root->node);
+out_devices:
+ close_all_devices(fs_info);
+out_cleanup:
+ extent_io_tree_cleanup(&fs_info->extent_cache);
+ extent_io_tree_cleanup(&fs_info->free_space_cache);
+ extent_io_tree_cleanup(&fs_info->block_group_cache);
+ extent_io_tree_cleanup(&fs_info->pinned_extents);
+ extent_io_tree_cleanup(&fs_info->pending_del);
+ extent_io_tree_cleanup(&fs_info->extent_ins);
+out:
+ free(tree_root);
+ free(extent_root);
+ free(chunk_root);
+ free(dev_root);
+ free(csum_root);
+ free(fs_info);
+ return NULL;
+}
+
int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr)
{
u8 fsid[BTRFS_FSID_SIZE];
diff --git a/disk-io.h b/disk-io.h
index 8fdcd91..2b1fcd5 100644
--- a/disk-io.h
+++ b/disk-io.h
@@ -48,6 +48,7 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
int writes, int use_earliest_bdev);
struct btrfs_root *open_ctree_recovery(const char *filename, u64 sb_bytenr,
u64 root_tree_bytenr);
+struct btrfs_root *open_ctree_broken(int fd, const char *device);
int close_ctree(struct btrfs_root *root);
int write_all_supers(struct btrfs_root *root);
int write_ctree_super(struct btrfs_trans_handle *trans,
diff --git a/find-root.c b/find-root.c
index bd44e1f..e0bc069 100644
--- a/find-root.c
+++ b/find-root.c
@@ -92,172 +92,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
return 0;
}
-static int close_all_devices(struct btrfs_fs_info *fs_info)
-{
- struct list_head *list;
- struct list_head *next;
- struct btrfs_device *device;
-
- return 0;
-
- list = &fs_info->fs_devices->devices;
- list_for_each(next, list) {
- device = list_entry(next, struct btrfs_device, dev_list);
- close(device->fd);
- }
- return 0;
-}
-
-static struct btrfs_root *open_ctree_broken(int fd, const char *device)
-{
- u32 sectorsize;
- u32 nodesize;
- u32 leafsize;
- u32 blocksize;
- u32 stripesize;
- u64 generation;
- struct btrfs_root *tree_root = malloc(sizeof(struct btrfs_root));
- struct btrfs_root *extent_root = malloc(sizeof(struct btrfs_root));
- struct btrfs_root *chunk_root = malloc(sizeof(struct btrfs_root));
- struct btrfs_root *dev_root = malloc(sizeof(struct btrfs_root));
- struct btrfs_root *csum_root = malloc(sizeof(struct btrfs_root));
- struct btrfs_fs_info *fs_info = malloc(sizeof(*fs_info));
- int ret;
- struct btrfs_super_block *disk_super;
- struct btrfs_fs_devices *fs_devices = NULL;
- u64 total_devs;
- u64 features;
-
- ret = btrfs_scan_one_device(fd, device, &fs_devices,
- &total_devs, BTRFS_SUPER_INFO_OFFSET);
-
- if (ret) {
- fprintf(stderr, "No valid Btrfs found on %s\n", device);
- goto out;
- }
-
- if (total_devs != 1) {
- ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1);
- if (ret)
- goto out;
- }
-
- memset(fs_info, 0, sizeof(*fs_info));
- fs_info->tree_root = tree_root;
- fs_info->extent_root = extent_root;
- fs_info->chunk_root = chunk_root;
- fs_info->dev_root = dev_root;
- fs_info->csum_root = csum_root;
-
- fs_info->readonly = 1;
-
- extent_io_tree_init(&fs_info->extent_cache);
- extent_io_tree_init(&fs_info->free_space_cache);
- extent_io_tree_init(&fs_info->block_group_cache);
- extent_io_tree_init(&fs_info->pinned_extents);
- extent_io_tree_init(&fs_info->pending_del);
- extent_io_tree_init(&fs_info->extent_ins);
- cache_tree_init(&fs_info->fs_root_cache);
-
- cache_tree_init(&fs_info->mapping_tree.cache_tree);
-
- mutex_init(&fs_info->fs_mutex);
- fs_info->fs_devices = fs_devices;
- INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
- INIT_LIST_HEAD(&fs_info->space_info);
-
- __setup_root(4096, 4096, 4096, 4096, tree_root,
- fs_info, BTRFS_ROOT_TREE_OBJECTID);
-
- ret = btrfs_open_devices(fs_devices, O_RDONLY);
- if (ret)
- goto out_cleanup;
-
- fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET;
- disk_super = &fs_info->super_copy;
- ret = btrfs_read_dev_super(fs_devices->latest_bdev,
- disk_super, BTRFS_SUPER_INFO_OFFSET);
- if (ret) {
- printk("No valid btrfs found\n");
- goto out_devices;
- }
-
- memcpy(fs_info->fsid, &disk_super->fsid, BTRFS_FSID_SIZE);
-
-
- features = btrfs_super_incompat_flags(disk_super) &
- ~BTRFS_FEATURE_INCOMPAT_SUPP;
- if (features) {
- printk("couldn't open because of unsupported "
- "option features (%Lx).\n", features);
- goto out_devices;
- }
-
- features = btrfs_super_incompat_flags(disk_super);
- if (!(features & BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF)) {
- features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF;
- btrfs_set_super_incompat_flags(disk_super, features);
- }
-
- nodesize = btrfs_super_nodesize(disk_super);
- leafsize = btrfs_super_leafsize(disk_super);
- sectorsize = btrfs_super_sectorsize(disk_super);
- stripesize = btrfs_super_stripesize(disk_super);
- tree_root->nodesize = nodesize;
- tree_root->leafsize = leafsize;
- tree_root->sectorsize = sectorsize;
- tree_root->stripesize = stripesize;
-
- ret = btrfs_read_sys_array(tree_root);
- if (ret)
- goto out_devices;
- blocksize = btrfs_level_size(tree_root,
- btrfs_super_chunk_root_level(disk_super));
- generation = btrfs_super_chunk_root_generation(disk_super);
-
- __setup_root(nodesize, leafsize, sectorsize, stripesize,
- chunk_root, fs_info, BTRFS_CHUNK_TREE_OBJECTID);
-
- chunk_root->node = read_tree_block(chunk_root,
- btrfs_super_chunk_root(disk_super),
- blocksize, generation);
- if (!chunk_root->node) {
- printk("Couldn't read chunk root\n");
- goto out_devices;
- }
-
- read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid,
- (unsigned long)btrfs_header_chunk_tree_uuid(chunk_root->node),
- BTRFS_UUID_SIZE);
-
- if (!(btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_METADUMP)) {
- ret = btrfs_read_chunk_tree(chunk_root);
- if (ret)
- goto out_chunk;
- }
-
- return fs_info->chunk_root;
-out_chunk:
- free_extent_buffer(fs_info->chunk_root->node);
-out_devices:
- close_all_devices(fs_info);
-out_cleanup:
- extent_io_tree_cleanup(&fs_info->extent_cache);
- extent_io_tree_cleanup(&fs_info->free_space_cache);
- extent_io_tree_cleanup(&fs_info->block_group_cache);
- extent_io_tree_cleanup(&fs_info->pinned_extents);
- extent_io_tree_cleanup(&fs_info->pending_del);
- extent_io_tree_cleanup(&fs_info->extent_ins);
-out:
- free(tree_root);
- free(extent_root);
- free(chunk_root);
- free(dev_root);
- free(csum_root);
- free(fs_info);
- return NULL;
-}
-
static int dump_root_bytenr(struct btrfs_root *root, u64 bytenr, u64 gen)
{
struct btrfs_root *tmp = malloc(sizeof(struct btrfs_root));
diff --git a/restore.c b/restore.c
index a4ccb18..90d54e4 100644
--- a/restore.c
+++ b/restore.c
@@ -779,9 +779,13 @@ static void usage()
static struct btrfs_root *open_fs(const char *dev, u64 root_location, int super_mirror)
{
+ struct btrfs_key key;
struct btrfs_root *root;
u64 bytenr;
+ u64 generation;
+ u32 blocksize;
int i;
+ int dev_fd;
for (i = super_mirror; i < BTRFS_SUPER_MIRROR_MAX; i++) {
bytenr = btrfs_sb_offset(i);
@@ -791,7 +795,49 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location, int super_
fprintf(stderr, "Could not open root, trying backup super\n");
}
- return NULL;
+ fprintf(stderr, "Ok couldn't open the root the normal way, trying "
+ "the broken way\n");
+
+ dev_fd = open(dev, O_RDONLY);
+ if (dev_fd < 0) {
+ fprintf(stderr, "Failed to open device %s\n", dev);
+ return NULL;
+ }
+
+ root = open_ctree_broken(dev_fd, dev);
+ close(dev_fd);
+ if (!root) {
+ fprintf(stderr, "Broken ctree open failed\n");
+ return NULL;
+ }
+ if (!root_location)
+ bytenr = btrfs_super_root(&root->fs_info->super_copy);
+
+ blocksize = btrfs_level_size(root,
+ btrfs_super_root_level(&root->fs_info->super_copy));
+ generation = btrfs_super_generation(&root->fs_info->super_copy);
+
+ root->fs_info->tree_root->node = read_tree_block(root, bytenr,
+ blocksize,
+ generation);
+ if (!root->fs_info->tree_root->node) {
+ fprintf(stderr, "Couldn't read tree node\n");
+ close_ctree(root);
+ return NULL;
+ }
+
+ key.objectid = BTRFS_FS_TREE_OBJECTID;
+ key.type = BTRFS_ROOT_ITEM_KEY;
+ key.offset = (u64)-1;
+
+ root->fs_info->fs_root = btrfs_read_fs_root(root->fs_info, &key);
+ if (!root->fs_info->fs_root) {
+ fprintf(stderr, "Couldn't read fs_root\n");
+ close_ctree(root);
+ return NULL;
+ }
+
+ return root->fs_info->fs_root;
}
static int find_first_dir(struct btrfs_root *root, u64 *objectid)
--
1.7.6.233.gd79bc
++++++ 0131-Btrfs-progs-don-t-bug-out-if-we-can-t-find-the-last-.patch ++++++
From 412d4f1fe3a14c7e61efbd0ad4280323de71606a Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Wed, 7 Dec 2011 15:54:13 -0500
Subject: [PATCH 32/35] Btrfs-progs: don't bug out if we can't find the last
root
Return an error instead of BUG()'ing out.
Signed-off-by: Josef Bacik
---
root-tree.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/root-tree.c b/root-tree.c
index 782472c..7a6ae0a 100644
--- a/root-tree.c
+++ b/root-tree.c
@@ -43,6 +43,11 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
BUG_ON(ret == 0);
l = path->nodes[0];
+ if (path->slots[0] == 0) {
+ ret = -ENOENT;
+ goto out;
+ }
+
BUG_ON(path->slots[0] == 0);
slot = path->slots[0] - 1;
btrfs_item_key_to_cpu(l, &found_key, slot);
--
1.7.6.233.gd79bc
++++++ 0132-Btrfs-progs-make-find_and_setup_root-return-an-error.patch ++++++
From df8b44a2980ace8b2e7483b96a661907e20b8a4c Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Wed, 7 Dec 2011 16:11:23 -0500
Subject: [PATCH 33/35] Btrfs-progs: make find_and_setup_root return an error
Don't BUG(), return an error so the recovery program can work its mojo.
Signed-off-by: Josef Bacik
---
disk-io.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/disk-io.c b/disk-io.c
index 8a8071c..b0b9502 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -438,13 +438,15 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
root, fs_info, objectid);
ret = btrfs_find_last_root(tree_root, objectid,
&root->root_item, &root->root_key);
- BUG_ON(ret);
+ if (ret)
+ return ret;
blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
generation = btrfs_root_generation(&root->root_item);
root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
blocksize, generation);
- BUG_ON(!root->node);
+ if (!root->node)
+ return -ENOENT;
return 0;
}
--
1.7.6.233.gd79bc
++++++ 0133-Btrfs-progs-check-return-value-properly.patch ++++++
From 4686f96637316b509cb16c657b73b40a329be6db Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Thu, 8 Dec 2011 17:24:54 -0500
Subject: [PATCH 34/35] Btrfs-progs: check return value properly
We were checking for a null root coming back from btrfs_read_fs_root but thats
not right since it returns a ERR_PTR. Thanks,
Signed-off-by: Josef Bacik
---
restore.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/restore.c b/restore.c
index 90d54e4..398c49a 100644
--- a/restore.c
+++ b/restore.c
@@ -831,8 +831,8 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location, int super_
key.offset = (u64)-1;
root->fs_info->fs_root = btrfs_read_fs_root(root->fs_info, &key);
- if (!root->fs_info->fs_root) {
- fprintf(stderr, "Couldn't read fs_root\n");
+ if (IS_ERR(root->fs_info->fs_root)) {
+ fprintf(stderr, "Couldn't read fs_root: %d\n", PTR_ERR(root));
close_ctree(root);
return NULL;
}
--
1.7.6.233.gd79bc
++++++ 0134-Btrfs-progs-give-restore-a-list-roots-option.patch ++++++
From 9bb7aa76e43f4942f5fa398bf00778067859f66c Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Fri, 9 Dec 2011 14:09:18 -0500
Subject: [PATCH 35/35] Btrfs-progs: give restore a list roots option
Since restore has the ability to open really really screwed up file systems, add
a list roots option to it so we can still get the contents of the tree root on a
horribly broken fs. Thanks,
Signed-off-by: Josef Bacik
---
restore.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 88 insertions(+), 7 deletions(-)
diff --git a/restore.c b/restore.c
index 398c49a..95daef2 100644
--- a/restore.c
+++ b/restore.c
@@ -773,11 +773,71 @@ next:
static void usage()
{
- fprintf(stderr, "Usage: restore [-svioc] [-t disk offset] "
+ fprintf(stderr, "Usage: restore [-sviocl] [-t disk offset] "
"[-m regex] <device> <directory>\n");
}
-static struct btrfs_root *open_fs(const char *dev, u64 root_location, int super_mirror)
+static int do_list_roots(struct btrfs_root *root)
+{
+ struct btrfs_key key;
+ struct btrfs_key found_key;
+ struct btrfs_disk_key disk_key;
+ struct btrfs_path *path;
+ struct extent_buffer *leaf;
+ struct btrfs_root_item ri;
+ unsigned long offset;
+ int slot;
+ int ret;
+
+ root = root->fs_info->tree_root;
+ path = btrfs_alloc_path();
+ if (!path) {
+ fprintf(stderr, "Failed to alloc path\n");
+ return -1;
+ }
+
+ key.offset = 0;
+ key.objectid = 0;
+ key.type = BTRFS_ROOT_ITEM_KEY;
+
+ ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to do search %d\n", ret);
+ btrfs_free_path(path);
+ return -1;
+ }
+
+ while (1) {
+ leaf = path->nodes[0];
+ slot = path->slots[0];
+ if (slot >= btrfs_header_nritems(leaf)) {
+ ret = btrfs_next_leaf(root, path);
+ if (ret)
+ break;
+ leaf = path->nodes[0];
+ slot = path->slots[0];
+ }
+ btrfs_item_key(leaf, &disk_key, slot);
+ btrfs_disk_key_to_cpu(&found_key, &disk_key);
+ if (btrfs_key_type(&found_key) != BTRFS_ROOT_ITEM_KEY) {
+ path->slots[0]++;
+ continue;
+ }
+
+ offset = btrfs_item_ptr_offset(leaf, slot);
+ read_extent_buffer(leaf, &ri, offset, sizeof(ri));
+ printf(" tree ");
+ btrfs_print_key(&disk_key);
+ printf(" %Lu level %d\n", btrfs_root_bytenr(&ri),
+ btrfs_root_level(&ri));
+ path->slots[0]++;
+ }
+ btrfs_free_path(path);
+
+ return 0;
+}
+
+static struct btrfs_root *open_fs(const char *dev, u64 root_location, int super_mirror, int list_roots)
{
struct btrfs_key key;
struct btrfs_root *root;
@@ -791,7 +851,7 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location, int super_
bytenr = btrfs_sb_offset(i);
root = open_ctree_recovery(dev, bytenr, root_location);
if (root)
- return root;
+ goto out;
fprintf(stderr, "Could not open root, trying backup super\n");
}
@@ -826,16 +886,27 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location, int super_
return NULL;
}
+ if (list_roots)
+ goto out;
+
key.objectid = BTRFS_FS_TREE_OBJECTID;
key.type = BTRFS_ROOT_ITEM_KEY;
key.offset = (u64)-1;
root->fs_info->fs_root = btrfs_read_fs_root(root->fs_info, &key);
if (IS_ERR(root->fs_info->fs_root)) {
- fprintf(stderr, "Couldn't read fs_root: %d\n", PTR_ERR(root));
+ fprintf(stderr, "Couldn't read fs_root: %ld\n", PTR_ERR(root));
close_ctree(root);
return NULL;
}
+out:
+ if (list_roots) {
+ int ret = do_list_roots(root);
+ if (ret) {
+ root = NULL;
+ close_ctree(root);
+ }
+ }
return root->fs_info->fs_root;
}
@@ -917,8 +988,9 @@ int main(int argc, char **argv)
int match_cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
regex_t match_reg, *mreg = NULL;
char reg_err[256];
+ int list_roots = 0;
- while ((opt = getopt(argc, argv, "sviot:u:df:r:cm:")) != -1) {
+ while ((opt = getopt(argc, argv, "sviot:u:df:r:cm:l")) != -1) {
switch (opt) {
case 's':
get_snaps = 1;
@@ -975,13 +1047,19 @@ int main(int argc, char **argv)
case 'm':
match_regstr = optarg;
break;
+ case 'l':
+ list_roots = 1;
+ break;
default:
usage();
exit(1);
}
}
- if (optind + 1 >= argc) {
+ if (!list_roots && optind + 1 >= argc) {
+ usage();
+ exit(1);
+ } else if (list_roots && optind >= argc) {
usage();
exit(1);
}
@@ -995,10 +1073,13 @@ int main(int argc, char **argv)
return -EBUSY;
}
- root = open_fs(argv[optind], tree_location, super_mirror);
+ root = open_fs(argv[optind], tree_location, super_mirror, list_roots);
if (root == NULL)
return 1;
+ if (list_roots)
+ goto out;
+
if (fs_location != 0) {
free_extent_buffer(root->node);
root->node = read_tree_block(root, fs_location, 4096, 0);
--
1.7.6.233.gd79bc
++++++ 0135-Btrfs-progs-fix-compiler-warning-of-extent-tree.c.patch ++++++
From 243a10fc066200621fbdee91eb28a53f5cc91d81 Mon Sep 17 00:00:00 2001
From: Tsutomu Itoh
Date: Tue, 1 Nov 2011 12:20:42 +0900
Subject: [PATCH 135/138] Btrfs-progs: fix compiler warning of extent-tree.c
In recovery-beta, following compiler warning was displayed.
gcc -Wp,-MMD,./.extent-tree.o.d,-MT,extent-tree.o -Wall -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -g -O0 -c extent-tree.c
extent-tree.c: In function 'lookup_inline_extent_backref':
extent-tree.c:1071: warning: format '%u' expects type 'unsigned int', but argument 3 has type 'long unsigned int'
Signed-off-by: Tsutomu Itoh
---
extent-tree.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/extent-tree.c b/extent-tree.c
index 5bed3c2..5144d57 100644
--- a/extent-tree.c
+++ b/extent-tree.c
@@ -1068,7 +1068,7 @@ static int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
#endif
if (item_size < sizeof(*ei)) {
printf("Size is %u, needs to be %u, slot %d\n", item_size,
- sizeof(*ei), path->slots[0]);
+ (u32)sizeof(*ei), path->slots[0]);
btrfs_print_leaf(root, leaf);
return -EINVAL;
}
--
1.7.6.233.gd79bc
++++++ 0136-Btrfs-progs-change-the-way-mkfs-picks-raid-profiles.patch ++++++
From 6b74bd1ecd84d86cad6aaa1fd643de6f3f3c40b8 Mon Sep 17 00:00:00 2001
From: Ilya Dryomov
Date: Tue, 1 Nov 2011 23:27:39 +0200
Subject: [PATCH 136/138] Btrfs-progs: change the way mkfs picks raid profiles
Currently mkfs in response to
mkfs.btrfs -d raid10 dev1 dev2
instead of telling "you can't do that" creates a SINGLE on two devices,
and only rebalance can transform it to raid0. Generally, it never warns
users about decisions it makes and it's not at all obvious which profile
it picks when.
Fix this by checking the number of effective devices and reporting back
if the specified profile is impossible to create. Do not create FS in
case invalid profile was given.
Signed-off-by: Ilya Dryomov
---
mkfs.c | 46 +++++++++++++++++++++++++++++++++++-----------
1 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/mkfs.c b/mkfs.c
index be236d0..d39c5a7 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -228,12 +228,26 @@ static int create_one_raid_group(struct btrfs_trans_handle *trans,
static int create_raid_groups(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 data_profile,
- u64 metadata_profile, int mixed)
+ int data_profile_opt, u64 metadata_profile,
+ int metadata_profile_opt, int mixed)
{
u64 num_devices = btrfs_super_num_devices(&root->fs_info->super_copy);
u64 allowed;
int ret;
+ /*
+ * Set default profiles according to number of added devices.
+ * For mixed groups defaults are single/single.
+ */
+ if (!metadata_profile_opt && !mixed) {
+ metadata_profile = (num_devices > 1) ?
+ BTRFS_BLOCK_GROUP_RAID1 : BTRFS_BLOCK_GROUP_DUP;
+ }
+ if (!data_profile_opt && !mixed) {
+ data_profile = (num_devices > 1) ?
+ BTRFS_BLOCK_GROUP_RAID0 : 0; /* raid0 or single */
+ }
+
if (num_devices == 1)
allowed = BTRFS_BLOCK_GROUP_DUP;
else if (num_devices >= 4) {
@@ -242,6 +256,19 @@ static int create_raid_groups(struct btrfs_trans_handle *trans,
} else
allowed = BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1;
+ if (metadata_profile & ~allowed) {
+ fprintf(stderr, "unable to create FS with metadata "
+ "profile %llu (%llu devices)\n", metadata_profile,
+ num_devices);
+ exit(1);
+ }
+ if (data_profile & ~allowed) {
+ fprintf(stderr, "unable to create FS with data "
+ "profile %llu (%llu devices)\n", data_profile,
+ num_devices);
+ exit(1);
+ }
+
if (allowed & metadata_profile) {
u64 meta_flags = BTRFS_BLOCK_GROUP_METADATA;
@@ -326,15 +353,16 @@ static u64 parse_profile(char *s)
if (strcmp(s, "raid0") == 0) {
return BTRFS_BLOCK_GROUP_RAID0;
} else if (strcmp(s, "raid1") == 0) {
- return BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_DUP;
+ return BTRFS_BLOCK_GROUP_RAID1;
} else if (strcmp(s, "raid10") == 0) {
- return BTRFS_BLOCK_GROUP_RAID10 | BTRFS_BLOCK_GROUP_DUP;
+ return BTRFS_BLOCK_GROUP_RAID10;
} else if (strcmp(s, "single") == 0) {
return 0;
} else {
fprintf(stderr, "Unknown option %s\n", s);
print_usage();
}
+ /* not reached */
return 0;
}
@@ -1172,8 +1200,8 @@ int main(int ac, char **av)
u64 dev_block_count = 0;
u64 blocks[7];
u64 alloc_start = 0;
- u64 metadata_profile = BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_DUP;
- u64 data_profile = BTRFS_BLOCK_GROUP_RAID0;
+ u64 metadata_profile = 0;
+ u64 data_profile = 0;
u32 leafsize = getpagesize();
u32 sectorsize = 4096;
u32 nodesize = leafsize;
@@ -1311,11 +1339,6 @@ int main(int ac, char **av)
}
}
if (mixed) {
- if (!metadata_profile_opt)
- metadata_profile = 0;
- if (!data_profile_opt)
- data_profile = 0;
-
if (metadata_profile != data_profile) {
fprintf(stderr, "With mixed block groups data and metadata "
"profiles must be the same\n");
@@ -1400,7 +1423,8 @@ int main(int ac, char **av)
raid_groups:
if (!source_dir_set) {
ret = create_raid_groups(trans, root, data_profile,
- metadata_profile, mixed);
+ data_profile_opt, metadata_profile,
+ metadata_profile_opt, mixed);
BUG_ON(ret);
}
--
1.7.6.233.gd79bc
++++++ 0137-Btrfs-progs-fail-gracefully-on-error-from-open_ctree.patch ++++++
From 670b953e28c25f835b713a22b03b9b0f86d8e025 Mon Sep 17 00:00:00 2001
From: Ilya Dryomov
Date: Tue, 1 Nov 2011 23:47:22 +0200
Subject: [PATCH 137/138] Btrfs-progs: fail gracefully on error from
open_ctree()
Error checking block got moved mistakenly exposing us to a potential
segmentation fault.
Signed-off-by: Ilya Dryomov
---
mkfs.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/mkfs.c b/mkfs.c
index d39c5a7..d4d13af 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -1359,7 +1359,12 @@ int main(int ac, char **av)
fprintf(stderr, "error during mkfs %d\n", ret);
exit(1);
}
+
root = open_ctree(file, 0, O_RDWR);
+ if (!root) {
+ fprintf(stderr, "ctree init failed\n");
+ return -1;
+ }
root->fs_info->alloc_start = alloc_start;
ret = make_root_dir(root, mixed);
@@ -1374,10 +1379,6 @@ int main(int ac, char **av)
goto raid_groups;
btrfs_register_one_device(file);
- if (!root) {
- fprintf(stderr, "ctree init failed\n");
- return -1;
- }
zero_end = 1;
while(ac-- > 0) {
--
1.7.6.233.gd79bc
++++++ 0138-Btrfs-progs-bugfix-for-scrubbing-single-devices.patch ++++++
From d439a663a5ba789f7542163317264a6b4dbbe3f2 Mon Sep 17 00:00:00 2001
From: Arne Jansen
Date: Tue, 29 Nov 2011 08:40:28 +0100
Subject: [PATCH 138/138] Btrfs-progs: bugfix for scrubbing single devices
Scrub can be invoked to scrub only a single device of a (mounted) filesystem.
The code determines whether the given path is a mountpoint of a filesystem
by issueing a btrfs-specific ioctl to it. Only in case of EINVAL it assumed
it may be a device, all other errnos just caused it fail, but some devices
(correctly) return ENOTTY. This patch adds this to the error check.
Signed-off-by: Arne Jansen
---
scrub.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/scrub.c b/scrub.c
index 66761c5..5b0bf16 100644
--- a/scrub.c
+++ b/scrub.c
@@ -987,7 +987,7 @@ static int scrub_fs_info(int fd, char *path,
memset(fi_args, 0, sizeof(*fi_args));
ret = ioctl(fd, BTRFS_IOC_FS_INFO, fi_args);
- if (ret && errno == EINVAL) {
+ if (ret && (errno == EINVAL || errno == ENOTTY)) {
/* path is no mounted btrfs. try if it's a device */
ret = check_mounted_where(fd, path, mp, sizeof(mp),
&fs_devices_mnt);
--
1.7.6.233.gd79bc
++++++ 0900-Revert-btrfs-progs-add-qgroup-commands.patch ++++++
++++ 1164 lines (skipped)
++++++ 0901-Revert-Btrfs-progs-add-restriper-commands.patch ++++++
++++ 750 lines (skipped)
++++++ Plug-Memory-leak-in-find_and_setup_log_root.patch ++++++
commit a2fe2e1b978f724f53d025461e65adb4e030d043
Author: Dirk Mueller
Date: Thu Dec 16 20:40:34 2010 +0100
[PATCH] Plug Memory leak in find_and_setup_log_root()
The error path forgets to free a previously allocated
memory structure.
Index: btrfs-progs-v0.19-116-g13eced9/disk-io.c
===================================================================
--- btrfs-progs-v0.19-116-g13eced9.orig/disk-io.c
+++ btrfs-progs-v0.19-116-g13eced9/disk-io.c
@@ -454,11 +454,13 @@ static int find_and_setup_log_root(struc
{
u32 blocksize;
u64 blocknr = btrfs_super_log_root(disk_super);
- struct btrfs_root *log_root = malloc(sizeof(struct btrfs_root));
+ struct btrfs_root *log_root;
if (blocknr == 0)
return 0;
+ log_root = malloc(sizeof(struct btrfs_root));
+
blocksize = btrfs_level_size(tree_root,
btrfs_super_log_root_level(disk_super));
++++++ boot-btrfs.sh ++++++
--- /var/tmp/diff_new_pack.gc4Frh/_old 2011-12-19 17:26:50.000000000 +0100
+++ /var/tmp/diff_new_pack.gc4Frh/_new 2011-12-19 17:26:50.000000000 +0100
@@ -1,4 +1,10 @@
-#!/bin/bash
-#%stage: filesystem
+#!/bin/bash -e
+#%stage: block
#%if: "$rootfstype" = "btrfs"
-#%programs: /sbin/btrfs /sbin/btrfs-zero-log /sbin/btrfs-convert /sbin/btrfs-select-super /sbin/btrfs-image /sbin/btrfstune /sbin/btrfs-restore /sbin/btrfs-find-root /sbin/btrfsck /sbin/mkfs.btrfs
+#%programs: /sbin/btrfs /sbin/btrfs-zero-log /sbin/btrfs-convert /sbin/btrfs-select-super /sbin/btrfs-image /sbin/btrfstune /sbin/btrfs-restore /sbin/btrfs-find-root /sbin/btrfsck /sbin/mkfs.btrfs /sbin/btrfs-dump-super
+
+modprobe btrfs
+
+if [ -x /sbin/btrfs ]; then
+ /sbin/btrfs dev scan >& /dev/null
+fi
++++++ btrfs-progs-fix-open_ctree_usage_segfaults.patch ++++++
--- btrfs-progs-v0.19-118-gfdb6c04.orig/btrfs-image.c
+++ btrfs-progs-v0.19-118-gfdb6c04/btrfs-image.c
@@ -491,6 +491,11 @@ static int create_metadump(const char *i
int ret;
root = open_ctree(input, 0, 0);
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
+ exit(1);
+ }
+
BUG_ON(root->nodesize != root->leafsize);
ret = metadump_init(&metadump, root, out, num_threads,
--- btrfs-progs-v0.19-118-gfdb6c04.orig/btrfs-select-super.c
+++ btrfs-progs-v0.19-118-gfdb6c04/btrfs-select-super.c
@@ -100,8 +100,10 @@ int main(int ac, char **av)
}
root = open_ctree_fd(fp, av[optind], bytenr, 1, use_earliest_bdev);
- if (root == NULL)
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
return 1;
+ }
fprintf(stderr, "Found superblock with generation %llu.\n", root->fs_info->super_copy.generation);
--- btrfs-progs-v0.19-118-gfdb6c04.orig/btrfslabel.c
+++ btrfs-progs-v0.19-118-gfdb6c04/btrfslabel.c
@@ -46,7 +46,7 @@
#define GET_LABEL 3
#define SET_LABEL 4
-static void change_label_unmounted(char *dev, char *nLabel)
+static int change_label_unmounted(char *dev, char *nLabel)
{
struct btrfs_root *root;
struct btrfs_trans_handle *trans;
@@ -55,6 +55,10 @@ static void change_label_unmounted(char
* and as read-write.
*/
root = open_ctree(dev, 0, 1);
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
+ return -1;
+ }
trans = btrfs_start_transaction(root, 1);
strncpy(root->fs_info->super_copy.label, nLabel, BTRFS_LABEL_SIZE);
@@ -62,9 +66,10 @@ static void change_label_unmounted(char
/* Now we close it since we are done. */
close_ctree(root);
+ return 0;
}
-static void get_label_unmounted(char *dev)
+static int get_label_unmounted(char *dev)
{
struct btrfs_root *root;
@@ -72,11 +77,16 @@ static void get_label_unmounted(char *de
* and as read-only.
*/
root = open_ctree(dev, 0, 0);
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
+ return -1;
+ }
fprintf(stdout, "%s\n", root->fs_info->super_copy.label);
/* Now we close it since we are done. */
close_ctree(root);
+ return 0;
}
int get_label(char *btrfs_dev)
@@ -95,8 +105,7 @@ int get_label(char *btrfs_dev)
fprintf(stderr, "FATAL: the filesystem has to be unmounted\n");
return -2;
}
- get_label_unmounted(btrfs_dev);
- return 0;
+ return get_label_unmounted(btrfs_dev);
}
@@ -116,6 +125,5 @@ int set_label(char *btrfs_dev, char *nLa
fprintf(stderr, "FATAL: the filesystem has to be unmounted\n");
return -2;
}
- change_label_unmounted(btrfs_dev, nLabel);
- return 0;
+ return change_label_unmounted(btrfs_dev, nLabel);
}
--- btrfs-progs-v0.19-118-gfdb6c04.orig/btrfstune.c
+++ btrfs-progs-v0.19-118-gfdb6c04/btrfstune.c
@@ -108,6 +108,11 @@ int main(int argc, char *argv[])
root = open_ctree(device, 0, 1);
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
+ return 1;
+ }
+
if (seeding_flag) {
ret = update_seeding_flag(root, seeding_value);
if (!ret)
--- btrfs-progs-v0.19-118-gfdb6c04.orig/dir-test.c
+++ btrfs-progs-v0.19-118-gfdb6c04/dir-test.c
@@ -436,6 +436,12 @@ int main(int ac, char **av)
radix_tree_init();
root = open_ctree(av[ac-1], &super, 0);
+
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
+ return 1;
+ }
+
trans = btrfs_start_transaction(root, 1);
dir_oid = btrfs_super_root_dir(&super);
@@ -479,6 +485,11 @@ int main(int ac, char **av)
btrfs_header_nritems(&root->node->node.header));
close_ctree(root, &super);
root = open_ctree("dbfile", &super, 0);
+
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
+ return 1;
+ }
}
while(count--) {
ret = ops[op](trans, root, &radix);
--- btrfs-progs-v0.19-118-gfdb6c04.orig/find-root.c
+++ btrfs-progs-v0.19-118-gfdb6c04/find-root.c
@@ -351,8 +351,11 @@ int main(int argc, char **argv)
root = open_ctree_broken(dev_fd, argv[optind]);
close(dev_fd);
- if (!root)
+
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
exit(1);
+ }
csum_size = btrfs_super_csum_size(&root->fs_info->super_copy);
ret = find_root(root);
--- btrfs-progs-v0.19-118-gfdb6c04.orig/mkfs.c
+++ btrfs-progs-v0.19-118-gfdb6c04/mkfs.c
@@ -1362,8 +1362,9 @@ int main(int ac, char **av)
root = open_ctree(file, 0, O_RDWR);
if (!root) {
- fprintf(stderr, "ctree init failed\n");
- return -1;
+ fprintf(stderr, "Open ctree failed\n");
+ close (fd);
+ exit(1);
}
root->fs_info->alloc_start = alloc_start;
--- btrfs-progs-v0.19-118-gfdb6c04.orig/quick-test.c
+++ btrfs-progs-v0.19-118-gfdb6c04/quick-test.c
@@ -52,6 +52,10 @@ int main(int ac, char **av) {
radix_tree_init();
root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR);
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
+ exit(1);
+ }
trans = btrfs_start_transaction(root, 1);
srand(55);
btrfs_set_key_type(&ins, BTRFS_STRING_ITEM_KEY);
@@ -75,6 +79,10 @@ int main(int ac, char **av) {
close_ctree(root);
exit(1);
root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR);
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
+ exit(1);
+ }
printf("starting search\n");
srand(55);
for (i = 0; i < run_size; i++) {
@@ -94,6 +102,10 @@ int main(int ac, char **av) {
close_ctree(root);
root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR);
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
+ exit(1);
+ }
printf("node %p level %d total ptrs %d free spc %lu\n", root->node,
btrfs_header_level(root->node),
btrfs_header_nritems(root->node),
@@ -122,6 +134,10 @@ int main(int ac, char **av) {
close_ctree(root);
root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR);
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
+ exit(1);
+ }
trans = btrfs_start_transaction(root, 1);
srand(128);
for (i = 0; i < run_size; i++) {
@@ -138,6 +154,10 @@ int main(int ac, char **av) {
close_ctree(root);
root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, O_RDWR);
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
+ exit(1);
+ }
srand(128);
printf("starting search2\n");
for (i = 0; i < run_size; i++) {
--- btrfs-progs-v0.19-118-gfdb6c04.orig/random-test.c
+++ btrfs-progs-v0.19-118-gfdb6c04/random-test.c
@@ -356,6 +356,10 @@ int main(int ac, char **av)
struct btrfs_trans_handle *trans;
radix_tree_init();
root = open_ctree("dbfile", &super);
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
+ exit(1);
+ }
fill_radix(root, &radix);
signal(SIGTERM, sigstopper);
@@ -398,6 +402,10 @@ int main(int ac, char **av)
btrfs_header_nritems(&root->node->node.header));
close_ctree(root, &super);
root = open_ctree("dbfile", &super);
+ if (!root) {
+ fprintf(stderr, "Open ctree failed\n");
+ goto out;
+ }
}
while(count--) {
ret = ops[op](trans, root, &radix);
++++++ btrfs-progs-v0.19-116-g13eced9.tar.bz2 -> btrfs-progs-v0.19-118-gfdb6c04.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v0.19-116-g13eced9/Makefile new/btrfs-progs-v0.19-118-gfdb6c04/Makefile
--- old/btrfs-progs-v0.19-116-g13eced9/Makefile 2011-11-05 19:58:41.000000000 +0100
+++ new/btrfs-progs-v0.19-118-gfdb6c04/Makefile 2011-12-01 17:33:21.000000000 +0100
@@ -37,8 +37,8 @@
bash version.sh
btrfs: $(objects) btrfs.o btrfs_cmds.o scrub.o
- $(CC) -lpthread $(CFLAGS) -o btrfs btrfs.o btrfs_cmds.o scrub.o \
- $(objects) $(LDFLAGS) $(LIBS)
+ $(CC) $(CFLAGS) -o btrfs btrfs.o btrfs_cmds.o scrub.o \
+ $(objects) $(LDFLAGS) $(LIBS) -lpthread
calc-size: $(objects) calc-size.o
gcc $(CFLAGS) -o calc-size calc-size.o $(objects) $(LDFLAGS) $(LIBS)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v0.19-116-g13eced9/btrfs-zero-log.c new/btrfs-progs-v0.19-118-gfdb6c04/btrfs-zero-log.c
--- old/btrfs-progs-v0.19-116-g13eced9/btrfs-zero-log.c 2011-11-05 19:58:41.000000000 +0100
+++ new/btrfs-progs-v0.19-118-gfdb6c04/btrfs-zero-log.c 2011-12-01 17:33:21.000000000 +0100
@@ -42,6 +42,7 @@
int main(int ac, char **av)
{
struct btrfs_root *root;
+ struct btrfs_trans_handle *trans;
int ret;
if (ac != 2)
@@ -62,8 +63,10 @@
if (root == NULL)
return 1;
+ trans = btrfs_start_transaction(root, 1);
btrfs_set_super_log_root(&root->fs_info->super_copy, 0);
btrfs_set_super_log_root_level(&root->fs_info->super_copy, 0);
+ btrfs_commit_transaction(trans, root);
close_ctree(root);
return ret;
}
++++++ local-version-override.patch ++++++
--- /var/tmp/diff_new_pack.gc4Frh/_old 2011-12-19 17:26:50.000000000 +0100
+++ /var/tmp/diff_new_pack.gc4Frh/_new 2011-12-19 17:26:50.000000000 +0100
@@ -1,7 +1,7 @@
-Index: btrfs-progs-v0.19-35-g1b444cd/version.sh
+Index: btrfs-progs-v0.19-116-g13eced9/version.sh
===================================================================
---- btrfs-progs-v0.19-35-g1b444cd.orig/version.sh
-+++ btrfs-progs-v0.19-35-g1b444cd/version.sh
+--- btrfs-progs-v0.19-116-g13eced9.orig/version.sh
++++ btrfs-progs-v0.19-116-g13eced9/version.sh
@@ -6,7 +6,7 @@
# Copyright 2008, Oracle
# Released under the GNU GPLv2
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org