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),
{
}
-ImageWatcher::~ImageWatcher()
+template <typename I>
+ImageWatcher<I>::~ImageWatcher()
{
delete m_task_finisher;
{
}
}
-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);
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) {
}
}
-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();
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;
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;
}
}
-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());
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());
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());
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 &&
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());
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());
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());
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());
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());
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
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();
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();
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;
{
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) {
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;
}
}
-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);
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);
}
}
-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(
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()) {
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);
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;
}
}
-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);
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 {
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();
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;
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;
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;
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);
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: "
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) {
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;
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;
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;
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;
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;
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;
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;
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;
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;
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);
}
}
-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
}
}
-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;
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;
<< 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);
}
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 << ", "
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;
}
} // namespace librbd
+
+template class librbd::ImageWatcher<librbd::ImageCtx>;