blob: 2e1ce113ddfad2e12c54eb172c57f3ee595de235 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.io;
using fuchsia.mem;
using zx;
/// Describes how the connection to an should be handled, as well as
/// how to interpret the optional handle.
///
/// Refer to |Node::Describe()| and |Node::OnOpen()| for usage.
union NodeInfo {
Service service;
FileObject file;
DirectoryObject directory;
Pipe pipe;
Vmofile vmofile;
Device device;
Tty tty;
};
/// The default protocol, interface information must be acquired some
/// other way.
struct Service {
};
/// Indicates the file is ready for reading.
const uint32 FILE_SIGNAL_READABLE = 0x01000000; // ZX_USER_SIGNAL_0
/// Indicates the file is ready for writing.
const uint32 FILE_SIGNAL_WRITABLE = 0x02000000; // ZX_USER_SIGNAL_1
/// The object may be cast to interface 'File'.
struct FileObject {
/// An optional event which transmits information about an object's readability
/// or writability. This event relays information about the underlying object, not
/// the capability granted to client: this event may be signalled "readable" on a
/// connection that does not have the capability to read.
///
/// The "FILE_SIGNAL_" values may be observed on this event.
handle<event>? event;
};
/// The object may be cast to interface 'Directory'.
struct DirectoryObject {
};
/// The object is accompanied by a pipe.
struct Pipe {
handle<socket> socket;
};
/// The object is a file which is represented as an immutable VMO.
/// Although a VMO is returned as a part of this structure, this underlying object
/// may represent multiple Vmofiles. To identify the logical portion of the VMO
/// that represents the single file, an offset and length parameter are also supplied.
struct Vmofile {
/// The VMO which backs this file.
handle<vmo> vmo;
/// The index into |vmo| which represents the first byte of the file.
uint64 offset;
/// The number of bytes, starting at |offset|, which may be used to represent this file.
uint64 length;
};
/// Indicates the device is ready for reading.
const uint32 DEVICE_SIGNAL_READABLE = 0x01000000; // ZX_USER_SIGNAL_0
/// Indicates the device is ready for writing.
const uint32 DEVICE_SIGNAL_WRITABLE = 0x02000000; // ZX_USER_SIGNAL_1
/// Indicates the device has encountered an error state.
const uint32 DEVICE_SIGNAL_ERROR = 0x04000000; // ZX_USER_SIGNAL_2
/// Indicates the device has hung up on the current connection.
const uint32 DEVICE_SIGNAL_HANGUP = 0x08000000; // ZX_USER_SIGNAL_3
/// Indicates an out-of-band state transition has occurred.
const uint32 DEVICE_SIGNAL_OOB = 0x10000000; // ZX_USER_SIGNAL_4
/// The object may be cast to interface 'Device'.
struct Device {
/// An optional event which transmits information about a device's state.
///
/// The "DEVICE_SIGNAL_" values may be observed on this event.
handle<event>? event;
};
/// The object may be cast to interface 'Tty'
struct Tty {
handle<event>? event;
};
/// Can read from target object.
const uint32 OPEN_RIGHT_READABLE = 0x00000001;
/// Can write to target object.
const uint32 OPEN_RIGHT_WRITABLE = 0x00000002;
/// Connection can mount/umount filesystem.
const uint32 OPEN_RIGHT_ADMIN = 0x00000004;
/// Create the object if it doesn't exist.
const uint32 OPEN_FLAG_CREATE = 0x00010000;
/// (with Create) Fail if the object already exists.
const uint32 OPEN_FLAG_CREATE_IF_ABSENT = 0x00020000;
/// Truncate the object before usage.
const uint32 OPEN_FLAG_TRUNCATE = 0x00040000;
/// Assert that the object to be opened is a directory.
/// Return an error if the target object is not a directory.
const uint32 OPEN_FLAG_DIRECTORY = 0x00080000;
/// Seek to the end of the object before all writes.
const uint32 OPEN_FLAG_APPEND = 0x00100000;
/// If the object is a mount point, open the local directory.
const uint32 OPEN_FLAG_NO_REMOTE = 0x00200000;
/// Open a reference to the object, not the object itself.
/// It is ONLY valid to pass the following flags together with OPEN_FLAG_NODE_REFERENCE:
/// - OPEN_FLAG_DIRECTORY
/// - OPEN_FLAG_NOT_DIRECTORY
/// - OPEN_FLAG_DESCRIBE
/// otherwise an error is returned.
/// If an object is opened or cloned using this method, the resulting connection does not carry
/// any permission flags.
/// The resulting node allows a limited set of operations: |GetAttr|, |Clone|, |Close|, |Describe|,
/// and, if the node is a file, these extra operations: |GetFlags|, |SetFlags|.
const uint32 OPEN_FLAG_NODE_REFERENCE = 0x00400000;
/// Binary OR of OPEN_FLAG_DIRECTORY, OPEN_FLAG_NOT_DIRECTORY, OPEN_FLAG_DESCRIBE, and
/// OPEN_FLAG_NODE_REFERENCE. Flags used when opening a node reference must fall within this mask.
const uint32 OPEN_FLAGS_ALLOWED_WITH_NODE_REFERENCE = 0x02c80000;
/// Requests that an "OnOpen" event is sent to the interface request.
/// The event will contain a non-null NodeInfo if the open/clone is successful.
const uint32 OPEN_FLAG_DESCRIBE = 0x00800000;
/// Specify this flag to request POSIX-compatibility. Currently, it affects permission handling.
/// During Open:
/// - If the target path is a directory, the rights on the new connection expands to include
/// OPEN_RIGHT_WRITABLE if and only if the current connection and all intermediate mount points
/// are writable.
/// - Otherwise, this flag is ignored. It is an access denied error to request more rights
/// than those on the current connection, or any intermediate mount points.
///
/// If the posix compatibility flag is not specified, opening always uses the requested rights,
/// failing the operation with access denied error if requested rights exceeds the rights attached
/// to the current connection.
///
/// If the requesting connection is read-only and the requested rights are read-only, the flag
/// may be ignored by the server, and is not forwarded downstream. This is an implementation detail,
/// necessary to enforce hierarchical permissions across mount points, and should have no effect
/// on the expected behavior for clients.
const uint32 OPEN_FLAG_POSIX = 0x01000000;
/// Assert that the object to be opened is not a directory.
/// Return an error if the target object is a directory.
const uint32 OPEN_FLAG_NOT_DIRECTORY = 0x02000000;
/// When used during clone, the new connection inherits the rights on the source connection,
/// regardless if it is a file or directory. Otherwise, clone attempts to use the requested rights.
/// It is invalid to pass any of the OPEN_RIGHT_* flags together with CLONE_FLAG_SAME_RIGHTS.
const uint32 CLONE_FLAG_SAME_RIGHTS = 0x04000000;
/// Node defines the minimal interface for entities which can be accessed in a filesystem.
[Layout="Simple", FragileBase]
protocol Node {
/// Create another connection to the same remote object.
///
/// |flags| may be any of:
/// - OPEN_RIGHT_*
/// - OPEN_FLAG_APPEND
/// - OPEN_FLAG_NO_REMOTE
/// - OPEN_FLAG_DESCRIBE
/// - CLONE_FLAG_SAME_RIGHTS
///
/// All other flags are ignored.
///
/// The OPEN_RIGHT_* bits in |flags| request corresponding rights over the resulting
/// cloned object.
/// The cloned object must have rights less than or equal to the original object.
/// Alternatively, pass CLONE_FLAG_SAME_RIGHTS to inherit the rights on the source connection.
/// It is invalid to pass any of the OPEN_RIGHT_* flags together with CLONE_FLAG_SAME_RIGHTS.
Clone(uint32 flags, request<Node> object);
/// Terminates connection with object.
///
/// This method does not require any rights.
Close() -> (zx.status s);
/// Returns extra information about the type of the object.
/// If the |Describe| operation fails, the connection is closed.
///
/// This method does not require any rights.
Describe() -> (NodeInfo info);
/// An event produced eagerly by a FIDL server if requested by |OPEN_FLAG_DESCRIBE|.
///
/// Indicates the success or failure of the open operation, and optionally describes the
/// object. If the status is |ZX_OK|, |info| contains descriptive information about the object
/// (the same as would be returned by |Describe|).
-> OnOpen(zx.status s, NodeInfo? info);
/// Synchronizes updates to the node to the underlying media, if it exists.
///
/// This method does not require any rights.
Sync() -> (zx.status s);
/// Acquires information about the node.
///
/// This method does not require any rights.
GetAttr() -> (zx.status s, NodeAttributes attributes);
/// Updates information about the node.
/// |flags| may be any of NODE_ATTRIBUTE_FLAG_*.
///
/// This method requires following rights: OPEN_RIGHT_WRITABLE.
SetAttr(uint32 flags, NodeAttributes attributes) -> (zx.status s);
/// Deprecated. Only for use with compatibility with devhost.
Ioctl(uint32 opcode, uint64 max_out, vector<handle>:MAX_IOCTL_HANDLES handles,
vector<uint8>:MAX_BUF in)
-> (zx.status s, vector<handle>:MAX_IOCTL_HANDLES handles, vector<uint8>:MAX_BUF out);
};
/// Bits reserved for posix protections. Native fuchsia filesystems
/// are not required to set bits contained within MODE_PROTECTION_MASK,
/// but filesystems that wish to do so may refer to sys/stat.h for their
/// definitions.
const uint32 MODE_PROTECTION_MASK = 0x00FFF;
/// Bits indicating node type. The canonical mechanism to check
/// for a node type is to take 'mode', bitwise AND it with the
/// MODE_TYPE_MASK, and check exact equality against a mode type.
const uint32 MODE_TYPE_MASK = 0xFF000;
const uint32 MODE_TYPE_DIRECTORY = 0x04000;
const uint32 MODE_TYPE_BLOCK_DEVICE = 0x06000;
const uint32 MODE_TYPE_FILE = 0x08000;
const uint32 MODE_TYPE_SOCKET = 0x0C000;
const uint32 MODE_TYPE_SERVICE = 0x10000;
/// NodeAttributes defines generic information about a filesystem node.
struct NodeAttributes {
/// Protection bits and node type information describe in 'mode'.
uint32 mode;
/// A filesystem-unique ID.
uint64 id;
/// Node size, in bytes.
uint64 content_size;
/// Space needed to store node (possibly larger than size), in bytes.
uint64 storage_size;
/// Hard link count.
uint64 link_count;
/// Time of creation (may be updated manually after creation) in ns since Unix epoch, UTC.
uint64 creation_time;
/// Time of last modification in ns since Unix epoch, UTC.
uint64 modification_time;
};
const uint64 MAX_IOCTL_HANDLES = 2;
/// The maximal buffer size which can be transmitted for buffered operations.
/// This capacity is currently set somewhat arbitrarily.
const uint64 MAX_BUF = 8192;
/// The maximum length, in bytes, of a filesystem string.
// TODO(smklein): Update to 4095. +1 is for null-terminator, which shouldn't be
// part of the FIDL length.
const uint64 MAX_PATH = 4096;
/// The maximum length, in bytes, of a single filesystem component.
const uint64 MAX_FILENAME = 255;
/// The fields of 'attributes' which are used to update the Node are indicated
/// by the 'flags' argument.
const uint32 NODE_ATTRIBUTE_FLAG_CREATION_TIME = 0x00000001;
const uint32 NODE_ATTRIBUTE_FLAG_MODIFICATION_TIME = 0x00000002;
/// Update the Seek offset.
enum SeekOrigin : uint32 {
/// Seek from the start of the file.
START = 0;
/// Seek from the current position in the file.
CURRENT = 1;
/// Seek from the end of the file.
END = 2;
};
/// Requests that the VMO be readable.
const uint32 VMO_FLAG_READ = 0x00000001;
/// Requests that the VMO be writable.
const uint32 VMO_FLAG_WRITE = 0x00000002;
/// Requests that the VMO be executable.
const uint32 VMO_FLAG_EXEC = 0x00000004;
/// Require a copy-on-write clone of the underlying VMO.
/// The request should fail if the VMO is not cloned.
/// May not be supplied with fuchsia_io_VMO_FLAG_EXACT.
const uint32 VMO_FLAG_PRIVATE = 0x00010000;
/// Require an exact (non-cloned) handle to the underlying VMO.
/// The request should fail if a handle to the exact VMO is not returned.
/// May not be supplied with VMO_FLAG_PRIVATE.
const uint32 VMO_FLAG_EXACT = 0x00020000;
/// File defines the interface of a node which contains a flat layout of data.
[Layout = "Simple"]
protocol File {
compose Node;
/// Reads 'count' bytes at the seek offset.
/// The seek offset is moved forward by the number of bytes read.
///
/// This method requires following rights: OPEN_RIGHT_READABLE.
Read(uint64 count) -> (zx.status s, vector<uint8>:MAX_BUF data);
/// Reads 'count' bytes at the provided offset.
/// Does not affect the seek offset.
///
/// This method requires following rights: OPEN_RIGHT_READABLE.
ReadAt(uint64 count, uint64 offset) -> (zx.status s, vector<uint8>:MAX_BUF data);
/// Writes data at the seek offset.
/// The seek offset is moved forward by the number of bytes written.
///
/// This method requires following rights: OPEN_RIGHT_WRITABLE.
Write(vector<uint8>:MAX_BUF data) -> (zx.status s, uint64 actual);
/// Writes data to the provided offset.
/// Does not affect the seek offset.
///
/// This method requires following rights: OPEN_RIGHT_WRITABLE.
WriteAt(vector<uint8>:MAX_BUF data, uint64 offset) -> (zx.status s, uint64 actual);
/// Moves the offset at which the next invocation of |Read()| or |Write()| will
/// occur.
///
/// This method does not require any rights.
Seek(int64 offset, SeekOrigin start) -> (zx.status s, uint64 offset);
/// Shrinks the file size to 'length' bytes.
///
/// This method requires following rights: OPEN_RIGHT_WRITABLE.
Truncate(uint64 length) -> (zx.status s);
/// Acquires the Directory::Open rights and flags used to access this file.
///
/// This method does not require any rights.
GetFlags() -> (zx.status s, uint32 flags);
/// Changes the Directory::Open flags used to access the file.
/// Supported flags which can be turned on / off:
/// - OPEN_FLAG_APPEND
///
/// This method does not require any rights.
SetFlags(uint32 flags) -> (zx.status s);
/// Acquires a buffer representing this file, if there is one, with the
/// requested access rights.
///
/// |flags| may be any of VMO_FLAG_*.
///
/// This method requires following rights:
/// - OPEN_RIGHT_WRITABLE if |flags| includes VMO_FLAG_WRITE.
/// - OPEN_RIGHT_READABLE if |flags| includes VMO_FLAG_READ or VMO_FLAG_EXEC.
GetBuffer(uint32 flags) -> (zx.status s, fuchsia.mem.Buffer? buffer);
};
// Dirent type information associated with the results of ReadDirents.
// The following values are aligned with the values from libc's "dirent.h" "DT_...".
/// A dirent with an unknown type.
const uint8 DIRENT_TYPE_UNKNOWN = 0;
/// A dirent representing a directory object.
const uint8 DIRENT_TYPE_DIRECTORY = 4;
/// A dirent representing a block device object.
const uint8 DIRENT_TYPE_BLOCK_DEVICE = 6;
/// A dirent representing a file object.
const uint8 DIRENT_TYPE_FILE = 8;
/// A dirent representing a socket object.
const uint8 DIRENT_TYPE_SOCKET = 12;
/// A dirent representing a service object.
const uint8 DIRENT_TYPE_SERVICE = 16;
/// Nodes which do not have ino values should return this value
/// from Readdir and GetAttr.
const uint64 INO_UNKNOWN = 0xFFFFFFFFFFFFFFFF;
/// Indicates the directory being watched has been deleted.
const uint8 WATCH_EVENT_DELETED = 0;
/// Indicates a node has been created (either new or moved) into a directory.
const uint8 WATCH_EVENT_ADDED = 1;
/// Identifies a node has been removed (either deleted or moved) from the directory.
const uint8 WATCH_EVENT_REMOVED = 2;
/// Identifies a node already existed in the directory when watching started.
const uint8 WATCH_EVENT_EXISTING = 3;
/// Identifies that no more WATCH_EVENT_EXISTING events will be sent.
const uint8 WATCH_EVENT_IDLE = 4;
/// Used by Directory::Watch. Requests transmission of WATCH_EVENT_DELETED.
const uint32 WATCH_MASK_DELETED = 0x00000001;
/// Used by Directory::Watch. Requests transmission of WATCH_EVENT_ADDED.
const uint32 WATCH_MASK_ADDED = 0x00000002;
/// Used by Directory::Watch. Requests transmission of WATCH_EVENT_REMOVED.
const uint32 WATCH_MASK_REMOVED = 0x00000004;
/// Used by Directory::Watch. Requests transmission of WATCH_EVENT_EXISTING.
const uint32 WATCH_MASK_EXISTING = 0x00000008;
/// Used by Directory::Watch. Requests transmission of WATCH_EVENT_IDLE.
const uint32 WATCH_MASK_IDLE = 0x00000010;
/// Used by Directory::Watch. Requests transmission of all watcher events.
const uint32 WATCH_MASK_ALL = 0x0000001F;
/// TODO(ZX-2645): Unused.
///
/// WatchedEvent describes events returned from a DirectoryWatcher.
struct WatchedEvent {
uint8 event;
uint8 len;
vector<uint8>:MAX_FILENAME name;
};
/// TODO(ZX-2645): Unused.
///
/// DirectoryWatcher transmits messages from a filesystem server
/// about events happening in the filesystem. Clients can register
/// new watchers using the Directory "Watch" method, where they can
/// filter which events they want to receive notifications for.
[Layout = "Simple"]
protocol DirectoryWatcher {
/// TODO(smklein): Convert this to a vector of WatchedEvents, when possible.
OnEvent(vector<uint8>:MAX_BUF events);
};
/// Directory defines a node which is capable of containing other Objects.
[Layout = "Simple", FragileBase]
protocol Directory {
compose Node;
/// Opens a new object relative to this directory object.
///
/// |path| may contain multiple segments, separated by "/" characters,
/// and should never be empty i.e. "" is an invalid path.
///
/// |flags| may be any of the OPEN_FLAG_* and OPEN_RIGHT_* values, bitwise ORed together.
/// The OPEN_FLAG_DESCRIBE flag may cause an |OnOpen| event to be transmitted
/// on the |object| handle, indicating the type of object opened.
///
/// If an unknown value is sent for either flags or mode, the connection should
/// be closed.
///
/// OPEN_RIGHTS_* flags provided in |flags| will restrict access rights on the |object| channel
/// which will be connected to the opened entity.
///
/// Rights are never increased. When you open a nested entity within a directory, you may only
/// request the same rights as what the directory connection already has, or a subset of those.
/// Exceeding those rights causes an access denied error to be transmitted in the
/// |OnOpen| event if applicable, and the |object| connection closed.
///
/// The caller must specify either one or more of the OPEN_RIGHT_* flags, or
/// the OPEN_FLAG_NODE_REFERENCE flag.
// TODO(smklein): Who uses mode? Can it be removed?
Open(uint32 flags, uint32 mode, string:MAX_PATH path, request<Node> object);
/// Detaches an object from this directory object.
///
/// The underlying object may or may not be deleted after this method
/// completes: although the link will be removed from the containing directory,
/// objects with multiple references (such as files which are still open)
/// will not actually be destroyed until all references are removed.
///
/// If a directory is unlinked while it still has an open reference,
/// it must become read-only, preventing new entries from being created
/// until all references close and the directory is destroyed.
///
/// |path| identifies the file which should be detached.
/// If |path| contains multiple segments, separated by "/" characters,
/// then the directory is traversed, one segment at a time, relative to the
/// originally accessed Directory.
///
/// Returns:
/// ZX_ERR_ACCESS_DENIED if the connection (or the underlying filesystem) does not
/// allow writable access.
/// ZX_ERR_INVALID_ARGS if |path| contains ".." segments.
/// ZX_ERR_NOT_EMPTY if |path| refers to a non-empty directory.
/// ZX_ERR_UNAVAILABLE if |path| refers to a mount point, containing a remote channel.
/// ZX_ERR_UNAVAILABLE if |path| is ".".
///
/// Other errors may be returned for filesystem-specific reasons.
///
/// This method requires following rights: OPEN_RIGHT_WRITABLE.
Unlink(string:MAX_PATH path) -> (zx.status s);
/// Reads a collection of variably sized dirents into a buffer.
/// The number of dirents in a directory may be very large: akin to
/// calling read multiple times on a file, directories have a seek
/// offset which is updated on subsequent calls to ReadDirents.
///
/// These dirents are of the form:
/// struct dirent {
/// // Describes the inode of the entry.
/// uint64 ino;
/// // Describes the length of the dirent name.
/// uint8 size;
/// // Describes the type of the entry. Aligned with the
/// /// POSIX d_type values. Use DIRENT_TYPE_* constants.
/// uint8 type;
/// // Unterminated name of entry.
/// char name[0];
/// }
///
/// This method does not require any rights, since one could always probe for
/// directory contents by triggering name conflicts during file creation.
// TODO(smklein): Convert to a vector of variable-length objects, when
// llcpp arrives.
// TODO(smklein): Get rid of "max_bytes".
// TODO(smklein): Document the behavior when the seek pointer reaches the end of the directory.
ReadDirents(uint64 max_bytes) -> (zx.status s, vector<uint8>:MAX_BUF dirents);
/// Resets the directory seek offset.
///
/// This method does not require any rights, similar to ReadDirents.
Rewind() -> (zx.status s);
/// Acquires a token to a Directory which can be used to identify
/// access to it at a later point in time.
///
/// This method requires following rights: OPEN_RIGHT_WRITABLE.
GetToken() -> (zx.status s, handle? token);
/// Renames an object named src to the name dst, in a directory represented by token.
///
/// |src/dst| must be resolved object names. Including "/" in any position
/// other than the end of the string will return ZX_ERR_INVALID_ARGS.
/// Returning "/" at the end of either string implies that it must be a
/// directory, or else ZX_ERR_NOT_DIR should be returned.
///
/// This method requires following rights: OPEN_RIGHT_WRITABLE.
Rename(string:MAX_PATH src, handle dst_parent_token, string:MAX_PATH dst) -> (zx.status s);
/// Creates a link to an object named src by the name dst, within a directory represented by
/// token.
///
/// |src| must be a resolved object name. Including "/" in the string will
/// return ZX_ERR_INVALID_ARGS.
///
/// |dst| must be a resolved object name. Including "/" in the string will
/// return ZX_ERR_INVALID_ARGS.
///
/// This method requires following rights: OPEN_RIGHT_WRITABLE.
Link(string:MAX_PATH src, handle dst_parent_token, string:MAX_PATH dst) -> (zx.status s);
/// Watches a directory, receiving events of added messages on the
/// watcher request channel.
///
/// The "watcher" handle will send messages of the form:
/// struct {
/// uint8 event;
/// uint8 len;
/// char name[];
/// };
/// Where names are NOT null-terminated.
///
/// TODO: This API is unstable; in the future, watcher will be a "DirectoryWatcher" client.
///
/// Mask specifies a bitmask of events to observe.
/// Options must be zero; it is reserved.
///
/// This method does not require any rights, similar to ReadDirents.
Watch(uint32 mask, uint32 options, handle<channel> watcher) -> (zx.status s);
};
const uint32 MOUNT_CREATE_FLAG_REPLACE = 0x00000001;
const uint64 MAX_FS_NAME_BUFFER = 32;
struct FilesystemInfo {
/// The number of data bytes which may be stored in a filesystem.
uint64 total_bytes;
/// The number of data bytes which are in use by the filesystem.
uint64 used_bytes;
/// The number of nodes which may be stored in the filesystem.
uint64 total_nodes;
/// The number of nodes used by the filesystem.
uint64 used_nodes;
/// The amount of space which may be allocated from the underlying
/// volume manager. If unsupported, this will be zero.
uint64 free_shared_pool_bytes;
/// A unique identifier for this filesystem instance. Will not be preserved
/// across reboots.
uint64 fs_id;
/// The size of a single filesystem block.
uint32 block_size;
/// The maximum length of a filesystem name.
uint32 max_filename_size;
/// A unique identifier for the type of the underlying filesystem.
uint32 fs_type;
uint32 padding;
/// TODO(smklein): Replace this field with a string when supported
/// by the "Simple" interface. At the moment, name is a fixed-size,
/// null-terminated buffer.
array<int8>:MAX_FS_NAME_BUFFER name;
};
/// DirectoryAdmin defines a directory which is capable of handling
/// administrator tasks within the filesystem.
[Layout = "Simple"]
protocol DirectoryAdmin {
compose Directory;
/// Mount a channel representing a remote filesystem onto this directory.
/// All future requests to this node will be forwarded to the remote filesystem.
/// To re-open a node without forwarding to the remote target, the node
/// should be opened with OPEN_FLAG_NO_REMOTE.
Mount(Directory remote) -> (zx.status s);
/// Atomically create a directory with a provided path, and mount the
/// remote handle to the newly created directory.
MountAndCreate(Directory remote, string:MAX_FILENAME name, uint32 flags) -> (zx.status s);
/// Unmount this filesystem. After this function returns successfully,
/// all connections to the filesystem will be terminated.
Unmount() -> (zx.status s);
/// Detach a node which was previously attached to this directory
/// with Mount.
UnmountNode() -> (zx.status s, Directory? remote);
/// Query the filesystem for filesystem-specific information.
QueryFilesystem() -> (zx.status s, FilesystemInfo? info);
/// Acquire the path to the device backing this filesystem, if there is one.
GetDevicePath() -> (zx.status s, string:MAX_PATH? path);
};