pub trait AsyncFileSystem: FileSystem {
// Required methods
fn async_lookup<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
parent: Self::Inode,
name: &'life2 CStr,
) -> Pin<Box<dyn Future<Output = Result<Entry>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn async_getattr<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
handle: Option<Self::Handle>,
) -> Pin<Box<dyn Future<Output = Result<(stat64, Duration)>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn async_setattr<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
attr: stat64,
handle: Option<Self::Handle>,
valid: SetattrValid,
) -> Pin<Box<dyn Future<Output = Result<(stat64, Duration)>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn async_open<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
flags: u32,
fuse_flags: u32,
) -> Pin<Box<dyn Future<Output = Result<(Option<Self::Handle>, OpenOptions)>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn async_create<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
parent: Self::Inode,
name: &'life2 CStr,
args: CreateIn,
) -> Pin<Box<dyn Future<Output = Result<(Entry, Option<Self::Handle>, OpenOptions)>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn async_read<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
handle: Self::Handle,
w: &'life2 mut (dyn AsyncZeroCopyWriter + Send),
size: u32,
offset: u64,
lock_owner: Option<u64>,
flags: u32,
) -> Pin<Box<dyn Future<Output = Result<usize>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn async_write<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
handle: Self::Handle,
r: &'life2 mut (dyn AsyncZeroCopyReader + Send),
size: u32,
offset: u64,
lock_owner: Option<u64>,
delayed_write: bool,
flags: u32,
fuse_flags: u32,
) -> Pin<Box<dyn Future<Output = Result<usize>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn async_fsync<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
datasync: bool,
handle: Self::Handle,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn async_fallocate<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
handle: Self::Handle,
mode: u32,
offset: u64,
length: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn async_fsyncdir<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
datasync: bool,
handle: Self::Handle,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
}
Expand description
The main trait that connects a file system with a transport with asynchronous IO.
Required Methods§
Sourcefn async_lookup<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
parent: Self::Inode,
name: &'life2 CStr,
) -> Pin<Box<dyn Future<Output = Result<Entry>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn async_lookup<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
parent: Self::Inode,
name: &'life2 CStr,
) -> Pin<Box<dyn Future<Output = Result<Entry>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Look up a directory entry by name and get its attributes.
If this call is successful then the lookup count of the Inode
associated with the returned
Entry
must be increased by 1.
Sourcefn async_getattr<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
handle: Option<Self::Handle>,
) -> Pin<Box<dyn Future<Output = Result<(stat64, Duration)>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn async_getattr<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
handle: Option<Self::Handle>,
) -> Pin<Box<dyn Future<Output = Result<(stat64, Duration)>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Get attributes for a file / directory.
If handle
is not None
, then it contains the handle previously returned by the
implementation after a call to open
or opendir
. However, implementations should still
take care to verify the handle if they do not trust the client (e.g., virtio-fs).
If writeback caching is enabled (FsOptions::WRITEBACK_CACHE
), then the kernel module
likely has a better idea of the length of the file than the file system (for
example, if there was a write that extended the size of the file but has not yet been
flushed). In this case, the st_size
field of the returned struct is ignored.
The returned Duration
indicates how long the returned attributes should be considered
valid by the client. If the attributes are only changed via the FUSE kernel module (i.e.,
the kernel module has exclusive access), then this should be a very large value.
Sourcefn async_setattr<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
attr: stat64,
handle: Option<Self::Handle>,
valid: SetattrValid,
) -> Pin<Box<dyn Future<Output = Result<(stat64, Duration)>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn async_setattr<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
attr: stat64,
handle: Option<Self::Handle>,
valid: SetattrValid,
) -> Pin<Box<dyn Future<Output = Result<(stat64, Duration)>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Set attributes for a file / directory.
If handle
is not None
, then it contains the handle previously returned by the
implementation after a call to open
or opendir
. However, implementations should still
take care to verify the handle if they do not trust the client (e.g., virtio-fs).
The valid
parameter indicates the fields of attr
that may be considered valid and should
be set by the file system. The content of all other fields in attr
is undefined.
If the FsOptions::HANDLE_KILLPRIV
was set during init
, then the implementation is
expected to reset the setuid and setgid bits if the file size or owner is being changed.
This method returns the new attributes after making the modifications requested by the
client. The returned Duration
indicates how long the returned attributes should be
considered valid by the client. If the attributes are only changed via the FUSE kernel
module (i.e., the kernel module has exclusive access), then this should be a very large
value.
Sourcefn async_open<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
flags: u32,
fuse_flags: u32,
) -> Pin<Box<dyn Future<Output = Result<(Option<Self::Handle>, OpenOptions)>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn async_open<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
flags: u32,
fuse_flags: u32,
) -> Pin<Box<dyn Future<Output = Result<(Option<Self::Handle>, OpenOptions)>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Open a file.
Open the file associated with inode
for reading / writing. All values accepted by the
open(2)
system call are valid values for flags
and must be handled by the file system.
However, there are some additional rules:
-
Creation flags (
libc::O_CREAT
,libc::O_EXCL
,libc::O_NOCTTY
) will be filtered out and handled by the kernel. -
The file system should check the access modes (
libc::O_RDONLY
,libc::O_WRONLY
,libc::O_RDWR
) to determine if the operation is permitted. If the file system was mounted with the-o default_permissions
mount option, then this check will also be carried out by the kernel before sending the open request. -
When writeback caching is enabled (
FsOptions::WRITEBACK_CACHE
) the kernel may send read requests even for files opened withlibc::O_WRONLY
. The file system should be prepared to handle this. -
When writeback caching is enabled, the kernel will handle the
libc::O_APPEND
flag. However, this will not work reliably unless the kernel has exclusive access to the file. In this case the file system may either ignore thelibc::O_APPEND
flag or return an error to indicate that reliablelibc::O_APPEND
handling is not available. -
When writeback caching is disabled, the file system is expected to properly handle
libc::O_APPEND
and ensure that each write is appended to the end of the file.
The file system may choose to return a Handle
to refer to the newly opened file. The
kernel will then use this Handle
for all operations on the content of the file (read
,
write
, flush
, release
, fsync
). If the file system does not return a
Handle
then the kernel will use the Inode
for the file to operate on its contents. In
this case the file system may wish to enable the FsOptions::ZERO_MESSAGE_OPEN
feature if
it is supported by the kernel (see below).
The returned OpenOptions
allow the file system to change the way the opened file is
handled by the kernel. See the documentation of OpenOptions
for more information.
If the FsOptions::ZERO_MESSAGE_OPEN
feature is enabled by both the file system
implementation and the kernel, then the file system may return an error of ENOSYS
. This
will be interpreted by the kernel as success and future calls to open
and release
will
be handled by the kernel without being passed on to the file system.
Sourcefn async_create<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
parent: Self::Inode,
name: &'life2 CStr,
args: CreateIn,
) -> Pin<Box<dyn Future<Output = Result<(Entry, Option<Self::Handle>, OpenOptions)>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn async_create<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
parent: Self::Inode,
name: &'life2 CStr,
args: CreateIn,
) -> Pin<Box<dyn Future<Output = Result<(Entry, Option<Self::Handle>, OpenOptions)>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Create and open a file.
If the file does not already exist, the file system should create it with the specified
mode
. When the FsOptions::DONT_MASK
feature is set, the file system is responsible for
setting the permissions of the created file to mode & !umask
.
If the file system returns an ENOSYS
error, then the kernel will treat this method as
unimplemented and all future calls to create
will be handled by calling the mknod
and
open
methods instead.
See the documentation for the open
method for more information about opening the file. In
addition to the optional Handle
and the OpenOptions
, the file system must also return an
Entry
for the file. This increases the lookup count for the Inode
associated with the
file by 1.
Sourcefn async_read<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
handle: Self::Handle,
w: &'life2 mut (dyn AsyncZeroCopyWriter + Send),
size: u32,
offset: u64,
lock_owner: Option<u64>,
flags: u32,
) -> Pin<Box<dyn Future<Output = Result<usize>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn async_read<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
handle: Self::Handle,
w: &'life2 mut (dyn AsyncZeroCopyWriter + Send),
size: u32,
offset: u64,
lock_owner: Option<u64>,
flags: u32,
) -> Pin<Box<dyn Future<Output = Result<usize>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Read data from a file.
Returns size
bytes of data starting from offset off
from the file associated with
inode
or handle
.
flags
contains the flags used to open the file. Similarly, handle
is the Handle
returned by the file system from the open
method, if any. If the file system
implementation did not return a Handle
from open
then the contents of handle
are
undefined.
This method should return exactly the number of bytes requested by the kernel, except in the
case of error or EOF. Otherwise, the kernel will substitute the rest of the data with
zeroes. An exception to this rule is if the file was opened with the “direct I/O” option
(libc::O_DIRECT
), in which case the kernel will forward the return code from this method
to the userspace application that made the system call.
Sourcefn async_write<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
handle: Self::Handle,
r: &'life2 mut (dyn AsyncZeroCopyReader + Send),
size: u32,
offset: u64,
lock_owner: Option<u64>,
delayed_write: bool,
flags: u32,
fuse_flags: u32,
) -> Pin<Box<dyn Future<Output = Result<usize>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn async_write<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
handle: Self::Handle,
r: &'life2 mut (dyn AsyncZeroCopyReader + Send),
size: u32,
offset: u64,
lock_owner: Option<u64>,
delayed_write: bool,
flags: u32,
fuse_flags: u32,
) -> Pin<Box<dyn Future<Output = Result<usize>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Write data to a file.
Writes size
bytes of data starting from offset off
to the file associated with inode
or handle
.
flags
contains the flags used to open the file. Similarly, handle
is the Handle
returned by the file system from the open
method, if any. If the file system
implementation did not return a Handle
from open
then the contents of handle
are
undefined.
If the FsOptions::HANDLE_KILLPRIV
feature is not enabled then then the file system is
expected to clear the setuid and setgid bits.
If delayed_write
is true then it indicates that this is a write for buffered data.
This method should return exactly the number of bytes requested by the kernel, except in the
case of error. An exception to this rule is if the file was opened with the “direct I/O”
option (libc::O_DIRECT
), in which case the kernel will forward the return code from this
method to the userspace application that made the system call.
Sourcefn async_fsync<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
datasync: bool,
handle: Self::Handle,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn async_fsync<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
datasync: bool,
handle: Self::Handle,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Synchronize file contents.
File systems must ensure that the file contents have been flushed to disk before returning
from this method. If datasync
is true then only the file data (but not the metadata) needs
to be flushed.
handle
is the Handle
returned by the file system from the open
method, if any. If the
file system did not return a Handle
from open
then the contents of
handle
are undefined.
If this method returns an ENOSYS
error then the kernel will treat it as success and all
subsequent calls to fsync
will be handled by the kernel without being forwarded to the
file system.
Sourcefn async_fallocate<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
handle: Self::Handle,
mode: u32,
offset: u64,
length: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn async_fallocate<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
handle: Self::Handle,
mode: u32,
offset: u64,
length: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Allocate requested space for file data.
If this function returns success, then the file sytem must guarantee that it is possible to
write up to length
bytes of data starting at offset
without failing due to a lack of
free space on the disk.
handle
is the Handle
returned by the file system from the open
method, if any. If the
file system did not return a Handle
from open
then the contents of handle
are
undefined.
If this method returns an ENOSYS
error then the kernel will treat that as a permanent
failure: all future calls to fallocate
will fail with EOPNOTSUPP
without being forwarded
to the file system.
Sourcefn async_fsyncdir<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
datasync: bool,
handle: Self::Handle,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn async_fsyncdir<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 Context,
inode: Self::Inode,
datasync: bool,
handle: Self::Handle,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Synchronize the contents of a directory.
File systems must ensure that the directory contents have been flushed to disk before
returning from this method. If datasync
is true then only the directory data (but not the
metadata) needs to be flushed.
handle
is the Handle
returned by the file system from the opendir
method, if any. If
the file system did not return a Handle
from opendir
then the contents of
handle
are undefined.
If this method returns an ENOSYS
error then the kernel will treat it as success and all
subsequent calls to fsyncdir
will be handled by the kernel without being forwarded to the
file system.