// dup/replay?
if (op->may_write() || op->may_cache()) {
+ // warning: we will get back *a* request for this reqid, but not
+ // necessarily the most recent. this happens with flush and
+ // promote ops, but we can't possible have both in our log where
+ // the original request is still not stable on disk, so for our
+ // purposes here it doesn't matter which one we get.
const pg_log_entry_t *entry = pg_log.get_log().get_request(m->get_reqid());
if (entry) {
const eversion_t& oldv = entry->version;
}
ctx->log.back().mod_desc.claim(ctx->mod_desc);
+ if (!ctx->extra_reqids.empty()) {
+ dout(20) << __func__ << " extra_reqids " << ctx->extra_reqids << dendl;
+ ctx->log.back().extra_reqids.swap(ctx->extra_reqids);
+ }
// apply new object state.
ctx->obc->obs = ctx->new_obs;
}
}
+ if (cursor.is_complete()) {
+ // include reqids only in the final step. this is a bit fragile
+ // but it works...
+ pg_log.get_log().get_object_reqids(ctx->obc->obs.oi.soid, 10, &reply_obj.reqids);
+ dout(20) << " got reqids" << dendl;
+ }
+
dout(20) << " cursor.is_complete=" << cursor.is_complete()
<< " " << out_attrs.size() << " attrs"
<< " " << bl.length() << " bytes"
<< " " << reply_obj.omap_header.length() << " omap header bytes"
<< " " << reply_obj.omap_data.length() << " omap data bytes in "
<< omap_keys << " keys"
+ << " " << reply_obj.reqids.size() << " reqids"
<< dendl;
reply_obj.cursor = cursor;
if (!async_read_started) {
&cop->results.flags,
&cop->results.source_data_digest,
&cop->results.source_omap_digest,
+ &cop->results.reqids,
&cop->rval);
C_Copyfrom *fin = new C_Copyfrom(this, obc->obs.oi.soid,
obs.oi.set_data_digest(cb->results->data_digest);
obs.oi.set_omap_digest(cb->results->omap_digest);
+ ctx->extra_reqids = cb->results->reqids;
+
// cache: clear whiteout?
if (obs.oi.is_whiteout()) {
dout(10) << __func__ << " clearing whiteout on " << obs.oi.soid << dendl;
++tctx->delta_stats.num_object_clones;
tctx->new_obs.exists = true;
+ tctx->extra_reqids = results->reqids;
+
if (whiteout) {
// create a whiteout
tctx->op_t->touch(soid);
uint32_t flags; // object_copy_data_t::FLAG_*
uint32_t source_data_digest, source_omap_digest;
uint32_t data_digest, omap_digest;
+ vector<osd_reqid_t> reqids;
bool is_data_digest() {
return flags & object_copy_data_t::FLAG_DATA_DIGEST;
}
int num_read; ///< count read ops
int num_write; ///< count update ops
+ vector<osd_reqid_t> extra_reqids;
+
CopyFromCallback *copy_cb;
hobject_t new_temp_oid, discard_temp_oid; ///< temp objects we should start/stop tracking
uint32_t *out_flags;
uint32_t *out_data_digest;
uint32_t *out_omap_digest;
+ vector<osd_reqid_t> *out_reqids;
int *prval;
C_ObjectOperation_copyget(object_copy_cursor_t *c,
uint64_t *s,
uint32_t *flags,
uint32_t *dd,
uint32_t *od,
+ vector<osd_reqid_t> *oreqids,
int *r)
: cursor(c),
out_size(s), out_mtime(m),
out_attrs(a), out_data(d), out_omap_header(oh),
out_omap_data(o), out_snaps(osnaps), out_snap_seq(osnap_seq),
out_flags(flags), out_data_digest(dd), out_omap_digest(od),
- prval(r) {}
+ out_reqids(oreqids), prval(r) {}
void finish(int r) {
if (r < 0)
return;
*out_data_digest = copy_reply.data_digest;
if (out_omap_digest)
*out_omap_digest = copy_reply.omap_digest;
+ if (out_reqids)
+ *out_reqids = copy_reply.reqids;
*cursor = copy_reply.cursor;
} catch (buffer::error& e) {
if (prval)
uint32_t *out_flags,
uint32_t *out_data_digest,
uint32_t *out_omap_digest,
+ vector<osd_reqid_t> *out_reqids,
int *prval) {
OSDOp& osd_op = add_op(CEPH_OSD_OP_COPY_GET);
osd_op.op.copy_get.max = max;
out_attrs, out_data, out_omap_header,
out_omap_data, out_snaps, out_snap_seq,
out_flags, out_data_digest, out_omap_digest,
- prval);
+ out_reqids, prval);
out_bl[p] = &h->bl;
out_handler[p] = h;
}