Parent epic: #345
Motivation
Core/Source/SolidSyslogFileBlockDevice.c caches a readHandle and a writeHandle,
each wrapping a SolidSyslogFile* open across calls. In steady-state Read↔Write
alternation on the same block (the BlockStore pattern: write record → read record →
write sent flag) both handles end up open on the same file path simultaneously.
Most platforms tolerate this; FatFs does not without FF_FS_LOCK ≥ 4, which is why
bfaa39c had to flip it on. That's a workaround. The cleaner invariant — and the
one E27 should pin down for the storage layer — is at most one SolidSyslogFile*
open on any given block file path at any moment, by construction.
This is foundational for any block-device driver where a logical block is a
single-handle resource (FatFs with default FS_LOCK, several embedded flash
filesystems, future S18.04 flash example). It also removes the duplicate-handle
attack surface from the reentrancy audit's table before the audit happens.
Invariant
Across all SolidSyslogFile instances, at most one is open on any given block
file path at any moment.
Acceptance
SolidSyslogFileBlockDevice keeps a single cached open handle. Same-block runs
(multi-Append, drain Reads, Append-then-WriteAt) keep the handle open — the
performance shape of the current dual-handle design is preserved for runs.
- The invariant is enforced at test time:
FileFake trips a clear test assertion
if a path is opened while another instance still has it open.
- All existing Linux/Windows unit tests stay green. All existing Linux/Windows
BDD scenarios stay green.
SolidSyslogStore's public contract is unchanged. The change to
SolidSyslogFileBlockDevice_Create's signature (one SolidSyslogFile* rather
than two) is the only public-API change; integrator code under
Bdd/Targets/{Linux,Windows}/ is updated in lockstep.
Out of scope
- FatFs /
FS_LOCK retuning — that's the downstream beneficiary (S08.05 slice 6),
not this story.
- The wider E27 audit doc.
- Reentrancy concerns outside the store layer (Switching sender currentIndex,
callback contracts, error handler slot) — separate child stories of E27.
Parent epic: #345
Motivation
Core/Source/SolidSyslogFileBlockDevice.ccaches areadHandleand awriteHandle,each wrapping a
SolidSyslogFile*open across calls. In steady-state Read↔Writealternation on the same block (the BlockStore pattern: write record → read record →
write sent flag) both handles end up open on the same file path simultaneously.
Most platforms tolerate this; FatFs does not without
FF_FS_LOCK ≥ 4, which is whybfaa39chad to flip it on. That's a workaround. The cleaner invariant — and theone E27 should pin down for the storage layer — is at most one
SolidSyslogFile*open on any given block file path at any moment, by construction.
This is foundational for any block-device driver where a logical block is a
single-handle resource (FatFs with default
FS_LOCK, several embedded flashfilesystems, future S18.04 flash example). It also removes the duplicate-handle
attack surface from the reentrancy audit's table before the audit happens.
Invariant
Acceptance
SolidSyslogFileBlockDevicekeeps a single cached open handle. Same-block runs(multi-Append, drain Reads, Append-then-WriteAt) keep the handle open — the
performance shape of the current dual-handle design is preserved for runs.
FileFaketrips a clear test assertionif a path is opened while another instance still has it open.
BDD scenarios stay green.
SolidSyslogStore's public contract is unchanged. The change toSolidSyslogFileBlockDevice_Create's signature (oneSolidSyslogFile*ratherthan two) is the only public-API change; integrator code under
Bdd/Targets/{Linux,Windows}/is updated in lockstep.Out of scope
FS_LOCKretuning — that's the downstream beneficiary (S08.05 slice 6),not this story.
callback contracts, error handler slot) — separate child stories of E27.