Compare commits
11 Commits
faf3300937
...
5f60745451
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f60745451 | ||
|
|
1e5383dc62 | ||
|
|
e90b4d62a9 | ||
|
|
ac5de77243 | ||
|
|
9d05e9f974 | ||
|
|
88ab18375f | ||
|
|
fdf75de971 | ||
|
|
653ad85ae9 | ||
|
|
0f2f9b0014 | ||
|
|
914b081b1c | ||
|
|
c317c9211f |
@ -1,107 +0,0 @@
|
||||
From c9c4eb1f3fd343512d50b075b40bba656cbd02cb Mon Sep 17 00:00:00 2001
|
||||
From: Qu Wenruo <wqu@suse.com>
|
||||
Date: Mon, 20 Jul 2020 20:51:08 +0800
|
||||
Subject: [PATCH 10/74] btrfs-progs: convert: prevent 32bit overflow for
|
||||
cctx->total_bytes
|
||||
|
||||
[BUG]
|
||||
When convert is called on a 64GiB ext4 fs, it fails like this:
|
||||
|
||||
$ btrfs-convert /dev/loop0p1
|
||||
create btrfs filesystem:
|
||||
blocksize: 4096
|
||||
nodesize: 16384
|
||||
features: extref, skinny-metadata (default)
|
||||
checksum: crc32c
|
||||
creating ext2 image file
|
||||
ERROR: missing data block for bytenr 1048576
|
||||
ERROR: failed to create ext2_saved/image: -2
|
||||
WARNING: an error occurred during conversion, filesystem is partially created but not finalized and not mountable
|
||||
|
||||
Btrfs-convert also corrupts the source fs:
|
||||
|
||||
$ LANG=C e2fsck /dev/loop0p1 -f
|
||||
e2fsck 1.45.6 (20-Mar-2020)
|
||||
Resize inode not valid. Recreate<y>? yes
|
||||
Pass 1: Checking inodes, blocks, and sizes
|
||||
Deleted inode 3681 has zero dtime. Fix<y>? yes
|
||||
Inodes that were part of a corrupted orphan linked list found. Fix<y>? yes
|
||||
Inode 3744 was part of the orphaned inode list. FIXED.
|
||||
Deleted inode 3745 has zero dtime. Fix<y>? yes
|
||||
Inode 3747 has INLINE_DATA_FL flag on filesystem without inline data support.
|
||||
Clear<y>? yes
|
||||
...
|
||||
|
||||
[CAUSE]
|
||||
After some debugging, the first strange behavior is, the value of
|
||||
cctx->total_bytes is 0 in ext2_open_fs().
|
||||
|
||||
It turns out that, the value assign for cctx->total_bytes could lead to
|
||||
bit overflow for the unsigned int value.
|
||||
|
||||
And that 0 cctx->total_bytes leads to various problems for later free
|
||||
space calculation.
|
||||
For example, in calculate_available_space(), we use cctx->total_bytes to
|
||||
ensure we won't create a data chunk beyond device end:
|
||||
|
||||
cue_len = min(cctx->total_bytes - cur_off, cur_len);
|
||||
|
||||
If that cur_offset is also 0, we will create a cache_extent with 0 size,
|
||||
which could cause a lot of problems for cache tree search.
|
||||
|
||||
[FIX]
|
||||
Do manual casting for the multiply operation, so we could got a real u64
|
||||
result. The fix will be applied to all supported fses (ext* and
|
||||
reiserfs).
|
||||
|
||||
Reported-by: Christian Zangl <coralllama@gmail.com>
|
||||
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
|
||||
Signed-off-by: Qu Wenruo <wqu@suse.com>
|
||||
Signed-off-by: David Sterba <dsterba@suse.com>
|
||||
---
|
||||
convert/main.c | 1 +
|
||||
convert/source-ext2.c | 2 +-
|
||||
convert/source-reiserfs.c | 2 +-
|
||||
3 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/convert/main.c b/convert/main.c
|
||||
index 7709e9a..df6a2ae 100644
|
||||
--- a/convert/main.c
|
||||
+++ b/convert/main.c
|
||||
@@ -1136,6 +1136,7 @@ static int do_convert(const char *devname, u32 convert_flags, u32 nodesize,
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
+ ASSERT(cctx.total_bytes);
|
||||
blocksize = cctx.blocksize;
|
||||
total_bytes = (u64)blocksize * (u64)cctx.block_count;
|
||||
if (blocksize < 4096) {
|
||||
diff --git a/convert/source-ext2.c b/convert/source-ext2.c
|
||||
index f11ef65..d73684e 100644
|
||||
--- a/convert/source-ext2.c
|
||||
+++ b/convert/source-ext2.c
|
||||
@@ -87,7 +87,7 @@ static int ext2_open_fs(struct btrfs_convert_context *cctx, const char *name)
|
||||
cctx->fs_data = ext2_fs;
|
||||
cctx->blocksize = ext2_fs->blocksize;
|
||||
cctx->block_count = ext2_fs->super->s_blocks_count;
|
||||
- cctx->total_bytes = ext2_fs->blocksize * ext2_fs->super->s_blocks_count;
|
||||
+ cctx->total_bytes = (u64)ext2_fs->super->s_blocks_count * ext2_fs->blocksize;
|
||||
cctx->volume_name = strndup((char *)ext2_fs->super->s_volume_name, 16);
|
||||
cctx->first_data_block = ext2_fs->super->s_first_data_block;
|
||||
cctx->inodes_count = ext2_fs->super->s_inodes_count;
|
||||
diff --git a/convert/source-reiserfs.c b/convert/source-reiserfs.c
|
||||
index 9fd6b9a..3b4cb5a 100644
|
||||
--- a/convert/source-reiserfs.c
|
||||
+++ b/convert/source-reiserfs.c
|
||||
@@ -82,7 +82,7 @@ static int reiserfs_open_fs(struct btrfs_convert_context *cxt, const char *name)
|
||||
cxt->fs_data = fs;
|
||||
cxt->blocksize = fs->fs_blocksize;
|
||||
cxt->block_count = get_sb_block_count(fs->fs_ondisk_sb);
|
||||
- cxt->total_bytes = cxt->blocksize * cxt->block_count;
|
||||
+ cxt->total_bytes = (u64)cxt->block_count * cxt->blocksize;
|
||||
cxt->volume_name = strndup(fs->fs_ondisk_sb->s_label, 16);
|
||||
cxt->first_data_block = 0;
|
||||
cxt->inodes_count = reiserfs_count_objectids(fs);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
86
0001-fix-exclusive-op-enqueue-timeout.patch
Normal file
86
0001-fix-exclusive-op-enqueue-timeout.patch
Normal file
@ -0,0 +1,86 @@
|
||||
From d03594b0313db71413b9dcb040f8d5c4da7213b1 Mon Sep 17 00:00:00 2001
|
||||
From: David Sterba <dsterba@suse.com>
|
||||
Date: Fri, 19 Apr 2024 11:04:42 +0800
|
||||
Subject: [PATCH] fix exclusive op enqueue timeout
|
||||
There's a report that 'btrfs balance start --enqueue' does not properly
|
||||
wait when there are multiple instances started. The command does a busy
|
||||
wait instead of timeouts.
|
||||
|
||||
Strace output:
|
||||
|
||||
0.000006 pselect6(5, NULL, NULL, [4], {tv_sec=60, tv_nsec=0}, NULL) = 1 (except [4], left {tv_sec=59, tv_nsec=999999716})
|
||||
0.000008 pselect6(5, NULL, NULL, [4], {tv_sec=29, tv_nsec=999999000}, NULL) = 1 (except [4], left {tv_sec=29, tv_nsec=999998786})
|
||||
|
||||
After the first select there's almost the entire time left, the second
|
||||
one starts right after it.
|
||||
|
||||
Polling/selecting sysfs files is possible under some conditions:
|
||||
|
||||
- the file descriptor must be reopened before each poll/select
|
||||
- the whole buffer must be read too
|
||||
|
||||
With that in place it now works as expected. The remaining timeout logic
|
||||
is slightly adjusted to wait at most 10 seconds so the pending jobs do
|
||||
not wait too long if there's still a lot of time left from the first
|
||||
select.
|
||||
|
||||
Issue: #746
|
||||
Signed-off-by: David Sterba <dsterba@suse.com>
|
||||
---
|
||||
common/utils.c | 21 ++++++++++++++++++++-
|
||||
1 file changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/common/utils.c b/common/utils.c
|
||||
index a1dc1ba..2cc1664 100644
|
||||
--- a/common/utils.c
|
||||
+++ b/common/utils.c
|
||||
@@ -1323,26 +1323,45 @@ int check_running_fs_exclop(int fd, enum exclusive_operation start, bool enqueue
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * The sysfs file descriptor needs to be reopened and all data read
|
||||
+ * before each select().
|
||||
+ */
|
||||
while (exclop > 0) {
|
||||
fd_set fds;
|
||||
struct timeval tv = { .tv_sec = 60, .tv_usec = 0 };
|
||||
+ char tmp[1024];
|
||||
|
||||
+ close(sysfs_fd);
|
||||
+ sysfs_fd = sysfs_open_fsid_file(fd, "exclusive_operation");
|
||||
+ if (sysfs_fd < 0)
|
||||
+ return sysfs_fd;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sysfs_fd, &fds);
|
||||
|
||||
+ ret = read(sysfs_fd, tmp, sizeof(tmp));
|
||||
ret = select(sysfs_fd + 1, NULL, NULL, &fds, &tv);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
break;
|
||||
}
|
||||
if (ret > 0) {
|
||||
+ close(sysfs_fd);
|
||||
+ sysfs_fd = sysfs_open_fsid_file(fd, "exclusive_operation");
|
||||
+ if (sysfs_fd < 0)
|
||||
+ return sysfs_fd;
|
||||
+
|
||||
+ FD_ZERO(&fds);
|
||||
+ FD_SET(sysfs_fd, &fds);
|
||||
+
|
||||
+ ret = read(sysfs_fd, tmp, sizeof(tmp));
|
||||
/*
|
||||
* Notified before the timeout, check again before
|
||||
* returning. In case there are more operations
|
||||
* waiting, we want to reduce the chances to race so
|
||||
* reuse the remaining time to randomize the order.
|
||||
*/
|
||||
- tv.tv_sec /= 2;
|
||||
+ tv.tv_sec = (tv.tv_sec % 10) + 1;
|
||||
ret = select(sysfs_fd + 1, NULL, NULL, &fds, &tv);
|
||||
exclop = get_fs_exclop(fd);
|
||||
if (exclop <= 0)
|
||||
--
|
||||
2.43.0
|
||||
|
||||
Binary file not shown.
BIN
btrfs-progs-v6.0.tar.xz
Normal file
BIN
btrfs-progs-v6.0.tar.xz
Normal file
Binary file not shown.
@ -1,15 +1,16 @@
|
||||
Name: btrfs-progs
|
||||
Version: 5.7
|
||||
Release: 3
|
||||
Version: 6.0
|
||||
Release: 2
|
||||
Summary: btrfs userspace programs
|
||||
License: GPLv2 and GPL+ and LGPL-2.1+ and GPL-3.0+ and LGPL-2.1 and Artistic-1.0-Perl and MIT
|
||||
License: GPLv2 and GPL+ and LGPL-2.1+ and GPL-3.0+ and LGPL-2.1 and MIT
|
||||
URL: https://btrfs.wiki.kernel.org/index.php/Main_Page
|
||||
Source0: https://www.kernel.org/pub/linux/kernel/people/kdave/%{name}/%{name}-v%{version}.tar.xz
|
||||
Patch1: 0001-btrfs-progs-convert-prevent-32bit-overflow-for-cctx-.patch
|
||||
|
||||
Patch0001: 0001-fix-exclusive-op-enqueue-timeout.patch
|
||||
|
||||
BuildRequires: python3-devel >= 3.4
|
||||
BuildRequires: libacl-devel, e2fsprogs-devel, libblkid-devel, libuuid-devel, zlib-devel, libzstd-devel, lzo-devel
|
||||
BuildRequires: git, gcc, asciidoc, systemd, xmlto, autoconf, automake
|
||||
BuildRequires: libacl-devel, e2fsprogs-devel, libblkid-devel, libuuid-devel, zlib-devel, libzstd-devel, lzo-devel, systemd-devel
|
||||
BuildRequires: gcc, asciidoc, systemd, xmlto, autoconf, automake, python3-sphinx
|
||||
|
||||
%define _root_sbindir /sbin
|
||||
|
||||
@ -33,7 +34,7 @@ Requires: man
|
||||
This package includes man files for btrfs-progs
|
||||
|
||||
%prep
|
||||
%autosetup -n %{name}-v%{version} -p1 -S git
|
||||
%autosetup -n %{name}-v%{version} -p1
|
||||
|
||||
%build
|
||||
./autogen.sh
|
||||
@ -57,18 +58,35 @@ make mandir=%{_mandir} bindir=%{_sbindir} libdir=%{_libdir} incdir=%{_includedir
|
||||
%{_sbindir}/btrfs-map-logical
|
||||
%{_sbindir}/btrfs-find-root
|
||||
%{_udevrulesdir}/64-btrfs-dm.rules
|
||||
%{_udevrulesdir}/64-btrfs-zoned.rules
|
||||
%exclude %{_libdir}/*.a
|
||||
|
||||
%files devel
|
||||
%{_includedir}/*
|
||||
%{_libdir}/libbtrfs.so
|
||||
%{_libdir}/libbtrfsutil.so*
|
||||
%{_libdir}/pkgconfig/libbtrfsutil.pc
|
||||
|
||||
%files help
|
||||
%{_mandir}/man5/*.gz
|
||||
%{_mandir}/man8/*.gz
|
||||
|
||||
%changelog
|
||||
* Fri Apr 19 2024 cenhuilin <cenhuilin@kylinos.cn> - 6.0-2
|
||||
- fix exclusive op enqueue timeout
|
||||
|
||||
* Mon Oct 24 2022 zhanchengbin <zhanchengbin1@huawei.com> - 6.0-1
|
||||
- Update to btrfs-progs-6.0
|
||||
|
||||
* Tue Oct 18 2022 zhanchengbin <zhanchengbin1@huawei.com> - 5.15-2
|
||||
- delete license Artistic-1.0-Perl
|
||||
|
||||
* Tue Nov 16 2021 Wenchao Hao <haowenchao@huawei.com> - 5.15-1
|
||||
- Update to btrfs-progs-5.15
|
||||
|
||||
* Fri Jul 30 2021 chenyanpanHW <chenyanpan@huawei.com> - 5.7-4
|
||||
- DESC: delete -S git from %autosetup, and delete BuildRequires git
|
||||
|
||||
* Thu Dec 10 2020 yanglongkang<yanglongkang@huawei.com> - 5.7-3
|
||||
- fix URL error
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user