Struct devices::virtio::fs::passthrough::PassthroughFs
source · pub struct PassthroughFs {Show 17 fields
process_lock: Mutex<()>,
tag: String,
inodes: Mutex<MultikeyBTreeMap<Inode, InodeAltKey, Arc<InodeData>>>,
next_inode: AtomicU64,
handles: Mutex<BTreeMap<u64, Arc<HandleData>>>,
next_handle: AtomicU64,
proc: File,
writeback: AtomicBool,
zero_message_open: AtomicBool,
zero_message_opendir: AtomicBool,
dbus_connection: Option<Mutex<Connection>>,
dbus_fd: Option<RawFd>,
expiring_casefold_lookup_caches: Option<Mutex<ExpiringCasefoldLookupCaches>>,
permission_paths: RwLock<Vec<PermissionData>>,
xattr_paths: RwLock<Vec<XattrData>>,
cfg: Config,
root_dir: String,
}
Expand description
A file system that simply “passes through” all requests it receives to the underlying file system. To keep the implementation simple it servers the contents of its root directory. Users that wish to serve only a specific directory should set up the environment so that that directory ends up as the root of the file system process. One way to accomplish this is via a combination of mount namespaces and the pivot_root system call.
Fields§
§process_lock: Mutex<()>
§tag: String
§inodes: Mutex<MultikeyBTreeMap<Inode, InodeAltKey, Arc<InodeData>>>
§next_inode: AtomicU64
§handles: Mutex<BTreeMap<u64, Arc<HandleData>>>
§next_handle: AtomicU64
§proc: File
§writeback: AtomicBool
§zero_message_open: AtomicBool
§zero_message_opendir: AtomicBool
§dbus_connection: Option<Mutex<Connection>>
§dbus_fd: Option<RawFd>
§expiring_casefold_lookup_caches: Option<Mutex<ExpiringCasefoldLookupCaches>>
§permission_paths: RwLock<Vec<PermissionData>>
§xattr_paths: RwLock<Vec<XattrData>>
§cfg: Config
§root_dir: String
Implementations§
source§impl PassthroughFs
impl PassthroughFs
pub fn new(tag: &str, cfg: Config) -> Result<PassthroughFs>
fn set_permission_path(&mut self)
pub fn set_root_dir(&mut self, shared_dir: String) -> Result<()>
pub fn cfg(&self) -> &Config
pub fn keep_rds(&self) -> Vec<RawDescriptor>
fn rewrite_xattr_name<'xattr>(&self, name: &'xattr CStr) -> Cow<'xattr, CStr>
fn find_inode(&self, inode: Inode) -> Result<Arc<InodeData>>
fn find_handle(&self, handle: u64, inode: Inode) -> Result<Arc<HandleData>>
fn open_fd(&self, fd: RawDescriptor, flags: i32) -> Result<File>
sourcefn update_open_flags(&self, flags: i32) -> i32
fn update_open_flags(&self, flags: i32) -> i32
Modifies the provided open flags based on the writeback caching configuration. Return the updated open flags.
fn open_inode(&self, inode: &InodeData, flags: i32) -> Result<File>
fn increase_inode_refcount(&self, inode_data: &InodeData) -> Inode
fn add_entry( &self, f: File, st: stat64, open_flags: c_int, path: String ) -> Entry
sourcefn lock_casefold_lookup_caches(
&self
) -> Option<MutexGuard<'_, ExpiringCasefoldLookupCaches>>
fn lock_casefold_lookup_caches( &self ) -> Option<MutexGuard<'_, ExpiringCasefoldLookupCaches>>
Acquires lock of expiring_casefold_lookup_caches
if ascii_casefold
is enabled.
fn get_case_unfolded_name( &self, parent: &InodeData, name: &[u8] ) -> Result<Option<CString>>
fn ascii_casefold_lookup( &self, parent: &InodeData, name: &[u8] ) -> Result<Entry>
fn do_lookup(&self, parent: &InodeData, name: &CStr) -> Result<Entry>
fn get_cache_open_options(&self, flags: u32) -> OpenOptions
fn do_lookup_with_casefold_fallback( &self, parent: &InodeData, name: &CStr ) -> Result<Entry>
fn do_open( &self, inode: Inode, flags: u32 ) -> Result<(Option<u64>, OpenOptions)>
fn do_open_at( &self, parent_data: Arc<InodeData>, name: &CStr, inode: Inode, flags: u32 ) -> Result<(Option<u64>, OpenOptions)>
fn do_release(&self, inode: Inode, handle: u64) -> Result<()>
fn do_getattr(&self, inode: &InodeData) -> Result<(stat64, Duration)>
fn do_unlink(&self, parent: &InodeData, name: &CStr, flags: c_int) -> Result<()>
fn do_fsync<F: AsRawDescriptor>(&self, file: &F, datasync: bool) -> Result<()>
fn with_proc_chdir<F, T>(&self, f: F) -> Twhere
F: FnOnce() -> T,
fn do_getxattr( &self, inode: &InodeData, name: &CStr, value: &mut [u8] ) -> Result<usize>
fn get_encryption_policy_ex<R: Read>( &self, inode: Inode, handle: u64, r: R ) -> Result<IoctlReply>
fn get_fsxattr(&self, inode: Inode, handle: u64) -> Result<IoctlReply>
fn set_fsxattr<R: Read>( &self, ctx: Context, inode: Inode, handle: u64, r: R ) -> Result<IoctlReply>
fn get_flags(&self, inode: Inode, handle: u64) -> Result<IoctlReply>
fn set_flags<R: Read>( &self, ctx: Context, inode: Inode, handle: u64, r: R ) -> Result<IoctlReply>
fn enable_verity<R: Read>( &self, inode: Inode, handle: u64, r: R ) -> Result<IoctlReply>
fn measure_verity<R: Read>( &self, inode: Inode, handle: u64, r: R, out_size: u32 ) -> Result<IoctlReply>
source§impl PassthroughFs
impl PassthroughFs
fn find_and_set_ugid_permission( &self, st: &mut stat64, path: &str, is_root_path: bool ) -> bool
fn set_permission_from_data(&self, st: &mut stat64, perm_data: &PermissionData)
sourcefn set_ugid_permission(&self, st: &mut stat64, path: &str)
fn set_ugid_permission(&self, st: &mut stat64, path: &str)
Set permission according to path
sourcefn change_ugid_creds(
&self,
ctx: &Context,
parent_data: &InodeData,
name: &CStr
) -> (u32, u32)
fn change_ugid_creds( &self, ctx: &Context, parent_data: &InodeData, name: &CStr ) -> (u32, u32)
Set host uid/gid to configured value according to path
fn find_ugid_creds_for_path( &self, path: &str, is_root_path: bool ) -> Option<(u32, u32)>
source§impl PassthroughFs
impl PassthroughFs
sourcefn string_from_u8_slice(&self, buf: &[u8]) -> Result<String>
fn string_from_u8_slice(&self, buf: &[u8]) -> Result<String>
Convert u8 slice to string
sourcefn set_permission(&self, st: &mut stat64, path: &str)
fn set_permission(&self, st: &mut stat64, path: &str)
Set permission according to path
sourcefn change_creds(
&self,
ctx: &Context,
parent_data: &InodeData,
name: &CStr
) -> (u32, u32)
fn change_creds( &self, ctx: &Context, parent_data: &InodeData, name: &CStr ) -> (u32, u32)
Set host uid/gid to configured value according to path
fn read_permission_data<R: Read>(&self, r: R) -> Result<PermissionData>
sourcefn set_permission_by_path<R: Read>(&self, r: R) -> IoctlReply
fn set_permission_by_path<R: Read>(&self, r: R) -> IoctlReply
Sets uid/gid/umask for all files and directories under a specific path.
This ioctl does not correspond to any upstream FUSE feature. It is used for arcvm It associates the specified path with the provide uid, gid, and umask values within the filesystem metadata.
During subsequent lookup operations, the stored uid/gid/umask values are retrieved and
applied to all files and directories found under the registered path. Before sending
file stat information to the client, the uid and gid are substituted by guest_uid
and
guest_gid
if the file falls under the registered path. The file mode is masked by the
umask.
When the guest creates a file within the specified path, the file gid/uid stat in host
will be overwritten to host_uid
and host_gid
values.
This functionality enables dynamic configuration of ownership and permissions for a specific directory hierarchy within the filesystem.
§Notes
- This method affects all existing and future files under the registered path.
- The original file ownership and permissions are overridden by the provided values.
- The registered path should not be renamed
- Refer go/remove-mount-passthrough-fuse for more design details
fn get_xattr_by_path(&self, path: &str, name: &str) -> Option<String>
fn skip_host_set_xattr(&self, path: &str, name: &str) -> bool
fn read_xattr_data<R: Read>(&self, r: R) -> Result<XattrData>
sourcefn set_xattr_by_path<R: Read>(&self, r: R) -> IoctlReply
fn set_xattr_by_path<R: Read>(&self, r: R) -> IoctlReply
Sets xattr value for all files and directories under a specific path.
This ioctl does not correspond to any upstream FUSE feature. It is used for arcvm. It associates the specified path and xattr name with a value.
When the getxattr is called for the specified path and name, the predefined value is returned.
§Notes
- This method affects all existing and future files under the registered path.
- The SECURITY_CONTEXT feature will be disabled if this ioctl is enabled.
- The registered path should not be renamed
- Refer go/remove-mount-passthrough-fuse for more design details
fn do_getxattr_with_filter( &self, data: Arc<InodeData>, name: Cow<'_, CStr>, buf: &mut [u8] ) -> Result<usize>
sourcefn lookup_host_uid(&self, ctx: &Context, inode: Inode) -> u32
fn lookup_host_uid(&self, ctx: &Context, inode: Inode) -> u32
Looks up the host uid according to the path of file that inode is referring to.
Trait Implementations§
source§impl Debug for PassthroughFs
impl Debug for PassthroughFs
source§impl FileSystem for PassthroughFs
impl FileSystem for PassthroughFs
§type Inode = u64
type Inode = u64
getattr
and setattr
). Can also be used as the
starting point for looking up paths in the filesystem tree. An Inode
may support operating
directly on the content of the path that to which it points. FileSystem
implementations
that support this should set the FsOptions::ZERO_MESSAGE_OPEN
option in the return value
of the init
function. On linux based systems, an Inode
is equivalent to opening a file
or directory with the libc::O_PATH
flag. Read more§type DirIter = ReadDir<Box<[u8]>>
type DirIter = ReadDir<Box<[u8]>>
readdir
for more
details.source§fn statfs(&self, _ctx: Context, inode: Inode) -> Result<statvfs64>
fn statfs(&self, _ctx: Context, inode: Inode) -> Result<statvfs64>
source§fn lookup(&self, _ctx: Context, parent: Inode, name: &CStr) -> Result<Entry>
fn lookup(&self, _ctx: Context, parent: Inode, name: &CStr) -> Result<Entry>
source§fn batch_forget(&self, _ctx: Context, requests: Vec<(Inode, u64)>)
fn batch_forget(&self, _ctx: Context, requests: Vec<(Inode, u64)>)
source§fn opendir(
&self,
_ctx: Context,
inode: Inode,
flags: u32
) -> Result<(Option<u64>, OpenOptions)>
fn opendir( &self, _ctx: Context, inode: Inode, flags: u32 ) -> Result<(Option<u64>, OpenOptions)>
source§fn releasedir(
&self,
_ctx: Context,
inode: Inode,
_flags: u32,
handle: u64
) -> Result<()>
fn releasedir( &self, _ctx: Context, inode: Inode, _flags: u32, handle: u64 ) -> Result<()>
source§fn mkdir(
&self,
ctx: Context,
parent: Inode,
name: &CStr,
mode: u32,
umask: u32,
security_ctx: Option<&CStr>
) -> Result<Entry>
fn mkdir( &self, ctx: Context, parent: Inode, name: &CStr, mode: u32, umask: u32, security_ctx: Option<&CStr> ) -> Result<Entry>
source§fn rmdir(&self, _ctx: Context, parent: Inode, name: &CStr) -> Result<()>
fn rmdir(&self, _ctx: Context, parent: Inode, name: &CStr) -> Result<()>
source§fn readdir(
&self,
_ctx: Context,
inode: Inode,
handle: u64,
size: u32,
offset: u64
) -> Result<Self::DirIter>
fn readdir( &self, _ctx: Context, inode: Inode, handle: u64, size: u32, offset: u64 ) -> Result<Self::DirIter>
source§fn open(
&self,
_ctx: Context,
inode: Inode,
flags: u32
) -> Result<(Option<u64>, OpenOptions)>
fn open( &self, _ctx: Context, inode: Inode, flags: u32 ) -> Result<(Option<u64>, OpenOptions)>
source§fn release(
&self,
_ctx: Context,
inode: Inode,
_flags: u32,
handle: u64,
_flush: bool,
_flock_release: bool,
_lock_owner: Option<u64>
) -> Result<()>
fn release( &self, _ctx: Context, inode: Inode, _flags: u32, handle: u64, _flush: bool, _flock_release: bool, _lock_owner: Option<u64> ) -> Result<()>
source§fn chromeos_tmpfile(
&self,
ctx: Context,
parent: Self::Inode,
mode: u32,
umask: u32,
security_ctx: Option<&CStr>
) -> Result<Entry>
fn chromeos_tmpfile( &self, ctx: Context, parent: Self::Inode, mode: u32, umask: u32, security_ctx: Option<&CStr> ) -> Result<Entry>
source§fn create(
&self,
ctx: Context,
parent: Inode,
name: &CStr,
mode: u32,
flags: u32,
umask: u32,
security_ctx: Option<&CStr>
) -> Result<(Entry, Option<u64>, OpenOptions)>
fn create( &self, ctx: Context, parent: Inode, name: &CStr, mode: u32, flags: u32, umask: u32, security_ctx: Option<&CStr> ) -> Result<(Entry, Option<u64>, OpenOptions)>
source§fn unlink(&self, _ctx: Context, parent: Inode, name: &CStr) -> Result<()>
fn unlink(&self, _ctx: Context, parent: Inode, name: &CStr) -> Result<()>
source§fn read<W: Write + ZeroCopyWriter>(
&self,
_ctx: Context,
inode: Inode,
handle: u64,
w: W,
size: u32,
offset: u64,
_lock_owner: Option<u64>,
_flags: u32
) -> Result<usize>
fn read<W: Write + ZeroCopyWriter>( &self, _ctx: Context, inode: Inode, handle: u64, w: W, size: u32, offset: u64, _lock_owner: Option<u64>, _flags: u32 ) -> Result<usize>
source§fn write<R: Read + ZeroCopyReader>(
&self,
_ctx: Context,
inode: Inode,
handle: u64,
r: R,
size: u32,
offset: u64,
_lock_owner: Option<u64>,
_delayed_write: bool,
flags: u32
) -> Result<usize>
fn write<R: Read + ZeroCopyReader>( &self, _ctx: Context, inode: Inode, handle: u64, r: R, size: u32, offset: u64, _lock_owner: Option<u64>, _delayed_write: bool, flags: u32 ) -> Result<usize>
source§fn getattr(
&self,
_ctx: Context,
inode: Inode,
_handle: Option<u64>
) -> Result<(stat64, Duration)>
fn getattr( &self, _ctx: Context, inode: Inode, _handle: Option<u64> ) -> Result<(stat64, Duration)>
source§fn setattr(
&self,
_ctx: Context,
inode: Inode,
attr: stat64,
handle: Option<u64>,
valid: SetattrValid
) -> Result<(stat64, Duration)>
fn setattr( &self, _ctx: Context, inode: Inode, attr: stat64, handle: Option<u64>, valid: SetattrValid ) -> Result<(stat64, Duration)>
source§fn rename(
&self,
_ctx: Context,
olddir: Inode,
oldname: &CStr,
newdir: Inode,
newname: &CStr,
flags: u32
) -> Result<()>
fn rename( &self, _ctx: Context, olddir: Inode, oldname: &CStr, newdir: Inode, newname: &CStr, flags: u32 ) -> Result<()>
source§fn mknod(
&self,
ctx: Context,
parent: Inode,
name: &CStr,
mode: u32,
rdev: u32,
umask: u32,
security_ctx: Option<&CStr>
) -> Result<Entry>
fn mknod( &self, ctx: Context, parent: Inode, name: &CStr, mode: u32, rdev: u32, umask: u32, security_ctx: Option<&CStr> ) -> Result<Entry>
source§fn link(
&self,
_ctx: Context,
inode: Inode,
newparent: Inode,
newname: &CStr
) -> Result<Entry>
fn link( &self, _ctx: Context, inode: Inode, newparent: Inode, newname: &CStr ) -> Result<Entry>
source§fn symlink(
&self,
ctx: Context,
linkname: &CStr,
parent: Inode,
name: &CStr,
security_ctx: Option<&CStr>
) -> Result<Entry>
fn symlink( &self, ctx: Context, linkname: &CStr, parent: Inode, name: &CStr, security_ctx: Option<&CStr> ) -> Result<Entry>
source§fn flush(
&self,
_ctx: Context,
inode: Inode,
handle: u64,
_lock_owner: u64
) -> Result<()>
fn flush( &self, _ctx: Context, inode: Inode, handle: u64, _lock_owner: u64 ) -> Result<()>
source§fn fsync(
&self,
_ctx: Context,
inode: Inode,
datasync: bool,
handle: u64
) -> Result<()>
fn fsync( &self, _ctx: Context, inode: Inode, datasync: bool, handle: u64 ) -> Result<()>
source§fn fsyncdir(
&self,
_ctx: Context,
inode: Inode,
datasync: bool,
handle: u64
) -> Result<()>
fn fsyncdir( &self, _ctx: Context, inode: Inode, datasync: bool, handle: u64 ) -> Result<()>
source§fn access(&self, ctx: Context, inode: Inode, mask: u32) -> Result<()>
fn access(&self, ctx: Context, inode: Inode, mask: u32) -> Result<()>
source§fn setxattr(
&self,
_ctx: Context,
inode: Inode,
name: &CStr,
value: &[u8],
flags: u32
) -> Result<()>
fn setxattr( &self, _ctx: Context, inode: Inode, name: &CStr, value: &[u8], flags: u32 ) -> Result<()>
source§fn getxattr(
&self,
_ctx: Context,
inode: Inode,
name: &CStr,
size: u32
) -> Result<GetxattrReply>
fn getxattr( &self, _ctx: Context, inode: Inode, name: &CStr, size: u32 ) -> Result<GetxattrReply>
source§fn listxattr(
&self,
_ctx: Context,
inode: Inode,
size: u32
) -> Result<ListxattrReply>
fn listxattr( &self, _ctx: Context, inode: Inode, size: u32 ) -> Result<ListxattrReply>
source§fn removexattr(&self, _ctx: Context, inode: Inode, name: &CStr) -> Result<()>
fn removexattr(&self, _ctx: Context, inode: Inode, name: &CStr) -> Result<()>
source§fn fallocate(
&self,
_ctx: Context,
inode: Inode,
handle: u64,
mode: u32,
offset: u64,
length: u64
) -> Result<()>
fn fallocate( &self, _ctx: Context, inode: Inode, handle: u64, mode: u32, offset: u64, length: u64 ) -> Result<()>
source§fn ioctl<R: Read>(
&self,
ctx: Context,
inode: Inode,
handle: u64,
_flags: IoctlFlags,
cmd: u32,
_arg: u64,
in_size: u32,
out_size: u32,
r: R
) -> Result<IoctlReply>
fn ioctl<R: Read>( &self, ctx: Context, inode: Inode, handle: u64, _flags: IoctlFlags, cmd: u32, _arg: u64, in_size: u32, out_size: u32, r: R ) -> Result<IoctlReply>
source§fn copy_file_range(
&self,
ctx: Context,
inode_src: Inode,
handle_src: u64,
offset_src: u64,
inode_dst: Inode,
handle_dst: u64,
offset_dst: u64,
length: u64,
flags: u64
) -> Result<usize>
fn copy_file_range( &self, ctx: Context, inode_src: Inode, handle_src: u64, offset_src: u64, inode_dst: Inode, handle_dst: u64, offset_dst: u64, length: u64, flags: u64 ) -> Result<usize>
source§fn set_up_mapping<M: Mapper>(
&self,
_ctx: Context,
inode: Self::Inode,
_handle: Self::Handle,
file_offset: u64,
mem_offset: u64,
size: usize,
prot: u32,
mapper: M
) -> Result<()>
fn set_up_mapping<M: Mapper>( &self, _ctx: Context, inode: Self::Inode, _handle: Self::Handle, file_offset: u64, mem_offset: u64, size: usize, prot: u32, mapper: M ) -> Result<()>
source§fn remove_mapping<M: Mapper>(
&self,
msgs: &[RemoveMappingOne],
mapper: M
) -> Result<()>
fn remove_mapping<M: Mapper>( &self, msgs: &[RemoveMappingOne], mapper: M ) -> Result<()>
source§fn atomic_open(
&self,
ctx: Context,
parent: Self::Inode,
name: &CStr,
mode: u32,
flags: u32,
umask: u32,
security_ctx: Option<&CStr>
) -> Result<(Entry, Option<Self::Handle>, OpenOptions)>
fn atomic_open( &self, ctx: Context, parent: Self::Inode, name: &CStr, mode: u32, flags: u32, umask: u32, security_ctx: Option<&CStr> ) -> Result<(Entry, Option<Self::Handle>, OpenOptions)>
source§fn max_buffer_size(&self) -> u32
fn max_buffer_size(&self) -> u32
Auto Trait Implementations§
impl RefUnwindSafe for PassthroughFs
impl Send for PassthroughFs
impl Sync for PassthroughFs
impl Unpin for PassthroughFs
impl UnwindSafe for PassthroughFs
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.