From 9457abb729754458aafc07a9ee514407906a1011 Mon Sep 17 00:00:00 2001 From: "J. Eric Ivancich" Date: Fri, 31 Jan 2020 15:01:40 -0500 Subject: [PATCH] rgw: fix bug with (un)ordered bucket listing and marker w/ namespace When listing without specifying a namespace, the returned entries could be in one or more namespaces. The marker used to continue the listing may therefore contain a namespace, and that needs to be preserved. This fixes a bug in both ordered and unordered listings where it was not preserved. Signed-off-by: J. Eric Ivancich --- src/rgw/rgw_common.h | 8 ++++++++ src/rgw/rgw_rados.cc | 30 +++++++++++++++++------------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 07745d6adc3..8d840731fe0 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -1371,6 +1371,14 @@ struct rgw_obj_key { return instance; } + void set_ns(const std::string& _ns) { + ns = _ns; + } + + const std::string& get_ns() const { + return ns; + } + string get_index_key_name() const { if (ns.empty()) { if (name.size() < 1 || name[0] != '_') { diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 85f20574257..de678164c21 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -1746,21 +1746,23 @@ int RGWRados::Bucket::List::list_objects_ordered( result->clear(); + // use a local marker; either the marker will have a previous entry + // or it will be empty; either way it's OK to copy rgw_obj_key marker_obj(params.marker.name, params.marker.instance, - params.ns); + params.marker.ns); rgw_obj_index_key cur_marker; marker_obj.get_index_key(&cur_marker); rgw_obj_key end_marker_obj(params.end_marker.name, params.end_marker.instance, - params.ns); + params.end_marker.ns); rgw_obj_index_key cur_end_marker; end_marker_obj.get_index_key(&cur_end_marker); const bool cur_end_marker_valid = !params.end_marker.empty(); rgw_obj_key prefix_obj(params.prefix); - prefix_obj.ns = params.ns; + prefix_obj.set_ns(params.ns); string cur_prefix = prefix_obj.get_index_key_name(); string after_delim_s; /* needed in !params.delim.empty() AND later */ @@ -1858,8 +1860,8 @@ int RGWRados::Bucket::List::list_objects_ordered( } if (count < max) { - params.marker = index_key; - next_marker = index_key; + params.marker = index_key; + next_marker = index_key; } if (params.filter && @@ -2038,21 +2040,23 @@ int RGWRados::Bucket::List::list_objects_unordered(int64_t max_p, result->clear(); + // use a local marker; either the marker will have a previous entry + // or it will be empty; either way it's OK to copy rgw_obj_key marker_obj(params.marker.name, params.marker.instance, - params.ns); + params.marker.ns); rgw_obj_index_key cur_marker; marker_obj.get_index_key(&cur_marker); rgw_obj_key end_marker_obj(params.end_marker.name, params.end_marker.instance, - params.ns); + params.end_marker.ns); rgw_obj_index_key cur_end_marker; end_marker_obj.get_index_key(&cur_end_marker); const bool cur_end_marker_valid = !params.end_marker.empty(); rgw_obj_key prefix_obj(params.prefix); - prefix_obj.ns = params.ns; + prefix_obj.set_ns(params.ns); string cur_prefix = prefix_obj.get_index_key_name(); while (truncated && count <= max) { @@ -2078,6 +2082,11 @@ int RGWRados::Bucket::List::list_objects_unordered(int64_t max_p, rgw_obj_index_key index_key = entry.key; rgw_obj_key obj(index_key); + if (count < max) { + params.marker.set(index_key); + next_marker.set(index_key); + } + /* note that parse_raw_oid() here will not set the correct * object's instance, as rgw_obj_index_key encodes that * separately. We don't need to set the instance because it's @@ -2105,11 +2114,6 @@ int RGWRados::Bucket::List::list_objects_unordered(int64_t max_p, continue; } - if (count < max) { - params.marker.set(index_key); - next_marker.set(index_key); - } - if (params.filter && !params.filter->filter(obj.name, index_key.name)) continue; -- 2.39.5