]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: ensure deep-copy snapshot map includes all destination snap ids
authorJason Dillaman <dillaman@redhat.com>
Wed, 5 Feb 2020 20:27:39 +0000 (15:27 -0500)
committerJason Dillaman <dillaman@redhat.com>
Wed, 16 Sep 2020 17:19:29 +0000 (13:19 -0400)
When deep-copying from an arbitrary start snapshot id, the snap sequence
will be missing all older snapshots. Additionally, snapshot types that
are not deep-copied still need to be included in the destination snap
map.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 5ddc15a34b3bc2726ea15cfbfbe2bd28a329db99)

Conflicts:
src/librbd/deep_copy/ImageCopyRequest.cc: RefCountedObject changes

src/librbd/deep_copy/ImageCopyRequest.cc
src/librbd/deep_copy/ImageCopyRequest.h
src/librbd/deep_copy/Utils.cc
src/librbd/deep_copy/Utils.h
src/librbd/image/RefreshRequest.cc

index e446c3a5869a1651313bcd0d92019a91610ae086..266e76b956b881b57979bc03853f6e7ba1a9d7cd 100644 (file)
@@ -23,16 +23,16 @@ using librbd::util::unique_lock_name;
 
 template <typename I>
 ImageCopyRequest<I>::ImageCopyRequest(I *src_image_ctx, I *dst_image_ctx,
-                                      librados::snap_t snap_id_start,
-                                      librados::snap_t snap_id_end,
+                                      librados::snap_t src_snap_id_start,
+                                      librados::snap_t src_snap_id_end,
                                       bool flatten,
                                       const ObjectNumber &object_number,
                                       const SnapSeqs &snap_seqs,
                                       ProgressContext *prog_ctx,
                                       Context *on_finish)
   : RefCountedObject(dst_image_ctx->cct, 1), m_src_image_ctx(src_image_ctx),
-    m_dst_image_ctx(dst_image_ctx), m_snap_id_start(snap_id_start),
-    m_snap_id_end(snap_id_end), m_flatten(flatten),
+    m_dst_image_ctx(dst_image_ctx), m_src_snap_id_start(src_snap_id_start),
+    m_src_snap_id_end(src_snap_id_end), m_flatten(flatten),
     m_object_number(object_number), m_snap_seqs(snap_seqs),
     m_prog_ctx(prog_ctx), m_on_finish(on_finish), m_cct(dst_image_ctx->cct),
     m_lock(unique_lock_name("ImageCopyRequest::m_lock", this)) {
@@ -40,8 +40,12 @@ ImageCopyRequest<I>::ImageCopyRequest(I *src_image_ctx, I *dst_image_ctx,
 
 template <typename I>
 void ImageCopyRequest<I>::send() {
-  util::compute_snap_map(m_snap_id_start, m_snap_id_end, m_snap_seqs,
+  m_dst_image_ctx->snap_lock.get_read();
+  util::compute_snap_map(m_dst_image_ctx->cct, m_src_snap_id_start,
+                         m_src_snap_id_end, m_dst_image_ctx->snaps, m_snap_seqs,
                          &m_snap_map);
+  m_dst_image_ctx->snap_lock.put_read();
+
   if (m_snap_map.empty()) {
     lderr(m_cct) << "failed to map snapshots within boundary" << dendl;
     finish(-EINVAL);
index e50507e884859c28b4bfb26aa44316f012e71ae1..5a50cdd16ffb2f138e4996b57cad846c5ee8899e 100644 (file)
@@ -30,19 +30,21 @@ class ImageCopyRequest : public RefCountedObject {
 public:
   static ImageCopyRequest* create(ImageCtxT *src_image_ctx,
                                   ImageCtxT *dst_image_ctx,
-                                  librados::snap_t snap_id_start,
-                                  librados::snap_t snap_id_end, bool flatten,
+                                  librados::snap_t src_snap_id_start,
+                                  librados::snap_t src_snap_id_end,
+                                  bool flatten,
                                   const ObjectNumber &object_number,
                                   const SnapSeqs &snap_seqs,
                                   ProgressContext *prog_ctx,
                                   Context *on_finish) {
-    return new ImageCopyRequest(src_image_ctx, dst_image_ctx, snap_id_start,
-                                snap_id_end, flatten, object_number, snap_seqs,
-                                prog_ctx, on_finish);
+    return new ImageCopyRequest(src_image_ctx, dst_image_ctx, src_snap_id_start,
+                                src_snap_id_end, flatten, object_number,
+                                snap_seqs, prog_ctx, on_finish);
   }
 
   ImageCopyRequest(ImageCtxT *src_image_ctx, ImageCtxT *dst_image_ctx,
-                   librados::snap_t snap_id_start, librados::snap_t snap_id_end,
+                   librados::snap_t src_snap_id_start,
+                   librados::snap_t src_snap_id_end,
                    bool flatten, const ObjectNumber &object_number,
                    const SnapSeqs &snap_seqs, ProgressContext *prog_ctx,
                    Context *on_finish);
@@ -68,8 +70,8 @@ private:
 
   ImageCtxT *m_src_image_ctx;
   ImageCtxT *m_dst_image_ctx;
-  librados::snap_t m_snap_id_start;
-  librados::snap_t m_snap_id_end;
+  librados::snap_t m_src_snap_id_start;
+  librados::snap_t m_src_snap_id_end;
   bool m_flatten;
   ObjectNumber m_object_number;
   SnapSeqs m_snap_seqs;
index 32b96587d194c202cc9c251abeff991606fbdeea..c2dd25020e43bb29158563e4626bf390589da7b8 100644 (file)
@@ -1,29 +1,61 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#include "common/debug.h"
 #include "Utils.h"
+#include <set>
 
 namespace librbd {
 namespace deep_copy {
 namespace util {
 
-void compute_snap_map(librados::snap_t snap_id_start,
-                      librados::snap_t snap_id_end,
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::deep_copy::util::" << __func__ << ": "
+
+void compute_snap_map(CephContext* cct,
+                      librados::snap_t src_snap_id_start,
+                      librados::snap_t src_snap_id_end,
+                      const SnapIds& dst_snap_ids,
                       const SnapSeqs &snap_seqs,
                       SnapMap *snap_map) {
+  std::set<librados::snap_t> ordered_dst_snap_ids{
+    dst_snap_ids.begin(), dst_snap_ids.end()};
+  auto dst_snap_id_it = ordered_dst_snap_ids.begin();
+
   SnapIds snap_ids;
   for (auto &it : snap_seqs) {
+    // ensure all dst snap ids are included in the mapping table since
+    // deep copy will skip non-user snapshots
+    while (dst_snap_id_it != ordered_dst_snap_ids.end()) {
+      if (*dst_snap_id_it < it.second) {
+        snap_ids.insert(snap_ids.begin(), *dst_snap_id_it);
+      } else if (*dst_snap_id_it > it.second) {
+        break;
+      }
+      ++dst_snap_id_it;
+    }
+
+    // we should only have the HEAD revision in the the last snap seq
+    ceph_assert(snap_ids.empty() || snap_ids[0] != CEPH_NOSNAP);
     snap_ids.insert(snap_ids.begin(), it.second);
-    if (it.first < snap_id_start) {
+
+    if (it.first < src_snap_id_start) {
       continue;
-    } else if (it.first > snap_id_end) {
+    } else if (it.first > src_snap_id_end) {
       break;
     }
 
     (*snap_map)[it.first] = snap_ids;
   }
+
+  ldout(cct, 10) << "src_snap_id_start=" << src_snap_id_start << ", "
+                 << "src_snap_id_end=" << src_snap_id_end << ", "
+                 << "dst_snap_ids=" << dst_snap_ids << ", "
+                 << "snap_seqs=" << snap_seqs << ", "
+                 << "snap_map=" << *snap_map << dendl;
 }
 
-} // util
+} // namespace util
 } // namespace deep_copy
 } // namespace librbd
index 28e1d6d7ea475d9fd0dfaadbe31f9a789436aea4..0681548db0f079fa5c3285a8ffa0484968e5e7b5 100644 (file)
 
 #include <boost/optional.hpp>
 
+struct CephContext;
+
 namespace librbd {
 namespace deep_copy {
 namespace util {
 
-void compute_snap_map(librados::snap_t snap_id_start,
-                      librados::snap_t snap_id_end,
+void compute_snap_map(CephContext* cct,
+                      librados::snap_t src_snap_id_start,
+                      librados::snap_t src_snap_id_end,
+                      const SnapIds& dst_snap_ids,
                       const SnapSeqs &snap_seqs,
                       SnapMap *snap_map);
 
index 7ec565d6cafc342f80192ae78d9066ccc552bcec..ad3c1bb8643091fbd91c6921301b3eee0c1e5b45 100644 (file)
@@ -1504,8 +1504,8 @@ bool RefreshRequest<I>::get_migration_info(ParentImageInfo *parent_md,
                      m_migration_spec.image_name, m_migration_spec.image_id, {},
                      overlap, m_migration_spec.flatten};
 
-  deep_copy::util::compute_snap_map(0, CEPH_NOSNAP, snap_seqs,
-                                    &migration_info->snap_map);
+  deep_copy::util::compute_snap_map(m_image_ctx.cct, 0, CEPH_NOSNAP, {},
+                                    snap_seqs, &migration_info->snap_map);
   return true;
 }