From: Cory Snyder Date: Thu, 21 Sep 2023 19:27:51 +0000 (+0000) Subject: rgw: prevent another leftover bucket index olh entry scenario X-Git-Tag: v16.2.15~169^2~4 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=541a2a94ad263a03f88029390f595031be77bca4;p=ceph.git rgw: prevent another leftover bucket index olh entry scenario If a call to bucket_index_link_olh or bucket_index_unlink_instance fails, its associated pending xattr may have prevented the olh object from being removed by another thread. We should do a best effort cleanup attempt for this case by calling update_olh before returning an error to the caller. Signed-off-by: Cory Snyder (cherry picked from commit 570adec5bb8142f5baf1f05f0040e8afdb11ec05) Conflicts: src/rgw/driver/rados/rgw_rados.cc Cherry-pick notes: - Conflicts due to rgw_rados file being moved into driver dir in later versions --- diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 4004135747e4a..1e115f98b26fa 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -7520,6 +7520,13 @@ int RGWRados::set_olh(const DoutPrefixProvider *dpp, RGWObjectCtx& obj_ctx, cons } continue; } + // it's possible that the pending xattr from this op prevented the olh + // object from being cleaned by another thread that was deleting the last + // existing version. We invoke a best-effort update_olh here to handle this case. + int r = update_olh(dpp, obj_ctx, state, bucket_info, olh_obj); + if (r < 0 && r != -ECANCELED) { + ldpp_dout(dpp, 20) << "update_olh() target_obj=" << olh_obj << " returned " << r << dendl; + } return ret; } break; @@ -7578,9 +7585,17 @@ int RGWRados::unlink_obj_instance(const DoutPrefixProvider *dpp, RGWObjectCtx& o ret = bucket_index_unlink_instance(dpp, bucket_info, target_obj, op_tag, olh_tag, olh_epoch, zones_trace); if (ret < 0) { ldpp_dout(dpp, 20) << "bucket_index_unlink_instance() target_obj=" << target_obj << " returned " << ret << dendl; + olh_cancel_modification(dpp, bucket_info, *state, olh_obj, op_tag, y); if (ret == -ECANCELED) { continue; } + // it's possible that the pending xattr from this op prevented the olh + // object from being cleaned by another thread that was deleting the last + // existing version. We invoke a best-effort update_olh here to handle this case. + int r = update_olh(dpp, obj_ctx, state, bucket_info, olh_obj, zones_trace); + if (r < 0 && r != -ECANCELED) { + ldpp_dout(dpp, 20) << "update_olh() target_obj=" << olh_obj << " returned " << r << dendl; + } return ret; } break;