From ac59f6d9e2727ba682b76864b90d3949e623fe33 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 19 Jan 2009 15:04:55 -0800 Subject: [PATCH] mds: properly close session when inodes are still being preallocated --- src/mds/InoTable.cc | 12 ++++---- src/mds/Server.cc | 73 +++++++++++++++++++++++++------------------- src/mds/SessionMap.h | 5 ++- 3 files changed, 50 insertions(+), 40 deletions(-) diff --git a/src/mds/InoTable.cc b/src/mds/InoTable.cc index b95e0ed2985bf..7dde6b29b860f 100644 --- a/src/mds/InoTable.cc +++ b/src/mds/InoTable.cc @@ -48,35 +48,35 @@ void InoTable::reset_state() inodeno_t InoTable::project_alloc_id(inodeno_t id) { + dout(10) << "project_alloc_id " << id << " to " << projected_free << "/" << free << dendl; assert(is_active()); if (!id) id = projected_free.start(); projected_free.erase(id); - dout(10) << "project_alloc_id " << id << dendl; ++projected_version; return id; } void InoTable::apply_alloc_id(inodeno_t id) { - dout(10) << "apply_alloc_id " << id << dendl; + dout(10) << "apply_alloc_id " << id << " to " << projected_free << "/" << free << dendl; free.erase(id); ++version; } void InoTable::project_alloc_ids(deque& ids, int want) { + dout(10) << "project_alloc_ids " << ids << " to " << projected_free << "/" << free << dendl; assert(is_active()); for (int i=0; i& ids) { - dout(10) << "apply_alloc_ids " << ids << dendl; + dout(10) << "apply_alloc_ids " << ids << " to " << projected_free << "/" << free << dendl; for (deque::iterator p = ids.begin(); p != ids.end(); p++) @@ -87,14 +87,14 @@ void InoTable::apply_alloc_ids(deque& ids) void InoTable::project_release_ids(deque& ids) { - dout(10) << "project_release_ids " << ids << dendl; + dout(10) << "project_release_ids " << ids << " to " << projected_free << "/" << free << dendl; for (deque::iterator p = ids.begin(); p != ids.end(); p++) projected_free.insert(*p); ++projected_version; } void InoTable::apply_release_ids(deque& ids) { - dout(10) << "apply_release_ids " << ids << dendl; + dout(10) << "apply_release_ids " << ids << " to " << projected_free << "/" << free << dendl; for (deque::iterator p = ids.begin(); p != ids.end(); p++) free.insert(*p); ++version; diff --git a/src/mds/Server.cc b/src/mds/Server.cc index e8d2c8e0a7b42..7bb850bec7cb8 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -137,7 +137,9 @@ public: C_MDS_session_finish(MDS *m, Session *se, bool s, version_t mv) : mds(m), session(se), open(s), cmapv(mv), inotablev(0) { } C_MDS_session_finish(MDS *m, Session *se, bool s, version_t mv, deque& i, version_t iv) : - mds(m), session(se), open(s), cmapv(mv), inos(i), inotablev(iv) { } + mds(m), session(se), open(s), cmapv(mv), inotablev(iv) { + inos.swap(i); + } void finish(int r) { assert(r == 0); mds->server->_session_logged(session, open, cmapv, inos, inotablev); @@ -183,30 +185,36 @@ void Server::handle_client_session(MClientSession *m) break; case CEPH_SESSION_REQUEST_CLOSE: - if (!session || session->is_closing()) { - dout(10) << "already closing|dne, dropping this req" << dendl; - return; - } - if (m->seq < session->get_push_seq()) { - dout(10) << "old push seq " << m->seq << " < " << session->get_push_seq() - << ", dropping" << dendl; - return; - } - if (m->seq != session->get_push_seq()) { - dout(10) << "old push seq " << m->seq << " != " << session->get_push_seq() - << ", BUGGY!" << dendl; - assert(0); + { + if (!session || session->is_closing()) { + dout(10) << "already closing|dne, dropping this req" << dendl; + return; + } + if (m->seq < session->get_push_seq()) { + dout(10) << "old push seq " << m->seq << " < " << session->get_push_seq() + << ", dropping" << dendl; + return; + } + if (m->seq != session->get_push_seq()) { + dout(10) << "old push seq " << m->seq << " != " << session->get_push_seq() + << ", BUGGY!" << dendl; + assert(0); + } + mds->sessionmap.set_state(session, Session::STATE_CLOSING); + pv = ++mds->sessionmap.projected; + + deque both = session->prealloc_inos; + both.insert(both.end(), session->pending_prealloc_inos.begin(), + session->pending_prealloc_inos.end()); + if (both.size()) { + mds->inotable->project_release_ids(both); + piv = mds->inotable->get_projected_version(); + } else + piv = 0; + + mdlog->submit_entry(new ESession(m->get_source_inst(), false, pv, both, piv), + new C_MDS_session_finish(mds, session, false, pv, both, piv)); } - mds->sessionmap.set_state(session, Session::STATE_CLOSING); - pv = ++mds->sessionmap.projected; - if (session->prealloc_inos.size()) { - assert(session->projected_inos == 0); - mds->inotable->project_release_ids(session->prealloc_inos); - piv = mds->inotable->get_projected_version(); - } else - piv = 0; - mdlog->submit_entry(new ESession(m->get_source_inst(), false, pv, session->prealloc_inos, piv), - new C_MDS_session_finish(mds, session, false, pv, session->prealloc_inos, piv)); break; default: @@ -1365,11 +1373,12 @@ CInode* Server::prepare_new_inode(MDRequest *mdr, CDir *dir, inodeno_t useino) assert(0); // just for now. } - int want = g_conf.mds_client_prealloc_inos - mdr->session->get_num_projected_prealloc_inos(); - if (want > 0) { - mds->inotable->project_alloc_ids(mdr->prealloc_inos, want); + int got = g_conf.mds_client_prealloc_inos - mdr->session->get_num_projected_prealloc_inos(); + if (got > 0) { + mds->inotable->project_alloc_ids(mdr->prealloc_inos, got); assert(mdr->prealloc_inos.size()); // or else fix projected increment semantics - mdr->session->projected_inos += mdr->prealloc_inos.size(); + mdr->session->pending_prealloc_inos.insert(mdr->session->pending_prealloc_inos.end(), + mdr->prealloc_inos.begin(), mdr->prealloc_inos.end()); mds->sessionmap.projected++; dout(10) << "prepare_new_inode prealloc " << mdr->prealloc_inos << dendl; } @@ -1412,9 +1421,11 @@ void Server::apply_allocated_inos(MDRequest *mdr) if (mdr->prealloc_inos.size()) { for (deque::iterator p = mdr->prealloc_inos.begin(); p != mdr->prealloc_inos.end(); - p++) - session->prealloc_inos.push_back(*p); - session->projected_inos -= mdr->prealloc_inos.size(); + p++) { + assert(session->pending_prealloc_inos.front() == *p); + session->prealloc_inos.push_back(session->pending_prealloc_inos.front()); + session->pending_prealloc_inos.pop_front(); + } mds->sessionmap.version++; mds->inotable->apply_alloc_ids(mdr->prealloc_inos); } diff --git a/src/mds/SessionMap.h b/src/mds/SessionMap.h index 69b518f529849..c58b6e0673980 100644 --- a/src/mds/SessionMap.h +++ b/src/mds/SessionMap.h @@ -52,7 +52,7 @@ public: entity_inst_t inst; xlist::item session_list_item; - int projected_inos; // journaling prealloc, will be added to prealloc_inos + deque pending_prealloc_inos; // journaling prealloc, will be added to prealloc_inos deque prealloc_inos; // preallocated, ready to use. deque used_inos; // journaling use @@ -77,7 +77,7 @@ public: return ino; } int get_num_projected_prealloc_inos() { - return prealloc_inos.size() + projected_inos; + return prealloc_inos.size() + pending_prealloc_inos.size(); } int get_client() { return inst.name.num(); } @@ -143,7 +143,6 @@ public: Session() : state(STATE_UNDEF), session_list_item(this), - projected_inos(0), cap_push_seq(0) { } void encode(bufferlist& bl) const { -- 2.39.5