]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: a rados op to create a redirect
authormyoungwon oh <omwmw@sk.com>
Fri, 28 Apr 2017 07:00:04 +0000 (16:00 +0900)
committermyoungwon oh <omwmw@sk.com>
Sat, 6 May 2017 05:58:53 +0000 (14:58 +0900)
Signed-off-by: Myoungwon Oh omwmw@sk.com
src/include/rados.h
src/include/rados/librados.hpp
src/librados/librados.cc
src/osd/PrimaryLogPG.cc
src/osdc/Objecter.h
src/tools/rados/rados.cc

index 4eb09b89cc2eef68f71f62671c314a619a5776eb..b9adab6c3bb1c3d2a54cfa1033f521f7596e4641 100644 (file)
@@ -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")         \
index 5c1780c5595f170ae450a8ff79198e6ece71ec57..68f78ccb4da22358afd6a21932bc782f5b030116 100644 (file)
@@ -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;
   };
 
index 271ec3859e0a1bee969e27c4224e0544faa398de..04cf6cb361dd8b8fe774c1e9afa69c72c25d4b81 100644 (file)
@@ -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;
index c3a790ac6cd70051fc92ae64198fcf29d9ef189d..914dd381b4413020f1edfad9ee384aacd00bcebd 100644 (file)
@@ -4469,6 +4469,7 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& 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<OSDOp>& 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<string,bufferlist> rmattrs;
+       result = getattrs_maybe_cache(ctx->obc,
+                   &rmattrs,
+                   true);
+       if (result < 0) {
+         return result;
+       }
+       map<string, bufferlist>::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 --
       
index 980cdc7e0e8345571573e290fb798d0b126f2c7d..559d5e391ead8d8e8f8d6b29e55f7a338bb7a1cb 100644 (file)
@@ -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) {
index 9fc6442c34dbe3c34467a0eadc95313f0b1ade8d..5fc72b429e6b44c44a8467499b7682de8e66cc6a 100644 (file)
@@ -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) {