PushOp &op,
RecoveryMessages *m)
{
+ assert(m->t);
+
bool oneshot = op.before_progress.first && op.after_progress.data_complete;
- coll_t tcoll = oneshot ? coll : get_temp_coll(m->t);
+ ghobject_t tobj;
+ if (oneshot) {
+ tobj = ghobject_t(op.soid, ghobject_t::NO_GEN,
+ get_parent()->whoami_shard().shard);
+ } else {
+ tobj = ghobject_t(get_parent()->get_temp_recovery_object(op.version,
+ op.soid.snap),
+ ghobject_t::NO_GEN,
+ get_parent()->whoami_shard().shard);
+ if (op.before_progress.first) {
+ dout(10) << __func__ << ": Adding oid "
+ << tobj.hobj << " in the temp collection" << dendl;
+ add_temp_obj(tobj.hobj);
+ }
+ }
+
if (op.before_progress.first) {
- get_parent()->on_local_recover_start(
- op.soid,
- m->t);
- m->t->remove(
- get_temp_coll(m->t),
- ghobject_t(
- op.soid, ghobject_t::NO_GEN, get_parent()->whoami_shard().shard));
- m->t->touch(
- tcoll,
- ghobject_t(
- op.soid, ghobject_t::NO_GEN, get_parent()->whoami_shard().shard));
+ m->t->remove(coll, tobj);
+ m->t->touch(coll, tobj);
}
if (!op.data_included.empty()) {
tracepoint(osd, do_osd_op_pre_omapgetkeys, soid.oid.name.c_str(), soid.snap.val, start_after.c_str(), max_return);
set<string> out_set;
- if (!pool.info.require_rollback()) {
+ if (pool.info.supports_omap()) {
ObjectMap::ObjectMapIterator iter = osd->store->get_omap_iterator(
- coll, soid
+ coll, ghobject_t(soid)
);
assert(iter);
iter->upper_bound(start_after);
tracepoint(osd, do_osd_op_pre_omapgetvals, soid.oid.name.c_str(), soid.snap.val, start_after.c_str(), max_return, filter_prefix.c_str());
map<string, bufferlist> out_set;
- if (!pool.info.require_rollback()) {
+ if (pool.info.supports_omap()) {
ObjectMap::ObjectMapIterator iter = osd->store->get_omap_iterator(
- coll, soid
+ coll, ghobject_t(soid)
);
if (!iter) {
result = -ENOENT;
}
tracepoint(osd, do_osd_op_pre_omapgetvalsbykeys, soid.oid.name.c_str(), soid.snap.val, list_entries(keys_to_get).c_str());
map<string, bufferlist> out;
- if (!pool.info.require_rollback()) {
+ if (pool.info.supports_omap()) {
- osd->store->omap_get_values(coll, soid, keys_to_get, &out);
+ osd->store->omap_get_values(coll, ghobject_t(soid), keys_to_get, &out);
} // else return empty omap entries
::encode(out, osd_op.outdata);
ctx->delta_stats.num_rd_kb += SHIFT_ROUND_UP(osd_op.outdata.length(), 10);
ReadOp(int n,
RadosTestContext *context,
const string &oid,
+ bool balance_reads,
TestOpStat *stat = 0)
: TestOp(n, context, stat),
- completion(NULL),
+ completions(3),
oid(oid),
snap(0),
- retval(0),
+ balance_reads(balance_reads),
+ results(3),
+ retvals(3),
+ waiting_on(0),
attrretval(0)
{}
op.omap_get_header(&header, 0);
}
op.getxattrs(&xattrs, 0);
- assert(!context->io_ctx.aio_operate(context->prefix+oid, completions[0], &op, 0));
++
+ unsigned flags = 0;
+ if (balance_reads)
+ flags |= librados::OPERATION_BALANCE_READS;
- assert(!context->io_ctx.aio_operate(context->prefix+oid, completion, &op,
++
++ assert(!context->io_ctx.aio_operate(context->prefix+oid, completions[0], &op,
+ flags, NULL));
+ waiting_on++;
+
+ // send 2 pipelined reads on the same object/snap. This can help testing
+ // OSD's read behavior in some scenarios
+ for (uint32_t i = 1; i < 3; ++i) {
+ librados::ObjectReadOperation pipeline_op;
+
+ pipeline_op.read(0,
+ !old_value.has_contents() ? 0 :
+ old_value.most_recent_gen()->get_length(old_value.most_recent()),
+ &results[i],
+ &retvals[i]);
+ assert(!context->io_ctx.aio_operate(context->prefix+oid, completions[i], &pipeline_op, 0));
+ waiting_on++;
+ }
+
if (snap >= 0) {
context->io_ctx.snap_set_read(0);
}