// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab #ifndef CEPH_LIBRBD_CACHE_REPLICATED_WRITE_LOG #define CEPH_LIBRBD_CACHE_REPLICATED_WRITE_LOG #include #include #include #include "common/Timer.h" #include "common/RWLock.h" #include "common/WorkQueue.h" #include "common/AsyncOpTracker.h" #include "librbd/cache/ImageWriteback.h" #include "librbd/Utils.h" #include "librbd/BlockGuard.h" #include "librbd/cache/Types.h" #include "librbd/cache/pwl/AbstractWriteLog.h" #include "librbd/cache/pwl/LogMap.h" #include "librbd/cache/pwl/LogOperation.h" #include "librbd/cache/pwl/Request.h" #include "librbd/cache/pwl/rwl/Builder.h" class Context; namespace librbd { struct ImageCtx; namespace cache { namespace pwl { namespace rwl { template class WriteLog : public AbstractWriteLog { public: WriteLog( ImageCtxT &image_ctx, librbd::cache::pwl::ImageCacheState* cache_state, ImageWritebackInterface& image_writeback, plugin::Api& plugin_api); ~WriteLog(); WriteLog(const WriteLog&) = delete; WriteLog &operator=(const WriteLog&) = delete; typedef io::Extent Extent; using This = AbstractWriteLog; using C_WriteRequestT = pwl::C_WriteRequest; using C_WriteSameRequestT = pwl::C_WriteSameRequest; void copy_bl_to_buffer( WriteRequestResources *resources, std::unique_ptr &op_set) override; void complete_user_request(Context *&user_req, int r) override; private: using C_BlockIORequestT = pwl::C_BlockIORequest; using C_FlushRequestT = pwl::C_FlushRequest; using C_DiscardRequestT = pwl::C_DiscardRequest; PMEMobjpool *m_log_pool = nullptr; Builder *m_builderobj; const char* m_pwl_pool_layout_name; const uint64_t MAX_EXTENT_SIZE = 1048576; Builder* create_builder(); void remove_pool_file(); void load_existing_entries(pwl::DeferredContexts &later); void alloc_op_log_entries(pwl::GenericLogOperations &ops); int append_op_log_entries(pwl::GenericLogOperations &ops); void flush_then_append_scheduled_ops(void); void enlist_op_flusher(); void flush_op_log_entries(pwl::GenericLogOperationsVector &ops); template void flush_pmem_buffer(V& ops); void inc_allocated_cached_bytes( std::shared_ptr log_entry) override; protected: using AbstractWriteLog::m_lock; using AbstractWriteLog::m_log_entries; using AbstractWriteLog::m_image_ctx; using AbstractWriteLog::m_perfcounter; using AbstractWriteLog::m_ops_to_flush; using AbstractWriteLog::m_cache_state; using AbstractWriteLog::m_first_free_entry; using AbstractWriteLog::m_first_valid_entry; void process_work() override; void schedule_append_ops(pwl::GenericLogOperations &ops, C_BlockIORequestT *req) override; void append_scheduled_ops(void) override; void reserve_cache(C_BlockIORequestT *req, bool &alloc_succeeds, bool &no_space) override; void collect_read_extents( uint64_t read_buffer_offset, LogMapEntry map_entry, std::vector> &log_entries_to_read, std::vector &bls_to_read, uint64_t entry_hit_length, Extent hit_extent, pwl::C_ReadRequest *read_ctx) override; void complete_read( std::vector> &log_entries_to_read, std::vector &bls_to_read, Context *ctx) override; bool retire_entries(const unsigned long int frees_per_tx) override; void persist_last_flushed_sync_gen() override; bool alloc_resources(C_BlockIORequestT *req) override; void schedule_flush_and_append(pwl::GenericLogOperationsVector &ops) override; void setup_schedule_append( pwl::GenericLogOperationsVector &ops, bool do_early_flush, C_BlockIORequestT *req) override; void construct_flush_entries(pwl::GenericLogEntries entries_to_flush, DeferredContexts &post_unlock, bool has_write_entry) override; bool initialize_pool(Context *on_finish, pwl::DeferredContexts &later) override; void write_data_to_buffer( std::shared_ptr ws_entry, pwl::WriteLogCacheEntry *pmem_entry) override; uint64_t get_max_extent() override { return MAX_EXTENT_SIZE; } }; } // namespace rwl } // namespace pwl } // namespace cache } // namespace librbd extern template class librbd::cache::pwl::rwl::WriteLog; #endif // CEPH_LIBRBD_CACHE_REPLICATED_WRITE_LOG