Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/fuse/src/lib.rs
5394 views
1
// Copyright 2020 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
//! FUSE (Filesystem in Userspace) server and filesystem mounting support.
6
7
#![cfg(any(target_os = "android", target_os = "linux"))]
8
9
use std::ffi::FromBytesWithNulError;
10
use std::fs::File;
11
use std::io;
12
13
use remain::sorted;
14
use thiserror::Error as ThisError;
15
16
pub mod filesystem;
17
pub mod fuzzing;
18
pub mod mount;
19
mod server;
20
#[allow(dead_code)]
21
pub mod sys;
22
pub mod worker;
23
24
use filesystem::FileSystem;
25
pub use mount::mount;
26
pub use server::Mapper;
27
pub use server::Reader;
28
pub use server::Server;
29
pub use server::Writer;
30
31
/// Errors that may occur during the creation or operation of an Fs device.
32
#[sorted]
33
#[derive(ThisError, Debug)]
34
pub enum Error {
35
/// A request is missing readable descriptors.
36
/// Failed to decode protocol messages.
37
#[error("failed to decode fuse message: {0}")]
38
DecodeMessage(io::Error),
39
/// Failed to encode protocol messages.
40
#[error("failed to encode fuse message: {0}")]
41
EncodeMessage(io::Error),
42
/// Failed to set up FUSE endpoint to talk with.
43
#[error("failed to set up FUSE endpoint to talk with: {0}")]
44
EndpointSetup(io::Error),
45
/// Failed to flush protocol messages.
46
#[error("failed to flush fuse message: {0}")]
47
FlushMessage(io::Error),
48
/// A C string parameter is invalid.
49
#[error("a c string parameter is invalid: {0}")]
50
InvalidCString(FromBytesWithNulError),
51
/// The `len` field of the header is too small.
52
#[error("the `len` field of the header is too small")]
53
InvalidHeaderLength,
54
/// The `size` field of the `SetxattrIn` message does not match the length
55
/// of the decoded value.
56
#[error(
57
"The `size` field of the `SetxattrIn` message does not match the\
58
length of the decoded value: size = {0}, value.len() = {1}"
59
)]
60
InvalidXattrSize(u32, usize),
61
/// One or more parameters are missing.
62
#[error("one or more parameters are missing")]
63
MissingParameter,
64
/// Thread exited
65
#[error("Thread exited")]
66
ThreadExited,
67
/// Requested too many `iovec`s for an `ioctl` retry.
68
#[error(
69
"requested too many `iovec`s for an `ioctl` retry reply: requested\
70
{0}, max: {1}"
71
)]
72
TooManyIovecs(usize, usize),
73
}
74
75
pub type Result<T> = ::std::result::Result<T, Error>;
76
77
#[derive(Default)]
78
pub struct FuseConfig {
79
dev_fuse_file: Option<File>,
80
max_write_bytes: Option<u32>,
81
max_read_bytes: Option<u32>,
82
num_of_threads: Option<usize>,
83
}
84
85
impl FuseConfig {
86
pub fn new() -> Self {
87
FuseConfig {
88
..Default::default()
89
}
90
}
91
92
/// Set the FUSE device.
93
pub fn dev_fuse(&mut self, file: File) -> &mut Self {
94
self.dev_fuse_file = Some(file);
95
self
96
}
97
98
/// Set the maximum data in a read request. Must be large enough (usually equal) to `n` in
99
/// `MountOption::MaxRead(n)`.
100
pub fn max_read(&mut self, bytes: u32) -> &mut Self {
101
self.max_read_bytes = Some(bytes);
102
self
103
}
104
105
/// Set the maximum data in a write request.
106
pub fn max_write(&mut self, bytes: u32) -> &mut Self {
107
self.max_write_bytes = Some(bytes);
108
self
109
}
110
111
/// Set the number of threads to run the `FileSystem`.
112
pub fn num_threads(&mut self, num: usize) -> &mut Self {
113
self.num_of_threads = Some(num);
114
self
115
}
116
117
pub fn enter_message_loop<F: FileSystem + Sync + Send>(self, fs: F) -> Result<()> {
118
let FuseConfig {
119
dev_fuse_file,
120
max_write_bytes,
121
max_read_bytes,
122
num_of_threads,
123
} = self;
124
let num = num_of_threads.unwrap_or(1);
125
if num == 1 {
126
worker::start_message_loop(
127
dev_fuse_file.ok_or(Error::MissingParameter)?,
128
max_read_bytes.ok_or(Error::MissingParameter)?,
129
max_write_bytes.ok_or(Error::MissingParameter)?,
130
fs,
131
)
132
} else {
133
worker::internal::start_message_loop_mt(
134
dev_fuse_file.ok_or(Error::MissingParameter)?,
135
max_read_bytes.ok_or(Error::MissingParameter)?,
136
max_write_bytes.ok_or(Error::MissingParameter)?,
137
num,
138
fs,
139
)
140
}
141
}
142
}
143
144