]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: convert ImageWatcher class to template
authorJason Dillaman <dillaman@redhat.com>
Thu, 4 Aug 2016 17:47:33 +0000 (13:47 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 23 Aug 2016 13:15:08 +0000 (09:15 -0400)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 814c305ce8c35b5ce01d7e29a912d5ef3978754b)

 Conflicts:
src/librbd/ImageWatcher.cc: no shrink guard
src/librbd/Operations.cc: no shrink guard

src/librbd/ImageCtx.cc
src/librbd/ImageCtx.h
src/librbd/ImageWatcher.cc
src/librbd/ImageWatcher.h
src/librbd/Operations.cc

index f88d32d63b56334550f3b9c59fbb6ad3c8d8d8e1..edce967b3063e6b1860841eed4b8757301ea5fbb 100644 (file)
@@ -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) {
index 709987f7a33d6e93643de33f6582c812aa4394e0..5c992e70730a0b6fee6ff42cc124e8b76d995ea9 100644 (file)
@@ -42,7 +42,7 @@ namespace librbd {
   class CopyupRequest;
   template <typename> class ExclusiveLock;
   template <typename> class ImageState;
-  class ImageWatcher;
+  template <typename> class ImageWatcher;
   template <typename> 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<ImageCtx> *image_watcher;
     Journal<ImageCtx> *journal;
 
     /**
index 78e2585ca302653f1fc47d68e1975051d996f83d..ef5cdf1102eeb2626113df3dd6d4b94ed5855411 100644 (file)
@@ -68,7 +68,8 @@ struct C_UnwatchAndFlush : public Context {
 
 static const double    RETRY_DELAY_SECONDS = 1.0;
 
-ImageWatcher::ImageWatcher(ImageCtx &image_ctx)
+template <typename I>
+ImageWatcher<I>::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 <typename I>
+ImageWatcher<I>::~ImageWatcher()
 {
   delete m_task_finisher;
   {
@@ -89,7 +91,8 @@ ImageWatcher::~ImageWatcher()
   }
 }
 
-void ImageWatcher::register_watch(Context *on_finish) {
+template <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::flush(Context *on_finish) {
   m_notifier.flush(on_finish);
 }
 
-void ImageWatcher::schedule_async_progress(const AsyncRequestId &request,
-                                          uint64_t offset, uint64_t total) {
+template <typename I>
+void ImageWatcher<I>::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<I>::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 <typename I>
+int ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::schedule_async_complete(const AsyncRequestId &request,
+                                              int r) {
   FunctionContext *ctx = new FunctionContext(
-    boost::bind(&ImageWatcher::notify_async_complete, this, request, r));
+    boost::bind(&ImageWatcher<I>::notify_async_complete, this, request, r));
   m_task_finisher->queue(ctx);
 }
 
-void ImageWatcher::notify_async_complete(const AsyncRequestId &request, int r) {
+template <typename I>
+void ImageWatcher<I>::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<I>::handle_async_complete, this, request, r,
+                _1)));
 }
 
-void ImageWatcher::handle_async_complete(const AsyncRequestId &request, int r,
-                                         int ret_val) {
+template <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::schedule_cancel_async_requests() {
   FunctionContext *ctx = new FunctionContext(
-    boost::bind(&ImageWatcher::cancel_async_requests, this));
+    boost::bind(&ImageWatcher<I>::cancel_async_requests, this));
   m_task_finisher->queue(TASK_CODE_CANCEL_ASYNC_REQUESTS, ctx);
 }
 
-void ImageWatcher::cancel_async_requests() {
+template <typename I>
+void ImageWatcher<I>::cancel_async_requests() {
   RWLock::WLocker l(m_async_request_lock);
   for (std::map<AsyncRequestId, AsyncRequest>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+ClientId ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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<I>::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 <typename I>
+void ImageWatcher<I>::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<I>::handle_request_lock>(this));
 }
 
-void ImageWatcher::handle_request_lock(int r) {
+template <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+Context *ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+int ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::handle_payload(const AsyncProgressPayload &payload,
+                                     C_NotifyAck *ack_ctx) {
   RWLock::RLocker l(m_async_request_lock);
   std::map<AsyncRequestId, AsyncRequest>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+bool ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::WatchCtx::handle_error(uint64_t handle, int err) {
   image_watcher.handle_error(handle, err);
 }
 
-void ImageWatcher::RemoteContext::finish(int r) {
+template <typename I>
+void ImageWatcher<I>::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 <typename I>
+ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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 <typename I>
+void ImageWatcher<I>::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<librbd::ImageCtx>;
index 5182a972772d314d51271b1656d46598cde8c471..e72eea725e622ddb1bce51468700a10b0e9e5251 100644 (file)
@@ -22,9 +22,10 @@ namespace librbd {
 class ImageCtx;
 template <typename T> class TaskFinisher;
 
+template <typename ImageCtxT = ImageCtx>
 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<librbd::ImageCtx>;
+
 #endif // CEPH_LIBRBD_IMAGE_WATCHER_H
index 90bc53a96582cc9d1fd8415302f231b50e771f9e..0c6d8cdb80c58c0cff549fd7a10538462433160f 100644 (file)
@@ -311,7 +311,7 @@ int Operations<I>::flatten(ProgressContext &prog_ctx) {
   r = invoke_async_request("flatten", false,
                            boost::bind(&Operations<I>::execute_flatten, this,
                                        boost::ref(prog_ctx), _1),
-                           boost::bind(&ImageWatcher::notify_flatten,
+                           boost::bind(&ImageWatcher<I>::notify_flatten,
                                        m_image_ctx.image_watcher, request_id,
                                        boost::ref(prog_ctx), _1));
 
@@ -391,7 +391,7 @@ int Operations<I>::rebuild_object_map(ProgressContext &prog_ctx) {
   r = invoke_async_request("rebuild object map", true,
                            boost::bind(&Operations<I>::execute_rebuild_object_map,
                                        this, boost::ref(prog_ctx), _1),
-                           boost::bind(&ImageWatcher::notify_rebuild_object_map,
+                           boost::bind(&ImageWatcher<I>::notify_rebuild_object_map,
                                        m_image_ctx.image_watcher, request_id,
                                        boost::ref(prog_ctx), _1));
 
@@ -448,7 +448,7 @@ int Operations<I>::rename(const char *dstname) {
     r = invoke_async_request("rename", true,
                              boost::bind(&Operations<I>::execute_rename, this,
                                          dstname, _1),
-                             boost::bind(&ImageWatcher::notify_rename,
+                             boost::bind(&ImageWatcher<I>::notify_rename,
                                          m_image_ctx.image_watcher, dstname,
                                          _1));
     if (r < 0 && r != -EEXIST) {
@@ -534,7 +534,7 @@ int Operations<I>::resize(uint64_t size, ProgressContext& prog_ctx) {
   r = invoke_async_request("resize", false,
                            boost::bind(&Operations<I>::execute_resize, this,
                                        size, boost::ref(prog_ctx), _1, 0),
-                           boost::bind(&ImageWatcher::notify_resize,
+                           boost::bind(&ImageWatcher<I>::notify_resize,
                                        m_image_ctx.image_watcher, request_id,
                                        size, boost::ref(prog_ctx), _1));
 
@@ -622,7 +622,7 @@ void Operations<I>::snap_create(const char *snap_name, Context *on_finish) {
     m_image_ctx, "snap_create", true,
     boost::bind(&Operations<I>::execute_snap_create, this, snap_name, _1, 0,
                 false),
-    boost::bind(&ImageWatcher::notify_snap_create, m_image_ctx.image_watcher,
+    boost::bind(&ImageWatcher<I>::notify_snap_create, m_image_ctx.image_watcher,
                 snap_name, _1),
     {-EEXIST}, on_finish);
   req->send();
@@ -785,7 +785,7 @@ void Operations<I>::snap_remove(const char *snap_name, Context *on_finish) {
     C_InvokeAsyncRequest<I> *req = new C_InvokeAsyncRequest<I>(
       m_image_ctx, "snap_remove", true,
       boost::bind(&Operations<I>::execute_snap_remove, this, snap_name, _1),
-      boost::bind(&ImageWatcher::notify_snap_remove, m_image_ctx.image_watcher,
+      boost::bind(&ImageWatcher<I>::notify_snap_remove, m_image_ctx.image_watcher,
                   snap_name, _1),
       {-ENOENT}, on_finish);
     req->send();
@@ -871,7 +871,7 @@ int Operations<I>::snap_rename(const char *srcname, const char *dstname) {
     r = invoke_async_request("snap_rename", true,
                              boost::bind(&Operations<I>::execute_snap_rename,
                                          this, snap_id, dstname, _1),
-                             boost::bind(&ImageWatcher::notify_snap_rename,
+                             boost::bind(&ImageWatcher<I>::notify_snap_rename,
                                          m_image_ctx.image_watcher, snap_id,
                                          dstname, _1));
     if (r < 0 && r != -EEXIST) {
@@ -955,7 +955,7 @@ int Operations<I>::snap_protect(const char *snap_name) {
     r = invoke_async_request("snap_protect", true,
                              boost::bind(&Operations<I>::execute_snap_protect,
                                          this, snap_name, _1),
-                             boost::bind(&ImageWatcher::notify_snap_protect,
+                             boost::bind(&ImageWatcher<I>::notify_snap_protect,
                                          m_image_ctx.image_watcher, snap_name,
                                          _1));
     if (r < 0 && r != -EBUSY) {
@@ -1041,7 +1041,7 @@ int Operations<I>::snap_unprotect(const char *snap_name) {
     r = invoke_async_request("snap_unprotect", true,
                              boost::bind(&Operations<I>::execute_snap_unprotect,
                                          this, snap_name, _1),
-                             boost::bind(&ImageWatcher::notify_snap_unprotect,
+                             boost::bind(&ImageWatcher<I>::notify_snap_unprotect,
                                          m_image_ctx.image_watcher, snap_name,
                                          _1));
     if (r < 0 && r != -EINVAL) {