Behaviour for the export resolution layer the MOUNT v3 handler delegates to. Keeps Tahr decoupled from any particular backing store (a static config file, an in-memory test fixture, a database of exports, …).
The MountList and ExportNode types live in
Tahr.Mount.Types.
Callbacks
resolve/2— given the path a client passed toMNT, return the file-handle the server will hand back, or an error atom mapped to amountstat3(:perm,:noent,:notdir,:acces, …).list_exports/1— return the list of currently-published exports (used byMOUNTPROC3_EXPORT).list_mounts/1— optional bookkeeping: list the currently-active mounts (used byMOUNTPROC3_DUMP). Implementations that don't track mount state can return[].record_mount/3/forget_mount/3/forget_all_mounts/2— bookkeeping hooks invoked by the handler onMNT/UMNT/UMNTALL. Default-implementable as no-ops; the handler will still send the protocol-correct reply to the client either way.
Every callback receives an auth term (Tahr.RPC.Auth.credential())
and an opaque ctx map drawn from the original RPC envelope, so
backend implementations can do AUTH_SYS-aware lookup decisions
(uid / gid / hostname-from-AUTH_SYS) without the handler having
to flatten them out.
Summary
Callbacks
Forget all of a client's mount entries. Called on
MOUNTPROC3_UMNTALL. Default no-op.
Forget one client's mount entry for path. Called on
MOUNTPROC3_UMNT. Default no-op.
Return all exports currently published by the server. The handler
encodes the list as the MOUNTPROC3_EXPORT reply.
Return the list of mounts the backend wants to advertise via
MOUNTPROC3_DUMP. Backends that don't track mount state should
return an empty list — the protocol allows that.
Record a successful mount. Called from the handler after
resolve/2 returns :ok. Default no-op.
Resolve a MNT request to a file-handle.
Types
@type ctx() :: map()
Opaque context — the handler passes the RPC ctx through.
@type resolve_error() ::
:perm | :noent | :io | :acces | :notdir | :inval | :nametoolong
Reasons resolve/2 may refuse with.
Callbacks
@callback forget_all_mounts(client :: String.t(), Tahr.RPC.Auth.credential()) :: :ok
Forget all of a client's mount entries. Called on
MOUNTPROC3_UMNTALL. Default no-op.
@callback forget_mount( client :: String.t(), path :: Tahr.Mount.Types.dirpath(), Tahr.RPC.Auth.credential() ) :: :ok
Forget one client's mount entry for path. Called on
MOUNTPROC3_UMNT. Default no-op.
@callback list_exports(ctx()) :: [Tahr.Mount.Types.ExportNode.t()]
Return all exports currently published by the server. The handler
encodes the list as the MOUNTPROC3_EXPORT reply.
@callback list_mounts(ctx()) :: [Tahr.Mount.Types.MountList.t()]
Return the list of mounts the backend wants to advertise via
MOUNTPROC3_DUMP. Backends that don't track mount state should
return an empty list — the protocol allows that.
@callback record_mount( client :: String.t(), path :: Tahr.Mount.Types.dirpath(), Tahr.RPC.Auth.credential() ) :: :ok
Record a successful mount. Called from the handler after
resolve/2 returns :ok. Default no-op.
@callback resolve(path :: Tahr.Mount.Types.dirpath(), ctx()) :: {:ok, Tahr.Mount.Types.fhandle3(), [non_neg_integer()]} | {:error, resolve_error()}
Resolve a MNT request to a file-handle.
Return {:ok, fhandle, auth_flavors} on success — auth_flavors
is the list of RPC auth flavour numbers the export accepts (e.g.
[1] for AUTH_SYS only).
Return {:error, reason} to refuse the mount; the handler maps
reason to the RFC 1813 mountstat3 code.