mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-27 00:38:16 +00:00
d91f4d4557
Non-slash delimiter ListObjects/ListObjectVersions force a recursive walk and defer common-prefix folding to from_meta_cache_entries_sorted_infos. When a page of max_keys+1 raw candidates collapses into fewer than max_keys common prefixes, list_objects_paginate left is_truncated=false with no next_marker even though the walker had filled its raw candidate limit (disk_has_more=true). Clients were told listing was complete and silently lost every key beyond the scan window, a data-loss bug for backup/sync/mirror/reconcile consumers (backlog ECA-03 / #944). Add a delimiter re-fold guard: when disk_has_more is true but the folded visible entries are fewer than max_keys, set is_truncated=true and continue from the last RAW scanned key (captured before folding via last_scanned_entry_name). Using the last raw key rather than a folded prefix is required for correctness: forward_past advances on name > marker, and a folded prefix such as "data-" is lexicographically smaller than its own keys ("data-0001"), so it would re-list and re-fold the same keys forever. A real scanned key strictly advances past the scanned window and keeps pagination finite. The slash-delimiter and no-delimiter paths fold during the walk and are unaffected. Regression tests cover the direct re-fold case, the disk-exhausted no-marker case, the no-delimiter path guard, and an end-to-end 5000 data-* + 100 other-* paging loop asserting bounded termination and full common-prefix coverage. Co-authored-by: heihutu <heihutu@gmail.com>