]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore: consider segment_header_t::modify_time as the 58787/head
authorXuehan Xu <xuxuehan@qianxin.com>
Wed, 24 Jul 2024 13:17:43 +0000 (21:17 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Mon, 5 Aug 2024 06:16:12 +0000 (14:16 +0800)
segments' modify_time for no-tail OOL segments

OOL segments don't contain record headers anymore, we use
segment_header_t::modify_time as the approximation of segment
modify_time

Fixes: https://tracker.ceph.com/issues/67106
Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
src/crimson/os/seastore/async_cleaner.cc
src/crimson/os/seastore/async_cleaner.h
src/crimson/os/seastore/journal/segment_allocator.cc
src/crimson/os/seastore/seastore_types.cc
src/crimson/os/seastore/seastore_types.h

index 7e13befde0d7808a848b71ffa05b55d656cf8e84..5046980eae56ceb7f6c94154fdd2139eb5b9999d 100644 (file)
@@ -1372,20 +1372,33 @@ SegmentCleaner::mount_ret SegmentCleaner::mount()
         segment_id
       ).safe_then([this, FNAME, segment_id, header](auto tail)
         -> scan_extents_ertr::future<> {
-        if (tail.segment_nonce != header.segment_nonce) {
+       bool tail_valid = (tail.segment_nonce == header.segment_nonce);
+        if (!tail_valid && header.type == segment_type_t::JOURNAL) {
           return scan_no_tail_segment(header, segment_id);
         }
-        ceph_assert(header.get_type() == tail.get_type());
-
-        sea_time_point modify_time = mod_to_timepoint(tail.modify_time);
-        std::size_t num_extents = tail.num_extents;
-        if ((modify_time == NULL_TIME && num_extents == 0) ||
-            (modify_time != NULL_TIME && num_extents != 0)) {
-          segments.update_modify_time(segment_id, modify_time, num_extents);
-        } else {
-          ERROR("illegal modify time {}", tail);
-          return crimson::ct_error::input_output_error::make();
-        }
+        ceph_assert(header.get_type() == tail.get_type() || !tail_valid);
+
+       sea_time_point header_time = mod_to_timepoint(header.modify_time);
+       if (tail_valid) {
+         sea_time_point tail_time = mod_to_timepoint(tail.modify_time);
+         std::size_t num_extents = tail.num_extents;
+         DEBUG("updating modify time for segment {}, "
+               "mod time {}-{}, num_extents {}",
+               segment_id, header_time, tail_time, num_extents);
+         if (num_extents == 0) {
+           ceph_assert(tail_time == NULL_TIME);
+         } else {
+           ceph_assert(header_time != NULL_TIME);
+           ceph_assert(tail_time != NULL_TIME);
+           sea_time_point avg_time = get_average_time(
+             header_time, 1, tail_time, 1);
+           segments.update_modify_time(segment_id, avg_time, num_extents);
+         }
+       } else {
+         DEBUG("updating modify time for segment {}, mod time {}, without tail",
+               segment_id, header_time);
+         segments.init_modify_time(segment_id, header_time);
+       }
 
         init_mark_segment_closed(
           segment_id,
@@ -1396,8 +1409,22 @@ SegmentCleaner::mount_ret SegmentCleaner::mount()
         return seastar::now();
       }).handle_error(
         crimson::ct_error::enodata::handle(
-          [this, header, segment_id](auto) {
-          return scan_no_tail_segment(header, segment_id);
+          [this, header, segment_id, FNAME](auto) {
+         if (header.type == segment_type_t::JOURNAL) {
+           return scan_no_tail_segment(header, segment_id);
+         } else {
+           sea_time_point modify_time = mod_to_timepoint(header.modify_time);
+           DEBUG("updating modify time for segment {}, mod time {}",
+             segment_id, modify_time);
+           segments.init_modify_time(segment_id, modify_time);
+           init_mark_segment_closed(
+             segment_id,
+             header.segment_seq,
+             header.type,
+             header.category,
+             header.generation);
+           return scan_extents_ertr::now();
+         }
         }),
         crimson::ct_error::pass_further_all{}
       );
index adf9fb177ad8f936abf66b93a3d347ba9a6d8ec5..485497b9a9cce80b1b7ecbb910055933015263b3 100644 (file)
@@ -43,6 +43,7 @@ struct segment_info_t {
 
   sea_time_point modify_time = NULL_TIME;
 
+  // Might be unavailable(0), see mount() -> init_modify_time()
   std::size_t num_extents = 0;
 
   segment_off_t written_to = 0;
@@ -75,6 +76,13 @@ struct segment_info_t {
 
   void set_closed();
 
+  void init_modify_time(sea_time_point _modify_time) {
+    ceph_assert(modify_time == NULL_TIME);
+    ceph_assert(num_extents == 0);
+    ceph_assert(_modify_time != NULL_TIME);
+    modify_time = _modify_time;
+  }
+
   void update_modify_time(sea_time_point _modify_time, std::size_t _num_extents) {
     ceph_assert(!is_closed());
     assert(_modify_time != NULL_TIME);
@@ -226,6 +234,15 @@ public:
 
   void update_written_to(segment_type_t, paddr_t);
 
+  void init_modify_time(
+      segment_id_t id, sea_time_point tp) {
+    if (tp == NULL_TIME) {
+      return;
+    }
+
+    segments[id].init_modify_time(tp);
+  }
+
   void update_modify_time(
       segment_id_t id, sea_time_point tp, std::size_t num) {
     if (num == 0) {
index 61e1be585c8eec4d62d46d8593c2ccf6ff110acd..7760c869b49f0aa6cd2f9dc14a64bbad544f661e 100644 (file)
@@ -93,6 +93,7 @@ SegmentAllocator::do_open(bool is_mkfs)
       alloc_tail = JOURNAL_SEQ_NULL;
     }
     auto header = segment_header_t{
+      timepoint_to_mod(seastar::lowres_system_clock::now()),
       new_segment_seq,
       segment_id,
       dirty_tail,
index 25d787f0fd3e9a76710d231b9286addfe57045fe..5481a680f27e3bff74414b6b62d244576fea66fc 100644 (file)
@@ -371,6 +371,7 @@ std::ostream &operator<<(std::ostream &out, const segment_header_t &header)
              << ", dirty_tail=" << header.dirty_tail
              << ", alloc_tail=" << header.alloc_tail
              << ", segment_nonce=" << header.segment_nonce
+            << ", modify_time=" << mod_time_point_printer_t{header.modify_time}
              << ")";
 }
 
index dc2f478136ea3853acf66c10eb8e4aaaeb84e585..35c331d50963ef987514fbfaac72ec32a7fa5c0a 100644 (file)
@@ -1799,6 +1799,8 @@ using segment_nonce_t = uint32_t;
  * 4) Replay from the latest tails
  */
 struct segment_header_t {
+  mod_time_point_t modify_time;
+
   segment_seq_t segment_seq;
   segment_id_t physical_segment_id; // debugging
 
@@ -1817,6 +1819,7 @@ struct segment_header_t {
 
   DENC(segment_header_t, v, p) {
     DENC_START(1, 1, p);
+    denc(v.modify_time, p);
     denc(v.segment_seq, p);
     denc(v.physical_segment_id, p);
     denc(v.dirty_tail, p);