From: Daniel Gryniewicz Date: Mon, 14 Jun 2021 14:58:26 +0000 (-0400) Subject: Remove get_raw_obj() from Object X-Git-Tag: v17.1.0~1247^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ee35d48ca74a792a9e77a6a5a8b29fcc4e19f273;p=ceph.git Remove get_raw_obj() from Object Signed-off-by: Daniel Gryniewicz --- diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index 679968b1034b..87cdd054ec8b 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -314,139 +314,6 @@ int rgw_remove_object(const DoutPrefixProvider *dpp, rgw::sal::Store* store, rgw return object->delete_object(dpp, &rctx, null_yield); } -int rgw_remove_bucket_bypass_gc(rgw::sal::Store* store, rgw::sal::Bucket* bucket, - int concurrent_max, bool keep_index_consistent, - optional_yield y, - const DoutPrefixProvider *dpp) -{ - int ret; - map stats; - map common_prefixes; - RGWObjectCtx obj_ctx(store); - CephContext *cct = store->ctx(); - - string bucket_ver, master_ver; - - ret = bucket->get_bucket_info(dpp, null_yield); - if (ret < 0) - return ret; - - ret = bucket->get_bucket_stats(dpp, RGW_NO_SHARD, &bucket_ver, &master_ver, stats, NULL); - if (ret < 0) - return ret; - - string prefix, delimiter; - - ret = abort_bucket_multiparts(dpp, store, cct, bucket, prefix, delimiter); - if (ret < 0) { - return ret; - } - - rgw::sal::Bucket::ListParams params; - rgw::sal::Bucket::ListResults results; - - params.list_versions = true; - params.allow_unordered = true; - - std::unique_ptr handles = store->get_completions(); - - int max_aio = concurrent_max; - results.is_truncated = true; - - while (results.is_truncated) { - ret = bucket->list(dpp, params, listing_max_entries, results, null_yield); - if (ret < 0) - return ret; - - std::vector::iterator it = results.objs.begin(); - for (; it != results.objs.end(); ++it) { - RGWObjState *astate = NULL; - std::unique_ptr obj = bucket->get_object((*it).key); - - ret = obj->get_obj_state(dpp, &obj_ctx, &astate, y, false); - if (ret == -ENOENT) { - ldpp_dout(dpp, 1) << "WARNING: cannot find obj state for obj " << obj << dendl; - continue; - } - if (ret < 0) { - ldpp_dout(dpp, -1) << "ERROR: get obj state returned with error " << ret << dendl; - return ret; - } - - if (astate->manifest) { - RGWObjManifest& manifest = *astate->manifest; - RGWObjManifest::obj_iterator miter = manifest.obj_begin(dpp); - std::unique_ptr head_obj = bucket->get_object(manifest.get_obj().key); - rgw_raw_obj raw_head_obj; - head_obj->get_raw_obj(&raw_head_obj); - - for (; miter != manifest.obj_end(dpp) && max_aio--; ++miter) { - if (!max_aio) { - ret = handles->drain(); - if (ret < 0) { - ldpp_dout(dpp, -1) << "ERROR: could not drain handles as aio completion returned with " << ret << dendl; - return ret; - } - max_aio = concurrent_max; - } - - rgw_raw_obj last_obj = miter.get_location().get_raw_obj(store); - if (last_obj == raw_head_obj) { - // have the head obj deleted at the end - continue; - } - - ret = store->delete_raw_obj_aio(dpp, last_obj, handles.get()); - if (ret < 0) { - ldpp_dout(dpp, -1) << "ERROR: delete obj aio failed with " << ret << dendl; - return ret; - } - } // for all shadow objs - - ret = head_obj->delete_obj_aio(dpp, astate, handles.get(), keep_index_consistent, null_yield); - if (ret < 0) { - ldpp_dout(dpp, -1) << "ERROR: delete obj aio failed with " << ret << dendl; - return ret; - } - } - - if (!max_aio) { - ret = handles->drain(); - if (ret < 0) { - ldpp_dout(dpp, -1) << "ERROR: could not drain handles as aio completion returned with " << ret << dendl; - return ret; - } - max_aio = concurrent_max; - } - obj_ctx.invalidate(obj->get_obj()); - } // for all RGW objects - } - - ret = handles->drain(); - if (ret < 0) { - ldpp_dout(dpp, -1) << "ERROR: could not drain handles as aio completion returned with " << ret << dendl; - return ret; - } - - bucket->sync_user_stats(dpp, y); - if (ret < 0) { - ldpp_dout(dpp, 1) << "WARNING: failed sync user stats before bucket delete. ret=" << ret << dendl; - } - - RGWObjVersionTracker objv_tracker; - - // this function can only be run if caller wanted children to be - // deleted, so we can ignore the check for children as any that - // remain are detritus from a prior bug - ret = bucket->remove_bucket(dpp, true, std::string(), std::string(), false, nullptr, y); - if (ret < 0) { - ldpp_dout(dpp, -1) << "ERROR: could not remove bucket " << bucket << dendl; - return ret; - } - - return ret; -} - static void set_err_msg(std::string *sink, std::string msg) { if (sink && !msg.empty()) @@ -1139,7 +1006,7 @@ int RGWBucketAdminOp::remove_bucket(rgw::sal::Store* store, RGWBucketAdminOpStat return ret; if (bypass_gc) - ret = rgw_remove_bucket_bypass_gc(store, bucket.get(), op_state.get_max_aio(), keep_index_consistent, y, dpp); + ret = bucket->remove_bucket_bypass_gc(op_state.get_max_aio(), keep_index_consistent, y, dpp); else ret = bucket->remove_bucket(dpp, op_state.will_delete_children(), string(), string(), false, nullptr, y); diff --git a/src/rgw/rgw_bucket.h b/src/rgw/rgw_bucket.h index 36df4a524996..d09abfd9181a 100644 --- a/src/rgw/rgw_bucket.h +++ b/src/rgw/rgw_bucket.h @@ -220,7 +220,6 @@ public: }; extern int rgw_remove_object(const DoutPrefixProvider *dpp, rgw::sal::Store* store, rgw::sal::Bucket* bucket, rgw_obj_key& key); -extern int rgw_remove_bucket_bypass_gc(rgw::sal::Store* store, rgw::sal::Bucket* bucket, int concurrent_max, optional_yield y); extern int rgw_object_get_attr(rgw::sal::Store* store, rgw::sal::Object* obj, const char* attr_name, bufferlist& out_bl, diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h index df900c1681d4..7aa34080240a 100644 --- a/src/rgw/rgw_sal.h +++ b/src/rgw/rgw_sal.h @@ -378,6 +378,10 @@ class Bucket { virtual Attrs& get_attrs(void) { return attrs; } virtual int set_attrs(Attrs a) { attrs = a; return 0; } virtual int remove_bucket(const DoutPrefixProvider* dpp, bool delete_children, std::string prefix, std::string delimiter, bool forward_to_master, req_info* req_info, optional_yield y) = 0; + virtual int remove_bucket_bypass_gc(int concurrent_max, bool + keep_index_consistent, + optional_yield y, const + DoutPrefixProvider *dpp) = 0; virtual RGWAccessControlPolicy& get_acl(void) = 0; virtual int set_acl(const DoutPrefixProvider* dpp, RGWAccessControlPolicy& acl, optional_yield y) = 0; virtual int get_bucket_info(const DoutPrefixProvider* dpp, optional_yield y) = 0; @@ -686,7 +690,6 @@ class Object { virtual bool is_expired() = 0; virtual void gen_rand_obj_instance_name() = 0; virtual void raw_obj_to_obj(const rgw_raw_obj& raw_obj) = 0; - virtual void get_raw_obj(rgw_raw_obj* raw_obj) = 0; virtual MPSerializer* get_serializer(const DoutPrefixProvider *dpp, const std::string& lock_name) = 0; virtual int transition(RGWObjectCtx& rctx, Bucket* bucket, diff --git a/src/rgw/rgw_sal_rados.cc b/src/rgw/rgw_sal_rados.cc index 98877909600a..be0c29eec102 100644 --- a/src/rgw/rgw_sal_rados.cc +++ b/src/rgw/rgw_sal_rados.cc @@ -46,7 +46,9 @@ namespace rgw::sal { -RadosObject::~RadosObject() {} +// default number of entries to list with each bucket listing call +// (use marker to bridge between calls) +static constexpr size_t listing_max_entries = 1000; static int decode_policy(CephContext* cct, bufferlist& bl, @@ -316,6 +318,139 @@ int RadosBucket::remove_bucket(const DoutPrefixProvider* dpp, return ret; } +int RadosBucket::remove_bucket_bypass_gc(int concurrent_max, bool + keep_index_consistent, + optional_yield y, const + DoutPrefixProvider *dpp) +{ + int ret; + map stats; + map common_prefixes; + RGWObjectCtx obj_ctx(store); + CephContext *cct = store->ctx(); + + string bucket_ver, master_ver; + + ret = get_bucket_info(dpp, null_yield); + if (ret < 0) + return ret; + + ret = get_bucket_stats(dpp, RGW_NO_SHARD, &bucket_ver, &master_ver, stats, NULL); + if (ret < 0) + return ret; + + string prefix, delimiter; + + ret = abort_bucket_multiparts(dpp, store, cct, this, prefix, delimiter); + if (ret < 0) { + return ret; + } + + rgw::sal::Bucket::ListParams params; + rgw::sal::Bucket::ListResults results; + + params.list_versions = true; + params.allow_unordered = true; + + std::unique_ptr handles = store->get_completions(); + + int max_aio = concurrent_max; + results.is_truncated = true; + + while (results.is_truncated) { + ret = list(dpp, params, listing_max_entries, results, null_yield); + if (ret < 0) + return ret; + + std::vector::iterator it = results.objs.begin(); + for (; it != results.objs.end(); ++it) { + RGWObjState *astate = NULL; + std::unique_ptr obj = get_object((*it).key); + + ret = obj->get_obj_state(dpp, &obj_ctx, &astate, y, false); + if (ret == -ENOENT) { + ldpp_dout(dpp, 1) << "WARNING: cannot find obj state for obj " << obj << dendl; + continue; + } + if (ret < 0) { + ldpp_dout(dpp, -1) << "ERROR: get obj state returned with error " << ret << dendl; + return ret; + } + + if (astate->manifest) { + RGWObjManifest& manifest = *astate->manifest; + RGWObjManifest::obj_iterator miter = manifest.obj_begin(dpp); + std::unique_ptr head_obj = get_object(manifest.get_obj().key); + rgw_raw_obj raw_head_obj; + dynamic_cast(head_obj.get())->get_raw_obj(&raw_head_obj); + + for (; miter != manifest.obj_end(dpp) && max_aio--; ++miter) { + if (!max_aio) { + ret = handles->drain(); + if (ret < 0) { + ldpp_dout(dpp, -1) << "ERROR: could not drain handles as aio completion returned with " << ret << dendl; + return ret; + } + max_aio = concurrent_max; + } + + rgw_raw_obj last_obj = miter.get_location().get_raw_obj(store); + if (last_obj == raw_head_obj) { + // have the head obj deleted at the end + continue; + } + + ret = store->delete_raw_obj_aio(dpp, last_obj, handles.get()); + if (ret < 0) { + ldpp_dout(dpp, -1) << "ERROR: delete obj aio failed with " << ret << dendl; + return ret; + } + } // for all shadow objs + + ret = head_obj->delete_obj_aio(dpp, astate, handles.get(), keep_index_consistent, null_yield); + if (ret < 0) { + ldpp_dout(dpp, -1) << "ERROR: delete obj aio failed with " << ret << dendl; + return ret; + } + } + + if (!max_aio) { + ret = handles->drain(); + if (ret < 0) { + ldpp_dout(dpp, -1) << "ERROR: could not drain handles as aio completion returned with " << ret << dendl; + return ret; + } + max_aio = concurrent_max; + } + obj_ctx.invalidate(obj->get_obj()); + } // for all RGW objects + } + + ret = handles->drain(); + if (ret < 0) { + ldpp_dout(dpp, -1) << "ERROR: could not drain handles as aio completion returned with " << ret << dendl; + return ret; + } + + sync_user_stats(dpp, y); + if (ret < 0) { + ldpp_dout(dpp, 1) << "WARNING: failed sync user stats before bucket delete. ret=" << ret << dendl; + } + + RGWObjVersionTracker objv_tracker; + + // this function can only be run if caller wanted children to be + // deleted, so we can ignore the check for children as any that + // remain are detritus from a prior bug + ret = remove_bucket(dpp, true, std::string(), std::string(), false, nullptr, y); + if (ret < 0) { + ldpp_dout(dpp, -1) << "ERROR: could not remove bucket " << this << dendl; + return ret; + } + + return ret; +} + int RadosBucket::get_bucket_info(const DoutPrefixProvider* dpp, optional_yield y) { auto obj_ctx = store->svc()->sysobj->init_obj_ctx(); @@ -1242,6 +1377,8 @@ int Object::range_to_ofs(uint64_t obj_size, int64_t &ofs, int64_t &end) return 0; } +RadosObject::~RadosObject() {} + int RadosObject::get_obj_state(const DoutPrefixProvider* dpp, RGWObjectCtx* rctx, RGWObjState **state, optional_yield y, bool follow_olh) { return store->getRados()->get_obj_state(dpp, rctx, bucket->get_info(), get_obj(), state, follow_olh, y); @@ -1996,7 +2133,7 @@ RadosWriter::~RadosWriter() std::optional raw_head; if (!rgw::sal::Object::empty(head_obj.get())) { raw_head.emplace(); - head_obj->get_raw_obj(&*raw_head); + dynamic_cast(head_obj.get())->get_raw_obj(&*raw_head); } /** diff --git a/src/rgw/rgw_sal_rados.h b/src/rgw/rgw_sal_rados.h index 4a417eca2197..5fdf440bff58 100644 --- a/src/rgw/rgw_sal_rados.h +++ b/src/rgw/rgw_sal_rados.h @@ -186,7 +186,7 @@ class RadosObject : public Object { virtual bool is_expired() override; virtual void gen_rand_obj_instance_name() override; virtual void raw_obj_to_obj(const rgw_raw_obj& raw_obj) override; - virtual void get_raw_obj(rgw_raw_obj* raw_obj) override; + void get_raw_obj(rgw_raw_obj* raw_obj); virtual std::unique_ptr clone() override { return std::unique_ptr(new RadosObject(*this)); } @@ -294,6 +294,10 @@ class RadosBucket : public Bucket { virtual int list(const DoutPrefixProvider* dpp, ListParams&, int, ListResults&, optional_yield y) override; Object* create_object(const rgw_obj_key& key /* Attributes */) override; virtual int remove_bucket(const DoutPrefixProvider* dpp, bool delete_children, std::string prefix, std::string delimiter, bool forward_to_master, req_info* req_info, optional_yield y) override; + virtual int remove_bucket_bypass_gc(int concurrent_max, bool + keep_index_consistent, + optional_yield y, const + DoutPrefixProvider *dpp) override; virtual RGWAccessControlPolicy& get_acl(void) override { return acls; } virtual int set_acl(const DoutPrefixProvider* dpp, RGWAccessControlPolicy& acl, optional_yield y) override; virtual int get_bucket_info(const DoutPrefixProvider* dpp, optional_yield y) override;