From: myoungwon oh Date: Fri, 28 Jun 2019 09:47:56 +0000 (+0900) Subject: src/osd: add tier_flush operation X-Git-Tag: v15.1.0~2104^2~4 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=a0af9f70911a31b194a27b4a7b95a036111e5abf;p=ceph-ci.git src/osd: add tier_flush operation 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 --- diff --git a/doc/dev/deduplication.rst b/doc/dev/deduplication.rst index 62b487d3c64..4a4c611d48a 100644 --- a/doc/dev/deduplication.rst +++ b/doc/dev/deduplication.rst @@ -173,6 +173,11 @@ Interface rados -p base_pool unset-manifest +* tier-flush + + flush the object that has chunks to the chunk pool. :: + + rados -p base_pool tier-flush Dedup tool ========== diff --git a/src/include/rados.h b/src/include/rados.h index ca26a1941ee..f9aa1d526c4 100644 --- a/src/include/rados.h +++ b/src/include/rados.h @@ -315,6 +315,7 @@ extern const char *ceph_osd_state_name(int s); 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 */ \ diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp index cbce2e0bd45..ff31fe54e28 100644 --- a/src/include/rados/librados.hpp +++ b/src/include/rados/librados.hpp @@ -493,6 +493,7 @@ inline namespace v14_2_0 { std::string tgt_oid, uint64_t tgt_offset, int flag = 0); void tier_promote(); void unset_manifest(); + void tier_flush(); friend class IoCtx; diff --git a/src/librados/librados_cxx.cc b/src/librados/librados_cxx.cc index 4dc75a8900b..c3e1b1b5700 100644 --- a/src/librados/librados_cxx.cc +++ b/src/librados/librados_cxx.cc @@ -653,6 +653,13 @@ void librados::ObjectWriteOperation::unset_manifest() 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); diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index 9f5491616c2..ad6f9950b6d 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -2277,7 +2277,8 @@ PrimaryLogPG::cache_result_t PrimaryLogPG::maybe_handle_manifest_detail( 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; } } @@ -5612,6 +5613,7 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector& ops) 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) @@ -6967,6 +6969,46 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector& ops) 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; { diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h index b428ecc5217..90e1bd725cd 100644 --- a/src/osdc/Objecter.h +++ b/src/osdc/Objecter.h @@ -1174,6 +1174,10 @@ struct ObjectOperation { 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) { diff --git a/src/tools/rados/rados.cc b/src/tools/rados/rados.cc index 37c6d3352e0..79c390a5f45 100644 --- a/src/tools/rados/rados.cc +++ b/src/tools/rados/rados.cc @@ -131,6 +131,7 @@ void usage(ostream& out) " convert an object to chunked object\n" " tier-promote promote the object to the base tier\n" " unset-manifest unset redirect or chunked object\n" +" tier-flush flush the chunked object\n" "\n" "IMPORT AND EXPORT\n" " export [filename]\n" @@ -3770,6 +3771,21 @@ 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-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) {