]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mdstypes: write inode_t::compare() function
authorGreg Farnum <greg@inktank.com>
Wed, 1 Oct 2014 01:07:30 +0000 (18:07 -0700)
committerGreg Farnum <gfarnum@redhat.com>
Fri, 7 Nov 2014 19:48:42 +0000 (11:48 -0800)
This compares one inode_t against another, seeing which version is newer
and checking that differences in the data members make sense given that.

Signed-off-by: Greg Farnum <greg@inktank.com>
src/mds/mdstypes.cc
src/mds/mdstypes.h

index eb1ae77d655c1064c3f2a0fb667a48541543cdae..ecdbc4f3bade995d1f286c2a22d36260bf557110 100644 (file)
@@ -390,6 +390,70 @@ void inode_t::generate_test_instances(list<inode_t*>& ls)
   // i am lazy.
 }
 
+int inode_t::compare(const inode_t &other, bool *divergent) const
+{
+  assert(ino == other.ino);
+  if (version == other.version) {
+    if (rdev != other.rdev ||
+        ctime != other.ctime ||
+        mode != other.mode ||
+        uid != other.uid ||
+        gid != other.gid ||
+        nlink != other.nlink ||
+        memcmp(&dir_layout, &other.dir_layout, sizeof(dir_layout)) ||
+        memcmp(&layout, &other.layout, sizeof(layout)) ||
+        old_pools != other.old_pools ||
+        size != other.size ||
+        max_size_ever != other.max_size_ever ||
+        truncate_seq != other.truncate_seq ||
+        truncate_size != other.truncate_size ||
+        truncate_from != other.truncate_from ||
+        truncate_pending != other.truncate_pending ||
+        mtime != other.mtime ||
+        atime != other.atime ||
+        time_warp_seq != other.time_warp_seq ||
+        !(*const_cast<bufferlist*>(&inline_data) ==
+            *const_cast<bufferlist*>(&other.inline_data)) ||
+        inline_version != other.inline_version ||
+        client_ranges != other.client_ranges ||
+        !(dirstat == other.dirstat) ||
+        !(rstat == other.rstat) ||
+        !(accounted_rstat == other.accounted_rstat) ||
+        file_data_version != other.file_data_version ||
+        xattr_version != other.xattr_version ||
+        backtrace_version != other.backtrace_version) {
+      *divergent = true;
+    }
+    return 0;
+  } else if (version > other.version) {
+    *divergent = !older_is_consistent(other);
+    return 1;
+  } else {
+    assert(version < other.version);
+    *divergent = !other.older_is_consistent(*this);
+    return -1;
+  }
+  assert(0 == "can't have reached this point");
+  *divergent = true;
+  return 0;
+}
+
+bool inode_t::older_is_consistent(const inode_t &other) const
+{
+  if (max_size_ever < other.max_size_ever ||
+      truncate_seq < other.truncate_seq ||
+      time_warp_seq < other.time_warp_seq ||
+      inline_version < other.inline_version ||
+      dirstat.version < other.dirstat.version ||
+      rstat.version < other.rstat.version ||
+      accounted_rstat.version < other.accounted_rstat.version ||
+      file_data_version < other.file_data_version ||
+      xattr_version < other.xattr_version ||
+      backtrace_version < other.backtrace_version) {
+    return false;
+  }
+  return true;
+}
 
 /*
  * old_inode_t
index d7c2665058b63c2dd5ac58a990884d0949ae892c..59d79cf0b3188b6495c4b8d1c9315c044aa9df6a 100644 (file)
@@ -308,6 +308,11 @@ inline bool operator==(const client_writeable_range_t& l,
  * inode_t
  */
 struct inode_t {
+  /**
+   * ***************
+   * Do not forget to add any new fields to the compare() function.
+   * ***************
+   */
   // base (immutable)
   inodeno_t ino;
   uint32_t   rdev;    // if special file
@@ -447,6 +452,21 @@ struct inode_t {
   void decode(bufferlist::iterator& bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<inode_t*>& ls);
+  /**
+   * Compare this inode_t with another that represent *the same inode*
+   * at different points in time.
+   * @pre The inodes are the same ino
+   *
+   * @param other The inode_t to compare ourselves with
+   * @param divergent A bool pointer which will be set to true
+   * if the values are different in a way that can't be explained
+   * by one being a newer version than the other.
+   *
+   * @returns 1 if we are newer than the other, 0 if equal, -1 if older.
+   */
+  int compare(const inode_t &other, bool *divergent) const;
+private:
+  bool older_is_consistent(const inode_t &other) const;
 };
 WRITE_CLASS_ENCODER(inode_t)