}
assert(!session); // ?
session = mds->sessionmap.get_or_add_session(m->get_source_inst());
- session->state = Session::STATE_OPENING;
+ mds->sessionmap.set_state(session, Session::STATE_OPENING);
mds->sessionmap.touch_session(session);
pv = ++mds->sessionmap.projected;
mdlog->submit_entry(new ESession(m->get_source_inst(), true, pv),
assert(0);
return;
}
- session->state = Session::STATE_OPEN;
+ mds->sessionmap.set_state(session, Session::STATE_OPEN);
mds->sessionmap.touch_session(session);
mds->locker->resume_stale_caps(session);
mds->messenger->send_message(new MClientSession(CEPH_SESSION_RESUME, m->stamp), session->inst);
return;
}
assert(m->seq == session->get_push_seq());
- session->state = Session::STATE_CLOSING;
+ mds->sessionmap.set_state(session, Session::STATE_CLOSING);
pv = ++mds->sessionmap.projected;
mdlog->submit_entry(new ESession(m->get_source_inst(), false, pv),
new C_MDS_session_finish(mds, session, false, pv));
// apply
if (open) {
assert(session->is_opening());
- session->state = Session::STATE_OPEN;
+ mds->sessionmap.set_state(session, Session::STATE_OPEN);
mds->sessionmap.version++;
} else if (session->is_closing()) {
mds->sessionmap.remove_session(session);
mds->sessionmap.version++;
+
+ // kill any lingering capabilities
+ for (xlist<Capability*>::iterator p = session->caps.begin(); !p.end(); ++p) {
+ CInode *in = (*p)->get_inode();
+ dout(10) << " killing capability on " << *in << dendl;
+ in->remove_client_cap(session->inst.name.num());
+ }
+
} else {
// close must have been canceled (by an import?) ...
assert(!open);
<< dendl;
for (map<int,entity_inst_t>::iterator p = cm.begin(); p != cm.end(); ++p) {
Session *session = mds->sessionmap.get_or_add_session(p->second);
- if (session->state == Session::STATE_UNDEF ||
- session->state == Session::STATE_CLOSING)
- session->state = Session::STATE_OPENING;
+ if (session->is_undef() || session->is_closing())
+ mds->sessionmap.set_state(session, Session::STATE_OPENING);
}
}
assert(session);
if (session->is_opening()) {
dout(10) << "force_open_sessions opening " << session->inst << dendl;
- session->state = Session::STATE_OPEN;
+ mds->sessionmap.set_state(session, Session::STATE_OPEN);
mds->messenger->send_message(new MClientSession(CEPH_SESSION_OPEN), session->inst);
}
}
++p) {
Session *session = *p;
if (session->is_closing()) continue;
- session->state = Session::STATE_CLOSING;
+ mds->sessionmap.set_state(session, Session::STATE_CLOSING);
version_t pv = ++mds->sessionmap.projected;
mdlog->submit_entry(new ESession(session->inst, false, pv),
new C_MDS_session_finish(mds, session, false, pv));
utime_t cutoff = now;
cutoff -= g_conf.mds_cap_timeout;
while (1) {
- Session *session = mds->sessionmap.get_oldest_active_session();
+ Session *session = mds->sessionmap.get_oldest_session(Session::STATE_OPEN);
if (!session) break;
dout(20) << "laggiest active session is " << session->inst << dendl;
if (session->last_cap_renew >= cutoff) {
}
dout(10) << "new stale session " << session->inst << " last " << session->last_cap_renew << dendl;
- mds->sessionmap.mark_session_stale(session);
+ mds->sessionmap.set_state(session, Session::STATE_STALE);
mds->locker->revoke_stale_caps(session);
mds->messenger->send_message(new MClientSession(CEPH_SESSION_STALE, g_clock.now()),
session->inst);
cutoff = now;
cutoff -= g_conf.mds_session_autoclose;
while (1) {
- Session *session = mds->sessionmap.get_oldest_stale_session();
+ Session *session = mds->sessionmap.get_oldest_session(Session::STATE_STALE);
if (!session) break;
+ assert(session->is_stale());
dout(20) << "oldest stale session is " << session->inst << dendl;
if (session->last_cap_renew >= cutoff) {
dout(20) << "oldest stale session is " << session->inst << " and sufficiently new ("
}
dout(10) << "autoclosing stale session " << session->inst << " last " << session->last_cap_renew << dendl;
-
- mds->sessionmap.mark_session_stale(session);
- mds->locker->revoke_stale_caps(session);
- mds->messenger->send_message(new MClientSession(CEPH_SESSION_CLOSE),
- session->inst);
+ mds->sessionmap.set_state(session, Session::STATE_CLOSING);
+ version_t pv = ++mds->sessionmap.projected;
+ mdlog->submit_entry(new ESession(session->inst, false, pv),
+ new C_MDS_session_finish(mds, session, false, pv));
}
-
}
static const int STATE_STALE = 4;
static const int STATE_RECONNECTING = 5; // ?
+private:
int state;
+ friend class SessionMap;
+public:
entity_inst_t inst;
xlist<Session*>::item session_list_item;
+ bool is_undef() { return state == STATE_UNDEF; }
bool is_opening() { return state == STATE_OPENING; }
bool is_open() { return state == STATE_OPEN; }
bool is_closing() { return state == STATE_CLOSING; }
MDS *mds;
hash_map<entity_name_t, Session*> session_map;
public:
- xlist<Session*> active_sessions;
- xlist<Session*> stale_sessions;
+ map<int,xlist<Session*> > by_state;
public: // i am lazy
version_t version, projected, committing, committed;
}
void touch_session(Session *s) {
s->last_cap_renew = g_clock.now();
- active_sessions.push_back(&s->session_list_item);
}
- Session *get_oldest_active_session() {
- if (active_sessions.empty()) return 0;
- return active_sessions.front();
+ Session *get_oldest_session(int state) {
+ if (by_state[state].empty()) return 0;
+ return by_state[state].front();
}
- void mark_session_stale(Session *s) {
- stale_sessions.push_back(&s->session_list_item);
- }
- Session *get_oldest_stale_session() {
- if (stale_sessions.empty()) return 0;
- return stale_sessions.front();
+ void set_state(Session *session, int s) {
+ if (session->state != s) {
+ session->state = s;
+ by_state[s].push_back(&session->session_list_item);
+ }
}
void get_client_set(set<int>& s) {
++p) {
Session *session = get_or_add_session(p->second);
session->inst = p->second;
- session->state = Session::STATE_OPEN;
+ set_state(session, Session::STATE_OPEN);
}
version++;
}