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<inodeno_t>& ids, int want)
{
+ dout(10) << "project_alloc_ids " << ids << " to " << projected_free << "/" << free << dendl;
assert(is_active());
for (int i=0; i<want; i++) {
inodeno_t id = projected_free.start();
projected_free.erase(id);
ids.push_back(id);
}
- dout(10) << "project_alloc_ids " << ids << dendl;
++projected_version;
}
void InoTable::apply_alloc_ids(deque<inodeno_t>& ids)
{
- dout(10) << "apply_alloc_ids " << ids << dendl;
+ dout(10) << "apply_alloc_ids " << ids << " to " << projected_free << "/" << free << dendl;
for (deque<inodeno_t>::iterator p = ids.begin();
p != ids.end();
p++)
void InoTable::project_release_ids(deque<inodeno_t>& ids)
{
- dout(10) << "project_release_ids " << ids << dendl;
+ dout(10) << "project_release_ids " << ids << " to " << projected_free << "/" << free << dendl;
for (deque<inodeno_t>::iterator p = ids.begin(); p != ids.end(); p++)
projected_free.insert(*p);
++projected_version;
}
void InoTable::apply_release_ids(deque<inodeno_t>& ids)
{
- dout(10) << "apply_release_ids " << ids << dendl;
+ dout(10) << "apply_release_ids " << ids << " to " << projected_free << "/" << free << dendl;
for (deque<inodeno_t>::iterator p = ids.begin(); p != ids.end(); p++)
free.insert(*p);
++version;
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<inodeno_t>& 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);
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<inodeno_t> 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:
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;
}
if (mdr->prealloc_inos.size()) {
for (deque<inodeno_t>::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);
}