]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: Use map for CInode pinrefs
authorSam Lang <sam.lang@inktank.com>
Tue, 5 Mar 2013 14:28:47 +0000 (08:28 -0600)
committerSam Lang <sam.lang@inktank.com>
Sat, 16 Mar 2013 16:45:36 +0000 (11:45 -0500)
Implements pin refs on the inode as a map instead of
a multiset, allowing individual ref counts to act as
real references with values that can be >1.
The pin refs are only used for debugging, but allowing
them to be >1 avoids the need for a separate state field
for things like DIRTYPARENT.

Signed-off-by: Sam Lang <sam.lang@inktank.com>
Reviewed-by: Greg Farnum <greg@inktank.com>
src/mds/CInode.h
src/mds/mdstypes.h

index f7b8f3316f67d3da1e90be3caecfff5976c6d844..e43a4565c650c795e60cc11ed96129c2be15658c 100644 (file)
@@ -783,22 +783,22 @@ public:
   void bad_put(int by) {
     generic_dout(0) << " bad put " << *this << " by " << by << " " << pin_name(by) << " was " << ref
 #ifdef MDS_REF_SET
-                   << " (" << ref_set << ")"
+                   << " (" << ref_map << ")"
 #endif
                    << dendl;
 #ifdef MDS_REF_SET
-    assert(ref_set.count(by) == 1);
+    assert(ref_map[by] > 0);
 #endif
     assert(ref > 0);
   }
   void bad_get(int by) {
     generic_dout(0) << " bad get " << *this << " by " << by << " " << pin_name(by) << " was " << ref
 #ifdef MDS_REF_SET
-                   << " (" << ref_set << ")"
+                   << " (" << ref_map << ")"
 #endif
                    << dendl;
 #ifdef MDS_REF_SET
-    assert(ref_set.count(by) == 0);
+    assert(ref_map[by] >= 0);
 #endif
   }
   void first_get();
index b374abbc2c5943b5c9dc5b9799f083968e4adbc7..21cc60e93914a9bb084f72b210e124392a5f5db1 100644 (file)
@@ -1169,11 +1169,29 @@ class MDSCacheObject {
 protected:
   __s32      ref;       // reference count
 #ifdef MDS_REF_SET
-  multiset<int> ref_set;
+  map<int,int> ref_map;
 #endif
 
  public:
-  int get_num_ref() { return ref; }
+  int get_num_ref(int by = -1) {
+#ifdef MDS_REF_SET
+    if (by >= 0) {
+      if (ref_map.find(by) == ref_map.end())
+       return 0;
+      return ref_map[by];
+    }
+#endif
+    return ref;
+  }
+#ifdef MDS_REF_SET
+  int get_pin_totals() {
+    int total = 0;
+    for(map<int,int>::iterator i = ref_map.begin(); i != ref_map.end(); ++i) {
+      total += i->second;
+    }
+    return total;
+  }
+#endif
   virtual const char *pin_name(int by) = 0;
   //bool is_pinned_by(int by) { return ref_set.count(by); }
   //multiset<int>& get_ref_set() { return ref_set; }
@@ -1181,13 +1199,13 @@ protected:
   virtual void last_put() {}
   virtual void bad_put(int by) {
 #ifdef MDS_REF_SET
-    assert(ref_set.count(by) > 0);
+    assert(ref_map[by] > 0);
 #endif
     assert(ref > 0);
   }
   void put(int by) {
 #ifdef MDS_REF_SET
-    if (ref == 0 || ref_set.count(by) == 0) {
+    if (ref == 0 || ref_map[by] == 0) {
 #else
     if (ref == 0) {
 #endif
@@ -1195,8 +1213,8 @@ protected:
     } else {
       ref--;
 #ifdef MDS_REF_SET
-      ref_set.erase(ref_set.find(by));
-      assert(ref == (int)ref_set.size());
+      ref_map[by]--;
+      assert(ref == get_pin_totals());
 #endif
       if (ref == 0)
        last_put();
@@ -1206,39 +1224,28 @@ protected:
   virtual void first_get() {}
   virtual void bad_get(int by) {
 #ifdef MDS_REF_SET
-    assert(by < 0 || ref_set.count(by) == 0);
+    assert(by < 0 || ref_map[by] == 0);
 #endif
     assert(0);
   }
   void get(int by) {
+    if (ref == 0)
+      first_get();
+    ref++;
 #ifdef MDS_REF_SET
-    if (by >= 0 && ref_set.count(by)) {
-      bad_get(by);
-    } else {
-#endif
-      if (ref == 0) 
-       first_get();
-      ref++;
-#ifdef MDS_REF_SET
-      ref_set.insert(by);
-      assert(ref == (int)ref_set.size());
-    }
+    if (ref_map.find(by) == ref_map.end())
+      ref_map[by] = 0;
+    ref_map[by]++;
+    assert(ref == get_pin_totals());
 #endif
   }
 
   void print_pin_set(ostream& out) {
 #ifdef MDS_REF_SET
-    multiset<int>::iterator it = ref_set.begin();
-    while (it != ref_set.end()) {
-      out << " " << pin_name(*it);
-      int last = *it;
-      int c = 0;
-      do {
-       ++it;
-       c++;
-      } while (it != ref_set.end() && *it == last);
-      if (c > 1)
-       out << "*" << c;
+    map<int, int>::iterator it = ref_map.begin();
+    while (it != ref_map.end()) {
+      out << " " << pin_name(it->first) << "=" << it->second;
+      it++;
     }
 #else
     out << " nref=" << ref;