Files
erofs-freebsd-out-tree/tests/TC131-nfs-export-basic.md
T
2026-08-18 09:20:44 +02:00

4.3 KiB

Test Case: FreeBSD NFSv3 Export Basic Functionality

Test ID: TC131-nfs-export-basic Category: NFS Export Priority: Critical Regression: EROFS VOP_VPTOFH / VFS_FHTOVP / export updates

Objective

Verify that FreeBSD 15 mountd can install an export on a read-only EROFS mount, that nfsd can resolve EROFS file handles, and that regular files, directories, symlinks, and FIFOs are visible through a real NFSv3 client.

Preconditions

  • FreeBSD 15 amd64 server/client, optionally the same host over loopback.
  • Root privilege for module, md, NFS service, getfh, and fhopen operations.
  • erofs.ko, test-nfs.erofs, and tests/nfs_fh_tool.c available in the guest.
  • The fixture contains basic/regular.txt, basic/subdir, basic/link-to-regular, and basic/test.fifo.

Procedure

  1. Build the module and helper:

    ./build.sh
    cc -O2 -Wall -Wextra -std=c17 tests/nfs_fh_tool.c -o nfs_fh_tool
    
  2. Load and mount EROFS on a fixed md unit:

    kldload ./erofs.ko
    mdconfig -a -t vnode -f test-nfs.erofs -u 42
    mkdir -p /mnt/repo22-erofs
    mount -t erofs -o ro /dev/md42 /mnt/repo22-erofs
    mount -v | grep /mnt/repo22-erofs
    

    The line must show read-only and must not show NFS exported before mountd processes /etc/exports.

  3. Configure the real FreeBSD mountd/nfsd flow:

    cp -p /etc/exports /tmp/exports.before 2>/dev/null || true
    printf '%s\n' \
      '/mnt/repo22-erofs -ro -maproot=root -network 127.0.0.0 -mask 255.0.0.0' \
      > /etc/exports
    service rpcbind onestart
    service mountd onestart
    service nfsd onestart
    service mountd onereload
    rpcinfo -p 127.0.0.1
    showmount -e 127.0.0.1
    mount -v | grep /mnt/repo22-erofs
    

    After reload, the EROFS mount line must show NFS exported. The flag is installed by the generic FreeBSD export layer after the filesystem accepts the export-only MNT_UPDATE; EROFS must not set it during the initial mount.

  4. Mount the export through NFSv3 and confirm the negotiated options:

    mkdir -p /mnt/repo22-nfs
    mount_nfs -o nfsv3,tcp,rdirplus 127.0.0.1:/mnt/repo22-erofs \
      /mnt/repo22-nfs
    nfsstat -m
    
  5. Verify all required vnode types and read-only behavior:

    cmp /mnt/repo22-nfs/basic/regular.txt \
      /mnt/repo22-erofs/basic/regular.txt
    test -d /mnt/repo22-nfs/basic/subdir
    test "$(readlink /mnt/repo22-nfs/basic/link-to-regular)" = regular.txt
    test -p /mnt/repo22-nfs/basic/test.fifo
    test "$(stat -f %i /mnt/repo22-nfs/basic/regular.txt)" = \
      "$(stat -f %i /mnt/repo22-erofs/basic/regular.txt)"
    ! touch /mnt/repo22-nfs/write-must-fail
    
  6. Exercise both shared- and exclusive-lock file-handle resolution locally:

    ./nfs_fh_tool capture /mnt/repo22-erofs/basic/regular.txt regular.fh
    ./nfs_fh_tool stat regular.fh
    ./nfs_fh_tool cat regular.fh regular.out
    cmp regular.out /mnt/repo22-erofs/basic/regular.txt
    

    fhstat requests a shared lock and fhopen requests an exclusive lock.

  7. Confirm that NFSv3 used READDIRPLUS and did not issue writes:

    nfsstat -c
    nfsstat -s
    

Expected Results

  • mountd accepts the EROFS export-only update.
  • showmount -e lists the EROFS path and mount -v shows NFS exported only after mountd reloads exports.
  • NFSv3 regular reads, directory traversal, symlink lookup, FIFO metadata, and inode numbers match the direct EROFS mount.
  • Writes fail with EROFS/Read-only file system.
  • fhstat and fhopen both resolve the same 64-bit EROFS NID.
  • NFS statistics show READDIRPLUS traffic and zero successful write RPCs.

Cleanup

Always remove clients before stopping the loopback server:

umount /mnt/repo22-nfs
: > /etc/exports
service mountd onereload
service nfsd onestop
service mountd onestop
service rpcbind onestop
umount /mnt/repo22-erofs
mdconfig -d -u 42
kldunload erofs
rm -f /etc/exports

Restore a pre-existing /etc/exports instead of removing it when applicable.

Notes

  • The EROFS FreeBSD file-handle payload is 16 bytes: len, pad, nid_hi, nid_lo, and a nonzero superblock-seeded per-inode generation matching va_gen.
  • Do not use Linux exportfs; FreeBSD mountd installs exports through a mount update carrying the export option.
  • Throughput is recorded for information only; correctness has no fixed MB/s threshold.