]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: revise mds sessionmap encoding [disk format change]
authorSage Weil <sage@newdream.net>
Thu, 25 Feb 2010 23:50:09 +0000 (15:50 -0800)
committerSage Weil <sage@newdream.net>
Fri, 26 Feb 2010 21:14:29 +0000 (13:14 -0800)
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.

src/mds/SessionMap.cc

index 5244ab147c3ffc26b40072a22aa8e1d31f6af980..d3da3cee6ca3192d9b7711e8fc63eb2be23938e0 100644 (file)
@@ -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;
+    }
   }
 }