blob: 9bbf3ef85804322a8f1fce0bf4383e0330fea49b [file] [log] [blame]
Victor Hsiehf393a722021-12-08 13:04:27 -08001mod attr;
Victor Hsieh4d6b9d42021-11-08 15:53:49 -08002mod dir;
Victor Hsieh09e26262021-03-03 16:00:55 -08003mod remote_file;
4
Victor Hsiehf393a722021-12-08 13:04:27 -08005pub use attr::Attr;
Victor Hsieh4d6b9d42021-11-08 15:53:49 -08006pub use dir::{InMemoryDir, RemoteDirEditor};
Victor Hsieh6a47e7f2021-03-03 15:53:49 -08007pub use remote_file::{RemoteFileEditor, RemoteFileReader, RemoteMerkleTreeReader};
Victor Hsieh09e26262021-03-03 16:00:55 -08008
Victor Hsieh2445e332021-06-04 16:44:53 -07009use binder::unstable_api::{new_spibinder, AIBinder};
10use binder::FromIBinder;
Victor Hsieh09e26262021-03-03 16:00:55 -080011use std::io;
Victor Hsieh4d6b9d42021-11-08 15:53:49 -080012use std::path::{Path, MAIN_SEPARATOR};
Victor Hsieh09e26262021-03-03 16:00:55 -080013
Victor Hsiehd0bb5d32021-03-19 12:48:03 -070014use crate::common::CHUNK_SIZE;
Victor Hsieh2445e332021-06-04 16:44:53 -070015use authfs_aidl_interface::aidl::com::android::virt::fs::IVirtFdService::IVirtFdService;
Victor Hsieh45636232021-10-15 17:52:51 -070016use authfs_aidl_interface::binder::{Status, Strong};
Victor Hsieh09e26262021-03-03 16:00:55 -080017
Victor Hsieh2445e332021-06-04 16:44:53 -070018pub type VirtFdService = Strong<dyn IVirtFdService>;
Victor Hsieh45636232021-10-15 17:52:51 -070019pub type VirtFdServiceStatus = Status;
Victor Hsieh09e26262021-03-03 16:00:55 -080020
Victor Hsiehd0bb5d32021-03-19 12:48:03 -070021pub type ChunkBuffer = [u8; CHUNK_SIZE as usize];
22
Victor Hsieh2445e332021-06-04 16:44:53 -070023pub const RPC_SERVICE_PORT: u32 = 3264;
24
Victor Hsieh1a8cd042021-09-03 16:29:45 -070025pub fn get_rpc_binder_service(cid: u32) -> io::Result<VirtFdService> {
Victor Hsieh2445e332021-06-04 16:44:53 -070026 // SAFETY: AIBinder returned by RpcClient has correct reference count, and the ownership can be
27 // safely taken by new_spibinder.
28 let ibinder = unsafe {
29 new_spibinder(binder_rpc_unstable_bindgen::RpcClient(cid, RPC_SERVICE_PORT) as *mut AIBinder)
30 };
31 if let Some(ibinder) = ibinder {
Chris Wailes2acfb0a2021-07-21 11:51:22 -070032 Ok(<dyn IVirtFdService>::try_from(ibinder).map_err(|e| {
Victor Hsieh2445e332021-06-04 16:44:53 -070033 io::Error::new(
34 io::ErrorKind::AddrNotAvailable,
35 format!("Cannot connect to RPC service: {}", e),
36 )
37 })?)
38 } else {
39 Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid raw AIBinder"))
40 }
41}
42
Victor Hsiehd0bb5d32021-03-19 12:48:03 -070043/// A trait for reading data by chunks. Chunks can be read by specifying the chunk index. Only the
44/// last chunk may have incomplete chunk size.
45pub trait ReadByChunk {
46 /// Reads the `chunk_index`-th chunk to a `ChunkBuffer`. Returns the size read, which has to be
47 /// `CHUNK_SIZE` except for the last incomplete chunk. Reading beyond the file size (including
48 /// empty file) should return 0.
49 fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize>;
Victor Hsieh09e26262021-03-03 16:00:55 -080050}
51
52/// A trait to write a buffer to the destination at a given offset. The implementation does not
53/// necessarily own or maintain the destination state.
54///
55/// NB: The trait is required in a member of `fusefs::AuthFs`, which is required to be Sync and
56/// immutable (this the member).
57pub trait RandomWrite {
58 /// Writes `buf` to the destination at `offset`. Returns the written size, which may not be the
59 /// full buffer.
60 fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
61
62 /// Writes the full `buf` to the destination at `offset`.
63 fn write_all_at(&self, buf: &[u8], offset: u64) -> io::Result<()> {
64 let mut input_offset = 0;
65 let mut output_offset = offset;
66 while input_offset < buf.len() {
67 let size = self.write_at(&buf[input_offset..], output_offset)?;
68 input_offset += size;
69 output_offset += size as u64;
70 }
71 Ok(())
72 }
Victor Hsieh9d0ab622021-04-26 17:07:02 -070073
74 /// Resizes the file to the new size.
75 fn resize(&self, size: u64) -> io::Result<()>;
Victor Hsieh09e26262021-03-03 16:00:55 -080076}
Victor Hsieh4d6b9d42021-11-08 15:53:49 -080077
78/// Checks whether the path is a simple file name without any directory separator.
79pub fn validate_basename(path: &Path) -> io::Result<()> {
80 if matches!(path.to_str(), Some(path_str) if !path_str.contains(MAIN_SEPARATOR)) {
81 Ok(())
82 } else {
83 Err(io::Error::from_raw_os_error(libc::EINVAL))
84 }
85}