Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 40 additions & 4 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,22 @@ lib/bcachefs/tests/fixtures/ — volumes upstream's tools wrote
144,978 bytes gzip -9, of a 33,554,432-byte raw volume
sha256 7be2c99db0e68c784ea59ef394454a084fa57868b14027528ab6b8b21031840e
raw 021c816a064fc2fca2402c8b2a87a9e6124e0b2f4a32779ef14654e908bcacff

lib/bcachefs/tests/fixtures/encrypted.img.gz
716,785 bytes gzip -9n, of a 33,554,432-byte raw volume
sha256 2a32529edf3e30de75d02cdc4ad0b2060552555b012e9647dc24702c0ee7f82d
raw a640704b34cadfc6544f096a36c74bd60b047a079fb20fd96c622f9bcd81a72e

lib/bcachefs/tests/fixtures/encrypted-wide-macs.img.gz
774,007 bytes gzip -9n, of a 33,554,432-byte raw volume
sha256 fd137a545190906ded0269eeec3e32835ffe3585d3e4c2cebe84d234a96b1b1f
raw 52638d7b3c31abb202e6b12c5ccb5a58fe95bee412bada3d7fc3756705cdcace

SPDX-License-Identifier: MIT OR Apache-2.0

`lib/bcachefs/src/upstream` implements upstream's on-disk format, and the only
honest judge of a format reader is bytes the format's own implementation wrote.
This fixture is those bytes. It was produced by `bcachefs-tools` v1.39.4 running
`lib/bcachefs/src/engine` reads upstream's on-disk format, and the only honest
judge of a format reader is bytes the format's own implementation wrote. This
fixture is those bytes. It was produced by `bcachefs-tools` v1.39.4 running
in a QEMU guest booted from the Arch Linux 2026.09.01 install medium, as a
development instrument: neither the tools nor that medium is a dependency of
this repository, nothing fetches either, and the suite reads only what is
Expand All @@ -295,7 +306,7 @@ The commands, in the guest, against a 32 MiB raw disk on `/dev/vdc`:
bcachefs fsck -y /dev/vdc

`--block_size=4096` is explicit because `bcachefs format` picks a smaller block
for a small device, and 4096 is the only block size this crate reads. 32 MiB is
for a small device, and ToyOS's block devices have 4096-byte blocks. 32 MiB is
the smallest volume that formats, fills and passes fsck at that block size: 16
and 24 MiB both fail during format, and 8 and 12 MiB fail even at the default
block size. `bcachefs show-super` on the result:
Expand Down Expand Up @@ -331,6 +342,31 @@ layout is a published on-disk format, not a copyrightable work of the program,
and the file contents are ours. The tool is not distributed with this repository
in any form.

`encrypted.img.gz` and `encrypted-wide-macs.img.gz` are encrypted volumes
upstream's tools wrote, which the engine unlocks and reads: ChaCha20/Poly1305
with 80-bit data MACs, and with the 128-bit ones that `--wide_macs` sets. They were produced by `bcachefs-tools` v1.39.4 (commit
d997ad76e906), built from its tag, in a QEMU guest booted from the Ubuntu
26.04.1 arm64 cloud image, as a development instrument on the same terms as
above. The commands, against a raw image file, the second time with
`--wide_macs` and the label `toyosencw`:

truncate -s 32M enc.img
printf '%s\n' 'toyos-test-passphrase' > pass
bcachefs format --block_size=4096 --encrypted --passphrase_file pass --fs_label=toyosenc enc.img
bcachefs unlock -k session -f pass enc.img # in a fresh session keyring
bcachefs fusemount enc.img /mnt/t
printf hello-toyos > /mnt/t/a.txt; seq 1 40000 > /mnt/t/seq.txt; sync
fusermount3 -u /mnt/t
bcachefs fsck -n -K enc.img # exit 0
gzip -9n < enc.img > enc.img.gz

The passphrase is a published test value. The files are an eleven-byte string,
the output of `seq` and an empty `lost+found`; the UUIDs, hash seeds and keys
inside are generated values; the member's device name is the image file's
basename, and no model or serial is recorded. Timestamps are 2026-10-22, the
guest's clock. The same reasoning as for `crc32c.img.gz` makes the bytes this
project's own.


lib/fat32/tests/fixtures/ — volumes macOS's FAT tools wrote
------------------------------------------------------------
Expand Down
18 changes: 15 additions & 3 deletions build/licence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,15 +417,27 @@ pub const COMMITTED_FILES: &[(&str, &str, &str, Terms)] = &[
"ours: OVMF's answer on a q35 guest, read off that boot's own loader log",
Terms::Spdx("MIT OR Apache-2.0"),
),
// A bcachefs volume upstream's own tools wrote, gzipped. The bytes inside
// it are this repository's test material; `NOTICE` carries the raw digest,
// the commands, and the fsck that called it clean.
// bcachefs volumes upstream's own tools wrote, gzipped. The bytes inside
// them are this repository's test material; `NOTICE` carries each raw
// digest, the commands, and the fsck that called it clean.
(
"lib/bcachefs/tests/fixtures/crc32c.img.gz",
"7be2c99db0e68c784ea59ef394454a084fa57868b14027528ab6b8b21031840e",
"NOTICE",
Terms::Spdx("MIT OR Apache-2.0"),
),
(
"lib/bcachefs/tests/fixtures/encrypted.img.gz",
"2a32529edf3e30de75d02cdc4ad0b2060552555b012e9647dc24702c0ee7f82d",
"NOTICE",
Terms::Spdx("MIT OR Apache-2.0"),
),
(
"lib/bcachefs/tests/fixtures/encrypted-wide-macs.img.gz",
"fd137a545190906ded0269eeec3e32835ffe3585d3e4c2cebe84d234a96b1b1f",
"NOTICE",
Terms::Spdx("MIT OR Apache-2.0"),
),
// FAT32 volumes macOS's `newfs_msdos` formatted and its `msdosfs`
// populated, as runs of nonzero sectors. Each boot sector carries
// `newfs_msdos`'s boot stub; `NOTICE` carries its notice, each raw digest
Expand Down
13 changes: 9 additions & 4 deletions issues/bcachefs-crate-is-not-bcachefs.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@ default filesystem.** The name stops being wrong by the crate growing into it.

This entry therefore stops being a question and becomes work: what is owed is the
implementation, and the gap between the two formats recorded above is the measure
of it. The upstream research this tree used to carry went with the documents, so
whoever picks this up reads the format out of upstream's own source and
specification again — that reading is part of the work now, not a head start on
it.
of it. The format is implemented clean-room (root `CLAUDE.md`): an analyst reads
upstream and writes the specification, and a different agent implements from it.

**Where it stands.** `lib/bcachefs/src/engine` reads clean single-device 1.39
volumes, crc32c and ChaCha20/Poly1305, and formats a minimal complete volume that
upstream's `bcachefs fsck -n -K` passes. It replaced a read side written from
upstream's headers. Its tests read volumes upstream's tools wrote
(`lib/bcachefs/tests/fixtures/`). The rest of the crate is still the interim
format, which ROOT, the loader and DATA use until the engine replaces it.

The track itself is not planned here.

Expand Down
3 changes: 1 addition & 2 deletions issues/deviceerror-classify-trusts-a-lying-transfererror.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ and by the same rule would refuse `kernel/src/file_backing.rs`'s `impl` for
the kernel's `BlockError`, the fileserver's for its `Attempted`
(`system/fileserver/src/cache.rs`), the loader's `Outside`
(`loader/src/microcode.rs`) and the crate's own test devices
(`lib/bcachefs/tests/crash.rs`, `lib/bcachefs/tests/integration.rs`,
`lib/bcachefs/tests/upstream_fixture.rs`).
(`lib/bcachefs/tests/crash.rs`, `lib/bcachefs/tests/integration.rs`).
Implementing `TransferError` from outside is what the trait is *for*: a
foreign block device is the only authority on whether its own transfer was
attempted. Making `classify` crate-private has the identical problem, because
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ opened: 2026-10-11
**Candidates** (scan of the restructured tree, 2026-10-11), best first:
1. `toyos-fat32-check`: FAT32 checker written from Microsoft's fatgen103. No ToyOS dependencies, `no_std`.
2. `toyos-fat32`: FAT32 read/write hardened against hostile volumes. It needs `toyos-wallclock` folded in, and its tests made self-contained.
3. The bcachefs `upstream` reader, split out of `lib/bcachefs`.
3. The bcachefs engine (`lib/bcachefs/src/engine`), split out of `lib/bcachefs` once the interim format leaves it.
4. `toyos-microcode` and `toyos-usbhid`.
5. Later: the TCP stack (once `wire`'s grab-bag is factored out), the SSH server (once its track and defect issues close), and the AML interpreter (once it is decoupled from `toyos-acpi`).

Expand Down
6 changes: 5 additions & 1 deletion lib/bcachefs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
[package]
name = "bcachefs"
description = "The /home filesystem: a read side of the real bcachefs on-disk format."
description = "bcachefs: the on-disk format's reader, mkfs and check, and the interim ToyOS format they replace."
version = "0.1.0"
edition = "2021"
license = "MIT OR Apache-2.0"

[dependencies]
toyos-blockdev = { path = "../blockdev" }
toyos-crypto = { path = "../crypto" }

[features]
default = ["std"]
std = []
Expand Down
19 changes: 17 additions & 2 deletions lib/bcachefs/src/crc32c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,21 @@ const CRC32C_TABLE: [u32; 256] = {

/// Compute CRC-32c over a byte slice.
pub fn crc32c(data: &[u8]) -> u32 {
let mut crc = 0xFFFF_FFFFu32;
update(0xFFFF_FFFF, data) ^ 0xFFFF_FFFF
}

/// The same register with no initial or final inversion: bcachefs's data
/// checksum type 5, whose value over zeros is 0.
pub fn crc32c_zero(data: &[u8]) -> u32 {
update(0, data)
}

fn update(mut crc: u32, data: &[u8]) -> u32 {
for &byte in data {
let idx = ((crc ^ byte as u32) & 0xFF) as usize;
crc = (crc >> 8) ^ CRC32C_TABLE[idx];
}
crc ^ 0xFFFF_FFFF
crc
}

#[cfg(test)]
Expand All @@ -46,6 +55,12 @@ mod tests {
assert_eq!(crc32c(b"123456789"), 0xE3069283);
}

#[test]
fn the_uninverted_register_has_its_own_check_value() {
assert_eq!(crc32c_zero(b"123456789"), 0x58E3_FA20);
assert_eq!(crc32c_zero(&[0; 4096]), 0);
}

#[test]
fn zeroes() {
// CRC of all zeroes should be deterministic
Expand Down
Loading