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
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();
/**
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 {
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.
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;
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;
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)
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);
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();