402 lines
15 KiB
Plaintext
402 lines
15 KiB
Plaintext
// 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 zx;
|
|
|
|
// Interfaces which may be returned by NodeInfo, an object
|
|
// returned when calling Open or Describe:
|
|
|
|
// The default protocol, interface information must be acquired some
|
|
// other way.
|
|
struct Service {
|
|
uint8 reserved;
|
|
};
|
|
|
|
// The object may be cast to interface 'File'.
|
|
struct FileObject {
|
|
handle<event>? event;
|
|
};
|
|
|
|
// The object may be cast to interface 'Directory'.
|
|
struct DirectoryObject {
|
|
uint8 reserved;
|
|
};
|
|
|
|
// The object is accompanied by a pipe.
|
|
struct Pipe {
|
|
handle<socket> socket;
|
|
};
|
|
|
|
// The object is accompanied by a VMO.
|
|
struct Vmofile {
|
|
handle<vmo> vmo;
|
|
uint64 offset;
|
|
uint64 length;
|
|
};
|
|
|
|
// The object may be cast to interface 'Device'.
|
|
struct Device {
|
|
handle<event>? event;
|
|
};
|
|
|
|
// Describes how the connection to the Object should be handled, as well as
|
|
// how to interpret the optional handle.
|
|
union NodeInfo {
|
|
Service service;
|
|
FileObject file;
|
|
DirectoryObject directory;
|
|
Pipe pipe;
|
|
Vmofile vmofile;
|
|
Device device;
|
|
};
|
|
|
|
// 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;
|
|
// 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.
|
|
const uint32 OPEN_FLAG_NODE_REFERENCE = 0x00400000;
|
|
// Requests that an "OnOpen" event is sent, with
|
|
// a non-null NodeInfo (if the open is successful).
|
|
// Implies "OPEN_FLAG_STATUS".
|
|
const uint32 OPEN_FLAG_DESCRIBE = 0x00800000;
|
|
// Requests that an "OnOpen" event is sent.
|
|
const uint32 OPEN_FLAG_STATUS = 0x01000000;
|
|
|
|
// Node defines the minimal interface for entities which can be accessed in a filesystem.
|
|
[Layout="Simple", FragileBase]
|
|
interface Node {
|
|
// Create another connection to the same remote object.
|
|
Clone(uint32 flags, request<Node> object);
|
|
|
|
// Terminates connection with object.
|
|
Close() -> (zx.status s);
|
|
|
|
// Returns extra information about the type of the object.
|
|
// If the |Describe| operation fails, the connection is closed.
|
|
Describe() -> (NodeInfo info);
|
|
|
|
// An event produced eagerly by a fidl server if requested
|
|
// by open flags.
|
|
// Indicates the success or failure of the open operation,
|
|
// and optionally describes the object.
|
|
// If the status is |ZX_OK| and |OPEN_FLAG_DESCRIBE| was passed
|
|
// to open, |info| contains descriptive information about
|
|
// the object (the same as would be returned by |Describe|),
|
|
// otherwise it is null.
|
|
-> OnOpen(zx.status s, NodeInfo? info);
|
|
|
|
// Synchronizes updates to the node to the underlying media, if it exists.
|
|
Sync() -> (zx.status s);
|
|
|
|
// Acquire information about the node.
|
|
GetAttr() -> (zx.status s, NodeAttributes attributes);
|
|
|
|
// Update information about the node.
|
|
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;
|
|
const uint64 MAX_BUF = 8192;
|
|
const uint64 MAX_PATH = 4096;
|
|
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;
|
|
};
|
|
|
|
// VMO access rights.
|
|
const uint32 VMO_FLAG_READ = 0x00000001;
|
|
const uint32 VMO_FLAG_WRITE = 0x00000002;
|
|
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"]
|
|
interface File : Node {
|
|
// Read 'count' bytes at the seek offset.
|
|
// The seek offset is moved forward by the number of bytes read.
|
|
Read(uint64 count) -> (zx.status s, vector<uint8>:MAX_BUF data);
|
|
|
|
// Read 'count' bytes at the provided offset.
|
|
// Does not affect the seek offset.
|
|
ReadAt(uint64 count, uint64 offset) -> (zx.status s, vector<uint8>:MAX_BUF data);
|
|
|
|
// Write data at the seek offset.
|
|
// The seek offset is moved forward by the number of bytes written.
|
|
Write(vector<uint8>:MAX_BUF data) -> (zx.status s, uint64 actual);
|
|
|
|
// Write data to the provided offset.
|
|
// Does not affect the seek offset.
|
|
WriteAt(vector<uint8>:MAX_BUF data, uint64 offset) -> (zx.status s, uint64 actual);
|
|
|
|
Seek(int64 offset, SeekOrigin start) -> (zx.status s, uint64 offset);
|
|
|
|
// Shrink the file size to 'length' bytes.
|
|
Truncate(uint64 length) -> (zx.status s);
|
|
|
|
// Acquire the Directory::Open rights and flags used to access this file.
|
|
GetFlags() -> (zx.status s, uint32 flags);
|
|
|
|
// Change the Directory::Open flags used to access the file.
|
|
// Supported flags which can be turned on / off:
|
|
// - OPEN_FLAG_APPEND
|
|
SetFlags(uint32 flags) -> (zx.status s);
|
|
|
|
// Acquire a VMO representing this file, if there is one, with the
|
|
// requested access rights.
|
|
GetVmo(uint32 flags) -> (zx.status s, handle<vmo>? vmo);
|
|
};
|
|
|
|
// Dirent type information associated with the results of ReadDirents.
|
|
const uint8 DIRENT_TYPE_UNKNOWN = 0;
|
|
const uint8 DIRENT_TYPE_DIRECTORY = 4;
|
|
const uint8 DIRENT_TYPE_BLOCK_DEVICE = 6;
|
|
const uint8 DIRENT_TYPE_FILE = 8;
|
|
const uint8 DIRENT_TYPE_SOCKET = 12;
|
|
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;
|
|
|
|
// The following are bitmasks corresponding to the "watch events".
|
|
// They may be used as arguments to the Directory Watch method, to
|
|
// specify which events should receive notifications.
|
|
const uint32 WATCH_MASK_DELETED = 0x00000001;
|
|
const uint32 WATCH_MASK_ADDED = 0x00000002;
|
|
const uint32 WATCH_MASK_REMOVED = 0x00000004;
|
|
const uint32 WATCH_MASK_EXISTING = 0x00000008;
|
|
const uint32 WATCH_MASK_IDLE = 0x00000010;
|
|
const uint32 WATCH_MASK_ALL = 0x0000001F;
|
|
|
|
// WARNING(ZX-2645): Unused.
|
|
//
|
|
// WatchedEvent describes events returned from a DirectoryWatcher.
|
|
struct WatchedEvent {
|
|
uint8 event;
|
|
uint8 len;
|
|
vector<uint8>:MAX_FILENAME name;
|
|
};
|
|
|
|
// WARNING(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"]
|
|
interface 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]
|
|
interface Directory : Node {
|
|
// Open a new object relative to this directory object.
|
|
Open(uint32 flags, uint32 mode, string:MAX_PATH path, request<Node> object);
|
|
|
|
// Remove an object relative to this directory object.
|
|
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];
|
|
// }
|
|
ReadDirents(uint64 max_bytes) -> (zx.status s, vector<uint8>:MAX_BUF dirents);
|
|
|
|
// Reset the directory seek offset.
|
|
Rewind() -> (zx.status s);
|
|
|
|
// Acquire a token to a Directory which can be used to identify
|
|
// access to it at a later point in time.
|
|
GetToken() -> (zx.status s, handle? token);
|
|
|
|
// Within the directory, rename an object named src to the name dst, in
|
|
// a directory represented by token.
|
|
Rename(string:MAX_PATH src, handle dst_parent_token, string:MAX_PATH dst) -> (zx.status s);
|
|
|
|
// Within the directory, create a link to an object named src by the name
|
|
// dst, within a directory represented by token.
|
|
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.
|
|
//
|
|
// 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.
|
|
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"]
|
|
interface DirectoryAdmin : Directory {
|
|
// Mount a channel representing a remote filesystem onto this directory.
|
|
// All future requests to this node will be forwarded to the remote filesytem.
|
|
// To re-open a node without forwarding to the remote target, the node
|
|
// should be opened with OPEN_FLAG_NO_RMOTE.
|
|
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);
|
|
};
|