From 2a0514c7ab76aa85f1f9680f43bebce30acf834a Mon Sep 17 00:00:00 2001 From: Yuan Lu Date: Sun, 26 Apr 2020 15:56:10 +0800 Subject: [PATCH] librbd: add aio_discard Signed-off-by: Peterson, Scott Signed-off-by: Li, Xiaoyan Signed-off-by: Lu, Yuan Signed-off-by: Chamarthy, Mahati --- src/librbd/cache/ReplicatedWriteLog.cc | 82 ++++++++++++++++++-------- src/librbd/cache/ReplicatedWriteLog.h | 2 + 2 files changed, 61 insertions(+), 23 deletions(-) diff --git a/src/librbd/cache/ReplicatedWriteLog.cc b/src/librbd/cache/ReplicatedWriteLog.cc index 533ba7eacb6a6..ad2c0d881632d 100644 --- a/src/librbd/cache/ReplicatedWriteLog.cc +++ b/src/librbd/cache/ReplicatedWriteLog.cc @@ -625,27 +625,38 @@ void ReplicatedWriteLog::aio_read(Extents&& image_extents, uint64_t entry_hit_length = min(entry_image_extent.second - entry_offset, extent.second - extent_offset); Extent hit_extent(entry_image_extent.first, entry_hit_length); - - /* Offset of the map entry into the log entry's buffer */ - uint64_t map_entry_buffer_offset = entry_image_extent.first - map_entry.log_entry->ram_entry.image_offset_bytes; - /* Offset into the log entry buffer of this read hit */ - uint64_t read_buffer_offset = map_entry_buffer_offset + entry_offset; - /* Create buffer object referring to pmem pool for this read hit */ - auto write_entry = map_entry.log_entry; - - /* Make a bl for this hit extent. This will add references to the write_entry->pmem_bp */ - buffer::list hit_bl; - - buffer::list entry_bl_copy; - write_entry->copy_pmem_bl(&entry_bl_copy); - entry_bl_copy.begin(read_buffer_offset).copy(entry_hit_length, hit_bl); - - ceph_assert(hit_bl.length() == entry_hit_length); - - /* Add hit extent to read extents */ - ImageExtentBuf hit_extent_buf(hit_extent, hit_bl); - read_ctx->read_extents.push_back(hit_extent_buf); - + if (0 == map_entry.log_entry->write_bytes() && 0 < map_entry.log_entry->bytes_dirty()) { + /* discard log entry */ + auto discard_entry = map_entry.log_entry; + ldout(cct, 20) << "read hit on discard entry: log_entry=" << *discard_entry << dendl; + /* Discards read as zero, so we'll construct a bufferlist of zeros */ + bufferlist zero_bl; + zero_bl.append_zero(entry_hit_length); + /* Add hit extent to read extents */ + ImageExtentBuf hit_extent_buf(hit_extent, zero_bl); + read_ctx->read_extents.push_back(hit_extent_buf); + } else { + /* write and writesame log entry */ + /* Offset of the map entry into the log entry's buffer */ + uint64_t map_entry_buffer_offset = entry_image_extent.first - map_entry.log_entry->ram_entry.image_offset_bytes; + /* Offset into the log entry buffer of this read hit */ + uint64_t read_buffer_offset = map_entry_buffer_offset + entry_offset; + /* Create buffer object referring to pmem pool for this read hit */ + auto write_entry = map_entry.log_entry; + + /* Make a bl for this hit extent. This will add references to the write_entry->pmem_bp */ + buffer::list hit_bl; + + buffer::list entry_bl_copy; + write_entry->copy_pmem_bl(&entry_bl_copy); + entry_bl_copy.begin(read_buffer_offset).copy(entry_hit_length, hit_bl); + + ceph_assert(hit_bl.length() == entry_hit_length); + + /* Add hit extent to read extents */ + ImageExtentBuf hit_extent_buf(hit_extent, hit_bl); + read_ctx->read_extents.push_back(hit_extent_buf); + } /* Exclude RWL hit range from buffer and extent */ extent_offset += entry_hit_length; ldout(cct, 20) << map_entry << dendl; @@ -710,6 +721,29 @@ template void ReplicatedWriteLog::aio_discard(uint64_t offset, uint64_t length, uint32_t discard_granularity_bytes, Context *on_finish) { + CephContext *cct = m_image_ctx.cct; + + ldout(cct, 20) << dendl; + + utime_t now = ceph_clock_now(); + m_perfcounter->inc(l_librbd_rwl_discard, 1); + Extents discard_extents = {{offset, length}}; + + ceph_assert(m_initialized); + + auto *discard_req = + new C_DiscardRequestT(*this, now, std::move(discard_extents), discard_granularity_bytes, + m_lock, m_perfcounter, on_finish); + + /* The lambda below will be called when the block guard for all + * blocks affected by this write is obtained */ + GuardedRequestFunctionContext *guarded_ctx = + new GuardedRequestFunctionContext([this, discard_req](GuardedRequestFunctionContext &guard_ctx) { + discard_req->blockguard_acquired(guard_ctx); + alloc_and_dispatch_io_req(discard_req); + }); + + detain_guarded_request(discard_req, guarded_ctx, false); } /** @@ -1319,9 +1353,11 @@ void ReplicatedWriteLog::complete_op_log_entries(GenericLogOperations &&ops, utime_t now = ceph_clock_now(); auto log_entry = op->get_log_entry(); log_entry->completed = true; - if (op->reserved_allocated()) { + if (op->is_writing_op()) { op->mark_log_entry_completed(); dirty_entries.push_back(log_entry); + } + if (op->reserved_allocated()) { published_reserves++; } op->complete(result); @@ -1713,7 +1749,7 @@ bool ReplicatedWriteLog::can_flush_entry(std::shared_ptr log template Context* ReplicatedWriteLog::construct_flush_entry_ctx(std::shared_ptr log_entry) { - //TODO handle writesame, invalidate and discard in later PRs + //TODO handle invalidate in later PRs CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << "" << dendl; diff --git a/src/librbd/cache/ReplicatedWriteLog.h b/src/librbd/cache/ReplicatedWriteLog.h index 668289889dc4a..c3e8fcb60c33e 100644 --- a/src/librbd/cache/ReplicatedWriteLog.h +++ b/src/librbd/cache/ReplicatedWriteLog.h @@ -96,6 +96,8 @@ public: using C_WriteRequestT = rwl::C_WriteRequest; using C_BlockIORequestT = rwl::C_BlockIORequest; using C_FlushRequestT = rwl::C_FlushRequest; + using C_DiscardRequestT = rwl::C_DiscardRequest; + CephContext * get_context(); void release_guarded_request(BlockGuardCell *cell); void release_write_lanes(C_BlockIORequestT *req); -- 2.39.5