]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: Cleanup around bluestore_blob_t::get_ondisk_length()
authorAdam Kupczyk <akupczyk@ibm.com>
Thu, 7 May 2026 10:38:07 +0000 (10:38 +0000)
committerAdam Kupczyk <akupczyk@ibm.com>
Fri, 8 May 2026 13:51:54 +0000 (13:51 +0000)
Split get_ondisk_length() into
- get_ondisk_capacity()
- get_ondisk_length()
The change is done to amplify the difference between disk space used,
and potential capacity for disk space use.

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

index b5619a49ffc9f36f57c4d0234509be751a8a7787..6c47ce2b5587644fb2ac6763e46fcfe38740e729 100644 (file)
@@ -1002,7 +1002,7 @@ void BlueStore::GarbageCollector::process_protrusive_extents(
     Blob* b = b_it->first;
     BlobInfo& bi = b_it->second;
     if (bi.referenced_bytes == 0) {
-      uint64_t len_on_disk = b_it->first->get_blob().get_ondisk_length();
+      uint64_t len_on_disk = b_it->first->get_blob().get_ondisk_capacity();
       int64_t blob_expected_for_release =
         round_up_to(len_on_disk, min_alloc_size) / min_alloc_size;
 
@@ -2940,7 +2940,7 @@ void BlueStore::Blob::split(Collection *coll, uint32_t blob_offset, Blob *r)
 void BlueStore::Blob::maybe_prune_tail() {
   if (get_blob().can_prune_tail()) {
     dirty_blob().prune_tail();
-    used_in_blob.prune_tail(get_blob().get_ondisk_length());
+    used_in_blob.prune_tail(get_blob().get_ondisk_capacity());
     dout(20) << __func__ << " pruned tail, now " << get_blob() << dendl;
   }
 }
@@ -5102,7 +5102,7 @@ int BlueStore::Onode::get_fragmentation_score()
     if (e.blob->get_blob().is_compressed()) {
       if (visited_compressed_blobs.insert(e.blob).second) {
         e.blob->get_blob().map(
-          0, e.blob->get_blob().get_ondisk_length(),
+          0, e.blob->get_blob().get_ondisk_size(),
           [&](uint64_t offset, uint64_t length) {
             frag.note(offset, length);
             return 0;
@@ -12906,7 +12906,7 @@ int BlueStore::_prepare_read_ioc(
       compressed_blob_bls->push_back(bufferlist());
       bufferlist& bl = compressed_blob_bls->back();
       auto r = bptr->get_blob().map(
-        0, bptr->get_blob().get_ondisk_length(),
+        0, bptr->get_blob().get_ondisk_size(),
         [&](uint64_t offset, uint64_t length) {
           int r = bdev->aio_read(offset, length, &bl, ioc);
           if (r < 0)
@@ -16622,7 +16622,7 @@ void BlueStore::_do_write_small(
 
         // direct write into unused blocks of an existing mutable blob?
         if ((b_off % chunk_size == 0 && b_len % chunk_size == 0) &&
-            b->get_blob().get_ondisk_length() >= b_off + b_len &&
+            b->get_blob().get_ondisk_capacity() >= b_off + b_len &&
             b->get_blob().is_unused(b_off, b_len) &&
             b->get_blob().is_allocated(b_off, b_len)) {
           _buffer_cache_write(txc, o, offset, bl,
@@ -16671,7 +16671,7 @@ void BlueStore::_do_write_small(
        uint64_t head_read = p2phase(b_off, chunk_size);
        uint64_t tail_read = p2nphase(b_off + b_len, chunk_size);
        if ((head_read || tail_read) &&
-           (b->get_blob().get_ondisk_length() >= b_off + b_len + tail_read) &&
+           (b->get_blob().get_ondisk_capacity() >= b_off + b_len + tail_read) &&
            head_read + tail_read < min_alloc_size) {
          b_off -= head_read;
          b_len += head_read + tail_read;
@@ -16681,7 +16681,7 @@ void BlueStore::_do_write_small(
        }
 
        // chunk-aligned deferred overwrite?
-       if (b->get_blob().get_ondisk_length() >= b_off + b_len &&
+       if (b->get_blob().get_ondisk_capacity() >= b_off + b_len &&
            b_off % chunk_size == 0 &&
            b_len % chunk_size == 0 &&
            b->get_blob().is_allocated(b_off, b_len)) {
@@ -16924,7 +16924,7 @@ bool BlueStore::BigDeferredWriteContext::can_defer(
     off = offset;
     b_off = offset - ep->blob_start();
     uint64_t chunk_size = blob.get_chunk_size(block_size);
-    uint64_t ondisk = blob.get_ondisk_length();
+    uint64_t ondisk = blob.get_ondisk_capacity();
     used = std::min(l, ondisk - b_off);
 
     // will read some data to fill out the chunk?
@@ -18256,7 +18256,7 @@ int BlueStore::_do_remove(
        sb->loaded &&
        maybe_unshared_blobs.count(sb)) {
       if (b.is_compressed()) {
-       expect[sb].get(0, b.get_ondisk_length());
+       expect[sb].get(0, b.get_ondisk_size());
       } else {
        // todo: it seems to be an overkill to go through map()
        b.map(e.blob_offset, e.length, [&](uint64_t off, uint64_t len) {
index 8fbf54384700a62274640bed32012687ed71b95b..8acac0f644638147b97483c8d5b023e989aeda09 100644 (file)
@@ -536,7 +536,7 @@ void Scan::candidate(const Extent* e)
       bit->second.consumed_size += e->length;
       if (bit->second.consumed_size == bit->second.blob_use_size) {
         // Seen all extents of the blob, can take gain.
-        gain = h_bblob.get_ondisk_length();
+        gain = h_bblob.get_ondisk_size();
       }
       estimator->batch(e, gain);
     } else {
index fecca7dee36064fec1fe7cc00c7384318cf64a31..ae86d083ba0a9db1b8d1f792cef56c783846129a 100644 (file)
@@ -1161,7 +1161,9 @@ uint32_t bluestore_blob_t::release_extents(
   uint32_t released_length = 0;
   constexpr auto EMPTY = bluestore_pextent_t::INVALID_OFFSET;
   if (offset == 0 && length == get_logical_length()) {
-    released_length = get_ondisk_length();
+    // There are 2 distinct cases for releasing whole blob:
+    // a) releasing compressed blob b) speedup for releasing whole regular blob
+    released_length = get_ondisk_capacity();
     released_disk->insert(released_disk->end(), extents.begin(), extents.end());
     extents.resize(1);
     extents[0].offset = EMPTY;
index d7259bac500a7e392b11d48d84fc3f1c36fa33c0..dcd4aa07034290d629d302c4c09c2d91ea7e18a8 100644 (file)
@@ -570,7 +570,7 @@ public:
       denc_varint_lowz(logical_length, p);
       denc_varint_lowz(compressed_length, p);
     } else {
-      logical_length = get_ondisk_length();
+      logical_length = get_ondisk_capacity();
     }
     if (has_csum()) {
       denc(csum_type, p);
@@ -899,7 +899,10 @@ public:
     }
   }
 
-  uint32_t get_ondisk_length() const {
+  /// Count blob's capacity for data
+  /// It returns how much data blob can hold without resizing.
+  /// Compressed blobs cannot be modified, so actual disk usage is returned.
+  uint32_t get_ondisk_capacity() const {
     uint32_t len = 0;
     for (auto &p : extents) {
       len += p.length;
@@ -907,6 +910,19 @@ public:
     return len;
   }
 
+  /// Count blob's usage of disk
+  /// For compressed blobs get_ondisk_capacity == get_ondisk_size.
+  /// It is similar to get_ondisk_capacity() except unmapped extents do not count.
+  uint32_t get_ondisk_size() const {
+    uint32_t len = 0;
+    for (auto &p : extents) {
+      if (p.is_valid()) {
+        len += p.length;
+      }
+    }
+    return len;
+  }
+
   uint32_t get_logical_length() const {
     return logical_length;
   }