From e307b9aefb4b0d8735db00b361e12f2d0eda95a2 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Tue, 25 Aug 2020 17:30:00 +0800 Subject: [PATCH] crimson/osd: drop misdirected ops see also `PrimaryLogPG::do_op()`, we should ignore the ops hitting us if we are not supposed to serve them. this happens when the client is using a stale osdmap. Fixes: https://tracker.ceph.com/issues/47031 Signed-off-by: Kefu Chai --- .../osd/osd_operations/client_request.cc | 31 ++++++++++++++++++- .../osd/osd_operations/client_request.h | 3 ++ src/crimson/osd/pg.h | 3 ++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/crimson/osd/osd_operations/client_request.cc b/src/crimson/osd/osd_operations/client_request.cc index 339d4c0935f78..c14a83a1c4737 100644 --- a/src/crimson/osd/osd_operations/client_request.cc +++ b/src/crimson/osd/osd_operations/client_request.cc @@ -137,8 +137,12 @@ seastar::future<> ClientRequest::process_op( return seastar::now(); }).then([this, &pg] { return with_blocking_future(handle.enter(pp(pg).get_obc)); - }).then([this, &pg]() { + }).then([this, &pg]() -> PG::load_obc_ertr::future<> { op_info.set_from_op(&*m, *pg.get_osdmap()); + if (is_misdirected(pg)) { + logger().trace("process_op: dropping misdirected op"); + return seastar::now(); + } return pg.with_locked_obc( m, op_info, @@ -159,4 +163,29 @@ seastar::future<> ClientRequest::process_op( })); } +bool ClientRequest::is_misdirected(const PG& pg) const +{ + // primary can handle both normal ops and balanced reads + if (pg.is_primary()) { + return false; + } + // otherwise take a closer look + if (const int flags = m->get_flags(); + flags & CEPH_OSD_FLAG_BALANCE_READS || + flags & CEPH_OSD_FLAG_LOCALIZE_READS) { + if (!op_info.may_read()) { + // no read found, so it can't be balanced read + return true; + } + if (op_info.may_write() || op_info.may_cache()) { + // write op, but i am not primary + return true; + } + // balanced reads; any replica will do + return pg.is_nonprimary(); + } + // neither balanced nor localize reads + return true; +} + } diff --git a/src/crimson/osd/osd_operations/client_request.h b/src/crimson/osd/osd_operations/client_request.h index d2fdbe926dfe2..ea3124a93e532 100644 --- a/src/crimson/osd/osd_operations/client_request.h +++ b/src/crimson/osd/osd_operations/client_request.h @@ -68,6 +68,9 @@ private: ConnectionPipeline &cp(); PGPipeline &pp(PG &pg); + +private: + bool is_misdirected(const PG& pg) const; }; } diff --git a/src/crimson/osd/pg.h b/src/crimson/osd/pg.h index 421ff418e4ef2..9335ca35fcca6 100644 --- a/src/crimson/osd/pg.h +++ b/src/crimson/osd/pg.h @@ -427,6 +427,9 @@ public: bool is_primary() const final { return peering_state.is_primary(); } + bool is_nonprimary() const { + return peering_state.is_nonprimary(); + } bool is_peered() const final { return peering_state.is_peered(); } -- 2.39.5