From 83e895a02fff83fbb476ec97048e763b08a8bc48 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Fri, 3 Oct 2025 12:24:18 -0400 Subject: [PATCH] rgw: fix 'bucket rm --bypass-gc' for copied objects the `--bypass-gc` argument to `radosgw-admin bucket rm` causes us to call `RadosBucket::remove_bypass_gc()`, which loops over the tail objects and removes each with `RGWRados::delete_raw_obj_aio()` however, this was removing the objects with `cls_rgw_remove_obj()`, which is for head objects, not tails. tail objects must be removed with `cls_refcount_put()`, which preserves them until the last copy is removed rename `delete_raw_obj_aio()` to `delete_tail_obj_aio()` to clarify its purpose Fixes: https://tracker.ceph.com/issues/73348 Signed-off-by: Casey Bodley (cherry picked from commit 1fba459071da9f7ec13defe2c666f0df8174c8da) --- src/rgw/driver/rados/rgw_rados.cc | 8 +++++--- src/rgw/driver/rados/rgw_rados.h | 3 ++- src/rgw/driver/rados/rgw_sal_rados.cc | 6 +++++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/rgw/driver/rados/rgw_rados.cc b/src/rgw/driver/rados/rgw_rados.cc index 707b35f70956..63a4c1f3d325 100644 --- a/src/rgw/driver/rados/rgw_rados.cc +++ b/src/rgw/driver/rados/rgw_rados.cc @@ -10653,7 +10653,10 @@ librados::Rados* RGWRados::get_rados_handle() return &rados; } -int RGWRados::delete_raw_obj_aio(const DoutPrefixProvider *dpp, const rgw_raw_obj& obj, list& handles) +int RGWRados::delete_tail_obj_aio(const DoutPrefixProvider *dpp, + const rgw_raw_obj& obj, + const std::string& tag, + list& handles) { rgw_rados_ref ref; int ret = get_raw_obj_ref(dpp, obj, &ref); @@ -10663,8 +10666,7 @@ int RGWRados::delete_raw_obj_aio(const DoutPrefixProvider *dpp, const rgw_raw_ob } ObjectWriteOperation op; - list prefixes; - cls_rgw_remove_obj(op, prefixes); + cls_refcount_put(op, tag, true); AioCompletion *c = librados::Rados::aio_create_completion(nullptr, nullptr); ret = ref.ioctx.aio_operate(ref.obj.oid, c, &op); diff --git a/src/rgw/driver/rados/rgw_rados.h b/src/rgw/driver/rados/rgw_rados.h index 6d716bd9052a..e66b26bc6b8a 100644 --- a/src/rgw/driver/rados/rgw_rados.h +++ b/src/rgw/driver/rados/rgw_rados.h @@ -1624,7 +1624,8 @@ public: librados::Rados* get_rados_handle(); - int delete_raw_obj_aio(const DoutPrefixProvider *dpp, const rgw_raw_obj& obj, std::list& handles); + int delete_tail_obj_aio(const DoutPrefixProvider *dpp, const rgw_raw_obj& obj, + const std::string& tag, std::list& handles); int delete_obj_aio(const DoutPrefixProvider *dpp, const rgw_obj& obj, RGWBucketInfo& info, RGWObjState *astate, std::list& handles, bool keep_index_consistent, optional_yield y); diff --git a/src/rgw/driver/rados/rgw_sal_rados.cc b/src/rgw/driver/rados/rgw_sal_rados.cc index 2beaab86ea74..534e926986d1 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.cc +++ b/src/rgw/driver/rados/rgw_sal_rados.cc @@ -535,6 +535,10 @@ int RadosBucket::remove_bypass_gc(int concurrent_max, bool rgw_raw_obj raw_head_obj; store->get_raw_obj(manifest.get_head_placement_rule(), head_obj, &raw_head_obj); + // tag for cls_refcount + const std::string tag = (astate->tail_tag.length() > 0 + ? astate->tail_tag.to_str() + : astate->obj_tag.to_str()); for (; miter != manifest.obj_end(dpp) && max_aio--; ++miter) { if (!max_aio) { ret = drain_aio(handles); @@ -551,7 +555,7 @@ int RadosBucket::remove_bypass_gc(int concurrent_max, bool continue; } - ret = store->getRados()->delete_raw_obj_aio(dpp, last_obj, handles); + ret = store->getRados()->delete_tail_obj_aio(dpp, last_obj, tag, handles); if (ret < 0) { ldpp_dout(dpp, -1) << "ERROR: delete obj aio failed with " << ret << dendl; return ret; -- 2.47.3