Files
erofs-freebsd-out-tree/tests/TC154-nfs-per-inode-generation.md
T
2026-08-18 09:20:44 +02:00

2.9 KiB

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:

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:

    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:

    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.