From b51c282ab53ec14caae60dd68c2c1b40d04c7460 Mon Sep 17 00:00:00 2001 From: lixiaoy1 Date: Mon, 9 Dec 2019 09:56:56 -0500 Subject: [PATCH] librbd: finish write request early Finish write requests if the image is read-only or length is 0. Signed-off-by: Li, Xiaoyan --- src/librbd/io/ImageRequest.cc | 30 +++++++++++++++--- src/librbd/io/ImageRequest.h | 5 ++- src/test/librbd/io/test_mock_ImageRequest.cc | 32 ++++++++++++++++++++ 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/librbd/io/ImageRequest.cc b/src/librbd/io/ImageRequest.cc index dc2acce5df011..977182eacd1c5 100644 --- a/src/librbd/io/ImageRequest.cc +++ b/src/librbd/io/ImageRequest.cc @@ -219,7 +219,6 @@ void ImageRequest::aio_compare_and_write(I *ictx, AioCompletion *c, req.send(); } - template void ImageRequest::send() { I &image_ctx = this->m_image_ctx; @@ -237,6 +236,10 @@ void ImageRequest::send() { return; } + if (finish_request_early()) { + return; + } + if (m_bypass_image_cache || m_image_ctx.image_cache == nullptr) { update_timestamp(); send_request(); @@ -407,6 +410,27 @@ void ImageReadRequest::send_image_cache_request() { req_comp); } +template +bool AbstractImageWriteRequest::finish_request_early() { + AioCompletion *aio_comp = this->m_aio_comp; + { + std::shared_lock image_locker{this->m_image_ctx.image_lock}; + if (this->m_image_ctx.snap_id != CEPH_NOSNAP || this->m_image_ctx.read_only) { + aio_comp->fail(-EROFS); + return true; + } + } + uint64_t total_bytes = 0; + for (auto& image_extent : this->m_image_extents) { + total_bytes += image_extent.second; + } + if (total_bytes == 0) { + aio_comp->set_request_count(0); + return true; + } + return false; +} + template void AbstractImageWriteRequest::send_request() { I &image_ctx = this->m_image_ctx; @@ -420,10 +444,6 @@ void AbstractImageWriteRequest::send_request() { // prevent image size from changing between computing clip and recording // pending async operation std::shared_lock image_locker{image_ctx.image_lock}; - if (image_ctx.snap_id != CEPH_NOSNAP || image_ctx.read_only) { - aio_comp->fail(-EROFS); - return; - } snapc = image_ctx.snapc; journaling = (image_ctx.journal != nullptr && diff --git a/src/librbd/io/ImageRequest.h b/src/librbd/io/ImageRequest.h index f62a679620950..e5a04597d3e7d 100644 --- a/src/librbd/io/ImageRequest.h +++ b/src/librbd/io/ImageRequest.h @@ -83,7 +83,9 @@ protected: m_trace.event("start"); } - + virtual bool finish_request_early() { + return false; + } virtual int clip_request(); virtual void update_timestamp(); virtual void send_request() = 0; @@ -138,6 +140,7 @@ protected: } void send_request() override; + bool finish_request_early() override; virtual int prune_object_extents( LightweightObjectExtents* object_extents) const { diff --git a/src/test/librbd/io/test_mock_ImageRequest.cc b/src/test/librbd/io/test_mock_ImageRequest.cc index c63e2c99540ff..2dab0ebe4b64c 100644 --- a/src/test/librbd/io/test_mock_ImageRequest.cc +++ b/src/test/librbd/io/test_mock_ImageRequest.cc @@ -173,6 +173,38 @@ TEST_F(TestMockIoImageRequest, AioWriteModifyTimestamp) { ASSERT_EQ(0, aio_comp_ctx_2.wait()); } +TEST_F(TestMockIoImageRequest, AioWriteEarlyFinish) { + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + + MockTestImageCtx mock_image_ctx(*ictx); + + C_SaferCond aio_comp_ctx_1, aio_comp_ctx_2; + AioCompletion *aio_comp_1 = AioCompletion::create_and_start( + &aio_comp_ctx_1, ictx, AIO_TYPE_WRITE); + AioCompletion *aio_comp_2 = AioCompletion::create_and_start( + &aio_comp_ctx_2, ictx, AIO_TYPE_WRITE); + + bufferlist bl; + MockImageWriteRequest mock_aio_image_write_1(mock_image_ctx, aio_comp_1, + {{0, 0}}, std::move(bl), 0, {}); + { + std::shared_lock owner_locker{mock_image_ctx.owner_lock}; + mock_aio_image_write_1.send(); + } + ASSERT_EQ(0, aio_comp_ctx_1.wait()); + + mock_image_ctx.snap_id = 123; + bl.append("1"); + MockImageWriteRequest mock_aio_image_write_2(mock_image_ctx, aio_comp_2, + {{0, 1}}, std::move(bl), 0, {}); + { + std::shared_lock owner_locker{mock_image_ctx.owner_lock}; + mock_aio_image_write_2.send(); + } + ASSERT_EQ(-EROFS, aio_comp_ctx_2.wait()); +} + TEST_F(TestMockIoImageRequest, AioReadAccessTimestamp) { REQUIRE_FORMAT_V2(); -- 2.39.5