]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librados: fix locking for AioCompletionImpl refcounting
authorJosh Durgin <josh.durgin@inktank.com>
Tue, 13 Aug 2013 02:17:09 +0000 (19:17 -0700)
committerSage Weil <sage@inktank.com>
Thu, 15 Aug 2013 18:29:04 +0000 (11:29 -0700)
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 <josh.durgin@inktank.com>
Reviewed-by: Sage Weil <sage@inktank.com>
Tested-by: Oliver Francke <Oliver.Francke@filoo.de>
(cherry picked from commit 7a52e2ff5025754f3040eff3fc52d4893cafc389)

src/librados/AioCompletionImpl.h

index b3e1e8a16e2c5f08814388e48fe2bd175abf4fc4..8d6c5a542b0aed2ae709d7c957c3a2f5b5f26e99 100644 (file)
@@ -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) {