From 5301b2b7057a49eb336dbe2ab3e49f4d5bbdc0a9 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Sun, 25 Jan 2015 22:15:07 -0500 Subject: [PATCH] librbd: trim header update not using AIO The original trim header update code was using blocking IO to update the header. After migrating to an asynchronous trim which performs all work in librados callbacks, it exposed a potential deadlock in the librados_test_stub when attempting to do blocking IO within a librados callback. This commit changes the header update to use AIO. Fixes: #10637 Signed-off-by: Jason Dillaman --- src/librbd/internal.cc | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 23a94b77e24..7c51b5c3658 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -1684,13 +1684,19 @@ reprotect_and_return_err: ldout(m_ictx->cct, 2) << "async_resize_helper finished (" << r << ")" << dendl; - RWLock::WLocker l(m_ictx->md_lock); - if (r < 0 && m_ictx->size == m_new_size) { - m_ictx->size = m_original_size; - } - m_ctx->complete(r); + if (r < 0) { + RWLock::WLocker l(m_ictx->md_lock); + if (m_ictx->size == m_new_size) { + m_ictx->size = m_original_size; + } + m_ctx->complete(r); + } } BOOST_SCOPE_EXIT_END + if (r < 0) { + return; + } + RWLock::RLocker l(m_ictx->owner_lock); if (m_ictx->image_watcher->is_lock_supported() && !m_ictx->image_watcher->is_lock_owner()) { @@ -1700,24 +1706,29 @@ reprotect_and_return_err: RWLock::WLocker l2(m_ictx->md_lock); m_ictx->size = m_new_size; + + librados::ObjectWriteOperation op; if (m_ictx->old_format) { // rewrite header bufferlist bl; m_ictx->header.image_size = m_new_size; bl.append((const char *)&m_ictx->header, sizeof(m_ictx->header)); - r = m_ictx->md_ctx.write(m_ictx->header_oid, bl, bl.length(), 0); + op.write(0, bl); } else { - librados::ObjectWriteOperation op; if (m_ictx->image_watcher->is_lock_supported()) { m_ictx->image_watcher->assert_header_locked(&op); } cls_client::set_size(&op, m_new_size); - r = m_ictx->md_ctx.operate(m_ictx->header_oid, &op); } + librados::AioCompletion *rados_completion = + librados::Rados::aio_create_completion(m_ctx, NULL, rados_ctx_cb); + r = m_ictx->md_ctx.aio_operate(m_ictx->header_oid, rados_completion, &op); + rados_completion->release(); if (r < 0) { lderr(m_ictx->cct) << "error writing header: " << cpp_strerror(r) << dendl; + return; } } -- 2.47.3