From 37b37e78f858a2d981698de2e9e1aafef7953642 Mon Sep 17 00:00:00 2001 From: Orit Wasserman Date: Mon, 31 Jul 2017 14:45:25 +0300 Subject: [PATCH] rgw: Fix up to 1000 entries at a time in check_bad_index_multipart Fixes: http://tracker.ceph.com/issues/20772 Signed-off-by: Orit Wasserman (cherry picked from commit 25cef9a09721e1a67d217535d4d624ab60adca02) Signed-off-by: Matt Benjamin --- src/rgw/rgw_bucket.cc | 49 ++++++++++++++++++++++++++----------------- src/rgw/rgw_bucket.h | 3 ++- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index 88695ad74953..e44ccca1b59b 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -431,16 +431,9 @@ int rgw_bucket_set_attrs(RGWRados *store, RGWBucketInfo& bucket_info, static void dump_mulipart_index_results(list& objs_to_unlink, Formatter *f) { - // make sure that an appropiately titled header has been opened previously - list::iterator oiter = objs_to_unlink.begin(); - - f->open_array_section("invalid_multipart_entries"); - - for ( ; oiter != objs_to_unlink.end(); ++oiter) { - f->dump_string("object", oiter->name); + for (const auto& o : objs_to_unlink) { + f->dump_string("object", o.name); } - - f->close_section(); } void check_bad_user_bucket_mapping(RGWRados *store, const rgw_user& user_id, @@ -1008,12 +1001,13 @@ static void dump_index_check(map existing_stats } int RGWBucket::check_bad_index_multipart(RGWBucketAdminOpState& op_state, - list& objs_to_unlink, std::string *err_msg) + RGWFormatterFlusher& flusher, + std::string *err_msg) { bool fix_index = op_state.will_fix_index(); rgw_bucket bucket = op_state.get_bucket(); - int max = 1000; + size_t max = 1000; map common_prefixes; string ns = ""; @@ -1076,6 +1070,11 @@ int RGWBucket::check_bad_index_multipart(RGWBucketAdminOpState& op_state, } while (is_truncated); + list objs_to_unlink; + Formatter *f = flusher.get_formatter(); + + f->open_array_section("invalid_multipart_entries"); + map::iterator aiter; for (aiter = all_objs.begin(); aiter != all_objs.end(); ++aiter) { string& name = aiter->second; @@ -1083,10 +1082,22 @@ int RGWBucket::check_bad_index_multipart(RGWBucketAdminOpState& op_state, if (meta_objs.find(name) == meta_objs.end()) { objs_to_unlink.push_back(aiter->first); } - } - if (objs_to_unlink.empty()) - return 0; + if (objs_to_unlink.size() > max) { + if (fix_index) { + int r = store->remove_objs_from_index(bucket, objs_to_unlink); + if (r < 0) { + set_err_msg(err_msg, "ERROR: remove_obj_from_index() returned error: " + + cpp_strerror(-r)); + return r; + } + } + + dump_mulipart_index_results(objs_to_unlink, flusher.get_formatter()); + flusher.flush(); + objs_to_unlink.clear(); + } + } if (fix_index) { int r = store->remove_objs_from_index(bucket, objs_to_unlink); @@ -1098,6 +1109,10 @@ int RGWBucket::check_bad_index_multipart(RGWBucketAdminOpState& op_state, } } + dump_mulipart_index_results(objs_to_unlink, f); + f->close_section(); + flusher.flush(); + return 0; } @@ -1315,7 +1330,6 @@ int RGWBucketAdminOp::check_index(RGWRados *store, RGWBucketAdminOpState& op_sta map result; map existing_stats; map calculated_stats; - list objs_to_unlink; RGWBucket bucket; @@ -1326,13 +1340,10 @@ int RGWBucketAdminOp::check_index(RGWRados *store, RGWBucketAdminOpState& op_sta Formatter *formatter = flusher.get_formatter(); flusher.start(0); - ret = bucket.check_bad_index_multipart(op_state, objs_to_unlink); + ret = bucket.check_bad_index_multipart(op_state, flusher); if (ret < 0) return ret; - dump_mulipart_index_results(objs_to_unlink, formatter); - flusher.flush(); - ret = bucket.check_object_index(op_state, result); if (ret < 0) return ret; diff --git a/src/rgw/rgw_bucket.h b/src/rgw/rgw_bucket.h index 765ec6a6caac..d68e890c901f 100644 --- a/src/rgw/rgw_bucket.h +++ b/src/rgw/rgw_bucket.h @@ -274,7 +274,8 @@ public: int init(RGWRados *storage, RGWBucketAdminOpState& op_state); int check_bad_index_multipart(RGWBucketAdminOpState& op_state, - list& objs_to_unlink, std::string *err_msg = NULL); + RGWFormatterFlusher& flusher, + std::string *err_msg = NULL); int check_object_index(RGWBucketAdminOpState& op_state, map result, std::string *err_msg = NULL); -- 2.47.3