namespace mirror {
using namespace image_sync;
+using librbd::util::create_async_context_callback;
using librbd::util::create_context_callback;
using librbd::util::unique_lock_name;
dout(10) << dendl;
- Context *ctx = create_context_callback<
- ImageSync<I>, &ImageSync<I>::handle_notify_sync_request>(this);
+ m_lock.Lock();
+ if (m_canceled) {
+ m_lock.Unlock();
+ BaseRequest::finish(-ECANCELED);
+ return;
+ }
+
+ Context *ctx = create_async_context_callback(
+ m_work_queue, create_context_callback<
+ ImageSync<I>, &ImageSync<I>::handle_notify_sync_request>(this));
m_instance_watcher->notify_sync_request(m_local_image_ctx->id, ctx);
+ m_lock.Unlock();
}
template <typename I>
void ImageSync<I>::handle_notify_sync_request(int r) {
dout(10) << ": r=" << r << dendl;
+ m_lock.Lock();
+ if (r == 0 && m_canceled) {
+ r = -ECANCELED;
+ }
+ m_lock.Unlock();
+
if (r < 0) {
BaseRequest::finish(r);
return;
template <typename I>
void InstanceWatcher<I>::notify_sync_complete(const std::string &sync_id) {
- dout(10) << "sync_id=" << sync_id << dendl;
-
Mutex::Locker locker(m_lock);
+ notify_sync_complete(m_lock, sync_id);
+}
+
+template <typename I>
+void InstanceWatcher<I>::notify_sync_complete(const Mutex&,
+ const std::string &sync_id) {
+ dout(10) << "sync_id=" << sync_id << dendl;
+ assert(m_lock.is_locked());
auto it = m_inflight_sync_reqs.find(sync_id);
assert(it != m_inflight_sync_reqs.end());
Context *on_start = nullptr;
{
Mutex::Locker locker(m_lock);
-
assert(sync_ctx->req != nullptr);
assert(sync_ctx->on_start != nullptr);
std::swap(sync_ctx->on_start, on_start);
sync_ctx->req = nullptr;
+
+ if (r == -ECANCELED) {
+ notify_sync_complete(m_lock, sync_ctx->sync_id);
+ }
}
on_start->complete(r == -ECANCELED ? r : 0);
-
- if (r == -ECANCELED) {
- notify_sync_complete(sync_ctx->sync_id);
- }
}
template <typename I>
bool unsuspend_notify_request(C_NotifyInstanceRequest *req);
void unsuspend_notify_requests();
+ void notify_sync_complete(const Mutex& lock, const std::string &sync_id);
void handle_notify_sync_request(C_SyncRequest *sync_ctx, int r);
void handle_notify_sync_complete(C_SyncRequest *sync_ctx, int r);