OPTION(osd_op_complaint_time, OPT_FLOAT, 30) // how many seconds old makes an op complaint-worthy
OPTION(osd_command_max_records, OPT_INT, 256)
OPTION(osd_op_log_threshold, OPT_INT, 5) // how many op log messages to show in one go
+OPTION(osd_verify_sparse_read_holes, OPT_BOOL, false) // read fiemap-reported holes and verify they are zeros
OPTION(filestore, OPT_BOOL, false)
OPTION(filestore_debug_omap_check, OPT_BOOL, 0) // Expensive debugging check on sync
// Use omap for xattrs for attrs over
::decode(m, iter);
map<uint64_t, uint64_t>::iterator miter;
bufferlist data_bl;
+ uint64_t last = op.extent.offset;
for (miter = m.begin(); miter != m.end(); ++miter) {
+ // verify hole?
+ if (g_conf->osd_verify_sparse_read_holes &&
+ last < miter->first) {
+ bufferlist t;
+ uint64_t len = miter->first - last;
+ r = osd->store->read(coll, soid, last, len, t);
+ if (!t.is_zero()) {
+ osd->clog.error() << coll << " " << soid << " sparse-read found data in hole "
+ << last << "~" << len << "\n";
+ }
+ }
+
bufferlist tmpbl;
r = osd->store->read(coll, soid, miter->first, miter->second, tmpbl);
if (r < 0)
total_read += r;
dout(10) << "sparse-read " << miter->first << "@" << miter->second << dendl;
data_bl.claim_append(tmpbl);
+ last = miter->first + r;
}
+ // verify trailing hole?
+ if (g_conf->osd_verify_sparse_read_holes) {
+ uint64_t end = MIN(op.extent.offset + op.extent.length, oi.size);
+ if (last < end) {
+ bufferlist t;
+ uint64_t len = end - last;
+ r = osd->store->read(coll, soid, last, len, t);
+ if (!t.is_zero()) {
+ osd->clog.error() << coll << " " << soid << " sparse-read found data in hole "
+ << last << "~" << len << "\n";
+ }
+ }
+ }
+
if (r < 0) {
result = r;
break;