diff options
author | Sage Weil <sage@newdream.net> | 2010-02-25 15:50:09 -0800 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-02-26 13:14:29 -0800 |
commit | 155abb477215c472602929c49011c1b0d9ecd186 (patch) | |
tree | 5d20c63c90534a364c90d44060e1b01e58777a45 /src/mds/SessionMap.cc | |
parent | a0e55647c5d74609d40ba99bc736c054c2253aa3 (diff) | |
download | ceph-155abb477215c472602929c49011c1b0d9ecd186.tar.gz |
mds: revise mds sessionmap encoding [disk format change]
Encode session name before session itself, so that we can use
an existing session instead of allocating a new one. This lets
us keep eagerly reconnecting clients that connect before we
load the sessionmap.
Add proper struct_v. Drop useless/incorrect 'n' value.
Continue to read old format, of course. Some minor hackery
because we didn't have a struct_v before.
Diffstat (limited to 'src/mds/SessionMap.cc')
-rw-r--r-- | src/mds/SessionMap.cc | 68 |
1 files changed, 49 insertions, 19 deletions
diff --git a/src/mds/SessionMap.cc b/src/mds/SessionMap.cc index 5244ab147c3..d3da3cee6ca 100644 --- a/src/mds/SessionMap.cc +++ b/src/mds/SessionMap.cc @@ -145,12 +145,13 @@ void SessionMap::_save_finish(version_t v) void SessionMap::encode(bufferlist& bl) { - ::encode(version, bl); + __u64 pre = -1; // for 0.19 compatibility; we forgot an encoding prefix. + ::encode(pre, bl); + + __u8 struct_v = 2; + ::encode(struct_v, bl); - // this is a meaningless upper bound, because we don't include all - // sessions below. it can be ignored by decode(). - __u32 n = session_map.size(); - ::encode(n, bl); + ::encode(version, bl); for (hash_map<entity_name_t,Session*>::iterator p = session_map.begin(); p != session_map.end(); @@ -159,25 +160,54 @@ void SessionMap::encode(bufferlist& bl) p->second->is_closing() || p->second->is_stale() || p->second->is_stale_purging() || - p->second->is_stale_closing()) + p->second->is_stale_closing()) { + ::encode(p->first, bl); p->second->encode(bl); + } } void SessionMap::decode(bufferlist::iterator& p) { utime_t now = g_clock.now(); - - ::decode(version, p); - - // this is a meaningless upper bound. can be ignored. - __u32 n; - ::decode(n, p); - - while (n-- && !p.end()) { - Session *s = new Session; - s->decode(p); - session_map[s->inst.name] = s; - set_state(s, Session::STATE_OPEN); - s->last_cap_renew = now; + __u64 pre; + ::decode(pre, p); + if (version == (__u64)-1) { + __u8 struct_v; + ::decode(struct_v, p); + assert(struct_v == 2); + + while (!p.end()) { + entity_inst_t inst; + ::decode(inst.name, p); + Session *s = get_or_add_open_session(inst); + s->decode(p); + } + + } else { + // --- old format ---- + version = pre; + + // this is a meaningless upper bound. can be ignored. + __u32 n; + ::decode(n, p); + + while (n-- && !p.end()) { + bufferlist::iterator p2 = p; + Session *s = new Session; + s->decode(p); + if (session_map.count(s->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; + delete s; + s = session_map[s->inst.name]; + p = p2; + s->decode(p); + } else { + session_map[s->inst.name] = s; + } + set_state(s, Session::STATE_OPEN); + s->last_cap_renew = now; + } } } |