From: Xiubo Li Date: Wed, 15 Jul 2020 02:40:35 +0000 (+0800) Subject: client: defer swapping the newmap to mdsmap X-Git-Tag: v16.1.0~782^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b835cad14d031faefad2ceb1651de9be49134f65;p=ceph.git client: defer swapping the newmap to mdsmap This is preparing for adding the command lock support. For the new mds map we could access it without the client_lock, so before swaping it to the `mdsmap` member, it will be safe to access. With this we can defer to hold the client_lock and it will be safe for the new command_lock to avoid possible dead lock in future or something else. Fixes: https://tracker.ceph.com/issues/46620 Signed-off-by: Xiubo Li --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 431346afa5f..4f929a39e34 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -2732,9 +2732,8 @@ void Client::handle_mds_map(const MConstRef& m) ldout(cct, 1) << __func__ << " epoch " << m->get_epoch() << dendl; std::unique_ptr oldmap(new MDSMap); - oldmap.swap(mdsmap); - mdsmap->decode(m->get_encoded()); + oldmap->decode(m->get_encoded()); // Cancel any commands for missing or laggy GIDs std::list cancel_ops; @@ -2742,7 +2741,7 @@ void Client::handle_mds_map(const MConstRef& m) for (const auto &i : commands) { auto &op = i.second; const mds_gid_t op_mds_gid = op.mds_gid; - if (mdsmap->is_dne_gid(op_mds_gid) || mdsmap->is_laggy_gid(op_mds_gid)) { + if (oldmap->is_dne_gid(op_mds_gid) || oldmap->is_laggy_gid(op_mds_gid)) { ldout(cct, 1) << __func__ << ": cancelling command op " << i.first << dendl; cancel_ops.push_back(i.first); if (op.outs) { @@ -2760,6 +2759,8 @@ void Client::handle_mds_map(const MConstRef& m) for (const auto &tid : cancel_ops) command_table.erase(tid); + oldmap.swap(mdsmap); + // reset session for (auto p = mds_sessions.begin(); p != mds_sessions.end(); ) { mds_rank_t mds = p->first; @@ -2786,7 +2787,7 @@ void Client::handle_mds_map(const MConstRef& m) trim_cache_for_reconnect(session); } else if (oldstate == newstate) continue; // no change - + session->mds_state = newstate; if (newstate == MDSMap::STATE_RECONNECT) { session->con = messenger->connect_to_mds(session->addrs);