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
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) :
* 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));
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() ||
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);
// 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
<< ", 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++;