]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
move to generic ceph_seq_t 32-bit sequence number and comparator
authorSage Weil <sage@newdream.net>
Thu, 8 Jan 2009 23:38:28 +0000 (15:38 -0800)
committerSage Weil <sage@newdream.net>
Thu, 8 Jan 2009 23:38:28 +0000 (15:38 -0800)
We want to behave when the seq # rolls over.  We'll be fine as long
as we don't differ by more than 1<<31.

src/client/Client.h
src/include/ceph_fs.h
src/kernel/caps.c
src/kernel/inode.c
src/mds/Capability.h
src/mds/Locker.cc
src/mds/Locker.h
src/mds/mdstypes.h
src/messages/MClientCaps.h

index e359bd5e6b1c6372dbd8e9bfb8bb0730d250838b..536c5fe7b9ee9da795424529de90b0ee253847f0 100644 (file)
@@ -199,7 +199,7 @@ class Inode {
   int snap_caps, snap_cap_refs;
   unsigned exporting_issued;
   int exporting_mds;
-  capseq_t exporting_mseq;
+  ceph_seq_t exporting_mseq;
   utime_t hold_caps_until;
   xlist<Inode*>::item cap_item;
 
index a79822a1a6b30ec10d7e93b43401bf1369c0ccf8..d06e7a57890dbbc459066c770fd5455bcddd2473 100644 (file)
@@ -100,6 +100,18 @@ struct ceph_timespec {
 } __attribute__ ((packed));
 
 
+/*
+ * Rollover-safe type and comparator for 32-bit sequence numbers.
+ * Comparator returns -1, 0, or 1.
+ */
+typedef __u32 ceph_seq_t;
+
+static inline __s32 ceph_seq_cmp(__u32 a, __u32 b)
+{
+       return ((__s32)a - (__s32)b);
+}
+
+
 /*
  * "Frags" are a way to describe a subset of a 32-bit number space,
  * using a mask and a value to match against that mask.  Any given frag
@@ -833,7 +845,7 @@ struct ceph_mds_reply_inode {
        struct ceph_mds_reply_cap cap;
        struct ceph_file_layout layout;
        struct ceph_timespec ctime, mtime, atime;
-       __le64 time_warp_seq;
+       __le32 time_warp_seq;
        __le64 size, max_size, truncate_seq;
        __le32 mode, uid, gid;
        __le32 nlink;
@@ -958,7 +970,6 @@ static inline int ceph_flags_to_mode(int flags)
  */
 #define CEPH_CAP_EXPIREABLE (CEPH_CAP_PIN|CEPH_CAP_ANY_RDCACHE)
 
-
 static inline int ceph_caps_for_mode(int mode)
 {
        switch (mode) {
@@ -1041,10 +1052,10 @@ struct ceph_mds_caps {
 
        /* filelock */
        __le64 size, max_size;
-       __le64 truncate_seq;
+       __le32 truncate_seq;
        struct ceph_timespec mtime, atime, ctime;
        struct ceph_file_layout layout;
-       __le64 time_warp_seq;
+       __le32 time_warp_seq;
 } __attribute__ ((packed));
 
 
index c29da0175eba49fa03b0194d73572c0c43d2de11..3b2d0142191a8641b25bc3ede848ea3ba2941f13 100644 (file)
@@ -1450,7 +1450,7 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex,
        /* make sure we haven't seen a higher mseq */
        for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
                t = rb_entry(p, struct ceph_cap, ci_node);
-               if (t->mseq > mseq) {
+               if (ceph_seq_cmp(t->mseq, mseq) > 0) {
                        dout(10, " higher mseq on cap from mds%d\n",
                             t->session->s_mds);
                        remember = 0;
@@ -1498,7 +1498,7 @@ static void handle_cap_import(struct ceph_mds_client *mdsc,
        unsigned long ttl_ms = le32_to_cpu(im->ttl_ms);
 
        if (ci->i_cap_exporting_mds >= 0 &&
-           ci->i_cap_exporting_mseq < mseq) {
+           ceph_seq_cmp(ci->i_cap_exporting_mseq, mseq) < 0) {
                dout(10, "handle_cap_import inode %p ci %p mds%d mseq %d"
                     " - cleared exporting from mds%d\n",
                     inode, ci, mds, mseq,
@@ -1510,7 +1510,7 @@ static void handle_cap_import(struct ceph_mds_client *mdsc,
                dout(10, "handle_cap_import inode %p ci %p mds%d mseq %d\n",
                     inode, ci, mds, mseq);
        }
-
+       
        realm = ceph_update_snap_trace(mdsc, snaptrace, snaptrace+snaptrace_len,
                                       false);
        ceph_add_cap(inode, session, -1, issued, wanted, seq, mseq, realmino,
index 0bcc32b381d818e800fd57e1f3d5282eb906eb0c..5d6c8345370ac6cc28a09fe428a95be079baea3e 100644 (file)
@@ -330,7 +330,7 @@ void ceph_fill_file_bits(struct inode *inode, int issued,
        struct ceph_inode_info *ci = ceph_inode(inode);
        int warn = 0;
 
-       if (truncate_seq > ci->i_truncate_seq ||
+       if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) > 0 ||
            (truncate_seq == ci->i_truncate_seq && size > inode->i_size)) {
                dout(10, "size %lld -> %llu\n", inode->i_size, size);
                inode->i_size = size;
@@ -346,11 +346,11 @@ void ceph_fill_file_bits(struct inode *inode, int issued,
                 */
                if (timespec_compare(ctime, &inode->i_ctime) > 0)
                        inode->i_ctime = *ctime;
-               if (time_warp_seq > ci->i_time_warp_seq)
+               if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0)
                        derr(0, "WARNING: %p mds time_warp_seq %llu > %llu\n",
                             inode, time_warp_seq, ci->i_time_warp_seq);
        } else if (issued & (CEPH_CAP_FILE_WR|CEPH_CAP_FILE_WRBUFFER)) {
-               if (time_warp_seq > ci->i_time_warp_seq) {
+               if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) {
                        /* the MDS did a utimes() */
                        inode->i_ctime = *ctime;
                        inode->i_mtime = *mtime;
@@ -368,7 +368,7 @@ void ceph_fill_file_bits(struct inode *inode, int issued,
                }
        } else {
                /* we have no write caps; whatever the MDS says is true */
-               if (time_warp_seq >= ci->i_time_warp_seq) {
+               if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) {
                        inode->i_ctime = *ctime;
                        inode->i_mtime = *mtime;
                        inode->i_atime = *atime;
index 51e2145a31084899c2e344d047fa576b2ba2391b..fb322db8b07a9e01f482176c968ca0391bb0abe5 100644 (file)
@@ -19,9 +19,6 @@
 #include "include/buffer.h"
 #include "include/xlist.h"
 
-#include <map>
-using namespace std;
-
 #include "config.h"
 
 /*
@@ -74,10 +71,10 @@ public:
     int32_t issued;
     int32_t pending;
     snapid_t client_follows;
-    capseq_t mseq;
+    ceph_seq_t mseq;
     utime_t last_issue_stamp;
     Export() {}
-    Export(int w, int i, int p, snapid_t cf, capseq_t s, utime_t lis) : 
+    Export(int w, int i, int p, snapid_t cf, ceph_seq_t s, utime_t lis) : 
       wanted(w), issued(i), pending(p), client_follows(cf), mseq(s), last_issue_stamp(lis) {}
     void encode(bufferlist &bl) const {
       ::encode(wanted, bl);
@@ -102,7 +99,6 @@ private:
   int client;
 
   __u32 _wanted;     // what the client wants (ideally)
-    //::decode(cap_history, bl);
 
   utime_t last_issue_stamp;
 
@@ -119,14 +115,14 @@ public:
   int issued() {
     return _pending | _issued;
   }
-  capseq_t issue(int c) {
+  ceph_seq_t issue(int c) {
     _pending = c;
     _issued |= c;
     //last_issue = 
     ++last_sent;
     return last_sent;
   }
-  void confirm_receipt(capseq_t seq, int caps) {
+  void confirm_receipt(ceph_seq_t seq, int caps) {
     if (seq == last_sent)
       _pending = _issued = caps;
   }    
@@ -139,7 +135,7 @@ public:
   static const int _max_revoke = 3;
   __u32 _pending, _issued;
   __u32 _revoke_before[_max_revoke];  // caps before this issue
-  capseq_t _revoke_seq[_max_revoke];
+  ceph_seq_t _revoke_seq[_max_revoke];
   int _num_revoke;
 
 public:
@@ -150,7 +146,7 @@ public:
       c |= _revoke_before[i];
     return c;
   }
-  capseq_t issue(int c) {
+  ceph_seq_t issue(int c) {
     if (_pending & ~c) {
       // note _revoked_ caps prior to this revocation
       if (_num_revoke < _max_revoke) {
@@ -167,7 +163,7 @@ public:
     ++last_sent;
     return last_sent;
   }
-  void confirm_receipt(capseq_t seq, int caps) {
+  void confirm_receipt(ceph_seq_t seq, int caps) {
     _issued = caps;
     if (seq == last_sent) {
       _pending = caps;
@@ -196,9 +192,9 @@ public:
 
 
 private:
-  capseq_t last_sent;
-  //capseq_t last_issue;
-  capseq_t mseq;
+  ceph_seq_t last_sent;
+  //ceph_seq_t last_issue;
+  ceph_seq_t mseq;
 
   int suppress;
   bool stale;
@@ -224,9 +220,9 @@ public:
     client_follows(0),
     session_caps_item(this), rdcaps_list(rl), rdcaps_item(this), snaprealm_caps_item(this) { }
   
-  capseq_t get_mseq() { return mseq; }
+  ceph_seq_t get_mseq() { return mseq; }
 
-  capseq_t get_last_sent() { return last_sent; }
+  ceph_seq_t get_last_sent() { return last_sent; }
   utime_t get_last_issue_stamp() { return last_issue_stamp; }
   void touch() {
     if (rdcaps_item.is_on_xlist())
@@ -235,7 +231,7 @@ public:
 
   void set_last_issue_stamp(utime_t t) { last_issue_stamp = t; }
 
-  //capseq_t get_last_issue() { return last_issue; }
+  //ceph_seq_t get_last_issue() { return last_issue; }
 
   bool is_suppress() { return suppress > 0; }
   void inc_suppress() { suppress++; }
@@ -254,7 +250,7 @@ public:
     _wanted = w;
   }
 
-  capseq_t get_last_seq() { return last_sent; }
+  ceph_seq_t get_last_seq() { return last_sent; }
 
 
   void check_rdcaps_list(int o, int n, int ow, int nw)
index 8182b731d46e9b4dfee511731db4aace07621682..9b6123afaf4c9c1fc0ddc45d12aca54ca2bec7cf 100644 (file)
@@ -490,9 +490,9 @@ struct C_Locker_FileUpdate_finish : public Context {
   bool share;
   int client;
   MClientCaps *ack;
-  capseq_t releasecap;
+  ceph_seq_t releasecap;
   C_Locker_FileUpdate_finish(Locker *l, CInode *i, Mutation *m, bool e=false, int c=-1,
-                            MClientCaps *ac = 0, capseq_t rc=0) : 
+                            MClientCaps *ac = 0, ceph_seq_t rc=0) : 
     locker(l), in(i), mut(m), share(e), client(c),
     ack(ac), releasecap(rc) {
     in->get(CInode::PIN_PTRWAITER);
@@ -503,7 +503,7 @@ struct C_Locker_FileUpdate_finish : public Context {
 };
 
 void Locker::file_update_finish(CInode *in, Mutation *mut, bool share, int client, 
-                               MClientCaps *ack, capseq_t releasecap)
+                               MClientCaps *ack, ceph_seq_t releasecap)
 {
   dout(10) << "file_update_finish on " << *in << dendl;
   in->pop_and_dirty_projected_inode(mut->ls);
@@ -1024,7 +1024,7 @@ void Locker::handle_client_caps(MClientCaps *m)
     in->add_waiter(CInode::WAIT_UNFREEZE, new C_MDS_RetryMessage(mds, m));
     return;
   }
-  if (m->get_mseq() < cap->get_mseq()) {
+  if (ceph_seq_cmp(m->get_mseq(), cap->get_mseq()) < 0) {
     dout(7) << "handle_client_caps mseq " << m->get_mseq() << " < " << cap->get_mseq()
            << ", dropping" << dendl;
     delete m;
@@ -1078,7 +1078,7 @@ void Locker::handle_client_caps(MClientCaps *m)
             << " on " << *in << dendl;
     
     MClientCaps *ack = 0;
-    capseq_t releasecap = 0;
+    ceph_seq_t releasecap = 0;
     
     if (m->get_dirty() && in->is_auth()) {
       dout(7) << " flush client" << client << " dirty " << ccap_string(m->get_dirty()) 
@@ -1087,7 +1087,8 @@ void Locker::handle_client_caps(MClientCaps *m)
                            m->get_caps(), 0, m->get_dirty(), 0);
     }
     if (m->get_caps() == 0) {
-      assert(m->get_seq() <= cap->get_last_sent());
+      
+      assert(ceph_seq_cmp(m->get_seq(), cap->get_last_sent()) <= 0);
       if (m->get_seq() == cap->get_last_sent()) {
        dout(7) << " releasing request client" << client << " seq " << m->get_seq() << " on " << *in << dendl;
        cap->releasing++;
@@ -1129,7 +1130,7 @@ void Locker::handle_client_caps(MClientCaps *m)
   delete m;
 }
 
-void Locker::_finish_release_cap(CInode *in, int client, capseq_t seq, MClientCaps *ack)
+void Locker::_finish_release_cap(CInode *in, int client, ceph_seq_t seq, MClientCaps *ack)
 {
   dout(10) << "_finish_release_cap client" << client << " seq " << seq << " on " << *in << dendl;
   
@@ -1144,7 +1145,7 @@ void Locker::_finish_release_cap(CInode *in, int client, capseq_t seq, MClientCa
   if (cap->releasing) {
     dout(10) << " another release attempt in flight, not releasing yet" << dendl;
     delete ack;
-  } else if (seq < cap->get_last_sent()) {
+  } else if (ceph_seq_cmp(seq, cap->get_last_sent()) < 0) {
     dout(10) << " NOT releasing cap client" << client << ", last_sent " << cap->get_last_sent()
             << " > " << seq << dendl;
     delete ack;
@@ -1172,7 +1173,7 @@ void Locker::_finish_release_cap(CInode *in, int client, capseq_t seq, MClientCa
  * if we update, return true; otherwise, false (no updated needed).
  */
 bool Locker::_do_cap_update(CInode *in, int dirty, int wanted, snapid_t follows, MClientCaps *m,
-                           MClientCaps *ack, capseq_t releasecap)
+                           MClientCaps *ack, ceph_seq_t releasecap)
 {
   dout(10) << "_do_cap_update dirty " << ccap_string(dirty)
           << " wanted " << ccap_string(wanted)
@@ -1263,7 +1264,8 @@ bool Locker::_do_cap_update(CInode *in, int dirty, int wanted, snapid_t follows,
              << " for " << *in << dendl;
       pi->atime = atime;
     }
-    if ((dirty & CEPH_CAP_FILE_EXCL) && pi->time_warp_seq < m->get_time_warp_seq()) {
+    if ((dirty & CEPH_CAP_FILE_EXCL) &&
+       ceph_seq_cmp(pi->time_warp_seq, m->get_time_warp_seq()) < 0) {
       dout(7) << "  time_warp_seq " << pi->time_warp_seq << " -> " << m->get_time_warp_seq()
              << " for " << *in << dendl;
       pi->time_warp_seq = m->get_time_warp_seq();
index bc7cefca78b2264d27303805302d8c1460882ee1..67fb6f66e110a5b65713763eee7227952f0dea06 100644 (file)
@@ -213,15 +213,15 @@ public:
  protected:
   void handle_client_caps(class MClientCaps *m);
   bool _do_cap_update(CInode *in, int had, int wanted, snapid_t follows, MClientCaps *m,
-                     MClientCaps *ack=0, capseq_t releasecap=0);
-  void _finish_release_cap(CInode *in, int client, capseq_t seq, MClientCaps *ack);
+                     MClientCaps *ack=0, ceph_seq_t releasecap=0);
+  void _finish_release_cap(CInode *in, int client, ceph_seq_t seq, MClientCaps *ack);
 
 
   void request_inode_file_caps(CInode *in);
   void handle_inode_file_caps(class MInodeFileCaps *m);
 
   void file_update_finish(CInode *in, Mutation *mut, bool share, int client,
-                         MClientCaps *ack, capseq_t releasecap);
+                         MClientCaps *ack, ceph_seq_t releasecap);
 public:
   bool check_inode_max_size(CInode *in, bool forceupdate=false, __u64 newsize=0);
 private:
index 2f7ff45c51562ffcb69f4873973c7d106e0830b5..8cd8d4e12c34be4ccdb62f8680127ba323c96938 100644 (file)
@@ -53,8 +53,6 @@ using namespace std;
 
 // CAPS
 
-typedef __u32 capseq_t;
-
 inline string gcap_string(int cap)
 {
   string s;
@@ -296,10 +294,10 @@ struct inode_t {
   ceph_file_layout layout;
   uint64_t   size;        // on directory, # dentries
   uint64_t   max_size;    // client(s) are auth to write this much...
-  uint64_t   truncate_seq;
+  uint32_t   truncate_seq;
   utime_t    mtime;   // file data modify time.
   utime_t    atime;   // file data access time.
-  uint64_t   time_warp_seq;  // count of (potential) mtime/atime timewarps (i.e., utimes())
+  uint32_t   time_warp_seq;  // count of (potential) mtime/atime timewarps (i.e., utimes())
 
   // dirfrag, recursive accounting
   frag_info_t dirstat;
index 2cf789a9861219d0243f38ce3ea688894eda67d5..4fe1f7f9dc8b64187b928c63e9f6f71aabd4cfa7 100644 (file)
@@ -27,19 +27,19 @@ class MClientCaps : public Message {
   int      get_caps() { return head.caps; }
   int      get_wanted() { return head.wanted; }
   int      get_dirty() { return head.dirty; }
-  capseq_t get_seq() { return head.seq; }
-  capseq_t get_mseq() { return head.migrate_seq; }
+  ceph_seq_t get_seq() { return head.seq; }
+  ceph_seq_t get_mseq() { return head.migrate_seq; }
 
   inodeno_t get_ino() { return inodeno_t(head.ino); }
   inodeno_t get_realm() { return inodeno_t(head.realm); }
 
   __u64 get_size() { return head.size;  }
   __u64 get_max_size() { return head.max_size;  }
-  __u64 get_truncate_seq() { return head.truncate_seq; }
+  __u32 get_truncate_seq() { return head.truncate_seq; }
   utime_t get_ctime() { return utime_t(head.ctime); }
   utime_t get_mtime() { return utime_t(head.mtime); }
   utime_t get_atime() { return utime_t(head.atime); }
-  __u64 get_time_warp_seq() { return head.time_warp_seq; }
+  __u32 get_time_warp_seq() { return head.time_warp_seq; }
 
   ceph_file_layout& get_layout() { return head.layout; }