From: myoungwon oh Date: Fri, 28 Apr 2017 07:00:04 +0000 (+0900) Subject: osd: a rados op to create a redirect X-Git-Tag: v12.1.0~57^2~9^2~2^2~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6f6677910d6d1772404ef81545d43b534c16f412;p=ceph.git osd: a rados op to create a redirect Signed-off-by: Myoungwon Oh omwmw@sk.com --- diff --git a/src/include/rados.h b/src/include/rados.h index 4eb09b89cc2e..b9adab6c3bb1 100644 --- a/src/include/rados.h +++ b/src/include/rados.h @@ -272,6 +272,9 @@ extern const char *ceph_osd_state_name(int s); f(WRITESAME, __CEPH_OSD_OP(WR, DATA, 38), "write-same") \ f(CMPEXT, __CEPH_OSD_OP(RD, DATA, 32), "cmpext") \ \ + /* Extensible */ \ + f(SET_REDIRECT, __CEPH_OSD_OP(WR, DATA, 39), "set-redirect") \ + \ /** attrs **/ \ /* read */ \ f(GETXATTR, __CEPH_OSD_OP(RD, ATTR, 1), "getxattr") \ diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp index 5c1780c5595f..68f78ccb4da2 100644 --- a/src/include/rados/librados.hpp +++ b/src/include/rados/librados.hpp @@ -463,6 +463,14 @@ namespace librados void cache_pin(); void cache_unpin(); + /** + * Extensible tier + * + * Set redirect target + */ + void set_redirect(const std::string& tgt_obj, const IoCtx& tgt_ioctx, + uint64_t tgt_version); + friend class IoCtx; }; diff --git a/src/librados/librados.cc b/src/librados/librados.cc index 271ec3859e0a..04cf6cb361dd 100644 --- a/src/librados/librados.cc +++ b/src/librados/librados.cc @@ -605,6 +605,15 @@ void librados::ObjectReadOperation::cache_evict() o->cache_evict(); } +void librados::ObjectWriteOperation::set_redirect(const std::string& tgt_obj, + const IoCtx& tgt_ioctx, + uint64_t tgt_version) +{ + ::ObjectOperation *o = &impl->o; + o->set_redirect(object_t(tgt_obj), tgt_ioctx.io_ctx_impl->snap_seq, + tgt_ioctx.io_ctx_impl->oloc, tgt_version); +} + 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 c3a790ac6cd7..914dd381b441 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -4469,6 +4469,7 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector& ops) case CEPH_OSD_OP_COPY_FROM: // we handle user_version update explicitly case CEPH_OSD_OP_CACHE_PIN: case CEPH_OSD_OP_CACHE_UNPIN: + case CEPH_OSD_OP_SET_REDIRECT: break; default: if (op.op & CEPH_OSD_OP_MODE_WR) @@ -5703,6 +5704,65 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector& ops) } break; + case CEPH_OSD_OP_SET_REDIRECT: + ++ctx->num_write; + { + if (pool.info.is_tier()) { + result = -EINVAL; + break; + } + object_t target_name; + object_locator_t target_oloc; + snapid_t target_snapid = (uint64_t)op.copy_from.snapid; + version_t target_version = op.copy_from.src_version; + try { + ::decode(target_name, bp); + ::decode(target_oloc, bp); + } + catch (buffer::error& e) { + result = -EINVAL; + goto fail; + } + pg_t raw_pg; + get_osdmap()->object_locator_to_pg(target_name, target_oloc, raw_pg); + hobject_t target(target_name, target_oloc.key, target_snapid, + raw_pg.ps(), raw_pg.pool(), + target_oloc.nspace); + if (target == soid) { + dout(20) << " set-redirect self is invalid" << dendl; + result = -EINVAL; + break; + } + oi.manifest.redirect_target = target; + oi.manifest.type = object_manifest_t::TYPE_REDIRECT; + t->truncate(soid, 0); + if (oi.is_omap() && pool.info.supports_omap()) { + t->omap_clear(soid); + obs.oi.clear_omap_digest(); + obs.oi.clear_flag(object_info_t::FLAG_OMAP); + } + ctx->delta_stats.num_bytes -= oi.size; + oi.size = 0; + oi.new_object(); + oi.user_version = target_version; + ctx->user_at_version = target_version; + /* rm_attrs */ + map rmattrs; + result = getattrs_maybe_cache(ctx->obc, + &rmattrs, + true); + if (result < 0) { + return result; + } + map::iterator iter; + for (iter = rmattrs.begin(); iter != rmattrs.end(); ++iter) { + const string& name = iter->first; + t->rmattr(soid, name); + } + dout(10) << "set-redirect oid:" << oi.soid << " user_version: " << oi.user_version << dendl; + } + + break; // -- object attrs -- diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h index 980cdc7e0e83..559d5e391ead 100644 --- a/src/osdc/Objecter.h +++ b/src/osdc/Objecter.h @@ -1122,6 +1122,18 @@ struct ObjectOperation { add_op(CEPH_OSD_OP_CACHE_EVICT); } + /* + * Extensible tier + */ + void set_redirect(object_t tgt, snapid_t snapid, object_locator_t tgt_oloc, + version_t tgt_version) { + OSDOp& osd_op = add_op(CEPH_OSD_OP_SET_REDIRECT); + osd_op.op.copy_from.snapid = snapid; + osd_op.op.copy_from.src_version = tgt_version; + ::encode(tgt, osd_op.indata); + ::encode(tgt_oloc, osd_op.indata); + } + 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 9fc6442c34db..5fc72b429e6b 100644 --- a/src/tools/rados/rados.cc +++ b/src/tools/rados/rados.cc @@ -3422,6 +3422,42 @@ 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], "set-redirect") == 0) { + if (!pool_name) + usage_exit(); + + const char *target = target_pool_name; + if (!target) + target = pool_name; + + const char *target_obj; + if (nargs.size() < 3) { + if (strcmp(target, pool_name) == 0) { + cerr << "cannot copy object into itself" << std::endl; + ret = -1; + goto out; + } + target_obj = nargs[1]; + } else { + target_obj = nargs[2]; + } + + IoCtx target_ctx; + ret = rados.ioctx_create(target, target_ctx); + if (target_oloc.size()) { + target_ctx.locator_set_key(target_oloc); + } + if (target_nspace.size()) { + target_ctx.set_namespace(target_nspace); + } + + ObjectWriteOperation op; + op.set_redirect(target_obj, target_ctx, 0); + ret = io_ctx.operate(nargs[1], &op); + if (ret < 0) { + cerr << "error set-redirect " << pool_name << "/" << nargs[1] << " => " << target << "/" << target_obj << ": " << cpp_strerror(ret) << std::endl; + goto out; + } } else if (strcmp(nargs[0], "export") == 0) { // export [filename] if (!pool_name || nargs.size() > 2) {