Accepting request 208360 from filesystems

Sync to a long-awaited upstream release. Version update. Only a handful of local packages that will be upstreamed later.

This set of changes is not suitable for direct copy to currently released products because there are changes in mkfs defaults (12.x, 13.x, SLES). Fine for Factory. (forwarded request 208357 from dsterba)

OBS-URL: https://build.opensuse.org/request/show/208360
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/btrfsprogs?expand=0&rev=36
This commit is contained in:
Stephan Kulow 2013-11-28 15:50:38 +00:00 committed by Git OBS Bridge
parent c8772966fc
commit 24434a14bd
34 changed files with 481 additions and 1743 deletions

View File

@ -1,33 +0,0 @@
From 5ca1ded494d7d58b71877bf1f774ac313fabe35f Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Thu, 2 May 2013 11:20:22 -0500
Subject: [PATCH 10/48] Btrfs-progs: make btrfsck a hardlink at install time
btrfsck gets hardlinked to btrfs during the build, but the
install phase simply copies them both to the destination without
preserving the link.
Just force-link btrfsck in the destination again during install
so that the installed btrfsck is a link as well.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
Makefile | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Makefile b/Makefile
index da7438e..0f0b1ac 100644
--- a/Makefile
+++ b/Makefile
@@ -193,6 +193,8 @@ clean :
install: $(libs) $(progs) install-man
$(INSTALL) -m755 -d $(DESTDIR)$(bindir)
$(INSTALL) $(progs) $(DESTDIR)$(bindir)
+ # btrfsck is a link to btrfs in the src tree, make it so for installed file as well
+ $(LN) -f $(DESTDIR)$(bindir)/btrfs $(DESTDIR)$(bindir)/btrfsck
$(INSTALL) -m755 -d $(DESTDIR)$(libdir)
$(INSTALL) $(libs) $(DESTDIR)$(libdir)
cp -a $(lib_links) $(DESTDIR)$(libdir)
--
1.8.2

View File

@ -1,27 +0,0 @@
From 86f2f0e7742ccbfaf62e2d6415bf170a85c71c0e Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sun, 12 May 2013 16:33:44 +0100
Subject: [PATCH 12/48] libbtrfs: Set SONAME to "libbtrfs.so.0" (instead of
"libbtrfs.so").
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 0f0b1ac..7a49174 100644
--- a/Makefile
+++ b/Makefile
@@ -100,7 +100,7 @@ version.h:
$(libs_shared): $(libbtrfs_objects) $(lib_links) send.h
@echo " [LD] $@"
$(Q)$(CC) $(CFLAGS) $(libbtrfs_objects) $(LDFLAGS) $(lib_LIBS) \
- -shared -Wl,-soname,libbtrfs.so -o libbtrfs.so.0.1
+ -shared -Wl,-soname,libbtrfs.so.0 -o libbtrfs.so.0.1
$(libs_static): $(libbtrfs_objects)
@echo " [AR] $@"
--
1.8.2

View File

@ -1,36 +0,0 @@
From bdccfd46b1f2ff668351790db42e8831ca4ec4b4 Mon Sep 17 00:00:00 2001
From: Josef Bacik <jbacik@fusionio.com>
Date: Fri, 14 Jun 2013 14:25:54 -0400
Subject: [PATCH 50/62] Btrfs-progs: commit the csum_root if we do
--init-csum-tree
This is just an oddity with the commit stuff in btrfs-progs. It will just
update the generation of the root you call with, which in btrfsck case would
have been the fs_root. But because we didn't actually update the fs_root we
wouldn't have cow'ed the fs root and therefore the generation will not match the
node which will make the file system unmountable. Fix this by calling with the
csum_root which is the one we're messing with. Thanks,
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
---
cmds-check.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cmds-check.c b/cmds-check.c
index 8015288318a2..dbb41e5a4d5b 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -5800,7 +5800,7 @@ int cmd_check(int argc, char **argv)
return -EIO;
}
- ret = btrfs_commit_transaction(trans, root);
+ ret = btrfs_commit_transaction(trans, info->csum_root);
if (ret)
exit(1);
goto out;
--
1.8.3.1

View File

@ -1,45 +0,0 @@
From 892bfedb24519d95dbe3d5cdc44d26adbc1c93dc Mon Sep 17 00:00:00 2001
From: David Sterba <dsterba@suse.cz>
Date: Tue, 9 Jul 2013 18:38:29 +0200
Subject: [PATCH 51/62] btrfs-progs: Fix getopt on arm/ppc platforms
(same as commit bb0eabc383e9a3fde7cdb02591ca88243f3e31fb)
There, 'char' is unsigned, so once assigned '-1' from getopt, it gets
the value 255. Then, it compared to '-1' gives false.
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
---
btrfs-crc.c | 2 +-
cmds-device.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/btrfs-crc.c b/btrfs-crc.c
index e4cda4312700..1990534ad4d2 100644
--- a/btrfs-crc.c
+++ b/btrfs-crc.c
@@ -34,7 +34,7 @@ void usage(void)
int main(int argc, char **argv)
{
- char c;
+ int c;
unsigned long checksum = 0;
char *str;
char *buf;
diff --git a/cmds-device.c b/cmds-device.c
index 41e79d375ce4..9e7328b20a55 100644
--- a/cmds-device.c
+++ b/cmds-device.c
@@ -294,7 +294,7 @@ static int cmd_dev_stats(int argc, char **argv)
int ret;
int fdmnt;
int i;
- char c;
+ int c;
int err = 0;
__u64 flags = 0;
--
1.8.3.1

View File

@ -1,38 +0,0 @@
From 2fdbfac178348ec229db866bccec8dd0f23738ab Mon Sep 17 00:00:00 2001
From: Michal Marek <mmarek@suse.cz>
Date: Tue, 9 Jul 2013 18:38:46 +0200
Subject: [PATCH 52/62] btrfs-progs: fix duplicate __[su]* typedefs on ppc64
The <ext2fs/ext2_types.h> header does attempt to avoid conflicts with
<linux/types.h>, but on ppc64, <asm-generic/int-ll64.h> gets somehow
included by other headers.
Include <linux/types.h> explicitly, so that <ext2fs/ext2_types.h>
notices it. The proper fix would be to fix <ext2fs/ext2_types.h> to not
use its own typedefs.
Originally observed in btrfs-convert, put the include into kerncompat.h
to avoid future problems.
Signed-off-by: Michal Marek <mmarek@suse.cz>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
---
kerncompat.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/kerncompat.h b/kerncompat.h
index 9c116b4fe841..6584818d0af3 100644
--- a/kerncompat.h
+++ b/kerncompat.h
@@ -26,6 +26,7 @@
#include <endian.h>
#include <byteswap.h>
#include <assert.h>
+#include <linux/types.h>
#ifndef READ
#define READ 0
--
1.8.3.1

View File

@ -1,61 +0,0 @@
From 2fac6f99128560c5993a02d2de0cc3d8238f3b51 Mon Sep 17 00:00:00 2001
From: David Sterba <dsterba@suse.cz>
Date: Tue, 9 Jul 2013 18:39:24 +0200
Subject: [PATCH 53/62] btrfs-progs: use reentrant localtime
localtime may return NULL (when an error is detected eg. after setting
tzname), followed by a segfault when the values is about to be used.
localtime_r works, does not set tzname and does not return NULL.
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
---
btrfs-list.c | 10 ++++++----
cmds-subvolume.c | 10 ++++++----
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/btrfs-list.c b/btrfs-list.c
index 4fab85882165..ea80bfeef2f1 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1337,10 +1337,12 @@ static void print_subvolume_column(struct root_info *subv,
printf("%llu", subv->top_id);
break;
case BTRFS_LIST_OTIME:
- if (subv->otime)
- strftime(tstr, 256, "%Y-%m-%d %X",
- localtime(&subv->otime));
- else
+ if (subv->otime) {
+ struct tm tm;
+
+ localtime_r(&subv->otime, &tm);
+ strftime(tstr, 256, "%Y-%m-%d %X", &tm);
+ } else
strcpy(tstr, "-");
printf("%s", tstr);
break;
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index ccb476274240..faf05cab2ad9 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -898,10 +898,12 @@ static int cmd_subvol_show(int argc, char **argv)
uuid_unparse(get_ri.puuid, uuidparse);
printf("\tParent uuid: \t\t%s\n", uuidparse);
- if (get_ri.otime)
- strftime(tstr, 256, "%Y-%m-%d %X",
- localtime(&get_ri.otime));
- else
+ if (get_ri.otime) {
+ struct tm tm;
+
+ localtime_r(&get_ri.otime, &tm);
+ strftime(tstr, 256, "%Y-%m-%d %X", &tm);
+ } else
strcpy(tstr, "-");
printf("\tCreation time: \t\t%s\n", tstr);
--
1.8.3.1

View File

@ -1,36 +0,0 @@
From 3b167f3ea4e8b8ea292326924653d8862114626e Mon Sep 17 00:00:00 2001
From: Anand Jain <anand.jain@oracle.com>
Date: Fri, 26 Jul 2013 01:35:30 +0800
Subject: [PATCH 54/62] btrfs-progs: don't have to report ENOMEDIUM error
during open
when we scan /proc/partitions the cdrom is scanned
as well, and we don't have to report ENOMEDIUM errors
against it.
Signed-off-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
---
utils.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/utils.c b/utils.c
index be0bfd5ecac2..6c1a96f2032f 100644
--- a/utils.c
+++ b/utils.c
@@ -1414,8 +1414,9 @@ scan_again:
fd = open(fullpath, O_RDONLY);
if (fd < 0) {
- fprintf(stderr, "failed to open %s: %s\n",
- fullpath, strerror(errno));
+ if (errno != ENOMEDIUM)
+ fprintf(stderr, "failed to open %s: %s\n",
+ fullpath, strerror(errno));
continue;
}
ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices,
--
1.8.3.1

View File

@ -1,94 +0,0 @@
From d74078b9e01ad6eab5ba4d951917c29a70e7be18 Mon Sep 17 00:00:00 2001
From: Jan Schmidt <list.btrfs@jan-o-sch.net>
Date: Mon, 6 May 2013 21:15:18 +0200
Subject: [PATCH 55/62] Btrfs-progs: added "btrfs quota rescan" -w switch
(wait)
With -w one can wait for a rescan operation to finish. It can be used when
starting a rescan operation or later to wait for the currently running
rescan operation to finish. Waiting is interruptible.
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
---
cmds-quota.c | 19 +++++++++++++++++--
ioctl.h | 1 +
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/cmds-quota.c b/cmds-quota.c
index 2e2971a41df7..af98d6e71570 100644
--- a/cmds-quota.c
+++ b/cmds-quota.c
@@ -93,10 +93,11 @@ static int cmd_quota_disable(int argc, char **argv)
}
static const char * const cmd_quota_rescan_usage[] = {
- "btrfs quota rescan [-s] <path>",
+ "btrfs quota rescan [-sw] <path>",
"Trash all qgroup numbers and scan the metadata again with the current config.",
"",
"-s show status of a running rescan operation",
+ "-w wait for rescan operation to finish (can be already in progress)",
NULL
};
@@ -108,21 +109,30 @@ static int cmd_quota_rescan(int argc, char **argv)
char *path = NULL;
struct btrfs_ioctl_quota_rescan_args args;
int ioctlnum = BTRFS_IOC_QUOTA_RESCAN;
+ int wait_for_completion = 0;
optind = 1;
while (1) {
- int c = getopt(argc, argv, "s");
+ int c = getopt(argc, argv, "sw");
if (c < 0)
break;
switch (c) {
case 's':
ioctlnum = BTRFS_IOC_QUOTA_RESCAN_STATUS;
break;
+ case 'w':
+ wait_for_completion = 1;
+ break;
default:
usage(cmd_quota_rescan_usage);
}
}
+ if (ioctlnum != BTRFS_IOC_QUOTA_RESCAN && wait_for_completion) {
+ fprintf(stderr, "ERROR: -w cannot be used with -s\n");
+ return 12;
+ }
+
if (check_argc_exact(argc - optind, 1))
usage(cmd_quota_rescan_usage);
@@ -137,6 +147,11 @@ static int cmd_quota_rescan(int argc, char **argv)
ret = ioctl(fd, ioctlnum, &args);
e = errno;
+
+ if (wait_for_completion && (ret == 0 || e == EINPROGRESS)) {
+ ret = ioctl(fd, BTRFS_IOC_QUOTA_RESCAN_WAIT, &args);
+ e = errno;
+ }
close(fd);
if (ioctlnum == BTRFS_IOC_QUOTA_RESCAN) {
diff --git a/ioctl.h b/ioctl.h
index abe6dd4234d9..c260bbf6b4bb 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -529,6 +529,7 @@ struct btrfs_ioctl_clone_range_args {
struct btrfs_ioctl_quota_rescan_args)
#define BTRFS_IOC_QUOTA_RESCAN_STATUS _IOR(BTRFS_IOCTL_MAGIC, 45, \
struct btrfs_ioctl_quota_rescan_args)
+#define BTRFS_IOC_QUOTA_RESCAN_WAIT _IO(BTRFS_IOCTL_MAGIC, 46)
#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \
char[BTRFS_LABEL_SIZE])
#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, \
--
1.8.3.1

View File

@ -1,36 +0,0 @@
From 85a8cc9ecfb9b61c5feaaf3ba861f27a2501691d Mon Sep 17 00:00:00 2001
From: Zach Brown <zab@redhat.com>
Date: Wed, 14 Aug 2013 16:16:40 -0700
Subject: [PATCH 56/62] btrfs-progs: fix qgroup realloc inheritance
qgroup.c:82:23: warning: memcpy with byte count of 0
qgroup.c:83:23: warning: memcpy with byte count of 0
The inheritance wasn't copying qgroups[] because a confused sizeof()
gave 0 byte memcpy()s. It's been like this for the year since it was
merged, so I guess this isn't a very important thing to do :).
Signed-off-by: Zach Brown <zab@redhat.com>
Reviewed-by: Arne Jansen <sensille@gmx.net>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
---
qgroup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qgroup.c b/qgroup.c
index dafde12becf6..e860b309e77c 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -74,7 +74,7 @@ int qgroup_inherit_realloc(struct btrfs_qgroup_inherit **inherit, int n,
if (*inherit) {
struct btrfs_qgroup_inherit *i = *inherit;
- int s = sizeof(out->qgroups);
+ int s = sizeof(out->qgroups[0]);
out->num_qgroups = i->num_qgroups;
out->num_ref_copies = i->num_ref_copies;
--
1.8.3.1

View File

@ -1,111 +0,0 @@
From 18d8ff57c3cd9ee31829b19fcd6ca57ed201720a Mon Sep 17 00:00:00 2001
From: Filipe David Borba Manana <fdmanana@gmail.com>
Date: Tue, 3 Sep 2013 12:19:58 +0100
Subject: [PATCH 57/62] Btrfs-progs: fix restore command leaving corrupted
files
When there are files that have parts shared with snapshots, the
restore command was incorrectly restoring them, as it was not
taking into account the offset and number of bytes fields from
the file extent item. Besides leaving the recovered file corrupt,
it was also inneficient as it read and wrote more data than needed
(with each extent copy overwriting portions of the one previously
written).
The following steps show how to reproduce this corruption issue:
$ mkfs.btrfs -f /dev/sdb3
$ mount /dev/sdb3 /mnt/btrfs
$ perl -e '$d = "\x41" . ("\x00" x (1024*1024+349)); open($f,">","/mnt/btrfs/foobar"); print $f $d; close($f);'
$ du -b /mnt/btrfs/foobar
1048926 /mnt/btrfs/foobar
$ md5sum /mnt/btrfs/foobar
f9f778f3a7410c40e4ed104a3a63c3c4 /mnt/btrfs/foobar
$ btrfs subvolume snapshot /mnt/btrfs /mnt/btrfs/my_snap
$ perl -e 'open($f, "+<", "/mnt/btrfs/foobar"); seek($f, 4096, 0); print $f "\xff"; close($f);'
$ md5sum /mnt/btrfs/foobar
b983fcefd4622a03a78936484c40272b /mnt/btrfs/foobar
$ umount /mnt/btrfs
$ btrfs restore /dev/sdb3 /tmp/copy
$ du -b /tmp/copy/foobar
1048926 /tmp/copy/foobar
$ md5sum /tmp/copy/foobar
88db338cbc1c44dfabae083f1ce642d5 /tmp/copy/foobar
$ od -t x1 -j 8192 -N 4 /tmp/copy/foobar
0020000 41 00 00 00
0020004
$ mount /dev/sdb3 /mnt/btrfs
$ od -t x1 -j 8192 -N 4 /mnt/btrfs/foobar
0020000 00 00 00 00
0020004
$ md5sum /mnt/btrfs/foobar
b983fcefd4622a03a78936484c40272b /mnt/btrfs/foobar
Tested this change with zlib, lzo compression and file sizes larger
than 1GiB, and found no regression or other corruption issues (so far
at least).
Signed-off-by: Filipe David Borba Manana <fdmanana@gmail.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
---
cmds-restore.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/cmds-restore.c b/cmds-restore.c
index e48df40320f6..9688599742d9 100644
--- a/cmds-restore.c
+++ b/cmds-restore.c
@@ -272,6 +272,7 @@ static int copy_one_extent(struct btrfs_root *root, int fd,
u64 bytenr;
u64 ram_size;
u64 disk_size;
+ u64 num_bytes;
u64 length;
u64 size_left;
u64 dev_bytenr;
@@ -288,7 +289,9 @@ static int copy_one_extent(struct btrfs_root *root, int fd,
disk_size = btrfs_file_extent_disk_num_bytes(leaf, fi);
ram_size = btrfs_file_extent_ram_bytes(leaf, fi);
offset = btrfs_file_extent_offset(leaf, fi);
- size_left = disk_size;
+ num_bytes = btrfs_file_extent_num_bytes(leaf, fi);
+ size_left = num_bytes;
+ bytenr += offset;
if (offset)
printf("offset is %Lu\n", offset);
@@ -296,7 +299,7 @@ static int copy_one_extent(struct btrfs_root *root, int fd,
if (disk_size == 0)
return 0;
- inbuf = malloc(disk_size);
+ inbuf = malloc(size_left);
if (!inbuf) {
fprintf(stderr, "No memory\n");
return -1;
@@ -351,8 +354,8 @@ again:
goto again;
if (compress == BTRFS_COMPRESS_NONE) {
- while (total < ram_size) {
- done = pwrite(fd, inbuf+total, ram_size-total,
+ while (total < num_bytes) {
+ done = pwrite(fd, inbuf+total, num_bytes-total,
pos+total);
if (done < 0) {
ret = -1;
@@ -365,7 +368,7 @@ again:
goto out;
}
- ret = decompress(inbuf, outbuf, disk_size, &ram_size, compress);
+ ret = decompress(inbuf, outbuf, num_bytes, &ram_size, compress);
if (ret) {
num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
bytenr, length);
--
1.8.3.1

View File

@ -1,253 +0,0 @@
From 6620f2caf5b50c28737eff1b522c22c153f9b1fa Mon Sep 17 00:00:00 2001
From: Anand Jain <anand.jain@oracle.com>
Date: Wed, 7 Aug 2013 20:11:25 +0800
Subject: [PATCH 58/62] btrfs-progs: avoid write to the disk before sure to
create fs
This patch provides fix for the following bug,
When mkfs.btrfs fails the disks shouldn't be written.
------------
btrfs fi show /dev/sdb
Label: none uuid: 60fb76f4-3b4d-4632-a7da-6a44dea5573d
Total devices 1 FS bytes used 24.00KiB
devid 1 size 2.00GiB used 20.00MiB path /dev/sdb
mkfs.btrfs -dsingle -mraid1 /dev/sdb -f
::
unable to create FS with metadata profile 16 (have 1 devices)
btrfs fi show /dev/sdb
Label: none uuid: 2da2179d-ecb1-4a4e-a44d-e7613a08c18d
Total devices 1 FS bytes used 24.00KiB
devid 1 size 2.00GiB used 20.00MiB path /dev/sdb
-------------
Signed-off-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
---
mkfs.c | 104 +++++++++++++++++++++++++---------------------------------------
utils.c | 41 +++++++++++++++++++++++++
utils.h | 2 ++
3 files changed, 84 insertions(+), 63 deletions(-)
diff --git a/mkfs.c b/mkfs.c
index 26be20df90d9..8a68f8a9f762 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -195,83 +195,28 @@ static int create_raid_groups(struct btrfs_trans_handle *trans,
int metadata_profile_opt, int mixed, int ssd)
{
u64 num_devices = btrfs_super_num_devices(root->fs_info->super_copy);
- u64 allowed = 0;
- u64 devices_for_raid = num_devices;
int ret;
- /*
- * Set default profiles according to number of added devices.
- * For mixed groups defaults are single/single.
- */
- if (!metadata_profile_opt && !mixed) {
- if (num_devices == 1 && ssd)
- printf("Detected a SSD, turning off metadata "
- "duplication. Mkfs with -m dup if you want to "
- "force metadata duplication.\n");
- metadata_profile = (num_devices > 1) ?
- BTRFS_BLOCK_GROUP_RAID1 : (ssd) ? 0: BTRFS_BLOCK_GROUP_DUP;
- }
- if (!data_profile_opt && !mixed) {
- data_profile = (num_devices > 1) ?
- BTRFS_BLOCK_GROUP_RAID0 : 0; /* raid0 or single */
- }
-
- if (devices_for_raid > 4)
- devices_for_raid = 4;
-
- switch (devices_for_raid) {
- default:
- case 4:
- allowed |= BTRFS_BLOCK_GROUP_RAID10;
- case 3:
- allowed |= BTRFS_BLOCK_GROUP_RAID6;
- case 2:
- allowed |= BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 |
- BTRFS_BLOCK_GROUP_RAID5;
- break;
- case 1:
- allowed |= BTRFS_BLOCK_GROUP_DUP;
- }
-
- if (metadata_profile & ~allowed) {
- fprintf(stderr, "unable to create FS with metadata "
- "profile %llu (have %llu devices)\n", metadata_profile,
- num_devices);
- exit(1);
- }
- if (data_profile & ~allowed) {
- fprintf(stderr, "unable to create FS with data "
- "profile %llu (have %llu devices)\n", data_profile,
- num_devices);
- exit(1);
- }
-
- /* allow dup'ed data chunks only in mixed mode */
- if (!mixed && (data_profile & BTRFS_BLOCK_GROUP_DUP)) {
- fprintf(stderr, "dup for data is allowed only in mixed mode\n");
- exit(1);
- }
-
- if (allowed & metadata_profile) {
+ if (metadata_profile) {
u64 meta_flags = BTRFS_BLOCK_GROUP_METADATA;
ret = create_one_raid_group(trans, root,
BTRFS_BLOCK_GROUP_SYSTEM |
- (allowed & metadata_profile));
+ metadata_profile);
BUG_ON(ret);
if (mixed)
meta_flags |= BTRFS_BLOCK_GROUP_DATA;
ret = create_one_raid_group(trans, root, meta_flags |
- (allowed & metadata_profile));
+ metadata_profile);
BUG_ON(ret);
}
- if (!mixed && num_devices > 1 && (allowed & data_profile)) {
+ if (!mixed && num_devices > 1 && data_profile) {
ret = create_one_raid_group(trans, root,
BTRFS_BLOCK_GROUP_DATA |
- (allowed & data_profile));
+ data_profile);
BUG_ON(ret);
}
recow_roots(trans, root);
@@ -1362,14 +1307,48 @@ int main(int ac, char **av)
}
}
- /* if we are here that means all devs are good to btrfsify */
optind = saved_optind;
dev_cnt = ac - optind;
+ file = av[optind++];
+ ssd = is_ssd(file);
+
+ /*
+ * Set default profiles according to number of added devices.
+ * For mixed groups defaults are single/single.
+ */
+ if (!mixed) {
+ if (!metadata_profile_opt) {
+ if (dev_cnt == 1 && ssd)
+ printf("Detected a SSD, turning off metadata "
+ "duplication. Mkfs with -m dup if you want to "
+ "force metadata duplication.\n");
+
+ metadata_profile = (dev_cnt > 1) ?
+ BTRFS_BLOCK_GROUP_RAID1 : (ssd) ?
+ 0: BTRFS_BLOCK_GROUP_DUP;
+ }
+ if (!data_profile_opt) {
+ data_profile = (dev_cnt > 1) ?
+ BTRFS_BLOCK_GROUP_RAID0 : 0; /* raid0 or single */
+ }
+ } else {
+ /* this is not needed but just for completeness */
+ metadata_profile = 0;
+ data_profile = 0;
+ }
+
+ ret = test_num_disk_vs_raid(metadata_profile, data_profile,
+ dev_cnt, mixed, estr);
+ if (ret) {
+ fprintf(stderr, "Error: %s\n", estr);
+ exit(1);
+ }
+
+ /* if we are here that means all devs are good to btrfsify */
printf("\nWARNING! - %s IS EXPERIMENTAL\n", BTRFS_BUILD_VERSION);
printf("WARNING! - see http://btrfs.wiki.kernel.org before using\n\n");
- file = av[optind++];
dev_cnt--;
if (!source_dir_set) {
@@ -1412,7 +1391,6 @@ int main(int ac, char **av)
dev_block_count = block_count;
}
- ssd = is_ssd(file);
if (mixed) {
if (metadata_profile != data_profile) {
diff --git a/utils.c b/utils.c
index 6c1a96f2032f..b2c6a06ffaa5 100644
--- a/utils.c
+++ b/utils.c
@@ -1766,6 +1766,47 @@ out:
return ret;
}
+int test_num_disk_vs_raid(u64 metadata_profile, u64 data_profile,
+ u64 dev_cnt, int mixed, char *estr)
+{
+ size_t sz = 100;
+ u64 allowed = 0;
+
+ switch (dev_cnt) {
+ default:
+ case 4:
+ allowed |= BTRFS_BLOCK_GROUP_RAID10;
+ case 3:
+ allowed |= BTRFS_BLOCK_GROUP_RAID6;
+ case 2:
+ allowed |= BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 |
+ BTRFS_BLOCK_GROUP_RAID5;
+ break;
+ case 1:
+ allowed |= BTRFS_BLOCK_GROUP_DUP;
+ }
+
+ if (metadata_profile & ~allowed) {
+ snprintf(estr, sz, "unable to create FS with metadata "
+ "profile %llu (have %llu devices)\n",
+ metadata_profile, dev_cnt);
+ return 1;
+ }
+ if (data_profile & ~allowed) {
+ snprintf(estr, sz, "unable to create FS with data "
+ "profile %llu (have %llu devices)\n",
+ metadata_profile, dev_cnt);
+ return 1;
+ }
+
+ if (!mixed && (data_profile & BTRFS_BLOCK_GROUP_DUP)) {
+ snprintf(estr, sz,
+ "dup for data is allowed only in mixed mode");
+ return 1;
+ }
+ return 0;
+}
+
/* Check if disk is suitable for btrfs
* returns:
* 1: something is wrong, estr provides the error
diff --git a/utils.h b/utils.h
index 3c17e14b79cd..720601723413 100644
--- a/utils.h
+++ b/utils.h
@@ -65,5 +65,7 @@ u64 btrfs_device_size(int fd, struct stat *st);
/* Helper to always get proper size of the destination string */
#define strncpy_null(dest, src) __strncpy__null(dest, src, sizeof(dest))
int test_dev_for_mkfs(char *file, int force_overwrite, char *estr);
+int test_num_disk_vs_raid(u64 metadata_profile, u64 data_profile,
+ u64 dev_cnt, int mixed, char *estr);
#endif
--
1.8.3.1

View File

@ -1,46 +0,0 @@
From 684d9a33f77967a9b50b597cece1b2b2e29d2b8d Mon Sep 17 00:00:00 2001
From: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Date: Thu, 5 Sep 2013 15:53:34 +0900
Subject: [PATCH 59/62] btrfs-progs: error if device for mkfs is too small
Eric pointed out that mkfs abort if specified volume is too small:
# truncate --size=2m testfile
# ./mkfs.btrfs testfile
:
SMALL VOLUME: forcing mixed metadata/data groups
mkfs.btrfs: volumes.c:852: btrfs_alloc_chunk: Assertion `!(ret)' failed.
Aborted (core dumped)
As the first step to fix problems around there, let mkfs to report
error if the size of target volume is less than the size of the first
system block group, BTRFS_MKFS_SYSTEM_GROUP_SIZE (= 4MB).
Reported-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
---
mkfs.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/mkfs.c b/mkfs.c
index 8a68f8a9f762..9a017c1dc95b 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -1400,6 +1400,12 @@ int main(int ac, char **av)
}
}
+ /* To create the first block group and chunk 0 in make_btrfs */
+ if (dev_block_count < BTRFS_MKFS_SYSTEM_GROUP_SIZE) {
+ fprintf(stderr, "device is too small to make filesystem\n");
+ exit(1);
+ }
+
blocks[0] = BTRFS_SUPER_INFO_OFFSET;
for (i = 1; i < 7; i++) {
blocks[i] = BTRFS_SUPER_INFO_OFFSET + 1024 * 1024 +
--
1.8.3.1

View File

@ -1,91 +0,0 @@
From b11f9613e3b0be7e4b560419a4fec7d7d7264664 Mon Sep 17 00:00:00 2001
From: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Date: Thu, 5 Sep 2013 15:55:08 +0900
Subject: [PATCH 60/62] btrfs-progs: error if device have no space to make
primary chunks
The previous patch works fine if the size of specified volume to mkfs
is less than 4MB. However usually btrfs requires more than 4MB to work,
and the minimum preferred size is depending on the raid setting etc.
This patch let mkfs print error message if it cannot allocate one of
chunks should be there at first.
[before]
# truncate --size=4500K testfile
# ./mkfs.btrfs -f testfile
:
SMALL VOLUME: forcing mixed metadata/data groups
mkfs.btrfs: mkfs.c:84: make_root_dir: Assertion `!(ret)' failed.
Aborted (core dumped)
[After]
# truncate --size=4500K testfile
# ./mkfs.btrfs -f testfile
:
SMALL VOLUME: forcing mixed metadata/data groups
no space to alloc data/metadata chunk
failed to setup the root directory
TBD is calculate minimum size for setting and put it in the error
message to let user know how large amount of volume is required.
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
---
mkfs.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/mkfs.c b/mkfs.c
index 9a017c1dc95b..f7105073a173 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -81,6 +81,11 @@ static int make_root_dir(struct btrfs_root *root, int mixed)
&chunk_start, &chunk_size,
BTRFS_BLOCK_GROUP_METADATA |
BTRFS_BLOCK_GROUP_DATA);
+ if (ret == -ENOSPC) {
+ fprintf(stderr,
+ "no space to alloc data/metadata chunk\n");
+ goto err;
+ }
BUG_ON(ret);
ret = btrfs_make_block_group(trans, root, 0,
BTRFS_BLOCK_GROUP_METADATA |
@@ -93,6 +98,10 @@ static int make_root_dir(struct btrfs_root *root, int mixed)
ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
&chunk_start, &chunk_size,
BTRFS_BLOCK_GROUP_METADATA);
+ if (ret == -ENOSPC) {
+ fprintf(stderr, "no space to alloc metadata chunk\n");
+ goto err;
+ }
BUG_ON(ret);
ret = btrfs_make_block_group(trans, root, 0,
BTRFS_BLOCK_GROUP_METADATA,
@@ -110,6 +119,10 @@ static int make_root_dir(struct btrfs_root *root, int mixed)
ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
&chunk_start, &chunk_size,
BTRFS_BLOCK_GROUP_DATA);
+ if (ret == -ENOSPC) {
+ fprintf(stderr, "no space to alloc data chunk\n");
+ goto err;
+ }
BUG_ON(ret);
ret = btrfs_make_block_group(trans, root, 0,
BTRFS_BLOCK_GROUP_DATA,
@@ -181,6 +194,10 @@ static int create_one_raid_group(struct btrfs_trans_handle *trans,
ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
&chunk_start, &chunk_size, type);
+ if (ret == -ENOSPC) {
+ fprintf(stderr, "not enough free space\n");
+ exit(1);
+ }
BUG_ON(ret);
ret = btrfs_make_block_group(trans, root->fs_info->extent_root, 0,
type, BTRFS_FIRST_CHUNK_TREE_OBJECTID,
--
1.8.3.1

View File

@ -1,233 +0,0 @@
From db3c0b4f365acb5ee9fa7e37d440b2ef6ff5636c Mon Sep 17 00:00:00 2001
From: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Date: Thu, 5 Sep 2013 15:57:19 +0900
Subject: [PATCH 61/62] btrfs-progs: calculate available blocks on device
properly
I found that mkfs.btrfs aborts when assigned multi volumes contain
a small volume:
# parted /dev/sdf p
Model: LSI MegaRAID SAS RMB (scsi)
Disk /dev/sdf: 72.8GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 32.3kB 72.4GB 72.4GB primary
2 72.4GB 72.8GB 461MB primary
# ./mkfs.btrfs -f /dev/sdf1 /dev/sdf2
:
SMALL VOLUME: forcing mixed metadata/data groups
adding device /dev/sdf2 id 2
mkfs.btrfs: volumes.c:852: btrfs_alloc_chunk: Assertion `!(ret)' failed.
Aborted (core dumped)
This failure of btrfs_alloc_chunk was caused by following steps:
1) since there is only small space in the small device, mkfs was
going to allocate a chunk from free space as much as available.
So mkfs called btrfs_alloc_chunk with
size = device->total_bytes - device->used_bytes.
2) (According to the comment in source code, to avoid overwriting
superblock,) btrfs_alloc_chunk starts taking chunks at an offset
of 1MB. It means that the layout of a disk will be like:
[[1MB at beginning for sb][allocated chunks]* ... free space ... ]
and you can see that the available free space for allocation is:
avail = device->total_bytes - device->used_bytes - 1MB.
3) Therefore there is only free space 1MB less than requested. damn.
>From further investigations I also found that this issue is easily
reproduced by using -A, --alloc-start option:
# truncate --size=1G testfile
# ./mkfs.btrfs -A900M -f testfile
:
mkfs.btrfs: volumes.c:852: btrfs_alloc_chunk: Assertion `!(ret)' failed.
Aborted (core dumped)
In this case there is only 100MB for allocation but btrfs_alloc_chunk
was going to allocate more than the 100MB.
The root cause of both of above troubles is a same simple bug:
btrfs_chunk_alloc does not calculate available bytes properly even
though it researches how many devices have enough room to have a
chunk to be allocated.
So this patch introduces new function btrfs_device_avail_bytes()
which returns available bytes for allocation in specified device.
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
---
ctree.h | 8 +++++
volumes.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 106 insertions(+), 6 deletions(-)
diff --git a/ctree.h b/ctree.h
index 0b0d701fe679..90be7abe9ebf 100644
--- a/ctree.h
+++ b/ctree.h
@@ -811,6 +811,14 @@ struct btrfs_csum_item {
u8 csum;
} __attribute__ ((__packed__));
+/*
+ * We don't want to overwrite 1M at the beginning of device, even though
+ * there is our 1st superblock at 64k. Some possible reasons:
+ * - the first 64k blank is useful for some boot loader/manager
+ * - the first 1M could be scratched by buggy partitioner or somesuch
+ */
+#define BTRFS_BLOCK_RESERVED_1M_FOR_SUPER ((u64)1024 * 1024)
+
/* tag for the radix tree of block groups in ram */
#define BTRFS_BLOCK_GROUP_DATA (1ULL << 0)
#define BTRFS_BLOCK_GROUP_SYSTEM (1ULL << 1)
diff --git a/volumes.c b/volumes.c
index 0ff22833d6be..e8d7f258dddb 100644
--- a/volumes.c
+++ b/volumes.c
@@ -268,7 +268,7 @@ static int find_free_dev_extent(struct btrfs_trans_handle *trans,
struct btrfs_dev_extent *dev_extent = NULL;
u64 hole_size = 0;
u64 last_byte = 0;
- u64 search_start = 0;
+ u64 search_start = root->fs_info->alloc_start;
u64 search_end = device->total_bytes;
int ret;
int slot = 0;
@@ -283,10 +283,12 @@ static int find_free_dev_extent(struct btrfs_trans_handle *trans,
/* we don't want to overwrite the superblock on the drive,
* so we make sure to start at an offset of at least 1MB
*/
- search_start = max((u64)1024 * 1024, search_start);
+ search_start = max(BTRFS_BLOCK_RESERVED_1M_FOR_SUPER, search_start);
- if (root->fs_info->alloc_start + num_bytes <= device->total_bytes)
- search_start = max(root->fs_info->alloc_start, search_start);
+ if (search_start >= search_end) {
+ ret = -ENOSPC;
+ goto error;
+ }
key.objectid = device->devid;
key.offset = search_start;
@@ -660,6 +662,94 @@ static u32 find_raid56_stripe_len(u32 data_devices, u32 dev_stripe_target)
return 64 * 1024;
}
+/*
+ * btrfs_device_avail_bytes - count bytes available for alloc_chunk
+ *
+ * It is not equal to "device->total_bytes - device->bytes_used".
+ * We do not allocate any chunk in 1M at beginning of device, and not
+ * allowed to allocate any chunk before alloc_start if it is specified.
+ * So search holes from max(1M, alloc_start) to device->total_bytes.
+ */
+static int btrfs_device_avail_bytes(struct btrfs_trans_handle *trans,
+ struct btrfs_device *device,
+ u64 *avail_bytes)
+{
+ struct btrfs_path *path;
+ struct btrfs_root *root = device->dev_root;
+ struct btrfs_key key;
+ struct btrfs_dev_extent *dev_extent = NULL;
+ struct extent_buffer *l;
+ u64 search_start = root->fs_info->alloc_start;
+ u64 search_end = device->total_bytes;
+ u64 extent_end = 0;
+ u64 free_bytes = 0;
+ int ret;
+ int slot = 0;
+
+ search_start = max(BTRFS_BLOCK_RESERVED_1M_FOR_SUPER, search_start);
+
+ path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
+
+ key.objectid = device->devid;
+ key.offset = root->fs_info->alloc_start;
+ key.type = BTRFS_DEV_EXTENT_KEY;
+
+ path->reada = 2;
+ ret = btrfs_search_slot(trans, root, &key, path, 0, 0);
+ if (ret < 0)
+ goto error;
+ ret = btrfs_previous_item(root, path, 0, key.type);
+ if (ret < 0)
+ goto error;
+
+ while (1) {
+ l = path->nodes[0];
+ slot = path->slots[0];
+ if (slot >= btrfs_header_nritems(l)) {
+ ret = btrfs_next_leaf(root, path);
+ if (ret == 0)
+ continue;
+ if (ret < 0)
+ goto error;
+ break;
+ }
+ btrfs_item_key_to_cpu(l, &key, slot);
+
+ if (key.objectid < device->devid)
+ goto next;
+ if (key.objectid > device->devid)
+ break;
+ if (btrfs_key_type(&key) != BTRFS_DEV_EXTENT_KEY)
+ goto next;
+ if (key.offset > search_end)
+ break;
+ if (key.offset > search_start)
+ free_bytes += key.offset - search_start;
+
+ dev_extent = btrfs_item_ptr(l, slot, struct btrfs_dev_extent);
+ extent_end = key.offset + btrfs_dev_extent_length(l,
+ dev_extent);
+ if (extent_end > search_start)
+ search_start = extent_end;
+ if (search_start > search_end)
+ break;
+next:
+ path->slots[0]++;
+ cond_resched();
+ }
+
+ if (search_start < search_end)
+ free_bytes += search_end - search_start;
+
+ *avail_bytes = free_bytes;
+ ret = 0;
+error:
+ btrfs_free_path(path);
+ return ret;
+}
+
int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
struct btrfs_root *extent_root, u64 *start,
u64 *num_bytes, u64 type)
@@ -678,7 +768,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
u64 calc_size = 8 * 1024 * 1024;
u64 min_free;
u64 max_chunk_size = 4 * calc_size;
- u64 avail;
+ u64 avail = 0;
u64 max_avail = 0;
u64 percent_max;
int num_stripes = 1;
@@ -782,7 +872,9 @@ again:
/* build a private list of devices we will allocate from */
while(index < num_stripes) {
device = list_entry(cur, struct btrfs_device, dev_list);
- avail = device->total_bytes - device->bytes_used;
+ ret = btrfs_device_avail_bytes(trans, device, &avail);
+ if (ret)
+ return ret;
cur = cur->next;
if (avail >= min_free) {
list_move_tail(&device->dev_list, &private_devs);
--
1.8.3.1

View File

@ -1,228 +0,0 @@
From 174273941f266c5ba71da02cc4d71a95ca41bc20 Mon Sep 17 00:00:00 2001
From: Josef Bacik <jbacik@fusionio.com>
Date: Tue, 1 Oct 2013 09:00:19 -0400
Subject: [PATCH 62/62] Btrfs-progs: keep track of transid failures and fix
them if possible
A user was reporting an issue with bad transid errors on his blocks. The thing
is that btrfs-progs will ignore transid failures for things like restore and
fsck so we can do a best effort to fix a users file system. So fsck can put
together a coherent view of the file system with stale blocks. So if everything
else is ok in the mind of fsck then we can recow these blocks to fix the
generation and the user can get their file system back. Thanks,
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
---
cmds-check.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ctree.c | 7 ++++++-
ctree.h | 1 +
disk-io.c | 15 +++++++++++++++
extent_io.c | 2 ++
extent_io.h | 2 ++
6 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/cmds-check.c b/cmds-check.c
index dbb41e5a4d5b..924aac08f350 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -5675,6 +5675,47 @@ static int reinit_extent_tree(struct btrfs_fs_info *fs_info)
return btrfs_commit_transaction(trans, fs_info->extent_root);
}
+static int recow_extent_buffer(struct btrfs_root *root, struct extent_buffer *eb)
+{
+ struct btrfs_path *path;
+ struct btrfs_trans_handle *trans;
+ struct btrfs_key key;
+ int ret;
+
+ printf("Recowing metadata block %llu\n", eb->start);
+ key.objectid = btrfs_header_owner(eb);
+ key.type = BTRFS_ROOT_ITEM_KEY;
+ key.offset = (u64)-1;
+
+ root = btrfs_read_fs_root(root->fs_info, &key);
+ if (IS_ERR(root)) {
+ fprintf(stderr, "Couldn't find owner root %llu\n",
+ key.objectid);
+ return PTR_ERR(root);
+ }
+
+ path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
+
+ trans = btrfs_start_transaction(root, 1);
+ if (IS_ERR(trans)) {
+ btrfs_free_path(path);
+ return PTR_ERR(trans);
+ }
+
+ path->lowest_level = btrfs_header_level(eb);
+ if (path->lowest_level)
+ btrfs_node_key_to_cpu(eb, &key, 0);
+ else
+ btrfs_item_key_to_cpu(eb, &key, 0);
+
+ ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
+ btrfs_commit_transaction(trans, root);
+ btrfs_free_path(path);
+ return ret;
+}
+
static struct option long_options[] = {
{ "super", 1, NULL, 's' },
{ "repair", 0, NULL, 0 },
@@ -5826,6 +5867,23 @@ int cmd_check(int argc, char **argv)
fprintf(stderr, "checking root refs\n");
ret = check_root_refs(root, &root_cache);
+ if (ret)
+ goto out;
+
+ while (repair && !list_empty(&root->fs_info->recow_ebs)) {
+ struct extent_buffer *eb;
+
+ eb = list_first_entry(&root->fs_info->recow_ebs,
+ struct extent_buffer, recow);
+ ret = recow_extent_buffer(root, eb);
+ if (ret)
+ break;
+ }
+
+ if (!list_empty(&root->fs_info->recow_ebs)) {
+ fprintf(stderr, "Transid errors in file system\n");
+ ret = 1;
+ }
out:
free_root_recs_tree(&root_cache);
close_ctree(root);
diff --git a/ctree.c b/ctree.c
index 1a4f3f06f38a..e7ccfa03fb0e 100644
--- a/ctree.c
+++ b/ctree.c
@@ -346,7 +346,8 @@ int __btrfs_cow_block(struct btrfs_trans_handle *trans,
(unsigned long)btrfs_header_fsid(cow),
BTRFS_FSID_SIZE);
- WARN_ON(btrfs_header_generation(buf) > trans->transid);
+ WARN_ON(!(buf->flags & EXTENT_BAD_TRANSID) &&
+ btrfs_header_generation(buf) > trans->transid);
update_ref_for_cow(trans, root, buf, cow);
@@ -370,6 +371,10 @@ int __btrfs_cow_block(struct btrfs_trans_handle *trans,
btrfs_free_extent(trans, root, buf->start, buf->len,
0, root->root_key.objectid, level, 1);
}
+ if (!list_empty(&buf->recow)) {
+ list_del_init(&buf->recow);
+ free_extent_buffer(buf);
+ }
free_extent_buffer(buf);
btrfs_mark_buffer_dirty(cow);
*cow_ret = cow;
diff --git a/ctree.h b/ctree.h
index 90be7abe9ebf..61cd93b91937 100644
--- a/ctree.h
+++ b/ctree.h
@@ -952,6 +952,7 @@ struct btrfs_fs_info {
struct btrfs_extent_ops *extent_ops;
struct list_head dirty_cowonly_roots;
+ struct list_head recow_ebs;
struct btrfs_fs_devices *fs_devices;
struct list_head space_info;
diff --git a/disk-io.c b/disk-io.c
index 1b91de6fc90d..d97ff8c706c9 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -180,6 +180,7 @@ static int verify_parent_transid(struct extent_io_tree *io_tree,
(unsigned long long)parent_transid,
(unsigned long long)btrfs_header_generation(eb));
if (ignore) {
+ eb->flags |= EXTENT_BAD_TRANSID;
printk("Ignoring transid failure\n");
return 0;
}
@@ -274,6 +275,12 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
csum_tree_block(root, eb, 1) == 0 &&
verify_parent_transid(eb->tree, eb, parent_transid, ignore)
== 0) {
+ if (eb->flags & EXTENT_BAD_TRANSID &&
+ list_empty(&eb->recow)) {
+ list_add_tail(&eb->recow,
+ &root->fs_info->recow_ebs);
+ eb->refs++;
+ }
btrfs_set_buffer_uptodate(eb);
return eb;
}
@@ -748,6 +755,7 @@ struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr)
mutex_init(&fs_info->fs_mutex);
INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
INIT_LIST_HEAD(&fs_info->space_info);
+ INIT_LIST_HEAD(&fs_info->recow_ebs);
if (!writable)
fs_info->readonly = 1;
@@ -899,6 +907,13 @@ FREE_EXTENT_CACHE_BASED_TREE(mapping_cache, free_map_lookup);
void btrfs_cleanup_all_caches(struct btrfs_fs_info *fs_info)
{
+ while (!list_empty(&fs_info->recow_ebs)) {
+ struct extent_buffer *eb;
+ eb = list_first_entry(&fs_info->recow_ebs,
+ struct extent_buffer, recow);
+ list_del_init(&eb->recow);
+ free_extent_buffer(eb);
+ }
free_mapping_cache_tree(&fs_info->mapping_tree.cache_tree);
extent_io_tree_cleanup(&fs_info->extent_cache);
extent_io_tree_cleanup(&fs_info->free_space_cache);
diff --git a/extent_io.c b/extent_io.c
index 464bd07e8d1a..398ee26b4a79 100644
--- a/extent_io.c
+++ b/extent_io.c
@@ -585,6 +585,7 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree,
eb->dev_bytenr = (u64)-1;
eb->cache_node.start = bytenr;
eb->cache_node.size = blocksize;
+ INIT_LIST_HEAD(&eb->recow);
free_some_buffers(tree);
ret = insert_cache_extent(&tree->cache, &eb->cache_node);
@@ -608,6 +609,7 @@ void free_extent_buffer(struct extent_buffer *eb)
struct extent_io_tree *tree = eb->tree;
BUG_ON(eb->flags & EXTENT_DIRTY);
list_del_init(&eb->lru);
+ list_del_init(&eb->recow);
remove_cache_extent(&tree->cache, &eb->cache_node);
BUG_ON(tree->cache_size < eb->len);
tree->cache_size -= eb->len;
diff --git a/extent_io.h b/extent_io.h
index 2604dcef31e3..45080c2661ae 100644
--- a/extent_io.h
+++ b/extent_io.h
@@ -39,6 +39,7 @@
#define EXTENT_DEFRAG_DONE (1 << 7)
#define EXTENT_BUFFER_FILLED (1 << 8)
#define EXTENT_CSUM (1 << 9)
+#define EXTENT_BAD_TRANSID (1 << 10)
#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK)
#define BLOCK_GROUP_DATA EXTENT_WRITEBACK
@@ -72,6 +73,7 @@ struct extent_buffer {
u32 len;
struct extent_io_tree *tree;
struct list_head lru;
+ struct list_head recow;
int refs;
int flags;
int fd;
--
1.8.3.1

View File

@ -1,7 +1,7 @@
From be65fb331902152d9b571b2d4ee1bf26bedc795f Mon Sep 17 00:00:00 2001
From fa69bc83f210e7940adf1051709178e493f58002 Mon Sep 17 00:00:00 2001
From: David Sterba <dsterba@suse.cz>
Date: Thu, 27 Oct 2011 16:23:14 -0400
Subject: [PATCH 40/46] btrfs-progs: fix loop device mount checks
Subject: [PATCH 162/170] btrfs-progs: fix loop device mount checks
When creating a fs on a loop device, mkfs checks whether the same file
is not already mounted, but the backing file of another loop dev may not
@ -12,11 +12,11 @@ Signed-off-by: David Sterba <dsterba@suse.cz>
utils.c | 34 +++++++++++++++++++---------------
1 file changed, 19 insertions(+), 15 deletions(-)
diff --git a/utils.c b/utils.c
index 41bfdb0..47b31fc 100644
--- a/utils.c
+++ b/utils.c
@@ -773,11 +773,11 @@ int is_same_blk_file(const char* a, const char* b)
Index: btrfs-progs-v0.20-rc1-598-g8116550e1662/utils.c
===================================================================
--- btrfs-progs-v0.20-rc1-598-g8116550e1662.orig/utils.c
+++ btrfs-progs-v0.20-rc1-598-g8116550e1662/utils.c
@@ -831,11 +831,11 @@ static int is_same_blk_file(const char*
char real_a[PATH_MAX];
char real_b[PATH_MAX];
@ -33,7 +33,7 @@ index 41bfdb0..47b31fc 100644
/* Identical path? */
if(strcmp(real_a, real_b) == 0)
@@ -818,8 +818,8 @@ int is_same_loop_file(const char* a, const char* b)
@@ -876,8 +876,8 @@ static int is_same_loop_file(const char*
{
char res_a[PATH_MAX];
char res_b[PATH_MAX];
@ -44,7 +44,7 @@ index 41bfdb0..47b31fc 100644
int ret;
/* Resolve a if it is a loop device */
@@ -828,10 +828,12 @@ int is_same_loop_file(const char* a, const char* b)
@@ -886,10 +886,12 @@ static int is_same_loop_file(const char*
return 0;
return ret;
} else if (ret) {
@ -61,7 +61,7 @@ index 41bfdb0..47b31fc 100644
} else {
final_a = a;
}
@@ -842,10 +844,12 @@ int is_same_loop_file(const char* a, const char* b)
@@ -900,10 +902,12 @@ static int is_same_loop_file(const char*
return 0;
return ret;
} else if (ret) {
@ -78,6 +78,3 @@ index 41bfdb0..47b31fc 100644
} else {
final_b = b;
}
--
1.8.0.2

View File

@ -0,0 +1,26 @@
From f0294c7f1135acd58320c8282ed68a337138a7c7 Mon Sep 17 00:00:00 2001
From: David Sterba <dsterba@suse.cz>
Date: Mon, 30 Apr 2012 17:46:53 +0200
Subject: [PATCH 163/170] btrfs-progs: fsck: fix segfault
fix from Chris Mason via pastebin
Signed-off-by: David Sterba <dsterba@suse.cz>
---
cmds-check.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Index: btrfs-progs-v0.20-rc1-598-g8116550e1662/cmds-check.c
===================================================================
--- btrfs-progs-v0.20-rc1-598-g8116550e1662.orig/cmds-check.c
+++ btrfs-progs-v0.20-rc1-598-g8116550e1662/cmds-check.c
@@ -2209,7 +2209,8 @@ static int check_owner_ref(struct btrfs_
if (btrfs_header_owner(buf) == back->root)
return 0;
}
- BUG_ON(rec->is_root);
+ if (rec->is_root)
+ return 1;
/* try to find the block by search corresponding fs tree */
key.objectid = btrfs_header_owner(buf);

View File

@ -0,0 +1,105 @@
From f160d979c4f8d46a9d0a52394240d51b78237d89 Mon Sep 17 00:00:00 2001
From: David Sterba <dsterba@suse.cz>
Date: Tue, 31 Jan 2012 14:40:22 +0100
Subject: [PATCH 164/170] btrfs-progs: convert: set label or copy from origin
Signed-off-by: David Sterba <dsterba@suse.cz>
---
btrfs-convert.c | 47 ++++++++++++++++++++++++++++++++++++++---------
1 file changed, 38 insertions(+), 9 deletions(-)
Index: btrfs-progs-v0.20-rc1-598-g8116550e1662/btrfs-convert.c
===================================================================
--- btrfs-progs-v0.20-rc1-598-g8116550e1662.orig/btrfs-convert.c
+++ btrfs-progs-v0.20-rc1-598-g8116550e1662/btrfs-convert.c
@@ -2199,8 +2199,8 @@ err:
return ret;
}
-static int do_convert(const char *devname, int datacsum, int packing,
- int noxattr)
+static int do_convert(const char *devname, int datacsum, int packing, int noxattr,
+ int copylabel, const char *fslabel)
{
int i, ret;
int fd = -1;
@@ -2294,6 +2294,17 @@ static int do_convert(const char *devnam
fprintf(stderr, "error during create_ext2_image %d\n", ret);
goto fail;
}
+ memset(root->fs_info->super_copy->label, 0, BTRFS_LABEL_SIZE);
+ if (copylabel == 1) {
+ strncpy(root->fs_info->super_copy->label,
+ ext2_fs->super->s_volume_name, 16);
+ fprintf(stderr, "copy label '%s'\n",
+ root->fs_info->super_copy->label);
+ } else if (copylabel == -1) {
+ strncpy(root->fs_info->super_copy->label, fslabel, BTRFS_LABEL_SIZE);
+ fprintf(stderr, "set label to '%s'\n", fslabel);
+ }
+
printf("cleaning up system chunk.\n");
ret = cleanup_sys_chunk(root, ext2_root);
if (ret) {
@@ -2688,11 +2699,13 @@ fail:
static void print_usage(void)
{
- printf("usage: btrfs-convert [-d] [-i] [-n] [-r] device\n");
- printf("\t-d disable data checksum\n");
- printf("\t-i ignore xattrs and ACLs\n");
- printf("\t-n disable packing of small files\n");
- printf("\t-r roll back to ext2fs\n");
+ printf("usage: btrfs-convert [-d] [-i] [-n] [-r] [-l label] [-L] device\n");
+ printf("\t-d disable data checksum\n");
+ printf("\t-i ignore xattrs and ACLs\n");
+ printf("\t-n disable packing of small files\n");
+ printf("\t-r roll back to ext2fs\n");
+ printf("\t-l LABEL set filesystem label\n");
+ printf("\t-L use label from converted fs\n");
}
int main(int argc, char *argv[])
@@ -2702,9 +2715,12 @@ int main(int argc, char *argv[])
int noxattr = 0;
int datacsum = 1;
int rollback = 0;
+ int copylabel = 0;
char *file;
+ char *fslabel = NULL;
+
while(1) {
- int c = getopt(argc, argv, "dinr");
+ int c = getopt(argc, argv, "dinrl:L");
if (c < 0)
break;
switch(c) {
@@ -2720,6 +2736,19 @@ int main(int argc, char *argv[])
case 'r':
rollback = 1;
break;
+ case 'l':
+ copylabel = -1;
+ fslabel = strdup(optarg);
+ if (strlen(fslabel) > BTRFS_LABEL_SIZE) {
+ fprintf(stderr,
+ "warning: label too long, trimmed to %d bytes\n",
+ BTRFS_LABEL_SIZE);
+ fslabel[BTRFS_LABEL_SIZE]=0;
+ }
+ break;
+ case 'L':
+ copylabel = 1;
+ break;
default:
print_usage();
return 1;
@@ -2740,7 +2769,7 @@ int main(int argc, char *argv[])
if (rollback) {
ret = do_rollback(file, 0);
} else {
- ret = do_convert(file, datacsum, packing, noxattr);
+ ret = do_convert(file, datacsum, packing, noxattr, copylabel, fslabel);
}
if (ret)
return 1;

View File

@ -0,0 +1,49 @@
From 0c26634f696f3ced9636de0ca2fa5b7b9d732bc3 Mon Sep 17 00:00:00 2001
From: David Sterba <dsterba@suse.cz>
Date: Thu, 7 Feb 2013 18:00:23 +0100
Subject: [PATCH 165/170] Revert "btrfs-progs: update options in find-root.c"
This reverts commit 7f04a61b6da5a1231454b07e3e37cc24601a76e4.
Reintroduce the 'verbose' option.
Signed-off-by: David Sterba <dsterba@suse.cz>
---
btrfs-find-root.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
Index: btrfs-progs-v0.20-rc1-598-g8116550e1662/btrfs-find-root.c
===================================================================
--- btrfs-progs-v0.20-rc1-598-g8116550e1662.orig/btrfs-find-root.c
+++ btrfs-progs-v0.20-rc1-598-g8116550e1662/btrfs-find-root.c
@@ -35,6 +35,7 @@
#include "utils.h"
#include "crc32c.h"
+static int verbose = 0;
static u16 csum_size = 0;
static u64 search_objectid = BTRFS_ROOT_TREE_OBJECTID;
static u64 search_generation = 0;
@@ -42,7 +43,7 @@ static unsigned long search_level = 0;
static void usage(void)
{
- fprintf(stderr, "Usage: find-roots [-o search_objectid] "
+ fprintf(stderr, "Usage: find-roots [-v] "
"[ -g search_generation ] [ -l search_level ] <device>\n");
}
@@ -286,9 +287,12 @@ int main(int argc, char **argv)
int opt;
int ret;
- while ((opt = getopt(argc, argv, "l:o:g:")) != -1) {
+ while ((opt = getopt(argc, argv, "l:o:g:v")) != -1) {
switch(opt) {
errno = 0;
+ case 'v':
+ verbose++;
+ break;
case 'o':
search_objectid = (u64)strtoll(optarg, NULL,
10);

View File

@ -0,0 +1,47 @@
From 3d75a27a857ae81f7cd64de886a293208be15af6 Mon Sep 17 00:00:00 2001
From: Josef Bacik <josef@redhat.com>
Date: Wed, 4 Jan 2012 10:03:33 -0500
Subject: [PATCH 166/170] 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 <josef@redhat.com>
---
btrfs-find-root.c | 9 +++++++++
1 file changed, 9 insertions(+)
Index: btrfs-progs-v0.20-rc1-598-g8116550e1662/btrfs-find-root.c
===================================================================
--- btrfs-progs-v0.20-rc1-598-g8116550e1662.orig/btrfs-find-root.c
+++ btrfs-progs-v0.20-rc1-598-g8116550e1662/btrfs-find-root.c
@@ -229,6 +229,10 @@ static int find_root(struct btrfs_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;
@@ -239,6 +243,8 @@ static int find_root(struct btrfs_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);
@@ -247,6 +253,9 @@ static int find_root(struct btrfs_root *
break;
}
offset = metadata_offset;
+ if (verbose)
+ printf("Checking metadata chunk %Lu, size %Lu"
+ "\n", metadata_offset, metadata_size);
}
err = __btrfs_map_block(&root->fs_info->mapping_tree, READ,
offset, &map_length, &type,

View File

@ -0,0 +1,25 @@
From cc4992b4c3610de4b30ea6a168573841e6cd43e5 Mon Sep 17 00:00:00 2001
From: Josef Bacik <josef@redhat.com>
Date: Wed, 7 Dec 2011 16:11:23 -0500
Subject: [PATCH 167/170] Btrfs-progs: make find_and_setup_root return an error
Don't BUG(), return an error so the recovery program can work its mojo.
Signed-off-by: Josef Bacik <josef@redhat.com>
---
disk-io.c | 2 ++
1 file changed, 2 insertions(+)
Index: btrfs-progs-v0.20-rc1-598-g8116550e1662/disk-io.c
===================================================================
--- btrfs-progs-v0.20-rc1-598-g8116550e1662.orig/disk-io.c
+++ btrfs-progs-v0.20-rc1-598-g8116550e1662/disk-io.c
@@ -524,6 +524,8 @@ static int find_and_setup_root(struct bt
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;

View File

@ -0,0 +1,29 @@
From 6c90b5f56a389b37fcdd85e6dd904288d601b27a Mon Sep 17 00:00:00 2001
From: Josef Bacik <josef@redhat.com>
Date: Wed, 7 Dec 2011 15:54:13 -0500
Subject: [PATCH 168/170] Btrfs-progs: don't bug out if we can't find the last
root
Return an error instead of BUG()'ing out.
Signed-off-by: Josef Bacik <josef@redhat.com>
---
root-tree.c | 5 +++++
1 file changed, 5 insertions(+)
Index: btrfs-progs-v0.20-rc1-598-g8116550e1662/root-tree.c
===================================================================
--- btrfs-progs-v0.20-rc1-598-g8116550e1662.orig/root-tree.c
+++ btrfs-progs-v0.20-rc1-598-g8116550e1662/root-tree.c
@@ -45,6 +45,11 @@ int btrfs_find_last_root(struct btrfs_ro
BUG_ON(ret == 0);
l = path->nodes[0];
+ if (path->slots[0] == 0) {
+ ret = -ENOENT;
+ goto out;
+ }
+
slot = path->slots[0] - 1;
btrfs_item_key_to_cpu(l, &found_key, slot);
if (found_key.objectid != objectid) {

View File

@ -0,0 +1,56 @@
From 4469ed43b26b6e7d5ad5cfea45e99708e39de4a6 Mon Sep 17 00:00:00 2001
From: David Marcin <djmarcin@google.com>
Date: Wed, 16 Nov 2011 12:18:08 -0800
Subject: [PATCH 169/170] btrfs-progs: Check metadata mirrors in find-root.
Signed-off-by: David Marcin <djmarcin@google.com>
---
btrfs-find-root.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/btrfs-find-root.c b/btrfs-find-root.c
index 7f7b64f..ffbdde1 100644
--- a/btrfs-find-root.c
+++ b/btrfs-find-root.c
@@ -236,6 +236,8 @@ static int find_root(struct btrfs_root *root)
while (1) {
u64 map_length = 4096;
u64 type;
+ int mirror_num;
+ int num_copies;
if (offset >
btrfs_super_total_bytes(root->fs_info->super_copy)) {
@@ -257,9 +259,11 @@ static int find_root(struct btrfs_root *root)
printf("Checking metadata chunk %Lu, size %Lu"
"\n", metadata_offset, metadata_size);
}
+ mirror_num = 1;
+ again:
err = __btrfs_map_block(&root->fs_info->mapping_tree, READ,
offset, &map_length, &type,
- &multi, 0, NULL);
+ &multi, mirror_num, NULL);
if (err) {
offset += map_length;
continue;
@@ -278,9 +282,16 @@ static int find_root(struct btrfs_root *root)
err = read_physical(root, fd, offset, bytenr, map_length);
if (!err) {
+ /* Found the root. */
ret = 0;
break;
} else if (err < 0) {
+ num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
+ offset, map_length);
+ mirror_num++;
+ if (mirror_num <= num_copies)
+ goto again;
+ /* Unrecoverable error in read. */
ret = err;
break;
}
--
1.8.3.1

View File

@ -0,0 +1,93 @@
From 1e9e1d5c876a4c281b3b9e72f4cbaaef1e3a2fa5 Mon Sep 17 00:00:00 2001
From: David Marcin <djmarcin@google.com>
Date: Mon, 21 Nov 2011 20:51:15 -0600
Subject: [PATCH 170/170] btrfs-progs: In find-root, dump bytenr for every
slot.
Signed-off-by: David Marcin <djmarcin@google.com>
---
btrfs-find-root.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 59 insertions(+), 1 deletion(-)
diff --git a/btrfs-find-root.c b/btrfs-find-root.c
index ffbdde1..00b10e7 100644
--- a/btrfs-find-root.c
+++ b/btrfs-find-root.c
@@ -127,8 +127,63 @@ out:
return NULL;
}
+static int dump_root_bytenr(struct btrfs_root *root, u64 bytenr, u64 gen)
+{
+ struct btrfs_root *tmp = malloc(sizeof(struct btrfs_root));
+ struct btrfs_path *path;
+ struct btrfs_key key;
+ struct btrfs_root_item ri;
+ struct extent_buffer *leaf;
+ struct btrfs_disk_key disk_key;
+ struct btrfs_key found_key;
+ int slot;
+ int ret;
+
+ if (!tmp)
+ return -ENOMEM;
+
+ __setup_root(4096, 4096, 4096, 4096, tmp,
+ root->fs_info, BTRFS_ROOT_TREE_OBJECTID);
+
+ tmp->node = read_tree_block(root, bytenr, 4096, gen);
+
+ key.objectid = 0;
+ key.type = BTRFS_ROOT_ITEM_KEY;
+ key.offset = -1;
+
+ path = btrfs_alloc_path();
+
+ /* Walk the slots of this root looking for BTRFS_ROOT_ITEM_KEYs. */
+ ret = btrfs_search_slot(NULL, tmp, &key, path, 0, 0);
+ BUG_ON(ret < 0);
+ while (1) {
+ leaf = path->nodes[0];
+ slot = path->slots[0];
+ if (slot >= btrfs_header_nritems(leaf)) {
+ ret = btrfs_next_leaf(tmp, path);
+ if (ret != 0)
+ break;
+ leaf = path->nodes[0];
+ slot = path->slots[0];
+ }
+ btrfs_item_key(leaf, &disk_key, path->slots[0]);
+ btrfs_disk_key_to_cpu(&found_key, &disk_key);
+ if (btrfs_key_type(&found_key) == BTRFS_ROOT_ITEM_KEY) {
+ unsigned long offset;
+
+ offset = btrfs_item_ptr_offset(leaf, slot);
+ read_extent_buffer(leaf, &ri, offset, sizeof(ri));
+ printf("Generation: %Lu Root bytenr: %Lu\n", gen, btrfs_root_bytenr(&ri));
+ }
+ path->slots[0]++;
+ }
+ btrfs_free_path(path);
+ free_extent_buffer(leaf);
+ return 0;
+}
+
static int search_iobuf(struct btrfs_root *root, void *iobuf,
- size_t iobuf_size, off_t offset)
+ size_t iobuf_size, off_t offset)
{
u64 gen = search_generation;
u64 objectid = search_objectid;
@@ -160,6 +215,9 @@ static int search_iobuf(struct btrfs_root *root, void *iobuf,
h_byte);
goto next;
}
+ /* Found some kind of root and it's fairly valid. */
+ if (dump_root_bytenr(root, h_byte, h_gen))
+ break;
if (h_gen != gen) {
fprintf(stderr, "Well block %Lu seems great, "
"but generation doesn't match, "
--
1.8.3.1

View File

@ -1,72 +0,0 @@
#!/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=`blockdev --getsize64 "$dev"`;
}
sysopen(F, $dev, O_EXCL | O_RDWR) or die("Cannot open $dev exclusively: $!");
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");
if (!-b $dev) {
system("fsync \'$dev\'");
} else {
system("blockdev --flushbufs \'$dev\'");
}

View File

@ -1,90 +0,0 @@
From 3c7ae0fc5139c195100eb931bc6e1148ac1f11f5 Mon Sep 17 00:00:00 2001
From: David Sterba <dsterba@suse.cz>
Date: Mon, 26 Mar 2012 15:39:08 +0200
Subject: [PATCH 37/46] btrfs-progs: add man page for btrfs-convert
Signed-off-by: David Sterba <dsterba@suse.cz>
---
man/Makefile | 2 +-
man/btrfs-convert.8.in | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 1 deletion(-)
create mode 100644 man/btrfs-convert.8.in
Index: btrfs-progs-v0.20-rc1-335-gf00dd83/man/btrfs-convert.8.in
===================================================================
--- /dev/null
+++ btrfs-progs-v0.20-rc1-335-gf00dd83/man/btrfs-convert.8.in
@@ -0,0 +1,60 @@
+.TH BTRFS-CONVERT 8
+.SH NAME
+btrfs-convert \- convert ext2/ext3/ext4 filesystem image to btrfs in-place
+.SH SYNOPSIS
+.B btrfs-convert \fB[\-dinL]\fP \fB[\-r]\fP \fB[\-l\fP \fILABEL\fP\fB]\fP \fIdevice\fP
+.SH DESCRIPTION
+.B btrfs-convert
+is used to convert a ext2/ext3/ext4 filesystem image to a btrfs one. This is
+performed on an unmounted image. The conversion is done in-place and it's
+possible to do a rollback to original fs. The original filesystem image is
+accessible as a subvolume named \fIext2\_subvol\fP.
+
+The success of the operation depends on amount of free space in the original
+filesystem, as btrfs uses this space to store it's own metadata and just adds
+pointers to the data blocks.
+
+Duration of the operation depends on fragmentation and allocated space on the
+orignal filesystem, it may take seveal hours for a terabyte-sized filesystem.
+
+If the operation does not finish succesfully, the image is recognized as the
+original fileystem.
+
+.SH OPTIONS
+.TP
+\fB\-d\fP
+Disable data checksumming. This may speed up the convert operation.
+.TP
+\fB\-i\fP
+Do not convert ACLs.
+.TP
+\fB\-n\fP
+Disable packing of small files.
+.TP
+\fB\-l\fR \fILABEL\fP
+Set the label of btrfs filesystem to \fILABEL\fP.
+.TP
+\fB\-L\fP
+Copy label from the original filesystem to btrfs.
+.TP
+\fB\-r\fP
+Try rollback to the original filesystem. Beware that this may not always
+succeed if the btrfs filesystem has been changed in a way that prevents this.
+
+.SH CAVEATS
+The resulting filesystem will inherit the fragmentation and it's possible to
+run whole filesystem defragmentation and then balance.
+
+The raid profile of both data and metada will be \fIsingle\fP, this is not the
+same as default mkfs will create. Use balance with convert filter to change
+raid profile you want.
+
+Security labels or quotas are not transferred to the new filesystem.
+
+Block sizes must be at least of btrfs supported size (currently 4KB on x86_64).
+
+.SH AVAILABILITY
+.B btrfs-convert
+is part of btrfs-progs.
+.SH SEE ALSO
+.BR mkfs.btrfs (8)
Index: btrfs-progs-v0.20-rc1-335-gf00dd83/man/Makefile
===================================================================
--- btrfs-progs-v0.20-rc1-335-gf00dd83.orig/man/Makefile
+++ btrfs-progs-v0.20-rc1-335-gf00dd83/man/Makefile
@@ -11,7 +11,7 @@ man8dir = $(mandir)/man8
# list only those we use
.SUFFIXES: .in .gz
-MANPAGES = mkfs.btrfs.8.gz btrfsck.8.gz btrfs-image.8.gz btrfs.8.gz
+MANPAGES = mkfs.btrfs.8.gz btrfsck.8.gz btrfs-image.8.gz btrfs.8.gz btrfs-convert.8.gz
INFILES = ${MANPAGES:.in=.gz}
all: $(MANPAGES)

View File

@ -1,13 +0,0 @@
Index: btrfs-progs-v0.20-rc1-335-gf00dd83/mkfs.c
===================================================================
--- btrfs-progs-v0.20-rc1-335-gf00dd83.orig/mkfs.c
+++ btrfs-progs-v0.20-rc1-335-gf00dd83/mkfs.c
@@ -1520,6 +1520,8 @@ raid_groups:
super = root->fs_info->super_copy;
flags = btrfs_super_incompat_flags(super);
+ printf("Turning on extended refs (higher hardlink limit)\n");
+ flags |= BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF;
if (mixed)
flags |= BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS;

View File

@ -1,106 +0,0 @@
From 3a628f64ccdf41671368474a53c093ab03df1f98 Mon Sep 17 00:00:00 2001
From: Jeff Mahoney <jeffm@suse.com>
Date: Thu, 15 Aug 2013 20:32:00 -0400
Subject: btrfs-progs: restore passing of super_bytenr to device scan
Commit 615f2867 (Btrfs-progs: cleanup similar code in open_ctree_*
and close_ctree) introduced a regression in btrfs-convert.
open_ctree takes a sb_bytenr argument to specify where to find the
superblock. Under normal conditions, this will be at BTRFS_SUPER_INFO_OFFSET,
and that commit assumed as much under all conditions.
make_btrfs allows the caller to specify which blocks to use for
certain blocks (including the superblock) and this is used by btrfs-convert
to avoid overwriting the source file system's superblock until the
conversion is complete.
When btrfs-convert goes to open the newly initialized file system, it
fails with: "No valid btrfs found" since its superblock wasn't written
to the normal location.
This patch restores the passing down of super_bytesnr to
btrfs_scan_one_device.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
btrfs-find-root.c | 2 +-
cmds-chunk.c | 2 +-
disk-io.c | 10 +++++++---
disk-io.h | 3 ++-
4 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/btrfs-find-root.c b/btrfs-find-root.c
index 9b3d7df..374cf81 100644
--- a/btrfs-find-root.c
+++ b/btrfs-find-root.c
@@ -82,7 +82,7 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device)
return NULL;
}
- ret = btrfs_scan_fs_devices(fd, device, &fs_devices);
+ ret = btrfs_scan_fs_devices(fd, device, &fs_devices, 0);
if (ret)
goto out;
diff --git a/cmds-chunk.c b/cmds-chunk.c
index 03314de..6ada328 100644
--- a/cmds-chunk.c
+++ b/cmds-chunk.c
@@ -1291,7 +1291,7 @@ static int recover_prepare(struct recover_control *rc, char *path)
goto fail_free_sb;
}
- ret = btrfs_scan_fs_devices(fd, path, &fs_devices);
+ ret = btrfs_scan_fs_devices(fd, path, &fs_devices, 0);
if (ret)
goto fail_free_sb;
diff --git a/disk-io.c b/disk-io.c
index 13dbe27..1b91de6 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -909,13 +909,17 @@ void btrfs_cleanup_all_caches(struct btrfs_fs_info *fs_info)
}
int btrfs_scan_fs_devices(int fd, const char *path,
- struct btrfs_fs_devices **fs_devices)
+ struct btrfs_fs_devices **fs_devices,
+ u64 super_bytenr)
{
u64 total_devs;
int ret;
+ if (super_bytenr == 0)
+ super_bytenr = BTRFS_SUPER_INFO_OFFSET;
+
ret = btrfs_scan_one_device(fd, path, fs_devices,
- &total_devs, BTRFS_SUPER_INFO_OFFSET);
+ &total_devs, super_bytenr);
if (ret) {
fprintf(stderr, "No valid Btrfs found on %s\n", path);
return ret;
@@ -1001,7 +1005,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
if (restore)
fs_info->on_restoring = 1;
- ret = btrfs_scan_fs_devices(fp, path, &fs_devices);
+ ret = btrfs_scan_fs_devices(fp, path, &fs_devices, sb_bytenr);
if (ret)
goto out;
diff --git a/disk-io.h b/disk-io.h
index effaa9f..d7792e0 100644
--- a/disk-io.h
+++ b/disk-io.h
@@ -59,7 +59,8 @@ int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info,
void btrfs_release_all_roots(struct btrfs_fs_info *fs_info);
void btrfs_cleanup_all_caches(struct btrfs_fs_info *fs_info);
int btrfs_scan_fs_devices(int fd, const char *path,
- struct btrfs_fs_devices **fs_devices);
+ struct btrfs_fs_devices **fs_devices,
+ u64 super_bytenr);
int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info);
struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, int writes);

View File

@ -1,30 +0,0 @@
From d37ac57247379f929cd25cc1388c3df8830d704d Mon Sep 17 00:00:00 2001
From: David Sterba <dsterba@suse.cz>
Date: Mon, 26 Mar 2012 14:50:48 +0200
Subject: [PATCH 8/8] btrfs-progs: use IEEE1541 suffixes for sizes
IEEE 1541-2002
Signed-off-by: David Sterba <dsterba@suse.cz>
---
utils.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/utils.c b/utils.c
index f885307..97e0da7 100644
--- a/utils.c
+++ b/utils.c
@@ -1094,8 +1094,8 @@ out:
return ret;
}
-static char *size_strs[] = { "", "KB", "MB", "GB", "TB",
- "PB", "EB", "ZB", "YB"};
+static char *size_strs[] = { "", "KiB", "MiB", "GiB", "TiB",
+ "PiB", "EiB", "ZiB", "YiB"};
char *pretty_sizes(u64 size)
{
int num_divs = 0;
--
1.7.6.233.gd79bc

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:719ec8f8d3018995d39937cc435bfe080d117aff5a1581aa8d547917cedd8eb6
size 246154

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:db4e7d64f3b0f3c9faf37cbd5a00b93f44c37f2853ed82ec3ffad9ca620daed4
size 274256

View File

@ -1,3 +1,11 @@
-------------------------------------------------------------------
Mon Nov 25 14:10:55 CET 2013 - dsterba@suse.cz
- bump version to 3.12
- update tarball and remove upstreamed patches
- fsck, image, restore: various improvements and fixes
- btrfs: quota rescan (fate#312751)
-------------------------------------------------------------------
Thu Oct 31 01:05:56 CET 2013 - dsterba@suse.cz

View File

@ -18,9 +18,9 @@
Name: btrfsprogs
Url: http://btrfs.wiki.kernel.org/index.php/Main_Page
Version: 0.20
Version: 3.12
Release: 0
%define tar_version v0.20-rc1-358-g194aa4a
%define tar_version v3.12
Summary: Utilities for the Btrfs filesystem
License: GPL-2.0
Group: System/Filesystems
@ -30,28 +30,18 @@ Group: System/Filesystems
Source: btrfs-progs-%{tar_version}.tar.bz2
Source1: boot-btrfs.sh
Source4: setup-btrfs.sh
Source2: btrfs-dev-clear-sb
Patch10: 0010-Btrfs-progs-make-btrfsck-a-hardlink-at-install-time.patch
Patch12: 0012-libbtrfs-Set-SONAME-to-libbtrfs.so.0-instead-of-libb.patch
Patch40: 0040-btrfs-progs-fix-loop-device-mount-checks.patch
Patch1: btrfs-progs-mkfs-default-extref.diff
Patch50: 0050-Btrfs-progs-commit-the-csum_root-if-we-do-init-csum-.patch
Patch51: 0051-btrfs-progs-Fix-getopt-on-arm-ppc-platforms.patch
Patch52: 0052-btrfs-progs-fix-duplicate-__-su-typedefs-on-ppc64.patch
Patch53: 0053-btrfs-progs-use-reentrant-localtime.patch
Patch54: 0054-btrfs-progs-don-t-have-to-report-ENOMEDIUM-error-dur.patch
Patch55: 0055-Btrfs-progs-added-btrfs-quota-rescan-w-switch-wait.patch
Patch56: 0056-btrfs-progs-fix-qgroup-realloc-inheritance.patch
Patch57: 0057-Btrfs-progs-fix-restore-command-leaving-corrupted-fi.patch
Patch58: 0058-btrfs-progs-avoid-write-to-the-disk-before-sure-to-c.patch
Patch59: 0059-btrfs-progs-error-if-device-for-mkfs-is-too-small.patch
Patch60: 0060-btrfs-progs-error-if-device-have-no-space-to-make-pr.patch
Patch61: 0061-btrfs-progs-calculate-available-blocks-on-device-pro.patch
Patch62: 0062-Btrfs-progs-keep-track-of-transid-failures-and-fix-t.patch
Patch162: 0162-btrfs-progs-fix-loop-device-mount-checks.patch
Patch163: 0163-btrfs-progs-fsck-fix-segfault.patch
Patch164: 0164-btrfs-progs-convert-set-label-or-copy-from-origin.patch
Patch165: 0165-Revert-btrfs-progs-update-options-in-find-root.c.patch
Patch166: 0166-Btrfs-progs-add-some-verbose-output-to-find-root.patch
Patch167: 0167-Btrfs-progs-make-find_and_setup_root-return-an-error.patch
Patch168: 0168-Btrfs-progs-don-t-bug-out-if-we-can-t-find-the-last-.patch
Patch169: 0169-btrfs-progs-Check-metadata-mirrors-in-find-root.patch
Patch170: 0170-btrfs-progs-In-find-root-dump-bytenr-for-every-slot.patch
Patch1000: local-version-override.patch
Patch1001: btrfs-progs-use-IEEE1541-suffixes-for-sizes.patch
Patch1002: btrfs-progs-add-man-page-for-btrfs-convert.patch
Patch1003: btrfs-progs-restore-passing-of-super_bytenr-to-device-scan
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: libacl-devel
@ -88,27 +78,16 @@ build applications to interface with btrfs.
%prep
%setup -q -n btrfs-progs-%{tar_version}
%patch10 -p1
%patch12 -p1
%patch40 -p1
%patch1 -p1
%patch162 -p1
%patch163 -p1
%patch164 -p1
%patch165 -p1
%patch166 -p1
%patch167 -p1
%patch168 -p1
%patch169 -p1
%patch170 -p1
%patch1000 -p1
%patch1001 -p1
%patch1002 -p1
%patch1003 -p1
%patch50 -p1
%patch51 -p1
%patch52 -p1
%patch53 -p1
%patch54 -p1
%patch55 -p1
%patch56 -p1
%patch57 -p1
%patch58 -p1
%patch59 -p1
%patch60 -p1
%patch61 -p1
%patch62 -p1
%build
make %{?_smp_mflags} CFLAGS="%{optflags}" all btrfs-convert \
@ -150,7 +129,6 @@ ln -s %{_sbindir}/fsck.btrfs ${RPM_BUILD_ROOT}/sbin
install -d -m0755 ${RPM_BUILD_ROOT}/lib/mkinitrd/scripts/
install -m 0755 %{S:1} ${RPM_BUILD_ROOT}/lib/mkinitrd/scripts/
install -m 0755 %{S:4} ${RPM_BUILD_ROOT}/lib/mkinitrd/scripts/
install -m 0755 %{S:2} ${RPM_BUILD_ROOT}/usr/sbin/
rm -f ${RPM_BUILD_ROOT}/%{_libdir}/*.la
# don't install .a for now
rm -f ${RPM_BUILD_ROOT}/%{_libdir}/*.a
@ -188,17 +166,21 @@ rm -f ${RPM_BUILD_ROOT}/%{_libdir}/*.a
%{_sbindir}/mkfs.btrfs
%{_sbindir}/btrfs-debug-tree
%{_sbindir}/btrfs-show-super
/usr/sbin/btrfs-dev-clear-sb
/lib/mkinitrd/scripts/boot-btrfs.sh
/lib/mkinitrd/scripts/setup-btrfs.sh
# other
/usr/bin/btrfs-map-logical
/usr/sbin/btrfs-dev-clear-sb
%_mandir/man8/btrfs-image.8.gz
%_mandir/man8/btrfsck.8.gz
%_mandir/man8/mkfs.btrfs.8.gz
%_mandir/man8/btrfs.8.gz
%_mandir/man8/btrfs-convert.8.gz
%_mandir/man8/btrfs-debug-tree.8.gz
%_mandir/man8/btrfs-find-root.8.gz
%_mandir/man8/btrfs-map-logical.8.gz
%_mandir/man8/btrfs-show-super.8.gz
%_mandir/man8/btrfs-zero-log.8.gz
%_mandir/man8/btrfstune.8.gz
%files -n libbtrfs0
%defattr(-, root, root)

View File

@ -6,8 +6,8 @@ Index: btrfs-progs-v0.19-116-g13eced9/version.sh
# Copyright 2008, Oracle
# Released under the GNU GPLv2
-v="v0.20-rc1"
+v="v0.20-rc1+20131031"
-v="v3.12"
+v="v3.12+20131125"
which git &> /dev/null
if [ $? == 0 -a -d .git ]; then