## mkfs-xfs

`mkfs-xfs` is a dependency-free Rust library for building XFS filesystems.
The current implementation covers the default single-data-device metadata
surface and checks it byte-for-byte against a pinned `mkfs.xfs` reference.

It is still early-stage: there is no stable public API and no CLI. The intended
entrypoint is the library.

### Basic Use

Build format options, derive a validated plan, then stream metadata to the
target:

```rust
use mkfs_xfs::image::write_plan_to;
use mkfs_xfs::{FormatOptions, FormatPlan, InodeGenerationPolicy};

let uuid = [0_u8; 16];
let options = FormatOptions::new(1 << 30, uuid)
    .with_inode_generation(InodeGenerationPolicy::Random);
let plan = FormatPlan::new(options)?;
let mut output = std::fs::OpenOptions::new().write(true).open("disk.img")?;
write_plan_to(&plan, &mut output)?;
```

For a regular file or Linux block device, derive the data size and sector size
from the target:

```rust
use mkfs_xfs::{FormatOptions, FormatPlan};

let uuid = [0_u8; 16];
let options = FormatOptions::from_target("/dev/sdX", uuid)?;
let plan = FormatPlan::new(options)?;
```

On Linux block devices this uses `BLKGETSIZE64` for device size and `BLKSSZGET`
for logical sector size. Regular files use their file length and default to
512-byte sectors.

### Writing an Image

The streaming API writes bounded-size metadata buffers directly to any seekable
writer:

```rust
use std::fs::OpenOptions;
use mkfs_xfs::image::write_plan_to;
use mkfs_xfs::{FormatOptions, FormatPlan};

let uuid = [0_u8; 16];
let plan = FormatPlan::new(FormatOptions::new(1 << 30, uuid))?;

let mut output = OpenOptions::new().write(true).open("disk.img")?;
write_plan_to(&plan, &mut output)?;
```

`MetadataImage::from_plan` remains useful for manifests and tests. It
materializes sparse extents in memory and is intentionally capped for very
large allocation-group counts.

### Validation

Use the pinned Nix environment for reproducible validation:

```sh
nix develop
cargo test
nix flake check
```

Compare the Rust metadata surface with pinned `mkfs.xfs`:

```sh
nix develop --command cargo run --example compare_xfsprogs
```

The comparison accepts optional image size and sector size arguments:

```sh
nix develop --command cargo run --example compare_xfsprogs -- 1099511627776
nix develop --command cargo run --example compare_xfsprogs -- 1073741824 4096
```

`examples/write_default_image.rs` can write the current sparse metadata image:

```sh
cargo run --example write_default_image -- /tmp/xfs.img
cargo run --example write_default_image -- /tmp/xfs-4k.img 1073741824 4096
```

### Reference Material

Reference notes and local xfsprogs source snapshots belong under `docs/` and
`tmp/`. The implementation should continue to prefer small, tested encoders and
byte-level comparison with `mkfs.xfs` over broad rewrites.
