From: Jianpeng Ma Date: Tue, 7 Sep 2021 02:00:53 +0000 (+0800) Subject: librbd/cache/pwl/ssd: Fix a race between get_cache_bl() and remove_cache_bl() X-Git-Tag: v16.2.7~50^2~10 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=457c84b3c169d6ac869b1b42633ad20fdd59f73b;p=ceph.git librbd/cache/pwl/ssd: Fix a race between get_cache_bl() and remove_cache_bl() In fact, although in get_cache_bl it use lock to protect, it can't protect function "list& operator= (const list& other)". So we should use copy_cache_bl. Fixes: https://tracker.ceph.com/issues/52400 Signed-off-by: Jianpeng Ma (cherry picked from commit fe72b3953735329441397f257d5dd18f6819187d) --- diff --git a/src/librbd/cache/pwl/LogEntry.h b/src/librbd/cache/pwl/LogEntry.h index b0d27b5aefa..766b5500767 100644 --- a/src/librbd/cache/pwl/LogEntry.h +++ b/src/librbd/cache/pwl/LogEntry.h @@ -219,7 +219,6 @@ public: BlockExtent block_extent(); virtual unsigned int reader_count() const = 0; /* Constructs a new bl containing copies of cache_bp */ - void copy_cache_bl(bufferlist *out_bl) override {}; bool can_retire() const override { return (this->completed && this->get_flushed() && (0 == reader_count())); } diff --git a/src/librbd/cache/pwl/ssd/LogEntry.cc b/src/librbd/cache/pwl/ssd/LogEntry.cc index 71f77f55031..0e6edd87b35 100644 --- a/src/librbd/cache/pwl/ssd/LogEntry.cc +++ b/src/librbd/cache/pwl/ssd/LogEntry.cc @@ -24,6 +24,11 @@ buffer::list& WriteLogEntry::get_cache_bl() { return cache_bl; } +void WriteLogEntry::copy_cache_bl(bufferlist *out) { + std::lock_guard locker(m_entry_bl_lock); + *out = cache_bl; +} + void WriteLogEntry::remove_cache_bl() { std::lock_guard locker(m_entry_bl_lock); cache_bl.clear(); diff --git a/src/librbd/cache/pwl/ssd/LogEntry.h b/src/librbd/cache/pwl/ssd/LogEntry.h index 86121473b82..8e26f661ff8 100644 --- a/src/librbd/cache/pwl/ssd/LogEntry.h +++ b/src/librbd/cache/pwl/ssd/LogEntry.h @@ -38,6 +38,7 @@ public: Context *ctx, ceph::bufferlist &&bl) override; void init_cache_bl(bufferlist &src_bl, uint64_t off, uint64_t len) override; buffer::list &get_cache_bl() override; + void copy_cache_bl(bufferlist *out) override; void remove_cache_bl() override; unsigned int get_aligned_data_size() const override; void inc_bl_refs() { bl_refs++; }; diff --git a/src/librbd/cache/pwl/ssd/WriteLog.cc b/src/librbd/cache/pwl/ssd/WriteLog.cc index 7e7fc42e865..e0d9a13199a 100644 --- a/src/librbd/cache/pwl/ssd/WriteLog.cc +++ b/src/librbd/cache/pwl/ssd/WriteLog.cc @@ -85,7 +85,7 @@ void WriteLog::collect_read_extents( ldout(m_image_ctx.cct, 5) << dendl; auto write_entry = static_pointer_cast(map_entry.log_entry); buffer::list hit_bl; - hit_bl = write_entry->get_cache_bl(); + write_entry->copy_cache_bl(&hit_bl); bool writesame = write_entry->is_writesame_entry(); auto hit_extent_buf = std::make_shared( hit_extent, hit_bl, true, read_buffer_offset, writesame);