]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
neorados: Cancel ReadOp/WriteOp execute
authorAdam Emerson <aemerson@redhat.com>
Wed, 1 May 2024 05:18:02 +0000 (01:18 -0400)
committerAdam C. Emerson <aemerson@redhat.com>
Tue, 1 Apr 2025 15:10:13 +0000 (11:10 -0400)
Signed-off-by: Adam Emerson <aemerson@redhat.com>
src/neorados/RADOS.cc
src/osdc/Objecter.cc
src/test/neorados/read_operations.cc
src/test/neorados/write_operations.cc

index b03a7f9b560c6691429a2cbbf0a8562ac81c0fab..b5d0eb4a8823ef602fbf45ae7781cbea51f76111 100644 (file)
@@ -1410,7 +1410,9 @@ void RADOS::unwatch_(uint64_t cookie, IOContext _ioc,
                           [objecter = impl->objecter,
                            linger_op, c = std::move(c)]
                           (bs::error_code ec) mutable {
-                            objecter->linger_cancel(linger_op);
+                            if (!ec) {
+                              objecter->linger_cancel(linger_op);
+                            }
                             asio::dispatch(asio::append(std::move(c), ec));
                           }));
 }
index ad371fefb2dde5ecc77b22d09d0e8a89dd205b33..7a97aab8756c9eaad2fe49a906a7f134bc8a8087 100644 (file)
@@ -60,6 +60,7 @@
 #include "common/async/waiter.h"
 #include "error_code.h"
 
+#include "neorados/RADOSImpl.h"
 
 using std::list;
 using std::make_pair;
@@ -2420,6 +2421,23 @@ void Objecter::_send_op_account(Op *op)
   }
 }
 
+struct op_cancellation {
+  ceph_tid_t tid;
+  Objecter* objecter;
+
+  op_cancellation(ceph_tid_t tid, Objecter* objecter)
+    : tid(tid), objecter(objecter) {}
+
+  void operator ()(asio::cancellation_type_t type) {
+    if (type == asio::cancellation_type::total ||
+       type == asio::cancellation_type::terminal) {
+      // Since nobody can cancel until we return (I hope) we shouldn't
+      // need a mutex or anything.
+      objecter->op_cancel(tid, asio::error::operation_aborted);
+    }
+  }
+};
+
 void Objecter::_op_submit(Op *op, shunique_lock<ceph::shared_mutex>& sul, ceph_tid_t *ptid)
 {
   // rwlock is locked
@@ -2503,6 +2521,16 @@ void Objecter::_op_submit(Op *op, shunique_lock<ceph::shared_mutex>& sul, ceph_t
 
   _session_op_assign(s, op);
 
+
+  auto compptr = std::get_if<Op::OpComp>(&op->onfinish);
+  if (compptr) {
+    // arrange for per-op cancellation
+    auto slot = boost::asio::get_associated_cancellation_slot(*compptr);
+    if (slot.is_connected()) {
+      slot.template emplace<op_cancellation>(op->tid, this);
+    }
+  }
+
   if (need_send) {
     _send_op(op);
   }
index d5df84585b8e0ad148e048f28e4697ae9db66991..352bef4973cd6aa4f5c0a7c6dcb9f40d6721af12 100644 (file)
@@ -19,6 +19,7 @@
 #include <utility>
 
 #include <boost/asio/use_awaitable.hpp>
+#include <boost/asio/experimental/awaitable_operators.hpp>
 
 #include <boost/container/flat_map.hpp>
 
@@ -748,3 +749,11 @@ CORO_TEST_F(NeoRadosReadOps, CmpExt, ReadOpTest) {
   }
   co_return;
 }
+
+CORO_TEST_F(NeoRadosReadOps, Cancel, ReadOpTest) {
+  using namespace boost::asio::experimental::awaitable_operators;
+  auto bl = filled_buffer_list(0x33, 4 * 1 << 20);
+  co_await execute(oid, WriteOp{}.write_full(std::move(bl)));
+  co_await (execute(oid, ReadOp{}.read(0, 0, &bl)) || wait_for(1us));
+  co_return;
+}
index 7dd720295d89d8ac6f507d5e40fd3ebad00b2ff7..293d5690dd9bbfb9a536b06d07493843cc45360e 100644 (file)
@@ -17,6 +17,7 @@
 #include <utility>
 
 #include <boost/asio/use_awaitable.hpp>
+#include <boost/asio/experimental/awaitable_operators.hpp>
 
 #include <boost/system/error_code.hpp>
 #include <boost/system/errc.hpp>
@@ -191,3 +192,10 @@ CORO_TEST_F(NeoRadosWriteOps, CmpExt, NeoRadosTest) {
   }
   co_return;
 }
+
+CORO_TEST_F(NeoRadosWriteOps, Cancel, NeoRadosTest) {
+  using namespace boost::asio::experimental::awaitable_operators;
+  auto bl = filled_buffer_list(0x33, 4 * 1 << 20);
+  co_await (execute(oid, WriteOp{}.write_full(std::move(bl))) || wait_for(1us));
+  co_return;
+}