test code v1
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
# Test Case: NFS Per-Inode Generation on Same-Superblock Replacement
|
||||
|
||||
**Test ID**: TC154-nfs-per-inode-generation
|
||||
**Category**: NFS Export
|
||||
**Priority**: Critical
|
||||
**Regression**: A mount-wide superblock hash aliases a replacement inode at the same NID
|
||||
|
||||
## Objective
|
||||
|
||||
Verify that an EROFS file handle keeps the existing 16-byte FreeBSD FID ABI but
|
||||
uses a stable per-inode generation. Remounting an unchanged image must preserve
|
||||
the complete handle. Replacing it with an image whose superblock block, UUID,
|
||||
NID, and file content are identical but whose raw inode metadata differs must
|
||||
make the old handle return `ESTALE`.
|
||||
|
||||
Also verify that a valid-NID handle resolving to a malformed replacement inode
|
||||
returns the positive inode-read errno instead of a negative Linux errno or a
|
||||
successful alias.
|
||||
|
||||
## Fixture
|
||||
|
||||
Generate all review fixtures on the host:
|
||||
|
||||
```sh
|
||||
python3 tests/review_fixtures.py make \
|
||||
--output /work/build/repo22-review-fixes-fixtures
|
||||
```
|
||||
|
||||
For `nfs-inode-a.erofs`, `nfs-inode-b.erofs`, and
|
||||
`nfs-inode-corrupt.erofs`, require the helper evidence to prove:
|
||||
|
||||
- target `/zz-identity.txt` has the same NID and inode offset;
|
||||
- the inode lies after the complete superblock checksum block;
|
||||
- the complete checksum block and declared superblock are byte-identical;
|
||||
- A and B differ only in the compact inode `i_mtime` field;
|
||||
- the helper's superblock-seeded raw-inode FNV generations are nonzero and
|
||||
different;
|
||||
- all three images retain a valid superblock checksum.
|
||||
|
||||
## Procedure
|
||||
|
||||
1. Compile `tests/nfs_fh_tool.c` natively on FreeBSD 15.
|
||||
2. Attach image A to an explicit md unit, mount it, capture `a.fh`, and compare
|
||||
`nfs_fh_tool describe`, `nfs_fh_tool stat`, and `stat -f '%v'`. The FID and
|
||||
`st_gen` values must equal `generation_a` in `fixture-manifest.json`.
|
||||
3. Unmount and detach image A, then reattach the unchanged image to the same md
|
||||
unit. Capture `a-remount.fh`, require a byte-for-byte handle match, and read
|
||||
through `a.fh`.
|
||||
4. Replace A with image B on the same md unit. Capture `b.fh`, require the same
|
||||
fsid and NID but `generation_b`, then run:
|
||||
|
||||
```sh
|
||||
nfs_fh_tool expect-stat a.fh ESTALE
|
||||
nfs_fh_tool expect-open a.fh ESTALE
|
||||
nfs_fh_tool stat b.fh
|
||||
```
|
||||
|
||||
5. Replace B with `nfs-inode-corrupt.erofs` on the same md unit. Resolving
|
||||
`a.fh` must return positive FreeBSD `EOPNOTSUPP` (45) from inode decoding:
|
||||
|
||||
```sh
|
||||
nfs_fh_tool expect-stat a.fh 45
|
||||
nfs_fh_tool expect-open a.fh 45
|
||||
```
|
||||
|
||||
6. Compare pre/post dmesg, unmount, detach the md unit, and unload the exact
|
||||
module under test.
|
||||
|
||||
## Expected Results
|
||||
|
||||
- Image A has an identical handle and generation across remounts.
|
||||
- Image B's same-NID replacement has a different generation and both old-handle
|
||||
operations return `ESTALE`.
|
||||
- The new handle resolves successfully and `va_gen == FID.gen`.
|
||||
- The malformed inode propagates errno 45 as a positive error and never returns
|
||||
a vnode.
|
||||
- The FID remains exactly 16 bytes with unchanged field offsets.
|
||||
Reference in New Issue
Block a user