summaryrefslogtreecommitdiffstats
path: root/src/osd/PrimaryLogPG.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/PrimaryLogPG.cc')
-rw-r--r--src/osd/PrimaryLogPG.cc76
1 files changed, 51 insertions, 25 deletions
diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc
index 44f8e85b5ef..3324ba9dc91 100644
--- a/src/osd/PrimaryLogPG.cc
+++ b/src/osd/PrimaryLogPG.cc
@@ -2286,6 +2286,16 @@ void PrimaryLogPG::do_op(OpRequestRef& op)
}
}
+ if (cct->_conf->bluestore_debug_inject_read_err &&
+ op->may_write() &&
+ pool.info.is_erasure() &&
+ ec_inject_test_write_error0(m->get_hobj(), m->get_reqid())) {
+ // Fail retried write with error
+ dout(0) << __func__ << " Error inject - Fail retried write with EINVAL" << dendl;
+ osd->reply_op_error(op, -EINVAL);
+ return;
+ }
+
ObjectContextRef obc;
bool can_create = op->may_write();
hobject_t missing_oid;
@@ -5798,10 +5808,19 @@ int PrimaryLogPG::do_extent_cmp(OpContext *ctx, OSDOp& osd_op)
int PrimaryLogPG::finish_extent_cmp(OSDOp& osd_op, const bufferlist &read_bl)
{
- for (uint64_t idx = 0; idx < osd_op.indata.length(); ++idx) {
- char read_byte = (idx < read_bl.length() ? read_bl[idx] : 0);
- if (osd_op.indata[idx] != read_byte) {
- return (-MAX_ERRNO - idx);
+ auto input_iter = osd_op.indata.begin();
+ auto read_iter = read_bl.begin();
+ uint64_t idx = 0;
+
+ while (input_iter != osd_op.indata.end()) {
+ char read_byte = (read_iter != read_bl.end() ? *read_iter : 0);
+ if (*input_iter != read_byte) {
+ return (-MAX_ERRNO - idx);
+ }
+ ++idx;
+ ++input_iter;
+ if (read_iter != read_bl.end()) {
+ ++read_iter;
}
}
@@ -7767,27 +7786,34 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
bool truncated = false;
bufferlist bl;
if (oi.is_omap()) {
- ObjectMap::ObjectMapIterator iter = osd->store->get_omap_iterator(
- ch, ghobject_t(soid)
- );
- if (!iter) {
- result = -ENOENT;
- goto fail;
- }
- iter->upper_bound(start_after);
- if (filter_prefix > start_after) iter->lower_bound(filter_prefix);
- for (num = 0;
- iter->valid() &&
- iter->key().substr(0, filter_prefix.size()) == filter_prefix;
- ++num, iter->next()) {
- dout(20) << "Found key " << iter->key() << dendl;
- if (num >= max_return ||
- bl.length() >= cct->_conf->osd_max_omap_bytes_per_request) {
- truncated = true;
- break;
- }
- encode(iter->key(), bl);
- encode(iter->value(), bl);
+ using omap_iter_seek_t = ObjectStore::omap_iter_seek_t;
+ result = osd->store->omap_iterate(
+ ch, ghobject_t(soid),
+ // try to seek as many keys-at-once as possible for the sake of performance.
+ // note complexity should be logarithmic, so seek(n/2) + seek(n/2) is worse
+ // than just seek(n).
+ ObjectStore::omap_iter_seek_t{
+ .seek_position = std::max(start_after, filter_prefix),
+ .seek_type = filter_prefix > start_after ? omap_iter_seek_t::LOWER_BOUND
+ : omap_iter_seek_t::UPPER_BOUND
+ },
+ [&bl, &truncated, &filter_prefix, &num, max_return,
+ max_bytes=cct->_conf->osd_max_omap_bytes_per_request]
+ (std::string_view key, std::string_view value) mutable {
+ if (key.substr(0, filter_prefix.size()) != filter_prefix) {
+ return ObjectStore::omap_iter_ret_t::STOP;
+ }
+ if (num >= max_return || bl.length() >= max_bytes) {
+ truncated = true;
+ return ObjectStore::omap_iter_ret_t::STOP;
+ }
+ encode(key, bl);
+ encode(value, bl);
+ ++num;
+ return ObjectStore::omap_iter_ret_t::NEXT;
+ });
+ if (result < 0) {
+ goto fail;
}
} // else return empty out_set
encode(num, osd_op.outdata);