From a71455c8cddd0b59e6af5080c12fe33871216b86 Mon Sep 17 00:00:00 2001 From: Greg Farnum Date: Wed, 19 Oct 2011 16:24:40 -0700 Subject: [PATCH] rgw: properly handle cleaning up of listings If a listing you get back from the OSD consists only of non-existent entries, you still need to handle it and resume the listing from after those entries, or you get stuck in an infinite request loop. Handle this by pushing down the last entry handling. Signed-off-by: Greg Farnum --- src/rgw/rgw_rados.cc | 14 +++++++++----- src/rgw/rgw_rados.h | 4 +++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 19921c4b605c..cd1a97fc3422 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -357,7 +357,8 @@ int RGWRados::list_objects(string& id, rgw_bucket& bucket, int max, string& pref do { std::map ent_map; - int r = cls_bucket_list(bucket, cur_marker, max - count, ent_map, &truncated); + int r = cls_bucket_list(bucket, cur_marker, max - count, ent_map, + &truncated, &cur_marker); if (r < 0) return r; @@ -365,7 +366,6 @@ int RGWRados::list_objects(string& id, rgw_bucket& bucket, int max, string& pref for (eiter = ent_map.begin(); eiter != ent_map.end(); ++eiter) { string obj = eiter->first; string key = obj; - cur_marker = obj; if (!rgw_obj::translate_raw_obj(obj, ns)) continue; @@ -850,7 +850,8 @@ int RGWRados::delete_bucket(std::string& id, rgw_bucket& bucket, bool remove_poo do { #define NUM_ENTRIES 1000 - r = cls_bucket_list(bucket, marker, NUM_ENTRIES, ent_map, &is_truncated); + r = cls_bucket_list(bucket, marker, NUM_ENTRIES, ent_map, + &is_truncated, &marker); if (r < 0) return r; @@ -863,7 +864,6 @@ int RGWRados::delete_bucket(std::string& id, rgw_bucket& bucket, bool remove_poo if (rgw_obj::translate_raw_obj(obj, ns)) return -ENOTEMPTY; } - marker = obj; } while (is_truncated); if (remove_pool) { @@ -2105,7 +2105,7 @@ int RGWRados::cls_obj_complete_del(rgw_bucket& bucket, string& tag, uint64_t epo } int RGWRados::cls_bucket_list(rgw_bucket& bucket, string start, uint32_t num, map& m, - bool *is_truncated) + bool *is_truncated, string *last_entry) { dout(0) << "cls_bucket_list " << bucket << " start " << start << " num " << num << dendl; @@ -2173,6 +2173,10 @@ int RGWRados::cls_bucket_list(rgw_bucket& bucket, string start, uint32_t num, ma dout(0) << " got " << e.name << dendl; } + if (dir.m.size()) { + *last_entry = dir.m.rbegin()->first; + } + if (updates.length()) { // we don't care if we lose suggested updates, send them off blindly AioCompletion *c = librados::Rados::aio_create_completion(NULL, NULL, NULL); diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 2927229589b2..9c9e7055febb 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -305,7 +305,9 @@ public: RGWObjEnt& ent, RGWObjCategory category); int cls_obj_complete_add(rgw_bucket& bucket, string& tag, uint64_t epoch, RGWObjEnt& ent, RGWObjCategory category); int cls_obj_complete_del(rgw_bucket& bucket, string& tag, uint64_t epoch, string& name); - int cls_bucket_list(rgw_bucket& bucket, string start, uint32_t num, map& m, bool *is_truncated); + int cls_bucket_list(rgw_bucket& bucket, string start, uint32_t num, + map& m, bool *is_truncated, + string *last_entry = NULL); int cls_bucket_head(rgw_bucket& bucket, struct rgw_bucket_dir_header& header); int prepare_update_index(RGWObjState *state, rgw_bucket& bucket, string& oid, string& tag); int complete_update_index(rgw_bucket& bucket, string& oid, string& tag, uint64_t epoch, uint64_t size, -- 2.47.3