mirror of
https://github.com/ceph/ceph
synced 2025-01-02 00:52:22 +00:00
osd/,rados/: modify TIER_FLUSH to implicitly make an object a manifest object
Existing object-dedup command always creates temporary object and perform set-chunk to make the input object manifest---this is because current tier-flush, which is called by object-dedup, works only if the target object is manifest, otherwise it just return 0. So, object-dedup may not work if the target is already manifest. Moreover, it causes unnecessary overhead if the target object is not manifest. To solve these, this commit makes existing tier-flush to change object's state to manifest implicitly. With this change, the only required operation when calling object-dedup is a tier-flush and object-dedup can work with the manifest object. Signed-off-by: Myoungwon Oh <myoungwon.oh@samsung.com>
This commit is contained in:
parent
23eace17e0
commit
ea749df517
@ -316,6 +316,17 @@ function test_dedup_object()
|
||||
die "Scrub failed expecting bar is removed"
|
||||
fi
|
||||
|
||||
CHUNK_OID=$(echo -n "There HIHIHI" | sha1sum | awk '{print $1}')
|
||||
RESULT=$($DEDUP_TOOL --op dump-chunk-refs --chunk-pool $CHUNK_POOL --object $CHUNK_OID | grep bar)
|
||||
if [ -z "$RESULT" ] ; then
|
||||
$CEPH_TOOL osd pool delete $POOL $POOL --yes-i-really-really-mean-it
|
||||
$CEPH_TOOL osd pool delete $CHUNK_POOL $CHUNK_POOL --yes-i-really-really-mean-it
|
||||
die "Scrub failed expecting bar is removed"
|
||||
fi
|
||||
# rerun tier-flush
|
||||
|
||||
RESULT=$($DEDUP_TOOL --pool $POOL --op object-dedup --object bar --chunk-pool $CHUNK_POOL --fingerprint-algorithm sha1 --dedup-cdc-chunk-size 4096)
|
||||
|
||||
CHUNK_OID=$(echo -n "There HIHIHI" | sha1sum | awk '{print $1}')
|
||||
RESULT=$($DEDUP_TOOL --op dump-chunk-refs --chunk-pool $CHUNK_POOL --object $CHUNK_OID | grep bar)
|
||||
if [ -z "$RESULT" ] ; then
|
||||
|
@ -758,8 +758,11 @@ inline namespace v14_2_0 {
|
||||
void set_chunk(uint64_t src_offset, uint64_t src_length, const IoCtx& tgt_ioctx,
|
||||
std::string tgt_oid, uint64_t tgt_offset, int flag = 0);
|
||||
/**
|
||||
* flush a manifest tier object to backing tier; will block racing
|
||||
* updates.
|
||||
* flush a manifest tier object to backing tier, performing deduplication;
|
||||
* will block racing updates.
|
||||
*
|
||||
* Invoking tier_flush() implicitly makes a manifest object even if
|
||||
* the target object is not manifest.
|
||||
*/
|
||||
void tier_flush();
|
||||
/**
|
||||
|
@ -7388,13 +7388,9 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
|
||||
result = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
if (!obs.oi.has_manifest()) {
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (oi.is_dirty()) {
|
||||
result = start_flush(ctx->op, ctx->obc, true, NULL, std::nullopt);
|
||||
if (oi.is_dirty() || !obs.oi.has_manifest()) {
|
||||
result = start_flush(ctx->op, ctx->obc, true, NULL, std::nullopt, true);
|
||||
if (result == -EINPROGRESS)
|
||||
result = -EAGAIN;
|
||||
} else {
|
||||
@ -10675,6 +10671,11 @@ int PrimaryLogPG::finish_set_dedup(hobject_t oid, int r, ceph_tid_t tid, uint64_
|
||||
ctx->new_obs = obc->obs;
|
||||
ctx->new_obs.oi.clear_flag(object_info_t::FLAG_DIRTY);
|
||||
--ctx->delta_stats.num_objects_dirty;
|
||||
if (!ctx->obs->oi.has_manifest()) {
|
||||
ctx->delta_stats.num_objects_manifest++;
|
||||
ctx->new_obs.oi.set_flag(object_info_t::FLAG_MANIFEST);
|
||||
ctx->new_obs.oi.manifest.type = object_manifest_t::TYPE_CHUNKED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Let's assume that there is a manifest snapshotted object, and we issue tier_flush() to head.
|
||||
@ -10756,7 +10757,8 @@ int PrimaryLogPG::finish_set_manifest_refcount(hobject_t oid, int r, ceph_tid_t
|
||||
int PrimaryLogPG::start_flush(
|
||||
OpRequestRef op, ObjectContextRef obc,
|
||||
bool blocking, hobject_t *pmissing,
|
||||
std::optional<std::function<void()>> &&on_flush)
|
||||
std::optional<std::function<void()>> &&on_flush,
|
||||
bool force_dedup)
|
||||
{
|
||||
const object_info_t& oi = obc->obs.oi;
|
||||
const hobject_t& soid = oi.soid;
|
||||
@ -10778,7 +10780,8 @@ int PrimaryLogPG::start_flush(
|
||||
snapset = obc->ssc->snapset;
|
||||
}
|
||||
|
||||
if (obc->obs.oi.has_manifest() && obc->obs.oi.manifest.is_chunked()) {
|
||||
if ((obc->obs.oi.has_manifest() && obc->obs.oi.manifest.is_chunked())
|
||||
|| force_dedup) {
|
||||
// current dedup tier only supports blocking operation
|
||||
if (!blocking) {
|
||||
return -EOPNOTSUPP;
|
||||
@ -10854,7 +10857,8 @@ int PrimaryLogPG::start_flush(
|
||||
osd->objecter->op_cancel(tids, -ECANCELED);
|
||||
}
|
||||
|
||||
if (obc->obs.oi.has_manifest() && obc->obs.oi.manifest.is_chunked()) {
|
||||
if ((obc->obs.oi.has_manifest() && obc->obs.oi.manifest.is_chunked())
|
||||
|| force_dedup) {
|
||||
int r = start_dedup(op, obc);
|
||||
if (r != -EINPROGRESS) {
|
||||
if (blocking)
|
||||
|
@ -1356,7 +1356,8 @@ protected:
|
||||
int start_flush(
|
||||
OpRequestRef op, ObjectContextRef obc,
|
||||
bool blocking, hobject_t *pmissing,
|
||||
std::optional<std::function<void()>> &&on_flush);
|
||||
std::optional<std::function<void()>> &&on_flush,
|
||||
bool force_dedup = false);
|
||||
void finish_flush(hobject_t oid, ceph_tid_t tid, int r);
|
||||
int try_flush_mark_clean(FlushOpRef fop);
|
||||
void cancel_flush(FlushOpRef fop, bool requeue, std::vector<ceph_tid_t> *tids);
|
||||
|
@ -1126,61 +1126,17 @@ int make_dedup_object(const po::variables_map &opts)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: add a better way to make an object a manifest object.
|
||||
* We're using set_chunk with an incorrect object here simply to make
|
||||
* the object a manifest object, the tier_flush() will remove
|
||||
* it and replace it with the real contents.
|
||||
*/
|
||||
// convert object to manifest object
|
||||
auto create_new_deduped_object =
|
||||
[&chunk_io_ctx, &io_ctx](string object_name) -> int {
|
||||
|
||||
int ret = 0;
|
||||
ObjectWriteOperation op;
|
||||
bufferlist temp;
|
||||
temp.append("temp");
|
||||
op.write_full(temp);
|
||||
|
||||
auto gen_r_num = [] () -> string {
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<uint64_t> dist;
|
||||
uint64_t r_num = dist(gen);
|
||||
return to_string(r_num);
|
||||
};
|
||||
string temp_oid = gen_r_num();
|
||||
// create temp chunk object for set-chunk
|
||||
ret = chunk_io_ctx.operate(temp_oid, &op);
|
||||
if (ret == -EEXIST) {
|
||||
// one more try
|
||||
temp_oid = gen_r_num();
|
||||
ret = chunk_io_ctx.operate(temp_oid, &op);
|
||||
}
|
||||
if (ret < 0) {
|
||||
cerr << " operate fail : " << cpp_strerror(ret) << std::endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// set-chunk to make manifest object
|
||||
ObjectReadOperation chunk_op;
|
||||
chunk_op.set_chunk(0, 4, chunk_io_ctx, temp_oid, 0,
|
||||
CEPH_OSD_OP_FLAG_WITH_REFERENCE);
|
||||
ret = io_ctx.operate(object_name, &chunk_op, NULL);
|
||||
if (ret < 0) {
|
||||
cerr << " set_chunk fail : " << cpp_strerror(ret) << std::endl;
|
||||
return ret;
|
||||
}
|
||||
[&io_ctx](string object_name) -> int {
|
||||
|
||||
// tier-flush to perform deduplication
|
||||
ObjectReadOperation flush_op;
|
||||
flush_op.tier_flush();
|
||||
ret = io_ctx.operate(object_name, &flush_op, NULL);
|
||||
int ret = io_ctx.operate(object_name, &flush_op, NULL);
|
||||
if (ret < 0) {
|
||||
cerr << " tier_flush fail : " << cpp_strerror(ret) << std::endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// tier-evict
|
||||
ObjectReadOperation evict_op;
|
||||
evict_op.tier_evict();
|
||||
|
Loading…
Reference in New Issue
Block a user