From c4dc8835de57462c28b94aafa97dd592ba89ef42 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Fri, 12 Apr 2019 11:07:31 -0400 Subject: [PATCH] librbd: write-around cache should honor FUA op flag If force unit access is specified, the cache should be bypassed just like other non-optimized IO through the cache. Signed-off-by: Jason Dillaman --- src/librbd/cache/WriteAroundObjectDispatch.cc | 17 ++++++++++---- src/librbd/cache/WriteAroundObjectDispatch.h | 5 ++-- .../test_mock_WriteAroundObjectDispatch.cc | 23 +++++++++++++++++++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/librbd/cache/WriteAroundObjectDispatch.cc b/src/librbd/cache/WriteAroundObjectDispatch.cc index 38a81fe5397..1952d1af3e4 100644 --- a/src/librbd/cache/WriteAroundObjectDispatch.cc +++ b/src/librbd/cache/WriteAroundObjectDispatch.cc @@ -73,7 +73,7 @@ bool WriteAroundObjectDispatch::discard( ldout(cct, 20) << "object_no=" << object_no << " " << object_off << "~" << object_len << dendl; - return dispatch_io(object_no, object_off, object_len, dispatch_result, + return dispatch_io(object_no, object_off, object_len, 0, dispatch_result, on_finish, on_dispatched); } @@ -88,8 +88,8 @@ bool WriteAroundObjectDispatch::write( ldout(cct, 20) << "object_no=" << object_no << " " << object_off << "~" << data.length() << dendl; - return dispatch_io(object_no, object_off, data.length(), dispatch_result, - on_finish, on_dispatched); + return dispatch_io(object_no, object_off, data.length(), op_flags, + dispatch_result, on_finish, on_dispatched); } template @@ -104,7 +104,7 @@ bool WriteAroundObjectDispatch::write_same( ldout(cct, 20) << "object_no=" << object_no << " " << object_off << "~" << object_len << dendl; - return dispatch_io(object_no, object_off, object_len, dispatch_result, + return dispatch_io(object_no, object_off, object_len, 0, dispatch_result, on_finish, on_dispatched); } @@ -194,7 +194,7 @@ bool WriteAroundObjectDispatch::dispatch_unoptimized_io( template bool WriteAroundObjectDispatch::dispatch_io( uint64_t object_no, uint64_t object_off, uint64_t object_len, - io::DispatchResult* dispatch_result, Context** on_finish, + int op_flags, io::DispatchResult* dispatch_result, Context** on_finish, Context* on_dispatched) { auto cct = m_image_ctx->cct; @@ -205,6 +205,13 @@ bool WriteAroundObjectDispatch::dispatch_io( return false; } + if ((op_flags & LIBRADOS_OP_FLAG_FADVISE_FUA) != 0) { + // force unit access flag is set -- disable write-around + m_lock.Unlock(); + return dispatch_unoptimized_io(object_no, object_off, object_len, + dispatch_result, on_dispatched); + } + auto tid = ++m_last_tid; auto ctx = util::create_async_context_callback(*m_image_ctx, *on_finish); diff --git a/src/librbd/cache/WriteAroundObjectDispatch.h b/src/librbd/cache/WriteAroundObjectDispatch.h index bafde05a36a..b9909b9db8f 100644 --- a/src/librbd/cache/WriteAroundObjectDispatch.h +++ b/src/librbd/cache/WriteAroundObjectDispatch.h @@ -168,8 +168,9 @@ private: io::DispatchResult* dispatch_result, Context* on_dispatched); bool dispatch_io(uint64_t object_no, uint64_t object_off, - uint64_t object_len, io::DispatchResult* dispatch_result, - Context** on_finish, Context* on_dispatch); + uint64_t object_len, int op_flags, + io::DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatch); bool block_overlapping_io(InFlightObjectExtents* in_flight_object_extents, uint64_t object_off, uint64_t object_len); diff --git a/src/test/librbd/cache/test_mock_WriteAroundObjectDispatch.cc b/src/test/librbd/cache/test_mock_WriteAroundObjectDispatch.cc index 1fa346f7211..611109fcc47 100644 --- a/src/test/librbd/cache/test_mock_WriteAroundObjectDispatch.cc +++ b/src/test/librbd/cache/test_mock_WriteAroundObjectDispatch.cc @@ -632,5 +632,28 @@ TEST_F(TestMockCacheWriteAroundObjectDispatch, UnoptimizedIOBlockedIO) { finish_ctx_ptr2->complete(0); } +TEST_F(TestMockCacheWriteAroundObjectDispatch, FUA) { + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockTestImageCtx mock_image_ctx(*ictx); + MockWriteAroundObjectDispatch object_dispatch(&mock_image_ctx, 16384, false); + + InSequence seq; + + bufferlist data; + data.append(std::string(4096, '1')); + + io::DispatchResult dispatch_result; + MockContext finish_ctx; + MockContext dispatch_ctx; + Context* finish_ctx_ptr = &finish_ctx; + ASSERT_FALSE(object_dispatch.write("oid", 0, 0, std::move(data), {}, + LIBRADOS_OP_FLAG_FADVISE_FUA, {}, + nullptr, nullptr, &dispatch_result, + &finish_ctx_ptr, &dispatch_ctx)); + ASSERT_EQ(finish_ctx_ptr, &finish_ctx); +} + } // namespace cache } // namespace librbd -- 2.39.5