From e2283e3066f5929b1a8cf56d627d8acc22f5f040 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Fri, 27 Feb 2015 09:46:55 -0500 Subject: [PATCH] librbd: flush pending AIO after acquiring lock There was a potential race condition between a delayed AIO operation waiting on acquiring a lock and a snap_create flushing all pending IO. Since snap_create owned md_lock, the delayed AIO would not be allowed to complete -- deadlocking the flush. Signed-off-by: Jason Dillaman --- src/librbd/internal.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 19645f0f9119e..9551332f89224 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -454,13 +454,20 @@ namespace librbd { // need to upgrade to a write lock int r = 0; + bool acquired_lock = false; ictx->owner_lock.put_read(); { RWLock::WLocker l(ictx->owner_lock); if (!ictx->image_watcher->is_lock_owner()) { r = ictx->image_watcher->try_lock(); + acquired_lock = ictx->image_watcher->is_lock_owner(); } } + if (acquired_lock) { + // finish any AIO that was previously waiting on acquiring the + // exclusive lock + ictx->flush_async_operations(); + } ictx->owner_lock.get_read(); return r; } -- 2.39.5