1 // Copyright (C) 2023 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #pragma once 16 17 #include <utility> 18 #include <vector> 19 20 #include <snapuserd/block_server.h> 21 #include "worker.h" 22 23 namespace android { 24 namespace snapshot { 25 26 class ReadWorker : public Worker, public IBlockServer::Delegate { 27 public: 28 ReadWorker(const std::string& cow_device, const std::string& backing_device, 29 const std::string& misc_name, const std::string& base_path_merge, 30 std::shared_ptr<SnapshotHandler> snapuserd, 31 std::shared_ptr<IBlockServerOpener> opener, bool direct_read = false); 32 33 bool Run(); 34 bool Init() override; 35 void CloseFds() override; 36 bool RequestSectors(uint64_t sector, uint64_t size) override; 37 block_server()38 IBlockServer* block_server() const { return block_server_.get(); } 39 40 private: 41 bool SendBufferedIo(); 42 43 bool ProcessCowOp(const CowOperation* cow_op, void* buffer); 44 bool ProcessXorOp(const CowOperation* cow_op, void* buffer); 45 bool ProcessOrderedOp(const CowOperation* cow_op, void* buffer); 46 bool ProcessCopyOp(const CowOperation* cow_op, void* buffer); 47 bool ProcessReplaceOp(const CowOperation* cow_op, void* buffer, size_t buffer_size); 48 bool ProcessZeroOp(void* buffer); 49 50 bool IsMappingPresent(const CowOperation* cow_op, loff_t requested_offset, 51 loff_t cow_op_offset); 52 bool GetCowOpBlockOffset(const CowOperation* cow_op, uint64_t io_block, off_t* block_offset); 53 bool ReadAlignedSector(sector_t sector, size_t sz); 54 bool ReadUnalignedSector(sector_t sector, size_t size); 55 int ReadUnalignedSector(sector_t sector, size_t size, 56 std::vector<std::pair<sector_t, const CowOperation*>>::iterator& it); 57 bool ReadFromSourceDevice(const CowOperation* cow_op, void* buffer); 58 bool ReadDataFromBaseDevice(sector_t sector, void* buffer, size_t read_size); 59 IsBlockAligned(uint64_t size)60 constexpr bool IsBlockAligned(uint64_t size) { return ((size & (BLOCK_SZ - 1)) == 0); } ChunkToSector(chunk_t chunk)61 constexpr sector_t ChunkToSector(chunk_t chunk) { return chunk << CHUNK_SHIFT; } SectorToChunk(sector_t sector)62 constexpr chunk_t SectorToChunk(sector_t sector) { return sector >> CHUNK_SHIFT; } 63 64 std::string backing_store_device_; 65 unique_fd backing_store_fd_; 66 unique_fd backing_store_direct_fd_; 67 bool direct_read_ = false; 68 69 std::shared_ptr<IBlockServerOpener> block_server_opener_; 70 std::unique_ptr<IBlockServer> block_server_; 71 72 std::vector<uint8_t> xor_buffer_; 73 std::unique_ptr<void, decltype(&::free)> aligned_buffer_; 74 std::unique_ptr<uint8_t[]> decompressed_buffer_; 75 }; 76 77 } // namespace snapshot 78 } // namespace android 79