From 2fe9816305fc1406ab7fb043bbb32affffc2d190 Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Wed, 20 Jun 2012 12:55:38 -0700 Subject: [PATCH] OSD,PG,ObjectStore: handle messages with old hobject_t encoding Messages that embed an hobject_t need to have the pool field fixed on messages from old peers. Signed-off-by: Samuel Just --- src/messages/MOSDPGBackfill.h | 5 ++ src/messages/MOSDPGLog.h | 4 +- src/messages/MOSDPGMissing.h | 2 +- src/messages/MOSDPGScan.h | 6 +++ src/messages/MOSDSubOp.h | 17 +++++-- src/messages/MOSDSubOpReply.h | 3 ++ src/os/ObjectStore.h | 24 ++++++++-- src/osd/PG.cc | 4 +- src/osd/ReplicatedPG.cc | 24 ++++++++++ src/osd/osd_types.cc | 86 ++++++++++++++++++++++++++++++----- src/osd/osd_types.h | 8 ++-- 11 files changed, 155 insertions(+), 28 deletions(-) diff --git a/src/messages/MOSDPGBackfill.h b/src/messages/MOSDPGBackfill.h index 7e6c45e1e9a70..bc2a696b6ce79 100644 --- a/src/messages/MOSDPGBackfill.h +++ b/src/messages/MOSDPGBackfill.h @@ -48,6 +48,11 @@ public: ::decode(pgid, p); ::decode(last_backfill, p); ::decode(stats, p); + + // Handle hobject_t format change + if (!last_backfill.is_max() && + last_backfill.pool == -1) + last_backfill.pool = pgid.pool(); } virtual void encode_payload(uint64_t features) { diff --git a/src/messages/MOSDPGLog.h b/src/messages/MOSDPGLog.h index b296fb3997d39..53358d68cdf41 100644 --- a/src/messages/MOSDPGLog.h +++ b/src/messages/MOSDPGLog.h @@ -70,8 +70,8 @@ public: bufferlist::iterator p = payload.begin(); ::decode(epoch, p); ::decode(info, p); - ::decode(log, p); - ::decode(missing, p); + log.decode(p, info.pgid.pool()); + missing.decode(p, info.pgid.pool()); if (header.version >= 2) { ::decode(query_epoch, p); } diff --git a/src/messages/MOSDPGMissing.h b/src/messages/MOSDPGMissing.h index 024414b37913f..b931b36353fe2 100644 --- a/src/messages/MOSDPGMissing.h +++ b/src/messages/MOSDPGMissing.h @@ -50,7 +50,7 @@ public: bufferlist::iterator p = payload.begin(); ::decode(epoch, p); ::decode(info, p); - ::decode(missing, p); + missing.decode(p, info.pgid.pool()); } }; diff --git a/src/messages/MOSDPGScan.h b/src/messages/MOSDPGScan.h index cc69b92e170b7..7df3a966dba7a 100644 --- a/src/messages/MOSDPGScan.h +++ b/src/messages/MOSDPGScan.h @@ -45,6 +45,12 @@ public: ::decode(pgid, p); ::decode(begin, p); ::decode(end, p); + + // handle hobject_t format upgrade + if (begin.pool == -1) + begin.pool = pgid.pool(); + if (end.pool == -1) + end.pool = pgid.pool(); } virtual void encode_payload(uint64_t features) { diff --git a/src/messages/MOSDSubOp.h b/src/messages/MOSDSubOp.h index a92449a930950..3da997dc8df2f 100644 --- a/src/messages/MOSDSubOp.h +++ b/src/messages/MOSDSubOp.h @@ -25,7 +25,7 @@ class MOSDSubOp : public Message { - static const int HEAD_VERSION = 6; + static const int HEAD_VERSION = 7; static const int COMPAT_VERSION = 1; public: @@ -83,6 +83,9 @@ public: map omap_entries; bufferlist omap_header; + // indicates that we must fix hobject_t encoding + bool hobject_incorrect_pool; + virtual void decode_payload() { bufferlist::iterator p = payload.begin(); ::decode(map_epoch, p); @@ -125,7 +128,7 @@ public: ::decode(oloc, p); if (header.version >= 4) { ::decode(data_included, p); - ::decode(recovery_info, p); + recovery_info.decode(p, pgid.pool()); ::decode(recovery_progress, p); ::decode(current_progress, p); } @@ -133,6 +136,13 @@ public: ::decode(omap_entries, p); if (header.version >= 6) ::decode(omap_header, p); + + if (header.version < 7) { + // Handle hobject_t format change + if (poid.pool == -1) + poid.pool = pgid.pool(); + hobject_incorrect_pool = true; + } } virtual void encode_payload(uint64_t features) { @@ -192,7 +202,8 @@ public: noop(noop_), old_exists(false), old_size(0), version(v), - first(false), complete(false) { + first(false), complete(false), + hobject_incorrect_pool(false) { memset(&peer_stat, 0, sizeof(peer_stat)); set_tid(rtid); } diff --git a/src/messages/MOSDSubOpReply.h b/src/messages/MOSDSubOpReply.h index fc2d7717eab72..d577dd3c2d30f 100644 --- a/src/messages/MOSDSubOpReply.h +++ b/src/messages/MOSDSubOpReply.h @@ -68,6 +68,9 @@ public: ::decode(last_complete_ondisk, p); ::decode(peer_stat, p); ::decode(attrset, p); + + if (poid.pool == -1) + poid.pool = pgid.pool(); } virtual void encode_payload(uint64_t features) { ::encode(map_epoch, payload); diff --git a/src/os/ObjectStore.h b/src/os/ObjectStore.h index 56f5401a5afee..53f365773db69 100644 --- a/src/os/ObjectStore.h +++ b/src/os/ObjectStore.h @@ -158,8 +158,13 @@ public: uint32_t largest_data_len, largest_data_off, largest_data_off_in_tbl; bufferlist tbl; bool sobject_encoding; + int64_t pool_override; + bool use_pool_override; public: + void set_pool_override(int64_t pool) { + pool_override = pool; + } void swap(Transaction& other) { std::swap(ops, other.ops); @@ -225,10 +230,14 @@ public: class iterator { bufferlist::iterator p; bool sobject_encoding; + int64_t pool_override; + bool use_pool_override; iterator(Transaction *t) : p(t->tbl.begin()), - sobject_encoding(t->sobject_encoding) {} + sobject_encoding(t->sobject_encoding), + pool_override(t->pool_override), + use_pool_override(t->use_pool_override) {} friend class Transaction; @@ -253,6 +262,10 @@ public: hoid.oid = soid.oid; } else { ::decode(hoid, p); + if (use_pool_override && pool_override != -1 && + hoid.pool == -1) { + hoid.pool = pool_override; + } } return hoid; } @@ -531,7 +544,7 @@ public: // etc. Transaction() : ops(0), pad_unused_bytes(0), largest_data_len(0), largest_data_off(0), largest_data_off_in_tbl(0), - sobject_encoding(false) {} + sobject_encoding(false), pool_override(-1), use_pool_override(false) {} Transaction(bufferlist::iterator &dp) : ops(0), pad_unused_bytes(0), largest_data_len(0), largest_data_off(0), largest_data_off_in_tbl(0), sobject_encoding(false) { @@ -545,7 +558,7 @@ public: } void encode(bufferlist& bl) const { - ENCODE_START(5, 5, bl); + ENCODE_START(6, 5, bl); ::encode(ops, bl); ::encode(pad_unused_bytes, bl); ::encode(largest_data_len, bl); @@ -555,7 +568,7 @@ public: ENCODE_FINISH(bl); } void decode(bufferlist::iterator &bl) { - DECODE_START_LEGACY_COMPAT_LEN(5, 5, 5, bl); + DECODE_START_LEGACY_COMPAT_LEN(6, 5, 5, bl); DECODE_OLDEST(2); if (struct_v < 4) sobject_encoding = true; @@ -570,6 +583,9 @@ public: } ::decode(tbl, bl); DECODE_FINISH(bl); + if (struct_v < 6) { + use_pool_override = true; + } } void dump(ceph::Formatter *f); diff --git a/src/osd/PG.cc b/src/osd/PG.cc index a63ab28779c0e..d3c670aa77dc2 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -2622,12 +2622,12 @@ void PG::sub_op_scrub_map(OpRequestRef op) bufferlist::iterator p = m->get_data().begin(); if (scrub_received_maps.count(from)) { ScrubMap incoming; - incoming.decode(p); + incoming.decode(p, info.pgid.pool()); dout(10) << "from replica " << from << dendl; dout(10) << "map version is " << incoming.valid_through << dendl; scrub_received_maps[from].merge_incr(incoming); } else { - scrub_received_maps[from].decode(p); + scrub_received_maps[from].decode(p, info.pgid.pool()); } if (--scrub_waiting_on == 0) { diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 2473be6264584..a2a0efcdce98e 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -1140,6 +1140,20 @@ void ReplicatedPG::do_scan(OpRequestRef op) bufferlist::iterator p = m->get_data().begin(); ::decode(bi.objects, p); + // handle hobject_t encoding change + if (bi.objects.size() && bi.objects.begin()->first.pool == -1) { + map tmp; + tmp.swap(bi.objects); + for (map::iterator i = tmp.begin(); + i != tmp.end(); + ++i) { + hobject_t first(i->first); + if (first.pool == -1) + first.pool = info.pgid.pool(); + bi.objects[first] = i->second; + } + } + backfill_pos = backfill_info.begin > peer_backfill_info.begin ? peer_backfill_info.begin : backfill_info.begin; dout(10) << " backfill_pos now " << backfill_pos << dendl; @@ -4178,9 +4192,19 @@ void ReplicatedPG::sub_op_modify(OpRequestRef op) vector log; bufferlist::iterator p = m->get_data().begin(); + ::decode(rm->opt, p); p = m->logbl.begin(); ::decode(log, p); + if (m->hobject_incorrect_pool) { + for (vector::iterator i = log.begin(); + i != log.end(); + ++i) { + if (i->soid.pool == -1) + i->soid.pool = info.pgid.pool(); + } + rm->opt.set_pool_override(info.pgid.pool()); + } info.stats = m->pg_stats; update_snap_collections(log, rm->localt); diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index ecb42ce33d77f..cdc7d67a31cc4 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -1528,16 +1528,16 @@ ostream& operator<<(ostream& out, const pg_log_entry_t& e) void pg_log_t::encode(bufferlist& bl) const { - ENCODE_START(3, 3, bl); + ENCODE_START(4, 3, bl); ::encode(head, bl); ::encode(tail, bl); ::encode(log, bl); ENCODE_FINISH(bl); } -void pg_log_t::decode(bufferlist::iterator &bl) +void pg_log_t::decode(bufferlist::iterator &bl, int64_t pool) { - DECODE_START_LEGACY_COMPAT_LEN(3, 3, 3, bl); + DECODE_START_LEGACY_COMPAT_LEN(4, 3, 3, bl); ::decode(head, bl); ::decode(tail, bl); if (struct_v < 2) { @@ -1546,6 +1546,17 @@ void pg_log_t::decode(bufferlist::iterator &bl) } ::decode(log, bl); DECODE_FINISH(bl); + + // handle hobject_t format change + if (struct_v < 4) { + assert(pool != -1); + for (list::iterator i = log.begin(); + i != log.end(); + ++i) { + if (i->soid.pool == -1) + i->soid.pool = pool; + } + } } void pg_log_t::dump(Formatter *f) const @@ -1642,17 +1653,36 @@ ostream& pg_log_t::print(ostream& out) const void pg_missing_t::encode(bufferlist &bl) const { - ENCODE_START(2, 2, bl); + ENCODE_START(3, 2, bl); ::encode(missing, bl); ENCODE_FINISH(bl); } -void pg_missing_t::decode(bufferlist::iterator &bl) +void pg_missing_t::decode(bufferlist::iterator &bl, int64_t pool) { - DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl); + DECODE_START_LEGACY_COMPAT_LEN(3, 2, 2, bl); ::decode(missing, bl); DECODE_FINISH(bl); + if (struct_v < 3) { + assert(pool != -1); + // Handle hobject_t upgrade + map tmp; + for (map::iterator i = missing.begin(); + i != missing.end(); + ) { + if (i->first.pool == -1) { + hobject_t to_insert(i->first); + to_insert.pool = pool; + tmp[to_insert] = i->second; + missing.erase(i++); + } else { + ++i; + } + } + missing.insert(tmp.begin(), tmp.end()); + } + for (map::iterator it = missing.begin(); it != missing.end(); ++it) @@ -2286,7 +2316,7 @@ void ObjectRecoveryProgress::dump(Formatter *f) const void ObjectRecoveryInfo::encode(bufferlist &bl) const { - ENCODE_START(1, 1, bl); + ENCODE_START(2, 1, bl); ::encode(soid, bl); ::encode(version, bl); ::encode(size, bl); @@ -2297,9 +2327,10 @@ void ObjectRecoveryInfo::encode(bufferlist &bl) const ENCODE_FINISH(bl); } -void ObjectRecoveryInfo::decode(bufferlist::iterator &bl) +void ObjectRecoveryInfo::decode(bufferlist::iterator &bl, + int64_t pool) { - DECODE_START(1, bl); + DECODE_START(2, bl); ::decode(soid, bl); ::decode(version, bl); ::decode(size, bl); @@ -2308,6 +2339,22 @@ void ObjectRecoveryInfo::decode(bufferlist::iterator &bl) ::decode(copy_subset, bl); ::decode(clone_subset, bl); DECODE_FINISH(bl); + + if (struct_v < 2) { + assert(pool != -1); + if (soid.pool == -1) + soid.pool = pool; + map > tmp; + tmp.swap(clone_subset); + for (map >::iterator i = tmp.begin(); + i != tmp.end(); + ++i) { + hobject_t first(i->first); + if (first.pool == -1) + first.pool = pool; + clone_subset[first].swap(i->second); + } + } } void ObjectRecoveryInfo::generate_test_instances( @@ -2378,7 +2425,7 @@ void ScrubMap::merge_incr(const ScrubMap &l) void ScrubMap::encode(bufferlist& bl) const { - ENCODE_START(2, 2, bl); + ENCODE_START(3, 2, bl); ::encode(objects, bl); ::encode(attrs, bl); ::encode(logbl, bl); @@ -2387,15 +2434,30 @@ void ScrubMap::encode(bufferlist& bl) const ENCODE_FINISH(bl); } -void ScrubMap::decode(bufferlist::iterator& bl) +void ScrubMap::decode(bufferlist::iterator& bl, int64_t pool) { - DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl); + DECODE_START_LEGACY_COMPAT_LEN(3, 2, 2, bl); ::decode(objects, bl); ::decode(attrs, bl); ::decode(logbl, bl); ::decode(valid_through, bl); ::decode(incr_since, bl); DECODE_FINISH(bl); + + // handle hobject_t upgrade + if (struct_v < 3) { + assert(pool != -1); + map tmp; + tmp.swap(objects); + for (map::iterator i = tmp.begin(); + i != tmp.end(); + ++i) { + hobject_t first(i->first); + if (first.pool == -1) + first.pool = pool; + objects[first] = i->second; + } + } } void ScrubMap::dump(Formatter *f) const diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index 8d11aea2e30e7..d3033c344424f 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -1330,7 +1330,7 @@ struct pg_log_t { ostream& print(ostream& out) const; void encode(bufferlist &bl) const; - void decode(bufferlist::iterator &bl); + void decode(bufferlist::iterator &bl, int64_t pool = -1); void dump(Formatter *f) const; static void generate_test_instances(list& o); }; @@ -1401,7 +1401,7 @@ struct pg_missing_t { } void encode(bufferlist &bl) const; - void decode(bufferlist::iterator &bl); + void decode(bufferlist::iterator &bl, int64_t pool = -1); void dump(Formatter *f) const; static void generate_test_instances(list& o); }; @@ -1705,7 +1705,7 @@ struct ObjectRecoveryInfo { static void generate_test_instances(list& o); void encode(bufferlist &bl) const; - void decode(bufferlist::iterator &bl); + void decode(bufferlist::iterator &bl, int64_t pool = -1); ostream &print(ostream &out) const; void dump(Formatter *f) const; }; @@ -1768,7 +1768,7 @@ struct ScrubMap { void merge_incr(const ScrubMap &l); void encode(bufferlist& bl) const; - void decode(bufferlist::iterator& bl); + void decode(bufferlist::iterator& bl, int64_t pool=-1); void dump(Formatter *f) const; static void generate_test_instances(list& o); }; -- 2.39.5