]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: Make write_v2 not need to use compress_extents, addendum
authorAdam Kupczyk <akupczyk@ibm.com>
Mon, 10 Mar 2025 08:48:01 +0000 (08:48 +0000)
committerAdam Kupczyk <akupczyk@ibm.com>
Thu, 13 Mar 2025 06:52:03 +0000 (06:52 +0000)
There was possible case that affected rightmost changed extent.
It could be that 2 mergeable extents were next to each other.
This change melds them together.

Signed-off-by: Adam Kupczyk <akupczyk@ibm.com>
src/os/bluestore/Writer.cc
src/os/bluestore/Writer.h

index 41f2845e85ef0ec501b4e4503689853e09d8f39c..73a9efcd7ca13cf34abbd409cd94a02eb4d152b1 100644 (file)
@@ -588,6 +588,26 @@ inline void BlueStore::Writer::_place_extent_in_blob(
   }
 }
 
+// Iterator it can be invalidated.
+void BlueStore::Writer::_maybe_meld_with_prev_extent(exmp_it it)
+{
+  if (it == onode->extent_map.extent_map.end())   return; // can't merge with non-existent
+  if (it == onode->extent_map.extent_map.begin()) return; // can't merge when there is only 1 extent
+  if (it->logical_end() >= right_shard_bound)     return; // not allowed to escape shard range
+  auto it_p = it;
+  --it_p;
+  if (it_p->logical_offset < left_shard_bound) return; // we could jump here behind our inserted range
+  if (it_p->blob == it->blob &&
+      it_p->logical_end() == it->logical_offset &&
+      it_p->blob_offset + it_p->length == it->blob_offset) // this one is specifc, currently is always true
+  {
+    it_p->length += it->length;
+    onode->extent_map.rm(it);
+    left_affected_range = std::min(left_affected_range, it_p->logical_offset);
+    right_affected_range = std::max(right_affected_range, it_p->logical_end());
+  }
+}
+
 /**
  * Note from developer
  * This module tries to keep naming convention:
@@ -1408,8 +1428,13 @@ void BlueStore::Writer::do_write(
   _collect_released_allocated();
   // update statfs
   txc->statfs_delta += statfs_delta;
-  // note: compress extent is not needed; _try_reuse_allocated_* joins extents if possible
-  // in other cases new blobs cannot be joined with existing ones
+  // Note: compress extent is mostly not needed; _try_reuse_allocated_* joins extents if possible;
+  // same is done after _blob_put_data_subau_allocate (allocate more to existing blob).
+  // New blobs cannot be joined with existing ones.
+  // The only case that adjecent extents can be meld together is on the boundary.
+  // More specific, since we are operating left side first, right side later
+  // the only non-joined extent is between after_punch_it - 1 and after_punch_it.
+  _maybe_meld_with_prev_extent(after_punch_it);
   dout(25) << "result: " << std::endl << onode->print(pp_mode) << dendl;
 }
 
index 39f7c477b15b2edf65c141bae22ea0600d81cc29..3962aa02dc94cc5cb9b73ab9bd36454a2393010a 100644 (file)
@@ -152,6 +152,8 @@ private:
     uint32_t map_end,
     uint32_t in_blob_offset);
 
+  void _maybe_meld_with_prev_extent(exmp_it after_punch_it);
+
   inline void _blob_put_data_subau(
     Blob* blob,
     uint32_t in_blob_offset,