From: Radoslaw Zarzynski Date: Mon, 1 Dec 2025 14:35:48 +0000 (+0000) Subject: crimon/osd: implement PG::PGLogEntryHandler::partial_write() for FastEC X-Git-Tag: v21.0.0~3^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4924533853ec8913b60fb5ef75892a0c12c63403;p=ceph.git crimon/osd: implement PG::PGLogEntryHandler::partial_write() for FastEC Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/crimson/osd/pg.cc b/src/crimson/osd/pg.cc index e0170e3b19cc..e02e3dcfec82 100644 --- a/src/crimson/osd/pg.cc +++ b/src/crimson/osd/pg.cc @@ -1946,4 +1946,73 @@ void PG::send_message_osd_cluster(int osd, MOSDPGPush* msg, epoch_t from_epoch) } } +void PG::PGLogEntryHandler::partial_write(pg_info_t *info, + eversion_t previous_version, + const pg_log_entry_t &entry) +{ + assert(info != nullptr); + if (entry.written_shards.empty() && info->partial_writes_last_complete.empty()) { + return; + } + logger().debug("{}: version version={} written_shards={}" + "present_shards={} pwlc={} previous_version={}", + __func__, + entry.version, + entry.written_shards, + entry.present_shards, + info->partial_writes_last_complete, + previous_version); + const pg_pool_t &pool = pg->get_pool(); + for (shard_id_t shard : pool.nonprimary_shards) { + auto pwlc_iter = info->partial_writes_last_complete.find(shard); + if (!entry.is_written_shard(shard)) { + if (pwlc_iter == info->partial_writes_last_complete.end()) { + // 1st partial write since all logs were updated + info->partial_writes_last_complete[shard] = + std::pair(previous_version, entry.version); + + continue; + } + auto &&[old_v, new_v] = pwlc_iter->second; + if (old_v == new_v) { + if (old_v.version == eversion_t::max().version) { + // shard is backfilling or in async recovery, pwlc is + // invalid + logger().debug("{}: pwlc invalid {}", __func__, shard); + } else if (old_v.version >= entry.version.version) { + // Abnormal case - consider_adjusting_pwlc may advance pwlc + // during peering because all shards have updates but these + // have not been marked complete. At the end of peering + // partial_write catches up with these entries - these need + // to be ignored to preserve old_v.epoch + logger().debug("{}: pwlc is ahead of entry {}", __func__, shard); + } else { + old_v = previous_version; + new_v = entry.version; + } + } else if (new_v == previous_version) { + // Subsequent partial write, contiguous versions + new_v = entry.version; + } else { + // Subsequent partial write, discontiguous versions + logger().debug("{}: cannot update shard {}", __func__, shard); + } + } else if (pwlc_iter != info->partial_writes_last_complete.end()) { + auto &&[old_v, new_v] = pwlc_iter->second; + // Log updated or shard absent, partial write entry is a no-op + if (old_v.version == eversion_t::max().version) { + // shard is backfilling or in async recovery, pwlc is invalid + logger().debug("{}: pwlc invalid {}", __func__, shard); + } else if (old_v.version >= entry.version.version) { + // Abnormal case - see above + logger().debug("{}: pwlc is ahead of entry {}", __func__, shard); + } else { + old_v = new_v = entry.version; + } + } + } + logger().debug("{}: after pwlc={}", + __func__, info->partial_writes_last_complete); +} + } diff --git a/src/crimson/osd/pg.h b/src/crimson/osd/pg.h index 64e0d9f98caf..808491abf219 100644 --- a/src/crimson/osd/pg.h +++ b/src/crimson/osd/pg.h @@ -624,11 +624,7 @@ public: void partial_write(pg_info_t *info, eversion_t previous_version, const pg_log_entry_t &entry - ) override { - // TODO - ceph_assert(entry.written_shards.empty() && - info->partial_writes_last_complete.empty()); - } + ) override; }; PGLog::LogEntryHandlerRef get_log_handler( ceph::os::Transaction &t) final {