From: Jason Dillaman Date: Tue, 3 Mar 2015 02:07:01 +0000 (-0500) Subject: librbd: allow AioCompletions to be blocked X-Git-Tag: v0.94~65^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7d2fe5b8f3c1959a554da2efb18b05987c2d8c4c;p=ceph.git librbd: allow AioCompletions to be blocked Blocked AioCompletions will not fire their callback until unblocked. This is an expansion / replacement of the previous 'building' flag used to block completions while additional requests were added to the completion. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/AioCompletion.cc b/src/librbd/AioCompletion.cc index 4ead667d6dbf..8c38e1c95c4a 100644 --- a/src/librbd/AioCompletion.cc +++ b/src/librbd/AioCompletion.cc @@ -26,14 +26,7 @@ namespace librbd { void AioCompletion::finish_adding_requests(CephContext *cct) { ldout(cct, 20) << "AioCompletion::finish_adding_requests " << (void*)this << " pending " << pending_count << dendl; - lock.Lock(); - assert(building); - building = false; - if (!pending_count) { - finalize(cct, rval); - complete(); - } - lock.Unlock(); + unblock(cct); } int AioCompletion::wait_for_complete() { @@ -89,6 +82,7 @@ namespace librbd { break; } + // note: possible for image to be closed after op marked finished async_op.finish_op(); if (complete_cb) { @@ -113,7 +107,7 @@ namespace librbd { } assert(pending_count); int count = --pending_count; - if (!count && !building) { + if (!count && blockers == 0) { finalize(cct, rval); complete(); } diff --git a/src/librbd/AioCompletion.h b/src/librbd/AioCompletion.h index 41c89f2f0b93..cef8388e6202 100644 --- a/src/librbd/AioCompletion.h +++ b/src/librbd/AioCompletion.h @@ -50,7 +50,7 @@ namespace librbd { void *complete_arg; rbd_completion_t rbd_comp; int pending_count; ///< number of requests - bool building; ///< true if we are still building this completion + uint32_t blockers; int ref; bool released; ImageCtx *ictx; @@ -67,7 +67,7 @@ namespace librbd { AioCompletion() : lock("AioCompletion::lock", true), done(false), rval(0), complete_cb(NULL), complete_arg(NULL), rbd_comp(NULL), - pending_count(0), building(true), + pending_count(0), blockers(1), ref(1), released(false), ictx(NULL), aio_type(AIO_TYPE_NONE), read_bl(NULL), read_buf(NULL), read_buf_len(0) { @@ -134,6 +134,20 @@ namespace librbd { if (!n) delete this; } + + void block() { + Mutex::Locker l(lock); + ++blockers; + } + void unblock(CephContext *cct) { + Mutex::Locker l(lock); + assert(blockers > 0); + --blockers; + if (pending_count == 0 && blockers == 0) { + finalize(cct, rval); + complete(); + } + } }; class C_AioRead : public Context {