]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
revoke caps, mark stale
authorSage Weil <sage@newdream.net>
Fri, 4 Jan 2008 01:17:18 +0000 (17:17 -0800)
committerSage Weil <sage@newdream.net>
Fri, 4 Jan 2008 01:17:18 +0000 (17:17 -0800)
src/mds/Capability.h
src/mds/Locker.cc
src/mds/Locker.h
src/mds/Server.cc
src/mds/SessionMap.h

index 8df19e6a70b228c5736346d542f4ff8c1e496108..6cb7ef520c34c602350a2976021ef78480f08faf 100644 (file)
@@ -64,6 +64,7 @@ private:
   capseq_t last_sent, last_recv;
   
   bool suppress;
+  bool stale;
 public:
   xlist<Capability*>::item session_caps_item;
 
@@ -72,13 +73,14 @@ public:
     wanted_caps(want),
     last_sent(s),
     last_recv(s),
-    suppress(false),
+    suppress(false), stale(false),
     session_caps_item(this) { 
   }
   Capability(CInode *i, Export& other) : 
     inode(i),
     wanted_caps(other.wanted),
     last_sent(0), last_recv(0),
+    suppress(false), stale(false),
     session_caps_item(this) { 
     // issued vs pending
     if (other.issued & ~other.pending)
@@ -89,6 +91,9 @@ public:
   bool is_suppress() { return suppress; }
   void set_suppress(bool b) { suppress = b; }
 
+  bool is_stale() { return stale; }
+  void set_stale(bool b) { stale = b; }
+
   CInode *get_inode() { return inode; }
   void set_inode(CInode *i) { inode = i; }
   void add_to_cap_list(xlist<Capability*>& ls) {
@@ -151,19 +156,8 @@ public:
 
   // issue caps; return seq number.
   capseq_t issue(int c) {
-    //int was = pending();
-    //no!  if (c == was && last_sent) return -1;  // repeat of previous?
-    
     ++last_sent;
     cap_history[last_sent] = c;
-
-    /* no!
-    // not recalling, just adding?
-    if (c & ~was &&
-        cap_history.count(last_sent-1)) { 
-      cap_history.erase(last_sent-1);
-    }
-    */
     return last_sent;
   }
   capseq_t get_last_seq() { return last_sent; }
@@ -225,6 +219,12 @@ public:
     return r;
   }
 
+  void revoke() {
+    if (pending())
+      issue(0);
+    confirm_receipt(last_sent, 0);
+  }
+
   // serializers
   void _encode(bufferlist& bl) {
     bl.append((char*)&wanted_caps, sizeof(wanted_caps));
index 860b1000ba12e9f9c06867087ced883c596a7360..e4a8792008aefa13f6ed512b98e2068bf837630e 100644 (file)
@@ -558,6 +558,24 @@ bool Locker::issue_caps(CInode *in)
   return (nissued == 0);  // true if no re-issued, no callbacks
 }
 
+void Locker::revoke_stale_caps(Session *session)
+{
+  dout(10) << "revoke_stale_caps for client " << session->inst.name << dendl;
+  
+  for (xlist<Capability*>::iterator p = session->caps.begin(); !p.end(); ++p) {
+    Capability *cap = *p;
+    CInode *in = cap->get_inode();
+    int issued = cap->issued();
+    if (issued) {
+      dout(10) << " revoking " << cap_string(issued) << " on " << *in << dendl;      
+      cap->revoke();
+      file_eval(&in->filelock);
+    } else {
+      dout(10) << " nothing issued on " << *in << dendl;
+    }
+    cap->set_stale(true);
+  }       
+}
 
 class C_MDL_RequestInodeFileCaps : public Context {
   Locker *locker;
index 2993f04c7cfd9b1d64166fc782af6be3bfa3054b..7fb2ec97039b56a4b11b0773ea7fcdb3c72022df 100644 (file)
@@ -25,6 +25,7 @@ using std::list;
 using std::set;
 
 class MDS;
+class Session;
 class CDir;
 class CInode;
 class CDentry;
@@ -180,6 +181,7 @@ protected:
   version_t issue_file_data_version(CInode *in);
   Capability* issue_new_caps(CInode *in, int mode, Session *session);
   bool issue_caps(CInode *in);
+  void revoke_stale_caps(Session *session);
 
  protected:
   void handle_client_file_caps(class MClientFileCaps *m);
index f31d41ceeb3122f6d4f5a9d4dd3ac335206c0aca..7f4494898af322c1ffc7e99ec7a6b348f7237c56 100644 (file)
@@ -285,23 +285,23 @@ void Server::terminate_sessions()
 
 void Server::find_idle_sessions()
 {
-  dout(10) << "find_idle_sessions " << mds->sessionmap.session_list.size() << dendl;
+  dout(10) << "find_idle_sessions" << dendl;
   
   utime_t cutoff = g_clock.now();
   cutoff -= g_conf.mds_cap_timeout;  
   while (1) {
-    Session *oldest = mds->sessionmap.get_oldest_session();
-    if (!oldest) break;
-    dout(20) << "oldest session is " << oldest->inst << dendl;
-    if (oldest->last_cap_renew >= cutoff) {
-      dout(20) << "oldest session is " << oldest->inst << " and sufficiently new (" 
-              << oldest->last_cap_renew << ")" << dendl;
+    Session *session = mds->sessionmap.get_oldest_active_session();
+    if (!session) break;
+    dout(20) << "laggiest session is " << session->inst << dendl;
+    if (session->last_cap_renew >= cutoff) {
+      dout(20) << "laggiest session is " << session->inst << " and sufficiently new (" 
+              << session->last_cap_renew << ")" << dendl;
       break;
     }
 
-    dout(10) << " expiring caps for " << oldest << " " << oldest->inst << " last " << oldest->last_cap_renew << dendl;
-    // write me!!!
-    break;
+    dout(10) << "new stale session " << session->inst << " last " << session->last_cap_renew << dendl;
+    mds->sessionmap.mark_session_stale(session);
+    mds->locker->revoke_stale_caps(session);
   }
 }
 
index 739ffbe1bd458d2de38737bdf283463a93a78df0..1dc6cd1ea63aef59a5b269ea964a11ee508a3d3a 100644 (file)
@@ -49,6 +49,7 @@ public:
   bool is_opening() { return state == STATE_OPENING; }
   bool is_open() { return state == STATE_OPEN; }
   bool is_closing() { return state == STATE_CLOSING; }
+  bool is_stale() { return state == STATE_STALE; }
 
   // -- caps --
 private:
@@ -122,7 +123,8 @@ private:
   MDS *mds;
   hash_map<entity_name_t, Session*> session_map;
 public:
-  xlist<Session*> session_list;
+  xlist<Session*> active_sessions;
+  xlist<Session*> stale_sessions;
   
 public:  // i am lazy
   version_t version, projected, committing, committed;
@@ -145,8 +147,6 @@ public:
       return session_map[i.name];
     Session *s = session_map[i.name] = new Session;
     s->inst = i;
-    session_list.push_back(&s->session_list_item);
-    assert(session_list.back() == s);
     return s;
   }
   void remove_session(Session *s) {
@@ -156,11 +156,14 @@ public:
   }
   void touch_session(Session *s) {
     s->last_cap_renew = g_clock.now();
-    session_list.push_back(&s->session_list_item);
+    active_sessions.push_back(&s->session_list_item);
   }
-  Session *get_oldest_session() {
-    if (session_list.empty()) return 0;
-    return session_list.front();
+  Session *get_oldest_active_session() {
+    if (active_sessions.empty()) return 0;
+    return active_sessions.front();
+  }
+  void mark_session_stale(Session *s) {
+    stale_sessions.push_back(&s->session_list_item);
   }
 
   void get_client_set(set<int>& s) {