@@ -6045,9 +6045,13 @@ struct tombstone_entry {
60456045 * Delete an object.
60466046 * bucket: name of the bucket storing the object
60476047 * obj: name of the object to delete
6048+ * force: if b.i. entry exists but head object does not, still remove entry
60486049 * Returns: 0 on success, -ERR# otherwise.
60496050 */
6050- int RGWRados::Object::Delete::delete_obj (optional_yield y, const DoutPrefixProvider *dpp, bool log_op)
6051+ int RGWRados::Object::Delete::delete_obj (optional_yield y,
6052+ const DoutPrefixProvider* dpp,
6053+ bool log_op,
6054+ const bool force)
60516055{
60526056 RGWRados *store = target->get_store ();
60536057 const rgw_obj& src_obj = target->get_obj ();
@@ -6105,8 +6109,10 @@ int RGWRados::Object::Delete::delete_obj(optional_yield y, const DoutPrefixProvi
61056109 return r;
61066110 }
61076111 result.delete_marker = dirent.is_delete_marker ();
6108- r = store->unlink_obj_instance (dpp, target->get_ctx (), target->get_bucket_info (), obj, params.olh_epoch ,
6109- y, params.bilog_flags , params.null_verid , params.zones_trace , add_log);
6112+ r = store->unlink_obj_instance (
6113+ dpp, target->get_ctx (), target->get_bucket_info (), obj,
6114+ params.olh_epoch , y, params.bilog_flags ,
6115+ params.null_verid , params.zones_trace , add_log, force);
61106116 if (r < 0 ) {
61116117 return r;
61126118 }
@@ -6186,8 +6192,14 @@ int RGWRados::Object::Delete::delete_obj(optional_yield y, const DoutPrefixProvi
61866192 }
61876193
61886194 if (!state->exists ) {
6189- target->invalidate_state ();
6190- return -ENOENT;
6195+ if (!force) {
6196+ target->invalidate_state ();
6197+ return -ENOENT;
6198+ } else {
6199+ ldpp_dout (dpp, 5 ) << " WARNING: head for \" " << src_obj <<
6200+ " \" does not exist; will continue with deleting bucket "
6201+ " index entry(ies)" << dendl;
6202+ }
61916203 }
61926204
61936205 r = target->prepare_atomic_modification (dpp, op, false , NULL , NULL , NULL , true , false , y);
@@ -6272,7 +6284,8 @@ int RGWRados::delete_obj(const DoutPrefixProvider *dpp,
62726284 uint16_t bilog_flags,
62736285 const real_time& expiration_time,
62746286 rgw_zone_set *zones_trace,
6275- bool log_op)
6287+ bool log_op,
6288+ const bool force) // force removal even if head object is broken
62766289{
62776290 RGWRados::Object del_target (this , bucket_info, obj_ctx, obj);
62786291 RGWRados::Object::Delete del_op (&del_target);
@@ -6284,7 +6297,7 @@ int RGWRados::delete_obj(const DoutPrefixProvider *dpp,
62846297 del_op.params .zones_trace = zones_trace;
62856298 del_op.params .null_verid = null_verid;
62866299
6287- return del_op.delete_obj (y, dpp, log_op ? rgw::sal::FLAG_LOG_OP : 0 );
6300+ return del_op.delete_obj (y, dpp, log_op, force );
62886301}
62896302
62906303int RGWRados::delete_raw_obj (const DoutPrefixProvider *dpp, const rgw_raw_obj& obj, optional_yield y)
@@ -8590,9 +8603,10 @@ int RGWRados::apply_olh_log(const DoutPrefixProvider *dpp,
85908603 std::map<uint64_t , std::vector<rgw_bucket_olh_log_entry> >& log,
85918604 uint64_t *plast_ver,
85928605 optional_yield y,
8593- bool null_verid,
8594- rgw_zone_set* zones_trace,
8595- bool log_op)
8606+ bool null_verid,
8607+ rgw_zone_set* zones_trace,
8608+ bool log_op,
8609+ const bool force)
85968610{
85978611 if (log.empty ()) {
85988612 return 0 ;
@@ -8705,7 +8719,9 @@ int RGWRados::apply_olh_log(const DoutPrefixProvider *dpp,
87058719 liter != remove_instances.end (); ++liter) {
87068720 cls_rgw_obj_key& key = *liter;
87078721 rgw_obj obj_instance (bucket, key);
8708- int ret = delete_obj (dpp, obj_ctx, bucket_info, obj_instance, 0 , y, null_verid, RGW_BILOG_FLAG_VERSIONED_OP, ceph::real_time (), zones_trace, log_op);
8722+ int ret = delete_obj (dpp, obj_ctx, bucket_info, obj_instance, 0 , y,
8723+ null_verid, RGW_BILOG_FLAG_VERSIONED_OP,
8724+ ceph::real_time (), zones_trace, log_op, force);
87098725 if (ret < 0 && ret != -ENOENT) {
87108726 ldpp_dout (dpp, 0 ) << " ERROR: delete_obj() returned " << ret << " obj_instance=" << obj_instance << dendl;
87118727 return ret;
@@ -8809,7 +8825,15 @@ int RGWRados::clear_olh(const DoutPrefixProvider *dpp,
88098825/*
88108826 * read olh log and apply it
88118827 */
8812- int RGWRados::update_olh (const DoutPrefixProvider *dpp, RGWObjectCtx& obj_ctx, RGWObjState *state, RGWBucketInfo& bucket_info, const rgw_obj& obj, optional_yield y, rgw_zone_set *zones_trace, bool null_verid, bool log_op)
8828+ int RGWRados::update_olh (const DoutPrefixProvider* dpp,
8829+ RGWObjectCtx& obj_ctx,
8830+ RGWObjState* state,
8831+ RGWBucketInfo& bucket_info,
8832+ const rgw_obj& obj, optional_yield y,
8833+ rgw_zone_set* zones_trace,
8834+ bool null_verid,
8835+ bool log_op,
8836+ const bool force)
88138837{
88148838 map<uint64_t , vector<rgw_bucket_olh_log_entry> > log;
88158839 bool is_truncated;
@@ -8820,7 +8844,9 @@ int RGWRados::update_olh(const DoutPrefixProvider *dpp, RGWObjectCtx& obj_ctx, R
88208844 if (ret < 0 ) {
88218845 return ret;
88228846 }
8823- ret = apply_olh_log (dpp, obj_ctx, *state, bucket_info, obj, state->olh_tag , log, &ver_marker, y, null_verid, zones_trace, log_op);
8847+ ret = apply_olh_log (dpp, obj_ctx, *state, bucket_info, obj,
8848+ state->olh_tag , log, &ver_marker, y,
8849+ null_verid, zones_trace, log_op, force);
88248850 if (ret < 0 ) {
88258851 return ret;
88268852 }
@@ -8921,8 +8947,17 @@ int RGWRados::set_olh(const DoutPrefixProvider *dpp, RGWObjectCtx& obj_ctx,
89218947 return 0 ;
89228948}
89238949
8924- int RGWRados::unlink_obj_instance (const DoutPrefixProvider *dpp, RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, const rgw_obj& target_obj,
8925- uint64_t olh_epoch, optional_yield y, uint16_t bilog_flags, bool null_verid, rgw_zone_set *zones_trace, bool log_op)
8950+ int RGWRados::unlink_obj_instance (const DoutPrefixProvider* dpp,
8951+ RGWObjectCtx& obj_ctx,
8952+ RGWBucketInfo& bucket_info,
8953+ const rgw_obj& target_obj,
8954+ uint64_t olh_epoch,
8955+ optional_yield y,
8956+ uint16_t bilog_flags,
8957+ bool null_verid,
8958+ rgw_zone_set* zones_trace,
8959+ bool log_op,
8960+ const bool force)
89268961{
89278962 string op_tag;
89288963
@@ -8977,7 +9012,8 @@ int RGWRados::unlink_obj_instance(const DoutPrefixProvider *dpp, RGWObjectCtx& o
89779012 // it's possible that the pending xattr from this op prevented the olh
89789013 // object from being cleaned by another thread that was deleting the last
89799014 // existing version. We invoke a best-effort update_olh here to handle this case.
8980- int r = update_olh (dpp, obj_ctx, state, bucket_info, olh_obj, y, zones_trace, null_verid, log_op);
9015+ int r = update_olh (dpp, obj_ctx, state, bucket_info, olh_obj, y,
9016+ zones_trace, null_verid, log_op, force);
89819017 if (r < 0 && r != -ECANCELED) {
89829018 ldpp_dout (dpp, 20 ) << " update_olh() target_obj=" << olh_obj << " returned " << r << dendl;
89839019 }
@@ -8991,7 +9027,8 @@ int RGWRados::unlink_obj_instance(const DoutPrefixProvider *dpp, RGWObjectCtx& o
89919027 return -EIO;
89929028 }
89939029
8994- ret = update_olh (dpp, obj_ctx, state, bucket_info, olh_obj, y, zones_trace, null_verid, log_op);
9030+ ret = update_olh (dpp, obj_ctx, state, bucket_info, olh_obj, y,
9031+ zones_trace, null_verid, log_op, force);
89959032 if (ret == -ECANCELED) { /* already did what we needed, no need to retry, raced with another user */
89969033 return 0 ;
89979034 }
0 commit comments