Since version 5.12 btrfs supports zoned mode. This is a special on-disk format and allocation/write strategy that's friendly to zoned devices. In short, a device is partitioned into fixed-size zones and each zone can be updated by append-only manner, or reset. As btrfs has no fixed data structures, except the super blocks, the zoned mode only requires block placement that follows the device constraints. You can learn about the whole architecture at https://zonedstorage.io.
Because of the append-only write, several btrfs features are not supported:
- nodatacow -- overwrite in-place
- fallocate -- preallocating space for in-place first write
- mixed-bg -- unordered writes to data and metadata
- booting -- resetting the first zone after superblock rotation would remove the boot loader data
The above is really incompatible because it expects an in-place write at some point. There are some features that are not part of the first implementation but is planned to be implemented in the future:
- only 'single' profile works, TBD: synchronize zone write pointers among the block groups
- fitrim, TBD: do not depend on free space cache
Creating a zoned filesystem needs btrfs-progs 5.12. Proper detection of zoned devices with btrfs needs util-linux 2.37+ (not yet released).
The WD Ultrastar series 600 advertises HM-SMR, ie. the host-managed zoned mode. There are two more: DA (device managed, no zoned information exported to the system), HA (host aware, can be used as regular disk but zoned writes improve performance). There are not many devices available at the moment, the information about exact zoned mode is hard to find, check data sheets or community sources gathering information from real devices.
The driver null_blk provides memory backed device and is suitable for testing. There are some quirks setting up the devices. The module must be loaded with nr_devices=0 or the numbering of device nodes will be offset. The configfs must be mounted at /sys/kernel/config and the administration of the null_blk devices is done in /sys/kernel/config/nullb. The device nodes are named like /dev/nullb0 and are numbered sequentially. NOTE: the device name may be different than the named directory in sysfs!
modprobe configfs modprobe null_blk nr_devices=0
Create a device mydev, assuming no other previously created devices, size is 2048MiB, zone size 256MiB. There are more tunable parameters, this is a minimal example taking defaults:
cd /sys/kernel/config/nullb/ mkdir mydev cd mydev echo 2048 > size echo 1 > zoned echo 1 > memory_backed echo 256 > zone_size echo 1 > power
This will create a device /dev/nullb0 and the value of file index will match the ending number of the device node.
Remove the device:
Then continue with mkfs.btrfs /dev/nullb0, the zoned mode is auto-detected.
For convenience, there's a script wrapping the basic null_blk management operations https://github.com/kdave/nullb.git
- the feature sets an incompat bit and requires new kernel to access the filesystem (for both read and write)
- superblock needs to be handled in a special way, there are still 3 copies but at different offsets (0, 512GiB, 4TiB) and the 2 consecutive zones are a ring buffer of the superblocks, finding the latest one needs read it from the write pointer or do a full scan of the zones
- mixing zoned and non zoned devices is possible (zones are emulated) but is recommended only for testing
- mixing zoned devices with different zone sizes is not possible
- zone sizes must be power of two, zone sizes of real devices are eg. 256MiB or 1GiB, larger size is expected, maximum zone size supported by btrfs is 8GiB
Status, stability, reporting bugs
The zoned mode has been released in 5.12 and there are still some rough edges and corner cases one can hit during testing. Please report bugs to https://github.com/naota/linux/issues/ .
- https://hddscan.com/blog/2020/hdd-wd-smr.html -- some details about exact device types
- https://lwn.net/Articles/853308/ -- Btrfs on zoned block devices