xref: /aosp_15_r20/system/core/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.h (revision 00c7fec1bb09f3284aad6a6f96d2f63dfc3650ad)
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