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