From: Casey Bodley Date: Tue, 11 Mar 2025 16:07:22 +0000 (-0400) Subject: cls/rgw: non-versioned listings skip past version suffix X-Git-Tag: v19.2.3~198^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=b49828d5a1d30feb578f2282b217567fb519c522;p=ceph.git cls/rgw: non-versioned listings skip past version suffix when skipping a versioned entry for a non-versioned listing, we must advance the marker or risk infinite loops. in particular, plain entries converted by convert_plain_entry_to_versioned() sort at the end of an object's versions, but have an empty version id whose retry would start back at the beginning of the object's versions Fixes: https://tracker.ceph.com/issues/70399 Signed-off-by: Casey Bodley (cherry picked from commit 90902ce21864cadeca87684eff0b0e1a24970384) --- diff --git a/src/cls/rgw/cls_rgw.cc b/src/cls/rgw/cls_rgw.cc index 32c83d49bb358..ec3ce531de84c 100644 --- a/src/cls/rgw/cls_rgw.cc +++ b/src/cls/rgw/cls_rgw.cc @@ -314,6 +314,14 @@ static void get_list_index_key(rgw_bucket_dir_entry& entry, string *index_key) index_key->append(entry.key.instance); } +// Format an omap key for an object name that sorts after all versioned keys +// generated by get_list_index_key(). +static std::string cls_rgw_after_versions(const std::string& key) +{ + // assert: ! key.empty() + return key + '\1'; // suffix "\1" sorts after suffixes like "\0v123\0iabc" +} + static void encode_obj_versioned_data_key(const cls_rgw_obj_key& key, string *index_key, bool append_delete_marker_suffix = false) { *index_key = BI_PREFIX_CHAR; @@ -604,6 +612,13 @@ int rgw_bucket_list(cls_method_context_t hctx, bufferlist *in, bufferlist *out) (!entry.is_visible() || op.start_obj.name == key.name)) { CLS_LOG(20, "%s: entry %s[%s] is not visible", __func__, key.name.c_str(), key.instance.c_str()); + + // advance past any versioned entries for this name + start_after_omap_key = cls_rgw_after_versions(key.name); + start_after_entry_key.set(start_after_omap_key); + + kiter = keys.lower_bound(start_after_omap_key); + --kiter; continue; }