]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librados/snap_set_diff: don't assert on empty snapset 20648/head
authorMykola Golub <mgolub@suse.com>
Mon, 19 Feb 2018 11:17:29 +0000 (13:17 +0200)
committerMykola Golub <mgolub@suse.com>
Wed, 28 Feb 2018 15:33:50 +0000 (17:33 +0200)
Instead treat the diff as a full-object delta.

Signed-off-by: Mykola Golub <mgolub@suse.com>
src/librados/snap_set_diff.cc
src/librados/snap_set_diff.h
src/librbd/api/DiffIterate.cc
src/librbd/deep_copy/ObjectCopyRequest.cc
src/librbd/deep_copy/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 7b07634cfa69a72312152f5b356d73ccf77c5eae..7a33c64b3ba3d97447ab3bcaf678e73570c5d9fc 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 39ed63c3c3cec76fe1ccd00e39e58e90fd6448b9..b3424266976d9032686bb9b6f117480ef28347f6 100644 (file)
@@ -190,6 +190,12 @@ template <typename I>
 void ObjectCopyRequest<I>::handle_read_object(int r) {
   ldout(m_cct, 20) << "r=" << r << dendl;
 
+  if (r == -ENOENT && m_read_whole_object) {
+    ldout(m_cct, 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;
@@ -478,7 +484,16 @@ void ObjectCopyRequest<I>::compute_read_ops() {
     librados::snap_t clone_end_snap_id;
     calc_snap_set_diff(m_cct, m_snap_set, start_src_snap_id,
                        end_src_snap_id, &diff, &end_size, &exists,
-                       &clone_end_snap_id);
+                       &clone_end_snap_id, &m_read_whole_object);
+
+    if (m_read_whole_object) {
+      ldout(m_cct, 1) << "need to read full object" << dendl;
+      diff.insert(0, m_src_image_ctx->layout.object_size);
+      exists = true;
+      end_size = m_src_image_ctx->layout.object_size;
+      clone_end_snap_id = end_src_snap_id;
+    }
+
     if (!exists) {
       end_size = 0;
     }
index e974b56d8f4e7d2592def824f868acdedc35c394..8e2b56fa57a7e8c86a95bd6630f305afb354b299 100644 (file)
@@ -142,6 +142,7 @@ private:
   int m_snap_ret = 0;
   bool m_retry_missing_read = false;
   librados::snap_set_t m_retry_snap_set;
+  bool m_read_whole_object = false;
 
   std::map<WriteReadSnapIds, CopyOps> m_read_ops;
   std::list<WriteReadSnapIds> m_read_snaps;