summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zafman <david.zafman@inktank.com>2013-01-08 19:24:13 -0800
committerSamuel Just <sam.just@inktank.com>2013-03-19 10:40:30 -0700
commit2fd8db29ccf56fd5473826f20e351edfe200419d (patch)
treeb1dd0f01167dff18aef0dff9e290e2d2f8d5de7b
parentee59f517ccc195e591e0b1b6ddf6d1d054c4e2fd (diff)
downloadceph-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.cc41
-rw-r--r--src/osd/osd_types.cc14
-rw-r--r--src/osd/osd_types.h4
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);