From 7ac6ef454b6052b07b9e64a061543e8f6b27a7a9 Mon Sep 17 00:00:00 2001 From: Cory Snyder Date: Mon, 3 Jul 2023 19:01:47 +0000 Subject: [PATCH] rgw: extract apply_olh logic for clearing olh to a method Also clears stale pending entries prior to attempting to clear OLH index entries and remove the OLH object. Signed-off-by: Cory Snyder (cherry picked from commit 3437897deaec478f231dcad68b05fa38a7f2cb10) Conflicts: src/rgw/driver/rados/rgw_rados.cc src/rgw/driver/rados/rgw_rados.h Cherry-pick notes: - conflicts due to https://github.com/ceph/ceph/pull/50206 on main but not reef --- src/rgw/driver/rados/rgw_rados.cc | 92 ++++++++++++++++++++++++------- src/rgw/driver/rados/rgw_rados.h | 20 ++++++- 2 files changed, 89 insertions(+), 23 deletions(-) diff --git a/src/rgw/driver/rados/rgw_rados.cc b/src/rgw/driver/rados/rgw_rados.cc index 21f22214bab..2544bb3ee30 100644 --- a/src/rgw/driver/rados/rgw_rados.cc +++ b/src/rgw/driver/rados/rgw_rados.cc @@ -7292,7 +7292,7 @@ int RGWRados::bucket_index_trim_olh_log(const DoutPrefixProvider *dpp, int RGWRados::bucket_index_clear_olh(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, - RGWObjState& state, + const std::string& olh_tag, const rgw_obj& obj_instance) { rgw_rados_ref ref; @@ -7303,8 +7303,6 @@ int RGWRados::bucket_index_clear_olh(const DoutPrefixProvider *dpp, BucketShard bs(this); - string olh_tag(state.olh_tag.c_str(), state.olh_tag.length()); - cls_rgw_obj_key key(obj_instance.key.get_index_key_name(), string()); int ret = guard_reshard(dpp, &bs, obj_instance, bucket_info, @@ -7478,28 +7476,80 @@ int RGWRados::apply_olh_log(const DoutPrefixProvider *dpp, } if (need_to_remove) { - ObjectWriteOperation rm_op; + string olh_tag(state.olh_tag.c_str(), state.olh_tag.length()); + clear_olh(dpp, obj_ctx, obj, bucket_info, ref, olh_tag, last_ver, null_yield); + } - rm_op.cmpxattr(RGW_ATTR_OLH_ID_TAG, CEPH_OSD_CMPXATTR_OP_EQ, olh_tag); - rm_op.cmpxattr(RGW_ATTR_OLH_VER, CEPH_OSD_CMPXATTR_OP_EQ, last_ver); - cls_obj_check_prefix_exist(rm_op, RGW_ATTR_OLH_PENDING_PREFIX, true); /* fail if found one of these, pending modification */ - rm_op.remove(); + return 0; +} - r = rgw_rados_operate(dpp, ref.pool.ioctx(), ref.obj.oid, &rm_op, null_yield); - if (r == -ECANCELED) { - return 0; /* someone else won this race */ - } else { - /* - * only clear if was successful, otherwise we might clobber pending operations on this object - */ - r = bucket_index_clear_olh(dpp, bucket_info, state, obj); - if (r < 0) { - ldpp_dout(dpp, 0) << "ERROR: could not clear bucket index olh entries r=" << r << dendl; - return r; - } +int RGWRados::clear_olh(const DoutPrefixProvider *dpp, + RGWObjectCtx& obj_ctx, + const rgw_obj& obj, + RGWBucketInfo& bucket_info, + const std::string& tag, + const uint64_t ver, + optional_yield y) { + rgw_rados_ref ref; + int r = get_obj_head_ref(dpp, bucket_info, obj, &ref); + if (r < 0) { + return r; + } + return clear_olh(dpp, obj_ctx, obj, bucket_info, ref, tag, ver, y); +} + + +int RGWRados::clear_olh(const DoutPrefixProvider *dpp, + RGWObjectCtx& obj_ctx, + const rgw_obj& obj, + RGWBucketInfo& bucket_info, + rgw_rados_ref& ref, + const std::string& tag, + const uint64_t ver, + optional_yield y) { + ObjectWriteOperation rm_op; + + RGWObjManifest *manifest = nullptr; + RGWObjState *s = nullptr; + + int r = get_obj_state(dpp, &obj_ctx, bucket_info, obj, &s, &manifest, false, y); + if (r < 0) { + return r; + } + map pending_entries; + rgw_filter_attrset(s->attrset, RGW_ATTR_OLH_PENDING_PREFIX, &pending_entries); + + map rm_pending_entries; + check_pending_olh_entries(dpp, pending_entries, &rm_pending_entries); + + if (!rm_pending_entries.empty()) { + r = remove_olh_pending_entries(dpp, bucket_info, *s, obj, rm_pending_entries); + if (r < 0) { + ldpp_dout(dpp, 0) << "ERROR: rm_pending_entries returned ret=" << r << dendl; + return r; } } + bufferlist tag_bl; + tag_bl.append(tag.c_str(), tag.length()); + rm_op.cmpxattr(RGW_ATTR_OLH_ID_TAG, CEPH_OSD_CMPXATTR_OP_EQ, tag_bl); + rm_op.cmpxattr(RGW_ATTR_OLH_VER, CEPH_OSD_CMPXATTR_OP_EQ, ver); + cls_obj_check_prefix_exist(rm_op, RGW_ATTR_OLH_PENDING_PREFIX, true); /* fail if found one of these, pending modification */ + rm_op.remove(); + + r = rgw_rados_operate(dpp, ref.pool.ioctx(), ref.obj.oid, &rm_op, y); + if (r == -ECANCELED) { + return r; /* someone else made a modification in the meantime */ + } else { + /* + * only clear if was successful, otherwise we might clobber pending operations on this object + */ + r = bucket_index_clear_olh(dpp, bucket_info, tag, obj); + if (r < 0) { + ldpp_dout(dpp, 0) << "ERROR: could not clear bucket index olh entries r=" << r << dendl; + return r; + } + } return 0; } @@ -7729,7 +7779,7 @@ void RGWRados::check_pending_olh_entries(const DoutPrefixProvider *dpp, } } -int RGWRados::remove_olh_pending_entries(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& olh_obj, map& pending_attrs) +int RGWRados::remove_olh_pending_entries(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& olh_obj, map& pending_attrs) { rgw_rados_ref ref; int r = get_obj_head_ref(dpp, bucket_info, olh_obj, &ref); diff --git a/src/rgw/driver/rados/rgw_rados.h b/src/rgw/driver/rados/rgw_rados.h index 9e38e09e89b..890505e45b7 100644 --- a/src/rgw/driver/rados/rgw_rados.h +++ b/src/rgw/driver/rados/rgw_rados.h @@ -399,6 +399,15 @@ class RGWRados int get_system_obj_ref(const DoutPrefixProvider *dpp, const rgw_raw_obj& obj, rgw_rados_ref *ref); uint64_t max_bucket_id; + int clear_olh(const DoutPrefixProvider *dpp, + RGWObjectCtx& obj_ctx, + const rgw_obj& obj, + RGWBucketInfo& bucket_info, + rgw_rados_ref& ref, + const std::string& tag, + const uint64_t ver, + optional_yield y); + int get_olh_target_state(const DoutPrefixProvider *dpp, RGWObjectCtx& rctx, RGWBucketInfo& bucket_info, const rgw_obj& obj, RGWObjState *olh_state, RGWObjState **target_state, @@ -1319,11 +1328,18 @@ public: const rgw_obj& obj_instance, uint64_t ver_marker, std::map > *log, bool *is_truncated); int bucket_index_trim_olh_log(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, RGWObjState& obj_state, const rgw_obj& obj_instance, uint64_t ver); - int bucket_index_clear_olh(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& obj_instance); + int bucket_index_clear_olh(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, const std::string& olh_tag, const rgw_obj& obj_instance); int apply_olh_log(const DoutPrefixProvider *dpp, RGWObjectCtx& obj_ctx, RGWObjState& obj_state, RGWBucketInfo& bucket_info, const rgw_obj& obj, bufferlist& obj_tag, std::map >& log, uint64_t *plast_ver, rgw_zone_set *zones_trace = nullptr); int update_olh(const DoutPrefixProvider *dpp, RGWObjectCtx& obj_ctx, RGWObjState *state, RGWBucketInfo& bucket_info, const rgw_obj& obj, rgw_zone_set *zones_trace = nullptr); + int clear_olh(const DoutPrefixProvider *dpp, + RGWObjectCtx& obj_ctx, + const rgw_obj& obj, + RGWBucketInfo& bucket_info, + const std::string& tag, + const uint64_t ver, + optional_yield y); int set_olh(const DoutPrefixProvider *dpp, RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, const rgw_obj& target_obj, bool delete_marker, rgw_bucket_dir_entry_meta *meta, uint64_t olh_epoch, ceph::real_time unmod_since, bool high_precision_time, optional_yield y, rgw_zone_set *zones_trace = nullptr, bool log_data_change = false); @@ -1333,7 +1349,7 @@ public: uint64_t olh_epoch, optional_yield y, rgw_zone_set *zones_trace = nullptr); void check_pending_olh_entries(const DoutPrefixProvider *dpp, std::map& pending_entries, std::map *rm_pending_entries); - int remove_olh_pending_entries(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& olh_obj, std::map& pending_attrs); + int remove_olh_pending_entries(const DoutPrefixProvider *dpp, const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& olh_obj, std::map& pending_attrs); int follow_olh(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, RGWObjectCtx& ctx, RGWObjState *state, const rgw_obj& olh_obj, rgw_obj *target); int get_olh(const DoutPrefixProvider *dpp, RGWBucketInfo& bucket_info, const rgw_obj& obj, RGWOLHInfo *olh); -- 2.39.5