}
return true;
}
+
+bool ObjectDesc::check_sparse(const std::map<uint64_t, uint64_t>& extents,
+ bufferlist &to_check) {
+ iterator i = begin();
+ bufferlist::iterator p = to_check.begin();
+ uint64_t pos = 0;
+ for (std::map<uint64_t, uint64_t>::const_iterator extent = extents.begin();
+ extent != extents.end();
+ ++extent) {
+ const uint64_t start = extent->first;
+ const uint64_t end = start + extent->second;
+ for (; pos < end; ++i, ++pos) {
+ if (i.end()) {
+ std::cout << "reached end of iterator first" << std::endl;
+ return false;
+ }
+ if (pos < start) {
+ // check the hole
+ if (*i != '\0') {
+ std::cout << "incorrect buffer at pos " << pos << std::endl;
+ return false;
+ }
+ } else {
+ // then the extent
+ if (*i != *p) {
+ std::cout << "incorrect buffer at pos " << pos << std::endl;
+ return false;
+ }
+ ++p;
+ }
+ }
+ }
+ uint64_t size = layers.empty() ? 0 :
+ most_recent_gen()->get_length(most_recent());
+ if (pos != size) {
+ std::cout << "only read " << pos << " out of size " << size << std::endl;
+ return false;
+ }
+ return true;
+}
// takes ownership of gen
void update(ContentsGenerator *gen, const ContDesc &next);
bool check(bufferlist &to_check);
+ bool check_sparse(const std::map<uint64_t, uint64_t>& extends,
+ bufferlist &to_check);
const ContDesc &most_recent();
ContentsGenerator *most_recent_gen() {
return layers.begin()->first.get();
bufferlist result;
int retval;
+ std::map<uint64_t, uint64_t> extent_result;
+ bool is_sparse_read;
map<string, bufferlist> attrs;
int attrretval;
oid(oid),
snap(0),
retval(0),
+ is_sparse_read(false),
attrretval(0)
{}
-
+
void _begin()
{
context->state_lock.Lock();
context->io_ctx.snap_set_read(context->snaps[snap]);
}
- op.read(0,
- !old_value.has_contents() ? 0 :
- old_value.most_recent_gen()->get_length(old_value.most_recent()),
- &result,
- &retval);
+ uint64_t read_len = 0;
+ if (old_value.has_contents())
+ read_len = old_value.most_recent_gen()->get_length(old_value.most_recent());
+ if (rand() % 2) {
+ is_sparse_read = false;
+ op.read(0,
+ read_len,
+ &result,
+ &retval);
+ } else {
+ is_sparse_read = true;
+ op.sparse_read(0,
+ read_len,
+ &extent_result,
+ &result,
+ &retval);
+ }
for (map<string, ContDesc>::iterator i = old_value.attrs.begin();
i != old_value.attrs.end();
<< ", expected " << old_value.most_recent() << std::endl;
context->errors++;
}
- if (!old_value.check(result)) {
- cerr << num << ": oid " << oid << " contents " << to_check << " corrupt" << std::endl;
- context->errors++;
+ if (is_sparse_read) {
+ if (!old_value.check_sparse(extent_result, result)) {
+ cerr << num << ": oid " << oid << " contents " << to_check << " corrupt" << std::endl;
+ context->errors++;
+ }
+ } else {
+ if (!old_value.check(result)) {
+ cerr << num << ": oid " << oid << " contents " << to_check << " corrupt" << std::endl;
+ context->errors++;
+ }
}
if (context->errors) assert(0);
}