bufferlist *bl) {
if (!sinfo.supports_direct_reads()) {
- return -EOPNOTSUPP;
-}
-
- int r = _objects_read_sync(hoid, off, len, op_flags, bl);
-
- if (r < 0) {
- dout(20) << __func__ << " r=" << r
- << " hoid=" << hoid
- << " off=" << off
- << " len=" << len
- << " op_flags=" << op_flags
- << " primary=" << switcher->is_primary()
- << " shard=" << (off / sinfo.get_chunk_size()) % sinfo.get_k()
- << dendl;
- } else {
- return r;
+ return -EOPNOTSUPP;
}
- // The above returns errors largely only interesting for tracing. Here we
- // simplify this down to:
- // Primary returns EIO, which causes an async read to be executed immediately.
- // A non-primary returns EAGAIN which forces the client to resent to the
- // primary.
- if (switcher->is_primary()) {
- return -EIO;
+ if (get_parent()->get_local_missing().is_missing(hoid)) {
+ return -EIO; // Permission denied (cos its missing)
}
- return -EAGAIN;
+ auto [shard_offset, shard_len] = extent_to_shard_extent(off, len);
+
+
+ dout(20) << __func__ << " Submitting sync read: "
+ << " hoid=" << hoid
+ << " shard_offset=" << shard_offset
+ << " shard_len=" << shard_len
+ << " op_flags=" << op_flags
+ << " primary=" << switcher->is_primary()
+ << dendl;
+
+
+ return switcher->store->read(switcher->ch,
+ ghobject_t(hoid, ghobject_t::NO_GEN, get_parent()->whoami_shard().shard),
+ shard_offset,
+ shard_len, *bl, op_flags);
}
std::pair<uint64_t, uint64_t> ECBackend::extent_to_shard_extent(uint64_t off, uint64_t len) {
return std::pair(shard_offset, shard_len);
}
-// NOTE: Return codes from this function are largely nonsense and translated
-// to more useful values before returning to client.
-int ECBackend::_objects_read_sync(
- const hobject_t &hoid,
- uint64_t off,
- uint64_t len,
- uint32_t op_flags,
- bufferlist *bl) {
-
- if (get_parent()->get_local_missing().is_missing(hoid)) {
- return -EACCES; // Permission denied (cos its missing)
- }
-
- auto [shard_offset, shard_len] = extent_to_shard_extent(off, len);
-
-
- dout(20) << __func__ << " Submitting sync read: "
- << " hoid=" << hoid
- << " shard_offset=" << shard_offset
- << " shard_len=" << shard_len
- << " op_flags=" << op_flags
- << " primary=" << switcher->is_primary()
- << dendl;
-
-
- return switcher->store->read(switcher->ch,
- ghobject_t(hoid, ghobject_t::NO_GEN, get_parent()->whoami_shard().shard),
- shard_offset,
- shard_len, *bl, op_flags);
-}
-
int ECBackend::objects_readv_sync(const hobject_t &hoid,
std::map<uint64_t, uint64_t>& m,
uint32_t op_flags,
return legacy.objects_read_sync(hoid, off, len, op_flags, bl);
}
+ int objects_readv_sync(const hobject_t &hoid,
+ std::map<uint64_t, uint64_t>& m,
+ uint32_t op_flags,
+ ceph::buffer::list *bl) override
+ {
+ if (is_optimized()) {
+ return optimized.objects_readv_sync(hoid, m, op_flags, bl);
+ }
+ ceph_abort_msg("Sync reads legacy EC");
+ }
+
std::pair<uint64_t, uint64_t> extent_to_shard_extent(
uint64_t off, uint64_t len) override {
if (is_optimized()) {
}
++ctx->num_read;
- if (pool.info.is_erasure()) {
+ if (pool.info.is_erasure() && !ctx->op->ec_direct_read()) {
// translate sparse read to a normal one if not supported
if (length > 0) {
} else {
// read into a buffer
map<uint64_t, uint64_t> m;
+ auto [shard_offset, shard_length] = pgbackend->extent_to_shard_extent(offset, length);
int r = osd->store->fiemap(ch, ghobject_t(soid, ghobject_t::NO_GEN,
info.pgid.shard),
- offset, length, m);
+ shard_offset, shard_length, m);
if (r < 0) {
return r;
}
r = rep_repair_primary_object(soid, ctx);
}
if (r < 0) {
+ dout(10) << " sparse_read failed r=" << r << " from object " << soid << dendl;
return r;
}
// 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 ((uint64_t)r == oi.size && oi.is_data_digest()) {
+ // For now, we do not check the CRC for EC ever. We could implement this,
+ // but it would only work for very small objects and as such is probably
+ // not very useful.
+ if ((uint64_t)r == oi.size && oi.is_data_digest() && !pool.info.is_erasure()) {
uint32_t crc = data_bl.crc32c(-1);
if (oi.data_digest != crc) {
osd->clog->error() << info.pgid << std::hex