blob: 039285f8fd57067a7e62e1f7f4fc7c7151293a41 [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 Hsiehd18b9752021-11-09 16:03:34 -080020use std::path::Path;
Victor Hsiehf01f3232020-12-11 13:31:31 -080021
Victor Hsieh2445e332021-06-04 16:44:53 -070022use super::{ChunkBuffer, RandomWrite, ReadByChunk, VirtFdService};
Victor Hsiehda3fbc42021-02-23 16:12:49 -080023use crate::common::CHUNK_SIZE;
Victor Hsiehf01f3232020-12-11 13:31:31 -080024
Victor Hsieh60acfd32021-02-23 13:08:13 -080025fn remote_read_chunk(
Victor Hsiehc3d45b12021-06-30 09:16:41 -070026 service: &VirtFdService,
Victor Hsieh60acfd32021-02-23 13:08:13 -080027 remote_fd: i32,
28 chunk_index: u64,
Victor Hsiehd0bb5d32021-03-19 12:48:03 -070029 buf: &mut ChunkBuffer,
Victor Hsieh60acfd32021-02-23 13:08:13 -080030) -> io::Result<usize> {
31 let offset = i64::try_from(chunk_index * CHUNK_SIZE)
32 .map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
33
34 let chunk = service
Victor Hsieh60acfd32021-02-23 13:08:13 -080035 .readFile(remote_fd, offset, buf.len() as i32)
36 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
Victor Hsiehc81738d2021-03-25 09:52:00 -070037 let size = min(buf.len(), chunk.len());
38 buf[..size].copy_from_slice(&chunk[..size]);
39 Ok(size)
Victor Hsieh60acfd32021-02-23 13:08:13 -080040}
41
Victor Hsieh09e26262021-03-03 16:00:55 -080042pub struct RemoteFileReader {
Victor Hsiehf01f3232020-12-11 13:31:31 -080043 // This needs to have Sync trait to be used in fuse::worker::start_message_loop.
Victor Hsiehc3d45b12021-06-30 09:16:41 -070044 service: VirtFdService,
Victor Hsiehf01f3232020-12-11 13:31:31 -080045 file_fd: i32,
46}
47
Victor Hsieh09e26262021-03-03 16:00:55 -080048impl RemoteFileReader {
Victor Hsiehc3d45b12021-06-30 09:16:41 -070049 pub fn new(service: VirtFdService, file_fd: i32) -> Self {
Victor Hsieh09e26262021-03-03 16:00:55 -080050 RemoteFileReader { service, file_fd }
Victor Hsiehf01f3232020-12-11 13:31:31 -080051 }
Victor Hsiehd18b9752021-11-09 16:03:34 -080052
53 pub fn new_by_path(
54 service: VirtFdService,
55 dir_fd: i32,
56 related_path: &Path,
57 ) -> io::Result<Self> {
58 let file_fd =
59 service.openFileInDirectory(dir_fd, related_path.to_str().unwrap()).map_err(|e| {
60 io::Error::new(
61 io::ErrorKind::Other,
62 format!(
63 "Failed to create a remote file reader by path {}: {}",
64 related_path.display(),
65 e.get_description()
66 ),
67 )
68 })?;
69 Ok(RemoteFileReader { service, file_fd })
70 }
71
72 pub fn get_remote_fd(&self) -> i32 {
73 self.file_fd
74 }
Victor Hsiehf01f3232020-12-11 13:31:31 -080075}
76
Victor Hsiehd0bb5d32021-03-19 12:48:03 -070077impl ReadByChunk for RemoteFileReader {
78 fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
Victor Hsieh60acfd32021-02-23 13:08:13 -080079 remote_read_chunk(&self.service, self.file_fd, chunk_index, buf)
Victor Hsiehf01f3232020-12-11 13:31:31 -080080 }
81}
82
Victor Hsieh09e26262021-03-03 16:00:55 -080083pub struct RemoteMerkleTreeReader {
Victor Hsiehf01f3232020-12-11 13:31:31 -080084 // This needs to be a Sync to be used in fuse::worker::start_message_loop.
Victor Hsiehc3d45b12021-06-30 09:16:41 -070085 service: VirtFdService,
Victor Hsiehf01f3232020-12-11 13:31:31 -080086 file_fd: i32,
87}
88
Victor Hsieh09e26262021-03-03 16:00:55 -080089impl RemoteMerkleTreeReader {
Victor Hsiehc3d45b12021-06-30 09:16:41 -070090 pub fn new(service: VirtFdService, file_fd: i32) -> Self {
Victor Hsieh09e26262021-03-03 16:00:55 -080091 RemoteMerkleTreeReader { service, file_fd }
Victor Hsiehf01f3232020-12-11 13:31:31 -080092 }
93}
94
Victor Hsiehd0bb5d32021-03-19 12:48:03 -070095impl ReadByChunk for RemoteMerkleTreeReader {
96 fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
Victor Hsiehda3fbc42021-02-23 16:12:49 -080097 let offset = i64::try_from(chunk_index * CHUNK_SIZE)
Victor Hsiehf01f3232020-12-11 13:31:31 -080098 .map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
99
Victor Hsieh60acfd32021-02-23 13:08:13 -0800100 let chunk = self
101 .service
Victor Hsiehf01f3232020-12-11 13:31:31 -0800102 .readFsverityMerkleTree(self.file_fd, offset, buf.len() as i32)
103 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
Victor Hsiehc81738d2021-03-25 09:52:00 -0700104 let size = min(buf.len(), chunk.len());
105 buf[..size].copy_from_slice(&chunk[..size]);
106 Ok(size)
Victor Hsiehf01f3232020-12-11 13:31:31 -0800107 }
108}
Victor Hsieh60acfd32021-02-23 13:08:13 -0800109
110pub struct RemoteFileEditor {
111 // This needs to have Sync trait to be used in fuse::worker::start_message_loop.
Victor Hsiehc3d45b12021-06-30 09:16:41 -0700112 service: VirtFdService,
Victor Hsieh60acfd32021-02-23 13:08:13 -0800113 file_fd: i32,
114}
115
116impl RemoteFileEditor {
Victor Hsiehc3d45b12021-06-30 09:16:41 -0700117 pub fn new(service: VirtFdService, file_fd: i32) -> Self {
Victor Hsieh60acfd32021-02-23 13:08:13 -0800118 RemoteFileEditor { service, file_fd }
119 }
120}
121
122impl RandomWrite for RemoteFileEditor {
123 fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
124 let offset =
125 i64::try_from(offset).map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
126 let size = self
127 .service
Chris Wailes68c39f82021-07-27 16:03:44 -0700128 .writeFile(self.file_fd, buf, offset)
Victor Hsieh60acfd32021-02-23 13:08:13 -0800129 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
130 Ok(size as usize) // within range because size is supposed to <= buf.len(), which is a usize
131 }
Victor Hsieh9d0ab622021-04-26 17:07:02 -0700132
133 fn resize(&self, size: u64) -> io::Result<()> {
134 let size =
135 i64::try_from(size).map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?;
136 self.service
Victor Hsieh9d0ab622021-04-26 17:07:02 -0700137 .resize(self.file_fd, size)
138 .map_err(|e| io::Error::new(io::ErrorKind::Other, e.get_description()))?;
139 Ok(())
140 }
Victor Hsieh60acfd32021-02-23 13:08:13 -0800141}
142
Victor Hsiehd0bb5d32021-03-19 12:48:03 -0700143impl ReadByChunk for RemoteFileEditor {
144 fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
Victor Hsieh60acfd32021-02-23 13:08:13 -0800145 remote_read_chunk(&self.service, self.file_fd, chunk_index, buf)
146 }
147}