]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore: write only modified region when rewriting the extent in an inpla...
authorMyoungwon Oh <myoungwon.oh@samsung.com>
Sun, 10 Dec 2023 03:34:03 +0000 (12:34 +0900)
committerMyoungwon Oh <myoungwon.oh@samsung.com>
Fri, 5 Jan 2024 06:44:18 +0000 (15:44 +0900)
Signed-off-by: Myoungwon Oh <myoungwon.oh@samsung.com>
src/crimson/os/seastore/cached_extent.h
src/crimson/os/seastore/extent_placement_manager.cc
src/crimson/os/seastore/object_data_handler.h
src/test/crimson/seastore/test_block.h

index 18c102ed3e17398a8712de2ac50f4250db058039..a72011db27521e23ad6d02cfafebd132d3bdd8f3 100644 (file)
@@ -1244,6 +1244,14 @@ public:
 
   virtual void clear_delta() {}
 
+  struct modified_region_t {
+    extent_len_t offset;
+    extent_len_t len;
+  };
+  virtual std::optional<modified_region_t> get_modified_region() {
+    return std::nullopt;
+  }
+
   virtual ~LogicalCachedExtent();
 protected:
 
index f53b9f5be9163c301da30732c7aa9c7ba7857fbf..45f51a401e0810c8daacd65c53e91c9e1476a2e9 100644 (file)
@@ -790,19 +790,33 @@ RandomBlockOolWriter::do_write(
     stats.num_records += 1;
 
     ex->prepare_write();
-    return rbm->write(paddr,
-      ex->get_bptr()
+    extent_len_t offset = 0;
+    bufferptr bp;
+    if (can_inplace_rewrite(t, ex)) {
+      auto r = ex->get_modified_region();
+      if (r.has_value() && r->len > rbm->get_block_size()) {
+       offset = p2align(r->offset, rbm->get_block_size());
+       extent_len_t len =
+         p2roundup(r->offset + r->len, rbm->get_block_size()) - offset;
+       bp = ceph::bufferptr(ex->get_bptr(), offset, len);
+      } else {
+       bp = ex->get_bptr();
+      }
+    } else {
+      bp = ex->get_bptr();
+    }
+    return rbm->write(paddr + offset,
+      bp
     ).handle_error(
       alloc_write_iertr::pass_further{},
       crimson::ct_error::assert_all{
        "Invalid error when writing record"}
-    ).safe_then([&t, &ex, paddr, FNAME]() {
+    ).safe_then([&t, &ex, paddr, this, FNAME]() {
       TRACET("ool extent written at {} -- {}",
             t, paddr, *ex);
       if (ex->is_initial_pending()) {
        t.mark_allocated_extent_ool(ex);
-      } else if (ex->is_dirty()) {
-       assert(t.get_src() == transaction_type_t::TRIM_DIRTY);
+      } else if (can_inplace_rewrite(t, ex)) {
        t.mark_inplace_rewrite_extent_ool(ex);
       } else {
        ceph_assert("impossible");
index 76d69eb73f9b1169b1f57e2ef553bf5703ccf828..2b01089214c271786ec2357d5e24d66df459db9e 100644 (file)
@@ -64,6 +64,20 @@ struct ObjectDataBlock : crimson::os::seastore::LogicalCachedExtent {
   void clear_delta() final {
     delta.clear();
   }
+
+  std::optional<modified_region_t> get_modified_region() final {
+    interval_set<extent_len_t> range;
+    for (auto &p : delta) {
+      if (p.len > 0) {
+       range.union_insert(p.offset, p.len);
+      }
+    }
+    if (range.empty()) {
+      return std::nullopt;
+    }
+    return modified_region_t{range.range_start(),
+      range.range_end() - range.range_start()};
+  }
 };
 using ObjectDataBlockRef = TCachedExtentRef<ObjectDataBlock>;
 
index bfb50670420cb54054336b8c78bb59e0948ce8ad..8ddb3880b4f59d82e9d8d2e12f2ef0f8b97e64da 100644 (file)
@@ -83,6 +83,20 @@ struct TestBlock : crimson::os::seastore::LogicalCachedExtent {
   void clear_delta() final {
     delta.clear();
   }
+
+  std::optional<modified_region_t> get_modified_region() final {
+    interval_set<extent_len_t> range;
+    for (auto &p : delta) {
+      if (p.len > 0) {
+       range.union_insert(p.offset, p.len);
+      }
+    }
+    if (range.empty()) {
+      return std::nullopt;
+    }
+    return modified_region_t{range.range_start(),
+      range.range_end() - range.range_start()};
+  }
 };
 using TestBlockRef = TCachedExtentRef<TestBlock>;