Filesystems implement FUSE operations with route macros or handle_event/3.
Exfuse.mount/3 mounts one filesystem process; routes define the directory
tree below that mount point.
init do
opts
end
readdir "/" do
{:reply, ["docs"], socket}
end
getattr "/" do
{:reply, dir(), socket}
end
readdir "/docs" do
{:reply, Map.keys(state), socket}
end
getattr "/docs" do
{:reply, dir(), socket}
end
getattr "/docs/:name" do
{:reply, file(size: byte_size(state[name])), socket}
end
read "/docs/:name" do
{:reply, read_chunk(state[name], event), socket}
end
plug "/media/*path", MyApp.MediaFile:name binds one path segment as a binary. *name binds the remaining path
tail as a list of segments, and bare * matches the remaining tail without
binding it. Route blocks can read event, socket and state; params are
endpoint variables, not fields on the socket. init blocks can read
mount_point and opts.
Or implement handle_event/3 and pattern match on the event payload:
def handle_event(:getattr, %{path: "/"}, socket) do
{:reply, dir(), socket}
end
def handle_event(:read, %{path: "/docs/" <> _} = event, socket) do
{:reply, read_chunk(event), socket}
end
def handle_event(_op, _event, socket), do: {:error, :enoent, socket}The payload is a map. Every payload includes path, uid, gid, pid, and
umask. Extra fields:
:read-flags,handle,offset,size:write-handle,offset,data:open-flags:create-mode,flags:truncate-size:rename-target:mkdirand:chmod-mode:chown-owner_uid,owner_gid:flushand:release-flags,handle:fsync-datasync,flags,handle
plug/2 delegates every operation matching the path to an endpoint process.
Endpoint processes are keyed by route params. A plugged module can define
init/1; after that it receives packets through handle_event/3.
defmodule MyApp.MediaFile do
def init(socket) do
{:ok, socket}
end
def handle_event(:read, %{params: %{file: file}} = event, socket) do
{:reply, read_media(file, event), socket}
end
end
Summary
Functions
Builds a directory attribute reply for getattr.
Builds a regular file attribute reply for getattr.
Builds a symlink attribute reply for getattr.
Types
@type event() :: %{ :path => String.t(), optional(:uid) => non_neg_integer(), optional(:gid) => non_neg_integer(), optional(:pid) => non_neg_integer(), optional(:umask) => non_neg_integer(), optional(:flags) => integer(), optional(:handle) => Exfuse.Socket.handle(), optional(:offset) => non_neg_integer(), optional(:size) => non_neg_integer(), optional(:mode) => non_neg_integer(), optional(:data) => binary(), optional(:target) => String.t(), optional(:owner_uid) => non_neg_integer(), optional(:owner_gid) => non_neg_integer(), optional(:datasync) => boolean() }
@type event_result() :: {:noreply, Exfuse.Socket.t()} | {:reply, term(), Exfuse.Socket.t()} | {:error, term(), Exfuse.Socket.t()}
@type operation() ::
:readdir
| :getattr
| :readlink
| :read
| :write
| :open
| :create
| :truncate
| :unlink
| :rename
| :mkdir
| :rmdir
| :chmod
| :chown
| :flush
| :release
| :fsync
Callbacks
@callback handle_event(operation(), event(), Exfuse.Socket.t()) :: event_result()