osd: add tier_evict for manifest tier

Truncate the object size to 0 if the mainfest object is composed of chunks.

Signed-off-by: Myoungwon Oh <myoungwon.oh@samsung.com>
This commit is contained in:
myoungwon oh 2020-09-14 15:07:01 +09:00
parent 5865352387
commit 3e429a0362
6 changed files with 86 additions and 1 deletions

View File

@ -327,6 +327,7 @@ extern const char *ceph_osd_state_name(int s);
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(CACHE, DATA, 43), "tier-flush") \
f(TIER_EVICT, __CEPH_OSD_OP(CACHE, DATA, 44), "tier-evict") \
\
/** attrs **/ \
/* read */ \

View File

@ -753,6 +753,11 @@ inline namespace v14_2_0 {
* updates.
*/
void tier_flush();
/**
* evict a manifest tier object to backing tier; will block racing
* updates.
*/
void tier_evict();
};
/* IoCtx : This is a context in which we can perform I/O.

View File

@ -638,6 +638,13 @@ void librados::ObjectReadOperation::tier_flush()
o->tier_flush();
}
void librados::ObjectReadOperation::tier_evict()
{
ceph_assert(impl);
::ObjectOperation *o = &impl->o;
o->tier_evict();
}
void librados::ObjectWriteOperation::set_redirect(const std::string& tgt_obj,
const IoCtx& tgt_ioctx,
uint64_t tgt_version,

View File

@ -2375,7 +2375,8 @@ PrimaryLogPG::cache_result_t PrimaryLogPG::maybe_handle_manifest_detail(
op.op == CEPH_OSD_OP_SET_CHUNK ||
op.op == CEPH_OSD_OP_UNSET_MANIFEST ||
op.op == CEPH_OSD_OP_TIER_PROMOTE ||
op.op == CEPH_OSD_OP_TIER_FLUSH) {
op.op == CEPH_OSD_OP_TIER_FLUSH ||
op.op == CEPH_OSD_OP_TIER_EVICT) {
return cache_result_t::NOOP;
}
}
@ -5655,6 +5656,7 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
case CEPH_OSD_OP_SET_CHUNK:
case CEPH_OSD_OP_TIER_PROMOTE:
case CEPH_OSD_OP_TIER_FLUSH:
case CEPH_OSD_OP_TIER_EVICT:
break;
default:
if (op.op & CEPH_OSD_OP_MODE_WR)
@ -7038,6 +7040,48 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
break;
case CEPH_OSD_OP_TIER_EVICT:
++ctx->num_write;
result = 0;
{
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 = -EINVAL;
break;
}
// The chunks already has a reference, so it is just enough to invoke truncate if necessary
uint64_t chunk_length = 0;
for (auto p : obs.oi.manifest.chunk_map) {
chunk_length += p.second.length;
}
if (chunk_length == obs.oi.size) {
// truncate
for (auto p : obs.oi.manifest.chunk_map) {
p.second.set_flag(chunk_info_t::FLAG_MISSING);
}
t->truncate(obs.oi.soid, 0);
ctx->delta_stats.num_bytes -= obs.oi.size;
ctx->delta_stats.num_wr++;
oi.size = 0;
ctx->cache_operation = true;
}
osd->logger->inc(l_osd_tier_evict);
}
break;
case CEPH_OSD_OP_UNSET_MANIFEST:
++ctx->num_write;
result = 0;

View File

@ -1557,6 +1557,10 @@ struct ObjectOperation {
add_op(CEPH_OSD_OP_TIER_FLUSH);
}
void tier_evict() {
add_op(CEPH_OSD_OP_TIER_EVICT);
}
void set_alloc_hint(uint64_t expected_object_size,
uint64_t expected_write_size,
uint32_t flags) {

View File

@ -132,6 +132,7 @@ void usage(ostream& out)
" 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"
" tier-evict <obj-name> evict the chunked object\n"
"\n"
"IMPORT AND EXPORT\n"
" export [filename]\n"
@ -3820,6 +3821,29 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
<< cpp_strerror(ret) << std::endl;
return 1;
}
} else if (strcmp(nargs[0], "tier-evict") == 0) {
if (!pool_name || nargs.size() < 2) {
usage(cerr);
return 1;
}
string oid(nargs[1]);
ObjectReadOperation op;
op.tier_evict();
librados::AioCompletion *completion =
librados::Rados::aio_create_completion();
io_ctx.aio_operate(oid.c_str(), completion, &op,
librados::OPERATION_IGNORE_CACHE |
librados::OPERATION_IGNORE_OVERLAY,
NULL);
completion->wait_for_complete();
ret = completion->get_return_value();
completion->release();
if (ret < 0) {
cerr << "error tier-evict " << 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) {