From: Mykola Golub Date: Fri, 6 Jul 2018 10:30:09 +0000 (+0300) Subject: librbd: restart object deep copy with flatten X-Git-Tag: v14.0.1~590^2~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=d3d3b51b8d642c081f1268a1d3f756909f850cfb;p=ceph.git librbd: restart object deep copy with flatten if copyup request was appended with non empty writes when the deep copy was in flight. Signed-off-by: Mykola Golub --- diff --git a/src/librbd/io/CopyupRequest.cc b/src/librbd/io/CopyupRequest.cc index b67fa8d45fec0..b8d71eadff0d5 100644 --- a/src/librbd/io/CopyupRequest.cc +++ b/src/librbd/io/CopyupRequest.cc @@ -236,14 +236,14 @@ void CopyupRequest::send() m_state = STATE_READ_FROM_PARENT; if (is_deep_copy()) { - bool flatten = is_copyup_required() ? true : m_ictx->migration_info.flatten; + m_flatten = is_copyup_required() ? true : m_ictx->migration_info.flatten; auto req = deep_copy::ObjectCopyRequest::create( m_ictx->parent, m_ictx->migration_parent, m_ictx, - m_ictx->migration_info.snap_map, m_object_no, flatten, + m_ictx->migration_info.snap_map, m_object_no, m_flatten, util::create_context_callback(this)); ldout(m_ictx->cct, 20) << "deep copy object req " << req << ", object_no " << m_object_no - << ", flatten " << flatten + << ", flatten " << m_flatten << dendl; req->send(); return; @@ -279,7 +279,16 @@ bool CopyupRequest::should_complete(int *r) { switch (m_state) { case STATE_READ_FROM_PARENT: ldout(cct, 20) << "READ_FROM_PARENT" << dendl; - remove_from_list(); + m_ictx->copyup_list_lock.Lock(); + if (*r == -ENOENT && is_deep_copy() && m_ictx->migration_parent && + !m_flatten && is_copyup_required()) { + ldout(cct, 5) << "restart deep copy with flatten" << dendl; + m_ictx->copyup_list_lock.Unlock(); + send(); + return false; + } + remove_from_list(m_ictx->copyup_list_lock); + m_ictx->copyup_list_lock.Unlock(); if (*r >= 0 || *r == -ENOENT) { if (!is_copyup_required() && !is_update_object_map_required(*r)) { if (*r == -ENOENT && is_deep_copy()) { @@ -335,10 +344,16 @@ bool CopyupRequest::should_complete(int *r) { } template -void CopyupRequest::remove_from_list() -{ +void CopyupRequest::remove_from_list() { Mutex::Locker l(m_ictx->copyup_list_lock); + remove_from_list(m_ictx->copyup_list_lock); +} + +template +void CopyupRequest::remove_from_list(Mutex &lock) { + assert(m_ictx->copyup_list_lock.is_locked()); + auto it = m_ictx->copyup_list.find(m_object_no); assert(it != m_ictx->copyup_list.end()); m_ictx->copyup_list.erase(it); diff --git a/src/librbd/io/CopyupRequest.h b/src/librbd/io/CopyupRequest.h index 31eae5c1ac6c6..de79308562260 100644 --- a/src/librbd/io/CopyupRequest.h +++ b/src/librbd/io/CopyupRequest.h @@ -92,6 +92,7 @@ private: ZTracer::Trace m_trace; State m_state; + bool m_flatten; ceph::bufferlist m_copyup_data; std::vector *> m_pending_requests; std::atomic m_pending_copyups { 0 }; @@ -108,6 +109,7 @@ private: bool should_complete(int *r); void remove_from_list(); + void remove_from_list(Mutex &lock); bool send_object_map_head(); bool send_object_map();