<feed xmlns='http://www.w3.org/2005/Atom'>
<title>fstools, branch master</title>
<subtitle>OpenWrt filesystem utilities</subtitle>
<id>https://git.openwrt.org/project/fstools/atom?h=master</id>
<link rel='self' href='https://git.openwrt.org/project/fstools/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/fstools/'/>
<updated>2026-07-25T13:59:17Z</updated>
<entry>
<title>block: preen a registered volume before mount on request</title>
<updated>2026-07-25T13:59:17Z</updated>
<author>
<name>Daniel Golle</name>
</author>
<published>2026-06-14T17:29:47Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/fstools/commit/?id=2aa16407fdedb3f1e1b915879f4d6772c5fe896c'/>
<id>urn:sha1:2aa16407fdedb3f1e1b915879f4d6772c5fe896c</id>
<content type='text'>
blockd gains an optional check_fs attribute on the hotplug registration. When
set, the autofs mount path runs the filesystem's preen check (e2fsck -p,
fsck.f2fs -a) before mounting, so a volume left dirty by power loss is repaired
instead of mounted read-only or refused. The check self-gates: a clean fs is a
no-op. Plain fstab mounts keep the global check_fs; the per-mount attribute lets
blockd-managed volumes (e.g. uvol) opt in without an fstab section, and does not
touch unrelated autofs mounts.

blockd hands the attribute down as a check_fs token appended to the mount
options of "block autofs add". parse_mount_options() consumes the token like a
flag, so it never reaches mount(2), and as a side effect an fstab section can
now request the check per mount using 'option options check_fs' as well.

Signed-off-by: Daniel Golle &lt;daniel@makrotopia.org&gt;
</content>
</entry>
<entry>
<title>block: use preen mode for the f2fs filesystem check</title>
<updated>2026-07-25T13:59:17Z</updated>
<author>
<name>Daniel Golle</name>
</author>
<published>2026-07-25T13:39:27Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/fstools/commit/?id=d43ffbaba77c3c933a1bf1d8c54509a3e745f833'/>
<id>urn:sha1:d43ffbaba77c3c933a1bf1d8c54509a3e745f833</id>
<content type='text'>
check_fs is meant to express "repair the volume if it is dirty", which is what
the other filesystems get: e2fsck -p leaves a clean volume untouched. fsck.f2fs
-f instead forces a full check of the volume on every single mount, which is
expensive on large volumes and needlessly delays boot.

Use fsck.f2fs -a, which self-gates on the dirty flag just like e2fsck -p.

Signed-off-by: Daniel Golle &lt;daniel@makrotopia.org&gt;
</content>
</entry>
<entry>
<title>blockd: do not let a slow startup helper hold back readiness</title>
<updated>2026-07-25T13:59:17Z</updated>
<author>
<name>Daniel Golle</name>
</author>
<published>2026-07-25T13:57:49Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/fstools/commit/?id=a71e97d7194c8392dbaaff821ec1eac6e74a4dec'/>
<id>urn:sha1:a71e97d7194c8392dbaaff821ec1eac6e74a4dec</id>
<content type='text'>
Readiness is currently announced only once the last coldplug helper has exited.
A single helper can take arbitrarily long, most notably when it runs fsck on a
large volume, and it must not be interrupted: aborting a repair halfway through
leaves the volume in a worse state than not mounting it at all. Until then no
mount.ready is sent and the status method keeps reporting false, so every
consumer is back to guessing with a timeout of its own.

Arm a 10s timer at startup and latch readiness when it expires, leaving the
remaining helpers running. The devices they register still emit their own
notifications, so a consumer waiting for one specific volume can wait for that
instead of for a level which may be minutes away.

Signed-off-by: Daniel Golle &lt;daniel@makrotopia.org&gt;
</content>
</entry>
<entry>
<title>blockd: expose storage readiness via a queryable status method</title>
<updated>2026-07-25T13:56:46Z</updated>
<author>
<name>Daniel Golle</name>
</author>
<published>2026-06-07T14:39:29Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/fstools/commit/?id=1c17d24d1f469368cf87e42265ff32be0c5c1449'/>
<id>urn:sha1:1c17d24d1f469368cf87e42265ff32be0c5c1449</id>
<content type='text'>
Storage readiness is a level ("is storage available now?"), but blockd only
emitted it as an edge: a single mount.ready notification sent once the initial
coldplug settles. A subscriber that connects after that notification fired
never learns that storage is ready and falls back to a timeout.

Track readiness in a blockd_ready latch and expose it via a no-arg "status"
method returning { "ready": &lt;bool&gt; }, and add the same field to the no-device
"info" reply. Consumers can then subscribe and query the current level instead
of having to catch the one-shot notification at the right moment. mount.ready
stays as a lightweight "something changed, re-query me" hint.

Signed-off-by: Daniel Golle &lt;daniel@makrotopia.org&gt;
</content>
</entry>
<entry>
<title>blockd: pass registrant mount options down to block on autofs mount</title>
<updated>2026-07-25T13:56:18Z</updated>
<author>
<name>Daniel Golle</name>
</author>
<published>2026-06-07T14:21:32Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/fstools/commit/?id=f60b3a35770c0e93720a280e9f9cdad189b9e5b6'/>
<id>urn:sha1:f60b3a35770c0e93720a280e9f9cdad189b9e5b6</id>
<content type='text'>
A runtime volume registered over the block.hotplug ubus call carries no
fstab entry, so block had no way to learn how it should be mounted and
fell back to read-write. A read-only backing store (e.g. a squashfs or
erofs uvol volume, or an ext4 volume registered read-only) then failed
to mount with EACCES.

Keep the declared options with the device in blockd and hand them to
"block autofs add" as a fourth argument when the kernel requests the
mount. block applies them to the synthesised runtime mount via
parse_mount_options, so "options":"ro" mounts the volume read-only
without block or blockd ever inspecting the filesystem type.

Signed-off-by: Daniel Golle &lt;daniel@makrotopia.org&gt;
</content>
</entry>
<entry>
<title>blockd: notify when an idle autofs mount is unmounted</title>
<updated>2026-07-25T13:56:18Z</updated>
<author>
<name>Daniel Golle</name>
</author>
<published>2026-06-03T01:49:21Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/fstools/commit/?id=998f6abe257502afc03eaa6cee216944d62ef652'/>
<id>urn:sha1:998f6abe257502afc03eaa6cee216944d62ef652</id>
<content type='text'>
autofs_expire() tears down idle mounts (the holder is gone), after which the
backing block device has no remaining holder. Emit a mount.umount notification
with the device name so subscribers can act on the device becoming free - e.g.
uvol's deferred reap of a volume that was still in use when removal was
requested.

Signed-off-by: Daniel Golle &lt;daniel@makrotopia.org&gt;
</content>
</entry>
<entry>
<title>block: mount ubus-registered devices without an fstab entry</title>
<updated>2026-07-25T13:56:18Z</updated>
<author>
<name>Daniel Golle</name>
</author>
<published>2026-06-01T23:38:43Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/fstools/commit/?id=0008996709f246ae701c56d70832d10933eb13c0'/>
<id>urn:sha1:0008996709f246ae701c56d70832d10933eb13c0</id>
<content type='text'>
Devices injected into blockd at runtime over ubus (for example by uvol,
which derives its volumes from the self-describing LVM/UBI backing store
rather than from persistent UCI) have no matching section in
/etc/config/fstab. mount_device() looked the device up via find_block()
and, finding nothing, fell through to anon-mount or skipped it entirely,
so such a device never mounted at its registered target.

The autofs trigger only fires for devices blockd has registered for
autofs, so its presence is sufficient proof that a runtime registration
exists. Synthesise a minimal autofs mount in that case and let the
regular autofs path mount the device at /tmp/run/blockd/&lt;device&gt;, which
blockd's symlink already exposes at the requested target. This lets a
volume be mounted purely over ubus, with no persistent fstab state.

Signed-off-by: Daniel Golle &lt;daniel@makrotopia.org&gt;
</content>
</entry>
<entry>
<title>blockd: coldplug block devices</title>
<updated>2026-07-25T13:56:18Z</updated>
<author>
<name>Daniel Golle</name>
</author>
<published>2024-06-14T01:38:53Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/fstools/commit/?id=4fd15022aaf4dfc2ab410bc89e1ba164989fd465'/>
<id>urn:sha1:4fd15022aaf4dfc2ab410bc89e1ba164989fd465</id>
<content type='text'>
blockd may be started after the hotplug scripts of already attached storage
devices have run, leaving those devices unregistered. Call 'block hotplug' for
each of them when blockd starts (ie. coldplug).

Do not wait for the helpers synchronously: block's autofs and hotplug actions
call back into blockd over ubus with a 3s timeout, so blocking the main loop
would make every child time out before it can register anything. Reap them via
uloop and start the next one from the previous one's callback, so the loop stays
alive while at most one helper runs at a time. Serialising them keeps the mount
order deterministic where two devices resolve to the same target, and avoids
spawning one blkid probe per block device at once on a low-memory system.

Announce readiness once the last helper has finished, so the coldplugged device
list is complete before subscribers re-register.

Signed-off-by: Daniel Golle &lt;daniel@makrotopia.org&gt;
</content>
</entry>
<entry>
<title>blockd: retry interrupted waitpid() in synchronous block() helper</title>
<updated>2026-07-25T13:55:08Z</updated>
<author>
<name>Daniel Golle</name>
</author>
<published>2026-06-02T11:44:40Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/fstools/commit/?id=89a6f529d580657d8d92db930690c026f7f49016'/>
<id>urn:sha1:89a6f529d580657d8d92db930690c026f7f49016</id>
<content type='text'>
The synchronous variant of block() reads WEXITSTATUS(status) straight
after waitpid(), but waitpid() may be interrupted by SIGCHLD from one of
the asynchronous hotplug-call children, returning -1 with errno EINTR and
leaving status untouched. The garbage status was then decoded as a
non-zero exit code (typically 127), so a perfectly successful
"block autofs add" was reported as a failure and the autofs request was
answered with AUTOFS_IOC_FAIL. The kernel then denied access to a volume
that had in fact just been mounted, which surfaced as intermittent
first-access failures on freshly registered uvol volumes.

Retry waitpid() on EINTR and initialise status so the child's real exit
code is used.

Signed-off-by: Daniel Golle &lt;daniel@makrotopia.org&gt;
</content>
</entry>
<entry>
<title>blockd: fix bounds of the ubus event name buffer</title>
<updated>2026-07-25T13:55:08Z</updated>
<author>
<name>Daniel Golle</name>
</author>
<published>2026-07-25T13:55:08Z</published>
<link rel='alternate' type='text/html' href='https://git.openwrt.org/project/fstools/commit/?id=37cf94d22cdb00146f403627e81270c67257c88d'/>
<id>urn:sha1:37cf94d22cdb00146f403627e81270c67257c88d</id>
<content type='text'>
The third argument of strncat() is the space left in the destination, not the
size of the destination. Passing sizeof(evname) - 1 allows up to 15 bytes plus
a terminator to be appended behind the "mount." prefix, ie. up to 22 bytes in a
16 byte buffer. No caller passes an action long enough to overflow it today,
which is why this has not been noticed, but the bound is wrong.

Build the event name with a single snprintf() instead, which cannot write past
the end of the buffer regardless of the action.

Signed-off-by: Daniel Golle &lt;daniel@makrotopia.org&gt;
</content>
</entry>
</feed>
