blob: dbf6bd9ea8044bbfcfa14e8ab40b5a23f469614c [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 Hsieh09e26262021-03-03 16:00:55 -080022use super::{RandomWrite, ReadOnlyDataByChunk};
Victor Hsiehda3fbc42021-02-23 16:12:49 -080023use crate::common::CHUNK_SIZE;
Victor Hsiehf01f3232020-12-11 13:31:31 -080024
25use authfs_aidl_interface::aidl::com::android::virt::fs::IVirtFdService;
26use authfs_aidl_interface::binder::Strong;
27
28type VirtFdService = Strong<dyn IVirtFdService::IVirtFdService>;
29
Victor Hsieh60acfd32021-02-23 13:08:13 -080030fn remote_read_chunk(
31 service: &Arc<Mutex<VirtFdService>>,
32 remote_fd: i32,
33 chunk_index: u64,
34 mut buf: &mut [u8],
35) -> io::Result<usize> {
36 let offset = i64::try_from(chunk_index * CHUNK_SIZE)
37 .map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
38
39 let chunk = service
40 .lock()
41 .unwrap()
42 .readFile(remote_fd, offset, buf.len() as i32)
43 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
44 buf.write(&chunk)
45}
46
Victor Hsieh09e26262021-03-03 16:00:55 -080047pub struct RemoteFileReader {
Victor Hsiehf01f3232020-12-11 13:31:31 -080048 // This needs to have Sync trait to be used in fuse::worker::start_message_loop.
49 service: Arc<Mutex<VirtFdService>>,
50 file_fd: i32,
51}
52
Victor Hsieh09e26262021-03-03 16:00:55 -080053impl RemoteFileReader {
Victor Hsiehf01f3232020-12-11 13:31:31 -080054 pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
Victor Hsieh09e26262021-03-03 16:00:55 -080055 RemoteFileReader { service, file_fd }
Victor Hsiehf01f3232020-12-11 13:31:31 -080056 }
57}
58
Victor Hsieh09e26262021-03-03 16:00:55 -080059impl ReadOnlyDataByChunk for RemoteFileReader {
Victor Hsieh60acfd32021-02-23 13:08:13 -080060 fn read_chunk(&self, chunk_index: u64, buf: &mut [u8]) -> io::Result<usize> {
61 remote_read_chunk(&self.service, self.file_fd, chunk_index, buf)
Victor Hsiehf01f3232020-12-11 13:31:31 -080062 }
63}
64
Victor Hsieh09e26262021-03-03 16:00:55 -080065pub struct RemoteMerkleTreeReader {
Victor Hsiehf01f3232020-12-11 13:31:31 -080066 // 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
Victor Hsieh09e26262021-03-03 16:00:55 -080072impl RemoteMerkleTreeReader {
Victor Hsiehf01f3232020-12-11 13:31:31 -080073 pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
Victor Hsieh09e26262021-03-03 16:00:55 -080074 RemoteMerkleTreeReader { service, file_fd }
Victor Hsiehf01f3232020-12-11 13:31:31 -080075 }
76}
77
Victor Hsieh09e26262021-03-03 16:00:55 -080078impl ReadOnlyDataByChunk for RemoteMerkleTreeReader {
Victor Hsiehf01f3232020-12-11 13:31:31 -080079 fn read_chunk(&self, chunk_index: u64, mut buf: &mut [u8]) -> io::Result<usize> {
Victor Hsiehda3fbc42021-02-23 16:12:49 -080080 let offset = i64::try_from(chunk_index * CHUNK_SIZE)
Victor Hsiehf01f3232020-12-11 13:31:31 -080081 .map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
82
Victor Hsieh60acfd32021-02-23 13:08:13 -080083 let chunk = self
84 .service
Victor Hsiehf01f3232020-12-11 13:31:31 -080085 .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}
Victor Hsieh60acfd32021-02-23 13:08:13 -080092
93pub struct RemoteFileEditor {
94 // This needs to have Sync trait to be used in fuse::worker::start_message_loop.
95 service: Arc<Mutex<VirtFdService>>,
96 file_fd: i32,
97}
98
99impl RemoteFileEditor {
Victor Hsieh60acfd32021-02-23 13:08:13 -0800100 pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
101 RemoteFileEditor { service, file_fd }
102 }
103}
104
105impl RandomWrite for RemoteFileEditor {
106 fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
107 let offset =
108 i64::try_from(offset).map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
109 let size = self
110 .service
111 .lock()
112 .unwrap()
113 .writeFile(self.file_fd, &buf, offset)
114 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
115 Ok(size as usize) // within range because size is supposed to <= buf.len(), which is a usize
116 }
117}
118
119impl ReadOnlyDataByChunk for RemoteFileEditor {
120 fn read_chunk(&self, chunk_index: u64, buf: &mut [u8]) -> io::Result<usize> {
121 remote_read_chunk(&self.service, self.file_fd, chunk_index, buf)
122 }
123}