XDR types for NFS v3 — RFC 1813 §2.5.
Shape constants:
NFS3_FHSIZE = 64 # max v3 file-handle bytes
NFS3_COOKIEVERFSIZE = 8 # cookie verifier
NFS3_CREATEVERFSIZE = 8 # create verifier
NFS3_WRITEVERFSIZE = 8 # write verifierEach XDR primitive in §2.5 has a sibling encode_*/1 /
decode_*/1 pair. Composite types follow the same shape and
destructure into the structs declared in this module
(Fattr3, WccAttr, WccData, Specdata3, Nfstime3,
Sattr3).
Procedure-specific request / reply types
(e.g. LOOKUP3args / LOOKUP3res) are intentionally not defined
here; each handler procedure builds its own out of these primitives.
Keeping the type module focused on §2.5 keeps it reviewable
independently of the procedure handlers.
Summary
Types
Fixed 8-byte READDIR / READDIRPLUS cookie verifier.
uint32; byte count for a request/response.
Discriminated union from RFC 1813 §3.3.8 CREATE arguments.
Fixed 8-byte CREATE verifier (used by EXCLUSIVE creates).
Directory + file-name pair for LOOKUP / CREATE / etc.
Variable-length file handle, ≤ 64 bytes.
uint64; persistent inode-style id.
UTF-8-ish file name (NFSv3 doesn't constrain encoding).
RFC 1813 §2.5 file types.
uint32; group id.
uint32; mode bits.
uint64; opaque READDIR cursor.
UTF-8-ish symlink target.
RFC 1813 §2.6 status codes. :ok is success, the rest are POSIX-flavoured errnos.
uint64; byte offset within a file.
uint64; file size in bytes.
WRITE / COMMIT stability hints from RFC 1813 §3.3.7. Determines whether the server may lose the write before COMMIT.
uint32; user id.
Fixed 8-byte WRITE verifier (used by COMMIT).
Functions
Decode an 8-byte cookie verifier.
Decode a createhow3 discriminated union.
Decode an 8-byte CREATE verifier.
Decode a diropargs3.
Decode fattr3.
Decode fhandle3.
Decode filename3.
Decode a 32-bit ftype3 enum to its atom.
Decode nfspath3.
Decode a 32-bit nfsstat3 code back to its atom. Unknown codes
surface as {:unknown, n} so handlers can report it without
crashing.
Decode nfstime3.
Decode post_op_attr.
Decode post_op_fh3.
Decode pre_op_attr.
Decode a sattr3 struct.
Decode specdata3.
Decode a stable_how from the wire integer.
Decode a wcc_attr.
Decode wcc_data.
Decode an 8-byte WRITE verifier.
Encode an 8-byte cookie verifier.
Encode a createhow3 discriminated union.
Encode an 8-byte CREATE verifier.
Encode a diropargs3 (dir fhandle + name).
Encode fattr3.
Encode fhandle3 (variable opaque ≤ 64 bytes).
Encode filename3 (a non-empty XDR string).
Encode an ftype3 atom as its 32-bit wire enum.
Encode nfspath3 (an XDR string).
Encode an nfsstat3 atom as its 32-bit wire integer.
Encode nfstime3.
Encode post_op_attr — nil means "no attrs available", otherwise
the Fattr3 is encoded prefixed with a TRUE flag.
Encode post_op_fh3 — nil means "no handle available", otherwise
the fhandle3 is encoded prefixed with a TRUE flag.
Encode pre_op_attr (the optional wcc_attr half of a wcc_data).
nil means no pre-op attrs were captured.
Encode a sattr3 struct.
Encode specdata3.
Encode a stable_how atom to its wire integer.
Encode a wcc_attr (size + mtime + ctime).
Encode wcc_data (pre_op_attr + post_op_attr).
Encode an 8-byte WRITE verifier.
READDIR / READDIRPLUS cookie verifier size.
CREATE verifier size.
Max v3 file-handle byte size.
WRITE verifier size.
Types
@type cookieverf3() :: <<_::64>>
Fixed 8-byte READDIR / READDIRPLUS cookie verifier.
@type count3() :: non_neg_integer()
uint32; byte count for a request/response.
@type createhow3() :: {:unchecked, Tahr.NFSv3.Types.Sattr3.t()} | {:guarded, Tahr.NFSv3.Types.Sattr3.t()} | {:exclusive, createverf3()}
Discriminated union from RFC 1813 §3.3.8 CREATE arguments.
{:unchecked, %Sattr3{}}— overwrite if exists.{:guarded, %Sattr3{}}— fail withNFS3ERR_EXISTif exists.{:exclusive, createverf3}— atomic create-if-not-exists keyed by the 8-byte verifier.
@type createverf3() :: <<_::64>>
Fixed 8-byte CREATE verifier (used by EXCLUSIVE creates).
Directory + file-name pair for LOOKUP / CREATE / etc.
@type fhandle3() :: binary()
Variable-length file handle, ≤ 64 bytes.
@type fileid3() :: non_neg_integer()
uint64; persistent inode-style id.
@type filename3() :: binary()
UTF-8-ish file name (NFSv3 doesn't constrain encoding).
@type ftype3() :: :reg | :dir | :blk | :chr | :lnk | :sock | :fifo
RFC 1813 §2.5 file types.
@type gid3() :: non_neg_integer()
uint32; group id.
@type mode3() :: non_neg_integer()
uint32; mode bits.
@type nfs_cookie3() :: non_neg_integer()
uint64; opaque READDIR cursor.
@type nfspath3() :: binary()
UTF-8-ish symlink target.
@type nfsstat3() ::
:ok
| :perm
| :noent
| :io
| :nxio
| :acces
| :exist
| :xdev
| :nodev
| :notdir
| :isdir
| :inval
| :fbig
| :nospc
| :rofs
| :mlink
| :nametoolong
| :notempty
| :dquot
| :stale
| :remote
| :badhandle
| :not_sync
| :bad_cookie
| :notsupp
| :too_small
| :server_fault
| :bad_type
| :jukebox
RFC 1813 §2.6 status codes. :ok is success, the rest are POSIX-flavoured errnos.
@type offset3() :: non_neg_integer()
uint64; byte offset within a file.
@type size3() :: non_neg_integer()
uint64; file size in bytes.
@type stable_how() :: :unstable | :data_sync | :file_sync
WRITE / COMMIT stability hints from RFC 1813 §3.3.7. Determines whether the server may lose the write before COMMIT.
:unstable— volatile cache, client must COMMIT.:data_sync— data persistent, metadata may not be.:file_sync— data + metadata persistent.
@type uid3() :: non_neg_integer()
uint32; user id.
@type writeverf3() :: <<_::64>>
Fixed 8-byte WRITE verifier (used by COMMIT).
Functions
@spec decode_cookieverf3(binary()) :: {:ok, cookieverf3(), binary()} | {:error, term()}
Decode an 8-byte cookie verifier.
@spec decode_createhow3(binary()) :: {:ok, createhow3(), binary()} | {:error, term()}
Decode a createhow3 discriminated union.
@spec decode_createverf3(binary()) :: {:ok, createverf3(), binary()} | {:error, term()}
Decode an 8-byte CREATE verifier.
@spec decode_diropargs3(binary()) :: {:ok, diropargs3(), binary()} | {:error, term()}
Decode a diropargs3.
@spec decode_fattr3(binary()) :: {:ok, Tahr.NFSv3.Types.Fattr3.t(), binary()} | {:error, term()}
Decode fattr3.
Decode fhandle3.
Decode filename3.
Decode a 32-bit ftype3 enum to its atom.
Decode nfspath3.
@spec decode_nfsstat3(binary()) :: {:ok, nfsstat3() | {:unknown, non_neg_integer()}, binary()} | {:error, term()}
Decode a 32-bit nfsstat3 code back to its atom. Unknown codes
surface as {:unknown, n} so handlers can report it without
crashing.
@spec decode_nfstime3(binary()) :: {:ok, Tahr.NFSv3.Types.Nfstime3.t(), binary()} | {:error, term()}
Decode nfstime3.
@spec decode_post_op_attr(binary()) :: {:ok, Tahr.NFSv3.Types.Fattr3.t() | nil, binary()} | {:error, term()}
Decode post_op_attr.
Decode post_op_fh3.
@spec decode_pre_op_attr(binary()) :: {:ok, Tahr.NFSv3.Types.WccAttr.t() | nil, binary()} | {:error, term()}
Decode pre_op_attr.
@spec decode_sattr3(binary()) :: {:ok, Tahr.NFSv3.Types.Sattr3.t(), binary()} | {:error, term()}
Decode a sattr3 struct.
@spec decode_specdata3(binary()) :: {:ok, Tahr.NFSv3.Types.Specdata3.t(), binary()} | {:error, term()}
Decode specdata3.
@spec decode_stable_how(binary()) :: {:ok, stable_how(), binary()} | {:error, term()}
Decode a stable_how from the wire integer.
@spec decode_wcc_attr(binary()) :: {:ok, Tahr.NFSv3.Types.WccAttr.t(), binary()} | {:error, term()}
Decode a wcc_attr.
@spec decode_wcc_data(binary()) :: {:ok, Tahr.NFSv3.Types.WccData.t(), binary()} | {:error, term()}
Decode wcc_data.
@spec decode_writeverf3(binary()) :: {:ok, writeverf3(), binary()} | {:error, term()}
Decode an 8-byte WRITE verifier.
@spec encode_cookieverf3(cookieverf3()) :: binary()
Encode an 8-byte cookie verifier.
@spec encode_createhow3(createhow3()) :: binary()
Encode a createhow3 discriminated union.
@spec encode_createverf3(createverf3()) :: binary()
Encode an 8-byte CREATE verifier.
@spec encode_diropargs3(diropargs3()) :: binary()
Encode a diropargs3 (dir fhandle + name).
@spec encode_fattr3(Tahr.NFSv3.Types.Fattr3.t()) :: binary()
Encode fattr3.
Encode fhandle3 (variable opaque ≤ 64 bytes).
Encode filename3 (a non-empty XDR string).
Encode an ftype3 atom as its 32-bit wire enum.
Encode nfspath3 (an XDR string).
Encode an nfsstat3 atom as its 32-bit wire integer.
@spec encode_nfstime3(Tahr.NFSv3.Types.Nfstime3.t()) :: binary()
Encode nfstime3.
@spec encode_post_op_attr(Tahr.NFSv3.Types.Fattr3.t() | nil) :: binary()
Encode post_op_attr — nil means "no attrs available", otherwise
the Fattr3 is encoded prefixed with a TRUE flag.
Encode post_op_fh3 — nil means "no handle available", otherwise
the fhandle3 is encoded prefixed with a TRUE flag.
@spec encode_pre_op_attr(Tahr.NFSv3.Types.WccAttr.t() | nil) :: binary()
Encode pre_op_attr (the optional wcc_attr half of a wcc_data).
nil means no pre-op attrs were captured.
@spec encode_sattr3(Tahr.NFSv3.Types.Sattr3.t()) :: binary()
Encode a sattr3 struct.
@spec encode_specdata3(Tahr.NFSv3.Types.Specdata3.t()) :: binary()
Encode specdata3.
@spec encode_stable_how(stable_how()) :: binary()
Encode a stable_how atom to its wire integer.
@spec encode_wcc_attr(Tahr.NFSv3.Types.WccAttr.t()) :: binary()
Encode a wcc_attr (size + mtime + ctime).
@spec encode_wcc_data(Tahr.NFSv3.Types.WccData.t()) :: binary()
Encode wcc_data (pre_op_attr + post_op_attr).
@spec encode_writeverf3(writeverf3()) :: binary()
Encode an 8-byte WRITE verifier.
@spec nfs3_cookieverfsize() :: 8
READDIR / READDIRPLUS cookie verifier size.
@spec nfs3_createverfsize() :: 8
CREATE verifier size.
@spec nfs3_fhsize() :: 64
Max v3 file-handle byte size.
@spec nfs3_writeverfsize() :: 8
WRITE verifier size.