Hello community,
here is the log from the commit of package btrfsprogs for openSUSE:Factory checked in at 2012-03-20 11:26:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/btrfsprogs (Old)
and /work/SRC/openSUSE:Factory/.btrfsprogs.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "btrfsprogs", Maintainer is "MFasheh@suse.com"
Changes:
--------
--- /work/SRC/openSUSE:Factory/btrfsprogs/btrfsprogs.changes 2012-02-21 12:15:45.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.btrfsprogs.new/btrfsprogs.changes 2012-03-20 11:26:15.000000000 +0100
@@ -1,0 +2,20 @@
+Fri Mar 9 16:26:20 UTC 2012 - rschweikert@suse.com
+
+- place binaries in /usr tree (UsrMerge project)
+- adjust mkinitrd scrippt accordingly
+
+-------------------------------------------------------------------
+Mon Mar 5 13:06:43 CET 2012 - dsterba@suse.cz
+
+- add btrfsck repair options for:
+ - rebuild extent records
+ - fix block group accounting
+ - reset csums for rescue nodatasum mount
+ - prune corrupt extent allocation tree blocks
+- device scanning fixes for dm and multipath
+- initrd support: move btrfs device scan after block device setup
+- documentation updates
+- add csize for file commpressed size
+- updated restore utility
+
+-------------------------------------------------------------------
Old:
----
0114-btrfs-progs-add-qgroup-commands.patch
0900-Revert-btrfs-progs-add-qgroup-commands.patch
0901-Revert-Btrfs-progs-add-restriper-commands.patch
New:
----
0114-btrfs-progs-Add-ioctl-to-read-compressed-size-of-a-f.patch
0139-Btrfs-progs-make-find-root-spit-out-the-size-of-the-.patch
0140-Btrfs-progs-add-some-verbose-output-to-find-root.patch
0141-Btrfs-progs-fix-restore-to-actually-use-the-root-loc.patch
0142-Btrfs-progs-remove-the-physical-disk-size-check-from.patch
0143-Btrfs-progs-fix-error-output-and-dont-read-from-cach.patch
0144-Btrfs-progs-print-the-objectid-of-the-root-we-find-w.patch
0145-Btrfs-progs-make-specifying-root-objectid-work-if-th.patch
0146-Btrfs-progs-don-t-free-the-existing-node.patch
0147-mkfs-Handle-creation-of-filesystem-larger-than-the-f.patch
0150-btrfs-progs-removed-extraneous-whitespace-from-mkfs-.patch
0151-btrfs-progs-document-rootdir-mkfs-switch.patch
0152-Add-open_ctree_fs_info-for-partial-FS-opens.patch
0153-btrfsck-print-some-progress-Signed-off-by-Chris-Maso.patch
0154-Allow-extent_buffers-to-use-more-ram.patch
0155-btrfsck-don-t-BUG-on-corrupted-extent-records.patch
0156-btrfs-corrupt-block-add-e-option-to-corrupt-the-exte.patch
0157-btrfsck-add-code-to-rebuild-extent-records.patch
0158-btrfs-corrupt-block-add-E-option-to-randomly-corrupt.patch
0159-btrfsck-fix-block-group-accounting-during-repair.patch
0160-Turn-off-some-commands-in-Makefile.patch
0161-Fix-btrfs-convert-btrfs-restore-and-btrfs-find-root-.patch
0162-btrfsck-make-sure-to-dirty-all-block-groups-as-we-fi.patch
0163-btrfsck-add-init-csum-tree-to-replace-the-csum-root-.patch
0164-btrfsck-make-sure-we-fix-the-block-group-accounting-.patch
0165-btrfsck-remove-extents-from-the-fsck-reference-track.patch
0166-Btrfsck-add-the-ability-to-prune-corrupt-extent-allo.patch
0167-Btrfs-use-proc-partitions-scanning-for-btrfs_scan_fo.patch
0168-Scan-dev-md-and-device-mapper-devices-last.patch
0169-btrfsck-add-early-code-to-handle-corrupted-block-gro.patch
0170-Btrfs-progs-btrfs-map-logical-Fix-typo-in-usage.patch
0171-Btrfs-progs-btrfs-corrupt-block-fix-the-wrong-usage.patch
0172-Btrfs-progs-fix-btrfsck-s-snapshot-wrong-unresolved-.patch
btrfs-dev-clear-sb
btrfs-man-update
btrfs-mkfs-update-disclaimer.patch
btrfs-reorder-commands-help
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ btrfsprogs.spec ++++++
--- /var/tmp/diff_new_pack.HFJOpo/_old 2012-03-20 11:26:16.000000000 +0100
+++ /var/tmp/diff_new_pack.HFJOpo/_new 2012-03-20 11:26:16.000000000 +0100
@@ -28,6 +28,7 @@
# 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
+Source2: btrfs-dev-clear-sb
Patch0: memleak-fix.diff
Patch1: Plug-Memory-leak-in-find_and_setup_log_root.patch
Patch1000: local-version-override.patch
@@ -46,9 +47,9 @@
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
+Patch113: 0113-Btrfs-progs-add-restriper-commands.patch
+Patch114: 0114-btrfs-progs-Add-ioctl-to-read-compressed-size-of-a-f.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
@@ -69,17 +70,50 @@
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
+Patch139: 0139-Btrfs-progs-make-find-root-spit-out-the-size-of-the-.patch
+Patch140: 0140-Btrfs-progs-add-some-verbose-output-to-find-root.patch
+Patch141: 0141-Btrfs-progs-fix-restore-to-actually-use-the-root-loc.patch
+Patch142: 0142-Btrfs-progs-remove-the-physical-disk-size-check-from.patch
+Patch143: 0143-Btrfs-progs-fix-error-output-and-dont-read-from-cach.patch
+Patch144: 0144-Btrfs-progs-print-the-objectid-of-the-root-we-find-w.patch
+Patch145: 0145-Btrfs-progs-make-specifying-root-objectid-work-if-th.patch
+Patch146: 0146-Btrfs-progs-don-t-free-the-existing-node.patch
+Patch147: 0147-mkfs-Handle-creation-of-filesystem-larger-than-the-f.patch
+Patch150: 0150-btrfs-progs-removed-extraneous-whitespace-from-mkfs-.patch
+Patch151: 0151-btrfs-progs-document-rootdir-mkfs-switch.patch
+Patch152: 0152-Add-open_ctree_fs_info-for-partial-FS-opens.patch
+Patch153: 0153-btrfsck-print-some-progress-Signed-off-by-Chris-Maso.patch
+Patch154: 0154-Allow-extent_buffers-to-use-more-ram.patch
+Patch155: 0155-btrfsck-don-t-BUG-on-corrupted-extent-records.patch
+Patch156: 0156-btrfs-corrupt-block-add-e-option-to-corrupt-the-exte.patch
+Patch157: 0157-btrfsck-add-code-to-rebuild-extent-records.patch
+Patch158: 0158-btrfs-corrupt-block-add-E-option-to-randomly-corrupt.patch
+Patch159: 0159-btrfsck-fix-block-group-accounting-during-repair.patch
+Patch160: 0160-Turn-off-some-commands-in-Makefile.patch
+Patch161: 0161-Fix-btrfs-convert-btrfs-restore-and-btrfs-find-root-.patch
+Patch162: 0162-btrfsck-make-sure-to-dirty-all-block-groups-as-we-fi.patch
+Patch163: 0163-btrfsck-add-init-csum-tree-to-replace-the-csum-root-.patch
+Patch164: 0164-btrfsck-make-sure-we-fix-the-block-group-accounting-.patch
+Patch165: 0165-btrfsck-remove-extents-from-the-fsck-reference-track.patch
+Patch166: 0166-Btrfsck-add-the-ability-to-prune-corrupt-extent-allo.patch
+Patch167: 0167-Btrfs-use-proc-partitions-scanning-for-btrfs_scan_fo.patch
+Patch168: 0168-Scan-dev-md-and-device-mapper-devices-last.patch
+Patch169: 0169-btrfsck-add-early-code-to-handle-corrupted-block-gro.patch
+Patch170: 0170-Btrfs-progs-btrfs-map-logical-Fix-typo-in-usage.patch
+Patch171: 0171-Btrfs-progs-btrfs-corrupt-block-fix-the-wrong-usage.patch
+Patch172: 0172-Btrfs-progs-fix-btrfsck-s-snapshot-wrong-unresolved-.patch
+
+# other fixes
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
+Patch250: btrfs-progs-fix-open_ctree_usage_segfaults.patch
+Patch251: btrfs-mkfs-update-disclaimer.patch
+Source252: btrfs-man-update
+Patch253: btrfs-reorder-commands-help
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: libacl-devel
@@ -110,9 +144,10 @@
%patch110 -p1
%patch111 -p1
%patch112 -p1
-%patch113 -p1
-%patch114 -p1
%patch115 -p1
+%patch114 -p1
+%patch113 -p1
+# josef's tree
%patch116 -p1
%patch117 -p1
%patch118 -p1
@@ -132,48 +167,100 @@
%patch132 -p1
%patch133 -p1
%patch134 -p1
+%patch139 -p1
+%patch140 -p1
+%patch141 -p1
+%patch142 -p1
+%patch143 -p1
+%patch144 -p1
+%patch145 -p1
+%patch146 -p1
+%patch147 -p1
+%patch150 -p1
+%patch151 -p1
+# other fixes
%patch135 -p1
%patch136 -p1
%patch137 -p1
%patch138 -p1
-%patch150 -p1
-%patch900 -p1
-%patch901 -p1
+%patch152 -p1
+%patch153 -p1
+%patch154 -p1
+%patch155 -p1
+%patch156 -p1
+%patch157 -p1
+%patch158 -p1
+%patch159 -p1
+%patch160 -p1
+%patch161 -p1
+%patch162 -p1
+%patch163 -p1
+%patch164 -p1
+%patch165 -p1
+%patch166 -p1
+%patch167 -p1
+%patch168 -p1
+%patch169 -p1
+%patch170 -p1
+%patch171 -p1
+%patch172 -p1
+%patch250 -p1
+%patch251 -p1
+#%patch252 -p1
+%patch253 -p1
%build
-make %{?_smp_mflags} CFLAGS="%{optflags}" all convert \
+make %{?_smp_mflags} CFLAGS="%{optflags}" all btrfs-convert \
btrfs-zero-log btrfs-select-super btrfs-image btrfstune \
- restore find-root btrfs-dump-super
+ btrfs-find-root btrfs-restore btrfs-dump-super
+
+patch -p1 < %{S:252}
%install
-make install DESTDIR=${RPM_BUILD_ROOT} prefix=%{_prefix} bindir=/sbin mandir=%{_mandir}
-install -m 0755 -d ${RPM_BUILD_ROOT}/sbin
+make install DESTDIR=${RPM_BUILD_ROOT} prefix=%{_prefix} bindir=%{_sbindir} mandir=%{_mandir}
+install -m 0755 -d ${RPM_BUILD_ROOT}/%{_sbindir}
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}
+# move some utilities out of /usr/sbin
+mv ${RPM_BUILD_ROOT}/%{_sbindir}/{btrfs-show,btrfs-vol,btrfsctl} ${RPM_BUILD_ROOT}/%{_bindir}
+mv ${RPM_BUILD_ROOT}/%{_sbindir}/{btrfs-map-logical,btrfs-debug-tree} ${RPM_BUILD_ROOT}/%{_bindir}
# mkinitrd rescue utilities
-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
+install -m 0755 btrfs-zero-log ${RPM_BUILD_ROOT}/%{_sbindir}
+install -m 0755 btrfs-select-super ${RPM_BUILD_ROOT}/%{_sbindir}
+install -m 0755 btrfs-image ${RPM_BUILD_ROOT}/%{_sbindir}
+install -m 0755 btrfstune ${RPM_BUILD_ROOT}/%{_sbindir}
+install -m 0755 btrfs-dump-super ${RPM_BUILD_ROOT}/%{_sbindir}
+install -m 0755 btrfs-restore ${RPM_BUILD_ROOT}/%{_sbindir}
+install -m 0755 btrfs-find-root ${RPM_BUILD_ROOT}/%{_sbindir}
+#UsrMerge
+install -m 0755 -d ${RPM_BUILD_ROOT}/sbin
+ln -s %{_sbindir}/btrfs ${RPM_BUILD_ROOT}/sbin
+ln -s %{_sbindir}/btrfs-zero-log ${RPM_BUILD_ROOT}/sbin
+ln -s %{_sbindir}/btrfs-convert ${RPM_BUILD_ROOT}/sbin
+ln -s %{_sbindir}/btrfs-select-super ${RPM_BUILD_ROOT}/sbin
+ln -s %{_sbindir}/btrfs-image ${RPM_BUILD_ROOT}/sbin
+ln -s %{_sbindir}/btrfstune ${RPM_BUILD_ROOT}/sbin
+ln -s %{_sbindir}/btrfsck ${RPM_BUILD_ROOT}/sbin
+ln -s %{_sbindir}/btrfs-restore ${RPM_BUILD_ROOT}/sbin
+ln -s %{_sbindir}/btrfs-find-root ${RPM_BUILD_ROOT}/sbin
+ln -s %{_sbindir}/btrfs-dump-super ${RPM_BUILD_ROOT}/sbin
+ln -s %{_sbindir}/mkfs.btrfs ${RPM_BUILD_ROOT}/sbin
+#EndUsrMerge
# 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
+cp %{_bindir}/true ${RPM_BUILD_ROOT}/%{_sbindir}/fsck.btrfs
+#UsrMerge
+ln -s %{_sbindir}/fsck.btrfs ${RPM_BUILD_ROOT}/sbin
+#EndUsrMerge
install -d -m0755 ${RPM_BUILD_ROOT}/lib/mkinitrd/scripts/
-cp %{S:1} ${RPM_BUILD_ROOT}/lib/mkinitrd/scripts/
+install -m 0755 %{S:1} ${RPM_BUILD_ROOT}/lib/mkinitrd/scripts/
+install -m 0755 %{S:2} ${RPM_BUILD_ROOT}/usr/sbin/
%files
%defattr(-, root, root)
/sbin/fsck.btrfs
# mkinitrd utils
+#UsrMerge
/sbin/btrfs
/sbin/btrfs-zero-log
/sbin/btrfs-convert
@@ -185,6 +272,20 @@
/sbin/btrfs-find-root
/sbin/btrfs-dump-super
/sbin/mkfs.btrfs
+#EndUsrMerge
+%{_sbindir}/btrfs
+%{_sbindir}/btrfs-zero-log
+%{_sbindir}/btrfs-convert
+%{_sbindir}/btrfs-select-super
+%{_sbindir}/btrfs-image
+%{_sbindir}/btrfstune
+%{_sbindir}/btrfsck
+%{_sbindir}/btrfs-restore
+%{_sbindir}/btrfs-find-root
+%{_sbindir}/btrfs-dump-super
+%{_sbindir}/fsck.btrfs
+%{_sbindir}/mkfs.btrfs
+/usr/sbin/btrfs-dev-clear-sb
/lib/mkinitrd/scripts/boot-btrfs.sh
# other
/usr/bin/btrfs-map-logical
++++++ 0113-Btrfs-progs-add-restriper-commands.patch ++++++
++++ 1115 lines (skipped)
++++ between /work/SRC/openSUSE:Factory/btrfsprogs/0113-Btrfs-progs-add-restriper-commands.patch
++++ and /work/SRC/openSUSE:Factory/.btrfsprogs.new/0113-Btrfs-progs-add-restriper-commands.patch
++++++ 0114-btrfs-progs-Add-ioctl-to-read-compressed-size-of-a-f.patch ++++++
From 72218a2090e1cbafe9baa97aaa465a28438c3dbb Mon Sep 17 00:00:00 2001
From: David Sterba
Date: Mon, 19 Dec 2011 17:51:11 +0100
Subject: [PATCH 16/43] btrfs-progs: Add ioctl to read compressed size of a
file
Signed-off-by: David Sterba
---
btrfs.c | 9 ++++++-
btrfs_cmds.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++
btrfs_cmds.h | 1 +
ioctl.h | 13 ++++++++++
man/btrfs.8.in.old | 10 +++++++
5 files changed, 100 insertions(+), 1 deletions(-)
diff --git a/btrfs.c b/btrfs.c
index e78f194..f5b8fd4 100644
--- a/btrfs.c
+++ b/btrfs.c
@@ -325,7 +325,14 @@ static struct Command commands[] = {
"filesystem label", "<device> [<newlabel>]\n"
"With one argument, get the label of filesystem on <device>.\n"
"If <newlabel> is passed, set the filesystem label to <newlabel>.\n"
- "The filesystem must be unmounted.\n"
+ "The filesystem must be unmounted."
+ },
+ { do_compr_size, -1,
+ "filesystem csize", "[-s start] [-e end] <file>\n"
+ "Read ordinary and compressed size of extents in the range [start,end)\n"
+ "-s start range start inclusive, accepts K/M/G modifiers\n"
+ "-e end range end exclusive, accepts K/M/G modifiers\n",
+ NULL
},
{ do_scrub_start, -1,
"scrub start", "[-Bdqr] <path>|<device>\n"
diff --git a/btrfs_cmds.c b/btrfs_cmds.c
index 12346e5..c8196d1 100644
--- a/btrfs_cmds.c
+++ b/btrfs_cmds.c
@@ -2058,3 +2058,71 @@ out:
free(inodes);
return ret;
}
+
+int do_compr_size(int argc, char **argv)
+{
+ int ret;
+ int fd;
+ struct btrfs_ioctl_compr_size_args args;
+
+ args.start = 0;
+ args.end = (u64)-1;
+ optind = 1;
+ while (1) {
+ int c = getopt(argc, argv, "s:e:r");
+ if (c < 0)
+ break;
+ switch (c) {
+ case 's':
+ args.start = parse_size(optarg);
+ break;
+ case 'e':
+ args.end = parse_size(optarg);
+ break;
+ default:
+ fprintf(stderr, "ERROR: Invalid arguments for csize\n");
+ return 1;
+ }
+ }
+
+ if (args.start > args.end) {
+ fprintf(stderr, "ERROR: Invalid range for csize\n");
+ return 1;
+ }
+
+ if (argc - optind == 0) {
+ fprintf(stderr, "ERROR: Invalid arguments for csize\n");
+ return 1;
+ }
+ argc -= optind;
+
+ fd = open_file_or_dir(argv[optind]);
+ if (fd < 0) {
+ fprintf(stderr, "ERROR: can't access '%s'\n", argv[optind]);
+ return 1;
+ }
+
+ ret = ioctl(fd, BTRFS_IOC_COMPR_SIZE, &args);
+ if (ret < 0) {
+ fprintf(stderr, "ERROR: ioctl returned %d, errno %d %s\n",
+ ret, errno, strerror(errno));
+ return errno;
+ }
+
+ printf("File name: %s\n", argv[optind]);
+ if (args.end == (u64)-1)
+ printf("File range: %llu-EOF\n",
+ (unsigned long long)args.start);
+ else
+ printf("File range: %llu-%llu\n",
+ (unsigned long long)args.start,
+ (unsigned long long)args.end);
+
+ printf("Compressed size: %llu\n",
+ (unsigned long long)(args.compressed_size << 9));
+ printf("Uncompressed size: %llu\n",
+ (unsigned long long)(args.size << 9));
+ printf("Ratio: %3.2f%%\n",
+ 100.0 * args.compressed_size / args.size);
+ return 0;
+}
diff --git a/btrfs_cmds.h b/btrfs_cmds.h
index 53d51d6..07dad7a 100644
--- a/btrfs_cmds.h
+++ b/btrfs_cmds.h
@@ -46,3 +46,4 @@ int open_file_or_dir(const char *fname);
int do_ino_to_path(int nargs, char **argv);
int do_logical_to_ino(int nargs, char **argv);
char *path_for_root(int fd, u64 root);
+int do_compr_size(int argc, char **argv);
diff --git a/ioctl.h b/ioctl.h
index 78aebce..a820098 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -272,6 +272,17 @@ struct btrfs_ioctl_logical_ino_args {
__u64 inodes;
};
+struct btrfs_ioctl_compr_size_args {
+ /* Range start, inclusive */
+ __u64 start; /* in */
+ /* Range end, exclusive */
+ __u64 end; /* in */
+ __u64 size; /* out */
+ __u64 compressed_size; /* out */
+ __u64 reserved[2];
+};
+
+
/* BTRFS_IOC_SNAP_CREATE is no longer used by the btrfs command */
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
struct btrfs_ioctl_vol_args)
@@ -330,5 +341,7 @@ struct btrfs_ioctl_logical_ino_args {
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_COMPR_SIZE _IOR(BTRFS_IOCTL_MAGIC, 51, \
+ struct btrfs_ioctl_compr_size_args)
#endif
diff --git a/man/btrfs.8.in.old b/man/btrfs.8.in.old
index be478e0..b7dacea 100644
--- a/man/btrfs.8.in.old
+++ b/man/btrfs.8.in.old
@@ -31,6 +31,8 @@ btrfs \- control a btrfs filesystem
.PP
\fBbtrfs\fP \fBfilesystem defragment\fP\fI <file>|<dir> [<file>|<dir>...]\fP
.PP
+\fBbtrfs\fP \fBfilesystem csize \fP\fI [-s start] [-e end] <file> \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
@@ -209,6 +211,14 @@ 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
+\fBfilesystem csize \fR \fI [-s start] [-e end] <file> \fR
+Read ordinary and compressed size of extents in the range [start,end) of \fI<file>\fR
+.IP
+\fB-s start\fP range start inclusive, accepts K/M/G modifiers
+.IP
+\fB-e end\fP range end exclusive, accepts K/M/G modifiers
+.TP
+
\fBdevice balance\fR \fI<path>\fR
Balance the chunks of the filesystem identified by \fI<path>\fR
across the devices.
--
1.7.6.233.gd79bc
++++++ 0139-Btrfs-progs-make-find-root-spit-out-the-size-of-the-.patch ++++++
From b36b23becb0d79faefd38da11b684a78b95243c9 Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Wed, 4 Jan 2012 09:56:06 -0500
Subject: [PATCH 36/43] Btrfs-progs: make find root spit out the size of the
disk
In order to figure out what exactly is broken on a fs we need to spit out the
current offset we are on and the size of the fs to know if the super is wrong
and we just need to ignore it, or if the offset we got is bad and we should just
keep searching. Thanks,
Signed-off-by: Josef Bacik
---
find-root.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/find-root.c b/find-root.c
index e0bc069..f9cb7ed 100644
--- a/find-root.c
+++ b/find-root.c
@@ -258,7 +258,9 @@ static int find_root(struct btrfs_root *root)
if (offset >
btrfs_super_total_bytes(&root->fs_info->super_copy)) {
- printf("Went past the fs size, exiting");
+ printf("Went past the fs size, exiting, offset=%Lu, "
+ "total_bytes=%Lu\n", offset,
+ btrfs_super_total_bytes(&root->fs_info->super_copy));
break;
}
if (offset >= (metadata_offset + metadata_size)) {
--
1.7.6.233.gd79bc
++++++ 0140-Btrfs-progs-add-some-verbose-output-to-find-root.patch ++++++
From d4d88fe3c9b393e2b21754237104c68a37123aa6 Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Wed, 4 Jan 2012 10:03:33 -0500
Subject: [PATCH 37/43] Btrfs-progs: add some verbose output to find-root
Trying to track down why we can't find roots, add some verbose output so we know
what chunks we're scanning and when we move to new chunks. Thanks,
Signed-off-by: Josef Bacik
---
find-root.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/find-root.c b/find-root.c
index f9cb7ed..484f85f 100644
--- a/find-root.c
+++ b/find-root.c
@@ -250,6 +250,10 @@ static int find_root(struct btrfs_root *root)
return ret;
offset = metadata_offset;
+ if (verbose)
+ printf("Checking metadata chunk %Lu, size %Lu\n",
+ metadata_offset, metadata_size);
+
while (1) {
u64 map_length = 4096;
u64 type;
@@ -264,6 +268,8 @@ static int find_root(struct btrfs_root *root)
break;
}
if (offset >= (metadata_offset + metadata_size)) {
+ if (verbose)
+ printf("Moving to the next metadata chunk\n");
err = btrfs_next_metadata(&root->fs_info->mapping_tree,
&metadata_offset,
&metadata_size);
@@ -272,6 +278,9 @@ static int find_root(struct btrfs_root *root)
break;
}
offset = metadata_offset;
+ if (verbose)
+ printf("Checking metadata chunk %Lu, size %Lu"
+ "\n", metadata_offset, metadata_size);
}
mirror_num = 1;
again:
--
1.7.6.233.gd79bc
++++++ 0141-Btrfs-progs-fix-restore-to-actually-use-the-root-loc.patch ++++++
From f0346659db85b826c14392f9a627d845ab47b7e2 Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Wed, 4 Jan 2012 10:36:41 -0500
Subject: [PATCH 38/43] Btrfs-progs: fix restore to actually use the root
location if specified
We were using the wrong variable for the root location if we specified -f when
doing restore. Fix this. Thanks,
Signed-off-by: Josef Bacik
---
restore.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/restore.c b/restore.c
index 95daef2..0b75902 100644
--- a/restore.c
+++ b/restore.c
@@ -871,13 +871,13 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location, int super_
return NULL;
}
if (!root_location)
- bytenr = btrfs_super_root(&root->fs_info->super_copy);
+ root_location = 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,
+ root->fs_info->tree_root->node = read_tree_block(root, root_location,
blocksize,
generation);
if (!root->fs_info->tree_root->node) {
@@ -895,7 +895,7 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location, int super_
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: %ld\n", PTR_ERR(root));
+ fprintf(stderr, "Couldn't read fs_root: %d\n", PTR_ERR(root));
close_ctree(root);
return NULL;
}
--
1.7.6.233.gd79bc
++++++ 0142-Btrfs-progs-remove-the-physical-disk-size-check-from.patch ++++++
From a3958e5a851f8d0efeafe5946b8a32ea0fd45436 Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Wed, 4 Jan 2012 10:37:43 -0500
Subject: [PATCH 39/43] Btrfs-progs: remove the physical disk size check from
find-root
Our logical offsets may be beyond what we think the size of the disk is, so our
check is bogus, remove it. Thanks,
Signed-off-by: Josef Bacik
---
find-root.c | 7 -------
1 files changed, 0 insertions(+), 7 deletions(-)
diff --git a/find-root.c b/find-root.c
index 484f85f..43cb778 100644
--- a/find-root.c
+++ b/find-root.c
@@ -260,13 +260,6 @@ static int find_root(struct btrfs_root *root)
int mirror_num;
int num_copies;
- if (offset >
- btrfs_super_total_bytes(&root->fs_info->super_copy)) {
- printf("Went past the fs size, exiting, offset=%Lu, "
- "total_bytes=%Lu\n", offset,
- btrfs_super_total_bytes(&root->fs_info->super_copy));
- break;
- }
if (offset >= (metadata_offset + metadata_size)) {
if (verbose)
printf("Moving to the next metadata chunk\n");
--
1.7.6.233.gd79bc
++++++ 0143-Btrfs-progs-fix-error-output-and-dont-read-from-cach.patch ++++++
From 5ec6eeaff067c706e5bb9fc3144e9bab4e50da1e Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Wed, 4 Jan 2012 10:48:32 -0500
Subject: [PATCH 40/43] Btrfs-progs: fix error output and dont read from cache
If we have to build our fs_info by hand don't read from the cache when looking
for the fs_root just in case we set something up last time. Also actually print
the right error, not the root which is ok. Thanks,
Signed-off-by: Josef Bacik
---
restore.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/restore.c b/restore.c
index 0b75902..abc66ca 100644
--- a/restore.c
+++ b/restore.c
@@ -893,9 +893,10 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location, int super_
key.type = BTRFS_ROOT_ITEM_KEY;
key.offset = (u64)-1;
- root->fs_info->fs_root = btrfs_read_fs_root(root->fs_info, &key);
+ root->fs_info->fs_root = btrfs_read_fs_root_no_cache(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: %d\n",
+ PTR_ERR(root->fs_info->fs_root));
close_ctree(root);
return NULL;
}
--
1.7.6.233.gd79bc
++++++ 0144-Btrfs-progs-print-the-objectid-of-the-root-we-find-w.patch ++++++
From a657103b449bfae0cc67dc9d7153ee19c20d9115 Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Wed, 4 Jan 2012 10:50:31 -0500
Subject: [PATCH 41/43] Btrfs-progs: print the objectid of the root we find
when doing find-root
We need to know if we find a valid fs tree when doing find root, so print the
objectid of the roots we find when we find a tree root. Thanks,
Signed-off-by: Josef Bacik
---
find-root.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/find-root.c b/find-root.c
index 43cb778..bc7440a 100644
--- a/find-root.c
+++ b/find-root.c
@@ -138,7 +138,9 @@ static int dump_root_bytenr(struct btrfs_root *root, u64 bytenr, u64 gen)
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));
+ printf("Generation: %Lu Root bytenr: %Lu "
+ "Root objectid: %Lu\n", gen,
+ btrfs_root_bytenr(&ri), found_key.objectid);
}
path->slots[0]++;
}
--
1.7.6.233.gd79bc
++++++ 0145-Btrfs-progs-make-specifying-root-objectid-work-if-th.patch ++++++
From 87edb6fbf4991e47e7563c4589197aa88befe266 Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Wed, 4 Jan 2012 11:50:55 -0500
Subject: [PATCH 42/43] Btrfs-progs: make specifying root objectid work if the
fs is broken
We need to be able to handle the case where we want to restore from a specific
root if the fs is really really really toast, this patch does that. Thanks,
Signed-off-by: Josef Bacik
---
restore.c | 109 +++++++++++++++++++++++++++++++++++++++----------------------
1 files changed, 70 insertions(+), 39 deletions(-)
diff --git a/restore.c b/restore.c
index abc66ca..5aa35ae 100644
--- a/restore.c
+++ b/restore.c
@@ -837,7 +837,35 @@ static int do_list_roots(struct btrfs_root *root)
return 0;
}
-static struct btrfs_root *open_fs(const char *dev, u64 root_location, int super_mirror, int list_roots)
+static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
+ u32 stripesize, struct btrfs_root *root,
+ struct btrfs_fs_info *fs_info, u64 objectid)
+{
+ root->node = NULL;
+ root->commit_root = NULL;
+ root->sectorsize = sectorsize;
+ root->nodesize = nodesize;
+ root->leafsize = leafsize;
+ root->stripesize = stripesize;
+ root->ref_cows = 0;
+ root->track_dirty = 0;
+
+ root->fs_info = fs_info;
+ root->objectid = objectid;
+ root->last_trans = 0;
+ root->highest_inode = 0;
+ root->last_inode_alloc = 0;
+
+ INIT_LIST_HEAD(&root->dirty_list);
+ memset(&root->root_key, 0, sizeof(root->root_key));
+ memset(&root->root_item, 0, sizeof(root->root_item));
+ root->root_key.objectid = objectid;
+ return 0;
+}
+
+static struct btrfs_root *open_fs(const char *dev, u64 root_location,
+ u64 fs_location, u64 root_objectid,
+ int super_mirror, int list_roots)
{
struct btrfs_key key;
struct btrfs_root *root;
@@ -889,23 +917,51 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location, int super_
if (list_roots)
goto out;
- key.objectid = BTRFS_FS_TREE_OBJECTID;
- key.type = BTRFS_ROOT_ITEM_KEY;
- key.offset = (u64)-1;
+ if (!root_objectid)
+ root_objectid = BTRFS_FS_TREE_OBJECTID;
- root->fs_info->fs_root = btrfs_read_fs_root_no_cache(root->fs_info, &key);
- if (IS_ERR(root->fs_info->fs_root)) {
- fprintf(stderr, "Couldn't read fs_root: %d\n",
- PTR_ERR(root->fs_info->fs_root));
- close_ctree(root);
- return NULL;
- }
out:
+ if (fs_location) {
+ struct btrfs_root *fs_root = root->fs_info->fs_root;
+ if (fs_root) {
+ free_extent_buffer(fs_root->node);
+ } else {
+ fs_root = malloc(sizeof(struct btrfs_root));
+ if (!fs_root) {
+ fprintf(stderr, "Out of memory\n");
+ close_ctree(root);
+ return NULL;
+ }
+ __setup_root(4096, 4096, 4096, 4096, fs_root,
+ root->fs_info, root_objectid);
+ root->fs_info->fs_root = fs_root;
+ }
+ fs_root->node = read_tree_block(root, fs_location, 4096, 0);
+ if (!fs_root->node) {
+ fprintf(stderr, "Failed to read fs location\n");
+ close_ctree(root);
+ return NULL;
+ }
+ } else if (root_objectid) {
+ key.objectid = root_objectid;
+ key.type = BTRFS_ROOT_ITEM_KEY;
+ key.offset = (u64)-1;
+
+ root->fs_info->fs_root =
+ btrfs_read_fs_root_no_cache(root->fs_info, &key);
+ if (IS_ERR(root->fs_info->fs_root)) {
+ fprintf(stderr, "Error reading fs root %d\n",
+ PTR_ERR(root->fs_info->fs_root));
+ close_ctree(root);
+ return NULL;
+ }
+ }
+
if (list_roots) {
int ret = do_list_roots(root);
if (ret) {
- root = NULL;
close_ctree(root);
+ return NULL;
}
}
@@ -1074,22 +1130,14 @@ int main(int argc, char **argv)
return -EBUSY;
}
- root = open_fs(argv[optind], tree_location, super_mirror, list_roots);
+ root = open_fs(argv[optind], tree_location, fs_location, root_objectid,
+ 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);
- if (!root->node) {
- fprintf(stderr, "Failed to read fs location\n");
- goto out;
- }
- }
-
memset(path_name, 0, 4096);
strncpy(dir_name, argv[optind + 1], 128);
@@ -1102,23 +1150,6 @@ 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)
--
1.7.6.233.gd79bc
++++++ 0146-Btrfs-progs-don-t-free-the-existing-node.patch ++++++
From 77ac61128a0722cab89c785f5f2247304133b214 Mon Sep 17 00:00:00 2001
From: Josef Bacik
Date: Wed, 4 Jan 2012 11:55:43 -0500
Subject: [PATCH 43/43] Btrfs-progs: don't free the existing node
It may be used elsewhere and in the case of a broken fs it won't be there at all
and it makes an assertion trip. Thanks,
Signed-off-by: Josef Bacik
---
restore.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/restore.c b/restore.c
index 5aa35ae..a2c2931 100644
--- a/restore.c
+++ b/restore.c
@@ -923,9 +923,7 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location,
out:
if (fs_location) {
struct btrfs_root *fs_root = root->fs_info->fs_root;
- if (fs_root) {
- free_extent_buffer(fs_root->node);
- } else {
+ if (!fs_root) {
fs_root = malloc(sizeof(struct btrfs_root));
if (!fs_root) {
fprintf(stderr, "Out of memory\n");
--
1.7.6.233.gd79bc
++++++ 0147-mkfs-Handle-creation-of-filesystem-larger-than-the-f.patch ++++++
From 7e2b203768ae87b3614149e99e00afe4fa9394ab Mon Sep 17 00:00:00 2001
From: Jan Kara
Date: Thu, 26 Jan 2012 17:03:05 +0100
Subject: [PATCH] mkfs: Handle creation of filesystem larger than the first
device
make_btrfs() function takes a size of filesystem as an argument. It uses this
value to set the size of the first device as well which is wrong for
filesystems larger than this device. It results in 'attemp to access beyond end
of device' messages from the kernel. So add size of the first device as an
argument to make_btrfs().
CC: David Sterba
Signed-off-by: Jan Kara
---
convert.c | 2 +-
mkfs.c | 6 ++++--
utils.c | 4 ++--
utils.h | 2 +-
4 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/convert.c b/convert.c
index c036f46..13f3ece 100644
--- a/convert.c
+++ b/convert.c
@@ -2374,7 +2374,7 @@ int do_convert(const char *devname, int datacsum, int packing, int noxattr)
goto fail;
}
ret = make_btrfs(fd, devname, ext2_fs->super->s_volume_name,
- blocks, total_bytes, blocksize, blocksize,
+ blocks, total_bytes, total_bytes, blocksize, blocksize,
blocksize, blocksize);
if (ret) {
fprintf(stderr, "unable to create initial ctree\n");
diff --git a/mkfs.c b/mkfs.c
index be236d0..97481bd 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -1302,8 +1302,10 @@ int main(int ac, char **av)
first_file = file;
source_dir_size = size_sourcedir(source_dir, sectorsize,
&num_of_meta_chunks, &size_of_data);
- if(block_count < source_dir_size)
+ if (block_count < source_dir_size)
block_count = source_dir_size;
+ dev_block_count = block_count;
+
ret = zero_output_file(fd, block_count, sectorsize);
if (ret) {
fprintf(stderr, "unable to zero the output file\n");
@@ -1329,7 +1331,7 @@ int main(int ac, char **av)
leafsize * i;
}
- ret = make_btrfs(fd, file, label, blocks, block_count,
+ ret = make_btrfs(fd, file, label, blocks, block_count, dev_block_count,
nodesize, leafsize,
sectorsize, stripesize);
if (ret) {
diff --git a/utils.c b/utils.c
index 6c96548..a2be9c9 100644
--- a/utils.c
+++ b/utils.c
@@ -74,7 +74,7 @@ static u64 reference_root_table[] = {
};
int make_btrfs(int fd, const char *device, const char *label,
- u64 blocks[7], u64 num_bytes, u32 nodesize,
+ u64 blocks[7], u64 num_bytes, u64 dev_num_bytes, u32 nodesize,
u32 leafsize, u32 sectorsize, u32 stripesize)
{
struct btrfs_super_block super;
@@ -276,7 +276,7 @@ int make_btrfs(int fd, const char *device, const char *label,
dev_item = btrfs_item_ptr(buf, nritems, struct btrfs_dev_item);
btrfs_set_device_id(buf, dev_item, 1);
btrfs_set_device_generation(buf, dev_item, 0);
- btrfs_set_device_total_bytes(buf, dev_item, num_bytes);
+ btrfs_set_device_total_bytes(buf, dev_item, dev_num_bytes);
btrfs_set_device_bytes_used(buf, dev_item,
BTRFS_MKFS_SYSTEM_GROUP_SIZE);
btrfs_set_device_io_align(buf, dev_item, sectorsize);
diff --git a/utils.h b/utils.h
index c5f55e1..bf2d5a4 100644
--- a/utils.h
+++ b/utils.h
@@ -22,7 +22,7 @@
#define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024)
int make_btrfs(int fd, const char *device, const char *label,
- u64 blocks[6], u64 num_bytes, u32 nodesize,
+ u64 blocks[6], u64 num_bytes, u64 dev_num_bytes, u32 nodesize,
u32 leafsize, u32 sectorsize, u32 stripesize);
int btrfs_make_root_dir(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 objectid);
--
1.7.6.233.gd79bc
++++++ 0150-btrfs-progs-removed-extraneous-whitespace-from-mkfs-.patch ++++++
From c250b72ed982832cb8833dd962afed6ec7c5b27e Mon Sep 17 00:00:00 2001
From: Phillip Susi
Date: Mon, 9 Jan 2012 10:18:55 -0500
Subject: [PATCH 150/151] btrfs-progs: removed extraneous whitespace from mkfs
man page
There were extra spaces around some of the arguments in the man
page for mkfs.
Signed-off-by: Phillip Susi
---
man/mkfs.btrfs.8.in | 22 +++++++++++-----------
1 files changed, 11 insertions(+), 11 deletions(-)
Index: btrfs-progs-v0.19-118-gfdb6c04/man/mkfs.btrfs.8.in
===================================================================
--- btrfs-progs-v0.19-118-gfdb6c04.orig/man/mkfs.btrfs.8.in
+++ btrfs-progs-v0.19-118-gfdb6c04/man/mkfs.btrfs.8.in
@@ -5,16 +5,16 @@ mkfs.btrfs \- create an btrfs filesystem
.B mkfs.btrfs
[ \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 ]
-[ \fB \-M\fP\fI mixed data+metadata\fP ]
-[ \fB \-n\fP\fI nodesize\fP ]
-[ \fB \-s\fP\fI sectorsize\fP ]
-[ \fB \-h\fP ]
-[ \fB \-V\fP ] \fI device\fP [ \fI device ...\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 ]
+[ \fB\-M\fP\fI mixed data+metadata\fP ]
+[ \fB\-n\fP\fI nodesize\fP ]
+[ \fB\-s\fP\fI sectorsize\fP ]
+[ \fB\-h\fP ]
+[ \fB\-V\fP ] \fI device\fP [ \fI device ...\fP ]
.SH DESCRIPTION
.B mkfs.btrfs
is used to create an btrfs filesystem (usually in a disk partition, or an array
++++++ 0151-btrfs-progs-document-rootdir-mkfs-switch.patch ++++++
From 3a858a5e19255c402f7c97f492d0b2ac69cf286a Mon Sep 17 00:00:00 2001
From: Phillip Susi
Date: Mon, 9 Jan 2012 10:18:56 -0500
Subject: [PATCH 151/151] btrfs-progs: document --rootdir mkfs switch
Signed-off-by: Phillip Susi
---
man/mkfs.btrfs.8.in | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
Index: btrfs-progs-v0.19-118-gfdb6c04/man/mkfs.btrfs.8.in
===================================================================
--- btrfs-progs-v0.19-118-gfdb6c04.orig/man/mkfs.btrfs.8.in
+++ btrfs-progs-v0.19-118-gfdb6c04/man/mkfs.btrfs.8.in
@@ -13,6 +13,7 @@ mkfs.btrfs \- create an btrfs filesystem
[ \fB\-M\fP\fI mixed data+metadata\fP ]
[ \fB\-n\fP\fI nodesize\fP ]
[ \fB\-s\fP\fI sectorsize\fP ]
+[ \fB\-r\fP\fI rootdir\fP ]
[ \fB\-h\fP ]
[ \fB\-V\fP ] \fI device\fP [ \fI device ...\fP ]
.SH DESCRIPTION
@@ -62,6 +63,9 @@ Specify the nodesize. By default the val
\fB\-s\fR, \fB\-\-sectorsize \fIsize\fR
Specify the sectorsize, the minimum block allocation.
.TP
+\fB\-r\fR, \fB\-\-rootdir \fIrootdir\fR
+Specify a directory to copy into the newly created fs.
+.TP
\fB\-V\fR, \fB\-\-version\fR
Print the \fBmkfs.btrfs\fP version and exit.
.SH AVAILABILITY
++++++ 0152-Add-open_ctree_fs_info-for-partial-FS-opens.patch ++++++
From bffb42193524b984ec8407773a0997707bb20cbf Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Sun, 5 Feb 2012 16:11:48 -0500
Subject: [PATCH 01/18] Add open_ctree_fs_info for partial FS opens
fsck needs to be able to open a damaged FS, which means open_ctree needs
to be able to return a damaged FS.
This adds a new open_ctree_fs_info which can be used to open any and all
roots that are valid. btrfs-debug-tree is changed to use it.
Signed-off-by: Chris Mason
---
btrfsck.c | 7 +++-
debug-tree.c | 59 +++++++++++++++++++++++++-------------
disk-io.c | 90 ++++++++++++++++++++++++++++++++++++---------------------
disk-io.h | 3 ++
extent_io.c | 3 ++
5 files changed, 107 insertions(+), 55 deletions(-)
diff --git a/btrfsck.c b/btrfsck.c
index 509ab72..40eb407 100644
--- a/btrfsck.c
+++ b/btrfsck.c
@@ -2809,6 +2809,7 @@ int main(int ac, char **av)
{
struct cache_tree root_cache;
struct btrfs_root *root;
+ struct btrfs_fs_info *info;
u64 bytenr = 0;
int ret;
int num;
@@ -2846,11 +2847,13 @@ int main(int ac, char **av)
return -EBUSY;
}
- root = open_ctree(av[optind], bytenr, 0);
+ info = open_ctree_fs_info(av[optind], bytenr, 0, 0);
- if (root == NULL)
+ if (info == NULL)
return 1;
+ root = info->fs_root;
+
ret = check_extents(root);
if (ret)
goto out;
diff --git a/debug-tree.c b/debug-tree.c
index 2aeabfd..c497892 100644
--- a/debug-tree.c
+++ b/debug-tree.c
@@ -104,6 +104,7 @@ static void print_old_roots(struct btrfs_super_block *super)
int main(int ac, char **av)
{
struct btrfs_root *root;
+ struct btrfs_fs_info *info;
struct btrfs_path path;
struct btrfs_key key;
struct btrfs_root_item ri;
@@ -152,12 +153,18 @@ int main(int ac, char **av)
if (ac != 1)
print_usage();
- root = open_ctree(av[optind], 0, 0);
- if (!root) {
+ info = open_ctree_fs_info(av[optind], 0, 0, 1);
+ if (!info) {
fprintf(stderr, "unable to open %s\n", av[optind]);
exit(1);
}
+ root = info->fs_root;
+
if (block_only) {
+ if (!root) {
+ fprintf(stderr, "unable to open %s\n", av[optind]);
+ exit(1);
+ }
leaf = read_tree_block(root,
block_only,
root->leafsize, 0);
@@ -184,25 +191,32 @@ int main(int ac, char **av)
if (!extent_only) {
if (roots_only) {
printf("root tree: %llu level %d\n",
- (unsigned long long)root->fs_info->tree_root->node->start,
- btrfs_header_level(root->fs_info->tree_root->node));
+ (unsigned long long)info->tree_root->node->start,
+ btrfs_header_level(info->tree_root->node));
printf("chunk tree: %llu level %d\n",
- (unsigned long long)root->fs_info->chunk_root->node->start,
- btrfs_header_level(root->fs_info->chunk_root->node));
+ (unsigned long long)info->chunk_root->node->start,
+ btrfs_header_level(info->chunk_root->node));
} else {
- printf("root tree\n");
- btrfs_print_tree(root->fs_info->tree_root,
- root->fs_info->tree_root->node, 1);
+ if (info->tree_root->node) {
+ printf("root tree\n");
+ btrfs_print_tree(info->tree_root,
+ info->tree_root->node, 1);
+ }
- printf("chunk tree\n");
- btrfs_print_tree(root->fs_info->chunk_root,
- root->fs_info->chunk_root->node, 1);
+ if (info->chunk_root->node) {
+ printf("chunk tree\n");
+ btrfs_print_tree(info->chunk_root,
+ info->chunk_root->node, 1);
+ }
}
}
- tree_root_scan = root->fs_info->tree_root;
+ tree_root_scan = info->tree_root;
btrfs_init_path(&path);
again:
+ if (!extent_buffer_uptodate(tree_root_scan->node))
+ goto no_node;
+
key.offset = 0;
key.objectid = 0;
btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
@@ -232,6 +246,9 @@ again:
btrfs_level_size(tree_root_scan,
btrfs_root_level(&ri)),
0);
+ if (!extent_buffer_uptodate(buf))
+ goto next;
+
switch(found_key.objectid) {
case BTRFS_ROOT_TREE_OBJECTID:
if (!skip)
@@ -320,13 +337,15 @@ again:
}
}
}
+next:
path.slots[0]++;
}
+no_node:
btrfs_release_path(root, &path);
- if (tree_root_scan == root->fs_info->tree_root &&
- root->fs_info->log_root_tree) {
- tree_root_scan = root->fs_info->log_root_tree;
+ if (tree_root_scan == info->tree_root &&
+ info->log_root_tree) {
+ tree_root_scan = info->log_root_tree;
goto again;
}
@@ -334,14 +353,14 @@ again:
return 0;
if (root_backups)
- print_old_roots(&root->fs_info->super_copy);
+ print_old_roots(&info->super_copy);
printf("total bytes %llu\n",
- (unsigned long long)btrfs_super_total_bytes(&root->fs_info->super_copy));
+ (unsigned long long)btrfs_super_total_bytes(&info->super_copy));
printf("bytes used %llu\n",
- (unsigned long long)btrfs_super_bytes_used(&root->fs_info->super_copy));
+ (unsigned long long)btrfs_super_bytes_used(&info->super_copy));
uuidbuf[36] = '\0';
- uuid_unparse(root->fs_info->super_copy.fsid, uuidbuf);
+ uuid_unparse(info->super_copy.fsid, uuidbuf);
printf("uuid %s\n", uuidbuf);
printf("%s\n", BTRFS_BUILD_VERSION);
return 0;
diff --git a/disk-io.c b/disk-io.c
index b0b9502..e9fdba8 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -445,8 +445,9 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
generation = btrfs_root_generation(&root->root_item);
root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
blocksize, generation);
- if (!root->node)
- return -ENOENT;
+ if (!extent_buffer_uptodate(root->node))
+ return -EIO;
+
return 0;
}
@@ -473,7 +474,9 @@ static int find_and_setup_log_root(struct btrfs_root *tree_root,
btrfs_super_generation(disk_super) + 1);
fs_info->log_root_tree = log_root;
- BUG_ON(!log_root->node);
+
+ if (!extent_buffer_uptodate(log_root->node))
+ return -EIO;
return 0;
}
@@ -603,9 +606,9 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
return root;
}
-struct btrfs_root *__open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
+static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
u64 root_tree_bytenr, int writes,
- int use_earliest_bdev)
+ int use_earliest_bdev, int partial)
{
u32 sectorsize;
u32 nodesize;
@@ -742,7 +745,7 @@ struct btrfs_root *__open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
chunk_root->node = read_tree_block(chunk_root,
btrfs_super_chunk_root(disk_super),
blocksize, generation);
- if (!chunk_root->node) {
+ if (!extent_buffer_uptodate(chunk_root->node)) {
printk("Couldn't read chunk root\n");
goto out_devices;
}
@@ -754,7 +757,7 @@ struct btrfs_root *__open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
if (!(btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_METADUMP)) {
ret = btrfs_read_chunk_tree(chunk_root);
if (ret)
- goto out_chunk;
+ goto out_failed;
}
blocksize = btrfs_level_size(tree_root,
@@ -766,15 +769,15 @@ struct btrfs_root *__open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
tree_root->node = read_tree_block(tree_root,
root_tree_bytenr,
blocksize, generation);
- if (!tree_root->node) {
+ if (!extent_buffer_uptodate(tree_root->node)) {
printk("Couldn't read tree root\n");
- goto out_chunk;
+ goto out_failed;
}
ret = find_and_setup_root(tree_root, fs_info,
BTRFS_EXTENT_TREE_OBJECTID, extent_root);
if (ret) {
printk("Couldn't setup extent tree\n");
- goto out_tree;
+ goto out_failed;
}
extent_root->track_dirty = 1;
@@ -782,7 +785,7 @@ struct btrfs_root *__open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
BTRFS_DEV_TREE_OBJECTID, dev_root);
if (ret) {
printk("Couldn't setup device tree\n");
- goto out_extent;
+ goto out_failed;
}
dev_root->track_dirty = 1;
@@ -790,7 +793,7 @@ struct btrfs_root *__open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
BTRFS_CSUM_TREE_OBJECTID, csum_root);
if (ret) {
printk("Couldn't setup csum tree\n");
- goto out_dev;
+ goto out_failed;
}
csum_root->track_dirty = 1;
@@ -806,23 +809,28 @@ struct btrfs_root *__open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
fs_info->fs_root = btrfs_read_fs_root(fs_info, &key);
if (!fs_info->fs_root)
- goto out_csum;
+ goto out_failed;
fs_info->data_alloc_profile = (u64)-1;
fs_info->metadata_alloc_profile = (u64)-1;
fs_info->system_alloc_profile = fs_info->metadata_alloc_profile;
- return fs_info->fs_root;
-out_csum:
- free_extent_buffer(fs_info->csum_root->node);
-out_dev:
- free_extent_buffer(fs_info->dev_root->node);
-out_extent:
- free_extent_buffer(fs_info->extent_root->node);
-out_tree:
- free_extent_buffer(fs_info->tree_root->node);
-out_chunk:
- free_extent_buffer(fs_info->chunk_root->node);
+ return fs_info;
+
+out_failed:
+ if (partial)
+ return fs_info;
+
+ if (fs_info->csum_root)
+ free_extent_buffer(fs_info->csum_root->node);
+ if (fs_info->dev_root)
+ free_extent_buffer(fs_info->dev_root->node);
+ if (fs_info->extent_root)
+ free_extent_buffer(fs_info->extent_root->node);
+ if (fs_info->tree_root)
+ free_extent_buffer(fs_info->tree_root->node);
+ if (fs_info->chunk_root)
+ free_extent_buffer(fs_info->chunk_root->node);
out_devices:
close_all_devices(fs_info);
out_cleanup:
@@ -842,10 +850,12 @@ out:
return NULL;
}
-struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, int writes)
+struct btrfs_fs_info *open_ctree_fs_info(const char *filename,
+ u64 sb_bytenr, int writes,
+ int partial)
{
int fp;
- struct btrfs_root *root;
+ struct btrfs_fs_info *info;
int flags = O_CREAT | O_RDWR;
if (!writes)
@@ -856,33 +866,47 @@ 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, 0);
+ info = __open_ctree_fd(fp, filename, sb_bytenr, 0, writes, 0, partial);
close(fp);
+ return info;
+}
- return root;
+struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, int writes)
+{
+ struct btrfs_fs_info *info;
+
+ info = open_ctree_fs_info(filename, sb_bytenr, writes, 0);
+ if (!info)
+ return NULL;
+ return info->fs_root;
}
struct btrfs_root *open_ctree_recovery(const char *filename, u64 sb_bytenr,
u64 root_tree_bytenr)
{
int fp;
- struct btrfs_root *root;
+ struct btrfs_fs_info *info;
fp = open(filename, O_RDONLY);
if (fp < 0) {
fprintf (stderr, "Could not open %s\n", filename);
return NULL;
}
- root = __open_ctree_fd(fp, filename, sb_bytenr, root_tree_bytenr, 0, 0);
+ info = __open_ctree_fd(fp, filename, sb_bytenr, root_tree_bytenr, 0, 0, 0);
close(fp);
-
- return root;
+ if (!info)
+ return NULL;
+ return info->fs_root;
}
struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
int writes, int use_earliest_bdev)
{
- return __open_ctree_fd(fp, path, sb_bytenr, 0, writes, use_earliest_bdev);
+ struct btrfs_fs_info *info;
+ info = __open_ctree_fd(fp, path, sb_bytenr, 0, writes, use_earliest_bdev, 0);
+ if (!info)
+ return NULL;
+ return info->fs_root;
}
struct btrfs_root *open_ctree_broken(int fd, const char *device)
diff --git a/disk-io.h b/disk-io.h
index 2b1fcd5..664cabd 100644
--- a/disk-io.h
+++ b/disk-io.h
@@ -48,6 +48,9 @@ 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_fs_info *open_ctree_fs_info(const char *filename,
+ u64 sb_bytenr, int writes,
+ int partial);
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);
diff --git a/extent_io.c b/extent_io.c
index 973e918..9990338 100644
--- a/extent_io.c
+++ b/extent_io.c
@@ -706,6 +706,9 @@ int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
int extent_buffer_uptodate(struct extent_buffer *eb)
{
+ if (!eb)
+ return 0;
+
if (eb->flags & EXTENT_UPTODATE)
return 1;
return 0;
--
1.7.6.233.gd79bc
++++++ 0153-btrfsck-print-some-progress-Signed-off-by-Chris-Maso.patch ++++++
From bed79b9cd39caf88f5bf8fe9340afa539924a8cc Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Mon, 6 Feb 2012 05:05:59 -0500
Subject: [PATCH 02/18] btrfsck: print some progress Signed-off-by: Chris
Mason
---
btrfsck.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/btrfsck.c b/btrfsck.c
index 40eb407..a3c6286 100644
--- a/btrfsck.c
+++ b/btrfsck.c
@@ -2854,13 +2854,16 @@ int main(int ac, char **av)
root = info->fs_root;
+ fprintf(stderr, "checking extents\n");
ret = check_extents(root);
if (ret)
goto out;
+ fprintf(stderr, "checking fs roots\n");
ret = check_fs_roots(root, &root_cache);
if (ret)
goto out;
+ fprintf(stderr, "checking root refs\n");
ret = check_root_refs(root, &root_cache);
out:
free_root_recs(&root_cache);
--
1.7.6.233.gd79bc
++++++ 0154-Allow-extent_buffers-to-use-more-ram.patch ++++++
From 769671c6aeef3359498100f0ef31975706d99fca Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Mon, 6 Feb 2012 05:06:18 -0500
Subject: [PATCH 03/18] Allow extent_buffers to use more ram
This changes free_some_buffers (called each time we allocate an extent
buffer) to allow a higher hard limit on the number of extent buffers
in use.
Signed-off-by: Chris Mason
---
extent_io.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/extent_io.c b/extent_io.c
index 9990338..ebb35b2 100644
--- a/extent_io.c
+++ b/extent_io.c
@@ -28,7 +28,8 @@
#include "extent_io.h"
#include "list.h"
-u64 cache_max = 1024 * 1024 * 32;
+u64 cache_soft_max = 1024 * 1024 * 256;
+u64 cache_hard_max = 1 * 1024 * 1024 * 1024;
void extent_io_tree_init(struct extent_io_tree *tree)
{
@@ -540,18 +541,19 @@ static int free_some_buffers(struct extent_io_tree *tree)
struct extent_buffer *eb;
struct list_head *node, *next;
- if (tree->cache_size < cache_max)
+ if (tree->cache_size < cache_soft_max)
return 0;
+
list_for_each_safe(node, next, &tree->lru) {
eb = list_entry(node, struct extent_buffer, lru);
if (eb->refs == 1) {
free_extent_buffer(eb);
- if (tree->cache_size < cache_max)
+ if (tree->cache_size < cache_hard_max)
break;
} else {
list_move_tail(&eb->lru, &tree->lru);
}
- if (nrscan++ > 64)
+ if (nrscan++ > 64 && tree->cache_size < cache_hard_max)
break;
}
return 0;
--
1.7.6.233.gd79bc
++++++ 0155-btrfsck-don-t-BUG-on-corrupted-extent-records.patch ++++++
From ab19832dce62c53452454897fe1d2eaf2e1dbd59 Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Mon, 6 Feb 2012 08:53:43 -0500
Subject: [PATCH 04/18] btrfsck: don't BUG on corrupted extent records
---
btrfsck.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/btrfsck.c b/btrfsck.c
index a3c6286..90e9c80 100644
--- a/btrfsck.c
+++ b/btrfsck.c
@@ -2441,11 +2441,14 @@ static int process_extent_item(struct cache_tree *extent_cache,
0);
break;
default:
- BUG();
+ fprintf(stderr, "corrupt extent record: key %Lu %u %Lu\n",
+ key.objectid, key.type, key.offset);
+ goto out;
}
ptr += btrfs_extent_inline_ref_size(type);
}
WARN_ON(ptr > end);
+out:
return 0;
}
--
1.7.6.233.gd79bc
++++++ 0156-btrfs-corrupt-block-add-e-option-to-corrupt-the-exte.patch ++++++
From a0e60b027576e8e3e3d77b77eaff1360a374af60 Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Mon, 6 Feb 2012 08:54:05 -0500
Subject: [PATCH 05/18] btrfs-corrupt-block: add -e option to corrupt the
extent record
From 395fb7119f0aa110a2b8988e68159ff1fcf1f7f0 Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Tue, 7 Feb 2012 08:36:38 -0500
Subject: [PATCH 07/18] btrfs-corrupt-block: add -E option to randomly corrupt
This will zero out the extent allocation tree records for the extent.
Signed-off-by: Chris Mason
---
btrfs-corrupt-block.c | 115 ++++++++++++++++++++++++++++++++-----------------
1 files changed, 76 insertions(+), 39 deletions(-)
diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c
index ace61c1..59e7cb4 100644
--- a/btrfs-corrupt-block.c
+++ b/btrfs-corrupt-block.c
@@ -32,11 +32,6 @@
#include "list.h"
#include "version.h"
-/* we write the mirror info to stdout unless they are dumping the data
- * to stdout
- * */
-static FILE *info_file;
-
struct extent_buffer *debug_corrupt_block(struct btrfs_root *root, u64 bytenr,
u32 blocksize, int copy)
{
@@ -62,7 +57,7 @@ struct extent_buffer *debug_corrupt_block(struct btrfs_root *root, u64 bytenr,
device->total_ios++;
eb->dev_bytenr = multi->stripes[0].physical;
- fprintf(info_file, "mirror %d logical %Lu physical %Lu "
+ fprintf(stdout, "mirror %d logical %Lu physical %Lu "
"device %s\n", mirror_num, (unsigned long long)bytenr,
(unsigned long long)eb->dev_bytenr, device->name);
kfree(multi);
@@ -106,24 +101,88 @@ static struct option long_options[] = {
{ 0, 0, 0, 0}
};
+static int corrupt_extent(struct btrfs_root *root, u64 bytenr, int copy)
+{
+ struct btrfs_trans_handle *trans;
+ struct btrfs_key key;
+ struct extent_buffer *leaf;
+ u32 item_size;
+ unsigned long ptr;
+ struct btrfs_path *path;
+ int ret;
+ int slot;
+
+ trans = btrfs_start_transaction(root, 1);
+ path = btrfs_alloc_path();
+
+ key.objectid = bytenr;
+ key.type = (u8)-1;
+ key.offset = (u64)-1;
+
+ while(1) {
+ ret = btrfs_search_slot(trans, root->fs_info->extent_root,
+ &key, path, 0, 1);
+ if (ret < 0)
+ break;
+
+ if (ret > 0) {
+ if (path->slots[0] == 0)
+ break;
+ path->slots[0]--;
+ }
+ leaf = path->nodes[0];
+ slot = path->slots[0];
+ btrfs_item_key_to_cpu(leaf, &key, slot);
+ if (key.objectid != bytenr)
+ break;
+
+ if (key.type != BTRFS_EXTENT_ITEM_KEY &&
+ key.type != BTRFS_TREE_BLOCK_REF_KEY &&
+ key.type != BTRFS_EXTENT_DATA_REF_KEY &&
+ key.type != BTRFS_EXTENT_REF_V0_KEY &&
+ key.type != BTRFS_SHARED_BLOCK_REF_KEY &&
+ key.type != BTRFS_SHARED_DATA_REF_KEY)
+ goto next;
+
+ fprintf(stderr, "corrupting extent record: key %Lu %u %Lu\n",
+ key.objectid, key.type, key.offset);
+
+ ptr = btrfs_item_ptr_offset(leaf, slot);
+ item_size = btrfs_item_size_nr(leaf, slot);
+ memset_extent_buffer(leaf, 0, ptr, item_size);
+ btrfs_mark_buffer_dirty(leaf);
+next:
+ btrfs_release_path(NULL, path);
+
+ if (key.offset > 0)
+ key.offset--;
+ if (key.offset == 0)
+ break;
+ }
+
+ btrfs_free_path(path);
+ btrfs_commit_transaction(trans, root);
+ ret = close_ctree(root);
+ BUG_ON(ret);
+ return 0;
+}
+
int main(int ac, char **av)
{
struct cache_tree root_cache;
struct btrfs_root *root;
struct extent_buffer *eb;
char *dev;
- char *output_file = NULL;
u64 logical = 0;
int ret = 0;
int option_index = 0;
int copy = 0;
u64 bytes = 4096;
- int out_fd = 0;
- int err;
+ int extent_rec;
while(1) {
int c;
- c = getopt_long(ac, av, "l:c:", long_options,
+ c = getopt_long(ac, av, "l:c:e", long_options,
&option_index);
if (c < 0)
break;
@@ -152,6 +211,9 @@ int main(int ac, char **av)
print_usage();
}
break;
+ case 'e':
+ extent_rec = 1;
+ break;
default:
print_usage();
}
@@ -174,23 +236,9 @@ int main(int ac, char **av)
fprintf(stderr, "Open ctree failed\n");
exit(1);
}
-
- info_file = stdout;
- if (output_file) {
- if (strcmp(output_file, "-") == 0) {
- out_fd = 1;
- info_file = stderr;
- } else {
- out_fd = open(output_file, O_RDWR | O_CREAT, 0600);
- if (out_fd < 0)
- goto close;
- err = ftruncate(out_fd, 0);
- if (err) {
- close(out_fd);
- goto close;
- }
- info_file = stdout;
- }
+ if (extent_rec) {
+ ret = corrupt_extent (root, logical, 0);
+ goto out;
}
if (bytes == 0)
@@ -201,21 +249,10 @@ int main(int ac, char **av)
while (bytes > 0) {
eb = debug_corrupt_block(root, logical, root->sectorsize, copy);
- if (eb && output_file) {
- err = write(out_fd, eb->data, eb->len);
- if (err < 0 || err != eb->len) {
- fprintf(stderr, "output file write failed\n");
- goto out_close_fd;
- }
- }
free_extent_buffer(eb);
logical += root->sectorsize;
bytes -= root->sectorsize;
}
-
-out_close_fd:
- if (output_file && out_fd != 1)
- close(out_fd);
-close:
+out:
return ret;
}
--
1.7.6.233.gd79bc
++++++ 0157-btrfsck-add-code-to-rebuild-extent-records.patch ++++++
++++ 892 lines (skipped)
++++++ 0158-btrfs-corrupt-block-add-E-option-to-randomly-corrupt.patch ++++++
the extent_root
Signed-off-by: Chris Mason
---
btrfs-corrupt-block.c | 132 +++++++++++++++++++++++++++++++++++++++----------
extent-tree.c | 9 ++-
2 files changed, 111 insertions(+), 30 deletions(-)
diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c
index 59e7cb4..9ad3e05 100644
--- a/btrfs-corrupt-block.c
+++ b/btrfs-corrupt-block.c
@@ -93,17 +93,9 @@ static void print_usage(void)
exit(1);
}
-static struct option long_options[] = {
- /* { "byte-count", 1, NULL, 'b' }, */
- { "logical", 1, NULL, 'l' },
- { "copy", 1, NULL, 'c' },
- { "bytes", 1, NULL, 'b' },
- { 0, 0, 0, 0}
-};
-
-static int corrupt_extent(struct btrfs_root *root, u64 bytenr, int copy)
+static int corrupt_extent(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, u64 bytenr, int copy)
{
- struct btrfs_trans_handle *trans;
struct btrfs_key key;
struct extent_buffer *leaf;
u32 item_size;
@@ -111,8 +103,8 @@ static int corrupt_extent(struct btrfs_root *root, u64 bytenr, int copy)
struct btrfs_path *path;
int ret;
int slot;
+ int should_del = rand() % 3;
- trans = btrfs_start_transaction(root, 1);
path = btrfs_alloc_path();
key.objectid = bytenr;
@@ -121,7 +113,7 @@ static int corrupt_extent(struct btrfs_root *root, u64 bytenr, int copy)
while(1) {
ret = btrfs_search_slot(trans, root->fs_info->extent_root,
- &key, path, 0, 1);
+ &key, path, -1, 1);
if (ret < 0)
break;
@@ -129,6 +121,7 @@ static int corrupt_extent(struct btrfs_root *root, u64 bytenr, int copy)
if (path->slots[0] == 0)
break;
path->slots[0]--;
+ ret = 0;
}
leaf = path->nodes[0];
slot = path->slots[0];
@@ -144,13 +137,26 @@ static int corrupt_extent(struct btrfs_root *root, u64 bytenr, int copy)
key.type != BTRFS_SHARED_DATA_REF_KEY)
goto next;
- fprintf(stderr, "corrupting extent record: key %Lu %u %Lu\n",
- key.objectid, key.type, key.offset);
+ if (should_del) {
+ fprintf(stderr, "deleting extent record: key %Lu %u %Lu\n",
+ key.objectid, key.type, key.offset);
- ptr = btrfs_item_ptr_offset(leaf, slot);
- item_size = btrfs_item_size_nr(leaf, slot);
- memset_extent_buffer(leaf, 0, ptr, item_size);
- btrfs_mark_buffer_dirty(leaf);
+ if (key.type == BTRFS_EXTENT_ITEM_KEY) {
+ /* make sure this extent doesn't get
+ * reused for other purposes */
+ btrfs_pin_extent(root->fs_info,
+ key.objectid, key.offset);
+ }
+
+ btrfs_del_item(trans, root, path);
+ } else {
+ fprintf(stderr, "corrupting extent record: key %Lu %u %Lu\n",
+ key.objectid, key.type, key.offset);
+ ptr = btrfs_item_ptr_offset(leaf, slot);
+ item_size = btrfs_item_size_nr(leaf, slot);
+ memset_extent_buffer(leaf, 0, ptr, item_size);
+ btrfs_mark_buffer_dirty(leaf);
+ }
next:
btrfs_release_path(NULL, path);
@@ -161,12 +167,65 @@ next:
}
btrfs_free_path(path);
- btrfs_commit_transaction(trans, root);
- ret = close_ctree(root);
- BUG_ON(ret);
return 0;
}
+static void btrfs_corrupt_extent_leaf(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, struct extent_buffer *eb)
+{
+ u32 nr = btrfs_header_nritems(eb);
+ u32 victim = rand() % nr;
+ u64 objectid;
+ struct btrfs_key key;
+
+ btrfs_item_key_to_cpu(eb, &key, victim);
+ objectid = key.objectid;
+ corrupt_extent(trans, root, objectid, 1);
+}
+
+static void btrfs_corrupt_extent_tree(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, struct extent_buffer *eb)
+{
+ int i;
+ u32 nr;
+
+ if (!eb)
+ return;
+
+ nr = btrfs_header_nritems(eb);
+ if (btrfs_is_leaf(eb)) {
+ btrfs_corrupt_extent_leaf(trans, root, eb);
+ return;
+ }
+
+ if (btrfs_header_level(eb) == 1 && eb != root->node) {
+ if (rand() % 5)
+ return;
+ }
+
+ for (i = 0; i < nr; i++) {
+ struct extent_buffer *next;
+
+ next = read_tree_block(root, btrfs_node_blockptr(eb, i),
+ root->leafsize, btrfs_node_ptr_generation(eb, i));
+ if (!next)
+ continue;
+ btrfs_corrupt_extent_tree(trans, root, next);
+ free_extent_buffer(next);
+ }
+}
+
+static struct option long_options[] = {
+ /* { "byte-count", 1, NULL, 'b' }, */
+ { "logical", 1, NULL, 'l' },
+ { "copy", 1, NULL, 'c' },
+ { "bytes", 1, NULL, 'b' },
+ { "extent-record", 0, NULL, 'e' },
+ { "extent-tree", 0, NULL, 'E' },
+ { 0, 0, 0, 0}
+};
+
+
int main(int ac, char **av)
{
struct cache_tree root_cache;
@@ -178,11 +237,14 @@ int main(int ac, char **av)
int option_index = 0;
int copy = 0;
u64 bytes = 4096;
- int extent_rec;
+ int extent_rec = 0;
+ int extent_tree = 0;
+
+ srand(128);
while(1) {
int c;
- c = getopt_long(ac, av, "l:c:e", long_options,
+ c = getopt_long(ac, av, "l:c:eE", long_options,
&option_index);
if (c < 0)
break;
@@ -214,6 +276,9 @@ int main(int ac, char **av)
case 'e':
extent_rec = 1;
break;
+ case 'E':
+ extent_tree = 1;
+ break;
default:
print_usage();
}
@@ -221,7 +286,7 @@ int main(int ac, char **av)
ac = ac - optind;
if (ac == 0)
print_usage();
- if (logical == 0)
+ if (logical == 0 && !extent_tree)
print_usage();
if (copy < 0)
print_usage();
@@ -237,8 +302,19 @@ int main(int ac, char **av)
exit(1);
}
if (extent_rec) {
- ret = corrupt_extent (root, logical, 0);
- goto out;
+ struct btrfs_trans_handle *trans;
+ trans = btrfs_start_transaction(root, 1);
+ ret = corrupt_extent (trans, root, logical, 0);
+ btrfs_commit_transaction(trans, root);
+ goto out_close;
+ }
+ if (extent_tree) {
+ struct btrfs_trans_handle *trans;
+ trans = btrfs_start_transaction(root, 1);
+ btrfs_corrupt_extent_tree(trans, root->fs_info->extent_root,
+ root->fs_info->extent_root->node);
+ btrfs_commit_transaction(trans, root);
+ goto out_close;
}
if (bytes == 0)
@@ -253,6 +329,8 @@ int main(int ac, char **av)
logical += root->sectorsize;
bytes -= root->sectorsize;
}
-out:
+ return ret;
+out_close:
+ close_ctree(root);
return ret;
}
diff --git a/extent-tree.c b/extent-tree.c
index 1f13992..01dfa3f 100644
--- a/extent-tree.c
+++ b/extent-tree.c
@@ -1083,7 +1083,9 @@ static int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
ptr += sizeof(struct btrfs_tree_block_info);
BUG_ON(ptr > end);
} else {
- BUG_ON(!(flags & BTRFS_EXTENT_FLAG_DATA));
+ if (!(flags & BTRFS_EXTENT_FLAG_DATA)) {
+ return -EIO;
+ }
}
err = -ENOENT;
@@ -2120,8 +2122,6 @@ static int __free_extent(struct btrfs_trans_handle *trans,
extent_slot = path->slots[0];
}
} else {
- btrfs_print_leaf(extent_root, path->nodes[0]);
- WARN_ON(1);
printk(KERN_ERR "btrfs unable to find ref byte nr %llu "
"parent %llu root %llu owner %llu offset %llu\n",
(unsigned long long)bytenr,
@@ -2129,6 +2129,8 @@ static int __free_extent(struct btrfs_trans_handle *trans,
(unsigned long long)root_objectid,
(unsigned long long)owner_objectid,
(unsigned long long)owner_offset);
+ ret = -EIO;
+ goto fail;
}
leaf = path->nodes[0];
@@ -2238,6 +2240,7 @@ static int __free_extent(struct btrfs_trans_handle *trans,
mark_free);
BUG_ON(ret);
}
+fail:
btrfs_free_path(path);
finish_current_insert(trans, extent_root);
return ret;
--
1.7.6.233.gd79bc
++++++ 0159-btrfsck-fix-block-group-accounting-during-repair.patch ++++++
From 4fc0390c2bbce8a5b39fb592da80bfe1870152a4 Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Wed, 8 Feb 2012 21:29:13 -0500
Subject: [PATCH 08/18] btrfsck: fix block group accounting during repair
Signed-off-by: Chris Mason
---
btrfsck.c | 36 +++++++++-----
convert.c | 62 +-----------------------
ctree.h | 3 +
extent-tree.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 174 insertions(+), 75 deletions(-)
Index: btrfs-progs-v0.19-118-gfdb6c04/btrfsck.c
===================================================================
--- btrfs-progs-v0.19-118-gfdb6c04.orig/btrfsck.c
+++ btrfs-progs-v0.19-118-gfdb6c04/btrfsck.c
@@ -2725,7 +2725,7 @@ static int add_root_to_pending(struct ex
static int delete_extent_records(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct btrfs_path *path,
- u64 bytenr)
+ u64 bytenr, u64 new_len)
{
struct btrfs_key key;
struct btrfs_key found_key;
@@ -2787,7 +2787,7 @@ static int delete_extent_records(struct
if (found_key.type == BTRFS_EXTENT_ITEM_KEY) {
ret = btrfs_update_block_group(trans, root, bytenr,
- found_key.offset, 0, 1);
+ found_key.offset, 0, 0);
if (ret)
break;
}
@@ -2959,7 +2959,7 @@ static int fixup_extent_refs(struct btrf
/* step one, delete all the existing records */
ret = delete_extent_records(trans, info->extent_root, path,
- rec->start);
+ rec->start, rec->max_size);
if (ret < 0)
goto out;
@@ -2987,19 +2987,16 @@ out:
return ret;
}
-static int check_extent_refs(struct btrfs_root *root,
- struct cache_tree *extent_cache, int repair)
+static int check_extent_refs(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct cache_tree *extent_cache, int repair)
{
struct extent_record *rec;
struct cache_extent *cache;
- struct btrfs_trans_handle *trans = NULL;
int err = 0;
int ret = 0;
int fixed = 0;
- if (repair)
- trans = btrfs_start_transaction(root, 1);
-
if (repair) {
/*
* if we're doing a repair, we have to make sure
@@ -3074,12 +3071,12 @@ repair_abort:
fprintf(stderr, "failed to repair damaged filesystem, aborting\n");
exit(1);
}
- btrfs_commit_transaction(trans, root);
}
return err;
}
-static int check_extents(struct btrfs_root *root, int repair)
+static int check_extents(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, int repair)
{
struct cache_tree extent_cache;
struct cache_tree seen;
@@ -3160,7 +3157,7 @@ static int check_extents(struct btrfs_ro
if (ret != 0)
break;
}
- ret = check_extent_refs(root, &extent_cache, repair);
+ ret = check_extent_refs(trans, root, &extent_cache, repair);
free(bits);
return ret;
}
@@ -3183,6 +3180,7 @@ int main(int ac, char **av)
struct cache_tree root_cache;
struct btrfs_root *root;
struct btrfs_fs_info *info;
+ struct btrfs_trans_handle *trans = NULL;
u64 bytenr = 0;
int ret;
int num;
@@ -3244,9 +3242,16 @@ int main(int ac, char **av)
root = info->fs_root;
fprintf(stderr, "checking extents\n");
- ret = check_extents(root, repair);
+ if (repair)
+ trans = btrfs_start_transaction(root, 1);
+
+ ret = check_extents(trans, root, repair);
if (ret)
goto out;
+
+ if (repair)
+ btrfs_fix_block_accounting(trans, root);
+
fprintf(stderr, "checking fs roots\n");
ret = check_fs_roots(root, &root_cache);
if (ret)
@@ -3256,6 +3261,11 @@ int main(int ac, char **av)
ret = check_root_refs(root, &root_cache);
out:
free_root_recs(&root_cache);
+ if (repair) {
+ ret = btrfs_commit_transaction(trans, root);
+ if (ret)
+ exit(1);
+ }
close_ctree(root);
if (found_old_backref) {
Index: btrfs-progs-v0.19-118-gfdb6c04/convert.c
===================================================================
--- btrfs-progs-v0.19-118-gfdb6c04.orig/convert.c
+++ btrfs-progs-v0.19-118-gfdb6c04/convert.c
@@ -1504,66 +1504,6 @@ fail:
return new_root;
}
-/*
- * Fixup block accounting. The initial block accounting created by
- * make_block_groups isn't accuracy in this case.
- */
-static int fixup_block_accounting(struct btrfs_trans_handle *trans,
- struct btrfs_root *root)
-{
- int ret;
- int slot;
- u64 start = 0;
- u64 bytes_used = 0;
- struct btrfs_path path;
- struct btrfs_key key;
- struct extent_buffer *leaf;
- struct btrfs_block_group_cache *cache;
- struct btrfs_fs_info *fs_info = root->fs_info;
-
- while(1) {
- cache = btrfs_lookup_block_group(fs_info, start);
- if (!cache)
- break;
- start = cache->key.objectid + cache->key.offset;
- btrfs_set_block_group_used(&cache->item, 0);
- cache->space_info->bytes_used = 0;
- }
-
- btrfs_init_path(&path);
- key.offset = 0;
- key.objectid = 0;
- btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
- ret = btrfs_search_slot(trans, root->fs_info->extent_root,
- &key, &path, 0, 0);
- if (ret < 0)
- return ret;
- while(1) {
- leaf = path.nodes[0];
- slot = path.slots[0];
- if (slot >= btrfs_header_nritems(leaf)) {
- ret = btrfs_next_leaf(root, &path);
- if (ret < 0)
- return ret;
- if (ret > 0)
- break;
- leaf = path.nodes[0];
- slot = path.slots[0];
- }
- btrfs_item_key_to_cpu(leaf, &key, slot);
- if (key.type == BTRFS_EXTENT_ITEM_KEY) {
- bytes_used += key.offset;
- ret = btrfs_update_block_group(trans, root,
- key.objectid, key.offset, 1, 0);
- BUG_ON(ret);
- }
- path.slots[0]++;
- }
- btrfs_set_super_bytes_used(&root->fs_info->super_copy, bytes_used);
- btrfs_release_path(root, &path);
- return 0;
-}
-
static int create_chunk_mapping(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{
@@ -1735,7 +1675,7 @@ static int init_btrfs(struct btrfs_root
ret = btrfs_make_block_groups(trans, root);
if (ret)
goto err;
- ret = fixup_block_accounting(trans, root);
+ ret = btrfs_fixup_block_accounting(trans, root);
if (ret)
goto err;
ret = create_chunk_mapping(trans, root);
Index: btrfs-progs-v0.19-118-gfdb6c04/ctree.h
===================================================================
--- btrfs-progs-v0.19-118-gfdb6c04.orig/ctree.h
+++ btrfs-progs-v0.19-118-gfdb6c04/ctree.h
@@ -1785,6 +1785,9 @@ static inline u32 btrfs_level_size(struc
btrfs_item_offset_nr(leaf, slot)))
/* extent-tree.c */
+int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root);
+int btrfs_check_block_accounting(struct btrfs_root *root);
void btrfs_pin_extent(struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes);
int btrfs_extent_post_op(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
Index: btrfs-progs-v0.19-118-gfdb6c04/extent-tree.c
===================================================================
--- btrfs-progs-v0.19-118-gfdb6c04.orig/extent-tree.c
+++ btrfs-progs-v0.19-118-gfdb6c04/extent-tree.c
@@ -1734,7 +1734,12 @@ static int update_space_info(struct btrf
if (found) {
found->total_bytes += total_bytes;
found->bytes_used += bytes_used;
- WARN_ON(found->total_bytes < found->bytes_used);
+ if (found->total_bytes < found->bytes_used) {
+ fprintf(stderr, "warning, bad space info total_bytes "
+ "%llu used %llu\n",
+ (unsigned long long)found->total_bytes,
+ (unsigned long long)found->bytes_used);
+ }
*space_info = found;
return 0;
}
@@ -1853,6 +1858,7 @@ static int update_block_group(struct btr
old_val = btrfs_block_group_used(&cache->item);
num_bytes = min(total, cache->key.offset - byte_in_group);
+
if (alloc) {
old_val += num_bytes;
cache->space_info->bytes_used += num_bytes;
@@ -3274,3 +3280,143 @@ int btrfs_update_block_group(struct btrf
return update_block_group(trans, root, bytenr, num_bytes,
alloc, mark_free);
}
+
+static int btrfs_count_extents_in_block_group(struct btrfs_root *root,
+ struct btrfs_path *path, u64 start,
+ u64 len,
+ u64 *total)
+{
+ struct btrfs_key key;
+ struct extent_buffer *leaf;
+ u64 bytes_used = 0;
+ int ret;
+ int slot;
+
+ key.offset = 0;
+ key.objectid = start;
+ btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
+ ret = btrfs_search_slot(NULL, root->fs_info->extent_root,
+ &key, path, 0, 0);
+ if (ret < 0)
+ return ret;
+ while(1) {
+ leaf = path->nodes[0];
+ slot = path->slots[0];
+ if (slot >= btrfs_header_nritems(leaf)) {
+ ret = btrfs_next_leaf(root, path);
+ if (ret < 0)
+ return ret;
+ if (ret > 0)
+ break;
+ leaf = path->nodes[0];
+ slot = path->slots[0];
+ }
+ btrfs_item_key_to_cpu(leaf, &key, slot);
+ if (key.objectid > start + len)
+ break;
+ if (key.type == BTRFS_EXTENT_ITEM_KEY)
+ bytes_used += key.offset;
+ path->slots[0]++;
+ }
+ *total = bytes_used;
+ btrfs_release_path(root, path);
+ return 0;
+}
+
+int btrfs_check_block_accounting(struct btrfs_root *root)
+{
+ int ret;
+ u64 start = 0;
+ u64 bytes_used = 0;
+ struct btrfs_path path;
+ struct btrfs_block_group_cache *cache;
+ struct btrfs_fs_info *fs_info = root->fs_info;
+
+ btrfs_init_path(&path);
+
+ while(1) {
+ cache = btrfs_lookup_block_group(fs_info, start);
+ if (!cache)
+ break;
+
+ ret = btrfs_count_extents_in_block_group(root, &path,
+ cache->key.objectid,
+ cache->key.offset,
+ &bytes_used);
+
+ if (ret == 0) {
+ u64 on_disk = btrfs_block_group_used(&cache->item);
+ if (on_disk != bytes_used) {
+ fprintf(stderr, "bad block group accounting found %llu "
+ "expected %llu block group %llu\n",
+ (unsigned long long)bytes_used,
+ (unsigned long long)on_disk,
+ (unsigned long long)cache->key.objectid);
+ }
+ }
+ start = cache->key.objectid + cache->key.offset;
+
+ cache->space_info->bytes_used = 0;
+ }
+ return 0;
+}
+
+/*
+ * Fixup block accounting. The initial block accounting created by
+ * make_block_groups isn't accuracy in this case.
+ */
+int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root)
+{
+ int ret;
+ int slot;
+ u64 start = 0;
+ u64 bytes_used = 0;
+ struct btrfs_path path;
+ struct btrfs_key key;
+ struct extent_buffer *leaf;
+ struct btrfs_block_group_cache *cache;
+ struct btrfs_fs_info *fs_info = root->fs_info;
+
+ while(1) {
+ cache = btrfs_lookup_block_group(fs_info, start);
+ if (!cache)
+ break;
+ start = cache->key.objectid + cache->key.offset;
+ btrfs_set_block_group_used(&cache->item, 0);
+ cache->space_info->bytes_used = 0;
+ }
+
+ btrfs_init_path(&path);
+ key.offset = 0;
+ key.objectid = 0;
+ btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
+ ret = btrfs_search_slot(trans, root->fs_info->extent_root,
+ &key, &path, 0, 0);
+ if (ret < 0)
+ return ret;
+ while(1) {
+ leaf = path.nodes[0];
+ slot = path.slots[0];
+ if (slot >= btrfs_header_nritems(leaf)) {
+ ret = btrfs_next_leaf(root, &path);
+ if (ret < 0)
+ return ret;
+ if (ret > 0)
+ break;
+ leaf = path.nodes[0];
+ slot = path.slots[0];
+ }
+ btrfs_item_key_to_cpu(leaf, &key, slot);
+ if (key.type == BTRFS_EXTENT_ITEM_KEY) {
+ bytes_used += key.offset;
+ ret = btrfs_update_block_group(trans, root,
+ key.objectid, key.offset, 1, 0);
+ BUG_ON(ret);
+ }
+ path.slots[0]++;
+ }
+ btrfs_set_super_bytes_used(&root->fs_info->super_copy, bytes_used);
+ btrfs_release_path(root, &path);
+ return 0;
+}
++++++ 0160-Turn-off-some-commands-in-Makefile.patch ++++++
From 6608cffe25fb1d1c3c33caffc98f2f9ba59ed2e6 Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Wed, 8 Feb 2012 21:38:20 -0500
Subject: [PATCH 09/18] Turn off some commands in Makefile
Signed-off-by: Chris Mason
---
Makefile | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/Makefile b/Makefile
index 055d2d6..930500e 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ LIBS=-luuid
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 \
+ btrfs btrfs-map-logical btrfs-image btrfs-zero-log \
btrfs-dump-super
btrfs_man_page_source = btrfs.c btrfs_cmds.c scrub.c
--
1.7.6.233.gd79bc
++++++ 0161-Fix-btrfs-convert-btrfs-restore-and-btrfs-find-root-.patch ++++++
From 46f7f481f4270304f358c4c6a0020ca0ca7b9e97 Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Wed, 8 Feb 2012 22:26:26 -0500
Subject: [PATCH 10/18] Fix btrfs-convert, btrfs-restore and btrfs-find-root
build
Signed-off-by: Chris Mason
fixit
Signed-off-by: Chris Mason
---
Makefile | 14 +++++++-------
convert.c | 2 +-
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/Makefile b/Makefile
index 930500e..556bcce 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,8 @@ LIBS=-luuid
RESTORE_LIBS=-lz -llzo2
progs = btrfsctl mkfs.btrfs btrfs-debug-tree btrfs-show btrfs-vol btrfsck \
- btrfs btrfs-map-logical btrfs-image btrfs-zero-log \
+ btrfs btrfs-map-logical btrfs-image btrfs-zero-log btrfs-convert \
+ btrfs-find-root btrfs-restore btrfstune \
btrfs-dump-super
btrfs_man_page_source = btrfs.c btrfs_cmds.c scrub.c
@@ -47,11 +48,11 @@ btrfs: $(objects) btrfs.o btrfs_cmds.o scrub.o helpmsg.o
calc-size: $(objects) calc-size.o
gcc $(CFLAGS) -o calc-size calc-size.o $(objects) $(LDFLAGS) $(LIBS)
-find-root: $(objects) find-root.o
- gcc $(CFLAGS) -o find-root find-root.o $(objects) $(LDFLAGS) $(LIBS)
+btrfs-find-root: $(objects) find-root.o
+ gcc $(CFLAGS) -o btrfs-find-root find-root.o $(objects) $(LDFLAGS) $(LIBS)
-restore: $(objects) restore.o
- gcc $(CFLAGS) -o restore restore.o $(objects) $(LDFLAGS) $(LIBS) $(RESTORE_LIBS)
+btrfs-restore: $(objects) restore.o
+ gcc $(CFLAGS) -o btrfs-restore restore.o $(objects) $(LDFLAGS) $(LIBS) $(RESTORE_LIBS)
btrfsctl: $(objects) btrfsctl.o
$(CC) $(CFLAGS) -o btrfsctl btrfsctl.o $(objects) $(LDFLAGS) $(LIBS)
@@ -98,7 +99,7 @@ dir-test: $(objects) dir-test.o
quick-test: $(objects) quick-test.o
$(CC) $(CFLAGS) -o quick-test $(objects) quick-test.o $(LDFLAGS) $(LIBS)
-convert: $(objects) convert.o
+btrfs-convert: $(objects) convert.o
$(CC) $(CFLAGS) -o btrfs-convert $(objects) convert.o -lext2fs -lcom_err $(LDFLAGS) $(LIBS)
ioctl-test: $(objects) ioctl-test.o
@@ -140,7 +141,6 @@ clean :
install: $(progs) install-man
$(INSTALL) -m755 -d $(DESTDIR)$(bindir)
$(INSTALL) $(progs) $(DESTDIR)$(bindir)
- if [ -e btrfs-convert ]; then $(INSTALL) btrfs-convert $(DESTDIR)$(bindir); fi
test: test-userspace test-root
diff --git a/convert.c b/convert.c
index a2f7925..5afcc45 100644
--- a/convert.c
+++ b/convert.c
@@ -1675,7 +1675,7 @@ static int init_btrfs(struct btrfs_root *root)
ret = btrfs_make_block_groups(trans, root);
if (ret)
goto err;
- ret = btrfs_fixup_block_accounting(trans, root);
+ ret = btrfs_fix_block_accounting(trans, root);
if (ret)
goto err;
ret = create_chunk_mapping(trans, root);
--
1.7.6.233.gd79bc
++++++ 0162-btrfsck-make-sure-to-dirty-all-block-groups-as-we-fi.patch ++++++
From 494ba283ed46df812d56652d6ccc1b548bb5fe17 Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Thu, 9 Feb 2012 09:29:19 -0500
Subject: [PATCH 11/18] btrfsck: make sure to dirty all block groups as we fix
accounting
The code that corrects the count of bytes used in each block group
was only marking block groups dirty when they contained extents. This
fixes things to dirty all the block groups, so any empty block groups
are written with their correct (zero) count.
Signed-off-by: Chris Mason
---
extent-tree.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/extent-tree.c b/extent-tree.c
index 544ab2f..5c4057e 100644
--- a/extent-tree.c
+++ b/extent-tree.c
@@ -3378,6 +3378,8 @@ int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans,
struct btrfs_block_group_cache *cache;
struct btrfs_fs_info *fs_info = root->fs_info;
+ root = root->fs_info->extent_root;
+
while(1) {
cache = btrfs_lookup_block_group(fs_info, start);
if (!cache)
@@ -3385,6 +3387,10 @@ int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans,
start = cache->key.objectid + cache->key.offset;
btrfs_set_block_group_used(&cache->item, 0);
cache->space_info->bytes_used = 0;
+ set_extent_bits(&root->fs_info->block_group_cache,
+ cache->key.objectid,
+ cache->key.objectid + cache->key.offset -1,
+ BLOCK_GROUP_DIRTY, GFP_NOFS);
}
btrfs_init_path(&path);
--
1.7.6.233.gd79bc
++++++ 0163-btrfsck-add-init-csum-tree-to-replace-the-csum-root-.patch ++++++
From 80a0a84e46d07d2b2b07991ee2813b017301786c Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Thu, 9 Feb 2012 10:38:05 -0500
Subject: [PATCH 12/18] btrfsck: add --init-csum-tree to replace the csum root
with an empty one
This will effectively delete all of your crcs, but at least you'll
be able to mount the FS with nodatasum.
Signed-off-by: Chris Mason
---
btrfsck.c | 27 ++++++++++++++++++++++-----
ctree.c | 40 ++++++++++++++++++++++++++++++++++++++++
ctree.h | 2 ++
disk-io.c | 3 ++-
4 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/btrfsck.c b/btrfsck.c
index 1320238..a451397 100644
--- a/btrfsck.c
+++ b/btrfsck.c
@@ -3171,6 +3171,7 @@ static void print_usage(void)
static struct option long_options[] = {
{ "super", 1, NULL, 's' },
{ "repair", 0, NULL, 0 },
+ { "init-csum-tree", 0, NULL, 0 },
{ 0, 0, 0, 0}
};
@@ -3185,6 +3186,8 @@ int main(int ac, char **av)
int num;
int repair = 0;
int option_index = 0;
+ int init_csum_tree = 0;
+ int rw = 0;
while(1) {
int c;
@@ -3206,6 +3209,11 @@ int main(int ac, char **av)
if (option_index == 1) {
printf("enabling repair mode\n");
repair = 1;
+ rw = 1;
+ } else if (option_index == 2) {
+ printf("Creating a new CRC tree\n");
+ init_csum_tree = 1;
+ rw = 1;
}
}
@@ -3225,7 +3233,7 @@ int main(int ac, char **av)
return -EBUSY;
}
- info = open_ctree_fs_info(av[optind], bytenr, repair, 1);
+ info = open_ctree_fs_info(av[optind], bytenr, rw, 1);
if (info == NULL)
return 1;
@@ -3241,9 +3249,19 @@ int main(int ac, char **av)
root = info->fs_root;
fprintf(stderr, "checking extents\n");
- if (repair)
+ if (rw)
trans = btrfs_start_transaction(root, 1);
+ if (init_csum_tree) {
+ fprintf(stderr, "Reinit crc root\n");
+ ret = btrfs_fsck_reinit_root(trans, info->csum_root);
+ if (ret) {
+ fprintf(stderr, "crc root initialization failed\n");
+ return -EIO;
+ }
+ goto out;
+ }
+
ret = check_extents(trans, root, repair);
if (ret)
goto out;
@@ -3260,15 +3278,14 @@ int main(int ac, char **av)
ret = check_root_refs(root, &root_cache);
out:
free_root_recs(&root_cache);
- if (repair) {
+ if (rw) {
ret = btrfs_commit_transaction(trans, root);
if (ret)
exit(1);
}
close_ctree(root);
- if (found_old_backref) {
- /*
+ if (found_old_backref) { /*
* there was a disk format change when mixed
* backref was in testing tree. The old format
* existed about one week.
diff --git a/ctree.c b/ctree.c
index 005550f..282c868 100644
--- a/ctree.c
+++ b/ctree.c
@@ -138,6 +138,46 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
return 0;
}
+int btrfs_fsck_reinit_root(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root)
+{
+ struct extent_buffer *c;
+ struct extent_buffer *old = root->node;
+ int level;
+ struct btrfs_disk_key disk_key = {0,0,0};
+
+ level = 0;
+
+ c = btrfs_alloc_free_block(trans, root,
+ btrfs_level_size(root, 0),
+ root->root_key.objectid,
+ &disk_key, level, 0, 0);
+ if (IS_ERR(c))
+ return PTR_ERR(c);
+
+ memset_extent_buffer(c, 0, 0, sizeof(struct btrfs_header));
+ btrfs_set_header_level(c, level);
+ btrfs_set_header_bytenr(c, c->start);
+ btrfs_set_header_generation(c, trans->transid);
+ btrfs_set_header_backref_rev(c, BTRFS_MIXED_BACKREF_REV);
+ btrfs_set_header_owner(c, root->root_key.objectid);
+
+ write_extent_buffer(c, root->fs_info->fsid,
+ (unsigned long)btrfs_header_fsid(c),
+ BTRFS_FSID_SIZE);
+
+ write_extent_buffer(c, root->fs_info->chunk_tree_uuid,
+ (unsigned long)btrfs_header_chunk_tree_uuid(c),
+ BTRFS_UUID_SIZE);
+
+ btrfs_mark_buffer_dirty(c);
+
+ free_extent_buffer(old);
+ root->node = c;
+ add_root_to_dirty_list(root);
+ return 0;
+}
+
/*
* check if the tree block can be shared by multiple trees
*/
diff --git a/ctree.h b/ctree.h
index 6f12869..c53f65a 100644
--- a/ctree.h
+++ b/ctree.h
@@ -1851,6 +1851,8 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 bytenr, u64 num,
int alloc, int mark_free);
/* ctree.c */
+int btrfs_fsck_reinit_root(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root);
void reada_for_search(struct btrfs_root *root, struct btrfs_path *path,
int level, int slot, u64 objectid);
struct extent_buffer *read_node_slot(struct btrfs_root *root,
diff --git a/disk-io.c b/disk-io.c
index e9fdba8..d9df313 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -793,7 +793,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, u64 sb_by
BTRFS_CSUM_TREE_OBJECTID, csum_root);
if (ret) {
printk("Couldn't setup csum tree\n");
- goto out_failed;
+ if (!partial)
+ goto out_failed;
}
csum_root->track_dirty = 1;
--
1.7.6.233.gd79bc
++++++ 0164-btrfsck-make-sure-we-fix-the-block-group-accounting-.patch ++++++
From 1cc34194f336d77e96bc11baec9bea765fdc9849 Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Thu, 9 Feb 2012 11:53:33 -0500
Subject: [PATCH 13/18] btrfsck: make sure we fix the block group accounting
during repair
From a84a34ca88e7157fda4306ab87a6372e0825628d Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Fri, 10 Feb 2012 13:28:50 -0500
Subject: [PATCH 14/18] btrfsck: remove extents from the fsck reference
The block group accounting is fixed after we check the extent back
references. This makes sure the accounting is fixed unless we
were not able to repair the backrefs.
Signed-off-by: Chris Mason
---
btrfsck.c | 12 ++++++++----
extent-tree.c | 24 ++++++++++++++++++++++++
2 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/btrfsck.c b/btrfsck.c
index a451397..3aa19ae 100644
--- a/btrfsck.c
+++ b/btrfsck.c
@@ -3070,7 +3070,12 @@ repair_abort:
if (ret) {
fprintf(stderr, "failed to repair damaged filesystem, aborting\n");
exit(1);
+ } else {
+ btrfs_fix_block_accounting(trans, root);
}
+ if (err)
+ fprintf(stderr, "repaired damaged extent references\n");
+ return ret;
}
return err;
}
@@ -3263,11 +3268,10 @@ int main(int ac, char **av)
}
ret = check_extents(trans, root, repair);
- if (ret)
+ if (ret) {
+ fprintf(stderr, "check extents failed with %d!!!!!!!!!\n", ret);
goto out;
-
- if (repair)
- btrfs_fix_block_accounting(trans, root);
+ }
fprintf(stderr, "checking fs roots\n");
ret = check_fs_roots(root, &root_cache);
diff --git a/extent-tree.c b/extent-tree.c
index 5c4057e..dd593fe 100644
--- a/extent-tree.c
+++ b/extent-tree.c
@@ -1953,6 +1953,21 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
return 0;
}
+static int extent_root_pending_ops(struct btrfs_fs_info *info)
+{
+ u64 start;
+ u64 end;
+ int ret;
+
+ ret = find_first_extent_bit(&info->extent_ins, 0, &start,
+ &end, EXTENT_LOCKED);
+ if (!ret) {
+ ret = find_first_extent_bit(&info->pending_del, 0, &start, &end,
+ EXTENT_LOCKED);
+ }
+ return ret == 0;
+
+}
static int finish_current_insert(struct btrfs_trans_handle *trans,
struct btrfs_root *extent_root)
{
@@ -3380,6 +3395,15 @@ int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans,
root = root->fs_info->extent_root;
+ while(extent_root_pending_ops(fs_info)) {
+ ret = finish_current_insert(trans, root);
+ if (ret)
+ return ret;
+ ret = del_pending_extents(trans, root);
+ if (ret)
+ return ret;
+ }
+
while(1) {
cache = btrfs_lookup_block_group(fs_info, start);
if (!cache)
--
1.7.6.233.gd79bc
++++++ 0165-btrfsck-remove-extents-from-the-fsck-reference-track.patch ++++++
tracker as they are freed
During btrfsck --repair, we make an index of extents that have incorrect
reference counts. Once we've collect the whole index, we go through
and modify the extent allocation tree to reflect the correct results.
Changing the extent allocation tree may free blocks, and so it may
end up removing a block that had a missing reference structure. The
fsck code may then circle back around and add the reference back.
The result is an extent that isn't actually used, but is recorded in the
extent allocation tree.
This commit adds a hook called as extents are freed. The hook searches
the index of incorrect references and updates it to reflect the freeing
of the extent.
Signed-off-by: Chris Mason
---
btrfsck.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
ctree.h | 6 ++++
extent-tree.c | 6 ++++
3 files changed, 99 insertions(+), 7 deletions(-)
Index: btrfs-progs-v0.19-118-gfdb6c04/btrfsck.c
===================================================================
--- btrfs-progs-v0.19-118-gfdb6c04.orig/btrfsck.c
+++ btrfs-progs-v0.19-118-gfdb6c04/btrfsck.c
@@ -2137,7 +2137,7 @@ static int add_extent_rec(struct cache_t
if (inc_ref)
rec->refs++;
if (rec->nr == 1)
- rec->nr = nr;
+ rec->nr = max(nr, max_size);
if (start != rec->start) {
fprintf(stderr, "warning, start mismatch %llu %llu\n",
@@ -2175,7 +2175,7 @@ static int add_extent_rec(struct cache_t
rec = malloc(sizeof(*rec));
rec->start = start;
rec->max_size = max_size;
- rec->nr = nr;
+ rec->nr = max(nr, max_size);
rec->content_checked = 0;
rec->owner_ref_checked = 0;
INIT_LIST_HEAD(&rec->backrefs);
@@ -2722,6 +2722,77 @@ static int add_root_to_pending(struct ex
return 0;
}
+/* as we fix the tree, we might be deleting blocks that
+ * we're tracking for repair. This hook makes sure we
+ * remove any backrefs for blocks as we are fixing them.
+ */
+static int free_extent_hook(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ u64 bytenr, u64 num_bytes, u64 parent,
+ u64 root_objectid, u64 owner, u64 offset,
+ int refs_to_drop)
+{
+ struct extent_record *rec;
+ struct cache_extent *cache;
+ int is_data;
+ struct cache_tree *extent_cache = root->fs_info->fsck_extent_cache;
+
+ is_data = owner >= BTRFS_FIRST_FREE_OBJECTID;
+ cache = find_cache_extent(extent_cache, bytenr, num_bytes);
+ if (!cache)
+ return 0;
+
+ rec = container_of(cache, struct extent_record, cache);
+ if (is_data) {
+ struct data_backref *back;
+ back = find_data_backref(rec, parent, root_objectid, owner,
+ offset);
+ if (!back)
+ goto out;
+ if (back->node.found_ref) {
+ back->found_ref -= refs_to_drop;
+ if (rec->refs)
+ rec->refs -= refs_to_drop;
+ }
+ if (back->node.found_extent_tree) {
+ back->num_refs -= refs_to_drop;
+ if (rec->extent_item_refs)
+ rec->extent_item_refs -= refs_to_drop;
+ }
+ if (back->found_ref == 0)
+ back->node.found_ref = 0;
+ if (back->num_refs == 0)
+ back->node.found_extent_tree = 0;
+
+ if (!back->node.found_extent_tree && back->node.found_ref) {
+ list_del(&back->node.list);
+ free(back);
+ }
+ } else {
+ struct tree_backref *back;
+ back = find_tree_backref(rec, parent, root_objectid);
+ if (!back)
+ goto out;
+ if (back->node.found_ref) {
+ if (rec->refs)
+ rec->refs--;
+ back->node.found_ref = 0;
+ }
+ if (back->node.found_extent_tree) {
+ if (rec->extent_item_refs)
+ rec->extent_item_refs--;
+ back->node.found_extent_tree = 0;
+ }
+ if (!back->node.found_extent_tree && back->node.found_ref) {
+ list_del(&back->node.list);
+ free(back);
+ }
+ }
+ maybe_free_extent_rec(extent_cache, rec);
+out:
+ return 0;
+}
+
static int delete_extent_records(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct btrfs_path *path,
@@ -3008,7 +3079,7 @@ static int check_extent_refs(struct btrf
while(cache) {
rec = container_of(cache, struct extent_record, cache);
btrfs_pin_extent(root->fs_info,
- rec->start, rec->nr);
+ rec->start, rec->max_size);
cache = next_cache_extent(cache);
}
}
@@ -3105,6 +3176,11 @@ static int check_extents(struct btrfs_tr
cache_tree_init(&nodes);
cache_tree_init(&reada);
+ if (repair) {
+ root->fs_info->fsck_extent_cache = &extent_cache;
+ root->fs_info->free_extent_hook = free_extent_hook;
+ }
+
bits_nr = 1024;
bits = malloc(bits_nr * sizeof(struct block_info));
if (!bits) {
@@ -3163,6 +3239,12 @@ static int check_extents(struct btrfs_tr
break;
}
ret = check_extent_refs(trans, root, &extent_cache, repair);
+
+ if (repair) {
+ root->fs_info->fsck_extent_cache = NULL;
+ root->fs_info->free_extent_hook = NULL;
+ }
+
free(bits);
return ret;
}
@@ -3269,10 +3351,8 @@ int main(int ac, char **av)
}
ret = check_extents(trans, root, repair);
- if (ret) {
- fprintf(stderr, "check extents failed with %d!!!!!!!!!\n", ret);
- goto out;
- }
+ if (ret)
+ fprintf(stderr, "Errors found in extent allocation tree\n");
fprintf(stderr, "checking fs roots\n");
ret = check_fs_roots(root, &root_cache);
Index: btrfs-progs-v0.19-118-gfdb6c04/ctree.h
===================================================================
--- btrfs-progs-v0.19-118-gfdb6c04.orig/ctree.h
+++ btrfs-progs-v0.19-118-gfdb6c04/ctree.h
@@ -797,6 +797,12 @@ struct btrfs_fs_info {
struct list_head space_info;
int system_allocs;
int readonly;
+ int (*free_extent_hook)(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ u64 bytenr, u64 num_bytes, u64 parent,
+ u64 root_objectid, u64 owner, u64 offset,
+ int refs_to_drop);
+ struct cache_tree * fsck_extent_cache;
};
/*
Index: btrfs-progs-v0.19-118-gfdb6c04/extent-tree.c
===================================================================
--- btrfs-progs-v0.19-118-gfdb6c04.orig/extent-tree.c
+++ btrfs-progs-v0.19-118-gfdb6c04/extent-tree.c
@@ -2083,6 +2083,12 @@ static int __free_extent(struct btrfs_tr
u32 item_size;
u64 refs;
+ if (root->fs_info->free_extent_hook) {
+ root->fs_info->free_extent_hook(trans, root, bytenr, num_bytes,
+ parent, root_objectid, owner_objectid,
+ owner_offset, refs_to_drop);
+
+ }
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
++++++ 0166-Btrfsck-add-the-ability-to-prune-corrupt-extent-allo.patch ++++++
++++ 974 lines (skipped)
++++++ 0167-Btrfs-use-proc-partitions-scanning-for-btrfs_scan_fo.patch ++++++
From 8ded348cf85fd8572d4ee7fc9d0cad150f4fc2be Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Tue, 21 Feb 2012 15:33:20 -0500
Subject: [PATCH 16/18] Btrfs: use /proc/partitions scanning for
btrfs_scan_for_fsid
btrfs_scan_for_fsid is used by open_ctree and by mkfs when it is
checking for mounted devices. It currently scans all of /dev,
which is rarely the right answer.
Signed-off-by: Chris Mason
---
utils.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/utils.c b/utils.c
index cfb8fde..2d82342 100644
--- a/utils.c
+++ b/utils.c
@@ -1052,7 +1052,12 @@ fail:
int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs,
int run_ioctls)
{
- return btrfs_scan_one_dir("/dev", run_ioctls);
+ int ret;
+
+ ret = btrfs_scan_block_devices(run_ioctls);
+ if (ret)
+ ret = btrfs_scan_one_dir("/dev", run_ioctls);
+ return ret;
}
int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
--
1.7.6.233.gd79bc
++++++ 0168-Scan-dev-md-and-device-mapper-devices-last.patch ++++++
From bde44c1e4808c8b3d7291d2ad22536d4b5d7e2f5 Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Tue, 21 Feb 2012 15:56:10 -0500
Subject: [PATCH 17/18] Scan /dev/md and device mapper devices last
When we're using multipath or raid0, it is possible
that btrfs dev scan will find one of the component devices
instead of the proper virtual device the kernel creates.
We want to make sure the kernel scans the virtual devices last,
since it always remembers the last device it finds with a given fsid.
Signed-off-by: Chris Mason
---
utils.c | 25 ++++++++++++++++++++++++-
volumes.c | 9 ++++++++-
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/utils.c b/utils.c
index 2d82342..0beaf80 100644
--- a/utils.c
+++ b/utils.c
@@ -1156,7 +1156,10 @@ int btrfs_scan_block_devices(int run_ioctl)
int i;
char buf[1024];
char fullpath[110];
+ int scans = 0;
+ int special;
+scan_again:
proc_partitions = fopen("/proc/partitions","r");
if (!proc_partitions) {
fprintf(stderr, "Unable to open '/proc/partitions' for scanning\n");
@@ -1172,8 +1175,23 @@ int btrfs_scan_block_devices(int run_ioctl)
strcpy(fullpath,"/dev/");
while(fgets(buf, 1023, proc_partitions)) {
-
i = sscanf(buf," %*d %*d %*d %99s", fullpath+5);
+
+ /*
+ * multipath and MD devices may register as a btrfs filesystem
+ * both through the original block device and through
+ * the special (/dev/mapper or /dev/mdX) entry.
+ * This scans the special entries last
+ */
+ special = strncmp(fullpath, "/dev/dm-", strlen("/dev/dm-")) == 0;
+ if (!special)
+ special = strncmp(fullpath, "/dev/md", strlen("/dev/md")) == 0;
+
+ if (scans == 0 && special)
+ continue;
+ if (scans > 0 && !special)
+ continue;
+
ret = lstat(fullpath, &st);
if (ret < 0) {
fprintf(stderr, "failed to stat %s\n", fullpath);
@@ -1198,6 +1216,11 @@ int btrfs_scan_block_devices(int run_ioctl)
}
fclose(proc_partitions);
+
+ if (scans == 0) {
+ scans++;
+ goto scan_again;
+ }
return 0;
}
diff --git a/volumes.c b/volumes.c
index 74c88de..e7f4c3e 100644
--- a/volumes.c
+++ b/volumes.c
@@ -130,7 +130,14 @@ static int device_list_add(const char *path,
btrfs_stack_device_bytes_used(&disk_super->dev_item);
list_add(&device->dev_list, &fs_devices->devices);
device->fs_devices = fs_devices;
- }
+ } else if (!device->name || strcmp(device->name, path)) {
+ char *name = strdup(path);
+ if (!name)
+ return -ENOMEM;
+ kfree(device->name);
+ device->name = name;
+ }
+
if (found_transid > fs_devices->latest_trans) {
fs_devices->latest_devid = devid;
--
1.7.6.233.gd79bc
++++++ 0169-btrfsck-add-early-code-to-handle-corrupted-block-gro.patch ++++++
From 6d1e1b7a4cfd1e0ab93efa42c14759848a26a6d4 Mon Sep 17 00:00:00 2001
From: Chris Mason
Date: Tue, 21 Feb 2012 21:20:54 -0500
Subject: [PATCH 18/18] btrfsck: add early code to handle corrupted block
groups
This is mostly disabled, but it is step one in handling
corrupted block groups in the extent allocation tree.
Signed-off-by: Chris Mason
---
btrfs-corrupt-block.c | 5 ----
btrfsck.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++-
ctree.c | 8 +++++-
extent-tree.c | 19 ++++++----------
volumes.c | 12 ----------
volumes.h | 13 +++++++++++
6 files changed, 81 insertions(+), 32 deletions(-)
diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c
index 980a006..7051e99 100644
--- a/btrfs-corrupt-block.c
+++ b/btrfs-corrupt-block.c
@@ -242,11 +242,6 @@ static void btrfs_corrupt_extent_tree(struct btrfs_trans_handle *trans,
if (!eb)
return;
- if ((rand() % 10) == 0) {
- corrupt_keys(trans, root, eb);
- return;
- }
-
nr = btrfs_header_nritems(eb);
if (btrfs_is_leaf(eb)) {
btrfs_corrupt_extent_leaf(trans, root, eb);
diff --git a/btrfsck.c b/btrfsck.c
index 7dc84b5..c1a28bc 100644
--- a/btrfsck.c
+++ b/btrfsck.c
@@ -26,6 +26,7 @@
#include
#include "kerncompat.h"
#include "ctree.h"
+#include "volumes.h"
#include "repair.h"
#include "disk-io.h"
#include "print-tree.h"
@@ -3140,6 +3141,55 @@ static void free_corrupt_blocks(struct btrfs_fs_info *info)
}
}
+static int check_block_group(struct btrfs_trans_handle *trans,
+ struct btrfs_fs_info *info,
+ struct map_lookup *map,
+ int *reinit)
+{
+ struct btrfs_key key;
+ struct btrfs_path path;
+ int ret;
+
+ key.objectid = map->ce.start;
+ key.offset = map->ce.size;
+ key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
+
+ btrfs_init_path(&path);
+ ret = btrfs_search_slot(NULL, info->extent_root,
+ &key, &path, 0, 0);
+ btrfs_release_path(NULL, &path);
+ if (ret <= 0)
+ goto out;
+
+ ret = btrfs_make_block_group(trans, info->extent_root, 0, map->type,
+ BTRFS_FIRST_CHUNK_TREE_OBJECTID,
+ key.objectid, key.offset);
+ *reinit = 1;
+out:
+ return ret;
+}
+
+static int check_block_groups(struct btrfs_trans_handle *trans,
+ struct btrfs_fs_info *info, int *reinit)
+{
+ struct cache_extent *ce;
+ struct map_lookup *map;
+ struct btrfs_mapping_tree *map_tree = &info->mapping_tree;
+
+ /* this isn't quite working */
+ return 0;
+
+ ce = find_first_cache_extent(&map_tree->cache_tree, 0);
+ while (1) {
+ if (!ce)
+ break;
+ map = container_of(ce, struct map_lookup, ce);
+ check_block_group(trans, info, map, reinit);
+ ce = next_cache_extent(ce);
+ }
+ return 0;
+}
+
static int check_extent_refs(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct cache_tree *extent_cache, int repair)
@@ -3149,6 +3199,7 @@ static int check_extent_refs(struct btrfs_trans_handle *trans,
int err = 0;
int ret = 0;
int fixed = 0;
+ int reinit = 0;
if (repair) {
/*
@@ -3174,6 +3225,9 @@ static int check_extent_refs(struct btrfs_trans_handle *trans,
cache = next_cache_extent(cache);
}
prune_corrupt_blocks(trans, root->fs_info);
+ check_block_groups(trans, root->fs_info, &reinit);
+ if (reinit)
+ btrfs_read_block_groups(root->fs_info->extent_root);
}
while(1) {
fixed = 0;
@@ -3356,6 +3410,7 @@ static struct option long_options[] = {
{ "super", 1, NULL, 's' },
{ "repair", 0, NULL, 0 },
{ "init-csum-tree", 0, NULL, 0 },
+ { "init-extent-tree", 0, NULL, 0 },
{ 0, 0, 0, 0}
};
@@ -3445,7 +3500,6 @@ int main(int ac, char **av)
}
goto out;
}
-
ret = check_extents(trans, root, repair);
if (ret)
fprintf(stderr, "Errors found in extent allocation tree\n");
diff --git a/ctree.c b/ctree.c
index a49bce4..2d86b1e 100644
--- a/ctree.c
+++ b/ctree.c
@@ -151,8 +151,10 @@ int btrfs_fsck_reinit_root(struct btrfs_trans_handle *trans,
btrfs_level_size(root, 0),
root->root_key.objectid,
&disk_key, level, 0, 0);
- if (IS_ERR(c))
- return PTR_ERR(c);
+ if (IS_ERR(c)) {
+ c = old;
+ extent_buffer_get(c);
+ }
memset_extent_buffer(c, 0, 0, sizeof(struct btrfs_header));
btrfs_set_header_level(c, level);
@@ -1262,6 +1264,8 @@ again:
key->objectid);
b = read_node_slot(root, b, slot);
+ if (!extent_buffer_uptodate(b))
+ return -EIO;
} else {
p->slots[level] = slot;
if (ins_len > 0 &&
diff --git a/extent-tree.c b/extent-tree.c
index ee87f1f..20cdffa 100644
--- a/extent-tree.c
+++ b/extent-tree.c
@@ -1703,7 +1703,6 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
cache = (struct btrfs_block_group_cache *)(unsigned long)ptr;
ret = write_one_cache_group(trans, root, path, cache);
- BUG_ON(ret);
}
btrfs_free_path(path);
return 0;
@@ -1894,6 +1893,10 @@ static int update_pinned_extents(struct btrfs_root *root,
}
while (num > 0) {
cache = btrfs_lookup_block_group(fs_info, bytenr);
+ if (!cache) {
+ len = min((u64)root->sectorsize, num);
+ goto next;
+ }
WARN_ON(!cache);
len = min(num, cache->key.offset -
(bytenr - cache->key.objectid));
@@ -1906,6 +1909,7 @@ static int update_pinned_extents(struct btrfs_root *root,
cache->space_info->bytes_pinned -= len;
fs_info->total_pinned -= len;
}
+next:
bytenr += len;
num -= len;
}
@@ -2263,9 +2267,7 @@ static int __free_extent(struct btrfs_trans_handle *trans,
BUG_ON(ret);
}
- ret = update_block_group(trans, root, bytenr, num_bytes, 0,
- mark_free);
- BUG_ON(ret);
+ update_block_group(trans, root, bytenr, num_bytes, 0, mark_free);
}
fail:
btrfs_free_path(path);
@@ -2596,13 +2598,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
ret = update_block_group(trans, root, ins->objectid, ins->offset,
1, 0);
- if (ret) {
- printk(KERN_ERR "btrfs update block group failed for %llu "
- "%llu\n", (unsigned long long)ins->objectid,
- (unsigned long long)ins->offset);
- BUG();
- }
- return ret;
+ return 0;
}
static int alloc_tree_block(struct btrfs_trans_handle *trans,
@@ -3185,7 +3181,6 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
finish_current_insert(trans, extent_root);
ret = del_pending_extents(trans, extent_root);
- BUG_ON(ret);
set_avail_alloc_bits(extent_root->fs_info, type);
return 0;
}
diff --git a/volumes.c b/volumes.c
index e7f4c3e..088f639 100644
--- a/volumes.c
+++ b/volumes.c
@@ -35,18 +35,6 @@ struct stripe {
u64 physical;
};
-struct map_lookup {
- struct cache_extent ce;
- u64 type;
- int io_align;
- int io_width;
- int stripe_len;
- int sector_size;
- int num_stripes;
- int sub_stripes;
- struct btrfs_bio_stripe stripes[];
-};
-
#define map_lookup_size(n) (sizeof(struct map_lookup) + \
(sizeof(struct btrfs_bio_stripe) * (n)))
diff --git a/volumes.h b/volumes.h
index c34af74..4755176 100644
--- a/volumes.h
+++ b/volumes.h
@@ -18,6 +18,7 @@
#ifndef __BTRFS_VOLUMES_
#define __BTRFS_VOLUMES_
+
struct btrfs_device {
struct list_head dev_list;
struct btrfs_root *dev_root;
@@ -92,6 +93,18 @@ struct btrfs_multi_bio {
struct btrfs_bio_stripe stripes[];
};
+struct map_lookup {
+ struct cache_extent ce;
+ u64 type;
+ int io_align;
+ int io_width;
+ int stripe_len;
+ int sector_size;
+ int num_stripes;
+ int sub_stripes;
+ struct btrfs_bio_stripe stripes[];
+};
+
#define btrfs_multi_bio_size(n) (sizeof(struct btrfs_multi_bio) + \
(sizeof(struct btrfs_bio_stripe) * (n)))
--
1.7.6.233.gd79bc
++++++ 0170-Btrfs-progs-btrfs-map-logical-Fix-typo-in-usage.patch ++++++
From 863db40c3f7cc3a3f7c035ea5747e84c9e2b8747 Mon Sep 17 00:00:00 2001
From: Miao Xie
Date: Thu, 23 Feb 2012 15:51:09 +0800
Subject: [PATCH 1/3] Btrfs-progs, btrfs-map-logical: Fix typo in usage
The right option is 'o' not 'c'. And this tool is used for the block devices
on which there is a btrfs file system, so change "mount_point" to "device".
Signed-off-by: Miao Xie
---
btrfs-map-logical.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/btrfs-map-logical.c b/btrfs-map-logical.c
index d79a73a..fa4fb3f 100644
--- a/btrfs-map-logical.c
+++ b/btrfs-map-logical.c
@@ -84,7 +84,7 @@ struct extent_buffer *debug_read_block(struct btrfs_root *root, u64 bytenr,
static void print_usage(void)
{
- fprintf(stderr, "usage: btrfs-map-logical [options] mount_point\n");
+ fprintf(stderr, "usage: btrfs-map-logical [options] device\n");
fprintf(stderr, "\t-l Logical extent to map\n");
fprintf(stderr, "\t-c Copy of the extent to read (usually 1 or 2)\n");
fprintf(stderr, "\t-o Output file to hold the extent\n");
@@ -96,7 +96,7 @@ static struct option long_options[] = {
/* { "byte-count", 1, NULL, 'b' }, */
{ "logical", 1, NULL, 'l' },
{ "copy", 1, NULL, 'c' },
- { "output", 1, NULL, 'c' },
+ { "output", 1, NULL, 'o' },
{ "bytes", 1, NULL, 'b' },
{ 0, 0, 0, 0}
};
--
1.7.6.233.gd79bc
++++++ 0171-Btrfs-progs-btrfs-corrupt-block-fix-the-wrong-usage.patch ++++++
From 2b0d4908db8a2b6120be1617b50187b32b79e56e Mon Sep 17 00:00:00 2001
From: Miao Xie
Date: Thu, 23 Feb 2012 15:52:05 +0800
Subject: [PATCH 2/3] Btrfs-progs, btrfs-corrupt-block: fix the wrong usage
The old usage is a copy of btrfs-map-logical, it's wrong, fix it.
Signed-off-by: Miao Xie
---
btrfs-corrupt-block.c | 15 +++++++++------
1 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c
index 7051e99..124fb38 100644
--- a/btrfs-corrupt-block.c
+++ b/btrfs-corrupt-block.c
@@ -85,11 +85,14 @@ struct extent_buffer *debug_corrupt_block(struct btrfs_root *root, u64 bytenr,
static void print_usage(void)
{
- fprintf(stderr, "usage: btrfs-map-logical [options] mount_point\n");
- fprintf(stderr, "\t-l Logical extent to map\n");
- fprintf(stderr, "\t-c Copy of the extent to read (usually 1 or 2)\n");
- fprintf(stderr, "\t-o Output file to hold the extent\n");
- fprintf(stderr, "\t-b Number of bytes to read\n");
+ fprintf(stderr, "usage: btrfs-corrupt-block [options] device\n");
+ fprintf(stderr, "\t-l Logical extent to be corrupted\n");
+ fprintf(stderr, "\t-c Copy of the extent to be corrupted"
+ " (usually 1 or 2, default: 0)\n");
+ fprintf(stderr, "\t-b Number of bytes to be corrupted\n");
+ fprintf(stderr, "\t-e Extent to be corrupted\n");
+ fprintf(stderr, "\t-E The whole extent free to be corrupted\n");
+ fprintf(stderr, "\t-k Corrupt keys\n");
exit(1);
}
@@ -296,7 +299,7 @@ int main(int ac, char **av)
while(1) {
int c;
- c = getopt_long(ac, av, "l:c:eEk", long_options,
+ c = getopt_long(ac, av, "l:c:b:eEk", long_options,
&option_index);
if (c < 0)
break;
--
1.7.6.233.gd79bc
++++++ 0172-Btrfs-progs-fix-btrfsck-s-snapshot-wrong-unresolved-.patch ++++++
From c1d427d2a7b8557265a641a6d199f1b9436d27af Mon Sep 17 00:00:00 2001
From: Miao Xie
Date: Thu, 23 Feb 2012 15:52:58 +0800
Subject: [PATCH 3/3] Btrfs-progs: fix btrfsck's snapshot wrong "unresolved
refs"
If the fs/file tree is not the parent of the snapshot, it is reasonable
that we can not find the relative reference and back reference. But btrfsck
doesn't consider this case, and reports "unresolved refs" message, it's wrong,
fix it.
Signed-off-by: Miao Xie
---
btrfsck.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 67 insertions(+), 5 deletions(-)
diff --git a/btrfsck.c b/btrfsck.c
index c1a28bc..2f1a515 100644
--- a/btrfsck.c
+++ b/btrfsck.c
@@ -747,7 +747,65 @@ static int leave_shared_node(struct btrfs_root *root,
return 0;
}
-static int process_dir_item(struct extent_buffer *eb,
+static int is_child_root(struct btrfs_root *root, u64 parent_root_id,
+ u64 child_root_id)
+{
+ struct btrfs_path path;
+ struct btrfs_key key;
+ struct extent_buffer *leaf;
+ int has_parent = 0;
+ int ret;
+
+ btrfs_init_path(&path);
+
+ key.objectid = parent_root_id;
+ key.type = BTRFS_ROOT_REF_KEY;
+ key.offset = child_root_id;
+ ret = btrfs_search_slot(NULL, root->fs_info->tree_root, &key, &path,
+ 0, 0);
+ BUG_ON(ret < 0);
+ btrfs_release_path(root, &path);
+ if (!ret)
+ return 1;
+
+ key.objectid = child_root_id;
+ key.type = BTRFS_ROOT_BACKREF_KEY;
+ key.offset = 0;
+ ret = btrfs_search_slot(NULL, root->fs_info->tree_root, &key, &path,
+ 0, 0);
+ BUG_ON(ret <= 0);
+
+ while (1) {
+ leaf = path.nodes[0];
+ if (path.slots[0] >= btrfs_header_nritems(leaf)) {
+ ret = btrfs_next_leaf(root->fs_info->tree_root, &path);
+ BUG_ON(ret < 0);
+
+ if (ret > 0)
+ break;
+ }
+
+ btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
+ if (key.objectid != child_root_id ||
+ key.type != BTRFS_ROOT_BACKREF_KEY)
+ break;
+
+ has_parent = 1;
+
+ if (key.offset == parent_root_id) {
+ btrfs_release_path(root, &path);
+ return 1;
+ }
+
+ path.slots[0]++;
+ }
+
+ btrfs_release_path(root, &path);
+ return has_parent? 0 : -1;
+}
+
+static int process_dir_item(struct btrfs_root *root,
+ struct extent_buffer *eb,
int slot, struct btrfs_key *key,
struct shared_node *active_node)
{
@@ -795,9 +853,13 @@ static int process_dir_item(struct extent_buffer *eb,
key->objectid, key->offset, namebuf,
len, filetype, key->type, error);
} else if (location.type == BTRFS_ROOT_ITEM_KEY) {
- add_inode_backref(root_cache, location.objectid,
- key->objectid, key->offset, namebuf,
- len, filetype, key->type, error);
+ u64 parent = root->objectid;
+
+ if (is_child_root(root, parent, location.objectid))
+ add_inode_backref(root_cache, location.objectid,
+ key->objectid, key->offset,
+ namebuf, len, filetype,
+ key->type, error);
} else {
fprintf(stderr, "warning line %d\n", __LINE__);
}
@@ -1028,7 +1090,7 @@ static int process_one_leaf(struct btrfs_root *root, struct extent_buffer *eb,
switch (key.type) {
case BTRFS_DIR_ITEM_KEY:
case BTRFS_DIR_INDEX_KEY:
- ret = process_dir_item(eb, i, &key, active_node);
+ ret = process_dir_item(root, eb, i, &key, active_node);
break;
case BTRFS_INODE_REF_KEY:
ret = process_inode_ref(eb, i, &key, active_node);
--
1.7.6.233.gd79bc
++++++ boot-btrfs.sh ++++++
--- /var/tmp/diff_new_pack.HFJOpo/_old 2012-03-20 11:26:17.000000000 +0100
+++ /var/tmp/diff_new_pack.HFJOpo/_new 2012-03-20 11:26:17.000000000 +0100
@@ -1,10 +1,10 @@
#!/bin/bash -e
-#%stage: block
+#%stage: filesystem
#%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 /sbin/btrfs-dump-super
modprobe btrfs
-if [ -x /sbin/btrfs ]; then
- /sbin/btrfs dev scan >& /dev/null
+if [ -x /usr/sbin/btrfs ]; then
+ /usr/sbin/btrfs dev scan >& /dev/null
fi
++++++ btrfs-dev-clear-sb ++++++
#!/usr/bin/perl
# clear btrfs signature from a device
use Fcntl;
use constant BTRFS_SUPER_INFO_OFFSET => 64 * 1024;
use constant BTRFS_SUPER_INFO_SIZE => 4096;
use constant BTRFS_SUPER_MIRROR_MAX => 3;
use constant BTRFS_SUPER_MIRROR_SHIFT => 12;
use constant BTRFS_MAGIC => "_BHRfS_M";
use constant BTRFS_DEAD => '_BHRf$_M';
sub btrfs_sb_offset($) {
my $mirror =$_[0];
my $start = 16 * 1024;
if ($mirror>0) {
return $start << (BTRFS_SUPER_MIRROR_SHIFT * $mirror);
}
return BTRFS_SUPER_INFO_OFFSET;
}
my $dbg=1;
my $savesb=0;
# main
my $dev=$ARGV[0];
my $size;
if(!-b $dev) {
print("Not a block device: $dev\n");
$size=(stat($dev))[7];
} else {
$size=`blkdev --getsize64 "$dev"`;
}
sysopen(F, $dev, O_EXCL | O_RDWR) or die("Cannot open $dev exclusively: $!");
sysseek(F, 0, 2);
$size=tell(F);
print("Device size: $size\n") if($dbg);
for(my $i=0;$i<6;$i++) {
my $off=btrfs_sb_offset($i);
if($off > $size) {
print("Offset for SB $i beyond EOF\n") if($dbg);
last;
}
print("Offset $i is $off\n") if($dbg);
sysseek(F, $off, 0);
sysread(F, $buf, BTRFS_SUPER_INFO_SIZE);
if($savesb) {
open(Q,">SB$i");
print Q ($buf);
close(Q);
}
my $sbmagic=substr($buf, 0x40, length(BTRFS_MAGIC));
print("SB magic: $sbmagic\n") if($dbg);
if(BTRFS_MAGIC eq $sbmagic) {
print("Found a valid signature of superblock $i\n");
sysseek(F, $off + 0x40, 0);
print("Clearing...\n");
syswrite(F, BTRFS_DEAD, length(BTRFS_DEAD));
} elsif(BTRFS_DEAD eq $sbmagic) {
print("Found a signature of a dead superblock $i\n");
} else {
print("Superblock $i does not look like a btrfs one\n");
}
}
close(F);
print("Syncing dev\n");
system("fsync \'$dev\'");
++++++ btrfs-man-update ++++++
Index: btrfs-progs-v0.19-118-gfdb6c04/man/btrfs.8.in
===================================================================
--- btrfs-progs-v0.19-118-gfdb6c04.orig/man/btrfs.8.in
+++ btrfs-progs-v0.19-118-gfdb6c04/man/btrfs.8.in
@@ -29,15 +29,36 @@ btrfs \- control a btrfs filesystem
\fB\fBbtrfs\fP \fBfilesystem sync\fP\fI <path> \fP
\fP
.PP
-\fB\fBbtrfs\fP \fBscrub cancel\fP {\fI<path>\fP|\fI<device>\fP}
+\fB\fBbtrfs\fP \fBfilesystem df\fP\fI <path> \fP
\fP
.PP
-\fB\fBbtrfs\fP \fBscrub resume\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
+\fB\fBbtrfs\fP \fBfilesystem balance start [-d [filters]] [-m [filters]] [-s [filters]] [-vf]\fP\fI <path> \fP
+\fP
+.PP
+\fB\fBbtrfs\fP \fBfilesystem balance pause\fP\fI <path> \fP
+\fP
+.PP
+\fB\fBbtrfs\fP \fBfilesystem balance cancel\fP\fI <path> \fP
+\fP
+.PP
+\fB\fBbtrfs\fP \fBfilesystem balance resume\fP\fI <path> \fP
+\fP
+.PP
+\fB\fBbtrfs\fP \fBfilesystem balance status [-v]\fP\fI <path> \fP
+\fP
+.PP
+\fB\fBbtrfs\fP \fBfilesystem csize [-s start] [-e end]\fP\fI <file> \fP
\fP
.PP
\fB\fBbtrfs\fP \fBscrub start\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
\fP
.PP
+\fB\fBbtrfs\fP \fBscrub cancel\fP {\fI<path>\fP|\fI<device>\fP}
+\fP
+.PP
+\fB\fBbtrfs\fP \fBscrub resume\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
+\fP
+.PP
\fB\fBbtrfs\fP \fBscrub status\fP [-d] {\fI<path>\fP|\fI<device>\fP}
\fP
.PP
@@ -56,9 +77,18 @@ btrfs \- control a btrfs filesystem
\fB\fBbtrfs\fP \fBsubvolume set-default\fP\fI <id> <path>\fP
\fP
.PP
+\fB\fBbtrfs\fP \fBsubvolume get-default\fP\fI <path>\fP
+\fP
+.PP
\fB\fBbtrfs\fP \fBsubvolume snapshot\fP\fI [-r] <source> [<dest>/]<name>\fP
\fP
.PP
+\fB\fBbtrfs\fP \fBinspect-internal inode-resolve [-v] <inode> \fP\fI<path>\fP
+\fP
+.PP
+\fB\fBbtrfs\fP \fBinspect-internal logical-resolve [-v] [-P] <logical> \fP\fI<path>\fP
+\fP
+.PP
.SH DESCRIPTION
\fBbtrfs\fP 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
@@ -171,24 +201,26 @@ otherwise the devices list is extracted
Force a sync for the filesystem identified by \fI<path>\fP.
.TP
-\fBbtrfs\fP \fBscrub cancel\fP {\fI<path>\fP|\fI<device>\fP}
-If a scrub is running on the filesystem identified by \fI<path>\fP, cancel it.
-Progress is saved in the scrub progress file and scrubbing can be resumed later
-using the \fBscrub resume\fP command.
-If a \fI<device>\fP is given, the corresponding filesystem is found and
-\fBscrub cancel\fP behaves as if it was called on that filesystem.
+\fBbtrfs\fP \fBfilesystem df\fP\fI <path> \fP
+Show space usage information for the filesystem identified by \fI<path>\fP.
.TP
-\fBbtrfs\fP \fBscrub resume\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
-Resume a canceled or interrupted scrub cycle on the filesystem identified by
-\fI<path>\fP or on a given \fI<device>\fP. Does not start a new scrub if the
-last scrub finished successfully.
-.RS
+\fBbtrfs\fP \fBfilesystem balance\fP\fI <path> \fP
+
+Balance chunks across the devices, control by subcommands \fIstart\fP,
+\fIpause\fP, \fIcancel\fP, \fIresume\fP and read \fIstatus\fP. See section
+BALANCE FILTERS for more details.
-\fIOptions\fP
.TP
-see \fBscrub start\fP.
-.RE
+\fB\fBbtrfs\fP \fBfilesystem csize [-s start] [-e end]\fP\fI <file> \fP
+Read regular and compressed size of extents in the range \fI[start,end)\fP.
+
+\fB-s start\fP
+range start inclusive, accepts K/M/G modifiers
+\fB-e end\fP
+range end exclusive, accepts K/M/G modifiers
+
+No range reads whole file, no end of range reads up to the end of file.
.TP
\fBbtrfs\fP \fBscrub start\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
@@ -213,6 +245,26 @@ Scrub unused space as well. (NOT IMPLEME
.RE
.TP
+\fBbtrfs\fP \fBscrub cancel\fP {\fI<path>\fP|\fI<device>\fP}
+If a scrub is running on the filesystem identified by \fI<path>\fP, cancel it.
+Progress is saved in the scrub progress file and scrubbing can be resumed later
+using the \fBscrub resume\fP command.
+If a \fI<device>\fP is given, the corresponding filesystem is found and
+\fBscrub cancel\fP behaves as if it was called on that filesystem.
+
+.TP
+\fBbtrfs\fP \fBscrub resume\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
+Resume a canceled or interrupted scrub cycle on the filesystem identified by
+\fI<path>\fP or on a given \fI<device>\fP. Does not start a new scrub if the
+last scrub finished successfully.
+.RS
+
+\fIOptions\fP
+.TP
+see \fBscrub start\fP.
+.RE
+
+.TP
\fBbtrfs\fP \fBscrub status\fP [-d] {\fI<path>\fP|\fI<device>\fP}
Show status of a running scrub for the filesystem identified by \fI<path>\fP or
for the specified \fI<device>\fP.
++++++ btrfs-mkfs-update-disclaimer.patch ++++++
Index: btrfs-progs-v0.19-118-gfdb6c04/mkfs.c
===================================================================
--- btrfs-progs-v0.19-118-gfdb6c04.orig/mkfs.c
+++ btrfs-progs-v0.19-118-gfdb6c04/mkfs.c
@@ -1297,8 +1297,13 @@ int main(int ac, char **av)
if (ac == 0)
print_usage();
- printf("\nWARNING! - %s IS EXPERIMENTAL\n", BTRFS_BUILD_VERSION);
- printf("WARNING! - see http://btrfs.wiki.kernel.org before using\n\n");
+ printf("\n%s\n", BTRFS_BUILD_VERSION);
+ printf("\n\
+ATTENTION:\n\
+\n\
+mkfs.btrfs is not intended to be used directly. Please use the\n\
+YaST partitioner to create and manage btrfs filesystems to be\n\
+in a supported state on SUSE Linux Enterprise systems.\n\n");
if (source_dir == 0) {
file = av[optind++];
@@ -1456,7 +1461,6 @@ raid_groups:
pretty_buf = pretty_sizes(btrfs_super_total_bytes(&root->fs_info->super_copy)));
free(pretty_buf);
- printf("%s\n", BTRFS_BUILD_VERSION);
btrfs_commit_transaction(trans, root);
if (source_dir_set) {
++++++ btrfs-reorder-commands-help ++++++
Index: btrfs-progs-v0.19-118-gfdb6c04/btrfs.c
===================================================================
--- btrfs-progs-v0.19-118-gfdb6c04.orig/btrfs.c
+++ btrfs-progs-v0.19-118-gfdb6c04/btrfs.c
@@ -231,17 +231,17 @@ static struct Command commands[] = {
"the name <name> in the <dest> directory.",
NULL
},
- { do_delete_subvolume, 1,
- "subvolume delete", "<subvolume>\n"
- "Delete the subvolume <subvolume>.",
- NULL
- },
{ do_create_subvol, 1,
"subvolume create", "[<dest>/]<name>\n"
"Create a subvolume in <dest> (or the current directory if\n"
"not passed).",
NULL
},
+ { do_delete_subvolume, 1,
+ "subvolume delete", "<subvolume>\n"
+ "Delete the subvolume <subvolume>.",
+ NULL
+ },
{ do_subvol_list, -1, "subvolume list", "[-p] <path>\n"
"List the snapshot/subvolume of a filesystem.",
"[-p] <path>\n"
@@ -254,6 +254,9 @@ static struct Command commands[] = {
"as default.",
NULL
},
+ { do_get_default_subvol, 1, "subvolume get-default", "<path>\n"
+ "Get the default subvolume of a filesystem."
+ },
{ do_find_newer, 2, "subvolume find-new", "<path> \n"
"List the recently modified files in a filesystem.",
NULL
@@ -270,9 +273,6 @@ static struct Command commands[] = {
"-l len defragment only up to len bytes\n"
"-t size minimal size of file to be considered for defragmenting\n"
},
- { do_get_default_subvol, 1, "subvolume get-default", "<path>\n"
- "Get the default subvolume of a filesystem."
- },
{ do_fssync, 1,
"filesystem sync", "<path>\n"
"Force a sync on the filesystem <path>.",
++++++ local-version-override.patch ++++++
--- /var/tmp/diff_new_pack.HFJOpo/_old 2012-03-20 11:26:17.000000000 +0100
+++ /var/tmp/diff_new_pack.HFJOpo/_new 2012-03-20 11:26:17.000000000 +0100
@@ -1,7 +1,7 @@
-Index: btrfs-progs-v0.19-35-g1b444cd/version.sh
+Index: btrfs-progs-v0.19-116-g13eced9/version.sh
===================================================================
---- btrfs-progs-v0.19-35-g1b444cd.orig/version.sh
-+++ btrfs-progs-v0.19-35-g1b444cd/version.sh
+--- btrfs-progs-v0.19-116-g13eced9.orig/version.sh
++++ btrfs-progs-v0.19-116-g13eced9/version.sh
@@ -6,7 +6,7 @@
# Copyright 2008, Oracle
# Released under the GNU GPLv2
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org