This is a real fault review. The environment is a Western Digital HC620 Host-Managed SMR hard disk, using Btrfs zoned, mounted on /mnt/disk1, the system is Ubuntu 26.04 LTS, and the kernel is:
|
|
The fault was not an ordinary hard disk speed decrease, but two serious abnormalities occurred one after another:
btrfs-cleanerandbtrfs-transactionenter the uninterruptibleDstate, and the file system cannot be unmounted;- The Btrfs transaction is aborted with
-11, and the kernel actively switches the file system to read-only.
Both failures occurred around multi-terabyte deletions, data copies, and zoned space reclamation. The system was not reinstalled, and btrfs check --repair was never run. This article preserves the original logs, reasoning, commands, and unresolved questions for anyone investigating a similar failure.
Note: This does not prove that every Btrfs deployment on an HC620 will fail, and a single call stack cannot identify a specific kernel fix. The kernel and Ubuntu package versions reflect the system as of July 24, 2026. Check the current repositories before following the version-specific steps.
Environment and triggering process
This disk mainly stores backup and cold data. The operations before the first failure are roughly as follows:
|
|
The HC620 is a Host-Managed SMR. Disks are managed according to zones. Each zone is displayed on site as:
|
|
On these devices, a written zone cannot be overwritten freely as it can on a conventional CMR drive. Deleting a file only removes references to its data blocks. The invalidated space cannot be reused until Btrfs reclaims the block group, moves any live data, and resets the zone. Btrfs reports this space as:
|
|
So “delete 3TB and immediately write 3TB” is not just a delete plus a copy. Possibly happening simultaneously in the background:
|
|
This becomes an important background for subsequent analysis of the call stack.
First failure: btrfs-cleaner blocked for a long time
The initial log contains:
|
|
The key call chain is:
|
|
Read it from bottom to top, the process is:
|
|
The log also indicates that the mutex is likely held by the same btrfs-cleaner thread. Combined with the call chain, the on-site judgment is that the cleaning thread enters the lock wait when block-group deletion, zone finish and new chunk allocation overlap. Subsequently, btrfs-transaction and kworker waiting for Btrfs flush were also blocked.
This is an explanation of the on-site call stack, which does not mean that the only corresponding upstream bug has been found. What is certain is:
- Blocking occurs in the block-group/chunk cleanup path of Btrfs zoned;
- The thread has entered the
Dstate in the kernel state; - Ordinary
kill -9cannot terminate the kernel thread; - Continuing operations that depend on transaction commit may get stuck together.
Initial diagnostic checks
First stop rsnapshot, rsync, Docker container or other disk writing tasks, and then check the uninterruptible process:
|
|
Save the kernel log of this startup:
|
|
Save the relevant thread stack:
|
|
Add a timeout when querying the file system to prevent the diagnostic command itself from permanently blocking:
|
|
Then try a normal uninstall:
|
|
turn out:
|
|
target is busy is not the same thing as kernel lockup
target is busy usually means that the following reference is still available:
- The current working directory of the process is located at
/mnt/disk1; - The file is still open;
- The backup or copy program is still running;
- There are sub-mount points under
/mnt/disk1; - The user process has entered the
Dstate due to file system lock.
First ensure that all terminals exit the mounting directory:
|
|
Check submounts and occupiers:
|
|
Ordinary user processes can be terminated normally before considering forced termination:
|
|
If rsnapshot or rsync:
|
|
But don’t try to kill:
|
|
They are kernel threads. On-site inspection shows that the main blocker is the Btrfs kernel thread, and continuing kill, umount or global sync cannot solve the root cause.
Why lazy unmount or forced unmount is not used?
It was not implemented at that time:
|
|
umount -l just removes the mount point from the directory tree first, and the actual file system reference still has to wait until it is no longer busy before it can be cleaned up. When a Btrfs transaction is locked, it may only hide the mount point and does not mean that the data has been committed or that the file system has been unmounted.
umount -f is also not a reliable means of relieving local Btrfs kernel deadlocks. It is more commonly used on parts of the network or in user-mode file systems.
Also not running:
|
|
These operations may wait for the blocked transaction or re-enter the problematic block-group reclamation path.
Add noauto before restarting
In order to avoid using the same kernel to automatically read and write this disk immediately after the machine restarts, first check /etc/fstab:
|
|
Backup configuration:
|
|
For example it turned out to be:
|
|
Temporarily changed to:
|
|
noauto means only that it will not be automatically mounted when booting, not that it will disable the file system. After the system is started, it can still be manually mounted read-only or read-write.
From normal restart to last resort
A normal restart was performed on site:
|
|
This time it was completed normally, and the file system was able to be remounted after restarting. If the normal restart is stuck due to Btrfs, the level of enforcement will be increased step by step according to the risk:
|
|
The last resort is:
|
|
Two --force no longer stop the service and unmount the file system normally, the effect is close to a hard reset, and uncommitted data may be lost. It can only be used when the system cannot be terminated normally and cannot be used as a normal restart command.
Check after restart
First confirm the actual booted kernel and disk:
|
|
Confirm there is no automatic mounting:
|
|
Mount read-only for the first time:
|
|
In the actual environment, UUID or /dev/disk/by-id/ should be used first, and the default device should not always be /dev/sda.
Check the kernel log, Btrfs device count, and space status:
|
|
Live btrfs device stats all 0:
|
|
This shows that Btrfs does not record device read and write, flush, verification or generation errors, which is a good sign. But it does not prove that the kernel lockup has been fixed, nor does it rule out the problem of unread data.
What scrub does and doesn’t do
A scrub is scheduled after the system is stable:
|
|
If you want the front desk to wait for results:
|
|
Cancel task:
|
|
Scrub reads the stored data and metadata and checks the checksum saved by Btrfs. It is used to find read errors, data or metadata validation errors, not:
|
|
If the result is:
|
|
It can only show that no exception was found in this reading and verification, but it cannot prove that the zoned cleanup path of btrfs-cleaner will not be locked again in the future.
Save results:
|
|
Do not run rsync, rsnapshot, balance or perform mass deletions at the same time during Scrub. For this type of backup disk, it can be performed every one to three months based on actual usage intensity.
Why balance is not run for “reclaiming space”
Appeared at the scene:
|
|
This number only represents the usage of the allocated Data block group, and does not mean that only 1.33% of the entire disk is left. At that time, there were still several TiB Device unallocated, and there was no shortage of space to continue to allocate.
So there is no execution:
|
|
Balance will relocate the block group where the first failure is:
|
|
Running balance on the affected kernel may re-enter similar block-group deletion and zone reclamation paths.
How to handle multi-terabyte deletes and writes
The most effective workflow adjustment is to copy and verify new data before deleting old data when there is enough space.
|
|
copy:
|
|
Compare capacity:
|
|
Practice using the content verification method without modifying the target:
|
|
When deletion is necessary first, do not delete several TB at once and then write immediately. It can be divided into batches of 200~500GiB by date, subdirectory or capacity:
|
|
btrfs filesystem sync will commit the file system transaction and wake up related cleanup work, but the command return does not mean that all block groups and zone reclaim have been completed.
If you are deleting a Btrfs subvolume or snapshot, you can also execute:
|
|
It waits for the subvolume for which the deletion request has been submitted to complete cleanup and does not apply to normal rm -rf deletions.
Check after each batch:
|
|
Meet the following conditions before continuing:
btrfs filesystem syncreturns normally;- No Btrfs threads are in
Dstate; - There are no new blocked, hung, abort or Btrfs errors in the kernel log;
- Disk activity has dropped significantly;
Device zone unusableis not growing rapidly.
Device zone unusable does not need to fall to zero. It may remain at a few dozen GiB until the next reclamation threshold is reached; that alone does not mean the file system is still busy or stuck.
Writes can also be batched, with priority and bandwidth limited:
|
|
--bwlimit=100M is just a conservative starting point. Rate limiting cannot fix kernel bugs, but it can reduce the probability of cleaner, transaction commit, writeback, and zone activation being under high load at the same time. Don’t run multiple large rsyncs concurrently.
Monitor zoned reclamation metrics
First get the file system UUID:
|
|
Check the space and recovery indicators of data, metadata and system:
|
|
in:
bytes_pinned: Space that usually cannot be released until the current transaction is committed;bytes_zone_unusable: zoned space that has expired but cannot be directly reused;reclaim_count: cumulative number of reclamation attempts;reclaim_bytes: cumulative number of reclaimed bytes;reclaim_errors: cumulative number of reclamation errors.
You can also view transaction commit statistics:
|
|
If max_commit_ms lasts for tens or hundreds of seconds, or the log appears again:
|
|
You should stop the backup task and save the log, do not continue to pour data and wait for it to recover on its own.
Disable backup tasks from overlapping
All rsnapshot cycles use the same lock:
|
|
weekly and monthly also use:
|
|
This can avoid daily, weekly, monthly and a large number of rsync being performed at the same time. Scrubs, mass deletes, and large copies should also be scheduled for different time periods.
Second failure: transaction aborted and forced read-only
After the first failed restart, the file system can be mounted normally and there are no errors in device stats. But when writing a large amount of data again later, a more explicit transaction failure occurred:
|
|
The operating environment is still:
|
|
This time it is not “temporarily stuck”, but the transaction has been aborted, and the kernel actively switches to read-only to protect the file system. -11 corresponds to EAGAIN, but the specific code that triggers it cannot be determined based on errno alone.
The device statistics at that time were still all 0:
|
|
The space status is not full:
|
|
This set of evidence favors zoned Btrfs internal write, chunk allocation, or transaction logic anomalies rather than ordinary media I/O errors or disk-wide ENOSPC. However, without a complete analysis of the first error and the corresponding source code, the cause should not be asserted to be a certain patch.
Correct handling after forced readonly
Don’t try:
|
|
Stop the writing task first:
|
|
Save complete logs before and after the failure. The first error that actually causes the transaction to abort may appear dozens of lines before forced readonly:
|
|
Confirm mount options:
|
|
ro should appear there. Then uninstall and restart normally:
|
|
If it prompts busy:
|
|
Stop the listed normal user processes before uninstalling.
Check for an incomplete copy
Part of the data that has been written before the transaction is aborted cannot be directly regarded as a complete backup. May appear:
- The file has not been created yet;
- The file length is incomplete;
- The data is written, but the directory entry or timestamp is not committed;
- Changes in the last transaction are rolled back.
Therefore the source disk must be retained. After switching to a stable environment and re-reading and writing the mount, use the original rsync to complete:
|
|
Then use the verification mode to verify:
|
|
No output means that rsync has not found anything that needs to be updated.
Kernel solution: first distinguish between testing and long-term use
The same machine, the same 7.0.0-28-generic, and the same HC620 have appeared continuously:
btrfs-cleaneris locked with the transaction thread;error -11, transaction aborted, forced readonly.
Therefore, we no longer continue to use this kernel to read and write terabytes of data to this disk. Three routes were discussed:
| Option | Purpose | Limitations |
|---|---|---|
| Ubuntu 26.04 + 7.1 Mainline | Determine whether the new upstream kernel mitigates the fault | Non-Ubuntu production support kernel, specific fixes are not confirmed |
| Ubuntu 24.04 + 6.8 GA | Determine whether 7.0 introduces regression, long-term support is better | zoned Btrfs code is older |
| Ubuntu 24.04 + 6.17 | Short-term comparison test zone reclaim behavior | Support cycle is nearing the end, not suitable for long-term unattended operation |
The most important thing here is not to pursue the largest version number, but:
- Keep an old kernel that can be booted;
- Only do a one-time GRUB boot for the first time;
- Mount read-only first;
- Test step by step from 100 to 200GiB;
- “Write 3TB immediately after deleting 3TB” is no longer directly reproduced.
Confirmed on Ubuntu 24.04 6.8 GA
Do not mix Ubuntu 24.04 packages with existing Ubuntu 26.04. A safer way is to install Ubuntu Server 24.04 on another SSD and then mount the HC620 data disk for testing.
Install and keep the 6.8 GA metapackage:
|
|
Confirm system and kernel:
|
|
The key is that uname -r starts with 6.8., and do not hard-code a certain patch version permanently.
Query the current repository instead of copying the historical version of this article:
|
|
If testing targets GA 6.8, don’t let linux-generic-hwe-24.04 take the system back to another HWE core line.
Short term test on Ubuntu 24.04 6.17
First check whether the current repositories still provide and maintain the package:
|
|
After confirming that the package is still available, install it explicitly:
|
|
Confirmation document:
|
|
Only start once for the first time. The full version below must be replaced with the version actually installed on your machine:
|
|
Check after restarting:
|
|
The 24.04 Noble repository should not be added to Ubuntu 26.04 to force-install this kernel, otherwise it may introduce firmware, DKMS, initramfs and subsequent apt maintenance issues.
Boundaries when testing 7.1 Mainline
The Mainline package is suitable for verifying “whether the new upstream kernel changes the fault behavior” and is not equivalent to the official Ubuntu production kernel. Must check before installation:
|
|
Testing risk increases significantly if Secure Boot is enabled, critical DKMS modules are present, or the server does not have an out-of-band console. The specific version, file name and check value should be re-obtained from the current Ubuntu Mainline Kernel Archive, and expired download addresses should not be copied.
Keep the current bootable kernel and boot the new kernel all at once via GRUB. Check after startup:
|
|
First mounting and testing of the new kernel
Whether testing 6.8, 6.17 or updating the kernel, first keep noauto in /etc/fstab and mount it read-only after startup:
|
|
After no new errors:
|
|
Step by step test:
|
|
Just because a small batch passed doesn’t immediately mean it’s “fixed” with terabytes of pressure. At the very least, multiple rounds, large amounts of data, and long run times are required to improve confidence.
Whether to reformat Btrfs
Reformatting can result in a clean file system, but it cannot fix kernel zoned path problems alone. Both exceptions occurred in the block-group, zone and transaction path at runtime, and the device stats had no media errors.
Rebuilding the file system only makes sense when:
btrfs check --readonlyAn explicit structural error was found;- scrub continues to have irreparable verification errors;
- Unable to mount normally or generation errors continue to occur;
- It has been decided to adjust the data/metadata profile;
- Prepare to replace the file system.
Even if you want to rebuild, complete another verifiable backup first rather than treating formatting as a trial-and-error command.
How to choose between Btrfs and F2FS
F2FS can bypass the Btrfs-specific calling path that appears this time:
|
|
But it’s not a “problem-free” solution. F2FS also has risks in GC, segment migration, zone reset, power failure recovery and file system repair. Long foreground GC delays may still occur with large writes immediately following large deletes.
The main trade-offs between the two are:
| Feature | Btrfs zoned | F2FS |
|---|---|---|
| File data checksum | Yes | Usually no equivalent end-to-end data checksum |
| scrub | yes | no Btrfs style scrub |
| Snapshots | Yes | No Btrfs-style snapshots |
| This fault path | has actually been triggered twice | Btrfs-specific paths can be avoided |
| Background space reclamation | block group/zone reclaim | segment GC/zone reset |
If the HC620 is only one of multiple backups, F2FS plus external parity is acceptable. Neither using single-disk Btrfs nor F2FS is safe enough if it’s the only copy.
You can save the SHA256 list to another disk when using F2FS:
|
|
Verify later:
|
|
The drive’s own ECC, bad sector remapping, and SATA CRC will still work, but they won’t cover the complete end-to-end link between applications, memory, file systems, controllers, and disks. Btrfs checksum and hard disk ECC are complementary, not duplicate functions.
Practical rules from this incident
This troubleshooting resulted in the following practical rules:
- No longer use
7.0.0-28-genericto do large-scale reading and writing of this HC620; - Retain the source data and at least one independent copy;
- Copy and verify first, then delete in batches;
- Divide several TB operations into batches of 200~500GiB;
- rsync, rsnapshot, scrub, mass deletion and balance do not overlap;
- Stop writing immediately after the
Dstatus or hung-task log appears; - Do not force remount,rw after forced readonly;
- Do not use
btrfs check --repairto make blind attempts; - The test kernel must retain the rollback items and start with a read-only mount;
- Long-term reliability comes from multiple copies first and file system selection second.
The entire fault chain can be summarized as:
|
|
This set of results is enough to show that the current “HC620 + Btrfs zoned + 7.0.0-28 + CLOS” combination is not suitable for continuing large-scale unattended tasks, but it is not enough to prove that all HC620s, all Btrfs zoned, or all 7.0 kernels have the same problem.