From: Josh Durgin Date: Tue, 13 Aug 2013 02:17:09 +0000 (-0700) Subject: librados: fix locking for AioCompletionImpl refcounting X-Git-Tag: v0.61.8~5 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=ef731dfc84a71d3c3262f5cff9a9d33a60255485;p=ceph.git librados: fix locking for AioCompletionImpl refcounting Add an already-locked helper so that C_Aio{Safe,Complete} can increment the reference count when their caller holds the lock. C_AioCompleteAndSafe's caller is not holding the lock, so call regular get() to ensure no racing updates can occur. This eliminates all direct manipulations of AioCompletionImpl->ref, and makes the necessary locking clear. The only place C_AioCompleteAndSafe is used is in handling aio_flush_async(). This could cause a missing completion. Refs: #5919 Signed-off-by: Josh Durgin Reviewed-by: Sage Weil Tested-by: Oliver Francke (cherry picked from commit 7a52e2ff5025754f3040eff3fc52d4893cafc389) --- diff --git a/src/librados/AioCompletionImpl.h b/src/librados/AioCompletionImpl.h index b3e1e8a16e2c5..8d6c5a542b0ae 100644 --- a/src/librados/AioCompletionImpl.h +++ b/src/librados/AioCompletionImpl.h @@ -134,10 +134,14 @@ struct librados::AioCompletionImpl { void get() { lock.Lock(); - assert(ref > 0); - ref++; + _get(); lock.Unlock(); } + void _get() { + assert(lock.is_locked()); + assert(ref > 0); + ++ref; + } void release() { lock.Lock(); assert(!released); @@ -162,7 +166,7 @@ struct C_AioComplete : public Context { AioCompletionImpl *c; C_AioComplete(AioCompletionImpl *cc) : c(cc) { - c->ref++; + c->_get(); } void finish(int r) { @@ -181,7 +185,7 @@ struct C_AioSafe : public Context { AioCompletionImpl *c; C_AioSafe(AioCompletionImpl *cc) : c(cc) { - c->ref++; + c->_get(); } void finish(int r) { @@ -208,7 +212,7 @@ struct C_AioCompleteAndSafe : public Context { AioCompletionImpl *c; C_AioCompleteAndSafe(AioCompletionImpl *cc) : c(cc) { - c->ref++; + c->get(); } void finish(int r) {