]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: add support for multipart delete on a SLO of Swift.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Mon, 9 Nov 2015 16:16:34 +0000 (17:16 +0100)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Tue, 8 Dec 2015 16:58:08 +0000 (17:58 +0100)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_common.h
src/rgw/rgw_http_errors.h
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rest_swift.cc
src/rgw/rgw_rest_swift.h

index 89115b2dd8f4b4f1aa4c3a8e0a758aa8f125d980..998b2ba2fdbc1343a46c2fef30056adb8a22af1f 100644 (file)
@@ -152,6 +152,7 @@ using ceph::crypto::MD5;
 #define ERR_INVALID_ACCESS_KEY   2028
 #define ERR_MALFORMED_XML        2029
 #define ERR_USER_EXIST           2030
+#define ERR_NOT_SLO_MANIFEST     2031
 #define ERR_USER_SUSPENDED       2100
 #define ERR_INTERNAL_ERROR       2200
 #define ERR_NOT_IMPLEMENTED      2201
index aaa5312cbec6e124db0ba3be82e19194d6ff3623..7750d136c8e4209fb5ed6586003c8f05ffb351cc 100644 (file)
@@ -66,6 +66,7 @@ const static struct rgw_http_errors RGW_HTTP_SWIFT_ERRORS[] = {
     { ERR_USER_SUSPENDED, 401, "UserSuspended" },
     { ERR_INVALID_UTF8, 412, "Invalid UTF8" },
     { ERR_BAD_URL, 412, "Bad URL" },
+    { ERR_NOT_SLO_MANIFEST, 400, "Not an SLO manifest" }
 };
 
 struct rgw_http_status_code {
index 19608a3ab7c7985d13d2dd70f42d75a0d51a492b..79093f775b49b815bceb84e616ba4cd03c4cf895 100644 (file)
@@ -2659,6 +2659,61 @@ void RGWPutMetadataObject::execute()
   ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs, NULL);
 }
 
+int RGWDeleteObj::handle_slo_manifest(bufferlist& bl)
+{
+  RGWSLOInfo slo_info;
+  bufferlist::iterator bliter = bl.begin();
+  try {
+    ::decode(slo_info, bliter);
+  } catch (buffer::error& err) {
+    ldout(s->cct, 0) << "ERROR: failed to decode slo manifest" << dendl;
+    return -EIO;
+  }
+
+  try {
+    deleter = std::unique_ptr<RGWBulkDelete::Deleter>(\
+          new RGWBulkDelete::Deleter(store, s));
+  } catch (std::bad_alloc) {
+    return -ENOMEM;
+  }
+
+  list<RGWBulkDelete::acct_path_t> items;
+  for (const auto& iter : slo_info.entries) {
+    const string& path_str = iter.path;
+
+    const size_t sep_pos = path_str.find('/', 1 /* skip first slash */);
+    if (string::npos == sep_pos) {
+      return -EINVAL;
+    }
+
+    RGWBulkDelete::acct_path_t path;
+
+    string bucket_name;
+    url_decode(path_str.substr(1, sep_pos - 1), bucket_name);
+
+    string obj_name;
+    url_decode(path_str.substr(sep_pos + 1), obj_name);
+
+    path.bucket_name = bucket_name;
+    path.obj_key = obj_name;
+
+    items.push_back(path);
+  }
+
+  /* Request removal of the manifet object itself. */
+  RGWBulkDelete::acct_path_t path;
+  path.bucket_name = s->bucket_name_str;
+  path.obj_key = s->object;
+  items.push_back(path);
+
+  int ret = deleter->delete_chunk(items);
+  if (ret < 0) {
+    return ret;
+  }
+
+  return 0;
+}
+
 int RGWDeleteObj::verify_permission()
 {
   if (!verify_bucket_permission(s, RGW_PERM_WRITE))
@@ -2676,16 +2731,37 @@ void RGWDeleteObj::execute()
 {
   ret = -EINVAL;
   rgw_obj obj(s->bucket, s->object);
-  map<string, bufferlist> orig_attrs;
+  map<string, bufferlist> attrs;
+
+  ret = get_params();
+  if (ret < 0) {
+    return;
+  }
 
   if (!s->object.empty()) {
-    if (need_object_expiration()) {
+    if (need_object_expiration() || multipart_delete) {
       /* check if obj exists, read orig attrs */
-      ret = get_obj_attrs(store, s, obj, orig_attrs);
+      ret = get_obj_attrs(store, s, obj, attrs);
       if (ret < 0) {
         return;
       }
     }
+
+    if (multipart_delete) {
+      const auto slo_attr = attrs.find(RGW_ATTR_SLO_MANIFEST);
+
+      if (slo_attr != attrs.end()) {
+        ret = handle_slo_manifest(slo_attr->second);
+        if (ret < 0) {
+          ldout(s->cct, 0) << "ERROR: failed to handle slo manifest ret=" << ret << dendl;
+        }
+      } else {
+        ret = -ERR_NOT_SLO_MANIFEST;
+      }
+
+      return;
+    }
+
     RGWObjectCtx *obj_ctx = static_cast<RGWObjectCtx *>(s->obj_ctx);
 
     obj_ctx->set_atomic(obj);
@@ -2697,6 +2773,7 @@ void RGWDeleteObj::execute()
     if (ret < 0) {
       return;
     }
+
     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;
@@ -2709,7 +2786,7 @@ void RGWDeleteObj::execute()
 
     /* Check whether the object has expired. Swift API documentation
      * stands that we should return 404 Not Found in such case. */
-    if (need_object_expiration() && object_is_expired(orig_attrs)) {
+    if (need_object_expiration() && object_is_expired(attrs)) {
       ret = -ENOENT;
       return;
     }
index ce0f70d21d82e9177679d0340970775052aec716..3c3d873fa90845804dc296da57a610fb7cfc64b0 100644 (file)
@@ -764,15 +764,24 @@ class RGWDeleteObj : public RGWOp {
 protected:
   int ret;
   bool delete_marker;
+  bool multipart_delete;
   string version_id;
+  std::unique_ptr<RGWBulkDelete::Deleter> deleter;
 
 public:
-  RGWDeleteObj() : ret(0), delete_marker(false) {}
+  RGWDeleteObj()
+    : ret(0),
+      delete_marker(false),
+      multipart_delete(false),
+      deleter(nullptr) {
+  }
 
   int verify_permission();
   void pre_exec();
   void execute();
+  int handle_slo_manifest(bufferlist& bl);
 
+  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 0ca9ce9996cd875fda6f89d008f6161486cebd55..8f17c103b2302fc2bb2a2d76242d40c43bc7d5ed 100644 (file)
@@ -731,6 +731,14 @@ void RGWPutMetadataObject_ObjStore_SWIFT::send_response()
   rgw_flush_formatter_and_reset(s, s->formatter);
 }
 
+int RGWDeleteObj_ObjStore_SWIFT::get_params()
+{
+  const string& mm = s->info.args.get("multipart-manifest");
+  multipart_delete = (mm.compare("delete") == 0);
+
+  return RGWDeleteObj_ObjStore::get_params();
+}
+
 void RGWDeleteObj_ObjStore_SWIFT::send_response()
 {
   int r = ret;
index 7647cb125556ae523613dde6629ac24a6a1c86ac..a64c9966d9935d9cfaa643909bffc3b8a6bf0319 100644 (file)
@@ -125,6 +125,7 @@ public:
   RGWDeleteObj_ObjStore_SWIFT() {}
   ~RGWDeleteObj_ObjStore_SWIFT() {}
 
+  int get_params();
   bool need_object_expiration() { return true; }
   void send_response();
 };