From 8f01dd9ec9f170b2fe5a19a58c855c0cc782f680 Mon Sep 17 00:00:00 2001 From: Pritha Srivastava Date: Mon, 17 Feb 2020 21:03:19 +0530 Subject: [PATCH] rgw: Fix for correctly listing all elements of queue. The gc list operations lists 1000 elements at a time, and if 1000 elements are returned from a queue, then the next iteration also lists the same queue to see if there are some more elements. This fix takes care of cases when there are more than 1000 elements in the queue and the number of elements is a multiple of 1000. The truncated flag of queue list is also taken into account to determine whether we should continue processing the same queue or move on to the next gc object. Signed-off-by: Pritha Srivastava --- src/rgw/rgw_admin.cc | 3 ++- src/rgw/rgw_gc.cc | 16 +++++++++++++--- src/rgw/rgw_gc.h | 2 +- src/rgw/rgw_rados.cc | 4 ++-- src/rgw/rgw_rados.h | 2 +- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 4f4dc5d3f5b04..56560064fdb37 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -7129,11 +7129,12 @@ next: if (opt_cmd == OPT::GC_LIST) { int index = 0; bool truncated; + bool processing_queue = false; formatter->open_array_section("entries"); do { list result; - int ret = store->getRados()->list_gc_objs(&index, marker, 1000, !include_all, result, &truncated); + int ret = store->getRados()->list_gc_objs(&index, marker, 1000, !include_all, result, &truncated, processing_queue); if (ret < 0) { cerr << "ERROR: failed to list objs: " << cpp_strerror(-ret) << std::endl; return 1; diff --git a/src/rgw/rgw_gc.cc b/src/rgw/rgw_gc.cc index b8210edc88189..98be34bf4c282 100644 --- a/src/rgw/rgw_gc.cc +++ b/src/rgw/rgw_gc.cc @@ -190,7 +190,7 @@ int RGWGC::remove(int index, int num_entries) return store->gc_operate(obj_names[index], &op); } -int RGWGC::list(int *index, string& marker, uint32_t max, bool expired_only, std::list& result, bool *truncated) +int RGWGC::list(int *index, string& marker, uint32_t max, bool expired_only, std::list& result, bool *truncated, bool& processing_queue) { result.clear(); string next_marker; @@ -200,7 +200,8 @@ int RGWGC::list(int *index, string& marker, uint32_t max, bool expired_only, std std::list entries, queue_entries; int ret = 0; - if (! transitioned_objects_cache[*index] && ! check_queue) { + //processing_queue is set to true from previous iteration if the queue was under process and probably has more elements in it. + if (! transitioned_objects_cache[*index] && ! check_queue && ! processing_queue) { ret = cls_rgw_gc_list(store->gc_pool_ctx, obj_names[*index], marker, max - result.size(), expired_only, entries, truncated, next_marker); if (ret != -ENOENT && ret < 0) { return ret; @@ -229,7 +230,8 @@ int RGWGC::list(int *index, string& marker, uint32_t max, bool expired_only, std marker.clear(); } } - if (transitioned_objects_cache[*index] || check_queue) { + if (transitioned_objects_cache[*index] || check_queue || processing_queue) { + processing_queue = false; ret = cls_rgw_gc_queue_list_entries(store->gc_pool_ctx, obj_names[*index], marker, (max - result.size()) - entries.size(), expired_only, queue_entries, truncated, next_marker); if (ret < 0) { return ret; @@ -255,6 +257,13 @@ int RGWGC::list(int *index, string& marker, uint32_t max, bool expired_only, std } if (result.size() == max) { + if (queue_entries.size() > 0 && *truncated) { + processing_queue = true; + } else { + processing_queue = false; + *index += 1; //move to next gc object + } + /* close approximation, it might be that the next of the objects don't hold * anything, in this case truncated should have been false, but we can find * that out on the next iteration @@ -264,6 +273,7 @@ int RGWGC::list(int *index, string& marker, uint32_t max, bool expired_only, std } } *truncated = false; + processing_queue = false; return 0; } diff --git a/src/rgw/rgw_gc.h b/src/rgw/rgw_gc.h index 6917394a4648f..5dda753fd5483 100644 --- a/src/rgw/rgw_gc.h +++ b/src/rgw/rgw_gc.h @@ -62,7 +62,7 @@ public: void initialize(CephContext *_cct, RGWRados *_store); void finalize(); - int list(int *index, string& marker, uint32_t max, bool expired_only, std::list& result, bool *truncated); + int list(int *index, string& marker, uint32_t max, bool expired_only, std::list& result, bool *truncated, bool& processing_queue); void list_init(int *index) { *index = 0; } int process(int index, int process_max_secs, bool expired_only, RGWGCIOManager& io_manager); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 85f20574257f9..a11ac42a62f80 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -8017,9 +8017,9 @@ int RGWRados::gc_operate(string& oid, librados::ObjectReadOperation *op, bufferl return rgw_rados_operate(gc_pool_ctx, oid, op, pbl, null_yield); } -int RGWRados::list_gc_objs(int *index, string& marker, uint32_t max, bool expired_only, std::list& result, bool *truncated) +int RGWRados::list_gc_objs(int *index, string& marker, uint32_t max, bool expired_only, std::list& result, bool *truncated, bool& processing_queue) { - return gc->list(index, marker, max, expired_only, result, truncated); + return gc->list(index, marker, max, expired_only, result, truncated, processing_queue); } int RGWRados::process_gc(bool expired_only) diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 040f88d01be8c..e19b8d44811e6 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -1438,7 +1438,7 @@ public: librados::ObjectWriteOperation *op); int gc_operate(string& oid, librados::ObjectReadOperation *op, bufferlist *pbl); - int list_gc_objs(int *index, string& marker, uint32_t max, bool expired_only, std::list& result, bool *truncated); + int list_gc_objs(int *index, string& marker, uint32_t max, bool expired_only, std::list& result, bool *truncated, bool& processing_queue); int process_gc(bool expired_only); bool process_expire_objects(); int defer_gc(void *ctx, const RGWBucketInfo& bucket_info, const rgw_obj& obj, optional_yield y); -- 2.39.5