]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
RadosModel: use sharedptr_registry for snaps_in_use
authorSamuel Just <sam.just@inktank.com>
Tue, 5 Nov 2013 23:40:29 +0000 (15:40 -0800)
committerSamuel Just <sam.just@inktank.com>
Wed, 6 Nov 2013 02:00:04 +0000 (18:00 -0800)
There might be two concurrent rollback ops each of which
adds snap x to snaps_in_use.  Between when the first
completes and the second completes, snap x may be removed
since the first would have removed snap x from snaps_in_use.
Using sharedptr_registry here avoids this by ensuring that
the snap won't be removed from snaps_in_use until all refs
are gone.

This patch also adds size() to sharedptr_registry.

Fixes: #6719
Signed-off-by: Samuel Just <sam.just@inktank.com>
Reviewed-by: David Zafman <david.zafman@inktank.com>
src/common/sharedptr_registry.hpp
src/test/osd/RadosModel.h
src/test/osd/TestRados.cc

index 9fe2fe6be1a10a5e195f73fb4588c2fdaaf45dc2..83396b8cc5f67e6fa506c7edab7754e19ce49ba4 100644 (file)
@@ -149,6 +149,11 @@ public:
     return retval;
   }
 
+  unsigned size() {
+    Mutex::Locker l(lock);
+    return contents.size();
+  }
+
   void remove(const K &key) {
     Mutex::Locker l(lock);
     contents.erase(key);
index 902d4b970c3df06babd51ed7625a85e4e1adecc3..80bcf00a6d785a38900d15532f5b8fdbd0f2aba4 100644 (file)
@@ -18,6 +18,7 @@
 #include "Object.h"
 #include "TestOpStat.h"
 #include "test/librados/test.h"
+#include "common/sharedptr_registry.hpp"
 
 #ifndef RADOSMODEL_H
 #define RADOSMODEL_H
@@ -143,7 +144,7 @@ public:
   map<int, map<string,ObjectDesc> > pool_obj_cont;
   set<string> oid_in_use;
   set<string> oid_not_in_use;
-  set<int> snaps_in_use;
+  SharedPtrRegistry<int, int> snaps_in_use;
   int current_snap;
   string pool_name;
   librados::IoCtx io_ctx;
@@ -1321,6 +1322,7 @@ public:
   bool done;
   librados::ObjectWriteOperation op;
   librados::AioCompletion *comp;
+  std::tr1::shared_ptr<int> in_use;
 
   RollbackOp(int n,
             RadosTestContext *context,
@@ -1351,7 +1353,9 @@ public:
     context->oid_not_in_use.erase(oid);
 
     roll_back_to = rand_choose(context->snaps)->first;
-    context->snaps_in_use.insert(roll_back_to);
+    in_use = context->snaps_in_use.lookup_or_create(
+      roll_back_to,
+      roll_back_to);
 
     cout << "rollback oid " << oid << " to " << roll_back_to << std::endl;
 
@@ -1382,7 +1386,7 @@ public:
     context->update_object_version(oid, comp->get_version64());
     context->oid_in_use.erase(oid);
     context->oid_not_in_use.insert(oid);
-    context->snaps_in_use.erase(roll_back_to);
+    in_use = std::tr1::shared_ptr<int>();
     context->kick();
   }
 
index 0c1d55c7777e6affa23c749b1b51003b59b5bc2f..20a4f8209cc55edc12bec980f2d232b68fa50ff4 100644 (file)
@@ -116,7 +116,7 @@ private:
       }
       while (true) {
        int snap = rand_choose(context.snaps)->first;
-       if (context.snaps_in_use.count(snap))
+       if (context.snaps_in_use.lookup(snap))
          continue;  // in use; try again!
        cout << "snap_remove snap " << snap << std::endl;
        return new SnapRemoveOp(m_op, &context, snap, m_stats);