From 127dd41fcad11b7251c0dbf29455b1c0a3aef2de Mon Sep 17 00:00:00 2001 From: myoungwon oh Date: Mon, 12 Apr 2021 00:37:11 +0900 Subject: [PATCH] osd: fix not set promote_obc when manifest object is rollbacked Signed-off-by: Myoungwon Oh --- src/osd/PrimaryLogPG.cc | 5 ++ src/test/librados/tier_cxx.cc | 96 +++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index 626e8ccefbda6..e660cc49fa53d 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -8251,6 +8251,11 @@ int PrimaryLogPG::_rollback_to(OpContext *ctx, OSDOp& op) ObjectContextRef promote_obc; cache_result_t tier_mode_result; if (obs.exists && obs.oi.has_manifest()) { + /* + * In the case of manifest object, the object_info exists on the base tier at all time, + * so promote_obc should be equal to rollback_to + * */ + promote_obc = rollback_to; tier_mode_result = maybe_handle_manifest_detail( ctx->op, diff --git a/src/test/librados/tier_cxx.cc b/src/test/librados/tier_cxx.cc index 4d285377a7746..ff87975ad3c60 100644 --- a/src/test/librados/tier_cxx.cc +++ b/src/test/librados/tier_cxx.cc @@ -6083,6 +6083,102 @@ TEST_F(LibRadosTwoPoolsPP, ManifestRollbackRefcount) { is_intended_refcount_state(ioctx, "foo", cache_ioctx, "chunk2", 1); } +TEST_F(LibRadosTwoPoolsPP, ManifestEvictRollback) { + // skip test if not yet pacific + if (_get_required_osd_release(cluster) < "pacific") { + cout << "cluster is not yet pacific, skipping test" << std::endl; + return; + } + + // create object + { + bufferlist bl; + bl.append("CDere hiHI"); + ObjectWriteOperation op; + op.write_full(bl); + ASSERT_EQ(0, ioctx.operate("foo", &op)); + } + { + bufferlist bl; + bl.append("ABere hiHI"); + ObjectWriteOperation op; + op.write_full(bl); + ASSERT_EQ(0, cache_ioctx.operate("chunk1", &op)); + } + { + bufferlist bl; + bl.append("CDere hiHI"); + ObjectWriteOperation op; + op.write_full(bl); + ASSERT_EQ(0, cache_ioctx.operate("chunk2", &op)); + } + { + bufferlist bl; + bl.append("EFere hiHI"); + ObjectWriteOperation op; + op.write_full(bl); + ASSERT_EQ(0, cache_ioctx.operate("chunk3", &op)); + } + + // wait for maps to settle + cluster.wait_for_latest_osdmap(); + + // create a snapshot, clone + vector my_snaps(1); + ASSERT_EQ(0, ioctx.selfmanaged_snap_create(&my_snaps[0])); + ASSERT_EQ(0, ioctx.selfmanaged_snap_set_write_ctx(my_snaps[0], + my_snaps)); + + { + bufferlist bl; + bl.append("there hiHI"); + ASSERT_EQ(0, ioctx.write("foo", bl, bl.length(), 0)); + } + + + // set-chunk + manifest_set_chunk(cluster, cache_ioctx, ioctx, 2, 2, "chunk1", "foo"); + manifest_set_chunk(cluster, cache_ioctx, ioctx, 8, 2, "chunk3", "foo"); + // foo snap[0]: + // foo head : [chunk1] [chunk3] + + ioctx.snap_set_read(my_snaps[0]); + manifest_set_chunk(cluster, cache_ioctx, ioctx, 0, 10, "chunk2", "foo"); + // foo snap[0]: [ chunk2 ] + // foo head : [chunk1] [chunk3] + + sleep(10); + ioctx.snap_set_read(librados::SNAP_HEAD); + is_intended_refcount_state(ioctx, "foo", cache_ioctx, "chunk1", 1); + is_intended_refcount_state(ioctx, "foo", cache_ioctx, "chunk3", 1); + + + ioctx.snap_set_read(my_snaps[0]); + // evict--this makes the chunk missing state + { + ObjectReadOperation op, stat_op; + op.tier_evict(); + librados::AioCompletion *completion = cluster.aio_create_completion(); + ASSERT_EQ(0, ioctx.aio_operate( + "foo", completion, &op, + librados::OPERATION_IGNORE_OVERLAY, NULL)); + completion->wait_for_complete(); + ASSERT_EQ(0, completion->get_return_value()); + } + + // rollback to my_snaps[0] + ASSERT_EQ(0, ioctx.selfmanaged_snap_rollback("foo", my_snaps[0])); + + ioctx.snap_set_read(librados::SNAP_HEAD); + { + bufferlist bl; + ASSERT_EQ(1, ioctx.read("foo", bl, 1, 0)); + ASSERT_EQ('C', bl[0]); + } + + is_intended_refcount_state(ioctx, "foo", cache_ioctx, "chunk2", 1); +} + class LibRadosTwoPoolsECPP : public RadosTestECPP { public: -- 2.39.5