OPTION(osd_command_max_records, OPT_INT)
OPTION(osd_max_pg_blocked_by, OPT_U32) // max peer osds to report that are blocking our progress
OPTION(osd_op_log_threshold, OPT_INT) // how many op log messages to show in one go
-OPTION(osd_verify_sparse_read_holes, OPT_BOOL) // read fiemap-reported holes and verify they are zeros
OPTION(osd_backoff_on_unfound, OPT_BOOL) // object unfound
OPTION(osd_backoff_on_degraded, OPT_BOOL) // [mainly for debug?] object unreadable/writeable
OPTION(osd_backoff_on_peering, OPT_BOOL) // [debug] pg peering
return r;
}
- 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 (cct->_conf->osd_verify_sparse_read_holes &&
- last < miter->first) {
- bufferlist t;
- uint64_t len = miter->first - last;
- r = pgbackend->objects_read_sync(soid, last, len, op.flags, &t);
- if (r < 0) {
- osd->clog->error() << coll << " " << soid
- << " sparse-read failed to read: "
- << r;
- } else if (!t.is_zero()) {
- osd->clog->error() << coll << " " << soid
- << " sparse-read found data in hole "
- << last << "~" << len;
- }
- }
-
- bufferlist tmpbl;
- r = pgbackend->objects_read_sync(soid, miter->first, miter->second,
- op.flags, &tmpbl);
- if (r == -EIO) {
- r = rep_repair_primary_object(soid, ctx);
- }
- if (r < 0) {
- return r;
- }
-
- // this is usually happen when we get extent that exceeds the actual file
- // size
- if (r < (int)miter->second)
- miter->second = r;
- 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 (cct->_conf->osd_verify_sparse_read_holes) {
- uint64_t end = std::min<uint64_t>(op.extent.offset + op.extent.length,
- oi.size);
- if (last < end) {
- bufferlist t;
- uint64_t len = end - last;
- r = pgbackend->objects_read_sync(soid, last, len, op.flags, &t);
- if (r < 0) {
- osd->clog->error() << coll << " " << soid
- << " sparse-read failed to read: " << r;
- } else if (!t.is_zero()) {
- osd->clog->error() << coll << " " << soid
- << " sparse-read found data in hole "
- << last << "~" << len;
- }
- }
+ r = pgbackend->objects_readv_sync(soid, m, op.flags, &data_bl);
+ if (r == -EIO) {
+ r = rep_repair_primary_object(soid, ctx);
+ }
+ if (r < 0) {
+ return r;
}
// Why SPARSE_READ need checksum? In fact, librbd always use sparse-read.
// Maybe at first, there is no much whole objects. With continued use, more
// and more whole object exist. So from this point, for spare-read add
// checksum make sense.
- if (total_read == oi.size && oi.is_data_digest()) {
+ if ((uint64_t)r == oi.size && oi.is_data_digest()) {
uint32_t crc = data_bl.crc32c(-1);
if (oi.data_digest != crc) {
osd->clog->error() << info.pgid << std::hex
encode(m, osd_op.outdata); // re-encode since it might be modified
::encode_destructively(data_bl, osd_op.outdata);
- dout(10) << " sparse_read got " << total_read << " bytes from object "
+ dout(10) << " sparse_read got " << r << " bytes from object "
<< soid << dendl;
}
return store->read(ch, ghobject_t(hoid), off, len, *bl, op_flags);
}
+int ReplicatedBackend::objects_readv_sync(
+ const hobject_t &hoid,
+ map<uint64_t, uint64_t>& m,
+ uint32_t op_flags,
+ bufferlist *bl)
+{
+ interval_set<uint64_t> im(m);
+ auto r = store->readv(ch, ghobject_t(hoid), im, *bl, op_flags);
+ if (r >= 0) {
+ im.move_into(m);
+ }
+ return r;
+}
+
void ReplicatedBackend::objects_read_async(
const hobject_t &hoid,
const list<pair<boost::tuple<uint64_t, uint64_t, uint32_t>,