]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: Remove GC deferred entries options and code.
authorNathan Hoad <nhoad@bloomberg.net>
Thu, 23 Apr 2026 18:03:24 +0000 (14:03 -0400)
committerNathan Hoad <nhoad@bloomberg.net>
Thu, 30 Apr 2026 19:52:14 +0000 (15:52 -0400)
This code has been disabled since v16.2.8.

Signed-off-by: Nathan Hoad <nhoad@bloomberg.net>
src/cls/rgw_gc/cls_rgw_gc.cc
src/common/options/rgw.yaml.in
src/rgw/driver/rados/rgw_gc.cc
src/rgw/driver/rados/rgw_gc.h
src/rgw/driver/rados/rgw_rados.cc
src/rgw/driver/rados/rgw_rados.h
src/test/cls_rgw_gc/test_cls_rgw_gc.cc

index ecaba00cacfdb3cecfdf6a367ad587b2d7863a0d..60d6d2dedbb2deab1d40de12ba0edc75dc2bc949 100644 (file)
@@ -47,8 +47,7 @@ static int cls_rgw_gc_queue_init(cls_method_context_t hctx, bufferlist *in, buff
   CLS_LOG(10, "INFO: cls_rgw_gc_queue_init: queue size is %lu\n", op.size);
 
   init_op.queue_size = op.size;
-  const auto& conf = cls_get_config(hctx);
-  init_op.max_urgent_data_size = conf->rgw_gc_max_deferred_entries_size;
+  init_op.max_urgent_data_size = 0;
   encode(urgent_data, init_op.bl_urgent_data);
 
   return queue_init(hctx, init_op);
@@ -497,22 +496,6 @@ static int cls_rgw_gc_queue_update_entry(cls_method_context_t hctx, bufferlist *
     return -ENOSPC;
   }
 
-  // Due to Tracker 47866 we are no longer executing this code, as it
-  // appears to possibly create a GC entry for an object that has not
-  // been deleted. Instead we will log at level 0 to perhaps confirm
-  // that when and how often this bug would otherwise be hit.
-#if 0
-  cls_queue_enqueue_op enqueue_op;
-  bufferlist bl_data;
-  encode(op.info, bl_data);
-  enqueue_op.bl_data_vec.emplace_back(bl_data);
-  CLS_LOG(10, "INFO: cls_gc_update_entry: Data size is: %u \n", bl_data.length());
-  
-  ret = queue_enqueue(hctx, enqueue_op, head);
-  if (ret < 0) {
-    return ret;
-  }
-#else
   std::string first_chain = "<empty-chain>";
   if (! op.info.chain.objs.empty()) {
     first_chain = op.info.chain.objs.cbegin()->key.name;
@@ -521,7 +504,6 @@ static int cls_rgw_gc_queue_update_entry(cls_method_context_t hctx, bufferlist *
          "INFO: refrained from enqueueing GC entry during GC defer"
          " tag=%s, first_chain=%s\n",
          op.info.tag.c_str(), first_chain.c_str());
-#endif
 
   if (has_urgent_data) {
     head.bl_urgent_data.clear();
index 57000c5154b53618b4ddd61a8a75e90d3fa7e87c..b52d85d758a48521d7d1bbd3aaee2f61db2e559c 100644 (file)
@@ -1962,34 +1962,17 @@ options:
   - rgw_gc_processor_max_time
   - rgw_gc_max_concurrent_io
   with_legacy: true
-- name: rgw_gc_max_deferred_entries_size
-  type: uint
-  level: advanced
-  desc: maximum allowed size of deferred entries in queue head for gc
-  default: 3_K
-  services:
-  - rgw
-  with_legacy: true
 - name: rgw_gc_max_queue_size
   type: uint
   level: advanced
   desc: Maximum allowed queue size for gc
   long_desc: The maximum allowed size of each gc queue, and its value should not be
-    greater than (osd_max_object_size - rgw_gc_max_deferred_entries_size - 1K).
-  default: 131068_K
+    greater than osd_max_object_size - 1K.
+  default: 134068_K
   services:
   - rgw
   see_also:
   - osd_max_object_size
-  - rgw_gc_max_deferred_entries_size
-  with_legacy: true
-- name: rgw_gc_max_deferred
-  type: uint
-  level: advanced
-  desc: Number of maximum deferred data entries to be stored in queue for gc
-  default: 50
-  services:
-  - rgw
   with_legacy: true
 - name: rgw_s3_success_create_obj_status
   type: int
index 8a9e464f1dd584ce302b75c75a5216c3ed61dde2..de52f29936d693a9ac9e8ac60a71d58fac729272 100644 (file)
@@ -50,8 +50,8 @@ void RGWGC::initialize(CephContext *_cct, RGWRados *_store, optional_yield y) {
     //version = 1 -> marked ready for transition
     librados::ObjectWriteOperation op;
     op.create(false);
-    const uint64_t queue_size = cct->_conf->rgw_gc_max_queue_size, num_deferred_entries = cct->_conf->rgw_gc_max_deferred;
-    gc_log_init2(op, queue_size, num_deferred_entries);
+    const uint64_t queue_size = cct->_conf->rgw_gc_max_queue_size;
+    gc_log_init2(op, queue_size, 0);
     store->gc_operate(this, obj_names[i], std::move(op), y);
   }
 }
@@ -139,90 +139,6 @@ int RGWGC::send_chain(const cls_rgw_obj_chain& chain, const string& tag, optiona
   return store->gc_operate(this, obj_names[i], std::move(set_entry_op), y);
 }
 
-struct defer_chain_state {
-  librados::AioCompletion* completion = nullptr;
-  // TODO: hold a reference on the state in RGWGC to avoid use-after-free if
-  // RGWGC destructs before this completion fires
-  RGWGC* gc = nullptr;
-  cls_rgw_gc_obj_info info;
-
-  ~defer_chain_state() {
-    if (completion) {
-      completion->release();
-    }
-  }
-};
-
-static void async_defer_callback(librados::completion_t, void* arg)
-{
-  std::unique_ptr<defer_chain_state> state{static_cast<defer_chain_state*>(arg)};
-  if (state->completion->get_return_value() == -ECANCELED) {
-    state->gc->on_defer_canceled(state->info);
-  }
-}
-
-void RGWGC::on_defer_canceled(const cls_rgw_gc_obj_info& info)
-{
-  const std::string& tag = info.tag;
-  const int i = tag_index(tag);
-
-  // ECANCELED from cls_version_check() tells us that we've transitioned
-  transitioned_objects_cache[i] = true;
-
-  ObjectWriteOperation op;
-  cls_rgw_gc_queue_defer_entry(op, cct->_conf->rgw_gc_obj_min_wait, info);
-  cls_rgw_gc_remove(op, {tag});
-
-  aio_completion_ptr c{librados::Rados::aio_create_completion(nullptr, nullptr)};
-
-  store->gc_aio_operate(obj_names[i], c.get(), &op);
-}
-
-int RGWGC::async_defer_chain(const string& tag, const cls_rgw_obj_chain& chain)
-{
-  const int i = tag_index(tag);
-  cls_rgw_gc_obj_info info;
-  info.chain = chain;
-  info.tag = tag;
-
-  // if we've transitioned this shard object, we can rely on the cls_rgw_gc queue
-  if (transitioned_objects_cache[i]) {
-    ObjectWriteOperation op;
-    cls_rgw_gc_queue_defer_entry(op, cct->_conf->rgw_gc_obj_min_wait, info);
-
-    // this tag may still be present in omap, so remove it once the cls_rgw_gc
-    // enqueue succeeds
-    cls_rgw_gc_remove(op, {tag});
-
-    aio_completion_ptr c{librados::Rados::aio_create_completion(nullptr, nullptr)};
-
-    int ret = store->gc_aio_operate(obj_names[i], c.get(), &op);
-    return ret;
-  }
-
-  // if we haven't seen the transition yet, write the defer to omap with cls_rgw
-  ObjectWriteOperation op;
-
-  // assert that we haven't initialized cls_rgw_gc queue. this prevents us
-  // from writing new entries to omap after the transition
-  gc_log_defer1(op, cct->_conf->rgw_gc_obj_min_wait, info);
-
-  // prepare a callback to detect the transition via ECANCELED from cls_version_check()
-  auto state = std::make_unique<defer_chain_state>();
-  state->gc = this;
-  state->info.chain = chain;
-  state->info.tag = tag;
-  state->completion = librados::Rados::aio_create_completion(
-      state.get(), async_defer_callback);
-
-  int ret = store->gc_aio_operate(obj_names[i], state->completion, &op);
-  if (ret == 0) {
-    // coverity[leaked_storage:SUPPRESS]
-    state.release(); // release ownership until async_defer_callback()
-  }
-  return ret;
-}
-
 int RGWGC::remove(int index, const std::vector<string>& tags, AioCompletion **pc, optional_yield y)
 {
   ObjectWriteOperation op;
index b7a118204271f46d01985c1906c98b71c8b8a115..57fc084b63bd11853df481a0844ce76086056836 100644 (file)
@@ -52,12 +52,6 @@ public:
   std::vector<bool> transitioned_objects_cache;
   std::tuple<int, std::optional<cls_rgw_obj_chain>> send_split_chain(const cls_rgw_obj_chain& chain, const std::string& tag, optional_yield y);
 
-  // asynchronously defer garbage collection on an object that's still being read
-  int async_defer_chain(const std::string& tag, const cls_rgw_obj_chain& info);
-
-  // callback for when async_defer_chain() fails with ECANCELED
-  void on_defer_canceled(const cls_rgw_gc_obj_info& info);
-
   int remove(int index, const std::vector<std::string>& tags, librados::AioCompletion **pc, optional_yield y);
   int remove(int index, int num_entries, optional_yield y);
 
index c495903d9041981f396fb531eb0b18dce4010be1..2a8127a8817e942b3689d35bd06c835ccdb72cfd 100644 (file)
@@ -6449,43 +6449,6 @@ int RGWRados::bucket_resync_encrypted_multipart(const DoutPrefixProvider* dpp,
   return 0;
 }
 
-int RGWRados::defer_gc(const DoutPrefixProvider *dpp, RGWObjectCtx* octx, RGWBucketInfo& bucket_info, const rgw_obj& obj, optional_yield y)
-{
-  std::string oid, key;
-  get_obj_bucket_and_oid_loc(obj, oid, key);
-  if (!octx)
-    return 0;
-
-  RGWObjState *state = NULL;
-  RGWObjManifest *manifest = nullptr;
-
-  int r = get_obj_state(dpp, octx, bucket_info, obj, &state, &manifest, false, y);
-  if (r < 0)
-    return r;
-
-  if (!state->is_atomic) {
-    ldpp_dout(dpp, 20) << "state for obj=" << obj << " is not atomic, not deferring gc operation" << dendl;
-    return -EINVAL;
-  }
-
-  string tag;
-
-  if (state->tail_tag.length() > 0) {
-    tag = state->tail_tag.c_str();
-  } else if (state->obj_tag.length() > 0) {
-    tag = state->obj_tag.c_str();
-  } else {
-    ldpp_dout(dpp, 20) << "state->obj_tag is empty, not deferring gc operation" << dendl;
-    return -EINVAL;
-  }
-
-  ldpp_dout(dpp, 0) << "defer chain tag=" << tag << dendl;
-
-  cls_rgw_obj_chain chain;
-  update_gc_chain(dpp, state->obj, *manifest, &chain);
-  return gc->async_defer_chain(tag, chain);
-}
-
 void RGWRados::remove_rgw_head_obj(ObjectWriteOperation& op)
 {
   list<string> prefixes;
index d8fe665fcf3e1cf666fc6a82fe2e90714bb4d9b6..d1b61933606761cc3e5cb315eff8c9aba41aecf1 100644 (file)
@@ -1630,7 +1630,6 @@ public:
   int list_gc_objs(int *index, std::string& marker, uint32_t max, bool expired_only, std::list<cls_rgw_gc_obj_info>& result, bool *truncated, bool& processing_queue);
   int process_gc(bool expired_only, optional_yield y);
   bool process_expired_objects(const DoutPrefixProvider *dpp, optional_yield y);
-  int defer_gc(const DoutPrefixProvider *dpp, RGWObjectCtx* ctx, RGWBucketInfo& bucket_info, const rgw_obj& obj, optional_yield y);
 
   int process_lc(const std::unique_ptr<rgw::sal::Bucket>& optional_bucket);
 
index 6014542a324cd24471c98c4958f1b9146460b6aa..44cc464ffd08642d58a6880547d0ed8396404baa 100644 (file)
@@ -207,161 +207,6 @@ TEST(cls_rgw_gc, gc_queue_ops2)
   ASSERT_EQ("chain-1", it.tag);
 }
 
-#if 0 // TODO: fix or remove defer_gc()
-TEST(cls_rgw_gc, gc_queue_ops3)
-{
-  //Testing remove queue entries
-  string queue_name = "my-third-queue";
-  uint64_t queue_size = 501, num_urgent_data_entries = 10;
-  librados::ObjectWriteOperation op;
-  op.create(true);
-  cls_rgw_gc_queue_init(op, queue_size, num_urgent_data_entries);
-  ASSERT_EQ(0, ioctx.operate(queue_name, &op));
-
-  uint64_t size = 0;
-  int ret = cls_rgw_gc_queue_get_capacity(ioctx, queue_name, size);
-  ASSERT_EQ(0, ret);
-  ASSERT_EQ(size, queue_size);
-
-  //Test remove queue, when queue is empty
-  librados::ObjectWriteOperation remove_op;
-  string marker1;
-  uint64_t num_entries = 2;
-  cls_rgw_gc_queue_remove_entries(remove_op, num_entries);
-  ASSERT_EQ(0, ioctx.operate(queue_name, &remove_op));
-
-  cls_rgw_gc_obj_info defer_info;
-
-  //Test enqueue
-  for (int i = 0; i < 2; i++) {
-    string tag = "chain-" + to_string(i);
-    librados::ObjectWriteOperation op;
-    cls_rgw_gc_obj_info info;
-
-    cls_rgw_obj obj1, obj2;
-    create_obj(obj1, i, 1);
-    create_obj(obj2, i, 2);
-    info.chain.objs.push_back(obj1);
-    info.chain.objs.push_back(obj2);
-
-    info.tag = tag;
-    cls_rgw_gc_queue_enqueue(op, 5, info);
-    ASSERT_EQ(0, ioctx.operate(queue_name, &op));
-    if (i == 0)
-      defer_info = info;
-  }
-
-  //Test defer entry for 1st element
-  librados::ObjectWriteOperation defer_op;
-  cls_rgw_gc_queue_defer_entry(defer_op, 10, defer_info);
-  ASSERT_EQ(0, ioctx.operate(queue_name, &defer_op));
-
-  //Test list queue
-  list<cls_rgw_gc_obj_info> list_info1, list_info2;
-  string marker, next_marker;
-  uint64_t max = 2;
-  bool expired_only = false, truncated;
-  cls_rgw_gc_queue_list_entries(ioctx, queue_name, marker, max, expired_only, list_info1, &truncated, next_marker);
-  ASSERT_EQ(2, list_info1.size());
-
-  int i = 0;
-  for (auto it : list_info1) {
-    std::cerr << "[          ] list info tag = " << it.tag << std::endl;
-    if (i == 0) {
-      ASSERT_EQ("chain-1", it.tag);
-    }
-    if (i == 1) {
-      ASSERT_EQ("chain-0", it.tag);
-    }
-    i++;
-  }
-
-  //Test remove entries
-  num_entries = 2;
-  cls_rgw_gc_queue_remove_entries(remove_op, num_entries);
-  ASSERT_EQ(0, ioctx.operate(queue_name, &remove_op));
-
-  //Test list queue again
-  cls_rgw_gc_queue_list_entries(ioctx, queue_name, marker, max, expired_only, list_info2, &truncated, next_marker);
-  ASSERT_EQ(0, list_info2.size());
-
-}
-
-TEST(cls_rgw_gc, gc_queue_ops4)
-{
-  //Testing remove queue entries
-  string queue_name = "my-fourth-queue";
-  uint64_t queue_size = 501, num_urgent_data_entries = 10;
-  librados::ObjectWriteOperation op;
-  op.create(true);
-  cls_rgw_gc_queue_init(op, queue_size, num_urgent_data_entries);
-  ASSERT_EQ(0, ioctx.operate(queue_name, &op));
-
-  uint64_t size = 0;
-  int ret = cls_rgw_gc_queue_get_capacity(ioctx, queue_name, size);
-  ASSERT_EQ(0, ret);
-  ASSERT_EQ(size, queue_size);
-
-  //Test remove queue, when queue is empty
-  librados::ObjectWriteOperation remove_op;
-  string marker1;
-  uint64_t num_entries = 2;
-
-  cls_rgw_gc_queue_remove_entries(remove_op, num_entries);
-  ASSERT_EQ(0, ioctx.operate(queue_name, &remove_op));
-
-  cls_rgw_gc_obj_info defer_info;
-
-  //Test enqueue
-  for (int i = 0; i < 2; i++) {
-    string tag = "chain-" + to_string(i);
-    librados::ObjectWriteOperation op;
-    cls_rgw_gc_obj_info info;
-
-    cls_rgw_obj obj1, obj2;
-    create_obj(obj1, i, 1);
-    create_obj(obj2, i, 2);
-    info.chain.objs.push_back(obj1);
-    info.chain.objs.push_back(obj2);
-
-    info.tag = tag;
-    cls_rgw_gc_queue_enqueue(op, 5, info);
-    ASSERT_EQ(0, ioctx.operate(queue_name, &op));
-    defer_info = info;
-  }
-
-  //Test defer entry for last element
-  librados::ObjectWriteOperation defer_op;
-  cls_rgw_gc_queue_defer_entry(defer_op, 10, defer_info);
-  ASSERT_EQ(0, ioctx.operate(queue_name, &defer_op));
-
-  //Test list queue
-  list<cls_rgw_gc_obj_info> list_info1, list_info2;
-  string marker, next_marker;
-  uint64_t max = 2;
-  bool expired_only = false, truncated;
-  cls_rgw_gc_queue_list_entries(ioctx, queue_name, marker, max, expired_only, list_info1, &truncated, next_marker);
-  ASSERT_EQ(2, list_info1.size());
-
-  int i = 0;
-  for (auto it : list_info1) {
-    string tag = "chain-" + to_string(i);
-    ASSERT_EQ(tag, it.tag);
-    i++;
-  }
-
-  //Test remove entries
-  num_entries = 2;
-  cls_rgw_gc_queue_remove_entries(remove_op, num_entries);
-  ASSERT_EQ(0, ioctx.operate(queue_name, &remove_op));
-
-  //Test list queue again
-  cls_rgw_gc_queue_list_entries(ioctx, queue_name, marker, max, expired_only, list_info2, &truncated, next_marker);
-  ASSERT_EQ(0, list_info2.size());
-
-}
-#endif // defer_gc() disabled
-
 TEST(cls_rgw_gc, gc_queue_ops5)
 {
   //Testing remove queue entries