From 49a39ebf6f7c6b7b0b19e4486fc10e57637e143c Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 4 Aug 2016 13:47:33 -0400 Subject: [PATCH] librbd: convert ImageWatcher class to template Signed-off-by: Jason Dillaman (cherry picked from commit 814c305ce8c35b5ce01d7e29a912d5ef3978754b) Conflicts: src/librbd/ImageWatcher.cc: no shrink guard src/librbd/Operations.cc: no shrink guard --- src/librbd/ImageCtx.cc | 4 +- src/librbd/ImageCtx.h | 4 +- src/librbd/ImageWatcher.cc | 300 +++++++++++++++++++++++-------------- src/librbd/ImageWatcher.h | 7 +- src/librbd/Operations.cc | 18 +-- 5 files changed, 202 insertions(+), 131 deletions(-) diff --git a/src/librbd/ImageCtx.cc b/src/librbd/ImageCtx.cc index f88d32d63b563..edce967b3063e 100644 --- a/src/librbd/ImageCtx.cc +++ b/src/librbd/ImageCtx.cc @@ -791,7 +791,7 @@ struct C_InvalidateCache : public Context { void ImageCtx::register_watch(Context *on_finish) { assert(image_watcher == NULL); - image_watcher = new ImageWatcher(*this); + image_watcher = new ImageWatcher<>(*this); image_watcher->register_watch(on_finish); } @@ -1022,7 +1022,7 @@ struct C_InvalidateCache : public Context { void ImageCtx::notify_update() { state->handle_update_notification(); - ImageWatcher::notify_header_update(md_ctx, header_oid); + ImageWatcher<>::notify_header_update(md_ctx, header_oid); } void ImageCtx::notify_update(Context *on_finish) { diff --git a/src/librbd/ImageCtx.h b/src/librbd/ImageCtx.h index 709987f7a33d6..5c992e70730a0 100644 --- a/src/librbd/ImageCtx.h +++ b/src/librbd/ImageCtx.h @@ -42,7 +42,7 @@ namespace librbd { class CopyupRequest; template class ExclusiveLock; template class ImageState; - class ImageWatcher; + template class ImageWatcher; template class Journal; class LibrbdAdminSocketHook; class ObjectMap; @@ -79,7 +79,7 @@ namespace librbd { std::string name; std::string snap_name; IoCtx data_ctx, md_ctx; - ImageWatcher *image_watcher; + ImageWatcher *image_watcher; Journal *journal; /** diff --git a/src/librbd/ImageWatcher.cc b/src/librbd/ImageWatcher.cc index 78e2585ca3026..ef5cdf1102eeb 100644 --- a/src/librbd/ImageWatcher.cc +++ b/src/librbd/ImageWatcher.cc @@ -68,7 +68,8 @@ struct C_UnwatchAndFlush : public Context { static const double RETRY_DELAY_SECONDS = 1.0; -ImageWatcher::ImageWatcher(ImageCtx &image_ctx) +template +ImageWatcher::ImageWatcher(I &image_ctx) : m_image_ctx(image_ctx), m_watch_lock(util::unique_lock_name("librbd::ImageWatcher::m_watch_lock", this)), m_watch_ctx(*this), m_watch_handle(0), @@ -80,7 +81,8 @@ ImageWatcher::ImageWatcher(ImageCtx &image_ctx) { } -ImageWatcher::~ImageWatcher() +template +ImageWatcher::~ImageWatcher() { delete m_task_finisher; { @@ -89,7 +91,8 @@ ImageWatcher::~ImageWatcher() } } -void ImageWatcher::register_watch(Context *on_finish) { +template +void ImageWatcher::register_watch(Context *on_finish) { ldout(m_image_ctx.cct, 10) << this << " registering image watcher" << dendl; RWLock::RLocker watch_locker(m_watch_lock); @@ -102,7 +105,8 @@ void ImageWatcher::register_watch(Context *on_finish) { aio_comp->release(); } -void ImageWatcher::handle_register_watch(int r) { +template +void ImageWatcher::handle_register_watch(int r) { RWLock::WLocker watch_locker(m_watch_lock); assert(m_watch_state == WATCH_STATE_UNREGISTERED); if (r < 0) { @@ -112,7 +116,8 @@ void ImageWatcher::handle_register_watch(int r) { } } -void ImageWatcher::unregister_watch(Context *on_finish) { +template +void ImageWatcher::unregister_watch(Context *on_finish) { ldout(m_image_ctx.cct, 10) << this << " unregistering image watcher" << dendl; cancel_async_requests(); @@ -140,20 +145,23 @@ void ImageWatcher::unregister_watch(Context *on_finish) { g->activate(); } -void ImageWatcher::flush(Context *on_finish) { +template +void ImageWatcher::flush(Context *on_finish) { m_notifier.flush(on_finish); } -void ImageWatcher::schedule_async_progress(const AsyncRequestId &request, - uint64_t offset, uint64_t total) { +template +void ImageWatcher::schedule_async_progress(const AsyncRequestId &request, + uint64_t offset, uint64_t total) { FunctionContext *ctx = new FunctionContext( - boost::bind(&ImageWatcher::notify_async_progress, this, request, offset, + boost::bind(&ImageWatcher::notify_async_progress, this, request, offset, total)); m_task_finisher->queue(Task(TASK_CODE_ASYNC_PROGRESS, request), ctx); } -int ImageWatcher::notify_async_progress(const AsyncRequestId &request, - uint64_t offset, uint64_t total) { +template +int ImageWatcher::notify_async_progress(const AsyncRequestId &request, + uint64_t offset, uint64_t total) { ldout(m_image_ctx.cct, 20) << this << " remote async request progress: " << request << " @ " << offset << "/" << total << dendl; @@ -164,25 +172,30 @@ int ImageWatcher::notify_async_progress(const AsyncRequestId &request, return 0; } -void ImageWatcher::schedule_async_complete(const AsyncRequestId &request, - int r) { +template +void ImageWatcher::schedule_async_complete(const AsyncRequestId &request, + int r) { FunctionContext *ctx = new FunctionContext( - boost::bind(&ImageWatcher::notify_async_complete, this, request, r)); + boost::bind(&ImageWatcher::notify_async_complete, this, request, r)); m_task_finisher->queue(ctx); } -void ImageWatcher::notify_async_complete(const AsyncRequestId &request, int r) { +template +void ImageWatcher::notify_async_complete(const AsyncRequestId &request, + int r) { ldout(m_image_ctx.cct, 20) << this << " remote async request finished: " << request << " = " << r << dendl; bufferlist bl; ::encode(NotifyMessage(AsyncCompletePayload(request, r)), bl); m_notifier.notify(bl, nullptr, new FunctionContext( - boost::bind(&ImageWatcher::handle_async_complete, this, request, r, _1))); + boost::bind(&ImageWatcher::handle_async_complete, this, request, r, + _1))); } -void ImageWatcher::handle_async_complete(const AsyncRequestId &request, int r, - int ret_val) { +template +void ImageWatcher::handle_async_complete(const AsyncRequestId &request, + int r, int ret_val) { ldout(m_image_ctx.cct, 20) << this << " " << __func__ << ": " << "request=" << request << ", r=" << ret_val << dendl; @@ -198,9 +211,10 @@ void ImageWatcher::handle_async_complete(const AsyncRequestId &request, int r, } } -void ImageWatcher::notify_flatten(uint64_t request_id, - ProgressContext &prog_ctx, - Context *on_finish) { +template +void ImageWatcher::notify_flatten(uint64_t request_id, + ProgressContext &prog_ctx, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); @@ -212,9 +226,10 @@ void ImageWatcher::notify_flatten(uint64_t request_id, notify_async_request(async_request_id, std::move(bl), prog_ctx, on_finish); } -void ImageWatcher::notify_resize(uint64_t request_id, uint64_t size, - ProgressContext &prog_ctx, - Context *on_finish) { +template +void ImageWatcher::notify_resize(uint64_t request_id, uint64_t size, + ProgressContext &prog_ctx, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); @@ -226,8 +241,9 @@ void ImageWatcher::notify_resize(uint64_t request_id, uint64_t size, notify_async_request(async_request_id, std::move(bl), prog_ctx, on_finish); } -void ImageWatcher::notify_snap_create(const std::string &snap_name, - Context *on_finish) { +template +void ImageWatcher::notify_snap_create(const std::string &snap_name, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); @@ -237,8 +253,9 @@ void ImageWatcher::notify_snap_create(const std::string &snap_name, notify_lock_owner(std::move(bl), on_finish); } -void ImageWatcher::notify_snap_rename(const snapid_t &src_snap_id, - const std::string &dst_snap_name, +template +void ImageWatcher::notify_snap_rename(const snapid_t &src_snap_id, + const std::string &dst_snap_name, Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && @@ -249,8 +266,9 @@ void ImageWatcher::notify_snap_rename(const snapid_t &src_snap_id, notify_lock_owner(std::move(bl), on_finish); } -void ImageWatcher::notify_snap_remove(const std::string &snap_name, - Context *on_finish) { +template +void ImageWatcher::notify_snap_remove(const std::string &snap_name, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); @@ -260,8 +278,9 @@ void ImageWatcher::notify_snap_remove(const std::string &snap_name, notify_lock_owner(std::move(bl), on_finish); } -void ImageWatcher::notify_snap_protect(const std::string &snap_name, - Context *on_finish) { +template +void ImageWatcher::notify_snap_protect(const std::string &snap_name, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); @@ -271,8 +290,9 @@ void ImageWatcher::notify_snap_protect(const std::string &snap_name, notify_lock_owner(std::move(bl), on_finish); } -void ImageWatcher::notify_snap_unprotect(const std::string &snap_name, - Context *on_finish) { +template +void ImageWatcher::notify_snap_unprotect(const std::string &snap_name, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); @@ -282,9 +302,10 @@ void ImageWatcher::notify_snap_unprotect(const std::string &snap_name, notify_lock_owner(std::move(bl), on_finish); } -void ImageWatcher::notify_rebuild_object_map(uint64_t request_id, - ProgressContext &prog_ctx, - Context *on_finish) { +template +void ImageWatcher::notify_rebuild_object_map(uint64_t request_id, + ProgressContext &prog_ctx, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); @@ -296,8 +317,9 @@ void ImageWatcher::notify_rebuild_object_map(uint64_t request_id, notify_async_request(async_request_id, std::move(bl), prog_ctx, on_finish); } -void ImageWatcher::notify_rename(const std::string &image_name, - Context *on_finish) { +template +void ImageWatcher::notify_rename(const std::string &image_name, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); @@ -307,7 +329,8 @@ void ImageWatcher::notify_rename(const std::string &image_name, notify_lock_owner(std::move(bl), on_finish); } -void ImageWatcher::notify_header_update(Context *on_finish) { +template +void ImageWatcher::notify_header_update(Context *on_finish) { ldout(m_image_ctx.cct, 10) << this << ": " << __func__ << dendl; // supports legacy (empty buffer) clients @@ -316,21 +339,24 @@ void ImageWatcher::notify_header_update(Context *on_finish) { m_notifier.notify(bl, nullptr, on_finish); } -void ImageWatcher::notify_header_update(librados::IoCtx &io_ctx, - const std::string &oid) { +template +void ImageWatcher::notify_header_update(librados::IoCtx &io_ctx, + const std::string &oid) { // supports legacy (empty buffer) clients bufferlist bl; ::encode(NotifyMessage(HeaderUpdatePayload()), bl); io_ctx.notify2(oid, bl, image_watcher::Notifier::NOTIFY_TIMEOUT, nullptr); } -void ImageWatcher::schedule_cancel_async_requests() { +template +void ImageWatcher::schedule_cancel_async_requests() { FunctionContext *ctx = new FunctionContext( - boost::bind(&ImageWatcher::cancel_async_requests, this)); + boost::bind(&ImageWatcher::cancel_async_requests, this)); m_task_finisher->queue(TASK_CODE_CANCEL_ASYNC_REQUESTS, ctx); } -void ImageWatcher::cancel_async_requests() { +template +void ImageWatcher::cancel_async_requests() { RWLock::WLocker l(m_async_request_lock); for (std::map::iterator iter = m_async_requests.begin(); @@ -340,19 +366,22 @@ void ImageWatcher::cancel_async_requests() { m_async_requests.clear(); } -void ImageWatcher::set_owner_client_id(const ClientId& client_id) { +template +void ImageWatcher::set_owner_client_id(const ClientId& client_id) { assert(m_owner_client_id_lock.is_locked()); m_owner_client_id = client_id; ldout(m_image_ctx.cct, 10) << this << " current lock owner: " << m_owner_client_id << dendl; } -ClientId ImageWatcher::get_client_id() { +template +ClientId ImageWatcher::get_client_id() { RWLock::RLocker l(m_watch_lock); return ClientId(m_image_ctx.md_ctx.get_instance_id(), m_watch_handle); } -void ImageWatcher::notify_acquired_lock() { +template +void ImageWatcher::notify_acquired_lock() { ldout(m_image_ctx.cct, 10) << this << " notify acquired lock" << dendl; ClientId client_id = get_client_id(); @@ -366,7 +395,8 @@ void ImageWatcher::notify_acquired_lock() { m_notifier.notify(bl, nullptr, nullptr); } -void ImageWatcher::notify_released_lock() { +template +void ImageWatcher::notify_released_lock() { ldout(m_image_ctx.cct, 10) << this << " notify released lock" << dendl; { @@ -379,7 +409,8 @@ void ImageWatcher::notify_released_lock() { m_notifier.notify(bl, nullptr, nullptr); } -void ImageWatcher::schedule_request_lock(bool use_timer, int timer_delay) { +template +void ImageWatcher::schedule_request_lock(bool use_timer, int timer_delay) { assert(m_image_ctx.owner_lock.is_locked()); if (m_image_ctx.exclusive_lock == nullptr) { @@ -394,7 +425,7 @@ void ImageWatcher::schedule_request_lock(bool use_timer, int timer_delay) { ldout(m_image_ctx.cct, 15) << this << " requesting exclusive lock" << dendl; FunctionContext *ctx = new FunctionContext( - boost::bind(&ImageWatcher::notify_request_lock, this)); + boost::bind(&ImageWatcher::notify_request_lock, this)); if (use_timer) { if (timer_delay < 0) { timer_delay = RETRY_DELAY_SECONDS; @@ -407,7 +438,8 @@ void ImageWatcher::schedule_request_lock(bool use_timer, int timer_delay) { } } -void ImageWatcher::notify_request_lock() { +template +void ImageWatcher::notify_request_lock() { RWLock::RLocker owner_locker(m_image_ctx.owner_lock); RWLock::RLocker snap_locker(m_image_ctx.snap_lock); @@ -422,10 +454,11 @@ void ImageWatcher::notify_request_lock() { bufferlist bl; ::encode(NotifyMessage(RequestLockPayload(get_client_id(), false)), bl); notify_lock_owner(std::move(bl), create_context_callback< - ImageWatcher, &ImageWatcher::handle_request_lock>(this)); + ImageWatcher, &ImageWatcher::handle_request_lock>(this)); } -void ImageWatcher::handle_request_lock(int r) { +template +void ImageWatcher::handle_request_lock(int r) { RWLock::RLocker owner_locker(m_image_ctx.owner_lock); RWLock::RLocker snap_locker(m_image_ctx.snap_lock); @@ -454,7 +487,8 @@ void ImageWatcher::handle_request_lock(int r) { } } -void ImageWatcher::notify_lock_owner(bufferlist &&bl, Context *on_finish) { +template +void ImageWatcher::notify_lock_owner(bufferlist &&bl, Context *on_finish) { assert(on_finish != nullptr); assert(m_image_ctx.owner_lock.is_locked()); NotifyLockOwner *notify_lock_owner = NotifyLockOwner::create( @@ -462,7 +496,8 @@ void ImageWatcher::notify_lock_owner(bufferlist &&bl, Context *on_finish) { notify_lock_owner->send(); } -Context *ImageWatcher::remove_async_request(const AsyncRequestId &id) { +template +Context *ImageWatcher::remove_async_request(const AsyncRequestId &id) { RWLock::WLocker async_request_locker(m_async_request_lock); auto it = m_async_requests.find(id); if (it != m_async_requests.end()) { @@ -473,12 +508,13 @@ Context *ImageWatcher::remove_async_request(const AsyncRequestId &id) { return nullptr; } -void ImageWatcher::schedule_async_request_timed_out(const AsyncRequestId &id) { +template +void ImageWatcher::schedule_async_request_timed_out(const AsyncRequestId &id) { ldout(m_image_ctx.cct, 20) << "scheduling async request time out: " << id << dendl; Context *ctx = new FunctionContext(boost::bind( - &ImageWatcher::async_request_timed_out, this, id)); + &ImageWatcher::async_request_timed_out, this, id)); Task task(TASK_CODE_ASYNC_REQUEST, id); m_task_finisher->cancel(task); @@ -486,7 +522,8 @@ void ImageWatcher::schedule_async_request_timed_out(const AsyncRequestId &id) { m_task_finisher->add_event_after(task, m_image_ctx.request_timed_out_seconds, ctx); } -void ImageWatcher::async_request_timed_out(const AsyncRequestId &id) { +template +void ImageWatcher::async_request_timed_out(const AsyncRequestId &id) { Context *on_complete = remove_async_request(id); if (on_complete != nullptr) { ldout(m_image_ctx.cct, 5) << "async request timed out: " << id << dendl; @@ -494,8 +531,9 @@ void ImageWatcher::async_request_timed_out(const AsyncRequestId &id) { } } -void ImageWatcher::notify_async_request(const AsyncRequestId &async_request_id, - bufferlist &&in, +template +void ImageWatcher::notify_async_request(const AsyncRequestId &async_request_id, + bufferlist &&in, ProgressContext& prog_ctx, Context *on_finish) { assert(on_finish != nullptr); @@ -528,9 +566,10 @@ void ImageWatcher::notify_async_request(const AsyncRequestId &async_request_id, notify_lock_owner(std::move(in), on_notify); } -int ImageWatcher::prepare_async_request(const AsyncRequestId& async_request_id, - bool* new_request, Context** ctx, - ProgressContext** prog_ctx) { +template +int ImageWatcher::prepare_async_request(const AsyncRequestId& async_request_id, + bool* new_request, Context** ctx, + ProgressContext** prog_ctx) { if (async_request_id.client_id == get_client_id()) { return -ERESTART; } else { @@ -547,8 +586,9 @@ int ImageWatcher::prepare_async_request(const AsyncRequestId& async_request_id, return 0; } -bool ImageWatcher::handle_payload(const HeaderUpdatePayload &payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const HeaderUpdatePayload &payload, + C_NotifyAck *ack_ctx) { ldout(m_image_ctx.cct, 10) << this << " image header updated" << dendl; m_image_ctx.state->handle_update_notification(); @@ -560,8 +600,9 @@ bool ImageWatcher::handle_payload(const HeaderUpdatePayload &payload, return true; } -bool ImageWatcher::handle_payload(const AcquiredLockPayload &payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const AcquiredLockPayload &payload, + C_NotifyAck *ack_ctx) { ldout(m_image_ctx.cct, 10) << this << " image exclusively locked announcement" << dendl; @@ -583,8 +624,9 @@ bool ImageWatcher::handle_payload(const AcquiredLockPayload &payload, return true; } -bool ImageWatcher::handle_payload(const ReleasedLockPayload &payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const ReleasedLockPayload &payload, + C_NotifyAck *ack_ctx) { ldout(m_image_ctx.cct, 10) << this << " exclusive lock released" << dendl; bool cancel_async_requests = true; @@ -616,8 +658,9 @@ bool ImageWatcher::handle_payload(const ReleasedLockPayload &payload, return true; } -bool ImageWatcher::handle_payload(const RequestLockPayload &payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const RequestLockPayload &payload, + C_NotifyAck *ack_ctx) { ldout(m_image_ctx.cct, 10) << this << " exclusive lock requested" << dendl; if (payload.client_id == get_client_id()) { return true; @@ -647,8 +690,9 @@ bool ImageWatcher::handle_payload(const RequestLockPayload &payload, return true; } -bool ImageWatcher::handle_payload(const AsyncProgressPayload &payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const AsyncProgressPayload &payload, + C_NotifyAck *ack_ctx) { RWLock::RLocker l(m_async_request_lock); std::map::iterator req_it = m_async_requests.find(payload.async_request_id); @@ -663,8 +707,9 @@ bool ImageWatcher::handle_payload(const AsyncProgressPayload &payload, return true; } -bool ImageWatcher::handle_payload(const AsyncCompletePayload &payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const AsyncCompletePayload &payload, + C_NotifyAck *ack_ctx) { Context *on_complete = remove_async_request(payload.async_request_id); if (on_complete != nullptr) { ldout(m_image_ctx.cct, 10) << this << " request finished: " @@ -675,8 +720,9 @@ bool ImageWatcher::handle_payload(const AsyncCompletePayload &payload, return true; } -bool ImageWatcher::handle_payload(const FlattenPayload &payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const FlattenPayload &payload, + C_NotifyAck *ack_ctx) { RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr) { @@ -701,8 +747,9 @@ bool ImageWatcher::handle_payload(const FlattenPayload &payload, return true; } -bool ImageWatcher::handle_payload(const ResizePayload &payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const ResizePayload &payload, + C_NotifyAck *ack_ctx) { RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr) { int r; @@ -727,8 +774,9 @@ bool ImageWatcher::handle_payload(const ResizePayload &payload, return true; } -bool ImageWatcher::handle_payload(const SnapCreatePayload &payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const SnapCreatePayload &payload, + C_NotifyAck *ack_ctx) { RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr) { int r; @@ -747,8 +795,9 @@ bool ImageWatcher::handle_payload(const SnapCreatePayload &payload, return true; } -bool ImageWatcher::handle_payload(const SnapRenamePayload &payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const SnapRenamePayload &payload, + C_NotifyAck *ack_ctx) { RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr) { int r; @@ -768,8 +817,9 @@ bool ImageWatcher::handle_payload(const SnapRenamePayload &payload, return true; } -bool ImageWatcher::handle_payload(const SnapRemovePayload &payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const SnapRemovePayload &payload, + C_NotifyAck *ack_ctx) { RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr) { int r; @@ -787,8 +837,9 @@ bool ImageWatcher::handle_payload(const SnapRemovePayload &payload, return true; } -bool ImageWatcher::handle_payload(const SnapProtectPayload& payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const SnapProtectPayload& payload, + C_NotifyAck *ack_ctx) { RWLock::RLocker owner_locker(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr) { int r; @@ -806,8 +857,9 @@ bool ImageWatcher::handle_payload(const SnapProtectPayload& payload, return true; } -bool ImageWatcher::handle_payload(const SnapUnprotectPayload& payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const SnapUnprotectPayload& payload, + C_NotifyAck *ack_ctx) { RWLock::RLocker owner_locker(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr) { int r; @@ -825,8 +877,9 @@ bool ImageWatcher::handle_payload(const SnapUnprotectPayload& payload, return true; } -bool ImageWatcher::handle_payload(const RebuildObjectMapPayload& payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const RebuildObjectMapPayload& payload, + C_NotifyAck *ack_ctx) { RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr) { int r; @@ -851,8 +904,9 @@ bool ImageWatcher::handle_payload(const RebuildObjectMapPayload& payload, return true; } -bool ImageWatcher::handle_payload(const RenamePayload& payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const RenamePayload& payload, + C_NotifyAck *ack_ctx) { RWLock::RLocker owner_locker(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr) { int r; @@ -870,8 +924,9 @@ bool ImageWatcher::handle_payload(const RenamePayload& payload, return true; } -bool ImageWatcher::handle_payload(const UnknownPayload &payload, - C_NotifyAck *ack_ctx) { +template +bool ImageWatcher::handle_payload(const UnknownPayload &payload, + C_NotifyAck *ack_ctx) { RWLock::RLocker l(m_image_ctx.owner_lock); if (m_image_ctx.exclusive_lock != nullptr) { int r; @@ -882,8 +937,9 @@ bool ImageWatcher::handle_payload(const UnknownPayload &payload, return true; } -void ImageWatcher::process_payload(uint64_t notify_id, uint64_t handle, - const Payload &payload, int r) { +template +void ImageWatcher::process_payload(uint64_t notify_id, uint64_t handle, + const Payload &payload, int r) { if (r < 0) { bufferlist out_bl; acknowledge_notify(notify_id, handle, out_bl); @@ -892,8 +948,9 @@ void ImageWatcher::process_payload(uint64_t notify_id, uint64_t handle, } } -void ImageWatcher::handle_notify(uint64_t notify_id, uint64_t handle, - bufferlist &bl) { +template +void ImageWatcher::handle_notify(uint64_t notify_id, uint64_t handle, + bufferlist &bl) { NotifyMessage notify_message; if (bl.length() == 0) { // legacy notification for header updates @@ -919,7 +976,8 @@ void ImageWatcher::handle_notify(uint64_t notify_id, uint64_t handle, } } -void ImageWatcher::handle_error(uint64_t handle, int err) { +template +void ImageWatcher::handle_error(uint64_t handle, int err) { lderr(m_image_ctx.cct) << this << " image watch failed: " << handle << ", " << cpp_strerror(err) << dendl; @@ -934,17 +992,19 @@ void ImageWatcher::handle_error(uint64_t handle, int err) { m_watch_state = WATCH_STATE_ERROR; FunctionContext *ctx = new FunctionContext( - boost::bind(&ImageWatcher::reregister_watch, this)); + boost::bind(&ImageWatcher::reregister_watch, this)); m_task_finisher->queue(TASK_CODE_REREGISTER_WATCH, ctx); } } -void ImageWatcher::acknowledge_notify(uint64_t notify_id, uint64_t handle, - bufferlist &out) { +template +void ImageWatcher::acknowledge_notify(uint64_t notify_id, uint64_t handle, + bufferlist &out) { m_image_ctx.md_ctx.notify_ack(m_image_ctx.header_oid, notify_id, handle, out); } -void ImageWatcher::reregister_watch() { +template +void ImageWatcher::reregister_watch() { ldout(m_image_ctx.cct, 10) << this << " re-registering image watch" << dendl; bool releasing_lock = false; @@ -981,7 +1041,7 @@ void ImageWatcher::reregister_watch() { << cpp_strerror(r) << dendl; if (r != -ESHUTDOWN) { FunctionContext *ctx = new FunctionContext(boost::bind( - &ImageWatcher::reregister_watch, this)); + &ImageWatcher::reregister_watch, this)); m_task_finisher->add_event_after(TASK_CODE_REREGISTER_WATCH, RETRY_DELAY_SECONDS, ctx); } @@ -993,30 +1053,35 @@ void ImageWatcher::reregister_watch() { handle_payload(HeaderUpdatePayload(), NULL); } -void ImageWatcher::WatchCtx::handle_notify(uint64_t notify_id, - uint64_t handle, - uint64_t notifier_id, - bufferlist& bl) { +template +void ImageWatcher::WatchCtx::handle_notify(uint64_t notify_id, + uint64_t handle, + uint64_t notifier_id, + bufferlist& bl) { image_watcher.handle_notify(notify_id, handle, bl); } -void ImageWatcher::WatchCtx::handle_error(uint64_t handle, int err) { +template +void ImageWatcher::WatchCtx::handle_error(uint64_t handle, int err) { image_watcher.handle_error(handle, err); } -void ImageWatcher::RemoteContext::finish(int r) { +template +void ImageWatcher::RemoteContext::finish(int r) { m_image_watcher.schedule_async_complete(m_async_request_id, r); } -ImageWatcher::C_NotifyAck::C_NotifyAck(ImageWatcher *image_watcher, - uint64_t notify_id, uint64_t handle) +template +ImageWatcher::C_NotifyAck::C_NotifyAck(ImageWatcher *image_watcher, + uint64_t notify_id, uint64_t handle) : image_watcher(image_watcher), notify_id(notify_id), handle(handle) { CephContext *cct = image_watcher->m_image_ctx.cct; ldout(cct, 10) << this << " C_NotifyAck start: id=" << notify_id << ", " << "handle=" << handle << dendl; } -void ImageWatcher::C_NotifyAck::finish(int r) { +template +void ImageWatcher::C_NotifyAck::finish(int r) { assert(r == 0); CephContext *cct = image_watcher->m_image_ctx.cct; ldout(cct, 10) << this << " C_NotifyAck finish: id=" << notify_id << ", " @@ -1025,7 +1090,8 @@ void ImageWatcher::C_NotifyAck::finish(int r) { image_watcher->acknowledge_notify(notify_id, handle, out); } -void ImageWatcher::C_ResponseMessage::finish(int r) { +template +void ImageWatcher::C_ResponseMessage::finish(int r) { CephContext *cct = notify_ack->image_watcher->m_image_ctx.cct; ldout(cct, 10) << this << " C_ResponseMessage: r=" << r << dendl; @@ -1034,3 +1100,5 @@ void ImageWatcher::C_ResponseMessage::finish(int r) { } } // namespace librbd + +template class librbd::ImageWatcher; diff --git a/src/librbd/ImageWatcher.h b/src/librbd/ImageWatcher.h index 5182a972772d3..e72eea725e622 100644 --- a/src/librbd/ImageWatcher.h +++ b/src/librbd/ImageWatcher.h @@ -22,9 +22,10 @@ namespace librbd { class ImageCtx; template class TaskFinisher; +template class ImageWatcher { public: - ImageWatcher(ImageCtx& image_ctx); + ImageWatcher(ImageCtxT& image_ctx); ~ImageWatcher(); void register_watch(Context *on_finish); @@ -219,7 +220,7 @@ private: } }; - ImageCtx &m_image_ctx; + ImageCtxT &m_image_ctx; mutable RWLock m_watch_lock; WatchCtx m_watch_ctx; @@ -314,4 +315,6 @@ private: } // namespace librbd +extern template class librbd::ImageWatcher; + #endif // CEPH_LIBRBD_IMAGE_WATCHER_H diff --git a/src/librbd/Operations.cc b/src/librbd/Operations.cc index 90bc53a96582c..0c6d8cdb80c58 100644 --- a/src/librbd/Operations.cc +++ b/src/librbd/Operations.cc @@ -311,7 +311,7 @@ int Operations::flatten(ProgressContext &prog_ctx) { r = invoke_async_request("flatten", false, boost::bind(&Operations::execute_flatten, this, boost::ref(prog_ctx), _1), - boost::bind(&ImageWatcher::notify_flatten, + boost::bind(&ImageWatcher::notify_flatten, m_image_ctx.image_watcher, request_id, boost::ref(prog_ctx), _1)); @@ -391,7 +391,7 @@ int Operations::rebuild_object_map(ProgressContext &prog_ctx) { r = invoke_async_request("rebuild object map", true, boost::bind(&Operations::execute_rebuild_object_map, this, boost::ref(prog_ctx), _1), - boost::bind(&ImageWatcher::notify_rebuild_object_map, + boost::bind(&ImageWatcher::notify_rebuild_object_map, m_image_ctx.image_watcher, request_id, boost::ref(prog_ctx), _1)); @@ -448,7 +448,7 @@ int Operations::rename(const char *dstname) { r = invoke_async_request("rename", true, boost::bind(&Operations::execute_rename, this, dstname, _1), - boost::bind(&ImageWatcher::notify_rename, + boost::bind(&ImageWatcher::notify_rename, m_image_ctx.image_watcher, dstname, _1)); if (r < 0 && r != -EEXIST) { @@ -534,7 +534,7 @@ int Operations::resize(uint64_t size, ProgressContext& prog_ctx) { r = invoke_async_request("resize", false, boost::bind(&Operations::execute_resize, this, size, boost::ref(prog_ctx), _1, 0), - boost::bind(&ImageWatcher::notify_resize, + boost::bind(&ImageWatcher::notify_resize, m_image_ctx.image_watcher, request_id, size, boost::ref(prog_ctx), _1)); @@ -622,7 +622,7 @@ void Operations::snap_create(const char *snap_name, Context *on_finish) { m_image_ctx, "snap_create", true, boost::bind(&Operations::execute_snap_create, this, snap_name, _1, 0, false), - boost::bind(&ImageWatcher::notify_snap_create, m_image_ctx.image_watcher, + boost::bind(&ImageWatcher::notify_snap_create, m_image_ctx.image_watcher, snap_name, _1), {-EEXIST}, on_finish); req->send(); @@ -785,7 +785,7 @@ void Operations::snap_remove(const char *snap_name, Context *on_finish) { C_InvokeAsyncRequest *req = new C_InvokeAsyncRequest( m_image_ctx, "snap_remove", true, boost::bind(&Operations::execute_snap_remove, this, snap_name, _1), - boost::bind(&ImageWatcher::notify_snap_remove, m_image_ctx.image_watcher, + boost::bind(&ImageWatcher::notify_snap_remove, m_image_ctx.image_watcher, snap_name, _1), {-ENOENT}, on_finish); req->send(); @@ -871,7 +871,7 @@ int Operations::snap_rename(const char *srcname, const char *dstname) { r = invoke_async_request("snap_rename", true, boost::bind(&Operations::execute_snap_rename, this, snap_id, dstname, _1), - boost::bind(&ImageWatcher::notify_snap_rename, + boost::bind(&ImageWatcher::notify_snap_rename, m_image_ctx.image_watcher, snap_id, dstname, _1)); if (r < 0 && r != -EEXIST) { @@ -955,7 +955,7 @@ int Operations::snap_protect(const char *snap_name) { r = invoke_async_request("snap_protect", true, boost::bind(&Operations::execute_snap_protect, this, snap_name, _1), - boost::bind(&ImageWatcher::notify_snap_protect, + boost::bind(&ImageWatcher::notify_snap_protect, m_image_ctx.image_watcher, snap_name, _1)); if (r < 0 && r != -EBUSY) { @@ -1041,7 +1041,7 @@ int Operations::snap_unprotect(const char *snap_name) { r = invoke_async_request("snap_unprotect", true, boost::bind(&Operations::execute_snap_unprotect, this, snap_name, _1), - boost::bind(&ImageWatcher::notify_snap_unprotect, + boost::bind(&ImageWatcher::notify_snap_unprotect, m_image_ctx.image_watcher, snap_name, _1)); if (r < 0 && r != -EINVAL) { -- 2.39.5