diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.h b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.h index 777aa0705..79a5bc952 100644 --- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.h +++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.h @@ -46,6 +46,7 @@ #include #include #include +#include "snapuserd_readahead.h" namespace android { namespace snapshot { @@ -96,82 +97,6 @@ struct MergeGroupState { : merge_state_(state), num_ios_in_progress(n_ios) {} }; -class ReadAhead { - public: - ReadAhead(const std::string& cow_device, const std::string& backing_device, - const std::string& misc_name, std::shared_ptr snapuserd); - bool RunThread(); - - private: - void InitializeRAIter(); - bool RAIterDone(); - void RAIterNext(); - void RAResetIter(uint64_t num_blocks); - const CowOperation* GetRAOpIter(); - - void InitializeBuffer(); - bool InitReader(); - bool InitializeFds(); - - void CloseFds() { backing_store_fd_ = {}; } - - bool ReadAheadIOStart(); - int PrepareNextReadAhead(uint64_t* source_offset, int* pending_ops, - std::vector& blocks, - std::vector& xor_op_vec); - bool ReconstructDataFromCow(); - void CheckOverlap(const CowOperation* cow_op); - - bool ReadAheadAsyncIO(); - bool ReapIoCompletions(int pending_ios_to_complete); - bool ReadXorData(size_t block_index, size_t xor_op_index, - std::vector& xor_op_vec); - void ProcessXorData(size_t& block_xor_index, size_t& xor_index, - std::vector& xor_op_vec, void* buffer, - loff_t& buffer_offset); - void UpdateScratchMetadata(); - - bool ReadAheadSyncIO(); - bool InitializeIouring(); - void FinalizeIouring(); - - void* read_ahead_buffer_; - void* metadata_buffer_; - - std::unique_ptr cowop_iter_; - - std::string cow_device_; - std::string backing_store_device_; - std::string misc_name_; - - unique_fd cow_fd_; - unique_fd backing_store_fd_; - - std::shared_ptr snapuserd_; - std::unique_ptr reader_; - - std::unordered_set dest_blocks_; - std::unordered_set source_blocks_; - bool overlap_; - std::vector blocks_; - int total_blocks_merged_ = 0; - std::unique_ptr ra_temp_buffer_; - std::unique_ptr ra_temp_meta_buffer_; - BufferSink bufsink_; - - uint64_t total_ra_blocks_completed_ = 0; - bool read_ahead_async_ = false; - // Queue depth of 8 seems optimal. We don't want - // to have a huge depth as it may put more memory pressure - // on the kernel worker threads given that we use - // IOSQE_ASYNC flag - ASYNC flags can potentially - // result in EINTR; Since we don't restart - // syscalls and fallback to synchronous I/O, we - // don't want huge queue depth - int queue_depth_ = 8; - std::unique_ptr ring_; -}; - class UpdateVerify { public: UpdateVerify(const std::string& misc_name); diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp index 17f1f0e27..af2428602 100644 --- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp +++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#include "snapuserd_readahead.h" + #include "snapuserd_core.h" namespace android { diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.h b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.h new file mode 100644 index 000000000..5e94de005 --- /dev/null +++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.h @@ -0,0 +1,112 @@ +// Copyright (C) 2023 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace android { +namespace snapshot { + +class SnapshotHandler; + +class ReadAhead { + public: + ReadAhead(const std::string& cow_device, const std::string& backing_device, + const std::string& misc_name, std::shared_ptr snapuserd); + bool RunThread(); + + private: + void InitializeRAIter(); + bool RAIterDone(); + void RAIterNext(); + void RAResetIter(uint64_t num_blocks); + const CowOperation* GetRAOpIter(); + + void InitializeBuffer(); + bool InitReader(); + bool InitializeFds(); + + void CloseFds() { backing_store_fd_ = {}; } + + bool ReadAheadIOStart(); + int PrepareNextReadAhead(uint64_t* source_offset, int* pending_ops, + std::vector& blocks, + std::vector& xor_op_vec); + bool ReconstructDataFromCow(); + void CheckOverlap(const CowOperation* cow_op); + + bool ReadAheadAsyncIO(); + bool ReapIoCompletions(int pending_ios_to_complete); + bool ReadXorData(size_t block_index, size_t xor_op_index, + std::vector& xor_op_vec); + void ProcessXorData(size_t& block_xor_index, size_t& xor_index, + std::vector& xor_op_vec, void* buffer, + loff_t& buffer_offset); + void UpdateScratchMetadata(); + + bool ReadAheadSyncIO(); + bool InitializeIouring(); + void FinalizeIouring(); + + void* read_ahead_buffer_; + void* metadata_buffer_; + + std::unique_ptr cowop_iter_; + + std::string cow_device_; + std::string backing_store_device_; + std::string misc_name_; + + android::base::unique_fd cow_fd_; + android::base::unique_fd backing_store_fd_; + + std::shared_ptr snapuserd_; + std::unique_ptr reader_; + + std::unordered_set dest_blocks_; + std::unordered_set source_blocks_; + bool overlap_; + std::vector blocks_; + int total_blocks_merged_ = 0; + std::unique_ptr ra_temp_buffer_; + std::unique_ptr ra_temp_meta_buffer_; + BufferSink bufsink_; + + uint64_t total_ra_blocks_completed_ = 0; + bool read_ahead_async_ = false; + // Queue depth of 8 seems optimal. We don't want + // to have a huge depth as it may put more memory pressure + // on the kernel worker threads given that we use + // IOSQE_ASYNC flag - ASYNC flags can potentially + // result in EINTR; Since we don't restart + // syscalls and fallback to synchronous I/O, we + // don't want huge queue depth + int queue_depth_ = 8; + std::unique_ptr ring_; +}; + +} // namespace snapshot +} // namespace android