Skip to content

Commit 90902ce

Browse files
committed
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 <[email protected]>
1 parent 9f55c66 commit 90902ce

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

src/cls/rgw/cls_rgw.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,14 @@ static void get_list_index_key(rgw_bucket_dir_entry& entry, string *index_key)
364364
index_key->append(entry.key.instance);
365365
}
366366

367+
// Format an omap key for an object name that sorts after all versioned keys
368+
// generated by get_list_index_key().
369+
static std::string cls_rgw_after_versions(const std::string& key)
370+
{
371+
// assert: ! key.empty()
372+
return key + '\1'; // suffix "\1" sorts after suffixes like "\0v123\0iabc"
373+
}
374+
367375
static void encode_obj_versioned_data_key(const cls_rgw_obj_key& key, string *index_key, bool append_delete_marker_suffix = false)
368376
{
369377
*index_key = BI_PREFIX_CHAR;
@@ -654,6 +662,13 @@ int rgw_bucket_list(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
654662
(!entry.is_visible() || op.start_obj.name == key.name)) {
655663
CLS_LOG(20, "%s: entry %s[%s] is not visible",
656664
__func__, key.name.c_str(), key.instance.c_str());
665+
666+
// advance past any versioned entries for this name
667+
start_after_omap_key = cls_rgw_after_versions(key.name);
668+
start_after_entry_key.set(start_after_omap_key);
669+
670+
kiter = keys.lower_bound(start_after_omap_key);
671+
--kiter;
657672
continue;
658673
}
659674

0 commit comments

Comments
 (0)