blob: 7c3d12e88529f6d7925f4a760f1b6b16f4ddfc36 [file] [log] [blame]
Victor Hsiehf01f3232020-12-11 13:31:31 -08001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17use std::convert::TryFrom;
18use std::io;
19use std::io::Write;
20use std::sync::{Arc, Mutex};
21
22use crate::reader::ReadOnlyDataByChunk;
23
24use authfs_aidl_interface::aidl::com::android::virt::fs::IVirtFdService;
25use authfs_aidl_interface::binder::Strong;
26
27type VirtFdService = Strong<dyn IVirtFdService::IVirtFdService>;
28
29pub mod server {
30 // TODO(victorhsieh): use remote binder.
31 pub fn get_local_service() -> super::VirtFdService {
32 let service_name = "authfs_fd_server";
33 authfs_aidl_interface::binder::get_interface(&service_name)
34 .expect("Cannot reach authfs_fd_server binder service")
35 }
36}
37
38pub struct RemoteChunkedFileReader {
39 // This needs to have Sync trait to be used in fuse::worker::start_message_loop.
40 service: Arc<Mutex<VirtFdService>>,
41 file_fd: i32,
42}
43
44impl RemoteChunkedFileReader {
45 pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
46 RemoteChunkedFileReader { service, file_fd }
47 }
48}
49
50impl ReadOnlyDataByChunk for RemoteChunkedFileReader {
51 fn read_chunk(&self, chunk_index: u64, mut buf: &mut [u8]) -> io::Result<usize> {
52 let offset = i64::try_from(chunk_index * Self::CHUNK_SIZE)
53 .map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
54
55 let service = Arc::clone(&self.service);
56 let chunk = service
57 .lock()
58 .unwrap()
59 .readFile(self.file_fd, offset, buf.len() as i32)
60 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
61 buf.write(&chunk)
62 }
63}
64
65pub struct RemoteFsverityMerkleTreeReader {
66 // This needs to be a Sync to be used in fuse::worker::start_message_loop.
67 // TODO(victorhsieh): change to Strong<> once binder supports it.
68 service: Arc<Mutex<VirtFdService>>,
69 file_fd: i32,
70}
71
72impl RemoteFsverityMerkleTreeReader {
73 pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
74 RemoteFsverityMerkleTreeReader { service, file_fd }
75 }
76}
77
78impl ReadOnlyDataByChunk for RemoteFsverityMerkleTreeReader {
79 fn read_chunk(&self, chunk_index: u64, mut buf: &mut [u8]) -> io::Result<usize> {
80 let offset = i64::try_from(chunk_index * Self::CHUNK_SIZE)
81 .map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
82
83 let service = Arc::clone(&self.service);
84 let chunk = service
85 .lock()
86 .unwrap()
87 .readFsverityMerkleTree(self.file_fd, offset, buf.len() as i32)
88 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
89 buf.write(&chunk)
90 }
91}