]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: fix rebuild_object_map() when no object map exists 6273/head
authorJosh Durgin <jdurgin@redhat.com>
Thu, 15 Oct 2015 01:28:33 +0000 (18:28 -0700)
committerJosh Durgin <jdurgin@redhat.com>
Thu, 15 Oct 2015 07:32:08 +0000 (00:32 -0700)
Enabling the object map feature and then attempting to rebuild it
results in an assert failure, since the number of objects was
accidentally passed to ObjectMap::aio_resize() instead of the size of
the image.

Fixes: #13496
Signed-off-by: Josh Durgin <jdurgin@redhat.com>
src/librbd/RebuildObjectMapRequest.cc
src/test/librbd/test_librbd.cc

index 0a7950a8fb1d900fd4960f746a81f9ec81909eb9..8a3b29fe0ecd7df5fd84cae85402ab52d94a8489 100644 (file)
@@ -228,9 +228,10 @@ void RebuildObjectMapRequest::send_resize_object_map() {
   CephContext *cct = m_image_ctx.cct;
 
   uint64_t num_objects;
+  uint64_t size;
   {
     RWLock::RLocker l(m_image_ctx.snap_lock);
-    uint64_t size = get_image_size();
+    size = get_image_size();
     num_objects = Striper::get_num_objects(m_image_ctx.layout, size);
   }
 
@@ -245,7 +246,7 @@ void RebuildObjectMapRequest::send_resize_object_map() {
   // should have been canceled prior to releasing lock
   assert(!m_image_ctx.image_watcher->is_lock_supported() ||
          m_image_ctx.image_watcher->is_lock_owner());
-  m_image_ctx.object_map.aio_resize(num_objects, OBJECT_NONEXISTENT,
+  m_image_ctx.object_map.aio_resize(size, OBJECT_NONEXISTENT,
                                     create_callback_context());
 }
 
index 5dc5c66da471bca12c0c8afa2cc14187361baa56..340d43b8c847c860926443f3d759fd77f6141da2 100644 (file)
@@ -3080,6 +3080,31 @@ TEST_F(TestLibRBD, RebuildObjectMap)
   ASSERT_PASSED(validate_object_map, image2);
 }
 
+TEST_F(TestLibRBD, RebuildNewObjectMap)
+{
+  REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
+
+  rados_ioctx_t ioctx;
+  rados_ioctx_create(_cluster, m_pool_name.c_str(), &ioctx);
+
+  std::string name = get_temp_image_name();
+  uint64_t size = 1 << 20;
+  int order = 18;
+  uint64_t features = RBD_FEATURE_EXCLUSIVE_LOCK;
+  ASSERT_EQ(0, create_image_full(ioctx, name.c_str(), size, &order,
+                                false, features));
+
+  rbd_image_t image;
+  ASSERT_EQ(0, rbd_open(ioctx, name.c_str(), &image, NULL));
+  ASSERT_EQ(0, rbd_update_features(image, RBD_FEATURE_OBJECT_MAP, true));
+  ASSERT_EQ(0, rbd_rebuild_object_map(image, print_progress_percent, NULL));
+
+  ASSERT_PASSED(validate_object_map, image);
+
+  ASSERT_EQ(0, rbd_close(image));
+  rados_ioctx_destroy(ioctx);
+}
+
 TEST_F(TestLibRBD, BlockingAIO)
 {
   librados::IoCtx ioctx;