From 33e5e6080b0e8e5bac31ddf3167f5db27e97c34f Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Fri, 15 Sep 2023 08:41:35 +0800 Subject: [PATCH] mds: record the internal client request and receive client reply This will be used to avoid possible multiple reintegration issue later. Fixes: https://tracker.ceph.com/issues/62702 Signed-off-by: Xiubo Li (cherry picked from commit 723c1b7c9e773a68b6c2586155092ca95ab4f3e7) Conflicts: with commit 7243b680526 ("mds: ensure next replay is queued on req drop") --- src/mds/MDSMetaRequest.h | 33 +++++++++++++++++++++++++++++++++ src/mds/MDSRank.cc | 2 ++ src/mds/MDSRank.h | 3 +++ src/mds/Server.cc | 30 ++++++++++++++++++++++++++++++ src/mds/Server.h | 1 + 5 files changed, 69 insertions(+) create mode 100644 src/mds/MDSMetaRequest.h diff --git a/src/mds/MDSMetaRequest.h b/src/mds/MDSMetaRequest.h new file mode 100644 index 0000000000000..ad47204106869 --- /dev/null +++ b/src/mds/MDSMetaRequest.h @@ -0,0 +1,33 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2023 Red Hat, Inc. + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_MDS_META_REQUEST_H +#define CEPH_MDS_META_REQUEST_H + +#include "include/types.h" + +struct MDSMetaRequest { +private: + int op; + ceph_tid_t tid; +public: + explicit MDSMetaRequest(int o, ceph_tid_t t) : + op(o), tid(t) { } + virtual ~MDSMetaRequest() { } + + int get_op() { return op; } + ceph_tid_t get_tid() { return tid; } +}; + +#endif // !CEPH_MDS_META_REQUEST_H diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index c5eaf9873ec8d..4f2e13b90be7f 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -1179,6 +1179,7 @@ bool MDSRank::is_valid_message(const cref_t &m) { type == CEPH_MSG_CLIENT_RECONNECT || type == CEPH_MSG_CLIENT_RECLAIM || type == CEPH_MSG_CLIENT_REQUEST || + type == CEPH_MSG_CLIENT_REPLY || type == MSG_MDS_PEER_REQUEST || type == MSG_MDS_HEARTBEAT || type == MSG_MDS_TABLE_REQUEST || @@ -1232,6 +1233,7 @@ void MDSRank::handle_message(const cref_t &m) ALLOW_MESSAGES_FROM(CEPH_ENTITY_TYPE_CLIENT); // fall-thru case CEPH_MSG_CLIENT_REQUEST: + case CEPH_MSG_CLIENT_REPLY: server->dispatch(m); break; case MSG_MDS_PEER_REQUEST: diff --git a/src/mds/MDSRank.h b/src/mds/MDSRank.h index 1744e8268dd3b..31effdaae3bd6 100644 --- a/src/mds/MDSRank.h +++ b/src/mds/MDSRank.h @@ -43,6 +43,7 @@ #include "Server.h" #include "MetricsHandler.h" #include "osdc/Journaler.h" +#include "MDSMetaRequest.h" // Full .h import instead of forward declaration for PerfCounter, for the // benefit of those including this header and using MDSRank::logger @@ -423,6 +424,8 @@ class MDSRank { PerfCounters *logger = nullptr, *mlogger = nullptr; OpTracker op_tracker; + std::map> internal_client_requests; + // The last different state I held before current MDSMap::DaemonState last_state = MDSMap::STATE_BOOT; // The state assigned to me by the MDSMap diff --git a/src/mds/Server.cc b/src/mds/Server.cc index e6fe0f8c9a1c1..dbb0067020d4e 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -31,6 +31,7 @@ #include "Mutation.h" #include "MetricsHandler.h" #include "cephfs_features.h" +#include "MDSContext.h" #include "msg/Messenger.h" @@ -358,6 +359,9 @@ void Server::dispatch(const cref_t &m) case CEPH_MSG_CLIENT_REQUEST: handle_client_request(ref_cast(m)); return; + case CEPH_MSG_CLIENT_REPLY: + handle_client_reply(ref_cast(m)); + return; case CEPH_MSG_CLIENT_RECLAIM: handle_client_reclaim(ref_cast(m)); return; @@ -2289,6 +2293,10 @@ void Server::reply_client_request(MDRequestRef& mdr, const ref_t & mds->send_message_client(reply, session); } + if (client_inst.name.is_mds() && reply->get_op() == CEPH_MDS_OP_RENAME) { + mds->send_message(reply, mdr->client_request->get_connection()); + } + if (req->is_queued_for_replay()) { if (int r = reply->get_result(); r < 0) { derr << "reply_client_request: failed to replay " << *req @@ -2521,6 +2529,28 @@ void Server::handle_client_request(const cref_t &req) return; } +void Server::handle_client_reply(const cref_t &reply) +{ + dout(4) << "handle_client_reply " << *reply << dendl; + + ceph_assert(reply->is_safe()); + ceph_tid_t tid = reply->get_tid(); + + if (mds->internal_client_requests.count(tid) == 0) { + dout(1) << " no pending request on tid " << tid << dendl; + return; + } + + switch (reply->get_op()) { + case CEPH_MDS_OP_RENAME: + break; + default: + dout(5) << " unknown client op " << reply->get_op() << dendl; + } + + mds->internal_client_requests.erase(tid); +} + void Server::handle_osd_map() { /* Note that we check the OSDMAP_FULL flag directly rather than diff --git a/src/mds/Server.h b/src/mds/Server.h index efe9e0636d575..a3da04cae9834 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -158,6 +158,7 @@ public: // -- requests -- void handle_client_request(const cref_t &m); + void handle_client_reply(const cref_t &m); void journal_and_reply(MDRequestRef& mdr, CInode *tracei, CDentry *tracedn, LogEvent *le, MDSLogContextBase *fin); -- 2.39.5