Merge pull request #39358 from Jeegn-Chen/wip-tracker-49206

rgw: avoid infinite loop when deleting a bucket

Signed-off-by: J. Eric Ivancich <ivancich@redhat.com>
This commit is contained in:
J. Eric Ivancich 2021-06-23 10:37:52 -04:00 committed by GitHub
commit da5d094f26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -8620,6 +8620,22 @@ int RGWRados::cls_bucket_list_ordered(const DoutPrefixProvider *dpp,
}
// A helper function to retrieve the hash source from an incomplete multipart entry
// by removing everything from the second last dot to the end.
static int parse_index_hash_source(const std::string& oid_wo_ns, std::string *index_hash_source) {
std::size_t found = oid_wo_ns.rfind('.');
if (found == std::string::npos || found < 1) {
return -EINVAL;
}
found = oid_wo_ns.rfind('.', found - 1);
if (found == std::string::npos || found < 1) {
return -EINVAL;
}
*index_hash_source = oid_wo_ns.substr(0, found);
return 0;
}
int RGWRados::cls_bucket_list_unordered(const DoutPrefixProvider *dpp,
RGWBucketInfo& bucket_info,
int shard_id,
@ -8668,18 +8684,11 @@ int RGWRados::cls_bucket_list_unordered(const DoutPrefixProvider *dpp,
// in it, so we need to get to the bucket shard index, so we can
// start reading from there
std::string key;
// test whether object name is a multipart meta name
if(! multipart_meta_filter.filter(start_after.name, key)) {
// if multipart_meta_filter fails, must be "regular" (i.e.,
// unadorned) and the name is the key
key = start_after.name;
}
// now convert the key (oid) to an rgw_obj_key since that will
// separate out the namespace, name, and instance
rgw_obj_key obj_key;
bool parsed = rgw_obj_key::parse_raw_oid(key, &obj_key);
bool parsed = rgw_obj_key::parse_raw_oid(start_after.name, &obj_key);
if (!parsed) {
ldpp_dout(dpp, 0) <<
"ERROR: RGWRados::cls_bucket_list_unordered received an invalid "
@ -8693,7 +8702,21 @@ int RGWRados::cls_bucket_list_unordered(const DoutPrefixProvider *dpp,
} else {
// so now we have the key used to compute the bucket index shard
// and can extract the specific shard from it
current_shard = svc.bi_rados->bucket_shard_index(obj_key.name, num_shards);
if (obj_key.ns == RGW_OBJ_NS_MULTIPART) {
// Use obj_key.ns == RGW_OBJ_NS_MULTIPART instead of
// the implementation relying on MultipartMetaFilter
// because MultipartMetaFilter only checks .meta suffix, which may
// exclude data multiparts but include some regular objects with .meta suffix
// by mistake.
string index_hash_source;
r = parse_index_hash_source(obj_key.name, &index_hash_source);
if (r < 0) {
return r;
}
current_shard = svc.bi_rados->bucket_shard_index(index_hash_source, num_shards);
} else {
current_shard = svc.bi_rados->bucket_shard_index(obj_key.name, num_shards);
}
}
}