# repo22 xattr/ACL root-cause manual test report

Date: 2026-08-08 18:12 UTC; final integration rerun on 2026-08-08
Baseline: `29a215dd4519579f6313b3df67d524a6b4bdf3ca` plus the scoped xattr/ACL fixes
Guest: FreeBSD 15.0-RELEASE-p8 amd64
Host tools: erofs-utils 1.8.6 plus deterministic transformed fixtures

## Build and module

- `git diff --check`: PASS.
- `./build.sh`: PASS; final `build/erofs.ko` SHA-256 is
  `50a19ea96c7414f73d92049671e66a9eacc9ff5abe27950a46d16c8e6c763baf`.
- `nm -u build/erofs.ko | grep -w bcmp`: no match, PASS.
- `kldload /tmp/repo22-integration-20260808/erofs.ko`: PASS.
- Repeated `mdconfig -a -t vnode -f IMAGE`, `mount -t erofs`, `umount`, and
  `mdconfig -d`: PASS for every fixture below.
- `kldunload erofs`: PASS; final module, EROFS mount, and md-device counts were
  all zero.
- New dmesg errors, traps, or panics: none.

## Existing xattr and ACL regression

- Inline user, trusted, and security xattrs: PASS.
- Shared user xattrs and shared POSIX access ACL: PASS.
- Packed long-prefix table and xattr-name-filter: PASS.
- Access/default ACL decode and inherited child ACL: PASS.
- Owner, owning-group, named-user, and other access matrix: PASS.
- Read-only ACL/xattr mutation rejection: PASS.
- TC117 malformed name length and value size: PASS. Xattr operations returned
  `EINTEGRITY`; directory metadata and file contents remained readable.
- An invalid long-prefix reference without a declared prefix table is now
  skipped like Linux. Other valid xattrs and file data remain readable.

## New regression cases

- TC134 metabox shared nonzero base: PASS with
  `metabox-shared-nonzero-base.erofs`. The image has
  `SHARED_EA_IN_METABOX`, `xattr_blkaddr=1`, and a plain metabox carrier.
  `getextattr -qq user metaboxshared /mnt/repo22-integration/hello.txt`
  returned exactly `nonzero-base`.
- TC135 metabox long-prefix backing: PASS with
  `metabox-prefix-shared.erofs`.
  `getextattr -qq user repo22.application.component.setting` on
  `/mnt/repo22-integration/long/file2.txt` returned `long-prefix-value`.
  Primary-image long-prefix fallback also passed with
  `long-prefix-primary-fallback.erofs` and the same expected value.
- TC136 truncated metabox extension: PASS; mount returned `EINTEGRITY`.
  Out-of-range ishare prefix ID: PASS; mount returned `EINTEGRITY`.
- TC137 shared xattr outside declared image: PASS; normal data and an in-bounds
  xattr remained readable, while the redirected entry returned `EINTEGRITY`.
  Prefix record outside declared image: PASS; mount failed. The valid primary
  fallback control mounted and returned the expected value.
- TC138 unordered unique UID qualifiers: PASS and preserved order 3002, 2002.
  Header-only ACL: PASS and fell back to mode. Duplicate UID qualifier: PASS
  negative test and returned `EINTEGRITY`.
- TC139 FIFO access ACL, list/get system xattr: PASS. `setfacl`, `setextattr`,
  and `rmextattr` all returned read-only filesystem errors.
- TC140 compressed metabox: PASS with `metabox-large-shared.erofs`. On-disk
  qualification found `METABOX`, metabox inode datalayout 1
  (`EROFS_INODE_COMPRESSED_FULL`), and no fragment pcluster. A cold file read,
  the metabox long-prefix lookup, and a 231-byte xattr value all matched the
  source fixture.

## Final metabox and metadata-boundary smoke

The final combined module was exercised with these exact guest operations:

```sh
kldload /tmp/repo22-integration-20260808/erofs.ko
mdconfig -a -t vnode -f /tmp/repo22-integration-20260808/IMAGE.erofs
mount -t erofs /dev/md0 /mnt/repo22-integration
getextattr -qq user NAME /mnt/repo22-integration/PATH
umount /mnt/repo22-integration
mdconfig -d -u 0
kldunload erofs
```

- Compressed metabox and metabox long-prefix:
  `metabox-large-shared.erofs` returned `long-prefix-value` for
  `repo22.application.component.setting`; its regular file content also
  matched `long prefix fixture 1`.
- Primary shared fallback while `METABOX` is enabled:
  `metabox-large-shared.erofs` has `SHARED_EA_IN_METABOX` clear and
  `xattr_blkaddr=1`; `shared_key` returned `repo22-shared-value` from the
  primary shared-xattr area.
- `SHARED_EA_IN_METABOX` nonzero base:
  `metabox-shared-nonzero-base.erofs` returned `nonzero-base` from the shared
  entry addressed relative to metabox block 1.
- Cross-metadata shared xattr: `shared-cross-metadata.erofs` returned
  `repo22-shared-value` for `shared_key` on `shared/file3.txt`.
- Cross-metadata inline xattr: `xattr-cross-metadata.erofs` returned the exact
  expected `alpha`, `gamma`, and `delta` values on `file000`, `file090`, and
  `file179`. The metabox-specific inline boundary fixture also returned
  `valid-inline-boundary` for `crossboundary`.

The fragment-backed compressed metabox negative layout was **not generated and
was not executed**. The passing TC140 fixture is compressed but non-fragment.
The code still rejects a compressed metabox inode whose fragment flag is set;
that rejection remains layout-reviewed rather than fixture-verified.

## Fixture qualification

The old `namespace-shared.erofs` contains an xattr entry with name index `0x80`
but advertises no `XATTR_PREFIXES` feature and contains no prefix table. It is
not a valid long-prefix fixture. The driver now follows Linux behavior by
skipping that unresolved entry while preserving all valid xattrs and file data.

## Separate namei write set

The previously observed cold nested lookup issue was fixed by the separate
`src/namei.c` and `src/dir.c` write set and passed TC141 in the same final
integration build. Those source files are intentionally excluded from the
xattr/ACL commit.
