- 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] - 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 - updated mkinitrd script to scan devices before mount (bnc#727383) OBS-URL: https://build.opensuse.org/package/show/filesystems/btrfsprogs?expand=0&rev=115
This commit is contained in:
parent
2f977a5763
commit
db07609875
37
0100-btrfs-progs-ignore-a-option-in-mkfs.patch
Normal file
37
0100-btrfs-progs-ignore-a-option-in-mkfs.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From a6aa706ee793b406761baeaa7cde78d1250f2d2b Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
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 <dsterba@suse.cz>
|
||||
---
|
||||
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
|
||||
|
108
0102-Add-the-force-option.patch
Normal file
108
0102-Add-the-force-option.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From 8456dc84b0c7548ca4f83c4e58e8e9dd443b7686 Mon Sep 17 00:00:00 2001
|
||||
From: Goffredo Baroncelli <kreijack@inwind.it>
|
||||
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
|
||||
|
35
0103-mkfs.btrfs-man-page-document-the-force-option.patch
Normal file
35
0103-mkfs.btrfs-man-page-document-the-force-option.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From fdd55a58d661cede927b741e57abc4f564bb7bd6 Mon Sep 17 00:00:00 2001
|
||||
From: Goffredo Baroncelli <kreijack@inwind.it>
|
||||
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
|
||||
|
@ -0,0 +1,42 @@
|
||||
From da911929cf232b81a4e2dcffbb26dc3cc6f222af Mon Sep 17 00:00:00 2001
|
||||
From: Goffredo Baroncelli <kreijack@inwind.it>
|
||||
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 <kreijack@inwind.it>
|
||||
---
|
||||
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
|
||||
|
275
0105-Regression-tests.patch
Normal file
275
0105-Regression-tests.patch
Normal file
@ -0,0 +1,275 @@
|
||||
From 8ed24be618165f2f76851e007347408ab9013d30 Mon Sep 17 00:00:00 2001
|
||||
From: Hugo Mills <hugo@carfax.org.uk>
|
||||
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 <hugo@carfax.org.uk>
|
||||
---
|
||||
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
|
||||
|
84
0106-Fix-sub-snap-parameter-handling.patch
Normal file
84
0106-Fix-sub-snap-parameter-handling.patch
Normal file
@ -0,0 +1,84 @@
|
||||
From 33be6f1695e8bd450be2e22fbf88b826488186a1 Mon Sep 17 00:00:00 2001
|
||||
From: Hugo Mills <hugo@carfax.org.uk>
|
||||
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 <sensille@gmx.net>, fixes it.
|
||||
|
||||
Signed-off-by: Hugo Mills <hugo@carfax.org.uk>
|
||||
---
|
||||
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
|
||||
|
474
0107-Add-info-for-the-commands.patch
Normal file
474
0107-Add-info-for-the-commands.patch
Normal file
@ -0,0 +1,474 @@
|
||||
From 18254b66cf6ff7c9eff605ac7de9b4947d39a96f Mon Sep 17 00:00:00 2001
|
||||
From: Goffredo Baroncelli <kreijack@inwind.it>
|
||||
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 <limits.h>
|
||||
#include <uuid/uuid.h>
|
||||
#include <ctype.h>
|
||||
+#include <getopt.h>
|
||||
|
||||
#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> <last_gen>\i
|
||||
+ *
|
||||
+ * List the recently modified files in a filesystem.
|
||||
+ *
|
||||
+ * List the recently modified files in a subvolume, after \I<last_gen>\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
|
||||
|
202
0108-Add-the-header-footer-introduction-of-the-man-page.patch
Normal file
202
0108-Add-the-header-footer-introduction-of-the-man-page.patch
Normal file
@ -0,0 +1,202 @@
|
||||
From aa8bba1e2c99eb895c7e43f5092e4bf56d68d9c5 Mon Sep 17 00:00:00 2001
|
||||
From: Goffredo Baroncelli <kreijack@inwind.it>
|
||||
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,<chunkaddr+1>\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
|
||||
|
458
0109-helpextract-tool-to-extract-the-info-for-the-help-fr.patch
Normal file
458
0109-helpextract-tool-to-extract-the-info-for-the-help-fr.patch
Normal file
@ -0,0 +1,458 @@
|
||||
From e1825e850af190793dadf5ca78f36f394bae9e86 Mon Sep 17 00:00:00 2001
|
||||
From: Goffredo Baroncelli <kreijack@inwind.it>
|
||||
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 <stdio.h>
|
||||
+#include <errno.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <ctype.h>
|
||||
+
|
||||
+#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
|
||||
|
710
0110-Update-the-makefile-for-generating-the-man-page.patch
Normal file
710
0110-Update-the-makefile-for-generating-the-man-page.patch
Normal file
@ -0,0 +1,710 @@
|
||||
From e93b09f73b0914d8e0b8c2c78b6a1a8ebefa151c Mon Sep 17 00:00:00 2001
|
||||
From: Goffredo Baroncelli <kreijack@inwind.it>
|
||||
Date: Sat, 16 Jul 2011 11:03:14 +0200
|
||||
Subject: [PATCH 11/35] Update the makefile for generating the man page.
|
||||
|
||||
The makefile is update in order to generate the man/btrfs.8.in by the
|
||||
helpextract tool on the basis of the sources comments. The old man page
|
||||
is renamed as btrfs.8.in.old.
|
||||
---
|
||||
Makefile | 11 ++-
|
||||
man/btrfs.8.in | 322 ----------------------------------------------------
|
||||
man/btrfs.8.in.old | 322 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 332 insertions(+), 323 deletions(-)
|
||||
delete mode 100644 man/btrfs.8.in
|
||||
create mode 100644 man/btrfs.8.in.old
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 5f25d66..b673100 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -19,6 +19,8 @@ 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_man_page_source = btrfs.c btrfs_cmds.c scrub.c
|
||||
+
|
||||
# make C=1 to enable sparse
|
||||
ifdef C
|
||||
check = sparse $(CHECKFLAGS)
|
||||
@@ -97,13 +99,20 @@ convert: $(objects) convert.o
|
||||
ioctl-test: $(objects) ioctl-test.o
|
||||
$(CC) $(CFLAGS) -o ioctl-test $(objects) ioctl-test.o $(LDFLAGS) $(LIBS)
|
||||
|
||||
-manpages:
|
||||
+helpextract: helpextract.o
|
||||
+ $(CC) $(CFLAGS) -o $@ helpextract.o
|
||||
+
|
||||
+man/btrfs.8.in: helpextract $(btrfs_man_page_source)
|
||||
+ ./helpextract --man-page $(btrfs_man_page_source) >$@
|
||||
+
|
||||
+manpages: man/btrfs.8.in
|
||||
cd man; make
|
||||
|
||||
install-man:
|
||||
cd man; make install
|
||||
|
||||
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
|
||||
cd man; make clean
|
||||
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
|
||||
deleted file mode 100644
|
||||
index be478e0..0000000
|
||||
--- a/man/btrfs.8.in
|
||||
+++ /dev/null
|
||||
@@ -1,322 +0,0 @@
|
||||
-.TH BTRFS 8 "" "btrfs" "btrfs"
|
||||
-.\"
|
||||
-.\" Man page written by Goffredo Baroncelli <kreijack@inwind.it> (Feb 2010)
|
||||
-.\"
|
||||
-.SH NAME
|
||||
-btrfs \- control a btrfs filesystem
|
||||
-.SH SYNOPSIS
|
||||
-\fBbtrfs\fP \fBsubvolume snapshot\fP\fI [-r] <source> [<dest>/]<name>\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBsubvolume delete\fP\fI <subvolume>\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBsubvolume create\fP\fI [<dest>/]<name>\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBsubvolume list\fP\fI [-p] <path>\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBsubvolume set-default\fP\fI <id> <path>\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBfilesystem sync\fP\fI <path> \fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBfilesystem resize\fP\fI [+/\-]<size>[gkm]|max <filesystem>\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBfilesystem label\fP\fI <dev> [newlabel]\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBfilesystem defrag\fP\fI [options] <file>|<dir> [<file>|<dir>...]\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBsubvolume find-new\fP\fI <subvolume> <last_gen>\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBfilesystem balance\fP\fI <path> \fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBfilesystem defragment\fP\fI <file>|<dir> [<file>|<dir>...]\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBdevice scan\fP\fI [--all-devices|<device> [<device>...]]\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBdevice show\fP\fI [--all-devices|<uuid>|<label>]\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBdevice add\fP\fI <device> [<device>...] <path> \fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBdevice delete\fP\fI <device> [<device>...] <path> \fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBscrub start\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBscrub cancel\fP {\fI<path>\fP|\fI<device>\fP}
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBscrub resume\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBscrub status\fP [-d] {\fI<path>\fP|\fI<device>\fP}
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBinspect-internal inode-resolve\fP [-v] \fI<inode>\fP \fI<path>\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBinspect-internal logical-resolve\fP
|
||||
-[-Pv] \fI<logical>\fP \fI<path>\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fBhelp|\-\-help|\-h \fP\fI\fP
|
||||
-.PP
|
||||
-\fBbtrfs\fP \fB<command> \-\-help \fP\fI\fP
|
||||
-.PP
|
||||
-.SH DESCRIPTION
|
||||
-.B btrfs
|
||||
-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
|
||||
-.I btrfs sub snaps
|
||||
-instead of
|
||||
-.I btrfs subvolume snapshot.
|
||||
-But
|
||||
-.I btrfs file s
|
||||
-is not allowed, because
|
||||
-.I file s
|
||||
-may be interpreted both as
|
||||
-.I filesystem show
|
||||
-and as
|
||||
-.I filesystem sync.
|
||||
-In this case
|
||||
-.I btrfs
|
||||
-returnsfilesystem sync
|
||||
-If a command is terminated by
|
||||
-.I --help
|
||||
-, the detailed help is showed. If the passed command matches more commands,
|
||||
-detailed help of all the matched commands is showed. For example
|
||||
-.I btrfs dev --help
|
||||
-shows the help of all
|
||||
-.I device*
|
||||
-commands.
|
||||
-
|
||||
-.SH COMMANDS
|
||||
-.TP
|
||||
-
|
||||
-\fBsubvolume snapshot\fR\fI [-r] <source> [<dest>/]<name>\fR
|
||||
-Create a writable/readonly snapshot of the subvolume \fI<source>\fR with the
|
||||
-name \fI<name>\fR in the \fI<dest>\fR directory. If \fI<source>\fR is not a
|
||||
-subvolume, \fBbtrfs\fR returns an error. If \fI-r\fR is given, the snapshot
|
||||
-will be readonly.
|
||||
-.TP
|
||||
-
|
||||
-\fBsubvolume delete\fR\fI <subvolume>\fR
|
||||
-Delete the subvolume \fI<subvolume>\fR. If \fI<subvolume>\fR is not a
|
||||
-subvolume, \fBbtrfs\fR returns an error.
|
||||
-.TP
|
||||
-
|
||||
-\fBsubvolume create\fR\fI [<dest>/]<name>\fR
|
||||
-Create a subvolume in \fI<dest>\fR (or in the current directory if
|
||||
-\fI<dest>\fR is omitted).
|
||||
-.TP
|
||||
-
|
||||
-\fBsubvolume list\fR\fI [-p] <path>\fR
|
||||
-List the subvolumes present in the filesystem \fI<path>\fR. 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 \fItop level\fR
|
||||
-subvolume.
|
||||
-The subvolume's ID may be used by the \fBsubvolume set-default\fR command, or
|
||||
-at mount time via the \fIsubvol=\fR option.
|
||||
-If \fI-p\fR is given, then \fIparent <ID>\fR is added to the output between ID
|
||||
-and top level. The parent's ID may be used at mount time via the
|
||||
-\fIsubvolrootid=\fR option.
|
||||
-.TP
|
||||
-
|
||||
-\fBsubvolume set-default\fR\fI <id> <path>\fR
|
||||
-Set the subvolume of the filesystem \fI<path>\fR which is mounted as
|
||||
-\fIdefault\fR. The subvolume is identified by \fI<id>\fR, which
|
||||
-is returned by the \fBsubvolume list\fR command.
|
||||
-.TP
|
||||
-
|
||||
-\fBsubvolume get-default\fR\fI <path>\fR
|
||||
-Get the default subvolume of the filesystem \fI<path>\fR. The output format
|
||||
-is similar to \fBsubvolume list\fR command.
|
||||
-.TP
|
||||
-
|
||||
-\fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
|
||||
-
|
||||
-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 \fIstart\fR and \fIlen\fR. Any extent bigger than \fIthresh\fR 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.
|
||||
-
|
||||
-\fB-v\fP be verbose
|
||||
-
|
||||
-\fB-c\fP compress file contents while defragmenting
|
||||
-
|
||||
-\fB-f\fP flush filesystem after defragmenting
|
||||
-
|
||||
-\fB-s start\fP defragment only from byte \fIstart\fR onward
|
||||
-
|
||||
-\fB-l len\fP defragment only up to \fIlen\fR bytes
|
||||
-
|
||||
-\fB-t size\fP defragment only files at least \fIsize\fR 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
|
||||
-\fBcp --reflink\fP.
|
||||
-\fBsubvolume find-new\fR\fI <subvolume> <last_gen>\fR
|
||||
-List the recently modified files in a subvolume, after \fI<last_gen>\fR ID.
|
||||
-.TP
|
||||
-
|
||||
-\fBfilesystem sync\fR\fI <path> \fR
|
||||
-Force a sync for the filesystem identified by \fI<path>\fR.
|
||||
-.TP
|
||||
-
|
||||
-.\"
|
||||
-.\" Some wording are extracted by the resize2fs man page
|
||||
-.\"
|
||||
-
|
||||
-\fBfilesystem resize\fR\fI [+/\-]<size>[gkm]|max <path>\fR
|
||||
-Resize a filesystem identified by \fI<path>\fR.
|
||||
-The \fI<size>\fR parameter specifies the new size of the filesystem.
|
||||
-If the prefix \fI+\fR or \fI\-\fR is present the size is increased or decreased
|
||||
-by the quantity \fI<size>\fR.
|
||||
-If no units are specified, the unit of the \fI<size>\fR 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 \fBresize\fR command \fBdoes not\fR 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.
|
||||
-.TP
|
||||
-
|
||||
-\fBbtrfs\fP \fBfilesystem label\fP\fI <dev> [newlabel]\fP
|
||||
-Show or update the label of a filesystem. \fI<dev>\fR is used to identify the
|
||||
-filesystem.
|
||||
-If a \fInewlabel\fR optional argument is passed, the label is changed. The
|
||||
-following costraints exist for a label:
|
||||
-.IP
|
||||
-- the maximum allowable lenght shall be less or equal than 256 chars
|
||||
-.IP
|
||||
-- the label shall not contain the '/' or '\\' characters.
|
||||
-
|
||||
-NOTE: Currently there are the following limitations:
|
||||
-.IP
|
||||
-- the filesystem has to be unmounted
|
||||
-.IP
|
||||
-- the filesystem should not have more than one device.
|
||||
-.TP
|
||||
-
|
||||
-\fBfilesystem show\fR [--all-devices|<uuid>|<label>]\fR
|
||||
-Show the btrfs filesystem with some additional info. If no \fIUUID\fP or
|
||||
-\fIlabel\fP is passed, \fBbtrfs\fR show info of all the btrfs filesystem.
|
||||
-If \fB--all-devices\fP is passed, all the devices under /dev are scanned;
|
||||
-otherwise the devices list is extracted from the /proc/partitions file.
|
||||
-.TP
|
||||
-
|
||||
-\fBdevice balance\fR \fI<path>\fR
|
||||
-Balance the chunks of the filesystem identified by \fI<path>\fR
|
||||
-across the devices.
|
||||
-.TP
|
||||
-
|
||||
-\fBdevice add\fR\fI <dev> [<dev>..] <path>\fR
|
||||
-Add device(s) to the filesystem identified by \fI<path>\fR.
|
||||
-.TP
|
||||
-
|
||||
-\fBdevice delete\fR\fI <dev> [<dev>..] <path>\fR
|
||||
-Remove device(s) from a filesystem identified by \fI<path>\fR.
|
||||
-.TP
|
||||
-
|
||||
-\fBdevice scan\fR \fI[--all-devices|<device> [<device>...]\fR
|
||||
-If one or more devices are passed, these are scanned for a btrfs filesystem.
|
||||
-If no devices are passed, \fBbtrfs\fR scans all the block devices listed
|
||||
-in the /proc/partitions file.
|
||||
-Finally, if \fB--all-devices\fP is passed, all the devices under /dev are
|
||||
-scanned.
|
||||
-.TP
|
||||
-
|
||||
-\fBscrub start\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
|
||||
-Start a scrub on all devices of the filesystem identified by \fI<path>\fR or on
|
||||
-a single \fI<device>\fR. Without options, scrub is started as a background
|
||||
-process. Progress can be obtained with the \fBscrub status\fR command. Scrubbing
|
||||
-involves reading all data from all disks and verifying checksums. Errors are
|
||||
-corrected along the way if possible.
|
||||
-.RS
|
||||
-
|
||||
-\fIOptions\fR
|
||||
-.IP -B 5
|
||||
-Do not background and print scrub statistics when finished.
|
||||
-.IP -d 5
|
||||
-Print separate statistics for each device of the filesystem (-B only).
|
||||
-.IP -q 5
|
||||
-Quiet. Omit error messages and statistics.
|
||||
-.IP -r 5
|
||||
-Read only mode. Do not attempt to correct anything.
|
||||
-.IP -u 5
|
||||
-Scrub unused space as well. (NOT IMPLEMENTED)
|
||||
-.RE
|
||||
-.TP
|
||||
-
|
||||
-\fBscrub cancel\fP {\fI<path>\fP|\fI<device>\fP}
|
||||
-If a scrub is running on the filesystem identified by \fI<path>\fR, cancel it.
|
||||
-Progress is saved in the scrub progress file and scrubbing can be resumed later
|
||||
-using the \fBscrub resume\fR command.
|
||||
-If a \fI<device>\fR is given, the corresponding filesystem is found and
|
||||
-\fBscrub cancel\fP behaves as if it was called on that filesystem.
|
||||
-.TP
|
||||
-
|
||||
-\fBscrub resume\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
|
||||
-Resume a canceled or interrupted scrub cycle on the filesystem identified by
|
||||
-\fI<path>\fR or on a given \fI<device>\fR. Does not start a new scrub if the
|
||||
-last scrub finished successfully.
|
||||
-.RS
|
||||
-
|
||||
-\fIOptions\fR
|
||||
-.TP
|
||||
-see \fBscrub start\fP.
|
||||
-.RE
|
||||
-.TP
|
||||
-
|
||||
-\fBscrub status\fP [-d] {\fI<path>\fP|\fI<device>\fP}
|
||||
-Show status of a running scrub for the filesystem identified by \fI<path>\fR or
|
||||
-for the specified \fI<device>\fR.
|
||||
-If no scrub is running, show statistics of the last finished or canceled scrub
|
||||
-for that filesystem or device.
|
||||
-.RS
|
||||
-
|
||||
-\fIOptions\fR
|
||||
-.IP -d 5
|
||||
-Print separate statistics for each device of the filesystem.
|
||||
-.RE
|
||||
-.TP
|
||||
-
|
||||
-\fBinspect-internal inode-resolve\fP [-v] \fI<inode>\fP \fI<path>\fP
|
||||
-Resolves an <inode> in subvolume <path> to all filesystem paths.
|
||||
-.RS
|
||||
-
|
||||
-\fIOptions\fR
|
||||
-.IP -v 5
|
||||
-verbose mode. print count of returned paths and ioctl() return value
|
||||
-.RE
|
||||
-.TP
|
||||
-
|
||||
-\fBinspect-internal logical-resolve\fP [-Pv] \fI<logical>\fP \fI<path>\fP
|
||||
-Resolves a <logical> address in the filesystem mounted at <path> to all inodes.
|
||||
-By default, each inode is then resolved to a file system path (similar to the
|
||||
-\fBinode-resolve\fP subcommand).
|
||||
-.RS
|
||||
-
|
||||
-\fIOptions\fR
|
||||
-.IP -P 5
|
||||
-skip the path resolving and print the inodes instead
|
||||
-.IP -v 5
|
||||
-verbose mode. print count of returned paths and all ioctl() return values
|
||||
-.RE
|
||||
-
|
||||
-.SH EXIT STATUS
|
||||
-\fBbtrfs\fR returns a zero exist status if it succeeds. Non zero is returned in
|
||||
-case of failure.
|
||||
-
|
||||
-.SH AVAILABILITY
|
||||
-.B btrfs
|
||||
-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.
|
||||
-.SH SEE ALSO
|
||||
-.BR mkfs.btrfs (8)
|
||||
diff --git a/man/btrfs.8.in.old b/man/btrfs.8.in.old
|
||||
new file mode 100644
|
||||
index 0000000..be478e0
|
||||
--- /dev/null
|
||||
+++ b/man/btrfs.8.in.old
|
||||
@@ -0,0 +1,322 @@
|
||||
+.TH BTRFS 8 "" "btrfs" "btrfs"
|
||||
+.\"
|
||||
+.\" Man page written by Goffredo Baroncelli <kreijack@inwind.it> (Feb 2010)
|
||||
+.\"
|
||||
+.SH NAME
|
||||
+btrfs \- control a btrfs filesystem
|
||||
+.SH SYNOPSIS
|
||||
+\fBbtrfs\fP \fBsubvolume snapshot\fP\fI [-r] <source> [<dest>/]<name>\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBsubvolume delete\fP\fI <subvolume>\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBsubvolume create\fP\fI [<dest>/]<name>\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBsubvolume list\fP\fI [-p] <path>\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBsubvolume set-default\fP\fI <id> <path>\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBfilesystem sync\fP\fI <path> \fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBfilesystem resize\fP\fI [+/\-]<size>[gkm]|max <filesystem>\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBfilesystem label\fP\fI <dev> [newlabel]\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBfilesystem defrag\fP\fI [options] <file>|<dir> [<file>|<dir>...]\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBsubvolume find-new\fP\fI <subvolume> <last_gen>\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBfilesystem balance\fP\fI <path> \fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBfilesystem defragment\fP\fI <file>|<dir> [<file>|<dir>...]\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBdevice scan\fP\fI [--all-devices|<device> [<device>...]]\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBdevice show\fP\fI [--all-devices|<uuid>|<label>]\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBdevice add\fP\fI <device> [<device>...] <path> \fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBdevice delete\fP\fI <device> [<device>...] <path> \fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBscrub start\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBscrub cancel\fP {\fI<path>\fP|\fI<device>\fP}
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBscrub resume\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBscrub status\fP [-d] {\fI<path>\fP|\fI<device>\fP}
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBinspect-internal inode-resolve\fP [-v] \fI<inode>\fP \fI<path>\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBinspect-internal logical-resolve\fP
|
||||
+[-Pv] \fI<logical>\fP \fI<path>\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fBhelp|\-\-help|\-h \fP\fI\fP
|
||||
+.PP
|
||||
+\fBbtrfs\fP \fB<command> \-\-help \fP\fI\fP
|
||||
+.PP
|
||||
+.SH DESCRIPTION
|
||||
+.B btrfs
|
||||
+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
|
||||
+.I btrfs sub snaps
|
||||
+instead of
|
||||
+.I btrfs subvolume snapshot.
|
||||
+But
|
||||
+.I btrfs file s
|
||||
+is not allowed, because
|
||||
+.I file s
|
||||
+may be interpreted both as
|
||||
+.I filesystem show
|
||||
+and as
|
||||
+.I filesystem sync.
|
||||
+In this case
|
||||
+.I btrfs
|
||||
+returnsfilesystem sync
|
||||
+If a command is terminated by
|
||||
+.I --help
|
||||
+, the detailed help is showed. If the passed command matches more commands,
|
||||
+detailed help of all the matched commands is showed. For example
|
||||
+.I btrfs dev --help
|
||||
+shows the help of all
|
||||
+.I device*
|
||||
+commands.
|
||||
+
|
||||
+.SH COMMANDS
|
||||
+.TP
|
||||
+
|
||||
+\fBsubvolume snapshot\fR\fI [-r] <source> [<dest>/]<name>\fR
|
||||
+Create a writable/readonly snapshot of the subvolume \fI<source>\fR with the
|
||||
+name \fI<name>\fR in the \fI<dest>\fR directory. If \fI<source>\fR is not a
|
||||
+subvolume, \fBbtrfs\fR returns an error. If \fI-r\fR is given, the snapshot
|
||||
+will be readonly.
|
||||
+.TP
|
||||
+
|
||||
+\fBsubvolume delete\fR\fI <subvolume>\fR
|
||||
+Delete the subvolume \fI<subvolume>\fR. If \fI<subvolume>\fR is not a
|
||||
+subvolume, \fBbtrfs\fR returns an error.
|
||||
+.TP
|
||||
+
|
||||
+\fBsubvolume create\fR\fI [<dest>/]<name>\fR
|
||||
+Create a subvolume in \fI<dest>\fR (or in the current directory if
|
||||
+\fI<dest>\fR is omitted).
|
||||
+.TP
|
||||
+
|
||||
+\fBsubvolume list\fR\fI [-p] <path>\fR
|
||||
+List the subvolumes present in the filesystem \fI<path>\fR. 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 \fItop level\fR
|
||||
+subvolume.
|
||||
+The subvolume's ID may be used by the \fBsubvolume set-default\fR command, or
|
||||
+at mount time via the \fIsubvol=\fR option.
|
||||
+If \fI-p\fR is given, then \fIparent <ID>\fR is added to the output between ID
|
||||
+and top level. The parent's ID may be used at mount time via the
|
||||
+\fIsubvolrootid=\fR option.
|
||||
+.TP
|
||||
+
|
||||
+\fBsubvolume set-default\fR\fI <id> <path>\fR
|
||||
+Set the subvolume of the filesystem \fI<path>\fR which is mounted as
|
||||
+\fIdefault\fR. The subvolume is identified by \fI<id>\fR, which
|
||||
+is returned by the \fBsubvolume list\fR command.
|
||||
+.TP
|
||||
+
|
||||
+\fBsubvolume get-default\fR\fI <path>\fR
|
||||
+Get the default subvolume of the filesystem \fI<path>\fR. The output format
|
||||
+is similar to \fBsubvolume list\fR command.
|
||||
+.TP
|
||||
+
|
||||
+\fBfilesystem defragment\fP -c[zlib|lzo] [-l \fIlen\fR] [-s \fIstart\fR] [-t \fIsize\fR] -[vf] <\fIfile\fR>|<\fIdir\fR> [<\fIfile\fR>|<\fIdir\fR>...]
|
||||
+
|
||||
+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 \fIstart\fR and \fIlen\fR. Any extent bigger than \fIthresh\fR 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.
|
||||
+
|
||||
+\fB-v\fP be verbose
|
||||
+
|
||||
+\fB-c\fP compress file contents while defragmenting
|
||||
+
|
||||
+\fB-f\fP flush filesystem after defragmenting
|
||||
+
|
||||
+\fB-s start\fP defragment only from byte \fIstart\fR onward
|
||||
+
|
||||
+\fB-l len\fP defragment only up to \fIlen\fR bytes
|
||||
+
|
||||
+\fB-t size\fP defragment only files at least \fIsize\fR 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
|
||||
+\fBcp --reflink\fP.
|
||||
+\fBsubvolume find-new\fR\fI <subvolume> <last_gen>\fR
|
||||
+List the recently modified files in a subvolume, after \fI<last_gen>\fR ID.
|
||||
+.TP
|
||||
+
|
||||
+\fBfilesystem sync\fR\fI <path> \fR
|
||||
+Force a sync for the filesystem identified by \fI<path>\fR.
|
||||
+.TP
|
||||
+
|
||||
+.\"
|
||||
+.\" Some wording are extracted by the resize2fs man page
|
||||
+.\"
|
||||
+
|
||||
+\fBfilesystem resize\fR\fI [+/\-]<size>[gkm]|max <path>\fR
|
||||
+Resize a filesystem identified by \fI<path>\fR.
|
||||
+The \fI<size>\fR parameter specifies the new size of the filesystem.
|
||||
+If the prefix \fI+\fR or \fI\-\fR is present the size is increased or decreased
|
||||
+by the quantity \fI<size>\fR.
|
||||
+If no units are specified, the unit of the \fI<size>\fR 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 \fBresize\fR command \fBdoes not\fR 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.
|
||||
+.TP
|
||||
+
|
||||
+\fBbtrfs\fP \fBfilesystem label\fP\fI <dev> [newlabel]\fP
|
||||
+Show or update the label of a filesystem. \fI<dev>\fR is used to identify the
|
||||
+filesystem.
|
||||
+If a \fInewlabel\fR optional argument is passed, the label is changed. The
|
||||
+following costraints exist for a label:
|
||||
+.IP
|
||||
+- the maximum allowable lenght shall be less or equal than 256 chars
|
||||
+.IP
|
||||
+- the label shall not contain the '/' or '\\' characters.
|
||||
+
|
||||
+NOTE: Currently there are the following limitations:
|
||||
+.IP
|
||||
+- the filesystem has to be unmounted
|
||||
+.IP
|
||||
+- the filesystem should not have more than one device.
|
||||
+.TP
|
||||
+
|
||||
+\fBfilesystem show\fR [--all-devices|<uuid>|<label>]\fR
|
||||
+Show the btrfs filesystem with some additional info. If no \fIUUID\fP or
|
||||
+\fIlabel\fP is passed, \fBbtrfs\fR show info of all the btrfs filesystem.
|
||||
+If \fB--all-devices\fP is passed, all the devices under /dev are scanned;
|
||||
+otherwise the devices list is extracted from the /proc/partitions file.
|
||||
+.TP
|
||||
+
|
||||
+\fBdevice balance\fR \fI<path>\fR
|
||||
+Balance the chunks of the filesystem identified by \fI<path>\fR
|
||||
+across the devices.
|
||||
+.TP
|
||||
+
|
||||
+\fBdevice add\fR\fI <dev> [<dev>..] <path>\fR
|
||||
+Add device(s) to the filesystem identified by \fI<path>\fR.
|
||||
+.TP
|
||||
+
|
||||
+\fBdevice delete\fR\fI <dev> [<dev>..] <path>\fR
|
||||
+Remove device(s) from a filesystem identified by \fI<path>\fR.
|
||||
+.TP
|
||||
+
|
||||
+\fBdevice scan\fR \fI[--all-devices|<device> [<device>...]\fR
|
||||
+If one or more devices are passed, these are scanned for a btrfs filesystem.
|
||||
+If no devices are passed, \fBbtrfs\fR scans all the block devices listed
|
||||
+in the /proc/partitions file.
|
||||
+Finally, if \fB--all-devices\fP is passed, all the devices under /dev are
|
||||
+scanned.
|
||||
+.TP
|
||||
+
|
||||
+\fBscrub start\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
|
||||
+Start a scrub on all devices of the filesystem identified by \fI<path>\fR or on
|
||||
+a single \fI<device>\fR. Without options, scrub is started as a background
|
||||
+process. Progress can be obtained with the \fBscrub status\fR command. Scrubbing
|
||||
+involves reading all data from all disks and verifying checksums. Errors are
|
||||
+corrected along the way if possible.
|
||||
+.RS
|
||||
+
|
||||
+\fIOptions\fR
|
||||
+.IP -B 5
|
||||
+Do not background and print scrub statistics when finished.
|
||||
+.IP -d 5
|
||||
+Print separate statistics for each device of the filesystem (-B only).
|
||||
+.IP -q 5
|
||||
+Quiet. Omit error messages and statistics.
|
||||
+.IP -r 5
|
||||
+Read only mode. Do not attempt to correct anything.
|
||||
+.IP -u 5
|
||||
+Scrub unused space as well. (NOT IMPLEMENTED)
|
||||
+.RE
|
||||
+.TP
|
||||
+
|
||||
+\fBscrub cancel\fP {\fI<path>\fP|\fI<device>\fP}
|
||||
+If a scrub is running on the filesystem identified by \fI<path>\fR, cancel it.
|
||||
+Progress is saved in the scrub progress file and scrubbing can be resumed later
|
||||
+using the \fBscrub resume\fR command.
|
||||
+If a \fI<device>\fR is given, the corresponding filesystem is found and
|
||||
+\fBscrub cancel\fP behaves as if it was called on that filesystem.
|
||||
+.TP
|
||||
+
|
||||
+\fBscrub resume\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
|
||||
+Resume a canceled or interrupted scrub cycle on the filesystem identified by
|
||||
+\fI<path>\fR or on a given \fI<device>\fR. Does not start a new scrub if the
|
||||
+last scrub finished successfully.
|
||||
+.RS
|
||||
+
|
||||
+\fIOptions\fR
|
||||
+.TP
|
||||
+see \fBscrub start\fP.
|
||||
+.RE
|
||||
+.TP
|
||||
+
|
||||
+\fBscrub status\fP [-d] {\fI<path>\fP|\fI<device>\fP}
|
||||
+Show status of a running scrub for the filesystem identified by \fI<path>\fR or
|
||||
+for the specified \fI<device>\fR.
|
||||
+If no scrub is running, show statistics of the last finished or canceled scrub
|
||||
+for that filesystem or device.
|
||||
+.RS
|
||||
+
|
||||
+\fIOptions\fR
|
||||
+.IP -d 5
|
||||
+Print separate statistics for each device of the filesystem.
|
||||
+.RE
|
||||
+.TP
|
||||
+
|
||||
+\fBinspect-internal inode-resolve\fP [-v] \fI<inode>\fP \fI<path>\fP
|
||||
+Resolves an <inode> in subvolume <path> to all filesystem paths.
|
||||
+.RS
|
||||
+
|
||||
+\fIOptions\fR
|
||||
+.IP -v 5
|
||||
+verbose mode. print count of returned paths and ioctl() return value
|
||||
+.RE
|
||||
+.TP
|
||||
+
|
||||
+\fBinspect-internal logical-resolve\fP [-Pv] \fI<logical>\fP \fI<path>\fP
|
||||
+Resolves a <logical> address in the filesystem mounted at <path> to all inodes.
|
||||
+By default, each inode is then resolved to a file system path (similar to the
|
||||
+\fBinode-resolve\fP subcommand).
|
||||
+.RS
|
||||
+
|
||||
+\fIOptions\fR
|
||||
+.IP -P 5
|
||||
+skip the path resolving and print the inodes instead
|
||||
+.IP -v 5
|
||||
+verbose mode. print count of returned paths and all ioctl() return values
|
||||
+.RE
|
||||
+
|
||||
+.SH EXIT STATUS
|
||||
+\fBbtrfs\fR returns a zero exist status if it succeeds. Non zero is returned in
|
||||
+case of failure.
|
||||
+
|
||||
+.SH AVAILABILITY
|
||||
+.B btrfs
|
||||
+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.
|
||||
+.SH SEE ALSO
|
||||
+.BR mkfs.btrfs (8)
|
||||
--
|
||||
1.7.6.233.gd79bc
|
||||
|
@ -0,0 +1,78 @@
|
||||
From 72aba9c58e83186db249f31198c03ebd0c34d7af Mon Sep 17 00:00:00 2001
|
||||
From: Goffredo Baroncelli <kreijack@inwind.it>
|
||||
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
|
||||
|
@ -0,0 +1,53 @@
|
||||
From e2d4509137cb8713b02a030e6116b041ae82588d Mon Sep 17 00:00:00 2001
|
||||
From: Goffredo Baroncelli <kreijack@inwind.it>
|
||||
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
|
750
0113-Btrfs-progs-add-restriper-commands.patch
Normal file
750
0113-Btrfs-progs-add-restriper-commands.patch
Normal file
@ -0,0 +1,750 @@
|
||||
From 192484f121dbbffd004303a760ef8b4dbd470ce2 Mon Sep 17 00:00:00 2001
|
||||
From: Ilya Dryomov <idryomov@gmail.com>
|
||||
Date: Tue, 23 Aug 2011 23:08:16 +0300
|
||||
Subject: [PATCH 14/35] Btrfs-progs: add restriper commands
|
||||
|
||||
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
|
||||
---
|
||||
btrfs.c | 21 +++
|
||||
btrfs_cmds.c | 505 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
btrfs_cmds.h | 5 +
|
||||
ctree.h | 9 +
|
||||
ioctl.h | 46 +++++-
|
||||
print-tree.c | 3 +
|
||||
volumes.h | 42 +++++
|
||||
7 files changed, 628 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/btrfs.c b/btrfs.c
|
||||
index 66b0d80..52af8f7 100644
|
||||
--- a/btrfs.c
|
||||
+++ b/btrfs.c
|
||||
@@ -329,6 +329,27 @@ static struct Command commands[] = {
|
||||
"Show status of running or finished scrub.",
|
||||
NULL
|
||||
},
|
||||
+ { do_restripe, -1,
|
||||
+ "filesystem restripe start", "[-d [filters]] [-m [filters]] "
|
||||
+ "[-s [filters]] [-vf] <path>\n"
|
||||
+ "Start restriper."
|
||||
+ },
|
||||
+ { do_restripe_cancel, 1,
|
||||
+ "filesystem restripe cancel", "<path>\n"
|
||||
+ "Cancel restriper."
|
||||
+ },
|
||||
+ { do_restripe_pause, 1,
|
||||
+ "filesystem restripe pause", "<path>\n"
|
||||
+ "Pause restriper."
|
||||
+ },
|
||||
+ { do_restripe_resume, 1,
|
||||
+ "filesystem restripe resume", "<path>\n"
|
||||
+ "Resume interrupted restripe operation."
|
||||
+ },
|
||||
+ { do_restripe_progress, -1,
|
||||
+ "filesystem restripe status", "[-v] <path>\n"
|
||||
+ "Show status of running or paused restripe operation."
|
||||
+ },
|
||||
{ do_scan, 999,
|
||||
"device scan", "[<device>...]\n"
|
||||
"Scan all device for or the passed device for a btrfs\n"
|
||||
diff --git a/btrfs_cmds.c b/btrfs_cmds.c
|
||||
index 1bfc669..e4c5592 100644
|
||||
--- a/btrfs_cmds.c
|
||||
+++ b/btrfs_cmds.c
|
||||
@@ -1094,14 +1094,515 @@ int do_balance(int argc, char **argv)
|
||||
e = errno;
|
||||
close(fdmnt);
|
||||
if(ret<0){
|
||||
- fprintf(stderr, "ERROR: error during balancing '%s' - %s\n",
|
||||
- path, strerror(e));
|
||||
+ if (e == ECANCELED) {
|
||||
+ fprintf(stderr, "restripe interrupted by user\n");
|
||||
+ } else {
|
||||
+ fprintf(stderr, "ERROR: error during restriping '%s' "
|
||||
+ "- %s\n", path, strerror(e));
|
||||
+ return 19;
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int parse_one_profile(char *profile, u64 *flags)
|
||||
+{
|
||||
+ if (!strcmp(profile, "raid0")) {
|
||||
+ *flags |= BTRFS_BLOCK_GROUP_RAID0;
|
||||
+ } else if (!strcmp(profile, "raid1")) {
|
||||
+ *flags |= BTRFS_BLOCK_GROUP_RAID1;
|
||||
+ } else if (!strcmp(profile, "raid10")) {
|
||||
+ *flags |= BTRFS_BLOCK_GROUP_RAID10;
|
||||
+ } else if (!strcmp(profile, "dup")) {
|
||||
+ *flags |= BTRFS_BLOCK_GROUP_DUP;
|
||||
+ } else if (!strcmp(profile, "single")) {
|
||||
+ *flags |= BTRFS_AVAIL_ALLOC_BIT_SINGLE;
|
||||
+ } else {
|
||||
+ fprintf(stderr, "Unknown profile '%s'\n", profile);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int parse_profiles(char *profiles, u64 *flags)
|
||||
+{
|
||||
+ char *this_char;
|
||||
+ char *save_ptr;
|
||||
+
|
||||
+ for (this_char = strtok_r(profiles, "|", &save_ptr);
|
||||
+ this_char != NULL;
|
||||
+ this_char = strtok_r(NULL, "|", &save_ptr)) {
|
||||
+ if (parse_one_profile(this_char, flags))
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int parse_range(char *range, u64 *start, u64 *end)
|
||||
+{
|
||||
+ char *dots;
|
||||
+
|
||||
+ dots = strstr(range, "..");
|
||||
+ if (dots) {
|
||||
+ const char *rest = dots + 2;
|
||||
+ int skipped = 0;
|
||||
+
|
||||
+ *dots = 0;
|
||||
+
|
||||
+ if (!*rest) {
|
||||
+ *end = (u64)-1;
|
||||
+ skipped++;
|
||||
+ } else {
|
||||
+ *end = strtoull(rest, (char **)NULL, 10);
|
||||
+ }
|
||||
+ if (dots == range) {
|
||||
+ *start = 0;
|
||||
+ skipped++;
|
||||
+ } else {
|
||||
+ *start = strtoull(range, (char **)NULL, 10);
|
||||
+ }
|
||||
+
|
||||
+ if (skipped <= 1)
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static int parse_filters(char *filters, struct btrfs_restripe_args *rargs)
|
||||
+{
|
||||
+ char *this_char;
|
||||
+ char *value;
|
||||
+ char *save_ptr;
|
||||
+
|
||||
+ if (!filters)
|
||||
+ return 0;
|
||||
+
|
||||
+ for (this_char = strtok_r(filters, ",", &save_ptr);
|
||||
+ this_char != NULL;
|
||||
+ this_char = strtok_r(NULL, ",", &save_ptr)) {
|
||||
+ if ((value = strchr(this_char, '=')) != NULL)
|
||||
+ *value++ = 0;
|
||||
+ if (!strcmp(this_char, "profiles")) {
|
||||
+ if (!value || !*value) {
|
||||
+ fprintf(stderr, "the profiles filter requires "
|
||||
+ "an argument\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ if (parse_profiles(value, &rargs->profiles)) {
|
||||
+ fprintf(stderr, "Invalid profiles argument\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ rargs->flags |= BTRFS_RESTRIPE_ARGS_PROFILES;
|
||||
+ } else if (!strcmp(this_char, "usage")) {
|
||||
+ if (!value || !*value) {
|
||||
+ fprintf(stderr, "the usage filter requires "
|
||||
+ "an argument\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ rargs->usage = strtoull(value, (char **)NULL, 10);
|
||||
+ if (rargs->usage < 1 || rargs->usage > 100) {
|
||||
+ fprintf(stderr, "Invalid usage argument: %s\n",
|
||||
+ value);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ rargs->flags |= BTRFS_RESTRIPE_ARGS_USAGE;
|
||||
+ } else if (!strcmp(this_char, "devid")) {
|
||||
+ if (!value || !*value) {
|
||||
+ fprintf(stderr, "the devid filter requires "
|
||||
+ "an argument\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ rargs->devid = strtoull(value, (char **)NULL, 10);
|
||||
+ if (rargs->devid == 0) {
|
||||
+ fprintf(stderr, "Invalid devid argument: %s\n",
|
||||
+ value);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ rargs->flags |= BTRFS_RESTRIPE_ARGS_DEVID;
|
||||
+ } else if (!strcmp(this_char, "drange")) {
|
||||
+ if (!value || !*value) {
|
||||
+ fprintf(stderr, "the drange filter requires "
|
||||
+ "an argument\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ if (parse_range(value, &rargs->pstart, &rargs->pend)) {
|
||||
+ fprintf(stderr, "Invalid drange argument\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ rargs->flags |= BTRFS_RESTRIPE_ARGS_DRANGE;
|
||||
+ } else if (!strcmp(this_char, "vrange")) {
|
||||
+ if (!value || !*value) {
|
||||
+ fprintf(stderr, "the vrange filter requires "
|
||||
+ "an argument\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ if (parse_range(value, &rargs->vstart, &rargs->vend)) {
|
||||
+ fprintf(stderr, "Invalid vrange argument\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ rargs->flags |= BTRFS_RESTRIPE_ARGS_VRANGE;
|
||||
+ } else if (!strcmp(this_char, "convert")) {
|
||||
+ if (!value || !*value) {
|
||||
+ fprintf(stderr, "the convert option requires "
|
||||
+ "an argument\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ if (parse_one_profile(value, &rargs->target)) {
|
||||
+ fprintf(stderr, "Invalid convert argument\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ rargs->flags |= BTRFS_RESTRIPE_ARGS_CONVERT;
|
||||
+ } else if (!strcmp(this_char, "soft")) {
|
||||
+ rargs->flags |= BTRFS_RESTRIPE_ARGS_SOFT;
|
||||
+ } else {
|
||||
+ fprintf(stderr, "Unrecognized restripe option '%s'\n",
|
||||
+ this_char);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void dump_ioctl_restripe_args(struct btrfs_ioctl_restripe_args *args);
|
||||
+
|
||||
+static struct option restripe_longopts[] = {
|
||||
+ { "data", 2, NULL, 'd'},
|
||||
+ { "metadata", 2, NULL, 'm' },
|
||||
+ { "system", 2, NULL, 's' },
|
||||
+ { "force", 0, NULL, 'f' },
|
||||
+ { "verbose", 0, NULL, 'v' },
|
||||
+ { 0, 0, 0, 0}
|
||||
+};
|
||||
|
||||
+/*
|
||||
+ * [-d [filters]] [-m [filters]] [-s [filters]] [-vf]
|
||||
+ */
|
||||
+int do_restripe(int ac, char **av)
|
||||
+{
|
||||
+ int fd;
|
||||
+ char *path;
|
||||
+ struct btrfs_ioctl_restripe_args args;
|
||||
+ struct btrfs_restripe_args *ptrs[] = { &args.data, &args.sys,
|
||||
+ &args.meta, NULL };
|
||||
+ int force = 0;
|
||||
+ int verbose = 0;
|
||||
+ int nofilters = 1;
|
||||
+ int i;
|
||||
+ int longindex;
|
||||
+ int ret;
|
||||
+ int e;
|
||||
+
|
||||
+ memset(&args, 0, sizeof(args));
|
||||
+
|
||||
+ while (1) {
|
||||
+ int opt = getopt_long(ac, av, "d::s::m::fv", restripe_longopts,
|
||||
+ &longindex);
|
||||
+ if (opt < 0)
|
||||
+ break;
|
||||
+
|
||||
+ switch (opt) {
|
||||
+ case 'd':
|
||||
+ nofilters = 0;
|
||||
+ args.flags |= BTRFS_RESTRIPE_DATA;
|
||||
+
|
||||
+ if (parse_filters(optarg, &args.data))
|
||||
+ return 1;
|
||||
+ break;
|
||||
+ case 's':
|
||||
+ nofilters = 0;
|
||||
+ args.flags |= BTRFS_RESTRIPE_SYSTEM;
|
||||
+
|
||||
+ if (parse_filters(optarg, &args.sys))
|
||||
+ return 1;
|
||||
+ break;
|
||||
+ case 'm':
|
||||
+ nofilters = 0;
|
||||
+ args.flags |= BTRFS_RESTRIPE_METADATA;
|
||||
+
|
||||
+ if (parse_filters(optarg, &args.meta))
|
||||
+ return 1;
|
||||
+ break;
|
||||
+ case 'f':
|
||||
+ force = 1;
|
||||
+ break;
|
||||
+ case 'v':
|
||||
+ verbose = 1;
|
||||
+ break;
|
||||
+ default:
|
||||
+ fprintf(stderr, "Invalid arguments for restripe\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (ac - optind != 1) {
|
||||
+ fprintf(stderr, "Invalid arguments for restripe\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (nofilters) {
|
||||
+ /* relocate everything - no filters */
|
||||
+ args.flags |= BTRFS_RESTRIPE_TYPE_MASK;
|
||||
+ }
|
||||
+
|
||||
+ /* drange makes sense only when devid is set */
|
||||
+ for (i = 0; ptrs[i]; i++) {
|
||||
+ if ((ptrs[i]->flags & BTRFS_RESTRIPE_ARGS_DRANGE) &&
|
||||
+ !(ptrs[i]->flags & BTRFS_RESTRIPE_ARGS_DEVID)) {
|
||||
+ fprintf(stderr, "drange filter can be used only if "
|
||||
+ "devid filter is used\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* soft makes sense only when convert for corresponding type is set */
|
||||
+ for (i = 0; ptrs[i]; i++) {
|
||||
+ if ((ptrs[i]->flags & BTRFS_RESTRIPE_ARGS_SOFT) &&
|
||||
+ !(ptrs[i]->flags & BTRFS_RESTRIPE_ARGS_CONVERT)) {
|
||||
+ fprintf(stderr, "'soft' option can be used only if "
|
||||
+ "changing profiles\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ path = av[optind];
|
||||
+ fd = open_file_or_dir(path);
|
||||
+ if (fd < 0) {
|
||||
+ fprintf(stderr, "ERROR: can't access to '%s'\n", path);
|
||||
+ return 12;
|
||||
+ }
|
||||
+
|
||||
+ if (force)
|
||||
+ args.flags |= BTRFS_RESTRIPE_FORCE;
|
||||
+ if (verbose)
|
||||
+ dump_ioctl_restripe_args(&args);
|
||||
+
|
||||
+ ret = ioctl(fd, BTRFS_IOC_RESTRIPE, &args);
|
||||
+ e = errno;
|
||||
+ close(fd);
|
||||
+
|
||||
+ if (ret < 0) {
|
||||
+ if (e == ECANCELED) {
|
||||
+ fprintf(stderr, "restripe interrupted by user\n");
|
||||
+ } else {
|
||||
+ fprintf(stderr, "ERROR: error during restriping '%s' "
|
||||
+ "- %s\n", path, strerror(e));
|
||||
+ return 19;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int do_restripe_cancel(int ac, char **av)
|
||||
+{
|
||||
+ int fd;
|
||||
+ char *path = av[1];
|
||||
+ int ret;
|
||||
+ int e;
|
||||
+
|
||||
+ fd = open_file_or_dir(path);
|
||||
+ if (fd < 0) {
|
||||
+ fprintf(stderr, "ERROR: can't access to '%s'\n", path);
|
||||
+ return 12;
|
||||
+ }
|
||||
+
|
||||
+ ret = ioctl(fd, BTRFS_IOC_RESTRIPE_CTL, BTRFS_RESTRIPE_CTL_CANCEL);
|
||||
+ e = errno;
|
||||
+ close(fd);
|
||||
+
|
||||
+ if (ret < 0) {
|
||||
+ fprintf(stderr, "ERROR: restripe cancel on '%s' failed - %s\n",
|
||||
+ path, (e == ENOTCONN) ? "Not in progress" : strerror(e));
|
||||
+ return 19;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int do_restripe_pause(int ac, char **av)
|
||||
+{
|
||||
+ int fd;
|
||||
+ char *path = av[1];
|
||||
+ int ret;
|
||||
+ int e;
|
||||
+
|
||||
+ fd = open_file_or_dir(path);
|
||||
+ if (fd < 0) {
|
||||
+ fprintf(stderr, "ERROR: can't access to '%s'\n", path);
|
||||
+ return 12;
|
||||
+ }
|
||||
+
|
||||
+ ret = ioctl(fd, BTRFS_IOC_RESTRIPE_CTL, BTRFS_RESTRIPE_CTL_PAUSE);
|
||||
+ e = errno;
|
||||
+ close(fd);
|
||||
+
|
||||
+ if (ret < 0) {
|
||||
+ fprintf(stderr, "ERROR: restripe pause on '%s' failed - %s\n",
|
||||
+ path, (e == ENOTCONN) ? "Not running" : strerror(e));
|
||||
+ return 19;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int do_restripe_resume(int ac, char **av)
|
||||
+{
|
||||
+ int fd;
|
||||
+ char *path = av[1];
|
||||
+ int ret;
|
||||
+ int e;
|
||||
+
|
||||
+ fd = open_file_or_dir(path);
|
||||
+ if (fd < 0) {
|
||||
+ fprintf(stderr, "ERROR: can't access to '%s'\n", path);
|
||||
+ return 12;
|
||||
+ }
|
||||
+
|
||||
+ ret = ioctl(fd, BTRFS_IOC_RESTRIPE_CTL, BTRFS_RESTRIPE_CTL_RESUME);
|
||||
+ e = errno;
|
||||
+ close(fd);
|
||||
+
|
||||
+ if (ret < 0) {
|
||||
+ if (e == ECANCELED) {
|
||||
+ fprintf(stderr, "restripe interrupted by user\n");
|
||||
+ } else if (e == ENOTCONN || e == EINPROGRESS) {
|
||||
+ fprintf(stderr, "ERROR: restripe resume on '%s' "
|
||||
+ "failed - %s\n", path,
|
||||
+ (e == ENOTCONN) ? "Not in progress" :
|
||||
+ "Already running");
|
||||
+ return 19;
|
||||
+ } else {
|
||||
+ fprintf(stderr, "ERROR: error during restriping '%s' "
|
||||
+ "- %s\n", path, strerror(e));
|
||||
+ return 19;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct option restripe_progress_longopts[] = {
|
||||
+ { "verbose", 0, NULL, 'v' },
|
||||
+ { 0, 0, 0, 0}
|
||||
+};
|
||||
+
|
||||
+int do_restripe_progress(int ac, char **av)
|
||||
+{
|
||||
+ int fd;
|
||||
+ char *path;
|
||||
+ struct btrfs_ioctl_restripe_args args;
|
||||
+ int verbose = 0;
|
||||
+ int longindex;
|
||||
+ int ret;
|
||||
+ int e;
|
||||
+
|
||||
+ while (1) {
|
||||
+ int opt = getopt_long(ac, av, "v", restripe_progress_longopts,
|
||||
+ &longindex);
|
||||
+ if (opt < 0)
|
||||
+ break;
|
||||
+
|
||||
+ switch (opt) {
|
||||
+ case 'v':
|
||||
+ verbose = 1;
|
||||
+ break;
|
||||
+ default:
|
||||
+ fprintf(stderr, "Invalid arguments for restripe "
|
||||
+ "status\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (ac - optind != 1) {
|
||||
+ fprintf(stderr, "Invalid arguments for restripe status\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ path = av[optind];
|
||||
+ fd = open_file_or_dir(path);
|
||||
+ if (fd < 0) {
|
||||
+ fprintf(stderr, "ERROR: can't access to '%s'\n", path);
|
||||
+ return 12;
|
||||
+ }
|
||||
+
|
||||
+ ret = ioctl(fd, BTRFS_IOC_RESTRIPE_PROGRESS, &args);
|
||||
+ e = errno;
|
||||
+ close(fd);
|
||||
+
|
||||
+ if (ret < 0) {
|
||||
+ fprintf(stderr, "ERROR: restripe status on '%s' failed - %s\n",
|
||||
+ path, (e == ENOTCONN) ? "Not in progress" : strerror(e));
|
||||
return 19;
|
||||
}
|
||||
+
|
||||
+ if (args.state & BTRFS_RESTRIPE_ST_RUNNING) {
|
||||
+ printf("Restripe on '%s' is running", path);
|
||||
+ if (args.state & BTRFS_RESTRIPE_ST_CANCEL_REQ)
|
||||
+ printf(", cancel requested\n");
|
||||
+ else if (args.state & BTRFS_RESTRIPE_ST_PAUSE_REQ)
|
||||
+ printf(", pause requested\n");
|
||||
+ else
|
||||
+ printf("\n");
|
||||
+ } else {
|
||||
+ printf("Restripe on '%s' is paused\n", path);
|
||||
+ }
|
||||
+
|
||||
+ printf("%llu out of about %llu chunks restriped (%llu considered), "
|
||||
+ "%3.f%% left\n", args.stat.completed, args.stat.expected,
|
||||
+ args.stat.considered,
|
||||
+ 100 * (1 - (float)args.stat.completed/args.stat.expected));
|
||||
+
|
||||
+ if (verbose)
|
||||
+ dump_ioctl_restripe_args(&args);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void dump_restripe_args(struct btrfs_restripe_args *args)
|
||||
+{
|
||||
+ if (args->flags & BTRFS_RESTRIPE_ARGS_CONVERT) {
|
||||
+ printf("converting, target=%llu, soft is %s", args->target,
|
||||
+ (args->flags & BTRFS_RESTRIPE_ARGS_SOFT) ? "on" : "off");
|
||||
+ } else {
|
||||
+ printf("balancing");
|
||||
+ }
|
||||
+
|
||||
+ if (args->flags & BTRFS_RESTRIPE_ARGS_PROFILES)
|
||||
+ printf(", profiles=%llu", args->profiles);
|
||||
+ if (args->flags & BTRFS_RESTRIPE_ARGS_USAGE)
|
||||
+ printf(", usage=%llu", args->usage);
|
||||
+ if (args->flags & BTRFS_RESTRIPE_ARGS_DEVID)
|
||||
+ printf(", devid=%llu", args->devid);
|
||||
+ if (args->flags & BTRFS_RESTRIPE_ARGS_DRANGE)
|
||||
+ printf(", drange=%llu..%llu", args->pstart, args->pend);
|
||||
+ if (args->flags & BTRFS_RESTRIPE_ARGS_VRANGE)
|
||||
+ printf(", vrange=%llu..%llu", args->vstart, args->vend);
|
||||
+
|
||||
+ printf("\n");
|
||||
+}
|
||||
+
|
||||
+static void dump_ioctl_restripe_args(struct btrfs_ioctl_restripe_args *args)
|
||||
+{
|
||||
+ printf("Dumping filters: flags 0x%llx, state 0x%llx, force is %s\n",
|
||||
+ args->flags, args->state,
|
||||
+ (args->flags & BTRFS_RESTRIPE_FORCE) ? "on" : "off");
|
||||
+ if (args->flags & BTRFS_RESTRIPE_DATA) {
|
||||
+ printf(" DATA (flags 0x%llx): ", args->data.flags);
|
||||
+ dump_restripe_args(&args->data);
|
||||
+ }
|
||||
+ if (args->flags & BTRFS_RESTRIPE_METADATA) {
|
||||
+ printf(" METADATA (flags 0x%llx): ", args->meta.flags);
|
||||
+ dump_restripe_args(&args->meta);
|
||||
+ }
|
||||
+ if (args->flags & BTRFS_RESTRIPE_SYSTEM) {
|
||||
+ printf(" SYSTEM (flags 0x%llx): ", args->sys.flags);
|
||||
+ dump_restripe_args(&args->sys);
|
||||
+ }
|
||||
+}
|
||||
|
||||
|
||||
/**** man: btrfs device delete
|
||||
diff --git a/btrfs_cmds.h b/btrfs_cmds.h
|
||||
index 81182b1..2cd0ac1 100644
|
||||
--- a/btrfs_cmds.h
|
||||
+++ b/btrfs_cmds.h
|
||||
@@ -27,6 +27,11 @@ int do_scrub_start(int nargs, char **argv);
|
||||
int do_scrub_status(int argc, char **argv);
|
||||
int do_scrub_resume(int argc, char **argv);
|
||||
int do_scrub_cancel(int nargs, char **argv);
|
||||
+int do_restripe(int ac, char **av);
|
||||
+int do_restripe_cancel(int ac, char **av);
|
||||
+int do_restripe_pause(int ac, char **av);
|
||||
+int do_restripe_resume(int ac, char **av);
|
||||
+int do_restripe_progress(int ac, char **av);
|
||||
int do_remove_volume(int nargs, char **args);
|
||||
int do_scan(int nargs, char **argv);
|
||||
int do_resize(int nargs, char **argv);
|
||||
diff --git a/ctree.h b/ctree.h
|
||||
index 54748c8..58ea3d3 100644
|
||||
--- a/ctree.h
|
||||
+++ b/ctree.h
|
||||
@@ -61,6 +61,9 @@ struct btrfs_trans_handle;
|
||||
#define BTRFS_CSUM_TREE_OBJECTID 7ULL
|
||||
|
||||
|
||||
+/* for storing restripe params in the root tree */
|
||||
+#define BTRFS_RESTRIPE_OBJECTID -4ULL
|
||||
+
|
||||
/* oprhan objectid for tracking unlinked/truncated files */
|
||||
#define BTRFS_ORPHAN_OBJECTID -5ULL
|
||||
|
||||
@@ -705,6 +708,12 @@ struct btrfs_csum_item {
|
||||
#define BTRFS_BLOCK_GROUP_DUP (1 << 5)
|
||||
#define BTRFS_BLOCK_GROUP_RAID10 (1 << 6)
|
||||
|
||||
+/*
|
||||
+ * to avoid troubles..
|
||||
+ */
|
||||
+#define BTRFS_AVAIL_ALLOC_BIT_SINGLE (1 << 7)
|
||||
+#define BTRFS_BLOCK_GROUP_RESERVED (1 << 7)
|
||||
+
|
||||
struct btrfs_block_group_item {
|
||||
__le64 used;
|
||||
__le64 chunk_objectid;
|
||||
diff --git a/ioctl.h b/ioctl.h
|
||||
index 1ae7537..af8b18b 100644
|
||||
--- a/ioctl.h
|
||||
+++ b/ioctl.h
|
||||
@@ -91,6 +91,45 @@ struct btrfs_ioctl_fs_info_args {
|
||||
__u64 reserved[124]; /* pad to 1k */
|
||||
};
|
||||
|
||||
+#define BTRFS_RESTRIPE_CTL_CANCEL 1
|
||||
+#define BTRFS_RESTRIPE_CTL_PAUSE 2
|
||||
+#define BTRFS_RESTRIPE_CTL_RESUME 3
|
||||
+
|
||||
+struct btrfs_restripe_args {
|
||||
+ __u64 profiles;
|
||||
+ __u64 usage;
|
||||
+ __u64 devid;
|
||||
+ __u64 pstart;
|
||||
+ __u64 pend;
|
||||
+ __u64 vstart;
|
||||
+ __u64 vend;
|
||||
+
|
||||
+ __u64 target;
|
||||
+
|
||||
+ __u64 flags;
|
||||
+
|
||||
+ __u64 unused[8];
|
||||
+} __attribute__ ((__packed__));
|
||||
+
|
||||
+struct btrfs_restripe_progress {
|
||||
+ __u64 expected;
|
||||
+ __u64 considered;
|
||||
+ __u64 completed;
|
||||
+};
|
||||
+
|
||||
+struct btrfs_ioctl_restripe_args {
|
||||
+ __u64 flags;
|
||||
+ __u64 state;
|
||||
+
|
||||
+ struct btrfs_restripe_args data;
|
||||
+ struct btrfs_restripe_args sys;
|
||||
+ struct btrfs_restripe_args meta;
|
||||
+
|
||||
+ struct btrfs_restripe_progress stat;
|
||||
+
|
||||
+ __u64 unused[72]; /* pad to 1k */
|
||||
+};
|
||||
+
|
||||
struct btrfs_ioctl_search_key {
|
||||
/* which root are we searching. 0 is the tree of tree roots */
|
||||
__u64 tree_id;
|
||||
@@ -272,10 +311,15 @@ struct btrfs_ioctl_logical_ino_args {
|
||||
#define BTRFS_IOC_DEV_INFO _IOWR(BTRFS_IOCTL_MAGIC, 30, \
|
||||
struct btrfs_ioctl_dev_info_args)
|
||||
#define BTRFS_IOC_FS_INFO _IOR(BTRFS_IOCTL_MAGIC, 31, \
|
||||
- struct btrfs_ioctl_fs_info_args)
|
||||
+ struct btrfs_ioctl_fs_info_args)
|
||||
#define BTRFS_IOC_INO_PATHS _IOWR(BTRFS_IOCTL_MAGIC, 35, \
|
||||
struct btrfs_ioctl_ino_path_args)
|
||||
#define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, \
|
||||
struct btrfs_ioctl_ino_path_args)
|
||||
|
||||
+#define BTRFS_IOC_RESTRIPE _IOW(BTRFS_IOCTL_MAGIC, 32, \
|
||||
+ struct btrfs_ioctl_restripe_args)
|
||||
+#define BTRFS_IOC_RESTRIPE_CTL _IOW(BTRFS_IOCTL_MAGIC, 33, int)
|
||||
+#define BTRFS_IOC_RESTRIPE_PROGRESS _IOR(BTRFS_IOCTL_MAGIC, 34, \
|
||||
+ struct btrfs_ioctl_restripe_args)
|
||||
#endif
|
||||
diff --git a/print-tree.c b/print-tree.c
|
||||
index 6039699..49f98af 100644
|
||||
--- a/print-tree.c
|
||||
+++ b/print-tree.c
|
||||
@@ -391,6 +391,9 @@ static void print_objectid(unsigned long long objectid, u8 type)
|
||||
case BTRFS_CSUM_TREE_OBJECTID:
|
||||
printf("CSUM_TREE");
|
||||
break;
|
||||
+ case BTRFS_RESTRIPE_OBJECTID:
|
||||
+ printf("RESTRIPE");
|
||||
+ break;
|
||||
case BTRFS_ORPHAN_OBJECTID:
|
||||
printf("ORPHAN");
|
||||
break;
|
||||
diff --git a/volumes.h b/volumes.h
|
||||
index 7104d36..6929aca 100644
|
||||
--- a/volumes.h
|
||||
+++ b/volumes.h
|
||||
@@ -91,6 +91,48 @@ struct btrfs_multi_bio {
|
||||
#define btrfs_multi_bio_size(n) (sizeof(struct btrfs_multi_bio) + \
|
||||
(sizeof(struct btrfs_bio_stripe) * (n)))
|
||||
|
||||
+/*
|
||||
+ * Restriper's general "type" filter. Shares bits with chunk type for
|
||||
+ * simplicity, RESTRIPE prefix is used to avoid confusion.
|
||||
+ */
|
||||
+#define BTRFS_RESTRIPE_DATA (1ULL << 0)
|
||||
+#define BTRFS_RESTRIPE_SYSTEM (1ULL << 1)
|
||||
+#define BTRFS_RESTRIPE_METADATA (1ULL << 2)
|
||||
+
|
||||
+#define BTRFS_RESTRIPE_TYPE_MASK (BTRFS_RESTRIPE_DATA | \
|
||||
+ BTRFS_RESTRIPE_SYSTEM | \
|
||||
+ BTRFS_RESTRIPE_METADATA)
|
||||
+
|
||||
+#define BTRFS_RESTRIPE_FORCE (1ULL << 3)
|
||||
+
|
||||
+/*
|
||||
+ * Restripe filters
|
||||
+ */
|
||||
+#define BTRFS_RESTRIPE_ARGS_PROFILES (1ULL << 0)
|
||||
+#define BTRFS_RESTRIPE_ARGS_USAGE (1ULL << 1)
|
||||
+#define BTRFS_RESTRIPE_ARGS_DEVID (1ULL << 2)
|
||||
+#define BTRFS_RESTRIPE_ARGS_DRANGE (1ULL << 3)
|
||||
+#define BTRFS_RESTRIPE_ARGS_VRANGE (1ULL << 4)
|
||||
+
|
||||
+/*
|
||||
+ * Profile changing flags. When SOFT is set we won't relocate chunk if
|
||||
+ * it already has the target profile (even though it may be
|
||||
+ * half-filled).
|
||||
+ */
|
||||
+#define BTRFS_RESTRIPE_ARGS_CONVERT (1ULL << 8)
|
||||
+#define BTRFS_RESTRIPE_ARGS_SOFT (1ULL << 9)
|
||||
+
|
||||
+/*
|
||||
+ * Restripe state bits
|
||||
+ */
|
||||
+#define RESTRIPE_RUNNING 0
|
||||
+#define RESTRIPE_CANCEL_REQ 1
|
||||
+#define RESTRIPE_PAUSE_REQ 2
|
||||
+
|
||||
+#define BTRFS_RESTRIPE_ST_RUNNING (1ULL << RESTRIPE_RUNNING)
|
||||
+#define BTRFS_RESTRIPE_ST_CANCEL_REQ (1ULL << RESTRIPE_CANCEL_REQ)
|
||||
+#define BTRFS_RESTRIPE_ST_PAUSE_REQ (1ULL << RESTRIPE_PAUSE_REQ)
|
||||
+
|
||||
int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_device *device,
|
||||
u64 chunk_tree, u64 chunk_objectid,
|
||||
--
|
||||
1.7.6.233.gd79bc
|
||||
|
1225
0114-btrfs-progs-add-qgroup-commands.patch
Normal file
1225
0114-btrfs-progs-add-qgroup-commands.patch
Normal file
File diff suppressed because it is too large
Load Diff
85
0115-btrfs-progs-fixup-is_mounted-checks.patch
Normal file
85
0115-btrfs-progs-fixup-is_mounted-checks.patch
Normal file
@ -0,0 +1,85 @@
|
||||
From 6ca37050db7e94257559da2b8e8009c2347ed798 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Mason <chris.mason@oracle.com>
|
||||
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 <chris.mason@oracle.com>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,95 @@
|
||||
From 0e6aead68455a1043aed04e0557dc14af2cd6f60 Mon Sep 17 00:00:00 2001
|
||||
From: Josef Bacik <josef@redhat.com>
|
||||
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 <josef@redhat.com>
|
||||
---
|
||||
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
|
||||
|
134
0117-Btrfs-progs-try-other-mirrors-if-decomression-fails.patch
Normal file
134
0117-Btrfs-progs-try-other-mirrors-if-decomression-fails.patch
Normal file
@ -0,0 +1,134 @@
|
||||
From 9dee07a6365d2facddea9a501737dce92333c582 Mon Sep 17 00:00:00 2001
|
||||
From: Josef Bacik <josef@redhat.com>
|
||||
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 <josef@redhat.com>
|
||||
---
|
||||
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
|
||||
|
40
0118-Btrfs-progs-try-other-mirrors-on-read-failure.patch
Normal file
40
0118-Btrfs-progs-try-other-mirrors-on-read-failure.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From ff0e1b17030a9b1e027c8b77f67ab44136e172ac Mon Sep 17 00:00:00 2001
|
||||
From: Josef Bacik <josef@redhat.com>
|
||||
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 <josef@redhat.com>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,54 @@
|
||||
From 16073605bb947e6acfa3b13b6280a90fed9b717a Mon Sep 17 00:00:00 2001
|
||||
From: David Marcin <djmarcin@google.com>
|
||||
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
|
||||
|
55
0120-btrfs-progs-Check-metadata-mirrors-in-find-root.patch
Normal file
55
0120-btrfs-progs-Check-metadata-mirrors-in-find-root.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From a1ebf7b951c6796039748601404aa01fd283ddef Mon Sep 17 00:00:00 2001
|
||||
From: David Marcin <djmarcin@google.com>
|
||||
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 <djmarcin@google.com>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,84 @@
|
||||
From 266f413a32d774c68f41f488bb79fac6ad63e930 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Stuge <peter@stuge.se>
|
||||
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 <peter@stuge.se>
|
||||
Signed-off-by: Josef Bacik <josef@redhat.com>
|
||||
---
|
||||
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
|
||||
|
130
0122-restore-Add-regex-matching-of-paths-and-files-to-be-.patch
Normal file
130
0122-restore-Add-regex-matching-of-paths-and-files-to-be-.patch
Normal file
@ -0,0 +1,130 @@
|
||||
From 2f0c2a29ab13b17ae1cc21effcf532f2447b7c8c Mon Sep 17 00:00:00 2001
|
||||
From: Peter Stuge <peter@stuge.se>
|
||||
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 <peter@stuge.se>
|
||||
Signed-off-by: Josef Bacik <josef@redhat.com>
|
||||
---
|
||||
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 <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <zlib.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <regex.h>
|
||||
#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
|
||||
|
@ -0,0 +1,92 @@
|
||||
From e8919ef79253ace49de01ba228290e4e0cafbfb7 Mon Sep 17 00:00:00 2001
|
||||
From: David Marcin <djmarcin@google.com>
|
||||
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 <djmarcin@google.com>
|
||||
---
|
||||
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
|
||||
|
161
0124-btrfs-progs-Add-utility-to-dump-all-superblocks-foun.patch
Normal file
161
0124-btrfs-progs-Add-utility-to-dump-all-superblocks-foun.patch
Normal file
@ -0,0 +1,161 @@
|
||||
From db874f1e8924e86bbdee6600b0e5b3e6d11f9238 Mon Sep 17 00:00:00 2001
|
||||
From: David Marcin <djmarcin@google.com>
|
||||
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 <djmarcin@google.com>
|
||||
---
|
||||
.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 <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <sys/stat.h>
|
||||
+#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;
|
||||
+}
|
179
0125-btrfs-progs-Add-the-ability-to-use-the-earliest-supe.patch
Normal file
179
0125-btrfs-progs-Add-the-ability-to-use-the-earliest-supe.patch
Normal file
@ -0,0 +1,179 @@
|
||||
From 6330d8d3b70c0ad35ce8048ccf69b3e96718ed53 Mon Sep 17 00:00:00 2001
|
||||
From: David Marcin <djmarcin@google.com>
|
||||
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 <djmarcin@google.com>
|
||||
---
|
||||
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
|
||||
|
111
0126-btrfs-progs-Use-oldest-super-for-btrfs-select-super..patch
Normal file
111
0126-btrfs-progs-Use-oldest-super-for-btrfs-select-super..patch
Normal file
@ -0,0 +1,111 @@
|
||||
From a780325614c0d89c9c0ea6779ada5af512b6e319 Mon Sep 17 00:00:00 2001
|
||||
From: David Marcin <djmarcin@google.com>
|
||||
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 <djmarcin@google.com>
|
||||
---
|
||||
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
|
||||
|
191
0127-btrfs-progs-add-lzo-compression-support-to-restore.patch
Normal file
191
0127-btrfs-progs-add-lzo-compression-support-to-restore.patch
Normal file
@ -0,0 +1,191 @@
|
||||
From 2fe46117d3cde3737a1600195883e63ab4c59a8d Mon Sep 17 00:00:00 2001
|
||||
From: Josef Bacik <josef@redhat.com>
|
||||
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 <josef@redhat.com>
|
||||
---
|
||||
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 <zlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <regex.h>
|
||||
+#include <lzo/lzoconf.h>
|
||||
+#include <lzo/lzo1x.h>
|
||||
#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
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 1b8b3c3579ee127b174a850213df7ad81edd5710 Mon Sep 17 00:00:00 2001
|
||||
From: Josef Bacik <josef@redhat.com>
|
||||
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 <josef@redhat.com>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,36 @@
|
||||
From 3ceceda914e19a3f7982c5050e6ffb23522071f2 Mon Sep 17 00:00:00 2001
|
||||
From: David Marcin <djmarcin@google.com>
|
||||
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 <djmarcin@google.com>
|
||||
---
|
||||
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
|
||||
|
443
0130-Btrfs-progs-fix-restore-to-fall-back-to-the-broken-o.patch
Normal file
443
0130-Btrfs-progs-fix-restore-to-fall-back-to-the-broken-o.patch
Normal file
@ -0,0 +1,443 @@
|
||||
From fb0cfed5d3500e76ce30c6a9803ee1720bf1b4a5 Mon Sep 17 00:00:00 2001
|
||||
From: Josef Bacik <josef@redhat.com>
|
||||
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 <josef@redhat.com>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,32 @@
|
||||
From 412d4f1fe3a14c7e61efbd0ad4280323de71606a Mon Sep 17 00:00:00 2001
|
||||
From: Josef Bacik <josef@redhat.com>
|
||||
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 <josef@redhat.com>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,37 @@
|
||||
From df8b44a2980ace8b2e7483b96a661907e20b8a4c Mon Sep 17 00:00:00 2001
|
||||
From: Josef Bacik <josef@redhat.com>
|
||||
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 <josef@redhat.com>
|
||||
---
|
||||
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
|
||||
|
31
0133-Btrfs-progs-check-return-value-properly.patch
Normal file
31
0133-Btrfs-progs-check-return-value-properly.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From 4686f96637316b509cb16c657b73b40a329be6db Mon Sep 17 00:00:00 2001
|
||||
From: Josef Bacik <josef@redhat.com>
|
||||
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 <josef@redhat.com>
|
||||
---
|
||||
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
|
||||
|
180
0134-Btrfs-progs-give-restore-a-list-roots-option.patch
Normal file
180
0134-Btrfs-progs-give-restore-a-list-roots-option.patch
Normal file
@ -0,0 +1,180 @@
|
||||
From 9bb7aa76e43f4942f5fa398bf00778067859f66c Mon Sep 17 00:00:00 2001
|
||||
From: Josef Bacik <josef@redhat.com>
|
||||
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 <josef@redhat.com>
|
||||
---
|
||||
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
|
||||
|
32
0135-Btrfs-progs-fix-compiler-warning-of-extent-tree.c.patch
Normal file
32
0135-Btrfs-progs-fix-compiler-warning-of-extent-tree.c.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 243a10fc066200621fbdee91eb28a53f5cc91d81 Mon Sep 17 00:00:00 2001
|
||||
From: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
|
||||
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 <t-itoh@jp.fujitsu.com>
|
||||
---
|
||||
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
|
||||
|
130
0136-Btrfs-progs-change-the-way-mkfs-picks-raid-profiles.patch
Normal file
130
0136-Btrfs-progs-change-the-way-mkfs-picks-raid-profiles.patch
Normal file
@ -0,0 +1,130 @@
|
||||
From 6b74bd1ecd84d86cad6aaa1fd643de6f3f3c40b8 Mon Sep 17 00:00:00 2001
|
||||
From: Ilya Dryomov <idryomov@gmail.com>
|
||||
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 <idryomov@gmail.com>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,45 @@
|
||||
From 670b953e28c25f835b713a22b03b9b0f86d8e025 Mon Sep 17 00:00:00 2001
|
||||
From: Ilya Dryomov <idryomov@gmail.com>
|
||||
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 <idryomov@gmail.com>
|
||||
---
|
||||
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
|
||||
|
32
0138-Btrfs-progs-bugfix-for-scrubbing-single-devices.patch
Normal file
32
0138-Btrfs-progs-bugfix-for-scrubbing-single-devices.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From d439a663a5ba789f7542163317264a6b4dbbe3f2 Mon Sep 17 00:00:00 2001
|
||||
From: Arne Jansen <sensille@gmx.net>
|
||||
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 <sensille@gmx.net>
|
||||
---
|
||||
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
|
||||
|
1164
0900-Revert-btrfs-progs-add-qgroup-commands.patch
Normal file
1164
0900-Revert-btrfs-progs-add-qgroup-commands.patch
Normal file
File diff suppressed because it is too large
Load Diff
750
0901-Revert-Btrfs-progs-add-restriper-commands.patch
Normal file
750
0901-Revert-Btrfs-progs-add-restriper-commands.patch
Normal file
@ -0,0 +1,750 @@
|
||||
From 927d075e63d7c21038c53eae1e1b1edbdb01cdcf Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.cz>
|
||||
Date: Wed, 14 Dec 2011 18:46:02 +0100
|
||||
Subject: [PATCH] Revert "Btrfs-progs: add restriper commands"
|
||||
|
||||
This reverts commit 192484f121dbbffd004303a760ef8b4dbd470ce2.
|
||||
---
|
||||
btrfs.c | 21 ---
|
||||
btrfs_cmds.c | 505 +---------------------------------------------------------
|
||||
btrfs_cmds.h | 5 -
|
||||
ctree.h | 9 -
|
||||
ioctl.h | 46 +-----
|
||||
print-tree.c | 3 -
|
||||
volumes.h | 42 -----
|
||||
7 files changed, 3 insertions(+), 628 deletions(-)
|
||||
|
||||
diff --git a/btrfs.c b/btrfs.c
|
||||
index 52af8f7..66b0d80 100644
|
||||
--- a/btrfs.c
|
||||
+++ b/btrfs.c
|
||||
@@ -329,27 +329,6 @@ static struct Command commands[] = {
|
||||
"Show status of running or finished scrub.",
|
||||
NULL
|
||||
},
|
||||
- { do_restripe, -1,
|
||||
- "filesystem restripe start", "[-d [filters]] [-m [filters]] "
|
||||
- "[-s [filters]] [-vf] <path>\n"
|
||||
- "Start restriper."
|
||||
- },
|
||||
- { do_restripe_cancel, 1,
|
||||
- "filesystem restripe cancel", "<path>\n"
|
||||
- "Cancel restriper."
|
||||
- },
|
||||
- { do_restripe_pause, 1,
|
||||
- "filesystem restripe pause", "<path>\n"
|
||||
- "Pause restriper."
|
||||
- },
|
||||
- { do_restripe_resume, 1,
|
||||
- "filesystem restripe resume", "<path>\n"
|
||||
- "Resume interrupted restripe operation."
|
||||
- },
|
||||
- { do_restripe_progress, -1,
|
||||
- "filesystem restripe status", "[-v] <path>\n"
|
||||
- "Show status of running or paused restripe operation."
|
||||
- },
|
||||
{ do_scan, 999,
|
||||
"device scan", "[<device>...]\n"
|
||||
"Scan all device for or the passed device for a btrfs\n"
|
||||
diff --git a/btrfs_cmds.c b/btrfs_cmds.c
|
||||
index e4c5592..1bfc669 100644
|
||||
--- a/btrfs_cmds.c
|
||||
+++ b/btrfs_cmds.c
|
||||
@@ -1094,515 +1094,14 @@ int do_balance(int argc, char **argv)
|
||||
e = errno;
|
||||
close(fdmnt);
|
||||
if(ret<0){
|
||||
- if (e == ECANCELED) {
|
||||
- fprintf(stderr, "restripe interrupted by user\n");
|
||||
- } else {
|
||||
- fprintf(stderr, "ERROR: error during restriping '%s' "
|
||||
- "- %s\n", path, strerror(e));
|
||||
- return 19;
|
||||
- }
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int parse_one_profile(char *profile, u64 *flags)
|
||||
-{
|
||||
- if (!strcmp(profile, "raid0")) {
|
||||
- *flags |= BTRFS_BLOCK_GROUP_RAID0;
|
||||
- } else if (!strcmp(profile, "raid1")) {
|
||||
- *flags |= BTRFS_BLOCK_GROUP_RAID1;
|
||||
- } else if (!strcmp(profile, "raid10")) {
|
||||
- *flags |= BTRFS_BLOCK_GROUP_RAID10;
|
||||
- } else if (!strcmp(profile, "dup")) {
|
||||
- *flags |= BTRFS_BLOCK_GROUP_DUP;
|
||||
- } else if (!strcmp(profile, "single")) {
|
||||
- *flags |= BTRFS_AVAIL_ALLOC_BIT_SINGLE;
|
||||
- } else {
|
||||
- fprintf(stderr, "Unknown profile '%s'\n", profile);
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int parse_profiles(char *profiles, u64 *flags)
|
||||
-{
|
||||
- char *this_char;
|
||||
- char *save_ptr;
|
||||
-
|
||||
- for (this_char = strtok_r(profiles, "|", &save_ptr);
|
||||
- this_char != NULL;
|
||||
- this_char = strtok_r(NULL, "|", &save_ptr)) {
|
||||
- if (parse_one_profile(this_char, flags))
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int parse_range(char *range, u64 *start, u64 *end)
|
||||
-{
|
||||
- char *dots;
|
||||
-
|
||||
- dots = strstr(range, "..");
|
||||
- if (dots) {
|
||||
- const char *rest = dots + 2;
|
||||
- int skipped = 0;
|
||||
-
|
||||
- *dots = 0;
|
||||
-
|
||||
- if (!*rest) {
|
||||
- *end = (u64)-1;
|
||||
- skipped++;
|
||||
- } else {
|
||||
- *end = strtoull(rest, (char **)NULL, 10);
|
||||
- }
|
||||
- if (dots == range) {
|
||||
- *start = 0;
|
||||
- skipped++;
|
||||
- } else {
|
||||
- *start = strtoull(range, (char **)NULL, 10);
|
||||
- }
|
||||
-
|
||||
- if (skipped <= 1)
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
-static int parse_filters(char *filters, struct btrfs_restripe_args *rargs)
|
||||
-{
|
||||
- char *this_char;
|
||||
- char *value;
|
||||
- char *save_ptr;
|
||||
-
|
||||
- if (!filters)
|
||||
- return 0;
|
||||
-
|
||||
- for (this_char = strtok_r(filters, ",", &save_ptr);
|
||||
- this_char != NULL;
|
||||
- this_char = strtok_r(NULL, ",", &save_ptr)) {
|
||||
- if ((value = strchr(this_char, '=')) != NULL)
|
||||
- *value++ = 0;
|
||||
- if (!strcmp(this_char, "profiles")) {
|
||||
- if (!value || !*value) {
|
||||
- fprintf(stderr, "the profiles filter requires "
|
||||
- "an argument\n");
|
||||
- return 1;
|
||||
- }
|
||||
- if (parse_profiles(value, &rargs->profiles)) {
|
||||
- fprintf(stderr, "Invalid profiles argument\n");
|
||||
- return 1;
|
||||
- }
|
||||
- rargs->flags |= BTRFS_RESTRIPE_ARGS_PROFILES;
|
||||
- } else if (!strcmp(this_char, "usage")) {
|
||||
- if (!value || !*value) {
|
||||
- fprintf(stderr, "the usage filter requires "
|
||||
- "an argument\n");
|
||||
- return 1;
|
||||
- }
|
||||
- rargs->usage = strtoull(value, (char **)NULL, 10);
|
||||
- if (rargs->usage < 1 || rargs->usage > 100) {
|
||||
- fprintf(stderr, "Invalid usage argument: %s\n",
|
||||
- value);
|
||||
- return 1;
|
||||
- }
|
||||
- rargs->flags |= BTRFS_RESTRIPE_ARGS_USAGE;
|
||||
- } else if (!strcmp(this_char, "devid")) {
|
||||
- if (!value || !*value) {
|
||||
- fprintf(stderr, "the devid filter requires "
|
||||
- "an argument\n");
|
||||
- return 1;
|
||||
- }
|
||||
- rargs->devid = strtoull(value, (char **)NULL, 10);
|
||||
- if (rargs->devid == 0) {
|
||||
- fprintf(stderr, "Invalid devid argument: %s\n",
|
||||
- value);
|
||||
- return 1;
|
||||
- }
|
||||
- rargs->flags |= BTRFS_RESTRIPE_ARGS_DEVID;
|
||||
- } else if (!strcmp(this_char, "drange")) {
|
||||
- if (!value || !*value) {
|
||||
- fprintf(stderr, "the drange filter requires "
|
||||
- "an argument\n");
|
||||
- return 1;
|
||||
- }
|
||||
- if (parse_range(value, &rargs->pstart, &rargs->pend)) {
|
||||
- fprintf(stderr, "Invalid drange argument\n");
|
||||
- return 1;
|
||||
- }
|
||||
- rargs->flags |= BTRFS_RESTRIPE_ARGS_DRANGE;
|
||||
- } else if (!strcmp(this_char, "vrange")) {
|
||||
- if (!value || !*value) {
|
||||
- fprintf(stderr, "the vrange filter requires "
|
||||
- "an argument\n");
|
||||
- return 1;
|
||||
- }
|
||||
- if (parse_range(value, &rargs->vstart, &rargs->vend)) {
|
||||
- fprintf(stderr, "Invalid vrange argument\n");
|
||||
- return 1;
|
||||
- }
|
||||
- rargs->flags |= BTRFS_RESTRIPE_ARGS_VRANGE;
|
||||
- } else if (!strcmp(this_char, "convert")) {
|
||||
- if (!value || !*value) {
|
||||
- fprintf(stderr, "the convert option requires "
|
||||
- "an argument\n");
|
||||
- return 1;
|
||||
- }
|
||||
- if (parse_one_profile(value, &rargs->target)) {
|
||||
- fprintf(stderr, "Invalid convert argument\n");
|
||||
- return 1;
|
||||
- }
|
||||
- rargs->flags |= BTRFS_RESTRIPE_ARGS_CONVERT;
|
||||
- } else if (!strcmp(this_char, "soft")) {
|
||||
- rargs->flags |= BTRFS_RESTRIPE_ARGS_SOFT;
|
||||
- } else {
|
||||
- fprintf(stderr, "Unrecognized restripe option '%s'\n",
|
||||
- this_char);
|
||||
- return 1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static void dump_ioctl_restripe_args(struct btrfs_ioctl_restripe_args *args);
|
||||
-
|
||||
-static struct option restripe_longopts[] = {
|
||||
- { "data", 2, NULL, 'd'},
|
||||
- { "metadata", 2, NULL, 'm' },
|
||||
- { "system", 2, NULL, 's' },
|
||||
- { "force", 0, NULL, 'f' },
|
||||
- { "verbose", 0, NULL, 'v' },
|
||||
- { 0, 0, 0, 0}
|
||||
-};
|
||||
-
|
||||
-/*
|
||||
- * [-d [filters]] [-m [filters]] [-s [filters]] [-vf]
|
||||
- */
|
||||
-int do_restripe(int ac, char **av)
|
||||
-{
|
||||
- int fd;
|
||||
- char *path;
|
||||
- struct btrfs_ioctl_restripe_args args;
|
||||
- struct btrfs_restripe_args *ptrs[] = { &args.data, &args.sys,
|
||||
- &args.meta, NULL };
|
||||
- int force = 0;
|
||||
- int verbose = 0;
|
||||
- int nofilters = 1;
|
||||
- int i;
|
||||
- int longindex;
|
||||
- int ret;
|
||||
- int e;
|
||||
-
|
||||
- memset(&args, 0, sizeof(args));
|
||||
-
|
||||
- while (1) {
|
||||
- int opt = getopt_long(ac, av, "d::s::m::fv", restripe_longopts,
|
||||
- &longindex);
|
||||
- if (opt < 0)
|
||||
- break;
|
||||
-
|
||||
- switch (opt) {
|
||||
- case 'd':
|
||||
- nofilters = 0;
|
||||
- args.flags |= BTRFS_RESTRIPE_DATA;
|
||||
-
|
||||
- if (parse_filters(optarg, &args.data))
|
||||
- return 1;
|
||||
- break;
|
||||
- case 's':
|
||||
- nofilters = 0;
|
||||
- args.flags |= BTRFS_RESTRIPE_SYSTEM;
|
||||
-
|
||||
- if (parse_filters(optarg, &args.sys))
|
||||
- return 1;
|
||||
- break;
|
||||
- case 'm':
|
||||
- nofilters = 0;
|
||||
- args.flags |= BTRFS_RESTRIPE_METADATA;
|
||||
-
|
||||
- if (parse_filters(optarg, &args.meta))
|
||||
- return 1;
|
||||
- break;
|
||||
- case 'f':
|
||||
- force = 1;
|
||||
- break;
|
||||
- case 'v':
|
||||
- verbose = 1;
|
||||
- break;
|
||||
- default:
|
||||
- fprintf(stderr, "Invalid arguments for restripe\n");
|
||||
- return 1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (ac - optind != 1) {
|
||||
- fprintf(stderr, "Invalid arguments for restripe\n");
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- if (nofilters) {
|
||||
- /* relocate everything - no filters */
|
||||
- args.flags |= BTRFS_RESTRIPE_TYPE_MASK;
|
||||
- }
|
||||
-
|
||||
- /* drange makes sense only when devid is set */
|
||||
- for (i = 0; ptrs[i]; i++) {
|
||||
- if ((ptrs[i]->flags & BTRFS_RESTRIPE_ARGS_DRANGE) &&
|
||||
- !(ptrs[i]->flags & BTRFS_RESTRIPE_ARGS_DEVID)) {
|
||||
- fprintf(stderr, "drange filter can be used only if "
|
||||
- "devid filter is used\n");
|
||||
- return 1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* soft makes sense only when convert for corresponding type is set */
|
||||
- for (i = 0; ptrs[i]; i++) {
|
||||
- if ((ptrs[i]->flags & BTRFS_RESTRIPE_ARGS_SOFT) &&
|
||||
- !(ptrs[i]->flags & BTRFS_RESTRIPE_ARGS_CONVERT)) {
|
||||
- fprintf(stderr, "'soft' option can be used only if "
|
||||
- "changing profiles\n");
|
||||
- return 1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- path = av[optind];
|
||||
- fd = open_file_or_dir(path);
|
||||
- if (fd < 0) {
|
||||
- fprintf(stderr, "ERROR: can't access to '%s'\n", path);
|
||||
- return 12;
|
||||
- }
|
||||
-
|
||||
- if (force)
|
||||
- args.flags |= BTRFS_RESTRIPE_FORCE;
|
||||
- if (verbose)
|
||||
- dump_ioctl_restripe_args(&args);
|
||||
-
|
||||
- ret = ioctl(fd, BTRFS_IOC_RESTRIPE, &args);
|
||||
- e = errno;
|
||||
- close(fd);
|
||||
-
|
||||
- if (ret < 0) {
|
||||
- if (e == ECANCELED) {
|
||||
- fprintf(stderr, "restripe interrupted by user\n");
|
||||
- } else {
|
||||
- fprintf(stderr, "ERROR: error during restriping '%s' "
|
||||
- "- %s\n", path, strerror(e));
|
||||
- return 19;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-int do_restripe_cancel(int ac, char **av)
|
||||
-{
|
||||
- int fd;
|
||||
- char *path = av[1];
|
||||
- int ret;
|
||||
- int e;
|
||||
-
|
||||
- fd = open_file_or_dir(path);
|
||||
- if (fd < 0) {
|
||||
- fprintf(stderr, "ERROR: can't access to '%s'\n", path);
|
||||
- return 12;
|
||||
- }
|
||||
-
|
||||
- ret = ioctl(fd, BTRFS_IOC_RESTRIPE_CTL, BTRFS_RESTRIPE_CTL_CANCEL);
|
||||
- e = errno;
|
||||
- close(fd);
|
||||
-
|
||||
- if (ret < 0) {
|
||||
- fprintf(stderr, "ERROR: restripe cancel on '%s' failed - %s\n",
|
||||
- path, (e == ENOTCONN) ? "Not in progress" : strerror(e));
|
||||
- return 19;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-int do_restripe_pause(int ac, char **av)
|
||||
-{
|
||||
- int fd;
|
||||
- char *path = av[1];
|
||||
- int ret;
|
||||
- int e;
|
||||
-
|
||||
- fd = open_file_or_dir(path);
|
||||
- if (fd < 0) {
|
||||
- fprintf(stderr, "ERROR: can't access to '%s'\n", path);
|
||||
- return 12;
|
||||
- }
|
||||
-
|
||||
- ret = ioctl(fd, BTRFS_IOC_RESTRIPE_CTL, BTRFS_RESTRIPE_CTL_PAUSE);
|
||||
- e = errno;
|
||||
- close(fd);
|
||||
-
|
||||
- if (ret < 0) {
|
||||
- fprintf(stderr, "ERROR: restripe pause on '%s' failed - %s\n",
|
||||
- path, (e == ENOTCONN) ? "Not running" : strerror(e));
|
||||
- return 19;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-int do_restripe_resume(int ac, char **av)
|
||||
-{
|
||||
- int fd;
|
||||
- char *path = av[1];
|
||||
- int ret;
|
||||
- int e;
|
||||
-
|
||||
- fd = open_file_or_dir(path);
|
||||
- if (fd < 0) {
|
||||
- fprintf(stderr, "ERROR: can't access to '%s'\n", path);
|
||||
- return 12;
|
||||
- }
|
||||
-
|
||||
- ret = ioctl(fd, BTRFS_IOC_RESTRIPE_CTL, BTRFS_RESTRIPE_CTL_RESUME);
|
||||
- e = errno;
|
||||
- close(fd);
|
||||
-
|
||||
- if (ret < 0) {
|
||||
- if (e == ECANCELED) {
|
||||
- fprintf(stderr, "restripe interrupted by user\n");
|
||||
- } else if (e == ENOTCONN || e == EINPROGRESS) {
|
||||
- fprintf(stderr, "ERROR: restripe resume on '%s' "
|
||||
- "failed - %s\n", path,
|
||||
- (e == ENOTCONN) ? "Not in progress" :
|
||||
- "Already running");
|
||||
- return 19;
|
||||
- } else {
|
||||
- fprintf(stderr, "ERROR: error during restriping '%s' "
|
||||
- "- %s\n", path, strerror(e));
|
||||
- return 19;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static struct option restripe_progress_longopts[] = {
|
||||
- { "verbose", 0, NULL, 'v' },
|
||||
- { 0, 0, 0, 0}
|
||||
-};
|
||||
-
|
||||
-int do_restripe_progress(int ac, char **av)
|
||||
-{
|
||||
- int fd;
|
||||
- char *path;
|
||||
- struct btrfs_ioctl_restripe_args args;
|
||||
- int verbose = 0;
|
||||
- int longindex;
|
||||
- int ret;
|
||||
- int e;
|
||||
-
|
||||
- while (1) {
|
||||
- int opt = getopt_long(ac, av, "v", restripe_progress_longopts,
|
||||
- &longindex);
|
||||
- if (opt < 0)
|
||||
- break;
|
||||
-
|
||||
- switch (opt) {
|
||||
- case 'v':
|
||||
- verbose = 1;
|
||||
- break;
|
||||
- default:
|
||||
- fprintf(stderr, "Invalid arguments for restripe "
|
||||
- "status\n");
|
||||
- return 1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (ac - optind != 1) {
|
||||
- fprintf(stderr, "Invalid arguments for restripe status\n");
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- path = av[optind];
|
||||
- fd = open_file_or_dir(path);
|
||||
- if (fd < 0) {
|
||||
- fprintf(stderr, "ERROR: can't access to '%s'\n", path);
|
||||
- return 12;
|
||||
- }
|
||||
-
|
||||
- ret = ioctl(fd, BTRFS_IOC_RESTRIPE_PROGRESS, &args);
|
||||
- e = errno;
|
||||
- close(fd);
|
||||
+ fprintf(stderr, "ERROR: error during balancing '%s' - %s\n",
|
||||
+ path, strerror(e));
|
||||
|
||||
- if (ret < 0) {
|
||||
- fprintf(stderr, "ERROR: restripe status on '%s' failed - %s\n",
|
||||
- path, (e == ENOTCONN) ? "Not in progress" : strerror(e));
|
||||
return 19;
|
||||
}
|
||||
-
|
||||
- if (args.state & BTRFS_RESTRIPE_ST_RUNNING) {
|
||||
- printf("Restripe on '%s' is running", path);
|
||||
- if (args.state & BTRFS_RESTRIPE_ST_CANCEL_REQ)
|
||||
- printf(", cancel requested\n");
|
||||
- else if (args.state & BTRFS_RESTRIPE_ST_PAUSE_REQ)
|
||||
- printf(", pause requested\n");
|
||||
- else
|
||||
- printf("\n");
|
||||
- } else {
|
||||
- printf("Restripe on '%s' is paused\n", path);
|
||||
- }
|
||||
-
|
||||
- printf("%llu out of about %llu chunks restriped (%llu considered), "
|
||||
- "%3.f%% left\n", args.stat.completed, args.stat.expected,
|
||||
- args.stat.considered,
|
||||
- 100 * (1 - (float)args.stat.completed/args.stat.expected));
|
||||
-
|
||||
- if (verbose)
|
||||
- dump_ioctl_restripe_args(&args);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void dump_restripe_args(struct btrfs_restripe_args *args)
|
||||
-{
|
||||
- if (args->flags & BTRFS_RESTRIPE_ARGS_CONVERT) {
|
||||
- printf("converting, target=%llu, soft is %s", args->target,
|
||||
- (args->flags & BTRFS_RESTRIPE_ARGS_SOFT) ? "on" : "off");
|
||||
- } else {
|
||||
- printf("balancing");
|
||||
- }
|
||||
-
|
||||
- if (args->flags & BTRFS_RESTRIPE_ARGS_PROFILES)
|
||||
- printf(", profiles=%llu", args->profiles);
|
||||
- if (args->flags & BTRFS_RESTRIPE_ARGS_USAGE)
|
||||
- printf(", usage=%llu", args->usage);
|
||||
- if (args->flags & BTRFS_RESTRIPE_ARGS_DEVID)
|
||||
- printf(", devid=%llu", args->devid);
|
||||
- if (args->flags & BTRFS_RESTRIPE_ARGS_DRANGE)
|
||||
- printf(", drange=%llu..%llu", args->pstart, args->pend);
|
||||
- if (args->flags & BTRFS_RESTRIPE_ARGS_VRANGE)
|
||||
- printf(", vrange=%llu..%llu", args->vstart, args->vend);
|
||||
-
|
||||
- printf("\n");
|
||||
-}
|
||||
-
|
||||
-static void dump_ioctl_restripe_args(struct btrfs_ioctl_restripe_args *args)
|
||||
-{
|
||||
- printf("Dumping filters: flags 0x%llx, state 0x%llx, force is %s\n",
|
||||
- args->flags, args->state,
|
||||
- (args->flags & BTRFS_RESTRIPE_FORCE) ? "on" : "off");
|
||||
- if (args->flags & BTRFS_RESTRIPE_DATA) {
|
||||
- printf(" DATA (flags 0x%llx): ", args->data.flags);
|
||||
- dump_restripe_args(&args->data);
|
||||
- }
|
||||
- if (args->flags & BTRFS_RESTRIPE_METADATA) {
|
||||
- printf(" METADATA (flags 0x%llx): ", args->meta.flags);
|
||||
- dump_restripe_args(&args->meta);
|
||||
- }
|
||||
- if (args->flags & BTRFS_RESTRIPE_SYSTEM) {
|
||||
- printf(" SYSTEM (flags 0x%llx): ", args->sys.flags);
|
||||
- dump_restripe_args(&args->sys);
|
||||
- }
|
||||
-}
|
||||
|
||||
|
||||
/**** man: btrfs device delete
|
||||
diff --git a/btrfs_cmds.h b/btrfs_cmds.h
|
||||
index 2cd0ac1..81182b1 100644
|
||||
--- a/btrfs_cmds.h
|
||||
+++ b/btrfs_cmds.h
|
||||
@@ -27,11 +27,6 @@ int do_scrub_start(int nargs, char **argv);
|
||||
int do_scrub_status(int argc, char **argv);
|
||||
int do_scrub_resume(int argc, char **argv);
|
||||
int do_scrub_cancel(int nargs, char **argv);
|
||||
-int do_restripe(int ac, char **av);
|
||||
-int do_restripe_cancel(int ac, char **av);
|
||||
-int do_restripe_pause(int ac, char **av);
|
||||
-int do_restripe_resume(int ac, char **av);
|
||||
-int do_restripe_progress(int ac, char **av);
|
||||
int do_remove_volume(int nargs, char **args);
|
||||
int do_scan(int nargs, char **argv);
|
||||
int do_resize(int nargs, char **argv);
|
||||
diff --git a/ctree.h b/ctree.h
|
||||
index 58ea3d3..54748c8 100644
|
||||
--- a/ctree.h
|
||||
+++ b/ctree.h
|
||||
@@ -61,9 +61,6 @@ struct btrfs_trans_handle;
|
||||
#define BTRFS_CSUM_TREE_OBJECTID 7ULL
|
||||
|
||||
|
||||
-/* for storing restripe params in the root tree */
|
||||
-#define BTRFS_RESTRIPE_OBJECTID -4ULL
|
||||
-
|
||||
/* oprhan objectid for tracking unlinked/truncated files */
|
||||
#define BTRFS_ORPHAN_OBJECTID -5ULL
|
||||
|
||||
@@ -708,12 +705,6 @@ struct btrfs_csum_item {
|
||||
#define BTRFS_BLOCK_GROUP_DUP (1 << 5)
|
||||
#define BTRFS_BLOCK_GROUP_RAID10 (1 << 6)
|
||||
|
||||
-/*
|
||||
- * to avoid troubles..
|
||||
- */
|
||||
-#define BTRFS_AVAIL_ALLOC_BIT_SINGLE (1 << 7)
|
||||
-#define BTRFS_BLOCK_GROUP_RESERVED (1 << 7)
|
||||
-
|
||||
struct btrfs_block_group_item {
|
||||
__le64 used;
|
||||
__le64 chunk_objectid;
|
||||
diff --git a/ioctl.h b/ioctl.h
|
||||
index af8b18b..1ae7537 100644
|
||||
--- a/ioctl.h
|
||||
+++ b/ioctl.h
|
||||
@@ -91,45 +91,6 @@ struct btrfs_ioctl_fs_info_args {
|
||||
__u64 reserved[124]; /* pad to 1k */
|
||||
};
|
||||
|
||||
-#define BTRFS_RESTRIPE_CTL_CANCEL 1
|
||||
-#define BTRFS_RESTRIPE_CTL_PAUSE 2
|
||||
-#define BTRFS_RESTRIPE_CTL_RESUME 3
|
||||
-
|
||||
-struct btrfs_restripe_args {
|
||||
- __u64 profiles;
|
||||
- __u64 usage;
|
||||
- __u64 devid;
|
||||
- __u64 pstart;
|
||||
- __u64 pend;
|
||||
- __u64 vstart;
|
||||
- __u64 vend;
|
||||
-
|
||||
- __u64 target;
|
||||
-
|
||||
- __u64 flags;
|
||||
-
|
||||
- __u64 unused[8];
|
||||
-} __attribute__ ((__packed__));
|
||||
-
|
||||
-struct btrfs_restripe_progress {
|
||||
- __u64 expected;
|
||||
- __u64 considered;
|
||||
- __u64 completed;
|
||||
-};
|
||||
-
|
||||
-struct btrfs_ioctl_restripe_args {
|
||||
- __u64 flags;
|
||||
- __u64 state;
|
||||
-
|
||||
- struct btrfs_restripe_args data;
|
||||
- struct btrfs_restripe_args sys;
|
||||
- struct btrfs_restripe_args meta;
|
||||
-
|
||||
- struct btrfs_restripe_progress stat;
|
||||
-
|
||||
- __u64 unused[72]; /* pad to 1k */
|
||||
-};
|
||||
-
|
||||
struct btrfs_ioctl_search_key {
|
||||
/* which root are we searching. 0 is the tree of tree roots */
|
||||
__u64 tree_id;
|
||||
@@ -311,15 +272,10 @@ struct btrfs_ioctl_logical_ino_args {
|
||||
#define BTRFS_IOC_DEV_INFO _IOWR(BTRFS_IOCTL_MAGIC, 30, \
|
||||
struct btrfs_ioctl_dev_info_args)
|
||||
#define BTRFS_IOC_FS_INFO _IOR(BTRFS_IOCTL_MAGIC, 31, \
|
||||
- struct btrfs_ioctl_fs_info_args)
|
||||
+ struct btrfs_ioctl_fs_info_args)
|
||||
#define BTRFS_IOC_INO_PATHS _IOWR(BTRFS_IOCTL_MAGIC, 35, \
|
||||
struct btrfs_ioctl_ino_path_args)
|
||||
#define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, \
|
||||
struct btrfs_ioctl_ino_path_args)
|
||||
|
||||
-#define BTRFS_IOC_RESTRIPE _IOW(BTRFS_IOCTL_MAGIC, 32, \
|
||||
- struct btrfs_ioctl_restripe_args)
|
||||
-#define BTRFS_IOC_RESTRIPE_CTL _IOW(BTRFS_IOCTL_MAGIC, 33, int)
|
||||
-#define BTRFS_IOC_RESTRIPE_PROGRESS _IOR(BTRFS_IOCTL_MAGIC, 34, \
|
||||
- struct btrfs_ioctl_restripe_args)
|
||||
#endif
|
||||
diff --git a/print-tree.c b/print-tree.c
|
||||
index 49f98af..6039699 100644
|
||||
--- a/print-tree.c
|
||||
+++ b/print-tree.c
|
||||
@@ -391,9 +391,6 @@ static void print_objectid(unsigned long long objectid, u8 type)
|
||||
case BTRFS_CSUM_TREE_OBJECTID:
|
||||
printf("CSUM_TREE");
|
||||
break;
|
||||
- case BTRFS_RESTRIPE_OBJECTID:
|
||||
- printf("RESTRIPE");
|
||||
- break;
|
||||
case BTRFS_ORPHAN_OBJECTID:
|
||||
printf("ORPHAN");
|
||||
break;
|
||||
diff --git a/volumes.h b/volumes.h
|
||||
index 5845c1d..08c53e4 100644
|
||||
--- a/volumes.h
|
||||
+++ b/volumes.h
|
||||
@@ -95,48 +95,6 @@ struct btrfs_multi_bio {
|
||||
#define btrfs_multi_bio_size(n) (sizeof(struct btrfs_multi_bio) + \
|
||||
(sizeof(struct btrfs_bio_stripe) * (n)))
|
||||
|
||||
-/*
|
||||
- * Restriper's general "type" filter. Shares bits with chunk type for
|
||||
- * simplicity, RESTRIPE prefix is used to avoid confusion.
|
||||
- */
|
||||
-#define BTRFS_RESTRIPE_DATA (1ULL << 0)
|
||||
-#define BTRFS_RESTRIPE_SYSTEM (1ULL << 1)
|
||||
-#define BTRFS_RESTRIPE_METADATA (1ULL << 2)
|
||||
-
|
||||
-#define BTRFS_RESTRIPE_TYPE_MASK (BTRFS_RESTRIPE_DATA | \
|
||||
- BTRFS_RESTRIPE_SYSTEM | \
|
||||
- BTRFS_RESTRIPE_METADATA)
|
||||
-
|
||||
-#define BTRFS_RESTRIPE_FORCE (1ULL << 3)
|
||||
-
|
||||
-/*
|
||||
- * Restripe filters
|
||||
- */
|
||||
-#define BTRFS_RESTRIPE_ARGS_PROFILES (1ULL << 0)
|
||||
-#define BTRFS_RESTRIPE_ARGS_USAGE (1ULL << 1)
|
||||
-#define BTRFS_RESTRIPE_ARGS_DEVID (1ULL << 2)
|
||||
-#define BTRFS_RESTRIPE_ARGS_DRANGE (1ULL << 3)
|
||||
-#define BTRFS_RESTRIPE_ARGS_VRANGE (1ULL << 4)
|
||||
-
|
||||
-/*
|
||||
- * Profile changing flags. When SOFT is set we won't relocate chunk if
|
||||
- * it already has the target profile (even though it may be
|
||||
- * half-filled).
|
||||
- */
|
||||
-#define BTRFS_RESTRIPE_ARGS_CONVERT (1ULL << 8)
|
||||
-#define BTRFS_RESTRIPE_ARGS_SOFT (1ULL << 9)
|
||||
-
|
||||
-/*
|
||||
- * Restripe state bits
|
||||
- */
|
||||
-#define RESTRIPE_RUNNING 0
|
||||
-#define RESTRIPE_CANCEL_REQ 1
|
||||
-#define RESTRIPE_PAUSE_REQ 2
|
||||
-
|
||||
-#define BTRFS_RESTRIPE_ST_RUNNING (1ULL << RESTRIPE_RUNNING)
|
||||
-#define BTRFS_RESTRIPE_ST_CANCEL_REQ (1ULL << RESTRIPE_CANCEL_REQ)
|
||||
-#define BTRFS_RESTRIPE_ST_PAUSE_REQ (1ULL << RESTRIPE_PAUSE_REQ)
|
||||
-
|
||||
int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_device *device,
|
||||
u64 chunk_tree, u64 chunk_objectid,
|
||||
--
|
||||
1.7.6.233.gd79bc
|
||||
|
@ -7,11 +7,11 @@ Date: Thu Dec 16 20:40:34 2010 +0100
|
||||
The error path forgets to free a previously allocated
|
||||
memory structure.
|
||||
|
||||
diff --git a/disk-io.c b/disk-io.c
|
||||
index a6e1000..2b5e1d5 100644
|
||||
--- a/disk-io.c
|
||||
+++ b/disk-io.c
|
||||
@@ -423,11 +423,13 @@ static int find_and_setup_log_root(struct btrfs_root *tree_root,
|
||||
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);
|
@ -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
|
||||
|
248
btrfs-progs-fix-open_ctree_usage_segfaults.patch
Normal file
248
btrfs-progs-fix-open_ctree_usage_segfaults.patch
Normal file
@ -0,0 +1,248 @@
|
||||
--- 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);
|
@ -1,22 +0,0 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 96e2002..7a5e2c1 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -37,7 +37,7 @@ version:
|
||||
bash version.sh
|
||||
|
||||
btrfs: $(objects) btrfs.o btrfs_cmds.o scrub.o
|
||||
- $(CC) -lpthread $(CFLAGS) -o btrfs btrfs.o btrfs_cmds.o scrub.o \
|
||||
+ $(CC) -pthread $(CFLAGS) -o btrfs btrfs.o btrfs_cmds.o scrub.o \
|
||||
$(objects) $(LDFLAGS) $(LIBS)
|
||||
|
||||
calc-size: $(objects) calc-size.o
|
||||
@@ -83,7 +83,7 @@ btrfs-corrupt-block: $(objects) btrfs-corrupt-block.o
|
||||
$(CC) $(CFLAGS) -o btrfs-corrupt-block $(objects) btrfs-corrupt-block.o $(LDFLAGS) $(LIBS)
|
||||
|
||||
btrfs-image: $(objects) btrfs-image.o
|
||||
- $(CC) $(CFLAGS) -o btrfs-image $(objects) btrfs-image.o -lpthread -lz $(LDFLAGS) $(LIBS)
|
||||
+ $(CC) $(CFLAGS) -o btrfs-image $(objects) btrfs-image.o -pthread -lz $(LDFLAGS) $(LIBS)
|
||||
|
||||
dir-test: $(objects) dir-test.o
|
||||
$(CC) $(CFLAGS) -o dir-test $(objects) dir-test.o $(LDFLAGS) $(LIBS)
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:00bf3761187270d3ba2da8d3eb17989ed4e64b12e024850a2f537ee9b84bdbfd
|
||||
size 162346
|
3
btrfs-progs-v0.19-118-gfdb6c04.tar.bz2
Normal file
3
btrfs-progs-v0.19-118-gfdb6c04.tar.bz2
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7c7d0bb613659bd63e4894bfb481a85cbadb695f7b9418c97921274ac8344021
|
||||
size 162236
|
@ -1,15 +0,0 @@
|
||||
--- a/btrfsck.c.new 2011-10-04 02:05:51.891833030 +0200
|
||||
+++ b/btrfsck.c 2011-10-04 02:07:51.999653799 +0200
|
||||
@@ -2816,10 +2816,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,4 +1,36 @@
|
||||
-------------------------------------------------------------------
|
||||
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)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Wed Nov 9 14:34:56 CET 2011 - dsterba@suse.cz
|
||||
|
||||
- add several tools to mkinitrd if root fs is btrfs
|
||||
|
122
btrfsprogs.spec
122
btrfsprogs.spec
@ -21,24 +21,69 @@ Name: btrfsprogs
|
||||
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 @@ Utilities needed to create and maintain btrfs file systems under Linux.
|
||||
%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 @@ cp %{S:1} ${RPM_BUILD_ROOT}/lib/mkinitrd/scripts/
|
||||
/sbin/btrfsck
|
||||
/sbin/btrfs-restore
|
||||
/sbin/btrfs-find-root
|
||||
/sbin/btrfs-dump-super
|
||||
/sbin/mkfs.btrfs
|
||||
/lib/mkinitrd/scripts/boot-btrfs.sh
|
||||
# other
|
||||
|
@ -1,12 +0,0 @@
|
||||
--- Makefile.orig 2011-11-08 19:03:26.188610871 +0100
|
||||
+++ Makefile 2011-11-08 19:03:52.699995062 +0100
|
||||
@@ -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
|
||||
+progsextra = restore find-root calc-size btrfs-corrupt-block
|
||||
|
||||
# make C=1 to enable sparse
|
||||
ifdef C
|
@ -1,77 +0,0 @@
|
||||
Index: btrfs-progs-v0.19-116-g13eced9/utils.c
|
||||
===================================================================
|
||||
--- btrfs-progs-v0.19-116-g13eced9.orig/utils.c
|
||||
+++ btrfs-progs-v0.19-116-g13eced9/utils.c
|
||||
@@ -674,21 +674,29 @@ int is_same_blk_file(const char* a, cons
|
||||
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)
|
||||
return 1;
|
||||
|
||||
- if(stat(a, &st_buf_a) < 0 ||
|
||||
- stat(b, &st_buf_b) < 0)
|
||||
- {
|
||||
- if (errno == ENOENT)
|
||||
- return 0;
|
||||
+ if(stat(a, &st_buf_a) < 0)
|
||||
+ {
|
||||
+ if (errno == ENOENT)
|
||||
+ return 0;
|
||||
+
|
||||
+ return -errno;
|
||||
+ }
|
||||
+
|
||||
+ if(stat(b, &st_buf_b) < 0)
|
||||
+ {
|
||||
+ if (errno == ENOENT)
|
||||
+ return 0;
|
||||
+
|
||||
return -errno;
|
||||
}
|
||||
|
||||
@@ -729,10 +737,12 @@ int is_same_loop_file(const char* a, con
|
||||
return 0;
|
||||
return ret;
|
||||
} else if (ret) {
|
||||
- if ((ret = resolve_loop_device(a, res_a, sizeof(res_a))) < 0)
|
||||
+ if((ret = resolve_loop_device(a, res_a, sizeof(res_a))) < 0) {
|
||||
+ if (errno != EPERM)
|
||||
return ret;
|
||||
-
|
||||
- final_a = res_a;
|
||||
+ } else {
|
||||
+ final_a = res_a;
|
||||
+ }
|
||||
} else {
|
||||
final_a = a;
|
||||
}
|
||||
@@ -743,10 +753,12 @@ int is_same_loop_file(const char* a, con
|
||||
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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user