Current extensible tier flush a chunked object when all chunks mark as dirty.
So, to make the state of object consistent, tier-flush operation is needed.
Signed-off-by: Myoungwon Oh <omwmw@sk.com>
rados -p base_pool unset-manifest <obj-name>
+* tier-flush
+
+ flush the object that has chunks to the chunk pool. ::
+
+ rados -p base_pool tier-flush <obj-name>
Dedup tool
==========
f(SET_CHUNK, __CEPH_OSD_OP(WR, DATA, 40), "set-chunk") \
f(TIER_PROMOTE, __CEPH_OSD_OP(WR, DATA, 41), "tier-promote") \
f(UNSET_MANIFEST, __CEPH_OSD_OP(WR, DATA, 42), "unset-manifest") \
+ f(TIER_FLUSH, __CEPH_OSD_OP(WR, DATA, 43), "tier-flush") \
\
/** attrs **/ \
/* read */ \
std::string tgt_oid, uint64_t tgt_offset, int flag = 0);
void tier_promote();
void unset_manifest();
+ void tier_flush();
friend class IoCtx;
o->unset_manifest();
}
+void librados::ObjectWriteOperation::tier_flush()
+{
+ ceph_assert(impl);
+ ::ObjectOperation *o = &impl->o;
+ o->tier_flush();
+}
+
void librados::ObjectWriteOperation::tmap_update(const bufferlist& cmdbl)
{
ceph_assert(impl);
if (op.op == CEPH_OSD_OP_SET_REDIRECT ||
op.op == CEPH_OSD_OP_SET_CHUNK ||
op.op == CEPH_OSD_OP_TIER_PROMOTE ||
- op.op == CEPH_OSD_OP_UNSET_MANIFEST) {
+ op.op == CEPH_OSD_OP_UNSET_MANIFEST ||
+ op.op == CEPH_OSD_OP_TIER_FLUSH) {
return cache_result_t::NOOP;
}
}
case CEPH_OSD_OP_CACHE_UNPIN:
case CEPH_OSD_OP_SET_REDIRECT:
case CEPH_OSD_OP_TIER_PROMOTE:
+ case CEPH_OSD_OP_TIER_FLUSH:
break;
default:
if (op.op & CEPH_OSD_OP_MODE_WR)
break;
+ case CEPH_OSD_OP_TIER_FLUSH:
+ ++ctx->num_write;
+ {
+ if (pool.info.is_tier()) {
+ result = -EINVAL;
+ break;
+ }
+ if (!obs.exists) {
+ result = -ENOENT;
+ break;
+ }
+ if (get_osdmap()->require_osd_release < ceph_release_t::octopus) {
+ result = -EOPNOTSUPP;
+ break;
+ }
+ if (!obs.oi.has_manifest()) {
+ result = 0;
+ break;
+ }
+
+ hobject_t missing;
+ bool is_dirty = false;
+ for (auto& p : ctx->obc->obs.oi.manifest.chunk_map) {
+ if (p.second.is_dirty()) {
+ is_dirty = true;
+ break;
+ }
+ }
+
+ if (is_dirty) {
+ result = start_flush(ctx->op, ctx->obc, true, NULL, std::nullopt);
+ if (result == -EINPROGRESS)
+ result = -EAGAIN;
+ } else {
+ result = 0;
+ }
+ }
+
+ break;
+
case CEPH_OSD_OP_UNSET_MANIFEST:
++ctx->num_write;
{
add_op(CEPH_OSD_OP_UNSET_MANIFEST);
}
+ void tier_flush() {
+ add_op(CEPH_OSD_OP_TIER_FLUSH);
+ }
+
void set_alloc_hint(uint64_t expected_object_size,
uint64_t expected_write_size,
uint32_t flags) {
" convert an object to chunked object\n"
" tier-promote <obj-name> promote the object to the base tier\n"
" unset-manifest <obj-name> unset redirect or chunked object\n"
+" tier-flush <obj-name> flush the chunked object\n"
"\n"
"IMPORT AND EXPORT\n"
" export [filename]\n"
<< cpp_strerror(ret) << std::endl;
return 1;
}
+ } else if (strcmp(nargs[0], "tier-flush") == 0) {
+ if (!pool_name || nargs.size() < 2) {
+ usage(cerr);
+ return 1;
+ }
+ string oid(nargs[1]);
+
+ ObjectWriteOperation op;
+ op.tier_flush();
+ ret = io_ctx.operate(oid, &op);
+ if (ret < 0) {
+ cerr << "error tier-flush " << pool_name << "/" << oid << " : "
+ << cpp_strerror(ret) << std::endl;
+ return 1;
+ }
} else if (strcmp(nargs[0], "export") == 0) {
// export [filename]
if (!pool_name || nargs.size() > 2) {