blob: bd9989335604bf920447702e26acbbe9a6e1b777 [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
Victor Hsiehd0bb5d32021-03-19 12:48:03 -070017use std::cmp::min;
Victor Hsiehf01f3232020-12-11 13:31:31 -080018use std::convert::TryFrom;
19use std::io;
Victor Hsiehf01f3232020-12-11 13:31:31 -080020use std::sync::{Arc, Mutex};
21
Victor Hsiehd0bb5d32021-03-19 12:48:03 -070022use super::{ChunkBuffer, RandomWrite, ReadByChunk};
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,
Victor Hsiehd0bb5d32021-03-19 12:48:03 -070034 buf: &mut ChunkBuffer,
Victor Hsieh60acfd32021-02-23 13:08:13 -080035) -> 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()))?;
Victor Hsiehc81738d2021-03-25 09:52:00 -070044 let size = min(buf.len(), chunk.len());
45 buf[..size].copy_from_slice(&chunk[..size]);
46 Ok(size)
Victor Hsieh60acfd32021-02-23 13:08:13 -080047}
48
Victor Hsieh09e26262021-03-03 16:00:55 -080049pub struct RemoteFileReader {
Victor Hsiehf01f3232020-12-11 13:31:31 -080050 // This needs to have Sync trait to be used in fuse::worker::start_message_loop.
51 service: Arc<Mutex<VirtFdService>>,
52 file_fd: i32,
53}
54
Victor Hsieh09e26262021-03-03 16:00:55 -080055impl RemoteFileReader {
Victor Hsiehf01f3232020-12-11 13:31:31 -080056 pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
Victor Hsieh09e26262021-03-03 16:00:55 -080057 RemoteFileReader { service, file_fd }
Victor Hsiehf01f3232020-12-11 13:31:31 -080058 }
59}
60
Victor Hsiehd0bb5d32021-03-19 12:48:03 -070061impl ReadByChunk for RemoteFileReader {
62 fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
Victor Hsieh60acfd32021-02-23 13:08:13 -080063 remote_read_chunk(&self.service, self.file_fd, chunk_index, buf)
Victor Hsiehf01f3232020-12-11 13:31:31 -080064 }
65}
66
Victor Hsieh09e26262021-03-03 16:00:55 -080067pub struct RemoteMerkleTreeReader {
Victor Hsiehf01f3232020-12-11 13:31:31 -080068 // This needs to be a Sync to be used in fuse::worker::start_message_loop.
69 // TODO(victorhsieh): change to Strong<> once binder supports it.
70 service: Arc<Mutex<VirtFdService>>,
71 file_fd: i32,
72}
73
Victor Hsieh09e26262021-03-03 16:00:55 -080074impl RemoteMerkleTreeReader {
Victor Hsiehf01f3232020-12-11 13:31:31 -080075 pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
Victor Hsieh09e26262021-03-03 16:00:55 -080076 RemoteMerkleTreeReader { service, file_fd }
Victor Hsiehf01f3232020-12-11 13:31:31 -080077 }
78}
79
Victor Hsiehd0bb5d32021-03-19 12:48:03 -070080impl ReadByChunk for RemoteMerkleTreeReader {
81 fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
Victor Hsiehda3fbc42021-02-23 16:12:49 -080082 let offset = i64::try_from(chunk_index * CHUNK_SIZE)
Victor Hsiehf01f3232020-12-11 13:31:31 -080083 .map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
84
Victor Hsieh60acfd32021-02-23 13:08:13 -080085 let chunk = self
86 .service
Victor Hsiehf01f3232020-12-11 13:31:31 -080087 .lock()
88 .unwrap()
89 .readFsverityMerkleTree(self.file_fd, offset, buf.len() as i32)
90 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
Victor Hsiehc81738d2021-03-25 09:52:00 -070091 let size = min(buf.len(), chunk.len());
92 buf[..size].copy_from_slice(&chunk[..size]);
93 Ok(size)
Victor Hsiehf01f3232020-12-11 13:31:31 -080094 }
95}
Victor Hsieh60acfd32021-02-23 13:08:13 -080096
97pub struct RemoteFileEditor {
98 // This needs to have Sync trait to be used in fuse::worker::start_message_loop.
99 service: Arc<Mutex<VirtFdService>>,
100 file_fd: i32,
101}
102
103impl RemoteFileEditor {
Victor Hsieh60acfd32021-02-23 13:08:13 -0800104 pub fn new(service: Arc<Mutex<VirtFdService>>, file_fd: i32) -> Self {
105 RemoteFileEditor { service, file_fd }
106 }
107}
108
109impl RandomWrite for RemoteFileEditor {
110 fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
111 let offset =
112 i64::try_from(offset).map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
113 let size = self
114 .service
115 .lock()
116 .unwrap()
117 .writeFile(self.file_fd, &buf, offset)
118 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
119 Ok(size as usize) // within range because size is supposed to <= buf.len(), which is a usize
120 }
Victor Hsieh9d0ab622021-04-26 17:07:02 -0700121
122 fn resize(&self, size: u64) -> io::Result<()> {
123 let size =
124 i64::try_from(size).map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
125 self.service
126 .lock()
127 .unwrap()
128 .resize(self.file_fd, size)
129 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
130 Ok(())
131 }
Victor Hsieh60acfd32021-02-23 13:08:13 -0800132}
133
Victor Hsiehd0bb5d32021-03-19 12:48:03 -0700134impl ReadByChunk for RemoteFileEditor {
135 fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
Victor Hsieh60acfd32021-02-23 13:08:13 -0800136 remote_read_chunk(&self.service, self.file_fd, chunk_index, buf)
137 }
138}