From e2211a29e6661534a8dd3bdc23960c6f0a266826 Mon Sep 17 00:00:00 2001 From: myoungwon oh Date: Tue, 15 May 2018 17:36:42 +0900 Subject: [PATCH] osd,librados: add unset-manifest op Signed-off-by: Myoungwon Oh --- src/include/rados.h | 1 + src/include/rados/librados.hpp | 1 + src/librados/librados.cc | 6 ++++ src/osd/PrimaryLogPG.cc | 56 +++++++++++++++++++++++++++++++++- src/osdc/Objecter.h | 4 +++ src/tools/rados/rados.cc | 14 +++++++++ 6 files changed, 81 insertions(+), 1 deletion(-) diff --git a/src/include/rados.h b/src/include/rados.h index 959a76d12348e..15622c6fb9cef 100644 --- a/src/include/rados.h +++ b/src/include/rados.h @@ -314,6 +314,7 @@ extern int ceph_release_from_features(uint64_t features); f(SET_REDIRECT, __CEPH_OSD_OP(WR, DATA, 39), "set-redirect") \ 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") \ \ /** attrs **/ \ /* read */ \ diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp index 79fa156034873..53e2c4991478d 100644 --- a/src/include/rados/librados.hpp +++ b/src/include/rados/librados.hpp @@ -474,6 +474,7 @@ namespace librados 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); void tier_promote(); + void unset_manifest(); friend class IoCtx; diff --git a/src/librados/librados.cc b/src/librados/librados.cc index 77bc9ca9ad3bc..08c4379c4a63c 100644 --- a/src/librados/librados.cc +++ b/src/librados/librados.cc @@ -633,6 +633,12 @@ void librados::ObjectWriteOperation::tier_promote() o->tier_promote(); } +void librados::ObjectWriteOperation::unset_manifest() +{ + ::ObjectOperation *o = &impl->o; + o->unset_manifest(); +} + void librados::ObjectWriteOperation::tmap_put(const bufferlist &bl) { ::ObjectOperation *o = &impl->o; diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index 656eff8f17270..f402e4518df79 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -2420,7 +2420,8 @@ PrimaryLogPG::cache_result_t PrimaryLogPG::maybe_handle_manifest_detail( ceph_osd_op& op = osd_op.op; 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_TIER_PROMOTE || + op.op == CEPH_OSD_OP_UNSET_MANIFEST) { return cache_result_t::NOOP; } } @@ -6977,6 +6978,59 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector& ops) break; + case CEPH_OSD_OP_UNSET_MANIFEST: + ++ctx->num_write; + { + if (pool.info.is_tier()) { + result = -EINVAL; + break; + } + if (!obs.exists) { + result = -ENOENT; + break; + } + if (!oi.has_manifest()) { + result = -EOPNOTSUPP; + break; + } + if (get_osdmap()->require_osd_release < CEPH_RELEASE_LUMINOUS) { + result = -EOPNOTSUPP; + break; + } + + if (oi.manifest.is_redirect()) { + if ((oi.flags & object_info_t::FLAG_REDIRECT_HAS_REFERENCE)) { + ctx->register_on_commit( + [oi, ctx, this](){ + object_locator_t target_oloc(oi.manifest.redirect_target); + refcount_manifest(ctx->obc, target_oloc, oi.manifest.redirect_target, + SnapContext(), false, NULL, 0); + }); + } + } else if (oi.manifest.is_chunked()) { + ctx->register_on_commit( + [oi, ctx, this](){ + for (auto p : oi.manifest.chunk_map) { + if (p.second.flags & chunk_info_t::FLAG_HAS_REFERENCE) { + object_locator_t target_oloc(p.second.oid); + refcount_manifest(ctx->obc, target_oloc, p.second.oid, + SnapContext(), false, NULL, p.first); + } + } + }); + } else { + assert(0 == "unrecognized manifest type"); + } + + oi.clear_flag(object_info_t::FLAG_MANIFEST); + oi.manifest = object_manifest_t(); + ctx->delta_stats.num_objects_manifest--; + ctx->delta_stats.num_wr++; + ctx->modify = true; + } + + break; + // -- object attrs -- case CEPH_OSD_OP_SETXATTR: diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h index b37c5de90a03c..466bf49372d30 100644 --- a/src/osdc/Objecter.h +++ b/src/osdc/Objecter.h @@ -1156,6 +1156,10 @@ struct ObjectOperation { add_op(CEPH_OSD_OP_TIER_PROMOTE); } + void unset_manifest() { + add_op(CEPH_OSD_OP_UNSET_MANIFEST); + } + 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 4b21e8322d170..d14d6ac550893 100644 --- a/src/tools/rados/rados.cc +++ b/src/tools/rados/rados.cc @@ -131,6 +131,7 @@ void usage(ostream& out) " set-chunk --target-pool [--with-reference]\n" " 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" "\n" "IMPORT AND EXPORT\n" " export [filename]\n" @@ -3696,6 +3697,19 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, << cpp_strerror(ret) << std::endl; goto out; } + } else if (strcmp(nargs[0], "unset-manifest") == 0) { + if (!pool_name || nargs.size() < 2) + usage_exit(); + string oid(nargs[1]); + + ObjectWriteOperation op; + op.unset_manifest(); + ret = io_ctx.operate(oid, &op); + if (ret < 0) { + cerr << "error unset-manifest " << pool_name << "/" << oid << " : " + << cpp_strerror(ret) << std::endl; + goto out; + } } else if (strcmp(nargs[0], "export") == 0) { // export [filename] if (!pool_name || nargs.size() > 2) { -- 2.39.5