From 4332a188b72eea09c48d913d1b4576259a32a4a4 Mon Sep 17 00:00:00 2001 From: Alex Ainscow Date: Thu, 8 May 2025 14:22:36 +0100 Subject: [PATCH] osd: Recover non-primary shards with the correct version. Scrub revealed a bug whereby the non-primary shards were being given a version number in the OI which did not match the expected version in the authoritative OI. A secondary issue is that all attributes were being pushed to the non primary shards, whereas only OI is actually needed. Signed-off-by: Alex Ainscow # Conflicts: # src/osd/osd_types.h --- src/osd/ECBackend.cc | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/osd/ECBackend.cc b/src/osd/ECBackend.cc index 7c8781b3e6111..76f8a8ad11e4d 100644 --- a/src/osd/ECBackend.cc +++ b/src/osd/ECBackend.cc @@ -623,7 +623,7 @@ void ECBackend::RecoveryBackend::continue_recovery_op( m->pushes[pg_shard].push_back(PushOp()); PushOp &pop = m->pushes[pg_shard].back(); pop.soid = op.hoid; - pop.version = op.v; + pop.version = op.recovery_info.oi.get_version_for_shard(pg_shard.shard); op.returned_data->get_shard_first_buffer(pg_shard.shard, pop.data); dout(10) << __func__ << ": pop shard=" << pg_shard << ", oid=" << pop.soid @@ -636,7 +636,26 @@ void ECBackend::RecoveryBackend::continue_recovery_op( op.returned_data->get_shard_first_offset(pg_shard.shard), pop.data.length()); if (op.recovery_progress.first) { - pop.attrset = op.xattrs; + if (sinfo.is_nonprimary_shard(pg_shard.shard)) { + if (pop.version == op.recovery_info.oi.version) { + dout(10) << __func__ << ": copy OI attr only" << dendl; + pop.attrset[OI_ATTR] = op.xattrs[OI_ATTR]; + } else { + // We are recovering a partial write - make sure we push the correct + // version in the OI or a scrub error will occur. + object_info_t oi(op.recovery_info.oi); + oi.shard_versions.clear(); + oi.version = pop.version; + dout(10) << __func__ << ": partial write OI attr: oi=" << oi << dendl; + bufferlist bl; + oi.encode(bl, get_osdmap()->get_features( + CEPH_ENTITY_TYPE_OSD, nullptr)); + pop.attrset[OI_ATTR] = bl; + } + } else { + dout(10) << __func__ << ": push all attrs (not nonprimary)" << dendl; + pop.attrset = op.xattrs; + } } pop.recovery_info = op.recovery_info; pop.before_progress = op.recovery_progress; -- 2.39.5