watcher/Types.cc
WatchNotifyTypes.cc)
-if(WITH_RBD_RWL OR WITH_RBD_SSD_CACHE)
- list(APPEND librbd_types_srcs cache/pwl/Types.cc)
-endif()
-
add_library(rbd_types STATIC
${librbd_types_srcs})
cache/ImageWriteback.cc
cache/ObjectCacherObjectDispatch.cc
cache/ObjectCacherWriteback.cc
- cache/pwl/DiscardRequest.cc
- cache/pwl/InitRequest.cc
- cache/pwl/ShutdownRequest.cc
- cache/Utils.cc
cache/WriteAroundObjectDispatch.cc
crypto/BlockCrypto.cc
crypto/CryptoContextPool.cc
crypto/luks/LoadRequest.cc)
endif()
-if(WITH_RBD_RWL OR WITH_RBD_SSD_CACHE)
- set(librbd_internal_srcs
- ${librbd_internal_srcs}
- cache/pwl/ImageCacheState.cc
- cache/pwl/LogEntry.cc
- cache/pwl/LogMap.cc
- cache/pwl/LogOperation.cc
- cache/pwl/ReadRequest.cc
- cache/pwl/Request.cc
- cache/pwl/SyncPoint.cc
- cache/pwl/AbstractWriteLog.cc
- cache/WriteLogImageDispatch.cc)
- if(WITH_RBD_RWL)
- set(librbd_internal_srcs
- ${librbd_internal_srcs}
- cache/pwl/ReplicatedWriteLog.cc)
- endif()
- if(WITH_RBD_SSD_CACHE)
- set(librbd_internal_srcs
- ${librbd_internal_srcs}
- cache/pwl/SSDWriteLog.cc)
- endif()
-endif()
-
add_library(rbd_api STATIC librbd.cc)
add_library(rbd_internal STATIC
${librbd_internal_srcs}
target_link_libraries(rbd_internal PRIVATE ${LIBCRYPTSETUP_LIBRARIES})
endif()
-if(WITH_RBD_RWL OR WITH_RBD_SSD_CACHE)
- target_link_libraries(rbd_internal
- PUBLIC blk)
- target_link_libraries(rbd_internal PRIVATE
- StdFilesystem::filesystem)
-endif()
-if(WITH_RBD_RWL)
- target_link_libraries(rbd_types
- PUBLIC blk)
-endif()
add_custom_target(librbd_plugins)
set(librbd_plugins_dir ${CEPH_INSTALL_PKGLIBDIR}/librbd)
install(TARGETS librbd_plugin_parent_cache DESTINATION ${librbd_plugins_dir})
add_dependencies(librbd_plugins librbd_plugin_parent_cache)
+if(WITH_RBD_RWL OR WITH_RBD_SSD_CACHE)
+ set(rbd_plugin_pwl_srcs
+ cache/WriteLogImageDispatch.cc
+ cache/pwl/AbstractWriteLog.cc
+ cache/pwl/DiscardRequest.cc
+ cache/pwl/ImageCacheState.cc
+ cache/pwl/InitRequest.cc
+ cache/pwl/LogEntry.cc
+ cache/pwl/LogMap.cc
+ cache/pwl/LogOperation.cc
+ cache/pwl/ReadRequest.cc
+ cache/pwl/Request.cc
+ cache/pwl/ShutdownRequest.cc
+ cache/pwl/SyncPoint.cc
+ cache/pwl/Types.cc
+ plugin/WriteLogImageCache.cc)
+
+ if(WITH_RBD_SSD_CACHE)
+ set(rbd_plugin_pwl_srcs
+ ${rbd_plugin_pwl_srcs}
+ cache/pwl/SSDWriteLog.cc)
+ endif()
+ if(WITH_RBD_RWL)
+ set(rbd_plugin_pwl_srcs
+ ${rbd_plugin_pwl_srcs}
+ cache/pwl/ReplicatedWriteLog.cc)
+ endif()
+
+ add_library(librbd_plugin_pwl_cache SHARED
+ ${rbd_plugin_pwl_srcs})
+ target_link_libraries(librbd_plugin_pwl_cache PRIVATE
+ blk
+ ceph-common
+ cls_rbd_client
+ StdFilesystem::filesystem)
+
+ if(WITH_RBD_RWL)
+ target_link_libraries(librbd_plugin_pwl_cache
+ PUBLIC pmem::pmemobj
+ PRIVATE pmem::pmem)
+ endif()
+
+ set_target_properties(librbd_plugin_pwl_cache PROPERTIES
+ OUTPUT_NAME ceph_librbd_pwl_cache
+ VERSION 1.0.0
+ SOVERSION 1)
+ install(TARGETS librbd_plugin_pwl_cache DESTINATION ${librbd_plugins_dir})
+ add_dependencies(librbd_plugins librbd_plugin_pwl_cache)
+endif()
+
add_library(librbd ${CEPH_SHARED}
librbd.cc)
if(WITH_LTTNG)
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-
-#include "librbd/cache/pwl/DiscardRequest.h"
-#include "librbd/cache/Utils.h"
-#include "include/Context.h"
-
-namespace librbd {
-namespace cache {
-namespace util {
-
-template <typename I>
-void discard_cache(I &image_ctx, Context *ctx) {
- cache::pwl::DiscardRequest<I> *req = cache::pwl::DiscardRequest<I>::create(
- image_ctx, ctx);
- req->send();
-}
-
-} // namespace util
-} // namespace cache
-} // namespace librbd
-
-template void librbd::cache::util::discard_cache(
- librbd::ImageCtx &image_ctx, Context *ctx);
#endif // WITH_RBD_RWL
}
-template <typename T = librbd::ImageCtx>
-void discard_cache(T &image_ctx, Context *ctx);
-
} // namespace util
} // namespace cache
} // namespace librbd
namespace librbd {
namespace cache {
-namespace {
-
-void start_in_flight_io(io::AioCompletion* aio_comp) {
- if (!aio_comp->async_op.started()) {
- aio_comp->start_op();
- }
-}
-
-} // anonymous namespace
-
template <typename I>
void WriteLogImageDispatch<I>::shut_down(Context* on_finish) {
ceph_assert(m_image_cache != nullptr);
});
cache::pwl::ShutdownRequest<I> *req = cache::pwl::ShutdownRequest<I>::create(
- *m_image_ctx, m_image_cache, ctx);
+ *m_image_ctx, m_image_cache, m_plugin_api, ctx);
req->send();
}
return true;
}
- start_in_flight_io(aio_comp);
-
- aio_comp->set_request_count(1);
- aio_comp->read_result = std::move(read_result);
- aio_comp->read_result.set_image_extents(image_extents);
+ m_plugin_api.update_aio_comp(aio_comp, 1, read_result, image_extents);
- auto *req_comp = new io::ReadResult::C_ImageReadRequest(
- aio_comp, 0, image_extents);
+ auto *req_comp = m_plugin_api.create_image_read_request(aio_comp, 0, image_extents);
m_image_cache->read(std::move(image_extents),
&req_comp->bl, op_flags,
return true;
}
- start_in_flight_io(aio_comp);
-
- aio_comp->set_request_count(1);
- io::C_AioRequest *req_comp = new io::C_AioRequest(aio_comp);
+ m_plugin_api.update_aio_comp(aio_comp, 1);
+ io::C_AioRequest *req_comp = m_plugin_api.create_aio_request(aio_comp);
m_image_cache->write(std::move(image_extents),
std::move(bl), op_flags, req_comp);
return true;
return true;
}
- start_in_flight_io(aio_comp);
-
- aio_comp->set_request_count(image_extents.size());
+ m_plugin_api.update_aio_comp(aio_comp, image_extents.size());
for (auto &extent : image_extents) {
- io::C_AioRequest *req_comp = new io::C_AioRequest(aio_comp);
+ io::C_AioRequest *req_comp = m_plugin_api.create_aio_request(aio_comp);
m_image_cache->discard(extent.first, extent.second,
discard_granularity_bytes,
req_comp);
return true;
}
- start_in_flight_io(aio_comp);
-
- aio_comp->set_request_count(image_extents.size());
+ m_plugin_api.update_aio_comp(aio_comp, image_extents.size());
for (auto &extent : image_extents) {
- io::C_AioRequest *req_comp = new io::C_AioRequest(aio_comp);
+ io::C_AioRequest *req_comp = m_plugin_api.create_aio_request(aio_comp);
m_image_cache->writesame(extent.first, extent.second,
std::move(bl), op_flags,
req_comp);
return true;
}
- start_in_flight_io(aio_comp);
-
- aio_comp->set_request_count(1);
- io::C_AioRequest *req_comp = new io::C_AioRequest(aio_comp);
+ m_plugin_api.update_aio_comp(aio_comp, 1);
+ io::C_AioRequest *req_comp = m_plugin_api.create_aio_request(aio_comp);
m_image_cache->compare_and_write(
std::move(image_extents), std::move(cmp_bl), std::move(bl),
mismatch_offset, op_flags, req_comp);
auto cct = m_image_ctx->cct;
ldout(cct, 20) << "tid=" << tid << dendl;
- start_in_flight_io(aio_comp);
-
*dispatch_result = io::DISPATCH_RESULT_COMPLETE;
- aio_comp->set_request_count(1);
- io::C_AioRequest *req_comp = new io::C_AioRequest(aio_comp);
+ m_plugin_api.update_aio_comp(aio_comp, 1);
+
+ io::C_AioRequest *req_comp = m_plugin_api.create_aio_request(aio_comp);
m_image_cache->flush(flush_source, req_comp);
return true;
io::AioCompletion* aio_comp, io::Extents &image_extents) const {
auto total_bytes = io::util::get_extents_length(image_extents);
if (total_bytes == 0) {
- aio_comp->set_request_count(0);
+ m_plugin_api.update_aio_comp(aio_comp, 0);
return true;
}
return false;
#include "common/zipkin_trace.h"
#include "librbd/io/ReadResult.h"
#include "librbd/io/Types.h"
+#include "librbd/plugin/Api.h"
struct Context;
class WriteLogImageDispatch : public io::ImageDispatchInterface {
public:
WriteLogImageDispatch(ImageCtxT* image_ctx,
- pwl::AbstractWriteLog<ImageCtx> *image_cache) :
- m_image_ctx(image_ctx), m_image_cache(image_cache) {
+ pwl::AbstractWriteLog<ImageCtx> *image_cache,
+ plugin::Api<ImageCtxT>& plugin_api) :
+ m_image_ctx(image_ctx), m_image_cache(image_cache),
+ m_plugin_api(plugin_api) {
}
io::ImageDispatchLayer get_dispatch_layer() const override {
private:
ImageCtxT* m_image_ctx;
pwl::AbstractWriteLog<ImageCtx> *m_image_cache;
+ plugin::Api<ImageCtxT>& m_plugin_api;
bool preprocess_length(
io::AioCompletion* aio_comp, io::Extents &image_extents) const;
#include "librbd/cache/pwl/ImageCacheState.h"
#include "librbd/cache/pwl/LogEntry.h"
#include "librbd/cache/pwl/ReadRequest.h"
+#include "librbd/plugin/Api.h"
#include <map>
#include <vector>
typedef AbstractWriteLog<ImageCtx>::Extents Extents;
template <typename I>
-AbstractWriteLog<I>::AbstractWriteLog(I &image_ctx, librbd::cache::pwl::ImageCacheState<I>* cache_state)
+AbstractWriteLog<I>::AbstractWriteLog(I &image_ctx, librbd::cache::pwl::ImageCacheState<I>* cache_state,
+ cache::ImageWritebackInterface& image_writeback,
+ plugin::Api<I>& plugin_api)
: m_write_log_guard(image_ctx.cct),
- m_deferred_dispatch_lock(ceph::make_mutex(util::unique_lock_name(
+ m_deferred_dispatch_lock(ceph::make_mutex(pwl::unique_lock_name(
"librbd::cache::pwl::AbstractWriteLog::m_deferred_dispatch_lock", this))),
- m_blockguard_lock(ceph::make_mutex(util::unique_lock_name(
+ m_blockguard_lock(ceph::make_mutex(pwl::unique_lock_name(
"librbd::cache::pwl::AbstractWriteLog::m_blockguard_lock", this))),
m_thread_pool(
image_ctx.cct, "librbd::cache::pwl::AbstractWriteLog::thread_pool", "tp_pwl", 4, ""),
m_cache_state(cache_state),
m_image_ctx(image_ctx),
m_log_pool_config_size(DEFAULT_POOL_SIZE),
- m_image_writeback(image_ctx),
- m_log_retire_lock(ceph::make_mutex(util::unique_lock_name(
+ m_image_writeback(image_writeback),
+ m_plugin_api(plugin_api),
+ m_log_retire_lock(ceph::make_mutex(pwl::unique_lock_name(
"librbd::cache::pwl::AbstractWriteLog::m_log_retire_lock", this))),
m_entry_reader_lock("librbd::cache::pwl::AbstractWriteLog::m_entry_reader_lock"),
- m_log_append_lock(ceph::make_mutex(util::unique_lock_name(
+ m_log_append_lock(ceph::make_mutex(pwl::unique_lock_name(
"librbd::cache::pwl::AbstractWriteLog::m_log_append_lock", this))),
- m_lock(ceph::make_mutex(util::unique_lock_name(
+ m_lock(ceph::make_mutex(pwl::unique_lock_name(
"librbd::cache::pwl::AbstractWriteLog::m_lock", this))),
m_blocks_to_log_entries(image_ctx.cct),
m_work_queue("librbd::cache::pwl::ReplicatedWriteLog::work_queue",
&m_thread_pool)
{
CephContext *cct = m_image_ctx.cct;
- ImageCtx::get_timer_instance(cct, &m_timer, &m_timer_lock);
+ m_plugin_api.get_image_timer_instance(cct, &m_timer, &m_timer_lock);
}
template <typename I>
struct ImageCtx;
+namespace plugin { template <typename> struct Api; }
+
namespace cache {
namespace pwl {
typedef io::Extent Extent;
typedef io::Extents Extents;
- AbstractWriteLog(ImageCtxT &image_ctx, librbd::cache::pwl::ImageCacheState<ImageCtxT>* cache_state);
+ AbstractWriteLog(ImageCtxT &image_ctx, librbd::cache::pwl::ImageCacheState<ImageCtxT>* cache_state,
+ cache::ImageWritebackInterface& image_writeback,
+ plugin::Api<ImageCtxT>& plugin_api);
virtual ~AbstractWriteLog();
AbstractWriteLog(const AbstractWriteLog&) = delete;
AbstractWriteLog &operator=(const AbstractWriteLog&) = delete;
std::atomic<bool> m_alloc_failed_since_retire = {false};
- ImageWriteback<ImageCtxT> m_image_writeback;
+ cache::ImageWritebackInterface& m_image_writeback;
+ plugin::Api<ImageCtxT>& m_plugin_api;
+
/*
* When m_first_free_entry == m_first_valid_entry, the log is
* empty. There is always at least one free entry, which can't be
#include "librbd/asio/ContextWQ.h"
#include "librbd/cache/pwl/DiscardRequest.h"
-#if defined(WITH_RBD_RWL)
#if __has_include(<filesystem>)
#include <filesystem>
namespace fs = std::filesystem;
#endif
#include "librbd/cache/pwl/ImageCacheState.h"
-#endif // WITH_RBD_RWL
#include "librbd/cache/Types.h"
#include "librbd/io/ImageDispatcherInterface.h"
template <typename I>
DiscardRequest<I>* DiscardRequest<I>::create(
I &image_ctx,
+ plugin::Api<I>& plugin_api,
Context *on_finish) {
- return new DiscardRequest(image_ctx, on_finish);
+ return new DiscardRequest(image_ctx, plugin_api, on_finish);
}
template <typename I>
DiscardRequest<I>::DiscardRequest(
I &image_ctx,
+ plugin::Api<I>& plugin_api,
Context *on_finish)
: m_image_ctx(image_ctx),
+ m_plugin_api(plugin_api),
m_on_finish(create_async_context_callback(image_ctx, on_finish)),
m_error_result(0) {
}
template <typename I>
void DiscardRequest<I>::send() {
-#if defined(WITH_RBD_RWL)
delete_image_cache_file();
-#else
- finish();
-#endif
}
-#if defined(WITH_RBD_RWL)
template <typename I>
void DiscardRequest<I>::delete_image_cache_file() {
CephContext *cct = m_image_ctx.cct;
ldout(cct, 10) << dendl;
- m_cache_state = ImageCacheState<I>::get_image_cache_state(&m_image_ctx);
+ m_cache_state = ImageCacheState<I>::get_image_cache_state(&m_image_ctx, m_plugin_api);
if (!m_cache_state) {
remove_feature_bit();
return;
finish();
}
-#endif // WITH_RBD_RWL
-
template <typename I>
void DiscardRequest<I>::finish() {
-#if defined(WITH_RBD_RWL)
if (m_cache_state) {
delete m_cache_state;
m_cache_state = nullptr;
}
-#endif // WITH_RBD_RWL
m_on_finish->complete(m_error_result);
delete this;
namespace librbd {
class ImageCtx;
+namespace plugin { template <typename> struct Api; }
namespace cache {
public:
static DiscardRequest* create(
ImageCtxT &image_ctx,
+ plugin::Api<ImageCtxT>& plugin_api,
Context *on_finish);
void send();
*/
DiscardRequest(ImageCtxT &image_ctx,
+ plugin::Api<ImageCtxT>& plugin_api,
Context *on_finish);
ImageCtxT &m_image_ctx;
ImageCacheState<ImageCtxT>* m_cache_state;
+ plugin::Api<ImageCtxT>& m_plugin_api;
Context *m_on_finish;
int m_error_result;
#include "common/ceph_json.h"
#include "common/environment.h"
#include "common/hostname.h"
+#include "librbd/plugin/Api.h"
#undef dout_subsys
#define dout_subsys ceph_subsys_rbd_pwl
} // namespace
template <typename I>
-ImageCacheState<I>::ImageCacheState(I *image_ctx) : m_image_ctx(image_ctx) {
+ImageCacheState<I>::ImageCacheState(I *image_ctx, plugin::Api<I>& plugin_api) :
+ m_image_ctx(image_ctx), m_plugin_api(plugin_api) {
ldout(image_ctx->cct, 20) << "Initialize RWL cache state with config data. "
<< dendl;
template <typename I>
ImageCacheState<I>::ImageCacheState(
- I *image_ctx, JSONFormattable &f) : m_image_ctx(image_ctx) {
+ I *image_ctx, JSONFormattable &f, plugin::Api<I>& plugin_api) :
+ m_image_ctx(image_ctx), m_plugin_api(plugin_api) {
ldout(image_ctx->cct, 20) << "Initialize RWL cache state with data from "
<< "server side"<< dendl;
ldout(m_image_ctx->cct, 20) << __func__ << " Store state: "
<< image_state_json << dendl;
- m_image_ctx->operations->execute_metadata_set(IMAGE_CACHE_STATE,
- image_state_json, on_finish);
+ m_plugin_api.execute_image_metadata_set(m_image_ctx, IMAGE_CACHE_STATE,
+ image_state_json, on_finish);
}
template <typename I>
void ImageCacheState<I>::clear_image_cache_state(Context *on_finish) {
std::shared_lock owner_lock{m_image_ctx->owner_lock};
ldout(m_image_ctx->cct, 20) << __func__ << " Remove state: " << dendl;
- m_image_ctx->operations->execute_metadata_remove(IMAGE_CACHE_STATE, on_finish);
+ m_plugin_api.execute_image_metadata_remove(
+ m_image_ctx, IMAGE_CACHE_STATE, on_finish);
}
template <typename I>
template <typename I>
ImageCacheState<I>* ImageCacheState<I>::create_image_cache_state(
- I* image_ctx, int &r) {
+ I* image_ctx, plugin::Api<I>& plugin_api, int &r) {
std::string cache_state_str;
ImageCacheState<I>* cache_state = nullptr;
ldout(image_ctx->cct, 20) << "image_cache_state:" << cache_state_str << dendl;
r = 0;
- bool dirty_cache = image_ctx->test_features(RBD_FEATURE_DIRTY_CACHE);
+ bool dirty_cache = plugin_api.test_image_features(image_ctx, RBD_FEATURE_DIRTY_CACHE);
if (dirty_cache) {
cls_client::metadata_get(&image_ctx->md_ctx, image_ctx->header_oid,
IMAGE_CACHE_STATE, &cache_state_str);
bool pwl_enabled = cache::util::is_pwl_enabled(*image_ctx);
bool cache_desired = pwl_enabled;
cache_desired &= !image_ctx->read_only;
- cache_desired &= !image_ctx->test_features(RBD_FEATURE_MIGRATING);
- cache_desired &= !image_ctx->test_features(RBD_FEATURE_JOURNALING);
+ cache_desired &= !plugin_api.test_image_features(image_ctx, RBD_FEATURE_MIGRATING);
+ cache_desired &= !plugin_api.test_image_features(image_ctx, RBD_FEATURE_JOURNALING);
cache_desired &= !image_ctx->old_format;
if (!dirty_cache && !cache_desired) {
<< dendl;
r = -EINVAL;
}else if ((!dirty_cache || cache_state_str.empty()) && cache_desired) {
- cache_state = new ImageCacheState<I>(image_ctx);
+ cache_state = new ImageCacheState<I>(image_ctx, plugin_api);
} else {
ceph_assert(!cache_state_str.empty());
JSONFormattable f;
switch (cache_type) {
case IMAGE_CACHE_TYPE_RWL:
if (!cache_exists) {
- cache_state = new ImageCacheState<I>(image_ctx);
+ cache_state = new ImageCacheState<I>(image_ctx, plugin_api);
} else {
- cache_state = new ImageCacheState<I>(image_ctx, f);
+ cache_state = new ImageCacheState<I>(image_ctx, f, plugin_api);
}
break;
default:
}
template <typename I>
-ImageCacheState<I>* ImageCacheState<I>::get_image_cache_state(I* image_ctx) {
+ImageCacheState<I>* ImageCacheState<I>::get_image_cache_state(
+ I* image_ctx, plugin::Api<I>& plugin_api) {
ImageCacheState<I>* cache_state = nullptr;
string cache_state_str;
cls_client::metadata_get(&image_ctx->md_ctx, image_ctx->header_oid,
JSONFormattable f;
bool success = get_json_format(cache_state_str, &f);
if (!success) {
- cache_state = new ImageCacheState<I>(image_ctx);
+ cache_state = new ImageCacheState<I>(image_ctx, plugin_api);
} else {
- cache_state = new ImageCacheState<I>(image_ctx, f);
+ cache_state = new ImageCacheState<I>(image_ctx, f, plugin_api);
}
}
return cache_state;
}
namespace librbd {
+
+namespace plugin { template <typename> struct Api; }
+
namespace cache {
namespace pwl {
class ImageCacheState {
private:
ImageCtxT* m_image_ctx;
+ plugin::Api<ImageCtxT>& m_plugin_api;
public:
bool present = false;
bool empty = true;
uint64_t size = 0;
bool log_periodic_stats;
- ImageCacheState(ImageCtxT* image_ctx);
+ ImageCacheState(ImageCtxT* image_ctx, plugin::Api<ImageCtxT>& plugin_api);
- ImageCacheState(ImageCtxT* image_ctx, JSONFormattable& f);
+ ImageCacheState(ImageCtxT* image_ctx, JSONFormattable& f,
+ plugin::Api<ImageCtxT>& plugin_api);
~ImageCacheState() {}
void dump(ceph::Formatter *f) const;
static ImageCacheState<ImageCtxT>* create_image_cache_state(
- ImageCtxT* image_ctx, int &r);
+ ImageCtxT* image_ctx, plugin::Api<ImageCtxT>& plugin_api, int &r);
static ImageCacheState<ImageCtxT>* get_image_cache_state(
- ImageCtxT* image_ctx);
+ ImageCtxT* image_ctx, plugin::Api<ImageCtxT>& plugin_api);
bool is_valid();
};
#include "common/errno.h"
#include "librbd/asio/ContextWQ.h"
-#if defined(WITH_RBD_RWL) || defined(WITH_RBD_SSD_CACHE)
#include "librbd/cache/pwl/ImageCacheState.h"
#include "librbd/cache/WriteLogImageDispatch.h"
-#endif // WITH_RBD_RWL || WITH_RBD_SSD_CACHE
+#include "librbd/cache/ImageWriteback.h"
#ifdef WITH_RBD_RWL
#include "librbd/cache/pwl/ReplicatedWriteLog.h"
#endif
+
#ifdef WITH_RBD_SSD_CACHE
#include "librbd/cache/pwl/SSDWriteLog.h"
#endif
#include "librbd/cache/Utils.h"
#include "librbd/ImageCtx.h"
+#include "librbd/plugin/Api.h"
#define dout_subsys ceph_subsys_rbd_pwl
#undef dout_prefix
using librbd::util::create_context_callback;
template <typename I>
-InitRequest<I>* InitRequest<I>::create(I &image_ctx,
- Context *on_finish) {
- return new InitRequest(image_ctx, on_finish);
+InitRequest<I>* InitRequest<I>::create(
+ I &image_ctx,
+ cache::ImageWritebackInterface& image_writeback,
+ plugin::Api<I>& plugin_api,
+ Context *on_finish) {
+ return new InitRequest(image_ctx, image_writeback, plugin_api, on_finish);
}
template <typename I>
-InitRequest<I>::InitRequest(I &image_ctx, Context *on_finish)
+InitRequest<I>::InitRequest(
+ I &image_ctx,
+ cache::ImageWritebackInterface& image_writeback,
+ plugin::Api<I>& plugin_api,
+ Context *on_finish)
: m_image_ctx(image_ctx),
+ m_image_writeback(image_writeback),
+ m_plugin_api(plugin_api),
m_on_finish(create_async_context_callback(image_ctx, on_finish)),
m_error_result(0) {
}
template <typename I>
void InitRequest<I>::send() {
-#if defined(WITH_RBD_RWL) || defined(WITH_RBD_SSD_CACHE)
get_image_cache_state();
-#else
- finish();
-#endif // WITH_RBD_RWL
}
-#if defined(WITH_RBD_RWL) || defined(WITH_RBD_SSD_CACHE)
template <typename I>
void InitRequest<I>::get_image_cache_state() {
CephContext *cct = m_image_ctx.cct;
ldout(cct, 10) << dendl;
int r;
- auto cache_state = ImageCacheState<I>::create_image_cache_state(&m_image_ctx, r);
+ auto cache_state = ImageCacheState<I>::create_image_cache_state(
+ &m_image_ctx, m_plugin_api, r);
if (r < 0 || !cache_state) {
save_result(r);
case cache::IMAGE_CACHE_TYPE_RWL:
m_image_cache =
new librbd::cache::pwl::ReplicatedWriteLog<I>(m_image_ctx,
- cache_state);
+ cache_state,
+ m_image_writeback,
+ m_plugin_api);
break;
#endif
#ifdef WITH_RBD_SSD_CACHE
case cache::IMAGE_CACHE_TYPE_SSD:
m_image_cache =
new librbd::cache::pwl::SSDWriteLog<I>(m_image_ctx,
- cache_state);
+ cache_state,
+ m_image_writeback,
+ m_plugin_api);
break;
#endif
default:
}
// Register RWL dispatch
- auto image_dispatch = new cache::WriteLogImageDispatch<I>(&m_image_ctx, m_image_cache);
+ auto image_dispatch = new cache::WriteLogImageDispatch<I>(
+ &m_image_ctx, m_image_cache, m_plugin_api);
m_image_ctx.io_image_dispatcher->register_dispatch(image_dispatch);
finish();
}
-#endif // WITH_RBD_RWL
-
template <typename I>
void InitRequest<I>::finish() {
m_on_finish->complete(m_error_result);
namespace io { class ImageDispatchInterface; }
+namespace plugin { template <typename> struct Api; }
+
namespace cache {
+class ImageWritebackInterface;
+
namespace pwl {
template<typename>
template <typename ImageCtxT = ImageCtx>
class InitRequest {
public:
- static InitRequest* create(ImageCtxT &image_ctx, Context *on_finish);
+ static InitRequest* create(
+ ImageCtxT &image_ctx,
+ librbd::cache::ImageWritebackInterface& image_writeback,
+ plugin::Api<ImageCtxT>& plugin_api,
+ Context *on_finish);
void send();
* @endverbatim
*/
- InitRequest(ImageCtxT &image_ctx, Context *on_finish);
+ InitRequest(ImageCtxT &image_ctx,
+ librbd::cache::ImageWritebackInterface& image_writeback,
+ plugin::Api<ImageCtxT>& plugin_api,
+ Context *on_finish);
ImageCtxT &m_image_ctx;
+ librbd::cache::ImageWritebackInterface& m_image_writeback;
+ plugin::Api<ImageCtxT>& m_plugin_api;
AbstractWriteLog<ImageCtxT> *m_image_cache;
Context *m_on_finish;
WriteLogEntry(std::shared_ptr<SyncPointLogEntry> sync_point_entry,
const uint64_t image_offset_bytes, const uint64_t write_bytes)
: GenericWriteLogEntry(sync_point_entry, image_offset_bytes, write_bytes),
- m_entry_bl_lock(ceph::make_mutex(util::unique_lock_name(
+ m_entry_bl_lock(ceph::make_mutex(pwl::unique_lock_name(
"librbd::cache::pwl::WriteLogEntry::m_entry_bl_lock", this)))
{ }
WriteLogEntry(const uint64_t image_offset_bytes, const uint64_t write_bytes)
: GenericWriteLogEntry(nullptr, image_offset_bytes, write_bytes),
- m_entry_bl_lock(ceph::make_mutex(util::unique_lock_name(
+ m_entry_bl_lock(ceph::make_mutex(pwl::unique_lock_name(
"librbd::cache::pwl::WriteLogEntry::m_entry_bl_lock", this)))
{ }
~WriteLogEntry() override {};
template <typename T>
LogMap<T>::LogMap(CephContext *cct)
: m_cct(cct),
- m_lock(ceph::make_mutex(util::unique_lock_name(
+ m_lock(ceph::make_mutex(pwl::unique_lock_name(
"librbd::cache::pwl::LogMap::m_lock", this))) {
}
PerfCounters *perfcounter,
CephContext *cct)
: GenericLogOperation(dispatch_time, perfcounter),
- m_lock(ceph::make_mutex(util::unique_lock_name(
+ m_lock(ceph::make_mutex(pwl::unique_lock_name(
"librbd::cache::pwl::GenericWriteLogOperation::m_lock", this))),
m_cct(cct),
sync_point(sync_point) {
#include "librbd/asio/ContextWQ.h"
#include "librbd/cache/pwl/ImageCacheState.h"
#include "librbd/cache/pwl/LogEntry.h"
+#include "librbd/plugin/Api.h"
#include <map>
#include <vector>
template <typename I>
ReplicatedWriteLog<I>::ReplicatedWriteLog(
- I &image_ctx, librbd::cache::pwl::ImageCacheState<I>* cache_state)
-: AbstractWriteLog<I>(image_ctx, cache_state),
+ I &image_ctx, librbd::cache::pwl::ImageCacheState<I>* cache_state,
+ ImageWritebackInterface& image_writeback,
+ plugin::Api<I>& plugin_api)
+: AbstractWriteLog<I>(image_ctx, cache_state, image_writeback, plugin_api),
m_pwl_pool_layout_name(POBJ_LAYOUT_NAME(rbd_pwl))
{
}
class ReplicatedWriteLog : public AbstractWriteLog<ImageCtxT> {
public:
ReplicatedWriteLog(
- ImageCtxT &image_ctx, librbd::cache::pwl::ImageCacheState<ImageCtxT>* cache_state);
+ ImageCtxT &image_ctx, librbd::cache::pwl::ImageCacheState<ImageCtxT>* cache_state,
+ ImageWritebackInterface& image_writeback,
+ plugin::Api<ImageCtxT>& plugin_api);
~ReplicatedWriteLog();
ReplicatedWriteLog(const ReplicatedWriteLog&) = delete;
ReplicatedWriteLog &operator=(const ReplicatedWriteLog&) = delete;
template <typename I>
SSDWriteLog<I>::SSDWriteLog(
- I &image_ctx, librbd::cache::pwl::ImageCacheState<I>* cache_state)
- : AbstractWriteLog<I>(image_ctx, cache_state)
+ I &image_ctx, librbd::cache::pwl::ImageCacheState<I>* cache_state,
+ cache::ImageWritebackInterface& image_writeback,
+ plugin::Api<I>& plugin_api)
+ : AbstractWriteLog<I>(image_ctx, cache_state, image_writeback, plugin_api)
{
}
class SSDWriteLog : public AbstractWriteLog<ImageCtxT> {
public:
SSDWriteLog(ImageCtxT &image_ctx,
- librbd::cache::pwl::ImageCacheState<ImageCtxT>* cache_state);
+ librbd::cache::pwl::ImageCacheState<ImageCtxT>* cache_state,
+ cache::ImageWritebackInterface& image_writeback,
+ plugin::Api<ImageCtxT>& plugin_api);
~SSDWriteLog() {}
SSDWriteLog(const SSDWriteLog&) = delete;
SSDWriteLog &operator=(const SSDWriteLog&) = delete;
#include "librbd/asio/ContextWQ.h"
#include "librbd/cache/Types.h"
-#if defined(WITH_RBD_RWL)
#include "librbd/cache/pwl/AbstractWriteLog.h"
-#endif // WITH_RBD_RWL
+#include "librbd/plugin/Api.h"
#define dout_subsys ceph_subsys_rbd_pwl
#undef dout_prefix
ShutdownRequest<I>* ShutdownRequest<I>::create(
I &image_ctx,
AbstractWriteLog<I> *image_cache,
+ plugin::Api<I>& plugin_api,
Context *on_finish) {
- return new ShutdownRequest(image_ctx, image_cache, on_finish);
+ return new ShutdownRequest(image_ctx, image_cache, plugin_api, on_finish);
}
template <typename I>
ShutdownRequest<I>::ShutdownRequest(
I &image_ctx,
AbstractWriteLog<I> *image_cache,
+ plugin::Api<I>& plugin_api,
Context *on_finish)
: m_image_ctx(image_ctx),
m_image_cache(image_cache),
+ m_plugin_api(plugin_api),
m_on_finish(create_async_context_callback(image_ctx, on_finish)),
m_error_result(0) {
}
template <typename I>
void ShutdownRequest<I>::send() {
-#if defined(WITH_RBD_RWL)
send_shutdown_image_cache();
-#else
- finish();
-#endif // WITH_RBD_RWL
}
-#if defined(WITH_RBD_RWL)
template <typename I>
void ShutdownRequest<I>::send_shutdown_image_cache() {
CephContext *cct = m_image_ctx.cct;
Context *ctx = create_context_callback<klass, &klass::handle_remove_image_cache_state>(
this);
std::shared_lock owner_lock{m_image_ctx.owner_lock};
- m_image_ctx.operations->execute_metadata_remove(IMAGE_CACHE_STATE, ctx);
+ m_plugin_api.execute_image_metadata_remove(&m_image_ctx, IMAGE_CACHE_STATE, ctx);
}
template <typename I>
finish();
}
-#endif // WITH_RBD_RWL
-
template <typename I>
void ShutdownRequest<I>::finish() {
m_on_finish->complete(m_error_result);
class ImageCtx;
+namespace plugin { template <typename> struct Api; }
+
namespace cache {
namespace pwl {
static ShutdownRequest* create(
ImageCtxT &image_ctx,
AbstractWriteLog<ImageCtxT> *image_cache,
+ plugin::Api<ImageCtxT>& plugin_api,
Context *on_finish);
void send();
ShutdownRequest(ImageCtxT &image_ctx,
AbstractWriteLog<ImageCtxT> *image_cache,
+ plugin::Api<ImageCtxT>& plugin_api,
Context *on_finish);
ImageCtxT &m_image_ctx;
AbstractWriteLog<ImageCtxT> *m_image_cache;
+ plugin::Api<ImageCtxT>& m_plugin_api;
Context *m_on_finish;
int m_error_result;
#include "Types.h"
#include "common/ceph_context.h"
#include "include/Context.h"
+#include "include/stringify.h"
#define dout_subsys ceph_subsys_rbd_pwl
#undef dout_prefix
}
}
+std::string unique_lock_name(const std::string &name, void *address) {
+ return name + " (" + stringify(address) + ")";
+}
+
} // namespace pwl
} // namespace cache
} // namespace librbd
: io::Extent(extent), m_bl(bl) { }
};
+std::string unique_lock_name(const std::string &name, void *address);
+
} // namespace pwl
} // namespace cache
} // namespace librbd
#include "common/dout.h"
#include "common/errno.h"
#include "include/stringify.h"
-#include "librbd/cache/pwl/InitRequest.h"
#include "librbd/ExclusiveLock.h"
#include "librbd/ImageCtx.h"
#include "librbd/ImageState.h"
return;
}
- send_open_image_cache();
+ finish();
}
template <typename I>
send_close_journal();
}
-template <typename I>
-void PostAcquireRequest<I>::send_open_image_cache() {
- CephContext *cct = m_image_ctx.cct;
- ldout(cct, 10) << dendl;
-
- using klass = PostAcquireRequest<I>;
- Context *ctx = create_async_context_callback(
- m_image_ctx, create_context_callback<
- klass, &klass::handle_open_image_cache>(this));
- cache::pwl::InitRequest<I> *req = cache::pwl::InitRequest<I>::create(
- m_image_ctx, ctx);
- req->send();
-}
-
-template <typename I>
-void PostAcquireRequest<I>::handle_open_image_cache(int r) {
- CephContext *cct = m_image_ctx.cct;
- ldout(cct, 10) << "r=" << r << dendl;
-
- save_result(r);
- if (r < 0) {
- lderr(cct) << "failed to open image cache: " << cpp_strerror(r)
- << dendl;
- send_process_plugin_release_lock();
- return;
- }
-
- finish();
-}
-
template <typename I>
void PostAcquireRequest<I>::send_close_journal() {
if (m_journal == nullptr) {
* PROCESS_PLUGIN_ACQUIRE*
* | * *
* | * *
- * v * *
- * OPEN_IMAGE_CACHE *
- * | * * *
- * | * * *
* | v v v
* | PROCESS_PLUGIN_RELEASE
* | |
void send_process_plugin_release_lock();
void handle_process_plugin_release_lock(int r);
- void send_open_image_cache();
- void handle_open_image_cache(int r);
-
void apply();
void revert();
void send_process_plugin_release_lock();
void handle_process_plugin_release_lock(int r);
- void send_shut_down_image_cache();
- void handle_shut_down_image_cache(int r);
-
void send_invalidate_cache();
void handle_invalidate_cache(int r);
#include "librbd/Journal.h"
#include "librbd/ObjectMap.h"
#include "librbd/Operations.h"
+#include "librbd/PluginRegistry.h"
#include "librbd/Types.h"
#include "librbd/Utils.h"
#include "librbd/api/Config.h"
!ictx->exclusive_lock->is_lock_owner()) &&
ictx->test_features(RBD_FEATURE_DIRTY_CACHE)) {
C_SaferCond ctx3;
- librbd::cache::util::discard_cache<>(*ictx, &ctx3);
+ ictx->plugin_registry->discard(&ctx3);
r = ctx3.wait();
}
return r;
// -*- 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 {
on_finish);
}
+template <typename I>
+void Api<I>::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 <typename I>
+void Api<I>::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 <typename I>
+void Api<I>::get_image_timer_instance(
+ CephContext *cct, SafeTimer **timer, ceph::mutex **timer_lock) {
+ ImageCtx::get_timer_instance(cct, timer, timer_lock);
+}
+
+template <typename I>
+bool Api<I>::test_image_features(I *image_ctx, uint64_t features) {
+ return image_ctx->test_features(features);
+}
+
+template <typename I>
+void Api<I>::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 <typename I>
+void Api<I>::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 <typename I>
+io::ReadResult::C_ImageReadRequest* Api<I>::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 <typename I>
+io::C_AioRequest* Api<I>::create_aio_request(io::AioCompletion* aio_comp) {
+ io::C_AioRequest *req_comp = new io::C_AioRequest(aio_comp);
+ return req_comp;
+}
+
+template <typename I>
+void Api<I>::start_in_flight_io(io::AioCompletion* aio_comp) {
+ if (!aio_comp->async_op.started()) {
+ aio_comp->start_op();
+ }
+}
+
} // namespace plugin
} // namespace librbd
#ifndef CEPH_LIBRBD_PLUGIN_API_H
#define CEPH_LIBRBD_PLUGIN_API_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; }
+class SafeTimer;
+
namespace librbd {
+namespace io {
+class AioCompletion;
+class C_AioRequest;
+}
+
struct ImageCtx;
namespace plugin {
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
--- /dev/null
+// -*- 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/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<librbd::ImageCtx>(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 <typename I>
+void WriteLogImageCache<I>::init(I* image_ctx, Api<I>& api,
+ cache::ImageWritebackInterface& image_writeback,
+ PluginHookPoints& hook_points_list,
+ Context* on_finish) {
+ bool rwl_enabled = image_ctx->config.template get_val<bool>(
+ "rbd_rwl_enabled");
+ if (!rwl_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<WriteLogImageCache::HookPoints>(
+ image_ctx, image_writeback, api);
+ hook_points_list.emplace_back(std::move(hook_points));
+
+ on_finish->complete(0);
+}
+
+template <typename I>
+WriteLogImageCache<I>::~WriteLogImageCache() {
+}
+
+template <typename I>
+WriteLogImageCache<I>::HookPoints::HookPoints(
+ I* image_ctx, cache::ImageWritebackInterface& image_writeback,
+ plugin::Api<I>& plugin_api)
+ : m_image_ctx(image_ctx), m_image_writeback(image_writeback),
+ m_plugin_api(plugin_api)
+{
+}
+
+template <typename I>
+WriteLogImageCache<I>::HookPoints::~HookPoints() {
+}
+
+template <typename I>
+void WriteLogImageCache<I>::HookPoints::acquired_exclusive_lock(
+ Context* on_finish) {
+ cache::pwl::InitRequest<I> *req = cache::pwl::InitRequest<I>::create(
+ *m_image_ctx, m_image_writeback, m_plugin_api, on_finish);
+ req->send();
+}
+
+template <typename I>
+void WriteLogImageCache<I>::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 <typename I>
+void WriteLogImageCache<I>::HookPoints::discard(
+ Context* on_finish) {
+ cache::pwl::DiscardRequest<I> *req = cache::pwl::DiscardRequest<I>::create(
+ *m_image_ctx, m_plugin_api, on_finish);
+ req->send();
+}
+
+} // namespace plugin
+} // namespace librbd
+
+template class librbd::plugin::WriteLogImageCache<librbd::ImageCtx>;
--- /dev/null
+// -*- 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 <typename ImageCtxT>
+class WriteLogImageCache : public Interface<ImageCtxT> {
+public:
+ WriteLogImageCache(CephContext* cct) : Interface<ImageCtxT>(cct) {
+ }
+
+ ~WriteLogImageCache() override;
+
+ void init(ImageCtxT* image_ctx, Api<ImageCtxT>& 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<ImageCtxT>& 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<ImageCtxT>& m_plugin_api;
+ };
+
+};
+
+} // namespace plugin
+} // namespace librbd
+
+extern template class librbd::plugin::WriteLogImageCache<librbd::ImageCtx>;
+
+#endif // CEPH_LIBRBD_PLUGIN_WRITELOG_IMAGE_CACHE_H
OpenSSL::SSL
${UNITTEST_LIBS})
+if(WITH_RBD_RWL OR WITH_RBD_SSD_CACHE)
+ target_link_libraries(unittest_librbd
+ librbd_plugin_pwl_cache)
+endif()
+
add_executable(ceph_test_librbd
test_main.cc
$<TARGET_OBJECTS:common_texttable_obj>)
#include "test/librbd/test_support.h"
#include "test/librbd/mock/MockImageCtx.h"
#include "include/rbd/librbd.hpp"
-#include "librbd/cache/pwl/AbstractWriteLog.h"
#include "librbd/cache/pwl/ImageCacheState.h"
#include "librbd/cache/pwl/Types.h"
#include "librbd/cache/ImageWriteback.h"
+#include "librbd/plugin/Api.h"
namespace librbd {
namespace {
#include "librbd/cache/pwl/AbstractWriteLog.cc"
#include "librbd/cache/pwl/ReplicatedWriteLog.cc"
+template class librbd::cache::pwl::ReplicatedWriteLog<librbd::MockImageCtx>;
// template definitions
#include "librbd/cache/ImageWriteback.cc"
#include "librbd/cache/pwl/ImageCacheState.cc"
#include "librbd/cache/pwl/Request.cc"
+#include "librbd/plugin/Api.cc"
namespace librbd {
namespace cache {
using ::testing::InSequence;
using ::testing::Invoke;
+typedef io::Extent Extent;
+typedef io::Extents Extents;
+
struct TestMockCacheReplicatedWriteLog : public TestMockFixture {
typedef librbd::cache::pwl::ReplicatedWriteLog<librbd::MockImageCtx> MockReplicatedWriteLog;
typedef librbd::cache::pwl::ImageCacheState<librbd::MockImageCtx> MockImageCacheStateRWL;
+ typedef librbd::cache::ImageWriteback<librbd::MockImageCtx> MockImageWriteback;
+ typedef librbd::plugin::Api<librbd::MockImageCtx> MockApi;
- MockImageCacheStateRWL *get_cache_state(MockImageCtx& mock_image_ctx) {
- MockImageCacheStateRWL *rwl_state = new MockImageCacheStateRWL(&mock_image_ctx);
+ MockImageCacheStateRWL *get_cache_state(
+ MockImageCtx& mock_image_ctx, MockApi& mock_api) {
+ MockImageCacheStateRWL *rwl_state = new MockImageCacheStateRWL(&mock_image_ctx, mock_api);
return rwl_state;
}
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockImageCacheStateRWL image_cache_state(&mock_image_ctx);
+ MockApi mock_api;
+ MockImageCacheStateRWL image_cache_state(&mock_image_ctx, mock_api);
validate_cache_state(ictx, image_cache_state, false, true, true, "", "", 0);
\"pwl_path\": \"/tmp\", \
\"pwl_size\": \"1024\" }";
get_jf(strf, &f);
- MockImageCacheStateRWL image_cache_state(&mock_image_ctx, f);
+ MockApi mock_api;
+ MockImageCacheStateRWL image_cache_state(&mock_image_ctx, f, mock_api);
validate_cache_state(ictx, image_cache_state, true, false, false,
"testhost", "/tmp", 1024);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockReplicatedWriteLog rwl(mock_image_ctx, get_cache_state(mock_image_ctx));
+ MockImageWriteback mock_image_writeback(mock_image_ctx);
+ MockApi mock_api;
+ MockReplicatedWriteLog rwl(
+ mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
+ mock_image_writeback, mock_api);
MockContextRWL finish_ctx1;
expect_op_work_queue(mock_image_ctx);
expect_metadata_set(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockReplicatedWriteLog rwl(mock_image_ctx, get_cache_state(mock_image_ctx));
+ MockImageWriteback mock_image_writeback(mock_image_ctx);
+ MockApi mock_api;
+ MockReplicatedWriteLog rwl(
+ mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
+ mock_image_writeback, mock_api);
MockContextRWL finish_ctx1;
expect_op_work_queue(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockReplicatedWriteLog rwl(mock_image_ctx, get_cache_state(mock_image_ctx));
+ MockImageWriteback mock_image_writeback(mock_image_ctx);
+ MockApi mock_api;
+ MockReplicatedWriteLog rwl(
+ mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
+ mock_image_writeback, mock_api);
+
expect_op_work_queue(mock_image_ctx);
expect_metadata_set(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockReplicatedWriteLog rwl(mock_image_ctx, get_cache_state(mock_image_ctx));
+ MockImageWriteback mock_image_writeback(mock_image_ctx);
+ MockApi mock_api;
+ MockReplicatedWriteLog rwl(
+ mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
+ mock_image_writeback, mock_api);
+
expect_op_work_queue(mock_image_ctx);
expect_metadata_set(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockReplicatedWriteLog rwl(mock_image_ctx, get_cache_state(mock_image_ctx));
+ MockImageWriteback mock_image_writeback(mock_image_ctx);
+ MockApi mock_api;
+ MockReplicatedWriteLog rwl(
+ mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
+ mock_image_writeback, mock_api);
+
expect_op_work_queue(mock_image_ctx);
expect_metadata_set(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockReplicatedWriteLog rwl(mock_image_ctx, get_cache_state(mock_image_ctx));
+ MockImageWriteback mock_image_writeback(mock_image_ctx);
+ MockApi mock_api;
+ MockReplicatedWriteLog rwl(
+ mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
+ mock_image_writeback, mock_api);
expect_op_work_queue(mock_image_ctx);
expect_metadata_set(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockReplicatedWriteLog rwl(mock_image_ctx, get_cache_state(mock_image_ctx));
+ MockImageWriteback mock_image_writeback(mock_image_ctx);
+ MockApi mock_api;
+ MockReplicatedWriteLog rwl(
+ mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
+ mock_image_writeback, mock_api);
expect_op_work_queue(mock_image_ctx);
expect_metadata_set(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockReplicatedWriteLog rwl(mock_image_ctx, get_cache_state(mock_image_ctx));
+ MockImageWriteback mock_image_writeback(mock_image_ctx);
+ MockApi mock_api;
+ MockReplicatedWriteLog rwl(
+ mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
+ mock_image_writeback, mock_api);
expect_op_work_queue(mock_image_ctx);
expect_metadata_set(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockReplicatedWriteLog rwl(mock_image_ctx, get_cache_state(mock_image_ctx));
+ MockImageWriteback mock_image_writeback(mock_image_ctx);
+ MockApi mock_api;
+ MockReplicatedWriteLog rwl(
+ mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
+ mock_image_writeback, mock_api);
expect_op_work_queue(mock_image_ctx);
expect_metadata_set(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockReplicatedWriteLog rwl(mock_image_ctx, get_cache_state(mock_image_ctx));
+ MockImageWriteback mock_image_writeback(mock_image_ctx);
+ MockApi mock_api;
+ MockReplicatedWriteLog rwl(
+ mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
+ mock_image_writeback, mock_api);
expect_op_work_queue(mock_image_ctx);
expect_metadata_set(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockReplicatedWriteLog rwl(mock_image_ctx, get_cache_state(mock_image_ctx));
+ MockImageWriteback mock_image_writeback(mock_image_ctx);
+ MockApi mock_api;
+ MockReplicatedWriteLog rwl(
+ mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
+ mock_image_writeback, mock_api);
expect_op_work_queue(mock_image_ctx);
expect_metadata_set(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockReplicatedWriteLog rwl(mock_image_ctx, get_cache_state(mock_image_ctx));
+ MockImageWriteback mock_image_writeback(mock_image_ctx);
+ MockApi mock_api;
+ MockReplicatedWriteLog rwl(
+ mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
+ mock_image_writeback, mock_api);
expect_op_work_queue(mock_image_ctx);
expect_metadata_set(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockReplicatedWriteLog rwl(mock_image_ctx, get_cache_state(mock_image_ctx));
+ MockImageWriteback mock_image_writeback(mock_image_ctx);
+ MockApi mock_api;
+ MockReplicatedWriteLog rwl(
+ mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
+ mock_image_writeback, mock_api);
expect_op_work_queue(mock_image_ctx);
expect_metadata_set(mock_image_ctx);
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockImageCtx mock_image_ctx(*ictx);
- MockReplicatedWriteLog rwl(mock_image_ctx, get_cache_state(mock_image_ctx));
+ MockImageWriteback mock_image_writeback(mock_image_ctx);
+ MockApi mock_api;
+ MockReplicatedWriteLog rwl(
+ mock_image_ctx, get_cache_state(mock_image_ctx, mock_api),
+ mock_image_writeback, mock_api);
expect_op_work_queue(mock_image_ctx);
expect_metadata_set(mock_image_ctx);
#include "test/librbd/mock/MockObjectMap.h"
#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
#include "test/librados_test_stub/MockTestMemRadosClient.h"
-#include "librbd/cache/pwl/InitRequest.h"
#include "librbd/exclusive_lock/PostAcquireRequest.h"
#include "librbd/image/RefreshRequest.h"
RefreshRequest<librbd::MockTestImageCtx> *RefreshRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
} // namespace image
-
-namespace cache {
-namespace pwl {
-
-template<>
-struct InitRequest<librbd::MockTestImageCtx> {
- static InitRequest *s_instance;
- Context *on_finish = nullptr;
-
- static InitRequest *create(librbd::MockTestImageCtx &image_ctx,
- Context *on_finish) {
- ceph_assert(s_instance != nullptr);
- s_instance->on_finish = on_finish;
- return s_instance;
- }
-
- InitRequest() {
- s_instance = this;
- }
- MOCK_METHOD0(send, void());
-};
-
-InitRequest<librbd::MockTestImageCtx> *InitRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
-
-} // namespace pwl
-} // namespace cache
} // namespace librbd
// template definitions
public:
typedef PostAcquireRequest<MockTestImageCtx> MockPostAcquireRequest;
typedef librbd::image::RefreshRequest<MockTestImageCtx> MockRefreshRequest;
- typedef librbd::cache::pwl::InitRequest<MockTestImageCtx> MockInitRequest;
void expect_test_features(MockTestImageCtx &mock_image_ctx, uint64_t features,
bool enabled) {
expect_acquired_exclusive_lock(mock_image_ctx, 0);
- MockInitRequest mock_init_request;
- expect_init_image_cache(mock_image_ctx, mock_init_request, 0);
C_SaferCond acquire_ctx;
C_SaferCond ctx;
MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,
expect_acquired_exclusive_lock(mock_image_ctx, 0);
- MockInitRequest mock_init_request;
- expect_init_image_cache(mock_image_ctx, mock_init_request, 0);
-
C_SaferCond acquire_ctx;
C_SaferCond ctx;
MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,
expect_acquired_exclusive_lock(mock_image_ctx, 0);
- MockInitRequest mock_init_request;
- expect_init_image_cache(mock_image_ctx, mock_init_request, 0);
-
C_SaferCond acquire_ctx;
C_SaferCond ctx;
MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,
expect_acquired_exclusive_lock(mock_image_ctx, 0);
- MockInitRequest mock_init_request;
- expect_init_image_cache(mock_image_ctx, mock_init_request, 0);
-
C_SaferCond acquire_ctx;
C_SaferCond ctx;
MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,
expect_acquired_exclusive_lock(mock_image_ctx, 0);
- MockInitRequest mock_init_request;
- expect_init_image_cache(mock_image_ctx, mock_init_request, 0);
-
C_SaferCond acquire_ctx;
C_SaferCond ctx;
MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,
expect_acquired_exclusive_lock(mock_image_ctx, -ENOENT);
expect_prerelease_exclusive_lock(mock_image_ctx, 0);
- MockInitRequest mock_init_request;
- expect_init_image_cache(mock_image_ctx, mock_init_request, -ENOENT);
-
expect_close_journal(mock_image_ctx, mock_journal);
expect_close_object_map(mock_image_ctx, mock_object_map);
expect_acquired_exclusive_lock(mock_image_ctx, 0);
- MockInitRequest mock_init_request;
- expect_init_image_cache(mock_image_ctx, mock_init_request, 0);
-
C_SaferCond acquire_ctx;
C_SaferCond ctx;
MockPostAcquireRequest *req = MockPostAcquireRequest::create(mock_image_ctx,