diff options
author | David Zafman <david.zafman@inktank.com> | 2013-01-08 19:24:13 -0800 |
---|---|---|
committer | Samuel Just <sam.just@inktank.com> | 2013-03-19 10:40:30 -0700 |
commit | 2fd8db29ccf56fd5473826f20e351edfe200419d (patch) | |
tree | b1dd0f01167dff18aef0dff9e290e2d2f8d5de7b | |
parent | ee59f517ccc195e591e0b1b6ddf6d1d054c4e2fd (diff) | |
download | ceph-2fd8db29ccf56fd5473826f20e351edfe200419d.tar.gz |
osd: Add digest of omap for deep-scrub
Add ScrubMap encode/decode v4 message with omap digest
Compute digest of header and key/value. Use bufferlist
to reflect structure and compute as we go, clearing
bufferlist to reduce memory usage.
Signed-off-by: David Zafman <david.zafman@inktank.com>
Reviewed-by: Samuel Just <sam.just@inktank.com>
(cherry picked from commit 509a93e89f04d7e9393090563cf7be8e0ea53891)
-rw-r--r-- | src/osd/PG.cc | 41 | ||||
-rw-r--r-- | src/osd/osd_types.cc | 14 | ||||
-rw-r--r-- | src/osd/osd_types.h | 4 |
3 files changed, 50 insertions, 9 deletions
diff --git a/src/osd/PG.cc b/src/osd/PG.cc index 982ce1a3d76..2f1d77cb602 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -3153,8 +3153,8 @@ void PG::_scan_list(ScrubMap &map, vector<hobject_t> &ls, bool deep) // calculate the CRC32 on deep scrubs if (deep) { - bufferhash h; - bufferlist bl; + bufferhash h, oh; + bufferlist bl, hdrbl; int r; __u64 pos = 0; while ( (r = osd->store->read(coll, poid, pos, @@ -3165,6 +3165,33 @@ void PG::_scan_list(ScrubMap &map, vector<hobject_t> &ls, bool deep) } o.digest = h.digest(); o.digest_present = true; + + bl.clear(); + r = osd->store->omap_get_header(coll, poid, &hdrbl); + if (r == 0) { + dout(25) << "CRC header " << string(hdrbl.c_str(), hdrbl.length()) + << dendl; + ::encode(hdrbl, bl); + oh << bl; + bl.clear(); + } + + ObjectMap::ObjectMapIterator iter = osd->store->get_omap_iterator( + coll, poid); + assert(iter); + for (iter->seek_to_first(); iter->valid() ; iter->next()) { + dout(25) << "CRC key " << iter->key() << " value " + << string(iter->value().c_str(), iter->value().length()) << dendl; + + ::encode(iter->key(), bl); + ::encode(iter->value(), bl); + oh << bl; + bl.clear(); + } + + //Store final calculated CRC32 of omap header & key/values + o.omap_digest = oh.digest(); + o.omap_digest_present = true; } if (poid.snap != CEPH_SNAPDIR && poid.snap != CEPH_NOSNAP) { @@ -4068,6 +4095,16 @@ bool PG::_compare_scrub_objects(ScrubMap::object &auth, << " != known digest " << auth.digest; } } + if (auth.omap_digest_present && candidate.omap_digest_present) { + if (auth.omap_digest != candidate.omap_digest) { + if (!ok) + errorstream << ", "; + ok = false; + + errorstream << "omap_digest " << candidate.omap_digest + << " != known omap_digest " << auth.omap_digest; + } + } for (map<string,bufferptr>::const_iterator i = auth.attrs.begin(); i != auth.attrs.end(); i++) { diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index 8f9f9ab5cc4..e0f2b987281 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -2806,7 +2806,7 @@ void ScrubMap::generate_test_instances(list<ScrubMap*>& o) void ScrubMap::object::encode(bufferlist& bl) const { - ENCODE_START(4, 2, bl); + ENCODE_START(5, 2, bl); ::encode(size, bl); ::encode(negative, bl); ::encode(attrs, bl); @@ -2814,12 +2814,14 @@ void ScrubMap::object::encode(bufferlist& bl) const ::encode(digest_present, bl); ::encode(nlinks, bl); ::encode(snapcolls, bl); + ::encode(omap_digest, bl); + ::encode(omap_digest_present, bl); ENCODE_FINISH(bl); } void ScrubMap::object::decode(bufferlist::iterator& bl) { - DECODE_START_LEGACY_COMPAT_LEN(4, 2, 2, bl); + DECODE_START_LEGACY_COMPAT_LEN(5, 2, 2, bl); ::decode(size, bl); ::decode(negative, bl); ::decode(attrs, bl); @@ -2827,10 +2829,6 @@ void ScrubMap::object::decode(bufferlist::iterator& bl) ::decode(digest, bl); ::decode(digest_present, bl); } - else { - digest = 0; - digest_present = false; - } if (struct_v >= 4) { ::decode(nlinks, bl); ::decode(snapcolls, bl); @@ -2839,6 +2837,10 @@ void ScrubMap::object::decode(bufferlist::iterator& bl) * return nlink >= 1 */ nlinks = 0; } + if (struct_v >= 5) { + ::decode(omap_digest, bl); + ::decode(omap_digest_present, bl); + } DECODE_FINISH(bl); } diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index e896d09dbf0..fa9070a27e5 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -1836,10 +1836,12 @@ struct ScrubMap { bool digest_present; uint32_t nlinks; set<snapid_t> snapcolls; + __u32 omap_digest; + bool omap_digest_present; object() : size(0), negative(false), digest(0), digest_present(false), - nlinks(0) {} + nlinks(0), omap_digest(0), omap_digest_present(false) {} void encode(bufferlist& bl) const; void decode(bufferlist::iterator& bl); |