OSDOp& osd_op = *p;
ceph_osd_op& op = osd_op.op;
if (op.op == CEPH_OSD_OP_SET_REDIRECT ||
- op.op == CEPH_OSD_OP_SET_CHUNK) {
+ op.op == CEPH_OSD_OP_SET_CHUNK ||
+ op.op == CEPH_OSD_OP_TIER_PROMOTE) {
return cache_result_t::NOOP;
}
}
if (op->may_write() || write_ordered) {
do_proxy_write(op, obc);
} else {
+ // promoted object
+ if (obc->obs.oi.size != 0) {
+ return cache_result_t::NOOP;
+ }
do_proxy_read(op, obc);
}
return cache_result_t::HANDLED_PROXY;
ObjectContextRef obc;
PrimaryLogPG *pg;
utime_t start;
+ PrimaryLogPG::OpContext *ctx;
+ PrimaryLogPG::CopyCallbackResults promote_results;
public:
- PromoteManifestCallback(ObjectContextRef obc_, PrimaryLogPG *pg_)
+ PromoteManifestCallback(ObjectContextRef obc_, PrimaryLogPG *pg_, PrimaryLogPG::OpContext *ctx = NULL)
: obc(obc_),
pg(pg_),
- start(ceph_clock_now()) {}
+ start(ceph_clock_now()), ctx(ctx) {}
void finish(PrimaryLogPG::CopyCallbackResults results) override {
PrimaryLogPG::CopyResults *results_data = results.get<1>();
int r = results.get<0>();
- pg->finish_promote_manifest(r, results_data, obc);
+ if (ctx) {
+ promote_results = results;
+ pg->execute_ctx(ctx);
+ } else {
+ pg->finish_promote_manifest(r, results_data, obc);
+ }
pg->osd->logger->tinc(l_osd_tier_promote_lat, ceph_clock_now() - start);
}
+ friend struct PromoteFinisher;
+};
+
+struct PromoteFinisher : public PrimaryLogPG::OpFinisher {
+ PromoteManifestCallback *promote_callback;
+
+ PromoteFinisher(PromoteManifestCallback *promote_callback)
+ : promote_callback(promote_callback) {
+ }
+
+ int execute() override {
+ if (promote_callback->ctx->obc->obs.oi.manifest.is_redirect()) {
+ promote_callback->ctx->pg->finish_promote(promote_callback->promote_results.get<0>(),
+ promote_callback->promote_results.get<1>(),
+ promote_callback->obc);
+ } else if (promote_callback->ctx->obc->obs.oi.manifest.is_chunked()) {
+ promote_callback->ctx->pg->finish_promote_manifest(promote_callback->promote_results.get<0>(),
+ promote_callback->promote_results.get<1>(),
+ promote_callback->obc);
+ } else {
+ assert(0 == "unrecognized manifest type");
+ }
+ return 0;
+ }
};
void PrimaryLogPG::promote_object(ObjectContextRef obc,
}
CopyCallback *cb;
- object_locator_t my_oloc = oloc;
- my_oloc.pool = pool.info.tier_of;
+ object_locator_t my_oloc;
+ hobject_t src_hoid;
if (!obc->obs.oi.has_manifest()) {
+ my_oloc = oloc;
+ my_oloc.pool = pool.info.tier_of;
+ src_hoid = obc->obs.oi.soid;
cb = new PromoteCallback(obc, this);
} else {
if (obc->obs.oi.manifest.is_chunked()) {
+ src_hoid = obc->obs.oi.soid;
cb = new PromoteManifestCallback(obc, this);
+ } else if (obc->obs.oi.manifest.is_redirect()) {
+ object_locator_t src_oloc(obc->obs.oi.manifest.redirect_target);
+ my_oloc = src_oloc;
+ src_hoid = obc->obs.oi.manifest.redirect_target;
+ cb = new PromoteCallback(obc, this);
} else {
- assert(0);
+ assert(0 == "unrecognized manifest type");
}
}
CEPH_OSD_COPY_FROM_FLAG_IGNORE_CACHE |
CEPH_OSD_COPY_FROM_FLAG_MAP_SNAP_CLONE |
CEPH_OSD_COPY_FROM_FLAG_RWORDERED;
- start_copy(cb, obc, obc->obs.oi.soid, my_oloc, 0, flags,
+ start_copy(cb, obc, src_hoid, my_oloc, 0, flags,
obc->obs.oi.soid.snap == CEPH_NOSNAP,
src_fadvise_flags, 0);
break;
}
- object_locator_t tgt_oloc(obs.oi.soid);
- promote_object(ctx->obc, obs.oi.soid, tgt_oloc, ctx->op, NULL);
-
- dout(10) << "tier-promote oid:" << oi.soid << " manifest: " << obs.oi.manifest << dendl;
- result = -EAGAIN;
+ if (op_finisher == nullptr) {
+ PromoteManifestCallback *cb;
+ object_locator_t my_oloc;
+ hobject_t src_hoid;
+
+ if (obs.oi.manifest.is_chunked()) {
+ src_hoid = obs.oi.soid;
+ cb = new PromoteManifestCallback(ctx->obc, this, ctx);
+ } else if (obs.oi.manifest.is_redirect()) {
+ object_locator_t src_oloc(obs.oi.manifest.redirect_target);
+ my_oloc = src_oloc;
+ src_hoid = obs.oi.manifest.redirect_target;
+ cb = new PromoteManifestCallback(ctx->obc, this, ctx);
+ } else {
+ assert(0 == "unrecognized manifest type");
+ }
+ ctx->op_finishers[ctx->current_osd_subop_num].reset(
+ new PromoteFinisher(cb));
+ unsigned flags = CEPH_OSD_COPY_FROM_FLAG_IGNORE_OVERLAY |
+ CEPH_OSD_COPY_FROM_FLAG_IGNORE_CACHE |
+ CEPH_OSD_COPY_FROM_FLAG_MAP_SNAP_CLONE |
+ CEPH_OSD_COPY_FROM_FLAG_RWORDERED;
+ unsigned src_fadvise_flags = LIBRADOS_OP_FLAG_FADVISE_SEQUENTIAL;
+ start_copy(cb, ctx->obc, src_hoid, my_oloc, 0, flags,
+ obs.oi.soid.snap == CEPH_NOSNAP,
+ src_fadvise_flags, 0);
+
+ dout(10) << "tier-promote oid:" << oi.soid << " manifest: " << obs.oi.manifest << dendl;
+ result = -EINPROGRESS;
+ } else {
+ result = op_finisher->execute();
+ assert(result == 0);
+ ctx->op_finishers.erase(ctx->current_osd_subop_num);
+ }
}
break;
if (!obc->obs.oi.has_manifest()) {
_copy_some(obc, cop);
} else {
- auto p = obc->obs.oi.manifest.chunk_map.begin();
- _copy_some_manifest(obc, cop, p->first);
+ if (obc->obs.oi.manifest.is_redirect()) {
+ _copy_some(obc, cop);
+ } else if (obc->obs.oi.manifest.is_chunked()) {
+ auto p = obc->obs.oi.manifest.chunk_map.begin();
+ _copy_some_manifest(obc, cop, p->first);
+ } else {
+ assert(0 == "unrecognized manifest type");
+ }
}
}