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