blob: ed7381c6f5dec9a92b8796b9b7349b22c5d3cb6b [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;
Victor Hsieh60acfd32021-02-23 13:08:13 -080024use crate::writer::RandomWrite;
Victor Hsiehf01f3232020-12-11 13:31:31 -080025
26use authfs_aidl_interface::aidl::com::android::virt::fs::IVirtFdService;
27use authfs_aidl_interface::binder::Strong;
28
29type VirtFdService = Strong<dyn IVirtFdService::IVirtFdService>;
30
31pub mod server {
32 // TODO(victorhsieh): use remote binder.
33 pub fn get_local_service() -> super::VirtFdService {
34 let service_name = "authfs_fd_server";
35 authfs_aidl_interface::binder::get_interface(&service_name)
36 .expect("Cannot reach authfs_fd_server binder service")
37 }
38}
39
Victor Hsieh60acfd32021-02-23 13:08:13 -080040fn remote_read_chunk(
41 service: &Arc<Mutex<VirtFdService>>,
42 remote_fd: i32,
43 chunk_index: u64,
44 mut buf: &mut [u8],
45) -> io::Result<usize> {
46 let offset = i64::try_from(chunk_index * CHUNK_SIZE)
47 .map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
48
49 let chunk = service
50 .lock()
51 .unwrap()
52 .readFile(remote_fd, offset, buf.len() as i32)
53 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
54 buf.write(&chunk)
55}
56
Victor Hsiehf01f3232020-12-11 13:31:31 -080057pub struct RemoteChunkedFileReader {
58 // This needs to have Sync trait to be used in fuse::worker::start_message_loop.
59 service: Arc<Mutex<VirtFdService>>,
60 file_fd: i32,
61}
62
63impl RemoteChunkedFileReader {
64 pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
65 RemoteChunkedFileReader { service, file_fd }
66 }
67}
68
69impl ReadOnlyDataByChunk for RemoteChunkedFileReader {
Victor Hsieh60acfd32021-02-23 13:08:13 -080070 fn read_chunk(&self, chunk_index: u64, buf: &mut [u8]) -> io::Result<usize> {
71 remote_read_chunk(&self.service, self.file_fd, chunk_index, buf)
Victor Hsiehf01f3232020-12-11 13:31:31 -080072 }
73}
74
75pub struct RemoteFsverityMerkleTreeReader {
76 // This needs to be a Sync to be used in fuse::worker::start_message_loop.
77 // TODO(victorhsieh): change to Strong<> once binder supports it.
78 service: Arc<Mutex<VirtFdService>>,
79 file_fd: i32,
80}
81
82impl RemoteFsverityMerkleTreeReader {
83 pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
84 RemoteFsverityMerkleTreeReader { service, file_fd }
85 }
86}
87
88impl ReadOnlyDataByChunk for RemoteFsverityMerkleTreeReader {
89 fn read_chunk(&self, chunk_index: u64, mut buf: &mut [u8]) -> io::Result<usize> {
Victor Hsiehda3fbc42021-02-23 16:12:49 -080090 let offset = i64::try_from(chunk_index * CHUNK_SIZE)
Victor Hsiehf01f3232020-12-11 13:31:31 -080091 .map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
92
Victor Hsieh60acfd32021-02-23 13:08:13 -080093 let chunk = self
94 .service
Victor Hsiehf01f3232020-12-11 13:31:31 -080095 .lock()
96 .unwrap()
97 .readFsverityMerkleTree(self.file_fd, offset, buf.len() as i32)
98 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
99 buf.write(&chunk)
100 }
101}
Victor Hsieh60acfd32021-02-23 13:08:13 -0800102
103pub struct RemoteFileEditor {
104 // This needs to have Sync trait to be used in fuse::worker::start_message_loop.
105 service: Arc<Mutex<VirtFdService>>,
106 file_fd: i32,
107}
108
109impl RemoteFileEditor {
110 #[allow(dead_code)]
111 pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
112 RemoteFileEditor { service, file_fd }
113 }
114}
115
116impl RandomWrite for RemoteFileEditor {
117 fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
118 let offset =
119 i64::try_from(offset).map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
120 let size = self
121 .service
122 .lock()
123 .unwrap()
124 .writeFile(self.file_fd, &buf, offset)
125 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
126 Ok(size as usize) // within range because size is supposed to <= buf.len(), which is a usize
127 }
128}
129
130impl ReadOnlyDataByChunk for RemoteFileEditor {
131 fn read_chunk(&self, chunk_index: u64, buf: &mut [u8]) -> io::Result<usize> {
132 remote_read_chunk(&self.service, self.file_fd, chunk_index, buf)
133 }
134}