]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
luminous: librbd: fixed assert when flattening clone with zero overlap 24285/head
authorJason Dillaman <dillaman@redhat.com>
Wed, 12 Sep 2018 01:52:05 +0000 (21:52 -0400)
committerryan <mr.iridescent.rsy@hotmail.com>
Wed, 26 Sep 2018 05:51:15 +0000 (13:51 +0800)
Fixes: http://tracker.ceph.com/issues/35702
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 8e90354)

 Conflicts:
src/librbd/Operations.cc
src/test/librbd/test_librbd.cc

src/librbd/Operations.cc
src/librbd/operation/FlattenRequest.cc
src/test/librbd/test_librbd.cc

index bc118915dc40777bbc1e12b5747771879fb149e2..e9e8fa4b76fdf2a6f50ed044d661fac11fe1e770 100644 (file)
@@ -398,7 +398,6 @@ void Operations<I>::execute_flatten(ProgressContext &prog_ctx,
   }
 
   ::SnapContext snapc = m_image_ctx.snapc;
-  assert(m_image_ctx.parent != NULL);
 
   uint64_t overlap;
   int r = m_image_ctx.get_parent_overlap(CEPH_NOSNAP, &overlap);
index 78cca8d38dc55024f6ffdd063c6eee378b5587cd..35c947c044362ff98790dc4f465e9367ebc30540 100644 (file)
@@ -130,7 +130,7 @@ bool FlattenRequest<I>::send_update_header() {
     RWLock::RLocker parent_locker(image_ctx.parent_lock);
     // stop early if the parent went away - it just means
     // another flatten finished first, so this one is useless.
-    if (!image_ctx.parent) {
+    if (image_ctx.parent_md.spec.pool_id == -1) {
       ldout(cct, 5) << "image already flattened" << dendl;
       return true;
     }
index 67e348a40cdc9267497ba3ca6cbdc2ccd9e4018a..a4e6d1d268df1f8d5840e67dea6661dd7c17a460 100644 (file)
@@ -6195,6 +6195,38 @@ TEST_F(TestLibRBD, TestTrashMoveAndRestore) {
   ASSERT_TRUE(found);
 }
 
+TEST_F(TestLibRBD, ZeroOverlapFlatten) {
+  REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
+
+  librados::IoCtx ioctx;
+  ASSERT_EQ(0, _rados.ioctx_create(m_pool_name.c_str(), ioctx));
+
+  librbd::RBD rbd;
+  librbd::Image parent_image;
+  std::string name = get_temp_image_name();
+
+  uint64_t size = 1;
+  int order = 0;
+
+  ASSERT_EQ(0, create_image_pp(rbd, ioctx, name.c_str(), size, &order));
+  ASSERT_EQ(0, rbd.open(ioctx, parent_image, name.c_str(), NULL));
+
+  uint64_t features;
+  ASSERT_EQ(0, parent_image.features(&features));
+
+  ASSERT_EQ(0, parent_image.snap_create("snap"));
+  ASSERT_EQ(0, parent_image.snap_protect("snap"));
+
+  std::string clone_name = this->get_temp_image_name();
+  ASSERT_EQ(0, rbd.clone(ioctx, name.c_str(), "snap", ioctx, clone_name.c_str(),
+                         features, &order));
+
+  librbd::Image clone_image;
+  ASSERT_EQ(0, rbd.open(ioctx, clone_image, clone_name.c_str(), NULL));
+  ASSERT_EQ(0, clone_image.resize(0));
+  ASSERT_EQ(0, clone_image.flatten());
+}
+
 // poorman's assert()
 namespace ceph {
   void __ceph_assert_fail(const char *assertion, const char *file, int line,