]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: Make truncate() drop unused allocations
authorAdam Kupczyk <akupczyk@ibm.com>
Tue, 22 Oct 2024 18:53:22 +0000 (18:53 +0000)
committerAdam Kupczyk <akupczyk@ibm.com>
Fri, 17 Jan 2025 08:38:32 +0000 (08:38 +0000)
Review fixes. Removed overcatious assert.
Improved if .. else style.
Skipped processing extent truncation when seek() goes to end.

Fixes: https://tracker.ceph.com/issues/68385 (addendum)
Signed-off-by: Adam Kupczyk <akupczyk@ibm.com>
(cherry picked from commit 85fac18a1cb0491e270261c71a506c4c1ba5e0bf)

src/os/bluestore/BlueFS.cc

index cb81a99308b04a95d13a7762e0e6aeaabdeff659..d10d248145f37302b0c46c21324fe156a983bd47 100644 (file)
@@ -3686,7 +3686,7 @@ int BlueFS::truncate(FileWriter *h, uint64_t offset)/*_WF_L*/
   if (offset > fnode.size) {
     ceph_abort_msg("truncate up not supported");
   }
-  ceph_assert(offset <= fnode.size);
+
   _flush_bdev(h);
   {
     std::lock_guard ll(log.lock);
@@ -3695,43 +3695,41 @@ int BlueFS::truncate(FileWriter *h, uint64_t offset)/*_WF_L*/
     vselector->sub_usage(h->file->vselector_hint, fnode);
     uint64_t x_off = 0;
     auto p = fnode.seek(offset, &x_off);
-    uint64_t cut_off =
-      (p == fnode.extents.end()) ? 0 : p2roundup(x_off, alloc_size[p->bdev]);
-    uint64_t new_allocated;
-    if (0 == cut_off) {
-      // whole pextent to remove
-      changed_extents = true;
-      new_allocated = offset;
-    } else if (cut_off < p->length) {
-      dirty.pending_release[p->bdev].insert(p->offset + cut_off, p->length - cut_off);
-      new_allocated = (offset - x_off) + cut_off;
-      p->length = cut_off;
-      changed_extents = true;
-      ++p;
-    } else {
-      ceph_assert(cut_off >= p->length);
-      new_allocated  = (offset - x_off) + p->length;
-      // just leave it here
-      ++p;
-    }
-    while (p != fnode.extents.end()) {
-      dirty.pending_release[p->bdev].insert(p->offset, p->length);
-      p = fnode.extents.erase(p);
-      changed_extents = true;
+    if (p != fnode.extents.end()) {
+      uint64_t cut_off = p2roundup(x_off, alloc_size[p->bdev]);
+      if (0 == cut_off) {
+        // whole pextent to remove
+        fnode.allocated = offset;
+        changed_extents = true;
+      } else if (cut_off < p->length) {
+        dirty.pending_release[p->bdev].insert(p->offset + cut_off,
+                                              p->length - cut_off);
+        fnode.allocated = (offset - x_off) + cut_off;
+        p->length = cut_off;
+        changed_extents = true;
+        ++p;
+      } else {
+        // cut_off > p->length means that we misaligned the extent
+        ceph_assert(cut_off == p->length);
+        fnode.allocated = (offset - x_off) + p->length;
+        ++p; // leave extent untouched
+      }
+      while (p != fnode.extents.end()) {
+        dirty.pending_release[p->bdev].insert(p->offset, p->length);
+        p = fnode.extents.erase(p);
+        changed_extents = true;
+      }
     }
     if (changed_extents) {
       fnode.size = offset;
-      fnode.allocated = new_allocated;
       fnode.reset_delta();
       log.t.op_file_update(fnode);
       // sad, but is_dirty must be set to signal flushing of the log
       h->file->is_dirty = true;
-    } else {
-      if (offset != fnode.size) {
-        fnode.size = offset;
-        //skipping log.t.op_file_update_inc, it will be done by flush()
-        h->file->is_dirty = true;
-      }
+    } else if (offset != fnode.size) {
+      fnode.size = offset;
+      // skipping log.t.op_file_update_inc, it will be done by flush()
+      h->file->is_dirty = true;
     }
     vselector->add_usage(h->file->vselector_hint, fnode);
   }