Skip to content

S27.01: FileBlockDevice keeps at most one open handle per path #353

Description

@DavidCozens

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    storyStory issue

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions