Tahr.NFSv3.Types (tahr v0.1.0)

Copy Markdown View Source

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 verifier

Each 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_attrnil means "no attrs available", otherwise the Fattr3 is encoded prefixed with a TRUE flag.

Encode post_op_fh3nil 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

cookieverf3()

@type cookieverf3() :: <<_::64>>

Fixed 8-byte READDIR / READDIRPLUS cookie verifier.

count3()

@type count3() :: non_neg_integer()

uint32; byte count for a request/response.

createhow3()

@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 with NFS3ERR_EXIST if exists.
  • {:exclusive, createverf3} — atomic create-if-not-exists keyed by the 8-byte verifier.

createverf3()

@type createverf3() :: <<_::64>>

Fixed 8-byte CREATE verifier (used by EXCLUSIVE creates).

diropargs3()

@type diropargs3() :: {fhandle3(), filename3()}

Directory + file-name pair for LOOKUP / CREATE / etc.

fhandle3()

@type fhandle3() :: binary()

Variable-length file handle, ≤ 64 bytes.

fileid3()

@type fileid3() :: non_neg_integer()

uint64; persistent inode-style id.

filename3()

@type filename3() :: binary()

UTF-8-ish file name (NFSv3 doesn't constrain encoding).

ftype3()

@type ftype3() :: :reg | :dir | :blk | :chr | :lnk | :sock | :fifo

RFC 1813 §2.5 file types.

gid3()

@type gid3() :: non_neg_integer()

uint32; group id.

mode3()

@type mode3() :: non_neg_integer()

uint32; mode bits.

nfs_cookie3()

@type nfs_cookie3() :: non_neg_integer()

uint64; opaque READDIR cursor.

nfspath3()

@type nfspath3() :: binary()

UTF-8-ish symlink target.

nfsstat3()

@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.

offset3()

@type offset3() :: non_neg_integer()

uint64; byte offset within a file.

size3()

@type size3() :: non_neg_integer()

uint64; file size in bytes.

stable_how()

@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.

uid3()

@type uid3() :: non_neg_integer()

uint32; user id.

writeverf3()

@type writeverf3() :: <<_::64>>

Fixed 8-byte WRITE verifier (used by COMMIT).

Functions

decode_cookieverf3(binary)

@spec decode_cookieverf3(binary()) ::
  {:ok, cookieverf3(), binary()} | {:error, term()}

Decode an 8-byte cookie verifier.

decode_createhow3(binary)

@spec decode_createhow3(binary()) :: {:ok, createhow3(), binary()} | {:error, term()}

Decode a createhow3 discriminated union.

decode_createverf3(binary)

@spec decode_createverf3(binary()) ::
  {:ok, createverf3(), binary()} | {:error, term()}

Decode an 8-byte CREATE verifier.

decode_diropargs3(binary)

@spec decode_diropargs3(binary()) :: {:ok, diropargs3(), binary()} | {:error, term()}

Decode a diropargs3.

decode_fattr3(binary)

@spec decode_fattr3(binary()) ::
  {:ok, Tahr.NFSv3.Types.Fattr3.t(), binary()} | {:error, term()}

Decode fattr3.

decode_fhandle3(binary)

@spec decode_fhandle3(binary()) :: {:ok, fhandle3(), binary()} | {:error, term()}

Decode fhandle3.

decode_filename3(binary)

@spec decode_filename3(binary()) :: {:ok, filename3(), binary()} | {:error, term()}

Decode filename3.

decode_ftype3(binary)

@spec decode_ftype3(binary()) :: {:ok, ftype3(), binary()} | {:error, term()}

Decode a 32-bit ftype3 enum to its atom.

decode_nfspath3(binary)

@spec decode_nfspath3(binary()) :: {:ok, nfspath3(), binary()} | {:error, term()}

Decode nfspath3.

decode_nfsstat3(binary)

@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.

decode_nfstime3(binary)

@spec decode_nfstime3(binary()) ::
  {:ok, Tahr.NFSv3.Types.Nfstime3.t(), binary()} | {:error, term()}

Decode nfstime3.

decode_post_op_attr(binary)

@spec decode_post_op_attr(binary()) ::
  {:ok, Tahr.NFSv3.Types.Fattr3.t() | nil, binary()} | {:error, term()}

Decode post_op_attr.

decode_post_op_fh3(binary)

@spec decode_post_op_fh3(binary()) ::
  {:ok, fhandle3() | nil, binary()} | {:error, term()}

Decode post_op_fh3.

decode_pre_op_attr(binary)

@spec decode_pre_op_attr(binary()) ::
  {:ok, Tahr.NFSv3.Types.WccAttr.t() | nil, binary()} | {:error, term()}

Decode pre_op_attr.

decode_sattr3(binary)

@spec decode_sattr3(binary()) ::
  {:ok, Tahr.NFSv3.Types.Sattr3.t(), binary()} | {:error, term()}

Decode a sattr3 struct.

decode_specdata3(binary)

@spec decode_specdata3(binary()) ::
  {:ok, Tahr.NFSv3.Types.Specdata3.t(), binary()} | {:error, term()}

Decode specdata3.

decode_stable_how(binary)

@spec decode_stable_how(binary()) :: {:ok, stable_how(), binary()} | {:error, term()}

Decode a stable_how from the wire integer.

decode_wcc_attr(binary)

@spec decode_wcc_attr(binary()) ::
  {:ok, Tahr.NFSv3.Types.WccAttr.t(), binary()} | {:error, term()}

Decode a wcc_attr.

decode_wcc_data(binary)

@spec decode_wcc_data(binary()) ::
  {:ok, Tahr.NFSv3.Types.WccData.t(), binary()} | {:error, term()}

Decode wcc_data.

decode_writeverf3(binary)

@spec decode_writeverf3(binary()) :: {:ok, writeverf3(), binary()} | {:error, term()}

Decode an 8-byte WRITE verifier.

encode_cookieverf3(verf)

@spec encode_cookieverf3(cookieverf3()) :: binary()

Encode an 8-byte cookie verifier.

encode_createhow3(arg)

@spec encode_createhow3(createhow3()) :: binary()

Encode a createhow3 discriminated union.

encode_createverf3(verf)

@spec encode_createverf3(createverf3()) :: binary()

Encode an 8-byte CREATE verifier.

encode_diropargs3(arg)

@spec encode_diropargs3(diropargs3()) :: binary()

Encode a diropargs3 (dir fhandle + name).

encode_fattr3(a)

@spec encode_fattr3(Tahr.NFSv3.Types.Fattr3.t()) :: binary()

Encode fattr3.

encode_fhandle3(fh)

@spec encode_fhandle3(fhandle3()) :: binary()

Encode fhandle3 (variable opaque ≤ 64 bytes).

encode_filename3(name)

@spec encode_filename3(filename3()) :: binary()

Encode filename3 (a non-empty XDR string).

encode_ftype3(t)

@spec encode_ftype3(ftype3()) :: binary()

Encode an ftype3 atom as its 32-bit wire enum.

encode_nfspath3(path)

@spec encode_nfspath3(nfspath3()) :: binary()

Encode nfspath3 (an XDR string).

encode_nfsstat3(stat)

@spec encode_nfsstat3(nfsstat3()) :: binary()

Encode an nfsstat3 atom as its 32-bit wire integer.

encode_nfstime3(nfstime3)

@spec encode_nfstime3(Tahr.NFSv3.Types.Nfstime3.t()) :: binary()

Encode nfstime3.

encode_post_op_attr(a)

@spec encode_post_op_attr(Tahr.NFSv3.Types.Fattr3.t() | nil) :: binary()

Encode post_op_attrnil means "no attrs available", otherwise the Fattr3 is encoded prefixed with a TRUE flag.

encode_post_op_fh3(fh)

@spec encode_post_op_fh3(fhandle3() | nil) :: binary()

Encode post_op_fh3nil means "no handle available", otherwise the fhandle3 is encoded prefixed with a TRUE flag.

encode_pre_op_attr(w)

@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.

encode_sattr3(s)

@spec encode_sattr3(Tahr.NFSv3.Types.Sattr3.t()) :: binary()

Encode a sattr3 struct.

encode_specdata3(specdata3)

@spec encode_specdata3(Tahr.NFSv3.Types.Specdata3.t()) :: binary()

Encode specdata3.

encode_stable_how(atom)

@spec encode_stable_how(stable_how()) :: binary()

Encode a stable_how atom to its wire integer.

encode_wcc_attr(w)

@spec encode_wcc_attr(Tahr.NFSv3.Types.WccAttr.t()) :: binary()

Encode a wcc_attr (size + mtime + ctime).

encode_wcc_data(wcc_data)

@spec encode_wcc_data(Tahr.NFSv3.Types.WccData.t()) :: binary()

Encode wcc_data (pre_op_attr + post_op_attr).

encode_writeverf3(verf)

@spec encode_writeverf3(writeverf3()) :: binary()

Encode an 8-byte WRITE verifier.

nfs3_cookieverfsize()

@spec nfs3_cookieverfsize() :: 8

READDIR / READDIRPLUS cookie verifier size.

nfs3_createverfsize()

@spec nfs3_createverfsize() :: 8

CREATE verifier size.

nfs3_fhsize()

@spec nfs3_fhsize() :: 64

Max v3 file-handle byte size.

nfs3_writeverfsize()

@spec nfs3_writeverfsize() :: 8

WRITE verifier size.