]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: culculate etag for DLOs of Swift API.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Tue, 23 Feb 2016 17:46:44 +0000 (18:46 +0100)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Mon, 29 Feb 2016 11:16:42 +0000 (12:16 +0100)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rest_swift.cc

index df884086ec02b72dcd8045a75c96a2b424c5813b..f9b05bd39e57c09dbe1c9b83f6cac71a73b847e0 100644 (file)
@@ -702,6 +702,7 @@ static int iterate_user_manifest_parts(CephContext * const cct,
                                        RGWAccessControlPolicy * const bucket_policy,
                                        uint64_t * const ptotal_len,
                                        uint64_t * const pobj_size,
+                                       string * const pobj_sum,
                                        int (*cb)(rgw_bucket& bucket,
                                                  const RGWObjEnt& ent,
                                                  RGWAccessControlPolicy * const bucket_policy,
@@ -724,16 +725,15 @@ static int iterate_user_manifest_parts(CephContext * const cct,
   list_op.params.prefix = obj_prefix;
   list_op.params.delim = delim;
 
+  MD5 etag_sum;
   do {
 #define MAX_LIST_OBJS 100
     int r = list_op.list_objects(MAX_LIST_OBJS, &objs, NULL, &is_truncated);
-    if (r < 0)
+    if (r < 0) {
       return r;
+    }
 
-    vector<RGWObjEnt>::iterator viter;
-
-    for (viter = objs.begin(); viter != objs.end(); ++viter) {
-      RGWObjEnt& ent = *viter;
+    for (RGWObjEnt& ent : objs) {
       uint64_t cur_total_len = obj_ofs;
       uint64_t start_ofs = 0, end_ofs = ent.size;
 
@@ -743,6 +743,10 @@ static int iterate_user_manifest_parts(CephContext * const cct,
       }
 
       obj_ofs += ent.size;
+      if (pobj_sum) {
+        etag_sum.Update((const byte *)ent.etag.c_str(),
+                        ent.etag.length());
+      }
 
       if (!found_end && obj_ofs > (uint64_t)end) {
        end_ofs = end - cur_total_len + 1;
@@ -774,6 +778,9 @@ static int iterate_user_manifest_parts(CephContext * const cct,
   if (pobj_size) {
     *pobj_size = obj_ofs;
   }
+  if (pobj_sum) {
+    complete_etag(etag_sum, pobj_sum);
+  }
 
   return 0;
 }
@@ -917,10 +924,14 @@ int RGWGetObj::handle_user_manifest(const char *prefix)
     bucket_policy = s->bucket_acl;
   }
 
-  /* dry run to find out total length */
+  /* dry run to find out:
+   * - total length (of the parts we are going to send to client),
+   * - overall DLO's content size,
+   * - md5 sum of overall DLO's content (for etag of Swift API). */
   int r = iterate_user_manifest_parts(s->cct, store, ofs, end,
-        bucket, obj_prefix, bucket_policy, &total_len, &s->obj_size,
-        NULL, NULL);
+        bucket, obj_prefix, bucket_policy,
+        &total_len, &s->obj_size, &lo_etag,
+        nullptr /* cb */, nullptr /* cb arg */);
   if (r < 0) {
     return r;
   }
@@ -932,7 +943,8 @@ int RGWGetObj::handle_user_manifest(const char *prefix)
   }
 
   r = iterate_user_manifest_parts(s->cct, store, ofs, end,
-        bucket, obj_prefix, bucket_policy, NULL, NULL,
+        bucket, obj_prefix, bucket_policy,
+        nullptr, nullptr, nullptr,
         get_obj_user_manifest_iterate_cb, (void *)this);
   if (r < 0) {
     return r;
index 398534d582bd65338811152b60d1aa4c682967a5..1f511b93bfd1ae8a66d2ce06ffa235f4a911fab8 100644 (file)
@@ -160,6 +160,7 @@ protected:
   rgw_obj obj;
   utime_t gc_invalidate_time;
   bool is_slo;
+  string lo_etag;
 
   int init_common();
 public:
index dda1f173a8789174f2b7f5c5385b8f4130f908b3..49aa79e62f738ca4b4b820ac7753d8f98ac90f83 100644 (file)
@@ -1012,8 +1012,9 @@ int RGWGetObj_ObjStore_SWIFT::send_response_data_error()
   return send_response_data(bl, 0, 0);
 }
 
-int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, off_t bl_ofs,
-                                                off_t bl_len)
+int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl,
+                                                 const off_t bl_ofs,
+                                                 const off_t bl_len)
 {
   string content_type;
 
@@ -1041,12 +1042,16 @@ int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, off_t bl_ofs,
   }
 
   if (! op_ret) {
-    map<string, bufferlist>::iterator iter = attrs.find(RGW_ATTR_ETAG);
-    if (iter != attrs.end()) {
-      bufferlist& bl = iter->second;
-      if (bl.length()) {
-       char *etag = bl.c_str();
-       dump_etag(s, etag);
+    if (!lo_etag.empty()) {
+      dump_etag(s, ("\"" + lo_etag + "\"").c_str());
+    } else {
+      auto iter = attrs.find(RGW_ATTR_ETAG);
+      if (iter != attrs.end()) {
+        bufferlist& bl = iter->second;
+        if (bl.length()) {
+          char *etag = bl.c_str();
+          dump_etag(s, etag);
+        }
       }
     }