From 5dd03479f79c6efe9fff78ca570a7b0366f36c21 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 25 Sep 2019 13:19:53 -0500 Subject: [PATCH] osd/PrimaryLogPG: make proxied writes behave with RETURNVEC Signed-off-by: Sage Weil --- src/osd/PrimaryLogPG.cc | 8 ++++- src/test/librados/tier_cxx.cc | 68 +++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index d5b4ad26ace..3c49fae9318 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -3089,6 +3089,10 @@ void PrimaryLogPG::do_proxy_write(OpRequestRef op, ObjectContextRef obc) if (!(op->may_write() || op->may_cache())) { flags |= CEPH_OSD_FLAG_RWORDERED; } + if (op->allows_returnvec()) { + flags |= CEPH_OSD_FLAG_RETURNVEC; + } + dout(10) << __func__ << " Start proxy write for " << *m << dendl; ProxyWriteOpRef pwop(std::make_shared(op, soid, m->ops, m->get_reqid())); @@ -3462,6 +3466,7 @@ void PrimaryLogPG::finish_proxy_write(hobject_t oid, ceph_tid_t tid, int r) MOSDOpReply *reply = new MOSDOpReply(m, r, get_osdmap_epoch(), 0, true); reply->set_reply_versions(eversion_t(), pwop->user_version); reply->add_flags(CEPH_OSD_FLAG_ACK | CEPH_OSD_FLAG_ONDISK); + reply->claim_op_out_data(pwop->ops); dout(10) << " sending commit on " << pwop << " " << reply << dendl; osd->send_message_osd_client(reply, m->get_connection()); pwop->sent_reply = true; @@ -3751,7 +3756,8 @@ void PrimaryLogPG::execute_ctx(OpContext *ctx) // prepare the reply ctx->reply = new MOSDOpReply(m, result, get_osdmap_epoch(), 0, ignore_out_data); - dout(20) << __func__ << " alloc reply " << ctx->reply << dendl; + dout(20) << __func__ << " alloc reply " << ctx->reply + << " result " << result << dendl; // read or error? if ((ctx->op_t->empty() || result < 0) && !ctx->update_log_only) { diff --git a/src/test/librados/tier_cxx.cc b/src/test/librados/tier_cxx.cc index 6add1718209..92707ce6ba4 100644 --- a/src/test/librados/tier_cxx.cc +++ b/src/test/librados/tier_cxx.cc @@ -6513,3 +6513,71 @@ TEST_F(LibRadosTwoPoolsPP, PropagateBaseTierError) { ASSERT_EQ(-ECANCELED, ioctx.operate("propagate-base-tier-error", &op2)); } + +TEST_F(LibRadosTwoPoolsPP, HelloWriteReturn) { + // configure cache + bufferlist inbl; + ASSERT_EQ(0, cluster.mon_command( + "{\"prefix\": \"osd tier add\", \"pool\": \"" + pool_name + + "\", \"tierpool\": \"" + cache_pool_name + + "\", \"force_nonempty\": \"--force-nonempty\" }", + inbl, NULL, NULL)); + ASSERT_EQ(0, cluster.mon_command( + "{\"prefix\": \"osd tier set-overlay\", \"pool\": \"" + pool_name + + "\", \"overlaypool\": \"" + cache_pool_name + "\"}", + inbl, NULL, NULL)); + ASSERT_EQ(0, cluster.mon_command( + "{\"prefix\": \"osd tier cache-mode\", \"pool\": \"" + cache_pool_name + + "\", \"mode\": \"writeback\"}", + inbl, NULL, NULL)); + + // set things up such that the op would normally be proxied + ASSERT_EQ(0, cluster.mon_command( + set_pool_str(cache_pool_name, "hit_set_count", 2), + inbl, NULL, NULL)); + ASSERT_EQ(0, cluster.mon_command( + set_pool_str(cache_pool_name, "hit_set_period", 600), + inbl, NULL, NULL)); + ASSERT_EQ(0, cluster.mon_command( + set_pool_str(cache_pool_name, "hit_set_type", + "explicit_object"), + inbl, NULL, NULL)); + ASSERT_EQ(0, cluster.mon_command( + set_pool_str(cache_pool_name, "min_read_recency_for_promote", + "10000"), + inbl, NULL, NULL)); + + // wait for maps to settle + cluster.wait_for_latest_osdmap(); + + // this *will* return data due to the RETURNVEC flag + { + bufferlist in, out; + int rval; + ObjectWriteOperation o; + o.exec("hello", "write_return_data", in, &out, &rval); + librados::AioCompletion *completion = cluster.aio_create_completion(); + ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &o, + librados::OPERATION_RETURNVEC)); + completion->wait_for_safe(); + ASSERT_EQ(42, completion->get_return_value()); + ASSERT_EQ(42, rval); + out.hexdump(std::cout); + ASSERT_EQ("you might see this", std::string(out.c_str(), out.length())); + } + + // this will overflow because the return data is too big + { + bufferlist in, out; + int rval; + ObjectWriteOperation o; + o.exec("hello", "write_too_much_return_data", in, &out, &rval); + librados::AioCompletion *completion = cluster.aio_create_completion(); + ASSERT_EQ(0, ioctx.aio_operate("foo", completion, &o, + librados::OPERATION_RETURNVEC)); + completion->wait_for_safe(); + ASSERT_EQ(-EOVERFLOW, completion->get_return_value()); + ASSERT_EQ(-EOVERFLOW, rval); + ASSERT_EQ("", std::string(out.c_str(), out.length())); + } +} -- 2.39.5