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 <future> 18 #include "writer_base.h" 19 20 namespace android { 21 namespace snapshot { 22 23 class CowWriterV2 : public CowWriterBase { 24 public: 25 explicit CowWriterV2(const CowOptions& options, android::base::unique_fd&& fd); 26 ~CowWriterV2() override; 27 28 bool Initialize(std::optional<uint64_t> label = {}) override; 29 bool Finalize() override; 30 CowSizeInfo GetCowSizeInfo() const override; 31 32 protected: 33 virtual bool EmitCopy(uint64_t new_block, uint64_t old_block, uint64_t num_blocks = 1) override; 34 virtual bool EmitRawBlocks(uint64_t new_block_start, const void* data, size_t size) override; 35 virtual bool EmitXorBlocks(uint32_t new_block_start, const void* data, size_t size, 36 uint32_t old_block, uint16_t offset) override; 37 virtual bool EmitZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) override; 38 virtual bool EmitLabel(uint64_t label) override; 39 virtual bool EmitSequenceData(size_t num_ops, const uint32_t* data) override; 40 41 private: 42 bool EmitCluster(); 43 bool EmitClusterIfNeeded(); 44 bool EmitBlocks(uint64_t new_block_start, const void* data, size_t size, uint64_t old_block, 45 uint16_t offset, CowOperationType type); 46 void SetupHeaders(); 47 void SetupWriteOptions(); 48 bool ParseOptions(); 49 bool OpenForWrite(); 50 bool OpenForAppend(uint64_t label); 51 bool GetDataPos(uint64_t* pos); 52 bool WriteRawData(const void* data, size_t size); 53 bool WriteOperation(const CowOperationV2& op, const void* data = nullptr, size_t size = 0); 54 void AddOperation(const CowOperationV2& op); 55 void InitPos(); 56 void InitBatchWrites(); 57 void InitWorkers(); 58 bool FlushCluster(); 59 60 bool CompressBlocks(size_t num_blocks, const void* data); 61 bool Truncate(off_t length); 62 bool EnsureSpaceAvailable(const uint64_t bytes_needed) const; 63 64 private: 65 CowFooter footer_{}; 66 CowHeader header_{}; 67 CowCompression compression_; 68 // in the case that we are using one thread for compression, we can store and re-use the same 69 // compressor 70 std::unique_ptr<ICompressor> compressor_; 71 uint64_t current_op_pos_ = 0; 72 uint64_t next_op_pos_ = 0; 73 uint64_t next_data_pos_ = 0; 74 uint64_t current_data_pos_ = 0; 75 ssize_t total_data_written_ = 0; 76 uint32_t cluster_size_ = 0; 77 uint32_t current_cluster_size_ = 0; 78 uint64_t current_data_size_ = 0; 79 bool merge_in_progress_ = false; 80 81 int num_compress_threads_ = 1; 82 std::vector<std::unique_ptr<CompressWorker>> compress_threads_; 83 std::vector<std::future<bool>> threads_; 84 std::vector<std::vector<uint8_t>> compressed_buf_; 85 std::vector<std::vector<uint8_t>>::iterator buf_iter_; 86 87 std::vector<std::unique_ptr<CowOperationV2>> opbuffer_vec_; 88 std::vector<std::unique_ptr<uint8_t[]>> databuffer_vec_; 89 std::unique_ptr<struct iovec[]> cowop_vec_; 90 int op_vec_index_ = 0; 91 92 std::unique_ptr<struct iovec[]> data_vec_; 93 int data_vec_index_ = 0; 94 bool batch_write_ = false; 95 }; 96 97 } // namespace snapshot 98 } // namespace android 99