From 48f69894eda35c56b3ebde3224cc1d1d0a1c9630 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 22 Feb 2011 12:20:40 -0800 Subject: [PATCH] osd: verify object version during push Fail to push if the ondisk version doesn't match the version we want to send. This isn't supposed to happen. If it does it means we have a bug somewhere else. Log something to the error log and don't push. This is better than the current behavior, which goes into a loop (repeatedly pulling the object and retrying when it's not the right version). Signed-off-by: Sage Weil --- src/osd/ReplicatedPG.cc | 15 +++++++++++---- src/osd/ReplicatedPG.h | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index cbe29e2257da8..9d142640ef917 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -3386,7 +3386,7 @@ void ReplicatedPG::push_start(const sobject_t& soid, int peer, dout(10) << "push_start " << soid << " size " << size << " data " << data_subset << " cloning " << clone_subsets << dendl; - send_push_op(soid, peer, size, true, complete, pi->data_subset_pushing, pi->clone_subsets); + send_push_op(soid, version, peer, size, true, complete, pi->data_subset_pushing, pi->clone_subsets); } @@ -3394,7 +3394,7 @@ void ReplicatedPG::push_start(const sobject_t& soid, int peer, * push - send object to a peer */ -void ReplicatedPG::send_push_op(const sobject_t& soid, int peer, +void ReplicatedPG::send_push_op(const sobject_t& soid, eversion_t version, int peer, uint64_t size, bool first, bool complete, interval_set &data_subset, map >& clone_subsets) @@ -3423,6 +3423,12 @@ void ReplicatedPG::send_push_op(const sobject_t& soid, int peer, bv.push_back(attrset[OI_ATTR]); object_info_t oi(bv); + if (oi.version != version) { + osd->clog.error() << "push " << soid << " v " << version << " to osd" << peer + << " failed because local copy is " << oi.version << "\n"; + return; + } + // ok dout(7) << "send_push_op " << soid << " v " << oi.version << " size " << size @@ -3482,7 +3488,8 @@ void ReplicatedPG::sub_op_push_reply(MOSDSubOpReply *reply) pi->data_subset_pushing.span_of(pi->data_subset, from, g_conf.osd_recovery_max_chunk); dout(10) << " pushing more, " << pi->data_subset_pushing << " of " << pi->data_subset << dendl; complete = pi->data_subset.range_end() == pi->data_subset_pushing.range_end(); - send_push_op(soid, peer, pi->size, false, complete, pi->data_subset_pushing, pi->clone_subsets); + send_push_op(soid, pi->version, peer, pi->size, false, complete, + pi->data_subset_pushing, pi->clone_subsets); } else { // done! peer_missing[peer].got(soid, pi->version); @@ -3543,7 +3550,7 @@ void ReplicatedPG::sub_op_pull(MOSDSubOp *op) // complete==false means nothing. we don't know because the primary may // not be pulling the entire object. - send_push_op(soid, op->get_source().num(), size, op->first, complete, op->data_subset, op->clone_subsets); + send_push_op(soid, op->version, op->get_source().num(), size, op->first, complete, op->data_subset, op->clone_subsets); } op->put(); } diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h index b89c5aa0c080f..5079f0b8ed2fb 100644 --- a/src/osd/ReplicatedPG.h +++ b/src/osd/ReplicatedPG.h @@ -525,7 +525,7 @@ protected: uint64_t size, eversion_t version, interval_set &data_subset, map >& clone_subsets); - void send_push_op(const sobject_t& oid, int dest, + void send_push_op(const sobject_t& oid, eversion_t version, int dest, uint64_t size, bool first, bool complete, interval_set& data_subset, map >& clone_subsets); -- 2.39.5