SnapRealm *dir_realm,
snapid_t snapid, unsigned max_bytes)
{
- int client = session->inst.name.num();
+ int client = session->info.inst.name.num();
assert(snapid);
assert(session->connection);
}
// my needs
- assert(session->inst.name.is_client());
- int my_client = session->inst.name.num();
+ assert(session->info.inst.name.is_client());
+ int my_client = session->info.inst.name.num();
int my_want = ceph_caps_for_mode(mode);
// register a capability
void Locker::revoke_stale_caps(Session *session)
{
- dout(10) << "revoke_stale_caps for " << session->inst.name << dendl;
+ dout(10) << "revoke_stale_caps for " << session->info.inst.name << dendl;
client_t client = session->get_client();
for (xlist<Capability*>::iterator p = session->caps.begin(); !p.end(); ++p) {
void Locker::resume_stale_caps(Session *session)
{
- dout(10) << "resume_stale_caps for " << session->inst.name << dendl;
+ dout(10) << "resume_stale_caps for " << session->info.inst.name << dendl;
for (xlist<Capability*>::iterator p = session->caps.begin(); !p.end(); ++p) {
Capability *cap = *p;
void Locker::remove_stale_leases(Session *session)
{
- dout(10) << "remove_stale_leases for " << session->inst.name << dendl;
+ dout(10) << "remove_stale_leases for " << session->info.inst.name << dendl;
xlist<ClientLease*>::iterator p = session->leases.begin();
while (!p.end()) {
ClientLease *l = *p;
void MDCache::try_reconnect_cap(CInode *in, Session *session)
{
- client_t client = session->get_client();
+ client_t client = session->info.get_client();
ceph_mds_cap_reconnect *rc = get_replay_cap_reconnect(in->ino(), client);
if (rc) {
in->reconnect_cap(client, *rc, session);
void MDCache::do_cap_import(Session *session, CInode *in, Capability *cap)
{
- client_t client = session->inst.name.num();
+ client_t client = session->info.inst.name.num();
SnapRealm *realm = in->find_snaprealm();
if (realm->have_past_parents_open()) {
- dout(10) << "do_cap_import " << session->inst.name << " mseq " << cap->get_mseq() << " on " << *in << dendl;
+ dout(10) << "do_cap_import " << session->info.inst.name << " mseq " << cap->get_mseq() << " on " << *in << dendl;
cap->set_last_issue();
MClientCaps *reap = new MClientCaps(CEPH_CAP_OP_IMPORT,
in->ino(),
realm->build_snap_trace(reap->snapbl);
mds->send_message_client_counted(reap, session);
} else {
- dout(10) << "do_cap_import missing past snap parents, delaying " << session->inst.name << " mseq "
+ dout(10) << "do_cap_import missing past snap parents, delaying " << session->info.inst.name << " mseq "
<< cap->get_mseq() << " on " << *in << dendl;
in->auth_pin(this);
cap->inc_suppress();
void MDS::send_message_client_counted(Message *m, Session *session)
{
version_t seq = session->inc_push_seq();
- dout(10) << "send_message_client_counted " << session->inst.name << " seq "
+ dout(10) << "send_message_client_counted " << session->info.inst.name << " seq "
<< seq << " " << *m << dendl;
if (session->connection) {
messenger->send_message(m, session->connection);
void MDS::send_message_client(Message *m, Session *session)
{
- dout(10) << "send_message_client " << session->inst << " " << *m << dendl;
+ dout(10) << "send_message_client " << session->info.inst << " " << *m << dendl;
if (session->connection) {
messenger->send_message(m, session->connection);
} else {
Session *s = sessionmap.get_session(n);
if (!s) {
s = new Session;
- s->inst.addr = con->get_peer_addr();
- s->inst.name = n;
- dout(10) << " new session " << s << " for " << s->inst << " con " << con << dendl;
+ s->info.inst.addr = con->get_peer_addr();
+ s->info.inst.name = n;
+ dout(10) << " new session " << s << " for " << s->info.inst << " con " << con << dendl;
con->set_priv(s);
s->connection = con;
sessionmap.add_session(s);
} else {
- dout(10) << " existing session " << s << " for " << s->inst << " existing con " << s->connection
+ dout(10) << " existing session " << s << " for " << s->info.inst << " existing con " << s->connection
<< ", new/authorizing con " << con << dendl;
con->set_priv(s->get());
{
Session *session = (Session *)m->get_connection()->get_priv();
if (session) {
- dout(20) << "get_session have " << session << " " << session->inst
+ dout(20) << "get_session have " << session << " " << session->info.inst
<< " state " << session->get_state_name() << dendl;
session->put(); // not carry ref
} else {
void Server::_session_logged(Session *session, uint64_t state_seq, bool open, version_t pv,
interval_set<inodeno_t>& inos, version_t piv)
{
- dout(10) << "_session_logged " << session->inst << " state_seq " << state_seq << " " << (open ? "open":"close")
+ dout(10) << "_session_logged " << session->info.inst << " state_seq " << state_seq << " " << (open ? "open":"close")
<< " " << pv << dendl;
if (piv) {
Capability *cap = session->caps.front();
CInode *in = cap->get_inode();
dout(20) << " killing capability " << ccap_string(cap->issued()) << " on " << *in << dendl;
- mds->locker->remove_client_cap(in, session->inst.name.num());
+ mds->locker->remove_client_cap(in, session->info.inst.name.num());
}
while (!session->leases.empty()) {
ClientLease *r = session->leases.front();
session->clear();
} else if (session->is_killing()) {
// destroy session, close connection
- mds->messenger->mark_down(session->inst.addr);
+ mds->messenger->mark_down(session->info.inst.addr);
mds->sessionmap.remove_session(session);
} else {
assert(0);
if (sseqmap.count(p->first)) {
uint64_t sseq = sseqmap[p->first];
if (session->get_state_seq() != sseq) {
- dout(10) << "force_open_sessions skipping changed " << session->inst << dendl;
+ dout(10) << "force_open_sessions skipping changed " << session->info.inst << dendl;
} else {
- dout(10) << "force_open_sessions opened " << session->inst << dendl;
+ dout(10) << "force_open_sessions opened " << session->info.inst << dendl;
mds->sessionmap.set_state(session, Session::STATE_OPEN);
mds->sessionmap.touch_session(session);
Message *m = new MClientSession(CEPH_SESSION_OPEN);
session->preopen_out_queue.push_back(m);
}
} else {
- dout(10) << "force_open_sessions skipping already-open " << session->inst << dendl;
+ dout(10) << "force_open_sessions skipping already-open " << session->info.inst << dendl;
assert(session->is_open() || session->is_stale());
}
session->dec_importing();
while (1) {
Session *session = mds->sessionmap.get_oldest_session(Session::STATE_OPEN);
if (!session) break;
- dout(20) << "laggiest active session is " << session->inst << dendl;
+ dout(20) << "laggiest active session is " << session->info.inst << dendl;
if (session->last_cap_renew >= cutoff) {
- dout(20) << "laggiest active session is " << session->inst << " and sufficiently new ("
+ dout(20) << "laggiest active session is " << session->info.inst << " and sufficiently new ("
<< session->last_cap_renew << ")" << dendl;
break;
}
- dout(10) << "new stale session " << session->inst << " last " << session->last_cap_renew << dendl;
+ dout(10) << "new stale session " << session->info.inst << " last " << session->last_cap_renew << dendl;
mds->sessionmap.set_state(session, Session::STATE_STALE);
mds->locker->revoke_stale_caps(session);
mds->locker->remove_stale_leases(session);
if (!session)
break;
if (session->is_importing()) {
- dout(10) << "stopping at importing session " << session->inst << dendl;
+ dout(10) << "stopping at importing session " << session->info.inst << dendl;
break;
}
assert(session->is_stale());
if (session->last_cap_renew >= cutoff) {
- dout(20) << "oldest stale session is " << session->inst << " and sufficiently new ("
+ dout(20) << "oldest stale session is " << session->info.inst << " and sufficiently new ("
<< session->last_cap_renew << ")" << dendl;
break;
}
utime_t age = now;
age -= session->last_cap_renew;
- mds->clog.info() << "closing stale session " << session->inst
+ mds->clog.info() << "closing stale session " << session->info.inst
<< " after " << age << "\n";
- dout(10) << "autoclosing stale session " << session->inst << " last " << session->last_cap_renew << dendl;
+ dout(10) << "autoclosing stale session " << session->info.inst << " last " << session->last_cap_renew << dendl;
kill_session(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.swap(session->prealloc_inos);
+ both.swap(session->info.prealloc_inos);
both.insert(session->pending_prealloc_inos);
session->pending_prealloc_inos.clear();
if (both.size()) {
} else
piv = 0;
- mdlog->start_submit_entry(new ESession(session->inst, false, pv, both, piv),
+ mdlog->start_submit_entry(new ESession(session->info.inst, false, pv, both, piv),
new C_MDS_session_finish(mds, session, sseq, false, pv, both, piv));
mdlog->flush();
mds->sessionmap.set_state(session, Session::STATE_OPENING);
version_t pv = ++mds->sessionmap.projected;
uint64_t sseq = session->get_state_seq();
- mdlog->start_submit_entry(new ESession(session->inst, true, pv),
+ mdlog->start_submit_entry(new ESession(session->info.inst, true, pv),
new C_MDS_session_finish(mds, session, sseq, true, pv));
mdlog->flush();
- mds->clog.debug() << "reconnect by new " << session->inst
+ mds->clog.debug() << "reconnect by new " << session->info.inst
<< " after " << delay << "\n";
} else {
- mds->clog.debug() << "reconnect by " << session->inst
+ mds->clog.debug() << "reconnect by " << session->info.inst
<< " after " << delay << "\n";
}
p != client_reconnect_gather.end();
p++) {
Session *session = mds->sessionmap.get_session(entity_name_t::CLIENT(p->v));
- dout(1) << "reconnect gave up on " << session->inst << dendl;
+ dout(1) << "reconnect gave up on " << session->info.inst << dendl;
failed_reconnects++;
}
client_reconnect_gather.clear();
++p) {
Session *session = *p;
if (!session->is_open() ||
- !session->inst.name.is_client())
+ !session->info.inst.name.is_client())
continue;
- dout(10) << " session " << session->inst
+ dout(10) << " session " << session->info.inst
<< " caps " << session->caps.size()
<< ", leases " << session->leases.size()
<< dendl;
CInode *in = new CInode(mdcache);
// assign ino
- if (mdr->session->prealloc_inos.size()) {
+ if (mdr->session->info.prealloc_inos.size()) {
mdr->used_prealloc_ino =
in->inode.ino = mdr->session->take_ino(useino); // prealloc -> used
mds->sessionmap.projected++;
dout(10) << "prepare_new_inode used_prealloc " << mdr->used_prealloc_ino
- << " (" << mdr->session->prealloc_inos
- << ", " << mdr->session->prealloc_inos.size() << " left)"
+ << " (" << mdr->session->info.prealloc_inos
+ << ", " << mdr->session->info.prealloc_inos.size() << " left)"
<< dendl;
} else {
mdr->alloc_ino =
}
if (mdr->prealloc_inos.size()) {
session->pending_prealloc_inos.subtract(mdr->prealloc_inos);
- session->prealloc_inos.insert(mdr->prealloc_inos);
+ session->info.prealloc_inos.insert(mdr->prealloc_inos);
mds->sessionmap.version++;
mds->inotable->apply_alloc_ids(mdr->prealloc_inos);
}
if (mdr->used_prealloc_ino) {
- session->used_inos.erase(mdr->used_prealloc_ino);
+ session->info.used_inos.erase(mdr->used_prealloc_ino);
mds->sessionmap.version++;
}
}
++p)
dout(10) << p->first << " " << p->second
<< " state " << p->second->get_state_name()
- << " completed " << p->second->completed_requests
- << " prealloc_inos " << p->second->prealloc_inos
- << " used_ions " << p->second->used_inos
+ << " completed " << p->second->info.completed_requests
+ << " prealloc_inos " << p->second->info.prealloc_inos
+ << " used_ions " << p->second->info.used_inos
<< dendl;
}
p->second->is_stale() ||
p->second->is_killing()) {
::encode(p->first, bl);
- p->second->encode(bl);
+ p->second->info.encode(bl);
}
}
Session *s = get_or_add_session(inst);
if (s->is_closed())
set_state(s, Session::STATE_OPEN);
- s->decode(p);
+ s->info.decode(p);
}
} else {
while (n-- && !p.end()) {
bufferlist::iterator p2 = p;
Session *s = new Session;
- s->decode(p);
- if (session_map.count(s->inst.name)) {
+ s->info.decode(p);
+ if (session_map.count(s->info.inst.name)) {
// eager client connected too fast! aie.
- dout(10) << " already had session for " << s->inst.name << ", recovering" << dendl;
- entity_name_t n = s->inst.name;
+ dout(10) << " already had session for " << s->info.inst.name << ", recovering" << dendl;
+ entity_name_t n = s->info.inst.name;
delete s;
s = session_map[n];
p = p2;
- s->decode(p);
+ s->info.decode(p);
} else {
- session_map[s->inst.name] = s;
+ session_map[s->info.inst.name] = s;
}
set_state(s, Session::STATE_OPEN);
s->last_cap_renew = now;
p != session_map.end();
++p) {
p->second->pending_prealloc_inos.clear();
- p->second->prealloc_inos.clear();
- p->second->used_inos.clear();
+ p->second->info.prealloc_inos.clear();
+ p->second->info.used_inos.clear();
}
projected = ++version;
}
int importing_count;
friend class SessionMap;
public:
- entity_inst_t inst;
+ session_info_t info; ///< durable bits
+
Connection *connection;
xlist<Session*>::item item_session_list;
elist<MDRequest*> requests;
interval_set<inodeno_t> pending_prealloc_inos; // journaling prealloc, will be added to prealloc_inos
- interval_set<inodeno_t> prealloc_inos; // preallocated, ready to use.
- interval_set<inodeno_t> used_inos; // journaling use
inodeno_t next_ino() {
- if (prealloc_inos.empty())
+ if (info.prealloc_inos.empty())
return 0;
- return prealloc_inos.range_start();
+ return info.prealloc_inos.range_start();
}
inodeno_t take_ino(inodeno_t ino = 0) {
- assert(!prealloc_inos.empty());
+ assert(!info.prealloc_inos.empty());
if (ino) {
- if (prealloc_inos.contains(ino))
- prealloc_inos.erase(ino);
+ if (info.prealloc_inos.contains(ino))
+ info.prealloc_inos.erase(ino);
else
ino = 0;
}
if (!ino) {
- ino = prealloc_inos.range_start();
- prealloc_inos.erase(ino);
+ ino = info.prealloc_inos.range_start();
+ info.prealloc_inos.erase(ino);
}
- used_inos.insert(ino, 1);
+ info.used_inos.insert(ino, 1);
return ino;
}
int get_num_projected_prealloc_inos() {
- return prealloc_inos.size() + pending_prealloc_inos.size();
+ return info.prealloc_inos.size() + pending_prealloc_inos.size();
}
- client_t get_client() { return client_t(inst.name.num()); }
+ client_t get_client() {
+ return info.get_client();
+ }
int get_state() { return state; }
const char *get_state_name() { return get_state_name(state); }
// -- completed requests --
private:
- set<tid_t> completed_requests;
+
public:
void add_completed_request(tid_t t) {
- completed_requests.insert(t);
+ info.completed_requests.insert(t);
}
void trim_completed_requests(tid_t mintid) {
// trim
- while (!completed_requests.empty() &&
- (mintid == 0 || *completed_requests.begin() < mintid))
- completed_requests.erase(completed_requests.begin());
+ while (!info.completed_requests.empty() &&
+ (mintid == 0 || *info.completed_requests.begin() < mintid))
+ info.completed_requests.erase(info.completed_requests.begin());
}
bool have_completed_request(tid_t tid) const {
- return completed_requests.count(tid);
+ return info.completed_requests.count(tid);
}
void clear() {
pending_prealloc_inos.clear();
- prealloc_inos.clear();
- used_inos.clear();
+ info.clear_meta();
cap_push_seq = 0;
last_cap_renew = utime_t();
- completed_requests.clear();
}
- void encode(bufferlist& bl) const {
- __u8 v = 1;
- ::encode(v, bl);
- ::encode(inst, bl);
- ::encode(completed_requests, bl);
- ::encode(prealloc_inos, bl); // hacky, see below.
- ::encode(used_inos, bl);
- }
- void decode(bufferlist::iterator& p) {
- __u8 v;
- ::decode(v, p);
- ::decode(inst, p);
- ::decode(completed_requests, p);
- ::decode(prealloc_inos, p);
- ::decode(used_inos, p);
- prealloc_inos.insert(used_inos);
- used_inos.clear();
- }
};
-WRITE_CLASS_ENCODER(Session)
/*
* session map
s = session_map[i.name];
else
s = session_map[i.name] = new Session;
- s->inst = i;
+ s->info.inst = i;
s->last_cap_renew = ceph_clock_now(g_ceph_context);
return s;
}
void add_session(Session *s) {
- assert(session_map.count(s->inst.name) == 0);
- session_map[s->inst.name] = s;
+ assert(session_map.count(s->info.inst.name) == 0);
+ session_map[s->info.inst.name] = s;
if (by_state.count(s->state) == 0)
by_state[s->state] = new xlist<Session*>;
by_state[s->state]->push_back(&s->item_session_list);
void remove_session(Session *s) {
s->trim_completed_requests(0);
s->item_session_list.remove_myself();
- session_map.erase(s->inst.name);
+ session_map.erase(s->info.inst.name);
s->put();
}
void touch_session(Session *session) {
for (hash_map<entity_name_t,Session*>::iterator p = session_map.begin();
p != session_map.end();
p++)
- if (p->second->inst.name.is_client())
- s.insert(p->second->inst.name.num());
+ if (p->second->info.inst.name.is_client())
+ s.insert(p->second->info.inst.name.num());
}
void get_client_session_set(set<Session*>& s) {
for (hash_map<entity_name_t,Session*>::iterator p = session_map.begin();
p != session_map.end();
p++)
- if (p->second->inst.name.is_client())
+ if (p->second->info.inst.name.is_client())
s.insert(p->second);
}
// helpers
entity_inst_t& get_inst(entity_name_t w) {
assert(session_map.count(w));
- return session_map[w]->inst;
+ return session_map[w]->info.inst;
}
version_t inc_push_seq(client_t client) {
return get_session(entity_name_t::CLIENT(client.v))->inc_push_seq();
<< dendl;
Session *session = mds->sessionmap.get_session(client_name);
assert(session);
- dout(20) << " (session prealloc " << session->prealloc_inos << ")" << dendl;
+ dout(20) << " (session prealloc " << session->info.prealloc_inos << ")" << dendl;
if (used_preallocated_ino) {
- if (session->prealloc_inos.empty()) {
+ if (session->info.prealloc_inos.empty()) {
// HRM: badness in the journal
mds->clog.warn() << " replayed op " << client_reqs << " on session for " << client_name
<< " with empty prealloc_inos\n";
mds->clog.warn() << " replayed op " << client_reqs << " used ino " << i
<< " but session next is " << next << "\n";
assert(i == used_preallocated_ino);
- session->used_inos.clear();
+ session->info.used_inos.clear();
}
mds->sessionmap.projected = ++mds->sessionmap.version;
}
if (preallocated_inos.size()) {
- session->prealloc_inos.insert(preallocated_inos);
+ session->info.prealloc_inos.insert(preallocated_inos);
mds->sessionmap.projected = ++mds->sessionmap.version;
}
assert(sessionmapv == mds->sessionmap.version);
if (open) {
session = mds->sessionmap.get_or_add_session(client_inst);
mds->sessionmap.set_state(session, Session::STATE_OPEN);
- dout(10) << " opened session " << session->inst << dendl;
+ dout(10) << " opened session " << session->info.inst << dendl;
} else {
session = mds->sessionmap.get_session(client_inst.name);
if (session) { // there always should be a session, but there's a bug
if (session->connection == NULL) {
- dout(10) << " removed session " << session->inst << dendl;
+ dout(10) << " removed session " << session->info.inst << dendl;
mds->sessionmap.remove_session(session);
} else {
session->clear(); // the client has reconnected; keep the Session, but reset
- dout(10) << " reset session " << session->inst << " (they reconnected)" << dendl;
+ dout(10) << " reset session " << session->info.inst << " (they reconnected)" << dendl;
}
} else {
mds->clog.error() << "replayed stray Session close event for " << client_inst
ls.back()->rstat = *nls.front();
ls.back()->accounted_rstat = *nls.back();
}
+
+
+/*
+ * session_info_t
+ */
+void session_info_t::encode(bufferlist& bl) const
+{
+ __u8 v = 1;
+ ::encode(v, bl);
+ ::encode(inst, bl);
+ ::encode(completed_requests, bl);
+ ::encode(prealloc_inos, bl); // hacky, see below.
+ ::encode(used_inos, bl);
+}
+
+void session_info_t::decode(bufferlist::iterator& p)
+{
+ __u8 v;
+ ::decode(v, p);
+ ::decode(inst, p);
+ ::decode(completed_requests, p);
+ ::decode(prealloc_inos, p);
+ ::decode(used_inos, p);
+ prealloc_inos.insert(used_inos);
+ used_inos.clear();
+}
#include "include/frag.h"
#include "include/xlist.h"
+#include "include/interval_set.h"
#include "inode_backtrace.h"
}
+/*
+ * session_info_t
+ */
+
+struct session_info_t {
+ entity_inst_t inst;
+ set<tid_t> completed_requests;
+ interval_set<inodeno_t> prealloc_inos; // preallocated, ready to use.
+ interval_set<inodeno_t> used_inos; // journaling use
+
+ client_t get_client() const { return client_t(inst.name.num()); }
+
+ void clear_meta() {
+ prealloc_inos.clear();
+ used_inos.clear();
+ completed_requests.clear();
+ }
+
+ void encode(bufferlist& bl) const;
+ void decode(bufferlist::iterator& p);
+ void dump(Formatter *f) const;
+ static void generate_test_instances(list<session_info_t*>& ls);
+};
+WRITE_CLASS_ENCODER(session_info_t)
+
// =======
// dentries