]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: add DELETE_IF_UNMODIFIED_SINCE header to obj delete
authorYehuda Sadeh <yehuda@redhat.com>
Wed, 1 Apr 2015 21:57:19 +0000 (14:57 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Fri, 12 Feb 2016 00:12:49 +0000 (16:12 -0800)
Will delete object only if not modified after the specified time. Still
need to close a race where object is modified after the check.

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rados.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_s3.h

index 87e79757227a5485fa9e0d95cc6550e23013c2e1..fa1ed649a4984faff44c4e8558360f7d9a6c5d2b 100644 (file)
@@ -2864,15 +2864,15 @@ void RGWDeleteObj::pre_exec()
 
 void RGWDeleteObj::execute()
 {
-  op_ret = -EINVAL;
-  rgw_obj obj(s->bucket, s->object);
-  map<string, bufferlist> attrs;
-
   op_ret = get_params();
   if (op_ret < 0) {
     return;
   }
 
+  rgw_obj obj(s->bucket, s->object);
+  map<string, bufferlist> attrs;
+
+
   if (!s->object.empty()) {
     if (need_object_expiration() || multipart_delete) {
       /* check if obj exists, read orig attrs */
@@ -2913,6 +2913,7 @@ void RGWDeleteObj::execute()
     del_op.params.bucket_owner = s->bucket_owner.get_id();
     del_op.params.versioning_status = s->bucket_info.versioning_status();
     del_op.params.obj_owner = s->owner;
+    del_op.params.unmod_since = unmod_since;
 
     op_ret = del_op.delete_obj();
     if (op_ret >= 0) {
@@ -2926,6 +2927,8 @@ void RGWDeleteObj::execute()
       op_ret = -ENOENT;
       return;
     }
+  } else {
+    op_ret = -EINVAL;
   }
 }
 
index 9f2fd568598e3f460d3e6f34a06f6451720457a0..4c0507d824ca632349b9edd7f4658c9a0e73f53a 100644 (file)
@@ -813,12 +813,14 @@ protected:
   bool delete_marker;
   bool multipart_delete;
   string version_id;
+  time_t unmod_since; /* if unmodified since */
   std::unique_ptr<RGWBulkDelete::Deleter> deleter;
 
 public:
   RGWDeleteObj()
     : delete_marker(false),
       multipart_delete(false),
+      unmod_since(0),
       deleter(nullptr) {
   }
 
@@ -827,7 +829,7 @@ public:
   void execute();
   int handle_slo_manifest(bufferlist& bl);
 
-  virtual int get_params() { return 0; };
+  virtual int get_params() { return 0; }
   virtual void send_response() = 0;
   virtual const string name() { return "delete_obj"; }
   virtual RGWOpType get_type() { return RGW_OP_DELETE_OBJ; }
index 9d1598cb2a78a99200f95ac364873506c45e9c45..4fb3bdfe3559381d56876c8e86a2c6fc38c3294c 100644 (file)
@@ -1983,8 +1983,9 @@ public:
         uint32_t bilog_flags;
         list<rgw_obj_key> *remove_objs;
         utime_t expiration_time;
+        time_t unmod_since;
 
-        DeleteParams() : versioning_status(0), olh_epoch(0), bilog_flags(0), remove_objs(NULL) {}
+        DeleteParams() : versioning_status(0), olh_epoch(0), bilog_flags(0), remove_objs(NULL), unmod_since(0) {}
       } params;
 
       struct DeleteResult {
index 52a1dc4d01feeb25df87ac34ecba736d30ffbbf8..3affe25b37452eb3e26a2077945f76aa3f9b8c14 100644 (file)
@@ -1578,6 +1578,19 @@ done:
   rgw_flush_formatter_and_reset(s, s->formatter);
 }
 
+int RGWDeleteObj_ObjStore_S3::get_params()
+{
+  const char *if_unmod = s->info.env->get("HTTP_X_AMZ_DELETE_IF_UNMODIFIED_SINCE");
+
+  if (if_unmod) {
+    if (parse_time(if_unmod, &unmod_since) < 0) {
+      ldout(s->cct, 10) << "failed to parse time: " << if_unmod << dendl;
+      return -EINVAL;
+    }
+  }
+
+  return 0;
+}
 
 void RGWDeleteObj_ObjStore_S3::send_response()
 {
index 88f674b79b1af1ce94d1e6d1d2b41a0a547685d4..561261a0b8e7cc797544585e166ff685631a2788 100644 (file)
@@ -196,6 +196,7 @@ public:
   RGWDeleteObj_ObjStore_S3() {}
   ~RGWDeleteObj_ObjStore_S3() {}
 
+  int get_params();
   void send_response();
 };