From: Samuel Just Date: Tue, 5 Nov 2013 23:40:29 +0000 (-0800) Subject: RadosModel: use sharedptr_registry for snaps_in_use X-Git-Tag: v0.72~9 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a3ccd29716af900be265b6f995eb4069b334c516;p=ceph.git RadosModel: use sharedptr_registry for snaps_in_use 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 Reviewed-by: David Zafman --- diff --git a/src/common/sharedptr_registry.hpp b/src/common/sharedptr_registry.hpp index 9fe2fe6be1a1..83396b8cc5f6 100644 --- a/src/common/sharedptr_registry.hpp +++ b/src/common/sharedptr_registry.hpp @@ -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); diff --git a/src/test/osd/RadosModel.h b/src/test/osd/RadosModel.h index 902d4b970c3d..80bcf00a6d78 100644 --- a/src/test/osd/RadosModel.h +++ b/src/test/osd/RadosModel.h @@ -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 > pool_obj_cont; set oid_in_use; set oid_not_in_use; - set snaps_in_use; + SharedPtrRegistry 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 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(); context->kick(); } diff --git a/src/test/osd/TestRados.cc b/src/test/osd/TestRados.cc index 0c1d55c7777e..20a4f8209cc5 100644 --- a/src/test/osd/TestRados.cc +++ b/src/test/osd/TestRados.cc @@ -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);