mirror of
https://github.com/falk-werner/webfuse
synced 2024-10-27 20:34:10 +00:00
917 lines
31 KiB
Markdown
917 lines
31 KiB
Markdown
# Webfuse2 Protocol
|
|
|
|
## Scope
|
|
|
|
This document describes the webfuse 2 communication protocol. The protocol is used to transfer messages between a `webfuse service` and a `webfuse provider`. In contrast to `legacy webfuse`, which is based on `JSON RPC` the `webfuse2 protocol` is a binary protocol.
|
|
|
|
## Definitions
|
|
|
|
### Webfuse Service
|
|
|
|
A `webfuse service` is both,
|
|
- a [websocket](https://en.wikipedia.org/wiki/WebSocket) service providing the `webfuse` protocol
|
|
- a [fuse](https://github.com/libfuse/libfuse) filesystem attached to a local mountpoint
|
|
|
|
The `webfuse service` awaits incoming connections from a `webfuse provider`. Once connected, it communicates all the filesystem requests originated by the `libfuse` to the connected `webfuse provider` using the `websocket`-based `webfuse protocol`.
|
|
|
|
By doing so, `webfuse` allows to inject a filesystem to a remote device.
|
|
|
|
### Webfuse Provider
|
|
|
|
A `webfuse provider` provides a filesystem to a remote device using the `websocket`-based `webfuse protocol`. Therefore, a `webfuse provider` implements a `websocket` client.
|
|
|
|
## Websocket protocol name
|
|
|
|
The webfuse2 protocol uses the following websocket protocol name: `webfuse2`.
|
|
|
|
## Message exchange
|
|
|
|
Once connected, the `webfuse2 protocol` implements a strict request-response scheme, where
|
|
- all requests are send by the `webfuse service`,
|
|
- all requests require a response and
|
|
- all responses are send by the `webfuse provider`
|
|
|
|
Note that this communication is reversed the typical client-server-communication scheme. In `webfuse` the `webfuse service` (server) sends all the requests and the `webfuse provider` (client) sends the responses.
|
|
|
|
For message transfer, the [websocket](https://en.wikipedia.org/wiki/WebSocket) protocol is used. All messages are in binary form, plain text messages are never used by the `webfuse protocol`.
|
|
|
|
|
|
## Endianness
|
|
|
|
All numeric data types are transferred in [Big Endian](https://en.wikipedia.org/wiki/Endianness).
|
|
For instance, the uint32 value 1 will be transferred as
|
|
|
|
00 00 00 01
|
|
|
|
## Data Types
|
|
|
|
### Basic data types
|
|
|
|
| Data Type | Width | Description |
|
|
| --------- | ------ | ----------- |
|
|
| bool | 8 bit | boolean value |
|
|
| u8 | 8 bit | 8 bit unsigned integer |
|
|
| u32 | 32 bit | 32 bit unsigned integer |
|
|
| u64 | 64 bit | 64 bit unsigned integer |
|
|
| i32 | 32 bit | 32 bit signed integer |
|
|
|
|
### Derrived integral types
|
|
|
|
| Data Type | Base Type | Description |
|
|
| --------- | --------- | ----------- |
|
|
| uid | u32 | user ID |
|
|
| gid | u32 | group ID |
|
|
| dev | u64 | device ID |
|
|
| handle | u64 | file handle |
|
|
|
|
### Flags and Enums
|
|
|
|
| Data Type | Base Type | Description |
|
|
| ------------ | --------- | ------------------------- |
|
|
| result | i32 | result type of methods |
|
|
| access_mode | u32 | mode of `access` method |
|
|
| mode | u32 | file type and permissions |
|
|
| open_flags | i32 | flags of `open` method |
|
|
| rename_flags | u8 | flags of `rename` method |
|
|
|
|
#### result
|
|
|
|
| Value Range | Description |
|
|
| -------------- | ---------------------- |
|
|
| 0 | method call succeed |
|
|
| negative value | error code (see below) |
|
|
| positive value | amount of bytes read or written (`read` and `write` only) |
|
|
|
|
| Error Code | Value | Description |
|
|
| ------------ | ----- | ----------- |
|
|
| E2BIG | -7 | argument list too long |
|
|
| EACCES | -13 | permission denied |
|
|
| EAGAIN | -11 | resource temporarily unavailable |
|
|
| EBADF | -9 | bad file descriptor |
|
|
| EBUSY | -16 | device or resource busy |
|
|
| EDESTADDRREQ | -89 | destination address required |
|
|
| EDQUOT | -122 | disk quota exceeded |
|
|
| EEXIST | -17 | file exists |
|
|
| EFAULT | -14 | bad address |
|
|
| EFBIG | -27 | file too large |
|
|
| EINTR | -4 | interrupt function call |
|
|
| EINVAL | -22 | invalid argument |
|
|
| EIO | -5 | input / output error |
|
|
| EISDIR | -21 | is a directory
|
|
| ELOOP | -40 | too many levels of symbolic links |
|
|
| EMFILE | -24 | too many open files |
|
|
| EMLINK | -31 | too many links |
|
|
| ENAMETOOLONG | -36 | filename too long |
|
|
| ENFILE | -23 | too many open files in system |
|
|
| ENODATA | -61 | the named attribute does not exist, or the process has not access to this attribute |
|
|
| ENODEV | -19 | no such device |
|
|
| ENOENT | -2 | no such file or directory |
|
|
| ENOMEM | -12 | not enough space / cannot allocate memory |
|
|
| ENOSPC | -28 | no space left on device |
|
|
| ENOSYS | -38 | function not implemented |
|
|
| ENOTDIR | -20 | not a directory |
|
|
| ENOTEMPTY | -39 | directory not empty |
|
|
| ENOTSUP | -95 | operation not supported |
|
|
| ENXIO | -6 | no such device or address |
|
|
| EOVERFLOW | -75 | value too large to be stored in data type |
|
|
| EPERM | -1 | operation not permitted |
|
|
| EPIPE | -32 | broken pipe |
|
|
| ERANGE | -34 | result too large |
|
|
| EROFS | -30 | read-only filesystem |
|
|
| ETXTBSY | -26 | text file busy |
|
|
| EXDEV | -18 | improper link |
|
|
| EWOULDBLOCK | -11 | resource temporarily unavailable |
|
|
|
|
#### access mode
|
|
|
|
| Mode | Value | Description |
|
|
| ---- | ----- | ----------- |
|
|
| F_OK | 0 | Tests, whether the file exists |
|
|
| X_OK | 1 | Tests, whether the file is executable |
|
|
| W_OK | 2 | Tests, whether the file is writable |
|
|
| R_OK | 4 | Tests, whether the file is readable |
|
|
|
|
#### mode
|
|
|
|
_Note that the following numbers are in `octal` notation._
|
|
|
|
| Fields and Flags | Mask | Description |
|
|
| ---------------- | -------- | ----------- |
|
|
| Protection mask | 0o000777 | Cointains the file protection flags (rwx for owner, group and others) |
|
|
| Sticky mask | 0o007000 | Sticky bits |
|
|
| S_ISVTX | 0o001000 | Sticky bit |
|
|
| S_ISGID | 0o002000 | Set-Group-ID bit |
|
|
| S_ISUID | 0o004000 | Set-User-ID bit |
|
|
| Filetype mask | 0o170000 | Filetype mask |
|
|
| S_IFREG | 0o100000 | regular file |
|
|
| S_IFDIR | 0o040000 | directory |
|
|
| S_IFCHR | 0o020000 | character device |
|
|
| S_IFBLK | 0o060000 | block device |
|
|
| S_IFIFO | 0o010000 | named pipe |
|
|
| S_IFLNK | 0o120000 | link |
|
|
| S_IFSOCK | 0o140000 | socket |
|
|
|
|
#### open_flags
|
|
|
|
_Note that the following numbers are in `octal` notation._
|
|
|
|
| Flags | Value | Description |
|
|
| ---------------- | -------- | ----------- |
|
|
| O_ACCMODE | 0o03 | Access mode mask |
|
|
| O_RDONLY | 0o00 | open file read-only |
|
|
| O_WRONLY | 0o01 | open file write-only |
|
|
| O_RDWR | 0o02 | open file for reading and writing |
|
|
| O_APPEND | 0o000002000 | open file in append mode |
|
|
| O_ASYNC | 0o000020000 | enable signal-driven I/O |
|
|
| O_CLOEXEC | 0o002000000 | enable close-on-exec |
|
|
| O_CREAT | 0o000000100 | create file if path does not exists |
|
|
| O_DIRECT | 0o000040000 | try to minimize cache effects on I/O |
|
|
| O_DIRECTORY | 0o000200000 | open a directory |
|
|
| O_DSYNC | 0o000010000 | write with synchronized I/O data integrity |
|
|
| O_EXCL | 0o000000200 | ensure that file exists when specified in conjunction with O_CREATE |
|
|
| O_LARGEFILE | 0o000100000 | allow large files to be opened |
|
|
| O_NOATIME | 0o001000000 | do not update file last access time |
|
|
| O_NOCTTY | 0o000000400 | make device the process's controlling terminal |
|
|
| O_NOFOLLOW | 0o000400000 | fail to open, if basename is a symbolic link |
|
|
| O_NONBLOCK | 0o000004000 | open in nonblocking mode |
|
|
| O_NDELAY | 0o000004000 | open in nonblocking mode |
|
|
| O_PATH | 0o010000000 | see manual entry of `open(2)` for details |
|
|
| O_SYNC | 0o004010000 | write using synchronized I/O |
|
|
| O_TMPFILE | 0o020200000 | create an unnamed temporary file |
|
|
| O_TRUNC | 0o000001000 | truncate fole to length 0 |
|
|
|
|
#### rename_flags
|
|
|
|
| Flag | Value | Description |
|
|
| ---------------- | ----- | ----------- |
|
|
| RENAME_NOREPLACE | 1 | do not overwrite the new file |
|
|
| RENAME_EXCHANGE | 2 | atomically exchange the files |
|
|
|
|
### Complex Types
|
|
|
|
| Data Type | Description |
|
|
| ---------- | --------------------- |
|
|
| string | UTF-8 string |
|
|
| strings | list of strings |
|
|
| bytes | array of bytes |
|
|
| timestamp | date and time |
|
|
| attributes | file attributes |
|
|
| statistics | filesystem statistics |
|
|
|
|
#### string
|
|
|
|
| Field | Data Type | Description |
|
|
| ----- | --------- | ----------------------------- |
|
|
| size | u32 | length of the string in bytes |
|
|
| data | u8[] | string data (UTF-8) |
|
|
|
|
#### strings
|
|
|
|
| Field | Data Type | Description |
|
|
| ----- | --------- | --------------------------------- |
|
|
| size | u32 | count of the elements in the list |
|
|
| data | string[] | strings |
|
|
|
|
#### bytes
|
|
|
|
| Field | Data Type | Description |
|
|
| ----- | --------- | ------------------------ |
|
|
| size | u32 | length of the byte array |
|
|
| data | u8[] | array data |
|
|
|
|
#### timestamp
|
|
|
|
| Field | Data Type | Description |
|
|
| ------- | --------- | ----------------------------- |
|
|
| seconds | u64 | seconds sind epoch (1.1.1970) |
|
|
| nsec | u32 | nano seconds |
|
|
|
|
#### attributes
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | ---------- | -------------------------- |
|
|
| inode | u64 | Inode value |
|
|
| nlink | u64 | Number of hard links |
|
|
| mode | mode (u32) | file mode flags |
|
|
| uid | uid (u32) | user ID |
|
|
| gid | gid (u32) | group ID |
|
|
| rdev | dev (u64) | device ID |
|
|
| size | u64 | file size |
|
|
| blocks | u64 | number 512-byte blocks |
|
|
| atime | timestamp | time of last access |
|
|
| mtime | timestamp | time of last modification |
|
|
| ctime | timestamp | time of last status change |
|
|
|
|
#### statistics
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | ---------- | -------------------------- |
|
|
| bsize | u64 | Filesystem block size |
|
|
| frsize | u64 | Fragment size |
|
|
| blocks | u64 | Size of the filesystem if `frsize` units |
|
|
| bfree | u64 | Number of free blocks |
|
|
| bavail | u64 | Number of free blocks for unprivileged users |
|
|
| files | u64 | Number of inodes |
|
|
| ffree | u64 | Number of free inodes |
|
|
| namemax | u64 | Maximum filename length |
|
|
|
|
## Messages
|
|
|
|
| Field | Type | Descripton |
|
|
| ------- | ---- | ---------- |
|
|
| id | u32 | Unique ID of the message |
|
|
| type | u8 | Type of the message |
|
|
| payload | u8[] | Payload according to the message type |
|
|
|
|
The `id` is just a number without any meaning for the `webfuse provider`. It is set by the `webfuse service` of a request and is copied by the `webfuse provider` to the response. A `webfuse service` implementation might choose to keep track on pending requests using the `id`.
|
|
|
|
### Erroneous Responses
|
|
|
|
Most responses contain a `result` encoding the status of the operation. While successful responses may contain additional data, erroneous responses must not be decoded by a `webfuse service` implementation beyond the `result` value.
|
|
|
|
### Unknown requests
|
|
|
|
There are two reserved message types:
|
|
- **0x00:** Unknown request
|
|
- **0x80:** Unknown response
|
|
|
|
A `webfuse service` may send a request of type `unknown request` for conformance testing reasons.
|
|
|
|
Since each request requires a response, a `webfuse provider` must respond to any unknown requests with a message of `unknown response` type. This allows to add new request types in future.
|
|
|
|
### Accept additional data in requests
|
|
|
|
Both, a `webfuse provider` and a `webfuse service` must accept messages that contain more data than specified. This allows to add optional fields to existing requests and / or responses in future.
|
|
|
|
_Note there are no optional fields in the current revision of the `webfuse2 protocol` yet._
|
|
|
|
### Message Types
|
|
|
|
_Note that the following numbers are in `hexadecimal` notation._
|
|
|
|
| Method | Request | Response |
|
|
| -------- | ------- | -------- |
|
|
| access | 0x01 | 0x81 |
|
|
| getattr | 0x02 | 0x82 |
|
|
| readlink | 0x03 | 0x83 |
|
|
| symlink | 0x04 | 0x84 |
|
|
| link | 0x05 | 0x85 |
|
|
| rename | 0x06 | 0x86 |
|
|
| chmod | 0x07 | 0x87 |
|
|
| chown | 0x08 | 0x88 |
|
|
| truncate | 0x09 | 0x89 |
|
|
| fsync | 0x0a | 0x8a |
|
|
| open | 0x0b | 0x8b |
|
|
| mknod | 0x0c | 0x8c |
|
|
| create | 0x0d | 0x8d |
|
|
| release | 0x0e | 0x8e |
|
|
| unlink | 0x0f | 0x8f |
|
|
| read | 0x10 | 0x90 |
|
|
| write | 0x11 | 0x91 |
|
|
| mkdir | 0x12 | 0x92 |
|
|
| readdir | 0x13 | 0x93 |
|
|
| rmdir | 0x14 | 0x94 |
|
|
| statfs | 0x15 | 0x95 |
|
|
| utimens | 0x16 | 0x96 |
|
|
| getcreds | 0x17 | 0x97 |
|
|
|
|
## Methods
|
|
|
|
Since `webfuse` aims to communicate the `libfuse API` over a `websocket` connection, `webfuse` methods are tightly connected to [fuse operations](https://libfuse.github.io/doxygen/structfuse__operations.html) which itself have a tight connection to `posix filesystem operations`. Therefore, additional information about most `webfuse` operations can be found in the [fuse operations documentation](https://libfuse.github.io/doxygen/structfuse__operations.html) and / or the [man pages](https://man7.org/index.html).
|
|
|
|
### access
|
|
|
|
Checks the user's permissions for a file (see [man access(2)](https://man7.org/linux/man-pages/man2/access.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ----- | ---------------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x01) |
|
|
| path | string | path of file to check |
|
|
| mode | access_mode (i8) | access mode to check |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x81) |
|
|
| result | result | operation status |
|
|
|
|
### getattr
|
|
|
|
Retrieve file attributes (see [man getattr(2)](https://man7.org/linux/man-pages/man2/getxattr.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x02) |
|
|
| path | string | path |
|
|
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| --------- | ---------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x82) |
|
|
| result | result | operation status |
|
|
| attibutes | attributes | attributes of file |
|
|
|
|
### readlink
|
|
|
|
Read value of a symbolik link (see [man readlink(2)](https://man7.org/linux/man-pages/man2/readlink.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x03) |
|
|
| path | string | path of link |
|
|
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| -------- | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x83) |
|
|
| result | result | operation status |
|
|
| resolved | string | resolved path |
|
|
|
|
### symlink
|
|
|
|
Make a new name of a file (see [man symlink(2)](https://man7.org/linux/man-pages/man2/symlink.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| -------- | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x04) |
|
|
| target | string | target of link |
|
|
| linkpath | string | name of the link |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x84) |
|
|
| result | result | operation status |
|
|
|
|
### link
|
|
|
|
Make a new name for a file (see [man link(2)](https://man7.org/linux/man-pages/man2/link.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| -------- | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x05) |
|
|
| old_path | string | path of the existing file |
|
|
| new_path | string | new name of the file |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x85) |
|
|
| result | result | operation status |
|
|
|
|
### rename
|
|
|
|
Change the name of a file (see [man rename(2)](https://man7.org/linux/man-pages/man2/rename.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| -------- | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x06) |
|
|
| old_path | string | old name of the file |
|
|
| new_path | string | new name of the file |
|
|
| flags | rename_flags (u8) | flags to control the rename operation |
|
|
|
|
The following `flags` are defined:
|
|
- **0x00:** move the file from `old_path` to `new_path`
|
|
- **0x01 (RENAME_NOREPLACE):** do not override `new_path`
|
|
This results in an error, when `new_path` already exists.
|
|
- **0x02 (RENAME_EXCHANGE):** atomically exchange the files
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x86) |
|
|
| result | result | operation status |
|
|
|
|
### chmod
|
|
|
|
Change permissions of a file (see [man chmod(2)](https://man7.org/linux/man-pages/man2/chmod.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | ---------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x07) |
|
|
| path | string | path of the file |
|
|
| mode | mode (u32) | new file permissions |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x87) |
|
|
| result | result | operation status |
|
|
|
|
### chown
|
|
|
|
Change ownership of a file (see [man chown(2)](https://man7.org/linux/man-pages/man2/chown.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x08) |
|
|
| path | string | path of the file |
|
|
| uid | uid (u32) | user id of the new owner |
|
|
| gid | gid (u32) | group id of the new owning group |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x88) |
|
|
| result | result | operation status |
|
|
|
|
### truncate
|
|
|
|
Truncate a file to a specified length (see [man truncate(2)](https://man7.org/linux/man-pages/man2/truncate64.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | ------------ | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x09) |
|
|
| path | string | path of the file |
|
|
| size | u64 | new file size |
|
|
| handle | handle (u64) | handle of the file |
|
|
|
|
_Note that handle might be invalid (-1), even if the file is open._
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x89) |
|
|
| result | result | operation status |
|
|
|
|
### fsync
|
|
|
|
Sychronize a file's in-core state with storage device (see [man fsync(2)](https://man7.org/linux/man-pages/man2/fsync.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x0a) |
|
|
| path | string | path of the file |
|
|
| is_datasync | bool | if true, sync only user data |
|
|
| handle | handle (u64) | handle of the file |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x8a) |
|
|
| result | result | operation status |
|
|
|
|
### open
|
|
|
|
Open and possibly create a file ([man open(2)](https://man7.org/linux/man-pages/man2/open.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x0b) |
|
|
| path | string | path of the file |
|
|
| flags | open_flags (i32) | flags |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x8b) |
|
|
| result | result | operation status |
|
|
| handle | handle (u64) | handle of the file |
|
|
|
|
### mknod
|
|
|
|
Create a special or ordinary file (see [man mknod(2)](https://man7.org/linux/man-pages/man2/mknod.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x0c) |
|
|
| path | string | path of the file |
|
|
| mode | mode (u32) | mode of the file |
|
|
| dev | dev (64) | device type |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x8c) |
|
|
| result | result | operation status |
|
|
|
|
### create
|
|
|
|
Create a new file or rewrite an existing one (see [man creat(3p)](https://man7.org/linux/man-pages/man3/creat.3p.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x0d) |
|
|
| path | string | path of the file |
|
|
| mode | mode (u32) | mode of the file |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x8d) |
|
|
| result | result | operation status |
|
|
| handle | handle (u64) | handle of the file |
|
|
|
|
### release
|
|
|
|
Releases a file handle (see [man close(2)](https://man7.org/linux/man-pages/man2/close.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x0e) |
|
|
| path | string | path of the file |
|
|
| handle | handle (u64) | handle of the file |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x8e) |
|
|
| result | result | operation status |
|
|
|
|
### unlink
|
|
|
|
Delete a name and possibly the file it refers to ([man unlink(2)](https://man7.org/linux/man-pages/man2/unlink.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x0f) |
|
|
| path | string | path of the file |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x8f) |
|
|
| result | result | operation status |
|
|
|
|
### read
|
|
|
|
Read from a file description (see [man read(2)](https://man7.org/linux/man-pages/man2/read.2.html), [man pread(2)](https://man7.org/linux/man-pages/man2/pread.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x10) |
|
|
| path | string | path of the file |
|
|
| buffer_size | u32 | max. amount of bytes requested |
|
|
| offset | u64 | offset of the file |
|
|
| handle | handle (u64) | handle of the file |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x90) |
|
|
| result | result | amount of byte read or error code |
|
|
| data | bytes | requested data |
|
|
|
|
_Note that results returns the amount of bytes read on success._
|
|
|
|
### write
|
|
|
|
Write to a file (see [man write(2)](https://man7.org/linux/man-pages/man2/write.2.html), [man pread(2)](https://man7.org/linux/man-pages/man2/pread.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x17) |
|
|
| data | bytes | data to write |
|
|
| offset | u64 | offset to write to |
|
|
| handle | handle (u64) | handle of the file |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x91) |
|
|
| result | result | amount of bytes written or error code |
|
|
|
|
_Note that results returns the amount of bytes written on success._
|
|
|
|
### mkdir
|
|
|
|
Create a directory (see [man mkdir(2)](https://man7.org/linux/man-pages/man2/mkdir.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x12) |
|
|
| path | string | path of the directory |
|
|
| mode | mode (u32) | directory permissions |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x92) |
|
|
| result | result | operation status |
|
|
|
|
### readdir
|
|
|
|
Reads the contents of a directory.
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x13) |
|
|
| path | string | path of the directory |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x93) |
|
|
| result | result | operation status |
|
|
| items | strings | names of the directory entries |
|
|
|
|
### rmdir
|
|
|
|
Delete a directory (see [man rmdir(2)](https://man7.org/linux/man-pages/man2/rmdir.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x14) |
|
|
| path | string | path of the directory |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x94) |
|
|
| result | result | operation status |
|
|
|
|
### statfs
|
|
|
|
Get filesystem statistics (see [man statvfs(3)](https://man7.org/linux/man-pages/man3/statvfs.3.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x15) |
|
|
| path | string | path of the file |
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x95) |
|
|
| result | result | operation status |
|
|
| statistics | statistics | filesystem statistics |
|
|
|
|
### utimens
|
|
|
|
Change the file timestamps with nanosecond precision ([man utimesat(2)](https://man7.org/linux/man-pages/man2/utimensat.2.html)).
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x16) |
|
|
| path | string | path of the file |
|
|
| atime | timestamp | new last access time |
|
|
| mtime | timestamp | new last modified time |
|
|
| handle | handle (u64) | handle of the file |
|
|
|
|
_Note that handle might be invalid (-1), even if the file is open._
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x96) |
|
|
| result | result | operation status |
|
|
|
|
### getcreds
|
|
|
|
Query credentials. When authentication is active and the in-protocol
|
|
authentication mechanism is used, this is the first request a
|
|
webfuse service sends to a provider.
|
|
|
|
#### Request
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x17) |
|
|
|
|
_Note that handle might be invalid (-1), even if the file is open._
|
|
|
|
#### Response
|
|
|
|
| Field | Data Type | Description |
|
|
| ------ | --------- | ----------- |
|
|
| id | u32 | message id |
|
|
| type | u8 | message type (0x97) |
|
|
| creds | str | credentials |
|
|
|
|
## Examples
|
|
|
|
### Get file attributes
|
|
|
|
````
|
|
service -> provider:
|
|
00 00 00 01 # message id = 1
|
|
02 # message type = getattr request
|
|
00 00 00 01 # path.size = 1
|
|
'/' # path = "/"
|
|
|
|
provider -> service:
|
|
00 00 00 01 # message id = 1
|
|
82 # message type = getattr response
|
|
00 00 00 00 # result = 0 (OK)
|
|
00 00 00 00 00 00 00 01 # attributes.inode = 1
|
|
00 00 00 00 00 00 00 02 # attributes.nlink = 2
|
|
00 00 41 a4 # attributes.mode = 0o40644 (S_IDDIR | 0o0644)
|
|
00 00 03 e8 # attributes.uid = 1000
|
|
00 00 03 e8 # attributes.gid = 1000
|
|
00 00 00 00 00 00 00 00 # attributes.size = 0
|
|
00 00 00 00 00 00 00 00 # attributes.blocks = 0
|
|
00 00 00 00 00 00 00 00 # attrbites.atime.sec = 0
|
|
00 00 00 00 00 # attributs.atime.nsec = 0
|
|
00 00 00 00 00 00 00 00 # attrbites.mtime.sec = 0
|
|
00 00 00 00 00 # attributs.mtime.nsec = 0
|
|
00 00 00 00 00 00 00 00 # attrbites.ctime.sec = 0
|
|
00 00 00 00 00 # attributs.ctime.nsec = 0
|
|
````
|
|
|
|
### Get file attributes (Failure)
|
|
|
|
_Note that attributs are skipped in case of an error._
|
|
|
|
````
|
|
service -> provider:
|
|
00 00 00 01 # message id = 1
|
|
02 # message type = getattr request
|
|
00 00 00 04 # path.size = 4
|
|
"/foo" # path = "/foo"
|
|
|
|
provider -> service:
|
|
00 00 00 01 # message id = 1
|
|
82 # message type = getattr response
|
|
ff ff ff fe # result = -2 (ENOENT)
|
|
````
|
|
|
|
### List directory contents
|
|
|
|
_Note that '.' and '..' should not be included in the response._
|
|
|
|
````
|
|
service -> provider:
|
|
00 00 00 02 # message id = 2
|
|
13 # message type = readdir request
|
|
00 00 00 04 # path.size = 4
|
|
'/dir' # path = "/dir"
|
|
|
|
provider -> service:
|
|
00 00 00 02 # message id = 2
|
|
93 # message type = readdir response
|
|
00 00 00 00 # result = 0 (OK)
|
|
00 00 00 03 # items.size = 3
|
|
00 00 00 03 # items[0].size = 3
|
|
"foo" # items[0] = "foo"
|
|
00 00 00 03 # items[0].size = 3
|
|
"bar" # items[0] = "bar"
|
|
00 00 00 03 # items[0].size = 3
|
|
"baz" # items[0] = "baz"
|
|
````
|
|
|
|
### Unknown request
|
|
|
|
````
|
|
service -> provider:
|
|
00 00 00 23 # message id = 0x23
|
|
42 # message type = ??? (not specified yet)
|
|
... # some more data
|
|
|
|
provider -> service:
|
|
00 00 00 23 # message id = 0x23
|
|
80 # message type = unknown response
|
|
````
|