Accepting request 205320 from home:dsterba:branches:filesystems
SR: a few fixes, aimed for 13.1 RC2 - fsck updates - more mkfs sanity checks - qgroup rescan wait OBS-URL: https://build.opensuse.org/request/show/205320 OBS-URL: https://build.opensuse.org/package/show/filesystems/btrfsprogs?expand=0&rev=144
This commit is contained in:
parent
3ba375bc14
commit
5be20c4ea7
@ -0,0 +1,36 @@
|
|||||||
|
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
|
||||||
|
|
45
0051-btrfs-progs-Fix-getopt-on-arm-ppc-platforms.patch
Normal file
45
0051-btrfs-progs-Fix-getopt-on-arm-ppc-platforms.patch
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
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
|
||||||
|
|
38
0052-btrfs-progs-fix-duplicate-__-su-typedefs-on-ppc64.patch
Normal file
38
0052-btrfs-progs-fix-duplicate-__-su-typedefs-on-ppc64.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
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
|
||||||
|
|
61
0053-btrfs-progs-use-reentrant-localtime.patch
Normal file
61
0053-btrfs-progs-use-reentrant-localtime.patch
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
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
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
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
|
||||||
|
|
@ -0,0 +1,94 @@
|
|||||||
|
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
|
||||||
|
|
36
0056-btrfs-progs-fix-qgroup-realloc-inheritance.patch
Normal file
36
0056-btrfs-progs-fix-qgroup-realloc-inheritance.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
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
|
||||||
|
|
111
0057-Btrfs-progs-fix-restore-command-leaving-corrupted-fi.patch
Normal file
111
0057-Btrfs-progs-fix-restore-command-leaving-corrupted-fi.patch
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
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
|
||||||
|
|
253
0058-btrfs-progs-avoid-write-to-the-disk-before-sure-to-c.patch
Normal file
253
0058-btrfs-progs-avoid-write-to-the-disk-before-sure-to-c.patch
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
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
|
||||||
|
|
46
0059-btrfs-progs-error-if-device-for-mkfs-is-too-small.patch
Normal file
46
0059-btrfs-progs-error-if-device-for-mkfs-is-too-small.patch
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
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
|
||||||
|
|
@ -0,0 +1,91 @@
|
|||||||
|
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
|
||||||
|
|
233
0061-btrfs-progs-calculate-available-blocks-on-device-pro.patch
Normal file
233
0061-btrfs-progs-calculate-available-blocks-on-device-pro.patch
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
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
|
||||||
|
|
228
0062-Btrfs-progs-keep-track-of-transid-failures-and-fix-t.patch
Normal file
228
0062-Btrfs-progs-keep-track-of-transid-failures-and-fix-t.patch
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
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
|
||||||
|
|
@ -1,3 +1,10 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Oct 31 01:05:56 CET 2013 - dsterba@suse.cz
|
||||||
|
|
||||||
|
- fsck updates
|
||||||
|
- more mkfs sanity checks
|
||||||
|
- qgroup rescan wait
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Fri Oct 4 20:16:02 UTC 2013 - rgoldwyn@suse.com
|
Fri Oct 4 20:16:02 UTC 2013 - rgoldwyn@suse.com
|
||||||
|
|
||||||
|
@ -35,6 +35,19 @@ 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
|
Patch12: 0012-libbtrfs-Set-SONAME-to-libbtrfs.so.0-instead-of-libb.patch
|
||||||
Patch40: 0040-btrfs-progs-fix-loop-device-mount-checks.patch
|
Patch40: 0040-btrfs-progs-fix-loop-device-mount-checks.patch
|
||||||
Patch1: btrfs-progs-mkfs-default-extref.diff
|
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
|
||||||
Patch1000: local-version-override.patch
|
Patch1000: local-version-override.patch
|
||||||
Patch1001: btrfs-progs-use-IEEE1541-suffixes-for-sizes.patch
|
Patch1001: btrfs-progs-use-IEEE1541-suffixes-for-sizes.patch
|
||||||
Patch1002: btrfs-progs-add-man-page-for-btrfs-convert.patch
|
Patch1002: btrfs-progs-add-man-page-for-btrfs-convert.patch
|
||||||
@ -83,6 +96,19 @@ build applications to interface with btrfs.
|
|||||||
%patch1001 -p1
|
%patch1001 -p1
|
||||||
%patch1002 -p1
|
%patch1002 -p1
|
||||||
%patch1003 -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
|
%build
|
||||||
make %{?_smp_mflags} CFLAGS="%{optflags}" all btrfs-convert \
|
make %{?_smp_mflags} CFLAGS="%{optflags}" all btrfs-convert \
|
||||||
|
@ -7,7 +7,7 @@ Index: btrfs-progs-v0.19-116-g13eced9/version.sh
|
|||||||
# Released under the GNU GPLv2
|
# Released under the GNU GPLv2
|
||||||
|
|
||||||
-v="v0.20-rc1"
|
-v="v0.20-rc1"
|
||||||
+v="v0.20-rc1+20130701"
|
+v="v0.20-rc1+20131031"
|
||||||
|
|
||||||
which git &> /dev/null
|
which git &> /dev/null
|
||||||
if [ $? == 0 -a -d .git ]; then
|
if [ $? == 0 -a -d .git ]; then
|
||||||
|
Loading…
Reference in New Issue
Block a user