- attrs = meta_obj->get_attrs();
-
- do {
- op_ret = list_multipart_parts(this, store, s, upload_id, meta_oid, max_parts,
- marker, obj_parts, &marker, &truncated);
- if (op_ret == -ENOENT) {
- op_ret = -ERR_NO_SUCH_UPLOAD;
- }
- if (op_ret < 0)
- return;
-
- total_parts += obj_parts.size();
- if (!truncated && total_parts != (int)parts->parts.size()) {
- ldpp_dout(this, 0) << "NOTICE: total parts mismatch: have: " << total_parts
- << " expected: " << parts->parts.size() << dendl;
- op_ret = -ERR_INVALID_PART;
- return;
- }
-
- for (obj_iter = obj_parts.begin(); iter != parts->parts.end() && obj_iter != obj_parts.end(); ++iter, ++obj_iter, ++handled_parts) {
- uint64_t part_size = obj_iter->second.accounted_size;
- if (handled_parts < (int)parts->parts.size() - 1 &&
- part_size < min_part_size) {
- op_ret = -ERR_TOO_SMALL;
- return;
- }
-
- char petag[CEPH_CRYPTO_MD5_DIGESTSIZE];
- if (iter->first != (int)obj_iter->first) {
- ldpp_dout(this, 0) << "NOTICE: parts num mismatch: next requested: "
- << iter->first << " next uploaded: "
- << obj_iter->first << dendl;
- op_ret = -ERR_INVALID_PART;
- return;
- }
- string part_etag = rgw_string_unquote(iter->second);
- if (part_etag.compare(obj_iter->second.etag) != 0) {
- ldpp_dout(this, 0) << "NOTICE: etag mismatch: part: " << iter->first
- << " etag: " << iter->second << dendl;
- op_ret = -ERR_INVALID_PART;
- return;
- }
-
- hex_to_buf(obj_iter->second.etag.c_str(), petag,
- CEPH_CRYPTO_MD5_DIGESTSIZE);
- hash.Update((const unsigned char *)petag, sizeof(petag));
-
- RGWUploadPartInfo& obj_part = obj_iter->second;
-
- /* update manifest for part */
- string oid = mp.get_part(obj_iter->second.num);
- rgw_obj src_obj;
- src_obj.init_ns(s->bucket->get_key(), oid, mp_ns);
-
- if (obj_part.manifest.empty()) {
- ldpp_dout(this, 0) << "ERROR: empty manifest for object part: obj="
- << src_obj << dendl;
- op_ret = -ERR_INVALID_PART;
- return;
- } else {
- manifest.append(this, obj_part.manifest, store->svc()->zone);
- }
-
- bool part_compressed = (obj_part.cs_info.compression_type != "none");
- if ((handled_parts > 0) &&
- ((part_compressed != compressed) ||
- (cs_info.compression_type != obj_part.cs_info.compression_type))) {
- ldpp_dout(this, 0) << "ERROR: compression type was changed during multipart upload ("
- << cs_info.compression_type << ">>" << obj_part.cs_info.compression_type << ")" << dendl;
- op_ret = -ERR_INVALID_PART;
- return;
- }
-
- if (part_compressed) {
- int64_t new_ofs; // offset in compression data for new part
- if (cs_info.blocks.size() > 0)
- new_ofs = cs_info.blocks.back().new_ofs + cs_info.blocks.back().len;
- else
- new_ofs = 0;
- for (const auto& block : obj_part.cs_info.blocks) {
- compression_block cb;
- cb.old_ofs = block.old_ofs + cs_info.orig_size;
- cb.new_ofs = new_ofs;
- cb.len = block.len;
- cs_info.blocks.push_back(cb);
- new_ofs = cb.new_ofs + cb.len;
- }
- if (!compressed)
- cs_info.compression_type = obj_part.cs_info.compression_type;
- cs_info.orig_size += obj_part.cs_info.orig_size;
- compressed = true;
- }
-
- rgw_obj_index_key remove_key;
- src_obj.key.get_index_key(&remove_key);
-
- remove_objs.push_back(remove_key);
-
- ofs += obj_part.size;
- accounted_size += obj_part.accounted_size;
- }
- } while (truncated);
-
- hash.Final((unsigned char *)final_etag);
-
- buf_to_hex((unsigned char *)final_etag, sizeof(final_etag), final_etag_str);
- snprintf(&final_etag_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2], sizeof(final_etag_str) - CEPH_CRYPTO_MD5_DIGESTSIZE * 2,
- "-%lld", (long long)parts->parts.size());
- etag = final_etag_str;
- ldpp_dout(this, 10) << "calculated etag: " << final_etag_str << dendl;
-
- etag_bl.append(final_etag_str, strlen(final_etag_str));
-
- attrs[RGW_ATTR_ETAG] = etag_bl;