]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: fix data corruption when race condition 5117/head
authorwuxingyi <wuxingyi@letv.com>
Wed, 10 Jun 2015 06:57:57 +0000 (06:57 +0000)
committerAbhishek Lekshmanan <abhishek.lekshmanan@ril.com>
Wed, 1 Jul 2015 16:43:36 +0000 (22:13 +0530)
We should delete the object in the multipart namespace lastly to prevent a previous upload
wrongly deleting objects belong to the following upload.

Fixes: #11749
Signed-off-by: wuxingyi <wuxingyi@letv.com>
(cherry picked from commit ac1e729a75b5d995028bbc223bcf5ecce0d112cc)

src/rgw/rgw_rados.cc

index 38718b44bb5fbeb45875fae741f294ed4a53dd2c..a8257b00c29be25ef2d2d607aafcb51a083a7208 100644 (file)
@@ -915,11 +915,36 @@ RGWPutObjProcessor_Aio::~RGWPutObjProcessor_Aio()
     return;
 
   list<rgw_obj>::iterator iter;
+  bool is_multipart_obj = false;
+  rgw_obj multipart_obj;
+
+  /** 
+   * We should delete the object in the "multipart" namespace to avoid race condition. 
+   * Such race condition is caused by the fact that the multipart object is the gatekeeper of a multipart 
+   * upload, when it is deleted, a second upload would start with the same suffix("2/"), therefore, objects
+   * written by the second upload may be deleted by the first upload.
+   * details is describled on #11749
+   */ 
   for (iter = written_objs.begin(); iter != written_objs.end(); ++iter) {
-    rgw_obj& obj = *iter;
+    rgw_obj &obj = *iter;
+    if (RGW_OBJ_NS_MULTIPART == obj.ns) {
+      ldout(store->ctx(), 5) << "NOTE: we should not process the multipart object (" << obj << ") here" << dendl;
+      multipart_obj = *iter;
+      is_multipart_obj = true;
+      continue;
+    }
+
     int r = store->delete_obj(obj_ctx, bucket_info, obj, 0, 0);
     if (r < 0 && r != -ENOENT) {
-      ldout(store->ctx(), 0) << "WARNING: failed to remove obj (" << obj << "), leaked" << dendl;
+      ldout(store->ctx(), 5) << "WARNING: failed to remove obj (" << obj << "), leaked" << dendl;
+    }
+  }
+
+  if (true == is_multipart_obj) {
+    ldout(store->ctx(), 5) << "NOTE: we are going to process the multipart obj (" << multipart_obj << dendl;
+    int r = store->delete_obj(obj_ctx, bucket_info, multipart_obj, 0, 0);
+    if (r < 0 && r != -ENOENT) {
+      ldout(store->ctx(), 0) << "WARNING: failed to remove obj (" << multipart_obj << "), leaked" << dendl;
     }
   }
 }