]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
uclient: Now handles STALE state nicely.
authorGreg Farnum <gregf@hq.newdream.net>
Fri, 26 Jun 2009 22:05:13 +0000 (15:05 -0700)
committerGreg Farnum <gregf@hq.newdream.net>
Fri, 26 Jun 2009 22:05:13 +0000 (15:05 -0700)
src/client/Client.cc
src/client/Client.h

index 2ac2a31d21b23fec5340c0ace936d641416ab8d3..bd231da743e104f2db9b396f370b6afd2f8d8090 100644 (file)
@@ -900,12 +900,12 @@ void Client::handle_client_session(MClientSession *m)
   case CEPH_SESSION_RENEWCAPS:
     mds_sessions[from].cap_ttl = 
       mds_sessions[from].last_cap_renew_request + mdsmap->get_session_timeout();
+    wake_inode_waiters(from);
     break;
 
   case CEPH_SESSION_STALE:
-    // FIXME
+    mds_sessions[from].was_stale = true;
     break;
-
   default:
     assert(0);
   }
@@ -1170,8 +1170,7 @@ void Client::send_reconnect(int mds)
        dout(10) << "    path " << path << dendl;
 
        in->caps[mds]->seq = 0;  // reset seq.
-       m->add_cap(p->first.ino, in->caps[mds]->cap_id,
-                  path.get_ino(), path.get_path(),   
+       m->add_cap(p->first.ino, path.get_ino(), path.get_path(),   // ino
                   in->caps_wanted(), // wanted
                   in->caps[mds]->issued,     // issued
                   in->inode.size, in->inode.mtime, in->inode.atime, in->snaprealm->ino);
@@ -1644,6 +1643,15 @@ void Client::signal_cond_list(list<Cond*>& ls)
   ls.clear();
 }
 
+void Client::wake_inode_waiters(int mds_num)
+{
+  MDSSession * mds = &mds_sessions[mds_num];
+  xlist<InodeCap*>::iterator iter = mds->caps.begin();
+  while (!iter.end()){
+    signal_cond_list((*iter)->inode->waitfor_caps);
+    ++iter;
+  }
+}
 
 
 // flush dirty data (from objectcache)
@@ -1721,6 +1729,10 @@ void Client::add_update_cap(Inode *in, int mds, __u64 cap_id,
       in->exporting_mseq = 0;
     }
     in->caps[mds] = cap = new InodeCap;
+    mds_sessions[mds].caps.push_back(&cap->cap_item);
+    cap->session = &mds_sessions[mds];
+    cap->inode = in;
+    cap->gen = mds_sessions[mds].cap_gen;
     cap_list.push_back(&in->cap_item);
   }
 
@@ -1763,6 +1775,8 @@ void Client::remove_cap(Inode *in, int mds)
   i.seq = cap->seq;
   i.migrate_seq = cap->mseq;
   session->release->caps.push_back(i);
+  
+  cap->cap_item.remove_myself();
 
   if (in->auth_cap == cap)
     in->auth_cap = NULL;
@@ -2501,19 +2515,25 @@ void Client::tick()
 
 void Client::renew_caps()
 {
-  dout(10) << "renew_caps" << dendl;
+  dout(10) << "renew_caps()" << dendl;
   last_cap_renew = g_clock.now();
   
   for (map<int,MDSSession>::iterator p = mds_sessions.begin();
        p != mds_sessions.end();
        p++) {
     dout(15) << "renew_caps requesting from mds" << p->first << dendl;
-    p->second.last_cap_renew_request = g_clock.now();
-    messenger->send_message(new MClientSession(CEPH_SESSION_REQUEST_RENEWCAPS),
-                           mdsmap->get_inst(p->first));
+    renew_caps(p->first);
   }
 }
 
+void Client::renew_caps(const int session) {
+  dout(10) << "renew_caps(session number)" << dendl;
+  mds_sessions[session].last_cap_renew_request = g_clock.now();
+  messenger->send_message(new MClientSession(CEPH_SESSION_REQUEST_RENEWCAPS),
+                         mdsmap->get_inst(session));
+
+}
+
 
 // ===============================================================
 // high level (POSIXy) interface
index 42d6d21b1da7372543851c3d6a86e5d52941ee32..93b269f80717068ffb438db424241a829e7f6c07 100644 (file)
@@ -88,6 +88,23 @@ extern class Logger  *client_logger;
  - when Dir is empty, it's removed (and it's Inode ref--)
  
 */
+struct InodeCap;
+struct MDSSession {
+  version_t seq;
+  __u64 cap_gen;
+  utime_t cap_ttl, last_cap_renew_request;
+  int num_caps;
+  entity_inst_t inst;
+  bool closing;
+  bool was_stale;
+
+  xlist<InodeCap*> caps;
+  
+  MClientCapRelease *release;
+  
+  MDSSession() : seq(0), cap_gen(0), num_caps(0),
+                closing(false), was_stale(false), release(NULL) {}
+};
 
 class Dir;
 class Inode;
@@ -127,9 +144,6 @@ class Dir {
   bool is_empty() {  return dentries.empty(); }
 };
 
-
-struct InodeCap;
-
 struct SnapRealm {
   inodeno_t ino;
   int nref;
@@ -173,14 +187,20 @@ inline ostream& operator<<(ostream& out, const SnapRealm& r) {
 }
 
 struct InodeCap {
+  MDSSession *session;
+  Inode *inode;
+  xlist<InodeCap*>::item cap_item;
+
   __u64 cap_id;
   unsigned issued;
   unsigned implemented;
   unsigned wanted;   // as known to mds.
   __u64 seq;
   __u32 mseq;  // migration seq
+  __u32 gen;
 
-  InodeCap() : issued(0), implemented(0), wanted(0), seq(0), mseq(0) {}
+  InodeCap() : session(NULL), inode(NULL), cap_item(this), issued(0),
+              implemented(0), wanted(0), seq(0), mseq(0), gen(0) {}
 };
 
 struct CapSnap {
@@ -335,12 +355,27 @@ class Inode {
     return caps.size() || exporting_mds >= 0;
   }
 
+  bool cap_is_valid(InodeCap* cap) {
+    cout << "cap_gen     " << cap->session-> cap_gen << std::endl
+        << "session gen " << cap->gen << std::endl
+        << "cap expire  " << cap->session->cap_ttl << std::endl
+        << "cur time    " << g_clock.now() << std::endl;
+    if ((cap->session->cap_gen <= cap->gen)
+       && (g_clock.now() < cap->session->cap_ttl)) {
+      return true;
+    }
+    //if we make it here, the capabilities aren't up-to-date
+    cap->session->was_stale = true;
+    return true;
+  }
+
   int caps_issued() {
     int c = exporting_issued | snap_caps;
     for (map<int,InodeCap*>::iterator it = caps.begin();
          it != caps.end();
          it++)
-      c |= it->second->issued;
+      if (cap_is_valid(it->second))
+       c |= it->second->issued;
     return c;
   }
 
@@ -559,6 +594,7 @@ class Client : public Dispatcher {
   Context *tick_event;
   utime_t last_cap_renew;
   void renew_caps();
+  void renew_caps(int s);
 public:
   void tick();
 
@@ -572,18 +608,6 @@ public:
   bufferlist signed_ticket;
   
   // mds sessions
-  struct MDSSession {
-    version_t seq;
-    __u64 cap_gen;
-    utime_t cap_ttl, last_cap_renew_request;
-    int num_caps;
-    entity_inst_t inst;
-    bool closing;
-
-    MClientCapRelease *release;
-
-    MDSSession() : seq(0), cap_gen(0), num_caps(0), closing(false), release(NULL) {}
-  };
   map<int, MDSSession> mds_sessions;  // mds -> push seq
   map<int, list<Cond*> > waiting_for_session;
   list<Cond*> waiting_for_mdsmap;
@@ -698,6 +722,7 @@ protected:
   Mutex                  client_lock;
 
   // helpers
+  void wake_inode_waiters(int mds);
   void wait_on_list(list<Cond*>& ls);
   void signal_cond_list(list<Cond*>& ls);