]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/PrimaryLogPG: make proxied writes behave with RETURNVEC
authorSage Weil <sage@redhat.com>
Wed, 25 Sep 2019 18:19:53 +0000 (13:19 -0500)
committerSage Weil <sage@redhat.com>
Wed, 25 Sep 2019 18:29:20 +0000 (13:29 -0500)
Signed-off-by: Sage Weil <sage@redhat.com>
src/osd/PrimaryLogPG.cc
src/test/librados/tier_cxx.cc

index d5b4ad26ace340bbe4f1846483390b48d4db153d..3c49fae93186631dcbfa7f692e6b44ca2ce87cbb 100644 (file)
@@ -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<ProxyWriteOp>(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) {
index 6add171820969fd0fab8039cddd32c2d4eb9e3d1..92707ce6ba454f0460ae39c42ab8861d4aa7fc48 100644 (file)
@@ -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()));
+  }
+}