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 <stddef.h> 18 #include <stdint.h> 19 20 #include <memory> 21 #include <string> 22 #include <unordered_set> 23 #include <vector> 24 25 #include <android-base/unique_fd.h> 26 #include <libsnapshot/cow_reader.h> 27 #include <liburing.h> 28 #include <snapuserd/snapuserd_buffer.h> 29 30 namespace android { 31 namespace snapshot { 32 33 class SnapshotHandler; 34 35 class ReadAhead { 36 public: 37 ReadAhead(const std::string& cow_device, const std::string& backing_device, 38 const std::string& misc_name, std::shared_ptr<SnapshotHandler> snapuserd, 39 uint32_t cow_op_merge_size); 40 bool RunThread(); 41 42 private: 43 void InitializeRAIter(); 44 bool RAIterDone(); 45 void RAIterNext(); 46 void RAResetIter(uint64_t num_blocks); 47 const CowOperation* GetRAOpIter(); 48 49 void InitializeBuffer(); 50 bool InitReader(); 51 bool InitializeFds(); 52 CloseFds()53 void CloseFds() { backing_store_fd_ = {}; } 54 55 bool ReadAheadIOStart(); 56 int PrepareNextReadAhead(uint64_t* source_offset, int* pending_ops, 57 std::vector<uint64_t>& blocks, 58 std::vector<const CowOperation*>& xor_op_vec); 59 bool ReconstructDataFromCow(); 60 void CheckOverlap(const CowOperation* cow_op); 61 62 bool ReadAheadAsyncIO(); 63 bool ReapIoCompletions(int pending_ios_to_complete); 64 bool ReadXorData(size_t block_index, size_t xor_op_index, 65 std::vector<const CowOperation*>& xor_op_vec); 66 void ProcessXorData(size_t& block_xor_index, size_t& xor_index, 67 std::vector<const CowOperation*>& xor_op_vec, void* buffer, 68 loff_t& buffer_offset); 69 void UpdateScratchMetadata(); 70 71 bool ReadAheadSyncIO(); 72 bool InitializeIouring(); 73 void FinalizeIouring(); 74 75 void* read_ahead_buffer_; 76 void* metadata_buffer_; 77 78 std::unique_ptr<ICowOpIter> cowop_iter_; 79 80 std::string cow_device_; 81 std::string backing_store_device_; 82 std::string misc_name_; 83 84 android::base::unique_fd cow_fd_; 85 android::base::unique_fd backing_store_fd_; 86 87 std::shared_ptr<SnapshotHandler> snapuserd_; 88 std::unique_ptr<CowReader> reader_; 89 CowHeader header_; 90 91 std::unordered_set<uint64_t> dest_blocks_; 92 std::unordered_set<uint64_t> source_blocks_; 93 bool overlap_; 94 std::vector<uint64_t> blocks_; 95 int total_blocks_merged_ = 0; 96 std::unique_ptr<uint8_t[]> ra_temp_buffer_; 97 std::unique_ptr<uint8_t[]> ra_temp_meta_buffer_; 98 BufferSink bufsink_; 99 100 uint64_t total_ra_blocks_completed_ = 0; 101 bool read_ahead_async_ = false; 102 // Queue depth of 8 seems optimal. We don't want 103 // to have a huge depth as it may put more memory pressure 104 // on the kernel worker threads given that we use 105 // IOSQE_ASYNC flag - ASYNC flags can potentially 106 // result in EINTR; Since we don't restart 107 // syscalls and fallback to synchronous I/O, we 108 // don't want huge queue depth 109 int queue_depth_ = 8; 110 uint32_t cow_op_merge_size_; 111 std::unique_ptr<struct io_uring> ring_; 112 }; 113 114 } // namespace snapshot 115 } // namespace android 116