]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Fix the multipart uploads functional test failures due to bucket index sharding.
authorGuang Yang <yguang@yahoo-inc.com>
Mon, 3 Nov 2014 12:56:06 +0000 (12:56 +0000)
committerYehuda Sadeh <yehuda@redhat.com>
Wed, 14 Jan 2015 03:21:24 +0000 (19:21 -0800)
Signed-off-by: Guang Yang <yguang@yahoo-inc.com>
src/rgw/rgw_common.h
src/rgw/rgw_op.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index 0769f91a037bb848b7ba6bbdab7318a2ea66d4f0..22af8cbd553aa382b5088c6f0b0de13bc8ba172e 100644 (file)
@@ -1048,6 +1048,9 @@ public:
 
   bool in_extra_data; /* in-memory only member, does not serialize */
 
+  // Represents the hash index source for this object once it is set (non-empty)
+  std::string index_hash_source;
+
   rgw_obj() : in_extra_data(false) {}
   rgw_obj(const char *b, const char *o) : in_extra_data(false) {
     rgw_bucket _b(b);
@@ -1146,6 +1149,9 @@ public:
       return orig_key;
   }
 
+  string& get_hash_object() {
+    return index_hash_source.empty() ? object : index_hash_source;
+  }
   /**
    * Translate a namespace-mangled object name to the user-facing name
    * existing in the given namespace.
index 0319a56982da4500189f715bc8260ffedc7f9c76..124511026d7a8c5b501eb66dfc855f1d03473b41 100644 (file)
@@ -1453,6 +1453,7 @@ int RGWPutObjProcessor_Multipart::prepare(RGWRados *store, void *obj_ctx, string
   }
 
   head_obj = manifest_gen.get_cur_obj();
+  head_obj.index_hash_source = obj_str;
   cur_obj = head_obj;
   add_obj(cur_obj);
 
@@ -2526,6 +2527,7 @@ void RGWInitMultipart::execute()
     obj.init_ns(s->bucket, tmp_obj_name, mp_ns);
     // the meta object will be indexed with 0 size, we c
     obj.set_in_extra_data(true);
+    obj.index_hash_source = s->object_str;
     ret = store->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, PUT_OBJ_CREATE_EXCL, s->owner.get_id());
   } while (ret == -EEXIST);
 }
@@ -2734,6 +2736,7 @@ void RGWCompleteMultipart::execute()
 
   meta_obj.init_ns(s->bucket, meta_oid, mp_ns);
   meta_obj.set_in_extra_data(true);
+  meta_obj.index_hash_source = s->object_str;
 
   ret = get_obj_attrs(store, s, meta_obj, attrs, NULL, NULL);
   if (ret < 0) {
@@ -2885,6 +2888,7 @@ void RGWAbortMultipart::execute()
         string oid = mp.get_part(obj_iter->second.num);
         rgw_obj obj;
         obj.init_ns(s->bucket, oid, mp_ns);
+        obj.index_hash_source = s->object_str;
         ret = store->delete_obj(s->obj_ctx, owner, obj);
         if (ret < 0 && ret != -ENOENT)
           return;
@@ -2893,6 +2897,7 @@ void RGWAbortMultipart::execute()
         RGWObjManifest::obj_iterator oiter;
         for (oiter = manifest.obj_begin(); oiter != manifest.obj_end(); ++oiter) {
           rgw_obj loc = oiter.get_location();
+          loc.index_hash_source = s->object_str;
           ret = store->delete_obj(s->obj_ctx, owner, loc);
           if (ret < 0 && ret != -ENOENT)
             return;
@@ -2904,6 +2909,7 @@ void RGWAbortMultipart::execute()
   // and also remove the metadata obj
   meta_obj.init_ns(s->bucket, meta_oid, mp_ns);
   meta_obj.set_in_extra_data(true);
+  meta_obj.index_hash_source = s->object_str;
   ret = store->delete_obj(s->obj_ctx, owner, meta_obj);
   if (ret == -ENOENT) {
     ret = -ERR_NO_SUCH_BUCKET;
index 914e24342506d72f7756115dae4c796427b72f7f..a485954e2d53f9e56dd448860e955cb62de677c4 100644 (file)
@@ -2971,8 +2971,8 @@ int RGWRados::put_obj_meta_impl(void *ctx, rgw_obj& obj,  uint64_t size,
     ldout(cct, 0) << "ERROR: complete_atomic_overwrite returned r=" << r << dendl;
   }
 
-  r = complete_update_index(bucket, obj.object, index_tag, poolid, epoch, size,
-                            ut, etag, content_type, &acl_bl, category, remove_objs);
+  r = complete_update_index(bucket, obj, index_tag, poolid, epoch, size,
+      ut, etag, content_type, &acl_bl, category, remove_objs);
   if (r < 0)
     goto done_cancel;
 
@@ -2988,7 +2988,7 @@ int RGWRados::put_obj_meta_impl(void *ctx, rgw_obj& obj,  uint64_t size,
   return 0;
 
 done_cancel:
-  int ret = complete_update_index_cancel(bucket, obj.object, index_tag);
+  int ret = complete_update_index_cancel(bucket, obj, index_tag);
   if (ret < 0) {
     ldout(cct, 0) << "ERROR: complete_update_index_cancel() returned ret=" << ret << dendl;
   }
@@ -3985,9 +3985,9 @@ int RGWRados::delete_obj_impl(void *ctx, const string& bucket_owner, rgw_obj& ob
   int64_t poolid = ref.ioctx.get_id();
   if (r >= 0 || r == -ENOENT) {
     uint64_t epoch = ref.ioctx.get_last_version();
-    r = complete_update_index_del(bucket, obj.object, tag, poolid, epoch);
+    r = complete_update_index_del(bucket, obj, tag, poolid, epoch);
   } else {
-    int ret = complete_update_index_cancel(bucket, obj.object, tag);
+    int ret = complete_update_index_cancel(bucket, obj, tag);
     if (ret < 0) {
       ldout(cct, 0) << "ERROR: complete_update_index_cancel returned ret=" << ret << dendl;
     }
@@ -4046,7 +4046,7 @@ int RGWRados::delete_obj_index(rgw_obj& obj)
   get_obj_bucket_and_oid_key(obj, bucket, oid, key);
 
   string tag;
-  int r = complete_update_index_del(bucket, obj.object, tag, -1 /* pool */, 0);
+  int r = complete_update_index_del(bucket, obj, tag, -1 /* pool */, 0);
 
   return r;
 }
@@ -4622,13 +4622,12 @@ int RGWRados::prepare_update_index(RGWObjState *state, rgw_bucket& bucket,
       append_rand_alpha(cct, tag, tag, 32);
     }
   }
-  ret = cls_obj_prepare_op(bucket, op, tag,
-                               obj.object, obj.key);
+  ret = cls_obj_prepare_op(bucket, op, tag, obj.object, obj.key, obj.get_hash_object());
 
   return ret;
 }
 
-int RGWRados::complete_update_index(rgw_bucket& bucket, string& oid, string& tag, int64_t poolid, uint64_t epoch, uint64_t size,
+int RGWRados::complete_update_index(rgw_bucket& bucket, rgw_obj& oid, string& tag, int64_t poolid, uint64_t epoch, uint64_t size,
                                     utime_t& ut, string& etag, string& content_type, bufferlist *acl_bl, RGWObjCategory category,
                                     list<string> *remove_objs)
 {
@@ -4636,7 +4635,7 @@ int RGWRados::complete_update_index(rgw_bucket& bucket, string& oid, string& tag
     return 0;
 
   RGWObjEnt ent;
-  ent.name = oid;
+  ent.name = oid.object;
   ent.size = size;
   ent.mtime = ut;
   ent.etag = etag;
@@ -4651,7 +4650,7 @@ int RGWRados::complete_update_index(rgw_bucket& bucket, string& oid, string& tag
   ent.owner_display_name = owner.get_display_name();
   ent.content_type = content_type;
 
-  int ret = cls_obj_complete_add(bucket, tag, poolid, epoch, ent, category, remove_objs);
+  int ret = cls_obj_complete_add(bucket, tag, poolid, epoch, ent, category, remove_objs, oid.get_hash_object());
 
   return ret;
 }
@@ -4770,10 +4769,10 @@ done:
 
   if (update_index) {
     if (ret >= 0) {
-      ret = complete_update_index(bucket, dst_obj.object, tag, poolid, epoch, size,
+      ret = complete_update_index(bucket, dst_obj, tag, poolid, epoch, size,
                                   ut, etag, content_type, &acl_bl, category, NULL);
     } else {
-      int r = complete_update_index_cancel(bucket, dst_obj.object, tag);
+      int r = complete_update_index_cancel(bucket, dst_obj, tag);
       if (r < 0) {
         ldout(cct, 0) << "ERROR: comlete_update_index_cancel() returned r=" << r << dendl;
       }
@@ -6243,11 +6242,11 @@ int RGWRados::cls_rgw_init_index(librados::IoCtx& index_ctx, librados::ObjectWri
 }
 
 int RGWRados::cls_obj_prepare_op(rgw_bucket& bucket, RGWModifyOp op, string& tag,
-                                 string& name, string& locator)
+                                 string& name, string& locator, const string& index_hash_object)
 {
   librados::IoCtx index_ctx;
   string bucket_obj;
-  int ret = open_bucket_index_shard(bucket, index_ctx, name, &bucket_obj);
+  int ret = open_bucket_index_shard(bucket, index_ctx, index_hash_object, &bucket_obj);
   ldout(cct, 20) << " bucket index object: " << bucket_obj << dendl;
   if (ret < 0)
     return ret;
@@ -6261,11 +6260,11 @@ int RGWRados::cls_obj_prepare_op(rgw_bucket& bucket, RGWModifyOp op, string& tag
 int RGWRados::cls_obj_complete_op(rgw_bucket& bucket, RGWModifyOp op, string& tag,
                                   int64_t pool, uint64_t epoch,
                                   RGWObjEnt& ent, RGWObjCategory category,
-                                 list<string> *remove_objs)
+                                 list<string> *remove_objs, const string& index_hash_object)
 {
   librados::IoCtx index_ctx;
   string bucket_obj;
-  int ret = open_bucket_index_shard(bucket, index_ctx, ent.name, &bucket_obj);
+  int ret = open_bucket_index_shard(bucket, index_ctx, index_hash_object, &bucket_obj);
   ldout(cct, 20) << " bucket index object: " << bucket_obj << dendl;
   if (ret < 0)
     return ret;
@@ -6294,25 +6293,25 @@ int RGWRados::cls_obj_complete_op(rgw_bucket& bucket, RGWModifyOp op, string& ta
 int RGWRados::cls_obj_complete_add(rgw_bucket& bucket, string& tag,
                                    int64_t pool, uint64_t epoch,
                                    RGWObjEnt& ent, RGWObjCategory category,
-                                   list<string> *remove_objs)
+                                   list<string> *remove_obj, const string& index_hash_object)
 {
-  return cls_obj_complete_op(bucket, CLS_RGW_OP_ADD, tag, pool, epoch, ent, category, remove_objs);
+  return cls_obj_complete_op(bucket, CLS_RGW_OP_ADD, tag, pool, epoch, ent, category, remove_obj, index_hash_object);
 }
 
 int RGWRados::cls_obj_complete_del(rgw_bucket& bucket, string& tag,
                                    int64_t pool, uint64_t epoch,
-                                   string& name)
+                                   string& name, const string& index_hash_object)
 {
   RGWObjEnt ent;
   ent.name = name;
-  return cls_obj_complete_op(bucket, CLS_RGW_OP_DEL, tag, pool, epoch, ent, RGW_OBJ_CATEGORY_NONE, NULL);
+  return cls_obj_complete_op(bucket, CLS_RGW_OP_DEL, tag, pool, epoch, ent, RGW_OBJ_CATEGORY_NONE, NULL, index_hash_object);
 }
 
-int RGWRados::cls_obj_complete_cancel(rgw_bucket& bucket, string& tag, string& name)
+int RGWRados::cls_obj_complete_cancel(rgw_bucket& bucket, string& tag, string& name, const string& index_hash_object)
 {
   RGWObjEnt ent;
   ent.name = name;
-  return cls_obj_complete_op(bucket, CLS_RGW_OP_ADD, tag, -1 /* pool id */, 0, ent, RGW_OBJ_CATEGORY_NONE, NULL);
+  return cls_obj_complete_op(bucket, CLS_RGW_OP_ADD, tag, -1 /* pool id */, 0, ent, RGW_OBJ_CATEGORY_NONE, NULL, index_hash_object);
 }
 
 int RGWRados::cls_obj_set_bucket_tag_timeout(rgw_bucket& bucket, uint64_t timeout)
@@ -6392,15 +6391,15 @@ int RGWRados::cls_bucket_list(rgw_bucket& bucket, const string& start, const str
       librados::IoCtx sub_ctx;
       sub_ctx.dup(index_ctx);
       r = check_disk_state(sub_ctx, bucket, dirent, e, updates[vnames[pos]]);
-      if (r < 0) {
-        if (r == -ENOENT)
-          continue;
-        else
+      if (r < 0 && r != -ENOENT) {
           return r;
       }
     }
-    m[e.name] = e;
-    ldout(cct, 10) << "RGWRados::cls_bucket_list: got " << e.name << dendl;
+    if (r >= 0) {
+      m[e.name] = e;
+      ldout(cct, 10) << "RGWRados::cls_bucket_list: got " << e.name << dendl;
+      ++count;
+    }
 
     // Refresh the candidates map
     candidates.erase(candidates.begin());
@@ -6408,7 +6407,6 @@ int RGWRados::cls_bucket_list(rgw_bucket& bucket, const string& start, const str
     if (vcurrents[pos] != vends[pos]) {
       candidates[vcurrents[pos]->second.name] = pos;
     }
-    ++count;
   }
 
   // Suggest updates if there is any
@@ -6431,6 +6429,7 @@ int RGWRados::cls_bucket_list(rgw_bucket& bucket, const string& start, const str
   }
   if (m.size())
     *last_entry = m.rbegin()->first;
+
   return 0;
 }
 
index b501fa450b2b068b29940bcfa08415a252170eca..819f494925bd3e9b93ff9edb1be6d33949258059 100644 (file)
@@ -1845,12 +1845,12 @@ public:
 
   int cls_rgw_init_index(librados::IoCtx& io_ctx, librados::ObjectWriteOperation& op, string& oid);
   int cls_obj_prepare_op(rgw_bucket& bucket, RGWModifyOp op, string& tag,
-                         string& name, string& locator);
+                         string& name, string& locator, const string& index_hash_object);
   int cls_obj_complete_op(rgw_bucket& bucket, RGWModifyOp op, string& tag, int64_t pool, uint64_t epoch,
-                          RGWObjEnt& ent, RGWObjCategory category, list<string> *remove_objs);
-  int cls_obj_complete_add(rgw_bucket& bucket, string& tag, int64_t pool, uint64_t epoch, RGWObjEnt& ent, RGWObjCategory category, list<string> *remove_objs);
-  int cls_obj_complete_del(rgw_bucket& bucket, string& tag, int64_t pool, uint64_t epoch, string& name);
-  int cls_obj_complete_cancel(rgw_bucket& bucket, string& tag, string& name);
+                          RGWObjEnt& ent, RGWObjCategory category, list<string> *remove_objs, const string& index_hash_object);
+  int cls_obj_complete_add(rgw_bucket& bucket, string& tag, int64_t pool, uint64_t epoch, RGWObjEnt& ent, RGWObjCategory category, list<string> *remove_objs, const string& index_hash_object);
+  int cls_obj_complete_del(rgw_bucket& bucket, string& tag, int64_t pool, uint64_t epoch, string& name, const string& index_hash_object);
+  int cls_obj_complete_cancel(rgw_bucket& bucket, string& tag, string& name, const string& index_hash_object);
   int cls_obj_set_bucket_tag_timeout(rgw_bucket& bucket, uint64_t timeout);
   int cls_bucket_list(rgw_bucket& bucket, const string& start, const string& prefix, uint32_t hint_num,
                       map<string, RGWObjEnt>& m, bool *is_truncated, string *last_entry,
@@ -1859,20 +1859,20 @@ public:
   int cls_bucket_head_async(rgw_bucket& bucket, RGWGetDirHeader_CB *ctx, int *num_aio);
   int prepare_update_index(RGWObjState *state, rgw_bucket& bucket,
                            RGWModifyOp op, rgw_obj& oid, string& tag);
-  int complete_update_index(rgw_bucket& bucket, string& oid, string& tag, int64_t poolid, uint64_t epoch, uint64_t size,
+  int complete_update_index(rgw_bucket& bucket, rgw_obj& oid, string& tag, int64_t poolid, uint64_t epoch, uint64_t size,
                             utime_t& ut, string& etag, string& content_type, bufferlist *acl_bl, RGWObjCategory category,
                            list<string> *remove_objs);
-  int complete_update_index_del(rgw_bucket& bucket, string& oid, string& tag, int64_t pool, uint64_t epoch) {
+  int complete_update_index_del(rgw_bucket& bucket, rgw_obj& oid, string& tag, int64_t pool, uint64_t epoch) {
     if (bucket_is_system(bucket))
       return 0;
 
-    return cls_obj_complete_del(bucket, tag, pool, epoch, oid);
+    return cls_obj_complete_del(bucket, tag, pool, epoch, oid.object, oid.get_hash_object());
   }
-  int complete_update_index_cancel(rgw_bucket& bucket, string& oid, string& tag) {
+  int complete_update_index_cancel(rgw_bucket& bucket, rgw_obj& oid, string& tag) {
     if (bucket_is_system(bucket))
       return 0;
 
-    return cls_obj_complete_cancel(bucket, tag, oid);
+    return cls_obj_complete_cancel(bucket, tag, oid.object, oid.get_hash_object());
   }
   int list_bi_log_entries(rgw_bucket& bucket, string& marker, uint32_t max, std::list<rgw_bi_log_entry>& result, bool *truncated);
   int trim_bi_log_entries(rgw_bucket& bucket, string& marker, string& end_marker);