]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: purge orphan objects created by lost async file creation
authorYan, Zheng <zyan@redhat.com>
Tue, 28 Jul 2020 09:27:18 +0000 (17:27 +0800)
committerYan, Zheng <ukernel@gmail.com>
Mon, 1 Feb 2021 05:46:21 +0000 (13:46 +0800)
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/mds/Server.cc
src/mds/Server.h

index 19c5d1f8a45a69a2e483dc8a12636a64a14833da..61a67d8a50ec2fac94d3a2b170f681da82c97199 100644 (file)
@@ -297,7 +297,14 @@ void Server::dispatch(const cref_t<Message> &m)
        queue_replay = true;
        if (req->head.ino &&
            !session->have_completed_request(req->get_reqid().tid, nullptr)) {
-         mdcache->add_replay_ino_alloc(inodeno_t(req->head.ino));
+         inodeno_t ino(req->head.ino);
+         mdcache->add_replay_ino_alloc(ino);
+         if (replay_unsafe_with_closed_session &&
+             session->free_prealloc_inos.contains(ino)) {
+           // don't purge inodes that will be created by later replay
+           session->free_prealloc_inos.erase(ino);
+           session->delegated_inos.insert(ino);
+         }
        }
       } else if (req->get_retry_attempt()) {
        // process completed request in clientreplay stage. The completed request
@@ -370,10 +377,6 @@ class C_MDS_session_finish : public ServerLogContext {
 public:
   C_MDS_session_finish(Server *srv, Session *se, uint64_t sseq, bool s, version_t mv, Context *fin_ = nullptr) :
     ServerLogContext(srv), session(se), state_seq(sseq), open(s), cmapv(mv), inotablev(0), fin(fin_) { }
-  C_MDS_session_finish(Server *srv, Session *se, uint64_t sseq, bool s, version_t mv,
-                      const interval_set<inodeno_t>& to_free, version_t iv, Context *fin_ = nullptr) :
-    ServerLogContext(srv), session(se), state_seq(sseq), open(s), cmapv(mv),
-    inos_to_free(to_free), inotablev(iv), fin(fin_) { }
   C_MDS_session_finish(Server *srv, Session *se, uint64_t sseq, bool s, version_t mv,
                       const interval_set<inodeno_t>& to_free, version_t iv,
                       const interval_set<inodeno_t>& to_purge, LogSegment *_ls, Context *fin_ = nullptr) :
@@ -1255,7 +1258,7 @@ void Server::handle_conf_change(const std::set<std::string>& changed) {
  * XXX bump in the interface here, not using an MDSContext here
  * because all the callers right now happen to use a SaferCond
  */
-void Server::kill_session(Session *session, Context *on_safe, bool need_purge_inos)
+void Server::kill_session(Session *session, Context *on_safe)
 {
   ceph_assert(ceph_mutex_is_locked_by_me(mds->mds_lock));
 
@@ -1264,7 +1267,7 @@ void Server::kill_session(Session *session, Context *on_safe, bool need_purge_in
        session->is_stale()) &&
       !session->is_importing()) {
     dout(10) << "kill_session " << session << dendl;
-    journal_close_session(session, Session::STATE_KILLING, on_safe, need_purge_inos);
+    journal_close_session(session, Session::STATE_KILLING, on_safe);
   } else {
     dout(10) << "kill_session importing or already closing/killing " << session << dendl;
     if (session->is_closing() ||
@@ -1322,12 +1325,13 @@ size_t Server::apply_blocklist(const std::set<entity_addr_t> &blocklist)
   return victims.size();
 }
 
-void Server::journal_close_session(Session *session, int state, Context *on_safe, bool need_purge_inos)
+void Server::journal_close_session(Session *session, int state, Context *on_safe)
 {
   dout(10) << __func__ << " : "
-          << "("<< need_purge_inos << ")"
           << session->info.inst
-          << "(" << session->info.prealloc_inos.size() << "|" << session->pending_prealloc_inos.size() << ")" << dendl;
+          << " pending_prealloc_inos " << session->pending_prealloc_inos
+          << " free_prealloc_inos " << session->free_prealloc_inos
+          << " delegated_inos " << session->delegated_inos << dendl;
 
   uint64_t sseq = mds->sessionmap.set_state(session, state);
   version_t pv = mds->sessionmap.mark_projected(session);
@@ -1335,29 +1339,19 @@ void Server::journal_close_session(Session *session, int state, Context *on_safe
 
   // release alloc and pending-alloc inos for this session
   // and wipe out session state, in case the session close aborts for some reason
-  interval_set<inodeno_t> both;
-  both.insert(session->pending_prealloc_inos);
-  if (!need_purge_inos)
-    both.insert(session->info.prealloc_inos);
-  if (both.size()) {
-    mds->inotable->project_release_ids(both);
+  interval_set<inodeno_t> inos_to_free;
+  inos_to_free.insert(session->pending_prealloc_inos);
+  inos_to_free.insert(session->free_prealloc_inos);
+  if (inos_to_free.size()) {
+    mds->inotable->project_release_ids(inos_to_free);
     piv = mds->inotable->get_projected_version();
   } else
     piv = 0;
   
-  if(need_purge_inos && session->info.prealloc_inos.size()) {
-    dout(10) << "start purge indoes " << session->info.prealloc_inos << dendl;
-    LogSegment* ls = mdlog->get_current_segment();
-    LogEvent* e = new ESession(session->info.inst, false, pv, both, piv, session->info.prealloc_inos);
-    MDSLogContextBase* c = new C_MDS_session_finish(this, session, sseq, false, pv, both, piv,
-                                                   session->info.prealloc_inos, ls, on_safe);
-    mdlog->start_submit_entry(e, c);
-  } else {
-    interval_set<inodeno_t> empty;
-    LogEvent* e = new ESession(session->info.inst, false, pv, both, piv, empty);
-    MDSLogContextBase* c = new C_MDS_session_finish(this, session, sseq, false, pv, both, piv, on_safe);
-    mdlog->start_submit_entry(e, c);
-  }
+  auto le = new ESession(session->info.inst, false, pv, inos_to_free, piv, session->delegated_inos);
+  auto fin = new C_MDS_session_finish(this, session, sseq, false, pv, inos_to_free, piv,
+                                     session->delegated_inos, mdlog->get_current_segment(), on_safe);
+  mdlog->start_submit_entry(le, fin);
   mdlog->flush();
 
   // clean up requests, too
@@ -1703,12 +1697,15 @@ void Server::reconnect_tick()
                      << ", after waiting " << elapse1
                      << " seconds during MDS startup";
 
+    // make _session_logged() purge orphan objects of lost async/unsafe requests
+    session->delegated_inos.swap(session->free_prealloc_inos);
+
     if (g_conf()->mds_session_blocklist_on_timeout) {
       CachedStackStringStream css;
       mds->evict_client(session->get_client().v, false, true, *css,
                        gather.new_sub());
     } else {
-      kill_session(session, NULL, true);
+      kill_session(session, NULL);
     }
 
     failed_reconnects++;
index 0074c4ff1eada14f57752425a3d0b57636caefaa..2021ec53e33fc0a578692c53dca8e35724fb2490 100644 (file)
@@ -130,9 +130,10 @@ public:
   void finish_flush_session(Session *session, version_t seq);
   void terminate_sessions();
   void find_idle_sessions();
-  void kill_session(Session *session, Context *on_safe, bool need_purge_inos = false);
+
+  void kill_session(Session *session, Context *on_safe);
   size_t apply_blocklist(const std::set<entity_addr_t> &blocklist);
-  void journal_close_session(Session *session, int state, Context *on_safe, bool need_purge_inos = false);
+  void journal_close_session(Session *session, int state, Context *on_safe);
 
   size_t get_num_pending_reclaim() const { return client_reclaim_gather.size(); }
   Session *find_session_by_uuid(std::string_view uuid);