Filesystem Settings
A flexBlock device is an ordinary Linux block device, so any filesystem works on it. A few settings matter more than usual, because the volume sits behind a write-back cache and its cold data lives in object storage.
Format time
Section titled “Format time”ext4 lazy initialization
Section titled “ext4 lazy initialization”Format ext4 with lazy inode table initialization turned off:
sudo mkfs.ext4 -E lazy_itable_init=0 /dev/ublkb0Otherwise the kernel zeroes inode tables in the background after the first mount, while the volume is already serving.
Logical block size
Section titled “Logical block size”| Command | Flag | Default | Meaning |
|---|---|---|---|
init | --logical-block-size <512|4096> | 4096 | Advertised block size. Fixed for the volume’s life. |
With 4096, the kernel aligns and splits guest I/O on page boundaries. Choose 512 only for software that insists on it; sub-page I/O is served buffered.
Mount options
Section titled “Mount options”discard or fstrim.timer
Section titled “discard or fstrim.timer”Returning freed space matters more on a write-back-cached volume than on a plain SSD.
| Approach | Behavior |
|---|---|
discard mount option | Every extent a delete frees is applied as it happens. A dirty chunk whose pages are all freed is dropped before it is ever uploaded, and its object is deleted. A fully freed chunk that has left the cache is not fetched back from object storage when its space is reused, because it no longer has an object. |
fstrim.timer | Batches the deletes and is lighter on a busy bucket. But between trims, deleted data that was dirty is still uploaded, and space reused after the chunk left the cache pays a chunk fetch, usually at its next flush, unless the new writes cover the whole chunk. |
While a freed chunk is still in the cache, reusing it is cheap either way. A chunk freed only in part keeps its object, though freeing part of an evicted chunk brings it back dirty and costs a fetch and an upload at its next flush.
The XFS example mounts with discard; the ext4 example relies on fstrim.timer:
sudo systemctl enable --now fstrim.timerfsck at boot
Section titled “fsck at boot”Set the fsck pass (the last fstab field) to 0. A full check on a cold cache reads all of the filesystem’s metadata from the bucket. ext4 still replays its journal at mount.
Read-ahead
Section titled “Read-ahead”| Flag | Default | Meaning |
|---|---|---|
--read-ahead <SIZE> | 32M | Kernel read-ahead for the exported device, a whole number of KiB and of logical blocks, up to 64M. 0 disables. |
The default is 32 MiB whatever the chunk size, so buffered sequential readers pull whole chunks instead of making a round trip per page. For cold sequential reads, flexBlock also prefetches chunks itself; see Sequential prefetch.
Kernel writeback throttling
Section titled “Kernel writeback throttling”The kernel’s writeback throttling (wbt_lat_usec, 2 ms on SSD-class devices) stays at its default, because it keeps reads fast while buffered writers are busy.
With the cache saturated and completions taking hundreds of milliseconds, though, it can hold buffered writeback, fsync and the journal to a trickle for minutes while direct I/O proceeds. For such mixed workloads, write 0 after each start:
echo 0 | sudo tee /sys/block/ublkb0/queue/wbt_lat_usecThis keeps writeback steady at the cost of read latency under buffered writes.
Other filesystems and layers
Section titled “Other filesystems and layers”- btrfs, OpenZFS and LUKS work on the device as on any other. LVM and mdadm work too. Close LUKS, LVM and md mappings before stopping the daemon, since it refuses to stop while device-mapper or another kernel user holds the device.
- ZFS pools. ublk devices have no
/dev/disk/by-identries, so import a ZFS pool withzpool import -d /dev.