}
     ldout(store->ctx(), 0) << "NOTICE: resharding operation on bucket index detected, blocking" << dendl;
     string new_bucket_id;
-    r = store->block_while_resharding(bs, &new_bucket_id, target->bucket_info);
+    r = store->block_while_resharding(bs, &new_bucket_id,
+                                      target->bucket_info, null_yield);
     if (r == -ERR_BUSY_RESHARDING) {
       continue;
     }
     }
     ldout(cct, 0) << "NOTICE: resharding operation on bucket index detected, blocking" << dendl;
     string new_bucket_id;
-    r = block_while_resharding(bs, &new_bucket_id, bucket_info);
+    r = block_while_resharding(bs, &new_bucket_id, bucket_info, null_yield);
     if (r == -ERR_BUSY_RESHARDING) {
       continue;
     }
 
 int RGWRados::block_while_resharding(RGWRados::BucketShard *bs,
                                     string *new_bucket_id,
-                                    const RGWBucketInfo& bucket_info)
+                                     const RGWBucketInfo& bucket_info,
+                                     optional_yield y)
 {
   std::shared_ptr<RGWReshardWait> waiter = reshard_wait;
 
-  return waiter->block_while_resharding(bs, new_bucket_id, bucket_info);
+  return waiter->block_while_resharding(bs, new_bucket_id, bucket_info, y);
 }
 
 int RGWRados::bucket_index_link_olh(const RGWBucketInfo& bucket_info, RGWObjState& olh_state, const rgw_obj& obj_instance,
 
                    std::function<int(BucketShard *)> call);
   int block_while_resharding(RGWRados::BucketShard *bs,
                             string *new_bucket_id,
-                            const RGWBucketInfo& bucket_info);
+                            const RGWBucketInfo& bucket_info,
+                             optional_yield y);
 
   void bucket_index_guard_olh_op(RGWObjState& olh_state, librados::ObjectOperation& op);
   int olh_init_modification(const RGWBucketInfo& bucket_info, RGWObjState& state, const rgw_obj& olh_obj, string *op_tag);
 
 const int num_retries = 10;
 static const std::chrono::seconds default_reshard_sleep_duration(5);
 
-int RGWReshardWait::do_wait()
+int RGWReshardWait::do_wait(optional_yield y)
 {
   std::unique_lock lock(mutex);
 
+  if (going_down) {
+    return -ECANCELED;
+  }
+
+#ifdef HAVE_BOOST_CONTEXT
+  if (y) {
+    auto& context = y.get_io_context();
+    auto& yield = y.get_yield_context();
+
+    Waiter waiter(context);
+    waiters.push_back(waiter);
+    lock.unlock();
+
+    waiter.timer.expires_after(default_reshard_sleep_duration);
+
+    boost::system::error_code ec;
+    waiter.timer.async_wait(yield[ec]);
+
+    lock.lock();
+    waiters.erase(waiters.iterator_to(waiter));
+    return -ec.value();
+  }
+#endif
+
   cond.wait_for(lock, default_reshard_sleep_duration);
 
   if (going_down) {
   return 0;
 }
 
+void RGWReshardWait::stop()
+{
+  std::scoped_lock lock(mutex);
+  going_down = true;
+  cond.notify_all();
+  for (auto& waiter : waiters) {
+    // unblock any waiters with ECANCELED
+    waiter.timer.cancel();
+  }
+}
+
 int RGWReshardWait::block_while_resharding(RGWRados::BucketShard *bs,
                                           string *new_bucket_id,
-                                          const RGWBucketInfo& bucket_info)
+                                          const RGWBucketInfo& bucket_info,
+                                           optional_yield y)
 {
   int ret = 0;
   cls_rgw_bucket_instance_entry entry;
       } // if taking of lock succeeded
     } // block to encapsulate recovery from incomplete reshard
 
-    ret = do_wait();
+    ret = do_wait(y);
     if (ret < 0) {
       ldout(store->ctx(), 0) << __func__ << " ERROR: bucket is still resharding, please retry" << dendl;
       return ret;
 
 #include <vector>
 #include <functional>
 
+#include <boost/intrusive/list.hpp>
+
 #include "include/rados/librados.hpp"
 #include "common/ceph_time.h"
 #include "cls/rgw/cls_rgw_types.h"
   ceph::mutex mutex = ceph::make_mutex("RGWReshardWait::lock");
   ceph::condition_variable cond;
 
+  using Clock = ceph::coarse_real_clock;
+  struct Waiter : boost::intrusive::list_base_hook<> {
+    boost::asio::basic_waitable_timer<Clock> timer;
+    explicit Waiter(boost::asio::io_context& ioc) : timer(ioc) {}
+  };
+  boost::intrusive::list<Waiter> waiters;
+
   bool going_down{false};
 
-  int do_wait();
+  int do_wait(optional_yield y);
 public:
   explicit RGWReshardWait(RGWRados *_store) : store(_store) {}
   ~RGWReshardWait() {
   }
   int block_while_resharding(RGWRados::BucketShard *bs,
                             string *new_bucket_id,
-                            const RGWBucketInfo& bucket_info);
-
-  void stop() {
-    std::scoped_lock lock(mutex);
-    going_down = true;
-    cond.notify_all();
-  }
+                            const RGWBucketInfo& bucket_info,
+                             optional_yield y);
+  // unblock any threads waiting on reshard
+  void stop();
 };
 
 #endif