What beamfs protects and how, its runtime interfaces (module parameters, sysfs, uevents, debugfs, tracepoints), its userspace tools and its known limitations. Documentation/ABI/testing/sysfs-fs-beamfs describes the attributes under /sys/fs/beamfs// and the uevent raised there. Assisted-by: LLM Signed-off-by: Aurelien DESBRIERES --- Documentation/ABI/testing/sysfs-fs-beamfs | 88 ++++++++++ Documentation/filesystems/beamfs.rst | 197 ++++++++++++++++++++++ Documentation/filesystems/index.rst | 1 + 3 files changed, 286 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-fs-beamfs create mode 100644 Documentation/filesystems/beamfs.rst diff --git a/Documentation/ABI/testing/sysfs-fs-beamfs b/Documentation/ABI/testing/sysfs-fs-beamfs new file mode 100644 index 000000000000..d59b96239a9a --- /dev/null +++ b/Documentation/ABI/testing/sysfs-fs-beamfs @@ -0,0 +1,88 @@ +What: /sys/fs/beamfs// +Date: October 2026 +Contact: Aurelien DESBRIERES +Description: One directory per mounted beamfs volume, named after the + block device, holding the scrubber's controls and counters + and the volume's clock anchor. The counters are kept since + the mount. + + A KOBJ_CHANGE uevent is raised on this directory, at most + once a minute per reason, with the variables BEAMFS_ALERT=1, + BEAMFS_REASON= and BEAMFS_DETAIL=; the reasons + are "uncorrectable" (a block could not be recovered), + "no-margin" (a block whose worst codeword has no correction + left) and "correction-rate" (more blocks corrected in one + sweep than alert_rate_limit allows). + +What: /sys/fs/beamfs//interval +Date: October 2026 +Contact: Aurelien DESBRIERES +Description: (RW) Milliseconds the scrubber waits between two blocks of + this volume. Writing it sets the pace the scrubber returns + to when nothing is wrong, and the pacing only tightens from + there. 0 parks the scrubber; correction on read is not + affected. The value a volume starts with is the module + parameter scrub_interval_ms. + +What: /sys/fs/beamfs//cursor +Date: October 2026 +Contact: Aurelien DESBRIERES +Description: (RO) Where the sweep is, as a physical block number. + +What: /sys/fs/beamfs//passes +Date: October 2026 +Contact: Aurelien DESBRIERES +Description: (RO) Complete sweeps of the volume since the mount. + +What: /sys/fs/beamfs//blocks +Date: October 2026 +Contact: Aurelien DESBRIERES +Description: (RO) Blocks the scrubber has read since the mount. + +What: /sys/fs/beamfs//corrected +Date: October 2026 +Contact: Aurelien DESBRIERES +Description: (RO) Blocks the scrubber corrected and wrote back since + the mount. + +What: /sys/fs/beamfs//uncorrectable +Date: October 2026 +Contact: Aurelien DESBRIERES +Description: (RO) Blocks with a codeword the scrubber could not correct + since the mount. + +What: /sys/fs/beamfs//error_budget +Date: October 2026 +Contact: Aurelien DESBRIERES +Description: (RO) How much correction capacity the volume has left: one + line per wear level, " ", the number of + blocks whose worst codeword has needed that many + corrections, from 0 (untouched) to 8 (no correction left). + Reading walks the volume's budget region, which is a cost + paid on request rather than a counter kept in memory. + "disabled" on a volume formatted without a budget region. + +What: /sys/fs/beamfs//clock_anchor +Date: October 2026 +Contact: Aurelien DESBRIERES +Description: (RO) What the two clocks read at the same instant, taken + once per sweep: "mono ", "real " and + "quality ", the worth of that wall + clock reading. A reader dating a journal entry needs all + three. + +What: /sys/fs/beamfs//scrub_pace +Date: October 2026 +Contact: Aurelien DESBRIERES +Description: (RO) The pacing of the scrubber: "interval_ms ", + "base_ms ", "factor ", + "corrected " and "wear_visits ". + +What: /sys/fs/beamfs//alert_rate_limit +Date: October 2026 +Contact: Aurelien DESBRIERES +Description: (RW) Blocks that may be corrected in one sweep before the + "correction-rate" uevent is raised. 0, the default, disables + the check: the right number depends on where the machine + sits. diff --git a/Documentation/filesystems/beamfs.rst b/Documentation/filesystems/beamfs.rst new file mode 100644 index 000000000000..7e5d6ca2d079 --- /dev/null +++ b/Documentation/filesystems/beamfs.rst @@ -0,0 +1,197 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +====== +beamfs +====== + +beamfs is a block-device filesystem that corrects corrupted bytes in +place, on a single device, with no second copy to repair from. File +data, directory blocks, inodes, the allocation bitmap and the +superblock carry Reed-Solomon parity, built on lib/reed_solomon, and +every read decodes. A read the decoder cannot vouch for fails with +``-EIO`` instead of returning wrong data. + +It is meant for systems that keep their data on one storage device in +a radiation environment: on-board computers in space, and equipment in +radiotherapy rooms, where high-energy photon beams and proton or ion +beams produce secondary neutrons that cause single-event upsets in +electronics [#tg203]_. + +beamfs protects the path between the medium and the page cache. It +does not protect memory after a read, and it does not replace ECC +memory or redundancy across devices; a beamfs volume can sit on a +mirror. + + +Data blocks +=========== + +The block size is 4096 bytes. A data block holds sixteen RS(255,239) +codewords over GF(2^8), primitive polynomial 0x187: 3824 coded bytes +and 256 bytes of parity, then a 16-byte tail. Each codeword corrects +up to eight corrupted bytes. In the default layout 288 bytes of every +4096 are overhead, 256 of parity, 16 of descriptor and 16 of +generation, which leaves 3808 bytes of file data per block. + +By default the symbols of the sixteen codewords are interleaved across +the block, so a burst in the coded bytes is spread over all of them. +The parity of each codeword stays together, so nine corrupted bytes in +the parity of one codeword are enough to defeat it. + +A read decodes every codeword of the block into a private copy. The +corrected bytes reach the page cache; the read does not write them +back to the medium. A codeword the decoder reports as uncorrectable +fails the read with ``-EIO``. + +Beyond eight corrupted bytes in a codeword, a Reed-Solomon decoder can +also land on a different valid codeword and report success. With the +``DATA_CSUM`` feature a CRC32 of the payload, stored in the block, is +checked after decoding, and such a read fails closed. ``DATA_CSUM`` +and ``DATA_SELFID`` are enabled together by ``mkfs.beamfs +--data-csum``; neither is on by default. + + +Metadata +======== + +The superblock carries a CRC32 and Reed-Solomon parity over the region +the CRC covers. It also holds the correction journal: a ring of 64 +events, each naming the block, the codeword and the number of symbols +corrected, with a monotonic timestamp. The ``raf-decode`` tool in the +beamfs repository decodes it. + +Each inode is one Reed-Solomon codeword, with a CRC32 that covers its +block pointers. Directory blocks carry sixteen codewords of inline +parity, as data blocks do, and hold variable-length entries. The block +allocation bitmap is Reed-Solomon protected. + +An indirect block is 512 little-endian 64-bit pointers and has no room +for parity. Its parity lives in a separate region, at a slot computed +from the block number; ``mkfs.beamfs -I`` chooses ``rs`` (the +default), ``crc`` or ``none``. In ``rs`` mode the parity detects and +journals a damaged indirect block but does not repair the buffer, +pointers 478 to 511 have no parity, and a pointer flipped onto another +allocated block is detected only with ``DATA_SELFID``. + + +Background scrubbing +==================== + +Correction happens on read, so a block nobody reads accumulates upsets +until it is past the correction radius. Each mounted volume runs a +kernel thread, ``beamfs-scrub/``, that walks the allocated blocks +at a bounded pace and decodes each one, so that drift is found while +it is still correctable. + +When the volume has an error budget, each data block also records the +largest number of symbols corrected in any of its codewords: how much +of its correction capacity it has used. + + +Using beamfs +============ + +The userspace tools are in https://github.com/roastercode/beamfs, +under ``tools/``:: + + mkfs.beamfs /dev/sdX + mount -t beamfs /dev/sdX /mnt + fsck.beamfs /dev/sdX + +beamfs takes no mount options. + +Module parameters +----------------- + +``scrub_interval_ms`` + Milliseconds between two blocks for volumes mounted from then on + (default 100). 0 parks the scrubber; correction on read is + unaffected. + +``clock_source`` + Declared quality of the wall clock that anchors journal timestamps: + 0 unknown (the default), 1 RTC, 2 NTP, 3 hardware (PTP or GPS). + +sysfs +----- + +Each mounted volume has a directory ``/sys/fs/beamfs//``: + +``interval`` (rw) + Milliseconds between two blocks for this volume's scrubber. + +``cursor``, ``passes``, ``blocks`` (ro) + Position of the scrubber, completed sweeps, blocks decoded. + +``corrected``, ``uncorrectable`` (ro) + Blocks the scrubber corrected, and blocks it could not correct. + +``error_budget`` (ro) + For each number of corrected symbols, how many blocks reached it; + ``disabled`` if the volume has no error budget. + +``clock_anchor`` (ro) + Monotonic and wall-clock time at the same instant, and the declared + quality of the wall clock. + +``scrub_pace`` (ro) + The scrubber's current pace. + +``alert_rate_limit`` (rw) + Blocks corrected in one sweep at or above which an alert is sent; 0, + the default, disables the check. + +Alerts +------ + +When a threshold is crossed, beamfs sends a ``KOBJ_CHANGE`` uevent on +``/sys/fs/beamfs/`` with ``BEAMFS_ALERT=1``, ``BEAMFS_REASON`` +and ``BEAMFS_DETAIL``, and logs the same line. ``BEAMFS_REASON`` is +one of: + +``uncorrectable`` + A block could not be recovered. + +``no-margin`` + A block has used all its correctable symbols. It still reads + correctly. + +``correction-rate`` + A sweep corrected at least ``alert_rate_limit`` blocks. + +Each reason is sent at most once a minute. What to do about an alert +is left to userspace. + +debugfs and tracepoints +----------------------- + +Reading ``/sys/kernel/debug/beamfs/rs_bench`` encodes and decodes in +memory and reports the cost per block; ``rs_bench_iters`` sets the +number of iterations. The tracepoints are in the ``beamfs`` trace +system. + + +Limitations +=========== + +- There is no journal and no copy-on-write. Metadata reaches the + medium through writeback, in no guaranteed order; after an unclean + shutdown the volume is checked with ``fsck.beamfs``. +- Metadata goes through buffer heads. +- Without ``DATA_SELFID``, an indirect pointer flipped onto another + allocated block in range is not detected. +- The measurements published so far emulate single-bit upsets on the + read path, with at most two erroneous symbols per codeword and per + decode [#beamfsv3]_. The eight-symbol limit, bursts, miscorrection + and performance are not measured. + + +References +========== + +.. [#tg203] M. Miften et al., Management of radiotherapy patients with + implanted cardiac pacemakers and defibrillators: a report of the + AAPM TG-203, Medical Physics, 2019. doi:10.1002/mp.13838 + +.. [#beamfsv3] A. Desbrieres, beamfs v3 technical report, Zenodo, + 2026. doi:10.5281/zenodo.23253350 diff --git a/Documentation/filesystems/index.rst b/Documentation/filesystems/index.rst index 7cce7cc28d12..bff91a3c82ff 100644 --- a/Documentation/filesystems/index.rst +++ b/Documentation/filesystems/index.rst @@ -74,6 +74,7 @@ Documentation for filesystem implementations. afs autofs autofs-mount-control + beamfs befs btrfs ceph -- 2.55.0