]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: defer swapping the newmap to mdsmap
authorXiubo Li <xiubli@redhat.com>
Wed, 15 Jul 2020 02:40:35 +0000 (10:40 +0800)
committerXiubo Li <xiubli@redhat.com>
Tue, 20 Oct 2020 12:14:48 +0000 (08:14 -0400)
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 <xiubli@redhat.com>
src/client/Client.cc

index 431346afa5f173c33528afd7c2d73f5ae3a0a373..4f929a39e349a8003ac9e4a56272ba93f4f930fc 100644 (file)
@@ -2732,9 +2732,8 @@ void Client::handle_mds_map(const MConstRef<MMDSMap>& m)
   ldout(cct, 1) << __func__ << " epoch " << m->get_epoch() << dendl;
 
   std::unique_ptr<MDSMap> 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<ceph_tid_t> cancel_ops;
@@ -2742,7 +2741,7 @@ void Client::handle_mds_map(const MConstRef<MMDSMap>& 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<MMDSMap>& 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<MMDSMap>& 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);