• v1.0.0 a9b8039ef7

    v1.0.0
    Test / test (push) Successful in 2m4s
    Release / gates (push) Successful in 2m5s
    Release / build (amd64, freebsd) (push) Successful in 1m27s
    Release / build (amd64, linux) (push) Successful in 1m22s
    Release / build (amd64, netbsd) (push) Successful in 1m19s
    Release / build (amd64, openbsd) (push) Successful in 1m20s
    Release / build (arm64, darwin) (push) Successful in 1m21s
    Release / build (arm64, freebsd) (push) Successful in 1m26s
    Release / build (arm64, linux) (push) Successful in 1m25s
    Release / build (arm64, netbsd) (push) Successful in 1m31s
    Release / build (arm64, openbsd) (push) Successful in 1m27s
    Release / build (loong64, linux) (push) Successful in 1m37s
    Release / build (riscv64, linux) (push) Successful in 1m21s
    Release / release (push) Successful in 40s
    Stable

    petrbalvin released this 2026-09-21 16:51:17 +00:00 | 0 commits to main since this release

    Added

    The first release of a full NFSv4.2 implementation in pure Go: server and client,
    minor version 2 on the wire only, no portmapper, no mountd, no separate locking
    protocol.

    • Wire foundation: the XDR codec of RFC 4506, ONC RPC record marking of
      RFC 5531 with fragment reassembly, the call and reply headers, AUTH_SYS, and
      the NFSv4.2 operation, error and attribute numbers verified against the
      standards and the Linux client header.
    • Stateless operations: PUTROOTFH, PUTFH, SAVEFH, RESTOREFH, GETFH, LOOKUP,
      LOOKUPP, PUTPUBFH, GETATTR, ACCESS, READ, READDIR, WRITE, CREATE, REMOVE,
      RENAME, SETATTR, LINK, READLINK, COMMIT, VERIFY, NVERIFY, SECINFO and
      SECINFO_NO_NAME, over a virtual filesystem with a local directory backend.
    • Sessions: EXCHANGE_ID, CREATE_SESSION, DESTROY_SESSION, BIND_CONN_TO_SESSION
      and SEQUENCE with a slot table, a reply cache per slot, and client reboot
      detection that drops the state of the previous life.
    • Open state: OPEN and CLOSE with real stateids, share reservations enforced
      across opens of the same file, OPEN_DOWNGRADE, and regular file creation
      through the unchecked, guarded and exclusive forms, where an exclusive create
      replays by its verifier.
    • Ownership: every object a client creates carries the identity the client
      presented, and the server answers the owner and owner group of every object,
      so ownership reads correctly on any conformant client.
    • Byte range locking: LOCK, LOCKT and LOCKU with per owner conflict
      detection, range splitting on unlock, and RELEASE_LOCKOWNER.
    • Lease and recovery: lease renewal on every SEQUENCE, DESTROY_CLIENTID,
      RECLAIM_COMPLETE inside the grace window, CLAIM_PREVIOUS reclamation, and
      persistent file handle maps that survive a server restart.
    • Delegations: read and write delegations granted on the only open of a
      file, recalled over the back channel on a conflicting open, returned through
      DELEGRETURN.
    • Directory delegations: GET_DIR_DELEGATION with CB_NOTIFY on create,
      rename and remove, and CB_NOTIFY_LOCK when a released range frees a denied
      lock.
    • Back channel: CB_COMPOUND over the same TCP connection, CB_SEQUENCE,
      CB_RECALL, and callback delivery that the client demultiplexes from replies.
    • Optional operations of RFC 7862: SEEK, ALLOCATE, DEALLOCATE, IO_ADVISE,
      READ_PLUS, WRITE_SAME, COPY, CLONE, COPY_NOTIFY, OFFLOAD_CANCEL,
      OFFLOAD_STATUS, LAYOUTERROR and LAYOUTSTATS.
    • Extended attributes: GETXATTR, SETXATTR, LISTXATTR and REMOVEXATTR of
      RFC 8276 over the user namespace of the local backend.
    • Named attributes: OPENATTR with create, lookup, read, write and remove
      over the synthetic attribute directory of an object.
    • pNFS: the metadata server role with LAYOUTGET, LAYOUTCOMMIT,
      LAYOUTRETURN, GETDEVICEINFO and GETDEVICELIST, and layout bodies for
      flexfiles (RFC 8435), files, block volumes, objects and SCSI, all over one
      emulated device that is the metadata server itself. The flexfiles version 2
      body of draft-haynes-nfsv4-flex-filesv2-00 (layout type 0x6) is served the
      same way.
    • Migration and referrals: the fs_locations and fs_locations_info
      attributes, referral stubs whose other operations answer NFS4ERR_MOVED.
    • Kerberos: RPCSEC_GSS with the krb5, krb5i and krb5p service levels, the
      AES profiles of RFC 3961 and RFC 3962 and the tokens of RFC 4121 implemented
      in pure Go, plus the version three credential of RFC 7861 with CREATE, LIST
      and assertion binding.
    • RPC-with-TLS: the AUTH_TLS probe and in place TLS upgrade of RFC 9289.
    • RPC-over-RDMA framing: the chunk lists and message assembly of RFC 8166
      over a stream transport; the verbs transport itself sits outside pure Go.
    • The nfsd command: the -export directory and the -addr listen
      address, a TOML configuration file through -config carrying the listen
      address, the operation log, the state directory, the connection cap, the
      TLS key pair and one [[export]], with the flags overriding the file and a
      broken file ending the start up with the file and the line named; a read
      only export with -ro; RPC-with-TLS through -tls-cert and -tls-key,
      where a client that skips STARTTLS is refused with auth too weak for every
      procedure but the NULL of the probe; the operation log of -log-ops; the
      connection cap of -max-connections; persistent recovery state through
      -state-dir, where file handles and opens are written as they change, a
      restart loads them back and the grace window lets clients reclaim their
      opens with CLAIM_PREVIOUS; root squash with -root-squash or root-squash
      in the export, mapping a client claiming uid 0 onto nobody (65534);
      READY=1 on $NOTIFY_SOCKET once the listener is up, so a Type=notify
      unit starts on real readiness; version reporting; and a clean shutdown on
      SIGINT and SIGTERM.
    • The nfs command: ls, cat, put, get, rm, mkdir and stat against a running
      server; the whole operation matrix as nfs selftest, one line per check
      plus a summary and a nonzero exit when a check fails; transfers spread over
      several session slots with -concurrency, measured on loopback at a 64 MiB
      put dropping from 77 ms sequential to 32 ms at four; a session owner id
      unique to the process, so two clients of the command beside each other are
      two clients, not one rebooting; and the version report.
    • Kernel interop: the server is verified end to end against the Linux
      kernel NFSv4.2 client, which mounts the tree over mount -t nfs4 and reads,
      writes, creates and removes through it, with correct ownership, as root and
      non root callers alike.
    • Interoperability stance: strict conformance as the rule, a documented
      tolerance layer confined to the deviations of real clients, and the server
      and client pair as the strict reference of the stack.
    • Performance: the server answers a COMPOUND from one buffer instead of
      copying every operation result twice, READ fills the reply in place, WRITE
      hands the request's own bytes to the storage and the wire buffers recycle;
      the local backend keeps open descriptors of regular files in a bounded
      cache and revalidates the file identity on every use; READDIR pages cost
      the page against a cached sorted order of the directory; COPY and CLONE run
      through copy_file_range and the reflink of the filesystem with a fallback
      to the userspace copy; the session store locks per session instead of one
      server wide mutex and the lease check runs lock free against an atomic
      renewal stamp, six clients beside each other measured at 4.8 times the
      sequential throughput. Measured numbers: 11 percent faster reads, 19
      percent fewer allocations per COMPOUND, 27 percent fewer bytes per read,
      16.9 percent faster reads and 11.0 percent faster writes of 64 KiB chunks,
      and a READDIR page of 64 entries in a 10 000 entry directory measured 30
      times faster; the reports live in docs/_results/.
    • Operations: docs/DEPLOYMENT.md carries the production picture, the
      hardened systemd unit with Type=notify and the two capability model, the
      firewall note and the upgrade and monitoring story; docs/CONFIGURATION.md
      lists every configuration key; docs/BENCHMARKING.md states the measurement
      method.
    • Platforms: Linux on amd64, arm64, loong64 and riscv64; FreeBSD, OpenBSD
      and NetBSD on amd64 and arm64, all three verified live on amd64, OpenBSD
      and NetBSD with both ends of the project running inside the system and
      across to the Linux server because their kernel clients speak only NFSv3;
      darwin on arm64 as a cross compiled build without runtime testing. Extended
      attributes and the sparse operations answer not supported on OpenBSD,
      NetBSD and darwin, whose local backends have no system interface an
      arbitrary attribute name could use. The stack is pure Go end to end, and
      the module ships the two commands only: there is no importable package and
      no library surface.
    Downloads