From: Qu Wenruo <quwenruo.btrfs@gmx.com>
To: Askar Safin <safinaskar@gmail.com>
Cc: dsterba@suse.com, linux-btrfs@vger.kernel.org,
lists@colorremedies.com, wqu@suse.com
Subject: Re: [PATCH RFC] btrfs: exit scrub and balance early if the fs is being frozen
Date: Thu, 16 Oct 2025 09:31:14 +1030 [thread overview]
Message-ID: <5517a3cd-1afa-4db0-bf8b-439f3ba410ed@gmx.com> (raw)
In-Reply-To: <20251015111217.5538-1-safinaskar@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3062 bytes --]
在 2025/10/15 21:42, Askar Safin 写道:
> I just noticed that suspend behavior depends on whether "btrfs scrub" is
> started in terminal window or as a systemd service. I think this is because
> systemd tries to freeze user session when suspending, but doesn't freeze
> services.
I don't think it's the case, as the pm suspend-to-ram requires all user
space programs to be frozen.
I guess the difference is in the systemd's handling of user slice.
Maybe it is sending some signal first, then freeze for the time-out
case, but directly freeze for the service.
Anyway, mind to test the attached newer patch?
This one also adds the extra signal checking (including the regular
SIGINT and fatal ones), hope it would be the last testing patch.
Please apply it upon clean upstream branch (aka, no previous test
patches applied).
But if the latest patch doesn't work, I'm running out of ideas.
Inside the kernel I can only find out how to check signals and freezing
status, but if systemd is not using those two ways, I have no more ideas.
Thanks,
Qu
>
> So I retested everything.
>
> All tests were done with my distro's version of btrfs-progs (6.14-1).
> My distro is Debian Trixie.
> I have btrfs raid-1, which spans two actual partitions, 3.5 TiB each.
>
> Let's start with unpatched v6.18-rc1.
>
> - scrub in win, freeze_filesystems=0 - suspend doesn't work
>
> - scrub as a service, freeze_filesystems=0 - suspend doesn't work
>
> - scrub in win, freeze_filesystems=1
> suspend takes 6-10 mins. I. e. the system hangs for 6-10 mins and then
> suspends. I suspect this is time needed to complete scrub
>
> - scrub as a service, freeze_filesystems=1 - the same
>
> Also: on unpatched kernel "btrfs scrub" terminates instantly if it receives
> INT, but doesn't terminate if it receives KILL, TERM or HUP.
>
> Now v6.18-rc1 with your old 7 Jul 2025 patch
> ( https://lore.kernel.org/linux-btrfs/9606fae20bff6c1fbe14dc7b067f3b333c2a955b.1751847905.git.wqu@suse.com/ ).
>
> - scrub in win, freeze_filesystems=0 - suspend doesn't work
>
> - scrub as a service, freeze_filesystems=0 - suspend doesn't work
>
> - scrub in win, freeze_filesystems=1
> suspend takes 1 min. I. e. the system hangs for 1 min, then suspends
>
> - scrub as a service, freeze_filesystems=1
> suspend works perfectly. I. e. the system instantly suspends. I don't even
> notice 19s delay you are talking about
>
> Now v6.18-rc1 with your new 15 Oct 2025 patch
> ( https://lore.kernel.org/linux-btrfs/8c3628d5-8fce-45a1-b29c-65c2c52f1c06@gmx.com/ ).
>
> - scrub in win, freeze_filesystems=0 - hangs for 60s, then suspends
>
> - scrub as a service, freeze_filesystems=0 - works perfectly, i. e. suspends instantly
>
> - scrub in win, freeze_filesystems=1 - hangs for 60s, then suspends
> here is journalctl: https://zerobin.net/?7b394069a9050b8d#7PrnCDJV2t9inNFS3/EhxHJUS24iSGX7FAmjUstKKr4=
>
> - scrub as a service, freeze_filesystems=1 - works perfectly, i. e. suspends instantly
>
[-- Attachment #2: 0001-btrfs-cancel-the-scrub-if-the-fs-or-the-process-is-b.patch --]
[-- Type: text/x-patch, Size: 2817 bytes --]
From e56bff151de2c98ad489ab0721b1d68e58b45129 Mon Sep 17 00:00:00 2001
Message-ID: <e56bff151de2c98ad489ab0721b1d68e58b45129.1760569187.git.wqu@suse.com>
From: Qu Wenruo <wqu@suse.com>
Date: Wed, 15 Oct 2025 17:07:00 +1030
Subject: [PATCH] btrfs: cancel the scrub if the fs or the process is being
frozen
It's a known bug that btrfs scrub/dev-replace can prevent the fs from
suspending.
There are at least two factors involved:
- Holding super_block::s_writers for the whole scrub/dev-replace
duration
We hold that mutex through mnt_want_write_file() for the whole
scrub/dev-replace duration.
That will prevent the fs being frozen.
It's tunable for the kernel to suspend the fs before suspending, if
that's the case, btrfs will refuse to freeze and break the suspension.
- Stuck in kernel space for a long time
During suspension all user progresses (and some kernel threads) will
be frozen.
But if a user space progress has fallen into kernel and do not return
for a long time, it will make suspension to time out.
Unfortunately scrub/dev-replace is a long running ioctl, and it will
prevent the btrfs-progs from returning to user space.
Address them in one go:
- Introduce a new helper should_cancel_scrub()
Which checks both fs and process freezing.
- Cancel the run if should_cancel_scrub() is true
The check is done at scrub_simple_mirror() and
scrub_raid56_parity_stripe().
Unfortunately canceling is the only feasible solution here, pausing is
not possible as we will still stay in the kernel state thus will still
prevent the process from being frozen.
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/scrub.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index fe266785804e..1ddcd8a88610 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -2234,6 +2234,22 @@ static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx,
return ret;
}
+static bool should_cancel_scrub(struct btrfs_fs_info *fs_info)
+{
+ /*
+ * If some one is trying to freeze the fs or the scrub process,
+ * cancel the run.
+ */
+ if (fs_info->sb->s_writers.frozen > SB_UNFROZEN ||
+ freezing(current))
+ return true;
+
+ /* Also check for pending signals. */
+ if (signal_pending(current))
+ return true;
+ return false;
+}
+
/*
* Scrub one range which can only has simple mirror based profile.
* (Including all range in SINGLE/DUP/RAID1/RAID1C*, and each stripe in
@@ -2263,7 +2279,8 @@ static int scrub_simple_mirror(struct scrub_ctx *sctx,
/* Canceled? */
if (atomic_read(&fs_info->scrub_cancel_req) ||
- atomic_read(&sctx->cancel_req)) {
+ atomic_read(&sctx->cancel_req) ||
+ should_cancel_scrub(fs_info)) {
ret = -ECANCELED;
break;
}
--
2.50.1
next prev parent reply other threads:[~2025-10-15 23:01 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-07 0:25 [PATCH RFC] btrfs: exit scrub and balance early if the fs is being frozen Qu Wenruo
2025-07-07 5:23 ` Qu Wenruo
2025-07-07 12:30 ` David Sterba
2025-07-07 12:37 ` Daniel Vacek
2025-07-07 22:16 ` Qu Wenruo
2025-07-07 12:25 ` David Sterba
2025-10-12 8:23 ` Askar Safin
2025-10-12 23:56 ` Qu Wenruo
2025-10-15 4:05 ` Askar Safin
2025-10-15 7:00 ` Qu Wenruo
2025-10-15 7:59 ` Askar Safin
2025-10-15 8:07 ` Qu Wenruo
2025-10-15 11:12 ` Askar Safin
2025-10-15 23:01 ` Qu Wenruo [this message]
2025-10-16 8:40 ` Askar Safin
2025-10-16 9:46 ` Qu Wenruo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5517a3cd-1afa-4db0-bf8b-439f3ba410ed@gmx.com \
--to=quwenruo.btrfs@gmx.com \
--cc=dsterba@suse.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=lists@colorremedies.com \
--cc=safinaskar@gmail.com \
--cc=wqu@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox