ext4 Filesystem
This example puts an ext4 filesystem on the volume served by flexblock@nvme1n1p1.service and mounts it at /mnt/archive. The unit is the same shape as the XFS one; only formatting, growth and the discard choice differ. It assumes the systemd service is installed and its environment file pins --ublk-dev-id 0, so the device is /dev/ublkb0.
Format
Section titled “Format”Format once, with the service running:
sudo systemctl daemon-reloadsudo systemctl enable --now flexblock@nvme1n1p1.servicesudo mkfs.ext4 -E lazy_itable_init=0 /dev/ublkb0-E lazy_itable_init=0 disables lazy inode table initialization. Inode tables are then zeroed during mkfs, instead of by a kernel thread in the background after the first mount, while the volume is already serving.
Install as /etc/systemd/system/mnt-archive.mount (the escaped form of /mnt/archive):
[Unit]Description=flexBlock archive volumeRequires=flexblock@nvme1n1p1.serviceAfter=flexblock@nvme1n1p1.service
[Mount]What=/dev/ublkb0Where=/mnt/archiveType=ext4Options=noatime,errors=remount-ro,_netdev
[Install]WantedBy=multi-user.targetsudo systemctl daemon-reloadsudo systemctl enable --now mnt-archive.mountAlso add the device timeout drop-in for dev-ublkb0.device. _netdev is required here for the same reason as with XFS.
/dev/ublkb0 /mnt/archive ext4 noatime,errors=remount-ro,nofail,_netdev,x-systemd.requires=flexblock@nvme1n1p1.service,x-systemd.after=flexblock@nvme1n1p1.service,x-systemd.device-timeout=30min 0 0The final field, the fsck pass, is 0, so boot does not run a full check across a cold cache, which would read all of the filesystem’s metadata from the bucket. ext4 replays its journal at mount regardless.
Discard or fstrim.timer
Section titled “Discard or fstrim.timer”This example does not mount with discard. It relies on the periodic fstrim.timer instead:
sudo systemctl enable --now fstrim.timerReturning freed space to flexBlock matters more on a write-back cached volume than on a plain SSD, because freed space that flexBlock does not know about still gets uploaded, stored and sometimes fetched back. Both approaches work; they trade bucket load against wasted transfers.
discard mount option | fstrim.timer | |
|---|---|---|
| When freed space is returned | As the filesystem frees it | In periodic batches |
| Load on the bucket | Deletes as they happen | Batched deletes, lighter on a busy bucket |
| A dirty chunk freed in full | Dropped; never uploaded | Still uploaded if it is flushed before the next trim |
| Reusing a fully freed chunk that has left the cache | No fetch: the chunk has no object anymore | Can cost a chunk fetch from the bucket, usually at its next flush, unless new writes cover the whole chunk |
A few details hold either way:
- Reusing a freed chunk that is still in the cache is cheap.
- A chunk freed only in part keeps its object. Freeing part of a chunk that has left the cache brings it back dirty, and costs a fetch and an upload at its next flush.
Choose discard (as the XFS example does) when you want the leanest uploads and fewest fetches. Choose fstrim.timer when a busy bucket benefits from batched deletes.
Growing
Section titled “Growing”- After a live grow with
update --device-size, just runsudo resize2fs /dev/ublkb0. - After an offline grow, start the service and mount, then run
sudo resize2fs /dev/ublkb0.
See Growing a Volume.