blob: 01e803cedc3a321d4918251a5c8ca37b3ac35f8a [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
Victor Hsiehda3fbc42021-02-23 16:12:49 -080022use crate::common::CHUNK_SIZE;
Victor Hsiehf01f3232020-12-11 13:31:31 -080023use crate::reader::ReadOnlyDataByChunk;
24
25use authfs_aidl_interface::aidl::com::android::virt::fs::IVirtFdService;
26use authfs_aidl_interface::binder::Strong;
27
28type VirtFdService = Strong<dyn IVirtFdService::IVirtFdService>;
29
30pub mod server {
31 // TODO(victorhsieh): use remote binder.
32 pub fn get_local_service() -> super::VirtFdService {
33 let service_name = "authfs_fd_server";
34 authfs_aidl_interface::binder::get_interface(&service_name)
35 .expect("Cannot reach authfs_fd_server binder service")
36 }
37}
38
39pub struct RemoteChunkedFileReader {
40 // This needs to have Sync trait to be used in fuse::worker::start_message_loop.
41 service: Arc<Mutex<VirtFdService>>,
42 file_fd: i32,
43}
44
45impl RemoteChunkedFileReader {
46 pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
47 RemoteChunkedFileReader { service, file_fd }
48 }
49}
50
51impl ReadOnlyDataByChunk for RemoteChunkedFileReader {
52 fn read_chunk(&self, chunk_index: u64, mut buf: &mut [u8]) -> io::Result<usize> {
Victor Hsiehda3fbc42021-02-23 16:12:49 -080053 let offset = i64::try_from(chunk_index * CHUNK_SIZE)
Victor Hsiehf01f3232020-12-11 13:31:31 -080054 .map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
55
56 let service = Arc::clone(&self.service);
57 let chunk = service
58 .lock()
59 .unwrap()
60 .readFile(self.file_fd, offset, buf.len() as i32)
61 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
62 buf.write(&chunk)
63 }
64}
65
66pub struct RemoteFsverityMerkleTreeReader {
67 // This needs to be a Sync to be used in fuse::worker::start_message_loop.
68 // TODO(victorhsieh): change to Strong<> once binder supports it.
69 service: Arc<Mutex<VirtFdService>>,
70 file_fd: i32,
71}
72
73impl RemoteFsverityMerkleTreeReader {
74 pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
75 RemoteFsverityMerkleTreeReader { service, file_fd }
76 }
77}
78
79impl ReadOnlyDataByChunk for RemoteFsverityMerkleTreeReader {
80 fn read_chunk(&self, chunk_index: u64, mut buf: &mut [u8]) -> io::Result<usize> {
Victor Hsiehda3fbc42021-02-23 16:12:49 -080081 let offset = i64::try_from(chunk_index * CHUNK_SIZE)
Victor Hsiehf01f3232020-12-11 13:31:31 -080082 .map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
83
84 let service = Arc::clone(&self.service);
85 let chunk = service
86 .lock()
87 .unwrap()
88 .readFsverityMerkleTree(self.file_fd, offset, buf.len() as i32)
89 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
90 buf.write(&chunk)
91 }
92}