From: Yehuda Sadeh Date: Wed, 23 Dec 2015 18:38:57 +0000 (-0800) Subject: rgw: store obj pg version in the object's head X-Git-Tag: v10.1.0~354^2~102 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d2e41e8f5fd496d95ced4c380f9bfabd262feebd;p=ceph.git rgw: store obj pg version in the object's head this is done atomically when object is written, will allow us to determine whether object is newer or not. Signed-off-by: Yehuda Sadeh --- diff --git a/src/cls/rgw/cls_rgw.cc b/src/cls/rgw/cls_rgw.cc index 9414d338ef1..d109819489c 100644 --- a/src/cls/rgw/cls_rgw.cc +++ b/src/cls/rgw/cls_rgw.cc @@ -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); diff --git a/src/cls/rgw/cls_rgw_client.cc b/src/cls/rgw/cls_rgw_client.cc index cfd71a887a3..c2847741713 100644 --- a/src/cls/rgw/cls_rgw_client.cc +++ b/src/cls/rgw/cls_rgw_client.cc @@ -208,6 +208,15 @@ void cls_rgw_remove_obj(librados::ObjectWriteOperation& o, list& 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; diff --git a/src/cls/rgw/cls_rgw_client.h b/src/cls/rgw/cls_rgw_client.h index 3131ad61d50..6d136a9202a 100644 --- a/src/cls/rgw/cls_rgw_client.h +++ b/src/cls/rgw/cls_rgw_client.h @@ -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& 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); diff --git a/src/cls/rgw/cls_rgw_ops.h b/src/cls/rgw/cls_rgw_ops.h index fb0dbfe3880..1c8f96bff24 100644 --- a/src/cls/rgw/cls_rgw_ops.h +++ b/src/cls/rgw/cls_rgw_ops.h @@ -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; diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 981045c8b63..ed82e87004e 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -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" diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 94fe5653eff..4da29aa148d 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -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;