From 19fcec84d8d7d21e796c7624e521b60d28ee21ed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:45:59 +0200 Subject: Adding upstream version 16.2.11+ds. Signed-off-by: Daniel Baumann --- src/librbd/plugin/Api.cc | 92 ++++++++++++++++++++++++++++ src/librbd/plugin/Api.h | 84 ++++++++++++++++++++++++++ src/librbd/plugin/ParentCache.cc | 81 +++++++++++++++++++++++++ src/librbd/plugin/ParentCache.h | 38 ++++++++++++ src/librbd/plugin/Types.h | 45 ++++++++++++++ src/librbd/plugin/WriteLogImageCache.cc | 104 ++++++++++++++++++++++++++++++++ src/librbd/plugin/WriteLogImageCache.h | 53 ++++++++++++++++ 7 files changed, 497 insertions(+) create mode 100644 src/librbd/plugin/Api.cc create mode 100644 src/librbd/plugin/Api.h create mode 100644 src/librbd/plugin/ParentCache.cc create mode 100644 src/librbd/plugin/ParentCache.h create mode 100644 src/librbd/plugin/Types.h create mode 100644 src/librbd/plugin/WriteLogImageCache.cc create mode 100644 src/librbd/plugin/WriteLogImageCache.h (limited to 'src/librbd/plugin') diff --git a/src/librbd/plugin/Api.cc b/src/librbd/plugin/Api.cc new file mode 100644 index 000000000..67303be3f --- /dev/null +++ b/src/librbd/plugin/Api.cc @@ -0,0 +1,92 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "common/Timer.h" +#include "librbd/plugin/Api.h" +#include "librbd/ImageCtx.h" +#include "librbd/io/AioCompletion.h" +#include "librbd/io/Utils.h" +#include "librbd/Operations.h" +#include "librbd/Utils.h" + +namespace librbd { +namespace plugin { + +template +void Api::read_parent( + I *image_ctx, uint64_t object_no, io::ReadExtents* extents, + librados::snap_t snap_id, const ZTracer::Trace &trace, + Context* on_finish) { + io::util::read_parent(image_ctx, object_no, extents, snap_id, trace, + on_finish); +} + +template +void Api::execute_image_metadata_set( + I *image_ctx, const std::string &key, + const std::string &value, Context *on_finish) { + ImageCtx* ictx = util::get_image_ctx(image_ctx); + ictx->operations->execute_metadata_set(key, value, on_finish); +} + +template +void Api::execute_image_metadata_remove( + I *image_ctx, const std::string &key, Context *on_finish) { + ImageCtx* ictx = util::get_image_ctx(image_ctx); + ictx->operations->execute_metadata_remove(key, on_finish); +} + +template +void Api::get_image_timer_instance( + CephContext *cct, SafeTimer **timer, ceph::mutex **timer_lock) { + ImageCtx::get_timer_instance(cct, timer, timer_lock); +} + +template +bool Api::test_image_features(I *image_ctx, uint64_t features) { + return image_ctx->test_features(features); +} + +template +void Api::update_aio_comp(io::AioCompletion* aio_comp, + uint32_t request_count, + io::ReadResult &read_result, + io::Extents &image_extents) { + aio_comp->set_request_count(request_count); + aio_comp->read_result = std::move(read_result); + aio_comp->read_result.set_image_extents(image_extents); + start_in_flight_io(aio_comp); +} + +template +void Api::update_aio_comp( + io::AioCompletion* aio_comp, uint32_t request_count) { + aio_comp->set_request_count(request_count); + start_in_flight_io(aio_comp); +} + +template +io::ReadResult::C_ImageReadRequest* Api::create_image_read_request( + io::AioCompletion* aio_comp, uint64_t buffer_offset, + const Extents& image_extents) { + return new io::ReadResult::C_ImageReadRequest( + aio_comp, buffer_offset, image_extents); +} + +template +io::C_AioRequest* Api::create_aio_request(io::AioCompletion* aio_comp) { + io::C_AioRequest *req_comp = new io::C_AioRequest(aio_comp); + return req_comp; +} + +template +void Api::start_in_flight_io(io::AioCompletion* aio_comp) { + if (!aio_comp->async_op.started()) { + aio_comp->start_op(); + } +} + +} // namespace plugin +} // namespace librbd + +template class librbd::plugin::Api; diff --git a/src/librbd/plugin/Api.h b/src/librbd/plugin/Api.h new file mode 100644 index 000000000..04f77e5c3 --- /dev/null +++ b/src/librbd/plugin/Api.h @@ -0,0 +1,84 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_PLUGIN_API_H +#define CEPH_LIBRBD_PLUGIN_API_H + +#include "common/Timer.h" +#include "common/ceph_mutex.h" +#include "include/common_fwd.h" +#include "include/int_types.h" +#include "include/rados/librados.hpp" +#include "librbd/io/Types.h" +#include "librbd/io/ReadResult.h" + +namespace ZTracer { struct Trace; } + +namespace librbd { + +namespace io { +class AioCompletion; +class C_AioRequest; +} + +struct ImageCtx; + +namespace plugin { + +template +struct Api { + using Extents = librbd::io::Extents; + + Api() {} + virtual ~Api() {} + + virtual void read_parent( + ImageCtxT *image_ctx, uint64_t object_no, io::ReadExtents* extents, + librados::snap_t snap_id, const ZTracer::Trace &trace, + Context* on_finish); + + virtual void execute_image_metadata_set( + ImageCtxT *image_ctx, + const std::string &key, + const std::string &value, + Context *on_finish); + + virtual void execute_image_metadata_remove( + ImageCtxT *image_ctx, + const std::string &key, + Context *on_finish); + + virtual void get_image_timer_instance( + CephContext *cct, SafeTimer **timer, + ceph::mutex **timer_lock); + + virtual bool test_image_features( + ImageCtxT *image_ctx, + uint64_t features); + + virtual void update_aio_comp( + io::AioCompletion* aio_comp, + uint32_t request_count, + io::ReadResult& read_result, + io::Extents &image_extents); + + virtual void update_aio_comp( + io::AioCompletion* aio_comp, + uint32_t request_count); + + virtual io::ReadResult::C_ImageReadRequest* create_image_read_request( + io::AioCompletion* aio_comp, uint64_t buffer_offset, + const Extents& image_extents); + + virtual io::C_AioRequest* create_aio_request(io::AioCompletion* aio_comp); + +private: + void start_in_flight_io(io::AioCompletion* aio_comp); +}; + +} // namespace plugin +} // namespace librbd + +extern template class librbd::plugin::Api; + +#endif // CEPH_LIBRBD_PLUGIN_API_H diff --git a/src/librbd/plugin/ParentCache.cc b/src/librbd/plugin/ParentCache.cc new file mode 100644 index 000000000..3eba430ab --- /dev/null +++ b/src/librbd/plugin/ParentCache.cc @@ -0,0 +1,81 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "librbd/plugin/ParentCache.h" +#include "ceph_ver.h" +#include "common/dout.h" +#include "common/errno.h" +#include "common/PluginRegistry.h" +#include "librbd/ImageCtx.h" +#include "librbd/cache/ParentCacheObjectDispatch.h" + +extern "C" { + +const char *__ceph_plugin_version() { + return CEPH_GIT_NICE_VER; +} + +int __ceph_plugin_init(CephContext *cct, const std::string& type, + const std::string& name) { + auto plugin_registry = cct->get_plugin_registry(); + return plugin_registry->add( + type, name, new librbd::plugin::ParentCache(cct)); +} + +} // extern "C" + +#define dout_subsys ceph_subsys_rbd +#undef dout_prefix +#define dout_prefix *_dout << "librbd::plugin::ParentCache: " \ + << this << " " << __func__ << ": " + +namespace librbd { +namespace plugin { + +template +void ParentCache::init(I* image_ctx, Api& api, + cache::ImageWritebackInterface& image_writeback, + PluginHookPoints& hook_points_list, + Context* on_finish) { + bool parent_cache_enabled = image_ctx->config.template get_val( + "rbd_parent_cache_enabled"); + if (image_ctx->child == nullptr || !parent_cache_enabled || + !image_ctx->data_ctx.is_valid()) { + on_finish->complete(0); + return; + } + + auto cct = image_ctx->cct; + ldout(cct, 5) << dendl; + + auto parent_cache = cache::ParentCacheObjectDispatch::create( + image_ctx, api); + on_finish = new LambdaContext([this, on_finish, parent_cache](int r) { + if (r < 0) { + // the object dispatcher will handle cleanup if successfully initialized + delete parent_cache; + } + + handle_init_parent_cache(r, on_finish); + }); + parent_cache->init(on_finish); +} + +template +void ParentCache::handle_init_parent_cache(int r, Context* on_finish) { + ldout(cct, 5) << "r=" << r << dendl; + + if (r < 0) { + lderr(cct) << "Failed to initialize parent cache object dispatch layer: " + << cpp_strerror(r) << dendl; + on_finish->complete(r); + return; + } + + on_finish->complete(0); +} + +} // namespace plugin +} // namespace librbd + +template class librbd::plugin::ParentCache; diff --git a/src/librbd/plugin/ParentCache.h b/src/librbd/plugin/ParentCache.h new file mode 100644 index 000000000..1039efff9 --- /dev/null +++ b/src/librbd/plugin/ParentCache.h @@ -0,0 +1,38 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_PLUGIN_PARENT_CACHE_H +#define CEPH_LIBRBD_PLUGIN_PARENT_CACHE_H + +#include "librbd/plugin/Types.h" +#include "include/Context.h" + +namespace librbd { + +struct ImageCtx; + +namespace plugin { + +template +class ParentCache : public Interface { +public: + ParentCache(CephContext* cct) : Interface(cct) { + } + + void init(ImageCtxT* image_ctx, Api& api, + cache::ImageWritebackInterface& image_writeback, + PluginHookPoints& hook_points_list, + Context* on_finish) override; + +private: + void handle_init_parent_cache(int r, Context* on_finish); + using ceph::Plugin::cct; + +}; + +} // namespace plugin +} // namespace librbd + +extern template class librbd::plugin::ParentCache; + +#endif // CEPH_LIBRBD_PLUGIN_PARENT_CACHE_H diff --git a/src/librbd/plugin/Types.h b/src/librbd/plugin/Types.h new file mode 100644 index 000000000..b66d754ac --- /dev/null +++ b/src/librbd/plugin/Types.h @@ -0,0 +1,45 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_PLUGIN_TYPES_H +#define CEPH_LIBRBD_PLUGIN_TYPES_H + +#include "include/common_fwd.h" +#include "include/Context.h" +#include "common/PluginRegistry.h" +#include "librbd/cache/ImageWriteback.h" + +namespace librbd { +namespace plugin { + +template struct Api; + +struct HookPoints { + virtual ~HookPoints() { + } + virtual void acquired_exclusive_lock(Context* on_finish) = 0; + virtual void prerelease_exclusive_lock(Context* on_finish) = 0; + virtual void discard(Context* on_finish) { + on_finish->complete(0); + } +}; + +typedef std::list> PluginHookPoints; + +template +struct Interface : public ceph::Plugin { + Interface(CephContext* cct) : Plugin(cct) { + } + + virtual ~Interface() { + } + + virtual void init(ImageCtxT* image_ctx, Api& api, + librbd::cache::ImageWritebackInterface& image_writeback, + PluginHookPoints& hook_points_list, Context* on_finish) = 0; +}; + +} // namespace plugin +} // namespace librbd + +#endif // CEPH_LIBRBD_PLUGIN_TYPES_H diff --git a/src/librbd/plugin/WriteLogImageCache.cc b/src/librbd/plugin/WriteLogImageCache.cc new file mode 100644 index 000000000..308bb6a00 --- /dev/null +++ b/src/librbd/plugin/WriteLogImageCache.cc @@ -0,0 +1,104 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "ceph_ver.h" +#include "common/dout.h" +#include "common/errno.h" +#include "common/PluginRegistry.h" +#include "librbd/ImageCtx.h" +#include "librbd/cache/WriteLogImageDispatch.h" +#include "librbd/cache/ImageWriteback.h" +#include "librbd/cache/Utils.h" +#include "librbd/cache/pwl/DiscardRequest.h" +#include "librbd/cache/pwl/InitRequest.h" +#include "librbd/io/ImageDispatcherInterface.h" +#include "librbd/plugin/WriteLogImageCache.h" + +extern "C" { + +const char *__ceph_plugin_version() { + return CEPH_GIT_NICE_VER; +} + +int __ceph_plugin_init(CephContext *cct, const std::string& type, + const std::string& name) { + auto plugin_registry = cct->get_plugin_registry(); + return plugin_registry->add( + type, name, new librbd::plugin::WriteLogImageCache(cct)); +} + +} // extern "C" + +#define dout_subsys ceph_subsys_rbd +#undef dout_prefix +#define dout_prefix *_dout << "librbd::plugin::WriteLogImageCache: " \ + << this << " " << __func__ << ": " + +namespace librbd { +namespace plugin { + +template +void WriteLogImageCache::init(I* image_ctx, Api& api, + cache::ImageWritebackInterface& image_writeback, + PluginHookPoints& hook_points_list, + Context* on_finish) { + bool pwl_enabled = librbd::cache::util::is_pwl_enabled(*image_ctx); + if (!pwl_enabled || !image_ctx->data_ctx.is_valid()) { + on_finish->complete(0); + return; + } + + auto cct = image_ctx->cct; + ldout(cct, 5) << dendl; + + auto hook_points = std::make_unique( + image_ctx, image_writeback, api); + hook_points_list.emplace_back(std::move(hook_points)); + + on_finish->complete(0); +} + +template +WriteLogImageCache::~WriteLogImageCache() { +} + +template +WriteLogImageCache::HookPoints::HookPoints( + I* image_ctx, cache::ImageWritebackInterface& image_writeback, + plugin::Api& plugin_api) + : m_image_ctx(image_ctx), m_image_writeback(image_writeback), + m_plugin_api(plugin_api) +{ +} + +template +WriteLogImageCache::HookPoints::~HookPoints() { +} + +template +void WriteLogImageCache::HookPoints::acquired_exclusive_lock( + Context* on_finish) { + cache::pwl::InitRequest *req = cache::pwl::InitRequest::create( + *m_image_ctx, m_image_writeback, m_plugin_api, on_finish); + req->send(); +} + +template +void WriteLogImageCache::HookPoints::prerelease_exclusive_lock( + Context* on_finish) { + m_image_ctx->io_image_dispatcher->shut_down_dispatch( + io::IMAGE_DISPATCH_LAYER_WRITEBACK_CACHE, on_finish); +} + +template +void WriteLogImageCache::HookPoints::discard( + Context* on_finish) { + cache::pwl::DiscardRequest *req = cache::pwl::DiscardRequest::create( + *m_image_ctx, m_plugin_api, on_finish); + req->send(); +} + +} // namespace plugin +} // namespace librbd + +template class librbd::plugin::WriteLogImageCache; diff --git a/src/librbd/plugin/WriteLogImageCache.h b/src/librbd/plugin/WriteLogImageCache.h new file mode 100644 index 000000000..2ceb87ec6 --- /dev/null +++ b/src/librbd/plugin/WriteLogImageCache.h @@ -0,0 +1,53 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_PLUGIN_WRITELOG_IMAGE_CACHE_H +#define CEPH_LIBRBD_PLUGIN_WRITELOG_IMAGE_CACHE_H + +#include "librbd/plugin/Types.h" +#include "include/Context.h" + +namespace librbd { + +struct ImageCtx; + +namespace plugin { + +template +class WriteLogImageCache : public Interface { +public: + WriteLogImageCache(CephContext* cct) : Interface(cct) { + } + + ~WriteLogImageCache() override; + + void init(ImageCtxT* image_ctx, Api& api, + cache::ImageWritebackInterface& image_writeback, + PluginHookPoints& hook_points_list, + Context* on_finish) override; + + class HookPoints : public plugin::HookPoints { + public: + HookPoints(ImageCtxT* image_ctx, + cache::ImageWritebackInterface& image_writeback, + plugin::Api& plugin_api); + ~HookPoints() override; + + void acquired_exclusive_lock(Context* on_finish) override; + void prerelease_exclusive_lock(Context* on_finish) override; + void discard(Context* on_finish) override; + + private: + ImageCtxT* m_image_ctx; + cache::ImageWritebackInterface& m_image_writeback; + plugin::Api& m_plugin_api; + }; + +}; + +} // namespace plugin +} // namespace librbd + +extern template class librbd::plugin::WriteLogImageCache; + +#endif // CEPH_LIBRBD_PLUGIN_WRITELOG_IMAGE_CACHE_H -- cgit v1.2.3