diff --git a/0001-fix-exclusive-op-enqueue-timeout.patch b/0001-fix-exclusive-op-enqueue-timeout.patch new file mode 100644 index 0000000000000000000000000000000000000000..2a4a7f0396961eead34394e93875af17232dcab8 --- /dev/null +++ b/0001-fix-exclusive-op-enqueue-timeout.patch @@ -0,0 +1,86 @@ +From d03594b0313db71413b9dcb040f8d5c4da7213b1 Mon Sep 17 00:00:00 2001 +From: David Sterba +Date: Thu, 18 Apr 2024 18:24:48 +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 +--- + common/utils.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/common/utils.c b/common/utils.c +index 62f0e3f..7cde492 100644 +--- a/common/utils.c ++++ b/common/utils.c +@@ -1326,26 +1326,45 @@ int check_running_fs_exclop(int fd, enum exclusive_operation start, bool enqueue + fflush(stdout); + } + ++ /* ++ * 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 + diff --git a/btrfs-progs.spec b/btrfs-progs.spec index a9cedce6ed56e233dac0522eb45d266b51b8bb58..ecb69900b71000411213b88d2f3e0efefbcd37ac 100644 --- a/btrfs-progs.spec +++ b/btrfs-progs.spec @@ -1,11 +1,13 @@ Name: btrfs-progs Version: 6.6.3 -Release: 1 +Release: 2 Summary: btrfs userspace programs 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 +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, systemd-devel BuildRequires: gcc, asciidoc, systemd, xmlto, autoconf, automake, python3-sphinx @@ -70,6 +72,9 @@ make mandir=%{_mandir} bindir=%{_sbindir} libdir=%{_libdir} incdir=%{_includedir %{_mandir}/man8/*.gz %changelog +* Fri Apr 19 2024 cenhuilin - 6.6.3-2 +- fix exclusive op enqueue timeout + * Wed Jan 17 2024 wuguanghao - 6.6.3-1 - upgrade version to 6.6.3