From: Adam Kupczyk Date: Wed, 10 May 2023 09:30:23 +0000 (+0000) Subject: os/bluestore: Add discard_unused_buffers function X-Git-Tag: v19.0.0~486^2~17 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=eb854a7148d9183e8b35a3b8f186c8a49ae6ae84;p=ceph.git os/bluestore: Add discard_unused_buffers function When we punch_hole in blobs we leave Buffers unchanged. Normally it is not a problem, but when we merge blobs there is a collision. Signed-off-by: Adam Kupczyk --- diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index e179c5982337..9705df8985ea 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -2423,6 +2423,37 @@ bool BlueStore::Blob::can_reuse_blob(uint32_t min_alloc_size, return true; } +#undef dout_prefix +#define dout_prefix *_dout << "bluestore.blob(" << this << ") " +#undef dout_context +#define dout_context cct + +// Cut Buffers that are not covered by extents. +// It happens when we punch hole in Blob, but not refill with new data. +// Normally it is not a problem (other then wasted memory), +// but when 2 Blobs are merged Buffers might collide. +// Todo: in future cut Buffers when we delete extents from Blobs, +// and get rid of this function. +void BlueStore::Blob::discard_unused_buffers(CephContext* cct, BufferCacheShard* cache) +{ + dout(25) << __func__ << " input " << *this << " bc=" << bc << dendl; + const PExtentVector& extents = get_blob().get_extents(); + uint32_t epos = 0; + auto e = extents.begin(); + while(e != extents.end()) { + if (!e->is_valid()) { + bc._discard(cache, epos, e->length); + } + epos += e->length; + ++e; + } + ceph_assert(epos <= blob.get_logical_length()); + // Preferably, we would trim up to blob.get_logical_length(), + // but we copied writing buffers (see _dup_writing) before blob logical_length is fixed. + bc._discard(cache, epos, OBJECT_MAX_SIZE - epos); + dout(25) << __func__ << " output bc=" << bc << dendl; +} + void BlueStore::Blob::dup(const Blob& from, bool copy_used_in_blob) { set_shared_blob(from.shared_blob); diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index 53170d0e07c6..c121a426f124 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -401,7 +401,8 @@ public: void _rm_buffer(BufferCacheShard* cache, Buffer *b) { _rm_buffer(cache, buffer_map.find(b->offset)); } - void _rm_buffer(BufferCacheShard* cache, + std::map>::iterator + _rm_buffer(BufferCacheShard* cache, std::map>::iterator p) { ceph_assert(p != buffer_map.end()); cache->_audit("_rm_buffer start"); @@ -410,8 +411,9 @@ public: } else { cache->_rm(p->second.get()); } - buffer_map.erase(p); + p = buffer_map.erase(p); cache->_audit("_rm_buffer end"); + return p; } std::map>::iterator _data_lower_bound( @@ -684,6 +686,8 @@ public: #endif return blob; } + /// clear buffers from unused sections + void discard_unused_buffers(CephContext* cct, BufferCacheShard* cache); inline const BufferSpace& get_bc() const { return bc;