]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: introduce lease seq #
authorSage Weil <sage@newdream.net>
Sun, 11 Jan 2009 20:01:07 +0000 (12:01 -0800)
committerSage Weil <sage@newdream.net>
Sun, 11 Jan 2009 20:01:07 +0000 (12:01 -0800)
Only recognize a release message if the seq # matches.  This prevents
races between mds requested revocations and volunatry client releases.

src/include/ceph_fs.h
src/mds/Locker.cc
src/mds/mdstypes.h
src/messages/MClientLease.h
src/messages/MClientReply.h

index 05b2f204758381f19799babc8c271934781f4ae3..497f18c418184e79f3feb2019eb134d317e39d7f 100644 (file)
@@ -855,6 +855,7 @@ struct ceph_mds_reply_inode {
 struct ceph_mds_reply_lease {
        __le16 mask;
        __le32 duration_ms;
+       __le32 seq;
 } __attribute__ ((packed));
 
 struct ceph_mds_reply_dirfrag {
@@ -1065,6 +1066,7 @@ struct ceph_mds_lease {
        __le16 mask;
        __le64 ino;
        __le64 first, last;
+       __le32 seq;
 } __attribute__ ((packed));
 /* followed by a __le32+string for dname */
 
index 41a9c24a1c291c715662de2e16afcb658eb4cabd..98c1cbb8d72751c16513de6ca92da36ebb96f4c4 100644 (file)
@@ -1364,6 +1364,11 @@ void Locker::handle_client_lease(MClientLease *m)
     delete m;
     return;
   } 
+  if (l->seq != m->get_seq()) {
+    dout(7) << "handle_client_lease lease seq " << l->seq << " != " << m->get_seq() << dendl;
+    delete m;
+    return;
+  }
 
   switch (m->get_action()) {
   case CEPH_MDS_LEASE_RELEASE:
@@ -1390,16 +1395,20 @@ void Locker::handle_client_lease(MClientLease *m)
 void Locker::_issue_client_lease(MDSCacheObject *p, int mask, int pool, int client,
                                 bufferlist &bl, utime_t now, Session *session)
 {
+  LeaseStat e;
+  e.mask = mask;
+
   if (mask) {
     ClientLease *l = p->add_client_lease(client, mask);
     session->touch_lease(l);
 
+    e.seq = ++l->seq;
+
     now += mdcache->client_lease_durations[pool];
     mdcache->touch_client_lease(l, pool, now);
-  }
+  } else
+    e.seq = 0;
 
-  LeaseStat e;
-  e.mask = mask;
   e.duration_ms = (int)(1000 * mdcache->client_lease_durations[pool]);
   ::encode(e, bl);
   dout(20) << "_issue_client_lease mask " << e.mask << " dur " << e.duration_ms << "ms" << dendl;
@@ -1467,24 +1476,19 @@ void Locker::revoke_client_leases(SimpleLock *lock)
       continue;
     
     n++;
-    if (lock->get_type() == CEPH_LOCK_DN) {
-      CDentry *dn = (CDentry*)lock->get_parent();
-      int mask = CEPH_LOCK_DN;
-
-      // i should also revoke the dir ICONTENT lease, if they have it!
-      CInode *diri = dn->get_dir()->get_inode();
-      mds->send_message_client(new MClientLease(CEPH_MDS_LEASE_REVOKE,
-                                               mask,
-                                               diri->ino(),
-                                               diri->first, CEPH_NOSNAP,
-                                               dn->get_name()),
-                              l->client);
-    } else {
-      CInode *in = (CInode*)lock->get_parent();
-      mds->send_message_client(new MClientLease(CEPH_MDS_LEASE_REVOKE,
-                                               lock->get_type(), in->ino(), in->first, in->last),
-                              l->client);
-    }
+    assert(lock->get_type() == CEPH_LOCK_DN);
+
+    CDentry *dn = (CDentry*)lock->get_parent();
+    int mask = CEPH_LOCK_DN;
+    
+    // i should also revoke the dir ICONTENT lease, if they have it!
+    CInode *diri = dn->get_dir()->get_inode();
+    mds->send_message_client(new MClientLease(CEPH_MDS_LEASE_REVOKE, l->seq,
+                                             mask,
+                                             diri->ino(),
+                                             diri->first, CEPH_NOSNAP,
+                                             dn->get_name()),
+                            l->client);
   }
   assert(n == lock->get_num_client_lease());
 }
index e83e681cf4e91e2de8cccfb97f462e2fed0705a4..8674109c29792deee19bd108150be567d33adff3 100644 (file)
@@ -877,12 +877,13 @@ struct ClientLease {
   int mask;                 // CEPH_STAT_MASK_*
   MDSCacheObject *parent;
 
+  ceph_seq_t seq;
   utime_t ttl;
   xlist<ClientLease*>::item session_lease_item; // per-session list
   xlist<ClientLease*>::item lease_item;         // global list
 
   ClientLease(int c, MDSCacheObject *p) : 
-    client(c), mask(0), parent(p),
+    client(c), mask(0), parent(p), seq(0),
     session_lease_item(this),
     lease_item(this) { }
 };
index 57496c73ae1d80b1ce504ece7db576d20fc66cc6..7869eb9cc222bce8777d819905ae87d2b2e22028 100644 (file)
@@ -33,24 +33,27 @@ struct MClientLease : public Message {
   nstring dname;
   
   int get_action() { return h.action; }
+  ceph_seq_t get_seq() { return h.seq; }
   int get_mask() { return h.mask; }
   inodeno_t get_ino() { return inodeno_t(h.ino); }
   snapid_t get_first() { return snapid_t(h.first); }
   snapid_t get_last() { return snapid_t(h.last); }
 
   MClientLease() : Message(CEPH_MSG_CLIENT_LEASE) {}
-  MClientLease(int ac, int m, __u64 i, __u64 sf, __u64 sl) :
+  MClientLease(int ac, ceph_seq_t seq, int m, __u64 i, __u64 sf, __u64 sl) :
     Message(CEPH_MSG_CLIENT_LEASE) {
     h.action = ac;
+    h.seq = seq;
     h.mask = m;
     h.ino = i;
     h.first = sf;
     h.last = sl;
   }
-  MClientLease(int ac, int m, __u64 i, __u64 sf, __u64 sl, const nstring& d) :
+  MClientLease(int ac, ceph_seq_t seq, int m, __u64 i, __u64 sf, __u64 sl, const nstring& d) :
     Message(CEPH_MSG_CLIENT_LEASE),
     dname(d) {
     h.action = ac;
+    h.seq = seq;
     h.mask = m;
     h.ino = i;
     h.first = sf;
@@ -60,6 +63,7 @@ struct MClientLease : public Message {
   const char *get_type_name() { return "client_lease"; }
   void print(ostream& out) {
     out << "client_lease(a=" << get_lease_action_name(get_action())
+       << " seq " << get_seq()
        << " mask " << get_mask();
     out << " " << get_ino();
     if (h.last != CEPH_NOSNAP)
index 34542397d0293809ece8262c21b950367810b44c..5b98f1f72480002a91989434052b7147a9a643b5 100644 (file)
@@ -49,13 +49,16 @@ struct LeaseStat {
   // this matches ceph_mds_reply_lease
   __u16 mask;
   __u32 duration_ms;  
+  __u32 seq;
   void encode(bufferlist &bl) const {
     ::encode(mask, bl);
     ::encode(duration_ms, bl);
+    ::encode(seq, bl);
   }
   void decode(bufferlist::iterator &bl) {
     ::decode(mask, bl);
     ::decode(duration_ms, bl);
+    ::decode(seq, bl);
   }
 };
 WRITE_CLASS_ENCODER(LeaseStat)