]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: store obj pg version in the object's head
authorYehuda Sadeh <yehuda@redhat.com>
Wed, 23 Dec 2015 18:38:57 +0000 (10:38 -0800)
committerYehuda Sadeh <yehuda@redhat.com>
Fri, 12 Feb 2016 00:13:48 +0000 (16:13 -0800)
this is done atomically when object is written, will allow us
to determine whether object is newer or not.

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/cls/rgw/cls_rgw.cc
src/cls/rgw/cls_rgw_client.cc
src/cls/rgw/cls_rgw_client.h
src/cls/rgw/cls_rgw_ops.h
src/rgw/rgw_common.h
src/rgw/rgw_rados.cc

index 9414d338ef11f35b8f7f9a5071d77e3d02cbe2d2..d109819489c07aeb76adc3c1d69d61c8284ed350 100644 (file)
@@ -36,6 +36,7 @@ cls_method_handle_t h_rgw_bucket_read_olh_log;
 cls_method_handle_t h_rgw_bucket_trim_olh_log;
 cls_method_handle_t h_rgw_bucket_clear_olh;
 cls_method_handle_t h_rgw_obj_remove;
+cls_method_handle_t h_rgw_obj_store_pg_ver;
 cls_method_handle_t h_rgw_obj_check_attrs_prefix;
 cls_method_handle_t h_rgw_obj_check_mtime;
 cls_method_handle_t h_rgw_bi_get_op;
@@ -1987,6 +1988,30 @@ static int rgw_obj_remove(cls_method_context_t hctx, bufferlist *in, bufferlist
   return 0;
 }
 
+static int rgw_obj_store_pg_ver(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+  // decode request
+  rgw_cls_obj_store_pg_ver_op op;
+  bufferlist::iterator iter = in->begin();
+  try {
+    ::decode(op, iter);
+  } catch (buffer::error& err) {
+    CLS_LOG(0, "ERROR: %s(): failed to decode request", __func__);
+    return -EINVAL;
+  }
+
+  bufferlist bl;
+  uint64_t ver = cls_current_version(hctx);
+  ::encode(ver, bl);
+  int ret = cls_cxx_setxattr(hctx, op.attr.c_str(), &bl);
+  if (ret < 0) {
+    CLS_LOG(0, "ERROR: %s(): cls_cxx_setxattr (attr=%s) returned %d", __func__, op.attr.c_str(), ret);
+    return ret;
+  }
+
+  return 0;
+}
+
 static int rgw_obj_check_attrs_prefix(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
 {
   // decode request
@@ -3133,6 +3158,7 @@ void __cls_init()
   cls_register_cxx_method(h_class, "bucket_clear_olh", CLS_METHOD_RD | CLS_METHOD_WR, rgw_bucket_clear_olh, &h_rgw_bucket_clear_olh);
 
   cls_register_cxx_method(h_class, "obj_remove", CLS_METHOD_RD | CLS_METHOD_WR, rgw_obj_remove, &h_rgw_obj_remove);
+  cls_register_cxx_method(h_class, "obj_store_pg_ver", CLS_METHOD_WR, rgw_obj_store_pg_ver, &h_rgw_obj_store_pg_ver);
   cls_register_cxx_method(h_class, "obj_check_attrs_prefix", CLS_METHOD_RD, rgw_obj_check_attrs_prefix, &h_rgw_obj_check_attrs_prefix);
   cls_register_cxx_method(h_class, "obj_check_mtime", CLS_METHOD_RD, rgw_obj_check_mtime, &h_rgw_obj_check_mtime);
 
index cfd71a887a3d97ed06ee39b34642825b2fed8242..c2847741713ae49ed6f4839e4086d7caed891a80 100644 (file)
@@ -208,6 +208,15 @@ void cls_rgw_remove_obj(librados::ObjectWriteOperation& o, list<string>& keep_at
   o.exec("rgw", "obj_remove", in);
 }
 
+void cls_rgw_obj_store_pg_ver(librados::ObjectWriteOperation& o, const string& attr)
+{
+  bufferlist in;
+  struct rgw_cls_obj_store_pg_ver_op call;
+  call.attr = attr;
+  ::encode(call, in);
+  o.exec("rgw", "obj_store_pg_ver", in);
+}
+
 void cls_rgw_obj_check_attrs_prefix(librados::ObjectOperation& o, const string& prefix, bool fail_if_exist)
 {
   bufferlist in;
index 3131ad61d50dea7db1bccce6cc75811aa28387da..6d136a9202aee75845aba689375391598eba99cd 100644 (file)
@@ -315,6 +315,7 @@ void cls_rgw_bucket_complete_op(librados::ObjectWriteOperation& o, RGWModifyOp o
                                 uint16_t bilog_op);
 
 void cls_rgw_remove_obj(librados::ObjectWriteOperation& o, list<string>& keep_attr_prefixes);
+void cls_rgw_obj_store_pg_ver(librados::ObjectWriteOperation& o, const string& attr);
 void cls_rgw_obj_check_attrs_prefix(librados::ObjectOperation& o, const string& prefix, bool fail_if_exist);
 void cls_rgw_obj_check_mtime(librados::ObjectOperation& o, const utime_t& mtime, RGWCheckMTimeType type);
 
index fb0dbfe38808611d853b47affd1448b9d1f668f3..1c8f96bff2432d71eb1a83695d274bad909a068f 100644 (file)
@@ -437,6 +437,23 @@ struct rgw_cls_obj_remove_op {
 };
 WRITE_CLASS_ENCODER(rgw_cls_obj_remove_op)
 
+struct rgw_cls_obj_store_pg_ver_op {
+  string attr;
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(attr, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(attr, bl);
+    DECODE_FINISH(bl);
+  }
+};
+WRITE_CLASS_ENCODER(rgw_cls_obj_store_pg_ver_op)
+
 struct rgw_cls_obj_check_attrs_prefix {
   string check_prefix;
   bool fail_if_exist;
index 981045c8b634cded90deb47452564e15d801fbfe..ed82e87004ea6062512a15c56cc9d423ad5d10cc 100644 (file)
@@ -81,6 +81,8 @@ using ceph::crypto::MD5;
  * user through custom HTTP header named X-Static-Large-Object. */
 #define RGW_ATTR_SLO_UINDICATOR RGW_ATTR_META_PREFIX "static-large-object"
 
+#define RGW_ATTR_PG_VER        RGW_ATTR_PREFIX "pg_ver"
+
 #define RGW_ATTR_TEMPURL_KEY1   RGW_ATTR_META_PREFIX "temp-url-key"
 #define RGW_ATTR_TEMPURL_KEY2   RGW_ATTR_META_PREFIX "temp-url-key-2"
 
index 94fe5653effe087b30197b6cb3eb75c0b31015b8..4da29aa148dc428fb857a427ff399fb749eb5132 100644 (file)
@@ -5648,6 +5648,9 @@ int RGWRados::Object::Write::write_meta(uint64_t size,
       acl_bl = bl;
     }
   }
+  if (attrs.find(RGW_ATTR_PG_VER) == attrs.end()) {
+    cls_rgw_obj_store_pg_ver(op, RGW_ATTR_PG_VER);
+  }
 
   if (!op.size())
     return 0;
@@ -6406,6 +6409,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
 
   set_copy_attrs(src_attrs, attrs, attrs_mod);
   attrs.erase(RGW_ATTR_ID_TAG);
+  attrs.erase(RGW_ATTR_PG_VER);
 
   RGWObjManifest manifest;
   RGWObjState *astate = NULL;