]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
cls/rgw: add an objclass method to check obj mtime
authorYehuda Sadeh <yehuda@redhat.com>
Wed, 1 Apr 2015 22:56:49 +0000 (15:56 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Fri, 12 Feb 2016 00:12:50 +0000 (16:12 -0800)
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/cls/rgw/cls_rgw_types.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index 088e2c5965f4422f143cd696709d9c0d4cbeced6..66524d9692037cc80dc81749f6189424fca97137 100644 (file)
@@ -37,6 +37,7 @@ 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_check_attrs_prefix;
+cls_method_handle_t h_rgw_obj_check_mtime;
 cls_method_handle_t h_rgw_bi_get_op;
 cls_method_handle_t h_rgw_bi_put_op;
 cls_method_handle_t h_rgw_bi_list_op;
@@ -2029,6 +2030,63 @@ static int rgw_obj_check_attrs_prefix(cls_method_context_t hctx, bufferlist *in,
   return 0;
 }
 
+static int rgw_obj_check_mtime(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+  // decode request
+  rgw_cls_obj_check_mtime 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;
+  }
+
+  time_t mtime;
+  int ret = cls_cxx_stat(hctx, NULL, &mtime);
+  if (ret < 0 && ret != -ENOENT) {
+    CLS_LOG(0, "ERROR: %s(): cls_cxx_stat() returned %d", __func__, ret);
+    return ret;
+  }
+  if (ret == -ENOENT) {
+    CLS_LOG(10, "object does not exist, skipping check");
+  }
+
+  utime_t obj_ut(mtime, 0);
+
+  CLS_LOG(10, "%s: obj_ut=%lld.%06lld op.mtime=%lld.%06lld", __func__,
+          (long long)obj_ut.sec(), (long long)obj_ut.nsec(),
+          (long long)op.mtime.sec(), (long long)op.mtime.nsec());
+
+  bool check;
+
+  switch (op.type) {
+  case CLS_RGW_CHECK_TIME_MTIME_EQ:
+    check = (obj_ut == op.mtime);
+    break;
+  case CLS_RGW_CHECK_TIME_MTIME_LT:
+    check = (obj_ut < op.mtime);
+    break;
+  case CLS_RGW_CHECK_TIME_MTIME_LE:
+    check = (obj_ut <= op.mtime);
+    break;
+  case CLS_RGW_CHECK_TIME_MTIME_GT:
+    check = (obj_ut > op.mtime);
+    break;
+  case CLS_RGW_CHECK_TIME_MTIME_GE:
+    check = (obj_ut >= op.mtime);
+    break;
+  default:
+    return -EINVAL;
+  };
+
+  if (!check) {
+    return -ECANCELED;
+  }
+
+  return 0;
+}
+
 static int rgw_bi_get_op(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
 {
   // decode request
@@ -3076,6 +3134,7 @@ void __cls_init()
 
   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_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);
 
   cls_register_cxx_method(h_class, "bi_get", CLS_METHOD_RD, rgw_bi_get_op, &h_rgw_bi_get_op);
   cls_register_cxx_method(h_class, "bi_put", CLS_METHOD_RD | CLS_METHOD_WR, rgw_bi_put_op, &h_rgw_bi_put_op);
index 62034f2d1ab99fc5ace88009458a4ba819e406a1..cfd71a887a3d97ed06ee39b34642825b2fed8242 100644 (file)
@@ -218,6 +218,16 @@ void cls_rgw_obj_check_attrs_prefix(librados::ObjectOperation& o, const string&
   o.exec("rgw", "obj_check_attrs_prefix", in);
 }
 
+void cls_rgw_obj_check_mtime(librados::ObjectOperation& o, const utime_t& mtime, RGWCheckMTimeType type)
+{
+  bufferlist in;
+  struct rgw_cls_obj_check_mtime call;
+  call.mtime = mtime;
+  call.type = type;
+  ::encode(call, in);
+  o.exec("rgw", "obj_check_mtime", in);
+}
+
 int cls_rgw_bi_get(librados::IoCtx& io_ctx, const string oid,
                    BIIndexType index_type, cls_rgw_obj_key& key,
                    rgw_cls_bi_entry *entry)
index 37c856fa07f636ae06b603b4be3977531a4ba159..3131ad61d50dea7db1bccce6cc75811aa28387da 100644 (file)
@@ -316,6 +316,7 @@ void cls_rgw_bucket_complete_op(librados::ObjectWriteOperation& o, RGWModifyOp o
 
 void cls_rgw_remove_obj(librados::ObjectWriteOperation& o, list<string>& keep_attr_prefixes);
 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);
 
 int cls_rgw_bi_get(librados::IoCtx& io_ctx, const string oid,
                    BIIndexType index_type, cls_rgw_obj_key& key,
index 0a0686fbccb16cb92082540ed7021a4ad1242532..fb0dbfe38808611d853b47affd1448b9d1f668f3 100644 (file)
@@ -459,6 +459,30 @@ struct rgw_cls_obj_check_attrs_prefix {
 };
 WRITE_CLASS_ENCODER(rgw_cls_obj_check_attrs_prefix)
 
+struct rgw_cls_obj_check_mtime {
+  utime_t mtime;
+  RGWCheckMTimeType type;
+
+  rgw_cls_obj_check_mtime() : type(CLS_RGW_CHECK_TIME_MTIME_EQ) {}
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(mtime, bl);
+    ::encode((uint8_t)type, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(mtime, bl);
+    uint8_t c;
+    ::decode(c, bl);
+    type = (RGWCheckMTimeType)c;
+    DECODE_FINISH(bl);
+  }
+};
+WRITE_CLASS_ENCODER(rgw_cls_obj_check_mtime)
+
 struct rgw_cls_usage_log_add_op {
   rgw_usage_log_info info;
 
index dfa9286c0008e2e970d68b498b0537e429b1d63f..f903793732705d7e48d348eaa851515b1d404329 100644 (file)
@@ -36,6 +36,14 @@ enum RGWBILogFlags {
   RGW_BILOG_FLAG_VERSIONED_OP = 0x1,
 };
 
+enum RGWCheckMTimeType {
+  CLS_RGW_CHECK_TIME_MTIME_EQ = 0,
+  CLS_RGW_CHECK_TIME_MTIME_LT = 1,
+  CLS_RGW_CHECK_TIME_MTIME_LE = 2,
+  CLS_RGW_CHECK_TIME_MTIME_GT = 3,
+  CLS_RGW_CHECK_TIME_MTIME_GE = 4,
+};
+
 struct rgw_bucket_pending_info {
   RGWPendingState state;
   utime_t timestamp;
index 29b237b607e8458a175ace93de3de58d296942d0..7def00886fbe4521eeb7adc79ef5ed792bb0ec0d 100644 (file)
@@ -6013,6 +6013,11 @@ void RGWRados::cls_obj_check_prefix_exist(ObjectOperation& op, const string& pre
   cls_rgw_obj_check_attrs_prefix(op, prefix, fail_if_exist);
 }
 
+void RGWRados::cls_obj_check_mtime(ObjectOperation& op, const utime_t& mtime, RGWCheckMTimeType type)
+{
+  cls_rgw_obj_check_mtime(op, mtime, type);
+}
+
 
 /**
  * Delete an object.
index 4fb3bdfe3559381d56876c8e86a2c6fc38c3294c..f7b29cf4418d675c4dc6cf91fdc590585048522b 100644 (file)
@@ -1611,6 +1611,7 @@ class RGWRados
 
   void remove_rgw_head_obj(librados::ObjectWriteOperation& op);
   void cls_obj_check_prefix_exist(librados::ObjectOperation& op, const string& prefix, bool fail_if_exist);
+  void cls_obj_check_mtime(librados::ObjectOperation& op, const utime_t& mtime, RGWCheckMTimeType type);
 protected:
   CephContext *cct;