ReplicatedPG: add Mutex to protect snapset_contexts

snapset_contexts_locks is added and locked in each function where
snapset_contexts or the SnapSetContext::ref data member needs to be
accessed or modified.

http://tracker.ceph.com/issues/5510 refs #5510

Signed-off-by: Loic Dachary <loic@dachary.org>
This commit is contained in:
Loic Dachary 2013-08-15 20:15:03 +02:00
parent e1be37a375
commit 1688fb4842
2 changed files with 14 additions and 4 deletions

View File

@ -613,7 +613,9 @@ void ReplicatedPG::calc_trim_to()
ReplicatedPG::ReplicatedPG(OSDService *o, OSDMapRef curmap,
const PGPool &_pool, pg_t p, const hobject_t& oid,
const hobject_t& ioid) :
PG(o, curmap, _pool, p, oid, ioid), temp_created(false),
PG(o, curmap, _pool, p, oid, ioid),
snapset_contexts_lock("ReplicatedPG::snapset_contexts"),
temp_created(false),
temp_coll(coll_t::make_temp_coll(p)), snap_trimmer_machine(this)
{
snap_trimmer_machine.initiate();
@ -4794,9 +4796,10 @@ void ReplicatedPG::add_object_context_to_pg_stat(ObjectContext *obc, pg_stat_t *
SnapSetContext *ReplicatedPG::create_snapset_context(const object_t& oid)
{
Mutex::Locker l(snapset_contexts_lock);
SnapSetContext *ssc = new SnapSetContext(oid);
dout(10) << "create_snapset_context " << ssc << " " << ssc->oid << dendl;
register_snapset_context(ssc);
_register_snapset_context(ssc);
ssc->ref++;
return ssc;
}
@ -4807,6 +4810,7 @@ SnapSetContext *ReplicatedPG::get_snapset_context(const object_t& oid,
bool can_create,
const string& nspace)
{
Mutex::Locker l(snapset_contexts_lock);
SnapSetContext *ssc;
map<object_t, SnapSetContext*>::iterator p = snapset_contexts.find(oid);
if (p != snapset_contexts.end()) {
@ -4825,7 +4829,7 @@ SnapSetContext *ReplicatedPG::get_snapset_context(const object_t& oid,
return NULL;
}
ssc = new SnapSetContext(oid);
register_snapset_context(ssc);
_register_snapset_context(ssc);
if (r >= 0) {
bufferlist::iterator bvp = bv.begin();
ssc->snapset.decode(bvp);
@ -4840,9 +4844,9 @@ SnapSetContext *ReplicatedPG::get_snapset_context(const object_t& oid,
void ReplicatedPG::put_snapset_context(SnapSetContext *ssc)
{
Mutex::Locker l(snapset_contexts_lock);
dout(10) << "put_snapset_context " << ssc->oid << " "
<< ssc->ref << " -> " << (ssc->ref-1) << dendl;
--ssc->ref;
if (ssc->ref == 0) {
if (ssc->registered)

View File

@ -278,6 +278,7 @@ protected:
// projected object info
map<hobject_t, ObjectContext*> object_contexts;
map<object_t, SnapSetContext*> snapset_contexts;
Mutex snapset_contexts_lock;
// debug order that client ops are applied
map<hobject_t, map<client_t, tid_t> > debug_op_order;
@ -327,6 +328,11 @@ protected:
SnapSetContext *get_snapset_context(const object_t& oid, const string &key,
ps_t seed, bool can_create, const string &nspace);
void register_snapset_context(SnapSetContext *ssc) {
Mutex::Locker l(snapset_contexts_lock);
_register_snapset_context(ssc);
}
void _register_snapset_context(SnapSetContext *ssc) {
assert(snapset_contexts_lock.is_locked());
if (!ssc->registered) {
assert(snapset_contexts.count(ssc->oid) == 0);
ssc->registered = true;