]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: Add discard_unused_buffers function
authorAdam Kupczyk <akupczyk@ibm.com>
Wed, 10 May 2023 09:30:23 +0000 (09:30 +0000)
committerAdam Kupczyk <akupczyk@ibm.com>
Thu, 6 Jul 2023 15:28:50 +0000 (15:28 +0000)
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 <akupczyk@ibm.com>
src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h

index e179c5982337861e90936c47396e5ec123296e7c..9705df8985ea404baac852645b572bd3877ae822 100644 (file)
@@ -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);
index 53170d0e07c639dc30f2da69cfda06ab6daee7bc..c121a426f1241f219268346b9c47a3379feafa7d 100644 (file)
@@ -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<uint32_t, std::unique_ptr<Buffer>>::iterator
+    _rm_buffer(BufferCacheShard* cache,
                    std::map<uint32_t, std::unique_ptr<Buffer>>::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<uint32_t,std::unique_ptr<Buffer>>::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;