From f087db5709223f18da87a65b0c309342db1a84d5 Mon Sep 17 00:00:00 2001 From: Mykola Golub Date: Wed, 6 Jun 2018 23:48:07 +0300 Subject: [PATCH] librbd: force 'invalid object map' flag on-disk update when called by object_map::RefreshRequest. Since we really only open the object map when we own the exclusive lock. Fixes: http://tracker.ceph.com/issues/24434 Signed-off-by: Mykola Golub --- src/librbd/object_map/RefreshRequest.cc | 4 ++-- src/test/librbd/test_ObjectMap.cc | 29 +++++++++++++++---------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/librbd/object_map/RefreshRequest.cc b/src/librbd/object_map/RefreshRequest.cc index 2aad847fbc9..769cca5cf5b 100644 --- a/src/librbd/object_map/RefreshRequest.cc +++ b/src/librbd/object_map/RefreshRequest.cc @@ -169,7 +169,7 @@ void RefreshRequest::send_invalidate() { Context *ctx = create_context_callback< klass, &klass::handle_invalidate>(this); InvalidateRequest *req = InvalidateRequest::create( - m_image_ctx, m_snap_id, false, ctx); + m_image_ctx, m_snap_id, true, ctx); RWLock::RLocker owner_locker(m_image_ctx.owner_lock); RWLock::WLocker snap_locker(m_image_ctx.snap_lock); @@ -199,7 +199,7 @@ void RefreshRequest::send_resize_invalidate() { Context *ctx = create_context_callback< klass, &klass::handle_resize_invalidate>(this); InvalidateRequest *req = InvalidateRequest::create( - m_image_ctx, m_snap_id, false, ctx); + m_image_ctx, m_snap_id, true, ctx); RWLock::RLocker owner_locker(m_image_ctx.owner_lock); RWLock::WLocker snap_locker(m_image_ctx.snap_lock); diff --git a/src/test/librbd/test_ObjectMap.cc b/src/test/librbd/test_ObjectMap.cc index 464c233faad..ef556df435a 100644 --- a/src/test/librbd/test_ObjectMap.cc +++ b/src/test/librbd/test_ObjectMap.cc @@ -4,6 +4,7 @@ #include "test/librbd/test_support.h" #include "librbd/ExclusiveLock.h" #include "librbd/ImageCtx.h" +#include "librbd/ImageState.h" #include "librbd/ImageWatcher.h" #include "librbd/internal.h" #include "librbd/ObjectMap.h" @@ -107,7 +108,7 @@ TEST_F(TestObjectMap, InvalidateFlagOnDisk) { ASSERT_TRUE(flags_set); } -TEST_F(TestObjectMap, InvalidateFlagInMemoryOnly) { +TEST_F(TestObjectMap, AcquireLockInvalidatesWhenTooSmall) { REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP); librbd::ImageCtx *ictx; @@ -116,21 +117,25 @@ TEST_F(TestObjectMap, InvalidateFlagInMemoryOnly) { ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set)); ASSERT_FALSE(flags_set); + librados::ObjectWriteOperation op; + librbd::cls_client::object_map_resize(&op, 0, OBJECT_NONEXISTENT); + std::string oid = librbd::ObjectMap<>::object_map_name(ictx->id, CEPH_NOSNAP); - bufferlist valid_bl; - ASSERT_LT(0, ictx->md_ctx.read(oid, valid_bl, 0, 0)); + ASSERT_EQ(0, ictx->md_ctx.operate(oid, &op)); - bufferlist corrupt_bl; - corrupt_bl.append("corrupt"); - ASSERT_EQ(0, ictx->md_ctx.write_full(oid, corrupt_bl)); + C_SaferCond lock_ctx; + { + RWLock::WLocker owner_locker(ictx->owner_lock); + ictx->exclusive_lock->try_acquire_lock(&lock_ctx); + } + ASSERT_EQ(0, lock_ctx.wait()); - ASSERT_EQ(0, when_open_object_map(ictx)); ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set)); ASSERT_TRUE(flags_set); - ASSERT_EQ(0, ictx->md_ctx.write_full(oid, valid_bl)); - ASSERT_EQ(0, open_image(m_image_name, &ictx)); - ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set)); - ASSERT_FALSE(flags_set); + // Test the flag is stored on disk + ASSERT_EQ(0, ictx->state->refresh()); + ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, + &flags_set)); + ASSERT_TRUE(flags_set); } - -- 2.39.5