]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: restart object deep copy with flatten
authorMykola Golub <mgolub@suse.com>
Fri, 6 Jul 2018 10:30:09 +0000 (13:30 +0300)
committerJason Dillaman <dillaman@redhat.com>
Tue, 14 Aug 2018 22:29:45 +0000 (18:29 -0400)
if copyup request was appended with non empty writes when the deep
copy was in flight.

Signed-off-by: Mykola Golub <mgolub@suse.com>
src/librbd/io/CopyupRequest.cc
src/librbd/io/CopyupRequest.h

index b67fa8d45fec07604fda97c96a50b23ac06b71e4..b8d71eadff0d5e8bdd1ecce8fb03c84f17104008 100644 (file)
@@ -236,14 +236,14 @@ void CopyupRequest<I>::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<I>::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<I>::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<I>::should_complete(int *r) {
 }
 
 template <typename I>
-void CopyupRequest<I>::remove_from_list()
-{
+void CopyupRequest<I>::remove_from_list() {
   Mutex::Locker l(m_ictx->copyup_list_lock);
 
+  remove_from_list(m_ictx->copyup_list_lock);
+}
+
+template <typename I>
+void CopyupRequest<I>::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);
index 31eae5c1ac6c6b32de177aad22377001cd5ccd1e..de7930856226001273dda74165bb6090556e6068 100644 (file)
@@ -92,6 +92,7 @@ private:
   ZTracer::Trace m_trace;
 
   State m_state;
+  bool m_flatten;
   ceph::bufferlist m_copyup_data;
   std::vector<AbstractObjectWriteRequest<ImageCtxT> *> m_pending_requests;
   std::atomic<unsigned> 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();