// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
+
#include "librbd/ImageWatcher.h"
#include "librbd/AioCompletion.h"
#include "librbd/ExclusiveLock.h"
bufferlist bl;
::encode(NotifyMessage(AsyncProgressPayload(request, offset, total)), bl);
-
- m_image_ctx.md_ctx.notify2(m_image_ctx.header_oid, bl, NOTIFY_TIMEOUT, NULL);
+ m_image_ctx.md_ctx.notify2(m_image_ctx.header_oid, bl,
+ Notifier::NOTIFY_TIMEOUT, NULL);
return 0;
}
::encode(NotifyMessage(AsyncCompletePayload(request, r)), bl);
if (r >= 0) {
- librbd::notify_change(m_image_ctx.md_ctx, m_image_ctx.header_oid,
- &m_image_ctx);
+ m_image_ctx.notify_update();
}
int ret = m_image_ctx.md_ctx.notify2(m_image_ctx.header_oid, bl,
Notifier::NOTIFY_TIMEOUT, NULL);
return notify_lock_owner(bl);
}
-void ImageWatcher::notify_header_update(librados::IoCtx &io_ctx,
- const std::string &oid)
-{
+void ImageWatcher::notify_header_update(Context *on_finish) {
// supports legacy (empty buffer) clients
bufferlist bl;
::encode(NotifyMessage(HeaderUpdatePayload()), bl);
-
- io_ctx.notify2(oid, bl, NOTIFY_TIMEOUT, NULL);
+ m_notifier.notify(bl, nullptr, on_finish);
}
void ImageWatcher::schedule_cancel_async_requests() {
bufferlist bl;
::encode(NotifyMessage(AcquiredLockPayload(client_id)), bl);
- m_image_ctx.md_ctx.notify2(m_image_ctx.header_oid, bl, NOTIFY_TIMEOUT, NULL);
+ m_image_ctx.md_ctx.notify2(m_image_ctx.header_oid, bl,
+ Notifier::NOTIFY_TIMEOUT, NULL);
}
void ImageWatcher::notify_released_lock() {
bufferlist bl;
::encode(NotifyMessage(ReleasedLockPayload(get_client_id())), bl);
- m_image_ctx.md_ctx.notify2(m_image_ctx.header_oid, bl, NOTIFY_TIMEOUT, NULL);
+ m_image_ctx.md_ctx.notify2(m_image_ctx.header_oid, bl,
+ Notifier::NOTIFY_TIMEOUT, NULL);
}
void ImageWatcher::schedule_request_lock(bool use_timer, int timer_delay) {
namespace librbd {
+namespace {
+
+template <typename I>
+struct C_NotifyUpdate : public Context {
+ I &image_ctx;
+ Context *on_finish;
+ bool notified = false;
+
+ C_NotifyUpdate(I &image_ctx, Context *on_finish)
+ : image_ctx(image_ctx), on_finish(on_finish) {
+ }
+
+ virtual void complete(int r) override {
+ if (r < 0 || notified) {
+ Context::complete(r);
+ } else {
+ notified = true;
+ image_ctx.notify_update(this);
+ }
+ }
+ virtual void finish(int r) override {
+ on_finish->complete(r);
+ }
+};
+
+} // anonymous namespace
+
template <typename I>
Operations<I>::Operations(I &image_ctx) : m_image_ctx(image_ctx) {
}
if (r < 0 && r != -EINVAL) {
return r;
}
-
- notify_change();
ldout(cct, 20) << "flatten finished" << dendl;
return 0;
}
}
operation::FlattenRequest<I> *req = new operation::FlattenRequest<I>(
- m_image_ctx, on_finish, object_size, overlap_objects, snapc, prog_ctx);
+ m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), object_size,
+ overlap_objects, snapc, prog_ctx);
req->send();
}
if (r < 0) {
return r;
}
-
- notify_change();
return 0;
}
}
operation::RebuildObjectMapRequest<I> *req =
- new operation::RebuildObjectMapRequest<I>(m_image_ctx, on_finish, prog_ctx);
+ new operation::RebuildObjectMapRequest<I>(
+ m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), prog_ctx);
req->send();
}
return r;
}
}
-
- if (m_image_ctx.old_format) {
- notify_change();
- }
return 0;
}
ldout(cct, 5) << this << " " << __func__ << ": dest_name=" << dstname
<< dendl;
- operation::RenameRequest<I> *req =
- new operation::RenameRequest<I>(m_image_ctx, on_finish, dstname);
+ if (m_image_ctx.old_format) {
+ on_finish = new C_NotifyUpdate<I>(m_image_ctx, on_finish);
+ }
+ operation::RenameRequest<I> *req = new operation::RenameRequest<I>(
+ m_image_ctx, on_finish, dstname);
req->send();
}
size, boost::ref(prog_ctx)));
m_image_ctx.perfcounter->inc(l_librbd_resize);
- notify_change();
ldout(cct, 2) << "resize finished" << dendl;
return r;
}
}
operation::ResizeRequest<I> *req = new operation::ResizeRequest<I>(
- m_image_ctx, on_finish, size, prog_ctx, journal_op_tid, false);
+ m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), size, prog_ctx,
+ journal_op_tid, false);
req->send();
}
}
m_image_ctx.perfcounter->inc(l_librbd_snap_create);
- notify_change();
return 0;
}
<< dendl;
operation::SnapshotCreateRequest<I> *req =
- new operation::SnapshotCreateRequest<I>(m_image_ctx, on_finish, snap_name,
- journal_op_tid);
+ new operation::SnapshotCreateRequest<I>(
+ m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), snap_name,
+ journal_op_tid);
req->send();
}
}
m_image_ctx.perfcounter->inc(l_librbd_snap_rollback);
- notify_change();
return r;
}
// async mode used for journal replay
operation::SnapshotRollbackRequest<I> *request =
- new operation::SnapshotRollbackRequest<I>(m_image_ctx, on_finish, snap_name,
- snap_id, new_size, prog_ctx);
+ new operation::SnapshotRollbackRequest<I>(
+ m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), snap_name,
+ snap_id, new_size, prog_ctx);
request->send();
}
}
m_image_ctx.perfcounter->inc(l_librbd_snap_remove);
- notify_change();
return 0;
}
}
operation::SnapshotRemoveRequest<I> *req =
- new operation::SnapshotRemoveRequest<I>(m_image_ctx, on_finish, snap_name,
- snap_id);
+ new operation::SnapshotRemoveRequest<I>(
+ m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), snap_name,
+ snap_id);
req->send();
}
}
m_image_ctx.perfcounter->inc(l_librbd_snap_rename);
- notify_change();
return 0;
}
<< "new_snap_name=" << dst_name << dendl;
operation::SnapshotRenameRequest<I> *req =
- new operation::SnapshotRenameRequest<I>(m_image_ctx, on_finish, src_snap_id,
- dst_name);
+ new operation::SnapshotRenameRequest<I>(
+ m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), src_snap_id,
+ dst_name);
req->send();
}
return r;
}
}
-
- notify_change();
return 0;
}
<< dendl;
operation::SnapshotProtectRequest<I> *request =
- new operation::SnapshotProtectRequest<I>(m_image_ctx, on_finish, snap_name);
+ new operation::SnapshotProtectRequest<I>(
+ m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), snap_name);
request->send();
}
return r;
}
}
-
- notify_change();
return 0;
}
<< dendl;
operation::SnapshotUnprotectRequest<I> *request =
- new operation::SnapshotUnprotectRequest<I>(m_image_ctx, on_finish,
- snap_name);
+ new operation::SnapshotUnprotectRequest<I>(
+ m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), snap_name);
request->send();
}
return r;
}
-template <typename I>
-void Operations<I>::notify_change() {
- m_image_ctx.state->handle_update_notification();
- ImageWatcher::notify_header_update(m_image_ctx.md_ctx,
- m_image_ctx.header_oid);
-}
-
} // namespace librbd
template class librbd::Operations<librbd::ImageCtx>;