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,
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{}
);
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;
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);
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) {