]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: fix multipart get part when count==1 58288/head
authorCasey Bodley <cbodley@redhat.com>
Wed, 26 Jun 2024 14:52:37 +0000 (10:52 -0400)
committerCasey Bodley <cbodley@redhat.com>
Wed, 26 Jun 2024 14:52:39 +0000 (10:52 -0400)
the RGWObjManifest for multipart uploads is subtly different when
there's only a single part. in that case, get_cur_part_id() for the
final rule returns 1 where it otherwise returns (parts_count + 1)

this caused two problems:
* we returned a parts_count of 0 instead 1, and
* the do-while loop got stuck in an infinite loop expecting the last
  rule's part id to be higher than the requested part id

Fixes: https://tracker.ceph.com/issues/66705
Signed-off-by: Casey Bodley <cbodley@redhat.com>
src/rgw/driver/rados/rgw_rados.cc

index ec1bd23f59c895358a3aa35cae48d500e36fa06e..bc7eb39fc5097ac746c518771bab0701cbeac6d2 100644 (file)
@@ -6639,12 +6639,15 @@ static int get_part_obj_state(const DoutPrefixProvider* dpp, optional_yield y,
   }
   // navigate to the requested part in the manifest
   RGWObjManifest::obj_iterator end = manifest->obj_end(dpp);
-  if (end.get_cur_part_id() == 0) { // not multipart
+  const int last_part_id = end.get_cur_part_id();
+  if (last_part_id == 0) { // not multipart
     ldpp_dout(dpp, 20) << "object does not have a multipart manifest" << dendl;
     return -ERR_INVALID_PART;
   }
   if (parts_count) {
-    *parts_count = end.get_cur_part_id() - 1;
+    // when a multipart upload only contains a single part, the last part id
+    // is off by one. don't let parts_count go to 0
+    *parts_count = std::max(1, last_part_id - 1);
   }
   ldpp_dout(dpp, 20) << "seeking to part #" << part_num
       << " in the object manifest" << dendl;
@@ -6704,7 +6707,7 @@ static int get_part_obj_state(const DoutPrefixProvider* dpp, optional_yield y,
   do {
     ++iter;
     gen.create_next(iter.get_ofs() - part_offset);
-  } while (iter.get_cur_part_id() == part_num);
+  } while (iter != end && iter.get_cur_part_id() == part_num);
 
   // update the object size
   sm->state.size = part_manifest.get_obj_size();