]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librados/snap_set_diff: don't assert on empty snapset 20991/head
authorMykola Golub <mgolub@suse.com>
Mon, 19 Feb 2018 11:17:29 +0000 (13:17 +0200)
committerMykola Golub <mgolub@suse.com>
Wed, 21 Mar 2018 16:30:39 +0000 (18:30 +0200)
Instead treat the diff as a full-object delta.

Signed-off-by: Mykola Golub <mgolub@suse.com>
(cherry picked from commit 2be4840afd4fc54c2ad06ccc2aac903e45bd37f5)

Conflicts:
src/librbd/deep_copy/ObjectCopyRequest.cc
src/librbd/deep_copy/ObjectCopyRequest.h
            deep_copy::ObjectCopyRequest does not exist in luminous,
            fixed rbd_mirror::image_sync::ObjectCopyRequest instead

src/librados/snap_set_diff.cc
src/librados/snap_set_diff.h
src/librbd/api/DiffIterate.cc
src/tools/rbd_mirror/image_sync/ObjectCopyRequest.cc
src/tools/rbd_mirror/image_sync/ObjectCopyRequest.h

index fcf42d080dabc17100b7ee976036c5ca4807bf84..8b83b908e0ec2ec0e5cc9821ba5d9387cf973587 100644 (file)
@@ -17,7 +17,8 @@
 void calc_snap_set_diff(CephContext *cct, const librados::snap_set_t& snap_set,
                        librados::snap_t start, librados::snap_t end,
                        interval_set<uint64_t> *diff, uint64_t *end_size,
-                        bool *end_exists, librados::snap_t *clone_end_snap_id)
+                        bool *end_exists, librados::snap_t *clone_end_snap_id,
+                        bool *whole_object)
 {
   ldout(cct, 10) << "calc_snap_set_diff start " << start << " end " << end
                 << ", snap_set seq " << snap_set.seq << dendl;
@@ -27,6 +28,7 @@ void calc_snap_set_diff(CephContext *cct, const librados::snap_set_t& snap_set,
   *end_size = 0;
   *end_exists = false;
   *clone_end_snap_id = 0;
+  *whole_object = false;
 
   for (vector<librados::clone_info_t>::const_iterator r = snap_set.clones.begin();
        r != snap_set.clones.end();
@@ -38,6 +40,11 @@ void calc_snap_set_diff(CephContext *cct, const librados::snap_set_t& snap_set,
       // head is valid starting from right after the last seen seq
       a = snap_set.seq + 1;
       b = librados::SNAP_HEAD;
+    } else if (r->snaps.empty()) {
+      ldout(cct, 1) << "clone " << r->cloneid
+                    << ": empty snaps, return whole object" << dendl;
+      *whole_object = true;
+      return;
     } else {
       a = r->snaps[0];
       // note: b might be < r->cloneid if a snap has been trimmed.
index aba03ee317ec4ab76a31390b7bbfc70f0fd8bd10..d09a368a4cc8352424e370e02074a05109fb5784 100644 (file)
@@ -12,6 +12,7 @@ void calc_snap_set_diff(CephContext *cct,
                        const librados::snap_set_t& snap_set,
                        librados::snap_t start, librados::snap_t end,
                        interval_set<uint64_t> *diff, uint64_t *end_size,
-                       bool *end_exists, librados::snap_t *clone_end_snap_id);
+                       bool *end_exists, librados::snap_t *clone_end_snap_id,
+                       bool *whole_object);
 
 #endif
index 04b8ba450e19132e1211d62ba74ca9c789824e4e..1bd3a8fe5800dfdcffa6b8daf12a06b43f2ee480 100644 (file)
@@ -131,17 +131,22 @@ private:
     uint64_t end_size;
     bool end_exists;
     librados::snap_t clone_end_snap_id;
+    bool whole_object;
     calc_snap_set_diff(cct, m_snap_set, m_diff_context.from_snap_id,
                        m_diff_context.end_snap_id, &diff, &end_size,
-                       &end_exists, &clone_end_snap_id);
+                       &end_exists, &clone_end_snap_id, &whole_object);
+    if (whole_object) {
+      ldout(cct, 1) << "object " << m_oid << ": need to provide full object"
+                    << dendl;
+    }
     ldout(cct, 20) << "  diff " << diff << " end_exists=" << end_exists
                    << dendl;
-    if (diff.empty()) {
+    if (diff.empty() && !whole_object) {
       if (m_diff_context.from_snap_id == 0 && !end_exists) {
         compute_parent_overlap(diffs);
       }
       return;
-    } else if (m_diff_context.whole_object) {
+    } else if (m_diff_context.whole_object || whole_object) {
       // provide the full object extents to the callback
       for (vector<ObjectExtent>::iterator q = m_object_extents.begin();
            q != m_object_extents.end(); ++q) {
index cc59030878ba35846c0182e6756aaed1c88755f4..533f175f9ff3011cfc5f054d277c1bb52ccf6421 100644 (file)
@@ -173,6 +173,13 @@ template <typename I>
 void ObjectCopyRequest<I>::handle_read_object(int r) {
   dout(20) << ": r=" << r << dendl;
 
+  auto snap_seq = m_snap_sync_ops.begin()->first.second;
+  if (r == -ENOENT && m_read_whole_object[snap_seq]) {
+    dout(5) << ": object missing when forced to read whole object"
+            << dendl;
+    r = 0;
+  }
+
   if (r == -ENOENT) {
     m_retry_snap_set = m_snap_set;
     m_retry_missing_read = true;
@@ -413,9 +420,18 @@ void ObjectCopyRequest<I>::compute_diffs() {
     uint64_t end_size;
     bool exists;
     librados::snap_t clone_end_snap_id;
+    bool read_whole_object;
     calc_snap_set_diff(cct, m_snap_set, start_remote_snap_id,
                        end_remote_snap_id, &diff, &end_size, &exists,
-                       &clone_end_snap_id);
+                       &clone_end_snap_id, &read_whole_object);
+
+    if (read_whole_object) {
+      dout(1) << ": need to read full object" << dendl;
+      diff.insert(0, m_remote_image_ctx->layout.object_size);
+      exists = true;
+      end_size = m_remote_image_ctx->layout.object_size;
+      clone_end_snap_id = end_remote_snap_id;
+    }
 
     dout(20) << ": "
              << "start_remote_snap=" << start_remote_snap_id << ", "
@@ -455,6 +471,7 @@ void ObjectCopyRequest<I>::compute_diffs() {
         // do not read past the sync point snapshot
         clone_end_snap_id = remote_sync_pont_snap_id;
       }
+      m_read_whole_object[clone_end_snap_id] = read_whole_object;
 
       // object write/zero, or truncate
       // NOTE: a single snapshot clone might represent multiple snapshots, but
index 8430e7030c43933fb299222d7ac5d0fdea085ccd..d52097dc6fbd48f13dd6f0cce28239b0087499dd 100644 (file)
@@ -120,6 +120,7 @@ private:
 
   bool m_retry_missing_read = false;
   librados::snap_set_t m_retry_snap_set;
+  std::map<librados::snap_t, bool> m_read_whole_object;
 
   SnapSyncOps m_snap_sync_ops;
   SnapObjectStates m_snap_object_states;