# Pre-12 Batch 06: codec descriptor ownership

Date: 2026-08-13

## Scope

- Moved the LZMA, DEFLATE, and ZSTD descriptors into their backend source
  files.
- Made their backend-only config, decompress, and availability helpers
  `static`.
- Kept the LZ4 config loader and descriptor, plus the SHIFTED and INTERLACED
  descriptors and transform, in `src/decompressor.c`.
- Replaced the central descriptor object array with the descriptor pointer
  table `z_erofs_decomp`.
- Reduced `src/compress.h` to the three backend descriptor declarations and
  the LZ4 decompress prototype needed by the central descriptor.

## Descriptor tuples

The normalized tuples are unchanged before and after this batch:

| Index | Name | Config callback | Decompress callback | Compile condition |
| --- | --- | --- | --- | --- |
| `Z_EROFS_COMPRESSION_LZ4` | `lz4` | `z_erofs_load_lz4_config` | `z_erofs_lz4_decompress` | always |
| `Z_EROFS_COMPRESSION_LZMA` | `lzma` | `z_erofs_load_lzma_config` | `z_erofs_lzma_decompress` | always |
| `Z_EROFS_COMPRESSION_DEFLATE` | `deflate` | `z_erofs_load_deflate_config` | `z_erofs_deflate_decompress` | always |
| `Z_EROFS_COMPRESSION_ZSTD` | `zstd` | `z_erofs_load_zstd_config` | `z_erofs_zstd_decompress` | descriptor and config always; decompress implementation selected by `ZSTDIO` |
| `Z_EROFS_COMPRESSION_SHIFTED` | `shifted` | `NULL` | `z_erofs_transform_plain` | always |
| `Z_EROFS_COMPRESSION_INTERLACED` | `interlaced` | `NULL` | `z_erofs_transform_plain` | always |

## Static validation

- Confirmed one declaration and one definition for each backend descriptor;
  the only additional occurrence is its central pointer-table entry.
- Confirmed the LZMA and DEFLATE config/decompress helpers have no external
  consumers and are now `static` in their backends.
- Confirmed the ZSTD config/decompress/availability helpers have no external
  consumers and are now `static`; the two decompress definitions are mutually
  exclusive under `#ifdef ZSTDIO`.
- Confirmed `z_erofs_decomp` explicitly fills all six runtime indices in the
  original order. Decompression retains the array-length bound, rejects a
  null table entry, and rejects a null decompress callback with
  `EOPNOTSUPP`. Config parsing retains the existing compression-config loop
  bound and treats a null entry or null config callback as `EOPNOTSUPP` before
  releasing the config buffer on the existing path.
- Confirmed the `WITH_ZSTDIO=0` static conditional path remained valid;
  actual build deferred to final validation. Without `ZSTDIO`, the path
  keeps the descriptor non-null, reports the existing mount error and
  `EOPNOTSUPP` from config, and selects the decompress stub returning `-1`.
- Confirmed `WITH_ZSTDIO=1` adds `-DZSTDIO`, keeps the same descriptor and
  config callback, and selects the existing ZSTD implementation with its
  resource-release and error paths unchanged.
- `git diff --check` and `git diff --cached --check` were required for this
  batch.

## Deferred validation

No build, QEMU, smoke, feature, or other dynamic validation was run for this
batch. Follow-up validation must build the FreeBSD KLD with both
`WITH_ZSTDIO=0` and `WITH_ZSTDIO=1`.
