summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-07-22 17:18:59 -0700
committerSage Weil <sage@inktank.com>2013-07-22 17:18:59 -0700
commitabee5b595271ade7cfad37487d3759c1442c1560 (patch)
treecee1a59810955a9058cdf78c11c909ad2704d3e3
parentbfaf85982282241b6d938e315eaeeb6e01d207d2 (diff)
downloadceph-abee5b595271ade7cfad37487d3759c1442c1560.tar.gz
librbd: avoid recursive locking of AioCompletion::lock
The caller of the callback is holding the completion lock; do not retake it. Fixes assert triggered when lockdep is enabled. Signed-off-by: Sage Weil <sage@inktank.com>
-rw-r--r--src/librbd/AioCompletion.h11
-rw-r--r--src/librbd/internal.cc4
2 files changed, 13 insertions, 2 deletions
diff --git a/src/librbd/AioCompletion.h b/src/librbd/AioCompletion.h
index 899586d51a7..b09ed9f9a9b 100644
--- a/src/librbd/AioCompletion.h
+++ b/src/librbd/AioCompletion.h
@@ -139,6 +139,10 @@ namespace librbd {
lock.Unlock();
return r;
}
+ ssize_t _get_return_value() {
+ assert(lock.is_locked());
+ return rval;
+ }
void get() {
lock.Lock();
@@ -152,6 +156,13 @@ namespace librbd {
released = true;
put_unlock();
}
+ void _release() {
+ assert(lock.is_locked());
+ assert(!released);
+ released = true;
+ int n = --ref;
+ assert(n > 0);
+ }
void put() {
lock.Lock();
put_unlock();
diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc
index 1fd7942f3b8..db7d55d82ff 100644
--- a/src/librbd/internal.cc
+++ b/src/librbd/internal.cc
@@ -2317,8 +2317,8 @@ reprotect_and_return_err:
{
Context *ctx = reinterpret_cast<Context *>(arg);
AioCompletion *comp = reinterpret_cast<AioCompletion *>(cb);
- ctx->complete(comp->get_return_value());
- comp->release();
+ ctx->complete(comp->_get_return_value()); // caller already holds aioc lock
+ comp->_release();
}
int64_t read_iterate(ImageCtx *ictx, uint64_t off, uint64_t len,