From 7d10b8d61c2cc579bd1dd2851f5e19b7fd3ca94c Mon Sep 17 00:00:00 2001 From: Adam Emerson Date: Wed, 1 May 2024 01:18:02 -0400 Subject: [PATCH] neorados: Cancel ReadOp/WriteOp execute Signed-off-by: Adam Emerson --- src/neorados/RADOS.cc | 4 +++- src/osdc/Objecter.cc | 28 +++++++++++++++++++++++++++ src/test/neorados/read_operations.cc | 9 +++++++++ src/test/neorados/write_operations.cc | 8 ++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/neorados/RADOS.cc b/src/neorados/RADOS.cc index b03a7f9b560c6..b5d0eb4a8823e 100644 --- a/src/neorados/RADOS.cc +++ b/src/neorados/RADOS.cc @@ -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)); })); } diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index ad371fefb2dde..7a97aab8756c9 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -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& sul, ceph_tid_t *ptid) { // rwlock is locked @@ -2503,6 +2521,16 @@ void Objecter::_op_submit(Op *op, shunique_lock& sul, ceph_t _session_op_assign(s, op); + + auto compptr = std::get_if(&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->tid, this); + } + } + if (need_send) { _send_op(op); } diff --git a/src/test/neorados/read_operations.cc b/src/test/neorados/read_operations.cc index d5df84585b8e0..352bef4973cd6 100644 --- a/src/test/neorados/read_operations.cc +++ b/src/test/neorados/read_operations.cc @@ -19,6 +19,7 @@ #include #include +#include #include @@ -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; +} diff --git a/src/test/neorados/write_operations.cc b/src/test/neorados/write_operations.cc index 7dd720295d89d..293d5690dd9bb 100644 --- a/src/test/neorados/write_operations.cc +++ b/src/test/neorados/write_operations.cc @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -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; +} -- 2.39.5