mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC] btrfs: zoned: reset stale zones in unallocated device space
@ 2026-10-27  8:36 Марк Коренберг
  2026-10-27 10:27 ` Johannes Thumshirn
  0 siblings, 1 reply; 4+ messages in thread
From: Марк Коренберг @ 2026-10-27  8:36 UTC (permalink / raw)
  To: David Sterba, Chris Mason, linux-btrfs, linux-kernel

Hi,

I'd like to propose a feature for zoned btrfs. I'm not planning to
implement it myself, but I'd like to get feedback and, if the idea is
considered reasonable, have it tracked as a TODO / project idea.

Background
----------
I maintain a host-managed zoned block device implemented with ublk,
where each zone is backed by S3 objects. Storage cost is proportional
to the amount of data actually held in zones, so zones that contain
data but are not referenced by the filesystem are a real cost, not
just lost capacity.

Problem
-------
With a long commit interval (e.g. commit=300) and heavy buffered
writes, btrfs may allocate new block groups and write a large amount
of data into their zones before the transaction commits. If the
filesystem then goes down uncleanly before the commit, this is fine
from a consistency point of view: nobody called fsync(), and after
the next mount the filesystem is consistent at the last committed
transaction.

For a virtual device like mine, "goes down uncleanly" is more likely
the ublk server crashing or losing connectivity to S3 than an actual
power loss, but the effect on btrfs is the same: the running
transaction never commits.

The device extents of those new block groups were never persisted, so
after the next mount the corresponding zones belong to unallocated
device space from btrfs' point of view, while on the device they are
still non-empty (write pointer > zone start) and hold data.

As far as I can tell, btrfs currently handles this lazily: such zones
are reset only when the allocator picks that range for a new chunk
(btrfs_ensure_empty_zones()). Until then they hold stale data
indefinitely. On SMR HDDs this does not matter much, but on ZNS SSDs
(where a reset helps the device's internal GC) and especially on
virtual/cloud-backed zoned devices it does.

(Stale data past the committed alloc_offset inside *existing* block
groups is accounted as zone_unusable and can only be reclaimed via
relocation; this proposal does not try to address that case.)

Current workaround
------------------
The only safe way I see today is offline: unmount, walk the dev tree
to collect allocated dev extents, and issue BLKRESETZONE for every
non-empty sequential zone not covered by a dev extent. Doing this on
a mounted filesystem from userspace is unsafe, because it races with
chunk allocation (a dev extent may be allocated in the running
transaction but not yet visible in the committed dev tree).

Proposal
--------
Let the kernel do it, since it can serialize against chunk allocation
(chunk_mutex / device->alloc_state). The operation itself: reset
every sequential zone that is fully contained in unallocated device
space and whose write pointer is not at the zone start.

Possible interfaces, in order of my preference:

 1. Automatic background cleanup, e.g. once after mount (after the
    dev extents are loaded) and/or as part of the existing
    reclaim/discard workers, possibly behind a mount option or sysfs
    knob. This requires no administrator action and covers the
    problem completely.

 2. FITRIM: on zoned filesystems, apply the reset to unallocated
    device space as part of fstrim. Many distributions already run
    fstrim periodically (fstrim.timer), so this would also work
    without extra configuration in most setups, and it fits the
    "release unused space to the device" semantics.

 3. A dedicated trigger: a new ioctl (exposed as a btrfs-progs
    subcommand) or a sysfs knob under /sys/fs/btrfs/<UUID>/ that
    starts the cleanup on demand. Least convenient, but still much
    better than the current offline-only workaround.

Risk
----
With corrupted metadata (a dev extent missing from the dev tree),
this could reset a zone that actually holds live data. But the
allocator already makes exactly the same assumption today when it
resets non-empty zones before reusing them, so this does not add a
new class of risk; it only performs the reset earlier. If automatic
cleanup is considered too aggressive, options 2 and 3 are explicit
and opt-in.

Questions
---------
 - Does this sound like something you would accept upstream?
 - Which interface would you prefer?
 - Am I missing a reason why the reset is intentionally deferred to
   allocation time?

If the idea is acceptable, I'd appreciate it being added to the btrfs
TODO list so that someone interested could pick it up.

Thanks,
Korenberg Mark

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-27 15:06 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-27  8:36 [RFC] btrfs: zoned: reset stale zones in unallocated device space Марк Коренберг
2026-10-27 10:27 ` Johannes Thumshirn
2026-10-27 14:48   ` Марк Коренберг
2026-10-27 15:05     ` Johannes Thumshirn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®