# Test Case: Chunk Index Decode and Mapped Device ID

**Test ID**: TC095-chunk-index-read  
**Category**: Chunk-Based  
**Priority**: High

## Objective

Verify first/middle/last 8-byte indexes, zero-high and nonzero-high 48-bit
decode, the rounded device-ID mask, and `ENODEV` for mapped ID 3.

## Field qualification

After G6 generation, print the fields on the host that will be exercised:

```sh
OUTPUT=/path/to/generated-fixtures
python3 -B - "$OUTPUT/manifest.json" <<'PY'
import json, sys
m = json.load(open(sys.argv[1]))
for fixture in ('multi2', 'multi2-unified48', 'bad-mapped-device3'):
    c = m['fixtures'].get(fixture, {}).get('image', {}).get('chunks', {})
    if '/indexed.bin' in c:
        print(fixture, c['/indexed.bin'])
print(m['mutations'])
PY
```

The normal `indexed.bin` has five 32768-byte indexes with IDs `1,2,1,2,1`.
The 48-bit control has format bit `0x40` with zero high words; its unified
target also contains a real nonzero high word.  The negative second index is
exactly device ID 3 while `extra_devices=2`, whose mask is 3.

## Normal and cross-index reads

```sh
I=/root/repo22-g6/images
S=/root/repo22-g6/sources/chunk
mkdir -p /mnt/g6
kldload /root/repo22-g6/erofs.ko
mdconfig -a -t vnode -f "$I/multi2-primary.erofs" -u 90
mdconfig -a -t vnode -f "$I/multi2-slot1.blob" -u 91
mdconfig -a -t vnode -f "$I/multi2-slot2.blob" -u 92
mount -t erofs -o ro -o device.1=/dev/md91 -o device.2=/dev/md92 \
  /dev/md90 /mnt/g6
cmp "$S/indexed.bin" /mnt/g6/indexed.bin
dd if="$S/indexed.bin" of=/tmp/tc095.first.src bs=1 skip=0 count=4096 2>/dev/null
dd if=/mnt/g6/indexed.bin of=/tmp/tc095.first.mnt bs=1 skip=0 count=4096 2>/dev/null
cmp /tmp/tc095.first.src /tmp/tc095.first.mnt
dd if="$S/indexed.bin" of=/tmp/tc095.middle.src bs=1 skip=65536 count=4096 2>/dev/null
dd if=/mnt/g6/indexed.bin of=/tmp/tc095.middle.mnt bs=1 skip=65536 count=4096 2>/dev/null
cmp /tmp/tc095.middle.src /tmp/tc095.middle.mnt
dd if="$S/indexed.bin" of=/tmp/tc095.last.src bs=1 skip=131072 count=4096 2>/dev/null
dd if=/mnt/g6/indexed.bin of=/tmp/tc095.last.mnt bs=1 skip=131072 count=4096 2>/dev/null
cmp /tmp/tc095.last.src /tmp/tc095.last.mnt
dd if="$S/indexed.bin" of=/tmp/tc095.cross.src bs=1 skip=28672 count=8192 2>/dev/null
dd if=/mnt/g6/indexed.bin of=/tmp/tc095.cross.mnt bs=1 skip=28672 count=8192 2>/dev/null
cmp /tmp/tc095.cross.src /tmp/tc095.cross.mnt
umount /mnt/g6
mdconfig -d -u 92
mdconfig -d -u 91
mdconfig -d -u 90
```

## 48-bit indexes and high unified address

```sh
mdconfig -a -t vnode -f "$I/multi2-unified48-primary.erofs" -u 90
mdconfig -a -t vnode -f "$I/multi2-unified48-slot1.blob" -u 91
mdconfig -a -t vnode -f "$I/multi2-unified48-slot2.blob" -u 92
mount -t erofs -o ro -o device.2=/dev/md92 -o device.1=/dev/md91 \
  /dev/md90 /mnt/g6
cmp "$S/indexed.bin" /mnt/g6/indexed.bin
cmp "$S/unified-address.bin" /mnt/g6/unified-address.bin
umount /mnt/g6
mdconfig -d -u 92
mdconfig -d -u 91
mdconfig -d -u 90
```

## Mapped undeclared ID

```sh
mdconfig -a -t vnode -f "$I/bad-mapped-device3.erofs" -u 90
mdconfig -a -t vnode -f "$I/multi2-slot1.blob" -u 91
mdconfig -a -t vnode -f "$I/multi2-slot2.blob" -u 92
mount -t erofs -o ro -o device.1=/dev/md91 -o device.2=/dev/md92 \
  /dev/md90 /mnt/g6
truss -f -o /tmp/tc095-enodev.truss dd if=/mnt/g6/indexed.bin \
  of=/dev/null bs=1 skip=32768 count=4096
tail -20 /tmp/tc095-enodev.truss
cmp "$S/tc006.bin" /mnt/g6/tc006.bin
```

The affected read must return exactly `ENODEV`; the mount and unaffected file
remain usable.

## Cleanup and zero-state check

```sh
umount /mnt/g6
mdconfig -d -u 92
mdconfig -d -u 91
mdconfig -d -u 90
kldunload erofs
rm -f /tmp/tc095.*.src /tmp/tc095.*.mnt
mount -p | awk '$3 == "erofs" { print }'
mdconfig -l
kldstat -n erofs 2>/dev/null || true
sysctl -n kern.geom.conftxt | grep -E 'md9[0-2]|erofs' || true
```

All four final outputs must be empty.
